1 //===-- MipsastISel.cpp - Mips FastISel implementation
2 //---------------------===//
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"
21 // All possible address modes.
22 typedef struct Address {
23 enum { RegBase, FrameIndexBase } BaseType;
32 // Innocuous defaults for our address.
33 Address() : BaseType(RegBase), Offset(0) { Base.Reg = 0; }
36 class MipsFastISel final : public FastISel {
38 /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
39 /// make the right decision when generating code for different targets.
41 const TargetMachine &TM;
42 const TargetInstrInfo &TII;
43 const TargetLowering &TLI;
44 const MipsSubtarget *Subtarget;
45 MipsFunctionInfo *MFI;
47 // Convenience variables to avoid some queries.
51 bool UnsupportedFPMode;
54 explicit MipsFastISel(FunctionLoweringInfo &funcInfo,
55 const TargetLibraryInfo *libInfo)
56 : FastISel(funcInfo, libInfo),
57 M(const_cast<Module &>(*funcInfo.Fn->getParent())),
58 TM(funcInfo.MF->getTarget()),
59 TII(*TM.getSubtargetImpl()->getInstrInfo()),
60 TLI(*TM.getSubtargetImpl()->getTargetLowering()),
61 Subtarget(&TM.getSubtarget<MipsSubtarget>()) {
62 MFI = funcInfo.MF->getInfo<MipsFunctionInfo>();
63 Context = &funcInfo.Fn->getContext();
64 TargetSupported = ((Subtarget->getRelocationModel() == Reloc::PIC_) &&
65 ((Subtarget->hasMips32r2() || Subtarget->hasMips32()) &&
66 (Subtarget->isABI_O32())));
67 UnsupportedFPMode = Subtarget->isFP64bit();
70 bool fastSelectInstruction(const Instruction *I) override;
71 unsigned fastMaterializeConstant(const Constant *C) override;
73 bool ComputeAddress(const Value *Obj, Address &Addr);
76 bool EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
77 unsigned Alignment = 0);
78 bool EmitStore(MVT VT, unsigned SrcReg, Address &Addr,
79 unsigned Alignment = 0);
80 bool SelectLoad(const Instruction *I);
81 bool SelectRet(const Instruction *I);
82 bool SelectStore(const Instruction *I);
83 bool SelectIntExt(const Instruction *I);
84 bool SelectTrunc(const Instruction *I);
85 bool SelectFPExt(const Instruction *I);
86 bool SelectFPTrunc(const Instruction *I);
87 bool SelectFPToI(const Instruction *I, bool IsSigned);
89 bool isTypeLegal(Type *Ty, MVT &VT);
90 bool isLoadTypeLegal(Type *Ty, MVT &VT);
92 unsigned MaterializeFP(const ConstantFP *CFP, MVT VT);
93 unsigned MaterializeGV(const GlobalValue *GV, MVT VT);
94 unsigned MaterializeInt(const Constant *C, MVT VT);
95 unsigned Materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);
97 bool EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg,
100 bool EmitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
102 bool EmitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
103 bool EmitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
105 bool EmitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
107 // for some reason, this default is not generated by tablegen
108 // so we explicitly generate it here.
110 unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC,
111 unsigned Op0, bool Op0IsKill, uint64_t imm1,
112 uint64_t imm2, unsigned Op3, bool Op3IsKill) {
116 MachineInstrBuilder EmitInst(unsigned Opc) {
117 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
120 MachineInstrBuilder EmitInst(unsigned Opc, unsigned DstReg) {
121 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
125 MachineInstrBuilder EmitInstStore(unsigned Opc, unsigned SrcReg,
126 unsigned MemReg, int64_t MemOffset) {
127 return EmitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset);
130 MachineInstrBuilder EmitInstLoad(unsigned Opc, unsigned DstReg,
131 unsigned MemReg, int64_t MemOffset) {
132 return EmitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);
135 #include "MipsGenFastISel.inc"
138 bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) {
139 EVT evt = TLI.getValueType(Ty, true);
140 // Only handle simple types.
141 if (evt == MVT::Other || !evt.isSimple())
143 VT = evt.getSimpleVT();
145 // Handle all legal types, i.e. a register that will directly hold this
147 return TLI.isTypeLegal(VT);
150 bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
151 if (isTypeLegal(Ty, VT))
153 // We will extend this in a later patch:
154 // If this is a type than can be sign or zero-extended to a basic operation
155 // go ahead and accept it now.
156 if (VT == MVT::i8 || VT == MVT::i16)
161 bool MipsFastISel::ComputeAddress(const Value *Obj, Address &Addr) {
162 // This construct looks a big awkward but it is how other ports handle this
163 // and as this function is more fully completed, these cases which
164 // return false will have additional code in them.
166 if (isa<Instruction>(Obj))
168 else if (isa<ConstantExpr>(Obj))
170 Addr.Base.Reg = getRegForValue(Obj);
171 return Addr.Base.Reg != 0;
174 bool MipsFastISel::EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
175 unsigned Alignment) {
177 // more cases will be handled here in following patches.
180 switch (VT.SimpleTy) {
182 ResultReg = createResultReg(&Mips::GPR32RegClass);
187 ResultReg = createResultReg(&Mips::GPR32RegClass);
192 ResultReg = createResultReg(&Mips::GPR32RegClass);
197 if (UnsupportedFPMode)
199 ResultReg = createResultReg(&Mips::FGR32RegClass);
204 if (UnsupportedFPMode)
206 ResultReg = createResultReg(&Mips::AFGR64RegClass);
213 EmitInstLoad(Opc, ResultReg, Addr.Base.Reg, Addr.Offset);
217 // Materialize a constant into a register, and return the register
218 // number (or zero if we failed to handle it).
219 unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) {
220 EVT CEVT = TLI.getValueType(C->getType(), true);
222 // Only handle simple types.
223 if (!CEVT.isSimple())
225 MVT VT = CEVT.getSimpleVT();
227 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
228 return (UnsupportedFPMode) ? 0 : MaterializeFP(CFP, VT);
229 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
230 return MaterializeGV(GV, VT);
231 else if (isa<ConstantInt>(C))
232 return MaterializeInt(C, VT);
237 bool MipsFastISel::EmitStore(MVT VT, unsigned SrcReg, Address &Addr,
238 unsigned Alignment) {
240 // more cases will be handled here in following patches.
243 switch (VT.SimpleTy) {
254 if (UnsupportedFPMode)
259 if (UnsupportedFPMode)
266 EmitInstStore(Opc, SrcReg, Addr.Base.Reg, Addr.Offset);
270 bool MipsFastISel::EmitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
273 switch (SrcVT.SimpleTy) {
283 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
284 EmitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
285 EmitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
289 bool MipsFastISel::EmitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
291 switch (SrcVT.SimpleTy) {
295 EmitInst(Mips::SEB, DestReg).addReg(SrcReg);
298 EmitInst(Mips::SEH, DestReg).addReg(SrcReg);
304 bool MipsFastISel::EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
305 unsigned DestReg, bool IsZExt) {
307 return EmitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
308 return EmitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
311 bool MipsFastISel::EmitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
313 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
315 if (Subtarget->hasMips32r2())
316 return EmitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
317 return EmitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
320 bool MipsFastISel::EmitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
322 switch (SrcVT.SimpleTy) {
326 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(1);
329 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xff);
332 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xffff);
338 bool MipsFastISel::SelectLoad(const Instruction *I) {
339 // Atomic loads need special handling.
340 if (cast<LoadInst>(I)->isAtomic())
343 // Verify we have a legal type before going any further.
345 if (!isLoadTypeLegal(I->getType(), VT))
348 // See if we can handle this address.
350 if (!ComputeAddress(I->getOperand(0), Addr))
354 if (!EmitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment()))
356 updateValueMap(I, ResultReg);
360 bool MipsFastISel::SelectStore(const Instruction *I) {
361 Value *Op0 = I->getOperand(0);
364 // Atomic stores need special handling.
365 if (cast<StoreInst>(I)->isAtomic())
368 // Verify we have a legal type before going any further.
370 if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
373 // Get the value to be stored into a register.
374 SrcReg = getRegForValue(Op0);
378 // See if we can handle this address.
380 if (!ComputeAddress(I->getOperand(1), Addr))
383 if (!EmitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment()))
388 bool MipsFastISel::SelectRet(const Instruction *I) {
389 const ReturnInst *Ret = cast<ReturnInst>(I);
391 if (!FuncInfo.CanLowerReturn)
393 if (Ret->getNumOperands() > 0) {
396 EmitInst(Mips::RetRA);
400 // Attempt to fast-select a floating-point extend instruction.
401 bool MipsFastISel::SelectFPExt(const Instruction *I) {
402 if (UnsupportedFPMode)
404 Value *Src = I->getOperand(0);
405 EVT SrcVT = TLI.getValueType(Src->getType(), true);
406 EVT DestVT = TLI.getValueType(I->getType(), true);
408 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
412 getRegForValue(Src); // his must be a 32 bit floating point register class
413 // maybe we should handle this differently
417 unsigned DestReg = createResultReg(&Mips::AFGR64RegClass);
418 EmitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
419 updateValueMap(I, DestReg);
423 // Attempt to fast-select a floating-point truncate instruction.
424 bool MipsFastISel::SelectFPTrunc(const Instruction *I) {
425 if (UnsupportedFPMode)
427 Value *Src = I->getOperand(0);
428 EVT SrcVT = TLI.getValueType(Src->getType(), true);
429 EVT DestVT = TLI.getValueType(I->getType(), true);
431 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
434 unsigned SrcReg = getRegForValue(Src);
438 unsigned DestReg = createResultReg(&Mips::FGR32RegClass);
442 EmitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
443 updateValueMap(I, DestReg);
447 bool MipsFastISel::SelectIntExt(const Instruction *I) {
448 Type *DestTy = I->getType();
449 Value *Src = I->getOperand(0);
450 Type *SrcTy = Src->getType();
452 bool isZExt = isa<ZExtInst>(I);
453 unsigned SrcReg = getRegForValue(Src);
458 SrcEVT = TLI.getValueType(SrcTy, true);
459 DestEVT = TLI.getValueType(DestTy, true);
460 if (!SrcEVT.isSimple())
462 if (!DestEVT.isSimple())
465 MVT SrcVT = SrcEVT.getSimpleVT();
466 MVT DestVT = DestEVT.getSimpleVT();
467 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
469 if (!EmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
471 updateValueMap(I, ResultReg);
475 bool MipsFastISel::SelectTrunc(const Instruction *I) {
476 // The high bits for a type smaller than the register size are assumed to be
478 Value *Op = I->getOperand(0);
481 SrcVT = TLI.getValueType(Op->getType(), true);
482 DestVT = TLI.getValueType(I->getType(), true);
484 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
486 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
489 unsigned SrcReg = getRegForValue(Op);
493 // Because the high bits are undefined, a truncate doesn't generate
495 updateValueMap(I, SrcReg);
499 // Attempt to fast-select a floating-point-to-integer conversion.
500 bool MipsFastISel::SelectFPToI(const Instruction *I, bool IsSigned) {
501 if (UnsupportedFPMode)
505 return false; // We don't handle this case yet. There is no native
506 // instruction for this but it can be synthesized.
507 Type *DstTy = I->getType();
508 if (!isTypeLegal(DstTy, DstVT))
511 if (DstVT != MVT::i32)
514 Value *Src = I->getOperand(0);
515 Type *SrcTy = Src->getType();
516 if (!isTypeLegal(SrcTy, SrcVT))
519 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
522 unsigned SrcReg = getRegForValue(Src);
526 // Determine the opcode for the conversion, which takes place
527 // entirely within FPRs.
528 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
529 unsigned TempReg = createResultReg(&Mips::FGR32RegClass);
532 if (SrcVT == MVT::f32)
533 Opc = Mips::TRUNC_W_S;
535 Opc = Mips::TRUNC_W_D32;
537 // Generate the convert.
538 EmitInst(Opc, TempReg).addReg(SrcReg);
540 EmitInst(Mips::MFC1, DestReg).addReg(TempReg);
542 updateValueMap(I, DestReg);
546 bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
547 if (!TargetSupported)
549 switch (I->getOpcode()) {
552 case Instruction::Load:
553 return SelectLoad(I);
554 case Instruction::Store:
555 return SelectStore(I);
556 case Instruction::Ret:
558 case Instruction::Trunc:
559 return SelectTrunc(I);
560 case Instruction::ZExt:
561 case Instruction::SExt:
562 return SelectIntExt(I);
563 case Instruction::FPTrunc:
564 return SelectFPTrunc(I);
565 case Instruction::FPExt:
566 return SelectFPExt(I);
567 case Instruction::FPToSI:
568 return SelectFPToI(I, /*isSigned*/ true);
569 case Instruction::FPToUI:
570 return SelectFPToI(I, /*isSigned*/ false);
575 unsigned MipsFastISel::MaterializeFP(const ConstantFP *CFP, MVT VT) {
576 if (UnsupportedFPMode)
578 int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
579 if (VT == MVT::f32) {
580 const TargetRegisterClass *RC = &Mips::FGR32RegClass;
581 unsigned DestReg = createResultReg(RC);
582 unsigned TempReg = Materialize32BitInt(Imm, &Mips::GPR32RegClass);
583 EmitInst(Mips::MTC1, DestReg).addReg(TempReg);
585 } else if (VT == MVT::f64) {
586 const TargetRegisterClass *RC = &Mips::AFGR64RegClass;
587 unsigned DestReg = createResultReg(RC);
588 unsigned TempReg1 = Materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);
590 Materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
591 EmitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);
597 unsigned MipsFastISel::MaterializeGV(const GlobalValue *GV, MVT VT) {
598 // For now 32-bit only.
601 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
602 unsigned DestReg = createResultReg(RC);
603 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
604 bool IsThreadLocal = GVar && GVar->isThreadLocal();
605 // TLS not supported at this time.
608 EmitInst(Mips::LW, DestReg)
609 .addReg(MFI->getGlobalBaseReg())
610 .addGlobalAddress(GV, 0, MipsII::MO_GOT);
611 if ((GV->hasInternalLinkage() ||
612 (GV->hasLocalLinkage() && !isa<Function>(GV)))) {
613 unsigned TempReg = createResultReg(RC);
614 EmitInst(Mips::ADDiu, TempReg)
616 .addGlobalAddress(GV, 0, MipsII::MO_ABS_LO);
622 unsigned MipsFastISel::MaterializeInt(const Constant *C, MVT VT) {
623 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
625 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
626 const ConstantInt *CI = cast<ConstantInt>(C);
628 if ((VT != MVT::i1) && CI->isNegative())
629 Imm = CI->getSExtValue();
631 Imm = CI->getZExtValue();
632 return Materialize32BitInt(Imm, RC);
635 unsigned MipsFastISel::Materialize32BitInt(int64_t Imm,
636 const TargetRegisterClass *RC) {
637 unsigned ResultReg = createResultReg(RC);
639 if (isInt<16>(Imm)) {
640 unsigned Opc = Mips::ADDiu;
641 EmitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
643 } else if (isUInt<16>(Imm)) {
644 EmitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);
647 unsigned Lo = Imm & 0xFFFF;
648 unsigned Hi = (Imm >> 16) & 0xFFFF;
650 // Both Lo and Hi have nonzero bits.
651 unsigned TmpReg = createResultReg(RC);
652 EmitInst(Mips::LUi, TmpReg).addImm(Hi);
653 EmitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo);
655 EmitInst(Mips::LUi, ResultReg).addImm(Hi);
662 FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,
663 const TargetLibraryInfo *libInfo) {
664 return new MipsFastISel(funcInfo, libInfo);