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