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