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