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