71#define DEBUG_TYPE "mips-fastisel"
80class MipsFastISel final :
public FastISel {
85 enum BaseKind { 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);
249 :
FastISel(funcInfo, libInfo, libcallLowering),
260 bool fastSelectInstruction(
const Instruction *
I)
override;
262#include "MipsGenFastISel.inc"
286#define GET_CALLING_CONV_IMPL
287#include "MipsGenCallingConv.inc"
293unsigned MipsFastISel::emitLogicalOp(
unsigned ISDOpc, MVT RetVT,
320 RHSReg = materializeInt(
C, MVT::i32);
322 RHSReg = getRegForValue(
RHS);
326 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
330 emitInst(
Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
334Register MipsFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
336 "Alloca should always return a pointer.");
338 auto SI = 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)
360unsigned MipsFastISel::materialize32BitInt(int64_t
Imm,
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) {
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) {
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) {
412 Register DestReg = createResultReg(RC);
418 emitInst(Mips::LW, DestReg)
422 Register TempReg = createResultReg(RC);
423 emitInst(Mips::ADDiu, TempReg)
431unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {
433 Register DestReg = createResultReg(RC);
434 emitInst(Mips::LW, DestReg)
442Register MipsFastISel::fastMaterializeConstant(
const Constant *
C) {
451 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
453 return materializeGV(GV, VT);
455 return materializeInt(
C, VT);
460bool MipsFastISel::computeAddress(
const Value *Obj,
Address &Addr) {
461 const User *
U =
nullptr;
462 unsigned Opcode = Instruction::UserOp1;
466 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
467 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
468 Opcode =
I->getOpcode();
472 Opcode =
C->getOpcode();
478 case Instruction::BitCast:
480 return computeAddress(
U->getOperand(0), Addr);
481 case Instruction::GetElementPtr: {
483 int64_t TmpOffset = Addr.getOffset();
491 const StructLayout *SL =
DL.getStructLayout(STy);
499 TmpOffset += CI->getSExtValue() * S;
502 if (canFoldAddIntoGEP(U,
Op)) {
512 goto unsupported_gep;
517 Addr.setOffset(TmpOffset);
518 if (computeAddress(
U->getOperand(0), Addr))
525 case Instruction::Alloca: {
527 auto SI = FuncInfo.StaticAllocaMap.find(AI);
528 if (SI != FuncInfo.StaticAllocaMap.end()) {
529 Addr.setKind(Address::FrameIndexBase);
530 Addr.setFI(
SI->second);
536 Addr.setReg(getRegForValue(Obj));
537 return Addr.getReg() != 0;
540bool MipsFastISel::computeCallAddress(
const Value *V,
Address &Addr) {
541 const User *
U =
nullptr;
542 unsigned Opcode = Instruction::UserOp1;
547 if (
I->getParent() == FuncInfo.MBB->getBasicBlock()) {
548 Opcode =
I->getOpcode();
552 Opcode =
C->getOpcode();
559 case Instruction::BitCast:
561 return computeCallAddress(
U->getOperand(0), Addr);
563 case Instruction::IntToPtr:
567 return computeCallAddress(
U->getOperand(0), Addr);
569 case Instruction::PtrToInt:
572 return computeCallAddress(
U->getOperand(0), Addr);
577 Addr.setGlobalValue(GV);
582 if (!Addr.getGlobalValue()) {
583 Addr.setReg(getRegForValue(V));
584 return Addr.getReg() != 0;
590bool MipsFastISel::isTypeLegal(
Type *Ty, MVT &VT) {
593 if (evt == MVT::Other || !evt.
isSimple())
602bool MipsFastISel::isTypeSupported(
Type *Ty, MVT &VT) {
606 if (isTypeLegal(Ty, VT))
611 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
617bool MipsFastISel::isLoadTypeLegal(
Type *Ty, MVT &VT) {
618 if (isTypeLegal(Ty, VT))
623 if (VT == MVT::i8 || VT == MVT::i16)
632bool MipsFastISel::emitCmp(
unsigned ResultReg,
const CmpInst *CI) {
635 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(
Left, IsUnsigned);
638 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(
Right, IsUnsigned);
647 Register TempReg = createResultReg(&Mips::GPR32RegClass);
648 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
649 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
653 Register TempReg = createResultReg(&Mips::GPR32RegClass);
654 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
655 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
659 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
662 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
665 Register TempReg = createResultReg(&Mips::GPR32RegClass);
666 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
667 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
671 Register TempReg = createResultReg(&Mips::GPR32RegClass);
672 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
673 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
677 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
680 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
683 Register TempReg = createResultReg(&Mips::GPR32RegClass);
684 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
685 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
689 Register TempReg = createResultReg(&Mips::GPR32RegClass);
690 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
691 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
700 if (UnsupportedFPMode)
702 bool IsFloat =
Left->getType()->isFloatTy();
703 bool IsDouble =
Left->getType()->isDoubleTy();
704 if (!IsFloat && !IsDouble)
706 unsigned Opc, CondMovOpc;
709 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
710 CondMovOpc = Mips::MOVT_I;
713 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
714 CondMovOpc = Mips::MOVF_I;
717 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
718 CondMovOpc = Mips::MOVT_I;
721 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
722 CondMovOpc = Mips::MOVT_I;
725 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
726 CondMovOpc = Mips::MOVF_I;
729 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
730 CondMovOpc = Mips::MOVF_I;
735 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);
736 Register 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(Mips::FCC0, RegState::Define).addReg(LeftReg)
741 emitInst(CondMovOpc, ResultReg)
744 .addReg(RegWithZero);
751bool MipsFastISel::emitLoad(MVT VT,
unsigned &ResultReg,
Address &Addr) {
758 ResultReg = createResultReg(&Mips::GPR32RegClass);
762 ResultReg = createResultReg(&Mips::GPR32RegClass);
766 ResultReg = createResultReg(&Mips::GPR32RegClass);
770 if (UnsupportedFPMode)
772 ResultReg = createResultReg(&Mips::FGR32RegClass);
776 if (UnsupportedFPMode)
778 ResultReg = createResultReg(&Mips::AFGR64RegClass);
784 if (Addr.isRegBase()) {
785 simplifyAddress(Addr);
786 emitInstLoad(
Opc, ResultReg, Addr.getReg(), Addr.getOffset());
789 if (Addr.isFIBase()) {
790 unsigned FI = Addr.getFI();
791 int64_t
Offset = Addr.getOffset();
792 MachineFrameInfo &MFI = MF->getFrameInfo();
793 MachineMemOperand *MMO = MF->getMachineMemOperand(
796 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
805bool MipsFastISel::emitStore(MVT VT,
unsigned SrcReg,
Address &Addr) {
821 if (UnsupportedFPMode)
826 if (UnsupportedFPMode)
833 if (Addr.isRegBase()) {
834 simplifyAddress(Addr);
835 emitInstStore(
Opc, SrcReg, Addr.getReg(), Addr.getOffset());
838 if (Addr.isFIBase()) {
839 unsigned FI = Addr.getFI();
840 int64_t
Offset = Addr.getOffset();
841 MachineFrameInfo &MFI = MF->getFrameInfo();
842 MachineMemOperand *MMO = MF->getMachineMemOperand(
845 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
855bool MipsFastISel::selectLogicalOp(
const Instruction *
I) {
857 if (!isTypeSupported(
I->getType(), VT))
861 switch (
I->getOpcode()) {
864 case Instruction::And:
865 ResultReg = emitLogicalOp(
ISD::AND, VT,
I->getOperand(0),
I->getOperand(1));
867 case Instruction::Or:
868 ResultReg = emitLogicalOp(
ISD::OR, VT,
I->getOperand(0),
I->getOperand(1));
870 case Instruction::Xor:
871 ResultReg = emitLogicalOp(
ISD::XOR, VT,
I->getOperand(0),
I->getOperand(1));
878 updateValueMap(
I, ResultReg);
882bool MipsFastISel::selectLoad(
const Instruction *
I) {
891 if (!isLoadTypeLegal(LI->
getType(), VT))
907 updateValueMap(LI, ResultReg);
911bool MipsFastISel::selectStore(
const Instruction *
I) {
914 Value *Op0 =
SI->getOperand(0);
923 if (!isLoadTypeLegal(
SI->getOperand(0)->getType(), VT))
932 SrcReg = getRegForValue(Op0);
938 if (!computeAddress(
SI->getOperand(1), Addr))
948bool MipsFastISel::selectBranch(
const Instruction *
I) {
950 MachineBasicBlock *BrBB = FuncInfo.MBB;
959 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->
getSuccessor(1));
963 unsigned ZExtCondReg = 0;
966 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
973 if (ZExtCondReg == 0) {
978 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32,
true);
979 if (ZExtCondReg == 0)
983 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::BGTZ))
991bool MipsFastISel::selectCmp(
const Instruction *
I) {
993 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
996 updateValueMap(
I, ResultReg);
1001bool MipsFastISel::selectFPExt(
const Instruction *
I) {
1002 if (UnsupportedFPMode)
1004 Value *Src =
I->getOperand(0);
1008 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
1012 getRegForValue(Src);
1017 Register DestReg = createResultReg(&Mips::AFGR64RegClass);
1018 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1019 updateValueMap(
I, DestReg);
1023bool MipsFastISel::selectSelect(
const Instruction *
I) {
1029 if (!isTypeSupported(
I->getType(), VT) || UnsupportedFPMode) {
1031 dbgs() <<
".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1035 unsigned CondMovOpc;
1039 CondMovOpc = Mips::MOVN_I_I;
1040 RC = &Mips::GPR32RegClass;
1041 }
else if (VT == MVT::f32) {
1042 CondMovOpc = Mips::MOVN_I_S;
1043 RC = &Mips::FGR32RegClass;
1044 }
else if (VT == MVT::f64) {
1045 CondMovOpc = Mips::MOVN_I_D32;
1046 RC = &Mips::AFGR64RegClass;
1052 Register Src1Reg = getRegForValue(
SI->getTrueValue());
1053 Register Src2Reg = getRegForValue(
SI->getFalseValue());
1056 if (!Src1Reg || !Src2Reg || !CondReg)
1059 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1063 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg,
true))
1066 Register ResultReg = createResultReg(RC);
1067 Register TempReg = createResultReg(RC);
1069 if (!ResultReg || !TempReg)
1072 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1073 emitInst(CondMovOpc, ResultReg)
1074 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1075 updateValueMap(
I, ResultReg);
1080bool MipsFastISel::selectFPTrunc(
const Instruction *
I) {
1081 if (UnsupportedFPMode)
1083 Value *Src =
I->getOperand(0);
1087 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
1090 Register SrcReg = getRegForValue(Src);
1094 Register DestReg = createResultReg(&Mips::FGR32RegClass);
1098 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1099 updateValueMap(
I, DestReg);
1104bool MipsFastISel::selectFPToInt(
const Instruction *
I,
bool IsSigned) {
1105 if (UnsupportedFPMode)
1111 Type *DstTy =
I->getType();
1112 if (!isTypeLegal(DstTy, DstVT))
1115 if (DstVT != MVT::i32)
1118 Value *Src =
I->getOperand(0);
1119 Type *SrcTy = Src->getType();
1120 if (!isTypeLegal(SrcTy, SrcVT))
1123 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1126 Register SrcReg = getRegForValue(Src);
1132 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1133 Register TempReg = createResultReg(&Mips::FGR32RegClass);
1134 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1137 emitInst(
Opc, TempReg).addReg(SrcReg);
1138 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1140 updateValueMap(
I, DestReg);
1144bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1145 SmallVectorImpl<MVT> &OutVTs,
1146 unsigned &NumBytes) {
1147 CallingConv::ID CC = CLI.CallConv;
1150 for (
const ArgListEntry &Arg : CLI.Args)
1152 CCState CCInfo(CC,
false, *FuncInfo.MF, ArgLocs, *
Context);
1153 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,
1154 CCAssignFnForCall(CC));
1156 NumBytes = CCInfo.getStackSize();
1161 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1164 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1165 CCValAssign &VA = ArgLocs[i];
1171 if (ArgVT == MVT::f32) {
1173 }
else if (ArgVT == MVT::f64) {
1179 }
else if (i == 1) {
1180 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {
1181 if (ArgVT == MVT::f32) {
1183 }
else if (ArgVT == MVT::f64) {
1191 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||
1192 (ArgVT == MVT::i8)) &&
1211 Register ArgReg = getRegForValue(ArgVal);
1223 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
false);
1231 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
true);
1242 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1266 unsigned BEAlign = 0;
1267 if (ArgSize < 8 && !Subtarget->isLittle())
1268 BEAlign = 8 - ArgSize;
1271 Addr.setKind(Address::RegBase);
1272 Addr.setReg(Mips::SP);
1276 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
1288bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,
1289 unsigned NumBytes) {
1290 CallingConv::ID CC = CLI.CallConv;
1291 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1292 if (RetVT != MVT::isVoid) {
1294 MipsCCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *
Context);
1296 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);
1299 if (RVLocs.
size() != 1)
1302 MVT CopyVT = RVLocs[0].getValVT();
1304 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
1310 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1311 TII.get(TargetOpcode::COPY),
1312 ResultReg).
addReg(RVLocs[0].getLocReg());
1313 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1315 CLI.ResultReg = ResultReg;
1316 CLI.NumResultRegs = 1;
1321bool MipsFastISel::fastLowerArguments() {
1324 if (!FuncInfo.CanLowerReturn) {
1330 if (
F->isVarArg()) {
1335 CallingConv::ID CC =
F->getCallingConv();
1336 if (CC != CallingConv::C) {
1337 LLVM_DEBUG(
dbgs() <<
".. gave up (calling convention is not C)\n");
1342 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1343 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1344 auto NextGPR32 = GPR32ArgRegs.
begin();
1345 auto NextFGR32 = FGR32ArgRegs.begin();
1346 auto NextAFGR64 = AFGR64ArgRegs.begin();
1348 struct AllocatedReg {
1358 for (
const auto &FormalArg :
F->args()) {
1359 if (FormalArg.hasAttribute(Attribute::InReg) ||
1360 FormalArg.hasAttribute(Attribute::StructRet) ||
1361 FormalArg.hasAttribute(Attribute::ByVal)) {
1362 LLVM_DEBUG(dbgs() <<
".. gave up (inreg, structret, byval)\n");
1366 Type *ArgTy = FormalArg.getType();
1367 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {
1368 LLVM_DEBUG(dbgs() <<
".. gave up (struct, array, or vector)\n");
1375 if (!ArgVT.isSimple()) {
1376 LLVM_DEBUG(dbgs() <<
".. .. gave up (not a simple type)\n");
1380 switch (ArgVT.getSimpleVT().
SimpleTy) {
1384 if (!FormalArg.hasAttribute(Attribute::SExt) &&
1385 !FormalArg.hasAttribute(Attribute::ZExt)) {
1388 LLVM_DEBUG(dbgs() <<
".. .. gave up (i8/i16 arg is not extended)\n");
1392 if (NextGPR32 == GPR32ArgRegs.
end()) {
1393 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1398 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1401 NextFGR32 = FGR32ArgRegs.end();
1402 NextAFGR64 = AFGR64ArgRegs.end();
1406 if (FormalArg.hasAttribute(Attribute::ZExt)) {
1408 LLVM_DEBUG(dbgs() <<
".. .. gave up (i32 arg is zero extended)\n");
1412 if (NextGPR32 == GPR32ArgRegs.
end()) {
1413 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1418 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1421 NextFGR32 = FGR32ArgRegs.end();
1422 NextAFGR64 = AFGR64ArgRegs.end();
1426 if (UnsupportedFPMode) {
1430 if (NextFGR32 == FGR32ArgRegs.end()) {
1431 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of FGR32 arguments)\n");
1435 Allocation.
emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1438 if (NextGPR32 != GPR32ArgRegs.
end())
1440 if (NextAFGR64 != AFGR64ArgRegs.end())
1445 if (UnsupportedFPMode) {
1449 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1450 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of AFGR64 arguments)\n");
1454 Allocation.
emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1457 if (NextGPR32 != GPR32ArgRegs.
end())
1459 if (NextGPR32 != GPR32ArgRegs.
end())
1461 if (NextFGR32 != FGR32ArgRegs.end())
1471 for (
const auto &FormalArg :
F->args()) {
1472 unsigned ArgNo = FormalArg.getArgNo();
1473 unsigned SrcReg = Allocation[ArgNo].Reg;
1474 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1478 Register ResultReg = createResultReg(Allocation[ArgNo].RC);
1479 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
1482 updateValueMap(&FormalArg, ResultReg);
1487 unsigned IncomingArgSizeInBytes = 0;
1492 IncomingArgSizeInBytes = std::max(
getABI().GetCalleeAllocdArgSizeInBytes(CC),
1493 IncomingArgSizeInBytes);
1495 MF->getInfo<MipsFunctionInfo>()->setFormalArgInfo(IncomingArgSizeInBytes,
1501bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1502 CallingConv::ID CC = CLI.CallConv;
1503 bool IsTailCall = CLI.IsTailCall;
1504 bool IsVarArg = CLI.IsVarArg;
1509 if (CC == CallingConv::Fast)
1522 if (CLI.RetTy->isVoidTy())
1523 RetVT = MVT::isVoid;
1524 else if (!isTypeSupported(CLI.RetTy, RetVT))
1527 for (
auto Flag : CLI.OutFlags)
1533 OutVTs.
reserve(CLI.OutVals.size());
1535 for (
auto *Val : CLI.OutVals) {
1537 if (!isTypeLegal(Val->getType(), VT) &&
1538 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
1549 if (!computeCallAddress(Callee, Addr))
1554 if (!processCallArgs(CLI, OutVTs, NumBytes))
1557 if (!Addr.getGlobalValue())
1561 unsigned DestAddress;
1563 DestAddress = materializeExternalCallSym(Symbol);
1565 DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);
1566 emitInst(TargetOpcode::COPY,
getABI().getTempReg(9,
false))
1567 .addReg(DestAddress);
1568 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1569 TII.get(Mips::JALR), Mips::RA)
1573 for (
auto Reg : CLI.OutRegs)
1588 MIB.
addSym(FuncInfo.MF->getContext().getOrCreateSymbol(
1593 return finishCall(CLI, RetVT, NumBytes);
1596bool MipsFastISel::fastLowerIntrinsicCall(
const IntrinsicInst *
II) {
1597 switch (
II->getIntrinsicID()) {
1600 case Intrinsic::bswap: {
1601 Type *RetTy =
II->getCalledFunction()->getReturnType();
1604 if (!isTypeSupported(RetTy, VT))
1607 Register SrcReg = getRegForValue(
II->getOperand(0));
1610 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1613 if (VT == MVT::i16) {
1615 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1616 updateValueMap(
II, DestReg);
1619 unsigned TempReg[3];
1620 for (
unsigned &R : TempReg) {
1621 R = createResultReg(&Mips::GPR32RegClass);
1625 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1626 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1627 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);
1628 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);
1629 updateValueMap(
II, DestReg);
1632 }
else if (VT == MVT::i32) {
1634 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1635 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1636 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1637 updateValueMap(
II, DestReg);
1640 unsigned TempReg[8];
1641 for (
unsigned &R : TempReg) {
1642 R = createResultReg(&Mips::GPR32RegClass);
1647 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1648 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1649 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1650 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1652 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1653 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1655 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1656 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1657 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1658 updateValueMap(
II, DestReg);
1664 case Intrinsic::memcpy:
1665 case Intrinsic::memmove: {
1668 if (MTI->isVolatile())
1670 if (!MTI->getLength()->getType()->isIntegerTy(32))
1673 return lowerCallTo(
II, IntrMemName,
II->arg_size() - 1);
1675 case Intrinsic::memset: {
1682 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
1688bool MipsFastISel::selectRet(
const Instruction *
I) {
1689 const Function &
F = *
I->getParent()->getParent();
1694 if (!FuncInfo.CanLowerReturn)
1698 SmallVector<unsigned, 4> RetRegs;
1701 CallingConv::ID CC =
F.getCallingConv();
1704 if (CC == CallingConv::Fast)
1712 MipsCCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
1715 CCInfo.AnalyzeReturn(Outs, RetCC);
1718 if (ValLocs.
size() != 1)
1721 CCValAssign &VA = ValLocs[0];
1740 if (!MRI.getRegClass(SrcReg)->contains(DestReg))
1751 if (RVVT == MVT::f128)
1755 if (RVVT == MVT::f64 && UnsupportedFPMode) {
1762 if (RVVT != DestVT) {
1763 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
1766 if (Outs[0].
Flags.isZExt() || Outs[0].Flags.isSExt()) {
1767 bool IsZExt = Outs[0].Flags.isZExt();
1768 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1775 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1776 TII.get(TargetOpcode::COPY), DestReg).
addReg(SrcReg);
1781 MachineInstrBuilder MIB = emitInst(Mips::RetRA);
1782 for (
unsigned Reg : RetRegs)
1787bool MipsFastISel::selectTrunc(
const Instruction *
I) {
1796 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1798 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1807 updateValueMap(
I, SrcReg);
1811bool MipsFastISel::selectIntExt(
const Instruction *
I) {
1812 Type *DestTy =
I->getType();
1813 Value *Src =
I->getOperand(0);
1814 Type *SrcTy = Src->getType();
1817 Register SrcReg = getRegForValue(Src);
1821 EVT SrcEVT, DestEVT;
1831 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1833 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1835 updateValueMap(
I, ResultReg);
1839bool MipsFastISel::emitIntSExt32r1(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1852 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1853 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1854 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1858bool MipsFastISel::emitIntSExt32r2(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1864 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1867 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1873bool MipsFastISel::emitIntSExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1875 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
1878 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1879 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1882bool MipsFastISel::emitIntZExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1900 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(
Imm);
1904bool MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1905 unsigned DestReg,
bool IsZExt) {
1910 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||
1911 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))
1914 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1915 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1918unsigned MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1920 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1921 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1925bool MipsFastISel::selectDivRem(
const Instruction *
I,
unsigned ISDOpcode) {
1931 if (DestVT != MVT::i32)
1935 switch (ISDOpcode) {
1940 DivOpc = Mips::SDIV;
1944 DivOpc = Mips::UDIV;
1948 Register Src0Reg = getRegForValue(
I->getOperand(0));
1949 Register Src1Reg = getRegForValue(
I->getOperand(1));
1950 if (!Src0Reg || !Src1Reg)
1953 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1956 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1959 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1966 emitInst(MFOpc, ResultReg);
1968 updateValueMap(
I, ResultReg);
1972bool MipsFastISel::selectShift(
const Instruction *
I) {
1975 if (!isTypeSupported(
I->getType(), RetVT))
1978 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1982 unsigned Opcode =
I->getOpcode();
1983 const Value *Op0 =
I->getOperand(0);
1984 Register Op0Reg = getRegForValue(Op0);
1989 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1990 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1995 bool IsZExt = Opcode == Instruction::LShr;
1996 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))
2008 case Instruction::Shl:
2011 case Instruction::AShr:
2014 case Instruction::LShr:
2019 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2020 updateValueMap(
I, ResultReg);
2024 Register Op1Reg = getRegForValue(
I->getOperand(1));
2031 case Instruction::Shl:
2032 Opcode = Mips::SLLV;
2034 case Instruction::AShr:
2035 Opcode = Mips::SRAV;
2037 case Instruction::LShr:
2038 Opcode = Mips::SRLV;
2042 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2043 updateValueMap(
I, ResultReg);
2047bool MipsFastISel::fastSelectInstruction(
const Instruction *
I) {
2048 switch (
I->getOpcode()) {
2051 case Instruction::Load:
2052 return selectLoad(
I);
2053 case Instruction::Store:
2054 return selectStore(
I);
2055 case Instruction::SDiv:
2059 case Instruction::UDiv:
2063 case Instruction::SRem:
2067 case Instruction::URem:
2071 case Instruction::Shl:
2072 case Instruction::LShr:
2073 case Instruction::AShr:
2074 return selectShift(
I);
2075 case Instruction::And:
2076 case Instruction::Or:
2077 case Instruction::Xor:
2078 return selectLogicalOp(
I);
2079 case Instruction::CondBr:
2080 return selectBranch(
I);
2081 case Instruction::Ret:
2082 return selectRet(
I);
2083 case Instruction::Trunc:
2084 return selectTrunc(
I);
2085 case Instruction::ZExt:
2086 case Instruction::SExt:
2087 return selectIntExt(
I);
2088 case Instruction::FPTrunc:
2089 return selectFPTrunc(
I);
2090 case Instruction::FPExt:
2091 return selectFPExt(
I);
2092 case Instruction::FPToSI:
2093 return selectFPToInt(
I,
true);
2094 case Instruction::FPToUI:
2095 return selectFPToInt(
I,
false);
2096 case Instruction::ICmp:
2097 case Instruction::FCmp:
2098 return selectCmp(
I);
2099 case Instruction::Select:
2100 return selectSelect(
I);
2105unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(
const Value *V,
2112 if (VMVT == MVT::i1)
2115 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
2116 Register TempReg = createResultReg(&Mips::GPR32RegClass);
2117 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
2124void MipsFastISel::simplifyAddress(
Address &Addr) {
2127 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
2128 Register DestReg = createResultReg(&Mips::GPR32RegClass);
2129 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());
2130 Addr.setReg(DestReg);
2135unsigned MipsFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2137 unsigned Op0,
unsigned Op1) {
2144 if (MachineInstOpcode == Mips::MUL) {
2145 Register ResultReg = createResultReg(RC);
2146 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
2149 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
2165 return new MipsFastISel(funcInfo, libInfo, libcallLowering);
static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
Select the AArch64 opcode for the basic binary operation GenericOpc, appropriate for the register ban...
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...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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
cl::opt< bool > NoZeroDivCheck
static MCRegister 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.
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.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
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
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.
Tracks which library functions to use for a particular subtarget or function.
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 & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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 & 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
const MipsABIInfo & getABI() const
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
unsigned getNumOperands() 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.
@ 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, const LibcallLoweringInfo *libcallLowering)
WebAssemblyABI getABI(StringRef Name)
Parse an ABI name into the corresponding enum.
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
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)
MCRegisterClass TargetRegisterClass
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.