xref: /aosp_15_r20/external/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker//=- HexagonInstrInfoV4.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 V4 instructions in TableGen format.
11*9880d681SAndroid Build Coastguard Worker//
12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Workerdef DuplexIClass0:  InstDuplex < 0 >;
15*9880d681SAndroid Build Coastguard Workerdef DuplexIClass1:  InstDuplex < 1 >;
16*9880d681SAndroid Build Coastguard Workerdef DuplexIClass2:  InstDuplex < 2 >;
17*9880d681SAndroid Build Coastguard Workerlet isExtendable = 1 in {
18*9880d681SAndroid Build Coastguard Worker  def DuplexIClass3:  InstDuplex < 3 >;
19*9880d681SAndroid Build Coastguard Worker  def DuplexIClass4:  InstDuplex < 4 >;
20*9880d681SAndroid Build Coastguard Worker  def DuplexIClass5:  InstDuplex < 5 >;
21*9880d681SAndroid Build Coastguard Worker  def DuplexIClass6:  InstDuplex < 6 >;
22*9880d681SAndroid Build Coastguard Worker  def DuplexIClass7:  InstDuplex < 7 >;
23*9880d681SAndroid Build Coastguard Worker}
24*9880d681SAndroid Build Coastguard Workerdef DuplexIClass8:  InstDuplex < 8 >;
25*9880d681SAndroid Build Coastguard Workerdef DuplexIClass9:  InstDuplex < 9 >;
26*9880d681SAndroid Build Coastguard Workerdef DuplexIClassA:  InstDuplex < 0xA >;
27*9880d681SAndroid Build Coastguard Workerdef DuplexIClassB:  InstDuplex < 0xB >;
28*9880d681SAndroid Build Coastguard Workerdef DuplexIClassC:  InstDuplex < 0xC >;
29*9880d681SAndroid Build Coastguard Workerdef DuplexIClassD:  InstDuplex < 0xD >;
30*9880d681SAndroid Build Coastguard Workerdef DuplexIClassE:  InstDuplex < 0xE >;
31*9880d681SAndroid Build Coastguard Workerdef DuplexIClassF:  InstDuplex < 0xF >;
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Workerdef addrga: PatLeaf<(i32 AddrGA:$Addr)>;
34*9880d681SAndroid Build Coastguard Workerdef addrgp: PatLeaf<(i32 AddrGP:$Addr)>;
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
37*9880d681SAndroid Build Coastguard Workerclass T_Immext<Operand ImmType>
38*9880d681SAndroid Build Coastguard Worker  : EXTENDERInst<(outs), (ins ImmType:$imm),
39*9880d681SAndroid Build Coastguard Worker                 "immext(#$imm)", []> {
40*9880d681SAndroid Build Coastguard Worker    bits<32> imm;
41*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0000;
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker    let Inst{27-16} = imm{31-20};
44*9880d681SAndroid Build Coastguard Worker    let Inst{13-0} = imm{19-6};
45*9880d681SAndroid Build Coastguard Worker  }
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Workerdef A4_ext : T_Immext<u26_6Imm>;
48*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
49*9880d681SAndroid Build Coastguard Worker  let isBranch = 1 in
50*9880d681SAndroid Build Coastguard Worker    def A4_ext_b : T_Immext<brtarget>;
51*9880d681SAndroid Build Coastguard Worker  let isCall = 1 in
52*9880d681SAndroid Build Coastguard Worker    def A4_ext_c : T_Immext<calltarget>;
53*9880d681SAndroid Build Coastguard Worker  def A4_ext_g : T_Immext<globaladdress>;
54*9880d681SAndroid Build Coastguard Worker}
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Workerdef BITPOS32 : SDNodeXForm<imm, [{
57*9880d681SAndroid Build Coastguard Worker   // Return the bit position we will set [0-31].
58*9880d681SAndroid Build Coastguard Worker   // As an SDNode.
59*9880d681SAndroid Build Coastguard Worker   int32_t imm = N->getSExtValue();
60*9880d681SAndroid Build Coastguard Worker   return XformMskToBitPosU5Imm(imm, SDLoc(N));
61*9880d681SAndroid Build Coastguard Worker}]>;
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker// Hexagon V4 Architecture spec defines 8 instruction classes:
65*9880d681SAndroid Build Coastguard Worker// LD ST ALU32 XTYPE J JR MEMOP NV CR SYSTEM(system is not implemented in the
66*9880d681SAndroid Build Coastguard Worker// compiler)
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker// LD Instructions:
69*9880d681SAndroid Build Coastguard Worker// ========================================
70*9880d681SAndroid Build Coastguard Worker// Loads (8/16/32/64 bit)
71*9880d681SAndroid Build Coastguard Worker// Deallocframe
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker// ST Instructions:
74*9880d681SAndroid Build Coastguard Worker// ========================================
75*9880d681SAndroid Build Coastguard Worker// Stores (8/16/32/64 bit)
76*9880d681SAndroid Build Coastguard Worker// Allocframe
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker// ALU32 Instructions:
79*9880d681SAndroid Build Coastguard Worker// ========================================
80*9880d681SAndroid Build Coastguard Worker// Arithmetic / Logical (32 bit)
81*9880d681SAndroid Build Coastguard Worker// Vector Halfword
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker// XTYPE Instructions (32/64 bit):
84*9880d681SAndroid Build Coastguard Worker// ========================================
85*9880d681SAndroid Build Coastguard Worker// Arithmetic, Logical, Bit Manipulation
86*9880d681SAndroid Build Coastguard Worker// Multiply (Integer, Fractional, Complex)
87*9880d681SAndroid Build Coastguard Worker// Permute / Vector Permute Operations
88*9880d681SAndroid Build Coastguard Worker// Predicate Operations
89*9880d681SAndroid Build Coastguard Worker// Shift / Shift with Add/Sub/Logical
90*9880d681SAndroid Build Coastguard Worker// Vector Byte ALU
91*9880d681SAndroid Build Coastguard Worker// Vector Halfword (ALU, Shift, Multiply)
92*9880d681SAndroid Build Coastguard Worker// Vector Word (ALU, Shift)
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker// J Instructions:
95*9880d681SAndroid Build Coastguard Worker// ========================================
96*9880d681SAndroid Build Coastguard Worker// Jump/Call PC-relative
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker// JR Instructions:
99*9880d681SAndroid Build Coastguard Worker// ========================================
100*9880d681SAndroid Build Coastguard Worker// Jump/Call Register
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker// MEMOP Instructions:
103*9880d681SAndroid Build Coastguard Worker// ========================================
104*9880d681SAndroid Build Coastguard Worker// Operation on memory (8/16/32 bit)
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker// NV Instructions:
107*9880d681SAndroid Build Coastguard Worker// ========================================
108*9880d681SAndroid Build Coastguard Worker// New-value Jumps
109*9880d681SAndroid Build Coastguard Worker// New-value Stores
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker// CR Instructions:
112*9880d681SAndroid Build Coastguard Worker// ========================================
113*9880d681SAndroid Build Coastguard Worker// Control-Register Transfers
114*9880d681SAndroid Build Coastguard Worker// Hardware Loop Setup
115*9880d681SAndroid Build Coastguard Worker// Predicate Logicals & Reductions
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker// SYSTEM Instructions (not implemented in the compiler):
118*9880d681SAndroid Build Coastguard Worker// ========================================
119*9880d681SAndroid Build Coastguard Worker// Prefetch
120*9880d681SAndroid Build Coastguard Worker// Cache Maintenance
121*9880d681SAndroid Build Coastguard Worker// Bus Operations
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
125*9880d681SAndroid Build Coastguard Worker// ALU32 +
126*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Workerclass T_ALU32_3op_not<string mnemonic, bits<3> MajOp, bits<3> MinOp,
129*9880d681SAndroid Build Coastguard Worker                      bit OpsRev>
130*9880d681SAndroid Build Coastguard Worker  : T_ALU32_3op<mnemonic, MajOp, MinOp, OpsRev, 0> {
131*9880d681SAndroid Build Coastguard Worker  let AsmString = "$Rd = "#mnemonic#"($Rs, ~$Rt)";
132*9880d681SAndroid Build Coastguard Worker}
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Workerlet BaseOpcode = "andn_rr", CextOpcode = "andn" in
135*9880d681SAndroid Build Coastguard Workerdef A4_andn    : T_ALU32_3op_not<"and", 0b001, 0b100, 1>;
136*9880d681SAndroid Build Coastguard Workerlet BaseOpcode = "orn_rr", CextOpcode = "orn" in
137*9880d681SAndroid Build Coastguard Workerdef A4_orn     : T_ALU32_3op_not<"or",  0b001, 0b101, 1>;
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Workerlet CextOpcode = "rcmp.eq" in
140*9880d681SAndroid Build Coastguard Workerdef A4_rcmpeq  : T_ALU32_3op<"cmp.eq",  0b011, 0b010, 0, 1>;
141*9880d681SAndroid Build Coastguard Workerlet CextOpcode = "!rcmp.eq" in
142*9880d681SAndroid Build Coastguard Workerdef A4_rcmpneq : T_ALU32_3op<"!cmp.eq", 0b011, 0b011, 0, 1>;
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Workerdef C4_cmpneq  : T_ALU32_3op_cmp<"!cmp.eq",  0b00, 1, 1>;
145*9880d681SAndroid Build Coastguard Workerdef C4_cmplte  : T_ALU32_3op_cmp<"!cmp.gt",  0b10, 1, 0>;
146*9880d681SAndroid Build Coastguard Workerdef C4_cmplteu : T_ALU32_3op_cmp<"!cmp.gtu", 0b11, 1, 0>;
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker// Pats for instruction selection.
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker// A class to embed the usual comparison patfrags within a zext to i32.
151*9880d681SAndroid Build Coastguard Worker// The seteq/setne frags use "lhs" and "rhs" as operands, so use the same
152*9880d681SAndroid Build Coastguard Worker// names, or else the frag's "body" won't match the operands.
153*9880d681SAndroid Build Coastguard Workerclass CmpInReg<PatFrag Op>
154*9880d681SAndroid Build Coastguard Worker  : PatFrag<(ops node:$lhs, node:$rhs),(i32 (zext (i1 Op.Fragment)))>;
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Workerdef: T_cmp32_rr_pat<A4_rcmpeq,  CmpInReg<seteq>, i32>;
157*9880d681SAndroid Build Coastguard Workerdef: T_cmp32_rr_pat<A4_rcmpneq, CmpInReg<setne>, i32>;
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Workerdef: T_cmp32_rr_pat<C4_cmpneq,  setne,  i1>;
160*9880d681SAndroid Build Coastguard Workerdef: T_cmp32_rr_pat<C4_cmplteu, setule, i1>;
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Workerdef: T_cmp32_rr_pat<C4_cmplteu, RevCmp<setuge>, i1>;
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Workerclass T_CMP_rrbh<string mnemonic, bits<3> MinOp, bit IsComm>
165*9880d681SAndroid Build Coastguard Worker  : SInst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, IntRegs:$Rt),
166*9880d681SAndroid Build Coastguard Worker    "$Pd = "#mnemonic#"($Rs, $Rt)", [], "", S_3op_tc_2early_SLOT23>,
167*9880d681SAndroid Build Coastguard Worker    ImmRegRel {
168*9880d681SAndroid Build Coastguard Worker  let InputType = "reg";
169*9880d681SAndroid Build Coastguard Worker  let CextOpcode = mnemonic;
170*9880d681SAndroid Build Coastguard Worker  let isCompare = 1;
171*9880d681SAndroid Build Coastguard Worker  let isCommutable = IsComm;
172*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0;
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard Worker  bits<2> Pd;
175*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
176*9880d681SAndroid Build Coastguard Worker  bits<5> Rt;
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1100;
179*9880d681SAndroid Build Coastguard Worker  let Inst{27-21} = 0b0111110;
180*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
181*9880d681SAndroid Build Coastguard Worker  let Inst{12-8} = Rt;
182*9880d681SAndroid Build Coastguard Worker  let Inst{7-5} = MinOp;
183*9880d681SAndroid Build Coastguard Worker  let Inst{1-0} = Pd;
184*9880d681SAndroid Build Coastguard Worker}
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Workerdef A4_cmpbeq  : T_CMP_rrbh<"cmpb.eq",  0b110, 1>;
187*9880d681SAndroid Build Coastguard Workerdef A4_cmpbgt  : T_CMP_rrbh<"cmpb.gt",  0b010, 0>;
188*9880d681SAndroid Build Coastguard Workerdef A4_cmpbgtu : T_CMP_rrbh<"cmpb.gtu", 0b111, 0>;
189*9880d681SAndroid Build Coastguard Workerdef A4_cmpheq  : T_CMP_rrbh<"cmph.eq",  0b011, 1>;
190*9880d681SAndroid Build Coastguard Workerdef A4_cmphgt  : T_CMP_rrbh<"cmph.gt",  0b100, 0>;
191*9880d681SAndroid Build Coastguard Workerdef A4_cmphgtu : T_CMP_rrbh<"cmph.gtu", 0b101, 0>;
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in {
194*9880d681SAndroid Build Coastguard Worker  def: Pat<(i1 (seteq (and (xor (i32 IntRegs:$Rs), (i32 IntRegs:$Rt)),
195*9880d681SAndroid Build Coastguard Worker                       255), 0)),
196*9880d681SAndroid Build Coastguard Worker           (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt)>;
197*9880d681SAndroid Build Coastguard Worker  def: Pat<(i1 (setne (and (xor (i32 IntRegs:$Rs), (i32 IntRegs:$Rt)),
198*9880d681SAndroid Build Coastguard Worker                       255), 0)),
199*9880d681SAndroid Build Coastguard Worker           (C2_not (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt))>;
200*9880d681SAndroid Build Coastguard Worker  def: Pat<(i1 (seteq (and (xor (i32 IntRegs:$Rs), (i32 IntRegs:$Rt)),
201*9880d681SAndroid Build Coastguard Worker                           65535), 0)),
202*9880d681SAndroid Build Coastguard Worker           (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt)>;
203*9880d681SAndroid Build Coastguard Worker  def: Pat<(i1 (setne (and (xor (i32 IntRegs:$Rs), (i32 IntRegs:$Rt)),
204*9880d681SAndroid Build Coastguard Worker                           65535), 0)),
205*9880d681SAndroid Build Coastguard Worker           (C2_not (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt))>;
206*9880d681SAndroid Build Coastguard Worker}
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Workerclass T_CMP_ribh<string mnemonic, bits<2> MajOp, bit IsHalf, bit IsComm,
209*9880d681SAndroid Build Coastguard Worker                 Operand ImmType, bit IsImmExt, bit IsImmSigned, int ImmBits>
210*9880d681SAndroid Build Coastguard Worker  : ALU64Inst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, ImmType:$Imm),
211*9880d681SAndroid Build Coastguard Worker    "$Pd = "#mnemonic#"($Rs, #$Imm)", [], "", ALU64_tc_2early_SLOT23>,
212*9880d681SAndroid Build Coastguard Worker    ImmRegRel {
213*9880d681SAndroid Build Coastguard Worker  let InputType = "imm";
214*9880d681SAndroid Build Coastguard Worker  let CextOpcode = mnemonic;
215*9880d681SAndroid Build Coastguard Worker  let isCompare = 1;
216*9880d681SAndroid Build Coastguard Worker  let isCommutable = IsComm;
217*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0;
218*9880d681SAndroid Build Coastguard Worker  let isExtendable = IsImmExt;
219*9880d681SAndroid Build Coastguard Worker  let opExtendable = !if (IsImmExt, 2, 0);
220*9880d681SAndroid Build Coastguard Worker  let isExtentSigned = IsImmSigned;
221*9880d681SAndroid Build Coastguard Worker  let opExtentBits = ImmBits;
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker  bits<2> Pd;
224*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
225*9880d681SAndroid Build Coastguard Worker  bits<8> Imm;
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1101;
228*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b1101;
229*9880d681SAndroid Build Coastguard Worker  let Inst{22-21} = MajOp;
230*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
231*9880d681SAndroid Build Coastguard Worker  let Inst{12-5} = Imm;
232*9880d681SAndroid Build Coastguard Worker  let Inst{4} = 0b0;
233*9880d681SAndroid Build Coastguard Worker  let Inst{3} = IsHalf;
234*9880d681SAndroid Build Coastguard Worker  let Inst{1-0} = Pd;
235*9880d681SAndroid Build Coastguard Worker}
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Workerdef A4_cmpbeqi  : T_CMP_ribh<"cmpb.eq",  0b00, 0, 1, u8Imm, 0, 0, 8>;
238*9880d681SAndroid Build Coastguard Workerdef A4_cmpbgti  : T_CMP_ribh<"cmpb.gt",  0b01, 0, 0, s8Imm, 0, 1, 8>;
239*9880d681SAndroid Build Coastguard Workerdef A4_cmpbgtui : T_CMP_ribh<"cmpb.gtu", 0b10, 0, 0, u7Ext, 1, 0, 7>;
240*9880d681SAndroid Build Coastguard Workerdef A4_cmpheqi  : T_CMP_ribh<"cmph.eq",  0b00, 1, 1, s8Ext, 1, 1, 8>;
241*9880d681SAndroid Build Coastguard Workerdef A4_cmphgti  : T_CMP_ribh<"cmph.gt",  0b01, 1, 0, s8Ext, 1, 1, 8>;
242*9880d681SAndroid Build Coastguard Workerdef A4_cmphgtui : T_CMP_ribh<"cmph.gtu", 0b10, 1, 0, u7Ext, 1, 0, 7>;
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Workerclass T_RCMP_EQ_ri<string mnemonic, bit IsNeg>
245*9880d681SAndroid Build Coastguard Worker  : ALU32_ri<(outs IntRegs:$Rd), (ins IntRegs:$Rs, s8Ext:$s8),
246*9880d681SAndroid Build Coastguard Worker    "$Rd = "#mnemonic#"($Rs, #$s8)", [], "", ALU32_2op_tc_1_SLOT0123>,
247*9880d681SAndroid Build Coastguard Worker    ImmRegRel {
248*9880d681SAndroid Build Coastguard Worker  let InputType = "imm";
249*9880d681SAndroid Build Coastguard Worker  let CextOpcode = !if (IsNeg, "!rcmp.eq", "rcmp.eq");
250*9880d681SAndroid Build Coastguard Worker  let isExtendable = 1;
251*9880d681SAndroid Build Coastguard Worker  let opExtendable = 2;
252*9880d681SAndroid Build Coastguard Worker  let isExtentSigned = 1;
253*9880d681SAndroid Build Coastguard Worker  let opExtentBits = 8;
254*9880d681SAndroid Build Coastguard Worker  let hasNewValue = 1;
255*9880d681SAndroid Build Coastguard Worker
256*9880d681SAndroid Build Coastguard Worker  bits<5> Rd;
257*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
258*9880d681SAndroid Build Coastguard Worker  bits<8> s8;
259*9880d681SAndroid Build Coastguard Worker
260*9880d681SAndroid Build Coastguard Worker  let IClass = 0b0111;
261*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b0011;
262*9880d681SAndroid Build Coastguard Worker  let Inst{22} = 0b1;
263*9880d681SAndroid Build Coastguard Worker  let Inst{21} = IsNeg;
264*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
265*9880d681SAndroid Build Coastguard Worker  let Inst{13} = 0b1;
266*9880d681SAndroid Build Coastguard Worker  let Inst{12-5} = s8;
267*9880d681SAndroid Build Coastguard Worker  let Inst{4-0} = Rd;
268*9880d681SAndroid Build Coastguard Worker}
269*9880d681SAndroid Build Coastguard Worker
270*9880d681SAndroid Build Coastguard Workerdef A4_rcmpeqi  : T_RCMP_EQ_ri<"cmp.eq",  0>;
271*9880d681SAndroid Build Coastguard Workerdef A4_rcmpneqi : T_RCMP_EQ_ri<"!cmp.eq", 1>;
272*9880d681SAndroid Build Coastguard Worker
273*9880d681SAndroid Build Coastguard Workerdef: Pat<(i32 (zext (i1 (seteq (i32 IntRegs:$Rs), s32ImmPred:$s8)))),
274*9880d681SAndroid Build Coastguard Worker         (A4_rcmpeqi IntRegs:$Rs, s32ImmPred:$s8)>;
275*9880d681SAndroid Build Coastguard Workerdef: Pat<(i32 (zext (i1 (setne (i32 IntRegs:$Rs), s32ImmPred:$s8)))),
276*9880d681SAndroid Build Coastguard Worker         (A4_rcmpneqi IntRegs:$Rs, s32ImmPred:$s8)>;
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker// Preserve the S2_tstbit_r generation
279*9880d681SAndroid Build Coastguard Workerdef: Pat<(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))),
280*9880d681SAndroid Build Coastguard Worker                                         (i32 IntRegs:$src1))), 0)))),
281*9880d681SAndroid Build Coastguard Worker         (C2_muxii (S2_tstbit_r IntRegs:$src1, IntRegs:$src2), 1, 0)>;
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
284*9880d681SAndroid Build Coastguard Worker// ALU32 -
285*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
286*9880d681SAndroid Build Coastguard Worker
287*9880d681SAndroid Build Coastguard Worker
288*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
289*9880d681SAndroid Build Coastguard Worker// ALU32/PERM +
290*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
291*9880d681SAndroid Build Coastguard Worker
292*9880d681SAndroid Build Coastguard Worker// Combine a word and an immediate into a register pair.
293*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, isExtentSigned = 1, isExtendable = 1,
294*9880d681SAndroid Build Coastguard Worker    opExtentBits = 8 in
295*9880d681SAndroid Build Coastguard Workerclass T_Combine1 <bits<2> MajOp, dag ins, string AsmStr>
296*9880d681SAndroid Build Coastguard Worker  : ALU32Inst <(outs DoubleRegs:$Rdd), ins, AsmStr> {
297*9880d681SAndroid Build Coastguard Worker    bits<5> Rdd;
298*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
299*9880d681SAndroid Build Coastguard Worker    bits<8> s8;
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker    let IClass      = 0b0111;
302*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b0011;
303*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = MajOp;
304*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
305*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = 0b1;
306*9880d681SAndroid Build Coastguard Worker    let Inst{12-5}  = s8;
307*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rdd;
308*9880d681SAndroid Build Coastguard Worker  }
309*9880d681SAndroid Build Coastguard Worker
310*9880d681SAndroid Build Coastguard Workerlet opExtendable = 2 in
311*9880d681SAndroid Build Coastguard Workerdef A4_combineri : T_Combine1<0b00, (ins IntRegs:$Rs, s8Ext:$s8),
312*9880d681SAndroid Build Coastguard Worker                                    "$Rdd = combine($Rs, #$s8)">;
313*9880d681SAndroid Build Coastguard Worker
314*9880d681SAndroid Build Coastguard Workerlet opExtendable = 1 in
315*9880d681SAndroid Build Coastguard Workerdef A4_combineir : T_Combine1<0b01, (ins s8Ext:$s8, IntRegs:$Rs),
316*9880d681SAndroid Build Coastguard Worker                                    "$Rdd = combine(#$s8, $Rs)">;
317*9880d681SAndroid Build Coastguard Worker
318*9880d681SAndroid Build Coastguard Worker// The complexity of the combines involving immediates should be greater
319*9880d681SAndroid Build Coastguard Worker// than the complexity of the combine with two registers.
320*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 50 in {
321*9880d681SAndroid Build Coastguard Workerdef: Pat<(HexagonCOMBINE IntRegs:$r, s32ImmPred:$i),
322*9880d681SAndroid Build Coastguard Worker         (A4_combineri IntRegs:$r, s32ImmPred:$i)>;
323*9880d681SAndroid Build Coastguard Worker
324*9880d681SAndroid Build Coastguard Workerdef: Pat<(HexagonCOMBINE s32ImmPred:$i, IntRegs:$r),
325*9880d681SAndroid Build Coastguard Worker         (A4_combineir s32ImmPred:$i, IntRegs:$r)>;
326*9880d681SAndroid Build Coastguard Worker}
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker// A4_combineii: Set two small immediates.
329*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, isExtendable = 1, opExtentBits = 6, opExtendable = 2 in
330*9880d681SAndroid Build Coastguard Workerdef A4_combineii: ALU32Inst<(outs DoubleRegs:$Rdd), (ins s8Imm:$s8, u6Ext:$U6),
331*9880d681SAndroid Build Coastguard Worker  "$Rdd = combine(#$s8, #$U6)"> {
332*9880d681SAndroid Build Coastguard Worker    bits<5> Rdd;
333*9880d681SAndroid Build Coastguard Worker    bits<8> s8;
334*9880d681SAndroid Build Coastguard Worker    bits<6> U6;
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0111;
337*9880d681SAndroid Build Coastguard Worker    let Inst{27-23} = 0b11001;
338*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = U6{5-1};
339*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = U6{0};
340*9880d681SAndroid Build Coastguard Worker    let Inst{12-5}  = s8;
341*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rdd;
342*9880d681SAndroid Build Coastguard Worker  }
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker// The complexity of the combine with two immediates should be greater than
345*9880d681SAndroid Build Coastguard Worker// the complexity of a combine involving a register.
346*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 75 in
347*9880d681SAndroid Build Coastguard Workerdef: Pat<(HexagonCOMBINE s8ImmPred:$s8, u32ImmPred:$u6),
348*9880d681SAndroid Build Coastguard Worker         (A4_combineii imm:$s8, imm:$u6)>;
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
351*9880d681SAndroid Build Coastguard Worker// ALU32/PERM -
352*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
355*9880d681SAndroid Build Coastguard Worker// LD +
356*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Workerdef Zext64: OutPatFrag<(ops node:$Rs),
359*9880d681SAndroid Build Coastguard Worker  (i64 (A4_combineir 0, (i32 $Rs)))>;
360*9880d681SAndroid Build Coastguard Workerdef Sext64: OutPatFrag<(ops node:$Rs),
361*9880d681SAndroid Build Coastguard Worker  (i64 (A2_sxtw (i32 $Rs)))>;
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker// Patterns to generate indexed loads with different forms of the address:
364*9880d681SAndroid Build Coastguard Worker// - frameindex,
365*9880d681SAndroid Build Coastguard Worker// - base + offset,
366*9880d681SAndroid Build Coastguard Worker// - base (without offset).
367*9880d681SAndroid Build Coastguard Workermulticlass Loadxm_pat<PatFrag Load, ValueType VT, PatFrag ValueMod,
368*9880d681SAndroid Build Coastguard Worker                      PatLeaf ImmPred, InstHexagon MI> {
369*9880d681SAndroid Build Coastguard Worker  def: Pat<(VT (Load AddrFI:$fi)),
370*9880d681SAndroid Build Coastguard Worker           (VT (ValueMod (MI AddrFI:$fi, 0)))>;
371*9880d681SAndroid Build Coastguard Worker  def: Pat<(VT (Load (add AddrFI:$fi, ImmPred:$Off))),
372*9880d681SAndroid Build Coastguard Worker           (VT (ValueMod (MI AddrFI:$fi, imm:$Off)))>;
373*9880d681SAndroid Build Coastguard Worker  def: Pat<(VT (Load (add IntRegs:$Rs, ImmPred:$Off))),
374*9880d681SAndroid Build Coastguard Worker           (VT (ValueMod (MI IntRegs:$Rs, imm:$Off)))>;
375*9880d681SAndroid Build Coastguard Worker  def: Pat<(VT (Load (i32 IntRegs:$Rs))),
376*9880d681SAndroid Build Coastguard Worker           (VT (ValueMod (MI IntRegs:$Rs, 0)))>;
377*9880d681SAndroid Build Coastguard Worker}
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Workerdefm: Loadxm_pat<extloadi1,   i64, Zext64, s32_0ImmPred, L2_loadrub_io>;
380*9880d681SAndroid Build Coastguard Workerdefm: Loadxm_pat<extloadi8,   i64, Zext64, s32_0ImmPred, L2_loadrub_io>;
381*9880d681SAndroid Build Coastguard Workerdefm: Loadxm_pat<extloadi16,  i64, Zext64, s31_1ImmPred, L2_loadruh_io>;
382*9880d681SAndroid Build Coastguard Workerdefm: Loadxm_pat<zextloadi1,  i64, Zext64, s32_0ImmPred, L2_loadrub_io>;
383*9880d681SAndroid Build Coastguard Workerdefm: Loadxm_pat<zextloadi8,  i64, Zext64, s32_0ImmPred, L2_loadrub_io>;
384*9880d681SAndroid Build Coastguard Workerdefm: Loadxm_pat<zextloadi16, i64, Zext64, s31_1ImmPred, L2_loadruh_io>;
385*9880d681SAndroid Build Coastguard Workerdefm: Loadxm_pat<sextloadi8,  i64, Sext64, s32_0ImmPred, L2_loadrb_io>;
386*9880d681SAndroid Build Coastguard Workerdefm: Loadxm_pat<sextloadi16, i64, Sext64, s31_1ImmPred, L2_loadrh_io>;
387*9880d681SAndroid Build Coastguard Worker
388*9880d681SAndroid Build Coastguard Worker// Map Rdd = anyext(Rs) -> Rdd = combine(#0, Rs).
389*9880d681SAndroid Build Coastguard Workerdef: Pat<(i64 (anyext (i32 IntRegs:$src1))), (Zext64 IntRegs:$src1)>;
390*9880d681SAndroid Build Coastguard Worker
391*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
392*9880d681SAndroid Build Coastguard Worker// Template class for load instructions with Absolute set addressing mode.
393*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
394*9880d681SAndroid Build Coastguard Workerlet isExtended = 1, opExtendable = 2, opExtentBits = 6, addrMode = AbsoluteSet,
395*9880d681SAndroid Build Coastguard Worker    hasSideEffects = 0 in
396*9880d681SAndroid Build Coastguard Workerclass T_LD_abs_set<string mnemonic, RegisterClass RC, bits<4>MajOp>:
397*9880d681SAndroid Build Coastguard Worker            LDInst<(outs RC:$dst1, IntRegs:$dst2),
398*9880d681SAndroid Build Coastguard Worker            (ins u6Ext:$addr),
399*9880d681SAndroid Build Coastguard Worker            "$dst1 = "#mnemonic#"($dst2 = #$addr)",
400*9880d681SAndroid Build Coastguard Worker            []> {
401*9880d681SAndroid Build Coastguard Worker  bits<7> name;
402*9880d681SAndroid Build Coastguard Worker  bits<5> dst1;
403*9880d681SAndroid Build Coastguard Worker  bits<5> dst2;
404*9880d681SAndroid Build Coastguard Worker  bits<6> addr;
405*9880d681SAndroid Build Coastguard Worker
406*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1001;
407*9880d681SAndroid Build Coastguard Worker  let Inst{27-25} = 0b101;
408*9880d681SAndroid Build Coastguard Worker  let Inst{24-21} = MajOp;
409*9880d681SAndroid Build Coastguard Worker  let Inst{13-12} = 0b01;
410*9880d681SAndroid Build Coastguard Worker  let Inst{4-0}   = dst1;
411*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = dst2;
412*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = addr{5-2};
413*9880d681SAndroid Build Coastguard Worker  let Inst{6-5}   = addr{1-0};
414*9880d681SAndroid Build Coastguard Worker}
415*9880d681SAndroid Build Coastguard Worker
416*9880d681SAndroid Build Coastguard Workerlet accessSize = ByteAccess, hasNewValue = 1 in {
417*9880d681SAndroid Build Coastguard Worker  def L4_loadrb_ap   : T_LD_abs_set <"memb",   IntRegs, 0b1000>;
418*9880d681SAndroid Build Coastguard Worker  def L4_loadrub_ap  : T_LD_abs_set <"memub",  IntRegs, 0b1001>;
419*9880d681SAndroid Build Coastguard Worker}
420*9880d681SAndroid Build Coastguard Worker
421*9880d681SAndroid Build Coastguard Workerlet accessSize = HalfWordAccess, hasNewValue = 1 in {
422*9880d681SAndroid Build Coastguard Worker  def L4_loadrh_ap  : T_LD_abs_set <"memh",  IntRegs, 0b1010>;
423*9880d681SAndroid Build Coastguard Worker  def L4_loadruh_ap : T_LD_abs_set <"memuh", IntRegs, 0b1011>;
424*9880d681SAndroid Build Coastguard Worker  def L4_loadbsw2_ap : T_LD_abs_set <"membh",  IntRegs, 0b0001>;
425*9880d681SAndroid Build Coastguard Worker  def L4_loadbzw2_ap : T_LD_abs_set <"memubh", IntRegs, 0b0011>;
426*9880d681SAndroid Build Coastguard Worker}
427*9880d681SAndroid Build Coastguard Worker
428*9880d681SAndroid Build Coastguard Workerlet accessSize = WordAccess, hasNewValue = 1 in
429*9880d681SAndroid Build Coastguard Worker  def L4_loadri_ap : T_LD_abs_set <"memw", IntRegs, 0b1100>;
430*9880d681SAndroid Build Coastguard Worker
431*9880d681SAndroid Build Coastguard Workerlet accessSize = WordAccess in {
432*9880d681SAndroid Build Coastguard Worker  def L4_loadbzw4_ap : T_LD_abs_set <"memubh", DoubleRegs, 0b0101>;
433*9880d681SAndroid Build Coastguard Worker  def L4_loadbsw4_ap : T_LD_abs_set <"membh",  DoubleRegs, 0b0111>;
434*9880d681SAndroid Build Coastguard Worker}
435*9880d681SAndroid Build Coastguard Worker
436*9880d681SAndroid Build Coastguard Workerlet accessSize = DoubleWordAccess in
437*9880d681SAndroid Build Coastguard Workerdef L4_loadrd_ap : T_LD_abs_set <"memd", DoubleRegs, 0b1110>;
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Workerlet accessSize = ByteAccess in
440*9880d681SAndroid Build Coastguard Worker  def L4_loadalignb_ap : T_LD_abs_set <"memb_fifo", DoubleRegs, 0b0100>;
441*9880d681SAndroid Build Coastguard Worker
442*9880d681SAndroid Build Coastguard Workerlet accessSize = HalfWordAccess in
443*9880d681SAndroid Build Coastguard Workerdef L4_loadalignh_ap : T_LD_abs_set <"memh_fifo", DoubleRegs, 0b0010>;
444*9880d681SAndroid Build Coastguard Worker
445*9880d681SAndroid Build Coastguard Worker// Load - Indirect with long offset
446*9880d681SAndroid Build Coastguard Workerlet InputType = "imm", addrMode = BaseLongOffset, isExtended = 1,
447*9880d681SAndroid Build Coastguard WorkeropExtentBits = 6, opExtendable = 3 in
448*9880d681SAndroid Build Coastguard Workerclass T_LoadAbsReg <string mnemonic, string CextOp, RegisterClass RC,
449*9880d681SAndroid Build Coastguard Worker                    bits<4> MajOp>
450*9880d681SAndroid Build Coastguard Worker  : LDInst <(outs RC:$dst), (ins IntRegs:$src1, u2Imm:$src2, u6Ext:$src3),
451*9880d681SAndroid Build Coastguard Worker  "$dst = "#mnemonic#"($src1<<#$src2 + #$src3)",
452*9880d681SAndroid Build Coastguard Worker  [] >, ImmRegShl {
453*9880d681SAndroid Build Coastguard Worker    bits<5> dst;
454*9880d681SAndroid Build Coastguard Worker    bits<5> src1;
455*9880d681SAndroid Build Coastguard Worker    bits<2> src2;
456*9880d681SAndroid Build Coastguard Worker    bits<6> src3;
457*9880d681SAndroid Build Coastguard Worker    let CextOpcode = CextOp;
458*9880d681SAndroid Build Coastguard Worker    let hasNewValue = !if (!eq(!cast<string>(RC), "DoubleRegs"), 0, 1);
459*9880d681SAndroid Build Coastguard Worker
460*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1001;
461*9880d681SAndroid Build Coastguard Worker    let Inst{27-25} = 0b110;
462*9880d681SAndroid Build Coastguard Worker    let Inst{24-21} = MajOp;
463*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src1;
464*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = src2{1};
465*9880d681SAndroid Build Coastguard Worker    let Inst{12}    = 0b1;
466*9880d681SAndroid Build Coastguard Worker    let Inst{11-8}  = src3{5-2};
467*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = src2{0};
468*9880d681SAndroid Build Coastguard Worker    let Inst{6-5}   = src3{1-0};
469*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = dst;
470*9880d681SAndroid Build Coastguard Worker  }
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Workerlet accessSize = ByteAccess in {
473*9880d681SAndroid Build Coastguard Worker  def L4_loadrb_ur  : T_LoadAbsReg<"memb",  "LDrib", IntRegs, 0b1000>;
474*9880d681SAndroid Build Coastguard Worker  def L4_loadrub_ur : T_LoadAbsReg<"memub", "LDriub", IntRegs, 0b1001>;
475*9880d681SAndroid Build Coastguard Worker  def L4_loadalignb_ur : T_LoadAbsReg<"memb_fifo", "LDrib_fifo",
476*9880d681SAndroid Build Coastguard Worker                                      DoubleRegs, 0b0100>;
477*9880d681SAndroid Build Coastguard Worker}
478*9880d681SAndroid Build Coastguard Worker
479*9880d681SAndroid Build Coastguard Workerlet accessSize = HalfWordAccess in {
480*9880d681SAndroid Build Coastguard Worker  def L4_loadrh_ur   : T_LoadAbsReg<"memh",   "LDrih",    IntRegs, 0b1010>;
481*9880d681SAndroid Build Coastguard Worker  def L4_loadruh_ur  : T_LoadAbsReg<"memuh",  "LDriuh",   IntRegs, 0b1011>;
482*9880d681SAndroid Build Coastguard Worker  def L4_loadbsw2_ur : T_LoadAbsReg<"membh",  "LDribh2",  IntRegs, 0b0001>;
483*9880d681SAndroid Build Coastguard Worker  def L4_loadbzw2_ur : T_LoadAbsReg<"memubh", "LDriubh2", IntRegs, 0b0011>;
484*9880d681SAndroid Build Coastguard Worker  def L4_loadalignh_ur : T_LoadAbsReg<"memh_fifo", "LDrih_fifo",
485*9880d681SAndroid Build Coastguard Worker                                      DoubleRegs, 0b0010>;
486*9880d681SAndroid Build Coastguard Worker}
487*9880d681SAndroid Build Coastguard Worker
488*9880d681SAndroid Build Coastguard Workerlet accessSize = WordAccess in {
489*9880d681SAndroid Build Coastguard Worker  def L4_loadri_ur   : T_LoadAbsReg<"memw", "LDriw", IntRegs, 0b1100>;
490*9880d681SAndroid Build Coastguard Worker  def L4_loadbsw4_ur : T_LoadAbsReg<"membh", "LDribh4", DoubleRegs, 0b0111>;
491*9880d681SAndroid Build Coastguard Worker  def L4_loadbzw4_ur : T_LoadAbsReg<"memubh", "LDriubh4", DoubleRegs, 0b0101>;
492*9880d681SAndroid Build Coastguard Worker}
493*9880d681SAndroid Build Coastguard Worker
494*9880d681SAndroid Build Coastguard Workerlet accessSize = DoubleWordAccess in
495*9880d681SAndroid Build Coastguard Workerdef L4_loadrd_ur  : T_LoadAbsReg<"memd", "LDrid", DoubleRegs, 0b1110>;
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Workermulticlass T_LoadAbsReg_Pat <PatFrag ldOp, InstHexagon MI, ValueType VT = i32> {
499*9880d681SAndroid Build Coastguard Worker  def  : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2),
500*9880d681SAndroid Build Coastguard Worker                             (HexagonCONST32 tglobaladdr:$src3)))),
501*9880d681SAndroid Build Coastguard Worker              (MI IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3)>;
502*9880d681SAndroid Build Coastguard Worker  def  : Pat <(VT (ldOp (add IntRegs:$src1,
503*9880d681SAndroid Build Coastguard Worker                             (HexagonCONST32 tglobaladdr:$src2)))),
504*9880d681SAndroid Build Coastguard Worker              (MI IntRegs:$src1, 0, tglobaladdr:$src2)>;
505*9880d681SAndroid Build Coastguard Worker
506*9880d681SAndroid Build Coastguard Worker  def  : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2),
507*9880d681SAndroid Build Coastguard Worker                             (HexagonCONST32 tconstpool:$src3)))),
508*9880d681SAndroid Build Coastguard Worker              (MI IntRegs:$src1, u2ImmPred:$src2, tconstpool:$src3)>;
509*9880d681SAndroid Build Coastguard Worker  def  : Pat <(VT (ldOp (add IntRegs:$src1,
510*9880d681SAndroid Build Coastguard Worker                             (HexagonCONST32 tconstpool:$src2)))),
511*9880d681SAndroid Build Coastguard Worker              (MI IntRegs:$src1, 0, tconstpool:$src2)>;
512*9880d681SAndroid Build Coastguard Worker
513*9880d681SAndroid Build Coastguard Worker  def  : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2),
514*9880d681SAndroid Build Coastguard Worker                             (HexagonCONST32 tjumptable:$src3)))),
515*9880d681SAndroid Build Coastguard Worker              (MI IntRegs:$src1, u2ImmPred:$src2, tjumptable:$src3)>;
516*9880d681SAndroid Build Coastguard Worker  def  : Pat <(VT (ldOp (add IntRegs:$src1,
517*9880d681SAndroid Build Coastguard Worker                             (HexagonCONST32 tjumptable:$src2)))),
518*9880d681SAndroid Build Coastguard Worker              (MI IntRegs:$src1, 0, tjumptable:$src2)>;
519*9880d681SAndroid Build Coastguard Worker}
520*9880d681SAndroid Build Coastguard Worker
521*9880d681SAndroid Build Coastguard Workerlet AddedComplexity  = 60 in {
522*9880d681SAndroid Build Coastguard Workerdefm : T_LoadAbsReg_Pat <sextloadi8, L4_loadrb_ur>;
523*9880d681SAndroid Build Coastguard Workerdefm : T_LoadAbsReg_Pat <zextloadi8, L4_loadrub_ur>;
524*9880d681SAndroid Build Coastguard Workerdefm : T_LoadAbsReg_Pat <extloadi8,  L4_loadrub_ur>;
525*9880d681SAndroid Build Coastguard Worker
526*9880d681SAndroid Build Coastguard Workerdefm : T_LoadAbsReg_Pat <sextloadi16, L4_loadrh_ur>;
527*9880d681SAndroid Build Coastguard Workerdefm : T_LoadAbsReg_Pat <zextloadi16, L4_loadruh_ur>;
528*9880d681SAndroid Build Coastguard Workerdefm : T_LoadAbsReg_Pat <extloadi16,  L4_loadruh_ur>;
529*9880d681SAndroid Build Coastguard Worker
530*9880d681SAndroid Build Coastguard Workerdefm : T_LoadAbsReg_Pat <load, L4_loadri_ur>;
531*9880d681SAndroid Build Coastguard Workerdefm : T_LoadAbsReg_Pat <load, L4_loadrd_ur, i64>;
532*9880d681SAndroid Build Coastguard Worker}
533*9880d681SAndroid Build Coastguard Worker
534*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
535*9880d681SAndroid Build Coastguard Worker// Template classes for the non-predicated load instructions with
536*9880d681SAndroid Build Coastguard Worker// base + register offset addressing mode
537*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
538*9880d681SAndroid Build Coastguard Workerclass T_load_rr <string mnemonic, RegisterClass RC, bits<3> MajOp>:
539*9880d681SAndroid Build Coastguard Worker   LDInst<(outs RC:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$u2),
540*9880d681SAndroid Build Coastguard Worker  "$dst = "#mnemonic#"($src1 + $src2<<#$u2)",
541*9880d681SAndroid Build Coastguard Worker  [], "", V4LDST_tc_ld_SLOT01>, ImmRegShl, AddrModeRel {
542*9880d681SAndroid Build Coastguard Worker    bits<5> dst;
543*9880d681SAndroid Build Coastguard Worker    bits<5> src1;
544*9880d681SAndroid Build Coastguard Worker    bits<5> src2;
545*9880d681SAndroid Build Coastguard Worker    bits<2> u2;
546*9880d681SAndroid Build Coastguard Worker
547*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0011;
548*9880d681SAndroid Build Coastguard Worker
549*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1010;
550*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = MajOp;
551*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src1;
552*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = src2;
553*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = u2{1};
554*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = u2{0};
555*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = dst;
556*9880d681SAndroid Build Coastguard Worker  }
557*9880d681SAndroid Build Coastguard Worker
558*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
559*9880d681SAndroid Build Coastguard Worker// Template classes for the predicated load instructions with
560*9880d681SAndroid Build Coastguard Worker// base + register offset addressing mode
561*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
562*9880d681SAndroid Build Coastguard Workerlet isPredicated =  1 in
563*9880d681SAndroid Build Coastguard Workerclass T_pload_rr <string mnemonic, RegisterClass RC, bits<3> MajOp,
564*9880d681SAndroid Build Coastguard Worker                  bit isNot, bit isPredNew>:
565*9880d681SAndroid Build Coastguard Worker   LDInst <(outs RC:$dst),
566*9880d681SAndroid Build Coastguard Worker           (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$u2),
567*9880d681SAndroid Build Coastguard Worker  !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
568*9880d681SAndroid Build Coastguard Worker  ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$u2)",
569*9880d681SAndroid Build Coastguard Worker  [], "", V4LDST_tc_ld_SLOT01>, AddrModeRel {
570*9880d681SAndroid Build Coastguard Worker    bits<5> dst;
571*9880d681SAndroid Build Coastguard Worker    bits<2> src1;
572*9880d681SAndroid Build Coastguard Worker    bits<5> src2;
573*9880d681SAndroid Build Coastguard Worker    bits<5> src3;
574*9880d681SAndroid Build Coastguard Worker    bits<2> u2;
575*9880d681SAndroid Build Coastguard Worker
576*9880d681SAndroid Build Coastguard Worker    let isPredicatedFalse = isNot;
577*9880d681SAndroid Build Coastguard Worker    let isPredicatedNew = isPredNew;
578*9880d681SAndroid Build Coastguard Worker
579*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0011;
580*9880d681SAndroid Build Coastguard Worker
581*9880d681SAndroid Build Coastguard Worker    let Inst{27-26} = 0b00;
582*9880d681SAndroid Build Coastguard Worker    let Inst{25}    = isPredNew;
583*9880d681SAndroid Build Coastguard Worker    let Inst{24}    = isNot;
584*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = MajOp;
585*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src2;
586*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = src3;
587*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = u2{1};
588*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = u2{0};
589*9880d681SAndroid Build Coastguard Worker    let Inst{6-5}   = src1;
590*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = dst;
591*9880d681SAndroid Build Coastguard Worker  }
592*9880d681SAndroid Build Coastguard Worker
593*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
594*9880d681SAndroid Build Coastguard Worker// multiclass for load instructions with base + register offset
595*9880d681SAndroid Build Coastguard Worker// addressing mode
596*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
597*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, addrMode = BaseRegOffset in
598*9880d681SAndroid Build Coastguard Workermulticlass ld_idxd_shl <string mnemonic, string CextOp, RegisterClass RC,
599*9880d681SAndroid Build Coastguard Worker                        bits<3> MajOp > {
600*9880d681SAndroid Build Coastguard Worker  let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl,
601*9880d681SAndroid Build Coastguard Worker      InputType = "reg" in {
602*9880d681SAndroid Build Coastguard Worker    let isPredicable = 1 in
603*9880d681SAndroid Build Coastguard Worker    def L4_#NAME#_rr : T_load_rr <mnemonic, RC, MajOp>;
604*9880d681SAndroid Build Coastguard Worker
605*9880d681SAndroid Build Coastguard Worker    // Predicated
606*9880d681SAndroid Build Coastguard Worker    def L4_p#NAME#t_rr : T_pload_rr <mnemonic, RC, MajOp, 0, 0>;
607*9880d681SAndroid Build Coastguard Worker    def L4_p#NAME#f_rr : T_pload_rr <mnemonic, RC, MajOp, 1, 0>;
608*9880d681SAndroid Build Coastguard Worker
609*9880d681SAndroid Build Coastguard Worker    // Predicated new
610*9880d681SAndroid Build Coastguard Worker    def L4_p#NAME#tnew_rr : T_pload_rr <mnemonic, RC, MajOp, 0, 1>;
611*9880d681SAndroid Build Coastguard Worker    def L4_p#NAME#fnew_rr : T_pload_rr <mnemonic, RC, MajOp, 1, 1>;
612*9880d681SAndroid Build Coastguard Worker  }
613*9880d681SAndroid Build Coastguard Worker}
614*9880d681SAndroid Build Coastguard Worker
615*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, accessSize = ByteAccess in {
616*9880d681SAndroid Build Coastguard Worker  defm loadrb  : ld_idxd_shl<"memb", "LDrib", IntRegs, 0b000>;
617*9880d681SAndroid Build Coastguard Worker  defm loadrub : ld_idxd_shl<"memub", "LDriub", IntRegs, 0b001>;
618*9880d681SAndroid Build Coastguard Worker}
619*9880d681SAndroid Build Coastguard Worker
620*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, accessSize = HalfWordAccess in {
621*9880d681SAndroid Build Coastguard Worker  defm loadrh  : ld_idxd_shl<"memh", "LDrih", IntRegs, 0b010>;
622*9880d681SAndroid Build Coastguard Worker  defm loadruh : ld_idxd_shl<"memuh", "LDriuh", IntRegs, 0b011>;
623*9880d681SAndroid Build Coastguard Worker}
624*9880d681SAndroid Build Coastguard Worker
625*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, accessSize = WordAccess in
626*9880d681SAndroid Build Coastguard Workerdefm loadri : ld_idxd_shl<"memw", "LDriw", IntRegs, 0b100>;
627*9880d681SAndroid Build Coastguard Worker
628*9880d681SAndroid Build Coastguard Workerlet accessSize = DoubleWordAccess in
629*9880d681SAndroid Build Coastguard Workerdefm loadrd  : ld_idxd_shl<"memd", "LDrid", DoubleRegs, 0b110>;
630*9880d681SAndroid Build Coastguard Worker
631*9880d681SAndroid Build Coastguard Worker// 'def pats' for load instructions with base + register offset and non-zero
632*9880d681SAndroid Build Coastguard Worker// immediate value. Immediate value is used to left-shift the second
633*9880d681SAndroid Build Coastguard Worker// register operand.
634*9880d681SAndroid Build Coastguard Workerclass Loadxs_pat<PatFrag Load, ValueType VT, InstHexagon MI>
635*9880d681SAndroid Build Coastguard Worker  : Pat<(VT (Load (add (i32 IntRegs:$Rs),
636*9880d681SAndroid Build Coastguard Worker                       (i32 (shl (i32 IntRegs:$Rt), u2ImmPred:$u2))))),
637*9880d681SAndroid Build Coastguard Worker        (VT (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2))>;
638*9880d681SAndroid Build Coastguard Worker
639*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 40 in {
640*9880d681SAndroid Build Coastguard Worker  def: Loadxs_pat<extloadi8,   i32, L4_loadrub_rr>;
641*9880d681SAndroid Build Coastguard Worker  def: Loadxs_pat<zextloadi8,  i32, L4_loadrub_rr>;
642*9880d681SAndroid Build Coastguard Worker  def: Loadxs_pat<sextloadi8,  i32, L4_loadrb_rr>;
643*9880d681SAndroid Build Coastguard Worker  def: Loadxs_pat<extloadi16,  i32, L4_loadruh_rr>;
644*9880d681SAndroid Build Coastguard Worker  def: Loadxs_pat<zextloadi16, i32, L4_loadruh_rr>;
645*9880d681SAndroid Build Coastguard Worker  def: Loadxs_pat<sextloadi16, i32, L4_loadrh_rr>;
646*9880d681SAndroid Build Coastguard Worker  def: Loadxs_pat<load,        i32, L4_loadri_rr>;
647*9880d681SAndroid Build Coastguard Worker  def: Loadxs_pat<load,        i64, L4_loadrd_rr>;
648*9880d681SAndroid Build Coastguard Worker}
649*9880d681SAndroid Build Coastguard Worker
650*9880d681SAndroid Build Coastguard Worker// 'def pats' for load instruction base + register offset and
651*9880d681SAndroid Build Coastguard Worker// zero immediate value.
652*9880d681SAndroid Build Coastguard Workerclass Loadxs_simple_pat<PatFrag Load, ValueType VT, InstHexagon MI>
653*9880d681SAndroid Build Coastguard Worker  : Pat<(VT (Load (add (i32 IntRegs:$Rs), (i32 IntRegs:$Rt)))),
654*9880d681SAndroid Build Coastguard Worker        (VT (MI IntRegs:$Rs, IntRegs:$Rt, 0))>;
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 20 in {
657*9880d681SAndroid Build Coastguard Worker  def: Loadxs_simple_pat<extloadi8,   i32, L4_loadrub_rr>;
658*9880d681SAndroid Build Coastguard Worker  def: Loadxs_simple_pat<zextloadi8,  i32, L4_loadrub_rr>;
659*9880d681SAndroid Build Coastguard Worker  def: Loadxs_simple_pat<sextloadi8,  i32, L4_loadrb_rr>;
660*9880d681SAndroid Build Coastguard Worker  def: Loadxs_simple_pat<extloadi16,  i32, L4_loadruh_rr>;
661*9880d681SAndroid Build Coastguard Worker  def: Loadxs_simple_pat<zextloadi16, i32, L4_loadruh_rr>;
662*9880d681SAndroid Build Coastguard Worker  def: Loadxs_simple_pat<sextloadi16, i32, L4_loadrh_rr>;
663*9880d681SAndroid Build Coastguard Worker  def: Loadxs_simple_pat<load,        i32, L4_loadri_rr>;
664*9880d681SAndroid Build Coastguard Worker  def: Loadxs_simple_pat<load,        i64, L4_loadrd_rr>;
665*9880d681SAndroid Build Coastguard Worker}
666*9880d681SAndroid Build Coastguard Worker
667*9880d681SAndroid Build Coastguard Worker// zext i1->i64
668*9880d681SAndroid Build Coastguard Workerdef: Pat<(i64 (zext (i1 PredRegs:$src1))),
669*9880d681SAndroid Build Coastguard Worker         (Zext64 (C2_muxii PredRegs:$src1, 1, 0))>;
670*9880d681SAndroid Build Coastguard Worker
671*9880d681SAndroid Build Coastguard Worker// zext i32->i64
672*9880d681SAndroid Build Coastguard Workerdef: Pat<(i64 (zext (i32 IntRegs:$src1))),
673*9880d681SAndroid Build Coastguard Worker         (Zext64 IntRegs:$src1)>;
674*9880d681SAndroid Build Coastguard Worker
675*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
676*9880d681SAndroid Build Coastguard Worker// LD -
677*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
678*9880d681SAndroid Build Coastguard Worker
679*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
680*9880d681SAndroid Build Coastguard Worker// ST +
681*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
682*9880d681SAndroid Build Coastguard Worker///
683*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
684*9880d681SAndroid Build Coastguard Worker// Template class for store instructions with Absolute set addressing mode.
685*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
686*9880d681SAndroid Build Coastguard Workerlet isExtended = 1, opExtendable = 1, opExtentBits = 6,
687*9880d681SAndroid Build Coastguard Worker    addrMode = AbsoluteSet in
688*9880d681SAndroid Build Coastguard Workerclass T_ST_absset <string mnemonic, string BaseOp, RegisterClass RC,
689*9880d681SAndroid Build Coastguard Worker                   bits<3> MajOp, MemAccessSize AccessSz, bit isHalf = 0>
690*9880d681SAndroid Build Coastguard Worker  : STInst<(outs IntRegs:$dst),
691*9880d681SAndroid Build Coastguard Worker           (ins u6Ext:$addr, RC:$src),
692*9880d681SAndroid Build Coastguard Worker    mnemonic#"($dst = #$addr) = $src"#!if(isHalf, ".h","")>, NewValueRel {
693*9880d681SAndroid Build Coastguard Worker    bits<5> dst;
694*9880d681SAndroid Build Coastguard Worker    bits<6> addr;
695*9880d681SAndroid Build Coastguard Worker    bits<5> src;
696*9880d681SAndroid Build Coastguard Worker    let accessSize = AccessSz;
697*9880d681SAndroid Build Coastguard Worker    let BaseOpcode = BaseOp#"_AbsSet";
698*9880d681SAndroid Build Coastguard Worker
699*9880d681SAndroid Build Coastguard Worker    // Store upper-half and store doubleword cannot be NV.
700*9880d681SAndroid Build Coastguard Worker    let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isHalf,0,1));
701*9880d681SAndroid Build Coastguard Worker
702*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1010;
703*9880d681SAndroid Build Coastguard Worker
704*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1011;
705*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = MajOp;
706*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = dst;
707*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = 0b0;
708*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = src;
709*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = 0b1;
710*9880d681SAndroid Build Coastguard Worker    let Inst{5-0}   = addr;
711*9880d681SAndroid Build Coastguard Worker  }
712*9880d681SAndroid Build Coastguard Worker
713*9880d681SAndroid Build Coastguard Workerdef S4_storerb_ap : T_ST_absset <"memb", "STrib", IntRegs, 0b000, ByteAccess>;
714*9880d681SAndroid Build Coastguard Workerdef S4_storerh_ap : T_ST_absset <"memh", "STrih", IntRegs, 0b010,
715*9880d681SAndroid Build Coastguard Worker                                 HalfWordAccess>;
716*9880d681SAndroid Build Coastguard Workerdef S4_storeri_ap : T_ST_absset <"memw", "STriw", IntRegs, 0b100, WordAccess>;
717*9880d681SAndroid Build Coastguard Worker
718*9880d681SAndroid Build Coastguard Workerlet isNVStorable = 0 in {
719*9880d681SAndroid Build Coastguard Worker  def S4_storerf_ap : T_ST_absset <"memh", "STrif", IntRegs,
720*9880d681SAndroid Build Coastguard Worker                                   0b011, HalfWordAccess, 1>;
721*9880d681SAndroid Build Coastguard Worker  def S4_storerd_ap : T_ST_absset <"memd", "STrid", DoubleRegs,
722*9880d681SAndroid Build Coastguard Worker                                   0b110, DoubleWordAccess>;
723*9880d681SAndroid Build Coastguard Worker}
724*9880d681SAndroid Build Coastguard Worker
725*9880d681SAndroid Build Coastguard Workerlet opExtendable = 1, isNewValue = 1, isNVStore = 1, opNewValue = 2,
726*9880d681SAndroid Build Coastguard WorkerisExtended = 1, opExtentBits= 6 in
727*9880d681SAndroid Build Coastguard Workerclass T_ST_absset_nv <string mnemonic, string BaseOp, bits<2> MajOp,
728*9880d681SAndroid Build Coastguard Worker                      MemAccessSize AccessSz >
729*9880d681SAndroid Build Coastguard Worker  : NVInst <(outs IntRegs:$dst),
730*9880d681SAndroid Build Coastguard Worker            (ins u6Ext:$addr, IntRegs:$src),
731*9880d681SAndroid Build Coastguard Worker    mnemonic#"($dst = #$addr) = $src.new">, NewValueRel {
732*9880d681SAndroid Build Coastguard Worker    bits<5> dst;
733*9880d681SAndroid Build Coastguard Worker    bits<6> addr;
734*9880d681SAndroid Build Coastguard Worker    bits<3> src;
735*9880d681SAndroid Build Coastguard Worker    let accessSize = AccessSz;
736*9880d681SAndroid Build Coastguard Worker    let BaseOpcode = BaseOp#"_AbsSet";
737*9880d681SAndroid Build Coastguard Worker
738*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1010;
739*9880d681SAndroid Build Coastguard Worker
740*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b1011101;
741*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = dst;
742*9880d681SAndroid Build Coastguard Worker    let Inst{13-11} = 0b000;
743*9880d681SAndroid Build Coastguard Worker    let Inst{12-11} = MajOp;
744*9880d681SAndroid Build Coastguard Worker    let Inst{10-8}  = src;
745*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = 0b1;
746*9880d681SAndroid Build Coastguard Worker    let Inst{5-0}   = addr;
747*9880d681SAndroid Build Coastguard Worker  }
748*9880d681SAndroid Build Coastguard Worker
749*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, addrMode = AbsoluteSet in {
750*9880d681SAndroid Build Coastguard Worker  def S4_storerbnew_ap : T_ST_absset_nv <"memb", "STrib", 0b00, ByteAccess>;
751*9880d681SAndroid Build Coastguard Worker  def S4_storerhnew_ap : T_ST_absset_nv <"memh", "STrih", 0b01, HalfWordAccess>;
752*9880d681SAndroid Build Coastguard Worker  def S4_storerinew_ap : T_ST_absset_nv <"memw", "STriw", 0b10, WordAccess>;
753*9880d681SAndroid Build Coastguard Worker}
754*9880d681SAndroid Build Coastguard Worker
755*9880d681SAndroid Build Coastguard Workerlet isExtended = 1, opExtendable = 2, opExtentBits = 6, InputType = "imm",
756*9880d681SAndroid Build Coastguard Worker    addrMode = BaseLongOffset, AddedComplexity = 40 in
757*9880d681SAndroid Build Coastguard Workerclass T_StoreAbsReg <string mnemonic, string CextOp, RegisterClass RC,
758*9880d681SAndroid Build Coastguard Worker                     bits<3> MajOp, MemAccessSize AccessSz, bit isHalf = 0>
759*9880d681SAndroid Build Coastguard Worker  : STInst<(outs),
760*9880d681SAndroid Build Coastguard Worker           (ins IntRegs:$src1, u2Imm:$src2, u6Ext:$src3, RC:$src4),
761*9880d681SAndroid Build Coastguard Worker   mnemonic#"($src1<<#$src2 + #$src3) = $src4"#!if(isHalf, ".h",""),
762*9880d681SAndroid Build Coastguard Worker   []>, ImmRegShl, NewValueRel {
763*9880d681SAndroid Build Coastguard Worker
764*9880d681SAndroid Build Coastguard Worker    bits<5> src1;
765*9880d681SAndroid Build Coastguard Worker    bits<2> src2;
766*9880d681SAndroid Build Coastguard Worker    bits<6> src3;
767*9880d681SAndroid Build Coastguard Worker    bits<5> src4;
768*9880d681SAndroid Build Coastguard Worker
769*9880d681SAndroid Build Coastguard Worker    let accessSize = AccessSz;
770*9880d681SAndroid Build Coastguard Worker    let CextOpcode = CextOp;
771*9880d681SAndroid Build Coastguard Worker    let BaseOpcode = CextOp#"_shl";
772*9880d681SAndroid Build Coastguard Worker
773*9880d681SAndroid Build Coastguard Worker    // Store upper-half and store doubleword cannot be NV.
774*9880d681SAndroid Build Coastguard Worker    let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isHalf,0,1));
775*9880d681SAndroid Build Coastguard Worker
776*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1010;
777*9880d681SAndroid Build Coastguard Worker
778*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} =0b1101;
779*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = MajOp;
780*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src1;
781*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = src2{1};
782*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = src4;
783*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = 0b1;
784*9880d681SAndroid Build Coastguard Worker    let Inst{6}     = src2{0};
785*9880d681SAndroid Build Coastguard Worker    let Inst{5-0}   = src3;
786*9880d681SAndroid Build Coastguard Worker}
787*9880d681SAndroid Build Coastguard Worker
788*9880d681SAndroid Build Coastguard Workerdef S4_storerb_ur : T_StoreAbsReg <"memb", "STrib", IntRegs, 0b000, ByteAccess>;
789*9880d681SAndroid Build Coastguard Workerdef S4_storerh_ur : T_StoreAbsReg <"memh", "STrih", IntRegs, 0b010,
790*9880d681SAndroid Build Coastguard Worker                                   HalfWordAccess>;
791*9880d681SAndroid Build Coastguard Workerdef S4_storerf_ur : T_StoreAbsReg <"memh", "STrif", IntRegs, 0b011,
792*9880d681SAndroid Build Coastguard Worker                                   HalfWordAccess, 1>;
793*9880d681SAndroid Build Coastguard Workerdef S4_storeri_ur : T_StoreAbsReg <"memw", "STriw", IntRegs, 0b100, WordAccess>;
794*9880d681SAndroid Build Coastguard Workerdef S4_storerd_ur : T_StoreAbsReg <"memd", "STrid", DoubleRegs, 0b110,
795*9880d681SAndroid Build Coastguard Worker                                   DoubleWordAccess>;
796*9880d681SAndroid Build Coastguard Worker
797*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 40 in
798*9880d681SAndroid Build Coastguard Workermulticlass T_StoreAbsReg_Pats <InstHexagon MI, RegisterClass RC, ValueType VT,
799*9880d681SAndroid Build Coastguard Worker                           PatFrag stOp> {
800*9880d681SAndroid Build Coastguard Worker def : Pat<(stOp (VT RC:$src4),
801*9880d681SAndroid Build Coastguard Worker                 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
802*9880d681SAndroid Build Coastguard Worker                      u32ImmPred:$src3)),
803*9880d681SAndroid Build Coastguard Worker          (MI IntRegs:$src1, u2ImmPred:$src2, u32ImmPred:$src3, RC:$src4)>;
804*9880d681SAndroid Build Coastguard Worker
805*9880d681SAndroid Build Coastguard Worker def : Pat<(stOp (VT RC:$src4),
806*9880d681SAndroid Build Coastguard Worker                 (add (shl IntRegs:$src1, u2ImmPred:$src2),
807*9880d681SAndroid Build Coastguard Worker                      (HexagonCONST32 tglobaladdr:$src3))),
808*9880d681SAndroid Build Coastguard Worker           (MI IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>;
809*9880d681SAndroid Build Coastguard Worker
810*9880d681SAndroid Build Coastguard Worker def : Pat<(stOp (VT RC:$src4),
811*9880d681SAndroid Build Coastguard Worker                 (add IntRegs:$src1, (HexagonCONST32 tglobaladdr:$src3))),
812*9880d681SAndroid Build Coastguard Worker           (MI IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>;
813*9880d681SAndroid Build Coastguard Worker}
814*9880d681SAndroid Build Coastguard Worker
815*9880d681SAndroid Build Coastguard Workerdefm : T_StoreAbsReg_Pats <S4_storerd_ur, DoubleRegs, i64, store>;
816*9880d681SAndroid Build Coastguard Workerdefm : T_StoreAbsReg_Pats <S4_storeri_ur, IntRegs, i32, store>;
817*9880d681SAndroid Build Coastguard Workerdefm : T_StoreAbsReg_Pats <S4_storerb_ur, IntRegs, i32, truncstorei8>;
818*9880d681SAndroid Build Coastguard Workerdefm : T_StoreAbsReg_Pats <S4_storerh_ur, IntRegs, i32, truncstorei16>;
819*9880d681SAndroid Build Coastguard Worker
820*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, isNVStore = 1, isExtended = 1, addrMode = BaseLongOffset,
821*9880d681SAndroid Build Coastguard Worker    opExtentBits = 6, isNewValue = 1, opNewValue = 3, opExtendable = 2 in
822*9880d681SAndroid Build Coastguard Workerclass T_StoreAbsRegNV <string mnemonic, string CextOp, bits<2> MajOp,
823*9880d681SAndroid Build Coastguard Worker                       MemAccessSize AccessSz>
824*9880d681SAndroid Build Coastguard Worker  : NVInst <(outs ),
825*9880d681SAndroid Build Coastguard Worker            (ins IntRegs:$src1, u2Imm:$src2, u6Ext:$src3, IntRegs:$src4),
826*9880d681SAndroid Build Coastguard Worker  mnemonic#"($src1<<#$src2 + #$src3) = $src4.new">, NewValueRel {
827*9880d681SAndroid Build Coastguard Worker    bits<5> src1;
828*9880d681SAndroid Build Coastguard Worker    bits<2> src2;
829*9880d681SAndroid Build Coastguard Worker    bits<6> src3;
830*9880d681SAndroid Build Coastguard Worker    bits<3> src4;
831*9880d681SAndroid Build Coastguard Worker
832*9880d681SAndroid Build Coastguard Worker    let CextOpcode  = CextOp;
833*9880d681SAndroid Build Coastguard Worker    let BaseOpcode  = CextOp#"_shl";
834*9880d681SAndroid Build Coastguard Worker    let IClass      = 0b1010;
835*9880d681SAndroid Build Coastguard Worker
836*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b1101101;
837*9880d681SAndroid Build Coastguard Worker    let Inst{12-11} = 0b00;
838*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = 0b1;
839*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src1;
840*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = src2{1};
841*9880d681SAndroid Build Coastguard Worker    let Inst{12-11} = MajOp;
842*9880d681SAndroid Build Coastguard Worker    let Inst{10-8}  = src4;
843*9880d681SAndroid Build Coastguard Worker    let Inst{6}     = src2{0};
844*9880d681SAndroid Build Coastguard Worker    let Inst{5-0}   = src3;
845*9880d681SAndroid Build Coastguard Worker  }
846*9880d681SAndroid Build Coastguard Worker
847*9880d681SAndroid Build Coastguard Workerdef S4_storerbnew_ur : T_StoreAbsRegNV <"memb", "STrib", 0b00, ByteAccess>;
848*9880d681SAndroid Build Coastguard Workerdef S4_storerhnew_ur : T_StoreAbsRegNV <"memh", "STrih", 0b01, HalfWordAccess>;
849*9880d681SAndroid Build Coastguard Workerdef S4_storerinew_ur : T_StoreAbsRegNV <"memw", "STriw", 0b10, WordAccess>;
850*9880d681SAndroid Build Coastguard Worker
851*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
852*9880d681SAndroid Build Coastguard Worker// Template classes for the non-predicated store instructions with
853*9880d681SAndroid Build Coastguard Worker// base + register offset addressing mode
854*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
855*9880d681SAndroid Build Coastguard Workerlet isPredicable = 1 in
856*9880d681SAndroid Build Coastguard Workerclass T_store_rr <string mnemonic, RegisterClass RC, bits<3> MajOp, bit isH>
857*9880d681SAndroid Build Coastguard Worker  : STInst < (outs ), (ins IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, RC:$Rt),
858*9880d681SAndroid Build Coastguard Worker  mnemonic#"($Rs + $Ru<<#$u2) = $Rt"#!if(isH, ".h",""),
859*9880d681SAndroid Build Coastguard Worker  [],"",V4LDST_tc_st_SLOT01>, ImmRegShl, AddrModeRel {
860*9880d681SAndroid Build Coastguard Worker
861*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
862*9880d681SAndroid Build Coastguard Worker    bits<5> Ru;
863*9880d681SAndroid Build Coastguard Worker    bits<2> u2;
864*9880d681SAndroid Build Coastguard Worker    bits<5> Rt;
865*9880d681SAndroid Build Coastguard Worker
866*9880d681SAndroid Build Coastguard Worker    // Store upper-half and store doubleword cannot be NV.
867*9880d681SAndroid Build Coastguard Worker    let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isH,0,1));
868*9880d681SAndroid Build Coastguard Worker
869*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0011;
870*9880d681SAndroid Build Coastguard Worker
871*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1011;
872*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = MajOp;
873*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
874*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Ru;
875*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = u2{1};
876*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = u2{0};
877*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rt;
878*9880d681SAndroid Build Coastguard Worker  }
879*9880d681SAndroid Build Coastguard Worker
880*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
881*9880d681SAndroid Build Coastguard Worker// Template classes for the predicated store instructions with
882*9880d681SAndroid Build Coastguard Worker// base + register offset addressing mode
883*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
884*9880d681SAndroid Build Coastguard Workerlet isPredicated = 1 in
885*9880d681SAndroid Build Coastguard Workerclass T_pstore_rr <string mnemonic, RegisterClass RC, bits<3> MajOp,
886*9880d681SAndroid Build Coastguard Worker                   bit isNot, bit isPredNew, bit isH>
887*9880d681SAndroid Build Coastguard Worker  : STInst <(outs),
888*9880d681SAndroid Build Coastguard Worker            (ins PredRegs:$Pv, IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, RC:$Rt),
889*9880d681SAndroid Build Coastguard Worker
890*9880d681SAndroid Build Coastguard Worker  !if(isNot, "if (!$Pv", "if ($Pv")#!if(isPredNew, ".new) ",
891*9880d681SAndroid Build Coastguard Worker  ") ")#mnemonic#"($Rs+$Ru<<#$u2) = $Rt"#!if(isH, ".h",""),
892*9880d681SAndroid Build Coastguard Worker  [], "", V4LDST_tc_st_SLOT01> , AddrModeRel{
893*9880d681SAndroid Build Coastguard Worker    bits<2> Pv;
894*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
895*9880d681SAndroid Build Coastguard Worker    bits<5> Ru;
896*9880d681SAndroid Build Coastguard Worker    bits<2> u2;
897*9880d681SAndroid Build Coastguard Worker    bits<5> Rt;
898*9880d681SAndroid Build Coastguard Worker
899*9880d681SAndroid Build Coastguard Worker    let isPredicatedFalse = isNot;
900*9880d681SAndroid Build Coastguard Worker    let isPredicatedNew = isPredNew;
901*9880d681SAndroid Build Coastguard Worker    // Store upper-half and store doubleword cannot be NV.
902*9880d681SAndroid Build Coastguard Worker    let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isH,0,1));
903*9880d681SAndroid Build Coastguard Worker
904*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0011;
905*9880d681SAndroid Build Coastguard Worker
906*9880d681SAndroid Build Coastguard Worker    let Inst{27-26} = 0b01;
907*9880d681SAndroid Build Coastguard Worker    let Inst{25}    = isPredNew;
908*9880d681SAndroid Build Coastguard Worker    let Inst{24}    = isNot;
909*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = MajOp;
910*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
911*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Ru;
912*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = u2{1};
913*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = u2{0};
914*9880d681SAndroid Build Coastguard Worker    let Inst{6-5}   = Pv;
915*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rt;
916*9880d681SAndroid Build Coastguard Worker  }
917*9880d681SAndroid Build Coastguard Worker
918*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
919*9880d681SAndroid Build Coastguard Worker// Template classes for the new-value store instructions with
920*9880d681SAndroid Build Coastguard Worker// base + register offset addressing mode
921*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
922*9880d681SAndroid Build Coastguard Workerlet isPredicable = 1, isNewValue = 1, opNewValue = 3 in
923*9880d681SAndroid Build Coastguard Workerclass T_store_new_rr <string mnemonic, bits<2> MajOp> :
924*9880d681SAndroid Build Coastguard Worker  NVInst < (outs ), (ins IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, IntRegs:$Nt),
925*9880d681SAndroid Build Coastguard Worker  mnemonic#"($Rs + $Ru<<#$u2) = $Nt.new",
926*9880d681SAndroid Build Coastguard Worker  [],"",V4LDST_tc_st_SLOT0>, ImmRegShl, AddrModeRel {
927*9880d681SAndroid Build Coastguard Worker
928*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
929*9880d681SAndroid Build Coastguard Worker    bits<5> Ru;
930*9880d681SAndroid Build Coastguard Worker    bits<2> u2;
931*9880d681SAndroid Build Coastguard Worker    bits<3> Nt;
932*9880d681SAndroid Build Coastguard Worker
933*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0011;
934*9880d681SAndroid Build Coastguard Worker
935*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b1011101;
936*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
937*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Ru;
938*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = u2{1};
939*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = u2{0};
940*9880d681SAndroid Build Coastguard Worker    let Inst{4-3}   = MajOp;
941*9880d681SAndroid Build Coastguard Worker    let Inst{2-0}   = Nt;
942*9880d681SAndroid Build Coastguard Worker  }
943*9880d681SAndroid Build Coastguard Worker
944*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
945*9880d681SAndroid Build Coastguard Worker// Template classes for the predicated new-value store instructions with
946*9880d681SAndroid Build Coastguard Worker// base + register offset addressing mode
947*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
948*9880d681SAndroid Build Coastguard Workerlet isPredicated = 1, isNewValue = 1, opNewValue = 4 in
949*9880d681SAndroid Build Coastguard Workerclass T_pstore_new_rr <string mnemonic, bits<2> MajOp, bit isNot, bit isPredNew>
950*9880d681SAndroid Build Coastguard Worker  : NVInst<(outs),
951*9880d681SAndroid Build Coastguard Worker           (ins PredRegs:$Pv, IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, IntRegs:$Nt),
952*9880d681SAndroid Build Coastguard Worker   !if(isNot, "if (!$Pv", "if ($Pv")#!if(isPredNew, ".new) ",
953*9880d681SAndroid Build Coastguard Worker   ") ")#mnemonic#"($Rs+$Ru<<#$u2) = $Nt.new",
954*9880d681SAndroid Build Coastguard Worker   [], "", V4LDST_tc_st_SLOT0>, AddrModeRel {
955*9880d681SAndroid Build Coastguard Worker    bits<2> Pv;
956*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
957*9880d681SAndroid Build Coastguard Worker    bits<5> Ru;
958*9880d681SAndroid Build Coastguard Worker    bits<2> u2;
959*9880d681SAndroid Build Coastguard Worker    bits<3> Nt;
960*9880d681SAndroid Build Coastguard Worker
961*9880d681SAndroid Build Coastguard Worker    let isPredicatedFalse = isNot;
962*9880d681SAndroid Build Coastguard Worker    let isPredicatedNew = isPredNew;
963*9880d681SAndroid Build Coastguard Worker
964*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0011;
965*9880d681SAndroid Build Coastguard Worker    let Inst{27-26} = 0b01;
966*9880d681SAndroid Build Coastguard Worker    let Inst{25}    = isPredNew;
967*9880d681SAndroid Build Coastguard Worker    let Inst{24}    = isNot;
968*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = 0b101;
969*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
970*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Ru;
971*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = u2{1};
972*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = u2{0};
973*9880d681SAndroid Build Coastguard Worker    let Inst{6-5}   = Pv;
974*9880d681SAndroid Build Coastguard Worker    let Inst{4-3}   = MajOp;
975*9880d681SAndroid Build Coastguard Worker    let Inst{2-0}   = Nt;
976*9880d681SAndroid Build Coastguard Worker  }
977*9880d681SAndroid Build Coastguard Worker
978*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
979*9880d681SAndroid Build Coastguard Worker// multiclass for store instructions with base + register offset addressing
980*9880d681SAndroid Build Coastguard Worker// mode
981*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
982*9880d681SAndroid Build Coastguard Workerlet isNVStorable = 1 in
983*9880d681SAndroid Build Coastguard Workermulticlass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC,
984*9880d681SAndroid Build Coastguard Worker                       bits<3> MajOp, bit isH = 0> {
985*9880d681SAndroid Build Coastguard Worker  let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
986*9880d681SAndroid Build Coastguard Worker    def S4_#NAME#_rr : T_store_rr <mnemonic, RC, MajOp, isH>;
987*9880d681SAndroid Build Coastguard Worker
988*9880d681SAndroid Build Coastguard Worker    // Predicated
989*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#t_rr : T_pstore_rr <mnemonic, RC, MajOp, 0, 0, isH>;
990*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#f_rr : T_pstore_rr <mnemonic, RC, MajOp, 1, 0, isH>;
991*9880d681SAndroid Build Coastguard Worker
992*9880d681SAndroid Build Coastguard Worker    // Predicated new
993*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#tnew_rr : T_pstore_rr <mnemonic, RC, MajOp, 0, 1, isH>;
994*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#fnew_rr : T_pstore_rr <mnemonic, RC, MajOp, 1, 1, isH>;
995*9880d681SAndroid Build Coastguard Worker  }
996*9880d681SAndroid Build Coastguard Worker}
997*9880d681SAndroid Build Coastguard Worker
998*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
999*9880d681SAndroid Build Coastguard Worker// multiclass for new-value store instructions with base + register offset
1000*9880d681SAndroid Build Coastguard Worker// addressing mode.
1001*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1002*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, isNVStore = 1 in
1003*9880d681SAndroid Build Coastguard Workermulticlass ST_Idxd_shl_nv <string mnemonic, string CextOp, RegisterClass RC,
1004*9880d681SAndroid Build Coastguard Worker                           bits<2> MajOp> {
1005*9880d681SAndroid Build Coastguard Worker  let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
1006*9880d681SAndroid Build Coastguard Worker    def S4_#NAME#new_rr : T_store_new_rr<mnemonic, MajOp>;
1007*9880d681SAndroid Build Coastguard Worker
1008*9880d681SAndroid Build Coastguard Worker    // Predicated
1009*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#newt_rr : T_pstore_new_rr <mnemonic, MajOp, 0, 0>;
1010*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#newf_rr : T_pstore_new_rr <mnemonic, MajOp, 1, 0>;
1011*9880d681SAndroid Build Coastguard Worker
1012*9880d681SAndroid Build Coastguard Worker    // Predicated new
1013*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#newtnew_rr : T_pstore_new_rr <mnemonic, MajOp, 0, 1>;
1014*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#newfnew_rr : T_pstore_new_rr <mnemonic, MajOp, 1, 1>;
1015*9880d681SAndroid Build Coastguard Worker  }
1016*9880d681SAndroid Build Coastguard Worker}
1017*9880d681SAndroid Build Coastguard Worker
1018*9880d681SAndroid Build Coastguard Workerlet addrMode = BaseRegOffset, InputType = "reg", hasSideEffects = 0 in {
1019*9880d681SAndroid Build Coastguard Worker  let accessSize = ByteAccess in
1020*9880d681SAndroid Build Coastguard Worker  defm storerb: ST_Idxd_shl<"memb", "STrib", IntRegs, 0b000>,
1021*9880d681SAndroid Build Coastguard Worker                ST_Idxd_shl_nv<"memb", "STrib", IntRegs, 0b00>;
1022*9880d681SAndroid Build Coastguard Worker
1023*9880d681SAndroid Build Coastguard Worker  let accessSize = HalfWordAccess in
1024*9880d681SAndroid Build Coastguard Worker  defm storerh: ST_Idxd_shl<"memh", "STrih", IntRegs, 0b010>,
1025*9880d681SAndroid Build Coastguard Worker                ST_Idxd_shl_nv<"memh", "STrih", IntRegs, 0b01>;
1026*9880d681SAndroid Build Coastguard Worker
1027*9880d681SAndroid Build Coastguard Worker  let accessSize = WordAccess in
1028*9880d681SAndroid Build Coastguard Worker  defm storeri: ST_Idxd_shl<"memw", "STriw", IntRegs, 0b100>,
1029*9880d681SAndroid Build Coastguard Worker                ST_Idxd_shl_nv<"memw", "STriw", IntRegs, 0b10>;
1030*9880d681SAndroid Build Coastguard Worker
1031*9880d681SAndroid Build Coastguard Worker  let isNVStorable = 0, accessSize = DoubleWordAccess in
1032*9880d681SAndroid Build Coastguard Worker  defm storerd: ST_Idxd_shl<"memd", "STrid", DoubleRegs, 0b110>;
1033*9880d681SAndroid Build Coastguard Worker
1034*9880d681SAndroid Build Coastguard Worker  let isNVStorable = 0, accessSize = HalfWordAccess in
1035*9880d681SAndroid Build Coastguard Worker  defm storerf: ST_Idxd_shl<"memh", "STrif", IntRegs, 0b011, 1>;
1036*9880d681SAndroid Build Coastguard Worker}
1037*9880d681SAndroid Build Coastguard Worker
1038*9880d681SAndroid Build Coastguard Workerclass Storexs_pat<PatFrag Store, PatFrag Value, InstHexagon MI>
1039*9880d681SAndroid Build Coastguard Worker  : Pat<(Store Value:$Ru, (add (i32 IntRegs:$Rs),
1040*9880d681SAndroid Build Coastguard Worker                               (i32 (shl (i32 IntRegs:$Rt), u2ImmPred:$u2)))),
1041*9880d681SAndroid Build Coastguard Worker        (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2, Value:$Ru)>;
1042*9880d681SAndroid Build Coastguard Worker
1043*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 40 in {
1044*9880d681SAndroid Build Coastguard Worker  def: Storexs_pat<truncstorei8,  I32, S4_storerb_rr>;
1045*9880d681SAndroid Build Coastguard Worker  def: Storexs_pat<truncstorei16, I32, S4_storerh_rr>;
1046*9880d681SAndroid Build Coastguard Worker  def: Storexs_pat<store,         I32, S4_storeri_rr>;
1047*9880d681SAndroid Build Coastguard Worker  def: Storexs_pat<store,         I64, S4_storerd_rr>;
1048*9880d681SAndroid Build Coastguard Worker}
1049*9880d681SAndroid Build Coastguard Worker
1050*9880d681SAndroid Build Coastguard Worker// memd(Rx++#s4:3)=Rtt
1051*9880d681SAndroid Build Coastguard Worker// memd(Rx++#s4:3:circ(Mu))=Rtt
1052*9880d681SAndroid Build Coastguard Worker// memd(Rx++I:circ(Mu))=Rtt
1053*9880d681SAndroid Build Coastguard Worker// memd(Rx++Mu)=Rtt
1054*9880d681SAndroid Build Coastguard Worker// memd(Rx++Mu:brev)=Rtt
1055*9880d681SAndroid Build Coastguard Worker// memd(gp+#u16:3)=Rtt
1056*9880d681SAndroid Build Coastguard Worker
1057*9880d681SAndroid Build Coastguard Worker// Store doubleword conditionally.
1058*9880d681SAndroid Build Coastguard Worker// if ([!]Pv[.new]) memd(#u6)=Rtt
1059*9880d681SAndroid Build Coastguard Worker// TODO: needs to be implemented.
1060*9880d681SAndroid Build Coastguard Worker
1061*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1062*9880d681SAndroid Build Coastguard Worker// Template class
1063*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1064*9880d681SAndroid Build Coastguard Workerlet isPredicable = 1, isExtendable = 1, isExtentSigned = 1, opExtentBits = 8,
1065*9880d681SAndroid Build Coastguard Worker    opExtendable = 2 in
1066*9880d681SAndroid Build Coastguard Workerclass T_StoreImm <string mnemonic, Operand OffsetOp, bits<2> MajOp >
1067*9880d681SAndroid Build Coastguard Worker  : STInst <(outs ), (ins IntRegs:$Rs, OffsetOp:$offset, s8Ext:$S8),
1068*9880d681SAndroid Build Coastguard Worker  mnemonic#"($Rs+#$offset)=#$S8",
1069*9880d681SAndroid Build Coastguard Worker  [], "", V4LDST_tc_st_SLOT01>,
1070*9880d681SAndroid Build Coastguard Worker  ImmRegRel, PredNewRel {
1071*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
1072*9880d681SAndroid Build Coastguard Worker    bits<8> S8;
1073*9880d681SAndroid Build Coastguard Worker    bits<8> offset;
1074*9880d681SAndroid Build Coastguard Worker    bits<6> offsetBits;
1075*9880d681SAndroid Build Coastguard Worker
1076*9880d681SAndroid Build Coastguard Worker    string OffsetOpStr = !cast<string>(OffsetOp);
1077*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(OffsetOpStr, "u6_2Imm"), offset{7-2},
1078*9880d681SAndroid Build Coastguard Worker                     !if (!eq(OffsetOpStr, "u6_1Imm"), offset{6-1},
1079*9880d681SAndroid Build Coastguard Worker                                         /* u6_0Imm */ offset{5-0}));
1080*9880d681SAndroid Build Coastguard Worker
1081*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0011;
1082*9880d681SAndroid Build Coastguard Worker
1083*9880d681SAndroid Build Coastguard Worker    let Inst{27-25} = 0b110;
1084*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = MajOp;
1085*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
1086*9880d681SAndroid Build Coastguard Worker    let Inst{12-7}  = offsetBits;
1087*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = S8{7};
1088*9880d681SAndroid Build Coastguard Worker    let Inst{6-0}   = S8{6-0};
1089*9880d681SAndroid Build Coastguard Worker  }
1090*9880d681SAndroid Build Coastguard Worker
1091*9880d681SAndroid Build Coastguard Workerlet isPredicated = 1, isExtendable = 1, isExtentSigned = 1, opExtentBits = 6,
1092*9880d681SAndroid Build Coastguard Worker    opExtendable = 3 in
1093*9880d681SAndroid Build Coastguard Workerclass T_StoreImm_pred <string mnemonic, Operand OffsetOp, bits<2> MajOp,
1094*9880d681SAndroid Build Coastguard Worker                       bit isPredNot, bit isPredNew >
1095*9880d681SAndroid Build Coastguard Worker  : STInst <(outs ),
1096*9880d681SAndroid Build Coastguard Worker            (ins PredRegs:$Pv, IntRegs:$Rs, OffsetOp:$offset, s6Ext:$S6),
1097*9880d681SAndroid Build Coastguard Worker  !if(isPredNot, "if (!$Pv", "if ($Pv")#!if(isPredNew, ".new) ",
1098*9880d681SAndroid Build Coastguard Worker  ") ")#mnemonic#"($Rs+#$offset)=#$S6",
1099*9880d681SAndroid Build Coastguard Worker  [], "", V4LDST_tc_st_SLOT01>,
1100*9880d681SAndroid Build Coastguard Worker  ImmRegRel, PredNewRel {
1101*9880d681SAndroid Build Coastguard Worker    bits<2> Pv;
1102*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
1103*9880d681SAndroid Build Coastguard Worker    bits<6> S6;
1104*9880d681SAndroid Build Coastguard Worker    bits<8> offset;
1105*9880d681SAndroid Build Coastguard Worker    bits<6> offsetBits;
1106*9880d681SAndroid Build Coastguard Worker
1107*9880d681SAndroid Build Coastguard Worker    string OffsetOpStr = !cast<string>(OffsetOp);
1108*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(OffsetOpStr, "u6_2Imm"), offset{7-2},
1109*9880d681SAndroid Build Coastguard Worker                     !if (!eq(OffsetOpStr, "u6_1Imm"), offset{6-1},
1110*9880d681SAndroid Build Coastguard Worker                                         /* u6_0Imm */ offset{5-0}));
1111*9880d681SAndroid Build Coastguard Worker    let isPredicatedNew = isPredNew;
1112*9880d681SAndroid Build Coastguard Worker    let isPredicatedFalse = isPredNot;
1113*9880d681SAndroid Build Coastguard Worker
1114*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0011;
1115*9880d681SAndroid Build Coastguard Worker
1116*9880d681SAndroid Build Coastguard Worker    let Inst{27-25} = 0b100;
1117*9880d681SAndroid Build Coastguard Worker    let Inst{24}    = isPredNew;
1118*9880d681SAndroid Build Coastguard Worker    let Inst{23}    = isPredNot;
1119*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = MajOp;
1120*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
1121*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = S6{5};
1122*9880d681SAndroid Build Coastguard Worker    let Inst{12-7}  = offsetBits;
1123*9880d681SAndroid Build Coastguard Worker    let Inst{6-5}   = Pv;
1124*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = S6{4-0};
1125*9880d681SAndroid Build Coastguard Worker  }
1126*9880d681SAndroid Build Coastguard Worker
1127*9880d681SAndroid Build Coastguard Worker
1128*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1129*9880d681SAndroid Build Coastguard Worker// multiclass for store instructions with base + immediate offset
1130*9880d681SAndroid Build Coastguard Worker// addressing mode and immediate stored value.
1131*9880d681SAndroid Build Coastguard Worker// mem[bhw](Rx++#s4:3)=#s8
1132*9880d681SAndroid Build Coastguard Worker// if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6
1133*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1134*9880d681SAndroid Build Coastguard Worker
1135*9880d681SAndroid Build Coastguard Workermulticlass ST_Imm_Pred <string mnemonic, Operand OffsetOp, bits<2> MajOp,
1136*9880d681SAndroid Build Coastguard Worker                        bit PredNot> {
1137*9880d681SAndroid Build Coastguard Worker  def _io    : T_StoreImm_pred <mnemonic, OffsetOp, MajOp, PredNot, 0>;
1138*9880d681SAndroid Build Coastguard Worker  // Predicate new
1139*9880d681SAndroid Build Coastguard Worker  def new_io : T_StoreImm_pred <mnemonic, OffsetOp, MajOp, PredNot, 1>;
1140*9880d681SAndroid Build Coastguard Worker}
1141*9880d681SAndroid Build Coastguard Worker
1142*9880d681SAndroid Build Coastguard Workermulticlass ST_Imm <string mnemonic, string CextOp, Operand OffsetOp,
1143*9880d681SAndroid Build Coastguard Worker                   bits<2> MajOp> {
1144*9880d681SAndroid Build Coastguard Worker  let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in {
1145*9880d681SAndroid Build Coastguard Worker    def _io : T_StoreImm <mnemonic, OffsetOp, MajOp>;
1146*9880d681SAndroid Build Coastguard Worker
1147*9880d681SAndroid Build Coastguard Worker    defm t : ST_Imm_Pred <mnemonic, OffsetOp, MajOp, 0>;
1148*9880d681SAndroid Build Coastguard Worker    defm f : ST_Imm_Pred <mnemonic, OffsetOp, MajOp, 1>;
1149*9880d681SAndroid Build Coastguard Worker  }
1150*9880d681SAndroid Build Coastguard Worker}
1151*9880d681SAndroid Build Coastguard Worker
1152*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, addrMode = BaseImmOffset,
1153*9880d681SAndroid Build Coastguard Worker    InputType = "imm" in {
1154*9880d681SAndroid Build Coastguard Worker  let accessSize = ByteAccess in
1155*9880d681SAndroid Build Coastguard Worker  defm S4_storeirb : ST_Imm<"memb", "STrib", u6_0Imm, 0b00>;
1156*9880d681SAndroid Build Coastguard Worker
1157*9880d681SAndroid Build Coastguard Worker  let accessSize = HalfWordAccess in
1158*9880d681SAndroid Build Coastguard Worker  defm S4_storeirh : ST_Imm<"memh", "STrih", u6_1Imm, 0b01>;
1159*9880d681SAndroid Build Coastguard Worker
1160*9880d681SAndroid Build Coastguard Worker  let accessSize = WordAccess in
1161*9880d681SAndroid Build Coastguard Worker  defm S4_storeiri : ST_Imm<"memw", "STriw", u6_2Imm, 0b10>;
1162*9880d681SAndroid Build Coastguard Worker}
1163*9880d681SAndroid Build Coastguard Worker
1164*9880d681SAndroid Build Coastguard Workerdef IMM_BYTE : SDNodeXForm<imm, [{
1165*9880d681SAndroid Build Coastguard Worker  // -1 etc is  represented as 255 etc
1166*9880d681SAndroid Build Coastguard Worker  // assigning to a byte restores our desired signed value.
1167*9880d681SAndroid Build Coastguard Worker  int8_t imm = N->getSExtValue();
1168*9880d681SAndroid Build Coastguard Worker  return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1169*9880d681SAndroid Build Coastguard Worker}]>;
1170*9880d681SAndroid Build Coastguard Worker
1171*9880d681SAndroid Build Coastguard Workerdef IMM_HALF : SDNodeXForm<imm, [{
1172*9880d681SAndroid Build Coastguard Worker  // -1 etc is  represented as 65535 etc
1173*9880d681SAndroid Build Coastguard Worker  // assigning to a short restores our desired signed value.
1174*9880d681SAndroid Build Coastguard Worker  int16_t imm = N->getSExtValue();
1175*9880d681SAndroid Build Coastguard Worker  return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1176*9880d681SAndroid Build Coastguard Worker}]>;
1177*9880d681SAndroid Build Coastguard Worker
1178*9880d681SAndroid Build Coastguard Workerdef IMM_WORD : SDNodeXForm<imm, [{
1179*9880d681SAndroid Build Coastguard Worker  // -1 etc can be represented as 4294967295 etc
1180*9880d681SAndroid Build Coastguard Worker  // Currently, it's not doing this. But some optimization
1181*9880d681SAndroid Build Coastguard Worker  // might convert -1 to a large +ve number.
1182*9880d681SAndroid Build Coastguard Worker  // assigning to a word restores our desired signed value.
1183*9880d681SAndroid Build Coastguard Worker  int32_t imm = N->getSExtValue();
1184*9880d681SAndroid Build Coastguard Worker  return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32);
1185*9880d681SAndroid Build Coastguard Worker}]>;
1186*9880d681SAndroid Build Coastguard Worker
1187*9880d681SAndroid Build Coastguard Workerdef ToImmByte : OutPatFrag<(ops node:$R), (IMM_BYTE $R)>;
1188*9880d681SAndroid Build Coastguard Workerdef ToImmHalf : OutPatFrag<(ops node:$R), (IMM_HALF $R)>;
1189*9880d681SAndroid Build Coastguard Workerdef ToImmWord : OutPatFrag<(ops node:$R), (IMM_WORD $R)>;
1190*9880d681SAndroid Build Coastguard Worker
1191*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 40 in {
1192*9880d681SAndroid Build Coastguard Worker  // Not using frameindex patterns for these stores, because the offset
1193*9880d681SAndroid Build Coastguard Worker  // is not extendable. This could cause problems during removing the frame
1194*9880d681SAndroid Build Coastguard Worker  // indices, since the offset with respect to R29/R30 may not fit in the
1195*9880d681SAndroid Build Coastguard Worker  // u6 field.
1196*9880d681SAndroid Build Coastguard Worker  def: Storexm_add_pat<truncstorei8, s32ImmPred, u6_0ImmPred, ToImmByte,
1197*9880d681SAndroid Build Coastguard Worker                       S4_storeirb_io>;
1198*9880d681SAndroid Build Coastguard Worker  def: Storexm_add_pat<truncstorei16, s32ImmPred, u6_1ImmPred, ToImmHalf,
1199*9880d681SAndroid Build Coastguard Worker                       S4_storeirh_io>;
1200*9880d681SAndroid Build Coastguard Worker  def: Storexm_add_pat<store, s32ImmPred, u6_2ImmPred, ToImmWord,
1201*9880d681SAndroid Build Coastguard Worker                       S4_storeiri_io>;
1202*9880d681SAndroid Build Coastguard Worker}
1203*9880d681SAndroid Build Coastguard Worker
1204*9880d681SAndroid Build Coastguard Workerdef: Storexm_simple_pat<truncstorei8,  s32ImmPred, ToImmByte, S4_storeirb_io>;
1205*9880d681SAndroid Build Coastguard Workerdef: Storexm_simple_pat<truncstorei16, s32ImmPred, ToImmHalf, S4_storeirh_io>;
1206*9880d681SAndroid Build Coastguard Workerdef: Storexm_simple_pat<store,         s32ImmPred, ToImmWord, S4_storeiri_io>;
1207*9880d681SAndroid Build Coastguard Worker
1208*9880d681SAndroid Build Coastguard Worker// memb(Rx++#s4:0:circ(Mu))=Rt
1209*9880d681SAndroid Build Coastguard Worker// memb(Rx++I:circ(Mu))=Rt
1210*9880d681SAndroid Build Coastguard Worker// memb(Rx++Mu)=Rt
1211*9880d681SAndroid Build Coastguard Worker// memb(Rx++Mu:brev)=Rt
1212*9880d681SAndroid Build Coastguard Worker// memb(gp+#u16:0)=Rt
1213*9880d681SAndroid Build Coastguard Worker
1214*9880d681SAndroid Build Coastguard Worker// Store halfword.
1215*9880d681SAndroid Build Coastguard Worker// TODO: needs to be implemented
1216*9880d681SAndroid Build Coastguard Worker// memh(Re=#U6)=Rt.H
1217*9880d681SAndroid Build Coastguard Worker// memh(Rs+#s11:1)=Rt.H
1218*9880d681SAndroid Build Coastguard Worker// memh(Rs+Ru<<#u2)=Rt.H
1219*9880d681SAndroid Build Coastguard Worker// TODO: needs to be implemented.
1220*9880d681SAndroid Build Coastguard Worker
1221*9880d681SAndroid Build Coastguard Worker// memh(Ru<<#u2+#U6)=Rt.H
1222*9880d681SAndroid Build Coastguard Worker// memh(Rx++#s4:1:circ(Mu))=Rt.H
1223*9880d681SAndroid Build Coastguard Worker// memh(Rx++#s4:1:circ(Mu))=Rt
1224*9880d681SAndroid Build Coastguard Worker// memh(Rx++I:circ(Mu))=Rt.H
1225*9880d681SAndroid Build Coastguard Worker// memh(Rx++I:circ(Mu))=Rt
1226*9880d681SAndroid Build Coastguard Worker// memh(Rx++Mu)=Rt.H
1227*9880d681SAndroid Build Coastguard Worker// memh(Rx++Mu)=Rt
1228*9880d681SAndroid Build Coastguard Worker// memh(Rx++Mu:brev)=Rt.H
1229*9880d681SAndroid Build Coastguard Worker// memh(Rx++Mu:brev)=Rt
1230*9880d681SAndroid Build Coastguard Worker// memh(gp+#u16:1)=Rt
1231*9880d681SAndroid Build Coastguard Worker// if ([!]Pv[.new]) memh(#u6)=Rt.H
1232*9880d681SAndroid Build Coastguard Worker// if ([!]Pv[.new]) memh(#u6)=Rt
1233*9880d681SAndroid Build Coastguard Worker
1234*9880d681SAndroid Build Coastguard Worker// if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H
1235*9880d681SAndroid Build Coastguard Worker// TODO: needs to be implemented.
1236*9880d681SAndroid Build Coastguard Worker
1237*9880d681SAndroid Build Coastguard Worker// if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H
1238*9880d681SAndroid Build Coastguard Worker// TODO: Needs to be implemented.
1239*9880d681SAndroid Build Coastguard Worker
1240*9880d681SAndroid Build Coastguard Worker// Store word.
1241*9880d681SAndroid Build Coastguard Worker// memw(Re=#U6)=Rt
1242*9880d681SAndroid Build Coastguard Worker// TODO: Needs to be implemented.
1243*9880d681SAndroid Build Coastguard Worker// memw(Rx++#s4:2)=Rt
1244*9880d681SAndroid Build Coastguard Worker// memw(Rx++#s4:2:circ(Mu))=Rt
1245*9880d681SAndroid Build Coastguard Worker// memw(Rx++I:circ(Mu))=Rt
1246*9880d681SAndroid Build Coastguard Worker// memw(Rx++Mu)=Rt
1247*9880d681SAndroid Build Coastguard Worker// memw(Rx++Mu:brev)=Rt
1248*9880d681SAndroid Build Coastguard Worker
1249*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===
1250*9880d681SAndroid Build Coastguard Worker// ST -
1251*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===
1252*9880d681SAndroid Build Coastguard Worker
1253*9880d681SAndroid Build Coastguard Worker
1254*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1255*9880d681SAndroid Build Coastguard Worker// NV/ST +
1256*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1257*9880d681SAndroid Build Coastguard Worker
1258*9880d681SAndroid Build Coastguard Workerlet opNewValue = 2, opExtendable = 1, isExtentSigned = 1, isPredicable = 1 in
1259*9880d681SAndroid Build Coastguard Workerclass T_store_io_nv <string mnemonic, RegisterClass RC,
1260*9880d681SAndroid Build Coastguard Worker                    Operand ImmOp, bits<2>MajOp>
1261*9880d681SAndroid Build Coastguard Worker  : NVInst_V4 <(outs),
1262*9880d681SAndroid Build Coastguard Worker               (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
1263*9880d681SAndroid Build Coastguard Worker  mnemonic#"($src1+#$src2) = $src3.new",
1264*9880d681SAndroid Build Coastguard Worker  [],"",ST_tc_st_SLOT0> {
1265*9880d681SAndroid Build Coastguard Worker    bits<5> src1;
1266*9880d681SAndroid Build Coastguard Worker    bits<13> src2; // Actual address offset
1267*9880d681SAndroid Build Coastguard Worker    bits<3> src3;
1268*9880d681SAndroid Build Coastguard Worker    bits<11> offsetBits; // Represents offset encoding
1269*9880d681SAndroid Build Coastguard Worker
1270*9880d681SAndroid Build Coastguard Worker    let opExtentBits = !if (!eq(mnemonic, "memb"), 11,
1271*9880d681SAndroid Build Coastguard Worker                       !if (!eq(mnemonic, "memh"), 12,
1272*9880d681SAndroid Build Coastguard Worker                       !if (!eq(mnemonic, "memw"), 13, 0)));
1273*9880d681SAndroid Build Coastguard Worker
1274*9880d681SAndroid Build Coastguard Worker    let opExtentAlign = !if (!eq(mnemonic, "memb"), 0,
1275*9880d681SAndroid Build Coastguard Worker                        !if (!eq(mnemonic, "memh"), 1,
1276*9880d681SAndroid Build Coastguard Worker                        !if (!eq(mnemonic, "memw"), 2, 0)));
1277*9880d681SAndroid Build Coastguard Worker
1278*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(mnemonic, "memb"),  src2{10-0},
1279*9880d681SAndroid Build Coastguard Worker                     !if (!eq(mnemonic, "memh"),  src2{11-1},
1280*9880d681SAndroid Build Coastguard Worker                     !if (!eq(mnemonic, "memw"),  src2{12-2}, 0)));
1281*9880d681SAndroid Build Coastguard Worker
1282*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1010;
1283*9880d681SAndroid Build Coastguard Worker
1284*9880d681SAndroid Build Coastguard Worker    let Inst{27} = 0b0;
1285*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = offsetBits{10-9};
1286*9880d681SAndroid Build Coastguard Worker    let Inst{24-21} = 0b1101;
1287*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src1;
1288*9880d681SAndroid Build Coastguard Worker    let Inst{13} = offsetBits{8};
1289*9880d681SAndroid Build Coastguard Worker    let Inst{12-11} = MajOp;
1290*9880d681SAndroid Build Coastguard Worker    let Inst{10-8} = src3;
1291*9880d681SAndroid Build Coastguard Worker    let Inst{7-0} = offsetBits{7-0};
1292*9880d681SAndroid Build Coastguard Worker  }
1293*9880d681SAndroid Build Coastguard Worker
1294*9880d681SAndroid Build Coastguard Workerlet opExtendable = 2, opNewValue = 3, isPredicated = 1 in
1295*9880d681SAndroid Build Coastguard Workerclass T_pstore_io_nv <string mnemonic, RegisterClass RC, Operand predImmOp,
1296*9880d681SAndroid Build Coastguard Worker                         bits<2>MajOp, bit PredNot, bit isPredNew>
1297*9880d681SAndroid Build Coastguard Worker  : NVInst_V4 <(outs),
1298*9880d681SAndroid Build Coastguard Worker               (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC:$src4),
1299*9880d681SAndroid Build Coastguard Worker  !if(PredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1300*9880d681SAndroid Build Coastguard Worker  ") ")#mnemonic#"($src2+#$src3) = $src4.new",
1301*9880d681SAndroid Build Coastguard Worker  [],"",V2LDST_tc_st_SLOT0> {
1302*9880d681SAndroid Build Coastguard Worker    bits<2> src1;
1303*9880d681SAndroid Build Coastguard Worker    bits<5> src2;
1304*9880d681SAndroid Build Coastguard Worker    bits<9> src3;
1305*9880d681SAndroid Build Coastguard Worker    bits<3> src4;
1306*9880d681SAndroid Build Coastguard Worker    bits<6> offsetBits; // Represents offset encoding
1307*9880d681SAndroid Build Coastguard Worker
1308*9880d681SAndroid Build Coastguard Worker    let isPredicatedNew = isPredNew;
1309*9880d681SAndroid Build Coastguard Worker    let isPredicatedFalse = PredNot;
1310*9880d681SAndroid Build Coastguard Worker    let opExtentBits = !if (!eq(mnemonic, "memb"), 6,
1311*9880d681SAndroid Build Coastguard Worker                       !if (!eq(mnemonic, "memh"), 7,
1312*9880d681SAndroid Build Coastguard Worker                       !if (!eq(mnemonic, "memw"), 8, 0)));
1313*9880d681SAndroid Build Coastguard Worker
1314*9880d681SAndroid Build Coastguard Worker    let opExtentAlign = !if (!eq(mnemonic, "memb"), 0,
1315*9880d681SAndroid Build Coastguard Worker                        !if (!eq(mnemonic, "memh"), 1,
1316*9880d681SAndroid Build Coastguard Worker                        !if (!eq(mnemonic, "memw"), 2, 0)));
1317*9880d681SAndroid Build Coastguard Worker
1318*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(mnemonic, "memb"), src3{5-0},
1319*9880d681SAndroid Build Coastguard Worker                     !if (!eq(mnemonic, "memh"), src3{6-1},
1320*9880d681SAndroid Build Coastguard Worker                     !if (!eq(mnemonic, "memw"), src3{7-2}, 0)));
1321*9880d681SAndroid Build Coastguard Worker
1322*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0100;
1323*9880d681SAndroid Build Coastguard Worker
1324*9880d681SAndroid Build Coastguard Worker    let Inst{27}    = 0b0;
1325*9880d681SAndroid Build Coastguard Worker    let Inst{26}    = PredNot;
1326*9880d681SAndroid Build Coastguard Worker    let Inst{25}    = isPredNew;
1327*9880d681SAndroid Build Coastguard Worker    let Inst{24-21} = 0b0101;
1328*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src2;
1329*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = offsetBits{5};
1330*9880d681SAndroid Build Coastguard Worker    let Inst{12-11} = MajOp;
1331*9880d681SAndroid Build Coastguard Worker    let Inst{10-8}  = src4;
1332*9880d681SAndroid Build Coastguard Worker    let Inst{7-3}   = offsetBits{4-0};
1333*9880d681SAndroid Build Coastguard Worker    let Inst{2}     = 0b0;
1334*9880d681SAndroid Build Coastguard Worker    let Inst{1-0}   = src1;
1335*9880d681SAndroid Build Coastguard Worker  }
1336*9880d681SAndroid Build Coastguard Worker
1337*9880d681SAndroid Build Coastguard Worker// multiclass for new-value store instructions with base + immediate offset.
1338*9880d681SAndroid Build Coastguard Worker//
1339*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, isNVStore = 1, isNewValue = 1, hasSideEffects = 0,
1340*9880d681SAndroid Build Coastguard Worker    isExtendable = 1 in
1341*9880d681SAndroid Build Coastguard Workermulticlass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC,
1342*9880d681SAndroid Build Coastguard Worker                   Operand ImmOp, Operand predImmOp, bits<2> MajOp> {
1343*9880d681SAndroid Build Coastguard Worker
1344*9880d681SAndroid Build Coastguard Worker  let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
1345*9880d681SAndroid Build Coastguard Worker    def S2_#NAME#new_io : T_store_io_nv <mnemonic, RC, ImmOp, MajOp>;
1346*9880d681SAndroid Build Coastguard Worker    // Predicated
1347*9880d681SAndroid Build Coastguard Worker    def S2_p#NAME#newt_io :T_pstore_io_nv <mnemonic, RC, predImmOp, MajOp, 0, 0>;
1348*9880d681SAndroid Build Coastguard Worker    def S2_p#NAME#newf_io :T_pstore_io_nv <mnemonic, RC, predImmOp, MajOp, 1, 0>;
1349*9880d681SAndroid Build Coastguard Worker    // Predicated new
1350*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#newtnew_io :T_pstore_io_nv <mnemonic, RC, predImmOp,
1351*9880d681SAndroid Build Coastguard Worker                                              MajOp, 0, 1>;
1352*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#newfnew_io :T_pstore_io_nv <mnemonic, RC, predImmOp,
1353*9880d681SAndroid Build Coastguard Worker                                              MajOp, 1, 1>;
1354*9880d681SAndroid Build Coastguard Worker  }
1355*9880d681SAndroid Build Coastguard Worker}
1356*9880d681SAndroid Build Coastguard Worker
1357*9880d681SAndroid Build Coastguard Workerlet addrMode = BaseImmOffset, InputType = "imm" in {
1358*9880d681SAndroid Build Coastguard Worker  let accessSize = ByteAccess in
1359*9880d681SAndroid Build Coastguard Worker  defm storerb: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
1360*9880d681SAndroid Build Coastguard Worker                           u6_0Ext, 0b00>, AddrModeRel;
1361*9880d681SAndroid Build Coastguard Worker
1362*9880d681SAndroid Build Coastguard Worker  let accessSize = HalfWordAccess, opExtentAlign = 1 in
1363*9880d681SAndroid Build Coastguard Worker  defm storerh: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
1364*9880d681SAndroid Build Coastguard Worker                           u6_1Ext, 0b01>, AddrModeRel;
1365*9880d681SAndroid Build Coastguard Worker
1366*9880d681SAndroid Build Coastguard Worker  let accessSize = WordAccess, opExtentAlign = 2 in
1367*9880d681SAndroid Build Coastguard Worker  defm storeri: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
1368*9880d681SAndroid Build Coastguard Worker                           u6_2Ext, 0b10>, AddrModeRel;
1369*9880d681SAndroid Build Coastguard Worker}
1370*9880d681SAndroid Build Coastguard Worker
1371*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1372*9880d681SAndroid Build Coastguard Worker// Post increment loads with register offset.
1373*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1374*9880d681SAndroid Build Coastguard Worker
1375*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1 in
1376*9880d681SAndroid Build Coastguard Workerdef L2_loadbsw2_pr : T_load_pr <"membh", IntRegs, 0b0001, HalfWordAccess>;
1377*9880d681SAndroid Build Coastguard Worker
1378*9880d681SAndroid Build Coastguard Workerdef L2_loadbsw4_pr : T_load_pr <"membh", DoubleRegs, 0b0111, WordAccess>;
1379*9880d681SAndroid Build Coastguard Worker
1380*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, addrMode = PostInc in
1381*9880d681SAndroid Build Coastguard Workerclass T_loadalign_pr <string mnemonic, bits<4> MajOp, MemAccessSize AccessSz>
1382*9880d681SAndroid Build Coastguard Worker  : LDInstPI <(outs DoubleRegs:$dst, IntRegs:$_dst_),
1383*9880d681SAndroid Build Coastguard Worker              (ins DoubleRegs:$src1, IntRegs:$src2, ModRegs:$src3),
1384*9880d681SAndroid Build Coastguard Worker  "$dst = "#mnemonic#"($src2++$src3)", [],
1385*9880d681SAndroid Build Coastguard Worker  "$src1 = $dst, $src2 = $_dst_"> {
1386*9880d681SAndroid Build Coastguard Worker    bits<5> dst;
1387*9880d681SAndroid Build Coastguard Worker    bits<5> src2;
1388*9880d681SAndroid Build Coastguard Worker    bits<1> src3;
1389*9880d681SAndroid Build Coastguard Worker
1390*9880d681SAndroid Build Coastguard Worker    let accessSize = AccessSz;
1391*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1001;
1392*9880d681SAndroid Build Coastguard Worker
1393*9880d681SAndroid Build Coastguard Worker    let Inst{27-25} = 0b110;
1394*9880d681SAndroid Build Coastguard Worker    let Inst{24-21} = MajOp;
1395*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src2;
1396*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = src3;
1397*9880d681SAndroid Build Coastguard Worker    let Inst{12}    = 0b0;
1398*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = 0b0;
1399*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = dst;
1400*9880d681SAndroid Build Coastguard Worker  }
1401*9880d681SAndroid Build Coastguard Worker
1402*9880d681SAndroid Build Coastguard Workerdef L2_loadalignb_pr : T_loadalign_pr <"memb_fifo", 0b0100, ByteAccess>;
1403*9880d681SAndroid Build Coastguard Workerdef L2_loadalignh_pr : T_loadalign_pr <"memh_fifo", 0b0010, HalfWordAccess>;
1404*9880d681SAndroid Build Coastguard Worker
1405*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1406*9880d681SAndroid Build Coastguard Worker// Template class for non-predicated post increment .new stores
1407*9880d681SAndroid Build Coastguard Worker// mem[bhwd](Rx++#s4:[0123])=Nt.new
1408*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1409*9880d681SAndroid Build Coastguard Workerlet isPredicable = 1, hasSideEffects = 0, addrMode = PostInc, isNVStore = 1,
1410*9880d681SAndroid Build Coastguard Worker    isNewValue = 1, opNewValue = 3 in
1411*9880d681SAndroid Build Coastguard Workerclass T_StorePI_nv <string mnemonic, Operand ImmOp, bits<2> MajOp >
1412*9880d681SAndroid Build Coastguard Worker  : NVInstPI_V4 <(outs IntRegs:$_dst_),
1413*9880d681SAndroid Build Coastguard Worker                 (ins IntRegs:$src1, ImmOp:$offset, IntRegs:$src2),
1414*9880d681SAndroid Build Coastguard Worker  mnemonic#"($src1++#$offset) = $src2.new",
1415*9880d681SAndroid Build Coastguard Worker  [], "$src1 = $_dst_">,
1416*9880d681SAndroid Build Coastguard Worker  AddrModeRel {
1417*9880d681SAndroid Build Coastguard Worker    bits<5> src1;
1418*9880d681SAndroid Build Coastguard Worker    bits<3> src2;
1419*9880d681SAndroid Build Coastguard Worker    bits<7> offset;
1420*9880d681SAndroid Build Coastguard Worker    bits<4> offsetBits;
1421*9880d681SAndroid Build Coastguard Worker
1422*9880d681SAndroid Build Coastguard Worker    string ImmOpStr = !cast<string>(ImmOp);
1423*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2},
1424*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1},
1425*9880d681SAndroid Build Coastguard Worker                                      /* s4_0Imm */ offset{3-0}));
1426*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1010;
1427*9880d681SAndroid Build Coastguard Worker
1428*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b1011101;
1429*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src1;
1430*9880d681SAndroid Build Coastguard Worker    let Inst{13} = 0b0;
1431*9880d681SAndroid Build Coastguard Worker    let Inst{12-11} = MajOp;
1432*9880d681SAndroid Build Coastguard Worker    let Inst{10-8} = src2;
1433*9880d681SAndroid Build Coastguard Worker    let Inst{7} = 0b0;
1434*9880d681SAndroid Build Coastguard Worker    let Inst{6-3} = offsetBits;
1435*9880d681SAndroid Build Coastguard Worker    let Inst{1} = 0b0;
1436*9880d681SAndroid Build Coastguard Worker  }
1437*9880d681SAndroid Build Coastguard Worker
1438*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1439*9880d681SAndroid Build Coastguard Worker// Template class for predicated post increment .new stores
1440*9880d681SAndroid Build Coastguard Worker// if([!]Pv[.new]) mem[bhwd](Rx++#s4:[0123])=Nt.new
1441*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1442*9880d681SAndroid Build Coastguard Workerlet isPredicated = 1, hasSideEffects = 0, addrMode = PostInc, isNVStore = 1,
1443*9880d681SAndroid Build Coastguard Worker    isNewValue = 1, opNewValue = 4 in
1444*9880d681SAndroid Build Coastguard Workerclass T_StorePI_nv_pred <string mnemonic, Operand ImmOp,
1445*9880d681SAndroid Build Coastguard Worker                         bits<2> MajOp, bit isPredNot, bit isPredNew >
1446*9880d681SAndroid Build Coastguard Worker  : NVInstPI_V4 <(outs IntRegs:$_dst_),
1447*9880d681SAndroid Build Coastguard Worker                 (ins PredRegs:$src1, IntRegs:$src2,
1448*9880d681SAndroid Build Coastguard Worker                      ImmOp:$offset, IntRegs:$src3),
1449*9880d681SAndroid Build Coastguard Worker  !if(isPredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1450*9880d681SAndroid Build Coastguard Worker  ") ")#mnemonic#"($src2++#$offset) = $src3.new",
1451*9880d681SAndroid Build Coastguard Worker  [], "$src2 = $_dst_">,
1452*9880d681SAndroid Build Coastguard Worker  AddrModeRel {
1453*9880d681SAndroid Build Coastguard Worker    bits<2> src1;
1454*9880d681SAndroid Build Coastguard Worker    bits<5> src2;
1455*9880d681SAndroid Build Coastguard Worker    bits<3> src3;
1456*9880d681SAndroid Build Coastguard Worker    bits<7> offset;
1457*9880d681SAndroid Build Coastguard Worker    bits<4> offsetBits;
1458*9880d681SAndroid Build Coastguard Worker
1459*9880d681SAndroid Build Coastguard Worker    string ImmOpStr = !cast<string>(ImmOp);
1460*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2},
1461*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1},
1462*9880d681SAndroid Build Coastguard Worker                                      /* s4_0Imm */ offset{3-0}));
1463*9880d681SAndroid Build Coastguard Worker    let isPredicatedNew = isPredNew;
1464*9880d681SAndroid Build Coastguard Worker    let isPredicatedFalse = isPredNot;
1465*9880d681SAndroid Build Coastguard Worker
1466*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1010;
1467*9880d681SAndroid Build Coastguard Worker
1468*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b1011101;
1469*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src2;
1470*9880d681SAndroid Build Coastguard Worker    let Inst{13} = 0b1;
1471*9880d681SAndroid Build Coastguard Worker    let Inst{12-11} = MajOp;
1472*9880d681SAndroid Build Coastguard Worker    let Inst{10-8} = src3;
1473*9880d681SAndroid Build Coastguard Worker    let Inst{7} = isPredNew;
1474*9880d681SAndroid Build Coastguard Worker    let Inst{6-3} = offsetBits;
1475*9880d681SAndroid Build Coastguard Worker    let Inst{2} = isPredNot;
1476*9880d681SAndroid Build Coastguard Worker    let Inst{1-0} = src1;
1477*9880d681SAndroid Build Coastguard Worker  }
1478*9880d681SAndroid Build Coastguard Worker
1479*9880d681SAndroid Build Coastguard Workermulticlass ST_PostInc_Pred_nv<string mnemonic, Operand ImmOp,
1480*9880d681SAndroid Build Coastguard Worker                              bits<2> MajOp, bit PredNot> {
1481*9880d681SAndroid Build Coastguard Worker  def _pi : T_StorePI_nv_pred <mnemonic, ImmOp, MajOp, PredNot, 0>;
1482*9880d681SAndroid Build Coastguard Worker
1483*9880d681SAndroid Build Coastguard Worker  // Predicate new
1484*9880d681SAndroid Build Coastguard Worker  def new_pi : T_StorePI_nv_pred <mnemonic, ImmOp, MajOp, PredNot, 1>;
1485*9880d681SAndroid Build Coastguard Worker}
1486*9880d681SAndroid Build Coastguard Worker
1487*9880d681SAndroid Build Coastguard Workermulticlass ST_PostInc_nv<string mnemonic, string BaseOp, Operand ImmOp,
1488*9880d681SAndroid Build Coastguard Worker                         bits<2> MajOp> {
1489*9880d681SAndroid Build Coastguard Worker  let BaseOpcode = "POST_"#BaseOp in {
1490*9880d681SAndroid Build Coastguard Worker    def S2_#NAME#_pi : T_StorePI_nv <mnemonic, ImmOp, MajOp>;
1491*9880d681SAndroid Build Coastguard Worker
1492*9880d681SAndroid Build Coastguard Worker    // Predicated
1493*9880d681SAndroid Build Coastguard Worker    defm S2_p#NAME#t : ST_PostInc_Pred_nv <mnemonic, ImmOp, MajOp, 0>;
1494*9880d681SAndroid Build Coastguard Worker    defm S2_p#NAME#f : ST_PostInc_Pred_nv <mnemonic, ImmOp, MajOp, 1>;
1495*9880d681SAndroid Build Coastguard Worker  }
1496*9880d681SAndroid Build Coastguard Worker}
1497*9880d681SAndroid Build Coastguard Worker
1498*9880d681SAndroid Build Coastguard Workerlet accessSize = ByteAccess in
1499*9880d681SAndroid Build Coastguard Workerdefm storerbnew: ST_PostInc_nv <"memb", "STrib", s4_0Imm, 0b00>;
1500*9880d681SAndroid Build Coastguard Worker
1501*9880d681SAndroid Build Coastguard Workerlet accessSize = HalfWordAccess in
1502*9880d681SAndroid Build Coastguard Workerdefm storerhnew: ST_PostInc_nv <"memh", "STrih", s4_1Imm, 0b01>;
1503*9880d681SAndroid Build Coastguard Worker
1504*9880d681SAndroid Build Coastguard Workerlet accessSize = WordAccess in
1505*9880d681SAndroid Build Coastguard Workerdefm storerinew: ST_PostInc_nv <"memw", "STriw", s4_2Imm, 0b10>;
1506*9880d681SAndroid Build Coastguard Worker
1507*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1508*9880d681SAndroid Build Coastguard Worker// Template class for post increment .new stores with register offset
1509*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1510*9880d681SAndroid Build Coastguard Workerlet isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 3 in
1511*9880d681SAndroid Build Coastguard Workerclass T_StorePI_RegNV <string mnemonic, bits<2> MajOp, MemAccessSize AccessSz>
1512*9880d681SAndroid Build Coastguard Worker  : NVInstPI_V4 <(outs IntRegs:$_dst_),
1513*9880d681SAndroid Build Coastguard Worker                 (ins IntRegs:$src1, ModRegs:$src2, IntRegs:$src3),
1514*9880d681SAndroid Build Coastguard Worker  #mnemonic#"($src1++$src2) = $src3.new",
1515*9880d681SAndroid Build Coastguard Worker  [], "$src1 = $_dst_"> {
1516*9880d681SAndroid Build Coastguard Worker    bits<5> src1;
1517*9880d681SAndroid Build Coastguard Worker    bits<1> src2;
1518*9880d681SAndroid Build Coastguard Worker    bits<3> src3;
1519*9880d681SAndroid Build Coastguard Worker    let accessSize = AccessSz;
1520*9880d681SAndroid Build Coastguard Worker
1521*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1010;
1522*9880d681SAndroid Build Coastguard Worker
1523*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b1101101;
1524*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src1;
1525*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = src2;
1526*9880d681SAndroid Build Coastguard Worker    let Inst{12-11} = MajOp;
1527*9880d681SAndroid Build Coastguard Worker    let Inst{10-8}  = src3;
1528*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = 0b0;
1529*9880d681SAndroid Build Coastguard Worker  }
1530*9880d681SAndroid Build Coastguard Worker
1531*9880d681SAndroid Build Coastguard Workerdef S2_storerbnew_pr : T_StorePI_RegNV<"memb", 0b00, ByteAccess>;
1532*9880d681SAndroid Build Coastguard Workerdef S2_storerhnew_pr : T_StorePI_RegNV<"memh", 0b01, HalfWordAccess>;
1533*9880d681SAndroid Build Coastguard Workerdef S2_storerinew_pr : T_StorePI_RegNV<"memw", 0b10, WordAccess>;
1534*9880d681SAndroid Build Coastguard Worker
1535*9880d681SAndroid Build Coastguard Worker// memb(Rx++#s4:0:circ(Mu))=Nt.new
1536*9880d681SAndroid Build Coastguard Worker// memb(Rx++I:circ(Mu))=Nt.new
1537*9880d681SAndroid Build Coastguard Worker// memb(Rx++Mu:brev)=Nt.new
1538*9880d681SAndroid Build Coastguard Worker// memh(Rx++#s4:1:circ(Mu))=Nt.new
1539*9880d681SAndroid Build Coastguard Worker// memh(Rx++I:circ(Mu))=Nt.new
1540*9880d681SAndroid Build Coastguard Worker// memh(Rx++Mu)=Nt.new
1541*9880d681SAndroid Build Coastguard Worker// memh(Rx++Mu:brev)=Nt.new
1542*9880d681SAndroid Build Coastguard Worker
1543*9880d681SAndroid Build Coastguard Worker// memw(Rx++#s4:2:circ(Mu))=Nt.new
1544*9880d681SAndroid Build Coastguard Worker// memw(Rx++I:circ(Mu))=Nt.new
1545*9880d681SAndroid Build Coastguard Worker// memw(Rx++Mu)=Nt.new
1546*9880d681SAndroid Build Coastguard Worker// memw(Rx++Mu:brev)=Nt.new
1547*9880d681SAndroid Build Coastguard Worker
1548*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1549*9880d681SAndroid Build Coastguard Worker// NV/ST -
1550*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1551*9880d681SAndroid Build Coastguard Worker
1552*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1553*9880d681SAndroid Build Coastguard Worker// NV/J +
1554*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1555*9880d681SAndroid Build Coastguard Worker
1556*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1557*9880d681SAndroid Build Coastguard Worker// multiclass/template class for the new-value compare jumps with the register
1558*9880d681SAndroid Build Coastguard Worker// operands.
1559*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1560*9880d681SAndroid Build Coastguard Worker
1561*9880d681SAndroid Build Coastguard Workerlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11,
1562*9880d681SAndroid Build Coastguard Worker    opExtentAlign = 2 in
1563*9880d681SAndroid Build Coastguard Workerclass NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum,
1564*9880d681SAndroid Build Coastguard Worker                      bit isNegCond, bit isTak>
1565*9880d681SAndroid Build Coastguard Worker  : NVInst_V4<(outs),
1566*9880d681SAndroid Build Coastguard Worker    (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1567*9880d681SAndroid Build Coastguard Worker    "if ("#!if(isNegCond, "!","")#mnemonic#
1568*9880d681SAndroid Build Coastguard Worker    "($src1"#!if(!eq(NvOpNum, 0),".new, ",", ")#
1569*9880d681SAndroid Build Coastguard Worker    "$src2"#!if(!eq(NvOpNum, 1),".new))","))")#" jump:"
1570*9880d681SAndroid Build Coastguard Worker    #!if(isTak, "t","nt")#" $offset", []> {
1571*9880d681SAndroid Build Coastguard Worker
1572*9880d681SAndroid Build Coastguard Worker      bits<5> src1;
1573*9880d681SAndroid Build Coastguard Worker      bits<5> src2;
1574*9880d681SAndroid Build Coastguard Worker      bits<3> Ns;    // New-Value Operand
1575*9880d681SAndroid Build Coastguard Worker      bits<5> RegOp; // Non-New-Value Operand
1576*9880d681SAndroid Build Coastguard Worker      bits<11> offset;
1577*9880d681SAndroid Build Coastguard Worker
1578*9880d681SAndroid Build Coastguard Worker      let isTaken = isTak;
1579*9880d681SAndroid Build Coastguard Worker      let isPredicatedFalse = isNegCond;
1580*9880d681SAndroid Build Coastguard Worker      let opNewValue{0} = NvOpNum;
1581*9880d681SAndroid Build Coastguard Worker
1582*9880d681SAndroid Build Coastguard Worker      let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0});
1583*9880d681SAndroid Build Coastguard Worker      let RegOp = !if(!eq(NvOpNum, 0), src2, src1);
1584*9880d681SAndroid Build Coastguard Worker
1585*9880d681SAndroid Build Coastguard Worker      let IClass = 0b0010;
1586*9880d681SAndroid Build Coastguard Worker      let Inst{27-26} = 0b00;
1587*9880d681SAndroid Build Coastguard Worker      let Inst{25-23} = majOp;
1588*9880d681SAndroid Build Coastguard Worker      let Inst{22} = isNegCond;
1589*9880d681SAndroid Build Coastguard Worker      let Inst{18-16} = Ns;
1590*9880d681SAndroid Build Coastguard Worker      let Inst{13} = isTak;
1591*9880d681SAndroid Build Coastguard Worker      let Inst{12-8} = RegOp;
1592*9880d681SAndroid Build Coastguard Worker      let Inst{21-20} = offset{10-9};
1593*9880d681SAndroid Build Coastguard Worker      let Inst{7-1} = offset{8-2};
1594*9880d681SAndroid Build Coastguard Worker}
1595*9880d681SAndroid Build Coastguard Worker
1596*9880d681SAndroid Build Coastguard Worker
1597*9880d681SAndroid Build Coastguard Workermulticlass NVJrr_cond<string mnemonic, bits<3> majOp, bit NvOpNum,
1598*9880d681SAndroid Build Coastguard Worker                       bit isNegCond> {
1599*9880d681SAndroid Build Coastguard Worker  // Branch not taken:
1600*9880d681SAndroid Build Coastguard Worker  def _nt: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 0>;
1601*9880d681SAndroid Build Coastguard Worker  // Branch taken:
1602*9880d681SAndroid Build Coastguard Worker  def _t : NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 1>;
1603*9880d681SAndroid Build Coastguard Worker}
1604*9880d681SAndroid Build Coastguard Worker
1605*9880d681SAndroid Build Coastguard Worker// NvOpNum = 0 -> First Operand is a new-value Register
1606*9880d681SAndroid Build Coastguard Worker// NvOpNum = 1 -> Second Operand is a new-value Register
1607*9880d681SAndroid Build Coastguard Worker
1608*9880d681SAndroid Build Coastguard Workermulticlass NVJrr_base<string mnemonic, string BaseOp, bits<3> majOp,
1609*9880d681SAndroid Build Coastguard Worker                       bit NvOpNum> {
1610*9880d681SAndroid Build Coastguard Worker  let BaseOpcode = BaseOp#_NVJ in {
1611*9880d681SAndroid Build Coastguard Worker    defm _t_jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 0>; // True cond
1612*9880d681SAndroid Build Coastguard Worker    defm _f_jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 1>; // False cond
1613*9880d681SAndroid Build Coastguard Worker  }
1614*9880d681SAndroid Build Coastguard Worker}
1615*9880d681SAndroid Build Coastguard Worker
1616*9880d681SAndroid Build Coastguard Worker// if ([!]cmp.eq(Ns.new,Rt)) jump:[n]t #r9:2
1617*9880d681SAndroid Build Coastguard Worker// if ([!]cmp.gt(Ns.new,Rt)) jump:[n]t #r9:2
1618*9880d681SAndroid Build Coastguard Worker// if ([!]cmp.gtu(Ns.new,Rt)) jump:[n]t #r9:2
1619*9880d681SAndroid Build Coastguard Worker// if ([!]cmp.gt(Rt,Ns.new)) jump:[n]t #r9:2
1620*9880d681SAndroid Build Coastguard Worker// if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2
1621*9880d681SAndroid Build Coastguard Worker
1622*9880d681SAndroid Build Coastguard Workerlet isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
1623*9880d681SAndroid Build Coastguard Worker    Defs = [PC], hasSideEffects = 0 in {
1624*9880d681SAndroid Build Coastguard Worker  defm J4_cmpeq  : NVJrr_base<"cmp.eq",  "CMPEQ",  0b000, 0>, PredRel;
1625*9880d681SAndroid Build Coastguard Worker  defm J4_cmpgt  : NVJrr_base<"cmp.gt",  "CMPGT",  0b001, 0>, PredRel;
1626*9880d681SAndroid Build Coastguard Worker  defm J4_cmpgtu : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel;
1627*9880d681SAndroid Build Coastguard Worker  defm J4_cmplt  : NVJrr_base<"cmp.gt",  "CMPLT",  0b011, 1>, PredRel;
1628*9880d681SAndroid Build Coastguard Worker  defm J4_cmpltu : NVJrr_base<"cmp.gtu", "CMPLTU", 0b100, 1>, PredRel;
1629*9880d681SAndroid Build Coastguard Worker}
1630*9880d681SAndroid Build Coastguard Worker
1631*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1632*9880d681SAndroid Build Coastguard Worker// multiclass/template class for the new-value compare jumps instruction
1633*9880d681SAndroid Build Coastguard Worker// with a register and an unsigned immediate (U5) operand.
1634*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1635*9880d681SAndroid Build Coastguard Worker
1636*9880d681SAndroid Build Coastguard Workerlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11,
1637*9880d681SAndroid Build Coastguard Worker    opExtentAlign = 2 in
1638*9880d681SAndroid Build Coastguard Workerclass NVJri_template<string mnemonic, bits<3> majOp, bit isNegCond,
1639*9880d681SAndroid Build Coastguard Worker                         bit isTak>
1640*9880d681SAndroid Build Coastguard Worker  : NVInst_V4<(outs),
1641*9880d681SAndroid Build Coastguard Worker    (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1642*9880d681SAndroid Build Coastguard Worker    "if ("#!if(isNegCond, "!","")#mnemonic#"($src1.new, #$src2)) jump:"
1643*9880d681SAndroid Build Coastguard Worker    #!if(isTak, "t","nt")#" $offset", []> {
1644*9880d681SAndroid Build Coastguard Worker
1645*9880d681SAndroid Build Coastguard Worker      let isTaken = isTak;
1646*9880d681SAndroid Build Coastguard Worker      let isPredicatedFalse = isNegCond;
1647*9880d681SAndroid Build Coastguard Worker      let isTaken = isTak;
1648*9880d681SAndroid Build Coastguard Worker
1649*9880d681SAndroid Build Coastguard Worker      bits<3> src1;
1650*9880d681SAndroid Build Coastguard Worker      bits<5> src2;
1651*9880d681SAndroid Build Coastguard Worker      bits<11> offset;
1652*9880d681SAndroid Build Coastguard Worker
1653*9880d681SAndroid Build Coastguard Worker      let IClass = 0b0010;
1654*9880d681SAndroid Build Coastguard Worker      let Inst{26} = 0b1;
1655*9880d681SAndroid Build Coastguard Worker      let Inst{25-23} = majOp;
1656*9880d681SAndroid Build Coastguard Worker      let Inst{22} = isNegCond;
1657*9880d681SAndroid Build Coastguard Worker      let Inst{18-16} = src1;
1658*9880d681SAndroid Build Coastguard Worker      let Inst{13} = isTak;
1659*9880d681SAndroid Build Coastguard Worker      let Inst{12-8} = src2;
1660*9880d681SAndroid Build Coastguard Worker      let Inst{21-20} = offset{10-9};
1661*9880d681SAndroid Build Coastguard Worker      let Inst{7-1} = offset{8-2};
1662*9880d681SAndroid Build Coastguard Worker}
1663*9880d681SAndroid Build Coastguard Worker
1664*9880d681SAndroid Build Coastguard Workermulticlass NVJri_cond<string mnemonic, bits<3> majOp, bit isNegCond> {
1665*9880d681SAndroid Build Coastguard Worker  // Branch not taken:
1666*9880d681SAndroid Build Coastguard Worker  def _nt: NVJri_template<mnemonic, majOp, isNegCond, 0>;
1667*9880d681SAndroid Build Coastguard Worker  // Branch taken:
1668*9880d681SAndroid Build Coastguard Worker  def _t : NVJri_template<mnemonic, majOp, isNegCond, 1>;
1669*9880d681SAndroid Build Coastguard Worker}
1670*9880d681SAndroid Build Coastguard Worker
1671*9880d681SAndroid Build Coastguard Workermulticlass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> {
1672*9880d681SAndroid Build Coastguard Worker  let BaseOpcode = BaseOp#_NVJri in {
1673*9880d681SAndroid Build Coastguard Worker    defm _t_jumpnv : NVJri_cond<mnemonic, majOp, 0>; // True Cond
1674*9880d681SAndroid Build Coastguard Worker    defm _f_jumpnv : NVJri_cond<mnemonic, majOp, 1>; // False cond
1675*9880d681SAndroid Build Coastguard Worker  }
1676*9880d681SAndroid Build Coastguard Worker}
1677*9880d681SAndroid Build Coastguard Worker
1678*9880d681SAndroid Build Coastguard Worker// if ([!]cmp.eq(Ns.new,#U5)) jump:[n]t #r9:2
1679*9880d681SAndroid Build Coastguard Worker// if ([!]cmp.gt(Ns.new,#U5)) jump:[n]t #r9:2
1680*9880d681SAndroid Build Coastguard Worker// if ([!]cmp.gtu(Ns.new,#U5)) jump:[n]t #r9:2
1681*9880d681SAndroid Build Coastguard Worker
1682*9880d681SAndroid Build Coastguard Workerlet isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
1683*9880d681SAndroid Build Coastguard Worker    Defs = [PC], hasSideEffects = 0 in {
1684*9880d681SAndroid Build Coastguard Worker  defm J4_cmpeqi  : NVJri_base<"cmp.eq", "CMPEQ", 0b000>, PredRel;
1685*9880d681SAndroid Build Coastguard Worker  defm J4_cmpgti  : NVJri_base<"cmp.gt", "CMPGT", 0b001>, PredRel;
1686*9880d681SAndroid Build Coastguard Worker  defm J4_cmpgtui : NVJri_base<"cmp.gtu", "CMPGTU", 0b010>, PredRel;
1687*9880d681SAndroid Build Coastguard Worker}
1688*9880d681SAndroid Build Coastguard Worker
1689*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1690*9880d681SAndroid Build Coastguard Worker// multiclass/template class for the new-value compare jumps instruction
1691*9880d681SAndroid Build Coastguard Worker// with a register and an hardcoded 0/-1 immediate value.
1692*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1693*9880d681SAndroid Build Coastguard Worker
1694*9880d681SAndroid Build Coastguard Workerlet isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11,
1695*9880d681SAndroid Build Coastguard Worker    opExtentAlign = 2 in
1696*9880d681SAndroid Build Coastguard Workerclass NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal,
1697*9880d681SAndroid Build Coastguard Worker                            bit isNegCond, bit isTak>
1698*9880d681SAndroid Build Coastguard Worker  : NVInst_V4<(outs),
1699*9880d681SAndroid Build Coastguard Worker    (ins IntRegs:$src1, brtarget:$offset),
1700*9880d681SAndroid Build Coastguard Worker    "if ("#!if(isNegCond, "!","")#mnemonic
1701*9880d681SAndroid Build Coastguard Worker    #"($src1.new, #"#ImmVal#")) jump:"
1702*9880d681SAndroid Build Coastguard Worker    #!if(isTak, "t","nt")#" $offset", []> {
1703*9880d681SAndroid Build Coastguard Worker
1704*9880d681SAndroid Build Coastguard Worker      let isTaken = isTak;
1705*9880d681SAndroid Build Coastguard Worker      let isPredicatedFalse = isNegCond;
1706*9880d681SAndroid Build Coastguard Worker      let isTaken = isTak;
1707*9880d681SAndroid Build Coastguard Worker
1708*9880d681SAndroid Build Coastguard Worker      bits<3> src1;
1709*9880d681SAndroid Build Coastguard Worker      bits<11> offset;
1710*9880d681SAndroid Build Coastguard Worker      let IClass = 0b0010;
1711*9880d681SAndroid Build Coastguard Worker      let Inst{26} = 0b1;
1712*9880d681SAndroid Build Coastguard Worker      let Inst{25-23} = majOp;
1713*9880d681SAndroid Build Coastguard Worker      let Inst{22} = isNegCond;
1714*9880d681SAndroid Build Coastguard Worker      let Inst{18-16} = src1;
1715*9880d681SAndroid Build Coastguard Worker      let Inst{13} = isTak;
1716*9880d681SAndroid Build Coastguard Worker      let Inst{21-20} = offset{10-9};
1717*9880d681SAndroid Build Coastguard Worker      let Inst{7-1} = offset{8-2};
1718*9880d681SAndroid Build Coastguard Worker}
1719*9880d681SAndroid Build Coastguard Worker
1720*9880d681SAndroid Build Coastguard Workermulticlass NVJ_ConstImm_cond<string mnemonic, bits<3> majOp, string ImmVal,
1721*9880d681SAndroid Build Coastguard Worker                             bit isNegCond> {
1722*9880d681SAndroid Build Coastguard Worker  // Branch not taken:
1723*9880d681SAndroid Build Coastguard Worker  def _nt: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 0>;
1724*9880d681SAndroid Build Coastguard Worker  // Branch taken:
1725*9880d681SAndroid Build Coastguard Worker  def _t : NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 1>;
1726*9880d681SAndroid Build Coastguard Worker}
1727*9880d681SAndroid Build Coastguard Worker
1728*9880d681SAndroid Build Coastguard Workermulticlass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp,
1729*9880d681SAndroid Build Coastguard Worker                             string ImmVal> {
1730*9880d681SAndroid Build Coastguard Worker  let BaseOpcode = BaseOp#_NVJ_ConstImm in {
1731*9880d681SAndroid Build Coastguard Worker    defm _t_jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True
1732*9880d681SAndroid Build Coastguard Worker    defm _f_jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False
1733*9880d681SAndroid Build Coastguard Worker  }
1734*9880d681SAndroid Build Coastguard Worker}
1735*9880d681SAndroid Build Coastguard Worker
1736*9880d681SAndroid Build Coastguard Worker// if ([!]tstbit(Ns.new,#0)) jump:[n]t #r9:2
1737*9880d681SAndroid Build Coastguard Worker// if ([!]cmp.eq(Ns.new,#-1)) jump:[n]t #r9:2
1738*9880d681SAndroid Build Coastguard Worker// if ([!]cmp.gt(Ns.new,#-1)) jump:[n]t #r9:2
1739*9880d681SAndroid Build Coastguard Worker
1740*9880d681SAndroid Build Coastguard Workerlet isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator=1,
1741*9880d681SAndroid Build Coastguard Worker    Defs = [PC], hasSideEffects = 0 in {
1742*9880d681SAndroid Build Coastguard Worker  defm J4_tstbit0 : NVJ_ConstImm_base<"tstbit", "TSTBIT", 0b011, "0">, PredRel;
1743*9880d681SAndroid Build Coastguard Worker  defm J4_cmpeqn1 : NVJ_ConstImm_base<"cmp.eq", "CMPEQ",  0b100, "-1">, PredRel;
1744*9880d681SAndroid Build Coastguard Worker  defm J4_cmpgtn1 : NVJ_ConstImm_base<"cmp.gt", "CMPGT",  0b101, "-1">, PredRel;
1745*9880d681SAndroid Build Coastguard Worker}
1746*9880d681SAndroid Build Coastguard Worker
1747*9880d681SAndroid Build Coastguard Worker// J4_hintjumpr: Hint indirect conditional jump.
1748*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isIndirectBranch = 1, hasSideEffects = 0 in
1749*9880d681SAndroid Build Coastguard Workerdef J4_hintjumpr: JRInst <
1750*9880d681SAndroid Build Coastguard Worker  (outs),
1751*9880d681SAndroid Build Coastguard Worker  (ins IntRegs:$Rs),
1752*9880d681SAndroid Build Coastguard Worker  "hintjr($Rs)"> {
1753*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
1754*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0101;
1755*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b0010101;
1756*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
1757*9880d681SAndroid Build Coastguard Worker  }
1758*9880d681SAndroid Build Coastguard Worker
1759*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1760*9880d681SAndroid Build Coastguard Worker// NV/J -
1761*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1762*9880d681SAndroid Build Coastguard Worker
1763*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1764*9880d681SAndroid Build Coastguard Worker// CR +
1765*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1766*9880d681SAndroid Build Coastguard Worker
1767*9880d681SAndroid Build Coastguard Worker// PC-relative add
1768*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, isExtendable = 1, opExtendable = 1,
1769*9880d681SAndroid Build Coastguard Worker    isExtentSigned = 0, opExtentBits = 6, hasSideEffects = 0, Uses = [PC] in
1770*9880d681SAndroid Build Coastguard Workerdef C4_addipc : CRInst <(outs IntRegs:$Rd), (ins u6Ext:$u6),
1771*9880d681SAndroid Build Coastguard Worker  "$Rd = add(pc, #$u6)", [], "", CR_tc_2_SLOT3 > {
1772*9880d681SAndroid Build Coastguard Worker    bits<5> Rd;
1773*9880d681SAndroid Build Coastguard Worker    bits<6> u6;
1774*9880d681SAndroid Build Coastguard Worker
1775*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0110;
1776*9880d681SAndroid Build Coastguard Worker    let Inst{27-16} = 0b101001001001;
1777*9880d681SAndroid Build Coastguard Worker    let Inst{12-7} = u6;
1778*9880d681SAndroid Build Coastguard Worker    let Inst{4-0} = Rd;
1779*9880d681SAndroid Build Coastguard Worker  }
1780*9880d681SAndroid Build Coastguard Worker
1781*9880d681SAndroid Build Coastguard Worker
1782*9880d681SAndroid Build Coastguard Worker
1783*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
1784*9880d681SAndroid Build Coastguard Workerclass T_LOGICAL_3OP<string MnOp1, string MnOp2, bits<2> OpBits, bit IsNeg>
1785*9880d681SAndroid Build Coastguard Worker    : CRInst<(outs PredRegs:$Pd),
1786*9880d681SAndroid Build Coastguard Worker             (ins PredRegs:$Ps, PredRegs:$Pt, PredRegs:$Pu),
1787*9880d681SAndroid Build Coastguard Worker             "$Pd = " # MnOp1 # "($Ps, " # MnOp2 # "($Pt, " #
1788*9880d681SAndroid Build Coastguard Worker                   !if (IsNeg,"!","") # "$Pu))",
1789*9880d681SAndroid Build Coastguard Worker             [], "", CR_tc_2early_SLOT23> {
1790*9880d681SAndroid Build Coastguard Worker  bits<2> Pd;
1791*9880d681SAndroid Build Coastguard Worker  bits<2> Ps;
1792*9880d681SAndroid Build Coastguard Worker  bits<2> Pt;
1793*9880d681SAndroid Build Coastguard Worker  bits<2> Pu;
1794*9880d681SAndroid Build Coastguard Worker
1795*9880d681SAndroid Build Coastguard Worker  let IClass = 0b0110;
1796*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b1011;
1797*9880d681SAndroid Build Coastguard Worker  let Inst{23} = IsNeg;
1798*9880d681SAndroid Build Coastguard Worker  let Inst{22-21} = OpBits;
1799*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0b1;
1800*9880d681SAndroid Build Coastguard Worker  let Inst{17-16} = Ps;
1801*9880d681SAndroid Build Coastguard Worker  let Inst{13} = 0b0;
1802*9880d681SAndroid Build Coastguard Worker  let Inst{9-8} = Pt;
1803*9880d681SAndroid Build Coastguard Worker  let Inst{7-6} = Pu;
1804*9880d681SAndroid Build Coastguard Worker  let Inst{1-0} = Pd;
1805*9880d681SAndroid Build Coastguard Worker}
1806*9880d681SAndroid Build Coastguard Worker
1807*9880d681SAndroid Build Coastguard Workerdef C4_and_and  : T_LOGICAL_3OP<"and", "and", 0b00, 0>;
1808*9880d681SAndroid Build Coastguard Workerdef C4_and_or   : T_LOGICAL_3OP<"and", "or",  0b01, 0>;
1809*9880d681SAndroid Build Coastguard Workerdef C4_or_and   : T_LOGICAL_3OP<"or",  "and", 0b10, 0>;
1810*9880d681SAndroid Build Coastguard Workerdef C4_or_or    : T_LOGICAL_3OP<"or",  "or",  0b11, 0>;
1811*9880d681SAndroid Build Coastguard Workerdef C4_and_andn : T_LOGICAL_3OP<"and", "and", 0b00, 1>;
1812*9880d681SAndroid Build Coastguard Workerdef C4_and_orn  : T_LOGICAL_3OP<"and", "or",  0b01, 1>;
1813*9880d681SAndroid Build Coastguard Workerdef C4_or_andn  : T_LOGICAL_3OP<"or",  "and", 0b10, 1>;
1814*9880d681SAndroid Build Coastguard Workerdef C4_or_orn   : T_LOGICAL_3OP<"or",  "or",  0b11, 1>;
1815*9880d681SAndroid Build Coastguard Worker
1816*9880d681SAndroid Build Coastguard Worker// op(Ps, op(Pt, Pu))
1817*9880d681SAndroid Build Coastguard Workerclass LogLog_pat<SDNode Op1, SDNode Op2, InstHexagon MI>
1818*9880d681SAndroid Build Coastguard Worker  : Pat<(i1 (Op1 I1:$Ps, (Op2 I1:$Pt, I1:$Pu))),
1819*9880d681SAndroid Build Coastguard Worker        (MI I1:$Ps, I1:$Pt, I1:$Pu)>;
1820*9880d681SAndroid Build Coastguard Worker
1821*9880d681SAndroid Build Coastguard Worker// op(Ps, op(Pt, ~Pu))
1822*9880d681SAndroid Build Coastguard Workerclass LogLogNot_pat<SDNode Op1, SDNode Op2, InstHexagon MI>
1823*9880d681SAndroid Build Coastguard Worker  : Pat<(i1 (Op1 I1:$Ps, (Op2 I1:$Pt, (not I1:$Pu)))),
1824*9880d681SAndroid Build Coastguard Worker        (MI I1:$Ps, I1:$Pt, I1:$Pu)>;
1825*9880d681SAndroid Build Coastguard Worker
1826*9880d681SAndroid Build Coastguard Workerdef: LogLog_pat<and, and, C4_and_and>;
1827*9880d681SAndroid Build Coastguard Workerdef: LogLog_pat<and, or,  C4_and_or>;
1828*9880d681SAndroid Build Coastguard Workerdef: LogLog_pat<or,  and, C4_or_and>;
1829*9880d681SAndroid Build Coastguard Workerdef: LogLog_pat<or,  or,  C4_or_or>;
1830*9880d681SAndroid Build Coastguard Worker
1831*9880d681SAndroid Build Coastguard Workerdef: LogLogNot_pat<and, and, C4_and_andn>;
1832*9880d681SAndroid Build Coastguard Workerdef: LogLogNot_pat<and, or,  C4_and_orn>;
1833*9880d681SAndroid Build Coastguard Workerdef: LogLogNot_pat<or,  and, C4_or_andn>;
1834*9880d681SAndroid Build Coastguard Workerdef: LogLogNot_pat<or,  or,  C4_or_orn>;
1835*9880d681SAndroid Build Coastguard Worker
1836*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1837*9880d681SAndroid Build Coastguard Worker// PIC: Support for PIC compilations. The patterns and SD nodes defined
1838*9880d681SAndroid Build Coastguard Worker// below are needed to support code generation for PIC
1839*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1840*9880d681SAndroid Build Coastguard Worker
1841*9880d681SAndroid Build Coastguard Workerdef SDT_HexagonAtGot
1842*9880d681SAndroid Build Coastguard Worker  : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32>]>;
1843*9880d681SAndroid Build Coastguard Workerdef SDT_HexagonAtPcrel
1844*9880d681SAndroid Build Coastguard Worker  : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
1845*9880d681SAndroid Build Coastguard Worker
1846*9880d681SAndroid Build Coastguard Worker// AT_GOT address-of-GOT, address-of-global, offset-in-global
1847*9880d681SAndroid Build Coastguard Workerdef HexagonAtGot       : SDNode<"HexagonISD::AT_GOT", SDT_HexagonAtGot>;
1848*9880d681SAndroid Build Coastguard Worker// AT_PCREL address-of-global
1849*9880d681SAndroid Build Coastguard Workerdef HexagonAtPcrel     : SDNode<"HexagonISD::AT_PCREL", SDT_HexagonAtPcrel>;
1850*9880d681SAndroid Build Coastguard Worker
1851*9880d681SAndroid Build Coastguard Workerdef: Pat<(HexagonAtGot I32:$got, I32:$addr, (i32 0)),
1852*9880d681SAndroid Build Coastguard Worker         (L2_loadri_io I32:$got, imm:$addr)>;
1853*9880d681SAndroid Build Coastguard Workerdef: Pat<(HexagonAtGot I32:$got, I32:$addr, s30_2ImmPred:$off),
1854*9880d681SAndroid Build Coastguard Worker         (A2_addi (L2_loadri_io I32:$got, imm:$addr), imm:$off)>;
1855*9880d681SAndroid Build Coastguard Workerdef: Pat<(HexagonAtPcrel I32:$addr),
1856*9880d681SAndroid Build Coastguard Worker         (C4_addipc imm:$addr)>;
1857*9880d681SAndroid Build Coastguard Worker
1858*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1859*9880d681SAndroid Build Coastguard Worker// CR -
1860*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1861*9880d681SAndroid Build Coastguard Worker
1862*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1863*9880d681SAndroid Build Coastguard Worker// XTYPE/ALU +
1864*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1865*9880d681SAndroid Build Coastguard Worker
1866*9880d681SAndroid Build Coastguard Worker// Logical with-not instructions.
1867*9880d681SAndroid Build Coastguard Workerdef A4_andnp : T_ALU64_logical<"and", 0b001, 1, 0, 1>;
1868*9880d681SAndroid Build Coastguard Workerdef A4_ornp  : T_ALU64_logical<"or",  0b011, 1, 0, 1>;
1869*9880d681SAndroid Build Coastguard Worker
1870*9880d681SAndroid Build Coastguard Workerdef: Pat<(i64 (and (i64 DoubleRegs:$Rs), (i64 (not (i64 DoubleRegs:$Rt))))),
1871*9880d681SAndroid Build Coastguard Worker         (A4_andnp DoubleRegs:$Rs, DoubleRegs:$Rt)>;
1872*9880d681SAndroid Build Coastguard Workerdef: Pat<(i64 (or  (i64 DoubleRegs:$Rs), (i64 (not (i64 DoubleRegs:$Rt))))),
1873*9880d681SAndroid Build Coastguard Worker         (A4_ornp DoubleRegs:$Rs, DoubleRegs:$Rt)>;
1874*9880d681SAndroid Build Coastguard Worker
1875*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, hasSideEffects = 0 in
1876*9880d681SAndroid Build Coastguard Workerdef S4_parity: ALU64Inst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt),
1877*9880d681SAndroid Build Coastguard Worker      "$Rd = parity($Rs, $Rt)", [], "", ALU64_tc_2_SLOT23> {
1878*9880d681SAndroid Build Coastguard Worker  bits<5> Rd;
1879*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
1880*9880d681SAndroid Build Coastguard Worker  bits<5> Rt;
1881*9880d681SAndroid Build Coastguard Worker
1882*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1101;
1883*9880d681SAndroid Build Coastguard Worker  let Inst{27-21} = 0b0101111;
1884*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
1885*9880d681SAndroid Build Coastguard Worker  let Inst{12-8} = Rt;
1886*9880d681SAndroid Build Coastguard Worker  let Inst{4-0} = Rd;
1887*9880d681SAndroid Build Coastguard Worker}
1888*9880d681SAndroid Build Coastguard Worker
1889*9880d681SAndroid Build Coastguard Worker//  Add and accumulate.
1890*9880d681SAndroid Build Coastguard Worker//  Rd=add(Rs,add(Ru,#s6))
1891*9880d681SAndroid Build Coastguard Workerlet isExtentSigned = 1, hasNewValue = 1, isExtendable = 1, opExtentBits = 6,
1892*9880d681SAndroid Build Coastguard Worker    opExtendable = 3 in
1893*9880d681SAndroid Build Coastguard Workerdef S4_addaddi : ALU64Inst <(outs IntRegs:$Rd),
1894*9880d681SAndroid Build Coastguard Worker                            (ins IntRegs:$Rs, IntRegs:$Ru, s6Ext:$s6),
1895*9880d681SAndroid Build Coastguard Worker  "$Rd = add($Rs, add($Ru, #$s6))" ,
1896*9880d681SAndroid Build Coastguard Worker  [(set (i32 IntRegs:$Rd), (add (i32 IntRegs:$Rs),
1897*9880d681SAndroid Build Coastguard Worker                           (add (i32 IntRegs:$Ru), s32ImmPred:$s6)))],
1898*9880d681SAndroid Build Coastguard Worker  "", ALU64_tc_2_SLOT23> {
1899*9880d681SAndroid Build Coastguard Worker    bits<5> Rd;
1900*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
1901*9880d681SAndroid Build Coastguard Worker    bits<5> Ru;
1902*9880d681SAndroid Build Coastguard Worker    bits<6> s6;
1903*9880d681SAndroid Build Coastguard Worker
1904*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
1905*9880d681SAndroid Build Coastguard Worker
1906*9880d681SAndroid Build Coastguard Worker    let Inst{27-23} = 0b10110;
1907*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = s6{5-4};
1908*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
1909*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = s6{3};
1910*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rd;
1911*9880d681SAndroid Build Coastguard Worker    let Inst{7-5}   = s6{2-0};
1912*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Ru;
1913*9880d681SAndroid Build Coastguard Worker  }
1914*9880d681SAndroid Build Coastguard Worker
1915*9880d681SAndroid Build Coastguard Workerlet isExtentSigned = 1, hasSideEffects = 0, hasNewValue = 1, isExtendable = 1,
1916*9880d681SAndroid Build Coastguard Worker    opExtentBits = 6, opExtendable = 2 in
1917*9880d681SAndroid Build Coastguard Workerdef S4_subaddi: ALU64Inst <(outs IntRegs:$Rd),
1918*9880d681SAndroid Build Coastguard Worker                           (ins IntRegs:$Rs, s6Ext:$s6, IntRegs:$Ru),
1919*9880d681SAndroid Build Coastguard Worker  "$Rd = add($Rs, sub(#$s6, $Ru))",
1920*9880d681SAndroid Build Coastguard Worker  [], "", ALU64_tc_2_SLOT23> {
1921*9880d681SAndroid Build Coastguard Worker    bits<5> Rd;
1922*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
1923*9880d681SAndroid Build Coastguard Worker    bits<6> s6;
1924*9880d681SAndroid Build Coastguard Worker    bits<5> Ru;
1925*9880d681SAndroid Build Coastguard Worker
1926*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
1927*9880d681SAndroid Build Coastguard Worker
1928*9880d681SAndroid Build Coastguard Worker    let Inst{27-23} = 0b10111;
1929*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = s6{5-4};
1930*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
1931*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = s6{3};
1932*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rd;
1933*9880d681SAndroid Build Coastguard Worker    let Inst{7-5}   = s6{2-0};
1934*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Ru;
1935*9880d681SAndroid Build Coastguard Worker  }
1936*9880d681SAndroid Build Coastguard Worker
1937*9880d681SAndroid Build Coastguard Worker// Rd=add(Rs,sub(#s6,Ru))
1938*9880d681SAndroid Build Coastguard Workerdef: Pat<(add (i32 IntRegs:$src1), (sub s32ImmPred:$src2,
1939*9880d681SAndroid Build Coastguard Worker                                        (i32 IntRegs:$src3))),
1940*9880d681SAndroid Build Coastguard Worker         (S4_subaddi IntRegs:$src1, s32ImmPred:$src2, IntRegs:$src3)>;
1941*9880d681SAndroid Build Coastguard Worker
1942*9880d681SAndroid Build Coastguard Worker// Rd=sub(add(Rs,#s6),Ru)
1943*9880d681SAndroid Build Coastguard Workerdef: Pat<(sub (add (i32 IntRegs:$src1), s32ImmPred:$src2),
1944*9880d681SAndroid Build Coastguard Worker                   (i32 IntRegs:$src3)),
1945*9880d681SAndroid Build Coastguard Worker         (S4_subaddi IntRegs:$src1, s32ImmPred:$src2, IntRegs:$src3)>;
1946*9880d681SAndroid Build Coastguard Worker
1947*9880d681SAndroid Build Coastguard Worker// Rd=add(sub(Rs,Ru),#s6)
1948*9880d681SAndroid Build Coastguard Workerdef: Pat<(add (sub (i32 IntRegs:$src1), (i32 IntRegs:$src3)),
1949*9880d681SAndroid Build Coastguard Worker                   (s32ImmPred:$src2)),
1950*9880d681SAndroid Build Coastguard Worker         (S4_subaddi IntRegs:$src1, s32ImmPred:$src2, IntRegs:$src3)>;
1951*9880d681SAndroid Build Coastguard Worker
1952*9880d681SAndroid Build Coastguard Worker
1953*9880d681SAndroid Build Coastguard Worker//  Add or subtract doublewords with carry.
1954*9880d681SAndroid Build Coastguard Worker//TODO:
1955*9880d681SAndroid Build Coastguard Worker//  Rdd=add(Rss,Rtt,Px):carry
1956*9880d681SAndroid Build Coastguard Worker//TODO:
1957*9880d681SAndroid Build Coastguard Worker//  Rdd=sub(Rss,Rtt,Px):carry
1958*9880d681SAndroid Build Coastguard Worker
1959*9880d681SAndroid Build Coastguard Worker// Extract bitfield
1960*9880d681SAndroid Build Coastguard Worker// Rdd=extract(Rss,#u6,#U6)
1961*9880d681SAndroid Build Coastguard Worker// Rdd=extract(Rss,Rtt)
1962*9880d681SAndroid Build Coastguard Worker// Rd=extract(Rs,Rtt)
1963*9880d681SAndroid Build Coastguard Worker// Rd=extract(Rs,#u5,#U5)
1964*9880d681SAndroid Build Coastguard Worker
1965*9880d681SAndroid Build Coastguard Workerdef S4_extractp_rp : T_S3op_64 < "extract",  0b11, 0b100, 0>;
1966*9880d681SAndroid Build Coastguard Workerdef S4_extractp    : T_S2op_extract <"extract",  0b1010, DoubleRegs, u6Imm>;
1967*9880d681SAndroid Build Coastguard Worker
1968*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1 in {
1969*9880d681SAndroid Build Coastguard Worker  def S4_extract_rp : T_S3op_extract<"extract",  0b01>;
1970*9880d681SAndroid Build Coastguard Worker  def S4_extract    : T_S2op_extract <"extract",  0b1101, IntRegs, u5Imm>;
1971*9880d681SAndroid Build Coastguard Worker}
1972*9880d681SAndroid Build Coastguard Worker
1973*9880d681SAndroid Build Coastguard Worker// Complex add/sub halfwords/words
1974*9880d681SAndroid Build Coastguard Workerlet Defs = [USR_OVF] in {
1975*9880d681SAndroid Build Coastguard Worker  def S4_vxaddsubh : T_S3op_64 < "vxaddsubh", 0b01, 0b100, 0, 1>;
1976*9880d681SAndroid Build Coastguard Worker  def S4_vxaddsubw : T_S3op_64 < "vxaddsubw", 0b01, 0b000, 0, 1>;
1977*9880d681SAndroid Build Coastguard Worker  def S4_vxsubaddh : T_S3op_64 < "vxsubaddh", 0b01, 0b110, 0, 1>;
1978*9880d681SAndroid Build Coastguard Worker  def S4_vxsubaddw : T_S3op_64 < "vxsubaddw", 0b01, 0b010, 0, 1>;
1979*9880d681SAndroid Build Coastguard Worker}
1980*9880d681SAndroid Build Coastguard Worker
1981*9880d681SAndroid Build Coastguard Workerlet Defs = [USR_OVF] in {
1982*9880d681SAndroid Build Coastguard Worker  def S4_vxaddsubhr : T_S3op_64 < "vxaddsubh", 0b11, 0b000, 0, 1, 1, 1>;
1983*9880d681SAndroid Build Coastguard Worker  def S4_vxsubaddhr : T_S3op_64 < "vxsubaddh", 0b11, 0b010, 0, 1, 1, 1>;
1984*9880d681SAndroid Build Coastguard Worker}
1985*9880d681SAndroid Build Coastguard Worker
1986*9880d681SAndroid Build Coastguard Workerlet Itinerary = M_tc_3x_SLOT23, Defs = [USR_OVF] in {
1987*9880d681SAndroid Build Coastguard Worker  def M4_mac_up_s1_sat: T_MType_acc_rr<"+= mpy", 0b011, 0b000, 0, [], 0, 1, 1>;
1988*9880d681SAndroid Build Coastguard Worker  def M4_nac_up_s1_sat: T_MType_acc_rr<"-= mpy", 0b011, 0b001, 0, [], 0, 1, 1>;
1989*9880d681SAndroid Build Coastguard Worker}
1990*9880d681SAndroid Build Coastguard Worker
1991*9880d681SAndroid Build Coastguard Worker// Logical xor with xor accumulation.
1992*9880d681SAndroid Build Coastguard Worker// Rxx^=xor(Rss,Rtt)
1993*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
1994*9880d681SAndroid Build Coastguard Workerdef M4_xor_xacc
1995*9880d681SAndroid Build Coastguard Worker  : SInst <(outs DoubleRegs:$Rxx),
1996*9880d681SAndroid Build Coastguard Worker           (ins DoubleRegs:$dst2, DoubleRegs:$Rss, DoubleRegs:$Rtt),
1997*9880d681SAndroid Build Coastguard Worker  "$Rxx ^= xor($Rss, $Rtt)",
1998*9880d681SAndroid Build Coastguard Worker  [(set (i64 DoubleRegs:$Rxx),
1999*9880d681SAndroid Build Coastguard Worker   (xor (i64 DoubleRegs:$dst2), (xor (i64 DoubleRegs:$Rss),
2000*9880d681SAndroid Build Coastguard Worker                                     (i64 DoubleRegs:$Rtt))))],
2001*9880d681SAndroid Build Coastguard Worker  "$dst2 = $Rxx", S_3op_tc_1_SLOT23> {
2002*9880d681SAndroid Build Coastguard Worker    bits<5> Rxx;
2003*9880d681SAndroid Build Coastguard Worker    bits<5> Rss;
2004*9880d681SAndroid Build Coastguard Worker    bits<5> Rtt;
2005*9880d681SAndroid Build Coastguard Worker
2006*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1100;
2007*9880d681SAndroid Build Coastguard Worker
2008*9880d681SAndroid Build Coastguard Worker    let Inst{27-22} = 0b101010;
2009*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rss;
2010*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rtt;
2011*9880d681SAndroid Build Coastguard Worker    let Inst{7-5}   = 0b000;
2012*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rxx;
2013*9880d681SAndroid Build Coastguard Worker  }
2014*9880d681SAndroid Build Coastguard Worker
2015*9880d681SAndroid Build Coastguard Worker// Rotate and reduce bytes
2016*9880d681SAndroid Build Coastguard Worker// Rdd=vrcrotate(Rss,Rt,#u2)
2017*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
2018*9880d681SAndroid Build Coastguard Workerdef S4_vrcrotate
2019*9880d681SAndroid Build Coastguard Worker  : SInst <(outs DoubleRegs:$Rdd),
2020*9880d681SAndroid Build Coastguard Worker           (ins DoubleRegs:$Rss, IntRegs:$Rt, u2Imm:$u2),
2021*9880d681SAndroid Build Coastguard Worker  "$Rdd = vrcrotate($Rss, $Rt, #$u2)",
2022*9880d681SAndroid Build Coastguard Worker  [], "", S_3op_tc_3x_SLOT23> {
2023*9880d681SAndroid Build Coastguard Worker    bits<5> Rdd;
2024*9880d681SAndroid Build Coastguard Worker    bits<5> Rss;
2025*9880d681SAndroid Build Coastguard Worker    bits<5> Rt;
2026*9880d681SAndroid Build Coastguard Worker    bits<2> u2;
2027*9880d681SAndroid Build Coastguard Worker
2028*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1100;
2029*9880d681SAndroid Build Coastguard Worker
2030*9880d681SAndroid Build Coastguard Worker    let Inst{27-22} = 0b001111;
2031*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rss;
2032*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = u2{1};
2033*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rt;
2034*9880d681SAndroid Build Coastguard Worker    let Inst{7-6}   = 0b11;
2035*9880d681SAndroid Build Coastguard Worker    let Inst{5}     = u2{0};
2036*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rdd;
2037*9880d681SAndroid Build Coastguard Worker  }
2038*9880d681SAndroid Build Coastguard Worker
2039*9880d681SAndroid Build Coastguard Worker// Rotate and reduce bytes with accumulation
2040*9880d681SAndroid Build Coastguard Worker// Rxx+=vrcrotate(Rss,Rt,#u2)
2041*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
2042*9880d681SAndroid Build Coastguard Workerdef S4_vrcrotate_acc
2043*9880d681SAndroid Build Coastguard Worker  : SInst <(outs DoubleRegs:$Rxx),
2044*9880d681SAndroid Build Coastguard Worker           (ins DoubleRegs:$dst2, DoubleRegs:$Rss, IntRegs:$Rt, u2Imm:$u2),
2045*9880d681SAndroid Build Coastguard Worker  "$Rxx += vrcrotate($Rss, $Rt, #$u2)", [],
2046*9880d681SAndroid Build Coastguard Worker  "$dst2 = $Rxx", S_3op_tc_3x_SLOT23> {
2047*9880d681SAndroid Build Coastguard Worker    bits<5> Rxx;
2048*9880d681SAndroid Build Coastguard Worker    bits<5> Rss;
2049*9880d681SAndroid Build Coastguard Worker    bits<5> Rt;
2050*9880d681SAndroid Build Coastguard Worker    bits<2> u2;
2051*9880d681SAndroid Build Coastguard Worker
2052*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1100;
2053*9880d681SAndroid Build Coastguard Worker
2054*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b1011101;
2055*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rss;
2056*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = u2{1};
2057*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rt;
2058*9880d681SAndroid Build Coastguard Worker    let Inst{5}     = u2{0};
2059*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rxx;
2060*9880d681SAndroid Build Coastguard Worker  }
2061*9880d681SAndroid Build Coastguard Worker
2062*9880d681SAndroid Build Coastguard Worker// Vector reduce conditional negate halfwords
2063*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
2064*9880d681SAndroid Build Coastguard Workerdef S2_vrcnegh
2065*9880d681SAndroid Build Coastguard Worker  : SInst <(outs DoubleRegs:$Rxx),
2066*9880d681SAndroid Build Coastguard Worker           (ins DoubleRegs:$dst2, DoubleRegs:$Rss, IntRegs:$Rt),
2067*9880d681SAndroid Build Coastguard Worker  "$Rxx += vrcnegh($Rss, $Rt)", [],
2068*9880d681SAndroid Build Coastguard Worker  "$dst2 = $Rxx", S_3op_tc_3x_SLOT23> {
2069*9880d681SAndroid Build Coastguard Worker    bits<5> Rxx;
2070*9880d681SAndroid Build Coastguard Worker    bits<5> Rss;
2071*9880d681SAndroid Build Coastguard Worker    bits<5> Rt;
2072*9880d681SAndroid Build Coastguard Worker
2073*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1100;
2074*9880d681SAndroid Build Coastguard Worker
2075*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b1011001;
2076*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rss;
2077*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = 0b1;
2078*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rt;
2079*9880d681SAndroid Build Coastguard Worker    let Inst{7-5}   = 0b111;
2080*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rxx;
2081*9880d681SAndroid Build Coastguard Worker  }
2082*9880d681SAndroid Build Coastguard Worker
2083*9880d681SAndroid Build Coastguard Worker// Split bitfield
2084*9880d681SAndroid Build Coastguard Workerdef A4_bitspliti : T_S2op_2_di <"bitsplit", 0b110, 0b100>;
2085*9880d681SAndroid Build Coastguard Worker
2086*9880d681SAndroid Build Coastguard Worker// Arithmetic/Convergent round
2087*9880d681SAndroid Build Coastguard Workerdef A4_cround_ri : T_S2op_2_ii <"cround", 0b111, 0b000>;
2088*9880d681SAndroid Build Coastguard Worker
2089*9880d681SAndroid Build Coastguard Workerdef A4_round_ri  : T_S2op_2_ii <"round", 0b111, 0b100>;
2090*9880d681SAndroid Build Coastguard Worker
2091*9880d681SAndroid Build Coastguard Workerlet Defs = [USR_OVF] in
2092*9880d681SAndroid Build Coastguard Workerdef A4_round_ri_sat : T_S2op_2_ii <"round", 0b111, 0b110, 1>;
2093*9880d681SAndroid Build Coastguard Worker
2094*9880d681SAndroid Build Coastguard Worker// Logical-logical words.
2095*9880d681SAndroid Build Coastguard Worker// Compound or-and -- Rx=or(Ru,and(Rx,#s10))
2096*9880d681SAndroid Build Coastguard Workerlet isExtentSigned = 1, hasNewValue = 1, isExtendable = 1, opExtentBits = 10,
2097*9880d681SAndroid Build Coastguard Worker    opExtendable = 3 in
2098*9880d681SAndroid Build Coastguard Workerdef S4_or_andix:
2099*9880d681SAndroid Build Coastguard Worker  ALU64Inst<(outs IntRegs:$Rx),
2100*9880d681SAndroid Build Coastguard Worker            (ins IntRegs:$Ru, IntRegs:$_src_, s10Ext:$s10),
2101*9880d681SAndroid Build Coastguard Worker  "$Rx = or($Ru, and($_src_, #$s10))" ,
2102*9880d681SAndroid Build Coastguard Worker  [(set (i32 IntRegs:$Rx),
2103*9880d681SAndroid Build Coastguard Worker        (or (i32 IntRegs:$Ru), (and (i32 IntRegs:$_src_), s32ImmPred:$s10)))] ,
2104*9880d681SAndroid Build Coastguard Worker  "$_src_ = $Rx", ALU64_tc_2_SLOT23> {
2105*9880d681SAndroid Build Coastguard Worker    bits<5> Rx;
2106*9880d681SAndroid Build Coastguard Worker    bits<5> Ru;
2107*9880d681SAndroid Build Coastguard Worker    bits<10> s10;
2108*9880d681SAndroid Build Coastguard Worker
2109*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
2110*9880d681SAndroid Build Coastguard Worker
2111*9880d681SAndroid Build Coastguard Worker    let Inst{27-22} = 0b101001;
2112*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rx;
2113*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = s10{9};
2114*9880d681SAndroid Build Coastguard Worker    let Inst{13-5}  = s10{8-0};
2115*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Ru;
2116*9880d681SAndroid Build Coastguard Worker  }
2117*9880d681SAndroid Build Coastguard Worker
2118*9880d681SAndroid Build Coastguard Worker// Miscellaneous ALU64 instructions.
2119*9880d681SAndroid Build Coastguard Worker//
2120*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, hasSideEffects = 0 in
2121*9880d681SAndroid Build Coastguard Workerdef A4_modwrapu: ALU64Inst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt),
2122*9880d681SAndroid Build Coastguard Worker      "$Rd = modwrap($Rs, $Rt)", [], "", ALU64_tc_2_SLOT23> {
2123*9880d681SAndroid Build Coastguard Worker  bits<5> Rd;
2124*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
2125*9880d681SAndroid Build Coastguard Worker  bits<5> Rt;
2126*9880d681SAndroid Build Coastguard Worker
2127*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1101;
2128*9880d681SAndroid Build Coastguard Worker  let Inst{27-21} = 0b0011111;
2129*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
2130*9880d681SAndroid Build Coastguard Worker  let Inst{12-8} = Rt;
2131*9880d681SAndroid Build Coastguard Worker  let Inst{7-5} = 0b111;
2132*9880d681SAndroid Build Coastguard Worker  let Inst{4-0} = Rd;
2133*9880d681SAndroid Build Coastguard Worker}
2134*9880d681SAndroid Build Coastguard Worker
2135*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
2136*9880d681SAndroid Build Coastguard Workerdef A4_bitsplit: ALU64Inst<(outs DoubleRegs:$Rd),
2137*9880d681SAndroid Build Coastguard Worker      (ins IntRegs:$Rs, IntRegs:$Rt),
2138*9880d681SAndroid Build Coastguard Worker      "$Rd = bitsplit($Rs, $Rt)", [], "", ALU64_tc_1_SLOT23> {
2139*9880d681SAndroid Build Coastguard Worker  bits<5> Rd;
2140*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
2141*9880d681SAndroid Build Coastguard Worker  bits<5> Rt;
2142*9880d681SAndroid Build Coastguard Worker
2143*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1101;
2144*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b0100;
2145*9880d681SAndroid Build Coastguard Worker  let Inst{21} = 0b1;
2146*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
2147*9880d681SAndroid Build Coastguard Worker  let Inst{12-8} = Rt;
2148*9880d681SAndroid Build Coastguard Worker  let Inst{4-0} = Rd;
2149*9880d681SAndroid Build Coastguard Worker}
2150*9880d681SAndroid Build Coastguard Worker
2151*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
2152*9880d681SAndroid Build Coastguard Workerdef dep_S2_packhl: ALU64Inst<(outs DoubleRegs:$Rd),
2153*9880d681SAndroid Build Coastguard Worker      (ins IntRegs:$Rs, IntRegs:$Rt),
2154*9880d681SAndroid Build Coastguard Worker      "$Rd = packhl($Rs, $Rt):deprecated", [], "", ALU64_tc_1_SLOT23> {
2155*9880d681SAndroid Build Coastguard Worker  bits<5> Rd;
2156*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
2157*9880d681SAndroid Build Coastguard Worker  bits<5> Rt;
2158*9880d681SAndroid Build Coastguard Worker
2159*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1101;
2160*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b0100;
2161*9880d681SAndroid Build Coastguard Worker  let Inst{21} = 0b0;
2162*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
2163*9880d681SAndroid Build Coastguard Worker  let Inst{12-8} = Rt;
2164*9880d681SAndroid Build Coastguard Worker  let Inst{4-0} = Rd;
2165*9880d681SAndroid Build Coastguard Worker}
2166*9880d681SAndroid Build Coastguard Worker
2167*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, hasSideEffects = 0 in
2168*9880d681SAndroid Build Coastguard Workerdef dep_A2_addsat: ALU64Inst<(outs IntRegs:$Rd),
2169*9880d681SAndroid Build Coastguard Worker      (ins IntRegs:$Rs, IntRegs:$Rt),
2170*9880d681SAndroid Build Coastguard Worker      "$Rd = add($Rs, $Rt):sat:deprecated", [], "", ALU64_tc_2_SLOT23> {
2171*9880d681SAndroid Build Coastguard Worker  bits<5> Rd;
2172*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
2173*9880d681SAndroid Build Coastguard Worker  bits<5> Rt;
2174*9880d681SAndroid Build Coastguard Worker
2175*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1101;
2176*9880d681SAndroid Build Coastguard Worker  let Inst{27-21} = 0b0101100;
2177*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
2178*9880d681SAndroid Build Coastguard Worker  let Inst{12-8} = Rt;
2179*9880d681SAndroid Build Coastguard Worker  let Inst{7} = 0b0;
2180*9880d681SAndroid Build Coastguard Worker  let Inst{4-0} = Rd;
2181*9880d681SAndroid Build Coastguard Worker}
2182*9880d681SAndroid Build Coastguard Worker
2183*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, hasSideEffects = 0 in
2184*9880d681SAndroid Build Coastguard Workerdef dep_A2_subsat: ALU64Inst<(outs IntRegs:$Rd),
2185*9880d681SAndroid Build Coastguard Worker      (ins IntRegs:$Rs, IntRegs:$Rt),
2186*9880d681SAndroid Build Coastguard Worker      "$Rd = sub($Rs, $Rt):sat:deprecated", [], "", ALU64_tc_2_SLOT23> {
2187*9880d681SAndroid Build Coastguard Worker  bits<5> Rd;
2188*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
2189*9880d681SAndroid Build Coastguard Worker  bits<5> Rt;
2190*9880d681SAndroid Build Coastguard Worker
2191*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1101;
2192*9880d681SAndroid Build Coastguard Worker  let Inst{27-21} = 0b0101100;
2193*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rt;
2194*9880d681SAndroid Build Coastguard Worker  let Inst{12-8} = Rs;
2195*9880d681SAndroid Build Coastguard Worker  let Inst{7} = 0b1;
2196*9880d681SAndroid Build Coastguard Worker  let Inst{4-0} = Rd;
2197*9880d681SAndroid Build Coastguard Worker}
2198*9880d681SAndroid Build Coastguard Worker
2199*9880d681SAndroid Build Coastguard Worker// Rx[&|]=xor(Rs,Rt)
2200*9880d681SAndroid Build Coastguard Workerdef M4_or_xor   : T_MType_acc_rr < "|= xor", 0b110, 0b001, 0>;
2201*9880d681SAndroid Build Coastguard Workerdef M4_and_xor  : T_MType_acc_rr < "&= xor", 0b010, 0b010, 0>;
2202*9880d681SAndroid Build Coastguard Worker
2203*9880d681SAndroid Build Coastguard Worker// Rx[&|^]=or(Rs,Rt)
2204*9880d681SAndroid Build Coastguard Workerdef M4_xor_or   : T_MType_acc_rr < "^= or",  0b110, 0b011, 0>;
2205*9880d681SAndroid Build Coastguard Worker
2206*9880d681SAndroid Build Coastguard Workerlet CextOpcode = "ORr_ORr" in
2207*9880d681SAndroid Build Coastguard Workerdef M4_or_or    : T_MType_acc_rr < "|= or",  0b110, 0b000, 0>;
2208*9880d681SAndroid Build Coastguard Workerdef M4_and_or   : T_MType_acc_rr < "&= or",  0b010, 0b001, 0>;
2209*9880d681SAndroid Build Coastguard Worker
2210*9880d681SAndroid Build Coastguard Worker// Rx[&|^]=and(Rs,Rt)
2211*9880d681SAndroid Build Coastguard Workerdef M4_xor_and  : T_MType_acc_rr < "^= and", 0b110, 0b010, 0>;
2212*9880d681SAndroid Build Coastguard Worker
2213*9880d681SAndroid Build Coastguard Workerlet CextOpcode = "ORr_ANDr" in
2214*9880d681SAndroid Build Coastguard Workerdef M4_or_and   : T_MType_acc_rr < "|= and", 0b010, 0b011, 0>;
2215*9880d681SAndroid Build Coastguard Workerdef M4_and_and  : T_MType_acc_rr < "&= and", 0b010, 0b000, 0>;
2216*9880d681SAndroid Build Coastguard Worker
2217*9880d681SAndroid Build Coastguard Worker// Rx[&|^]=and(Rs,~Rt)
2218*9880d681SAndroid Build Coastguard Workerdef M4_xor_andn : T_MType_acc_rr < "^= and", 0b001, 0b010, 0, [], 1>;
2219*9880d681SAndroid Build Coastguard Workerdef M4_or_andn  : T_MType_acc_rr < "|= and", 0b001, 0b000, 0, [], 1>;
2220*9880d681SAndroid Build Coastguard Workerdef M4_and_andn : T_MType_acc_rr < "&= and", 0b001, 0b001, 0, [], 1>;
2221*9880d681SAndroid Build Coastguard Worker
2222*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat2 <M4_or_xor, xor, or>;
2223*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat2 <M4_and_xor, xor, and>;
2224*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat2 <M4_or_and, and, or>;
2225*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat2 <M4_and_and, and, and>;
2226*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat2 <M4_xor_and, and, xor>;
2227*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat2 <M4_or_or, or, or>;
2228*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat2 <M4_and_or, or, and>;
2229*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat2 <M4_xor_or, or, xor>;
2230*9880d681SAndroid Build Coastguard Worker
2231*9880d681SAndroid Build Coastguard Workerclass T_MType_acc_pat3 <InstHexagon MI, SDNode firstOp, SDNode secOp>
2232*9880d681SAndroid Build Coastguard Worker  : Pat <(i32 (secOp IntRegs:$src1, (firstOp IntRegs:$src2,
2233*9880d681SAndroid Build Coastguard Worker                                              (not IntRegs:$src3)))),
2234*9880d681SAndroid Build Coastguard Worker         (i32 (MI IntRegs:$src1, IntRegs:$src2, IntRegs:$src3))>;
2235*9880d681SAndroid Build Coastguard Worker
2236*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat3 <M4_or_andn, and, or>;
2237*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat3 <M4_and_andn, and, and>;
2238*9880d681SAndroid Build Coastguard Workerdef: T_MType_acc_pat3 <M4_xor_andn, and, xor>;
2239*9880d681SAndroid Build Coastguard Worker
2240*9880d681SAndroid Build Coastguard Worker// Compound or-or and or-and
2241*9880d681SAndroid Build Coastguard Workerlet isExtentSigned = 1, InputType = "imm", hasNewValue = 1, isExtendable = 1,
2242*9880d681SAndroid Build Coastguard Worker    opExtentBits = 10, opExtendable = 3 in
2243*9880d681SAndroid Build Coastguard Workerclass T_CompOR <string mnemonic, bits<2> MajOp, SDNode OpNode>
2244*9880d681SAndroid Build Coastguard Worker  : MInst_acc <(outs IntRegs:$Rx),
2245*9880d681SAndroid Build Coastguard Worker               (ins IntRegs:$src1, IntRegs:$Rs, s10Ext:$s10),
2246*9880d681SAndroid Build Coastguard Worker  "$Rx |= "#mnemonic#"($Rs, #$s10)",
2247*9880d681SAndroid Build Coastguard Worker  [(set (i32 IntRegs:$Rx), (or (i32 IntRegs:$src1),
2248*9880d681SAndroid Build Coastguard Worker                           (OpNode (i32 IntRegs:$Rs), s32ImmPred:$s10)))],
2249*9880d681SAndroid Build Coastguard Worker  "$src1 = $Rx", ALU64_tc_2_SLOT23>, ImmRegRel {
2250*9880d681SAndroid Build Coastguard Worker    bits<5> Rx;
2251*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
2252*9880d681SAndroid Build Coastguard Worker    bits<10> s10;
2253*9880d681SAndroid Build Coastguard Worker
2254*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
2255*9880d681SAndroid Build Coastguard Worker
2256*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1010;
2257*9880d681SAndroid Build Coastguard Worker    let Inst{23-22} = MajOp;
2258*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
2259*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = s10{9};
2260*9880d681SAndroid Build Coastguard Worker    let Inst{13-5}  = s10{8-0};
2261*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rx;
2262*9880d681SAndroid Build Coastguard Worker  }
2263*9880d681SAndroid Build Coastguard Worker
2264*9880d681SAndroid Build Coastguard Workerlet CextOpcode = "ORr_ANDr" in
2265*9880d681SAndroid Build Coastguard Workerdef S4_or_andi : T_CompOR <"and", 0b00, and>;
2266*9880d681SAndroid Build Coastguard Worker
2267*9880d681SAndroid Build Coastguard Workerlet CextOpcode = "ORr_ORr" in
2268*9880d681SAndroid Build Coastguard Workerdef S4_or_ori : T_CompOR <"or", 0b10, or>;
2269*9880d681SAndroid Build Coastguard Worker
2270*9880d681SAndroid Build Coastguard Worker//    Modulo wrap
2271*9880d681SAndroid Build Coastguard Worker//        Rd=modwrap(Rs,Rt)
2272*9880d681SAndroid Build Coastguard Worker//    Round
2273*9880d681SAndroid Build Coastguard Worker//        Rd=cround(Rs,#u5)
2274*9880d681SAndroid Build Coastguard Worker//        Rd=cround(Rs,Rt)
2275*9880d681SAndroid Build Coastguard Worker//        Rd=round(Rs,#u5)[:sat]
2276*9880d681SAndroid Build Coastguard Worker//        Rd=round(Rs,Rt)[:sat]
2277*9880d681SAndroid Build Coastguard Worker//    Vector reduce add unsigned halfwords
2278*9880d681SAndroid Build Coastguard Worker//        Rd=vraddh(Rss,Rtt)
2279*9880d681SAndroid Build Coastguard Worker//    Vector add bytes
2280*9880d681SAndroid Build Coastguard Worker//        Rdd=vaddb(Rss,Rtt)
2281*9880d681SAndroid Build Coastguard Worker//    Vector conditional negate
2282*9880d681SAndroid Build Coastguard Worker//        Rdd=vcnegh(Rss,Rt)
2283*9880d681SAndroid Build Coastguard Worker//        Rxx+=vrcnegh(Rss,Rt)
2284*9880d681SAndroid Build Coastguard Worker//    Vector maximum bytes
2285*9880d681SAndroid Build Coastguard Worker//        Rdd=vmaxb(Rtt,Rss)
2286*9880d681SAndroid Build Coastguard Worker//    Vector reduce maximum halfwords
2287*9880d681SAndroid Build Coastguard Worker//        Rxx=vrmaxh(Rss,Ru)
2288*9880d681SAndroid Build Coastguard Worker//        Rxx=vrmaxuh(Rss,Ru)
2289*9880d681SAndroid Build Coastguard Worker//    Vector reduce maximum words
2290*9880d681SAndroid Build Coastguard Worker//        Rxx=vrmaxuw(Rss,Ru)
2291*9880d681SAndroid Build Coastguard Worker//        Rxx=vrmaxw(Rss,Ru)
2292*9880d681SAndroid Build Coastguard Worker//    Vector minimum bytes
2293*9880d681SAndroid Build Coastguard Worker//        Rdd=vminb(Rtt,Rss)
2294*9880d681SAndroid Build Coastguard Worker//    Vector reduce minimum halfwords
2295*9880d681SAndroid Build Coastguard Worker//        Rxx=vrminh(Rss,Ru)
2296*9880d681SAndroid Build Coastguard Worker//        Rxx=vrminuh(Rss,Ru)
2297*9880d681SAndroid Build Coastguard Worker//    Vector reduce minimum words
2298*9880d681SAndroid Build Coastguard Worker//        Rxx=vrminuw(Rss,Ru)
2299*9880d681SAndroid Build Coastguard Worker//        Rxx=vrminw(Rss,Ru)
2300*9880d681SAndroid Build Coastguard Worker//    Vector subtract bytes
2301*9880d681SAndroid Build Coastguard Worker//        Rdd=vsubb(Rss,Rtt)
2302*9880d681SAndroid Build Coastguard Worker
2303*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2304*9880d681SAndroid Build Coastguard Worker// XTYPE/ALU -
2305*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2306*9880d681SAndroid Build Coastguard Worker
2307*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2308*9880d681SAndroid Build Coastguard Worker// XTYPE/BIT +
2309*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2310*9880d681SAndroid Build Coastguard Worker
2311*9880d681SAndroid Build Coastguard Worker// Bit reverse
2312*9880d681SAndroid Build Coastguard Workerdef S2_brevp : T_S2op_3 <"brev", 0b11, 0b110>;
2313*9880d681SAndroid Build Coastguard Worker
2314*9880d681SAndroid Build Coastguard Worker// Bit count
2315*9880d681SAndroid Build Coastguard Workerdef S2_ct0p : T_COUNT_LEADING_64<"ct0", 0b111, 0b010>;
2316*9880d681SAndroid Build Coastguard Workerdef S2_ct1p : T_COUNT_LEADING_64<"ct1", 0b111, 0b100>;
2317*9880d681SAndroid Build Coastguard Workerdef S4_clbpnorm : T_COUNT_LEADING_64<"normamt", 0b011, 0b000>;
2318*9880d681SAndroid Build Coastguard Worker
2319*9880d681SAndroid Build Coastguard Worker// Count trailing zeros: 64-bit.
2320*9880d681SAndroid Build Coastguard Workerdef: Pat<(i32 (trunc (cttz I64:$Rss))), (S2_ct0p I64:$Rss)>;
2321*9880d681SAndroid Build Coastguard Worker
2322*9880d681SAndroid Build Coastguard Worker// Count trailing ones: 64-bit.
2323*9880d681SAndroid Build Coastguard Workerdef: Pat<(i32 (trunc (cttz (not I64:$Rss)))), (S2_ct1p I64:$Rss)>;
2324*9880d681SAndroid Build Coastguard Worker
2325*9880d681SAndroid Build Coastguard Worker// Define leading/trailing patterns that require zero-extensions to 64 bits.
2326*9880d681SAndroid Build Coastguard Workerdef: Pat<(i64 (ctlz I64:$Rss)), (Zext64 (S2_cl0p I64:$Rss))>;
2327*9880d681SAndroid Build Coastguard Workerdef: Pat<(i64 (cttz I64:$Rss)), (Zext64 (S2_ct0p I64:$Rss))>;
2328*9880d681SAndroid Build Coastguard Workerdef: Pat<(i64 (ctlz (not I64:$Rss))), (Zext64 (S2_cl1p I64:$Rss))>;
2329*9880d681SAndroid Build Coastguard Workerdef: Pat<(i64 (cttz (not I64:$Rss))), (Zext64 (S2_ct1p I64:$Rss))>;
2330*9880d681SAndroid Build Coastguard Worker
2331*9880d681SAndroid Build Coastguard Worker
2332*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, hasNewValue = 1 in
2333*9880d681SAndroid Build Coastguard Workerdef S4_clbaddi : SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, s6Imm:$s6),
2334*9880d681SAndroid Build Coastguard Worker    "$Rd = add(clb($Rs), #$s6)", [], "", S_2op_tc_2_SLOT23> {
2335*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
2336*9880d681SAndroid Build Coastguard Worker  bits<5> Rd;
2337*9880d681SAndroid Build Coastguard Worker  bits<6> s6;
2338*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1000;
2339*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b1100;
2340*9880d681SAndroid Build Coastguard Worker  let Inst{23-21} = 0b001;
2341*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
2342*9880d681SAndroid Build Coastguard Worker  let Inst{13-8} = s6;
2343*9880d681SAndroid Build Coastguard Worker  let Inst{7-5} = 0b000;
2344*9880d681SAndroid Build Coastguard Worker  let Inst{4-0} = Rd;
2345*9880d681SAndroid Build Coastguard Worker}
2346*9880d681SAndroid Build Coastguard Worker
2347*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, hasNewValue = 1 in
2348*9880d681SAndroid Build Coastguard Workerdef S4_clbpaddi : SInst<(outs IntRegs:$Rd), (ins DoubleRegs:$Rs, s6Imm:$s6),
2349*9880d681SAndroid Build Coastguard Worker    "$Rd = add(clb($Rs), #$s6)", [], "", S_2op_tc_2_SLOT23> {
2350*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
2351*9880d681SAndroid Build Coastguard Worker  bits<5> Rd;
2352*9880d681SAndroid Build Coastguard Worker  bits<6> s6;
2353*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1000;
2354*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b1000;
2355*9880d681SAndroid Build Coastguard Worker  let Inst{23-21} = 0b011;
2356*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
2357*9880d681SAndroid Build Coastguard Worker  let Inst{13-8} = s6;
2358*9880d681SAndroid Build Coastguard Worker  let Inst{7-5} = 0b010;
2359*9880d681SAndroid Build Coastguard Worker  let Inst{4-0} = Rd;
2360*9880d681SAndroid Build Coastguard Worker}
2361*9880d681SAndroid Build Coastguard Worker
2362*9880d681SAndroid Build Coastguard Worker
2363*9880d681SAndroid Build Coastguard Worker// Bit test/set/clear
2364*9880d681SAndroid Build Coastguard Workerdef S4_ntstbit_i : T_TEST_BIT_IMM<"!tstbit", 0b001>;
2365*9880d681SAndroid Build Coastguard Workerdef S4_ntstbit_r : T_TEST_BIT_REG<"!tstbit", 1>;
2366*9880d681SAndroid Build Coastguard Worker
2367*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 20 in {   // Complexity greater than cmp reg-imm.
2368*9880d681SAndroid Build Coastguard Worker  def: Pat<(i1 (seteq (and (shl 1, u5ImmPred:$u5), (i32 IntRegs:$Rs)), 0)),
2369*9880d681SAndroid Build Coastguard Worker           (S4_ntstbit_i (i32 IntRegs:$Rs), u5ImmPred:$u5)>;
2370*9880d681SAndroid Build Coastguard Worker  def: Pat<(i1 (seteq (and (shl 1, (i32 IntRegs:$Rt)), (i32 IntRegs:$Rs)), 0)),
2371*9880d681SAndroid Build Coastguard Worker           (S4_ntstbit_r (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))>;
2372*9880d681SAndroid Build Coastguard Worker}
2373*9880d681SAndroid Build Coastguard Worker
2374*9880d681SAndroid Build Coastguard Worker// Add extra complexity to prefer these instructions over bitsset/bitsclr.
2375*9880d681SAndroid Build Coastguard Worker// The reason is that tstbit/ntstbit can be folded into a compound instruction:
2376*9880d681SAndroid Build Coastguard Worker//   if ([!]tstbit(...)) jump ...
2377*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in
2378*9880d681SAndroid Build Coastguard Workerdef: Pat<(i1 (setne (and (i32 IntRegs:$Rs), (i32 Set5ImmPred:$u5)), (i32 0))),
2379*9880d681SAndroid Build Coastguard Worker         (S2_tstbit_i (i32 IntRegs:$Rs), (BITPOS32 Set5ImmPred:$u5))>;
2380*9880d681SAndroid Build Coastguard Worker
2381*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in
2382*9880d681SAndroid Build Coastguard Workerdef: Pat<(i1 (seteq (and (i32 IntRegs:$Rs), (i32 Set5ImmPred:$u5)), (i32 0))),
2383*9880d681SAndroid Build Coastguard Worker         (S4_ntstbit_i (i32 IntRegs:$Rs), (BITPOS32 Set5ImmPred:$u5))>;
2384*9880d681SAndroid Build Coastguard Worker
2385*9880d681SAndroid Build Coastguard Workerdef C4_nbitsset  : T_TEST_BITS_REG<"!bitsset", 0b01, 1>;
2386*9880d681SAndroid Build Coastguard Workerdef C4_nbitsclr  : T_TEST_BITS_REG<"!bitsclr", 0b10, 1>;
2387*9880d681SAndroid Build Coastguard Workerdef C4_nbitsclri : T_TEST_BITS_IMM<"!bitsclr", 0b10, 1>;
2388*9880d681SAndroid Build Coastguard Worker
2389*9880d681SAndroid Build Coastguard Worker// Do not increase complexity of these patterns. In the DAG, "cmp i8" may be
2390*9880d681SAndroid Build Coastguard Worker// represented as a compare against "value & 0xFF", which is an exact match
2391*9880d681SAndroid Build Coastguard Worker// for cmpb (same for cmph). The patterns below do not contain any additional
2392*9880d681SAndroid Build Coastguard Worker// complexity that would make them preferable, and if they were actually used
2393*9880d681SAndroid Build Coastguard Worker// instead of cmpb/cmph, they would result in a compare against register that
2394*9880d681SAndroid Build Coastguard Worker// is loaded with the byte/half mask (i.e. 0xFF or 0xFFFF).
2395*9880d681SAndroid Build Coastguard Workerdef: Pat<(i1 (setne (and I32:$Rs, u6ImmPred:$u6), 0)),
2396*9880d681SAndroid Build Coastguard Worker         (C4_nbitsclri I32:$Rs, u6ImmPred:$u6)>;
2397*9880d681SAndroid Build Coastguard Workerdef: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), 0)),
2398*9880d681SAndroid Build Coastguard Worker         (C4_nbitsclr I32:$Rs, I32:$Rt)>;
2399*9880d681SAndroid Build Coastguard Workerdef: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), I32:$Rt)),
2400*9880d681SAndroid Build Coastguard Worker         (C4_nbitsset I32:$Rs, I32:$Rt)>;
2401*9880d681SAndroid Build Coastguard Worker
2402*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2403*9880d681SAndroid Build Coastguard Worker// XTYPE/BIT -
2404*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2405*9880d681SAndroid Build Coastguard Worker
2406*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2407*9880d681SAndroid Build Coastguard Worker// XTYPE/MPY +
2408*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2409*9880d681SAndroid Build Coastguard Worker
2410*9880d681SAndroid Build Coastguard Worker// Rd=add(#u6,mpyi(Rs,#U6)) -- Multiply by immed and add immed.
2411*9880d681SAndroid Build Coastguard Worker
2412*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, isExtendable = 1, opExtentBits = 6, opExtendable = 1 in
2413*9880d681SAndroid Build Coastguard Workerdef M4_mpyri_addi : MInst<(outs IntRegs:$Rd),
2414*9880d681SAndroid Build Coastguard Worker  (ins u6Ext:$u6, IntRegs:$Rs, u6Imm:$U6),
2415*9880d681SAndroid Build Coastguard Worker  "$Rd = add(#$u6, mpyi($Rs, #$U6))" ,
2416*9880d681SAndroid Build Coastguard Worker  [(set (i32 IntRegs:$Rd),
2417*9880d681SAndroid Build Coastguard Worker        (add (mul (i32 IntRegs:$Rs), u6ImmPred:$U6),
2418*9880d681SAndroid Build Coastguard Worker             u32ImmPred:$u6))] ,"",ALU64_tc_3x_SLOT23> {
2419*9880d681SAndroid Build Coastguard Worker    bits<5> Rd;
2420*9880d681SAndroid Build Coastguard Worker    bits<6> u6;
2421*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
2422*9880d681SAndroid Build Coastguard Worker    bits<6> U6;
2423*9880d681SAndroid Build Coastguard Worker
2424*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
2425*9880d681SAndroid Build Coastguard Worker
2426*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1000;
2427*9880d681SAndroid Build Coastguard Worker    let Inst{23}    = U6{5};
2428*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = u6{5-4};
2429*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
2430*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = u6{3};
2431*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rd;
2432*9880d681SAndroid Build Coastguard Worker    let Inst{7-5}   = u6{2-0};
2433*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = U6{4-0};
2434*9880d681SAndroid Build Coastguard Worker  }
2435*9880d681SAndroid Build Coastguard Worker
2436*9880d681SAndroid Build Coastguard Worker// Rd=add(#u6,mpyi(Rs,Rt))
2437*9880d681SAndroid Build Coastguard Workerlet CextOpcode = "ADD_MPY", InputType = "imm", hasNewValue = 1,
2438*9880d681SAndroid Build Coastguard Worker    isExtendable = 1, opExtentBits = 6, opExtendable = 1 in
2439*9880d681SAndroid Build Coastguard Workerdef M4_mpyrr_addi : MInst <(outs IntRegs:$Rd),
2440*9880d681SAndroid Build Coastguard Worker  (ins u6Ext:$u6, IntRegs:$Rs, IntRegs:$Rt),
2441*9880d681SAndroid Build Coastguard Worker  "$Rd = add(#$u6, mpyi($Rs, $Rt))" ,
2442*9880d681SAndroid Build Coastguard Worker  [(set (i32 IntRegs:$Rd),
2443*9880d681SAndroid Build Coastguard Worker        (add (mul (i32 IntRegs:$Rs), (i32 IntRegs:$Rt)), u32ImmPred:$u6))],
2444*9880d681SAndroid Build Coastguard Worker  "", ALU64_tc_3x_SLOT23>, ImmRegRel {
2445*9880d681SAndroid Build Coastguard Worker    bits<5> Rd;
2446*9880d681SAndroid Build Coastguard Worker    bits<6> u6;
2447*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
2448*9880d681SAndroid Build Coastguard Worker    bits<5> Rt;
2449*9880d681SAndroid Build Coastguard Worker
2450*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
2451*9880d681SAndroid Build Coastguard Worker
2452*9880d681SAndroid Build Coastguard Worker    let Inst{27-23} = 0b01110;
2453*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = u6{5-4};
2454*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
2455*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = u6{3};
2456*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rt;
2457*9880d681SAndroid Build Coastguard Worker    let Inst{7-5}   = u6{2-0};
2458*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rd;
2459*9880d681SAndroid Build Coastguard Worker  }
2460*9880d681SAndroid Build Coastguard Worker
2461*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1 in
2462*9880d681SAndroid Build Coastguard Workerclass T_AddMpy <bit MajOp, PatLeaf ImmPred, dag ins>
2463*9880d681SAndroid Build Coastguard Worker  : ALU64Inst <(outs IntRegs:$dst), ins,
2464*9880d681SAndroid Build Coastguard Worker  "$dst = add($src1, mpyi("#!if(MajOp,"$src3, #$src2))",
2465*9880d681SAndroid Build Coastguard Worker                                      "#$src2, $src3))"),
2466*9880d681SAndroid Build Coastguard Worker  [(set (i32 IntRegs:$dst),
2467*9880d681SAndroid Build Coastguard Worker        (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3), ImmPred:$src2)))],
2468*9880d681SAndroid Build Coastguard Worker  "", ALU64_tc_3x_SLOT23> {
2469*9880d681SAndroid Build Coastguard Worker    bits<5> dst;
2470*9880d681SAndroid Build Coastguard Worker    bits<5> src1;
2471*9880d681SAndroid Build Coastguard Worker    bits<8> src2;
2472*9880d681SAndroid Build Coastguard Worker    bits<5> src3;
2473*9880d681SAndroid Build Coastguard Worker
2474*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
2475*9880d681SAndroid Build Coastguard Worker
2476*9880d681SAndroid Build Coastguard Worker    bits<6> ImmValue = !if(MajOp, src2{5-0}, src2{7-2});
2477*9880d681SAndroid Build Coastguard Worker
2478*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1111;
2479*9880d681SAndroid Build Coastguard Worker    let Inst{23}    = MajOp;
2480*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = ImmValue{5-4};
2481*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = src3;
2482*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = ImmValue{3};
2483*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = dst;
2484*9880d681SAndroid Build Coastguard Worker    let Inst{7-5}   = ImmValue{2-0};
2485*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = src1;
2486*9880d681SAndroid Build Coastguard Worker  }
2487*9880d681SAndroid Build Coastguard Worker
2488*9880d681SAndroid Build Coastguard Workerdef M4_mpyri_addr_u2 : T_AddMpy<0b0, u6_2ImmPred,
2489*9880d681SAndroid Build Coastguard Worker                       (ins IntRegs:$src1, u6_2Imm:$src2, IntRegs:$src3)>;
2490*9880d681SAndroid Build Coastguard Worker
2491*9880d681SAndroid Build Coastguard Workerlet isExtendable = 1, opExtentBits = 6, opExtendable = 3,
2492*9880d681SAndroid Build Coastguard Worker    CextOpcode = "ADD_MPY", InputType = "imm" in
2493*9880d681SAndroid Build Coastguard Workerdef M4_mpyri_addr : T_AddMpy<0b1, u32ImmPred,
2494*9880d681SAndroid Build Coastguard Worker                    (ins IntRegs:$src1, IntRegs:$src3, u6Ext:$src2)>, ImmRegRel;
2495*9880d681SAndroid Build Coastguard Worker
2496*9880d681SAndroid Build Coastguard Worker// Rx=add(Ru,mpyi(Rx,Rs))
2497*9880d681SAndroid Build Coastguard Workerlet CextOpcode = "ADD_MPY", InputType = "reg", hasNewValue = 1 in
2498*9880d681SAndroid Build Coastguard Workerdef M4_mpyrr_addr: MInst_acc <(outs IntRegs:$Rx),
2499*9880d681SAndroid Build Coastguard Worker                              (ins IntRegs:$Ru, IntRegs:$_src_, IntRegs:$Rs),
2500*9880d681SAndroid Build Coastguard Worker  "$Rx = add($Ru, mpyi($_src_, $Rs))",
2501*9880d681SAndroid Build Coastguard Worker  [(set (i32 IntRegs:$Rx), (add (i32 IntRegs:$Ru),
2502*9880d681SAndroid Build Coastguard Worker                           (mul (i32 IntRegs:$_src_), (i32 IntRegs:$Rs))))],
2503*9880d681SAndroid Build Coastguard Worker  "$_src_ = $Rx", M_tc_3x_SLOT23>, ImmRegRel {
2504*9880d681SAndroid Build Coastguard Worker    bits<5> Rx;
2505*9880d681SAndroid Build Coastguard Worker    bits<5> Ru;
2506*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
2507*9880d681SAndroid Build Coastguard Worker
2508*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1110;
2509*9880d681SAndroid Build Coastguard Worker
2510*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b0011000;
2511*9880d681SAndroid Build Coastguard Worker    let Inst{12-8} = Rx;
2512*9880d681SAndroid Build Coastguard Worker    let Inst{4-0} = Ru;
2513*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
2514*9880d681SAndroid Build Coastguard Worker  }
2515*9880d681SAndroid Build Coastguard Worker
2516*9880d681SAndroid Build Coastguard Worker
2517*9880d681SAndroid Build Coastguard Worker// Vector reduce multiply word by signed half (32x16)
2518*9880d681SAndroid Build Coastguard Worker//Rdd=vrmpyweh(Rss,Rtt)[:<<1]
2519*9880d681SAndroid Build Coastguard Workerdef M4_vrmpyeh_s0 : T_M2_vmpy<"vrmpyweh", 0b010, 0b100, 0, 0, 0>;
2520*9880d681SAndroid Build Coastguard Workerdef M4_vrmpyeh_s1 : T_M2_vmpy<"vrmpyweh", 0b110, 0b100, 1, 0, 0>;
2521*9880d681SAndroid Build Coastguard Worker
2522*9880d681SAndroid Build Coastguard Worker//Rdd=vrmpywoh(Rss,Rtt)[:<<1]
2523*9880d681SAndroid Build Coastguard Workerdef M4_vrmpyoh_s0 : T_M2_vmpy<"vrmpywoh", 0b001, 0b010, 0, 0, 0>;
2524*9880d681SAndroid Build Coastguard Workerdef M4_vrmpyoh_s1 : T_M2_vmpy<"vrmpywoh", 0b101, 0b010, 1, 0, 0>;
2525*9880d681SAndroid Build Coastguard Worker
2526*9880d681SAndroid Build Coastguard Worker//Rdd+=vrmpyweh(Rss,Rtt)[:<<1]
2527*9880d681SAndroid Build Coastguard Workerdef M4_vrmpyeh_acc_s0: T_M2_vmpy_acc<"vrmpyweh", 0b001, 0b110, 0, 0>;
2528*9880d681SAndroid Build Coastguard Workerdef M4_vrmpyeh_acc_s1: T_M2_vmpy_acc<"vrmpyweh", 0b101, 0b110, 1, 0>;
2529*9880d681SAndroid Build Coastguard Worker
2530*9880d681SAndroid Build Coastguard Worker//Rdd=vrmpywoh(Rss,Rtt)[:<<1]
2531*9880d681SAndroid Build Coastguard Workerdef M4_vrmpyoh_acc_s0: T_M2_vmpy_acc<"vrmpywoh", 0b011, 0b110, 0, 0>;
2532*9880d681SAndroid Build Coastguard Workerdef M4_vrmpyoh_acc_s1: T_M2_vmpy_acc<"vrmpywoh", 0b111, 0b110, 1, 0>;
2533*9880d681SAndroid Build Coastguard Worker
2534*9880d681SAndroid Build Coastguard Worker// Vector multiply halfwords, signed by unsigned
2535*9880d681SAndroid Build Coastguard Worker// Rdd=vmpyhsu(Rs,Rt)[:<<]:sat
2536*9880d681SAndroid Build Coastguard Workerdef M2_vmpy2su_s0 : T_XTYPE_mpy64 < "vmpyhsu", 0b000, 0b111, 1, 0, 0>;
2537*9880d681SAndroid Build Coastguard Workerdef M2_vmpy2su_s1 : T_XTYPE_mpy64 < "vmpyhsu", 0b100, 0b111, 1, 1, 0>;
2538*9880d681SAndroid Build Coastguard Worker
2539*9880d681SAndroid Build Coastguard Worker// Rxx+=vmpyhsu(Rs,Rt)[:<<1]:sat
2540*9880d681SAndroid Build Coastguard Workerdef M2_vmac2su_s0 : T_XTYPE_mpy64_acc < "vmpyhsu", "+", 0b011, 0b101, 1, 0, 0>;
2541*9880d681SAndroid Build Coastguard Workerdef M2_vmac2su_s1 : T_XTYPE_mpy64_acc < "vmpyhsu", "+", 0b111, 0b101, 1, 1, 0>;
2542*9880d681SAndroid Build Coastguard Worker
2543*9880d681SAndroid Build Coastguard Worker// Vector polynomial multiply halfwords
2544*9880d681SAndroid Build Coastguard Worker// Rdd=vpmpyh(Rs,Rt)
2545*9880d681SAndroid Build Coastguard Workerdef M4_vpmpyh : T_XTYPE_mpy64 < "vpmpyh", 0b110, 0b111, 0, 0, 0>;
2546*9880d681SAndroid Build Coastguard Worker
2547*9880d681SAndroid Build Coastguard Worker// Rxx^=vpmpyh(Rs,Rt)
2548*9880d681SAndroid Build Coastguard Workerdef M4_vpmpyh_acc : T_XTYPE_mpy64_acc < "vpmpyh", "^", 0b101, 0b111, 0, 0, 0>;
2549*9880d681SAndroid Build Coastguard Worker
2550*9880d681SAndroid Build Coastguard Worker// Polynomial multiply words
2551*9880d681SAndroid Build Coastguard Worker// Rdd=pmpyw(Rs,Rt)
2552*9880d681SAndroid Build Coastguard Workerdef M4_pmpyw : T_XTYPE_mpy64 < "pmpyw", 0b010, 0b111, 0, 0, 0>;
2553*9880d681SAndroid Build Coastguard Worker
2554*9880d681SAndroid Build Coastguard Worker// Rxx^=pmpyw(Rs,Rt)
2555*9880d681SAndroid Build Coastguard Workerdef M4_pmpyw_acc  : T_XTYPE_mpy64_acc < "pmpyw", "^", 0b001, 0b111, 0, 0, 0>;
2556*9880d681SAndroid Build Coastguard Worker
2557*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2558*9880d681SAndroid Build Coastguard Worker// XTYPE/MPY -
2559*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2560*9880d681SAndroid Build Coastguard Worker
2561*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2562*9880d681SAndroid Build Coastguard Worker// ALU64/Vector compare
2563*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2564*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2565*9880d681SAndroid Build Coastguard Worker// Template class for vector compare
2566*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2567*9880d681SAndroid Build Coastguard Worker
2568*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
2569*9880d681SAndroid Build Coastguard Workerclass T_vcmpImm <string Str, bits<2> cmpOp, bits<2> minOp, Operand ImmOprnd>
2570*9880d681SAndroid Build Coastguard Worker  : ALU64_rr <(outs PredRegs:$Pd),
2571*9880d681SAndroid Build Coastguard Worker              (ins DoubleRegs:$Rss, ImmOprnd:$Imm),
2572*9880d681SAndroid Build Coastguard Worker  "$Pd = "#Str#"($Rss, #$Imm)",
2573*9880d681SAndroid Build Coastguard Worker  [], "", ALU64_tc_2early_SLOT23> {
2574*9880d681SAndroid Build Coastguard Worker    bits<2> Pd;
2575*9880d681SAndroid Build Coastguard Worker    bits<5> Rss;
2576*9880d681SAndroid Build Coastguard Worker    bits<32> Imm;
2577*9880d681SAndroid Build Coastguard Worker    bits<8> ImmBits;
2578*9880d681SAndroid Build Coastguard Worker    let ImmBits{6-0} = Imm{6-0};
2579*9880d681SAndroid Build Coastguard Worker    let ImmBits{7} = !if (!eq(cmpOp,0b10), 0b0, Imm{7}); // 0 for vcmp[bhw].gtu
2580*9880d681SAndroid Build Coastguard Worker
2581*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
2582*9880d681SAndroid Build Coastguard Worker
2583*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1100;
2584*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = cmpOp;
2585*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rss;
2586*9880d681SAndroid Build Coastguard Worker    let Inst{12-5} = ImmBits;
2587*9880d681SAndroid Build Coastguard Worker    let Inst{4-3} = minOp;
2588*9880d681SAndroid Build Coastguard Worker    let Inst{1-0} = Pd;
2589*9880d681SAndroid Build Coastguard Worker  }
2590*9880d681SAndroid Build Coastguard Worker
2591*9880d681SAndroid Build Coastguard Worker// Vector compare bytes
2592*9880d681SAndroid Build Coastguard Workerdef A4_vcmpbgt   : T_vcmp <"vcmpb.gt", 0b1010>;
2593*9880d681SAndroid Build Coastguard Workerdef: T_vcmp_pat<A4_vcmpbgt, setgt, v8i8>;
2594*9880d681SAndroid Build Coastguard Worker
2595*9880d681SAndroid Build Coastguard Workerlet AsmString = "$Pd = any8(vcmpb.eq($Rss, $Rtt))" in
2596*9880d681SAndroid Build Coastguard Workerdef A4_vcmpbeq_any : T_vcmp <"any8(vcmpb.gt", 0b1000>;
2597*9880d681SAndroid Build Coastguard Worker
2598*9880d681SAndroid Build Coastguard Workerdef A4_vcmpbeqi  : T_vcmpImm <"vcmpb.eq",  0b00, 0b00, u8Imm>;
2599*9880d681SAndroid Build Coastguard Workerdef A4_vcmpbgti  : T_vcmpImm <"vcmpb.gt",  0b01, 0b00, s8Imm>;
2600*9880d681SAndroid Build Coastguard Workerdef A4_vcmpbgtui : T_vcmpImm <"vcmpb.gtu", 0b10, 0b00, u7Imm>;
2601*9880d681SAndroid Build Coastguard Worker
2602*9880d681SAndroid Build Coastguard Worker// Vector compare halfwords
2603*9880d681SAndroid Build Coastguard Workerdef A4_vcmpheqi  : T_vcmpImm <"vcmph.eq",  0b00, 0b01, s8Imm>;
2604*9880d681SAndroid Build Coastguard Workerdef A4_vcmphgti  : T_vcmpImm <"vcmph.gt",  0b01, 0b01, s8Imm>;
2605*9880d681SAndroid Build Coastguard Workerdef A4_vcmphgtui : T_vcmpImm <"vcmph.gtu", 0b10, 0b01, u7Imm>;
2606*9880d681SAndroid Build Coastguard Worker
2607*9880d681SAndroid Build Coastguard Worker// Vector compare words
2608*9880d681SAndroid Build Coastguard Workerdef A4_vcmpweqi  : T_vcmpImm <"vcmpw.eq",  0b00, 0b10, s8Imm>;
2609*9880d681SAndroid Build Coastguard Workerdef A4_vcmpwgti  : T_vcmpImm <"vcmpw.gt",  0b01, 0b10, s8Imm>;
2610*9880d681SAndroid Build Coastguard Workerdef A4_vcmpwgtui : T_vcmpImm <"vcmpw.gtu", 0b10, 0b10, u7Imm>;
2611*9880d681SAndroid Build Coastguard Worker
2612*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2613*9880d681SAndroid Build Coastguard Worker// XTYPE/SHIFT +
2614*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2615*9880d681SAndroid Build Coastguard Worker// Shift by immediate and accumulate/logical.
2616*9880d681SAndroid Build Coastguard Worker// Rx=add(#u8,asl(Rx,#U5))  Rx=add(#u8,lsr(Rx,#U5))
2617*9880d681SAndroid Build Coastguard Worker// Rx=sub(#u8,asl(Rx,#U5))  Rx=sub(#u8,lsr(Rx,#U5))
2618*9880d681SAndroid Build Coastguard Worker// Rx=and(#u8,asl(Rx,#U5))  Rx=and(#u8,lsr(Rx,#U5))
2619*9880d681SAndroid Build Coastguard Worker// Rx=or(#u8,asl(Rx,#U5))   Rx=or(#u8,lsr(Rx,#U5))
2620*9880d681SAndroid Build Coastguard Workerlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2621*9880d681SAndroid Build Coastguard Worker    hasNewValue = 1, opNewValue = 0 in
2622*9880d681SAndroid Build Coastguard Workerclass T_S4_ShiftOperate<string MnOp, string MnSh, SDNode Op, SDNode Sh,
2623*9880d681SAndroid Build Coastguard Worker                        bit asl_lsr, bits<2> MajOp, InstrItinClass Itin>
2624*9880d681SAndroid Build Coastguard Worker  : MInst_acc<(outs IntRegs:$Rd), (ins u8Ext:$u8, IntRegs:$Rx, u5Imm:$U5),
2625*9880d681SAndroid Build Coastguard Worker      "$Rd = "#MnOp#"(#$u8, "#MnSh#"($Rx, #$U5))",
2626*9880d681SAndroid Build Coastguard Worker      [(set (i32 IntRegs:$Rd),
2627*9880d681SAndroid Build Coastguard Worker            (Op (Sh I32:$Rx, u5ImmPred:$U5), u32ImmPred:$u8))],
2628*9880d681SAndroid Build Coastguard Worker      "$Rd = $Rx", Itin> {
2629*9880d681SAndroid Build Coastguard Worker
2630*9880d681SAndroid Build Coastguard Worker  bits<5> Rd;
2631*9880d681SAndroid Build Coastguard Worker  bits<8> u8;
2632*9880d681SAndroid Build Coastguard Worker  bits<5> Rx;
2633*9880d681SAndroid Build Coastguard Worker  bits<5> U5;
2634*9880d681SAndroid Build Coastguard Worker
2635*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1101;
2636*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b1110;
2637*9880d681SAndroid Build Coastguard Worker  let Inst{23-21} = u8{7-5};
2638*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rd;
2639*9880d681SAndroid Build Coastguard Worker  let Inst{13} = u8{4};
2640*9880d681SAndroid Build Coastguard Worker  let Inst{12-8} = U5;
2641*9880d681SAndroid Build Coastguard Worker  let Inst{7-5} = u8{3-1};
2642*9880d681SAndroid Build Coastguard Worker  let Inst{4} = asl_lsr;
2643*9880d681SAndroid Build Coastguard Worker  let Inst{3} = u8{0};
2644*9880d681SAndroid Build Coastguard Worker  let Inst{2-1} = MajOp;
2645*9880d681SAndroid Build Coastguard Worker}
2646*9880d681SAndroid Build Coastguard Worker
2647*9880d681SAndroid Build Coastguard Workermulticlass T_ShiftOperate<string mnemonic, SDNode Op, bits<2> MajOp,
2648*9880d681SAndroid Build Coastguard Worker                          InstrItinClass Itin> {
2649*9880d681SAndroid Build Coastguard Worker  def _asl_ri : T_S4_ShiftOperate<mnemonic, "asl", Op, shl, 0, MajOp, Itin>;
2650*9880d681SAndroid Build Coastguard Worker  def _lsr_ri : T_S4_ShiftOperate<mnemonic, "lsr", Op, srl, 1, MajOp, Itin>;
2651*9880d681SAndroid Build Coastguard Worker}
2652*9880d681SAndroid Build Coastguard Worker
2653*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 200 in {
2654*9880d681SAndroid Build Coastguard Worker  defm S4_addi : T_ShiftOperate<"add", add, 0b10, ALU64_tc_2_SLOT23>;
2655*9880d681SAndroid Build Coastguard Worker  defm S4_andi : T_ShiftOperate<"and", and, 0b00, ALU64_tc_2_SLOT23>;
2656*9880d681SAndroid Build Coastguard Worker}
2657*9880d681SAndroid Build Coastguard Worker
2658*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 30 in
2659*9880d681SAndroid Build Coastguard Workerdefm S4_ori  : T_ShiftOperate<"or",  or,  0b01, ALU64_tc_1_SLOT23>;
2660*9880d681SAndroid Build Coastguard Worker
2661*9880d681SAndroid Build Coastguard Workerdefm S4_subi : T_ShiftOperate<"sub", sub, 0b11, ALU64_tc_1_SLOT23>;
2662*9880d681SAndroid Build Coastguard Worker
2663*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 200 in {
2664*9880d681SAndroid Build Coastguard Worker  def: Pat<(add addrga:$addr, (shl I32:$src2, u5ImmPred:$src3)),
2665*9880d681SAndroid Build Coastguard Worker           (S4_addi_asl_ri addrga:$addr, IntRegs:$src2, u5ImmPred:$src3)>;
2666*9880d681SAndroid Build Coastguard Worker  def: Pat<(add addrga:$addr, (srl I32:$src2, u5ImmPred:$src3)),
2667*9880d681SAndroid Build Coastguard Worker           (S4_addi_lsr_ri addrga:$addr, IntRegs:$src2, u5ImmPred:$src3)>;
2668*9880d681SAndroid Build Coastguard Worker  def: Pat<(sub addrga:$addr, (shl I32:$src2, u5ImmPred:$src3)),
2669*9880d681SAndroid Build Coastguard Worker           (S4_subi_asl_ri addrga:$addr, IntRegs:$src2, u5ImmPred:$src3)>;
2670*9880d681SAndroid Build Coastguard Worker  def: Pat<(sub addrga:$addr, (srl I32:$src2, u5ImmPred:$src3)),
2671*9880d681SAndroid Build Coastguard Worker           (S4_subi_lsr_ri addrga:$addr, IntRegs:$src2, u5ImmPred:$src3)>;
2672*9880d681SAndroid Build Coastguard Worker}
2673*9880d681SAndroid Build Coastguard Worker
2674*9880d681SAndroid Build Coastguard Worker// Vector conditional negate
2675*9880d681SAndroid Build Coastguard Worker// Rdd=vcnegh(Rss,Rt)
2676*9880d681SAndroid Build Coastguard Workerlet Defs = [USR_OVF], Itinerary = S_3op_tc_2_SLOT23 in
2677*9880d681SAndroid Build Coastguard Workerdef S2_vcnegh   : T_S3op_shiftVect < "vcnegh",   0b11, 0b01>;
2678*9880d681SAndroid Build Coastguard Worker
2679*9880d681SAndroid Build Coastguard Worker// Rd=[cround|round](Rs,Rt)
2680*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, Itinerary = S_3op_tc_2_SLOT23 in {
2681*9880d681SAndroid Build Coastguard Worker  def A4_cround_rr    : T_S3op_3 < "cround", IntRegs, 0b11, 0b00>;
2682*9880d681SAndroid Build Coastguard Worker  def A4_round_rr     : T_S3op_3 < "round", IntRegs, 0b11, 0b10>;
2683*9880d681SAndroid Build Coastguard Worker}
2684*9880d681SAndroid Build Coastguard Worker
2685*9880d681SAndroid Build Coastguard Worker// Rd=round(Rs,Rt):sat
2686*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, Defs = [USR_OVF], Itinerary = S_3op_tc_2_SLOT23 in
2687*9880d681SAndroid Build Coastguard Workerdef A4_round_rr_sat : T_S3op_3 < "round", IntRegs, 0b11, 0b11, 1>;
2688*9880d681SAndroid Build Coastguard Worker
2689*9880d681SAndroid Build Coastguard Worker// Rd=[cmpyiwh|cmpyrwh](Rss,Rt):<<1:rnd:sat
2690*9880d681SAndroid Build Coastguard Workerlet Defs = [USR_OVF], Itinerary = S_3op_tc_3x_SLOT23 in {
2691*9880d681SAndroid Build Coastguard Worker  def M4_cmpyi_wh     : T_S3op_8<"cmpyiwh", 0b100, 1, 1, 1>;
2692*9880d681SAndroid Build Coastguard Worker  def M4_cmpyr_wh     : T_S3op_8<"cmpyrwh", 0b110, 1, 1, 1>;
2693*9880d681SAndroid Build Coastguard Worker}
2694*9880d681SAndroid Build Coastguard Worker
2695*9880d681SAndroid Build Coastguard Worker// Rdd=[add|sub](Rss,Rtt,Px):carry
2696*9880d681SAndroid Build Coastguard Workerlet isPredicateLate = 1, hasSideEffects = 0 in
2697*9880d681SAndroid Build Coastguard Workerclass T_S3op_carry <string mnemonic, bits<3> MajOp>
2698*9880d681SAndroid Build Coastguard Worker  : SInst < (outs DoubleRegs:$Rdd, PredRegs:$Px),
2699*9880d681SAndroid Build Coastguard Worker            (ins DoubleRegs:$Rss, DoubleRegs:$Rtt, PredRegs:$Pu),
2700*9880d681SAndroid Build Coastguard Worker  "$Rdd = "#mnemonic#"($Rss, $Rtt, $Pu):carry",
2701*9880d681SAndroid Build Coastguard Worker  [], "$Px = $Pu", S_3op_tc_1_SLOT23 > {
2702*9880d681SAndroid Build Coastguard Worker    bits<5> Rdd;
2703*9880d681SAndroid Build Coastguard Worker    bits<5> Rss;
2704*9880d681SAndroid Build Coastguard Worker    bits<5> Rtt;
2705*9880d681SAndroid Build Coastguard Worker    bits<2> Pu;
2706*9880d681SAndroid Build Coastguard Worker
2707*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1100;
2708*9880d681SAndroid Build Coastguard Worker
2709*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b0010;
2710*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = MajOp;
2711*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rss;
2712*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rtt;
2713*9880d681SAndroid Build Coastguard Worker    let Inst{6-5}   = Pu;
2714*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rdd;
2715*9880d681SAndroid Build Coastguard Worker  }
2716*9880d681SAndroid Build Coastguard Worker
2717*9880d681SAndroid Build Coastguard Workerdef A4_addp_c : T_S3op_carry < "add", 0b110 >;
2718*9880d681SAndroid Build Coastguard Workerdef A4_subp_c : T_S3op_carry < "sub", 0b111 >;
2719*9880d681SAndroid Build Coastguard Worker
2720*9880d681SAndroid Build Coastguard Workerlet Itinerary = S_3op_tc_3_SLOT23, hasSideEffects = 0 in
2721*9880d681SAndroid Build Coastguard Workerclass T_S3op_6 <string mnemonic, bits<3> MinOp, bit isUnsigned>
2722*9880d681SAndroid Build Coastguard Worker  : SInst <(outs DoubleRegs:$Rxx),
2723*9880d681SAndroid Build Coastguard Worker           (ins DoubleRegs:$dst2, DoubleRegs:$Rss, IntRegs:$Ru),
2724*9880d681SAndroid Build Coastguard Worker  "$Rxx = "#mnemonic#"($Rss, $Ru)" ,
2725*9880d681SAndroid Build Coastguard Worker  [] , "$dst2 = $Rxx"> {
2726*9880d681SAndroid Build Coastguard Worker    bits<5> Rxx;
2727*9880d681SAndroid Build Coastguard Worker    bits<5> Rss;
2728*9880d681SAndroid Build Coastguard Worker    bits<5> Ru;
2729*9880d681SAndroid Build Coastguard Worker
2730*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1100;
2731*9880d681SAndroid Build Coastguard Worker
2732*9880d681SAndroid Build Coastguard Worker    let Inst{27-21} = 0b1011001;
2733*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rss;
2734*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = isUnsigned;
2735*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rxx;
2736*9880d681SAndroid Build Coastguard Worker    let Inst{7-5}   = MinOp;
2737*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Ru;
2738*9880d681SAndroid Build Coastguard Worker  }
2739*9880d681SAndroid Build Coastguard Worker
2740*9880d681SAndroid Build Coastguard Worker// Vector reduce maximum halfwords
2741*9880d681SAndroid Build Coastguard Worker// Rxx=vrmax[u]h(Rss,Ru)
2742*9880d681SAndroid Build Coastguard Workerdef A4_vrmaxh  : T_S3op_6 < "vrmaxh",  0b001, 0>;
2743*9880d681SAndroid Build Coastguard Workerdef A4_vrmaxuh : T_S3op_6 < "vrmaxuh", 0b001, 1>;
2744*9880d681SAndroid Build Coastguard Worker
2745*9880d681SAndroid Build Coastguard Worker// Vector reduce maximum words
2746*9880d681SAndroid Build Coastguard Worker// Rxx=vrmax[u]w(Rss,Ru)
2747*9880d681SAndroid Build Coastguard Workerdef A4_vrmaxw  : T_S3op_6 < "vrmaxw",  0b010, 0>;
2748*9880d681SAndroid Build Coastguard Workerdef A4_vrmaxuw : T_S3op_6 < "vrmaxuw", 0b010, 1>;
2749*9880d681SAndroid Build Coastguard Worker
2750*9880d681SAndroid Build Coastguard Worker// Vector reduce minimum halfwords
2751*9880d681SAndroid Build Coastguard Worker// Rxx=vrmin[u]h(Rss,Ru)
2752*9880d681SAndroid Build Coastguard Workerdef A4_vrminh  : T_S3op_6 < "vrminh",  0b101, 0>;
2753*9880d681SAndroid Build Coastguard Workerdef A4_vrminuh : T_S3op_6 < "vrminuh", 0b101, 1>;
2754*9880d681SAndroid Build Coastguard Worker
2755*9880d681SAndroid Build Coastguard Worker// Vector reduce minimum words
2756*9880d681SAndroid Build Coastguard Worker// Rxx=vrmin[u]w(Rss,Ru)
2757*9880d681SAndroid Build Coastguard Workerdef A4_vrminw  : T_S3op_6 < "vrminw",  0b110, 0>;
2758*9880d681SAndroid Build Coastguard Workerdef A4_vrminuw : T_S3op_6 < "vrminuw", 0b110, 1>;
2759*9880d681SAndroid Build Coastguard Worker
2760*9880d681SAndroid Build Coastguard Worker// Shift an immediate left by register amount.
2761*9880d681SAndroid Build Coastguard Workerlet hasNewValue = 1, hasSideEffects = 0 in
2762*9880d681SAndroid Build Coastguard Workerdef S4_lsli: SInst <(outs IntRegs:$Rd), (ins s6Imm:$s6, IntRegs:$Rt),
2763*9880d681SAndroid Build Coastguard Worker  "$Rd = lsl(#$s6, $Rt)" ,
2764*9880d681SAndroid Build Coastguard Worker  [(set (i32 IntRegs:$Rd), (shl s6ImmPred:$s6,
2765*9880d681SAndroid Build Coastguard Worker                                 (i32 IntRegs:$Rt)))],
2766*9880d681SAndroid Build Coastguard Worker  "", S_3op_tc_1_SLOT23> {
2767*9880d681SAndroid Build Coastguard Worker    bits<5> Rd;
2768*9880d681SAndroid Build Coastguard Worker    bits<6> s6;
2769*9880d681SAndroid Build Coastguard Worker    bits<5> Rt;
2770*9880d681SAndroid Build Coastguard Worker
2771*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1100;
2772*9880d681SAndroid Build Coastguard Worker
2773*9880d681SAndroid Build Coastguard Worker    let Inst{27-22} = 0b011010;
2774*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = s6{5-1};
2775*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = Rt;
2776*9880d681SAndroid Build Coastguard Worker    let Inst{7-6}   = 0b11;
2777*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = Rd;
2778*9880d681SAndroid Build Coastguard Worker    let Inst{5}     = s6{0};
2779*9880d681SAndroid Build Coastguard Worker  }
2780*9880d681SAndroid Build Coastguard Worker
2781*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2782*9880d681SAndroid Build Coastguard Worker// XTYPE/SHIFT -
2783*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2784*9880d681SAndroid Build Coastguard Worker
2785*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2786*9880d681SAndroid Build Coastguard Worker// MEMOP: Word, Half, Byte
2787*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2788*9880d681SAndroid Build Coastguard Worker
2789*9880d681SAndroid Build Coastguard Workerdef MEMOPIMM : SDNodeXForm<imm, [{
2790*9880d681SAndroid Build Coastguard Worker  // Call the transformation function XformM5ToU5Imm to get the negative
2791*9880d681SAndroid Build Coastguard Worker  // immediate's positive counterpart.
2792*9880d681SAndroid Build Coastguard Worker  int32_t imm = N->getSExtValue();
2793*9880d681SAndroid Build Coastguard Worker  return XformM5ToU5Imm(imm, SDLoc(N));
2794*9880d681SAndroid Build Coastguard Worker}]>;
2795*9880d681SAndroid Build Coastguard Worker
2796*9880d681SAndroid Build Coastguard Workerdef MEMOPIMM_HALF : SDNodeXForm<imm, [{
2797*9880d681SAndroid Build Coastguard Worker  // -1 .. -31 represented as 65535..65515
2798*9880d681SAndroid Build Coastguard Worker  // assigning to a short restores our desired signed value.
2799*9880d681SAndroid Build Coastguard Worker  // Call the transformation function XformM5ToU5Imm to get the negative
2800*9880d681SAndroid Build Coastguard Worker  // immediate's positive counterpart.
2801*9880d681SAndroid Build Coastguard Worker  int16_t imm = N->getSExtValue();
2802*9880d681SAndroid Build Coastguard Worker  return XformM5ToU5Imm(imm, SDLoc(N));
2803*9880d681SAndroid Build Coastguard Worker}]>;
2804*9880d681SAndroid Build Coastguard Worker
2805*9880d681SAndroid Build Coastguard Workerdef MEMOPIMM_BYTE : SDNodeXForm<imm, [{
2806*9880d681SAndroid Build Coastguard Worker  // -1 .. -31 represented as 255..235
2807*9880d681SAndroid Build Coastguard Worker  // assigning to a char restores our desired signed value.
2808*9880d681SAndroid Build Coastguard Worker  // Call the transformation function XformM5ToU5Imm to get the negative
2809*9880d681SAndroid Build Coastguard Worker  // immediate's positive counterpart.
2810*9880d681SAndroid Build Coastguard Worker  int8_t imm = N->getSExtValue();
2811*9880d681SAndroid Build Coastguard Worker  return XformM5ToU5Imm(imm, SDLoc(N));
2812*9880d681SAndroid Build Coastguard Worker}]>;
2813*9880d681SAndroid Build Coastguard Worker
2814*9880d681SAndroid Build Coastguard Workerdef SETMEMIMM : SDNodeXForm<imm, [{
2815*9880d681SAndroid Build Coastguard Worker   // Return the bit position we will set [0-31].
2816*9880d681SAndroid Build Coastguard Worker   // As an SDNode.
2817*9880d681SAndroid Build Coastguard Worker   int32_t imm = N->getSExtValue();
2818*9880d681SAndroid Build Coastguard Worker   return XformMskToBitPosU5Imm(imm, SDLoc(N));
2819*9880d681SAndroid Build Coastguard Worker}]>;
2820*9880d681SAndroid Build Coastguard Worker
2821*9880d681SAndroid Build Coastguard Workerdef CLRMEMIMM : SDNodeXForm<imm, [{
2822*9880d681SAndroid Build Coastguard Worker   // Return the bit position we will clear [0-31].
2823*9880d681SAndroid Build Coastguard Worker   // As an SDNode.
2824*9880d681SAndroid Build Coastguard Worker   // we bit negate the value first
2825*9880d681SAndroid Build Coastguard Worker   int32_t imm = ~(N->getSExtValue());
2826*9880d681SAndroid Build Coastguard Worker   return XformMskToBitPosU5Imm(imm, SDLoc(N));
2827*9880d681SAndroid Build Coastguard Worker}]>;
2828*9880d681SAndroid Build Coastguard Worker
2829*9880d681SAndroid Build Coastguard Workerdef SETMEMIMM_SHORT : SDNodeXForm<imm, [{
2830*9880d681SAndroid Build Coastguard Worker   // Return the bit position we will set [0-15].
2831*9880d681SAndroid Build Coastguard Worker   // As an SDNode.
2832*9880d681SAndroid Build Coastguard Worker   int16_t imm = N->getSExtValue();
2833*9880d681SAndroid Build Coastguard Worker   return XformMskToBitPosU4Imm(imm, SDLoc(N));
2834*9880d681SAndroid Build Coastguard Worker}]>;
2835*9880d681SAndroid Build Coastguard Worker
2836*9880d681SAndroid Build Coastguard Workerdef CLRMEMIMM_SHORT : SDNodeXForm<imm, [{
2837*9880d681SAndroid Build Coastguard Worker   // Return the bit position we will clear [0-15].
2838*9880d681SAndroid Build Coastguard Worker   // As an SDNode.
2839*9880d681SAndroid Build Coastguard Worker   // we bit negate the value first
2840*9880d681SAndroid Build Coastguard Worker   int16_t imm = ~(N->getSExtValue());
2841*9880d681SAndroid Build Coastguard Worker   return XformMskToBitPosU4Imm(imm, SDLoc(N));
2842*9880d681SAndroid Build Coastguard Worker}]>;
2843*9880d681SAndroid Build Coastguard Worker
2844*9880d681SAndroid Build Coastguard Workerdef SETMEMIMM_BYTE : SDNodeXForm<imm, [{
2845*9880d681SAndroid Build Coastguard Worker   // Return the bit position we will set [0-7].
2846*9880d681SAndroid Build Coastguard Worker   // As an SDNode.
2847*9880d681SAndroid Build Coastguard Worker   int8_t imm =  N->getSExtValue();
2848*9880d681SAndroid Build Coastguard Worker   return XformMskToBitPosU3Imm(imm, SDLoc(N));
2849*9880d681SAndroid Build Coastguard Worker}]>;
2850*9880d681SAndroid Build Coastguard Worker
2851*9880d681SAndroid Build Coastguard Workerdef CLRMEMIMM_BYTE : SDNodeXForm<imm, [{
2852*9880d681SAndroid Build Coastguard Worker   // Return the bit position we will clear [0-7].
2853*9880d681SAndroid Build Coastguard Worker   // As an SDNode.
2854*9880d681SAndroid Build Coastguard Worker   // we bit negate the value first
2855*9880d681SAndroid Build Coastguard Worker   int8_t imm = ~(N->getSExtValue());
2856*9880d681SAndroid Build Coastguard Worker   return XformMskToBitPosU3Imm(imm, SDLoc(N));
2857*9880d681SAndroid Build Coastguard Worker}]>;
2858*9880d681SAndroid Build Coastguard Worker
2859*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2860*9880d681SAndroid Build Coastguard Worker// Template class for MemOp instructions with the register value.
2861*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2862*9880d681SAndroid Build Coastguard Workerclass MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp,
2863*9880d681SAndroid Build Coastguard Worker                     string memOp, bits<2> memOpBits> :
2864*9880d681SAndroid Build Coastguard Worker      MEMInst_V4<(outs),
2865*9880d681SAndroid Build Coastguard Worker                 (ins IntRegs:$base, ImmOp:$offset, IntRegs:$delta),
2866*9880d681SAndroid Build Coastguard Worker                 opc#"($base+#$offset)"#memOp#"$delta",
2867*9880d681SAndroid Build Coastguard Worker                 []>,
2868*9880d681SAndroid Build Coastguard Worker                 Requires<[UseMEMOP]> {
2869*9880d681SAndroid Build Coastguard Worker
2870*9880d681SAndroid Build Coastguard Worker    bits<5> base;
2871*9880d681SAndroid Build Coastguard Worker    bits<5> delta;
2872*9880d681SAndroid Build Coastguard Worker    bits<32> offset;
2873*9880d681SAndroid Build Coastguard Worker    bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
2874*9880d681SAndroid Build Coastguard Worker
2875*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
2876*9880d681SAndroid Build Coastguard Worker                     !if (!eq(opcBits, 0b01), offset{6-1},
2877*9880d681SAndroid Build Coastguard Worker                     !if (!eq(opcBits, 0b10), offset{7-2},0)));
2878*9880d681SAndroid Build Coastguard Worker
2879*9880d681SAndroid Build Coastguard Worker    let opExtentAlign = opcBits;
2880*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0011;
2881*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1110;
2882*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = opcBits;
2883*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = base;
2884*9880d681SAndroid Build Coastguard Worker    let Inst{13} = 0b0;
2885*9880d681SAndroid Build Coastguard Worker    let Inst{12-7} = offsetBits;
2886*9880d681SAndroid Build Coastguard Worker    let Inst{6-5} = memOpBits;
2887*9880d681SAndroid Build Coastguard Worker    let Inst{4-0} = delta;
2888*9880d681SAndroid Build Coastguard Worker}
2889*9880d681SAndroid Build Coastguard Worker
2890*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2891*9880d681SAndroid Build Coastguard Worker// Template class for MemOp instructions with the immediate value.
2892*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2893*9880d681SAndroid Build Coastguard Workerclass MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp,
2894*9880d681SAndroid Build Coastguard Worker                     string memOp, bits<2> memOpBits> :
2895*9880d681SAndroid Build Coastguard Worker      MEMInst_V4 <(outs),
2896*9880d681SAndroid Build Coastguard Worker                  (ins IntRegs:$base, ImmOp:$offset, u5Imm:$delta),
2897*9880d681SAndroid Build Coastguard Worker                  opc#"($base+#$offset)"#memOp#"#$delta"
2898*9880d681SAndroid Build Coastguard Worker                  #!if(memOpBits{1},")", ""), // clrbit, setbit - include ')'
2899*9880d681SAndroid Build Coastguard Worker                  []>,
2900*9880d681SAndroid Build Coastguard Worker                  Requires<[UseMEMOP]> {
2901*9880d681SAndroid Build Coastguard Worker
2902*9880d681SAndroid Build Coastguard Worker    bits<5> base;
2903*9880d681SAndroid Build Coastguard Worker    bits<5> delta;
2904*9880d681SAndroid Build Coastguard Worker    bits<32> offset;
2905*9880d681SAndroid Build Coastguard Worker    bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
2906*9880d681SAndroid Build Coastguard Worker
2907*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
2908*9880d681SAndroid Build Coastguard Worker                     !if (!eq(opcBits, 0b01), offset{6-1},
2909*9880d681SAndroid Build Coastguard Worker                     !if (!eq(opcBits, 0b10), offset{7-2},0)));
2910*9880d681SAndroid Build Coastguard Worker
2911*9880d681SAndroid Build Coastguard Worker    let opExtentAlign = opcBits;
2912*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0011;
2913*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1111;
2914*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = opcBits;
2915*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = base;
2916*9880d681SAndroid Build Coastguard Worker    let Inst{13} = 0b0;
2917*9880d681SAndroid Build Coastguard Worker    let Inst{12-7} = offsetBits;
2918*9880d681SAndroid Build Coastguard Worker    let Inst{6-5} = memOpBits;
2919*9880d681SAndroid Build Coastguard Worker    let Inst{4-0} = delta;
2920*9880d681SAndroid Build Coastguard Worker}
2921*9880d681SAndroid Build Coastguard Worker
2922*9880d681SAndroid Build Coastguard Worker// multiclass to define MemOp instructions with register operand.
2923*9880d681SAndroid Build Coastguard Workermulticlass MemOp_rr<string opc, bits<2> opcBits, Operand ImmOp> {
2924*9880d681SAndroid Build Coastguard Worker  def L4_add#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add
2925*9880d681SAndroid Build Coastguard Worker  def L4_sub#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub
2926*9880d681SAndroid Build Coastguard Worker  def L4_and#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and
2927*9880d681SAndroid Build Coastguard Worker  def L4_or#NAME  : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or
2928*9880d681SAndroid Build Coastguard Worker}
2929*9880d681SAndroid Build Coastguard Worker
2930*9880d681SAndroid Build Coastguard Worker// multiclass to define MemOp instructions with immediate Operand.
2931*9880d681SAndroid Build Coastguard Workermulticlass MemOp_ri<string opc, bits<2> opcBits, Operand ImmOp> {
2932*9880d681SAndroid Build Coastguard Worker  def L4_iadd#NAME : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >;
2933*9880d681SAndroid Build Coastguard Worker  def L4_isub#NAME : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >;
2934*9880d681SAndroid Build Coastguard Worker  def L4_iand#NAME : MemOp_ri_base<opc, opcBits, ImmOp, " = clrbit(", 0b10>;
2935*9880d681SAndroid Build Coastguard Worker  def L4_ior#NAME : MemOp_ri_base<opc, opcBits, ImmOp, " = setbit(", 0b11>;
2936*9880d681SAndroid Build Coastguard Worker}
2937*9880d681SAndroid Build Coastguard Worker
2938*9880d681SAndroid Build Coastguard Workermulticlass MemOp_base <string opc, bits<2> opcBits, Operand ImmOp> {
2939*9880d681SAndroid Build Coastguard Worker  defm _#NAME : MemOp_rr <opc, opcBits, ImmOp>;
2940*9880d681SAndroid Build Coastguard Worker  defm _#NAME : MemOp_ri <opc, opcBits, ImmOp>;
2941*9880d681SAndroid Build Coastguard Worker}
2942*9880d681SAndroid Build Coastguard Worker
2943*9880d681SAndroid Build Coastguard Worker// Define MemOp instructions.
2944*9880d681SAndroid Build Coastguard Workerlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0 in {
2945*9880d681SAndroid Build Coastguard Worker  let opExtentBits = 6, accessSize = ByteAccess in
2946*9880d681SAndroid Build Coastguard Worker  defm memopb_io : MemOp_base <"memb", 0b00, u6_0Ext>;
2947*9880d681SAndroid Build Coastguard Worker
2948*9880d681SAndroid Build Coastguard Worker  let opExtentBits = 7, accessSize = HalfWordAccess in
2949*9880d681SAndroid Build Coastguard Worker  defm memoph_io : MemOp_base <"memh", 0b01, u6_1Ext>;
2950*9880d681SAndroid Build Coastguard Worker
2951*9880d681SAndroid Build Coastguard Worker  let opExtentBits = 8, accessSize = WordAccess in
2952*9880d681SAndroid Build Coastguard Worker  defm memopw_io : MemOp_base <"memw", 0b10, u6_2Ext>;
2953*9880d681SAndroid Build Coastguard Worker}
2954*9880d681SAndroid Build Coastguard Worker
2955*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2956*9880d681SAndroid Build Coastguard Worker// Multiclass to define 'Def Pats' for ALU operations on the memory
2957*9880d681SAndroid Build Coastguard Worker// Here value used for the ALU operation is an immediate value.
2958*9880d681SAndroid Build Coastguard Worker// mem[bh](Rs+#0) += #U5
2959*9880d681SAndroid Build Coastguard Worker// mem[bh](Rs+#u6) += #U5
2960*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2961*9880d681SAndroid Build Coastguard Worker
2962*9880d681SAndroid Build Coastguard Workermulticlass MemOpi_u5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ImmPred,
2963*9880d681SAndroid Build Coastguard Worker                          InstHexagon MI, SDNode OpNode> {
2964*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 180 in
2965*9880d681SAndroid Build Coastguard Worker  def: Pat<(stOp (OpNode (ldOp IntRegs:$addr), u5ImmPred:$addend),
2966*9880d681SAndroid Build Coastguard Worker                  IntRegs:$addr),
2967*9880d681SAndroid Build Coastguard Worker            (MI IntRegs:$addr, 0, u5ImmPred:$addend)>;
2968*9880d681SAndroid Build Coastguard Worker
2969*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 190 in
2970*9880d681SAndroid Build Coastguard Worker  def: Pat<(stOp (OpNode (ldOp (add IntRegs:$base, ImmPred:$offset)),
2971*9880d681SAndroid Build Coastguard Worker                  u5ImmPred:$addend),
2972*9880d681SAndroid Build Coastguard Worker            (add IntRegs:$base, ImmPred:$offset)),
2973*9880d681SAndroid Build Coastguard Worker            (MI IntRegs:$base, ImmPred:$offset, u5ImmPred:$addend)>;
2974*9880d681SAndroid Build Coastguard Worker}
2975*9880d681SAndroid Build Coastguard Worker
2976*9880d681SAndroid Build Coastguard Workermulticlass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ImmPred,
2977*9880d681SAndroid Build Coastguard Worker                          InstHexagon addMI, InstHexagon subMI> {
2978*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_u5Pats<ldOp, stOp, ImmPred, addMI, add>;
2979*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_u5Pats<ldOp, stOp, ImmPred, subMI, sub>;
2980*9880d681SAndroid Build Coastguard Worker}
2981*9880d681SAndroid Build Coastguard Worker
2982*9880d681SAndroid Build Coastguard Workermulticlass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
2983*9880d681SAndroid Build Coastguard Worker  // Half Word
2984*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u31_1ImmPred,
2985*9880d681SAndroid Build Coastguard Worker                        L4_iadd_memoph_io, L4_isub_memoph_io>;
2986*9880d681SAndroid Build Coastguard Worker  // Byte
2987*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_u5ALUOp <ldOpByte, truncstorei8, u32ImmPred,
2988*9880d681SAndroid Build Coastguard Worker                        L4_iadd_memopb_io, L4_isub_memopb_io>;
2989*9880d681SAndroid Build Coastguard Worker}
2990*9880d681SAndroid Build Coastguard Worker
2991*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseMEMOP] in {
2992*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_u5ExtType<zextloadi8, zextloadi16>; // zero extend
2993*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_u5ExtType<sextloadi8, sextloadi16>; // sign extend
2994*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_u5ExtType<extloadi8,  extloadi16>;  // any extend
2995*9880d681SAndroid Build Coastguard Worker
2996*9880d681SAndroid Build Coastguard Worker  // Word
2997*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_u5ALUOp <load, store, u30_2ImmPred, L4_iadd_memopw_io,
2998*9880d681SAndroid Build Coastguard Worker                        L4_isub_memopw_io>;
2999*9880d681SAndroid Build Coastguard Worker}
3000*9880d681SAndroid Build Coastguard Worker
3001*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3002*9880d681SAndroid Build Coastguard Worker// multiclass to define 'Def Pats' for ALU operations on the memory.
3003*9880d681SAndroid Build Coastguard Worker// Here value used for the ALU operation is a negative value.
3004*9880d681SAndroid Build Coastguard Worker// mem[bh](Rs+#0) += #m5
3005*9880d681SAndroid Build Coastguard Worker// mem[bh](Rs+#u6) += #m5
3006*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3007*9880d681SAndroid Build Coastguard Worker
3008*9880d681SAndroid Build Coastguard Workermulticlass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ImmPred,
3009*9880d681SAndroid Build Coastguard Worker                          PatLeaf immPred, SDNodeXForm xformFunc,
3010*9880d681SAndroid Build Coastguard Worker                          InstHexagon MI> {
3011*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 190 in
3012*9880d681SAndroid Build Coastguard Worker  def: Pat<(stOp (add (ldOp IntRegs:$addr), immPred:$subend), IntRegs:$addr),
3013*9880d681SAndroid Build Coastguard Worker           (MI IntRegs:$addr, 0, (xformFunc immPred:$subend))>;
3014*9880d681SAndroid Build Coastguard Worker
3015*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 195 in
3016*9880d681SAndroid Build Coastguard Worker  def: Pat<(stOp (add (ldOp (add IntRegs:$base, ImmPred:$offset)),
3017*9880d681SAndroid Build Coastguard Worker                  immPred:$subend),
3018*9880d681SAndroid Build Coastguard Worker           (add IntRegs:$base, ImmPred:$offset)),
3019*9880d681SAndroid Build Coastguard Worker           (MI IntRegs:$base, ImmPred:$offset, (xformFunc immPred:$subend))>;
3020*9880d681SAndroid Build Coastguard Worker}
3021*9880d681SAndroid Build Coastguard Worker
3022*9880d681SAndroid Build Coastguard Workermulticlass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
3023*9880d681SAndroid Build Coastguard Worker  // Half Word
3024*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_m5Pats <ldOpHalf, truncstorei16, u31_1ImmPred, m5HImmPred,
3025*9880d681SAndroid Build Coastguard Worker                       MEMOPIMM_HALF, L4_isub_memoph_io>;
3026*9880d681SAndroid Build Coastguard Worker  // Byte
3027*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_m5Pats <ldOpByte, truncstorei8, u32ImmPred, m5BImmPred,
3028*9880d681SAndroid Build Coastguard Worker                       MEMOPIMM_BYTE, L4_isub_memopb_io>;
3029*9880d681SAndroid Build Coastguard Worker}
3030*9880d681SAndroid Build Coastguard Worker
3031*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseMEMOP] in {
3032*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_m5ExtType<zextloadi8, zextloadi16>; // zero extend
3033*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_m5ExtType<sextloadi8, sextloadi16>; // sign extend
3034*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_m5ExtType<extloadi8,  extloadi16>;  // any extend
3035*9880d681SAndroid Build Coastguard Worker
3036*9880d681SAndroid Build Coastguard Worker  // Word
3037*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_m5Pats <load, store, u30_2ImmPred, m5ImmPred,
3038*9880d681SAndroid Build Coastguard Worker                       MEMOPIMM, L4_isub_memopw_io>;
3039*9880d681SAndroid Build Coastguard Worker}
3040*9880d681SAndroid Build Coastguard Worker
3041*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3042*9880d681SAndroid Build Coastguard Worker// Multiclass to define 'def Pats' for bit operations on the memory.
3043*9880d681SAndroid Build Coastguard Worker// mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
3044*9880d681SAndroid Build Coastguard Worker// mem[bhw](Rs+#u6) = [clrbit|setbit](#U5)
3045*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3046*9880d681SAndroid Build Coastguard Worker
3047*9880d681SAndroid Build Coastguard Workermulticlass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred,
3048*9880d681SAndroid Build Coastguard Worker                     PatLeaf extPred, SDNodeXForm xformFunc, InstHexagon MI,
3049*9880d681SAndroid Build Coastguard Worker                     SDNode OpNode> {
3050*9880d681SAndroid Build Coastguard Worker
3051*9880d681SAndroid Build Coastguard Worker  // mem[bhw](Rs+#u6:[012]) = [clrbit|setbit](#U5)
3052*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 250 in
3053*9880d681SAndroid Build Coastguard Worker  def: Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
3054*9880d681SAndroid Build Coastguard Worker                  immPred:$bitend),
3055*9880d681SAndroid Build Coastguard Worker           (add IntRegs:$base, extPred:$offset)),
3056*9880d681SAndroid Build Coastguard Worker           (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$bitend))>;
3057*9880d681SAndroid Build Coastguard Worker
3058*9880d681SAndroid Build Coastguard Worker  // mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
3059*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 225 in
3060*9880d681SAndroid Build Coastguard Worker  def: Pat<(stOp (OpNode (ldOp IntRegs:$addr), immPred:$bitend), IntRegs:$addr),
3061*9880d681SAndroid Build Coastguard Worker           (MI IntRegs:$addr, 0, (xformFunc immPred:$bitend))>;
3062*9880d681SAndroid Build Coastguard Worker}
3063*9880d681SAndroid Build Coastguard Worker
3064*9880d681SAndroid Build Coastguard Workermulticlass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf> {
3065*9880d681SAndroid Build Coastguard Worker  // Byte - clrbit
3066*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u32ImmPred,
3067*9880d681SAndroid Build Coastguard Worker                       CLRMEMIMM_BYTE, L4_iand_memopb_io, and>;
3068*9880d681SAndroid Build Coastguard Worker  // Byte - setbit
3069*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred, u32ImmPred,
3070*9880d681SAndroid Build Coastguard Worker                       SETMEMIMM_BYTE, L4_ior_memopb_io, or>;
3071*9880d681SAndroid Build Coastguard Worker  // Half Word - clrbit
3072*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u31_1ImmPred,
3073*9880d681SAndroid Build Coastguard Worker                       CLRMEMIMM_SHORT, L4_iand_memoph_io, and>;
3074*9880d681SAndroid Build Coastguard Worker  // Half Word - setbit
3075*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u31_1ImmPred,
3076*9880d681SAndroid Build Coastguard Worker                       SETMEMIMM_SHORT, L4_ior_memoph_io, or>;
3077*9880d681SAndroid Build Coastguard Worker}
3078*9880d681SAndroid Build Coastguard Worker
3079*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseMEMOP] in {
3080*9880d681SAndroid Build Coastguard Worker  // mem[bh](Rs+#0) = [clrbit|setbit](#U5)
3081*9880d681SAndroid Build Coastguard Worker  // mem[bh](Rs+#u6:[01]) = [clrbit|setbit](#U5)
3082*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_bitExtType<zextloadi8, zextloadi16>; // zero extend
3083*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_bitExtType<sextloadi8, sextloadi16>; // sign extend
3084*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_bitExtType<extloadi8,  extloadi16>;  // any extend
3085*9880d681SAndroid Build Coastguard Worker
3086*9880d681SAndroid Build Coastguard Worker  // memw(Rs+#0) = [clrbit|setbit](#U5)
3087*9880d681SAndroid Build Coastguard Worker  // memw(Rs+#u6:2) = [clrbit|setbit](#U5)
3088*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_bitPats<load, store, Clr5ImmPred, u30_2ImmPred, CLRMEMIMM,
3089*9880d681SAndroid Build Coastguard Worker                       L4_iand_memopw_io, and>;
3090*9880d681SAndroid Build Coastguard Worker  defm: MemOpi_bitPats<load, store, Set5ImmPred, u30_2ImmPred, SETMEMIMM,
3091*9880d681SAndroid Build Coastguard Worker                       L4_ior_memopw_io, or>;
3092*9880d681SAndroid Build Coastguard Worker}
3093*9880d681SAndroid Build Coastguard Worker
3094*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3095*9880d681SAndroid Build Coastguard Worker// Multiclass to define 'def Pats' for ALU operations on the memory
3096*9880d681SAndroid Build Coastguard Worker// where addend is a register.
3097*9880d681SAndroid Build Coastguard Worker// mem[bhw](Rs+#0) [+-&|]= Rt
3098*9880d681SAndroid Build Coastguard Worker// mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
3099*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3100*9880d681SAndroid Build Coastguard Worker
3101*9880d681SAndroid Build Coastguard Workermulticlass MemOpr_Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred,
3102*9880d681SAndroid Build Coastguard Worker                        InstHexagon MI, SDNode OpNode> {
3103*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 141 in
3104*9880d681SAndroid Build Coastguard Worker  // mem[bhw](Rs+#0) [+-&|]= Rt
3105*9880d681SAndroid Build Coastguard Worker  def: Pat<(stOp (OpNode (ldOp IntRegs:$addr), (i32 IntRegs:$addend)),
3106*9880d681SAndroid Build Coastguard Worker                 IntRegs:$addr),
3107*9880d681SAndroid Build Coastguard Worker           (MI IntRegs:$addr, 0, (i32 IntRegs:$addend))>;
3108*9880d681SAndroid Build Coastguard Worker
3109*9880d681SAndroid Build Coastguard Worker  // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
3110*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 150 in
3111*9880d681SAndroid Build Coastguard Worker  def: Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
3112*9880d681SAndroid Build Coastguard Worker                  (i32 IntRegs:$orend)),
3113*9880d681SAndroid Build Coastguard Worker           (add IntRegs:$base, extPred:$offset)),
3114*9880d681SAndroid Build Coastguard Worker           (MI IntRegs:$base, extPred:$offset, (i32 IntRegs:$orend))>;
3115*9880d681SAndroid Build Coastguard Worker}
3116*9880d681SAndroid Build Coastguard Worker
3117*9880d681SAndroid Build Coastguard Workermulticlass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf extPred,
3118*9880d681SAndroid Build Coastguard Worker                        InstHexagon addMI, InstHexagon subMI,
3119*9880d681SAndroid Build Coastguard Worker                        InstHexagon andMI, InstHexagon orMI> {
3120*9880d681SAndroid Build Coastguard Worker  defm: MemOpr_Pats <ldOp, stOp, extPred, addMI, add>;
3121*9880d681SAndroid Build Coastguard Worker  defm: MemOpr_Pats <ldOp, stOp, extPred, subMI, sub>;
3122*9880d681SAndroid Build Coastguard Worker  defm: MemOpr_Pats <ldOp, stOp, extPred, andMI, and>;
3123*9880d681SAndroid Build Coastguard Worker  defm: MemOpr_Pats <ldOp, stOp, extPred, orMI,  or>;
3124*9880d681SAndroid Build Coastguard Worker}
3125*9880d681SAndroid Build Coastguard Worker
3126*9880d681SAndroid Build Coastguard Workermulticlass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
3127*9880d681SAndroid Build Coastguard Worker  // Half Word
3128*9880d681SAndroid Build Coastguard Worker  defm: MemOPr_ALUOp <ldOpHalf, truncstorei16, u31_1ImmPred,
3129*9880d681SAndroid Build Coastguard Worker                      L4_add_memoph_io, L4_sub_memoph_io,
3130*9880d681SAndroid Build Coastguard Worker                      L4_and_memoph_io, L4_or_memoph_io>;
3131*9880d681SAndroid Build Coastguard Worker  // Byte
3132*9880d681SAndroid Build Coastguard Worker  defm: MemOPr_ALUOp <ldOpByte, truncstorei8, u32ImmPred,
3133*9880d681SAndroid Build Coastguard Worker                      L4_add_memopb_io, L4_sub_memopb_io,
3134*9880d681SAndroid Build Coastguard Worker                      L4_and_memopb_io, L4_or_memopb_io>;
3135*9880d681SAndroid Build Coastguard Worker}
3136*9880d681SAndroid Build Coastguard Worker
3137*9880d681SAndroid Build Coastguard Worker// Define 'def Pats' for MemOps with register addend.
3138*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseMEMOP] in {
3139*9880d681SAndroid Build Coastguard Worker  // Byte, Half Word
3140*9880d681SAndroid Build Coastguard Worker  defm: MemOPr_ExtType<zextloadi8, zextloadi16>; // zero extend
3141*9880d681SAndroid Build Coastguard Worker  defm: MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend
3142*9880d681SAndroid Build Coastguard Worker  defm: MemOPr_ExtType<extloadi8,  extloadi16>;  // any extend
3143*9880d681SAndroid Build Coastguard Worker  // Word
3144*9880d681SAndroid Build Coastguard Worker  defm: MemOPr_ALUOp <load, store, u30_2ImmPred, L4_add_memopw_io,
3145*9880d681SAndroid Build Coastguard Worker                      L4_sub_memopw_io, L4_and_memopw_io, L4_or_memopw_io>;
3146*9880d681SAndroid Build Coastguard Worker}
3147*9880d681SAndroid Build Coastguard Worker
3148*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3149*9880d681SAndroid Build Coastguard Worker// XTYPE/PRED +
3150*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3151*9880d681SAndroid Build Coastguard Worker
3152*9880d681SAndroid Build Coastguard Worker// Hexagon V4 only supports these flavors of byte/half compare instructions:
3153*9880d681SAndroid Build Coastguard Worker// EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by
3154*9880d681SAndroid Build Coastguard Worker// hardware. However, compiler can still implement these patterns through
3155*9880d681SAndroid Build Coastguard Worker// appropriate patterns combinations based on current implemented patterns.
3156*9880d681SAndroid Build Coastguard Worker// The implemented patterns are: EQ/GT/GTU.
3157*9880d681SAndroid Build Coastguard Worker// Missing patterns are: GE/GEU/LT/LTU/LE/LEU.
3158*9880d681SAndroid Build Coastguard Worker
3159*9880d681SAndroid Build Coastguard Worker// Following instruction is not being extended as it results into the
3160*9880d681SAndroid Build Coastguard Worker// incorrect code for negative numbers.
3161*9880d681SAndroid Build Coastguard Worker// Pd=cmpb.eq(Rs,#u8)
3162*9880d681SAndroid Build Coastguard Worker
3163*9880d681SAndroid Build Coastguard Worker// p=!cmp.eq(r1,#s10)
3164*9880d681SAndroid Build Coastguard Workerdef C4_cmpneqi  : T_CMP <"cmp.eq",  0b00, 1, s10Ext>;
3165*9880d681SAndroid Build Coastguard Workerdef C4_cmpltei  : T_CMP <"cmp.gt",  0b01, 1, s10Ext>;
3166*9880d681SAndroid Build Coastguard Workerdef C4_cmplteui : T_CMP <"cmp.gtu", 0b10, 1, u9Ext>;
3167*9880d681SAndroid Build Coastguard Worker
3168*9880d681SAndroid Build Coastguard Workerdef : T_CMP_pat <C4_cmpneqi,  setne,  s32ImmPred>;
3169*9880d681SAndroid Build Coastguard Workerdef : T_CMP_pat <C4_cmpltei,  setle,  s32ImmPred>;
3170*9880d681SAndroid Build Coastguard Workerdef : T_CMP_pat <C4_cmplteui, setule, u9ImmPred>;
3171*9880d681SAndroid Build Coastguard Worker
3172*9880d681SAndroid Build Coastguard Worker// rs <= rt -> !(rs > rt).
3173*9880d681SAndroid Build Coastguard Worker/*
3174*9880d681SAndroid Build Coastguard Workerdef: Pat<(i1 (setle (i32 IntRegs:$src1), s32ImmPred:$src2)),
3175*9880d681SAndroid Build Coastguard Worker         (C2_not (C2_cmpgti IntRegs:$src1, s32ImmPred:$src2))>;
3176*9880d681SAndroid Build Coastguard Worker//         (C4_cmpltei IntRegs:$src1, s32ImmPred:$src2)>;
3177*9880d681SAndroid Build Coastguard Worker*/
3178*9880d681SAndroid Build Coastguard Worker// Map cmplt(Rs, Imm) -> !cmpgt(Rs, Imm-1).
3179*9880d681SAndroid Build Coastguard Workerdef: Pat<(i1 (setlt (i32 IntRegs:$src1), s32ImmPred:$src2)),
3180*9880d681SAndroid Build Coastguard Worker         (C4_cmpltei IntRegs:$src1, (DEC_CONST_SIGNED s32ImmPred:$src2))>;
3181*9880d681SAndroid Build Coastguard Worker
3182*9880d681SAndroid Build Coastguard Worker// rs != rt -> !(rs == rt).
3183*9880d681SAndroid Build Coastguard Workerdef: Pat<(i1 (setne (i32 IntRegs:$src1), s32ImmPred:$src2)),
3184*9880d681SAndroid Build Coastguard Worker         (C4_cmpneqi IntRegs:$src1, s32ImmPred:$src2)>;
3185*9880d681SAndroid Build Coastguard Worker
3186*9880d681SAndroid Build Coastguard Worker// SDNode for converting immediate C to C-1.
3187*9880d681SAndroid Build Coastguard Workerdef DEC_CONST_BYTE : SDNodeXForm<imm, [{
3188*9880d681SAndroid Build Coastguard Worker   // Return the byte immediate const-1 as an SDNode.
3189*9880d681SAndroid Build Coastguard Worker   int32_t imm = N->getSExtValue();
3190*9880d681SAndroid Build Coastguard Worker   return XformU7ToU7M1Imm(imm, SDLoc(N));
3191*9880d681SAndroid Build Coastguard Worker}]>;
3192*9880d681SAndroid Build Coastguard Worker
3193*9880d681SAndroid Build Coastguard Worker// For the sequence
3194*9880d681SAndroid Build Coastguard Worker//   zext( setult ( and(Rs, 255), u8))
3195*9880d681SAndroid Build Coastguard Worker// Use the isdigit transformation below
3196*9880d681SAndroid Build Coastguard Worker
3197*9880d681SAndroid Build Coastguard Worker// Generate code of the form 'C2_muxii(cmpbgtui(Rdd, C-1),0,1)'
3198*9880d681SAndroid Build Coastguard Worker// for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
3199*9880d681SAndroid Build Coastguard Worker// The isdigit transformation relies on two 'clever' aspects:
3200*9880d681SAndroid Build Coastguard Worker// 1) The data type is unsigned which allows us to eliminate a zero test after
3201*9880d681SAndroid Build Coastguard Worker//    biasing the expression by 48. We are depending on the representation of
3202*9880d681SAndroid Build Coastguard Worker//    the unsigned types, and semantics.
3203*9880d681SAndroid Build Coastguard Worker// 2) The front end has converted <= 9 into < 10 on entry to LLVM
3204*9880d681SAndroid Build Coastguard Worker//
3205*9880d681SAndroid Build Coastguard Worker// For the C code:
3206*9880d681SAndroid Build Coastguard Worker//   retval = ((c>='0') & (c<='9')) ? 1 : 0;
3207*9880d681SAndroid Build Coastguard Worker// The code is transformed upstream of llvm into
3208*9880d681SAndroid Build Coastguard Worker//   retval = (c-48) < 10 ? 1 : 0;
3209*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 139 in
3210*9880d681SAndroid Build Coastguard Workerdef: Pat<(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)),
3211*9880d681SAndroid Build Coastguard Worker                         u7StrictPosImmPred:$src2)))),
3212*9880d681SAndroid Build Coastguard Worker         (C2_muxii (A4_cmpbgtui IntRegs:$src1,
3213*9880d681SAndroid Build Coastguard Worker                    (DEC_CONST_BYTE u7StrictPosImmPred:$src2)),
3214*9880d681SAndroid Build Coastguard Worker          0, 1)>;
3215*9880d681SAndroid Build Coastguard Worker
3216*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3217*9880d681SAndroid Build Coastguard Worker// XTYPE/PRED -
3218*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3219*9880d681SAndroid Build Coastguard Worker
3220*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3221*9880d681SAndroid Build Coastguard Worker// Multiclass for DeallocReturn
3222*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3223*9880d681SAndroid Build Coastguard Workerclass L4_RETURN<string mnemonic, bit isNot, bit isPredNew, bit isTak>
3224*9880d681SAndroid Build Coastguard Worker  : LD0Inst<(outs), (ins PredRegs:$src),
3225*9880d681SAndroid Build Coastguard Worker  !if(isNot, "if (!$src", "if ($src")#
3226*9880d681SAndroid Build Coastguard Worker  !if(isPredNew, ".new) ", ") ")#mnemonic#
3227*9880d681SAndroid Build Coastguard Worker  !if(isPredNew, #!if(isTak,":t", ":nt"),""),
3228*9880d681SAndroid Build Coastguard Worker  [], "", LD_tc_3or4stall_SLOT0> {
3229*9880d681SAndroid Build Coastguard Worker
3230*9880d681SAndroid Build Coastguard Worker    bits<2> src;
3231*9880d681SAndroid Build Coastguard Worker    let BaseOpcode = "L4_RETURN";
3232*9880d681SAndroid Build Coastguard Worker    let isPredicatedFalse = isNot;
3233*9880d681SAndroid Build Coastguard Worker    let isPredicatedNew = isPredNew;
3234*9880d681SAndroid Build Coastguard Worker    let isTaken = isTak;
3235*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1001;
3236*9880d681SAndroid Build Coastguard Worker
3237*9880d681SAndroid Build Coastguard Worker    let Inst{27-16} = 0b011000011110;
3238*9880d681SAndroid Build Coastguard Worker
3239*9880d681SAndroid Build Coastguard Worker    let Inst{13} = isNot;
3240*9880d681SAndroid Build Coastguard Worker    let Inst{12} = isTak;
3241*9880d681SAndroid Build Coastguard Worker    let Inst{11} = isPredNew;
3242*9880d681SAndroid Build Coastguard Worker    let Inst{10} = 0b0;
3243*9880d681SAndroid Build Coastguard Worker    let Inst{9-8} = src;
3244*9880d681SAndroid Build Coastguard Worker    let Inst{4-0} = 0b11110;
3245*9880d681SAndroid Build Coastguard Worker  }
3246*9880d681SAndroid Build Coastguard Worker
3247*9880d681SAndroid Build Coastguard Worker// Produce all predicated forms, p, !p, p.new, !p.new, :t, :nt
3248*9880d681SAndroid Build Coastguard Workermulticlass L4_RETURN_PRED<string mnemonic, bit PredNot> {
3249*9880d681SAndroid Build Coastguard Worker  let isPredicated = 1 in {
3250*9880d681SAndroid Build Coastguard Worker    def _#NAME# : L4_RETURN <mnemonic, PredNot, 0, 1>;
3251*9880d681SAndroid Build Coastguard Worker    def _#NAME#new_pnt : L4_RETURN <mnemonic, PredNot, 1, 0>;
3252*9880d681SAndroid Build Coastguard Worker    def _#NAME#new_pt : L4_RETURN <mnemonic, PredNot, 1, 1>;
3253*9880d681SAndroid Build Coastguard Worker  }
3254*9880d681SAndroid Build Coastguard Worker}
3255*9880d681SAndroid Build Coastguard Worker
3256*9880d681SAndroid Build Coastguard Workermulticlass LD_MISC_L4_RETURN<string mnemonic> {
3257*9880d681SAndroid Build Coastguard Worker  let isBarrier = 1, isPredicable = 1 in
3258*9880d681SAndroid Build Coastguard Worker    def NAME : LD0Inst <(outs), (ins), mnemonic, [], "",
3259*9880d681SAndroid Build Coastguard Worker                        LD_tc_3or4stall_SLOT0> {
3260*9880d681SAndroid Build Coastguard Worker      let BaseOpcode = "L4_RETURN";
3261*9880d681SAndroid Build Coastguard Worker      let IClass = 0b1001;
3262*9880d681SAndroid Build Coastguard Worker      let Inst{27-16} = 0b011000011110;
3263*9880d681SAndroid Build Coastguard Worker      let Inst{13-10} = 0b0000;
3264*9880d681SAndroid Build Coastguard Worker      let Inst{4-0} = 0b11110;
3265*9880d681SAndroid Build Coastguard Worker    }
3266*9880d681SAndroid Build Coastguard Worker  defm t : L4_RETURN_PRED<mnemonic, 0 >;
3267*9880d681SAndroid Build Coastguard Worker  defm f : L4_RETURN_PRED<mnemonic, 1 >;
3268*9880d681SAndroid Build Coastguard Worker}
3269*9880d681SAndroid Build Coastguard Worker
3270*9880d681SAndroid Build Coastguard Workerlet isReturn = 1, isTerminator = 1,
3271*9880d681SAndroid Build Coastguard Worker    Defs = [R29, R30, R31, PC], Uses = [R30], hasSideEffects = 0 in
3272*9880d681SAndroid Build Coastguard Workerdefm L4_return: LD_MISC_L4_RETURN <"dealloc_return">, PredNewRel;
3273*9880d681SAndroid Build Coastguard Worker
3274*9880d681SAndroid Build Coastguard Worker// Restore registers and dealloc return function call.
3275*9880d681SAndroid Build Coastguard Workerlet isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
3276*9880d681SAndroid Build Coastguard Worker    Defs = [R29, R30, R31, PC], isPredicable = 0, isAsmParserOnly = 1 in {
3277*9880d681SAndroid Build Coastguard Worker  def RESTORE_DEALLOC_RET_JMP_V4 : T_JMP<"">;
3278*9880d681SAndroid Build Coastguard Worker  let isExtended = 1, opExtendable = 0 in
3279*9880d681SAndroid Build Coastguard Worker  def RESTORE_DEALLOC_RET_JMP_V4_EXT : T_JMP<"">;
3280*9880d681SAndroid Build Coastguard Worker
3281*9880d681SAndroid Build Coastguard Worker  let Defs = [R14, R15, R28, R29, R30, R31, PC] in {
3282*9880d681SAndroid Build Coastguard Worker    def RESTORE_DEALLOC_RET_JMP_V4_PIC : T_JMP<"">;
3283*9880d681SAndroid Build Coastguard Worker
3284*9880d681SAndroid Build Coastguard Worker    let isExtended = 1, opExtendable = 0 in
3285*9880d681SAndroid Build Coastguard Worker    def RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC : T_JMP<"">;
3286*9880d681SAndroid Build Coastguard Worker  }
3287*9880d681SAndroid Build Coastguard Worker}
3288*9880d681SAndroid Build Coastguard Worker
3289*9880d681SAndroid Build Coastguard Worker// Restore registers and dealloc frame before a tail call.
3290*9880d681SAndroid Build Coastguard Workerlet isCall = 1, Defs = [R29, R30, R31, PC], isAsmParserOnly = 1 in {
3291*9880d681SAndroid Build Coastguard Worker  def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : T_Call<0, "">, PredRel;
3292*9880d681SAndroid Build Coastguard Worker
3293*9880d681SAndroid Build Coastguard Worker  let isExtended = 1, opExtendable = 0 in
3294*9880d681SAndroid Build Coastguard Worker  def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT : T_Call<0, "">, PredRel;
3295*9880d681SAndroid Build Coastguard Worker
3296*9880d681SAndroid Build Coastguard Worker  let Defs = [R14, R15, R28, R29, R30, R31, PC] in {
3297*9880d681SAndroid Build Coastguard Worker    def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC : T_Call<0, "">, PredRel;
3298*9880d681SAndroid Build Coastguard Worker
3299*9880d681SAndroid Build Coastguard Worker    let isExtended = 1, opExtendable = 0 in
3300*9880d681SAndroid Build Coastguard Worker    def RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC : T_Call<0, "">, PredRel;
3301*9880d681SAndroid Build Coastguard Worker  }
3302*9880d681SAndroid Build Coastguard Worker}
3303*9880d681SAndroid Build Coastguard Worker
3304*9880d681SAndroid Build Coastguard Worker// Save registers function call.
3305*9880d681SAndroid Build Coastguard Workerlet isCall = 1, Uses = [R29, R31], isAsmParserOnly = 1 in {
3306*9880d681SAndroid Build Coastguard Worker  def SAVE_REGISTERS_CALL_V4 : T_Call<0, "">, PredRel;
3307*9880d681SAndroid Build Coastguard Worker
3308*9880d681SAndroid Build Coastguard Worker  let isExtended = 1, opExtendable = 0 in
3309*9880d681SAndroid Build Coastguard Worker  def SAVE_REGISTERS_CALL_V4_EXT : T_Call<0, "">, PredRel;
3310*9880d681SAndroid Build Coastguard Worker
3311*9880d681SAndroid Build Coastguard Worker  let Defs = [P0] in
3312*9880d681SAndroid Build Coastguard Worker  def SAVE_REGISTERS_CALL_V4STK : T_Call<0, "">, PredRel;
3313*9880d681SAndroid Build Coastguard Worker
3314*9880d681SAndroid Build Coastguard Worker  let Defs = [P0], isExtended = 1, opExtendable = 0 in
3315*9880d681SAndroid Build Coastguard Worker  def SAVE_REGISTERS_CALL_V4STK_EXT : T_Call<0, "">, PredRel;
3316*9880d681SAndroid Build Coastguard Worker
3317*9880d681SAndroid Build Coastguard Worker  let Defs = [R14, R15, R28] in
3318*9880d681SAndroid Build Coastguard Worker  def SAVE_REGISTERS_CALL_V4_PIC : T_Call<0, "">, PredRel;
3319*9880d681SAndroid Build Coastguard Worker
3320*9880d681SAndroid Build Coastguard Worker  let Defs = [R14, R15, R28], isExtended = 1, opExtendable = 0 in
3321*9880d681SAndroid Build Coastguard Worker  def SAVE_REGISTERS_CALL_V4_EXT_PIC : T_Call<0, "">, PredRel;
3322*9880d681SAndroid Build Coastguard Worker
3323*9880d681SAndroid Build Coastguard Worker  let Defs = [R14, R15, R28, P0] in
3324*9880d681SAndroid Build Coastguard Worker  def SAVE_REGISTERS_CALL_V4STK_PIC : T_Call<0, "">, PredRel;
3325*9880d681SAndroid Build Coastguard Worker
3326*9880d681SAndroid Build Coastguard Worker  let Defs = [R14, R15, R28, P0], isExtended = 1, opExtendable = 0 in
3327*9880d681SAndroid Build Coastguard Worker  def SAVE_REGISTERS_CALL_V4STK_EXT_PIC : T_Call<0, "">, PredRel;
3328*9880d681SAndroid Build Coastguard Worker}
3329*9880d681SAndroid Build Coastguard Worker
3330*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3331*9880d681SAndroid Build Coastguard Worker// Template class for non predicated store instructions with
3332*9880d681SAndroid Build Coastguard Worker// GP-Relative or absolute addressing.
3333*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3334*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, isPredicable = 1 in
3335*9880d681SAndroid Build Coastguard Workerclass T_StoreAbsGP <string mnemonic, RegisterClass RC, Operand ImmOp,
3336*9880d681SAndroid Build Coastguard Worker                    bits<2>MajOp, bit isAbs, bit isHalf>
3337*9880d681SAndroid Build Coastguard Worker  : STInst<(outs), (ins ImmOp:$addr, RC:$src),
3338*9880d681SAndroid Build Coastguard Worker  mnemonic # "(#$addr) = $src"#!if(isHalf, ".h",""),
3339*9880d681SAndroid Build Coastguard Worker  [], "", V2LDST_tc_st_SLOT01> {
3340*9880d681SAndroid Build Coastguard Worker    bits<19> addr;
3341*9880d681SAndroid Build Coastguard Worker    bits<5> src;
3342*9880d681SAndroid Build Coastguard Worker    bits<16> offsetBits;
3343*9880d681SAndroid Build Coastguard Worker
3344*9880d681SAndroid Build Coastguard Worker    string ImmOpStr = !cast<string>(ImmOp);
3345*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(ImmOpStr, "u16_3Imm"), addr{18-3},
3346*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2},
3347*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1},
3348*9880d681SAndroid Build Coastguard Worker                                      /* u16_0Imm */ addr{15-0})));
3349*9880d681SAndroid Build Coastguard Worker    // Store upper-half and store doubleword cannot be NV.
3350*9880d681SAndroid Build Coastguard Worker    let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isHalf,0,1));
3351*9880d681SAndroid Build Coastguard Worker    let Uses = !if (isAbs, [], [GP]);
3352*9880d681SAndroid Build Coastguard Worker
3353*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0100;
3354*9880d681SAndroid Build Coastguard Worker    let Inst{27} = 1;
3355*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = offsetBits{15-14};
3356*9880d681SAndroid Build Coastguard Worker    let Inst{24}    = 0b0;
3357*9880d681SAndroid Build Coastguard Worker    let Inst{23-22} = MajOp;
3358*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = isHalf;
3359*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = offsetBits{13-9};
3360*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = offsetBits{8};
3361*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = src;
3362*9880d681SAndroid Build Coastguard Worker    let Inst{7-0}   = offsetBits{7-0};
3363*9880d681SAndroid Build Coastguard Worker  }
3364*9880d681SAndroid Build Coastguard Worker
3365*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3366*9880d681SAndroid Build Coastguard Worker// Template class for predicated store instructions with
3367*9880d681SAndroid Build Coastguard Worker// GP-Relative or absolute addressing.
3368*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3369*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, isPredicated = 1, opExtentBits = 6, opExtendable = 1 in
3370*9880d681SAndroid Build Coastguard Workerclass T_StoreAbs_Pred <string mnemonic, RegisterClass RC, bits<2> MajOp,
3371*9880d681SAndroid Build Coastguard Worker                       bit isHalf, bit isNot, bit isNew>
3372*9880d681SAndroid Build Coastguard Worker  : STInst<(outs), (ins PredRegs:$src1, u32MustExt:$absaddr, RC: $src2),
3373*9880d681SAndroid Build Coastguard Worker  !if(isNot, "if (!$src1", "if ($src1")#!if(isNew, ".new) ",
3374*9880d681SAndroid Build Coastguard Worker  ") ")#mnemonic#"(#$absaddr) = $src2"#!if(isHalf, ".h",""),
3375*9880d681SAndroid Build Coastguard Worker  [], "", ST_tc_st_SLOT01>, AddrModeRel {
3376*9880d681SAndroid Build Coastguard Worker    bits<2> src1;
3377*9880d681SAndroid Build Coastguard Worker    bits<6> absaddr;
3378*9880d681SAndroid Build Coastguard Worker    bits<5> src2;
3379*9880d681SAndroid Build Coastguard Worker
3380*9880d681SAndroid Build Coastguard Worker    let isPredicatedNew = isNew;
3381*9880d681SAndroid Build Coastguard Worker    let isPredicatedFalse = isNot;
3382*9880d681SAndroid Build Coastguard Worker    // Store upper-half and store doubleword cannot be NV.
3383*9880d681SAndroid Build Coastguard Worker    let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isHalf,0,1));
3384*9880d681SAndroid Build Coastguard Worker
3385*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1010;
3386*9880d681SAndroid Build Coastguard Worker
3387*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1111;
3388*9880d681SAndroid Build Coastguard Worker    let Inst{23-22} = MajOp;
3389*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = isHalf;
3390*9880d681SAndroid Build Coastguard Worker    let Inst{17-16} = absaddr{5-4};
3391*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = isNew;
3392*9880d681SAndroid Build Coastguard Worker    let Inst{12-8}  = src2;
3393*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = 0b1;
3394*9880d681SAndroid Build Coastguard Worker    let Inst{6-3}   = absaddr{3-0};
3395*9880d681SAndroid Build Coastguard Worker    let Inst{2}     = isNot;
3396*9880d681SAndroid Build Coastguard Worker    let Inst{1-0}   = src1;
3397*9880d681SAndroid Build Coastguard Worker  }
3398*9880d681SAndroid Build Coastguard Worker
3399*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3400*9880d681SAndroid Build Coastguard Worker// Template class for predicated store instructions with absolute addressing.
3401*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3402*9880d681SAndroid Build Coastguard Workerclass T_StoreAbs <string mnemonic, RegisterClass RC, Operand ImmOp,
3403*9880d681SAndroid Build Coastguard Worker                 bits<2> MajOp, bit isHalf>
3404*9880d681SAndroid Build Coastguard Worker  : T_StoreAbsGP <mnemonic, RC, u32MustExt, MajOp, 1, isHalf>,
3405*9880d681SAndroid Build Coastguard Worker                  AddrModeRel {
3406*9880d681SAndroid Build Coastguard Worker  string ImmOpStr = !cast<string>(ImmOp);
3407*9880d681SAndroid Build Coastguard Worker  let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19,
3408*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "u16_2Imm"), 18,
3409*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "u16_1Imm"), 17,
3410*9880d681SAndroid Build Coastguard Worker                                      /* u16_0Imm */ 16)));
3411*9880d681SAndroid Build Coastguard Worker
3412*9880d681SAndroid Build Coastguard Worker  let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3,
3413*9880d681SAndroid Build Coastguard Worker                      !if (!eq(ImmOpStr, "u16_2Imm"), 2,
3414*9880d681SAndroid Build Coastguard Worker                      !if (!eq(ImmOpStr, "u16_1Imm"), 1,
3415*9880d681SAndroid Build Coastguard Worker                                       /* u16_0Imm */ 0)));
3416*9880d681SAndroid Build Coastguard Worker}
3417*9880d681SAndroid Build Coastguard Worker
3418*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3419*9880d681SAndroid Build Coastguard Worker// Multiclass for store instructions with absolute addressing.
3420*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3421*9880d681SAndroid Build Coastguard Workerlet addrMode = Absolute, isExtended = 1 in
3422*9880d681SAndroid Build Coastguard Workermulticlass ST_Abs<string mnemonic, string CextOp, RegisterClass RC,
3423*9880d681SAndroid Build Coastguard Worker                  Operand ImmOp, bits<2> MajOp, bit isHalf = 0> {
3424*9880d681SAndroid Build Coastguard Worker  let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3425*9880d681SAndroid Build Coastguard Worker    let opExtendable = 0, isPredicable = 1 in
3426*9880d681SAndroid Build Coastguard Worker    def S2_#NAME#abs : T_StoreAbs <mnemonic, RC, ImmOp, MajOp, isHalf>;
3427*9880d681SAndroid Build Coastguard Worker
3428*9880d681SAndroid Build Coastguard Worker    // Predicated
3429*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#t_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 0, 0>;
3430*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#f_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 1, 0>;
3431*9880d681SAndroid Build Coastguard Worker
3432*9880d681SAndroid Build Coastguard Worker    // .new Predicated
3433*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#tnew_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 0, 1>;
3434*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#fnew_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 1, 1>;
3435*9880d681SAndroid Build Coastguard Worker  }
3436*9880d681SAndroid Build Coastguard Worker}
3437*9880d681SAndroid Build Coastguard Worker
3438*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3439*9880d681SAndroid Build Coastguard Worker// Template class for non predicated new-value store instructions with
3440*9880d681SAndroid Build Coastguard Worker// GP-Relative or absolute addressing.
3441*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3442*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, isPredicable = 1, mayStore = 1, isNVStore = 1,
3443*9880d681SAndroid Build Coastguard Worker    isNewValue = 1, opNewValue = 1 in
3444*9880d681SAndroid Build Coastguard Workerclass T_StoreAbsGP_NV <string mnemonic, Operand ImmOp, bits<2>MajOp>
3445*9880d681SAndroid Build Coastguard Worker  : NVInst_V4<(outs), (ins ImmOp:$addr, IntRegs:$src),
3446*9880d681SAndroid Build Coastguard Worker  mnemonic #"(#$addr) = $src.new",
3447*9880d681SAndroid Build Coastguard Worker  [], "", V2LDST_tc_st_SLOT0> {
3448*9880d681SAndroid Build Coastguard Worker    bits<19> addr;
3449*9880d681SAndroid Build Coastguard Worker    bits<3> src;
3450*9880d681SAndroid Build Coastguard Worker    bits<16> offsetBits;
3451*9880d681SAndroid Build Coastguard Worker
3452*9880d681SAndroid Build Coastguard Worker    string ImmOpStr = !cast<string>(ImmOp);
3453*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(ImmOpStr, "u16_3Imm"), addr{18-3},
3454*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2},
3455*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1},
3456*9880d681SAndroid Build Coastguard Worker                                      /* u16_0Imm */ addr{15-0})));
3457*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0100;
3458*9880d681SAndroid Build Coastguard Worker
3459*9880d681SAndroid Build Coastguard Worker    let Inst{27} = 1;
3460*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = offsetBits{15-14};
3461*9880d681SAndroid Build Coastguard Worker    let Inst{24-21} = 0b0101;
3462*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = offsetBits{13-9};
3463*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = offsetBits{8};
3464*9880d681SAndroid Build Coastguard Worker    let Inst{12-11} = MajOp;
3465*9880d681SAndroid Build Coastguard Worker    let Inst{10-8}  = src;
3466*9880d681SAndroid Build Coastguard Worker    let Inst{7-0}   = offsetBits{7-0};
3467*9880d681SAndroid Build Coastguard Worker  }
3468*9880d681SAndroid Build Coastguard Worker
3469*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3470*9880d681SAndroid Build Coastguard Worker// Template class for predicated new-value store instructions with
3471*9880d681SAndroid Build Coastguard Worker// absolute addressing.
3472*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3473*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, isPredicated = 1, mayStore = 1, isNVStore = 1,
3474*9880d681SAndroid Build Coastguard Worker    isNewValue = 1, opNewValue = 2, opExtentBits = 6, opExtendable = 1 in
3475*9880d681SAndroid Build Coastguard Workerclass T_StoreAbs_NV_Pred <string mnemonic, bits<2> MajOp, bit isNot, bit isNew>
3476*9880d681SAndroid Build Coastguard Worker  : NVInst_V4<(outs), (ins PredRegs:$src1, u32MustExt:$absaddr, IntRegs:$src2),
3477*9880d681SAndroid Build Coastguard Worker  !if(isNot, "if (!$src1", "if ($src1")#!if(isNew, ".new) ",
3478*9880d681SAndroid Build Coastguard Worker  ") ")#mnemonic#"(#$absaddr) = $src2.new",
3479*9880d681SAndroid Build Coastguard Worker  [], "", ST_tc_st_SLOT0>, AddrModeRel {
3480*9880d681SAndroid Build Coastguard Worker    bits<2> src1;
3481*9880d681SAndroid Build Coastguard Worker    bits<6> absaddr;
3482*9880d681SAndroid Build Coastguard Worker    bits<3> src2;
3483*9880d681SAndroid Build Coastguard Worker
3484*9880d681SAndroid Build Coastguard Worker    let isPredicatedNew = isNew;
3485*9880d681SAndroid Build Coastguard Worker    let isPredicatedFalse = isNot;
3486*9880d681SAndroid Build Coastguard Worker
3487*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1010;
3488*9880d681SAndroid Build Coastguard Worker
3489*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1111;
3490*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = 0b101;
3491*9880d681SAndroid Build Coastguard Worker    let Inst{17-16} = absaddr{5-4};
3492*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = isNew;
3493*9880d681SAndroid Build Coastguard Worker    let Inst{12-11} = MajOp;
3494*9880d681SAndroid Build Coastguard Worker    let Inst{10-8}  = src2;
3495*9880d681SAndroid Build Coastguard Worker    let Inst{7}     = 0b1;
3496*9880d681SAndroid Build Coastguard Worker    let Inst{6-3}   = absaddr{3-0};
3497*9880d681SAndroid Build Coastguard Worker    let Inst{2}     = isNot;
3498*9880d681SAndroid Build Coastguard Worker    let Inst{1-0}   = src1;
3499*9880d681SAndroid Build Coastguard Worker}
3500*9880d681SAndroid Build Coastguard Worker
3501*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3502*9880d681SAndroid Build Coastguard Worker// Template class for non-predicated new-value store instructions with
3503*9880d681SAndroid Build Coastguard Worker// absolute addressing.
3504*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3505*9880d681SAndroid Build Coastguard Workerclass T_StoreAbs_NV <string mnemonic, Operand ImmOp, bits<2> MajOp>
3506*9880d681SAndroid Build Coastguard Worker  : T_StoreAbsGP_NV <mnemonic, u32MustExt, MajOp>, AddrModeRel {
3507*9880d681SAndroid Build Coastguard Worker
3508*9880d681SAndroid Build Coastguard Worker  string ImmOpStr = !cast<string>(ImmOp);
3509*9880d681SAndroid Build Coastguard Worker  let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19,
3510*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "u16_2Imm"), 18,
3511*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "u16_1Imm"), 17,
3512*9880d681SAndroid Build Coastguard Worker                                      /* u16_0Imm */ 16)));
3513*9880d681SAndroid Build Coastguard Worker
3514*9880d681SAndroid Build Coastguard Worker  let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3,
3515*9880d681SAndroid Build Coastguard Worker                      !if (!eq(ImmOpStr, "u16_2Imm"), 2,
3516*9880d681SAndroid Build Coastguard Worker                      !if (!eq(ImmOpStr, "u16_1Imm"), 1,
3517*9880d681SAndroid Build Coastguard Worker                                       /* u16_0Imm */ 0)));
3518*9880d681SAndroid Build Coastguard Worker}
3519*9880d681SAndroid Build Coastguard Worker
3520*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3521*9880d681SAndroid Build Coastguard Worker// Multiclass for new-value store instructions with absolute addressing.
3522*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3523*9880d681SAndroid Build Coastguard Workerlet addrMode = Absolute, isExtended = 1  in
3524*9880d681SAndroid Build Coastguard Workermulticlass ST_Abs_NV <string mnemonic, string CextOp, Operand ImmOp,
3525*9880d681SAndroid Build Coastguard Worker                   bits<2> MajOp> {
3526*9880d681SAndroid Build Coastguard Worker  let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3527*9880d681SAndroid Build Coastguard Worker    let opExtendable = 0, isPredicable = 1 in
3528*9880d681SAndroid Build Coastguard Worker    def S2_#NAME#newabs : T_StoreAbs_NV <mnemonic, ImmOp, MajOp>;
3529*9880d681SAndroid Build Coastguard Worker
3530*9880d681SAndroid Build Coastguard Worker    // Predicated
3531*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#newt_abs  : T_StoreAbs_NV_Pred <mnemonic, MajOp, 0, 0>;
3532*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#newf_abs  : T_StoreAbs_NV_Pred <mnemonic, MajOp, 1, 0>;
3533*9880d681SAndroid Build Coastguard Worker
3534*9880d681SAndroid Build Coastguard Worker    // .new Predicated
3535*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#newtnew_abs : T_StoreAbs_NV_Pred <mnemonic, MajOp, 0, 1>;
3536*9880d681SAndroid Build Coastguard Worker    def S4_p#NAME#newfnew_abs : T_StoreAbs_NV_Pred <mnemonic, MajOp, 1, 1>;
3537*9880d681SAndroid Build Coastguard Worker  }
3538*9880d681SAndroid Build Coastguard Worker}
3539*9880d681SAndroid Build Coastguard Worker
3540*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3541*9880d681SAndroid Build Coastguard Worker// Stores with absolute addressing
3542*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3543*9880d681SAndroid Build Coastguard Workerlet accessSize = ByteAccess in
3544*9880d681SAndroid Build Coastguard Workerdefm storerb : ST_Abs    <"memb", "STrib", IntRegs, u16_0Imm, 0b00>,
3545*9880d681SAndroid Build Coastguard Worker               ST_Abs_NV <"memb", "STrib", u16_0Imm, 0b00>;
3546*9880d681SAndroid Build Coastguard Worker
3547*9880d681SAndroid Build Coastguard Workerlet accessSize = HalfWordAccess in
3548*9880d681SAndroid Build Coastguard Workerdefm storerh : ST_Abs    <"memh", "STrih", IntRegs, u16_1Imm, 0b01>,
3549*9880d681SAndroid Build Coastguard Worker               ST_Abs_NV <"memh", "STrih", u16_1Imm, 0b01>;
3550*9880d681SAndroid Build Coastguard Worker
3551*9880d681SAndroid Build Coastguard Workerlet accessSize = WordAccess in
3552*9880d681SAndroid Build Coastguard Workerdefm storeri : ST_Abs    <"memw", "STriw", IntRegs, u16_2Imm, 0b10>,
3553*9880d681SAndroid Build Coastguard Worker               ST_Abs_NV <"memw", "STriw", u16_2Imm, 0b10>;
3554*9880d681SAndroid Build Coastguard Worker
3555*9880d681SAndroid Build Coastguard Workerlet isNVStorable = 0, accessSize = DoubleWordAccess in
3556*9880d681SAndroid Build Coastguard Workerdefm storerd : ST_Abs <"memd", "STrid", DoubleRegs, u16_3Imm, 0b11>;
3557*9880d681SAndroid Build Coastguard Worker
3558*9880d681SAndroid Build Coastguard Workerlet isNVStorable = 0, accessSize = HalfWordAccess in
3559*9880d681SAndroid Build Coastguard Workerdefm storerf : ST_Abs <"memh", "STrif", IntRegs, u16_1Imm, 0b01, 1>;
3560*9880d681SAndroid Build Coastguard Worker
3561*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3562*9880d681SAndroid Build Coastguard Worker// GP-relative stores.
3563*9880d681SAndroid Build Coastguard Worker// mem[bhwd](#global)=Rt
3564*9880d681SAndroid Build Coastguard Worker// Once predicated, these instructions map to absolute addressing mode.
3565*9880d681SAndroid Build Coastguard Worker// if ([!]Pv[.new]) mem[bhwd](##global)=Rt
3566*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3567*9880d681SAndroid Build Coastguard Worker
3568*9880d681SAndroid Build Coastguard Workerlet Uses = [GP], isAsmParserOnly = 1 in
3569*9880d681SAndroid Build Coastguard Workerclass T_StoreGP <string mnemonic, string BaseOp, RegisterClass RC,
3570*9880d681SAndroid Build Coastguard Worker                 Operand ImmOp, bits<2> MajOp, bit isHalf = 0>
3571*9880d681SAndroid Build Coastguard Worker  : T_StoreAbsGP <mnemonic, RC, ImmOp, MajOp, 0, isHalf> {
3572*9880d681SAndroid Build Coastguard Worker    // Set BaseOpcode same as absolute addressing instructions so that
3573*9880d681SAndroid Build Coastguard Worker    // non-predicated GP-Rel instructions can have relate with predicated
3574*9880d681SAndroid Build Coastguard Worker    // Absolute instruction.
3575*9880d681SAndroid Build Coastguard Worker    let BaseOpcode = BaseOp#_abs;
3576*9880d681SAndroid Build Coastguard Worker  }
3577*9880d681SAndroid Build Coastguard Worker
3578*9880d681SAndroid Build Coastguard Workerlet Uses = [GP], isAsmParserOnly = 1 in
3579*9880d681SAndroid Build Coastguard Workermulticlass ST_GP <string mnemonic, string BaseOp, Operand ImmOp,
3580*9880d681SAndroid Build Coastguard Worker                  bits<2> MajOp, bit isHalf = 0> {
3581*9880d681SAndroid Build Coastguard Worker  // Set BaseOpcode same as absolute addressing instructions so that
3582*9880d681SAndroid Build Coastguard Worker  // non-predicated GP-Rel instructions can have relate with predicated
3583*9880d681SAndroid Build Coastguard Worker  // Absolute instruction.
3584*9880d681SAndroid Build Coastguard Worker  let BaseOpcode = BaseOp#_abs in {
3585*9880d681SAndroid Build Coastguard Worker    def NAME#gp : T_StoreAbsGP <mnemonic, IntRegs, ImmOp, MajOp,
3586*9880d681SAndroid Build Coastguard Worker                                0, isHalf>;
3587*9880d681SAndroid Build Coastguard Worker    // New-value store
3588*9880d681SAndroid Build Coastguard Worker    def NAME#newgp : T_StoreAbsGP_NV <mnemonic, ImmOp, MajOp> ;
3589*9880d681SAndroid Build Coastguard Worker  }
3590*9880d681SAndroid Build Coastguard Worker}
3591*9880d681SAndroid Build Coastguard Worker
3592*9880d681SAndroid Build Coastguard Workerlet accessSize = ByteAccess in
3593*9880d681SAndroid Build Coastguard Workerdefm S2_storerb : ST_GP<"memb", "STrib", u16_0Imm, 0b00>, NewValueRel;
3594*9880d681SAndroid Build Coastguard Worker
3595*9880d681SAndroid Build Coastguard Workerlet accessSize = HalfWordAccess in
3596*9880d681SAndroid Build Coastguard Workerdefm S2_storerh : ST_GP<"memh", "STrih", u16_1Imm, 0b01>, NewValueRel;
3597*9880d681SAndroid Build Coastguard Worker
3598*9880d681SAndroid Build Coastguard Workerlet accessSize = WordAccess in
3599*9880d681SAndroid Build Coastguard Workerdefm S2_storeri : ST_GP<"memw", "STriw", u16_2Imm, 0b10>, NewValueRel;
3600*9880d681SAndroid Build Coastguard Worker
3601*9880d681SAndroid Build Coastguard Workerlet isNVStorable = 0, accessSize = DoubleWordAccess in
3602*9880d681SAndroid Build Coastguard Workerdef S2_storerdgp : T_StoreGP <"memd", "STrid", DoubleRegs,
3603*9880d681SAndroid Build Coastguard Worker                              u16_3Imm, 0b11>, PredNewRel;
3604*9880d681SAndroid Build Coastguard Worker
3605*9880d681SAndroid Build Coastguard Workerlet isNVStorable = 0, accessSize = HalfWordAccess in
3606*9880d681SAndroid Build Coastguard Workerdef S2_storerfgp : T_StoreGP <"memh", "STrif", IntRegs,
3607*9880d681SAndroid Build Coastguard Worker                              u16_1Imm, 0b01, 1>, PredNewRel;
3608*9880d681SAndroid Build Coastguard Worker
3609*9880d681SAndroid Build Coastguard Workerclass Loada_pat<PatFrag Load, ValueType VT, PatFrag Addr, InstHexagon MI>
3610*9880d681SAndroid Build Coastguard Worker  : Pat<(VT (Load Addr:$addr)), (MI Addr:$addr)>;
3611*9880d681SAndroid Build Coastguard Worker
3612*9880d681SAndroid Build Coastguard Workerclass Loadam_pat<PatFrag Load, ValueType VT, PatFrag Addr, PatFrag ValueMod,
3613*9880d681SAndroid Build Coastguard Worker                 InstHexagon MI>
3614*9880d681SAndroid Build Coastguard Worker  : Pat<(VT (Load Addr:$addr)), (ValueMod (MI Addr:$addr))>;
3615*9880d681SAndroid Build Coastguard Worker
3616*9880d681SAndroid Build Coastguard Workerclass Storea_pat<PatFrag Store, PatFrag Value, PatFrag Addr, InstHexagon MI>
3617*9880d681SAndroid Build Coastguard Worker  : Pat<(Store Value:$val, Addr:$addr), (MI Addr:$addr, Value:$val)>;
3618*9880d681SAndroid Build Coastguard Worker
3619*9880d681SAndroid Build Coastguard Workerclass Stoream_pat<PatFrag Store, PatFrag Value, PatFrag Addr, PatFrag ValueMod,
3620*9880d681SAndroid Build Coastguard Worker                  InstHexagon MI>
3621*9880d681SAndroid Build Coastguard Worker  : Pat<(Store Value:$val, Addr:$addr),
3622*9880d681SAndroid Build Coastguard Worker        (MI Addr:$addr, (ValueMod Value:$val))>;
3623*9880d681SAndroid Build Coastguard Worker
3624*9880d681SAndroid Build Coastguard Workerdef: Storea_pat<SwapSt<atomic_store_8>,  I32, addrgp, S2_storerbgp>;
3625*9880d681SAndroid Build Coastguard Workerdef: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, S2_storerhgp>;
3626*9880d681SAndroid Build Coastguard Workerdef: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, S2_storerigp>;
3627*9880d681SAndroid Build Coastguard Workerdef: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, S2_storerdgp>;
3628*9880d681SAndroid Build Coastguard Worker
3629*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in {
3630*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<truncstorei8,  I32, addrgp, S2_storerbgp>;
3631*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<truncstorei16, I32, addrgp, S2_storerhgp>;
3632*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<store,         I32, addrgp, S2_storerigp>;
3633*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<store,         I64, addrgp, S2_storerdgp>;
3634*9880d681SAndroid Build Coastguard Worker
3635*9880d681SAndroid Build Coastguard Worker  // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
3636*9880d681SAndroid Build Coastguard Worker  //       to "r0 = 1; memw(#foo) = r0"
3637*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 100 in
3638*9880d681SAndroid Build Coastguard Worker  def: Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
3639*9880d681SAndroid Build Coastguard Worker           (S2_storerbgp tglobaladdr:$global, (A2_tfrsi 1))>;
3640*9880d681SAndroid Build Coastguard Worker}
3641*9880d681SAndroid Build Coastguard Worker
3642*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3643*9880d681SAndroid Build Coastguard Worker// Template class for non predicated load instructions with
3644*9880d681SAndroid Build Coastguard Worker// absolute addressing mode.
3645*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3646*9880d681SAndroid Build Coastguard Workerlet isPredicable = 1, hasSideEffects = 0 in
3647*9880d681SAndroid Build Coastguard Workerclass T_LoadAbsGP <string mnemonic, RegisterClass RC, Operand ImmOp,
3648*9880d681SAndroid Build Coastguard Worker                   bits<3> MajOp>
3649*9880d681SAndroid Build Coastguard Worker  : LDInst <(outs RC:$dst), (ins ImmOp:$addr),
3650*9880d681SAndroid Build Coastguard Worker  "$dst = "#mnemonic# "(#$addr)",
3651*9880d681SAndroid Build Coastguard Worker  [], "", V2LDST_tc_ld_SLOT01> {
3652*9880d681SAndroid Build Coastguard Worker    bits<5> dst;
3653*9880d681SAndroid Build Coastguard Worker    bits<19> addr;
3654*9880d681SAndroid Build Coastguard Worker    bits<16> offsetBits;
3655*9880d681SAndroid Build Coastguard Worker
3656*9880d681SAndroid Build Coastguard Worker    string ImmOpStr = !cast<string>(ImmOp);
3657*9880d681SAndroid Build Coastguard Worker    let offsetBits = !if (!eq(ImmOpStr, "u16_3Imm"), addr{18-3},
3658*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2},
3659*9880d681SAndroid Build Coastguard Worker                     !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1},
3660*9880d681SAndroid Build Coastguard Worker                                      /* u16_0Imm */ addr{15-0})));
3661*9880d681SAndroid Build Coastguard Worker
3662*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0100;
3663*9880d681SAndroid Build Coastguard Worker
3664*9880d681SAndroid Build Coastguard Worker    let Inst{27}    = 0b1;
3665*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = offsetBits{15-14};
3666*9880d681SAndroid Build Coastguard Worker    let Inst{24}    = 0b1;
3667*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = MajOp;
3668*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = offsetBits{13-9};
3669*9880d681SAndroid Build Coastguard Worker    let Inst{13-5}  = offsetBits{8-0};
3670*9880d681SAndroid Build Coastguard Worker    let Inst{4-0}   = dst;
3671*9880d681SAndroid Build Coastguard Worker  }
3672*9880d681SAndroid Build Coastguard Worker
3673*9880d681SAndroid Build Coastguard Workerclass T_LoadAbs <string mnemonic, RegisterClass RC, Operand ImmOp,
3674*9880d681SAndroid Build Coastguard Worker                 bits<3> MajOp>
3675*9880d681SAndroid Build Coastguard Worker  : T_LoadAbsGP <mnemonic, RC, u32MustExt, MajOp>, AddrModeRel {
3676*9880d681SAndroid Build Coastguard Worker
3677*9880d681SAndroid Build Coastguard Worker    string ImmOpStr = !cast<string>(ImmOp);
3678*9880d681SAndroid Build Coastguard Worker    let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19,
3679*9880d681SAndroid Build Coastguard Worker                       !if (!eq(ImmOpStr, "u16_2Imm"), 18,
3680*9880d681SAndroid Build Coastguard Worker                       !if (!eq(ImmOpStr, "u16_1Imm"), 17,
3681*9880d681SAndroid Build Coastguard Worker                                        /* u16_0Imm */ 16)));
3682*9880d681SAndroid Build Coastguard Worker
3683*9880d681SAndroid Build Coastguard Worker    let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3,
3684*9880d681SAndroid Build Coastguard Worker                        !if (!eq(ImmOpStr, "u16_2Imm"), 2,
3685*9880d681SAndroid Build Coastguard Worker                        !if (!eq(ImmOpStr, "u16_1Imm"), 1,
3686*9880d681SAndroid Build Coastguard Worker                                        /* u16_0Imm */ 0)));
3687*9880d681SAndroid Build Coastguard Worker  }
3688*9880d681SAndroid Build Coastguard Worker
3689*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3690*9880d681SAndroid Build Coastguard Worker// Template class for predicated load instructions with
3691*9880d681SAndroid Build Coastguard Worker// absolute addressing mode.
3692*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3693*9880d681SAndroid Build Coastguard Workerlet isPredicated = 1, hasSideEffects = 0, hasNewValue = 1, opExtentBits = 6,
3694*9880d681SAndroid Build Coastguard Worker    opExtendable = 2 in
3695*9880d681SAndroid Build Coastguard Workerclass T_LoadAbs_Pred <string mnemonic, RegisterClass RC, bits<3> MajOp,
3696*9880d681SAndroid Build Coastguard Worker                      bit isPredNot, bit isPredNew>
3697*9880d681SAndroid Build Coastguard Worker  : LDInst <(outs RC:$dst), (ins PredRegs:$src1, u32MustExt:$absaddr),
3698*9880d681SAndroid Build Coastguard Worker  !if(isPredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3699*9880d681SAndroid Build Coastguard Worker  ") ")#"$dst = "#mnemonic#"(#$absaddr)">, AddrModeRel {
3700*9880d681SAndroid Build Coastguard Worker    bits<5> dst;
3701*9880d681SAndroid Build Coastguard Worker    bits<2> src1;
3702*9880d681SAndroid Build Coastguard Worker    bits<6> absaddr;
3703*9880d681SAndroid Build Coastguard Worker
3704*9880d681SAndroid Build Coastguard Worker    let isPredicatedNew = isPredNew;
3705*9880d681SAndroid Build Coastguard Worker    let isPredicatedFalse = isPredNot;
3706*9880d681SAndroid Build Coastguard Worker    let hasNewValue = !if (!eq(!cast<string>(RC), "DoubleRegs"), 0, 1);
3707*9880d681SAndroid Build Coastguard Worker
3708*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1001;
3709*9880d681SAndroid Build Coastguard Worker
3710*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b1111;
3711*9880d681SAndroid Build Coastguard Worker    let Inst{23-21} = MajOp;
3712*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = absaddr{5-1};
3713*9880d681SAndroid Build Coastguard Worker    let Inst{13} = 0b1;
3714*9880d681SAndroid Build Coastguard Worker    let Inst{12} = isPredNew;
3715*9880d681SAndroid Build Coastguard Worker    let Inst{11} = isPredNot;
3716*9880d681SAndroid Build Coastguard Worker    let Inst{10-9} = src1;
3717*9880d681SAndroid Build Coastguard Worker    let Inst{8} = absaddr{0};
3718*9880d681SAndroid Build Coastguard Worker    let Inst{7} = 0b1;
3719*9880d681SAndroid Build Coastguard Worker    let Inst{4-0} = dst;
3720*9880d681SAndroid Build Coastguard Worker  }
3721*9880d681SAndroid Build Coastguard Worker
3722*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3723*9880d681SAndroid Build Coastguard Worker// Multiclass for the load instructions with absolute addressing mode.
3724*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3725*9880d681SAndroid Build Coastguard Workermulticlass LD_Abs_Pred<string mnemonic, RegisterClass RC, bits<3> MajOp,
3726*9880d681SAndroid Build Coastguard Worker                       bit PredNot> {
3727*9880d681SAndroid Build Coastguard Worker  def _abs : T_LoadAbs_Pred <mnemonic, RC, MajOp, PredNot, 0>;
3728*9880d681SAndroid Build Coastguard Worker  // Predicate new
3729*9880d681SAndroid Build Coastguard Worker  def new_abs : T_LoadAbs_Pred <mnemonic, RC, MajOp, PredNot, 1>;
3730*9880d681SAndroid Build Coastguard Worker}
3731*9880d681SAndroid Build Coastguard Worker
3732*9880d681SAndroid Build Coastguard Workerlet addrMode = Absolute, isExtended = 1 in
3733*9880d681SAndroid Build Coastguard Workermulticlass LD_Abs<string mnemonic, string CextOp, RegisterClass RC,
3734*9880d681SAndroid Build Coastguard Worker                  Operand ImmOp, bits<3> MajOp> {
3735*9880d681SAndroid Build Coastguard Worker  let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3736*9880d681SAndroid Build Coastguard Worker    let opExtendable = 1, isPredicable = 1 in
3737*9880d681SAndroid Build Coastguard Worker    def L4_#NAME#_abs: T_LoadAbs <mnemonic, RC, ImmOp, MajOp>;
3738*9880d681SAndroid Build Coastguard Worker
3739*9880d681SAndroid Build Coastguard Worker    // Predicated
3740*9880d681SAndroid Build Coastguard Worker    defm L4_p#NAME#t : LD_Abs_Pred<mnemonic, RC, MajOp, 0>;
3741*9880d681SAndroid Build Coastguard Worker    defm L4_p#NAME#f : LD_Abs_Pred<mnemonic, RC, MajOp, 1>;
3742*9880d681SAndroid Build Coastguard Worker  }
3743*9880d681SAndroid Build Coastguard Worker}
3744*9880d681SAndroid Build Coastguard Worker
3745*9880d681SAndroid Build Coastguard Workerlet accessSize = ByteAccess, hasNewValue = 1 in {
3746*9880d681SAndroid Build Coastguard Worker  defm loadrb  : LD_Abs<"memb",  "LDrib",  IntRegs, u16_0Imm, 0b000>;
3747*9880d681SAndroid Build Coastguard Worker  defm loadrub : LD_Abs<"memub", "LDriub", IntRegs, u16_0Imm, 0b001>;
3748*9880d681SAndroid Build Coastguard Worker}
3749*9880d681SAndroid Build Coastguard Worker
3750*9880d681SAndroid Build Coastguard Workerlet accessSize = HalfWordAccess, hasNewValue = 1 in {
3751*9880d681SAndroid Build Coastguard Worker  defm loadrh  : LD_Abs<"memh",  "LDrih",  IntRegs, u16_1Imm, 0b010>;
3752*9880d681SAndroid Build Coastguard Worker  defm loadruh : LD_Abs<"memuh", "LDriuh", IntRegs, u16_1Imm, 0b011>;
3753*9880d681SAndroid Build Coastguard Worker}
3754*9880d681SAndroid Build Coastguard Worker
3755*9880d681SAndroid Build Coastguard Workerlet accessSize = WordAccess, hasNewValue = 1 in
3756*9880d681SAndroid Build Coastguard Workerdefm loadri  : LD_Abs<"memw",  "LDriw",  IntRegs, u16_2Imm, 0b100>;
3757*9880d681SAndroid Build Coastguard Worker
3758*9880d681SAndroid Build Coastguard Workerlet accessSize = DoubleWordAccess in
3759*9880d681SAndroid Build Coastguard Workerdefm loadrd  : LD_Abs<"memd",  "LDrid", DoubleRegs, u16_3Imm, 0b110>;
3760*9880d681SAndroid Build Coastguard Worker
3761*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3762*9880d681SAndroid Build Coastguard Worker// multiclass for load instructions with GP-relative addressing mode.
3763*9880d681SAndroid Build Coastguard Worker// Rx=mem[bhwd](##global)
3764*9880d681SAndroid Build Coastguard Worker// Once predicated, these instructions map to absolute addressing mode.
3765*9880d681SAndroid Build Coastguard Worker// if ([!]Pv[.new]) Rx=mem[bhwd](##global)
3766*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3767*9880d681SAndroid Build Coastguard Worker
3768*9880d681SAndroid Build Coastguard Workerlet isAsmParserOnly = 1, Uses = [GP] in
3769*9880d681SAndroid Build Coastguard Workerclass T_LoadGP <string mnemonic, string BaseOp, RegisterClass RC, Operand ImmOp,
3770*9880d681SAndroid Build Coastguard Worker                bits<3> MajOp>
3771*9880d681SAndroid Build Coastguard Worker  : T_LoadAbsGP <mnemonic, RC, ImmOp, MajOp>, PredNewRel {
3772*9880d681SAndroid Build Coastguard Worker    let BaseOpcode = BaseOp#_abs;
3773*9880d681SAndroid Build Coastguard Worker  }
3774*9880d681SAndroid Build Coastguard Worker
3775*9880d681SAndroid Build Coastguard Workerlet accessSize = ByteAccess, hasNewValue = 1 in {
3776*9880d681SAndroid Build Coastguard Worker  def L2_loadrbgp  : T_LoadGP<"memb",  "LDrib",  IntRegs, u16_0Imm, 0b000>;
3777*9880d681SAndroid Build Coastguard Worker  def L2_loadrubgp : T_LoadGP<"memub", "LDriub", IntRegs, u16_0Imm, 0b001>;
3778*9880d681SAndroid Build Coastguard Worker}
3779*9880d681SAndroid Build Coastguard Worker
3780*9880d681SAndroid Build Coastguard Workerlet accessSize = HalfWordAccess, hasNewValue = 1 in {
3781*9880d681SAndroid Build Coastguard Worker  def L2_loadrhgp  : T_LoadGP<"memh",  "LDrih",  IntRegs, u16_1Imm, 0b010>;
3782*9880d681SAndroid Build Coastguard Worker  def L2_loadruhgp : T_LoadGP<"memuh", "LDriuh", IntRegs, u16_1Imm, 0b011>;
3783*9880d681SAndroid Build Coastguard Worker}
3784*9880d681SAndroid Build Coastguard Worker
3785*9880d681SAndroid Build Coastguard Workerlet accessSize = WordAccess, hasNewValue = 1 in
3786*9880d681SAndroid Build Coastguard Workerdef L2_loadrigp  : T_LoadGP<"memw",  "LDriw",  IntRegs, u16_2Imm, 0b100>;
3787*9880d681SAndroid Build Coastguard Worker
3788*9880d681SAndroid Build Coastguard Workerlet accessSize = DoubleWordAccess in
3789*9880d681SAndroid Build Coastguard Workerdef L2_loadrdgp  : T_LoadGP<"memd", "LDrid", DoubleRegs, u16_3Imm, 0b110>;
3790*9880d681SAndroid Build Coastguard Worker
3791*9880d681SAndroid Build Coastguard Workerdef: Loada_pat<atomic_load_8,  i32, addrgp, L2_loadrubgp>;
3792*9880d681SAndroid Build Coastguard Workerdef: Loada_pat<atomic_load_16, i32, addrgp, L2_loadruhgp>;
3793*9880d681SAndroid Build Coastguard Workerdef: Loada_pat<atomic_load_32, i32, addrgp, L2_loadrigp>;
3794*9880d681SAndroid Build Coastguard Workerdef: Loada_pat<atomic_load_64, i64, addrgp, L2_loadrdgp>;
3795*9880d681SAndroid Build Coastguard Worker
3796*9880d681SAndroid Build Coastguard Worker// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
3797*9880d681SAndroid Build Coastguard Workerdef: Loadam_pat<load, i1, addrga, I32toI1, L4_loadrub_abs>;
3798*9880d681SAndroid Build Coastguard Workerdef: Loadam_pat<load, i1, addrgp, I32toI1, L2_loadrubgp>;
3799*9880d681SAndroid Build Coastguard Worker
3800*9880d681SAndroid Build Coastguard Workerdef: Stoream_pat<store, I1, addrga, I1toI32, S2_storerbabs>;
3801*9880d681SAndroid Build Coastguard Workerdef: Stoream_pat<store, I1, addrgp, I1toI32, S2_storerbgp>;
3802*9880d681SAndroid Build Coastguard Worker
3803*9880d681SAndroid Build Coastguard Worker// Map from load(globaladdress) -> mem[u][bhwd](#foo)
3804*9880d681SAndroid Build Coastguard Workerclass LoadGP_pats <PatFrag ldOp, InstHexagon MI, ValueType VT = i32>
3805*9880d681SAndroid Build Coastguard Worker  : Pat <(VT (ldOp (HexagonCONST32_GP tglobaladdr:$global))),
3806*9880d681SAndroid Build Coastguard Worker         (VT (MI tglobaladdr:$global))>;
3807*9880d681SAndroid Build Coastguard Worker
3808*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in {
3809*9880d681SAndroid Build Coastguard Worker  def: LoadGP_pats <extloadi8,   L2_loadrubgp>;
3810*9880d681SAndroid Build Coastguard Worker  def: LoadGP_pats <sextloadi8,  L2_loadrbgp>;
3811*9880d681SAndroid Build Coastguard Worker  def: LoadGP_pats <zextloadi8,  L2_loadrubgp>;
3812*9880d681SAndroid Build Coastguard Worker  def: LoadGP_pats <extloadi16,  L2_loadruhgp>;
3813*9880d681SAndroid Build Coastguard Worker  def: LoadGP_pats <sextloadi16, L2_loadrhgp>;
3814*9880d681SAndroid Build Coastguard Worker  def: LoadGP_pats <zextloadi16, L2_loadruhgp>;
3815*9880d681SAndroid Build Coastguard Worker  def: LoadGP_pats <load,        L2_loadrigp>;
3816*9880d681SAndroid Build Coastguard Worker  def: LoadGP_pats <load,        L2_loadrdgp, i64>;
3817*9880d681SAndroid Build Coastguard Worker}
3818*9880d681SAndroid Build Coastguard Worker
3819*9880d681SAndroid Build Coastguard Worker// When the Interprocedural Global Variable optimizer realizes that a certain
3820*9880d681SAndroid Build Coastguard Worker// global variable takes only two constant values, it shrinks the global to
3821*9880d681SAndroid Build Coastguard Worker// a boolean. Catch those loads here in the following 3 patterns.
3822*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in {
3823*9880d681SAndroid Build Coastguard Worker  def: LoadGP_pats <extloadi1, L2_loadrubgp>;
3824*9880d681SAndroid Build Coastguard Worker  def: LoadGP_pats <zextloadi1, L2_loadrubgp>;
3825*9880d681SAndroid Build Coastguard Worker}
3826*9880d681SAndroid Build Coastguard Worker
3827*9880d681SAndroid Build Coastguard Worker// Transfer global address into a register
3828*9880d681SAndroid Build Coastguard Workerdef: Pat<(HexagonCONST32 tglobaladdr:$Rs),      (A2_tfrsi s16Ext:$Rs)>;
3829*9880d681SAndroid Build Coastguard Workerdef: Pat<(HexagonCONST32_GP tblockaddress:$Rs), (A2_tfrsi s16Ext:$Rs)>;
3830*9880d681SAndroid Build Coastguard Workerdef: Pat<(HexagonCONST32_GP tglobaladdr:$Rs),   (A2_tfrsi s16Ext:$Rs)>;
3831*9880d681SAndroid Build Coastguard Worker
3832*9880d681SAndroid Build Coastguard Workerlet AddedComplexity  = 30 in {
3833*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<truncstorei8,  I32, u32ImmPred, S2_storerbabs>;
3834*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<truncstorei16, I32, u32ImmPred, S2_storerhabs>;
3835*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<store,         I32, u32ImmPred, S2_storeriabs>;
3836*9880d681SAndroid Build Coastguard Worker}
3837*9880d681SAndroid Build Coastguard Worker
3838*9880d681SAndroid Build Coastguard Workerlet AddedComplexity  = 30 in {
3839*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<load,        i32, u32ImmPred, L4_loadri_abs>;
3840*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<sextloadi8,  i32, u32ImmPred, L4_loadrb_abs>;
3841*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<zextloadi8,  i32, u32ImmPred, L4_loadrub_abs>;
3842*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<sextloadi16, i32, u32ImmPred, L4_loadrh_abs>;
3843*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<zextloadi16, i32, u32ImmPred, L4_loadruh_abs>;
3844*9880d681SAndroid Build Coastguard Worker}
3845*9880d681SAndroid Build Coastguard Worker
3846*9880d681SAndroid Build Coastguard Worker// Indexed store word - global address.
3847*9880d681SAndroid Build Coastguard Worker// memw(Rs+#u6:2)=#S8
3848*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in
3849*9880d681SAndroid Build Coastguard Workerdef: Storex_add_pat<store, addrga, u6_2ImmPred, S4_storeiri_io>;
3850*9880d681SAndroid Build Coastguard Worker
3851*9880d681SAndroid Build Coastguard Worker// Load from a global address that has only one use in the current basic block.
3852*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in {
3853*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<extloadi8,   i32, addrga, L4_loadrub_abs>;
3854*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<sextloadi8,  i32, addrga, L4_loadrb_abs>;
3855*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<zextloadi8,  i32, addrga, L4_loadrub_abs>;
3856*9880d681SAndroid Build Coastguard Worker
3857*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<extloadi16,  i32, addrga, L4_loadruh_abs>;
3858*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<sextloadi16, i32, addrga, L4_loadrh_abs>;
3859*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<zextloadi16, i32, addrga, L4_loadruh_abs>;
3860*9880d681SAndroid Build Coastguard Worker
3861*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<load,        i32, addrga, L4_loadri_abs>;
3862*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<load,        i64, addrga, L4_loadrd_abs>;
3863*9880d681SAndroid Build Coastguard Worker}
3864*9880d681SAndroid Build Coastguard Worker
3865*9880d681SAndroid Build Coastguard Worker// Store to a global address that has only one use in the current basic block.
3866*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in {
3867*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<truncstorei8,  I32, addrga, S2_storerbabs>;
3868*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<truncstorei16, I32, addrga, S2_storerhabs>;
3869*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<store,         I32, addrga, S2_storeriabs>;
3870*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<store,         I64, addrga, S2_storerdabs>;
3871*9880d681SAndroid Build Coastguard Worker
3872*9880d681SAndroid Build Coastguard Worker  def: Stoream_pat<truncstorei32, I64, addrga, LoReg, S2_storeriabs>;
3873*9880d681SAndroid Build Coastguard Worker}
3874*9880d681SAndroid Build Coastguard Worker
3875*9880d681SAndroid Build Coastguard Worker// i8/i16/i32 -> i64 loads
3876*9880d681SAndroid Build Coastguard Worker// We need a complexity of 120 here to override preceding handling of
3877*9880d681SAndroid Build Coastguard Worker// zextload.
3878*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 120 in {
3879*9880d681SAndroid Build Coastguard Worker  def: Loadam_pat<extloadi8,   i64, addrga, Zext64, L4_loadrub_abs>;
3880*9880d681SAndroid Build Coastguard Worker  def: Loadam_pat<sextloadi8,  i64, addrga, Sext64, L4_loadrb_abs>;
3881*9880d681SAndroid Build Coastguard Worker  def: Loadam_pat<zextloadi8,  i64, addrga, Zext64, L4_loadrub_abs>;
3882*9880d681SAndroid Build Coastguard Worker
3883*9880d681SAndroid Build Coastguard Worker  def: Loadam_pat<extloadi16,  i64, addrga, Zext64, L4_loadruh_abs>;
3884*9880d681SAndroid Build Coastguard Worker  def: Loadam_pat<sextloadi16, i64, addrga, Sext64, L4_loadrh_abs>;
3885*9880d681SAndroid Build Coastguard Worker  def: Loadam_pat<zextloadi16, i64, addrga, Zext64, L4_loadruh_abs>;
3886*9880d681SAndroid Build Coastguard Worker
3887*9880d681SAndroid Build Coastguard Worker  def: Loadam_pat<extloadi32,  i64, addrga, Zext64, L4_loadri_abs>;
3888*9880d681SAndroid Build Coastguard Worker  def: Loadam_pat<sextloadi32, i64, addrga, Sext64, L4_loadri_abs>;
3889*9880d681SAndroid Build Coastguard Worker  def: Loadam_pat<zextloadi32, i64, addrga, Zext64, L4_loadri_abs>;
3890*9880d681SAndroid Build Coastguard Worker}
3891*9880d681SAndroid Build Coastguard Worker
3892*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in {
3893*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<extloadi8,   i32, addrgp, L4_loadrub_abs>;
3894*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<sextloadi8,  i32, addrgp, L4_loadrb_abs>;
3895*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<zextloadi8,  i32, addrgp, L4_loadrub_abs>;
3896*9880d681SAndroid Build Coastguard Worker
3897*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<extloadi16,  i32, addrgp, L4_loadruh_abs>;
3898*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<sextloadi16, i32, addrgp, L4_loadrh_abs>;
3899*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<zextloadi16, i32, addrgp, L4_loadruh_abs>;
3900*9880d681SAndroid Build Coastguard Worker
3901*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<load,        i32, addrgp, L4_loadri_abs>;
3902*9880d681SAndroid Build Coastguard Worker  def: Loada_pat<load,        i64, addrgp, L4_loadrd_abs>;
3903*9880d681SAndroid Build Coastguard Worker}
3904*9880d681SAndroid Build Coastguard Worker
3905*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 100 in {
3906*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<truncstorei8,  I32, addrgp, S2_storerbabs>;
3907*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<truncstorei16, I32, addrgp, S2_storerhabs>;
3908*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<store,         I32, addrgp, S2_storeriabs>;
3909*9880d681SAndroid Build Coastguard Worker  def: Storea_pat<store,         I64, addrgp, S2_storerdabs>;
3910*9880d681SAndroid Build Coastguard Worker}
3911*9880d681SAndroid Build Coastguard Worker
3912*9880d681SAndroid Build Coastguard Workerdef: Loada_pat<atomic_load_8,  i32, addrgp, L4_loadrub_abs>;
3913*9880d681SAndroid Build Coastguard Workerdef: Loada_pat<atomic_load_16, i32, addrgp, L4_loadruh_abs>;
3914*9880d681SAndroid Build Coastguard Workerdef: Loada_pat<atomic_load_32, i32, addrgp, L4_loadri_abs>;
3915*9880d681SAndroid Build Coastguard Workerdef: Loada_pat<atomic_load_64, i64, addrgp, L4_loadrd_abs>;
3916*9880d681SAndroid Build Coastguard Worker
3917*9880d681SAndroid Build Coastguard Workerdef: Storea_pat<SwapSt<atomic_store_8>,  I32, addrgp, S2_storerbabs>;
3918*9880d681SAndroid Build Coastguard Workerdef: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, S2_storerhabs>;
3919*9880d681SAndroid Build Coastguard Workerdef: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, S2_storeriabs>;
3920*9880d681SAndroid Build Coastguard Workerdef: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, S2_storerdabs>;
3921*9880d681SAndroid Build Coastguard Worker
3922*9880d681SAndroid Build Coastguard Workerlet Constraints = "@earlyclobber $dst" in
3923*9880d681SAndroid Build Coastguard Workerdef Insert4 : PseudoM<(outs DoubleRegs:$dst), (ins IntRegs:$a, IntRegs:$b,
3924*9880d681SAndroid Build Coastguard Worker                                                   IntRegs:$c, IntRegs:$d),
3925*9880d681SAndroid Build Coastguard Worker  ".error \"Should never try to emit Insert4\"",
3926*9880d681SAndroid Build Coastguard Worker  [(set (i64 DoubleRegs:$dst),
3927*9880d681SAndroid Build Coastguard Worker        (or (or (or (shl (i64 (zext (i32 (and (i32 IntRegs:$b), (i32 65535))))),
3928*9880d681SAndroid Build Coastguard Worker                         (i32 16)),
3929*9880d681SAndroid Build Coastguard Worker                    (i64 (zext (i32 (and (i32 IntRegs:$a), (i32 65535)))))),
3930*9880d681SAndroid Build Coastguard Worker                (shl (i64 (anyext (i32 (and (i32 IntRegs:$c), (i32 65535))))),
3931*9880d681SAndroid Build Coastguard Worker                     (i32 32))),
3932*9880d681SAndroid Build Coastguard Worker            (shl (i64 (anyext (i32 IntRegs:$d))), (i32 48))))]>;
3933*9880d681SAndroid Build Coastguard Worker
3934*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3935*9880d681SAndroid Build Coastguard Worker// :raw for of boundscheck:hi:lo insns
3936*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3937*9880d681SAndroid Build Coastguard Worker
3938*9880d681SAndroid Build Coastguard Worker// A4_boundscheck_lo: Detect if a register is within bounds.
3939*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
3940*9880d681SAndroid Build Coastguard Workerdef A4_boundscheck_lo: ALU64Inst <
3941*9880d681SAndroid Build Coastguard Worker  (outs PredRegs:$Pd),
3942*9880d681SAndroid Build Coastguard Worker  (ins DoubleRegs:$Rss, DoubleRegs:$Rtt),
3943*9880d681SAndroid Build Coastguard Worker  "$Pd = boundscheck($Rss, $Rtt):raw:lo"> {
3944*9880d681SAndroid Build Coastguard Worker    bits<2> Pd;
3945*9880d681SAndroid Build Coastguard Worker    bits<5> Rss;
3946*9880d681SAndroid Build Coastguard Worker    bits<5> Rtt;
3947*9880d681SAndroid Build Coastguard Worker
3948*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
3949*9880d681SAndroid Build Coastguard Worker
3950*9880d681SAndroid Build Coastguard Worker    let Inst{27-23} = 0b00100;
3951*9880d681SAndroid Build Coastguard Worker    let Inst{13} = 0b1;
3952*9880d681SAndroid Build Coastguard Worker    let Inst{7-5} = 0b100;
3953*9880d681SAndroid Build Coastguard Worker    let Inst{1-0} = Pd;
3954*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rss;
3955*9880d681SAndroid Build Coastguard Worker    let Inst{12-8} = Rtt;
3956*9880d681SAndroid Build Coastguard Worker  }
3957*9880d681SAndroid Build Coastguard Worker
3958*9880d681SAndroid Build Coastguard Worker// A4_boundscheck_hi: Detect if a register is within bounds.
3959*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
3960*9880d681SAndroid Build Coastguard Workerdef A4_boundscheck_hi: ALU64Inst <
3961*9880d681SAndroid Build Coastguard Worker  (outs PredRegs:$Pd),
3962*9880d681SAndroid Build Coastguard Worker  (ins DoubleRegs:$Rss, DoubleRegs:$Rtt),
3963*9880d681SAndroid Build Coastguard Worker  "$Pd = boundscheck($Rss, $Rtt):raw:hi"> {
3964*9880d681SAndroid Build Coastguard Worker    bits<2> Pd;
3965*9880d681SAndroid Build Coastguard Worker    bits<5> Rss;
3966*9880d681SAndroid Build Coastguard Worker    bits<5> Rtt;
3967*9880d681SAndroid Build Coastguard Worker
3968*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
3969*9880d681SAndroid Build Coastguard Worker
3970*9880d681SAndroid Build Coastguard Worker    let Inst{27-23} = 0b00100;
3971*9880d681SAndroid Build Coastguard Worker    let Inst{13} = 0b1;
3972*9880d681SAndroid Build Coastguard Worker    let Inst{7-5} = 0b101;
3973*9880d681SAndroid Build Coastguard Worker    let Inst{1-0} = Pd;
3974*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rss;
3975*9880d681SAndroid Build Coastguard Worker    let Inst{12-8} = Rtt;
3976*9880d681SAndroid Build Coastguard Worker  }
3977*9880d681SAndroid Build Coastguard Worker
3978*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, isAsmParserOnly = 1 in
3979*9880d681SAndroid Build Coastguard Workerdef A4_boundscheck : MInst <
3980*9880d681SAndroid Build Coastguard Worker  (outs PredRegs:$Pd), (ins IntRegs:$Rs, DoubleRegs:$Rtt),
3981*9880d681SAndroid Build Coastguard Worker  "$Pd=boundscheck($Rs,$Rtt)">;
3982*9880d681SAndroid Build Coastguard Worker
3983*9880d681SAndroid Build Coastguard Worker// A4_tlbmatch: Detect if a VA/ASID matches a TLB entry.
3984*9880d681SAndroid Build Coastguard Workerlet isPredicateLate = 1, hasSideEffects = 0 in
3985*9880d681SAndroid Build Coastguard Workerdef A4_tlbmatch : ALU64Inst<(outs PredRegs:$Pd),
3986*9880d681SAndroid Build Coastguard Worker  (ins DoubleRegs:$Rs, IntRegs:$Rt),
3987*9880d681SAndroid Build Coastguard Worker  "$Pd = tlbmatch($Rs, $Rt)",
3988*9880d681SAndroid Build Coastguard Worker  [], "", ALU64_tc_2early_SLOT23> {
3989*9880d681SAndroid Build Coastguard Worker    bits<2> Pd;
3990*9880d681SAndroid Build Coastguard Worker    bits<5> Rs;
3991*9880d681SAndroid Build Coastguard Worker    bits<5> Rt;
3992*9880d681SAndroid Build Coastguard Worker
3993*9880d681SAndroid Build Coastguard Worker    let IClass = 0b1101;
3994*9880d681SAndroid Build Coastguard Worker    let Inst{27-23} = 0b00100;
3995*9880d681SAndroid Build Coastguard Worker    let Inst{20-16} = Rs;
3996*9880d681SAndroid Build Coastguard Worker    let Inst{13} = 0b1;
3997*9880d681SAndroid Build Coastguard Worker    let Inst{12-8} = Rt;
3998*9880d681SAndroid Build Coastguard Worker    let Inst{7-5} = 0b011;
3999*9880d681SAndroid Build Coastguard Worker    let Inst{1-0} = Pd;
4000*9880d681SAndroid Build Coastguard Worker  }
4001*9880d681SAndroid Build Coastguard Worker
4002*9880d681SAndroid Build Coastguard Worker// We need custom lowering of ISD::PREFETCH into HexagonISD::DCFETCH
4003*9880d681SAndroid Build Coastguard Worker// because the SDNode ISD::PREFETCH has properties MayLoad and MayStore.
4004*9880d681SAndroid Build Coastguard Worker// We don't really want either one here.
4005*9880d681SAndroid Build Coastguard Workerdef SDTHexagonDCFETCH : SDTypeProfile<0, 2, [SDTCisPtrTy<0>,SDTCisInt<1>]>;
4006*9880d681SAndroid Build Coastguard Workerdef HexagonDCFETCH : SDNode<"HexagonISD::DCFETCH", SDTHexagonDCFETCH,
4007*9880d681SAndroid Build Coastguard Worker                            [SDNPHasChain]>;
4008*9880d681SAndroid Build Coastguard Worker
4009*9880d681SAndroid Build Coastguard Worker// Use LD0Inst for dcfetch, but set "mayLoad" to 0 because this doesn't
4010*9880d681SAndroid Build Coastguard Worker// really do a load.
4011*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 1, mayLoad = 0 in
4012*9880d681SAndroid Build Coastguard Workerdef Y2_dcfetchbo : LD0Inst<(outs), (ins IntRegs:$Rs, u11_3Imm:$u11_3),
4013*9880d681SAndroid Build Coastguard Worker      "dcfetch($Rs + #$u11_3)",
4014*9880d681SAndroid Build Coastguard Worker      [(HexagonDCFETCH IntRegs:$Rs, u11_3ImmPred:$u11_3)],
4015*9880d681SAndroid Build Coastguard Worker      "", LD_tc_ld_SLOT0> {
4016*9880d681SAndroid Build Coastguard Worker  bits<5> Rs;
4017*9880d681SAndroid Build Coastguard Worker  bits<14> u11_3;
4018*9880d681SAndroid Build Coastguard Worker
4019*9880d681SAndroid Build Coastguard Worker  let IClass = 0b1001;
4020*9880d681SAndroid Build Coastguard Worker  let Inst{27-21} = 0b0100000;
4021*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = Rs;
4022*9880d681SAndroid Build Coastguard Worker  let Inst{13} = 0b0;
4023*9880d681SAndroid Build Coastguard Worker  let Inst{10-0} = u11_3{13-3};
4024*9880d681SAndroid Build Coastguard Worker}
4025*9880d681SAndroid Build Coastguard Worker
4026*9880d681SAndroid Build Coastguard Worker
4027*9880d681SAndroid Build Coastguard Workerdef: Pat<(HexagonDCFETCH (i32 (add IntRegs:$Rs, u11_3ImmPred:$u11_3)), (i32 0)),
4028*9880d681SAndroid Build Coastguard Worker         (Y2_dcfetchbo IntRegs:$Rs, u11_3ImmPred:$u11_3)>;
4029*9880d681SAndroid Build Coastguard Worker
4030*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
4031*9880d681SAndroid Build Coastguard Worker// Compound instructions
4032*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
4033*9880d681SAndroid Build Coastguard Worker
4034*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, hasSideEffects = 0, isExtentSigned = 1,
4035*9880d681SAndroid Build Coastguard Worker    isPredicated = 1, isPredicatedNew = 1, isExtendable = 1,
4036*9880d681SAndroid Build Coastguard Worker    opExtentBits = 11, opExtentAlign = 2, opExtendable = 1,
4037*9880d681SAndroid Build Coastguard Worker    isTerminator = 1 in
4038*9880d681SAndroid Build Coastguard Workerclass CJInst_tstbit_R0<string px, bit np, string tnt>
4039*9880d681SAndroid Build Coastguard Worker  : InstHexagon<(outs), (ins IntRegs:$Rs, brtarget:$r9_2),
4040*9880d681SAndroid Build Coastguard Worker  ""#px#" = tstbit($Rs, #0); if ("
4041*9880d681SAndroid Build Coastguard Worker    #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2",
4042*9880d681SAndroid Build Coastguard Worker  [], "", COMPOUND, TypeCOMPOUND>, OpcodeHexagon {
4043*9880d681SAndroid Build Coastguard Worker  bits<4> Rs;
4044*9880d681SAndroid Build Coastguard Worker  bits<11> r9_2;
4045*9880d681SAndroid Build Coastguard Worker
4046*9880d681SAndroid Build Coastguard Worker  // np: !p[01]
4047*9880d681SAndroid Build Coastguard Worker  let isPredicatedFalse = np;
4048*9880d681SAndroid Build Coastguard Worker  // tnt: Taken/Not Taken
4049*9880d681SAndroid Build Coastguard Worker  let isBrTaken = !if (!eq(tnt, "t"), "true", "false");
4050*9880d681SAndroid Build Coastguard Worker  let isTaken   = !if (!eq(tnt, "t"), 1, 0);
4051*9880d681SAndroid Build Coastguard Worker
4052*9880d681SAndroid Build Coastguard Worker  let IClass = 0b0001;
4053*9880d681SAndroid Build Coastguard Worker  let Inst{27-26} = 0b00;
4054*9880d681SAndroid Build Coastguard Worker  let Inst{25} = !if (!eq(px, "!p1"), 1,
4055*9880d681SAndroid Build Coastguard Worker                 !if (!eq(px,  "p1"), 1, 0));
4056*9880d681SAndroid Build Coastguard Worker  let Inst{24-23} = 0b11;
4057*9880d681SAndroid Build Coastguard Worker  let Inst{22} = np;
4058*9880d681SAndroid Build Coastguard Worker  let Inst{21-20} = r9_2{10-9};
4059*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rs;
4060*9880d681SAndroid Build Coastguard Worker  let Inst{13} = !if (!eq(tnt, "t"), 1, 0);
4061*9880d681SAndroid Build Coastguard Worker  let Inst{9-8} = 0b11;
4062*9880d681SAndroid Build Coastguard Worker  let Inst{7-1} = r9_2{8-2};
4063*9880d681SAndroid Build Coastguard Worker}
4064*9880d681SAndroid Build Coastguard Worker
4065*9880d681SAndroid Build Coastguard Workerlet Defs = [PC, P0], Uses = [P0] in {
4066*9880d681SAndroid Build Coastguard Worker  def J4_tstbit0_tp0_jump_nt : CJInst_tstbit_R0<"p0", 0, "nt">;
4067*9880d681SAndroid Build Coastguard Worker  def J4_tstbit0_tp0_jump_t : CJInst_tstbit_R0<"p0", 0, "t">;
4068*9880d681SAndroid Build Coastguard Worker  def J4_tstbit0_fp0_jump_nt : CJInst_tstbit_R0<"p0", 1, "nt">;
4069*9880d681SAndroid Build Coastguard Worker  def J4_tstbit0_fp0_jump_t : CJInst_tstbit_R0<"p0", 1, "t">;
4070*9880d681SAndroid Build Coastguard Worker}
4071*9880d681SAndroid Build Coastguard Worker
4072*9880d681SAndroid Build Coastguard Workerlet Defs = [PC, P1], Uses = [P1] in {
4073*9880d681SAndroid Build Coastguard Worker  def J4_tstbit0_tp1_jump_nt : CJInst_tstbit_R0<"p1", 0, "nt">;
4074*9880d681SAndroid Build Coastguard Worker  def J4_tstbit0_tp1_jump_t : CJInst_tstbit_R0<"p1", 0, "t">;
4075*9880d681SAndroid Build Coastguard Worker  def J4_tstbit0_fp1_jump_nt : CJInst_tstbit_R0<"p1", 1, "nt">;
4076*9880d681SAndroid Build Coastguard Worker  def J4_tstbit0_fp1_jump_t : CJInst_tstbit_R0<"p1", 1, "t">;
4077*9880d681SAndroid Build Coastguard Worker}
4078*9880d681SAndroid Build Coastguard Worker
4079*9880d681SAndroid Build Coastguard Worker
4080*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, hasSideEffects = 0,
4081*9880d681SAndroid Build Coastguard Worker    isExtentSigned = 1, isPredicated = 1, isPredicatedNew = 1,
4082*9880d681SAndroid Build Coastguard Worker    isExtendable = 1, opExtentBits = 11, opExtentAlign = 2,
4083*9880d681SAndroid Build Coastguard Worker    opExtendable = 2, isTerminator = 1 in
4084*9880d681SAndroid Build Coastguard Workerclass CJInst_RR<string px, string op, bit np, string tnt>
4085*9880d681SAndroid Build Coastguard Worker  : InstHexagon<(outs), (ins IntRegs:$Rs, IntRegs:$Rt, brtarget:$r9_2),
4086*9880d681SAndroid Build Coastguard Worker  ""#px#" = cmp."#op#"($Rs, $Rt); if ("
4087*9880d681SAndroid Build Coastguard Worker   #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2",
4088*9880d681SAndroid Build Coastguard Worker  [], "", COMPOUND, TypeCOMPOUND>, OpcodeHexagon {
4089*9880d681SAndroid Build Coastguard Worker  bits<4> Rs;
4090*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
4091*9880d681SAndroid Build Coastguard Worker  bits<11> r9_2;
4092*9880d681SAndroid Build Coastguard Worker
4093*9880d681SAndroid Build Coastguard Worker  // np: !p[01]
4094*9880d681SAndroid Build Coastguard Worker  let isPredicatedFalse = np;
4095*9880d681SAndroid Build Coastguard Worker  // tnt: Taken/Not Taken
4096*9880d681SAndroid Build Coastguard Worker  let isBrTaken = !if (!eq(tnt, "t"), "true", "false");
4097*9880d681SAndroid Build Coastguard Worker  let isTaken   = !if (!eq(tnt, "t"), 1, 0);
4098*9880d681SAndroid Build Coastguard Worker
4099*9880d681SAndroid Build Coastguard Worker  let IClass = 0b0001;
4100*9880d681SAndroid Build Coastguard Worker  let Inst{27-23} = !if (!eq(op, "eq"),  0b01000,
4101*9880d681SAndroid Build Coastguard Worker                    !if (!eq(op, "gt"),  0b01001,
4102*9880d681SAndroid Build Coastguard Worker                    !if (!eq(op, "gtu"), 0b01010, 0)));
4103*9880d681SAndroid Build Coastguard Worker  let Inst{22} = np;
4104*9880d681SAndroid Build Coastguard Worker  let Inst{21-20} = r9_2{10-9};
4105*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rs;
4106*9880d681SAndroid Build Coastguard Worker  let Inst{13} = !if (!eq(tnt, "t"), 1, 0);
4107*9880d681SAndroid Build Coastguard Worker  // px: Predicate reg 0/1
4108*9880d681SAndroid Build Coastguard Worker  let Inst{12} = !if (!eq(px, "!p1"), 1,
4109*9880d681SAndroid Build Coastguard Worker                 !if (!eq(px,  "p1"), 1, 0));
4110*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rt;
4111*9880d681SAndroid Build Coastguard Worker  let Inst{7-1} = r9_2{8-2};
4112*9880d681SAndroid Build Coastguard Worker}
4113*9880d681SAndroid Build Coastguard Worker
4114*9880d681SAndroid Build Coastguard Worker// P[10] taken/not taken.
4115*9880d681SAndroid Build Coastguard Workermulticlass T_tnt_CJInst_RR<string op, bit np> {
4116*9880d681SAndroid Build Coastguard Worker  let Defs = [PC, P0], Uses = [P0] in {
4117*9880d681SAndroid Build Coastguard Worker    def NAME#p0_jump_nt : CJInst_RR<"p0", op, np, "nt">;
4118*9880d681SAndroid Build Coastguard Worker    def NAME#p0_jump_t : CJInst_RR<"p0", op, np, "t">;
4119*9880d681SAndroid Build Coastguard Worker  }
4120*9880d681SAndroid Build Coastguard Worker  let Defs = [PC, P1], Uses = [P1] in {
4121*9880d681SAndroid Build Coastguard Worker    def NAME#p1_jump_nt : CJInst_RR<"p1", op, np, "nt">;
4122*9880d681SAndroid Build Coastguard Worker    def NAME#p1_jump_t : CJInst_RR<"p1", op, np, "t">;
4123*9880d681SAndroid Build Coastguard Worker  }
4124*9880d681SAndroid Build Coastguard Worker}
4125*9880d681SAndroid Build Coastguard Worker// Predicate / !Predicate
4126*9880d681SAndroid Build Coastguard Workermulticlass T_pnp_CJInst_RR<string op>{
4127*9880d681SAndroid Build Coastguard Worker  defm J4_cmp#NAME#_t : T_tnt_CJInst_RR<op, 0>;
4128*9880d681SAndroid Build Coastguard Worker  defm J4_cmp#NAME#_f : T_tnt_CJInst_RR<op, 1>;
4129*9880d681SAndroid Build Coastguard Worker}
4130*9880d681SAndroid Build Coastguard Worker// TypeCJ Instructions compare RR and jump
4131*9880d681SAndroid Build Coastguard Workerdefm eq : T_pnp_CJInst_RR<"eq">;
4132*9880d681SAndroid Build Coastguard Workerdefm gt : T_pnp_CJInst_RR<"gt">;
4133*9880d681SAndroid Build Coastguard Workerdefm gtu : T_pnp_CJInst_RR<"gtu">;
4134*9880d681SAndroid Build Coastguard Worker
4135*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, hasSideEffects = 0, isExtentSigned = 1,
4136*9880d681SAndroid Build Coastguard Worker    isPredicated = 1, isPredicatedNew = 1, isExtendable = 1, opExtentBits = 11,
4137*9880d681SAndroid Build Coastguard Worker    opExtentAlign = 2, opExtendable = 2, isTerminator = 1 in
4138*9880d681SAndroid Build Coastguard Workerclass CJInst_RU5<string px, string op, bit np, string tnt>
4139*9880d681SAndroid Build Coastguard Worker  : InstHexagon<(outs), (ins IntRegs:$Rs, u5Imm:$U5, brtarget:$r9_2),
4140*9880d681SAndroid Build Coastguard Worker  ""#px#" = cmp."#op#"($Rs, #$U5); if ("
4141*9880d681SAndroid Build Coastguard Worker    #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2",
4142*9880d681SAndroid Build Coastguard Worker  [], "", COMPOUND, TypeCOMPOUND>, OpcodeHexagon {
4143*9880d681SAndroid Build Coastguard Worker  bits<4> Rs;
4144*9880d681SAndroid Build Coastguard Worker  bits<5> U5;
4145*9880d681SAndroid Build Coastguard Worker  bits<11> r9_2;
4146*9880d681SAndroid Build Coastguard Worker
4147*9880d681SAndroid Build Coastguard Worker  // np: !p[01]
4148*9880d681SAndroid Build Coastguard Worker  let isPredicatedFalse = np;
4149*9880d681SAndroid Build Coastguard Worker  // tnt: Taken/Not Taken
4150*9880d681SAndroid Build Coastguard Worker  let isBrTaken = !if (!eq(tnt, "t"), "true", "false");
4151*9880d681SAndroid Build Coastguard Worker  let isTaken   = !if (!eq(tnt, "t"), 1, 0);
4152*9880d681SAndroid Build Coastguard Worker
4153*9880d681SAndroid Build Coastguard Worker  let IClass = 0b0001;
4154*9880d681SAndroid Build Coastguard Worker  let Inst{27-26} = 0b00;
4155*9880d681SAndroid Build Coastguard Worker  // px: Predicate reg 0/1
4156*9880d681SAndroid Build Coastguard Worker  let Inst{25} = !if (!eq(px, "!p1"), 1,
4157*9880d681SAndroid Build Coastguard Worker                 !if (!eq(px,  "p1"), 1, 0));
4158*9880d681SAndroid Build Coastguard Worker  let Inst{24-23} = !if (!eq(op, "eq"),  0b00,
4159*9880d681SAndroid Build Coastguard Worker                    !if (!eq(op, "gt"),  0b01,
4160*9880d681SAndroid Build Coastguard Worker                    !if (!eq(op, "gtu"), 0b10, 0)));
4161*9880d681SAndroid Build Coastguard Worker  let Inst{22} = np;
4162*9880d681SAndroid Build Coastguard Worker  let Inst{21-20} = r9_2{10-9};
4163*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rs;
4164*9880d681SAndroid Build Coastguard Worker  let Inst{13} = !if (!eq(tnt, "t"), 1, 0);
4165*9880d681SAndroid Build Coastguard Worker  let Inst{12-8} = U5;
4166*9880d681SAndroid Build Coastguard Worker  let Inst{7-1} = r9_2{8-2};
4167*9880d681SAndroid Build Coastguard Worker}
4168*9880d681SAndroid Build Coastguard Worker// P[10] taken/not taken.
4169*9880d681SAndroid Build Coastguard Workermulticlass T_tnt_CJInst_RU5<string op, bit np> {
4170*9880d681SAndroid Build Coastguard Worker  let Defs = [PC, P0], Uses = [P0] in {
4171*9880d681SAndroid Build Coastguard Worker    def NAME#p0_jump_nt : CJInst_RU5<"p0", op, np, "nt">;
4172*9880d681SAndroid Build Coastguard Worker    def NAME#p0_jump_t : CJInst_RU5<"p0", op, np, "t">;
4173*9880d681SAndroid Build Coastguard Worker  }
4174*9880d681SAndroid Build Coastguard Worker  let Defs = [PC, P1], Uses = [P1] in {
4175*9880d681SAndroid Build Coastguard Worker    def NAME#p1_jump_nt : CJInst_RU5<"p1", op, np, "nt">;
4176*9880d681SAndroid Build Coastguard Worker    def NAME#p1_jump_t : CJInst_RU5<"p1", op, np, "t">;
4177*9880d681SAndroid Build Coastguard Worker  }
4178*9880d681SAndroid Build Coastguard Worker}
4179*9880d681SAndroid Build Coastguard Worker// Predicate / !Predicate
4180*9880d681SAndroid Build Coastguard Workermulticlass T_pnp_CJInst_RU5<string op>{
4181*9880d681SAndroid Build Coastguard Worker  defm J4_cmp#NAME#i_t : T_tnt_CJInst_RU5<op, 0>;
4182*9880d681SAndroid Build Coastguard Worker  defm J4_cmp#NAME#i_f : T_tnt_CJInst_RU5<op, 1>;
4183*9880d681SAndroid Build Coastguard Worker}
4184*9880d681SAndroid Build Coastguard Worker// TypeCJ Instructions compare RI and jump
4185*9880d681SAndroid Build Coastguard Workerdefm eq : T_pnp_CJInst_RU5<"eq">;
4186*9880d681SAndroid Build Coastguard Workerdefm gt : T_pnp_CJInst_RU5<"gt">;
4187*9880d681SAndroid Build Coastguard Workerdefm gtu : T_pnp_CJInst_RU5<"gtu">;
4188*9880d681SAndroid Build Coastguard Worker
4189*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, hasSideEffects = 0, isExtentSigned = 1,
4190*9880d681SAndroid Build Coastguard Worker    isPredicated = 1, isPredicatedFalse = 1, isPredicatedNew = 1,
4191*9880d681SAndroid Build Coastguard Worker    isExtendable = 1, opExtentBits = 11, opExtentAlign = 2, opExtendable = 1,
4192*9880d681SAndroid Build Coastguard Worker    isTerminator = 1 in
4193*9880d681SAndroid Build Coastguard Workerclass CJInst_Rn1<string px, string op, bit np, string tnt>
4194*9880d681SAndroid Build Coastguard Worker  : InstHexagon<(outs), (ins IntRegs:$Rs, brtarget:$r9_2),
4195*9880d681SAndroid Build Coastguard Worker  ""#px#" = cmp."#op#"($Rs,#-1); if ("
4196*9880d681SAndroid Build Coastguard Worker  #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2",
4197*9880d681SAndroid Build Coastguard Worker  [], "", COMPOUND, TypeCOMPOUND>, OpcodeHexagon {
4198*9880d681SAndroid Build Coastguard Worker  bits<4> Rs;
4199*9880d681SAndroid Build Coastguard Worker  bits<11> r9_2;
4200*9880d681SAndroid Build Coastguard Worker
4201*9880d681SAndroid Build Coastguard Worker  // np: !p[01]
4202*9880d681SAndroid Build Coastguard Worker  let isPredicatedFalse = np;
4203*9880d681SAndroid Build Coastguard Worker  // tnt: Taken/Not Taken
4204*9880d681SAndroid Build Coastguard Worker  let isBrTaken = !if (!eq(tnt, "t"), "true", "false");
4205*9880d681SAndroid Build Coastguard Worker  let isTaken   = !if (!eq(tnt, "t"), 1, 0);
4206*9880d681SAndroid Build Coastguard Worker
4207*9880d681SAndroid Build Coastguard Worker  let IClass = 0b0001;
4208*9880d681SAndroid Build Coastguard Worker  let Inst{27-26} = 0b00;
4209*9880d681SAndroid Build Coastguard Worker  let Inst{25} = !if (!eq(px, "!p1"), 1,
4210*9880d681SAndroid Build Coastguard Worker                 !if (!eq(px,  "p1"), 1, 0));
4211*9880d681SAndroid Build Coastguard Worker
4212*9880d681SAndroid Build Coastguard Worker  let Inst{24-23} = 0b11;
4213*9880d681SAndroid Build Coastguard Worker  let Inst{22} = np;
4214*9880d681SAndroid Build Coastguard Worker  let Inst{21-20} = r9_2{10-9};
4215*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rs;
4216*9880d681SAndroid Build Coastguard Worker  let Inst{13} = !if (!eq(tnt, "t"), 1, 0);
4217*9880d681SAndroid Build Coastguard Worker  let Inst{9-8} = !if (!eq(op, "eq"),  0b00,
4218*9880d681SAndroid Build Coastguard Worker                  !if (!eq(op, "gt"),  0b01, 0));
4219*9880d681SAndroid Build Coastguard Worker  let Inst{7-1} = r9_2{8-2};
4220*9880d681SAndroid Build Coastguard Worker}
4221*9880d681SAndroid Build Coastguard Worker
4222*9880d681SAndroid Build Coastguard Worker// P[10] taken/not taken.
4223*9880d681SAndroid Build Coastguard Workermulticlass T_tnt_CJInst_Rn1<string op, bit np> {
4224*9880d681SAndroid Build Coastguard Worker  let Defs = [PC, P0], Uses = [P0] in {
4225*9880d681SAndroid Build Coastguard Worker    def NAME#p0_jump_nt : CJInst_Rn1<"p0", op, np, "nt">;
4226*9880d681SAndroid Build Coastguard Worker    def NAME#p0_jump_t : CJInst_Rn1<"p0", op, np, "t">;
4227*9880d681SAndroid Build Coastguard Worker  }
4228*9880d681SAndroid Build Coastguard Worker  let Defs = [PC, P1], Uses = [P1] in {
4229*9880d681SAndroid Build Coastguard Worker    def NAME#p1_jump_nt : CJInst_Rn1<"p1", op, np, "nt">;
4230*9880d681SAndroid Build Coastguard Worker    def NAME#p1_jump_t : CJInst_Rn1<"p1", op, np, "t">;
4231*9880d681SAndroid Build Coastguard Worker  }
4232*9880d681SAndroid Build Coastguard Worker}
4233*9880d681SAndroid Build Coastguard Worker// Predicate / !Predicate
4234*9880d681SAndroid Build Coastguard Workermulticlass T_pnp_CJInst_Rn1<string op>{
4235*9880d681SAndroid Build Coastguard Worker  defm J4_cmp#NAME#n1_t : T_tnt_CJInst_Rn1<op, 0>;
4236*9880d681SAndroid Build Coastguard Worker  defm J4_cmp#NAME#n1_f : T_tnt_CJInst_Rn1<op, 1>;
4237*9880d681SAndroid Build Coastguard Worker}
4238*9880d681SAndroid Build Coastguard Worker// TypeCJ Instructions compare -1 and jump
4239*9880d681SAndroid Build Coastguard Workerdefm eq : T_pnp_CJInst_Rn1<"eq">;
4240*9880d681SAndroid Build Coastguard Workerdefm gt : T_pnp_CJInst_Rn1<"gt">;
4241*9880d681SAndroid Build Coastguard Worker
4242*9880d681SAndroid Build Coastguard Worker// J4_jumpseti: Direct unconditional jump and set register to immediate.
4243*9880d681SAndroid Build Coastguard Workerlet Defs = [PC], isBranch = 1, hasSideEffects = 0, hasNewValue = 1,
4244*9880d681SAndroid Build Coastguard Worker    isExtentSigned = 1, opNewValue = 0, isExtendable = 1, opExtentBits = 11,
4245*9880d681SAndroid Build Coastguard Worker    opExtentAlign = 2, opExtendable = 2 in
4246*9880d681SAndroid Build Coastguard Workerdef J4_jumpseti: CJInst <
4247*9880d681SAndroid Build Coastguard Worker  (outs IntRegs:$Rd),
4248*9880d681SAndroid Build Coastguard Worker  (ins u6Imm:$U6, brtarget:$r9_2),
4249*9880d681SAndroid Build Coastguard Worker  "$Rd = #$U6 ; jump $r9_2"> {
4250*9880d681SAndroid Build Coastguard Worker    bits<4> Rd;
4251*9880d681SAndroid Build Coastguard Worker    bits<6> U6;
4252*9880d681SAndroid Build Coastguard Worker    bits<11> r9_2;
4253*9880d681SAndroid Build Coastguard Worker
4254*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0001;
4255*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b0110;
4256*9880d681SAndroid Build Coastguard Worker    let Inst{21-20} = r9_2{10-9};
4257*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = Rd;
4258*9880d681SAndroid Build Coastguard Worker    let Inst{13-8} = U6;
4259*9880d681SAndroid Build Coastguard Worker    let Inst{7-1} = r9_2{8-2};
4260*9880d681SAndroid Build Coastguard Worker  }
4261*9880d681SAndroid Build Coastguard Worker
4262*9880d681SAndroid Build Coastguard Worker// J4_jumpsetr: Direct unconditional jump and transfer register.
4263*9880d681SAndroid Build Coastguard Workerlet Defs = [PC], isBranch = 1, hasSideEffects = 0, hasNewValue = 1,
4264*9880d681SAndroid Build Coastguard Worker    isExtentSigned = 1, opNewValue = 0, isExtendable = 1, opExtentBits = 11,
4265*9880d681SAndroid Build Coastguard Worker    opExtentAlign = 2, opExtendable = 2 in
4266*9880d681SAndroid Build Coastguard Workerdef J4_jumpsetr: CJInst <
4267*9880d681SAndroid Build Coastguard Worker  (outs IntRegs:$Rd),
4268*9880d681SAndroid Build Coastguard Worker  (ins IntRegs:$Rs, brtarget:$r9_2),
4269*9880d681SAndroid Build Coastguard Worker  "$Rd = $Rs ; jump $r9_2"> {
4270*9880d681SAndroid Build Coastguard Worker    bits<4> Rd;
4271*9880d681SAndroid Build Coastguard Worker    bits<4> Rs;
4272*9880d681SAndroid Build Coastguard Worker    bits<11> r9_2;
4273*9880d681SAndroid Build Coastguard Worker
4274*9880d681SAndroid Build Coastguard Worker    let IClass = 0b0001;
4275*9880d681SAndroid Build Coastguard Worker    let Inst{27-24} = 0b0111;
4276*9880d681SAndroid Build Coastguard Worker    let Inst{21-20} = r9_2{10-9};
4277*9880d681SAndroid Build Coastguard Worker    let Inst{11-8} = Rd;
4278*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = Rs;
4279*9880d681SAndroid Build Coastguard Worker    let Inst{7-1} = r9_2{8-2};
4280*9880d681SAndroid Build Coastguard Worker  }
4281*9880d681SAndroid Build Coastguard Worker
4282*9880d681SAndroid Build Coastguard Worker// Duplex instructions
4283*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
4284*9880d681SAndroid Build Coastguard Workerinclude "HexagonIsetDx.td"
4285