71#define DEBUG_TYPE "mips-fastisel"
77class MipsFastISel final :
public FastISel {
82 enum BaseKind { RegBase, FrameIndexBase };
85 BaseKind Kind = RegBase;
99 void setKind(BaseKind
K) { Kind =
K; }
100 BaseKind getKind()
const {
return Kind; }
101 bool isRegBase()
const {
return Kind == RegBase; }
102 bool isFIBase()
const {
return Kind == FrameIndexBase; }
104 void setReg(
unsigned Reg) {
105 assert(isRegBase() &&
"Invalid base register access!");
110 assert(isRegBase() &&
"Invalid base register access!");
114 void setFI(
unsigned FI) {
115 assert(isFIBase() &&
"Invalid base frame index access!");
119 unsigned getFI()
const {
120 assert(isFIBase() &&
"Invalid base frame index access!");
124 void setOffset(int64_t Offset_) {
Offset = Offset_; }
141 bool fastLowerArguments()
override;
142 bool fastLowerCall(CallLoweringInfo &CLI)
override;
145 bool UnsupportedFPMode;
159 bool selectFPToInt(
const Instruction *
I,
bool IsSigned);
164 bool selectDivRem(
const Instruction *
I,
unsigned ISDOpcode);
167 bool isTypeLegal(
Type *Ty,
MVT &VT);
168 bool isTypeSupported(
Type *Ty,
MVT &VT);
169 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
170 bool computeAddress(
const Value *Obj, Address &Addr);
171 bool computeCallAddress(
const Value *V, Address &Addr);
172 void simplifyAddress(Address &Addr);
176 bool emitLoad(
MVT VT,
unsigned &ResultReg, Address &Addr);
178 unsigned emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
bool isZExt);
179 bool emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg,
182 bool emitIntZExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg);
184 bool emitIntSExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg);
185 bool emitIntSExt32r1(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
187 bool emitIntSExt32r2(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
190 unsigned getRegEnsuringSimpleIntegerWidening(
const Value *,
bool IsUnsigned);
192 unsigned emitLogicalOp(
unsigned ISDOpc,
MVT RetVT,
const Value *
LHS,
199 unsigned materializeExternalCallSym(
MCSymbol *Syn);
202 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc));
206 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
211 unsigned MemReg, int64_t MemOffset) {
216 unsigned MemReg, int64_t MemOffset) {
220 unsigned fastEmitInst_rr(
unsigned MachineInstOpcode,
222 unsigned Op0,
unsigned Op1);
237 bool finishCall(CallLoweringInfo &CLI,
MVT RetVT,
unsigned NumBytes);
246 :
FastISel(funcInfo, libInfo, libcallLowering),
257 bool fastSelectInstruction(
const Instruction *
I)
override;
259#include "MipsGenFastISel.inc"
283#define GET_CALLING_CONV_IMPL
284#include "MipsGenCallingConv.inc"
290unsigned MipsFastISel::emitLogicalOp(
unsigned ISDOpc, MVT RetVT,
317 RHSReg = materializeInt(
C, MVT::i32);
319 RHSReg = getRegForValue(
RHS);
323 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
327 emitInst(
Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
331Register MipsFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
333 "Alloca should always return a pointer.");
335 auto SI = FuncInfo.StaticAllocaMap.find(AI);
337 if (SI != FuncInfo.StaticAllocaMap.end()) {
338 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
339 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::LEA_ADDiu),
349unsigned MipsFastISel::materializeInt(
const Constant *
C, MVT VT) {
350 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
357unsigned MipsFastISel::materialize32BitInt(int64_t
Imm,
359 Register ResultReg = createResultReg(RC);
362 unsigned Opc = Mips::ADDiu;
363 emitInst(
Opc, ResultReg).addReg(Mips::ZERO).addImm(
Imm);
366 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(
Imm);
369 unsigned Lo =
Imm & 0xFFFF;
370 unsigned Hi = (
Imm >> 16) & 0xFFFF;
373 Register TmpReg = createResultReg(RC);
374 emitInst(Mips::LUi, TmpReg).addImm(
Hi);
375 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(
Lo);
377 emitInst(Mips::LUi, ResultReg).addImm(
Hi);
382unsigned MipsFastISel::materializeFP(
const ConstantFP *CFP, MVT VT) {
383 if (UnsupportedFPMode)
386 if (VT == MVT::f32) {
388 Register DestReg = createResultReg(RC);
389 unsigned TempReg = materialize32BitInt(
Imm, &Mips::GPR32RegClass);
390 emitInst(Mips::MTC1, DestReg).addReg(TempReg);
392 }
else if (VT == MVT::f64) {
394 Register DestReg = createResultReg(RC);
395 unsigned TempReg1 = materialize32BitInt(
Imm >> 32, &Mips::GPR32RegClass);
397 materialize32BitInt(
Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
398 emitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);
404unsigned MipsFastISel::materializeGV(
const GlobalValue *GV, MVT VT) {
409 Register DestReg = createResultReg(RC);
415 emitInst(Mips::LW, DestReg)
419 Register TempReg = createResultReg(RC);
420 emitInst(Mips::ADDiu, TempReg)
428unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {
430 Register DestReg = createResultReg(RC);
431 emitInst(Mips::LW, DestReg)
439Register MipsFastISel::fastMaterializeConstant(
const Constant *
C) {
448 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
450 return materializeGV(GV, VT);
452 return materializeInt(
C, VT);
457bool MipsFastISel::computeAddress(
const Value *Obj,
Address &Addr) {
458 const User *
U =
nullptr;
459 unsigned Opcode = Instruction::UserOp1;
463 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
464 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
465 Opcode =
I->getOpcode();
469 Opcode =
C->getOpcode();
475 case Instruction::BitCast:
477 return computeAddress(
U->getOperand(0), Addr);
478 case Instruction::GetElementPtr: {
480 int64_t TmpOffset = Addr.getOffset();
488 const StructLayout *SL =
DL.getStructLayout(STy);
496 TmpOffset += CI->getSExtValue() * S;
499 if (canFoldAddIntoGEP(U,
Op)) {
509 goto unsupported_gep;
514 Addr.setOffset(TmpOffset);
515 if (computeAddress(
U->getOperand(0), Addr))
522 case Instruction::Alloca: {
524 auto SI = FuncInfo.StaticAllocaMap.find(AI);
525 if (SI != FuncInfo.StaticAllocaMap.end()) {
526 Addr.setKind(Address::FrameIndexBase);
527 Addr.setFI(
SI->second);
533 Addr.setReg(getRegForValue(Obj));
534 return Addr.getReg() != 0;
537bool MipsFastISel::computeCallAddress(
const Value *V,
Address &Addr) {
538 const User *
U =
nullptr;
539 unsigned Opcode = Instruction::UserOp1;
544 if (
I->getParent() == FuncInfo.MBB->getBasicBlock()) {
545 Opcode =
I->getOpcode();
549 Opcode =
C->getOpcode();
556 case Instruction::BitCast:
558 return computeCallAddress(
U->getOperand(0), Addr);
560 case Instruction::IntToPtr:
564 return computeCallAddress(
U->getOperand(0), Addr);
566 case Instruction::PtrToInt:
569 return computeCallAddress(
U->getOperand(0), Addr);
574 Addr.setGlobalValue(GV);
579 if (!Addr.getGlobalValue()) {
580 Addr.setReg(getRegForValue(V));
581 return Addr.getReg() != 0;
587bool MipsFastISel::isTypeLegal(
Type *Ty, MVT &VT) {
590 if (evt == MVT::Other || !evt.
isSimple())
599bool MipsFastISel::isTypeSupported(
Type *Ty, MVT &VT) {
603 if (isTypeLegal(Ty, VT))
608 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
614bool MipsFastISel::isLoadTypeLegal(
Type *Ty, MVT &VT) {
615 if (isTypeLegal(Ty, VT))
620 if (VT == MVT::i8 || VT == MVT::i16)
629bool MipsFastISel::emitCmp(
unsigned ResultReg,
const CmpInst *CI) {
632 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(
Left, IsUnsigned);
635 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(
Right, IsUnsigned);
644 Register TempReg = createResultReg(&Mips::GPR32RegClass);
645 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
646 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
650 Register TempReg = createResultReg(&Mips::GPR32RegClass);
651 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
652 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
656 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
659 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
662 Register TempReg = createResultReg(&Mips::GPR32RegClass);
663 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
664 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
668 Register TempReg = createResultReg(&Mips::GPR32RegClass);
669 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
670 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
674 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
677 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
680 Register TempReg = createResultReg(&Mips::GPR32RegClass);
681 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
682 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
686 Register TempReg = createResultReg(&Mips::GPR32RegClass);
687 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
688 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
697 if (UnsupportedFPMode)
699 bool IsFloat =
Left->getType()->isFloatTy();
700 bool IsDouble =
Left->getType()->isDoubleTy();
701 if (!IsFloat && !IsDouble)
703 unsigned Opc, CondMovOpc;
706 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
707 CondMovOpc = Mips::MOVT_I;
710 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
711 CondMovOpc = Mips::MOVF_I;
714 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
715 CondMovOpc = Mips::MOVT_I;
718 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
719 CondMovOpc = Mips::MOVT_I;
722 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
723 CondMovOpc = Mips::MOVF_I;
726 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
727 CondMovOpc = Mips::MOVF_I;
732 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);
733 Register RegWithOne = createResultReg(&Mips::GPR32RegClass);
734 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
735 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
736 emitInst(
Opc).addReg(Mips::FCC0, RegState::Define).addReg(LeftReg)
738 emitInst(CondMovOpc, ResultReg)
741 .addReg(RegWithZero);
748bool MipsFastISel::emitLoad(MVT VT,
unsigned &ResultReg,
Address &Addr) {
755 ResultReg = createResultReg(&Mips::GPR32RegClass);
759 ResultReg = createResultReg(&Mips::GPR32RegClass);
763 ResultReg = createResultReg(&Mips::GPR32RegClass);
767 if (UnsupportedFPMode)
769 ResultReg = createResultReg(&Mips::FGR32RegClass);
773 if (UnsupportedFPMode)
775 ResultReg = createResultReg(&Mips::AFGR64RegClass);
781 if (Addr.isRegBase()) {
782 simplifyAddress(Addr);
783 emitInstLoad(
Opc, ResultReg, Addr.getReg(), Addr.getOffset());
786 if (Addr.isFIBase()) {
787 unsigned FI = Addr.getFI();
788 int64_t
Offset = Addr.getOffset();
789 MachineFrameInfo &MFI = MF->getFrameInfo();
790 MachineMemOperand *MMO = MF->getMachineMemOperand(
793 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
802bool MipsFastISel::emitStore(MVT VT,
unsigned SrcReg,
Address &Addr) {
818 if (UnsupportedFPMode)
823 if (UnsupportedFPMode)
830 if (Addr.isRegBase()) {
831 simplifyAddress(Addr);
832 emitInstStore(
Opc, SrcReg, Addr.getReg(), Addr.getOffset());
835 if (Addr.isFIBase()) {
836 unsigned FI = Addr.getFI();
837 int64_t
Offset = Addr.getOffset();
838 MachineFrameInfo &MFI = MF->getFrameInfo();
839 MachineMemOperand *MMO = MF->getMachineMemOperand(
842 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
852bool MipsFastISel::selectLogicalOp(
const Instruction *
I) {
854 if (!isTypeSupported(
I->getType(), VT))
858 switch (
I->getOpcode()) {
861 case Instruction::And:
862 ResultReg = emitLogicalOp(
ISD::AND, VT,
I->getOperand(0),
I->getOperand(1));
864 case Instruction::Or:
865 ResultReg = emitLogicalOp(
ISD::OR, VT,
I->getOperand(0),
I->getOperand(1));
867 case Instruction::Xor:
868 ResultReg = emitLogicalOp(
ISD::XOR, VT,
I->getOperand(0),
I->getOperand(1));
875 updateValueMap(
I, ResultReg);
879bool MipsFastISel::selectLoad(
const Instruction *
I) {
888 if (!isLoadTypeLegal(LI->
getType(), VT))
904 updateValueMap(LI, ResultReg);
908bool MipsFastISel::selectStore(
const Instruction *
I) {
911 Value *Op0 =
SI->getOperand(0);
920 if (!isLoadTypeLegal(
SI->getOperand(0)->getType(), VT))
929 SrcReg = getRegForValue(Op0);
935 if (!computeAddress(
SI->getOperand(1), Addr))
945bool MipsFastISel::selectBranch(
const Instruction *
I) {
947 MachineBasicBlock *BrBB = FuncInfo.MBB;
956 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->
getSuccessor(1));
960 unsigned ZExtCondReg = 0;
963 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
970 if (ZExtCondReg == 0) {
975 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32,
true);
976 if (ZExtCondReg == 0)
980 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::BGTZ))
988bool MipsFastISel::selectCmp(
const Instruction *
I) {
990 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
993 updateValueMap(
I, ResultReg);
998bool MipsFastISel::selectFPExt(
const Instruction *
I) {
999 if (UnsupportedFPMode)
1001 Value *Src =
I->getOperand(0);
1005 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
1009 getRegForValue(Src);
1014 Register DestReg = createResultReg(&Mips::AFGR64RegClass);
1015 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1016 updateValueMap(
I, DestReg);
1020bool MipsFastISel::selectSelect(
const Instruction *
I) {
1026 if (!isTypeSupported(
I->getType(), VT) || UnsupportedFPMode) {
1028 dbgs() <<
".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1032 unsigned CondMovOpc;
1036 CondMovOpc = Mips::MOVN_I_I;
1037 RC = &Mips::GPR32RegClass;
1038 }
else if (VT == MVT::f32) {
1039 CondMovOpc = Mips::MOVN_I_S;
1040 RC = &Mips::FGR32RegClass;
1041 }
else if (VT == MVT::f64) {
1042 CondMovOpc = Mips::MOVN_I_D32;
1043 RC = &Mips::AFGR64RegClass;
1049 Register Src1Reg = getRegForValue(
SI->getTrueValue());
1050 Register Src2Reg = getRegForValue(
SI->getFalseValue());
1053 if (!Src1Reg || !Src2Reg || !CondReg)
1056 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1060 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg,
true))
1063 Register ResultReg = createResultReg(RC);
1064 Register TempReg = createResultReg(RC);
1066 if (!ResultReg || !TempReg)
1069 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1070 emitInst(CondMovOpc, ResultReg)
1071 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1072 updateValueMap(
I, ResultReg);
1077bool MipsFastISel::selectFPTrunc(
const Instruction *
I) {
1078 if (UnsupportedFPMode)
1080 Value *Src =
I->getOperand(0);
1084 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
1087 Register SrcReg = getRegForValue(Src);
1091 Register DestReg = createResultReg(&Mips::FGR32RegClass);
1095 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1096 updateValueMap(
I, DestReg);
1101bool MipsFastISel::selectFPToInt(
const Instruction *
I,
bool IsSigned) {
1102 if (UnsupportedFPMode)
1108 Type *DstTy =
I->getType();
1109 if (!isTypeLegal(DstTy, DstVT))
1112 if (DstVT != MVT::i32)
1115 Value *Src =
I->getOperand(0);
1116 Type *SrcTy = Src->getType();
1117 if (!isTypeLegal(SrcTy, SrcVT))
1120 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1123 Register SrcReg = getRegForValue(Src);
1129 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1130 Register TempReg = createResultReg(&Mips::FGR32RegClass);
1131 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1134 emitInst(
Opc, TempReg).addReg(SrcReg);
1135 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1137 updateValueMap(
I, DestReg);
1141bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1142 SmallVectorImpl<MVT> &OutVTs,
1143 unsigned &NumBytes) {
1144 CallingConv::ID CC = CLI.CallConv;
1147 for (
const ArgListEntry &Arg : CLI.Args)
1149 CCState CCInfo(CC,
false, *FuncInfo.MF, ArgLocs, *
Context);
1150 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,
1151 CCAssignFnForCall(CC));
1153 NumBytes = CCInfo.getStackSize();
1158 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1161 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1162 CCValAssign &VA = ArgLocs[i];
1168 if (ArgVT == MVT::f32) {
1170 }
else if (ArgVT == MVT::f64) {
1176 }
else if (i == 1) {
1177 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {
1178 if (ArgVT == MVT::f32) {
1180 }
else if (ArgVT == MVT::f64) {
1188 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||
1189 (ArgVT == MVT::i8)) &&
1208 Register ArgReg = getRegForValue(ArgVal);
1220 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
false);
1228 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
true);
1239 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1263 unsigned BEAlign = 0;
1264 if (ArgSize < 8 && !Subtarget->isLittle())
1265 BEAlign = 8 - ArgSize;
1268 Addr.setKind(Address::RegBase);
1269 Addr.setReg(Mips::SP);
1273 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
1285bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,
1286 unsigned NumBytes) {
1287 CallingConv::ID CC = CLI.CallConv;
1288 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1289 if (RetVT != MVT::isVoid) {
1291 MipsCCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *
Context);
1293 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);
1296 if (RVLocs.
size() != 1)
1299 MVT CopyVT = RVLocs[0].getValVT();
1301 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
1307 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1308 TII.get(TargetOpcode::COPY),
1309 ResultReg).
addReg(RVLocs[0].getLocReg());
1310 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1312 CLI.ResultReg = ResultReg;
1313 CLI.NumResultRegs = 1;
1318bool MipsFastISel::fastLowerArguments() {
1321 if (!FuncInfo.CanLowerReturn) {
1327 if (
F->isVarArg()) {
1332 CallingConv::ID CC =
F->getCallingConv();
1333 if (CC != CallingConv::C) {
1334 LLVM_DEBUG(
dbgs() <<
".. gave up (calling convention is not C)\n");
1339 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1340 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1341 auto NextGPR32 = GPR32ArgRegs.
begin();
1342 auto NextFGR32 = FGR32ArgRegs.begin();
1343 auto NextAFGR64 = AFGR64ArgRegs.begin();
1345 struct AllocatedReg {
1355 for (
const auto &FormalArg :
F->args()) {
1356 if (FormalArg.hasAttribute(Attribute::InReg) ||
1357 FormalArg.hasAttribute(Attribute::StructRet) ||
1358 FormalArg.hasAttribute(Attribute::ByVal)) {
1359 LLVM_DEBUG(dbgs() <<
".. gave up (inreg, structret, byval)\n");
1363 Type *ArgTy = FormalArg.getType();
1364 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {
1365 LLVM_DEBUG(dbgs() <<
".. gave up (struct, array, or vector)\n");
1372 if (!ArgVT.isSimple()) {
1373 LLVM_DEBUG(dbgs() <<
".. .. gave up (not a simple type)\n");
1377 switch (ArgVT.getSimpleVT().
SimpleTy) {
1381 if (!FormalArg.hasAttribute(Attribute::SExt) &&
1382 !FormalArg.hasAttribute(Attribute::ZExt)) {
1385 LLVM_DEBUG(dbgs() <<
".. .. gave up (i8/i16 arg is not extended)\n");
1389 if (NextGPR32 == GPR32ArgRegs.
end()) {
1390 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1395 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1398 NextFGR32 = FGR32ArgRegs.end();
1399 NextAFGR64 = AFGR64ArgRegs.end();
1403 if (FormalArg.hasAttribute(Attribute::ZExt)) {
1405 LLVM_DEBUG(dbgs() <<
".. .. gave up (i32 arg is zero extended)\n");
1409 if (NextGPR32 == GPR32ArgRegs.
end()) {
1410 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1415 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1418 NextFGR32 = FGR32ArgRegs.end();
1419 NextAFGR64 = AFGR64ArgRegs.end();
1423 if (UnsupportedFPMode) {
1427 if (NextFGR32 == FGR32ArgRegs.end()) {
1428 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of FGR32 arguments)\n");
1432 Allocation.
emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1435 if (NextGPR32 != GPR32ArgRegs.
end())
1437 if (NextAFGR64 != AFGR64ArgRegs.end())
1442 if (UnsupportedFPMode) {
1446 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1447 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of AFGR64 arguments)\n");
1451 Allocation.
emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1454 if (NextGPR32 != GPR32ArgRegs.
end())
1456 if (NextGPR32 != GPR32ArgRegs.
end())
1458 if (NextFGR32 != FGR32ArgRegs.end())
1468 for (
const auto &FormalArg :
F->args()) {
1469 unsigned ArgNo = FormalArg.getArgNo();
1470 unsigned SrcReg = Allocation[ArgNo].Reg;
1471 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1475 Register ResultReg = createResultReg(Allocation[ArgNo].RC);
1476 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY),
1479 updateValueMap(&FormalArg, ResultReg);
1484 unsigned IncomingArgSizeInBytes = 0;
1489 IncomingArgSizeInBytes = std::max(
getABI().GetCalleeAllocdArgSizeInBytes(CC),
1490 IncomingArgSizeInBytes);
1492 MF->getInfo<MipsFunctionInfo>()->setFormalArgInfo(IncomingArgSizeInBytes,
1498bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1499 CallingConv::ID CC = CLI.CallConv;
1500 bool IsTailCall = CLI.IsTailCall;
1501 bool IsVarArg = CLI.IsVarArg;
1506 if (CC == CallingConv::Fast)
1519 if (CLI.RetTy->isVoidTy())
1520 RetVT = MVT::isVoid;
1521 else if (!isTypeSupported(CLI.RetTy, RetVT))
1524 for (
auto Flag : CLI.OutFlags)
1530 OutVTs.
reserve(CLI.OutVals.size());
1532 for (
auto *Val : CLI.OutVals) {
1534 if (!isTypeLegal(Val->getType(), VT) &&
1535 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
1546 if (!computeCallAddress(Callee, Addr))
1551 if (!processCallArgs(CLI, OutVTs, NumBytes))
1554 if (!Addr.getGlobalValue())
1558 unsigned DestAddress;
1560 DestAddress = materializeExternalCallSym(Symbol);
1562 DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);
1563 emitInst(TargetOpcode::COPY,
getABI().getTempReg(9,
false))
1564 .addReg(DestAddress);
1565 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1566 TII.get(Mips::JALR), Mips::RA)
1570 for (
auto Reg : CLI.OutRegs)
1589 return finishCall(CLI, RetVT, NumBytes);
1592bool MipsFastISel::fastLowerIntrinsicCall(
const IntrinsicInst *
II) {
1593 switch (
II->getIntrinsicID()) {
1596 case Intrinsic::bswap: {
1597 Type *RetTy =
II->getCalledFunction()->getReturnType();
1600 if (!isTypeSupported(RetTy, VT))
1603 Register SrcReg = getRegForValue(
II->getOperand(0));
1606 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1609 if (VT == MVT::i16) {
1611 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1612 updateValueMap(
II, DestReg);
1615 unsigned TempReg[3];
1616 for (
unsigned &R : TempReg) {
1617 R = createResultReg(&Mips::GPR32RegClass);
1621 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1622 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1623 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);
1624 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);
1625 updateValueMap(
II, DestReg);
1628 }
else if (VT == MVT::i32) {
1630 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1631 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1632 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1633 updateValueMap(
II, DestReg);
1636 unsigned TempReg[8];
1637 for (
unsigned &R : TempReg) {
1638 R = createResultReg(&Mips::GPR32RegClass);
1643 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1644 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1645 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1646 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1648 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1649 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1651 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1652 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1653 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1654 updateValueMap(
II, DestReg);
1660 case Intrinsic::memcpy:
1661 case Intrinsic::memmove: {
1664 if (MTI->isVolatile())
1666 if (!MTI->getLength()->getType()->isIntegerTy(32))
1669 return lowerCallTo(
II, IntrMemName,
II->arg_size() - 1);
1671 case Intrinsic::memset: {
1678 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
1684bool MipsFastISel::selectRet(
const Instruction *
I) {
1685 const Function &
F = *
I->getParent()->getParent();
1690 if (!FuncInfo.CanLowerReturn)
1694 SmallVector<unsigned, 4> RetRegs;
1697 CallingConv::ID CC =
F.getCallingConv();
1700 if (CC == CallingConv::Fast)
1708 MipsCCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
1711 CCInfo.AnalyzeReturn(Outs, RetCC);
1714 if (ValLocs.
size() != 1)
1717 CCValAssign &VA = ValLocs[0];
1736 if (!MRI.getRegClass(SrcReg)->contains(DestReg))
1747 if (RVVT == MVT::f128)
1751 if (RVVT == MVT::f64 && UnsupportedFPMode) {
1758 if (RVVT != DestVT) {
1759 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
1762 if (Outs[0].
Flags.isZExt() || Outs[0].Flags.isSExt()) {
1763 bool IsZExt = Outs[0].Flags.isZExt();
1764 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1771 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1772 TII.get(TargetOpcode::COPY), DestReg).
addReg(SrcReg);
1777 MachineInstrBuilder MIB = emitInst(Mips::RetRA);
1778 for (
unsigned Reg : RetRegs)
1783bool MipsFastISel::selectTrunc(
const Instruction *
I) {
1792 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1794 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1803 updateValueMap(
I, SrcReg);
1807bool MipsFastISel::selectIntExt(
const Instruction *
I) {
1808 Type *DestTy =
I->getType();
1809 Value *Src =
I->getOperand(0);
1810 Type *SrcTy = Src->getType();
1813 Register SrcReg = getRegForValue(Src);
1817 EVT SrcEVT, DestEVT;
1827 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1829 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1831 updateValueMap(
I, ResultReg);
1835bool MipsFastISel::emitIntSExt32r1(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1848 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1849 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1850 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1854bool MipsFastISel::emitIntSExt32r2(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1860 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1863 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1869bool MipsFastISel::emitIntSExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1871 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
1874 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1875 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1878bool MipsFastISel::emitIntZExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1896 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(
Imm);
1900bool MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1901 unsigned DestReg,
bool IsZExt) {
1906 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||
1907 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))
1910 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1911 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1914unsigned MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1916 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1917 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1921bool MipsFastISel::selectDivRem(
const Instruction *
I,
unsigned ISDOpcode) {
1927 if (DestVT != MVT::i32)
1931 switch (ISDOpcode) {
1936 DivOpc = Mips::SDIV;
1940 DivOpc = Mips::UDIV;
1944 Register Src0Reg = getRegForValue(
I->getOperand(0));
1945 Register Src1Reg = getRegForValue(
I->getOperand(1));
1946 if (!Src0Reg || !Src1Reg)
1949 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1950 if (!Subtarget->
getMCCLOpts().mno_check_zero_division &&
1953 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1956 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1963 emitInst(MFOpc, ResultReg);
1965 updateValueMap(
I, ResultReg);
1969bool MipsFastISel::selectShift(
const Instruction *
I) {
1972 if (!isTypeSupported(
I->getType(), RetVT))
1975 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1979 unsigned Opcode =
I->getOpcode();
1980 const Value *Op0 =
I->getOperand(0);
1981 Register Op0Reg = getRegForValue(Op0);
1986 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1987 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1992 bool IsZExt = Opcode == Instruction::LShr;
1993 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))
2005 case Instruction::Shl:
2008 case Instruction::AShr:
2011 case Instruction::LShr:
2016 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2017 updateValueMap(
I, ResultReg);
2021 Register Op1Reg = getRegForValue(
I->getOperand(1));
2028 case Instruction::Shl:
2029 Opcode = Mips::SLLV;
2031 case Instruction::AShr:
2032 Opcode = Mips::SRAV;
2034 case Instruction::LShr:
2035 Opcode = Mips::SRLV;
2039 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2040 updateValueMap(
I, ResultReg);
2044bool MipsFastISel::fastSelectInstruction(
const Instruction *
I) {
2045 switch (
I->getOpcode()) {
2048 case Instruction::Load:
2049 return selectLoad(
I);
2050 case Instruction::Store:
2051 return selectStore(
I);
2052 case Instruction::SDiv:
2056 case Instruction::UDiv:
2060 case Instruction::SRem:
2064 case Instruction::URem:
2068 case Instruction::Shl:
2069 case Instruction::LShr:
2070 case Instruction::AShr:
2071 return selectShift(
I);
2072 case Instruction::And:
2073 case Instruction::Or:
2074 case Instruction::Xor:
2075 return selectLogicalOp(
I);
2076 case Instruction::CondBr:
2077 return selectBranch(
I);
2078 case Instruction::Ret:
2079 return selectRet(
I);
2080 case Instruction::Trunc:
2081 return selectTrunc(
I);
2082 case Instruction::ZExt:
2083 case Instruction::SExt:
2084 return selectIntExt(
I);
2085 case Instruction::FPTrunc:
2086 return selectFPTrunc(
I);
2087 case Instruction::FPExt:
2088 return selectFPExt(
I);
2089 case Instruction::FPToSI:
2090 return selectFPToInt(
I,
true);
2091 case Instruction::FPToUI:
2092 return selectFPToInt(
I,
false);
2093 case Instruction::ICmp:
2094 case Instruction::FCmp:
2095 return selectCmp(
I);
2096 case Instruction::Select:
2097 return selectSelect(
I);
2102unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(
const Value *V,
2109 if (VMVT == MVT::i1)
2112 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
2113 Register TempReg = createResultReg(&Mips::GPR32RegClass);
2114 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
2121void MipsFastISel::simplifyAddress(
Address &Addr) {
2124 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
2125 Register DestReg = createResultReg(&Mips::GPR32RegClass);
2126 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());
2127 Addr.setReg(DestReg);
2132unsigned MipsFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2134 unsigned Op0,
unsigned Op1) {
2141 if (MachineInstOpcode == Mips::MUL) {
2142 Register ResultReg = createResultReg(RC);
2143 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
2146 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
2162 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
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
const MipsMCOptions & getMCCLOpts() 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.
MCSymbol * getSymbol(const GlobalValue *GV) const
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.