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