Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/Target/X86/X86InstrFPStack.td @ 0:95c75e76d11b
LLVM 3.4
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 12 Dec 2013 13:56:28 +0900 |
parents | |
children | 54457678186b |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:95c75e76d11b |
---|---|
1 //===- X86InstrFPStack.td - FPU Instruction Set ------------*- tablegen -*-===// | |
2 // | |
3 // The LLVM Compiler Infrastructure | |
4 // | |
5 // This file is distributed under the University of Illinois Open Source | |
6 // License. See LICENSE.TXT for details. | |
7 // | |
8 //===----------------------------------------------------------------------===// | |
9 // | |
10 // This file describes the X86 x87 FPU instruction set, defining the | |
11 // instructions, and properties of the instructions which are needed for code | |
12 // generation, machine code emission, and analysis. | |
13 // | |
14 //===----------------------------------------------------------------------===// | |
15 | |
16 //===----------------------------------------------------------------------===// | |
17 // FPStack specific DAG Nodes. | |
18 //===----------------------------------------------------------------------===// | |
19 | |
20 def SDTX86FpGet2 : SDTypeProfile<2, 0, [SDTCisVT<0, f80>, | |
21 SDTCisVT<1, f80>]>; | |
22 def SDTX86Fld : SDTypeProfile<1, 2, [SDTCisFP<0>, | |
23 SDTCisPtrTy<1>, | |
24 SDTCisVT<2, OtherVT>]>; | |
25 def SDTX86Fst : SDTypeProfile<0, 3, [SDTCisFP<0>, | |
26 SDTCisPtrTy<1>, | |
27 SDTCisVT<2, OtherVT>]>; | |
28 def SDTX86Fild : SDTypeProfile<1, 2, [SDTCisFP<0>, SDTCisPtrTy<1>, | |
29 SDTCisVT<2, OtherVT>]>; | |
30 def SDTX86Fnstsw : SDTypeProfile<1, 1, [SDTCisVT<0, i16>, SDTCisVT<1, i16>]>; | |
31 def SDTX86FpToIMem : SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisPtrTy<1>]>; | |
32 | |
33 def SDTX86CwdStore : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; | |
34 | |
35 def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, | |
36 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; | |
37 def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, | |
38 [SDNPHasChain, SDNPInGlue, SDNPMayStore, | |
39 SDNPMemOperand]>; | |
40 def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild, | |
41 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; | |
42 def X86fildflag : SDNode<"X86ISD::FILD_FLAG", SDTX86Fild, | |
43 [SDNPHasChain, SDNPOutGlue, SDNPMayLoad, | |
44 SDNPMemOperand]>; | |
45 def X86fp_stsw : SDNode<"X86ISD::FNSTSW16r", SDTX86Fnstsw>; | |
46 def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem, | |
47 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; | |
48 def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem, | |
49 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; | |
50 def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem, | |
51 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; | |
52 def X86fp_cwd_get16 : SDNode<"X86ISD::FNSTCW16m", SDTX86CwdStore, | |
53 [SDNPHasChain, SDNPMayStore, SDNPSideEffect, | |
54 SDNPMemOperand]>; | |
55 | |
56 //===----------------------------------------------------------------------===// | |
57 // FPStack pattern fragments | |
58 //===----------------------------------------------------------------------===// | |
59 | |
60 def fpimm0 : PatLeaf<(fpimm), [{ | |
61 return N->isExactlyValue(+0.0); | |
62 }]>; | |
63 | |
64 def fpimmneg0 : PatLeaf<(fpimm), [{ | |
65 return N->isExactlyValue(-0.0); | |
66 }]>; | |
67 | |
68 def fpimm1 : PatLeaf<(fpimm), [{ | |
69 return N->isExactlyValue(+1.0); | |
70 }]>; | |
71 | |
72 def fpimmneg1 : PatLeaf<(fpimm), [{ | |
73 return N->isExactlyValue(-1.0); | |
74 }]>; | |
75 | |
76 // Some 'special' instructions | |
77 let usesCustomInserter = 1 in { // Expanded after instruction selection. | |
78 def FP32_TO_INT16_IN_MEM : PseudoI<(outs), (ins i16mem:$dst, RFP32:$src), | |
79 [(X86fp_to_i16mem RFP32:$src, addr:$dst)]>; | |
80 def FP32_TO_INT32_IN_MEM : PseudoI<(outs), (ins i32mem:$dst, RFP32:$src), | |
81 [(X86fp_to_i32mem RFP32:$src, addr:$dst)]>; | |
82 def FP32_TO_INT64_IN_MEM : PseudoI<(outs), (ins i64mem:$dst, RFP32:$src), | |
83 [(X86fp_to_i64mem RFP32:$src, addr:$dst)]>; | |
84 def FP64_TO_INT16_IN_MEM : PseudoI<(outs), (ins i16mem:$dst, RFP64:$src), | |
85 [(X86fp_to_i16mem RFP64:$src, addr:$dst)]>; | |
86 def FP64_TO_INT32_IN_MEM : PseudoI<(outs), (ins i32mem:$dst, RFP64:$src), | |
87 [(X86fp_to_i32mem RFP64:$src, addr:$dst)]>; | |
88 def FP64_TO_INT64_IN_MEM : PseudoI<(outs), (ins i64mem:$dst, RFP64:$src), | |
89 [(X86fp_to_i64mem RFP64:$src, addr:$dst)]>; | |
90 def FP80_TO_INT16_IN_MEM : PseudoI<(outs), (ins i16mem:$dst, RFP80:$src), | |
91 [(X86fp_to_i16mem RFP80:$src, addr:$dst)]>; | |
92 def FP80_TO_INT32_IN_MEM : PseudoI<(outs), (ins i32mem:$dst, RFP80:$src), | |
93 [(X86fp_to_i32mem RFP80:$src, addr:$dst)]>; | |
94 def FP80_TO_INT64_IN_MEM : PseudoI<(outs), (ins i64mem:$dst, RFP80:$src), | |
95 [(X86fp_to_i64mem RFP80:$src, addr:$dst)]>; | |
96 } | |
97 | |
98 // All FP Stack operations are represented with four instructions here. The | |
99 // first three instructions, generated by the instruction selector, use "RFP32" | |
100 // "RFP64" or "RFP80" registers: traditional register files to reference 32-bit, | |
101 // 64-bit or 80-bit floating point values. These sizes apply to the values, | |
102 // not the registers, which are always 80 bits; RFP32, RFP64 and RFP80 can be | |
103 // copied to each other without losing information. These instructions are all | |
104 // pseudo instructions and use the "_Fp" suffix. | |
105 // In some cases there are additional variants with a mixture of different | |
106 // register sizes. | |
107 // The second instruction is defined with FPI, which is the actual instruction | |
108 // emitted by the assembler. These use "RST" registers, although frequently | |
109 // the actual register(s) used are implicit. These are always 80 bits. | |
110 // The FP stackifier pass converts one to the other after register allocation | |
111 // occurs. | |
112 // | |
113 // Note that the FpI instruction should have instruction selection info (e.g. | |
114 // a pattern) and the FPI instruction should have emission info (e.g. opcode | |
115 // encoding and asm printing info). | |
116 | |
117 // Pseudo Instruction for FP stack return values. | |
118 def FpPOP_RETVAL : FpI_<(outs RFP80:$dst), (ins), SpecialFP, []>; | |
119 | |
120 // FpIf32, FpIf64 - Floating Point Pseudo Instruction template. | |
121 // f32 instructions can use SSE1 and are predicated on FPStackf32 == !SSE1. | |
122 // f64 instructions can use SSE2 and are predicated on FPStackf64 == !SSE2. | |
123 // f80 instructions cannot use SSE and use neither of these. | |
124 class FpIf32<dag outs, dag ins, FPFormat fp, list<dag> pattern> : | |
125 FpI_<outs, ins, fp, pattern>, Requires<[FPStackf32]>; | |
126 class FpIf64<dag outs, dag ins, FPFormat fp, list<dag> pattern> : | |
127 FpI_<outs, ins, fp, pattern>, Requires<[FPStackf64]>; | |
128 | |
129 // Factoring for arithmetic. | |
130 multiclass FPBinary_rr<SDNode OpNode> { | |
131 // Register op register -> register | |
132 // These are separated out because they have no reversed form. | |
133 def _Fp32 : FpIf32<(outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2), TwoArgFP, | |
134 [(set RFP32:$dst, (OpNode RFP32:$src1, RFP32:$src2))]>; | |
135 def _Fp64 : FpIf64<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2), TwoArgFP, | |
136 [(set RFP64:$dst, (OpNode RFP64:$src1, RFP64:$src2))]>; | |
137 def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), TwoArgFP, | |
138 [(set RFP80:$dst, (OpNode RFP80:$src1, RFP80:$src2))]>; | |
139 } | |
140 // The FopST0 series are not included here because of the irregularities | |
141 // in where the 'r' goes in assembly output. | |
142 // These instructions cannot address 80-bit memory. | |
143 multiclass FPBinary<SDNode OpNode, Format fp, string asmstring> { | |
144 // ST(0) = ST(0) + [mem] | |
145 def _Fp32m : FpIf32<(outs RFP32:$dst), | |
146 (ins RFP32:$src1, f32mem:$src2), OneArgFPRW, | |
147 [(set RFP32:$dst, | |
148 (OpNode RFP32:$src1, (loadf32 addr:$src2)))]>; | |
149 def _Fp64m : FpIf64<(outs RFP64:$dst), | |
150 (ins RFP64:$src1, f64mem:$src2), OneArgFPRW, | |
151 [(set RFP64:$dst, | |
152 (OpNode RFP64:$src1, (loadf64 addr:$src2)))]>; | |
153 def _Fp64m32: FpIf64<(outs RFP64:$dst), | |
154 (ins RFP64:$src1, f32mem:$src2), OneArgFPRW, | |
155 [(set RFP64:$dst, | |
156 (OpNode RFP64:$src1, (f64 (extloadf32 addr:$src2))))]>; | |
157 def _Fp80m32: FpI_<(outs RFP80:$dst), | |
158 (ins RFP80:$src1, f32mem:$src2), OneArgFPRW, | |
159 [(set RFP80:$dst, | |
160 (OpNode RFP80:$src1, (f80 (extloadf32 addr:$src2))))]>; | |
161 def _Fp80m64: FpI_<(outs RFP80:$dst), | |
162 (ins RFP80:$src1, f64mem:$src2), OneArgFPRW, | |
163 [(set RFP80:$dst, | |
164 (OpNode RFP80:$src1, (f80 (extloadf64 addr:$src2))))]>; | |
165 def _F32m : FPI<0xD8, fp, (outs), (ins f32mem:$src), | |
166 !strconcat("f", asmstring, "{s}\t$src")> { | |
167 let mayLoad = 1; | |
168 } | |
169 def _F64m : FPI<0xDC, fp, (outs), (ins f64mem:$src), | |
170 !strconcat("f", asmstring, "{l}\t$src")> { | |
171 let mayLoad = 1; | |
172 } | |
173 // ST(0) = ST(0) + [memint] | |
174 def _FpI16m32 : FpIf32<(outs RFP32:$dst), (ins RFP32:$src1, i16mem:$src2), | |
175 OneArgFPRW, | |
176 [(set RFP32:$dst, (OpNode RFP32:$src1, | |
177 (X86fild addr:$src2, i16)))]>; | |
178 def _FpI32m32 : FpIf32<(outs RFP32:$dst), (ins RFP32:$src1, i32mem:$src2), | |
179 OneArgFPRW, | |
180 [(set RFP32:$dst, (OpNode RFP32:$src1, | |
181 (X86fild addr:$src2, i32)))]>; | |
182 def _FpI16m64 : FpIf64<(outs RFP64:$dst), (ins RFP64:$src1, i16mem:$src2), | |
183 OneArgFPRW, | |
184 [(set RFP64:$dst, (OpNode RFP64:$src1, | |
185 (X86fild addr:$src2, i16)))]>; | |
186 def _FpI32m64 : FpIf64<(outs RFP64:$dst), (ins RFP64:$src1, i32mem:$src2), | |
187 OneArgFPRW, | |
188 [(set RFP64:$dst, (OpNode RFP64:$src1, | |
189 (X86fild addr:$src2, i32)))]>; | |
190 def _FpI16m80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, i16mem:$src2), | |
191 OneArgFPRW, | |
192 [(set RFP80:$dst, (OpNode RFP80:$src1, | |
193 (X86fild addr:$src2, i16)))]>; | |
194 def _FpI32m80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, i32mem:$src2), | |
195 OneArgFPRW, | |
196 [(set RFP80:$dst, (OpNode RFP80:$src1, | |
197 (X86fild addr:$src2, i32)))]>; | |
198 def _FI16m : FPI<0xDE, fp, (outs), (ins i16mem:$src), | |
199 !strconcat("fi", asmstring, "{s}\t$src")> { | |
200 let mayLoad = 1; | |
201 } | |
202 def _FI32m : FPI<0xDA, fp, (outs), (ins i32mem:$src), | |
203 !strconcat("fi", asmstring, "{l}\t$src")> { | |
204 let mayLoad = 1; | |
205 } | |
206 } | |
207 | |
208 let Defs = [FPSW] in { | |
209 defm ADD : FPBinary_rr<fadd>; | |
210 defm SUB : FPBinary_rr<fsub>; | |
211 defm MUL : FPBinary_rr<fmul>; | |
212 defm DIV : FPBinary_rr<fdiv>; | |
213 defm ADD : FPBinary<fadd, MRM0m, "add">; | |
214 defm SUB : FPBinary<fsub, MRM4m, "sub">; | |
215 defm SUBR: FPBinary<fsub ,MRM5m, "subr">; | |
216 defm MUL : FPBinary<fmul, MRM1m, "mul">; | |
217 defm DIV : FPBinary<fdiv, MRM6m, "div">; | |
218 defm DIVR: FPBinary<fdiv, MRM7m, "divr">; | |
219 } | |
220 | |
221 class FPST0rInst<bits<8> o, string asm> | |
222 : FPI<o, AddRegFrm, (outs), (ins RST:$op), asm>, D8; | |
223 class FPrST0Inst<bits<8> o, string asm> | |
224 : FPI<o, AddRegFrm, (outs), (ins RST:$op), asm>, DC; | |
225 class FPrST0PInst<bits<8> o, string asm> | |
226 : FPI<o, AddRegFrm, (outs), (ins RST:$op), asm>, DE; | |
227 | |
228 // NOTE: GAS and apparently all other AT&T style assemblers have a broken notion | |
229 // of some of the 'reverse' forms of the fsub and fdiv instructions. As such, | |
230 // we have to put some 'r's in and take them out of weird places. | |
231 def ADD_FST0r : FPST0rInst <0xC0, "fadd\t$op">; | |
232 def ADD_FrST0 : FPrST0Inst <0xC0, "fadd\t{%st(0), $op|$op, st(0)}">; | |
233 def ADD_FPrST0 : FPrST0PInst<0xC0, "faddp\t$op">; | |
234 def SUBR_FST0r : FPST0rInst <0xE8, "fsubr\t$op">; | |
235 def SUB_FrST0 : FPrST0Inst <0xE8, "fsub{r}\t{%st(0), $op|$op, st(0)}">; | |
236 def SUB_FPrST0 : FPrST0PInst<0xE8, "fsub{r}p\t$op">; | |
237 def SUB_FST0r : FPST0rInst <0xE0, "fsub\t$op">; | |
238 def SUBR_FrST0 : FPrST0Inst <0xE0, "fsub{|r}\t{%st(0), $op|$op, st(0)}">; | |
239 def SUBR_FPrST0 : FPrST0PInst<0xE0, "fsub{|r}p\t$op">; | |
240 def MUL_FST0r : FPST0rInst <0xC8, "fmul\t$op">; | |
241 def MUL_FrST0 : FPrST0Inst <0xC8, "fmul\t{%st(0), $op|$op, st(0)}">; | |
242 def MUL_FPrST0 : FPrST0PInst<0xC8, "fmulp\t$op">; | |
243 def DIVR_FST0r : FPST0rInst <0xF8, "fdivr\t$op">; | |
244 def DIV_FrST0 : FPrST0Inst <0xF8, "fdiv{r}\t{%st(0), $op|$op, st(0)}">; | |
245 def DIV_FPrST0 : FPrST0PInst<0xF8, "fdiv{r}p\t$op">; | |
246 def DIV_FST0r : FPST0rInst <0xF0, "fdiv\t$op">; | |
247 def DIVR_FrST0 : FPrST0Inst <0xF0, "fdiv{|r}\t{%st(0), $op|$op, st(0)}">; | |
248 def DIVR_FPrST0 : FPrST0PInst<0xF0, "fdiv{|r}p\t$op">; | |
249 | |
250 def COM_FST0r : FPST0rInst <0xD0, "fcom\t$op">; | |
251 def COMP_FST0r : FPST0rInst <0xD8, "fcomp\t$op">; | |
252 | |
253 // Unary operations. | |
254 multiclass FPUnary<SDNode OpNode, bits<8> opcode, string asmstring> { | |
255 def _Fp32 : FpIf32<(outs RFP32:$dst), (ins RFP32:$src), OneArgFPRW, | |
256 [(set RFP32:$dst, (OpNode RFP32:$src))]>; | |
257 def _Fp64 : FpIf64<(outs RFP64:$dst), (ins RFP64:$src), OneArgFPRW, | |
258 [(set RFP64:$dst, (OpNode RFP64:$src))]>; | |
259 def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src), OneArgFPRW, | |
260 [(set RFP80:$dst, (OpNode RFP80:$src))]>; | |
261 def _F : FPI<opcode, RawFrm, (outs), (ins), asmstring>, D9; | |
262 } | |
263 | |
264 let Defs = [FPSW] in { | |
265 defm CHS : FPUnary<fneg, 0xE0, "fchs">; | |
266 defm ABS : FPUnary<fabs, 0xE1, "fabs">; | |
267 defm SQRT: FPUnary<fsqrt,0xFA, "fsqrt">; | |
268 defm SIN : FPUnary<fsin, 0xFE, "fsin">; | |
269 defm COS : FPUnary<fcos, 0xFF, "fcos">; | |
270 | |
271 let neverHasSideEffects = 1 in { | |
272 def TST_Fp32 : FpIf32<(outs), (ins RFP32:$src), OneArgFP, []>; | |
273 def TST_Fp64 : FpIf64<(outs), (ins RFP64:$src), OneArgFP, []>; | |
274 def TST_Fp80 : FpI_<(outs), (ins RFP80:$src), OneArgFP, []>; | |
275 } | |
276 def TST_F : FPI<0xE4, RawFrm, (outs), (ins), "ftst">, D9; | |
277 } // Defs = [FPSW] | |
278 | |
279 // Versions of FP instructions that take a single memory operand. Added for the | |
280 // disassembler; remove as they are included with patterns elsewhere. | |
281 def FCOM32m : FPI<0xD8, MRM2m, (outs), (ins f32mem:$src), "fcom{s}\t$src">; | |
282 def FCOMP32m : FPI<0xD8, MRM3m, (outs), (ins f32mem:$src), "fcomp{s}\t$src">; | |
283 | |
284 def FLDENVm : FPI<0xD9, MRM4m, (outs), (ins f32mem:$src), "fldenv\t$src">; | |
285 def FSTENVm : FPI<0xD9, MRM6m, (outs f32mem:$dst), (ins), "fnstenv\t$dst">; | |
286 | |
287 def FICOM32m : FPI<0xDA, MRM2m, (outs), (ins i32mem:$src), "ficom{l}\t$src">; | |
288 def FICOMP32m: FPI<0xDA, MRM3m, (outs), (ins i32mem:$src), "ficomp{l}\t$src">; | |
289 | |
290 def FCOM64m : FPI<0xDC, MRM2m, (outs), (ins f64mem:$src), "fcom{l}\t$src">; | |
291 def FCOMP64m : FPI<0xDC, MRM3m, (outs), (ins f64mem:$src), "fcomp{l}\t$src">; | |
292 | |
293 def FRSTORm : FPI<0xDD, MRM4m, (outs f32mem:$dst), (ins), "frstor\t$dst">; | |
294 def FSAVEm : FPI<0xDD, MRM6m, (outs f32mem:$dst), (ins), "fnsave\t$dst">; | |
295 def FNSTSWm : FPI<0xDD, MRM7m, (outs f32mem:$dst), (ins), "fnstsw\t$dst">; | |
296 | |
297 def FICOM16m : FPI<0xDE, MRM2m, (outs), (ins i16mem:$src), "ficom{s}\t$src">; | |
298 def FICOMP16m: FPI<0xDE, MRM3m, (outs), (ins i16mem:$src), "ficomp{s}\t$src">; | |
299 | |
300 def FBLDm : FPI<0xDF, MRM4m, (outs), (ins f32mem:$src), "fbld\t$src">; | |
301 def FBSTPm : FPI<0xDF, MRM6m, (outs f32mem:$dst), (ins), "fbstp\t$dst">; | |
302 | |
303 // Floating point cmovs. | |
304 class FpIf32CMov<dag outs, dag ins, FPFormat fp, list<dag> pattern> : | |
305 FpI_<outs, ins, fp, pattern>, Requires<[FPStackf32, HasCMov]>; | |
306 class FpIf64CMov<dag outs, dag ins, FPFormat fp, list<dag> pattern> : | |
307 FpI_<outs, ins, fp, pattern>, Requires<[FPStackf64, HasCMov]>; | |
308 | |
309 multiclass FPCMov<PatLeaf cc> { | |
310 def _Fp32 : FpIf32CMov<(outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2), | |
311 CondMovFP, | |
312 [(set RFP32:$dst, (X86cmov RFP32:$src1, RFP32:$src2, | |
313 cc, EFLAGS))]>; | |
314 def _Fp64 : FpIf64CMov<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2), | |
315 CondMovFP, | |
316 [(set RFP64:$dst, (X86cmov RFP64:$src1, RFP64:$src2, | |
317 cc, EFLAGS))]>; | |
318 def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), | |
319 CondMovFP, | |
320 [(set RFP80:$dst, (X86cmov RFP80:$src1, RFP80:$src2, | |
321 cc, EFLAGS))]>, | |
322 Requires<[HasCMov]>; | |
323 } | |
324 | |
325 let Defs = [FPSW] in { | |
326 let Uses = [EFLAGS], Constraints = "$src1 = $dst" in { | |
327 defm CMOVB : FPCMov<X86_COND_B>; | |
328 defm CMOVBE : FPCMov<X86_COND_BE>; | |
329 defm CMOVE : FPCMov<X86_COND_E>; | |
330 defm CMOVP : FPCMov<X86_COND_P>; | |
331 defm CMOVNB : FPCMov<X86_COND_AE>; | |
332 defm CMOVNBE: FPCMov<X86_COND_A>; | |
333 defm CMOVNE : FPCMov<X86_COND_NE>; | |
334 defm CMOVNP : FPCMov<X86_COND_NP>; | |
335 } // Uses = [EFLAGS], Constraints = "$src1 = $dst" | |
336 | |
337 let Predicates = [HasCMov] in { | |
338 // These are not factored because there's no clean way to pass DA/DB. | |
339 def CMOVB_F : FPI<0xC0, AddRegFrm, (outs RST:$op), (ins), | |
340 "fcmovb\t{$op, %st(0)|st(0), $op}">, DA; | |
341 def CMOVBE_F : FPI<0xD0, AddRegFrm, (outs RST:$op), (ins), | |
342 "fcmovbe\t{$op, %st(0)|st(0), $op}">, DA; | |
343 def CMOVE_F : FPI<0xC8, AddRegFrm, (outs RST:$op), (ins), | |
344 "fcmove\t{$op, %st(0)|st(0), $op}">, DA; | |
345 def CMOVP_F : FPI<0xD8, AddRegFrm, (outs RST:$op), (ins), | |
346 "fcmovu\t{$op, %st(0)|st(0), $op}">, DA; | |
347 def CMOVNB_F : FPI<0xC0, AddRegFrm, (outs RST:$op), (ins), | |
348 "fcmovnb\t{$op, %st(0)|st(0), $op}">, DB; | |
349 def CMOVNBE_F: FPI<0xD0, AddRegFrm, (outs RST:$op), (ins), | |
350 "fcmovnbe\t{$op, %st(0)|st(0), $op}">, DB; | |
351 def CMOVNE_F : FPI<0xC8, AddRegFrm, (outs RST:$op), (ins), | |
352 "fcmovne\t{$op, %st(0)|st(0), $op}">, DB; | |
353 def CMOVNP_F : FPI<0xD8, AddRegFrm, (outs RST:$op), (ins), | |
354 "fcmovnu\t{$op, %st(0)|st(0), $op}">, DB; | |
355 } // Predicates = [HasCMov] | |
356 | |
357 // Floating point loads & stores. | |
358 let canFoldAsLoad = 1 in { | |
359 def LD_Fp32m : FpIf32<(outs RFP32:$dst), (ins f32mem:$src), ZeroArgFP, | |
360 [(set RFP32:$dst, (loadf32 addr:$src))]>; | |
361 let isReMaterializable = 1 in | |
362 def LD_Fp64m : FpIf64<(outs RFP64:$dst), (ins f64mem:$src), ZeroArgFP, | |
363 [(set RFP64:$dst, (loadf64 addr:$src))]>; | |
364 def LD_Fp80m : FpI_<(outs RFP80:$dst), (ins f80mem:$src), ZeroArgFP, | |
365 [(set RFP80:$dst, (loadf80 addr:$src))]>; | |
366 } | |
367 def LD_Fp32m64 : FpIf64<(outs RFP64:$dst), (ins f32mem:$src), ZeroArgFP, | |
368 [(set RFP64:$dst, (f64 (extloadf32 addr:$src)))]>; | |
369 def LD_Fp64m80 : FpI_<(outs RFP80:$dst), (ins f64mem:$src), ZeroArgFP, | |
370 [(set RFP80:$dst, (f80 (extloadf64 addr:$src)))]>; | |
371 def LD_Fp32m80 : FpI_<(outs RFP80:$dst), (ins f32mem:$src), ZeroArgFP, | |
372 [(set RFP80:$dst, (f80 (extloadf32 addr:$src)))]>; | |
373 def ILD_Fp16m32: FpIf32<(outs RFP32:$dst), (ins i16mem:$src), ZeroArgFP, | |
374 [(set RFP32:$dst, (X86fild addr:$src, i16))]>; | |
375 def ILD_Fp32m32: FpIf32<(outs RFP32:$dst), (ins i32mem:$src), ZeroArgFP, | |
376 [(set RFP32:$dst, (X86fild addr:$src, i32))]>; | |
377 def ILD_Fp64m32: FpIf32<(outs RFP32:$dst), (ins i64mem:$src), ZeroArgFP, | |
378 [(set RFP32:$dst, (X86fild addr:$src, i64))]>; | |
379 def ILD_Fp16m64: FpIf64<(outs RFP64:$dst), (ins i16mem:$src), ZeroArgFP, | |
380 [(set RFP64:$dst, (X86fild addr:$src, i16))]>; | |
381 def ILD_Fp32m64: FpIf64<(outs RFP64:$dst), (ins i32mem:$src), ZeroArgFP, | |
382 [(set RFP64:$dst, (X86fild addr:$src, i32))]>; | |
383 def ILD_Fp64m64: FpIf64<(outs RFP64:$dst), (ins i64mem:$src), ZeroArgFP, | |
384 [(set RFP64:$dst, (X86fild addr:$src, i64))]>; | |
385 def ILD_Fp16m80: FpI_<(outs RFP80:$dst), (ins i16mem:$src), ZeroArgFP, | |
386 [(set RFP80:$dst, (X86fild addr:$src, i16))]>; | |
387 def ILD_Fp32m80: FpI_<(outs RFP80:$dst), (ins i32mem:$src), ZeroArgFP, | |
388 [(set RFP80:$dst, (X86fild addr:$src, i32))]>; | |
389 def ILD_Fp64m80: FpI_<(outs RFP80:$dst), (ins i64mem:$src), ZeroArgFP, | |
390 [(set RFP80:$dst, (X86fild addr:$src, i64))]>; | |
391 | |
392 def ST_Fp32m : FpIf32<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP, | |
393 [(store RFP32:$src, addr:$op)]>; | |
394 def ST_Fp64m32 : FpIf64<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, | |
395 [(truncstoref32 RFP64:$src, addr:$op)]>; | |
396 def ST_Fp64m : FpIf64<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP, | |
397 [(store RFP64:$src, addr:$op)]>; | |
398 def ST_Fp80m32 : FpI_<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP, | |
399 [(truncstoref32 RFP80:$src, addr:$op)]>; | |
400 def ST_Fp80m64 : FpI_<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP, | |
401 [(truncstoref64 RFP80:$src, addr:$op)]>; | |
402 // FST does not support 80-bit memory target; FSTP must be used. | |
403 | |
404 let mayStore = 1, neverHasSideEffects = 1 in { | |
405 def ST_FpP32m : FpIf32<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP, []>; | |
406 def ST_FpP64m32 : FpIf64<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, []>; | |
407 def ST_FpP64m : FpIf64<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP, []>; | |
408 def ST_FpP80m32 : FpI_<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP, []>; | |
409 def ST_FpP80m64 : FpI_<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP, []>; | |
410 } | |
411 def ST_FpP80m : FpI_<(outs), (ins f80mem:$op, RFP80:$src), OneArgFP, | |
412 [(store RFP80:$src, addr:$op)]>; | |
413 let mayStore = 1, neverHasSideEffects = 1 in { | |
414 def IST_Fp16m32 : FpIf32<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, []>; | |
415 def IST_Fp32m32 : FpIf32<(outs), (ins i32mem:$op, RFP32:$src), OneArgFP, []>; | |
416 def IST_Fp64m32 : FpIf32<(outs), (ins i64mem:$op, RFP32:$src), OneArgFP, []>; | |
417 def IST_Fp16m64 : FpIf64<(outs), (ins i16mem:$op, RFP64:$src), OneArgFP, []>; | |
418 def IST_Fp32m64 : FpIf64<(outs), (ins i32mem:$op, RFP64:$src), OneArgFP, []>; | |
419 def IST_Fp64m64 : FpIf64<(outs), (ins i64mem:$op, RFP64:$src), OneArgFP, []>; | |
420 def IST_Fp16m80 : FpI_<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, []>; | |
421 def IST_Fp32m80 : FpI_<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, []>; | |
422 def IST_Fp64m80 : FpI_<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, []>; | |
423 } | |
424 | |
425 let mayLoad = 1, SchedRW = [WriteLoad] in { | |
426 def LD_F32m : FPI<0xD9, MRM0m, (outs), (ins f32mem:$src), "fld{s}\t$src", | |
427 IIC_FLD>; | |
428 def LD_F64m : FPI<0xDD, MRM0m, (outs), (ins f64mem:$src), "fld{l}\t$src", | |
429 IIC_FLD>; | |
430 def LD_F80m : FPI<0xDB, MRM5m, (outs), (ins f80mem:$src), "fld{t}\t$src", | |
431 IIC_FLD80>; | |
432 def ILD_F16m : FPI<0xDF, MRM0m, (outs), (ins i16mem:$src), "fild{s}\t$src", | |
433 IIC_FILD>; | |
434 def ILD_F32m : FPI<0xDB, MRM0m, (outs), (ins i32mem:$src), "fild{l}\t$src", | |
435 IIC_FILD>; | |
436 def ILD_F64m : FPI<0xDF, MRM5m, (outs), (ins i64mem:$src), "fild{ll}\t$src", | |
437 IIC_FILD>; | |
438 } | |
439 let mayStore = 1, SchedRW = [WriteStore] in { | |
440 def ST_F32m : FPI<0xD9, MRM2m, (outs), (ins f32mem:$dst), "fst{s}\t$dst", | |
441 IIC_FST>; | |
442 def ST_F64m : FPI<0xDD, MRM2m, (outs), (ins f64mem:$dst), "fst{l}\t$dst", | |
443 IIC_FST>; | |
444 def ST_FP32m : FPI<0xD9, MRM3m, (outs), (ins f32mem:$dst), "fstp{s}\t$dst", | |
445 IIC_FST>; | |
446 def ST_FP64m : FPI<0xDD, MRM3m, (outs), (ins f64mem:$dst), "fstp{l}\t$dst", | |
447 IIC_FST>; | |
448 def ST_FP80m : FPI<0xDB, MRM7m, (outs), (ins f80mem:$dst), "fstp{t}\t$dst", | |
449 IIC_FST80>; | |
450 def IST_F16m : FPI<0xDF, MRM2m, (outs), (ins i16mem:$dst), "fist{s}\t$dst", | |
451 IIC_FIST>; | |
452 def IST_F32m : FPI<0xDB, MRM2m, (outs), (ins i32mem:$dst), "fist{l}\t$dst", | |
453 IIC_FIST>; | |
454 def IST_FP16m : FPI<0xDF, MRM3m, (outs), (ins i16mem:$dst), "fistp{s}\t$dst", | |
455 IIC_FIST>; | |
456 def IST_FP32m : FPI<0xDB, MRM3m, (outs), (ins i32mem:$dst), "fistp{l}\t$dst", | |
457 IIC_FIST>; | |
458 def IST_FP64m : FPI<0xDF, MRM7m, (outs), (ins i64mem:$dst), "fistp{ll}\t$dst", | |
459 IIC_FIST>; | |
460 } | |
461 | |
462 // FISTTP requires SSE3 even though it's a FPStack op. | |
463 let Predicates = [HasSSE3] in { | |
464 def ISTT_Fp16m32 : FpI_<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, | |
465 [(X86fp_to_i16mem RFP32:$src, addr:$op)]>; | |
466 def ISTT_Fp32m32 : FpI_<(outs), (ins i32mem:$op, RFP32:$src), OneArgFP, | |
467 [(X86fp_to_i32mem RFP32:$src, addr:$op)]>; | |
468 def ISTT_Fp64m32 : FpI_<(outs), (ins i64mem:$op, RFP32:$src), OneArgFP, | |
469 [(X86fp_to_i64mem RFP32:$src, addr:$op)]>; | |
470 def ISTT_Fp16m64 : FpI_<(outs), (ins i16mem:$op, RFP64:$src), OneArgFP, | |
471 [(X86fp_to_i16mem RFP64:$src, addr:$op)]>; | |
472 def ISTT_Fp32m64 : FpI_<(outs), (ins i32mem:$op, RFP64:$src), OneArgFP, | |
473 [(X86fp_to_i32mem RFP64:$src, addr:$op)]>; | |
474 def ISTT_Fp64m64 : FpI_<(outs), (ins i64mem:$op, RFP64:$src), OneArgFP, | |
475 [(X86fp_to_i64mem RFP64:$src, addr:$op)]>; | |
476 def ISTT_Fp16m80 : FpI_<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, | |
477 [(X86fp_to_i16mem RFP80:$src, addr:$op)]>; | |
478 def ISTT_Fp32m80 : FpI_<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, | |
479 [(X86fp_to_i32mem RFP80:$src, addr:$op)]>; | |
480 def ISTT_Fp64m80 : FpI_<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, | |
481 [(X86fp_to_i64mem RFP80:$src, addr:$op)]>; | |
482 } // Predicates = [HasSSE3] | |
483 | |
484 let mayStore = 1, SchedRW = [WriteStore] in { | |
485 def ISTT_FP16m : FPI<0xDF, MRM1m, (outs), (ins i16mem:$dst), "fisttp{s}\t$dst", | |
486 IIC_FST>; | |
487 def ISTT_FP32m : FPI<0xDB, MRM1m, (outs), (ins i32mem:$dst), "fisttp{l}\t$dst", | |
488 IIC_FST>; | |
489 def ISTT_FP64m : FPI<0xDD, MRM1m, (outs), (ins i64mem:$dst), | |
490 "fisttp{ll}\t$dst", IIC_FST>; | |
491 } | |
492 | |
493 // FP Stack manipulation instructions. | |
494 let SchedRW = [WriteMove] in { | |
495 def LD_Frr : FPI<0xC0, AddRegFrm, (outs), (ins RST:$op), "fld\t$op", | |
496 IIC_FLD>, D9; | |
497 def ST_Frr : FPI<0xD0, AddRegFrm, (outs), (ins RST:$op), "fst\t$op", | |
498 IIC_FST>, DD; | |
499 def ST_FPrr : FPI<0xD8, AddRegFrm, (outs), (ins RST:$op), "fstp\t$op", | |
500 IIC_FST>, DD; | |
501 def XCH_F : FPI<0xC8, AddRegFrm, (outs), (ins RST:$op), "fxch\t$op", | |
502 IIC_FXCH>, D9; | |
503 } | |
504 | |
505 // Floating point constant loads. | |
506 let isReMaterializable = 1 in { | |
507 def LD_Fp032 : FpIf32<(outs RFP32:$dst), (ins), ZeroArgFP, | |
508 [(set RFP32:$dst, fpimm0)]>; | |
509 def LD_Fp132 : FpIf32<(outs RFP32:$dst), (ins), ZeroArgFP, | |
510 [(set RFP32:$dst, fpimm1)]>; | |
511 def LD_Fp064 : FpIf64<(outs RFP64:$dst), (ins), ZeroArgFP, | |
512 [(set RFP64:$dst, fpimm0)]>; | |
513 def LD_Fp164 : FpIf64<(outs RFP64:$dst), (ins), ZeroArgFP, | |
514 [(set RFP64:$dst, fpimm1)]>; | |
515 def LD_Fp080 : FpI_<(outs RFP80:$dst), (ins), ZeroArgFP, | |
516 [(set RFP80:$dst, fpimm0)]>; | |
517 def LD_Fp180 : FpI_<(outs RFP80:$dst), (ins), ZeroArgFP, | |
518 [(set RFP80:$dst, fpimm1)]>; | |
519 } | |
520 | |
521 let SchedRW = [WriteZero] in { | |
522 def LD_F0 : FPI<0xEE, RawFrm, (outs), (ins), "fldz", IIC_FLDZ>, D9; | |
523 def LD_F1 : FPI<0xE8, RawFrm, (outs), (ins), "fld1", IIC_FIST>, D9; | |
524 } | |
525 | |
526 // Floating point compares. | |
527 let SchedRW = [WriteFAdd] in { | |
528 def UCOM_Fpr32 : FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, | |
529 [(set FPSW, (trunc (X86cmp RFP32:$lhs, RFP32:$rhs)))]>; | |
530 def UCOM_Fpr64 : FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, | |
531 [(set FPSW, (trunc (X86cmp RFP64:$lhs, RFP64:$rhs)))]>; | |
532 def UCOM_Fpr80 : FpI_ <(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, | |
533 [(set FPSW, (trunc (X86cmp RFP80:$lhs, RFP80:$rhs)))]>; | |
534 } // SchedRW | |
535 } // Defs = [FPSW] | |
536 | |
537 let SchedRW = [WriteFAdd] in { | |
538 // CC = ST(0) cmp ST(i) | |
539 let Defs = [EFLAGS, FPSW] in { | |
540 def UCOM_FpIr32: FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, | |
541 [(set EFLAGS, (X86cmp RFP32:$lhs, RFP32:$rhs))]>; | |
542 def UCOM_FpIr64: FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, | |
543 [(set EFLAGS, (X86cmp RFP64:$lhs, RFP64:$rhs))]>; | |
544 def UCOM_FpIr80: FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, | |
545 [(set EFLAGS, (X86cmp RFP80:$lhs, RFP80:$rhs))]>; | |
546 } | |
547 | |
548 let Defs = [FPSW], Uses = [ST0] in { | |
549 def UCOM_Fr : FPI<0xE0, AddRegFrm, // FPSW = cmp ST(0) with ST(i) | |
550 (outs), (ins RST:$reg), | |
551 "fucom\t$reg", IIC_FUCOM>, DD; | |
552 def UCOM_FPr : FPI<0xE8, AddRegFrm, // FPSW = cmp ST(0) with ST(i), pop | |
553 (outs), (ins RST:$reg), | |
554 "fucomp\t$reg", IIC_FUCOM>, DD; | |
555 def UCOM_FPPr : FPI<0xE9, RawFrm, // cmp ST(0) with ST(1), pop, pop | |
556 (outs), (ins), | |
557 "fucompp", IIC_FUCOM>, DA; | |
558 } | |
559 | |
560 let Defs = [EFLAGS, FPSW], Uses = [ST0] in { | |
561 def UCOM_FIr : FPI<0xE8, AddRegFrm, // CC = cmp ST(0) with ST(i) | |
562 (outs), (ins RST:$reg), | |
563 "fucomi\t$reg", IIC_FUCOMI>, DB; | |
564 def UCOM_FIPr : FPI<0xE8, AddRegFrm, // CC = cmp ST(0) with ST(i), pop | |
565 (outs), (ins RST:$reg), | |
566 "fucompi\t$reg", IIC_FUCOMI>, DF; | |
567 } | |
568 | |
569 let Defs = [EFLAGS, FPSW] in { | |
570 def COM_FIr : FPI<0xF0, AddRegFrm, (outs), (ins RST:$reg), | |
571 "fcomi\t$reg", IIC_FCOMI>, DB; | |
572 def COM_FIPr : FPI<0xF0, AddRegFrm, (outs), (ins RST:$reg), | |
573 "fcompi\t$reg", IIC_FCOMI>, DF; | |
574 } | |
575 } // SchedRW | |
576 | |
577 // Floating point flag ops. | |
578 let SchedRW = [WriteALU] in { | |
579 let Defs = [AX], Uses = [FPSW] in | |
580 def FNSTSW16r : I<0xE0, RawFrm, // AX = fp flags | |
581 (outs), (ins), "fnstsw\t{%ax|ax}", | |
582 [(set AX, (X86fp_stsw FPSW))], IIC_FNSTSW>, DF; | |
583 | |
584 def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world | |
585 (outs), (ins i16mem:$dst), "fnstcw\t$dst", | |
586 [(X86fp_cwd_get16 addr:$dst)], IIC_FNSTCW>; | |
587 } // SchedRW | |
588 let mayLoad = 1 in | |
589 def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16] | |
590 (outs), (ins i16mem:$dst), "fldcw\t$dst", [], IIC_FLDCW>, | |
591 Sched<[WriteLoad]>; | |
592 | |
593 // FPU control instructions | |
594 let SchedRW = [WriteMicrocoded] in { | |
595 let Defs = [FPSW] in | |
596 def FNINIT : I<0xE3, RawFrm, (outs), (ins), "fninit", [], IIC_FNINIT>, DB; | |
597 def FFREE : FPI<0xC0, AddRegFrm, (outs), (ins RST:$reg), | |
598 "ffree\t$reg", IIC_FFREE>, DD; | |
599 // Clear exceptions | |
600 | |
601 let Defs = [FPSW] in | |
602 def FNCLEX : I<0xE2, RawFrm, (outs), (ins), "fnclex", [], IIC_FNCLEX>, DB; | |
603 } // SchedRW | |
604 | |
605 // Operandless floating-point instructions for the disassembler. | |
606 let SchedRW = [WriteMicrocoded] in { | |
607 def WAIT : I<0x9B, RawFrm, (outs), (ins), "wait", [], IIC_WAIT>; | |
608 | |
609 def FNOP : I<0xD0, RawFrm, (outs), (ins), "fnop", [], IIC_FNOP>, D9; | |
610 def FXAM : I<0xE5, RawFrm, (outs), (ins), "fxam", [], IIC_FXAM>, D9; | |
611 def FLDL2T : I<0xE9, RawFrm, (outs), (ins), "fldl2t", [], IIC_FLDL>, D9; | |
612 def FLDL2E : I<0xEA, RawFrm, (outs), (ins), "fldl2e", [], IIC_FLDL>, D9; | |
613 def FLDPI : I<0xEB, RawFrm, (outs), (ins), "fldpi", [], IIC_FLDL>, D9; | |
614 def FLDLG2 : I<0xEC, RawFrm, (outs), (ins), "fldlg2", [], IIC_FLDL>, D9; | |
615 def FLDLN2 : I<0xED, RawFrm, (outs), (ins), "fldln2", [], IIC_FLDL>, D9; | |
616 def F2XM1 : I<0xF0, RawFrm, (outs), (ins), "f2xm1", [], IIC_F2XM1>, D9; | |
617 def FYL2X : I<0xF1, RawFrm, (outs), (ins), "fyl2x", [], IIC_FYL2X>, D9; | |
618 def FPTAN : I<0xF2, RawFrm, (outs), (ins), "fptan", [], IIC_FPTAN>, D9; | |
619 def FPATAN : I<0xF3, RawFrm, (outs), (ins), "fpatan", [], IIC_FPATAN>, D9; | |
620 def FXTRACT : I<0xF4, RawFrm, (outs), (ins), "fxtract", [], IIC_FXTRACT>, D9; | |
621 def FPREM1 : I<0xF5, RawFrm, (outs), (ins), "fprem1", [], IIC_FPREM1>, D9; | |
622 def FDECSTP : I<0xF6, RawFrm, (outs), (ins), "fdecstp", [], IIC_FPSTP>, D9; | |
623 def FINCSTP : I<0xF7, RawFrm, (outs), (ins), "fincstp", [], IIC_FPSTP>, D9; | |
624 def FPREM : I<0xF8, RawFrm, (outs), (ins), "fprem", [], IIC_FPREM>, D9; | |
625 def FYL2XP1 : I<0xF9, RawFrm, (outs), (ins), "fyl2xp1", [], IIC_FYL2XP1>, D9; | |
626 def FSINCOS : I<0xFB, RawFrm, (outs), (ins), "fsincos", [], IIC_FSINCOS>, D9; | |
627 def FRNDINT : I<0xFC, RawFrm, (outs), (ins), "frndint", [], IIC_FRNDINT>, D9; | |
628 def FSCALE : I<0xFD, RawFrm, (outs), (ins), "fscale", [], IIC_FSCALE>, D9; | |
629 def FCOMPP : I<0xD9, RawFrm, (outs), (ins), "fcompp", [], IIC_FCOMPP>, DE; | |
630 | |
631 def FXSAVE : I<0xAE, MRM0m, (outs opaque512mem:$dst), (ins), | |
632 "fxsave\t$dst", [], IIC_FXSAVE>, TB; | |
633 def FXSAVE64 : I<0xAE, MRM0m, (outs opaque512mem:$dst), (ins), | |
634 "fxsaveq\t$dst", [], IIC_FXSAVE>, TB, REX_W, | |
635 Requires<[In64BitMode]>; | |
636 def FXRSTOR : I<0xAE, MRM1m, (outs), (ins opaque512mem:$src), | |
637 "fxrstor\t$src", [], IIC_FXRSTOR>, TB; | |
638 def FXRSTOR64 : I<0xAE, MRM1m, (outs), (ins opaque512mem:$src), | |
639 "fxrstorq\t$src", [], IIC_FXRSTOR>, TB, REX_W, | |
640 Requires<[In64BitMode]>; | |
641 } // SchedRW | |
642 | |
643 //===----------------------------------------------------------------------===// | |
644 // Non-Instruction Patterns | |
645 //===----------------------------------------------------------------------===// | |
646 | |
647 // Required for RET of f32 / f64 / f80 values. | |
648 def : Pat<(X86fld addr:$src, f32), (LD_Fp32m addr:$src)>; | |
649 def : Pat<(X86fld addr:$src, f64), (LD_Fp64m addr:$src)>; | |
650 def : Pat<(X86fld addr:$src, f80), (LD_Fp80m addr:$src)>; | |
651 | |
652 // Required for CALL which return f32 / f64 / f80 values. | |
653 def : Pat<(X86fst RFP32:$src, addr:$op, f32), (ST_Fp32m addr:$op, RFP32:$src)>; | |
654 def : Pat<(X86fst RFP64:$src, addr:$op, f32), (ST_Fp64m32 addr:$op, | |
655 RFP64:$src)>; | |
656 def : Pat<(X86fst RFP64:$src, addr:$op, f64), (ST_Fp64m addr:$op, RFP64:$src)>; | |
657 def : Pat<(X86fst RFP80:$src, addr:$op, f32), (ST_Fp80m32 addr:$op, | |
658 RFP80:$src)>; | |
659 def : Pat<(X86fst RFP80:$src, addr:$op, f64), (ST_Fp80m64 addr:$op, | |
660 RFP80:$src)>; | |
661 def : Pat<(X86fst RFP80:$src, addr:$op, f80), (ST_FpP80m addr:$op, | |
662 RFP80:$src)>; | |
663 | |
664 // Floating point constant -0.0 and -1.0 | |
665 def : Pat<(f32 fpimmneg0), (CHS_Fp32 (LD_Fp032))>, Requires<[FPStackf32]>; | |
666 def : Pat<(f32 fpimmneg1), (CHS_Fp32 (LD_Fp132))>, Requires<[FPStackf32]>; | |
667 def : Pat<(f64 fpimmneg0), (CHS_Fp64 (LD_Fp064))>, Requires<[FPStackf64]>; | |
668 def : Pat<(f64 fpimmneg1), (CHS_Fp64 (LD_Fp164))>, Requires<[FPStackf64]>; | |
669 def : Pat<(f80 fpimmneg0), (CHS_Fp80 (LD_Fp080))>; | |
670 def : Pat<(f80 fpimmneg1), (CHS_Fp80 (LD_Fp180))>; | |
671 | |
672 // Used to conv. i64 to f64 since there isn't a SSE version. | |
673 def : Pat<(X86fildflag addr:$src, i64), (ILD_Fp64m64 addr:$src)>; | |
674 | |
675 // FP extensions map onto simple pseudo-value conversions if they are to/from | |
676 // the FP stack. | |
677 def : Pat<(f64 (fextend RFP32:$src)), (COPY_TO_REGCLASS RFP32:$src, RFP64)>, | |
678 Requires<[FPStackf32]>; | |
679 def : Pat<(f80 (fextend RFP32:$src)), (COPY_TO_REGCLASS RFP32:$src, RFP80)>, | |
680 Requires<[FPStackf32]>; | |
681 def : Pat<(f80 (fextend RFP64:$src)), (COPY_TO_REGCLASS RFP64:$src, RFP80)>, | |
682 Requires<[FPStackf64]>; | |
683 | |
684 // FP truncations map onto simple pseudo-value conversions if they are to/from | |
685 // the FP stack. We have validated that only value-preserving truncations make | |
686 // it through isel. | |
687 def : Pat<(f32 (fround RFP64:$src)), (COPY_TO_REGCLASS RFP64:$src, RFP32)>, | |
688 Requires<[FPStackf32]>; | |
689 def : Pat<(f32 (fround RFP80:$src)), (COPY_TO_REGCLASS RFP80:$src, RFP32)>, | |
690 Requires<[FPStackf32]>; | |
691 def : Pat<(f64 (fround RFP80:$src)), (COPY_TO_REGCLASS RFP80:$src, RFP64)>, | |
692 Requires<[FPStackf64]>; |