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