153c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman//===-- X86SelectionDAGInfo.cpp - X86 SelectionDAG Info -------------------===//
253c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman//
353c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman//                     The LLVM Compiler Infrastructure
453c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman//
553c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman// This file is distributed under the University of Illinois Open Source
653c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman// License. See LICENSE.TXT for details.
753c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman//
853c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman//===----------------------------------------------------------------------===//
953c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman//
1053c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman// This file implements the X86SelectionDAGInfo class.
1153c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman//
1253c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman//===----------------------------------------------------------------------===//
1353c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman
14cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "X86InstrInfo.h"
15cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "X86ISelLowering.h"
16cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "X86RegisterInfo.h"
17cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "X86Subtarget.h"
18cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "X86SelectionDAGInfo.h"
19ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman#include "llvm/CodeGen/SelectionDAG.h"
200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
21cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Target/TargetLowering.h"
22cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2353c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohmanusing namespace llvm;
2453c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman
25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "x86-selectiondag-info"
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
27cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesX86SelectionDAGInfo::X86SelectionDAGInfo(const DataLayout &DL)
28cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    : TargetSelectionDAGInfo(&DL) {}
2953c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman
30cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesX86SelectionDAGInfo::~X86SelectionDAGInfo() {}
31ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
32ff7a562751604a9fe13efc75bd59622244b54d35Dan GohmanSDValue
33ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew TrickX86SelectionDAGInfo::EmitTargetCodeForMemset(SelectionDAG &DAG, SDLoc dl,
34ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                             SDValue Chain,
35ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                             SDValue Dst, SDValue Src,
36ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                             SDValue Size, unsigned Align,
37ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                             bool isVolatile,
38e72f2027e9116c55a5b39ac72732df8d6c45d37cChris Lattner                                         MachinePointerInfo DstPtrInfo) const {
39ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
40cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const X86Subtarget &Subtarget = DAG.getTarget().getSubtarget<X86Subtarget>();
41ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
42e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner  // If to a segment-relative address space, use the default lowering.
43e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner  if (DstPtrInfo.getAddrSpace() >= 256)
44e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner    return SDValue();
45a20e1e7ef596842127794372244fd5c646f71296Chad Rosier
46ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  // If not DWORD aligned or size is more than the threshold, call the library.
47ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  // The libc version is likely to be faster for these cases. It can use the
48ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  // address value and run time information about the CPU.
49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if ((Align & 3) != 0 || !ConstantSize ||
50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ConstantSize->getZExtValue() > Subtarget.getMaxInlineSizeThreshold()) {
51ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    // Check to see if there is a specialized entry-point for memory zeroing.
52ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    ConstantSDNode *V = dyn_cast<ConstantSDNode>(Src);
53ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
54ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    if (const char *bzeroEntry =  V &&
55cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        V->isNullValue() ? Subtarget.getBZeroEntry() : nullptr) {
56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      EVT IntPtr = DAG.getTargetLoweringInfo().getPointerTy();
57ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth      Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext());
58ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      TargetLowering::ArgListTy Args;
59ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      TargetLowering::ArgListEntry Entry;
60ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      Entry.Node = Dst;
61ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      Entry.Ty = IntPtrTy;
62ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      Args.push_back(Entry);
63ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      Entry.Node = Size;
64ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      Args.push_back(Entry);
65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TargetLowering::CallLoweringInfo CLI(DAG);
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CLI.setDebugLoc(dl).setChain(Chain)
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .setCallee(CallingConv::C, Type::getVoidTy(*DAG.getContext()),
69cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                   DAG.getExternalSymbol(bzeroEntry, IntPtr), std::move(Args),
70cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                   0)
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .setDiscardResult();
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
73cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      std::pair<SDValue,SDValue> CallResult = DAG.getTargetLoweringInfo().LowerCallTo(CLI);
74ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      return CallResult.second;
75ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    }
76ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
77ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    // Otherwise have the target-independent code call memset.
78ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    return SDValue();
79ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  }
80ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
81ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  uint64_t SizeVal = ConstantSize->getZExtValue();
82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SDValue InFlag;
83ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  EVT AVT;
84ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  SDValue Count;
85ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Src);
86ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  unsigned BytesLeft = 0;
87ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  bool TwoRepStos = false;
88ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  if (ValC) {
89ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    unsigned ValReg;
90ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    uint64_t Val = ValC->getZExtValue() & 255;
91ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
92ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    // If the value is a constant, then we can potentially use larger sets.
93ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    switch (Align & 3) {
94ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    case 2:   // WORD aligned
95ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      AVT = MVT::i16;
96ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      ValReg = X86::AX;
97ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      Val = (Val << 8) | Val;
98ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      break;
99ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    case 0:  // DWORD aligned
100ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      AVT = MVT::i32;
101ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      ValReg = X86::EAX;
102ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      Val = (Val << 8)  | Val;
103ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      Val = (Val << 16) | Val;
104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (Subtarget.is64Bit() && ((Align & 0x7) == 0)) {  // QWORD aligned
105ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman        AVT = MVT::i64;
106ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman        ValReg = X86::RAX;
107ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman        Val = (Val << 32) | Val;
108ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      }
109ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      break;
110ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    default:  // Byte aligned
111ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      AVT = MVT::i8;
112ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      ValReg = X86::AL;
113ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      Count = DAG.getIntPtrConstant(SizeVal);
114ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      break;
115ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    }
116ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
117ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    if (AVT.bitsGT(MVT::i8)) {
118ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      unsigned UBytes = AVT.getSizeInBits() / 8;
119ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      Count = DAG.getIntPtrConstant(SizeVal / UBytes);
120ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman      BytesLeft = SizeVal % UBytes;
121ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    }
122ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
123ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    Chain  = DAG.getCopyToReg(Chain, dl, ValReg, DAG.getConstant(Val, AVT),
124ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                              InFlag);
125ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    InFlag = Chain.getValue(1);
126ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  } else {
127ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    AVT = MVT::i8;
128ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    Count  = DAG.getIntPtrConstant(SizeVal);
129ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    Chain  = DAG.getCopyToReg(Chain, dl, X86::AL, Src, InFlag);
130ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    InFlag = Chain.getValue(1);
131ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  }
132ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Chain = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RCX : X86::ECX,
134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                           Count, InFlag);
135ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  InFlag = Chain.getValue(1);
136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Chain = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RDI : X86::EDI,
137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                           Dst, InFlag);
138ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  InFlag = Chain.getValue(1);
139ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
140f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
141ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops);
143ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
144ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  if (TwoRepStos) {
145ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    InFlag = Chain.getValue(1);
146ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    Count  = Size;
147ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    EVT CVT = Count.getValueType();
148ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    SDValue Left = DAG.getNode(ISD::AND, dl, CVT, Count,
149ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                               DAG.getConstant((AVT == MVT::i64) ? 7 : 3, CVT));
150ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    Chain  = DAG.getCopyToReg(Chain, dl, (CVT == MVT::i64) ? X86::RCX :
151ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                                             X86::ECX,
152ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                              Left, InFlag);
153ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    InFlag = Chain.getValue(1);
154f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    Tys = DAG.getVTList(MVT::Other, MVT::Glue);
155ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    SDValue Ops[] = { Chain, DAG.getValueType(MVT::i8), InFlag };
156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops);
157ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  } else if (BytesLeft) {
158ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    // Handle the last 1 - 7 bytes.
159ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    unsigned Offset = SizeVal - BytesLeft;
160ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    EVT AddrVT = Dst.getValueType();
161ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    EVT SizeVT = Size.getValueType();
162ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
163ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    Chain = DAG.getMemset(Chain, dl,
164ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                          DAG.getNode(ISD::ADD, dl, AddrVT, Dst,
165ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                      DAG.getConstant(Offset, AddrVT)),
166ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                          Src,
167ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                          DAG.getConstant(BytesLeft, SizeVT),
168e72f2027e9116c55a5b39ac72732df8d6c45d37cChris Lattner                          Align, isVolatile, DstPtrInfo.getWithOffset(Offset));
169ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  }
170ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
171ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  // TODO: Use a Tokenfactor, as in memcpy, instead of a single chain.
172ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  return Chain;
173ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman}
174ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
175ff7a562751604a9fe13efc75bd59622244b54d35Dan GohmanSDValue
176ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew TrickX86SelectionDAGInfo::EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl,
177ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                        SDValue Chain, SDValue Dst, SDValue Src,
178ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                        SDValue Size, unsigned Align,
179ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                        bool isVolatile, bool AlwaysInline,
180e72f2027e9116c55a5b39ac72732df8d6c45d37cChris Lattner                                         MachinePointerInfo DstPtrInfo,
181e72f2027e9116c55a5b39ac72732df8d6c45d37cChris Lattner                                         MachinePointerInfo SrcPtrInfo) const {
1827a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // This requires the copy size to be a constant, preferably
183ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  // within a subtarget-specific limit.
184ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
185cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const X86Subtarget &Subtarget = DAG.getTarget().getSubtarget<X86Subtarget>();
186ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  if (!ConstantSize)
187ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    return SDValue();
188ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  uint64_t SizeVal = ConstantSize->getZExtValue();
189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!AlwaysInline && SizeVal > Subtarget.getMaxInlineSizeThreshold())
190ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    return SDValue();
191ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
1921e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands  /// If not DWORD aligned, it is more efficient to call the library.  However
1931e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands  /// if calling the library is not allowed (AlwaysInline), then soldier on as
1941e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands  /// the code generated here is better than the long load-store sequence we
1951e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands  /// would otherwise get.
1961e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands  if (!AlwaysInline && (Align & 3) != 0)
197ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    return SDValue();
198ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
199e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner  // If to a segment-relative address space, use the default lowering.
200e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner  if (DstPtrInfo.getAddrSpace() >= 256 ||
201e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner      SrcPtrInfo.getAddrSpace() >= 256)
202e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner    return SDValue();
2031e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands
204f09e02f01a817f4daf95ef8d3f1f2545297d32e7Benjamin Kramer  // ESI might be used as a base pointer, in that case we can't simply overwrite
205f09e02f01a817f4daf95ef8d3f1f2545297d32e7Benjamin Kramer  // the register.  Fall back to generic code.
206f09e02f01a817f4daf95ef8d3f1f2545297d32e7Benjamin Kramer  const X86RegisterInfo *TRI =
207f09e02f01a817f4daf95ef8d3f1f2545297d32e7Benjamin Kramer      static_cast<const X86RegisterInfo *>(DAG.getTarget().getRegisterInfo());
208f09e02f01a817f4daf95ef8d3f1f2545297d32e7Benjamin Kramer  if (TRI->hasBasePointer(DAG.getMachineFunction()) &&
209f09e02f01a817f4daf95ef8d3f1f2545297d32e7Benjamin Kramer      TRI->getBaseRegister() == X86::ESI)
210f09e02f01a817f4daf95ef8d3f1f2545297d32e7Benjamin Kramer    return SDValue();
211f09e02f01a817f4daf95ef8d3f1f2545297d32e7Benjamin Kramer
2121e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands  MVT AVT;
2131e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands  if (Align & 1)
2141e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands    AVT = MVT::i8;
2151e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands  else if (Align & 2)
2161e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands    AVT = MVT::i16;
2171e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands  else if (Align & 4)
2181e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands    // DWORD aligned
2191e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands    AVT = MVT::i32;
2201e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands  else
2211e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands    // QWORD aligned
222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    AVT = Subtarget.is64Bit() ? MVT::i64 : MVT::i32;
223ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
224ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  unsigned UBytes = AVT.getSizeInBits() / 8;
225ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  unsigned CountVal = SizeVal / UBytes;
226ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  SDValue Count = DAG.getIntPtrConstant(CountVal);
227ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  unsigned BytesLeft = SizeVal % UBytes;
228ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SDValue InFlag;
230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Chain  = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RCX :
231ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                                              X86::ECX,
232ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                            Count, InFlag);
233ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  InFlag = Chain.getValue(1);
234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Chain  = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RDI :
235ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                                              X86::EDI,
236ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                            Dst, InFlag);
237ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  InFlag = Chain.getValue(1);
238cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Chain  = DAG.getCopyToReg(Chain, dl, Subtarget.is64Bit() ? X86::RSI :
239ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                                              X86::ESI,
240ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                            Src, InFlag);
241ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  InFlag = Chain.getValue(1);
242ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
243f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
244ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SDValue RepMovs = DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops);
246ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
247ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  SmallVector<SDValue, 4> Results;
248ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  Results.push_back(RepMovs);
249ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  if (BytesLeft) {
250ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    // Handle the last 1 - 7 bytes.
251ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    unsigned Offset = SizeVal - BytesLeft;
252ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    EVT DstVT = Dst.getValueType();
253ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    EVT SrcVT = Src.getValueType();
254ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    EVT SizeVT = Size.getValueType();
255ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman    Results.push_back(DAG.getMemcpy(Chain, dl,
256ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                    DAG.getNode(ISD::ADD, dl, DstVT, Dst,
257ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                                DAG.getConstant(Offset, DstVT)),
258ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                    DAG.getNode(ISD::ADD, dl, SrcVT, Src,
259ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                                DAG.getConstant(Offset, SrcVT)),
260ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                    DAG.getConstant(BytesLeft, SizeVT),
261ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman                                    Align, isVolatile, AlwaysInline,
262e72f2027e9116c55a5b39ac72732df8d6c45d37cChris Lattner                                    DstPtrInfo.getWithOffset(Offset),
263e72f2027e9116c55a5b39ac72732df8d6c45d37cChris Lattner                                    SrcPtrInfo.getWithOffset(Offset)));
264ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman  }
265ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman
266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Results);
267ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman}
268