72#define DEBUG_TYPE "mips-fastisel"
80class MipsFastISel final :
public FastISel {
85 using BaseKind =
enum { 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);
260 bool fastSelectInstruction(
const Instruction *
I)
override;
262#include "MipsGenFastISel.inc"
285#include "MipsGenCallingConv.inc"
291unsigned MipsFastISel::emitLogicalOp(
unsigned ISDOpc, MVT RetVT,
318 RHSReg = materializeInt(
C, MVT::i32);
320 RHSReg = getRegForValue(
RHS);
324 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
328 emitInst(
Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
332Register MipsFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
334 "Alloca should always return a pointer.");
336 DenseMap<const AllocaInst *, int>::iterator
SI =
337 FuncInfo.StaticAllocaMap.find(AI);
339 if (SI != FuncInfo.StaticAllocaMap.end()) {
340 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
341 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::LEA_ADDiu),
351unsigned MipsFastISel::materializeInt(
const Constant *
C, MVT VT) {
352 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
354 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
359unsigned MipsFastISel::materialize32BitInt(int64_t Imm,
360 const TargetRegisterClass *RC) {
361 Register ResultReg = createResultReg(RC);
364 unsigned Opc = Mips::ADDiu;
365 emitInst(
Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
368 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);
371 unsigned Lo =
Imm & 0xFFFF;
372 unsigned Hi = (
Imm >> 16) & 0xFFFF;
375 Register TmpReg = createResultReg(RC);
376 emitInst(Mips::LUi, TmpReg).addImm(
Hi);
377 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(
Lo);
379 emitInst(Mips::LUi, ResultReg).addImm(
Hi);
384unsigned MipsFastISel::materializeFP(
const ConstantFP *CFP, MVT VT) {
385 if (UnsupportedFPMode)
388 if (VT == MVT::f32) {
389 const TargetRegisterClass *RC = &Mips::FGR32RegClass;
390 Register DestReg = createResultReg(RC);
391 unsigned TempReg = materialize32BitInt(Imm, &Mips::GPR32RegClass);
392 emitInst(Mips::MTC1, DestReg).addReg(TempReg);
394 }
else if (VT == MVT::f64) {
395 const TargetRegisterClass *RC = &Mips::AFGR64RegClass;
396 Register DestReg = createResultReg(RC);
397 unsigned TempReg1 = materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);
399 materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
400 emitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);
406unsigned MipsFastISel::materializeGV(
const GlobalValue *GV, MVT VT) {
410 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
411 Register DestReg = createResultReg(RC);
417 emitInst(Mips::LW, DestReg)
422 Register TempReg = createResultReg(RC);
423 emitInst(Mips::ADDiu, TempReg)
431unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {
432 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
433 Register DestReg = createResultReg(RC);
434 emitInst(Mips::LW, DestReg)
442Register MipsFastISel::fastMaterializeConstant(
const Constant *
C) {
451 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
453 return materializeGV(GV, VT);
455 return materializeInt(
C, VT);
460bool MipsFastISel::computeAddress(
const Value *Obj,
Address &Addr) {
461 const User *
U =
nullptr;
462 unsigned Opcode = Instruction::UserOp1;
466 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
467 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
468 Opcode =
I->getOpcode();
472 Opcode =
C->getOpcode();
478 case Instruction::BitCast:
480 return computeAddress(
U->getOperand(0), Addr);
481 case Instruction::GetElementPtr: {
483 int64_t TmpOffset = Addr.getOffset();
491 const StructLayout *SL =
DL.getStructLayout(STy);
499 TmpOffset += CI->getSExtValue() * S;
502 if (canFoldAddIntoGEP(U,
Op)) {
512 goto unsupported_gep;
517 Addr.setOffset(TmpOffset);
518 if (computeAddress(
U->getOperand(0), Addr))
525 case Instruction::Alloca: {
527 DenseMap<const AllocaInst *, int>::iterator
SI =
528 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);
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))
991bool MipsFastISel::selectCmp(
const Instruction *
I) {
993 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
996 updateValueMap(
I, ResultReg);
1001bool MipsFastISel::selectFPExt(
const Instruction *
I) {
1002 if (UnsupportedFPMode)
1004 Value *Src =
I->getOperand(0);
1008 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
1012 getRegForValue(Src);
1017 Register DestReg = createResultReg(&Mips::AFGR64RegClass);
1018 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1019 updateValueMap(
I, DestReg);
1023bool MipsFastISel::selectSelect(
const Instruction *
I) {
1029 if (!isTypeSupported(
I->getType(), VT) || UnsupportedFPMode) {
1031 dbgs() <<
".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1035 unsigned CondMovOpc;
1036 const TargetRegisterClass *RC;
1039 CondMovOpc = Mips::MOVN_I_I;
1040 RC = &Mips::GPR32RegClass;
1041 }
else if (VT == MVT::f32) {
1042 CondMovOpc = Mips::MOVN_I_S;
1043 RC = &Mips::FGR32RegClass;
1044 }
else if (VT == MVT::f64) {
1045 CondMovOpc = Mips::MOVN_I_D32;
1046 RC = &Mips::AFGR64RegClass;
1052 Register Src1Reg = getRegForValue(
SI->getTrueValue());
1053 Register Src2Reg = getRegForValue(
SI->getFalseValue());
1056 if (!Src1Reg || !Src2Reg || !CondReg)
1059 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1063 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg,
true))
1066 Register ResultReg = createResultReg(RC);
1067 Register TempReg = createResultReg(RC);
1069 if (!ResultReg || !TempReg)
1072 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1073 emitInst(CondMovOpc, ResultReg)
1074 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1075 updateValueMap(
I, ResultReg);
1080bool MipsFastISel::selectFPTrunc(
const Instruction *
I) {
1081 if (UnsupportedFPMode)
1083 Value *Src =
I->getOperand(0);
1087 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
1090 Register SrcReg = getRegForValue(Src);
1094 Register DestReg = createResultReg(&Mips::FGR32RegClass);
1098 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1099 updateValueMap(
I, DestReg);
1104bool MipsFastISel::selectFPToInt(
const Instruction *
I,
bool IsSigned) {
1105 if (UnsupportedFPMode)
1111 Type *DstTy =
I->getType();
1112 if (!isTypeLegal(DstTy, DstVT))
1115 if (DstVT != MVT::i32)
1118 Value *Src =
I->getOperand(0);
1119 Type *SrcTy = Src->getType();
1120 if (!isTypeLegal(SrcTy, SrcVT))
1123 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1126 Register SrcReg = getRegForValue(Src);
1132 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1133 Register TempReg = createResultReg(&Mips::FGR32RegClass);
1134 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1137 emitInst(
Opc, TempReg).addReg(SrcReg);
1138 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1140 updateValueMap(
I, DestReg);
1144bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1145 SmallVectorImpl<MVT> &OutVTs,
1146 unsigned &NumBytes) {
1147 CallingConv::ID CC = CLI.CallConv;
1150 for (
const ArgListEntry &Arg : CLI.Args)
1152 CCState CCInfo(CC,
false, *FuncInfo.MF, ArgLocs, *
Context);
1153 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,
1154 CCAssignFnForCall(CC));
1156 NumBytes = CCInfo.getStackSize();
1161 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1164 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1165 CCValAssign &VA = ArgLocs[i];
1171 if (ArgVT == MVT::f32) {
1173 }
else if (ArgVT == MVT::f64) {
1179 }
else if (i == 1) {
1180 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {
1181 if (ArgVT == MVT::f32) {
1183 }
else if (ArgVT == MVT::f64) {
1191 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||
1192 (ArgVT == MVT::i8)) &&
1211 Register ArgReg = getRegForValue(ArgVal);
1223 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
false);
1231 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
true);
1242 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1266 unsigned BEAlign = 0;
1267 if (ArgSize < 8 && !Subtarget->isLittle())
1268 BEAlign = 8 - ArgSize;
1271 Addr.setKind(Address::RegBase);
1272 Addr.setReg(Mips::SP);
1276 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
1288bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,
1289 unsigned NumBytes) {
1290 CallingConv::ID CC = CLI.CallConv;
1291 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1292 if (RetVT != MVT::isVoid) {
1294 MipsCCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *
Context);
1296 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);
1299 if (RVLocs.
size() != 1)
1302 MVT CopyVT = RVLocs[0].getValVT();
1304 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
1310 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1311 TII.get(TargetOpcode::COPY),
1312 ResultReg).
addReg(RVLocs[0].getLocReg());
1313 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1315 CLI.ResultReg = ResultReg;
1316 CLI.NumResultRegs = 1;
1321bool MipsFastISel::fastLowerArguments() {
1324 if (!FuncInfo.CanLowerReturn) {
1330 if (
F->isVarArg()) {
1335 CallingConv::ID CC =
F->getCallingConv();
1336 if (CC != CallingConv::C) {
1337 LLVM_DEBUG(
dbgs() <<
".. gave up (calling convention is not C)\n");
1341 std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,
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 {
1350 const TargetRegisterClass *RC;
1352 AllocatedReg(
const TargetRegisterClass *RC,
unsigned Reg)
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::min(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, Mips::T9).addReg(DestAddress);
1568 MachineInstrBuilder MIB =
1569 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::JALR),
1570 Mips::RA).
addReg(Mips::T9);
1573 for (
auto Reg : CLI.OutRegs)
1588 MIB.
addSym(FuncInfo.MF->getContext().getOrCreateSymbol(
1593 return finishCall(CLI, RetVT, NumBytes);
1596bool MipsFastISel::fastLowerIntrinsicCall(
const IntrinsicInst *
II) {
1597 switch (
II->getIntrinsicID()) {
1600 case Intrinsic::bswap: {
1601 Type *RetTy =
II->getCalledFunction()->getReturnType();
1604 if (!isTypeSupported(RetTy, VT))
1607 Register SrcReg = getRegForValue(
II->getOperand(0));
1610 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1613 if (VT == MVT::i16) {
1615 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1616 updateValueMap(
II, DestReg);
1619 unsigned TempReg[3];
1620 for (
unsigned &R : TempReg) {
1621 R = createResultReg(&Mips::GPR32RegClass);
1625 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1626 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1627 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);
1628 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);
1629 updateValueMap(
II, DestReg);
1632 }
else if (VT == MVT::i32) {
1634 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1635 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1636 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1637 updateValueMap(
II, DestReg);
1640 unsigned TempReg[8];
1641 for (
unsigned &R : TempReg) {
1642 R = createResultReg(&Mips::GPR32RegClass);
1647 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1648 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1649 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1650 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1652 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1653 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1655 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1656 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1657 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1658 updateValueMap(
II, DestReg);
1664 case Intrinsic::memcpy:
1665 case Intrinsic::memmove: {
1668 if (MTI->isVolatile())
1670 if (!MTI->getLength()->getType()->isIntegerTy(32))
1673 return lowerCallTo(
II, IntrMemName,
II->arg_size() - 1);
1675 case Intrinsic::memset: {
1682 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
1688bool MipsFastISel::selectRet(
const Instruction *
I) {
1689 const Function &
F = *
I->getParent()->getParent();
1694 if (!FuncInfo.CanLowerReturn)
1698 SmallVector<unsigned, 4> RetRegs;
1700 if (
Ret->getNumOperands() > 0) {
1701 CallingConv::ID CC =
F.getCallingConv();
1704 if (CC == CallingConv::Fast)
1712 MipsCCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
1715 CCInfo.AnalyzeReturn(Outs, RetCC);
1718 if (ValLocs.
size() != 1)
1721 CCValAssign &VA = ValLocs[0];
1722 const Value *RV =
Ret->getOperand(0);
1740 if (!
MRI.getRegClass(SrcReg)->contains(DestReg))
1751 if (RVVT == MVT::f128)
1755 if (RVVT == MVT::f64 && UnsupportedFPMode) {
1762 if (RVVT != DestVT) {
1763 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
1766 if (Outs[0].
Flags.isZExt() || Outs[0].Flags.isSExt()) {
1767 bool IsZExt = Outs[0].Flags.isZExt();
1768 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1775 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1776 TII.get(TargetOpcode::COPY), DestReg).
addReg(SrcReg);
1781 MachineInstrBuilder MIB = emitInst(Mips::RetRA);
1782 for (
unsigned Reg : RetRegs)
1787bool MipsFastISel::selectTrunc(
const Instruction *
I) {
1796 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1798 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1807 updateValueMap(
I, SrcReg);
1811bool MipsFastISel::selectIntExt(
const Instruction *
I) {
1812 Type *DestTy =
I->getType();
1813 Value *Src =
I->getOperand(0);
1814 Type *SrcTy = Src->getType();
1817 Register SrcReg = getRegForValue(Src);
1821 EVT SrcEVT, DestEVT;
1831 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1833 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1835 updateValueMap(
I, ResultReg);
1839bool MipsFastISel::emitIntSExt32r1(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1852 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1853 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1854 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1858bool MipsFastISel::emitIntSExt32r2(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1864 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1867 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1873bool MipsFastISel::emitIntSExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1875 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
1878 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1879 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1882bool MipsFastISel::emitIntZExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1900 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);
1904bool MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1905 unsigned DestReg,
bool IsZExt) {
1910 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||
1911 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))
1914 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1915 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1918unsigned MipsFastISel::emitIntExt(MVT SrcVT,
unsigned SrcReg, MVT DestVT,
1920 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1921 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1925bool MipsFastISel::selectDivRem(
const Instruction *
I,
unsigned ISDOpcode) {
1931 if (DestVT != MVT::i32)
1935 switch (ISDOpcode) {
1940 DivOpc = Mips::SDIV;
1944 DivOpc = Mips::UDIV;
1948 Register Src0Reg = getRegForValue(
I->getOperand(0));
1949 Register Src1Reg = getRegForValue(
I->getOperand(1));
1950 if (!Src0Reg || !Src1Reg)
1953 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1956 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1959 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1966 emitInst(MFOpc, ResultReg);
1968 updateValueMap(
I, ResultReg);
1972bool MipsFastISel::selectShift(
const Instruction *
I) {
1975 if (!isTypeSupported(
I->getType(), RetVT))
1978 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1982 unsigned Opcode =
I->getOpcode();
1983 const Value *Op0 =
I->getOperand(0);
1984 Register Op0Reg = getRegForValue(Op0);
1989 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1990 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1995 bool IsZExt = Opcode == Instruction::LShr;
1996 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))
2003 uint64_t ShiftVal =
C->getZExtValue();
2008 case Instruction::Shl:
2011 case Instruction::AShr:
2014 case Instruction::LShr:
2019 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2020 updateValueMap(
I, ResultReg);
2024 Register Op1Reg = getRegForValue(
I->getOperand(1));
2031 case Instruction::Shl:
2032 Opcode = Mips::SLLV;
2034 case Instruction::AShr:
2035 Opcode = Mips::SRAV;
2037 case Instruction::LShr:
2038 Opcode = Mips::SRLV;
2042 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2043 updateValueMap(
I, ResultReg);
2047bool MipsFastISel::fastSelectInstruction(
const Instruction *
I) {
2048 switch (
I->getOpcode()) {
2051 case Instruction::Load:
2052 return selectLoad(
I);
2053 case Instruction::Store:
2054 return selectStore(
I);
2055 case Instruction::SDiv:
2059 case Instruction::UDiv:
2063 case Instruction::SRem:
2067 case Instruction::URem:
2071 case Instruction::Shl:
2072 case Instruction::LShr:
2073 case Instruction::AShr:
2074 return selectShift(
I);
2075 case Instruction::And:
2076 case Instruction::Or:
2077 case Instruction::Xor:
2078 return selectLogicalOp(
I);
2079 case Instruction::Br:
2080 return selectBranch(
I);
2081 case Instruction::Ret:
2082 return selectRet(
I);
2083 case Instruction::Trunc:
2084 return selectTrunc(
I);
2085 case Instruction::ZExt:
2086 case Instruction::SExt:
2087 return selectIntExt(
I);
2088 case Instruction::FPTrunc:
2089 return selectFPTrunc(
I);
2090 case Instruction::FPExt:
2091 return selectFPExt(
I);
2092 case Instruction::FPToSI:
2093 return selectFPToInt(
I,
true);
2094 case Instruction::FPToUI:
2095 return selectFPToInt(
I,
false);
2096 case Instruction::ICmp:
2097 case Instruction::FCmp:
2098 return selectCmp(
I);
2099 case Instruction::Select:
2100 return selectSelect(
I);
2105unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(
const Value *V,
2112 if (VMVT == MVT::i1)
2115 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
2116 Register TempReg = createResultReg(&Mips::GPR32RegClass);
2117 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
2124void MipsFastISel::simplifyAddress(
Address &Addr) {
2127 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
2128 Register DestReg = createResultReg(&Mips::GPR32RegClass);
2129 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());
2130 Addr.setReg(DestReg);
2135unsigned MipsFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2136 const TargetRegisterClass *RC,
2137 unsigned Op0,
unsigned Op1) {
2144 if (MachineInstOpcode == Mips::MUL) {
2145 Register ResultReg = createResultReg(RC);
2146 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
2149 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
2164 return new MipsFastISel(funcInfo, libInfo);
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...
#define LLVM_ATTRIBUTE_UNUSED
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 unsigned 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) LLVM_ATTRIBUTE_UNUSED
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.
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
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)
@ 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.