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