]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARC/ARCInstrInfo.td
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / ARC / ARCInstrInfo.td
1 //===- ARCInstrInfo.td - Target Description for ARC --------*- tablegen -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file describes the ARC instructions in TableGen format.
10 //
11 //===----------------------------------------------------------------------===//
12
13 include "ARCInstrFormats.td"
14
15 // ---------------------------------------------------------------------------
16 // Selection DAG Nodes.
17 // ---------------------------------------------------------------------------
18
19 // Selection DAG types.
20 def SDT_ARCcmptst : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
21 def SDT_ARCcmov : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>;
22 def SDT_ARCmov : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>]>;
23 def SDT_ARCbrcc : SDTypeProfile<0, 4, []>;
24 def SDT_ARCBranchLink : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
25 def SDT_ARCCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,
26                                            SDTCisVT<1, i32> ]>;
27 def SDT_ARCCallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i32>,
28                                          SDTCisVT<1, i32> ]>;
29
30
31 // Global Address.
32 def ARCGAWrapper : SDNode<"ARCISD::GAWRAPPER", SDT_ARCmov, []>;
33
34 // Comparison
35 def ARCcmp : SDNode<"ARCISD::CMP", SDT_ARCcmptst, [SDNPOutGlue]>;
36
37 // Conditionanal mov
38 def ARCcmov : SDNode<"ARCISD::CMOV", SDT_ARCcmov, [SDNPInGlue]>;
39
40 // Conditional Branch
41 def ARCbrcc : SDNode<"ARCISD::BRcc", SDT_ARCbrcc,
42                        [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
43
44 // Direct Call
45 def ARCBranchLink     : SDNode<"ARCISD::BL",SDT_ARCBranchLink,
46                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
47                              SDNPVariadic]>;
48
49 // Indirect Call
50 def ARCJumpLink       : SDNode<"ARCISD::JL",SDT_ARCBranchLink,
51                                  [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
52                                   SDNPVariadic]>;
53 // Call return
54 def ret      : SDNode<"ARCISD::RET", SDTNone,
55                       [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
56
57 // Call sequencing nodes.
58 // These are target-independent nodes, but have target-specific formats.
59 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARCCallSeqStart,
60                            [SDNPHasChain, SDNPOutGlue]>;
61 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_ARCCallSeqEnd,
62                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
63
64 //===----------------------------------------------------------------------===//
65 // Instruction Pattern Stuff
66 //===----------------------------------------------------------------------===//
67
68 def imm32 : ImmLeaf<i32, [{
69   return (Imm & 0xFFFFFFFF) == Imm;
70 }]>;
71
72 // Addressing modes
73 def FrameADDR_ri : ComplexPattern<i32, 2, "SelectFrameADDR_ri",
74                                   [add, frameindex], []>;
75 def AddrModeS9 : ComplexPattern<i32, 2, "SelectAddrModeS9", []>;
76 def AddrModeImm : ComplexPattern<i32, 2, "SelectAddrModeImm", []>;
77 def AddrModeFar : ComplexPattern<i32, 2, "SelectAddrModeFar", []>;
78
79 //===----------------------------------------------------------------------===//
80 // Instruction Class Templates
81 //===----------------------------------------------------------------------===//
82
83 //===----------------------------------------------------------------------===//
84 // Pseudo Instructions
85 //===----------------------------------------------------------------------===//
86
87 let Defs = [SP], Uses = [SP] in {
88 def ADJCALLSTACKDOWN : PseudoInstARC<(outs), (ins i32imm:$amt, i32imm:$amt2),
89                                "# ADJCALLSTACKDOWN $amt, $amt2",
90                                [(callseq_start timm:$amt, timm:$amt2)]>;
91 def ADJCALLSTACKUP : PseudoInstARC<(outs), (ins i32imm:$amt1, i32imm:$amt2),
92                             "# ADJCALLSTACKUP $amt1",
93                             [(callseq_end timm:$amt1, timm:$amt2)]>;
94 }
95
96 def GETFI : PseudoInstARC<(outs GPR32:$dst), (ins MEMii:$addr),
97                              "pldfi $dst, $addr",
98                              [(set GPR32:$dst, FrameADDR_ri:$addr)]>;
99
100
101 def ST_FAR : PseudoInstARC<(outs), (ins GPR32:$dst, MEMrlimm:$addr),
102                              "ST_FAR $dst, $addr",
103                              [(store GPR32:$dst, AddrModeFar:$addr)]>;
104
105 def STH_FAR : PseudoInstARC<(outs), (ins GPR32:$dst, MEMrlimm:$addr),
106                              "STH_FAR $dst, $addr",
107                              [(truncstorei16 GPR32:$dst, AddrModeFar:$addr)]>;
108
109 def STB_FAR : PseudoInstARC<(outs), (ins GPR32:$dst, MEMrlimm:$addr),
110                              "STB_FAR $dst, $addr",
111                              [(truncstorei8 GPR32:$dst, AddrModeFar:$addr)]>;
112
113 //===----------------------------------------------------------------------===//
114 // Instruction Generation multiclasses.
115 // Generate many variants of a single instruction with a single defining
116 // multiclass.  These classes do not contain Selection DAG patterns.
117 //===----------------------------------------------------------------------===//
118
119 // Generic 3 operand binary instructions (i.e., add r0, r1, r2).
120 multiclass ArcBinaryInst<bits<5> major, bits<6> mincode,
121                        string opasm> {
122   // 3 register variant.
123   def _rrr : F32_DOP_RR<major, mincode, 0, (outs GPR32:$A),
124                         (ins GPR32:$B, GPR32:$C),
125                         !strconcat(opasm, "\t$A, $B, $C"),
126                         []>;
127   def _f_rrr : F32_DOP_RR<major, mincode, 1, (outs GPR32:$A),
128                           (ins GPR32:$B, GPR32:$C),
129                           !strconcat(opasm, ".f\t$A, $B, $C"),
130                           []>
131   { let Defs = [STATUS32]; }
132
133   // 2 register with unsigned 6-bit immediate variant.
134   def _rru6 : F32_DOP_RU6<major, mincode, 0, (outs GPR32:$A),
135                           (ins GPR32:$B, immU6:$U6),
136                           !strconcat(opasm, "\t$A, $B, $U6"),
137                           []>;
138   def _f_rru6 : F32_DOP_RU6<major, mincode, 1, (outs GPR32:$A),
139                             (ins GPR32:$B, immU6:$U6),
140                             !strconcat(opasm, ".f\t$A, $B, $U6"),
141                             []>
142   { let Defs = [STATUS32]; }
143
144   // 2 register with 32-bit immediate variant.
145   def _rrlimm : F32_DOP_RLIMM<major, mincode, 0,
146                               (outs GPR32:$A),
147                               (ins GPR32:$B, i32imm:$LImm),
148                               !strconcat(opasm, "\t$A, $B, $LImm"),
149                               []>;
150   def _f_rrlimm : F32_DOP_RLIMM<major, mincode, 1,
151                                 (outs GPR32:$A),
152                                 (ins GPR32:$B, i32imm:$LImm),
153                                 !strconcat(opasm, ".f\t$A, $B, $LImm"),
154                                 []>
155   { let Defs = [STATUS32]; }
156
157   // 2 matched-register with signed 12-bit immediate variant (add r0, r0, -1).
158   def _rrs12 : F32_DOP_RS12<major, mincode, 0,
159                             (outs GPR32:$B),
160                             (ins GPR32:$in, immS<12>:$S12),
161                             !strconcat(opasm, "\t$B, $in, $S12"),
162                             []>
163   { let Constraints = "$B = $in"; }
164   def _f_rrs12 : F32_DOP_RS12<major, mincode, 1,
165                               (outs GPR32:$B),
166                               (ins GPR32:$in, immS<12>:$S12),
167                               !strconcat(opasm, ".f\t$B, $in, $S12"),
168                               []>
169   { let Constraints = "$B = $in"; let Defs = [STATUS32]; }
170 }
171
172 // Special multivariant GEN4 DOP format instruction that take 2 registers.
173 // This is the class that is used for various comparison instructions.
174 multiclass ArcSpecialDOPInst<bits<6> subop, string opasm, bit F> {
175   def _rr : F32_DOP_RR<0b00100, subop, F, (outs), (ins GPR32:$B, GPR32:$C),
176                !strconcat(opasm, "\t$B, $C"),
177                []>;
178
179   def _ru6 : F32_DOP_RU6<0b00100, subop, F, (outs), (ins GPR32:$B, i32imm:$U6),
180                !strconcat(opasm, "\t$B, $U6"),
181                []>;
182
183   def _rlimm : F32_DOP_RLIMM<0b00100, subop, F, (outs),
184                (ins GPR32:$B, i32imm:$LImm),
185                !strconcat(opasm, "\t$B, $LImm"),
186                []>;
187 }
188
189 // Generic 2-operand unary instructions.
190 multiclass ArcUnaryInst<bits<5> major, bits<6> subop,
191                         string opasm> {
192   def _rr : F32_SOP_RR<major, subop, 0, (outs GPR32:$B), (ins GPR32:$C),
193                        !strconcat(opasm, "\t$B, $C"), []>;
194
195   def _f_rr : F32_SOP_RR<major, subop, 1, (outs GPR32:$B), (ins GPR32:$C),
196                        !strconcat(opasm, ".f\t$B, $C"), []>
197   { let Defs = [STATUS32]; }
198 }
199
200
201 multiclass ArcBinaryGEN4Inst<bits<6> mincode, string opasm> :
202   ArcBinaryInst<0b00100, mincode, opasm>;
203 multiclass ArcBinaryEXT5Inst<bits<6> mincode, string opasm> :
204   ArcBinaryInst<0b00101, mincode, opasm>;
205
206 multiclass ArcUnaryGEN4Inst<bits<6> mincode, string opasm> :
207   ArcUnaryInst<0b00100, mincode, opasm>;
208
209 // Pattern generation for differnt instruction variants.
210 multiclass MultiPat<SDPatternOperator InFrag,
211                Instruction RRR, Instruction RRU6, Instruction RRLImm> {
212   def _rrr : Pat<(InFrag i32:$B, i32:$C), (RRR i32:$B, i32:$C)>;
213   def _rru6 : Pat<(InFrag i32:$B, immU6:$U6), (RRU6 i32:$B, immU6:$U6)>;
214   def _rrlimm : Pat<(InFrag i32:$B, imm32:$LImm), (RRLImm i32:$B, imm32:$LImm)>;
215 }
216
217 // ---------------------------------------------------------------------------
218 // Instruction defintions and patterns for 3 operand binary instructions.
219 // ---------------------------------------------------------------------------
220
221 // Definitions for 3 operand binary instructions.
222 defm ADD : ArcBinaryGEN4Inst<0b000000, "add">;
223 defm SUB : ArcBinaryGEN4Inst<0b000010, "sub">;
224 defm SUB1 : ArcBinaryGEN4Inst<0b010111, "sub1">;
225 defm SUB2 : ArcBinaryGEN4Inst<0b011000, "sub2">;
226 defm SUB3 : ArcBinaryGEN4Inst<0b011001, "sub3">;
227 defm OR  : ArcBinaryGEN4Inst<0b000101, "or">;
228 defm AND : ArcBinaryGEN4Inst<0b000100, "and">;
229 defm XOR : ArcBinaryGEN4Inst<0b000111, "xor">;
230 defm MAX : ArcBinaryGEN4Inst<0b001000, "max">;
231 defm MIN : ArcBinaryGEN4Inst<0b001001, "min">;
232 defm ASL : ArcBinaryEXT5Inst<0b000000, "asl">;
233 defm LSR : ArcBinaryEXT5Inst<0b000001, "lsr">;
234 defm ASR : ArcBinaryEXT5Inst<0b000010, "asr">;
235 defm ROR : ArcBinaryEXT5Inst<0b000011, "ror">;
236 defm MPY  : ArcBinaryGEN4Inst<0b011010, "mpy">;
237 defm MPYM : ArcBinaryGEN4Inst<0b011011, "mpym">;
238 defm MPYMU : ArcBinaryGEN4Inst<0b011100, "mpymu">;
239 defm SETEQ : ArcBinaryGEN4Inst<0b111000, "seteq">;
240
241 // Patterns for 3 operand binary instructions.
242 defm : MultiPat<add, ADD_rrr, ADD_rru6, ADD_rrlimm>;
243 defm : MultiPat<sub, SUB_rrr, SUB_rru6, SUB_rrlimm>;
244 defm : MultiPat<or, OR_rrr, OR_rru6, OR_rrlimm>;
245 defm : MultiPat<and, AND_rrr, AND_rru6, AND_rrlimm>;
246 defm : MultiPat<xor, XOR_rrr, XOR_rru6, XOR_rrlimm>;
247 defm : MultiPat<smax, MAX_rrr, MAX_rru6, MAX_rrlimm>;
248 defm : MultiPat<smin, MIN_rrr, MIN_rru6, MIN_rrlimm>;
249 defm : MultiPat<shl, ASL_rrr, ASL_rru6, ASL_rrlimm>;
250 defm : MultiPat<srl, LSR_rrr, LSR_rru6, LSR_rrlimm>;
251 defm : MultiPat<sra, ASR_rrr, ASR_rru6, ASR_rrlimm>;
252 defm : MultiPat<rotr, ROR_rrr, ROR_rru6, ROR_rrlimm>;
253 defm : MultiPat<mul, MPY_rrr, MPY_rru6, MPY_rrlimm>;
254 defm : MultiPat<mulhs, MPYM_rrr, MPYM_rru6, MPYM_rrlimm>;
255 defm : MultiPat<mulhu, MPYMU_rrr, MPYMU_rru6, MPYMU_rrlimm>;
256
257 // ---------------------------------------------------------------------------
258 // Unary Instruction definitions.
259 // ---------------------------------------------------------------------------
260 // General unary instruction definitions.
261 defm SEXB : ArcUnaryGEN4Inst<0b000101, "sexb">;
262 defm SEXH : ArcUnaryGEN4Inst<0b000110, "sexh">;
263
264 // General Unary Instruction fragments.
265 def : Pat<(sext_inreg i32:$a, i8), (SEXB_rr i32:$a)>;
266 def : Pat<(sext_inreg i32:$a, i16), (SEXH_rr i32:$a)>;
267
268 // Comparison instruction definition
269 let isCompare = 1, Defs = [STATUS32] in {
270 defm CMP : ArcSpecialDOPInst<0b001100, "cmp", 1>;
271 }
272
273 def cmp : PatFrag<(ops node:$op1, node:$op2), (ARCcmp $op1, $op2)>;
274 defm : MultiPat<cmp, CMP_rr, CMP_ru6, CMP_rlimm>;
275
276 // ---------------------------------------------------------------------------
277 // MOV instruction and variants (conditional mov).
278 // ---------------------------------------------------------------------------
279 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
280 def MOV_rs12 : F32_DOP_RS12<0b00100, 0b001010, 0,
281                  (outs GPR32:$B), (ins immS<12>:$S12),
282                  "mov\t$B, $S12",
283                  [(set GPR32:$B, immS<12>:$S12)]>;
284 }
285
286 def MOV_rr : F32_DOP_RR<0b00100, 0b001010, 0,
287                 (outs GPR32:$B), (ins GPR32:$C),
288                 "mov\t$B, $C", []>;
289
290 def MOV_rlimm : F32_DOP_RLIMM<0b00100, 0b001010, 0,
291                       (outs GPR32:$B), (ins i32imm:$LImm),
292                       "mov\t$B, $LImm", []>;
293
294 def MOV_ru6 : F32_DOP_RU6<0b00100, 0b001010, 0,
295                           (outs GPR32:$B), (ins immU6:$U6),
296                           "mov\t$B, $U6", []>;
297
298 def cmov : PatFrag<(ops node:$op1, node:$op2, node:$cc),
299                    (ARCcmov $op1, $op2, $cc)>;
300 let Uses = [STATUS32] in {
301 def MOVcc : F32_DOP_CC_RR<0b00100, 0b001010, 0,
302                (outs GPR32:$B),
303                (ins GPR32:$C, GPR32:$fval, cmovpred:$cc),
304                !strconcat("mov.", "$cc\t$B, $C"),
305                [(set GPR32:$B, (cmov i32:$C, i32:$fval, cmovpred:$cc))]> {
306   let Constraints = "$B = $fval";
307 }
308 }
309 def : Pat<(ARCGAWrapper tglobaladdr:$addr),
310            (MOV_rlimm tglobaladdr:$addr)>;
311
312 def : Pat<(ARCGAWrapper tjumptable:$addr),
313            (MOV_rlimm tjumptable:$addr)>;
314
315
316 // ---------------------------------------------------------------------------
317 // Control flow instructions (branch, return, calls, etc).
318 // ---------------------------------------------------------------------------
319
320 // Branch instructions
321 let isBranch = 1, isTerminator = 1 in {
322
323   // Unconditional branch.
324   let isBarrier = 1 in
325   def BR : F32_BR0_UCOND_FAR<(outs), (ins btargetS25:$S25),
326                              "b\t$S25", [(br bb:$S25)]>;
327
328   let Uses=[STATUS32] in
329   // Conditional branch.
330   def Bcc : F32_BR0_COND<(outs), (ins btargetS21:$S21, ccond:$cc),
331                          "b$cc\t$S21", []>;
332
333   // Compare and branch (limited range).
334   def BRcc_rr  : F32_BR1_BCC<(outs),
335                              (ins btargetS9:$S9, GPR32:$B, GPR32:$C, brccond:$cc),
336                              "br$cc\t$B, $C, $S9", 0, []>;
337   def BRcc_ru6 : F32_BR1_BCC<(outs),
338                              (ins btargetS9:$S9, GPR32:$B, immU6:$C, brccond:$cc),
339                              "br$cc\t$B, $C, $S9", 1, []>;
340
341   // Pseudo compare and branch.
342   // After register allocation, this can expand into either a limited range
343   // Compare and branch (BRcc), or into CMP + Bcc.
344   // At worst, this expands into 2 4-byte instructions.
345   def BRcc_rr_p : PseudoInstARC<(outs),
346                                 (ins btarget:$T, GPR32:$B, GPR32:$C, ccond:$cc),
347                                 "pbr$cc\t$B, $C, $T", 
348                                 [(ARCbrcc bb:$T, i32:$B, i32:$C, imm32:$cc)]>
349                                 { let Size = 8; }
350
351   def BRcc_ru6_p : PseudoInstARC<(outs),
352                                  (ins btarget:$T, GPR32:$B, i32imm:$C, ccond:$cc),
353                                  "pbr$cc\t$B, $C, $T",
354                                  [(ARCbrcc bb:$T, i32:$B, immU6:$C, imm32:$cc)]>
355                                  { let Size = 8; }
356 } // let isBranch, isTerminator
357
358 // Unconditional Jump.
359 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
360   // Indirect.
361   let isIndirectBranch = 1 in
362   def J :  F32_DOP_RR<0b00100, 0b100000, 0,
363                       (outs), (ins GPR32:$C),
364                       "j\t[$C]", [(brind i32:$C)]>;
365
366   // Direct.
367   def J_LImm : F32_DOP_RLIMM<0b00100, 0b100000, 0,
368                              (outs), (ins i32imm:$LImm),
369                              "j\t$LImm", []>;
370 }
371
372 // Call instructions.
373 let isCall = 1, isBarrier = 1, Defs = [BLINK], Uses = [SP] in {
374   // Direct unconditional call.
375   def BL : F32_BR1_BL_UCOND_FAR<(outs), (ins calltargetS25:$S25),
376                       "bl\t$S25", [(ARCBranchLink tglobaladdr:$S25)]>;
377
378   // Indirect unconditional call.
379   let isIndirectBranch = 1 in
380   def JL : F32_DOP_RR<0b00100, 0b100010, 0, (outs), (ins GPR32:$C),
381                      "jl\t[$C]", [(ARCJumpLink i32:$C)]>;
382
383   // Direct unconditional call.
384   def JL_LImm : F32_DOP_RLIMM<0b00100, 0b100010, 0, (outs), (ins i32imm:$LImm),
385                               "jl\t$LImm", []>;
386 } // let isCall, isBarrier, Defs, Uses
387
388 // Pattern to generate BL instruction.
389 def : Pat<(ARCBranchLink texternalsym:$dst), (BL texternalsym:$dst)>;
390
391 // Return from call.
392 let isReturn = 1, isTerminator = 1, isBarrier = 1  in
393 // This is a specialized 2-byte instruction that doesn't generalize
394 // to any larger 2-byte class, so go ahead and define it here.
395 def J_S_BLINK : InstARC<2, (outs), (ins), "j_s\t[%blink]", [(ret)]> {
396   let Inst{15-0} = 0b0111111011100000;
397 }
398
399 //----------------------------------------------------------------------------
400 // Compact stack-based operations.
401 //----------------------------------------------------------------------------
402
403 // 2-byte push/pop blink instructions commonly used for prolog/epilog
404 // generation.  These 2 instructions are actually specialized 2-byte
405 // format instructions that aren't generalized to a larger 2-byte
406 // class, so we might as well have them here.
407 let Uses = [BLINK], Defs = [SP] in
408 def PUSH_S_BLINK : F16_SP_OPS_buconst<0b111, "push_s">;
409
410 let Defs = [BLINK, SP] in
411 def POP_S_BLINK : F16_SP_OPS_buconst<0b110, "pop_s">;
412
413 def PUSH_S_r : F16_SP_OPS_uconst<0b110,
414   (outs), (ins GPR32Reduced:$b3), "push_s">;
415 def POP_S_r : F16_SP_OPS_uconst<0b111,
416   (outs GPR32Reduced:$b3), (ins), "pop_s">;
417
418 def SP_SUB_SP_S : F16_SP_OPS_bconst<0b001, "sub_s">;
419 def SP_ADD_SP_S : F16_SP_OPS_bconst<0b000, "add_s">;
420 def SP_ADD_S : F16_SP_OPS_u7_aligned<0b100,
421                 (outs GPR32Reduced:$b3), (ins immU<7>:$u7),
422                 "add_s\t$b3, %sp, $u7">;
423
424 def SP_LD_S : F16_SP_LD<0b000, "ld_s">;
425 def SP_LDB_S : F16_SP_LD<0b001, "ldb_s">;
426 def SP_ST_S : F16_SP_ST<0b010, "st_s">;
427 def SP_STB_S : F16_SP_ST<0b011, "stb_s">;
428
429 def LEAVE_S : F16_SP_OPS<0b110,
430   (outs), (ins immU<7>:$u7), "leave_s\t$u7"> {
431
432   bits<7> u7;
433   
434   let fieldB = u7{6-4};
435   let fieldU{4-1} = u7{3-0};
436   let fieldU{0} = 0b0;
437 }
438
439 def ENTER_S : F16_SP_OPS<0b111,
440   (outs), (ins immU<6>:$u6), "enter_s\t$u6"> {
441
442   bits<6> u6;
443   
444   let fieldB{2} = 0;
445   let fieldB{1-0} = u6{5-4};
446   let fieldU{4-1} = u6{3-0};
447   let fieldU{0} = 0b0;
448 }
449
450 //----------------------------------------------------------------------------
451 // Compact Move/Load instructions.
452 //----------------------------------------------------------------------------
453 class COMPACT_MOV_S :
454   F16_COMPACT<0b0, (outs GPR32:$g), (ins GPR32:$h),
455           "mov_s\t$g, $h"> {  
456   let DecoderMethod = "DecodeMoveHRegInstruction";
457 }
458
459 def COMPACT_MOV_S_limm : COMPACT_MOV_S {
460   bits<32> LImm;  
461   let Inst{47-16} = LImm;
462
463   bits<5> LImmReg = 0b11110;  
464   let Inst{7-5} = LImmReg{2-0};
465   let Inst{1-0} = LImmReg{4-3};
466
467   let Size = 6;  
468 }
469
470 def COMPACT_MOV_S_hreg : COMPACT_MOV_S;
471
472 def COMPACT_LD_S :
473   F16_COMPACT<0b1, (outs GPR32:$r), (ins GPR32:$h, immU<5>:$u5),
474           "ld_s\t$r, [$h, $u5]"> {
475   bits<5> u5;
476   bits<2> r;
477
478   let Inst{10} = u5{4};
479   let Inst{9-8} = r;
480   let Inst{4-3} = u5{3-2};
481   let u5{1-0} = 0b00;
482 }
483
484 //----------------------------------------------------------------------------
485 // Compact Load/Add/Sub.
486 //----------------------------------------------------------------------------
487 def LD_S_AS_rrr : F16_LD_SUB<0b0, "ld_s.as\t$a, [$b, $c]">;
488 def SUB_S_rrr : F16_LD_SUB<0b1, "sub_s\t$a, $b, $c">;
489 def ADD_S_rru6 : F16_ADD;
490
491 //----------------------------------------------------------------------------
492 // Compact Load/Store.
493 //----------------------------------------------------------------------------
494 def LD_S_s11 : F16_LD_ST_s11<0b0, "ld_s\t%r1, [%gp, $s11]">;
495 def ST_S_s11 : F16_LD_ST_s11<0b1, "st_s\t%r0, [%gp, $s11]">;
496 def LDI_S_u7 : F16_LDI_u7;
497
498 //----------------------------------------------------------------------------
499 // Indexed Jump or Execute.
500 //----------------------------------------------------------------------------
501 def JLI_S : F16_JLI_EI<0, "jli_s">;
502 def EI_S : F16_JLI_EI<1, "ei_s">;
503
504 //----------------------------------------------------------------------------
505 // Load/Add Register-Register.
506 //----------------------------------------------------------------------------
507 def LD_S_rrr : F16_LD_ADD_RR<0b00, "ld_s\t$a, [$b, $c]">;
508 def LDB_S_rrr : F16_LD_ADD_RR<0b01, "ldb_s\t$a, [$b, $c]">;
509 def LDH_S_rrr : F16_LD_ADD_RR<0b10, "ldh_s\t$a, [$b, $c]">;
510 def ADD_S_rrr : F16_LD_ADD_RR<0b11, "add_s\t$a, $b, $c">;
511
512 //----------------------------------------------------------------------------
513 // Load/Add GP-Relative.
514 //----------------------------------------------------------------------------
515 def GP_LD_S : F16_GP_LD_ADD<0b00, (ins immS<11>:$s),
516   "ld_s\t%r0, [%gp, $s]"> {
517
518   bits<11> s;
519   let Inst{8-0} = s{10-2};
520   let s{1-0} = 0b00;
521 }
522
523 def GP_LDB_S : F16_GP_LD_ADD<0b01, (ins immS<9>:$s),
524   "ldb_s\t%r0, [%gp, $s]"> {
525
526   bits<9> s;
527   let Inst{8-0} = s{8-0};
528 }
529
530 def GP_LDH_S : F16_GP_LD_ADD<0b10, (ins immS<10>:$s),
531   "ldh_s\t%r0, [%gp, $s]"> {
532
533   bits<10> s;
534   let Inst{8-0} = s{9-1};
535   let s{0} = 0b0;
536 }
537
538 def GP_ADD_S : F16_GP_LD_ADD<0b11, (ins immS<11>:$s),
539   "add_s\t%r0, %gp, $s"> {
540
541   bits<11> s;
542   let Inst{8-0} = s{10-2};
543   let s{1-0} = 0b00;
544 }
545
546 //----------------------------------------------------------------------------
547 // Load PCL-Relative.
548 //----------------------------------------------------------------------------
549 def PCL_LD : InstARC<2, (outs GPR32:$b), (ins immU<10>:$u10),
550  "ld_s\t$b, [%pcl, $u10]", []> {
551  
552   bits<3> b; 
553   bits<10> u10; 
554
555   let Inst{15-11} = 0b11010;
556   let Inst{10-8} = b;
557   let Inst{7-0} = u10{9-2};
558   let u10{1-0} = 0b00;
559 }
560
561 let isBranch = 1 in {
562   //----------------------------------------------------------------------------
563   // Branch on Compare Register with Zero.
564   //----------------------------------------------------------------------------
565   def BREQ_S : F16_BCC_REG<0b0, "breq_s">;
566   def BRNE_S : F16_BCC_REG<0b1, "brne_s">;
567
568   //----------------------------------------------------------------------------
569   // Branch Conditionally.
570   //----------------------------------------------------------------------------
571   let isBarrier = 1 in
572   def B_S : F16_BCC_s10<0b00, "b_s">;
573
574   def BEQ_S : F16_BCC_s10<0b01, "beq_s">;
575   def BNE_S : F16_BCC_s10<0b10, "bne_s">;
576   def BGT_S : F16_BCC_s7<0b000, "bgt_s">;
577   def BGE_S : F16_BCC_s7<0b001, "bge_s">;
578   def BLT_S : F16_BCC_s7<0b010, "blt_s">;
579   def BLE_S : F16_BCC_s7<0b011, "ble_s">;
580   def BHI_S : F16_BCC_s7<0b100, "bhi_s">;
581   def BHS_S : F16_BCC_s7<0b101, "bhs_s">;
582   def BLO_S : F16_BCC_s7<0b110, "blo_s">;
583   def BLS_S : F16_BCC_s7<0b111, "bls_s">;
584 } // let isBranch
585
586 def BL_S :
587   InstARC<2, (outs), (ins btargetS13:$s13), "bl_s\t$s13", []> {
588
589   let Inst{15-11} = 0b11111;
590   
591   bits<13> s13;
592   let Inst{10-0} = s13{12-2};
593   let s13{1-0} = 0b00;
594   
595   let isCall = 1;
596   let isBarrier = 1;
597 }
598
599 //----------------------------------------------------------------------------
600 // Add/Sub/Shift Register-Immediate.
601 //----------------------------------------------------------------------------
602 def ADD_S_ru3 : F16_ADD_IMM<0b00,"add_s">;
603 def SUB_S_ru3 : F16_ADD_IMM<0b01,"sub_s">;
604 def ASL_S_ru3 : F16_ADD_IMM<0b10,"asl_s">;
605 def ASR_S_ru3 : F16_ADD_IMM<0b11,"asr_s">;
606
607 //----------------------------------------------------------------------------
608 // Shift/Subtract/Bit Immediate.
609 //----------------------------------------------------------------------------
610 def ASL_S_ru5 : F16_SH_SUB_BIT_DST<0b000,"asl_s">;
611 def LSR_S_ru5 : F16_SH_SUB_BIT_DST<0b001,"lsr_s">;
612 def ASR_S_ru5 : F16_SH_SUB_BIT_DST<0b010,"asr_s">;
613 def SUB_S_ru5 : F16_SH_SUB_BIT_DST<0b011,"sub_s">;
614 def BSET_S_ru5 : F16_SH_SUB_BIT_DST<0b100,"bset_s">;
615 def BCLR_S_ru5 : F16_SH_SUB_BIT_DST<0b101,"bclr_s">;
616 def BMSK_S_ru5 : F16_SH_SUB_BIT_DST<0b110,"bmsk_s">;
617 def BTST_S_ru5 : F16_SH_SUB_BIT<0b111, "btst_s\t$b, $u5">;
618
619 //----------------------------------------------------------------------------
620 // Dual Register Operations.
621 //----------------------------------------------------------------------------
622 def ADD_S_rlimm :
623   F16_OP_HREG_LIMM<0b000, (outs GPR32:$b_s3), (ins i32imm:$LImm),
624           !strconcat("add_s", "\t$b_s3, $b_s3, $LImm")>;
625
626 def ADD_S_rr :
627   F16_OP_HREG<0b000, (outs GPR32:$b_s3), (ins GPR32:$h),
628           !strconcat("add_s", "\t$b_s3, $b_s3, $h")>;
629
630 def ADD_S_rs3 :
631   F16_OP_HREG<0b001, (outs GPR32:$h), (ins immC<3>:$b_s3),
632           !strconcat("add_s", "\t$h, $h, $b_s3")>;
633
634 def ADD_S_limms3 :
635   F16_OP_HREG_LIMM<0b001, (outs), (ins immC<3>:$b_s3, i32imm:$LImm),
636           !strconcat("add_s", "\t0, $LImm, $b_s3")>;
637
638 def MOV_S_NE_rlimm :
639   F16_OP_HREG_LIMM<0b111, (outs GPR32:$b_s3), (ins i32imm:$LImm),
640           !strconcat("mov_s.ne", "\t$b_s3, $LImm")>;
641
642 def MOV_S_NE_rr :
643   F16_OP_HREG<0b111,(outs GPR32:$b_s3), (ins GPR32:$h),
644           !strconcat("mov_s.ne", "\t$b_s3, $h")>;
645
646 def MOV_S_rs3 :
647   F16_OP_HREG<0b011, (outs GPR32:$h), (ins immC<3>:$b_s3),
648           !strconcat("mov_s", "\t$h, $b_s3")>;
649
650 def MOV_S_s3 :
651   F16_OP_HREG30<0b011, (outs), (ins immC<3>:$b_s3),
652           !strconcat("mov_s", "\t0, $b_s3")>;
653
654 def CMP_S_rlimm :
655   F16_OP_HREG_LIMM<0b100, (outs GPR32:$b_s3), (ins i32imm:$LImm),
656           !strconcat("cmp_s", "\t$b_s3, $LImm")>;
657
658 def CMP_S_rr :
659   F16_OP_HREG<0b100, (outs GPR32:$b_s3), (ins GPR32:$h),
660           !strconcat("cmp_s", "\t$b_s3, $h")>;
661
662 def CMP_S_rs3 :
663   F16_OP_HREG<0b101, (outs GPR32:$h), (ins immC<3>:$b_s3),
664           !strconcat("cmp_s", "\t$h, $b_s3")>;
665
666 def CMP_S_limms3 :
667   F16_OP_HREG_LIMM<0b101, (outs), (ins immC<3>:$b_s3, i32imm:$LImm),
668           !strconcat("cmp_s", "\t$LImm, $b_s3")>;
669
670 //----------------------------------------------------------------------------
671 // Compact MOV/ADD/CMP Immediate instructions.
672 //----------------------------------------------------------------------------
673 def MOV_S_u8 :
674   F16_OP_IMM<0b11011, (outs GPR32:$b), (ins immU<8>:$u8),
675           !strconcat("mov_s", "\t$b, $u8")> {
676   bits<8> u8;
677   let Inst{7-0} = u8;
678 }
679
680 def ADD_S_u7 :
681   F16_OP_U7<0b0, !strconcat("add_s", "\t$b, $b, $u7")>;
682
683 def CMP_S_u7 :
684   F16_OP_U7<0b1, !strconcat("cmp_s", "\t$b, $u7")>;
685
686 //----------------------------------------------------------------------------
687 // Compact Load/Store instructions with offset.
688 //----------------------------------------------------------------------------
689 def LD_S_OFF :
690   F16_LD_ST_WORD_OFF<0x10, (outs GPR32:$c), (ins GPR32:$b, immU<7>:$off),
691   "ld_s">;
692
693 def LDB_S_OFF :
694   F16_LD_ST_BYTE_OFF<0x11, (outs GPR32:$c), (ins GPR32:$b, immU<5>:$off),
695   "ldb_s">;
696
697 class F16_LDH_OFF<bits<5> opc, string asmstr> :
698   F16_LD_ST_HALF_OFF<opc, (outs GPR32:$c), (ins GPR32:$b, immU<6>:$off),
699   asmstr>;
700
701 def LDH_S_OFF : F16_LDH_OFF<0x12, "ldh_s">;
702 def LDH_S_X_OFF : F16_LDH_OFF<0x13, "ldh_s.x">;
703
704 def ST_S_OFF :
705   F16_LD_ST_WORD_OFF<0x14, (outs), (ins GPR32:$c, GPR32:$b, immU<7>:$off),
706   "st_s">;
707
708 def STB_S_OFF :
709   F16_LD_ST_BYTE_OFF<0x15, (outs), (ins GPR32:$c, GPR32:$b, immU<5>:$off),
710   "stb_s">;
711
712 def STH_S_OFF :
713   F16_LD_ST_HALF_OFF<0x16, (outs), (ins GPR32:$c, GPR32:$b, immU<6>:$off),
714   "sth_s">;
715
716 //----------------------------------------------------------------------------
717 // General compact instructions.
718 //----------------------------------------------------------------------------
719 def GEN_SUB_S : F16_GEN_DOP<0x02, "sub_s">;
720 def GEN_AND_S : F16_GEN_DOP<0x04, "and_s">;
721 def GEN_OR_S : F16_GEN_DOP<0x05, "or_s">;
722 def GEN_BIC_S : F16_GEN_DOP<0x06, "bic_s">;
723 def GEN_XOR_S : F16_GEN_DOP<0x07, "xor_s">;
724 def GEN_MPYW_S : F16_GEN_DOP<0x09, "mpyw_s">;
725 def GEN_MPYUW_S : F16_GEN_DOP<0x0a, "mpyuw_s">;
726 def GEN_TST_S : F16_GEN_DOP_NODST<0x0b, "tst_s">;
727 def GEN_MPY_S : F16_GEN_DOP<0x0c, "mpy_s">;
728 def GEN_SEXB_S : F16_GEN_DOP_SINGLESRC<0x0d, "sexb_s">;
729 def GEN_SEXH_S : F16_GEN_DOP_SINGLESRC<0x0e, "sexh_s">;
730 def GEN_EXTB_S : F16_GEN_DOP_SINGLESRC<0x0f, "extb_s">;
731 def GEN_EXTH_S : F16_GEN_DOP_SINGLESRC<0x10, "exth_s">;
732 def GEN_ABS_S : F16_GEN_DOP_SINGLESRC<0x11, "abs_s">;
733 def GEN_NOT_S : F16_GEN_DOP_SINGLESRC<0x12, "not_s">;
734 def GEN_NEG_S : F16_GEN_DOP_SINGLESRC<0x13, "neg_s">;
735 def GEN_ADD1_S : F16_GEN_DOP<0x14, "add1_s">;
736 def GEN_ADD2_S : F16_GEN_DOP<0x15, "add2_s">;
737 def GEN_ADD3_S : F16_GEN_DOP<0x16, "add3_s">;
738 def GEN_ASL_S : F16_GEN_DOP<0x18, "asl_s">;
739 def GEN_LSR_S : F16_GEN_DOP<0x19, "lsr_s">;
740 def GEN_ASR_S : F16_GEN_DOP<0x1a, "asr_s">;
741 def GEN_AS1L_S : F16_GEN_DOP_SINGLESRC<0x1b, "asl_s">;
742 def GEN_AS1R_S : F16_GEN_DOP_SINGLESRC<0x1c, "asr_s">;
743 def GEN_LS1R_S : F16_GEN_DOP_SINGLESRC<0x1d, "lsr_s">;
744 def GEN_TRAP_S : F16_GEN_DOP_BASE<0x1e, (outs), (ins immU6:$u6),
745   "trap_s\t$u6"> {
746
747   bits<6> u6;
748   let b = u6{5-3};
749   let c = u6{2-0};
750 }
751
752 def GEN_BRK_S : F16_GEN_DOP_BASE<0x1f, (outs), (ins),
753   "brk_s"> {
754
755   let b = 0b111;
756   let c = 0b111;
757 }
758
759 let isBarrier = 1 in {
760   let isBranch = 1 in {
761     def GEN_J_S : F16_GEN_SOP<0x0, "j_s\t[$b]">;
762     def GEN_J_S_D : F16_GEN_SOP<0x1, "j_s.d\t[$b]">;
763   } // let isBranch
764
765   let isCall = 1 in {
766     def GEN_JL_S : F16_GEN_SOP<0x2, "jl_s\t[$b]">;
767     def GEN_JL_S_D : F16_GEN_SOP<0x3, "jl_s.d\t[$b]">;
768   } // let isCall
769 } // let isBarrier
770
771 def GEN_SUB_S_NE : F16_GEN_SOP<0x6, "sub_s.ne\t$b, $b, $b">;
772
773 def GEN_NOP_S : F16_GEN_ZOP<0x0, "nop_s">;
774 def GEN_UNIMP_S : F16_GEN_ZOP<0x1, "unimp_s">;
775 def GEN_SWI_S : F16_GEN_ZOP<0x2, "swi_s">;
776
777 let isReturn = 1, isTerminator = 1 in {
778   def GEN_JEQ_S : F16_GEN_ZOP<0x4, "jeq_s\t[%blink]">;
779   def GEN_JNE_S : F16_GEN_ZOP<0x5, "jne_s\t[%blink]">;
780   let isBarrier = 1 in {
781     //def GEN_J_S_BLINK : F16_GEN_ZOP<0x6, "j_s\t[%blink]">;
782     def GEN_J_S_D_BLINK : F16_GEN_ZOP<0x7, "j_s.d\t[%blink]">;
783   } // let isBarrier
784 } // let isReturn, isTerminator
785
786 //----------------------------------------------------------------------------
787 // Load/Store instructions.
788 //----------------------------------------------------------------------------
789
790 // Filter  class for load/store mappings
791 class ArcLdStRel;
792
793 // Load instruction variants:
794 // Control bits: x, aa, di, zz
795 // x - sign extend.
796 // aa - incrementing mode. (N/A for LIMM).
797 // di - uncached.
798 // zz - data size.
799 multiclass ArcLdInst<DataSizeMode zz, ExtMode x, CacheMode di, string asmop> {
800   let mayLoad = 1, ZZ = zz, X = x, DI = di in {
801     def _rs9: F32_LD_ADDR<x.Value, NoAM.Value, di.Value, zz.Value,
802                            (outs GPR32:$A), (ins MEMrs9:$addr),
803                            !strconcat(asmop, "\t$A, [$addr]"), []>, ArcLdStRel;
804
805     def _limm: F32_LD_LIMM<x.Value, di.Value, zz.Value,
806                            (outs GPR32:$A), (ins MEMii:$addr),
807                            !strconcat(asmop, "\t$A, [$addr]"), []>, ArcLdStRel;
808
809     def _rlimm: F32_LD_RLIMM<x.Value, NoAM.Value, di.Value, zz.Value,
810                              (outs GPR32:$A), (ins MEMrlimm:$addr),
811                              !strconcat(asmop, "\t$A, [$addr]"), []>, ArcLdStRel;
812
813     foreach aa = [PreIncAM, PostIncAM] in {
814       def aa.InstSuffix#_rs9: F32_LD_RS9<x.Value, aa.Value, di.Value, zz.Value,
815                                           (outs GPR32:$A, GPR32:$addrout),
816                                           (ins GPR32:$B, immS<9>:$S9),
817                                           asmop#aa.AsmSuffix#"\t$A, [$B,$S9]", []>, ArcLdStRel
818                                { let Constraints = "$addrout = $B"; let AA = aa; }
819     }
820   }
821 }
822
823 foreach di = [NoCC, UncachedCC] in {
824   defm LD#di.InstSuffix : ArcLdInst<WordSM, NoEM, di, "ld"#di.AsmSuffix>;
825   foreach zz = [ByteSM, HalfSM] in {
826     foreach x = [NoEM, SignedEM] in {
827       defm LD#zz.InstSuffix#x.InstSuffix#di.InstSuffix : ArcLdInst<zz, x, di, "ld"#zz.AsmSuffix#x.AsmSuffix#di.AsmSuffix>;
828     }
829   }
830 }
831
832 // Load instruction patterns.
833 // 32-bit loads.
834 def : Pat<(load AddrModeS9:$addr), (LD_rs9 AddrModeS9:$addr)>;
835 def : Pat<(load AddrModeImm:$addr), (LD_limm AddrModeImm:$addr)>;
836 def : Pat<(load AddrModeFar:$addr), (LD_rs9 AddrModeFar:$addr)>;
837
838 // 16-bit loads
839 def : Pat<(zextloadi16 AddrModeS9:$addr), (LDH_rs9 AddrModeS9:$addr)>;
840 def : Pat<(extloadi16 AddrModeS9:$addr), (LDH_rs9 AddrModeS9:$addr)>;
841 def : Pat<(zextloadi16 AddrModeImm:$addr), (LDH_limm AddrModeImm:$addr)>;
842 def : Pat<(extloadi16 AddrModeImm:$addr), (LDH_limm AddrModeImm:$addr)>;
843 def : Pat<(zextloadi16 AddrModeFar:$addr), (LDH_rlimm AddrModeFar:$addr)>;
844 def : Pat<(extloadi16 AddrModeFar:$addr), (LDH_rlimm AddrModeFar:$addr)>;
845 def : Pat<(sextloadi16 AddrModeImm:$addr),(LDH_X_limm AddrModeImm:$addr)>;
846 def : Pat<(sextloadi16 AddrModeFar:$addr),(LDH_X_rlimm AddrModeFar:$addr)>;
847 def : Pat<(sextloadi16 AddrModeS9:$addr),(LDH_X_rs9 AddrModeS9:$addr)>;
848
849 // 8-bit loads.
850 def : Pat<(zextloadi8 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>;
851 def : Pat<(extloadi8 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>;
852 def : Pat<(zextloadi8 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>;
853 def : Pat<(extloadi8 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>;
854 def : Pat<(zextloadi8 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>;
855 def : Pat<(extloadi8 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>;
856 def : Pat<(zextloadi1 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>;
857 def : Pat<(extloadi1 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>;
858 def : Pat<(zextloadi1 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>;
859 def : Pat<(extloadi1 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>;
860 def : Pat<(zextloadi1 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>;
861 def : Pat<(extloadi1 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>;
862 def : Pat<(sextloadi8 AddrModeImm:$addr),(LDB_X_limm AddrModeImm:$addr)>;
863 def : Pat<(sextloadi8 AddrModeFar:$addr),(LDB_X_rlimm AddrModeFar:$addr)>;
864 def : Pat<(sextloadi8 AddrModeS9:$addr),(LDB_X_rs9 AddrModeS9:$addr)>;
865
866
867 // Store instruction variants:
868 // Control bits: aa, di, zz
869 // aa - incrementing mode. (N/A for LIMM).
870 // di - uncached.
871 // zz - data size.
872 multiclass ArcStInst<DataSizeMode zz, CacheMode di, string asmop> {
873   let mayStore = 1, ZZ = zz, DI = di in {
874     def _rs9: F32_ST_ADDR<NoAM.Value, di.Value, zz.Value,
875                            (outs), (ins GPR32:$C, MEMrs9:$addr),
876                            !strconcat(asmop, "\t$C, [$addr]"), []>, ArcLdStRel;
877
878     def _limm: F32_ST_LIMM<di.Value, zz.Value,
879                            (outs), (ins GPR32:$C, MEMii:$addr),
880                            !strconcat(asmop, "\t$C, [$addr]"), []>, ArcLdStRel;
881
882
883     foreach aa = [PreIncAM, PostIncAM] in {
884       def aa.InstSuffix#_rs9: F32_ST_RS9<aa.Value, di.Value, zz.Value,
885                                           (outs GPR32:$addrout),
886                                           (ins GPR32:$C, GPR32:$B, immS<9>:$S9),
887                                           asmop#aa.AsmSuffix#"\t$C, [$B,$S9]", []>, ArcLdStRel
888                                { let Constraints = "$addrout = $B"; let AA = aa; }
889     }
890   }
891 }
892
893 foreach di = [NoCC, UncachedCC] in {
894   foreach zz = [ByteSM, HalfSM, WordSM] in {
895       defm ST#zz.InstSuffix#di.InstSuffix : ArcStInst<zz, di, "st"#zz.AsmSuffix#di.AsmSuffix>;
896   }
897 }
898
899 // Store instruction patterns.
900 // 32-bit stores
901 def : Pat<(store i32:$C, AddrModeS9:$addr),
902           (ST_rs9 i32:$C, AddrModeS9:$addr)>;
903 def : Pat<(store i32:$C, AddrModeImm:$addr),
904           (ST_limm i32:$C, AddrModeImm:$addr)>;
905
906 // 16-bit stores
907 def : Pat<(truncstorei16 i32:$C, AddrModeS9:$addr),
908           (STH_rs9 i32:$C, AddrModeS9:$addr)>;
909 def : Pat<(truncstorei16 i32:$C, AddrModeImm:$addr),
910           (STH_limm i32:$C, AddrModeImm:$addr)>;
911
912 // 8-bit stores
913 def : Pat<(truncstorei8 i32:$C, AddrModeS9:$addr),
914           (STB_rs9 i32:$C, AddrModeS9:$addr)>;
915 def : Pat<(truncstorei8 i32:$C, AddrModeImm:$addr),
916           (STB_limm i32:$C, AddrModeImm:$addr)>;
917
918 def getPostIncOpcode : InstrMapping {
919   let FilterClass = "ArcLdStRel";
920   let RowFields = [ "BaseOpcode", "ZZ", "DI", "X"];
921   let ColFields = [ "AA" ];
922   let KeyCol = [ "NoAM" ];
923   let ValueCols = [["PostIncAM"]];
924 }