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