1 //===-- MipsastISel.cpp - Mips FastISel implementation 2 //---------------------===// 3 4 #include "llvm/CodeGen/FunctionLoweringInfo.h" 5 #include "llvm/CodeGen/FastISel.h" 6 #include "llvm/CodeGen/MachineInstrBuilder.h" 7 #include "llvm/IR/GlobalAlias.h" 8 #include "llvm/IR/GlobalVariable.h" 9 #include "llvm/Target/TargetInstrInfo.h" 10 #include "llvm/Target/TargetLibraryInfo.h" 11 #include "MipsRegisterInfo.h" 12 #include "MipsISelLowering.h" 13 #include "MipsMachineFunction.h" 14 #include "MipsSubtarget.h" 15 #include "MipsTargetMachine.h" 16 17 using namespace llvm; 18 19 namespace { 20 21 class MipsFastISel final : public FastISel { 22 23 // All possible address modes. 24 class Address { 25 public: 26 typedef enum { RegBase, FrameIndexBase } BaseKind; 27 28 private: 29 BaseKind Kind; 30 union { 31 unsigned Reg; 32 int FI; 33 } Base; 34 35 int64_t Offset; 36 37 const GlobalValue *GV; 38 39 public: 40 // Innocuous defaults for our address. 41 Address() : Kind(RegBase), Offset(0), GV(0) { Base.Reg = 0; } 42 void setKind(BaseKind K) { Kind = K; } 43 BaseKind getKind() const { return Kind; } 44 bool isRegBase() const { return Kind == RegBase; } 45 void setReg(unsigned Reg) { 46 assert(isRegBase() && "Invalid base register access!"); 47 Base.Reg = Reg; 48 } 49 unsigned getReg() const { 50 assert(isRegBase() && "Invalid base register access!"); 51 return Base.Reg; 52 } 53 void setOffset(int64_t Offset_) { Offset = Offset_; } 54 int64_t getOffset() const { return Offset; } 55 void setGlobalValue(const GlobalValue *G) { GV = G; } 56 const GlobalValue *getGlobalValue() { return GV; } 57 }; 58 59 /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can 60 /// make the right decision when generating code for different targets. 61 Module &M; 62 const TargetMachine &TM; 63 const TargetInstrInfo &TII; 64 const TargetLowering &TLI; 65 const MipsSubtarget *Subtarget; 66 MipsFunctionInfo *MFI; 67 68 // Convenience variables to avoid some queries. 69 LLVMContext *Context; 70 71 bool TargetSupported; 72 bool UnsupportedFPMode; // To allow fast-isel to proceed and just not handle 73 // floating point but not reject doing fast-isel in other 74 // situations 75 76 private: 77 // Selection routines. 78 bool selectLoad(const Instruction *I); 79 bool selectStore(const Instruction *I); 80 bool selectBranch(const Instruction *I); 81 bool selectCmp(const Instruction *I); 82 bool selectFPExt(const Instruction *I); 83 bool selectFPTrunc(const Instruction *I); 84 bool selectFPToInt(const Instruction *I, bool IsSigned); 85 bool selectRet(const Instruction *I); 86 bool selectTrunc(const Instruction *I); 87 bool selectIntExt(const Instruction *I); 88 89 // Utility helper routines. 90 91 bool isTypeLegal(Type *Ty, MVT &VT); 92 bool isLoadTypeLegal(Type *Ty, MVT &VT); 93 bool computeAddress(const Value *Obj, Address &Addr); 94 95 // Emit helper routines. 96 bool emitCmp(unsigned DestReg, const CmpInst *CI); 97 bool emitLoad(MVT VT, unsigned &ResultReg, Address &Addr, 98 unsigned Alignment = 0); 99 bool emitStore(MVT VT, unsigned SrcReg, Address &Addr, 100 unsigned Alignment = 0); 101 bool emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg, 102 103 bool IsZExt); 104 bool emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg); 105 106 bool emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg); 107 bool emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT, 108 unsigned DestReg); 109 bool emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT, 110 unsigned DestReg); 111 112 unsigned getRegEnsuringSimpleIntegerWidening(const Value *, bool IsUnsigned); 113 114 unsigned materializeFP(const ConstantFP *CFP, MVT VT); 115 unsigned materializeGV(const GlobalValue *GV, MVT VT); 116 unsigned materializeInt(const Constant *C, MVT VT); 117 unsigned materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC); 118 119 MachineInstrBuilder emitInst(unsigned Opc) { 120 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)); 121 } 122 MachineInstrBuilder emitInst(unsigned Opc, unsigned DstReg) { 123 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), 124 DstReg); 125 } 126 MachineInstrBuilder emitInstStore(unsigned Opc, unsigned SrcReg, 127 unsigned MemReg, int64_t MemOffset) { 128 return emitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset); 129 } 130 MachineInstrBuilder emitInstLoad(unsigned Opc, unsigned DstReg, 131 unsigned MemReg, int64_t MemOffset) { 132 return emitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset); 133 } 134 // for some reason, this default is not generated by tablegen 135 // so we explicitly generate it here. 136 // 137 unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC, 138 unsigned Op0, bool Op0IsKill, uint64_t imm1, 139 uint64_t imm2, unsigned Op3, bool Op3IsKill) { 140 return 0; 141 } 142 143 public: 144 // Backend specific FastISel code. 145 146 explicit MipsFastISel(FunctionLoweringInfo &funcInfo, 147 const TargetLibraryInfo *libInfo) 148 : FastISel(funcInfo, libInfo), 149 M(const_cast<Module &>(*funcInfo.Fn->getParent())), 150 TM(funcInfo.MF->getTarget()), 151 TII(*TM.getSubtargetImpl()->getInstrInfo()), 152 TLI(*TM.getSubtargetImpl()->getTargetLowering()), 153 Subtarget(&TM.getSubtarget<MipsSubtarget>()) { 154 MFI = funcInfo.MF->getInfo<MipsFunctionInfo>(); 155 Context = &funcInfo.Fn->getContext(); 156 TargetSupported = ((Subtarget->getRelocationModel() == Reloc::PIC_) && 157 ((Subtarget->hasMips32r2() || Subtarget->hasMips32()) && 158 (Subtarget->isABI_O32()))); 159 UnsupportedFPMode = Subtarget->isFP64bit(); 160 } 161 162 unsigned fastMaterializeConstant(const Constant *C) override; 163 bool fastSelectInstruction(const Instruction *I) override; 164 165 #include "MipsGenFastISel.inc" 166 }; 167 } // end anonymous namespace. 168 169 unsigned MipsFastISel::materializeInt(const Constant *C, MVT VT) { 170 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1) 171 return 0; 172 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 173 const ConstantInt *CI = cast<ConstantInt>(C); 174 int64_t Imm; 175 if ((VT != MVT::i1) && CI->isNegative()) 176 Imm = CI->getSExtValue(); 177 else 178 Imm = CI->getZExtValue(); 179 return materialize32BitInt(Imm, RC); 180 } 181 182 unsigned MipsFastISel::materialize32BitInt(int64_t Imm, 183 const TargetRegisterClass *RC) { 184 unsigned ResultReg = createResultReg(RC); 185 186 if (isInt<16>(Imm)) { 187 unsigned Opc = Mips::ADDiu; 188 emitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm); 189 return ResultReg; 190 } else if (isUInt<16>(Imm)) { 191 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm); 192 return ResultReg; 193 } 194 unsigned Lo = Imm & 0xFFFF; 195 unsigned Hi = (Imm >> 16) & 0xFFFF; 196 if (Lo) { 197 // Both Lo and Hi have nonzero bits. 198 unsigned TmpReg = createResultReg(RC); 199 emitInst(Mips::LUi, TmpReg).addImm(Hi); 200 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo); 201 } else { 202 emitInst(Mips::LUi, ResultReg).addImm(Hi); 203 } 204 return ResultReg; 205 } 206 207 unsigned MipsFastISel::materializeFP(const ConstantFP *CFP, MVT VT) { 208 if (UnsupportedFPMode) 209 return 0; 210 int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); 211 if (VT == MVT::f32) { 212 const TargetRegisterClass *RC = &Mips::FGR32RegClass; 213 unsigned DestReg = createResultReg(RC); 214 unsigned TempReg = materialize32BitInt(Imm, &Mips::GPR32RegClass); 215 emitInst(Mips::MTC1, DestReg).addReg(TempReg); 216 return DestReg; 217 } else if (VT == MVT::f64) { 218 const TargetRegisterClass *RC = &Mips::AFGR64RegClass; 219 unsigned DestReg = createResultReg(RC); 220 unsigned TempReg1 = materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass); 221 unsigned TempReg2 = 222 materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass); 223 emitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1); 224 return DestReg; 225 } 226 return 0; 227 } 228 229 unsigned MipsFastISel::materializeGV(const GlobalValue *GV, MVT VT) { 230 // For now 32-bit only. 231 if (VT != MVT::i32) 232 return 0; 233 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 234 unsigned DestReg = createResultReg(RC); 235 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); 236 bool IsThreadLocal = GVar && GVar->isThreadLocal(); 237 // TLS not supported at this time. 238 if (IsThreadLocal) 239 return 0; 240 emitInst(Mips::LW, DestReg) 241 .addReg(MFI->getGlobalBaseReg()) 242 .addGlobalAddress(GV, 0, MipsII::MO_GOT); 243 if ((GV->hasInternalLinkage() || 244 (GV->hasLocalLinkage() && !isa<Function>(GV)))) { 245 unsigned TempReg = createResultReg(RC); 246 emitInst(Mips::ADDiu, TempReg) 247 .addReg(DestReg) 248 .addGlobalAddress(GV, 0, MipsII::MO_ABS_LO); 249 DestReg = TempReg; 250 } 251 return DestReg; 252 } 253 254 // Materialize a constant into a register, and return the register 255 // number (or zero if we failed to handle it). 256 unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) { 257 EVT CEVT = TLI.getValueType(C->getType(), true); 258 259 // Only handle simple types. 260 if (!CEVT.isSimple()) 261 return 0; 262 MVT VT = CEVT.getSimpleVT(); 263 264 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) 265 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT); 266 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) 267 return materializeGV(GV, VT); 268 else if (isa<ConstantInt>(C)) 269 return materializeInt(C, VT); 270 271 return 0; 272 } 273 274 bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) { 275 // This construct looks a big awkward but it is how other ports handle this 276 // and as this function is more fully completed, these cases which 277 // return false will have additional code in them. 278 // 279 if (isa<Instruction>(Obj)) 280 return false; 281 else if (isa<ConstantExpr>(Obj)) 282 return false; 283 Addr.setReg(getRegForValue(Obj)); 284 return Addr.getReg() != 0; 285 } 286 287 bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) { 288 EVT evt = TLI.getValueType(Ty, true); 289 // Only handle simple types. 290 if (evt == MVT::Other || !evt.isSimple()) 291 return false; 292 VT = evt.getSimpleVT(); 293 294 // Handle all legal types, i.e. a register that will directly hold this 295 // value. 296 return TLI.isTypeLegal(VT); 297 } 298 299 bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) { 300 if (isTypeLegal(Ty, VT)) 301 return true; 302 // We will extend this in a later patch: 303 // If this is a type than can be sign or zero-extended to a basic operation 304 // go ahead and accept it now. 305 if (VT == MVT::i8 || VT == MVT::i16) 306 return true; 307 return false; 308 } 309 // Because of how EmitCmp is called with fast-isel, you can 310 // end up with redundant "andi" instructions after the sequences emitted below. 311 // We should try and solve this issue in the future. 312 // 313 bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) { 314 const Value *Left = CI->getOperand(0), *Right = CI->getOperand(1); 315 bool IsUnsigned = CI->isUnsigned(); 316 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned); 317 if (LeftReg == 0) 318 return false; 319 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(Right, IsUnsigned); 320 if (RightReg == 0) 321 return false; 322 CmpInst::Predicate P = CI->getPredicate(); 323 324 switch (P) { 325 default: 326 return false; 327 case CmpInst::ICMP_EQ: { 328 unsigned TempReg = createResultReg(&Mips::GPR32RegClass); 329 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg); 330 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1); 331 break; 332 } 333 case CmpInst::ICMP_NE: { 334 unsigned TempReg = createResultReg(&Mips::GPR32RegClass); 335 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg); 336 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg); 337 break; 338 } 339 case CmpInst::ICMP_UGT: { 340 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg); 341 break; 342 } 343 case CmpInst::ICMP_ULT: { 344 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg); 345 break; 346 } 347 case CmpInst::ICMP_UGE: { 348 unsigned TempReg = createResultReg(&Mips::GPR32RegClass); 349 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg); 350 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1); 351 break; 352 } 353 case CmpInst::ICMP_ULE: { 354 unsigned TempReg = createResultReg(&Mips::GPR32RegClass); 355 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg); 356 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1); 357 break; 358 } 359 case CmpInst::ICMP_SGT: { 360 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg); 361 break; 362 } 363 case CmpInst::ICMP_SLT: { 364 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg); 365 break; 366 } 367 case CmpInst::ICMP_SGE: { 368 unsigned TempReg = createResultReg(&Mips::GPR32RegClass); 369 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg); 370 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1); 371 break; 372 } 373 case CmpInst::ICMP_SLE: { 374 unsigned TempReg = createResultReg(&Mips::GPR32RegClass); 375 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg); 376 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1); 377 break; 378 } 379 case CmpInst::FCMP_OEQ: 380 case CmpInst::FCMP_UNE: 381 case CmpInst::FCMP_OLT: 382 case CmpInst::FCMP_OLE: 383 case CmpInst::FCMP_OGT: 384 case CmpInst::FCMP_OGE: { 385 if (UnsupportedFPMode) 386 return false; 387 bool IsFloat = Left->getType()->isFloatTy(); 388 bool IsDouble = Left->getType()->isDoubleTy(); 389 if (!IsFloat && !IsDouble) 390 return false; 391 unsigned Opc, CondMovOpc; 392 switch (P) { 393 case CmpInst::FCMP_OEQ: 394 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32; 395 CondMovOpc = Mips::MOVT_I; 396 break; 397 case CmpInst::FCMP_UNE: 398 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32; 399 CondMovOpc = Mips::MOVF_I; 400 break; 401 case CmpInst::FCMP_OLT: 402 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32; 403 CondMovOpc = Mips::MOVT_I; 404 break; 405 case CmpInst::FCMP_OLE: 406 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32; 407 CondMovOpc = Mips::MOVT_I; 408 break; 409 case CmpInst::FCMP_OGT: 410 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32; 411 CondMovOpc = Mips::MOVF_I; 412 break; 413 case CmpInst::FCMP_OGE: 414 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32; 415 CondMovOpc = Mips::MOVF_I; 416 break; 417 default: 418 llvm_unreachable("Only switching of a subset of CCs."); 419 } 420 unsigned RegWithZero = createResultReg(&Mips::GPR32RegClass); 421 unsigned RegWithOne = createResultReg(&Mips::GPR32RegClass); 422 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0); 423 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1); 424 emitInst(Opc).addReg(LeftReg).addReg(RightReg).addReg( 425 Mips::FCC0, RegState::ImplicitDefine); 426 MachineInstrBuilder MI = emitInst(CondMovOpc, ResultReg) 427 .addReg(RegWithOne) 428 .addReg(Mips::FCC0) 429 .addReg(RegWithZero, RegState::Implicit); 430 MI->tieOperands(0, 3); 431 break; 432 } 433 } 434 return true; 435 } 436 bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr, 437 unsigned Alignment) { 438 // 439 // more cases will be handled here in following patches. 440 // 441 unsigned Opc; 442 switch (VT.SimpleTy) { 443 case MVT::i32: { 444 ResultReg = createResultReg(&Mips::GPR32RegClass); 445 Opc = Mips::LW; 446 break; 447 } 448 case MVT::i16: { 449 ResultReg = createResultReg(&Mips::GPR32RegClass); 450 Opc = Mips::LHu; 451 break; 452 } 453 case MVT::i8: { 454 ResultReg = createResultReg(&Mips::GPR32RegClass); 455 Opc = Mips::LBu; 456 break; 457 } 458 case MVT::f32: { 459 if (UnsupportedFPMode) 460 return false; 461 ResultReg = createResultReg(&Mips::FGR32RegClass); 462 Opc = Mips::LWC1; 463 break; 464 } 465 case MVT::f64: { 466 if (UnsupportedFPMode) 467 return false; 468 ResultReg = createResultReg(&Mips::AFGR64RegClass); 469 Opc = Mips::LDC1; 470 break; 471 } 472 default: 473 return false; 474 } 475 emitInstLoad(Opc, ResultReg, Addr.getReg(), Addr.getOffset()); 476 return true; 477 } 478 479 bool MipsFastISel::emitStore(MVT VT, unsigned SrcReg, Address &Addr, 480 unsigned Alignment) { 481 // 482 // more cases will be handled here in following patches. 483 // 484 unsigned Opc; 485 switch (VT.SimpleTy) { 486 case MVT::i8: 487 Opc = Mips::SB; 488 break; 489 case MVT::i16: 490 Opc = Mips::SH; 491 break; 492 case MVT::i32: 493 Opc = Mips::SW; 494 break; 495 case MVT::f32: 496 if (UnsupportedFPMode) 497 return false; 498 Opc = Mips::SWC1; 499 break; 500 case MVT::f64: 501 if (UnsupportedFPMode) 502 return false; 503 Opc = Mips::SDC1; 504 break; 505 default: 506 return false; 507 } 508 emitInstStore(Opc, SrcReg, Addr.getReg(), Addr.getOffset()); 509 return true; 510 } 511 512 bool MipsFastISel::selectLoad(const Instruction *I) { 513 // Atomic loads need special handling. 514 if (cast<LoadInst>(I)->isAtomic()) 515 return false; 516 517 // Verify we have a legal type before going any further. 518 MVT VT; 519 if (!isLoadTypeLegal(I->getType(), VT)) 520 return false; 521 522 // See if we can handle this address. 523 Address Addr; 524 if (!computeAddress(I->getOperand(0), Addr)) 525 return false; 526 527 unsigned ResultReg; 528 if (!emitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment())) 529 return false; 530 updateValueMap(I, ResultReg); 531 return true; 532 } 533 534 bool MipsFastISel::selectStore(const Instruction *I) { 535 Value *Op0 = I->getOperand(0); 536 unsigned SrcReg = 0; 537 538 // Atomic stores need special handling. 539 if (cast<StoreInst>(I)->isAtomic()) 540 return false; 541 542 // Verify we have a legal type before going any further. 543 MVT VT; 544 if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT)) 545 return false; 546 547 // Get the value to be stored into a register. 548 SrcReg = getRegForValue(Op0); 549 if (SrcReg == 0) 550 return false; 551 552 // See if we can handle this address. 553 Address Addr; 554 if (!computeAddress(I->getOperand(1), Addr)) 555 return false; 556 557 if (!emitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment())) 558 return false; 559 return true; 560 } 561 562 // 563 // This can cause a redundant sltiu to be generated. 564 // FIXME: try and eliminate this in a future patch. 565 // 566 bool MipsFastISel::selectBranch(const Instruction *I) { 567 const BranchInst *BI = cast<BranchInst>(I); 568 MachineBasicBlock *BrBB = FuncInfo.MBB; 569 // 570 // TBB is the basic block for the case where the comparison is true. 571 // FBB is the basic block for the case where the comparison is false. 572 // if (cond) goto TBB 573 // goto FBB 574 // TBB: 575 // 576 MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)]; 577 MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)]; 578 BI->getCondition(); 579 // For now, just try the simplest case where it's fed by a compare. 580 if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) { 581 unsigned CondReg = createResultReg(&Mips::GPR32RegClass); 582 if (!emitCmp(CondReg, CI)) 583 return false; 584 BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::BGTZ)) 585 .addReg(CondReg) 586 .addMBB(TBB); 587 fastEmitBranch(FBB, DbgLoc); 588 FuncInfo.MBB->addSuccessor(TBB); 589 return true; 590 } 591 return false; 592 } 593 594 bool MipsFastISel::selectCmp(const Instruction *I) { 595 const CmpInst *CI = cast<CmpInst>(I); 596 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass); 597 if (!emitCmp(ResultReg, CI)) 598 return false; 599 updateValueMap(I, ResultReg); 600 return true; 601 } 602 603 // Attempt to fast-select a floating-point extend instruction. 604 bool MipsFastISel::selectFPExt(const Instruction *I) { 605 if (UnsupportedFPMode) 606 return false; 607 Value *Src = I->getOperand(0); 608 EVT SrcVT = TLI.getValueType(Src->getType(), true); 609 EVT DestVT = TLI.getValueType(I->getType(), true); 610 611 if (SrcVT != MVT::f32 || DestVT != MVT::f64) 612 return false; 613 614 unsigned SrcReg = 615 getRegForValue(Src); // his must be a 32 bit floating point register class 616 // maybe we should handle this differently 617 if (!SrcReg) 618 return false; 619 620 unsigned DestReg = createResultReg(&Mips::AFGR64RegClass); 621 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg); 622 updateValueMap(I, DestReg); 623 return true; 624 } 625 626 // Attempt to fast-select a floating-point truncate instruction. 627 bool MipsFastISel::selectFPTrunc(const Instruction *I) { 628 if (UnsupportedFPMode) 629 return false; 630 Value *Src = I->getOperand(0); 631 EVT SrcVT = TLI.getValueType(Src->getType(), true); 632 EVT DestVT = TLI.getValueType(I->getType(), true); 633 634 if (SrcVT != MVT::f64 || DestVT != MVT::f32) 635 return false; 636 637 unsigned SrcReg = getRegForValue(Src); 638 if (!SrcReg) 639 return false; 640 641 unsigned DestReg = createResultReg(&Mips::FGR32RegClass); 642 if (!DestReg) 643 return false; 644 645 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg); 646 updateValueMap(I, DestReg); 647 return true; 648 } 649 650 // Attempt to fast-select a floating-point-to-integer conversion. 651 bool MipsFastISel::selectFPToInt(const Instruction *I, bool IsSigned) { 652 if (UnsupportedFPMode) 653 return false; 654 MVT DstVT, SrcVT; 655 if (!IsSigned) 656 return false; // We don't handle this case yet. There is no native 657 // instruction for this but it can be synthesized. 658 Type *DstTy = I->getType(); 659 if (!isTypeLegal(DstTy, DstVT)) 660 return false; 661 662 if (DstVT != MVT::i32) 663 return false; 664 665 Value *Src = I->getOperand(0); 666 Type *SrcTy = Src->getType(); 667 if (!isTypeLegal(SrcTy, SrcVT)) 668 return false; 669 670 if (SrcVT != MVT::f32 && SrcVT != MVT::f64) 671 return false; 672 673 unsigned SrcReg = getRegForValue(Src); 674 if (SrcReg == 0) 675 return false; 676 677 // Determine the opcode for the conversion, which takes place 678 // entirely within FPRs. 679 unsigned DestReg = createResultReg(&Mips::GPR32RegClass); 680 unsigned TempReg = createResultReg(&Mips::FGR32RegClass); 681 unsigned Opc; 682 683 if (SrcVT == MVT::f32) 684 Opc = Mips::TRUNC_W_S; 685 else 686 Opc = Mips::TRUNC_W_D32; 687 688 // Generate the convert. 689 emitInst(Opc, TempReg).addReg(SrcReg); 690 691 emitInst(Mips::MFC1, DestReg).addReg(TempReg); 692 693 updateValueMap(I, DestReg); 694 return true; 695 } 696 // 697 bool MipsFastISel::selectRet(const Instruction *I) { 698 const ReturnInst *Ret = cast<ReturnInst>(I); 699 700 if (!FuncInfo.CanLowerReturn) 701 return false; 702 if (Ret->getNumOperands() > 0) { 703 return false; 704 } 705 emitInst(Mips::RetRA); 706 return true; 707 } 708 709 bool MipsFastISel::selectTrunc(const Instruction *I) { 710 // The high bits for a type smaller than the register size are assumed to be 711 // undefined. 712 Value *Op = I->getOperand(0); 713 714 EVT SrcVT, DestVT; 715 SrcVT = TLI.getValueType(Op->getType(), true); 716 DestVT = TLI.getValueType(I->getType(), true); 717 718 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8) 719 return false; 720 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1) 721 return false; 722 723 unsigned SrcReg = getRegForValue(Op); 724 if (!SrcReg) 725 return false; 726 727 // Because the high bits are undefined, a truncate doesn't generate 728 // any code. 729 updateValueMap(I, SrcReg); 730 return true; 731 } 732 bool MipsFastISel::selectIntExt(const Instruction *I) { 733 Type *DestTy = I->getType(); 734 Value *Src = I->getOperand(0); 735 Type *SrcTy = Src->getType(); 736 737 bool isZExt = isa<ZExtInst>(I); 738 unsigned SrcReg = getRegForValue(Src); 739 if (!SrcReg) 740 return false; 741 742 EVT SrcEVT, DestEVT; 743 SrcEVT = TLI.getValueType(SrcTy, true); 744 DestEVT = TLI.getValueType(DestTy, true); 745 if (!SrcEVT.isSimple()) 746 return false; 747 if (!DestEVT.isSimple()) 748 return false; 749 750 MVT SrcVT = SrcEVT.getSimpleVT(); 751 MVT DestVT = DestEVT.getSimpleVT(); 752 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass); 753 754 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt)) 755 return false; 756 updateValueMap(I, ResultReg); 757 return true; 758 } 759 bool MipsFastISel::emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT, 760 unsigned DestReg) { 761 unsigned ShiftAmt; 762 switch (SrcVT.SimpleTy) { 763 default: 764 return false; 765 case MVT::i8: 766 ShiftAmt = 24; 767 break; 768 case MVT::i16: 769 ShiftAmt = 16; 770 break; 771 } 772 unsigned TempReg = createResultReg(&Mips::GPR32RegClass); 773 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt); 774 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt); 775 return true; 776 } 777 778 bool MipsFastISel::emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT, 779 unsigned DestReg) { 780 switch (SrcVT.SimpleTy) { 781 default: 782 return false; 783 case MVT::i8: 784 emitInst(Mips::SEB, DestReg).addReg(SrcReg); 785 break; 786 case MVT::i16: 787 emitInst(Mips::SEH, DestReg).addReg(SrcReg); 788 break; 789 } 790 return true; 791 } 792 793 bool MipsFastISel::emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, 794 unsigned DestReg) { 795 if ((DestVT != MVT::i32) && (DestVT != MVT::i16)) 796 return false; 797 if (Subtarget->hasMips32r2()) 798 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg); 799 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg); 800 } 801 802 bool MipsFastISel::emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, 803 unsigned DestReg) { 804 switch (SrcVT.SimpleTy) { 805 default: 806 return false; 807 case MVT::i1: 808 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(1); 809 break; 810 case MVT::i8: 811 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xff); 812 break; 813 case MVT::i16: 814 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xffff); 815 } 816 return true; 817 } 818 819 bool MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, 820 unsigned DestReg, bool IsZExt) { 821 if (IsZExt) 822 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg); 823 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg); 824 } 825 bool MipsFastISel::fastSelectInstruction(const Instruction *I) { 826 if (!TargetSupported) 827 return false; 828 switch (I->getOpcode()) { 829 default: 830 break; 831 case Instruction::Load: 832 return selectLoad(I); 833 case Instruction::Store: 834 return selectStore(I); 835 case Instruction::Br: 836 return selectBranch(I); 837 case Instruction::Ret: 838 return selectRet(I); 839 case Instruction::Trunc: 840 return selectTrunc(I); 841 case Instruction::ZExt: 842 case Instruction::SExt: 843 return selectIntExt(I); 844 case Instruction::FPTrunc: 845 return selectFPTrunc(I); 846 case Instruction::FPExt: 847 return selectFPExt(I); 848 case Instruction::FPToSI: 849 return selectFPToInt(I, /*isSigned*/ true); 850 case Instruction::FPToUI: 851 return selectFPToInt(I, /*isSigned*/ false); 852 case Instruction::ICmp: 853 case Instruction::FCmp: 854 return selectCmp(I); 855 } 856 return false; 857 } 858 859 unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(const Value *V, 860 bool IsUnsigned) { 861 unsigned VReg = getRegForValue(V); 862 if (VReg == 0) 863 return 0; 864 MVT VMVT = TLI.getValueType(V->getType(), true).getSimpleVT(); 865 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) { 866 unsigned TempReg = createResultReg(&Mips::GPR32RegClass); 867 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned)) 868 return 0; 869 VReg = TempReg; 870 } 871 return VReg; 872 } 873 874 namespace llvm { 875 FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo, 876 const TargetLibraryInfo *libInfo) { 877 return new MipsFastISel(funcInfo, libInfo); 878 } 879 } 880