When in v9 mode, emit fabsd/fnegd/fmovd
[oota-llvm.git] / lib / Target / Sparc / SparcInstrInfo.td
1 //===- SparcV8Instrs.td - Target Description for SparcV8 Target -----------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the SparcV8 instructions in TableGen format.
11 //
12 //===----------------------------------------------------------------------===//
13
14 //===----------------------------------------------------------------------===//
15 // Instruction format superclass
16 //===----------------------------------------------------------------------===//
17
18 include "SparcV8InstrFormats.td"
19
20 //===----------------------------------------------------------------------===//
21 // Feature predicates.
22 //===----------------------------------------------------------------------===//
23
24 // HasV9 - This predicate is true when the target processor supports V9
25 // instructions.  Note that the machine may be running in 32-bit mode.
26 def HasV9   : Predicate<"Subtarget.isV9()">;
27
28 // HasNoV9 - This predicate is true when the target doesn't have V9
29 // instructions.  Use of this is just a hack for the isel not having proper
30 // costs for V8 instructions that are more expensive than their V9 ones.
31 def HasNoV9 : Predicate<"!Subtarget.isV9()">;
32
33 // HasVIS - This is true when the target processor has VIS extensions.
34 def HasVIS : Predicate<"Subtarget.isVIS()">;
35
36 // UseDeprecatedInsts - This predicate is true when the target processor is a
37 // V8, or when it is V9 but the V8 deprecated instructions are efficient enough
38 // to use when appropriate.  In either of these cases, the instruction selector
39 // will pick deprecated instructions.
40 def UseDeprecatedInsts : Predicate<"Subtarget.useDeprecatedV8Instructions()">;
41
42 //===----------------------------------------------------------------------===//
43 // Instruction Pattern Stuff
44 //===----------------------------------------------------------------------===//
45
46 def simm13  : PatLeaf<(imm), [{
47   // simm13 predicate - True if the imm fits in a 13-bit sign extended field.
48   return (((int)N->getValue() << (32-13)) >> (32-13)) == (int)N->getValue();
49 }]>;
50
51 def LO10 : SDNodeXForm<imm, [{
52   return CurDAG->getTargetConstant((unsigned)N->getValue() & 1023, MVT::i32);
53 }]>;
54
55 def HI22 : SDNodeXForm<imm, [{
56   // Transformation function: shift the immediate value down into the low bits.
57   return CurDAG->getTargetConstant((unsigned)N->getValue() >> 10, MVT::i32);
58 }]>;
59
60 def SETHIimm : PatLeaf<(imm), [{
61   return (((unsigned)N->getValue() >> 10) << 10) == (unsigned)N->getValue();
62 }], HI22>;
63
64 // Addressing modes.
65 def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", []>;
66 def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", []>;
67
68 // Address operands
69 def MEMrr : Operand<i32> {
70   let PrintMethod = "printMemOperand";
71   let NumMIOperands = 2;
72   let MIOperandInfo = (ops IntRegs, IntRegs);
73 }
74 def MEMri : Operand<i32> {
75   let PrintMethod = "printMemOperand";
76   let NumMIOperands = 2;
77   let MIOperandInfo = (ops IntRegs, i32imm);
78 }
79
80 // Branch targets have OtherVT type.
81 def brtarget : Operand<OtherVT>;
82 def calltarget : Operand<i32>;
83
84 def SDTV8cmpfcc : 
85 SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>;
86 def SDTV8brcc : 
87 SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, SDTCisVT<1, OtherVT>,
88                      SDTCisVT<2, FlagVT>]>;
89 def SDTV8selectcc :
90 SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 
91                      SDTCisVT<3, i32>, SDTCisVT<4, FlagVT>]>;
92 def SDTV8FTOI :
93 SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;
94 def SDTV8ITOF :
95 SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
96
97 def V8cmpicc : SDNode<"V8ISD::CMPICC", SDTIntBinOp, [SDNPOutFlag]>;
98 def V8cmpfcc : SDNode<"V8ISD::CMPFCC", SDTV8cmpfcc, [SDNPOutFlag]>;
99 def V8bricc : SDNode<"V8ISD::BRICC", SDTV8brcc, [SDNPHasChain]>;
100 def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>;
101
102 def V8hi    : SDNode<"V8ISD::Hi", SDTIntUnaryOp>;
103 def V8lo    : SDNode<"V8ISD::Lo", SDTIntUnaryOp>;
104
105 def V8ftoi  : SDNode<"V8ISD::FTOI", SDTV8FTOI>;
106 def V8itof  : SDNode<"V8ISD::ITOF", SDTV8ITOF>;
107
108 def V8selecticc : SDNode<"V8ISD::SELECT_ICC", SDTV8selectcc>;
109 def V8selectfcc : SDNode<"V8ISD::SELECT_FCC", SDTV8selectcc>;
110
111 // These are target-independent nodes, but have target-specific formats.
112 def SDT_V8CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
113 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_V8CallSeq, [SDNPHasChain]>;
114 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_V8CallSeq, [SDNPHasChain]>;
115
116 def SDT_V8Call    : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
117 def call          : SDNode<"V8ISD::CALL", SDT_V8Call,
118                            [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
119
120 def SDT_V8RetFlag : SDTypeProfile<0, 0, []>;
121 def retflag       : SDNode<"V8ISD::RET_FLAG", SDT_V8RetFlag,
122                            [SDNPHasChain, SDNPOptInFlag]>;
123
124 //===----------------------------------------------------------------------===//
125 // Instructions
126 //===----------------------------------------------------------------------===//
127
128 // Pseudo instructions.
129 class Pseudo<dag ops, string asmstr, list<dag> pattern>
130    : InstV8<ops, asmstr, pattern>;
131
132 def ADJCALLSTACKDOWN : Pseudo<(ops i32imm:$amt),
133                                "!ADJCALLSTACKDOWN $amt",
134                                [(callseq_start imm:$amt)]>;
135 def ADJCALLSTACKUP : Pseudo<(ops i32imm:$amt),
136                             "!ADJCALLSTACKUP $amt",
137                             [(callseq_end imm:$amt)]>;
138 def IMPLICIT_DEF_Int : Pseudo<(ops IntRegs:$dst),
139                               "!IMPLICIT_DEF $dst",
140                               [(set IntRegs:$dst, (undef))]>;
141 def IMPLICIT_DEF_FP  : Pseudo<(ops FPRegs:$dst), "!IMPLICIT_DEF $dst",
142                               [(set FPRegs:$dst, (undef))]>;
143 def IMPLICIT_DEF_DFP : Pseudo<(ops DFPRegs:$dst), "!IMPLICIT_DEF $dst",
144                               [(set DFPRegs:$dst, (undef))]>;
145                               
146 // FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the 
147 // fpmover pass.
148 let Predicates = [HasNoV9] in {  // Only emit these in V8 mode.
149   def FpMOVD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src),
150                       "!FpMOVD $src, $dst", []>;
151   def FpNEGD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src),
152                       "!FpNEGD $src, $dst",
153                       [(set DFPRegs:$dst, (fneg DFPRegs:$src))]>;
154   def FpABSD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src),
155                       "!FpABSD $src, $dst",
156                       [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>;
157 }
158
159 // SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded by the
160 // scheduler into a branch sequence.  This has to handle all permutations of
161 // selection between i32/f32/f64 on ICC and FCC.
162 let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
163   def SELECT_CC_Int_ICC
164    : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond),
165             "; SELECT_CC_Int_ICC PSEUDO!",
166             [(set IntRegs:$dst, (V8selecticc IntRegs:$T, IntRegs:$F,
167                                              imm:$Cond, ICC))]>;
168   def SELECT_CC_Int_FCC
169    : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond),
170             "; SELECT_CC_Int_FCC PSEUDO!",
171             [(set IntRegs:$dst, (V8selectfcc IntRegs:$T, IntRegs:$F,
172                                              imm:$Cond, FCC))]>;
173   def SELECT_CC_FP_ICC
174    : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond),
175             "; SELECT_CC_FP_ICC PSEUDO!",
176             [(set FPRegs:$dst, (V8selecticc FPRegs:$T, FPRegs:$F,
177                                             imm:$Cond, ICC))]>;
178   def SELECT_CC_FP_FCC
179    : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond),
180             "; SELECT_CC_FP_FCC PSEUDO!",
181             [(set FPRegs:$dst, (V8selectfcc FPRegs:$T, FPRegs:$F,
182                                             imm:$Cond, FCC))]>;
183   def SELECT_CC_DFP_ICC
184    : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, i32imm:$Cond),
185             "; SELECT_CC_DFP_ICC PSEUDO!",
186             [(set DFPRegs:$dst, (V8selecticc DFPRegs:$T, DFPRegs:$F,
187                                              imm:$Cond, ICC))]>;
188   def SELECT_CC_DFP_FCC
189    : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, i32imm:$Cond),
190             "; SELECT_CC_DFP_FCC PSEUDO!",
191             [(set DFPRegs:$dst, (V8selectfcc DFPRegs:$T, DFPRegs:$F,
192                                              imm:$Cond, FCC))]>;
193 }
194
195
196 // Section A.3 - Synthetic Instructions, p. 85
197 // special cases of JMPL:
198 let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, noResults = 1 in {
199   let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
200     def RETL: F3_2<2, 0b111000, (ops), "retl", [(retflag)]>;
201 }
202
203 // Section B.1 - Load Integer Instructions, p. 90
204 def LDSBrr : F3_1<3, 0b001001,
205                   (ops IntRegs:$dst, MEMrr:$addr),
206                   "ldsb [$addr], $dst",
207                   [(set IntRegs:$dst, (sextload ADDRrr:$addr, i8))]>;
208 def LDSBri : F3_2<3, 0b001001,
209                   (ops IntRegs:$dst, MEMri:$addr),
210                   "ldsb [$addr], $dst",
211                   [(set IntRegs:$dst, (sextload ADDRri:$addr, i8))]>;
212 def LDSHrr : F3_1<3, 0b001010,
213                   (ops IntRegs:$dst, MEMrr:$addr),
214                   "ldsh [$addr], $dst",
215                   [(set IntRegs:$dst, (sextload ADDRrr:$addr, i16))]>;
216 def LDSHri : F3_2<3, 0b001010,
217                   (ops IntRegs:$dst, MEMri:$addr),
218                   "ldsh [$addr], $dst",
219                   [(set IntRegs:$dst, (sextload ADDRri:$addr, i16))]>;
220 def LDUBrr : F3_1<3, 0b000001,
221                   (ops IntRegs:$dst, MEMrr:$addr),
222                   "ldub [$addr], $dst",
223                   [(set IntRegs:$dst, (zextload ADDRrr:$addr, i8))]>;
224 def LDUBri : F3_2<3, 0b000001,
225                   (ops IntRegs:$dst, MEMri:$addr),
226                   "ldub [$addr], $dst",
227                   [(set IntRegs:$dst, (zextload ADDRri:$addr, i8))]>;
228 def LDUHrr : F3_1<3, 0b000010,
229                   (ops IntRegs:$dst, MEMrr:$addr),
230                   "lduh [$addr], $dst",
231                   [(set IntRegs:$dst, (zextload ADDRrr:$addr, i16))]>;
232 def LDUHri : F3_2<3, 0b000010,
233                   (ops IntRegs:$dst, MEMri:$addr),
234                   "lduh [$addr], $dst",
235                   [(set IntRegs:$dst, (zextload ADDRri:$addr, i16))]>;
236 def LDrr   : F3_1<3, 0b000000,
237                   (ops IntRegs:$dst, MEMrr:$addr),
238                   "ld [$addr], $dst",
239                   [(set IntRegs:$dst, (load ADDRrr:$addr))]>;
240 def LDri   : F3_2<3, 0b000000,
241                   (ops IntRegs:$dst, MEMri:$addr),
242                   "ld [$addr], $dst",
243                   [(set IntRegs:$dst, (load ADDRri:$addr))]>;
244
245 // Section B.2 - Load Floating-point Instructions, p. 92
246 def LDFrr  : F3_1<3, 0b100000,
247                   (ops FPRegs:$dst, MEMrr:$addr),
248                   "ld [$addr], $dst",
249                   [(set FPRegs:$dst, (load ADDRrr:$addr))]>;
250 def LDFri  : F3_2<3, 0b100000,
251                   (ops FPRegs:$dst, MEMri:$addr),
252                   "ld [$addr], $dst",
253                   [(set FPRegs:$dst, (load ADDRri:$addr))]>;
254 def LDDFrr : F3_1<3, 0b100011,
255                   (ops DFPRegs:$dst, MEMrr:$addr),
256                   "ldd [$addr], $dst",
257                   [(set DFPRegs:$dst, (load ADDRrr:$addr))]>;
258 def LDDFri : F3_2<3, 0b100011,
259                   (ops DFPRegs:$dst, MEMri:$addr),
260                   "ldd [$addr], $dst",
261                   [(set DFPRegs:$dst, (load ADDRri:$addr))]>;
262
263 // Section B.4 - Store Integer Instructions, p. 95
264 def STBrr : F3_1<3, 0b000101,
265                  (ops MEMrr:$addr, IntRegs:$src),
266                  "stb $src, [$addr]",
267                  [(truncstore IntRegs:$src, ADDRrr:$addr, i8)]>;
268 def STBri : F3_2<3, 0b000101,
269                  (ops MEMri:$addr, IntRegs:$src),
270                  "stb $src, [$addr]",
271                  [(truncstore IntRegs:$src, ADDRri:$addr, i8)]>;
272 def STHrr : F3_1<3, 0b000110,
273                  (ops MEMrr:$addr, IntRegs:$src),
274                  "sth $src, [$addr]",
275                  [(truncstore IntRegs:$src, ADDRrr:$addr, i16)]>;
276 def STHri : F3_2<3, 0b000110,
277                  (ops MEMri:$addr, IntRegs:$src),
278                  "sth $src, [$addr]",
279                  [(truncstore IntRegs:$src, ADDRri:$addr, i16)]>;
280 def STrr  : F3_1<3, 0b000100,
281                  (ops MEMrr:$addr, IntRegs:$src),
282                  "st $src, [$addr]",
283                  [(store IntRegs:$src, ADDRrr:$addr)]>;
284 def STri  : F3_2<3, 0b000100,
285                  (ops MEMri:$addr, IntRegs:$src),
286                  "st $src, [$addr]",
287                  [(store IntRegs:$src, ADDRri:$addr)]>;
288
289 // Section B.5 - Store Floating-point Instructions, p. 97
290 def STFrr   : F3_1<3, 0b100100,
291                    (ops MEMrr:$addr, FPRegs:$src),
292                    "st $src, [$addr]",
293                    [(store FPRegs:$src, ADDRrr:$addr)]>;
294 def STFri   : F3_2<3, 0b100100,
295                    (ops MEMri:$addr, FPRegs:$src),
296                    "st $src, [$addr]",
297                    [(store FPRegs:$src, ADDRri:$addr)]>;
298 def STDFrr  : F3_1<3, 0b100111,
299                    (ops MEMrr:$addr, DFPRegs:$src),
300                    "std  $src, [$addr]",
301                    [(store DFPRegs:$src, ADDRrr:$addr)]>;
302 def STDFri  : F3_2<3, 0b100111,
303                    (ops MEMri:$addr, DFPRegs:$src),
304                    "std $src, [$addr]",
305                    [(store DFPRegs:$src, ADDRri:$addr)]>;
306
307 // Section B.9 - SETHI Instruction, p. 104
308 def SETHIi: F2_1<0b100,
309                  (ops IntRegs:$dst, i32imm:$src),
310                  "sethi $src, $dst",
311                  [(set IntRegs:$dst, SETHIimm:$src)]>;
312
313 // Section B.10 - NOP Instruction, p. 105
314 // (It's a special case of SETHI)
315 let rd = 0, imm22 = 0 in
316   def NOP : F2_1<0b100, (ops), "nop", []>;
317
318 // Section B.11 - Logical Instructions, p. 106
319 def ANDrr   : F3_1<2, 0b000001,
320                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
321                    "and $b, $c, $dst",
322                    [(set IntRegs:$dst, (and IntRegs:$b, IntRegs:$c))]>;
323 def ANDri   : F3_2<2, 0b000001,
324                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
325                    "and $b, $c, $dst",
326                    [(set IntRegs:$dst, (and IntRegs:$b, simm13:$c))]>;
327 def ANDNrr  : F3_1<2, 0b000101,
328                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
329                    "andn $b, $c, $dst",
330                    [(set IntRegs:$dst, (and IntRegs:$b, (not IntRegs:$c)))]>;
331 def ANDNri  : F3_2<2, 0b000101,
332                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
333                    "andn $b, $c, $dst", []>;
334 def ORrr    : F3_1<2, 0b000010,
335                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
336                    "or $b, $c, $dst",
337                    [(set IntRegs:$dst, (or IntRegs:$b, IntRegs:$c))]>;
338 def ORri    : F3_2<2, 0b000010,
339                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
340                    "or $b, $c, $dst",
341                    [(set IntRegs:$dst, (or IntRegs:$b, simm13:$c))]>;
342 def ORNrr   : F3_1<2, 0b000110,
343                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
344                    "orn $b, $c, $dst",
345                    [(set IntRegs:$dst, (or IntRegs:$b, (not IntRegs:$c)))]>;
346 def ORNri   : F3_2<2, 0b000110,
347                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
348                    "orn $b, $c, $dst", []>;
349 def XORrr   : F3_1<2, 0b000011,
350                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
351                    "xor $b, $c, $dst",
352                    [(set IntRegs:$dst, (xor IntRegs:$b, IntRegs:$c))]>;
353 def XORri   : F3_2<2, 0b000011,
354                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
355                    "xor $b, $c, $dst",
356                    [(set IntRegs:$dst, (xor IntRegs:$b, simm13:$c))]>;
357 def XNORrr  : F3_1<2, 0b000111,
358                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
359                    "xnor $b, $c, $dst",
360                    [(set IntRegs:$dst, (not (xor IntRegs:$b, IntRegs:$c)))]>;
361 def XNORri  : F3_2<2, 0b000111,
362                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
363                    "xnor $b, $c, $dst", []>;
364
365 // Section B.12 - Shift Instructions, p. 107
366 def SLLrr : F3_1<2, 0b100101,
367                  (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
368                  "sll $b, $c, $dst",
369                  [(set IntRegs:$dst, (shl IntRegs:$b, IntRegs:$c))]>;
370 def SLLri : F3_2<2, 0b100101,
371                  (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
372                  "sll $b, $c, $dst",
373                  [(set IntRegs:$dst, (shl IntRegs:$b, simm13:$c))]>;
374 def SRLrr : F3_1<2, 0b100110, 
375                  (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
376                   "srl $b, $c, $dst",
377                   [(set IntRegs:$dst, (srl IntRegs:$b, IntRegs:$c))]>;
378 def SRLri : F3_2<2, 0b100110,
379                  (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
380                  "srl $b, $c, $dst", 
381                  [(set IntRegs:$dst, (srl IntRegs:$b, simm13:$c))]>;
382 def SRArr : F3_1<2, 0b100111, 
383                  (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
384                   "sra $b, $c, $dst",
385                   [(set IntRegs:$dst, (sra IntRegs:$b, IntRegs:$c))]>;
386 def SRAri : F3_2<2, 0b100111,
387                  (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
388                  "sra $b, $c, $dst",
389                  [(set IntRegs:$dst, (sra IntRegs:$b, simm13:$c))]>;
390
391 // Section B.13 - Add Instructions, p. 108
392 def ADDrr   : F3_1<2, 0b000000, 
393                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
394                   "add $b, $c, $dst",
395                    [(set IntRegs:$dst, (add IntRegs:$b, IntRegs:$c))]>;
396 def ADDri   : F3_2<2, 0b000000,
397                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
398                    "add $b, $c, $dst",
399                    [(set IntRegs:$dst, (add IntRegs:$b, simm13:$c))]>;
400 def ADDCCrr : F3_1<2, 0b010000, 
401                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
402                    "addcc $b, $c, $dst", []>;
403 def ADDCCri : F3_2<2, 0b010000,
404                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
405                    "addcc $b, $c, $dst", []>;
406 def ADDXrr  : F3_1<2, 0b001000, 
407                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
408                    "addx $b, $c, $dst", []>;
409 def ADDXri  : F3_2<2, 0b001000,
410                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
411                    "addx $b, $c, $dst", []>;
412
413 // Section B.15 - Subtract Instructions, p. 110
414 def SUBrr   : F3_1<2, 0b000100, 
415                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
416                    "sub $b, $c, $dst",
417                    [(set IntRegs:$dst, (sub IntRegs:$b, IntRegs:$c))]>;
418 def SUBri   : F3_2<2, 0b000100,
419                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
420                    "sub $b, $c, $dst",
421                    [(set IntRegs:$dst, (sub IntRegs:$b, simm13:$c))]>;
422 def SUBXrr  : F3_1<2, 0b001100, 
423                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
424                    "subx $b, $c, $dst", []>;
425 def SUBXri  : F3_2<2, 0b001100,
426                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
427                    "subx $b, $c, $dst", []>;
428 def SUBCCrr : F3_1<2, 0b010100, 
429                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
430                    "subcc $b, $c, $dst",
431                    [(set IntRegs:$dst, (V8cmpicc IntRegs:$b, IntRegs:$c))]>;
432 def SUBCCri : F3_2<2, 0b010100,
433                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
434                    "subcc $b, $c, $dst",
435                    [(set IntRegs:$dst, (V8cmpicc IntRegs:$b, simm13:$c))]>;
436 def SUBXCCrr: F3_1<2, 0b011100, 
437                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
438                    "subxcc $b, $c, $dst", []>;
439
440 // Section B.18 - Multiply Instructions, p. 113
441 def UMULrr  : F3_1<2, 0b001010, 
442                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
443                    "umul $b, $c, $dst", []>;
444 def UMULri  : F3_2<2, 0b001010,
445                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
446                    "umul $b, $c, $dst", []>;
447 def SMULrr  : F3_1<2, 0b001011, 
448                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
449                    "smul $b, $c, $dst",
450                    [(set IntRegs:$dst, (mul IntRegs:$b, IntRegs:$c))]>;
451 def SMULri  : F3_2<2, 0b001011,
452                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
453                    "smul $b, $c, $dst",
454                    [(set IntRegs:$dst, (mul IntRegs:$b, simm13:$c))]>;
455
456 // Section B.19 - Divide Instructions, p. 115
457 def UDIVrr   : F3_1<2, 0b001110, 
458                     (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
459                     "udiv $b, $c, $dst", []>;
460 def UDIVri   : F3_2<2, 0b001110,
461                     (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
462                     "udiv $b, $c, $dst", []>;
463 def SDIVrr   : F3_1<2, 0b001111,
464                     (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
465                     "sdiv $b, $c, $dst", []>;
466 def SDIVri   : F3_2<2, 0b001111,
467                     (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
468                     "sdiv $b, $c, $dst", []>;
469
470 // Section B.20 - SAVE and RESTORE, p. 117
471 def SAVErr    : F3_1<2, 0b111100,
472                      (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
473                      "save $b, $c, $dst", []>;
474 def SAVEri    : F3_2<2, 0b111100,
475                      (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
476                      "save $b, $c, $dst", []>;
477 def RESTORErr : F3_1<2, 0b111101,
478                      (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
479                      "restore $b, $c, $dst", []>;
480 def RESTOREri : F3_2<2, 0b111101,
481                      (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
482                      "restore $b, $c, $dst", []>;
483
484 // Section B.21 - Branch on Integer Condition Codes Instructions, p. 119
485
486 // conditional branch class:
487 class BranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
488  : F2_2<cc, 0b010, ops, asmstr, pattern> {
489   let isBranch = 1;
490   let isTerminator = 1;
491   let hasDelaySlot = 1;
492   let noResults = 1;
493 }
494
495 let isBarrier = 1 in
496   def BA   : BranchV8<0b1000, (ops brtarget:$dst),
497                       "ba $dst",
498                       [(br bb:$dst)]>;
499 def BNE  : BranchV8<0b1001, (ops brtarget:$dst),
500                     "bne $dst",
501                     [(V8bricc bb:$dst, SETNE, ICC)]>;
502 def BE   : BranchV8<0b0001, (ops brtarget:$dst),
503                     "be $dst",
504                     [(V8bricc bb:$dst, SETEQ, ICC)]>;
505 def BG   : BranchV8<0b1010, (ops brtarget:$dst),
506                     "bg $dst",
507                     [(V8bricc bb:$dst, SETGT, ICC)]>;
508 def BLE  : BranchV8<0b0010, (ops brtarget:$dst),
509                     "ble $dst",
510                     [(V8bricc bb:$dst, SETLE, ICC)]>;
511 def BGE  : BranchV8<0b1011, (ops brtarget:$dst),
512                     "bge $dst",
513                     [(V8bricc bb:$dst, SETGE, ICC)]>;
514 def BL   : BranchV8<0b0011, (ops brtarget:$dst),
515                     "bl $dst",
516                     [(V8bricc bb:$dst, SETLT, ICC)]>;
517 def BGU  : BranchV8<0b1100, (ops brtarget:$dst),
518                     "bgu $dst",
519                     [(V8bricc bb:$dst, SETUGT, ICC)]>;
520 def BLEU : BranchV8<0b0100, (ops brtarget:$dst),
521                     "bleu $dst",
522                     [(V8bricc bb:$dst, SETULE, ICC)]>;
523 def BCC  : BranchV8<0b1101, (ops brtarget:$dst),
524                     "bcc $dst",
525                     [(V8bricc bb:$dst, SETUGE, ICC)]>;
526 def BCS  : BranchV8<0b0101, (ops brtarget:$dst),
527                     "bcs $dst",
528                     [(V8bricc bb:$dst, SETULT, ICC)]>;
529
530 // Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
531
532 // floating-point conditional branch class:
533 class FPBranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
534  : F2_2<cc, 0b110, ops, asmstr, pattern> {
535   let isBranch = 1;
536   let isTerminator = 1;
537   let hasDelaySlot = 1;
538   let noResults = 1;
539 }
540
541 def FBU  : FPBranchV8<0b0111, (ops brtarget:$dst),
542                       "fbu $dst",
543                       [(V8brfcc bb:$dst, SETUO, FCC)]>;
544 def FBG  : FPBranchV8<0b0110, (ops brtarget:$dst),
545                       "fbg $dst",
546                       [(V8brfcc bb:$dst, SETGT, FCC)]>;
547 def FBUG : FPBranchV8<0b0101, (ops brtarget:$dst),
548                       "fbug $dst",
549                       [(V8brfcc bb:$dst, SETUGT, FCC)]>;
550 def FBL  : FPBranchV8<0b0100, (ops brtarget:$dst),
551                       "fbl $dst",
552                       [(V8brfcc bb:$dst, SETLT, FCC)]>;
553 def FBUL : FPBranchV8<0b0011, (ops brtarget:$dst),
554                       "fbul $dst",
555                       [(V8brfcc bb:$dst, SETULT, FCC)]>;
556 def FBLG : FPBranchV8<0b0010, (ops brtarget:$dst),
557                       "fblg $dst",
558                       [(V8brfcc bb:$dst, SETONE, FCC)]>;
559 def FBNE : FPBranchV8<0b0001, (ops brtarget:$dst),
560                       "fbne $dst",
561                       [(V8brfcc bb:$dst, SETNE, FCC)]>;
562 def FBE  : FPBranchV8<0b1001, (ops brtarget:$dst),
563                       "fbe $dst",
564                       [(V8brfcc bb:$dst, SETEQ, FCC)]>;
565 def FBUE : FPBranchV8<0b1010, (ops brtarget:$dst),
566                       "fbue $dst",
567                       [(V8brfcc bb:$dst, SETUEQ, FCC)]>;
568 def FBGE : FPBranchV8<0b1011, (ops brtarget:$dst),
569                       "fbge $dst",
570                       [(V8brfcc bb:$dst, SETGE, FCC)]>;
571 def FBUGE: FPBranchV8<0b1100, (ops brtarget:$dst),
572                       "fbuge $dst",
573                       [(V8brfcc bb:$dst, SETUGE, FCC)]>;
574 def FBLE : FPBranchV8<0b1101, (ops brtarget:$dst),
575                       "fble $dst",
576                       [(V8brfcc bb:$dst, SETLE, FCC)]>;
577 def FBULE: FPBranchV8<0b1110, (ops brtarget:$dst),
578                       "fbule $dst",
579                       [(V8brfcc bb:$dst, SETULE, FCC)]>;
580 def FBO  : FPBranchV8<0b1111, (ops brtarget:$dst),
581                       "fbo $dst",
582                       [(V8brfcc bb:$dst, SETO, FCC)]>;
583
584
585
586 // Section B.24 - Call and Link Instruction, p. 125
587 // This is the only Format 1 instruction
588 let Uses = [O0, O1, O2, O3, O4, O5],
589     hasDelaySlot = 1, isCall = 1, noResults = 1,
590     Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
591     D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { 
592   def CALL : InstV8<(ops calltarget:$dst),
593                     "call $dst", []> {
594     bits<30> disp;
595     let op = 1;
596     let Inst{29-0} = disp;
597   }
598   
599   // indirect calls
600   def JMPLrr : F3_1<2, 0b111000,
601                     (ops MEMrr:$ptr),
602                     "call $ptr",
603                     [(call  ADDRrr:$ptr)]>;
604   def JMPLri : F3_2<2, 0b111000,
605                     (ops MEMri:$ptr),
606                     "call $ptr",
607                     [(call  ADDRri:$ptr)]>;
608 }
609
610 // Section B.28 - Read State Register Instructions
611 def RDY : F3_1<2, 0b101000,
612                (ops IntRegs:$dst),
613                "rd %y, $dst", []>;
614
615 // Section B.29 - Write State Register Instructions
616 def WRYrr : F3_1<2, 0b110000,
617                  (ops IntRegs:$b, IntRegs:$c),
618                  "wr $b, $c, %y", []>;
619 def WRYri : F3_2<2, 0b110000,
620                  (ops IntRegs:$b, i32imm:$c),
621                  "wr $b, $c, %y", []>;
622
623 // Convert Integer to Floating-point Instructions, p. 141
624 def FITOS : F3_3<2, 0b110100, 0b011000100,
625                  (ops FPRegs:$dst, FPRegs:$src),
626                  "fitos $src, $dst",
627                  [(set FPRegs:$dst, (V8itof FPRegs:$src))]>;
628 def FITOD : F3_3<2, 0b110100, 0b011001000, 
629                  (ops DFPRegs:$dst, FPRegs:$src),
630                  "fitod $src, $dst",
631                  [(set DFPRegs:$dst, (V8itof FPRegs:$src))]>;
632
633 // Convert Floating-point to Integer Instructions, p. 142
634 def FSTOI : F3_3<2, 0b110100, 0b011010001,
635                  (ops FPRegs:$dst, FPRegs:$src),
636                  "fstoi $src, $dst",
637                  [(set FPRegs:$dst, (V8ftoi FPRegs:$src))]>;
638 def FDTOI : F3_3<2, 0b110100, 0b011010010,
639                  (ops FPRegs:$dst, DFPRegs:$src),
640                  "fdtoi $src, $dst",
641                  [(set FPRegs:$dst, (V8ftoi DFPRegs:$src))]>;
642
643 // Convert between Floating-point Formats Instructions, p. 143
644 def FSTOD : F3_3<2, 0b110100, 0b011001001, 
645                  (ops DFPRegs:$dst, FPRegs:$src),
646                  "fstod $src, $dst",
647                  [(set DFPRegs:$dst, (fextend FPRegs:$src))]>;
648 def FDTOS : F3_3<2, 0b110100, 0b011000110,
649                  (ops FPRegs:$dst, DFPRegs:$src),
650                  "fdtos $src, $dst",
651                  [(set FPRegs:$dst, (fround DFPRegs:$src))]>;
652
653 // Floating-point Move Instructions, p. 144
654 def FMOVS : F3_3<2, 0b110100, 0b000000001,
655                  (ops FPRegs:$dst, FPRegs:$src),
656                  "fmovs $src, $dst", []>;
657 def FNEGS : F3_3<2, 0b110100, 0b000000101, 
658                  (ops FPRegs:$dst, FPRegs:$src),
659                  "fnegs $src, $dst",
660                  [(set FPRegs:$dst, (fneg FPRegs:$src))]>;
661 def FABSS : F3_3<2, 0b110100, 0b000001001, 
662                  (ops FPRegs:$dst, FPRegs:$src),
663                  "fabss $src, $dst",
664                  [(set FPRegs:$dst, (fabs FPRegs:$src))]>;
665
666
667 // Floating-point Square Root Instructions, p.145
668 def FSQRTS : F3_3<2, 0b110100, 0b000101001, 
669                   (ops FPRegs:$dst, FPRegs:$src),
670                   "fsqrts $src, $dst",
671                   [(set FPRegs:$dst, (fsqrt FPRegs:$src))]>;
672 def FSQRTD : F3_3<2, 0b110100, 0b000101010, 
673                   (ops DFPRegs:$dst, DFPRegs:$src),
674                   "fsqrtd $src, $dst",
675                   [(set DFPRegs:$dst, (fsqrt DFPRegs:$src))]>;
676
677
678
679 // Floating-point Add and Subtract Instructions, p. 146
680 def FADDS  : F3_3<2, 0b110100, 0b001000001,
681                   (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
682                   "fadds $src1, $src2, $dst",
683                   [(set FPRegs:$dst, (fadd FPRegs:$src1, FPRegs:$src2))]>;
684 def FADDD  : F3_3<2, 0b110100, 0b001000010,
685                   (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
686                   "faddd $src1, $src2, $dst",
687                   [(set DFPRegs:$dst, (fadd DFPRegs:$src1, DFPRegs:$src2))]>;
688 def FSUBS  : F3_3<2, 0b110100, 0b001000101,
689                   (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
690                   "fsubs $src1, $src2, $dst",
691                   [(set FPRegs:$dst, (fsub FPRegs:$src1, FPRegs:$src2))]>;
692 def FSUBD  : F3_3<2, 0b110100, 0b001000110,
693                   (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
694                   "fsubd $src1, $src2, $dst",
695                   [(set DFPRegs:$dst, (fsub DFPRegs:$src1, DFPRegs:$src2))]>;
696
697 // Floating-point Multiply and Divide Instructions, p. 147
698 def FMULS  : F3_3<2, 0b110100, 0b001001001,
699                   (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
700                   "fmuls $src1, $src2, $dst",
701                   [(set FPRegs:$dst, (fmul FPRegs:$src1, FPRegs:$src2))]>;
702 def FMULD  : F3_3<2, 0b110100, 0b001001010,
703                   (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
704                   "fmuld $src1, $src2, $dst",
705                   [(set DFPRegs:$dst, (fmul DFPRegs:$src1, DFPRegs:$src2))]>;
706 def FSMULD : F3_3<2, 0b110100, 0b001101001,
707                   (ops DFPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
708                   "fsmuld $src1, $src2, $dst",
709                   [(set DFPRegs:$dst, (fmul (fextend FPRegs:$src1),
710                                             (fextend FPRegs:$src2)))]>;
711 def FDIVS  : F3_3<2, 0b110100, 0b001001101,
712                  (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
713                  "fdivs $src1, $src2, $dst",
714                  [(set FPRegs:$dst, (fdiv FPRegs:$src1, FPRegs:$src2))]>;
715 def FDIVD  : F3_3<2, 0b110100, 0b001001110,
716                  (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
717                  "fdivd $src1, $src2, $dst",
718                  [(set DFPRegs:$dst, (fdiv DFPRegs:$src1, DFPRegs:$src2))]>;
719
720 // Floating-point Compare Instructions, p. 148
721 // Note: the 2nd template arg is different for these guys.
722 // Note 2: the result of a FCMP is not available until the 2nd cycle
723 // after the instr is retired, but there is no interlock. This behavior
724 // is modelled with a forced noop after the instruction.
725 def FCMPS  : F3_3<2, 0b110101, 0b001010001,
726                   (ops FPRegs:$src1, FPRegs:$src2),
727                   "fcmps $src1, $src2\n\tnop",
728                   [(set FCC, (V8cmpfcc FPRegs:$src1, FPRegs:$src2))]>;
729 def FCMPD  : F3_3<2, 0b110101, 0b001010010,
730                   (ops DFPRegs:$src1, DFPRegs:$src2),
731                   "fcmpd $src1, $src2\n\tnop",
732                   [(set FCC, (V8cmpfcc DFPRegs:$src1, DFPRegs:$src2))]>;
733
734
735 //===----------------------------------------------------------------------===//
736 // V9 Instructions
737 //===----------------------------------------------------------------------===//
738
739 // V9 Conditional Moves.
740 let Predicates = [HasV9], isTwoAddress = 1 in {
741   // FIXME: Add instruction encodings for the JIT some day.
742   def MOVNE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F),
743                      "movne %icc, $F, $dst",
744                      [(set IntRegs:$dst,
745                            (V8selecticc IntRegs:$F, IntRegs:$T, 22, ICC))]>;
746   def MOVEQ : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F),
747                      "move %icc, $F, $dst",
748                      [(set IntRegs:$dst,
749                            (V8selecticc IntRegs:$F, IntRegs:$T, 17, ICC))]>;
750 }
751
752 // Floating-Point Move Instructions, p. 164 of the V9 manual.
753 let Predicates = [HasV9] in {
754   def FMOVD : F3_3<2, 0b110100, 0b000000010,
755                    (ops DFPRegs:$dst, DFPRegs:$src),
756                    "fmovd $src, $dst", []>;
757   def FNEGD : F3_3<2, 0b110100, 0b000000110, 
758                    (ops DFPRegs:$dst, DFPRegs:$src),
759                    "fnegd $src, $dst",
760                    [(set DFPRegs:$dst, (fneg DFPRegs:$src))]>;
761   def FABSD : F3_3<2, 0b110100, 0b000001010, 
762                    (ops DFPRegs:$dst, DFPRegs:$src),
763                    "fabsd $src, $dst",
764                    [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>;
765 }
766
767 //===----------------------------------------------------------------------===//
768 // Non-Instruction Patterns
769 //===----------------------------------------------------------------------===//
770
771 // Small immediates.
772 def : Pat<(i32 simm13:$val),
773           (ORri G0, imm:$val)>;
774 // Arbitrary immediates.
775 def : Pat<(i32 imm:$val),
776           (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;
777
778 // Global addresses, constant pool entries
779 def : Pat<(V8hi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>;
780 def : Pat<(V8lo tglobaladdr:$in), (ORri G0, tglobaladdr:$in)>;
781 def : Pat<(V8hi tconstpool:$in), (SETHIi tconstpool:$in)>;
782 def : Pat<(V8lo tconstpool:$in), (ORri G0, tconstpool:$in)>;
783
784 // Add reg, lo.  This is used when taking the addr of a global/constpool entry.
785 def : Pat<(add IntRegs:$r, (V8lo tglobaladdr:$in)),
786           (ADDri IntRegs:$r, tglobaladdr:$in)>;
787 def : Pat<(add IntRegs:$r, (V8lo tconstpool:$in)),
788           (ADDri IntRegs:$r, tconstpool:$in)>;
789
790
791 // Calls: 
792 def : Pat<(call tglobaladdr:$dst),
793           (CALL tglobaladdr:$dst)>;
794 def : Pat<(call externalsym:$dst),
795           (CALL externalsym:$dst)>;
796
797 def : Pat<(ret), (RETL)>;
798
799 // Map integer extload's to zextloads.
800 def : Pat<(i32 (extload ADDRrr:$src, i1)), (LDUBrr ADDRrr:$src)>;
801 def : Pat<(i32 (extload ADDRri:$src, i1)), (LDUBri ADDRri:$src)>;
802 def : Pat<(i32 (extload ADDRrr:$src, i8)), (LDUBrr ADDRrr:$src)>;
803 def : Pat<(i32 (extload ADDRri:$src, i8)), (LDUBri ADDRri:$src)>;
804 def : Pat<(i32 (extload ADDRrr:$src, i16)), (LDUHrr ADDRrr:$src)>;
805 def : Pat<(i32 (extload ADDRri:$src, i16)), (LDUHri ADDRri:$src)>;
806
807 // zextload bool -> zextload byte
808 def : Pat<(i32 (zextload ADDRrr:$src, i1)), (LDUBrr ADDRrr:$src)>;
809 def : Pat<(i32 (zextload ADDRri:$src, i1)), (LDUBri ADDRri:$src)>;
810
811 // truncstore bool -> truncstore byte.
812 def : Pat<(truncstore IntRegs:$src, ADDRrr:$addr, i1), 
813           (STBrr ADDRrr:$addr, IntRegs:$src)>;
814 def : Pat<(truncstore IntRegs:$src, ADDRri:$addr, i1), 
815           (STBri ADDRri:$addr, IntRegs:$src)>;