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