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