Atomic op support. If any gcc test uses __sync builtins, it might start failing...
[oota-llvm.git] / lib / Target / Alpha / AlphaInstrInfo.td
1 //===- AlphaInstrInfo.td - The Alpha Instruction Set -------*- tablegen -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 //
11 //===----------------------------------------------------------------------===//
12
13 include "AlphaInstrFormats.td"
14
15 //********************
16 //Custom DAG Nodes
17 //********************
18
19 def SDTFPUnaryOpUnC  : SDTypeProfile<1, 1, [
20   SDTCisFP<1>, SDTCisFP<0>
21 ]>;
22 def Alpha_cvtqt   : SDNode<"AlphaISD::CVTQT_",    SDTFPUnaryOpUnC, []>;
23 def Alpha_cvtqs   : SDNode<"AlphaISD::CVTQS_",    SDTFPUnaryOpUnC, []>;
24 def Alpha_cvttq   : SDNode<"AlphaISD::CVTTQ_"  ,  SDTFPUnaryOp, []>;
25 def Alpha_gprello : SDNode<"AlphaISD::GPRelLo",   SDTIntBinOp, []>;
26 def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi",   SDTIntBinOp, []>;
27 def Alpha_rellit  : SDNode<"AlphaISD::RelLit",    SDTIntBinOp, [SDNPMayLoad]>;
28
29 def retflag       : SDNode<"AlphaISD::RET_FLAG", SDTNone,
30                            [SDNPHasChain, SDNPOptInFlag]>;
31
32 // These are target-independent nodes, but have target-specific formats.
33 def SDT_AlphaCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64> ]>;
34 def SDT_AlphaCallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i64>,
35                                            SDTCisVT<1, i64> ]>;
36
37 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeqStart,
38                            [SDNPHasChain, SDNPOutFlag]>;
39 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_AlphaCallSeqEnd,
40                            [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
41
42 //********************
43 //Paterns for matching
44 //********************
45 def invX : SDNodeXForm<imm, [{ //invert
46   return getI64Imm(~N->getValue());
47 }]>;
48 def negX : SDNodeXForm<imm, [{ //negate
49   return getI64Imm(~N->getValue() + 1);
50 }]>;
51 def SExt32 : SDNodeXForm<imm, [{ //signed extend int to long
52   return getI64Imm(((int64_t)N->getValue() << 32) >> 32);
53 }]>;
54 def SExt16 : SDNodeXForm<imm, [{ //signed extend int to long
55   return getI64Imm(((int64_t)N->getValue() << 48) >> 48);
56 }]>;
57 def LL16 : SDNodeXForm<imm, [{ //lda part of constant
58   return getI64Imm(get_lda16(N->getValue()));
59 }]>;
60 def LH16 : SDNodeXForm<imm, [{ //ldah part of constant (or more if too big)
61   return getI64Imm(get_ldah16(N->getValue()));
62 }]>;
63 def iZAPX : SDNodeXForm<and, [{ // get imm to ZAPi
64   ConstantSDNode *RHS = cast<ConstantSDNode>(N->getOperand(1));
65   return getI64Imm(get_zapImm(SDOperand(), RHS->getValue()));
66 }]>;
67 def nearP2X : SDNodeXForm<imm, [{
68   return getI64Imm(Log2_64(getNearPower2((uint64_t)N->getValue())));
69 }]>;
70 def nearP2RemX : SDNodeXForm<imm, [{
71   uint64_t x = abs(N->getValue() - getNearPower2((uint64_t)N->getValue()));
72   return getI64Imm(Log2_64(x));
73 }]>;
74
75 def immUExt8  : PatLeaf<(imm), [{ //imm fits in 8 bit zero extended field
76   return (uint64_t)N->getValue() == (uint8_t)N->getValue();
77 }]>;
78 def immUExt8inv  : PatLeaf<(imm), [{ //inverted imm fits in 8 bit zero extended field
79   return (uint64_t)~N->getValue() == (uint8_t)~N->getValue();
80 }], invX>;
81 def immUExt8neg  : PatLeaf<(imm), [{ //negated imm fits in 8 bit zero extended field
82   return ((uint64_t)~N->getValue() + 1) == (uint8_t)((uint64_t)~N->getValue() + 1);
83 }], negX>;
84 def immSExt16  : PatLeaf<(imm), [{ //imm fits in 16 bit sign extended field
85   return ((int64_t)N->getValue() << 48) >> 48 == (int64_t)N->getValue();
86 }]>;
87 def immSExt16int  : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended field
88   return ((int64_t)N->getValue() << 48) >> 48 == ((int64_t)N->getValue() << 32) >> 32;
89 }], SExt16>;
90
91 def zappat : PatFrag<(ops node:$LHS), (and node:$LHS, imm:$L), [{
92   if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
93     uint64_t build = get_zapImm(N->getOperand(0), (uint64_t)RHS->getValue());
94     return build != 0;
95   }
96   return false;
97 }]>;
98
99 def immFPZ  : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
100   (void)N; // silence warning.
101   return true;
102 }]>;
103
104 def immRem1  : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),1, 0);}]>;
105 def immRem2  : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),2, 0);}]>;
106 def immRem3  : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),3, 0);}]>;
107 def immRem4  : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),4, 0);}]>;
108 def immRem5  : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),5, 0);}]>;
109 def immRem1n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),1, 1);}]>;
110 def immRem2n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),2, 1);}]>;
111 def immRem3n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),3, 1);}]>;
112 def immRem4n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),4, 1);}]>;
113 def immRem5n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),5, 1);}]>;
114
115 def immRemP2n : PatLeaf<(imm), [{
116   return isPowerOf2_64(getNearPower2((uint64_t)N->getValue()) - N->getValue());
117 }]>;
118 def immRemP2 : PatLeaf<(imm), [{
119   return isPowerOf2_64(N->getValue() - getNearPower2((uint64_t)N->getValue()));
120 }]>;
121 def immUExt8ME : PatLeaf<(imm), [{ //use this imm for mulqi
122   int64_t d =  abs((int64_t)N->getValue() - (int64_t)getNearPower2((uint64_t)N->getValue()));
123   if (isPowerOf2_64(d)) return false;
124   switch (d) {
125     case 1: case 3: case 5: return false; 
126     default: return (uint64_t)N->getValue() == (uint8_t)N->getValue();
127   };
128 }]>;
129
130 def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
131 def add4  : PatFrag<(ops node:$op1, node:$op2),
132                     (add (shl node:$op1, 2), node:$op2)>;
133 def sub4  : PatFrag<(ops node:$op1, node:$op2),
134                     (sub (shl node:$op1, 2), node:$op2)>;
135 def add8  : PatFrag<(ops node:$op1, node:$op2),
136                     (add (shl node:$op1, 3), node:$op2)>;
137 def sub8  : PatFrag<(ops node:$op1, node:$op2),
138                     (sub (shl node:$op1, 3), node:$op2)>;
139 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
140 class CmpOpFrag<dag res> : PatFrag<(ops node:$R), res>;
141
142 //Pseudo ops for selection
143
144 let isImplicitDef = 1 in {
145 def IDEF_I : PseudoInstAlpha<(outs GPRC:$RA), (ins), ";#idef $RA",
146              [(set GPRC:$RA, (undef))], s_pseudo>;
147 def IDEF_F32 : PseudoInstAlpha<(outs F4RC:$RA), (ins), ";#idef $RA",
148              [(set F4RC:$RA, (undef))], s_pseudo>;
149 def IDEF_F64 : PseudoInstAlpha<(outs F8RC:$RA), (ins), ";#idef $RA",
150              [(set F8RC:$RA, (undef))], s_pseudo>;
151 }
152
153 def WTF : PseudoInstAlpha<(outs), (ins variable_ops), "#wtf", [], s_pseudo>;
154
155 let hasCtrlDep = 1, Defs = [R30], Uses = [R30] in {
156 def ADJUSTSTACKUP : PseudoInstAlpha<(outs), (ins s64imm:$amt),
157                 "; ADJUP $amt", 
158                 [(callseq_start imm:$amt)], s_pseudo>;
159 def ADJUSTSTACKDOWN : PseudoInstAlpha<(outs), (ins s64imm:$amt1, s64imm:$amt2),
160                 "; ADJDOWN $amt1",
161                 [(callseq_end imm:$amt1, imm:$amt2)], s_pseudo>;
162 }
163
164 def ALTENT : PseudoInstAlpha<(outs), (ins s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>;
165 def PCLABEL : PseudoInstAlpha<(outs), (ins s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>;
166 def MEMLABEL : PseudoInstAlpha<(outs), (ins s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
167          "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>;
168
169
170 let usesCustomDAGSchedInserter = 1 in {   // Expanded by the scheduler.
171 def CAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$cmp, GPRC:$swp), "",
172         [(set GPRC:$dst, (atomic_lcs_32 GPRC:$ptr, GPRC:$cmp, GPRC:$swp))], s_pseudo>;
173 def CAS64 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$cmp, GPRC:$swp), "",
174         [(set GPRC:$dst, (atomic_lcs_64 GPRC:$ptr, GPRC:$cmp, GPRC:$swp))], s_pseudo>;
175
176 def LAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
177         [(set GPRC:$dst, (atomic_las_32 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
178 def LAS64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
179         [(set GPRC:$dst, (atomic_las_64 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
180
181 def SWAP32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
182         [(set GPRC:$dst, (atomic_swap_32 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
183 def SWAP64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
184         [(set GPRC:$dst, (atomic_swap_64 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
185 }
186
187 //***********************
188 //Real instructions
189 //***********************
190
191 //Operation Form:
192
193 //conditional moves, int
194
195 multiclass cmov_inst<bits<7> fun, string asmstr, PatFrag OpNode> {
196 def r : OForm4<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
197              [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
198 def i : OForm4L<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
199              [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), immUExt8:$RTRUE, GPRC:$RFALSE))], s_cmov>;
200 }
201
202 defm CMOVEQ  : cmov_inst<0x24, "cmoveq",  CmpOpFrag<(seteq node:$R, 0)>>;
203 defm CMOVNE  : cmov_inst<0x26, "cmovne",  CmpOpFrag<(setne node:$R, 0)>>;
204 defm CMOVLT  : cmov_inst<0x44, "cmovlt",  CmpOpFrag<(setlt node:$R, 0)>>;
205 defm CMOVLE  : cmov_inst<0x64, "cmovle",  CmpOpFrag<(setle node:$R, 0)>>;
206 defm CMOVGT  : cmov_inst<0x66, "cmovgt",  CmpOpFrag<(setgt node:$R, 0)>>;
207 defm CMOVGE  : cmov_inst<0x46, "cmovge",  CmpOpFrag<(setge node:$R, 0)>>;
208 defm CMOVLBC : cmov_inst<0x16, "cmovlbc", CmpOpFrag<(xor   node:$R, 1)>>;
209 defm CMOVLBS : cmov_inst<0x14, "cmovlbs", CmpOpFrag<(and   node:$R, 1)>>;
210
211 //General pattern for cmov
212 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
213       (CMOVNEr GPRC:$src2, GPRC:$src1, GPRC:$which)>;
214 def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2),
215       (CMOVEQi GPRC:$src1, immUExt8:$src2, GPRC:$which)>;
216
217 //Invert sense when we can for constants:
218 def : Pat<(select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
219           (CMOVEQi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
220 def : Pat<(select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
221           (CMOVLEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
222 def : Pat<(select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
223           (CMOVLTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
224 def : Pat<(select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
225           (CMOVGEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
226 def : Pat<(select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
227           (CMOVGTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
228
229 multiclass all_inst<bits<6> opc, bits<7> funl, bits<7> funq, 
230                     string asmstr, PatFrag OpNode, InstrItinClass itin> {
231   def Lr : OForm< opc, funl, !strconcat(asmstr, "l $RA,$RB,$RC"),
232                [(set GPRC:$RC, (intop (OpNode GPRC:$RA, GPRC:$RB)))], itin>;
233   def Li : OFormL<opc, funl, !strconcat(asmstr, "l $RA,$L,$RC"),
234                [(set GPRC:$RC, (intop (OpNode GPRC:$RA, immUExt8:$L)))], itin>;
235   def Qr : OForm< opc, funq, !strconcat(asmstr, "q $RA,$RB,$RC"),
236                [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
237   def Qi : OFormL<opc, funq, !strconcat(asmstr, "q $RA,$L,$RC"),
238                [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
239 }
240
241 defm MUL   : all_inst<0x13, 0x00, 0x20, "mul",   BinOpFrag<(mul node:$LHS, node:$RHS)>, s_imul>;
242 defm ADD   : all_inst<0x10, 0x00, 0x20, "add",   BinOpFrag<(add node:$LHS, node:$RHS)>, s_iadd>;
243 defm S4ADD : all_inst<0x10, 0x02, 0x22, "s4add", add4, s_iadd>;
244 defm S8ADD : all_inst<0x10, 0x12, 0x32, "s8add", add8, s_iadd>;
245 defm S4SUB : all_inst<0x10, 0x0B, 0x2B, "s4sub", sub4, s_iadd>;
246 defm S8SUB : all_inst<0x10, 0x1B, 0x3B, "s8sub", sub8, s_iadd>;
247 defm SUB   : all_inst<0x10, 0x09, 0x29, "sub",   BinOpFrag<(sub node:$LHS, node:$RHS)>, s_iadd>;
248 //Const cases since legalize does sub x, int -> add x, inv(int) + 1
249 def : Pat<(intop (add GPRC:$RA, immUExt8neg:$L)), (SUBLi GPRC:$RA, immUExt8neg:$L)>;
250 def : Pat<(add GPRC:$RA, immUExt8neg:$L), (SUBQi GPRC:$RA, immUExt8neg:$L)>;
251 def : Pat<(intop (add4 GPRC:$RA, immUExt8neg:$L)), (S4SUBLi GPRC:$RA, immUExt8neg:$L)>;
252 def : Pat<(add4 GPRC:$RA, immUExt8neg:$L), (S4SUBQi GPRC:$RA, immUExt8neg:$L)>;
253 def : Pat<(intop (add8 GPRC:$RA, immUExt8neg:$L)), (S8SUBLi GPRC:$RA, immUExt8neg:$L)>;
254 def : Pat<(add8 GPRC:$RA, immUExt8neg:$L), (S8SUBQi GPRC:$RA, immUExt8neg:$L)>;
255
256 multiclass log_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
257 def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"),
258               [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
259 def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"),
260               [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
261 }
262 multiclass inv_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
263 def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"),
264               [(set GPRC:$RC, (OpNode GPRC:$RA, (not GPRC:$RB)))], itin>;
265 def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"),
266               [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8inv:$L))], itin>;
267 }
268
269 defm AND   : log_inst<0x11, 0x00, "and",   and,   s_ilog>;
270 defm BIC   : inv_inst<0x11, 0x08, "bic",   and,   s_ilog>;
271 defm BIS   : log_inst<0x11, 0x20, "bis",   or,    s_ilog>;
272 defm ORNOT : inv_inst<0x11, 0x28, "ornot", or,    s_ilog>;
273 defm XOR   : log_inst<0x11, 0x40, "xor",   xor,   s_ilog>;
274 defm EQV   : inv_inst<0x11, 0x48, "eqv",   xor,   s_ilog>;
275
276 defm SL    : log_inst<0x12, 0x39, "sll",   shl,   s_ishf>;
277 defm SRA   : log_inst<0x12, 0x3c, "sra",   sra,   s_ishf>;
278 defm SRL   : log_inst<0x12, 0x34, "srl",   srl,   s_ishf>;
279 defm UMULH : log_inst<0x13, 0x30, "umulh", mulhu, s_imul>;
280
281 def CTLZ     : OForm2<0x1C, 0x32, "CTLZ $RB,$RC", 
282                       [(set GPRC:$RC, (ctlz GPRC:$RB))], s_imisc>;
283 def CTPOP    : OForm2<0x1C, 0x30, "CTPOP $RB,$RC", 
284                       [(set GPRC:$RC, (ctpop GPRC:$RB))], s_imisc>;
285 def CTTZ     : OForm2<0x1C, 0x33, "CTTZ $RB,$RC", 
286                       [(set GPRC:$RC, (cttz GPRC:$RB))], s_imisc>;
287 def EXTBL    : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC", 
288                       [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))], s_ishf>;
289 def EXTWL    : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC", 
290                       [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))], s_ishf>;
291 def EXTLL    : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC", 
292                       [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))], s_ishf>;
293 def SEXTB    : OForm2<0x1C, 0x00, "sextb $RB,$RC", 
294                       [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>;
295 def SEXTW    : OForm2<0x1C, 0x01, "sextw $RB,$RC", 
296                       [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))], s_ishf>;
297
298 //def EXTBLi   : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
299 //def EXTLH    : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
300 //def EXTLHi   : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
301 //def EXTLLi   : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
302 //def EXTQH    : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
303 //def EXTQHi   : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
304 //def EXTQ     : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
305 //def EXTQi    : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
306 //def EXTWH    : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
307 //def EXTWHi   : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
308 //def EXTWLi   : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
309
310 //def INSBL    : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
311 //def INSBLi   : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
312 //def INSLH    : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
313 //def INSLHi   : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
314 //def INSLL    : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
315 //def INSLLi   : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
316 //def INSQH    : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
317 //def INSQHi   : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
318 //def INSQL    : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
319 //def INSQLi   : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
320 //def INSWH    : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
321 //def INSWHi   : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
322 //def INSWL    : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
323 //def INSWLi   : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
324
325 //def MSKBL    : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
326 //def MSKBLi   : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
327 //def MSKLH    : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
328 //def MSKLHi   : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
329 //def MSKLL    : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
330 //def MSKLLi   : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
331 //def MSKQH    : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
332 //def MSKQHi   : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
333 //def MSKQL    : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
334 //def MSKQLi   : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
335 //def MSKWH    : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
336 //def MSKWHi   : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
337 //def MSKWL    : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
338 //def MSKWLi   : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
339                       
340 def ZAPNOTi  : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", [], s_ishf>;
341
342 // Define the pattern that produces ZAPNOTi.
343 def : Pat<(i64 (zappat GPRC:$RA):$imm),
344           (ZAPNOTi GPRC:$RA, (iZAPX GPRC:$imm))>;
345
346
347 //Comparison, int
348 //So this is a waste of what this instruction can do, but it still saves something
349 def CMPBGE  : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC", 
350                      [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))], s_ilog>;
351 def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
352                      [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))], s_ilog>;
353 def CMPEQ   : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC", 
354                      [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))], s_iadd>;
355 def CMPEQi  : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC", 
356                      [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))], s_iadd>;
357 def CMPLE   : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC", 
358                      [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))], s_iadd>;
359 def CMPLEi  : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
360                      [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))], s_iadd>;
361 def CMPLT   : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
362                      [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))], s_iadd>;
363 def CMPLTi  : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
364                      [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))], s_iadd>;
365 def CMPULE  : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
366                      [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))], s_iadd>;
367 def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
368                      [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))], s_iadd>;
369 def CMPULT  : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
370                      [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))], s_iadd>;
371 def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC", 
372                       [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))], s_iadd>;
373
374 //Patterns for unsupported int comparisons
375 def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
376 def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
377
378 def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
379 def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
380
381 def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
382 def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
383
384 def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
385 def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
386
387 def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
388 def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
389
390 def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
391 def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
392
393 def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
394 def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
395
396
397 let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in {
398   def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", s_jsr>; //Return from subroutine
399   def RETDAGp : MbrpForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", [(retflag)], s_jsr>; //Return from subroutine
400 }
401
402 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, Ra = 31, disp = 0 in
403 def JMP : MbrpForm< 0x1A, 0x00, (ops GPRC:$RS), "jmp $$31,($RS),0", 
404           [(brind GPRC:$RS)], s_jsr>; //Jump
405
406 let isCall = 1, Ra = 26,
407     Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
408             R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
409             F0, F1,
410             F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
411             F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
412     def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", [], s_jsr>; //Branch to subroutine
413 }
414 let isCall = 1, Ra = 26, Rb = 27, disp = 0,
415     Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
416             R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
417             F0, F1,
418             F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
419             F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in {
420     def JSR : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0", s_jsr>; //Jump to subroutine
421 }
422
423 let isCall = 1, Ra = 23, Rb = 27, disp = 0,
424     Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
425   def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0", s_jsr>; //Jump to div or rem
426
427
428 def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return
429
430
431 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
432 def LDQ   : MForm<0x29, 1, "ldq $RA,$DISP($RB)",
433                  [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
434 def LDQr  : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!gprellow",
435                  [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
436 def LDL   : MForm<0x28, 1, "ldl $RA,$DISP($RB)",
437                  [(set GPRC:$RA, (sextloadi32 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
438 def LDLr  : MForm<0x28, 1, "ldl $RA,$DISP($RB)\t\t!gprellow",
439                  [(set GPRC:$RA, (sextloadi32 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
440 def LDBU  : MForm<0x0A, 1, "ldbu $RA,$DISP($RB)",
441                  [(set GPRC:$RA, (zextloadi8 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
442 def LDBUr : MForm<0x0A, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow",
443                  [(set GPRC:$RA, (zextloadi8 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
444 def LDWU  : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)",
445                  [(set GPRC:$RA, (zextloadi16 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
446 def LDWUr : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
447                  [(set GPRC:$RA, (zextloadi16 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
448 }
449
450
451 let OutOperandList = (ops), InOperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
452 def STB   : MForm<0x0E, 0, "stb $RA,$DISP($RB)",
453                  [(truncstorei8 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
454 def STBr  : MForm<0x0E, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
455                  [(truncstorei8 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
456 def STW   : MForm<0x0D, 0, "stw $RA,$DISP($RB)",
457                  [(truncstorei16 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
458 def STWr  : MForm<0x0D, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
459                  [(truncstorei16 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
460 def STL   : MForm<0x2C, 0, "stl $RA,$DISP($RB)",
461                  [(truncstorei32 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
462 def STLr  : MForm<0x2C, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
463                  [(truncstorei32 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
464 def STQ   : MForm<0x2D, 0, "stq $RA,$DISP($RB)",
465                  [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
466 def STQr  : MForm<0x2D, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
467                  [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
468 }
469
470 //Load address
471 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
472 def LDA   : MForm<0x08, 0, "lda $RA,$DISP($RB)",
473                  [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_lda>;
474 def LDAr  : MForm<0x08, 0, "lda $RA,$DISP($RB)\t\t!gprellow",
475                  [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_lda>;  //Load address
476 def LDAH  : MForm<0x09, 0, "ldah $RA,$DISP($RB)",
477                  [], s_lda>;  //Load address high
478 def LDAHr : MForm<0x09, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh",
479                  [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))], s_lda>;  //Load address high
480 }
481
482 let OutOperandList = (ops), InOperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
483 def STS  : MForm<0x26, 0, "sts $RA,$DISP($RB)",
484                 [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
485 def STSr : MForm<0x26, 0, "sts $RA,$DISP($RB)\t\t!gprellow",
486                 [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
487 }
488 let OutOperandList = (ops F4RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
489 def LDS  : MForm<0x22, 1, "lds $RA,$DISP($RB)",
490                 [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
491 def LDSr : MForm<0x22, 1, "lds $RA,$DISP($RB)\t\t!gprellow",
492                 [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
493 }
494 let OutOperandList = (ops), InOperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
495 def STT  : MForm<0x27, 0, "stt $RA,$DISP($RB)",
496                 [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
497 def STTr : MForm<0x27, 0, "stt $RA,$DISP($RB)\t\t!gprellow",
498                 [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
499 }
500 let OutOperandList = (ops F8RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
501 def LDT  : MForm<0x23, 1, "ldt $RA,$DISP($RB)",
502                 [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
503 def LDTr : MForm<0x23, 1, "ldt $RA,$DISP($RB)\t\t!gprellow",
504                 [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
505 }
506
507
508 //constpool rels
509 def : Pat<(i64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
510           (LDQr tconstpool:$DISP, GPRC:$RB)>;
511 def : Pat<(i64 (sextloadi32 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
512           (LDLr tconstpool:$DISP, GPRC:$RB)>;
513 def : Pat<(i64 (zextloadi8 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
514           (LDBUr tconstpool:$DISP, GPRC:$RB)>;
515 def : Pat<(i64 (zextloadi16 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
516           (LDWUr tconstpool:$DISP, GPRC:$RB)>;
517 def : Pat<(i64 (Alpha_gprello tconstpool:$DISP, GPRC:$RB)),
518           (LDAr tconstpool:$DISP, GPRC:$RB)>;
519 def : Pat<(i64 (Alpha_gprelhi tconstpool:$DISP, GPRC:$RB)),
520           (LDAHr tconstpool:$DISP, GPRC:$RB)>;
521 def : Pat<(f32 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
522           (LDSr tconstpool:$DISP, GPRC:$RB)>;
523 def : Pat<(f64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
524           (LDTr tconstpool:$DISP, GPRC:$RB)>;
525
526 //jumptable rels
527 def : Pat<(i64 (Alpha_gprelhi tjumptable:$DISP, GPRC:$RB)),
528           (LDAHr tjumptable:$DISP, GPRC:$RB)>;
529 def : Pat<(i64 (Alpha_gprello tjumptable:$DISP, GPRC:$RB)),
530           (LDAr tjumptable:$DISP, GPRC:$RB)>;
531
532
533 //misc ext patterns
534 def : Pat<(i64 (extloadi8 (add GPRC:$RB, immSExt16:$DISP))),
535           (LDBU   immSExt16:$DISP, GPRC:$RB)>;
536 def : Pat<(i64 (extloadi16 (add GPRC:$RB, immSExt16:$DISP))),
537           (LDWU  immSExt16:$DISP, GPRC:$RB)>;
538 def : Pat<(i64 (extloadi32 (add GPRC:$RB, immSExt16:$DISP))),
539           (LDL   immSExt16:$DISP, GPRC:$RB)>;
540
541 //0 disp patterns
542 def : Pat<(i64 (load GPRC:$addr)),
543           (LDQ  0, GPRC:$addr)>;
544 def : Pat<(f64 (load GPRC:$addr)),
545           (LDT  0, GPRC:$addr)>;
546 def : Pat<(f32 (load GPRC:$addr)),
547           (LDS  0, GPRC:$addr)>;
548 def : Pat<(i64 (sextloadi32 GPRC:$addr)),
549           (LDL  0, GPRC:$addr)>;
550 def : Pat<(i64 (zextloadi16 GPRC:$addr)),
551           (LDWU 0, GPRC:$addr)>;
552 def : Pat<(i64 (zextloadi8 GPRC:$addr)),
553           (LDBU 0, GPRC:$addr)>;
554 def : Pat<(i64 (extloadi8 GPRC:$addr)),
555           (LDBU 0, GPRC:$addr)>;
556 def : Pat<(i64 (extloadi16 GPRC:$addr)),
557           (LDWU 0, GPRC:$addr)>;
558 def : Pat<(i64 (extloadi32 GPRC:$addr)),
559           (LDL  0, GPRC:$addr)>;
560
561 def : Pat<(store GPRC:$DATA, GPRC:$addr),
562           (STQ  GPRC:$DATA, 0, GPRC:$addr)>;
563 def : Pat<(store F8RC:$DATA, GPRC:$addr),
564           (STT  F8RC:$DATA, 0, GPRC:$addr)>;
565 def : Pat<(store F4RC:$DATA, GPRC:$addr),
566           (STS  F4RC:$DATA, 0, GPRC:$addr)>;
567 def : Pat<(truncstorei32 GPRC:$DATA, GPRC:$addr),
568           (STL  GPRC:$DATA, 0, GPRC:$addr)>;
569 def : Pat<(truncstorei16 GPRC:$DATA, GPRC:$addr),
570           (STW GPRC:$DATA, 0, GPRC:$addr)>;
571 def : Pat<(truncstorei8 GPRC:$DATA, GPRC:$addr),
572           (STB GPRC:$DATA, 0, GPRC:$addr)>;
573
574
575 //load address, rellocated gpdist form
576 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in {
577 def LDAg  : MForm<0x08, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>;  //Load address
578 def LDAHg : MForm<0x09, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>;  //Load address
579 }
580
581 //Load quad, rellocated literal form
582 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in 
583 def LDQl : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!literal",
584                  [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))], s_ild>;
585 def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
586           (LDQl texternalsym:$ext, GPRC:$RB)>;
587
588 let OutOperandList = (outs GPRC:$RR),
589     InOperandList = (ins GPRC:$RA, s64imm:$DISP, GPRC:$RB),
590     Constraints = "$RA = $RR",
591     DisableEncoding = "$RR" in {
592 def STQ_C : MForm<0x2F, 0, "stq_l $RA,$DISP($RB)", [], s_ist>;
593 def STL_C : MForm<0x2E, 0, "stl_l $RA,$DISP($RB)", [], s_ist>;
594 }
595 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
596 def LDQ_L : MForm<0x2B, 1, "ldq_l $RA,$DISP($RB)", [], s_ild>;
597 def LDL_L : MForm<0x2A, 1, "ldl_l $RA,$DISP($RB)", [], s_ild>;
598 }
599
600 def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process cycle counter
601 def MB  : MfcPForm<0x18, 0x4000, "mb",  s_imisc>; //memory barrier
602 def WMB : MfcPForm<0x18, 0x4400, "wmb", s_imisc>; //write memory barrier
603
604 def : Pat<(membarrier (i64 imm:$ll), (i64 imm:$ls), (i64 imm:$sl), (i64 1), (i64 imm:$dev)),
605           (WMB)>;
606 def : Pat<(membarrier (i64 imm:$ll), (i64 imm:$ls), (i64 imm:$sl), (i64 imm:$ss), (i64 imm:$dev)),
607           (MB)>;
608
609 //Basic Floating point ops
610
611 //Floats
612
613 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in 
614 def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
615                    [(set F4RC:$RC, (fsqrt F4RC:$RB))], s_fsqrts>;
616
617 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RA, F4RC:$RB) in {
618 def ADDS  : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
619                    [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))], s_fadd>;
620 def SUBS  : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
621                    [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))], s_fadd>;
622 def DIVS  : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
623                    [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))], s_fdivs>;
624 def MULS  : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
625                    [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))], s_fmul>;
626
627 def CPYSS  : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
628                    [(set F4RC:$RC, (fcopysign F4RC:$RB, F4RC:$RA))], s_fadd>;
629 def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
630 def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
631                    [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F4RC:$RA)))], s_fadd>;
632 }
633
634 //Doubles
635
636 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in 
637 def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
638                    [(set F8RC:$RC, (fsqrt F8RC:$RB))], s_fsqrtt>;
639
640 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RA, F8RC:$RB) in {
641 def ADDT  : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
642                    [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))], s_fadd>;
643 def SUBT  : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
644                    [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))], s_fadd>;
645 def DIVT  : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
646                    [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))], s_fdivt>;
647 def MULT  : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
648                    [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))], s_fmul>;
649
650 def CPYST  : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
651                    [(set F8RC:$RC, (fcopysign F8RC:$RB, F8RC:$RA))], s_fadd>;
652 def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
653 def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
654                    [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F8RC:$RA)))], s_fadd>;
655
656 def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", [], s_fadd>;
657 //                    [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
658 def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", [], s_fadd>;
659 //                    [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
660 def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", [], s_fadd>;
661 //                    [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
662 def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>;
663 //                    [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
664 }
665
666 //More CPYS forms:
667 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RA, F8RC:$RB) in {
668 def CPYSTs  : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
669                    [(set F8RC:$RC, (fcopysign F8RC:$RB, F4RC:$RA))], s_fadd>;
670 def CPYSNTs : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
671                    [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F4RC:$RA)))], s_fadd>;
672 }
673 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RA, F4RC:$RB) in {
674 def CPYSSt  : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
675                    [(set F4RC:$RC, (fcopysign F4RC:$RB, F8RC:$RA))], s_fadd>;
676 def CPYSESt : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
677 def CPYSNSt : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
678                    [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F8RC:$RA)))], s_fadd>;
679 }
680
681 //conditional moves, floats
682 let OutOperandList = (ops F4RC:$RDEST), InOperandList = (ops F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
683     isTwoAddress = 1 in {
684 def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if = zero
685 def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if >= zero
686 def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if > zero
687 def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if <= zero
688 def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; // FCMOVE if < zero
689 def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if != zero
690 }
691 //conditional moves, doubles
692 let OutOperandList = (ops F8RC:$RDEST), InOperandList = (ops F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
693     isTwoAddress = 1 in {
694 def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
695 def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
696 def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
697 def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
698 def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
699 def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
700 }
701
702 //misc FP selects
703 //Select double
704      
705 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
706       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
707 def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
708       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
709 def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
710       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
711
712 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
713       (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
714 def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
715       (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
716 def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
717       (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
718
719 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
720       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
721 def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
722       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
723 def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
724       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
725
726 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
727       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
728 def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
729       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
730 def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
731       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
732
733 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
734       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
735 def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
736       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
737 def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
738       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
739
740 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
741       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
742 def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
743       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
744 def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
745       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
746
747 //Select single
748 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
749       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
750 def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
751       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
752 def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
753       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
754
755 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
756       (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
757 def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
758       (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
759 def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
760       (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
761
762 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
763       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
764 def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
765       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
766 def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
767       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
768
769 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
770       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
771 def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
772       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
773 def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
774       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
775
776 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
777       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
778 def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
779       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
780 def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
781       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
782
783 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
784       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
785 def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
786       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
787 def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
788       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
789
790
791
792 let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F4RC:$RA), Fb = 31 in 
793 def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[], s_ftoi>; //Floating to integer move, S_floating
794 let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F8RC:$RA), Fb = 31 in 
795 def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
796         [(set GPRC:$RC, (bitconvert F8RC:$RA))], s_ftoi>; //Floating to integer move
797 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in 
798 def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[], s_itof>; //Integer to floating move, S_floating
799 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in 
800 def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
801         [(set F8RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move
802
803
804 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in 
805 def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
806         [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))], s_fadd>;
807 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in 
808 def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
809         [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))], s_fadd>;
810 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in 
811 def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
812         [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))], s_fadd>;
813 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in 
814 def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
815                    [(set F8RC:$RC, (fextend F4RC:$RB))], s_fadd>;
816 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in 
817 def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
818                    [(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>;
819
820
821 /////////////////////////////////////////////////////////
822 //Branching
823 /////////////////////////////////////////////////////////
824 class br_icc<bits<6> opc, string asmstr>
825   : BFormN<opc, (ops u64imm:$opc, GPRC:$R, target:$dst), 
826     !strconcat(asmstr, " $R,$dst"),  s_icbr>;
827 class br_fcc<bits<6> opc, string asmstr>
828   : BFormN<opc, (ops u64imm:$opc, F8RC:$R, target:$dst), 
829     !strconcat(asmstr, " $R,$dst"),  s_fbr>;
830
831 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
832 let Ra = 31 in
833 def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>;
834
835 def COND_BRANCH_I : BFormN<0, (ops u64imm:$opc, GPRC:$R, target:$dst), 
836                     "{:comment} COND_BRANCH imm:$opc, GPRC:$R, bb:$dst", 
837                     s_icbr>;
838 def COND_BRANCH_F : BFormN<0, (ops u64imm:$opc, F8RC:$R, target:$dst), 
839                     "{:comment} COND_BRANCH imm:$opc, F8RC:$R, bb:$dst",
840                     s_fbr>;
841 //Branches, int
842 def BEQ  : br_icc<0x39, "beq">;
843 def BGE  : br_icc<0x3E, "bge">;
844 def BGT  : br_icc<0x3F, "bgt">;
845 def BLBC : br_icc<0x38, "blbc">;
846 def BLBS : br_icc<0x3C, "blbs">;
847 def BLE  : br_icc<0x3B, "ble">;
848 def BLT  : br_icc<0x3A, "blt">;
849 def BNE  : br_icc<0x3D, "bne">;
850
851 //Branches, float
852 def FBEQ : br_fcc<0x31, "fbeq">;
853 def FBGE : br_fcc<0x36, "fbge">;
854 def FBGT : br_fcc<0x37, "fbgt">;
855 def FBLE : br_fcc<0x33, "fble">;
856 def FBLT : br_fcc<0x32, "fblt">;
857 def FBNE : br_fcc<0x36, "fbne">;
858 }
859
860 //An ugly trick to get the opcode as an imm I can use
861 def immBRCond : SDNodeXForm<imm, [{
862   switch((uint64_t)N->getValue()) {
863     case 0:  return getI64Imm(Alpha::BEQ);
864     case 1:  return getI64Imm(Alpha::BNE);
865     case 2:  return getI64Imm(Alpha::BGE);
866     case 3:  return getI64Imm(Alpha::BGT);
867     case 4:  return getI64Imm(Alpha::BLE);
868     case 5:  return getI64Imm(Alpha::BLT);
869     case 6:  return getI64Imm(Alpha::BLBS);
870     case 7:  return getI64Imm(Alpha::BLBC);
871     case 20: return getI64Imm(Alpha::FBEQ);
872     case 21: return getI64Imm(Alpha::FBNE);
873     case 22: return getI64Imm(Alpha::FBGE);
874     case 23: return getI64Imm(Alpha::FBGT);
875     case 24: return getI64Imm(Alpha::FBLE);
876     case 25: return getI64Imm(Alpha::FBLT);
877     default: assert(0 && "Unknown branch type");
878   }
879 }]>;
880
881 //Int cond patterns
882 def : Pat<(brcond (seteq GPRC:$RA, 0), bb:$DISP), 
883       (COND_BRANCH_I (immBRCond 0),  GPRC:$RA, bb:$DISP)>;
884 def : Pat<(brcond (setge GPRC:$RA, 0), bb:$DISP), 
885       (COND_BRANCH_I (immBRCond 2),  GPRC:$RA, bb:$DISP)>;
886 def : Pat<(brcond (setgt GPRC:$RA, 0), bb:$DISP), 
887       (COND_BRANCH_I (immBRCond 3),  GPRC:$RA, bb:$DISP)>;
888 def : Pat<(brcond (and   GPRC:$RA, 1), bb:$DISP), 
889       (COND_BRANCH_I (immBRCond 6),  GPRC:$RA, bb:$DISP)>;
890 def : Pat<(brcond (setle GPRC:$RA, 0), bb:$DISP), 
891       (COND_BRANCH_I (immBRCond 4),  GPRC:$RA, bb:$DISP)>;
892 def : Pat<(brcond (setlt GPRC:$RA, 0), bb:$DISP), 
893       (COND_BRANCH_I (immBRCond 5),  GPRC:$RA, bb:$DISP)>;
894 def : Pat<(brcond (setne GPRC:$RA, 0), bb:$DISP), 
895       (COND_BRANCH_I (immBRCond 1),  GPRC:$RA, bb:$DISP)>;
896
897 def : Pat<(brcond GPRC:$RA, bb:$DISP), 
898       (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
899 def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP), 
900       (COND_BRANCH_I (immBRCond 0), (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
901 def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP), 
902       (COND_BRANCH_I (immBRCond 0), (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
903
904 //FP cond patterns
905 def : Pat<(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP), 
906       (COND_BRANCH_F (immBRCond 20),  F8RC:$RA, bb:$DISP)>;
907 def : Pat<(brcond (setne F8RC:$RA, immFPZ), bb:$DISP), 
908       (COND_BRANCH_F (immBRCond 21),  F8RC:$RA, bb:$DISP)>;
909 def : Pat<(brcond (setge F8RC:$RA, immFPZ), bb:$DISP), 
910       (COND_BRANCH_F (immBRCond 22),  F8RC:$RA, bb:$DISP)>;
911 def : Pat<(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP), 
912       (COND_BRANCH_F (immBRCond 23),  F8RC:$RA, bb:$DISP)>;
913 def : Pat<(brcond (setle F8RC:$RA, immFPZ), bb:$DISP), 
914       (COND_BRANCH_F (immBRCond 24),  F8RC:$RA, bb:$DISP)>;
915 def : Pat<(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP), 
916       (COND_BRANCH_F (immBRCond 25),  F8RC:$RA, bb:$DISP)>;
917
918
919 def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),  
920       (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
921 def : Pat<(brcond (setoeq F8RC:$RA, F8RC:$RB), bb:$DISP), 
922       (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
923 def : Pat<(brcond (setueq F8RC:$RA, F8RC:$RB), bb:$DISP), 
924       (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
925
926 def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),  
927       (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
928 def : Pat<(brcond (setolt F8RC:$RA, F8RC:$RB), bb:$DISP), 
929       (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
930 def : Pat<(brcond (setult F8RC:$RA, F8RC:$RB), bb:$DISP), 
931       (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
932
933 def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),  
934       (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
935 def : Pat<(brcond (setole F8RC:$RA, F8RC:$RB), bb:$DISP), 
936       (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
937 def : Pat<(brcond (setule F8RC:$RA, F8RC:$RB), bb:$DISP), 
938       (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
939
940 def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),  
941       (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
942 def : Pat<(brcond (setogt F8RC:$RA, F8RC:$RB), bb:$DISP), 
943       (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
944 def : Pat<(brcond (setugt F8RC:$RA, F8RC:$RB), bb:$DISP), 
945       (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
946
947 def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),  
948       (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
949 def : Pat<(brcond (setoge F8RC:$RA, F8RC:$RB), bb:$DISP), 
950       (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
951 def : Pat<(brcond (setuge F8RC:$RA, F8RC:$RB), bb:$DISP), 
952       (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
953
954 def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),  
955       (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
956 def : Pat<(brcond (setone F8RC:$RA, F8RC:$RB), bb:$DISP), 
957       (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
958 def : Pat<(brcond (setune F8RC:$RA, F8RC:$RB), bb:$DISP), 
959       (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
960
961
962 def : Pat<(brcond (setoeq F8RC:$RA, immFPZ), bb:$DISP),   
963       (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
964 def : Pat<(brcond (setueq F8RC:$RA, immFPZ), bb:$DISP),   
965       (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
966
967 def : Pat<(brcond (setoge F8RC:$RA, immFPZ), bb:$DISP),   
968       (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
969 def : Pat<(brcond (setuge F8RC:$RA, immFPZ), bb:$DISP),   
970       (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
971
972 def : Pat<(brcond (setogt F8RC:$RA, immFPZ), bb:$DISP),   
973       (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
974 def : Pat<(brcond (setugt F8RC:$RA, immFPZ), bb:$DISP),   
975       (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
976
977 def : Pat<(brcond (setole F8RC:$RA, immFPZ), bb:$DISP),   
978       (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
979 def : Pat<(brcond (setule F8RC:$RA, immFPZ), bb:$DISP),   
980       (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
981
982 def : Pat<(brcond (setolt F8RC:$RA, immFPZ), bb:$DISP),   
983       (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
984 def : Pat<(brcond (setult F8RC:$RA, immFPZ), bb:$DISP),   
985       (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
986
987 def : Pat<(brcond (setone F8RC:$RA, immFPZ), bb:$DISP),   
988       (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
989 def : Pat<(brcond (setune F8RC:$RA, immFPZ), bb:$DISP),   
990       (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
991
992 //End Branches
993
994 //S_floating : IEEE Single
995 //T_floating : IEEE Double
996
997 //Unused instructions
998 //Mnemonic Format Opcode Description
999 //CALL_PAL Pcd 00 Trap to PALcode
1000 //ECB Mfc 18.E800 Evict cache block
1001 //EXCB Mfc 18.0400 Exception barrier
1002 //FETCH Mfc 18.8000 Prefetch data
1003 //FETCH_M Mfc 18.A000 Prefetch data, modify intent
1004 //LDQ_U Mem 0B Load unaligned quadword
1005 //MB Mfc 18.4000 Memory barrier
1006 //STQ_U Mem 0F Store unaligned quadword
1007 //TRAPB Mfc 18.0000 Trap barrier
1008 //WH64 Mfc 18.F800 Write hint \14 64 bytes
1009 //WMB Mfc 18.4400 Write memory barrier
1010 //MF_FPCR F-P 17.025 Move from FPCR
1011 //MT_FPCR F-P 17.024 Move to FPCR
1012 //There are in the Multimedia extentions, so let's not use them yet
1013 //def MAXSB8  : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
1014 //def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
1015 //def MAXUB8  : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
1016 //def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
1017 //def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
1018 //def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
1019 //def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
1020 //def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
1021 //def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
1022 //def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
1023 //def PKWB  : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
1024 //def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
1025 //def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
1026 //CVTLQ F-P 17.010 Convert longword to quadword
1027 //CVTQL F-P 17.030 Convert quadword to longword
1028
1029
1030 //Constant handling
1031
1032 def immConst2Part  : PatLeaf<(imm), [{
1033   //true if imm fits in a LDAH LDA pair
1034   int64_t val = (int64_t)N->getValue();
1035   return (val <= IMM_FULLHIGH  && val >= IMM_FULLLOW);
1036 }]>;
1037 def immConst2PartInt  : PatLeaf<(imm), [{
1038   //true if imm fits in a LDAH LDA pair with zeroext
1039   uint64_t uval = N->getValue();
1040   int32_t val32 = (int32_t)uval;
1041   return ((uval >> 32) == 0 && //empty upper bits
1042           val32 <= IMM_FULLHIGH);
1043 //          val32 >= IMM_FULLLOW  + IMM_LOW  * IMM_MULT); //Always True
1044 }], SExt32>;
1045
1046 def : Pat<(i64 immConst2Part:$imm),
1047           (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
1048
1049 def : Pat<(i64 immSExt16:$imm),
1050           (LDA immSExt16:$imm, R31)>;
1051
1052 def : Pat<(i64 immSExt16int:$imm),
1053           (ZAPNOTi (LDA (SExt16 immSExt16int:$imm), R31), 15)>;
1054 def : Pat<(i64 immConst2PartInt:$imm),
1055           (ZAPNOTi (LDA (LL16 (SExt32 immConst2PartInt:$imm)), 
1056                         (LDAH (LH16 (SExt32 immConst2PartInt:$imm)), R31)), 15)>;
1057
1058
1059 //TODO: I want to just define these like this!
1060 //def : Pat<(i64 0),
1061 //          (R31)>;
1062 //def : Pat<(f64 0.0),
1063 //          (F31)>;
1064 //def : Pat<(f64 -0.0),
1065 //          (CPYSNT F31, F31)>;
1066 //def : Pat<(f32 0.0),
1067 //          (F31)>;
1068 //def : Pat<(f32 -0.0),
1069 //          (CPYSNS F31, F31)>;
1070
1071 //Misc Patterns:
1072
1073 def : Pat<(sext_inreg GPRC:$RB, i32),
1074           (ADDLi GPRC:$RB, 0)>;
1075
1076 def : Pat<(fabs F8RC:$RB),
1077           (CPYST F31, F8RC:$RB)>;
1078 def : Pat<(fabs F4RC:$RB),
1079           (CPYSS F31, F4RC:$RB)>;
1080 def : Pat<(fneg F8RC:$RB),
1081           (CPYSNT F8RC:$RB, F8RC:$RB)>;
1082 def : Pat<(fneg F4RC:$RB),
1083           (CPYSNS F4RC:$RB, F4RC:$RB)>;
1084
1085 def : Pat<(fcopysign F4RC:$A, (fneg F4RC:$B)),
1086           (CPYSNS F4RC:$B, F4RC:$A)>;
1087 def : Pat<(fcopysign F8RC:$A, (fneg F8RC:$B)),
1088           (CPYSNT F8RC:$B, F8RC:$A)>;
1089 def : Pat<(fcopysign F4RC:$A, (fneg F8RC:$B)),
1090           (CPYSNSt F8RC:$B, F4RC:$A)>;
1091 def : Pat<(fcopysign F8RC:$A, (fneg F4RC:$B)),
1092           (CPYSNTs F4RC:$B, F8RC:$A)>;
1093
1094 //Yes, signed multiply high is ugly
1095 def : Pat<(mulhs GPRC:$RA, GPRC:$RB),
1096           (SUBQr (UMULHr GPRC:$RA, GPRC:$RB), (ADDQr (CMOVGEr GPRC:$RB, R31, GPRC:$RA), 
1097                                                      (CMOVGEr GPRC:$RA, R31, GPRC:$RB)))>;
1098
1099 //Stupid crazy arithmetic stuff:
1100 let AddedComplexity = 1 in {
1101 def : Pat<(mul GPRC:$RA, 5), (S4ADDQr GPRC:$RA, GPRC:$RA)>;
1102 def : Pat<(mul GPRC:$RA, 9), (S8ADDQr GPRC:$RA, GPRC:$RA)>;
1103 def : Pat<(mul GPRC:$RA, 3), (S4SUBQr GPRC:$RA, GPRC:$RA)>;
1104 def : Pat<(mul GPRC:$RA, 7), (S8SUBQr GPRC:$RA, GPRC:$RA)>;
1105
1106 //slight tree expansion if we are multiplying near to a power of 2
1107 //n is above a power of 2
1108 def : Pat<(mul GPRC:$RA, immRem1:$imm), 
1109           (ADDQr (SLr GPRC:$RA, (nearP2X immRem1:$imm)), GPRC:$RA)>;
1110 def : Pat<(mul GPRC:$RA, immRem2:$imm), 
1111           (ADDQr (SLr GPRC:$RA, (nearP2X immRem2:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>;
1112 def : Pat<(mul GPRC:$RA, immRem3:$imm),
1113           (ADDQr (SLr GPRC:$RA, (nearP2X immRem3:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>;
1114 def : Pat<(mul GPRC:$RA, immRem4:$imm),
1115           (S4ADDQr GPRC:$RA, (SLr GPRC:$RA, (nearP2X immRem4:$imm)))>;
1116 def : Pat<(mul GPRC:$RA, immRem5:$imm),
1117           (ADDQr (SLr GPRC:$RA, (nearP2X immRem5:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>;
1118 def : Pat<(mul GPRC:$RA, immRemP2:$imm),
1119           (ADDQr (SLr GPRC:$RA, (nearP2X immRemP2:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2:$imm)))>;
1120
1121 //n is below a power of 2
1122 //FIXME: figure out why something is truncating the imm to 32bits
1123 // this will fix 2007-11-27-mulneg3
1124 //def : Pat<(mul GPRC:$RA, immRem1n:$imm), 
1125 //          (SUBQr (SLr GPRC:$RA, (nearP2X immRem1n:$imm)), GPRC:$RA)>;
1126 //def : Pat<(mul GPRC:$RA, immRem2n:$imm), 
1127 //          (SUBQr (SLr GPRC:$RA, (nearP2X immRem2n:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>;
1128 //def : Pat<(mul GPRC:$RA, immRem3n:$imm),
1129 //          (SUBQr (SLr GPRC:$RA, (nearP2X immRem3n:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>;
1130 //def : Pat<(mul GPRC:$RA, immRem4n:$imm),
1131 //          (SUBQr (SLr GPRC:$RA, (nearP2X immRem4n:$imm)), (SLi GPRC:$RA, 2))>;
1132 //def : Pat<(mul GPRC:$RA, immRem5n:$imm),
1133 //          (SUBQr (SLr GPRC:$RA, (nearP2X immRem5n:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>;
1134 //def : Pat<(mul GPRC:$RA, immRemP2n:$imm),
1135 //          (SUBQr (SLr GPRC:$RA, (nearP2X immRemP2n:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2n:$imm)))>;
1136 } //Added complexity