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