]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Target/Lanai/LanaiInstrInfo.td
Vendor import of llvm trunk r338150:
[FreeBSD/FreeBSD.git] / lib / Target / Lanai / LanaiInstrInfo.td
1 //===-- LanaiInstrInfo.td - Target Description for Lanai Target -----------===//
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 Lanai instructions in TableGen format.
11 //
12 //===----------------------------------------------------------------------===//
13
14 //===----------------------------------------------------------------------===//
15 // Instruction format superclass
16 //===----------------------------------------------------------------------===//
17
18 include "LanaiInstrFormats.td"
19
20 // -------------------------------------------------- //
21 // Instruction Operands and Patterns
22 // -------------------------------------------------- //
23
24 //  These are target-independent nodes, but have target-specific formats.
25 def SDT_LanaiCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
26                                             SDTCisVT<1, i32>]>;
27 def SDT_LanaiCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
28                                           SDTCisVT<1, i32>]>;
29 def SDT_LanaiCall         : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
30 def SDT_LanaiSetFlag      : SDTypeProfile<0,  2, [SDTCisSameAs<0, 1>]>;
31 def SDT_LanaiSelectCC     : SDTypeProfile<1,  3, [SDTCisSameAs<0, 1>,
32                                                   SDTCisSameAs<1, 2>]>;
33 def SDT_LanaiSetCC        : SDTypeProfile<1,  1, [SDTCisVT<0, i32>,
34                                                   SDTCisVT<1, i32>]>;
35 def SDT_LanaiBrCC         : SDTypeProfile<0,  2, [SDTCisVT<0, OtherVT>,
36                                                   SDTCisVT<1, i32>]>;
37 def SDT_LanaiAdjDynAlloc  : SDTypeProfile<1,  1, [SDTCisVT<0, i32>,
38                                                   SDTCisVT<1, i32>]>;
39
40 def Call             : SDNode<"LanaiISD::CALL", SDT_LanaiCall,
41                               [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
42                                SDNPVariadic]>;
43 def RetFlag          : SDNode<"LanaiISD::RET_FLAG", SDTNone,
44                               [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
45 def CallSeqStart     : SDNode<"ISD::CALLSEQ_START", SDT_LanaiCallSeqStart,
46                               [SDNPHasChain, SDNPOutGlue]>;
47 def CallSeqEnd       : SDNode<"ISD::CALLSEQ_END", SDT_LanaiCallSeqEnd,
48                               [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
49 def LanaiSetFlag     : SDNode<"LanaiISD::SET_FLAG", SDT_LanaiSetFlag,
50                               [SDNPOutGlue]>;
51 def LanaiSubbF       : SDNode<"LanaiISD::SUBBF", SDT_LanaiSetFlag,
52                               [SDNPOutGlue, SDNPInGlue]>;
53 def LanaiBrCC        : SDNode<"LanaiISD::BR_CC", SDT_LanaiBrCC,
54                               [SDNPHasChain, SDNPInGlue]>;
55 def LanaiSelectCC    : SDNode<"LanaiISD::SELECT_CC", SDT_LanaiSelectCC,
56                               [SDNPInGlue]>;
57 def LanaiSetCC       : SDNode<"LanaiISD::SETCC", SDT_LanaiSetCC,
58                               [SDNPInGlue]>;
59 def LanaiHi          : SDNode<"LanaiISD::HI", SDTIntUnaryOp>;
60 def LanaiLo          : SDNode<"LanaiISD::LO", SDTIntUnaryOp>;
61 def LanaiSmall       : SDNode<"LanaiISD::SMALL", SDTIntUnaryOp>;
62 def LanaiAdjDynAlloc : SDNode<"LanaiISD::ADJDYNALLOC", SDT_LanaiAdjDynAlloc>;
63
64 // Extract bits 0-15 (low-end) of an immediate value.
65 def LO16 : SDNodeXForm<imm, [{
66   return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() & 0xffff,
67                                    SDLoc(N), MVT::i32);
68 }]>;
69
70 // Extract bits 16-31 (high-end) of an immediate value.
71 // Transformation function: shift the immediate value down into the low bits.
72 def HI16 : SDNodeXForm<imm, [{
73   return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() >> 16, SDLoc(N),
74                                    MVT::i32);
75 }]>;
76
77 def NEG : SDNodeXForm<imm, [{
78   return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32);
79 }]>;
80
81 def LO21 : SDNodeXForm<imm, [{
82   return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() & 0x1fffff,
83                                    SDLoc(N), MVT::i32);
84 }]>;
85
86 // Branch targets
87 def BrTargetAsmOperand : AsmOperandClass {
88   let Name = "BrTarget";
89 }
90 def BrTarget   : Operand<OtherVT> {
91   let ParserMatchClass = BrTargetAsmOperand;
92   let EncoderMethod = "getBranchTargetOpValue";
93   let DecoderMethod = "decodeBranch";
94 }
95
96 def CallTargetAsmOperand : AsmOperandClass {
97   let Name = "CallTarget";
98 }
99 def CallTarget : Operand<i32> {
100   let ParserMatchClass = CallTargetAsmOperand;
101   let EncoderMethod = "getBranchTargetOpValue";
102   let DecoderMethod = "decodeBranch";
103 }
104
105 def ImmShiftAsmOperand : AsmOperandClass { let Name = "ImmShift"; }
106 def immShift : Operand<i32>, PatLeaf<(imm), [{
107     int Imm = N->getSExtValue();
108     return Imm >= -31 && Imm <= 31;}]> {
109   let ParserMatchClass = ImmShiftAsmOperand;
110   let DecoderMethod = "decodeShiftImm";
111 }
112
113 def Imm10AsmOperand : AsmOperandClass { let Name = "Imm10"; }
114 def imm10 : Operand<i32>, PatLeaf<(imm), [{
115     return isInt<10>(N->getSExtValue()); }]> {
116   let ParserMatchClass = Imm10AsmOperand;
117 }
118
119 def LoImm16AsmOperand : AsmOperandClass { let Name = "LoImm16"; }
120 def i32lo16z : Operand<i32>, PatLeaf<(i32 imm), [{
121     // i32lo16 predicate - true if the 32-bit immediate has only rightmost 16
122     // bits set.
123     return ((N->getZExtValue() & 0xFFFFUL) == N->getZExtValue());}], LO16> {
124   let ParserMatchClass = LoImm16AsmOperand;
125 }
126 def i32neg16 : Operand<i32>, PatLeaf<(i32 imm), [{
127     // i32neg16 predicate - true if the 32-bit immediate is negative and can
128     // be represented by a 16 bit integer.
129     int Imm = N->getSExtValue();
130     return (Imm < 0) && (isInt<16>(Imm));}], LO16> {
131   let ParserMatchClass = LoImm16AsmOperand;
132 }
133 def i32lo16s : Operand<i32>, PatLeaf<(i32 imm), [{
134     // i32lo16 predicate - true if the 32-bit immediate has only rightmost 16
135     // bits set.
136     return ((int64_t)(N->getSExtValue() & 0xFFFFUL) == N->getSExtValue());}], LO16> {
137   let ParserMatchClass = LoImm16AsmOperand;
138 }
139
140 def LoImm16AndAsmOperand : AsmOperandClass { let Name = "LoImm16And"; }
141 def i32lo16and : Operand<i32>, PatLeaf<(i32 imm), [{
142     // i32lo16 predicate - true if the 32-bit immediate has the rightmost 16
143     // bits set and the leftmost 16 bits 1's.
144     return (N->getZExtValue() >= 0xFFFF0000UL);}], LO16> {
145   let ParserMatchClass = LoImm16AndAsmOperand;
146   let PrintMethod = "printLo16AndImmOperand";
147 }
148
149 def HiImm16AsmOperand : AsmOperandClass { let Name = "HiImm16"; }
150 def i32hi16 : Operand<i32>, PatLeaf<(i32 imm), [{
151     // i32hi16 predicate - true if the 32-bit immediate has only leftmost 16
152     // bits set.
153     return ((N->getZExtValue() & 0xFFFF0000UL) == N->getZExtValue());}], HI16> {
154   let ParserMatchClass = HiImm16AsmOperand;
155   let PrintMethod = "printHi16ImmOperand";
156 }
157
158 def HiImm16AndAsmOperand : AsmOperandClass { let Name = "HiImm16And"; }
159 def i32hi16and : Operand<i32>, PatLeaf<(i32 imm), [{
160     // i32lo16 predicate - true if the 32-bit immediate has the leftmost 16
161     // bits set and the rightmost 16 bits 1's.
162     return ((N->getZExtValue() & 0xFFFFUL) == 0xFFFFUL);}], HI16> {
163   let ParserMatchClass = HiImm16AndAsmOperand;
164   let PrintMethod = "printHi16AndImmOperand";
165 }
166
167 def LoImm21AsmOperand : AsmOperandClass { let Name = "LoImm21"; }
168 def i32lo21 : Operand<i32>, PatLeaf<(i32 imm), [{
169     // i32lo21 predicate - true if the 32-bit immediate has only rightmost 21
170     // bits set.
171     return ((N->getZExtValue() & 0x1FFFFFUL) == N->getZExtValue());}], LO21> {
172   let ParserMatchClass = LoImm21AsmOperand;
173 }
174
175 def AluOp : Operand<i32> {
176   let PrintMethod = "printAluOperand";
177 }
178
179 // Addressing modes.
180 def ADDRrr : ComplexPattern<i32, 3, "selectAddrRr", [], []>;
181 def ADDRri : ComplexPattern<i32, 3, "selectAddrRi", [frameindex], []>;
182 def ADDRsls : ComplexPattern<i32, 1, "selectAddrSls", [frameindex], []>;
183 def ADDRspls : ComplexPattern<i32, 3, "selectAddrSpls", [frameindex], []>;
184
185 // Address operands
186 def MemRegImmAsmOperand : AsmOperandClass {
187   let Name = "MemRegImm";
188   let ParserMethod  = "parseMemoryOperand";
189 }
190 def MEMri : Operand<i32> {
191   let DecoderMethod = "decodeRiMemoryValue";
192   let EncoderMethod = "getRiMemoryOpValue";
193   let MIOperandInfo = (ops GPR:$base, i32lo16s:$offset, AluOp:$Opcode);
194   let ParserMatchClass = MemRegImmAsmOperand;
195   let PrintMethod   = "printMemRiOperand";
196 }
197
198 def MemRegRegAsmOperand : AsmOperandClass {
199   let Name = "MemRegReg";
200   let ParserMethod  = "parseMemoryOperand";
201 }
202 def MEMrr : Operand<i32> {
203   let DecoderMethod = "decodeRrMemoryValue";
204   let EncoderMethod = "getRrMemoryOpValue";
205   let MIOperandInfo = (ops GPR:$Op1, GPR:$Op2, AluOp:$Opcode);
206   let ParserMatchClass = MemRegRegAsmOperand;
207   let PrintMethod   = "printMemRrOperand";
208 }
209
210 def MemImmAsmOperand : AsmOperandClass {
211   let Name = "MemImm";
212   let ParserMethod  = "parseMemoryOperand";
213 }
214 def MEMi : Operand<i32> {
215   let MIOperandInfo = (ops i32lo21:$offset);
216   let ParserMatchClass = MemImmAsmOperand;
217   let PrintMethod   = "printMemImmOperand";
218 }
219
220 def MemSplsAsmOperand : AsmOperandClass {
221   let Name = "MemSpls";
222   let ParserMethod  = "parseMemoryOperand";
223 }
224 def MEMspls : Operand<i32> {
225   let DecoderMethod = "decodeSplsValue";
226   let EncoderMethod = "getSplsOpValue";
227   let MIOperandInfo = (ops GPR:$base, imm10:$offset, AluOp:$Opcode);
228   let ParserMatchClass = MemSplsAsmOperand;
229   let PrintMethod   = "printMemSplsOperand";
230 }
231
232 def CCOp : Operand<i32> {
233   let PrintMethod = "printCCOperand";
234 }
235
236 // Predicate operand. Default to 0 = true.
237 def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
238
239 def pred : PredicateOperand<i32, (ops i32imm), (ops (i32 0))> {
240   let PrintMethod = "printPredicateOperand";
241   let ParserMatchClass = CondCodeOperand;
242   let DecoderMethod = "decodePredicateOperand";
243 }
244
245 let hasSideEffects = 0, Inst = 0x00000001 in
246   def NOP : InstLanai<(outs), (ins), "nop", []>;
247
248 // Special NOPs to change logging level in vlanai.
249 let hasSideEffects = 0, Inst = 0x00000002 in
250   def LOG0 : InstLanai<(outs), (ins), "log_0", []>;
251 let hasSideEffects = 0, Inst = 0x00000003 in
252   def LOG1 : InstLanai<(outs), (ins), "log_1", []>;
253 let hasSideEffects = 0, Inst = 0x00000004 in
254   def LOG2 : InstLanai<(outs), (ins), "log_2", []>;
255 let hasSideEffects = 0, Inst = 0x00000005 in
256   def LOG3 : InstLanai<(outs), (ins), "log_3", []>;
257 let hasSideEffects = 0, Inst = 0x00000006 in
258   def LOG4 : InstLanai<(outs), (ins), "log_4", []>;
259
260 // Map an SPLS instruction onto itself. All other instructions will be mapped
261 // onto -1. Used to identify SPLS instructions.
262 def splsIdempotent : InstrMapping {
263   let FilterClass = "InstSPLS";
264   let RowFields = ["AsmString"];
265   let ColFields = ["PostEncoderMethod"];
266   let KeyCol = ["adjustPqBitsSpls"];
267   let ValueCols = [["adjustPqBitsSpls"]];
268 }
269
270 // -------------------------------------------------- //
271 // ALU instructions
272 // -------------------------------------------------- //
273 multiclass ALUbase<bits<3> subOp, string AsmStr, SDNode OpNode,
274                    PatLeaf LoExt, PatLeaf HiExt,
275                    list<dag> loPattern, list<dag> hiPattern> {
276   // Register Immediate
277   let H = 0 in
278     def LO : InstRI<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, LoExt:$imm16),
279                     !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"),
280                     loPattern>;
281   let H = 1 in
282     def HI : InstRI<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, HiExt:$imm16),
283                     !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"),
284                     hiPattern>;
285
286 }
287
288 multiclass ALUarith<bits<3> subOp, string AsmStr, SDNode OpNode,
289                     PatLeaf LoExt, PatLeaf HiExt> {
290   defm I_ : ALUbase<subOp, AsmStr, OpNode, LoExt, HiExt, [], []>;
291
292   // Register Register
293   let JJJJJ = 0 in
294     def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI),
295                    !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"),
296                    [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>;
297 }
298
299 multiclass ALUlogic<bits<3> subOp, string AsmStr, SDNode OpNode,
300                     PatLeaf LoExt, PatLeaf HiExt> {
301   defm I_ : ALUbase<subOp, AsmStr, OpNode, LoExt, HiExt,
302                     [(set GPR:$Rd, (OpNode GPR:$Rs1, LoExt:$imm16))],
303                     [(set GPR:$Rd, (OpNode GPR:$Rs1, HiExt:$imm16))]>;
304
305   // Register Register
306   let JJJJJ = 0 in
307     def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI),
308                    !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"),
309                    [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>;
310 }
311
312 // Non flag setting ALU operations
313 let isAsCheapAsAMove = 1, F = 0 in {
314   let isCommutable = 1 in {
315     defm ADD_ : ALUarith<0b000, "add", add, i32lo16z, i32hi16>;
316   }
317   defm SUB_ : ALUarith<0b010,   "sub", sub, i32lo16z, i32hi16>;
318   let isCommutable = 1 in {
319     defm AND_ : ALUlogic<0b100, "and", and, i32lo16and, i32hi16and>;
320     defm OR_  : ALUlogic<0b101,  "or",  or, i32lo16z, i32hi16>;
321     defm XOR_ : ALUlogic<0b110, "xor", xor, i32lo16z, i32hi16>;
322   }
323 }
324
325 def : Pat<(add GPR:$Rs1, i32lo16z:$imm),
326           (ADD_I_LO GPR:$Rs1, i32lo16z:$imm)>;
327
328 def : Pat<(sub GPR:$Rs1, i32lo16z:$imm),
329           (SUB_I_LO GPR:$Rs1, i32lo16z:$imm)>;
330
331 def : Pat<(add GPR:$Rs1, i32hi16:$imm),
332           (ADD_I_HI GPR:$Rs1, i32hi16:$imm)>;
333
334 def : Pat<(sub GPR:$Rs1, i32hi16:$imm),
335           (SUB_I_HI GPR:$Rs1, i32hi16:$imm)>;
336
337 def : Pat<(i32 i32lo16and:$imm), (AND_I_LO (i32 R1), i32lo16and:$imm)>;
338 def : Pat<(i32 i32hi16and:$imm), (AND_I_HI (i32 R1), i32hi16and:$imm)>;
339
340 // Change add/sub with negative number to sub/add
341 def : Pat<(add GPR:$Rs1, i32neg16:$imm),
342           (SUB_I_LO GPR:$Rs1, (NEG $imm))>;
343 def : Pat<(sub GPR:$Rs1, i32neg16:$imm),
344           (ADD_I_LO GPR:$Rs1, (NEG $imm))>;
345
346 // Flag (incl. carry) setting addition and subtraction
347 let F = 1, Defs = [SR] in {
348   defm ADD_F_ : ALUarith<0b000, "add.f", addc, i32lo16z, i32hi16>;
349   defm SUB_F_ : ALUarith<0b010, "sub.f", subc, i32lo16z, i32hi16>;
350 }
351
352 def : Pat<(addc GPR:$Rs1, i32lo16z:$imm),
353           (ADD_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
354
355 def : Pat<(subc GPR:$Rs1, i32lo16z:$imm),
356           (SUB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
357
358 def : Pat<(addc GPR:$Rs1, i32hi16:$imm),
359           (ADD_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
360
361 def : Pat<(subc GPR:$Rs1, i32hi16:$imm),
362           (SUB_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
363
364 // Carry using addition and subtraction
365 let F = 0, Uses = [SR] in {
366   defm ADDC_ : ALUarith<0b001, "addc", adde, i32lo16z, i32hi16>;
367   defm SUBB_ : ALUarith<0b011, "subb", sube, i32lo16z, i32hi16>;
368 }
369
370 def : Pat<(adde GPR:$Rs1, i32lo16z:$imm),
371           (ADDC_I_LO GPR:$Rs1, i32lo16z:$imm)>;
372
373 def : Pat<(sube GPR:$Rs1, i32lo16z:$imm),
374           (SUBB_I_LO GPR:$Rs1, i32lo16z:$imm)>;
375
376 def : Pat<(adde GPR:$Rs1, i32hi16:$imm),
377           (ADDC_I_HI GPR:$Rs1, i32hi16:$imm)>;
378
379 def : Pat<(sube GPR:$Rs1, i32hi16:$imm),
380           (SUBB_I_HI GPR:$Rs1, i32hi16:$imm)>;
381
382 // Flag setting ALU operations
383 let isAsCheapAsAMove = 1, F = 1, Defs = [SR] in {
384   let isCommutable = 1 in {
385     defm AND_F_ : ALUlogic<0b100, "and.f",  and, i32lo16and, i32hi16and>;
386     defm OR_F_  : ALUlogic<0b101,  "or.f",   or, i32lo16z, i32hi16>;
387     defm XOR_F_ : ALUlogic<0b110, "xor.f",  xor, i32lo16z, i32hi16>;
388   }
389 }
390
391 let isAsCheapAsAMove = 1, F = 1, Defs = [SR], Uses = [SR] in {
392   defm ADDC_F_ : ALUarith<0b001, "addc.f", adde, i32lo16z, i32hi16>;
393   defm SUBB_F_ : ALUarith<0b011, "subb.f", sube, i32lo16z, i32hi16>;
394 }
395
396 def : Pat<(LanaiSubbF GPR:$Rs1, GPR:$Rs2),
397           (SUBB_F_R GPR:$Rs1, GPR:$Rs2)>;
398
399 def : Pat<(LanaiSubbF GPR:$Rs1, i32lo16z:$imm),
400           (SUBB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
401
402 def : Pat<(LanaiSubbF GPR:$Rs1, i32hi16:$imm),
403           (SUBB_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
404
405 def : InstAlias<"mov $src, $dst", (ADD_R GPR:$dst, GPR:$src, R0, 0)>;
406
407 let isAsCheapAsAMove = 1, Rs1 = R0.Num, isCodeGenOnly = 1, H = 1, F = 0,
408   isReMaterializable = 1 in
409   def MOVHI : InstRI<0b000, (outs GPR:$Rd), (ins i32hi16:$imm16),
410                      "mov\t$imm16, $Rd",
411                      [(set GPR:$Rd, i32hi16:$imm16)]>;
412
413 def : InstAlias<"mov $imm16, $dst", (ADD_I_LO GPR:$dst, R0, i32lo16z:$imm16)>;
414 def : InstAlias<"mov $imm16, $dst", (ADD_I_HI GPR:$dst, R0, i32hi16:$imm16)>;
415 def : InstAlias<"mov $imm16, $dst",
416                 (AND_I_LO GPR:$dst, R1, i32lo16and:$imm16)>;
417 def : InstAlias<"mov $imm16, $dst",
418                 (AND_I_HI GPR:$dst, R1, i32hi16and:$imm16)>;
419
420 // Shift instructions
421 class ShiftRI<string AsmStr, list<dag> Pattern>
422   : InstRI<0b111, (outs GPR:$Rd), (ins GPR:$Rs1, immShift:$imm16),
423            !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"), Pattern> {
424   let isReMaterializable = 1;
425 }
426
427 let F = 0 in {
428   let H = 0 in
429     def SL_I : ShiftRI<"sh", [(set GPR:$Rd, (shl GPR:$Rs1, immShift:$imm16))]>;
430   let H = 1 in
431     def SA_I : ShiftRI<"sha", []>;
432 }
433 def : Pat<(srl GPR:$Rs1, immShift:$imm), (SL_I GPR:$Rs1, (NEG $imm))>;
434 def : Pat<(sra GPR:$Rs1, immShift:$imm), (SA_I GPR:$Rs1, (NEG $imm))>;
435
436 let F = 1, Defs = [SR] in {
437   let H = 0 in
438     def SL_F_I : ShiftRI<"sh.f", []>;
439   let H = 1 in
440     def SA_F_I : ShiftRI<"sha.f", []>;
441 }
442
443 class ShiftRR<string AsmStr, list<dag> Pattern>
444   : InstRR<0b111, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI), AsmStr,
445            Pattern>;
446
447 let F = 0 in {
448   let JJJJJ = 0b10000 in
449     def SHL_R : ShiftRR<"sh$DDDI\t$Rs1, $Rs2, $Rd",
450                         [(set GPR:$Rd, (shl GPR:$Rs1, GPR:$Rs2))]>;
451   let isCodeGenOnly = 1 in {
452     let JJJJJ = 0b10000 in
453       def SRL_R : ShiftRR<"sh$DDDI\t$Rs1, $Rs2, $Rd", []>;
454   }
455   let JJJJJ = 0b11000 in
456     def SRA_R : ShiftRR<"sha$DDDI\t$Rs1, $Rs2, $Rd", []>;
457 }
458
459 let F = 1, Defs = [SR] in {
460   let JJJJJ = 0b10000 in
461     def SHL_F_R : ShiftRR<"sh.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
462   let isCodeGenOnly = 1 in {
463     let JJJJJ = 0b10000 in
464       def SRL_F_R : ShiftRR<"sh.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
465   }
466   let JJJJJ = 0b11000 in
467     def SRA_F_R : ShiftRR<"sha.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
468 }
469
470 // Expand shift-right operations
471 def : Pat<(srl GPR:$Rs1, GPR:$Rs2),
472           (SRL_R GPR:$Rs1, (SUB_R R0, GPR:$Rs2))>;
473 def : Pat<(sra GPR:$Rs1, GPR:$Rs2),
474           (SRA_R GPR:$Rs1, (SUB_R R0, GPR:$Rs2))>;
475
476 // -------------------------------------------------- //
477 // LOAD instructions
478 // -------------------------------------------------- //
479
480 class LoadRR<string OpcString, PatFrag OpNode, ValueType Ty>
481   : InstRRM<0b0, (outs GPR:$Rd), (ins MEMrr:$src),
482             !strconcat(OpcString, "\t$src, $Rd"),
483             [(set (Ty GPR:$Rd), (OpNode ADDRrr:$src))]>,
484     Sched<[WriteLD]> {
485   bits<20> src;
486
487   let Rs1 = src{19-15};
488   let Rs2 = src{14-10};
489   let P = src{9};
490   let Q = src{8};
491   let BBB = src{7-5};
492   let JJJJJ = src{4-0};
493   let mayLoad = 1;
494 }
495
496 class LoadRI<string OpcString, PatFrag OpNode, ValueType Ty>
497   : InstRM<0b0, (outs GPR:$Rd), (ins MEMri:$src),
498            !strconcat(OpcString, "\t$src, $Rd"),
499            [(set (Ty GPR:$Rd), (OpNode ADDRri:$src))]>,
500     Sched<[WriteLD]> {
501   bits<23> src;
502
503   let Itinerary = IIC_LD;
504   let Rs1 = src{22-18};
505   let P = src{17};
506   let Q = src{16};
507   let imm16 = src{15-0};
508   let isReMaterializable = 1;
509   let mayLoad = 1;
510 }
511
512 let E = 0 in {
513   let YL = 0b01 in {
514     // uld is used here and ld in the alias as the alias is printed out first if
515     // an alias exist
516     def LDW_RI : LoadRI<"uld", load, i32>;
517     def LDW_RR : LoadRR<"ld", load, i32>;
518   }
519 }
520
521 def : InstAlias<"ld $src, $dst", (LDW_RI GPR:$dst, MEMri:$src)>;
522
523 let E = 1 in {
524   let YL = 0b01 in {
525     def LDWz_RR : LoadRR<"uld", zextloadi32, i32>;
526   }
527 }
528
529 let E = 1 in {
530   let YL = 0b00 in
531     def LDHz_RR : LoadRR<"uld.h", zextloadi16, i32>;
532   let YL = 0b10 in
533     def LDBz_RR : LoadRR<"uld.b", zextloadi8, i32>;
534 }
535
536 let E = 0 in {
537   let YL = 0b00 in
538     def LDHs_RR : LoadRR<"ld.h", sextloadi16, i32>;
539   let YL = 0b10 in
540     def LDBs_RR : LoadRR<"ld.b", sextloadi8, i32>;
541 }
542
543 def LDADDR : InstSLS<0x0, (outs GPR:$Rd), (ins MEMi:$src),
544                      "ld\t$src, $Rd",
545                      [(set (i32 GPR:$Rd), (load ADDRsls:$src))]>,
546     Sched<[WriteLD]> {
547   bits<21> src;
548
549   let Itinerary = IIC_LD;
550   let msb = src{20-16};
551   let lsb = src{15-0};
552   let isReMaterializable = 1;
553   let mayLoad = 1;
554 }
555
556 class LoadSPLS<string asmstring, PatFrag opNode>
557   : InstSPLS<(outs GPR:$Rd), (ins MEMspls:$src),
558              !strconcat(asmstring, "\t$src, $Rd"),
559              [(set (i32 GPR:$Rd), (opNode ADDRspls:$src))]>,
560     Sched<[WriteLDSW]> {
561   bits<17> src;
562   let Itinerary = IIC_LDSW;
563   let Rs1 = src{16-12};
564   let P = src{11};
565   let Q = src{10};
566   let imm10 = src{9-0};
567   let mayLoad = 1;
568   let isReMaterializable = 1;
569 }
570
571 let Y = 0, S = 0, E = 1 in
572   def LDHz_RI : LoadSPLS<"uld.h", zextloadi16>;
573
574 let Y = 0, S = 0, E = 0 in
575   def LDHs_RI : LoadSPLS<"ld.h", sextloadi16>;
576
577 let Y = 1, S = 0, E = 1 in
578   def LDBz_RI : LoadSPLS<"uld.b", zextloadi8>;
579
580 let Y = 1, S = 0, E = 0 in
581   def LDBs_RI : LoadSPLS<"ld.b", sextloadi8>;
582
583 def SLI : InstSLI<(outs GPR:$Rd), (ins i32lo21:$imm),
584                   "mov\t$imm, $Rd",
585                   [(set GPR:$Rd, i32lo21:$imm)]> {
586   bits<21> imm;
587
588   let msb = imm{20-16};
589   let lsb = imm{15-0};
590   let isReMaterializable = 1;
591   let isAsCheapAsAMove = 1;
592 }
593
594 // -------------------------------------------------- //
595 // STORE instructions
596 // -------------------------------------------------- //
597
598 class StoreRR<string OpcString, PatFrag OpNode, ValueType Ty>
599   : InstRRM<0b1, (outs), (ins GPR:$Rd, MEMrr:$dst),
600             !strconcat(OpcString, "\t$Rd, $dst"),
601             [(OpNode (Ty GPR:$Rd), ADDRrr:$dst)]>,
602     Sched<[WriteST]> {
603   bits<20> dst;
604
605   let Itinerary = IIC_ST;
606   let Rs1 = dst{19-15};
607   let Rs2 = dst{14-10};
608   let P = dst{9};
609   let Q = dst{8};
610   let BBB = dst{7-5};
611   let JJJJJ = dst{4-0};
612   let mayStore = 1;
613 }
614
615 class StoreRI<string OpcString, PatFrag OpNode, ValueType Ty>
616   : InstRM<0b1, (outs), (ins GPR:$Rd, MEMri:$dst),
617            !strconcat(OpcString, "\t$Rd, $dst"),
618            [(OpNode (Ty GPR:$Rd), ADDRri:$dst)]>,
619     Sched<[WriteST]> {
620   bits<23> dst;
621
622   let Itinerary = IIC_ST;
623   let Rs1 = dst{22-18};
624   let P = dst{17};
625   let Q = dst{16};
626   let imm16 = dst{15-0};
627   let mayStore = 1;
628 }
629
630 let YL = 0b01, E = 0 in {
631   def SW_RR : StoreRR<"st", store, i32>;
632   def SW_RI : StoreRI<"st", store, i32>;
633 }
634
635 let E = 0 in {
636   let YL = 0b00 in
637     def STH_RR : StoreRR<"st.h", truncstorei16, i32>;
638   let YL = 0b10 in
639     def STB_RR : StoreRR<"st.b", truncstorei8, i32>;
640 }
641
642 def STADDR : InstSLS<0x1, (outs), (ins GPR:$Rd, MEMi:$dst),
643                      "st\t$Rd, $dst",
644                      [(store (i32 GPR:$Rd), ADDRsls:$dst)]>,
645     Sched<[WriteST]> {
646   bits<21> dst;
647
648   let Itinerary = IIC_ST;
649   let msb = dst{20-16};
650   let lsb = dst{15-0};
651   let mayStore = 1;
652 }
653
654 class StoreSPLS<string asmstring, PatFrag opNode>
655   : InstSPLS<(outs), (ins GPR:$Rd, MEMspls:$dst),
656              !strconcat(asmstring, "\t$Rd, $dst"),
657              [(opNode (i32 GPR:$Rd), ADDRspls:$dst)]>,
658     Sched<[WriteSTSW]> {
659   bits<17> dst;
660
661   let Itinerary = IIC_STSW;
662   let Rs1 = dst{16-12};
663   let P = dst{11};
664   let Q = dst{10};
665   let imm10 = dst{9-0};
666   let mayStore = 1;
667 }
668
669 let Y = 0, S = 1, E = 0 in
670   def STH_RI : StoreSPLS<"st.h", truncstorei16>;
671
672 let Y = 1, S = 1, E = 0 in
673   def STB_RI : StoreSPLS<"st.b", truncstorei8>;
674
675 // -------------------------------------------------- //
676 // BRANCH instructions
677 // -------------------------------------------------- //
678
679 let isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1 in {
680   def BT : InstBR<(outs), (ins BrTarget:$addr),
681                   "bt\t$addr",
682                   [(br bb:$addr)]> {
683     let DDDI = 0b0000;
684   }
685   let Uses = [SR] in
686     def BRCC : InstBR<(outs), (ins BrTarget:$addr, CCOp:$DDDI),
687                       "b$DDDI\t$addr",
688                       [(LanaiBrCC bb:$addr, imm:$DDDI)]>;
689
690   let isIndirectBranch = 1 in {
691     def JR : InstRR<0b101, (outs), (ins GPR:$Rs2), "bt\t$Rs2",
692                     [(brind GPR:$Rs2)]> {
693       let Rs1 = R0.Num;
694       let Rd = R2.Num;
695       let F = 0;
696       let JJJJJ = 0;
697       let DDDI = 0;
698     }
699   }
700 }
701
702 // -------------------------------------------------- //
703 // Condition/SF instructions
704 // -------------------------------------------------- //
705
706 // Instructions to set flags used in lowering comparisons.
707 multiclass SF<bits<3> op2Val, string AsmStr> {
708   let F = 1, Rd = R0.Num, JJJJJ = 0, Defs = [SR], DDDI = 0 in
709     def _RR : InstRR<op2Val, (outs), (ins GPR:$Rs1, GPR:$Rs2),
710                      !strconcat(AsmStr, "\t$Rs1, $Rs2, %r0"),
711                      [(LanaiSetFlag (i32 GPR:$Rs1), (i32 GPR:$Rs2))]>;
712   let F = 1, Rd = R0.Num, H = 0, Defs = [SR] in
713     def _RI_LO : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32lo16z:$imm16),
714                      !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
715                      [(LanaiSetFlag (i32 GPR:$Rs1), i32lo16z:$imm16)]>;
716   let F = 1, Rd = R0.Num, H = 1, Defs = [SR] in
717     def _RI_HI : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32hi16:$imm16),
718                      !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
719                      [(LanaiSetFlag (i32 GPR:$Rs1), i32hi16:$imm16)]>;
720 }
721 let isCodeGenOnly = 1, isCompare = 1 in {
722   defm SFSUB_F : SF<0b010, "sub.f">;
723 }
724
725 // Jump and link
726 let isCall = 1, hasDelaySlot = 1, isCodeGenOnly = 1, Uses = [SP],
727     Defs = [RCA] in {
728   def CALL : Pseudo<(outs), (ins CallTarget:$addr), "", []>;
729   def CALLR : Pseudo<(outs), (ins GPR:$Rs1), "", [(Call GPR:$Rs1)]>;
730 }
731
732 let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
733     Uses = [RCA] in {
734   def RET : InstRM<0b0, (outs), (ins),
735                    "ld\t-4[%fp], %pc ! return",
736                    [(RetFlag)]> {
737     let Rd = PC.Num;
738     let Rs1 = FP.Num;
739     let P = 1;
740     let Q = 0;
741     let imm16 = -4;
742
743     // Post encoding is not needed for RET.
744     let PostEncoderMethod = "";
745   }
746 }
747
748 // ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
749 // a stack adjustment and the codegen must know that they may modify the stack
750 // pointer before prolog-epilog rewriting occurs.
751 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
752 // sub / add which can clobber SP.
753 let Defs = [SP], Uses = [SP] in {
754   def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
755                                 "#ADJCALLSTACKDOWN $amt1 $amt2",
756                                 [(CallSeqStart timm:$amt1, timm:$amt2)]>;
757   def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
758                                 "#ADJCALLSTACKUP $amt1 $amt2",
759                                 [(CallSeqEnd timm:$amt1, timm:$amt2)]>;
760 }
761
762 let Defs = [SP], Uses = [SP] in {
763   def ADJDYNALLOC : Pseudo<(outs GPR:$dst), (ins GPR:$src),
764                            "#ADJDYNALLOC $dst $src",
765                            [(set GPR:$dst, (LanaiAdjDynAlloc GPR:$src))]>;
766 }
767
768 let Uses = [SR] in {
769   def SCC : InstSCC<(outs GPR:$Rs1), (ins CCOp:$DDDI),
770                     "s$DDDI\t$Rs1",
771                     [(set (i32 GPR:$Rs1), (LanaiSetCC imm:$DDDI))]>;
772 }
773
774 // Select with hardware support
775 let Uses = [SR], isSelect = 1 in {
776   def SELECT : InstRR<0b111, (outs GPR:$Rd),
777                       (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI),
778                       "sel.$DDDI $Rs1, $Rs2, $Rd",
779                       [(set (i32 GPR:$Rd),
780                        (LanaiSelectCC (i32 GPR:$Rs1), (i32 GPR:$Rs2),
781                                       (imm:$DDDI)))]> {
782     let JJJJJ = 0;
783     let F = 0;
784   }
785 }
786
787 let isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1,
788     isIndirectBranch = 1, Uses = [SR] in {
789   def BRIND_CC : InstRR<0b101, (outs), (ins GPR:$Rs1, CCOp:$DDDI),
790                         "b$DDDI\t$Rs1", []> {
791     let F = 0;
792     let JJJJJ = 0;
793     let Rd = PC.Num;
794     let Rs2 = R0.Num;
795   }
796
797   def BRIND_CCA : InstRR<0b101, (outs), (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI),
798                          "b${DDDI}\t$Rs1 add $Rs2", []> {
799     let F = 0;
800     let Rd = PC.Num;
801     let JJJJJ = 0;
802   }
803 }
804
805 // TODO: This only considers the case where BROFF is an immediate and not where
806 // it is a register. Add support for register relative branching.
807 let isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1, Rs1 = 0,
808     Uses = [SR] in
809   def BRR : InstBRR<(outs), (ins i16imm:$imm16, CCOp:$DDDI),
810                     "b${DDDI}.r\t$imm16", []>;
811
812 let F = 0 in {
813 // Population Count (POPC)
814 def POPC: InstSpecial<0b001, (outs GPR:$Rd), (ins GPR:$Rs1),
815                       "popc\t$Rs1, $Rd",
816                       [(set GPR:$Rd, (ctpop GPR:$Rs1))]>;
817
818 // Count Leading Zeros (LEADZ)
819 def LEADZ: InstSpecial<0b010, (outs GPR:$Rd), (ins GPR:$Rs1),
820                        "leadz\t$Rs1, $Rd", [(set GPR:$Rd, (ctlz GPR:$Rs1))]>;
821
822 // Count Trailing Zeros (TRAILZ)
823 def TRAILZ : InstSpecial<0b011, (outs GPR:$Rd), (ins GPR:$Rs1),
824                          "trailz\t$Rs1, $Rd",
825                          [(set GPR:$Rd, (cttz GPR:$Rs1))]>;
826 }
827
828 //===----------------------------------------------------------------------===//
829 // Non-Instruction Patterns
830 //===----------------------------------------------------------------------===//
831
832 // unsigned 16-bit immediate
833 def : Pat<(i32 i32lo16z:$imm), (OR_I_LO (i32 R0), imm:$imm)>;
834
835 // arbitrary immediate
836 def : Pat<(i32 imm:$imm), (OR_I_LO (MOVHI (HI16 imm:$imm)), (LO16 imm:$imm))>;
837
838 // Calls
839 def : Pat<(Call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>;
840 def : Pat<(Call texternalsym:$dst), (CALL texternalsym:$dst)>;
841
842 // Loads
843 def : Pat<(extloadi8  ADDRspls:$src), (i32 (LDBz_RI ADDRspls:$src))>;
844 def : Pat<(extloadi16 ADDRspls:$src), (i32 (LDHz_RI ADDRspls:$src))>;
845 // Loads up to 32-bits are already atomic.
846 // TODO: This is a workaround for a particular failing case and should be
847 // handled more generally.
848 def : Pat<(atomic_load_8  ADDRspls:$src), (i32 (LDBz_RI ADDRspls:$src))>;
849
850 // GlobalAddress, ExternalSymbol, Jumptable, ConstantPool
851 def : Pat<(LanaiHi tglobaladdr:$dst), (MOVHI tglobaladdr:$dst)>;
852 def : Pat<(LanaiLo tglobaladdr:$dst), (OR_I_LO (i32 R0), tglobaladdr:$dst)>;
853 def : Pat<(LanaiSmall tglobaladdr:$dst), (SLI tglobaladdr:$dst)>;
854 def : Pat<(LanaiHi texternalsym:$dst), (MOVHI texternalsym:$dst)>;
855 def : Pat<(LanaiLo texternalsym:$dst), (OR_I_LO (i32 R0), texternalsym:$dst)>;
856 def : Pat<(LanaiSmall texternalsym:$dst), (SLI texternalsym:$dst)>;
857 def : Pat<(LanaiHi tblockaddress:$dst), (MOVHI tblockaddress:$dst)>;
858 def : Pat<(LanaiLo tblockaddress:$dst), (OR_I_LO (i32 R0), tblockaddress:$dst)>;
859 def : Pat<(LanaiSmall tblockaddress:$dst), (SLI tblockaddress:$dst)>;
860 def : Pat<(LanaiHi tjumptable:$dst), (MOVHI tjumptable:$dst)>;
861 def : Pat<(LanaiLo tjumptable:$dst), (OR_I_LO (i32 R0), tjumptable:$dst)>;
862 def : Pat<(LanaiSmall tjumptable:$dst), (SLI tjumptable:$dst)>;
863 def : Pat<(LanaiHi tconstpool:$dst), (MOVHI tconstpool:$dst)>;
864 def : Pat<(LanaiLo tconstpool:$dst), (OR_I_LO (i32 R0), tconstpool:$dst)>;
865 def : Pat<(LanaiSmall tconstpool:$dst), (SLI tconstpool:$dst)>;
866
867 def : Pat<(or GPR:$hi, (LanaiLo tglobaladdr:$lo)),
868           (OR_I_LO GPR:$hi, tglobaladdr:$lo)>;
869 def : Pat<(or R0, (LanaiSmall tglobaladdr:$small)),
870           (SLI tglobaladdr:$small)>;
871 def : Pat<(or GPR:$hi, (LanaiLo texternalsym:$lo)),
872           (OR_I_LO GPR:$hi, texternalsym:$lo)>;
873 def : Pat<(or R0, (LanaiSmall texternalsym:$small)),
874           (SLI texternalsym:$small)>;
875 def : Pat<(or GPR:$hi, (LanaiLo tblockaddress:$lo)),
876           (OR_I_LO GPR:$hi, tblockaddress:$lo)>;
877 def : Pat<(or R0, (LanaiSmall tblockaddress:$small)),
878           (SLI tblockaddress:$small)>;
879 def : Pat<(or GPR:$hi, (LanaiLo tjumptable:$lo)),
880           (OR_I_LO GPR:$hi, tjumptable:$lo)>;
881 def : Pat<(or R0, (LanaiSmall tjumptable:$small)),
882           (SLI tjumptable:$small)>;
883 def : Pat<(or GPR:$hi, (LanaiLo tconstpool:$lo)),
884           (OR_I_LO GPR:$hi, tconstpool:$lo)>;
885 def : Pat<(or R0, (LanaiSmall tconstpool:$small)),
886           (SLI tconstpool:$small)>;