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