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