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