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