Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
def IMUL32rri : Ii32<0x69, MRMSrcReg, // R32 = R32*I32
(ops R32:$dst, R32:$src1, i32imm:$src2),
"imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}">;
def IMUL16rri8 : Ii8<0x6B, MRMSrcReg, // R16 = R16*I8
(ops R16:$dst, R16:$src1, i8imm:$src2),
"imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}">, OpSize;
def IMUL32rri8 : Ii8<0x6B, MRMSrcReg, // R32 = R32*I8
(ops R32:$dst, R32:$src1, i8imm:$src2),
"imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}">;
def IMUL16rmi : Ii16<0x69, MRMSrcMem, // R16 = [mem16]*I16
(ops R32:$dst, i16mem:$src1, i16imm:$src2),
"imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}">, OpSize;
def IMUL32rmi : Ii32<0x69, MRMSrcMem, // R32 = [mem32]*I32
(ops R32:$dst, i32mem:$src1, i32imm:$src2),
"imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}">;
def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem, // R16 = [mem16]*I8
(ops R32:$dst, i16mem:$src1, i8imm :$src2),
"imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}">, OpSize;
def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // R32 = [mem32]*I8
(ops R32:$dst, i32mem:$src1, i8imm: $src2),
"imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}">;
//===----------------------------------------------------------------------===//
// Test instructions are just like AND, except they don't generate a result.
//
Chris Lattner
committed
def TEST8rr : I<0x84, MRMDestReg, (ops R8:$src1, R8:$src2),
"test{b} {$src2, $src1|$src1, $src2}">;
Chris Lattner
committed
def TEST16rr : I<0x85, MRMDestReg, (ops R16:$src1, R16:$src2),
"test{w} {$src2, $src1|$src1, $src2}">, OpSize;
Chris Lattner
committed
def TEST32rr : I<0x85, MRMDestReg, (ops R32:$src1, R32:$src2),
"test{l} {$src2, $src1|$src1, $src2}">;
Chris Lattner
committed
def TEST8mr : I<0x84, MRMDestMem, (ops i8mem :$src1, R8 :$src2),
"test{b} {$src2, $src1|$src1, $src2}">;
Chris Lattner
committed
def TEST16mr : I<0x85, MRMDestMem, (ops i16mem:$src1, R16:$src2),
"test{w} {$src2, $src1|$src1, $src2}">, OpSize;
Chris Lattner
committed
def TEST32mr : I<0x85, MRMDestMem, (ops i32mem:$src1, R32:$src2),
"test{l} {$src2, $src1|$src1, $src2}">;
Chris Lattner
committed
def TEST8rm : I<0x84, MRMSrcMem, (ops R8 :$src1, i8mem :$src2),
"test{b} {$src2, $src1|$src1, $src2}">;
Chris Lattner
committed
def TEST16rm : I<0x85, MRMSrcMem, (ops R16:$src1, i16mem:$src2),
"test{w} {$src2, $src1|$src1, $src2}">, OpSize;
Chris Lattner
committed
def TEST32rm : I<0x85, MRMSrcMem, (ops R32:$src1, i32mem:$src2),
"test{l} {$src2, $src1|$src1, $src2}">;
def TEST8ri : Ii8 <0xF6, MRM0r, // flags = R8 & imm8
(ops R8:$src1, i8imm:$src2),
"test{b} {$src2, $src1|$src1, $src2}">;
def TEST16ri : Ii16<0xF7, MRM0r, // flags = R16 & imm16
(ops R16:$src1, i16imm:$src2),
"test{w} {$src2, $src1|$src1, $src2}">, OpSize;
def TEST32ri : Ii32<0xF7, MRM0r, // flags = R32 & imm32
(ops R32:$src1, i32imm:$src2),
"test{l} {$src2, $src1|$src1, $src2}">;
def TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8
(ops i32mem:$src1, i8imm:$src2),
"test{b} {$src2, $src1|$src1, $src2}">;
def TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16
(ops i16mem:$src1, i16imm:$src2),
"test{w} {$src2, $src1|$src1, $src2}">, OpSize;
def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32
(ops i32mem:$src1, i32imm:$src2),
"test{l} {$src2, $src1|$src1, $src2}">;
// Condition code ops, incl. set if equal/not equal/...
Chris Lattner
committed
def SAHF : I<0x9E, RawFrm, (ops), "sahf">, Imp<[AH],[]>; // flags = AH
def LAHF : I<0x9F, RawFrm, (ops), "lahf">, Imp<[],[AH]>; // AH = flags
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
def SETBr : I<0x92, MRM0r,
(ops R8 :$dst), "setb $dst">, TB; // R8 = < unsign
def SETBm : I<0x92, MRM0m,
(ops i8mem:$dst), "setb $dst">, TB; // [mem8] = < unsign
def SETAEr : I<0x93, MRM0r,
(ops R8 :$dst), "setae $dst">, TB; // R8 = >= unsign
def SETAEm : I<0x93, MRM0m,
(ops i8mem:$dst), "setae $dst">, TB; // [mem8] = >= unsign
def SETEr : I<0x94, MRM0r,
(ops R8 :$dst), "sete $dst">, TB; // R8 = ==
def SETEm : I<0x94, MRM0m,
(ops i8mem:$dst), "sete $dst">, TB; // [mem8] = ==
def SETNEr : I<0x95, MRM0r,
(ops R8 :$dst), "setne $dst">, TB; // R8 = !=
def SETNEm : I<0x95, MRM0m,
(ops i8mem:$dst), "setne $dst">, TB; // [mem8] = !=
def SETBEr : I<0x96, MRM0r,
(ops R8 :$dst), "setbe $dst">, TB; // R8 = <= unsign
def SETBEm : I<0x96, MRM0m,
(ops i8mem:$dst), "setbe $dst">, TB; // [mem8] = <= unsign
def SETAr : I<0x97, MRM0r,
(ops R8 :$dst), "seta $dst">, TB; // R8 = > signed
def SETAm : I<0x97, MRM0m,
(ops i8mem:$dst), "seta $dst">, TB; // [mem8] = > signed
def SETSr : I<0x98, MRM0r,
(ops R8 :$dst), "sets $dst">, TB; // R8 = <sign bit>
def SETSm : I<0x98, MRM0m,
(ops i8mem:$dst), "sets $dst">, TB; // [mem8] = <sign bit>
def SETNSr : I<0x99, MRM0r,
(ops R8 :$dst), "setns $dst">, TB; // R8 = !<sign bit>
def SETNSm : I<0x99, MRM0m,
(ops i8mem:$dst), "setns $dst">, TB; // [mem8] = !<sign bit>
def SETPr : I<0x9A, MRM0r,
(ops R8 :$dst), "setp $dst">, TB; // R8 = parity
def SETPm : I<0x9A, MRM0m,
(ops i8mem:$dst), "setp $dst">, TB; // [mem8] = parity
def SETLr : I<0x9C, MRM0r,
(ops R8 :$dst), "setl $dst">, TB; // R8 = < signed
def SETLm : I<0x9C, MRM0m,
(ops i8mem:$dst), "setl $dst">, TB; // [mem8] = < signed
def SETGEr : I<0x9D, MRM0r,
(ops R8 :$dst), "setge $dst">, TB; // R8 = >= signed
def SETGEm : I<0x9D, MRM0m,
(ops i8mem:$dst), "setge $dst">, TB; // [mem8] = >= signed
def SETLEr : I<0x9E, MRM0r,
(ops R8 :$dst), "setle $dst">, TB; // R8 = <= signed
def SETLEm : I<0x9E, MRM0m,
(ops i8mem:$dst), "setle $dst">, TB; // [mem8] = <= signed
def SETGr : I<0x9F, MRM0r,
(ops R8 :$dst), "setg $dst">, TB; // R8 = < signed
def SETGm : I<0x9F, MRM0m,
(ops i8mem:$dst), "setg $dst">, TB; // [mem8] = < signed
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
def CMP8rr : I<0x38, MRMDestReg,
(ops R8 :$src1, R8 :$src2),
"cmp{b} {$src2, $src1|$src1, $src2}">;
def CMP16rr : I<0x39, MRMDestReg,
(ops R16:$src1, R16:$src2),
"cmp{w} {$src2, $src1|$src1, $src2}">, OpSize;
def CMP32rr : I<0x39, MRMDestReg,
(ops R32:$src1, R32:$src2),
"cmp{l} {$src2, $src1|$src1, $src2}">;
def CMP8mr : I<0x38, MRMDestMem,
(ops i8mem :$src1, R8 :$src2),
"cmp{b} {$src2, $src1|$src1, $src2}">;
def CMP16mr : I<0x39, MRMDestMem,
(ops i16mem:$src1, R16:$src2),
"cmp{w} {$src2, $src1|$src1, $src2}">, OpSize;
def CMP32mr : I<0x39, MRMDestMem,
(ops i32mem:$src1, R32:$src2),
"cmp{l} {$src2, $src1|$src1, $src2}">;
def CMP8rm : I<0x3A, MRMSrcMem,
(ops R8 :$src1, i8mem :$src2),
"cmp{b} {$src2, $src1|$src1, $src2}">;
def CMP16rm : I<0x3B, MRMSrcMem,
(ops R16:$src1, i16mem:$src2),
"cmp{w} {$src2, $src1|$src1, $src2}">, OpSize;
def CMP32rm : I<0x3B, MRMSrcMem,
(ops R32:$src1, i32mem:$src2),
"cmp{l} {$src2, $src1|$src1, $src2}">;
def CMP8ri : Ii8<0x80, MRM7r,
(ops R16:$src1, i8imm:$src2),
"cmp{b} {$src2, $src1|$src1, $src2}">;
def CMP16ri : Ii16<0x81, MRM7r,
(ops R16:$src1, i16imm:$src2),
"cmp{w} {$src2, $src1|$src1, $src2}">, OpSize;
def CMP32ri : Ii32<0x81, MRM7r,
(ops R32:$src1, i32imm:$src2),
"cmp{l} {$src2, $src1|$src1, $src2}">;
def CMP8mi : Ii8 <0x80, MRM7m,
(ops i8mem :$src1, i8imm :$src2),
"cmp{b} {$src2, $src1|$src1, $src2}">;
def CMP16mi : Ii16<0x81, MRM7m,
(ops i16mem:$src1, i16imm:$src2),
"cmp{w} {$src2, $src1|$src1, $src2}">, OpSize;
def CMP32mi : Ii32<0x81, MRM7m,
(ops i32mem:$src1, i32imm:$src2),
"cmp{l} {$src2, $src1|$src1, $src2}">;
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
def MOVSX16rr8 : I<0xBE, MRMSrcReg, (ops R16:$dst, R8 :$src),
"movs{bw|x} {$src, $dst|$dst, $src}">, TB, OpSize;
def MOVSX16rm8 : I<0xBE, MRMSrcMem, (ops R16:$dst, i8mem :$src),
"movs{bw|x} {$src, $dst|$dst, $src}">, TB, OpSize;
def MOVSX32rr8 : I<0xBE, MRMSrcReg, (ops R32:$dst, R8 :$src),
"movs{bl|x} {$src, $dst|$dst, $src}">, TB;
def MOVSX32rm8 : I<0xBE, MRMSrcMem, (ops R32:$dst, i8mem :$src),
"movs{bl|x} {$src, $dst|$dst, $src}">, TB;
def MOVSX32rr16: I<0xBF, MRMSrcReg, (ops R32:$dst, R16:$src),
"movs{wl|x} {$src, $dst|$dst, $src}">, TB;
def MOVSX32rm16: I<0xBF, MRMSrcMem, (ops R32:$dst, i16mem:$src),
"movs{wl|x} {$src, $dst|$dst, $src}">, TB;
def MOVZX16rr8 : I<0xB6, MRMSrcReg, (ops R16:$dst, R8 :$src),
"movz{bw|x} {$src, $dst|$dst, $src}">, TB, OpSize;
def MOVZX16rm8 : I<0xB6, MRMSrcMem, (ops R16:$dst, i8mem :$src),
"movz{bw|x} {$src, $dst|$dst, $src}">, TB, OpSize;
def MOVZX32rr8 : I<0xB6, MRMSrcReg, (ops R32:$dst, R8 :$src),
"movz{bl|x} {$src, $dst|$dst, $src}">, TB;
def MOVZX32rm8 : I<0xB6, MRMSrcMem, (ops R32:$dst, i8mem :$src),
"movz{bl|x} {$src, $dst|$dst, $src}">, TB;
def MOVZX32rr16: I<0xB7, MRMSrcReg, (ops R32:$dst, R16:$src),
"movz{wl|x} {$src, $dst|$dst, $src}">, TB;
def MOVZX32rm16: I<0xB7, MRMSrcMem, (ops R32:$dst, i16mem:$src),
"movz{wl|x} {$src, $dst|$dst, $src}">, TB;
//===----------------------------------------------------------------------===//
// 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,
(ops RFP, RFP), "">; // f1 = fmov f2
def FpADD : FPI<0, Pseudo, TwoArgFP ,
(ops RFP, RFP, RFP), "">; // f1 = fadd f2, f3
def FpSUB : FPI<0, Pseudo, TwoArgFP ,
(ops RFP, RFP, RFP), "">; // f1 = fsub f2, f3
def FpMUL : FPI<0, Pseudo, TwoArgFP ,
(ops RFP, RFP, RFP), "">; // f1 = fmul f2, f3
def FpDIV : FPI<0, Pseudo, TwoArgFP ,
(ops RFP, RFP, RFP), "">; // f1 = fdiv f2, f3
def FpGETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP), "">,
Imp<[ST0], []>; // FPR = ST(0)
def FpSETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP), "">,
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), "fadd{s} $src">;
def FADD64m : FPI<0xDC, MRM0m, OneArgFPRW, // ST(0) = ST(0) + [mem64real]
(ops f64mem:$src), "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), "fmul{s} $src">;
def FMUL64m : FPI<0xDC, MRM1m, OneArgFPRW, // ST(0) = ST(0) * [mem64real]
(ops f64mem:$src), "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), "fsub{s} $src">;
def FSUB64m : FPI<0xDC, MRM4m, OneArgFPRW, // ST(0) = ST(0) - [mem64real]
(ops f64mem:$src), "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), "fsubr{s} $src">;
def FSUBR64m : FPI<0xDC, MRM5m, OneArgFPRW, // ST(0) = [mem64real] - ST(0)
(ops f64mem:$src), "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), "fdiv{s} $src">;
def FDIV64m : FPI<0xDC, MRM6m, OneArgFPRW, // ST(0) = ST(0) / [mem64real]
(ops f64mem:$src), "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), "fdivr{s} $src">;
def FDIVR64m : FPI<0xDC, MRM7m, OneArgFPRW, // ST(0) = [mem64real] / ST(0)
(ops f64mem:$src), "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), "fcmovb {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVBE : FPI<0xD0, AddRegFrm, CondMovFP,
(ops RST:$op), "fcmovbe {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVE : FPI<0xC8, AddRegFrm, CondMovFP,
(ops RST:$op), "fcmove {$op, %ST(0)|%ST(0), $op}">, DA;
def FCMOVAE : FPI<0xC0, AddRegFrm, CondMovFP,
(ops RST:$op), "fcmovae {$op, %ST(0)|%ST(0), $op}">, DB;
def FCMOVA : FPI<0xD0, AddRegFrm, CondMovFP,
(ops RST:$op), "fcmova {$op, %ST(0)|%ST(0), $op}">, DB;
def FCMOVNE : FPI<0xC8, AddRegFrm, CondMovFP,
(ops RST:$op), "fcmovne {$op, %ST(0)|%ST(0), $op}">, DB;
Chris Lattner
committed
}
// Floating point loads & stores...
def FLDrr : FPI<0xC0, AddRegFrm, NotFP, (ops RST:$src), "fld $src">, D9;
def FLD32m : FPI<0xD9, MRM0m, ZeroArgFP, (ops f32mem:$src), "fld{s} $src">;
def FLD64m : FPI<0xDD, MRM0m, ZeroArgFP, (ops f64mem:$src), "fld{l} $src">;
def FLD80m : FPI<0xDB, MRM5m, ZeroArgFP, (ops f80mem:$src), "fld{t} $src">;
def FILD16m : FPI<0xDF, MRM0m, ZeroArgFP, (ops i16mem:$src), "fild{s} $src">;
def FILD32m : FPI<0xDB, MRM0m, ZeroArgFP, (ops i32mem:$src), "fild{l} $src">;
def FILD64m : FPI<0xDF, MRM5m, ZeroArgFP, (ops i64mem:$src), "fild{t} $src">;
def FSTrr : FPI<0xD0, AddRegFrm, NotFP, (ops RST:$op), "fst $op">, DD;
def FSTPrr : FPI<0xD8, AddRegFrm, NotFP, (ops RST:$op), "fstp $op">, DD;
def FST32m : FPI<0xD9, MRM2m, OneArgFP, (ops f32mem:$op), "fst{s} $op">;
def FST64m : FPI<0xDD, MRM2m, OneArgFP, (ops f64mem:$op), "fst{l} $op">;
def FSTP32m : FPI<0xD9, MRM3m, OneArgFP, (ops f32mem:$op), "fstp{s} $op">;
def FSTP64m : FPI<0xDD, MRM3m, OneArgFP, (ops f64mem:$op), "fstp{l} $op">;
def FSTP80m : FPI<0xDB, MRM7m, OneArgFP, (ops f80mem:$op), "fstp{t} $op">;
def FIST16m : FPI<0xDF, MRM2m , OneArgFP, (ops i16mem:$op), "fist{s} $op">;
def FIST32m : FPI<0xDB, MRM2m , OneArgFP, (ops i32mem:$op), "fist{l} $op">;
def FISTP16m : FPI<0xDF, MRM3m , NotFP , (ops i16mem:$op), "fistp{s} $op">;
def FISTP32m : FPI<0xDB, MRM3m , NotFP , (ops i32mem:$op), "fistp{l} $op">;
def FISTP64m : FPI<0xDF, MRM7m , OneArgFP, (ops i64mem:$op), "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), "fldz">, D9;
def FLD1 : FPI<0xE8, RawFrm, ZeroArgFP, (ops), "fld1">, D9;
def FCHS : FPI<0xE0, RawFrm, OneArgFPRW, (ops), "fchs">, D9; // f1 = fchs f2
def FTST : FPI<0xE4, RawFrm, OneArgFP, (ops), "ftst">, D9; // ftst ST(0)
// Binary arithmetic operations...
class FPST0rInst<bits<8> o, dag ops, string asm>
: I<o, AddRegFrm, ops, asm>, D8 {
list<Register> Uses = [ST0];
list<Register> Defs = [ST0];
}
class FPrST0Inst<bits<8> o, dag ops, string asm>
: I<o, AddRegFrm, ops, asm>, DC {
list<Register> Uses = [ST0];
}
class FPrST0PInst<bits<8> o, dag ops, string asm>
: I<o, AddRegFrm, ops, asm>, DE {
list<Register> Uses = [ST0];
}
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
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">;
def FSUBRST0r : FPST0rInst <0xE8, (ops RST:$op),
"fsubr $op">;
def FSUBrST0 : FPrST0Inst <0xE8, (ops RST:$op),
"fsub {%ST(0), $op|$op, %ST(0)}">;
def FSUBPrST0 : FPrST0PInst<0xE8, (ops RST:$op),
"fsubp $op">;
def FSUBST0r : FPST0rInst <0xE0, (ops RST:$op),
"fsub $op">;
def FSUBRrST0 : FPrST0Inst <0xE0, (ops RST:$op),
"fsubr {%ST(0), $op|$op, %ST(0)}">;
def FSUBRPrST0 : FPrST0PInst<0xE0, (ops RST:$op),
"fsubrp $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 {%ST(0), $op|$op, %ST(0)}">;
def FDIVPrST0 : FPrST0PInst<0xF8, (ops RST:$op),
"fdivp $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)
"fdivr {%ST(0), $op|$op, %ST(0)}">;
def FDIVRPrST0 : FPrST0PInst<0xF0, (ops RST:$op), // ST(i) = ST(0) / ST(i), pop
"fdivrp $op">;
// Floating point compares
def FUCOMr : FPI<0xE0, AddRegFrm, CompareFP, // FPSW = cmp ST(0) with ST(i)
(ops RST:$reg),
"fucom $reg">, DD, Imp<[ST0],[]>;
def FUCOMPr : I<0xE8, AddRegFrm,
(ops RST:$reg), // FPSW = cmp ST(0) with ST(i), pop
"fucomp $reg">, DD, Imp<[ST0],[]>;
def FUCOMPPr : I<0xE9, RawFrm,
(ops), // cmp ST(0) with ST(1), pop, pop
"fucompp">, DA, Imp<[ST0],[]>;
def FUCOMIr : FPI<0xE8, AddRegFrm, CompareFP, // CC = cmp ST(0) with ST(i)
(ops RST:$reg),
"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),
"fucomip {$reg, %ST(0)|%ST(0), $reg}">, DF, Imp<[ST0],[]>;
def FNSTSW8r : I<0xE0, RawFrm, // AX = fp flags
(ops), "fnstsw">, DF, Imp<[],[AX]>;
def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world
(ops i16mem:$dst), "fnstcw $dst">;
def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
(ops i16mem:$dst), "fldcw $dst">;