X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FXCore%2FXCoreISelLowering.cpp;h=5af2c9c0cc32a8873584c4a7dc1ec954a9d0c4c1;hb=5b3fca50a08865f0db55fc92ad1c037a04e12177;hp=27e52332466438f3dc4c48f3a8a32a0dc8432641;hpb=20adc9dc4650313f017b27d9818eb2176238113d;p=oota-llvm.git diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index 27e52332466..5af2c9c0cc3 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -1,4 +1,4 @@ -//===-- XCoreISelLowering.cpp - XCore DAG Lowering Implementation ------===// +//===-- XCoreISelLowering.cpp - XCore DAG Lowering Implementation ---------===// // // The LLVM Compiler Infrastructure // @@ -14,17 +14,11 @@ #define DEBUG_TYPE "xcore-lower" #include "XCoreISelLowering.h" -#include "XCoreMachineFunctionInfo.h" #include "XCore.h" -#include "XCoreTargetObjectFile.h" -#include "XCoreTargetMachine.h" +#include "XCoreMachineFunctionInfo.h" #include "XCoreSubtarget.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/Intrinsics.h" -#include "llvm/CallingConv.h" -#include "llvm/GlobalVariable.h" -#include "llvm/GlobalAlias.h" +#include "XCoreTargetMachine.h" +#include "XCoreTargetObjectFile.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -33,18 +27,23 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalAlias.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/VectorExtras.h" -#include -#include +#include + using namespace llvm; const char *XCoreTargetLowering:: -getTargetNodeName(unsigned Opcode) const +getTargetNodeName(unsigned Opcode) const { - switch (Opcode) + switch (Opcode) { case XCoreISD::BL : return "XCoreISD::BL"; case XCoreISD::PCRelativeWrapper : return "XCoreISD::PCRelativeWrapper"; @@ -57,6 +56,7 @@ getTargetNodeName(unsigned Opcode) const case XCoreISD::LMUL : return "XCoreISD::LMUL"; case XCoreISD::MACCU : return "XCoreISD::MACCU"; case XCoreISD::MACCS : return "XCoreISD::MACCS"; + case XCoreISD::CRC8 : return "XCoreISD::CRC8"; case XCoreISD::BR_JT : return "XCoreISD::BR_JT"; case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32"; default : return NULL; @@ -69,7 +69,7 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) Subtarget(*XTM.getSubtargetImpl()) { // Set up the register classes. - addRegisterClass(MVT::i32, XCore::GRRegsRegisterClass); + addRegisterClass(MVT::i32, &XCore::GRRegsRegClass); // Compute derived properties from the register classes computeRegisterProperties(); @@ -77,16 +77,16 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) // Division is expensive setIntDivIsCheap(false); - setShiftAmountType(MVT::i32); setStackPointerRegisterToSaveRestore(XCore::SP); - setSchedulingPreference(SchedulingForRegPressure); + setSchedulingPreference(Sched::RegPressure); // Use i32 for setcc operations results (slt, sgt, ...). setBooleanContents(ZeroOrOneBooleanContent); + setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? // XCore does not have the NodeTypes below. - setOperationAction(ISD::BR_CC, MVT::Other, Expand); + setOperationAction(ISD::BR_CC, MVT::i32, Expand); setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); setOperationAction(ISD::ADDC, MVT::i32, Expand); setOperationAction(ISD::ADDE, MVT::i32, Expand); @@ -95,7 +95,7 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) // Stop the combiner recombining select and set_cc setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); - + // 64bit setOperationAction(ISD::ADD, MVT::i64, Custom); setOperationAction(ISD::SUB, MVT::i64, Custom); @@ -106,23 +106,22 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); - + // Bit Manipulation setOperationAction(ISD::CTPOP, MVT::i32, Expand); setOperationAction(ISD::ROTL , MVT::i32, Expand); setOperationAction(ISD::ROTR , MVT::i32, Expand); - + setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand); + setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand); + setOperationAction(ISD::TRAP, MVT::Other, Legal); - + // Jump tables. setOperationAction(ISD::BR_JT, MVT::Other, Custom); setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::BlockAddress, MVT::i32 , Custom); - // Thread Local Storage - setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); - // Conversion of i64 -> double produces constantpool nodes setOperationAction(ISD::ConstantPool, MVT::i32, Custom); @@ -143,43 +142,54 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) setOperationAction(ISD::VACOPY, MVT::Other, Expand); setOperationAction(ISD::VAARG, MVT::Other, Custom); setOperationAction(ISD::VASTART, MVT::Other, Custom); - + // Dynamic stack setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); - - maxStoresPerMemset = 4; - maxStoresPerMemmove = maxStoresPerMemcpy = 2; + + // TRAMPOLINE is custom lowered. + setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom); + setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom); + + // We want to custom lower some of our intrinsics. + setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); + + MaxStoresPerMemset = MaxStoresPerMemsetOptSize = 4; + MaxStoresPerMemmove = MaxStoresPerMemmoveOptSize + = MaxStoresPerMemcpy = MaxStoresPerMemcpyOptSize = 2; // We have target-specific dag combine patterns for the following nodes: setTargetDAGCombine(ISD::STORE); setTargetDAGCombine(ISD::ADD); + + setMinFunctionAlignment(1); } SDValue XCoreTargetLowering:: -LowerOperation(SDValue Op, SelectionDAG &DAG) { - switch (Op.getOpcode()) +LowerOperation(SDValue Op, SelectionDAG &DAG) const { + switch (Op.getOpcode()) { - case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); - case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); - case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); - case ISD::ConstantPool: return LowerConstantPool(Op, DAG); - case ISD::BR_JT: return LowerBR_JT(Op, DAG); - case ISD::LOAD: return LowerLOAD(Op, DAG); - case ISD::STORE: return LowerSTORE(Op, DAG); - case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); - case ISD::VAARG: return LowerVAARG(Op, DAG); - case ISD::VASTART: return LowerVASTART(Op, DAG); - case ISD::SMUL_LOHI: return LowerSMUL_LOHI(Op, DAG); - case ISD::UMUL_LOHI: return LowerUMUL_LOHI(Op, DAG); + case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); + case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); + case ISD::ConstantPool: return LowerConstantPool(Op, DAG); + case ISD::BR_JT: return LowerBR_JT(Op, DAG); + case ISD::LOAD: return LowerLOAD(Op, DAG); + case ISD::STORE: return LowerSTORE(Op, DAG); + case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); + case ISD::VAARG: return LowerVAARG(Op, DAG); + case ISD::VASTART: return LowerVASTART(Op, DAG); + case ISD::SMUL_LOHI: return LowerSMUL_LOHI(Op, DAG); + case ISD::UMUL_LOHI: return LowerUMUL_LOHI(Op, DAG); // FIXME: Remove these when LegalizeDAGTypes lands. case ISD::ADD: - case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG); - case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); + case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG); + case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); + case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG); + case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG); + case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); default: llvm_unreachable("unimplemented operand"); - return SDValue(); } } @@ -187,11 +197,10 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) { /// type with new values built out of custom code. void XCoreTargetLowering::ReplaceNodeResults(SDNode *N, SmallVectorImpl&Results, - SelectionDAG &DAG) { + SelectionDAG &DAG) const { switch (N->getOpcode()) { default: llvm_unreachable("Don't know how to custom expand this!"); - return; case ISD::ADD: case ISD::SUB: Results.push_back(ExpandADDSUB(N, DAG)); @@ -199,20 +208,14 @@ void XCoreTargetLowering::ReplaceNodeResults(SDNode *N, } } -/// getFunctionAlignment - Return the Log2 alignment of this function. -unsigned XCoreTargetLowering:: -getFunctionAlignment(const Function *) const { - return 1; -} - //===----------------------------------------------------------------------===// // Misc Lower Operation implementation //===----------------------------------------------------------------------===// SDValue XCoreTargetLowering:: -LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) +LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); SDValue Cond = DAG.getNode(ISD::SETCC, dl, MVT::i32, Op.getOperand(2), Op.getOperand(3), Op.getOperand(4)); return DAG.getNode(ISD::SELECT, dl, MVT::i32, Cond, Op.getOperand(0), @@ -220,98 +223,64 @@ LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) } SDValue XCoreTargetLowering:: -getGlobalAddressWrapper(SDValue GA, GlobalValue *GV, SelectionDAG &DAG) +getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV, + SelectionDAG &DAG) const { // FIXME there is no actual debug info here - DebugLoc dl = GA.getDebugLoc(); - if (isa(GV)) { - return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA); + SDLoc dl(GA); + const GlobalValue *UnderlyingGV = GV; + // If GV is an alias then use the aliasee to determine the wrapper type + if (const GlobalAlias *GA = dyn_cast(GV)) + UnderlyingGV = GA->resolveAliasedGlobal(); + if (const GlobalVariable *GVar = dyn_cast(UnderlyingGV)) { + if (GVar->isConstant()) + return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, GA); + return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA); } - const GlobalVariable *GVar = dyn_cast(GV); - if (!GVar) { - // If GV is an alias then use the aliasee to determine constness - if (const GlobalAlias *GA = dyn_cast(GV)) - GVar = dyn_cast_or_null(GA->resolveAliasedGlobal()); - } - bool isConst = GVar && GVar->isConstant(); - if (isConst) { - return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, GA); - } - return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA); + return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA); } SDValue XCoreTargetLowering:: -LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) +LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { - GlobalValue *GV = cast(Op)->getGlobal(); - SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32); - // If it's a debug information descriptor, don't mess with it. - if (DAG.isVerifiedDebugInfoDesc(Op)) - return GA; - return getGlobalAddressWrapper(GA, GV, DAG); + SDLoc DL(Op); + const GlobalAddressSDNode *GN = cast(Op); + const GlobalValue *GV = GN->getGlobal(); + int64_t Offset = GN->getOffset(); + // We can only fold positive offsets that are a multiple of the word size. + int64_t FoldedOffset = std::max(Offset & ~3, (int64_t)0); + SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, FoldedOffset); + GA = getGlobalAddressWrapper(GA, GV, DAG); + // Handle the rest of the offset. + if (Offset != FoldedOffset) { + SDValue Remaining = DAG.getConstant(Offset - FoldedOffset, MVT::i32); + GA = DAG.getNode(ISD::ADD, DL, MVT::i32, GA, Remaining); + } + return GA; } -static inline SDValue BuildGetId(SelectionDAG &DAG, DebugLoc dl) { +static inline SDValue BuildGetId(SelectionDAG &DAG, SDLoc dl) { return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::i32, DAG.getConstant(Intrinsic::xcore_getid, MVT::i32)); } -static inline bool isZeroLengthArray(const Type *Ty) { - const ArrayType *AT = dyn_cast_or_null(Ty); - return AT && (AT->getNumElements() == 0); -} - -SDValue XCoreTargetLowering:: -LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) -{ - // FIXME there isn't really debug info here - DebugLoc dl = Op.getDebugLoc(); - // transform to label + getid() * size - GlobalValue *GV = cast(Op)->getGlobal(); - SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32); - const GlobalVariable *GVar = dyn_cast(GV); - if (!GVar) { - // If GV is an alias then use the aliasee to determine size - if (const GlobalAlias *GA = dyn_cast(GV)) - GVar = dyn_cast_or_null(GA->resolveAliasedGlobal()); - } - if (! GVar) { - llvm_unreachable("Thread local object not a GlobalVariable?"); - return SDValue(); - } - const Type *Ty = cast(GV->getType())->getElementType(); - if (!Ty->isSized() || isZeroLengthArray(Ty)) { -#ifndef NDEBUG - errs() << "Size of thread local object " << GVar->getName() - << " is unknown\n"; -#endif - llvm_unreachable(0); - } - SDValue base = getGlobalAddressWrapper(GA, GV, DAG); - const TargetData *TD = TM.getTargetData(); - unsigned Size = TD->getTypeAllocSize(Ty); - SDValue offset = DAG.getNode(ISD::MUL, dl, MVT::i32, BuildGetId(DAG, dl), - DAG.getConstant(Size, MVT::i32)); - return DAG.getNode(ISD::ADD, dl, MVT::i32, base, offset); -} - SDValue XCoreTargetLowering:: -LowerBlockAddress(SDValue Op, SelectionDAG &DAG) +LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); - BlockAddress *BA = cast(Op)->getBlockAddress(); - SDValue Result = DAG.getBlockAddress(BA, getPointerTy(), /*isTarget=*/true); + const BlockAddress *BA = cast(Op)->getBlockAddress(); + SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy()); return DAG.getNode(XCoreISD::PCRelativeWrapper, DL, getPointerTy(), Result); } SDValue XCoreTargetLowering:: -LowerConstantPool(SDValue Op, SelectionDAG &DAG) +LowerConstantPool(SDValue Op, SelectionDAG &DAG) const { ConstantPoolSDNode *CP = cast(Op); // FIXME there isn't really debug info here - DebugLoc dl = CP->getDebugLoc(); + SDLoc dl(CP); EVT PtrVT = Op.getValueType(); SDValue Res; if (CP->isMachineConstantPoolEntry()) { @@ -329,12 +298,12 @@ unsigned XCoreTargetLowering::getJumpTableEncoding() const { } SDValue XCoreTargetLowering:: -LowerBR_JT(SDValue Op, SelectionDAG &DAG) +LowerBR_JT(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); SDValue Table = Op.getOperand(1); SDValue Index = Op.getOperand(2); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); JumpTableSDNode *JT = cast(Table); unsigned JTI = JT->getIndex(); MachineFunction &MF = DAG.getMachineFunction(); @@ -352,149 +321,138 @@ LowerBR_JT(SDValue Op, SelectionDAG &DAG) ScaledIndex); } -static bool -IsWordAlignedBasePlusConstantOffset(SDValue Addr, SDValue &AlignedBase, - int64_t &Offset) +SDValue XCoreTargetLowering:: +lowerLoadWordFromAlignedBasePlusOffset(SDLoc DL, SDValue Chain, SDValue Base, + int64_t Offset, SelectionDAG &DAG) const { - if (Addr.getOpcode() != ISD::ADD) { - return false; - } - ConstantSDNode *CN = 0; - if (!(CN = dyn_cast(Addr.getOperand(1)))) { - return false; - } - int64_t off = CN->getSExtValue(); - const SDValue &Base = Addr.getOperand(0); - const SDValue *Root = &Base; - if (Base.getOpcode() == ISD::ADD && - Base.getOperand(1).getOpcode() == ISD::SHL) { - ConstantSDNode *CN = dyn_cast(Base.getOperand(1) - .getOperand(1)); - if (CN && (CN->getSExtValue() >= 2)) { - Root = &Base.getOperand(0); - } - } - if (isa(*Root)) { - // All frame indicies are word aligned - AlignedBase = Base; - Offset = off; - return true; + if ((Offset & 0x3) == 0) { + return DAG.getLoad(getPointerTy(), DL, Chain, Base, MachinePointerInfo(), + false, false, false, 0); } - if (Root->getOpcode() == XCoreISD::DPRelativeWrapper || - Root->getOpcode() == XCoreISD::CPRelativeWrapper) { - // All dp / cp relative addresses are word aligned - AlignedBase = Base; - Offset = off; - return true; + // Lower to pair of consecutive word aligned loads plus some bit shifting. + int32_t HighOffset = RoundUpToAlignment(Offset, 4); + int32_t LowOffset = HighOffset - 4; + SDValue LowAddr, HighAddr; + if (GlobalAddressSDNode *GASD = + dyn_cast(Base.getNode())) { + LowAddr = DAG.getGlobalAddress(GASD->getGlobal(), DL, Base.getValueType(), + LowOffset); + HighAddr = DAG.getGlobalAddress(GASD->getGlobal(), DL, Base.getValueType(), + HighOffset); + } else { + LowAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base, + DAG.getConstant(LowOffset, MVT::i32)); + HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base, + DAG.getConstant(HighOffset, MVT::i32)); } - return false; + SDValue LowShift = DAG.getConstant((Offset - LowOffset) * 8, MVT::i32); + SDValue HighShift = DAG.getConstant((HighOffset - Offset) * 8, MVT::i32); + + SDValue Low = DAG.getLoad(getPointerTy(), DL, Chain, + LowAddr, MachinePointerInfo(), + false, false, false, 0); + SDValue High = DAG.getLoad(getPointerTy(), DL, Chain, + HighAddr, MachinePointerInfo(), + false, false, false, 0); + SDValue LowShifted = DAG.getNode(ISD::SRL, DL, MVT::i32, Low, LowShift); + SDValue HighShifted = DAG.getNode(ISD::SHL, DL, MVT::i32, High, HighShift); + SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, LowShifted, HighShifted); + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Low.getValue(1), + High.getValue(1)); + SDValue Ops[] = { Result, Chain }; + return DAG.getMergeValues(Ops, 2, DL); } -SDValue XCoreTargetLowering:: -LowerLOAD(SDValue Op, SelectionDAG &DAG) +static bool isWordAligned(SDValue Value, SelectionDAG &DAG) { + APInt KnownZero, KnownOne; + DAG.ComputeMaskedBits(Value, KnownZero, KnownOne); + return KnownZero.countTrailingOnes() >= 2; +} + +SDValue XCoreTargetLowering:: +LowerLOAD(SDValue Op, SelectionDAG &DAG) const { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); LoadSDNode *LD = cast(Op); assert(LD->getExtensionType() == ISD::NON_EXTLOAD && "Unexpected extension type"); assert(LD->getMemoryVT() == MVT::i32 && "Unexpected load EVT"); - if (allowsUnalignedMemoryAccesses(LD->getMemoryVT())) { + if (allowsUnalignedMemoryAccesses(LD->getMemoryVT())) return SDValue(); - } - unsigned ABIAlignment = getTargetData()-> + + unsigned ABIAlignment = getDataLayout()-> getABITypeAlignment(LD->getMemoryVT().getTypeForEVT(*DAG.getContext())); // Leave aligned load alone. - if (LD->getAlignment() >= ABIAlignment) { + if (LD->getAlignment() >= ABIAlignment) return SDValue(); - } + SDValue Chain = LD->getChain(); SDValue BasePtr = LD->getBasePtr(); - DebugLoc dl = Op.getDebugLoc(); - - SDValue Base; - int64_t Offset; - if (!LD->isVolatile() && - IsWordAlignedBasePlusConstantOffset(BasePtr, Base, Offset)) { - if (Offset % 4 == 0) { - // We've managed to infer better alignment information than the load - // already has. Use an aligned load. - // - // FIXME: No new alignment information is actually passed here. - // Should the offset really be 4? - // - return DAG.getLoad(getPointerTy(), dl, Chain, BasePtr, NULL, 4, - false, false, 0); + SDLoc DL(Op); + + if (!LD->isVolatile()) { + const GlobalValue *GV; + int64_t Offset = 0; + if (DAG.isBaseWithConstantOffset(BasePtr) && + isWordAligned(BasePtr->getOperand(0), DAG)) { + SDValue NewBasePtr = BasePtr->getOperand(0); + Offset = cast(BasePtr->getOperand(1))->getSExtValue(); + return lowerLoadWordFromAlignedBasePlusOffset(DL, Chain, NewBasePtr, + Offset, DAG); + } + if (TLI.isGAPlusOffset(BasePtr.getNode(), GV, Offset) && + MinAlign(GV->getAlignment(), 4) == 4) { + SDValue NewBasePtr = DAG.getGlobalAddress(GV, DL, + BasePtr->getValueType(0)); + return lowerLoadWordFromAlignedBasePlusOffset(DL, Chain, NewBasePtr, + Offset, DAG); } - // Lower to - // ldw low, base[offset >> 2] - // ldw high, base[(offset >> 2) + 1] - // shr low_shifted, low, (offset & 0x3) * 8 - // shl high_shifted, high, 32 - (offset & 0x3) * 8 - // or result, low_shifted, high_shifted - SDValue LowOffset = DAG.getConstant(Offset & ~0x3, MVT::i32); - SDValue HighOffset = DAG.getConstant((Offset & ~0x3) + 4, MVT::i32); - SDValue LowShift = DAG.getConstant((Offset & 0x3) * 8, MVT::i32); - SDValue HighShift = DAG.getConstant(32 - (Offset & 0x3) * 8, MVT::i32); - - SDValue LowAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, Base, LowOffset); - SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, Base, HighOffset); - - SDValue Low = DAG.getLoad(getPointerTy(), dl, Chain, - LowAddr, NULL, 4, false, false, 0); - SDValue High = DAG.getLoad(getPointerTy(), dl, Chain, - HighAddr, NULL, 4, false, false, 0); - SDValue LowShifted = DAG.getNode(ISD::SRL, dl, MVT::i32, Low, LowShift); - SDValue HighShifted = DAG.getNode(ISD::SHL, dl, MVT::i32, High, HighShift); - SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, LowShifted, HighShifted); - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Low.getValue(1), - High.getValue(1)); - SDValue Ops[] = { Result, Chain }; - return DAG.getMergeValues(Ops, 2, dl); } - + if (LD->getAlignment() == 2) { - int SVOffset = LD->getSrcValueOffset(); - SDValue Low = DAG.getExtLoad(ISD::ZEXTLOAD, dl, MVT::i32, Chain, - BasePtr, LD->getSrcValue(), SVOffset, MVT::i16, + SDValue Low = DAG.getExtLoad(ISD::ZEXTLOAD, DL, MVT::i32, Chain, + BasePtr, LD->getPointerInfo(), MVT::i16, LD->isVolatile(), LD->isNonTemporal(), 2); - SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr, + SDValue HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr, DAG.getConstant(2, MVT::i32)); - SDValue High = DAG.getExtLoad(ISD::EXTLOAD, dl, MVT::i32, Chain, - HighAddr, LD->getSrcValue(), SVOffset + 2, + SDValue High = DAG.getExtLoad(ISD::EXTLOAD, DL, MVT::i32, Chain, + HighAddr, + LD->getPointerInfo().getWithOffset(2), MVT::i16, LD->isVolatile(), LD->isNonTemporal(), 2); - SDValue HighShifted = DAG.getNode(ISD::SHL, dl, MVT::i32, High, + SDValue HighShifted = DAG.getNode(ISD::SHL, DL, MVT::i32, High, DAG.getConstant(16, MVT::i32)); - SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, Low, HighShifted); - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Low.getValue(1), + SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Low, HighShifted); + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Low.getValue(1), High.getValue(1)); SDValue Ops[] = { Result, Chain }; - return DAG.getMergeValues(Ops, 2, dl); + return DAG.getMergeValues(Ops, 2, DL); } - + // Lower to a call to __misaligned_load(BasePtr). - const Type *IntPtrTy = getTargetData()->getIntPtrType(*DAG.getContext()); + Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext()); TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; - + Entry.Ty = IntPtrTy; Entry.Node = BasePtr; Args.push_back(Entry); - - std::pair CallResult = - LowerCallTo(Chain, IntPtrTy, false, false, - false, false, 0, CallingConv::C, false, - /*isReturnValueUsed=*/true, + + TargetLowering::CallLoweringInfo CLI(Chain, IntPtrTy, false, false, + false, false, 0, CallingConv::C, /*isTailCall=*/false, + /*doesNotRet=*/false, /*isReturnValueUsed=*/true, DAG.getExternalSymbol("__misaligned_load", getPointerTy()), - Args, DAG, dl); + Args, DAG, DL); + std::pair CallResult = LowerCallTo(CLI); SDValue Ops[] = { CallResult.first, CallResult.second }; - return DAG.getMergeValues(Ops, 2, dl); + return DAG.getMergeValues(Ops, 2, DL); } SDValue XCoreTargetLowering:: -LowerSTORE(SDValue Op, SelectionDAG &DAG) +LowerSTORE(SDValue Op, SelectionDAG &DAG) const { StoreSDNode *ST = cast(Op); assert(!ST->isTruncatingStore() && "Unexpected store type"); @@ -502,7 +460,7 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG) if (allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { return SDValue(); } - unsigned ABIAlignment = getTargetData()-> + unsigned ABIAlignment = getDataLayout()-> getABITypeAlignment(ST->getMemoryVT().getTypeForEVT(*DAG.getContext())); // Leave aligned store alone. if (ST->getAlignment() >= ABIAlignment) { @@ -511,54 +469,54 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG) SDValue Chain = ST->getChain(); SDValue BasePtr = ST->getBasePtr(); SDValue Value = ST->getValue(); - DebugLoc dl = Op.getDebugLoc(); - + SDLoc dl(Op); + if (ST->getAlignment() == 2) { - int SVOffset = ST->getSrcValueOffset(); SDValue Low = Value; SDValue High = DAG.getNode(ISD::SRL, dl, MVT::i32, Value, DAG.getConstant(16, MVT::i32)); SDValue StoreLow = DAG.getTruncStore(Chain, dl, Low, BasePtr, - ST->getSrcValue(), SVOffset, MVT::i16, + ST->getPointerInfo(), MVT::i16, ST->isVolatile(), ST->isNonTemporal(), 2); SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr, DAG.getConstant(2, MVT::i32)); SDValue StoreHigh = DAG.getTruncStore(Chain, dl, High, HighAddr, - ST->getSrcValue(), SVOffset + 2, + ST->getPointerInfo().getWithOffset(2), MVT::i16, ST->isVolatile(), ST->isNonTemporal(), 2); return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, StoreLow, StoreHigh); } - + // Lower to a call to __misaligned_store(BasePtr, Value). - const Type *IntPtrTy = getTargetData()->getIntPtrType(*DAG.getContext()); + Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext()); TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; - + Entry.Ty = IntPtrTy; Entry.Node = BasePtr; Args.push_back(Entry); - + Entry.Node = Value; Args.push_back(Entry); - - std::pair CallResult = - LowerCallTo(Chain, Type::getVoidTy(*DAG.getContext()), false, false, - false, false, 0, CallingConv::C, false, - /*isReturnValueUsed=*/true, + + TargetLowering::CallLoweringInfo CLI(Chain, + Type::getVoidTy(*DAG.getContext()), false, false, + false, false, 0, CallingConv::C, /*isTailCall=*/false, + /*doesNotRet=*/false, /*isReturnValueUsed=*/true, DAG.getExternalSymbol("__misaligned_store", getPointerTy()), Args, DAG, dl); + std::pair CallResult = LowerCallTo(CLI); return CallResult.second; } SDValue XCoreTargetLowering:: -LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) +LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const { assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::SMUL_LOHI && "Unexpected operand to lower!"); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); SDValue LHS = Op.getOperand(0); SDValue RHS = Op.getOperand(1); SDValue Zero = DAG.getConstant(0, MVT::i32); @@ -571,11 +529,11 @@ LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) } SDValue XCoreTargetLowering:: -LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) +LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const { assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::UMUL_LOHI && "Unexpected operand to lower!"); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); SDValue LHS = Op.getOperand(0); SDValue RHS = Op.getOperand(1); SDValue Zero = DAG.getConstant(0, MVT::i32); @@ -647,7 +605,7 @@ isADDADDMUL(SDValue Op, SDValue &Mul0, SDValue &Mul1, SDValue &Addend0, } SDValue XCoreTargetLowering:: -TryExpandADDWithMul(SDNode *N, SelectionDAG &DAG) +TryExpandADDWithMul(SDNode *N, SelectionDAG &DAG) const { SDValue Mul; SDValue Other; @@ -660,7 +618,7 @@ TryExpandADDWithMul(SDNode *N, SelectionDAG &DAG) } else { return SDValue(); } - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); SDValue LL, RL, AddendL, AddendH; LL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Mul.getOperand(0), DAG.getConstant(0, MVT::i32)); @@ -707,7 +665,7 @@ TryExpandADDWithMul(SDNode *N, SelectionDAG &DAG) } SDValue XCoreTargetLowering:: -ExpandADDSUB(SDNode *N, SelectionDAG &DAG) +ExpandADDSUB(SDNode *N, SelectionDAG &DAG) const { assert(N->getValueType(0) == MVT::i64 && (N->getOpcode() == ISD::ADD || N->getOpcode() == ISD::SUB) && @@ -719,8 +677,8 @@ ExpandADDSUB(SDNode *N, SelectionDAG &DAG) return Result; } - DebugLoc dl = N->getDebugLoc(); - + SDLoc dl(N); + // Extract components SDValue LHSL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), DAG.getConstant(0, MVT::i32)); @@ -730,70 +688,150 @@ ExpandADDSUB(SDNode *N, SelectionDAG &DAG) N->getOperand(1), DAG.getConstant(0, MVT::i32)); SDValue RHSH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(1), DAG.getConstant(1, MVT::i32)); - + // Expand unsigned Opcode = (N->getOpcode() == ISD::ADD) ? XCoreISD::LADD : XCoreISD::LSUB; SDValue Zero = DAG.getConstant(0, MVT::i32); - SDValue Carry = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32), - LHSL, RHSL, Zero); - SDValue Lo(Carry.getNode(), 1); - - SDValue Ignored = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32), - LHSH, RHSH, Carry); - SDValue Hi(Ignored.getNode(), 1); + SDValue Lo = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32), + LHSL, RHSL, Zero); + SDValue Carry(Lo.getNode(), 1); + + SDValue Hi = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32), + LHSH, RHSH, Carry); + SDValue Ignored(Hi.getNode(), 1); // Merge the pieces return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); } SDValue XCoreTargetLowering:: -LowerVAARG(SDValue Op, SelectionDAG &DAG) +LowerVAARG(SDValue Op, SelectionDAG &DAG) const { llvm_unreachable("unimplemented"); - // FIX Arguments passed by reference need a extra dereference. + // FIXME Arguments passed by reference need a extra dereference. SDNode *Node = Op.getNode(); - DebugLoc dl = Node->getDebugLoc(); + SDLoc dl(Node); const Value *V = cast(Node->getOperand(2))->getValue(); EVT VT = Node->getValueType(0); SDValue VAList = DAG.getLoad(getPointerTy(), dl, Node->getOperand(0), - Node->getOperand(1), V, 0, false, false, 0); + Node->getOperand(1), MachinePointerInfo(V), + false, false, false, 0); // Increment the pointer, VAList, to the next vararg - SDValue Tmp3 = DAG.getNode(ISD::ADD, dl, getPointerTy(), VAList, - DAG.getConstant(VT.getSizeInBits(), + SDValue Tmp3 = DAG.getNode(ISD::ADD, dl, getPointerTy(), VAList, + DAG.getConstant(VT.getSizeInBits(), getPointerTy())); // Store the incremented VAList to the legalized pointer - Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), V, 0, - false, false, 0); + Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), + MachinePointerInfo(V), false, false, 0); // Load the actual argument out of the pointer VAList - return DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0, false, false, 0); + return DAG.getLoad(VT, dl, Tmp3, VAList, MachinePointerInfo(), + false, false, false, 0); } SDValue XCoreTargetLowering:: -LowerVASTART(SDValue Op, SelectionDAG &DAG) +LowerVASTART(SDValue Op, SelectionDAG &DAG) const { - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); // vastart stores the address of the VarArgsFrameIndex slot into the // memory location argument MachineFunction &MF = DAG.getMachineFunction(); XCoreFunctionInfo *XFI = MF.getInfo(); SDValue Addr = DAG.getFrameIndex(XFI->getVarArgsFrameIndex(), MVT::i32); - const Value *SV = cast(Op.getOperand(2))->getValue(); - return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), SV, 0, - false, false, 0); + return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), + MachinePointerInfo(), false, false, 0); } -SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { - DebugLoc dl = Op.getDebugLoc(); - // Depths > 0 not supported yet! +SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, + SelectionDAG &DAG) const { + SDLoc dl(Op); + // Depths > 0 not supported yet! if (cast(Op.getOperand(0))->getZExtValue() > 0) return SDValue(); - + MachineFunction &MF = DAG.getMachineFunction(); const TargetRegisterInfo *RegInfo = getTargetMachine().getRegisterInfo(); - return DAG.getCopyFromReg(DAG.getEntryNode(), dl, + return DAG.getCopyFromReg(DAG.getEntryNode(), dl, RegInfo->getFrameRegister(MF), MVT::i32); } +SDValue XCoreTargetLowering:: +LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const { + return Op.getOperand(0); +} + +SDValue XCoreTargetLowering:: +LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const { + SDValue Chain = Op.getOperand(0); + SDValue Trmp = Op.getOperand(1); // trampoline + SDValue FPtr = Op.getOperand(2); // nested function + SDValue Nest = Op.getOperand(3); // 'nest' parameter value + + const Value *TrmpAddr = cast(Op.getOperand(4))->getValue(); + + // .align 4 + // LDAPF_u10 r11, nest + // LDW_2rus r11, r11[0] + // STWSP_ru6 r11, sp[0] + // LDAPF_u10 r11, fptr + // LDW_2rus r11, r11[0] + // BAU_1r r11 + // nest: + // .word nest + // fptr: + // .word fptr + SDValue OutChains[5]; + + SDValue Addr = Trmp; + + SDLoc dl(Op); + OutChains[0] = DAG.getStore(Chain, dl, DAG.getConstant(0x0a3cd805, MVT::i32), + Addr, MachinePointerInfo(TrmpAddr), false, false, + 0); + + Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, + DAG.getConstant(4, MVT::i32)); + OutChains[1] = DAG.getStore(Chain, dl, DAG.getConstant(0xd80456c0, MVT::i32), + Addr, MachinePointerInfo(TrmpAddr, 4), false, + false, 0); + + Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, + DAG.getConstant(8, MVT::i32)); + OutChains[2] = DAG.getStore(Chain, dl, DAG.getConstant(0x27fb0a3c, MVT::i32), + Addr, MachinePointerInfo(TrmpAddr, 8), false, + false, 0); + + Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, + DAG.getConstant(12, MVT::i32)); + OutChains[3] = DAG.getStore(Chain, dl, Nest, Addr, + MachinePointerInfo(TrmpAddr, 12), false, false, + 0); + + Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, + DAG.getConstant(16, MVT::i32)); + OutChains[4] = DAG.getStore(Chain, dl, FPtr, Addr, + MachinePointerInfo(TrmpAddr, 16), false, false, + 0); + + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains, 5); +} + +SDValue XCoreTargetLowering:: +LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { + SDLoc DL(Op); + unsigned IntNo = cast(Op.getOperand(0))->getZExtValue(); + switch (IntNo) { + case Intrinsic::xcore_crc8: + EVT VT = Op.getValueType(); + SDValue Data = + DAG.getNode(XCoreISD::CRC8, DL, DAG.getVTList(VT, VT), + Op.getOperand(1), Op.getOperand(2) , Op.getOperand(3)); + SDValue Crc(Data.getNode(), 1); + SDValue Results[] = { Crc, Data }; + return DAG.getMergeValues(Results, 2, DL); + } + return SDValue(); +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// @@ -806,13 +844,19 @@ SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { /// XCore call implementation SDValue -XCoreTargetLowering::LowerCall(SDValue Chain, SDValue Callee, - CallingConv::ID CallConv, bool isVarArg, - bool &isTailCall, - const SmallVectorImpl &Outs, - const SmallVectorImpl &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl &InVals) { +XCoreTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, + SmallVectorImpl &InVals) const { + SelectionDAG &DAG = CLI.DAG; + SDLoc &dl = CLI.DL; + SmallVector &Outs = CLI.Outs; + SmallVector &OutVals = CLI.OutVals; + SmallVector &Ins = CLI.Ins; + SDValue Chain = CLI.Chain; + SDValue Callee = CLI.Callee; + bool &isTailCall = CLI.IsTailCall; + CallingConv::ID CallConv = CLI.CallConv; + bool isVarArg = CLI.IsVarArg; + // XCore target does not yet support tail call optimization. isTailCall = false; @@ -824,7 +868,7 @@ XCoreTargetLowering::LowerCall(SDValue Chain, SDValue Callee, case CallingConv::Fast: case CallingConv::C: return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, - Outs, Ins, dl, DAG, InVals); + Outs, OutVals, Ins, dl, DAG, InVals); } } @@ -837,14 +881,15 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg, bool isTailCall, const SmallVectorImpl &Outs, + const SmallVectorImpl &OutVals, const SmallVectorImpl &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl &InVals) { + SDLoc dl, SelectionDAG &DAG, + SmallVectorImpl &InVals) const { // Analyze operands of the call, assigning locations to each operand. SmallVector ArgLocs; - CCState CCInfo(CallConv, isVarArg, getTargetMachine(), - ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), + getTargetMachine(), ArgLocs, *DAG.getContext()); // The ABI dictates there should be one stack slot available to the callee // on function entry (for saving lr). @@ -855,8 +900,8 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); - Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, - getPointerTy(), true)); + Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, + getPointerTy(), true), dl); SmallVector, 4> RegsToPass; SmallVector MemOpChains; @@ -864,7 +909,7 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - SDValue Arg = Outs[i].Val; + SDValue Arg = OutVals[i]; // Promote the value if needed. switch (VA.getLocInfo()) { @@ -880,8 +925,8 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); break; } - - // Arguments that can be passed on register must be kept at + + // Arguments that can be passed on register must be kept at // RegsToPass vector if (VA.isRegLoc()) { RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); @@ -890,7 +935,7 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, int Offset = VA.getLocMemOffset(); - MemOpChains.push_back(DAG.getNode(XCoreISD::STWSP, dl, MVT::Other, + MemOpChains.push_back(DAG.getNode(XCoreISD::STWSP, dl, MVT::Other, Chain, Arg, DAG.getConstant(Offset/4, MVT::i32))); } @@ -899,16 +944,16 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, // Transform all store nodes into one single node because // all store nodes are independent of each other. if (!MemOpChains.empty()) - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &MemOpChains[0], MemOpChains.size()); - // Build a sequence of copy-to-reg nodes chained together with token + // Build a sequence of copy-to-reg nodes chained together with token // chain and flag operands which copy the outgoing args into registers. - // The InFlag in necessary since all emited instructions must be + // The InFlag in necessary since all emitted instructions must be // stuck together. SDValue InFlag; for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { - Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, + Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, RegsToPass[i].second, InFlag); InFlag = Chain.getValue(1); } @@ -917,20 +962,20 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. // Likewise ExternalSymbol -> TargetExternalSymbol. if (GlobalAddressSDNode *G = dyn_cast(Callee)) - Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i32); + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32); else if (ExternalSymbolSDNode *E = dyn_cast(Callee)) Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32); // XCoreBranchLink = #chain, #target_address, #opt_in_flags... - // = Chain, Callee, Reg#1, Reg#2, ... + // = Chain, Callee, Reg#1, Reg#2, ... // // Returns a chain & a flag for retval copy to use. - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(Chain); Ops.push_back(Callee); - // Add argument registers to the end of the list so that they are + // Add argument registers to the end of the list so that they are // known live into the call. for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) Ops.push_back(DAG.getRegister(RegsToPass[i].first, @@ -946,7 +991,7 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, getPointerTy(), true), DAG.getConstant(0, getPointerTy(), true), - InFlag); + InFlag, dl); InFlag = Chain.getValue(1); // Handle result values, copying them out of physregs into vregs that we @@ -961,13 +1006,13 @@ SDValue XCoreTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl &InVals) { + SDLoc dl, SelectionDAG &DAG, + SmallVectorImpl &InVals) const { // Assign locations to each value returned by this call. SmallVector RVLocs; - CCState CCInfo(CallConv, isVarArg, getTargetMachine(), - RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), + getTargetMachine(), RVLocs, *DAG.getContext()); CCInfo.AnalyzeCallResult(Ins, RetCC_XCore); @@ -992,9 +1037,10 @@ XCoreTargetLowering::LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Ins, - DebugLoc dl, + SDLoc dl, SelectionDAG &DAG, - SmallVectorImpl &InVals) { + SmallVectorImpl &InVals) + const { switch (CallConv) { default: @@ -1016,28 +1062,28 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, bool isVarArg, const SmallVectorImpl &Ins, - DebugLoc dl, + SDLoc dl, SelectionDAG &DAG, - SmallVectorImpl &InVals) { + SmallVectorImpl &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); // Assign locations to all of the incoming arguments. SmallVector ArgLocs; - CCState CCInfo(CallConv, isVarArg, getTargetMachine(), - ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), + getTargetMachine(), ArgLocs, *DAG.getContext()); CCInfo.AnalyzeFormalArguments(Ins, CC_XCore); - unsigned StackSlotSize = XCoreFrameInfo::stackSlotSize(); + unsigned StackSlotSize = XCoreFrameLowering::stackSlotSize(); unsigned LRSaveSize = StackSlotSize; - + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - + if (VA.isRegLoc()) { // Arguments passed in registers EVT RegVT = VA.getLocVT(); @@ -1051,8 +1097,7 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, llvm_unreachable(0); } case MVT::i32: - unsigned VReg = RegInfo.createVirtualRegister( - XCore::GRRegsRegisterClass); + unsigned VReg = RegInfo.createVirtualRegister(&XCore::GRRegsRegClass); RegInfo.addLiveIn(VA.getLocReg(), VReg); InVals.push_back(DAG.getCopyFromReg(Chain, dl, VReg, RegVT)); } @@ -1063,25 +1108,26 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; if (ObjSize > StackSlotSize) { errs() << "LowerFormalArguments Unhandled argument type: " - << (unsigned)VA.getLocVT().getSimpleVT().SimpleTy + << EVT(VA.getLocVT()).getEVTString() << "\n"; } // Create the frame index object for this incoming parameter... int FI = MFI->CreateFixedObject(ObjSize, LRSaveSize + VA.getLocMemOffset(), - true, false); + true); // Create the SelectionDAG nodes corresponding to a load //from this parameter SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); - InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, NULL, 0, - false, false, 0)); + InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, + MachinePointerInfo::getFixedStack(FI), + false, false, false, 0)); } } - + if (isVarArg) { /* Argument registers */ - static const unsigned ArgRegs[] = { + static const uint16_t ArgRegs[] = { XCore::R0, XCore::R1, XCore::R2, XCore::R3 }; XCoreFunctionInfo *XFI = MF.getInfo(); @@ -1092,22 +1138,21 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, int offset = 0; // Save remaining registers, storing higher register numbers at a higher // address - for (unsigned i = array_lengthof(ArgRegs) - 1; i >= FirstVAReg; --i) { + for (int i = array_lengthof(ArgRegs) - 1; i >= (int)FirstVAReg; --i) { // Create a stack slot - int FI = MFI->CreateFixedObject(4, offset, true, false); - if (i == FirstVAReg) { + int FI = MFI->CreateFixedObject(4, offset, true); + if (i == (int)FirstVAReg) { XFI->setVarArgsFrameIndex(FI); } offset -= StackSlotSize; SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); // Move argument from phys reg -> virt reg - unsigned VReg = RegInfo.createVirtualRegister( - XCore::GRRegsRegisterClass); + unsigned VReg = RegInfo.createVirtualRegister(&XCore::GRRegsRegClass); RegInfo.addLiveIn(ArgRegs[i], VReg); SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); // Move argument from virt reg -> stack - SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0, - false, false, 0); + SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, + MachinePointerInfo(), false, false, 0); MemOps.push_back(Store); } if (!MemOps.empty()) @@ -1117,10 +1162,10 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, // This will point to the next argument passed via stack. XFI->setVarArgsFrameIndex( MFI->CreateFixedObject(4, LRSaveSize + CCInfo.getNextStackOffset(), - true, false)); + true)); } } - + return Chain; } @@ -1129,63 +1174,61 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, //===----------------------------------------------------------------------===// bool XCoreTargetLowering:: -CanLowerReturn(CallingConv::ID CallConv, bool isVarArg, - const SmallVectorImpl &OutTys, - const SmallVectorImpl &ArgsFlags, - SelectionDAG &DAG) { +CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, + bool isVarArg, + const SmallVectorImpl &Outs, + LLVMContext &Context) const { SmallVector RVLocs; - CCState CCInfo(CallConv, isVarArg, getTargetMachine(), - RVLocs, *DAG.getContext()); - return CCInfo.CheckReturn(OutTys, ArgsFlags, RetCC_XCore); + CCState CCInfo(CallConv, isVarArg, MF, getTargetMachine(), RVLocs, Context); + return CCInfo.CheckReturn(Outs, RetCC_XCore); } SDValue XCoreTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, - DebugLoc dl, SelectionDAG &DAG) { + const SmallVectorImpl &OutVals, + SDLoc dl, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of // the return value to a location SmallVector RVLocs; // CCState - Info about the registers and stack slot. - CCState CCInfo(CallConv, isVarArg, getTargetMachine(), - RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), + getTargetMachine(), RVLocs, *DAG.getContext()); - // Analize return values. + // Analyze return values. CCInfo.AnalyzeReturn(Outs, RetCC_XCore); - // If this is the first return lowered for this function, add - // the regs to the liveout set for the function. - if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { - for (unsigned i = 0; i != RVLocs.size(); ++i) - if (RVLocs[i].isRegLoc()) - DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); - } - SDValue Flag; + SmallVector RetOps(1, Chain); + + // Return on XCore is always a "retsp 0" + RetOps.push_back(DAG.getConstant(0, MVT::i32)); // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); - Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), - Outs[i].Val, Flag); + Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), + OutVals[i], Flag); // guarantee that all emitted copies are // stuck together, avoiding something bad Flag = Chain.getValue(1); + RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); } - // Return on XCore is always a "retsp 0" + RetOps[0] = Chain; // Update chain. + + // Add the flag if we have it. if (Flag.getNode()) - return DAG.getNode(XCoreISD::RETSP, dl, MVT::Other, - Chain, DAG.getConstant(0, MVT::i32), Flag); - else // Return Void - return DAG.getNode(XCoreISD::RETSP, dl, MVT::Other, - Chain, DAG.getConstant(0, MVT::i32)); + RetOps.push_back(Flag); + + return DAG.getNode(XCoreISD::RETSP, dl, MVT::Other, + &RetOps[0], RetOps.size()); } //===----------------------------------------------------------------------===// @@ -1194,13 +1237,12 @@ XCoreTargetLowering::LowerReturn(SDValue Chain, MachineBasicBlock * XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB, - DenseMap *EM) const { + MachineBasicBlock *BB) const { const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); DebugLoc dl = MI->getDebugLoc(); assert((MI->getOpcode() == XCore::SELECT_CC) && "Unexpected instr type to insert"); - + // To "insert" a SELECT_CC instruction, we actually have to insert the diamond // control-flow pattern. The incoming instruction knows the destination vreg // to set, the condition code register to branch on, the true/false values to @@ -1208,7 +1250,7 @@ XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, const BasicBlock *LLVM_BB = BB->getBasicBlock(); MachineFunction::iterator It = BB; ++It; - + // thisMBB: // ... // TrueVal = ... @@ -1219,43 +1261,40 @@ XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineFunction *F = BB->getParent(); MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); - BuildMI(BB, dl, TII.get(XCore::BRFT_lru6)) - .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB); F->insert(It, copy0MBB); F->insert(It, sinkMBB); - // Update machine-CFG edges by first adding all successors of the current - // block to the new block which will contain the Phi node for the select. - // Also inform sdisel of the edge changes. - for (MachineBasicBlock::succ_iterator I = BB->succ_begin(), - E = BB->succ_end(); I != E; ++I) { - EM->insert(std::make_pair(*I, sinkMBB)); - sinkMBB->addSuccessor(*I); - } - // Next, remove all successors of the current block, and add the true - // and fallthrough blocks as its successors. - while (!BB->succ_empty()) - BB->removeSuccessor(BB->succ_begin()); + + // Transfer the remainder of BB and its successor edges to sinkMBB. + sinkMBB->splice(sinkMBB->begin(), BB, + llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + sinkMBB->transferSuccessorsAndUpdatePHIs(BB); + // Next, add the true and fallthrough blocks as its successors. BB->addSuccessor(copy0MBB); BB->addSuccessor(sinkMBB); - + + BuildMI(BB, dl, TII.get(XCore::BRFT_lru6)) + .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB); + // copy0MBB: // %FalseValue = ... // # fallthrough to sinkMBB BB = copy0MBB; - + // Update machine-CFG edges BB->addSuccessor(sinkMBB); - + // sinkMBB: // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] // ... BB = sinkMBB; - BuildMI(BB, dl, TII.get(XCore::PHI), MI->getOperand(0).getReg()) + BuildMI(*BB, BB->begin(), dl, + TII.get(XCore::PHI), MI->getOperand(0).getReg()) .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB) .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB); - - F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. + + MI->eraseFromParent(); // The pseudo instruction is gone now. return BB; } @@ -1266,7 +1305,7 @@ XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); switch (N->getOpcode()) { default: break; case XCoreISD::LADD: { @@ -1286,21 +1325,21 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, SDValue Carry = DAG.getConstant(0, VT); SDValue Result = DAG.getNode(ISD::AND, dl, VT, N2, DAG.getConstant(1, VT)); - SDValue Ops [] = { Carry, Result }; + SDValue Ops[] = { Result, Carry }; return DAG.getMergeValues(Ops, 2, dl); } // fold (ladd x, 0, y) -> 0, add x, y iff carry is unused and y has only the // low bit set - if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 0)) { + if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 1)) { APInt KnownZero, KnownOne; APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), VT.getSizeInBits() - 1); - DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne); - if (KnownZero == Mask) { + DAG.ComputeMaskedBits(N2, KnownZero, KnownOne); + if ((KnownZero & Mask) == Mask) { SDValue Carry = DAG.getConstant(0, VT); SDValue Result = DAG.getNode(ISD::ADD, dl, VT, N0, N2); - SDValue Ops [] = { Carry, Result }; + SDValue Ops[] = { Result, Carry }; return DAG.getMergeValues(Ops, 2, dl); } } @@ -1315,31 +1354,31 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, EVT VT = N0.getValueType(); // fold (lsub 0, 0, x) -> x, -x iff x has only the low bit set - if (N0C && N0C->isNullValue() && N1C && N1C->isNullValue()) { + if (N0C && N0C->isNullValue() && N1C && N1C->isNullValue()) { APInt KnownZero, KnownOne; APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), VT.getSizeInBits() - 1); - DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne); - if (KnownZero == Mask) { + DAG.ComputeMaskedBits(N2, KnownZero, KnownOne); + if ((KnownZero & Mask) == Mask) { SDValue Borrow = N2; SDValue Result = DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(0, VT), N2); - SDValue Ops [] = { Borrow, Result }; + SDValue Ops[] = { Result, Borrow }; return DAG.getMergeValues(Ops, 2, dl); } } // fold (lsub x, 0, y) -> 0, sub x, y iff borrow is unused and y has only the // low bit set - if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 0)) { + if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 1)) { APInt KnownZero, KnownOne; APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), VT.getSizeInBits() - 1); - DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne); - if (KnownZero == Mask) { + DAG.ComputeMaskedBits(N2, KnownZero, KnownOne); + if ((KnownZero & Mask) == Mask) { SDValue Borrow = DAG.getConstant(0, VT); SDValue Result = DAG.getNode(ISD::SUB, dl, VT, N0, N2); - SDValue Ops [] = { Borrow, Result }; + SDValue Ops[] = { Result, Borrow }; return DAG.getMergeValues(Ops, 2, dl); } } @@ -1357,18 +1396,23 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, // operands are constant canonicalize smallest to RHS. if ((N0C && !N1C) || (N0C && N1C && N0C->getZExtValue() < N1C->getZExtValue())) - return DAG.getNode(XCoreISD::LMUL, dl, DAG.getVTList(VT, VT), N1, N0, N2, N3); + return DAG.getNode(XCoreISD::LMUL, dl, DAG.getVTList(VT, VT), + N1, N0, N2, N3); // lmul(x, 0, a, b) if (N1C && N1C->isNullValue()) { // If the high result is unused fold to add(a, b) if (N->hasNUsesOfValue(0, 0)) { SDValue Lo = DAG.getNode(ISD::ADD, dl, VT, N2, N3); - SDValue Ops [] = { Lo, Lo }; + SDValue Ops[] = { Lo, Lo }; return DAG.getMergeValues(Ops, 2, dl); } // Otherwise fold to ladd(a, b, 0) - return DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N2, N3, N1); + SDValue Result = + DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N2, N3, N1); + SDValue Carry(Result.getNode(), 1); + SDValue Ops[] = { Carry, Result }; + return DAG.getMergeValues(Ops, 2, dl); } } break; @@ -1380,7 +1424,6 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, SDValue Mul0, Mul1, Addend0, Addend1; if (N->getValueType(0) == MVT::i32 && isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, true)) { - SDValue Zero = DAG.getConstant(0, MVT::i32); SDValue Ignored = DAG.getNode(XCoreISD::LMUL, dl, DAG.getVTList(MVT::i32, MVT::i32), Mul0, Mul1, Addend0, Addend1); @@ -1428,7 +1471,7 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, if (StoreBits % 8) { break; } - unsigned ABIAlignment = getTargetData()->getABITypeAlignment( + unsigned ABIAlignment = getDataLayout()->getABITypeAlignment( ST->getMemoryVT().getTypeForEVT(*DCI.DAG.getContext())); unsigned Alignment = ST->getAlignment(); if (Alignment >= ABIAlignment) { @@ -1443,9 +1486,8 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, return DAG.getMemmove(Chain, dl, ST->getBasePtr(), LD->getBasePtr(), DAG.getConstant(StoreBits/8, MVT::i32), - Alignment, false, ST->getSrcValue(), - ST->getSrcValueOffset(), LD->getSrcValue(), - LD->getSrcValueOffset()); + Alignment, false, ST->getPointerInfo(), + LD->getPointerInfo()); } } break; @@ -1455,21 +1497,19 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, } void XCoreTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, - const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, unsigned Depth) const { - KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); + KnownZero = KnownOne = APInt(KnownZero.getBitWidth(), 0); switch (Op.getOpcode()) { default: break; case XCoreISD::LADD: case XCoreISD::LSUB: - if (Op.getResNo() == 0) { + if (Op.getResNo() == 1) { // Top bits of carry / borrow are clear. - KnownZero = APInt::getHighBitsSet(Mask.getBitWidth(), - Mask.getBitWidth() - 1); - KnownZero &= Mask; + KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(), + KnownZero.getBitWidth() - 1); } break; } @@ -1497,18 +1537,18 @@ static inline bool isImmUs4(int64_t val) /// isLegalAddressingMode - Return true if the addressing mode represented /// by AM is legal for this target, for a load/store of the specified type. bool -XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM, - const Type *Ty) const { +XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM, + Type *Ty) const { if (Ty->getTypeID() == Type::VoidTyID) return AM.Scale == 0 && isImmUs(AM.BaseOffs) && isImmUs4(AM.BaseOffs); - const TargetData *TD = TM.getTargetData(); + const DataLayout *TD = TM.getDataLayout(); unsigned Size = TD->getTypeAllocSize(Ty); if (AM.BaseGV) { return Size >= 4 && !AM.HasBaseReg && AM.Scale == 0 && AM.BaseOffs%4 == 0; } - + switch (Size) { case 1: // reg + imm @@ -1533,29 +1573,24 @@ XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM, // reg + reg<<2 return AM.Scale == 4 && AM.BaseOffs == 0; } - - return false; } //===----------------------------------------------------------------------===// // XCore Inline Assembly Support //===----------------------------------------------------------------------===// -std::vector XCoreTargetLowering:: -getRegClassForInlineAsmConstraint(const std::string &Constraint, - EVT VT) const -{ - if (Constraint.size() != 1) - return std::vector(); - - switch (Constraint[0]) { +std::pair +XCoreTargetLowering:: +getRegForInlineAsmConstraint(const std::string &Constraint, + MVT VT) const { + if (Constraint.size() == 1) { + switch (Constraint[0]) { default : break; case 'r': - return make_vector(XCore::R0, XCore::R1, XCore::R2, - XCore::R3, XCore::R4, XCore::R5, - XCore::R6, XCore::R7, XCore::R8, - XCore::R9, XCore::R10, XCore::R11, 0); - break; + return std::make_pair(0U, &XCore::GRRegsRegClass); + } } - return std::vector(); + // Use the default implementation in TargetLowering to convert the register + // constraint into a member of a register class. + return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); }