Fix up immediate handling
[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 (int64_t)N->getValue() == (int16_t)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, Ra = 26, Rb = 27, disp = 0,
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, Ra = 23, Rb = 27, disp = 0,
432     Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
433   def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0">; //Jump to div or rem
434
435
436 def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP">; //Jump to subroutine return
437
438 let Ra = 31 in
439 def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)]>;
440
441
442 let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
443 def LDQ   : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)",
444                  [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))]>;
445 def LDQr  : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!gprellow",
446                  [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))]>;
447 def LDL   : MForm<0x29, 0, 1, "ldl $RA,$DISP($RB)",
448                  [(set GPRC:$RA, (sextload (add GPRC:$RB, immSExt16:$DISP), i32))]>;
449 def LDLr  : MForm<0x29, 0, 1, "ldl $RA,$DISP($RB)\t\t!gprellow",
450                  [(set GPRC:$RA, (sextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32))]>;
451 def LDBU  : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)",
452                  [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i8))]>;
453 def LDBUr : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow",
454                  [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8))]>;
455 def LDWU  : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)",
456                  [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i16))]>;
457 def LDWUr : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
458                  [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16))]>;
459 def STB   : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)",
460                  [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i8)]>;
461 def STBr  : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
462                  [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8)]>;
463 def STW   : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)",
464                  [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i16)]>;
465 def STWr  : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
466                  [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16)]>;
467 def STL   : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)",
468                  [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i32)]>;
469 def STLr  : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
470                  [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32)]>;
471 def STQ   : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)",
472                  [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>;
473 def STQr  : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
474                  [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>;
475
476 //Load address
477 def LDA   : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)",
478                  [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>;
479 def LDAr  : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)\t\t!gprellow",
480                  [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>;  //Load address
481 def LDAH  : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)",
482                  []>;  //Load address high
483 def LDAHr : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh",
484                  [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))]>;  //Load address high
485 }
486
487 let OperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
488 def STS  : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)",
489                 [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>;
490 def STSr : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)\t\t!gprellow",
491                 [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>;
492 def LDS  : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)",
493                 [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))]>;
494 def LDSr : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)\t\t!gprellow",
495                 [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))]>;
496 }
497 let OperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
498 def STT  : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)",
499                 [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>;
500 def STTr : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)\t\t!gprellow",
501                 [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>;
502 def LDT  : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)",
503                 [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))]>;
504 def LDTr : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)\t\t!gprellow",
505                 [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))]>;
506 }
507
508
509 //constpool rels
510 def : Pat<(i64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
511           (LDQr tconstpool:$DISP, GPRC:$RB)>;
512 def : Pat<(i64 (sextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i32)),
513           (LDLr tconstpool:$DISP, GPRC:$RB)>;
514 def : Pat<(i64 (zextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i8)),
515           (LDBUr tconstpool:$DISP, GPRC:$RB)>;
516 def : Pat<(i64 (zextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i16)),
517           (LDWUr tconstpool:$DISP, GPRC:$RB)>;
518 def : Pat<(i64 (Alpha_gprello tconstpool:$DISP, GPRC:$RB)),
519           (LDAr tconstpool:$DISP, GPRC:$RB)>;
520 def : Pat<(i64 (Alpha_gprelhi tconstpool:$DISP, GPRC:$RB)),
521           (LDAHr tconstpool:$DISP, GPRC:$RB)>;
522 def : Pat<(f32 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
523           (LDSr tconstpool:$DISP, GPRC:$RB)>;
524 def : Pat<(f64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
525           (LDTr tconstpool:$DISP, GPRC:$RB)>;
526
527
528 //misc ext patterns
529 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i8)),
530           (LDBU   immSExt16:$DISP, GPRC:$RB)>;
531 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i16)),
532           (LDWU  immSExt16:$DISP, GPRC:$RB)>;
533 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i32)),
534           (LDL   immSExt16:$DISP, GPRC:$RB)>;
535
536 //0 disp patterns
537 def : Pat<(i64 (load GPRC:$addr)),
538           (LDQ  0, GPRC:$addr)>;
539 def : Pat<(f64 (load GPRC:$addr)),
540           (LDT  0, GPRC:$addr)>;
541 def : Pat<(f32 (load GPRC:$addr)),
542           (LDS  0, GPRC:$addr)>;
543 def : Pat<(i64 (sextload GPRC:$addr, i32)),
544           (LDL  0, GPRC:$addr)>;
545 def : Pat<(i64 (zextload GPRC:$addr, i16)),
546           (LDWU 0, GPRC:$addr)>;
547 def : Pat<(i64 (zextload GPRC:$addr, i8)),
548           (LDBU 0, GPRC:$addr)>;
549 def : Pat<(i64 (extload GPRC:$addr, i8)),
550           (LDBU 0, GPRC:$addr)>;
551 def : Pat<(i64 (extload GPRC:$addr, i16)),
552           (LDWU 0, GPRC:$addr)>;
553 def : Pat<(i64 (extload GPRC:$addr, i32)),
554           (LDL  0, GPRC:$addr)>;
555
556 def : Pat<(store GPRC:$DATA, GPRC:$addr),
557           (STQ  GPRC:$DATA, 0, GPRC:$addr)>;
558 def : Pat<(store F8RC:$DATA, GPRC:$addr),
559           (STT  F8RC:$DATA, 0, GPRC:$addr)>;
560 def : Pat<(store F4RC:$DATA, GPRC:$addr),
561           (STS  F4RC:$DATA, 0, GPRC:$addr)>;
562 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i32),
563           (STL  GPRC:$DATA, 0, GPRC:$addr)>;
564 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i16),
565           (STW GPRC:$DATA, 0, GPRC:$addr)>;
566 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i8),
567           (STB GPRC:$DATA, 0, GPRC:$addr)>;
568
569
570 //load address, rellocated gpdist form
571 let OperandList = (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in {
572 def LDAg : MFormAlt<0x08,  "lda $RA,0($RB)\t\t!gpdisp!$NUM">;  //Load address
573 def LDAHg : MFormAlt<0x09, "ldah $RA,0($RB)\t\t!gpdisp!$NUM">;  //Load address
574 }
575
576 //Load quad, rellocated literal form
577 let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in 
578 def LDQl : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!literal",
579                  [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))]>;
580 def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
581           (LDQl texternalsym:$ext, GPRC:$RB)>;
582
583 //Branches, int
584 def BEQ : BForm<0x39,  "beq $RA,$DISP">; //Branch if = zero
585 def BGE : BForm<0x3E,  "bge $RA,$DISP">; //Branch if >= zero
586 def BGT : BForm<0x3F,  "bgt $RA,$DISP">; //Branch if > zero
587 def BLBC : BForm<0x38, "blbc $RA,$DISP">; //Branch if low bit clear
588 def BLBS : BForm<0x3C, "blbs $RA,$DISP">; //Branch if low bit set
589 def BLE : BForm<0x3B,  "ble $RA,$DISP">; //Branch if <= zero
590 def BLT : BForm<0x3A,  "blt $RA,$DISP">; //Branch if < zero
591 def BNE : BForm<0x3D,  "bne $RA,$DISP">; //Branch if != zero
592
593 //Branches, float
594 def FBEQ : FBForm<0x31, "fbeq $RA,$DISP">; //Floating branch if =  zero
595 def FBGE : FBForm<0x36, "fbge $RA,$DISP">; //Floating branch if >= zero
596 def FBGT : FBForm<0x37, "fbgt $RA,$DISP">; //Floating branch if > zero
597 def FBLE : FBForm<0x33, "fble $RA,$DISP">; //Floating branch if <= zero
598 def FBLT : FBForm<0x32, "fblt $RA,$DISP">; //Floating branch if < zero
599 def FBNE : FBForm<0x35, "fbne $RA,$DISP">; //Floating branch if != zero
600
601 def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter
602
603 //Basic Floating point ops
604
605 //Floats
606
607 let OperandList = (ops F4RC:$RC, F4RC:$RB), Fa = 31 in 
608 def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
609                    [(set F4RC:$RC, (fsqrt F4RC:$RB))]>;
610
611 let OperandList = (ops F4RC:$RC, F4RC:$RA, F4RC:$RB) in {
612 def ADDS  : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
613                    [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))]>;
614 def SUBS  : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
615                    [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))]>;
616 def DIVS  : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
617                    [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))]>;
618 def MULS  : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
619                    [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))]>;
620
621 def CPYSS  : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>;  //Copy sign
622 def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent
623 def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate
624 }
625
626 //Doubles
627
628 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in 
629 def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
630                    [(set F8RC:$RC, (fsqrt F8RC:$RB))]>;
631
632 let OperandList = (ops F8RC:$RC, F8RC:$RA, F8RC:$RB) in {
633 def ADDT  : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
634                    [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))]>;
635 def SUBT  : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
636                    [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))]>;
637 def DIVT  : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
638                    [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))]>;
639 def MULT  : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
640                    [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))]>;
641
642 def CPYST  : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>;  //Copy sign
643 def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent
644 def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate
645
646 def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", []>;
647 //                    [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
648 def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", []>;
649 //                    [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
650 def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", []>;
651 //                    [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
652 def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", []>;
653 //                    [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
654 }
655 //TODO: Add lots more FP patterns
656
657 //conditional moves, floats
658 let OperandList = (ops F4RC:$RDEST, F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
659     isTwoAddress = 1 in {
660 def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if = zero
661 def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if >= zero
662 def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if > zero
663 def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if <= zero
664 def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[]>; // FCMOVE if < zero
665 def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if != zero
666 }
667 //conditional moves, doubles
668 let OperandList = (ops F8RC:$RDEST, F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
669     isTwoAddress = 1 in {
670 def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", []>;
671 def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", []>;
672 def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", []>;
673 def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", []>;
674 def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", []>;
675 def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", []>;
676 }
677
678 //misc FP selects
679 //Select double
680 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
681       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
682 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
683       (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
684 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
685       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
686 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
687       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
688 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
689       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
690 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
691       (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
692 //Select single
693 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
694       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
695 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
696       (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
697 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
698       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
699 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
700       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
701 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
702       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
703 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
704       (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
705
706
707
708 let OperandList = (ops GPRC:$RC, F4RC:$RA), Fb = 31 in 
709 def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[]>; //Floating to integer move, S_floating
710 let OperandList = (ops GPRC:$RC, F8RC:$RA), Fb = 31 in 
711 def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
712         [(set GPRC:$RC, (Alpha_ftoit F8RC:$RA))]>; //Floating to integer move
713 let OperandList = (ops F4RC:$RC, GPRC:$RA), Fb = 31 in 
714 def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[]>; //Integer to floating move, S_floating
715 let OperandList = (ops F8RC:$RC, GPRC:$RA), Fb = 31 in 
716 def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
717         [(set F8RC:$RC, (Alpha_itoft GPRC:$RA))]>; //Integer to floating move
718
719
720 let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in 
721 def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
722         [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))]>;
723 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in 
724 def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
725         [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))]>;
726 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in 
727 def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
728         [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))]>;
729 let OperandList = (ops F8RC:$RC, F4RC:$RB), Fa = 31 in 
730 def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
731                    [(set F8RC:$RC, (fextend F4RC:$RB))]>;
732 let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in 
733 def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
734                    [(set F4RC:$RC, (fround F8RC:$RB))]>;
735
736 //S_floating : IEEE Single
737 //T_floating : IEEE Double
738
739 //Unused instructions
740 //Mnemonic Format Opcode Description
741 //CALL_PAL Pcd 00 Trap to PALcode
742 //ECB Mfc 18.E800 Evict cache block
743 //EXCB Mfc 18.0400 Exception barrier
744 //FETCH Mfc 18.8000 Prefetch data
745 //FETCH_M Mfc 18.A000 Prefetch data, modify intent
746 //LDL_L Mem 2A Load sign-extended longword locked
747 //LDQ_L Mem 2B Load quadword locked
748 //LDQ_U Mem 0B Load unaligned quadword
749 //MB Mfc 18.4000 Memory barrier
750 //STL_C Mem 2E Store longword conditional
751 //STQ_C Mem 2F Store quadword conditional
752 //STQ_U Mem 0F Store unaligned quadword
753 //TRAPB Mfc 18.0000 Trap barrier
754 //WH64 Mfc 18.F800 Write hint \14 64 bytes
755 //WMB Mfc 18.4400 Write memory barrier
756 //MF_FPCR F-P 17.025 Move from FPCR
757 //MT_FPCR F-P 17.024 Move to FPCR
758 //There are in the Multimedia extentions, so let's not use them yet
759 //def MAXSB8  : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
760 //def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
761 //def MAXUB8  : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
762 //def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
763 //def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
764 //def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
765 //def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
766 //def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
767 //def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
768 //def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
769 //def PKWB  : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
770 //def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
771 //def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
772 //CVTLQ F-P 17.010 Convert longword to quadword
773 //CVTQL F-P 17.030 Convert quadword to longword
774 //def AMASK    : OForm< 0x11, 0x61, "AMASK $RA,$RB,$RC", []>; //Architecture mask
775 //def AMASKi   : OFormL<0x11, 0x61, "AMASK $RA,$L,$RC", []>; //Architecture mask
776
777
778 //Constant handling
779
780 def immConst2Part  : PatLeaf<(imm), [{
781   // immZAP predicate - True if the immediate fits is suitable for use in a
782   // ZAP instruction
783   int64_t val = (int64_t)N->getValue();
784   return (val <= (int64_t)IMM_HIGH +(int64_t)IMM_HIGH* (int64_t)IMM_MULT &
785                val >= (int64_t)IMM_LOW + (int64_t)IMM_LOW * (int64_t)IMM_MULT);
786 }]>;
787
788 //TODO: factor this out
789 def LL16 : SDNodeXForm<imm, [{
790 int64_t l = N->getValue();
791   int64_t y = l / IMM_MULT;
792   if (l % IMM_MULT > IMM_HIGH)
793     ++y;
794   return getI64Imm(l - y * IMM_MULT);
795 }]>;
796 //TODO: factor this out
797 def LH16 : SDNodeXForm<imm, [{
798 int64_t l = N->getValue();
799   int64_t y = l / IMM_MULT;
800   if (l % IMM_MULT > IMM_HIGH)
801     ++y;
802   return getI64Imm(y);
803 }]>;
804
805 def : Pat<(i64 immConst2Part:$imm),
806           (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
807
808 def : Pat<(i64 immSExt16:$imm),
809           (LDA immSExt16:$imm, R31)>;
810
811 //TODO: I want to just define these like this!
812 //def : Pat<(i64 0),
813 //          (R31)>;
814 //def : Pat<(f64 0.0),
815 //          (F31)>;
816 //def : Pat<(f64 -0.0),
817 //          (CPYSNT F31, F31)>;
818 //def : Pat<(f32 0.0),
819 //          (F31)>;
820 //def : Pat<(f32 -0.0),
821 //          (CPYSNS F31, F31)>;
822
823 //Misc Patterns:
824
825 def : Pat<(sext_inreg GPRC:$RB, i32),
826           (ADDLi GPRC:$RB, 0)>;
827
828 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
829           (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>; //may be CMOVNE
830
831 def : Pat<(fabs F8RC:$RB),
832           (CPYST F31, F8RC:$RB)>;
833 def : Pat<(fabs F4RC:$RB),
834           (CPYSS F31, F4RC:$RB)>;
835 def : Pat<(fneg F8RC:$RB),
836           (CPYSNT F8RC:$RB, F8RC:$RB)>;
837 def : Pat<(fneg F4RC:$RB),
838           (CPYSNS F4RC:$RB, F4RC:$RB)>;
839 //Yes, signed multiply high is ugly
840 def : Pat<(mulhs GPRC:$RA, GPRC:$RB),
841           (SUBQ (UMULH GPRC:$RA, GPRC:$RB), (ADDQ (CMOVGE GPRC:$RB, R31, GPRC:$RA), 
842                                                  (CMOVGE GPRC:$RA, R31, GPRC:$RB)))>;