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