14 #define DEBUG_TYPE "mips-lower"
42 STATISTIC(NumTailCalls,
"Number of tail calls");
50 cl::desc(
"MIPS: Don't trap on integer division by zero."),
54 Mips::A0, Mips::A1, Mips::A2, Mips::A3
58 Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
59 Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64
63 Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,
64 Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64
86 unsigned Flag)
const {
92 unsigned Flag)
const {
98 unsigned Flag)
const {
104 unsigned Flag)
const {
110 unsigned Flag)
const {
200 default:
return NULL;
208 HasMips64(Subtarget->hasMips64()), IsN64(Subtarget->isABI_N64()),
209 IsO32(Subtarget->isABI_O32()) {
417 unsigned LO = (Ty ==
MVT::i32) ? Mips::LO0 : Mips::LO0_64;
418 unsigned HI = (Ty ==
MVT::i32) ? Mips::HI0 : Mips::HI0_64;
481 "Illegal Condition Code");
563 unsigned ShiftRightOpc = ShiftRight.
getOpcode();
571 if (!(CN = dyn_cast<ConstantSDNode>(ShiftRight.
getOperand(1))))
575 uint64_t SMPos, SMSize;
578 if (!(CN = dyn_cast<ConstantSDNode>(Mask)) ||
604 uint64_t SMPos0, SMSize0, SMPos1, SMSize1;
611 if (!(CN = dyn_cast<ConstantSDNode>(And0.
getOperand(1))) ||
619 if (!(CN = dyn_cast<ConstantSDNode>(And1.getOperand(1))) ||
624 if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
631 if (!(CN = dyn_cast<ConstantSDNode>(Shl.
getOperand(1))))
639 if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.
getSizeInBits()))
731 case ISD::FABS:
return lowerFABS(Op, DAG);
741 case ISD::ADD:
return lowerADD(Op, DAG);
792 case Mips::ATOMIC_LOAD_ADD_I8:
793 return emitAtomicBinaryPartword(MI, BB, 1, Mips::ADDu);
794 case Mips::ATOMIC_LOAD_ADD_I16:
795 return emitAtomicBinaryPartword(MI, BB, 2, Mips::ADDu);
796 case Mips::ATOMIC_LOAD_ADD_I32:
797 return emitAtomicBinary(MI, BB, 4, Mips::ADDu);
798 case Mips::ATOMIC_LOAD_ADD_I64:
799 return emitAtomicBinary(MI, BB, 8, Mips::DADDu);
801 case Mips::ATOMIC_LOAD_AND_I8:
802 return emitAtomicBinaryPartword(MI, BB, 1,
Mips::AND);
803 case Mips::ATOMIC_LOAD_AND_I16:
804 return emitAtomicBinaryPartword(MI, BB, 2,
Mips::AND);
805 case Mips::ATOMIC_LOAD_AND_I32:
806 return emitAtomicBinary(MI, BB, 4,
Mips::AND);
807 case Mips::ATOMIC_LOAD_AND_I64:
808 return emitAtomicBinary(MI, BB, 8, Mips::AND64);
810 case Mips::ATOMIC_LOAD_OR_I8:
811 return emitAtomicBinaryPartword(MI, BB, 1,
Mips::OR);
812 case Mips::ATOMIC_LOAD_OR_I16:
813 return emitAtomicBinaryPartword(MI, BB, 2,
Mips::OR);
814 case Mips::ATOMIC_LOAD_OR_I32:
815 return emitAtomicBinary(MI, BB, 4,
Mips::OR);
816 case Mips::ATOMIC_LOAD_OR_I64:
817 return emitAtomicBinary(MI, BB, 8, Mips::OR64);
819 case Mips::ATOMIC_LOAD_XOR_I8:
820 return emitAtomicBinaryPartword(MI, BB, 1,
Mips::XOR);
821 case Mips::ATOMIC_LOAD_XOR_I16:
822 return emitAtomicBinaryPartword(MI, BB, 2,
Mips::XOR);
823 case Mips::ATOMIC_LOAD_XOR_I32:
824 return emitAtomicBinary(MI, BB, 4,
Mips::XOR);
825 case Mips::ATOMIC_LOAD_XOR_I64:
826 return emitAtomicBinary(MI, BB, 8, Mips::XOR64);
828 case Mips::ATOMIC_LOAD_NAND_I8:
829 return emitAtomicBinaryPartword(MI, BB, 1, 0,
true);
830 case Mips::ATOMIC_LOAD_NAND_I16:
831 return emitAtomicBinaryPartword(MI, BB, 2, 0,
true);
832 case Mips::ATOMIC_LOAD_NAND_I32:
833 return emitAtomicBinary(MI, BB, 4, 0,
true);
834 case Mips::ATOMIC_LOAD_NAND_I64:
835 return emitAtomicBinary(MI, BB, 8, 0,
true);
837 case Mips::ATOMIC_LOAD_SUB_I8:
838 return emitAtomicBinaryPartword(MI, BB, 1, Mips::SUBu);
839 case Mips::ATOMIC_LOAD_SUB_I16:
840 return emitAtomicBinaryPartword(MI, BB, 2, Mips::SUBu);
841 case Mips::ATOMIC_LOAD_SUB_I32:
842 return emitAtomicBinary(MI, BB, 4, Mips::SUBu);
843 case Mips::ATOMIC_LOAD_SUB_I64:
844 return emitAtomicBinary(MI, BB, 8, Mips::DSUBu);
846 case Mips::ATOMIC_SWAP_I8:
847 return emitAtomicBinaryPartword(MI, BB, 1, 0);
848 case Mips::ATOMIC_SWAP_I16:
849 return emitAtomicBinaryPartword(MI, BB, 2, 0);
850 case Mips::ATOMIC_SWAP_I32:
851 return emitAtomicBinary(MI, BB, 4, 0);
852 case Mips::ATOMIC_SWAP_I64:
853 return emitAtomicBinary(MI, BB, 8, 0);
855 case Mips::ATOMIC_CMP_SWAP_I8:
856 return emitAtomicCmpSwapPartword(MI, BB, 1);
857 case Mips::ATOMIC_CMP_SWAP_I16:
858 return emitAtomicCmpSwapPartword(MI, BB, 2);
859 case Mips::ATOMIC_CMP_SWAP_I32:
860 return emitAtomicCmpSwap(MI, BB, 4);
861 case Mips::ATOMIC_CMP_SWAP_I64:
862 return emitAtomicCmpSwap(MI, BB, 8);
863 case Mips::PseudoSDIV:
864 case Mips::PseudoUDIV:
866 case Mips::PseudoDSDIV:
867 case Mips::PseudoDUDIV:
876 unsigned Size,
unsigned BinOpcode,
878 assert((Size == 4 || Size == 8) &&
"Unsupported size for EmitAtomicBinary.");
885 unsigned LL,
SC,
AND, NOR, ZERO, BEQ;
900 ZERO = Mips::ZERO_64;
945 }
else if (BinOpcode) {
960 MipsTargetLowering::emitAtomicBinaryPartword(
MachineInstr *MI,
962 unsigned Size,
unsigned BinOpcode,
964 assert((Size == 1 || Size == 2) &&
965 "Unsupported size for EmitAtomicBinaryPartial.");
1027 int64_t MaskImm = (Size == 1) ? 255 : 65535;
1028 BuildMI(BB, DL, TII->
get(Mips::ADDiu), MaskLSB2)
1029 .addReg(Mips::ZERO).
addImm(-4);
1031 .addReg(Ptr).
addReg(MaskLSB2);
1038 .addReg(PtrLSB2).
addImm((Size == 1) ? 3 : 2);
1041 BuildMI(BB, DL, TII->
get(Mips::ORi), MaskUpper)
1042 .addReg(Mips::ZERO).
addImm(MaskImm);
1044 .addReg(MaskUpper).
addReg(ShiftAmt);
1045 BuildMI(BB, DL, TII->
get(Mips::NOR), Mask2).addReg(Mips::ZERO).
addReg(Mask);
1046 BuildMI(BB, DL, TII->
get(Mips::SLLV), Incr2).addReg(Incr).
addReg(ShiftAmt);
1074 BuildMI(BB, DL, TII->
get(Mips::NOR), BinOpRes)
1075 .addReg(Mips::ZERO).
addReg(AndRes);
1077 }
else if (BinOpcode) {
1080 BuildMI(BB, DL, TII->
get(BinOpcode), BinOpRes).addReg(OldVal).
addReg(Incr2);
1088 .addReg(OldVal).
addReg(Mask2);
1090 .addReg(MaskedOldVal0).
addReg(NewVal);
1102 int64_t ShiftImm = (Size == 1) ? 24 : 16;
1105 .addReg(OldVal).
addReg(Mask);
1106 BuildMI(BB, DL, TII->
get(Mips::SRLV), SrlRes)
1107 .addReg(MaskedOldVal1).
addReg(ShiftAmt);
1109 .addReg(SrlRes).
addImm(ShiftImm);
1111 .addReg(SllRes).
addImm(ShiftImm);
1120 unsigned Size)
const {
1121 assert((Size == 4 || Size == 8) &&
"Unsupported size for EmitAtomicCmpSwap.");
1128 unsigned LL,
SC, ZERO, BNE, BEQ;
1139 ZERO = Mips::ZERO_64;
1158 MF->
insert(It, loop1MBB);
1159 MF->
insert(It, loop2MBB);
1199 MipsTargetLowering::emitAtomicCmpSwapPartword(
MachineInstr *MI,
1201 unsigned Size)
const {
1202 assert((Size == 1 || Size == 2) &&
1203 "Unsupported size for EmitAtomicCmpSwapPartial.");
1243 MF->
insert(It, loop1MBB);
1244 MF->
insert(It, loop2MBB);
1273 int64_t MaskImm = (Size == 1) ? 255 : 65535;
1274 BuildMI(BB, DL, TII->
get(Mips::ADDiu), MaskLSB2)
1275 .addReg(Mips::ZERO).
addImm(-4);
1277 .addReg(Ptr).
addReg(MaskLSB2);
1284 .addReg(PtrLSB2).
addImm((Size == 1) ? 3 : 2);
1287 BuildMI(BB, DL, TII->
get(Mips::ORi), MaskUpper)
1288 .addReg(Mips::ZERO).
addImm(MaskImm);
1290 .addReg(MaskUpper).
addReg(ShiftAmt);
1291 BuildMI(BB, DL, TII->
get(Mips::NOR), Mask2).addReg(Mips::ZERO).
addReg(Mask);
1292 BuildMI(BB, DL, TII->
get(Mips::ANDi), MaskedCmpVal)
1293 .addReg(CmpVal).
addImm(MaskImm);
1294 BuildMI(BB, DL, TII->
get(Mips::SLLV), ShiftedCmpVal)
1295 .addReg(MaskedCmpVal).
addReg(ShiftAmt);
1296 BuildMI(BB, DL, TII->
get(Mips::ANDi), MaskedNewVal)
1297 .addReg(NewVal).
addImm(MaskImm);
1298 BuildMI(BB, DL, TII->
get(Mips::SLLV), ShiftedNewVal)
1299 .addReg(MaskedNewVal).
addReg(ShiftAmt);
1308 .addReg(OldVal).
addReg(Mask);
1310 .addReg(MaskedOldVal0).
addReg(ShiftedCmpVal).
addMBB(sinkMBB);
1319 .addReg(OldVal).
addReg(Mask2);
1321 .addReg(MaskedOldVal1).
addReg(ShiftedNewVal);
1332 int64_t ShiftImm = (Size == 1) ? 24 : 16;
1334 BuildMI(BB, DL, TII->
get(Mips::SRLV), SrlRes)
1335 .addReg(MaskedOldVal0).
addReg(ShiftAmt);
1337 .addReg(SrlRes).
addImm(ShiftImm);
1339 .addReg(SllRes).
addImm(ShiftImm);
1355 unsigned EntrySize =
1399 FCC0, Dest, CondRes);
1433 "Floating point operand expected.");
1467 if (GV->hasInternalLinkage() || (GV->hasLocalLinkage() && !isa<Function>(GV)))
1520 Entry.Node = Argument;
1522 Args.push_back(Entry);
1528 TlsGetAddr, Args, DAG, DL);
1529 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
1536 SDValue TGAHi = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
1539 SDValue TGALo = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
1543 return DAG.getNode(
ISD::ADD, DL, PtrVT, Add, Lo);
1549 SDValue TGA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
1553 Offset = DAG.getLoad(PtrVT, DL,
1555 false,
false,
false, 0);
1559 SDValue TGAHi = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
1561 SDValue TGALo = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
1569 return DAG.getNode(
ISD::ADD, DL, PtrVT, ThreadPointer, Offset);
1621 bool HasExtractInsert) {
1640 if (HasExtractInsert) {
1667 bool HasExtractInsert) {
1678 if (HasExtractInsert) {
1684 if (WidthX > WidthY)
1686 else if (WidthY > WidthX)
1704 if (WidthX > WidthY)
1706 else if (WidthY > WidthX)
1724 bool HasExtractInsert) {
1736 if (HasExtractInsert)
1754 bool HasExtractInsert) {
1762 if (HasExtractInsert)
1785 assert((cast<ConstantSDNode>(Op.
getOperand(0))->getZExtValue() == 0) &&
1786 "Frame address can only be determined for current frame.");
1793 IsN64 ? Mips::FP_64 : Mips::FP, VT);
1800 assert((cast<ConstantSDNode>(Op.
getOperand(0))->getZExtValue() == 0) &&
1801 "Return address can be determined only for current frame.");
1806 unsigned RA =
IsN64 ? Mips::RA_64 : Mips::RA;
1832 unsigned OffsetReg =
IsN64 ? Mips::V1_64 : Mips::V1;
1833 unsigned AddrReg =
IsN64 ? Mips::V0_64 : Mips::V0;
1936 SDValue Ops[] = { Chain, Ptr, Src };
1947 if ((LD->
getAlignment() >= MemVT.getSizeInBits() / 8) ||
2004 SDValue Chain,
unsigned Offset) {
2069 if ((SD->
getAlignment() < MemVT.getSizeInBits() / 8) &&
2078 || cast<ConstantSDNode>
2126 CCState &State,
const uint16_t *F64Regs) {
2128 static const unsigned IntRegsSize = 4, FloatRegsSize = 2;
2130 static const uint16_t IntRegs[] = { Mips::A0, Mips::A1, Mips::A2, Mips::A3 };
2131 static const uint16_t F32Regs[] = { Mips::F12, Mips::F14 };
2142 else if (ArgFlags.
isZExt())
2153 bool AllocateFloatsInIntReg = State.
isVarArg() || ValNo > 1
2156 bool isI64 = (ValVT ==
MVT::i32 && OrigAlign == 8);
2162 if (isI64 && (Reg == Mips::A1 || Reg == Mips::A3))
2165 }
else if (ValVT ==
MVT::f64 && AllocateFloatsInIntReg) {
2169 if (Reg == Mips::A1 || Reg == Mips::A3)
2182 unsigned Reg2 = State.
AllocateReg(IntRegs, IntRegsSize);
2183 if (Reg2 == Mips::A1 || Reg2 == Mips::A3)
2203 static const uint16_t F64Regs[] = { Mips::D6, Mips::D7 };
2205 return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State, F64Regs);
2211 static const uint16_t F64Regs[] = { Mips::D12_64, Mips::D14_64 };
2213 return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State, F64Regs);
2216 #include "MipsGenCallingConv.inc"
2224 assert((Reg == Mips::A0) || (Reg == Mips::A2));
2225 return (Reg == Mips::A0) ? Mips::A1 : Mips::A3;
2229 MipsTargetLowering::passArgOnStack(
SDValue StackPtr,
unsigned Offset,
2248 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
2249 bool IsPICCall,
bool GlobalOrExternal,
bool InternalLinkage,
2256 if (IsPICCall && !InternalLinkage) {
2257 unsigned GPReg =
IsN64 ? Mips::GP_64 : Mips::GP;
2259 RegsToPass.push_back(std::make_pair(GPReg,
getGlobalReg(CLI.
DAG, Ty)));
2268 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
2270 RegsToPass[i].second, InFlag);
2276 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
2278 RegsToPass[i].second.getValueType()));
2283 assert(Mask &&
"Missing call preserved mask for calling convention");
2287 Function *
F =
G->getGlobal()->getParent()->getFunction(Sym);
2326 getSpecialCallingConv(Callee);
2328 SpecialCallingConv);
2330 MipsCCInfo.analyzeCallOperands(Outs, IsVarArg,
2335 unsigned NextStackOffset = CCInfo.getNextStackOffset();
2340 isEligibleForTailCallOptimization(MipsCCInfo, NextStackOffset,
2357 IsN64 ? Mips::SP_64 : Mips::SP,
2361 std::deque< std::pair<unsigned, SDValue> > RegsToPass;
2366 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
2375 "ByVal args of size 0 should have been ignored by front-end.");
2376 assert(ByValArg != MipsCCInfo.byval_end());
2377 assert(!IsTailCall &&
2378 "Do not tail-call optimize if there is a byval argument.");
2379 passByValArg(Chain, DL, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg,
2403 RegsToPass.push_back(std::make_pair(LocRegLo, Lo));
2404 RegsToPass.push_back(std::make_pair(LocRegHigh, Hi));
2423 RegsToPass.push_back(std::make_pair(VA.
getLocReg(), Arg));
2433 Chain, Arg, DL, IsTailCall, DAG));
2438 if (!MemOpChains.
empty())
2440 &MemOpChains[0], MemOpChains.
size());
2445 bool IsPICCall = (
IsN64 || IsPIC);
2446 bool GlobalOrExternal =
false, InternalLinkage =
false;
2455 if (InternalLinkage)
2467 GlobalOrExternal =
true;
2470 const char *Sym = S->getSymbol();
2472 if (!
IsN64 && !IsPIC)
2483 GlobalOrExternal =
true;
2489 getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, InternalLinkage,
2490 CLI, Callee, Chain);
2505 return LowerCallResult(Chain, InFlag, CallConv, IsVarArg,
2512 MipsTargetLowering::LowerCallResult(
SDValue Chain,
SDValue InFlag,
2518 const Type *RetTy)
const {
2529 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
2531 RVLocs[i].getLocVT(), InFlag);
2535 if (RVLocs[i].getValVT() != RVLocs[i].getLocVT())
2550 MipsTargetLowering::LowerFormalArguments(
SDValue Chain,
2564 std::vector<SDValue> OutChains;
2575 MipsCCInfo.analyzeFormalArguments(Ins, UseSoftFloat, FuncArg);
2577 MipsCCInfo.hasByValArg());
2579 unsigned CurArgIdx = 0;
2582 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
2584 std::advance(FuncArg, Ins[i].OrigArgIndex - CurArgIdx);
2585 CurArgIdx = Ins[i].OrigArgIndex;
2592 "ByVal args of size 0 should have been ignored by front-end.");
2593 assert(ByValArg != MipsCCInfo.byval_end());
2594 copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, &*FuncArg,
2595 MipsCCInfo, *ByValArg);
2615 unsigned Opcode = 0;
2621 ArgValue = DAG.
getNode(Opcode, DL, RegVT, ArgValue,
2639 ArgValue, ArgValue2);
2656 false,
false,
false, 0);
2658 OutChains.push_back(Load.
getValue(1));
2677 writeVarArgRegs(OutChains, MipsCCInfo, Chain, DL, DAG);
2681 if (!OutChains.empty()) {
2682 OutChains.push_back(Chain);
2684 &OutChains[0], OutChains.size());
2702 return CCInfo.CheckReturn(Outs, RetCC_Mips);
2706 MipsTargetLowering::LowerReturn(
SDValue Chain,
2729 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
2732 assert(VA.
isRegLoc() &&
"Can only return in registers!");
2734 if (RVLocs[i].getValVT() != RVLocs[i].getLocVT())
2755 unsigned V0 =
IsN64 ? Mips::V0_64 : Mips::V0;
2766 RetOps.push_back(Flag);
2779 getConstraintType(
const std::string &Constraint)
const
2792 if (Constraint.size() == 1) {
2793 switch (Constraint[0]) {
2813 MipsTargetLowering::getSingleConstraintMatchWeight(
2814 AsmOperandInfo &
info,
const char *constraint)
const {
2816 Value *CallOperandVal = info.CallOperandVal;
2819 if (CallOperandVal == NULL)
2823 switch (*constraint) {
2852 if (isa<ConstantInt>(CallOperandVal))
2866 static std::pair<bool, bool>
2868 unsigned long long &Reg) {
2869 if (C.
front() !=
'{' || C.
back() !=
'}')
2870 return std::make_pair(
false,
false);
2874 I = std::find_if(B, E, std::ptr_fun(
isdigit));
2876 Prefix.assign(B, I - B);
2880 return std::make_pair(
true,
false);
2887 std::pair<unsigned, const TargetRegisterClass *> MipsTargetLowering::
2888 parseRegForInlineAsmConstraint(
const StringRef &
C,
MVT VT)
const {
2892 unsigned long long Reg;
2899 if ((Prefix ==
"hi" || Prefix ==
"lo")) {
2905 Mips::HI32RegClassID : Mips::LO32RegClassID);
2906 return std::make_pair(*(RC->
begin()), RC);
2907 }
else if (Prefix.compare(0, 4,
"$msa") == 0) {
2915 .Case(
"$msair", Mips::MSAIR)
2916 .
Case(
"$msacsr", Mips::MSACSR)
2917 .
Case(
"$msaaccess", Mips::MSAAccess)
2918 .
Case(
"$msasave", Mips::MSASave)
2919 .
Case(
"$msamodify", Mips::MSAModify)
2920 .
Case(
"$msarequest", Mips::MSARequest)
2921 .
Case(
"$msamap", Mips::MSAMap)
2922 .
Case(
"$msaunmap", Mips::MSAUnmap)
2929 return std::make_pair(Reg, RC);
2935 if (Prefix ==
"$f") {
2943 if (RC == &Mips::AFGR64RegClass) {
2944 assert(Reg % 2 == 0);
2947 }
else if (Prefix ==
"$fcc")
2949 else if (Prefix ==
"$w") {
2952 assert(Prefix ==
"$");
2957 return std::make_pair(*(RC->
begin() +
Reg), RC);
2963 std::pair<unsigned, const TargetRegisterClass*> MipsTargetLowering::
2964 getRegForInlineAsmConstraint(
const std::string &Constraint,
MVT VT)
const
2966 if (Constraint.size() == 1) {
2967 switch (Constraint[0]) {
2973 return std::make_pair(0U, &Mips::CPU16RegsRegClass);
2974 return std::make_pair(0U, &Mips::GPR32RegClass);
2977 return std::make_pair(0U, &Mips::GPR32RegClass);
2979 return std::make_pair(0U, &Mips::GPR64RegClass);
2981 return std::make_pair(0u, static_cast<const TargetRegisterClass*>(0));
2984 return std::make_pair(0U, &Mips::MSA128BRegClass);
2986 return std::make_pair(0U, &Mips::MSA128HRegClass);
2988 return std::make_pair(0U, &Mips::MSA128WRegClass);
2990 return std::make_pair(0U, &Mips::MSA128DRegClass);
2992 return std::make_pair(0U, &Mips::FGR32RegClass);
2995 return std::make_pair(0U, &Mips::FGR64RegClass);
2996 return std::make_pair(0U, &Mips::AFGR64RegClass);
3001 return std::make_pair((
unsigned)Mips::T9, &Mips::GPR32RegClass);
3002 assert(VT ==
MVT::i64 &&
"Unexpected type.");
3003 return std::make_pair((
unsigned)Mips::T9_64, &Mips::GPR64RegClass);
3006 return std::make_pair((
unsigned)Mips::LO0, &Mips::LO32RegClass);
3007 return std::make_pair((
unsigned)Mips::LO0_64, &Mips::LO64RegClass);
3011 return std::make_pair(0u, static_cast<const TargetRegisterClass*>(0));
3015 std::pair<unsigned, const TargetRegisterClass *> R;
3016 R = parseRegForInlineAsmConstraint(Constraint, VT);
3026 void MipsTargetLowering::LowerAsmOperandForConstraint(
SDValue Op,
3027 std::string &Constraint,
3028 std::vector<SDValue>&Ops,
3033 if (Constraint.length() > 1)
return;
3035 char ConstraintLetter = Constraint[0];
3036 switch (ConstraintLetter) {
3042 int64_t Val = C->getSExtValue();
3052 int64_t Val = C->getZExtValue();
3062 uint64_t Val = (uint64_t)C->getZExtValue();
3072 int64_t Val = C->getSExtValue();
3073 if ((
isInt<32>(Val)) && ((Val & 0xffff) == 0)){
3082 int64_t Val = C->getSExtValue();
3083 if ((Val >= -65535) && (Val <= -1)) {
3092 int64_t Val = C->getSExtValue();
3093 if ((isInt<15>(Val))) {
3102 int64_t Val = C->getSExtValue();
3103 if ((Val <= 65535) && (Val >= 1)) {
3111 if (Result.getNode()) {
3112 Ops.push_back(Result);
3119 bool MipsTargetLowering::isLegalAddressingMode(
const AddrMode &AM,
3145 EVT MipsTargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign,
3147 bool IsMemset,
bool ZeroMemset,
3156 bool MipsTargetLowering::isFPImmLegal(
const APFloat &Imm,
EVT VT)
const {
3164 unsigned MipsTargetLowering::getJumpTableEncoding()
const {
3173 const char *
const LibCalls[] =
3174 {
"__addtf3",
"__divtf3",
"__eqtf2",
"__extenddftf2",
"__extendsftf2",
3175 "__fixtfdi",
"__fixtfsi",
"__fixtfti",
"__fixunstfdi",
"__fixunstfsi",
3176 "__fixunstfti",
"__floatditf",
"__floatsitf",
"__floattitf",
3177 "__floatunditf",
"__floatunsitf",
"__floatuntitf",
"__getf2",
"__gttf2",
3178 "__letf2",
"__lttf2",
"__multf3",
"__netf2",
"__powitf2",
"__subtf3",
3179 "__trunctfdf2",
"__trunctfsf2",
"__unordtf2",
3180 "ceill",
"copysignl",
"cosl",
"exp2l",
"expl",
"floorl",
"fmal",
"fmodl",
3181 "log10l",
"log2l",
"logl",
"nearbyintl",
"powl",
"rintl",
"sinl",
"sqrtl",
3190 for (
const char *
const *
I = LibCalls;
I < End - 1; ++
I)
3191 assert(Comp(*
I, *(
I + 1)));
3194 return std::binary_search(LibCalls, End, CallSym, Comp);
3204 dyn_cast_or_null<const ExternalSymbolSDNode>(CallNode);
3212 MipsTargetLowering::getSpecialCallingConv(
SDValue Callee)
const {
3218 Function *
F =
G->getGlobal()->getParent()->getFunction(Sym);
3224 return SpecialCallingConv;
3230 : CCInfo(Info), CallConv(CC), IsO32(IsO32_), IsFP64(IsFP64_),
3231 SpecialCallingConv(SpecialCallingConv_){
3239 bool IsVarArg,
bool IsSoftFloat,
const SDNode *CallNode,
3240 std::vector<ArgListEntry> &FuncArgs) {
3242 "CallingConv::Fast shouldn't be used for vararg functions.");
3244 unsigned NumOpnds = Args.
size();
3247 for (
unsigned I = 0;
I != NumOpnds; ++
I) {
3248 MVT ArgVT = Args[
I].VT;
3257 if (IsVarArg && !Args[
I].IsFixed)
3260 MVT RegVT = getRegVT(ArgVT, FuncArgs[Args[
I].OrigArgIndex].Ty, CallNode,
3267 dbgs() <<
"Call operand #" <<
I <<
" has unhandled type "
3278 unsigned NumArgs = Args.
size();
3280 unsigned CurArgIdx = 0;
3282 for (
unsigned I = 0;
I != NumArgs; ++
I) {
3283 MVT ArgVT = Args[
I].VT;
3286 CurArgIdx = Args[
I].OrigArgIndex;
3293 MVT RegVT = getRegVT(ArgVT, FuncArg->getType(), 0, IsSoftFloat);
3299 dbgs() <<
"Formal Arg #" <<
I <<
" has unhandled type "
3306 template<
typename Ty>
3309 const SDNode *CallNode,
const Type *RetTy)
const {
3313 Fn = RetCC_F128Soft;
3317 for (
unsigned I = 0, E = RetVals.
size();
I < E; ++
I) {
3318 MVT VT = RetVals[
I].VT;
3320 MVT RegVT = this->getRegVT(VT, RetTy, CallNode, IsSoftFloat);
3324 dbgs() <<
"Call result #" <<
I <<
" has unhandled type "
3334 const SDNode *CallNode,
const Type *RetTy)
const {
3335 analyzeReturn(Ins, IsSoftFloat, CallNode, RetTy);
3340 const Type *RetTy)
const {
3341 analyzeReturn(Outs, IsSoftFloat, 0, RetTy);
3344 void MipsTargetLowering::MipsCC::handleByValArg(
unsigned ValNo,
MVT ValVT,
3348 assert(ArgFlags.
getByValSize() &&
"Byval argument's size shouldn't be 0.");
3351 unsigned RegSize = regSize();
3356 if (useRegsForByval())
3357 allocateRegs(ByVal, ByValSize, Align);
3360 ByVal.Address = CCInfo.AllocateStack(ByValSize - RegSize * ByVal.NumRegs,
3364 ByValArgs.push_back(ByVal);
3381 return CC_Mips_FastCC;
3383 if (SpecialCallingConv == Mips16RetHelperConv)
3384 return CC_Mips16RetHelper;
3392 const uint16_t *MipsTargetLowering::MipsCC::shadowRegs()
const {
3396 void MipsTargetLowering::MipsCC::allocateRegs(ByValArgInfo &ByVal,
3399 unsigned RegSize = regSize(), NumIntArgRegs = numIntArgRegs();
3400 const uint16_t *IntArgRegs = intArgRegs(), *ShadowRegs = shadowRegs();
3401 assert(!(ByValSize % RegSize) && !(Align % RegSize) &&
3402 "Byval argument's size and alignment should be a multiple of"
3405 ByVal.FirstIdx = CCInfo.getFirstUnallocated(IntArgRegs, NumIntArgRegs);
3408 if ((Align > RegSize) && (ByVal.FirstIdx % 2)) {
3409 CCInfo.AllocateReg(IntArgRegs[ByVal.FirstIdx], ShadowRegs[ByVal.FirstIdx]);
3414 for (
unsigned I = ByVal.FirstIdx; ByValSize && (
I < NumIntArgRegs);
3415 ByValSize -= RegSize, ++
I, ++ByVal.NumRegs)
3416 CCInfo.AllocateReg(IntArgRegs[
I], ShadowRegs[I]);
3419 MVT MipsTargetLowering::MipsCC::getRegVT(
MVT VT,
const Type *OrigTy,
3421 bool IsSoftFloat)
const {
3422 if (IsSoftFloat ||
IsO32)
3434 void MipsTargetLowering::
3435 copyByValRegs(
SDValue Chain,
SDLoc DL, std::vector<SDValue> &OutChains,
3438 const MipsCC &CC,
const ByValArgInfo &ByVal)
const {
3441 unsigned RegAreaSize = ByVal.NumRegs * CC.regSize();
3442 unsigned FrameObjSize = std::max(Flags.
getByValSize(), RegAreaSize);
3446 FrameObjOffset = (int)CC.reservedArgArea() -
3447 (int)((CC.numIntArgRegs() - ByVal.FirstIdx) * CC.regSize());
3449 FrameObjOffset = ByVal.Address;
3464 for (
unsigned I = 0;
I < ByVal.NumRegs; ++
I) {
3465 unsigned ArgReg = CC.intArgRegs()[ByVal.FirstIdx +
I];
3466 unsigned VReg =
addLiveIn(MF, ArgReg, RC);
3467 unsigned Offset =
I * CC.regSize();
3473 OutChains.push_back(Store);
3478 void MipsTargetLowering::
3480 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
3483 const MipsCC &CC,
const ByValArgInfo &ByVal,
3486 unsigned Offset = 0;
3487 unsigned RegSize = CC.regSize();
3488 unsigned Alignment = std::min(Flags.
getByValAlign(), RegSize);
3491 if (ByVal.NumRegs) {
3492 const uint16_t *ArgRegs = CC.intArgRegs();
3493 bool LeftoverBytes = (ByVal.NumRegs * RegSize > ByValSize);
3497 for (; I < ByVal.NumRegs - LeftoverBytes; ++
I, Offset += RegSize) {
3504 unsigned ArgReg = ArgRegs[ByVal.FirstIdx +
I];
3505 RegsToPass.push_back(std::make_pair(ArgReg, LoadVal));
3509 if (ByValSize == Offset)
3513 if (LeftoverBytes) {
3514 assert((ByValSize > Offset) && (ByValSize < Offset + RegSize) &&
3515 "Size of the remainder should be smaller than RegSize.");
3518 for (
unsigned LoadSize = RegSize / 2, TotalSizeLoaded = 0;
3519 Offset < ByValSize; LoadSize /= 2) {
3520 unsigned RemSize = ByValSize - Offset;
3522 if (RemSize < LoadSize)
3531 false,
false, Alignment);
3538 Shamt = TotalSizeLoaded;
3540 Shamt = (RegSize - (TotalSizeLoaded + LoadSize)) * 8;
3551 TotalSizeLoaded += LoadSize;
3552 Alignment = std::min(Alignment, LoadSize);
3555 unsigned ArgReg = ArgRegs[ByVal.FirstIdx +
I];
3556 RegsToPass.push_back(std::make_pair(ArgReg, Val));
3562 unsigned MemCpySize = ByValSize - Offset;
3568 Alignment,
false,
false,
3573 void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains,
3574 const MipsCC &CC,
SDValue Chain,
3576 unsigned NumRegs = CC.numIntArgRegs();
3577 const uint16_t *ArgRegs = CC.intArgRegs();
3578 const CCState &CCInfo = CC.getCCInfo();
3580 unsigned RegSize = CC.regSize();
3593 VaArgOffset = (int)CC.reservedArgArea() - (int)(RegSize * (NumRegs - Idx));
3604 for (
unsigned I = Idx; I < NumRegs; ++
I, VaArgOffset += RegSize) {
3605 unsigned Reg =
addLiveIn(MF, ArgRegs[I], RC);
3611 cast<StoreSDNode>(Store.
getNode())->getMemOperand()->setValue(0);
3612 OutChains.push_back(Store);
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
bool isInt< 32 >(int64_t x)
void setFrameAddressIsTaken(bool T)
unsigned getStackAlignment() const
static SDValue lowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG, bool HasExtractInsert)
static MVT getIntegerVT(unsigned BitWidth)
void push_back(const T &Elt)
const MachineFunction * getParent() const
SDValue getConstant(uint64_t Val, EVT VT, bool isTarget=false)
SDValue getValue(unsigned R) const
SDValue getAddrGlobal(NodeTy *N, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
const char * getSymbol() const
virtual void getOpndList(SmallVectorImpl< SDValue > &Ops, std::deque< std::pair< unsigned, SDValue > > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const
LLVMContext * getContext() const
LLVM Argument representation.
SDValue getCopyToReg(SDValue Chain, SDLoc dl, unsigned Reg, SDValue N)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, SDLoc DL)
bool hasSEInReg() const
Features related to the presence of specific instructions.
Reloc::Model getRelocationModel() const
LocInfo getLocInfo() const
static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG, bool IsLittle)
MO_TLSLDM - Represents the offset into the global offset table at which.
const uint16_t * intArgRegs() const
Return pointer to array of integer argument registers.
static MachinePointerInfo getJumpTable()
static const uint16_t Mips64IntRegs[8]
const TargetMachine & getTargetMachine() const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
void addLiveIn(unsigned Reg, unsigned vreg=0)
MO_GOT_HI16/LO16, MO_CALL_HI16/LO16 - Relocations used for large GOTs.
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
MipsTargetLowering(MipsTargetMachine &TM)
virtual const uint32_t * getCallPreservedMask(CallingConv::ID) const
MO_TLSGD - Represents the offset into the global offset table at which.
unsigned addLiveIn(unsigned PReg, const TargetRegisterClass *RC)
virtual ConstraintType getConstraintType(const std::string &Constraint) const
Given a constraint, return the type of constraint it is for this target.
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
const GlobalValue * getGlobal() const
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static SDValue lowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG, bool HasExtractInsert)
unsigned getOpcode() const
unsigned getSizeInBits() const
unsigned getByValSize() const
Type * getReturnType() const
void setBooleanVectorContents(BooleanContent Ty)
unsigned getValueSizeInBits() const
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB)
const SDValue & getOperand(unsigned Num) const
const Function * getFunction() const
void setVarArgsFrameIndex(int Index)
ByValArgInfo - Byval argument information.
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags=0)
StringSwitch & Case(const char(&S)[N], const T &Value)
const SDValue & getBasePtr() const
static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget *Subtarget)
EVT getSetCCResultType(LLVMContext &Context, EVT VT) const
getSetCCResultType - get the ISD::SETCC result ValueType
void analyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, bool IsSoftFloat, const SDNode *CallNode, const Type *RetTy) const
SDValue getExternalSymbol(const char *Sym, EVT VT)
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
virtual void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const
APInt Not(const APInt &APIVal)
Bitwise complement function.
static bool isShiftedMask(uint64_t I, uint64_t &Pos, uint64_t &Size)
SDValue getLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, bool isInvariant, unsigned Alignment, const MDNode *TBAAInfo=0, const MDNode *Ranges=0)
bool isVector() const
isVector - Return true if this is a vector value type.
virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const
static error_code advance(T &it, size_t Val)
static unsigned getBitWidth(Type *Ty, const DataLayout *TD)
std::string getEVTString() const
getEVTString - This function returns value type as a string, e.g. "i32".
SDValue getStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, unsigned Alignment, const MDNode *TBAAInfo=0)
const HexagonInstrInfo * TII
static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG)
static unsigned addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC)
#define llvm_unreachable(msg)
EVT getValueType(unsigned ResNo) const
const TargetRegisterClass * getRegClass(unsigned i) const
unsigned getSRetReturnReg() const
bool hasInternalLinkage() const
MachineFunction & getMachineFunction() const
SDValue getTargetGlobalAddress(const GlobalValue *GV, SDLoc DL, EVT VT, int64_t offset=0, unsigned char TargetFlags=0)
void addLoc(const CCValAssign &V)
SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const
Abstract Stack Frame Information.
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
SDVTList getVTList(EVT VT)
bool hasExtractInsert() const
virtual MVT getPointerTy(uint32_t=0) const
ID
LLVM Calling Convention Representation.
virtual const MipsSubtarget * getSubtargetImpl() const
bool inMips16HardFloat() const
static Mips::CondCode condCodeToFCC(ISD::CondCode CC)
const MachineInstrBuilder & addImm(int64_t Val) const
bool isInteger() const
isInteger - Return true if this is an integer, or a vector integer type.
SmallVector< ISD::InputArg, 32 > Ins
unsigned numIntArgRegs() const
numIntArgRegs - Number of integer registers available for calls.
SDValue getCALLSEQ_START(SDValue Chain, SDValue Op, SDLoc DL)
unsigned getLocReg() const
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
size_t array_lengthof(T(&)[N])
Find the length of an array.
unsigned getNumValues() const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
SDValue getRegisterMask(const uint32_t *RegMask)
bool hasStructRetAttr() const
Determine if the function returns a structure through first pointer argument.
static bool invertFPCondCodeUser(Mips::CondCode CC)
enable_if_c< std::numeric_limits< T >::is_integer &&!std::numeric_limits< T >::is_signed, std::size_t >::type countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
Simple integer binary arithmetic operators.
SmallVector< ISD::OutputArg, 32 > Outs
const MachineJumpTableInfo * getJumpTableInfo() const
const SDValue & getBasePtr() const
SDValue getUNDEF(EVT VT)
getUNDEF - Return an UNDEF node. UNDEF does not have a useful SDLoc.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const
EVT getMemoryVT() const
getMemoryVT - Return the type of the in-memory value.
SDValue getAddrGlobalLargeGOT(NodeTy *N, EVT Ty, SelectionDAG &DAG, unsigned HiFlag, unsigned LoFlag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
unsigned getKillRegState(bool B)
const BasicBlock * getBasicBlock() const
static unsigned getNextIntArgReg(unsigned Reg)
static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget *Subtarget)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
const TargetLoweringObjectFile & getObjFileLowering() const
virtual const char * getTargetNodeName(unsigned Opcode) const
getTargetNodeName - This method returns the name of a target specific
SDNode * getNode() const
get the SDNode which holds the desired result
unsigned getEntrySize(const DataLayout &TD) const
getEntrySize - Return the size of each entry in the jump table.
bundle_iterator< MachineInstr, instr_iterator > iterator
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
A switch()-like statement whose cases are string literals.
initializer< Ty > init(const Ty &Val)
static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG, bool HasExtractInsert)
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=0)
static const uint16_t O32IntRegs[4]
LLVM Basic Block Representation.
void analyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, bool IsSoftFloat, const Type *RetTy) const
const SDValue & getOperand(unsigned i) const
void setTargetDAGCombine(ISD::NodeType NT)
bool isNonTemporal() const
const Constant * getConstVal() const
bool isFloatingPoint() const
isFloatingPoint - Return true if this is a FP, or a vector FP type.
const MachineOperand & getOperand(unsigned i) const
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const
LowerOperation - Provide custom lowering hooks for some operations.
char back() const
back - Get the last character in the string.
bool isBeforeLegalizeOps() const
static SDValue createStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD, SDValue Chain, unsigned Offset)
bool isFloatTy() const
isFloatTy - Return true if this is 'float', a 32-bit IEEE fp type.
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
void setBooleanContents(BooleanContent Ty)
static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State, const uint16_t *F64Regs)
bool mipsSEUsesSoftFloat() const
ItTy next(ItTy it, Dist n)
SDValue getCopyFromReg(SDValue Chain, SDLoc dl, unsigned Reg, EVT VT)
const DataLayout * getDataLayout() const
static EVT getFloatingPointVT(unsigned BitWidth)
unsigned getOpcode() const
TRAP - Trapping instruction.
const MipsSubtarget * Subtarget
static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget *Subtarget)
Integer representation type.
const SDValue & getValue() const
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
bool inMips16Mode() const
Bit counting operators with an undefined result for zero inputs.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
SDValue getAddrNonPIC(NodeTy *N, EVT Ty, SelectionDAG &DAG) const
unsigned CountPopulation_64(uint64_t Value)
static std::pair< bool, bool > parsePhysicalReg(const StringRef &C, std::string &Prefix, unsigned long long &Reg)
virtual const TargetFrameLowering * getFrameLowering() const
bool isFP128Ty() const
isFP128Ty - Return true if this is 'fp128'.
std::vector< ArgListEntry > ArgListTy
STATISTIC(NumTailCalls,"Number of tail calls")
unsigned getNextStackOffset() const
unsigned getFirstUnallocated(const uint16_t *Regs, unsigned NumRegs) const
virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const
static SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG, bool HasExtractInsert)
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
MO_GOTTPREL - Represents the offset from the thread pointer (Initial.
const MCInstrDesc & get(unsigned Opcode) const
const BlockAddress * getBlockAddress() const
bool isShiftedMask_64(uint64_t Value)
const MipsTargetLowering * createMipsSETargetLowering(MipsTargetMachine &TM)
const MachinePointerInfo & getPointerInfo() const
void setIsKill(bool Val=true)
SDValue getMemcpy(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool AlwaysInline, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
unsigned getByValAlign() const
void setLoadExtAction(unsigned ExtType, MVT VT, LegalizeAction Action)
static SDValue createLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD, SDValue Chain, SDValue Src, unsigned Offset)
SDValue getTargetConstantPool(const Constant *C, EVT VT, unsigned Align=0, int Offset=0, unsigned char TargetFlags=0)
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags=0)
virtual const TargetInstrInfo * getInstrInfo() const
const char * const_iterator
virtual unsigned getJumpTableEncoding() const
MipsCC(CallingConv::ID CallConv, bool IsO32, bool IsFP64, CCState &Info, SpecialCallingConvType SpecialCallingConv=NoSpecialCallingConv)
unsigned getGlobalBaseReg()
void setExceptionPointerRegister(unsigned R)
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const
SDValue getExtLoad(ISD::LoadExtType ExtType, SDLoc dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, bool isVolatile, bool isNonTemporal, unsigned Alignment, const MDNode *TBAAInfo=0)
CCValAssign - Represent assignment of one arg/retval to a location.
static cl::opt< bool > NoZeroDivCheck("mno-check-zero-division", cl::Hidden, cl::desc("MIPS: Don't trap on integer division by zero."), cl::init(false))
SDValue getIntPtrConstant(uint64_t Val, bool isTarget=false)
const SDValue & getChain() const
void analyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, bool IsSoftFloat, Function::const_arg_iterator FuncArg)
Byte Swap and Counting operators.
MachineMemOperand * getMemOperand() const
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
MachineFrameInfo * getFrameInfo()
CondCode getSetCCInverse(CondCode Operation, bool isInteger)
R Default(const T &Value) const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
ISD::LoadExtType getExtensionType() const
SDValue getMemIntrinsicNode(unsigned Opcode, SDLoc dl, const EVT *VTs, unsigned NumVTs, const SDValue *Ops, unsigned NumOps, EVT MemVT, MachinePointerInfo PtrInfo, unsigned Align=0, bool Vol=false, bool ReadMem=true, bool WriteMem=true)
void setExceptionSelectorRegister(unsigned R)
void setMinFunctionAlignment(unsigned Align)
Set the target's minimum function alignment (in log2(bytes))
int64_t getSExtValue() const
virtual const TargetRegisterClass * getRegClassFor(MVT VT) const
ZERO_EXTEND - Used for integer types, zeroing the new bits.
AddrMode
ARM Addressing Modes.
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT)
ANY_EXTEND - Used for integer types. The high bits are undefined.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op)
MO_TPREL_HI/LO - Represents the hi and low part of the offset from.
unsigned reservedArgArea() const
static MachinePointerInfo getGOT()
static const uint32_t * getMips16RetHelperMask()
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned char TargetFlags=0)
SmallVector< SDValue, 32 > OutVals
void setFormalArgInfo(unsigned Size, bool HasByval)
Bitwise operators - logical and, logical or, logical xor.
static bool originalTypeIsF128(const Type *Ty, const SDNode *CallNode)
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const
bool hasAnyUseOfValue(unsigned Value) const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
MachineRegisterInfo & getRegInfo()
static cl::opt< bool > LargeGOT("mxgot", cl::Hidden, cl::desc("MIPS: Enable GOT larger than 64k."), cl::init(false))
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
SmallVectorImpl< ByValArgInfo >::const_iterator byval_iterator
bool isSingleFloat() const
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget *Subtarget)
bool IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM, SectionKind Kind) const
void setSubReg(unsigned subReg)
void setStackPointerRegisterToSaveRestore(unsigned R)
const TargetMachine & getTarget() const
static const MipsTargetLowering * create(MipsTargetMachine &TM)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
virtual const TargetRegisterInfo * getRegisterInfo() const
FSINCOS - Compute both fsin and fcos as a single operation.
bool isInt< 16 >(int64_t x)
unsigned MaxStoresPerMemcpy
Specify maximum bytes of store instructions per memcpy call.
void analyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, bool IsVarArg, bool IsSoftFloat, const SDNode *CallNode, std::vector< ArgListEntry > &FuncArgs)
static SDValue performORCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget *Subtarget)
int getVarArgsFrameIndex() const
MachinePointerInfo callPtrInfo(const StringRef &Name)
Create a MachinePointerInfo that has a MipsCallEntr object representing a GOT entry for an external f...
TLSModel::Model getTLSModel(const GlobalValue *GV) const
unsigned getReg() const
getReg - Returns the register number.
bool isFloatingPoint() const
isFloatingPoint - Return true if this is a FP, or a vector FP type.
char front() const
front - Get the first character in the string.
void insert(iterator MBBI, MachineBasicBlock *MBB)
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
void setReturnAddressIsTaken(bool s)
unsigned getAlignment() const
LLVM Value Representation.
SDValue getRegister(unsigned Reg, EVT VT)
bool isZero() const
Returns true if and only if the float is plus or minus zero.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
void setInsertFencesForAtomic(bool fence)
bool isTruncatingStore() const
SDValue getValueType(EVT)
bool isUInt< 16 >(uint64_t x)
BasicBlockListType::iterator iterator
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
const MipsTargetLowering * createMips16TargetLowering(MipsTargetMachine &TM)
Create MipsTargetLowering objects.
SDValue getMergeValues(const SDValue *Ops, unsigned NumOps, SDLoc dl)
getMergeValues - Create a MERGE_VALUES node from the given operands.
unsigned getOrigAlign() const
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
SDValue getTargetConstant(uint64_t Val, EVT VT)
SDValue getSetCC(SDLoc DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond)
unsigned getLocMemOffset() const
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue getEntryNode() const
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable)
static bool isF128SoftLibCall(const char *CallSym)
This function returns true if CallSym is a long double emulation routine.
TRUNCATE - Completely drop the high bits.
unsigned getAlignment() const
unsigned AllocateReg(unsigned Reg)
SDValue getAddrLocal(NodeTy *N, EVT Ty, SelectionDAG &DAG, bool HasMips64) const
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True, SDValue False, SDLoc DL)
static const uint16_t Mips64DPRegs[8]
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
unsigned AllocateStack(unsigned Size, unsigned Align)
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
EVT changeVectorElementTypeToInteger() const
static MachineBasicBlock * expandPseudoDIV(MachineInstr *MI, MachineBasicBlock &MBB, const TargetInstrInfo &TII, bool Is64Bit)
DebugLoc getDebugLoc() const
void setSRetReturnReg(unsigned Reg)
uint64_t getZExtValue() const