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 class MipsFastISel final : public FastISel {
23 // All possible address modes.
26 typedef enum { RegBase, FrameIndexBase } BaseKind;
37 const GlobalValue *GV;
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!");
49 unsigned getReg() const {
50 assert(isRegBase() && "Invalid base register access!");
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; }
59 /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
60 /// make the right decision when generating code for different targets.
62 const TargetMachine &TM;
63 const TargetInstrInfo &TII;
64 const TargetLowering &TLI;
65 const MipsSubtarget *Subtarget;
66 MipsFunctionInfo *MFI;
68 // Convenience variables to avoid some queries.
72 bool UnsupportedFPMode; // To allow fast-isel to proceed and just not handle
73 // floating point but not reject doing fast-isel in other
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);
89 // Utility helper routines.
91 bool isTypeLegal(Type *Ty, MVT &VT);
92 bool isLoadTypeLegal(Type *Ty, MVT &VT);
93 bool computeAddress(const Value *Obj, Address &Addr);
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,
104 bool emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
106 bool emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
107 bool emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
109 bool emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
112 unsigned getRegEnsuringSimpleIntegerWidening(const Value *, bool IsUnsigned);
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);
119 MachineInstrBuilder emitInst(unsigned Opc) {
120 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
122 MachineInstrBuilder emitInst(unsigned Opc, unsigned DstReg) {
123 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
126 MachineInstrBuilder emitInstStore(unsigned Opc, unsigned SrcReg,
127 unsigned MemReg, int64_t MemOffset) {
128 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);
134 // for some reason, this default is not generated by tablegen
135 // so we explicitly generate it here.
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) {
144 // Backend specific FastISel code.
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();
162 unsigned fastMaterializeConstant(const Constant *C) override;
163 bool fastSelectInstruction(const Instruction *I) override;
165 #include "MipsGenFastISel.inc"
167 } // end anonymous namespace.
169 bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) {
170 EVT evt = TLI.getValueType(Ty, true);
171 // Only handle simple types.
172 if (evt == MVT::Other || !evt.isSimple())
174 VT = evt.getSimpleVT();
176 // Handle all legal types, i.e. a register that will directly hold this
178 return TLI.isTypeLegal(VT);
181 bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
182 if (isTypeLegal(Ty, VT))
184 // We will extend this in a later patch:
185 // If this is a type than can be sign or zero-extended to a basic operation
186 // go ahead and accept it now.
187 if (VT == MVT::i8 || VT == MVT::i16)
192 bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {
193 // This construct looks a big awkward but it is how other ports handle this
194 // and as this function is more fully completed, these cases which
195 // return false will have additional code in them.
197 if (isa<Instruction>(Obj))
199 else if (isa<ConstantExpr>(Obj))
201 Addr.setReg(getRegForValue(Obj));
202 return Addr.getReg() != 0;
205 unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(const Value *V,
207 unsigned VReg = getRegForValue(V);
210 MVT VMVT = TLI.getValueType(V->getType(), true).getSimpleVT();
211 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
212 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
213 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
220 bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
221 unsigned Alignment) {
223 // more cases will be handled here in following patches.
226 switch (VT.SimpleTy) {
228 ResultReg = createResultReg(&Mips::GPR32RegClass);
233 ResultReg = createResultReg(&Mips::GPR32RegClass);
238 ResultReg = createResultReg(&Mips::GPR32RegClass);
243 if (UnsupportedFPMode)
245 ResultReg = createResultReg(&Mips::FGR32RegClass);
250 if (UnsupportedFPMode)
252 ResultReg = createResultReg(&Mips::AFGR64RegClass);
259 emitInstLoad(Opc, ResultReg, Addr.getReg(), Addr.getOffset());
263 // Materialize a constant into a register, and return the register
264 // number (or zero if we failed to handle it).
265 unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) {
266 EVT CEVT = TLI.getValueType(C->getType(), true);
268 // Only handle simple types.
269 if (!CEVT.isSimple())
271 MVT VT = CEVT.getSimpleVT();
273 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
274 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
275 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
276 return materializeGV(GV, VT);
277 else if (isa<ConstantInt>(C))
278 return materializeInt(C, VT);
283 bool MipsFastISel::emitStore(MVT VT, unsigned SrcReg, Address &Addr,
284 unsigned Alignment) {
286 // more cases will be handled here in following patches.
289 switch (VT.SimpleTy) {
300 if (UnsupportedFPMode)
305 if (UnsupportedFPMode)
312 emitInstStore(Opc, SrcReg, Addr.getReg(), Addr.getOffset());
316 bool MipsFastISel::emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
319 switch (SrcVT.SimpleTy) {
329 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
330 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
331 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
335 bool MipsFastISel::emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
337 switch (SrcVT.SimpleTy) {
341 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
344 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
350 bool MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
351 unsigned DestReg, bool IsZExt) {
353 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
354 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
357 bool MipsFastISel::emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
359 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
361 if (Subtarget->hasMips32r2())
362 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
363 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
366 bool MipsFastISel::emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
368 switch (SrcVT.SimpleTy) {
372 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(1);
375 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xff);
378 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xffff);
385 // This can cause a redundant sltiu to be generated.
386 // FIXME: try and eliminate this in a future patch.
388 bool MipsFastISel::selectBranch(const Instruction *I) {
389 const BranchInst *BI = cast<BranchInst>(I);
390 MachineBasicBlock *BrBB = FuncInfo.MBB;
392 // TBB is the basic block for the case where the comparison is true.
393 // FBB is the basic block for the case where the comparison is false.
394 // if (cond) goto TBB
398 MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
399 MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
401 // For now, just try the simplest case where it's fed by a compare.
402 if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
403 unsigned CondReg = createResultReg(&Mips::GPR32RegClass);
404 if (!emitCmp(CondReg, CI))
406 BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::BGTZ))
409 fastEmitBranch(FBB, DbgLoc);
410 FuncInfo.MBB->addSuccessor(TBB);
416 bool MipsFastISel::selectLoad(const Instruction *I) {
417 // Atomic loads need special handling.
418 if (cast<LoadInst>(I)->isAtomic())
421 // Verify we have a legal type before going any further.
423 if (!isLoadTypeLegal(I->getType(), VT))
426 // See if we can handle this address.
428 if (!computeAddress(I->getOperand(0), Addr))
432 if (!emitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment()))
434 updateValueMap(I, ResultReg);
438 bool MipsFastISel::selectStore(const Instruction *I) {
439 Value *Op0 = I->getOperand(0);
442 // Atomic stores need special handling.
443 if (cast<StoreInst>(I)->isAtomic())
446 // Verify we have a legal type before going any further.
448 if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
451 // Get the value to be stored into a register.
452 SrcReg = getRegForValue(Op0);
456 // See if we can handle this address.
458 if (!computeAddress(I->getOperand(1), Addr))
461 if (!emitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment()))
466 bool MipsFastISel::selectRet(const Instruction *I) {
467 const ReturnInst *Ret = cast<ReturnInst>(I);
469 if (!FuncInfo.CanLowerReturn)
471 if (Ret->getNumOperands() > 0) {
474 emitInst(Mips::RetRA);
478 // Attempt to fast-select a floating-point extend instruction.
479 bool MipsFastISel::selectFPExt(const Instruction *I) {
480 if (UnsupportedFPMode)
482 Value *Src = I->getOperand(0);
483 EVT SrcVT = TLI.getValueType(Src->getType(), true);
484 EVT DestVT = TLI.getValueType(I->getType(), true);
486 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
490 getRegForValue(Src); // his must be a 32 bit floating point register class
491 // maybe we should handle this differently
495 unsigned DestReg = createResultReg(&Mips::AFGR64RegClass);
496 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
497 updateValueMap(I, DestReg);
501 // Attempt to fast-select a floating-point truncate instruction.
502 bool MipsFastISel::selectFPTrunc(const Instruction *I) {
503 if (UnsupportedFPMode)
505 Value *Src = I->getOperand(0);
506 EVT SrcVT = TLI.getValueType(Src->getType(), true);
507 EVT DestVT = TLI.getValueType(I->getType(), true);
509 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
512 unsigned SrcReg = getRegForValue(Src);
516 unsigned DestReg = createResultReg(&Mips::FGR32RegClass);
520 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
521 updateValueMap(I, DestReg);
525 bool MipsFastISel::selectIntExt(const Instruction *I) {
526 Type *DestTy = I->getType();
527 Value *Src = I->getOperand(0);
528 Type *SrcTy = Src->getType();
530 bool isZExt = isa<ZExtInst>(I);
531 unsigned SrcReg = getRegForValue(Src);
536 SrcEVT = TLI.getValueType(SrcTy, true);
537 DestEVT = TLI.getValueType(DestTy, true);
538 if (!SrcEVT.isSimple())
540 if (!DestEVT.isSimple())
543 MVT SrcVT = SrcEVT.getSimpleVT();
544 MVT DestVT = DestEVT.getSimpleVT();
545 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
547 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
549 updateValueMap(I, ResultReg);
553 bool MipsFastISel::selectTrunc(const Instruction *I) {
554 // The high bits for a type smaller than the register size are assumed to be
556 Value *Op = I->getOperand(0);
559 SrcVT = TLI.getValueType(Op->getType(), true);
560 DestVT = TLI.getValueType(I->getType(), true);
562 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
564 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
567 unsigned SrcReg = getRegForValue(Op);
571 // Because the high bits are undefined, a truncate doesn't generate
573 updateValueMap(I, SrcReg);
577 // Attempt to fast-select a floating-point-to-integer conversion.
578 bool MipsFastISel::selectFPToInt(const Instruction *I, bool IsSigned) {
579 if (UnsupportedFPMode)
583 return false; // We don't handle this case yet. There is no native
584 // instruction for this but it can be synthesized.
585 Type *DstTy = I->getType();
586 if (!isTypeLegal(DstTy, DstVT))
589 if (DstVT != MVT::i32)
592 Value *Src = I->getOperand(0);
593 Type *SrcTy = Src->getType();
594 if (!isTypeLegal(SrcTy, SrcVT))
597 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
600 unsigned SrcReg = getRegForValue(Src);
604 // Determine the opcode for the conversion, which takes place
605 // entirely within FPRs.
606 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
607 unsigned TempReg = createResultReg(&Mips::FGR32RegClass);
610 if (SrcVT == MVT::f32)
611 Opc = Mips::TRUNC_W_S;
613 Opc = Mips::TRUNC_W_D32;
615 // Generate the convert.
616 emitInst(Opc, TempReg).addReg(SrcReg);
618 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
620 updateValueMap(I, DestReg);
624 // Because of how EmitCmp is called with fast-isel, you can
625 // end up with redundant "andi" instructions after the sequences emitted below.
626 // We should try and solve this issue in the future.
628 bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) {
629 const Value *Left = CI->getOperand(0), *Right = CI->getOperand(1);
630 bool IsUnsigned = CI->isUnsigned();
631 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned);
634 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(Right, IsUnsigned);
637 CmpInst::Predicate P = CI->getPredicate();
642 case CmpInst::ICMP_EQ: {
643 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
644 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
645 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
648 case CmpInst::ICMP_NE: {
649 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
650 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
651 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
654 case CmpInst::ICMP_UGT: {
655 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
658 case CmpInst::ICMP_ULT: {
659 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
662 case CmpInst::ICMP_UGE: {
663 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
664 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
665 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
668 case CmpInst::ICMP_ULE: {
669 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
670 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
671 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
674 case CmpInst::ICMP_SGT: {
675 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
678 case CmpInst::ICMP_SLT: {
679 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
682 case CmpInst::ICMP_SGE: {
683 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
684 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
685 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
688 case CmpInst::ICMP_SLE: {
689 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
690 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
691 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
694 case CmpInst::FCMP_OEQ:
695 case CmpInst::FCMP_UNE:
696 case CmpInst::FCMP_OLT:
697 case CmpInst::FCMP_OLE:
698 case CmpInst::FCMP_OGT:
699 case CmpInst::FCMP_OGE: {
700 if (UnsupportedFPMode)
702 bool IsFloat = Left->getType()->isFloatTy();
703 bool IsDouble = Left->getType()->isDoubleTy();
704 if (!IsFloat && !IsDouble)
706 unsigned Opc, CondMovOpc;
708 case CmpInst::FCMP_OEQ:
709 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
710 CondMovOpc = Mips::MOVT_I;
712 case CmpInst::FCMP_UNE:
713 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
714 CondMovOpc = Mips::MOVF_I;
716 case CmpInst::FCMP_OLT:
717 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
718 CondMovOpc = Mips::MOVT_I;
720 case CmpInst::FCMP_OLE:
721 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
722 CondMovOpc = Mips::MOVT_I;
724 case CmpInst::FCMP_OGT:
725 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
726 CondMovOpc = Mips::MOVF_I;
728 case CmpInst::FCMP_OGE:
729 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
730 CondMovOpc = Mips::MOVF_I;
733 llvm_unreachable("Only switching of a subset of CCs.");
735 unsigned RegWithZero = createResultReg(&Mips::GPR32RegClass);
736 unsigned RegWithOne = createResultReg(&Mips::GPR32RegClass);
737 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
738 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
739 emitInst(Opc).addReg(LeftReg).addReg(RightReg).addReg(
740 Mips::FCC0, RegState::ImplicitDefine);
741 MachineInstrBuilder MI = emitInst(CondMovOpc, ResultReg)
744 .addReg(RegWithZero, RegState::Implicit);
745 MI->tieOperands(0, 3);
752 bool MipsFastISel::selectCmp(const Instruction *I) {
753 const CmpInst *CI = cast<CmpInst>(I);
754 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
755 if (!emitCmp(ResultReg, CI))
757 updateValueMap(I, ResultReg);
761 bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
762 if (!TargetSupported)
764 switch (I->getOpcode()) {
767 case Instruction::Load:
768 return selectLoad(I);
769 case Instruction::Store:
770 return selectStore(I);
771 case Instruction::Br:
772 return selectBranch(I);
773 case Instruction::Ret:
775 case Instruction::Trunc:
776 return selectTrunc(I);
777 case Instruction::ZExt:
778 case Instruction::SExt:
779 return selectIntExt(I);
780 case Instruction::FPTrunc:
781 return selectFPTrunc(I);
782 case Instruction::FPExt:
783 return selectFPExt(I);
784 case Instruction::FPToSI:
785 return selectFPToInt(I, /*isSigned*/ true);
786 case Instruction::FPToUI:
787 return selectFPToInt(I, /*isSigned*/ false);
788 case Instruction::ICmp:
789 case Instruction::FCmp:
795 unsigned MipsFastISel::materializeFP(const ConstantFP *CFP, MVT VT) {
796 if (UnsupportedFPMode)
798 int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
799 if (VT == MVT::f32) {
800 const TargetRegisterClass *RC = &Mips::FGR32RegClass;
801 unsigned DestReg = createResultReg(RC);
802 unsigned TempReg = materialize32BitInt(Imm, &Mips::GPR32RegClass);
803 emitInst(Mips::MTC1, DestReg).addReg(TempReg);
805 } else if (VT == MVT::f64) {
806 const TargetRegisterClass *RC = &Mips::AFGR64RegClass;
807 unsigned DestReg = createResultReg(RC);
808 unsigned TempReg1 = materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);
810 materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
811 emitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);
817 unsigned MipsFastISel::materializeGV(const GlobalValue *GV, MVT VT) {
818 // For now 32-bit only.
821 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
822 unsigned DestReg = createResultReg(RC);
823 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
824 bool IsThreadLocal = GVar && GVar->isThreadLocal();
825 // TLS not supported at this time.
828 emitInst(Mips::LW, DestReg)
829 .addReg(MFI->getGlobalBaseReg())
830 .addGlobalAddress(GV, 0, MipsII::MO_GOT);
831 if ((GV->hasInternalLinkage() ||
832 (GV->hasLocalLinkage() && !isa<Function>(GV)))) {
833 unsigned TempReg = createResultReg(RC);
834 emitInst(Mips::ADDiu, TempReg)
836 .addGlobalAddress(GV, 0, MipsII::MO_ABS_LO);
842 unsigned MipsFastISel::materializeInt(const Constant *C, MVT VT) {
843 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
845 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
846 const ConstantInt *CI = cast<ConstantInt>(C);
848 if ((VT != MVT::i1) && CI->isNegative())
849 Imm = CI->getSExtValue();
851 Imm = CI->getZExtValue();
852 return materialize32BitInt(Imm, RC);
855 unsigned MipsFastISel::materialize32BitInt(int64_t Imm,
856 const TargetRegisterClass *RC) {
857 unsigned ResultReg = createResultReg(RC);
859 if (isInt<16>(Imm)) {
860 unsigned Opc = Mips::ADDiu;
861 emitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
863 } else if (isUInt<16>(Imm)) {
864 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);
867 unsigned Lo = Imm & 0xFFFF;
868 unsigned Hi = (Imm >> 16) & 0xFFFF;
870 // Both Lo and Hi have nonzero bits.
871 unsigned TmpReg = createResultReg(RC);
872 emitInst(Mips::LUi, TmpReg).addImm(Hi);
873 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo);
875 emitInst(Mips::LUi, ResultReg).addImm(Hi);
881 FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,
882 const TargetLibraryInfo *libInfo) {
883 return new MipsFastISel(funcInfo, libInfo);