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