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