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