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