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