LLVM API Documentation
00001 //===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Subclass of MipsTargetLowering specialized for mips32/64. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 #include "MipsSEISelLowering.h" 00014 #include "MipsMachineFunction.h" 00015 #include "MipsRegisterInfo.h" 00016 #include "MipsTargetMachine.h" 00017 #include "llvm/CodeGen/MachineInstrBuilder.h" 00018 #include "llvm/CodeGen/MachineRegisterInfo.h" 00019 #include "llvm/IR/Intrinsics.h" 00020 #include "llvm/Support/CommandLine.h" 00021 #include "llvm/Support/Debug.h" 00022 #include "llvm/Support/raw_ostream.h" 00023 #include "llvm/Target/TargetInstrInfo.h" 00024 00025 using namespace llvm; 00026 00027 #define DEBUG_TYPE "mips-isel" 00028 00029 static cl::opt<bool> 00030 EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden, 00031 cl::desc("MIPS: Enable tail calls."), cl::init(false)); 00032 00033 static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false), 00034 cl::desc("Expand double precision loads and " 00035 "stores to their single precision " 00036 "counterparts")); 00037 00038 MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM, 00039 const MipsSubtarget &STI) 00040 : MipsTargetLowering(TM, STI) { 00041 // Set up the register classes 00042 addRegisterClass(MVT::i32, &Mips::GPR32RegClass); 00043 00044 if (Subtarget.isGP64bit()) 00045 addRegisterClass(MVT::i64, &Mips::GPR64RegClass); 00046 00047 if (Subtarget.hasDSP() || Subtarget.hasMSA()) { 00048 // Expand all truncating stores and extending loads. 00049 unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE; 00050 unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE; 00051 00052 for (unsigned VT0 = FirstVT; VT0 <= LastVT; ++VT0) { 00053 for (unsigned VT1 = FirstVT; VT1 <= LastVT; ++VT1) 00054 setTruncStoreAction((MVT::SimpleValueType)VT0, 00055 (MVT::SimpleValueType)VT1, Expand); 00056 00057 setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand); 00058 setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand); 00059 setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand); 00060 } 00061 } 00062 00063 if (Subtarget.hasDSP()) { 00064 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8}; 00065 00066 for (unsigned i = 0; i < array_lengthof(VecTys); ++i) { 00067 addRegisterClass(VecTys[i], &Mips::DSPRRegClass); 00068 00069 // Expand all builtin opcodes. 00070 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 00071 setOperationAction(Opc, VecTys[i], Expand); 00072 00073 setOperationAction(ISD::ADD, VecTys[i], Legal); 00074 setOperationAction(ISD::SUB, VecTys[i], Legal); 00075 setOperationAction(ISD::LOAD, VecTys[i], Legal); 00076 setOperationAction(ISD::STORE, VecTys[i], Legal); 00077 setOperationAction(ISD::BITCAST, VecTys[i], Legal); 00078 } 00079 00080 setTargetDAGCombine(ISD::SHL); 00081 setTargetDAGCombine(ISD::SRA); 00082 setTargetDAGCombine(ISD::SRL); 00083 setTargetDAGCombine(ISD::SETCC); 00084 setTargetDAGCombine(ISD::VSELECT); 00085 } 00086 00087 if (Subtarget.hasDSPR2()) 00088 setOperationAction(ISD::MUL, MVT::v2i16, Legal); 00089 00090 if (Subtarget.hasMSA()) { 00091 addMSAIntType(MVT::v16i8, &Mips::MSA128BRegClass); 00092 addMSAIntType(MVT::v8i16, &Mips::MSA128HRegClass); 00093 addMSAIntType(MVT::v4i32, &Mips::MSA128WRegClass); 00094 addMSAIntType(MVT::v2i64, &Mips::MSA128DRegClass); 00095 addMSAFloatType(MVT::v8f16, &Mips::MSA128HRegClass); 00096 addMSAFloatType(MVT::v4f32, &Mips::MSA128WRegClass); 00097 addMSAFloatType(MVT::v2f64, &Mips::MSA128DRegClass); 00098 00099 setTargetDAGCombine(ISD::AND); 00100 setTargetDAGCombine(ISD::OR); 00101 setTargetDAGCombine(ISD::SRA); 00102 setTargetDAGCombine(ISD::VSELECT); 00103 setTargetDAGCombine(ISD::XOR); 00104 } 00105 00106 if (!Subtarget.abiUsesSoftFloat()) { 00107 addRegisterClass(MVT::f32, &Mips::FGR32RegClass); 00108 00109 // When dealing with single precision only, use libcalls 00110 if (!Subtarget.isSingleFloat()) { 00111 if (Subtarget.isFP64bit()) 00112 addRegisterClass(MVT::f64, &Mips::FGR64RegClass); 00113 else 00114 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass); 00115 } 00116 } 00117 00118 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); 00119 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); 00120 setOperationAction(ISD::MULHS, MVT::i32, Custom); 00121 setOperationAction(ISD::MULHU, MVT::i32, Custom); 00122 00123 if (Subtarget.hasCnMips()) 00124 setOperationAction(ISD::MUL, MVT::i64, Legal); 00125 else if (Subtarget.isGP64bit()) 00126 setOperationAction(ISD::MUL, MVT::i64, Custom); 00127 00128 if (Subtarget.isGP64bit()) { 00129 setOperationAction(ISD::MULHS, MVT::i64, Custom); 00130 setOperationAction(ISD::MULHU, MVT::i64, Custom); 00131 } 00132 00133 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom); 00134 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom); 00135 00136 setOperationAction(ISD::SDIVREM, MVT::i32, Custom); 00137 setOperationAction(ISD::UDIVREM, MVT::i32, Custom); 00138 setOperationAction(ISD::SDIVREM, MVT::i64, Custom); 00139 setOperationAction(ISD::UDIVREM, MVT::i64, Custom); 00140 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); 00141 setOperationAction(ISD::LOAD, MVT::i32, Custom); 00142 setOperationAction(ISD::STORE, MVT::i32, Custom); 00143 00144 setTargetDAGCombine(ISD::ADDE); 00145 setTargetDAGCombine(ISD::SUBE); 00146 setTargetDAGCombine(ISD::MUL); 00147 00148 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); 00149 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); 00150 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); 00151 00152 if (NoDPLoadStore) { 00153 setOperationAction(ISD::LOAD, MVT::f64, Custom); 00154 setOperationAction(ISD::STORE, MVT::f64, Custom); 00155 } 00156 00157 if (Subtarget.hasMips32r6()) { 00158 // MIPS32r6 replaces the accumulator-based multiplies with a three register 00159 // instruction 00160 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); 00161 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); 00162 setOperationAction(ISD::MUL, MVT::i32, Legal); 00163 setOperationAction(ISD::MULHS, MVT::i32, Legal); 00164 setOperationAction(ISD::MULHU, MVT::i32, Legal); 00165 00166 // MIPS32r6 replaces the accumulator-based division/remainder with separate 00167 // three register division and remainder instructions. 00168 setOperationAction(ISD::SDIVREM, MVT::i32, Expand); 00169 setOperationAction(ISD::UDIVREM, MVT::i32, Expand); 00170 setOperationAction(ISD::SDIV, MVT::i32, Legal); 00171 setOperationAction(ISD::UDIV, MVT::i32, Legal); 00172 setOperationAction(ISD::SREM, MVT::i32, Legal); 00173 setOperationAction(ISD::UREM, MVT::i32, Legal); 00174 00175 // MIPS32r6 replaces conditional moves with an equivalent that removes the 00176 // need for three GPR read ports. 00177 setOperationAction(ISD::SETCC, MVT::i32, Legal); 00178 setOperationAction(ISD::SELECT, MVT::i32, Legal); 00179 setOperationAction(ISD::SELECT_CC, MVT::i32, Expand); 00180 00181 setOperationAction(ISD::SETCC, MVT::f32, Legal); 00182 setOperationAction(ISD::SELECT, MVT::f32, Legal); 00183 setOperationAction(ISD::SELECT_CC, MVT::f32, Expand); 00184 00185 assert(Subtarget.isFP64bit() && "FR=1 is required for MIPS32r6"); 00186 setOperationAction(ISD::SETCC, MVT::f64, Legal); 00187 setOperationAction(ISD::SELECT, MVT::f64, Legal); 00188 setOperationAction(ISD::SELECT_CC, MVT::f64, Expand); 00189 00190 setOperationAction(ISD::BRCOND, MVT::Other, Legal); 00191 00192 // Floating point > and >= are supported via < and <= 00193 setCondCodeAction(ISD::SETOGE, MVT::f32, Expand); 00194 setCondCodeAction(ISD::SETOGT, MVT::f32, Expand); 00195 setCondCodeAction(ISD::SETUGE, MVT::f32, Expand); 00196 setCondCodeAction(ISD::SETUGT, MVT::f32, Expand); 00197 00198 setCondCodeAction(ISD::SETOGE, MVT::f64, Expand); 00199 setCondCodeAction(ISD::SETOGT, MVT::f64, Expand); 00200 setCondCodeAction(ISD::SETUGE, MVT::f64, Expand); 00201 setCondCodeAction(ISD::SETUGT, MVT::f64, Expand); 00202 } 00203 00204 if (Subtarget.hasMips64r6()) { 00205 // MIPS64r6 replaces the accumulator-based multiplies with a three register 00206 // instruction 00207 setOperationAction(ISD::MUL, MVT::i64, Legal); 00208 setOperationAction(ISD::MULHS, MVT::i64, Legal); 00209 setOperationAction(ISD::MULHU, MVT::i64, Legal); 00210 00211 // MIPS32r6 replaces the accumulator-based division/remainder with separate 00212 // three register division and remainder instructions. 00213 setOperationAction(ISD::SDIVREM, MVT::i64, Expand); 00214 setOperationAction(ISD::UDIVREM, MVT::i64, Expand); 00215 setOperationAction(ISD::SDIV, MVT::i64, Legal); 00216 setOperationAction(ISD::UDIV, MVT::i64, Legal); 00217 setOperationAction(ISD::SREM, MVT::i64, Legal); 00218 setOperationAction(ISD::UREM, MVT::i64, Legal); 00219 00220 // MIPS64r6 replaces conditional moves with an equivalent that removes the 00221 // need for three GPR read ports. 00222 setOperationAction(ISD::SETCC, MVT::i64, Legal); 00223 setOperationAction(ISD::SELECT, MVT::i64, Legal); 00224 setOperationAction(ISD::SELECT_CC, MVT::i64, Expand); 00225 } 00226 00227 computeRegisterProperties(); 00228 } 00229 00230 const MipsTargetLowering * 00231 llvm::createMipsSETargetLowering(MipsTargetMachine &TM, 00232 const MipsSubtarget &STI) { 00233 return new MipsSETargetLowering(TM, STI); 00234 } 00235 00236 const TargetRegisterClass * 00237 MipsSETargetLowering::getRepRegClassFor(MVT VT) const { 00238 if (VT == MVT::Untyped) 00239 return Subtarget.hasDSP() ? &Mips::ACC64DSPRegClass : &Mips::ACC64RegClass; 00240 00241 return TargetLowering::getRepRegClassFor(VT); 00242 } 00243 00244 // Enable MSA support for the given integer type and Register class. 00245 void MipsSETargetLowering:: 00246 addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) { 00247 addRegisterClass(Ty, RC); 00248 00249 // Expand all builtin opcodes. 00250 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 00251 setOperationAction(Opc, Ty, Expand); 00252 00253 setOperationAction(ISD::BITCAST, Ty, Legal); 00254 setOperationAction(ISD::LOAD, Ty, Legal); 00255 setOperationAction(ISD::STORE, Ty, Legal); 00256 setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Custom); 00257 setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Legal); 00258 setOperationAction(ISD::BUILD_VECTOR, Ty, Custom); 00259 00260 setOperationAction(ISD::ADD, Ty, Legal); 00261 setOperationAction(ISD::AND, Ty, Legal); 00262 setOperationAction(ISD::CTLZ, Ty, Legal); 00263 setOperationAction(ISD::CTPOP, Ty, Legal); 00264 setOperationAction(ISD::MUL, Ty, Legal); 00265 setOperationAction(ISD::OR, Ty, Legal); 00266 setOperationAction(ISD::SDIV, Ty, Legal); 00267 setOperationAction(ISD::SREM, Ty, Legal); 00268 setOperationAction(ISD::SHL, Ty, Legal); 00269 setOperationAction(ISD::SRA, Ty, Legal); 00270 setOperationAction(ISD::SRL, Ty, Legal); 00271 setOperationAction(ISD::SUB, Ty, Legal); 00272 setOperationAction(ISD::UDIV, Ty, Legal); 00273 setOperationAction(ISD::UREM, Ty, Legal); 00274 setOperationAction(ISD::VECTOR_SHUFFLE, Ty, Custom); 00275 setOperationAction(ISD::VSELECT, Ty, Legal); 00276 setOperationAction(ISD::XOR, Ty, Legal); 00277 00278 if (Ty == MVT::v4i32 || Ty == MVT::v2i64) { 00279 setOperationAction(ISD::FP_TO_SINT, Ty, Legal); 00280 setOperationAction(ISD::FP_TO_UINT, Ty, Legal); 00281 setOperationAction(ISD::SINT_TO_FP, Ty, Legal); 00282 setOperationAction(ISD::UINT_TO_FP, Ty, Legal); 00283 } 00284 00285 setOperationAction(ISD::SETCC, Ty, Legal); 00286 setCondCodeAction(ISD::SETNE, Ty, Expand); 00287 setCondCodeAction(ISD::SETGE, Ty, Expand); 00288 setCondCodeAction(ISD::SETGT, Ty, Expand); 00289 setCondCodeAction(ISD::SETUGE, Ty, Expand); 00290 setCondCodeAction(ISD::SETUGT, Ty, Expand); 00291 } 00292 00293 // Enable MSA support for the given floating-point type and Register class. 00294 void MipsSETargetLowering:: 00295 addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) { 00296 addRegisterClass(Ty, RC); 00297 00298 // Expand all builtin opcodes. 00299 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 00300 setOperationAction(Opc, Ty, Expand); 00301 00302 setOperationAction(ISD::LOAD, Ty, Legal); 00303 setOperationAction(ISD::STORE, Ty, Legal); 00304 setOperationAction(ISD::BITCAST, Ty, Legal); 00305 setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Legal); 00306 setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Legal); 00307 setOperationAction(ISD::BUILD_VECTOR, Ty, Custom); 00308 00309 if (Ty != MVT::v8f16) { 00310 setOperationAction(ISD::FABS, Ty, Legal); 00311 setOperationAction(ISD::FADD, Ty, Legal); 00312 setOperationAction(ISD::FDIV, Ty, Legal); 00313 setOperationAction(ISD::FEXP2, Ty, Legal); 00314 setOperationAction(ISD::FLOG2, Ty, Legal); 00315 setOperationAction(ISD::FMA, Ty, Legal); 00316 setOperationAction(ISD::FMUL, Ty, Legal); 00317 setOperationAction(ISD::FRINT, Ty, Legal); 00318 setOperationAction(ISD::FSQRT, Ty, Legal); 00319 setOperationAction(ISD::FSUB, Ty, Legal); 00320 setOperationAction(ISD::VSELECT, Ty, Legal); 00321 00322 setOperationAction(ISD::SETCC, Ty, Legal); 00323 setCondCodeAction(ISD::SETOGE, Ty, Expand); 00324 setCondCodeAction(ISD::SETOGT, Ty, Expand); 00325 setCondCodeAction(ISD::SETUGE, Ty, Expand); 00326 setCondCodeAction(ISD::SETUGT, Ty, Expand); 00327 setCondCodeAction(ISD::SETGE, Ty, Expand); 00328 setCondCodeAction(ISD::SETGT, Ty, Expand); 00329 } 00330 } 00331 00332 bool 00333 MipsSETargetLowering::allowsMisalignedMemoryAccesses(EVT VT, 00334 unsigned, 00335 unsigned, 00336 bool *Fast) const { 00337 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy; 00338 00339 if (Subtarget.systemSupportsUnalignedAccess()) { 00340 // MIPS32r6/MIPS64r6 is required to support unaligned access. It's 00341 // implementation defined whether this is handled by hardware, software, or 00342 // a hybrid of the two but it's expected that most implementations will 00343 // handle the majority of cases in hardware. 00344 if (Fast) 00345 *Fast = true; 00346 return true; 00347 } 00348 00349 switch (SVT) { 00350 case MVT::i64: 00351 case MVT::i32: 00352 if (Fast) 00353 *Fast = true; 00354 return true; 00355 default: 00356 return false; 00357 } 00358 } 00359 00360 SDValue MipsSETargetLowering::LowerOperation(SDValue Op, 00361 SelectionDAG &DAG) const { 00362 switch(Op.getOpcode()) { 00363 case ISD::LOAD: return lowerLOAD(Op, DAG); 00364 case ISD::STORE: return lowerSTORE(Op, DAG); 00365 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG); 00366 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG); 00367 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG); 00368 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG); 00369 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG); 00370 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG); 00371 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true, 00372 DAG); 00373 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG); 00374 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG); 00375 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG); 00376 case ISD::EXTRACT_VECTOR_ELT: return lowerEXTRACT_VECTOR_ELT(Op, DAG); 00377 case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG); 00378 case ISD::VECTOR_SHUFFLE: return lowerVECTOR_SHUFFLE(Op, DAG); 00379 } 00380 00381 return MipsTargetLowering::LowerOperation(Op, DAG); 00382 } 00383 00384 // selectMADD - 00385 // Transforms a subgraph in CurDAG if the following pattern is found: 00386 // (addc multLo, Lo0), (adde multHi, Hi0), 00387 // where, 00388 // multHi/Lo: product of multiplication 00389 // Lo0: initial value of Lo register 00390 // Hi0: initial value of Hi register 00391 // Return true if pattern matching was successful. 00392 static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) { 00393 // ADDENode's second operand must be a flag output of an ADDC node in order 00394 // for the matching to be successful. 00395 SDNode *ADDCNode = ADDENode->getOperand(2).getNode(); 00396 00397 if (ADDCNode->getOpcode() != ISD::ADDC) 00398 return false; 00399 00400 SDValue MultHi = ADDENode->getOperand(0); 00401 SDValue MultLo = ADDCNode->getOperand(0); 00402 SDNode *MultNode = MultHi.getNode(); 00403 unsigned MultOpc = MultHi.getOpcode(); 00404 00405 // MultHi and MultLo must be generated by the same node, 00406 if (MultLo.getNode() != MultNode) 00407 return false; 00408 00409 // and it must be a multiplication. 00410 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) 00411 return false; 00412 00413 // MultLo amd MultHi must be the first and second output of MultNode 00414 // respectively. 00415 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) 00416 return false; 00417 00418 // Transform this to a MADD only if ADDENode and ADDCNode are the only users 00419 // of the values of MultNode, in which case MultNode will be removed in later 00420 // phases. 00421 // If there exist users other than ADDENode or ADDCNode, this function returns 00422 // here, which will result in MultNode being mapped to a single MULT 00423 // instruction node rather than a pair of MULT and MADD instructions being 00424 // produced. 00425 if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) 00426 return false; 00427 00428 SDLoc DL(ADDENode); 00429 00430 // Initialize accumulator. 00431 SDValue ACCIn = CurDAG->getNode(MipsISD::MTLOHI, DL, MVT::Untyped, 00432 ADDCNode->getOperand(1), 00433 ADDENode->getOperand(1)); 00434 00435 // create MipsMAdd(u) node 00436 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd; 00437 00438 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped, 00439 MultNode->getOperand(0),// Factor 0 00440 MultNode->getOperand(1),// Factor 1 00441 ACCIn); 00442 00443 // replace uses of adde and addc here 00444 if (!SDValue(ADDCNode, 0).use_empty()) { 00445 SDValue LoOut = CurDAG->getNode(MipsISD::MFLO, DL, MVT::i32, MAdd); 00446 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut); 00447 } 00448 if (!SDValue(ADDENode, 0).use_empty()) { 00449 SDValue HiOut = CurDAG->getNode(MipsISD::MFHI, DL, MVT::i32, MAdd); 00450 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut); 00451 } 00452 00453 return true; 00454 } 00455 00456 // selectMSUB - 00457 // Transforms a subgraph in CurDAG if the following pattern is found: 00458 // (addc Lo0, multLo), (sube Hi0, multHi), 00459 // where, 00460 // multHi/Lo: product of multiplication 00461 // Lo0: initial value of Lo register 00462 // Hi0: initial value of Hi register 00463 // Return true if pattern matching was successful. 00464 static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) { 00465 // SUBENode's second operand must be a flag output of an SUBC node in order 00466 // for the matching to be successful. 00467 SDNode *SUBCNode = SUBENode->getOperand(2).getNode(); 00468 00469 if (SUBCNode->getOpcode() != ISD::SUBC) 00470 return false; 00471 00472 SDValue MultHi = SUBENode->getOperand(1); 00473 SDValue MultLo = SUBCNode->getOperand(1); 00474 SDNode *MultNode = MultHi.getNode(); 00475 unsigned MultOpc = MultHi.getOpcode(); 00476 00477 // MultHi and MultLo must be generated by the same node, 00478 if (MultLo.getNode() != MultNode) 00479 return false; 00480 00481 // and it must be a multiplication. 00482 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) 00483 return false; 00484 00485 // MultLo amd MultHi must be the first and second output of MultNode 00486 // respectively. 00487 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) 00488 return false; 00489 00490 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users 00491 // of the values of MultNode, in which case MultNode will be removed in later 00492 // phases. 00493 // If there exist users other than SUBENode or SUBCNode, this function returns 00494 // here, which will result in MultNode being mapped to a single MULT 00495 // instruction node rather than a pair of MULT and MSUB instructions being 00496 // produced. 00497 if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) 00498 return false; 00499 00500 SDLoc DL(SUBENode); 00501 00502 // Initialize accumulator. 00503 SDValue ACCIn = CurDAG->getNode(MipsISD::MTLOHI, DL, MVT::Untyped, 00504 SUBCNode->getOperand(0), 00505 SUBENode->getOperand(0)); 00506 00507 // create MipsSub(u) node 00508 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub; 00509 00510 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue, 00511 MultNode->getOperand(0),// Factor 0 00512 MultNode->getOperand(1),// Factor 1 00513 ACCIn); 00514 00515 // replace uses of sube and subc here 00516 if (!SDValue(SUBCNode, 0).use_empty()) { 00517 SDValue LoOut = CurDAG->getNode(MipsISD::MFLO, DL, MVT::i32, MSub); 00518 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut); 00519 } 00520 if (!SDValue(SUBENode, 0).use_empty()) { 00521 SDValue HiOut = CurDAG->getNode(MipsISD::MFHI, DL, MVT::i32, MSub); 00522 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut); 00523 } 00524 00525 return true; 00526 } 00527 00528 static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG, 00529 TargetLowering::DAGCombinerInfo &DCI, 00530 const MipsSubtarget &Subtarget) { 00531 if (DCI.isBeforeLegalize()) 00532 return SDValue(); 00533 00534 if (Subtarget.hasMips32() && !Subtarget.hasMips32r6() && 00535 N->getValueType(0) == MVT::i32 && selectMADD(N, &DAG)) 00536 return SDValue(N, 0); 00537 00538 return SDValue(); 00539 } 00540 00541 // Fold zero extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT 00542 // 00543 // Performs the following transformations: 00544 // - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to zero extension if its 00545 // sign/zero-extension is completely overwritten by the new one performed by 00546 // the ISD::AND. 00547 // - Removes redundant zero extensions performed by an ISD::AND. 00548 static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, 00549 TargetLowering::DAGCombinerInfo &DCI, 00550 const MipsSubtarget &Subtarget) { 00551 if (!Subtarget.hasMSA()) 00552 return SDValue(); 00553 00554 SDValue Op0 = N->getOperand(0); 00555 SDValue Op1 = N->getOperand(1); 00556 unsigned Op0Opcode = Op0->getOpcode(); 00557 00558 // (and (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d) 00559 // where $d + 1 == 2^n and n == 32 00560 // or $d + 1 == 2^n and n <= 32 and ZExt 00561 // -> (MipsVExtractZExt $a, $b, $c) 00562 if (Op0Opcode == MipsISD::VEXTRACT_SEXT_ELT || 00563 Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT) { 00564 ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(Op1); 00565 00566 if (!Mask) 00567 return SDValue(); 00568 00569 int32_t Log2IfPositive = (Mask->getAPIntValue() + 1).exactLogBase2(); 00570 00571 if (Log2IfPositive <= 0) 00572 return SDValue(); // Mask+1 is not a power of 2 00573 00574 SDValue Op0Op2 = Op0->getOperand(2); 00575 EVT ExtendTy = cast<VTSDNode>(Op0Op2)->getVT(); 00576 unsigned ExtendTySize = ExtendTy.getSizeInBits(); 00577 unsigned Log2 = Log2IfPositive; 00578 00579 if ((Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT && Log2 >= ExtendTySize) || 00580 Log2 == ExtendTySize) { 00581 SDValue Ops[] = { Op0->getOperand(0), Op0->getOperand(1), Op0Op2 }; 00582 return DAG.getNode(MipsISD::VEXTRACT_ZEXT_ELT, SDLoc(Op0), 00583 Op0->getVTList(), 00584 makeArrayRef(Ops, Op0->getNumOperands())); 00585 } 00586 } 00587 00588 return SDValue(); 00589 } 00590 00591 // Determine if the specified node is a constant vector splat. 00592 // 00593 // Returns true and sets Imm if: 00594 // * N is a ISD::BUILD_VECTOR representing a constant splat 00595 // 00596 // This function is quite similar to MipsSEDAGToDAGISel::selectVSplat. The 00597 // differences are that it assumes the MSA has already been checked and the 00598 // arbitrary requirement for a maximum of 32-bit integers isn't applied (and 00599 // must not be in order for binsri.d to be selectable). 00600 static bool isVSplat(SDValue N, APInt &Imm, bool IsLittleEndian) { 00601 BuildVectorSDNode *Node = dyn_cast<BuildVectorSDNode>(N.getNode()); 00602 00603 if (!Node) 00604 return false; 00605 00606 APInt SplatValue, SplatUndef; 00607 unsigned SplatBitSize; 00608 bool HasAnyUndefs; 00609 00610 if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, 00611 8, !IsLittleEndian)) 00612 return false; 00613 00614 Imm = SplatValue; 00615 00616 return true; 00617 } 00618 00619 // Test whether the given node is an all-ones build_vector. 00620 static bool isVectorAllOnes(SDValue N) { 00621 // Look through bitcasts. Endianness doesn't matter because we are looking 00622 // for an all-ones value. 00623 if (N->getOpcode() == ISD::BITCAST) 00624 N = N->getOperand(0); 00625 00626 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N); 00627 00628 if (!BVN) 00629 return false; 00630 00631 APInt SplatValue, SplatUndef; 00632 unsigned SplatBitSize; 00633 bool HasAnyUndefs; 00634 00635 // Endianness doesn't matter in this context because we are looking for 00636 // an all-ones value. 00637 if (BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs)) 00638 return SplatValue.isAllOnesValue(); 00639 00640 return false; 00641 } 00642 00643 // Test whether N is the bitwise inverse of OfNode. 00644 static bool isBitwiseInverse(SDValue N, SDValue OfNode) { 00645 if (N->getOpcode() != ISD::XOR) 00646 return false; 00647 00648 if (isVectorAllOnes(N->getOperand(0))) 00649 return N->getOperand(1) == OfNode; 00650 00651 if (isVectorAllOnes(N->getOperand(1))) 00652 return N->getOperand(0) == OfNode; 00653 00654 return false; 00655 } 00656 00657 // Perform combines where ISD::OR is the root node. 00658 // 00659 // Performs the following transformations: 00660 // - (or (and $a, $mask), (and $b, $inv_mask)) => (vselect $mask, $a, $b) 00661 // where $inv_mask is the bitwise inverse of $mask and the 'or' has a 128-bit 00662 // vector type. 00663 static SDValue performORCombine(SDNode *N, SelectionDAG &DAG, 00664 TargetLowering::DAGCombinerInfo &DCI, 00665 const MipsSubtarget &Subtarget) { 00666 if (!Subtarget.hasMSA()) 00667 return SDValue(); 00668 00669 EVT Ty = N->getValueType(0); 00670 00671 if (!Ty.is128BitVector()) 00672 return SDValue(); 00673 00674 SDValue Op0 = N->getOperand(0); 00675 SDValue Op1 = N->getOperand(1); 00676 00677 if (Op0->getOpcode() == ISD::AND && Op1->getOpcode() == ISD::AND) { 00678 SDValue Op0Op0 = Op0->getOperand(0); 00679 SDValue Op0Op1 = Op0->getOperand(1); 00680 SDValue Op1Op0 = Op1->getOperand(0); 00681 SDValue Op1Op1 = Op1->getOperand(1); 00682 bool IsLittleEndian = !Subtarget.isLittle(); 00683 00684 SDValue IfSet, IfClr, Cond; 00685 bool IsConstantMask = false; 00686 APInt Mask, InvMask; 00687 00688 // If Op0Op0 is an appropriate mask, try to find it's inverse in either 00689 // Op1Op0, or Op1Op1. Keep track of the Cond, IfSet, and IfClr nodes, while 00690 // looking. 00691 // IfClr will be set if we find a valid match. 00692 if (isVSplat(Op0Op0, Mask, IsLittleEndian)) { 00693 Cond = Op0Op0; 00694 IfSet = Op0Op1; 00695 00696 if (isVSplat(Op1Op0, InvMask, IsLittleEndian) && 00697 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask) 00698 IfClr = Op1Op1; 00699 else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) && 00700 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask) 00701 IfClr = Op1Op0; 00702 00703 IsConstantMask = true; 00704 } 00705 00706 // If IfClr is not yet set, and Op0Op1 is an appropriate mask, try the same 00707 // thing again using this mask. 00708 // IfClr will be set if we find a valid match. 00709 if (!IfClr.getNode() && isVSplat(Op0Op1, Mask, IsLittleEndian)) { 00710 Cond = Op0Op1; 00711 IfSet = Op0Op0; 00712 00713 if (isVSplat(Op1Op0, InvMask, IsLittleEndian) && 00714 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask) 00715 IfClr = Op1Op1; 00716 else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) && 00717 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask) 00718 IfClr = Op1Op0; 00719 00720 IsConstantMask = true; 00721 } 00722 00723 // If IfClr is not yet set, try looking for a non-constant match. 00724 // IfClr will be set if we find a valid match amongst the eight 00725 // possibilities. 00726 if (!IfClr.getNode()) { 00727 if (isBitwiseInverse(Op0Op0, Op1Op0)) { 00728 Cond = Op1Op0; 00729 IfSet = Op1Op1; 00730 IfClr = Op0Op1; 00731 } else if (isBitwiseInverse(Op0Op1, Op1Op0)) { 00732 Cond = Op1Op0; 00733 IfSet = Op1Op1; 00734 IfClr = Op0Op0; 00735 } else if (isBitwiseInverse(Op0Op0, Op1Op1)) { 00736 Cond = Op1Op1; 00737 IfSet = Op1Op0; 00738 IfClr = Op0Op1; 00739 } else if (isBitwiseInverse(Op0Op1, Op1Op1)) { 00740 Cond = Op1Op1; 00741 IfSet = Op1Op0; 00742 IfClr = Op0Op0; 00743 } else if (isBitwiseInverse(Op1Op0, Op0Op0)) { 00744 Cond = Op0Op0; 00745 IfSet = Op0Op1; 00746 IfClr = Op1Op1; 00747 } else if (isBitwiseInverse(Op1Op1, Op0Op0)) { 00748 Cond = Op0Op0; 00749 IfSet = Op0Op1; 00750 IfClr = Op1Op0; 00751 } else if (isBitwiseInverse(Op1Op0, Op0Op1)) { 00752 Cond = Op0Op1; 00753 IfSet = Op0Op0; 00754 IfClr = Op1Op1; 00755 } else if (isBitwiseInverse(Op1Op1, Op0Op1)) { 00756 Cond = Op0Op1; 00757 IfSet = Op0Op0; 00758 IfClr = Op1Op0; 00759 } 00760 } 00761 00762 // At this point, IfClr will be set if we have a valid match. 00763 if (!IfClr.getNode()) 00764 return SDValue(); 00765 00766 assert(Cond.getNode() && IfSet.getNode()); 00767 00768 // Fold degenerate cases. 00769 if (IsConstantMask) { 00770 if (Mask.isAllOnesValue()) 00771 return IfSet; 00772 else if (Mask == 0) 00773 return IfClr; 00774 } 00775 00776 // Transform the DAG into an equivalent VSELECT. 00777 return DAG.getNode(ISD::VSELECT, SDLoc(N), Ty, Cond, IfSet, IfClr); 00778 } 00779 00780 return SDValue(); 00781 } 00782 00783 static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG, 00784 TargetLowering::DAGCombinerInfo &DCI, 00785 const MipsSubtarget &Subtarget) { 00786 if (DCI.isBeforeLegalize()) 00787 return SDValue(); 00788 00789 if (Subtarget.hasMips32() && N->getValueType(0) == MVT::i32 && 00790 selectMSUB(N, &DAG)) 00791 return SDValue(N, 0); 00792 00793 return SDValue(); 00794 } 00795 00796 static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT, 00797 EVT ShiftTy, SelectionDAG &DAG) { 00798 // Clear the upper (64 - VT.sizeInBits) bits. 00799 C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits()); 00800 00801 // Return 0. 00802 if (C == 0) 00803 return DAG.getConstant(0, VT); 00804 00805 // Return x. 00806 if (C == 1) 00807 return X; 00808 00809 // If c is power of 2, return (shl x, log2(c)). 00810 if (isPowerOf2_64(C)) 00811 return DAG.getNode(ISD::SHL, DL, VT, X, 00812 DAG.getConstant(Log2_64(C), ShiftTy)); 00813 00814 unsigned Log2Ceil = Log2_64_Ceil(C); 00815 uint64_t Floor = 1LL << Log2_64(C); 00816 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil; 00817 00818 // If |c - floor_c| <= |c - ceil_c|, 00819 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))), 00820 // return (add constMult(x, floor_c), constMult(x, c - floor_c)). 00821 if (C - Floor <= Ceil - C) { 00822 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG); 00823 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG); 00824 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1); 00825 } 00826 00827 // If |c - floor_c| > |c - ceil_c|, 00828 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)). 00829 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG); 00830 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG); 00831 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1); 00832 } 00833 00834 static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG, 00835 const TargetLowering::DAGCombinerInfo &DCI, 00836 const MipsSETargetLowering *TL) { 00837 EVT VT = N->getValueType(0); 00838 00839 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) 00840 if (!VT.isVector()) 00841 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N), 00842 VT, TL->getScalarShiftAmountTy(VT), DAG); 00843 00844 return SDValue(N, 0); 00845 } 00846 00847 static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty, 00848 SelectionDAG &DAG, 00849 const MipsSubtarget &Subtarget) { 00850 // See if this is a vector splat immediate node. 00851 APInt SplatValue, SplatUndef; 00852 unsigned SplatBitSize; 00853 bool HasAnyUndefs; 00854 unsigned EltSize = Ty.getVectorElementType().getSizeInBits(); 00855 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1)); 00856 00857 if (!Subtarget.hasDSP()) 00858 return SDValue(); 00859 00860 if (!BV || 00861 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, 00862 EltSize, !Subtarget.isLittle()) || 00863 (SplatBitSize != EltSize) || 00864 (SplatValue.getZExtValue() >= EltSize)) 00865 return SDValue(); 00866 00867 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0), 00868 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32)); 00869 } 00870 00871 static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG, 00872 TargetLowering::DAGCombinerInfo &DCI, 00873 const MipsSubtarget &Subtarget) { 00874 EVT Ty = N->getValueType(0); 00875 00876 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8)) 00877 return SDValue(); 00878 00879 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget); 00880 } 00881 00882 // Fold sign-extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT for MSA and fold 00883 // constant splats into MipsISD::SHRA_DSP for DSPr2. 00884 // 00885 // Performs the following transformations: 00886 // - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to sign extension if its 00887 // sign/zero-extension is completely overwritten by the new one performed by 00888 // the ISD::SRA and ISD::SHL nodes. 00889 // - Removes redundant sign extensions performed by an ISD::SRA and ISD::SHL 00890 // sequence. 00891 // 00892 // See performDSPShiftCombine for more information about the transformation 00893 // used for DSPr2. 00894 static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG, 00895 TargetLowering::DAGCombinerInfo &DCI, 00896 const MipsSubtarget &Subtarget) { 00897 EVT Ty = N->getValueType(0); 00898 00899 if (Subtarget.hasMSA()) { 00900 SDValue Op0 = N->getOperand(0); 00901 SDValue Op1 = N->getOperand(1); 00902 00903 // (sra (shl (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d), imm:$d) 00904 // where $d + sizeof($c) == 32 00905 // or $d + sizeof($c) <= 32 and SExt 00906 // -> (MipsVExtractSExt $a, $b, $c) 00907 if (Op0->getOpcode() == ISD::SHL && Op1 == Op0->getOperand(1)) { 00908 SDValue Op0Op0 = Op0->getOperand(0); 00909 ConstantSDNode *ShAmount = dyn_cast<ConstantSDNode>(Op1); 00910 00911 if (!ShAmount) 00912 return SDValue(); 00913 00914 if (Op0Op0->getOpcode() != MipsISD::VEXTRACT_SEXT_ELT && 00915 Op0Op0->getOpcode() != MipsISD::VEXTRACT_ZEXT_ELT) 00916 return SDValue(); 00917 00918 EVT ExtendTy = cast<VTSDNode>(Op0Op0->getOperand(2))->getVT(); 00919 unsigned TotalBits = ShAmount->getZExtValue() + ExtendTy.getSizeInBits(); 00920 00921 if (TotalBits == 32 || 00922 (Op0Op0->getOpcode() == MipsISD::VEXTRACT_SEXT_ELT && 00923 TotalBits <= 32)) { 00924 SDValue Ops[] = { Op0Op0->getOperand(0), Op0Op0->getOperand(1), 00925 Op0Op0->getOperand(2) }; 00926 return DAG.getNode(MipsISD::VEXTRACT_SEXT_ELT, SDLoc(Op0Op0), 00927 Op0Op0->getVTList(), 00928 makeArrayRef(Ops, Op0Op0->getNumOperands())); 00929 } 00930 } 00931 } 00932 00933 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget.hasDSPR2())) 00934 return SDValue(); 00935 00936 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget); 00937 } 00938 00939 00940 static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, 00941 TargetLowering::DAGCombinerInfo &DCI, 00942 const MipsSubtarget &Subtarget) { 00943 EVT Ty = N->getValueType(0); 00944 00945 if (((Ty != MVT::v2i16) || !Subtarget.hasDSPR2()) && (Ty != MVT::v4i8)) 00946 return SDValue(); 00947 00948 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget); 00949 } 00950 00951 static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) { 00952 bool IsV216 = (Ty == MVT::v2i16); 00953 00954 switch (CC) { 00955 case ISD::SETEQ: 00956 case ISD::SETNE: return true; 00957 case ISD::SETLT: 00958 case ISD::SETLE: 00959 case ISD::SETGT: 00960 case ISD::SETGE: return IsV216; 00961 case ISD::SETULT: 00962 case ISD::SETULE: 00963 case ISD::SETUGT: 00964 case ISD::SETUGE: return !IsV216; 00965 default: return false; 00966 } 00967 } 00968 00969 static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) { 00970 EVT Ty = N->getValueType(0); 00971 00972 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8)) 00973 return SDValue(); 00974 00975 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get())) 00976 return SDValue(); 00977 00978 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0), 00979 N->getOperand(1), N->getOperand(2)); 00980 } 00981 00982 static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) { 00983 EVT Ty = N->getValueType(0); 00984 00985 if (Ty.is128BitVector() && Ty.isInteger()) { 00986 // Try the following combines: 00987 // (vselect (setcc $a, $b, SETLT), $b, $a)) -> (vsmax $a, $b) 00988 // (vselect (setcc $a, $b, SETLE), $b, $a)) -> (vsmax $a, $b) 00989 // (vselect (setcc $a, $b, SETLT), $a, $b)) -> (vsmin $a, $b) 00990 // (vselect (setcc $a, $b, SETLE), $a, $b)) -> (vsmin $a, $b) 00991 // (vselect (setcc $a, $b, SETULT), $b, $a)) -> (vumax $a, $b) 00992 // (vselect (setcc $a, $b, SETULE), $b, $a)) -> (vumax $a, $b) 00993 // (vselect (setcc $a, $b, SETULT), $a, $b)) -> (vumin $a, $b) 00994 // (vselect (setcc $a, $b, SETULE), $a, $b)) -> (vumin $a, $b) 00995 // SETGT/SETGE/SETUGT/SETUGE variants of these will show up initially but 00996 // will be expanded to equivalent SETLT/SETLE/SETULT/SETULE versions by the 00997 // legalizer. 00998 SDValue Op0 = N->getOperand(0); 00999 01000 if (Op0->getOpcode() != ISD::SETCC) 01001 return SDValue(); 01002 01003 ISD::CondCode CondCode = cast<CondCodeSDNode>(Op0->getOperand(2))->get(); 01004 bool Signed; 01005 01006 if (CondCode == ISD::SETLT || CondCode == ISD::SETLE) 01007 Signed = true; 01008 else if (CondCode == ISD::SETULT || CondCode == ISD::SETULE) 01009 Signed = false; 01010 else 01011 return SDValue(); 01012 01013 SDValue Op1 = N->getOperand(1); 01014 SDValue Op2 = N->getOperand(2); 01015 SDValue Op0Op0 = Op0->getOperand(0); 01016 SDValue Op0Op1 = Op0->getOperand(1); 01017 01018 if (Op1 == Op0Op0 && Op2 == Op0Op1) 01019 return DAG.getNode(Signed ? MipsISD::VSMIN : MipsISD::VUMIN, SDLoc(N), 01020 Ty, Op1, Op2); 01021 else if (Op1 == Op0Op1 && Op2 == Op0Op0) 01022 return DAG.getNode(Signed ? MipsISD::VSMAX : MipsISD::VUMAX, SDLoc(N), 01023 Ty, Op1, Op2); 01024 } else if ((Ty == MVT::v2i16) || (Ty == MVT::v4i8)) { 01025 SDValue SetCC = N->getOperand(0); 01026 01027 if (SetCC.getOpcode() != MipsISD::SETCC_DSP) 01028 return SDValue(); 01029 01030 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty, 01031 SetCC.getOperand(0), SetCC.getOperand(1), 01032 N->getOperand(1), N->getOperand(2), SetCC.getOperand(2)); 01033 } 01034 01035 return SDValue(); 01036 } 01037 01038 static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG, 01039 const MipsSubtarget &Subtarget) { 01040 EVT Ty = N->getValueType(0); 01041 01042 if (Subtarget.hasMSA() && Ty.is128BitVector() && Ty.isInteger()) { 01043 // Try the following combines: 01044 // (xor (or $a, $b), (build_vector allones)) 01045 // (xor (or $a, $b), (bitcast (build_vector allones))) 01046 SDValue Op0 = N->getOperand(0); 01047 SDValue Op1 = N->getOperand(1); 01048 SDValue NotOp; 01049 01050 if (ISD::isBuildVectorAllOnes(Op0.getNode())) 01051 NotOp = Op1; 01052 else if (ISD::isBuildVectorAllOnes(Op1.getNode())) 01053 NotOp = Op0; 01054 else 01055 return SDValue(); 01056 01057 if (NotOp->getOpcode() == ISD::OR) 01058 return DAG.getNode(MipsISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0), 01059 NotOp->getOperand(1)); 01060 } 01061 01062 return SDValue(); 01063 } 01064 01065 SDValue 01066 MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { 01067 SelectionDAG &DAG = DCI.DAG; 01068 SDValue Val; 01069 01070 switch (N->getOpcode()) { 01071 case ISD::ADDE: 01072 return performADDECombine(N, DAG, DCI, Subtarget); 01073 case ISD::AND: 01074 Val = performANDCombine(N, DAG, DCI, Subtarget); 01075 break; 01076 case ISD::OR: 01077 Val = performORCombine(N, DAG, DCI, Subtarget); 01078 break; 01079 case ISD::SUBE: 01080 return performSUBECombine(N, DAG, DCI, Subtarget); 01081 case ISD::MUL: 01082 return performMULCombine(N, DAG, DCI, this); 01083 case ISD::SHL: 01084 return performSHLCombine(N, DAG, DCI, Subtarget); 01085 case ISD::SRA: 01086 return performSRACombine(N, DAG, DCI, Subtarget); 01087 case ISD::SRL: 01088 return performSRLCombine(N, DAG, DCI, Subtarget); 01089 case ISD::VSELECT: 01090 return performVSELECTCombine(N, DAG); 01091 case ISD::XOR: 01092 Val = performXORCombine(N, DAG, Subtarget); 01093 break; 01094 case ISD::SETCC: 01095 Val = performSETCCCombine(N, DAG); 01096 break; 01097 } 01098 01099 if (Val.getNode()) { 01100 DEBUG(dbgs() << "\nMipsSE DAG Combine:\n"; 01101 N->printrWithDepth(dbgs(), &DAG); 01102 dbgs() << "\n=> \n"; 01103 Val.getNode()->printrWithDepth(dbgs(), &DAG); 01104 dbgs() << "\n"); 01105 return Val; 01106 } 01107 01108 return MipsTargetLowering::PerformDAGCombine(N, DCI); 01109 } 01110 01111 MachineBasicBlock * 01112 MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 01113 MachineBasicBlock *BB) const { 01114 switch (MI->getOpcode()) { 01115 default: 01116 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB); 01117 case Mips::BPOSGE32_PSEUDO: 01118 return emitBPOSGE32(MI, BB); 01119 case Mips::SNZ_B_PSEUDO: 01120 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B); 01121 case Mips::SNZ_H_PSEUDO: 01122 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H); 01123 case Mips::SNZ_W_PSEUDO: 01124 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W); 01125 case Mips::SNZ_D_PSEUDO: 01126 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D); 01127 case Mips::SNZ_V_PSEUDO: 01128 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V); 01129 case Mips::SZ_B_PSEUDO: 01130 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B); 01131 case Mips::SZ_H_PSEUDO: 01132 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H); 01133 case Mips::SZ_W_PSEUDO: 01134 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W); 01135 case Mips::SZ_D_PSEUDO: 01136 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D); 01137 case Mips::SZ_V_PSEUDO: 01138 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V); 01139 case Mips::COPY_FW_PSEUDO: 01140 return emitCOPY_FW(MI, BB); 01141 case Mips::COPY_FD_PSEUDO: 01142 return emitCOPY_FD(MI, BB); 01143 case Mips::INSERT_FW_PSEUDO: 01144 return emitINSERT_FW(MI, BB); 01145 case Mips::INSERT_FD_PSEUDO: 01146 return emitINSERT_FD(MI, BB); 01147 case Mips::INSERT_B_VIDX_PSEUDO: 01148 return emitINSERT_DF_VIDX(MI, BB, 1, false); 01149 case Mips::INSERT_H_VIDX_PSEUDO: 01150 return emitINSERT_DF_VIDX(MI, BB, 2, false); 01151 case Mips::INSERT_W_VIDX_PSEUDO: 01152 return emitINSERT_DF_VIDX(MI, BB, 4, false); 01153 case Mips::INSERT_D_VIDX_PSEUDO: 01154 return emitINSERT_DF_VIDX(MI, BB, 8, false); 01155 case Mips::INSERT_FW_VIDX_PSEUDO: 01156 return emitINSERT_DF_VIDX(MI, BB, 4, true); 01157 case Mips::INSERT_FD_VIDX_PSEUDO: 01158 return emitINSERT_DF_VIDX(MI, BB, 8, true); 01159 case Mips::FILL_FW_PSEUDO: 01160 return emitFILL_FW(MI, BB); 01161 case Mips::FILL_FD_PSEUDO: 01162 return emitFILL_FD(MI, BB); 01163 case Mips::FEXP2_W_1_PSEUDO: 01164 return emitFEXP2_W_1(MI, BB); 01165 case Mips::FEXP2_D_1_PSEUDO: 01166 return emitFEXP2_D_1(MI, BB); 01167 } 01168 } 01169 01170 bool MipsSETargetLowering:: 01171 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, 01172 unsigned NextStackOffset, 01173 const MipsFunctionInfo& FI) const { 01174 if (!EnableMipsTailCalls) 01175 return false; 01176 01177 // Return false if either the callee or caller has a byval argument. 01178 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg()) 01179 return false; 01180 01181 // Return true if the callee's argument area is no larger than the 01182 // caller's. 01183 return NextStackOffset <= FI.getIncomingArgSize(); 01184 } 01185 01186 void MipsSETargetLowering:: 01187 getOpndList(SmallVectorImpl<SDValue> &Ops, 01188 std::deque< std::pair<unsigned, SDValue> > &RegsToPass, 01189 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, 01190 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { 01191 Ops.push_back(Callee); 01192 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, 01193 InternalLinkage, CLI, Callee, Chain); 01194 } 01195 01196 SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const { 01197 LoadSDNode &Nd = *cast<LoadSDNode>(Op); 01198 01199 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore) 01200 return MipsTargetLowering::lowerLOAD(Op, DAG); 01201 01202 // Replace a double precision load with two i32 loads and a buildpair64. 01203 SDLoc DL(Op); 01204 SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain(); 01205 EVT PtrVT = Ptr.getValueType(); 01206 01207 // i32 load from lower address. 01208 SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr, 01209 MachinePointerInfo(), Nd.isVolatile(), 01210 Nd.isNonTemporal(), Nd.isInvariant(), 01211 Nd.getAlignment()); 01212 01213 // i32 load from higher address. 01214 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT)); 01215 SDValue Hi = DAG.getLoad(MVT::i32, DL, Lo.getValue(1), Ptr, 01216 MachinePointerInfo(), Nd.isVolatile(), 01217 Nd.isNonTemporal(), Nd.isInvariant(), 01218 std::min(Nd.getAlignment(), 4U)); 01219 01220 if (!Subtarget.isLittle()) 01221 std::swap(Lo, Hi); 01222 01223 SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi); 01224 SDValue Ops[2] = {BP, Hi.getValue(1)}; 01225 return DAG.getMergeValues(Ops, DL); 01226 } 01227 01228 SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { 01229 StoreSDNode &Nd = *cast<StoreSDNode>(Op); 01230 01231 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore) 01232 return MipsTargetLowering::lowerSTORE(Op, DAG); 01233 01234 // Replace a double precision store with two extractelement64s and i32 stores. 01235 SDLoc DL(Op); 01236 SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain(); 01237 EVT PtrVT = Ptr.getValueType(); 01238 SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, 01239 Val, DAG.getConstant(0, MVT::i32)); 01240 SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, 01241 Val, DAG.getConstant(1, MVT::i32)); 01242 01243 if (!Subtarget.isLittle()) 01244 std::swap(Lo, Hi); 01245 01246 // i32 store to lower address. 01247 Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(), 01248 Nd.isVolatile(), Nd.isNonTemporal(), Nd.getAlignment(), 01249 Nd.getAAInfo()); 01250 01251 // i32 store to higher address. 01252 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT)); 01253 return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(), 01254 Nd.isVolatile(), Nd.isNonTemporal(), 01255 std::min(Nd.getAlignment(), 4U), Nd.getAAInfo()); 01256 } 01257 01258 SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc, 01259 bool HasLo, bool HasHi, 01260 SelectionDAG &DAG) const { 01261 // MIPS32r6/MIPS64r6 removed accumulator based multiplies. 01262 assert(!Subtarget.hasMips32r6()); 01263 01264 EVT Ty = Op.getOperand(0).getValueType(); 01265 SDLoc DL(Op); 01266 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped, 01267 Op.getOperand(0), Op.getOperand(1)); 01268 SDValue Lo, Hi; 01269 01270 if (HasLo) 01271 Lo = DAG.getNode(MipsISD::MFLO, DL, Ty, Mult); 01272 if (HasHi) 01273 Hi = DAG.getNode(MipsISD::MFHI, DL, Ty, Mult); 01274 01275 if (!HasLo || !HasHi) 01276 return HasLo ? Lo : Hi; 01277 01278 SDValue Vals[] = { Lo, Hi }; 01279 return DAG.getMergeValues(Vals, DL); 01280 } 01281 01282 01283 static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) { 01284 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, 01285 DAG.getConstant(0, MVT::i32)); 01286 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, 01287 DAG.getConstant(1, MVT::i32)); 01288 return DAG.getNode(MipsISD::MTLOHI, DL, MVT::Untyped, InLo, InHi); 01289 } 01290 01291 static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) { 01292 SDValue Lo = DAG.getNode(MipsISD::MFLO, DL, MVT::i32, Op); 01293 SDValue Hi = DAG.getNode(MipsISD::MFHI, DL, MVT::i32, Op); 01294 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi); 01295 } 01296 01297 // This function expands mips intrinsic nodes which have 64-bit input operands 01298 // or output values. 01299 // 01300 // out64 = intrinsic-node in64 01301 // => 01302 // lo = copy (extract-element (in64, 0)) 01303 // hi = copy (extract-element (in64, 1)) 01304 // mips-specific-node 01305 // v0 = copy lo 01306 // v1 = copy hi 01307 // out64 = merge-values (v0, v1) 01308 // 01309 static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 01310 SDLoc DL(Op); 01311 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other; 01312 SmallVector<SDValue, 3> Ops; 01313 unsigned OpNo = 0; 01314 01315 // See if Op has a chain input. 01316 if (HasChainIn) 01317 Ops.push_back(Op->getOperand(OpNo++)); 01318 01319 // The next operand is the intrinsic opcode. 01320 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant); 01321 01322 // See if the next operand has type i64. 01323 SDValue Opnd = Op->getOperand(++OpNo), In64; 01324 01325 if (Opnd.getValueType() == MVT::i64) 01326 In64 = initAccumulator(Opnd, DL, DAG); 01327 else 01328 Ops.push_back(Opnd); 01329 01330 // Push the remaining operands. 01331 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo) 01332 Ops.push_back(Op->getOperand(OpNo)); 01333 01334 // Add In64 to the end of the list. 01335 if (In64.getNode()) 01336 Ops.push_back(In64); 01337 01338 // Scan output. 01339 SmallVector<EVT, 2> ResTys; 01340 01341 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end(); 01342 I != E; ++I) 01343 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I); 01344 01345 // Create node. 01346 SDValue Val = DAG.getNode(Opc, DL, ResTys, Ops); 01347 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val; 01348 01349 if (!HasChainIn) 01350 return Out; 01351 01352 assert(Val->getValueType(1) == MVT::Other); 01353 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) }; 01354 return DAG.getMergeValues(Vals, DL); 01355 } 01356 01357 // Lower an MSA copy intrinsic into the specified SelectionDAG node 01358 static SDValue lowerMSACopyIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 01359 SDLoc DL(Op); 01360 SDValue Vec = Op->getOperand(1); 01361 SDValue Idx = Op->getOperand(2); 01362 EVT ResTy = Op->getValueType(0); 01363 EVT EltTy = Vec->getValueType(0).getVectorElementType(); 01364 01365 SDValue Result = DAG.getNode(Opc, DL, ResTy, Vec, Idx, 01366 DAG.getValueType(EltTy)); 01367 01368 return Result; 01369 } 01370 01371 static SDValue lowerMSASplatZExt(SDValue Op, unsigned OpNr, SelectionDAG &DAG) { 01372 EVT ResVecTy = Op->getValueType(0); 01373 EVT ViaVecTy = ResVecTy; 01374 SDLoc DL(Op); 01375 01376 // When ResVecTy == MVT::v2i64, LaneA is the upper 32 bits of the lane and 01377 // LaneB is the lower 32-bits. Otherwise LaneA and LaneB are alternating 01378 // lanes. 01379 SDValue LaneA; 01380 SDValue LaneB = Op->getOperand(2); 01381 01382 if (ResVecTy == MVT::v2i64) { 01383 LaneA = DAG.getConstant(0, MVT::i32); 01384 ViaVecTy = MVT::v4i32; 01385 } else 01386 LaneA = LaneB; 01387 01388 SDValue Ops[16] = { LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, 01389 LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB }; 01390 01391 SDValue Result = DAG.getNode(ISD::BUILD_VECTOR, DL, ViaVecTy, 01392 makeArrayRef(Ops, ViaVecTy.getVectorNumElements())); 01393 01394 if (ViaVecTy != ResVecTy) 01395 Result = DAG.getNode(ISD::BITCAST, DL, ResVecTy, Result); 01396 01397 return Result; 01398 } 01399 01400 static SDValue lowerMSASplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG) { 01401 return DAG.getConstant(Op->getConstantOperandVal(ImmOp), Op->getValueType(0)); 01402 } 01403 01404 static SDValue getBuildVectorSplat(EVT VecTy, SDValue SplatValue, 01405 bool BigEndian, SelectionDAG &DAG) { 01406 EVT ViaVecTy = VecTy; 01407 SDValue SplatValueA = SplatValue; 01408 SDValue SplatValueB = SplatValue; 01409 SDLoc DL(SplatValue); 01410 01411 if (VecTy == MVT::v2i64) { 01412 // v2i64 BUILD_VECTOR must be performed via v4i32 so split into i32's. 01413 ViaVecTy = MVT::v4i32; 01414 01415 SplatValueA = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, SplatValue); 01416 SplatValueB = DAG.getNode(ISD::SRL, DL, MVT::i64, SplatValue, 01417 DAG.getConstant(32, MVT::i32)); 01418 SplatValueB = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, SplatValueB); 01419 } 01420 01421 // We currently hold the parts in little endian order. Swap them if 01422 // necessary. 01423 if (BigEndian) 01424 std::swap(SplatValueA, SplatValueB); 01425 01426 SDValue Ops[16] = { SplatValueA, SplatValueB, SplatValueA, SplatValueB, 01427 SplatValueA, SplatValueB, SplatValueA, SplatValueB, 01428 SplatValueA, SplatValueB, SplatValueA, SplatValueB, 01429 SplatValueA, SplatValueB, SplatValueA, SplatValueB }; 01430 01431 SDValue Result = DAG.getNode(ISD::BUILD_VECTOR, DL, ViaVecTy, 01432 makeArrayRef(Ops, ViaVecTy.getVectorNumElements())); 01433 01434 if (VecTy != ViaVecTy) 01435 Result = DAG.getNode(ISD::BITCAST, DL, VecTy, Result); 01436 01437 return Result; 01438 } 01439 01440 static SDValue lowerMSABinaryBitImmIntr(SDValue Op, SelectionDAG &DAG, 01441 unsigned Opc, SDValue Imm, 01442 bool BigEndian) { 01443 EVT VecTy = Op->getValueType(0); 01444 SDValue Exp2Imm; 01445 SDLoc DL(Op); 01446 01447 // The DAG Combiner can't constant fold bitcasted vectors yet so we must do it 01448 // here for now. 01449 if (VecTy == MVT::v2i64) { 01450 if (ConstantSDNode *CImm = dyn_cast<ConstantSDNode>(Imm)) { 01451 APInt BitImm = APInt(64, 1) << CImm->getAPIntValue(); 01452 01453 SDValue BitImmHiOp = DAG.getConstant(BitImm.lshr(32).trunc(32), MVT::i32); 01454 SDValue BitImmLoOp = DAG.getConstant(BitImm.trunc(32), MVT::i32); 01455 01456 if (BigEndian) 01457 std::swap(BitImmLoOp, BitImmHiOp); 01458 01459 Exp2Imm = 01460 DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, 01461 DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4i32, BitImmLoOp, 01462 BitImmHiOp, BitImmLoOp, BitImmHiOp)); 01463 } 01464 } 01465 01466 if (!Exp2Imm.getNode()) { 01467 // We couldnt constant fold, do a vector shift instead 01468 01469 // Extend i32 to i64 if necessary. Sign or zero extend doesn't matter since 01470 // only values 0-63 are valid. 01471 if (VecTy == MVT::v2i64) 01472 Imm = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Imm); 01473 01474 Exp2Imm = getBuildVectorSplat(VecTy, Imm, BigEndian, DAG); 01475 01476 Exp2Imm = 01477 DAG.getNode(ISD::SHL, DL, VecTy, DAG.getConstant(1, VecTy), Exp2Imm); 01478 } 01479 01480 return DAG.getNode(Opc, DL, VecTy, Op->getOperand(1), Exp2Imm); 01481 } 01482 01483 static SDValue lowerMSABitClear(SDValue Op, SelectionDAG &DAG) { 01484 EVT ResTy = Op->getValueType(0); 01485 SDLoc DL(Op); 01486 SDValue One = DAG.getConstant(1, ResTy); 01487 SDValue Bit = DAG.getNode(ISD::SHL, DL, ResTy, One, Op->getOperand(2)); 01488 01489 return DAG.getNode(ISD::AND, DL, ResTy, Op->getOperand(1), 01490 DAG.getNOT(DL, Bit, ResTy)); 01491 } 01492 01493 static SDValue lowerMSABitClearImm(SDValue Op, SelectionDAG &DAG) { 01494 SDLoc DL(Op); 01495 EVT ResTy = Op->getValueType(0); 01496 APInt BitImm = APInt(ResTy.getVectorElementType().getSizeInBits(), 1) 01497 << cast<ConstantSDNode>(Op->getOperand(2))->getAPIntValue(); 01498 SDValue BitMask = DAG.getConstant(~BitImm, ResTy); 01499 01500 return DAG.getNode(ISD::AND, DL, ResTy, Op->getOperand(1), BitMask); 01501 } 01502 01503 SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, 01504 SelectionDAG &DAG) const { 01505 SDLoc DL(Op); 01506 01507 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) { 01508 default: 01509 return SDValue(); 01510 case Intrinsic::mips_shilo: 01511 return lowerDSPIntr(Op, DAG, MipsISD::SHILO); 01512 case Intrinsic::mips_dpau_h_qbl: 01513 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL); 01514 case Intrinsic::mips_dpau_h_qbr: 01515 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR); 01516 case Intrinsic::mips_dpsu_h_qbl: 01517 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL); 01518 case Intrinsic::mips_dpsu_h_qbr: 01519 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR); 01520 case Intrinsic::mips_dpa_w_ph: 01521 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH); 01522 case Intrinsic::mips_dps_w_ph: 01523 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH); 01524 case Intrinsic::mips_dpax_w_ph: 01525 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH); 01526 case Intrinsic::mips_dpsx_w_ph: 01527 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH); 01528 case Intrinsic::mips_mulsa_w_ph: 01529 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH); 01530 case Intrinsic::mips_mult: 01531 return lowerDSPIntr(Op, DAG, MipsISD::Mult); 01532 case Intrinsic::mips_multu: 01533 return lowerDSPIntr(Op, DAG, MipsISD::Multu); 01534 case Intrinsic::mips_madd: 01535 return lowerDSPIntr(Op, DAG, MipsISD::MAdd); 01536 case Intrinsic::mips_maddu: 01537 return lowerDSPIntr(Op, DAG, MipsISD::MAddu); 01538 case Intrinsic::mips_msub: 01539 return lowerDSPIntr(Op, DAG, MipsISD::MSub); 01540 case Intrinsic::mips_msubu: 01541 return lowerDSPIntr(Op, DAG, MipsISD::MSubu); 01542 case Intrinsic::mips_addv_b: 01543 case Intrinsic::mips_addv_h: 01544 case Intrinsic::mips_addv_w: 01545 case Intrinsic::mips_addv_d: 01546 return DAG.getNode(ISD::ADD, DL, Op->getValueType(0), Op->getOperand(1), 01547 Op->getOperand(2)); 01548 case Intrinsic::mips_addvi_b: 01549 case Intrinsic::mips_addvi_h: 01550 case Intrinsic::mips_addvi_w: 01551 case Intrinsic::mips_addvi_d: 01552 return DAG.getNode(ISD::ADD, DL, Op->getValueType(0), Op->getOperand(1), 01553 lowerMSASplatImm(Op, 2, DAG)); 01554 case Intrinsic::mips_and_v: 01555 return DAG.getNode(ISD::AND, DL, Op->getValueType(0), Op->getOperand(1), 01556 Op->getOperand(2)); 01557 case Intrinsic::mips_andi_b: 01558 return DAG.getNode(ISD::AND, DL, Op->getValueType(0), Op->getOperand(1), 01559 lowerMSASplatImm(Op, 2, DAG)); 01560 case Intrinsic::mips_bclr_b: 01561 case Intrinsic::mips_bclr_h: 01562 case Intrinsic::mips_bclr_w: 01563 case Intrinsic::mips_bclr_d: 01564 return lowerMSABitClear(Op, DAG); 01565 case Intrinsic::mips_bclri_b: 01566 case Intrinsic::mips_bclri_h: 01567 case Intrinsic::mips_bclri_w: 01568 case Intrinsic::mips_bclri_d: 01569 return lowerMSABitClearImm(Op, DAG); 01570 case Intrinsic::mips_binsli_b: 01571 case Intrinsic::mips_binsli_h: 01572 case Intrinsic::mips_binsli_w: 01573 case Intrinsic::mips_binsli_d: { 01574 // binsli_x(IfClear, IfSet, nbits) -> (vselect LBitsMask, IfSet, IfClear) 01575 EVT VecTy = Op->getValueType(0); 01576 EVT EltTy = VecTy.getVectorElementType(); 01577 APInt Mask = APInt::getHighBitsSet(EltTy.getSizeInBits(), 01578 Op->getConstantOperandVal(3)); 01579 return DAG.getNode(ISD::VSELECT, DL, VecTy, 01580 DAG.getConstant(Mask, VecTy, true), Op->getOperand(2), 01581 Op->getOperand(1)); 01582 } 01583 case Intrinsic::mips_binsri_b: 01584 case Intrinsic::mips_binsri_h: 01585 case Intrinsic::mips_binsri_w: 01586 case Intrinsic::mips_binsri_d: { 01587 // binsri_x(IfClear, IfSet, nbits) -> (vselect RBitsMask, IfSet, IfClear) 01588 EVT VecTy = Op->getValueType(0); 01589 EVT EltTy = VecTy.getVectorElementType(); 01590 APInt Mask = APInt::getLowBitsSet(EltTy.getSizeInBits(), 01591 Op->getConstantOperandVal(3)); 01592 return DAG.getNode(ISD::VSELECT, DL, VecTy, 01593 DAG.getConstant(Mask, VecTy, true), Op->getOperand(2), 01594 Op->getOperand(1)); 01595 } 01596 case Intrinsic::mips_bmnz_v: 01597 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), Op->getOperand(3), 01598 Op->getOperand(2), Op->getOperand(1)); 01599 case Intrinsic::mips_bmnzi_b: 01600 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), 01601 lowerMSASplatImm(Op, 3, DAG), Op->getOperand(2), 01602 Op->getOperand(1)); 01603 case Intrinsic::mips_bmz_v: 01604 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), Op->getOperand(3), 01605 Op->getOperand(1), Op->getOperand(2)); 01606 case Intrinsic::mips_bmzi_b: 01607 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), 01608 lowerMSASplatImm(Op, 3, DAG), Op->getOperand(1), 01609 Op->getOperand(2)); 01610 case Intrinsic::mips_bneg_b: 01611 case Intrinsic::mips_bneg_h: 01612 case Intrinsic::mips_bneg_w: 01613 case Intrinsic::mips_bneg_d: { 01614 EVT VecTy = Op->getValueType(0); 01615 SDValue One = DAG.getConstant(1, VecTy); 01616 01617 return DAG.getNode(ISD::XOR, DL, VecTy, Op->getOperand(1), 01618 DAG.getNode(ISD::SHL, DL, VecTy, One, 01619 Op->getOperand(2))); 01620 } 01621 case Intrinsic::mips_bnegi_b: 01622 case Intrinsic::mips_bnegi_h: 01623 case Intrinsic::mips_bnegi_w: 01624 case Intrinsic::mips_bnegi_d: 01625 return lowerMSABinaryBitImmIntr(Op, DAG, ISD::XOR, Op->getOperand(2), 01626 !Subtarget.isLittle()); 01627 case Intrinsic::mips_bnz_b: 01628 case Intrinsic::mips_bnz_h: 01629 case Intrinsic::mips_bnz_w: 01630 case Intrinsic::mips_bnz_d: 01631 return DAG.getNode(MipsISD::VALL_NONZERO, DL, Op->getValueType(0), 01632 Op->getOperand(1)); 01633 case Intrinsic::mips_bnz_v: 01634 return DAG.getNode(MipsISD::VANY_NONZERO, DL, Op->getValueType(0), 01635 Op->getOperand(1)); 01636 case Intrinsic::mips_bsel_v: 01637 // bsel_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear) 01638 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), 01639 Op->getOperand(1), Op->getOperand(3), 01640 Op->getOperand(2)); 01641 case Intrinsic::mips_bseli_b: 01642 // bseli_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear) 01643 return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), 01644 Op->getOperand(1), lowerMSASplatImm(Op, 3, DAG), 01645 Op->getOperand(2)); 01646 case Intrinsic::mips_bset_b: 01647 case Intrinsic::mips_bset_h: 01648 case Intrinsic::mips_bset_w: 01649 case Intrinsic::mips_bset_d: { 01650 EVT VecTy = Op->getValueType(0); 01651 SDValue One = DAG.getConstant(1, VecTy); 01652 01653 return DAG.getNode(ISD::OR, DL, VecTy, Op->getOperand(1), 01654 DAG.getNode(ISD::SHL, DL, VecTy, One, 01655 Op->getOperand(2))); 01656 } 01657 case Intrinsic::mips_bseti_b: 01658 case Intrinsic::mips_bseti_h: 01659 case Intrinsic::mips_bseti_w: 01660 case Intrinsic::mips_bseti_d: 01661 return lowerMSABinaryBitImmIntr(Op, DAG, ISD::OR, Op->getOperand(2), 01662 !Subtarget.isLittle()); 01663 case Intrinsic::mips_bz_b: 01664 case Intrinsic::mips_bz_h: 01665 case Intrinsic::mips_bz_w: 01666 case Intrinsic::mips_bz_d: 01667 return DAG.getNode(MipsISD::VALL_ZERO, DL, Op->getValueType(0), 01668 Op->getOperand(1)); 01669 case Intrinsic::mips_bz_v: 01670 return DAG.getNode(MipsISD::VANY_ZERO, DL, Op->getValueType(0), 01671 Op->getOperand(1)); 01672 case Intrinsic::mips_ceq_b: 01673 case Intrinsic::mips_ceq_h: 01674 case Intrinsic::mips_ceq_w: 01675 case Intrinsic::mips_ceq_d: 01676 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01677 Op->getOperand(2), ISD::SETEQ); 01678 case Intrinsic::mips_ceqi_b: 01679 case Intrinsic::mips_ceqi_h: 01680 case Intrinsic::mips_ceqi_w: 01681 case Intrinsic::mips_ceqi_d: 01682 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01683 lowerMSASplatImm(Op, 2, DAG), ISD::SETEQ); 01684 case Intrinsic::mips_cle_s_b: 01685 case Intrinsic::mips_cle_s_h: 01686 case Intrinsic::mips_cle_s_w: 01687 case Intrinsic::mips_cle_s_d: 01688 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01689 Op->getOperand(2), ISD::SETLE); 01690 case Intrinsic::mips_clei_s_b: 01691 case Intrinsic::mips_clei_s_h: 01692 case Intrinsic::mips_clei_s_w: 01693 case Intrinsic::mips_clei_s_d: 01694 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01695 lowerMSASplatImm(Op, 2, DAG), ISD::SETLE); 01696 case Intrinsic::mips_cle_u_b: 01697 case Intrinsic::mips_cle_u_h: 01698 case Intrinsic::mips_cle_u_w: 01699 case Intrinsic::mips_cle_u_d: 01700 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01701 Op->getOperand(2), ISD::SETULE); 01702 case Intrinsic::mips_clei_u_b: 01703 case Intrinsic::mips_clei_u_h: 01704 case Intrinsic::mips_clei_u_w: 01705 case Intrinsic::mips_clei_u_d: 01706 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01707 lowerMSASplatImm(Op, 2, DAG), ISD::SETULE); 01708 case Intrinsic::mips_clt_s_b: 01709 case Intrinsic::mips_clt_s_h: 01710 case Intrinsic::mips_clt_s_w: 01711 case Intrinsic::mips_clt_s_d: 01712 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01713 Op->getOperand(2), ISD::SETLT); 01714 case Intrinsic::mips_clti_s_b: 01715 case Intrinsic::mips_clti_s_h: 01716 case Intrinsic::mips_clti_s_w: 01717 case Intrinsic::mips_clti_s_d: 01718 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01719 lowerMSASplatImm(Op, 2, DAG), ISD::SETLT); 01720 case Intrinsic::mips_clt_u_b: 01721 case Intrinsic::mips_clt_u_h: 01722 case Intrinsic::mips_clt_u_w: 01723 case Intrinsic::mips_clt_u_d: 01724 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01725 Op->getOperand(2), ISD::SETULT); 01726 case Intrinsic::mips_clti_u_b: 01727 case Intrinsic::mips_clti_u_h: 01728 case Intrinsic::mips_clti_u_w: 01729 case Intrinsic::mips_clti_u_d: 01730 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01731 lowerMSASplatImm(Op, 2, DAG), ISD::SETULT); 01732 case Intrinsic::mips_copy_s_b: 01733 case Intrinsic::mips_copy_s_h: 01734 case Intrinsic::mips_copy_s_w: 01735 return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_SEXT_ELT); 01736 case Intrinsic::mips_copy_s_d: 01737 if (Subtarget.hasMips64()) 01738 // Lower directly into VEXTRACT_SEXT_ELT since i64 is legal on Mips64. 01739 return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_SEXT_ELT); 01740 else { 01741 // Lower into the generic EXTRACT_VECTOR_ELT node and let the type 01742 // legalizer and EXTRACT_VECTOR_ELT lowering sort it out. 01743 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op), 01744 Op->getValueType(0), Op->getOperand(1), 01745 Op->getOperand(2)); 01746 } 01747 case Intrinsic::mips_copy_u_b: 01748 case Intrinsic::mips_copy_u_h: 01749 case Intrinsic::mips_copy_u_w: 01750 return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_ZEXT_ELT); 01751 case Intrinsic::mips_copy_u_d: 01752 if (Subtarget.hasMips64()) 01753 // Lower directly into VEXTRACT_ZEXT_ELT since i64 is legal on Mips64. 01754 return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_ZEXT_ELT); 01755 else { 01756 // Lower into the generic EXTRACT_VECTOR_ELT node and let the type 01757 // legalizer and EXTRACT_VECTOR_ELT lowering sort it out. 01758 // Note: When i64 is illegal, this results in copy_s.w instructions 01759 // instead of copy_u.w instructions. This makes no difference to the 01760 // behaviour since i64 is only illegal when the register file is 32-bit. 01761 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op), 01762 Op->getValueType(0), Op->getOperand(1), 01763 Op->getOperand(2)); 01764 } 01765 case Intrinsic::mips_div_s_b: 01766 case Intrinsic::mips_div_s_h: 01767 case Intrinsic::mips_div_s_w: 01768 case Intrinsic::mips_div_s_d: 01769 return DAG.getNode(ISD::SDIV, DL, Op->getValueType(0), Op->getOperand(1), 01770 Op->getOperand(2)); 01771 case Intrinsic::mips_div_u_b: 01772 case Intrinsic::mips_div_u_h: 01773 case Intrinsic::mips_div_u_w: 01774 case Intrinsic::mips_div_u_d: 01775 return DAG.getNode(ISD::UDIV, DL, Op->getValueType(0), Op->getOperand(1), 01776 Op->getOperand(2)); 01777 case Intrinsic::mips_fadd_w: 01778 case Intrinsic::mips_fadd_d: 01779 return DAG.getNode(ISD::FADD, DL, Op->getValueType(0), Op->getOperand(1), 01780 Op->getOperand(2)); 01781 // Don't lower mips_fcaf_[wd] since LLVM folds SETFALSE condcodes away 01782 case Intrinsic::mips_fceq_w: 01783 case Intrinsic::mips_fceq_d: 01784 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01785 Op->getOperand(2), ISD::SETOEQ); 01786 case Intrinsic::mips_fcle_w: 01787 case Intrinsic::mips_fcle_d: 01788 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01789 Op->getOperand(2), ISD::SETOLE); 01790 case Intrinsic::mips_fclt_w: 01791 case Intrinsic::mips_fclt_d: 01792 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01793 Op->getOperand(2), ISD::SETOLT); 01794 case Intrinsic::mips_fcne_w: 01795 case Intrinsic::mips_fcne_d: 01796 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01797 Op->getOperand(2), ISD::SETONE); 01798 case Intrinsic::mips_fcor_w: 01799 case Intrinsic::mips_fcor_d: 01800 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01801 Op->getOperand(2), ISD::SETO); 01802 case Intrinsic::mips_fcueq_w: 01803 case Intrinsic::mips_fcueq_d: 01804 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01805 Op->getOperand(2), ISD::SETUEQ); 01806 case Intrinsic::mips_fcule_w: 01807 case Intrinsic::mips_fcule_d: 01808 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01809 Op->getOperand(2), ISD::SETULE); 01810 case Intrinsic::mips_fcult_w: 01811 case Intrinsic::mips_fcult_d: 01812 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01813 Op->getOperand(2), ISD::SETULT); 01814 case Intrinsic::mips_fcun_w: 01815 case Intrinsic::mips_fcun_d: 01816 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01817 Op->getOperand(2), ISD::SETUO); 01818 case Intrinsic::mips_fcune_w: 01819 case Intrinsic::mips_fcune_d: 01820 return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1), 01821 Op->getOperand(2), ISD::SETUNE); 01822 case Intrinsic::mips_fdiv_w: 01823 case Intrinsic::mips_fdiv_d: 01824 return DAG.getNode(ISD::FDIV, DL, Op->getValueType(0), Op->getOperand(1), 01825 Op->getOperand(2)); 01826 case Intrinsic::mips_ffint_u_w: 01827 case Intrinsic::mips_ffint_u_d: 01828 return DAG.getNode(ISD::UINT_TO_FP, DL, Op->getValueType(0), 01829 Op->getOperand(1)); 01830 case Intrinsic::mips_ffint_s_w: 01831 case Intrinsic::mips_ffint_s_d: 01832 return DAG.getNode(ISD::SINT_TO_FP, DL, Op->getValueType(0), 01833 Op->getOperand(1)); 01834 case Intrinsic::mips_fill_b: 01835 case Intrinsic::mips_fill_h: 01836 case Intrinsic::mips_fill_w: 01837 case Intrinsic::mips_fill_d: { 01838 SmallVector<SDValue, 16> Ops; 01839 EVT ResTy = Op->getValueType(0); 01840 01841 for (unsigned i = 0; i < ResTy.getVectorNumElements(); ++i) 01842 Ops.push_back(Op->getOperand(1)); 01843 01844 // If ResTy is v2i64 then the type legalizer will break this node down into 01845 // an equivalent v4i32. 01846 return DAG.getNode(ISD::BUILD_VECTOR, DL, ResTy, Ops); 01847 } 01848 case Intrinsic::mips_fexp2_w: 01849 case Intrinsic::mips_fexp2_d: { 01850 EVT ResTy = Op->getValueType(0); 01851 return DAG.getNode( 01852 ISD::FMUL, SDLoc(Op), ResTy, Op->getOperand(1), 01853 DAG.getNode(ISD::FEXP2, SDLoc(Op), ResTy, Op->getOperand(2))); 01854 } 01855 case Intrinsic::mips_flog2_w: 01856 case Intrinsic::mips_flog2_d: 01857 return DAG.getNode(ISD::FLOG2, DL, Op->getValueType(0), Op->getOperand(1)); 01858 case Intrinsic::mips_fmadd_w: 01859 case Intrinsic::mips_fmadd_d: 01860 return DAG.getNode(ISD::FMA, SDLoc(Op), Op->getValueType(0), 01861 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3)); 01862 case Intrinsic::mips_fmul_w: 01863 case Intrinsic::mips_fmul_d: 01864 return DAG.getNode(ISD::FMUL, DL, Op->getValueType(0), Op->getOperand(1), 01865 Op->getOperand(2)); 01866 case Intrinsic::mips_fmsub_w: 01867 case Intrinsic::mips_fmsub_d: { 01868 EVT ResTy = Op->getValueType(0); 01869 return DAG.getNode(ISD::FSUB, SDLoc(Op), ResTy, Op->getOperand(1), 01870 DAG.getNode(ISD::FMUL, SDLoc(Op), ResTy, 01871 Op->getOperand(2), Op->getOperand(3))); 01872 } 01873 case Intrinsic::mips_frint_w: 01874 case Intrinsic::mips_frint_d: 01875 return DAG.getNode(ISD::FRINT, DL, Op->getValueType(0), Op->getOperand(1)); 01876 case Intrinsic::mips_fsqrt_w: 01877 case Intrinsic::mips_fsqrt_d: 01878 return DAG.getNode(ISD::FSQRT, DL, Op->getValueType(0), Op->getOperand(1)); 01879 case Intrinsic::mips_fsub_w: 01880 case Intrinsic::mips_fsub_d: 01881 return DAG.getNode(ISD::FSUB, DL, Op->getValueType(0), Op->getOperand(1), 01882 Op->getOperand(2)); 01883 case Intrinsic::mips_ftrunc_u_w: 01884 case Intrinsic::mips_ftrunc_u_d: 01885 return DAG.getNode(ISD::FP_TO_UINT, DL, Op->getValueType(0), 01886 Op->getOperand(1)); 01887 case Intrinsic::mips_ftrunc_s_w: 01888 case Intrinsic::mips_ftrunc_s_d: 01889 return DAG.getNode(ISD::FP_TO_SINT, DL, Op->getValueType(0), 01890 Op->getOperand(1)); 01891 case Intrinsic::mips_ilvev_b: 01892 case Intrinsic::mips_ilvev_h: 01893 case Intrinsic::mips_ilvev_w: 01894 case Intrinsic::mips_ilvev_d: 01895 return DAG.getNode(MipsISD::ILVEV, DL, Op->getValueType(0), 01896 Op->getOperand(1), Op->getOperand(2)); 01897 case Intrinsic::mips_ilvl_b: 01898 case Intrinsic::mips_ilvl_h: 01899 case Intrinsic::mips_ilvl_w: 01900 case Intrinsic::mips_ilvl_d: 01901 return DAG.getNode(MipsISD::ILVL, DL, Op->getValueType(0), 01902 Op->getOperand(1), Op->getOperand(2)); 01903 case Intrinsic::mips_ilvod_b: 01904 case Intrinsic::mips_ilvod_h: 01905 case Intrinsic::mips_ilvod_w: 01906 case Intrinsic::mips_ilvod_d: 01907 return DAG.getNode(MipsISD::ILVOD, DL, Op->getValueType(0), 01908 Op->getOperand(1), Op->getOperand(2)); 01909 case Intrinsic::mips_ilvr_b: 01910 case Intrinsic::mips_ilvr_h: 01911 case Intrinsic::mips_ilvr_w: 01912 case Intrinsic::mips_ilvr_d: 01913 return DAG.getNode(MipsISD::ILVR, DL, Op->getValueType(0), 01914 Op->getOperand(1), Op->getOperand(2)); 01915 case Intrinsic::mips_insert_b: 01916 case Intrinsic::mips_insert_h: 01917 case Intrinsic::mips_insert_w: 01918 case Intrinsic::mips_insert_d: 01919 return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(Op), Op->getValueType(0), 01920 Op->getOperand(1), Op->getOperand(3), Op->getOperand(2)); 01921 case Intrinsic::mips_insve_b: 01922 case Intrinsic::mips_insve_h: 01923 case Intrinsic::mips_insve_w: 01924 case Intrinsic::mips_insve_d: 01925 return DAG.getNode(MipsISD::INSVE, DL, Op->getValueType(0), 01926 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3), 01927 DAG.getConstant(0, MVT::i32)); 01928 case Intrinsic::mips_ldi_b: 01929 case Intrinsic::mips_ldi_h: 01930 case Intrinsic::mips_ldi_w: 01931 case Intrinsic::mips_ldi_d: 01932 return lowerMSASplatImm(Op, 1, DAG); 01933 case Intrinsic::mips_lsa: 01934 case Intrinsic::mips_dlsa: { 01935 EVT ResTy = Op->getValueType(0); 01936 return DAG.getNode(ISD::ADD, SDLoc(Op), ResTy, Op->getOperand(1), 01937 DAG.getNode(ISD::SHL, SDLoc(Op), ResTy, 01938 Op->getOperand(2), Op->getOperand(3))); 01939 } 01940 case Intrinsic::mips_maddv_b: 01941 case Intrinsic::mips_maddv_h: 01942 case Intrinsic::mips_maddv_w: 01943 case Intrinsic::mips_maddv_d: { 01944 EVT ResTy = Op->getValueType(0); 01945 return DAG.getNode(ISD::ADD, SDLoc(Op), ResTy, Op->getOperand(1), 01946 DAG.getNode(ISD::MUL, SDLoc(Op), ResTy, 01947 Op->getOperand(2), Op->getOperand(3))); 01948 } 01949 case Intrinsic::mips_max_s_b: 01950 case Intrinsic::mips_max_s_h: 01951 case Intrinsic::mips_max_s_w: 01952 case Intrinsic::mips_max_s_d: 01953 return DAG.getNode(MipsISD::VSMAX, DL, Op->getValueType(0), 01954 Op->getOperand(1), Op->getOperand(2)); 01955 case Intrinsic::mips_max_u_b: 01956 case Intrinsic::mips_max_u_h: 01957 case Intrinsic::mips_max_u_w: 01958 case Intrinsic::mips_max_u_d: 01959 return DAG.getNode(MipsISD::VUMAX, DL, Op->getValueType(0), 01960 Op->getOperand(1), Op->getOperand(2)); 01961 case Intrinsic::mips_maxi_s_b: 01962 case Intrinsic::mips_maxi_s_h: 01963 case Intrinsic::mips_maxi_s_w: 01964 case Intrinsic::mips_maxi_s_d: 01965 return DAG.getNode(MipsISD::VSMAX, DL, Op->getValueType(0), 01966 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG)); 01967 case Intrinsic::mips_maxi_u_b: 01968 case Intrinsic::mips_maxi_u_h: 01969 case Intrinsic::mips_maxi_u_w: 01970 case Intrinsic::mips_maxi_u_d: 01971 return DAG.getNode(MipsISD::VUMAX, DL, Op->getValueType(0), 01972 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG)); 01973 case Intrinsic::mips_min_s_b: 01974 case Intrinsic::mips_min_s_h: 01975 case Intrinsic::mips_min_s_w: 01976 case Intrinsic::mips_min_s_d: 01977 return DAG.getNode(MipsISD::VSMIN, DL, Op->getValueType(0), 01978 Op->getOperand(1), Op->getOperand(2)); 01979 case Intrinsic::mips_min_u_b: 01980 case Intrinsic::mips_min_u_h: 01981 case Intrinsic::mips_min_u_w: 01982 case Intrinsic::mips_min_u_d: 01983 return DAG.getNode(MipsISD::VUMIN, DL, Op->getValueType(0), 01984 Op->getOperand(1), Op->getOperand(2)); 01985 case Intrinsic::mips_mini_s_b: 01986 case Intrinsic::mips_mini_s_h: 01987 case Intrinsic::mips_mini_s_w: 01988 case Intrinsic::mips_mini_s_d: 01989 return DAG.getNode(MipsISD::VSMIN, DL, Op->getValueType(0), 01990 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG)); 01991 case Intrinsic::mips_mini_u_b: 01992 case Intrinsic::mips_mini_u_h: 01993 case Intrinsic::mips_mini_u_w: 01994 case Intrinsic::mips_mini_u_d: 01995 return DAG.getNode(MipsISD::VUMIN, DL, Op->getValueType(0), 01996 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG)); 01997 case Intrinsic::mips_mod_s_b: 01998 case Intrinsic::mips_mod_s_h: 01999 case Intrinsic::mips_mod_s_w: 02000 case Intrinsic::mips_mod_s_d: 02001 return DAG.getNode(ISD::SREM, DL, Op->getValueType(0), Op->getOperand(1), 02002 Op->getOperand(2)); 02003 case Intrinsic::mips_mod_u_b: 02004 case Intrinsic::mips_mod_u_h: 02005 case Intrinsic::mips_mod_u_w: 02006 case Intrinsic::mips_mod_u_d: 02007 return DAG.getNode(ISD::UREM, DL, Op->getValueType(0), Op->getOperand(1), 02008 Op->getOperand(2)); 02009 case Intrinsic::mips_mulv_b: 02010 case Intrinsic::mips_mulv_h: 02011 case Intrinsic::mips_mulv_w: 02012 case Intrinsic::mips_mulv_d: 02013 return DAG.getNode(ISD::MUL, DL, Op->getValueType(0), Op->getOperand(1), 02014 Op->getOperand(2)); 02015 case Intrinsic::mips_msubv_b: 02016 case Intrinsic::mips_msubv_h: 02017 case Intrinsic::mips_msubv_w: 02018 case Intrinsic::mips_msubv_d: { 02019 EVT ResTy = Op->getValueType(0); 02020 return DAG.getNode(ISD::SUB, SDLoc(Op), ResTy, Op->getOperand(1), 02021 DAG.getNode(ISD::MUL, SDLoc(Op), ResTy, 02022 Op->getOperand(2), Op->getOperand(3))); 02023 } 02024 case Intrinsic::mips_nlzc_b: 02025 case Intrinsic::mips_nlzc_h: 02026 case Intrinsic::mips_nlzc_w: 02027 case Intrinsic::mips_nlzc_d: 02028 return DAG.getNode(ISD::CTLZ, DL, Op->getValueType(0), Op->getOperand(1)); 02029 case Intrinsic::mips_nor_v: { 02030 SDValue Res = DAG.getNode(ISD::OR, DL, Op->getValueType(0), 02031 Op->getOperand(1), Op->getOperand(2)); 02032 return DAG.getNOT(DL, Res, Res->getValueType(0)); 02033 } 02034 case Intrinsic::mips_nori_b: { 02035 SDValue Res = DAG.getNode(ISD::OR, DL, Op->getValueType(0), 02036 Op->getOperand(1), 02037 lowerMSASplatImm(Op, 2, DAG)); 02038 return DAG.getNOT(DL, Res, Res->getValueType(0)); 02039 } 02040 case Intrinsic::mips_or_v: 02041 return DAG.getNode(ISD::OR, DL, Op->getValueType(0), Op->getOperand(1), 02042 Op->getOperand(2)); 02043 case Intrinsic::mips_ori_b: 02044 return DAG.getNode(ISD::OR, DL, Op->getValueType(0), 02045 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG)); 02046 case Intrinsic::mips_pckev_b: 02047 case Intrinsic::mips_pckev_h: 02048 case Intrinsic::mips_pckev_w: 02049 case Intrinsic::mips_pckev_d: 02050 return DAG.getNode(MipsISD::PCKEV, DL, Op->getValueType(0), 02051 Op->getOperand(1), Op->getOperand(2)); 02052 case Intrinsic::mips_pckod_b: 02053 case Intrinsic::mips_pckod_h: 02054 case Intrinsic::mips_pckod_w: 02055 case Intrinsic::mips_pckod_d: 02056 return DAG.getNode(MipsISD::PCKOD, DL, Op->getValueType(0), 02057 Op->getOperand(1), Op->getOperand(2)); 02058 case Intrinsic::mips_pcnt_b: 02059 case Intrinsic::mips_pcnt_h: 02060 case Intrinsic::mips_pcnt_w: 02061 case Intrinsic::mips_pcnt_d: 02062 return DAG.getNode(ISD::CTPOP, DL, Op->getValueType(0), Op->getOperand(1)); 02063 case Intrinsic::mips_shf_b: 02064 case Intrinsic::mips_shf_h: 02065 case Intrinsic::mips_shf_w: 02066 return DAG.getNode(MipsISD::SHF, DL, Op->getValueType(0), 02067 Op->getOperand(2), Op->getOperand(1)); 02068 case Intrinsic::mips_sll_b: 02069 case Intrinsic::mips_sll_h: 02070 case Intrinsic::mips_sll_w: 02071 case Intrinsic::mips_sll_d: 02072 return DAG.getNode(ISD::SHL, DL, Op->getValueType(0), Op->getOperand(1), 02073 Op->getOperand(2)); 02074 case Intrinsic::mips_slli_b: 02075 case Intrinsic::mips_slli_h: 02076 case Intrinsic::mips_slli_w: 02077 case Intrinsic::mips_slli_d: 02078 return DAG.getNode(ISD::SHL, DL, Op->getValueType(0), 02079 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG)); 02080 case Intrinsic::mips_splat_b: 02081 case Intrinsic::mips_splat_h: 02082 case Intrinsic::mips_splat_w: 02083 case Intrinsic::mips_splat_d: 02084 // We can't lower via VECTOR_SHUFFLE because it requires constant shuffle 02085 // masks, nor can we lower via BUILD_VECTOR & EXTRACT_VECTOR_ELT because 02086 // EXTRACT_VECTOR_ELT can't extract i64's on MIPS32. 02087 // Instead we lower to MipsISD::VSHF and match from there. 02088 return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0), 02089 lowerMSASplatZExt(Op, 2, DAG), Op->getOperand(1), 02090 Op->getOperand(1)); 02091 case Intrinsic::mips_splati_b: 02092 case Intrinsic::mips_splati_h: 02093 case Intrinsic::mips_splati_w: 02094 case Intrinsic::mips_splati_d: 02095 return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0), 02096 lowerMSASplatImm(Op, 2, DAG), Op->getOperand(1), 02097 Op->getOperand(1)); 02098 case Intrinsic::mips_sra_b: 02099 case Intrinsic::mips_sra_h: 02100 case Intrinsic::mips_sra_w: 02101 case Intrinsic::mips_sra_d: 02102 return DAG.getNode(ISD::SRA, DL, Op->getValueType(0), Op->getOperand(1), 02103 Op->getOperand(2)); 02104 case Intrinsic::mips_srai_b: 02105 case Intrinsic::mips_srai_h: 02106 case Intrinsic::mips_srai_w: 02107 case Intrinsic::mips_srai_d: 02108 return DAG.getNode(ISD::SRA, DL, Op->getValueType(0), 02109 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG)); 02110 case Intrinsic::mips_srl_b: 02111 case Intrinsic::mips_srl_h: 02112 case Intrinsic::mips_srl_w: 02113 case Intrinsic::mips_srl_d: 02114 return DAG.getNode(ISD::SRL, DL, Op->getValueType(0), Op->getOperand(1), 02115 Op->getOperand(2)); 02116 case Intrinsic::mips_srli_b: 02117 case Intrinsic::mips_srli_h: 02118 case Intrinsic::mips_srli_w: 02119 case Intrinsic::mips_srli_d: 02120 return DAG.getNode(ISD::SRL, DL, Op->getValueType(0), 02121 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG)); 02122 case Intrinsic::mips_subv_b: 02123 case Intrinsic::mips_subv_h: 02124 case Intrinsic::mips_subv_w: 02125 case Intrinsic::mips_subv_d: 02126 return DAG.getNode(ISD::SUB, DL, Op->getValueType(0), Op->getOperand(1), 02127 Op->getOperand(2)); 02128 case Intrinsic::mips_subvi_b: 02129 case Intrinsic::mips_subvi_h: 02130 case Intrinsic::mips_subvi_w: 02131 case Intrinsic::mips_subvi_d: 02132 return DAG.getNode(ISD::SUB, DL, Op->getValueType(0), 02133 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG)); 02134 case Intrinsic::mips_vshf_b: 02135 case Intrinsic::mips_vshf_h: 02136 case Intrinsic::mips_vshf_w: 02137 case Intrinsic::mips_vshf_d: 02138 return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0), 02139 Op->getOperand(1), Op->getOperand(2), Op->getOperand(3)); 02140 case Intrinsic::mips_xor_v: 02141 return DAG.getNode(ISD::XOR, DL, Op->getValueType(0), Op->getOperand(1), 02142 Op->getOperand(2)); 02143 case Intrinsic::mips_xori_b: 02144 return DAG.getNode(ISD::XOR, DL, Op->getValueType(0), 02145 Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG)); 02146 } 02147 } 02148 02149 static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) { 02150 SDLoc DL(Op); 02151 SDValue ChainIn = Op->getOperand(0); 02152 SDValue Address = Op->getOperand(2); 02153 SDValue Offset = Op->getOperand(3); 02154 EVT ResTy = Op->getValueType(0); 02155 EVT PtrTy = Address->getValueType(0); 02156 02157 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); 02158 02159 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false, 02160 false, false, 16); 02161 } 02162 02163 SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op, 02164 SelectionDAG &DAG) const { 02165 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue(); 02166 switch (Intr) { 02167 default: 02168 return SDValue(); 02169 case Intrinsic::mips_extp: 02170 return lowerDSPIntr(Op, DAG, MipsISD::EXTP); 02171 case Intrinsic::mips_extpdp: 02172 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP); 02173 case Intrinsic::mips_extr_w: 02174 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W); 02175 case Intrinsic::mips_extr_r_w: 02176 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W); 02177 case Intrinsic::mips_extr_rs_w: 02178 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W); 02179 case Intrinsic::mips_extr_s_h: 02180 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H); 02181 case Intrinsic::mips_mthlip: 02182 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP); 02183 case Intrinsic::mips_mulsaq_s_w_ph: 02184 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH); 02185 case Intrinsic::mips_maq_s_w_phl: 02186 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL); 02187 case Intrinsic::mips_maq_s_w_phr: 02188 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR); 02189 case Intrinsic::mips_maq_sa_w_phl: 02190 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL); 02191 case Intrinsic::mips_maq_sa_w_phr: 02192 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR); 02193 case Intrinsic::mips_dpaq_s_w_ph: 02194 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH); 02195 case Intrinsic::mips_dpsq_s_w_ph: 02196 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH); 02197 case Intrinsic::mips_dpaq_sa_l_w: 02198 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W); 02199 case Intrinsic::mips_dpsq_sa_l_w: 02200 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W); 02201 case Intrinsic::mips_dpaqx_s_w_ph: 02202 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH); 02203 case Intrinsic::mips_dpaqx_sa_w_ph: 02204 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH); 02205 case Intrinsic::mips_dpsqx_s_w_ph: 02206 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH); 02207 case Intrinsic::mips_dpsqx_sa_w_ph: 02208 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH); 02209 case Intrinsic::mips_ld_b: 02210 case Intrinsic::mips_ld_h: 02211 case Intrinsic::mips_ld_w: 02212 case Intrinsic::mips_ld_d: 02213 return lowerMSALoadIntr(Op, DAG, Intr); 02214 } 02215 } 02216 02217 static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) { 02218 SDLoc DL(Op); 02219 SDValue ChainIn = Op->getOperand(0); 02220 SDValue Value = Op->getOperand(2); 02221 SDValue Address = Op->getOperand(3); 02222 SDValue Offset = Op->getOperand(4); 02223 EVT PtrTy = Address->getValueType(0); 02224 02225 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); 02226 02227 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false, 02228 false, 16); 02229 } 02230 02231 SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op, 02232 SelectionDAG &DAG) const { 02233 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue(); 02234 switch (Intr) { 02235 default: 02236 return SDValue(); 02237 case Intrinsic::mips_st_b: 02238 case Intrinsic::mips_st_h: 02239 case Intrinsic::mips_st_w: 02240 case Intrinsic::mips_st_d: 02241 return lowerMSAStoreIntr(Op, DAG, Intr); 02242 } 02243 } 02244 02245 /// \brief Check if the given BuildVectorSDNode is a splat. 02246 /// This method currently relies on DAG nodes being reused when equivalent, 02247 /// so it's possible for this to return false even when isConstantSplat returns 02248 /// true. 02249 static bool isSplatVector(const BuildVectorSDNode *N) { 02250 unsigned int nOps = N->getNumOperands(); 02251 assert(nOps > 1 && "isSplatVector has 0 or 1 sized build vector"); 02252 02253 SDValue Operand0 = N->getOperand(0); 02254 02255 for (unsigned int i = 1; i < nOps; ++i) { 02256 if (N->getOperand(i) != Operand0) 02257 return false; 02258 } 02259 02260 return true; 02261 } 02262 02263 // Lower ISD::EXTRACT_VECTOR_ELT into MipsISD::VEXTRACT_SEXT_ELT. 02264 // 02265 // The non-value bits resulting from ISD::EXTRACT_VECTOR_ELT are undefined. We 02266 // choose to sign-extend but we could have equally chosen zero-extend. The 02267 // DAGCombiner will fold any sign/zero extension of the ISD::EXTRACT_VECTOR_ELT 02268 // result into this node later (possibly changing it to a zero-extend in the 02269 // process). 02270 SDValue MipsSETargetLowering:: 02271 lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const { 02272 SDLoc DL(Op); 02273 EVT ResTy = Op->getValueType(0); 02274 SDValue Op0 = Op->getOperand(0); 02275 EVT VecTy = Op0->getValueType(0); 02276 02277 if (!VecTy.is128BitVector()) 02278 return SDValue(); 02279 02280 if (ResTy.isInteger()) { 02281 SDValue Op1 = Op->getOperand(1); 02282 EVT EltTy = VecTy.getVectorElementType(); 02283 return DAG.getNode(MipsISD::VEXTRACT_SEXT_ELT, DL, ResTy, Op0, Op1, 02284 DAG.getValueType(EltTy)); 02285 } 02286 02287 return Op; 02288 } 02289 02290 static bool isConstantOrUndef(const SDValue Op) { 02291 if (Op->getOpcode() == ISD::UNDEF) 02292 return true; 02293 if (dyn_cast<ConstantSDNode>(Op)) 02294 return true; 02295 if (dyn_cast<ConstantFPSDNode>(Op)) 02296 return true; 02297 return false; 02298 } 02299 02300 static bool isConstantOrUndefBUILD_VECTOR(const BuildVectorSDNode *Op) { 02301 for (unsigned i = 0; i < Op->getNumOperands(); ++i) 02302 if (isConstantOrUndef(Op->getOperand(i))) 02303 return true; 02304 return false; 02305 } 02306 02307 // Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the 02308 // backend. 02309 // 02310 // Lowers according to the following rules: 02311 // - Constant splats are legal as-is as long as the SplatBitSize is a power of 02312 // 2 less than or equal to 64 and the value fits into a signed 10-bit 02313 // immediate 02314 // - Constant splats are lowered to bitconverted BUILD_VECTORs if SplatBitSize 02315 // is a power of 2 less than or equal to 64 and the value does not fit into a 02316 // signed 10-bit immediate 02317 // - Non-constant splats are legal as-is. 02318 // - Non-constant non-splats are lowered to sequences of INSERT_VECTOR_ELT. 02319 // - All others are illegal and must be expanded. 02320 SDValue MipsSETargetLowering::lowerBUILD_VECTOR(SDValue Op, 02321 SelectionDAG &DAG) const { 02322 BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Op); 02323 EVT ResTy = Op->getValueType(0); 02324 SDLoc DL(Op); 02325 APInt SplatValue, SplatUndef; 02326 unsigned SplatBitSize; 02327 bool HasAnyUndefs; 02328 02329 if (!Subtarget.hasMSA() || !ResTy.is128BitVector()) 02330 return SDValue(); 02331 02332 if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, 02333 HasAnyUndefs, 8, 02334 !Subtarget.isLittle()) && SplatBitSize <= 64) { 02335 // We can only cope with 8, 16, 32, or 64-bit elements 02336 if (SplatBitSize != 8 && SplatBitSize != 16 && SplatBitSize != 32 && 02337 SplatBitSize != 64) 02338 return SDValue(); 02339 02340 // If the value fits into a simm10 then we can use ldi.[bhwd] 02341 // However, if it isn't an integer type we will have to bitcast from an 02342 // integer type first. Also, if there are any undefs, we must lower them 02343 // to defined values first. 02344 if (ResTy.isInteger() && !HasAnyUndefs && SplatValue.isSignedIntN(10)) 02345 return Op; 02346 02347 EVT ViaVecTy; 02348 02349 switch (SplatBitSize) { 02350 default: 02351 return SDValue(); 02352 case 8: 02353 ViaVecTy = MVT::v16i8; 02354 break; 02355 case 16: 02356 ViaVecTy = MVT::v8i16; 02357 break; 02358 case 32: 02359 ViaVecTy = MVT::v4i32; 02360 break; 02361 case 64: 02362 // There's no fill.d to fall back on for 64-bit values 02363 return SDValue(); 02364 } 02365 02366 // SelectionDAG::getConstant will promote SplatValue appropriately. 02367 SDValue Result = DAG.getConstant(SplatValue, ViaVecTy); 02368 02369 // Bitcast to the type we originally wanted 02370 if (ViaVecTy != ResTy) 02371 Result = DAG.getNode(ISD::BITCAST, SDLoc(Node), ResTy, Result); 02372 02373 return Result; 02374 } else if (isSplatVector(Node)) 02375 return Op; 02376 else if (!isConstantOrUndefBUILD_VECTOR(Node)) { 02377 // Use INSERT_VECTOR_ELT operations rather than expand to stores. 02378 // The resulting code is the same length as the expansion, but it doesn't 02379 // use memory operations 02380 EVT ResTy = Node->getValueType(0); 02381 02382 assert(ResTy.isVector()); 02383 02384 unsigned NumElts = ResTy.getVectorNumElements(); 02385 SDValue Vector = DAG.getUNDEF(ResTy); 02386 for (unsigned i = 0; i < NumElts; ++i) { 02387 Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ResTy, Vector, 02388 Node->getOperand(i), 02389 DAG.getConstant(i, MVT::i32)); 02390 } 02391 return Vector; 02392 } 02393 02394 return SDValue(); 02395 } 02396 02397 // Lower VECTOR_SHUFFLE into SHF (if possible). 02398 // 02399 // SHF splits the vector into blocks of four elements, then shuffles these 02400 // elements according to a <4 x i2> constant (encoded as an integer immediate). 02401 // 02402 // It is therefore possible to lower into SHF when the mask takes the form: 02403 // <a, b, c, d, a+4, b+4, c+4, d+4, a+8, b+8, c+8, d+8, ...> 02404 // When undef's appear they are treated as if they were whatever value is 02405 // necessary in order to fit the above form. 02406 // 02407 // For example: 02408 // %2 = shufflevector <8 x i16> %0, <8 x i16> undef, 02409 // <8 x i32> <i32 3, i32 2, i32 1, i32 0, 02410 // i32 7, i32 6, i32 5, i32 4> 02411 // is lowered to: 02412 // (SHF_H $w0, $w1, 27) 02413 // where the 27 comes from: 02414 // 3 + (2 << 2) + (1 << 4) + (0 << 6) 02415 static SDValue lowerVECTOR_SHUFFLE_SHF(SDValue Op, EVT ResTy, 02416 SmallVector<int, 16> Indices, 02417 SelectionDAG &DAG) { 02418 int SHFIndices[4] = { -1, -1, -1, -1 }; 02419 02420 if (Indices.size() < 4) 02421 return SDValue(); 02422 02423 for (unsigned i = 0; i < 4; ++i) { 02424 for (unsigned j = i; j < Indices.size(); j += 4) { 02425 int Idx = Indices[j]; 02426 02427 // Convert from vector index to 4-element subvector index 02428 // If an index refers to an element outside of the subvector then give up 02429 if (Idx != -1) { 02430 Idx -= 4 * (j / 4); 02431 if (Idx < 0 || Idx >= 4) 02432 return SDValue(); 02433 } 02434 02435 // If the mask has an undef, replace it with the current index. 02436 // Note that it might still be undef if the current index is also undef 02437 if (SHFIndices[i] == -1) 02438 SHFIndices[i] = Idx; 02439 02440 // Check that non-undef values are the same as in the mask. If they 02441 // aren't then give up 02442 if (!(Idx == -1 || Idx == SHFIndices[i])) 02443 return SDValue(); 02444 } 02445 } 02446 02447 // Calculate the immediate. Replace any remaining undefs with zero 02448 APInt Imm(32, 0); 02449 for (int i = 3; i >= 0; --i) { 02450 int Idx = SHFIndices[i]; 02451 02452 if (Idx == -1) 02453 Idx = 0; 02454 02455 Imm <<= 2; 02456 Imm |= Idx & 0x3; 02457 } 02458 02459 return DAG.getNode(MipsISD::SHF, SDLoc(Op), ResTy, 02460 DAG.getConstant(Imm, MVT::i32), Op->getOperand(0)); 02461 } 02462 02463 // Lower VECTOR_SHUFFLE into ILVEV (if possible). 02464 // 02465 // ILVEV interleaves the even elements from each vector. 02466 // 02467 // It is possible to lower into ILVEV when the mask takes the form: 02468 // <0, n, 2, n+2, 4, n+4, ...> 02469 // where n is the number of elements in the vector. 02470 // 02471 // When undef's appear in the mask they are treated as if they were whatever 02472 // value is necessary in order to fit the above form. 02473 static SDValue lowerVECTOR_SHUFFLE_ILVEV(SDValue Op, EVT ResTy, 02474 SmallVector<int, 16> Indices, 02475 SelectionDAG &DAG) { 02476 assert ((Indices.size() % 2) == 0); 02477 int WsIdx = 0; 02478 int WtIdx = ResTy.getVectorNumElements(); 02479 02480 for (unsigned i = 0; i < Indices.size(); i += 2) { 02481 if (Indices[i] != -1 && Indices[i] != WsIdx) 02482 return SDValue(); 02483 if (Indices[i+1] != -1 && Indices[i+1] != WtIdx) 02484 return SDValue(); 02485 WsIdx += 2; 02486 WtIdx += 2; 02487 } 02488 02489 return DAG.getNode(MipsISD::ILVEV, SDLoc(Op), ResTy, Op->getOperand(0), 02490 Op->getOperand(1)); 02491 } 02492 02493 // Lower VECTOR_SHUFFLE into ILVOD (if possible). 02494 // 02495 // ILVOD interleaves the odd elements from each vector. 02496 // 02497 // It is possible to lower into ILVOD when the mask takes the form: 02498 // <1, n+1, 3, n+3, 5, n+5, ...> 02499 // where n is the number of elements in the vector. 02500 // 02501 // When undef's appear in the mask they are treated as if they were whatever 02502 // value is necessary in order to fit the above form. 02503 static SDValue lowerVECTOR_SHUFFLE_ILVOD(SDValue Op, EVT ResTy, 02504 SmallVector<int, 16> Indices, 02505 SelectionDAG &DAG) { 02506 assert ((Indices.size() % 2) == 0); 02507 int WsIdx = 1; 02508 int WtIdx = ResTy.getVectorNumElements() + 1; 02509 02510 for (unsigned i = 0; i < Indices.size(); i += 2) { 02511 if (Indices[i] != -1 && Indices[i] != WsIdx) 02512 return SDValue(); 02513 if (Indices[i+1] != -1 && Indices[i+1] != WtIdx) 02514 return SDValue(); 02515 WsIdx += 2; 02516 WtIdx += 2; 02517 } 02518 02519 return DAG.getNode(MipsISD::ILVOD, SDLoc(Op), ResTy, Op->getOperand(0), 02520 Op->getOperand(1)); 02521 } 02522 02523 // Lower VECTOR_SHUFFLE into ILVL (if possible). 02524 // 02525 // ILVL interleaves consecutive elements from the left half of each vector. 02526 // 02527 // It is possible to lower into ILVL when the mask takes the form: 02528 // <0, n, 1, n+1, 2, n+2, ...> 02529 // where n is the number of elements in the vector. 02530 // 02531 // When undef's appear in the mask they are treated as if they were whatever 02532 // value is necessary in order to fit the above form. 02533 static SDValue lowerVECTOR_SHUFFLE_ILVL(SDValue Op, EVT ResTy, 02534 SmallVector<int, 16> Indices, 02535 SelectionDAG &DAG) { 02536 assert ((Indices.size() % 2) == 0); 02537 int WsIdx = 0; 02538 int WtIdx = ResTy.getVectorNumElements(); 02539 02540 for (unsigned i = 0; i < Indices.size(); i += 2) { 02541 if (Indices[i] != -1 && Indices[i] != WsIdx) 02542 return SDValue(); 02543 if (Indices[i+1] != -1 && Indices[i+1] != WtIdx) 02544 return SDValue(); 02545 WsIdx ++; 02546 WtIdx ++; 02547 } 02548 02549 return DAG.getNode(MipsISD::ILVL, SDLoc(Op), ResTy, Op->getOperand(0), 02550 Op->getOperand(1)); 02551 } 02552 02553 // Lower VECTOR_SHUFFLE into ILVR (if possible). 02554 // 02555 // ILVR interleaves consecutive elements from the right half of each vector. 02556 // 02557 // It is possible to lower into ILVR when the mask takes the form: 02558 // <x, n+x, x+1, n+x+1, x+2, n+x+2, ...> 02559 // where n is the number of elements in the vector and x is half n. 02560 // 02561 // When undef's appear in the mask they are treated as if they were whatever 02562 // value is necessary in order to fit the above form. 02563 static SDValue lowerVECTOR_SHUFFLE_ILVR(SDValue Op, EVT ResTy, 02564 SmallVector<int, 16> Indices, 02565 SelectionDAG &DAG) { 02566 assert ((Indices.size() % 2) == 0); 02567 unsigned NumElts = ResTy.getVectorNumElements(); 02568 int WsIdx = NumElts / 2; 02569 int WtIdx = NumElts + NumElts / 2; 02570 02571 for (unsigned i = 0; i < Indices.size(); i += 2) { 02572 if (Indices[i] != -1 && Indices[i] != WsIdx) 02573 return SDValue(); 02574 if (Indices[i+1] != -1 && Indices[i+1] != WtIdx) 02575 return SDValue(); 02576 WsIdx ++; 02577 WtIdx ++; 02578 } 02579 02580 return DAG.getNode(MipsISD::ILVR, SDLoc(Op), ResTy, Op->getOperand(0), 02581 Op->getOperand(1)); 02582 } 02583 02584 // Lower VECTOR_SHUFFLE into PCKEV (if possible). 02585 // 02586 // PCKEV copies the even elements of each vector into the result vector. 02587 // 02588 // It is possible to lower into PCKEV when the mask takes the form: 02589 // <0, 2, 4, ..., n, n+2, n+4, ...> 02590 // where n is the number of elements in the vector. 02591 // 02592 // When undef's appear in the mask they are treated as if they were whatever 02593 // value is necessary in order to fit the above form. 02594 static SDValue lowerVECTOR_SHUFFLE_PCKEV(SDValue Op, EVT ResTy, 02595 SmallVector<int, 16> Indices, 02596 SelectionDAG &DAG) { 02597 assert ((Indices.size() % 2) == 0); 02598 int Idx = 0; 02599 02600 for (unsigned i = 0; i < Indices.size(); ++i) { 02601 if (Indices[i] != -1 && Indices[i] != Idx) 02602 return SDValue(); 02603 Idx += 2; 02604 } 02605 02606 return DAG.getNode(MipsISD::PCKEV, SDLoc(Op), ResTy, Op->getOperand(0), 02607 Op->getOperand(1)); 02608 } 02609 02610 // Lower VECTOR_SHUFFLE into PCKOD (if possible). 02611 // 02612 // PCKOD copies the odd elements of each vector into the result vector. 02613 // 02614 // It is possible to lower into PCKOD when the mask takes the form: 02615 // <1, 3, 5, ..., n+1, n+3, n+5, ...> 02616 // where n is the number of elements in the vector. 02617 // 02618 // When undef's appear in the mask they are treated as if they were whatever 02619 // value is necessary in order to fit the above form. 02620 static SDValue lowerVECTOR_SHUFFLE_PCKOD(SDValue Op, EVT ResTy, 02621 SmallVector<int, 16> Indices, 02622 SelectionDAG &DAG) { 02623 assert ((Indices.size() % 2) == 0); 02624 int Idx = 1; 02625 02626 for (unsigned i = 0; i < Indices.size(); ++i) { 02627 if (Indices[i] != -1 && Indices[i] != Idx) 02628 return SDValue(); 02629 Idx += 2; 02630 } 02631 02632 return DAG.getNode(MipsISD::PCKOD, SDLoc(Op), ResTy, Op->getOperand(0), 02633 Op->getOperand(1)); 02634 } 02635 02636 // Lower VECTOR_SHUFFLE into VSHF. 02637 // 02638 // This mostly consists of converting the shuffle indices in Indices into a 02639 // BUILD_VECTOR and adding it as an operand to the resulting VSHF. There is 02640 // also code to eliminate unused operands of the VECTOR_SHUFFLE. For example, 02641 // if the type is v8i16 and all the indices are less than 8 then the second 02642 // operand is unused and can be replaced with anything. We choose to replace it 02643 // with the used operand since this reduces the number of instructions overall. 02644 static SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy, 02645 SmallVector<int, 16> Indices, 02646 SelectionDAG &DAG) { 02647 SmallVector<SDValue, 16> Ops; 02648 SDValue Op0; 02649 SDValue Op1; 02650 EVT MaskVecTy = ResTy.changeVectorElementTypeToInteger(); 02651 EVT MaskEltTy = MaskVecTy.getVectorElementType(); 02652 bool Using1stVec = false; 02653 bool Using2ndVec = false; 02654 SDLoc DL(Op); 02655 int ResTyNumElts = ResTy.getVectorNumElements(); 02656 02657 for (int i = 0; i < ResTyNumElts; ++i) { 02658 // Idx == -1 means UNDEF 02659 int Idx = Indices[i]; 02660 02661 if (0 <= Idx && Idx < ResTyNumElts) 02662 Using1stVec = true; 02663 if (ResTyNumElts <= Idx && Idx < ResTyNumElts * 2) 02664 Using2ndVec = true; 02665 } 02666 02667 for (SmallVector<int, 16>::iterator I = Indices.begin(); I != Indices.end(); 02668 ++I) 02669 Ops.push_back(DAG.getTargetConstant(*I, MaskEltTy)); 02670 02671 SDValue MaskVec = DAG.getNode(ISD::BUILD_VECTOR, DL, MaskVecTy, Ops); 02672 02673 if (Using1stVec && Using2ndVec) { 02674 Op0 = Op->getOperand(0); 02675 Op1 = Op->getOperand(1); 02676 } else if (Using1stVec) 02677 Op0 = Op1 = Op->getOperand(0); 02678 else if (Using2ndVec) 02679 Op0 = Op1 = Op->getOperand(1); 02680 else 02681 llvm_unreachable("shuffle vector mask references neither vector operand?"); 02682 02683 // VECTOR_SHUFFLE concatenates the vectors in an vectorwise fashion. 02684 // <0b00, 0b01> + <0b10, 0b11> -> <0b00, 0b01, 0b10, 0b11> 02685 // VSHF concatenates the vectors in a bitwise fashion: 02686 // <0b00, 0b01> + <0b10, 0b11> -> 02687 // 0b0100 + 0b1110 -> 0b01001110 02688 // <0b10, 0b11, 0b00, 0b01> 02689 // We must therefore swap the operands to get the correct result. 02690 return DAG.getNode(MipsISD::VSHF, DL, ResTy, MaskVec, Op1, Op0); 02691 } 02692 02693 // Lower VECTOR_SHUFFLE into one of a number of instructions depending on the 02694 // indices in the shuffle. 02695 SDValue MipsSETargetLowering::lowerVECTOR_SHUFFLE(SDValue Op, 02696 SelectionDAG &DAG) const { 02697 ShuffleVectorSDNode *Node = cast<ShuffleVectorSDNode>(Op); 02698 EVT ResTy = Op->getValueType(0); 02699 02700 if (!ResTy.is128BitVector()) 02701 return SDValue(); 02702 02703 int ResTyNumElts = ResTy.getVectorNumElements(); 02704 SmallVector<int, 16> Indices; 02705 02706 for (int i = 0; i < ResTyNumElts; ++i) 02707 Indices.push_back(Node->getMaskElt(i)); 02708 02709 SDValue Result = lowerVECTOR_SHUFFLE_SHF(Op, ResTy, Indices, DAG); 02710 if (Result.getNode()) 02711 return Result; 02712 Result = lowerVECTOR_SHUFFLE_ILVEV(Op, ResTy, Indices, DAG); 02713 if (Result.getNode()) 02714 return Result; 02715 Result = lowerVECTOR_SHUFFLE_ILVOD(Op, ResTy, Indices, DAG); 02716 if (Result.getNode()) 02717 return Result; 02718 Result = lowerVECTOR_SHUFFLE_ILVL(Op, ResTy, Indices, DAG); 02719 if (Result.getNode()) 02720 return Result; 02721 Result = lowerVECTOR_SHUFFLE_ILVR(Op, ResTy, Indices, DAG); 02722 if (Result.getNode()) 02723 return Result; 02724 Result = lowerVECTOR_SHUFFLE_PCKEV(Op, ResTy, Indices, DAG); 02725 if (Result.getNode()) 02726 return Result; 02727 Result = lowerVECTOR_SHUFFLE_PCKOD(Op, ResTy, Indices, DAG); 02728 if (Result.getNode()) 02729 return Result; 02730 return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, DAG); 02731 } 02732 02733 MachineBasicBlock * MipsSETargetLowering:: 02734 emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ 02735 // $bb: 02736 // bposge32_pseudo $vr0 02737 // => 02738 // $bb: 02739 // bposge32 $tbb 02740 // $fbb: 02741 // li $vr2, 0 02742 // b $sink 02743 // $tbb: 02744 // li $vr1, 1 02745 // $sink: 02746 // $vr0 = phi($vr2, $fbb, $vr1, $tbb) 02747 02748 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 02749 const TargetInstrInfo *TII = 02750 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 02751 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 02752 DebugLoc DL = MI->getDebugLoc(); 02753 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 02754 MachineFunction::iterator It = std::next(MachineFunction::iterator(BB)); 02755 MachineFunction *F = BB->getParent(); 02756 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); 02757 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); 02758 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); 02759 F->insert(It, FBB); 02760 F->insert(It, TBB); 02761 F->insert(It, Sink); 02762 02763 // Transfer the remainder of BB and its successor edges to Sink. 02764 Sink->splice(Sink->begin(), BB, std::next(MachineBasicBlock::iterator(MI)), 02765 BB->end()); 02766 Sink->transferSuccessorsAndUpdatePHIs(BB); 02767 02768 // Add successors. 02769 BB->addSuccessor(FBB); 02770 BB->addSuccessor(TBB); 02771 FBB->addSuccessor(Sink); 02772 TBB->addSuccessor(Sink); 02773 02774 // Insert the real bposge32 instruction to $BB. 02775 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB); 02776 02777 // Fill $FBB. 02778 unsigned VR2 = RegInfo.createVirtualRegister(RC); 02779 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2) 02780 .addReg(Mips::ZERO).addImm(0); 02781 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); 02782 02783 // Fill $TBB. 02784 unsigned VR1 = RegInfo.createVirtualRegister(RC); 02785 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1) 02786 .addReg(Mips::ZERO).addImm(1); 02787 02788 // Insert phi function to $Sink. 02789 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), 02790 MI->getOperand(0).getReg()) 02791 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB); 02792 02793 MI->eraseFromParent(); // The pseudo instruction is gone now. 02794 return Sink; 02795 } 02796 02797 MachineBasicBlock * MipsSETargetLowering:: 02798 emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB, 02799 unsigned BranchOp) const{ 02800 // $bb: 02801 // vany_nonzero $rd, $ws 02802 // => 02803 // $bb: 02804 // bnz.b $ws, $tbb 02805 // b $fbb 02806 // $fbb: 02807 // li $rd1, 0 02808 // b $sink 02809 // $tbb: 02810 // li $rd2, 1 02811 // $sink: 02812 // $rd = phi($rd1, $fbb, $rd2, $tbb) 02813 02814 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 02815 const TargetInstrInfo *TII = 02816 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 02817 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 02818 DebugLoc DL = MI->getDebugLoc(); 02819 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 02820 MachineFunction::iterator It = std::next(MachineFunction::iterator(BB)); 02821 MachineFunction *F = BB->getParent(); 02822 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); 02823 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); 02824 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); 02825 F->insert(It, FBB); 02826 F->insert(It, TBB); 02827 F->insert(It, Sink); 02828 02829 // Transfer the remainder of BB and its successor edges to Sink. 02830 Sink->splice(Sink->begin(), BB, std::next(MachineBasicBlock::iterator(MI)), 02831 BB->end()); 02832 Sink->transferSuccessorsAndUpdatePHIs(BB); 02833 02834 // Add successors. 02835 BB->addSuccessor(FBB); 02836 BB->addSuccessor(TBB); 02837 FBB->addSuccessor(Sink); 02838 TBB->addSuccessor(Sink); 02839 02840 // Insert the real bnz.b instruction to $BB. 02841 BuildMI(BB, DL, TII->get(BranchOp)) 02842 .addReg(MI->getOperand(1).getReg()) 02843 .addMBB(TBB); 02844 02845 // Fill $FBB. 02846 unsigned RD1 = RegInfo.createVirtualRegister(RC); 02847 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1) 02848 .addReg(Mips::ZERO).addImm(0); 02849 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); 02850 02851 // Fill $TBB. 02852 unsigned RD2 = RegInfo.createVirtualRegister(RC); 02853 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2) 02854 .addReg(Mips::ZERO).addImm(1); 02855 02856 // Insert phi function to $Sink. 02857 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), 02858 MI->getOperand(0).getReg()) 02859 .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB); 02860 02861 MI->eraseFromParent(); // The pseudo instruction is gone now. 02862 return Sink; 02863 } 02864 02865 // Emit the COPY_FW pseudo instruction. 02866 // 02867 // copy_fw_pseudo $fd, $ws, n 02868 // => 02869 // copy_u_w $rt, $ws, $n 02870 // mtc1 $rt, $fd 02871 // 02872 // When n is zero, the equivalent operation can be performed with (potentially) 02873 // zero instructions due to register overlaps. This optimization is never valid 02874 // for lane 1 because it would require FR=0 mode which isn't supported by MSA. 02875 MachineBasicBlock * MipsSETargetLowering:: 02876 emitCOPY_FW(MachineInstr *MI, MachineBasicBlock *BB) const{ 02877 const TargetInstrInfo *TII = 02878 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 02879 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 02880 DebugLoc DL = MI->getDebugLoc(); 02881 unsigned Fd = MI->getOperand(0).getReg(); 02882 unsigned Ws = MI->getOperand(1).getReg(); 02883 unsigned Lane = MI->getOperand(2).getImm(); 02884 02885 if (Lane == 0) 02886 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Ws, 0, Mips::sub_lo); 02887 else { 02888 unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass); 02889 02890 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_W), Wt).addReg(Ws).addImm(Lane); 02891 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, 0, Mips::sub_lo); 02892 } 02893 02894 MI->eraseFromParent(); // The pseudo instruction is gone now. 02895 return BB; 02896 } 02897 02898 // Emit the COPY_FD pseudo instruction. 02899 // 02900 // copy_fd_pseudo $fd, $ws, n 02901 // => 02902 // splati.d $wt, $ws, $n 02903 // copy $fd, $wt:sub_64 02904 // 02905 // When n is zero, the equivalent operation can be performed with (potentially) 02906 // zero instructions due to register overlaps. This optimization is always 02907 // valid because FR=1 mode which is the only supported mode in MSA. 02908 MachineBasicBlock * MipsSETargetLowering:: 02909 emitCOPY_FD(MachineInstr *MI, MachineBasicBlock *BB) const{ 02910 assert(Subtarget.isFP64bit()); 02911 02912 const TargetInstrInfo *TII = 02913 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 02914 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 02915 unsigned Fd = MI->getOperand(0).getReg(); 02916 unsigned Ws = MI->getOperand(1).getReg(); 02917 unsigned Lane = MI->getOperand(2).getImm() * 2; 02918 DebugLoc DL = MI->getDebugLoc(); 02919 02920 if (Lane == 0) 02921 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Ws, 0, Mips::sub_64); 02922 else { 02923 unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass); 02924 02925 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_D), Wt).addReg(Ws).addImm(1); 02926 BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, 0, Mips::sub_64); 02927 } 02928 02929 MI->eraseFromParent(); // The pseudo instruction is gone now. 02930 return BB; 02931 } 02932 02933 // Emit the INSERT_FW pseudo instruction. 02934 // 02935 // insert_fw_pseudo $wd, $wd_in, $n, $fs 02936 // => 02937 // subreg_to_reg $wt:sub_lo, $fs 02938 // insve_w $wd[$n], $wd_in, $wt[0] 02939 MachineBasicBlock * 02940 MipsSETargetLowering::emitINSERT_FW(MachineInstr *MI, 02941 MachineBasicBlock *BB) const { 02942 const TargetInstrInfo *TII = 02943 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 02944 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 02945 DebugLoc DL = MI->getDebugLoc(); 02946 unsigned Wd = MI->getOperand(0).getReg(); 02947 unsigned Wd_in = MI->getOperand(1).getReg(); 02948 unsigned Lane = MI->getOperand(2).getImm(); 02949 unsigned Fs = MI->getOperand(3).getReg(); 02950 unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass); 02951 02952 BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt) 02953 .addImm(0) 02954 .addReg(Fs) 02955 .addImm(Mips::sub_lo); 02956 BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_W), Wd) 02957 .addReg(Wd_in) 02958 .addImm(Lane) 02959 .addReg(Wt) 02960 .addImm(0); 02961 02962 MI->eraseFromParent(); // The pseudo instruction is gone now. 02963 return BB; 02964 } 02965 02966 // Emit the INSERT_FD pseudo instruction. 02967 // 02968 // insert_fd_pseudo $wd, $fs, n 02969 // => 02970 // subreg_to_reg $wt:sub_64, $fs 02971 // insve_d $wd[$n], $wd_in, $wt[0] 02972 MachineBasicBlock * 02973 MipsSETargetLowering::emitINSERT_FD(MachineInstr *MI, 02974 MachineBasicBlock *BB) const { 02975 assert(Subtarget.isFP64bit()); 02976 02977 const TargetInstrInfo *TII = 02978 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 02979 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 02980 DebugLoc DL = MI->getDebugLoc(); 02981 unsigned Wd = MI->getOperand(0).getReg(); 02982 unsigned Wd_in = MI->getOperand(1).getReg(); 02983 unsigned Lane = MI->getOperand(2).getImm(); 02984 unsigned Fs = MI->getOperand(3).getReg(); 02985 unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass); 02986 02987 BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt) 02988 .addImm(0) 02989 .addReg(Fs) 02990 .addImm(Mips::sub_64); 02991 BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_D), Wd) 02992 .addReg(Wd_in) 02993 .addImm(Lane) 02994 .addReg(Wt) 02995 .addImm(0); 02996 02997 MI->eraseFromParent(); // The pseudo instruction is gone now. 02998 return BB; 02999 } 03000 03001 // Emit the INSERT_([BHWD]|F[WD])_VIDX pseudo instruction. 03002 // 03003 // For integer: 03004 // (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $rs) 03005 // => 03006 // (SLL $lanetmp1, $lane, <log2size) 03007 // (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1) 03008 // (INSERT_[BHWD], $wdtmp2, $wdtmp1, 0, $rs) 03009 // (NEG $lanetmp2, $lanetmp1) 03010 // (SLD_B $wd, $wdtmp2, $wdtmp2, $lanetmp2) 03011 // 03012 // For floating point: 03013 // (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $fs) 03014 // => 03015 // (SUBREG_TO_REG $wt, $fs, <subreg>) 03016 // (SLL $lanetmp1, $lane, <log2size) 03017 // (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1) 03018 // (INSVE_[WD], $wdtmp2, 0, $wdtmp1, 0) 03019 // (NEG $lanetmp2, $lanetmp1) 03020 // (SLD_B $wd, $wdtmp2, $wdtmp2, $lanetmp2) 03021 MachineBasicBlock * 03022 MipsSETargetLowering::emitINSERT_DF_VIDX(MachineInstr *MI, 03023 MachineBasicBlock *BB, 03024 unsigned EltSizeInBytes, 03025 bool IsFP) const { 03026 const TargetInstrInfo *TII = 03027 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 03028 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 03029 DebugLoc DL = MI->getDebugLoc(); 03030 unsigned Wd = MI->getOperand(0).getReg(); 03031 unsigned SrcVecReg = MI->getOperand(1).getReg(); 03032 unsigned LaneReg = MI->getOperand(2).getReg(); 03033 unsigned SrcValReg = MI->getOperand(3).getReg(); 03034 03035 const TargetRegisterClass *VecRC = nullptr; 03036 const TargetRegisterClass *GPRRC = 03037 Subtarget.isGP64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass; 03038 unsigned EltLog2Size; 03039 unsigned InsertOp = 0; 03040 unsigned InsveOp = 0; 03041 switch (EltSizeInBytes) { 03042 default: 03043 llvm_unreachable("Unexpected size"); 03044 case 1: 03045 EltLog2Size = 0; 03046 InsertOp = Mips::INSERT_B; 03047 InsveOp = Mips::INSVE_B; 03048 VecRC = &Mips::MSA128BRegClass; 03049 break; 03050 case 2: 03051 EltLog2Size = 1; 03052 InsertOp = Mips::INSERT_H; 03053 InsveOp = Mips::INSVE_H; 03054 VecRC = &Mips::MSA128HRegClass; 03055 break; 03056 case 4: 03057 EltLog2Size = 2; 03058 InsertOp = Mips::INSERT_W; 03059 InsveOp = Mips::INSVE_W; 03060 VecRC = &Mips::MSA128WRegClass; 03061 break; 03062 case 8: 03063 EltLog2Size = 3; 03064 InsertOp = Mips::INSERT_D; 03065 InsveOp = Mips::INSVE_D; 03066 VecRC = &Mips::MSA128DRegClass; 03067 break; 03068 } 03069 03070 if (IsFP) { 03071 unsigned Wt = RegInfo.createVirtualRegister(VecRC); 03072 BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt) 03073 .addImm(0) 03074 .addReg(SrcValReg) 03075 .addImm(EltSizeInBytes == 8 ? Mips::sub_64 : Mips::sub_lo); 03076 SrcValReg = Wt; 03077 } 03078 03079 // Convert the lane index into a byte index 03080 if (EltSizeInBytes != 1) { 03081 unsigned LaneTmp1 = RegInfo.createVirtualRegister(GPRRC); 03082 BuildMI(*BB, MI, DL, TII->get(Mips::SLL), LaneTmp1) 03083 .addReg(LaneReg) 03084 .addImm(EltLog2Size); 03085 LaneReg = LaneTmp1; 03086 } 03087 03088 // Rotate bytes around so that the desired lane is element zero 03089 unsigned WdTmp1 = RegInfo.createVirtualRegister(VecRC); 03090 BuildMI(*BB, MI, DL, TII->get(Mips::SLD_B), WdTmp1) 03091 .addReg(SrcVecReg) 03092 .addReg(SrcVecReg) 03093 .addReg(LaneReg); 03094 03095 unsigned WdTmp2 = RegInfo.createVirtualRegister(VecRC); 03096 if (IsFP) { 03097 // Use insve.df to insert to element zero 03098 BuildMI(*BB, MI, DL, TII->get(InsveOp), WdTmp2) 03099 .addReg(WdTmp1) 03100 .addImm(0) 03101 .addReg(SrcValReg) 03102 .addImm(0); 03103 } else { 03104 // Use insert.df to insert to element zero 03105 BuildMI(*BB, MI, DL, TII->get(InsertOp), WdTmp2) 03106 .addReg(WdTmp1) 03107 .addReg(SrcValReg) 03108 .addImm(0); 03109 } 03110 03111 // Rotate elements the rest of the way for a full rotation. 03112 // sld.df inteprets $rt modulo the number of columns so we only need to negate 03113 // the lane index to do this. 03114 unsigned LaneTmp2 = RegInfo.createVirtualRegister(GPRRC); 03115 BuildMI(*BB, MI, DL, TII->get(Mips::SUB), LaneTmp2) 03116 .addReg(Mips::ZERO) 03117 .addReg(LaneReg); 03118 BuildMI(*BB, MI, DL, TII->get(Mips::SLD_B), Wd) 03119 .addReg(WdTmp2) 03120 .addReg(WdTmp2) 03121 .addReg(LaneTmp2); 03122 03123 MI->eraseFromParent(); // The pseudo instruction is gone now. 03124 return BB; 03125 } 03126 03127 // Emit the FILL_FW pseudo instruction. 03128 // 03129 // fill_fw_pseudo $wd, $fs 03130 // => 03131 // implicit_def $wt1 03132 // insert_subreg $wt2:subreg_lo, $wt1, $fs 03133 // splati.w $wd, $wt2[0] 03134 MachineBasicBlock * 03135 MipsSETargetLowering::emitFILL_FW(MachineInstr *MI, 03136 MachineBasicBlock *BB) const { 03137 const TargetInstrInfo *TII = 03138 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 03139 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 03140 DebugLoc DL = MI->getDebugLoc(); 03141 unsigned Wd = MI->getOperand(0).getReg(); 03142 unsigned Fs = MI->getOperand(1).getReg(); 03143 unsigned Wt1 = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass); 03144 unsigned Wt2 = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass); 03145 03146 BuildMI(*BB, MI, DL, TII->get(Mips::IMPLICIT_DEF), Wt1); 03147 BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_SUBREG), Wt2) 03148 .addReg(Wt1) 03149 .addReg(Fs) 03150 .addImm(Mips::sub_lo); 03151 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_W), Wd).addReg(Wt2).addImm(0); 03152 03153 MI->eraseFromParent(); // The pseudo instruction is gone now. 03154 return BB; 03155 } 03156 03157 // Emit the FILL_FD pseudo instruction. 03158 // 03159 // fill_fd_pseudo $wd, $fs 03160 // => 03161 // implicit_def $wt1 03162 // insert_subreg $wt2:subreg_64, $wt1, $fs 03163 // splati.d $wd, $wt2[0] 03164 MachineBasicBlock * 03165 MipsSETargetLowering::emitFILL_FD(MachineInstr *MI, 03166 MachineBasicBlock *BB) const { 03167 assert(Subtarget.isFP64bit()); 03168 03169 const TargetInstrInfo *TII = 03170 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 03171 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 03172 DebugLoc DL = MI->getDebugLoc(); 03173 unsigned Wd = MI->getOperand(0).getReg(); 03174 unsigned Fs = MI->getOperand(1).getReg(); 03175 unsigned Wt1 = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass); 03176 unsigned Wt2 = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass); 03177 03178 BuildMI(*BB, MI, DL, TII->get(Mips::IMPLICIT_DEF), Wt1); 03179 BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_SUBREG), Wt2) 03180 .addReg(Wt1) 03181 .addReg(Fs) 03182 .addImm(Mips::sub_64); 03183 BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_D), Wd).addReg(Wt2).addImm(0); 03184 03185 MI->eraseFromParent(); // The pseudo instruction is gone now. 03186 return BB; 03187 } 03188 03189 // Emit the FEXP2_W_1 pseudo instructions. 03190 // 03191 // fexp2_w_1_pseudo $wd, $wt 03192 // => 03193 // ldi.w $ws, 1 03194 // fexp2.w $wd, $ws, $wt 03195 MachineBasicBlock * 03196 MipsSETargetLowering::emitFEXP2_W_1(MachineInstr *MI, 03197 MachineBasicBlock *BB) const { 03198 const TargetInstrInfo *TII = 03199 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 03200 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 03201 const TargetRegisterClass *RC = &Mips::MSA128WRegClass; 03202 unsigned Ws1 = RegInfo.createVirtualRegister(RC); 03203 unsigned Ws2 = RegInfo.createVirtualRegister(RC); 03204 DebugLoc DL = MI->getDebugLoc(); 03205 03206 // Splat 1.0 into a vector 03207 BuildMI(*BB, MI, DL, TII->get(Mips::LDI_W), Ws1).addImm(1); 03208 BuildMI(*BB, MI, DL, TII->get(Mips::FFINT_U_W), Ws2).addReg(Ws1); 03209 03210 // Emit 1.0 * fexp2(Wt) 03211 BuildMI(*BB, MI, DL, TII->get(Mips::FEXP2_W), MI->getOperand(0).getReg()) 03212 .addReg(Ws2) 03213 .addReg(MI->getOperand(1).getReg()); 03214 03215 MI->eraseFromParent(); // The pseudo instruction is gone now. 03216 return BB; 03217 } 03218 03219 // Emit the FEXP2_D_1 pseudo instructions. 03220 // 03221 // fexp2_d_1_pseudo $wd, $wt 03222 // => 03223 // ldi.d $ws, 1 03224 // fexp2.d $wd, $ws, $wt 03225 MachineBasicBlock * 03226 MipsSETargetLowering::emitFEXP2_D_1(MachineInstr *MI, 03227 MachineBasicBlock *BB) const { 03228 const TargetInstrInfo *TII = 03229 getTargetMachine().getSubtargetImpl()->getInstrInfo(); 03230 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 03231 const TargetRegisterClass *RC = &Mips::MSA128DRegClass; 03232 unsigned Ws1 = RegInfo.createVirtualRegister(RC); 03233 unsigned Ws2 = RegInfo.createVirtualRegister(RC); 03234 DebugLoc DL = MI->getDebugLoc(); 03235 03236 // Splat 1.0 into a vector 03237 BuildMI(*BB, MI, DL, TII->get(Mips::LDI_D), Ws1).addImm(1); 03238 BuildMI(*BB, MI, DL, TII->get(Mips::FFINT_U_D), Ws2).addReg(Ws1); 03239 03240 // Emit 1.0 * fexp2(Wt) 03241 BuildMI(*BB, MI, DL, TII->get(Mips::FEXP2_D), MI->getOperand(0).getReg()) 03242 .addReg(Ws2) 03243 .addReg(MI->getOperand(1).getReg()); 03244 03245 MI->eraseFromParent(); // The pseudo instruction is gone now. 03246 return BB; 03247 }