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