1def SDTHexagonFCONST32 : SDTypeProfile<1, 1, [
2                                            SDTCisVT<0, f32>,
3                                            SDTCisPtrTy<1>]>;
4def HexagonFCONST32 : SDNode<"HexagonISD::FCONST32",     SDTHexagonFCONST32>;
5
6let isReMaterializable = 1, isMoveImm = 1 in
7def FCONST32_nsdata : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global),
8              "$dst = CONST32(#$global)",
9              [(set (f32 IntRegs:$dst),
10              (HexagonFCONST32 tglobaladdr:$global))]>,
11               Requires<[HasV5T]>;
12
13let isReMaterializable = 1, isMoveImm = 1 in
14def CONST64_Float_Real : LDInst<(outs DoubleRegs:$dst), (ins f64imm:$src1),
15                       "$dst = CONST64(#$src1)",
16                       [(set DoubleRegs:$dst, fpimm:$src1)]>,
17          Requires<[HasV5T]>;
18
19let isReMaterializable = 1, isMoveImm = 1 in
20def CONST32_Float_Real : LDInst<(outs IntRegs:$dst), (ins f32imm:$src1),
21                       "$dst = CONST32(#$src1)",
22                       [(set IntRegs:$dst, fpimm:$src1)]>,
23          Requires<[HasV5T]>;
24
25// Transfer immediate float.
26// Only works with single precision fp value.
27// For double precision, use CONST64_float_real, as 64bit transfer
28// can only hold 40-bit values - 32 from const ext + 8 bit immediate.
29// Make sure that complexity is more than the CONST32 pattern in
30// HexagonInstrInfo.td patterns.
31let isExtended = 1, opExtendable = 1, isMoveImm = 1, isReMaterializable = 1,
32isPredicable = 1, AddedComplexity = 30, validSubTargets = HasV5SubT,
33isCodeGenOnly = 1 in
34def TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32Ext:$src1),
35           "$dst = #$src1",
36           [(set IntRegs:$dst, fpimm:$src1)]>,
37          Requires<[HasV5T]>;
38
39let isExtended = 1, opExtendable = 2, isPredicated = 1,
40neverHasSideEffects = 1, validSubTargets = HasV5SubT in
41def TFRI_cPt_f : ALU32_ri<(outs IntRegs:$dst),
42                          (ins PredRegs:$src1, f32Ext:$src2),
43           "if ($src1) $dst = #$src2",
44           []>,
45          Requires<[HasV5T]>;
46
47let isExtended = 1, opExtendable = 2, isPredicated = 1, isPredicatedFalse = 1,
48neverHasSideEffects = 1, validSubTargets = HasV5SubT in
49def TFRI_cNotPt_f : ALU32_ri<(outs IntRegs:$dst),
50                             (ins PredRegs:$src1, f32Ext:$src2),
51           "if (!$src1) $dst =#$src2",
52           []>,
53          Requires<[HasV5T]>;
54
55// Convert single precision to double precision and vice-versa.
56def CONVERT_sf2df : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
57                "$dst = convert_sf2df($src)",
58                [(set DoubleRegs:$dst, (fextend IntRegs:$src))]>,
59          Requires<[HasV5T]>;
60
61def CONVERT_df2sf : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
62                "$dst = convert_df2sf($src)",
63                [(set IntRegs:$dst, (fround DoubleRegs:$src))]>,
64          Requires<[HasV5T]>;
65
66
67// Load.
68def LDrid_f : LDInst<(outs DoubleRegs:$dst),
69            (ins MEMri:$addr),
70            "$dst = memd($addr)",
71            [(set DoubleRegs:$dst, (f64 (load ADDRriS11_3:$addr)))]>,
72          Requires<[HasV5T]>;
73
74
75let AddedComplexity = 20 in
76def LDrid_indexed_f : LDInst<(outs DoubleRegs:$dst),
77            (ins IntRegs:$src1, s11_3Imm:$offset),
78            "$dst = memd($src1+#$offset)",
79            [(set DoubleRegs:$dst, (f64 (load (add IntRegs:$src1,
80                                              s11_3ImmPred:$offset))))]>,
81          Requires<[HasV5T]>;
82
83def LDriw_f : LDInst<(outs IntRegs:$dst),
84            (ins MEMri:$addr), "$dst = memw($addr)",
85            [(set IntRegs:$dst, (f32 (load ADDRriS11_2:$addr)))]>,
86          Requires<[HasV5T]>;
87
88
89let AddedComplexity = 20 in
90def LDriw_indexed_f : LDInst<(outs IntRegs:$dst),
91            (ins IntRegs:$src1, s11_2Imm:$offset),
92            "$dst = memw($src1+#$offset)",
93            [(set IntRegs:$dst, (f32 (load (add IntRegs:$src1,
94                                           s11_2ImmPred:$offset))))]>,
95          Requires<[HasV5T]>;
96
97// Store.
98def STriw_f : STInst<(outs),
99            (ins MEMri:$addr, IntRegs:$src1),
100            "memw($addr) = $src1",
101            [(store (f32 IntRegs:$src1), ADDRriS11_2:$addr)]>,
102          Requires<[HasV5T]>;
103
104let AddedComplexity = 10 in
105def STriw_indexed_f : STInst<(outs),
106            (ins IntRegs:$src1, s11_2Imm:$src2, IntRegs:$src3),
107            "memw($src1+#$src2) = $src3",
108            [(store (f32 IntRegs:$src3),
109                (add IntRegs:$src1, s11_2ImmPred:$src2))]>,
110          Requires<[HasV5T]>;
111
112def STrid_f : STInst<(outs),
113            (ins MEMri:$addr, DoubleRegs:$src1),
114            "memd($addr) = $src1",
115            [(store (f64 DoubleRegs:$src1), ADDRriS11_2:$addr)]>,
116          Requires<[HasV5T]>;
117
118// Indexed store double word.
119let AddedComplexity = 10 in
120def STrid_indexed_f : STInst<(outs),
121            (ins IntRegs:$src1, s11_3Imm:$src2,  DoubleRegs:$src3),
122            "memd($src1+#$src2) = $src3",
123            [(store (f64 DoubleRegs:$src3),
124                                (add IntRegs:$src1, s11_3ImmPred:$src2))]>,
125          Requires<[HasV5T]>;
126
127
128// Add
129let isCommutable = 1 in
130def fADD_rr : ALU64_rr<(outs IntRegs:$dst),
131            (ins IntRegs:$src1, IntRegs:$src2),
132            "$dst = sfadd($src1, $src2)",
133            [(set IntRegs:$dst, (fadd IntRegs:$src1, IntRegs:$src2))]>,
134          Requires<[HasV5T]>;
135
136let isCommutable = 1 in
137def fADD64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
138                                                     DoubleRegs:$src2),
139               "$dst = dfadd($src1, $src2)",
140               [(set DoubleRegs:$dst, (fadd DoubleRegs:$src1,
141                                           DoubleRegs:$src2))]>,
142          Requires<[HasV5T]>;
143
144def fSUB_rr : ALU64_rr<(outs IntRegs:$dst),
145            (ins IntRegs:$src1, IntRegs:$src2),
146            "$dst = sfsub($src1, $src2)",
147            [(set IntRegs:$dst, (fsub IntRegs:$src1, IntRegs:$src2))]>,
148          Requires<[HasV5T]>;
149
150def fSUB64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
151                                                     DoubleRegs:$src2),
152               "$dst = dfsub($src1, $src2)",
153               [(set DoubleRegs:$dst, (fsub DoubleRegs:$src1,
154                                           DoubleRegs:$src2))]>,
155               Requires<[HasV5T]>;
156
157let isCommutable = 1 in
158def fMUL_rr : ALU64_rr<(outs IntRegs:$dst),
159            (ins IntRegs:$src1, IntRegs:$src2),
160            "$dst = sfmpy($src1, $src2)",
161            [(set IntRegs:$dst, (fmul IntRegs:$src1, IntRegs:$src2))]>,
162            Requires<[HasV5T]>;
163
164let isCommutable = 1 in
165def fMUL64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
166                                                     DoubleRegs:$src2),
167               "$dst = dfmpy($src1, $src2)",
168               [(set DoubleRegs:$dst, (fmul DoubleRegs:$src1,
169                                           DoubleRegs:$src2))]>,
170               Requires<[HasV5T]>;
171
172// Compare.
173let isCompare = 1 in {
174multiclass FCMP64_rr<string OpcStr, PatFrag OpNode> {
175  def _rr : ALU64_rr<(outs PredRegs:$dst), (ins DoubleRegs:$b, DoubleRegs:$c),
176                 !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
177                 [(set PredRegs:$dst,
178                        (OpNode (f64 DoubleRegs:$b), (f64 DoubleRegs:$c)))]>,
179                 Requires<[HasV5T]>;
180}
181
182multiclass FCMP32_rr<string OpcStr, PatFrag OpNode> {
183  def _rr : ALU64_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
184                 !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
185                 [(set PredRegs:$dst,
186                        (OpNode (f32 IntRegs:$b), (f32 IntRegs:$c)))]>,
187                 Requires<[HasV5T]>;
188}
189}
190
191defm FCMPOEQ64 : FCMP64_rr<"dfcmp.eq", setoeq>;
192defm FCMPUEQ64 : FCMP64_rr<"dfcmp.eq", setueq>;
193defm FCMPOGT64 : FCMP64_rr<"dfcmp.gt", setogt>;
194defm FCMPUGT64 : FCMP64_rr<"dfcmp.gt", setugt>;
195defm FCMPOGE64 : FCMP64_rr<"dfcmp.ge", setoge>;
196defm FCMPUGE64 : FCMP64_rr<"dfcmp.ge", setuge>;
197
198defm FCMPOEQ32 : FCMP32_rr<"sfcmp.eq", setoeq>;
199defm FCMPUEQ32 : FCMP32_rr<"sfcmp.eq", setueq>;
200defm FCMPOGT32 : FCMP32_rr<"sfcmp.gt", setogt>;
201defm FCMPUGT32 : FCMP32_rr<"sfcmp.gt", setugt>;
202defm FCMPOGE32 : FCMP32_rr<"sfcmp.ge", setoge>;
203defm FCMPUGE32 : FCMP32_rr<"sfcmp.ge", setuge>;
204
205// olt.
206def : Pat <(i1 (setolt (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
207      (i1 (FCMPOGT32_rr IntRegs:$src2, IntRegs:$src1))>,
208      Requires<[HasV5T]>;
209
210def : Pat <(i1 (setolt (f32 IntRegs:$src1), (fpimm:$src2))),
211      (i1 (FCMPOGT32_rr (f32 (TFRI_f fpimm:$src2)), (f32 IntRegs:$src1)))>,
212      Requires<[HasV5T]>;
213
214def : Pat <(i1 (setolt (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
215      (i1 (FCMPOGT64_rr DoubleRegs:$src2, DoubleRegs:$src1))>,
216      Requires<[HasV5T]>;
217
218def : Pat <(i1 (setolt (f64 DoubleRegs:$src1), (fpimm:$src2))),
219      (i1 (FCMPOGT64_rr (f64 (CONST64_Float_Real fpimm:$src2)),
220                        (f64 DoubleRegs:$src1)))>,
221      Requires<[HasV5T]>;
222
223// gt.
224def : Pat <(i1 (setugt (f64 DoubleRegs:$src1), (fpimm:$src2))),
225      (i1 (FCMPUGT64_rr (f64 DoubleRegs:$src1),
226                        (f64 (CONST64_Float_Real fpimm:$src2))))>,
227      Requires<[HasV5T]>;
228
229def : Pat <(i1 (setugt (f32 IntRegs:$src1), (fpimm:$src2))),
230      (i1 (FCMPUGT32_rr (f32 IntRegs:$src1), (f32 (TFRI_f fpimm:$src2))))>,
231      Requires<[HasV5T]>;
232
233// ult.
234def : Pat <(i1 (setult (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
235      (i1 (FCMPUGT32_rr IntRegs:$src2, IntRegs:$src1))>,
236      Requires<[HasV5T]>;
237
238def : Pat <(i1 (setult (f32 IntRegs:$src1), (fpimm:$src2))),
239      (i1 (FCMPUGT32_rr (f32 (TFRI_f fpimm:$src2)), (f32 IntRegs:$src1)))>,
240      Requires<[HasV5T]>;
241
242def : Pat <(i1 (setult (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
243      (i1 (FCMPUGT64_rr DoubleRegs:$src2, DoubleRegs:$src1))>,
244      Requires<[HasV5T]>;
245
246def : Pat <(i1 (setult (f64 DoubleRegs:$src1), (fpimm:$src2))),
247      (i1 (FCMPUGT64_rr (f64 (CONST64_Float_Real fpimm:$src2)),
248                        (f64 DoubleRegs:$src1)))>,
249      Requires<[HasV5T]>;
250
251// le.
252// rs <= rt -> rt >= rs.
253def : Pat<(i1 (setole (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
254      (i1 (FCMPOGE32_rr IntRegs:$src2, IntRegs:$src1))>,
255      Requires<[HasV5T]>;
256
257def : Pat<(i1 (setole (f32 IntRegs:$src1), (fpimm:$src2))),
258      (i1 (FCMPOGE32_rr (f32 (TFRI_f fpimm:$src2)), IntRegs:$src1))>,
259      Requires<[HasV5T]>;
260
261
262// Rss <= Rtt -> Rtt >= Rss.
263def : Pat<(i1 (setole (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
264      (i1 (FCMPOGE64_rr DoubleRegs:$src2, DoubleRegs:$src1))>,
265      Requires<[HasV5T]>;
266
267def : Pat<(i1 (setole (f64 DoubleRegs:$src1), (fpimm:$src2))),
268      (i1 (FCMPOGE64_rr (f64 (CONST64_Float_Real fpimm:$src2)),
269                                DoubleRegs:$src1))>,
270      Requires<[HasV5T]>;
271
272// rs <= rt -> rt >= rs.
273def : Pat<(i1 (setule (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
274      (i1 (FCMPUGE32_rr IntRegs:$src2, IntRegs:$src1))>,
275      Requires<[HasV5T]>;
276
277def : Pat<(i1 (setule (f32 IntRegs:$src1), (fpimm:$src2))),
278      (i1 (FCMPUGE32_rr (f32 (TFRI_f fpimm:$src2)), IntRegs:$src1))>,
279      Requires<[HasV5T]>;
280
281// Rss <= Rtt -> Rtt >= Rss.
282def : Pat<(i1 (setule (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
283      (i1 (FCMPUGE64_rr DoubleRegs:$src2, DoubleRegs:$src1))>,
284      Requires<[HasV5T]>;
285
286def : Pat<(i1 (setule (f64 DoubleRegs:$src1), (fpimm:$src2))),
287      (i1 (FCMPUGE64_rr (f64 (CONST64_Float_Real fpimm:$src2)),
288                                DoubleRegs:$src1))>,
289      Requires<[HasV5T]>;
290
291// ne.
292def : Pat<(i1 (setone (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
293      (i1 (NOT_p (FCMPOEQ32_rr IntRegs:$src1, IntRegs:$src2)))>,
294      Requires<[HasV5T]>;
295
296def : Pat<(i1 (setone (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
297      (i1 (NOT_p (FCMPOEQ64_rr DoubleRegs:$src1, DoubleRegs:$src2)))>,
298      Requires<[HasV5T]>;
299
300def : Pat<(i1 (setune (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
301      (i1 (NOT_p (FCMPUEQ32_rr IntRegs:$src1, IntRegs:$src2)))>,
302      Requires<[HasV5T]>;
303
304def : Pat<(i1 (setune (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
305      (i1 (NOT_p (FCMPUEQ64_rr DoubleRegs:$src1, DoubleRegs:$src2)))>,
306      Requires<[HasV5T]>;
307
308def : Pat<(i1 (setone (f32 IntRegs:$src1), (fpimm:$src2))),
309      (i1 (NOT_p (FCMPOEQ32_rr IntRegs:$src1, (f32 (TFRI_f fpimm:$src2)))))>,
310      Requires<[HasV5T]>;
311
312def : Pat<(i1 (setone (f64 DoubleRegs:$src1), (fpimm:$src2))),
313      (i1 (NOT_p (FCMPOEQ64_rr DoubleRegs:$src1,
314                              (f64 (CONST64_Float_Real fpimm:$src2)))))>,
315      Requires<[HasV5T]>;
316
317def : Pat<(i1 (setune (f32 IntRegs:$src1), (fpimm:$src2))),
318      (i1 (NOT_p (FCMPUEQ32_rr IntRegs:$src1,  (f32 (TFRI_f fpimm:$src2)))))>,
319      Requires<[HasV5T]>;
320
321def : Pat<(i1 (setune (f64 DoubleRegs:$src1), (fpimm:$src2))),
322      (i1 (NOT_p (FCMPUEQ64_rr DoubleRegs:$src1,
323                              (f64 (CONST64_Float_Real fpimm:$src2)))))>,
324      Requires<[HasV5T]>;
325
326// Convert Integer to Floating Point.
327def CONVERT_d2sf : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
328              "$dst = convert_d2sf($src)",
329              [(set (f32 IntRegs:$dst), (sint_to_fp (i64 DoubleRegs:$src)))]>,
330              Requires<[HasV5T]>;
331
332def CONVERT_ud2sf : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
333              "$dst = convert_ud2sf($src)",
334              [(set (f32 IntRegs:$dst), (uint_to_fp (i64 DoubleRegs:$src)))]>,
335              Requires<[HasV5T]>;
336
337def CONVERT_uw2sf : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
338              "$dst = convert_uw2sf($src)",
339              [(set (f32 IntRegs:$dst), (uint_to_fp (i32 IntRegs:$src)))]>,
340              Requires<[HasV5T]>;
341
342def CONVERT_w2sf : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
343              "$dst = convert_w2sf($src)",
344              [(set (f32 IntRegs:$dst), (sint_to_fp (i32 IntRegs:$src)))]>,
345              Requires<[HasV5T]>;
346
347def CONVERT_d2df : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
348              "$dst = convert_d2df($src)",
349              [(set (f64 DoubleRegs:$dst), (sint_to_fp (i64 DoubleRegs:$src)))]>,
350              Requires<[HasV5T]>;
351
352def CONVERT_ud2df : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
353              "$dst = convert_ud2df($src)",
354              [(set (f64 DoubleRegs:$dst), (uint_to_fp (i64 DoubleRegs:$src)))]>,
355              Requires<[HasV5T]>;
356
357def CONVERT_uw2df : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
358              "$dst = convert_uw2df($src)",
359              [(set (f64 DoubleRegs:$dst), (uint_to_fp (i32 IntRegs:$src)))]>,
360              Requires<[HasV5T]>;
361
362def CONVERT_w2df : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
363              "$dst = convert_w2df($src)",
364              [(set (f64 DoubleRegs:$dst), (sint_to_fp (i32 IntRegs:$src)))]>,
365              Requires<[HasV5T]>;
366
367// Convert Floating Point to Integer - default.
368def CONVERT_df2uw : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
369              "$dst = convert_df2uw($src):chop",
370              [(set (i32 IntRegs:$dst), (fp_to_uint (f64 DoubleRegs:$src)))]>,
371              Requires<[HasV5T]>;
372
373def CONVERT_df2w : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
374              "$dst = convert_df2w($src):chop",
375              [(set (i32 IntRegs:$dst), (fp_to_sint (f64 DoubleRegs:$src)))]>,
376              Requires<[HasV5T]>;
377
378def CONVERT_sf2uw : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
379              "$dst = convert_sf2uw($src):chop",
380              [(set (i32 IntRegs:$dst), (fp_to_uint (f32 IntRegs:$src)))]>,
381              Requires<[HasV5T]>;
382
383def CONVERT_sf2w : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
384              "$dst = convert_sf2w($src):chop",
385              [(set (i32 IntRegs:$dst), (fp_to_sint (f32 IntRegs:$src)))]>,
386              Requires<[HasV5T]>;
387
388def CONVERT_df2d : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
389              "$dst = convert_df2d($src):chop",
390              [(set (i64 DoubleRegs:$dst), (fp_to_sint (f64 DoubleRegs:$src)))]>,
391              Requires<[HasV5T]>;
392
393def CONVERT_df2ud : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
394              "$dst = convert_df2ud($src):chop",
395              [(set (i64 DoubleRegs:$dst), (fp_to_uint (f64 DoubleRegs:$src)))]>,
396              Requires<[HasV5T]>;
397
398def CONVERT_sf2d : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
399              "$dst = convert_sf2d($src):chop",
400              [(set (i64 DoubleRegs:$dst), (fp_to_sint (f32 IntRegs:$src)))]>,
401              Requires<[HasV5T]>;
402
403def CONVERT_sf2ud : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
404              "$dst = convert_sf2ud($src):chop",
405              [(set (i64 DoubleRegs:$dst), (fp_to_uint (f32 IntRegs:$src)))]>,
406              Requires<[HasV5T]>;
407
408// Convert Floating Point to Integer: non-chopped.
409let AddedComplexity = 20 in
410def CONVERT_df2uw_nchop : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
411              "$dst = convert_df2uw($src)",
412              [(set (i32 IntRegs:$dst), (fp_to_uint (f64 DoubleRegs:$src)))]>,
413              Requires<[HasV5T, IEEERndNearV5T]>;
414
415let AddedComplexity = 20 in
416def CONVERT_df2w_nchop : ALU64_rr<(outs IntRegs:$dst), (ins DoubleRegs:$src),
417              "$dst = convert_df2w($src)",
418              [(set (i32 IntRegs:$dst), (fp_to_sint (f64 DoubleRegs:$src)))]>,
419              Requires<[HasV5T, IEEERndNearV5T]>;
420
421let AddedComplexity = 20 in
422def CONVERT_sf2uw_nchop : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
423              "$dst = convert_sf2uw($src)",
424              [(set (i32 IntRegs:$dst), (fp_to_uint (f32 IntRegs:$src)))]>,
425              Requires<[HasV5T, IEEERndNearV5T]>;
426
427let AddedComplexity = 20 in
428def CONVERT_sf2w_nchop : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src),
429              "$dst = convert_sf2w($src)",
430              [(set (i32 IntRegs:$dst), (fp_to_sint (f32 IntRegs:$src)))]>,
431              Requires<[HasV5T, IEEERndNearV5T]>;
432
433let AddedComplexity = 20 in
434def CONVERT_df2d_nchop : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
435              "$dst = convert_df2d($src)",
436              [(set (i64 DoubleRegs:$dst), (fp_to_sint (f64 DoubleRegs:$src)))]>,
437              Requires<[HasV5T, IEEERndNearV5T]>;
438
439let AddedComplexity = 20 in
440def CONVERT_df2ud_nchop : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src),
441              "$dst = convert_df2ud($src)",
442              [(set (i64 DoubleRegs:$dst), (fp_to_uint (f64 DoubleRegs:$src)))]>,
443              Requires<[HasV5T, IEEERndNearV5T]>;
444
445let AddedComplexity = 20 in
446def CONVERT_sf2d_nchop : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
447              "$dst = convert_sf2d($src)",
448              [(set (i64 DoubleRegs:$dst), (fp_to_sint (f32 IntRegs:$src)))]>,
449              Requires<[HasV5T, IEEERndNearV5T]>;
450
451let AddedComplexity = 20 in
452def CONVERT_sf2ud_nchop : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
453              "$dst = convert_sf2ud($src)",
454              [(set (i64 DoubleRegs:$dst), (fp_to_uint (f32 IntRegs:$src)))]>,
455              Requires<[HasV5T, IEEERndNearV5T]>;
456
457
458
459// Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp].
460def : Pat <(i32 (bitconvert (f32 IntRegs:$src))),
461           (i32 (TFR IntRegs:$src))>,
462          Requires<[HasV5T]>;
463
464def : Pat <(f32 (bitconvert (i32 IntRegs:$src))),
465           (f32 (TFR IntRegs:$src))>,
466          Requires<[HasV5T]>;
467
468def : Pat <(i64 (bitconvert (f64 DoubleRegs:$src))),
469           (i64 (TFR64 DoubleRegs:$src))>,
470          Requires<[HasV5T]>;
471
472def : Pat <(f64 (bitconvert (i64 DoubleRegs:$src))),
473           (f64 (TFR64 DoubleRegs:$src))>,
474          Requires<[HasV5T]>;
475
476// Floating point fused multiply-add.
477def FMADD_dp : ALU64_acc<(outs DoubleRegs:$dst),
478                  (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
479              "$dst += dfmpy($src2, $src3)",
480              [(set (f64 DoubleRegs:$dst),
481                  (fma DoubleRegs:$src2, DoubleRegs:$src3, DoubleRegs:$src1))],
482                  "$src1 = $dst">,
483              Requires<[HasV5T]>;
484
485def FMADD_sp : ALU64_acc<(outs IntRegs:$dst),
486                  (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
487              "$dst += sfmpy($src2, $src3)",
488              [(set (f32 IntRegs:$dst),
489                  (fma IntRegs:$src2, IntRegs:$src3, IntRegs:$src1))],
490                  "$src1 = $dst">,
491              Requires<[HasV5T]>;
492
493
494// Floating point max/min.
495let AddedComplexity = 100 in
496def FMAX_dp : ALU64_rr<(outs DoubleRegs:$dst),
497                  (ins DoubleRegs:$src1, DoubleRegs:$src2),
498              "$dst = dfmax($src1, $src2)",
499              [(set DoubleRegs:$dst, (f64 (select (i1 (setolt DoubleRegs:$src2,
500                                                        DoubleRegs:$src1)),
501                                             DoubleRegs:$src1,
502                                             DoubleRegs:$src2)))]>,
503               Requires<[HasV5T]>;
504
505let AddedComplexity = 100 in
506def FMAX_sp : ALU64_rr<(outs IntRegs:$dst),
507                  (ins IntRegs:$src1, IntRegs:$src2),
508              "$dst = sfmax($src1, $src2)",
509              [(set IntRegs:$dst, (f32 (select (i1 (setolt IntRegs:$src2,
510                                                        IntRegs:$src1)),
511                                             IntRegs:$src1,
512                                             IntRegs:$src2)))]>,
513               Requires<[HasV5T]>;
514
515let AddedComplexity = 100 in
516def FMIN_dp : ALU64_rr<(outs DoubleRegs:$dst),
517                  (ins DoubleRegs:$src1, DoubleRegs:$src2),
518              "$dst = dfmin($src1, $src2)",
519              [(set DoubleRegs:$dst, (f64 (select (i1 (setogt DoubleRegs:$src2,
520                                                        DoubleRegs:$src1)),
521                                             DoubleRegs:$src1,
522                                             DoubleRegs:$src2)))]>,
523               Requires<[HasV5T]>;
524
525let AddedComplexity = 100 in
526def FMIN_sp : ALU64_rr<(outs IntRegs:$dst),
527                  (ins IntRegs:$src1, IntRegs:$src2),
528              "$dst = sfmin($src1, $src2)",
529              [(set IntRegs:$dst, (f32 (select (i1 (setogt IntRegs:$src2,
530                                                        IntRegs:$src1)),
531                                             IntRegs:$src1,
532                                             IntRegs:$src2)))]>,
533               Requires<[HasV5T]>;
534
535// Pseudo instruction to encode a set of conditional transfers.
536// This instruction is used instead of a mux and trades-off codesize
537// for performance. We conduct this transformation optimistically in
538// the hope that these instructions get promoted to dot-new transfers.
539let AddedComplexity = 100, isPredicated = 1 in
540def TFR_condset_rr_f : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
541                                                        IntRegs:$src2,
542                                                        IntRegs:$src3),
543                     "Error; should not emit",
544                     [(set IntRegs:$dst, (f32 (select PredRegs:$src1,
545                                                 IntRegs:$src2,
546                                                 IntRegs:$src3)))]>,
547               Requires<[HasV5T]>;
548
549let AddedComplexity = 100, isPredicated = 1 in
550def TFR_condset_rr64_f : ALU32_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
551                                                        DoubleRegs:$src2,
552                                                        DoubleRegs:$src3),
553                     "Error; should not emit",
554                     [(set DoubleRegs:$dst, (f64 (select PredRegs:$src1,
555                                                 DoubleRegs:$src2,
556                                                 DoubleRegs:$src3)))]>,
557               Requires<[HasV5T]>;
558
559
560
561let AddedComplexity = 100, isPredicated = 1 in
562def TFR_condset_ri_f : ALU32_rr<(outs IntRegs:$dst),
563            (ins PredRegs:$src1, IntRegs:$src2, f32imm:$src3),
564            "Error; should not emit",
565            [(set IntRegs:$dst,
566             (f32 (select PredRegs:$src1, IntRegs:$src2, fpimm:$src3)))]>,
567               Requires<[HasV5T]>;
568
569let AddedComplexity = 100, isPredicated = 1 in
570def TFR_condset_ir_f : ALU32_rr<(outs IntRegs:$dst),
571            (ins PredRegs:$src1, f32imm:$src2, IntRegs:$src3),
572            "Error; should not emit",
573            [(set IntRegs:$dst,
574             (f32 (select PredRegs:$src1, fpimm:$src2, IntRegs:$src3)))]>,
575               Requires<[HasV5T]>;
576
577let AddedComplexity = 100, isPredicated = 1 in
578def TFR_condset_ii_f : ALU32_rr<(outs IntRegs:$dst),
579                              (ins PredRegs:$src1, f32imm:$src2, f32imm:$src3),
580                     "Error; should not emit",
581                     [(set IntRegs:$dst, (f32 (select PredRegs:$src1,
582                                                 fpimm:$src2,
583                                                 fpimm:$src3)))]>,
584               Requires<[HasV5T]>;
585
586
587def : Pat <(select (i1 (setult (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
588                   (f32 IntRegs:$src3),
589                   (f32 IntRegs:$src4)),
590    (TFR_condset_rr_f (FCMPUGT32_rr IntRegs:$src2, IntRegs:$src1), IntRegs:$src4,
591                      IntRegs:$src3)>, Requires<[HasV5T]>;
592
593def : Pat <(select (i1 (setult (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
594                   (f64 DoubleRegs:$src3),
595                   (f64 DoubleRegs:$src4)),
596      (TFR_condset_rr64_f (FCMPUGT64_rr DoubleRegs:$src2, DoubleRegs:$src1),
597                DoubleRegs:$src4, DoubleRegs:$src3)>, Requires<[HasV5T]>;
598
599// Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i).
600def : Pat <(select (not PredRegs:$src1), fpimm:$src2, fpimm:$src3),
601      (TFR_condset_ii_f PredRegs:$src1, fpimm:$src3, fpimm:$src2)>;
602
603// Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
604// => r0 = TFR_condset_ri(p0, r1, #i)
605def : Pat <(select (not PredRegs:$src1), fpimm:$src2, IntRegs:$src3),
606      (TFR_condset_ri_f PredRegs:$src1, IntRegs:$src3, fpimm:$src2)>;
607
608// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
609// => r0 = TFR_condset_ir(p0, #i, r1)
610def : Pat <(select (not PredRegs:$src1), IntRegs:$src2, fpimm:$src3),
611      (TFR_condset_ir_f PredRegs:$src1, fpimm:$src3, IntRegs:$src2)>;
612
613def : Pat <(i32 (fp_to_sint (f64 DoubleRegs:$src1))),
614          (i32 (EXTRACT_SUBREG (i64 (CONVERT_df2d (f64 DoubleRegs:$src1))), subreg_loreg))>,
615          Requires<[HasV5T]>;
616
617def : Pat <(fabs (f32 IntRegs:$src1)),
618           (CLRBIT_31 (f32 IntRegs:$src1), 31)>,
619          Requires<[HasV5T]>;
620
621def : Pat <(fneg (f32 IntRegs:$src1)),
622           (TOGBIT_31 (f32 IntRegs:$src1), 31)>,
623          Requires<[HasV5T]>;
624
625/*
626def : Pat <(fabs (f64 DoubleRegs:$src1)),
627          (CLRBIT_31 (f32 (EXTRACT_SUBREG DoubleRegs:$src1, subreg_hireg)), 31)>,
628          Requires<[HasV5T]>;
629
630def : Pat <(fabs (f64 DoubleRegs:$src1)),
631          (CLRBIT_31 (f32 (EXTRACT_SUBREG DoubleRegs:$src1, subreg_hireg)), 31)>,
632          Requires<[HasV5T]>;
633          */
634