74#define DEBUG_TYPE "mips-fastisel"
82class MipsFastISel final :
public FastISel {
87 using BaseKind =
enum { RegBase, FrameIndexBase };
90 BaseKind Kind = RegBase;
102 Address() {
Base.Reg = 0; }
104 void setKind(BaseKind K) { Kind = K; }
105 BaseKind getKind()
const {
return Kind; }
106 bool isRegBase()
const {
return Kind == RegBase; }
107 bool isFIBase()
const {
return Kind == FrameIndexBase; }
109 void setReg(
unsigned Reg) {
110 assert(isRegBase() &&
"Invalid base register access!");
115 assert(isRegBase() &&
"Invalid base register access!");
119 void setFI(
unsigned FI) {
120 assert(isFIBase() &&
"Invalid base frame index access!");
124 unsigned getFI()
const {
125 assert(isFIBase() &&
"Invalid base frame index access!");
129 void setOffset(int64_t Offset_) { Offset = Offset_; }
130 int64_t
getOffset()
const {
return Offset; }
150 bool UnsupportedFPMode;
164 bool selectFPToInt(
const Instruction *
I,
bool IsSigned);
169 bool selectDivRem(
const Instruction *
I,
unsigned ISDOpcode);
172 bool isTypeLegal(
Type *Ty,
MVT &VT);
173 bool isTypeSupported(
Type *Ty,
MVT &VT);
174 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
175 bool computeAddress(
const Value *Obj, Address &
Addr);
176 bool computeCallAddress(
const Value *V, Address &
Addr);
177 void simplifyAddress(Address &
Addr);
183 unsigned emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
bool isZExt);
184 bool emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg,
187 bool emitIntZExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg);
189 bool emitIntSExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg);
190 bool emitIntSExt32r1(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
192 bool emitIntSExt32r2(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
195 unsigned getRegEnsuringSimpleIntegerWidening(
const Value *,
bool IsUnsigned);
197 unsigned emitLogicalOp(
unsigned ISDOpc,
MVT RetVT,
const Value *
LHS,
204 unsigned materializeExternalCallSym(
MCSymbol *Syn);
207 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc));
211 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc),
216 unsigned MemReg, int64_t MemOffset) {
221 unsigned MemReg, int64_t MemOffset) {
222 return emitInst(Opc, DstReg).
addReg(MemReg).
addImm(MemOffset);
227 unsigned Op0,
unsigned Op1);
242 bool finishCall(CallLoweringInfo &CLI,
MVT RetVT,
unsigned NumBytes);
264#include "MipsGenFastISel.inc"
285#include "MipsGenCallingConv.inc"
291unsigned MipsFastISel::emitLogicalOp(
unsigned ISDOpc,
MVT RetVT,
294 if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS))
312 Register LHSReg = getRegForValue(LHS);
317 if (
const auto *
C = dyn_cast<ConstantInt>(RHS))
318 RHSReg = materializeInt(
C, MVT::i32);
320 RHSReg = getRegForValue(RHS);
324 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
328 emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
332unsigned MipsFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
334 "Alloca should always return a pointer.");
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)
359unsigned MipsFastISel::materialize32BitInt(int64_t Imm,
361 Register ResultReg = createResultReg(RC);
363 if (isInt<16>(Imm)) {
364 unsigned Opc = Mips::ADDiu;
365 emitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
367 }
else if (isUInt<16>(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) {
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) {
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) {
411 Register DestReg = createResultReg(RC);
417 emitInst(Mips::LW, DestReg)
418 .addReg(MFI->getGlobalBaseReg(*MF))
422 Register TempReg = createResultReg(RC);
423 emitInst(Mips::ADDiu, TempReg)
431unsigned MipsFastISel::materializeExternalCallSym(
MCSymbol *
Sym) {
433 Register DestReg = createResultReg(RC);
434 emitInst(Mips::LW, DestReg)
435 .addReg(MFI->getGlobalBaseReg(*MF))
442unsigned MipsFastISel::fastMaterializeConstant(
const Constant *
C) {
443 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
450 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(
C))
451 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
452 else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(
C))
453 return materializeGV(GV, VT);
454 else if (isa<ConstantInt>(
C))
455 return materializeInt(
C, VT);
460bool MipsFastISel::computeAddress(
const Value *Obj, Address &
Addr) {
461 const User *
U =
nullptr;
462 unsigned Opcode = Instruction::UserOp1;
463 if (
const Instruction *
I = dyn_cast<Instruction>(Obj)) {
466 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
467 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
468 Opcode =
I->getOpcode();
471 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(Obj)) {
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();
492 unsigned Idx = cast<ConstantInt>(
Op)->getZExtValue();
499 TmpOffset += CI->getSExtValue() * S;
502 if (canFoldAddIntoGEP(U,
Op)) {
505 cast<ConstantInt>(cast<AddOperator>(
Op)->getOperand(1));
508 Op = cast<AddOperator>(
Op)->getOperand(0);
512 goto unsupported_gep;
517 Addr.setOffset(TmpOffset);
518 if (computeAddress(
U->getOperand(0),
Addr))
525 case Instruction::Alloca: {
528 FuncInfo.StaticAllocaMap.find(AI);
529 if (SI != FuncInfo.StaticAllocaMap.end()) {
530 Addr.setKind(Address::FrameIndexBase);
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;
545 if (
const auto *
I = dyn_cast<Instruction>(V)) {
548 if (
I->getParent() == FuncInfo.MBB->getBasicBlock()) {
549 Opcode =
I->getOpcode();
552 }
else if (
const auto *
C = dyn_cast<ConstantExpr>(V)) {
553 Opcode =
C->getOpcode();
560 case Instruction::BitCast:
562 return computeCallAddress(
U->getOperand(0),
Addr);
564 case Instruction::IntToPtr:
566 if (TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
567 TLI.getPointerTy(
DL))
568 return computeCallAddress(
U->getOperand(0),
Addr);
570 case Instruction::PtrToInt:
572 if (TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
573 return computeCallAddress(
U->getOperand(0),
Addr);
577 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
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) {
592 EVT evt = TLI.getValueType(
DL, Ty,
true);
594 if (evt == MVT::Other || !evt.
isSimple())
600 return TLI.isTypeLegal(VT);
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();
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();
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);
885 if (cast<LoadInst>(
I)->isAtomic())
890 if (!isLoadTypeLegal(
I->getType(), VT))
895 if (!computeAddress(
I->getOperand(0),
Addr))
901 updateValueMap(
I, ResultReg);
906 Value *Op0 =
I->getOperand(0);
910 if (cast<StoreInst>(
I)->isAtomic())
915 if (!isLoadTypeLegal(
I->getOperand(0)->getType(), VT))
919 SrcReg = getRegForValue(Op0);
925 if (!computeAddress(
I->getOperand(1),
Addr))
950 unsigned ZExtCondReg = 0;
953 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
960 if (ZExtCondReg == 0) {
965 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32,
true);
966 if (ZExtCondReg == 0)
970 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::BGTZ))
978 const CmpInst *CI = cast<CmpInst>(
I);
979 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
982 updateValueMap(
I, ResultReg);
988 if (UnsupportedFPMode)
990 Value *Src =
I->getOperand(0);
991 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
992 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
994 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
1003 Register DestReg = createResultReg(&Mips::AFGR64RegClass);
1004 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1005 updateValueMap(
I, DestReg);
1010 assert(isa<SelectInst>(
I) &&
"Expected a select instruction.");
1015 if (!isTypeSupported(
I->getType(), VT) || UnsupportedFPMode) {
1017 dbgs() <<
".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1021 unsigned CondMovOpc;
1025 CondMovOpc = Mips::MOVN_I_I;
1026 RC = &Mips::GPR32RegClass;
1027 }
else if (VT == MVT::f32) {
1028 CondMovOpc = Mips::MOVN_I_S;
1029 RC = &Mips::FGR32RegClass;
1030 }
else if (VT == MVT::f64) {
1031 CondMovOpc = Mips::MOVN_I_D32;
1032 RC = &Mips::AFGR64RegClass;
1038 Register Src1Reg = getRegForValue(
SI->getTrueValue());
1039 Register Src2Reg = getRegForValue(
SI->getFalseValue());
1042 if (!Src1Reg || !Src2Reg || !CondReg)
1045 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1049 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg,
true))
1052 Register ResultReg = createResultReg(RC);
1053 Register TempReg = createResultReg(RC);
1055 if (!ResultReg || !TempReg)
1058 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1059 emitInst(CondMovOpc, ResultReg)
1060 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1061 updateValueMap(
I, ResultReg);
1066bool MipsFastISel::selectFPTrunc(
const Instruction *
I) {
1067 if (UnsupportedFPMode)
1069 Value *Src =
I->getOperand(0);
1070 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
1071 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1073 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
1076 Register SrcReg = getRegForValue(Src);
1080 Register DestReg = createResultReg(&Mips::FGR32RegClass);
1084 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1085 updateValueMap(
I, DestReg);
1090bool MipsFastISel::selectFPToInt(
const Instruction *
I,
bool IsSigned) {
1091 if (UnsupportedFPMode)
1097 Type *DstTy =
I->getType();
1098 if (!isTypeLegal(DstTy, DstVT))
1101 if (DstVT != MVT::i32)
1104 Value *Src =
I->getOperand(0);
1105 Type *SrcTy = Src->getType();
1106 if (!isTypeLegal(SrcTy, SrcVT))
1109 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1112 Register SrcReg = getRegForValue(Src);
1118 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1119 Register TempReg = createResultReg(&Mips::FGR32RegClass);
1120 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1123 emitInst(Opc, TempReg).addReg(SrcReg);
1124 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1126 updateValueMap(
I, DestReg);
1130bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1132 unsigned &NumBytes) {
1135 CCState CCInfo(
CC,
false, *FuncInfo.MF, ArgLocs, *Context);
1136 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, CCAssignFnForCall(
CC));
1138 NumBytes = CCInfo.getStackSize();
1143 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1146 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1153 if (ArgVT == MVT::f32) {
1155 }
else if (ArgVT == MVT::f64) {
1156 if (Subtarget->isFP64bit())
1161 }
else if (i == 1) {
1162 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {
1163 if (ArgVT == MVT::f32) {
1165 }
else if (ArgVT == MVT::f64) {
1166 if (Subtarget->isFP64bit())
1173 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||
1174 (ArgVT == MVT::i8)) &&
1193 Register ArgReg = getRegForValue(ArgVal);
1205 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
false);
1213 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
true);
1224 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1238 if (isa<UndefValue>(ArgVal))
1248 unsigned BEAlign = 0;
1249 if (ArgSize < 8 && !Subtarget->isLittle())
1250 BEAlign = 8 - ArgSize;
1253 Addr.setKind(Address::RegBase);
1254 Addr.setReg(Mips::SP);
1270bool MipsFastISel::finishCall(CallLoweringInfo &CLI,
MVT RetVT,
1271 unsigned NumBytes) {
1273 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1274 if (RetVT != MVT::isVoid) {
1276 MipsCCState CCInfo(
CC,
false, *FuncInfo.MF, RVLocs, *Context);
1278 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips, CLI.RetTy,
1279 CLI.Symbol ? CLI.Symbol->getName().data()
1283 if (RVLocs.
size() != 1)
1286 MVT CopyVT = RVLocs[0].getValVT();
1288 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
1291 Register ResultReg = createResultReg(TLI.getRegClassFor(CopyVT));
1294 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1295 TII.get(TargetOpcode::COPY),
1296 ResultReg).
addReg(RVLocs[0].getLocReg());
1297 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1299 CLI.ResultReg = ResultReg;
1300 CLI.NumResultRegs = 1;
1305bool MipsFastISel::fastLowerArguments() {
1308 if (!FuncInfo.CanLowerReturn) {
1314 if (
F->isVarArg()) {
1321 LLVM_DEBUG(
dbgs() <<
".. gave up (calling convention is not C)\n");
1325 std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,
1327 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1328 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1329 auto NextGPR32 = GPR32ArgRegs.begin();
1330 auto NextFGR32 = FGR32ArgRegs.begin();
1331 auto NextAFGR64 = AFGR64ArgRegs.begin();
1333 struct AllocatedReg {
1343 for (
const auto &FormalArg :
F->args()) {
1344 if (FormalArg.hasAttribute(Attribute::InReg) ||
1345 FormalArg.hasAttribute(Attribute::StructRet) ||
1346 FormalArg.hasAttribute(Attribute::ByVal)) {
1351 Type *ArgTy = FormalArg.getType();
1357 EVT ArgVT = TLI.getValueType(
DL, ArgTy);
1369 if (!FormalArg.hasAttribute(Attribute::SExt) &&
1370 !FormalArg.hasAttribute(Attribute::ZExt)) {
1373 LLVM_DEBUG(
dbgs() <<
".. .. gave up (i8/i16 arg is not extended)\n");
1377 if (NextGPR32 == GPR32ArgRegs.end()) {
1378 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1383 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1386 NextFGR32 = FGR32ArgRegs.end();
1387 NextAFGR64 = AFGR64ArgRegs.end();
1391 if (FormalArg.hasAttribute(Attribute::ZExt)) {
1393 LLVM_DEBUG(
dbgs() <<
".. .. gave up (i32 arg is zero extended)\n");
1397 if (NextGPR32 == GPR32ArgRegs.end()) {
1398 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1403 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1406 NextFGR32 = FGR32ArgRegs.end();
1407 NextAFGR64 = AFGR64ArgRegs.end();
1411 if (UnsupportedFPMode) {
1415 if (NextFGR32 == FGR32ArgRegs.end()) {
1416 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of FGR32 arguments)\n");
1420 Allocation.
emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1423 if (NextGPR32 != GPR32ArgRegs.end())
1425 if (NextAFGR64 != AFGR64ArgRegs.end())
1430 if (UnsupportedFPMode) {
1434 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1435 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of AFGR64 arguments)\n");
1439 Allocation.
emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1442 if (NextGPR32 != GPR32ArgRegs.end())
1444 if (NextGPR32 != GPR32ArgRegs.end())
1446 if (NextFGR32 != FGR32ArgRegs.end())
1456 for (
const auto &FormalArg :
F->args()) {
1457 unsigned ArgNo = FormalArg.getArgNo();
1458 unsigned SrcReg = Allocation[ArgNo].Reg;
1459 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1463 Register ResultReg = createResultReg(Allocation[ArgNo].RC);
1464 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1465 TII.get(TargetOpcode::COPY), ResultReg)
1467 updateValueMap(&FormalArg, ResultReg);
1472 unsigned IncomingArgSizeInBytes = 0;
1477 IncomingArgSizeInBytes = std::min(getABI().GetCalleeAllocdArgSizeInBytes(
CC),
1478 IncomingArgSizeInBytes);
1486bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1488 bool IsTailCall = CLI.IsTailCall;
1489 bool IsVarArg = CLI.IsVarArg;
1507 if (CLI.RetTy->isVoidTy())
1508 RetVT = MVT::isVoid;
1509 else if (!isTypeSupported(CLI.RetTy, RetVT))
1512 for (
auto Flag : CLI.OutFlags)
1518 OutVTs.
reserve(CLI.OutVals.size());
1520 for (
auto *Val : CLI.OutVals) {
1522 if (!isTypeLegal(Val->getType(), VT) &&
1523 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))
1534 if (!computeCallAddress(Callee,
Addr))
1539 if (!processCallArgs(CLI, OutVTs, NumBytes))
1542 if (!
Addr.getGlobalValue())
1546 unsigned DestAddress;
1548 DestAddress = materializeExternalCallSym(Symbol);
1550 DestAddress = materializeGV(
Addr.getGlobalValue(), MVT::i32);
1551 emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);
1553 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Mips::JALR),
1554 Mips::RA).
addReg(Mips::T9);
1557 for (
auto Reg : CLI.OutRegs)
1572 MIB.
addSym(FuncInfo.MF->getContext().getOrCreateSymbol(
1577 return finishCall(CLI, RetVT, NumBytes);
1581 switch (
II->getIntrinsicID()) {
1584 case Intrinsic::bswap: {
1585 Type *
RetTy =
II->getCalledFunction()->getReturnType();
1588 if (!isTypeSupported(
RetTy, VT))
1591 Register SrcReg = getRegForValue(
II->getOperand(0));
1594 Register DestReg = createResultReg(&Mips::GPR32RegClass);
1597 if (VT == MVT::i16) {
1598 if (Subtarget->hasMips32r2()) {
1599 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1600 updateValueMap(
II, DestReg);
1603 unsigned TempReg[3];
1604 for (
unsigned &R : TempReg) {
1605 R = createResultReg(&Mips::GPR32RegClass);
1609 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1610 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1611 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);
1612 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);
1613 updateValueMap(
II, DestReg);
1616 }
else if (VT == MVT::i32) {
1617 if (Subtarget->hasMips32r2()) {
1618 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1619 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1620 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1621 updateValueMap(
II, DestReg);
1624 unsigned TempReg[8];
1625 for (
unsigned &R : TempReg) {
1626 R = createResultReg(&Mips::GPR32RegClass);
1631 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1632 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1633 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1634 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1636 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1637 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1639 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1640 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1641 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1642 updateValueMap(
II, DestReg);
1648 case Intrinsic::memcpy:
1649 case Intrinsic::memmove: {
1650 const auto *MTI = cast<MemTransferInst>(
II);
1652 if (MTI->isVolatile())
1654 if (!MTI->getLength()->getType()->isIntegerTy(32))
1656 const char *IntrMemName = isa<MemCpyInst>(
II) ?
"memcpy" :
"memmove";
1657 return lowerCallTo(
II, IntrMemName,
II->arg_size() - 1);
1659 case Intrinsic::memset: {
1666 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
1673 const Function &
F = *
I->getParent()->getParent();
1678 if (!FuncInfo.CanLowerReturn)
1684 if (
Ret->getNumOperands() > 0) {
1699 CCInfo.AnalyzeReturn(Outs, RetCC);
1702 if (ValLocs.
size() != 1)
1706 const Value *RV =
Ret->getOperand(0);
1724 if (!
MRI.getRegClass(SrcReg)->contains(DestReg))
1735 if (RVVT == MVT::f128)
1739 if (RVVT == MVT::f64 && UnsupportedFPMode) {
1746 if (RVVT != DestVT) {
1747 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
1750 if (Outs[0].
Flags.isZExt() || Outs[0].Flags.isSExt()) {
1751 bool IsZExt = Outs[0].Flags.isZExt();
1752 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1759 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1760 TII.get(TargetOpcode::COPY), DestReg).
addReg(SrcReg);
1766 for (
unsigned Reg : RetRegs)
1777 SrcVT = TLI.getValueType(
DL,
Op->getType(),
true);
1778 DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1780 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1782 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1791 updateValueMap(
I, SrcReg);
1796 Type *DestTy =
I->getType();
1797 Value *Src =
I->getOperand(0);
1798 Type *SrcTy = Src->getType();
1800 bool isZExt = isa<ZExtInst>(
I);
1801 Register SrcReg = getRegForValue(Src);
1805 EVT SrcEVT, DestEVT;
1806 SrcEVT = TLI.getValueType(
DL, SrcTy,
true);
1807 DestEVT = TLI.getValueType(
DL, DestTy,
true);
1815 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1817 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1819 updateValueMap(
I, ResultReg);
1823bool MipsFastISel::emitIntSExt32r1(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1836 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1837 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1838 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1842bool MipsFastISel::emitIntSExt32r2(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1848 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1851 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1857bool MipsFastISel::emitIntSExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1859 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
1861 if (Subtarget->hasMips32r2())
1862 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1863 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1866bool MipsFastISel::emitIntZExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1884 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);
1888bool MipsFastISel::emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1889 unsigned DestReg,
bool IsZExt) {
1894 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||
1895 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))
1898 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1899 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1902unsigned MipsFastISel::emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1904 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1905 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1909bool MipsFastISel::selectDivRem(
const Instruction *
I,
unsigned ISDOpcode) {
1910 EVT DestEVT = TLI.getValueType(
DL,
I->getType(),
true);
1915 if (DestVT != MVT::i32)
1919 switch (ISDOpcode) {
1924 DivOpc = Mips::SDIV;
1928 DivOpc = Mips::UDIV;
1932 Register Src0Reg = getRegForValue(
I->getOperand(0));
1933 Register Src1Reg = getRegForValue(
I->getOperand(1));
1934 if (!Src0Reg || !Src1Reg)
1937 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1938 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1940 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1947 emitInst(MFOpc, ResultReg);
1949 updateValueMap(
I, ResultReg);
1956 if (!isTypeSupported(
I->getType(), RetVT))
1959 Register ResultReg = createResultReg(&Mips::GPR32RegClass);
1963 unsigned Opcode =
I->getOpcode();
1964 const Value *Op0 =
I->getOperand(0);
1965 Register Op0Reg = getRegForValue(Op0);
1970 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1971 Register TempReg = createResultReg(&Mips::GPR32RegClass);
1975 MVT Op0MVT = TLI.getValueType(
DL, Op0->
getType(),
true).getSimpleVT();
1976 bool IsZExt = Opcode == Instruction::LShr;
1977 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))
1983 if (
const auto *
C = dyn_cast<ConstantInt>(
I->getOperand(1))) {
1989 case Instruction::Shl:
1992 case Instruction::AShr:
1995 case Instruction::LShr:
2000 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2001 updateValueMap(
I, ResultReg);
2005 Register Op1Reg = getRegForValue(
I->getOperand(1));
2012 case Instruction::Shl:
2013 Opcode = Mips::SLLV;
2015 case Instruction::AShr:
2016 Opcode = Mips::SRAV;
2018 case Instruction::LShr:
2019 Opcode = Mips::SRLV;
2023 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2024 updateValueMap(
I, ResultReg);
2028bool MipsFastISel::fastSelectInstruction(
const Instruction *
I) {
2029 switch (
I->getOpcode()) {
2032 case Instruction::Load:
2033 return selectLoad(
I);
2034 case Instruction::Store:
2035 return selectStore(
I);
2036 case Instruction::SDiv:
2040 case Instruction::UDiv:
2044 case Instruction::SRem:
2048 case Instruction::URem:
2052 case Instruction::Shl:
2053 case Instruction::LShr:
2054 case Instruction::AShr:
2055 return selectShift(
I);
2056 case Instruction::And:
2057 case Instruction::Or:
2058 case Instruction::Xor:
2059 return selectLogicalOp(
I);
2060 case Instruction::Br:
2061 return selectBranch(
I);
2062 case Instruction::Ret:
2063 return selectRet(
I);
2064 case Instruction::Trunc:
2065 return selectTrunc(
I);
2066 case Instruction::ZExt:
2067 case Instruction::SExt:
2068 return selectIntExt(
I);
2069 case Instruction::FPTrunc:
2070 return selectFPTrunc(
I);
2071 case Instruction::FPExt:
2072 return selectFPExt(
I);
2073 case Instruction::FPToSI:
2074 return selectFPToInt(
I,
true);
2075 case Instruction::FPToUI:
2076 return selectFPToInt(
I,
false);
2077 case Instruction::ICmp:
2078 case Instruction::FCmp:
2079 return selectCmp(
I);
2080 case Instruction::Select:
2081 return selectSelect(
I);
2086unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(
const Value *V,
2091 MVT VMVT = TLI.getValueType(
DL,
V->getType(),
true).getSimpleVT();
2093 if (VMVT == MVT::i1)
2096 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {
2097 Register TempReg = createResultReg(&Mips::GPR32RegClass);
2098 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))
2105void MipsFastISel::simplifyAddress(Address &
Addr) {
2106 if (!isInt<16>(
Addr.getOffset())) {
2108 materialize32BitInt(
Addr.getOffset(), &Mips::GPR32RegClass);
2109 Register DestReg = createResultReg(&Mips::GPR32RegClass);
2110 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(
Addr.getReg());
2111 Addr.setReg(DestReg);
2116unsigned MipsFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2118 unsigned Op0,
unsigned Op1) {
2125 if (MachineInstOpcode == Mips::MUL) {
2126 Register ResultReg = createResultReg(RC);
2130 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
2145 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.
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...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines the FastISel class.
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
cl::opt< bool > EmitJalrReloc
static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State) LLVM_ATTRIBUTE_UNUSED
static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State, ArrayRef< MCPhysReg > F64Regs)
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
support::ulittle16_t & Lo
support::ulittle16_t & Hi
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.
Conditional or Unconditional Branch instruction.
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
void convertToReg(unsigned RegNo)
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.
A constant value that is initialized with an expression using other constant values.
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
This is the shared class of boolean and integer constants.
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 class represents an Operation in the Expression.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
virtual bool fastLowerIntrinsicCall(const IntrinsicInst *II)
This method is called by target-independent code to do target- specific intrinsic lowering.
virtual unsigned fastMaterializeConstant(const Constant *C)
Emit a constant in a register using target-specific logic, such as constant pool loads.
virtual bool fastLowerCall(CallLoweringInfo &CLI)
This method is called by target-independent code to do target- specific call lowering.
Register fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, unsigned Op1)
Emit a MachineInstr with two register operands and a result register in the given register class.
virtual bool fastLowerArguments()
This method is called by target-independent code to do target- specific argument lowering.
const TargetInstrInfo & TII
virtual bool fastSelectInstruction(const Instruction *I)=0
This method is called by target-independent code when the normal FastISel process fails to select an ...
const TargetLowering & TLI
virtual unsigned fastMaterializeAlloca(const AllocaInst *C)
Emit an alloca address in a register using target-specific logic.
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
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Describe properties that are true of each instruction in the target description file.
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.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Value * getLength() const
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
bool useSoftFloat() const
const MipsInstrInfo * getInstrInfo() const override
const MipsTargetLowering * getTargetLowering() const override
Wrapper class representing virtual and physical registers.
Return a value (possibly void), from a function.
This class represents the LLVM 'select' instruction.
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)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
TypeSize getElementOffset(unsigned Idx) const
Class to represent struct types.
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
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 isArrayTy() const
True if this is an instance of ArrayType.
bool isStructTy() const
True if this is an instance of StructType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
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.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ 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.
@ MO_GOT
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
@ MO_JALR
Helper operand used to generate R_MIPS_JALR.
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
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...
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.
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
unsigned getKillRegState(bool B)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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 MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.