LLVM API Documentation
00001 //===-- MipsastISel.cpp - Mips FastISel implementation 00002 //---------------------===// 00003 00004 #include "llvm/CodeGen/FunctionLoweringInfo.h" 00005 #include "llvm/CodeGen/FastISel.h" 00006 #include "llvm/CodeGen/MachineInstrBuilder.h" 00007 #include "llvm/IR/GlobalAlias.h" 00008 #include "llvm/IR/GlobalVariable.h" 00009 #include "llvm/Target/TargetInstrInfo.h" 00010 #include "llvm/Target/TargetLibraryInfo.h" 00011 #include "MipsRegisterInfo.h" 00012 #include "MipsISelLowering.h" 00013 #include "MipsMachineFunction.h" 00014 #include "MipsSubtarget.h" 00015 #include "MipsTargetMachine.h" 00016 00017 using namespace llvm; 00018 00019 namespace { 00020 00021 // All possible address modes. 00022 typedef struct Address { 00023 enum { RegBase, FrameIndexBase } BaseType; 00024 00025 union { 00026 unsigned Reg; 00027 int FI; 00028 } Base; 00029 00030 int64_t Offset; 00031 00032 // Innocuous defaults for our address. 00033 Address() : BaseType(RegBase), Offset(0) { Base.Reg = 0; } 00034 } Address; 00035 00036 class MipsFastISel final : public FastISel { 00037 00038 /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can 00039 /// make the right decision when generating code for different targets. 00040 Module &M; 00041 const TargetMachine &TM; 00042 const TargetInstrInfo &TII; 00043 const TargetLowering &TLI; 00044 const MipsSubtarget *Subtarget; 00045 MipsFunctionInfo *MFI; 00046 00047 // Convenience variables to avoid some queries. 00048 LLVMContext *Context; 00049 00050 bool TargetSupported; 00051 00052 public: 00053 explicit MipsFastISel(FunctionLoweringInfo &funcInfo, 00054 const TargetLibraryInfo *libInfo) 00055 : FastISel(funcInfo, libInfo), 00056 M(const_cast<Module &>(*funcInfo.Fn->getParent())), 00057 TM(funcInfo.MF->getTarget()), 00058 TII(*TM.getSubtargetImpl()->getInstrInfo()), 00059 TLI(*TM.getSubtargetImpl()->getTargetLowering()), 00060 Subtarget(&TM.getSubtarget<MipsSubtarget>()) { 00061 MFI = funcInfo.MF->getInfo<MipsFunctionInfo>(); 00062 Context = &funcInfo.Fn->getContext(); 00063 TargetSupported = ((Subtarget->getRelocationModel() == Reloc::PIC_) && 00064 ((Subtarget->hasMips32r2() || Subtarget->hasMips32()) && 00065 (Subtarget->isABI_O32()))); 00066 } 00067 00068 bool fastSelectInstruction(const Instruction *I) override; 00069 unsigned fastMaterializeConstant(const Constant *C) override; 00070 00071 bool ComputeAddress(const Value *Obj, Address &Addr); 00072 00073 private: 00074 bool EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr, 00075 unsigned Alignment = 0); 00076 bool EmitStore(MVT VT, unsigned SrcReg, Address &Addr, 00077 unsigned Alignment = 0); 00078 bool SelectLoad(const Instruction *I); 00079 bool SelectRet(const Instruction *I); 00080 bool SelectStore(const Instruction *I); 00081 00082 bool isTypeLegal(Type *Ty, MVT &VT); 00083 bool isLoadTypeLegal(Type *Ty, MVT &VT); 00084 00085 unsigned MaterializeFP(const ConstantFP *CFP, MVT VT); 00086 unsigned MaterializeGV(const GlobalValue *GV, MVT VT); 00087 unsigned MaterializeInt(const Constant *C, MVT VT); 00088 unsigned Materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC); 00089 00090 // for some reason, this default is not generated by tablegen 00091 // so we explicitly generate it here. 00092 // 00093 unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC, 00094 unsigned Op0, bool Op0IsKill, uint64_t imm1, 00095 uint64_t imm2, unsigned Op3, bool Op3IsKill) { 00096 return 0; 00097 } 00098 00099 MachineInstrBuilder EmitInst(unsigned Opc) { 00100 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)); 00101 } 00102 00103 MachineInstrBuilder EmitInst(unsigned Opc, unsigned DstReg) { 00104 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), 00105 DstReg); 00106 } 00107 00108 MachineInstrBuilder EmitInstStore(unsigned Opc, unsigned SrcReg, 00109 unsigned MemReg, int64_t MemOffset) { 00110 return EmitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset); 00111 } 00112 00113 MachineInstrBuilder EmitInstLoad(unsigned Opc, unsigned DstReg, 00114 unsigned MemReg, int64_t MemOffset) { 00115 return EmitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset); 00116 } 00117 00118 #include "MipsGenFastISel.inc" 00119 }; 00120 00121 bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) { 00122 EVT evt = TLI.getValueType(Ty, true); 00123 // Only handle simple types. 00124 if (evt == MVT::Other || !evt.isSimple()) 00125 return false; 00126 VT = evt.getSimpleVT(); 00127 00128 // Handle all legal types, i.e. a register that will directly hold this 00129 // value. 00130 return TLI.isTypeLegal(VT); 00131 } 00132 00133 bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) { 00134 if (isTypeLegal(Ty, VT)) 00135 return true; 00136 // We will extend this in a later patch: 00137 // If this is a type than can be sign or zero-extended to a basic operation 00138 // go ahead and accept it now. 00139 if (VT == MVT::i8 || VT == MVT::i16) 00140 return true; 00141 return false; 00142 } 00143 00144 bool MipsFastISel::ComputeAddress(const Value *Obj, Address &Addr) { 00145 // This construct looks a big awkward but it is how other ports handle this 00146 // and as this function is more fully completed, these cases which 00147 // return false will have additional code in them. 00148 // 00149 if (isa<Instruction>(Obj)) 00150 return false; 00151 else if (isa<ConstantExpr>(Obj)) 00152 return false; 00153 Addr.Base.Reg = getRegForValue(Obj); 00154 return Addr.Base.Reg != 0; 00155 } 00156 00157 bool MipsFastISel::EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr, 00158 unsigned Alignment) { 00159 // 00160 // more cases will be handled here in following patches. 00161 // 00162 unsigned Opc; 00163 switch (VT.SimpleTy) { 00164 case MVT::i32: { 00165 ResultReg = createResultReg(&Mips::GPR32RegClass); 00166 Opc = Mips::LW; 00167 break; 00168 } 00169 case MVT::i16: { 00170 ResultReg = createResultReg(&Mips::GPR32RegClass); 00171 Opc = Mips::LHu; 00172 break; 00173 } 00174 case MVT::i8: { 00175 ResultReg = createResultReg(&Mips::GPR32RegClass); 00176 Opc = Mips::LBu; 00177 break; 00178 } 00179 case MVT::f32: { 00180 ResultReg = createResultReg(&Mips::FGR32RegClass); 00181 Opc = Mips::LWC1; 00182 break; 00183 } 00184 case MVT::f64: { 00185 ResultReg = createResultReg(&Mips::AFGR64RegClass); 00186 Opc = Mips::LDC1; 00187 break; 00188 } 00189 default: 00190 return false; 00191 } 00192 EmitInstLoad(Opc, ResultReg, Addr.Base.Reg, Addr.Offset); 00193 return true; 00194 } 00195 00196 // Materialize a constant into a register, and return the register 00197 // number (or zero if we failed to handle it). 00198 unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) { 00199 EVT CEVT = TLI.getValueType(C->getType(), true); 00200 00201 // Only handle simple types. 00202 if (!CEVT.isSimple()) 00203 return 0; 00204 MVT VT = CEVT.getSimpleVT(); 00205 00206 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) 00207 return MaterializeFP(CFP, VT); 00208 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) 00209 return MaterializeGV(GV, VT); 00210 else if (isa<ConstantInt>(C)) 00211 return MaterializeInt(C, VT); 00212 00213 return 0; 00214 } 00215 00216 bool MipsFastISel::EmitStore(MVT VT, unsigned SrcReg, Address &Addr, 00217 unsigned Alignment) { 00218 // 00219 // more cases will be handled here in following patches. 00220 // 00221 unsigned Opc; 00222 switch (VT.SimpleTy) { 00223 case MVT::i8: 00224 Opc = Mips::SB; 00225 break; 00226 case MVT::i16: 00227 Opc = Mips::SH; 00228 break; 00229 case MVT::i32: 00230 Opc = Mips::SW; 00231 break; 00232 case MVT::f32: 00233 Opc = Mips::SWC1; 00234 break; 00235 case MVT::f64: 00236 Opc = Mips::SDC1; 00237 break; 00238 default: 00239 return false; 00240 } 00241 EmitInstStore(Opc, SrcReg, Addr.Base.Reg, Addr.Offset); 00242 return true; 00243 } 00244 00245 bool MipsFastISel::SelectLoad(const Instruction *I) { 00246 // Atomic loads need special handling. 00247 if (cast<LoadInst>(I)->isAtomic()) 00248 return false; 00249 00250 // Verify we have a legal type before going any further. 00251 MVT VT; 00252 if (!isLoadTypeLegal(I->getType(), VT)) 00253 return false; 00254 00255 // See if we can handle this address. 00256 Address Addr; 00257 if (!ComputeAddress(I->getOperand(0), Addr)) 00258 return false; 00259 00260 unsigned ResultReg; 00261 if (!EmitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment())) 00262 return false; 00263 updateValueMap(I, ResultReg); 00264 return true; 00265 } 00266 00267 bool MipsFastISel::SelectStore(const Instruction *I) { 00268 Value *Op0 = I->getOperand(0); 00269 unsigned SrcReg = 0; 00270 00271 // Atomic stores need special handling. 00272 if (cast<StoreInst>(I)->isAtomic()) 00273 return false; 00274 00275 // Verify we have a legal type before going any further. 00276 MVT VT; 00277 if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT)) 00278 return false; 00279 00280 // Get the value to be stored into a register. 00281 SrcReg = getRegForValue(Op0); 00282 if (SrcReg == 0) 00283 return false; 00284 00285 // See if we can handle this address. 00286 Address Addr; 00287 if (!ComputeAddress(I->getOperand(1), Addr)) 00288 return false; 00289 00290 if (!EmitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment())) 00291 return false; 00292 return true; 00293 } 00294 00295 bool MipsFastISel::SelectRet(const Instruction *I) { 00296 const ReturnInst *Ret = cast<ReturnInst>(I); 00297 00298 if (!FuncInfo.CanLowerReturn) 00299 return false; 00300 if (Ret->getNumOperands() > 0) { 00301 return false; 00302 } 00303 EmitInst(Mips::RetRA); 00304 return true; 00305 } 00306 00307 bool MipsFastISel::fastSelectInstruction(const Instruction *I) { 00308 if (!TargetSupported) 00309 return false; 00310 switch (I->getOpcode()) { 00311 default: 00312 break; 00313 case Instruction::Load: 00314 return SelectLoad(I); 00315 case Instruction::Store: 00316 return SelectStore(I); 00317 case Instruction::Ret: 00318 return SelectRet(I); 00319 } 00320 return false; 00321 } 00322 } 00323 00324 unsigned MipsFastISel::MaterializeFP(const ConstantFP *CFP, MVT VT) { 00325 int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); 00326 if (VT == MVT::f32) { 00327 const TargetRegisterClass *RC = &Mips::FGR32RegClass; 00328 unsigned DestReg = createResultReg(RC); 00329 unsigned TempReg = Materialize32BitInt(Imm, &Mips::GPR32RegClass); 00330 EmitInst(Mips::MTC1, DestReg).addReg(TempReg); 00331 return DestReg; 00332 } else if (VT == MVT::f64) { 00333 const TargetRegisterClass *RC = &Mips::AFGR64RegClass; 00334 unsigned DestReg = createResultReg(RC); 00335 unsigned TempReg1 = Materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass); 00336 unsigned TempReg2 = 00337 Materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass); 00338 EmitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1); 00339 return DestReg; 00340 } 00341 return 0; 00342 } 00343 00344 unsigned MipsFastISel::MaterializeGV(const GlobalValue *GV, MVT VT) { 00345 // For now 32-bit only. 00346 if (VT != MVT::i32) 00347 return 0; 00348 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 00349 unsigned DestReg = createResultReg(RC); 00350 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); 00351 bool IsThreadLocal = GVar && GVar->isThreadLocal(); 00352 // TLS not supported at this time. 00353 if (IsThreadLocal) 00354 return 0; 00355 EmitInst(Mips::LW, DestReg).addReg(MFI->getGlobalBaseReg()).addGlobalAddress( 00356 GV, 0, MipsII::MO_GOT); 00357 if ((GV->hasInternalLinkage() || 00358 (GV->hasLocalLinkage() && !isa<Function>(GV)))) { 00359 unsigned TempReg = createResultReg(RC); 00360 EmitInst(Mips::ADDiu, TempReg).addReg(DestReg).addGlobalAddress( 00361 GV, 0, MipsII::MO_ABS_LO); 00362 DestReg = TempReg; 00363 } 00364 return DestReg; 00365 } 00366 00367 unsigned MipsFastISel::MaterializeInt(const Constant *C, MVT VT) { 00368 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1) 00369 return 0; 00370 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 00371 const ConstantInt *CI = cast<ConstantInt>(C); 00372 int64_t Imm; 00373 if ((VT != MVT::i1) && CI->isNegative()) 00374 Imm = CI->getSExtValue(); 00375 else 00376 Imm = CI->getZExtValue(); 00377 return Materialize32BitInt(Imm, RC); 00378 } 00379 00380 unsigned MipsFastISel::Materialize32BitInt(int64_t Imm, 00381 const TargetRegisterClass *RC) { 00382 unsigned ResultReg = createResultReg(RC); 00383 00384 if (isInt<16>(Imm)) { 00385 unsigned Opc = Mips::ADDiu; 00386 EmitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm); 00387 return ResultReg; 00388 } else if (isUInt<16>(Imm)) { 00389 EmitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm); 00390 return ResultReg; 00391 } 00392 unsigned Lo = Imm & 0xFFFF; 00393 unsigned Hi = (Imm >> 16) & 0xFFFF; 00394 if (Lo) { 00395 // Both Lo and Hi have nonzero bits. 00396 unsigned TmpReg = createResultReg(RC); 00397 EmitInst(Mips::LUi, TmpReg).addImm(Hi); 00398 EmitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo); 00399 } else { 00400 EmitInst(Mips::LUi, ResultReg).addImm(Hi); 00401 } 00402 return ResultReg; 00403 } 00404 00405 namespace llvm { 00406 FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo, 00407 const TargetLibraryInfo *libInfo) { 00408 return new MipsFastISel(funcInfo, libInfo); 00409 } 00410 }