SparcInstrInfo.td revision 6788faa06ad77fbfb57db7bcf8bc6a79389775a6
147997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//===- SparcV8Instrs.td - Target Description for SparcV8 Target -----------===//
247997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf// 
347997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//                     The LLVM Compiler Infrastructure
447997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//
547997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf// This file was developed by the LLVM research group and is distributed under
647997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf// the University of Illinois Open Source License. See LICENSE.TXT for details.
747997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf// 
847997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//===----------------------------------------------------------------------===//
947997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//
1047997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf// This file describes the SparcV8 instructions in TableGen format.
1147997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//
1247997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//===----------------------------------------------------------------------===//
1347997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf
1447997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//===----------------------------------------------------------------------===//
1547997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf// Instruction format superclass
1647997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//===----------------------------------------------------------------------===//
1747997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf
1847997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalfinclude "SparcV8InstrFormats.td"
1947997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf
2047997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//===----------------------------------------------------------------------===//
2147997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf// Feature predicates.
2247997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf//===----------------------------------------------------------------------===//
2347997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf
2447997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf// HasV9 - This predicate is true when the target processor supports V9
2547997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalf// instructions.  Note that the machine may be running in 32-bit mode.
2647997265eeb7d954a32ece693bbe6dab740872ddAdam Metcalfdef HasV9   : Predicate<"Subtarget.isV9()">;
27
28// HasNoV9 - This predicate is true when the target doesn't have V9
29// instructions.  Use of this is just a hack for the isel not having proper
30// costs for V8 instructions that are more expensive than their V9 ones.
31def HasNoV9 : Predicate<"!Subtarget.isV9()">;
32
33// HasVIS - This is true when the target processor has VIS extensions.
34def HasVIS : Predicate<"Subtarget.isVIS()">;
35
36// UseDeprecatedInsts - This predicate is true when the target processor is a
37// V8, or when it is V9 but the V8 deprecated instructions are efficient enough
38// to use when appropriate.  In either of these cases, the instruction selector
39// will pick deprecated instructions.
40def UseDeprecatedInsts : Predicate<"Subtarget.useDeprecatedV8Instructions()">;
41
42//===----------------------------------------------------------------------===//
43// Instruction Pattern Stuff
44//===----------------------------------------------------------------------===//
45
46def simm11  : PatLeaf<(imm), [{
47  // simm11 predicate - True if the imm fits in a 11-bit sign extended field.
48  return (((int)N->getValue() << (32-11)) >> (32-11)) == (int)N->getValue();
49}]>;
50
51def simm13  : PatLeaf<(imm), [{
52  // simm13 predicate - True if the imm fits in a 13-bit sign extended field.
53  return (((int)N->getValue() << (32-13)) >> (32-13)) == (int)N->getValue();
54}]>;
55
56def LO10 : SDNodeXForm<imm, [{
57  return CurDAG->getTargetConstant((unsigned)N->getValue() & 1023, MVT::i32);
58}]>;
59
60def HI22 : SDNodeXForm<imm, [{
61  // Transformation function: shift the immediate value down into the low bits.
62  return CurDAG->getTargetConstant((unsigned)N->getValue() >> 10, MVT::i32);
63}]>;
64
65def SETHIimm : PatLeaf<(imm), [{
66  return (((unsigned)N->getValue() >> 10) << 10) == (unsigned)N->getValue();
67}], HI22>;
68
69// Addressing modes.
70def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", []>;
71def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", []>;
72
73// Address operands
74def MEMrr : Operand<i32> {
75  let PrintMethod = "printMemOperand";
76  let NumMIOperands = 2;
77  let MIOperandInfo = (ops IntRegs, IntRegs);
78}
79def MEMri : Operand<i32> {
80  let PrintMethod = "printMemOperand";
81  let NumMIOperands = 2;
82  let MIOperandInfo = (ops IntRegs, i32imm);
83}
84
85// Branch targets have OtherVT type.
86def brtarget : Operand<OtherVT>;
87def calltarget : Operand<i32>;
88
89// Operand for printing out a condition code.
90let PrintMethod = "printV8CCOperand" in
91  def V8CC : Operand<i32>;
92
93def SDTV8cmpfcc : 
94SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>;
95def SDTV8brcc : 
96SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>,
97                     SDTCisVT<2, FlagVT>]>;
98def SDTV8selectcc :
99SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 
100                     SDTCisVT<3, i32>, SDTCisVT<4, FlagVT>]>;
101def SDTV8FTOI :
102SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;
103def SDTV8ITOF :
104SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
105
106def V8cmpicc : SDNode<"V8ISD::CMPICC", SDTIntBinOp, [SDNPOutFlag]>;
107def V8cmpfcc : SDNode<"V8ISD::CMPFCC", SDTV8cmpfcc, [SDNPOutFlag]>;
108def V8bricc : SDNode<"V8ISD::BRICC", SDTV8brcc, [SDNPHasChain]>;
109def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>;
110
111def V8hi    : SDNode<"V8ISD::Hi", SDTIntUnaryOp>;
112def V8lo    : SDNode<"V8ISD::Lo", SDTIntUnaryOp>;
113
114def V8ftoi  : SDNode<"V8ISD::FTOI", SDTV8FTOI>;
115def V8itof  : SDNode<"V8ISD::ITOF", SDTV8ITOF>;
116
117def V8selecticc : SDNode<"V8ISD::SELECT_ICC", SDTV8selectcc>;
118def V8selectfcc : SDNode<"V8ISD::SELECT_FCC", SDTV8selectcc>;
119
120// These are target-independent nodes, but have target-specific formats.
121def SDT_V8CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
122def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_V8CallSeq, [SDNPHasChain]>;
123def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_V8CallSeq, [SDNPHasChain]>;
124
125def SDT_V8Call    : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
126def call          : SDNode<"V8ISD::CALL", SDT_V8Call,
127	                   [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
128
129def SDT_V8RetFlag : SDTypeProfile<0, 0, []>;
130def retflag       : SDNode<"V8ISD::RET_FLAG", SDT_V8RetFlag,
131	                   [SDNPHasChain, SDNPOptInFlag]>;
132
133//===----------------------------------------------------------------------===//
134// SPARC Flag Conditions
135//===----------------------------------------------------------------------===//
136
137// Note that these values must be kept in sync with the V8CC::CondCode enum
138// values.
139class ICC_VAL<int N> : PatLeaf<(i32 N)> {
140 int ICCVal = N;
141}
142def ICC_NE  : ICC_VAL< 9>;  // Not Equal
143def ICC_E   : ICC_VAL< 1>;  // Equal
144def ICC_G   : ICC_VAL<10>;  // Greater
145def ICC_LE  : ICC_VAL< 2>;  // Less or Equal
146def ICC_GE  : ICC_VAL<11>;  // Greater or Equal
147def ICC_L   : ICC_VAL< 3>;  // Less
148def ICC_GU  : ICC_VAL<12>;  // Greater Unsigned
149def ICC_LEU : ICC_VAL< 4>;  // Less or Equal Unsigned
150def ICC_CC  : ICC_VAL<13>;  // Carry Clear/Great or Equal Unsigned
151def ICC_CS  : ICC_VAL< 5>;  // Carry Set/Less Unsigned
152def ICC_POS : ICC_VAL<14>;  // Positive
153def ICC_NEG : ICC_VAL< 6>;  // Negative
154def ICC_VC  : ICC_VAL<15>;  // Overflow Clear
155def ICC_VS  : ICC_VAL< 7>;  // Overflow Set
156
157class FCC_VAL<int N> : PatLeaf<(i32 N)> {
158  int FCCVal = N;
159}
160def FCC_U   : FCC_VAL<23>;  // Unordered
161def FCC_G   : FCC_VAL<22>;  // Greater
162def FCC_UG  : FCC_VAL<21>;  // Unordered or Greater
163def FCC_L   : FCC_VAL<20>;  // Less
164def FCC_UL  : FCC_VAL<19>;  // Unordered or Less
165def FCC_LG  : FCC_VAL<18>;  // Less or Greater
166def FCC_NE  : FCC_VAL<17>;  // Not Equal
167def FCC_E   : FCC_VAL<25>;  // Equal
168def FCC_UE  : FCC_VAL<24>;  // Unordered or Equal
169def FCC_GE  : FCC_VAL<25>;  // Greater or Equal
170def FCC_UGE : FCC_VAL<26>;  // Unordered or Greater or Equal
171def FCC_LE  : FCC_VAL<27>;  // Less or Equal
172def FCC_ULE : FCC_VAL<28>;  // Unordered or Less or Equal
173def FCC_O   : FCC_VAL<29>;  // Ordered
174
175
176//===----------------------------------------------------------------------===//
177// Instructions
178//===----------------------------------------------------------------------===//
179
180// Pseudo instructions.
181class Pseudo<dag ops, string asmstr, list<dag> pattern>
182   : InstV8<ops, asmstr, pattern>;
183
184def ADJCALLSTACKDOWN : Pseudo<(ops i32imm:$amt),
185                               "!ADJCALLSTACKDOWN $amt",
186                               [(callseq_start imm:$amt)]>;
187def ADJCALLSTACKUP : Pseudo<(ops i32imm:$amt),
188                            "!ADJCALLSTACKUP $amt",
189                            [(callseq_end imm:$amt)]>;
190def IMPLICIT_DEF_Int : Pseudo<(ops IntRegs:$dst),
191                              "!IMPLICIT_DEF $dst",
192                              [(set IntRegs:$dst, (undef))]>;
193def IMPLICIT_DEF_FP  : Pseudo<(ops FPRegs:$dst), "!IMPLICIT_DEF $dst",
194                              [(set FPRegs:$dst, (undef))]>;
195def IMPLICIT_DEF_DFP : Pseudo<(ops DFPRegs:$dst), "!IMPLICIT_DEF $dst",
196                              [(set DFPRegs:$dst, (undef))]>;
197                              
198// FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the 
199// fpmover pass.
200let Predicates = [HasNoV9] in {  // Only emit these in V8 mode.
201  def FpMOVD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src),
202                      "!FpMOVD $src, $dst", []>;
203  def FpNEGD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src),
204                      "!FpNEGD $src, $dst",
205                      [(set DFPRegs:$dst, (fneg DFPRegs:$src))]>;
206  def FpABSD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src),
207                      "!FpABSD $src, $dst",
208                      [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>;
209}
210
211// SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded by the
212// scheduler into a branch sequence.  This has to handle all permutations of
213// selection between i32/f32/f64 on ICC and FCC.
214let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
215  def SELECT_CC_Int_ICC
216   : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond),
217            "; SELECT_CC_Int_ICC PSEUDO!",
218            [(set IntRegs:$dst, (V8selecticc IntRegs:$T, IntRegs:$F,
219                                             imm:$Cond, ICC))]>, 
220                                             Requires<[HasNoV9]>;
221  def SELECT_CC_Int_FCC
222   : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond),
223            "; SELECT_CC_Int_FCC PSEUDO!",
224            [(set IntRegs:$dst, (V8selectfcc IntRegs:$T, IntRegs:$F,
225                                             imm:$Cond, FCC))]>, 
226                                             Requires<[HasNoV9]>;
227  def SELECT_CC_FP_ICC
228   : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond),
229            "; SELECT_CC_FP_ICC PSEUDO!",
230            [(set FPRegs:$dst, (V8selecticc FPRegs:$T, FPRegs:$F,
231                                            imm:$Cond, ICC))]>;
232  def SELECT_CC_FP_FCC
233   : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond),
234            "; SELECT_CC_FP_FCC PSEUDO!",
235            [(set FPRegs:$dst, (V8selectfcc FPRegs:$T, FPRegs:$F,
236                                            imm:$Cond, FCC))]>;
237  def SELECT_CC_DFP_ICC
238   : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, i32imm:$Cond),
239            "; SELECT_CC_DFP_ICC PSEUDO!",
240            [(set DFPRegs:$dst, (V8selecticc DFPRegs:$T, DFPRegs:$F,
241                                             imm:$Cond, ICC))]>;
242  def SELECT_CC_DFP_FCC
243   : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, i32imm:$Cond),
244            "; SELECT_CC_DFP_FCC PSEUDO!",
245            [(set DFPRegs:$dst, (V8selectfcc DFPRegs:$T, DFPRegs:$F,
246                                             imm:$Cond, FCC))]>;
247}
248
249
250// Section A.3 - Synthetic Instructions, p. 85
251// special cases of JMPL:
252let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, noResults = 1 in {
253  let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
254    def RETL: F3_2<2, 0b111000, (ops), "retl", [(retflag)]>;
255}
256
257// Section B.1 - Load Integer Instructions, p. 90
258def LDSBrr : F3_1<3, 0b001001,
259                  (ops IntRegs:$dst, MEMrr:$addr),
260                  "ldsb [$addr], $dst",
261                  [(set IntRegs:$dst, (sextload ADDRrr:$addr, i8))]>;
262def LDSBri : F3_2<3, 0b001001,
263                  (ops IntRegs:$dst, MEMri:$addr),
264                  "ldsb [$addr], $dst",
265                  [(set IntRegs:$dst, (sextload ADDRri:$addr, i8))]>;
266def LDSHrr : F3_1<3, 0b001010,
267                  (ops IntRegs:$dst, MEMrr:$addr),
268                  "ldsh [$addr], $dst",
269                  [(set IntRegs:$dst, (sextload ADDRrr:$addr, i16))]>;
270def LDSHri : F3_2<3, 0b001010,
271                  (ops IntRegs:$dst, MEMri:$addr),
272                  "ldsh [$addr], $dst",
273                  [(set IntRegs:$dst, (sextload ADDRri:$addr, i16))]>;
274def LDUBrr : F3_1<3, 0b000001,
275                  (ops IntRegs:$dst, MEMrr:$addr),
276                  "ldub [$addr], $dst",
277                  [(set IntRegs:$dst, (zextload ADDRrr:$addr, i8))]>;
278def LDUBri : F3_2<3, 0b000001,
279                  (ops IntRegs:$dst, MEMri:$addr),
280                  "ldub [$addr], $dst",
281                  [(set IntRegs:$dst, (zextload ADDRri:$addr, i8))]>;
282def LDUHrr : F3_1<3, 0b000010,
283                  (ops IntRegs:$dst, MEMrr:$addr),
284                  "lduh [$addr], $dst",
285                  [(set IntRegs:$dst, (zextload ADDRrr:$addr, i16))]>;
286def LDUHri : F3_2<3, 0b000010,
287                  (ops IntRegs:$dst, MEMri:$addr),
288                  "lduh [$addr], $dst",
289                  [(set IntRegs:$dst, (zextload ADDRri:$addr, i16))]>;
290def LDrr   : F3_1<3, 0b000000,
291                  (ops IntRegs:$dst, MEMrr:$addr),
292                  "ld [$addr], $dst",
293                  [(set IntRegs:$dst, (load ADDRrr:$addr))]>;
294def LDri   : F3_2<3, 0b000000,
295                  (ops IntRegs:$dst, MEMri:$addr),
296                  "ld [$addr], $dst",
297                  [(set IntRegs:$dst, (load ADDRri:$addr))]>;
298
299// Section B.2 - Load Floating-point Instructions, p. 92
300def LDFrr  : F3_1<3, 0b100000,
301                  (ops FPRegs:$dst, MEMrr:$addr),
302                  "ld [$addr], $dst",
303                  [(set FPRegs:$dst, (load ADDRrr:$addr))]>;
304def LDFri  : F3_2<3, 0b100000,
305                  (ops FPRegs:$dst, MEMri:$addr),
306                  "ld [$addr], $dst",
307                  [(set FPRegs:$dst, (load ADDRri:$addr))]>;
308def LDDFrr : F3_1<3, 0b100011,
309                  (ops DFPRegs:$dst, MEMrr:$addr),
310                  "ldd [$addr], $dst",
311                  [(set DFPRegs:$dst, (load ADDRrr:$addr))]>;
312def LDDFri : F3_2<3, 0b100011,
313                  (ops DFPRegs:$dst, MEMri:$addr),
314                  "ldd [$addr], $dst",
315                  [(set DFPRegs:$dst, (load ADDRri:$addr))]>;
316
317// Section B.4 - Store Integer Instructions, p. 95
318def STBrr : F3_1<3, 0b000101,
319                 (ops MEMrr:$addr, IntRegs:$src),
320                 "stb $src, [$addr]",
321                 [(truncstore IntRegs:$src, ADDRrr:$addr, i8)]>;
322def STBri : F3_2<3, 0b000101,
323                 (ops MEMri:$addr, IntRegs:$src),
324                 "stb $src, [$addr]",
325                 [(truncstore IntRegs:$src, ADDRri:$addr, i8)]>;
326def STHrr : F3_1<3, 0b000110,
327                 (ops MEMrr:$addr, IntRegs:$src),
328                 "sth $src, [$addr]",
329                 [(truncstore IntRegs:$src, ADDRrr:$addr, i16)]>;
330def STHri : F3_2<3, 0b000110,
331                 (ops MEMri:$addr, IntRegs:$src),
332                 "sth $src, [$addr]",
333                 [(truncstore IntRegs:$src, ADDRri:$addr, i16)]>;
334def STrr  : F3_1<3, 0b000100,
335                 (ops MEMrr:$addr, IntRegs:$src),
336                 "st $src, [$addr]",
337                 [(store IntRegs:$src, ADDRrr:$addr)]>;
338def STri  : F3_2<3, 0b000100,
339                 (ops MEMri:$addr, IntRegs:$src),
340                 "st $src, [$addr]",
341                 [(store IntRegs:$src, ADDRri:$addr)]>;
342
343// Section B.5 - Store Floating-point Instructions, p. 97
344def STFrr   : F3_1<3, 0b100100,
345                   (ops MEMrr:$addr, FPRegs:$src),
346                   "st $src, [$addr]",
347                   [(store FPRegs:$src, ADDRrr:$addr)]>;
348def STFri   : F3_2<3, 0b100100,
349                   (ops MEMri:$addr, FPRegs:$src),
350                   "st $src, [$addr]",
351                   [(store FPRegs:$src, ADDRri:$addr)]>;
352def STDFrr  : F3_1<3, 0b100111,
353                   (ops MEMrr:$addr, DFPRegs:$src),
354                   "std  $src, [$addr]",
355                   [(store DFPRegs:$src, ADDRrr:$addr)]>;
356def STDFri  : F3_2<3, 0b100111,
357                   (ops MEMri:$addr, DFPRegs:$src),
358                   "std $src, [$addr]",
359                   [(store DFPRegs:$src, ADDRri:$addr)]>;
360
361// Section B.9 - SETHI Instruction, p. 104
362def SETHIi: F2_1<0b100,
363                 (ops IntRegs:$dst, i32imm:$src),
364                 "sethi $src, $dst",
365                 [(set IntRegs:$dst, SETHIimm:$src)]>;
366
367// Section B.10 - NOP Instruction, p. 105
368// (It's a special case of SETHI)
369let rd = 0, imm22 = 0 in
370  def NOP : F2_1<0b100, (ops), "nop", []>;
371
372// Section B.11 - Logical Instructions, p. 106
373def ANDrr   : F3_1<2, 0b000001,
374                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
375                   "and $b, $c, $dst",
376                   [(set IntRegs:$dst, (and IntRegs:$b, IntRegs:$c))]>;
377def ANDri   : F3_2<2, 0b000001,
378                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
379                   "and $b, $c, $dst",
380                   [(set IntRegs:$dst, (and IntRegs:$b, simm13:$c))]>;
381def ANDNrr  : F3_1<2, 0b000101,
382                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
383                   "andn $b, $c, $dst",
384                   [(set IntRegs:$dst, (and IntRegs:$b, (not IntRegs:$c)))]>;
385def ANDNri  : F3_2<2, 0b000101,
386                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
387                   "andn $b, $c, $dst", []>;
388def ORrr    : F3_1<2, 0b000010,
389                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
390                   "or $b, $c, $dst",
391                   [(set IntRegs:$dst, (or IntRegs:$b, IntRegs:$c))]>;
392def ORri    : F3_2<2, 0b000010,
393                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
394                   "or $b, $c, $dst",
395                   [(set IntRegs:$dst, (or IntRegs:$b, simm13:$c))]>;
396def ORNrr   : F3_1<2, 0b000110,
397                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
398                   "orn $b, $c, $dst",
399                   [(set IntRegs:$dst, (or IntRegs:$b, (not IntRegs:$c)))]>;
400def ORNri   : F3_2<2, 0b000110,
401                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
402                   "orn $b, $c, $dst", []>;
403def XORrr   : F3_1<2, 0b000011,
404                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
405                   "xor $b, $c, $dst",
406                   [(set IntRegs:$dst, (xor IntRegs:$b, IntRegs:$c))]>;
407def XORri   : F3_2<2, 0b000011,
408                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
409                   "xor $b, $c, $dst",
410                   [(set IntRegs:$dst, (xor IntRegs:$b, simm13:$c))]>;
411def XNORrr  : F3_1<2, 0b000111,
412                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
413                   "xnor $b, $c, $dst",
414                   [(set IntRegs:$dst, (not (xor IntRegs:$b, IntRegs:$c)))]>;
415def XNORri  : F3_2<2, 0b000111,
416                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
417                   "xnor $b, $c, $dst", []>;
418
419// Section B.12 - Shift Instructions, p. 107
420def SLLrr : F3_1<2, 0b100101,
421                 (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
422                 "sll $b, $c, $dst",
423                 [(set IntRegs:$dst, (shl IntRegs:$b, IntRegs:$c))]>;
424def SLLri : F3_2<2, 0b100101,
425                 (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
426                 "sll $b, $c, $dst",
427                 [(set IntRegs:$dst, (shl IntRegs:$b, simm13:$c))]>;
428def SRLrr : F3_1<2, 0b100110, 
429                 (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
430                  "srl $b, $c, $dst",
431                  [(set IntRegs:$dst, (srl IntRegs:$b, IntRegs:$c))]>;
432def SRLri : F3_2<2, 0b100110,
433                 (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
434                 "srl $b, $c, $dst", 
435                 [(set IntRegs:$dst, (srl IntRegs:$b, simm13:$c))]>;
436def SRArr : F3_1<2, 0b100111, 
437                 (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
438                  "sra $b, $c, $dst",
439                  [(set IntRegs:$dst, (sra IntRegs:$b, IntRegs:$c))]>;
440def SRAri : F3_2<2, 0b100111,
441                 (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
442                 "sra $b, $c, $dst",
443                 [(set IntRegs:$dst, (sra IntRegs:$b, simm13:$c))]>;
444
445// Section B.13 - Add Instructions, p. 108
446def ADDrr   : F3_1<2, 0b000000, 
447                  (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
448                  "add $b, $c, $dst",
449                   [(set IntRegs:$dst, (add IntRegs:$b, IntRegs:$c))]>;
450def ADDri   : F3_2<2, 0b000000,
451                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
452                   "add $b, $c, $dst",
453                   [(set IntRegs:$dst, (add IntRegs:$b, simm13:$c))]>;
454def ADDCCrr : F3_1<2, 0b010000, 
455                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
456                   "addcc $b, $c, $dst", []>;
457def ADDCCri : F3_2<2, 0b010000,
458                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
459                   "addcc $b, $c, $dst", []>;
460def ADDXrr  : F3_1<2, 0b001000, 
461                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
462                   "addx $b, $c, $dst", []>;
463def ADDXri  : F3_2<2, 0b001000,
464                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
465                   "addx $b, $c, $dst", []>;
466
467// Section B.15 - Subtract Instructions, p. 110
468def SUBrr   : F3_1<2, 0b000100, 
469                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
470                   "sub $b, $c, $dst",
471                   [(set IntRegs:$dst, (sub IntRegs:$b, IntRegs:$c))]>;
472def SUBri   : F3_2<2, 0b000100,
473                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
474                   "sub $b, $c, $dst",
475                   [(set IntRegs:$dst, (sub IntRegs:$b, simm13:$c))]>;
476def SUBXrr  : F3_1<2, 0b001100, 
477                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
478                   "subx $b, $c, $dst", []>;
479def SUBXri  : F3_2<2, 0b001100,
480                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
481                   "subx $b, $c, $dst", []>;
482def SUBCCrr : F3_1<2, 0b010100, 
483                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
484                   "subcc $b, $c, $dst",
485                   [(set IntRegs:$dst, (V8cmpicc IntRegs:$b, IntRegs:$c))]>;
486def SUBCCri : F3_2<2, 0b010100,
487                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
488                   "subcc $b, $c, $dst",
489                   [(set IntRegs:$dst, (V8cmpicc IntRegs:$b, simm13:$c))]>;
490def SUBXCCrr: F3_1<2, 0b011100, 
491                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
492                   "subxcc $b, $c, $dst", []>;
493
494// Section B.18 - Multiply Instructions, p. 113
495def UMULrr  : F3_1<2, 0b001010, 
496                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
497                   "umul $b, $c, $dst", []>;
498def UMULri  : F3_2<2, 0b001010,
499                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
500                   "umul $b, $c, $dst", []>;
501def SMULrr  : F3_1<2, 0b001011, 
502                   (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
503                   "smul $b, $c, $dst",
504                   [(set IntRegs:$dst, (mul IntRegs:$b, IntRegs:$c))]>;
505def SMULri  : F3_2<2, 0b001011,
506                   (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
507                   "smul $b, $c, $dst",
508                   [(set IntRegs:$dst, (mul IntRegs:$b, simm13:$c))]>;
509
510// Section B.19 - Divide Instructions, p. 115
511def UDIVrr   : F3_1<2, 0b001110, 
512                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
513                    "udiv $b, $c, $dst", []>;
514def UDIVri   : F3_2<2, 0b001110,
515                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
516                    "udiv $b, $c, $dst", []>;
517def SDIVrr   : F3_1<2, 0b001111,
518                    (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
519                    "sdiv $b, $c, $dst", []>;
520def SDIVri   : F3_2<2, 0b001111,
521                    (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
522                    "sdiv $b, $c, $dst", []>;
523
524// Section B.20 - SAVE and RESTORE, p. 117
525def SAVErr    : F3_1<2, 0b111100,
526                     (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
527                     "save $b, $c, $dst", []>;
528def SAVEri    : F3_2<2, 0b111100,
529                     (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
530                     "save $b, $c, $dst", []>;
531def RESTORErr : F3_1<2, 0b111101,
532                     (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c),
533                     "restore $b, $c, $dst", []>;
534def RESTOREri : F3_2<2, 0b111101,
535                     (ops IntRegs:$dst, IntRegs:$b, i32imm:$c),
536                     "restore $b, $c, $dst", []>;
537
538// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119
539
540// conditional branch class:
541class BranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
542 : F2_2<cc, 0b010, ops, asmstr, pattern> {
543  let isBranch = 1;
544  let isTerminator = 1;
545  let hasDelaySlot = 1;
546  let noResults = 1;
547}
548
549let isBarrier = 1 in
550  def BA   : BranchV8<0b1000, (ops brtarget:$dst),
551                      "ba $dst",
552                      [(br bb:$dst)]>;
553def BNE  : BranchV8<0b1001, (ops brtarget:$dst),
554                    "bne $dst",
555                    [(V8bricc bb:$dst, ICC_NE, ICC)]>;
556def BE   : BranchV8<0b0001, (ops brtarget:$dst),
557                    "be $dst",
558                    [(V8bricc bb:$dst, ICC_E, ICC)]>;
559def BG   : BranchV8<0b1010, (ops brtarget:$dst),
560                    "bg $dst",
561                    [(V8bricc bb:$dst, ICC_G, ICC)]>;
562def BLE  : BranchV8<0b0010, (ops brtarget:$dst),
563                    "ble $dst",
564                    [(V8bricc bb:$dst, ICC_LE, ICC)]>;
565def BGE  : BranchV8<0b1011, (ops brtarget:$dst),
566                    "bge $dst",
567                    [(V8bricc bb:$dst, ICC_GE, ICC)]>;
568def BL   : BranchV8<0b0011, (ops brtarget:$dst),
569                    "bl $dst",
570                    [(V8bricc bb:$dst, ICC_L, ICC)]>;
571def BGU  : BranchV8<0b1100, (ops brtarget:$dst),
572                    "bgu $dst",
573                    [(V8bricc bb:$dst, ICC_GU, ICC)]>;
574def BLEU : BranchV8<0b0100, (ops brtarget:$dst),
575                    "bleu $dst",
576                    [(V8bricc bb:$dst, ICC_LEU, ICC)]>;
577def BCC  : BranchV8<0b1101, (ops brtarget:$dst),
578                    "bcc $dst",
579                    [(V8bricc bb:$dst, ICC_CC, ICC)]>;
580def BCS  : BranchV8<0b0101, (ops brtarget:$dst),
581                    "bcs $dst",
582                    [(V8bricc bb:$dst, ICC_CS, ICC)]>;
583def BPOS : BranchV8<0b1110, (ops brtarget:$dst),
584                    "bpos $dst",
585                    [(V8bricc bb:$dst, ICC_POS, ICC)]>;
586def BNEG : BranchV8<0b0110, (ops brtarget:$dst),
587                    "bneg $dst",
588                    [(V8bricc bb:$dst, ICC_NEG, ICC)]>;
589def BVC  : BranchV8<0b1111, (ops brtarget:$dst),
590                    "bvc $dst",
591                    [(V8bricc bb:$dst, ICC_VC, ICC)]>;
592def BVS  : BranchV8<0b0111, (ops brtarget:$dst),
593                    "bvs $dst",
594                    [(V8bricc bb:$dst, ICC_VS, ICC)]>;
595
596
597
598// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
599
600// floating-point conditional branch class:
601class FPBranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
602 : F2_2<cc, 0b110, ops, asmstr, pattern> {
603  let isBranch = 1;
604  let isTerminator = 1;
605  let hasDelaySlot = 1;
606  let noResults = 1;
607}
608
609def FBU  : FPBranchV8<0b0111, (ops brtarget:$dst),
610                      "fbu $dst",
611                      [(V8brfcc bb:$dst, FCC_U, FCC)]>;
612def FBG  : FPBranchV8<0b0110, (ops brtarget:$dst),
613                      "fbg $dst",
614                      [(V8brfcc bb:$dst, FCC_G, FCC)]>;
615def FBUG : FPBranchV8<0b0101, (ops brtarget:$dst),
616                      "fbug $dst",
617                      [(V8brfcc bb:$dst, FCC_UG, FCC)]>;
618def FBL  : FPBranchV8<0b0100, (ops brtarget:$dst),
619                      "fbl $dst",
620                      [(V8brfcc bb:$dst, FCC_L, FCC)]>;
621def FBUL : FPBranchV8<0b0011, (ops brtarget:$dst),
622                      "fbul $dst",
623                      [(V8brfcc bb:$dst, FCC_UL, FCC)]>;
624def FBLG : FPBranchV8<0b0010, (ops brtarget:$dst),
625                      "fblg $dst",
626                      [(V8brfcc bb:$dst, FCC_LG, FCC)]>;
627def FBNE : FPBranchV8<0b0001, (ops brtarget:$dst),
628                      "fbne $dst",
629                      [(V8brfcc bb:$dst, FCC_NE, FCC)]>;
630def FBE  : FPBranchV8<0b1001, (ops brtarget:$dst),
631                      "fbe $dst",
632                      [(V8brfcc bb:$dst, FCC_E, FCC)]>;
633def FBUE : FPBranchV8<0b1010, (ops brtarget:$dst),
634                      "fbue $dst",
635                      [(V8brfcc bb:$dst, FCC_UE, FCC)]>;
636def FBGE : FPBranchV8<0b1011, (ops brtarget:$dst),
637                      "fbge $dst",
638                      [(V8brfcc bb:$dst, FCC_GE, FCC)]>;
639def FBUGE: FPBranchV8<0b1100, (ops brtarget:$dst),
640                      "fbuge $dst",
641                      [(V8brfcc bb:$dst, FCC_UGE, FCC)]>;
642def FBLE : FPBranchV8<0b1101, (ops brtarget:$dst),
643                      "fble $dst",
644                      [(V8brfcc bb:$dst, FCC_LE, FCC)]>;
645def FBULE: FPBranchV8<0b1110, (ops brtarget:$dst),
646                      "fbule $dst",
647                      [(V8brfcc bb:$dst, FCC_ULE, FCC)]>;
648def FBO  : FPBranchV8<0b1111, (ops brtarget:$dst),
649                      "fbo $dst",
650                      [(V8brfcc bb:$dst, FCC_O, FCC)]>;
651
652
653
654// Section B.24 - Call and Link Instruction, p. 125
655// This is the only Format 1 instruction
656let Uses = [O0, O1, O2, O3, O4, O5],
657    hasDelaySlot = 1, isCall = 1, noResults = 1,
658    Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
659    D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { 
660  def CALL : InstV8<(ops calltarget:$dst),
661                    "call $dst", []> {
662    bits<30> disp;
663    let op = 1;
664    let Inst{29-0} = disp;
665  }
666  
667  // indirect calls
668  def JMPLrr : F3_1<2, 0b111000,
669                    (ops MEMrr:$ptr),
670                    "call $ptr",
671                    [(call  ADDRrr:$ptr)]>;
672  def JMPLri : F3_2<2, 0b111000,
673                    (ops MEMri:$ptr),
674                    "call $ptr",
675                    [(call  ADDRri:$ptr)]>;
676}
677
678// Section B.28 - Read State Register Instructions
679def RDY : F3_1<2, 0b101000,
680               (ops IntRegs:$dst),
681               "rd %y, $dst", []>;
682
683// Section B.29 - Write State Register Instructions
684def WRYrr : F3_1<2, 0b110000,
685                 (ops IntRegs:$b, IntRegs:$c),
686                 "wr $b, $c, %y", []>;
687def WRYri : F3_2<2, 0b110000,
688                 (ops IntRegs:$b, i32imm:$c),
689                 "wr $b, $c, %y", []>;
690
691// Convert Integer to Floating-point Instructions, p. 141
692def FITOS : F3_3<2, 0b110100, 0b011000100,
693                 (ops FPRegs:$dst, FPRegs:$src),
694                 "fitos $src, $dst",
695                 [(set FPRegs:$dst, (V8itof FPRegs:$src))]>;
696def FITOD : F3_3<2, 0b110100, 0b011001000, 
697                 (ops DFPRegs:$dst, FPRegs:$src),
698                 "fitod $src, $dst",
699                 [(set DFPRegs:$dst, (V8itof FPRegs:$src))]>;
700
701// Convert Floating-point to Integer Instructions, p. 142
702def FSTOI : F3_3<2, 0b110100, 0b011010001,
703                 (ops FPRegs:$dst, FPRegs:$src),
704                 "fstoi $src, $dst",
705                 [(set FPRegs:$dst, (V8ftoi FPRegs:$src))]>;
706def FDTOI : F3_3<2, 0b110100, 0b011010010,
707                 (ops FPRegs:$dst, DFPRegs:$src),
708                 "fdtoi $src, $dst",
709                 [(set FPRegs:$dst, (V8ftoi DFPRegs:$src))]>;
710
711// Convert between Floating-point Formats Instructions, p. 143
712def FSTOD : F3_3<2, 0b110100, 0b011001001, 
713                 (ops DFPRegs:$dst, FPRegs:$src),
714                 "fstod $src, $dst",
715                 [(set DFPRegs:$dst, (fextend FPRegs:$src))]>;
716def FDTOS : F3_3<2, 0b110100, 0b011000110,
717                 (ops FPRegs:$dst, DFPRegs:$src),
718                 "fdtos $src, $dst",
719                 [(set FPRegs:$dst, (fround DFPRegs:$src))]>;
720
721// Floating-point Move Instructions, p. 144
722def FMOVS : F3_3<2, 0b110100, 0b000000001,
723                 (ops FPRegs:$dst, FPRegs:$src),
724                 "fmovs $src, $dst", []>;
725def FNEGS : F3_3<2, 0b110100, 0b000000101, 
726                 (ops FPRegs:$dst, FPRegs:$src),
727                 "fnegs $src, $dst",
728                 [(set FPRegs:$dst, (fneg FPRegs:$src))]>;
729def FABSS : F3_3<2, 0b110100, 0b000001001, 
730                 (ops FPRegs:$dst, FPRegs:$src),
731                 "fabss $src, $dst",
732                 [(set FPRegs:$dst, (fabs FPRegs:$src))]>;
733
734
735// Floating-point Square Root Instructions, p.145
736def FSQRTS : F3_3<2, 0b110100, 0b000101001, 
737                  (ops FPRegs:$dst, FPRegs:$src),
738                  "fsqrts $src, $dst",
739                  [(set FPRegs:$dst, (fsqrt FPRegs:$src))]>;
740def FSQRTD : F3_3<2, 0b110100, 0b000101010, 
741                  (ops DFPRegs:$dst, DFPRegs:$src),
742                  "fsqrtd $src, $dst",
743                  [(set DFPRegs:$dst, (fsqrt DFPRegs:$src))]>;
744
745
746
747// Floating-point Add and Subtract Instructions, p. 146
748def FADDS  : F3_3<2, 0b110100, 0b001000001,
749                  (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
750                  "fadds $src1, $src2, $dst",
751                  [(set FPRegs:$dst, (fadd FPRegs:$src1, FPRegs:$src2))]>;
752def FADDD  : F3_3<2, 0b110100, 0b001000010,
753                  (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
754                  "faddd $src1, $src2, $dst",
755                  [(set DFPRegs:$dst, (fadd DFPRegs:$src1, DFPRegs:$src2))]>;
756def FSUBS  : F3_3<2, 0b110100, 0b001000101,
757                  (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
758                  "fsubs $src1, $src2, $dst",
759                  [(set FPRegs:$dst, (fsub FPRegs:$src1, FPRegs:$src2))]>;
760def FSUBD  : F3_3<2, 0b110100, 0b001000110,
761                  (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
762                  "fsubd $src1, $src2, $dst",
763                  [(set DFPRegs:$dst, (fsub DFPRegs:$src1, DFPRegs:$src2))]>;
764
765// Floating-point Multiply and Divide Instructions, p. 147
766def FMULS  : F3_3<2, 0b110100, 0b001001001,
767                  (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
768                  "fmuls $src1, $src2, $dst",
769                  [(set FPRegs:$dst, (fmul FPRegs:$src1, FPRegs:$src2))]>;
770def FMULD  : F3_3<2, 0b110100, 0b001001010,
771                  (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
772                  "fmuld $src1, $src2, $dst",
773                  [(set DFPRegs:$dst, (fmul DFPRegs:$src1, DFPRegs:$src2))]>;
774def FSMULD : F3_3<2, 0b110100, 0b001101001,
775                  (ops DFPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
776                  "fsmuld $src1, $src2, $dst",
777                  [(set DFPRegs:$dst, (fmul (fextend FPRegs:$src1),
778                                            (fextend FPRegs:$src2)))]>;
779def FDIVS  : F3_3<2, 0b110100, 0b001001101,
780                 (ops FPRegs:$dst, FPRegs:$src1, FPRegs:$src2),
781                 "fdivs $src1, $src2, $dst",
782                 [(set FPRegs:$dst, (fdiv FPRegs:$src1, FPRegs:$src2))]>;
783def FDIVD  : F3_3<2, 0b110100, 0b001001110,
784                 (ops DFPRegs:$dst, DFPRegs:$src1, DFPRegs:$src2),
785                 "fdivd $src1, $src2, $dst",
786                 [(set DFPRegs:$dst, (fdiv DFPRegs:$src1, DFPRegs:$src2))]>;
787
788// Floating-point Compare Instructions, p. 148
789// Note: the 2nd template arg is different for these guys.
790// Note 2: the result of a FCMP is not available until the 2nd cycle
791// after the instr is retired, but there is no interlock. This behavior
792// is modelled with a forced noop after the instruction.
793def FCMPS  : F3_3<2, 0b110101, 0b001010001,
794                  (ops FPRegs:$src1, FPRegs:$src2),
795                  "fcmps $src1, $src2\n\tnop",
796                  [(set FCC, (V8cmpfcc FPRegs:$src1, FPRegs:$src2))]>;
797def FCMPD  : F3_3<2, 0b110101, 0b001010010,
798                  (ops DFPRegs:$src1, DFPRegs:$src2),
799                  "fcmpd $src1, $src2\n\tnop",
800                  [(set FCC, (V8cmpfcc DFPRegs:$src1, DFPRegs:$src2))]>;
801
802
803//===----------------------------------------------------------------------===//
804// V9 Instructions
805//===----------------------------------------------------------------------===//
806
807// V9 Conditional Moves.
808let Predicates = [HasV9], isTwoAddress = 1 in {
809  // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual.
810  // FIXME: Add instruction encodings for the JIT some day.
811  def MOVICCrr
812    : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc),
813             "mov$cc %icc, $F, $dst",
814             [(set IntRegs:$dst,
815                         (V8selecticc IntRegs:$F, IntRegs:$T, imm:$cc, ICC))]>;
816  def MOVICCri
817    : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc),
818             "mov$cc %icc, $F, $dst",
819             [(set IntRegs:$dst,
820                          (V8selecticc simm11:$F, IntRegs:$T, imm:$cc, ICC))]>;
821
822  def MOVFCCrr
823    : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc),
824             "movf$cc %fcc, $F, $dst",
825             [(set IntRegs:$dst,
826                         (V8selectfcc IntRegs:$F, IntRegs:$T, imm:$cc, FCC))]>;
827  def MOVFCCri
828    : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc),
829             "movf$cc %fcc, $F, $dst",
830             [(set IntRegs:$dst,
831                          (V8selectfcc simm11:$F, IntRegs:$T, imm:$cc, FCC))]>;
832}
833
834// Floating-Point Move Instructions, p. 164 of the V9 manual.
835let Predicates = [HasV9] in {
836  def FMOVD : F3_3<2, 0b110100, 0b000000010,
837                   (ops DFPRegs:$dst, DFPRegs:$src),
838                   "fmovd $src, $dst", []>;
839  def FNEGD : F3_3<2, 0b110100, 0b000000110, 
840                   (ops DFPRegs:$dst, DFPRegs:$src),
841                   "fnegd $src, $dst",
842                   [(set DFPRegs:$dst, (fneg DFPRegs:$src))]>;
843  def FABSD : F3_3<2, 0b110100, 0b000001010, 
844                   (ops DFPRegs:$dst, DFPRegs:$src),
845                   "fabsd $src, $dst",
846                   [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>;
847}
848
849// POPCrr - This does a ctpop of a 64-bit register.  As such, we have to clear
850// the top 32-bits before using it.  To do this clearing, we use a SLLri X,0.
851def POPCrr : F3_1<2, 0b101110, 
852                  (ops IntRegs:$dst, IntRegs:$src),
853                  "popc $src, $dst", []>, Requires<[HasV9]>;
854def : Pat<(ctpop IntRegs:$src),
855          (POPCrr (SLLri IntRegs:$src, 0))>;
856
857//===----------------------------------------------------------------------===//
858// Non-Instruction Patterns
859//===----------------------------------------------------------------------===//
860
861// Small immediates.
862def : Pat<(i32 simm13:$val),
863          (ORri G0, imm:$val)>;
864// Arbitrary immediates.
865def : Pat<(i32 imm:$val),
866          (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;
867
868// Global addresses, constant pool entries
869def : Pat<(V8hi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>;
870def : Pat<(V8lo tglobaladdr:$in), (ORri G0, tglobaladdr:$in)>;
871def : Pat<(V8hi tconstpool:$in), (SETHIi tconstpool:$in)>;
872def : Pat<(V8lo tconstpool:$in), (ORri G0, tconstpool:$in)>;
873
874// Add reg, lo.  This is used when taking the addr of a global/constpool entry.
875def : Pat<(add IntRegs:$r, (V8lo tglobaladdr:$in)),
876          (ADDri IntRegs:$r, tglobaladdr:$in)>;
877def : Pat<(add IntRegs:$r, (V8lo tconstpool:$in)),
878          (ADDri IntRegs:$r, tconstpool:$in)>;
879
880
881// Calls: 
882def : Pat<(call tglobaladdr:$dst),
883          (CALL tglobaladdr:$dst)>;
884def : Pat<(call externalsym:$dst),
885          (CALL externalsym:$dst)>;
886
887def : Pat<(ret), (RETL)>;
888
889// Map integer extload's to zextloads.
890def : Pat<(i32 (extload ADDRrr:$src, i1)), (LDUBrr ADDRrr:$src)>;
891def : Pat<(i32 (extload ADDRri:$src, i1)), (LDUBri ADDRri:$src)>;
892def : Pat<(i32 (extload ADDRrr:$src, i8)), (LDUBrr ADDRrr:$src)>;
893def : Pat<(i32 (extload ADDRri:$src, i8)), (LDUBri ADDRri:$src)>;
894def : Pat<(i32 (extload ADDRrr:$src, i16)), (LDUHrr ADDRrr:$src)>;
895def : Pat<(i32 (extload ADDRri:$src, i16)), (LDUHri ADDRri:$src)>;
896
897// zextload bool -> zextload byte
898def : Pat<(i32 (zextload ADDRrr:$src, i1)), (LDUBrr ADDRrr:$src)>;
899def : Pat<(i32 (zextload ADDRri:$src, i1)), (LDUBri ADDRri:$src)>;
900
901// truncstore bool -> truncstore byte.
902def : Pat<(truncstore IntRegs:$src, ADDRrr:$addr, i1), 
903          (STBrr ADDRrr:$addr, IntRegs:$src)>;
904def : Pat<(truncstore IntRegs:$src, ADDRri:$addr, i1), 
905          (STBri ADDRri:$addr, IntRegs:$src)>;
906