typo
[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
23 def Alpha_itoft : SDNode<"AlphaISD::ITOFT_", SDTIntToFPOp, []>;
24 def Alpha_ftoit : SDNode<"AlphaISD::FTOIT_", SDTFPToIntOp, []>;
25 def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>;
26 def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>;
27 def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_", SDTFPUnaryOp, []>;
28 def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>;
29 def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>;
30 def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, []>;
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,[SDNPHasChain]>;
35 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_AlphaCallSeq,[SDNPHasChain]>;
36
37 //********************
38 //Paterns for matching
39 //********************
40 def invX : SDNodeXForm<imm, [{ //invert
41   return getI64Imm(~N->getValue());
42 }]>;
43 def negX : SDNodeXForm<imm, [{ //negate
44   return getI64Imm(~N->getValue() + 1);
45 }]>;
46 def SExt32 : SDNodeXForm<imm, [{ //signed extend int to long
47   return getI64Imm(((int64_t)N->getValue() << 32) >> 32);
48 }]>;
49 def SExt16 : SDNodeXForm<imm, [{ //signed extend int to long
50   return getI64Imm(((int64_t)N->getValue() << 48) >> 48);
51 }]>;
52 def LL16 : SDNodeXForm<imm, [{ //lda part of constant
53   return getI64Imm(get_lda16(N->getValue()));
54 }]>;
55 def LH16 : SDNodeXForm<imm, [{ //ldah part of constant (or more if too big)
56   return getI64Imm(get_ldah16(N->getValue()));
57 }]>;
58 def iZAPX : SDNodeXForm<imm, [{ // get imm to ZAPi
59   return getI64Imm(get_zapImm((uint64_t)N->getValue()));
60 }]>;
61
62 def immUExt8  : PatLeaf<(imm), [{ //imm fits in 8 bit zero extended field
63   return (uint64_t)N->getValue() == (uint8_t)N->getValue();
64 }]>;
65 def immUExt8inv  : PatLeaf<(imm), [{ //inverted imm fits in 8 bit zero extended field
66   return (uint64_t)~N->getValue() == (uint8_t)~N->getValue();
67 }], invX>;
68 def immUExt8neg  : PatLeaf<(imm), [{ //negated imm fits in 8 bit zero extended field
69   return ((uint64_t)~N->getValue() + 1) == (uint8_t)((uint64_t)~N->getValue() + 1);
70 }], negX>;
71 def immSExt16  : PatLeaf<(imm), [{ //imm fits in 16 bit sign extended field
72   return ((int64_t)N->getValue() << 48) >> 48 == (int64_t)N->getValue();
73 }]>;
74 def immSExt16int  : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended field
75   return ((int64_t)N->getValue() << 48) >> 48 == ((int64_t)N->getValue() << 32) >> 32;
76 }], SExt16>;
77 def immZAP  : PatLeaf<(imm), [{ //imm is good for zapi
78   uint64_t build = get_zapImm((uint64_t)N->getValue());
79   return build != 0;
80 }], iZAPX>;
81 def immFPZ  : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
82   return true;
83 }]>;
84
85 def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
86 def add4  : PatFrag<(ops node:$op1, node:$op2),
87                     (add (shl node:$op1, 2), node:$op2)>;
88 def sub4  : PatFrag<(ops node:$op1, node:$op2),
89                     (sub (shl node:$op1, 2), node:$op2)>;
90 def add8  : PatFrag<(ops node:$op1, node:$op2),
91                     (add (shl node:$op1, 3), node:$op2)>;
92 def sub8  : PatFrag<(ops node:$op1, node:$op2),
93                     (sub (shl node:$op1, 3), node:$op2)>;
94
95
96 //Pseudo ops for selection
97
98 def PHI : PseudoInstAlpha<(ops variable_ops), "#phi", []>;
99
100 def IDEF_I : PseudoInstAlpha<(ops GPRC:$RA), "#idef $RA",
101              [(set GPRC:$RA, (undef))]>;
102 def IDEF_F32 : PseudoInstAlpha<(ops F4RC:$RA), "#idef $RA",
103              [(set F4RC:$RA, (undef))]>;
104 def IDEF_F64 : PseudoInstAlpha<(ops F8RC:$RA), "#idef $RA",
105              [(set F8RC:$RA, (undef))]>;
106
107 def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf", []>;
108
109 let isLoad = 1, hasCtrlDep = 1 in {
110 def ADJUSTSTACKUP : PseudoInstAlpha<(ops s64imm:$amt), "; ADJUP $amt", 
111                 [(callseq_start imm:$amt)]>;
112 def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops s64imm:$amt), "; ADJDOWN $amt", 
113                 [(callseq_end imm:$amt)]>;
114 }
115 def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$$$TARGET..ng:\n", []>;
116 def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[]>;
117 def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
118          "LSMARKER$$$i$$$j$$$k$$$m:\n",[]>;
119
120
121
122 //An even better improvement on the Int = SetCC(FP):  SelectCC!
123 //These are evil because they hide control flow in a MBB
124 //really the ISel should emit multiple MBB
125 let isTwoAddress = 1 in {
126 //Conditional move of an int based on a FP CC
127   def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
128                                   "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
129   def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND),
130                                   "fbne $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n", []>;
131
132   def CMOVNE_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
133                                   "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
134   def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND),
135                                   "fbeq $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n", []>;
136 //Conditional move of an FP based on a Int CC
137   def FCMOVEQ_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
138                                   "bne $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
139   def FCMOVNE_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
140                                   "beq $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
141 }
142
143 //***********************
144 //Real instructions
145 //***********************
146
147 //Operation Form:
148
149 //conditional moves, int
150 def CMOVEQi  : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$L,$RDEST">; //CMOVE if RCOND =  zero
151 def CMOVGEi  : OForm4L< 0x11, 0x46, "cmovge $RCOND,$L,$RDEST">; //CMOVE if RCOND >= zero
152 def CMOVGTi  : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$L,$RDEST">; //CMOVE if RCOND > zero
153 def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit clear
154 def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit set
155 def CMOVLEi  : OForm4L< 0x11, 0x64, "cmovle $RCOND,$L,$RDEST">; //CMOVE if RCOND <= zero
156 def CMOVLTi  : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero
157 def CMOVNEi  : OForm4L< 0x11, 0x26, "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero
158
159 let OperandList = (ops GPRC:$RDEST, GPRC:$RFALSE, GPRC:$RTRUE, GPRC:$RCOND) in {
160 def CMOVLBC  : OForm4<  0x11, 0x16, "cmovlbc $RCOND,$RTRUE,$RDEST",
161                 [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>;
162 def CMOVLBS  : OForm4<  0x11, 0x14, "cmovlbs $RCOND,$RTRUE,$RDEST",
163                 [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>;
164 def CMOVEQ   : OForm4<  0x11, 0x24, "cmoveq $RCOND,$RTRUE,$RDEST",
165                 [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
166 def CMOVGE   : OForm4<  0x11, 0x46, "cmovge $RCOND,$RTRUE,$RDEST",
167                 [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
168 def CMOVGT   : OForm4<  0x11, 0x66, "cmovgt $RCOND,$RTRUE,$RDEST",
169                 [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
170 def CMOVLE   : OForm4<  0x11, 0x64, "cmovle $RCOND,$RTRUE,$RDEST",
171                 [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
172 def CMOVLT   : OForm4<  0x11, 0x44, "cmovlt $RCOND,$RTRUE,$RDEST",
173                 [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
174 def CMOVNE   : OForm4<  0x11, 0x26, "cmovne $RCOND,$RTRUE,$RDEST",
175                 [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
176 }
177
178 //FIXME: fold setcc with select for all cases.  clearly I need patterns for inverted conditions
179 //       and constants (which require inverted conditions as legalize puts the constant in the
180 //       wrong field for the instruction definition
181 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
182       (CMOVNE GPRC:$src2, GPRC:$src1, GPRC:$which)>;
183
184
185 def ADDL     : OForm< 0x10, 0x00, "addl $RA,$RB,$RC",
186                       [(set GPRC:$RC, (intop (add GPRC:$RA, GPRC:$RB)))]>;
187 def ADDLi    : OFormL<0x10, 0x00, "addl $RA,$L,$RC",
188                       [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8:$L)))]>;
189 def ADDQ     : OForm< 0x10, 0x20, "addq $RA,$RB,$RC",
190                       [(set GPRC:$RC, (add GPRC:$RA, GPRC:$RB))]>;
191 def ADDQi    : OFormL<0x10, 0x20, "addq $RA,$L,$RC",
192                       [(set GPRC:$RC, (add GPRC:$RA, immUExt8:$L))]>;
193 def AND      : OForm< 0x11, 0x00, "and $RA,$RB,$RC",
194                       [(set GPRC:$RC, (and GPRC:$RA, GPRC:$RB))]>;
195 def ANDi     : OFormL<0x11, 0x00, "and $RA,$L,$RC",
196                       [(set GPRC:$RC, (and GPRC:$RA, immUExt8:$L))]>;
197 def BIC      : OForm< 0x11, 0x08, "bic $RA,$RB,$RC",
198                       [(set GPRC:$RC, (and GPRC:$RA, (not GPRC:$RB)))]>;
199 def BICi     : OFormL<0x11, 0x08, "bic $RA,$L,$RC", 
200                       [(set GPRC:$RC, (and GPRC:$RA, immUExt8inv:$L))]>;
201 def BIS      : OForm< 0x11, 0x20, "bis $RA,$RB,$RC",
202                       [(set GPRC:$RC, (or GPRC:$RA, GPRC:$RB))]>;
203 def BISi     : OFormL<0x11, 0x20, "bis $RA,$L,$RC",
204                       [(set GPRC:$RC, (or GPRC:$RA, immUExt8:$L))]>;
205 def CTLZ     : OForm2<0x1C, 0x32, "CTLZ $RB,$RC", 
206                       [(set GPRC:$RC, (ctlz GPRC:$RB))]>;
207 def CTPOP    : OForm2<0x1C, 0x30, "CTPOP $RB,$RC", 
208                       [(set GPRC:$RC, (ctpop GPRC:$RB))]>;
209 def CTTZ     : OForm2<0x1C, 0x33, "CTTZ $RB,$RC", 
210                       [(set GPRC:$RC, (cttz GPRC:$RB))]>;
211 def EQV      : OForm< 0x11, 0x48, "eqv $RA,$RB,$RC",
212                       [(set GPRC:$RC, (xor GPRC:$RA, (not GPRC:$RB)))]>;
213 def EQVi     : OFormL<0x11, 0x48, "eqv $RA,$L,$RC", 
214                       [(set GPRC:$RC, (xor GPRC:$RA, immUExt8inv:$L))]>;
215 def EXTBL    : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC", 
216                       [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))]>;
217 def EXTWL    : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC", 
218                       [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))]>;
219 def EXTLL    : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC", 
220                       [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))]>;
221
222 //def EXTBLi   : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
223 //def EXTLH    : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
224 //def EXTLHi   : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
225 //def EXTLLi   : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
226 //def EXTQH    : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
227 //def EXTQHi   : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
228 //def EXTQ     : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
229 //def EXTQi    : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
230 //def EXTWH    : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
231 //def EXTWHi   : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
232 //def EXTWLi   : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
233
234 //def IMPLVER  : OForm< 0x11, 0x6C, "IMPLVER $RA,$RB,$RC", []>; //Implementation version
235 //def IMPLVERi : OFormL<0x11, 0x6C, "IMPLVER $RA,$L,$RC", []>; //Implementation version
236 //def INSBL    : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
237 //def INSBLi   : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
238 //def INSLH    : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
239 //def INSLHi   : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
240 //def INSLL    : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
241 //def INSLLi   : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
242 //def INSQH    : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
243 //def INSQHi   : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
244 //def INSQL    : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
245 //def INSQLi   : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
246 //def INSWH    : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
247 //def INSWHi   : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
248 //def INSWL    : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
249 //def INSWLi   : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
250 //def MSKBL    : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
251 //def MSKBLi   : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
252 //def MSKLH    : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
253 //def MSKLHi   : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
254 //def MSKLL    : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
255 //def MSKLLi   : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
256 //def MSKQH    : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
257 //def MSKQHi   : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
258 //def MSKQL    : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
259 //def MSKQLi   : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
260 //def MSKWH    : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
261 //def MSKWHi   : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
262 //def MSKWL    : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
263 //def MSKWLi   : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
264
265 def MULL     : OForm< 0x13, 0x00, "mull $RA,$RB,$RC",
266                       [(set GPRC:$RC, (intop (mul GPRC:$RA, GPRC:$RB)))]>;
267 def MULLi    : OFormL<0x13, 0x00, "mull $RA,$L,$RC",
268                       [(set GPRC:$RC, (intop (mul GPRC:$RA, immUExt8:$L)))]>;
269 def MULQ     : OForm< 0x13, 0x20, "mulq $RA,$RB,$RC",
270                       [(set GPRC:$RC, (mul GPRC:$RA, GPRC:$RB))]>;
271 def MULQi    : OFormL<0x13, 0x20, "mulq $RA,$L,$RC",
272                       [(set GPRC:$RC, (mul GPRC:$RA, immUExt8:$L))]>;
273 def ORNOT    : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC",
274                       [(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))]>;
275 def ORNOTi   : OFormL<0x11, 0x28, "ornot $RA,$L,$RC", 
276                       [(set GPRC:$RC, (or GPRC:$RA, immUExt8inv:$L))]>;
277 def S4ADDL   : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC", 
278                       [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))]>;
279 def S4ADDLi  : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC", 
280                       [(set GPRC:$RC, (intop (add4 GPRC:$RA, immUExt8:$L)))]>;
281 def S4ADDQ   : OForm< 0x10, 0x22, "s4addq $RA,$RB,$RC", 
282                       [(set GPRC:$RC, (add4 GPRC:$RA, GPRC:$RB))]>;
283 def S4ADDQi  : OFormL<0x10, 0x22, "s4addq $RA,$L,$RC", 
284                       [(set GPRC:$RC, (add4 GPRC:$RA, immUExt8:$L))]>;
285 def S4SUBL   : OForm< 0x10, 0x0B, "s4subl $RA,$RB,$RC",
286                       [(set GPRC:$RC, (intop (sub4 GPRC:$RA, GPRC:$RB)))]>;
287 def S4SUBLi  : OFormL<0x10, 0x0B, "s4subl $RA,$L,$RC",
288                       [(set GPRC:$RC, (intop (sub4 GPRC:$RA, immUExt8:$L)))]>;
289 def S4SUBQ   : OForm< 0x10, 0x2B, "s4subq $RA,$RB,$RC", 
290                       [(set GPRC:$RC, (sub4 GPRC:$RA, GPRC:$RB))]>;
291 def S4SUBQi  : OFormL<0x10, 0x2B, "s4subq $RA,$L,$RC", 
292                       [(set GPRC:$RC, (sub4 GPRC:$RA, immUExt8:$L))]>;
293 def S8ADDL   : OForm< 0x10, 0x12, "s8addl $RA,$RB,$RC", 
294                       [(set GPRC:$RC, (intop (add8 GPRC:$RA, GPRC:$RB)))]>;
295 def S8ADDLi  : OFormL<0x10, 0x12, "s8addl $RA,$L,$RC", 
296                       [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8:$L)))]>;
297 def S8ADDQ   : OForm< 0x10, 0x32, "s8addq $RA,$RB,$RC", 
298                       [(set GPRC:$RC, (add8 GPRC:$RA, GPRC:$RB))]>;
299 def S8ADDQi  : OFormL<0x10, 0x32, "s8addq $RA,$L,$RC", 
300                       [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8:$L))]>;
301 def S8SUBL   : OForm< 0x10, 0x1B, "s8subl $RA,$RB,$RC", 
302                       [(set GPRC:$RC, (intop (sub8 GPRC:$RA, GPRC:$RB)))]>;
303 def S8SUBLi  : OFormL<0x10, 0x1B, "s8subl $RA,$L,$RC", 
304                       [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8neg:$L)))]>;
305 def S8SUBQ   : OForm< 0x10, 0x3B, "s8subq $RA,$RB,$RC", 
306                       [(set GPRC:$RC, (sub8 GPRC:$RA, GPRC:$RB))]>;
307 def S8SUBQi  : OFormL<0x10, 0x3B, "s8subq $RA,$L,$RC", 
308                       [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8neg:$L))]>;
309 def SEXTB    : OForm2<0x1C, 0x00, "sextb $RB,$RC", 
310                       [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))]>;
311 def SEXTW    : OForm2<0x1C, 0x01, "sextw $RB,$RC", 
312                       [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))]>;
313 def SL       : OForm< 0x12, 0x39, "sll $RA,$RB,$RC",
314                       [(set GPRC:$RC, (shl GPRC:$RA, GPRC:$RB))]>;
315 def SLi      : OFormL<0x12, 0x39, "sll $RA,$L,$RC",
316                       [(set GPRC:$RC, (shl GPRC:$RA, immUExt8:$L))]>;
317 def SRA      : OForm< 0x12, 0x3C, "sra $RA,$RB,$RC",
318                       [(set GPRC:$RC, (sra GPRC:$RA, GPRC:$RB))]>;
319 def SRAi     : OFormL<0x12, 0x3C, "sra $RA,$L,$RC",
320                       [(set GPRC:$RC, (sra GPRC:$RA, immUExt8:$L))]>;
321 def SRL      : OForm< 0x12, 0x34, "srl $RA,$RB,$RC",
322                       [(set GPRC:$RC, (srl GPRC:$RA, GPRC:$RB))]>;
323 def SRLi     : OFormL<0x12, 0x34, "srl $RA,$L,$RC",
324                       [(set GPRC:$RC, (srl GPRC:$RA, immUExt8:$L))]>;
325 def SUBL     : OForm< 0x10, 0x09, "subl $RA,$RB,$RC",
326                       [(set GPRC:$RC, (intop (sub GPRC:$RA, GPRC:$RB)))]>;
327 def SUBLi    : OFormL<0x10, 0x09, "subl $RA,$L,$RC",
328                       [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8neg:$L)))]>;
329 def SUBQ     : OForm< 0x10, 0x29, "subq $RA,$RB,$RC",
330                       [(set GPRC:$RC, (sub GPRC:$RA, GPRC:$RB))]>;
331 def SUBQi    : OFormL<0x10, 0x29, "subq $RA,$L,$RC",
332                       [(set GPRC:$RC, (add GPRC:$RA, immUExt8neg:$L))]>;
333 def UMULH    : OForm< 0x13, 0x30, "umulh $RA,$RB,$RC",
334                       [(set GPRC:$RC, (mulhu GPRC:$RA, GPRC:$RB))]>;                     
335 def UMULHi   : OFormL<0x13, 0x30, "umulh $RA,$L,$RC", 
336                       [(set GPRC:$RC, (mulhu GPRC:$RA, immUExt8:$L))]>;
337 def XOR      : OForm< 0x11, 0x40, "xor $RA,$RB,$RC",
338                       [(set GPRC:$RC, (xor GPRC:$RA, GPRC:$RB))]>;
339 def XORi     : OFormL<0x11, 0x40, "xor $RA,$L,$RC",
340                       [(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))]>;
341 //FIXME: what to do about zap? the cases it catches are very complex
342 def ZAP      : OForm< 0x12, 0x30, "zap $RA,$RB,$RC", []>; //Zero bytes
343 //ZAPi is useless give ZAPNOTi
344 def ZAPi     : OFormL<0x12, 0x30, "zap $RA,$L,$RC", []>; //Zero bytes
345 //FIXME: what to do about zapnot? see ZAP :)
346 def ZAPNOT   : OForm< 0x12, 0x31, "zapnot $RA,$RB,$RC", []>; //Zero bytes not
347 def ZAPNOTi  : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", 
348                       [(set GPRC:$RC, (and GPRC:$RA, immZAP:$L))]>; 
349
350 //Comparison, int
351 //So this is a waste of what this instruction can do, but it still saves something
352 def CMPBGE  : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC", 
353                      [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))]>;
354 def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
355                      [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))]>;
356 def CMPEQ   : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC", 
357                      [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))]>;
358 def CMPEQi  : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC", 
359                      [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))]>;
360 def CMPLE   : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC", 
361                      [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))]>;
362 def CMPLEi  : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
363                      [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))]>;
364 def CMPLT   : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
365                      [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))]>;
366 def CMPLTi  : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
367                      [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))]>;
368 def CMPULE  : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
369                      [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))]>;
370 def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
371                      [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))]>;
372 def CMPULT  : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
373                      [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))]>;
374 def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC", 
375                       [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))]>;
376
377 //Patterns for unsupported int comparisons
378 def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
379 def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
380
381 def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
382 def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
383
384 def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
385 def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
386
387 def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
388 def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
389
390 def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
391 def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
392
393 def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
394 def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
395
396 def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
397 def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
398
399
400 let isReturn = 1, isTerminator = 1, noResults = 1 in 
401   def RET : MbrForm< 0x1A, 0x02, (ops GPRC:$RD, GPRC:$RS, s64imm:$DISP), "ret $RD,($RS),$DISP">; //Return from subroutine
402 //DAG Version:
403 let isReturn = 1, isTerminator = 1, noResults = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in 
404   def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1">; //Return from subroutine
405
406 def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP">; //Jump
407 let isCall = 1, noResults = 1, Ra = 26,
408     Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
409             R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
410             F0, F1,
411             F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
412             F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
413     def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", []>; //Branch to subroutine
414 }
415 let isCall = 1, noResults = 1, Ra = 26, Rb = 27, disp = 0,
416     Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
417             R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
418             F0, F1,
419             F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
420             F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in {
421     def JSR : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0">; //Jump to subroutine
422 }
423
424 let isCall = 1, noResults = 1, Ra = 23, Rb = 27, disp = 0,
425     Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
426   def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0">; //Jump to div or rem
427
428
429 def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP">; //Jump to subroutine return
430
431 let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
432 def LDQ   : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)",
433                  [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))]>;
434 def LDQr  : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!gprellow",
435                  [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))]>;
436 def LDL   : MForm<0x29, 0, 1, "ldl $RA,$DISP($RB)",
437                  [(set GPRC:$RA, (sextload (add GPRC:$RB, immSExt16:$DISP), i32))]>;
438 def LDLr  : MForm<0x29, 0, 1, "ldl $RA,$DISP($RB)\t\t!gprellow",
439                  [(set GPRC:$RA, (sextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32))]>;
440 def LDBU  : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)",
441                  [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i8))]>;
442 def LDBUr : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow",
443                  [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8))]>;
444 def LDWU  : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)",
445                  [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i16))]>;
446 def LDWUr : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
447                  [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16))]>;
448 def STB   : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)",
449                  [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i8)]>;
450 def STBr  : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
451                  [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8)]>;
452 def STW   : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)",
453                  [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i16)]>;
454 def STWr  : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
455                  [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16)]>;
456 def STL   : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)",
457                  [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i32)]>;
458 def STLr  : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
459                  [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32)]>;
460 def STQ   : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)",
461                  [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>;
462 def STQr  : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
463                  [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>;
464
465 //Load address
466 def LDA   : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)",
467                  [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>;
468 def LDAr  : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)\t\t!gprellow",
469                  [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>;  //Load address
470 def LDAH  : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)",
471                  []>;  //Load address high
472 def LDAHr : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh",
473                  [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))]>;  //Load address high
474 }
475
476 let OperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
477 def STS  : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)",
478                 [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>;
479 def STSr : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)\t\t!gprellow",
480                 [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>;
481 def LDS  : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)",
482                 [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))]>;
483 def LDSr : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)\t\t!gprellow",
484                 [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))]>;
485 }
486 let OperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
487 def STT  : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)",
488                 [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>;
489 def STTr : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)\t\t!gprellow",
490                 [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>;
491 def LDT  : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)",
492                 [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))]>;
493 def LDTr : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)\t\t!gprellow",
494                 [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))]>;
495 }
496
497
498 //constpool rels
499 def : Pat<(i64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
500           (LDQr tconstpool:$DISP, GPRC:$RB)>;
501 def : Pat<(i64 (sextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i32)),
502           (LDLr tconstpool:$DISP, GPRC:$RB)>;
503 def : Pat<(i64 (zextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i8)),
504           (LDBUr tconstpool:$DISP, GPRC:$RB)>;
505 def : Pat<(i64 (zextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i16)),
506           (LDWUr tconstpool:$DISP, GPRC:$RB)>;
507 def : Pat<(i64 (Alpha_gprello tconstpool:$DISP, GPRC:$RB)),
508           (LDAr tconstpool:$DISP, GPRC:$RB)>;
509 def : Pat<(i64 (Alpha_gprelhi tconstpool:$DISP, GPRC:$RB)),
510           (LDAHr tconstpool:$DISP, GPRC:$RB)>;
511 def : Pat<(f32 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
512           (LDSr tconstpool:$DISP, GPRC:$RB)>;
513 def : Pat<(f64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
514           (LDTr tconstpool:$DISP, GPRC:$RB)>;
515
516
517 //misc ext patterns
518 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i8)),
519           (LDBU   immSExt16:$DISP, GPRC:$RB)>;
520 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i16)),
521           (LDWU  immSExt16:$DISP, GPRC:$RB)>;
522 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i32)),
523           (LDL   immSExt16:$DISP, GPRC:$RB)>;
524
525 //0 disp patterns
526 def : Pat<(i64 (load GPRC:$addr)),
527           (LDQ  0, GPRC:$addr)>;
528 def : Pat<(f64 (load GPRC:$addr)),
529           (LDT  0, GPRC:$addr)>;
530 def : Pat<(f32 (load GPRC:$addr)),
531           (LDS  0, GPRC:$addr)>;
532 def : Pat<(i64 (sextload GPRC:$addr, i32)),
533           (LDL  0, GPRC:$addr)>;
534 def : Pat<(i64 (zextload GPRC:$addr, i16)),
535           (LDWU 0, GPRC:$addr)>;
536 def : Pat<(i64 (zextload GPRC:$addr, i8)),
537           (LDBU 0, GPRC:$addr)>;
538 def : Pat<(i64 (extload GPRC:$addr, i8)),
539           (LDBU 0, GPRC:$addr)>;
540 def : Pat<(i64 (extload GPRC:$addr, i16)),
541           (LDWU 0, GPRC:$addr)>;
542 def : Pat<(i64 (extload GPRC:$addr, i32)),
543           (LDL  0, GPRC:$addr)>;
544
545 def : Pat<(store GPRC:$DATA, GPRC:$addr),
546           (STQ  GPRC:$DATA, 0, GPRC:$addr)>;
547 def : Pat<(store F8RC:$DATA, GPRC:$addr),
548           (STT  F8RC:$DATA, 0, GPRC:$addr)>;
549 def : Pat<(store F4RC:$DATA, GPRC:$addr),
550           (STS  F4RC:$DATA, 0, GPRC:$addr)>;
551 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i32),
552           (STL  GPRC:$DATA, 0, GPRC:$addr)>;
553 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i16),
554           (STW GPRC:$DATA, 0, GPRC:$addr)>;
555 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i8),
556           (STB GPRC:$DATA, 0, GPRC:$addr)>;
557
558
559 //load address, rellocated gpdist form
560 let OperandList = (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in {
561 def LDAg : MFormAlt<0x08,  "lda $RA,0($RB)\t\t!gpdisp!$NUM">;  //Load address
562 def LDAHg : MFormAlt<0x09, "ldah $RA,0($RB)\t\t!gpdisp!$NUM">;  //Load address
563 }
564
565 //Load quad, rellocated literal form
566 let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in 
567 def LDQl : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!literal",
568                  [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))]>;
569 def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
570           (LDQl texternalsym:$ext, GPRC:$RB)>;
571
572 def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter
573
574 //Basic Floating point ops
575
576 //Floats
577
578 let OperandList = (ops F4RC:$RC, F4RC:$RB), Fa = 31 in 
579 def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
580                    [(set F4RC:$RC, (fsqrt F4RC:$RB))]>;
581
582 let OperandList = (ops F4RC:$RC, F4RC:$RA, F4RC:$RB) in {
583 def ADDS  : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
584                    [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))]>;
585 def SUBS  : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
586                    [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))]>;
587 def DIVS  : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
588                    [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))]>;
589 def MULS  : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
590                    [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))]>;
591
592 def CPYSS  : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>;  //Copy sign
593 def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent
594 def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate
595 }
596
597 //Doubles
598
599 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in 
600 def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
601                    [(set F8RC:$RC, (fsqrt F8RC:$RB))]>;
602
603 let OperandList = (ops F8RC:$RC, F8RC:$RA, F8RC:$RB) in {
604 def ADDT  : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
605                    [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))]>;
606 def SUBT  : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
607                    [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))]>;
608 def DIVT  : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
609                    [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))]>;
610 def MULT  : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
611                    [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))]>;
612
613 def CPYST  : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>;  //Copy sign
614 def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent
615 def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate
616
617 def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", []>;
618 //                    [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
619 def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", []>;
620 //                    [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
621 def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", []>;
622 //                    [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
623 def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", []>;
624 //                    [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
625 }
626 //TODO: Add lots more FP patterns
627
628 //conditional moves, floats
629 let OperandList = (ops F4RC:$RDEST, F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
630     isTwoAddress = 1 in {
631 def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if = zero
632 def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if >= zero
633 def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if > zero
634 def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if <= zero
635 def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[]>; // FCMOVE if < zero
636 def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if != zero
637 }
638 //conditional moves, doubles
639 let OperandList = (ops F8RC:$RDEST, F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
640     isTwoAddress = 1 in {
641 def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", []>;
642 def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", []>;
643 def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", []>;
644 def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", []>;
645 def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", []>;
646 def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", []>;
647 }
648
649 //misc FP selects
650 //Select double
651 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
652       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
653 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
654       (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
655 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
656       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
657 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
658       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
659 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
660       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
661 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
662       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
663 //Select single
664 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
665       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
666 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
667       (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
668 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
669       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
670 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
671       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
672 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
673       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
674 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
675       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
676
677
678
679 let OperandList = (ops GPRC:$RC, F4RC:$RA), Fb = 31 in 
680 def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[]>; //Floating to integer move, S_floating
681 let OperandList = (ops GPRC:$RC, F8RC:$RA), Fb = 31 in 
682 def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
683         [(set GPRC:$RC, (Alpha_ftoit F8RC:$RA))]>; //Floating to integer move
684 let OperandList = (ops F4RC:$RC, GPRC:$RA), Fb = 31 in 
685 def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[]>; //Integer to floating move, S_floating
686 let OperandList = (ops F8RC:$RC, GPRC:$RA), Fb = 31 in 
687 def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
688         [(set F8RC:$RC, (Alpha_itoft GPRC:$RA))]>; //Integer to floating move
689
690
691 let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in 
692 def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
693         [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))]>;
694 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in 
695 def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
696         [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))]>;
697 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in 
698 def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
699         [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))]>;
700 let OperandList = (ops F8RC:$RC, F4RC:$RB), Fa = 31 in 
701 def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
702                    [(set F8RC:$RC, (fextend F4RC:$RB))]>;
703 let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in 
704 def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
705                    [(set F4RC:$RC, (fround F8RC:$RB))]>;
706
707
708 /////////////////////////////////////////////////////////
709 //Branching
710 /////////////////////////////////////////////////////////
711 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, noResults = 1 in {
712 let Ra = 31 in
713 def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)]>;
714
715 //Branches, int
716 def BEQ  : BFormDG<0x39, "beq $RA,$DISP", 
717                    [(brcond (seteq GPRC:$RA, 0), bb:$DISP)]>;
718 def BGE  : BFormDG<0x3E, "bge $RA,$DISP", 
719                    [(brcond (setge GPRC:$RA, 0), bb:$DISP)]>;
720 def BGT  : BFormDG<0x3F, "bgt $RA,$DISP",
721                    [(brcond (setgt GPRC:$RA, 0), bb:$DISP)]>;
722 def BLBC : BFormDG<0x38, "blbc $RA,$DISP", []>; //TODO: Low bit clear
723 def BLBS : BFormDG<0x3C, "blbs $RA,$DISP",
724                    [(brcond (and GPRC:$RA, 1), bb:$DISP)]>;
725 def BLE  : BFormDG<0x3B, "ble $RA,$DISP",
726                    [(brcond (setle GPRC:$RA, 0), bb:$DISP)]>;
727 def BLT  : BFormDG<0x3A, "blt $RA,$DISP",
728                    [(brcond (setlt GPRC:$RA, 0), bb:$DISP)]>;
729 def BNE  : BFormDG<0x3D, "bne $RA,$DISP",
730                    [(brcond (setne GPRC:$RA, 0), bb:$DISP)]>;
731
732 //Branches, float
733 def FBEQ : FBForm<0x31, "fbeq $RA,$DISP", 
734                   [(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP)]>;
735 def FBGE : FBForm<0x36, "fbge $RA,$DISP",
736                   [(brcond (setge F8RC:$RA, immFPZ), bb:$DISP)]>;
737 def FBGT : FBForm<0x37, "fbgt $RA,$DISP",
738                   [(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP)]>;
739 def FBLE : FBForm<0x33, "fble $RA,$DISP",
740                   [(brcond (setle F8RC:$RA, immFPZ), bb:$DISP)]>;
741 def FBLT : FBForm<0x32, "fblt $RA,$DISP",
742                   [(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP)]>;
743 def FBNE : FBForm<0x35, "fbne $RA,$DISP",
744                   [(brcond (setne F8RC:$RA, immFPZ), bb:$DISP)]>;
745 }
746
747 def : Pat<(brcond GPRC:$RA, bb:$DISP), (BNE GPRC:$RA, bb:$DISP)>;
748 def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
749           (BEQ (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
750 def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
751           (BEQ (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
752 def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
753           (FBNE  (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
754 def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
755           (FBNE  (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
756 def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
757           (FBNE  (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
758 def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
759           (FBNE  (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
760 def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
761           (FBNE  (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
762 def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
763           (FBEQ  (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
764
765 //End Branches
766
767 //S_floating : IEEE Single
768 //T_floating : IEEE Double
769
770 //Unused instructions
771 //Mnemonic Format Opcode Description
772 //CALL_PAL Pcd 00 Trap to PALcode
773 //ECB Mfc 18.E800 Evict cache block
774 //EXCB Mfc 18.0400 Exception barrier
775 //FETCH Mfc 18.8000 Prefetch data
776 //FETCH_M Mfc 18.A000 Prefetch data, modify intent
777 //LDL_L Mem 2A Load sign-extended longword locked
778 //LDQ_L Mem 2B Load quadword locked
779 //LDQ_U Mem 0B Load unaligned quadword
780 //MB Mfc 18.4000 Memory barrier
781 //STL_C Mem 2E Store longword conditional
782 //STQ_C Mem 2F Store quadword conditional
783 //STQ_U Mem 0F Store unaligned quadword
784 //TRAPB Mfc 18.0000 Trap barrier
785 //WH64 Mfc 18.F800 Write hint \14 64 bytes
786 //WMB Mfc 18.4400 Write memory barrier
787 //MF_FPCR F-P 17.025 Move from FPCR
788 //MT_FPCR F-P 17.024 Move to FPCR
789 //There are in the Multimedia extentions, so let's not use them yet
790 //def MAXSB8  : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
791 //def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
792 //def MAXUB8  : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
793 //def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
794 //def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
795 //def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
796 //def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
797 //def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
798 //def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
799 //def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
800 //def PKWB  : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
801 //def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
802 //def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
803 //CVTLQ F-P 17.010 Convert longword to quadword
804 //CVTQL F-P 17.030 Convert quadword to longword
805 //def AMASK    : OForm< 0x11, 0x61, "AMASK $RA,$RB,$RC", []>; //Architecture mask
806 //def AMASKi   : OFormL<0x11, 0x61, "AMASK $RA,$L,$RC", []>; //Architecture mask
807
808
809 //Constant handling
810
811 def immConst2Part  : PatLeaf<(imm), [{
812   //true if imm fits in a LDAH LDA pair
813   int64_t val = (int64_t)N->getValue();
814   return (val <= IMM_FULLHIGH  && val >= IMM_FULLLOW);
815 }]>;
816 def immConst2PartInt  : PatLeaf<(imm), [{
817   //true if imm fits in a LDAH LDA pair with zeroext
818   uint64_t uval = N->getValue();
819   int32_t val32 = (int32_t)uval;
820   return ((uval >> 32) == 0 && //empty upper bits
821           val32 <= IMM_FULLHIGH);
822 //          val32 >= IMM_FULLLOW  + IMM_LOW  * IMM_MULT); //Always True
823 }], SExt32>;
824
825 def : Pat<(i64 immConst2Part:$imm),
826           (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
827
828 def : Pat<(i64 immSExt16:$imm),
829           (LDA immSExt16:$imm, R31)>;
830
831 def : Pat<(i64 immSExt16int:$imm),
832           (ZAPNOTi (LDA (SExt16 immSExt16int:$imm), R31), 15)>;
833 def : Pat<(i64 immConst2PartInt:$imm),
834           (ZAPNOTi (LDA (LL16 (SExt32 immConst2PartInt:$imm)), 
835                         (LDAH (LH16 (SExt32 immConst2PartInt:$imm)), R31)), 15)>;
836
837
838 //TODO: I want to just define these like this!
839 //def : Pat<(i64 0),
840 //          (R31)>;
841 //def : Pat<(f64 0.0),
842 //          (F31)>;
843 //def : Pat<(f64 -0.0),
844 //          (CPYSNT F31, F31)>;
845 //def : Pat<(f32 0.0),
846 //          (F31)>;
847 //def : Pat<(f32 -0.0),
848 //          (CPYSNS F31, F31)>;
849
850 //Misc Patterns:
851
852 def : Pat<(sext_inreg GPRC:$RB, i32),
853           (ADDLi GPRC:$RB, 0)>;
854
855 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
856           (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>; //may be CMOVNE
857
858 def : Pat<(fabs F8RC:$RB),
859           (CPYST F31, F8RC:$RB)>;
860 def : Pat<(fabs F4RC:$RB),
861           (CPYSS F31, F4RC:$RB)>;
862 def : Pat<(fneg F8RC:$RB),
863           (CPYSNT F8RC:$RB, F8RC:$RB)>;
864 def : Pat<(fneg F4RC:$RB),
865           (CPYSNS F4RC:$RB, F4RC:$RB)>;
866 //Yes, signed multiply high is ugly
867 def : Pat<(mulhs GPRC:$RA, GPRC:$RB),
868           (SUBQ (UMULH GPRC:$RA, GPRC:$RB), (ADDQ (CMOVGE GPRC:$RB, R31, GPRC:$RA), 
869                                                  (CMOVGE GPRC:$RA, R31, GPRC:$RB)))>;