14 #define DEBUG_TYPE "msp430-lower"
49 cl::desc(
"Hardware multiplier use mode"),
53 "Do not use hardware multiplier"),
55 "Assume hardware multiplier can be used inside interrupts"),
57 "Assume hardware multiplier cannot be used inside interrupts"),
62 Subtarget(*tm.getSubtargetImpl()) {
217 if (Constraint.size() == 1) {
218 switch (Constraint[0]) {
228 std::pair<unsigned, const TargetRegisterClass*>
232 if (Constraint.size() == 1) {
234 switch (Constraint[0]) {
238 return std::make_pair(0U, &MSP430::GR8RegClass);
240 return std::make_pair(0U, &MSP430::GR16RegClass);
251 #include "MSP430GenCallingConv.inc"
255 template<
typename ArgT>
258 unsigned CurrentArgIndex = ~0U;
259 for (
unsigned i = 0, e = Args.
size(); i != e; i++) {
260 if (CurrentArgIndex == Args[i].OrigArgIndex) {
283 template<
typename ArgT>
287 static const uint16_t RegList[] = {
288 MSP430::R15W, MSP430::R14W, MSP430::R13W, MSP430::R12W
300 unsigned RegsLeft = NbRegs;
301 bool UseStack =
false;
304 for (
unsigned i = 0, e = ArgsParts.
size(); i != e; i++) {
305 MVT ArgVT = Args[ValNo].VT;
315 else if (ArgFlags.
isZExt())
323 State.
HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, 2, ArgFlags);
327 unsigned Parts = ArgsParts[i];
329 if (!UseStack && Parts <= RegsLeft) {
330 unsigned FirstVal = ValNo;
331 for (
unsigned j = 0; j < Parts; j++) {
340 std::reverse(B, B + Parts);
343 for (
unsigned j = 0; j < Parts; j++)
344 CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
359 template<
typename ArgT>
367 std::reverse(RVLocs.
begin(), RVLocs.
end());
371 MSP430TargetLowering::LowerFormalArguments(
SDValue Chain,
386 return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
416 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
417 Outs, OutVals, Ins, dl, DAG, InVals);
427 MSP430TargetLowering::LowerCCCArguments(
SDValue Chain,
449 unsigned Offset = CCInfo.getNextStackOffset();
453 for (
unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
462 errs() <<
"LowerFormalArguments Unhandled argument type: "
502 errs() <<
"LowerFormalArguments Unhandled argument type: "
514 false,
false,
false, 0);
525 MSP430TargetLowering::LowerReturn(
SDValue Chain,
549 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
551 assert(VA.
isRegLoc() &&
"Can only return in registers!");
569 RetOps.push_back(Flag);
578 MSP430TargetLowering::LowerCCCCallTo(
SDValue Chain,
SDValue Callee,
594 unsigned NumBytes = CCInfo.getNextStackOffset();
605 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
644 MemOp = DAG.
getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
661 if (!MemOpChains.
empty())
663 &MemOpChains[0], MemOpChains.
size());
669 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
670 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
671 RegsToPass[i].second, InFlag);
691 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i)
693 RegsToPass[i].second.getValueType()));
710 return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
718 MSP430TargetLowering::LowerCallResult(
SDValue Chain,
SDValue InFlag,
732 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
734 RVLocs[i].getValVT(), InFlag).
getValue(1);
764 uint64_t ShiftAmount = cast<ConstantSDNode>(N->
getOperand(1))->getZExtValue();
771 if (Opc ==
ISD::SRL && ShiftAmount) {
778 while (ShiftAmount--)
787 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
788 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
800 const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
809 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
846 RHS = DAG.
getConstant(
C->getSExtValue() + 1,
C->getValueType(0));
859 RHS = DAG.
getConstant(
C->getSExtValue() + 1,
C->getValueType(0));
872 RHS = DAG.
getConstant(
C->getSExtValue() + 1,
C->getValueType(0));
885 RHS = DAG.
getConstant(
C->getSExtValue() + 1,
C->getValueType(0));
910 Chain, Dest, TargetCC, Flag);
925 if (RHSC->isNullValue() && LHS.
hasOneUse() &&
943 switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
1021 assert(VT ==
MVT::i16 &&
"Only support i16 for now!");
1032 int ReturnAddrIndex = FuncInfo->
getRAIndex();
1034 if (ReturnAddrIndex == 0) {
1050 unsigned Depth = cast<ConstantSDNode>(Op.
getOperand(0))->getZExtValue();
1076 unsigned Depth = cast<ConstantSDNode>(Op.
getOperand(0))->getZExtValue();
1082 false,
false,
false, 0);
1113 bool MSP430TargetLowering::getPostIndexedAddressParts(
SDNode *
N,
SDNode *Op,
1131 uint64_t RHSC = RHS->getZExtValue();
1132 if ((VT ==
MVT::i16 && RHSC != 2) ||
1148 default:
return NULL;
1210 Opc = MSP430::SHL8r1;
1211 RC = &MSP430::GR8RegClass;
1214 Opc = MSP430::SHL16r1;
1215 RC = &MSP430::GR16RegClass;
1218 Opc = MSP430::SAR8r1;
1219 RC = &MSP430::GR8RegClass;
1222 Opc = MSP430::SAR16r1;
1223 RC = &MSP430::GR16RegClass;
1226 Opc = MSP430::SAR8r1c;
1227 RC = &MSP430::GR8RegClass;
1230 Opc = MSP430::SAR16r1c;
1231 RC = &MSP430::GR16RegClass;
1271 .addReg(ShiftAmtSrcReg).
addImm(0);
1282 .addReg(SrcReg).
addMBB(BB)
1285 .addReg(ShiftAmtSrcReg).
addMBB(BB)
1289 BuildMI(LoopBB, dl, TII.
get(MSP430::SUB8ri), ShiftAmtReg2)
1290 .addReg(ShiftAmtReg).
addImm(1);
1298 .addReg(SrcReg).
addMBB(BB)
1310 if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1311 Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1312 Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
1318 assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
1319 "Unexpected instr type to insert");
void setFrameAddressIsTaken(bool T)
void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
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
void setRAIndex(int Index)
LLVMContext * getContext() const
SDValue getCopyToReg(SDValue Chain, SDLoc dl, unsigned Reg, SDValue N)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, SDLoc DL)
LocInfo getLocInfo() const
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const
const TargetMachine & getTargetMachine() const
Y = RRC X, rotate right via carry.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
SHL, SRA, SRL - Non-constant shifts.
unsigned getPointerSize(unsigned AS=0) const
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
void addLiveIn(unsigned Reg, unsigned vreg=0)
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const
void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
virtual ConstraintType getConstraintType(const std::string &Constraint) const
Given a constraint, return the type of constraint it is for this target.
unsigned getOpcode() const
ValuesClass< DataType > END_WITH_NULL values(const char *Arg, DataType Val, const char *Desc,...)
unsigned getSizeInBits() const
unsigned getByValSize() const
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const
void setBooleanVectorContents(BooleanContent Ty)
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB)
const SDValue & getOperand(unsigned Num) const
static void AnalyzeVarArgs(CCState &State, const SmallVectorImpl< ISD::OutputArg > &Outs)
MSP430TargetLowering(MSP430TargetMachine &TM)
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags=0)
static void ParseFunctionArgs(const SmallVectorImpl< ArgT > &Args, SmallVectorImpl< unsigned > &Out)
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const
LowerOperation - Provide custom lowering hooks for some operations.
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)
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
#define llvm_unreachable(msg)
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)
TargetLowering::ConstraintType getConstraintType(const std::string &Constraint) const
Abstract Stack Frame Information.
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Y = R{R,L}A X, rotate right (left) arithmetically.
SDVTList getVTList(EVT VT)
virtual MVT getPointerTy(uint32_t=0) const
ID
LLVM Calling Convention Representation.
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
SDValue getCALLSEQ_START(SDValue Chain, SDValue Op, SDLoc DL)
unsigned getLocReg() const
virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const
size_t array_lengthof(T(&)[N])
Find the length of an array.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
void setVarArgsFrameIndex(int Index)
Simple integer binary arithmetic operators.
SmallVector< ISD::OutputArg, 32 > Outs
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 LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
const BasicBlock * getBasicBlock() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
SDNode * getNode() const
get the SDNode which holds the desired result
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=0)
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
LLVM Basic Block Representation.
const SDValue & getOperand(unsigned i) const
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
static cl::opt< HWMultUseMode > HWMultMode("msp430-hwmult-mode", cl::Hidden, cl::desc("Hardware multiplier use mode"), cl::init(HWMultNoIntr), cl::values(clEnumValN(NoHWMult,"no","Do not use hardware multiplier"), clEnumValN(HWMultIntr,"interrupts","Assume hardware multiplier can be used inside interrupts"), clEnumValN(HWMultNoIntr,"use","Assume hardware multiplier cannot be used inside interrupts"), clEnumValEnd))
SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const
const MachineOperand & getOperand(unsigned i) const
int getVarArgsFrameIndex() const
static SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, ISD::CondCode CC, SDLoc dl, SelectionDAG &DAG)
void setBooleanContents(BooleanContent Ty)
ItTy next(ItTy it, Dist n)
SDValue getCopyFromReg(SDValue Chain, SDLoc dl, unsigned Reg, EVT VT)
const DataLayout * getDataLayout() const
unsigned getOpcode() const
void setPrefFunctionAlignment(unsigned Align)
Same as RET_FLAG, but used for returning from ISRs.
Bit counting operators with an undefined result for zero inputs.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
MSP430_INTR - Calling convention used for MSP430 interrupt routines.
SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const
void HandleByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags)
const MCInstrDesc & get(unsigned Opcode) const
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)
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags=0)
virtual const TargetInstrInfo * getInstrInfo() const
SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const
MachineBasicBlock * EmitShiftInstr(MachineInstr *MI, MachineBasicBlock *BB) const
CCValAssign - Represent assignment of one arg/retval to a location.
SDValue getIntPtrConstant(uint64_t Val, bool isTarget=false)
CMP - Compare instruction.
MachineFrameInfo * getFrameInfo()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
ISD::LoadExtType getExtensionType() const
void setIndexedLoadAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
static void AnalyzeRetResult(CCState &State, const SmallVectorImpl< ISD::InputArg > &Ins)
void computeRegisterProperties()
void setMinFunctionAlignment(unsigned Align)
Set the target's minimum function alignment (in log2(bytes))
ZERO_EXTEND - Used for integer types, zeroing the new bits.
void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT)
ANY_EXTEND - Used for integer types. The high bits are undefined.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned char TargetFlags=0)
SmallVector< SDValue, 32 > OutVals
Return with a flag operand. Operand 0 is the chain operand.
Bitwise operators - logical and, logical or, logical xor.
SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
MachineRegisterInfo & getRegInfo()
static void AnalyzeArguments(CCState &State, SmallVectorImpl< CCValAssign > &ArgLocs, const SmallVectorImpl< ArgT > &Args)
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
void setStackPointerRegisterToSaveRestore(unsigned R)
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
unsigned getPrimitiveSizeInBits() const
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) 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.
void insert(iterator MBBI, MachineBasicBlock *MBB)
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
void setIntDivIsCheap(bool isCheap=true)
void setReturnAddressIsTaken(bool s)
LLVM Value Representation.
SDValue getRegister(unsigned Reg, EVT VT)
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
SDValue getValueType(EVT)
BasicBlockListType::iterator iterator
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const
unsigned getLocMemOffset() const
SDValue getEntryNode() const
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable)
TRUNCATE - Completely drop the high bits.
unsigned AllocateReg(unsigned Reg)
static void AnalyzeReturnValues(CCState &State, SmallVectorImpl< CCValAssign > &RVLocs, const SmallVectorImpl< ArgT > &Args)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
virtual const char * getTargetNodeName(unsigned Opcode) const
DebugLoc getDebugLoc() const
virtual bool isZExtFree(Type *Ty1, Type *Ty2) const
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const