SparcInstrInfo.td revision 76afdc9a80cf078aebd0ec62dba0bfafe498b1dc
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
18include "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.
26def HasV9   : Predicate<"Subtarget.isV9()">;
27
28// HasVIS - This is true when the target processor has VIS extensions.
29def 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.
35def UseDeprecatedInsts : Predicate<"Subtarget.useDeprecatedV8Instructions()">;
36
37//===----------------------------------------------------------------------===//
38// Instruction Pattern Stuff
39//===----------------------------------------------------------------------===//
40
41def 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
46def LO10 : SDNodeXForm<imm, [{
47  return CurDAG->getTargetConstant((unsigned)N->getValue() & 1023, MVT::i32);
48}]>;
49
50def 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
55def SETHIimm : PatLeaf<(imm), [{
56  return (((unsigned)N->getValue() >> 10) << 10) == (unsigned)N->getValue();
57}], HI22>;
58
59// Addressing modes.
60def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", []>;
61def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", []>;
62
63// Address operands
64def MEMrr : Operand<i32> {
65  let PrintMethod = "printMemOperand";
66  let NumMIOperands = 2;
67  let MIOperandInfo = (ops IntRegs, IntRegs);
68}
69def 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.
76def brtarget : Operand<OtherVT>;
77def calltarget : Operand<i32>;
78
79def SDTV8cmpfcc : 
80SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>;
81def SDTV8brcc : 
82SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, SDTCisVT<1, OtherVT>,
83                     SDTCisVT<2, FlagVT>]>;
84def SDTV8selectcc :
85SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 
86                     SDTCisVT<3, i32>, SDTCisVT<4, FlagVT>]>;
87def SDTV8FTOI :
88SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;
89def SDTV8ITOF :
90SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
91
92def V8cmpicc : SDNode<"V8ISD::CMPICC", SDTIntBinOp, [SDNPOutFlag]>;
93def V8cmpfcc : SDNode<"V8ISD::CMPFCC", SDTV8cmpfcc, [SDNPOutFlag]>;
94def V8bricc : SDNode<"V8ISD::BRICC", SDTV8brcc, [SDNPHasChain]>;
95def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>;
96
97def V8hi    : SDNode<"V8ISD::Hi", SDTIntUnaryOp>;
98def V8lo    : SDNode<"V8ISD::Lo", SDTIntUnaryOp>;
99
100def V8ftoi  : SDNode<"V8ISD::FTOI", SDTV8FTOI>;
101def V8itof  : SDNode<"V8ISD::ITOF", SDTV8ITOF>;
102
103def V8selecticc : SDNode<"V8ISD::SELECT_ICC", SDTV8selectcc>;
104def V8selectfcc : SDNode<"V8ISD::SELECT_FCC", SDTV8selectcc>;
105
106// These are target-independent nodes, but have target-specific formats.
107def SDT_V8CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
108def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_V8CallSeq, [SDNPHasChain]>;
109def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_V8CallSeq, [SDNPHasChain]>;
110
111def SDT_V8Call    : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
112def call          : SDNode<"V8ISD::CALL", SDT_V8Call,
113	                   [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
114
115def SDT_V8RetFlag : SDTypeProfile<0, 0, []>;
116def retflag       : SDNode<"V8ISD::RET_FLAG", SDT_V8RetFlag,
117	                   [SDNPHasChain, SDNPOptInFlag]>;
118
119//===----------------------------------------------------------------------===//
120// Instructions
121//===----------------------------------------------------------------------===//
122
123// Pseudo instructions.
124class Pseudo<dag ops, string asmstr, list<dag> pattern>
125   : InstV8<ops, asmstr, pattern>;
126
127def ADJCALLSTACKDOWN : Pseudo<(ops i32imm:$amt),
128                               "!ADJCALLSTACKDOWN $amt",
129                               [(callseq_start imm:$amt)]>;
130def ADJCALLSTACKUP : Pseudo<(ops i32imm:$amt),
131                            "!ADJCALLSTACKUP $amt",
132                            [(callseq_end imm:$amt)]>;
133def IMPLICIT_DEF_Int : Pseudo<(ops IntRegs:$dst),
134                              "!IMPLICIT_DEF $dst",
135                              [(set IntRegs:$dst, (undef))]>;
136def IMPLICIT_DEF_FP  : Pseudo<(ops FPRegs:$dst), "!IMPLICIT_DEF $dst",
137                              [(set FPRegs:$dst, (undef))]>;
138def 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.
143def FpMOVD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src),
144                    "!FpMOVD $src, $dst", []>;   // pseudo 64-bit double move
145def FpNEGD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src),
146                    "!FpNEGD $src, $dst",
147                    [(set DFPRegs:$dst, (fneg DFPRegs:$src))]>;
148def 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.
155let 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:
191let 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
197def LDSBrr : F3_1<3, 0b001001,
198                  (ops IntRegs:$dst, MEMrr:$addr),
199                  "ldsb [$addr], $dst",
200                  [(set IntRegs:$dst, (sextload ADDRrr:$addr, i8))]>;
201def LDSBri : F3_2<3, 0b001001,
202                  (ops IntRegs:$dst, MEMri:$addr),
203                  "ldsb [$addr], $dst",
204                  [(set IntRegs:$dst, (sextload ADDRri:$addr, i8))]>;
205def LDSHrr : F3_1<3, 0b001010,
206                  (ops IntRegs:$dst, MEMrr:$addr),
207                  "ldsh [$addr], $dst",
208                  [(set IntRegs:$dst, (sextload ADDRrr:$addr, i16))]>;
209def LDSHri : F3_2<3, 0b001010,
210                  (ops IntRegs:$dst, MEMri:$addr),
211                  "ldsh [$addr], $dst",
212                  [(set IntRegs:$dst, (sextload ADDRri:$addr, i16))]>;
213def LDUBrr : F3_1<3, 0b000001,
214                  (ops IntRegs:$dst, MEMrr:$addr),
215                  "ldub [$addr], $dst",
216                  [(set IntRegs:$dst, (zextload ADDRrr:$addr, i8))]>;
217def LDUBri : F3_2<3, 0b000001,
218                  (ops IntRegs:$dst, MEMri:$addr),
219                  "ldub [$addr], $dst",
220                  [(set IntRegs:$dst, (zextload ADDRri:$addr, i8))]>;
221def LDUHrr : F3_1<3, 0b000010,
222                  (ops IntRegs:$dst, MEMrr:$addr),
223                  "lduh [$addr], $dst",
224                  [(set IntRegs:$dst, (zextload ADDRrr:$addr, i16))]>;
225def LDUHri : F3_2<3, 0b000010,
226                  (ops IntRegs:$dst, MEMri:$addr),
227                  "lduh [$addr], $dst",
228                  [(set IntRegs:$dst, (zextload ADDRri:$addr, i16))]>;
229def LDrr   : F3_1<3, 0b000000,
230                  (ops IntRegs:$dst, MEMrr:$addr),
231                  "ld [$addr], $dst",
232                  [(set IntRegs:$dst, (load ADDRrr:$addr))]>;
233def 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
239def LDFrr  : F3_1<3, 0b100000,
240                  (ops FPRegs:$dst, MEMrr:$addr),
241                  "ld [$addr], $dst",
242                  [(set FPRegs:$dst, (load ADDRrr:$addr))]>;
243def LDFri  : F3_2<3, 0b100000,
244                  (ops FPRegs:$dst, MEMri:$addr),
245                  "ld [$addr], $dst",
246                  [(set FPRegs:$dst, (load ADDRri:$addr))]>;
247def LDDFrr : F3_1<3, 0b100011,
248                  (ops DFPRegs:$dst, MEMrr:$addr),
249                  "ldd [$addr], $dst",
250                  [(set DFPRegs:$dst, (load ADDRrr:$addr))]>;
251def 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
257def STBrr : F3_1<3, 0b000101,
258                 (ops MEMrr:$addr, IntRegs:$src),
259                 "stb $src, [$addr]",
260                 [(truncstore IntRegs:$src, ADDRrr:$addr, i8)]>;
261def STBri : F3_2<3, 0b000101,
262                 (ops MEMri:$addr, IntRegs:$src),
263                 "stb $src, [$addr]",
264                 [(truncstore IntRegs:$src, ADDRri:$addr, i8)]>;
265def STHrr : F3_1<3, 0b000110,
266                 (ops MEMrr:$addr, IntRegs:$src),
267                 "sth $src, [$addr]",
268                 [(truncstore IntRegs:$src, ADDRrr:$addr, i16)]>;
269def STHri : F3_2<3, 0b000110,
270                 (ops MEMri:$addr, IntRegs:$src),
271                 "sth $src, [$addr]",
272                 [(truncstore IntRegs:$src, ADDRri:$addr, i16)]>;
273def STrr  : F3_1<3, 0b000100,
274                 (ops MEMrr:$addr, IntRegs:$src),
275                 "st $src, [$addr]",
276                 [(store IntRegs:$src, ADDRrr:$addr)]>;
277def 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
283def STFrr   : F3_1<3, 0b100100,
284                   (ops MEMrr:$addr, FPRegs:$src),
285                   "st $src, [$addr]",
286                   [(store FPRegs:$src, ADDRrr:$addr)]>;
287def STFri   : F3_2<3, 0b100100,
288                   (ops MEMri:$addr, FPRegs:$src),
289                   "st $src, [$addr]",
290                   [(store FPRegs:$src, ADDRri:$addr)]>;
291def STDFrr  : F3_1<3, 0b100111,
292                   (ops MEMrr:$addr, DFPRegs:$src),
293                   "std  $src, [$addr]",
294                   [(store DFPRegs:$src, ADDRrr:$addr)]>;
295def 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
301def 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)
308let rd = 0, imm22 = 0 in
309  def NOP : F2_1<0b100, (ops), "nop", []>;
310
311// Section B.11 - Logical Instructions, p. 106
312def 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))]>;
316def 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))]>;
320def 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)))]>;
324def ANDNri  : F3_2<2, 0b000101,
325                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
326                   "andn $b, $c, $dst", []>;
327def 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))]>;
331def 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))]>;
335def 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)))]>;
339def ORNri   : F3_2<2, 0b000110,
340                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
341                   "orn $b, $c, $dst", []>;
342def 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))]>;
346def 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))]>;
350def 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)))]>;
354def 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
359def 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))]>;
363def 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))]>;
367def 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))]>;
371def 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))]>;
375def 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))]>;
379def 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
385def 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))]>;
389def 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))]>;
393def ADDCCrr : F3_1<2, 0b010000, 
394                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
395                   "addcc $b, $c, $dst", []>;
396def ADDCCri : F3_2<2, 0b010000,
397                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
398                   "addcc $b, $c, $dst", []>;
399def ADDXrr  : F3_1<2, 0b001000, 
400                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
401                   "addx $b, $c, $dst", []>;
402def 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
407def 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))]>;
411def 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))]>;
415def SUBXrr  : F3_1<2, 0b001100, 
416                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
417                   "subx $b, $c, $dst", []>;
418def SUBXri  : F3_2<2, 0b001100,
419                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
420                   "subx $b, $c, $dst", []>;
421def 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))]>;
425def 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))]>;
429def 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
434def UMULrr  : F3_1<2, 0b001010, 
435                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
436                   "umul $b, $c, $dst", []>;
437def UMULri  : F3_2<2, 0b001010,
438                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
439                   "umul $b, $c, $dst", []>;
440def 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))]>;
444def 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
450def UDIVrr   : F3_1<2, 0b001110, 
451                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
452                    "udiv $b, $c, $dst", []>;
453def UDIVri   : F3_2<2, 0b001110,
454                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
455                    "udiv $b, $c, $dst", []>;
456def SDIVrr   : F3_1<2, 0b001111,
457                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
458                    "sdiv $b, $c, $dst", []>;
459def 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
464def SAVErr    : F3_1<2, 0b111100,
465                     (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
466                     "save $b, $c, $dst", []>;
467def SAVEri    : F3_2<2, 0b111100,
468                     (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
469                     "save $b, $c, $dst", []>;
470def RESTORErr : F3_1<2, 0b111101,
471                     (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
472                     "restore $b, $c, $dst", []>;
473def 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:
480class 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
488let isBarrier = 1 in
489  def BA   : BranchV8<0b1000, (ops brtarget:$dst),
490                      "ba $dst",
491                      [(br bb:$dst)]>;
492def BNE  : BranchV8<0b1001, (ops brtarget:$dst),
493                    "bne $dst",
494                    [(V8bricc bb:$dst, SETNE, ICC)]>;
495def BE   : BranchV8<0b0001, (ops brtarget:$dst),
496                    "be $dst",
497                    [(V8bricc bb:$dst, SETEQ, ICC)]>;
498def BG   : BranchV8<0b1010, (ops brtarget:$dst),
499                    "bg $dst",
500                    [(V8bricc bb:$dst, SETGT, ICC)]>;
501def BLE  : BranchV8<0b0010, (ops brtarget:$dst),
502                    "ble $dst",
503                    [(V8bricc bb:$dst, SETLE, ICC)]>;
504def BGE  : BranchV8<0b1011, (ops brtarget:$dst),
505                    "bge $dst",
506                    [(V8bricc bb:$dst, SETGE, ICC)]>;
507def BL   : BranchV8<0b0011, (ops brtarget:$dst),
508                    "bl $dst",
509                    [(V8bricc bb:$dst, SETLT, ICC)]>;
510def BGU  : BranchV8<0b1100, (ops brtarget:$dst),
511                    "bgu $dst",
512                    [(V8bricc bb:$dst, SETUGT, ICC)]>;
513def BLEU : BranchV8<0b0100, (ops brtarget:$dst),
514                    "bleu $dst",
515                    [(V8bricc bb:$dst, SETULE, ICC)]>;
516def BCC  : BranchV8<0b1101, (ops brtarget:$dst),
517                    "bcc $dst",
518                    [(V8bricc bb:$dst, SETUGE, ICC)]>;
519def 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:
526class 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
534def FBU  : FPBranchV8<0b0111, (ops brtarget:$dst),
535                      "fbu $dst",
536                      [(V8brfcc bb:$dst, SETUO, FCC)]>;
537def FBG  : FPBranchV8<0b0110, (ops brtarget:$dst),
538                      "fbg $dst",
539                      [(V8brfcc bb:$dst, SETGT, FCC)]>;
540def FBUG : FPBranchV8<0b0101, (ops brtarget:$dst),
541                      "fbug $dst",
542                      [(V8brfcc bb:$dst, SETUGT, FCC)]>;
543def FBL  : FPBranchV8<0b0100, (ops brtarget:$dst),
544                      "fbl $dst",
545                      [(V8brfcc bb:$dst, SETLT, FCC)]>;
546def FBUL : FPBranchV8<0b0011, (ops brtarget:$dst),
547                      "fbul $dst",
548                      [(V8brfcc bb:$dst, SETULT, FCC)]>;
549def FBLG : FPBranchV8<0b0010, (ops brtarget:$dst),
550                      "fblg $dst",
551                      [(V8brfcc bb:$dst, SETONE, FCC)]>;
552def FBNE : FPBranchV8<0b0001, (ops brtarget:$dst),
553                      "fbne $dst",
554                      [(V8brfcc bb:$dst, SETNE, FCC)]>;
555def FBE  : FPBranchV8<0b1001, (ops brtarget:$dst),
556                      "fbe $dst",
557                      [(V8brfcc bb:$dst, SETEQ, FCC)]>;
558def FBUE : FPBranchV8<0b1010, (ops brtarget:$dst),
559                      "fbue $dst",
560                      [(V8brfcc bb:$dst, SETUEQ, FCC)]>;
561def FBGE : FPBranchV8<0b1011, (ops brtarget:$dst),
562                      "fbge $dst",
563                      [(V8brfcc bb:$dst, SETGE, FCC)]>;
564def FBUGE: FPBranchV8<0b1100, (ops brtarget:$dst),
565                      "fbuge $dst",
566                      [(V8brfcc bb:$dst, SETUGE, FCC)]>;
567def FBLE : FPBranchV8<0b1101, (ops brtarget:$dst),
568                      "fble $dst",
569                      [(V8brfcc bb:$dst, SETLE, FCC)]>;
570def FBULE: FPBranchV8<0b1110, (ops brtarget:$dst),
571                      "fbule $dst",
572                      [(V8brfcc bb:$dst, SETULE, FCC)]>;
573def 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
581let 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
604def RDY : F3_1<2, 0b101000,
605               (ops IntRegs:$dst),
606               "rd %y, $dst", []>;
607
608// Section B.29 - Write State Register Instructions
609def WRYrr : F3_1<2, 0b110000,
610                 (ops IntRegs:$b, IntRegs:$c),
611                 "wr $b, $c, %y", []>;
612def 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
617def FITOS : F3_3<2, 0b110100, 0b011000100,
618                 (ops FPRegs:$dst, FPRegs:$src),
619                 "fitos $src, $dst",
620                 [(set FPRegs:$dst, (V8itof FPRegs:$src))]>;
621def 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
627def FSTOI : F3_3<2, 0b110100, 0b011010001,
628                 (ops FPRegs:$dst, FPRegs:$src),
629                 "fstoi $src, $dst",
630                 [(set FPRegs:$dst, (V8ftoi FPRegs:$src))]>;
631def 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
637def FSTOD : F3_3<2, 0b110100, 0b011001001, 
638                 (ops DFPRegs:$dst, FPRegs:$src),
639                 "fstod $src, $dst",
640                 [(set DFPRegs:$dst, (fextend FPRegs:$src))]>;
641def 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
647def FMOVS : F3_3<2, 0b110100, 0b000000001,
648                 (ops FPRegs:$dst, FPRegs:$src),
649                 "fmovs $src, $dst", []>;
650def FNEGS : F3_3<2, 0b110100, 0b000000101, 
651                 (ops FPRegs:$dst, FPRegs:$src),
652                 "fnegs $src, $dst",
653                 [(set FPRegs:$dst, (fneg FPRegs:$src))]>;
654def 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
661def FSQRTS : F3_3<2, 0b110100, 0b000101001, 
662                  (ops FPRegs:$dst, FPRegs:$src),
663                  "fsqrts $src, $dst",
664                  [(set FPRegs:$dst, (fsqrt FPRegs:$src))]>;
665def 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
673def 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))]>;
677def 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))]>;
681def 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))]>;
685def 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
691def 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))]>;
695def 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))]>;
699def 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)))]>;
704def 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))]>;
708def 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.
718def 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))]>;
722def 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.
733let 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.
750def : Pat<(i32 simm13:$val),
751          (ORri G0, imm:$val)>;
752// Arbitrary immediates.
753def : Pat<(i32 imm:$val),
754          (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;
755
756// Global addresses, constant pool entries
757def : Pat<(V8hi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>;
758def : Pat<(V8lo tglobaladdr:$in), (ORri G0, tglobaladdr:$in)>;
759def : Pat<(V8hi tconstpool:$in), (SETHIi tconstpool:$in)>;
760def : 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.
763def : Pat<(add IntRegs:$r, (V8lo tglobaladdr:$in)),
764          (ADDri IntRegs:$r, tglobaladdr:$in)>;
765def : Pat<(add IntRegs:$r, (V8lo tconstpool:$in)),
766          (ADDri IntRegs:$r, tconstpool:$in)>;
767
768
769// Calls: 
770def : Pat<(call tglobaladdr:$dst),
771          (CALL tglobaladdr:$dst)>;
772def : Pat<(call externalsym:$dst),
773          (CALL externalsym:$dst)>;
774
775def : Pat<(ret), (RETL)>;
776
777// Map integer extload's to zextloads.
778def : Pat<(i32 (extload ADDRrr:$src, i1)), (LDUBrr ADDRrr:$src)>;
779def : Pat<(i32 (extload ADDRri:$src, i1)), (LDUBri ADDRri:$src)>;
780def : Pat<(i32 (extload ADDRrr:$src, i8)), (LDUBrr ADDRrr:$src)>;
781def : Pat<(i32 (extload ADDRri:$src, i8)), (LDUBri ADDRri:$src)>;
782def : Pat<(i32 (extload ADDRrr:$src, i16)), (LDUHrr ADDRrr:$src)>;
783def : Pat<(i32 (extload ADDRri:$src, i16)), (LDUHri ADDRri:$src)>;
784
785// zextload bool -> zextload byte
786def : Pat<(i32 (zextload ADDRrr:$src, i1)), (LDUBrr ADDRrr:$src)>;
787def : Pat<(i32 (zextload ADDRri:$src, i1)), (LDUBri ADDRri:$src)>;
788
789// truncstore bool -> truncstore byte.
790def : Pat<(truncstore IntRegs:$src, ADDRrr:$addr, i1), 
791          (STBrr ADDRrr:$addr, IntRegs:$src)>;
792def : Pat<(truncstore IntRegs:$src, ADDRri:$addr, i1), 
793          (STBri ADDRri:$addr, IntRegs:$src)>;
794