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