1 //===-- HexagonSelectionDAGInfo.cpp - Hexagon SelectionDAG Info -----------===//
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 HexagonSelectionDAGInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "HexagonTargetMachine.h"
15 #include "llvm/CodeGen/SelectionDAG.h"
16 using namespace llvm;
17
18 #define DEBUG_TYPE "hexagon-selectiondag-info"
19
EmitTargetCodeForMemcpy(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Dst,SDValue Src,SDValue Size,unsigned Align,bool isVolatile,bool AlwaysInline,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo) const20 SDValue HexagonSelectionDAGInfo::EmitTargetCodeForMemcpy(
21 SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
22 SDValue Size, unsigned Align, bool isVolatile, bool AlwaysInline,
23 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
24 ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
25 if (AlwaysInline || (Align & 0x3) != 0 || !ConstantSize)
26 return SDValue();
27
28 uint64_t SizeVal = ConstantSize->getZExtValue();
29 if (SizeVal < 32 || (SizeVal % 8) != 0)
30 return SDValue();
31
32 // Special case aligned memcpys with size >= 32 bytes and a multiple of 8.
33 //
34 const TargetLowering &TLI = *DAG.getSubtarget().getTargetLowering();
35 TargetLowering::ArgListTy Args;
36 TargetLowering::ArgListEntry Entry;
37 Entry.Ty = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
38 Entry.Node = Dst;
39 Args.push_back(Entry);
40 Entry.Node = Src;
41 Args.push_back(Entry);
42 Entry.Node = Size;
43 Args.push_back(Entry);
44
45 const char *SpecialMemcpyName =
46 "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes";
47
48 TargetLowering::CallLoweringInfo CLI(DAG);
49 CLI.setDebugLoc(dl)
50 .setChain(Chain)
51 .setCallee(TLI.getLibcallCallingConv(RTLIB::MEMCPY),
52 Type::getVoidTy(*DAG.getContext()),
53 DAG.getTargetExternalSymbol(
54 SpecialMemcpyName, TLI.getPointerTy(DAG.getDataLayout())),
55 std::move(Args))
56 .setDiscardResult();
57
58 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
59 return CallResult.second;
60 }
61