Newer
Older
[(set V2F8:$dst, (sint_to_fp R32:$src))]>, XD;
def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops V2F8:$dst, i32mem:$src),
def SQRTSSrm : I<0x51, MRMSrcMem, (ops V4F4:$dst, f32mem:$src),
def SQRTSSrr : I<0x51, MRMSrcReg, (ops V4F4:$dst, V4F4:$src),
"sqrtss {$src, $dst|$dst, $src}",
[(set V4F4:$dst, (fsqrt V4F4:$src))]>, XS;
def SQRTSDrm : I<0x51, MRMSrcMem, (ops V2F8:$dst, f64mem:$src),
def SQRTSDrr : I<0x51, MRMSrcReg, (ops V2F8:$dst, V2F8:$src),
"sqrtsd {$src, $dst|$dst, $src}",
[(set V2F8:$dst, (fsqrt V2F8:$src))]>, XD;
def UCOMISDrr: I<0x2E, MRMSrcReg, (ops V2F8:$dst, V2F8:$src),
"ucomisd {$src, $dst|$dst, $src}", []>, TB, OpSize;
def UCOMISDrm: I<0x2E, MRMSrcMem, (ops V2F8:$dst, f64mem:$src),
"ucomisd {$src, $dst|$dst, $src}", []>, TB, OpSize;
def UCOMISSrr: I<0x2E, MRMSrcReg, (ops V4F4:$dst, V4F4:$src),
def UCOMISSrm: I<0x2E, MRMSrcMem, (ops V4F4:$dst, f32mem:$src),
// Pseudo-instructions that map fld0 to xorps/xorpd for sse.
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
def FLD0SS : I<0x57, MRMSrcReg, (ops V4F4:$dst),
def FLD0SD : I<0x57, MRMSrcReg, (ops V2F8:$dst),
let isTwoAddress = 1 in {
let isCommutable = 1 in {
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
def ADDSSrr : I<0x58, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
"addss {$src2, $dst|$dst, $src2}",
[(set V4F4:$dst, (fadd V4F4:$src1, V4F4:$src2))]>, XS;
def ADDSDrr : I<0x58, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
"addsd {$src2, $dst|$dst, $src2}",
[(set V2F8:$dst, (fadd V2F8:$src1, V2F8:$src2))]>, XD;
def ANDPSrr : I<0x54, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
"andps {$src2, $dst|$dst, $src2}", []>, TB;
def ANDPDrr : I<0x54, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
"andpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
def MULSSrr : I<0x59, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
"mulss {$src2, $dst|$dst, $src2}",
[(set V4F4:$dst, (fmul V4F4:$src1, V4F4:$src2))]>, XS;
def MULSDrr : I<0x59, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
"mulsd {$src2, $dst|$dst, $src2}",
[(set V2F8:$dst, (fmul V2F8:$src1, V2F8:$src2))]>, XD;
def ORPSrr : I<0x56, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
"orps {$src2, $dst|$dst, $src2}", []>, TB;
def ORPDrr : I<0x56, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
"orpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
def XORPSrr : I<0x57, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
"xorps {$src2, $dst|$dst, $src2}", []>, TB;
def XORPDrr : I<0x57, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
"xorpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
}
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
def ANDNPSrr : I<0x55, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
"andnps {$src2, $dst|$dst, $src2}", []>, TB;
def ANDNPDrr : I<0x55, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
"andnpd {$src2, $dst|$dst, $src2}", []>, TB, OpSize;
def ADDSSrm : I<0x58, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src2),
"addss {$src2, $dst|$dst, $src2}", []>, XS;
def ADDSDrm : I<0x58, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src2),
"addsd {$src2, $dst|$dst, $src2}", []>, XD;
def MULSSrm : I<0x59, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src2),
"mulss {$src2, $dst|$dst, $src2}", []>, XS;
def MULSDrm : I<0x59, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src2),
"mulsd {$src2, $dst|$dst, $src2}", []>, XD;
def DIVSSrm : I<0x5E, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src2),
"divss {$src2, $dst|$dst, $src2}", []>, XS;
def DIVSSrr : I<0x5E, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
"divss {$src2, $dst|$dst, $src2}",
[(set V4F4:$dst, (fdiv V4F4:$src1, V4F4:$src2))]>, XS;
def DIVSDrm : I<0x5E, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src2),
"divsd {$src2, $dst|$dst, $src2}", []>, XD;
def DIVSDrr : I<0x5E, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
"divsd {$src2, $dst|$dst, $src2}",
[(set V2F8:$dst, (fdiv V2F8:$src1, V2F8:$src2))]>, XD;
def SUBSSrm : I<0x5C, MRMSrcMem, (ops V4F4:$dst, V4F4:$src1, f32mem:$src2),
"subss {$src2, $dst|$dst, $src2}", []>, XS;
def SUBSSrr : I<0x5C, MRMSrcReg, (ops V4F4:$dst, V4F4:$src1, V4F4:$src2),
"subss {$src2, $dst|$dst, $src2}",
[(set V4F4:$dst, (fsub V4F4:$src1, V4F4:$src2))]>, XS;
def SUBSDrm : I<0x5C, MRMSrcMem, (ops V2F8:$dst, V2F8:$src1, f64mem:$src2),
"subsd {$src2, $dst|$dst, $src2}", []>, XD;
def SUBSDrr : I<0x5C, MRMSrcReg, (ops V2F8:$dst, V2F8:$src1, V2F8:$src2),
"subsd {$src2, $dst|$dst, $src2}",
[(set V2F8:$dst, (fsub V2F8:$src1, V2F8:$src2))]>, XD;
def CMPSSrr : I<0xC2, MRMSrcReg,
(ops V4F4:$dst, V4F4:$src1, V4F4:$src, SSECC:$cc),
"cmp${cc}ss {$src, $dst|$dst, $src}", []>, XS;
def CMPSSrm : I<0xC2, MRMSrcMem,
(ops V4F4:$dst, V4F4:$src1, f32mem:$src, SSECC:$cc),
"cmp${cc}ss {$src, $dst|$dst, $src}", []>, XS;
def CMPSDrr : I<0xC2, MRMSrcReg,
(ops V2F8:$dst, V2F8:$src1, V2F8:$src, SSECC:$cc),
"cmp${cc}sd {$src, $dst|$dst, $src}", []>, XD;
def CMPSDrm : I<0xC2, MRMSrcMem,
(ops V2F8:$dst, V2F8:$src1, f64mem:$src, SSECC:$cc),
"cmp${cc}sd {$src, $dst|$dst, $src}", []>, XD;
}
//===----------------------------------------------------------------------===//
// Miscellaneous Instructions
//===----------------------------------------------------------------------===//
def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", []>, TB, Imp<[],[EAX,EDX]>;
//===----------------------------------------------------------------------===//
// Stack-based Floating point support
//===----------------------------------------------------------------------===//
// FIXME: These need to indicate mod/ref sets for FP regs... & FP 'TOP'
// Floating point instruction template
class FPI<bits<8> o, Format F, FPFormat fp, dag ops, string asm>
: X86Inst<o, F, NoImm, ops, asm> {
let FPForm = fp; let FPFormBits = FPForm.Value;
}
// Pseudo instructions for floating point. We use these pseudo instructions
// because they can be expanded by the fp spackifier into one of many different
// forms of instructions for doing these operations. Until the stackifier runs,
// we prefer to be abstract.
def FpMOV : FPI<0, Pseudo, SpecialFP,
def FpADD : FPI<0, Pseudo, TwoArgFP ,
(ops RFP:$dst, RFP:$src1, RFP:$src2), "">; // f1 = fadd f2, f3
def FpSUB : FPI<0, Pseudo, TwoArgFP ,
(ops RFP:$dst, RFP:$src1, RFP:$src2), "">; // f1 = fsub f2, f3
def FpMUL : FPI<0, Pseudo, TwoArgFP ,
(ops RFP:$dst, RFP:$src1, RFP:$src2), "">; // f1 = fmul f2, f3
def FpDIV : FPI<0, Pseudo, TwoArgFP ,
(ops RFP:$dst, RFP:$src1, RFP:$src2), "">; // f1 = fdiv f2, f3
def FpGETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$dst), "">,
Imp<[ST0], []>; // FPR = ST(0)
def FpSETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$src), "">,
Imp<[], [ST0]>; // ST(0) = FPR
// FADD reg, mem: Before stackification, these are represented by:
// R1 = FADD* R2, [mem]
def FADD32m : FPI<0xD8, MRM0m, OneArgFPRW, // ST(0) = ST(0) + [mem32real]
(ops f32mem:$src, variable_ops),
"fadd{s} $src">;
def FADD64m : FPI<0xDC, MRM0m, OneArgFPRW, // ST(0) = ST(0) + [mem64real]
(ops f64mem:$src, variable_ops),
"fadd{l} $src">;
//def FIADD16m : FPI<0xDE, MRM0m, OneArgFPRW>; // ST(0) = ST(0) + [mem16int]
//def FIADD32m : FPI<0xDA, MRM0m, OneArgFPRW>; // ST(0) = ST(0) + [mem32int]
// FMUL reg, mem: Before stackification, these are represented by:
// R1 = FMUL* R2, [mem]
def FMUL32m : FPI<0xD8, MRM1m, OneArgFPRW, // ST(0) = ST(0) * [mem32real]
(ops f32mem:$src, variable_ops),
"fmul{s} $src">;
def FMUL64m : FPI<0xDC, MRM1m, OneArgFPRW, // ST(0) = ST(0) * [mem64real]
(ops f64mem:$src, variable_ops),
"fmul{l} $src">;
// ST(0) = ST(0) * [mem16int]
//def FIMUL16m : FPI16m<"fimul", 0xDE, MRM1m, OneArgFPRW>;
// ST(0) = ST(0) * [mem32int]
//def FIMUL32m : FPI32m<"fimul", 0xDA, MRM1m, OneArgFPRW>;
// FSUB reg, mem: Before stackification, these are represented by:
// R1 = FSUB* R2, [mem]
def FSUB32m : FPI<0xD8, MRM4m, OneArgFPRW, // ST(0) = ST(0) - [mem32real]
(ops f32mem:$src, variable_ops),
"fsub{s} $src">;
def FSUB64m : FPI<0xDC, MRM4m, OneArgFPRW, // ST(0) = ST(0) - [mem64real]
(ops f64mem:$src, variable_ops),
"fsub{l} $src">;
// ST(0) = ST(0) - [mem16int]
//def FISUB16m : FPI16m<"fisub", 0xDE, MRM4m, OneArgFPRW>;
// ST(0) = ST(0) - [mem32int]
//def FISUB32m : FPI32m<"fisub", 0xDA, MRM4m, OneArgFPRW>;
// FSUBR reg, mem: Before stackification, these are represented by:
// R1 = FSUBR* R2, [mem]
// Note that the order of operands does not reflect the operation being
// performed.
def FSUBR32m : FPI<0xD8, MRM5m, OneArgFPRW, // ST(0) = [mem32real] - ST(0)
(ops f32mem:$src, variable_ops),
"fsubr{s} $src">;
def FSUBR64m : FPI<0xDC, MRM5m, OneArgFPRW, // ST(0) = [mem64real] - ST(0)
(ops f64mem:$src, variable_ops),
"fsubr{l} $src">;
// ST(0) = [mem16int] - ST(0)
//def FISUBR16m : FPI16m<"fisubr", 0xDE, MRM5m, OneArgFPRW>;
// ST(0) = [mem32int] - ST(0)
//def FISUBR32m : FPI32m<"fisubr", 0xDA, MRM5m, OneArgFPRW>;
// FDIV reg, mem: Before stackification, these are represented by:
// R1 = FDIV* R2, [mem]
def FDIV32m : FPI<0xD8, MRM6m, OneArgFPRW, // ST(0) = ST(0) / [mem32real]
(ops f32mem:$src, variable_ops),
"fdiv{s} $src">;
def FDIV64m : FPI<0xDC, MRM6m, OneArgFPRW, // ST(0) = ST(0) / [mem64real]
(ops f64mem:$src, variable_ops),
"fdiv{l} $src">;
// ST(0) = ST(0) / [mem16int]
//def FIDIV16m : FPI16m<"fidiv", 0xDE, MRM6m, OneArgFPRW>;
// ST(0) = ST(0) / [mem32int]
//def FIDIV32m : FPI32m<"fidiv", 0xDA, MRM6m, OneArgFPRW>;
// FDIVR reg, mem: Before stackification, these are represented by:
// R1 = FDIVR* R2, [mem]
// Note that the order of operands does not reflect the operation being
// performed.
def FDIVR32m : FPI<0xD8, MRM7m, OneArgFPRW, // ST(0) = [mem32real] / ST(0)
(ops f32mem:$src, variable_ops),
"fdivr{s} $src">;
def FDIVR64m : FPI<0xDC, MRM7m, OneArgFPRW, // ST(0) = [mem64real] / ST(0)
(ops f64mem:$src, variable_ops),
"fdivr{l} $src">;
// ST(0) = [mem16int] / ST(0)
//def FIDIVR16m : FPI16m<"fidivr", 0xDE, MRM7m, OneArgFPRW>;
// ST(0) = [mem32int] / ST(0)
//def FIDIVR32m : FPI32m<"fidivr", 0xDA, MRM7m, OneArgFPRW>;
Chris Lattner
committed
// Floating point cmovs...
let isTwoAddress = 1, Uses = [ST0], Defs = [ST0] in {
def FCMOVB : FPI<0xC0, AddRegFrm, CondMovFP,
(ops RST:$op, variable_ops),
"fcmovb {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVBE : FPI<0xD0, AddRegFrm, CondMovFP,
(ops RST:$op, variable_ops),
"fcmovbe {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVE : FPI<0xC8, AddRegFrm, CondMovFP,
(ops RST:$op, variable_ops),
"fcmove {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVP : FPI<0xD8, AddRegFrm, CondMovFP,
(ops RST:$op, variable_ops),
"fcmovu {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVAE : FPI<0xC0, AddRegFrm, CondMovFP,
(ops RST:$op, variable_ops),
"fcmovae {$op, %ST(0)|%ST(0), $op}">, DB;
def FCMOVA : FPI<0xD0, AddRegFrm, CondMovFP,
(ops RST:$op, variable_ops),
"fcmova {$op, %ST(0)|%ST(0), $op}">, DB;
def FCMOVNE : FPI<0xC8, AddRegFrm, CondMovFP,
(ops RST:$op, variable_ops),
"fcmovne {$op, %ST(0)|%ST(0), $op}">, DB;
def FCMOVNP : FPI<0xD8, AddRegFrm, CondMovFP,
(ops RST:$op, variable_ops),
"fcmovnu {$op, %ST(0)|%ST(0), $op}">, DB;
Chris Lattner
committed
}
// Floating point loads & stores...
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
// FIXME: these are all marked variable_ops because they have an implicit
// destination. Instructions like FILD* that are generated by the instruction
// selector (not the fp stackifier) need more accurate operand accounting.
def FLDrr : FPI<0xC0, AddRegFrm, NotFP,
(ops RST:$src, variable_ops),
"fld $src">, D9;
def FLD32m : FPI<0xD9, MRM0m, ZeroArgFP,
(ops f32mem:$src, variable_ops),
"fld{s} $src">;
def FLD64m : FPI<0xDD, MRM0m, ZeroArgFP,
(ops f64mem:$src, variable_ops),
"fld{l} $src">;
def FLD80m : FPI<0xDB, MRM5m, ZeroArgFP,
(ops f80mem:$src, variable_ops),
"fld{t} $src">;
def FILD16m : FPI<0xDF, MRM0m, ZeroArgFP,
(ops i16mem:$src, variable_ops),
"fild{s} $src">;
def FILD32m : FPI<0xDB, MRM0m, ZeroArgFP,
(ops i32mem:$src, variable_ops),
"fild{l} $src">;
def FILD64m : FPI<0xDF, MRM5m, ZeroArgFP,
(ops i64mem:$src, variable_ops),
"fild{ll} $src">;
def FSTrr : FPI<0xD0, AddRegFrm, NotFP,
(ops RST:$op, variable_ops),
"fst $op">, DD;
def FSTPrr : FPI<0xD8, AddRegFrm, NotFP,
(ops RST:$op, variable_ops),
"fstp $op">, DD;
def FST32m : FPI<0xD9, MRM2m, OneArgFP,
(ops f32mem:$op, variable_ops),
"fst{s} $op">;
def FST64m : FPI<0xDD, MRM2m, OneArgFP,
(ops f64mem:$op, variable_ops),
"fst{l} $op">;
def FSTP32m : FPI<0xD9, MRM3m, OneArgFP,
(ops f32mem:$op, variable_ops),
"fstp{s} $op">;
def FSTP64m : FPI<0xDD, MRM3m, OneArgFP,
(ops f64mem:$op, variable_ops),
"fstp{l} $op">;
def FSTP80m : FPI<0xDB, MRM7m, OneArgFP,
(ops f80mem:$op, variable_ops),
"fstp{t} $op">;
def FIST16m : FPI<0xDF, MRM2m , OneArgFP,
(ops i16mem:$op, variable_ops),
"fist{s} $op">;
def FIST32m : FPI<0xDB, MRM2m , OneArgFP,
(ops i32mem:$op, variable_ops),
"fist{l} $op">;
def FISTP16m : FPI<0xDF, MRM3m , NotFP ,
(ops i16mem:$op, variable_ops),
"fistp{s} $op">;
def FISTP32m : FPI<0xDB, MRM3m , NotFP ,
(ops i32mem:$op, variable_ops),
"fistp{l} $op">;
def FISTP64m : FPI<0xDF, MRM7m , OneArgFP,
(ops i64mem:$op, variable_ops),
"fistp{ll} $op">;
def FXCH : FPI<0xC8, AddRegFrm, NotFP,
(ops RST:$op), "fxch $op">, D9; // fxch ST(i), ST(0)
// Floating point constant loads...
def FLD0 : FPI<0xEE, RawFrm, ZeroArgFP, (ops variable_ops), "fldz">, D9;
def FLD1 : FPI<0xE8, RawFrm, ZeroArgFP, (ops variable_ops), "fld1">, D9;
def FCHS : FPI<0xE0, RawFrm, OneArgFPRW, // f1 = fchs f2
(ops variable_ops),
"fchs">, D9;
def FABS : FPI<0xE1, RawFrm, OneArgFPRW, // f1 = fabs f2
(ops variable_ops),
"fabs">, D9;
def FSQRT : FPI<0xFA, RawFrm, OneArgFPRW, // fsqrt ST(0)
(ops variable_ops),
"fsqrt">, D9;
def FSIN : FPI<0xFE, RawFrm, OneArgFPRW, // fsin ST(0)
(ops variable_ops),
"fsin">, D9;
def FCOS : FPI<0xFF, RawFrm, OneArgFPRW, // fcos ST(0)
(ops variable_ops),
"fcos">, D9;
def FTST : FPI<0xE4, RawFrm, OneArgFP , // ftst ST(0)
(ops variable_ops),
"ftst">, D9;
// Binary arithmetic operations...
class FPST0rInst<bits<8> o, dag ops, string asm>
list<Register> Uses = [ST0];
list<Register> Defs = [ST0];
}
class FPrST0Inst<bits<8> o, dag ops, string asm>
list<Register> Uses = [ST0];
}
class FPrST0PInst<bits<8> o, dag ops, string asm>
list<Register> Uses = [ST0];
}
def FADDST0r : FPST0rInst <0xC0, (ops RST:$op),
"fadd $op">;
def FADDrST0 : FPrST0Inst <0xC0, (ops RST:$op),
"fadd {%ST(0), $op|$op, %ST(0)}">;
def FADDPrST0 : FPrST0PInst<0xC0, (ops RST:$op),
"faddp $op">;
// NOTE: GAS and apparently all other AT&T style assemblers have a broken notion
// of some of the 'reverse' forms of the fsub and fdiv instructions. As such,
// we have to put some 'r's in and take them out of weird places.
def FSUBRST0r : FPST0rInst <0xE8, (ops RST:$op),
"fsubr $op">;
def FSUBrST0 : FPrST0Inst <0xE8, (ops RST:$op),
"fsub{r} {%ST(0), $op|$op, %ST(0)}">;
def FSUBPrST0 : FPrST0PInst<0xE8, (ops RST:$op),
"fsub{r}p $op">;
def FSUBST0r : FPST0rInst <0xE0, (ops RST:$op),
"fsub $op">;
def FSUBRrST0 : FPrST0Inst <0xE0, (ops RST:$op),
"fsub{|r} {%ST(0), $op|$op, %ST(0)}">;
def FSUBRPrST0 : FPrST0PInst<0xE0, (ops RST:$op),
"fsub{|r}p $op">;
def FMULST0r : FPST0rInst <0xC8, (ops RST:$op),
"fmul $op">;
def FMULrST0 : FPrST0Inst <0xC8, (ops RST:$op),
"fmul {%ST(0), $op|$op, %ST(0)}">;
def FMULPrST0 : FPrST0PInst<0xC8, (ops RST:$op),
"fmulp $op">;
def FDIVRST0r : FPST0rInst <0xF8, (ops RST:$op),
"fdivr $op">;
def FDIVrST0 : FPrST0Inst <0xF8, (ops RST:$op),
"fdiv{r} {%ST(0), $op|$op, %ST(0)}">;
def FDIVPrST0 : FPrST0PInst<0xF8, (ops RST:$op),
"fdiv{r}p $op">;
def FDIVST0r : FPST0rInst <0xF0, (ops RST:$op), // ST(0) = ST(0) / ST(i)
"fdiv $op">;
def FDIVRrST0 : FPrST0Inst <0xF0, (ops RST:$op), // ST(i) = ST(0) / ST(i)
"fdiv{|r} {%ST(0), $op|$op, %ST(0)}">;
def FDIVRPrST0 : FPrST0PInst<0xF0, (ops RST:$op), // ST(i) = ST(0) / ST(i), pop
"fdiv{|r}p $op">;
// Floating point compares
def FUCOMr : FPI<0xE0, AddRegFrm, CompareFP, // FPSW = cmp ST(0) with ST(i)
(ops RST:$reg, variable_ops),
"fucom $reg">, DD, Imp<[ST0],[]>;
def FUCOMPr : I<0xE8, AddRegFrm, // FPSW = cmp ST(0) with ST(i), pop
(ops RST:$reg, variable_ops),
def FUCOMPPr : I<0xE9, RawFrm, // cmp ST(0) with ST(1), pop, pop
(ops variable_ops),
def FUCOMIr : FPI<0xE8, AddRegFrm, CompareFP, // CC = cmp ST(0) with ST(i)
(ops RST:$reg, variable_ops),
"fucomi {$reg, %ST(0)|%ST(0), $reg}">, DB, Imp<[ST0],[]>;
def FUCOMIPr : I<0xE8, AddRegFrm, // CC = cmp ST(0) with ST(i), pop
(ops RST:$reg, variable_ops),
"fucomip {$reg, %ST(0)|%ST(0), $reg}", []>, DF, Imp<[ST0],[]>;
def FNSTSW8r : I<0xE0, RawFrm, // AX = fp flags
def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world
def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]