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 1453c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman#define DEBUG_TYPE "x86-selectiondag-info" 15ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman#include "X86TargetMachine.h" 16ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman#include "llvm/DerivedTypes.h" 17ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman#include "llvm/CodeGen/SelectionDAG.h" 1853c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohmanusing namespace llvm; 1953c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman 20ff7a562751604a9fe13efc75bd59622244b54d35Dan GohmanX86SelectionDAGInfo::X86SelectionDAGInfo(const X86TargetMachine &TM) : 21ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman TargetSelectionDAGInfo(TM), 22ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Subtarget(&TM.getSubtarget<X86Subtarget>()), 23ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman TLI(*TM.getTargetLowering()) { 2453c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman} 2553c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman 2653c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan GohmanX86SelectionDAGInfo::~X86SelectionDAGInfo() { 2753c5e42ab9c1a2cce7ad19bb0b4dffe33c9473e6Dan Gohman} 28ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 29ff7a562751604a9fe13efc75bd59622244b54d35Dan GohmanSDValue 30ff7a562751604a9fe13efc75bd59622244b54d35Dan GohmanX86SelectionDAGInfo::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl, 31ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SDValue Chain, 32ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SDValue Dst, SDValue Src, 33ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SDValue Size, unsigned Align, 34ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman bool isVolatile, 35e72f2027e9116c55a5b39ac72732df8d6c45d37cChris Lattner MachinePointerInfo DstPtrInfo) const { 36ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size); 37ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 38e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner // If to a segment-relative address space, use the default lowering. 39e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner if (DstPtrInfo.getAddrSpace() >= 256) 40e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner return SDValue(); 41e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner 42ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman // If not DWORD aligned or size is more than the threshold, call the library. 43ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman // The libc version is likely to be faster for these cases. It can use the 44ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman // address value and run time information about the CPU. 45ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman if ((Align & 3) != 0 || 46ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman !ConstantSize || 47ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman ConstantSize->getZExtValue() > 48ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Subtarget->getMaxInlineSizeThreshold()) { 49ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SDValue InFlag(0, 0); 50ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 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 && 55ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman V->isNullValue() ? Subtarget->getBZeroEntry() : 0) { 56ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman EVT IntPtr = TLI.getPointerTy(); 57db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *IntPtrTy = getTargetData()->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); 65ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman std::pair<SDValue,SDValue> CallResult = 66ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman TLI.LowerCallTo(Chain, Type::getVoidTy(*DAG.getContext()), 67ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman false, false, false, false, 684bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng 0, CallingConv::C, /*isTailCall=*/false, 694bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng /*doesNotRet=*/false, /*isReturnValueUsed=*/false, 70ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, 71ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman DAG, dl); 72ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman return CallResult.second; 73ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman } 74ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 75ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman // Otherwise have the target-independent code call memset. 76ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman return SDValue(); 77ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman } 78ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 79ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman uint64_t SizeVal = ConstantSize->getZExtValue(); 80ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SDValue InFlag(0, 0); 81ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman EVT AVT; 82ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SDValue Count; 83ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Src); 84ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman unsigned BytesLeft = 0; 85ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman bool TwoRepStos = false; 86ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman if (ValC) { 87ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman unsigned ValReg; 88ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman uint64_t Val = ValC->getZExtValue() & 255; 89ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 90ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman // If the value is a constant, then we can potentially use larger sets. 91ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman switch (Align & 3) { 92ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman case 2: // WORD aligned 93ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman AVT = MVT::i16; 94ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman ValReg = X86::AX; 95ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Val = (Val << 8) | Val; 96ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman break; 97ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman case 0: // DWORD aligned 98ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman AVT = MVT::i32; 99ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman ValReg = X86::EAX; 100ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Val = (Val << 8) | Val; 101ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Val = (Val << 16) | Val; 102ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) { // QWORD aligned 103ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman AVT = MVT::i64; 104ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman ValReg = X86::RAX; 105ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Val = (Val << 32) | Val; 106ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman } 107ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman break; 108ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman default: // Byte aligned 109ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman AVT = MVT::i8; 110ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman ValReg = X86::AL; 111ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Count = DAG.getIntPtrConstant(SizeVal); 112ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman break; 113ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman } 114ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 115ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman if (AVT.bitsGT(MVT::i8)) { 116ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman unsigned UBytes = AVT.getSizeInBits() / 8; 117ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Count = DAG.getIntPtrConstant(SizeVal / UBytes); 118ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman BytesLeft = SizeVal % UBytes; 119ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman } 120ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 121ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Chain = DAG.getCopyToReg(Chain, dl, ValReg, DAG.getConstant(Val, AVT), 122ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman InFlag); 123ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman InFlag = Chain.getValue(1); 124ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman } else { 125ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman AVT = MVT::i8; 126ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Count = DAG.getIntPtrConstant(SizeVal); 127ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Chain = DAG.getCopyToReg(Chain, dl, X86::AL, Src, InFlag); 128ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman InFlag = Chain.getValue(1); 129ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman } 130ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 131ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RCX : 132ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman X86::ECX, 133ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Count, InFlag); 134ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman InFlag = Chain.getValue(1); 135ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RDI : 136ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman X86::EDI, 137ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 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 }; 142ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(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 }; 156ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(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 176ff7a562751604a9fe13efc75bd59622244b54d35Dan GohmanX86SelectionDAGInfo::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc 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); 185ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman if (!ConstantSize) 186ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman return SDValue(); 187ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman uint64_t SizeVal = ConstantSize->getZExtValue(); 188ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman if (!AlwaysInline && SizeVal > Subtarget->getMaxInlineSizeThreshold()) 189ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman return SDValue(); 190ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 1911e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands /// If not DWORD aligned, it is more efficient to call the library. However 1921e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands /// if calling the library is not allowed (AlwaysInline), then soldier on as 1931e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands /// the code generated here is better than the long load-store sequence we 1941e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands /// would otherwise get. 1951e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands if (!AlwaysInline && (Align & 3) != 0) 196ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman return SDValue(); 197ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 198e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner // If to a segment-relative address space, use the default lowering. 199e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner if (DstPtrInfo.getAddrSpace() >= 256 || 200e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner SrcPtrInfo.getAddrSpace() >= 256) 201e54b482d1c6ec714a73d8a87a4f7583aa86fac9fChris Lattner return SDValue(); 2021e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands 2031e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands MVT AVT; 2041e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands if (Align & 1) 2051e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands AVT = MVT::i8; 2061e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands else if (Align & 2) 2071e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands AVT = MVT::i16; 2081e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands else if (Align & 4) 2091e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands // DWORD aligned 2101e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands AVT = MVT::i32; 2111e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands else 2121e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands // QWORD aligned 2131e92ec688624d17b552c88afc956f61da4948cbbDuncan Sands AVT = Subtarget->is64Bit() ? MVT::i64 : MVT::i32; 214ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 215ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman unsigned UBytes = AVT.getSizeInBits() / 8; 216ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman unsigned CountVal = SizeVal / UBytes; 217ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SDValue Count = DAG.getIntPtrConstant(CountVal); 218ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman unsigned BytesLeft = SizeVal % UBytes; 219ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 220ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SDValue InFlag(0, 0); 221ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RCX : 222ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman X86::ECX, 223ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Count, InFlag); 224ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman InFlag = Chain.getValue(1); 225ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RDI : 226ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman X86::EDI, 227ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Dst, InFlag); 228ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman InFlag = Chain.getValue(1); 229ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RSI : 230ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman X86::ESI, 231ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Src, InFlag); 232ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman InFlag = Chain.getValue(1); 233ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 234f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue); 235ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag }; 236ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SDValue RepMovs = DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops, 237ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman array_lengthof(Ops)); 238ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 239ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman SmallVector<SDValue, 4> Results; 240ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Results.push_back(RepMovs); 241ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman if (BytesLeft) { 242ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman // Handle the last 1 - 7 bytes. 243ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman unsigned Offset = SizeVal - BytesLeft; 244ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman EVT DstVT = Dst.getValueType(); 245ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman EVT SrcVT = Src.getValueType(); 246ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman EVT SizeVT = Size.getValueType(); 247ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Results.push_back(DAG.getMemcpy(Chain, dl, 248ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman DAG.getNode(ISD::ADD, dl, DstVT, Dst, 249ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman DAG.getConstant(Offset, DstVT)), 250ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman DAG.getNode(ISD::ADD, dl, SrcVT, Src, 251ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman DAG.getConstant(Offset, SrcVT)), 252ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman DAG.getConstant(BytesLeft, SizeVT), 253ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman Align, isVolatile, AlwaysInline, 254e72f2027e9116c55a5b39ac72732df8d6c45d37cChris Lattner DstPtrInfo.getWithOffset(Offset), 255e72f2027e9116c55a5b39ac72732df8d6c45d37cChris Lattner SrcPtrInfo.getWithOffset(Offset))); 256ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman } 257ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman 258ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 259ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman &Results[0], Results.size()); 260ff7a562751604a9fe13efc75bd59622244b54d35Dan Gohman} 261