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