XCoreISelLowering.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1//===-- XCoreISelLowering.cpp - XCore DAG Lowering Implementation ---------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the XCoreTargetLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "xcore-lower" 15 16#include "XCoreISelLowering.h" 17#include "XCore.h" 18#include "XCoreMachineFunctionInfo.h" 19#include "XCoreSubtarget.h" 20#include "XCoreTargetMachine.h" 21#include "XCoreTargetObjectFile.h" 22#include "llvm/CodeGen/CallingConvLower.h" 23#include "llvm/CodeGen/MachineFrameInfo.h" 24#include "llvm/CodeGen/MachineFunction.h" 25#include "llvm/CodeGen/MachineInstrBuilder.h" 26#include "llvm/CodeGen/MachineJumpTableInfo.h" 27#include "llvm/CodeGen/MachineRegisterInfo.h" 28#include "llvm/CodeGen/SelectionDAGISel.h" 29#include "llvm/CodeGen/ValueTypes.h" 30#include "llvm/IR/CallingConv.h" 31#include "llvm/IR/Constants.h" 32#include "llvm/IR/DerivedTypes.h" 33#include "llvm/IR/Function.h" 34#include "llvm/IR/GlobalAlias.h" 35#include "llvm/IR/GlobalVariable.h" 36#include "llvm/IR/Intrinsics.h" 37#include "llvm/Support/Debug.h" 38#include "llvm/Support/ErrorHandling.h" 39#include "llvm/Support/raw_ostream.h" 40#include <algorithm> 41 42using namespace llvm; 43 44const char *XCoreTargetLowering:: 45getTargetNodeName(unsigned Opcode) const 46{ 47 switch (Opcode) 48 { 49 case XCoreISD::BL : return "XCoreISD::BL"; 50 case XCoreISD::PCRelativeWrapper : return "XCoreISD::PCRelativeWrapper"; 51 case XCoreISD::DPRelativeWrapper : return "XCoreISD::DPRelativeWrapper"; 52 case XCoreISD::CPRelativeWrapper : return "XCoreISD::CPRelativeWrapper"; 53 case XCoreISD::LDWSP : return "XCoreISD::LDWSP"; 54 case XCoreISD::STWSP : return "XCoreISD::STWSP"; 55 case XCoreISD::RETSP : return "XCoreISD::RETSP"; 56 case XCoreISD::LADD : return "XCoreISD::LADD"; 57 case XCoreISD::LSUB : return "XCoreISD::LSUB"; 58 case XCoreISD::LMUL : return "XCoreISD::LMUL"; 59 case XCoreISD::MACCU : return "XCoreISD::MACCU"; 60 case XCoreISD::MACCS : return "XCoreISD::MACCS"; 61 case XCoreISD::CRC8 : return "XCoreISD::CRC8"; 62 case XCoreISD::BR_JT : return "XCoreISD::BR_JT"; 63 case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32"; 64 case XCoreISD::FRAME_TO_ARGS_OFFSET : return "XCoreISD::FRAME_TO_ARGS_OFFSET"; 65 case XCoreISD::EH_RETURN : return "XCoreISD::EH_RETURN"; 66 case XCoreISD::MEMBARRIER : return "XCoreISD::MEMBARRIER"; 67 default : return NULL; 68 } 69} 70 71XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) 72 : TargetLowering(XTM, new XCoreTargetObjectFile()), 73 TM(XTM), 74 Subtarget(*XTM.getSubtargetImpl()) { 75 76 // Set up the register classes. 77 addRegisterClass(MVT::i32, &XCore::GRRegsRegClass); 78 79 // Compute derived properties from the register classes 80 computeRegisterProperties(); 81 82 // Division is expensive 83 setIntDivIsCheap(false); 84 85 setStackPointerRegisterToSaveRestore(XCore::SP); 86 87 setSchedulingPreference(Sched::Source); 88 89 // Use i32 for setcc operations results (slt, sgt, ...). 90 setBooleanContents(ZeroOrOneBooleanContent); 91 setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? 92 93 // XCore does not have the NodeTypes below. 94 setOperationAction(ISD::BR_CC, MVT::i32, Expand); 95 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 96 setOperationAction(ISD::ADDC, MVT::i32, Expand); 97 setOperationAction(ISD::ADDE, MVT::i32, Expand); 98 setOperationAction(ISD::SUBC, MVT::i32, Expand); 99 setOperationAction(ISD::SUBE, MVT::i32, Expand); 100 101 // Stop the combiner recombining select and set_cc 102 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); 103 104 // 64bit 105 setOperationAction(ISD::ADD, MVT::i64, Custom); 106 setOperationAction(ISD::SUB, MVT::i64, Custom); 107 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); 108 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); 109 setOperationAction(ISD::MULHS, MVT::i32, Expand); 110 setOperationAction(ISD::MULHU, MVT::i32, Expand); 111 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); 112 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); 113 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); 114 115 // Bit Manipulation 116 setOperationAction(ISD::CTPOP, MVT::i32, Expand); 117 setOperationAction(ISD::ROTL , MVT::i32, Expand); 118 setOperationAction(ISD::ROTR , MVT::i32, Expand); 119 setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand); 120 setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand); 121 122 setOperationAction(ISD::TRAP, MVT::Other, Legal); 123 124 // Jump tables. 125 setOperationAction(ISD::BR_JT, MVT::Other, Custom); 126 127 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 128 setOperationAction(ISD::BlockAddress, MVT::i32 , Custom); 129 130 // Conversion of i64 -> double produces constantpool nodes 131 setOperationAction(ISD::ConstantPool, MVT::i32, Custom); 132 133 // Loads 134 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 135 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 136 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 137 138 setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 139 setLoadExtAction(ISD::ZEXTLOAD, MVT::i16, Expand); 140 141 // Custom expand misaligned loads / stores. 142 setOperationAction(ISD::LOAD, MVT::i32, Custom); 143 setOperationAction(ISD::STORE, MVT::i32, Custom); 144 145 // Varargs 146 setOperationAction(ISD::VAEND, MVT::Other, Expand); 147 setOperationAction(ISD::VACOPY, MVT::Other, Expand); 148 setOperationAction(ISD::VAARG, MVT::Other, Custom); 149 setOperationAction(ISD::VASTART, MVT::Other, Custom); 150 151 // Dynamic stack 152 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); 153 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); 154 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); 155 156 // Exception handling 157 setOperationAction(ISD::EH_RETURN, MVT::Other, Custom); 158 setExceptionPointerRegister(XCore::R0); 159 setExceptionSelectorRegister(XCore::R1); 160 setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom); 161 162 // Atomic operations 163 // We request a fence for ATOMIC_* instructions, to reduce them to Monotonic. 164 // As we are always Sequential Consistent, an ATOMIC_FENCE becomes a no OP. 165 setInsertFencesForAtomic(true); 166 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); 167 setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Custom); 168 setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Custom); 169 170 // TRAMPOLINE is custom lowered. 171 setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom); 172 setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom); 173 174 // We want to custom lower some of our intrinsics. 175 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); 176 177 MaxStoresPerMemset = MaxStoresPerMemsetOptSize = 4; 178 MaxStoresPerMemmove = MaxStoresPerMemmoveOptSize 179 = MaxStoresPerMemcpy = MaxStoresPerMemcpyOptSize = 2; 180 181 // We have target-specific dag combine patterns for the following nodes: 182 setTargetDAGCombine(ISD::STORE); 183 setTargetDAGCombine(ISD::ADD); 184 setTargetDAGCombine(ISD::INTRINSIC_VOID); 185 setTargetDAGCombine(ISD::INTRINSIC_W_CHAIN); 186 187 setMinFunctionAlignment(1); 188 setPrefFunctionAlignment(2); 189} 190 191bool XCoreTargetLowering::isZExtFree(SDValue Val, EVT VT2) const { 192 if (Val.getOpcode() != ISD::LOAD) 193 return false; 194 195 EVT VT1 = Val.getValueType(); 196 if (!VT1.isSimple() || !VT1.isInteger() || 197 !VT2.isSimple() || !VT2.isInteger()) 198 return false; 199 200 switch (VT1.getSimpleVT().SimpleTy) { 201 default: break; 202 case MVT::i8: 203 return true; 204 } 205 206 return false; 207} 208 209SDValue XCoreTargetLowering:: 210LowerOperation(SDValue Op, SelectionDAG &DAG) const { 211 switch (Op.getOpcode()) 212 { 213 case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG); 214 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 215 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 216 case ISD::ConstantPool: return LowerConstantPool(Op, DAG); 217 case ISD::BR_JT: return LowerBR_JT(Op, DAG); 218 case ISD::LOAD: return LowerLOAD(Op, DAG); 219 case ISD::STORE: return LowerSTORE(Op, DAG); 220 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 221 case ISD::VAARG: return LowerVAARG(Op, DAG); 222 case ISD::VASTART: return LowerVASTART(Op, DAG); 223 case ISD::SMUL_LOHI: return LowerSMUL_LOHI(Op, DAG); 224 case ISD::UMUL_LOHI: return LowerUMUL_LOHI(Op, DAG); 225 // FIXME: Remove these when LegalizeDAGTypes lands. 226 case ISD::ADD: 227 case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG); 228 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 229 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); 230 case ISD::FRAME_TO_ARGS_OFFSET: return LowerFRAME_TO_ARGS_OFFSET(Op, DAG); 231 case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG); 232 case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG); 233 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); 234 case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG); 235 case ISD::ATOMIC_LOAD: return LowerATOMIC_LOAD(Op, DAG); 236 case ISD::ATOMIC_STORE: return LowerATOMIC_STORE(Op, DAG); 237 default: 238 llvm_unreachable("unimplemented operand"); 239 } 240} 241 242/// ReplaceNodeResults - Replace the results of node with an illegal result 243/// type with new values built out of custom code. 244void XCoreTargetLowering::ReplaceNodeResults(SDNode *N, 245 SmallVectorImpl<SDValue>&Results, 246 SelectionDAG &DAG) const { 247 switch (N->getOpcode()) { 248 default: 249 llvm_unreachable("Don't know how to custom expand this!"); 250 case ISD::ADD: 251 case ISD::SUB: 252 Results.push_back(ExpandADDSUB(N, DAG)); 253 return; 254 } 255} 256 257//===----------------------------------------------------------------------===// 258// Misc Lower Operation implementation 259//===----------------------------------------------------------------------===// 260 261SDValue XCoreTargetLowering:: 262LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const 263{ 264 SDLoc dl(Op); 265 SDValue Cond = DAG.getNode(ISD::SETCC, dl, MVT::i32, Op.getOperand(2), 266 Op.getOperand(3), Op.getOperand(4)); 267 return DAG.getNode(ISD::SELECT, dl, MVT::i32, Cond, Op.getOperand(0), 268 Op.getOperand(1)); 269} 270 271SDValue XCoreTargetLowering:: 272getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV, 273 SelectionDAG &DAG) const 274{ 275 // FIXME there is no actual debug info here 276 SDLoc dl(GA); 277 const GlobalValue *UnderlyingGV = GV; 278 // If GV is an alias then use the aliasee to determine the wrapper type 279 if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) 280 UnderlyingGV = GA->getAliasedGlobal(); 281 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(UnderlyingGV)) { 282 if ( ( GVar->isConstant() && 283 UnderlyingGV->isLocalLinkage(GV->getLinkage()) ) 284 || ( GVar->hasSection() && 285 StringRef(GVar->getSection()).startswith(".cp.") ) ) 286 return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, GA); 287 return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA); 288 } 289 return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA); 290} 291 292static bool IsSmallObject(const GlobalValue *GV, const XCoreTargetLowering &XTL) { 293 if (XTL.getTargetMachine().getCodeModel() == CodeModel::Small) 294 return true; 295 296 Type *ObjType = GV->getType()->getPointerElementType(); 297 if (!ObjType->isSized()) 298 return false; 299 300 unsigned ObjSize = XTL.getDataLayout()->getTypeAllocSize(ObjType); 301 return ObjSize < CodeModelLargeSize && ObjSize != 0; 302} 303 304SDValue XCoreTargetLowering:: 305LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const 306{ 307 const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op); 308 const GlobalValue *GV = GN->getGlobal(); 309 SDLoc DL(GN); 310 int64_t Offset = GN->getOffset(); 311 if (IsSmallObject(GV, *this)) { 312 // We can only fold positive offsets that are a multiple of the word size. 313 int64_t FoldedOffset = std::max(Offset & ~3, (int64_t)0); 314 SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, FoldedOffset); 315 GA = getGlobalAddressWrapper(GA, GV, DAG); 316 // Handle the rest of the offset. 317 if (Offset != FoldedOffset) { 318 SDValue Remaining = DAG.getConstant(Offset - FoldedOffset, MVT::i32); 319 GA = DAG.getNode(ISD::ADD, DL, MVT::i32, GA, Remaining); 320 } 321 return GA; 322 } else { 323 // Ideally we would not fold in offset with an index <= 11. 324 Type *Ty = Type::getInt8PtrTy(*DAG.getContext()); 325 Constant *GA = ConstantExpr::getBitCast(const_cast<GlobalValue*>(GV), Ty); 326 Ty = Type::getInt32Ty(*DAG.getContext()); 327 Constant *Idx = ConstantInt::get(Ty, Offset); 328 Constant *GAI = ConstantExpr::getGetElementPtr(GA, Idx); 329 SDValue CP = DAG.getConstantPool(GAI, MVT::i32); 330 return DAG.getLoad(getPointerTy(), DL, DAG.getEntryNode(), CP, 331 MachinePointerInfo(), false, false, false, 0); 332 } 333} 334 335SDValue XCoreTargetLowering:: 336LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const 337{ 338 SDLoc DL(Op); 339 340 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); 341 SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy()); 342 343 return DAG.getNode(XCoreISD::PCRelativeWrapper, DL, getPointerTy(), Result); 344} 345 346SDValue XCoreTargetLowering:: 347LowerConstantPool(SDValue Op, SelectionDAG &DAG) const 348{ 349 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 350 // FIXME there isn't really debug info here 351 SDLoc dl(CP); 352 EVT PtrVT = Op.getValueType(); 353 SDValue Res; 354 if (CP->isMachineConstantPoolEntry()) { 355 Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, 356 CP->getAlignment(), CP->getOffset()); 357 } else { 358 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, 359 CP->getAlignment(), CP->getOffset()); 360 } 361 return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, Res); 362} 363 364unsigned XCoreTargetLowering::getJumpTableEncoding() const { 365 return MachineJumpTableInfo::EK_Inline; 366} 367 368SDValue XCoreTargetLowering:: 369LowerBR_JT(SDValue Op, SelectionDAG &DAG) const 370{ 371 SDValue Chain = Op.getOperand(0); 372 SDValue Table = Op.getOperand(1); 373 SDValue Index = Op.getOperand(2); 374 SDLoc dl(Op); 375 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table); 376 unsigned JTI = JT->getIndex(); 377 MachineFunction &MF = DAG.getMachineFunction(); 378 const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); 379 SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32); 380 381 unsigned NumEntries = MJTI->getJumpTables()[JTI].MBBs.size(); 382 if (NumEntries <= 32) { 383 return DAG.getNode(XCoreISD::BR_JT, dl, MVT::Other, Chain, TargetJT, Index); 384 } 385 assert((NumEntries >> 31) == 0); 386 SDValue ScaledIndex = DAG.getNode(ISD::SHL, dl, MVT::i32, Index, 387 DAG.getConstant(1, MVT::i32)); 388 return DAG.getNode(XCoreISD::BR_JT32, dl, MVT::Other, Chain, TargetJT, 389 ScaledIndex); 390} 391 392SDValue XCoreTargetLowering:: 393lowerLoadWordFromAlignedBasePlusOffset(SDLoc DL, SDValue Chain, SDValue Base, 394 int64_t Offset, SelectionDAG &DAG) const 395{ 396 if ((Offset & 0x3) == 0) { 397 return DAG.getLoad(getPointerTy(), DL, Chain, Base, MachinePointerInfo(), 398 false, false, false, 0); 399 } 400 // Lower to pair of consecutive word aligned loads plus some bit shifting. 401 int32_t HighOffset = RoundUpToAlignment(Offset, 4); 402 int32_t LowOffset = HighOffset - 4; 403 SDValue LowAddr, HighAddr; 404 if (GlobalAddressSDNode *GASD = 405 dyn_cast<GlobalAddressSDNode>(Base.getNode())) { 406 LowAddr = DAG.getGlobalAddress(GASD->getGlobal(), DL, Base.getValueType(), 407 LowOffset); 408 HighAddr = DAG.getGlobalAddress(GASD->getGlobal(), DL, Base.getValueType(), 409 HighOffset); 410 } else { 411 LowAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base, 412 DAG.getConstant(LowOffset, MVT::i32)); 413 HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base, 414 DAG.getConstant(HighOffset, MVT::i32)); 415 } 416 SDValue LowShift = DAG.getConstant((Offset - LowOffset) * 8, MVT::i32); 417 SDValue HighShift = DAG.getConstant((HighOffset - Offset) * 8, MVT::i32); 418 419 SDValue Low = DAG.getLoad(getPointerTy(), DL, Chain, 420 LowAddr, MachinePointerInfo(), 421 false, false, false, 0); 422 SDValue High = DAG.getLoad(getPointerTy(), DL, Chain, 423 HighAddr, MachinePointerInfo(), 424 false, false, false, 0); 425 SDValue LowShifted = DAG.getNode(ISD::SRL, DL, MVT::i32, Low, LowShift); 426 SDValue HighShifted = DAG.getNode(ISD::SHL, DL, MVT::i32, High, HighShift); 427 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, LowShifted, HighShifted); 428 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Low.getValue(1), 429 High.getValue(1)); 430 SDValue Ops[] = { Result, Chain }; 431 return DAG.getMergeValues(Ops, 2, DL); 432} 433 434static bool isWordAligned(SDValue Value, SelectionDAG &DAG) 435{ 436 APInt KnownZero, KnownOne; 437 DAG.ComputeMaskedBits(Value, KnownZero, KnownOne); 438 return KnownZero.countTrailingOnes() >= 2; 439} 440 441SDValue XCoreTargetLowering:: 442LowerLOAD(SDValue Op, SelectionDAG &DAG) const { 443 const TargetLowering &TLI = DAG.getTargetLoweringInfo(); 444 LoadSDNode *LD = cast<LoadSDNode>(Op); 445 assert(LD->getExtensionType() == ISD::NON_EXTLOAD && 446 "Unexpected extension type"); 447 assert(LD->getMemoryVT() == MVT::i32 && "Unexpected load EVT"); 448 if (allowsUnalignedMemoryAccesses(LD->getMemoryVT())) 449 return SDValue(); 450 451 unsigned ABIAlignment = getDataLayout()-> 452 getABITypeAlignment(LD->getMemoryVT().getTypeForEVT(*DAG.getContext())); 453 // Leave aligned load alone. 454 if (LD->getAlignment() >= ABIAlignment) 455 return SDValue(); 456 457 SDValue Chain = LD->getChain(); 458 SDValue BasePtr = LD->getBasePtr(); 459 SDLoc DL(Op); 460 461 if (!LD->isVolatile()) { 462 const GlobalValue *GV; 463 int64_t Offset = 0; 464 if (DAG.isBaseWithConstantOffset(BasePtr) && 465 isWordAligned(BasePtr->getOperand(0), DAG)) { 466 SDValue NewBasePtr = BasePtr->getOperand(0); 467 Offset = cast<ConstantSDNode>(BasePtr->getOperand(1))->getSExtValue(); 468 return lowerLoadWordFromAlignedBasePlusOffset(DL, Chain, NewBasePtr, 469 Offset, DAG); 470 } 471 if (TLI.isGAPlusOffset(BasePtr.getNode(), GV, Offset) && 472 MinAlign(GV->getAlignment(), 4) == 4) { 473 SDValue NewBasePtr = DAG.getGlobalAddress(GV, DL, 474 BasePtr->getValueType(0)); 475 return lowerLoadWordFromAlignedBasePlusOffset(DL, Chain, NewBasePtr, 476 Offset, DAG); 477 } 478 } 479 480 if (LD->getAlignment() == 2) { 481 SDValue Low = DAG.getExtLoad(ISD::ZEXTLOAD, DL, MVT::i32, Chain, 482 BasePtr, LD->getPointerInfo(), MVT::i16, 483 LD->isVolatile(), LD->isNonTemporal(), 2); 484 SDValue HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr, 485 DAG.getConstant(2, MVT::i32)); 486 SDValue High = DAG.getExtLoad(ISD::EXTLOAD, DL, MVT::i32, Chain, 487 HighAddr, 488 LD->getPointerInfo().getWithOffset(2), 489 MVT::i16, LD->isVolatile(), 490 LD->isNonTemporal(), 2); 491 SDValue HighShifted = DAG.getNode(ISD::SHL, DL, MVT::i32, High, 492 DAG.getConstant(16, MVT::i32)); 493 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Low, HighShifted); 494 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Low.getValue(1), 495 High.getValue(1)); 496 SDValue Ops[] = { Result, Chain }; 497 return DAG.getMergeValues(Ops, 2, DL); 498 } 499 500 // Lower to a call to __misaligned_load(BasePtr). 501 Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext()); 502 TargetLowering::ArgListTy Args; 503 TargetLowering::ArgListEntry Entry; 504 505 Entry.Ty = IntPtrTy; 506 Entry.Node = BasePtr; 507 Args.push_back(Entry); 508 509 TargetLowering::CallLoweringInfo CLI(Chain, IntPtrTy, false, false, 510 false, false, 0, CallingConv::C, /*isTailCall=*/false, 511 /*doesNotRet=*/false, /*isReturnValueUsed=*/true, 512 DAG.getExternalSymbol("__misaligned_load", getPointerTy()), 513 Args, DAG, DL); 514 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI); 515 516 SDValue Ops[] = 517 { CallResult.first, CallResult.second }; 518 519 return DAG.getMergeValues(Ops, 2, DL); 520} 521 522SDValue XCoreTargetLowering:: 523LowerSTORE(SDValue Op, SelectionDAG &DAG) const 524{ 525 StoreSDNode *ST = cast<StoreSDNode>(Op); 526 assert(!ST->isTruncatingStore() && "Unexpected store type"); 527 assert(ST->getMemoryVT() == MVT::i32 && "Unexpected store EVT"); 528 if (allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { 529 return SDValue(); 530 } 531 unsigned ABIAlignment = getDataLayout()-> 532 getABITypeAlignment(ST->getMemoryVT().getTypeForEVT(*DAG.getContext())); 533 // Leave aligned store alone. 534 if (ST->getAlignment() >= ABIAlignment) { 535 return SDValue(); 536 } 537 SDValue Chain = ST->getChain(); 538 SDValue BasePtr = ST->getBasePtr(); 539 SDValue Value = ST->getValue(); 540 SDLoc dl(Op); 541 542 if (ST->getAlignment() == 2) { 543 SDValue Low = Value; 544 SDValue High = DAG.getNode(ISD::SRL, dl, MVT::i32, Value, 545 DAG.getConstant(16, MVT::i32)); 546 SDValue StoreLow = DAG.getTruncStore(Chain, dl, Low, BasePtr, 547 ST->getPointerInfo(), MVT::i16, 548 ST->isVolatile(), ST->isNonTemporal(), 549 2); 550 SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr, 551 DAG.getConstant(2, MVT::i32)); 552 SDValue StoreHigh = DAG.getTruncStore(Chain, dl, High, HighAddr, 553 ST->getPointerInfo().getWithOffset(2), 554 MVT::i16, ST->isVolatile(), 555 ST->isNonTemporal(), 2); 556 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, StoreLow, StoreHigh); 557 } 558 559 // Lower to a call to __misaligned_store(BasePtr, Value). 560 Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext()); 561 TargetLowering::ArgListTy Args; 562 TargetLowering::ArgListEntry Entry; 563 564 Entry.Ty = IntPtrTy; 565 Entry.Node = BasePtr; 566 Args.push_back(Entry); 567 568 Entry.Node = Value; 569 Args.push_back(Entry); 570 571 TargetLowering::CallLoweringInfo CLI(Chain, 572 Type::getVoidTy(*DAG.getContext()), false, false, 573 false, false, 0, CallingConv::C, /*isTailCall=*/false, 574 /*doesNotRet=*/false, /*isReturnValueUsed=*/true, 575 DAG.getExternalSymbol("__misaligned_store", getPointerTy()), 576 Args, DAG, dl); 577 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI); 578 579 return CallResult.second; 580} 581 582SDValue XCoreTargetLowering:: 583LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const 584{ 585 assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::SMUL_LOHI && 586 "Unexpected operand to lower!"); 587 SDLoc dl(Op); 588 SDValue LHS = Op.getOperand(0); 589 SDValue RHS = Op.getOperand(1); 590 SDValue Zero = DAG.getConstant(0, MVT::i32); 591 SDValue Hi = DAG.getNode(XCoreISD::MACCS, dl, 592 DAG.getVTList(MVT::i32, MVT::i32), Zero, Zero, 593 LHS, RHS); 594 SDValue Lo(Hi.getNode(), 1); 595 SDValue Ops[] = { Lo, Hi }; 596 return DAG.getMergeValues(Ops, 2, dl); 597} 598 599SDValue XCoreTargetLowering:: 600LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const 601{ 602 assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::UMUL_LOHI && 603 "Unexpected operand to lower!"); 604 SDLoc dl(Op); 605 SDValue LHS = Op.getOperand(0); 606 SDValue RHS = Op.getOperand(1); 607 SDValue Zero = DAG.getConstant(0, MVT::i32); 608 SDValue Hi = DAG.getNode(XCoreISD::LMUL, dl, 609 DAG.getVTList(MVT::i32, MVT::i32), LHS, RHS, 610 Zero, Zero); 611 SDValue Lo(Hi.getNode(), 1); 612 SDValue Ops[] = { Lo, Hi }; 613 return DAG.getMergeValues(Ops, 2, dl); 614} 615 616/// isADDADDMUL - Return whether Op is in a form that is equivalent to 617/// add(add(mul(x,y),a),b). If requireIntermediatesHaveOneUse is true then 618/// each intermediate result in the calculation must also have a single use. 619/// If the Op is in the correct form the constituent parts are written to Mul0, 620/// Mul1, Addend0 and Addend1. 621static bool 622isADDADDMUL(SDValue Op, SDValue &Mul0, SDValue &Mul1, SDValue &Addend0, 623 SDValue &Addend1, bool requireIntermediatesHaveOneUse) 624{ 625 if (Op.getOpcode() != ISD::ADD) 626 return false; 627 SDValue N0 = Op.getOperand(0); 628 SDValue N1 = Op.getOperand(1); 629 SDValue AddOp; 630 SDValue OtherOp; 631 if (N0.getOpcode() == ISD::ADD) { 632 AddOp = N0; 633 OtherOp = N1; 634 } else if (N1.getOpcode() == ISD::ADD) { 635 AddOp = N1; 636 OtherOp = N0; 637 } else { 638 return false; 639 } 640 if (requireIntermediatesHaveOneUse && !AddOp.hasOneUse()) 641 return false; 642 if (OtherOp.getOpcode() == ISD::MUL) { 643 // add(add(a,b),mul(x,y)) 644 if (requireIntermediatesHaveOneUse && !OtherOp.hasOneUse()) 645 return false; 646 Mul0 = OtherOp.getOperand(0); 647 Mul1 = OtherOp.getOperand(1); 648 Addend0 = AddOp.getOperand(0); 649 Addend1 = AddOp.getOperand(1); 650 return true; 651 } 652 if (AddOp.getOperand(0).getOpcode() == ISD::MUL) { 653 // add(add(mul(x,y),a),b) 654 if (requireIntermediatesHaveOneUse && !AddOp.getOperand(0).hasOneUse()) 655 return false; 656 Mul0 = AddOp.getOperand(0).getOperand(0); 657 Mul1 = AddOp.getOperand(0).getOperand(1); 658 Addend0 = AddOp.getOperand(1); 659 Addend1 = OtherOp; 660 return true; 661 } 662 if (AddOp.getOperand(1).getOpcode() == ISD::MUL) { 663 // add(add(a,mul(x,y)),b) 664 if (requireIntermediatesHaveOneUse && !AddOp.getOperand(1).hasOneUse()) 665 return false; 666 Mul0 = AddOp.getOperand(1).getOperand(0); 667 Mul1 = AddOp.getOperand(1).getOperand(1); 668 Addend0 = AddOp.getOperand(0); 669 Addend1 = OtherOp; 670 return true; 671 } 672 return false; 673} 674 675SDValue XCoreTargetLowering:: 676TryExpandADDWithMul(SDNode *N, SelectionDAG &DAG) const 677{ 678 SDValue Mul; 679 SDValue Other; 680 if (N->getOperand(0).getOpcode() == ISD::MUL) { 681 Mul = N->getOperand(0); 682 Other = N->getOperand(1); 683 } else if (N->getOperand(1).getOpcode() == ISD::MUL) { 684 Mul = N->getOperand(1); 685 Other = N->getOperand(0); 686 } else { 687 return SDValue(); 688 } 689 SDLoc dl(N); 690 SDValue LL, RL, AddendL, AddendH; 691 LL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 692 Mul.getOperand(0), DAG.getConstant(0, MVT::i32)); 693 RL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 694 Mul.getOperand(1), DAG.getConstant(0, MVT::i32)); 695 AddendL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 696 Other, DAG.getConstant(0, MVT::i32)); 697 AddendH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 698 Other, DAG.getConstant(1, MVT::i32)); 699 APInt HighMask = APInt::getHighBitsSet(64, 32); 700 unsigned LHSSB = DAG.ComputeNumSignBits(Mul.getOperand(0)); 701 unsigned RHSSB = DAG.ComputeNumSignBits(Mul.getOperand(1)); 702 if (DAG.MaskedValueIsZero(Mul.getOperand(0), HighMask) && 703 DAG.MaskedValueIsZero(Mul.getOperand(1), HighMask)) { 704 // The inputs are both zero-extended. 705 SDValue Hi = DAG.getNode(XCoreISD::MACCU, dl, 706 DAG.getVTList(MVT::i32, MVT::i32), AddendH, 707 AddendL, LL, RL); 708 SDValue Lo(Hi.getNode(), 1); 709 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 710 } 711 if (LHSSB > 32 && RHSSB > 32) { 712 // The inputs are both sign-extended. 713 SDValue Hi = DAG.getNode(XCoreISD::MACCS, dl, 714 DAG.getVTList(MVT::i32, MVT::i32), AddendH, 715 AddendL, LL, RL); 716 SDValue Lo(Hi.getNode(), 1); 717 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 718 } 719 SDValue LH, RH; 720 LH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 721 Mul.getOperand(0), DAG.getConstant(1, MVT::i32)); 722 RH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 723 Mul.getOperand(1), DAG.getConstant(1, MVT::i32)); 724 SDValue Hi = DAG.getNode(XCoreISD::MACCU, dl, 725 DAG.getVTList(MVT::i32, MVT::i32), AddendH, 726 AddendL, LL, RL); 727 SDValue Lo(Hi.getNode(), 1); 728 RH = DAG.getNode(ISD::MUL, dl, MVT::i32, LL, RH); 729 LH = DAG.getNode(ISD::MUL, dl, MVT::i32, LH, RL); 730 Hi = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, RH); 731 Hi = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, LH); 732 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 733} 734 735SDValue XCoreTargetLowering:: 736ExpandADDSUB(SDNode *N, SelectionDAG &DAG) const 737{ 738 assert(N->getValueType(0) == MVT::i64 && 739 (N->getOpcode() == ISD::ADD || N->getOpcode() == ISD::SUB) && 740 "Unknown operand to lower!"); 741 742 if (N->getOpcode() == ISD::ADD) { 743 SDValue Result = TryExpandADDWithMul(N, DAG); 744 if (Result.getNode() != 0) 745 return Result; 746 } 747 748 SDLoc dl(N); 749 750 // Extract components 751 SDValue LHSL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 752 N->getOperand(0), DAG.getConstant(0, MVT::i32)); 753 SDValue LHSH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 754 N->getOperand(0), DAG.getConstant(1, MVT::i32)); 755 SDValue RHSL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 756 N->getOperand(1), DAG.getConstant(0, MVT::i32)); 757 SDValue RHSH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 758 N->getOperand(1), DAG.getConstant(1, MVT::i32)); 759 760 // Expand 761 unsigned Opcode = (N->getOpcode() == ISD::ADD) ? XCoreISD::LADD : 762 XCoreISD::LSUB; 763 SDValue Zero = DAG.getConstant(0, MVT::i32); 764 SDValue Lo = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32), 765 LHSL, RHSL, Zero); 766 SDValue Carry(Lo.getNode(), 1); 767 768 SDValue Hi = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32), 769 LHSH, RHSH, Carry); 770 SDValue Ignored(Hi.getNode(), 1); 771 // Merge the pieces 772 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 773} 774 775SDValue XCoreTargetLowering:: 776LowerVAARG(SDValue Op, SelectionDAG &DAG) const 777{ 778 // Whist llvm does not support aggregate varargs we can ignore 779 // the possibility of the ValueType being an implicit byVal vararg. 780 SDNode *Node = Op.getNode(); 781 EVT VT = Node->getValueType(0); // not an aggregate 782 SDValue InChain = Node->getOperand(0); 783 SDValue VAListPtr = Node->getOperand(1); 784 EVT PtrVT = VAListPtr.getValueType(); 785 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 786 SDLoc dl(Node); 787 SDValue VAList = DAG.getLoad(PtrVT, dl, InChain, 788 VAListPtr, MachinePointerInfo(SV), 789 false, false, false, 0); 790 // Increment the pointer, VAList, to the next vararg 791 SDValue nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, VAList, 792 DAG.getIntPtrConstant(VT.getSizeInBits() / 8)); 793 // Store the incremented VAList to the legalized pointer 794 InChain = DAG.getStore(VAList.getValue(1), dl, nextPtr, VAListPtr, 795 MachinePointerInfo(SV), false, false, 0); 796 // Load the actual argument out of the pointer VAList 797 return DAG.getLoad(VT, dl, InChain, VAList, MachinePointerInfo(), 798 false, false, false, 0); 799} 800 801SDValue XCoreTargetLowering:: 802LowerVASTART(SDValue Op, SelectionDAG &DAG) const 803{ 804 SDLoc dl(Op); 805 // vastart stores the address of the VarArgsFrameIndex slot into the 806 // memory location argument 807 MachineFunction &MF = DAG.getMachineFunction(); 808 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 809 SDValue Addr = DAG.getFrameIndex(XFI->getVarArgsFrameIndex(), MVT::i32); 810 return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), 811 MachinePointerInfo(), false, false, 0); 812} 813 814SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, 815 SelectionDAG &DAG) const { 816 // This nodes represent llvm.frameaddress on the DAG. 817 // It takes one operand, the index of the frame address to return. 818 // An index of zero corresponds to the current function's frame address. 819 // An index of one to the parent's frame address, and so on. 820 // Depths > 0 not supported yet! 821 if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0) 822 return SDValue(); 823 824 MachineFunction &MF = DAG.getMachineFunction(); 825 const TargetRegisterInfo *RegInfo = getTargetMachine().getRegisterInfo(); 826 return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), 827 RegInfo->getFrameRegister(MF), MVT::i32); 828} 829 830SDValue XCoreTargetLowering:: 831LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const { 832 // This nodes represent llvm.returnaddress on the DAG. 833 // It takes one operand, the index of the return address to return. 834 // An index of zero corresponds to the current function's return address. 835 // An index of one to the parent's return address, and so on. 836 // Depths > 0 not supported yet! 837 if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0) 838 return SDValue(); 839 840 MachineFunction &MF = DAG.getMachineFunction(); 841 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 842 int FI = XFI->createLRSpillSlot(MF); 843 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 844 return DAG.getLoad(getPointerTy(), SDLoc(Op), DAG.getEntryNode(), FIN, 845 MachinePointerInfo::getFixedStack(FI), false, false, 846 false, 0); 847} 848 849SDValue XCoreTargetLowering:: 850LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const { 851 // This node represents offset from frame pointer to first on-stack argument. 852 // This is needed for correct stack adjustment during unwind. 853 // However, we don't know the offset until after the frame has be finalised. 854 // This is done during the XCoreFTAOElim pass. 855 return DAG.getNode(XCoreISD::FRAME_TO_ARGS_OFFSET, SDLoc(Op), MVT::i32); 856} 857 858SDValue XCoreTargetLowering:: 859LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const { 860 // OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) 861 // This node represents 'eh_return' gcc dwarf builtin, which is used to 862 // return from exception. The general meaning is: adjust stack by OFFSET and 863 // pass execution to HANDLER. 864 MachineFunction &MF = DAG.getMachineFunction(); 865 SDValue Chain = Op.getOperand(0); 866 SDValue Offset = Op.getOperand(1); 867 SDValue Handler = Op.getOperand(2); 868 SDLoc dl(Op); 869 870 // Absolute SP = (FP + FrameToArgs) + Offset 871 const TargetRegisterInfo *RegInfo = getTargetMachine().getRegisterInfo(); 872 SDValue Stack = DAG.getCopyFromReg(DAG.getEntryNode(), dl, 873 RegInfo->getFrameRegister(MF), MVT::i32); 874 SDValue FrameToArgs = DAG.getNode(XCoreISD::FRAME_TO_ARGS_OFFSET, dl, 875 MVT::i32); 876 Stack = DAG.getNode(ISD::ADD, dl, MVT::i32, Stack, FrameToArgs); 877 Stack = DAG.getNode(ISD::ADD, dl, MVT::i32, Stack, Offset); 878 879 // R0=ExceptionPointerRegister R1=ExceptionSelectorRegister 880 // which leaves 2 caller saved registers, R2 & R3 for us to use. 881 unsigned StackReg = XCore::R2; 882 unsigned HandlerReg = XCore::R3; 883 884 SDValue OutChains[] = { 885 DAG.getCopyToReg(Chain, dl, StackReg, Stack), 886 DAG.getCopyToReg(Chain, dl, HandlerReg, Handler) 887 }; 888 889 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains, 2); 890 891 return DAG.getNode(XCoreISD::EH_RETURN, dl, MVT::Other, Chain, 892 DAG.getRegister(StackReg, MVT::i32), 893 DAG.getRegister(HandlerReg, MVT::i32)); 894 895} 896 897SDValue XCoreTargetLowering:: 898LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const { 899 return Op.getOperand(0); 900} 901 902SDValue XCoreTargetLowering:: 903LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const { 904 SDValue Chain = Op.getOperand(0); 905 SDValue Trmp = Op.getOperand(1); // trampoline 906 SDValue FPtr = Op.getOperand(2); // nested function 907 SDValue Nest = Op.getOperand(3); // 'nest' parameter value 908 909 const Value *TrmpAddr = cast<SrcValueSDNode>(Op.getOperand(4))->getValue(); 910 911 // .align 4 912 // LDAPF_u10 r11, nest 913 // LDW_2rus r11, r11[0] 914 // STWSP_ru6 r11, sp[0] 915 // LDAPF_u10 r11, fptr 916 // LDW_2rus r11, r11[0] 917 // BAU_1r r11 918 // nest: 919 // .word nest 920 // fptr: 921 // .word fptr 922 SDValue OutChains[5]; 923 924 SDValue Addr = Trmp; 925 926 SDLoc dl(Op); 927 OutChains[0] = DAG.getStore(Chain, dl, DAG.getConstant(0x0a3cd805, MVT::i32), 928 Addr, MachinePointerInfo(TrmpAddr), false, false, 929 0); 930 931 Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, 932 DAG.getConstant(4, MVT::i32)); 933 OutChains[1] = DAG.getStore(Chain, dl, DAG.getConstant(0xd80456c0, MVT::i32), 934 Addr, MachinePointerInfo(TrmpAddr, 4), false, 935 false, 0); 936 937 Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, 938 DAG.getConstant(8, MVT::i32)); 939 OutChains[2] = DAG.getStore(Chain, dl, DAG.getConstant(0x27fb0a3c, MVT::i32), 940 Addr, MachinePointerInfo(TrmpAddr, 8), false, 941 false, 0); 942 943 Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, 944 DAG.getConstant(12, MVT::i32)); 945 OutChains[3] = DAG.getStore(Chain, dl, Nest, Addr, 946 MachinePointerInfo(TrmpAddr, 12), false, false, 947 0); 948 949 Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, 950 DAG.getConstant(16, MVT::i32)); 951 OutChains[4] = DAG.getStore(Chain, dl, FPtr, Addr, 952 MachinePointerInfo(TrmpAddr, 16), false, false, 953 0); 954 955 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains, 5); 956} 957 958SDValue XCoreTargetLowering:: 959LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { 960 SDLoc DL(Op); 961 unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 962 switch (IntNo) { 963 case Intrinsic::xcore_crc8: 964 EVT VT = Op.getValueType(); 965 SDValue Data = 966 DAG.getNode(XCoreISD::CRC8, DL, DAG.getVTList(VT, VT), 967 Op.getOperand(1), Op.getOperand(2) , Op.getOperand(3)); 968 SDValue Crc(Data.getNode(), 1); 969 SDValue Results[] = { Crc, Data }; 970 return DAG.getMergeValues(Results, 2, DL); 971 } 972 return SDValue(); 973} 974 975SDValue XCoreTargetLowering:: 976LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const { 977 SDLoc DL(Op); 978 return DAG.getNode(XCoreISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0)); 979} 980 981SDValue XCoreTargetLowering:: 982LowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const { 983 AtomicSDNode *N = cast<AtomicSDNode>(Op); 984 assert(N->getOpcode() == ISD::ATOMIC_LOAD && "Bad Atomic OP"); 985 assert(N->getOrdering() <= Monotonic && 986 "setInsertFencesForAtomic(true) and yet greater than Monotonic"); 987 if (N->getMemoryVT() == MVT::i32) { 988 if (N->getAlignment() < 4) 989 report_fatal_error("atomic load must be aligned"); 990 return DAG.getLoad(getPointerTy(), SDLoc(Op), N->getChain(), 991 N->getBasePtr(), N->getPointerInfo(), 992 N->isVolatile(), N->isNonTemporal(), 993 N->isInvariant(), N->getAlignment(), 994 N->getTBAAInfo(), N->getRanges()); 995 } 996 if (N->getMemoryVT() == MVT::i16) { 997 if (N->getAlignment() < 2) 998 report_fatal_error("atomic load must be aligned"); 999 return DAG.getExtLoad(ISD::EXTLOAD, SDLoc(Op), MVT::i32, N->getChain(), 1000 N->getBasePtr(), N->getPointerInfo(), MVT::i16, 1001 N->isVolatile(), N->isNonTemporal(), 1002 N->getAlignment(), N->getTBAAInfo()); 1003 } 1004 if (N->getMemoryVT() == MVT::i8) 1005 return DAG.getExtLoad(ISD::EXTLOAD, SDLoc(Op), MVT::i32, N->getChain(), 1006 N->getBasePtr(), N->getPointerInfo(), MVT::i8, 1007 N->isVolatile(), N->isNonTemporal(), 1008 N->getAlignment(), N->getTBAAInfo()); 1009 return SDValue(); 1010} 1011 1012SDValue XCoreTargetLowering:: 1013LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const { 1014 AtomicSDNode *N = cast<AtomicSDNode>(Op); 1015 assert(N->getOpcode() == ISD::ATOMIC_STORE && "Bad Atomic OP"); 1016 assert(N->getOrdering() <= Monotonic && 1017 "setInsertFencesForAtomic(true) and yet greater than Monotonic"); 1018 if (N->getMemoryVT() == MVT::i32) { 1019 if (N->getAlignment() < 4) 1020 report_fatal_error("atomic store must be aligned"); 1021 return DAG.getStore(N->getChain(), SDLoc(Op), N->getVal(), 1022 N->getBasePtr(), N->getPointerInfo(), 1023 N->isVolatile(), N->isNonTemporal(), 1024 N->getAlignment(), N->getTBAAInfo()); 1025 } 1026 if (N->getMemoryVT() == MVT::i16) { 1027 if (N->getAlignment() < 2) 1028 report_fatal_error("atomic store must be aligned"); 1029 return DAG.getTruncStore(N->getChain(), SDLoc(Op), N->getVal(), 1030 N->getBasePtr(), N->getPointerInfo(), MVT::i16, 1031 N->isVolatile(), N->isNonTemporal(), 1032 N->getAlignment(), N->getTBAAInfo()); 1033 } 1034 if (N->getMemoryVT() == MVT::i8) 1035 return DAG.getTruncStore(N->getChain(), SDLoc(Op), N->getVal(), 1036 N->getBasePtr(), N->getPointerInfo(), MVT::i8, 1037 N->isVolatile(), N->isNonTemporal(), 1038 N->getAlignment(), N->getTBAAInfo()); 1039 return SDValue(); 1040} 1041 1042//===----------------------------------------------------------------------===// 1043// Calling Convention Implementation 1044//===----------------------------------------------------------------------===// 1045 1046#include "XCoreGenCallingConv.inc" 1047 1048//===----------------------------------------------------------------------===// 1049// Call Calling Convention Implementation 1050//===----------------------------------------------------------------------===// 1051 1052/// XCore call implementation 1053SDValue 1054XCoreTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 1055 SmallVectorImpl<SDValue> &InVals) const { 1056 SelectionDAG &DAG = CLI.DAG; 1057 SDLoc &dl = CLI.DL; 1058 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; 1059 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; 1060 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; 1061 SDValue Chain = CLI.Chain; 1062 SDValue Callee = CLI.Callee; 1063 bool &isTailCall = CLI.IsTailCall; 1064 CallingConv::ID CallConv = CLI.CallConv; 1065 bool isVarArg = CLI.IsVarArg; 1066 1067 // XCore target does not yet support tail call optimization. 1068 isTailCall = false; 1069 1070 // For now, only CallingConv::C implemented 1071 switch (CallConv) 1072 { 1073 default: 1074 llvm_unreachable("Unsupported calling convention"); 1075 case CallingConv::Fast: 1076 case CallingConv::C: 1077 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 1078 Outs, OutVals, Ins, dl, DAG, InVals); 1079 } 1080} 1081 1082/// LowerCallResult - Lower the result values of a call into the 1083/// appropriate copies out of appropriate physical registers / memory locations. 1084static SDValue 1085LowerCallResult(SDValue Chain, SDValue InFlag, 1086 const SmallVectorImpl<CCValAssign> &RVLocs, 1087 SDLoc dl, SelectionDAG &DAG, 1088 SmallVectorImpl<SDValue> &InVals) { 1089 SmallVector<std::pair<int, unsigned>, 4> ResultMemLocs; 1090 // Copy results out of physical registers. 1091 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { 1092 const CCValAssign &VA = RVLocs[i]; 1093 if (VA.isRegLoc()) { 1094 Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getValVT(), 1095 InFlag).getValue(1); 1096 InFlag = Chain.getValue(2); 1097 InVals.push_back(Chain.getValue(0)); 1098 } else { 1099 assert(VA.isMemLoc()); 1100 ResultMemLocs.push_back(std::make_pair(VA.getLocMemOffset(), 1101 InVals.size())); 1102 // Reserve space for this result. 1103 InVals.push_back(SDValue()); 1104 } 1105 } 1106 1107 // Copy results out of memory. 1108 SmallVector<SDValue, 4> MemOpChains; 1109 for (unsigned i = 0, e = ResultMemLocs.size(); i != e; ++i) { 1110 int offset = ResultMemLocs[i].first; 1111 unsigned index = ResultMemLocs[i].second; 1112 SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other); 1113 SDValue Ops[] = { Chain, DAG.getConstant(offset / 4, MVT::i32) }; 1114 SDValue load = DAG.getNode(XCoreISD::LDWSP, dl, VTs, Ops, 2); 1115 InVals[index] = load; 1116 MemOpChains.push_back(load.getValue(1)); 1117 } 1118 1119 // Transform all loads nodes into one single node because 1120 // all load nodes are independent of each other. 1121 if (!MemOpChains.empty()) 1122 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1123 &MemOpChains[0], MemOpChains.size()); 1124 1125 return Chain; 1126} 1127 1128/// LowerCCCCallTo - functions arguments are copied from virtual 1129/// regs to (physical regs)/(stack frame), CALLSEQ_START and 1130/// CALLSEQ_END are emitted. 1131/// TODO: isTailCall, sret. 1132SDValue 1133XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 1134 CallingConv::ID CallConv, bool isVarArg, 1135 bool isTailCall, 1136 const SmallVectorImpl<ISD::OutputArg> &Outs, 1137 const SmallVectorImpl<SDValue> &OutVals, 1138 const SmallVectorImpl<ISD::InputArg> &Ins, 1139 SDLoc dl, SelectionDAG &DAG, 1140 SmallVectorImpl<SDValue> &InVals) const { 1141 1142 // Analyze operands of the call, assigning locations to each operand. 1143 SmallVector<CCValAssign, 16> ArgLocs; 1144 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 1145 getTargetMachine(), ArgLocs, *DAG.getContext()); 1146 1147 // The ABI dictates there should be one stack slot available to the callee 1148 // on function entry (for saving lr). 1149 CCInfo.AllocateStack(4, 4); 1150 1151 CCInfo.AnalyzeCallOperands(Outs, CC_XCore); 1152 1153 SmallVector<CCValAssign, 16> RVLocs; 1154 // Analyze return values to determine the number of bytes of stack required. 1155 CCState RetCCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 1156 getTargetMachine(), RVLocs, *DAG.getContext()); 1157 RetCCInfo.AllocateStack(CCInfo.getNextStackOffset(), 4); 1158 RetCCInfo.AnalyzeCallResult(Ins, RetCC_XCore); 1159 1160 // Get a count of how many bytes are to be pushed on the stack. 1161 unsigned NumBytes = RetCCInfo.getNextStackOffset(); 1162 1163 Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, 1164 getPointerTy(), true), dl); 1165 1166 SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 1167 SmallVector<SDValue, 12> MemOpChains; 1168 1169 // Walk the register/memloc assignments, inserting copies/loads. 1170 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 1171 CCValAssign &VA = ArgLocs[i]; 1172 SDValue Arg = OutVals[i]; 1173 1174 // Promote the value if needed. 1175 switch (VA.getLocInfo()) { 1176 default: llvm_unreachable("Unknown loc info!"); 1177 case CCValAssign::Full: break; 1178 case CCValAssign::SExt: 1179 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 1180 break; 1181 case CCValAssign::ZExt: 1182 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 1183 break; 1184 case CCValAssign::AExt: 1185 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 1186 break; 1187 } 1188 1189 // Arguments that can be passed on register must be kept at 1190 // RegsToPass vector 1191 if (VA.isRegLoc()) { 1192 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 1193 } else { 1194 assert(VA.isMemLoc()); 1195 1196 int Offset = VA.getLocMemOffset(); 1197 1198 MemOpChains.push_back(DAG.getNode(XCoreISD::STWSP, dl, MVT::Other, 1199 Chain, Arg, 1200 DAG.getConstant(Offset/4, MVT::i32))); 1201 } 1202 } 1203 1204 // Transform all store nodes into one single node because 1205 // all store nodes are independent of each other. 1206 if (!MemOpChains.empty()) 1207 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1208 &MemOpChains[0], MemOpChains.size()); 1209 1210 // Build a sequence of copy-to-reg nodes chained together with token 1211 // chain and flag operands which copy the outgoing args into registers. 1212 // The InFlag in necessary since all emitted instructions must be 1213 // stuck together. 1214 SDValue InFlag; 1215 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 1216 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 1217 RegsToPass[i].second, InFlag); 1218 InFlag = Chain.getValue(1); 1219 } 1220 1221 // If the callee is a GlobalAddress node (quite common, every direct call is) 1222 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 1223 // Likewise ExternalSymbol -> TargetExternalSymbol. 1224 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 1225 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32); 1226 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 1227 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32); 1228 1229 // XCoreBranchLink = #chain, #target_address, #opt_in_flags... 1230 // = Chain, Callee, Reg#1, Reg#2, ... 1231 // 1232 // Returns a chain & a flag for retval copy to use. 1233 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 1234 SmallVector<SDValue, 8> Ops; 1235 Ops.push_back(Chain); 1236 Ops.push_back(Callee); 1237 1238 // Add argument registers to the end of the list so that they are 1239 // known live into the call. 1240 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 1241 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 1242 RegsToPass[i].second.getValueType())); 1243 1244 if (InFlag.getNode()) 1245 Ops.push_back(InFlag); 1246 1247 Chain = DAG.getNode(XCoreISD::BL, dl, NodeTys, &Ops[0], Ops.size()); 1248 InFlag = Chain.getValue(1); 1249 1250 // Create the CALLSEQ_END node. 1251 Chain = DAG.getCALLSEQ_END(Chain, 1252 DAG.getConstant(NumBytes, getPointerTy(), true), 1253 DAG.getConstant(0, getPointerTy(), true), 1254 InFlag, dl); 1255 InFlag = Chain.getValue(1); 1256 1257 // Handle result values, copying them out of physregs into vregs that we 1258 // return. 1259 return LowerCallResult(Chain, InFlag, RVLocs, dl, DAG, InVals); 1260} 1261 1262//===----------------------------------------------------------------------===// 1263// Formal Arguments Calling Convention Implementation 1264//===----------------------------------------------------------------------===// 1265 1266namespace { 1267 struct ArgDataPair { SDValue SDV; ISD::ArgFlagsTy Flags; }; 1268} 1269 1270/// XCore formal arguments implementation 1271SDValue 1272XCoreTargetLowering::LowerFormalArguments(SDValue Chain, 1273 CallingConv::ID CallConv, 1274 bool isVarArg, 1275 const SmallVectorImpl<ISD::InputArg> &Ins, 1276 SDLoc dl, 1277 SelectionDAG &DAG, 1278 SmallVectorImpl<SDValue> &InVals) 1279 const { 1280 switch (CallConv) 1281 { 1282 default: 1283 llvm_unreachable("Unsupported calling convention"); 1284 case CallingConv::C: 1285 case CallingConv::Fast: 1286 return LowerCCCArguments(Chain, CallConv, isVarArg, 1287 Ins, dl, DAG, InVals); 1288 } 1289} 1290 1291/// LowerCCCArguments - transform physical registers into 1292/// virtual registers and generate load operations for 1293/// arguments places on the stack. 1294/// TODO: sret 1295SDValue 1296XCoreTargetLowering::LowerCCCArguments(SDValue Chain, 1297 CallingConv::ID CallConv, 1298 bool isVarArg, 1299 const SmallVectorImpl<ISD::InputArg> 1300 &Ins, 1301 SDLoc dl, 1302 SelectionDAG &DAG, 1303 SmallVectorImpl<SDValue> &InVals) const { 1304 MachineFunction &MF = DAG.getMachineFunction(); 1305 MachineFrameInfo *MFI = MF.getFrameInfo(); 1306 MachineRegisterInfo &RegInfo = MF.getRegInfo(); 1307 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 1308 1309 // Assign locations to all of the incoming arguments. 1310 SmallVector<CCValAssign, 16> ArgLocs; 1311 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 1312 getTargetMachine(), ArgLocs, *DAG.getContext()); 1313 1314 CCInfo.AnalyzeFormalArguments(Ins, CC_XCore); 1315 1316 unsigned StackSlotSize = XCoreFrameLowering::stackSlotSize(); 1317 1318 unsigned LRSaveSize = StackSlotSize; 1319 1320 if (!isVarArg) 1321 XFI->setReturnStackOffset(CCInfo.getNextStackOffset() + LRSaveSize); 1322 1323 // All getCopyFromReg ops must precede any getMemcpys to prevent the 1324 // scheduler clobbering a register before it has been copied. 1325 // The stages are: 1326 // 1. CopyFromReg (and load) arg & vararg registers. 1327 // 2. Chain CopyFromReg nodes into a TokenFactor. 1328 // 3. Memcpy 'byVal' args & push final InVals. 1329 // 4. Chain mem ops nodes into a TokenFactor. 1330 SmallVector<SDValue, 4> CFRegNode; 1331 SmallVector<ArgDataPair, 4> ArgData; 1332 SmallVector<SDValue, 4> MemOps; 1333 1334 // 1a. CopyFromReg (and load) arg registers. 1335 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 1336 1337 CCValAssign &VA = ArgLocs[i]; 1338 SDValue ArgIn; 1339 1340 if (VA.isRegLoc()) { 1341 // Arguments passed in registers 1342 EVT RegVT = VA.getLocVT(); 1343 switch (RegVT.getSimpleVT().SimpleTy) { 1344 default: 1345 { 1346#ifndef NDEBUG 1347 errs() << "LowerFormalArguments Unhandled argument type: " 1348 << RegVT.getSimpleVT().SimpleTy << "\n"; 1349#endif 1350 llvm_unreachable(0); 1351 } 1352 case MVT::i32: 1353 unsigned VReg = RegInfo.createVirtualRegister(&XCore::GRRegsRegClass); 1354 RegInfo.addLiveIn(VA.getLocReg(), VReg); 1355 ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 1356 CFRegNode.push_back(ArgIn.getValue(ArgIn->getNumValues() - 1)); 1357 } 1358 } else { 1359 // sanity check 1360 assert(VA.isMemLoc()); 1361 // Load the argument to a virtual register 1362 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 1363 if (ObjSize > StackSlotSize) { 1364 errs() << "LowerFormalArguments Unhandled argument type: " 1365 << EVT(VA.getLocVT()).getEVTString() 1366 << "\n"; 1367 } 1368 // Create the frame index object for this incoming parameter... 1369 int FI = MFI->CreateFixedObject(ObjSize, 1370 LRSaveSize + VA.getLocMemOffset(), 1371 true); 1372 1373 // Create the SelectionDAG nodes corresponding to a load 1374 //from this parameter 1375 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 1376 ArgIn = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 1377 MachinePointerInfo::getFixedStack(FI), 1378 false, false, false, 0); 1379 } 1380 const ArgDataPair ADP = { ArgIn, Ins[i].Flags }; 1381 ArgData.push_back(ADP); 1382 } 1383 1384 // 1b. CopyFromReg vararg registers. 1385 if (isVarArg) { 1386 // Argument registers 1387 static const uint16_t ArgRegs[] = { 1388 XCore::R0, XCore::R1, XCore::R2, XCore::R3 1389 }; 1390 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 1391 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs, 1392 array_lengthof(ArgRegs)); 1393 if (FirstVAReg < array_lengthof(ArgRegs)) { 1394 int offset = 0; 1395 // Save remaining registers, storing higher register numbers at a higher 1396 // address 1397 for (int i = array_lengthof(ArgRegs) - 1; i >= (int)FirstVAReg; --i) { 1398 // Create a stack slot 1399 int FI = MFI->CreateFixedObject(4, offset, true); 1400 if (i == (int)FirstVAReg) { 1401 XFI->setVarArgsFrameIndex(FI); 1402 } 1403 offset -= StackSlotSize; 1404 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 1405 // Move argument from phys reg -> virt reg 1406 unsigned VReg = RegInfo.createVirtualRegister(&XCore::GRRegsRegClass); 1407 RegInfo.addLiveIn(ArgRegs[i], VReg); 1408 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); 1409 CFRegNode.push_back(Val.getValue(Val->getNumValues() - 1)); 1410 // Move argument from virt reg -> stack 1411 SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, 1412 MachinePointerInfo(), false, false, 0); 1413 MemOps.push_back(Store); 1414 } 1415 } else { 1416 // This will point to the next argument passed via stack. 1417 XFI->setVarArgsFrameIndex( 1418 MFI->CreateFixedObject(4, LRSaveSize + CCInfo.getNextStackOffset(), 1419 true)); 1420 } 1421 } 1422 1423 // 2. chain CopyFromReg nodes into a TokenFactor. 1424 if (!CFRegNode.empty()) 1425 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &CFRegNode[0], 1426 CFRegNode.size()); 1427 1428 // 3. Memcpy 'byVal' args & push final InVals. 1429 // Aggregates passed "byVal" need to be copied by the callee. 1430 // The callee will use a pointer to this copy, rather than the original 1431 // pointer. 1432 for (SmallVectorImpl<ArgDataPair>::const_iterator ArgDI = ArgData.begin(), 1433 ArgDE = ArgData.end(); 1434 ArgDI != ArgDE; ++ArgDI) { 1435 if (ArgDI->Flags.isByVal() && ArgDI->Flags.getByValSize()) { 1436 unsigned Size = ArgDI->Flags.getByValSize(); 1437 unsigned Align = std::max(StackSlotSize, ArgDI->Flags.getByValAlign()); 1438 // Create a new object on the stack and copy the pointee into it. 1439 int FI = MFI->CreateStackObject(Size, Align, false); 1440 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 1441 InVals.push_back(FIN); 1442 MemOps.push_back(DAG.getMemcpy(Chain, dl, FIN, ArgDI->SDV, 1443 DAG.getConstant(Size, MVT::i32), 1444 Align, false, false, 1445 MachinePointerInfo(), 1446 MachinePointerInfo())); 1447 } else { 1448 InVals.push_back(ArgDI->SDV); 1449 } 1450 } 1451 1452 // 4, chain mem ops nodes into a TokenFactor. 1453 if (!MemOps.empty()) { 1454 MemOps.push_back(Chain); 1455 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &MemOps[0], 1456 MemOps.size()); 1457 } 1458 1459 return Chain; 1460} 1461 1462//===----------------------------------------------------------------------===// 1463// Return Value Calling Convention Implementation 1464//===----------------------------------------------------------------------===// 1465 1466bool XCoreTargetLowering:: 1467CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 1468 bool isVarArg, 1469 const SmallVectorImpl<ISD::OutputArg> &Outs, 1470 LLVMContext &Context) const { 1471 SmallVector<CCValAssign, 16> RVLocs; 1472 CCState CCInfo(CallConv, isVarArg, MF, getTargetMachine(), RVLocs, Context); 1473 if (!CCInfo.CheckReturn(Outs, RetCC_XCore)) 1474 return false; 1475 if (CCInfo.getNextStackOffset() != 0 && isVarArg) 1476 return false; 1477 return true; 1478} 1479 1480SDValue 1481XCoreTargetLowering::LowerReturn(SDValue Chain, 1482 CallingConv::ID CallConv, bool isVarArg, 1483 const SmallVectorImpl<ISD::OutputArg> &Outs, 1484 const SmallVectorImpl<SDValue> &OutVals, 1485 SDLoc dl, SelectionDAG &DAG) const { 1486 1487 XCoreFunctionInfo *XFI = 1488 DAG.getMachineFunction().getInfo<XCoreFunctionInfo>(); 1489 MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 1490 1491 // CCValAssign - represent the assignment of 1492 // the return value to a location 1493 SmallVector<CCValAssign, 16> RVLocs; 1494 1495 // CCState - Info about the registers and stack slot. 1496 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 1497 getTargetMachine(), RVLocs, *DAG.getContext()); 1498 1499 // Analyze return values. 1500 if (!isVarArg) 1501 CCInfo.AllocateStack(XFI->getReturnStackOffset(), 4); 1502 1503 CCInfo.AnalyzeReturn(Outs, RetCC_XCore); 1504 1505 SDValue Flag; 1506 SmallVector<SDValue, 4> RetOps(1, Chain); 1507 1508 // Return on XCore is always a "retsp 0" 1509 RetOps.push_back(DAG.getConstant(0, MVT::i32)); 1510 1511 SmallVector<SDValue, 4> MemOpChains; 1512 // Handle return values that must be copied to memory. 1513 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { 1514 CCValAssign &VA = RVLocs[i]; 1515 if (VA.isRegLoc()) 1516 continue; 1517 assert(VA.isMemLoc()); 1518 if (isVarArg) { 1519 report_fatal_error("Can't return value from vararg function in memory"); 1520 } 1521 1522 int Offset = VA.getLocMemOffset(); 1523 unsigned ObjSize = VA.getLocVT().getSizeInBits() / 8; 1524 // Create the frame index object for the memory location. 1525 int FI = MFI->CreateFixedObject(ObjSize, Offset, false); 1526 1527 // Create a SelectionDAG node corresponding to a store 1528 // to this memory location. 1529 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 1530 MemOpChains.push_back(DAG.getStore(Chain, dl, OutVals[i], FIN, 1531 MachinePointerInfo::getFixedStack(FI), false, false, 1532 0)); 1533 } 1534 1535 // Transform all store nodes into one single node because 1536 // all stores are independent of each other. 1537 if (!MemOpChains.empty()) 1538 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1539 &MemOpChains[0], MemOpChains.size()); 1540 1541 // Now handle return values copied to registers. 1542 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { 1543 CCValAssign &VA = RVLocs[i]; 1544 if (!VA.isRegLoc()) 1545 continue; 1546 // Copy the result values into the output registers. 1547 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag); 1548 1549 // guarantee that all emitted copies are 1550 // stuck together, avoiding something bad 1551 Flag = Chain.getValue(1); 1552 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 1553 } 1554 1555 RetOps[0] = Chain; // Update chain. 1556 1557 // Add the flag if we have it. 1558 if (Flag.getNode()) 1559 RetOps.push_back(Flag); 1560 1561 return DAG.getNode(XCoreISD::RETSP, dl, MVT::Other, 1562 &RetOps[0], RetOps.size()); 1563} 1564 1565//===----------------------------------------------------------------------===// 1566// Other Lowering Code 1567//===----------------------------------------------------------------------===// 1568 1569MachineBasicBlock * 1570XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 1571 MachineBasicBlock *BB) const { 1572 const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 1573 DebugLoc dl = MI->getDebugLoc(); 1574 assert((MI->getOpcode() == XCore::SELECT_CC) && 1575 "Unexpected instr type to insert"); 1576 1577 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond 1578 // control-flow pattern. The incoming instruction knows the destination vreg 1579 // to set, the condition code register to branch on, the true/false values to 1580 // select between, and a branch opcode to use. 1581 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1582 MachineFunction::iterator It = BB; 1583 ++It; 1584 1585 // thisMBB: 1586 // ... 1587 // TrueVal = ... 1588 // cmpTY ccX, r1, r2 1589 // bCC copy1MBB 1590 // fallthrough --> copy0MBB 1591 MachineBasicBlock *thisMBB = BB; 1592 MachineFunction *F = BB->getParent(); 1593 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 1594 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); 1595 F->insert(It, copy0MBB); 1596 F->insert(It, sinkMBB); 1597 1598 // Transfer the remainder of BB and its successor edges to sinkMBB. 1599 sinkMBB->splice(sinkMBB->begin(), BB, 1600 std::next(MachineBasicBlock::iterator(MI)), BB->end()); 1601 sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 1602 1603 // Next, add the true and fallthrough blocks as its successors. 1604 BB->addSuccessor(copy0MBB); 1605 BB->addSuccessor(sinkMBB); 1606 1607 BuildMI(BB, dl, TII.get(XCore::BRFT_lru6)) 1608 .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB); 1609 1610 // copy0MBB: 1611 // %FalseValue = ... 1612 // # fallthrough to sinkMBB 1613 BB = copy0MBB; 1614 1615 // Update machine-CFG edges 1616 BB->addSuccessor(sinkMBB); 1617 1618 // sinkMBB: 1619 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 1620 // ... 1621 BB = sinkMBB; 1622 BuildMI(*BB, BB->begin(), dl, 1623 TII.get(XCore::PHI), MI->getOperand(0).getReg()) 1624 .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB) 1625 .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB); 1626 1627 MI->eraseFromParent(); // The pseudo instruction is gone now. 1628 return BB; 1629} 1630 1631//===----------------------------------------------------------------------===// 1632// Target Optimization Hooks 1633//===----------------------------------------------------------------------===// 1634 1635SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, 1636 DAGCombinerInfo &DCI) const { 1637 SelectionDAG &DAG = DCI.DAG; 1638 SDLoc dl(N); 1639 switch (N->getOpcode()) { 1640 default: break; 1641 case ISD::INTRINSIC_VOID: 1642 switch (cast<ConstantSDNode>(N->getOperand(1))->getZExtValue()) { 1643 case Intrinsic::xcore_outt: 1644 case Intrinsic::xcore_outct: 1645 case Intrinsic::xcore_chkct: { 1646 SDValue OutVal = N->getOperand(3); 1647 // These instructions ignore the high bits. 1648 if (OutVal.hasOneUse()) { 1649 unsigned BitWidth = OutVal.getValueSizeInBits(); 1650 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 8); 1651 APInt KnownZero, KnownOne; 1652 TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(), 1653 !DCI.isBeforeLegalizeOps()); 1654 const TargetLowering &TLI = DAG.getTargetLoweringInfo(); 1655 if (TLO.ShrinkDemandedConstant(OutVal, DemandedMask) || 1656 TLI.SimplifyDemandedBits(OutVal, DemandedMask, KnownZero, KnownOne, 1657 TLO)) 1658 DCI.CommitTargetLoweringOpt(TLO); 1659 } 1660 break; 1661 } 1662 case Intrinsic::xcore_setpt: { 1663 SDValue Time = N->getOperand(3); 1664 // This instruction ignores the high bits. 1665 if (Time.hasOneUse()) { 1666 unsigned BitWidth = Time.getValueSizeInBits(); 1667 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16); 1668 APInt KnownZero, KnownOne; 1669 TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(), 1670 !DCI.isBeforeLegalizeOps()); 1671 const TargetLowering &TLI = DAG.getTargetLoweringInfo(); 1672 if (TLO.ShrinkDemandedConstant(Time, DemandedMask) || 1673 TLI.SimplifyDemandedBits(Time, DemandedMask, KnownZero, KnownOne, 1674 TLO)) 1675 DCI.CommitTargetLoweringOpt(TLO); 1676 } 1677 break; 1678 } 1679 } 1680 break; 1681 case XCoreISD::LADD: { 1682 SDValue N0 = N->getOperand(0); 1683 SDValue N1 = N->getOperand(1); 1684 SDValue N2 = N->getOperand(2); 1685 ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0); 1686 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); 1687 EVT VT = N0.getValueType(); 1688 1689 // canonicalize constant to RHS 1690 if (N0C && !N1C) 1691 return DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N1, N0, N2); 1692 1693 // fold (ladd 0, 0, x) -> 0, x & 1 1694 if (N0C && N0C->isNullValue() && N1C && N1C->isNullValue()) { 1695 SDValue Carry = DAG.getConstant(0, VT); 1696 SDValue Result = DAG.getNode(ISD::AND, dl, VT, N2, 1697 DAG.getConstant(1, VT)); 1698 SDValue Ops[] = { Result, Carry }; 1699 return DAG.getMergeValues(Ops, 2, dl); 1700 } 1701 1702 // fold (ladd x, 0, y) -> 0, add x, y iff carry is unused and y has only the 1703 // low bit set 1704 if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 1)) { 1705 APInt KnownZero, KnownOne; 1706 APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), 1707 VT.getSizeInBits() - 1); 1708 DAG.ComputeMaskedBits(N2, KnownZero, KnownOne); 1709 if ((KnownZero & Mask) == Mask) { 1710 SDValue Carry = DAG.getConstant(0, VT); 1711 SDValue Result = DAG.getNode(ISD::ADD, dl, VT, N0, N2); 1712 SDValue Ops[] = { Result, Carry }; 1713 return DAG.getMergeValues(Ops, 2, dl); 1714 } 1715 } 1716 } 1717 break; 1718 case XCoreISD::LSUB: { 1719 SDValue N0 = N->getOperand(0); 1720 SDValue N1 = N->getOperand(1); 1721 SDValue N2 = N->getOperand(2); 1722 ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0); 1723 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); 1724 EVT VT = N0.getValueType(); 1725 1726 // fold (lsub 0, 0, x) -> x, -x iff x has only the low bit set 1727 if (N0C && N0C->isNullValue() && N1C && N1C->isNullValue()) { 1728 APInt KnownZero, KnownOne; 1729 APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), 1730 VT.getSizeInBits() - 1); 1731 DAG.ComputeMaskedBits(N2, KnownZero, KnownOne); 1732 if ((KnownZero & Mask) == Mask) { 1733 SDValue Borrow = N2; 1734 SDValue Result = DAG.getNode(ISD::SUB, dl, VT, 1735 DAG.getConstant(0, VT), N2); 1736 SDValue Ops[] = { Result, Borrow }; 1737 return DAG.getMergeValues(Ops, 2, dl); 1738 } 1739 } 1740 1741 // fold (lsub x, 0, y) -> 0, sub x, y iff borrow is unused and y has only the 1742 // low bit set 1743 if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 1)) { 1744 APInt KnownZero, KnownOne; 1745 APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), 1746 VT.getSizeInBits() - 1); 1747 DAG.ComputeMaskedBits(N2, KnownZero, KnownOne); 1748 if ((KnownZero & Mask) == Mask) { 1749 SDValue Borrow = DAG.getConstant(0, VT); 1750 SDValue Result = DAG.getNode(ISD::SUB, dl, VT, N0, N2); 1751 SDValue Ops[] = { Result, Borrow }; 1752 return DAG.getMergeValues(Ops, 2, dl); 1753 } 1754 } 1755 } 1756 break; 1757 case XCoreISD::LMUL: { 1758 SDValue N0 = N->getOperand(0); 1759 SDValue N1 = N->getOperand(1); 1760 SDValue N2 = N->getOperand(2); 1761 SDValue N3 = N->getOperand(3); 1762 ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0); 1763 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); 1764 EVT VT = N0.getValueType(); 1765 // Canonicalize multiplicative constant to RHS. If both multiplicative 1766 // operands are constant canonicalize smallest to RHS. 1767 if ((N0C && !N1C) || 1768 (N0C && N1C && N0C->getZExtValue() < N1C->getZExtValue())) 1769 return DAG.getNode(XCoreISD::LMUL, dl, DAG.getVTList(VT, VT), 1770 N1, N0, N2, N3); 1771 1772 // lmul(x, 0, a, b) 1773 if (N1C && N1C->isNullValue()) { 1774 // If the high result is unused fold to add(a, b) 1775 if (N->hasNUsesOfValue(0, 0)) { 1776 SDValue Lo = DAG.getNode(ISD::ADD, dl, VT, N2, N3); 1777 SDValue Ops[] = { Lo, Lo }; 1778 return DAG.getMergeValues(Ops, 2, dl); 1779 } 1780 // Otherwise fold to ladd(a, b, 0) 1781 SDValue Result = 1782 DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N2, N3, N1); 1783 SDValue Carry(Result.getNode(), 1); 1784 SDValue Ops[] = { Carry, Result }; 1785 return DAG.getMergeValues(Ops, 2, dl); 1786 } 1787 } 1788 break; 1789 case ISD::ADD: { 1790 // Fold 32 bit expressions such as add(add(mul(x,y),a),b) -> 1791 // lmul(x, y, a, b). The high result of lmul will be ignored. 1792 // This is only profitable if the intermediate results are unused 1793 // elsewhere. 1794 SDValue Mul0, Mul1, Addend0, Addend1; 1795 if (N->getValueType(0) == MVT::i32 && 1796 isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, true)) { 1797 SDValue Ignored = DAG.getNode(XCoreISD::LMUL, dl, 1798 DAG.getVTList(MVT::i32, MVT::i32), Mul0, 1799 Mul1, Addend0, Addend1); 1800 SDValue Result(Ignored.getNode(), 1); 1801 return Result; 1802 } 1803 APInt HighMask = APInt::getHighBitsSet(64, 32); 1804 // Fold 64 bit expression such as add(add(mul(x,y),a),b) -> 1805 // lmul(x, y, a, b) if all operands are zero-extended. We do this 1806 // before type legalization as it is messy to match the operands after 1807 // that. 1808 if (N->getValueType(0) == MVT::i64 && 1809 isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, false) && 1810 DAG.MaskedValueIsZero(Mul0, HighMask) && 1811 DAG.MaskedValueIsZero(Mul1, HighMask) && 1812 DAG.MaskedValueIsZero(Addend0, HighMask) && 1813 DAG.MaskedValueIsZero(Addend1, HighMask)) { 1814 SDValue Mul0L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 1815 Mul0, DAG.getConstant(0, MVT::i32)); 1816 SDValue Mul1L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 1817 Mul1, DAG.getConstant(0, MVT::i32)); 1818 SDValue Addend0L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 1819 Addend0, DAG.getConstant(0, MVT::i32)); 1820 SDValue Addend1L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 1821 Addend1, DAG.getConstant(0, MVT::i32)); 1822 SDValue Hi = DAG.getNode(XCoreISD::LMUL, dl, 1823 DAG.getVTList(MVT::i32, MVT::i32), Mul0L, Mul1L, 1824 Addend0L, Addend1L); 1825 SDValue Lo(Hi.getNode(), 1); 1826 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 1827 } 1828 } 1829 break; 1830 case ISD::STORE: { 1831 // Replace unaligned store of unaligned load with memmove. 1832 StoreSDNode *ST = cast<StoreSDNode>(N); 1833 if (!DCI.isBeforeLegalize() || 1834 allowsUnalignedMemoryAccesses(ST->getMemoryVT()) || 1835 ST->isVolatile() || ST->isIndexed()) { 1836 break; 1837 } 1838 SDValue Chain = ST->getChain(); 1839 1840 unsigned StoreBits = ST->getMemoryVT().getStoreSizeInBits(); 1841 if (StoreBits % 8) { 1842 break; 1843 } 1844 unsigned ABIAlignment = getDataLayout()->getABITypeAlignment( 1845 ST->getMemoryVT().getTypeForEVT(*DCI.DAG.getContext())); 1846 unsigned Alignment = ST->getAlignment(); 1847 if (Alignment >= ABIAlignment) { 1848 break; 1849 } 1850 1851 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(ST->getValue())) { 1852 if (LD->hasNUsesOfValue(1, 0) && ST->getMemoryVT() == LD->getMemoryVT() && 1853 LD->getAlignment() == Alignment && 1854 !LD->isVolatile() && !LD->isIndexed() && 1855 Chain.reachesChainWithoutSideEffects(SDValue(LD, 1))) { 1856 return DAG.getMemmove(Chain, dl, ST->getBasePtr(), 1857 LD->getBasePtr(), 1858 DAG.getConstant(StoreBits/8, MVT::i32), 1859 Alignment, false, ST->getPointerInfo(), 1860 LD->getPointerInfo()); 1861 } 1862 } 1863 break; 1864 } 1865 } 1866 return SDValue(); 1867} 1868 1869void XCoreTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, 1870 APInt &KnownZero, 1871 APInt &KnownOne, 1872 const SelectionDAG &DAG, 1873 unsigned Depth) const { 1874 KnownZero = KnownOne = APInt(KnownZero.getBitWidth(), 0); 1875 switch (Op.getOpcode()) { 1876 default: break; 1877 case XCoreISD::LADD: 1878 case XCoreISD::LSUB: 1879 if (Op.getResNo() == 1) { 1880 // Top bits of carry / borrow are clear. 1881 KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(), 1882 KnownZero.getBitWidth() - 1); 1883 } 1884 break; 1885 case ISD::INTRINSIC_W_CHAIN: 1886 { 1887 unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 1888 switch (IntNo) { 1889 case Intrinsic::xcore_getts: 1890 // High bits are known to be zero. 1891 KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(), 1892 KnownZero.getBitWidth() - 16); 1893 break; 1894 case Intrinsic::xcore_int: 1895 case Intrinsic::xcore_inct: 1896 // High bits are known to be zero. 1897 KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(), 1898 KnownZero.getBitWidth() - 8); 1899 break; 1900 case Intrinsic::xcore_testct: 1901 // Result is either 0 or 1. 1902 KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(), 1903 KnownZero.getBitWidth() - 1); 1904 break; 1905 case Intrinsic::xcore_testwct: 1906 // Result is in the range 0 - 4. 1907 KnownZero = APInt::getHighBitsSet(KnownZero.getBitWidth(), 1908 KnownZero.getBitWidth() - 3); 1909 break; 1910 } 1911 } 1912 break; 1913 } 1914} 1915 1916//===----------------------------------------------------------------------===// 1917// Addressing mode description hooks 1918//===----------------------------------------------------------------------===// 1919 1920static inline bool isImmUs(int64_t val) 1921{ 1922 return (val >= 0 && val <= 11); 1923} 1924 1925static inline bool isImmUs2(int64_t val) 1926{ 1927 return (val%2 == 0 && isImmUs(val/2)); 1928} 1929 1930static inline bool isImmUs4(int64_t val) 1931{ 1932 return (val%4 == 0 && isImmUs(val/4)); 1933} 1934 1935/// isLegalAddressingMode - Return true if the addressing mode represented 1936/// by AM is legal for this target, for a load/store of the specified type. 1937bool 1938XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM, 1939 Type *Ty) const { 1940 if (Ty->getTypeID() == Type::VoidTyID) 1941 return AM.Scale == 0 && isImmUs(AM.BaseOffs) && isImmUs4(AM.BaseOffs); 1942 1943 const DataLayout *TD = TM.getDataLayout(); 1944 unsigned Size = TD->getTypeAllocSize(Ty); 1945 if (AM.BaseGV) { 1946 return Size >= 4 && !AM.HasBaseReg && AM.Scale == 0 && 1947 AM.BaseOffs%4 == 0; 1948 } 1949 1950 switch (Size) { 1951 case 1: 1952 // reg + imm 1953 if (AM.Scale == 0) { 1954 return isImmUs(AM.BaseOffs); 1955 } 1956 // reg + reg 1957 return AM.Scale == 1 && AM.BaseOffs == 0; 1958 case 2: 1959 case 3: 1960 // reg + imm 1961 if (AM.Scale == 0) { 1962 return isImmUs2(AM.BaseOffs); 1963 } 1964 // reg + reg<<1 1965 return AM.Scale == 2 && AM.BaseOffs == 0; 1966 default: 1967 // reg + imm 1968 if (AM.Scale == 0) { 1969 return isImmUs4(AM.BaseOffs); 1970 } 1971 // reg + reg<<2 1972 return AM.Scale == 4 && AM.BaseOffs == 0; 1973 } 1974} 1975 1976//===----------------------------------------------------------------------===// 1977// XCore Inline Assembly Support 1978//===----------------------------------------------------------------------===// 1979 1980std::pair<unsigned, const TargetRegisterClass*> 1981XCoreTargetLowering:: 1982getRegForInlineAsmConstraint(const std::string &Constraint, 1983 MVT VT) const { 1984 if (Constraint.size() == 1) { 1985 switch (Constraint[0]) { 1986 default : break; 1987 case 'r': 1988 return std::make_pair(0U, &XCore::GRRegsRegClass); 1989 } 1990 } 1991 // Use the default implementation in TargetLowering to convert the register 1992 // constraint into a member of a register class. 1993 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 1994} 1995