1 //===- SparcInstrInfo.td - Target Description for Sparc Target ------------===//
\r
3 // The LLVM Compiler Infrastructure
\r
5 // This file is distributed under the University of Illinois Open Source
\r
6 // License. See LICENSE.TXT for details.
\r
8 //===----------------------------------------------------------------------===//
\r
10 // This file describes the Sparc instructions in TableGen format.
\r
12 //===----------------------------------------------------------------------===//
\r
14 //===----------------------------------------------------------------------===//
\r
15 // Instruction format superclass
\r
16 //===----------------------------------------------------------------------===//
\r
18 include "SparcInstrFormats.td"
\r
20 //===----------------------------------------------------------------------===//
\r
21 // Feature predicates.
\r
22 //===----------------------------------------------------------------------===//
\r
24 // HasV9 - This predicate is true when the target processor supports V9
\r
25 // instructions. Note that the machine may be running in 32-bit mode.
\r
26 def HasV9 : Predicate<"Subtarget.isV9()">;
\r
28 // HasNoV9 - This predicate is true when the target doesn't have V9
\r
29 // instructions. Use of this is just a hack for the isel not having proper
\r
30 // costs for V8 instructions that are more expensive than their V9 ones.
\r
31 def HasNoV9 : Predicate<"!Subtarget.isV9()">;
\r
33 // HasVIS - This is true when the target processor has VIS extensions.
\r
34 def HasVIS : Predicate<"Subtarget.isVIS()">;
\r
36 // UseDeprecatedInsts - This predicate is true when the target processor is a
\r
37 // V8, or when it is V9 but the V8 deprecated instructions are efficient enough
\r
38 // to use when appropriate. In either of these cases, the instruction selector
\r
39 // will pick deprecated instructions.
\r
40 def UseDeprecatedInsts : Predicate<"Subtarget.useDeprecatedV8Instructions()">;
\r
42 //===----------------------------------------------------------------------===//
\r
43 // Instruction Pattern Stuff
\r
44 //===----------------------------------------------------------------------===//
\r
46 def simm11 : PatLeaf<(imm), [{
\r
47 // simm11 predicate - True if the imm fits in a 11-bit sign extended field.
\r
48 return (((int)N->getZExtValue() << (32-11)) >> (32-11)) ==
\r
49 (int)N->getZExtValue();
\r
52 def simm13 : PatLeaf<(imm), [{
\r
53 // simm13 predicate - True if the imm fits in a 13-bit sign extended field.
\r
54 return (((int)N->getZExtValue() << (32-13)) >> (32-13)) ==
\r
55 (int)N->getZExtValue();
\r
58 def LO10 : SDNodeXForm<imm, [{
\r
59 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() & 1023,
\r
63 def HI22 : SDNodeXForm<imm, [{
\r
64 // Transformation function: shift the immediate value down into the low bits.
\r
65 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() >> 10, MVT::i32);
\r
68 def SETHIimm : PatLeaf<(imm), [{
\r
69 return (((unsigned)N->getZExtValue() >> 10) << 10) ==
\r
70 (unsigned)N->getZExtValue();
\r
73 // Addressing modes.
\r
74 def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
\r
75 def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex], []>;
\r
78 def MEMrr : Operand<i32> {
\r
79 let PrintMethod = "printMemOperand";
\r
80 let MIOperandInfo = (ops IntRegs, IntRegs);
\r
82 def MEMri : Operand<i32> {
\r
83 let PrintMethod = "printMemOperand";
\r
84 let MIOperandInfo = (ops IntRegs, i32imm);
\r
87 // Branch targets have OtherVT type.
\r
88 def brtarget : Operand<OtherVT>;
\r
89 def calltarget : Operand<i32>;
\r
91 // Operand for printing out a condition code.
\r
92 let PrintMethod = "printCCOperand" in
\r
93 def CCOp : Operand<i32>;
\r
96 SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisSameAs<0, 1>]>;
\r
98 SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
\r
100 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>]>;
\r
102 SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;
\r
104 SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
\r
106 def SPcmpicc : SDNode<"SPISD::CMPICC", SDTIntBinOp, [SDNPOutFlag]>;
\r
107 def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutFlag]>;
\r
108 def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInFlag]>;
\r
109 def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInFlag]>;
\r
111 def SPhi : SDNode<"SPISD::Hi", SDTIntUnaryOp>;
\r
112 def SPlo : SDNode<"SPISD::Lo", SDTIntUnaryOp>;
\r
114 def SPftoi : SDNode<"SPISD::FTOI", SDTSPFTOI>;
\r
115 def SPitof : SDNode<"SPISD::ITOF", SDTSPITOF>;
\r
117 def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInFlag]>;
\r
118 def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInFlag]>;
\r
120 // These are target-independent nodes, but have target-specific formats.
\r
121 def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
\r
122 def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>,
\r
123 SDTCisVT<1, i32> ]>;
\r
125 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
\r
126 [SDNPHasChain, SDNPOutFlag]>;
\r
127 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd,
\r
128 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
\r
130 def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
\r
131 def call : SDNode<"SPISD::CALL", SDT_SPCall,
\r
132 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
\r
134 def retflag : SDNode<"SPISD::RET_FLAG", SDTNone,
\r
135 [SDNPHasChain, SDNPOptInFlag]>;
\r
137 def getPCX : Operand<i32> {
\r
138 let PrintMethod = "printGetPCX";
\r
141 //===----------------------------------------------------------------------===//
\r
142 // SPARC Flag Conditions
\r
143 //===----------------------------------------------------------------------===//
\r
145 // Note that these values must be kept in sync with the CCOp::CondCode enum
\r
147 class ICC_VAL<int N> : PatLeaf<(i32 N)>;
\r
148 def ICC_NE : ICC_VAL< 9>; // Not Equal
\r
149 def ICC_E : ICC_VAL< 1>; // Equal
\r
150 def ICC_G : ICC_VAL<10>; // Greater
\r
151 def ICC_LE : ICC_VAL< 2>; // Less or Equal
\r
152 def ICC_GE : ICC_VAL<11>; // Greater or Equal
\r
153 def ICC_L : ICC_VAL< 3>; // Less
\r
154 def ICC_GU : ICC_VAL<12>; // Greater Unsigned
\r
155 def ICC_LEU : ICC_VAL< 4>; // Less or Equal Unsigned
\r
156 def ICC_CC : ICC_VAL<13>; // Carry Clear/Great or Equal Unsigned
\r
157 def ICC_CS : ICC_VAL< 5>; // Carry Set/Less Unsigned
\r
158 def ICC_POS : ICC_VAL<14>; // Positive
\r
159 def ICC_NEG : ICC_VAL< 6>; // Negative
\r
160 def ICC_VC : ICC_VAL<15>; // Overflow Clear
\r
161 def ICC_VS : ICC_VAL< 7>; // Overflow Set
\r
163 class FCC_VAL<int N> : PatLeaf<(i32 N)>;
\r
164 def FCC_U : FCC_VAL<23>; // Unordered
\r
165 def FCC_G : FCC_VAL<22>; // Greater
\r
166 def FCC_UG : FCC_VAL<21>; // Unordered or Greater
\r
167 def FCC_L : FCC_VAL<20>; // Less
\r
168 def FCC_UL : FCC_VAL<19>; // Unordered or Less
\r
169 def FCC_LG : FCC_VAL<18>; // Less or Greater
\r
170 def FCC_NE : FCC_VAL<17>; // Not Equal
\r
171 def FCC_E : FCC_VAL<25>; // Equal
\r
172 def FCC_UE : FCC_VAL<24>; // Unordered or Equal
\r
173 def FCC_GE : FCC_VAL<25>; // Greater or Equal
\r
174 def FCC_UGE : FCC_VAL<26>; // Unordered or Greater or Equal
\r
175 def FCC_LE : FCC_VAL<27>; // Less or Equal
\r
176 def FCC_ULE : FCC_VAL<28>; // Unordered or Less or Equal
\r
177 def FCC_O : FCC_VAL<29>; // Ordered
\r
179 //===----------------------------------------------------------------------===//
\r
180 // Instruction Class Templates
\r
181 //===----------------------------------------------------------------------===//
\r
183 /// F3_12 multiclass - Define a normal F3_1/F3_2 pattern in one shot.
\r
184 multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode> {
\r
185 def rr : F3_1<2, Op3Val,
\r
186 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
\r
187 !strconcat(OpcStr, " $b, $c, $dst"),
\r
188 [(set IntRegs:$dst, (OpNode IntRegs:$b, IntRegs:$c))]>;
\r
189 def ri : F3_2<2, Op3Val,
\r
190 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
\r
191 !strconcat(OpcStr, " $b, $c, $dst"),
\r
192 [(set IntRegs:$dst, (OpNode IntRegs:$b, simm13:$c))]>;
\r
195 /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no
\r
197 multiclass F3_12np<string OpcStr, bits<6> Op3Val> {
\r
198 def rr : F3_1<2, Op3Val,
\r
199 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
\r
200 !strconcat(OpcStr, " $b, $c, $dst"), []>;
\r
201 def ri : F3_2<2, Op3Val,
\r
202 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
\r
203 !strconcat(OpcStr, " $b, $c, $dst"), []>;
\r
206 //===----------------------------------------------------------------------===//
\r
208 //===----------------------------------------------------------------------===//
\r
210 // Pseudo instructions.
\r
211 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
\r
212 : InstSP<outs, ins, asmstr, pattern>;
\r
215 let Defs = [O7], Uses = [O7] in {
\r
216 def GETPCX : Pseudo<(outs getPCX:$getpcseq), (ins), "$getpcseq", [] >;
\r
219 let Defs = [O6], Uses = [O6] in {
\r
220 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt),
\r
221 "!ADJCALLSTACKDOWN $amt",
\r
222 [(callseq_start timm:$amt)]>;
\r
223 def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
\r
224 "!ADJCALLSTACKUP $amt1",
\r
225 [(callseq_end timm:$amt1, timm:$amt2)]>;
\r
228 // FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the
\r
230 let Predicates = [HasNoV9] in { // Only emit these in V8 mode.
\r
231 def FpMOVD : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$src),
\r
232 "!FpMOVD $src, $dst", []>;
\r
233 def FpNEGD : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$src),
\r
234 "!FpNEGD $src, $dst",
\r
235 [(set DFPRegs:$dst, (fneg DFPRegs:$src))]>;
\r
236 def FpABSD : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$src),
\r
237 "!FpABSD $src, $dst",
\r
238 [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>;
\r
241 // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after
\r
242 // instruction selection into a branch sequence. This has to handle all
\r
243 // permutations of selection between i32/f32/f64 on ICC and FCC.
\r
244 let usesCustomInserter = 1 in { // Expanded after instruction selection.
\r
245 def SELECT_CC_Int_ICC
\r
246 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond),
\r
247 "; SELECT_CC_Int_ICC PSEUDO!",
\r
248 [(set IntRegs:$dst, (SPselecticc IntRegs:$T, IntRegs:$F,
\r
250 def SELECT_CC_Int_FCC
\r
251 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond),
\r
252 "; SELECT_CC_Int_FCC PSEUDO!",
\r
253 [(set IntRegs:$dst, (SPselectfcc IntRegs:$T, IntRegs:$F,
\r
255 def SELECT_CC_FP_ICC
\r
256 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond),
\r
257 "; SELECT_CC_FP_ICC PSEUDO!",
\r
258 [(set FPRegs:$dst, (SPselecticc FPRegs:$T, FPRegs:$F,
\r
260 def SELECT_CC_FP_FCC
\r
261 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, i32imm:$Cond),
\r
262 "; SELECT_CC_FP_FCC PSEUDO!",
\r
263 [(set FPRegs:$dst, (SPselectfcc FPRegs:$T, FPRegs:$F,
\r
265 def SELECT_CC_DFP_ICC
\r
266 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond),
\r
267 "; SELECT_CC_DFP_ICC PSEUDO!",
\r
268 [(set DFPRegs:$dst, (SPselecticc DFPRegs:$T, DFPRegs:$F,
\r
270 def SELECT_CC_DFP_FCC
\r
271 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, i32imm:$Cond),
\r
272 "; SELECT_CC_DFP_FCC PSEUDO!",
\r
273 [(set DFPRegs:$dst, (SPselectfcc DFPRegs:$T, DFPRegs:$F,
\r
278 // Section A.3 - Synthetic Instructions, p. 85
\r
279 // special cases of JMPL:
\r
280 let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in {
\r
281 let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
\r
282 def RETL: F3_2<2, 0b111000, (outs), (ins), "retl", [(retflag)]>;
\r
285 // Section B.1 - Load Integer Instructions, p. 90
\r
286 def LDSBrr : F3_1<3, 0b001001,
\r
287 (outs IntRegs:$dst), (ins MEMrr:$addr),
\r
288 "ldsb [$addr], $dst",
\r
289 [(set IntRegs:$dst, (sextloadi8 ADDRrr:$addr))]>;
\r
290 def LDSBri : F3_2<3, 0b001001,
\r
291 (outs IntRegs:$dst), (ins MEMri:$addr),
\r
292 "ldsb [$addr], $dst",
\r
293 [(set IntRegs:$dst, (sextloadi8 ADDRri:$addr))]>;
\r
294 def LDSHrr : F3_1<3, 0b001010,
\r
295 (outs IntRegs:$dst), (ins MEMrr:$addr),
\r
296 "ldsh [$addr], $dst",
\r
297 [(set IntRegs:$dst, (sextloadi16 ADDRrr:$addr))]>;
\r
298 def LDSHri : F3_2<3, 0b001010,
\r
299 (outs IntRegs:$dst), (ins MEMri:$addr),
\r
300 "ldsh [$addr], $dst",
\r
301 [(set IntRegs:$dst, (sextloadi16 ADDRri:$addr))]>;
\r
302 def LDUBrr : F3_1<3, 0b000001,
\r
303 (outs IntRegs:$dst), (ins MEMrr:$addr),
\r
304 "ldub [$addr], $dst",
\r
305 [(set IntRegs:$dst, (zextloadi8 ADDRrr:$addr))]>;
\r
306 def LDUBri : F3_2<3, 0b000001,
\r
307 (outs IntRegs:$dst), (ins MEMri:$addr),
\r
308 "ldub [$addr], $dst",
\r
309 [(set IntRegs:$dst, (zextloadi8 ADDRri:$addr))]>;
\r
310 def LDUHrr : F3_1<3, 0b000010,
\r
311 (outs IntRegs:$dst), (ins MEMrr:$addr),
\r
312 "lduh [$addr], $dst",
\r
313 [(set IntRegs:$dst, (zextloadi16 ADDRrr:$addr))]>;
\r
314 def LDUHri : F3_2<3, 0b000010,
\r
315 (outs IntRegs:$dst), (ins MEMri:$addr),
\r
316 "lduh [$addr], $dst",
\r
317 [(set IntRegs:$dst, (zextloadi16 ADDRri:$addr))]>;
\r
318 def LDrr : F3_1<3, 0b000000,
\r
319 (outs IntRegs:$dst), (ins MEMrr:$addr),
\r
320 "ld [$addr], $dst",
\r
321 [(set IntRegs:$dst, (load ADDRrr:$addr))]>;
\r
322 def LDri : F3_2<3, 0b000000,
\r
323 (outs IntRegs:$dst), (ins MEMri:$addr),
\r
324 "ld [$addr], $dst",
\r
325 [(set IntRegs:$dst, (load ADDRri:$addr))]>;
\r
327 // Section B.2 - Load Floating-point Instructions, p. 92
\r
328 def LDFrr : F3_1<3, 0b100000,
\r
329 (outs FPRegs:$dst), (ins MEMrr:$addr),
\r
330 "ld [$addr], $dst",
\r
331 [(set FPRegs:$dst, (load ADDRrr:$addr))]>;
\r
332 def LDFri : F3_2<3, 0b100000,
\r
333 (outs FPRegs:$dst), (ins MEMri:$addr),
\r
334 "ld [$addr], $dst",
\r
335 [(set FPRegs:$dst, (load ADDRri:$addr))]>;
\r
336 def LDDFrr : F3_1<3, 0b100011,
\r
337 (outs DFPRegs:$dst), (ins MEMrr:$addr),
\r
338 "ldd [$addr], $dst",
\r
339 [(set DFPRegs:$dst, (load ADDRrr:$addr))]>;
\r
340 def LDDFri : F3_2<3, 0b100011,
\r
341 (outs DFPRegs:$dst), (ins MEMri:$addr),
\r
342 "ldd [$addr], $dst",
\r
343 [(set DFPRegs:$dst, (load ADDRri:$addr))]>;
\r
345 // Section B.4 - Store Integer Instructions, p. 95
\r
346 def STBrr : F3_1<3, 0b000101,
\r
347 (outs), (ins MEMrr:$addr, IntRegs:$src),
\r
348 "stb $src, [$addr]",
\r
349 [(truncstorei8 IntRegs:$src, ADDRrr:$addr)]>;
\r
350 def STBri : F3_2<3, 0b000101,
\r
351 (outs), (ins MEMri:$addr, IntRegs:$src),
\r
352 "stb $src, [$addr]",
\r
353 [(truncstorei8 IntRegs:$src, ADDRri:$addr)]>;
\r
354 def STHrr : F3_1<3, 0b000110,
\r
355 (outs), (ins MEMrr:$addr, IntRegs:$src),
\r
356 "sth $src, [$addr]",
\r
357 [(truncstorei16 IntRegs:$src, ADDRrr:$addr)]>;
\r
358 def STHri : F3_2<3, 0b000110,
\r
359 (outs), (ins MEMri:$addr, IntRegs:$src),
\r
360 "sth $src, [$addr]",
\r
361 [(truncstorei16 IntRegs:$src, ADDRri:$addr)]>;
\r
362 def STrr : F3_1<3, 0b000100,
\r
363 (outs), (ins MEMrr:$addr, IntRegs:$src),
\r
364 "st $src, [$addr]",
\r
365 [(store IntRegs:$src, ADDRrr:$addr)]>;
\r
366 def STri : F3_2<3, 0b000100,
\r
367 (outs), (ins MEMri:$addr, IntRegs:$src),
\r
368 "st $src, [$addr]",
\r
369 [(store IntRegs:$src, ADDRri:$addr)]>;
\r
371 // Section B.5 - Store Floating-point Instructions, p. 97
\r
372 def STFrr : F3_1<3, 0b100100,
\r
373 (outs), (ins MEMrr:$addr, FPRegs:$src),
\r
374 "st $src, [$addr]",
\r
375 [(store FPRegs:$src, ADDRrr:$addr)]>;
\r
376 def STFri : F3_2<3, 0b100100,
\r
377 (outs), (ins MEMri:$addr, FPRegs:$src),
\r
378 "st $src, [$addr]",
\r
379 [(store FPRegs:$src, ADDRri:$addr)]>;
\r
380 def STDFrr : F3_1<3, 0b100111,
\r
381 (outs), (ins MEMrr:$addr, DFPRegs:$src),
\r
382 "std $src, [$addr]",
\r
383 [(store DFPRegs:$src, ADDRrr:$addr)]>;
\r
384 def STDFri : F3_2<3, 0b100111,
\r
385 (outs), (ins MEMri:$addr, DFPRegs:$src),
\r
386 "std $src, [$addr]",
\r
387 [(store DFPRegs:$src, ADDRri:$addr)]>;
\r
389 // Section B.9 - SETHI Instruction, p. 104
\r
390 def SETHIi: F2_1<0b100,
\r
391 (outs IntRegs:$dst), (ins i32imm:$src),
\r
392 "sethi $src, $dst",
\r
393 [(set IntRegs:$dst, SETHIimm:$src)]>;
\r
395 // Section B.10 - NOP Instruction, p. 105
\r
396 // (It's a special case of SETHI)
\r
397 let rd = 0, imm22 = 0 in
\r
398 def NOP : F2_1<0b100, (outs), (ins), "nop", []>;
\r
400 // Section B.11 - Logical Instructions, p. 106
\r
401 defm AND : F3_12<"and", 0b000001, and>;
\r
403 def ANDNrr : F3_1<2, 0b000101,
\r
404 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
\r
405 "andn $b, $c, $dst",
\r
406 [(set IntRegs:$dst, (and IntRegs:$b, (not IntRegs:$c)))]>;
\r
407 def ANDNri : F3_2<2, 0b000101,
\r
408 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
\r
409 "andn $b, $c, $dst", []>;
\r
411 defm OR : F3_12<"or", 0b000010, or>;
\r
413 def ORNrr : F3_1<2, 0b000110,
\r
414 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
\r
415 "orn $b, $c, $dst",
\r
416 [(set IntRegs:$dst, (or IntRegs:$b, (not IntRegs:$c)))]>;
\r
417 def ORNri : F3_2<2, 0b000110,
\r
418 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
\r
419 "orn $b, $c, $dst", []>;
\r
420 defm XOR : F3_12<"xor", 0b000011, xor>;
\r
422 def XNORrr : F3_1<2, 0b000111,
\r
423 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
\r
424 "xnor $b, $c, $dst",
\r
425 [(set IntRegs:$dst, (not (xor IntRegs:$b, IntRegs:$c)))]>;
\r
426 def XNORri : F3_2<2, 0b000111,
\r
427 (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
\r
428 "xnor $b, $c, $dst", []>;
\r
430 // Section B.12 - Shift Instructions, p. 107
\r
431 defm SLL : F3_12<"sll", 0b100101, shl>;
\r
432 defm SRL : F3_12<"srl", 0b100110, srl>;
\r
433 defm SRA : F3_12<"sra", 0b100111, sra>;
\r
435 // Section B.13 - Add Instructions, p. 108
\r
436 defm ADD : F3_12<"add", 0b000000, add>;
\r
438 // "LEA" forms of add (patterns to make tblgen happy)
\r
439 def LEA_ADDri : F3_2<2, 0b000000,
\r
440 (outs IntRegs:$dst), (ins MEMri:$addr),
\r
441 "add ${addr:arith}, $dst",
\r
442 [(set IntRegs:$dst, ADDRri:$addr)]>;
\r
444 let Defs = [ICC] in
\r
445 defm ADDCC : F3_12<"addcc", 0b010000, addc>;
\r
447 defm ADDX : F3_12<"addx", 0b001000, adde>;
\r
449 // Section B.15 - Subtract Instructions, p. 110
\r
450 defm SUB : F3_12 <"sub" , 0b000100, sub>;
\r
451 defm SUBX : F3_12 <"subx" , 0b001100, sube>;
\r
453 let Defs = [ICC] in {
\r
454 defm SUBCC : F3_12 <"subcc", 0b010100, SPcmpicc>;
\r
456 def SUBXCCrr: F3_1<2, 0b011100,
\r
457 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
\r
458 "subxcc $b, $c, $dst", []>;
\r
461 // Section B.18 - Multiply Instructions, p. 113
\r
462 defm UMUL : F3_12np<"umul", 0b001010>;
\r
463 defm SMUL : F3_12 <"smul", 0b001011, mul>;
\r
466 // Section B.19 - Divide Instructions, p. 115
\r
467 defm UDIV : F3_12np<"udiv", 0b001110>;
\r
468 defm SDIV : F3_12np<"sdiv", 0b001111>;
\r
470 // Section B.20 - SAVE and RESTORE, p. 117
\r
471 defm SAVE : F3_12np<"save" , 0b111100>;
\r
472 defm RESTORE : F3_12np<"restore", 0b111101>;
\r
474 // Section B.21 - Branch on Integer Condition Codes Instructions, p. 119
\r
476 // conditional branch class:
\r
477 class BranchSP<bits<4> cc, dag ins, string asmstr, list<dag> pattern>
\r
478 : F2_2<cc, 0b010, (outs), ins, asmstr, pattern> {
\r
480 let isTerminator = 1;
\r
481 let hasDelaySlot = 1;
\r
484 let isBarrier = 1 in
\r
485 def BA : BranchSP<0b1000, (ins brtarget:$dst),
\r
489 // FIXME: the encoding for the JIT should look at the condition field.
\r
490 let Uses = [ICC] in
\r
491 def BCOND : BranchSP<0, (ins brtarget:$dst, CCOp:$cc),
\r
493 [(SPbricc bb:$dst, imm:$cc)]>;
\r
496 // Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
\r
498 // floating-point conditional branch class:
\r
499 class FPBranchSP<bits<4> cc, dag ins, string asmstr, list<dag> pattern>
\r
500 : F2_2<cc, 0b110, (outs), ins, asmstr, pattern> {
\r
502 let isTerminator = 1;
\r
503 let hasDelaySlot = 1;
\r
506 // FIXME: the encoding for the JIT should look at the condition field.
\r
507 let Uses = [FCC] in
\r
508 def FBCOND : FPBranchSP<0, (ins brtarget:$dst, CCOp:$cc),
\r
510 [(SPbrfcc bb:$dst, imm:$cc)]>;
\r
513 // Section B.24 - Call and Link Instruction, p. 125
\r
514 // This is the only Format 1 instruction
\r
515 let Uses = [O0, O1, O2, O3, O4, O5],
\r
516 hasDelaySlot = 1, isCall = 1,
\r
517 Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
\r
518 D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in {
\r
519 def CALL : InstSP<(outs), (ins calltarget:$dst),
\r
523 let Inst{29-0} = disp;
\r
527 def JMPLrr : F3_1<2, 0b111000,
\r
528 (outs), (ins MEMrr:$ptr),
\r
530 [(call ADDRrr:$ptr)]>;
\r
531 def JMPLri : F3_2<2, 0b111000,
\r
532 (outs), (ins MEMri:$ptr),
\r
534 [(call ADDRri:$ptr)]>;
\r
537 // Section B.28 - Read State Register Instructions
\r
538 def RDY : F3_1<2, 0b101000,
\r
539 (outs IntRegs:$dst), (ins),
\r
540 "rd %y, $dst", []>;
\r
542 // Section B.29 - Write State Register Instructions
\r
543 def WRYrr : F3_1<2, 0b110000,
\r
544 (outs), (ins IntRegs:$b, IntRegs:$c),
\r
545 "wr $b, $c, %y", []>;
\r
546 def WRYri : F3_2<2, 0b110000,
\r
547 (outs), (ins IntRegs:$b, i32imm:$c),
\r
548 "wr $b, $c, %y", []>;
\r
550 // Convert Integer to Floating-point Instructions, p. 141
\r
551 def FITOS : F3_3<2, 0b110100, 0b011000100,
\r
552 (outs FPRegs:$dst), (ins FPRegs:$src),
\r
553 "fitos $src, $dst",
\r
554 [(set FPRegs:$dst, (SPitof FPRegs:$src))]>;
\r
555 def FITOD : F3_3<2, 0b110100, 0b011001000,
\r
556 (outs DFPRegs:$dst), (ins FPRegs:$src),
\r
557 "fitod $src, $dst",
\r
558 [(set DFPRegs:$dst, (SPitof FPRegs:$src))]>;
\r
560 // Convert Floating-point to Integer Instructions, p. 142
\r
561 def FSTOI : F3_3<2, 0b110100, 0b011010001,
\r
562 (outs FPRegs:$dst), (ins FPRegs:$src),
\r
563 "fstoi $src, $dst",
\r
564 [(set FPRegs:$dst, (SPftoi FPRegs:$src))]>;
\r
565 def FDTOI : F3_3<2, 0b110100, 0b011010010,
\r
566 (outs FPRegs:$dst), (ins DFPRegs:$src),
\r
567 "fdtoi $src, $dst",
\r
568 [(set FPRegs:$dst, (SPftoi DFPRegs:$src))]>;
\r
570 // Convert between Floating-point Formats Instructions, p. 143
\r
571 def FSTOD : F3_3<2, 0b110100, 0b011001001,
\r
572 (outs DFPRegs:$dst), (ins FPRegs:$src),
\r
573 "fstod $src, $dst",
\r
574 [(set DFPRegs:$dst, (fextend FPRegs:$src))]>;
\r
575 def FDTOS : F3_3<2, 0b110100, 0b011000110,
\r
576 (outs FPRegs:$dst), (ins DFPRegs:$src),
\r
577 "fdtos $src, $dst",
\r
578 [(set FPRegs:$dst, (fround DFPRegs:$src))]>;
\r
580 // Floating-point Move Instructions, p. 144
\r
581 def FMOVS : F3_3<2, 0b110100, 0b000000001,
\r
582 (outs FPRegs:$dst), (ins FPRegs:$src),
\r
583 "fmovs $src, $dst", []>;
\r
584 def FNEGS : F3_3<2, 0b110100, 0b000000101,
\r
585 (outs FPRegs:$dst), (ins FPRegs:$src),
\r
586 "fnegs $src, $dst",
\r
587 [(set FPRegs:$dst, (fneg FPRegs:$src))]>;
\r
588 def FABSS : F3_3<2, 0b110100, 0b000001001,
\r
589 (outs FPRegs:$dst), (ins FPRegs:$src),
\r
590 "fabss $src, $dst",
\r
591 [(set FPRegs:$dst, (fabs FPRegs:$src))]>;
\r
594 // Floating-point Square Root Instructions, p.145
\r
595 def FSQRTS : F3_3<2, 0b110100, 0b000101001,
\r
596 (outs FPRegs:$dst), (ins FPRegs:$src),
\r
597 "fsqrts $src, $dst",
\r
598 [(set FPRegs:$dst, (fsqrt FPRegs:$src))]>;
\r
599 def FSQRTD : F3_3<2, 0b110100, 0b000101010,
\r
600 (outs DFPRegs:$dst), (ins DFPRegs:$src),
\r
601 "fsqrtd $src, $dst",
\r
602 [(set DFPRegs:$dst, (fsqrt DFPRegs:$src))]>;
\r
606 // Floating-point Add and Subtract Instructions, p. 146
\r
607 def FADDS : F3_3<2, 0b110100, 0b001000001,
\r
608 (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2),
\r
609 "fadds $src1, $src2, $dst",
\r
610 [(set FPRegs:$dst, (fadd FPRegs:$src1, FPRegs:$src2))]>;
\r
611 def FADDD : F3_3<2, 0b110100, 0b001000010,
\r
612 (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2),
\r
613 "faddd $src1, $src2, $dst",
\r
614 [(set DFPRegs:$dst, (fadd DFPRegs:$src1, DFPRegs:$src2))]>;
\r
615 def FSUBS : F3_3<2, 0b110100, 0b001000101,
\r
616 (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2),
\r
617 "fsubs $src1, $src2, $dst",
\r
618 [(set FPRegs:$dst, (fsub FPRegs:$src1, FPRegs:$src2))]>;
\r
619 def FSUBD : F3_3<2, 0b110100, 0b001000110,
\r
620 (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2),
\r
621 "fsubd $src1, $src2, $dst",
\r
622 [(set DFPRegs:$dst, (fsub DFPRegs:$src1, DFPRegs:$src2))]>;
\r
624 // Floating-point Multiply and Divide Instructions, p. 147
\r
625 def FMULS : F3_3<2, 0b110100, 0b001001001,
\r
626 (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2),
\r
627 "fmuls $src1, $src2, $dst",
\r
628 [(set FPRegs:$dst, (fmul FPRegs:$src1, FPRegs:$src2))]>;
\r
629 def FMULD : F3_3<2, 0b110100, 0b001001010,
\r
630 (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2),
\r
631 "fmuld $src1, $src2, $dst",
\r
632 [(set DFPRegs:$dst, (fmul DFPRegs:$src1, DFPRegs:$src2))]>;
\r
633 def FSMULD : F3_3<2, 0b110100, 0b001101001,
\r
634 (outs DFPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2),
\r
635 "fsmuld $src1, $src2, $dst",
\r
636 [(set DFPRegs:$dst, (fmul (fextend FPRegs:$src1),
\r
637 (fextend FPRegs:$src2)))]>;
\r
638 def FDIVS : F3_3<2, 0b110100, 0b001001101,
\r
639 (outs FPRegs:$dst), (ins FPRegs:$src1, FPRegs:$src2),
\r
640 "fdivs $src1, $src2, $dst",
\r
641 [(set FPRegs:$dst, (fdiv FPRegs:$src1, FPRegs:$src2))]>;
\r
642 def FDIVD : F3_3<2, 0b110100, 0b001001110,
\r
643 (outs DFPRegs:$dst), (ins DFPRegs:$src1, DFPRegs:$src2),
\r
644 "fdivd $src1, $src2, $dst",
\r
645 [(set DFPRegs:$dst, (fdiv DFPRegs:$src1, DFPRegs:$src2))]>;
\r
647 // Floating-point Compare Instructions, p. 148
\r
648 // Note: the 2nd template arg is different for these guys.
\r
649 // Note 2: the result of a FCMP is not available until the 2nd cycle
\r
650 // after the instr is retired, but there is no interlock. This behavior
\r
651 // is modelled with a forced noop after the instruction.
\r
652 let Defs = [FCC] in {
\r
653 def FCMPS : F3_3<2, 0b110101, 0b001010001,
\r
654 (outs), (ins FPRegs:$src1, FPRegs:$src2),
\r
655 "fcmps $src1, $src2\n\tnop",
\r
656 [(SPcmpfcc FPRegs:$src1, FPRegs:$src2)]>;
\r
657 def FCMPD : F3_3<2, 0b110101, 0b001010010,
\r
658 (outs), (ins DFPRegs:$src1, DFPRegs:$src2),
\r
659 "fcmpd $src1, $src2\n\tnop",
\r
660 [(SPcmpfcc DFPRegs:$src1, DFPRegs:$src2)]>;
\r
663 //===----------------------------------------------------------------------===//
\r
665 //===----------------------------------------------------------------------===//
\r
667 // V9 Conditional Moves.
\r
668 let Predicates = [HasV9], Constraints = "$T = $dst" in {
\r
669 // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual.
\r
670 // FIXME: Add instruction encodings for the JIT some day.
\r
672 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, CCOp:$cc),
\r
673 "mov$cc %icc, $F, $dst",
\r
674 [(set IntRegs:$dst,
\r
675 (SPselecticc IntRegs:$F, IntRegs:$T, imm:$cc))]>;
\r
677 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, i32imm:$F, CCOp:$cc),
\r
678 "mov$cc %icc, $F, $dst",
\r
679 [(set IntRegs:$dst,
\r
680 (SPselecticc simm11:$F, IntRegs:$T, imm:$cc))]>;
\r
683 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, CCOp:$cc),
\r
684 "mov$cc %fcc0, $F, $dst",
\r
685 [(set IntRegs:$dst,
\r
686 (SPselectfcc IntRegs:$F, IntRegs:$T, imm:$cc))]>;
\r
688 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, i32imm:$F, CCOp:$cc),
\r
689 "mov$cc %fcc0, $F, $dst",
\r
690 [(set IntRegs:$dst,
\r
691 (SPselectfcc simm11:$F, IntRegs:$T, imm:$cc))]>;
\r
694 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, CCOp:$cc),
\r
695 "fmovs$cc %icc, $F, $dst",
\r
697 (SPselecticc FPRegs:$F, FPRegs:$T, imm:$cc))]>;
\r
699 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, CCOp:$cc),
\r
700 "fmovd$cc %icc, $F, $dst",
\r
701 [(set DFPRegs:$dst,
\r
702 (SPselecticc DFPRegs:$F, DFPRegs:$T, imm:$cc))]>;
\r
704 : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, CCOp:$cc),
\r
705 "fmovs$cc %fcc0, $F, $dst",
\r
707 (SPselectfcc FPRegs:$F, FPRegs:$T, imm:$cc))]>;
\r
709 : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$T, DFPRegs:$F, CCOp:$cc),
\r
710 "fmovd$cc %fcc0, $F, $dst",
\r
711 [(set DFPRegs:$dst,
\r
712 (SPselectfcc DFPRegs:$F, DFPRegs:$T, imm:$cc))]>;
\r
716 // Floating-Point Move Instructions, p. 164 of the V9 manual.
\r
717 let Predicates = [HasV9] in {
\r
718 def FMOVD : F3_3<2, 0b110100, 0b000000010,
\r
719 (outs DFPRegs:$dst), (ins DFPRegs:$src),
\r
720 "fmovd $src, $dst", []>;
\r
721 def FNEGD : F3_3<2, 0b110100, 0b000000110,
\r
722 (outs DFPRegs:$dst), (ins DFPRegs:$src),
\r
723 "fnegd $src, $dst",
\r
724 [(set DFPRegs:$dst, (fneg DFPRegs:$src))]>;
\r
725 def FABSD : F3_3<2, 0b110100, 0b000001010,
\r
726 (outs DFPRegs:$dst), (ins DFPRegs:$src),
\r
727 "fabsd $src, $dst",
\r
728 [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>;
\r
731 // POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear
\r
732 // the top 32-bits before using it. To do this clearing, we use a SLLri X,0.
\r
733 def POPCrr : F3_1<2, 0b101110,
\r
734 (outs IntRegs:$dst), (ins IntRegs:$src),
\r
735 "popc $src, $dst", []>, Requires<[HasV9]>;
\r
736 def : Pat<(ctpop IntRegs:$src),
\r
737 (POPCrr (SLLri IntRegs:$src, 0))>;
\r
739 //===----------------------------------------------------------------------===//
\r
740 // Non-Instruction Patterns
\r
741 //===----------------------------------------------------------------------===//
\r
743 // Small immediates.
\r
744 def : Pat<(i32 simm13:$val),
\r
745 (ORri G0, imm:$val)>;
\r
746 // Arbitrary immediates.
\r
747 def : Pat<(i32 imm:$val),
\r
748 (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;
\r
751 def : Pat<(subc IntRegs:$b, IntRegs:$c),
\r
752 (SUBCCrr IntRegs:$b, IntRegs:$c)>;
\r
753 def : Pat<(subc IntRegs:$b, simm13:$val),
\r
754 (SUBCCri IntRegs:$b, imm:$val)>;
\r
756 // Global addresses, constant pool entries
\r
757 def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>;
\r
758 def : Pat<(SPlo tglobaladdr:$in), (ORri G0, tglobaladdr:$in)>;
\r
759 def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>;
\r
760 def : Pat<(SPlo tconstpool:$in), (ORri G0, tconstpool:$in)>;
\r
762 // Add reg, lo. This is used when taking the addr of a global/constpool entry.
\r
763 def : Pat<(add IntRegs:$r, (SPlo tglobaladdr:$in)),
\r
764 (ADDri IntRegs:$r, tglobaladdr:$in)>;
\r
765 def : Pat<(add IntRegs:$r, (SPlo tconstpool:$in)),
\r
766 (ADDri IntRegs:$r, tconstpool:$in)>;
\r
769 def : Pat<(call tglobaladdr:$dst),
\r
770 (CALL tglobaladdr:$dst)>;
\r
771 def : Pat<(call texternalsym:$dst),
\r
772 (CALL texternalsym:$dst)>;
\r
774 // Map integer extload's to zextloads.
\r
775 def : Pat<(i32 (extloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>;
\r
776 def : Pat<(i32 (extloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>;
\r
777 def : Pat<(i32 (extloadi8 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>;
\r
778 def : Pat<(i32 (extloadi8 ADDRri:$src)), (LDUBri ADDRri:$src)>;
\r
779 def : Pat<(i32 (extloadi16 ADDRrr:$src)), (LDUHrr ADDRrr:$src)>;
\r
780 def : Pat<(i32 (extloadi16 ADDRri:$src)), (LDUHri ADDRri:$src)>;
\r
782 // zextload bool -> zextload byte
\r
783 def : Pat<(i32 (zextloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>;
\r
784 def : Pat<(i32 (zextloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>;
\r