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#include "MipsGenCallingConv.inc"
294unsigned MipsFastISel::emitLogicalOp(
unsigned ISDOpc, MVT RetVT,
321 RHSReg = materializeInt(
C, MVT::i32);
323 RHSReg = getRegForValue(
RHS);
327 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
331 emitInst(
Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
335Register MipsFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
337 "Alloca should always return a pointer.");
339 DenseMap<const AllocaInst *, int>::iterator
SI =
340 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)
357 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
362unsigned MipsFastISel::materialize32BitInt(int64_t Imm,
363 const TargetRegisterClass *RC) {
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) {
392 const TargetRegisterClass *RC = &Mips::FGR32RegClass;
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) {
398 const TargetRegisterClass *RC = &Mips::AFGR64RegClass;
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) {
413 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
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) {
435 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
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 DenseMap<const AllocaInst *, int>::iterator
SI =
531 FuncInfo.StaticAllocaMap.find(AI);
532 if (SI != FuncInfo.StaticAllocaMap.end()) {
533 Addr.setKind(Address::FrameIndexBase);
534 Addr.setFI(
SI->second);
540 Addr.setReg(getRegForValue(Obj));
541 return Addr.getReg() != 0;
544bool MipsFastISel::computeCallAddress(
const Value *V,
Address &Addr) {
545 const User *
U =
nullptr;
546 unsigned Opcode = Instruction::UserOp1;
551 if (
I->getParent() == FuncInfo.MBB->getBasicBlock()) {
552 Opcode =
I->getOpcode();
556 Opcode =
C->getOpcode();
563 case Instruction::BitCast:
565 return computeCallAddress(
U->getOperand(0), Addr);
567 case Instruction::IntToPtr:
571 return computeCallAddress(
U->getOperand(0), Addr);
573 case Instruction::PtrToInt:
576 return computeCallAddress(
U->getOperand(0), Addr);
581 Addr.setGlobalValue(GV);
586 if (!Addr.getGlobalValue()) {
587 Addr.setReg(getRegForValue(V));
588 return Addr.getReg() != 0;
594bool MipsFastISel::isTypeLegal(
Type *Ty, MVT &VT) {
597 if (evt == MVT::Other || !evt.
isSimple())
606bool MipsFastISel::isTypeSupported(
Type *Ty, MVT &VT) {
610 if (isTypeLegal(Ty, VT))
615 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
621bool MipsFastISel::isLoadTypeLegal(
Type *Ty, MVT &VT) {
622 if (isTypeLegal(Ty, VT))
627 if (VT == MVT::i8 || VT == MVT::i16)
636bool MipsFastISel::emitCmp(
unsigned ResultReg,
const CmpInst *CI) {
639 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(
Left, IsUnsigned);
642 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(
Right, IsUnsigned);
651 Register TempReg = createResultReg(&Mips::GPR32RegClass);
652 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
653 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
657 Register TempReg = createResultReg(&Mips::GPR32RegClass);
658 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
659 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
663 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
666 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
669 Register TempReg = createResultReg(&Mips::GPR32RegClass);
670 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
671 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
675 Register TempReg = createResultReg(&Mips::GPR32RegClass);
676 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
677 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
681 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
684 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
687 Register TempReg = createResultReg(&Mips::GPR32RegClass);
688 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
689 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
693 Register TempReg = createResultReg(&Mips::GPR32RegClass);
694 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
695 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
704 if (UnsupportedFPMode)
706 bool IsFloat =
Left->getType()->isFloatTy();
707 bool IsDouble =
Left->getType()->isDoubleTy();
708 if (!IsFloat && !IsDouble)
710 unsigned Opc, CondMovOpc;
713 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
714 CondMovOpc = Mips::MOVT_I;
717 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
718 CondMovOpc = Mips::MOVF_I;
721 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
722 CondMovOpc = Mips::MOVT_I;
725 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
726 CondMovOpc = Mips::MOVT_I;
729 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
730 CondMovOpc = Mips::MOVF_I;
733 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
734 CondMovOpc = Mips::MOVF_I;
739 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);
740 Register RegWithOne = createResultReg(&Mips::GPR32RegClass);
741 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
742 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
745 emitInst(CondMovOpc, ResultReg)
748 .addReg(RegWithZero);
755bool MipsFastISel::emitLoad(MVT VT,
unsigned &ResultReg,
Address &Addr) {
762 ResultReg = createResultReg(&Mips::GPR32RegClass);
766 ResultReg = createResultReg(&Mips::GPR32RegClass);
770 ResultReg = createResultReg(&Mips::GPR32RegClass);
774 if (UnsupportedFPMode)
776 ResultReg = createResultReg(&Mips::FGR32RegClass);
780 if (UnsupportedFPMode)
782 ResultReg = createResultReg(&Mips::AFGR64RegClass);
788 if (Addr.isRegBase()) {
789 simplifyAddress(Addr);
790 emitInstLoad(
Opc, ResultReg, Addr.getReg(), Addr.getOffset());
793 if (Addr.isFIBase()) {
794 unsigned FI = Addr.getFI();
795 int64_t
Offset = Addr.getOffset();
796 MachineFrameInfo &MFI = MF->getFrameInfo();
797 MachineMemOperand *MMO = MF->getMachineMemOperand(
800 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
809bool MipsFastISel::emitStore(MVT VT,
unsigned SrcReg,
Address &Addr) {
825 if (UnsupportedFPMode)
830 if (UnsupportedFPMode)
837 if (Addr.isRegBase()) {
838 simplifyAddress(Addr);
839 emitInstStore(
Opc, SrcReg, Addr.getReg(), Addr.getOffset());
842 if (Addr.isFIBase()) {
843 unsigned FI = Addr.getFI();
844 int64_t
Offset = Addr.getOffset();
845 MachineFrameInfo &MFI = MF->getFrameInfo();
846 MachineMemOperand *MMO = MF->getMachineMemOperand(
849 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
859bool MipsFastISel::selectLogicalOp(
const Instruction *
I) {
861 if (!isTypeSupported(
I->getType(), VT))
865 switch (
I->getOpcode()) {
868 case Instruction::And:
869 ResultReg = emitLogicalOp(
ISD::AND, VT,
I->getOperand(0),
I->getOperand(1));
871 case Instruction::Or:
872 ResultReg = emitLogicalOp(
ISD::OR, VT,
I->getOperand(0),
I->getOperand(1));
874 case Instruction::Xor:
875 ResultReg = emitLogicalOp(
ISD::XOR, VT,
I->getOperand(0),
I->getOperand(1));
882 updateValueMap(
I, ResultReg);
886bool MipsFastISel::selectLoad(
const Instruction *
I) {
895 if (!isLoadTypeLegal(LI->
getType(), VT))
911 updateValueMap(LI, ResultReg);
915bool MipsFastISel::selectStore(
const Instruction *
I) {
918 Value *Op0 =
SI->getOperand(0);
927 if (!isLoadTypeLegal(
SI->getOperand(0)->getType(), VT))
936 SrcReg = getRegForValue(Op0);
942 if (!computeAddress(
SI->getOperand(1), Addr))
952bool MipsFastISel::selectBranch(
const Instruction *
I) {
954 MachineBasicBlock *BrBB = FuncInfo.MBB;
963 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->
getSuccessor(1));
967 unsigned ZExtCondReg = 0;
970 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
977 if (ZExtCondReg == 0) {
982 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32,
true);
983 if (ZExtCondReg == 0)
987 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::BGTZ))
994bool MipsFastISel::selectCmp(
const Instruction *
I) {
996 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
999 updateValueMap(
I, ResultReg);
1004bool MipsFastISel::selectFPExt(
const Instruction *
I) {
1005 if (UnsupportedFPMode)
1007 Value *Src =
I->getOperand(0);
1011 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
1015 getRegForValue(Src);
1020 Register DestReg = createResultReg(&Mips::AFGR64RegClass);
1021 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1022 updateValueMap(
I, DestReg);
1026bool MipsFastISel::selectSelect(
const Instruction *
I) {
1032 if (!isTypeSupported(
I->getType(), VT) || UnsupportedFPMode) {
1034 dbgs() <<
".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1038 unsigned CondMovOpc;
1039 const TargetRegisterClass *RC;
1042 CondMovOpc = Mips::MOVN_I_I;
1043 RC = &Mips::GPR32RegClass;
1044 }
else if (VT == MVT::f32) {
1045 CondMovOpc = Mips::MOVN_I_S;
1046 RC = &Mips::FGR32RegClass;
1047 }
else if (VT == MVT::f64) {
1048 CondMovOpc = Mips::MOVN_I_D32;
1049 RC = &Mips::AFGR64RegClass;
1055 Register Src1Reg = getRegForValue(
SI->getTrueValue());
1056 Register Src2Reg = getRegForValue(
SI->getFalseValue());
1059 if (!Src1Reg || !Src2Reg || !CondReg)
1062 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1066 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg,
true))
1069 Register ResultReg = createResultReg(RC);
1070 Register TempReg = createResultReg(RC);
1072 if (!ResultReg || !TempReg)
1075 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1076 emitInst(CondMovOpc, ResultReg)
1077 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1078 updateValueMap(
I, ResultReg);
1083bool MipsFastISel::selectFPTrunc(
const Instruction *
I) {
1084 if (UnsupportedFPMode)
1086 Value *Src =
I->getOperand(0);
1090 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
1093 Register SrcReg = getRegForValue(Src);
1097 Register DestReg = createResultReg(&Mips::FGR32RegClass);
1101 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1102 updateValueMap(
I, DestReg);
1107bool MipsFastISel::selectFPToInt(
const Instruction *
I,
bool IsSigned) {
1108 if (UnsupportedFPMode)
1114 Type *DstTy =
I->getType();
1115 if (!isTypeLegal(DstTy, DstVT))
1118 if (DstVT != MVT::i32)
1121 Value *Src =
I->getOperand(0);
1122 Type *SrcTy = Src->getType();
1123 if (!isTypeLegal(SrcTy, SrcVT))
1126 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1129 Register SrcReg = getRegForValue(Src);
1135 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1136 Register TempReg = createResultReg(&Mips::FGR32RegClass);
1137 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1140 emitInst(
Opc, TempReg).addReg(SrcReg);
1141 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1143 updateValueMap(
I, DestReg);
1147bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1148 SmallVectorImpl<MVT> &OutVTs,
1149 unsigned &NumBytes) {
1150 CallingConv::ID CC = CLI.CallConv;
1153 for (
const ArgListEntry &Arg : CLI.Args)
1155 CCState CCInfo(CC,
false, *FuncInfo.MF, ArgLocs, *
Context);
1156 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,
1157 CCAssignFnForCall(CC));
1159 NumBytes = CCInfo.getStackSize();
1164 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1167 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1168 CCValAssign &VA = ArgLocs[i];
1174 if (ArgVT == MVT::f32) {
1176 }
else if (ArgVT == MVT::f64) {
1182 }
else if (i == 1) {
1183 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {
1184 if (ArgVT == MVT::f32) {
1186 }
else if (ArgVT == MVT::f64) {
1194 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||
1195 (ArgVT == MVT::i8)) &&
1214 Register ArgReg = getRegForValue(ArgVal);
1226 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
false);
1234 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
true);
1245 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1269 unsigned BEAlign = 0;
1270 if (ArgSize < 8 && !Subtarget->isLittle())
1271 BEAlign = 8 - ArgSize;
1274 Addr.setKind(Address::RegBase);
1275 Addr.setReg(Mips::SP);
1279 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
1291bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,
1292 unsigned NumBytes) {
1293 CallingConv::ID CC = CLI.CallConv;
1294 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1295 if (RetVT != MVT::isVoid) {
1297 MipsCCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *
Context);
1299 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);
1302 if (RVLocs.
size() != 1)
1305 MVT CopyVT = RVLocs[0].getValVT();
1307 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
1313 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1314 TII.get(TargetOpcode::COPY),
1315 ResultReg).
addReg(RVLocs[0].getLocReg());
1316 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1318 CLI.ResultReg = ResultReg;
1319 CLI.NumResultRegs = 1;
1324bool MipsFastISel::fastLowerArguments() {
1327 if (!FuncInfo.CanLowerReturn) {
1333 if (
F->isVarArg()) {
1338 CallingConv::ID CC =
F->getCallingConv();
1339 if (CC != CallingConv::C) {
1340 LLVM_DEBUG(
dbgs() <<
".. gave up (calling convention is not C)\n");
1344 std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,
1346 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1347 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1348 auto NextGPR32 = GPR32ArgRegs.begin();
1349 auto NextFGR32 = FGR32ArgRegs.begin();
1350 auto NextAFGR64 = AFGR64ArgRegs.begin();
1352 struct AllocatedReg {
1353 const TargetRegisterClass *RC;
1355 AllocatedReg(
const TargetRegisterClass *RC,
unsigned Reg)
1362 for (
const auto &FormalArg :
F->args()) {
1363 if (FormalArg.hasAttribute(Attribute::InReg) ||
1364 FormalArg.hasAttribute(Attribute::StructRet) ||
1365 FormalArg.hasAttribute(Attribute::ByVal)) {
1366 LLVM_DEBUG(dbgs() <<
".. gave up (inreg, structret, byval)\n");
1370 Type *ArgTy = FormalArg.getType();
1371 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {
1372 LLVM_DEBUG(dbgs() <<
".. gave up (struct, array, or vector)\n");
1379 if (!ArgVT.isSimple()) {
1380 LLVM_DEBUG(dbgs() <<
".. .. gave up (not a simple type)\n");
1384 switch (ArgVT.getSimpleVT().
SimpleTy) {
1388 if (!FormalArg.hasAttribute(Attribute::SExt) &&
1389 !FormalArg.hasAttribute(Attribute::ZExt)) {
1392 LLVM_DEBUG(dbgs() <<
".. .. gave up (i8/i16 arg is not extended)\n");
1396 if (NextGPR32 == GPR32ArgRegs.end()) {
1397 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1402 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1405 NextFGR32 = FGR32ArgRegs.end();
1406 NextAFGR64 = AFGR64ArgRegs.end();
1410 if (FormalArg.hasAttribute(Attribute::ZExt)) {
1412 LLVM_DEBUG(dbgs() <<
".. .. gave up (i32 arg is zero extended)\n");
1416 if (NextGPR32 == GPR32ArgRegs.end()) {
1417 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1422 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1425 NextFGR32 = FGR32ArgRegs.end();
1426 NextAFGR64 = AFGR64ArgRegs.end();
1430 if (UnsupportedFPMode) {
1434 if (NextFGR32 == FGR32ArgRegs.end()) {
1435 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of FGR32 arguments)\n");
1439 Allocation.
emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1442 if (NextGPR32 != GPR32ArgRegs.end())
1444 if (NextAFGR64 != AFGR64ArgRegs.end())
1449 if (UnsupportedFPMode) {
1453 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1454 LLVM_DEBUG(dbgs() <<
".. .. gave up (ran out of AFGR64 arguments)\n");
1458 Allocation.
emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1461 if (NextGPR32 != GPR32ArgRegs.end())
1463 if (NextGPR32 != GPR32ArgRegs.end())
1465 if (NextFGR32 != FGR32ArgRegs.end())
1475 for (
const auto &FormalArg :
F->args()) {
1476 unsigned ArgNo = FormalArg.getArgNo();
1477 unsigned SrcReg = Allocation[ArgNo].Reg;
1478 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1482 Register ResultReg = createResultReg(Allocation[ArgNo].RC);
1483 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1484 TII.get(TargetOpcode::COPY), ResultReg)
1485 .addReg(DstReg, getKillRegState(true));
1486 updateValueMap(&FormalArg, ResultReg);
1491 unsigned IncomingArgSizeInBytes = 0;
1496 IncomingArgSizeInBytes = std::min(getABI().GetCalleeAllocdArgSizeInBytes(CC),
1497 IncomingArgSizeInBytes);
1499 MF->getInfo<MipsFunctionInfo>()->setFormalArgInfo(IncomingArgSizeInBytes,
1505bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1506 CallingConv::ID CC = CLI.CallConv;
1507 bool IsTailCall = CLI.IsTailCall;
1508 bool IsVarArg = CLI.IsVarArg;
1513 if (CC == CallingConv::Fast)
1526 if (CLI.RetTy->isVoidTy())
1527 RetVT = MVT::isVoid;
1528 else if (!isTypeSupported(CLI.RetTy, RetVT))
1531 for (
auto Flag : CLI.OutFlags)
1537 OutVTs.
reserve(CLI.OutVals.size());
1539 for (
auto *Val : CLI.OutVals) {
1541 if (!isTypeLegal(Val->getType(), VT) &&
1542 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
1553 if (!computeCallAddress(Callee, Addr))
1558 if (!processCallArgs(CLI, OutVTs, NumBytes))
1561 if (!Addr.getGlobalValue())
1565 unsigned DestAddress;
1567 DestAddress = materializeExternalCallSym(Symbol);
1569 DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);
1570 emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);
1571 MachineInstrBuilder MIB =
1572 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::JALR),
1573 Mips::RA).
addReg(Mips::T9);
1576 for (
auto Reg : CLI.OutRegs)
1591 MIB.
addSym(FuncInfo.MF->getContext().getOrCreateSymbol(
1596 return finishCall(CLI, RetVT, NumBytes);
1599bool MipsFastISel::fastLowerIntrinsicCall(
const IntrinsicInst *
II) {
1600 switch (
II->getIntrinsicID()) {
1603 case Intrinsic::bswap: {
1604 Type *RetTy =
II->getCalledFunction()->getReturnType();
1607 if (!isTypeSupported(RetTy, VT))
1610 Register SrcReg = getRegForValue(
II->getOperand(0));
1613 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1616 if (VT == MVT::i16) {
1618 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1619 updateValueMap(
II, DestReg);
1622 unsigned TempReg[3];
1623 for (
unsigned &R : TempReg) {
1624 R = createResultReg(&Mips::GPR32RegClass);
1628 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1629 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1630 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);
1631 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);
1632 updateValueMap(
II, DestReg);
1635 }
else if (VT == MVT::i32) {
1637 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1638 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1639 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1640 updateValueMap(
II, DestReg);
1643 unsigned TempReg[8];
1644 for (
unsigned &R : TempReg) {
1645 R = createResultReg(&Mips::GPR32RegClass);
1650 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1651 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1652 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1653 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1655 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1656 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1658 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1659 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1660 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1661 updateValueMap(
II, DestReg);
1667 case Intrinsic::memcpy:
1668 case Intrinsic::memmove: {
1671 if (MTI->isVolatile())
1673 if (!MTI->getLength()->getType()->isIntegerTy(32))
1676 return lowerCallTo(
II, IntrMemName,
II->arg_size() - 1);
1678 case Intrinsic::memset: {
1685 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
1691bool MipsFastISel::selectRet(
const Instruction *
I) {
1692 const Function &
F = *
I->getParent()->getParent();
1697 if (!FuncInfo.CanLowerReturn)
1701 SmallVector<unsigned, 4> RetRegs;
1704 CallingConv::ID CC =
F.getCallingConv();
1707 if (CC == CallingConv::Fast)
1715 MipsCCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
1718 CCInfo.AnalyzeReturn(Outs, RetCC);
1721 if (ValLocs.
size() != 1)
1724 CCValAssign &VA = ValLocs[0];
1743 if (!
MRI.getRegClass(SrcReg)->contains(DestReg))
1754 if (RVVT == MVT::f128)
1758 if (RVVT == MVT::f64 && UnsupportedFPMode) {
1765 if (RVVT != DestVT) {
1766 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
1769 if (Outs[0].
Flags.isZExt() || Outs[0].Flags.isSExt()) {
1770 bool IsZExt = Outs[0].Flags.isZExt();
1771 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1778 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1779 TII.get(TargetOpcode::COPY), DestReg).
addReg(SrcReg);
1784 MachineInstrBuilder MIB = emitInst(Mips::RetRA);
1785 for (
unsigned Reg : RetRegs)
1790bool MipsFastISel::selectTrunc(
const Instruction *
I) {
1799 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1801 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1810 updateValueMap(
I, SrcReg);
1814bool MipsFastISel::selectIntExt(
const Instruction *
I) {
1815 Type *DestTy =
I->getType();
1816 Value *Src =
I->getOperand(0);
1817 Type *SrcTy = Src->getType();
1820 Register SrcReg = getRegForValue(Src);
1824 EVT SrcEVT, DestEVT;
1834 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1836 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1838 updateValueMap(
I, ResultReg);
1842bool MipsFastISel::emitIntSExt32r1(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1855 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1856 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1857 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1861bool MipsFastISel::emitIntSExt32r2(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1867 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1870 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1876bool MipsFastISel::emitIntSExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1878 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
1881 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1882 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1885bool MipsFastISel::emitIntZExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1903 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);
1907bool MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1908 unsigned DestReg,
bool IsZExt) {
1913 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||
1914 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))
1917 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1918 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1921unsigned MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1923 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1924 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1928bool MipsFastISel::selectDivRem(
const Instruction *
I,
unsigned ISDOpcode) {
1934 if (DestVT != MVT::i32)
1938 switch (ISDOpcode) {
1943 DivOpc = Mips::SDIV;
1947 DivOpc = Mips::UDIV;
1951 Register Src0Reg = getRegForValue(
I->getOperand(0));
1952 Register Src1Reg = getRegForValue(
I->getOperand(1));
1953 if (!Src0Reg || !Src1Reg)
1956 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1959 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1962 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1969 emitInst(MFOpc, ResultReg);
1971 updateValueMap(
I, ResultReg);
1975bool MipsFastISel::selectShift(
const Instruction *
I) {
1978 if (!isTypeSupported(
I->getType(), RetVT))
1981 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1985 unsigned Opcode =
I->getOpcode();
1986 const Value *Op0 =
I->getOperand(0);
1987 Register Op0Reg = getRegForValue(Op0);
1992 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1993 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1998 bool IsZExt = Opcode == Instruction::LShr;
1999 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))
2006 uint64_t ShiftVal =
C->getZExtValue();
2011 case Instruction::Shl:
2014 case Instruction::AShr:
2017 case Instruction::LShr:
2022 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2023 updateValueMap(
I, ResultReg);
2027 Register Op1Reg = getRegForValue(
I->getOperand(1));
2034 case Instruction::Shl:
2035 Opcode = Mips::SLLV;
2037 case Instruction::AShr:
2038 Opcode = Mips::SRAV;
2040 case Instruction::LShr:
2041 Opcode = Mips::SRLV;
2045 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2046 updateValueMap(
I, ResultReg);
2050bool MipsFastISel::fastSelectInstruction(
const Instruction *
I) {
2051 switch (
I->getOpcode()) {
2054 case Instruction::Load:
2055 return selectLoad(
I);
2056 case Instruction::Store:
2057 return selectStore(
I);
2058 case Instruction::SDiv:
2062 case Instruction::UDiv:
2066 case Instruction::SRem:
2070 case Instruction::URem:
2074 case Instruction::Shl:
2075 case Instruction::LShr:
2076 case Instruction::AShr:
2077 return selectShift(
I);
2078 case Instruction::And:
2079 case Instruction::Or:
2080 case Instruction::Xor:
2081 return selectLogicalOp(
I);
2082 case Instruction::Br:
2083 return selectBranch(
I);
2084 case Instruction::Ret:
2085 return selectRet(
I);
2086 case Instruction::Trunc:
2087 return selectTrunc(
I);
2088 case Instruction::ZExt:
2089 case Instruction::SExt:
2090 return selectIntExt(
I);
2091 case Instruction::FPTrunc:
2092 return selectFPTrunc(
I);
2093 case Instruction::FPExt:
2094 return selectFPExt(
I);
2095 case Instruction::FPToSI:
2096 return selectFPToInt(
I,
true);
2097 case Instruction::FPToUI:
2098 return selectFPToInt(
I,
false);
2099 case Instruction::ICmp:
2100 case Instruction::FCmp:
2101 return selectCmp(
I);
2102 case Instruction::Select:
2103 return selectSelect(
I);
2108unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(
const Value *V,
2115 if (VMVT == MVT::i1)
2118 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
2119 Register TempReg = createResultReg(&Mips::GPR32RegClass);
2120 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
2127void MipsFastISel::simplifyAddress(
Address &Addr) {
2130 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
2131 Register DestReg = createResultReg(&Mips::GPR32RegClass);
2132 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());
2133 Addr.setReg(DestReg);
2138unsigned MipsFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2139 const TargetRegisterClass *RC,
2140 unsigned Op0,
unsigned Op1) {
2147 if (MachineInstOpcode == Mips::MUL) {
2148 Register ResultReg = createResultReg(RC);
2149 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
2152 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
2168 return new MipsFastISel(funcInfo, libInfo, libcallLowering);
unsigned const MachineRegisterInfo * MRI
static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
Select the AArch64 opcode for the basic binary operation GenericOpc (such as G_OR or G_SDIV),...
static void emitLoad(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPostDec)
Emit a load-pair instruction for frame-destroy.
static void emitStore(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPreDec)
Emit a store-pair instruction for frame-setup.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the FastISel class.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
cl::opt< bool > EmitJalrReloc
static 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.
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
CCState - This class holds information needed while lowering arguments and return values.
void convertToReg(MCRegister Reg)
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
unsigned getValNo() const
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
Predicate getPredicate() const
Return the predicate for this instruction.
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Register fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0, Register Op1)
Emit a MachineInstr with two register operands and a result register in the given register class.
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasLocalLinkage() const
bool hasInternalLinkage() const
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
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 & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Value * getLength() const
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
Register getGlobalBaseReg(MachineFunction &MF)
bool useSoftFloat() const
const MipsInstrInfo * getInstrInfo() const override
bool inMips16Mode() const
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
const MipsTargetLowering * getTargetLowering() const override
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
TypeSize getElementOffset(unsigned Idx) const
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
const Use * const_op_iterator
Value * getOperand(unsigned i) const
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)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
generic_gep_type_iterator<> gep_type_iterator
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool isVector() const
Return true if this is a vector value type.
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.