1239310Sdimdef SDTHexagonFCONST32 : SDTypeProfile<1, 1, [
2239310Sdim                                            SDTCisVT<0, f32>,
3239310Sdim                                            SDTCisPtrTy<1>]>;
4239310Sdimdef HexagonFCONST32 : SDNode<"HexagonISD::FCONST32",     SDTHexagonFCONST32>;
5239310Sdim
6239310Sdimlet isReMaterializable = 1, isMoveImm = 1 in
7239310Sdimdef FCONST32_nsdata : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global),
8239310Sdim              "$dst = CONST32(#$global)",
9239310Sdim              [(set (f32 IntRegs:$dst),
10239310Sdim              (HexagonFCONST32 tglobaladdr:$global))]>,
11239310Sdim               Requires<[HasV5T]>;
12239310Sdim
13239310Sdimlet isReMaterializable = 1, isMoveImm = 1 in
14239310Sdimdef CONST64_Float_Real : LDInst<(outs DoubleRegs:$dst), (ins f64imm:$src1),
15239310Sdim                       "$dst = CONST64(#$src1)",
16239310Sdim                       [(set DoubleRegs:$dst, fpimm:$src1)]>,
17239310Sdim          Requires<[HasV5T]>;
18239310Sdim
19239310Sdimlet isReMaterializable = 1, isMoveImm = 1 in
20239310Sdimdef CONST32_Float_Real : LDInst<(outs IntRegs:$dst), (ins f32imm:$src1),
21239310Sdim                       "$dst = CONST32(#$src1)",
22239310Sdim                       [(set IntRegs:$dst, fpimm:$src1)]>,
23239310Sdim          Requires<[HasV5T]>;
24239310Sdim
25239310Sdim// Transfer immediate float.
26239310Sdim// Only works with single precision fp value.
27239310Sdim// For double precision, use CONST64_float_real, as 64bit transfer
28239310Sdim// can only hold 40-bit values - 32 from const ext + 8 bit immediate.
29263508Sdim// Make sure that complexity is more than the CONST32 pattern in
30263508Sdim// HexagonInstrInfo.td patterns.
31263508Sdimlet isExtended = 1, opExtendable = 1, isMoveImm = 1, isReMaterializable = 1,
32263508SdimisPredicable = 1, AddedComplexity = 30, validSubTargets = HasV5SubT,
33263508SdimisCodeGenOnly = 1 in
34263508Sdimdef TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32Ext:$src1),
35263508Sdim           "$dst = #$src1",
36239310Sdim           [(set IntRegs:$dst, fpimm:$src1)]>,
37239310Sdim          Requires<[HasV5T]>;
38239310Sdim
39263508Sdimlet isExtended = 1, opExtendable = 2, isPredicated = 1,
40263508SdimneverHasSideEffects = 1, validSubTargets = HasV5SubT in
41239310Sdimdef TFRI_cPt_f : ALU32_ri<(outs IntRegs:$dst),
42263508Sdim                          (ins PredRegs:$src1, f32Ext:$src2),
43263508Sdim           "if ($src1) $dst = #$src2",
44239310Sdim           []>,
45239310Sdim          Requires<[HasV5T]>;
46239310Sdim
47263508Sdimlet isExtended = 1, opExtendable = 2, isPredicated = 1, isPredicatedFalse = 1,
48263508SdimneverHasSideEffects = 1, validSubTargets = HasV5SubT in
49239310Sdimdef TFRI_cNotPt_f : ALU32_ri<(outs IntRegs:$dst),
50263508Sdim                             (ins PredRegs:$src1, f32Ext:$src2),
51263508Sdim           "if (!$src1) $dst =#$src2",
52239310Sdim           []>,
53239310Sdim          Requires<[HasV5T]>;
54239310Sdim
55239310Sdim// Convert single precision to double precision and vice-versa.
56239310Sdimdef CONVERT_sf2df : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
57239310Sdim                "$dst = convert_sf2df($src)",
58239310Sdim                [(set DoubleRegs:$dst, (fextend IntRegs:$src))]>,
59239310Sdim          Requires<[HasV5T]>;
60239310Sdim
61239310Sdimdef CONVERT_df2sf : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
62239310Sdim                "$dst = convert_df2sf($src)",
63239310Sdim                [(set IntRegs:$dst, (fround DoubleRegs:$src))]>,
64239310Sdim          Requires<[HasV5T]>;
65239310Sdim
66239310Sdim
67239310Sdim// Load.
68239310Sdimdef LDrid_f : LDInst<(outs DoubleRegs:$dst),
69239310Sdim            (ins MEMri:$addr),
70239310Sdim            "$dst = memd($addr)",
71239310Sdim            [(set DoubleRegs:$dst, (f64 (load ADDRriS11_3:$addr)))]>,
72239310Sdim          Requires<[HasV5T]>;
73239310Sdim
74239310Sdim
75239310Sdimlet AddedComplexity = 20 in
76239310Sdimdef LDrid_indexed_f : LDInst<(outs DoubleRegs:$dst),
77239310Sdim            (ins IntRegs:$src1, s11_3Imm:$offset),
78239310Sdim            "$dst = memd($src1+#$offset)",
79239310Sdim            [(set DoubleRegs:$dst, (f64 (load (add IntRegs:$src1,
80239310Sdim                                              s11_3ImmPred:$offset))))]>,
81239310Sdim          Requires<[HasV5T]>;
82239310Sdim
83239310Sdimdef LDriw_f : LDInst<(outs IntRegs:$dst),
84239310Sdim            (ins MEMri:$addr), "$dst = memw($addr)",
85239310Sdim            [(set IntRegs:$dst, (f32 (load ADDRriS11_2:$addr)))]>,
86239310Sdim          Requires<[HasV5T]>;
87239310Sdim
88239310Sdim
89239310Sdimlet AddedComplexity = 20 in
90239310Sdimdef LDriw_indexed_f : LDInst<(outs IntRegs:$dst),
91239310Sdim            (ins IntRegs:$src1, s11_2Imm:$offset),
92239310Sdim            "$dst = memw($src1+#$offset)",
93239310Sdim            [(set IntRegs:$dst, (f32 (load (add IntRegs:$src1,
94239310Sdim                                           s11_2ImmPred:$offset))))]>,
95239310Sdim          Requires<[HasV5T]>;
96239310Sdim
97239310Sdim// Store.
98239310Sdimdef STriw_f : STInst<(outs),
99239310Sdim            (ins MEMri:$addr, IntRegs:$src1),
100239310Sdim            "memw($addr) = $src1",
101239310Sdim            [(store (f32 IntRegs:$src1), ADDRriS11_2:$addr)]>,
102239310Sdim          Requires<[HasV5T]>;
103239310Sdim
104239310Sdimlet AddedComplexity = 10 in
105239310Sdimdef STriw_indexed_f : STInst<(outs),
106239310Sdim            (ins IntRegs:$src1, s11_2Imm:$src2, IntRegs:$src3),
107239310Sdim            "memw($src1+#$src2) = $src3",
108239310Sdim            [(store (f32 IntRegs:$src3),
109239310Sdim                (add IntRegs:$src1, s11_2ImmPred:$src2))]>,
110239310Sdim          Requires<[HasV5T]>;
111239310Sdim
112239310Sdimdef STrid_f : STInst<(outs),
113239310Sdim            (ins MEMri:$addr, DoubleRegs:$src1),
114239310Sdim            "memd($addr) = $src1",
115239310Sdim            [(store (f64 DoubleRegs:$src1), ADDRriS11_2:$addr)]>,
116239310Sdim          Requires<[HasV5T]>;
117239310Sdim
118239310Sdim// Indexed store double word.
119239310Sdimlet AddedComplexity = 10 in
120239310Sdimdef STrid_indexed_f : STInst<(outs),
121239310Sdim            (ins IntRegs:$src1, s11_3Imm:$src2,  DoubleRegs:$src3),
122239310Sdim            "memd($src1+#$src2) = $src3",
123239310Sdim            [(store (f64 DoubleRegs:$src3),
124239310Sdim                                (add IntRegs:$src1, s11_3ImmPred:$src2))]>,
125239310Sdim          Requires<[HasV5T]>;
126239310Sdim
127239310Sdim
128239310Sdim// Add
129239310Sdimlet isCommutable = 1 in
130239310Sdimdef fADD_rr : ALU64_rr<(outs IntRegs:$dst),
131239310Sdim            (ins IntRegs:$src1, IntRegs:$src2),
132239310Sdim            "$dst = sfadd($src1, $src2)",
133239310Sdim            [(set IntRegs:$dst, (fadd IntRegs:$src1, IntRegs:$src2))]>,
134239310Sdim          Requires<[HasV5T]>;
135239310Sdim
136239310Sdimlet isCommutable = 1 in
137239310Sdimdef fADD64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
138239310Sdim                                                     DoubleRegs:$src2),
139239310Sdim               "$dst = dfadd($src1, $src2)",
140239310Sdim               [(set DoubleRegs:$dst, (fadd DoubleRegs:$src1,
141239310Sdim                                           DoubleRegs:$src2))]>,
142239310Sdim          Requires<[HasV5T]>;
143239310Sdim
144239310Sdimdef fSUB_rr : ALU64_rr<(outs IntRegs:$dst),
145239310Sdim            (ins IntRegs:$src1, IntRegs:$src2),
146239310Sdim            "$dst = sfsub($src1, $src2)",
147239310Sdim            [(set IntRegs:$dst, (fsub IntRegs:$src1, IntRegs:$src2))]>,
148239310Sdim          Requires<[HasV5T]>;
149239310Sdim
150239310Sdimdef fSUB64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
151239310Sdim                                                     DoubleRegs:$src2),
152239310Sdim               "$dst = dfsub($src1, $src2)",
153239310Sdim               [(set DoubleRegs:$dst, (fsub DoubleRegs:$src1,
154239310Sdim                                           DoubleRegs:$src2))]>,
155239310Sdim               Requires<[HasV5T]>;
156239310Sdim
157239310Sdimlet isCommutable = 1 in
158239310Sdimdef fMUL_rr : ALU64_rr<(outs IntRegs:$dst),
159239310Sdim            (ins IntRegs:$src1, IntRegs:$src2),
160239310Sdim            "$dst = sfmpy($src1, $src2)",
161239310Sdim            [(set IntRegs:$dst, (fmul IntRegs:$src1, IntRegs:$src2))]>,
162239310Sdim            Requires<[HasV5T]>;
163239310Sdim
164239310Sdimlet isCommutable = 1 in
165239310Sdimdef fMUL64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
166239310Sdim                                                     DoubleRegs:$src2),
167239310Sdim               "$dst = dfmpy($src1, $src2)",
168239310Sdim               [(set DoubleRegs:$dst, (fmul DoubleRegs:$src1,
169239310Sdim                                           DoubleRegs:$src2))]>,
170239310Sdim               Requires<[HasV5T]>;
171239310Sdim
172239310Sdim// Compare.
173239310Sdimlet isCompare = 1 in {
174239310Sdimmulticlass FCMP64_rr<string OpcStr, PatFrag OpNode> {
175239310Sdim  def _rr : ALU64_rr<(outs PredRegs:$dst), (ins DoubleRegs:$b, DoubleRegs:$c),
176239310Sdim                 !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
177239310Sdim                 [(set PredRegs:$dst,
178239310Sdim                        (OpNode (f64 DoubleRegs:$b), (f64 DoubleRegs:$c)))]>,
179239310Sdim                 Requires<[HasV5T]>;
180239310Sdim}
181239310Sdim
182239310Sdimmulticlass FCMP32_rr<string OpcStr, PatFrag OpNode> {
183239310Sdim  def _rr : ALU64_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
184239310Sdim                 !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
185239310Sdim                 [(set PredRegs:$dst,
186239310Sdim                        (OpNode (f32 IntRegs:$b), (f32 IntRegs:$c)))]>,
187239310Sdim                 Requires<[HasV5T]>;
188239310Sdim}
189239310Sdim}
190239310Sdim
191239310Sdimdefm FCMPOEQ64 : FCMP64_rr<"dfcmp.eq", setoeq>;
192239310Sdimdefm FCMPUEQ64 : FCMP64_rr<"dfcmp.eq", setueq>;
193239310Sdimdefm FCMPOGT64 : FCMP64_rr<"dfcmp.gt", setogt>;
194239310Sdimdefm FCMPUGT64 : FCMP64_rr<"dfcmp.gt", setugt>;
195239310Sdimdefm FCMPOGE64 : FCMP64_rr<"dfcmp.ge", setoge>;
196239310Sdimdefm FCMPUGE64 : FCMP64_rr<"dfcmp.ge", setuge>;
197239310Sdim
198239310Sdimdefm FCMPOEQ32 : FCMP32_rr<"sfcmp.eq", setoeq>;
199239310Sdimdefm FCMPUEQ32 : FCMP32_rr<"sfcmp.eq", setueq>;
200239310Sdimdefm FCMPOGT32 : FCMP32_rr<"sfcmp.gt", setogt>;
201239310Sdimdefm FCMPUGT32 : FCMP32_rr<"sfcmp.gt", setugt>;
202239310Sdimdefm FCMPOGE32 : FCMP32_rr<"sfcmp.ge", setoge>;
203239310Sdimdefm FCMPUGE32 : FCMP32_rr<"sfcmp.ge", setuge>;
204239310Sdim
205239310Sdim// olt.
206239310Sdimdef : Pat <(i1 (setolt (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
207239310Sdim      (i1 (FCMPOGT32_rr IntRegs:$src2, IntRegs:$src1))>,
208239310Sdim      Requires<[HasV5T]>;
209239310Sdim
210239310Sdimdef : Pat <(i1 (setolt (f32 IntRegs:$src1), (fpimm:$src2))),
211239310Sdim      (i1 (FCMPOGT32_rr (f32 (TFRI_f fpimm:$src2)), (f32 IntRegs:$src1)))>,
212239310Sdim      Requires<[HasV5T]>;
213239310Sdim
214239310Sdimdef : Pat <(i1 (setolt (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
215239310Sdim      (i1 (FCMPOGT64_rr DoubleRegs:$src2, DoubleRegs:$src1))>,
216239310Sdim      Requires<[HasV5T]>;
217239310Sdim
218239310Sdimdef : Pat <(i1 (setolt (f64 DoubleRegs:$src1), (fpimm:$src2))),
219239310Sdim      (i1 (FCMPOGT64_rr (f64 (CONST64_Float_Real fpimm:$src2)),
220239310Sdim                        (f64 DoubleRegs:$src1)))>,
221239310Sdim      Requires<[HasV5T]>;
222239310Sdim
223239310Sdim// gt.
224239310Sdimdef : Pat <(i1 (setugt (f64 DoubleRegs:$src1), (fpimm:$src2))),
225239310Sdim      (i1 (FCMPUGT64_rr (f64 DoubleRegs:$src1),
226239310Sdim                        (f64 (CONST64_Float_Real fpimm:$src2))))>,
227239310Sdim      Requires<[HasV5T]>;
228239310Sdim
229239310Sdimdef : Pat <(i1 (setugt (f32 IntRegs:$src1), (fpimm:$src2))),
230239310Sdim      (i1 (FCMPUGT32_rr (f32 IntRegs:$src1), (f32 (TFRI_f fpimm:$src2))))>,
231239310Sdim      Requires<[HasV5T]>;
232239310Sdim
233239310Sdim// ult.
234239310Sdimdef : Pat <(i1 (setult (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
235239310Sdim      (i1 (FCMPUGT32_rr IntRegs:$src2, IntRegs:$src1))>,
236239310Sdim      Requires<[HasV5T]>;
237239310Sdim
238239310Sdimdef : Pat <(i1 (setult (f32 IntRegs:$src1), (fpimm:$src2))),
239239310Sdim      (i1 (FCMPUGT32_rr (f32 (TFRI_f fpimm:$src2)), (f32 IntRegs:$src1)))>,
240239310Sdim      Requires<[HasV5T]>;
241239310Sdim
242239310Sdimdef : Pat <(i1 (setult (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
243239310Sdim      (i1 (FCMPUGT64_rr DoubleRegs:$src2, DoubleRegs:$src1))>,
244239310Sdim      Requires<[HasV5T]>;
245239310Sdim
246239310Sdimdef : Pat <(i1 (setult (f64 DoubleRegs:$src1), (fpimm:$src2))),
247239310Sdim      (i1 (FCMPUGT64_rr (f64 (CONST64_Float_Real fpimm:$src2)),
248239310Sdim                        (f64 DoubleRegs:$src1)))>,
249239310Sdim      Requires<[HasV5T]>;
250239310Sdim
251239310Sdim// le.
252239310Sdim// rs <= rt -> rt >= rs.
253239310Sdimdef : Pat<(i1 (setole (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
254239310Sdim      (i1 (FCMPOGE32_rr IntRegs:$src2, IntRegs:$src1))>,
255239310Sdim      Requires<[HasV5T]>;
256239310Sdim
257239310Sdimdef : Pat<(i1 (setole (f32 IntRegs:$src1), (fpimm:$src2))),
258239310Sdim      (i1 (FCMPOGE32_rr (f32 (TFRI_f fpimm:$src2)), IntRegs:$src1))>,
259239310Sdim      Requires<[HasV5T]>;
260239310Sdim
261239310Sdim
262239310Sdim// Rss <= Rtt -> Rtt >= Rss.
263239310Sdimdef : Pat<(i1 (setole (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
264239310Sdim      (i1 (FCMPOGE64_rr DoubleRegs:$src2, DoubleRegs:$src1))>,
265239310Sdim      Requires<[HasV5T]>;
266239310Sdim
267239310Sdimdef : Pat<(i1 (setole (f64 DoubleRegs:$src1), (fpimm:$src2))),
268239310Sdim      (i1 (FCMPOGE64_rr (f64 (CONST64_Float_Real fpimm:$src2)),
269239310Sdim                                DoubleRegs:$src1))>,
270239310Sdim      Requires<[HasV5T]>;
271239310Sdim
272239310Sdim// rs <= rt -> rt >= rs.
273239310Sdimdef : Pat<(i1 (setule (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
274239310Sdim      (i1 (FCMPUGE32_rr IntRegs:$src2, IntRegs:$src1))>,
275239310Sdim      Requires<[HasV5T]>;
276239310Sdim
277239310Sdimdef : Pat<(i1 (setule (f32 IntRegs:$src1), (fpimm:$src2))),
278239310Sdim      (i1 (FCMPUGE32_rr (f32 (TFRI_f fpimm:$src2)), IntRegs:$src1))>,
279239310Sdim      Requires<[HasV5T]>;
280239310Sdim
281239310Sdim// Rss <= Rtt -> Rtt >= Rss.
282239310Sdimdef : Pat<(i1 (setule (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
283239310Sdim      (i1 (FCMPUGE64_rr DoubleRegs:$src2, DoubleRegs:$src1))>,
284239310Sdim      Requires<[HasV5T]>;
285239310Sdim
286239310Sdimdef : Pat<(i1 (setule (f64 DoubleRegs:$src1), (fpimm:$src2))),
287239310Sdim      (i1 (FCMPUGE64_rr (f64 (CONST64_Float_Real fpimm:$src2)),
288239310Sdim                                DoubleRegs:$src1))>,
289239310Sdim      Requires<[HasV5T]>;
290239310Sdim
291239310Sdim// ne.
292239310Sdimdef : Pat<(i1 (setone (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
293239310Sdim      (i1 (NOT_p (FCMPOEQ32_rr IntRegs:$src1, IntRegs:$src2)))>,
294239310Sdim      Requires<[HasV5T]>;
295239310Sdim
296239310Sdimdef : Pat<(i1 (setone (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
297239310Sdim      (i1 (NOT_p (FCMPOEQ64_rr DoubleRegs:$src1, DoubleRegs:$src2)))>,
298239310Sdim      Requires<[HasV5T]>;
299239310Sdim
300239310Sdimdef : Pat<(i1 (setune (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
301239310Sdim      (i1 (NOT_p (FCMPUEQ32_rr IntRegs:$src1, IntRegs:$src2)))>,
302239310Sdim      Requires<[HasV5T]>;
303239310Sdim
304239310Sdimdef : Pat<(i1 (setune (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
305239310Sdim      (i1 (NOT_p (FCMPUEQ64_rr DoubleRegs:$src1, DoubleRegs:$src2)))>,
306239310Sdim      Requires<[HasV5T]>;
307239310Sdim
308239310Sdimdef : Pat<(i1 (setone (f32 IntRegs:$src1), (fpimm:$src2))),
309239310Sdim      (i1 (NOT_p (FCMPOEQ32_rr IntRegs:$src1, (f32 (TFRI_f fpimm:$src2)))))>,
310239310Sdim      Requires<[HasV5T]>;
311239310Sdim
312239310Sdimdef : Pat<(i1 (setone (f64 DoubleRegs:$src1), (fpimm:$src2))),
313239310Sdim      (i1 (NOT_p (FCMPOEQ64_rr DoubleRegs:$src1,
314239310Sdim                              (f64 (CONST64_Float_Real fpimm:$src2)))))>,
315239310Sdim      Requires<[HasV5T]>;
316239310Sdim
317239310Sdimdef : Pat<(i1 (setune (f32 IntRegs:$src1), (fpimm:$src2))),
318239310Sdim      (i1 (NOT_p (FCMPUEQ32_rr IntRegs:$src1,  (f32 (TFRI_f fpimm:$src2)))))>,
319239310Sdim      Requires<[HasV5T]>;
320239310Sdim
321239310Sdimdef : Pat<(i1 (setune (f64 DoubleRegs:$src1), (fpimm:$src2))),
322239310Sdim      (i1 (NOT_p (FCMPUEQ64_rr DoubleRegs:$src1,
323239310Sdim                              (f64 (CONST64_Float_Real fpimm:$src2)))))>,
324239310Sdim      Requires<[HasV5T]>;
325239310Sdim
326239310Sdim// Convert Integer to Floating Point.
327239310Sdimdef CONVERT_d2sf : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
328239310Sdim              "$dst = convert_d2sf($src)",
329239310Sdim              [(set (f32 IntRegs:$dst), (sint_to_fp (i64 DoubleRegs:$src)))]>,
330239310Sdim              Requires<[HasV5T]>;
331239310Sdim
332239310Sdimdef CONVERT_ud2sf : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
333239310Sdim              "$dst = convert_ud2sf($src)",
334239310Sdim              [(set (f32 IntRegs:$dst), (uint_to_fp (i64 DoubleRegs:$src)))]>,
335239310Sdim              Requires<[HasV5T]>;
336239310Sdim
337239310Sdimdef CONVERT_uw2sf : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
338239310Sdim              "$dst = convert_uw2sf($src)",
339239310Sdim              [(set (f32 IntRegs:$dst), (uint_to_fp (i32 IntRegs:$src)))]>,
340239310Sdim              Requires<[HasV5T]>;
341239310Sdim
342239310Sdimdef CONVERT_w2sf : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
343239310Sdim              "$dst = convert_w2sf($src)",
344239310Sdim              [(set (f32 IntRegs:$dst), (sint_to_fp (i32 IntRegs:$src)))]>,
345239310Sdim              Requires<[HasV5T]>;
346239310Sdim
347239310Sdimdef CONVERT_d2df : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
348239310Sdim              "$dst = convert_d2df($src)",
349239310Sdim              [(set (f64 DoubleRegs:$dst), (sint_to_fp (i64 DoubleRegs:$src)))]>,
350239310Sdim              Requires<[HasV5T]>;
351239310Sdim
352239310Sdimdef CONVERT_ud2df : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
353239310Sdim              "$dst = convert_ud2df($src)",
354239310Sdim              [(set (f64 DoubleRegs:$dst), (uint_to_fp (i64 DoubleRegs:$src)))]>,
355239310Sdim              Requires<[HasV5T]>;
356239310Sdim
357239310Sdimdef CONVERT_uw2df : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
358239310Sdim              "$dst = convert_uw2df($src)",
359239310Sdim              [(set (f64 DoubleRegs:$dst), (uint_to_fp (i32 IntRegs:$src)))]>,
360239310Sdim              Requires<[HasV5T]>;
361239310Sdim
362239310Sdimdef CONVERT_w2df : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
363239310Sdim              "$dst = convert_w2df($src)",
364239310Sdim              [(set (f64 DoubleRegs:$dst), (sint_to_fp (i32 IntRegs:$src)))]>,
365239310Sdim              Requires<[HasV5T]>;
366239310Sdim
367239310Sdim// Convert Floating Point to Integer - default.
368239310Sdimdef CONVERT_df2uw : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
369239310Sdim              "$dst = convert_df2uw($src):chop",
370239310Sdim              [(set (i32 IntRegs:$dst), (fp_to_uint (f64 DoubleRegs:$src)))]>,
371239310Sdim              Requires<[HasV5T]>;
372239310Sdim
373239310Sdimdef CONVERT_df2w : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
374239310Sdim              "$dst = convert_df2w($src):chop",
375239310Sdim              [(set (i32 IntRegs:$dst), (fp_to_sint (f64 DoubleRegs:$src)))]>,
376239310Sdim              Requires<[HasV5T]>;
377239310Sdim
378239310Sdimdef CONVERT_sf2uw : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
379239310Sdim              "$dst = convert_sf2uw($src):chop",
380239310Sdim              [(set (i32 IntRegs:$dst), (fp_to_uint (f32 IntRegs:$src)))]>,
381239310Sdim              Requires<[HasV5T]>;
382239310Sdim
383239310Sdimdef CONVERT_sf2w : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
384239310Sdim              "$dst = convert_sf2w($src):chop",
385239310Sdim              [(set (i32 IntRegs:$dst), (fp_to_sint (f32 IntRegs:$src)))]>,
386239310Sdim              Requires<[HasV5T]>;
387239310Sdim
388239310Sdimdef CONVERT_df2d : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
389239310Sdim              "$dst = convert_df2d($src):chop",
390239310Sdim              [(set (i64 DoubleRegs:$dst), (fp_to_sint (f64 DoubleRegs:$src)))]>,
391239310Sdim              Requires<[HasV5T]>;
392239310Sdim
393239310Sdimdef CONVERT_df2ud : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
394239310Sdim              "$dst = convert_df2ud($src):chop",
395239310Sdim              [(set (i64 DoubleRegs:$dst), (fp_to_uint (f64 DoubleRegs:$src)))]>,
396239310Sdim              Requires<[HasV5T]>;
397239310Sdim
398239310Sdimdef CONVERT_sf2d : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
399239310Sdim              "$dst = convert_sf2d($src):chop",
400239310Sdim              [(set (i64 DoubleRegs:$dst), (fp_to_sint (f32 IntRegs:$src)))]>,
401239310Sdim              Requires<[HasV5T]>;
402239310Sdim
403239310Sdimdef CONVERT_sf2ud : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
404239310Sdim              "$dst = convert_sf2ud($src):chop",
405239310Sdim              [(set (i64 DoubleRegs:$dst), (fp_to_uint (f32 IntRegs:$src)))]>,
406239310Sdim              Requires<[HasV5T]>;
407239310Sdim
408239310Sdim// Convert Floating Point to Integer: non-chopped.
409239310Sdimlet AddedComplexity = 20 in
410239310Sdimdef CONVERT_df2uw_nchop : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
411239310Sdim              "$dst = convert_df2uw($src)",
412239310Sdim              [(set (i32 IntRegs:$dst), (fp_to_uint (f64 DoubleRegs:$src)))]>,
413239310Sdim              Requires<[HasV5T, IEEERndNearV5T]>;
414239310Sdim
415239310Sdimlet AddedComplexity = 20 in
416239310Sdimdef CONVERT_df2w_nchop : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
417239310Sdim              "$dst = convert_df2w($src)",
418239310Sdim              [(set (i32 IntRegs:$dst), (fp_to_sint (f64 DoubleRegs:$src)))]>,
419239310Sdim              Requires<[HasV5T, IEEERndNearV5T]>;
420239310Sdim
421239310Sdimlet AddedComplexity = 20 in
422239310Sdimdef CONVERT_sf2uw_nchop : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
423239310Sdim              "$dst = convert_sf2uw($src)",
424239310Sdim              [(set (i32 IntRegs:$dst), (fp_to_uint (f32 IntRegs:$src)))]>,
425239310Sdim              Requires<[HasV5T, IEEERndNearV5T]>;
426239310Sdim
427239310Sdimlet AddedComplexity = 20 in
428239310Sdimdef CONVERT_sf2w_nchop : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
429239310Sdim              "$dst = convert_sf2w($src)",
430239310Sdim              [(set (i32 IntRegs:$dst), (fp_to_sint (f32 IntRegs:$src)))]>,
431239310Sdim              Requires<[HasV5T, IEEERndNearV5T]>;
432239310Sdim
433239310Sdimlet AddedComplexity = 20 in
434239310Sdimdef CONVERT_df2d_nchop : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
435239310Sdim              "$dst = convert_df2d($src)",
436239310Sdim              [(set (i64 DoubleRegs:$dst), (fp_to_sint (f64 DoubleRegs:$src)))]>,
437239310Sdim              Requires<[HasV5T, IEEERndNearV5T]>;
438239310Sdim
439239310Sdimlet AddedComplexity = 20 in
440239310Sdimdef CONVERT_df2ud_nchop : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
441239310Sdim              "$dst = convert_df2ud($src)",
442239310Sdim              [(set (i64 DoubleRegs:$dst), (fp_to_uint (f64 DoubleRegs:$src)))]>,
443239310Sdim              Requires<[HasV5T, IEEERndNearV5T]>;
444239310Sdim
445239310Sdimlet AddedComplexity = 20 in
446239310Sdimdef CONVERT_sf2d_nchop : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
447239310Sdim              "$dst = convert_sf2d($src)",
448239310Sdim              [(set (i64 DoubleRegs:$dst), (fp_to_sint (f32 IntRegs:$src)))]>,
449239310Sdim              Requires<[HasV5T, IEEERndNearV5T]>;
450239310Sdim
451239310Sdimlet AddedComplexity = 20 in
452239310Sdimdef CONVERT_sf2ud_nchop : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
453239310Sdim              "$dst = convert_sf2ud($src)",
454239310Sdim              [(set (i64 DoubleRegs:$dst), (fp_to_uint (f32 IntRegs:$src)))]>,
455239310Sdim              Requires<[HasV5T, IEEERndNearV5T]>;
456239310Sdim
457239310Sdim
458239310Sdim
459239310Sdim// Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp].
460239310Sdimdef : Pat <(i32 (bitconvert (f32 IntRegs:$src))),
461239310Sdim           (i32 (TFR IntRegs:$src))>,
462239310Sdim          Requires<[HasV5T]>;
463239310Sdim
464239310Sdimdef : Pat <(f32 (bitconvert (i32 IntRegs:$src))),
465239310Sdim           (f32 (TFR IntRegs:$src))>,
466239310Sdim          Requires<[HasV5T]>;
467239310Sdim
468239310Sdimdef : Pat <(i64 (bitconvert (f64 DoubleRegs:$src))),
469239310Sdim           (i64 (TFR64 DoubleRegs:$src))>,
470239310Sdim          Requires<[HasV5T]>;
471239310Sdim
472239310Sdimdef : Pat <(f64 (bitconvert (i64 DoubleRegs:$src))),
473239310Sdim           (f64 (TFR64 DoubleRegs:$src))>,
474239310Sdim          Requires<[HasV5T]>;
475239310Sdim
476239310Sdim// Floating point fused multiply-add.
477239310Sdimdef FMADD_dp : ALU64_acc<(outs DoubleRegs:$dst),
478239310Sdim                  (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
479239310Sdim              "$dst += dfmpy($src2, $src3)",
480239310Sdim              [(set (f64 DoubleRegs:$dst),
481239310Sdim                  (fma DoubleRegs:$src2, DoubleRegs:$src3, DoubleRegs:$src1))],
482239310Sdim                  "$src1 = $dst">,
483239310Sdim              Requires<[HasV5T]>;
484239310Sdim
485239310Sdimdef FMADD_sp : ALU64_acc<(outs IntRegs:$dst),
486239310Sdim                  (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
487239310Sdim              "$dst += sfmpy($src2, $src3)",
488239310Sdim              [(set (f32 IntRegs:$dst),
489239310Sdim                  (fma IntRegs:$src2, IntRegs:$src3, IntRegs:$src1))],
490239310Sdim                  "$src1 = $dst">,
491239310Sdim              Requires<[HasV5T]>;
492239310Sdim
493239310Sdim
494239310Sdim// Floating point max/min.
495239310Sdimlet AddedComplexity = 100 in
496239310Sdimdef FMAX_dp : ALU64_rr<(outs DoubleRegs:$dst),
497239310Sdim                  (ins DoubleRegs:$src1, DoubleRegs:$src2),
498239310Sdim              "$dst = dfmax($src1, $src2)",
499239310Sdim              [(set DoubleRegs:$dst, (f64 (select (i1 (setolt DoubleRegs:$src2,
500239310Sdim                                                        DoubleRegs:$src1)),
501239310Sdim                                             DoubleRegs:$src1,
502239310Sdim                                             DoubleRegs:$src2)))]>,
503239310Sdim               Requires<[HasV5T]>;
504239310Sdim
505239310Sdimlet AddedComplexity = 100 in
506239310Sdimdef FMAX_sp : ALU64_rr<(outs IntRegs:$dst),
507239310Sdim                  (ins IntRegs:$src1, IntRegs:$src2),
508239310Sdim              "$dst = sfmax($src1, $src2)",
509239310Sdim              [(set IntRegs:$dst, (f32 (select (i1 (setolt IntRegs:$src2,
510239310Sdim                                                        IntRegs:$src1)),
511239310Sdim                                             IntRegs:$src1,
512239310Sdim                                             IntRegs:$src2)))]>,
513239310Sdim               Requires<[HasV5T]>;
514239310Sdim
515239310Sdimlet AddedComplexity = 100 in
516239310Sdimdef FMIN_dp : ALU64_rr<(outs DoubleRegs:$dst),
517239310Sdim                  (ins DoubleRegs:$src1, DoubleRegs:$src2),
518239310Sdim              "$dst = dfmin($src1, $src2)",
519239310Sdim              [(set DoubleRegs:$dst, (f64 (select (i1 (setogt DoubleRegs:$src2,
520239310Sdim                                                        DoubleRegs:$src1)),
521239310Sdim                                             DoubleRegs:$src1,
522239310Sdim                                             DoubleRegs:$src2)))]>,
523239310Sdim               Requires<[HasV5T]>;
524239310Sdim
525239310Sdimlet AddedComplexity = 100 in
526239310Sdimdef FMIN_sp : ALU64_rr<(outs IntRegs:$dst),
527239310Sdim                  (ins IntRegs:$src1, IntRegs:$src2),
528239310Sdim              "$dst = sfmin($src1, $src2)",
529239310Sdim              [(set IntRegs:$dst, (f32 (select (i1 (setogt IntRegs:$src2,
530239310Sdim                                                        IntRegs:$src1)),
531239310Sdim                                             IntRegs:$src1,
532239310Sdim                                             IntRegs:$src2)))]>,
533239310Sdim               Requires<[HasV5T]>;
534239310Sdim
535239310Sdim// Pseudo instruction to encode a set of conditional transfers.
536239310Sdim// This instruction is used instead of a mux and trades-off codesize
537239310Sdim// for performance. We conduct this transformation optimistically in
538239310Sdim// the hope that these instructions get promoted to dot-new transfers.
539239310Sdimlet AddedComplexity = 100, isPredicated = 1 in
540239310Sdimdef TFR_condset_rr_f : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
541239310Sdim                                                        IntRegs:$src2,
542239310Sdim                                                        IntRegs:$src3),
543239310Sdim                     "Error; should not emit",
544239310Sdim                     [(set IntRegs:$dst, (f32 (select PredRegs:$src1,
545239310Sdim                                                 IntRegs:$src2,
546239310Sdim                                                 IntRegs:$src3)))]>,
547239310Sdim               Requires<[HasV5T]>;
548239310Sdim
549239310Sdimlet AddedComplexity = 100, isPredicated = 1 in
550239310Sdimdef TFR_condset_rr64_f : ALU32_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
551239310Sdim                                                        DoubleRegs:$src2,
552239310Sdim                                                        DoubleRegs:$src3),
553239310Sdim                     "Error; should not emit",
554239310Sdim                     [(set DoubleRegs:$dst, (f64 (select PredRegs:$src1,
555239310Sdim                                                 DoubleRegs:$src2,
556239310Sdim                                                 DoubleRegs:$src3)))]>,
557239310Sdim               Requires<[HasV5T]>;
558239310Sdim
559239310Sdim
560239310Sdim
561239310Sdimlet AddedComplexity = 100, isPredicated = 1 in
562239310Sdimdef TFR_condset_ri_f : ALU32_rr<(outs IntRegs:$dst),
563239310Sdim            (ins PredRegs:$src1, IntRegs:$src2, f32imm:$src3),
564239310Sdim            "Error; should not emit",
565239310Sdim            [(set IntRegs:$dst,
566239310Sdim             (f32 (select PredRegs:$src1, IntRegs:$src2, fpimm:$src3)))]>,
567239310Sdim               Requires<[HasV5T]>;
568239310Sdim
569239310Sdimlet AddedComplexity = 100, isPredicated = 1 in
570239310Sdimdef TFR_condset_ir_f : ALU32_rr<(outs IntRegs:$dst),
571239310Sdim            (ins PredRegs:$src1, f32imm:$src2, IntRegs:$src3),
572239310Sdim            "Error; should not emit",
573239310Sdim            [(set IntRegs:$dst,
574239310Sdim             (f32 (select PredRegs:$src1, fpimm:$src2, IntRegs:$src3)))]>,
575239310Sdim               Requires<[HasV5T]>;
576239310Sdim
577239310Sdimlet AddedComplexity = 100, isPredicated = 1 in
578239310Sdimdef TFR_condset_ii_f : ALU32_rr<(outs IntRegs:$dst),
579239310Sdim                              (ins PredRegs:$src1, f32imm:$src2, f32imm:$src3),
580239310Sdim                     "Error; should not emit",
581239310Sdim                     [(set IntRegs:$dst, (f32 (select PredRegs:$src1,
582239310Sdim                                                 fpimm:$src2,
583239310Sdim                                                 fpimm:$src3)))]>,
584239310Sdim               Requires<[HasV5T]>;
585239310Sdim
586239310Sdim
587239310Sdimdef : Pat <(select (i1 (setult (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
588239310Sdim                   (f32 IntRegs:$src3),
589239310Sdim                   (f32 IntRegs:$src4)),
590239310Sdim    (TFR_condset_rr_f (FCMPUGT32_rr IntRegs:$src2, IntRegs:$src1), IntRegs:$src4,
591239310Sdim                      IntRegs:$src3)>, Requires<[HasV5T]>;
592239310Sdim
593239310Sdimdef : Pat <(select (i1 (setult (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
594239310Sdim                   (f64 DoubleRegs:$src3),
595239310Sdim                   (f64 DoubleRegs:$src4)),
596239310Sdim      (TFR_condset_rr64_f (FCMPUGT64_rr DoubleRegs:$src2, DoubleRegs:$src1),
597239310Sdim                DoubleRegs:$src4, DoubleRegs:$src3)>, Requires<[HasV5T]>;
598239310Sdim
599239310Sdim// Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i).
600239310Sdimdef : Pat <(select (not PredRegs:$src1), fpimm:$src2, fpimm:$src3),
601239310Sdim      (TFR_condset_ii_f PredRegs:$src1, fpimm:$src3, fpimm:$src2)>;
602239310Sdim
603239310Sdim// Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
604239310Sdim// => r0 = TFR_condset_ri(p0, r1, #i)
605239310Sdimdef : Pat <(select (not PredRegs:$src1), fpimm:$src2, IntRegs:$src3),
606239310Sdim      (TFR_condset_ri_f PredRegs:$src1, IntRegs:$src3, fpimm:$src2)>;
607239310Sdim
608239310Sdim// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
609239310Sdim// => r0 = TFR_condset_ir(p0, #i, r1)
610239310Sdimdef : Pat <(select (not PredRegs:$src1), IntRegs:$src2, fpimm:$src3),
611239310Sdim      (TFR_condset_ir_f PredRegs:$src1, fpimm:$src3, IntRegs:$src2)>;
612239310Sdim
613239310Sdimdef : Pat <(i32 (fp_to_sint (f64 DoubleRegs:$src1))),
614239310Sdim          (i32 (EXTRACT_SUBREG (i64 (CONVERT_df2d (f64 DoubleRegs:$src1))), subreg_loreg))>,
615239310Sdim          Requires<[HasV5T]>;
616239310Sdim
617239310Sdimdef : Pat <(fabs (f32 IntRegs:$src1)),
618239310Sdim           (CLRBIT_31 (f32 IntRegs:$src1), 31)>,
619239310Sdim          Requires<[HasV5T]>;
620239310Sdim
621239310Sdimdef : Pat <(fneg (f32 IntRegs:$src1)),
622239310Sdim           (TOGBIT_31 (f32 IntRegs:$src1), 31)>,
623239310Sdim          Requires<[HasV5T]>;
624239310Sdim
625239310Sdim/*
626239310Sdimdef : Pat <(fabs (f64 DoubleRegs:$src1)),
627239310Sdim          (CLRBIT_31 (f32 (EXTRACT_SUBREG DoubleRegs:$src1, subreg_hireg)), 31)>,
628239310Sdim          Requires<[HasV5T]>;
629239310Sdim
630239310Sdimdef : Pat <(fabs (f64 DoubleRegs:$src1)),
631239310Sdim          (CLRBIT_31 (f32 (EXTRACT_SUBREG DoubleRegs:$src1, subreg_hireg)), 31)>,
632239310Sdim          Requires<[HasV5T]>;
633239310Sdim          */
634