1//===- AlphaInstrInfo.td - The Alpha Instruction Set -------*- tablegen -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// 11//===----------------------------------------------------------------------===// 12 13include "AlphaInstrFormats.td" 14 15//******************** 16//Custom DAG Nodes 17//******************** 18 19def SDTFPUnaryOpUnC : SDTypeProfile<1, 1, [ 20 SDTCisFP<1>, SDTCisFP<0> 21]>; 22def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>; 23def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>; 24def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_" , SDTFPUnaryOp, []>; 25def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>; 26def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>; 27def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, [SDNPMayLoad]>; 28 29def retflag : SDNode<"AlphaISD::RET_FLAG", SDTNone, 30 [SDNPHasChain, SDNPOptInGlue]>; 31 32// These are target-independent nodes, but have target-specific formats. 33def SDT_AlphaCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64> ]>; 34def SDT_AlphaCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i64>, 35 SDTCisVT<1, i64> ]>; 36 37def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeqStart, 38 [SDNPHasChain, SDNPOutGlue]>; 39def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AlphaCallSeqEnd, 40 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 41 42//******************** 43//Paterns for matching 44//******************** 45def invX : SDNodeXForm<imm, [{ //invert 46 return getI64Imm(~N->getZExtValue()); 47}]>; 48def negX : SDNodeXForm<imm, [{ //negate 49 return getI64Imm(~N->getZExtValue() + 1); 50}]>; 51def SExt32 : SDNodeXForm<imm, [{ //signed extend int to long 52 return getI64Imm(((int64_t)N->getZExtValue() << 32) >> 32); 53}]>; 54def SExt16 : SDNodeXForm<imm, [{ //signed extend int to long 55 return getI64Imm(((int64_t)N->getZExtValue() << 48) >> 48); 56}]>; 57def LL16 : SDNodeXForm<imm, [{ //lda part of constant 58 return getI64Imm(get_lda16(N->getZExtValue())); 59}]>; 60def LH16 : SDNodeXForm<imm, [{ //ldah part of constant (or more if too big) 61 return getI64Imm(get_ldah16(N->getZExtValue())); 62}]>; 63def iZAPX : SDNodeXForm<and, [{ // get imm to ZAPi 64 ConstantSDNode *RHS = cast<ConstantSDNode>(N->getOperand(1)); 65 return getI64Imm(get_zapImm(SDValue(), RHS->getZExtValue())); 66}]>; 67def nearP2X : SDNodeXForm<imm, [{ 68 return getI64Imm(Log2_64(getNearPower2((uint64_t)N->getZExtValue()))); 69}]>; 70def nearP2RemX : SDNodeXForm<imm, [{ 71 uint64_t x = 72 abs64(N->getZExtValue() - getNearPower2((uint64_t)N->getZExtValue())); 73 return getI64Imm(Log2_64(x)); 74}]>; 75 76def immUExt8 : PatLeaf<(imm), [{ //imm fits in 8 bit zero extended field 77 return (uint64_t)N->getZExtValue() == (uint8_t)N->getZExtValue(); 78}]>; 79def immUExt8inv : PatLeaf<(imm), [{ //inverted imm fits in 8 bit zero extended field 80 return (uint64_t)~N->getZExtValue() == (uint8_t)~N->getZExtValue(); 81}], invX>; 82def immUExt8neg : PatLeaf<(imm), [{ //negated imm fits in 8 bit zero extended field 83 return ((uint64_t)~N->getZExtValue() + 1) == 84 (uint8_t)((uint64_t)~N->getZExtValue() + 1); 85}], negX>; 86def immSExt16 : PatLeaf<(imm), [{ //imm fits in 16 bit sign extended field 87 return ((int64_t)N->getZExtValue() << 48) >> 48 == 88 (int64_t)N->getZExtValue(); 89}]>; 90def immSExt16int : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended field 91 return ((int64_t)N->getZExtValue() << 48) >> 48 == 92 ((int64_t)N->getZExtValue() << 32) >> 32; 93}], SExt16>; 94 95def zappat : PatFrag<(ops node:$LHS), (and node:$LHS, imm), [{ 96 ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N->getOperand(1)); 97 if (!RHS) return 0; 98 uint64_t build = get_zapImm(N->getOperand(0), (uint64_t)RHS->getZExtValue()); 99 return build != 0; 100}]>; 101 102def immFPZ : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0 103 (void)N; // silence warning. 104 return true; 105}]>; 106 107def immRem1 :PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),1,0);}]>; 108def immRem2 :PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),2,0);}]>; 109def immRem3 :PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),3,0);}]>; 110def immRem4 :PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),4,0);}]>; 111def immRem5 :PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),5,0);}]>; 112def immRem1n:PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),1,1);}]>; 113def immRem2n:PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),2,1);}]>; 114def immRem3n:PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),3,1);}]>; 115def immRem4n:PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),4,1);}]>; 116def immRem5n:PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),5,1);}]>; 117 118def immRemP2n : PatLeaf<(imm), [{ 119 return isPowerOf2_64(getNearPower2((uint64_t)N->getZExtValue()) - 120 N->getZExtValue()); 121}]>; 122def immRemP2 : PatLeaf<(imm), [{ 123 return isPowerOf2_64(N->getZExtValue() - 124 getNearPower2((uint64_t)N->getZExtValue())); 125}]>; 126def immUExt8ME : PatLeaf<(imm), [{ //use this imm for mulqi 127 int64_t d = abs64((int64_t)N->getZExtValue() - 128 (int64_t)getNearPower2((uint64_t)N->getZExtValue())); 129 if (isPowerOf2_64(d)) return false; 130 switch (d) { 131 case 1: case 3: case 5: return false; 132 default: return (uint64_t)N->getZExtValue() == (uint8_t)N->getZExtValue(); 133 }; 134}]>; 135 136def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>; 137def add4 : PatFrag<(ops node:$op1, node:$op2), 138 (add (shl node:$op1, 2), node:$op2)>; 139def sub4 : PatFrag<(ops node:$op1, node:$op2), 140 (sub (shl node:$op1, 2), node:$op2)>; 141def add8 : PatFrag<(ops node:$op1, node:$op2), 142 (add (shl node:$op1, 3), node:$op2)>; 143def sub8 : PatFrag<(ops node:$op1, node:$op2), 144 (sub (shl node:$op1, 3), node:$op2)>; 145class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 146class CmpOpFrag<dag res> : PatFrag<(ops node:$R), res>; 147 148//Pseudo ops for selection 149 150def WTF : PseudoInstAlpha<(outs), (ins variable_ops), "#wtf", [], s_pseudo>; 151 152let hasCtrlDep = 1, Defs = [R30], Uses = [R30] in { 153def ADJUSTSTACKUP : PseudoInstAlpha<(outs), (ins s64imm:$amt), 154 "; ADJUP $amt", 155 [(callseq_start timm:$amt)], s_pseudo>; 156def ADJUSTSTACKDOWN : PseudoInstAlpha<(outs), (ins s64imm:$amt1, s64imm:$amt2), 157 "; ADJDOWN $amt1", 158 [(callseq_end timm:$amt1, timm:$amt2)], s_pseudo>; 159} 160 161def ALTENT : PseudoInstAlpha<(outs), (ins s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>; 162def PCLABEL : PseudoInstAlpha<(outs), (ins s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>; 163def MEMLABEL : PseudoInstAlpha<(outs), (ins s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m), 164 "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>; 165 166 167let usesCustomInserter = 1 in { // Expanded after instruction selection. 168def CAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$cmp, GPRC:$swp), "", 169 [(set GPRC:$dst, (atomic_cmp_swap_32 GPRC:$ptr, GPRC:$cmp, GPRC:$swp))], s_pseudo>; 170def CAS64 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$cmp, GPRC:$swp), "", 171 [(set GPRC:$dst, (atomic_cmp_swap_64 GPRC:$ptr, GPRC:$cmp, GPRC:$swp))], s_pseudo>; 172 173def LAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "", 174 [(set GPRC:$dst, (atomic_load_add_32 GPRC:$ptr, GPRC:$swp))], s_pseudo>; 175def LAS64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "", 176 [(set GPRC:$dst, (atomic_load_add_64 GPRC:$ptr, GPRC:$swp))], s_pseudo>; 177 178def SWAP32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "", 179 [(set GPRC:$dst, (atomic_swap_32 GPRC:$ptr, GPRC:$swp))], s_pseudo>; 180def SWAP64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "", 181 [(set GPRC:$dst, (atomic_swap_64 GPRC:$ptr, GPRC:$swp))], s_pseudo>; 182} 183 184//*********************** 185//Real instructions 186//*********************** 187 188//Operation Form: 189 190//conditional moves, int 191 192multiclass cmov_inst<bits<7> fun, string asmstr, PatFrag OpNode> { 193def r : OForm4<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"), 194 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>; 195def i : OForm4L<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"), 196 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), immUExt8:$RTRUE, GPRC:$RFALSE))], s_cmov>; 197} 198 199defm CMOVEQ : cmov_inst<0x24, "cmoveq", CmpOpFrag<(seteq node:$R, 0)>>; 200defm CMOVNE : cmov_inst<0x26, "cmovne", CmpOpFrag<(setne node:$R, 0)>>; 201defm CMOVLT : cmov_inst<0x44, "cmovlt", CmpOpFrag<(setlt node:$R, 0)>>; 202defm CMOVLE : cmov_inst<0x64, "cmovle", CmpOpFrag<(setle node:$R, 0)>>; 203defm CMOVGT : cmov_inst<0x66, "cmovgt", CmpOpFrag<(setgt node:$R, 0)>>; 204defm CMOVGE : cmov_inst<0x46, "cmovge", CmpOpFrag<(setge node:$R, 0)>>; 205defm CMOVLBC : cmov_inst<0x16, "cmovlbc", CmpOpFrag<(xor node:$R, 1)>>; 206defm CMOVLBS : cmov_inst<0x14, "cmovlbs", CmpOpFrag<(and node:$R, 1)>>; 207 208//General pattern for cmov 209def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2), 210 (CMOVNEr GPRC:$src2, GPRC:$src1, GPRC:$which)>; 211def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2), 212 (CMOVEQi GPRC:$src1, immUExt8:$src2, GPRC:$which)>; 213 214//Invert sense when we can for constants: 215def : Pat<(select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE), 216 (CMOVEQi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>; 217def : Pat<(select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE), 218 (CMOVLEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>; 219def : Pat<(select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE), 220 (CMOVLTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>; 221def : Pat<(select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE), 222 (CMOVGEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>; 223def : Pat<(select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE), 224 (CMOVGTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>; 225 226multiclass all_inst<bits<6> opc, bits<7> funl, bits<7> funq, 227 string asmstr, PatFrag OpNode, InstrItinClass itin> { 228 def Lr : OForm< opc, funl, !strconcat(asmstr, "l $RA,$RB,$RC"), 229 [(set GPRC:$RC, (intop (OpNode GPRC:$RA, GPRC:$RB)))], itin>; 230 def Li : OFormL<opc, funl, !strconcat(asmstr, "l $RA,$L,$RC"), 231 [(set GPRC:$RC, (intop (OpNode GPRC:$RA, immUExt8:$L)))], itin>; 232 def Qr : OForm< opc, funq, !strconcat(asmstr, "q $RA,$RB,$RC"), 233 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>; 234 def Qi : OFormL<opc, funq, !strconcat(asmstr, "q $RA,$L,$RC"), 235 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>; 236} 237 238defm MUL : all_inst<0x13, 0x00, 0x20, "mul", BinOpFrag<(mul node:$LHS, node:$RHS)>, s_imul>; 239defm ADD : all_inst<0x10, 0x00, 0x20, "add", BinOpFrag<(add node:$LHS, node:$RHS)>, s_iadd>; 240defm S4ADD : all_inst<0x10, 0x02, 0x22, "s4add", add4, s_iadd>; 241defm S8ADD : all_inst<0x10, 0x12, 0x32, "s8add", add8, s_iadd>; 242defm S4SUB : all_inst<0x10, 0x0B, 0x2B, "s4sub", sub4, s_iadd>; 243defm S8SUB : all_inst<0x10, 0x1B, 0x3B, "s8sub", sub8, s_iadd>; 244defm SUB : all_inst<0x10, 0x09, 0x29, "sub", BinOpFrag<(sub node:$LHS, node:$RHS)>, s_iadd>; 245//Const cases since legalize does sub x, int -> add x, inv(int) + 1 246def : Pat<(intop (add GPRC:$RA, immUExt8neg:$L)), (SUBLi GPRC:$RA, immUExt8neg:$L)>; 247def : Pat<(add GPRC:$RA, immUExt8neg:$L), (SUBQi GPRC:$RA, immUExt8neg:$L)>; 248def : Pat<(intop (add4 GPRC:$RA, immUExt8neg:$L)), (S4SUBLi GPRC:$RA, immUExt8neg:$L)>; 249def : Pat<(add4 GPRC:$RA, immUExt8neg:$L), (S4SUBQi GPRC:$RA, immUExt8neg:$L)>; 250def : Pat<(intop (add8 GPRC:$RA, immUExt8neg:$L)), (S8SUBLi GPRC:$RA, immUExt8neg:$L)>; 251def : Pat<(add8 GPRC:$RA, immUExt8neg:$L), (S8SUBQi GPRC:$RA, immUExt8neg:$L)>; 252 253multiclass log_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> { 254def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"), 255 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>; 256def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"), 257 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>; 258} 259multiclass inv_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> { 260def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"), 261 [(set GPRC:$RC, (OpNode GPRC:$RA, (not GPRC:$RB)))], itin>; 262def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"), 263 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8inv:$L))], itin>; 264} 265 266defm AND : log_inst<0x11, 0x00, "and", and, s_ilog>; 267defm BIC : inv_inst<0x11, 0x08, "bic", and, s_ilog>; 268defm BIS : log_inst<0x11, 0x20, "bis", or, s_ilog>; 269defm ORNOT : inv_inst<0x11, 0x28, "ornot", or, s_ilog>; 270defm XOR : log_inst<0x11, 0x40, "xor", xor, s_ilog>; 271defm EQV : inv_inst<0x11, 0x48, "eqv", xor, s_ilog>; 272 273defm SL : log_inst<0x12, 0x39, "sll", shl, s_ishf>; 274defm SRA : log_inst<0x12, 0x3c, "sra", sra, s_ishf>; 275defm SRL : log_inst<0x12, 0x34, "srl", srl, s_ishf>; 276defm UMULH : log_inst<0x13, 0x30, "umulh", mulhu, s_imul>; 277 278def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC", 279 [(set GPRC:$RC, (ctlz GPRC:$RB))], s_imisc>; 280def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC", 281 [(set GPRC:$RC, (ctpop GPRC:$RB))], s_imisc>; 282def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC", 283 [(set GPRC:$RC, (cttz GPRC:$RB))], s_imisc>; 284def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC", 285 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))], s_ishf>; 286def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC", 287 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))], s_ishf>; 288def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC", 289 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))], s_ishf>; 290def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC", 291 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>; 292def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC", 293 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))], s_ishf>; 294 295//def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low 296//def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high 297//def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high 298//def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low 299//def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high 300//def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high 301//def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low 302//def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low 303//def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high 304//def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high 305//def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low 306 307//def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low 308//def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low 309//def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high 310//def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high 311//def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low 312//def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low 313//def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high 314//def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high 315//def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low 316//def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low 317//def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high 318//def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high 319//def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low 320//def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low 321 322//def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low 323//def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low 324//def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high 325//def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high 326//def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low 327//def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low 328//def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high 329//def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high 330//def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low 331//def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low 332//def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high 333//def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high 334//def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low 335//def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low 336 337def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", [], s_ishf>; 338 339// Define the pattern that produces ZAPNOTi. 340def : Pat<(zappat:$imm GPRC:$RA), 341 (ZAPNOTi GPRC:$RA, (iZAPX GPRC:$imm))>; 342 343 344//Comparison, int 345//So this is a waste of what this instruction can do, but it still saves something 346def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC", 347 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))], s_ilog>; 348def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC", 349 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))], s_ilog>; 350def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC", 351 [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))], s_iadd>; 352def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC", 353 [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))], s_iadd>; 354def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC", 355 [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))], s_iadd>; 356def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC", 357 [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))], s_iadd>; 358def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC", 359 [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))], s_iadd>; 360def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC", 361 [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))], s_iadd>; 362def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC", 363 [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))], s_iadd>; 364def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC", 365 [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))], s_iadd>; 366def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC", 367 [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))], s_iadd>; 368def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC", 369 [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))], s_iadd>; 370 371//Patterns for unsupported int comparisons 372def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>; 373def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>; 374 375def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>; 376def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>; 377 378def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>; 379def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>; 380 381def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>; 382def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>; 383 384def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>; 385def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>; 386 387def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>; 388def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>; 389 390def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>; 391def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>; 392 393 394let isReturn = 1, isTerminator = 1, isBarrier = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in { 395 def RETDAG : MbrForm< 0x1A, 0x02, (ins), "ret $$31,($$26),1", s_jsr>; //Return from subroutine 396 def RETDAGp : MbrpForm< 0x1A, 0x02, (ins), "ret $$31,($$26),1", [(retflag)], s_jsr>; //Return from subroutine 397} 398 399let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, Ra = 31, disp = 0 in 400def JMP : MbrpForm< 0x1A, 0x00, (ins GPRC:$RS), "jmp $$31,($RS),0", 401 [(brind GPRC:$RS)], s_jsr>; //Jump 402 403let isCall = 1, Ra = 26, 404 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, 405 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, 406 F0, F1, 407 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, 408 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in { 409 def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", [], s_jsr>; //Branch to subroutine 410} 411let isCall = 1, Ra = 26, Rb = 27, disp = 0, 412 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, 413 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, 414 F0, F1, 415 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, 416 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in { 417 def JSR : MbrForm< 0x1A, 0x01, (ins), "jsr $$26,($$27),0", s_jsr>; //Jump to subroutine 418} 419 420let isCall = 1, Ra = 23, Rb = 27, disp = 0, 421 Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in 422 def JSRs : MbrForm< 0x1A, 0x01, (ins), "jsr $$23,($$27),0", s_jsr>; //Jump to div or rem 423 424 425def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ins GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return 426 427 428let OutOperandList = (outs GPRC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in { 429def LDQ : MForm<0x29, 1, "ldq $RA,$DISP($RB)", 430 [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>; 431def LDQr : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!gprellow", 432 [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>; 433def LDL : MForm<0x28, 1, "ldl $RA,$DISP($RB)", 434 [(set GPRC:$RA, (sextloadi32 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>; 435def LDLr : MForm<0x28, 1, "ldl $RA,$DISP($RB)\t\t!gprellow", 436 [(set GPRC:$RA, (sextloadi32 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>; 437def LDBU : MForm<0x0A, 1, "ldbu $RA,$DISP($RB)", 438 [(set GPRC:$RA, (zextloadi8 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>; 439def LDBUr : MForm<0x0A, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow", 440 [(set GPRC:$RA, (zextloadi8 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>; 441def LDWU : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)", 442 [(set GPRC:$RA, (zextloadi16 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>; 443def LDWUr : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow", 444 [(set GPRC:$RA, (zextloadi16 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>; 445} 446 447 448let OutOperandList = (outs), InOperandList = (ins GPRC:$RA, s64imm:$DISP, GPRC:$RB) in { 449def STB : MForm<0x0E, 0, "stb $RA,$DISP($RB)", 450 [(truncstorei8 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>; 451def STBr : MForm<0x0E, 0, "stb $RA,$DISP($RB)\t\t!gprellow", 452 [(truncstorei8 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>; 453def STW : MForm<0x0D, 0, "stw $RA,$DISP($RB)", 454 [(truncstorei16 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>; 455def STWr : MForm<0x0D, 0, "stw $RA,$DISP($RB)\t\t!gprellow", 456 [(truncstorei16 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>; 457def STL : MForm<0x2C, 0, "stl $RA,$DISP($RB)", 458 [(truncstorei32 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>; 459def STLr : MForm<0x2C, 0, "stl $RA,$DISP($RB)\t\t!gprellow", 460 [(truncstorei32 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>; 461def STQ : MForm<0x2D, 0, "stq $RA,$DISP($RB)", 462 [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>; 463def STQr : MForm<0x2D, 0, "stq $RA,$DISP($RB)\t\t!gprellow", 464 [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>; 465} 466 467//Load address 468let OutOperandList = (outs GPRC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in { 469def LDA : MForm<0x08, 0, "lda $RA,$DISP($RB)", 470 [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_lda>; 471def LDAr : MForm<0x08, 0, "lda $RA,$DISP($RB)\t\t!gprellow", 472 [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address 473def LDAH : MForm<0x09, 0, "ldah $RA,$DISP($RB)", 474 [], s_lda>; //Load address high 475def LDAHr : MForm<0x09, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh", 476 [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address high 477} 478 479let OutOperandList = (outs), InOperandList = (ins F4RC:$RA, s64imm:$DISP, GPRC:$RB) in { 480def STS : MForm<0x26, 0, "sts $RA,$DISP($RB)", 481 [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>; 482def STSr : MForm<0x26, 0, "sts $RA,$DISP($RB)\t\t!gprellow", 483 [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>; 484} 485let OutOperandList = (outs F4RC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in { 486def LDS : MForm<0x22, 1, "lds $RA,$DISP($RB)", 487 [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>; 488def LDSr : MForm<0x22, 1, "lds $RA,$DISP($RB)\t\t!gprellow", 489 [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>; 490} 491let OutOperandList = (outs), InOperandList = (ins F8RC:$RA, s64imm:$DISP, GPRC:$RB) in { 492def STT : MForm<0x27, 0, "stt $RA,$DISP($RB)", 493 [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>; 494def STTr : MForm<0x27, 0, "stt $RA,$DISP($RB)\t\t!gprellow", 495 [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>; 496} 497let OutOperandList = (outs F8RC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in { 498def LDT : MForm<0x23, 1, "ldt $RA,$DISP($RB)", 499 [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>; 500def LDTr : MForm<0x23, 1, "ldt $RA,$DISP($RB)\t\t!gprellow", 501 [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>; 502} 503 504 505//constpool rels 506def : Pat<(i64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))), 507 (LDQr tconstpool:$DISP, GPRC:$RB)>; 508def : Pat<(i64 (sextloadi32 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))), 509 (LDLr tconstpool:$DISP, GPRC:$RB)>; 510def : Pat<(i64 (zextloadi8 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))), 511 (LDBUr tconstpool:$DISP, GPRC:$RB)>; 512def : Pat<(i64 (zextloadi16 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))), 513 (LDWUr tconstpool:$DISP, GPRC:$RB)>; 514def : Pat<(i64 (Alpha_gprello tconstpool:$DISP, GPRC:$RB)), 515 (LDAr tconstpool:$DISP, GPRC:$RB)>; 516def : Pat<(i64 (Alpha_gprelhi tconstpool:$DISP, GPRC:$RB)), 517 (LDAHr tconstpool:$DISP, GPRC:$RB)>; 518def : Pat<(f32 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))), 519 (LDSr tconstpool:$DISP, GPRC:$RB)>; 520def : Pat<(f64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))), 521 (LDTr tconstpool:$DISP, GPRC:$RB)>; 522 523//jumptable rels 524def : Pat<(i64 (Alpha_gprelhi tjumptable:$DISP, GPRC:$RB)), 525 (LDAHr tjumptable:$DISP, GPRC:$RB)>; 526def : Pat<(i64 (Alpha_gprello tjumptable:$DISP, GPRC:$RB)), 527 (LDAr tjumptable:$DISP, GPRC:$RB)>; 528 529 530//misc ext patterns 531def : Pat<(i64 (extloadi8 (add GPRC:$RB, immSExt16:$DISP))), 532 (LDBU immSExt16:$DISP, GPRC:$RB)>; 533def : Pat<(i64 (extloadi16 (add GPRC:$RB, immSExt16:$DISP))), 534 (LDWU immSExt16:$DISP, GPRC:$RB)>; 535def : Pat<(i64 (extloadi32 (add GPRC:$RB, immSExt16:$DISP))), 536 (LDL immSExt16:$DISP, GPRC:$RB)>; 537 538//0 disp patterns 539def : Pat<(i64 (load GPRC:$addr)), 540 (LDQ 0, GPRC:$addr)>; 541def : Pat<(f64 (load GPRC:$addr)), 542 (LDT 0, GPRC:$addr)>; 543def : Pat<(f32 (load GPRC:$addr)), 544 (LDS 0, GPRC:$addr)>; 545def : Pat<(i64 (sextloadi32 GPRC:$addr)), 546 (LDL 0, GPRC:$addr)>; 547def : Pat<(i64 (zextloadi16 GPRC:$addr)), 548 (LDWU 0, GPRC:$addr)>; 549def : Pat<(i64 (zextloadi8 GPRC:$addr)), 550 (LDBU 0, GPRC:$addr)>; 551def : Pat<(i64 (extloadi8 GPRC:$addr)), 552 (LDBU 0, GPRC:$addr)>; 553def : Pat<(i64 (extloadi16 GPRC:$addr)), 554 (LDWU 0, GPRC:$addr)>; 555def : Pat<(i64 (extloadi32 GPRC:$addr)), 556 (LDL 0, GPRC:$addr)>; 557 558def : Pat<(store GPRC:$DATA, GPRC:$addr), 559 (STQ GPRC:$DATA, 0, GPRC:$addr)>; 560def : Pat<(store F8RC:$DATA, GPRC:$addr), 561 (STT F8RC:$DATA, 0, GPRC:$addr)>; 562def : Pat<(store F4RC:$DATA, GPRC:$addr), 563 (STS F4RC:$DATA, 0, GPRC:$addr)>; 564def : Pat<(truncstorei32 GPRC:$DATA, GPRC:$addr), 565 (STL GPRC:$DATA, 0, GPRC:$addr)>; 566def : Pat<(truncstorei16 GPRC:$DATA, GPRC:$addr), 567 (STW GPRC:$DATA, 0, GPRC:$addr)>; 568def : Pat<(truncstorei8 GPRC:$DATA, GPRC:$addr), 569 (STB GPRC:$DATA, 0, GPRC:$addr)>; 570 571 572//load address, rellocated gpdist form 573let OutOperandList = (outs GPRC:$RA), 574 InOperandList = (ins s16imm:$DISP, GPRC:$RB, s16imm:$NUM), 575 mayLoad = 1 in { 576def LDAg : MForm<0x08, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address 577def LDAHg : MForm<0x09, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address 578} 579 580//Load quad, rellocated literal form 581let OutOperandList = (outs GPRC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in 582def LDQl : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!literal", 583 [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))], s_ild>; 584def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB), 585 (LDQl texternalsym:$ext, GPRC:$RB)>; 586 587let OutOperandList = (outs GPRC:$RR), 588 InOperandList = (ins GPRC:$RA, s64imm:$DISP, GPRC:$RB), 589 Constraints = "$RA = $RR", 590 DisableEncoding = "$RR" in { 591def STQ_C : MForm<0x2F, 0, "stq_l $RA,$DISP($RB)", [], s_ist>; 592def STL_C : MForm<0x2E, 0, "stl_l $RA,$DISP($RB)", [], s_ist>; 593} 594let OutOperandList = (outs GPRC:$RA), 595 InOperandList = (ins s64imm:$DISP, GPRC:$RB), 596 mayLoad = 1 in { 597def LDQ_L : MForm<0x2B, 1, "ldq_l $RA,$DISP($RB)", [], s_ild>; 598def LDL_L : MForm<0x2A, 1, "ldl_l $RA,$DISP($RB)", [], s_ild>; 599} 600 601def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process cycle counter 602def MB : MfcPForm<0x18, 0x4000, "mb", s_imisc>; //memory barrier 603def WMB : MfcPForm<0x18, 0x4400, "wmb", s_imisc>; //write memory barrier 604 605def : Pat<(membarrier (i64 imm), (i64 imm), (i64 imm), (i64 1), (i64 imm)), 606 (WMB)>; 607def : Pat<(membarrier (i64 imm), (i64 imm), (i64 imm), (i64 imm), (i64 imm)), 608 (MB)>; 609 610def : Pat<(atomic_fence (imm), (imm)), (MB)>; 611 612//Basic Floating point ops 613 614//Floats 615 616let OutOperandList = (outs F4RC:$RC), InOperandList = (ins F4RC:$RB), Fa = 31 in 617def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC", 618 [(set F4RC:$RC, (fsqrt F4RC:$RB))], s_fsqrts>; 619 620let OutOperandList = (outs F4RC:$RC), InOperandList = (ins F4RC:$RA, F4RC:$RB) in { 621def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC", 622 [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))], s_fadd>; 623def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC", 624 [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))], s_fadd>; 625def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC", 626 [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))], s_fdivs>; 627def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC", 628 [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))], s_fmul>; 629 630def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", 631 [(set F4RC:$RC, (fcopysign F4RC:$RB, F4RC:$RA))], s_fadd>; 632def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent 633def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", 634 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F4RC:$RA)))], s_fadd>; 635} 636 637//Doubles 638 639let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F8RC:$RB), Fa = 31 in 640def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC", 641 [(set F8RC:$RC, (fsqrt F8RC:$RB))], s_fsqrtt>; 642 643let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F8RC:$RA, F8RC:$RB) in { 644def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC", 645 [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))], s_fadd>; 646def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC", 647 [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))], s_fadd>; 648def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC", 649 [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))], s_fdivt>; 650def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC", 651 [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))], s_fmul>; 652 653def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", 654 [(set F8RC:$RC, (fcopysign F8RC:$RB, F8RC:$RA))], s_fadd>; 655def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent 656def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", 657 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F8RC:$RA)))], s_fadd>; 658 659def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", [], s_fadd>; 660// [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>; 661def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", [], s_fadd>; 662// [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>; 663def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", [], s_fadd>; 664// [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>; 665def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>; 666// [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>; 667} 668 669//More CPYS forms: 670let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F4RC:$RA, F8RC:$RB) in { 671def CPYSTs : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", 672 [(set F8RC:$RC, (fcopysign F8RC:$RB, F4RC:$RA))], s_fadd>; 673def CPYSNTs : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", 674 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F4RC:$RA)))], s_fadd>; 675} 676let OutOperandList = (outs F4RC:$RC), InOperandList = (ins F8RC:$RA, F4RC:$RB) in { 677def CPYSSt : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", 678 [(set F4RC:$RC, (fcopysign F4RC:$RB, F8RC:$RA))], s_fadd>; 679def CPYSESt : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent 680def CPYSNSt : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", 681 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F8RC:$RA)))], s_fadd>; 682} 683 684//conditional moves, floats 685let OutOperandList = (outs F4RC:$RDEST), 686 InOperandList = (ins F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND), 687 Constraints = "$RTRUE = $RDEST" in { 688def FCMOVEQS : FPForm<0x17, 0x02A, 689 "fcmoveq $RCOND,$RTRUE,$RDEST", 690 [], s_fcmov>; //FCMOVE if = zero 691def FCMOVGES : FPForm<0x17, 0x02D, 692 "fcmovge $RCOND,$RTRUE,$RDEST", 693 [], s_fcmov>; //FCMOVE if >= zero 694def FCMOVGTS : FPForm<0x17, 0x02F, 695 "fcmovgt $RCOND,$RTRUE,$RDEST", 696 [], s_fcmov>; //FCMOVE if > zero 697def FCMOVLES : FPForm<0x17, 0x02E, 698 "fcmovle $RCOND,$RTRUE,$RDEST", 699 [], s_fcmov>; //FCMOVE if <= zero 700def FCMOVLTS : FPForm<0x17, 0x02C, 701 "fcmovlt $RCOND,$RTRUE,$RDEST", 702 [], s_fcmov>; // FCMOVE if < zero 703def FCMOVNES : FPForm<0x17, 0x02B, 704 "fcmovne $RCOND,$RTRUE,$RDEST", 705 [], s_fcmov>; //FCMOVE if != zero 706} 707//conditional moves, doubles 708let OutOperandList = (outs F8RC:$RDEST), 709 InOperandList = (ins F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND), 710 Constraints = "$RTRUE = $RDEST" in { 711def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", [], s_fcmov>; 712def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", [], s_fcmov>; 713def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", [], s_fcmov>; 714def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", [], s_fcmov>; 715def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", [], s_fcmov>; 716def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", [], s_fcmov>; 717} 718 719//misc FP selects 720//Select double 721 722def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 723 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 724def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 725 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 726def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 727 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 728 729def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 730 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 731def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 732 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 733def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 734 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 735 736def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 737 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>; 738def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 739 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>; 740def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 741 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>; 742 743def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 744 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>; 745def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 746 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>; 747def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 748 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>; 749 750def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 751 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>; 752def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 753 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>; 754def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 755 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>; 756 757def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 758 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>; 759def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 760 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>; 761def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), 762 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>; 763 764//Select single 765def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 766 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 767def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 768 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 769def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 770 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 771 772def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 773 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 774def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 775 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 776def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 777 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; 778 779def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 780 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>; 781def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 782 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>; 783def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 784 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>; 785 786def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 787 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>; 788def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 789 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>; 790def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 791 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>; 792 793def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 794 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>; 795def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 796 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>; 797def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 798 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>; 799 800def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 801 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>; 802def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 803 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>; 804def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), 805 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>; 806 807 808 809let OutOperandList = (outs GPRC:$RC), InOperandList = (ins F4RC:$RA), Fb = 31 in 810def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC", 811 [(set GPRC:$RC, (bitconvert F4RC:$RA))], s_ftoi>; //Floating to integer move, S_floating 812let OutOperandList = (outs GPRC:$RC), InOperandList = (ins F8RC:$RA), Fb = 31 in 813def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC", 814 [(set GPRC:$RC, (bitconvert F8RC:$RA))], s_ftoi>; //Floating to integer move 815let OutOperandList = (outs F4RC:$RC), InOperandList = (ins GPRC:$RA), Fb = 31 in 816def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC", 817 [(set F4RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move, S_floating 818let OutOperandList = (outs F8RC:$RC), InOperandList = (ins GPRC:$RA), Fb = 31 in 819def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC", 820 [(set F8RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move 821 822 823let OutOperandList = (outs F4RC:$RC), InOperandList = (ins F8RC:$RB), Fa = 31 in 824def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC", 825 [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))], s_fadd>; 826let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F8RC:$RB), Fa = 31 in 827def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC", 828 [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))], s_fadd>; 829let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F8RC:$RB), Fa = 31 in 830def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC", 831 [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))], s_fadd>; 832let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F4RC:$RB), Fa = 31 in 833def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC", 834 [(set F8RC:$RC, (fextend F4RC:$RB))], s_fadd>; 835let OutOperandList = (outs F4RC:$RC), InOperandList = (ins F8RC:$RB), Fa = 31 in 836def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC", 837 [(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>; 838 839def : Pat<(select GPRC:$RC, F8RC:$st, F8RC:$sf), 840 (f64 (FCMOVEQT F8RC:$st, F8RC:$sf, (ITOFT GPRC:$RC)))>; 841def : Pat<(select GPRC:$RC, F4RC:$st, F4RC:$sf), 842 (f32 (FCMOVEQS F4RC:$st, F4RC:$sf, (ITOFT GPRC:$RC)))>; 843 844///////////////////////////////////////////////////////// 845//Branching 846///////////////////////////////////////////////////////// 847class br_icc<bits<6> opc, string asmstr> 848 : BFormN<opc, (ins u64imm:$opc, GPRC:$R, target:$dst), 849 !strconcat(asmstr, " $R,$dst"), s_icbr>; 850class br_fcc<bits<6> opc, string asmstr> 851 : BFormN<opc, (ins u64imm:$opc, F8RC:$R, target:$dst), 852 !strconcat(asmstr, " $R,$dst"), s_fbr>; 853 854let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { 855let Ra = 31, isBarrier = 1 in 856def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>; 857 858def COND_BRANCH_I : BFormN<0, (ins u64imm:$opc, GPRC:$R, target:$dst), 859 "{:comment} COND_BRANCH imm:$opc, GPRC:$R, bb:$dst", 860 s_icbr>; 861def COND_BRANCH_F : BFormN<0, (ins u64imm:$opc, F8RC:$R, target:$dst), 862 "{:comment} COND_BRANCH imm:$opc, F8RC:$R, bb:$dst", 863 s_fbr>; 864//Branches, int 865def BEQ : br_icc<0x39, "beq">; 866def BGE : br_icc<0x3E, "bge">; 867def BGT : br_icc<0x3F, "bgt">; 868def BLBC : br_icc<0x38, "blbc">; 869def BLBS : br_icc<0x3C, "blbs">; 870def BLE : br_icc<0x3B, "ble">; 871def BLT : br_icc<0x3A, "blt">; 872def BNE : br_icc<0x3D, "bne">; 873 874//Branches, float 875def FBEQ : br_fcc<0x31, "fbeq">; 876def FBGE : br_fcc<0x36, "fbge">; 877def FBGT : br_fcc<0x37, "fbgt">; 878def FBLE : br_fcc<0x33, "fble">; 879def FBLT : br_fcc<0x32, "fblt">; 880def FBNE : br_fcc<0x36, "fbne">; 881} 882 883//An ugly trick to get the opcode as an imm I can use 884def immBRCond : SDNodeXForm<imm, [{ 885 switch((uint64_t)N->getZExtValue()) { 886 default: assert(0 && "Unknown branch type"); 887 case 0: return getI64Imm(Alpha::BEQ); 888 case 1: return getI64Imm(Alpha::BNE); 889 case 2: return getI64Imm(Alpha::BGE); 890 case 3: return getI64Imm(Alpha::BGT); 891 case 4: return getI64Imm(Alpha::BLE); 892 case 5: return getI64Imm(Alpha::BLT); 893 case 6: return getI64Imm(Alpha::BLBS); 894 case 7: return getI64Imm(Alpha::BLBC); 895 case 20: return getI64Imm(Alpha::FBEQ); 896 case 21: return getI64Imm(Alpha::FBNE); 897 case 22: return getI64Imm(Alpha::FBGE); 898 case 23: return getI64Imm(Alpha::FBGT); 899 case 24: return getI64Imm(Alpha::FBLE); 900 case 25: return getI64Imm(Alpha::FBLT); 901 } 902}]>; 903 904//Int cond patterns 905def : Pat<(brcond (seteq GPRC:$RA, 0), bb:$DISP), 906 (COND_BRANCH_I (immBRCond 0), GPRC:$RA, bb:$DISP)>; 907def : Pat<(brcond (setge GPRC:$RA, 0), bb:$DISP), 908 (COND_BRANCH_I (immBRCond 2), GPRC:$RA, bb:$DISP)>; 909def : Pat<(brcond (setgt GPRC:$RA, 0), bb:$DISP), 910 (COND_BRANCH_I (immBRCond 3), GPRC:$RA, bb:$DISP)>; 911def : Pat<(brcond (and GPRC:$RA, 1), bb:$DISP), 912 (COND_BRANCH_I (immBRCond 6), GPRC:$RA, bb:$DISP)>; 913def : Pat<(brcond (setle GPRC:$RA, 0), bb:$DISP), 914 (COND_BRANCH_I (immBRCond 4), GPRC:$RA, bb:$DISP)>; 915def : Pat<(brcond (setlt GPRC:$RA, 0), bb:$DISP), 916 (COND_BRANCH_I (immBRCond 5), GPRC:$RA, bb:$DISP)>; 917def : Pat<(brcond (setne GPRC:$RA, 0), bb:$DISP), 918 (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>; 919 920def : Pat<(brcond GPRC:$RA, bb:$DISP), 921 (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>; 922def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP), 923 (COND_BRANCH_I (immBRCond 0), (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>; 924def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP), 925 (COND_BRANCH_I (immBRCond 0), (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>; 926 927//FP cond patterns 928def : Pat<(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP), 929 (COND_BRANCH_F (immBRCond 20), F8RC:$RA, bb:$DISP)>; 930def : Pat<(brcond (setne F8RC:$RA, immFPZ), bb:$DISP), 931 (COND_BRANCH_F (immBRCond 21), F8RC:$RA, bb:$DISP)>; 932def : Pat<(brcond (setge F8RC:$RA, immFPZ), bb:$DISP), 933 (COND_BRANCH_F (immBRCond 22), F8RC:$RA, bb:$DISP)>; 934def : Pat<(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP), 935 (COND_BRANCH_F (immBRCond 23), F8RC:$RA, bb:$DISP)>; 936def : Pat<(brcond (setle F8RC:$RA, immFPZ), bb:$DISP), 937 (COND_BRANCH_F (immBRCond 24), F8RC:$RA, bb:$DISP)>; 938def : Pat<(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP), 939 (COND_BRANCH_F (immBRCond 25), F8RC:$RA, bb:$DISP)>; 940 941 942def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP), 943 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>; 944def : Pat<(brcond (setoeq F8RC:$RA, F8RC:$RB), bb:$DISP), 945 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>; 946def : Pat<(brcond (setueq F8RC:$RA, F8RC:$RB), bb:$DISP), 947 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>; 948 949def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP), 950 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>; 951def : Pat<(brcond (setolt F8RC:$RA, F8RC:$RB), bb:$DISP), 952 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>; 953def : Pat<(brcond (setult F8RC:$RA, F8RC:$RB), bb:$DISP), 954 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>; 955 956def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP), 957 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>; 958def : Pat<(brcond (setole F8RC:$RA, F8RC:$RB), bb:$DISP), 959 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>; 960def : Pat<(brcond (setule F8RC:$RA, F8RC:$RB), bb:$DISP), 961 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>; 962 963def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP), 964 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>; 965def : Pat<(brcond (setogt F8RC:$RA, F8RC:$RB), bb:$DISP), 966 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>; 967def : Pat<(brcond (setugt F8RC:$RA, F8RC:$RB), bb:$DISP), 968 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>; 969 970def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP), 971 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>; 972def : Pat<(brcond (setoge F8RC:$RA, F8RC:$RB), bb:$DISP), 973 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>; 974def : Pat<(brcond (setuge F8RC:$RA, F8RC:$RB), bb:$DISP), 975 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>; 976 977def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP), 978 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>; 979def : Pat<(brcond (setone F8RC:$RA, F8RC:$RB), bb:$DISP), 980 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>; 981def : Pat<(brcond (setune F8RC:$RA, F8RC:$RB), bb:$DISP), 982 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>; 983 984 985def : Pat<(brcond (setoeq F8RC:$RA, immFPZ), bb:$DISP), 986 (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>; 987def : Pat<(brcond (setueq F8RC:$RA, immFPZ), bb:$DISP), 988 (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>; 989 990def : Pat<(brcond (setoge F8RC:$RA, immFPZ), bb:$DISP), 991 (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>; 992def : Pat<(brcond (setuge F8RC:$RA, immFPZ), bb:$DISP), 993 (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>; 994 995def : Pat<(brcond (setogt F8RC:$RA, immFPZ), bb:$DISP), 996 (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>; 997def : Pat<(brcond (setugt F8RC:$RA, immFPZ), bb:$DISP), 998 (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>; 999 1000def : Pat<(brcond (setole F8RC:$RA, immFPZ), bb:$DISP), 1001 (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>; 1002def : Pat<(brcond (setule F8RC:$RA, immFPZ), bb:$DISP), 1003 (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>; 1004 1005def : Pat<(brcond (setolt F8RC:$RA, immFPZ), bb:$DISP), 1006 (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>; 1007def : Pat<(brcond (setult F8RC:$RA, immFPZ), bb:$DISP), 1008 (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>; 1009 1010def : Pat<(brcond (setone F8RC:$RA, immFPZ), bb:$DISP), 1011 (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>; 1012def : Pat<(brcond (setune F8RC:$RA, immFPZ), bb:$DISP), 1013 (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>; 1014 1015//End Branches 1016 1017//S_floating : IEEE Single 1018//T_floating : IEEE Double 1019 1020//Unused instructions 1021//Mnemonic Format Opcode Description 1022//CALL_PAL Pcd 00 Trap to PALcode 1023//ECB Mfc 18.E800 Evict cache block 1024//EXCB Mfc 18.0400 Exception barrier 1025//FETCH Mfc 18.8000 Prefetch data 1026//FETCH_M Mfc 18.A000 Prefetch data, modify intent 1027//LDQ_U Mem 0B Load unaligned quadword 1028//MB Mfc 18.4000 Memory barrier 1029//STQ_U Mem 0F Store unaligned quadword 1030//TRAPB Mfc 18.0000 Trap barrier 1031//WH64 Mfc 18.F800 Write hint 64 bytes 1032//WMB Mfc 18.4400 Write memory barrier 1033//MF_FPCR F-P 17.025 Move from FPCR 1034//MT_FPCR F-P 17.024 Move to FPCR 1035//There are in the Multimedia extensions, so let's not use them yet 1036//def MAXSB8 : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum 1037//def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum 1038//def MAXUB8 : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum 1039//def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum 1040//def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum 1041//def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum 1042//def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum 1043//def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum 1044//def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error 1045//def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes 1046//def PKWB : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes 1047//def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords 1048//def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words 1049//CVTLQ F-P 17.010 Convert longword to quadword 1050//CVTQL F-P 17.030 Convert quadword to longword 1051 1052 1053//Constant handling 1054 1055def immConst2Part : PatLeaf<(imm), [{ 1056 //true if imm fits in a LDAH LDA pair 1057 int64_t val = (int64_t)N->getZExtValue(); 1058 return (val <= IMM_FULLHIGH && val >= IMM_FULLLOW); 1059}]>; 1060def immConst2PartInt : PatLeaf<(imm), [{ 1061 //true if imm fits in a LDAH LDA pair with zeroext 1062 uint64_t uval = N->getZExtValue(); 1063 int32_t val32 = (int32_t)uval; 1064 return ((uval >> 32) == 0 && //empty upper bits 1065 val32 <= IMM_FULLHIGH); 1066// val32 >= IMM_FULLLOW + IMM_LOW * IMM_MULT); //Always True 1067}], SExt32>; 1068 1069def : Pat<(i64 immConst2Part:$imm), 1070 (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>; 1071 1072def : Pat<(i64 immSExt16:$imm), 1073 (LDA immSExt16:$imm, R31)>; 1074 1075def : Pat<(i64 immSExt16int:$imm), 1076 (ZAPNOTi (LDA (SExt16 immSExt16int:$imm), R31), 15)>; 1077def : Pat<(i64 immConst2PartInt:$imm), 1078 (ZAPNOTi (LDA (LL16 (i64 (SExt32 immConst2PartInt:$imm))), 1079 (LDAH (LH16 (i64 (SExt32 immConst2PartInt:$imm))), R31)), 15)>; 1080 1081 1082//TODO: I want to just define these like this! 1083//def : Pat<(i64 0), 1084// (R31)>; 1085//def : Pat<(f64 0.0), 1086// (F31)>; 1087//def : Pat<(f64 -0.0), 1088// (CPYSNT F31, F31)>; 1089//def : Pat<(f32 0.0), 1090// (F31)>; 1091//def : Pat<(f32 -0.0), 1092// (CPYSNS F31, F31)>; 1093 1094//Misc Patterns: 1095 1096def : Pat<(sext_inreg GPRC:$RB, i32), 1097 (ADDLi GPRC:$RB, 0)>; 1098 1099def : Pat<(fabs F8RC:$RB), 1100 (CPYST F31, F8RC:$RB)>; 1101def : Pat<(fabs F4RC:$RB), 1102 (CPYSS F31, F4RC:$RB)>; 1103def : Pat<(fneg F8RC:$RB), 1104 (CPYSNT F8RC:$RB, F8RC:$RB)>; 1105def : Pat<(fneg F4RC:$RB), 1106 (CPYSNS F4RC:$RB, F4RC:$RB)>; 1107 1108def : Pat<(fcopysign F4RC:$A, (fneg F4RC:$B)), 1109 (CPYSNS F4RC:$B, F4RC:$A)>; 1110def : Pat<(fcopysign F8RC:$A, (fneg F8RC:$B)), 1111 (CPYSNT F8RC:$B, F8RC:$A)>; 1112def : Pat<(fcopysign F4RC:$A, (fneg F8RC:$B)), 1113 (CPYSNSt F8RC:$B, F4RC:$A)>; 1114def : Pat<(fcopysign F8RC:$A, (fneg F4RC:$B)), 1115 (CPYSNTs F4RC:$B, F8RC:$A)>; 1116 1117//Yes, signed multiply high is ugly 1118def : Pat<(mulhs GPRC:$RA, GPRC:$RB), 1119 (SUBQr (UMULHr GPRC:$RA, GPRC:$RB), (ADDQr (CMOVGEr GPRC:$RB, R31, GPRC:$RA), 1120 (CMOVGEr GPRC:$RA, R31, GPRC:$RB)))>; 1121 1122//Stupid crazy arithmetic stuff: 1123let AddedComplexity = 1 in { 1124def : Pat<(mul GPRC:$RA, 5), (S4ADDQr GPRC:$RA, GPRC:$RA)>; 1125def : Pat<(mul GPRC:$RA, 9), (S8ADDQr GPRC:$RA, GPRC:$RA)>; 1126def : Pat<(mul GPRC:$RA, 3), (S4SUBQr GPRC:$RA, GPRC:$RA)>; 1127def : Pat<(mul GPRC:$RA, 7), (S8SUBQr GPRC:$RA, GPRC:$RA)>; 1128 1129//slight tree expansion if we are multiplying near to a power of 2 1130//n is above a power of 2 1131def : Pat<(mul GPRC:$RA, immRem1:$imm), 1132 (ADDQr (SLr GPRC:$RA, (nearP2X immRem1:$imm)), GPRC:$RA)>; 1133def : Pat<(mul GPRC:$RA, immRem2:$imm), 1134 (ADDQr (SLr GPRC:$RA, (nearP2X immRem2:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>; 1135def : Pat<(mul GPRC:$RA, immRem3:$imm), 1136 (ADDQr (SLr GPRC:$RA, (nearP2X immRem3:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>; 1137def : Pat<(mul GPRC:$RA, immRem4:$imm), 1138 (S4ADDQr GPRC:$RA, (SLr GPRC:$RA, (nearP2X immRem4:$imm)))>; 1139def : Pat<(mul GPRC:$RA, immRem5:$imm), 1140 (ADDQr (SLr GPRC:$RA, (nearP2X immRem5:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>; 1141def : Pat<(mul GPRC:$RA, immRemP2:$imm), 1142 (ADDQr (SLr GPRC:$RA, (nearP2X immRemP2:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2:$imm)))>; 1143 1144//n is below a power of 2 1145//FIXME: figure out why something is truncating the imm to 32bits 1146// this will fix 2007-11-27-mulneg3 1147//def : Pat<(mul GPRC:$RA, immRem1n:$imm), 1148// (SUBQr (SLr GPRC:$RA, (nearP2X immRem1n:$imm)), GPRC:$RA)>; 1149//def : Pat<(mul GPRC:$RA, immRem2n:$imm), 1150// (SUBQr (SLr GPRC:$RA, (nearP2X immRem2n:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>; 1151//def : Pat<(mul GPRC:$RA, immRem3n:$imm), 1152// (SUBQr (SLr GPRC:$RA, (nearP2X immRem3n:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>; 1153//def : Pat<(mul GPRC:$RA, immRem4n:$imm), 1154// (SUBQr (SLr GPRC:$RA, (nearP2X immRem4n:$imm)), (SLi GPRC:$RA, 2))>; 1155//def : Pat<(mul GPRC:$RA, immRem5n:$imm), 1156// (SUBQr (SLr GPRC:$RA, (nearP2X immRem5n:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>; 1157//def : Pat<(mul GPRC:$RA, immRemP2n:$imm), 1158// (SUBQr (SLr GPRC:$RA, (nearP2X immRemP2n:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2n:$imm)))>; 1159} //Added complexity 1160