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