14 #define DEBUG_TYPE "xcore-lower"
63 default :
return NULL;
70 Subtarget(*XTM.getSubtargetImpl()) {
203 case ISD::LOAD:
return LowerLOAD(Op, DAG);
260 if (
const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
261 UnderlyingGV = GA->resolveAliasedGlobal();
262 if (
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(UnderlyingGV)) {
263 if (GVar->isConstant())
278 int64_t FoldedOffset = std::max(Offset & ~3, (int64_t)0);
280 GA = getGlobalAddressWrapper(GA, GV, DAG);
282 if (Offset != FoldedOffset) {
294 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
335 unsigned NumEntries = MJTI->
getJumpTables()[JTI].MBBs.size();
336 if (NumEntries <= 32) {
339 assert((NumEntries >> 31) == 0);
350 if ((Offset & 0x3) == 0) {
352 false,
false,
false, 0);
356 int32_t LowOffset = HighOffset - 4;
359 dyn_cast<GlobalAddressSDNode>(Base.
getNode())) {
375 false,
false,
false, 0);
378 false,
false,
false, 0);
384 SDValue Ops[] = { Result, Chain };
390 APInt KnownZero, KnownOne;
400 "Unexpected extension type");
421 Offset = cast<ConstantSDNode>(BasePtr->
getOperand(1))->getSExtValue();
422 return lowerLoadWordFromAlignedBasePlusOffset(DL, Chain, NewBasePtr,
429 return lowerLoadWordFromAlignedBasePlusOffset(DL, Chain, NewBasePtr,
450 SDValue Ops[] = { Result, Chain };
460 Entry.
Node = BasePtr;
461 Args.push_back(Entry);
468 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
471 { CallResult.first, CallResult.second };
473 return DAG.getMergeValues(Ops, 2, DL);
519 Entry.
Node = BasePtr;
520 Args.push_back(Entry);
523 Args.push_back(Entry);
531 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
533 return CallResult.second;
540 "Unexpected operand to lower!");
557 "Unexpected operand to lower!");
577 SDValue &Addend1,
bool requireIntermediatesHaveOneUse)
594 if (requireIntermediatesHaveOneUse && !AddOp.
hasOneUse())
598 if (requireIntermediatesHaveOneUse && !OtherOp.
hasOneUse())
644 SDValue LL, RL, AddendL, AddendH;
665 if (LHSSB > 32 && RHSSB > 32) {
694 "Unknown operand to lower!");
697 SDValue Result = TryExpandADDWithMul(N, DAG);
724 SDValue Ignored(Hi.getNode(), 1);
739 const Value *SV = cast<SrcValueSDNode>(Node->
getOperand(2))->getValue();
743 false,
false,
false, 0);
752 false,
false,
false, 0);
772 if (cast<ConstantSDNode>(Op.
getOperand(0))->getZExtValue() > 0)
793 const Value *TrmpAddr = cast<SrcValueSDNode>(Op.
getOperand(4))->getValue();
829 OutChains[3] = DAG.
getStore(Chain, dl, Nest, Addr,
835 OutChains[4] = DAG.
getStore(Chain, dl, FPtr, Addr,
845 unsigned IntNo = cast<ConstantSDNode>(Op.
getOperand(0))->getZExtValue();
853 SDValue Results[] = { Crc, Data };
869 #include "XCoreGenCallingConv.inc"
900 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
901 Outs, OutVals, Ins, dl, DAG, InVals);
910 XCoreTargetLowering::LowerCCCCallTo(
SDValue Chain,
SDValue Callee,
928 CCInfo.AnalyzeCallOperands(Outs, CC_XCore);
931 unsigned NumBytes = CCInfo.getNextStackOffset();
940 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
976 if (!MemOpChains.
empty())
978 &MemOpChains[0], MemOpChains.
size());
985 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
986 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
987 RegsToPass[i].second, InFlag);
1010 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i)
1012 RegsToPass[i].second.getValueType()));
1029 return LowerCallResult(Chain, InFlag, CallConv, isVarArg,
1030 Ins, dl, DAG, InVals);
1036 XCoreTargetLowering::LowerCallResult(
SDValue Chain,
SDValue InFlag,
1050 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
1052 RVLocs[i].getValVT(), InFlag).
getValue(1);
1070 XCoreTargetLowering::LowerFormalArguments(
SDValue Chain,
1084 return LowerCCCArguments(Chain, CallConv, isVarArg,
1085 Ins, dl, DAG, InVals);
1094 XCoreTargetLowering::LowerCCCArguments(
SDValue Chain,
1115 unsigned LRSaveSize = StackSlotSize;
1129 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1141 errs() <<
"LowerFormalArguments Unhandled argument type: "
1157 if (ObjSize > StackSlotSize) {
1158 errs() <<
"LowerFormalArguments Unhandled argument type: "
1172 false,
false,
false, 0);
1174 const ArgDataPair ADP = { ArgIn, Ins[i].Flags };
1181 static const uint16_t ArgRegs[] = {
1182 XCore::R0, XCore::R1,
XCore::R2, XCore::R3
1185 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs,
1191 for (
int i =
array_lengthof(ArgRegs) - 1; i >= (int)FirstVAReg; --i) {
1194 if (i == (
int)FirstVAReg) {
1197 offset -= StackSlotSize;
1218 if (!CFRegNode.
empty())
1227 ArgDE = ArgData.
end();
1228 ArgDI != ArgDE; ++ArgDI) {
1229 if (ArgDI->Flags.isByVal() && ArgDI->Flags.getByValSize()) {
1230 unsigned Size = ArgDI->Flags.getByValSize();
1231 unsigned Align = std::max(StackSlotSize, ArgDI->Flags.getByValAlign());
1238 Align,
false,
false,
1247 if (!MemOps.
empty()) {
1260 bool XCoreTargetLowering::
1267 return CCInfo.CheckReturn(Outs, RetCC_XCore);
1271 XCoreTargetLowering::LowerReturn(
SDValue Chain,
1295 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
1297 assert(VA.
isRegLoc() &&
"Can only return in registers!");
1312 RetOps.push_back(Flag);
1315 &RetOps[0], RetOps.size());
1328 "Unexpected instr type to insert");
1390 DAGCombinerInfo &DCI)
const {
1408 if (N0C && N0C->
isNullValue() && N1C && N1C->isNullValue()) {
1412 SDValue Ops[] = { Result, Carry };
1419 APInt KnownZero, KnownOne;
1421 VT.getSizeInBits() - 1);
1423 if ((KnownZero & Mask) == Mask) {
1426 SDValue Ops[] = { Result, Carry };
1441 if (N0C && N0C->
isNullValue() && N1C && N1C->isNullValue()) {
1442 APInt KnownZero, KnownOne;
1444 VT.getSizeInBits() - 1);
1446 if ((KnownZero & Mask) == Mask) {
1450 SDValue Ops[] = { Result, Borrow };
1458 APInt KnownZero, KnownOne;
1460 VT.getSizeInBits() - 1);
1462 if ((KnownZero & Mask) == Mask) {
1465 SDValue Ops[] = { Result, Borrow };
1481 if ((N0C && !N1C) ||
1482 (N0C && N1C && N0C->
getZExtValue() < N1C->getZExtValue()))
1487 if (N1C && N1C->isNullValue()) {
1498 SDValue Ops[] = { Carry, Result };
1508 SDValue Mul0, Mul1, Addend0, Addend1;
1513 Mul1, Addend0, Addend1);
1538 Addend0L, Addend1L);
1547 if (!DCI.isBeforeLegalize() ||
1555 if (StoreBits % 8) {
1561 if (Alignment >= ABIAlignment) {
1583 void XCoreTargetLowering::computeMaskedBitsForTargetNode(
const SDValue Op,
1587 unsigned Depth)
const {
1608 return (val >= 0 && val <= 11);
1613 return (val%2 == 0 &&
isImmUs(val/2));
1618 return (val%4 == 0 &&
isImmUs(val/4));
1639 if (AM.
Scale == 0) {
1647 if (AM.
Scale == 0) {
1654 if (AM.
Scale == 0) {
1666 std::pair<unsigned, const TargetRegisterClass*>
1667 XCoreTargetLowering::
1668 getRegForInlineAsmConstraint(
const std::string &Constraint,
1670 if (Constraint.size() == 1) {
1671 switch (Constraint[0]) {
1674 return std::make_pair(0U, &XCore::GRRegsRegClass);
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
static bool isImmUs2(int64_t val)
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)
void setVarArgsFrameIndex(int off)
LocInfo getLocInfo() const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
const TargetMachine & getTargetMachine() const
unsigned getAlignment() const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
void addLiveIn(unsigned Reg, unsigned vreg=0)
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const
const GlobalValue * getGlobal() const
unsigned getOpcode() const
Type * getTypeForEVT(LLVMContext &Context) const
unsigned getSizeInBits() const
void setBooleanVectorContents(BooleanContent Ty)
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB)
const SDValue & getOperand(unsigned Num) const
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags=0)
void ComputeMaskedBits(SDValue Op, APInt &KnownZero, APInt &KnownOne, unsigned Depth=0) const
const SDValue & getBasePtr() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
SDValue getExternalSymbol(const char *Sym, EVT VT)
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
static bool isImmUs(int64_t val)
static int stackSlotSize()
Stack slot size (4 bytes)
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)
const std::vector< MachineJumpTableEntry > & getJumpTables() const
SDValue getStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, unsigned Alignment, const MDNode *TBAAInfo=0)
int getVarArgsFrameIndex() const
int64_t getOffset() const
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
virtual unsigned getJumpTableEncoding() const
EVT getValueType(unsigned ResNo) const
MachineFunction & getMachineFunction() const
SDValue getTargetGlobalAddress(const GlobalValue *GV, SDLoc DL, EVT VT, int64_t offset=0, unsigned char TargetFlags=0)
MachinePointerInfo getWithOffset(int64_t O) const
Abstract Stack Frame Information.
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
SDVTList getVTList(EVT VT)
virtual MVT getPointerTy(uint32_t=0) const
virtual unsigned getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
ID
LLVM Calling Convention Representation.
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
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
Simple integer binary arithmetic operators.
SmallVector< ISD::OutputArg, 32 > Outs
const MachineJumpTableInfo * getJumpTableInfo() const
const SDValue & getBasePtr() const
MachineConstantPoolValue * getMachineCPVal() const
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.
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const
LowerOperation - Provide custom lowering hooks for some operations.
const BasicBlock * getBasicBlock() const
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
SDNode * getNode() const
get the SDNode which holds the desired result
bundle_iterator< MachineInstr, instr_iterator > iterator
unsigned getStoreSizeInBits() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=0)
bool isMachineConstantPoolEntry() const
LLVM Basic Block Representation.
const SDValue & getOperand(unsigned i) const
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
void setTargetDAGCombine(ISD::NodeType NT)
bool isNonTemporal() const
const Constant * getConstVal() const
const MachineOperand & getOperand(unsigned i) const
virtual const char * getTargetNodeName(unsigned Opcode) const
getTargetNodeName - This method returns the name of a target specific
void setBooleanContents(BooleanContent Ty)
static Type * getVoidTy(LLVMContext &C)
ItTy next(ItTy it, Dist n)
SDValue getCopyFromReg(SDValue Chain, SDLoc dl, unsigned Reg, EVT VT)
const DataLayout * getDataLayout() const
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned getOpcode() const
TRAP - Trapping instruction.
const SDValue & getValue() const
unsigned MaxStoresPerMemmove
Specify maximum bytes of store instructions per memmove call.
Bit counting operators with an undefined result for zero inputs.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
std::vector< ArgListEntry > ArgListTy
SDValue getGlobalAddress(const GlobalValue *GV, SDLoc DL, EVT VT, int64_t offset=0, bool isTargetGA=false, unsigned char TargetFlags=0)
virtual bool isZExtFree(SDValue Val, EVT VT2) const
const MCInstrDesc & get(unsigned Opcode) const
const MachinePointerInfo & getPointerInfo() const
SDValue getMemcpy(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool AlwaysInline, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
void setLoadExtAction(unsigned ExtType, MVT VT, LegalizeAction Action)
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
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
unsigned getABITypeAlignment(Type *Ty) const
bool isBaseWithConstantOffset(SDValue Op) const
uint64_t getTypeAllocSize(Type *Ty) const
void setExceptionPointerRegister(unsigned R)
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.
SDValue getIntPtrConstant(uint64_t Val, bool isTarget=false)
const SDValue & getChain() const
SDValue getMemmove(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
MachineFrameInfo * getFrameInfo()
ISD::LoadExtType getExtensionType() const
Class for arbitrary precision integers.
void computeRegisterProperties()
void setExceptionSelectorRegister(unsigned R)
static bool isImmUs4(int64_t val)
void setMinFunctionAlignment(unsigned Align)
Set the target's minimum function alignment (in log2(bytes))
ZERO_EXTEND - Used for integer types, zeroing the new bits.
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)
XCoreTargetLowering(XCoreTargetMachine &TM)
uint64_t MinAlign(uint64_t A, uint64_t B)
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, bool MayNeedSP=false, const AllocaInst *Alloca=0)
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned char TargetFlags=0)
SmallVector< SDValue, 32 > OutVals
Bitwise operators - logical and, logical or, logical xor.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
MachineRegisterInfo & getRegInfo()
virtual const DataLayout * getDataLayout() const
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
bool isIndexed() const
isIndexed - Return true if this is a pre/post inc/dec load/store.
unsigned MaxStoresPerMemmoveOptSize
unsigned MaxStoresPerMemcpyOptSize
void setStackPointerRegisterToSaveRestore(unsigned R)
SDValue getTruncStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT TVT, bool isNonTemporal, bool isVolatile, unsigned Alignment, const MDNode *TBAAInfo=0)
unsigned countTrailingOnes() const
Count the number of trailing one bits.
virtual const TargetRegisterInfo * getRegisterInfo() const
virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const
bool reachesChainWithoutSideEffects(SDValue Dest, unsigned Depth=2) const
static bool isADDADDMUL(SDValue Op, SDValue &Mul0, SDValue &Mul1, SDValue &Addend0, SDValue &Addend1, bool requireIntermediatesHaveOneUse)
unsigned MaxStoresPerMemcpy
Specify maximum bytes of store instructions per memcpy call.
unsigned getReg() const
getReg - Returns the register number.
void insert(iterator MBBI, MachineBasicBlock *MBB)
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
void setIntDivIsCheap(bool isCheap=true)
unsigned getAlignment() const
virtual bool allowsUnalignedMemoryAccesses(EVT, bool *=0) const
Determine if the target supports unaligned memory accesses.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LLVM Value Representation.
SDValue getRegister(unsigned Reg, EVT VT)
bool isTruncatingStore() const
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
BasicBlockListType::iterator iterator
const TargetLowering & getTargetLoweringInfo() const
SDValue getMergeValues(const SDValue *Ops, unsigned NumOps, SDLoc dl)
getMergeValues - Create a MERGE_VALUES node from the given operands.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
unsigned MaxStoresPerMemsetOptSize
static bool isWordAligned(SDValue Value, SelectionDAG &DAG)
unsigned getLocMemOffset() const
SDValue getEntryNode() const
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable)
unsigned getAlignment() const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
unsigned AllocateStack(unsigned Size, unsigned Align)
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
INITIALIZE_PASS(GlobalMerge,"global-merge","Global Merge", false, false) bool GlobalMerge const DataLayout * TD
virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const
DebugLoc getDebugLoc() const
uint64_t getZExtValue() const