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