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