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 // All possible address modes. 22 typedef struct Address { 23 enum { RegBase, FrameIndexBase } BaseType; 24 25 union { 26 unsigned Reg; 27 int FI; 28 } Base; 29 30 int64_t Offset; 31 32 // Innocuous defaults for our address. 33 Address() : BaseType(RegBase), Offset(0) { Base.Reg = 0; } 34 } Address; 35 36 class MipsFastISel final : public FastISel { 37 38 /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can 39 /// make the right decision when generating code for different targets. 40 Module &M; 41 const TargetMachine &TM; 42 const TargetInstrInfo &TII; 43 const TargetLowering &TLI; 44 const MipsSubtarget *Subtarget; 45 MipsFunctionInfo *MFI; 46 47 // Convenience variables to avoid some queries. 48 LLVMContext *Context; 49 50 bool TargetSupported; 51 52 public: 53 explicit MipsFastISel(FunctionLoweringInfo &funcInfo, 54 const TargetLibraryInfo *libInfo) 55 : FastISel(funcInfo, libInfo), 56 M(const_cast<Module &>(*funcInfo.Fn->getParent())), 57 TM(funcInfo.MF->getTarget()), 58 TII(*TM.getSubtargetImpl()->getInstrInfo()), 59 TLI(*TM.getSubtargetImpl()->getTargetLowering()), 60 Subtarget(&TM.getSubtarget<MipsSubtarget>()) { 61 MFI = funcInfo.MF->getInfo<MipsFunctionInfo>(); 62 Context = &funcInfo.Fn->getContext(); 63 TargetSupported = ((Subtarget->getRelocationModel() == Reloc::PIC_) && 64 ((Subtarget->hasMips32r2() || Subtarget->hasMips32()) && 65 (Subtarget->isABI_O32()))); 66 } 67 68 bool fastSelectInstruction(const Instruction *I) override; 69 unsigned fastMaterializeConstant(const Constant *C) override; 70 71 bool ComputeAddress(const Value *Obj, Address &Addr); 72 73 private: 74 bool EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr, 75 unsigned Alignment = 0); 76 bool EmitStore(MVT VT, unsigned SrcReg, Address &Addr, 77 unsigned Alignment = 0); 78 bool SelectLoad(const Instruction *I); 79 bool SelectRet(const Instruction *I); 80 bool SelectStore(const Instruction *I); 81 bool SelectIntExt(const Instruction *I); 82 bool SelectTrunc(const Instruction *I); 83 bool SelectFPExt(const Instruction *I); 84 bool SelectFPTrunc(const Instruction *I); 85 86 bool isTypeLegal(Type *Ty, MVT &VT); 87 bool isLoadTypeLegal(Type *Ty, MVT &VT); 88 89 unsigned MaterializeFP(const ConstantFP *CFP, MVT VT); 90 unsigned MaterializeGV(const GlobalValue *GV, MVT VT); 91 unsigned MaterializeInt(const Constant *C, MVT VT); 92 unsigned Materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC); 93 94 bool EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg, 95 bool IsZExt); 96 97 bool EmitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg); 98 99 bool EmitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg); 100 bool EmitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT, 101 unsigned DestReg); 102 bool EmitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT, 103 unsigned DestReg); 104 // for some reason, this default is not generated by tablegen 105 // so we explicitly generate it here. 106 // 107 unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC, 108 unsigned Op0, bool Op0IsKill, uint64_t imm1, 109 uint64_t imm2, unsigned Op3, bool Op3IsKill) { 110 return 0; 111 } 112 113 MachineInstrBuilder EmitInst(unsigned Opc) { 114 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)); 115 } 116 117 MachineInstrBuilder EmitInst(unsigned Opc, unsigned DstReg) { 118 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), 119 DstReg); 120 } 121 122 MachineInstrBuilder EmitInstStore(unsigned Opc, unsigned SrcReg, 123 unsigned MemReg, int64_t MemOffset) { 124 return EmitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset); 125 } 126 127 MachineInstrBuilder EmitInstLoad(unsigned Opc, unsigned DstReg, 128 unsigned MemReg, int64_t MemOffset) { 129 return EmitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset); 130 } 131 132 #include "MipsGenFastISel.inc" 133 }; 134 135 bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) { 136 EVT evt = TLI.getValueType(Ty, true); 137 // Only handle simple types. 138 if (evt == MVT::Other || !evt.isSimple()) 139 return false; 140 VT = evt.getSimpleVT(); 141 142 // Handle all legal types, i.e. a register that will directly hold this 143 // value. 144 return TLI.isTypeLegal(VT); 145 } 146 147 bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) { 148 if (isTypeLegal(Ty, VT)) 149 return true; 150 // We will extend this in a later patch: 151 // If this is a type than can be sign or zero-extended to a basic operation 152 // go ahead and accept it now. 153 if (VT == MVT::i8 || VT == MVT::i16) 154 return true; 155 return false; 156 } 157 158 bool MipsFastISel::ComputeAddress(const Value *Obj, Address &Addr) { 159 // This construct looks a big awkward but it is how other ports handle this 160 // and as this function is more fully completed, these cases which 161 // return false will have additional code in them. 162 // 163 if (isa<Instruction>(Obj)) 164 return false; 165 else if (isa<ConstantExpr>(Obj)) 166 return false; 167 Addr.Base.Reg = getRegForValue(Obj); 168 return Addr.Base.Reg != 0; 169 } 170 171 bool MipsFastISel::EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr, 172 unsigned Alignment) { 173 // 174 // more cases will be handled here in following patches. 175 // 176 unsigned Opc; 177 switch (VT.SimpleTy) { 178 case MVT::i32: { 179 ResultReg = createResultReg(&Mips::GPR32RegClass); 180 Opc = Mips::LW; 181 break; 182 } 183 case MVT::i16: { 184 ResultReg = createResultReg(&Mips::GPR32RegClass); 185 Opc = Mips::LHu; 186 break; 187 } 188 case MVT::i8: { 189 ResultReg = createResultReg(&Mips::GPR32RegClass); 190 Opc = Mips::LBu; 191 break; 192 } 193 case MVT::f32: { 194 ResultReg = createResultReg(&Mips::FGR32RegClass); 195 Opc = Mips::LWC1; 196 break; 197 } 198 case MVT::f64: { 199 ResultReg = createResultReg(&Mips::AFGR64RegClass); 200 Opc = Mips::LDC1; 201 break; 202 } 203 default: 204 return false; 205 } 206 EmitInstLoad(Opc, ResultReg, Addr.Base.Reg, Addr.Offset); 207 return true; 208 } 209 210 // Materialize a constant into a register, and return the register 211 // number (or zero if we failed to handle it). 212 unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) { 213 EVT CEVT = TLI.getValueType(C->getType(), true); 214 215 // Only handle simple types. 216 if (!CEVT.isSimple()) 217 return 0; 218 MVT VT = CEVT.getSimpleVT(); 219 220 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) 221 return MaterializeFP(CFP, VT); 222 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) 223 return MaterializeGV(GV, VT); 224 else if (isa<ConstantInt>(C)) 225 return MaterializeInt(C, VT); 226 227 return 0; 228 } 229 230 bool MipsFastISel::EmitStore(MVT VT, unsigned SrcReg, Address &Addr, 231 unsigned Alignment) { 232 // 233 // more cases will be handled here in following patches. 234 // 235 unsigned Opc; 236 switch (VT.SimpleTy) { 237 case MVT::i8: 238 Opc = Mips::SB; 239 break; 240 case MVT::i16: 241 Opc = Mips::SH; 242 break; 243 case MVT::i32: 244 Opc = Mips::SW; 245 break; 246 case MVT::f32: 247 Opc = Mips::SWC1; 248 break; 249 case MVT::f64: 250 Opc = Mips::SDC1; 251 break; 252 default: 253 return false; 254 } 255 EmitInstStore(Opc, SrcReg, Addr.Base.Reg, Addr.Offset); 256 return true; 257 } 258 259 bool MipsFastISel::EmitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT, 260 unsigned DestReg) { 261 unsigned ShiftAmt; 262 switch (SrcVT.SimpleTy) { 263 default: 264 return false; 265 case MVT::i8: 266 ShiftAmt = 24; 267 break; 268 case MVT::i16: 269 ShiftAmt = 16; 270 break; 271 } 272 unsigned TempReg = createResultReg(&Mips::GPR32RegClass); 273 EmitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt); 274 EmitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt); 275 return true; 276 } 277 278 bool MipsFastISel::EmitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT, 279 unsigned DestReg) { 280 switch (SrcVT.SimpleTy) { 281 default: 282 return false; 283 case MVT::i8: 284 EmitInst(Mips::SEB, DestReg).addReg(SrcReg); 285 break; 286 case MVT::i16: 287 EmitInst(Mips::SEH, DestReg).addReg(SrcReg); 288 break; 289 } 290 return true; 291 } 292 293 bool MipsFastISel::EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, 294 unsigned DestReg, bool IsZExt) { 295 if (IsZExt) 296 return EmitIntZExt(SrcVT, SrcReg, DestVT, DestReg); 297 return EmitIntSExt(SrcVT, SrcReg, DestVT, DestReg); 298 } 299 300 bool MipsFastISel::EmitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, 301 unsigned DestReg) { 302 if ((DestVT != MVT::i32) && (DestVT != MVT::i16)) 303 return false; 304 if (Subtarget->hasMips32r2()) 305 return EmitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg); 306 return EmitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg); 307 } 308 309 bool MipsFastISel::EmitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, 310 unsigned DestReg) { 311 switch (SrcVT.SimpleTy) { 312 default: 313 return false; 314 case MVT::i1: 315 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(1); 316 break; 317 case MVT::i8: 318 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xff); 319 break; 320 case MVT::i16: 321 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xffff); 322 break; 323 } 324 return true; 325 } 326 327 bool MipsFastISel::SelectLoad(const Instruction *I) { 328 // Atomic loads need special handling. 329 if (cast<LoadInst>(I)->isAtomic()) 330 return false; 331 332 // Verify we have a legal type before going any further. 333 MVT VT; 334 if (!isLoadTypeLegal(I->getType(), VT)) 335 return false; 336 337 // See if we can handle this address. 338 Address Addr; 339 if (!ComputeAddress(I->getOperand(0), Addr)) 340 return false; 341 342 unsigned ResultReg; 343 if (!EmitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment())) 344 return false; 345 updateValueMap(I, ResultReg); 346 return true; 347 } 348 349 bool MipsFastISel::SelectStore(const Instruction *I) { 350 Value *Op0 = I->getOperand(0); 351 unsigned SrcReg = 0; 352 353 // Atomic stores need special handling. 354 if (cast<StoreInst>(I)->isAtomic()) 355 return false; 356 357 // Verify we have a legal type before going any further. 358 MVT VT; 359 if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT)) 360 return false; 361 362 // Get the value to be stored into a register. 363 SrcReg = getRegForValue(Op0); 364 if (SrcReg == 0) 365 return false; 366 367 // See if we can handle this address. 368 Address Addr; 369 if (!ComputeAddress(I->getOperand(1), Addr)) 370 return false; 371 372 if (!EmitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment())) 373 return false; 374 return true; 375 } 376 377 bool MipsFastISel::SelectRet(const Instruction *I) { 378 const ReturnInst *Ret = cast<ReturnInst>(I); 379 380 if (!FuncInfo.CanLowerReturn) 381 return false; 382 if (Ret->getNumOperands() > 0) { 383 return false; 384 } 385 EmitInst(Mips::RetRA); 386 return true; 387 } 388 389 // Attempt to fast-select a floating-point extend instruction. 390 bool MipsFastISel::SelectFPExt(const Instruction *I) { 391 Value *Src = I->getOperand(0); 392 EVT SrcVT = TLI.getValueType(Src->getType(), true); 393 EVT DestVT = TLI.getValueType(I->getType(), true); 394 395 if (SrcVT != MVT::f32 || DestVT != MVT::f64) 396 return false; 397 398 unsigned SrcReg = 399 getRegForValue(Src); // his must be a 32 bit floating point register class 400 // maybe we should handle this differently 401 if (!SrcReg) 402 return false; 403 404 unsigned DestReg = createResultReg(&Mips::AFGR64RegClass); 405 EmitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg); 406 updateValueMap(I, DestReg); 407 return true; 408 } 409 410 // Attempt to fast-select a floating-point truncate instruction. 411 bool MipsFastISel::SelectFPTrunc(const Instruction *I) { 412 Value *Src = I->getOperand(0); 413 EVT SrcVT = TLI.getValueType(Src->getType(), true); 414 EVT DestVT = TLI.getValueType(I->getType(), true); 415 416 if (SrcVT != MVT::f64 || DestVT != MVT::f32) 417 return false; 418 419 unsigned SrcReg = getRegForValue(Src); 420 if (!SrcReg) 421 return false; 422 423 unsigned DestReg = createResultReg(&Mips::FGR32RegClass); 424 if (!DestReg) 425 return false; 426 427 EmitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg); 428 updateValueMap(I, DestReg); 429 return true; 430 } 431 432 bool MipsFastISel::SelectIntExt(const Instruction *I) { 433 Type *DestTy = I->getType(); 434 Value *Src = I->getOperand(0); 435 Type *SrcTy = Src->getType(); 436 437 bool isZExt = isa<ZExtInst>(I); 438 unsigned SrcReg = getRegForValue(Src); 439 if (!SrcReg) 440 return false; 441 442 EVT SrcEVT, DestEVT; 443 SrcEVT = TLI.getValueType(SrcTy, true); 444 DestEVT = TLI.getValueType(DestTy, true); 445 if (!SrcEVT.isSimple()) 446 return false; 447 if (!DestEVT.isSimple()) 448 return false; 449 450 MVT SrcVT = SrcEVT.getSimpleVT(); 451 MVT DestVT = DestEVT.getSimpleVT(); 452 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass); 453 454 if (!EmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt)) 455 return false; 456 updateValueMap(I, ResultReg); 457 return true; 458 } 459 460 bool MipsFastISel::SelectTrunc(const Instruction *I) { 461 // The high bits for a type smaller than the register size are assumed to be 462 // undefined. 463 Value *Op = I->getOperand(0); 464 465 EVT SrcVT, DestVT; 466 SrcVT = TLI.getValueType(Op->getType(), true); 467 DestVT = TLI.getValueType(I->getType(), true); 468 469 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8) 470 return false; 471 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1) 472 return false; 473 474 unsigned SrcReg = getRegForValue(Op); 475 if (!SrcReg) 476 return false; 477 478 // Because the high bits are undefined, a truncate doesn't generate 479 // any code. 480 updateValueMap(I, SrcReg); 481 return true; 482 } 483 484 bool MipsFastISel::fastSelectInstruction(const Instruction *I) { 485 if (!TargetSupported) 486 return false; 487 switch (I->getOpcode()) { 488 default: 489 break; 490 case Instruction::Load: 491 return SelectLoad(I); 492 case Instruction::Store: 493 return SelectStore(I); 494 case Instruction::Ret: 495 return SelectRet(I); 496 case Instruction::Trunc: 497 return SelectTrunc(I); 498 case Instruction::ZExt: 499 case Instruction::SExt: 500 return SelectIntExt(I); 501 case Instruction::FPTrunc: 502 return SelectFPTrunc(I); 503 case Instruction::FPExt: 504 return SelectFPExt(I); 505 } 506 return false; 507 } 508 509 unsigned MipsFastISel::MaterializeFP(const ConstantFP *CFP, MVT VT) { 510 int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); 511 if (VT == MVT::f32) { 512 const TargetRegisterClass *RC = &Mips::FGR32RegClass; 513 unsigned DestReg = createResultReg(RC); 514 unsigned TempReg = Materialize32BitInt(Imm, &Mips::GPR32RegClass); 515 EmitInst(Mips::MTC1, DestReg).addReg(TempReg); 516 return DestReg; 517 } else if (VT == MVT::f64) { 518 const TargetRegisterClass *RC = &Mips::AFGR64RegClass; 519 unsigned DestReg = createResultReg(RC); 520 unsigned TempReg1 = Materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass); 521 unsigned TempReg2 = 522 Materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass); 523 EmitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1); 524 return DestReg; 525 } 526 return 0; 527 } 528 529 unsigned MipsFastISel::MaterializeGV(const GlobalValue *GV, MVT VT) { 530 // For now 32-bit only. 531 if (VT != MVT::i32) 532 return 0; 533 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 534 unsigned DestReg = createResultReg(RC); 535 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); 536 bool IsThreadLocal = GVar && GVar->isThreadLocal(); 537 // TLS not supported at this time. 538 if (IsThreadLocal) 539 return 0; 540 EmitInst(Mips::LW, DestReg) 541 .addReg(MFI->getGlobalBaseReg()) 542 .addGlobalAddress(GV, 0, MipsII::MO_GOT); 543 if ((GV->hasInternalLinkage() || 544 (GV->hasLocalLinkage() && !isa<Function>(GV)))) { 545 unsigned TempReg = createResultReg(RC); 546 EmitInst(Mips::ADDiu, TempReg) 547 .addReg(DestReg) 548 .addGlobalAddress(GV, 0, MipsII::MO_ABS_LO); 549 DestReg = TempReg; 550 } 551 return DestReg; 552 } 553 554 unsigned MipsFastISel::MaterializeInt(const Constant *C, MVT VT) { 555 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1) 556 return 0; 557 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 558 const ConstantInt *CI = cast<ConstantInt>(C); 559 int64_t Imm; 560 if ((VT != MVT::i1) && CI->isNegative()) 561 Imm = CI->getSExtValue(); 562 else 563 Imm = CI->getZExtValue(); 564 return Materialize32BitInt(Imm, RC); 565 } 566 567 unsigned MipsFastISel::Materialize32BitInt(int64_t Imm, 568 const TargetRegisterClass *RC) { 569 unsigned ResultReg = createResultReg(RC); 570 571 if (isInt<16>(Imm)) { 572 unsigned Opc = Mips::ADDiu; 573 EmitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm); 574 return ResultReg; 575 } else if (isUInt<16>(Imm)) { 576 EmitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm); 577 return ResultReg; 578 } 579 unsigned Lo = Imm & 0xFFFF; 580 unsigned Hi = (Imm >> 16) & 0xFFFF; 581 if (Lo) { 582 // Both Lo and Hi have nonzero bits. 583 unsigned TmpReg = createResultReg(RC); 584 EmitInst(Mips::LUi, TmpReg).addImm(Hi); 585 EmitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo); 586 } else { 587 EmitInst(Mips::LUi, ResultReg).addImm(Hi); 588 } 589 return ResultReg; 590 } 591 } 592 593 namespace llvm { 594 FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo, 595 const TargetLibraryInfo *libInfo) { 596 return new MipsFastISel(funcInfo, libInfo); 597 } 598 } 599