XCoreISelLowering.cpp revision b3e717192635873a0d8491fc45ddb64c0e4bda15
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 "XCoreTargetMachine.h" 20#include "XCoreSubtarget.h" 21#include "llvm/DerivedTypes.h" 22#include "llvm/Function.h" 23#include "llvm/Intrinsics.h" 24#include "llvm/CallingConv.h" 25#include "llvm/GlobalVariable.h" 26#include "llvm/GlobalAlias.h" 27#include "llvm/CodeGen/CallingConvLower.h" 28#include "llvm/CodeGen/MachineFrameInfo.h" 29#include "llvm/CodeGen/MachineFunction.h" 30#include "llvm/CodeGen/MachineInstrBuilder.h" 31#include "llvm/CodeGen/MachineRegisterInfo.h" 32#include "llvm/CodeGen/SelectionDAGISel.h" 33#include "llvm/CodeGen/ValueTypes.h" 34#include "llvm/Support/Debug.h" 35#include "llvm/Support/ErrorHandling.h" 36#include "llvm/ADT/VectorExtras.h" 37#include <queue> 38#include <set> 39using namespace llvm; 40 41const char *XCoreTargetLowering:: 42getTargetNodeName(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 default : return NULL; 53 } 54} 55 56XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) 57 : TargetLowering(XTM), 58 TM(XTM), 59 Subtarget(*XTM.getSubtargetImpl()) { 60 61 // Set up the register classes. 62 addRegisterClass(MVT::i32, XCore::GRRegsRegisterClass); 63 64 // Compute derived properties from the register classes 65 computeRegisterProperties(); 66 67 // Division is expensive 68 setIntDivIsCheap(false); 69 70 setShiftAmountType(MVT::i32); 71 setStackPointerRegisterToSaveRestore(XCore::SP); 72 73 setSchedulingPreference(SchedulingForRegPressure); 74 75 // Use i32 for setcc operations results (slt, sgt, ...). 76 setBooleanContents(ZeroOrOneBooleanContent); 77 78 // XCore does not have the NodeTypes below. 79 setOperationAction(ISD::BR_CC, MVT::Other, Expand); 80 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 81 setOperationAction(ISD::ADDC, MVT::i32, Expand); 82 setOperationAction(ISD::ADDE, MVT::i32, Expand); 83 setOperationAction(ISD::SUBC, MVT::i32, Expand); 84 setOperationAction(ISD::SUBE, MVT::i32, Expand); 85 86 // Stop the combiner recombining select and set_cc 87 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); 88 89 // 64bit 90 if (!Subtarget.isXS1A()) { 91 setOperationAction(ISD::ADD, MVT::i64, Custom); 92 setOperationAction(ISD::SUB, MVT::i64, Custom); 93 } 94 if (Subtarget.isXS1A()) { 95 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); 96 } 97 setOperationAction(ISD::MULHS, MVT::i32, Expand); 98 setOperationAction(ISD::MULHU, MVT::i32, Expand); 99 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); 100 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); 101 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); 102 103 // Bit Manipulation 104 setOperationAction(ISD::CTPOP, MVT::i32, Expand); 105 setOperationAction(ISD::ROTL , MVT::i32, Expand); 106 setOperationAction(ISD::ROTR , MVT::i32, Expand); 107 108 setOperationAction(ISD::TRAP, MVT::Other, Legal); 109 110 // Expand jump tables for now 111 setOperationAction(ISD::BR_JT, MVT::Other, Expand); 112 setOperationAction(ISD::JumpTable, MVT::i32, Custom); 113 114 // RET must be custom lowered, to meet ABI requirements 115 setOperationAction(ISD::RET, MVT::Other, Custom); 116 117 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 118 119 // Thread Local Storage 120 setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); 121 122 // Conversion of i64 -> double produces constantpool nodes 123 setOperationAction(ISD::ConstantPool, MVT::i32, Custom); 124 125 // Loads 126 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 127 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 128 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 129 130 setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 131 setLoadExtAction(ISD::ZEXTLOAD, MVT::i16, Expand); 132 133 // Custom expand misaligned loads / stores. 134 setOperationAction(ISD::LOAD, MVT::i32, Custom); 135 setOperationAction(ISD::STORE, MVT::i32, Custom); 136 137 // Varargs 138 setOperationAction(ISD::VAEND, MVT::Other, Expand); 139 setOperationAction(ISD::VACOPY, MVT::Other, Expand); 140 setOperationAction(ISD::VAARG, MVT::Other, Custom); 141 setOperationAction(ISD::VASTART, MVT::Other, Custom); 142 143 // Dynamic stack 144 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); 145 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); 146 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); 147 148 // Debug 149 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand); 150 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); 151 152 maxStoresPerMemset = 4; 153 maxStoresPerMemmove = maxStoresPerMemcpy = 2; 154 155 // We have target-specific dag combine patterns for the following nodes: 156 setTargetDAGCombine(ISD::STORE); 157} 158 159SDValue XCoreTargetLowering:: 160LowerOperation(SDValue Op, SelectionDAG &DAG) { 161 switch (Op.getOpcode()) 162 { 163 case ISD::CALL: return LowerCALL(Op, DAG); 164 case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); 165 case ISD::RET: return LowerRET(Op, DAG); 166 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 167 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); 168 case ISD::ConstantPool: return LowerConstantPool(Op, DAG); 169 case ISD::JumpTable: return LowerJumpTable(Op, DAG); 170 case ISD::LOAD: return LowerLOAD(Op, DAG); 171 case ISD::STORE: return LowerSTORE(Op, DAG); 172 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 173 case ISD::VAARG: return LowerVAARG(Op, DAG); 174 case ISD::VASTART: return LowerVASTART(Op, DAG); 175 // FIXME: Remove these when LegalizeDAGTypes lands. 176 case ISD::ADD: 177 case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG); 178 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 179 default: 180 llvm_unreachable("unimplemented operand"); 181 return SDValue(); 182 } 183} 184 185/// ReplaceNodeResults - Replace the results of node with an illegal result 186/// type with new values built out of custom code. 187void XCoreTargetLowering::ReplaceNodeResults(SDNode *N, 188 SmallVectorImpl<SDValue>&Results, 189 SelectionDAG &DAG) { 190 switch (N->getOpcode()) { 191 default: 192 llvm_unreachable("Don't know how to custom expand this!"); 193 return; 194 case ISD::ADD: 195 case ISD::SUB: 196 Results.push_back(ExpandADDSUB(N, DAG)); 197 return; 198 } 199} 200 201/// getFunctionAlignment - Return the Log2 alignment of this function. 202unsigned XCoreTargetLowering:: 203getFunctionAlignment(const Function *) const { 204 return 1; 205} 206 207//===----------------------------------------------------------------------===// 208// Misc Lower Operation implementation 209//===----------------------------------------------------------------------===// 210 211SDValue XCoreTargetLowering:: 212LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) 213{ 214 DebugLoc dl = Op.getDebugLoc(); 215 SDValue Cond = DAG.getNode(ISD::SETCC, dl, MVT::i32, Op.getOperand(2), 216 Op.getOperand(3), Op.getOperand(4)); 217 return DAG.getNode(ISD::SELECT, dl, MVT::i32, Cond, Op.getOperand(0), 218 Op.getOperand(1)); 219} 220 221SDValue XCoreTargetLowering:: 222getGlobalAddressWrapper(SDValue GA, GlobalValue *GV, SelectionDAG &DAG) 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 } else if (!Subtarget.isXS1A()) { 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 } 240 return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA); 241} 242 243SDValue XCoreTargetLowering:: 244LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) 245{ 246 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 247 SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32); 248 // If it's a debug information descriptor, don't mess with it. 249 if (DAG.isVerifiedDebugInfoDesc(Op)) 250 return GA; 251 return getGlobalAddressWrapper(GA, GV, DAG); 252} 253 254static 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 259static inline bool isZeroLengthArray(const Type *Ty) { 260 const ArrayType *AT = dyn_cast_or_null<ArrayType>(Ty); 261 return AT && (AT->getNumElements() == 0); 262} 263 264SDValue XCoreTargetLowering:: 265LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) 266{ 267 // FIXME there isn't really debug info here 268 DebugLoc dl = Op.getDebugLoc(); 269 // transform to label + getid() * size 270 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 271 SDValue GA = DAG.getTargetGlobalAddress(GV, 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 const Type *Ty = cast<PointerType>(GV->getType())->getElementType(); 283 if (!Ty->isSized() || isZeroLengthArray(Ty)) { 284#ifndef NDEBUG 285 cerr << "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 298SDValue XCoreTargetLowering:: 299LowerConstantPool(SDValue Op, SelectionDAG &DAG) 300{ 301 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 302 // FIXME there isn't really debug info here 303 DebugLoc dl = CP->getDebugLoc(); 304 if (Subtarget.isXS1A()) { 305 llvm_unreachable("Lowering of constant pool unimplemented"); 306 return SDValue(); 307 } else { 308 MVT PtrVT = Op.getValueType(); 309 SDValue Res; 310 if (CP->isMachineConstantPoolEntry()) { 311 Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, 312 CP->getAlignment()); 313 } else { 314 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, 315 CP->getAlignment()); 316 } 317 return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, Res); 318 } 319} 320 321SDValue XCoreTargetLowering:: 322LowerJumpTable(SDValue Op, SelectionDAG &DAG) 323{ 324 // FIXME there isn't really debug info here 325 DebugLoc dl = Op.getDebugLoc(); 326 MVT PtrVT = Op.getValueType(); 327 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); 328 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); 329 return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, JTI); 330} 331 332static bool 333IsWordAlignedBasePlusConstantOffset(SDValue Addr, SDValue &AlignedBase, 334 int64_t &Offset) 335{ 336 if (Addr.getOpcode() != ISD::ADD) { 337 return false; 338 } 339 ConstantSDNode *CN = 0; 340 if (!(CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) { 341 return false; 342 } 343 int64_t off = CN->getSExtValue(); 344 const SDValue &Base = Addr.getOperand(0); 345 const SDValue *Root = &Base; 346 if (Base.getOpcode() == ISD::ADD && 347 Base.getOperand(1).getOpcode() == ISD::SHL) { 348 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Base.getOperand(1) 349 .getOperand(1)); 350 if (CN && (CN->getSExtValue() >= 2)) { 351 Root = &Base.getOperand(0); 352 } 353 } 354 if (isa<FrameIndexSDNode>(*Root)) { 355 // All frame indicies are word aligned 356 AlignedBase = Base; 357 Offset = off; 358 return true; 359 } 360 if (Root->getOpcode() == XCoreISD::DPRelativeWrapper || 361 Root->getOpcode() == XCoreISD::CPRelativeWrapper) { 362 // All dp / cp relative addresses are word aligned 363 AlignedBase = Base; 364 Offset = off; 365 return true; 366 } 367 return false; 368} 369 370SDValue XCoreTargetLowering:: 371LowerLOAD(SDValue Op, SelectionDAG &DAG) 372{ 373 LoadSDNode *LD = cast<LoadSDNode>(Op); 374 assert(LD->getExtensionType() == ISD::NON_EXTLOAD && "Unexpected extension type"); 375 assert(LD->getMemoryVT() == MVT::i32 && "Unexpected load MVT"); 376 if (allowsUnalignedMemoryAccesses()) { 377 return SDValue(); 378 } 379 unsigned ABIAlignment = getTargetData()-> 380 getABITypeAlignment(LD->getMemoryVT().getTypeForMVT(*DAG.getContext())); 381 // Leave aligned load alone. 382 if (LD->getAlignment() >= ABIAlignment) { 383 return SDValue(); 384 } 385 SDValue Chain = LD->getChain(); 386 SDValue BasePtr = LD->getBasePtr(); 387 DebugLoc dl = Op.getDebugLoc(); 388 389 SDValue Base; 390 int64_t Offset; 391 if (!LD->isVolatile() && 392 IsWordAlignedBasePlusConstantOffset(BasePtr, Base, Offset)) { 393 if (Offset % 4 == 0) { 394 // We've managed to infer better alignment information than the load 395 // already has. Use an aligned load. 396 return DAG.getLoad(getPointerTy(), dl, Chain, BasePtr, NULL, 4); 397 } 398 // Lower to 399 // ldw low, base[offset >> 2] 400 // ldw high, base[(offset >> 2) + 1] 401 // shr low_shifted, low, (offset & 0x3) * 8 402 // shl high_shifted, high, 32 - (offset & 0x3) * 8 403 // or result, low_shifted, high_shifted 404 SDValue LowOffset = DAG.getConstant(Offset & ~0x3, MVT::i32); 405 SDValue HighOffset = DAG.getConstant((Offset & ~0x3) + 4, MVT::i32); 406 SDValue LowShift = DAG.getConstant((Offset & 0x3) * 8, MVT::i32); 407 SDValue HighShift = DAG.getConstant(32 - (Offset & 0x3) * 8, MVT::i32); 408 409 SDValue LowAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, Base, LowOffset); 410 SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, Base, HighOffset); 411 412 SDValue Low = DAG.getLoad(getPointerTy(), dl, Chain, 413 LowAddr, NULL, 4); 414 SDValue High = DAG.getLoad(getPointerTy(), dl, Chain, 415 HighAddr, NULL, 4); 416 SDValue LowShifted = DAG.getNode(ISD::SRL, dl, MVT::i32, Low, LowShift); 417 SDValue HighShifted = DAG.getNode(ISD::SHL, dl, MVT::i32, High, HighShift); 418 SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, LowShifted, HighShifted); 419 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Low.getValue(1), 420 High.getValue(1)); 421 SDValue Ops[] = { Result, Chain }; 422 return DAG.getMergeValues(Ops, 2, dl); 423 } 424 425 if (LD->getAlignment() == 2) { 426 int SVOffset = LD->getSrcValueOffset(); 427 SDValue Low = DAG.getExtLoad(ISD::ZEXTLOAD, dl, MVT::i32, Chain, 428 BasePtr, LD->getSrcValue(), SVOffset, MVT::i16, 429 LD->isVolatile(), 2); 430 SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr, 431 DAG.getConstant(2, MVT::i32)); 432 SDValue High = DAG.getExtLoad(ISD::EXTLOAD, dl, MVT::i32, Chain, 433 HighAddr, LD->getSrcValue(), SVOffset + 2, 434 MVT::i16, LD->isVolatile(), 2); 435 SDValue HighShifted = DAG.getNode(ISD::SHL, dl, MVT::i32, High, 436 DAG.getConstant(16, MVT::i32)); 437 SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, Low, HighShifted); 438 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Low.getValue(1), 439 High.getValue(1)); 440 SDValue Ops[] = { Result, Chain }; 441 return DAG.getMergeValues(Ops, 2, dl); 442 } 443 444 // Lower to a call to __misaligned_load(BasePtr). 445 const Type *IntPtrTy = getTargetData()->getIntPtrType(); 446 TargetLowering::ArgListTy Args; 447 TargetLowering::ArgListEntry Entry; 448 449 Entry.Ty = IntPtrTy; 450 Entry.Node = BasePtr; 451 Args.push_back(Entry); 452 453 std::pair<SDValue, SDValue> CallResult = 454 LowerCallTo(Chain, IntPtrTy, false, false, 455 false, false, 0, CallingConv::C, false, 456 DAG.getExternalSymbol("__misaligned_load", getPointerTy()), 457 Args, DAG, dl); 458 459 SDValue Ops[] = 460 { CallResult.first, CallResult.second }; 461 462 return DAG.getMergeValues(Ops, 2, dl); 463} 464 465SDValue XCoreTargetLowering:: 466LowerSTORE(SDValue Op, SelectionDAG &DAG) 467{ 468 StoreSDNode *ST = cast<StoreSDNode>(Op); 469 assert(!ST->isTruncatingStore() && "Unexpected store type"); 470 assert(ST->getMemoryVT() == MVT::i32 && "Unexpected store MVT"); 471 if (allowsUnalignedMemoryAccesses()) { 472 return SDValue(); 473 } 474 unsigned ABIAlignment = getTargetData()-> 475 getABITypeAlignment(ST->getMemoryVT().getTypeForMVT(*DAG.getContext())); 476 // Leave aligned store alone. 477 if (ST->getAlignment() >= ABIAlignment) { 478 return SDValue(); 479 } 480 SDValue Chain = ST->getChain(); 481 SDValue BasePtr = ST->getBasePtr(); 482 SDValue Value = ST->getValue(); 483 DebugLoc dl = Op.getDebugLoc(); 484 485 if (ST->getAlignment() == 2) { 486 int SVOffset = ST->getSrcValueOffset(); 487 SDValue Low = Value; 488 SDValue High = DAG.getNode(ISD::SRL, dl, MVT::i32, Value, 489 DAG.getConstant(16, MVT::i32)); 490 SDValue StoreLow = DAG.getTruncStore(Chain, dl, Low, BasePtr, 491 ST->getSrcValue(), SVOffset, MVT::i16, 492 ST->isVolatile(), 2); 493 SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr, 494 DAG.getConstant(2, MVT::i32)); 495 SDValue StoreHigh = DAG.getTruncStore(Chain, dl, High, HighAddr, 496 ST->getSrcValue(), SVOffset + 2, 497 MVT::i16, ST->isVolatile(), 2); 498 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, StoreLow, StoreHigh); 499 } 500 501 // Lower to a call to __misaligned_store(BasePtr, Value). 502 const Type *IntPtrTy = getTargetData()->getIntPtrType(); 503 TargetLowering::ArgListTy Args; 504 TargetLowering::ArgListEntry Entry; 505 506 Entry.Ty = IntPtrTy; 507 Entry.Node = BasePtr; 508 Args.push_back(Entry); 509 510 Entry.Node = Value; 511 Args.push_back(Entry); 512 513 std::pair<SDValue, SDValue> CallResult = 514 LowerCallTo(Chain, Type::VoidTy, false, false, 515 false, false, 0, CallingConv::C, false, 516 DAG.getExternalSymbol("__misaligned_store", getPointerTy()), 517 Args, DAG, dl); 518 519 return CallResult.second; 520} 521 522SDValue XCoreTargetLowering:: 523ExpandADDSUB(SDNode *N, SelectionDAG &DAG) 524{ 525 assert(N->getValueType(0) == MVT::i64 && 526 (N->getOpcode() == ISD::ADD || N->getOpcode() == ISD::SUB) && 527 "Unknown operand to lower!"); 528 assert(!Subtarget.isXS1A() && "Cannot custom lower ADD/SUB on xs1a"); 529 DebugLoc dl = N->getDebugLoc(); 530 531 // Extract components 532 SDValue LHSL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 533 N->getOperand(0), DAG.getConstant(0, MVT::i32)); 534 SDValue LHSH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 535 N->getOperand(0), DAG.getConstant(1, MVT::i32)); 536 SDValue RHSL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 537 N->getOperand(1), DAG.getConstant(0, MVT::i32)); 538 SDValue RHSH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, 539 N->getOperand(1), DAG.getConstant(1, MVT::i32)); 540 541 // Expand 542 unsigned Opcode = (N->getOpcode() == ISD::ADD) ? XCoreISD::LADD : 543 XCoreISD::LSUB; 544 SDValue Zero = DAG.getConstant(0, MVT::i32); 545 SDValue Carry = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32), 546 LHSL, RHSL, Zero); 547 SDValue Lo(Carry.getNode(), 1); 548 549 SDValue Ignored = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32), 550 LHSH, RHSH, Carry); 551 SDValue Hi(Ignored.getNode(), 1); 552 // Merge the pieces 553 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi); 554} 555 556SDValue XCoreTargetLowering:: 557LowerVAARG(SDValue Op, SelectionDAG &DAG) 558{ 559 llvm_unreachable("unimplemented"); 560 // FIX Arguments passed by reference need a extra dereference. 561 SDNode *Node = Op.getNode(); 562 DebugLoc dl = Node->getDebugLoc(); 563 const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 564 MVT VT = Node->getValueType(0); 565 SDValue VAList = DAG.getLoad(getPointerTy(), dl, Node->getOperand(0), 566 Node->getOperand(1), V, 0); 567 // Increment the pointer, VAList, to the next vararg 568 SDValue Tmp3 = DAG.getNode(ISD::ADD, dl, getPointerTy(), VAList, 569 DAG.getConstant(VT.getSizeInBits(), 570 getPointerTy())); 571 // Store the incremented VAList to the legalized pointer 572 Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), V, 0); 573 // Load the actual argument out of the pointer VAList 574 return DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0); 575} 576 577SDValue XCoreTargetLowering:: 578LowerVASTART(SDValue Op, SelectionDAG &DAG) 579{ 580 DebugLoc dl = Op.getDebugLoc(); 581 // vastart stores the address of the VarArgsFrameIndex slot into the 582 // memory location argument 583 MachineFunction &MF = DAG.getMachineFunction(); 584 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 585 SDValue Addr = DAG.getFrameIndex(XFI->getVarArgsFrameIndex(), MVT::i32); 586 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 587 return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), SV, 0); 588} 589 590SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { 591 DebugLoc dl = Op.getDebugLoc(); 592 // Depths > 0 not supported yet! 593 if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0) 594 return SDValue(); 595 596 MachineFunction &MF = DAG.getMachineFunction(); 597 const TargetRegisterInfo *RegInfo = getTargetMachine().getRegisterInfo(); 598 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, 599 RegInfo->getFrameRegister(MF), MVT::i32); 600} 601 602//===----------------------------------------------------------------------===// 603// Calling Convention Implementation 604// 605// The lower operations present on calling convention works on this order: 606// LowerCALL (virt regs --> phys regs, virt regs --> stack) 607// LowerFORMAL_ARGUMENTS (phys --> virt regs, stack --> virt regs) 608// LowerRET (virt regs --> phys regs) 609// LowerCALL (phys regs --> virt regs) 610// 611//===----------------------------------------------------------------------===// 612 613#include "XCoreGenCallingConv.inc" 614 615//===----------------------------------------------------------------------===// 616// CALL Calling Convention Implementation 617//===----------------------------------------------------------------------===// 618 619/// XCore custom CALL implementation 620SDValue XCoreTargetLowering:: 621LowerCALL(SDValue Op, SelectionDAG &DAG) 622{ 623 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); 624 unsigned CallingConv = TheCall->getCallingConv(); 625 // For now, only CallingConv::C implemented 626 switch (CallingConv) 627 { 628 default: 629 llvm_unreachable("Unsupported calling convention"); 630 case CallingConv::Fast: 631 case CallingConv::C: 632 return LowerCCCCallTo(Op, DAG, CallingConv); 633 } 634} 635 636/// LowerCCCCallTo - functions arguments are copied from virtual 637/// regs to (physical regs)/(stack frame), CALLSEQ_START and 638/// CALLSEQ_END are emitted. 639/// TODO: isTailCall, sret. 640SDValue XCoreTargetLowering:: 641LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC) 642{ 643 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); 644 SDValue Chain = TheCall->getChain(); 645 SDValue Callee = TheCall->getCallee(); 646 bool isVarArg = TheCall->isVarArg(); 647 DebugLoc dl = Op.getDebugLoc(); 648 649 // Analyze operands of the call, assigning locations to each operand. 650 SmallVector<CCValAssign, 16> ArgLocs; 651 CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, DAG.getContext()); 652 653 // The ABI dictates there should be one stack slot available to the callee 654 // on function entry (for saving lr). 655 CCInfo.AllocateStack(4, 4); 656 657 CCInfo.AnalyzeCallOperands(TheCall, CC_XCore); 658 659 // Get a count of how many bytes are to be pushed on the stack. 660 unsigned NumBytes = CCInfo.getNextStackOffset(); 661 662 Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, 663 getPointerTy(), true)); 664 665 SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 666 SmallVector<SDValue, 12> MemOpChains; 667 668 // Walk the register/memloc assignments, inserting copies/loads. 669 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 670 CCValAssign &VA = ArgLocs[i]; 671 672 // Arguments start after the 5 first operands of ISD::CALL 673 SDValue Arg = TheCall->getArg(i); 674 675 // Promote the value if needed. 676 switch (VA.getLocInfo()) { 677 default: llvm_unreachable("Unknown loc info!"); 678 case CCValAssign::Full: break; 679 case CCValAssign::SExt: 680 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 681 break; 682 case CCValAssign::ZExt: 683 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 684 break; 685 case CCValAssign::AExt: 686 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 687 break; 688 } 689 690 // Arguments that can be passed on register must be kept at 691 // RegsToPass vector 692 if (VA.isRegLoc()) { 693 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 694 } else { 695 assert(VA.isMemLoc()); 696 697 int Offset = VA.getLocMemOffset(); 698 699 MemOpChains.push_back(DAG.getNode(XCoreISD::STWSP, dl, MVT::Other, 700 Chain, Arg, 701 DAG.getConstant(Offset/4, MVT::i32))); 702 } 703 } 704 705 // Transform all store nodes into one single node because 706 // all store nodes are independent of each other. 707 if (!MemOpChains.empty()) 708 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 709 &MemOpChains[0], MemOpChains.size()); 710 711 // Build a sequence of copy-to-reg nodes chained together with token 712 // chain and flag operands which copy the outgoing args into registers. 713 // The InFlag in necessary since all emited instructions must be 714 // stuck together. 715 SDValue InFlag; 716 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 717 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 718 RegsToPass[i].second, InFlag); 719 InFlag = Chain.getValue(1); 720 } 721 722 // If the callee is a GlobalAddress node (quite common, every direct call is) 723 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 724 // Likewise ExternalSymbol -> TargetExternalSymbol. 725 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 726 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i32); 727 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 728 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32); 729 730 // XCoreBranchLink = #chain, #target_address, #opt_in_flags... 731 // = Chain, Callee, Reg#1, Reg#2, ... 732 // 733 // Returns a chain & a flag for retval copy to use. 734 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); 735 SmallVector<SDValue, 8> Ops; 736 Ops.push_back(Chain); 737 Ops.push_back(Callee); 738 739 // Add argument registers to the end of the list so that they are 740 // known live into the call. 741 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 742 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 743 RegsToPass[i].second.getValueType())); 744 745 if (InFlag.getNode()) 746 Ops.push_back(InFlag); 747 748 Chain = DAG.getNode(XCoreISD::BL, dl, NodeTys, &Ops[0], Ops.size()); 749 InFlag = Chain.getValue(1); 750 751 // Create the CALLSEQ_END node. 752 Chain = DAG.getCALLSEQ_END(Chain, 753 DAG.getConstant(NumBytes, getPointerTy(), true), 754 DAG.getConstant(0, getPointerTy(), true), 755 InFlag); 756 InFlag = Chain.getValue(1); 757 758 // Handle result values, copying them out of physregs into vregs that we 759 // return. 760 return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), 761 Op.getResNo()); 762} 763 764/// LowerCallResult - Lower the result values of an ISD::CALL into the 765/// appropriate copies out of appropriate physical registers. This assumes that 766/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call 767/// being lowered. Returns a SDNode with the same number of values as the 768/// ISD::CALL. 769SDNode *XCoreTargetLowering:: 770LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, 771 unsigned CallingConv, SelectionDAG &DAG) { 772 bool isVarArg = TheCall->isVarArg(); 773 DebugLoc dl = TheCall->getDebugLoc(); 774 775 // Assign locations to each value returned by this call. 776 SmallVector<CCValAssign, 16> RVLocs; 777 CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), 778 RVLocs, DAG.getContext()); 779 780 CCInfo.AnalyzeCallResult(TheCall, RetCC_XCore); 781 SmallVector<SDValue, 8> ResultVals; 782 783 // Copy all of the result registers out of their specified physreg. 784 for (unsigned i = 0; i != RVLocs.size(); ++i) { 785 Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 786 RVLocs[i].getValVT(), InFlag).getValue(1); 787 InFlag = Chain.getValue(2); 788 ResultVals.push_back(Chain.getValue(0)); 789 } 790 791 ResultVals.push_back(Chain); 792 793 // Merge everything together with a MERGE_VALUES node. 794 return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), 795 &ResultVals[0], ResultVals.size()).getNode(); 796} 797 798//===----------------------------------------------------------------------===// 799// FORMAL_ARGUMENTS Calling Convention Implementation 800//===----------------------------------------------------------------------===// 801 802/// XCore custom FORMAL_ARGUMENTS implementation 803SDValue XCoreTargetLowering:: 804LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) 805{ 806 unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 807 switch(CC) 808 { 809 default: 810 llvm_unreachable("Unsupported calling convention"); 811 case CallingConv::C: 812 case CallingConv::Fast: 813 return LowerCCCArguments(Op, DAG); 814 } 815} 816 817/// LowerCCCArguments - transform physical registers into 818/// virtual registers and generate load operations for 819/// arguments places on the stack. 820/// TODO: sret 821SDValue XCoreTargetLowering:: 822LowerCCCArguments(SDValue Op, SelectionDAG &DAG) 823{ 824 MachineFunction &MF = DAG.getMachineFunction(); 825 MachineFrameInfo *MFI = MF.getFrameInfo(); 826 MachineRegisterInfo &RegInfo = MF.getRegInfo(); 827 SDValue Root = Op.getOperand(0); 828 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; 829 unsigned CC = MF.getFunction()->getCallingConv(); 830 DebugLoc dl = Op.getDebugLoc(); 831 832 // Assign locations to all of the incoming arguments. 833 SmallVector<CCValAssign, 16> ArgLocs; 834 CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, DAG.getContext()); 835 836 CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_XCore); 837 838 unsigned StackSlotSize = XCoreFrameInfo::stackSlotSize(); 839 840 SmallVector<SDValue, 16> ArgValues; 841 842 unsigned LRSaveSize = StackSlotSize; 843 844 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 845 846 CCValAssign &VA = ArgLocs[i]; 847 848 if (VA.isRegLoc()) { 849 // Arguments passed in registers 850 MVT RegVT = VA.getLocVT(); 851 switch (RegVT.getSimpleVT()) { 852 default: 853 { 854#ifndef NDEBUG 855 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " 856 << RegVT.getSimpleVT() << "\n"; 857#endif 858 llvm_unreachable(0); 859 } 860 case MVT::i32: 861 unsigned VReg = RegInfo.createVirtualRegister( 862 XCore::GRRegsRegisterClass); 863 RegInfo.addLiveIn(VA.getLocReg(), VReg); 864 ArgValues.push_back(DAG.getCopyFromReg(Root, dl, VReg, RegVT)); 865 } 866 } else { 867 // sanity check 868 assert(VA.isMemLoc()); 869 // Load the argument to a virtual register 870 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 871 if (ObjSize > StackSlotSize) { 872 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " 873 << VA.getLocVT().getSimpleVT() 874 << "\n"; 875 } 876 // Create the frame index object for this incoming parameter... 877 int FI = MFI->CreateFixedObject(ObjSize, 878 LRSaveSize + VA.getLocMemOffset()); 879 880 // Create the SelectionDAG nodes corresponding to a load 881 //from this parameter 882 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 883 ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN, NULL, 0)); 884 } 885 } 886 887 if (isVarArg) { 888 /* Argument registers */ 889 static const unsigned ArgRegs[] = { 890 XCore::R0, XCore::R1, XCore::R2, XCore::R3 891 }; 892 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 893 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs, 894 array_lengthof(ArgRegs)); 895 if (FirstVAReg < array_lengthof(ArgRegs)) { 896 SmallVector<SDValue, 4> MemOps; 897 int offset = 0; 898 // Save remaining registers, storing higher register numbers at a higher 899 // address 900 for (unsigned i = array_lengthof(ArgRegs) - 1; i >= FirstVAReg; --i) { 901 // Create a stack slot 902 int FI = MFI->CreateFixedObject(4, offset); 903 if (i == FirstVAReg) { 904 XFI->setVarArgsFrameIndex(FI); 905 } 906 offset -= StackSlotSize; 907 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); 908 // Move argument from phys reg -> virt reg 909 unsigned VReg = RegInfo.createVirtualRegister( 910 XCore::GRRegsRegisterClass); 911 RegInfo.addLiveIn(ArgRegs[i], VReg); 912 SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); 913 // Move argument from virt reg -> stack 914 SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); 915 MemOps.push_back(Store); 916 } 917 if (!MemOps.empty()) 918 Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 919 &MemOps[0], MemOps.size()); 920 } else { 921 // This will point to the next argument passed via stack. 922 XFI->setVarArgsFrameIndex( 923 MFI->CreateFixedObject(4, LRSaveSize + CCInfo.getNextStackOffset())); 924 } 925 } 926 927 ArgValues.push_back(Root); 928 929 // Return the new list of results. 930 std::vector<MVT> RetVT(Op.getNode()->value_begin(), 931 Op.getNode()->value_end()); 932 return DAG.getNode(ISD::MERGE_VALUES, dl, RetVT, 933 &ArgValues[0], ArgValues.size()); 934} 935 936//===----------------------------------------------------------------------===// 937// Return Value Calling Convention Implementation 938//===----------------------------------------------------------------------===// 939 940SDValue XCoreTargetLowering:: 941LowerRET(SDValue Op, SelectionDAG &DAG) 942{ 943 // CCValAssign - represent the assignment of 944 // the return value to a location 945 SmallVector<CCValAssign, 16> RVLocs; 946 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); 947 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); 948 DebugLoc dl = Op.getDebugLoc(); 949 950 // CCState - Info about the registers and stack slot. 951 CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs, DAG.getContext()); 952 953 // Analize return values of ISD::RET 954 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_XCore); 955 956 // If this is the first return lowered for this function, add 957 // the regs to the liveout set for the function. 958 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 959 for (unsigned i = 0; i != RVLocs.size(); ++i) 960 if (RVLocs[i].isRegLoc()) 961 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 962 } 963 964 // The chain is always operand #0 965 SDValue Chain = Op.getOperand(0); 966 SDValue Flag; 967 968 // Copy the result values into the output registers. 969 for (unsigned i = 0; i != RVLocs.size(); ++i) { 970 CCValAssign &VA = RVLocs[i]; 971 assert(VA.isRegLoc() && "Can only return in registers!"); 972 973 // ISD::RET => ret chain, (regnum1,val1), ... 974 // So i*2+1 index only the regnums 975 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 976 Op.getOperand(i*2+1), Flag); 977 978 // guarantee that all emitted copies are 979 // stuck together, avoiding something bad 980 Flag = Chain.getValue(1); 981 } 982 983 // Return on XCore is always a "retsp 0" 984 if (Flag.getNode()) 985 return DAG.getNode(XCoreISD::RETSP, dl, MVT::Other, 986 Chain, DAG.getConstant(0, MVT::i32), Flag); 987 else // Return Void 988 return DAG.getNode(XCoreISD::RETSP, dl, MVT::Other, 989 Chain, DAG.getConstant(0, MVT::i32)); 990} 991 992//===----------------------------------------------------------------------===// 993// Other Lowering Code 994//===----------------------------------------------------------------------===// 995 996MachineBasicBlock * 997XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 998 MachineBasicBlock *BB) const { 999 const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 1000 DebugLoc dl = MI->getDebugLoc(); 1001 assert((MI->getOpcode() == XCore::SELECT_CC) && 1002 "Unexpected instr type to insert"); 1003 1004 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond 1005 // control-flow pattern. The incoming instruction knows the destination vreg 1006 // to set, the condition code register to branch on, the true/false values to 1007 // select between, and a branch opcode to use. 1008 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1009 MachineFunction::iterator It = BB; 1010 ++It; 1011 1012 // thisMBB: 1013 // ... 1014 // TrueVal = ... 1015 // cmpTY ccX, r1, r2 1016 // bCC copy1MBB 1017 // fallthrough --> copy0MBB 1018 MachineBasicBlock *thisMBB = BB; 1019 MachineFunction *F = BB->getParent(); 1020 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 1021 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); 1022 BuildMI(BB, dl, TII.get(XCore::BRFT_lru6)) 1023 .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB); 1024 F->insert(It, copy0MBB); 1025 F->insert(It, sinkMBB); 1026 // Update machine-CFG edges by transferring all successors of the current 1027 // block to the new block which will contain the Phi node for the select. 1028 sinkMBB->transferSuccessors(BB); 1029 // Next, add the true and fallthrough blocks as its successors. 1030 BB->addSuccessor(copy0MBB); 1031 BB->addSuccessor(sinkMBB); 1032 1033 // copy0MBB: 1034 // %FalseValue = ... 1035 // # fallthrough to sinkMBB 1036 BB = copy0MBB; 1037 1038 // Update machine-CFG edges 1039 BB->addSuccessor(sinkMBB); 1040 1041 // sinkMBB: 1042 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 1043 // ... 1044 BB = sinkMBB; 1045 BuildMI(BB, dl, TII.get(XCore::PHI), MI->getOperand(0).getReg()) 1046 .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB) 1047 .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB); 1048 1049 F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. 1050 return BB; 1051} 1052 1053//===----------------------------------------------------------------------===// 1054// Target Optimization Hooks 1055//===----------------------------------------------------------------------===// 1056 1057SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, 1058 DAGCombinerInfo &DCI) const { 1059 SelectionDAG &DAG = DCI.DAG; 1060 DebugLoc dl = N->getDebugLoc(); 1061 switch (N->getOpcode()) { 1062 default: break; 1063 case ISD::STORE: { 1064 // Replace unaligned store of unaligned load with memmove. 1065 StoreSDNode *ST = cast<StoreSDNode>(N); 1066 if (!DCI.isBeforeLegalize() || allowsUnalignedMemoryAccesses() || 1067 ST->isVolatile() || ST->isIndexed()) { 1068 break; 1069 } 1070 SDValue Chain = ST->getChain(); 1071 1072 unsigned StoreBits = ST->getMemoryVT().getStoreSizeInBits(); 1073 if (StoreBits % 8) { 1074 break; 1075 } 1076 unsigned ABIAlignment = getTargetData()-> 1077 getABITypeAlignment(ST->getMemoryVT().getTypeForMVT(*DAG.getContext())); 1078 unsigned Alignment = ST->getAlignment(); 1079 if (Alignment >= ABIAlignment) { 1080 break; 1081 } 1082 1083 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(ST->getValue())) { 1084 if (LD->hasNUsesOfValue(1, 0) && ST->getMemoryVT() == LD->getMemoryVT() && 1085 LD->getAlignment() == Alignment && 1086 !LD->isVolatile() && !LD->isIndexed() && 1087 Chain.reachesChainWithoutSideEffects(SDValue(LD, 1))) { 1088 return DAG.getMemmove(Chain, dl, ST->getBasePtr(), 1089 LD->getBasePtr(), 1090 DAG.getConstant(StoreBits/8, MVT::i32), 1091 Alignment, ST->getSrcValue(), 1092 ST->getSrcValueOffset(), LD->getSrcValue(), 1093 LD->getSrcValueOffset()); 1094 } 1095 } 1096 break; 1097 } 1098 } 1099 return SDValue(); 1100} 1101 1102//===----------------------------------------------------------------------===// 1103// Addressing mode description hooks 1104//===----------------------------------------------------------------------===// 1105 1106static inline bool isImmUs(int64_t val) 1107{ 1108 return (val >= 0 && val <= 11); 1109} 1110 1111static inline bool isImmUs2(int64_t val) 1112{ 1113 return (val%2 == 0 && isImmUs(val/2)); 1114} 1115 1116static inline bool isImmUs4(int64_t val) 1117{ 1118 return (val%4 == 0 && isImmUs(val/4)); 1119} 1120 1121/// isLegalAddressingMode - Return true if the addressing mode represented 1122/// by AM is legal for this target, for a load/store of the specified type. 1123bool 1124XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM, 1125 const Type *Ty) const { 1126 // Be conservative with void 1127 // FIXME: Can we be more aggressive? 1128 if (Ty->getTypeID() == Type::VoidTyID) 1129 return false; 1130 1131 const TargetData *TD = TM.getTargetData(); 1132 unsigned Size = TD->getTypeAllocSize(Ty); 1133 if (AM.BaseGV) { 1134 return Size >= 4 && !AM.HasBaseReg && AM.Scale == 0 && 1135 AM.BaseOffs%4 == 0; 1136 } 1137 1138 switch (Size) { 1139 case 1: 1140 // reg + imm 1141 if (AM.Scale == 0) { 1142 return isImmUs(AM.BaseOffs); 1143 } 1144 // reg + reg 1145 return AM.Scale == 1 && AM.BaseOffs == 0; 1146 case 2: 1147 case 3: 1148 // reg + imm 1149 if (AM.Scale == 0) { 1150 return isImmUs2(AM.BaseOffs); 1151 } 1152 // reg + reg<<1 1153 return AM.Scale == 2 && AM.BaseOffs == 0; 1154 default: 1155 // reg + imm 1156 if (AM.Scale == 0) { 1157 return isImmUs4(AM.BaseOffs); 1158 } 1159 // reg + reg<<2 1160 return AM.Scale == 4 && AM.BaseOffs == 0; 1161 } 1162 1163 return false; 1164} 1165 1166//===----------------------------------------------------------------------===// 1167// XCore Inline Assembly Support 1168//===----------------------------------------------------------------------===// 1169 1170std::vector<unsigned> XCoreTargetLowering:: 1171getRegClassForInlineAsmConstraint(const std::string &Constraint, 1172 MVT VT) const 1173{ 1174 if (Constraint.size() != 1) 1175 return std::vector<unsigned>(); 1176 1177 switch (Constraint[0]) { 1178 default : break; 1179 case 'r': 1180 return make_vector<unsigned>(XCore::R0, XCore::R1, XCore::R2, 1181 XCore::R3, XCore::R4, XCore::R5, 1182 XCore::R6, XCore::R7, XCore::R8, 1183 XCore::R9, XCore::R10, XCore::R11, 0); 1184 break; 1185 } 1186 return std::vector<unsigned>(); 1187} 1188