72#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);
251 :
FastISel(funcInfo, libInfo, libcallLowering),
262 bool fastSelectInstruction(
const Instruction *
I)
override;
264#include "MipsGenFastISel.inc"
288#define GET_CALLING_CONV_IMPL
289#include "MipsGenCallingConv.inc"
295unsigned MipsFastISel::emitLogicalOp(
unsigned ISDOpc, MVT RetVT,
322 RHSReg = materializeInt(
C, MVT::i32);
324 RHSReg = getRegForValue(
RHS);
328 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
332 emitInst(
Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
336Register MipsFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
338 "Alloca should always return a pointer.");
340 auto SI = FuncInfo.StaticAllocaMap.find(AI);
342 if (SI != FuncInfo.StaticAllocaMap.end()) {
343 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
344 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::LEA_ADDiu),
354unsigned MipsFastISel::materializeInt(
const Constant *
C, MVT VT) {
355 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
362unsigned MipsFastISel::materialize32BitInt(int64_t Imm,
364 Register ResultReg = createResultReg(RC);
367 unsigned Opc = Mips::ADDiu;
368 emitInst(
Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
371 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);
374 unsigned Lo =
Imm & 0xFFFF;
375 unsigned Hi = (
Imm >> 16) & 0xFFFF;
378 Register TmpReg = createResultReg(RC);
379 emitInst(Mips::LUi, TmpReg).addImm(
Hi);
380 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(
Lo);
382 emitInst(Mips::LUi, ResultReg).addImm(
Hi);
387unsigned MipsFastISel::materializeFP(
const ConstantFP *CFP, MVT VT) {
388 if (UnsupportedFPMode)
391 if (VT == MVT::f32) {
393 Register DestReg = createResultReg(RC);
394 unsigned TempReg = materialize32BitInt(Imm, &Mips::GPR32RegClass);
395 emitInst(Mips::MTC1, DestReg).addReg(TempReg);
397 }
else if (VT == MVT::f64) {
399 Register DestReg = createResultReg(RC);
400 unsigned TempReg1 = materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);
402 materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
403 emitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);
409unsigned MipsFastISel::materializeGV(
const GlobalValue *GV, MVT VT) {
414 Register DestReg = createResultReg(RC);
420 emitInst(Mips::LW, DestReg)
425 Register TempReg = createResultReg(RC);
426 emitInst(Mips::ADDiu, TempReg)
434unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {
436 Register DestReg = createResultReg(RC);
437 emitInst(Mips::LW, DestReg)
445Register MipsFastISel::fastMaterializeConstant(
const Constant *
C) {
454 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
456 return materializeGV(GV, VT);
458 return materializeInt(
C, VT);
463bool MipsFastISel::computeAddress(
const Value *Obj,
Address &Addr) {
464 const User *
U =
nullptr;
465 unsigned Opcode = Instruction::UserOp1;
469 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
470 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
471 Opcode =
I->getOpcode();
475 Opcode =
C->getOpcode();
481 case Instruction::BitCast:
483 return computeAddress(
U->getOperand(0), Addr);
484 case Instruction::GetElementPtr: {
486 int64_t TmpOffset = Addr.getOffset();
494 const StructLayout *SL =
DL.getStructLayout(STy);
502 TmpOffset += CI->getSExtValue() * S;
505 if (canFoldAddIntoGEP(U,
Op)) {
515 goto unsupported_gep;
520 Addr.setOffset(TmpOffset);
521 if (computeAddress(
U->getOperand(0), Addr))
528 case Instruction::Alloca: {
530 auto SI = FuncInfo.StaticAllocaMap.find(AI);
531 if (SI != FuncInfo.StaticAllocaMap.end()) {
532 Addr.setKind(Address::FrameIndexBase);
533 Addr.setFI(
SI->second);
539 Addr.setReg(getRegForValue(Obj));
540 return Addr.getReg() != 0;
543bool MipsFastISel::computeCallAddress(
const Value *V,
Address &Addr) {
544 const User *
U =
nullptr;
545 unsigned Opcode = Instruction::UserOp1;
550 if (
I->getParent() == FuncInfo.MBB->getBasicBlock()) {
551 Opcode =
I->getOpcode();
555 Opcode =
C->getOpcode();
562 case Instruction::BitCast:
564 return computeCallAddress(
U->getOperand(0), Addr);
566 case Instruction::IntToPtr:
570 return computeCallAddress(
U->getOperand(0), Addr);
572 case Instruction::PtrToInt:
575 return computeCallAddress(
U->getOperand(0), Addr);
580 Addr.setGlobalValue(GV);
585 if (!Addr.getGlobalValue()) {
586 Addr.setReg(getRegForValue(V));
587 return Addr.getReg() != 0;
593bool MipsFastISel::isTypeLegal(
Type *Ty, MVT &VT) {
596 if (evt == MVT::Other || !evt.
isSimple())
605bool MipsFastISel::isTypeSupported(
Type *Ty, MVT &VT) {
609 if (isTypeLegal(Ty, VT))
614 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
620bool MipsFastISel::isLoadTypeLegal(
Type *Ty, MVT &VT) {
621 if (isTypeLegal(Ty, VT))
626 if (VT == MVT::i8 || VT == MVT::i16)
635bool MipsFastISel::emitCmp(
unsigned ResultReg,
const CmpInst *CI) {
638 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(
Left, IsUnsigned);
641 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(
Right, IsUnsigned);
650 Register TempReg = createResultReg(&Mips::GPR32RegClass);
651 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
652 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
656 Register TempReg = createResultReg(&Mips::GPR32RegClass);
657 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
658 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
662 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
665 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
668 Register TempReg = createResultReg(&Mips::GPR32RegClass);
669 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
670 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
674 Register TempReg = createResultReg(&Mips::GPR32RegClass);
675 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
676 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
680 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
683 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
686 Register TempReg = createResultReg(&Mips::GPR32RegClass);
687 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
688 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
692 Register TempReg = createResultReg(&Mips::GPR32RegClass);
693 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
694 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
703 if (UnsupportedFPMode)
705 bool IsFloat =
Left->getType()->isFloatTy();
706 bool IsDouble =
Left->getType()->isDoubleTy();
707 if (!IsFloat && !IsDouble)
709 unsigned Opc, CondMovOpc;
712 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
713 CondMovOpc = Mips::MOVT_I;
716 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
717 CondMovOpc = Mips::MOVF_I;
720 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
721 CondMovOpc = Mips::MOVT_I;
724 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
725 CondMovOpc = Mips::MOVT_I;
728 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
729 CondMovOpc = Mips::MOVF_I;
732 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
733 CondMovOpc = Mips::MOVF_I;
738 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);
739 Register RegWithOne = createResultReg(&Mips::GPR32RegClass);
740 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
741 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
742 emitInst(
Opc).addReg(Mips::FCC0, RegState::Define).addReg(LeftReg)
744 emitInst(CondMovOpc, ResultReg)
747 .addReg(RegWithZero);
754bool MipsFastISel::emitLoad(MVT VT,
unsigned &ResultReg,
Address &Addr) {
761 ResultReg = createResultReg(&Mips::GPR32RegClass);
765 ResultReg = createResultReg(&Mips::GPR32RegClass);
769 ResultReg = createResultReg(&Mips::GPR32RegClass);
773 if (UnsupportedFPMode)
775 ResultReg = createResultReg(&Mips::FGR32RegClass);
779 if (UnsupportedFPMode)
781 ResultReg = createResultReg(&Mips::AFGR64RegClass);
787 if (Addr.isRegBase()) {
788 simplifyAddress(Addr);
789 emitInstLoad(
Opc, ResultReg, Addr.getReg(), Addr.getOffset());
792 if (Addr.isFIBase()) {
793 unsigned FI = Addr.getFI();
794 int64_t
Offset = Addr.getOffset();
795 MachineFrameInfo &MFI = MF->getFrameInfo();
796 MachineMemOperand *MMO = MF->getMachineMemOperand(
799 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
808bool MipsFastISel::emitStore(MVT VT,
unsigned SrcReg,
Address &Addr) {
824 if (UnsupportedFPMode)
829 if (UnsupportedFPMode)
836 if (Addr.isRegBase()) {
837 simplifyAddress(Addr);
838 emitInstStore(
Opc, SrcReg, Addr.getReg(), Addr.getOffset());
841 if (Addr.isFIBase()) {
842 unsigned FI = Addr.getFI();
843 int64_t
Offset = Addr.getOffset();
844 MachineFrameInfo &MFI = MF->getFrameInfo();
845 MachineMemOperand *MMO = MF->getMachineMemOperand(
848 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
858bool MipsFastISel::selectLogicalOp(
const Instruction *
I) {
860 if (!isTypeSupported(
I->getType(), VT))
864 switch (
I->getOpcode()) {
867 case Instruction::And:
868 ResultReg = emitLogicalOp(
ISD::AND, VT,
I->getOperand(0),
I->getOperand(1));
870 case Instruction::Or:
871 ResultReg = emitLogicalOp(
ISD::OR, VT,
I->getOperand(0),
I->getOperand(1));
873 case Instruction::Xor:
874 ResultReg = emitLogicalOp(
ISD::XOR, VT,
I->getOperand(0),
I->getOperand(1));
881 updateValueMap(
I, ResultReg);
885bool MipsFastISel::selectLoad(
const Instruction *
I) {
894 if (!isLoadTypeLegal(LI->
getType(), VT))
910 updateValueMap(LI, ResultReg);
914bool MipsFastISel::selectStore(
const Instruction *
I) {
917 Value *Op0 =
SI->getOperand(0);
926 if (!isLoadTypeLegal(
SI->getOperand(0)->getType(), VT))
935 SrcReg = getRegForValue(Op0);
941 if (!computeAddress(
SI->getOperand(1), Addr))
951bool MipsFastISel::selectBranch(
const Instruction *
I) {
953 MachineBasicBlock *BrBB = FuncInfo.MBB;
962 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->
getSuccessor(1));
966 unsigned ZExtCondReg = 0;
969 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
976 if (ZExtCondReg == 0) {
981 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32,
true);
982 if (ZExtCondReg == 0)
986 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::BGTZ))
989 finishCondBranch(BI->getParent(),
TBB, FBB);
993bool MipsFastISel::selectCmp(
const Instruction *
I) {
995 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
998 updateValueMap(
I, ResultReg);
1003bool MipsFastISel::selectFPExt(
const Instruction *
I) {
1004 if (UnsupportedFPMode)
1006 Value *Src =
I->getOperand(0);
1010 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
1014 getRegForValue(Src);
1019 Register DestReg = createResultReg(&Mips::AFGR64RegClass);
1020 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1021 updateValueMap(
I, DestReg);
1025bool MipsFastISel::selectSelect(
const Instruction *
I) {
1031 if (!isTypeSupported(
I->getType(), VT) || UnsupportedFPMode) {
1033 dbgs() <<
".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1037 unsigned CondMovOpc;
1041 CondMovOpc = Mips::MOVN_I_I;
1042 RC = &Mips::GPR32RegClass;
1043 }
else if (VT == MVT::f32) {
1044 CondMovOpc = Mips::MOVN_I_S;
1045 RC = &Mips::FGR32RegClass;
1046 }
else if (VT == MVT::f64) {
1047 CondMovOpc = Mips::MOVN_I_D32;
1048 RC = &Mips::AFGR64RegClass;
1054 Register Src1Reg = getRegForValue(
SI->getTrueValue());
1055 Register Src2Reg = getRegForValue(
SI->getFalseValue());
1058 if (!Src1Reg || !Src2Reg || !CondReg)
1061 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1065 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg,
true))
1068 Register ResultReg = createResultReg(RC);
1069 Register TempReg = createResultReg(RC);
1071 if (!ResultReg || !TempReg)
1074 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1075 emitInst(CondMovOpc, ResultReg)
1076 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1077 updateValueMap(
I, ResultReg);
1082bool MipsFastISel::selectFPTrunc(
const Instruction *
I) {
1083 if (UnsupportedFPMode)
1085 Value *Src =
I->getOperand(0);
1089 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
1092 Register SrcReg = getRegForValue(Src);
1096 Register DestReg = createResultReg(&Mips::FGR32RegClass);
1100 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1101 updateValueMap(
I, DestReg);
1106bool MipsFastISel::selectFPToInt(
const Instruction *
I,
bool IsSigned) {
1107 if (UnsupportedFPMode)
1113 Type *DstTy =
I->getType();
1114 if (!isTypeLegal(DstTy, DstVT))
1117 if (DstVT != MVT::i32)
1120 Value *Src =
I->getOperand(0);
1121 Type *SrcTy = Src->getType();
1122 if (!isTypeLegal(SrcTy, SrcVT))
1125 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1128 Register SrcReg = getRegForValue(Src);
1134 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1135 Register TempReg = createResultReg(&Mips::FGR32RegClass);
1136 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1139 emitInst(
Opc, TempReg).addReg(SrcReg);
1140 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1142 updateValueMap(
I, DestReg);
1146bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1147 SmallVectorImpl<MVT> &OutVTs,
1148 unsigned &NumBytes) {
1149 CallingConv::ID CC = CLI.CallConv;
1152 for (
const ArgListEntry &Arg : CLI.Args)
1154 CCState CCInfo(CC,
false, *FuncInfo.MF, ArgLocs, *
Context);
1155 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,
1156 CCAssignFnForCall(CC));
1158 NumBytes = CCInfo.getStackSize();
1163 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1166 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1167 CCValAssign &VA = ArgLocs[i];
1173 if (ArgVT == MVT::f32) {
1175 }
else if (ArgVT == MVT::f64) {
1181 }
else if (i == 1) {
1182 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {
1183 if (ArgVT == MVT::f32) {
1185 }
else if (ArgVT == MVT::f64) {
1193 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||
1194 (ArgVT == MVT::i8)) &&
1213 Register ArgReg = getRegForValue(ArgVal);
1225 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
false);
1233 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
true);
1244 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1268 unsigned BEAlign = 0;
1269 if (ArgSize < 8 && !Subtarget->isLittle())
1270 BEAlign = 8 - ArgSize;
1273 Addr.setKind(Address::RegBase);
1274 Addr.setReg(Mips::SP);
1278 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
1290bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,
1291 unsigned NumBytes) {
1292 CallingConv::ID CC = CLI.CallConv;
1293 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1294 if (RetVT != MVT::isVoid) {
1296 MipsCCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *
Context);
1298 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);
1301 if (RVLocs.
size() != 1)
1304 MVT CopyVT = RVLocs[0].getValVT();
1306 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
1312 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1313 TII.get(TargetOpcode::COPY),
1314 ResultReg).
addReg(RVLocs[0].getLocReg());
1315 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1317 CLI.ResultReg = ResultReg;
1318 CLI.NumResultRegs = 1;
1323bool MipsFastISel::fastLowerArguments() {
1326 if (!FuncInfo.CanLowerReturn) {
1332 if (
F->isVarArg()) {
1337 CallingConv::ID CC =
F->getCallingConv();
1338 if (CC != CallingConv::C) {
1339 LLVM_DEBUG(
dbgs() <<
".. gave up (calling convention is not C)\n");
1343 std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,
1345 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1346 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1347 auto NextGPR32 = GPR32ArgRegs.begin();
1348 auto NextFGR32 = FGR32ArgRegs.begin();
1349 auto NextAFGR64 = AFGR64ArgRegs.begin();
1351 struct AllocatedReg {
1361 for (
const auto &FormalArg :
F->args()) {
1362 if (FormalArg.hasAttribute(Attribute::InReg) ||
1363 FormalArg.hasAttribute(Attribute::StructRet) ||
1364 FormalArg.hasAttribute(Attribute::ByVal)) {
1365 LLVM_DEBUG(dbgs() <<
".. gave up (inreg, structret, byval)\n");
1369 Type *ArgTy = FormalArg.getType();
1370 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {
1371 LLVM_DEBUG(dbgs() <<
".. gave up (struct, array, or vector)\n");
1378 if (!ArgVT.isSimple()) {
1379 LLVM_DEBUG(dbgs() <<
".. .. gave up (not a simple type)\n");
1383 switch (ArgVT.getSimpleVT().
SimpleTy) {
1387 if (!FormalArg.hasAttribute(Attribute::SExt) &&
1388 !FormalArg.hasAttribute(Attribute::ZExt)) {
1391 LLVM_DEBUG(dbgs() <<
".. .. gave up (i8/i16 arg is not extended)\n");
1395 if (NextGPR32 == GPR32ArgRegs.end()) {
1396 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1401 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1404 NextFGR32 = FGR32ArgRegs.end();
1405 NextAFGR64 = AFGR64ArgRegs.end();
1409 if (FormalArg.hasAttribute(Attribute::ZExt)) {
1411 LLVM_DEBUG(dbgs() <<
".. .. gave up (i32 arg is zero extended)\n");
1415 if (NextGPR32 == GPR32ArgRegs.end()) {
1416 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1421 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1424 NextFGR32 = FGR32ArgRegs.end();
1425 NextAFGR64 = AFGR64ArgRegs.end();
1429 if (UnsupportedFPMode) {
1433 if (NextFGR32 == FGR32ArgRegs.end()) {
1434 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of FGR32 arguments)\n");
1438 Allocation.
emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1441 if (NextGPR32 != GPR32ArgRegs.end())
1443 if (NextAFGR64 != AFGR64ArgRegs.end())
1448 if (UnsupportedFPMode) {
1452 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1453 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of AFGR64 arguments)\n");
1457 Allocation.
emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1460 if (NextGPR32 != GPR32ArgRegs.end())
1462 if (NextGPR32 != GPR32ArgRegs.end())
1464 if (NextFGR32 != FGR32ArgRegs.end())
1474 for (
const auto &FormalArg :
F->args()) {
1475 unsigned ArgNo = FormalArg.getArgNo();
1476 unsigned SrcReg = Allocation[ArgNo].Reg;
1477 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1481 Register ResultReg = createResultReg(Allocation[ArgNo].RC);
1482 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1483 TII.get(TargetOpcode::COPY), ResultReg)
1484 .addReg(DstReg, getKillRegState(true));
1485 updateValueMap(&FormalArg, ResultReg);
1490 unsigned IncomingArgSizeInBytes = 0;
1495 IncomingArgSizeInBytes = std::max(getABI().GetCalleeAllocdArgSizeInBytes(CC),
1496 IncomingArgSizeInBytes);
1498 MF->getInfo<MipsFunctionInfo>()->setFormalArgInfo(IncomingArgSizeInBytes,
1504bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1505 CallingConv::ID CC = CLI.CallConv;
1506 bool IsTailCall = CLI.IsTailCall;
1507 bool IsVarArg = CLI.IsVarArg;
1512 if (CC == CallingConv::Fast)
1525 if (CLI.RetTy->isVoidTy())
1526 RetVT = MVT::isVoid;
1527 else if (!isTypeSupported(CLI.RetTy, RetVT))
1530 for (
auto Flag : CLI.OutFlags)
1536 OutVTs.
reserve(CLI.OutVals.size());
1538 for (
auto *Val : CLI.OutVals) {
1540 if (!isTypeLegal(Val->getType(), VT) &&
1541 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
1552 if (!computeCallAddress(Callee, Addr))
1557 if (!processCallArgs(CLI, OutVTs, NumBytes))
1560 if (!Addr.getGlobalValue())
1564 unsigned DestAddress;
1566 DestAddress = materializeExternalCallSym(Symbol);
1568 DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);
1569 emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);
1570 MachineInstrBuilder MIB =
1571 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::JALR),
1572 Mips::RA).
addReg(Mips::T9);
1575 for (
auto Reg : CLI.OutRegs)
1590 MIB.
addSym(FuncInfo.MF->getContext().getOrCreateSymbol(
1595 return finishCall(CLI, RetVT, NumBytes);
1598bool MipsFastISel::fastLowerIntrinsicCall(
const IntrinsicInst *
II) {
1599 switch (
II->getIntrinsicID()) {
1602 case Intrinsic::bswap: {
1603 Type *RetTy =
II->getCalledFunction()->getReturnType();
1606 if (!isTypeSupported(RetTy, VT))
1609 Register SrcReg = getRegForValue(
II->getOperand(0));
1612 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1615 if (VT == MVT::i16) {
1617 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1618 updateValueMap(
II, DestReg);
1621 unsigned TempReg[3];
1622 for (
unsigned &R : TempReg) {
1623 R = createResultReg(&Mips::GPR32RegClass);
1627 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1628 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1629 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);
1630 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);
1631 updateValueMap(
II, DestReg);
1634 }
else if (VT == MVT::i32) {
1636 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1637 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1638 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1639 updateValueMap(
II, DestReg);
1642 unsigned TempReg[8];
1643 for (
unsigned &R : TempReg) {
1644 R = createResultReg(&Mips::GPR32RegClass);
1649 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1650 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1651 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1652 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1654 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1655 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1657 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1658 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1659 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1660 updateValueMap(
II, DestReg);
1666 case Intrinsic::memcpy:
1667 case Intrinsic::memmove: {
1670 if (MTI->isVolatile())
1672 if (!MTI->getLength()->getType()->isIntegerTy(32))
1675 return lowerCallTo(
II, IntrMemName,
II->arg_size() - 1);
1677 case Intrinsic::memset: {
1684 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
1690bool MipsFastISel::selectRet(
const Instruction *
I) {
1691 const Function &
F = *
I->getParent()->getParent();
1696 if (!FuncInfo.CanLowerReturn)
1700 SmallVector<unsigned, 4> RetRegs;
1703 CallingConv::ID CC =
F.getCallingConv();
1706 if (CC == CallingConv::Fast)
1714 MipsCCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
1717 CCInfo.AnalyzeReturn(Outs, RetCC);
1720 if (ValLocs.
size() != 1)
1723 CCValAssign &VA = ValLocs[0];
1742 if (!MRI.getRegClass(SrcReg)->contains(DestReg))
1753 if (RVVT == MVT::f128)
1757 if (RVVT == MVT::f64 && UnsupportedFPMode) {
1764 if (RVVT != DestVT) {
1765 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
1768 if (Outs[0].
Flags.isZExt() || Outs[0].Flags.isSExt()) {
1769 bool IsZExt = Outs[0].Flags.isZExt();
1770 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1777 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1778 TII.get(TargetOpcode::COPY), DestReg).
addReg(SrcReg);
1783 MachineInstrBuilder MIB = emitInst(Mips::RetRA);
1784 for (
unsigned Reg : RetRegs)
1789bool MipsFastISel::selectTrunc(
const Instruction *
I) {
1798 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1800 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1809 updateValueMap(
I, SrcReg);
1813bool MipsFastISel::selectIntExt(
const Instruction *
I) {
1814 Type *DestTy =
I->getType();
1815 Value *Src =
I->getOperand(0);
1816 Type *SrcTy = Src->getType();
1819 Register SrcReg = getRegForValue(Src);
1823 EVT SrcEVT, DestEVT;
1833 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1835 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1837 updateValueMap(
I, ResultReg);
1841bool MipsFastISel::emitIntSExt32r1(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1854 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1855 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1856 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1860bool MipsFastISel::emitIntSExt32r2(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1866 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1869 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1875bool MipsFastISel::emitIntSExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1877 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
1880 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1881 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1884bool MipsFastISel::emitIntZExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1902 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);
1906bool MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1907 unsigned DestReg,
bool IsZExt) {
1912 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||
1913 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))
1916 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1917 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1920unsigned MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1922 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1923 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1927bool MipsFastISel::selectDivRem(
const Instruction *
I,
unsigned ISDOpcode) {
1933 if (DestVT != MVT::i32)
1937 switch (ISDOpcode) {
1942 DivOpc = Mips::SDIV;
1946 DivOpc = Mips::UDIV;
1950 Register Src0Reg = getRegForValue(
I->getOperand(0));
1951 Register Src1Reg = getRegForValue(
I->getOperand(1));
1952 if (!Src0Reg || !Src1Reg)
1955 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1958 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1961 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1968 emitInst(MFOpc, ResultReg);
1970 updateValueMap(
I, ResultReg);
1974bool MipsFastISel::selectShift(
const Instruction *
I) {
1977 if (!isTypeSupported(
I->getType(), RetVT))
1980 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1984 unsigned Opcode =
I->getOpcode();
1985 const Value *Op0 =
I->getOperand(0);
1986 Register Op0Reg = getRegForValue(Op0);
1991 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1992 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1997 bool IsZExt = Opcode == Instruction::LShr;
1998 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))
2005 uint64_t ShiftVal =
C->getZExtValue();
2010 case Instruction::Shl:
2013 case Instruction::AShr:
2016 case Instruction::LShr:
2021 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2022 updateValueMap(
I, ResultReg);
2026 Register Op1Reg = getRegForValue(
I->getOperand(1));
2033 case Instruction::Shl:
2034 Opcode = Mips::SLLV;
2036 case Instruction::AShr:
2037 Opcode = Mips::SRAV;
2039 case Instruction::LShr:
2040 Opcode = Mips::SRLV;
2044 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2045 updateValueMap(
I, ResultReg);
2049bool MipsFastISel::fastSelectInstruction(
const Instruction *
I) {
2050 switch (
I->getOpcode()) {
2053 case Instruction::Load:
2054 return selectLoad(
I);
2055 case Instruction::Store:
2056 return selectStore(
I);
2057 case Instruction::SDiv:
2061 case Instruction::UDiv:
2065 case Instruction::SRem:
2069 case Instruction::URem:
2073 case Instruction::Shl:
2074 case Instruction::LShr:
2075 case Instruction::AShr:
2076 return selectShift(
I);
2077 case Instruction::And:
2078 case Instruction::Or:
2079 case Instruction::Xor:
2080 return selectLogicalOp(
I);
2081 case Instruction::CondBr:
2082 return selectBranch(
I);
2083 case Instruction::Ret:
2084 return selectRet(
I);
2085 case Instruction::Trunc:
2086 return selectTrunc(
I);
2087 case Instruction::ZExt:
2088 case Instruction::SExt:
2089 return selectIntExt(
I);
2090 case Instruction::FPTrunc:
2091 return selectFPTrunc(
I);
2092 case Instruction::FPExt:
2093 return selectFPExt(
I);
2094 case Instruction::FPToSI:
2095 return selectFPToInt(
I,
true);
2096 case Instruction::FPToUI:
2097 return selectFPToInt(
I,
false);
2098 case Instruction::ICmp:
2099 case Instruction::FCmp:
2100 return selectCmp(
I);
2101 case Instruction::Select:
2102 return selectSelect(
I);
2107unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(
const Value *V,
2114 if (VMVT == MVT::i1)
2117 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
2118 Register TempReg = createResultReg(&Mips::GPR32RegClass);
2119 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
2126void MipsFastISel::simplifyAddress(
Address &Addr) {
2129 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
2130 Register DestReg = createResultReg(&Mips::GPR32RegClass);
2131 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());
2132 Addr.setReg(DestReg);
2137unsigned MipsFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2139 unsigned Op0,
unsigned Op1) {
2146 if (MachineInstOpcode == Mips::MUL) {
2147 Register ResultReg = createResultReg(RC);
2148 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
2151 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
2154 .
addReg(Mips::HI0, RegState::ImplicitDefine | RegState::Dead)
2155 .
addReg(Mips::LO0, RegState::ImplicitDefine | RegState::Dead);
2167 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 (such as G_OR or G_SDIV),...
static void emitLoad(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPostDec)
Emit a load-pair instruction for frame-destroy.
static void emitStore(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPreDec)
Emit a store-pair instruction for frame-setup.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the FastISel class.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
cl::opt< bool > EmitJalrReloc
static 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.
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 & 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
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.
@ C
The default llvm calling convention, compatible with C.
@ AND
Bitwise operators - logical and, logical or, logical xor.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering)
@ 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
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.