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