SparcInstrInfo.td revision b71f9f8488f665ef042097eca28aeddb85e6c2ee
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
18class InstV8 : Instruction {          // SparcV8 instruction baseline
19  field bits<32> Inst;
20
21  let Namespace = "V8";
22
23  bits<2> op;
24  let Inst{31-30} = op;               // Top two bits are the 'op' field
25
26  // Bit attributes specific to SparcV8 instructions
27  bit isPasi       = 0; // Does this instruction affect an alternate addr space?
28  bit isPrivileged = 0; // Is this a privileged instruction?
29}
30
31include "SparcV8InstrFormats.td"
32
33//===----------------------------------------------------------------------===//
34// Instruction Pattern Stuff
35//===----------------------------------------------------------------------===//
36
37def simm13  : PatLeaf<(imm), [{
38  // simm13 predicate - True if the imm fits in a 13-bit sign extended field.
39  return (((int)N->getValue() << (32-13)) >> (32-13)) == (int)N->getValue();
40}]>;
41
42def LO10 : SDNodeXForm<imm, [{
43  return CurDAG->getTargetConstant((unsigned)N->getValue() & 1023, MVT::i32);
44}]>;
45
46def HI22 : SDNodeXForm<imm, [{
47  // Transformation function: shift the immediate value down into the low bits.
48  return CurDAG->getTargetConstant((unsigned)N->getValue() >> 10, MVT::i32);
49}]>;
50
51def SETHIimm : PatLeaf<(imm), [{
52  return (((unsigned)N->getValue() >> 10) << 10) == (unsigned)N->getValue();
53}], HI22>;
54
55//===----------------------------------------------------------------------===//
56// Instructions
57//===----------------------------------------------------------------------===//
58
59// Pseudo instructions.
60class PseudoInstV8<string asmstr, dag ops> : InstV8  {
61  let AsmString = asmstr;
62  dag OperandList = ops;
63}
64def PHI : PseudoInstV8<"PHI", (ops variable_ops)>;
65def ADJCALLSTACKDOWN : PseudoInstV8<"!ADJCALLSTACKDOWN $amt",
66                                    (ops i32imm:$amt)>;
67def ADJCALLSTACKUP : PseudoInstV8<"!ADJCALLSTACKUP $amt",
68                                  (ops i32imm:$amt)>;
69//def IMPLICIT_USE : PseudoInstV8<"!IMPLICIT_USE",(ops variable_ops)>;
70def IMPLICIT_DEF : PseudoInstV8<"!IMPLICIT_DEF $dst", 
71                                (ops IntRegs:$dst)>;
72def FpMOVD : PseudoInstV8<"!FpMOVD", (ops)>; // pseudo 64-bit double move
73
74// Section A.3 - Synthetic Instructions, p. 85
75// special cases of JMPL:
76let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in {
77  let rd = I7.Num, rs1 = G0.Num, simm13 = 8 in
78    def RET : F3_2<2, 0b111000,
79                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
80                   "ret $b, $c, $dst", []>;
81  let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
82    def RETL: F3_2<2, 0b111000, (ops),
83                   "retl", [(ret)]>;
84}
85// CMP is a special case of SUBCC where destination is ignored, by setting it to
86// %g0 (hardwired zero).
87// FIXME: should keep track of the fact that it defs the integer condition codes
88let rd = 0 in
89  def CMPri: F3_2<2, 0b010100,
90                  (ops IntRegs:$b, i32imm:$c),
91                  "cmp $b, $c", []>;
92
93// Section B.1 - Load Integer Instructions, p. 90
94def LDSB: F3_2<3, 0b001001,
95               (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
96               "ldsb [$b+$c], $dst", []>;
97def LDSH: F3_2<3, 0b001010,
98               (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
99               "ldsh [$b+$c], $dst", []>;
100def LDUB: F3_2<3, 0b000001,
101               (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
102               "ldub [$b+$c], $dst", []>;
103def LDUH: F3_2<3, 0b000010,
104               (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
105               "lduh [$b+$c], $dst", []>;
106def LD  : F3_2<3, 0b000000,
107               (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
108               "ld [$b+$c], $dst", []>;
109def LDD : F3_2<3, 0b000011,
110               (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
111               "ldd [$b+$c], $dst", []>;
112
113// Section B.2 - Load Floating-point Instructions, p. 92
114def LDFrr  : F3_1<3, 0b100000,
115                  (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
116                  "ld [$b+$c], $dst", []>;
117def LDFri  : F3_2<3, 0b100000,
118                  (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
119                  "ld [$b+$c], $dst", []>;
120def LDDFrr : F3_1<3, 0b100011,
121                  (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
122                  "ldd [$b+$c], $dst", []>;
123def LDDFri : F3_2<3, 0b100011,
124                  (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
125                  "ldd [$b+$c], $dst", []>;
126def LDFSRrr: F3_1<3, 0b100001,
127                  (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
128                  "ld [$b+$c], $dst", []>;
129def LDFSRri: F3_2<3, 0b100001,
130                  (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
131                  "ld [$b+$c], $dst", []>;
132
133// Section B.4 - Store Integer Instructions, p. 95
134def STB : F3_2<3, 0b000101,
135               (ops IntRegs:$base, IntRegs:$offset, i32imm:$src),
136               "stb $src, [$base+$offset]", []>;
137def STH : F3_2<3, 0b000110,
138               (ops IntRegs:$base, IntRegs:$offset, i32imm:$src),
139               "sth $src, [$base+$offset]", []>;
140def ST  : F3_2<3, 0b000100,
141               (ops IntRegs:$base, IntRegs:$offset, i32imm:$src),
142               "st $src, [$base+$offset]", []>;
143def STD : F3_2<3, 0b000111,
144               (ops IntRegs:$base, IntRegs:$offset, i32imm:$src),
145               "std $src, [$base+$offset]", []>;
146
147// Section B.5 - Store Floating-point Instructions, p. 97
148def STFrr   : F3_1<3, 0b100100,
149                   (ops IntRegs:$base, IntRegs:$offset, IntRegs:$src),
150                   "st $src, [$base+$offset]", []>;
151def STFri   : F3_2<3, 0b100100,
152                   (ops IntRegs:$base, IntRegs:$offset, i32imm:$src),
153                   "st $src, [$base+$offset]", []>;
154def STDFrr  : F3_1<3, 0b100111,
155                   (ops IntRegs:$base, IntRegs:$offset, IntRegs:$src),
156                   "std  $src, [$base+$offset]", []>;
157def STDFri  : F3_2<3, 0b100111,
158                   (ops IntRegs:$base, IntRegs:$offset, i32imm:$src),
159                   "std $src, [$base+$offset]", []>;
160def STFSRrr : F3_1<3, 0b100101,
161                   (ops IntRegs:$base, IntRegs:$offset, IntRegs:$src),
162                   "st $src, [$base+$offset]", []>;
163def STFSRri : F3_2<3, 0b100101,
164                   (ops IntRegs:$base, IntRegs:$offset, i32imm:$src),
165                   "st $src, [$base+$offset]", []>;
166def STDFQrr : F3_1<3, 0b100110,
167                   (ops IntRegs:$base, IntRegs:$offset, IntRegs:$src),
168                   "std $src, [$base+$offset]", []>;
169def STDFQri : F3_2<3, 0b100110,
170                   (ops IntRegs:$base, IntRegs:$offset, i32imm:$src),
171                   "std $src, [$base+$offset]", []>;
172
173// Section B.9 - SETHI Instruction, p. 104
174def SETHIi: F2_1<0b100,
175                 (ops IntRegs:$dst, i32imm:$src),
176                 "sethi $src, $dst",
177                 [(set IntRegs:$dst, SETHIimm:$src)]>;
178
179// Section B.10 - NOP Instruction, p. 105
180// (It's a special case of SETHI)
181let rd = 0, imm22 = 0 in
182  def NOP : F2_1<0b100, (ops), "nop", []>;
183
184// Section B.11 - Logical Instructions, p. 106
185def ANDrr   : F3_1<2, 0b000001,
186                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
187                   "and $b, $c, $dst",
188                   [(set IntRegs:$dst, (and IntRegs:$b, IntRegs:$c))]>;
189def ANDri   : F3_2<2, 0b000001,
190                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
191                   "and $b, $c, $dst",
192                   [(set IntRegs:$dst, (and IntRegs:$b, simm13:$c))]>;
193def ANDCCrr : F3_1<2, 0b010001,
194                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
195                   "andcc $b, $c, $dst", []>;
196def ANDCCri : F3_2<2, 0b010001,
197                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
198                   "andcc $b, $c, $dst", []>;
199def ANDNrr  : F3_1<2, 0b000101,
200                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
201                   "andn $b, $c, $dst", []>;
202def ANDNri  : F3_2<2, 0b000101,
203                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
204                   "andn $b, $c, $dst", []>;
205def ANDNCCrr: F3_1<2, 0b010101,
206                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
207                   "andncc $b, $c, $dst", []>;
208def ANDNCCri: F3_2<2, 0b010101,
209                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
210                   "andncc $b, $c, $dst", []>;
211def ORrr    : F3_1<2, 0b000010,
212                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
213                   "or $b, $c, $dst",
214                   [(set IntRegs:$dst, (or IntRegs:$b, IntRegs:$c))]>;
215def ORri    : F3_2<2, 0b000010,
216                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
217                   "or $b, $c, $dst",
218                   [(set IntRegs:$dst, (or IntRegs:$b, simm13:$c))]>;
219def ORCCrr  : F3_1<2, 0b010010,
220                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
221                   "orcc $b, $c, $dst", []>;
222def ORCCri  : F3_2<2, 0b010010,
223                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
224                   "orcc $b, $c, $dst", []>;
225def ORNrr   : F3_1<2, 0b000110,
226                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
227                   "orn $b, $c, $dst", []>;
228def ORNri   : F3_2<2, 0b000110,
229                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
230                   "orn $b, $c, $dst", []>;
231def ORNCCrr : F3_1<2, 0b010110,
232                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
233                   "orncc $b, $c, $dst", []>;
234def ORNCCri : F3_2<2, 0b010110,
235                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
236                   "orncc $b, $c, $dst", []>;
237def XORrr   : F3_1<2, 0b000011,
238                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
239                   "xor $b, $c, $dst",
240                   [(set IntRegs:$dst, (xor IntRegs:$b, IntRegs:$c))]>;
241def XORri   : F3_2<2, 0b000011,
242                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
243                   "xor $b, $c, $dst",
244                   [(set IntRegs:$dst, (xor IntRegs:$b, simm13:$c))]>;
245def XORCCrr : F3_1<2, 0b010011,
246                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
247                   "xorcc $b, $c, $dst", []>;
248def XORCCri : F3_2<2, 0b010011,
249                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
250                   "xorcc $b, $c, $dst", []>;
251def XNORrr  : F3_1<2, 0b000111,
252                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
253                   "xnor $b, $c, $dst", []>;
254def XNORri  : F3_2<2, 0b000111,
255                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
256                   "xnor $b, $c, $dst", []>;
257def XNORCCrr: F3_1<2, 0b010111,
258                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
259                   "xnorcc $b, $c, $dst", []>;
260def XNORCCri: F3_2<2, 0b010111,
261                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
262                   "xnorcc $b, $c, $dst", []>;
263
264// Section B.12 - Shift Instructions, p. 107
265def SLLrr : F3_1<2, 0b100101,
266                 (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
267                 "sll $b, $c, $dst",
268                 [(set IntRegs:$dst, (shl IntRegs:$b, IntRegs:$c))]>;
269def SLLri : F3_2<2, 0b100101,
270                 (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
271                 "sll $b, $c, $dst",
272                 [(set IntRegs:$dst, (shl IntRegs:$b, simm13:$c))]>;
273def SRLrr : F3_1<2, 0b100110, 
274                 (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
275                  "srl $b, $c, $dst",
276                  [(set IntRegs:$dst, (srl IntRegs:$b, IntRegs:$c))]>;
277def SRLri : F3_2<2, 0b100110,
278                 (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
279                 "srl $b, $c, $dst", 
280                 [(set IntRegs:$dst, (srl IntRegs:$b, simm13:$c))]>;
281def SRArr : F3_1<2, 0b100111, 
282                 (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
283                  "sra $b, $c, $dst",
284                  [(set IntRegs:$dst, (sra IntRegs:$b, IntRegs:$c))]>;
285def SRAri : F3_2<2, 0b100111,
286                 (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
287                 "sra $b, $c, $dst",
288                 [(set IntRegs:$dst, (sra IntRegs:$b, simm13:$c))]>;
289
290// Section B.13 - Add Instructions, p. 108
291def ADDrr   : F3_1<2, 0b000000, 
292                  (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
293                  "add $b, $c, $dst",
294                   [(set IntRegs:$dst, (add IntRegs:$b, IntRegs:$c))]>;
295def ADDri   : F3_2<2, 0b000000,
296                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
297                   "add $b, $c, $dst",
298                   [(set IntRegs:$dst, (add IntRegs:$b, simm13:$c))]>;
299def ADDCCrr : F3_1<2, 0b010000, 
300                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
301                   "addcc $b, $c, $dst", []>;
302def ADDCCri : F3_2<2, 0b010000,
303                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
304                   "addcc $b, $c, $dst", []>;
305def ADDXrr  : F3_1<2, 0b001000, 
306                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
307                   "addx $b, $c, $dst", []>;
308def ADDXri  : F3_2<2, 0b001000,
309                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
310                   "addx $b, $c, $dst", []>;
311def ADDXCCrr: F3_1<2, 0b011000, 
312                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
313                   "addxcc $b, $c, $dst", []>;
314def ADDXCCri: F3_2<2, 0b011000,
315                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
316                   "addxcc $b, $c, $dst", []>;
317
318// Section B.15 - Subtract Instructions, p. 110
319def SUBrr   : F3_1<2, 0b000100, 
320                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
321                   "sub $b, $c, $dst",
322                   [(set IntRegs:$dst, (sub IntRegs:$b, IntRegs:$c))]>;
323def SUBri   : F3_2<2, 0b000100,
324                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
325                   "sub $b, $c, $dst",
326                   [(set IntRegs:$dst, (sub IntRegs:$b, simm13:$c))]>;
327def SUBCCrr : F3_1<2, 0b010100, 
328                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
329                   "subcc $b, $c, $dst", []>;
330def SUBCCri : F3_2<2, 0b010100,
331                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
332                   "subcc $b, $c, $dst", []>;
333def SUBXrr  : F3_1<2, 0b001100, 
334                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
335                   "subx $b, $c, $dst", []>;
336def SUBXri  : F3_2<2, 0b001100,
337                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
338                   "subx $b, $c, $dst", []>;
339def SUBXCCrr: F3_1<2, 0b011100, 
340                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
341                   "subxcc $b, $c, $dst", []>;
342def SUBXCCri: F3_2<2, 0b011100,
343                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
344                   "subxcc $b, $c, $dst", []>;
345
346// Section B.18 - Multiply Instructions, p. 113
347def UMULrr  : F3_1<2, 0b001010, 
348                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
349                   "umul $b, $c, $dst", []>;
350def UMULri  : F3_2<2, 0b001010,
351                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
352                   "umul $b, $c, $dst", []>;
353def SMULrr  : F3_1<2, 0b001011, 
354                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
355                   "smul $b, $c, $dst", []>;
356def SMULri  : F3_2<2, 0b001011,
357                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
358                   "smul $b, $c, $dst", []>;
359def UMULCCrr: F3_1<2, 0b011010, 
360                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
361                   "umulcc $b, $c, $dst", []>;
362def UMULCCri: F3_2<2, 0b011010,
363                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
364                   "umulcc $b, $c, $dst", []>;
365def SMULCCrr: F3_1<2, 0b011011, 
366                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
367                   "smulcc $b, $c, $dst", []>;
368def SMULCCri: F3_2<2, 0b011011,
369                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
370                   "smulcc $b, $c, $dst", []>;
371
372// Section B.19 - Divide Instructions, p. 115
373def UDIVrr   : F3_1<2, 0b001110, 
374                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
375                    "udiv $b, $c, $dst", []>;
376def UDIVri   : F3_2<2, 0b001110,
377                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
378                    "udiv $b, $c, $dst", []>;
379def SDIVrr   : F3_1<2, 0b001111,
380                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
381                    "sdiv $b, $c, $dst", []>;
382def SDIVri   : F3_2<2, 0b001111,
383                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
384                    "sdiv $b, $c, $dst", []>;
385def UDIVCCrr : F3_1<2, 0b011110,
386                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
387                    "udivcc $b, $c, $dst", []>;
388def UDIVCCri : F3_2<2, 0b011110,
389                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
390                    "udivcc $b, $c, $dst", []>;
391def SDIVCCrr : F3_1<2, 0b011111,
392                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
393                    "sdivcc $b, $c, $dst", []>;
394def SDIVCCri : F3_2<2, 0b011111,
395                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
396                    "sdivcc $b, $c, $dst", []>;
397
398// Section B.20 - SAVE and RESTORE, p. 117
399def SAVErr    : F3_1<2, 0b111100,
400                     (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
401                     "save $b, $c, $dst", []>;
402def SAVEri    : F3_2<2, 0b111100,
403                     (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
404                     "save $b, $c, $dst", []>;
405def RESTORErr : F3_1<2, 0b111101,
406                     (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
407                     "restore $b, $c, $dst", []>;
408def RESTOREri : F3_2<2, 0b111101,
409                     (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
410                     "restore $b, $c, $dst", []>;
411
412// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119
413
414// conditional branch class:
415class BranchV8<bits<4> cc, dag ops, string asmstr>
416 : F2_2<cc, 0b010, ops, asmstr> {
417  let isBranch = 1;
418  let isTerminator = 1;
419  let hasDelaySlot = 1;
420}
421
422let isBarrier = 1 in
423  def BA   : BranchV8<0b1000, (ops IntRegs:$dst), "ba $dst">;
424def BN   : BranchV8<0b0000, (ops IntRegs:$dst), "bn $dst">;
425def BNE  : BranchV8<0b1001, (ops IntRegs:$dst), "bne $dst">;
426def BE   : BranchV8<0b0001, (ops IntRegs:$dst), "be $dst">;
427def BG   : BranchV8<0b1010, (ops IntRegs:$dst), "bg $dst">;
428def BLE  : BranchV8<0b0010, (ops IntRegs:$dst), "ble $dst">;
429def BGE  : BranchV8<0b1011, (ops IntRegs:$dst), "bge $dst">;
430def BL   : BranchV8<0b0011, (ops IntRegs:$dst), "bl $dst">;
431def BGU  : BranchV8<0b1100, (ops IntRegs:$dst), "bgu $dst">;
432def BLEU : BranchV8<0b0100, (ops IntRegs:$dst), "bleu $dst">;
433def BCC  : BranchV8<0b1101, (ops IntRegs:$dst), "bcc $dst">;
434def BCS  : BranchV8<0b0101, (ops IntRegs:$dst), "bcs $dst">;
435
436// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
437
438// floating-point conditional branch class:
439class FPBranchV8<bits<4> cc, dag ops, string asmstr>
440 : F2_2<cc, 0b110, ops, asmstr> {
441  let isBranch = 1;
442  let isTerminator = 1;
443  let hasDelaySlot = 1;
444}
445
446def FBA  : FPBranchV8<0b1000, (ops IntRegs:$dst), "fba $dst">;
447def FBN  : FPBranchV8<0b0000, (ops IntRegs:$dst), "fbn $dst">;
448def FBU  : FPBranchV8<0b0111, (ops IntRegs:$dst), "fbu $dst">;
449def FBG  : FPBranchV8<0b0110, (ops IntRegs:$dst), "fbg $dst">;
450def FBUG : FPBranchV8<0b0101, (ops IntRegs:$dst), "fbug $dst">;
451def FBL  : FPBranchV8<0b0100, (ops IntRegs:$dst), "fbl $dst">;
452def FBUL : FPBranchV8<0b0011, (ops IntRegs:$dst), "fbul $dst">;
453def FBLG : FPBranchV8<0b0010, (ops IntRegs:$dst), "fblg $dst">;
454def FBNE : FPBranchV8<0b0001, (ops IntRegs:$dst), "fbne $dst">;
455def FBE  : FPBranchV8<0b1001, (ops IntRegs:$dst), "fbe $dst">;
456def FBUE : FPBranchV8<0b1010, (ops IntRegs:$dst), "fbue $dst">;
457def FBGE : FPBranchV8<0b1011, (ops IntRegs:$dst), "fbge $dst">;
458def FBUGE: FPBranchV8<0b1100, (ops IntRegs:$dst), "fbuge $dst">;
459def FBLE : FPBranchV8<0b1101, (ops IntRegs:$dst), "fble $dst">;
460def FBULE: FPBranchV8<0b1110, (ops IntRegs:$dst), "fbule $dst">;
461def FBO  : FPBranchV8<0b1111, (ops IntRegs:$dst), "fbo $dst">;
462
463
464
465// Section B.24 - Call and Link Instruction, p. 125
466// This is the only Format 1 instruction
467let Uses = [O0, O1, O2, O3, O4, O5], hasDelaySlot = 1, isCall = 1 in { 
468  // pc-relative call:
469  let Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
470    D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in
471  def CALL : InstV8 {
472    let OperandList = (ops IntRegs:$dst);
473    bits<30> disp;
474    let op = 1;
475    let Inst{29-0} = disp;
476    let AsmString = "call $dst";
477  }
478
479  // indirect call (O7 is an EXPLICIT def in indirect calls, so it cannot also
480  // be an implicit def):
481  let Defs = [O0, O1, O2, O3, O4, O5, G1, G2, G3, G4, G5, G6, G7,
482    D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in
483  def JMPLrr : F3_1<2, 0b111000,
484                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
485                    "jmpl $b+$c, $dst", []>;
486}
487
488// Section B.29 - Write State Register Instructions
489def WRrr : F3_1<2, 0b110000,
490                (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
491                "wr $b, $c, $dst", []>;
492def WRri : F3_2<2, 0b110000,
493                (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
494                "wr $b, $c, $dst", []>;
495
496// Convert Integer to Floating-point Instructions, p. 141
497def FITOS : F3_3<2, 0b110100, 0b011000100,
498                 (ops FPRegs:$dst, FPRegs:$src),
499                 "fitos $src, $dst">;
500def FITOD : F3_3<2, 0b110100, 0b011001000, 
501                 (ops DFPRegs:$dst, DFPRegs:$src),
502                 "fitod $src, $dst">;
503
504// Convert Floating-point to Integer Instructions, p. 142
505def FSTOI : F3_3<2, 0b110100, 0b011010001,
506                 (ops FPRegs:$dst, FPRegs:$src),
507                 "fstoi $src, $dst">;
508def FDTOI : F3_3<2, 0b110100, 0b011010010,
509                 (ops DFPRegs:$dst, DFPRegs:$src),
510                 "fdtoi $src, $dst">;
511
512// Convert between Floating-point Formats Instructions, p. 143
513def FSTOD : F3_3<2, 0b110100, 0b011001001, 
514                 (ops DFPRegs:$dst, FPRegs:$src),
515                 "fstod $src, $dst">;
516def FDTOS : F3_3<2, 0b110100, 0b011000110,
517                 (ops FPRegs:$dst, DFPRegs:$src),
518                 "fdtos $src, $dst">;
519
520// Floating-point Move Instructions, p. 144
521def FMOVS : F3_3<2, 0b110100, 0b000000001,
522                 (ops FPRegs:$dst, FPRegs:$src),
523                 "fmovs $src, $dst">;
524def FNEGS : F3_3<2, 0b110100, 0b000000101, 
525                 (ops FPRegs:$dst, FPRegs:$src),
526                 "fnegs $src, $dst">;
527def FABSS : F3_3<2, 0b110100, 0b000001001, 
528                 (ops FPRegs:$dst, FPRegs:$src),
529                 "fabss $src, $dst">;
530
531// Floating-point Add and Subtract Instructions, p. 146
532def FADDS  : F3_3<2, 0b110100, 0b001000001,
533                  (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
534                  "fadds $src1, $src2, $dst">;
535def FADDD  : F3_3<2, 0b110100, 0b001000010,
536                  (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
537                  "faddd $src1, $src2, $dst">;
538def FSUBS  : F3_3<2, 0b110100, 0b001000101,
539                  (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
540                  "fsubs $src1, $src2, $dst">;
541def FSUBD  : F3_3<2, 0b110100, 0b001000110,
542                  (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
543                  "fsubd $src1, $src2, $dst">;
544
545// Floating-point Multiply and Divide Instructions, p. 147
546def FMULS  : F3_3<2, 0b110100, 0b001001001,
547                  (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
548                  "fmuls $src1, $src2, $dst">;
549def FMULD  : F3_3<2, 0b110100, 0b001001010,
550                  (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
551                  "fmuld $src1, $src2, $dst">;
552def FSMULD : F3_3<2, 0b110100, 0b001101001,
553                  (ops DFPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
554                  "fsmuld $src1, $src2, $dst">;
555def FDIVS  : F3_3<2, 0b110100, 0b001001101,
556                 (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
557                 "fdivs $src1, $src2, $dst">;
558def FDIVD  : F3_3<2, 0b110100, 0b001001110,
559                 (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
560                 "fdivd $src1, $src2, $dst">;
561
562// Floating-point Compare Instructions, p. 148
563// Note: the 2nd template arg is different for these guys.
564// Note 2: the result of a FCMP is not available until the 2nd cycle
565// after the instr is retired, but there is no interlock. This behavior
566// is modelled with a forced noop after the instruction.
567def FCMPS  : F3_3<2, 0b110101, 0b001010001,
568                  (ops FPRegs:$src1, FPRegs:$src2),
569                  "fcmps $src1, $src2\n\tnop">;
570def FCMPD  : F3_3<2, 0b110101, 0b001010010,
571                  (ops DFPRegs:$src1, DFPRegs:$src2),
572                  "fcmpd $src1, $src2\n\tnop">;
573def FCMPES : F3_3<2, 0b110101, 0b001010101,
574                  (ops FPRegs:$src1, FPRegs:$src2),
575                  "fcmpes $src1, $src2\n\tnop">;
576def FCMPED : F3_3<2, 0b110101, 0b001010110,
577                  (ops DFPRegs:$src1, DFPRegs:$src2),
578                  "fcmped $src1, $src2\n\tnop">;
579
580//===----------------------------------------------------------------------===//
581// Non-Instruction Patterns
582//===----------------------------------------------------------------------===//
583
584// Small immediates.
585def : Pat<(i32 simm13:$val),
586          (ORri G0, imm:$val)>;
587// Arbitrary immediates.
588def : Pat<(i32 imm:$val),
589          (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;