75 #define DEBUG_TYPE "mips-fastisel" 83 class MipsFastISel final :
public FastISel {
88 using BaseKind =
enum { RegBase, FrameIndexBase };
91 BaseKind
Kind = RegBase;
105 void setKind(BaseKind K) { Kind = K; }
106 BaseKind getKind()
const {
return Kind; }
107 bool isRegBase()
const {
return Kind == RegBase; }
108 bool isFIBase()
const {
return Kind == FrameIndexBase; }
110 void setReg(
unsigned Reg) {
111 assert(isRegBase() &&
"Invalid base register access!");
116 assert(isRegBase() &&
"Invalid base register access!");
120 void setFI(
unsigned FI) {
121 assert(isFIBase() &&
"Invalid base frame index access!");
125 unsigned getFI()
const {
126 assert(isFIBase() &&
"Invalid base frame index access!");
130 void setOffset(int64_t Offset_) { Offset = Offset_; }
147 bool fastLowerArguments()
override;
148 bool fastLowerCall(CallLoweringInfo &CLI)
override;
149 bool fastLowerIntrinsicCall(
const IntrinsicInst *II)
override;
151 bool UnsupportedFPMode;
165 bool selectFPToInt(
const Instruction *I,
bool IsSigned);
170 bool selectDivRem(
const Instruction *I,
unsigned ISDOpcode);
173 bool isTypeLegal(
Type *Ty,
MVT &VT);
174 bool isTypeSupported(
Type *Ty,
MVT &VT);
175 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
178 void simplifyAddress(
Address &Addr);
182 bool emitLoad(
MVT VT,
unsigned &ResultReg,
Address &Addr,
183 unsigned Alignment = 0);
184 bool emitStore(
MVT VT,
unsigned SrcReg,
Address Addr,
186 bool emitStore(
MVT VT,
unsigned SrcReg,
Address &Addr,
187 unsigned Alignment = 0);
188 unsigned emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
bool isZExt);
189 bool emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg,
192 bool emitIntZExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg);
194 bool emitIntSExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
unsigned DestReg);
195 bool emitIntSExt32r1(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
197 bool emitIntSExt32r2(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
200 unsigned getRegEnsuringSimpleIntegerWidening(
const Value *,
bool IsUnsigned);
202 unsigned emitLogicalOp(
unsigned ISDOpc,
MVT RetVT,
const Value *LHS,
209 unsigned materializeExternalCallSym(
MCSymbol *Syn);
212 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.
get(Opc));
216 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.
get(Opc),
221 unsigned MemReg, int64_t MemOffset) {
226 unsigned MemReg, int64_t MemOffset) {
227 return emitInst(Opc, DstReg).
addReg(MemReg).
addImm(MemOffset);
230 unsigned fastEmitInst_rr(
unsigned MachineInstOpcode,
232 unsigned Op0,
bool Op0IsKill,
233 unsigned Op1,
bool Op1IsKill);
238 unsigned Op0,
bool Op0IsKill, uint64_t imm1,
239 uint64_t imm2,
unsigned Op3,
bool Op3IsKill) {
248 bool finishCall(CallLoweringInfo &CLI,
MVT RetVT,
unsigned NumBytes);
266 unsigned fastMaterializeAlloca(
const AllocaInst *AI)
override;
267 unsigned fastMaterializeConstant(
const Constant *C)
override;
268 bool fastSelectInstruction(
const Instruction *I)
override;
270 #include "MipsGenFastISel.inc" 291 #include "MipsGenCallingConv.inc" 297 unsigned MipsFastISel::emitLogicalOp(
unsigned ISDOpc,
MVT RetVT,
300 if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS))
318 unsigned LHSReg = getRegForValue(LHS);
323 if (
const auto *
C = dyn_cast<ConstantInt>(RHS))
326 RHSReg = getRegForValue(RHS);
330 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
334 emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
338 unsigned MipsFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
340 "Alloca should always return a pointer.");
343 FuncInfo.StaticAllocaMap.find(AI);
345 if (SI != FuncInfo.StaticAllocaMap.
end()) {
346 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
347 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Mips::LEA_ADDiu),
349 .addFrameIndex(SI->second)
357 unsigned MipsFastISel::materializeInt(
const Constant *
C,
MVT VT) {
365 unsigned MipsFastISel::materialize32BitInt(int64_t Imm,
367 unsigned ResultReg = createResultReg(RC);
370 unsigned Opc = Mips::ADDiu;
371 emitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);
374 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);
377 unsigned Lo = Imm & 0xFFFF;
378 unsigned Hi = (Imm >> 16) & 0xFFFF;
381 unsigned TmpReg = createResultReg(RC);
382 emitInst(Mips::LUi, TmpReg).addImm(Hi);
383 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo);
385 emitInst(Mips::LUi, ResultReg).addImm(Hi);
390 unsigned MipsFastISel::materializeFP(
const ConstantFP *CFP,
MVT VT) {
391 if (UnsupportedFPMode)
396 unsigned DestReg = createResultReg(RC);
397 unsigned TempReg = materialize32BitInt(Imm, &Mips::GPR32RegClass);
398 emitInst(Mips::MTC1, DestReg).addReg(TempReg);
402 unsigned DestReg = createResultReg(RC);
403 unsigned TempReg1 = materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);
405 materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);
412 unsigned MipsFastISel::materializeGV(
const GlobalValue *GV,
MVT VT) {
417 unsigned DestReg = createResultReg(RC);
423 emitInst(Mips::LW, DestReg)
424 .addReg(MFI->getGlobalBaseReg())
428 unsigned TempReg = createResultReg(RC);
429 emitInst(Mips::ADDiu, TempReg)
437 unsigned MipsFastISel::materializeExternalCallSym(
MCSymbol *Sym) {
439 unsigned DestReg = createResultReg(RC);
440 emitInst(Mips::LW, DestReg)
441 .addReg(MFI->getGlobalBaseReg())
448 unsigned MipsFastISel::fastMaterializeConstant(
const Constant *C) {
449 EVT CEVT = TLI.getValueType(DL, C->
getType(),
true);
456 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
457 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);
458 else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(C))
459 return materializeGV(GV, VT);
460 else if (isa<ConstantInt>(C))
461 return materializeInt(C, VT);
466 bool MipsFastISel::computeAddress(
const Value *Obj,
Address &Addr) {
467 const User *U =
nullptr;
468 unsigned Opcode = Instruction::UserOp1;
469 if (
const Instruction *
I = dyn_cast<Instruction>(Obj)) {
472 if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
473 FuncInfo.MBBMap[
I->getParent()] == FuncInfo.MBB) {
474 Opcode =
I->getOpcode();
477 }
else if (
const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
478 Opcode = C->getOpcode();
484 case Instruction::BitCast:
486 return computeAddress(U->
getOperand(0), Addr);
487 case Instruction::GetElementPtr: {
489 int64_t TmpOffset = Addr.getOffset();
498 unsigned Idx = cast<ConstantInt>(
Op)->getZExtValue();
503 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
505 TmpOffset += CI->getSExtValue() * S;
508 if (canFoldAddIntoGEP(U, Op)) {
511 cast<ConstantInt>(cast<AddOperator>(
Op)->getOperand(1));
514 Op = cast<AddOperator>(
Op)->getOperand(0);
518 goto unsupported_gep;
523 Addr.setOffset(TmpOffset);
531 case Instruction::Alloca: {
534 FuncInfo.StaticAllocaMap.find(AI);
535 if (SI != FuncInfo.StaticAllocaMap.end()) {
536 Addr.setKind(Address::FrameIndexBase);
537 Addr.setFI(SI->second);
543 Addr.setReg(getRegForValue(Obj));
544 return Addr.getReg() != 0;
547 bool MipsFastISel::computeCallAddress(
const Value *V,
Address &Addr) {
548 const User *U =
nullptr;
549 unsigned Opcode = Instruction::UserOp1;
551 if (
const auto *
I = dyn_cast<Instruction>(V)) {
554 if (
I->getParent() == FuncInfo.MBB->getBasicBlock()) {
555 Opcode =
I->getOpcode();
558 }
else if (
const auto *C = dyn_cast<ConstantExpr>(V)) {
559 Opcode = C->getOpcode();
566 case Instruction::BitCast:
568 return computeCallAddress(U->
getOperand(0), Addr);
570 case Instruction::IntToPtr:
573 TLI.getPointerTy(DL))
574 return computeCallAddress(U->
getOperand(0), Addr);
576 case Instruction::PtrToInt:
578 if (TLI.getValueType(DL, U->
getType()) == TLI.getPointerTy(DL))
579 return computeCallAddress(U->
getOperand(0), Addr);
583 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
584 Addr.setGlobalValue(GV);
589 if (!Addr.getGlobalValue()) {
590 Addr.setReg(getRegForValue(V));
591 return Addr.getReg() != 0;
597 bool MipsFastISel::isTypeLegal(
Type *Ty,
MVT &VT) {
598 EVT evt = TLI.getValueType(DL, Ty,
true);
606 return TLI.isTypeLegal(VT);
609 bool MipsFastISel::isTypeSupported(
Type *Ty,
MVT &VT) {
613 if (isTypeLegal(Ty, VT))
624 bool MipsFastISel::isLoadTypeLegal(
Type *Ty,
MVT &VT) {
625 if (isTypeLegal(Ty, VT))
642 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned);
645 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(
Right, IsUnsigned);
654 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
655 emitInst(
Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
656 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);
660 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
661 emitInst(
Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);
662 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
666 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
669 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
672 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
673 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
674 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
678 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
679 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);
680 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
684 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
687 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
690 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
691 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
692 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
696 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
697 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);
698 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
707 if (UnsupportedFPMode)
711 if (!IsFloat && !IsDouble)
713 unsigned Opc, CondMovOpc;
716 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
717 CondMovOpc = Mips::MOVT_I;
720 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;
721 CondMovOpc = Mips::MOVF_I;
724 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;
725 CondMovOpc = Mips::MOVT_I;
728 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;
729 CondMovOpc = Mips::MOVT_I;
732 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;
733 CondMovOpc = Mips::MOVF_I;
736 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;
737 CondMovOpc = Mips::MOVF_I;
742 unsigned RegWithZero = createResultReg(&Mips::GPR32RegClass);
743 unsigned RegWithOne = createResultReg(&Mips::GPR32RegClass);
744 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
745 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
748 emitInst(CondMovOpc, ResultReg)
751 .addReg(RegWithZero);
758 bool MipsFastISel::emitLoad(
MVT VT,
unsigned &ResultReg,
Address &Addr,
759 unsigned Alignment) {
766 ResultReg = createResultReg(&Mips::GPR32RegClass);
770 ResultReg = createResultReg(&Mips::GPR32RegClass);
774 ResultReg = createResultReg(&Mips::GPR32RegClass);
778 if (UnsupportedFPMode)
780 ResultReg = createResultReg(&Mips::FGR32RegClass);
784 if (UnsupportedFPMode)
786 ResultReg = createResultReg(&Mips::AFGR64RegClass);
792 if (Addr.isRegBase()) {
793 simplifyAddress(Addr);
794 emitInstLoad(Opc, ResultReg, Addr.getReg(), Addr.getOffset());
797 if (Addr.isFIBase()) {
798 unsigned FI = Addr.getFI();
800 int64_t
Offset = Addr.getOffset();
805 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc), ResultReg)
814 bool MipsFastISel::emitStore(
MVT VT,
unsigned SrcReg,
Address &Addr,
815 unsigned Alignment) {
831 if (UnsupportedFPMode)
836 if (UnsupportedFPMode)
843 if (Addr.isRegBase()) {
844 simplifyAddress(Addr);
845 emitInstStore(Opc, SrcReg, Addr.getReg(), Addr.getOffset());
848 if (Addr.isFIBase()) {
849 unsigned FI = Addr.getFI();
851 int64_t
Offset = Addr.getOffset();
856 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc))
866 bool MipsFastISel::selectLogicalOp(
const Instruction *
I) {
868 if (!isTypeSupported(I->
getType(), VT))
875 case Instruction::And:
878 case Instruction::Or:
881 case Instruction::Xor:
889 updateValueMap(I, ResultReg);
893 bool MipsFastISel::selectLoad(
const Instruction *I) {
900 if (!isLoadTypeLegal(I->
getType(), VT))
909 if (!emitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment()))
911 updateValueMap(I, ResultReg);
915 bool MipsFastISel::selectStore(
const Instruction *I) {
929 SrcReg = getRegForValue(Op0);
938 if (!emitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment()))
945 bool MipsFastISel::selectBranch(
const Instruction *I) {
960 unsigned ZExtCondReg = 0;
963 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
970 if (ZExtCondReg == 0) {
976 if (ZExtCondReg == 0)
980 BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Mips::BGTZ))
983 finishCondBranch(BI->
getParent(), TBB, FBB);
987 bool MipsFastISel::selectCmp(
const Instruction *I) {
988 const CmpInst *CI = cast<CmpInst>(
I);
989 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
992 updateValueMap(I, ResultReg);
997 bool MipsFastISel::selectFPExt(
const Instruction *I) {
998 if (UnsupportedFPMode)
1001 EVT SrcVT = TLI.getValueType(DL, Src->
getType(),
true);
1002 EVT DestVT = TLI.getValueType(DL, I->
getType(),
true);
1008 getRegForValue(Src);
1013 unsigned DestReg = createResultReg(&Mips::AFGR64RegClass);
1014 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
1015 updateValueMap(I, DestReg);
1019 bool MipsFastISel::selectSelect(
const Instruction *I) {
1020 assert(isa<SelectInst>(I) &&
"Expected a select instruction.");
1025 if (!isTypeSupported(I->
getType(), VT) || UnsupportedFPMode) {
1027 dbgs() <<
".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");
1031 unsigned CondMovOpc;
1035 CondMovOpc = Mips::MOVN_I_I;
1036 RC = &Mips::GPR32RegClass;
1038 CondMovOpc = Mips::MOVN_I_S;
1039 RC = &Mips::FGR32RegClass;
1041 CondMovOpc = Mips::MOVN_I_D32;
1042 RC = &Mips::AFGR64RegClass;
1050 unsigned CondReg = getRegForValue(Cond);
1052 if (!Src1Reg || !Src2Reg || !CondReg)
1055 unsigned ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
1062 unsigned ResultReg = createResultReg(RC);
1063 unsigned TempReg = createResultReg(RC);
1065 if (!ResultReg || !TempReg)
1068 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
1069 emitInst(CondMovOpc, ResultReg)
1070 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);
1071 updateValueMap(I, ResultReg);
1076 bool MipsFastISel::selectFPTrunc(
const Instruction *I) {
1077 if (UnsupportedFPMode)
1080 EVT SrcVT = TLI.getValueType(DL, Src->
getType(),
true);
1081 EVT DestVT = TLI.getValueType(DL, I->
getType(),
true);
1086 unsigned SrcReg = getRegForValue(Src);
1090 unsigned DestReg = createResultReg(&Mips::FGR32RegClass);
1094 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
1095 updateValueMap(I, DestReg);
1100 bool MipsFastISel::selectFPToInt(
const Instruction *I,
bool IsSigned) {
1101 if (UnsupportedFPMode)
1108 if (!isTypeLegal(DstTy, DstVT))
1116 if (!isTypeLegal(SrcTy, SrcVT))
1122 unsigned SrcReg = getRegForValue(Src);
1128 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1129 unsigned TempReg = createResultReg(&Mips::FGR32RegClass);
1130 unsigned Opc = (SrcVT ==
MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;
1133 emitInst(Opc, TempReg).addReg(SrcReg);
1134 emitInst(Mips::MFC1, DestReg).addReg(TempReg);
1136 updateValueMap(I, DestReg);
1140 bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,
1142 unsigned &NumBytes) {
1153 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);
1156 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1168 }
else if (i == 1) {
1197 unsigned ArgReg = getRegForValue(ArgVal);
1209 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
false);
1217 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT,
true);
1228 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1229 TII.get(TargetOpcode::COPY), VA.
getLocReg()).addReg(ArgReg);
1242 if (isa<UndefValue>(ArgVal))
1252 unsigned BEAlign = 0;
1253 if (ArgSize < 8 && !Subtarget->isLittle())
1254 BEAlign = 8 - ArgSize;
1257 Addr.setKind(Address::RegBase);
1258 Addr.setReg(Mips::SP);
1261 unsigned Alignment = DL.getABITypeAlignment(ArgVal->
getType());
1274 bool MipsFastISel::finishCall(CallLoweringInfo &CLI,
MVT RetVT,
1275 unsigned NumBytes) {
1277 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);
1283 CLI.Symbol ? CLI.Symbol->getName().data()
1287 if (RVLocs.
size() != 1)
1290 MVT CopyVT = RVLocs[0].getValVT();
1295 unsigned ResultReg = createResultReg(TLI.getRegClassFor(CopyVT));
1298 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1299 TII.get(TargetOpcode::COPY),
1300 ResultReg).addReg(RVLocs[0].getLocReg());
1301 CLI.InRegs.push_back(RVLocs[0].getLocReg());
1303 CLI.ResultReg = ResultReg;
1304 CLI.NumResultRegs = 1;
1309 bool MipsFastISel::fastLowerArguments() {
1312 if (!FuncInfo.CanLowerReturn) {
1325 LLVM_DEBUG(
dbgs() <<
".. gave up (calling convention is not C)\n");
1329 std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,
1331 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};
1332 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};
1333 auto NextGPR32 = GPR32ArgRegs.begin();
1334 auto NextFGR32 = FGR32ArgRegs.begin();
1335 auto NextAFGR64 = AFGR64ArgRegs.begin();
1337 struct AllocatedReg {
1341 : RC(RC),
Reg(Reg) {}
1347 for (
const auto &FormalArg : F->
args()) {
1355 Type *ArgTy = FormalArg.getType();
1361 EVT ArgVT = TLI.getValueType(DL, ArgTy);
1377 LLVM_DEBUG(
dbgs() <<
".. .. gave up (i8/i16 arg is not extended)\n");
1381 if (NextGPR32 == GPR32ArgRegs.end()) {
1382 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1387 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1390 NextFGR32 = FGR32ArgRegs.end();
1391 NextAFGR64 = AFGR64ArgRegs.end();
1397 LLVM_DEBUG(
dbgs() <<
".. .. gave up (i32 arg is zero extended)\n");
1401 if (NextGPR32 == GPR32ArgRegs.end()) {
1402 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of GPR32 arguments)\n");
1407 Allocation.
emplace_back(&Mips::GPR32RegClass, *NextGPR32++);
1410 NextFGR32 = FGR32ArgRegs.end();
1411 NextAFGR64 = AFGR64ArgRegs.end();
1415 if (UnsupportedFPMode) {
1419 if (NextFGR32 == FGR32ArgRegs.end()) {
1420 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of FGR32 arguments)\n");
1424 Allocation.
emplace_back(&Mips::FGR32RegClass, *NextFGR32++);
1427 if (NextGPR32 != GPR32ArgRegs.end())
1429 if (NextAFGR64 != AFGR64ArgRegs.end())
1434 if (UnsupportedFPMode) {
1438 if (NextAFGR64 == AFGR64ArgRegs.end()) {
1439 LLVM_DEBUG(
dbgs() <<
".. .. gave up (ran out of AFGR64 arguments)\n");
1443 Allocation.
emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);
1446 if (NextGPR32 != GPR32ArgRegs.end())
1448 if (NextGPR32 != GPR32ArgRegs.end())
1450 if (NextFGR32 != FGR32ArgRegs.end())
1460 for (
const auto &FormalArg : F->
args()) {
1461 unsigned ArgNo = FormalArg.getArgNo();
1462 unsigned SrcReg = Allocation[ArgNo].Reg;
1463 unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);
1467 unsigned ResultReg = createResultReg(Allocation[ArgNo].RC);
1468 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1469 TII.get(TargetOpcode::COPY), ResultReg)
1471 updateValueMap(&FormalArg, ResultReg);
1476 unsigned IncomingArgSizeInBytes = 0;
1481 IncomingArgSizeInBytes = std::min(getABI().GetCalleeAllocdArgSizeInBytes(CC),
1482 IncomingArgSizeInBytes);
1490 bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1492 bool IsTailCall = CLI.IsTailCall;
1493 bool IsVarArg = CLI.IsVarArg;
1511 if (CLI.RetTy->isVoidTy())
1513 else if (!isTypeSupported(CLI.RetTy, RetVT))
1516 for (
auto Flag : CLI.OutFlags)
1522 OutVTs.
reserve(CLI.OutVals.size());
1524 for (
auto *Val : CLI.OutVals) {
1526 if (!isTypeLegal(Val->getType(), VT) &&
1538 if (!computeCallAddress(Callee, Addr))
1543 if (!processCallArgs(CLI, OutVTs, NumBytes))
1546 if (!Addr.getGlobalValue())
1550 unsigned DestAddress;
1552 DestAddress = materializeExternalCallSym(Symbol);
1554 DestAddress = materializeGV(Addr.getGlobalValue(),
MVT::i32);
1555 emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);
1557 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Mips::JALR),
1561 for (
auto Reg : CLI.OutRegs)
1570 if (EmitJalrReloc && !Subtarget->inMips16Mode()) {
1576 MIB.
addSym(FuncInfo.MF->getContext().getOrCreateSymbol(
1581 return finishCall(CLI, RetVT, NumBytes);
1584 bool MipsFastISel::fastLowerIntrinsicCall(
const IntrinsicInst *II) {
1592 if (!isTypeSupported(RetTy, VT))
1595 unsigned SrcReg = getRegForValue(II->
getOperand(0));
1598 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1602 if (Subtarget->hasMips32r2()) {
1603 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
1604 updateValueMap(II, DestReg);
1607 unsigned TempReg[3];
1608 for (
int i = 0; i < 3; i++) {
1609 TempReg[i] = createResultReg(&Mips::GPR32RegClass);
1610 if (TempReg[i] == 0)
1613 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
1614 emitInst(
Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
1615 emitInst(
Mips::OR, TempReg[2]).addReg(TempReg[0]).addReg(TempReg[1]);
1616 emitInst(Mips::ANDi, DestReg).addReg(TempReg[2]).addImm(0xFFFF);
1617 updateValueMap(II, DestReg);
1621 if (Subtarget->hasMips32r2()) {
1622 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
1623 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
1624 emitInst(
Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
1625 updateValueMap(II, DestReg);
1628 unsigned TempReg[8];
1629 for (
int i = 0; i < 8; i++) {
1630 TempReg[i] = createResultReg(&Mips::GPR32RegClass);
1631 if (TempReg[i] == 0)
1635 emitInst(
Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
1636 emitInst(
Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
1637 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
1638 emitInst(
Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
1640 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
1641 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
1643 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
1644 emitInst(
Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
1645 emitInst(
Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
1646 updateValueMap(II, DestReg);
1654 const auto *MTI = cast<MemTransferInst>(II);
1656 if (MTI->isVolatile())
1658 if (!MTI->getLength()->getType()->isIntegerTy(32))
1660 const char *IntrMemName = isa<MemCpyInst>(II) ?
"memcpy" :
"memmove";
1664 const MemSetInst *MSI = cast<MemSetInst>(II);
1676 bool MipsFastISel::selectRet(
const Instruction *I) {
1682 if (!FuncInfo.CanLowerReturn)
1703 CCInfo.AnalyzeReturn(Outs, RetCC);
1706 if (ValLocs.size() != 1)
1721 unsigned Reg = getRegForValue(RV);
1725 unsigned SrcReg = Reg + VA.
getValNo();
1728 if (!
MRI.getRegClass(SrcReg)->contains(DestReg))
1731 EVT RVEVT = TLI.getValueType(DL, RV->
getType());
1743 if (RVVT ==
MVT::f64 && UnsupportedFPMode) {
1750 if (RVVT != DestVT) {
1754 if (Outs[0].Flags.isZExt() || Outs[0].Flags.isSExt()) {
1755 bool IsZExt = Outs[0].Flags.isZExt();
1756 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);
1763 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1764 TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);
1770 for (
unsigned i = 0, e = RetRegs.
size(); i != e; ++i)
1775 bool MipsFastISel::selectTrunc(
const Instruction *I) {
1781 SrcVT = TLI.getValueType(DL, Op->
getType(),
true);
1782 DestVT = TLI.getValueType(DL, I->
getType(),
true);
1789 unsigned SrcReg = getRegForValue(Op);
1795 updateValueMap(I, SrcReg);
1799 bool MipsFastISel::selectIntExt(
const Instruction *I) {
1804 bool isZExt = isa<ZExtInst>(
I);
1805 unsigned SrcReg = getRegForValue(Src);
1809 EVT SrcEVT, DestEVT;
1810 SrcEVT = TLI.getValueType(DL, SrcTy,
true);
1811 DestEVT = TLI.getValueType(DL, DestTy,
true);
1819 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
1821 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
1823 updateValueMap(I, ResultReg);
1827 bool MipsFastISel::emitIntSExt32r1(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1840 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
1841 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
1842 emitInst(
Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
1846 bool MipsFastISel::emitIntSExt32r2(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1852 emitInst(Mips::SEB, DestReg).addReg(SrcReg);
1855 emitInst(Mips::SEH, DestReg).addReg(SrcReg);
1861 bool MipsFastISel::emitIntSExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1865 if (Subtarget->hasMips32r2())
1866 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
1867 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
1870 bool MipsFastISel::emitIntZExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1888 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);
1892 bool MipsFastISel::emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1893 unsigned DestReg,
bool IsZExt) {
1902 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
1903 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
1906 unsigned MipsFastISel::emitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1908 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
1909 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);
1910 return Success ? DestReg : 0;
1913 bool MipsFastISel::selectDivRem(
const Instruction *I,
unsigned ISDOpcode) {
1914 EVT DestEVT = TLI.getValueType(DL, I->
getType(),
true);
1923 switch (ISDOpcode) {
1936 unsigned Src0Reg = getRegForValue(I->
getOperand(0));
1937 unsigned Src1Reg = getRegForValue(I->
getOperand(1));
1938 if (!Src0Reg || !Src1Reg)
1941 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
1942 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
1944 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
1951 emitInst(MFOpc, ResultReg);
1953 updateValueMap(I, ResultReg);
1957 bool MipsFastISel::selectShift(
const Instruction *I) {
1960 if (!isTypeSupported(I->
getType(), RetVT))
1963 unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
1969 unsigned Op0Reg = getRegForValue(Op0);
1974 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {
1975 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
1979 MVT Op0MVT = TLI.getValueType(DL, Op0->
getType(),
true).getSimpleVT();
1980 bool IsZExt = Opcode == Instruction::LShr;
1981 if (!emitIntExt(Op0MVT, Op0Reg,
MVT::i32, TempReg, IsZExt))
1987 if (
const auto *C = dyn_cast<ConstantInt>(I->
getOperand(1))) {
1988 uint64_t ShiftVal = C->getZExtValue();
1993 case Instruction::Shl:
1996 case Instruction::AShr:
1999 case Instruction::LShr:
2004 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);
2005 updateValueMap(I, ResultReg);
2009 unsigned Op1Reg = getRegForValue(I->
getOperand(1));
2016 case Instruction::Shl:
2017 Opcode = Mips::SLLV;
2019 case Instruction::AShr:
2020 Opcode = Mips::SRAV;
2022 case Instruction::LShr:
2023 Opcode = Mips::SRLV;
2027 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
2028 updateValueMap(I, ResultReg);
2032 bool MipsFastISel::fastSelectInstruction(
const Instruction *I) {
2037 return selectLoad(I);
2039 return selectStore(I);
2040 case Instruction::SDiv:
2044 case Instruction::UDiv:
2048 case Instruction::SRem:
2052 case Instruction::URem:
2056 case Instruction::Shl:
2057 case Instruction::LShr:
2058 case Instruction::AShr:
2059 return selectShift(I);
2060 case Instruction::And:
2061 case Instruction::Or:
2062 case Instruction::Xor:
2063 return selectLogicalOp(I);
2064 case Instruction::Br:
2065 return selectBranch(I);
2067 return selectRet(I);
2068 case Instruction::Trunc:
2069 return selectTrunc(I);
2070 case Instruction::ZExt:
2071 case Instruction::SExt:
2072 return selectIntExt(I);
2073 case Instruction::FPTrunc:
2074 return selectFPTrunc(I);
2075 case Instruction::FPExt:
2076 return selectFPExt(I);
2077 case Instruction::FPToSI:
2078 return selectFPToInt(I,
true);
2079 case Instruction::FPToUI:
2080 return selectFPToInt(I,
false);
2081 case Instruction::ICmp:
2082 case Instruction::FCmp:
2083 return selectCmp(I);
2085 return selectSelect(I);
2090 unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(
const Value *V,
2092 unsigned VReg = getRegForValue(V);
2095 MVT VMVT = TLI.getValueType(DL, V->
getType(),
true).getSimpleVT();
2101 unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
2102 if (!emitIntExt(VMVT, VReg,
MVT::i32, TempReg, IsUnsigned))
2109 void MipsFastISel::simplifyAddress(
Address &Addr) {
2112 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
2113 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
2114 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());
2115 Addr.setReg(DestReg);
2120 unsigned MipsFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2122 unsigned Op0,
bool Op0IsKill,
2123 unsigned Op1,
bool Op1IsKill) {
2131 unsigned ResultReg = createResultReg(RC);
2135 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
2151 return new MipsFastISel(funcInfo, libInfo);
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Return a value (possibly void), from a function.
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class is the base class for the comparison instructions.
bool hasLocalLinkage() const
C - The default llvm calling convention, compatible with C.
uint64_t getZExtValue() const
Get zero extended value.
This class represents lattice values for constants.
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.
void push_back(const T &Elt)
Describe properties that are true of each instruction in the target description file.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
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...
const MipsInstrInfo * getInstrInfo() const override
const Value * getTrueValue() const
0 1 0 0 True if ordered and less than
unsigned getValNo() const
LLVMContext & getContext() const
All values hold a context through their type.
1 1 1 0 True if unordered or not equal
This class wraps the llvm.memset intrinsic.
BasicBlock * getSuccessor(unsigned i) const
constexpr bool isInt< 16 >(int64_t x)
unsigned const TargetRegisterInfo * TRI
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Value * getCondition() const
bool isVectorTy() const
True if this is an instance of VectorType.
void reserve(size_type N)
Value * getLength() const
SI optimize exec mask operations pre RA
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
A description of a memory reference used in the backend.
This class represents the LLVM 'select' instruction.
const HexagonInstrInfo * TII
PointerType * getType() const
Overload to return most specific pointer type.
Class to represent struct types.
A Use represents the edge between a Value definition and its users.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isIntegerTy() const
True if this is an instance of IntegerType.
0 1 0 1 True if ordered and less than or equal
This file contains the simple types necessary to represent the attributes associated with functions a...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
LocInfo getLocInfo() const
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
This file implements a class to represent arbitrary precision integral constant values and operations...
unsigned getSizeInBits() const
Fast - This calling convention attempts to make calls as fast as possible (e.g.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
A constant value that is initialized with an expression using other constant values.
unsigned getNextStackOffset() const
getNextStackOffset - Return the next stack offset such that all stack slots satisfy their alignment r...
Type * getType() const
All values are typed, get the type of this value.
void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn, const Type *RetTy, const char *Func)
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
AttributeList getAttributes() const
Return the attribute list for this Function.
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
amdgpu Simplify well known AMD library false Value * Callee
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
Value * getOperand(unsigned i) const
unsigned getKillRegState(bool B)
Flag
These should be considered private to the implementation of the MCInstrDesc class.
TargetInstrInfo - Interface to description of machine instruction set.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
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)...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Type * getReturnType() const
Returns the type of the ret val.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
Conditional or Unconditional Branch instruction.
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static ManagedStatic< OptionRegistry > OR
ConstantFP - Floating Point Values [float, double].
bool hasInternalLinkage() const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const Value * getCondition() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Type * getIndexedType() const
static bool isAtomic(Instruction *I)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
The memory access writes data.
const APFloat & getValueAPF() const
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
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...
0 0 1 0 True if ordered and greater than
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
unsigned getNumOperands() const
StructType * getStructTypeOrNull() const
CCState - This class holds information needed while lowering arguments and return values...
This is the shared class of boolean and integer constants.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Provides information about what library functions are available for the current target.
static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State, ArrayRef< MCPhysReg > F64Regs)
CCValAssign - Represent assignment of one arg/retval to a location.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
unsigned fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill)
Emit a MachineInstr with two register operands and a result register in the given register class...
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State) LLVM_ATTRIBUTE_UNUSED
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
This file defines the FastISel class.
const MipsTargetLowering * getTargetLowering() const override
void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
const Value * getFalseValue() const
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Predicate getPredicate() const
Return the predicate for this instruction.
unsigned getNumArgOperands() const
bool isVector() const
Return true if this is a vector value type.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Bitwise operators - logical and, logical or, logical xor.
cl::opt< bool > EmitJalrReloc
uint64_t getElementOffset(unsigned Idx) const
void emplace_back(ArgTypes &&... Args)
unsigned getLocMemOffset() const
unsigned greater or equal
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
const Function * getParent() const
Return the enclosing method, or null if none.
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
constexpr bool isUInt< 16 >(uint64_t x)
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
0 0 0 1 True if ordered and equal
LLVM Value Representation.
bool useSoftFloat() const
Primary interface to the complete machine description for the target machine.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasOneUse() const
Return true if there is exactly one user of this value.
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
unsigned constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II, const MachineOperand &RegMO, unsigned OpIdx)
Try to constrain Reg so that it is usable by argument OpIdx of the provided MCInstrDesc II...
APInt bitcastToAPInt() const
#define LLVM_ATTRIBUTE_UNUSED
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
unsigned getLocReg() const
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
0 0 1 1 True if ordered and greater than or equal
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
void convertToReg(unsigned RegNo)
iterator_range< arg_iterator > args()
bool isStructTy() const
True if this is an instance of StructType.
bool isArrayTy() const
True if this is an instance of ArrayType.
A wrapper class for inspecting calls to intrinsic functions.
This file describes how to lower LLVM code to machine code.
const BasicBlock * getParent() const
an instruction to allocate memory on the stack
Helper operand used to generate R_MIPS_JALR.
gep_type_iterator gep_type_begin(const User *GEP)