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)
423 Register TempReg = createResultReg(RC);
424 emitInst(Mips::ADDiu, TempReg)
432unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {
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 auto SI = FuncInfo.StaticAllocaMap.find(AI);
529 if (SI != FuncInfo.StaticAllocaMap.end()) {
530 Addr.setKind(Address::FrameIndexBase);
531 Addr.setFI(
SI->second);
537 Addr.setReg(getRegForValue(Obj));
538 return Addr.getReg() != 0;
541bool MipsFastISel::computeCallAddress(
const Value *V,
Address &Addr) {
542 const User *
U =
nullptr;
543 unsigned Opcode = Instruction::UserOp1;
548 if (
I->getParent() == FuncInfo.MBB->getBasicBlock()) {
549 Opcode =
I->getOpcode();
553 Opcode =
C->getOpcode();
560 case Instruction::BitCast:
562 return computeCallAddress(
U->getOperand(0), Addr);
564 case Instruction::IntToPtr:
568 return computeCallAddress(
U->getOperand(0), Addr);
570 case Instruction::PtrToInt:
573 return computeCallAddress(
U->getOperand(0), Addr);
578 Addr.setGlobalValue(GV);
583 if (!Addr.getGlobalValue()) {
584 Addr.setReg(getRegForValue(V));
585 return Addr.getReg() != 0;
591bool MipsFastISel::isTypeLegal(
Type *Ty, MVT &VT) {
594 if (evt == MVT::Other || !evt.
isSimple())
603bool MipsFastISel::isTypeSupported(
Type *Ty, MVT &VT) {
607 if (isTypeLegal(Ty, VT))
612 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
618bool MipsFastISel::isLoadTypeLegal(
Type *Ty, MVT &VT) {
619 if (isTypeLegal(Ty, VT))
624 if (VT == MVT::i8 || VT == MVT::i16)
633bool MipsFastISel::emitCmp(
unsigned ResultReg,
const CmpInst *CI) {
636 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(
Left, IsUnsigned);
639 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(
Right, IsUnsigned);
648 Register TempReg = createResultReg(&Mips::GPR32RegClass);
649 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
650 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
654 Register TempReg = createResultReg(&Mips::GPR32RegClass);
655 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
656 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
660 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
663 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
666 Register TempReg = createResultReg(&Mips::GPR32RegClass);
667 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
668 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
672 Register TempReg = createResultReg(&Mips::GPR32RegClass);
673 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
674 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
678 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
681 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
684 Register TempReg = createResultReg(&Mips::GPR32RegClass);
685 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
686 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
690 Register TempReg = createResultReg(&Mips::GPR32RegClass);
691 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
692 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
701 if (UnsupportedFPMode)
703 bool IsFloat =
Left->getType()->isFloatTy();
704 bool IsDouble =
Left->getType()->isDoubleTy();
705 if (!IsFloat && !IsDouble)
707 unsigned Opc, CondMovOpc;
710 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
711 CondMovOpc = Mips::MOVT_I;
714 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
715 CondMovOpc = Mips::MOVF_I;
718 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
719 CondMovOpc = Mips::MOVT_I;
722 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
723 CondMovOpc = Mips::MOVT_I;
726 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
727 CondMovOpc = Mips::MOVF_I;
730 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
731 CondMovOpc = Mips::MOVF_I;
736 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);
737 Register RegWithOne = createResultReg(&Mips::GPR32RegClass);
738 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
739 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
740 emitInst(
Opc).addReg(Mips::FCC0, RegState::Define).addReg(LeftReg)
742 emitInst(CondMovOpc, ResultReg)
745 .addReg(RegWithZero);
752bool MipsFastISel::emitLoad(MVT VT,
unsigned &ResultReg,
Address &Addr) {
759 ResultReg = createResultReg(&Mips::GPR32RegClass);
763 ResultReg = createResultReg(&Mips::GPR32RegClass);
767 ResultReg = createResultReg(&Mips::GPR32RegClass);
771 if (UnsupportedFPMode)
773 ResultReg = createResultReg(&Mips::FGR32RegClass);
777 if (UnsupportedFPMode)
779 ResultReg = createResultReg(&Mips::AFGR64RegClass);
785 if (Addr.isRegBase()) {
786 simplifyAddress(Addr);
787 emitInstLoad(
Opc, ResultReg, Addr.getReg(), Addr.getOffset());
790 if (Addr.isFIBase()) {
791 unsigned FI = Addr.getFI();
792 int64_t
Offset = Addr.getOffset();
793 MachineFrameInfo &MFI = MF->getFrameInfo();
794 MachineMemOperand *MMO = MF->getMachineMemOperand(
797 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
806bool MipsFastISel::emitStore(MVT VT,
unsigned SrcReg,
Address &Addr) {
822 if (UnsupportedFPMode)
827 if (UnsupportedFPMode)
834 if (Addr.isRegBase()) {
835 simplifyAddress(Addr);
836 emitInstStore(
Opc, SrcReg, Addr.getReg(), Addr.getOffset());
839 if (Addr.isFIBase()) {
840 unsigned FI = Addr.getFI();
841 int64_t
Offset = Addr.getOffset();
842 MachineFrameInfo &MFI = MF->getFrameInfo();
843 MachineMemOperand *MMO = MF->getMachineMemOperand(
846 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
856bool MipsFastISel::selectLogicalOp(
const Instruction *
I) {
858 if (!isTypeSupported(
I->getType(), VT))
862 switch (
I->getOpcode()) {
865 case Instruction::And:
866 ResultReg = emitLogicalOp(
ISD::AND, VT,
I->getOperand(0),
I->getOperand(1));
868 case Instruction::Or:
869 ResultReg = emitLogicalOp(
ISD::OR, VT,
I->getOperand(0),
I->getOperand(1));
871 case Instruction::Xor:
872 ResultReg = emitLogicalOp(
ISD::XOR, VT,
I->getOperand(0),
I->getOperand(1));
879 updateValueMap(
I, ResultReg);
883bool MipsFastISel::selectLoad(
const Instruction *
I) {
892 if (!isLoadTypeLegal(LI->
getType(), VT))
908 updateValueMap(LI, ResultReg);
912bool MipsFastISel::selectStore(
const Instruction *
I) {
915 Value *Op0 =
SI->getOperand(0);
924 if (!isLoadTypeLegal(
SI->getOperand(0)->getType(), VT))
933 SrcReg = getRegForValue(Op0);
939 if (!computeAddress(
SI->getOperand(1), Addr))
949bool MipsFastISel::selectBranch(
const Instruction *
I) {
951 MachineBasicBlock *BrBB = FuncInfo.MBB;
960 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->
getSuccessor(1));
964 unsigned ZExtCondReg = 0;
967 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
974 if (ZExtCondReg == 0) {
979 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32,
true);
980 if (ZExtCondReg == 0)
984 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;
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");
1343 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1344 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1345 auto NextGPR32 = GPR32ArgRegs.
begin();
1346 auto NextFGR32 = FGR32ArgRegs.begin();
1347 auto NextAFGR64 = AFGR64ArgRegs.begin();
1349 struct AllocatedReg {
1359 for (
const auto &FormalArg :
F->args()) {
1360 if (FormalArg.hasAttribute(Attribute::InReg) ||
1361 FormalArg.hasAttribute(Attribute::StructRet) ||
1362 FormalArg.hasAttribute(Attribute::ByVal)) {
1363 LLVM_DEBUG(dbgs() <<
".. gave up (inreg, structret, byval)\n");
1367 Type *ArgTy = FormalArg.getType();
1368 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {
1369 LLVM_DEBUG(dbgs() <<
".. gave up (struct, array, or vector)\n");
1376 if (!ArgVT.isSimple()) {
1377 LLVM_DEBUG(dbgs() <<
".. .. gave up (not a simple type)\n");
1381 switch (ArgVT.getSimpleVT().
SimpleTy) {
1385 if (!FormalArg.hasAttribute(Attribute::SExt) &&
1386 !FormalArg.hasAttribute(Attribute::ZExt)) {
1389 LLVM_DEBUG(dbgs() <<
".. .. gave up (i8/i16 arg is not extended)\n");
1393 if (NextGPR32 == GPR32ArgRegs.
end()) {
1394 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1399 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1402 NextFGR32 = FGR32ArgRegs.end();
1403 NextAFGR64 = AFGR64ArgRegs.end();
1407 if (FormalArg.hasAttribute(Attribute::ZExt)) {
1409 LLVM_DEBUG(dbgs() <<
".. .. gave up (i32 arg is zero extended)\n");
1413 if (NextGPR32 == GPR32ArgRegs.
end()) {
1414 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1419 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1422 NextFGR32 = FGR32ArgRegs.end();
1423 NextAFGR64 = AFGR64ArgRegs.end();
1427 if (UnsupportedFPMode) {
1431 if (NextFGR32 == FGR32ArgRegs.end()) {
1432 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of FGR32 arguments)\n");
1436 Allocation.
emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1439 if (NextGPR32 != GPR32ArgRegs.
end())
1441 if (NextAFGR64 != AFGR64ArgRegs.end())
1446 if (UnsupportedFPMode) {
1450 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1451 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of AFGR64 arguments)\n");
1455 Allocation.
emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1458 if (NextGPR32 != GPR32ArgRegs.
end())
1460 if (NextGPR32 != GPR32ArgRegs.
end())
1462 if (NextFGR32 != FGR32ArgRegs.end())
1472 for (
const auto &FormalArg :
F->args()) {
1473 unsigned ArgNo = FormalArg.getArgNo();
1474 unsigned SrcReg = Allocation[ArgNo].Reg;
1475 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1479 Register ResultReg = createResultReg(Allocation[ArgNo].RC);
1480 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1481 TII.get(TargetOpcode::COPY), ResultReg)
1482 .addReg(DstReg, getKillRegState(true));
1483 updateValueMap(&FormalArg, ResultReg);
1488 unsigned IncomingArgSizeInBytes = 0;
1493 IncomingArgSizeInBytes = std::max(
getABI().GetCalleeAllocdArgSizeInBytes(CC),
1494 IncomingArgSizeInBytes);
1496 MF->getInfo<MipsFunctionInfo>()->setFormalArgInfo(IncomingArgSizeInBytes,
1502bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1503 CallingConv::ID CC = CLI.CallConv;
1504 bool IsTailCall = CLI.IsTailCall;
1505 bool IsVarArg = CLI.IsVarArg;
1510 if (CC == CallingConv::Fast)
1523 if (CLI.RetTy->isVoidTy())
1524 RetVT = MVT::isVoid;
1525 else if (!isTypeSupported(CLI.RetTy, RetVT))
1528 for (
auto Flag : CLI.OutFlags)
1534 OutVTs.
reserve(CLI.OutVals.size());
1536 for (
auto *Val : CLI.OutVals) {
1538 if (!isTypeLegal(Val->getType(), VT) &&
1539 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
1550 if (!computeCallAddress(Callee, Addr))
1555 if (!processCallArgs(CLI, OutVTs, NumBytes))
1558 if (!Addr.getGlobalValue())
1562 unsigned DestAddress;
1564 DestAddress = materializeExternalCallSym(Symbol);
1566 DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);
1567 emitInst(TargetOpcode::COPY,
getABI().getTempReg(9,
false))
1568 .addReg(DestAddress);
1569 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1570 TII.get(Mips::JALR), Mips::RA)
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;
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];
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))
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::CondBr:
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,
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)
2166 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
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.
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.