a44da571e6af311997e818138c77e27500bb948f
[oota-llvm.git] / lib / Target / X86 / X86InstrFPStack.td
1 //==- X86InstrFPStack.td - Describe the X86 Instruction Set -------*- C++ -*-=//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the Evan Cheng and is distributed under
6 // the University of Illinois Open Source 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 // All FP Stack operations are represented with two instructions here.  The
17 // first instruction, generated by the instruction selector, uses "RFP"
18 // registers: a traditional register file to reference floating point values.
19 // These instructions are all psuedo instructions and use the "Fp" prefix.
20 // The second instruction is defined with FPI, which is the actual instruction
21 // emitted by the assembler.  The FP stackifier pass converts one to the other
22 // after register allocation occurs.
23 //
24 // Note that the FpI instruction should have instruction selection info (e.g.
25 // a pattern) and the FPI instruction should have emission info (e.g. opcode
26 // encoding and asm printing info).
27
28 // FPI - Floating Point Instruction template.
29 class FPI<bits<8> o, Format F, dag ops, string asm> : I<o, F, ops, asm, []> {}
30
31 // FpI_ - Floating Point Psuedo Instruction template. Not Predicated.
32 class FpI_<dag ops, FPFormat fp, list<dag> pattern>
33   : X86Inst<0, Pseudo, NoImm, ops, ""> {
34   let FPForm = fp; let FPFormBits = FPForm.Value;
35   let Pattern = pattern;
36 }
37
38 // Random Pseudo Instructions.
39 def FpGETRESULT : FpI_<(ops RFP:$dst), SpecialFP,
40                   [(set RFP:$dst, X86fpget)]>;                    // FPR = ST(0)
41
42 let noResults = 1 in 
43   def FpSETRESULT : FpI_<(ops RFP:$src), SpecialFP,
44                         [(X86fpset RFP:$src)]>, Imp<[], [ST0]>;   // ST(0) = FPR
45
46 // FpI - Floating Point Psuedo Instruction template. Predicated on FPStack.
47 class FpI<dag ops, FPFormat fp, list<dag> pattern> :
48   FpI_<ops, fp, pattern>, Requires<[FPStack]>;
49
50
51 def FpMOV       : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2
52
53 // Arithmetic
54 // Add, Sub, Mul, Div.
55 def FpADD : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
56                 [(set RFP:$dst, (fadd RFP:$src1, RFP:$src2))]>;
57 def FpSUB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
58                 [(set RFP:$dst, (fsub RFP:$src1, RFP:$src2))]>;
59 def FpMUL : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
60                 [(set RFP:$dst, (fmul RFP:$src1, RFP:$src2))]>;
61 def FpDIV : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
62                 [(set RFP:$dst, (fdiv RFP:$src1, RFP:$src2))]>;
63
64 class FPST0rInst<bits<8> o, string asm>
65   : FPI<o, AddRegFrm, (ops RST:$op), asm>, D8;
66 class FPrST0Inst<bits<8> o, string asm>
67   : FPI<o, AddRegFrm, (ops RST:$op), asm>, DC;
68 class FPrST0PInst<bits<8> o, string asm>
69   : FPI<o, AddRegFrm, (ops RST:$op), asm>, DE;
70
71 // Binary Ops with a memory source.
72 def FpADD32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
73                     [(set RFP:$dst, (fadd RFP:$src1,
74                                      (extloadf64f32 addr:$src2)))]>;
75                 // ST(0) = ST(0) + [mem32]
76 def FpADD64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
77                     [(set RFP:$dst, (fadd RFP:$src1, (loadf64 addr:$src2)))]>;
78                 // ST(0) = ST(0) + [mem64]
79 def FpMUL32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
80                     [(set RFP:$dst, (fmul RFP:$src1,
81                                      (extloadf64f32 addr:$src2)))]>;
82                 // ST(0) = ST(0) * [mem32]
83 def FpMUL64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
84                     [(set RFP:$dst, (fmul RFP:$src1, (loadf64 addr:$src2)))]>;
85                 // ST(0) = ST(0) * [mem64]
86 def FpSUB32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
87                     [(set RFP:$dst, (fsub RFP:$src1,
88                                     (extloadf64f32 addr:$src2)))]>;
89                 // ST(0) = ST(0) - [mem32]
90 def FpSUB64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
91                     [(set RFP:$dst, (fsub RFP:$src1, (loadf64 addr:$src2)))]>;
92                 // ST(0) = ST(0) - [mem64]
93 def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
94                     [(set RFP:$dst, (fsub (extloadf64f32 addr:$src2),
95                                      RFP:$src1))]>;
96                 // ST(0) = [mem32] - ST(0)
97 def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
98                     [(set RFP:$dst, (fsub (loadf64 addr:$src2), RFP:$src1))]>;
99                 // ST(0) = [mem64] - ST(0)
100 def FpDIV32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
101                     [(set RFP:$dst, (fdiv RFP:$src1,
102                                     (extloadf64f32 addr:$src2)))]>;
103                 // ST(0) = ST(0) / [mem32]
104 def FpDIV64m  : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
105                     [(set RFP:$dst, (fdiv RFP:$src1, (loadf64 addr:$src2)))]>;
106                 // ST(0) = ST(0) / [mem64]
107 def FpDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
108                     [(set RFP:$dst, (fdiv (extloadf64f32 addr:$src2),
109                                      RFP:$src1))]>;
110                 // ST(0) = [mem32] / ST(0)
111 def FpDIVR64m : FpI<(ops RFP:$dst, RFP:$src1, f64mem:$src2), OneArgFPRW,
112                     [(set RFP:$dst, (fdiv (loadf64 addr:$src2), RFP:$src1))]>;
113                 // ST(0) = [mem64] / ST(0)
114
115
116 def FADD32m  : FPI<0xD8, MRM0m, (ops f32mem:$src), "fadd{s} $src">;
117 def FADD64m  : FPI<0xDC, MRM0m, (ops f64mem:$src), "fadd{l} $src">;
118 def FMUL32m  : FPI<0xD8, MRM1m, (ops f32mem:$src), "fmul{s} $src">;
119 def FMUL64m  : FPI<0xDC, MRM1m, (ops f64mem:$src), "fmul{l} $src">;
120 def FSUB32m  : FPI<0xD8, MRM4m, (ops f32mem:$src), "fsub{s} $src">;
121 def FSUB64m  : FPI<0xDC, MRM4m, (ops f64mem:$src), "fsub{l} $src">;
122 def FSUBR32m : FPI<0xD8, MRM5m, (ops f32mem:$src), "fsubr{s} $src">;
123 def FSUBR64m : FPI<0xDC, MRM5m, (ops f64mem:$src), "fsubr{l} $src">;
124 def FDIV32m  : FPI<0xD8, MRM6m, (ops f32mem:$src), "fdiv{s} $src">;
125 def FDIV64m  : FPI<0xDC, MRM6m, (ops f64mem:$src), "fdiv{l} $src">;
126 def FDIVR32m : FPI<0xD8, MRM7m, (ops f32mem:$src), "fdivr{s} $src">;
127 def FDIVR64m : FPI<0xDC, MRM7m, (ops f64mem:$src), "fdivr{l} $src">;
128
129 def FpIADD16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
130                     [(set RFP:$dst, (fadd RFP:$src1,
131                                      (X86fild addr:$src2, i16)))]>;
132                 // ST(0) = ST(0) + [mem16int]
133 def FpIADD32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
134                     [(set RFP:$dst, (fadd RFP:$src1,
135                                      (X86fild addr:$src2, i32)))]>;
136                 // ST(0) = ST(0) + [mem32int]
137 def FpIMUL16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
138                     [(set RFP:$dst, (fmul RFP:$src1,
139                                      (X86fild addr:$src2, i16)))]>;
140                 // ST(0) = ST(0) * [mem16int]
141 def FpIMUL32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
142                     [(set RFP:$dst, (fmul RFP:$src1,
143                                      (X86fild addr:$src2, i32)))]>;
144                 // ST(0) = ST(0) * [mem32int]
145 def FpISUB16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
146                     [(set RFP:$dst, (fsub RFP:$src1,
147                                      (X86fild addr:$src2, i16)))]>;
148                 // ST(0) = ST(0) - [mem16int]
149 def FpISUB32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
150                     [(set RFP:$dst, (fsub RFP:$src1,
151                                      (X86fild addr:$src2, i32)))]>;
152                 // ST(0) = ST(0) - [mem32int]
153 def FpISUBR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
154                      [(set RFP:$dst, (fsub (X86fild addr:$src2, i16),
155                                       RFP:$src1))]>;
156                 // ST(0) = [mem16int] - ST(0)
157 def FpISUBR32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
158                      [(set RFP:$dst, (fsub (X86fild addr:$src2, i32),
159                                       RFP:$src1))]>;
160                 // ST(0) = [mem32int] - ST(0)
161 def FpIDIV16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
162                     [(set RFP:$dst, (fdiv RFP:$src1,
163                                      (X86fild addr:$src2, i16)))]>;
164                 // ST(0) = ST(0) / [mem16int]
165 def FpIDIV32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
166                     [(set RFP:$dst, (fdiv RFP:$src1,
167                                      (X86fild addr:$src2, i32)))]>;
168                 // ST(0) = ST(0) / [mem32int]
169 def FpIDIVR16m : FpI<(ops RFP:$dst, RFP:$src1, i16mem:$src2), OneArgFPRW,
170                      [(set RFP:$dst, (fdiv (X86fild addr:$src2, i16),
171                                       RFP:$src1))]>;
172                 // ST(0) = [mem16int] / ST(0)
173 def FpIDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, i32mem:$src2), OneArgFPRW,
174                      [(set RFP:$dst, (fdiv (X86fild addr:$src2, i32),
175                                       RFP:$src1))]>;
176                 // ST(0) = [mem32int] / ST(0)
177
178 def FIADD16m  : FPI<0xDE, MRM0m, (ops i16mem:$src), "fiadd{s} $src">;
179 def FIADD32m  : FPI<0xDA, MRM0m, (ops i32mem:$src), "fiadd{l} $src">;
180 def FIMUL16m  : FPI<0xDE, MRM1m, (ops i16mem:$src), "fimul{s} $src">;
181 def FIMUL32m  : FPI<0xDA, MRM1m, (ops i32mem:$src), "fimul{l} $src">;
182 def FISUB16m  : FPI<0xDE, MRM4m, (ops i16mem:$src), "fisub{s} $src">;
183 def FISUB32m  : FPI<0xDA, MRM4m, (ops i32mem:$src), "fisub{l} $src">;
184 def FISUBR16m : FPI<0xDE, MRM5m, (ops i16mem:$src), "fisubr{s} $src">;
185 def FISUBR32m : FPI<0xDA, MRM5m, (ops i32mem:$src), "fisubr{l} $src">;
186 def FIDIV16m  : FPI<0xDE, MRM6m, (ops i16mem:$src), "fidiv{s} $src">;
187 def FIDIV32m  : FPI<0xDA, MRM6m, (ops i32mem:$src), "fidiv{l} $src">;
188 def FIDIVR16m : FPI<0xDE, MRM7m, (ops i16mem:$src), "fidivr{s} $src">;
189 def FIDIVR32m : FPI<0xDA, MRM7m, (ops i32mem:$src), "fidivr{l} $src">;
190
191 // NOTE: GAS and apparently all other AT&T style assemblers have a broken notion
192 // of some of the 'reverse' forms of the fsub and fdiv instructions.  As such,
193 // we have to put some 'r's in and take them out of weird places.
194 def FADDST0r   : FPST0rInst <0xC0, "fadd $op">;
195 def FADDrST0   : FPrST0Inst <0xC0, "fadd {%st(0), $op|$op, %ST(0)}">;
196 def FADDPrST0  : FPrST0PInst<0xC0, "faddp $op">;
197 def FSUBRST0r  : FPST0rInst <0xE8, "fsubr $op">;
198 def FSUBrST0   : FPrST0Inst <0xE8, "fsub{r} {%st(0), $op|$op, %ST(0)}">;
199 def FSUBPrST0  : FPrST0PInst<0xE8, "fsub{r}p $op">;
200 def FSUBST0r   : FPST0rInst <0xE0, "fsub $op">;
201 def FSUBRrST0  : FPrST0Inst <0xE0, "fsub{|r} {%st(0), $op|$op, %ST(0)}">;
202 def FSUBRPrST0 : FPrST0PInst<0xE0, "fsub{|r}p $op">;
203 def FMULST0r   : FPST0rInst <0xC8, "fmul $op">;
204 def FMULrST0   : FPrST0Inst <0xC8, "fmul {%st(0), $op|$op, %ST(0)}">;
205 def FMULPrST0  : FPrST0PInst<0xC8, "fmulp $op">;
206 def FDIVRST0r  : FPST0rInst <0xF8, "fdivr $op">;
207 def FDIVrST0   : FPrST0Inst <0xF8, "fdiv{r} {%st(0), $op|$op, %ST(0)}">;
208 def FDIVPrST0  : FPrST0PInst<0xF8, "fdiv{r}p $op">;
209 def FDIVST0r   : FPST0rInst <0xF0, "fdiv $op">;
210 def FDIVRrST0  : FPrST0Inst <0xF0, "fdiv{|r} {%st(0), $op|$op, %ST(0)}">;
211 def FDIVRPrST0 : FPrST0PInst<0xF0, "fdiv{|r}p $op">;
212
213
214 // Unary operations.
215 def FpCHS  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
216                  [(set RFP:$dst, (fneg RFP:$src))]>;
217 def FpABS  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
218                  [(set RFP:$dst, (fabs RFP:$src))]>;
219 def FpSQRT : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
220                  [(set RFP:$dst, (fsqrt RFP:$src))]>;
221 def FpSIN  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
222                  [(set RFP:$dst, (fsin RFP:$src))]>;
223 def FpCOS  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
224                  [(set RFP:$dst, (fcos RFP:$src))]>;
225 def FpTST  : FpI<(ops RFP:$src), OneArgFP,
226                  []>;
227
228 def FCHS  : FPI<0xE0, RawFrm, (ops), "fchs">, D9;
229 def FABS  : FPI<0xE1, RawFrm, (ops), "fabs">, D9;
230 def FSQRT : FPI<0xFA, RawFrm, (ops), "fsqrt">, D9;
231 def FSIN  : FPI<0xFE, RawFrm, (ops), "fsin">, D9;
232 def FCOS  : FPI<0xFF, RawFrm, (ops), "fcos">, D9;
233 def FTST  : FPI<0xE4, RawFrm, (ops), "ftst">, D9;
234
235
236 // Floating point cmovs.
237 let isTwoAddress = 1 in {
238   def FpCMOVB  : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
239                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
240                                       X86_COND_B))]>;
241   def FpCMOVBE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
242                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
243                                       X86_COND_BE))]>;
244   def FpCMOVE  : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
245                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
246                                       X86_COND_E))]>;
247   def FpCMOVP  : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
248                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
249                                       X86_COND_P))]>;
250   def FpCMOVNB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
251                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
252                                       X86_COND_AE))]>;
253   def FpCMOVNBE: FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
254                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
255                                       X86_COND_A))]>;
256   def FpCMOVNE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
257                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
258                                       X86_COND_NE))]>;
259   def FpCMOVNP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
260                      [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
261                                       X86_COND_NP))]>;
262 }
263
264 def FCMOVB  : FPI<0xC0, AddRegFrm, (ops RST:$op),
265                   "fcmovb {$op, %st(0)|%ST(0), $op}">, DA;
266 def FCMOVBE : FPI<0xD0, AddRegFrm, (ops RST:$op),
267                   "fcmovbe {$op, %st(0)|%ST(0), $op}">, DA;
268 def FCMOVE  : FPI<0xC8, AddRegFrm, (ops RST:$op),
269                   "fcmove {$op, %st(0)|%ST(0), $op}">, DA;
270 def FCMOVP  : FPI<0xD8, AddRegFrm, (ops RST:$op),
271                   "fcmovu  {$op, %st(0)|%ST(0), $op}">, DA;
272 def FCMOVNB : FPI<0xC0, AddRegFrm, (ops RST:$op),
273                   "fcmovnb {$op, %st(0)|%ST(0), $op}">, DB;
274 def FCMOVNBE  : FPI<0xD0, AddRegFrm, (ops RST:$op),
275                   "fcmovnbe {$op, %st(0)|%ST(0), $op}">, DB;
276 def FCMOVNE : FPI<0xC8, AddRegFrm, (ops RST:$op),
277                   "fcmovne {$op, %st(0)|%ST(0), $op}">, DB;
278 def FCMOVNP : FPI<0xD8, AddRegFrm, (ops RST:$op),
279                   "fcmovnu {$op, %st(0)|%ST(0), $op}">, DB;
280
281 // Floating point loads & stores.
282 def FpLD32m  : FpI<(ops RFP:$dst, f32mem:$src), ZeroArgFP,
283                    [(set RFP:$dst, (extloadf64f32 addr:$src))]>;
284 def FpLD64m  : FpI<(ops RFP:$dst, f64mem:$src), ZeroArgFP,
285                    [(set RFP:$dst, (loadf64 addr:$src))]>;
286 def FpILD16m : FpI<(ops RFP:$dst, i16mem:$src), ZeroArgFP,
287                    [(set RFP:$dst, (X86fild addr:$src, i16))]>;
288 def FpILD32m : FpI<(ops RFP:$dst, i32mem:$src), ZeroArgFP,
289                    [(set RFP:$dst, (X86fild addr:$src, i32))]>;
290 def FpILD64m : FpI<(ops RFP:$dst, i64mem:$src), ZeroArgFP,
291                    [(set RFP:$dst, (X86fild addr:$src, i64))]>;
292
293 def FpST32m   : FpI<(ops f32mem:$op, RFP:$src), OneArgFP,
294                 [(truncstore RFP:$src, addr:$op, f32)]>;
295 def FpST64m   : FpI<(ops f64mem:$op, RFP:$src), OneArgFP,
296                 [(store RFP:$src, addr:$op)]>;
297
298 def FpSTP32m  : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>;
299 def FpSTP64m  : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>;
300 def FpIST16m  : FpI<(ops i16mem:$op, RFP:$src), OneArgFP, []>;
301 def FpIST32m  : FpI<(ops i32mem:$op, RFP:$src), OneArgFP, []>;
302 def FpIST64m  : FpI<(ops i64mem:$op, RFP:$src), OneArgFP, []>;
303
304 def FLD32m   : FPI<0xD9, MRM0m, (ops f32mem:$src), "fld{s} $src">;
305 def FLD64m   : FPI<0xDD, MRM0m, (ops f64mem:$src), "fld{l} $src">;
306 def FILD16m  : FPI<0xDF, MRM0m, (ops i16mem:$src), "fild{s} $src">;
307 def FILD32m  : FPI<0xDB, MRM0m, (ops i32mem:$src), "fild{l} $src">;
308 def FILD64m  : FPI<0xDF, MRM5m, (ops i64mem:$src), "fild{ll} $src">;
309 def FST32m   : FPI<0xD9, MRM2m, (ops f32mem:$dst), "fst{s} $dst">;
310 def FST64m   : FPI<0xDD, MRM2m, (ops f64mem:$dst), "fst{l} $dst">;
311 def FSTP32m  : FPI<0xD9, MRM3m, (ops f32mem:$dst), "fstp{s} $dst">;
312 def FSTP64m  : FPI<0xDD, MRM3m, (ops f64mem:$dst), "fstp{l} $dst">;
313 def FIST16m  : FPI<0xDF, MRM2m, (ops i16mem:$dst), "fist{s} $dst">;
314 def FIST32m  : FPI<0xDB, MRM2m, (ops i32mem:$dst), "fist{l} $dst">;
315 def FISTP16m : FPI<0xDF, MRM3m, (ops i16mem:$dst), "fistp{s} $dst">;
316 def FISTP32m : FPI<0xDB, MRM3m, (ops i32mem:$dst), "fistp{l} $dst">;
317 def FISTP64m : FPI<0xDF, MRM7m, (ops i64mem:$dst), "fistp{ll} $dst">;
318
319 // FISTTP requires SSE3 even though it's a FPStack op.
320 def FpISTT16m  : FpI_<(ops i16mem:$op, RFP:$src), OneArgFP,
321                 [(X86fp_to_i16mem RFP:$src, addr:$op)]>,
322                 Requires<[HasSSE3]>;
323 def FpISTT32m  : FpI_<(ops i32mem:$op, RFP:$src), OneArgFP,
324                 [(X86fp_to_i32mem RFP:$src, addr:$op)]>,
325                 Requires<[HasSSE3]>;
326 def FpISTT64m  : FpI_<(ops i64mem:$op, RFP:$src), OneArgFP,
327                 [(X86fp_to_i64mem RFP:$src, addr:$op)]>,
328                 Requires<[HasSSE3]>;
329
330 def FISTTP16m : FPI<0xDF, MRM1m, (ops i16mem:$dst), "fisttp{s} $dst">;
331 def FISTTP32m : FPI<0xDB, MRM1m, (ops i32mem:$dst), "fisttp{l} $dst">;
332 def FISTTP64m : FPI<0xDD, MRM1m, (ops i64mem:$dst), "fisttp{ll} $dst">;
333
334 // FP Stack manipulation instructions.
335 def FLDrr   : FPI<0xC0, AddRegFrm, (ops RST:$op), "fld $op">, D9;
336 def FSTrr   : FPI<0xD0, AddRegFrm, (ops RST:$op), "fst $op">, DD;
337 def FSTPrr  : FPI<0xD8, AddRegFrm, (ops RST:$op), "fstp $op">, DD;
338 def FXCH    : FPI<0xC8, AddRegFrm, (ops RST:$op), "fxch $op">, D9;
339
340 // Floating point constant loads.
341 def FpLD0 : FpI<(ops RFP:$dst), ZeroArgFP,
342                 [(set RFP:$dst, fp64imm0)]>;
343 def FpLD1 : FpI<(ops RFP:$dst), ZeroArgFP,
344                 [(set RFP:$dst, fp64imm1)]>;
345
346 def FLD0 : FPI<0xEE, RawFrm, (ops), "fldz">, D9;
347 def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9;
348
349
350 // Floating point compares.
351 def FpUCOMr   : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP,
352                     []>;  // FPSW = cmp ST(0) with ST(i)
353 def FpUCOMIr  : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP,
354                     [(X86cmp RFP:$lhs, RFP:$rhs)]>; // CC = cmp ST(0) with ST(i)
355
356 def FUCOMr    : FPI<0xE0, AddRegFrm,    // FPSW = cmp ST(0) with ST(i)
357                     (ops RST:$reg),
358                     "fucom $reg">, DD, Imp<[ST0],[]>;
359 def FUCOMPr   : FPI<0xE8, AddRegFrm,    // FPSW = cmp ST(0) with ST(i), pop
360                   (ops RST:$reg),
361                   "fucomp $reg">, DD, Imp<[ST0],[]>;
362 def FUCOMPPr  : FPI<0xE9, RawFrm,       // cmp ST(0) with ST(1), pop, pop
363                   (ops),
364                   "fucompp">, DA, Imp<[ST0],[]>;
365
366 def FUCOMIr  : FPI<0xE8, AddRegFrm,     // CC = cmp ST(0) with ST(i)
367                    (ops RST:$reg),
368                    "fucomi {$reg, %st(0)|%ST(0), $reg}">, DB, Imp<[ST0],[]>;
369 def FUCOMIPr : FPI<0xE8, AddRegFrm,     // CC = cmp ST(0) with ST(i), pop
370                  (ops RST:$reg),
371                  "fucomip {$reg, %st(0)|%ST(0), $reg}">, DF, Imp<[ST0],[]>;
372
373
374 // Floating point flag ops.
375 def FNSTSW8r  : I<0xE0, RawFrm,                  // AX = fp flags
376                   (ops), "fnstsw", []>, DF, Imp<[],[AX]>;
377
378 def FNSTCW16m : I<0xD9, MRM7m,                   // [mem16] = X87 control world
379                   (ops i16mem:$dst), "fnstcw $dst", []>;
380 def FLDCW16m  : I<0xD9, MRM5m,                   // X87 control world = [mem16]
381                   (ops i16mem:$dst), "fldcw $dst", []>;
382
383
384 //===----------------------------------------------------------------------===//
385 // Alias Instructions
386 //===----------------------------------------------------------------------===//
387
388 // Alias instructions that map fld0 to pxor for sse.
389 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
390 def FsFLD0SS : I<0xEF, MRMInitReg, (ops FR32:$dst),
391                  "pxor $dst, $dst", [(set FR32:$dst, fp32imm0)]>,
392                Requires<[HasSSE1]>, TB, OpSize;
393 def FsFLD0SD : I<0xEF, MRMInitReg, (ops FR64:$dst),
394                  "pxor $dst, $dst", [(set FR64:$dst, fp64imm0)]>,
395                Requires<[HasSSE2]>, TB, OpSize;
396
397 // Alias instructions to do FR32 / FR64 reg-to-reg copy using movaps / movapd.
398 // Upper bits are disregarded.
399 def FsMOVAPSrr : I<0x28, MRMSrcReg, (ops V4F32:$dst, V4F32:$src),
400                    "movaps {$src, $dst|$dst, $src}", []>,
401                  Requires<[HasSSE1]>, TB;
402 def FsMOVAPDrr : I<0x28, MRMSrcReg, (ops V2F64:$dst, V2F64:$src),
403                    "movapd {$src, $dst|$dst, $src}", []>,
404                  Requires<[HasSSE2]>, TB, OpSize;
405
406 // Alias instructions to load FR32 / FR64 from f128mem using movaps / movapd.
407 // Upper bits are disregarded.
408 def FsMOVAPSrm : I<0x28, MRMSrcMem, (ops FR32:$dst, f128mem:$src),
409                    "movaps {$src, $dst|$dst, $src}",
410                    [(set FR32:$dst, (X86loadpf32 addr:$src))]>,
411                  Requires<[HasSSE1]>, TB;
412 def FsMOVAPDrm : I<0x28, MRMSrcMem, (ops FR64:$dst, f128mem:$src),
413                   "movapd {$src, $dst|$dst, $src}",
414                   [(set FR64:$dst, (X86loadpf64 addr:$src))]>,
415                 Requires<[HasSSE2]>, TB, OpSize;
416
417 // Alias bitwise logical operations using SSE logical ops on packed FP values.
418 let isTwoAddress = 1 in {
419 let isCommutable = 1 in {
420 def FsANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
421                   "andps {$src2, $dst|$dst, $src2}",
422                   [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>,
423                 Requires<[HasSSE1]>, TB;
424 def FsANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
425                   "andpd {$src2, $dst|$dst, $src2}",
426                   [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>,
427                 Requires<[HasSSE2]>, TB, OpSize;
428 def FsORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
429                  "orps {$src2, $dst|$dst, $src2}", []>,
430                Requires<[HasSSE1]>, TB;
431 def FsORPDrr : I<0x56, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
432                  "orpd {$src2, $dst|$dst, $src2}", []>,
433                Requires<[HasSSE2]>, TB, OpSize;
434 def FsXORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
435                   "xorps {$src2, $dst|$dst, $src2}",
436                   [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>,
437                 Requires<[HasSSE1]>, TB;
438 def FsXORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
439                   "xorpd {$src2, $dst|$dst, $src2}",
440                   [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>,
441                 Requires<[HasSSE2]>, TB, OpSize;
442 }
443 def FsANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
444                   "andps {$src2, $dst|$dst, $src2}",
445                   [(set FR32:$dst, (X86fand FR32:$src1,
446                                     (X86loadpf32 addr:$src2)))]>,
447                 Requires<[HasSSE1]>, TB;
448 def FsANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
449                   "andpd {$src2, $dst|$dst, $src2}",
450                   [(set FR64:$dst, (X86fand FR64:$src1,
451                                     (X86loadpf64 addr:$src2)))]>,
452                 Requires<[HasSSE2]>, TB, OpSize;
453 def FsORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
454                  "orps {$src2, $dst|$dst, $src2}", []>,
455                Requires<[HasSSE1]>, TB;
456 def FsORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
457                  "orpd {$src2, $dst|$dst, $src2}", []>,
458                Requires<[HasSSE2]>, TB, OpSize;
459 def FsXORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
460                   "xorps {$src2, $dst|$dst, $src2}",
461                   [(set FR32:$dst, (X86fxor FR32:$src1,
462                                     (X86loadpf32 addr:$src2)))]>,
463                 Requires<[HasSSE1]>, TB;
464 def FsXORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
465                   "xorpd {$src2, $dst|$dst, $src2}",
466                   [(set FR64:$dst, (X86fxor FR64:$src1,
467                                     (X86loadpf64 addr:$src2)))]>,
468                 Requires<[HasSSE2]>, TB, OpSize;
469
470 def FsANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
471                    "andnps {$src2, $dst|$dst, $src2}", []>,
472                  Requires<[HasSSE1]>, TB;
473 def FsANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2),
474                    "andnps {$src2, $dst|$dst, $src2}", []>,
475                  Requires<[HasSSE1]>, TB;
476 def FsANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
477                    "andnpd {$src2, $dst|$dst, $src2}", []>,
478                  Requires<[HasSSE2]>, TB, OpSize;
479 def FsANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2),
480                    "andnpd {$src2, $dst|$dst, $src2}", []>,
481                  Requires<[HasSSE2]>, TB, OpSize;
482 }