mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Long double patch 4 of N: initial x87 implementation.
Lots of problems yet but some simple things work. llvm-svn: 40847
This commit is contained in:
parent
f2a88ac82d
commit
a85f11d870
@ -457,6 +457,13 @@ def extloadf32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
|
||||
LD->getLoadedVT() == MVT::f32;
|
||||
return false;
|
||||
}]>;
|
||||
def extloadf64 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
|
||||
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
|
||||
return LD->getExtensionType() == ISD::EXTLOAD &&
|
||||
LD->getAddressingMode() == ISD::UNINDEXED &&
|
||||
LD->getLoadedVT() == MVT::f64;
|
||||
return false;
|
||||
}]>;
|
||||
|
||||
def sextloadi1 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
|
||||
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
|
||||
@ -561,6 +568,13 @@ def truncstoref32 : PatFrag<(ops node:$val, node:$ptr),
|
||||
ST->getAddressingMode() == ISD::UNINDEXED;
|
||||
return false;
|
||||
}]>;
|
||||
def truncstoref64 : PatFrag<(ops node:$val, node:$ptr),
|
||||
(st node:$val, node:$ptr), [{
|
||||
if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
|
||||
return ST->isTruncatingStore() && ST->getStoredVT() == MVT::f64 &&
|
||||
ST->getAddressingMode() == ISD::UNINDEXED;
|
||||
return false;
|
||||
}]>;
|
||||
|
||||
// indexed store fragments.
|
||||
def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset),
|
||||
|
@ -57,6 +57,9 @@ struct X86ATTAsmPrinter : public X86SharedAsmPrinter {
|
||||
void printf64mem(const MachineInstr *MI, unsigned OpNo) {
|
||||
printMemReference(MI, OpNo);
|
||||
}
|
||||
void printf80mem(const MachineInstr *MI, unsigned OpNo) {
|
||||
printMemReference(MI, OpNo);
|
||||
}
|
||||
void printf128mem(const MachineInstr *MI, unsigned OpNo) {
|
||||
printMemReference(MI, OpNo);
|
||||
}
|
||||
|
@ -326,53 +326,79 @@ static int Lookup(const TableEntry *Table, unsigned N, unsigned Opcode) {
|
||||
static const TableEntry OpcodeTable[] = {
|
||||
{ X86::ABS_Fp32 , X86::ABS_F },
|
||||
{ X86::ABS_Fp64 , X86::ABS_F },
|
||||
{ X86::ABS_Fp80 , X86::ABS_F },
|
||||
{ X86::ADD_Fp32m , X86::ADD_F32m },
|
||||
{ X86::ADD_Fp64m , X86::ADD_F64m },
|
||||
{ X86::ADD_Fp64m32 , X86::ADD_F32m },
|
||||
{ X86::ADD_Fp80m32 , X86::ADD_F32m },
|
||||
{ X86::ADD_Fp80m64 , X86::ADD_F64m },
|
||||
{ X86::ADD_FpI16m32 , X86::ADD_FI16m },
|
||||
{ X86::ADD_FpI16m64 , X86::ADD_FI16m },
|
||||
{ X86::ADD_FpI16m80 , X86::ADD_FI16m },
|
||||
{ X86::ADD_FpI32m32 , X86::ADD_FI32m },
|
||||
{ X86::ADD_FpI32m64 , X86::ADD_FI32m },
|
||||
{ X86::ADD_FpI32m80 , X86::ADD_FI32m },
|
||||
{ X86::CHS_Fp32 , X86::CHS_F },
|
||||
{ X86::CHS_Fp64 , X86::CHS_F },
|
||||
{ X86::CHS_Fp80 , X86::CHS_F },
|
||||
{ X86::CMOVBE_Fp32 , X86::CMOVBE_F },
|
||||
{ X86::CMOVBE_Fp64 , X86::CMOVBE_F },
|
||||
{ X86::CMOVBE_Fp80 , X86::CMOVBE_F },
|
||||
{ X86::CMOVB_Fp32 , X86::CMOVB_F },
|
||||
{ X86::CMOVB_Fp64 , X86::CMOVB_F },
|
||||
{ X86::CMOVB_Fp80 , X86::CMOVB_F },
|
||||
{ X86::CMOVE_Fp32 , X86::CMOVE_F },
|
||||
{ X86::CMOVE_Fp64 , X86::CMOVE_F },
|
||||
{ X86::CMOVE_Fp80 , X86::CMOVE_F },
|
||||
{ X86::CMOVNBE_Fp32 , X86::CMOVNBE_F },
|
||||
{ X86::CMOVNBE_Fp64 , X86::CMOVNBE_F },
|
||||
{ X86::CMOVNBE_Fp80 , X86::CMOVNBE_F },
|
||||
{ X86::CMOVNB_Fp32 , X86::CMOVNB_F },
|
||||
{ X86::CMOVNB_Fp64 , X86::CMOVNB_F },
|
||||
{ X86::CMOVNB_Fp80 , X86::CMOVNB_F },
|
||||
{ X86::CMOVNE_Fp32 , X86::CMOVNE_F },
|
||||
{ X86::CMOVNE_Fp64 , X86::CMOVNE_F },
|
||||
{ X86::CMOVNE_Fp80 , X86::CMOVNE_F },
|
||||
{ X86::CMOVNP_Fp32 , X86::CMOVNP_F },
|
||||
{ X86::CMOVNP_Fp64 , X86::CMOVNP_F },
|
||||
{ X86::CMOVNP_Fp80 , X86::CMOVNP_F },
|
||||
{ X86::CMOVP_Fp32 , X86::CMOVP_F },
|
||||
{ X86::CMOVP_Fp64 , X86::CMOVP_F },
|
||||
{ X86::CMOVP_Fp80 , X86::CMOVP_F },
|
||||
{ X86::COS_Fp32 , X86::COS_F },
|
||||
{ X86::COS_Fp64 , X86::COS_F },
|
||||
{ X86::COS_Fp80 , X86::COS_F },
|
||||
{ X86::DIVR_Fp32m , X86::DIVR_F32m },
|
||||
{ X86::DIVR_Fp64m , X86::DIVR_F64m },
|
||||
{ X86::DIVR_Fp64m32 , X86::DIVR_F32m },
|
||||
{ X86::DIVR_Fp80m32 , X86::DIVR_F32m },
|
||||
{ X86::DIVR_Fp80m64 , X86::DIVR_F64m },
|
||||
{ X86::DIVR_FpI16m32, X86::DIVR_FI16m},
|
||||
{ X86::DIVR_FpI16m64, X86::DIVR_FI16m},
|
||||
{ X86::DIVR_FpI16m80, X86::DIVR_FI16m},
|
||||
{ X86::DIVR_FpI32m32, X86::DIVR_FI32m},
|
||||
{ X86::DIVR_FpI32m64, X86::DIVR_FI32m},
|
||||
{ X86::DIVR_FpI32m80, X86::DIVR_FI32m},
|
||||
{ X86::DIV_Fp32m , X86::DIV_F32m },
|
||||
{ X86::DIV_Fp64m , X86::DIV_F64m },
|
||||
{ X86::DIV_Fp64m32 , X86::DIV_F32m },
|
||||
{ X86::DIV_Fp80m32 , X86::DIV_F32m },
|
||||
{ X86::DIV_Fp80m64 , X86::DIV_F64m },
|
||||
{ X86::DIV_FpI16m32 , X86::DIV_FI16m },
|
||||
{ X86::DIV_FpI16m64 , X86::DIV_FI16m },
|
||||
{ X86::DIV_FpI16m80 , X86::DIV_FI16m },
|
||||
{ X86::DIV_FpI32m32 , X86::DIV_FI32m },
|
||||
{ X86::DIV_FpI32m64 , X86::DIV_FI32m },
|
||||
{ X86::DIV_FpI32m80 , X86::DIV_FI32m },
|
||||
{ X86::ILD_Fp16m32 , X86::ILD_F16m },
|
||||
{ X86::ILD_Fp16m64 , X86::ILD_F16m },
|
||||
{ X86::ILD_Fp16m80 , X86::ILD_F16m },
|
||||
{ X86::ILD_Fp32m32 , X86::ILD_F32m },
|
||||
{ X86::ILD_Fp32m64 , X86::ILD_F32m },
|
||||
{ X86::ILD_Fp32m80 , X86::ILD_F32m },
|
||||
{ X86::ILD_Fp64m32 , X86::ILD_F64m },
|
||||
{ X86::ILD_Fp64m64 , X86::ILD_F64m },
|
||||
{ X86::ILD_Fp64m80 , X86::ILD_F64m },
|
||||
{ X86::ISTT_Fp16m32 , X86::ISTT_FP16m},
|
||||
{ X86::ISTT_Fp16m64 , X86::ISTT_FP16m},
|
||||
{ X86::ISTT_Fp32m32 , X86::ISTT_FP32m},
|
||||
@ -381,50 +407,76 @@ static const TableEntry OpcodeTable[] = {
|
||||
{ X86::ISTT_Fp64m64 , X86::ISTT_FP64m},
|
||||
{ X86::IST_Fp16m32 , X86::IST_F16m },
|
||||
{ X86::IST_Fp16m64 , X86::IST_F16m },
|
||||
{ X86::IST_Fp16m80 , X86::IST_F16m },
|
||||
{ X86::IST_Fp32m32 , X86::IST_F32m },
|
||||
{ X86::IST_Fp32m64 , X86::IST_F32m },
|
||||
{ X86::IST_Fp32m80 , X86::IST_F32m },
|
||||
{ X86::IST_Fp64m32 , X86::IST_FP64m },
|
||||
{ X86::IST_Fp64m64 , X86::IST_FP64m },
|
||||
{ X86::IST_Fp64m80 , X86::IST_FP64m },
|
||||
{ X86::LD_Fp032 , X86::LD_F0 },
|
||||
{ X86::LD_Fp064 , X86::LD_F0 },
|
||||
{ X86::LD_Fp080 , X86::LD_F0 },
|
||||
{ X86::LD_Fp132 , X86::LD_F1 },
|
||||
{ X86::LD_Fp164 , X86::LD_F1 },
|
||||
{ X86::LD_Fp180 , X86::LD_F1 },
|
||||
{ X86::LD_Fp32m , X86::LD_F32m },
|
||||
{ X86::LD_Fp64m , X86::LD_F64m },
|
||||
{ X86::LD_Fp80m , X86::LD_F80m },
|
||||
{ X86::MUL_Fp32m , X86::MUL_F32m },
|
||||
{ X86::MUL_Fp64m , X86::MUL_F64m },
|
||||
{ X86::MUL_Fp64m32 , X86::MUL_F32m },
|
||||
{ X86::MUL_Fp80m32 , X86::MUL_F32m },
|
||||
{ X86::MUL_Fp80m64 , X86::MUL_F64m },
|
||||
{ X86::MUL_FpI16m32 , X86::MUL_FI16m },
|
||||
{ X86::MUL_FpI16m64 , X86::MUL_FI16m },
|
||||
{ X86::MUL_FpI16m80 , X86::MUL_FI16m },
|
||||
{ X86::MUL_FpI32m32 , X86::MUL_FI32m },
|
||||
{ X86::MUL_FpI32m64 , X86::MUL_FI32m },
|
||||
{ X86::MUL_FpI32m80 , X86::MUL_FI32m },
|
||||
{ X86::SIN_Fp32 , X86::SIN_F },
|
||||
{ X86::SIN_Fp64 , X86::SIN_F },
|
||||
{ X86::SIN_Fp80 , X86::SIN_F },
|
||||
{ X86::SQRT_Fp32 , X86::SQRT_F },
|
||||
{ X86::SQRT_Fp64 , X86::SQRT_F },
|
||||
{ X86::SQRT_Fp80 , X86::SQRT_F },
|
||||
{ X86::ST_Fp32m , X86::ST_F32m },
|
||||
{ X86::ST_Fp64m , X86::ST_F64m },
|
||||
{ X86::ST_Fp64m32 , X86::ST_F32m },
|
||||
{ X86::ST_Fp80m32 , X86::ST_F32m },
|
||||
{ X86::ST_Fp80m64 , X86::ST_F64m },
|
||||
{ X86::ST_FpP80m , X86::ST_FP80m },
|
||||
{ X86::SUBR_Fp32m , X86::SUBR_F32m },
|
||||
{ X86::SUBR_Fp64m , X86::SUBR_F64m },
|
||||
{ X86::SUBR_Fp64m32 , X86::SUBR_F32m },
|
||||
{ X86::SUBR_Fp80m32 , X86::SUBR_F32m },
|
||||
{ X86::SUBR_Fp80m64 , X86::SUBR_F64m },
|
||||
{ X86::SUBR_FpI16m32, X86::SUBR_FI16m},
|
||||
{ X86::SUBR_FpI16m64, X86::SUBR_FI16m},
|
||||
{ X86::SUBR_FpI16m80, X86::SUBR_FI16m},
|
||||
{ X86::SUBR_FpI32m32, X86::SUBR_FI32m},
|
||||
{ X86::SUBR_FpI32m64, X86::SUBR_FI32m},
|
||||
{ X86::SUBR_FpI32m80, X86::SUBR_FI32m},
|
||||
{ X86::SUB_Fp32m , X86::SUB_F32m },
|
||||
{ X86::SUB_Fp64m , X86::SUB_F64m },
|
||||
{ X86::SUB_Fp64m32 , X86::SUB_F32m },
|
||||
{ X86::SUB_Fp80m32 , X86::SUB_F32m },
|
||||
{ X86::SUB_Fp80m64 , X86::SUB_F64m },
|
||||
{ X86::SUB_FpI16m32 , X86::SUB_FI16m },
|
||||
{ X86::SUB_FpI16m64 , X86::SUB_FI16m },
|
||||
{ X86::SUB_FpI16m80 , X86::SUB_FI16m },
|
||||
{ X86::SUB_FpI32m32 , X86::SUB_FI32m },
|
||||
{ X86::SUB_FpI32m64 , X86::SUB_FI32m },
|
||||
{ X86::SUB_FpI32m80 , X86::SUB_FI32m },
|
||||
{ X86::TST_Fp32 , X86::TST_F },
|
||||
{ X86::TST_Fp64 , X86::TST_F },
|
||||
{ X86::TST_Fp80 , X86::TST_F },
|
||||
{ X86::UCOM_FpIr32 , X86::UCOM_FIr },
|
||||
{ X86::UCOM_FpIr64 , X86::UCOM_FIr },
|
||||
{ X86::UCOM_FpIr80 , X86::UCOM_FIr },
|
||||
{ X86::UCOM_Fpr32 , X86::UCOM_Fr },
|
||||
{ X86::UCOM_Fpr64 , X86::UCOM_Fr },
|
||||
{ X86::UCOM_Fpr80 , X86::UCOM_Fr },
|
||||
};
|
||||
|
||||
static unsigned getConcreteOpcode(unsigned Opcode) {
|
||||
@ -563,7 +615,8 @@ void FPS::handleOneArgFP(MachineBasicBlock::iterator &I) {
|
||||
MI->getOpcode() == X86::IST_Fp64m64 ||
|
||||
MI->getOpcode() == X86::ISTT_Fp16m64 ||
|
||||
MI->getOpcode() == X86::ISTT_Fp32m64 ||
|
||||
MI->getOpcode() == X86::ISTT_Fp64m64)) {
|
||||
MI->getOpcode() == X86::ISTT_Fp64m64 ||
|
||||
MI->getOpcode() == X86::ST_FpP80m)) {
|
||||
duplicateToTop(Reg, 7 /*temp register*/, I);
|
||||
} else {
|
||||
moveToTop(Reg, I); // Move to the top of the stack...
|
||||
@ -856,7 +909,12 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
|
||||
case X86::MOV_Fp3232:
|
||||
case X86::MOV_Fp3264:
|
||||
case X86::MOV_Fp6432:
|
||||
case X86::MOV_Fp6464: {
|
||||
case X86::MOV_Fp6464:
|
||||
case X86::MOV_Fp3280:
|
||||
case X86::MOV_Fp6480:
|
||||
case X86::MOV_Fp8032:
|
||||
case X86::MOV_Fp8064:
|
||||
case X86::MOV_Fp8080: {
|
||||
unsigned SrcReg = getFPReg(MI->getOperand(1));
|
||||
unsigned DestReg = getFPReg(MI->getOperand(0));
|
||||
|
||||
|
@ -322,6 +322,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
|
||||
addLegalFPImmediate(-1.0); // FLD1/FCHS
|
||||
}
|
||||
|
||||
// Long double always uses X87.
|
||||
addRegisterClass(MVT::f80, X86::RFP80RegisterClass);
|
||||
|
||||
// First set operation action for all vector types to expand. Then we
|
||||
// will selectively turn on ones that can be effectively codegen'd.
|
||||
for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
|
||||
|
@ -48,6 +48,10 @@ def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem,
|
||||
def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
|
||||
[SDNPHasChain]>;
|
||||
|
||||
def extloadf80f32 : PatFrag<(ops node:$ptr), (f80 (extloadf32 node:$ptr))>;
|
||||
def extloadf80f64 : PatFrag<(ops node:$ptr), (f80 (extloadf64 node:$ptr))>;
|
||||
def extloadf64f32 : PatFrag<(ops node:$ptr), (f64 (extloadf32 node:$ptr))>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FPStack pattern fragments
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -136,11 +140,16 @@ def FpSETRESULT64 : FpI_<(outs), (ins RFP64:$src), SpecialFP,
|
||||
class FpI<dag outs, dag ins, FPFormat fp, list<dag> pattern> :
|
||||
FpI_<outs, ins, fp, pattern>, Requires<[FPStack]>;
|
||||
|
||||
// Register copies. Just copies, the 64->32 version does not truncate.
|
||||
// Register copies. Just copies, the shortening ones do not truncate.
|
||||
def MOV_Fp3232 : FpI<(outs RFP32:$dst), (ins RFP32:$src), SpecialFP, []>;
|
||||
def MOV_Fp3264 : FpI<(outs RFP64:$dst), (ins RFP32:$src), SpecialFP, []>;
|
||||
def MOV_Fp6432 : FpI<(outs RFP32:$dst), (ins RFP64:$src), SpecialFP, []>;
|
||||
def MOV_Fp6464 : FpI<(outs RFP64:$dst), (ins RFP64:$src), SpecialFP, []>;
|
||||
def MOV_Fp8032 : FpI<(outs RFP32:$dst), (ins RFP80:$src), SpecialFP, []>;
|
||||
def MOV_Fp3280 : FpI<(outs RFP80:$dst), (ins RFP32:$src), SpecialFP, []>;
|
||||
def MOV_Fp8064 : FpI<(outs RFP64:$dst), (ins RFP80:$src), SpecialFP, []>;
|
||||
def MOV_Fp6480 : FpI<(outs RFP80:$dst), (ins RFP64:$src), SpecialFP, []>;
|
||||
def MOV_Fp8080 : FpI<(outs RFP80:$dst), (ins RFP80:$src), SpecialFP, []>;
|
||||
|
||||
// Factoring for arithmetic.
|
||||
multiclass FPBinary_rr<SDNode OpNode> {
|
||||
@ -150,9 +159,12 @@ def _Fp32 : FpI<(outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2), TwoArgFP,
|
||||
[(set RFP32:$dst, (OpNode RFP32:$src1, RFP32:$src2))]>;
|
||||
def _Fp64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2), TwoArgFP,
|
||||
[(set RFP64:$dst, (OpNode RFP64:$src1, RFP64:$src2))]>;
|
||||
def _Fp80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), TwoArgFP,
|
||||
[(set RFP80:$dst, (OpNode RFP80:$src1, RFP80:$src2))]>;
|
||||
}
|
||||
// The FopST0 series are not included here because of the irregularities
|
||||
// in where the 'r' goes in assembly output.
|
||||
// These instructions cannot address 80-bit memory.
|
||||
multiclass FPBinary<SDNode OpNode, Format fp, string asmstring> {
|
||||
// ST(0) = ST(0) + [mem]
|
||||
def _Fp32m : FpI<(outs RFP32:$dst), (ins RFP32:$src1, f32mem:$src2), OneArgFPRW,
|
||||
@ -163,7 +175,13 @@ def _Fp64m : FpI<(outs RFP64:$dst), (ins RFP64:$src1, f64mem:$src2), OneArgFPRW
|
||||
(OpNode RFP64:$src1, (loadf64 addr:$src2)))]>;
|
||||
def _Fp64m32: FpI<(outs RFP64:$dst), (ins RFP64:$src1, f32mem:$src2), OneArgFPRW,
|
||||
[(set RFP64:$dst,
|
||||
(OpNode RFP64:$src1, (extloadf32 addr:$src2)))]>;
|
||||
(OpNode RFP64:$src1, (extloadf64f32 addr:$src2)))]>;
|
||||
def _Fp80m32: FpI<(outs RFP80:$dst), (ins RFP80:$src1, f32mem:$src2), OneArgFPRW,
|
||||
[(set RFP80:$dst,
|
||||
(OpNode RFP80:$src1, (extloadf80f32 addr:$src2)))]>;
|
||||
def _Fp80m64: FpI<(outs RFP80:$dst), (ins RFP80:$src1, f64mem:$src2), OneArgFPRW,
|
||||
[(set RFP80:$dst,
|
||||
(OpNode RFP80:$src1, (extloadf80f64 addr:$src2)))]>;
|
||||
def _F32m : FPI<0xD8, fp, (outs), (ins f32mem:$src),
|
||||
!strconcat("f", !strconcat(asmstring, "{s}\t$src"))>;
|
||||
def _F64m : FPI<0xDC, fp, (outs), (ins f64mem:$src),
|
||||
@ -181,6 +199,12 @@ def _FpI16m64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, i16mem:$src2), OneArgFP
|
||||
def _FpI32m64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, i32mem:$src2), OneArgFPRW,
|
||||
[(set RFP64:$dst, (OpNode RFP64:$src1,
|
||||
(X86fild addr:$src2, i32)))]>;
|
||||
def _FpI16m80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, i16mem:$src2), OneArgFPRW,
|
||||
[(set RFP80:$dst, (OpNode RFP80:$src1,
|
||||
(X86fild addr:$src2, i16)))]>;
|
||||
def _FpI32m80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, i32mem:$src2), OneArgFPRW,
|
||||
[(set RFP80:$dst, (OpNode RFP80:$src1,
|
||||
(X86fild addr:$src2, i32)))]>;
|
||||
def _FI16m : FPI<0xDE, fp, (outs), (ins i16mem:$src),
|
||||
!strconcat("fi", !strconcat(asmstring, "{s}\t$src"))>;
|
||||
def _FI32m : FPI<0xDA, fp, (outs), (ins i32mem:$src),
|
||||
@ -233,6 +257,8 @@ def _Fp32 : FpI<(outs RFP32:$dst), (ins RFP32:$src), OneArgFPRW,
|
||||
[(set RFP32:$dst, (OpNode RFP32:$src))]>;
|
||||
def _Fp64 : FpI<(outs RFP64:$dst), (ins RFP64:$src), OneArgFPRW,
|
||||
[(set RFP64:$dst, (OpNode RFP64:$src))]>;
|
||||
def _Fp80 : FpI<(outs RFP80:$dst), (ins RFP80:$src), OneArgFPRW,
|
||||
[(set RFP80:$dst, (OpNode RFP80:$src))]>;
|
||||
def _F : FPI<opcode, RawFrm, (outs), (ins), asmstring>, D9;
|
||||
}
|
||||
|
||||
@ -246,6 +272,8 @@ def TST_Fp32 : FpI<(outs), (ins RFP32:$src), OneArgFP,
|
||||
[]>;
|
||||
def TST_Fp64 : FpI<(outs), (ins RFP64:$src), OneArgFP,
|
||||
[]>;
|
||||
def TST_Fp80 : FpI<(outs), (ins RFP80:$src), OneArgFP,
|
||||
[]>;
|
||||
def TST_F : FPI<0xE4, RawFrm, (outs), (ins), "ftst">, D9;
|
||||
|
||||
// Floating point cmovs.
|
||||
@ -256,6 +284,9 @@ multiclass FPCMov<PatLeaf cc> {
|
||||
def _Fp64 : FpI<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2), CondMovFP,
|
||||
[(set RFP64:$dst, (X86cmov RFP64:$src1, RFP64:$src2,
|
||||
cc))]>;
|
||||
def _Fp80 : FpI<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), CondMovFP,
|
||||
[(set RFP80:$dst, (X86cmov RFP80:$src1, RFP80:$src2,
|
||||
cc))]>;
|
||||
}
|
||||
let isTwoAddress = 1 in {
|
||||
defm CMOVB : FPCMov<X86_COND_B>;
|
||||
@ -291,6 +322,8 @@ def LD_Fp32m : FpI<(outs RFP32:$dst), (ins f32mem:$src), ZeroArgFP,
|
||||
[(set RFP32:$dst, (loadf32 addr:$src))]>;
|
||||
def LD_Fp64m : FpI<(outs RFP64:$dst), (ins f64mem:$src), ZeroArgFP,
|
||||
[(set RFP64:$dst, (loadf64 addr:$src))]>;
|
||||
def LD_Fp80m : FpI<(outs RFP80:$dst), (ins f80mem:$src), ZeroArgFP,
|
||||
[(set RFP80:$dst, (loadf80 addr:$src))]>;
|
||||
def ILD_Fp16m32: FpI<(outs RFP32:$dst), (ins i16mem:$src), ZeroArgFP,
|
||||
[(set RFP32:$dst, (X86fild addr:$src, i16))]>;
|
||||
def ILD_Fp32m32: FpI<(outs RFP32:$dst), (ins i32mem:$src), ZeroArgFP,
|
||||
@ -303,6 +336,12 @@ def ILD_Fp32m64: FpI<(outs RFP64:$dst), (ins i32mem:$src), ZeroArgFP,
|
||||
[(set RFP64:$dst, (X86fild addr:$src, i32))]>;
|
||||
def ILD_Fp64m64: FpI<(outs RFP64:$dst), (ins i64mem:$src), ZeroArgFP,
|
||||
[(set RFP64:$dst, (X86fild addr:$src, i64))]>;
|
||||
def ILD_Fp16m80: FpI<(outs RFP80:$dst), (ins i16mem:$src), ZeroArgFP,
|
||||
[(set RFP80:$dst, (X86fild addr:$src, i16))]>;
|
||||
def ILD_Fp32m80: FpI<(outs RFP80:$dst), (ins i32mem:$src), ZeroArgFP,
|
||||
[(set RFP80:$dst, (X86fild addr:$src, i32))]>;
|
||||
def ILD_Fp64m80: FpI<(outs RFP80:$dst), (ins i64mem:$src), ZeroArgFP,
|
||||
[(set RFP80:$dst, (X86fild addr:$src, i64))]>;
|
||||
|
||||
def ST_Fp32m : FpI<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP,
|
||||
[(store RFP32:$src, addr:$op)]>;
|
||||
@ -310,19 +349,32 @@ def ST_Fp64m32 : FpI<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP,
|
||||
[(truncstoref32 RFP64:$src, addr:$op)]>;
|
||||
def ST_Fp64m : FpI<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP,
|
||||
[(store RFP64:$src, addr:$op)]>;
|
||||
def ST_Fp80m32 : FpI<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP,
|
||||
[(truncstoref32 RFP80:$src, addr:$op)]>;
|
||||
def ST_Fp80m64 : FpI<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP,
|
||||
[(truncstoref64 RFP80:$src, addr:$op)]>;
|
||||
// FST does not support 80-bit memory target; FSTP must be used.
|
||||
|
||||
def ST_FpP32m : FpI<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP, []>;
|
||||
def ST_FpP64m32 : FpI<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, []>;
|
||||
def ST_FpP64m : FpI<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP, []>;
|
||||
def ST_FpP80m32 : FpI<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def ST_FpP80m64 : FpI<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def ST_FpP80m : FpI<(outs), (ins f80mem:$op, RFP80:$src), OneArgFP,
|
||||
[(store RFP80:$src, addr:$op)]>;
|
||||
def IST_Fp16m32 : FpI<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, []>;
|
||||
def IST_Fp32m32 : FpI<(outs), (ins i32mem:$op, RFP32:$src), OneArgFP, []>;
|
||||
def IST_Fp64m32 : FpI<(outs), (ins i64mem:$op, RFP32:$src), OneArgFP, []>;
|
||||
def IST_Fp16m64 : FpI<(outs), (ins i16mem:$op, RFP64:$src), OneArgFP, []>;
|
||||
def IST_Fp32m64 : FpI<(outs), (ins i32mem:$op, RFP64:$src), OneArgFP, []>;
|
||||
def IST_Fp64m64 : FpI<(outs), (ins i64mem:$op, RFP64:$src), OneArgFP, []>;
|
||||
def IST_Fp16m80 : FpI<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def IST_Fp32m80 : FpI<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
def IST_Fp64m80 : FpI<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, []>;
|
||||
|
||||
def LD_F32m : FPI<0xD9, MRM0m, (outs), (ins f32mem:$src), "fld{s}\t$src">;
|
||||
def LD_F64m : FPI<0xDD, MRM0m, (outs), (ins f64mem:$src), "fld{l}\t$src">;
|
||||
def LD_F80m : FPI<0xDB, MRM5m, (outs), (ins f80mem:$src), "fld{t}\t$src">;
|
||||
def ILD_F16m : FPI<0xDF, MRM0m, (outs), (ins i16mem:$src), "fild{s}\t$src">;
|
||||
def ILD_F32m : FPI<0xDB, MRM0m, (outs), (ins i32mem:$src), "fild{l}\t$src">;
|
||||
def ILD_F64m : FPI<0xDF, MRM5m, (outs), (ins i64mem:$src), "fild{ll}\t$src">;
|
||||
@ -330,6 +382,7 @@ def ST_F32m : FPI<0xD9, MRM2m, (outs), (ins f32mem:$dst), "fst{s}\t$dst">;
|
||||
def ST_F64m : FPI<0xDD, MRM2m, (outs), (ins f64mem:$dst), "fst{l}\t$dst">;
|
||||
def ST_FP32m : FPI<0xD9, MRM3m, (outs), (ins f32mem:$dst), "fstp{s}\t$dst">;
|
||||
def ST_FP64m : FPI<0xDD, MRM3m, (outs), (ins f64mem:$dst), "fstp{l}\t$dst">;
|
||||
def ST_FP80m : FPI<0xDB, MRM7m, (outs), (ins f80mem:$dst), "fstp{t}\t$dst">;
|
||||
def IST_F16m : FPI<0xDF, MRM2m, (outs), (ins i16mem:$dst), "fist{s}\t$dst">;
|
||||
def IST_F32m : FPI<0xDB, MRM2m, (outs), (ins i32mem:$dst), "fist{l}\t$dst">;
|
||||
def IST_FP16m : FPI<0xDF, MRM3m, (outs), (ins i16mem:$dst), "fistp{s}\t$dst">;
|
||||
@ -376,6 +429,10 @@ def LD_Fp064 : FpI<(outs RFP64:$dst), (ins), ZeroArgFP,
|
||||
[(set RFP64:$dst, fpimm0)]>;
|
||||
def LD_Fp164 : FpI<(outs RFP64:$dst), (ins), ZeroArgFP,
|
||||
[(set RFP64:$dst, fpimm1)]>;
|
||||
def LD_Fp080 : FpI<(outs RFP80:$dst), (ins), ZeroArgFP,
|
||||
[(set RFP80:$dst, fpimm0)]>;
|
||||
def LD_Fp180 : FpI<(outs RFP80:$dst), (ins), ZeroArgFP,
|
||||
[(set RFP80:$dst, fpimm1)]>;
|
||||
}
|
||||
|
||||
def LD_F0 : FPI<0xEE, RawFrm, (outs), (ins), "fldz">, D9;
|
||||
@ -391,6 +448,10 @@ def UCOM_Fpr64 : FpI<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP,
|
||||
[]>; // FPSW = cmp ST(0) with ST(i)
|
||||
def UCOM_FpIr64: FpI<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP,
|
||||
[(X86cmp RFP64:$lhs, RFP64:$rhs)]>; // CC = ST(0) cmp ST(i)
|
||||
def UCOM_Fpr80 : FpI<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP,
|
||||
[]>; // FPSW = cmp ST(0) with ST(i)
|
||||
def UCOM_FpIr80: FpI<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP,
|
||||
[(X86cmp RFP80:$lhs, RFP80:$rhs)]>; // CC = ST(0) cmp ST(i)
|
||||
|
||||
def UCOM_Fr : FPI<0xE0, AddRegFrm, // FPSW = cmp ST(0) with ST(i)
|
||||
(outs), (ins RST:$reg),
|
||||
@ -425,6 +486,7 @@ def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
|
||||
// Required for RET of f32 / f64 values.
|
||||
def : Pat<(X86fld addr:$src, f32), (LD_Fp32m addr:$src)>;
|
||||
def : Pat<(X86fld addr:$src, f64), (LD_Fp64m addr:$src)>;
|
||||
def : Pat<(X86fld addr:$src, f80), (LD_Fp80m addr:$src)>;
|
||||
|
||||
// Required for CALL which return f32 / f64 values.
|
||||
def : Pat<(X86fst RFP32:$src, addr:$op, f32), (ST_Fp32m addr:$op, RFP32:$src)>;
|
||||
@ -436,10 +498,19 @@ def : Pat<(f32 fpimmneg0), (CHS_Fp32 (LD_Fp032))>, Requires<[FPStack]>;
|
||||
def : Pat<(f32 fpimmneg1), (CHS_Fp32 (LD_Fp132))>, Requires<[FPStack]>;
|
||||
def : Pat<(f64 fpimmneg0), (CHS_Fp64 (LD_Fp064))>, Requires<[FPStack]>;
|
||||
def : Pat<(f64 fpimmneg1), (CHS_Fp64 (LD_Fp164))>, Requires<[FPStack]>;
|
||||
def : Pat<(f80 fpimmneg0), (CHS_Fp80 (LD_Fp080))>, Requires<[FPStack]>;
|
||||
def : Pat<(f80 fpimmneg1), (CHS_Fp80 (LD_Fp180))>, Requires<[FPStack]>;
|
||||
|
||||
// Used to conv. i64 to f64 since there isn't a SSE version.
|
||||
def : Pat<(X86fildflag addr:$src, i64), (ILD_Fp64m64 addr:$src)>;
|
||||
|
||||
def : Pat<(extloadf32 addr:$src),
|
||||
def : Pat<(extloadf80f32 addr:$src),
|
||||
(MOV_Fp3280 (LD_Fp32m addr:$src))>, Requires<[FPStack]>;
|
||||
def : Pat<(extloadf80f64 addr:$src),
|
||||
(MOV_Fp6480 (LD_Fp64m addr:$src))>, Requires<[FPStack]>;
|
||||
def : Pat<(extloadf64f32 addr:$src),
|
||||
(MOV_Fp3264 (LD_Fp32m addr:$src))>, Requires<[FPStack]>;
|
||||
def : Pat<(fextend RFP32:$src), (MOV_Fp3264 RFP32:$src)>, Requires<[FPStack]>;
|
||||
|
||||
def : Pat<(f64 (fextend RFP32:$src)), (MOV_Fp3264 RFP32:$src)>, Requires<[FPStack]>;
|
||||
def : Pat<(f80 (fextend RFP32:$src)), (MOV_Fp3280 RFP32:$src)>, Requires<[FPStack]>;
|
||||
def : Pat<(f80 (fextend RFP64:$src)), (MOV_Fp6480 RFP64:$src)>, Requires<[FPStack]>;
|
||||
|
@ -119,6 +119,7 @@ def i64mem : X86MemOperand<"printi64mem">;
|
||||
def i128mem : X86MemOperand<"printi128mem">;
|
||||
def f32mem : X86MemOperand<"printf32mem">;
|
||||
def f64mem : X86MemOperand<"printf64mem">;
|
||||
def f80mem : X86MemOperand<"printf80mem">;
|
||||
def f128mem : X86MemOperand<"printf128mem">;
|
||||
|
||||
def lea32mem : Operand<i32> {
|
||||
@ -216,6 +217,7 @@ def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
|
||||
|
||||
def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
|
||||
def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
|
||||
def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
|
||||
|
||||
def sextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (sextloadi1 node:$ptr))>;
|
||||
def sextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (sextloadi1 node:$ptr))>;
|
||||
|
@ -76,6 +76,10 @@ struct X86IntelAsmPrinter : public X86SharedAsmPrinter {
|
||||
O << "QWORD PTR ";
|
||||
printMemReference(MI, OpNo);
|
||||
}
|
||||
void printf80mem(const MachineInstr *MI, unsigned OpNo) {
|
||||
O << "XWORD PTR ";
|
||||
printMemReference(MI, OpNo);
|
||||
}
|
||||
void printf128mem(const MachineInstr *MI, unsigned OpNo) {
|
||||
O << "XMMWORD PTR ";
|
||||
printMemReference(MI, OpNo);
|
||||
|
@ -476,6 +476,7 @@ def FR64 : RegisterClass<"X86", [f64], 64,
|
||||
|
||||
def RFP32 : RegisterClass<"X86", [f32], 32, [FP0, FP1, FP2, FP3, FP4, FP5, FP6]>;
|
||||
def RFP64 : RegisterClass<"X86", [f64], 32, [FP0, FP1, FP2, FP3, FP4, FP5, FP6]>;
|
||||
def RFP80 : RegisterClass<"X86", [f80], 32, [FP0, FP1, FP2, FP3, FP4, FP5, FP6]>;
|
||||
|
||||
// Floating point stack registers (these are not allocatable by the
|
||||
// register allocator - the floating point stackifier is responsible
|
||||
|
Loading…
Reference in New Issue
Block a user