1 //===- ARCInstrInfo.td - Target Description for ARC --------*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARC instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 include "ARCInstrFormats.td"
16 // ---------------------------------------------------------------------------
17 // Selection DAG Nodes.
18 // ---------------------------------------------------------------------------
20 // Selection DAG types.
21 def SDT_ARCcmptst : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
22 def SDT_ARCcmov : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>;
23 def SDT_ARCmov : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>]>;
24 def SDT_ARCbrcc : SDTypeProfile<0, 4, []>;
25 def SDT_ARCBranchLink : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
26 def SDT_ARCCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,
28 def SDT_ARCCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>,
33 def ARCGAWrapper : SDNode<"ARCISD::GAWRAPPER", SDT_ARCmov, []>;
36 def ARCcmp : SDNode<"ARCISD::CMP", SDT_ARCcmptst, [SDNPOutGlue]>;
39 def ARCcmov : SDNode<"ARCISD::CMOV", SDT_ARCcmov, [SDNPInGlue]>;
42 def ARCbrcc : SDNode<"ARCISD::BRcc", SDT_ARCbrcc,
43 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
46 def ARCBranchLink : SDNode<"ARCISD::BL",SDT_ARCBranchLink,
47 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
51 def ARCJumpLink : SDNode<"ARCISD::JL",SDT_ARCBranchLink,
52 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
55 def ret : SDNode<"ARCISD::RET", SDTNone,
56 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
58 // Call sequencing nodes.
59 // These are target-independent nodes, but have target-specific formats.
60 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARCCallSeqStart,
61 [SDNPHasChain, SDNPOutGlue]>;
62 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARCCallSeqEnd,
63 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
65 //===----------------------------------------------------------------------===//
66 // Instruction Pattern Stuff
67 //===----------------------------------------------------------------------===//
69 def imm32 : ImmLeaf<i32, [{
70 return (Imm & 0xFFFFFFFF) == Imm;
74 def FrameADDR_ri : ComplexPattern<i32, 2, "SelectFrameADDR_ri",
75 [add, frameindex], []>;
76 def AddrModeS9 : ComplexPattern<i32, 2, "SelectAddrModeS9", []>;
77 def AddrModeImm : ComplexPattern<i32, 2, "SelectAddrModeImm", []>;
78 def AddrModeFar : ComplexPattern<i32, 2, "SelectAddrModeFar", []>;
80 //===----------------------------------------------------------------------===//
81 // Instruction Class Templates
82 //===----------------------------------------------------------------------===//
84 //===----------------------------------------------------------------------===//
85 // Pseudo Instructions
86 //===----------------------------------------------------------------------===//
88 let Defs = [SP], Uses = [SP] in {
89 def ADJCALLSTACKDOWN : PseudoInstARC<(outs), (ins i32imm:$amt, i32imm:$amt2),
90 "# ADJCALLSTACKDOWN $amt, $amt2",
91 [(callseq_start timm:$amt, timm:$amt2)]>;
92 def ADJCALLSTACKUP : PseudoInstARC<(outs), (ins i32imm:$amt1, i32imm:$amt2),
93 "# ADJCALLSTACKUP $amt1",
94 [(callseq_end timm:$amt1, timm:$amt2)]>;
97 def GETFI : PseudoInstARC<(outs GPR32:$dst), (ins MEMii:$addr),
99 [(set GPR32:$dst, FrameADDR_ri:$addr)]>;
102 def ST_FAR : PseudoInstARC<(outs), (ins GPR32:$dst, MEMrlimm:$addr),
103 "ST_FAR $dst, $addr",
104 [(store GPR32:$dst, AddrModeFar:$addr)]>;
106 def STH_FAR : PseudoInstARC<(outs), (ins GPR32:$dst, MEMrlimm:$addr),
107 "STH_FAR $dst, $addr",
108 [(truncstorei16 GPR32:$dst, AddrModeFar:$addr)]>;
110 def STB_FAR : PseudoInstARC<(outs), (ins GPR32:$dst, MEMrlimm:$addr),
111 "STB_FAR $dst, $addr",
112 [(truncstorei8 GPR32:$dst, AddrModeFar:$addr)]>;
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 //===----------------------------------------------------------------------===//
120 // Generic 3 operand binary instructions (i.e., add r0, r1, r2).
121 multiclass ArcBinaryInst<bits<5> major, bits<6> mincode,
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"),
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"),
132 { let Defs = [STATUS32]; }
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"),
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"),
143 { let Defs = [STATUS32]; }
145 // 2 register with 32-bit immediate variant.
146 def _rrlimm : F32_DOP_RLIMM<major, mincode, 0,
148 (ins GPR32:$B, i32imm:$LImm),
149 !strconcat(opasm, "\t$A, $B, $LImm"),
151 def _f_rrlimm : F32_DOP_RLIMM<major, mincode, 1,
153 (ins GPR32:$B, i32imm:$LImm),
154 !strconcat(opasm, ".f\t$A, $B, $LImm"),
156 { let Defs = [STATUS32]; }
158 // 2 matched-register with signed 12-bit immediate variant (add r0, r0, -1).
159 def _rrs12 : F32_DOP_RS12<major, mincode, 0,
161 (ins GPR32:$in, immS<12>:$S12),
162 !strconcat(opasm, "\t$B, $in, $S12"),
164 { let Constraints = "$B = $in"; }
165 def _f_rrs12 : F32_DOP_RS12<major, mincode, 1,
167 (ins GPR32:$in, immS<12>:$S12),
168 !strconcat(opasm, ".f\t$B, $in, $S12"),
170 { let Constraints = "$B = $in"; let Defs = [STATUS32]; }
173 // Special multivariant GEN4 DOP format instruction that take 2 registers.
174 // This is the class that is used for various comparison instructions.
175 multiclass 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"),
180 def _ru6 : F32_DOP_RU6<0b00100, subop, F, (outs), (ins GPR32:$B, i32imm:$U6),
181 !strconcat(opasm, "\t$B, $U6"),
184 def _rlimm : F32_DOP_RLIMM<0b00100, subop, F, (outs),
185 (ins GPR32:$B, i32imm:$LImm),
186 !strconcat(opasm, "\t$B, $LImm"),
190 // Generic 2-operand unary instructions.
191 multiclass ArcUnaryInst<bits<5> major, bits<6> subop,
193 def _rr : F32_SOP_RR<major, subop, 0, (outs GPR32:$B), (ins GPR32:$C),
194 !strconcat(opasm, "\t$B, $C"), []>;
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]; }
202 multiclass ArcBinaryGEN4Inst<bits<6> mincode, string opasm> :
203 ArcBinaryInst<0b00100, mincode, opasm>;
204 multiclass ArcBinaryEXT5Inst<bits<6> mincode, string opasm> :
205 ArcBinaryInst<0b00101, mincode, opasm>;
207 multiclass ArcUnaryGEN4Inst<bits<6> mincode, string opasm> :
208 ArcUnaryInst<0b00100, mincode, opasm>;
210 // Pattern generation for differnt instruction variants.
211 multiclass 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)>;
218 // ---------------------------------------------------------------------------
219 // Instruction defintions and patterns for 3 operand binary instructions.
220 // ---------------------------------------------------------------------------
222 // Definitions for 3 operand binary instructions.
223 defm ADD : ArcBinaryGEN4Inst<0b000000, "add">;
224 defm SUB : ArcBinaryGEN4Inst<0b000010, "sub">;
225 defm SUB1 : ArcBinaryGEN4Inst<0b010111, "sub1">;
226 defm SUB2 : ArcBinaryGEN4Inst<0b011000, "sub2">;
227 defm SUB3 : ArcBinaryGEN4Inst<0b011001, "sub3">;
228 defm OR : ArcBinaryGEN4Inst<0b000101, "or">;
229 defm AND : ArcBinaryGEN4Inst<0b000100, "and">;
230 defm XOR : ArcBinaryGEN4Inst<0b000111, "xor">;
231 defm MAX : ArcBinaryGEN4Inst<0b001000, "max">;
232 defm MIN : ArcBinaryGEN4Inst<0b001001, "min">;
233 defm ASL : ArcBinaryEXT5Inst<0b000000, "asl">;
234 defm LSR : ArcBinaryEXT5Inst<0b000001, "lsr">;
235 defm ASR : ArcBinaryEXT5Inst<0b000010, "asr">;
236 defm ROR : ArcBinaryEXT5Inst<0b000011, "ror">;
237 defm MPY : ArcBinaryGEN4Inst<0b011010, "mpy">;
238 defm MPYM : ArcBinaryGEN4Inst<0b011011, "mpym">;
239 defm MPYMU : ArcBinaryGEN4Inst<0b011100, "mpymu">;
240 defm SETEQ : ArcBinaryGEN4Inst<0b111000, "seteq">;
242 // Patterns for 3 operand binary instructions.
243 defm : MultiPat<add, ADD_rrr, ADD_rru6, ADD_rrlimm>;
244 defm : MultiPat<sub, SUB_rrr, SUB_rru6, SUB_rrlimm>;
245 defm : MultiPat<or, OR_rrr, OR_rru6, OR_rrlimm>;
246 defm : MultiPat<and, AND_rrr, AND_rru6, AND_rrlimm>;
247 defm : MultiPat<xor, XOR_rrr, XOR_rru6, XOR_rrlimm>;
248 defm : MultiPat<smax, MAX_rrr, MAX_rru6, MAX_rrlimm>;
249 defm : MultiPat<smin, MIN_rrr, MIN_rru6, MIN_rrlimm>;
250 defm : MultiPat<shl, ASL_rrr, ASL_rru6, ASL_rrlimm>;
251 defm : MultiPat<srl, LSR_rrr, LSR_rru6, LSR_rrlimm>;
252 defm : MultiPat<sra, ASR_rrr, ASR_rru6, ASR_rrlimm>;
253 defm : MultiPat<rotr, ROR_rrr, ROR_rru6, ROR_rrlimm>;
254 defm : MultiPat<mul, MPY_rrr, MPY_rru6, MPY_rrlimm>;
255 defm : MultiPat<mulhs, MPYM_rrr, MPYM_rru6, MPYM_rrlimm>;
256 defm : MultiPat<mulhu, MPYMU_rrr, MPYMU_rru6, MPYMU_rrlimm>;
258 // ---------------------------------------------------------------------------
259 // Unary Instruction definitions.
260 // ---------------------------------------------------------------------------
261 // General unary instruction definitions.
262 defm SEXB : ArcUnaryGEN4Inst<0b000101, "sexb">;
263 defm SEXH : ArcUnaryGEN4Inst<0b000110, "sexh">;
265 // General Unary Instruction fragments.
266 def : Pat<(sext_inreg i32:$a, i8), (SEXB_rr i32:$a)>;
267 def : Pat<(sext_inreg i32:$a, i16), (SEXH_rr i32:$a)>;
269 // Comparison instruction definition
270 let isCompare = 1, Defs = [STATUS32] in {
271 defm CMP : ArcSpecialDOPInst<0b001100, "cmp", 1>;
274 def cmp : PatFrag<(ops node:$op1, node:$op2), (ARCcmp $op1, $op2)>;
275 defm : MultiPat<cmp, CMP_rr, CMP_ru6, CMP_rlimm>;
277 // ---------------------------------------------------------------------------
278 // MOV instruction and variants (conditional mov).
279 // ---------------------------------------------------------------------------
280 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
281 def MOV_rs12 : F32_DOP_RS12<0b00100, 0b001010, 0,
282 (outs GPR32:$B), (ins immS<12>:$S12),
284 [(set GPR32:$B, immS<12>:$S12)]>;
287 def MOV_rr : F32_DOP_RR<0b00100, 0b001010, 0,
288 (outs GPR32:$B), (ins GPR32:$C),
291 def MOV_rlimm : F32_DOP_RLIMM<0b00100, 0b001010, 0,
292 (outs GPR32:$B), (ins i32imm:$LImm),
293 "mov\t$B, $LImm", []>;
295 def MOV_ru6 : F32_DOP_RU6<0b00100, 0b001010, 0,
296 (outs GPR32:$B), (ins immU6:$U6),
299 def cmov : PatFrag<(ops node:$op1, node:$op2, node:$cc),
300 (ARCcmov $op1, $op2, $cc)>;
301 let Uses = [STATUS32] in {
302 def MOVcc : F32_DOP_CC_RR<0b00100, 0b001010, 0,
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";
310 def : Pat<(ARCGAWrapper tglobaladdr:$addr),
311 (MOV_rlimm tglobaladdr:$addr)>;
313 def : Pat<(ARCGAWrapper tjumptable:$addr),
314 (MOV_rlimm tjumptable:$addr)>;
317 // ---------------------------------------------------------------------------
318 // Control flow instructions (branch, return, calls, etc).
319 // ---------------------------------------------------------------------------
321 // Branch instructions
322 let isBranch = 1, isTerminator = 1 in {
324 // Unconditional branch.
326 def BR : F32_BR0_UCOND_FAR<(outs), (ins btargetS25:$S25),
327 "b\t$S25", [(br bb:$S25)]>;
329 let Uses=[STATUS32] in
330 // Conditional branch.
331 def Bcc : F32_BR0_COND<(outs), (ins btargetS21:$S21, ccond:$cc),
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, []>;
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)]>
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)]>
357 } // let isBranch, isTerminator
359 // Unconditional Jump.
360 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
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)]>;
368 def J_LImm : F32_DOP_RLIMM<0b00100, 0b100000, 0,
369 (outs), (ins i32imm:$LImm),
373 // Call instructions.
374 let 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)]>;
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)]>;
384 // Direct unconditional call.
385 def JL_LImm : F32_DOP_RLIMM<0b00100, 0b100010, 0, (outs), (ins i32imm:$LImm),
387 } // let isCall, isBarrier, Defs, Uses
389 // Pattern to generate BL instruction.
390 def : Pat<(ARCBranchLink texternalsym:$dst), (BL texternalsym:$dst)>;
393 let 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.
396 def J_S_BLINK : InstARC<2, (outs), (ins), "j_s\t[%blink]", [(ret)]> {
397 let Inst{15-0} = 0b0111111011100000;
400 //----------------------------------------------------------------------------
401 // Compact stack-based operations.
402 //----------------------------------------------------------------------------
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.
408 let Uses = [BLINK], Defs = [SP] in
409 def PUSH_S_BLINK : F16_SP_OPS_buconst<0b111, "push_s">;
411 let Defs = [BLINK, SP] in
412 def POP_S_BLINK : F16_SP_OPS_buconst<0b110, "pop_s">;
414 def PUSH_S_r : F16_SP_OPS_uconst<0b110,
415 (outs), (ins GPR32Reduced:$b3), "push_s">;
416 def POP_S_r : F16_SP_OPS_uconst<0b111,
417 (outs GPR32Reduced:$b3), (ins), "pop_s">;
419 def SP_SUB_SP_S : F16_SP_OPS_bconst<0b001, "sub_s">;
420 def SP_ADD_SP_S : F16_SP_OPS_bconst<0b000, "add_s">;
421 def SP_ADD_S : F16_SP_OPS_u7_aligned<0b100,
422 (outs GPR32Reduced:$b3), (ins immU<7>:$u7),
423 "add_s\t$b3, %sp, $u7">;
425 def SP_LD_S : F16_SP_LD<0b000, "ld_s">;
426 def SP_LDB_S : F16_SP_LD<0b001, "ldb_s">;
427 def SP_ST_S : F16_SP_ST<0b010, "st_s">;
428 def SP_STB_S : F16_SP_ST<0b011, "stb_s">;
430 def LEAVE_S : F16_SP_OPS<0b110,
431 (outs), (ins immU<7>:$u7), "leave_s\t$u7"> {
435 let fieldB = u7{6-4};
436 let fieldU{4-1} = u7{3-0};
440 def ENTER_S : F16_SP_OPS<0b111,
441 (outs), (ins immU<6>:$u6), "enter_s\t$u6"> {
446 let fieldB{1-0} = u6{5-4};
447 let fieldU{4-1} = u6{3-0};
451 //----------------------------------------------------------------------------
452 // Compact Move/Load instructions.
453 //----------------------------------------------------------------------------
454 class COMPACT_MOV_S :
455 F16_COMPACT<0b0, (outs GPR32:$g), (ins GPR32:$h),
457 let DecoderMethod = "DecodeMoveHRegInstruction";
460 def COMPACT_MOV_S_limm : COMPACT_MOV_S {
462 let Inst{47-16} = LImm;
464 bits<5> LImmReg = 0b11110;
465 let Inst{7-5} = LImmReg{2-0};
466 let Inst{1-0} = LImmReg{4-3};
471 def COMPACT_MOV_S_hreg : COMPACT_MOV_S;
474 F16_COMPACT<0b1, (outs GPR32:$r), (ins GPR32:$h, immU<5>:$u5),
475 "ld_s\t$r, [$h, $u5]"> {
479 let Inst{10} = u5{4};
481 let Inst{4-3} = u5{3-2};
485 //----------------------------------------------------------------------------
486 // Compact Load/Add/Sub.
487 //----------------------------------------------------------------------------
488 def LD_S_AS_rrr : F16_LD_SUB<0b0, "ld_s.as\t$a, [$b, $c]">;
489 def SUB_S_rrr : F16_LD_SUB<0b1, "sub_s\t$a, $b, $c">;
490 def ADD_S_rru6 : F16_ADD;
492 //----------------------------------------------------------------------------
493 // Compact Load/Store.
494 //----------------------------------------------------------------------------
495 def LD_S_s11 : F16_LD_ST_s11<0b0, "ld_s\t%r1, [%gp, $s11]">;
496 def ST_S_s11 : F16_LD_ST_s11<0b1, "st_s\t%r0, [%gp, $s11]">;
497 def LDI_S_u7 : F16_LDI_u7;
499 //----------------------------------------------------------------------------
500 // Indexed Jump or Execute.
501 //----------------------------------------------------------------------------
502 def JLI_S : F16_JLI_EI<0, "jli_s">;
503 def EI_S : F16_JLI_EI<1, "ei_s">;
505 //----------------------------------------------------------------------------
506 // Load/Add Register-Register.
507 //----------------------------------------------------------------------------
508 def LD_S_rrr : F16_LD_ADD_RR<0b00, "ld_s\t$a, [$b, $c]">;
509 def LDB_S_rrr : F16_LD_ADD_RR<0b01, "ldb_s\t$a, [$b, $c]">;
510 def LDH_S_rrr : F16_LD_ADD_RR<0b10, "ldh_s\t$a, [$b, $c]">;
511 def ADD_S_rrr : F16_LD_ADD_RR<0b11, "add_s\t$a, $b, $c">;
513 //----------------------------------------------------------------------------
514 // Load/Add GP-Relative.
515 //----------------------------------------------------------------------------
516 def GP_LD_S : F16_GP_LD_ADD<0b00, (ins immS<11>:$s),
517 "ld_s\t%r0, [%gp, $s]"> {
520 let Inst{8-0} = s{10-2};
524 def GP_LDB_S : F16_GP_LD_ADD<0b01, (ins immS<9>:$s),
525 "ldb_s\t%r0, [%gp, $s]"> {
528 let Inst{8-0} = s{8-0};
531 def GP_LDH_S : F16_GP_LD_ADD<0b10, (ins immS<10>:$s),
532 "ldh_s\t%r0, [%gp, $s]"> {
535 let Inst{8-0} = s{9-1};
539 def GP_ADD_S : F16_GP_LD_ADD<0b11, (ins immS<11>:$s),
540 "add_s\t%r0, %gp, $s"> {
543 let Inst{8-0} = s{10-2};
547 //----------------------------------------------------------------------------
548 // Load PCL-Relative.
549 //----------------------------------------------------------------------------
550 def PCL_LD : InstARC<2, (outs GPR32:$b), (ins immU<10>:$u10),
551 "ld_s\t$b, [%pcl, $u10]", []> {
556 let Inst{15-11} = 0b11010;
558 let Inst{7-0} = u10{9-2};
562 let 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">;
569 //----------------------------------------------------------------------------
570 // Branch Conditionally.
571 //----------------------------------------------------------------------------
573 def B_S : F16_BCC_s10<0b00, "b_s">;
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">;
588 InstARC<2, (outs), (ins btargetS13:$s13), "bl_s\t$s13", []> {
590 let Inst{15-11} = 0b11111;
593 let Inst{10-0} = s13{12-2};
600 //----------------------------------------------------------------------------
601 // Add/Sub/Shift Register-Immediate.
602 //----------------------------------------------------------------------------
603 def ADD_S_ru3 : F16_ADD_IMM<0b00,"add_s">;
604 def SUB_S_ru3 : F16_ADD_IMM<0b01,"sub_s">;
605 def ASL_S_ru3 : F16_ADD_IMM<0b10,"asl_s">;
606 def ASR_S_ru3 : F16_ADD_IMM<0b11,"asr_s">;
608 //----------------------------------------------------------------------------
609 // Shift/Subtract/Bit Immediate.
610 //----------------------------------------------------------------------------
611 def ASL_S_ru5 : F16_SH_SUB_BIT_DST<0b000,"asl_s">;
612 def LSR_S_ru5 : F16_SH_SUB_BIT_DST<0b001,"lsr_s">;
613 def ASR_S_ru5 : F16_SH_SUB_BIT_DST<0b010,"asr_s">;
614 def SUB_S_ru5 : F16_SH_SUB_BIT_DST<0b011,"sub_s">;
615 def BSET_S_ru5 : F16_SH_SUB_BIT_DST<0b100,"bset_s">;
616 def BCLR_S_ru5 : F16_SH_SUB_BIT_DST<0b101,"bclr_s">;
617 def BMSK_S_ru5 : F16_SH_SUB_BIT_DST<0b110,"bmsk_s">;
618 def BTST_S_ru5 : F16_SH_SUB_BIT<0b111, "btst_s\t$b, $u5">;
620 //----------------------------------------------------------------------------
621 // Dual Register Operations.
622 //----------------------------------------------------------------------------
624 F16_OP_HREG_LIMM<0b000, (outs GPR32:$b_s3), (ins i32imm:$LImm),
625 !strconcat("add_s", "\t$b_s3, $b_s3, $LImm")>;
628 F16_OP_HREG<0b000, (outs GPR32:$b_s3), (ins GPR32:$h),
629 !strconcat("add_s", "\t$b_s3, $b_s3, $h")>;
632 F16_OP_HREG<0b001, (outs GPR32:$h), (ins immC<3>:$b_s3),
633 !strconcat("add_s", "\t$h, $h, $b_s3")>;
636 F16_OP_HREG_LIMM<0b001, (outs), (ins immC<3>:$b_s3, i32imm:$LImm),
637 !strconcat("add_s", "\t0, $LImm, $b_s3")>;
640 F16_OP_HREG_LIMM<0b111, (outs GPR32:$b_s3), (ins i32imm:$LImm),
641 !strconcat("mov_s.ne", "\t$b_s3, $LImm")>;
644 F16_OP_HREG<0b111,(outs GPR32:$b_s3), (ins GPR32:$h),
645 !strconcat("mov_s.ne", "\t$b_s3, $h")>;
648 F16_OP_HREG<0b011, (outs GPR32:$h), (ins immC<3>:$b_s3),
649 !strconcat("mov_s", "\t$h, $b_s3")>;
652 F16_OP_HREG30<0b011, (outs), (ins immC<3>:$b_s3),
653 !strconcat("mov_s", "\t0, $b_s3")>;
656 F16_OP_HREG_LIMM<0b100, (outs GPR32:$b_s3), (ins i32imm:$LImm),
657 !strconcat("cmp_s", "\t$b_s3, $LImm")>;
660 F16_OP_HREG<0b100, (outs GPR32:$b_s3), (ins GPR32:$h),
661 !strconcat("cmp_s", "\t$b_s3, $h")>;
664 F16_OP_HREG<0b101, (outs GPR32:$h), (ins immC<3>:$b_s3),
665 !strconcat("cmp_s", "\t$h, $b_s3")>;
668 F16_OP_HREG_LIMM<0b101, (outs), (ins immC<3>:$b_s3, i32imm:$LImm),
669 !strconcat("cmp_s", "\t$LImm, $b_s3")>;
671 //----------------------------------------------------------------------------
672 // Compact MOV/ADD/CMP Immediate instructions.
673 //----------------------------------------------------------------------------
675 F16_OP_IMM<0b11011, (outs GPR32:$b), (ins immU<8>:$u8),
676 !strconcat("mov_s", "\t$b, $u8")> {
682 F16_OP_U7<0b0, !strconcat("add_s", "\t$b, $b, $u7")>;
685 F16_OP_U7<0b1, !strconcat("cmp_s", "\t$b, $u7")>;
687 //----------------------------------------------------------------------------
688 // Compact Load/Store instructions with offset.
689 //----------------------------------------------------------------------------
691 F16_LD_ST_WORD_OFF<0x10, (outs GPR32:$c), (ins GPR32:$b, immU<7>:$off),
695 F16_LD_ST_BYTE_OFF<0x11, (outs GPR32:$c), (ins GPR32:$b, immU<5>:$off),
698 class F16_LDH_OFF<bits<5> opc, string asmstr> :
699 F16_LD_ST_HALF_OFF<opc, (outs GPR32:$c), (ins GPR32:$b, immU<6>:$off),
702 def LDH_S_OFF : F16_LDH_OFF<0x12, "ldh_s">;
703 def LDH_S_X_OFF : F16_LDH_OFF<0x13, "ldh_s.x">;
706 F16_LD_ST_WORD_OFF<0x14, (outs), (ins GPR32:$c, GPR32:$b, immU<7>:$off),
710 F16_LD_ST_BYTE_OFF<0x15, (outs), (ins GPR32:$c, GPR32:$b, immU<5>:$off),
714 F16_LD_ST_HALF_OFF<0x16, (outs), (ins GPR32:$c, GPR32:$b, immU<6>:$off),
717 //----------------------------------------------------------------------------
718 // General compact instructions.
719 //----------------------------------------------------------------------------
720 def GEN_SUB_S : F16_GEN_DOP<0x02, "sub_s">;
721 def GEN_AND_S : F16_GEN_DOP<0x04, "and_s">;
722 def GEN_OR_S : F16_GEN_DOP<0x05, "or_s">;
723 def GEN_BIC_S : F16_GEN_DOP<0x06, "bic_s">;
724 def GEN_XOR_S : F16_GEN_DOP<0x07, "xor_s">;
725 def GEN_MPYW_S : F16_GEN_DOP<0x09, "mpyw_s">;
726 def GEN_MPYUW_S : F16_GEN_DOP<0x0a, "mpyuw_s">;
727 def GEN_TST_S : F16_GEN_DOP_NODST<0x0b, "tst_s">;
728 def GEN_MPY_S : F16_GEN_DOP<0x0c, "mpy_s">;
729 def GEN_SEXB_S : F16_GEN_DOP_SINGLESRC<0x0d, "sexb_s">;
730 def GEN_SEXH_S : F16_GEN_DOP_SINGLESRC<0x0e, "sexh_s">;
731 def GEN_EXTB_S : F16_GEN_DOP_SINGLESRC<0x0f, "extb_s">;
732 def GEN_EXTH_S : F16_GEN_DOP_SINGLESRC<0x10, "exth_s">;
733 def GEN_ABS_S : F16_GEN_DOP_SINGLESRC<0x11, "abs_s">;
734 def GEN_NOT_S : F16_GEN_DOP_SINGLESRC<0x12, "not_s">;
735 def GEN_NEG_S : F16_GEN_DOP_SINGLESRC<0x13, "neg_s">;
736 def GEN_ADD1_S : F16_GEN_DOP<0x14, "add1_s">;
737 def GEN_ADD2_S : F16_GEN_DOP<0x15, "add2_s">;
738 def GEN_ADD3_S : F16_GEN_DOP<0x16, "add3_s">;
739 def GEN_ASL_S : F16_GEN_DOP<0x18, "asl_s">;
740 def GEN_LSR_S : F16_GEN_DOP<0x19, "lsr_s">;
741 def GEN_ASR_S : F16_GEN_DOP<0x1a, "asr_s">;
742 def GEN_AS1L_S : F16_GEN_DOP_SINGLESRC<0x1b, "asl_s">;
743 def GEN_AS1R_S : F16_GEN_DOP_SINGLESRC<0x1c, "asr_s">;
744 def GEN_LS1R_S : F16_GEN_DOP_SINGLESRC<0x1d, "lsr_s">;
745 def GEN_TRAP_S : F16_GEN_DOP_BASE<0x1e, (outs), (ins immU6:$u6),
753 def GEN_BRK_S : F16_GEN_DOP_BASE<0x1f, (outs), (ins),
760 let 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]">;
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]">;
772 def GEN_SUB_S_NE : F16_GEN_SOP<0x6, "sub_s.ne\t$b, $b, $b">;
774 def GEN_NOP_S : F16_GEN_ZOP<0x0, "nop_s">;
775 def GEN_UNIMP_S : F16_GEN_ZOP<0x1, "unimp_s">;
776 def GEN_SWI_S : F16_GEN_ZOP<0x2, "swi_s">;
778 let 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]">;
785 } // let isReturn, isTerminator
787 //----------------------------------------------------------------------------
788 // Load/Store instructions.
789 //----------------------------------------------------------------------------
791 // Load instruction variants:
792 // Control bits: x, aa, di, zz
794 // aa - incrementing mode. (N/A for LIMM).
797 multiclass ArcLdInst<bits<2> zz, string asmop> {
799 def _rs9 : F32_LD_ADDR<0, 0b00, 0, zz,
800 (outs GPR32:$A), (ins MEMrs9:$addr),
801 !strconcat(asmop, "\t$A, [$addr]"), []>;
803 def _limm : F32_LD_LIMM<0, 0, zz,
804 (outs GPR32:$A), (ins MEMii:$addr),
805 !strconcat(asmop, "\t$A, [$addr]"), []>;
807 def _rlimm : F32_LD_RLIMM<0, 0b00, 0, zz,
808 (outs GPR32:$A), (ins MEMrlimm:$addr),
809 !strconcat(asmop, "\t$A, [$addr]"), []>;
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]"), []>;
815 def _X_limm : F32_LD_LIMM<1, 0, zz,
816 (outs GPR32:$A), (ins MEMii:$addr),
817 !strconcat(asmop, ".x\t$A, [$addr]"), []>;
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]"), []>;
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"; }
831 // Load instruction definitions.
832 defm LD : ArcLdInst<0b00, "ld">;
833 defm LDH : ArcLdInst<0b10, "ldh">;
834 defm LDB : ArcLdInst<0b01, "ldb">;
836 // Load instruction patterns.
838 def : Pat<(load AddrModeS9:$addr), (LD_rs9 AddrModeS9:$addr)>;
839 def : Pat<(load AddrModeImm:$addr), (LD_limm AddrModeImm:$addr)>;
840 def : Pat<(load AddrModeFar:$addr), (LD_rs9 AddrModeFar:$addr)>;
843 def : Pat<(zextloadi16 AddrModeS9:$addr), (LDH_rs9 AddrModeS9:$addr)>;
844 def : Pat<(extloadi16 AddrModeS9:$addr), (LDH_rs9 AddrModeS9:$addr)>;
845 def : Pat<(zextloadi16 AddrModeImm:$addr), (LDH_limm AddrModeImm:$addr)>;
846 def : Pat<(extloadi16 AddrModeImm:$addr), (LDH_limm AddrModeImm:$addr)>;
847 def : Pat<(zextloadi16 AddrModeFar:$addr), (LDH_rlimm AddrModeFar:$addr)>;
848 def : Pat<(extloadi16 AddrModeFar:$addr), (LDH_rlimm AddrModeFar:$addr)>;
849 def : Pat<(sextloadi16 AddrModeImm:$addr),(LDH_X_limm AddrModeImm:$addr)>;
850 def : Pat<(sextloadi16 AddrModeFar:$addr),(LDH_X_rlimm AddrModeFar:$addr)>;
851 def : Pat<(sextloadi16 AddrModeS9:$addr),(LDH_X_rs9 AddrModeS9:$addr)>;
854 def : Pat<(zextloadi8 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>;
855 def : Pat<(extloadi8 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>;
856 def : Pat<(zextloadi8 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>;
857 def : Pat<(extloadi8 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>;
858 def : Pat<(zextloadi8 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>;
859 def : Pat<(extloadi8 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>;
860 def : Pat<(zextloadi1 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>;
861 def : Pat<(extloadi1 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>;
862 def : Pat<(zextloadi1 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>;
863 def : Pat<(extloadi1 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>;
864 def : Pat<(zextloadi1 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>;
865 def : Pat<(extloadi1 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>;
866 def : Pat<(sextloadi8 AddrModeImm:$addr),(LDB_X_limm AddrModeImm:$addr)>;
867 def : Pat<(sextloadi8 AddrModeFar:$addr),(LDB_X_rlimm AddrModeFar:$addr)>;
868 def : Pat<(sextloadi8 AddrModeS9:$addr),(LDB_X_rs9 AddrModeS9:$addr)>;
871 // Store instruction variants:
872 // Control bits: aa, di, zz
873 // aa - incrementing mode. (N/A for LIMM).
876 multiclass 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]"), []>;
881 def _limm : F32_ST_LIMM<0, zz, (outs), (ins GPR32:$C, MEMii:$addr),
882 !strconcat(asmop, "\t$C, [$addr]"), []>;
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"; }
891 // Store instruction definitions.
892 defm ST : ArcStInst<0b00, "st">;
893 defm STH : ArcStInst<0b10, "sth">;
894 defm STB : ArcStInst<0b01, "stb">;
896 // Store instruction patterns.
898 def : Pat<(store i32:$C, AddrModeS9:$addr),
899 (ST_rs9 i32:$C, AddrModeS9:$addr)>;
900 def : Pat<(store i32:$C, AddrModeImm:$addr),
901 (ST_limm i32:$C, AddrModeImm:$addr)>;
904 def : Pat<(truncstorei16 i32:$C, AddrModeS9:$addr),
905 (STH_rs9 i32:$C, AddrModeS9:$addr)>;
906 def : Pat<(truncstorei16 i32:$C, AddrModeImm:$addr),
907 (STH_limm i32:$C, AddrModeImm:$addr)>;
910 def : Pat<(truncstorei8 i32:$C, AddrModeS9:$addr),
911 (STB_rs9 i32:$C, AddrModeS9:$addr)>;
912 def : Pat<(truncstorei8 i32:$C, AddrModeImm:$addr),
913 (STB_limm i32:$C, AddrModeImm:$addr)>;