XCoreISelLowering.cpp revision 223017
150471Speter//===-- XCoreISelLowering.cpp - XCore DAG Lowering Implementation ------===// 23044Sdg// 316Salm// The LLVM Compiler Infrastructure 411106Smarkm// 534135Sbde// This file is distributed under the University of Illinois Open Source 634135Sbde// License. See LICENSE.TXT for details. 716Salm// 834135Sbde//===----------------------------------------------------------------------===// 911106Smarkm// 1011106Smarkm// This file implements the XCoreTargetLowering class. 1111684Sache// 1211684Sache//===----------------------------------------------------------------------===// 1311106Smarkm 1411106Smarkm#define DEBUG_TYPE "xcore-lower" 1516Salm 16#include "XCoreISelLowering.h" 17#include "XCoreMachineFunctionInfo.h" 18#include "XCore.h" 19#include "XCoreTargetObjectFile.h" 20#include "XCoreTargetMachine.h" 21#include "XCoreSubtarget.h" 22#include "llvm/DerivedTypes.h" 23#include "llvm/Function.h" 24#include "llvm/Intrinsics.h" 25#include "llvm/CallingConv.h" 26#include "llvm/GlobalVariable.h" 27#include "llvm/GlobalAlias.h" 28#include "llvm/CodeGen/CallingConvLower.h" 29#include "llvm/CodeGen/MachineFrameInfo.h" 30#include "llvm/CodeGen/MachineFunction.h" 31#include "llvm/CodeGen/MachineInstrBuilder.h" 32#include "llvm/CodeGen/MachineJumpTableInfo.h" 33#include "llvm/CodeGen/MachineRegisterInfo.h" 34#include "llvm/CodeGen/SelectionDAGISel.h" 35#include "llvm/CodeGen/ValueTypes.h" 36#include "llvm/Support/Debug.h" 37#include "llvm/Support/ErrorHandling.h" 38#include "llvm/Support/raw_ostream.h" 39#include "llvm/ADT/VectorExtras.h" 40using namespace llvm; 41 42const char *XCoreTargetLowering:: 43getTargetNodeName(unsigned Opcode) const 44{ 45 switch (Opcode) 46 { 47 case XCoreISD::BL : return "XCoreISD::BL"; 48 case XCoreISD::PCRelativeWrapper : return "XCoreISD::PCRelativeWrapper"; 49 case XCoreISD::DPRelativeWrapper : return "XCoreISD::DPRelativeWrapper"; 50 case XCoreISD::CPRelativeWrapper : return "XCoreISD::CPRelativeWrapper"; 51 case XCoreISD::STWSP : return "XCoreISD::STWSP"; 52 case XCoreISD::RETSP : return "XCoreISD::RETSP"; 53 case XCoreISD::LADD : return "XCoreISD::LADD"; 54 case XCoreISD::LSUB : return "XCoreISD::LSUB"; 55 case XCoreISD::LMUL : return "XCoreISD::LMUL"; 56 case XCoreISD::MACCU : return "XCoreISD::MACCU"; 57 case XCoreISD::MACCS : return "XCoreISD::MACCS"; 58 case XCoreISD::BR_JT : return "XCoreISD::BR_JT"; 59 case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32"; 60 default : return NULL; 61 } 62} 63 64XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) 65 : TargetLowering(XTM, new XCoreTargetObjectFile()), 66 TM(XTM), 67 Subtarget(*XTM.getSubtargetImpl()) { 68 69 // Set up the register classes. 70 addRegisterClass(MVT::i32, XCore::GRRegsRegisterClass); 71 72 // Compute derived properties from the register classes 73 computeRegisterProperties(); 74 75 // Division is expensive 76 setIntDivIsCheap(false); 77 78 setStackPointerRegisterToSaveRestore(XCore::SP); 79 80 setSchedulingPreference(Sched::RegPressure); 81 82 // Use i32 for setcc operations results (slt, sgt, ...). 83 setBooleanContents(ZeroOrOneBooleanContent); 84 85 // XCore does not have the NodeTypes below. 86 setOperationAction(ISD::BR_CC, MVT::Other, Expand); 87 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 88 setOperationAction(ISD::ADDC, MVT::i32, Expand); 89 setOperationAction(ISD::ADDE, MVT::i32, Expand); 90 setOperationAction(ISD::SUBC, MVT::i32, Expand); 91 setOperationAction(ISD::SUBE, MVT::i32, Expand); 92 93 // Stop the combiner recombining select and set_cc 94 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); 95 96 // 64bit 97 setOperationAction(ISD::ADD, MVT::i64, Custom); 98 setOperationAction(ISD::SUB, MVT::i64, Custom); 99 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); 100 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); 101 setOperationAction(ISD::MULHS, MVT::i32, Expand); 102 setOperationAction(ISD::MULHU, MVT::i32, Expand); 103 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); 104 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); 105 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); 106 107 // Bit Manipulation 108 setOperationAction(ISD::CTPOP, MVT::i32, Expand); 109 setOperationAction(ISD::ROTL , MVT::i32, Expand); 110 setOperationAction(ISD::ROTR , MVT::i32, Expand); 111 112 setOperationAction(ISD::TRAP, MVT::Other, Legal); 113 114 // Jump tables. 115 setOperationAction(ISD::BR_JT, MVT::Other, Custom); 116 117 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 118 setOperationAction(ISD::BlockAddress, MVT::i32 , Custom); 119 120 // Thread Local Storage 121 setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); 122 123 // Conversion of i64 -> double produces constantpool nodes 124 setOperationAction(ISD::ConstantPool, MVT::i32, Custom); 125 126 // Loads 127 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 128 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 129 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 130 131 setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 132 setLoadExtAction(ISD::ZEXTLOAD, MVT::i16, Expand); 133 134 // Custom expand misaligned loads / stores. 135 setOperationAction(ISD::LOAD, MVT::i32, Custom); 136 setOperationAction(ISD::STORE, MVT::i32, Custom); 137 138 // Varargs 139 setOperationAction(ISD::VAEND, MVT::Other, Expand); 140 setOperationAction(ISD::VACOPY, MVT::Other, Expand); 141 setOperationAction(ISD::VAARG, MVT::Other, Custom); 142 setOperationAction(ISD::VASTART, MVT::Other, Custom); 143 144 // Dynamic stack 145 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); 146 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); 147 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); 148 149 // TRAMPOLINE is custom lowered. 150 setOperationAction(ISD::TRAMPOLINE, MVT::Other, Custom); 151 152 maxStoresPerMemset = maxStoresPerMemsetOptSize = 4; 153 maxStoresPerMemmove = maxStoresPerMemmoveOptSize 154 = maxStoresPerMemcpy = maxStoresPerMemcpyOptSize = 2; 155 156 // We have target-specific dag combine patterns for the following nodes: 157 setTargetDAGCombine(ISD::STORE); 158 setTargetDAGCombine(ISD::ADD); 159 160 setMinFunctionAlignment(1); 161} 162 163SDValue XCoreTargetLowering:: 164LowerOperation(SDValue Op, SelectionDAG &DAG) const { 165 switch (Op.getOpcode()) 166 { 167 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 168 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); 169 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 170 case ISD::ConstantPool: return LowerConstantPool(Op, DAG); 171 case ISD::BR_JT: return LowerBR_JT(Op, DAG); 172 case ISD::LOAD: return LowerLOAD(Op, DAG); 173 case ISD::STORE: return LowerSTORE(Op, DAG); 174 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 175 case ISD::VAARG: return LowerVAARG(Op, DAG); 176 case ISD::VASTART: return LowerVASTART(Op, DAG); 177 case ISD::SMUL_LOHI: return LowerSMUL_LOHI(Op, DAG); 178 case ISD::UMUL_LOHI: return LowerUMUL_LOHI(Op, DAG); 179 // FIXME: Remove these when LegalizeDAGTypes lands. 180 case ISD::ADD: 181 case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG); 182 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 183 case ISD::TRAMPOLINE: return LowerTRAMPOLINE(Op, DAG); 184 default: 185 llvm_unreachable("unimplemented operand"); 186 return SDValue(); 187 } 188} 189 190/// ReplaceNodeResults - Replace the results of node with an illegal result 191/// type with new values built out of custom code. 192void XCoreTargetLowering::ReplaceNodeResults(SDNode *N, 193 SmallVectorImpl<SDValue>&Results, 194 SelectionDAG &DAG) const { 195 switch (N->getOpcode()) { 196 default: 197 llvm_unreachable("Don't know how to custom expand this!"); 198 return; 199 case ISD::ADD: 200 case ISD::SUB: 201 Results.push_back(ExpandADDSUB(N, DAG)); 202 return; 203 } 204} 205 206//===----------------------------------------------------------------------===// 207// Misc Lower Operation implementation 208//===----------------------------------------------------------------------===// 209 210SDValue XCoreTargetLowering:: 211LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const 212{ 213 DebugLoc dl = Op.getDebugLoc(); 214 SDValue Cond = DAG.getNode(ISD::SETCC, dl, MVT::i32, Op.getOperand(2), 215 Op.getOperand(3), Op.getOperand(4)); 216 return DAG.getNode(ISD::SELECT, dl, MVT::i32, Cond, Op.getOperand(0), 217 Op.getOperand(1)); 218} 219 220SDValue XCoreTargetLowering:: 221getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV, 222 SelectionDAG &DAG) const 223{ 224 // FIXME there is no actual debug info here 225 DebugLoc dl = GA.getDebugLoc(); 226 if (isa<Function>(GV)) { 227 return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA); 228 } 229 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); 230 if (!GVar) { 231 // If GV is an alias then use the aliasee to determine constness 232 if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) 233 GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal()); 234 } 235 bool isConst = GVar && GVar->isConstant(); 236 if (isConst) { 237 return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, GA); 238 } 239 return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA); 240} 241 242SDValue XCoreTargetLowering:: 243LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const 244{ 245 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 246 SDValue GA = DAG.getTargetGlobalAddress(GV, Op.getDebugLoc(), MVT::i32); 247 return getGlobalAddressWrapper(GA, GV, DAG); 248} 249 250static inline SDValue BuildGetId(SelectionDAG &DAG, DebugLoc dl) { 251 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::i32, 252 DAG.getConstant(Intrinsic::xcore_getid, MVT::i32)); 253} 254 255static inline bool isZeroLengthArray(const Type *Ty) { 256 const ArrayType *AT = dyn_cast_or_null<ArrayType>(Ty); 257 return AT && (AT->getNumElements() == 0); 258} 259 260SDValue XCoreTargetLowering:: 261LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const 262{ 263 // FIXME there isn't really debug info here 264 DebugLoc dl = Op.getDebugLoc(); 265 // transform to label + getid() * size 266 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 267 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32); 268 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); 269 if (!GVar) { 270 // If GV is an alias then use the aliasee to determine size 271 if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) 272 GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal()); 273 } 274 if (! GVar) { 275 llvm_unreachable("Thread local object not a GlobalVariable?"); 276 return SDValue(); 277 } 278 const Type *Ty = cast<PointerType>(GV->getType())->getElementType(); 279 if (!Ty->isSized() || isZeroLengthArray(Ty)) { 280#ifndef NDEBUG 281 errs() << "Size of thread local object " << GVar->getName() 282 << " is unknown\n"; 283#endif 284 llvm_unreachable(0); 285 } 286 SDValue base = getGlobalAddressWrapper(GA, GV, DAG); 287 const TargetData *TD = TM.getTargetData(); 288 unsigned Size = TD->getTypeAllocSize(Ty); 289 SDValue offset = DAG.getNode(ISD::MUL, dl, MVT::i32, BuildGetId(DAG, dl), 290 DAG.getConstant(Size, MVT::i32)); 291 return DAG.getNode(ISD::ADD, dl, MVT::i32, base, offset); 292} 293 294SDValue XCoreTargetLowering:: 295LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const 296{ 297 DebugLoc DL = Op.getDebugLoc(); 298 299 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); 300 SDValue Result = DAG.getBlockAddress(BA, getPointerTy(), /*isTarget=*/true); 301 302 return DAG.getNode(XCoreISD::PCRelativeWrapper, DL, getPointerTy(), Result); 303} 304 305SDValue XCoreTargetLowering:: 306LowerConstantPool(SDValue Op, SelectionDAG &DAG) const 307{ 308 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 309 // FIXME there isn't really debug info here 310 DebugLoc dl = CP->getDebugLoc(); 311 EVT PtrVT = Op.getValueType(); 312 SDValue Res; 313 if (CP->isMachineConstantPoolEntry()) { 314 Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, 315 CP->getAlignment()); 316 } else { 317 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, 318 CP->getAlignment()); 319 } 320 return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, Res); 321} 322 323unsigned XCoreTargetLowering::getJumpTableEncoding() const { 324 return MachineJumpTableInfo::EK_Inline; 325} 326 327SDValue XCoreTargetLowering:: 328LowerBR_JT(SDValue Op, SelectionDAG &DAG) const 329{ 330 SDValue Chain = Op.getOperand(0); 331 SDValue Table = Op.getOperand(1); 332 SDValue Index = Op.getOperand(2); 333 DebugLoc dl = Op.getDebugLoc(); 334 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table); 335 unsigned JTI = JT->getIndex(); 336 MachineFunction &MF = DAG.getMachineFunction(); 337 const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); 338 SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32); 339 340 unsigned NumEntries = MJTI->getJumpTables()[JTI].MBBs.size(); 341 if (NumEntries <= 32) { 342 return DAG.getNode(XCoreISD::BR_JT, dl, MVT::Other, Chain, TargetJT, Index); 343 } 344 assert((NumEntries >> 31) == 0); 345 SDValue ScaledIndex = DAG.getNode(ISD::SHL, dl, MVT::i32, Index, 346 DAG.getConstant(1, MVT::i32)); 347 return DAG.getNode(XCoreISD::BR_JT32, dl, MVT::Other, Chain, TargetJT, 348 ScaledIndex); 349} 350 351static bool 352IsWordAlignedBasePlusConstantOffset(SDValue Addr, SDValue &AlignedBase, 353 int64_t &Offset) 354{ 355 if (Addr.getOpcode() != ISD::ADD) { 356 return false; 357 } 358 ConstantSDNode *CN = 0; 359 if (!(CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) { 360 return false; 361 } 362 int64_t off = CN->getSExtValue(); 363 const SDValue &Base = Addr.getOperand(0); 364 const SDValue *Root = &Base; 365 if (Base.getOpcode() == ISD::ADD && 366 Base.getOperand(1).getOpcode() == ISD::SHL) { 367 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Base.getOperand(1) 368 .getOperand(1)); 369 if (CN && (CN->getSExtValue() >= 2)) { 370 Root = &Base.getOperand(0); 371 } 372 } 373 if (isa<FrameIndexSDNode>(*Root)) { 374 // All frame indicies are word aligned 375 AlignedBase = Base; 376 Offset = off; 377 return true; 378 } 379 if (Root->getOpcode() == XCoreISD::DPRelativeWrapper || 380 Root->getOpcode() == XCoreISD::CPRelativeWrapper) { 381 // All dp / cp relative addresses are word aligned 382 AlignedBase = Base; 383 Offset = off; 384 return true; 385 } 386 return false; 387} 388 389SDValue XCoreTargetLowering:: 390LowerLOAD(SDValue Op, SelectionDAG &DAG) const { 391 LoadSDNode *LD = cast<LoadSDNode>(Op); 392 assert(LD->getExtensionType() == ISD::NON_EXTLOAD && 393 "Unexpected extension type"); 394 assert(LD->getMemoryVT() == MVT::i32 && "Unexpected load EVT"); 395 if (allowsUnalignedMemoryAccesses(LD->getMemoryVT())) 396 return SDValue(); 397 398 unsigned ABIAlignment = getTargetData()-> 399 getABITypeAlignment(LD->getMemoryVT().getTypeForEVT(*DAG.getContext())); 400 // Leave aligned load alone. 401 if (LD->getAlignment() >= ABIAlignment) 402 return SDValue(); 403 404 SDValue Chain = LD->getChain(); 405 SDValue BasePtr = LD->getBasePtr(); 406 DebugLoc DL = Op.getDebugLoc(); 407 408 SDValue Base; 409 int64_t Offset; 410 if (!LD->isVolatile() && 411 IsWordAlignedBasePlusConstantOffset(BasePtr, Base, Offset)) { 412 if (Offset % 4 == 0) { 413 // We've managed to infer better alignment information than the load 414 // already has. Use an aligned load. 415 // 416 return DAG.getLoad(getPointerTy(), DL, Chain, BasePtr, 417 MachinePointerInfo(), 418 false, false, 0); 419 } 420 // Lower to 421 // ldw low, base[offset >> 2] 422 // ldw high, base[(offset >> 2) + 1] 423 // shr low_shifted, low, (offset & 0x3) * 8 424 // shl high_shifted, high, 32 - (offset & 0x3) * 8 425 // or result, low_shifted, high_shifted 426 SDValue LowOffset = DAG.getConstant(Offset & ~0x3, MVT::i32); 427 SDValue HighOffset = DAG.getConstant((Offset & ~0x3) + 4, MVT::i32); 428 SDValue LowShift = DAG.getConstant((Offset & 0x3) * 8, MVT::i32); 429 SDValue HighShift = DAG.getConstant(32 - (Offset & 0x3) * 8, MVT::i32); 430 431 SDValue LowAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base, LowOffset); 432 SDValue HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base, HighOffset); 433 434 SDValue Low = DAG.getLoad(getPointerTy(), DL, Chain, 435 LowAddr, MachinePointerInfo(), false, false, 0); 436 SDValue High = DAG.getLoad(getPointerTy(), DL, Chain, 437 HighAddr, MachinePointerInfo(), false, false, 0); 438 SDValue LowShifted = DAG.getNode(ISD::SRL, DL, MVT::i32, Low, LowShift); 439 SDValue HighShifted = DAG.getNode(ISD::SHL, DL, MVT::i32, High, HighShift); 440 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, LowShifted, HighShifted); 441 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Low.getValue(1), 442 High.getValue(1)); 443 SDValue Ops[] = { Result, Chain }; 444 return DAG.getMergeValues(Ops, 2, DL); 445 } 446 447 if (LD->getAlignment() == 2) { 448 SDValue Low = DAG.getExtLoad(ISD::ZEXTLOAD, DL, MVT::i32, Chain, 449 BasePtr, LD->getPointerInfo(), MVT::i16, 450 LD->isVolatile(), LD->isNonTemporal(), 2); 451 SDValue HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr, 452 DAG.getConstant(2, MVT::i32)); 453 SDValue High = DAG.getExtLoad(ISD::EXTLOAD, DL, MVT::i32, Chain, 454 HighAddr, 455 LD->getPointerInfo().getWithOffset(2), 456 MVT::i16, LD->isVolatile(), 457 LD->isNonTemporal(), 2); 458 SDValue HighShifted = DAG.getNode(ISD::SHL, DL, MVT::i32, High, 459 DAG.getConstant(16, MVT::i32)); 460 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Low, HighShifted); 461 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Low.getValue(1), 462 High.getValue(1)); 463 SDValue Ops[] = { Result, Chain }; 464 return DAG.getMergeValues(Ops, 2, DL); 465 } 466 467 // Lower to a call to __misaligned_load(BasePtr). 468 const Type *IntPtrTy = getTargetData()->getIntPtrType(*DAG.getContext()); 469 TargetLowering::ArgListTy Args; 470 TargetLowering::ArgListEntry Entry; 471 472 Entry.Ty = IntPtrTy; 473 Entry.Node = BasePtr; 474 Args.push_back(Entry); 475 476 std::pair<SDValue, SDValue> CallResult = 477 LowerCallTo(Chain, IntPtrTy, false, false, 478 false, false, 0, CallingConv::C, false, 479 /*isReturnValueUsed=*/true, 480 DAG.getExternalSymbol("__misaligned_load", getPointerTy()), 481 Args, DAG, DL); 482 483 SDValue Ops[] = 484 { CallResult.first, CallResult.second }; 485 486 return DAG.getMergeValues(Ops, 2, DL); 487} 488 489SDValue XCoreTargetLowering:: 490LowerSTORE(SDValue Op, SelectionDAG &DAG) const 491{ 492 StoreSDNode *ST = cast<StoreSDNode>(Op); 493 assert(!ST->isTruncatingStore() && "Unexpected store type"); 494 assert(ST->getMemoryVT() == MVT::i32 && "Unexpected store EVT"); 495 if (allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { 496 return SDValue(); 497 } 498 unsigned ABIAlignment = getTargetData()-> 499 getABITypeAlignment(ST->getMemoryVT().getTypeForEVT(*DAG.getContext())); 500 // Leave aligned store alone. 501 if (ST->getAlignment() >= ABIAlignment) { 502 return SDValue(); 503 } 504 SDValue Chain = ST->getChain(); 505 SDValue BasePtr = ST->getBasePtr(); 506 SDValue Value = ST->getValue(); 507 DebugLoc dl = Op.getDebugLoc(); 508 509 if (ST->getAlignment() == 2) { 510 SDValue Low = Value; 511 SDValue High = DAG.getNode(ISD::SRL, dl, MVT::i32, Value, 512 DAG.getConstant(16, MVT::i32)); 513 SDValue StoreLow = DAG.getTruncStore(Chain, dl, Low, BasePtr, 514 ST->getPointerInfo(), MVT::i16, 515 ST->isVolatile(), ST->isNonTemporal(), 516 2); 517 SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr, 518 DAG.getConstant(2, MVT::i32)); 519 SDValue StoreHigh = DAG.getTruncStore(Chain, dl, High, HighAddr, 520 ST->getPointerInfo().getWithOffset(2), 521 MVT::i16, ST->isVolatile(), 522 ST->isNonTemporal(), 2); 523 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, StoreLow, StoreHigh); 524 } 525 526 // Lower to a call to __misaligned_store(BasePtr, Value). 527 const Type *IntPtrTy = getTargetData()->getIntPtrType(*DAG.getContext()); 528 TargetLowering::ArgListTy Args; 529 TargetLowering::ArgListEntry Entry; 530 531 Entry.Ty = IntPtrTy; 532 Entry.Node = BasePtr; 533 Args.push_back(Entry); 534 535 Entry.Node = Value; 536 Args.push_back(Entry); 537 538 std::pair<SDValue, SDValue> CallResult = 539 LowerCallTo(Chain, Type::getVoidTy(*DAG.getContext()), false, false, 540 false, false, 0, CallingConv::C, false, 541 /*isReturnValueUsed=*/true, 542 DAG.getExternalSymbol("__misaligned_store", getPointerTy()), 543 Args, DAG, dl); 544 545 return CallResult.second; 546} 547 548SDValue XCoreTargetLowering:: 549LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const 550{ 551 assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::SMUL_LOHI && 552 "Unexpected operand to lower!"); 553 DebugLoc dl = Op.getDebugLoc(); 554 SDValue LHS = Op.getOperand(0); 555 SDValue RHS = Op.getOperand(1); 556 SDValue Zero = DAG.getConstant(0, MVT::i32); 557 SDValue Hi = DAG.getNode(XCoreISD::MACCS, dl, 558 DAG.getVTList(MVT::i32, MVT::i32), Zero, Zero, 559 LHS, RHS); 560 SDValue Lo(Hi.getNode(), 1); 561 SDValue Ops[] = { Lo, Hi }; 562 return DAG.getMergeValues(Ops, 2, dl); 563} 564 565SDValue XCoreTargetLowering:: 566LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const 567{ 568 assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::UMUL_LOHI && 569 "Unexpected operand to lower!"); 570 DebugLoc dl = Op.getDebugLoc(); 571 SDValue LHS = Op.getOperand(0); 572 SDValue RHS = Op.getOperand(1); 573 SDValue Zero = DAG.getConstant(0, MVT::i32); 574 SDValue Hi = DAG.getNode(XCoreISD::LMUL, dl, 575 DAG.getVTList(MVT::i32, MVT::i32), LHS, RHS, 576 Zero, Zero); 577 SDValue Lo(Hi.getNode(), 1); 578 SDValue Ops[] = { Lo, Hi }; 579 return DAG.getMergeValues(Ops, 2, dl); 580} 581 582/// isADDADDMUL - Return whether Op is in a form that is equivalent to 583/// add(add(mul(x,y),a),b). If requireIntermediatesHaveOneUse is true then 584/// each intermediate result in the calculation must also have a single use. 585/// If the Op is in the correct form the constituent parts are written to Mul0, 586/// Mul1, Addend0 and Addend1. 587static bool 588isADDADDMUL(SDValue Op, SDValue &Mul0, SDValue &Mul1, SDValue &Addend0, 589 SDValue &Addend1, bool requireIntermediatesHaveOneUse) 590{ 591 if (Op.getOpcode() != ISD::ADD) 592 return false; 593 SDValue N0 = Op.getOperand(0); 594 SDValue N1 = Op.getOperand(1); 595 SDValue AddOp; 596 SDValue OtherOp; 597 if (N0.getOpcode() == ISD::ADD) { 598 AddOp = N0; 599 OtherOp = N1; 600 } else if (N1.getOpcode() == ISD::ADD) { 601 AddOp = N1; 602 OtherOp = N0; 603 } else { 604 return false; 605 } 606 if (requireIntermediatesHaveOneUse && !AddOp.hasOneUse()) 607 return false; 608 if (OtherOp.getOpcode() == ISD::MUL) { 609 // add(add(a,b),mul(x,y)) 610 if (requireIntermediatesHaveOneUse && !OtherOp.hasOneUse()) 611 return false; 612 Mul0 = OtherOp.getOperand(0); 613 Mul1 = OtherOp.getOperand(1); 614 Addend0 = AddOp.getOperand(0); 615 Addend1 = AddOp.getOperand(1); 616 return true; 617 } 618 if (AddOp.getOperand(0).getOpcode() == ISD::MUL) { 619 // add(add(mul(x,y),a),b) 620 if (requireIntermediatesHaveOneUse && !AddOp.getOperand(0).hasOneUse()) 621 return false; 622 Mul0 = AddOp.getOperand(0).getOperand(0); 623 Mul1 = AddOp.getOperand(0).getOperand(1); 624 Addend0 = AddOp.getOperand(1); 625 Addend1 = OtherOp; 626 return true; 627 } 628 if (AddOp.getOperand(1).getOpcode() == ISD::MUL) { 629 // add(add(a,mul(x,y)),b) 630 if (requireIntermediatesHaveOneUse && !AddOp.getOperand(1).hasOneUse()) 631 return false; 632 Mul0 = AddOp.getOperand(1).getOperand(0); 633 Mul1 = AddOp.getOperand(1).getOperand(1); 634 Addend0 = AddOp.getOperand(0); 635 Addend1 = OtherOp; 636 return true; 637 } 638 return false; 639} 640 641SDValue XCoreTargetLowering:: 642TryExpandADDWithMul(SDNode *N, SelectionDAG &DAG) const 643{ 644 SDValue Mul; 645 SDValue Other; 646 if (N->getOperand(0).getOpcode() == ISD::MUL) { 647 Mul = N->getOperand(0); 648 Other = N->getOperand(1); 649 } else if (N->getOperand(1).getOpcode() == ISD::MUL) { 650 Mul = N->getOperand(1); 651 Other = N->getOperand(0); 652 } else { 653 return SDValue(); 654 } 655 DebugLoc dl = N->getDebugLoc(); 656 SDValue LL, RL, AddendL, AddendH; 657 LL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 658 Mul.getOperand(0), DAG.getConstant(0, MVT::i32)); 659 RL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 660 Mul.getOperand(1), DAG.getConstant(0, MVT::i32)); 661 AddendL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 662 Other, DAG.getConstant(0, MVT::i32)); 663 AddendH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 664 Other, DAG.getConstant(1, MVT::i32)); 665 APInt HighMask = APInt::getHighBitsSet(64, 32); 666 unsigned LHSSB = DAG.ComputeNumSignBits(Mul.getOperand(0)); 667 unsigned RHSSB = DAG.ComputeNumSignBits(Mul.getOperand(1)); 668 if (DAG.MaskedValueIsZero(Mul.getOperand(0), HighMask) && 669 DAG.MaskedValueIsZero(Mul.getOperand(1), HighMask)) { 670 // The inputs are both zero-extended. 671 SDValue Hi = DAG.getNode(XCoreISD::MACCU, dl, 672 DAG.getVTList(MVT::i32, MVT::i32), AddendH, 673 AddendL, LL, RL); 674 SDValue Lo(Hi.getNode(), 1); 675 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 676 } 677 if (LHSSB > 32 && RHSSB > 32) { 678 // The inputs are both sign-extended. 679 SDValue Hi = DAG.getNode(XCoreISD::MACCS, dl, 680 DAG.getVTList(MVT::i32, MVT::i32), AddendH, 681 AddendL, LL, RL); 682 SDValue Lo(Hi.getNode(), 1); 683 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 684 } 685 SDValue LH, RH; 686 LH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 687 Mul.getOperand(0), DAG.getConstant(1, MVT::i32)); 688 RH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 689 Mul.getOperand(1), DAG.getConstant(1, MVT::i32)); 690 SDValue Hi = DAG.getNode(XCoreISD::MACCU, dl, 691 DAG.getVTList(MVT::i32, MVT::i32), AddendH, 692 AddendL, LL, RL); 693 SDValue Lo(Hi.getNode(), 1); 694 RH = DAG.getNode(ISD::MUL, dl, MVT::i32, LL, RH); 695 LH = DAG.getNode(ISD::MUL, dl, MVT::i32, LH, RL); 696 Hi = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, RH); 697 Hi = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, LH); 698 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 699} 700 701SDValue XCoreTargetLowering:: 702ExpandADDSUB(SDNode *N, SelectionDAG &DAG) const 703{ 704 assert(N->getValueType(0) == MVT::i64 && 705 (N->getOpcode() == ISD::ADD || N->getOpcode() == ISD::SUB) && 706 "Unknown operand to lower!"); 707 708 if (N->getOpcode() == ISD::ADD) { 709 SDValue Result = TryExpandADDWithMul(N, DAG); 710 if (Result.getNode() != 0) 711 return Result; 712 } 713 714 DebugLoc dl = N->getDebugLoc(); 715 716 // Extract components 717 SDValue LHSL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 718 N->getOperand(0), DAG.getConstant(0, MVT::i32)); 719 SDValue LHSH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 720 N->getOperand(0), DAG.getConstant(1, MVT::i32)); 721 SDValue RHSL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 722 N->getOperand(1), DAG.getConstant(0, MVT::i32)); 723 SDValue RHSH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 724 N->getOperand(1), DAG.getConstant(1, MVT::i32)); 725 726 // Expand 727 unsigned Opcode = (N->getOpcode() == ISD::ADD) ? XCoreISD::LADD : 728 XCoreISD::LSUB; 729 SDValue Zero = DAG.getConstant(0, MVT::i32); 730 SDValue Carry = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32), 731 LHSL, RHSL, Zero); 732 SDValue Lo(Carry.getNode(), 1); 733 734 SDValue Ignored = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32), 735 LHSH, RHSH, Carry); 736 SDValue Hi(Ignored.getNode(), 1); 737 // Merge the pieces 738 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 739} 740 741SDValue XCoreTargetLowering:: 742LowerVAARG(SDValue Op, SelectionDAG &DAG) const 743{ 744 llvm_unreachable("unimplemented"); 745 // FIX Arguments passed by reference need a extra dereference. 746 SDNode *Node = Op.getNode(); 747 DebugLoc dl = Node->getDebugLoc(); 748 const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 749 EVT VT = Node->getValueType(0); 750 SDValue VAList = DAG.getLoad(getPointerTy(), dl, Node->getOperand(0), 751 Node->getOperand(1), MachinePointerInfo(V), 752 false, false, 0); 753 // Increment the pointer, VAList, to the next vararg 754 SDValue Tmp3 = DAG.getNode(ISD::ADD, dl, getPointerTy(), VAList, 755 DAG.getConstant(VT.getSizeInBits(), 756 getPointerTy())); 757 // Store the incremented VAList to the legalized pointer 758 Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), 759 MachinePointerInfo(V), false, false, 0); 760 // Load the actual argument out of the pointer VAList 761 return DAG.getLoad(VT, dl, Tmp3, VAList, MachinePointerInfo(), 762 false, false, 0); 763} 764 765SDValue XCoreTargetLowering:: 766LowerVASTART(SDValue Op, SelectionDAG &DAG) const 767{ 768 DebugLoc dl = Op.getDebugLoc(); 769 // vastart stores the address of the VarArgsFrameIndex slot into the 770 // memory location argument 771 MachineFunction &MF = DAG.getMachineFunction(); 772 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 773 SDValue Addr = DAG.getFrameIndex(XFI->getVarArgsFrameIndex(), MVT::i32); 774 return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), 775 MachinePointerInfo(), false, false, 0); 776} 777 778SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, 779 SelectionDAG &DAG) const { 780 DebugLoc dl = Op.getDebugLoc(); 781 // Depths > 0 not supported yet! 782 if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0) 783 return SDValue(); 784 785 MachineFunction &MF = DAG.getMachineFunction(); 786 const TargetRegisterInfo *RegInfo = getTargetMachine().getRegisterInfo(); 787 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, 788 RegInfo->getFrameRegister(MF), MVT::i32); 789} 790 791SDValue XCoreTargetLowering:: 792LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) const { 793 SDValue Chain = Op.getOperand(0); 794 SDValue Trmp = Op.getOperand(1); // trampoline 795 SDValue FPtr = Op.getOperand(2); // nested function 796 SDValue Nest = Op.getOperand(3); // 'nest' parameter value 797 798 const Value *TrmpAddr = cast<SrcValueSDNode>(Op.getOperand(4))->getValue(); 799 800 // .align 4 801 // LDAPF_u10 r11, nest 802 // LDW_2rus r11, r11[0] 803 // STWSP_ru6 r11, sp[0] 804 // LDAPF_u10 r11, fptr 805 // LDW_2rus r11, r11[0] 806 // BAU_1r r11 807 // nest: 808 // .word nest 809 // fptr: 810 // .word fptr 811 SDValue OutChains[5]; 812 813 SDValue Addr = Trmp; 814 815 DebugLoc dl = Op.getDebugLoc(); 816 OutChains[0] = DAG.getStore(Chain, dl, DAG.getConstant(0x0a3cd805, MVT::i32), 817 Addr, MachinePointerInfo(TrmpAddr), false, false, 818 0); 819 820 Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, 821 DAG.getConstant(4, MVT::i32)); 822 OutChains[1] = DAG.getStore(Chain, dl, DAG.getConstant(0xd80456c0, MVT::i32), 823 Addr, MachinePointerInfo(TrmpAddr, 4), false, 824 false, 0); 825 826 Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, 827 DAG.getConstant(8, MVT::i32)); 828 OutChains[2] = DAG.getStore(Chain, dl, DAG.getConstant(0x27fb0a3c, MVT::i32), 829 Addr, MachinePointerInfo(TrmpAddr, 8), false, 830 false, 0); 831 832 Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, 833 DAG.getConstant(12, MVT::i32)); 834 OutChains[3] = DAG.getStore(Chain, dl, Nest, Addr, 835 MachinePointerInfo(TrmpAddr, 12), false, false, 836 0); 837 838 Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, 839 DAG.getConstant(16, MVT::i32)); 840 OutChains[4] = DAG.getStore(Chain, dl, FPtr, Addr, 841 MachinePointerInfo(TrmpAddr, 16), false, false, 842 0); 843 844 SDValue Ops[] = 845 { Trmp, DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains, 5) }; 846 return DAG.getMergeValues(Ops, 2, dl); 847} 848 849//===----------------------------------------------------------------------===// 850// Calling Convention Implementation 851//===----------------------------------------------------------------------===// 852 853#include "XCoreGenCallingConv.inc" 854 855//===----------------------------------------------------------------------===// 856// Call Calling Convention Implementation 857//===----------------------------------------------------------------------===// 858 859/// XCore call implementation 860SDValue 861XCoreTargetLowering::LowerCall(SDValue Chain, SDValue Callee, 862 CallingConv::ID CallConv, bool isVarArg, 863 bool &isTailCall, 864 const SmallVectorImpl<ISD::OutputArg> &Outs, 865 const SmallVectorImpl<SDValue> &OutVals, 866 const SmallVectorImpl<ISD::InputArg> &Ins, 867 DebugLoc dl, SelectionDAG &DAG, 868 SmallVectorImpl<SDValue> &InVals) const { 869 // XCore target does not yet support tail call optimization. 870 isTailCall = false; 871 872 // For now, only CallingConv::C implemented 873 switch (CallConv) 874 { 875 default: 876 llvm_unreachable("Unsupported calling convention"); 877 case CallingConv::Fast: 878 case CallingConv::C: 879 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 880 Outs, OutVals, Ins, dl, DAG, InVals); 881 } 882} 883 884/// LowerCCCCallTo - functions arguments are copied from virtual 885/// regs to (physical regs)/(stack frame), CALLSEQ_START and 886/// CALLSEQ_END are emitted. 887/// TODO: isTailCall, sret. 888SDValue 889XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 890 CallingConv::ID CallConv, bool isVarArg, 891 bool isTailCall, 892 const SmallVectorImpl<ISD::OutputArg> &Outs, 893 const SmallVectorImpl<SDValue> &OutVals, 894 const SmallVectorImpl<ISD::InputArg> &Ins, 895 DebugLoc dl, SelectionDAG &DAG, 896 SmallVectorImpl<SDValue> &InVals) const { 897 898 // Analyze operands of the call, assigning locations to each operand. 899 SmallVector<CCValAssign, 16> ArgLocs; 900 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 901 getTargetMachine(), ArgLocs, *DAG.getContext()); 902 903 // The ABI dictates there should be one stack slot available to the callee 904 // on function entry (for saving lr). 905 CCInfo.AllocateStack(4, 4); 906 907 CCInfo.AnalyzeCallOperands(Outs, CC_XCore); 908 909 // Get a count of how many bytes are to be pushed on the stack. 910 unsigned NumBytes = CCInfo.getNextStackOffset(); 911 912 Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, 913 getPointerTy(), true)); 914 915 SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 916 SmallVector<SDValue, 12> MemOpChains; 917 918 // Walk the register/memloc assignments, inserting copies/loads. 919 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 920 CCValAssign &VA = ArgLocs[i]; 921 SDValue Arg = OutVals[i]; 922 923 // Promote the value if needed. 924 switch (VA.getLocInfo()) { 925 default: llvm_unreachable("Unknown loc info!"); 926 case CCValAssign::Full: break; 927 case CCValAssign::SExt: 928 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 929 break; 930 case CCValAssign::ZExt: 931 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 932 break; 933 case CCValAssign::AExt: 934 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 935 break; 936 } 937 938 // Arguments that can be passed on register must be kept at 939 // RegsToPass vector 940 if (VA.isRegLoc()) { 941 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 942 } else { 943 assert(VA.isMemLoc()); 944 945 int Offset = VA.getLocMemOffset(); 946 947 MemOpChains.push_back(DAG.getNode(XCoreISD::STWSP, dl, MVT::Other, 948 Chain, Arg, 949 DAG.getConstant(Offset/4, MVT::i32))); 950 } 951 } 952 953 // Transform all store nodes into one single node because 954 // all store nodes are independent of each other. 955 if (!MemOpChains.empty()) 956 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 957 &MemOpChains[0], MemOpChains.size()); 958 959 // Build a sequence of copy-to-reg nodes chained together with token 960 // chain and flag operands which copy the outgoing args into registers. 961 // The InFlag in necessary since all emitted instructions must be 962 // stuck together. 963 SDValue InFlag; 964 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 965 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 966 RegsToPass[i].second, InFlag); 967 InFlag = Chain.getValue(1); 968 } 969 970 // If the callee is a GlobalAddress node (quite common, every direct call is) 971 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 972 // Likewise ExternalSymbol -> TargetExternalSymbol. 973 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 974 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32); 975 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 976 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32); 977 978 // XCoreBranchLink = #chain, #target_address, #opt_in_flags... 979 // = Chain, Callee, Reg#1, Reg#2, ... 980 // 981 // Returns a chain & a flag for retval copy to use. 982 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 983 SmallVector<SDValue, 8> Ops; 984 Ops.push_back(Chain); 985 Ops.push_back(Callee); 986 987 // Add argument registers to the end of the list so that they are 988 // known live into the call. 989 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 990 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 991 RegsToPass[i].second.getValueType())); 992 993 if (InFlag.getNode()) 994 Ops.push_back(InFlag); 995 996 Chain = DAG.getNode(XCoreISD::BL, dl, NodeTys, &Ops[0], Ops.size()); 997 InFlag = Chain.getValue(1); 998 999 // Create the CALLSEQ_END node. 1000 Chain = DAG.getCALLSEQ_END(Chain, 1001 DAG.getConstant(NumBytes, getPointerTy(), true), 1002 DAG.getConstant(0, getPointerTy(), true), 1003 InFlag); 1004 InFlag = Chain.getValue(1); 1005 1006 // Handle result values, copying them out of physregs into vregs that we 1007 // return. 1008 return LowerCallResult(Chain, InFlag, CallConv, isVarArg, 1009 Ins, dl, DAG, InVals); 1010} 1011 1012/// LowerCallResult - Lower the result values of a call into the 1013/// appropriate copies out of appropriate physical registers. 1014SDValue 1015XCoreTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 1016 CallingConv::ID CallConv, bool isVarArg, 1017 const SmallVectorImpl<ISD::InputArg> &Ins, 1018 DebugLoc dl, SelectionDAG &DAG, 1019 SmallVectorImpl<SDValue> &InVals) const { 1020 1021 // Assign locations to each value returned by this call. 1022 SmallVector<CCValAssign, 16> RVLocs; 1023 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 1024 getTargetMachine(), RVLocs, *DAG.getContext()); 1025 1026 CCInfo.AnalyzeCallResult(Ins, RetCC_XCore); 1027 1028 // Copy all of the result registers out of their specified physreg. 1029 for (unsigned i = 0; i != RVLocs.size(); ++i) { 1030 Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 1031 RVLocs[i].getValVT(), InFlag).getValue(1); 1032 InFlag = Chain.getValue(2); 1033 InVals.push_back(Chain.getValue(0)); 1034 } 1035 1036 return Chain; 1037} 1038 1039//===----------------------------------------------------------------------===// 1040// Formal Arguments Calling Convention Implementation 1041//===----------------------------------------------------------------------===// 1042 1043/// XCore formal arguments implementation 1044SDValue 1045XCoreTargetLowering::LowerFormalArguments(SDValue Chain, 1046 CallingConv::ID CallConv, 1047 bool isVarArg, 1048 const SmallVectorImpl<ISD::InputArg> &Ins, 1049 DebugLoc dl, 1050 SelectionDAG &DAG, 1051 SmallVectorImpl<SDValue> &InVals) 1052 const { 1053 switch (CallConv) 1054 { 1055 default: 1056 llvm_unreachable("Unsupported calling convention"); 1057 case CallingConv::C: 1058 case CallingConv::Fast: 1059 return LowerCCCArguments(Chain, CallConv, isVarArg, 1060 Ins, dl, DAG, InVals); 1061 } 1062} 1063 1064/// LowerCCCArguments - transform physical registers into 1065/// virtual registers and generate load operations for 1066/// arguments places on the stack. 1067/// TODO: sret 1068SDValue 1069XCoreTargetLowering::LowerCCCArguments(SDValue Chain, 1070 CallingConv::ID CallConv, 1071 bool isVarArg, 1072 const SmallVectorImpl<ISD::InputArg> 1073 &Ins, 1074 DebugLoc dl, 1075 SelectionDAG &DAG, 1076 SmallVectorImpl<SDValue> &InVals) const { 1077 MachineFunction &MF = DAG.getMachineFunction(); 1078 MachineFrameInfo *MFI = MF.getFrameInfo(); 1079 MachineRegisterInfo &RegInfo = MF.getRegInfo(); 1080 1081 // Assign locations to all of the incoming arguments. 1082 SmallVector<CCValAssign, 16> ArgLocs; 1083 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 1084 getTargetMachine(), ArgLocs, *DAG.getContext()); 1085 1086 CCInfo.AnalyzeFormalArguments(Ins, CC_XCore); 1087 1088 unsigned StackSlotSize = XCoreFrameLowering::stackSlotSize(); 1089 1090 unsigned LRSaveSize = StackSlotSize; 1091 1092 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 1093 1094 CCValAssign &VA = ArgLocs[i]; 1095 1096 if (VA.isRegLoc()) { 1097 // Arguments passed in registers 1098 EVT RegVT = VA.getLocVT(); 1099 switch (RegVT.getSimpleVT().SimpleTy) { 1100 default: 1101 { 1102#ifndef NDEBUG 1103 errs() << "LowerFormalArguments Unhandled argument type: " 1104 << RegVT.getSimpleVT().SimpleTy << "\n"; 1105#endif 1106 llvm_unreachable(0); 1107 } 1108 case MVT::i32: 1109 unsigned VReg = RegInfo.createVirtualRegister( 1110 XCore::GRRegsRegisterClass); 1111 RegInfo.addLiveIn(VA.getLocReg(), VReg); 1112 InVals.push_back(DAG.getCopyFromReg(Chain, dl, VReg, RegVT)); 1113 } 1114 } else { 1115 // sanity check 1116 assert(VA.isMemLoc()); 1117 // Load the argument to a virtual register 1118 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 1119 if (ObjSize > StackSlotSize) { 1120 errs() << "LowerFormalArguments Unhandled argument type: " 1121 << EVT(VA.getLocVT()).getEVTString() 1122 << "\n"; 1123 } 1124 // Create the frame index object for this incoming parameter... 1125 int FI = MFI->CreateFixedObject(ObjSize, 1126 LRSaveSize + VA.getLocMemOffset(), 1127 true); 1128 1129 // Create the SelectionDAG nodes corresponding to a load 1130 //from this parameter 1131 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 1132 InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 1133 MachinePointerInfo::getFixedStack(FI), 1134 false, false, 0)); 1135 } 1136 } 1137 1138 if (isVarArg) { 1139 /* Argument registers */ 1140 static const unsigned ArgRegs[] = { 1141 XCore::R0, XCore::R1, XCore::R2, XCore::R3 1142 }; 1143 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 1144 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs, 1145 array_lengthof(ArgRegs)); 1146 if (FirstVAReg < array_lengthof(ArgRegs)) { 1147 SmallVector<SDValue, 4> MemOps; 1148 int offset = 0; 1149 // Save remaining registers, storing higher register numbers at a higher 1150 // address 1151 for (unsigned i = array_lengthof(ArgRegs) - 1; i >= FirstVAReg; --i) { 1152 // Create a stack slot 1153 int FI = MFI->CreateFixedObject(4, offset, true); 1154 if (i == FirstVAReg) { 1155 XFI->setVarArgsFrameIndex(FI); 1156 } 1157 offset -= StackSlotSize; 1158 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 1159 // Move argument from phys reg -> virt reg 1160 unsigned VReg = RegInfo.createVirtualRegister( 1161 XCore::GRRegsRegisterClass); 1162 RegInfo.addLiveIn(ArgRegs[i], VReg); 1163 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); 1164 // Move argument from virt reg -> stack 1165 SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, 1166 MachinePointerInfo(), false, false, 0); 1167 MemOps.push_back(Store); 1168 } 1169 if (!MemOps.empty()) 1170 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1171 &MemOps[0], MemOps.size()); 1172 } else { 1173 // This will point to the next argument passed via stack. 1174 XFI->setVarArgsFrameIndex( 1175 MFI->CreateFixedObject(4, LRSaveSize + CCInfo.getNextStackOffset(), 1176 true)); 1177 } 1178 } 1179 1180 return Chain; 1181} 1182 1183//===----------------------------------------------------------------------===// 1184// Return Value Calling Convention Implementation 1185//===----------------------------------------------------------------------===// 1186 1187bool XCoreTargetLowering:: 1188CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 1189 bool isVarArg, 1190 const SmallVectorImpl<ISD::OutputArg> &Outs, 1191 LLVMContext &Context) const { 1192 SmallVector<CCValAssign, 16> RVLocs; 1193 CCState CCInfo(CallConv, isVarArg, MF, getTargetMachine(), RVLocs, Context); 1194 return CCInfo.CheckReturn(Outs, RetCC_XCore); 1195} 1196 1197SDValue 1198XCoreTargetLowering::LowerReturn(SDValue Chain, 1199 CallingConv::ID CallConv, bool isVarArg, 1200 const SmallVectorImpl<ISD::OutputArg> &Outs, 1201 const SmallVectorImpl<SDValue> &OutVals, 1202 DebugLoc dl, SelectionDAG &DAG) const { 1203 1204 // CCValAssign - represent the assignment of 1205 // the return value to a location 1206 SmallVector<CCValAssign, 16> RVLocs; 1207 1208 // CCState - Info about the registers and stack slot. 1209 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 1210 getTargetMachine(), RVLocs, *DAG.getContext()); 1211 1212 // Analyze return values. 1213 CCInfo.AnalyzeReturn(Outs, RetCC_XCore); 1214 1215 // If this is the first return lowered for this function, add 1216 // the regs to the liveout set for the function. 1217 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 1218 for (unsigned i = 0; i != RVLocs.size(); ++i) 1219 if (RVLocs[i].isRegLoc()) 1220 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 1221 } 1222 1223 SDValue Flag; 1224 1225 // Copy the result values into the output registers. 1226 for (unsigned i = 0; i != RVLocs.size(); ++i) { 1227 CCValAssign &VA = RVLocs[i]; 1228 assert(VA.isRegLoc() && "Can only return in registers!"); 1229 1230 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 1231 OutVals[i], Flag); 1232 1233 // guarantee that all emitted copies are 1234 // stuck together, avoiding something bad 1235 Flag = Chain.getValue(1); 1236 } 1237 1238 // Return on XCore is always a "retsp 0" 1239 if (Flag.getNode()) 1240 return DAG.getNode(XCoreISD::RETSP, dl, MVT::Other, 1241 Chain, DAG.getConstant(0, MVT::i32), Flag); 1242 else // Return Void 1243 return DAG.getNode(XCoreISD::RETSP, dl, MVT::Other, 1244 Chain, DAG.getConstant(0, MVT::i32)); 1245} 1246 1247//===----------------------------------------------------------------------===// 1248// Other Lowering Code 1249//===----------------------------------------------------------------------===// 1250 1251MachineBasicBlock * 1252XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 1253 MachineBasicBlock *BB) const { 1254 const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 1255 DebugLoc dl = MI->getDebugLoc(); 1256 assert((MI->getOpcode() == XCore::SELECT_CC) && 1257 "Unexpected instr type to insert"); 1258 1259 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond 1260 // control-flow pattern. The incoming instruction knows the destination vreg 1261 // to set, the condition code register to branch on, the true/false values to 1262 // select between, and a branch opcode to use. 1263 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1264 MachineFunction::iterator It = BB; 1265 ++It; 1266 1267 // thisMBB: 1268 // ... 1269 // TrueVal = ... 1270 // cmpTY ccX, r1, r2 1271 // bCC copy1MBB 1272 // fallthrough --> copy0MBB 1273 MachineBasicBlock *thisMBB = BB; 1274 MachineFunction *F = BB->getParent(); 1275 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 1276 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); 1277 F->insert(It, copy0MBB); 1278 F->insert(It, sinkMBB); 1279 1280 // Transfer the remainder of BB and its successor edges to sinkMBB. 1281 sinkMBB->splice(sinkMBB->begin(), BB, 1282 llvm::next(MachineBasicBlock::iterator(MI)), 1283 BB->end()); 1284 sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 1285 1286 // Next, add the true and fallthrough blocks as its successors. 1287 BB->addSuccessor(copy0MBB); 1288 BB->addSuccessor(sinkMBB); 1289 1290 BuildMI(BB, dl, TII.get(XCore::BRFT_lru6)) 1291 .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB); 1292 1293 // copy0MBB: 1294 // %FalseValue = ... 1295 // # fallthrough to sinkMBB 1296 BB = copy0MBB; 1297 1298 // Update machine-CFG edges 1299 BB->addSuccessor(sinkMBB); 1300 1301 // sinkMBB: 1302 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 1303 // ... 1304 BB = sinkMBB; 1305 BuildMI(*BB, BB->begin(), dl, 1306 TII.get(XCore::PHI), MI->getOperand(0).getReg()) 1307 .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB) 1308 .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB); 1309 1310 MI->eraseFromParent(); // The pseudo instruction is gone now. 1311 return BB; 1312} 1313 1314//===----------------------------------------------------------------------===// 1315// Target Optimization Hooks 1316//===----------------------------------------------------------------------===// 1317 1318SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, 1319 DAGCombinerInfo &DCI) const { 1320 SelectionDAG &DAG = DCI.DAG; 1321 DebugLoc dl = N->getDebugLoc(); 1322 switch (N->getOpcode()) { 1323 default: break; 1324 case XCoreISD::LADD: { 1325 SDValue N0 = N->getOperand(0); 1326 SDValue N1 = N->getOperand(1); 1327 SDValue N2 = N->getOperand(2); 1328 ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0); 1329 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); 1330 EVT VT = N0.getValueType(); 1331 1332 // canonicalize constant to RHS 1333 if (N0C && !N1C) 1334 return DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N1, N0, N2); 1335 1336 // fold (ladd 0, 0, x) -> 0, x & 1 1337 if (N0C && N0C->isNullValue() && N1C && N1C->isNullValue()) { 1338 SDValue Carry = DAG.getConstant(0, VT); 1339 SDValue Result = DAG.getNode(ISD::AND, dl, VT, N2, 1340 DAG.getConstant(1, VT)); 1341 SDValue Ops [] = { Carry, Result }; 1342 return DAG.getMergeValues(Ops, 2, dl); 1343 } 1344 1345 // fold (ladd x, 0, y) -> 0, add x, y iff carry is unused and y has only the 1346 // low bit set 1347 if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 0)) { 1348 APInt KnownZero, KnownOne; 1349 APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), 1350 VT.getSizeInBits() - 1); 1351 DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne); 1352 if (KnownZero == Mask) { 1353 SDValue Carry = DAG.getConstant(0, VT); 1354 SDValue Result = DAG.getNode(ISD::ADD, dl, VT, N0, N2); 1355 SDValue Ops [] = { Carry, Result }; 1356 return DAG.getMergeValues(Ops, 2, dl); 1357 } 1358 } 1359 } 1360 break; 1361 case XCoreISD::LSUB: { 1362 SDValue N0 = N->getOperand(0); 1363 SDValue N1 = N->getOperand(1); 1364 SDValue N2 = N->getOperand(2); 1365 ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0); 1366 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); 1367 EVT VT = N0.getValueType(); 1368 1369 // fold (lsub 0, 0, x) -> x, -x iff x has only the low bit set 1370 if (N0C && N0C->isNullValue() && N1C && N1C->isNullValue()) { 1371 APInt KnownZero, KnownOne; 1372 APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), 1373 VT.getSizeInBits() - 1); 1374 DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne); 1375 if (KnownZero == Mask) { 1376 SDValue Borrow = N2; 1377 SDValue Result = DAG.getNode(ISD::SUB, dl, VT, 1378 DAG.getConstant(0, VT), N2); 1379 SDValue Ops [] = { Borrow, Result }; 1380 return DAG.getMergeValues(Ops, 2, dl); 1381 } 1382 } 1383 1384 // fold (lsub x, 0, y) -> 0, sub x, y iff borrow is unused and y has only the 1385 // low bit set 1386 if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 0)) { 1387 APInt KnownZero, KnownOne; 1388 APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), 1389 VT.getSizeInBits() - 1); 1390 DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne); 1391 if (KnownZero == Mask) { 1392 SDValue Borrow = DAG.getConstant(0, VT); 1393 SDValue Result = DAG.getNode(ISD::SUB, dl, VT, N0, N2); 1394 SDValue Ops [] = { Borrow, Result }; 1395 return DAG.getMergeValues(Ops, 2, dl); 1396 } 1397 } 1398 } 1399 break; 1400 case XCoreISD::LMUL: { 1401 SDValue N0 = N->getOperand(0); 1402 SDValue N1 = N->getOperand(1); 1403 SDValue N2 = N->getOperand(2); 1404 SDValue N3 = N->getOperand(3); 1405 ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0); 1406 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); 1407 EVT VT = N0.getValueType(); 1408 // Canonicalize multiplicative constant to RHS. If both multiplicative 1409 // operands are constant canonicalize smallest to RHS. 1410 if ((N0C && !N1C) || 1411 (N0C && N1C && N0C->getZExtValue() < N1C->getZExtValue())) 1412 return DAG.getNode(XCoreISD::LMUL, dl, DAG.getVTList(VT, VT), N1, N0, N2, N3); 1413 1414 // lmul(x, 0, a, b) 1415 if (N1C && N1C->isNullValue()) { 1416 // If the high result is unused fold to add(a, b) 1417 if (N->hasNUsesOfValue(0, 0)) { 1418 SDValue Lo = DAG.getNode(ISD::ADD, dl, VT, N2, N3); 1419 SDValue Ops [] = { Lo, Lo }; 1420 return DAG.getMergeValues(Ops, 2, dl); 1421 } 1422 // Otherwise fold to ladd(a, b, 0) 1423 return DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N2, N3, N1); 1424 } 1425 } 1426 break; 1427 case ISD::ADD: { 1428 // Fold 32 bit expressions such as add(add(mul(x,y),a),b) -> 1429 // lmul(x, y, a, b). The high result of lmul will be ignored. 1430 // This is only profitable if the intermediate results are unused 1431 // elsewhere. 1432 SDValue Mul0, Mul1, Addend0, Addend1; 1433 if (N->getValueType(0) == MVT::i32 && 1434 isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, true)) { 1435 SDValue Ignored = DAG.getNode(XCoreISD::LMUL, dl, 1436 DAG.getVTList(MVT::i32, MVT::i32), Mul0, 1437 Mul1, Addend0, Addend1); 1438 SDValue Result(Ignored.getNode(), 1); 1439 return Result; 1440 } 1441 APInt HighMask = APInt::getHighBitsSet(64, 32); 1442 // Fold 64 bit expression such as add(add(mul(x,y),a),b) -> 1443 // lmul(x, y, a, b) if all operands are zero-extended. We do this 1444 // before type legalization as it is messy to match the operands after 1445 // that. 1446 if (N->getValueType(0) == MVT::i64 && 1447 isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, false) && 1448 DAG.MaskedValueIsZero(Mul0, HighMask) && 1449 DAG.MaskedValueIsZero(Mul1, HighMask) && 1450 DAG.MaskedValueIsZero(Addend0, HighMask) && 1451 DAG.MaskedValueIsZero(Addend1, HighMask)) { 1452 SDValue Mul0L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 1453 Mul0, DAG.getConstant(0, MVT::i32)); 1454 SDValue Mul1L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 1455 Mul1, DAG.getConstant(0, MVT::i32)); 1456 SDValue Addend0L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 1457 Addend0, DAG.getConstant(0, MVT::i32)); 1458 SDValue Addend1L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 1459 Addend1, DAG.getConstant(0, MVT::i32)); 1460 SDValue Hi = DAG.getNode(XCoreISD::LMUL, dl, 1461 DAG.getVTList(MVT::i32, MVT::i32), Mul0L, Mul1L, 1462 Addend0L, Addend1L); 1463 SDValue Lo(Hi.getNode(), 1); 1464 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 1465 } 1466 } 1467 break; 1468 case ISD::STORE: { 1469 // Replace unaligned store of unaligned load with memmove. 1470 StoreSDNode *ST = cast<StoreSDNode>(N); 1471 if (!DCI.isBeforeLegalize() || 1472 allowsUnalignedMemoryAccesses(ST->getMemoryVT()) || 1473 ST->isVolatile() || ST->isIndexed()) { 1474 break; 1475 } 1476 SDValue Chain = ST->getChain(); 1477 1478 unsigned StoreBits = ST->getMemoryVT().getStoreSizeInBits(); 1479 if (StoreBits % 8) { 1480 break; 1481 } 1482 unsigned ABIAlignment = getTargetData()->getABITypeAlignment( 1483 ST->getMemoryVT().getTypeForEVT(*DCI.DAG.getContext())); 1484 unsigned Alignment = ST->getAlignment(); 1485 if (Alignment >= ABIAlignment) { 1486 break; 1487 } 1488 1489 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(ST->getValue())) { 1490 if (LD->hasNUsesOfValue(1, 0) && ST->getMemoryVT() == LD->getMemoryVT() && 1491 LD->getAlignment() == Alignment && 1492 !LD->isVolatile() && !LD->isIndexed() && 1493 Chain.reachesChainWithoutSideEffects(SDValue(LD, 1))) { 1494 return DAG.getMemmove(Chain, dl, ST->getBasePtr(), 1495 LD->getBasePtr(), 1496 DAG.getConstant(StoreBits/8, MVT::i32), 1497 Alignment, false, ST->getPointerInfo(), 1498 LD->getPointerInfo()); 1499 } 1500 } 1501 break; 1502 } 1503 } 1504 return SDValue(); 1505} 1506 1507void XCoreTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, 1508 const APInt &Mask, 1509 APInt &KnownZero, 1510 APInt &KnownOne, 1511 const SelectionDAG &DAG, 1512 unsigned Depth) const { 1513 KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); 1514 switch (Op.getOpcode()) { 1515 default: break; 1516 case XCoreISD::LADD: 1517 case XCoreISD::LSUB: 1518 if (Op.getResNo() == 0) { 1519 // Top bits of carry / borrow are clear. 1520 KnownZero = APInt::getHighBitsSet(Mask.getBitWidth(), 1521 Mask.getBitWidth() - 1); 1522 KnownZero &= Mask; 1523 } 1524 break; 1525 } 1526} 1527 1528//===----------------------------------------------------------------------===// 1529// Addressing mode description hooks 1530//===----------------------------------------------------------------------===// 1531 1532static inline bool isImmUs(int64_t val) 1533{ 1534 return (val >= 0 && val <= 11); 1535} 1536 1537static inline bool isImmUs2(int64_t val) 1538{ 1539 return (val%2 == 0 && isImmUs(val/2)); 1540} 1541 1542static inline bool isImmUs4(int64_t val) 1543{ 1544 return (val%4 == 0 && isImmUs(val/4)); 1545} 1546 1547/// isLegalAddressingMode - Return true if the addressing mode represented 1548/// by AM is legal for this target, for a load/store of the specified type. 1549bool 1550XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM, 1551 const Type *Ty) const { 1552 if (Ty->getTypeID() == Type::VoidTyID) 1553 return AM.Scale == 0 && isImmUs(AM.BaseOffs) && isImmUs4(AM.BaseOffs); 1554 1555 const TargetData *TD = TM.getTargetData(); 1556 unsigned Size = TD->getTypeAllocSize(Ty); 1557 if (AM.BaseGV) { 1558 return Size >= 4 && !AM.HasBaseReg && AM.Scale == 0 && 1559 AM.BaseOffs%4 == 0; 1560 } 1561 1562 switch (Size) { 1563 case 1: 1564 // reg + imm 1565 if (AM.Scale == 0) { 1566 return isImmUs(AM.BaseOffs); 1567 } 1568 // reg + reg 1569 return AM.Scale == 1 && AM.BaseOffs == 0; 1570 case 2: 1571 case 3: 1572 // reg + imm 1573 if (AM.Scale == 0) { 1574 return isImmUs2(AM.BaseOffs); 1575 } 1576 // reg + reg<<1 1577 return AM.Scale == 2 && AM.BaseOffs == 0; 1578 default: 1579 // reg + imm 1580 if (AM.Scale == 0) { 1581 return isImmUs4(AM.BaseOffs); 1582 } 1583 // reg + reg<<2 1584 return AM.Scale == 4 && AM.BaseOffs == 0; 1585 } 1586 1587 return false; 1588} 1589 1590//===----------------------------------------------------------------------===// 1591// XCore Inline Assembly Support 1592//===----------------------------------------------------------------------===// 1593 1594std::vector<unsigned> XCoreTargetLowering:: 1595getRegClassForInlineAsmConstraint(const std::string &Constraint, 1596 EVT VT) const 1597{ 1598 if (Constraint.size() != 1) 1599 return std::vector<unsigned>(); 1600 1601 switch (Constraint[0]) { 1602 default : break; 1603 case 'r': 1604 return make_vector<unsigned>(XCore::R0, XCore::R1, XCore::R2, 1605 XCore::R3, XCore::R4, XCore::R5, 1606 XCore::R6, XCore::R7, XCore::R8, 1607 XCore::R9, XCore::R10, XCore::R11, 0); 1608 break; 1609 } 1610 return std::vector<unsigned>(); 1611} 1612