[Hexagon] Formatting v5 TD file. Removing commented defs.
[oota-llvm.git] / lib / Target / Hexagon / HexagonInstrInfoV5.td
1 //=- HexagonInstrInfoV5.td - Target Desc. for Hexagon Target -*- tablegen -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the Hexagon V5 instructions in TableGen format.
11 //
12 //===----------------------------------------------------------------------===//
13
14 //===----------------------------------------------------------------------===//
15 // XTYPE/MPY
16 //===----------------------------------------------------------------------===//
17
18   //Rdd[+]=vrmpybsu(Rss,Rtt)
19 let Predicates = [HasV5T] in {
20   def M5_vrmpybsu: T_XTYPE_Vect<"vrmpybsu", 0b110, 0b001, 0>;
21   def M5_vrmacbsu: T_XTYPE_Vect_acc<"vrmpybsu", 0b110, 0b001, 0>;
22
23   //Rdd[+]=vrmpybu(Rss,Rtt)
24   def M5_vrmpybuu: T_XTYPE_Vect<"vrmpybu", 0b100, 0b001, 0>;
25   def M5_vrmacbuu: T_XTYPE_Vect_acc<"vrmpybu", 0b100, 0b001, 0>;
26
27   def M5_vdmpybsu: T_M2_vmpy<"vdmpybsu", 0b101, 0b001, 0, 0, 1>;
28   def M5_vdmacbsu: T_M2_vmpy_acc_sat <"vdmpybsu", 0b001, 0b001, 0, 0>;
29 }
30
31 // Vector multiply bytes
32 // Rdd=vmpyb[s]u(Rs,Rt)
33 let Predicates = [HasV5T] in {
34   def M5_vmpybsu: T_XTYPE_mpy64 <"vmpybsu", 0b010, 0b001, 0, 0, 0>;
35   def M5_vmpybuu: T_XTYPE_mpy64 <"vmpybu",  0b100, 0b001, 0, 0, 0>;
36
37   // Rxx+=vmpyb[s]u(Rs,Rt)
38   def M5_vmacbsu: T_XTYPE_mpy64_acc <"vmpybsu", "+", 0b110, 0b001, 0, 0, 0>;
39   def M5_vmacbuu: T_XTYPE_mpy64_acc <"vmpybu", "+", 0b100, 0b001, 0, 0, 0>;
40
41   // Rd=vaddhub(Rss,Rtt):sat
42   let hasNewValue = 1, opNewValue = 0 in
43     def A5_vaddhubs: T_S3op_1 <"vaddhub", IntRegs, 0b01, 0b001, 0, 1>;
44 }
45
46 def S2_asr_i_p_rnd : S_2OpInstImm<"asr", 0b110, 0b111, u6Imm,
47       [(set I64:$dst,
48             (sra (i64 (add (i64 (sra I64:$src1, u6ImmPred:$src2)), 1)),
49                  (i32 1)))], 1>,
50       Requires<[HasV5T]> {
51   bits<6> src2;
52   let Inst{13-8} = src2;
53 }
54
55 let isAsmParserOnly = 1 in
56 def S2_asr_i_p_rnd_goodsyntax
57   : MInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
58     "$dst = asrrnd($src1, #$src2)">;
59
60 def C4_fastcorner9 : T_LOGICAL_2OP<"fastcorner9", 0b000, 0, 0>,
61   Requires<[HasV5T]> {
62   let Inst{13,7,4} = 0b111;
63 }
64
65 def C4_fastcorner9_not : T_LOGICAL_2OP<"!fastcorner9", 0b000, 0, 0>,
66   Requires<[HasV5T]> {
67   let Inst{20,13,7,4} = 0b1111;
68 }
69
70 def SDTHexagonFCONST32 : SDTypeProfile<1, 1, [SDTCisVT<0, f32>,
71                                               SDTCisPtrTy<1>]>;
72 def HexagonFCONST32 : SDNode<"HexagonISD::FCONST32", SDTHexagonFCONST32>;
73
74 let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in
75 def FCONST32_nsdata : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global),
76                              "$dst = CONST32(#$global)",
77                              [(set F32:$dst,
78                               (HexagonFCONST32 tglobaladdr:$global))]>,
79                              Requires<[HasV5T]>;
80
81 let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in
82 def CONST64_Float_Real : LDInst<(outs DoubleRegs:$dst), (ins f64imm:$src1),
83                                 "$dst = CONST64(#$src1)",
84                                 [(set F64:$dst, fpimm:$src1)]>,
85                                 Requires<[HasV5T]>;
86
87 let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in
88 def CONST32_Float_Real : LDInst<(outs IntRegs:$dst), (ins f32imm:$src1),
89                                 "$dst = CONST32(#$src1)",
90                                 [(set F32:$dst, fpimm:$src1)]>,
91                                 Requires<[HasV5T]>;
92
93 // Transfer immediate float.
94 // Only works with single precision fp value.
95 // For double precision, use CONST64_float_real, as 64bit transfer
96 // can only hold 40-bit values - 32 from const ext + 8 bit immediate.
97 // Make sure that complexity is more than the CONST32 pattern in
98 // HexagonInstrInfo.td patterns.
99 let isExtended = 1, opExtendable = 1, isMoveImm = 1, isReMaterializable = 1,
100     isPredicable = 1, AddedComplexity = 30, validSubTargets = HasV5SubT,
101     isCodeGenOnly = 1 in
102 def TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32Ext:$src1),
103                       "$dst = #$src1",
104                       [(set F32:$dst, fpimm:$src1)]>,
105                       Requires<[HasV5T]>;
106
107 let isExtended = 1, opExtendable = 2, isPredicated = 1,
108     hasSideEffects = 0, validSubTargets = HasV5SubT, isCodeGenOnly = 1 in
109 def TFRI_cPt_f : ALU32_ri<(outs IntRegs:$dst),
110                           (ins PredRegs:$src1, f32Ext:$src2),
111                           "if ($src1) $dst = #$src2", []>,
112                           Requires<[HasV5T]>;
113
114 let isPseudo = 1, isExtended = 1, opExtendable = 2, isPredicated = 1,
115     isPredicatedFalse = 1, hasSideEffects = 0, validSubTargets = HasV5SubT in
116 def TFRI_cNotPt_f : ALU32_ri<(outs IntRegs:$dst),
117                              (ins PredRegs:$src1, f32Ext:$src2),
118                              "if (!$src1) $dst = #$src2", []>,
119                              Requires<[HasV5T]>;
120
121 def SDTHexagonI32I64: SDTypeProfile<1, 1, [SDTCisVT<0, i32>,
122                                            SDTCisVT<1, i64>]>;
123
124 def HexagonPOPCOUNT: SDNode<"HexagonISD::POPCOUNT", SDTHexagonI32I64>;
125
126 let hasNewValue = 1, validSubTargets = HasV5SubT in
127 def S5_popcountp : ALU64_rr<(outs IntRegs:$Rd), (ins DoubleRegs:$Rss),
128   "$Rd = popcount($Rss)",
129   [(set I32:$Rd, (HexagonPOPCOUNT I64:$Rss))], "", S_2op_tc_2_SLOT23>,
130   Requires<[HasV5T]> {
131     bits<5> Rd;
132     bits<5> Rss;
133
134     let IClass = 0b1000;
135
136     let Inst{27-21} = 0b1000011;
137     let Inst{7-5} = 0b011;
138     let Inst{4-0} = Rd;
139     let Inst{20-16} = Rss;
140   }
141
142 defm: Loadx_pat<load, f32, s11_2ExtPred, L2_loadri_io>;
143 defm: Loadx_pat<load, f64, s11_3ExtPred, L2_loadrd_io>;
144
145 defm: Storex_pat<store, F32, s11_2ExtPred, S2_storeri_io>;
146 defm: Storex_pat<store, F64, s11_3ExtPred, S2_storerd_io>;
147
148 let isFP = 1, hasNewValue = 1, opNewValue = 0 in
149 class T_MInstFloat <string mnemonic, bits<3> MajOp, bits<3> MinOp>
150   : MInst<(outs IntRegs:$Rd),
151           (ins IntRegs:$Rs, IntRegs:$Rt),
152   "$Rd = "#mnemonic#"($Rs, $Rt)", [],
153   "" , M_tc_3or4x_SLOT23 > ,
154   Requires<[HasV5T]> {
155     bits<5> Rd;
156     bits<5> Rs;
157     bits<5> Rt;
158
159     let IClass = 0b1110;
160
161     let Inst{27-24} = 0b1011;
162     let Inst{23-21} = MajOp;
163     let Inst{20-16} = Rs;
164     let Inst{13} = 0b0;
165     let Inst{12-8} = Rt;
166     let Inst{7-5} = MinOp;
167     let Inst{4-0} = Rd;
168   }
169
170 let isCommutable = 1 in {
171   def F2_sfadd : T_MInstFloat < "sfadd", 0b000, 0b000>;
172   def F2_sfmpy : T_MInstFloat < "sfmpy", 0b010, 0b000>;
173 }
174
175 def F2_sfsub : T_MInstFloat < "sfsub", 0b000, 0b001>;
176
177 def: Pat<(f32 (fadd F32:$src1, F32:$src2)),
178          (F2_sfadd F32:$src1, F32:$src2)>;
179
180 def: Pat<(f32 (fsub F32:$src1, F32:$src2)),
181          (F2_sfsub F32:$src1, F32:$src2)>;
182
183 def: Pat<(f32 (fmul F32:$src1, F32:$src2)),
184          (F2_sfmpy F32:$src1, F32:$src2)>;
185
186 let Itinerary = M_tc_3x_SLOT23 in {
187   def F2_sfmax : T_MInstFloat < "sfmax", 0b100, 0b000>;
188   def F2_sfmin : T_MInstFloat < "sfmin", 0b100, 0b001>;
189 }
190
191 def F2_sffixupn : T_MInstFloat < "sffixupn", 0b110, 0b000>;
192 def F2_sffixupd : T_MInstFloat < "sffixupd", 0b110, 0b001>;
193
194 // F2_sfrecipa: Reciprocal approximation for division.
195 let isPredicateLate = 1, isFP = 1,
196 hasSideEffects = 0, hasNewValue = 1 in
197 def F2_sfrecipa: MInst <
198   (outs IntRegs:$Rd, PredRegs:$Pe),
199   (ins IntRegs:$Rs, IntRegs:$Rt),
200   "$Rd, $Pe = sfrecipa($Rs, $Rt)">,
201   Requires<[HasV5T]> {
202     bits<5> Rd;
203     bits<2> Pe;
204     bits<5> Rs;
205     bits<5> Rt;
206
207     let IClass = 0b1110;
208     let Inst{27-21} = 0b1011111;
209     let Inst{20-16} = Rs;
210     let Inst{13}    = 0b0;
211     let Inst{12-8}  = Rt;
212     let Inst{7}     = 0b1;
213     let Inst{6-5}   = Pe;
214     let Inst{4-0}   = Rd;
215   }
216
217 // F2_dfcmpeq: Floating point compare for equal.
218 let isCompare = 1, isFP = 1 in
219 class T_fcmp <string mnemonic, RegisterClass RC, bits<3> MinOp,
220               list<dag> pattern = [] >
221   : ALU64Inst <(outs PredRegs:$dst), (ins RC:$src1, RC:$src2),
222   "$dst = "#mnemonic#"($src1, $src2)", pattern,
223   "" , ALU64_tc_2early_SLOT23 > ,
224   Requires<[HasV5T]> {
225     bits<2> dst;
226     bits<5> src1;
227     bits<5> src2;
228
229     let IClass = 0b1101;
230
231     let Inst{27-21} = 0b0010111;
232     let Inst{20-16} = src1;
233     let Inst{12-8}  = src2;
234     let Inst{7-5}   = MinOp;
235     let Inst{1-0}   = dst;
236   }
237
238 class T_fcmp64 <string mnemonic, PatFrag OpNode, bits<3> MinOp>
239   : T_fcmp <mnemonic, DoubleRegs, MinOp,
240   [(set  I1:$dst, (OpNode F64:$src1, F64:$src2))]> {
241   let IClass = 0b1101;
242   let Inst{27-21} = 0b0010111;
243 }
244
245 class T_fcmp32 <string mnemonic, PatFrag OpNode, bits<3> MinOp>
246   : T_fcmp <mnemonic, IntRegs, MinOp,
247   [(set  I1:$dst, (OpNode F32:$src1, F32:$src2))]> {
248   let IClass = 0b1100;
249   let Inst{27-21} = 0b0111111;
250 }
251
252 def F2_dfcmpeq : T_fcmp64<"dfcmp.eq", setoeq, 0b000>;
253 def F2_dfcmpgt : T_fcmp64<"dfcmp.gt", setogt, 0b001>;
254 def F2_dfcmpge : T_fcmp64<"dfcmp.ge", setoge, 0b010>;
255 def F2_dfcmpuo : T_fcmp64<"dfcmp.uo", setuo,  0b011>;
256
257 def F2_sfcmpge : T_fcmp32<"sfcmp.ge", setoge, 0b000>;
258 def F2_sfcmpuo : T_fcmp32<"sfcmp.uo", setuo,  0b001>;
259 def F2_sfcmpeq : T_fcmp32<"sfcmp.eq", setoeq, 0b011>;
260 def F2_sfcmpgt : T_fcmp32<"sfcmp.gt", setogt, 0b100>;
261
262 //===----------------------------------------------------------------------===//
263 // Multiclass to define 'Def Pats' for ordered gt, ge, eq operations.
264 //===----------------------------------------------------------------------===//
265
266 let Predicates = [HasV5T] in
267 multiclass T_fcmp_pats<PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> {
268   // IntRegs
269   def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)),
270            (IntMI F32:$src1, F32:$src2)>;
271   // DoubleRegs
272   def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)),
273            (DoubleMI F64:$src1, F64:$src2)>;
274 }
275
276 defm : T_fcmp_pats <seteq, F2_sfcmpeq, F2_dfcmpeq>;
277 defm : T_fcmp_pats <setgt, F2_sfcmpgt, F2_dfcmpgt>;
278 defm : T_fcmp_pats <setge, F2_sfcmpge, F2_dfcmpge>;
279
280 //===----------------------------------------------------------------------===//
281 // Multiclass to define 'Def Pats' for unordered gt, ge, eq operations.
282 //===----------------------------------------------------------------------===//
283 let Predicates = [HasV5T] in
284 multiclass unord_Pats <PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> {
285   // IntRegs
286   def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)),
287            (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
288                   (IntMI F32:$src1, F32:$src2))>;
289
290   // DoubleRegs
291   def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)),
292            (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
293                   (DoubleMI F64:$src1, F64:$src2))>;
294 }
295
296 defm : unord_Pats <setuge, F2_sfcmpge, F2_dfcmpge>;
297 defm : unord_Pats <setugt, F2_sfcmpgt, F2_dfcmpgt>;
298 defm : unord_Pats <setueq, F2_sfcmpeq, F2_dfcmpeq>;
299
300 //===----------------------------------------------------------------------===//
301 // Multiclass to define 'Def Pats' for the following dags:
302 // seteq(setoeq(op1, op2), 0) -> not(setoeq(op1, op2))
303 // seteq(setoeq(op1, op2), 1) -> setoeq(op1, op2)
304 // setne(setoeq(op1, op2), 0) -> setoeq(op1, op2)
305 // setne(setoeq(op1, op2), 1) -> not(setoeq(op1, op2))
306 //===----------------------------------------------------------------------===//
307 let Predicates = [HasV5T] in
308 multiclass eq_ordgePats <PatFrag cmpOp, InstHexagon IntMI,
309                          InstHexagon DoubleMI> {
310   // IntRegs
311   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
312            (C2_not (IntMI F32:$src1, F32:$src2))>;
313   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
314            (IntMI F32:$src1, F32:$src2)>;
315   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
316            (IntMI F32:$src1, F32:$src2)>;
317   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
318            (C2_not (IntMI F32:$src1, F32:$src2))>;
319
320   // DoubleRegs
321   def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
322             (C2_not (DoubleMI F64:$src1, F64:$src2))>;
323   def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
324             (DoubleMI F64:$src1, F64:$src2)>;
325   def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
326             (DoubleMI F64:$src1, F64:$src2)>;
327   def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
328             (C2_not (DoubleMI F64:$src1, F64:$src2))>;
329 }
330
331 defm : eq_ordgePats<setoeq, F2_sfcmpeq, F2_dfcmpeq>;
332 defm : eq_ordgePats<setoge, F2_sfcmpge, F2_dfcmpge>;
333 defm : eq_ordgePats<setogt, F2_sfcmpgt, F2_dfcmpgt>;
334
335 //===----------------------------------------------------------------------===//
336 // Multiclass to define 'Def Pats' for the following dags:
337 // seteq(setolt(op1, op2), 0) -> not(setogt(op2, op1))
338 // seteq(setolt(op1, op2), 1) -> setogt(op2, op1)
339 // setne(setolt(op1, op2), 0) -> setogt(op2, op1)
340 // setne(setolt(op1, op2), 1) -> not(setogt(op2, op1))
341 //===----------------------------------------------------------------------===//
342 let Predicates = [HasV5T] in
343 multiclass eq_ordltPats <PatFrag cmpOp, InstHexagon IntMI,
344                          InstHexagon DoubleMI> {
345   // IntRegs
346   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
347            (C2_not (IntMI F32:$src2, F32:$src1))>;
348   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
349            (IntMI F32:$src2, F32:$src1)>;
350   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
351            (IntMI F32:$src2, F32:$src1)>;
352   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
353            (C2_not (IntMI F32:$src2, F32:$src1))>;
354
355   // DoubleRegs
356   def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
357            (C2_not (DoubleMI F64:$src2, F64:$src1))>;
358   def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
359            (DoubleMI F64:$src2, F64:$src1)>;
360   def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
361            (DoubleMI F64:$src2, F64:$src1)>;
362   def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
363            (C2_not (DoubleMI F64:$src2, F64:$src1))>;
364 }
365
366 defm : eq_ordltPats<setole, F2_sfcmpge, F2_dfcmpge>;
367 defm : eq_ordltPats<setolt, F2_sfcmpgt, F2_dfcmpgt>;
368
369
370 // o. seto inverse of setuo. http://llvm.org/docs/LangRef.html#i_fcmp
371 let Predicates = [HasV5T] in {
372   def: Pat<(i1 (seto F32:$src1, F32:$src2)),
373            (C2_not (F2_sfcmpuo F32:$src2, F32:$src1))>;
374   def: Pat<(i1 (seto F32:$src1, fpimm:$src2)),
375            (C2_not (F2_sfcmpuo (TFRI_f fpimm:$src2), F32:$src1))>;
376   def: Pat<(i1 (seto F64:$src1, F64:$src2)),
377            (C2_not (F2_dfcmpuo F64:$src2, F64:$src1))>;
378   def: Pat<(i1 (seto F64:$src1, fpimm:$src2)),
379            (C2_not (F2_dfcmpuo (CONST64_Float_Real fpimm:$src2), F64:$src1))>;
380 }
381
382 // Ordered lt.
383 let Predicates = [HasV5T] in {
384   def: Pat<(i1 (setolt F32:$src1, F32:$src2)),
385            (F2_sfcmpgt F32:$src2, F32:$src1)>;
386   def: Pat<(i1 (setolt F32:$src1, fpimm:$src2)),
387            (F2_sfcmpgt (f32 (TFRI_f fpimm:$src2)), F32:$src1)>;
388   def: Pat<(i1 (setolt F64:$src1, F64:$src2)),
389            (F2_dfcmpgt F64:$src2, F64:$src1)>;
390   def: Pat<(i1 (setolt F64:$src1, fpimm:$src2)),
391            (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
392 }
393
394 // Unordered lt.
395 let Predicates = [HasV5T] in {
396   def: Pat<(i1 (setult F32:$src1, F32:$src2)),
397            (C2_or (F2_sfcmpuo  F32:$src1, F32:$src2),
398                   (F2_sfcmpgt F32:$src2, F32:$src1))>;
399   def: Pat<(i1 (setult F32:$src1, fpimm:$src2)),
400            (C2_or (F2_sfcmpuo  F32:$src1, (TFRI_f fpimm:$src2)),
401                   (F2_sfcmpgt (TFRI_f fpimm:$src2), F32:$src1))>;
402   def: Pat<(i1 (setult F64:$src1, F64:$src2)),
403            (C2_or (F2_dfcmpuo  F64:$src1, F64:$src2),
404                   (F2_dfcmpgt F64:$src2, F64:$src1))>;
405   def: Pat<(i1 (setult F64:$src1, fpimm:$src2)),
406            (C2_or (F2_dfcmpuo  F64:$src1, (CONST64_Float_Real fpimm:$src2)),
407                   (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1))>;
408 }
409
410 // Ordered le.
411 let Predicates = [HasV5T] in {
412   // rs <= rt -> rt >= rs.
413   def: Pat<(i1 (setole F32:$src1, F32:$src2)),
414            (F2_sfcmpge F32:$src2, F32:$src1)>;
415   def: Pat<(i1 (setole F32:$src1, fpimm:$src2)),
416            (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1)>;
417
418   // Rss <= Rtt -> Rtt >= Rss.
419   def: Pat<(i1 (setole F64:$src1, F64:$src2)),
420            (F2_dfcmpge F64:$src2, F64:$src1)>;
421   def: Pat<(i1 (setole F64:$src1, fpimm:$src2)),
422            (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
423 }
424
425 // Unordered le.
426 let Predicates = [HasV5T] in {
427 // rs <= rt -> rt >= rs.
428   def: Pat<(i1 (setule F32:$src1, F32:$src2)),
429            (C2_or (F2_sfcmpuo  F32:$src1, F32:$src2),
430                   (F2_sfcmpge F32:$src2, F32:$src1))>;
431   def: Pat<(i1 (setule F32:$src1, fpimm:$src2)),
432            (C2_or (F2_sfcmpuo  F32:$src1, (TFRI_f fpimm:$src2)),
433                   (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1))>;
434   def: Pat<(i1 (setule F64:$src1, F64:$src2)),
435            (C2_or (F2_dfcmpuo  F64:$src1, F64:$src2),
436                   (F2_dfcmpge F64:$src2, F64:$src1))>;
437   def: Pat<(i1 (setule F64:$src1, fpimm:$src2)),
438            (C2_or (F2_dfcmpuo  F64:$src1, (CONST64_Float_Real fpimm:$src2)),
439                   (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1))>;
440 }
441
442 // Ordered ne.
443 let Predicates = [HasV5T] in {
444   def: Pat<(i1 (setone F32:$src1, F32:$src2)),
445            (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
446   def: Pat<(i1 (setone F64:$src1, F64:$src2)),
447            (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
448   def: Pat<(i1 (setone F32:$src1, fpimm:$src2)),
449            (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2)))>;
450   def: Pat<(i1 (setone F64:$src1, fpimm:$src2)),
451            (C2_not (F2_dfcmpeq F64:$src1, (CONST64_Float_Real fpimm:$src2)))>;
452 }
453
454 // Unordered ne.
455 let Predicates = [HasV5T] in {
456   def: Pat<(i1 (setune F32:$src1, F32:$src2)),
457            (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
458                   (C2_not (F2_sfcmpeq F32:$src1, F32:$src2)))>;
459   def: Pat<(i1 (setune F64:$src1, F64:$src2)),
460            (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
461                   (C2_not (F2_dfcmpeq F64:$src1, F64:$src2)))>;
462   def: Pat<(i1 (setune F32:$src1, fpimm:$src2)),
463            (C2_or (F2_sfcmpuo F32:$src1, (TFRI_f fpimm:$src2)),
464                   (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2))))>;
465   def: Pat<(i1 (setune F64:$src1, fpimm:$src2)),
466            (C2_or (F2_dfcmpuo F64:$src1, (CONST64_Float_Real fpimm:$src2)),
467                   (C2_not (F2_dfcmpeq F64:$src1,
468                                         (CONST64_Float_Real fpimm:$src2))))>;
469 }
470
471 // Besides set[o|u][comparions], we also need set[comparisons].
472 let Predicates = [HasV5T] in {
473   // lt.
474   def: Pat<(i1 (setlt F32:$src1, F32:$src2)),
475            (F2_sfcmpgt F32:$src2, F32:$src1)>;
476   def: Pat<(i1 (setlt F32:$src1, fpimm:$src2)),
477            (F2_sfcmpgt (TFRI_f fpimm:$src2), F32:$src1)>;
478   def: Pat<(i1 (setlt F64:$src1, F64:$src2)),
479            (F2_dfcmpgt F64:$src2, F64:$src1)>;
480   def: Pat<(i1 (setlt F64:$src1, fpimm:$src2)),
481            (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
482
483   // le.
484   // rs <= rt -> rt >= rs.
485   def: Pat<(i1 (setle F32:$src1, F32:$src2)),
486            (F2_sfcmpge F32:$src2, F32:$src1)>;
487   def: Pat<(i1 (setle F32:$src1, fpimm:$src2)),
488            (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1)>;
489
490   // Rss <= Rtt -> Rtt >= Rss.
491   def: Pat<(i1 (setle F64:$src1, F64:$src2)),
492            (F2_dfcmpge F64:$src2, F64:$src1)>;
493   def: Pat<(i1 (setle F64:$src1, fpimm:$src2)),
494            (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
495
496   // ne.
497   def: Pat<(i1 (setne F32:$src1, F32:$src2)),
498            (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
499   def: Pat<(i1 (setne F64:$src1, F64:$src2)),
500            (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
501   def: Pat<(i1 (setne F32:$src1, fpimm:$src2)),
502            (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2)))>;
503   def: Pat<(i1 (setne F64:$src1, fpimm:$src2)),
504            (C2_not (F2_dfcmpeq F64:$src1, (CONST64_Float_Real fpimm:$src2)))>;
505 }
506
507 // F2 convert template classes:
508 let isFP = 1 in
509 class F2_RDD_RSS_CONVERT<string mnemonic, bits<3> MinOp,
510                          SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
511                          string chop ="">
512   : SInst <(outs DoubleRegs:$Rdd), (ins DoubleRegs:$Rss),
513    "$Rdd = "#mnemonic#"($Rss)"#chop,
514    [(set RCOut:$Rdd, (Op RCIn:$Rss))], "",
515    S_2op_tc_3or4x_SLOT23> {
516      bits<5> Rdd;
517      bits<5> Rss;
518
519      let IClass = 0b1000;
520
521      let Inst{27-21} = 0b0000111;
522      let Inst{20-16} = Rss;
523      let Inst{7-5} = MinOp;
524      let Inst{4-0} = Rdd;
525   }
526
527 let isFP = 1 in
528 class F2_RDD_RS_CONVERT<string mnemonic, bits<3> MinOp,
529                         SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
530                         string chop ="">
531   : SInst <(outs DoubleRegs:$Rdd), (ins IntRegs:$Rs),
532    "$Rdd = "#mnemonic#"($Rs)"#chop,
533    [(set RCOut:$Rdd, (Op RCIn:$Rs))], "",
534    S_2op_tc_3or4x_SLOT23> {
535      bits<5> Rdd;
536      bits<5> Rs;
537
538      let IClass = 0b1000;
539
540      let Inst{27-21} = 0b0100100;
541      let Inst{20-16} = Rs;
542      let Inst{7-5} = MinOp;
543      let Inst{4-0} = Rdd;
544   }
545
546 let isFP = 1, hasNewValue = 1 in
547 class F2_RD_RSS_CONVERT<string mnemonic, bits<3> MinOp,
548                         SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
549                         string chop ="">
550   : SInst <(outs IntRegs:$Rd), (ins DoubleRegs:$Rss),
551    "$Rd = "#mnemonic#"($Rss)"#chop,
552    [(set RCOut:$Rd, (Op RCIn:$Rss))], "",
553    S_2op_tc_3or4x_SLOT23> {
554      bits<5> Rd;
555      bits<5> Rss;
556
557      let IClass = 0b1000;
558
559      let Inst{27-24} = 0b1000;
560      let Inst{23-21} = MinOp;
561      let Inst{20-16} = Rss;
562      let Inst{7-5} = 0b001;
563      let Inst{4-0} = Rd;
564   }
565
566 let isFP = 1, hasNewValue = 1 in
567 class F2_RD_RS_CONVERT<string mnemonic, bits<3> MajOp, bits<3> MinOp,
568                         SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
569                         string chop ="">
570   : SInst <(outs IntRegs:$Rd), (ins IntRegs:$Rs),
571    "$Rd = "#mnemonic#"($Rs)"#chop,
572    [(set RCOut:$Rd, (Op RCIn:$Rs))], "",
573    S_2op_tc_3or4x_SLOT23> {
574      bits<5> Rd;
575      bits<5> Rs;
576
577      let IClass = 0b1000;
578
579      let Inst{27-24} = 0b1011;
580      let Inst{23-21} = MajOp;
581      let Inst{20-16} = Rs;
582      let Inst{7-5} = MinOp;
583      let Inst{4-0} = Rd;
584   }
585
586 // Convert single precision to double precision and vice-versa.
587 def F2_conv_sf2df : F2_RDD_RS_CONVERT <"convert_sf2df", 0b000,
588                                        fextend, F64, F32>;
589
590 def F2_conv_df2sf : F2_RD_RSS_CONVERT <"convert_df2sf", 0b000,
591                                        fround, F32, F64>;
592
593 // Convert Integer to Floating Point.
594 def F2_conv_d2sf : F2_RD_RSS_CONVERT <"convert_d2sf", 0b010,
595                                        sint_to_fp, F32, I64>;
596 def F2_conv_ud2sf : F2_RD_RSS_CONVERT <"convert_ud2sf", 0b001,
597                                        uint_to_fp, F32, I64>;
598 def F2_conv_uw2sf : F2_RD_RS_CONVERT <"convert_uw2sf", 0b001, 0b000,
599                                        uint_to_fp, F32, I32>;
600 def F2_conv_w2sf : F2_RD_RS_CONVERT <"convert_w2sf", 0b010, 0b000,
601                                        sint_to_fp, F32, I32>;
602 def F2_conv_d2df : F2_RDD_RSS_CONVERT <"convert_d2df", 0b011,
603                                        sint_to_fp, F64, I64>;
604 def F2_conv_ud2df : F2_RDD_RSS_CONVERT <"convert_ud2df", 0b010,
605                                         uint_to_fp, F64, I64>;
606 def F2_conv_uw2df : F2_RDD_RS_CONVERT <"convert_uw2df", 0b001,
607                                        uint_to_fp, F64, I32>;
608 def F2_conv_w2df : F2_RDD_RS_CONVERT <"convert_w2df", 0b010,
609                                        sint_to_fp, F64, I32>;
610
611 // Convert Floating Point to Integer - default.
612 def F2_conv_df2uw_chop : F2_RD_RSS_CONVERT <"convert_df2uw", 0b101,
613                                             fp_to_uint, I32, F64, ":chop">;
614 def F2_conv_df2w_chop : F2_RD_RSS_CONVERT <"convert_df2w", 0b111,
615                                             fp_to_sint, I32, F64, ":chop">;
616 def F2_conv_sf2uw_chop : F2_RD_RS_CONVERT <"convert_sf2uw", 0b011, 0b001,
617                                        fp_to_uint, I32, F32, ":chop">;
618 def F2_conv_sf2w_chop : F2_RD_RS_CONVERT <"convert_sf2w", 0b100, 0b001,
619                                        fp_to_sint, I32, F32, ":chop">;
620 def F2_conv_df2d_chop : F2_RDD_RSS_CONVERT <"convert_df2d", 0b110,
621                                             fp_to_sint, I64, F64, ":chop">;
622 def F2_conv_df2ud_chop : F2_RDD_RSS_CONVERT <"convert_df2ud", 0b111,
623                                              fp_to_uint, I64, F64, ":chop">;
624 def F2_conv_sf2d_chop : F2_RDD_RS_CONVERT <"convert_sf2d", 0b110,
625                                        fp_to_sint, I64, F32, ":chop">;
626 def F2_conv_sf2ud_chop : F2_RDD_RS_CONVERT <"convert_sf2ud", 0b101,
627                                             fp_to_uint, I64, F32, ":chop">;
628
629 // Convert Floating Point to Integer: non-chopped.
630 let AddedComplexity = 20, Predicates = [HasV5T, IEEERndNearV5T] in {
631   def F2_conv_df2d : F2_RDD_RSS_CONVERT <"convert_df2d", 0b000,
632                                          fp_to_sint, I64, F64>;
633   def F2_conv_df2ud : F2_RDD_RSS_CONVERT <"convert_df2ud", 0b001,
634                                           fp_to_uint, I64, F64>;
635   def F2_conv_sf2ud : F2_RDD_RS_CONVERT <"convert_sf2ud", 0b011,
636                                          fp_to_uint, I64, F32>;
637   def F2_conv_sf2d : F2_RDD_RS_CONVERT <"convert_sf2d", 0b100,
638                                          fp_to_sint, I64, F32>;
639   def F2_conv_df2uw : F2_RD_RSS_CONVERT <"convert_df2uw", 0b011,
640                                          fp_to_uint, I32, F64>;
641   def F2_conv_df2w : F2_RD_RSS_CONVERT <"convert_df2w", 0b100,
642                                          fp_to_sint, I32, F64>;
643   def F2_conv_sf2uw : F2_RD_RS_CONVERT <"convert_sf2uw", 0b011, 0b000,
644                                          fp_to_uint, I32, F32>;
645   def F2_conv_sf2w : F2_RD_RS_CONVERT <"convert_sf2w", 0b100, 0b000,
646                                          fp_to_sint, I32, F32>;
647 }
648
649 // Fix up radicand.
650 let isFP = 1, hasNewValue = 1 in
651 def F2_sffixupr: SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs),
652   "$Rd = sffixupr($Rs)",
653   [], "" , S_2op_tc_3or4x_SLOT23>, Requires<[HasV5T]> {
654     bits<5> Rd;
655     bits<5> Rs;
656
657     let IClass = 0b1000;
658
659     let Inst{27-21} = 0b1011101;
660     let Inst{20-16} = Rs;
661     let Inst{7-5}   = 0b000;
662     let Inst{4-0}   = Rd;
663   }
664
665 // Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp].
666 let Predicates = [HasV5T] in {
667   def: Pat <(i32 (bitconvert F32:$src)), (I32:$src)>;
668   def: Pat <(f32 (bitconvert I32:$src)), (F32:$src)>;
669   def: Pat <(i64 (bitconvert F64:$src)), (I64:$src)>;
670   def: Pat <(f64 (bitconvert I64:$src)), (F64:$src)>;
671 }
672
673 // F2_sffma: Floating-point fused multiply add.
674 let isFP = 1, hasNewValue = 1 in
675 class T_sfmpy_acc <bit isSub, bit isLib>
676   : MInst<(outs IntRegs:$Rx),
677           (ins IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt),
678   "$Rx "#!if(isSub, "-=","+=")#" sfmpy($Rs, $Rt)"#!if(isLib, ":lib",""),
679   [], "$dst2 = $Rx" , M_tc_3_SLOT23 > ,
680   Requires<[HasV5T]> {
681     bits<5> Rx;
682     bits<5> Rs;
683     bits<5> Rt;
684
685     let IClass = 0b1110;
686
687     let Inst{27-21} = 0b1111000;
688     let Inst{20-16} = Rs;
689     let Inst{13}    = 0b0;
690     let Inst{12-8}  = Rt;
691     let Inst{7}     = 0b1;
692     let Inst{6}     = isLib;
693     let Inst{5}     = isSub;
694     let Inst{4-0}   = Rx;
695   }
696
697 def F2_sffma: T_sfmpy_acc <0, 0>;
698 def F2_sffms: T_sfmpy_acc <1, 0>;
699 def F2_sffma_lib: T_sfmpy_acc <0, 1>;
700 def F2_sffms_lib: T_sfmpy_acc <1, 1>;
701
702 // Floating-point fused multiply add w/ additional scaling (2**pu).
703 let isFP = 1, hasNewValue = 1 in
704 def F2_sffma_sc: MInst <
705   (outs IntRegs:$Rx),
706   (ins IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt, PredRegs:$Pu),
707   "$Rx += sfmpy($Rs, $Rt, $Pu):scale" ,
708   [], "$dst2 = $Rx" , M_tc_3_SLOT23 > ,
709   Requires<[HasV5T]> {
710     bits<5> Rx;
711     bits<5> Rs;
712     bits<5> Rt;
713     bits<2> Pu;
714
715     let IClass = 0b1110;
716
717     let Inst{27-21} = 0b1111011;
718     let Inst{20-16} = Rs;
719     let Inst{13}    = 0b0;
720     let Inst{12-8}  = Rt;
721     let Inst{7}     = 0b1;
722     let Inst{6-5}   = Pu;
723     let Inst{4-0}   = Rx;
724   }
725
726 let isExtended = 1, isExtentSigned = 1, opExtentBits = 8, opExtendable = 3,
727     isPseudo = 1, InputType = "imm" in
728 def MUX_ir_f : ALU32_rr<(outs IntRegs:$dst),
729       (ins PredRegs:$src1, IntRegs:$src2, f32Ext:$src3),
730       "$dst = mux($src1, $src2, #$src3)",
731       [(set F32:$dst, (f32 (select I1:$src1, F32:$src2, fpimm:$src3)))]>,
732     Requires<[HasV5T]>;
733
734 let isExtended = 1, isExtentSigned = 1, opExtentBits = 8, opExtendable = 2,
735     isPseudo = 1, InputType = "imm" in
736 def MUX_ri_f : ALU32_rr<(outs IntRegs:$dst),
737       (ins PredRegs:$src1, f32Ext:$src2, IntRegs:$src3),
738       "$dst = mux($src1, #$src2, $src3)",
739       [(set F32:$dst, (f32 (select I1:$src1, fpimm:$src2, F32:$src3)))]>,
740     Requires<[HasV5T]>;
741
742 //===----------------------------------------------------------------------===//
743 // :natural forms of vasrh and vasrhub insns
744 //===----------------------------------------------------------------------===//
745 // S5_asrhub_rnd_sat: Vector arithmetic shift right by immediate with round,
746 // saturate, and pack.
747 let Defs = [USR_OVF], hasSideEffects = 0, hasNewValue = 1, opNewValue = 0 in
748 class T_ASRHUB<bit isSat>
749   : SInst <(outs IntRegs:$Rd),
750   (ins DoubleRegs:$Rss, u4Imm:$u4),
751   "$Rd = vasrhub($Rss, #$u4):"#!if(isSat, "sat", "raw"),
752   [], "", S_2op_tc_2_SLOT23>,
753   Requires<[HasV5T]> {
754     bits<5> Rd;
755     bits<5> Rss;
756     bits<4> u4;
757
758     let IClass = 0b1000;
759
760     let Inst{27-21} = 0b1000011;
761     let Inst{20-16} = Rss;
762     let Inst{13-12} = 0b00;
763     let Inst{11-8} = u4;
764     let Inst{7-6} = 0b10;
765     let Inst{5} = isSat;
766     let Inst{4-0} = Rd;
767   }
768
769 def S5_asrhub_rnd_sat : T_ASRHUB <0>;
770 def S5_asrhub_sat : T_ASRHUB <1>;
771
772 let isAsmParserOnly = 1 in
773 def S5_asrhub_rnd_sat_goodsyntax
774   : SInst <(outs IntRegs:$Rd), (ins DoubleRegs:$Rss, u4Imm:$u4),
775   "$Rd = vasrhub($Rss, #$u4):rnd:sat">, Requires<[HasV5T]>;
776
777 // S5_vasrhrnd: Vector arithmetic shift right by immediate with round.
778 let hasSideEffects = 0 in
779 def S5_vasrhrnd : SInst <(outs DoubleRegs:$Rdd),
780                          (ins DoubleRegs:$Rss, u4Imm:$u4),
781   "$Rdd = vasrh($Rss, #$u4):raw">,
782   Requires<[HasV5T]> {
783     bits<5> Rdd;
784     bits<5> Rss;
785     bits<4> u4;
786
787     let IClass = 0b1000;
788
789     let Inst{27-21} = 0b0000001;
790     let Inst{20-16} = Rss;
791     let Inst{13-12} = 0b00;
792     let Inst{11-8}  = u4;
793     let Inst{7-5}   = 0b000;
794     let Inst{4-0}   = Rdd;
795   }
796
797 let isAsmParserOnly = 1 in
798 def S5_vasrhrnd_goodsyntax
799   : SInst <(outs DoubleRegs:$Rdd), (ins DoubleRegs:$Rss, u4Imm:$u4),
800   "$Rdd = vasrh($Rss,#$u4):rnd">, Requires<[HasV5T]>;
801
802 // Floating point reciprocal square root approximation
803 let Uses = [USR], isPredicateLate = 1, isFP = 1,
804     hasSideEffects = 0, hasNewValue = 1, opNewValue = 0,
805     validSubTargets = HasV5SubT in
806 def F2_sfinvsqrta: SInst <
807   (outs IntRegs:$Rd, PredRegs:$Pe),
808   (ins IntRegs:$Rs),
809   "$Rd, $Pe = sfinvsqrta($Rs)" > ,
810   Requires<[HasV5T]> {
811     bits<5> Rd;
812     bits<2> Pe;
813     bits<5> Rs;
814
815     let IClass = 0b1000;
816
817     let Inst{27-21} = 0b1011111;
818     let Inst{20-16} = Rs;
819     let Inst{7} = 0b0;
820     let Inst{6-5} = Pe;
821     let Inst{4-0} = Rd;
822   }
823
824 // Complex multiply 32x16
825 let Defs = [USR_OVF], Itinerary = S_3op_tc_3x_SLOT23 in {
826   def M4_cmpyi_whc : T_S3op_8<"cmpyiwh", 0b101, 1, 1, 1, 1>;
827   def M4_cmpyr_whc : T_S3op_8<"cmpyrwh", 0b111, 1, 1, 1, 1>;
828 }
829
830 // Classify floating-point value
831 let isFP = 1 in
832  def F2_sfclass : T_TEST_BIT_IMM<"sfclass", 0b111>;
833
834 let isFP = 1 in
835 def F2_dfclass: ALU64Inst<(outs PredRegs:$Pd), (ins DoubleRegs:$Rss, u5Imm:$u5),
836   "$Pd = dfclass($Rss, #$u5)",
837   [], "" , ALU64_tc_2early_SLOT23 > , Requires<[HasV5T]> {
838     bits<2> Pd;
839     bits<5> Rss;
840     bits<5> u5;
841
842     let IClass = 0b1101;
843     let Inst{27-21} = 0b1100100;
844     let Inst{20-16} = Rss;
845     let Inst{12-10} = 0b000;
846     let Inst{9-5}   = u5;
847     let Inst{4-3}   = 0b10;
848     let Inst{1-0}   = Pd;
849   }
850
851 // Instructions to create floating point constant
852 let hasNewValue = 1, opNewValue = 0 in
853 class T_fimm <string mnemonic, RegisterClass RC, bits<4> RegType, bit isNeg>
854   : ALU64Inst<(outs RC:$dst), (ins u10Imm:$src),
855   "$dst = "#mnemonic#"(#$src)"#!if(isNeg, ":neg", ":pos"),
856   [], "", ALU64_tc_3x_SLOT23>, Requires<[HasV5T]> {
857     bits<5> dst;
858     bits<10> src;
859
860     let IClass = 0b1101;
861     let Inst{27-24} = RegType;
862     let Inst{23}    = 0b0;
863     let Inst{22}    = isNeg;
864     let Inst{21}    = src{9};
865     let Inst{13-5}  = src{8-0};
866     let Inst{4-0}   = dst;
867   }
868
869 let hasNewValue = 1, opNewValue = 0 in {
870 def F2_sfimm_p : T_fimm <"sfmake", IntRegs, 0b0110, 0>;
871 def F2_sfimm_n : T_fimm <"sfmake", IntRegs, 0b0110, 1>;
872 }
873
874 def F2_dfimm_p : T_fimm <"dfmake", DoubleRegs, 0b1001, 0>;
875 def F2_dfimm_n : T_fimm <"dfmake", DoubleRegs, 0b1001, 1>;
876
877 def : Pat <(fabs (f32 IntRegs:$src1)),
878            (S2_clrbit_i (f32 IntRegs:$src1), 31)>,
879           Requires<[HasV5T]>;
880
881 def : Pat <(fneg (f32 IntRegs:$src1)),
882            (S2_togglebit_i (f32 IntRegs:$src1), 31)>,
883           Requires<[HasV5T]>;