72#define DEBUG_TYPE "mips-fastisel"
80class MipsFastISel final :
public FastISel {
85 using BaseKind =
enum { RegBase, FrameIndexBase };
88 BaseKind Kind = RegBase;
102 void setKind(BaseKind K) { Kind = K; }
103 BaseKind getKind()
const {
return Kind; }
104 bool isRegBase()
const {
return Kind == RegBase; }
105 bool isFIBase()
const {
return Kind == FrameIndexBase; }
107 void setReg(
unsigned Reg) {
108 assert(isRegBase() &&
"Invalid base register access!");
113 assert(isRegBase() &&
"Invalid base register access!");
117 void setFI(
unsigned FI) {
118 assert(isFIBase() &&
"Invalid base frame index access!");
122 unsigned getFI()
const {
123 assert(isFIBase() &&
"Invalid base frame index access!");
127 void setOffset(int64_t Offset_) {
Offset = Offset_; }
144 bool fastLowerArguments()
override;
145 bool fastLowerCall(CallLoweringInfo &CLI)
override;
148 bool UnsupportedFPMode;
162 bool selectFPToInt(
const Instruction *
I,
bool IsSigned);
167 bool selectDivRem(
const Instruction *
I,
unsigned ISDOpcode);
170 bool isTypeLegal(
Type *Ty,
MVT &VT);
171 bool isTypeSupported(
Type *Ty,
MVT &VT);
172 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
173 bool computeAddress(
const Value *Obj, Address &Addr);
174 bool computeCallAddress(
const Value *V, Address &Addr);
175 void simplifyAddress(Address &Addr);
179 bool emitLoad(
MVT VT,
unsigned &ResultReg, Address &Addr);
181 unsigned emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
bool isZExt);
182 bool emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg,
185 bool emitIntZExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg);
187 bool emitIntSExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg);
188 bool emitIntSExt32r1(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
190 bool emitIntSExt32r2(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
193 unsigned getRegEnsuringSimpleIntegerWidening(
const Value *,
bool IsUnsigned);
195 unsigned emitLogicalOp(
unsigned ISDOpc,
MVT RetVT,
const Value *
LHS,
202 unsigned materializeExternalCallSym(
MCSymbol *Syn);
205 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc));
209 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
214 unsigned MemReg, int64_t MemOffset) {
219 unsigned MemReg, int64_t MemOffset) {
223 unsigned fastEmitInst_rr(
unsigned MachineInstOpcode,
225 unsigned Op0,
unsigned Op1);
240 bool finishCall(CallLoweringInfo &CLI,
MVT RetVT,
unsigned NumBytes);
260 bool fastSelectInstruction(
const Instruction *
I)
override;
262#include "MipsGenFastISel.inc"
286#include "MipsGenCallingConv.inc"
292unsigned MipsFastISel::emitLogicalOp(
unsigned ISDOpc, MVT RetVT,
319 RHSReg = materializeInt(
C, MVT::i32);
321 RHSReg = getRegForValue(
RHS);
325 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
329 emitInst(
Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
333Register MipsFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
335 "Alloca should always return a pointer.");
337 DenseMap<const AllocaInst *, int>::iterator
SI =
338 FuncInfo.StaticAllocaMap.find(AI);
340 if (SI != FuncInfo.StaticAllocaMap.end()) {
341 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
342 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::LEA_ADDiu),
352unsigned MipsFastISel::materializeInt(
const Constant *
C, MVT VT) {
353 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
355 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
360unsigned MipsFastISel::materialize32BitInt(int64_t Imm,
361 const TargetRegisterClass *RC) {
362 Register ResultReg = createResultReg(RC);
365 unsigned Opc = Mips::ADDiu;
366 emitInst(
Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
369 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);
372 unsigned Lo =
Imm & 0xFFFF;
373 unsigned Hi = (
Imm >> 16) & 0xFFFF;
376 Register TmpReg = createResultReg(RC);
377 emitInst(Mips::LUi, TmpReg).addImm(
Hi);
378 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(
Lo);
380 emitInst(Mips::LUi, ResultReg).addImm(
Hi);
385unsigned MipsFastISel::materializeFP(
const ConstantFP *CFP, MVT VT) {
386 if (UnsupportedFPMode)
389 if (VT == MVT::f32) {
390 const TargetRegisterClass *RC = &Mips::FGR32RegClass;
391 Register DestReg = createResultReg(RC);
392 unsigned TempReg = materialize32BitInt(Imm, &Mips::GPR32RegClass);
393 emitInst(Mips::MTC1, DestReg).addReg(TempReg);
395 }
else if (VT == MVT::f64) {
396 const TargetRegisterClass *RC = &Mips::AFGR64RegClass;
397 Register DestReg = createResultReg(RC);
398 unsigned TempReg1 = materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);
400 materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
401 emitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);
407unsigned MipsFastISel::materializeGV(
const GlobalValue *GV, MVT VT) {
411 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
412 Register DestReg = createResultReg(RC);
418 emitInst(Mips::LW, DestReg)
423 Register TempReg = createResultReg(RC);
424 emitInst(Mips::ADDiu, TempReg)
432unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {
433 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
434 Register DestReg = createResultReg(RC);
435 emitInst(Mips::LW, DestReg)
443Register MipsFastISel::fastMaterializeConstant(
const Constant *
C) {
452 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
454 return materializeGV(GV, VT);
456 return materializeInt(
C, VT);
461bool MipsFastISel::computeAddress(
const Value *Obj,
Address &Addr) {
462 const User *
U =
nullptr;
463 unsigned Opcode = Instruction::UserOp1;
467 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
468 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
469 Opcode =
I->getOpcode();
473 Opcode =
C->getOpcode();
479 case Instruction::BitCast:
481 return computeAddress(
U->getOperand(0), Addr);
482 case Instruction::GetElementPtr: {
484 int64_t TmpOffset = Addr.getOffset();
492 const StructLayout *SL =
DL.getStructLayout(STy);
500 TmpOffset += CI->getSExtValue() * S;
503 if (canFoldAddIntoGEP(U,
Op)) {
513 goto unsupported_gep;
518 Addr.setOffset(TmpOffset);
519 if (computeAddress(
U->getOperand(0), Addr))
526 case Instruction::Alloca: {
528 DenseMap<const AllocaInst *, int>::iterator
SI =
529 FuncInfo.StaticAllocaMap.find(AI);
530 if (SI != FuncInfo.StaticAllocaMap.end()) {
531 Addr.setKind(Address::FrameIndexBase);
532 Addr.setFI(
SI->second);
538 Addr.setReg(getRegForValue(Obj));
539 return Addr.getReg() != 0;
542bool MipsFastISel::computeCallAddress(
const Value *V,
Address &Addr) {
543 const User *
U =
nullptr;
544 unsigned Opcode = Instruction::UserOp1;
549 if (
I->getParent() == FuncInfo.MBB->getBasicBlock()) {
550 Opcode =
I->getOpcode();
554 Opcode =
C->getOpcode();
561 case Instruction::BitCast:
563 return computeCallAddress(
U->getOperand(0), Addr);
565 case Instruction::IntToPtr:
569 return computeCallAddress(
U->getOperand(0), Addr);
571 case Instruction::PtrToInt:
574 return computeCallAddress(
U->getOperand(0), Addr);
579 Addr.setGlobalValue(GV);
584 if (!Addr.getGlobalValue()) {
585 Addr.setReg(getRegForValue(V));
586 return Addr.getReg() != 0;
592bool MipsFastISel::isTypeLegal(
Type *Ty, MVT &VT) {
595 if (evt == MVT::Other || !evt.
isSimple())
604bool MipsFastISel::isTypeSupported(
Type *Ty, MVT &VT) {
608 if (isTypeLegal(Ty, VT))
613 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
619bool MipsFastISel::isLoadTypeLegal(
Type *Ty, MVT &VT) {
620 if (isTypeLegal(Ty, VT))
625 if (VT == MVT::i8 || VT == MVT::i16)
634bool MipsFastISel::emitCmp(
unsigned ResultReg,
const CmpInst *CI) {
637 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(
Left, IsUnsigned);
640 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(
Right, IsUnsigned);
649 Register TempReg = createResultReg(&Mips::GPR32RegClass);
650 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
651 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
655 Register TempReg = createResultReg(&Mips::GPR32RegClass);
656 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
657 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
661 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
664 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
667 Register TempReg = createResultReg(&Mips::GPR32RegClass);
668 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
669 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
673 Register TempReg = createResultReg(&Mips::GPR32RegClass);
674 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
675 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
679 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
682 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
685 Register TempReg = createResultReg(&Mips::GPR32RegClass);
686 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
687 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
691 Register TempReg = createResultReg(&Mips::GPR32RegClass);
692 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
693 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
702 if (UnsupportedFPMode)
704 bool IsFloat =
Left->getType()->isFloatTy();
705 bool IsDouble =
Left->getType()->isDoubleTy();
706 if (!IsFloat && !IsDouble)
708 unsigned Opc, CondMovOpc;
711 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
712 CondMovOpc = Mips::MOVT_I;
715 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
716 CondMovOpc = Mips::MOVF_I;
719 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
720 CondMovOpc = Mips::MOVT_I;
723 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
724 CondMovOpc = Mips::MOVT_I;
727 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
728 CondMovOpc = Mips::MOVF_I;
731 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
732 CondMovOpc = Mips::MOVF_I;
737 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);
738 Register RegWithOne = createResultReg(&Mips::GPR32RegClass);
739 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
740 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
743 emitInst(CondMovOpc, ResultReg)
746 .addReg(RegWithZero);
753bool MipsFastISel::emitLoad(MVT VT,
unsigned &ResultReg,
Address &Addr) {
760 ResultReg = createResultReg(&Mips::GPR32RegClass);
764 ResultReg = createResultReg(&Mips::GPR32RegClass);
768 ResultReg = createResultReg(&Mips::GPR32RegClass);
772 if (UnsupportedFPMode)
774 ResultReg = createResultReg(&Mips::FGR32RegClass);
778 if (UnsupportedFPMode)
780 ResultReg = createResultReg(&Mips::AFGR64RegClass);
786 if (Addr.isRegBase()) {
787 simplifyAddress(Addr);
788 emitInstLoad(
Opc, ResultReg, Addr.getReg(), Addr.getOffset());
791 if (Addr.isFIBase()) {
792 unsigned FI = Addr.getFI();
793 int64_t
Offset = Addr.getOffset();
794 MachineFrameInfo &MFI = MF->getFrameInfo();
795 MachineMemOperand *MMO = MF->getMachineMemOperand(
798 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
807bool MipsFastISel::emitStore(MVT VT,
unsigned SrcReg,
Address &Addr) {
823 if (UnsupportedFPMode)
828 if (UnsupportedFPMode)
835 if (Addr.isRegBase()) {
836 simplifyAddress(Addr);
837 emitInstStore(
Opc, SrcReg, Addr.getReg(), Addr.getOffset());
840 if (Addr.isFIBase()) {
841 unsigned FI = Addr.getFI();
842 int64_t
Offset = Addr.getOffset();
843 MachineFrameInfo &MFI = MF->getFrameInfo();
844 MachineMemOperand *MMO = MF->getMachineMemOperand(
847 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
857bool MipsFastISel::selectLogicalOp(
const Instruction *
I) {
859 if (!isTypeSupported(
I->getType(), VT))
863 switch (
I->getOpcode()) {
866 case Instruction::And:
867 ResultReg = emitLogicalOp(
ISD::AND, VT,
I->getOperand(0),
I->getOperand(1));
869 case Instruction::Or:
870 ResultReg = emitLogicalOp(
ISD::OR, VT,
I->getOperand(0),
I->getOperand(1));
872 case Instruction::Xor:
873 ResultReg = emitLogicalOp(
ISD::XOR, VT,
I->getOperand(0),
I->getOperand(1));
880 updateValueMap(
I, ResultReg);
884bool MipsFastISel::selectLoad(
const Instruction *
I) {
893 if (!isLoadTypeLegal(LI->
getType(), VT))
909 updateValueMap(LI, ResultReg);
913bool MipsFastISel::selectStore(
const Instruction *
I) {
916 Value *Op0 =
SI->getOperand(0);
925 if (!isLoadTypeLegal(
SI->getOperand(0)->getType(), VT))
934 SrcReg = getRegForValue(Op0);
940 if (!computeAddress(
SI->getOperand(1), Addr))
950bool MipsFastISel::selectBranch(
const Instruction *
I) {
952 MachineBasicBlock *BrBB = FuncInfo.MBB;
961 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->
getSuccessor(1));
965 unsigned ZExtCondReg = 0;
968 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
975 if (ZExtCondReg == 0) {
980 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32,
true);
981 if (ZExtCondReg == 0)
985 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::BGTZ))
992bool MipsFastISel::selectCmp(
const Instruction *
I) {
994 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
997 updateValueMap(
I, ResultReg);
1002bool MipsFastISel::selectFPExt(
const Instruction *
I) {
1003 if (UnsupportedFPMode)
1005 Value *Src =
I->getOperand(0);
1009 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
1013 getRegForValue(Src);
1018 Register DestReg = createResultReg(&Mips::AFGR64RegClass);
1019 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1020 updateValueMap(
I, DestReg);
1024bool MipsFastISel::selectSelect(
const Instruction *
I) {
1030 if (!isTypeSupported(
I->getType(), VT) || UnsupportedFPMode) {
1032 dbgs() <<
".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1036 unsigned CondMovOpc;
1037 const TargetRegisterClass *RC;
1040 CondMovOpc = Mips::MOVN_I_I;
1041 RC = &Mips::GPR32RegClass;
1042 }
else if (VT == MVT::f32) {
1043 CondMovOpc = Mips::MOVN_I_S;
1044 RC = &Mips::FGR32RegClass;
1045 }
else if (VT == MVT::f64) {
1046 CondMovOpc = Mips::MOVN_I_D32;
1047 RC = &Mips::AFGR64RegClass;
1053 Register Src1Reg = getRegForValue(
SI->getTrueValue());
1054 Register Src2Reg = getRegForValue(
SI->getFalseValue());
1057 if (!Src1Reg || !Src2Reg || !CondReg)
1060 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1064 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg,
true))
1067 Register ResultReg = createResultReg(RC);
1068 Register TempReg = createResultReg(RC);
1070 if (!ResultReg || !TempReg)
1073 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1074 emitInst(CondMovOpc, ResultReg)
1075 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1076 updateValueMap(
I, ResultReg);
1081bool MipsFastISel::selectFPTrunc(
const Instruction *
I) {
1082 if (UnsupportedFPMode)
1084 Value *Src =
I->getOperand(0);
1088 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
1091 Register SrcReg = getRegForValue(Src);
1095 Register DestReg = createResultReg(&Mips::FGR32RegClass);
1099 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1100 updateValueMap(
I, DestReg);
1105bool MipsFastISel::selectFPToInt(
const Instruction *
I,
bool IsSigned) {
1106 if (UnsupportedFPMode)
1112 Type *DstTy =
I->getType();
1113 if (!isTypeLegal(DstTy, DstVT))
1116 if (DstVT != MVT::i32)
1119 Value *Src =
I->getOperand(0);
1120 Type *SrcTy = Src->getType();
1121 if (!isTypeLegal(SrcTy, SrcVT))
1124 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1127 Register SrcReg = getRegForValue(Src);
1133 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1134 Register TempReg = createResultReg(&Mips::FGR32RegClass);
1135 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1138 emitInst(
Opc, TempReg).addReg(SrcReg);
1139 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1141 updateValueMap(
I, DestReg);
1145bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1146 SmallVectorImpl<MVT> &OutVTs,
1147 unsigned &NumBytes) {
1148 CallingConv::ID CC = CLI.CallConv;
1151 for (
const ArgListEntry &Arg : CLI.Args)
1153 CCState CCInfo(CC,
false, *FuncInfo.MF, ArgLocs, *
Context);
1154 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,
1155 CCAssignFnForCall(CC));
1157 NumBytes = CCInfo.getStackSize();
1162 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1165 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1166 CCValAssign &VA = ArgLocs[i];
1172 if (ArgVT == MVT::f32) {
1174 }
else if (ArgVT == MVT::f64) {
1180 }
else if (i == 1) {
1181 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {
1182 if (ArgVT == MVT::f32) {
1184 }
else if (ArgVT == MVT::f64) {
1192 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||
1193 (ArgVT == MVT::i8)) &&
1212 Register ArgReg = getRegForValue(ArgVal);
1224 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
false);
1232 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
true);
1243 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1267 unsigned BEAlign = 0;
1268 if (ArgSize < 8 && !Subtarget->isLittle())
1269 BEAlign = 8 - ArgSize;
1272 Addr.setKind(Address::RegBase);
1273 Addr.setReg(Mips::SP);
1277 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
1289bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,
1290 unsigned NumBytes) {
1291 CallingConv::ID CC = CLI.CallConv;
1292 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1293 if (RetVT != MVT::isVoid) {
1295 MipsCCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *
Context);
1297 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);
1300 if (RVLocs.
size() != 1)
1303 MVT CopyVT = RVLocs[0].getValVT();
1305 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
1311 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1312 TII.get(TargetOpcode::COPY),
1313 ResultReg).
addReg(RVLocs[0].getLocReg());
1314 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1316 CLI.ResultReg = ResultReg;
1317 CLI.NumResultRegs = 1;
1322bool MipsFastISel::fastLowerArguments() {
1325 if (!FuncInfo.CanLowerReturn) {
1331 if (
F->isVarArg()) {
1336 CallingConv::ID CC =
F->getCallingConv();
1337 if (CC != CallingConv::C) {
1338 LLVM_DEBUG(
dbgs() <<
".. gave up (calling convention is not C)\n");
1342 std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,
1344 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1345 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1346 auto NextGPR32 = GPR32ArgRegs.begin();
1347 auto NextFGR32 = FGR32ArgRegs.begin();
1348 auto NextAFGR64 = AFGR64ArgRegs.begin();
1350 struct AllocatedReg {
1351 const TargetRegisterClass *RC;
1353 AllocatedReg(
const TargetRegisterClass *RC,
unsigned Reg)
1360 for (
const auto &FormalArg :
F->args()) {
1361 if (FormalArg.hasAttribute(Attribute::InReg) ||
1362 FormalArg.hasAttribute(Attribute::StructRet) ||
1363 FormalArg.hasAttribute(Attribute::ByVal)) {
1364 LLVM_DEBUG(dbgs() <<
".. gave up (inreg, structret, byval)\n");
1368 Type *ArgTy = FormalArg.getType();
1369 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {
1370 LLVM_DEBUG(dbgs() <<
".. gave up (struct, array, or vector)\n");
1377 if (!ArgVT.isSimple()) {
1378 LLVM_DEBUG(dbgs() <<
".. .. gave up (not a simple type)\n");
1382 switch (ArgVT.getSimpleVT().
SimpleTy) {
1386 if (!FormalArg.hasAttribute(Attribute::SExt) &&
1387 !FormalArg.hasAttribute(Attribute::ZExt)) {
1390 LLVM_DEBUG(dbgs() <<
".. .. gave up (i8/i16 arg is not extended)\n");
1394 if (NextGPR32 == GPR32ArgRegs.end()) {
1395 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1400 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1403 NextFGR32 = FGR32ArgRegs.end();
1404 NextAFGR64 = AFGR64ArgRegs.end();
1408 if (FormalArg.hasAttribute(Attribute::ZExt)) {
1410 LLVM_DEBUG(dbgs() <<
".. .. gave up (i32 arg is zero extended)\n");
1414 if (NextGPR32 == GPR32ArgRegs.end()) {
1415 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1420 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1423 NextFGR32 = FGR32ArgRegs.end();
1424 NextAFGR64 = AFGR64ArgRegs.end();
1428 if (UnsupportedFPMode) {
1432 if (NextFGR32 == FGR32ArgRegs.end()) {
1433 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of FGR32 arguments)\n");
1437 Allocation.
emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1440 if (NextGPR32 != GPR32ArgRegs.end())
1442 if (NextAFGR64 != AFGR64ArgRegs.end())
1447 if (UnsupportedFPMode) {
1451 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1452 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of AFGR64 arguments)\n");
1456 Allocation.
emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1459 if (NextGPR32 != GPR32ArgRegs.end())
1461 if (NextGPR32 != GPR32ArgRegs.end())
1463 if (NextFGR32 != FGR32ArgRegs.end())
1473 for (
const auto &FormalArg :
F->args()) {
1474 unsigned ArgNo = FormalArg.getArgNo();
1475 unsigned SrcReg = Allocation[ArgNo].Reg;
1476 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1480 Register ResultReg = createResultReg(Allocation[ArgNo].RC);
1481 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1482 TII.get(TargetOpcode::COPY), ResultReg)
1483 .addReg(DstReg, getKillRegState(true));
1484 updateValueMap(&FormalArg, ResultReg);
1489 unsigned IncomingArgSizeInBytes = 0;
1494 IncomingArgSizeInBytes = std::min(getABI().GetCalleeAllocdArgSizeInBytes(CC),
1495 IncomingArgSizeInBytes);
1497 MF->getInfo<MipsFunctionInfo>()->setFormalArgInfo(IncomingArgSizeInBytes,
1503bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1504 CallingConv::ID CC = CLI.CallConv;
1505 bool IsTailCall = CLI.IsTailCall;
1506 bool IsVarArg = CLI.IsVarArg;
1511 if (CC == CallingConv::Fast)
1524 if (CLI.RetTy->isVoidTy())
1525 RetVT = MVT::isVoid;
1526 else if (!isTypeSupported(CLI.RetTy, RetVT))
1529 for (
auto Flag : CLI.OutFlags)
1535 OutVTs.
reserve(CLI.OutVals.size());
1537 for (
auto *Val : CLI.OutVals) {
1539 if (!isTypeLegal(Val->getType(), VT) &&
1540 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
1551 if (!computeCallAddress(Callee, Addr))
1556 if (!processCallArgs(CLI, OutVTs, NumBytes))
1559 if (!Addr.getGlobalValue())
1563 unsigned DestAddress;
1565 DestAddress = materializeExternalCallSym(Symbol);
1567 DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);
1568 emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);
1569 MachineInstrBuilder MIB =
1570 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::JALR),
1571 Mips::RA).
addReg(Mips::T9);
1574 for (
auto Reg : CLI.OutRegs)
1589 MIB.
addSym(FuncInfo.MF->getContext().getOrCreateSymbol(
1594 return finishCall(CLI, RetVT, NumBytes);
1597bool MipsFastISel::fastLowerIntrinsicCall(
const IntrinsicInst *
II) {
1598 switch (
II->getIntrinsicID()) {
1601 case Intrinsic::bswap: {
1602 Type *RetTy =
II->getCalledFunction()->getReturnType();
1605 if (!isTypeSupported(RetTy, VT))
1608 Register SrcReg = getRegForValue(
II->getOperand(0));
1611 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1614 if (VT == MVT::i16) {
1616 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1617 updateValueMap(
II, DestReg);
1620 unsigned TempReg[3];
1621 for (
unsigned &R : TempReg) {
1622 R = createResultReg(&Mips::GPR32RegClass);
1626 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1627 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1628 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);
1629 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);
1630 updateValueMap(
II, DestReg);
1633 }
else if (VT == MVT::i32) {
1635 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1636 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1637 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1638 updateValueMap(
II, DestReg);
1641 unsigned TempReg[8];
1642 for (
unsigned &R : TempReg) {
1643 R = createResultReg(&Mips::GPR32RegClass);
1648 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1649 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1650 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1651 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1653 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1654 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1656 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1657 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1658 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1659 updateValueMap(
II, DestReg);
1665 case Intrinsic::memcpy:
1666 case Intrinsic::memmove: {
1669 if (MTI->isVolatile())
1671 if (!MTI->getLength()->getType()->isIntegerTy(32))
1674 return lowerCallTo(
II, IntrMemName,
II->arg_size() - 1);
1676 case Intrinsic::memset: {
1683 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
1689bool MipsFastISel::selectRet(
const Instruction *
I) {
1690 const Function &
F = *
I->getParent()->getParent();
1695 if (!FuncInfo.CanLowerReturn)
1699 SmallVector<unsigned, 4> RetRegs;
1701 if (
Ret->getNumOperands() > 0) {
1702 CallingConv::ID CC =
F.getCallingConv();
1705 if (CC == CallingConv::Fast)
1713 MipsCCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
1716 CCInfo.AnalyzeReturn(Outs, RetCC);
1719 if (ValLocs.
size() != 1)
1722 CCValAssign &VA = ValLocs[0];
1723 const Value *RV =
Ret->getOperand(0);
1741 if (!
MRI.getRegClass(SrcReg)->contains(DestReg))
1752 if (RVVT == MVT::f128)
1756 if (RVVT == MVT::f64 && UnsupportedFPMode) {
1763 if (RVVT != DestVT) {
1764 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
1767 if (Outs[0].
Flags.isZExt() || Outs[0].Flags.isSExt()) {
1768 bool IsZExt = Outs[0].Flags.isZExt();
1769 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1776 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1777 TII.get(TargetOpcode::COPY), DestReg).
addReg(SrcReg);
1782 MachineInstrBuilder MIB = emitInst(Mips::RetRA);
1783 for (
unsigned Reg : RetRegs)
1788bool MipsFastISel::selectTrunc(
const Instruction *
I) {
1797 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1799 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1808 updateValueMap(
I, SrcReg);
1812bool MipsFastISel::selectIntExt(
const Instruction *
I) {
1813 Type *DestTy =
I->getType();
1814 Value *Src =
I->getOperand(0);
1815 Type *SrcTy = Src->getType();
1818 Register SrcReg = getRegForValue(Src);
1822 EVT SrcEVT, DestEVT;
1832 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1834 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1836 updateValueMap(
I, ResultReg);
1840bool MipsFastISel::emitIntSExt32r1(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1853 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1854 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1855 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1859bool MipsFastISel::emitIntSExt32r2(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1865 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1868 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1874bool MipsFastISel::emitIntSExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1876 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
1879 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1880 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1883bool MipsFastISel::emitIntZExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1901 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);
1905bool MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1906 unsigned DestReg,
bool IsZExt) {
1911 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||
1912 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))
1915 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1916 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1919unsigned MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1921 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1922 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1926bool MipsFastISel::selectDivRem(
const Instruction *
I,
unsigned ISDOpcode) {
1932 if (DestVT != MVT::i32)
1936 switch (ISDOpcode) {
1941 DivOpc = Mips::SDIV;
1945 DivOpc = Mips::UDIV;
1949 Register Src0Reg = getRegForValue(
I->getOperand(0));
1950 Register Src1Reg = getRegForValue(
I->getOperand(1));
1951 if (!Src0Reg || !Src1Reg)
1954 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1957 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1960 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1967 emitInst(MFOpc, ResultReg);
1969 updateValueMap(
I, ResultReg);
1973bool MipsFastISel::selectShift(
const Instruction *
I) {
1976 if (!isTypeSupported(
I->getType(), RetVT))
1979 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1983 unsigned Opcode =
I->getOpcode();
1984 const Value *Op0 =
I->getOperand(0);
1985 Register Op0Reg = getRegForValue(Op0);
1990 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1991 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1996 bool IsZExt = Opcode == Instruction::LShr;
1997 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))
2004 uint64_t ShiftVal =
C->getZExtValue();
2009 case Instruction::Shl:
2012 case Instruction::AShr:
2015 case Instruction::LShr:
2020 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2021 updateValueMap(
I, ResultReg);
2025 Register Op1Reg = getRegForValue(
I->getOperand(1));
2032 case Instruction::Shl:
2033 Opcode = Mips::SLLV;
2035 case Instruction::AShr:
2036 Opcode = Mips::SRAV;
2038 case Instruction::LShr:
2039 Opcode = Mips::SRLV;
2043 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2044 updateValueMap(
I, ResultReg);
2048bool MipsFastISel::fastSelectInstruction(
const Instruction *
I) {
2049 switch (
I->getOpcode()) {
2052 case Instruction::Load:
2053 return selectLoad(
I);
2054 case Instruction::Store:
2055 return selectStore(
I);
2056 case Instruction::SDiv:
2060 case Instruction::UDiv:
2064 case Instruction::SRem:
2068 case Instruction::URem:
2072 case Instruction::Shl:
2073 case Instruction::LShr:
2074 case Instruction::AShr:
2075 return selectShift(
I);
2076 case Instruction::And:
2077 case Instruction::Or:
2078 case Instruction::Xor:
2079 return selectLogicalOp(
I);
2080 case Instruction::Br:
2081 return selectBranch(
I);
2082 case Instruction::Ret:
2083 return selectRet(
I);
2084 case Instruction::Trunc:
2085 return selectTrunc(
I);
2086 case Instruction::ZExt:
2087 case Instruction::SExt:
2088 return selectIntExt(
I);
2089 case Instruction::FPTrunc:
2090 return selectFPTrunc(
I);
2091 case Instruction::FPExt:
2092 return selectFPExt(
I);
2093 case Instruction::FPToSI:
2094 return selectFPToInt(
I,
true);
2095 case Instruction::FPToUI:
2096 return selectFPToInt(
I,
false);
2097 case Instruction::ICmp:
2098 case Instruction::FCmp:
2099 return selectCmp(
I);
2100 case Instruction::Select:
2101 return selectSelect(
I);
2106unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(
const Value *V,
2113 if (VMVT == MVT::i1)
2116 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
2117 Register TempReg = createResultReg(&Mips::GPR32RegClass);
2118 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
2125void MipsFastISel::simplifyAddress(
Address &Addr) {
2128 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
2129 Register DestReg = createResultReg(&Mips::GPR32RegClass);
2130 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());
2131 Addr.setReg(DestReg);
2136unsigned MipsFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2137 const TargetRegisterClass *RC,
2138 unsigned Op0,
unsigned Op1) {
2145 if (MachineInstOpcode == Mips::MUL) {
2146 Register ResultReg = createResultReg(RC);
2147 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
2150 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
2165 return new MipsFastISel(funcInfo, libInfo);
unsigned const MachineRegisterInfo * MRI
static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
Select the AArch64 opcode for the basic binary operation GenericOpc (such as G_OR or G_SDIV),...
static void emitLoad(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPostDec)
Emit a load-pair instruction for frame-destroy.
static void emitStore(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPreDec)
Emit a store-pair instruction for frame-setup.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the FastISel class.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
cl::opt< bool > EmitJalrReloc
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State, ArrayRef< MCPhysReg > F64Regs)
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
This file describes how to lower LLVM code to machine code.
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
an instruction to allocate memory on the stack
PointerType * getType() const
Overload to return most specific pointer type.
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
CCState - This class holds information needed while lowering arguments and return values.
void convertToReg(MCRegister Reg)
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
unsigned getValNo() const
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
Predicate getPredicate() const
Return the predicate for this instruction.
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Register fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0, Register Op1)
Emit a MachineInstr with two register operands and a result register in the given register class.
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasLocalLinkage() const
bool hasInternalLinkage() const
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Align getAlign() const
Return the alignment of the access that is being performed.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Value * getLength() const
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
Register getGlobalBaseReg(MachineFunction &MF)
bool useSoftFloat() const
const MipsInstrInfo * getInstrInfo() const override
bool inMips16Mode() const
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
const MipsTargetLowering * getTargetLowering() const override
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
TypeSize getElementOffset(unsigned Idx) const
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
const Use * const_op_iterator
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ AND
Bitwise operators - logical and, logical or, logical xor.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
generic_gep_type_iterator<> gep_type_iterator
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool isVector() const
Return true if this is a vector value type.
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.