OSDN Git Service

Add SwiftShader source to repo
[android-x86/external-swiftshader.git] / src / LLVM / lib / Target / Sparc / SparcInstrInfo.td
1 //===- SparcInstrInfo.td - Target Description for Sparc Target ------------===//\r
2 // \r
3 //                     The LLVM Compiler Infrastructure\r
4 //\r
5 // This file is distributed under the University of Illinois Open Source\r
6 // License. See LICENSE.TXT for details.\r
7 // \r
8 //===----------------------------------------------------------------------===//\r
9 //\r
10 // This file describes the Sparc instructions in TableGen format.\r
11 //\r
12 //===----------------------------------------------------------------------===//\r
13 \r
14 //===----------------------------------------------------------------------===//\r
15 // Instruction format superclass\r
16 //===----------------------------------------------------------------------===//\r
17 \r
18 include "SparcInstrFormats.td"\r
19 \r
20 //===----------------------------------------------------------------------===//\r
21 // Feature predicates.\r
22 //===----------------------------------------------------------------------===//\r
23 \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
27 \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
32 \r
33 // HasVIS - This is true when the target processor has VIS extensions.\r
34 def HasVIS : Predicate<"Subtarget.isVIS()">;\r
35 \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
41 \r
42 //===----------------------------------------------------------------------===//\r
43 // Instruction Pattern Stuff\r
44 //===----------------------------------------------------------------------===//\r
45 \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
50 }]>;\r
51 \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
56 }]>;\r
57 \r
58 def LO10 : SDNodeXForm<imm, [{\r
59   return CurDAG->getTargetConstant((unsigned)N->getZExtValue() & 1023,\r
60                                    MVT::i32);\r
61 }]>;\r
62 \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
66 }]>;\r
67 \r
68 def SETHIimm : PatLeaf<(imm), [{\r
69   return (((unsigned)N->getZExtValue() >> 10) << 10) ==\r
70          (unsigned)N->getZExtValue();\r
71 }], HI22>;\r
72 \r
73 // Addressing modes.\r
74 def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;\r
75 def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex], []>;\r
76 \r
77 // Address operands\r
78 def MEMrr : Operand<i32> {\r
79   let PrintMethod = "printMemOperand";\r
80   let MIOperandInfo = (ops IntRegs, IntRegs);\r
81 }\r
82 def MEMri : Operand<i32> {\r
83   let PrintMethod = "printMemOperand";\r
84   let MIOperandInfo = (ops IntRegs, i32imm);\r
85 }\r
86 \r
87 // Branch targets have OtherVT type.\r
88 def brtarget : Operand<OtherVT>;\r
89 def calltarget : Operand<i32>;\r
90 \r
91 // Operand for printing out a condition code.\r
92 let PrintMethod = "printCCOperand" in\r
93   def CCOp : Operand<i32>;\r
94 \r
95 def SDTSPcmpfcc : \r
96 SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisSameAs<0, 1>]>;\r
97 def SDTSPbrcc : \r
98 SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;\r
99 def SDTSPselectcc :\r
100 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>]>;\r
101 def SDTSPFTOI :\r
102 SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;\r
103 def SDTSPITOF :\r
104 SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;\r
105 \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
110 \r
111 def SPhi    : SDNode<"SPISD::Hi", SDTIntUnaryOp>;\r
112 def SPlo    : SDNode<"SPISD::Lo", SDTIntUnaryOp>;\r
113 \r
114 def SPftoi  : SDNode<"SPISD::FTOI", SDTSPFTOI>;\r
115 def SPitof  : SDNode<"SPISD::ITOF", SDTSPITOF>;\r
116 \r
117 def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInFlag]>;\r
118 def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInFlag]>;\r
119 \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
124 \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
129 \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
133 \r
134 def retflag       : SDNode<"SPISD::RET_FLAG", SDTNone,\r
135                            [SDNPHasChain, SDNPOptInFlag]>;\r
136 \r
137 def getPCX        : Operand<i32> {\r
138   let PrintMethod = "printGetPCX";\r
139 }  \r
140 \r
141 //===----------------------------------------------------------------------===//\r
142 // SPARC Flag Conditions\r
143 //===----------------------------------------------------------------------===//\r
144 \r
145 // Note that these values must be kept in sync with the CCOp::CondCode enum\r
146 // values.\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
162 \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
178 \r
179 //===----------------------------------------------------------------------===//\r
180 // Instruction Class Templates\r
181 //===----------------------------------------------------------------------===//\r
182 \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
193 }\r
194 \r
195 /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no\r
196 /// pattern.\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
204 }\r
205 \r
206 //===----------------------------------------------------------------------===//\r
207 // Instructions\r
208 //===----------------------------------------------------------------------===//\r
209 \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
213 \r
214 // GETPCX for PIC\r
215 let Defs = [O7], Uses = [O7] in {\r
216   def GETPCX : Pseudo<(outs getPCX:$getpcseq), (ins), "$getpcseq", [] >;\r
217 }\r
218 \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
226 }\r
227 \r
228 // FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the \r
229 // fpmover pass.\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
239 }\r
240 \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
249                                              imm:$Cond))]>;\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
254                                              imm:$Cond))]>;\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
259                                             imm:$Cond))]>;\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
264                                             imm:$Cond))]>;\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
269                                              imm:$Cond))]>;\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
274                                              imm:$Cond))]>;\r
275 }\r
276 \r
277 \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
283 }\r
284 \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
326 \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
344 \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
370 \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
388 \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
394 \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
399 \r
400 // Section B.11 - Logical Instructions, p. 106\r
401 defm AND    : F3_12<"and", 0b000001, and>;\r
402 \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
410 \r
411 defm OR     : F3_12<"or", 0b000010, or>;\r
412 \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
421 \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
429 \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
434 \r
435 // Section B.13 - Add Instructions, p. 108\r
436 defm ADD   : F3_12<"add", 0b000000, add>;\r
437 \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
443 \r
444 let Defs = [ICC] in                   \r
445   defm ADDCC  : F3_12<"addcc", 0b010000, addc>;\r
446 \r
447 defm ADDX  : F3_12<"addx", 0b001000, adde>;\r
448 \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
452 \r
453 let Defs = [ICC] in {\r
454   defm SUBCC  : F3_12  <"subcc", 0b010100, SPcmpicc>;\r
455 \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
459 }\r
460 \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
464 \r
465 \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
469 \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
473 \r
474 // Section B.21 - Branch on Integer Condition Codes Instructions, p. 119\r
475 \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
479   let isBranch = 1;\r
480   let isTerminator = 1;\r
481   let hasDelaySlot = 1;\r
482 }\r
483 \r
484 let isBarrier = 1 in\r
485   def BA   : BranchSP<0b1000, (ins brtarget:$dst),\r
486                       "ba $dst",\r
487                       [(br bb:$dst)]>;\r
488 \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
492                          "b$cc $dst",\r
493                         [(SPbricc bb:$dst, imm:$cc)]>;\r
494 \r
495 \r
496 // Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121\r
497 \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
501   let isBranch = 1;\r
502   let isTerminator = 1;\r
503   let hasDelaySlot = 1;\r
504 }\r
505 \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
509                               "fb$cc $dst",\r
510                               [(SPbrfcc bb:$dst, imm:$cc)]>;\r
511 \r
512 \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
520                     "call $dst", []> {\r
521     bits<30> disp;\r
522     let op = 1;\r
523     let Inst{29-0} = disp;\r
524   }\r
525   \r
526   // indirect calls\r
527   def JMPLrr : F3_1<2, 0b111000,\r
528                     (outs), (ins MEMrr:$ptr),\r
529                     "call $ptr",\r
530                     [(call ADDRrr:$ptr)]>;\r
531   def JMPLri : F3_2<2, 0b111000,\r
532                     (outs), (ins MEMri:$ptr),\r
533                     "call $ptr",\r
534                     [(call ADDRri:$ptr)]>;\r
535 }\r
536 \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
541 \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
549 \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
559 \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
569 \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
579 \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
592 \r
593 \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
603 \r
604 \r
605 \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
623 \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
646 \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
661 }\r
662 \r
663 //===----------------------------------------------------------------------===//\r
664 // V9 Instructions\r
665 //===----------------------------------------------------------------------===//\r
666 \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
671   def MOVICCrr\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
676   def MOVICCri\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
681 \r
682   def MOVFCCrr\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
687   def MOVFCCri\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
692 \r
693   def FMOVS_ICC\r
694     : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, CCOp:$cc),\r
695              "fmovs$cc %icc, $F, $dst",\r
696              [(set FPRegs:$dst,\r
697                          (SPselecticc FPRegs:$F, FPRegs:$T, imm:$cc))]>;\r
698   def FMOVD_ICC\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
703   def FMOVS_FCC\r
704     : Pseudo<(outs FPRegs:$dst), (ins FPRegs:$T, FPRegs:$F, CCOp:$cc),\r
705              "fmovs$cc %fcc0, $F, $dst",\r
706              [(set FPRegs:$dst,\r
707                          (SPselectfcc FPRegs:$F, FPRegs:$T, imm:$cc))]>;\r
708   def FMOVD_FCC\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
713 \r
714 }\r
715 \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
729 }\r
730 \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
738 \r
739 //===----------------------------------------------------------------------===//\r
740 // Non-Instruction Patterns\r
741 //===----------------------------------------------------------------------===//\r
742 \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
749 \r
750 // subc\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
755 \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
761 \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
767 \r
768 // Calls: \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
773 \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
781 \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