178 if (!
Subtarget.supportsMultiplication()) {
283 EVT VT =
Op.getValueType();
286 "Expected power-of-2 shift amount");
289 if (!isa<ConstantSDNode>(
N->getOperand(1))) {
294 SDVTList ResTys = DAG.
getVTList(MVT::i16, MVT::i16);
301 uint64_t ShiftAmount =
N->getConstantOperandVal(1);
302 if (ShiftAmount == 16) {
307 switch (
Op.getOpcode()) {
320 switch (
Op.getOpcode()) {
333 SDValue
Result = DAG.
getNode(Opc, dl, ResTys, SrcLo, SrcHi, Cnt);
339 if (!isa<ConstantSDNode>(
N->getOperand(1))) {
340 switch (
Op.getOpcode()) {
350 SDValue Amt =
N->getOperand(1);
351 EVT AmtVT = Amt.getValueType();
357 SDValue Amt =
N->getOperand(1);
358 EVT AmtVT = Amt.getValueType();
369 uint64_t ShiftAmount =
N->getConstantOperandVal(1);
370 SDValue Victim =
N->getOperand(0);
372 switch (
Op.getOpcode()) {
396 if (
Op.getOpcode() ==
ISD::SHL && 4 <= ShiftAmount && ShiftAmount < 7) {
402 }
else if (
Op.getOpcode() ==
ISD::SRL && 4 <= ShiftAmount &&
409 }
else if (
Op.getOpcode() ==
ISD::SHL && ShiftAmount == 7) {
414 }
else if (
Op.getOpcode() ==
ISD::SRL && ShiftAmount == 7) {
419 }
else if (
Op.getOpcode() ==
ISD::SRA && ShiftAmount == 6) {
424 }
else if (
Op.getOpcode() ==
ISD::SRA && ShiftAmount == 7) {
429 }
else if (
Op.getOpcode() ==
ISD::ROTL && ShiftAmount == 3) {
435 }
else if (
Op.getOpcode() ==
ISD::ROTR && ShiftAmount == 3) {
441 }
else if (
Op.getOpcode() ==
ISD::ROTL && ShiftAmount == 7) {
446 }
else if (
Op.getOpcode() ==
ISD::ROTR && ShiftAmount == 7) {
460 switch (ShiftAmount) {
479 if (4 <= ShiftAmount && ShiftAmount < 8)
480 switch (
Op.getOpcode()) {
494 else if (8 <= ShiftAmount && ShiftAmount < 12)
495 switch (
Op.getOpcode()) {
520 else if (12 <= ShiftAmount)
521 switch (
Op.getOpcode()) {
548 while (ShiftAmount--) {
549 Victim = DAG.
getNode(Opc8, dl, VT, Victim);
555SDValue AVRTargetLowering::LowerDivRem(SDValue
Op, SelectionDAG &DAG)
const {
556 unsigned Opcode =
Op->getOpcode();
558 "Invalid opcode for Div/Rem lowering");
560 EVT VT =
Op->getValueType(0);
561 Type *Ty = VT.getTypeForEVT(*DAG.getContext());
564 switch (VT.getSimpleVT().SimpleTy) {
568 LC = IsSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
571 LC = IsSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
574 LC = IsSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
578 SDValue InChain = DAG.getEntryNode();
581 TargetLowering::ArgListEntry Entry;
582 for (SDValue
const &Value :
Op->op_values()) {
584 Entry.Ty =
Value.getValueType().getTypeForEVT(*DAG.getContext());
585 Entry.IsSExt = IsSigned;
586 Entry.IsZExt = !IsSigned;
587 Args.push_back(Entry);
596 TargetLowering::CallLoweringInfo CLI(DAG);
601 .setSExtResult(IsSigned)
602 .setZExtResult(!IsSigned);
604 std::pair<SDValue, SDValue> CallInfo =
LowerCallTo(CLI);
605 return CallInfo.first;
608SDValue AVRTargetLowering::LowerGlobalAddress(SDValue
Op,
609 SelectionDAG &DAG)
const {
610 auto DL = DAG.getDataLayout();
612 const GlobalValue *GV = cast<GlobalAddressSDNode>(
Op)->getGlobal();
613 int64_t
Offset = cast<GlobalAddressSDNode>(
Op)->getOffset();
621SDValue AVRTargetLowering::LowerBlockAddress(SDValue
Op,
622 SelectionDAG &DAG)
const {
623 auto DL = DAG.getDataLayout();
624 const BlockAddress *BA = cast<BlockAddressSDNode>(
Op)->getBlockAddress();
652SDValue AVRTargetLowering::getAVRCmp(SDValue
LHS, SDValue
RHS,
653 SelectionDAG &DAG, SDLoc
DL)
const {
654 assert((
LHS.getSimpleValueType() ==
RHS.getSimpleValueType()) &&
655 "LHS and RHS have different types");
656 assert(((
LHS.getSimpleValueType() == MVT::i16) ||
657 (
LHS.getSimpleValueType() == MVT::i8)) &&
658 "invalid comparison type");
662 if (
LHS.getSimpleValueType() == MVT::i16 && isa<ConstantSDNode>(
RHS)) {
667 DAG.getIntPtrConstant(0,
DL));
669 DAG.getIntPtrConstant(1,
DL));
670 SDValue RHSlo = (Imm & 0xff) == 0
673 DAG.getIntPtrConstant(0,
DL));
674 SDValue RHShi = (Imm & 0xff00) == 0
677 DAG.getIntPtrConstant(1,
DL));
679 Cmp = DAG.getNode(
AVRISD::CMPC,
DL, MVT::Glue, LHShi, RHShi, Cmp);
680 }
else if (
RHS.getSimpleValueType() == MVT::i16 && isa<ConstantSDNode>(
LHS)) {
684 SDValue LHSlo = (
Imm & 0xff) == 0
687 DAG.getIntPtrConstant(0,
DL));
688 SDValue LHShi = (
Imm & 0xff00) == 0
691 DAG.getIntPtrConstant(1,
DL));
693 DAG.getIntPtrConstant(0,
DL));
695 DAG.getIntPtrConstant(1,
DL));
709 SDValue &AVRcc, SelectionDAG &DAG,
712 EVT VT =
LHS.getValueType();
713 bool UseTest =
false;
725 if (
const ConstantSDNode *
C = dyn_cast<ConstantSDNode>(
RHS)) {
726 switch (
C->getSExtValue()) {
738 LHS = DAG.getConstant(0,
DL, VT);
745 RHS = DAG.getConstant(
C->getSExtValue() + 1,
DL, VT);
758 if (
const ConstantSDNode *
C = dyn_cast<ConstantSDNode>(
RHS)) {
759 switch (
C->getSExtValue()) {
764 LHS = DAG.getConstant(0,
DL, VT);
788 if (
const ConstantSDNode *
C = dyn_cast<ConstantSDNode>(
RHS)) {
789 RHS = DAG.getConstant(
C->getSExtValue() + 1,
DL, VT);
802 if (VT == MVT::i32) {
804 DAG.getIntPtrConstant(0,
DL));
806 DAG.getIntPtrConstant(1,
DL));
808 DAG.getIntPtrConstant(0,
DL));
810 DAG.getIntPtrConstant(1,
DL));
815 DAG.getIntPtrConstant(1,
DL));
818 Cmp = getAVRCmp(LHSlo, RHSlo, DAG,
DL);
821 }
else if (VT == MVT::i64) {
823 DAG.getIntPtrConstant(0,
DL));
825 DAG.getIntPtrConstant(1,
DL));
828 DAG.getIntPtrConstant(0,
DL));
830 DAG.getIntPtrConstant(1,
DL));
832 DAG.getIntPtrConstant(0,
DL));
834 DAG.getIntPtrConstant(1,
DL));
837 DAG.getIntPtrConstant(0,
DL));
839 DAG.getIntPtrConstant(1,
DL));
842 DAG.getIntPtrConstant(0,
DL));
844 DAG.getIntPtrConstant(1,
DL));
846 DAG.getIntPtrConstant(0,
DL));
848 DAG.getIntPtrConstant(1,
DL));
853 DAG.getIntPtrConstant(1,
DL));
856 Cmp = getAVRCmp(LHS0, RHS0, DAG,
DL);
861 }
else if (VT == MVT::i8 || VT == MVT::i16) {
868 LHS, DAG.getIntPtrConstant(1,
DL)));
884SDValue AVRTargetLowering::LowerBR_CC(SDValue
Op, SelectionDAG &DAG)
const {
885 SDValue Chain =
Op.getOperand(0);
887 SDValue
LHS =
Op.getOperand(2);
888 SDValue
RHS =
Op.getOperand(3);
889 SDValue Dest =
Op.getOperand(4);
893 SDValue
Cmp = getAVRCmp(
LHS,
RHS,
CC, TargetCC, DAG, dl);
895 return DAG.getNode(
AVRISD::BRCOND, dl, MVT::Other, Chain, Dest, TargetCC,
899SDValue AVRTargetLowering::LowerSELECT_CC(SDValue
Op, SelectionDAG &DAG)
const {
900 SDValue
LHS =
Op.getOperand(0);
901 SDValue
RHS =
Op.getOperand(1);
902 SDValue TrueV =
Op.getOperand(2);
903 SDValue FalseV =
Op.getOperand(3);
908 SDValue
Cmp = getAVRCmp(
LHS,
RHS,
CC, TargetCC, DAG, dl);
910 SDVTList VTs = DAG.getVTList(
Op.getValueType(), MVT::Glue);
911 SDValue Ops[] = {TrueV, FalseV, TargetCC,
Cmp};
916SDValue AVRTargetLowering::LowerSETCC(SDValue
Op, SelectionDAG &DAG)
const {
917 SDValue
LHS =
Op.getOperand(0);
918 SDValue
RHS =
Op.getOperand(1);
925 SDValue TrueV = DAG.getConstant(1,
DL,
Op.getValueType());
926 SDValue FalseV = DAG.getConstant(0,
DL,
Op.getValueType());
927 SDVTList VTs = DAG.getVTList(
Op.getValueType(), MVT::Glue);
928 SDValue Ops[] = {TrueV, FalseV, TargetCC,
Cmp};
933SDValue AVRTargetLowering::LowerVASTART(SDValue
Op, SelectionDAG &DAG)
const {
934 const MachineFunction &MF = DAG.getMachineFunction();
935 const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
936 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
937 auto DL = DAG.getDataLayout();
942 SDValue FI = DAG.getFrameIndex(AFI->getVarArgsFrameIndex(),
getPointerTy(
DL));
944 return DAG.getStore(
Op.getOperand(0), dl, FI,
Op.getOperand(1),
945 MachinePointerInfo(SV));
949SDValue AVRTargetLowering::LowerINLINEASM(SDValue
Op, SelectionDAG &DAG)
const {
965 SmallVector<SDValue, 8> Ops;
966 SDNode *
N =
Op.getNode();
968 for (
unsigned I = 0;
I <
N->getNumOperands();
I++) {
969 SDValue Operand =
N->getOperand(
I);
970 if (Operand.getValueType() == MVT::Glue) {
975 Ops.push_back(Operand);
979 Ops.push_back(DAG.getTargetConstant(Flags, dl, MVT::i32));
980 Ops.push_back(ZeroReg);
987 SDValue
New = DAG.getNode(
N->getOpcode(), dl,
N->getVTList(), Ops);
988 DAG.ReplaceAllUsesOfValueWith(
Op, New);
989 DAG.ReplaceAllUsesOfValueWith(
Op.getValue(1),
New.getValue(1));
995 switch (
Op.getOpcode()) {
1003 return LowerShifts(
Op, DAG);
1005 return LowerGlobalAddress(
Op, DAG);
1007 return LowerBlockAddress(
Op, DAG);
1009 return LowerBR_CC(
Op, DAG);
1011 return LowerSELECT_CC(
Op, DAG);
1013 return LowerSETCC(
Op, DAG);
1015 return LowerVASTART(
Op, DAG);
1018 return LowerDivRem(
Op, DAG);
1020 return LowerINLINEASM(
Op, DAG);
1033 switch (
N->getOpcode()) {
1036 if (
const ConstantSDNode *
C = dyn_cast<ConstantSDNode>(
N->getOperand(1))) {
1095 if (
const LoadSDNode *LD = dyn_cast<LoadSDNode>(
N)) {
1096 VT = LD->getMemoryVT();
1097 Op = LD->getBasePtr().getNode();
1103 }
else if (
const StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
1104 VT = ST->getMemoryVT();
1105 Op = ST->getBasePtr().getNode();
1113 if (VT != MVT::i8 && VT != MVT::i16) {
1122 int RHSC =
RHS->getSExtValue();
1126 if ((VT == MVT::i16 && RHSC != -2) || (VT == MVT::i8 && RHSC != -1)) {
1130 Base =
Op->getOperand(0);
1151 if (
const LoadSDNode *LD = dyn_cast<LoadSDNode>(
N)) {
1152 VT = LD->getMemoryVT();
1155 }
else if (
const StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
1156 VT = ST->getMemoryVT();
1164 if (VT == MVT::i16 && !
Subtarget.hasLowByteFirst())
1170 if (VT != MVT::i8 && VT != MVT::i16) {
1179 int RHSC =
RHS->getSExtValue();
1182 if ((VT == MVT::i16 && RHSC != 2) || (VT == MVT::i8 && RHSC != 1)) {
1188 if (
const LoadSDNode *LD = dyn_cast<LoadSDNode>(
N))
1192 Base =
Op->getOperand(0);
1211#include "AVRGenCallingConv.inc"
1216 AVR::R25, AVR::R24, AVR::R23, AVR::R22, AVR::R21, AVR::R20,
1217 AVR::R19, AVR::R18, AVR::R17, AVR::R16, AVR::R15, AVR::R14,
1218 AVR::R13, AVR::R12, AVR::R11, AVR::R10, AVR::R9, AVR::R8};
1220 AVR::R22, AVR::R21, AVR::R20};
1222 AVR::R26R25, AVR::R25R24, AVR::R24R23, AVR::R23R22, AVR::R22R21,
1223 AVR::R21R20, AVR::R20R19, AVR::R19R18, AVR::R18R17, AVR::R17R16,
1224 AVR::R16R15, AVR::R15R14, AVR::R14R13, AVR::R13R12, AVR::R12R11,
1225 AVR::R11R10, AVR::R10R9, AVR::R9R8};
1227 AVR::R24R23, AVR::R23R22,
1228 AVR::R22R21, AVR::R21R20};
1231 "8-bit and 16-bit register arrays must be of equal length");
1233 "8-bit and 16-bit register arrays must be of equal length");
1239template <
typename ArgT>
1256 unsigned NumArgs = Args.size();
1259 int RegLastIdx = -1;
1261 bool UseStack =
false;
1262 for (
unsigned i = 0; i != NumArgs;) {
1263 MVT VT = Args[i].VT;
1268 unsigned ArgIndex = Args[i].OrigArgIndex;
1271 for (; j != NumArgs; ++j) {
1272 if (Args[j].OrigArgIndex != ArgIndex)
1274 TotalBytes += Args[j].VT.getStoreSize();
1277 TotalBytes =
alignTo(TotalBytes, 2);
1279 if (TotalBytes == 0)
1282 unsigned RegIdx = RegLastIdx + TotalBytes;
1283 RegLastIdx = RegIdx;
1285 if (RegIdx >= RegList8.
size()) {
1288 for (; i != j; ++i) {
1289 MVT VT = Args[i].VT;
1299 if (VT == MVT::i8) {
1301 }
else if (VT == MVT::i16) {
1305 "calling convention can only manage i8 and i16 types");
1307 assert(
Reg &&
"register not available in calling convention");
1318template <
typename ArgT>
1321 unsigned TotalBytes = 0;
1323 for (
const ArgT &Arg : Args) {
1324 TotalBytes += Arg.VT.getStoreSize();
1332template <
typename ArgT>
1335 unsigned NumArgs = Args.size();
1339 assert(TotalBytes <= 4 &&
1340 "return values greater than 4 bytes cannot be lowered on AVRTiny");
1342 assert(TotalBytes <= 8 &&
1343 "return values greater than 8 bytes cannot be lowered on AVR");
1358 if (TotalBytes > 4) {
1361 TotalBytes =
alignTo(TotalBytes, 2);
1365 int RegIdx = TotalBytes - 1;
1366 for (
unsigned i = 0; i != NumArgs; ++i) {
1367 MVT VT = Args[i].VT;
1369 if (VT == MVT::i8) {
1371 }
else if (VT == MVT::i16) {
1376 assert(
Reg &&
"register not available in calling convention");
1383SDValue AVRTargetLowering::LowerFormalArguments(
1385 const SmallVectorImpl<ISD::InputArg> &Ins,
const SDLoc &dl,
1386 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals)
const {
1387 MachineFunction &MF = DAG.getMachineFunction();
1388 MachineFrameInfo &MFI = MF.getFrameInfo();
1389 auto DL = DAG.getDataLayout();
1392 SmallVector<CCValAssign, 16> ArgLocs;
1393 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
1398 CCInfo.AnalyzeFormalArguments(Ins, ArgCC_AVR_Vararg);
1405 for (CCValAssign &VA : ArgLocs) {
1408 if (VA.isRegLoc()) {
1409 EVT RegVT = VA.getLocVT();
1410 const TargetRegisterClass *RC;
1411 if (RegVT == MVT::i8) {
1412 RC = &AVR::GPR8RegClass;
1413 }
else if (RegVT == MVT::i16) {
1414 RC = &AVR::DREGSRegClass;
1420 ArgValue = DAG.getCopyFromReg(Chain, dl,
Reg, RegVT);
1428 switch (VA.getLocInfo()) {
1434 ArgValue = DAG.getNode(
ISD::BITCAST, dl, VA.getValVT(), ArgValue);
1438 DAG.getValueType(VA.getValVT()));
1439 ArgValue = DAG.getNode(
ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
1443 DAG.getValueType(VA.getValVT()));
1444 ArgValue = DAG.getNode(
ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
1448 InVals.push_back(ArgValue);
1453 EVT LocVT = VA.getLocVT();
1456 int FI = MFI.CreateFixedObject(LocVT.getSizeInBits() / 8,
1457 VA.getLocMemOffset(),
true);
1462 InVals.push_back(DAG.getLoad(LocVT, dl, Chain, FIN,
1470 unsigned StackSize = CCInfo.getStackSize();
1471 AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
1473 AFI->setVarArgsFrameIndex(MFI.CreateFixedObject(2, StackSize,
true));
1483SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
1484 SmallVectorImpl<SDValue> &InVals)
const {
1485 SelectionDAG &DAG = CLI.DAG;
1487 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
1488 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
1489 SmallVectorImpl<ISD::InputArg> &
Ins = CLI.Ins;
1490 SDValue Chain = CLI.Chain;
1491 SDValue
Callee = CLI.Callee;
1492 bool &isTailCall = CLI.IsTailCall;
1494 bool isVarArg = CLI.IsVarArg;
1496 MachineFunction &MF = DAG.getMachineFunction();
1502 SmallVector<CCValAssign, 16> ArgLocs;
1503 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
1510 if (
const GlobalAddressSDNode *
G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1511 const GlobalValue *GV =
G->getGlobal();
1512 if (isa<Function>(GV))
1513 F = cast<Function>(GV);
1515 DAG.getTargetGlobalAddress(GV,
DL,
getPointerTy(DAG.getDataLayout()));
1516 }
else if (
const ExternalSymbolSDNode *ES =
1517 dyn_cast<ExternalSymbolSDNode>(Callee)) {
1518 Callee = DAG.getTargetExternalSymbol(ES->getSymbol(),
1524 CCInfo.AnalyzeCallOperands(Outs, ArgCC_AVR_Vararg);
1531 unsigned NumBytes = CCInfo.getStackSize();
1533 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0,
DL);
1535 SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
1539 bool HasStackArgs =
false;
1540 for (AI = 0, AE = ArgLocs.size(); AI != AE; ++AI) {
1541 CCValAssign &VA = ArgLocs[AI];
1542 EVT RegVT = VA.getLocVT();
1543 SDValue Arg = OutVals[AI];
1546 switch (VA.getLocInfo()) {
1567 if (VA.isMemLoc()) {
1568 HasStackArgs =
true;
1574 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
1584 SmallVector<SDValue, 8> MemOpChains;
1585 for (; AI != AE; AI++) {
1586 CCValAssign &VA = ArgLocs[AI];
1587 SDValue Arg = OutVals[AI];
1592 SDValue PtrOff = DAG.getNode(
1594 DAG.getRegister(AVR::SP,
getPointerTy(DAG.getDataLayout())),
1595 DAG.getIntPtrConstant(VA.getLocMemOffset() + 1,
DL));
1597 MemOpChains.push_back(
1598 DAG.getStore(Chain,
DL, Arg, PtrOff,
1602 if (!MemOpChains.empty())
1610 for (
auto Reg : RegsToPass) {
1611 Chain = DAG.getCopyToReg(Chain,
DL,
Reg.first,
Reg.second, InGlue);
1612 InGlue = Chain.getValue(1);
1616 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1617 SmallVector<SDValue, 8> Ops;
1618 Ops.push_back(Chain);
1619 Ops.push_back(Callee);
1623 for (
auto Reg : RegsToPass) {
1624 Ops.push_back(DAG.getRegister(
Reg.first,
Reg.second.getValueType()));
1634 TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);
1635 assert(Mask &&
"Missing call preserved mask for calling convention");
1636 Ops.push_back(DAG.getRegisterMask(Mask));
1638 if (InGlue.getNode()) {
1639 Ops.push_back(InGlue);
1643 InGlue = Chain.getValue(1);
1646 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue,
DL);
1649 InGlue = Chain.getValue(1);
1654 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins,
DL, DAG,
1661SDValue AVRTargetLowering::LowerCallResult(
1662 SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv,
bool isVarArg,
1663 const SmallVectorImpl<ISD::InputArg> &Ins,
const SDLoc &dl,
1664 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals)
const {
1667 SmallVector<CCValAssign, 16> RVLocs;
1668 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
1673 CCInfo.AnalyzeCallResult(Ins, RetCC_AVR_BUILTIN);
1679 for (CCValAssign
const &RVLoc : RVLocs) {
1680 Chain = DAG.getCopyFromReg(Chain, dl, RVLoc.getLocReg(), RVLoc.getValVT(),
1683 InGlue = Chain.getValue(2);
1684 InVals.push_back(Chain.getValue(0));
1694bool AVRTargetLowering::CanLowerReturn(
1696 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context)
const {
1698 SmallVector<CCValAssign, 16> RVLocs;
1699 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
1700 return CCInfo.CheckReturn(Outs, RetCC_AVR_BUILTIN);
1708AVRTargetLowering::LowerReturn(SDValue Chain,
CallingConv::ID CallConv,
1710 const SmallVectorImpl<ISD::OutputArg> &Outs,
1711 const SmallVectorImpl<SDValue> &OutVals,
1712 const SDLoc &dl, SelectionDAG &DAG)
const {
1714 SmallVector<CCValAssign, 16> RVLocs;
1717 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
1720 MachineFunction &MF = DAG.getMachineFunction();
1724 CCInfo.AnalyzeReturn(Outs, RetCC_AVR_BUILTIN);
1730 SmallVector<SDValue, 4> RetOps(1, Chain);
1732 for (
unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
1733 CCValAssign &VA = RVLocs[i];
1734 assert(VA.isRegLoc() &&
"Can only return in registers!");
1736 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Glue);
1739 Glue = Chain.getValue(1);
1740 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
1745 if (MF.getFunction().getAttributes().hasFnAttr(Attribute::Naked)) {
1749 const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
1751 if (!AFI->isInterruptOrSignalHandler()) {
1764 if (Glue.getNode()) {
1765 RetOps.push_back(Glue);
1768 return DAG.getNode(RetOpc, dl, MVT::Other, RetOps);
1775MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &
MI,
1776 MachineBasicBlock *BB,
1779 const TargetRegisterClass *RC;
1780 bool HasRepeatedOperand =
false;
1781 MachineFunction *
F = BB->getParent();
1782 MachineRegisterInfo &RI =
F->getRegInfo();
1786 switch (
MI.getOpcode()) {
1791 RC = &AVR::GPR8RegClass;
1792 HasRepeatedOperand =
true;
1796 RC = &AVR::DREGSRegClass;
1800 RC = &AVR::GPR8RegClass;
1804 RC = &AVR::DREGSRegClass;
1808 RC = &AVR::GPR8RegClass;
1812 RC = &AVR::DREGSRegClass;
1815 Opc =
Tiny ? AVR::ROLBRdR17 : AVR::ROLBRdR1;
1816 RC = &AVR::GPR8RegClass;
1820 RC = &AVR::DREGSRegClass;
1824 RC = &AVR::GPR8RegClass;
1828 RC = &AVR::DREGSRegClass;
1832 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1835 for (
I = BB->getIterator();
I !=
F->end() && &(*
I) != BB; ++
I)
1841 MachineBasicBlock *LoopBB =
F->CreateMachineBasicBlock(LLVM_BB);
1842 MachineBasicBlock *CheckBB =
F->CreateMachineBasicBlock(LLVM_BB);
1843 MachineBasicBlock *RemBB =
F->CreateMachineBasicBlock(LLVM_BB);
1845 F->insert(
I, LoopBB);
1846 F->insert(
I, CheckBB);
1847 F->insert(
I, RemBB);
1853 RemBB->transferSuccessorsAndUpdatePHIs(BB);
1856 BB->addSuccessor(CheckBB);
1857 LoopBB->addSuccessor(CheckBB);
1858 CheckBB->addSuccessor(LoopBB);
1859 CheckBB->addSuccessor(RemBB);
1861 Register ShiftAmtReg = RI.createVirtualRegister(&AVR::GPR8RegClass);
1862 Register ShiftAmtReg2 = RI.createVirtualRegister(&AVR::GPR8RegClass);
1863 Register ShiftReg = RI.createVirtualRegister(RC);
1864 Register ShiftReg2 = RI.createVirtualRegister(RC);
1865 Register ShiftAmtSrcReg =
MI.getOperand(2).getReg();
1875 auto ShiftMI =
BuildMI(LoopBB, dl,
TII.get(Opc), ShiftReg2).
addReg(ShiftReg);
1876 if (HasRepeatedOperand)
1877 ShiftMI.
addReg(ShiftReg);
1885 BuildMI(CheckBB, dl,
TII.get(AVR::PHI), ShiftReg)
1890 BuildMI(CheckBB, dl,
TII.get(AVR::PHI), ShiftAmtReg)
1895 BuildMI(CheckBB, dl,
TII.get(AVR::PHI), DstReg)
1901 BuildMI(CheckBB, dl,
TII.get(AVR::DECRd), ShiftAmtReg2).
addReg(ShiftAmtReg);
1904 MI.eraseFromParent();
1927 const bool ShiftLeft = Opc ==
ISD::SHL;
1928 const bool ArithmeticShift = Opc ==
ISD::SRA;
1931 Register ZeroReg =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
1939 if (ShiftLeft && (ShiftAmt % 8) >= 6) {
1944 size_t ShiftRegsOffset = ShiftAmt / 8;
1945 size_t ShiftRegsSize = Regs.size() - ShiftRegsOffset;
1947 Regs.
slice(ShiftRegsOffset, ShiftRegsSize);
1955 Register LowByte =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
1959 if (ShiftAmt % 8 == 6) {
1961 Register NewLowByte =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
1963 LowByte = NewLowByte;
1967 for (
size_t I = 0;
I < Regs.size();
I++) {
1968 int ShiftRegsIdx =
I + 1;
1969 if (ShiftRegsIdx < (
int)ShiftRegs.
size()) {
1970 Regs[
I] = ShiftRegs[ShiftRegsIdx];
1971 }
else if (ShiftRegsIdx == (
int)ShiftRegs.
size()) {
1972 Regs[
I] = std::pair(LowByte, 0);
1974 Regs[
I] = std::pair(ZeroReg, 0);
1982 if (!ShiftLeft && (ShiftAmt % 8) >= 6) {
1985 size_t ShiftRegsSize = Regs.size() - (ShiftAmt / 8);
1987 Regs.
slice(0, ShiftRegsSize);
1996 Register HighByte =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
1998 if (ArithmeticShift) {
2016 if (ShiftAmt % 8 == 6) {
2019 Register NewExt =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
2027 for (
int I = Regs.size() - 1;
I >= 0;
I--) {
2028 int ShiftRegsIdx =
I - (Regs.size() - ShiftRegs.
size()) - 1;
2029 if (ShiftRegsIdx >= 0) {
2030 Regs[
I] = ShiftRegs[ShiftRegsIdx];
2031 }
else if (ShiftRegsIdx == -1) {
2032 Regs[
I] = std::pair(HighByte, 0);
2034 Regs[
I] = std::pair(ExtByte, 0);
2043 while (ShiftLeft && ShiftAmt >= 8) {
2045 for (
size_t I = 0;
I < Regs.size() - 1;
I++) {
2046 Regs[
I] = Regs[
I + 1];
2050 Regs[Regs.size() - 1] = std::pair(ZeroReg, 0);
2053 Regs = Regs.drop_back(1);
2060 if (!ShiftLeft && ShiftAmt >= 8) {
2061 if (ArithmeticShift) {
2063 ShrExtendReg =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
2064 Register Tmp =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
2066 .
addReg(Regs[0].first, 0, Regs[0].second)
2067 .
addReg(Regs[0].first, 0, Regs[0].second);
2068 BuildMI(*BB,
MI, dl,
TII.get(AVR::SBCRdRr), ShrExtendReg)
2072 ShrExtendReg = ZeroReg;
2074 for (; ShiftAmt >= 8; ShiftAmt -= 8) {
2076 for (
size_t I = Regs.size() - 1;
I != 0;
I--) {
2077 Regs[
I] = Regs[
I - 1];
2081 Regs[0] = std::pair(ShrExtendReg, 0);
2084 Regs = Regs.drop_front(1);
2089 assert((ShiftAmt < 8) &&
"Unexpect shift amount");
2109 if (!ArithmeticShift && ShiftAmt >= 4) {
2111 for (
size_t I = 0;
I < Regs.size();
I++) {
2112 size_t Idx = ShiftLeft ?
I : Regs.size() -
I - 1;
2113 Register SwapReg =
MRI.createVirtualRegister(&AVR::LD8RegClass);
2117 Register R =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
2123 Register AndReg =
MRI.createVirtualRegister(&AVR::LD8RegClass);
2126 .
addImm(ShiftLeft ? 0xf0 : 0x0f);
2128 Register R =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
2132 size_t PrevIdx = ShiftLeft ?
Idx - 1 :
Idx + 1;
2133 Regs[PrevIdx] = std::pair(R, 0);
2136 Regs[
Idx] = std::pair(AndReg, 0);
2143 while (ShiftLeft && ShiftAmt) {
2145 for (ssize_t
I = Regs.size() - 1;
I >= 0;
I--) {
2146 Register Out =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
2149 if (
I == (ssize_t)Regs.size() - 1) {
2152 .
addReg(In, 0, InSubreg);
2156 .
addReg(In, 0, InSubreg);
2158 Regs[
I] = std::pair(Out, 0);
2162 while (!ShiftLeft && ShiftAmt) {
2164 for (
size_t I = 0;
I < Regs.size();
I++) {
2165 Register Out =
MRI.createVirtualRegister(&AVR::GPR8RegClass);
2169 unsigned Opc = ArithmeticShift ? AVR::ASRRd : AVR::LSRRd;
2174 Regs[
I] = std::pair(Out, 0);
2179 if (ShiftAmt != 0) {
2186AVRTargetLowering::insertWideShift(MachineInstr &
MI,
2187 MachineBasicBlock *BB)
const {
2189 const DebugLoc &dl =
MI.getDebugLoc();
2193 int64_t ShiftAmt =
MI.getOperand(4).getImm();
2195 switch (
MI.getOpcode()) {
2208 std::array<std::pair<Register, int>, 4>
Registers = {
2209 std::pair(
MI.getOperand(3).getReg(), AVR::sub_hi),
2210 std::pair(
MI.getOperand(3).getReg(), AVR::sub_lo),
2211 std::pair(
MI.getOperand(2).getReg(), AVR::sub_hi),
2212 std::pair(
MI.getOperand(2).getReg(), AVR::sub_lo),
2230 (Opc !=
ISD::SRA || (ShiftAmt < 16 || ShiftAmt >= 22))) {
2232 BuildMI(*BB,
MI, dl,
TII.get(AVR::REG_SEQUENCE),
MI.getOperand(0).getReg())
2237 BuildMI(*BB,
MI, dl,
TII.get(AVR::REG_SEQUENCE),
MI.getOperand(1).getReg())
2244 BuildMI(*BB,
MI, dl,
TII.get(AVR::REG_SEQUENCE),
MI.getOperand(1).getReg())
2249 BuildMI(*BB,
MI, dl,
TII.get(AVR::REG_SEQUENCE),
MI.getOperand(0).getReg())
2257 MI.eraseFromParent();
2262 if (
I->getOpcode() == AVR::COPY) {
2263 Register SrcReg =
I->getOperand(1).getReg();
2264 return (SrcReg == AVR::R0 || SrcReg == AVR::R1);
2273MachineBasicBlock *AVRTargetLowering::insertMul(MachineInstr &
MI,
2274 MachineBasicBlock *BB)
const {
2282 BuildMI(*BB,
I,
MI.getDebugLoc(),
TII.get(AVR::EORRdRr), AVR::R1)
2290AVRTargetLowering::insertCopyZero(MachineInstr &
MI,
2291 MachineBasicBlock *BB)
const {
2295 .
add(
MI.getOperand(0))
2297 MI.eraseFromParent();
2303MachineBasicBlock *AVRTargetLowering::insertAtomicArithmeticOp(
2304 MachineInstr &
MI, MachineBasicBlock *BB,
unsigned Opcode,
int Width)
const {
2305 MachineRegisterInfo &
MRI = BB->getParent()->getRegInfo();
2319 const TargetRegisterClass *RC =
2320 (Width == 8) ? &AVR::GPR8RegClass : &AVR::DREGSRegClass;
2321 unsigned LoadOpcode = (Width == 8) ? AVR::LDRdPtr : AVR::LDWRdPtr;
2322 unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr;
2330 BuildMI(*BB,
I, dl,
TII.get(LoadOpcode),
MI.getOperand(0).getReg())
2331 .
add(
MI.getOperand(1));
2337 .
add(
MI.getOperand(2));
2341 .
add(
MI.getOperand(1))
2350 MI.eraseFromParent();
2357 int Opc =
MI.getOpcode();
2373 return insertShift(
MI,
MBB, STI.hasTinyEncoding());
2377 return insertWideShift(
MI,
MBB);
2380 return insertMul(
MI,
MBB);
2382 return insertCopyZero(
MI,
MBB);
2383 case AVR::AtomicLoadAdd8:
2384 return insertAtomicArithmeticOp(
MI,
MBB, AVR::ADDRdRr, 8);
2385 case AVR::AtomicLoadAdd16:
2386 return insertAtomicArithmeticOp(
MI,
MBB, AVR::ADDWRdRr, 16);
2387 case AVR::AtomicLoadSub8:
2388 return insertAtomicArithmeticOp(
MI,
MBB, AVR::SUBRdRr, 8);
2389 case AVR::AtomicLoadSub16:
2390 return insertAtomicArithmeticOp(
MI,
MBB, AVR::SUBWRdRr, 16);
2391 case AVR::AtomicLoadAnd8:
2392 return insertAtomicArithmeticOp(
MI,
MBB, AVR::ANDRdRr, 8);
2393 case AVR::AtomicLoadAnd16:
2394 return insertAtomicArithmeticOp(
MI,
MBB, AVR::ANDWRdRr, 16);
2395 case AVR::AtomicLoadOr8:
2396 return insertAtomicArithmeticOp(
MI,
MBB, AVR::ORRdRr, 8);
2397 case AVR::AtomicLoadOr16:
2398 return insertAtomicArithmeticOp(
MI,
MBB, AVR::ORWRdRr, 16);
2399 case AVR::AtomicLoadXor8:
2400 return insertAtomicArithmeticOp(
MI,
MBB, AVR::EORRdRr, 8);
2401 case AVR::AtomicLoadXor16:
2402 return insertAtomicArithmeticOp(
MI,
MBB, AVR::EORWRdRr, 16);
2405 assert((Opc == AVR::Select16 || Opc == AVR::Select8) &&
2406 "Unexpected instr type to insert");
2427 if (FallThrough !=
nullptr) {
2443 unsigned CallFrameSize =
TII.getCallFrameSizeAt(
MI);
2457 MBB->addSuccessor(falseMBB);
2458 MBB->addSuccessor(trueMBB);
2466 MI.getOperand(0).getReg())
2472 MI.eraseFromParent();
2482 if (Constraint.
size() == 1) {
2484 switch (Constraint[0]) {
2527 switch (ConstraintCode[0]) {
2538 Value *CallOperandVal =
info.CallOperandVal;
2543 if (!CallOperandVal) {
2548 switch (*constraint) {
2572 if (
const ConstantFP *
C = dyn_cast<ConstantFP>(CallOperandVal)) {
2579 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(CallOperandVal)) {
2580 if (isUInt<6>(
C->getZExtValue())) {
2586 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(CallOperandVal)) {
2587 if ((
C->getSExtValue() >= -63) && (
C->getSExtValue() <= 0)) {
2593 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(CallOperandVal)) {
2594 if (
C->getZExtValue() == 2) {
2600 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(CallOperandVal)) {
2601 if (
C->getZExtValue() == 0) {
2607 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(CallOperandVal)) {
2608 if (isUInt<8>(
C->getZExtValue())) {
2614 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(CallOperandVal)) {
2615 if (
C->getSExtValue() == -1) {
2621 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(CallOperandVal)) {
2622 if ((
C->getZExtValue() == 8) || (
C->getZExtValue() == 16) ||
2623 (
C->getZExtValue() == 24)) {
2629 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(CallOperandVal)) {
2630 if (
C->getZExtValue() == 1) {
2636 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(CallOperandVal)) {
2637 if ((
C->getSExtValue() >= -6) && (
C->getSExtValue() <= 5)) {
2650std::pair<unsigned, const TargetRegisterClass *>
2654 if (Constraint.
size() == 1) {
2655 switch (Constraint[0]) {
2658 return std::make_pair(0U, &AVR::LD8loRegClass);
2659 else if (VT == MVT::i16)
2660 return std::make_pair(0U, &AVR::DREGSLD8loRegClass);
2663 if (VT == MVT::i8 || VT == MVT::i16)
2664 return std::make_pair(0U, &AVR::PTRDISPREGSRegClass);
2668 return std::make_pair(0U, &AVR::LD8RegClass);
2669 else if (VT == MVT::i16)
2670 return std::make_pair(0U, &AVR::DLDREGSRegClass);
2674 return std::make_pair(0U, &AVR::GPR8loRegClass);
2675 else if (VT == MVT::i16)
2676 return std::make_pair(0U, &AVR::DREGSloRegClass);
2679 if (VT == MVT::i8 || VT == MVT::i16)
2680 return std::make_pair(0U, &AVR::PTRREGSRegClass);
2683 return std::make_pair(0U, &AVR::GPRSPRegClass);
2686 return std::make_pair(0U, &AVR::GPR8RegClass);
2687 else if (VT == MVT::i16)
2688 return std::make_pair(0U, &AVR::DREGSRegClass);
2693 &AVR::GPR8RegClass);
2696 if (VT == MVT::i8 || VT == MVT::i16)
2697 return std::make_pair(0U, &AVR::IWREGSRegClass);
2701 if (VT == MVT::i8 || VT == MVT::i16)
2702 return std::make_pair(
unsigned(AVR::R27R26), &AVR::PTRREGSRegClass);
2706 if (VT == MVT::i8 || VT == MVT::i16)
2707 return std::make_pair(
unsigned(AVR::R29R28), &AVR::PTRREGSRegClass);
2711 if (VT == MVT::i8 || VT == MVT::i16)
2712 return std::make_pair(
unsigned(AVR::R31R30), &AVR::PTRREGSRegClass);
2725 std::vector<SDValue> &Ops,
2729 EVT Ty =
Op.getValueType();
2732 if (Constraint.
size() != 1) {
2736 char ConstraintLetter = Constraint[0];
2737 switch (ConstraintLetter) {
2755 int64_t CVal64 =
C->getSExtValue();
2757 switch (ConstraintLetter) {
2759 if (!isUInt<6>(CUVal64))
2764 if (CVal64 < -63 || CVal64 > 0)
2779 if (!isUInt<8>(CUVal64))
2795 if (CUVal64 != 8 && CUVal64 != 16 && CUVal64 != 24)
2805 if (CVal64 < -6 || CVal64 > 5)
2815 if (!FC || !FC->isZero())
2822 if (Result.getNode()) {
2823 Ops.push_back(Result);
2836 .
Case(
"r0", AVR::R0)
2837 .
Case(
"r1", AVR::R1)
2841 .
Case(
"r0", AVR::R1R0)
2842 .
Case(
"sp", AVR::SP)
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI Pre allocate WWM Registers
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Utilities related to the AVR instruction set.
A specific AVR target MCU.
Register getTmpRegister() const
Register getZeroRegister() const
const AVRInstrInfo * getInstrInfo() const override
const AVRRegisterInfo * getRegisterInfo() const override
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
Replace a node with an illegal result type with a new node built out of custom code.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
Returns true by value, base pointer and offset pointer and addressing mode by reference if the node's...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
const AVRSubtarget & Subtarget
InlineAsm::ConstraintCode getInlineAsmMemConstraint(StringRef ConstraintCode) const override
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
AVRTargetLowering(const AVRTargetMachine &TM, const AVRSubtarget &STI)
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
Return the ValueType of the result of SETCC operations.
bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
Returns true by value, base pointer and offset pointer and addressing mode by reference if this node ...
A generic AVR implementation.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
LLVM Basic Block Representation.
CCState - This class holds information needed while lowering arguments and return values.
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
LLVMContext & getContext() const
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
void addLoc(const CCValAssign &V)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP, bool IsCustom=false)
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
static auto integer_valuetypes()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
BasicBlockListType::iterator iterator
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) 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
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
MutableArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDValue getValue(unsigned R) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This class is used to represent ISD::STORE nodes.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const
Get the CallingConv that should be used for the specified libcall.
void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC)
Set the CallingConv that should be used for the specified libcall.
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
void setSupportsUnalignedAtomics(bool UnalignedSupported)
Sets whether unaligned atomic operations are supported.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
std::vector< ArgListEntry > ArgListTy
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual InlineAsm::ConstraintCode getInlineAsmMemConstraint(StringRef ConstraintCode) const
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
CondCodes
AVR specific condition codes.
@ COND_SH
Unsigned same or higher.
@ COND_GE
Greater than or equal.
@ ASRWN
Word arithmetic shift right N bits.
@ RET_GLUE
Return from subroutine.
@ SWAP
Swap Rd[7:4] <-> Rd[3:0].
@ RETI_GLUE
Return from ISR.
@ LSLW
Wide logical shift left.
@ ROLLOOP
A loop of single left bit rotate instructions.
@ ASRLO
Lower 8-bit of word arithmetic shift right.
@ ASRLOOP
A loop of single arithmetic shift right instructions.
@ LSRLOOP
A loop of single logical shift right instructions.
@ LSR
Logical shift right.
@ LSRLO
Lower 8-bit of word logical shift right.
@ TST
Test for zero or minus instruction.
@ LSRBN
Byte logical shift right N bits.
@ ASRW
Wide arithmetic shift right.
@ SELECT_CC
Operand 0 and operand 1 are selection variable, operand 2 is condition code and operand 3 is flag ope...
@ CMPC
Compare with carry instruction.
@ LSLWN
Word logical shift left N bits.
@ RORLOOP
A loop of single right bit rotate instructions.
@ CMP
Compare instruction.
@ ASRBN
Byte arithmetic shift right N bits.
@ CALL
Represents an abstract call instruction, which includes a bunch of information.
@ ASR
Arithmetic shift right.
@ LSRW
Wide logical shift right.
@ LSLBN
Byte logical shift left N bits.
@ LSLHI
Higher 8-bit of word logical shift left.
@ LSRWN
Word logical shift right N bits.
@ WRAPPER
A wrapper node for TargetConstantPool, TargetExternalSymbol, and TargetGlobalAddress.
@ LSLLOOP
A loop of single logical shift left instructions.
@ BRCOND
AVR conditional branches.
bool isProgramMemoryAccess(MemSDNode const *N)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ AVR_BUILTIN
Used for special AVR rtlib functions which have an "optimized" convention to preserve registers.
@ C
The default llvm calling convention, compatible with C.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ SIGN_EXTEND
Conversion operators.
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ BasicBlock
Various leaf nodes.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
@ Undef
Value of the register doesn't matter.
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
This is an optimization pass for GlobalISel generic memory operations.
static void analyzeReturnValues(const SmallVectorImpl< ArgT > &Args, CCState &CCInfo, bool Tiny)
Analyze incoming and outgoing value of returning from a function.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static const MCPhysReg RegList16Tiny[]
static const MCPhysReg RegList8Tiny[]
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
static void analyzeArguments(TargetLowering::CallLoweringInfo *CLI, const Function *F, const DataLayout *TD, const SmallVectorImpl< ArgT > &Args, SmallVectorImpl< CCValAssign > &ArgLocs, CCState &CCInfo, bool Tiny)
Analyze incoming and outgoing function arguments.
static const MCPhysReg RegList16AVR[]
static unsigned getTotalArgumentsSizeInBytes(const SmallVectorImpl< ArgT > &Args)
Count the total number of bytes needed to pass or return these arguments.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
static AVRCC::CondCodes intCCToAVRCC(ISD::CondCode CC)
IntCCToAVRCC - Convert a DAG integer condition code to an AVR CC.
static bool isCopyMulResult(MachineBasicBlock::iterator const &I)
static void insertMultibyteShift(MachineInstr &MI, MachineBasicBlock *BB, MutableArrayRef< std::pair< Register, int > > Regs, ISD::NodeType Opc, int64_t ShiftAmt)
static const MCPhysReg RegList8AVR[]
Registers for calling conventions, ordered in reverse as required by ABI.
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.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool isVector() const
Return true if this is a vector value type.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
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.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg If BaseGV is null...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.