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