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