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 EmitCmp(unsigned DestReg, const CmpInst *CI);
81 bool SelectLoad(const Instruction *I);
82 bool SelectBranch(const Instruction *I);
83 bool SelectRet(const Instruction *I);
84 bool SelectStore(const Instruction *I);
85 bool SelectIntExt(const Instruction *I);
86 bool SelectTrunc(const Instruction *I);
87 bool SelectFPExt(const Instruction *I);
88 bool SelectFPTrunc(const Instruction *I);
89 bool SelectFPToI(const Instruction *I, bool IsSigned);
90 bool SelectCmp(const Instruction *I);
92 bool isTypeLegal(Type *Ty, MVT &VT);
93 bool isLoadTypeLegal(Type *Ty, MVT &VT);
95 unsigned getRegEnsuringSimpleIntegerWidening(const Value *, bool IsUnsigned);
97 unsigned MaterializeFP(const ConstantFP *CFP, MVT VT);
98 unsigned MaterializeGV(const GlobalValue *GV, MVT VT);
99 unsigned MaterializeInt(const Constant *C, MVT VT);
100 unsigned Materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);
102 bool EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg,
105 bool EmitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
107 bool EmitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
108 bool EmitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
110 bool EmitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
112 // for some reason, this default is not generated by tablegen
113 // so we explicitly generate it here.
115 unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC,
116 unsigned Op0, bool Op0IsKill, uint64_t imm1,
117 uint64_t imm2, unsigned Op3, bool Op3IsKill) {
121 MachineInstrBuilder EmitInst(unsigned Opc) {
122 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
125 MachineInstrBuilder EmitInst(unsigned Opc, unsigned DstReg) {
126 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
130 MachineInstrBuilder EmitInstStore(unsigned Opc, unsigned SrcReg,
131 unsigned MemReg, int64_t MemOffset) {
132 return EmitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset);
135 MachineInstrBuilder EmitInstLoad(unsigned Opc, unsigned DstReg,
136 unsigned MemReg, int64_t MemOffset) {
137 return EmitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);
140 #include "MipsGenFastISel.inc"
143 bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) {
144 EVT evt = TLI.getValueType(Ty, true);
145 // Only handle simple types.
146 if (evt == MVT::Other || !evt.isSimple())
148 VT = evt.getSimpleVT();
150 // Handle all legal types, i.e. a register that will directly hold this
152 return TLI.isTypeLegal(VT);
155 bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
156 if (isTypeLegal(Ty, VT))
158 // We will extend this in a later patch:
159 // If this is a type than can be sign or zero-extended to a basic operation
160 // go ahead and accept it now.
161 if (VT == MVT::i8 || VT == MVT::i16)
166 bool MipsFastISel::ComputeAddress(const Value *Obj, Address &Addr) {
167 // This construct looks a big awkward but it is how other ports handle this
168 // and as this function is more fully completed, these cases which
169 // return false will have additional code in them.
171 if (isa<Instruction>(Obj))
173 else if (isa<ConstantExpr>(Obj))
175 Addr.Base.Reg = getRegForValue(Obj);
176 return Addr.Base.Reg != 0;
179 unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(const Value *V,
181 unsigned VReg = getRegForValue(V);
184 MVT VMVT = TLI.getValueType(V->getType(), true).getSimpleVT();
185 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
186 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
187 if (!EmitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
194 bool MipsFastISel::EmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
195 unsigned Alignment) {
197 // more cases will be handled here in following patches.
200 switch (VT.SimpleTy) {
202 ResultReg = createResultReg(&Mips::GPR32RegClass);
207 ResultReg = createResultReg(&Mips::GPR32RegClass);
212 ResultReg = createResultReg(&Mips::GPR32RegClass);
217 if (UnsupportedFPMode)
219 ResultReg = createResultReg(&Mips::FGR32RegClass);
224 if (UnsupportedFPMode)
226 ResultReg = createResultReg(&Mips::AFGR64RegClass);
233 EmitInstLoad(Opc, ResultReg, Addr.Base.Reg, Addr.Offset);
237 // Materialize a constant into a register, and return the register
238 // number (or zero if we failed to handle it).
239 unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) {
240 EVT CEVT = TLI.getValueType(C->getType(), true);
242 // Only handle simple types.
243 if (!CEVT.isSimple())
245 MVT VT = CEVT.getSimpleVT();
247 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
248 return (UnsupportedFPMode) ? 0 : MaterializeFP(CFP, VT);
249 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
250 return MaterializeGV(GV, VT);
251 else if (isa<ConstantInt>(C))
252 return MaterializeInt(C, VT);
257 bool MipsFastISel::EmitStore(MVT VT, unsigned SrcReg, Address &Addr,
258 unsigned Alignment) {
260 // more cases will be handled here in following patches.
263 switch (VT.SimpleTy) {
274 if (UnsupportedFPMode)
279 if (UnsupportedFPMode)
286 EmitInstStore(Opc, SrcReg, Addr.Base.Reg, Addr.Offset);
290 bool MipsFastISel::EmitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
293 switch (SrcVT.SimpleTy) {
303 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
304 EmitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
305 EmitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
309 bool MipsFastISel::EmitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
311 switch (SrcVT.SimpleTy) {
315 EmitInst(Mips::SEB, DestReg).addReg(SrcReg);
318 EmitInst(Mips::SEH, DestReg).addReg(SrcReg);
324 bool MipsFastISel::EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
325 unsigned DestReg, bool IsZExt) {
327 return EmitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
328 return EmitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
331 bool MipsFastISel::EmitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
333 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
335 if (Subtarget->hasMips32r2())
336 return EmitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
337 return EmitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
340 bool MipsFastISel::EmitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
342 switch (SrcVT.SimpleTy) {
346 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(1);
349 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xff);
352 EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xffff);
359 // This can cause a redundant sltiu to be generated.
360 // FIXME: try and eliminate this in a future patch.
362 bool MipsFastISel::SelectBranch(const Instruction *I) {
363 const BranchInst *BI = cast<BranchInst>(I);
364 MachineBasicBlock *BrBB = FuncInfo.MBB;
366 // TBB is the basic block for the case where the comparison is true.
367 // FBB is the basic block for the case where the comparison is false.
368 // if (cond) goto TBB
372 MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
373 MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
375 // For now, just try the simplest case where it's fed by a compare.
376 if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
377 unsigned CondReg = createResultReg(&Mips::GPR32RegClass);
378 if (!EmitCmp(CondReg, CI))
380 BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::BGTZ))
383 fastEmitBranch(FBB, DbgLoc);
384 FuncInfo.MBB->addSuccessor(TBB);
390 bool MipsFastISel::SelectLoad(const Instruction *I) {
391 // Atomic loads need special handling.
392 if (cast<LoadInst>(I)->isAtomic())
395 // Verify we have a legal type before going any further.
397 if (!isLoadTypeLegal(I->getType(), VT))
400 // See if we can handle this address.
402 if (!ComputeAddress(I->getOperand(0), Addr))
406 if (!EmitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment()))
408 updateValueMap(I, ResultReg);
412 bool MipsFastISel::SelectStore(const Instruction *I) {
413 Value *Op0 = I->getOperand(0);
416 // Atomic stores need special handling.
417 if (cast<StoreInst>(I)->isAtomic())
420 // Verify we have a legal type before going any further.
422 if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
425 // Get the value to be stored into a register.
426 SrcReg = getRegForValue(Op0);
430 // See if we can handle this address.
432 if (!ComputeAddress(I->getOperand(1), Addr))
435 if (!EmitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment()))
440 bool MipsFastISel::SelectRet(const Instruction *I) {
441 const ReturnInst *Ret = cast<ReturnInst>(I);
443 if (!FuncInfo.CanLowerReturn)
445 if (Ret->getNumOperands() > 0) {
448 EmitInst(Mips::RetRA);
452 // Attempt to fast-select a floating-point extend instruction.
453 bool MipsFastISel::SelectFPExt(const Instruction *I) {
454 if (UnsupportedFPMode)
456 Value *Src = I->getOperand(0);
457 EVT SrcVT = TLI.getValueType(Src->getType(), true);
458 EVT DestVT = TLI.getValueType(I->getType(), true);
460 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
464 getRegForValue(Src); // his must be a 32 bit floating point register class
465 // maybe we should handle this differently
469 unsigned DestReg = createResultReg(&Mips::AFGR64RegClass);
470 EmitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
471 updateValueMap(I, DestReg);
475 // Attempt to fast-select a floating-point truncate instruction.
476 bool MipsFastISel::SelectFPTrunc(const Instruction *I) {
477 if (UnsupportedFPMode)
479 Value *Src = I->getOperand(0);
480 EVT SrcVT = TLI.getValueType(Src->getType(), true);
481 EVT DestVT = TLI.getValueType(I->getType(), true);
483 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
486 unsigned SrcReg = getRegForValue(Src);
490 unsigned DestReg = createResultReg(&Mips::FGR32RegClass);
494 EmitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
495 updateValueMap(I, DestReg);
499 bool MipsFastISel::SelectIntExt(const Instruction *I) {
500 Type *DestTy = I->getType();
501 Value *Src = I->getOperand(0);
502 Type *SrcTy = Src->getType();
504 bool isZExt = isa<ZExtInst>(I);
505 unsigned SrcReg = getRegForValue(Src);
510 SrcEVT = TLI.getValueType(SrcTy, true);
511 DestEVT = TLI.getValueType(DestTy, true);
512 if (!SrcEVT.isSimple())
514 if (!DestEVT.isSimple())
517 MVT SrcVT = SrcEVT.getSimpleVT();
518 MVT DestVT = DestEVT.getSimpleVT();
519 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
521 if (!EmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
523 updateValueMap(I, ResultReg);
527 bool MipsFastISel::SelectTrunc(const Instruction *I) {
528 // The high bits for a type smaller than the register size are assumed to be
530 Value *Op = I->getOperand(0);
533 SrcVT = TLI.getValueType(Op->getType(), true);
534 DestVT = TLI.getValueType(I->getType(), true);
536 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
538 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
541 unsigned SrcReg = getRegForValue(Op);
545 // Because the high bits are undefined, a truncate doesn't generate
547 updateValueMap(I, SrcReg);
551 // Attempt to fast-select a floating-point-to-integer conversion.
552 bool MipsFastISel::SelectFPToI(const Instruction *I, bool IsSigned) {
553 if (UnsupportedFPMode)
557 return false; // We don't handle this case yet. There is no native
558 // instruction for this but it can be synthesized.
559 Type *DstTy = I->getType();
560 if (!isTypeLegal(DstTy, DstVT))
563 if (DstVT != MVT::i32)
566 Value *Src = I->getOperand(0);
567 Type *SrcTy = Src->getType();
568 if (!isTypeLegal(SrcTy, SrcVT))
571 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
574 unsigned SrcReg = getRegForValue(Src);
578 // Determine the opcode for the conversion, which takes place
579 // entirely within FPRs.
580 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
581 unsigned TempReg = createResultReg(&Mips::FGR32RegClass);
584 if (SrcVT == MVT::f32)
585 Opc = Mips::TRUNC_W_S;
587 Opc = Mips::TRUNC_W_D32;
589 // Generate the convert.
590 EmitInst(Opc, TempReg).addReg(SrcReg);
592 EmitInst(Mips::MFC1, DestReg).addReg(TempReg);
594 updateValueMap(I, DestReg);
598 // Because of how EmitCmp is called with fast-isel, you can
599 // end up with redundant "andi" instructions after the sequences emitted below.
600 // We should try and solve this issue in the future.
602 bool MipsFastISel::EmitCmp(unsigned ResultReg, const CmpInst *CI) {
603 const Value *Left = CI->getOperand(0), *Right = CI->getOperand(1);
604 bool IsUnsigned = CI->isUnsigned();
605 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned);
608 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(Right, IsUnsigned);
611 CmpInst::Predicate P = CI->getPredicate();
616 case CmpInst::ICMP_EQ: {
617 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
618 EmitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
619 EmitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
622 case CmpInst::ICMP_NE: {
623 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
624 EmitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
625 EmitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
628 case CmpInst::ICMP_UGT: {
629 EmitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
632 case CmpInst::ICMP_ULT: {
633 EmitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
636 case CmpInst::ICMP_UGE: {
637 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
638 EmitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
639 EmitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
642 case CmpInst::ICMP_ULE: {
643 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
644 EmitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
645 EmitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
648 case CmpInst::ICMP_SGT: {
649 EmitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
652 case CmpInst::ICMP_SLT: {
653 EmitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
656 case CmpInst::ICMP_SGE: {
657 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
658 EmitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
659 EmitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
662 case CmpInst::ICMP_SLE: {
663 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
664 EmitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
665 EmitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
668 case CmpInst::FCMP_OEQ:
669 case CmpInst::FCMP_UNE:
670 case CmpInst::FCMP_OLT:
671 case CmpInst::FCMP_OLE:
672 case CmpInst::FCMP_OGT:
673 case CmpInst::FCMP_OGE: {
674 if (UnsupportedFPMode)
676 bool IsFloat = Left->getType()->isFloatTy();
677 bool IsDouble = Left->getType()->isDoubleTy();
678 if (!IsFloat && !IsDouble)
680 unsigned Opc, CondMovOpc;
682 case CmpInst::FCMP_OEQ:
683 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
684 CondMovOpc = Mips::MOVT_I;
686 case CmpInst::FCMP_UNE:
687 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
688 CondMovOpc = Mips::MOVF_I;
690 case CmpInst::FCMP_OLT:
691 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
692 CondMovOpc = Mips::MOVT_I;
694 case CmpInst::FCMP_OLE:
695 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
696 CondMovOpc = Mips::MOVT_I;
698 case CmpInst::FCMP_OGT:
699 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
700 CondMovOpc = Mips::MOVF_I;
702 case CmpInst::FCMP_OGE:
703 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
704 CondMovOpc = Mips::MOVF_I;
707 llvm_unreachable("Only switching of a subset of CCs.");
709 unsigned RegWithZero = createResultReg(&Mips::GPR32RegClass);
710 unsigned RegWithOne = createResultReg(&Mips::GPR32RegClass);
711 EmitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
712 EmitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
713 EmitInst(Opc).addReg(LeftReg).addReg(RightReg).addReg(
714 Mips::FCC0, RegState::ImplicitDefine);
715 MachineInstrBuilder MI = EmitInst(CondMovOpc, ResultReg)
718 .addReg(RegWithZero, RegState::Implicit);
719 MI->tieOperands(0, 3);
726 bool MipsFastISel::SelectCmp(const Instruction *I) {
727 const CmpInst *CI = cast<CmpInst>(I);
728 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
729 if (!EmitCmp(ResultReg, CI))
731 updateValueMap(I, ResultReg);
735 bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
736 if (!TargetSupported)
738 switch (I->getOpcode()) {
741 case Instruction::Load:
742 return SelectLoad(I);
743 case Instruction::Store:
744 return SelectStore(I);
745 case Instruction::Br:
746 return SelectBranch(I);
747 case Instruction::Ret:
749 case Instruction::Trunc:
750 return SelectTrunc(I);
751 case Instruction::ZExt:
752 case Instruction::SExt:
753 return SelectIntExt(I);
754 case Instruction::FPTrunc:
755 return SelectFPTrunc(I);
756 case Instruction::FPExt:
757 return SelectFPExt(I);
758 case Instruction::FPToSI:
759 return SelectFPToI(I, /*isSigned*/ true);
760 case Instruction::FPToUI:
761 return SelectFPToI(I, /*isSigned*/ false);
762 case Instruction::ICmp:
763 case Instruction::FCmp:
769 unsigned MipsFastISel::MaterializeFP(const ConstantFP *CFP, MVT VT) {
770 if (UnsupportedFPMode)
772 int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
773 if (VT == MVT::f32) {
774 const TargetRegisterClass *RC = &Mips::FGR32RegClass;
775 unsigned DestReg = createResultReg(RC);
776 unsigned TempReg = Materialize32BitInt(Imm, &Mips::GPR32RegClass);
777 EmitInst(Mips::MTC1, DestReg).addReg(TempReg);
779 } else if (VT == MVT::f64) {
780 const TargetRegisterClass *RC = &Mips::AFGR64RegClass;
781 unsigned DestReg = createResultReg(RC);
782 unsigned TempReg1 = Materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);
784 Materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
785 EmitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);
791 unsigned MipsFastISel::MaterializeGV(const GlobalValue *GV, MVT VT) {
792 // For now 32-bit only.
795 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
796 unsigned DestReg = createResultReg(RC);
797 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
798 bool IsThreadLocal = GVar && GVar->isThreadLocal();
799 // TLS not supported at this time.
802 EmitInst(Mips::LW, DestReg)
803 .addReg(MFI->getGlobalBaseReg())
804 .addGlobalAddress(GV, 0, MipsII::MO_GOT);
805 if ((GV->hasInternalLinkage() ||
806 (GV->hasLocalLinkage() && !isa<Function>(GV)))) {
807 unsigned TempReg = createResultReg(RC);
808 EmitInst(Mips::ADDiu, TempReg)
810 .addGlobalAddress(GV, 0, MipsII::MO_ABS_LO);
816 unsigned MipsFastISel::MaterializeInt(const Constant *C, MVT VT) {
817 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
819 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
820 const ConstantInt *CI = cast<ConstantInt>(C);
822 if ((VT != MVT::i1) && CI->isNegative())
823 Imm = CI->getSExtValue();
825 Imm = CI->getZExtValue();
826 return Materialize32BitInt(Imm, RC);
829 unsigned MipsFastISel::Materialize32BitInt(int64_t Imm,
830 const TargetRegisterClass *RC) {
831 unsigned ResultReg = createResultReg(RC);
833 if (isInt<16>(Imm)) {
834 unsigned Opc = Mips::ADDiu;
835 EmitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
837 } else if (isUInt<16>(Imm)) {
838 EmitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);
841 unsigned Lo = Imm & 0xFFFF;
842 unsigned Hi = (Imm >> 16) & 0xFFFF;
844 // Both Lo and Hi have nonzero bits.
845 unsigned TmpReg = createResultReg(RC);
846 EmitInst(Mips::LUi, TmpReg).addImm(Hi);
847 EmitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo);
849 EmitInst(Mips::LUi, ResultReg).addImm(Hi);
856 FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,
857 const TargetLibraryInfo *libInfo) {
858 return new MipsFastISel(funcInfo, libInfo);