xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- HexagonSelectionDAGInfo.cpp - Hexagon SelectionDAG Info -----------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This file implements the HexagonSelectionDAGInfo class.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #include "HexagonTargetMachine.h"
14*0b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAG.h"
15*0b57cec5SDimitry Andric using namespace llvm;
16*0b57cec5SDimitry Andric 
17*0b57cec5SDimitry Andric #define DEBUG_TYPE "hexagon-selectiondag-info"
18*0b57cec5SDimitry Andric 
19*0b57cec5SDimitry Andric SDValue HexagonSelectionDAGInfo::EmitTargetCodeForMemcpy(
20*0b57cec5SDimitry Andric     SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
21*0b57cec5SDimitry Andric     SDValue Size, unsigned Align, bool isVolatile, bool AlwaysInline,
22*0b57cec5SDimitry Andric     MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
23*0b57cec5SDimitry Andric   ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
24*0b57cec5SDimitry Andric   if (AlwaysInline || (Align & 0x3) != 0 || !ConstantSize)
25*0b57cec5SDimitry Andric     return SDValue();
26*0b57cec5SDimitry Andric 
27*0b57cec5SDimitry Andric   uint64_t SizeVal = ConstantSize->getZExtValue();
28*0b57cec5SDimitry Andric   if (SizeVal < 32 || (SizeVal % 8) != 0)
29*0b57cec5SDimitry Andric     return SDValue();
30*0b57cec5SDimitry Andric 
31*0b57cec5SDimitry Andric   // Special case aligned memcpys with size >= 32 bytes and a multiple of 8.
32*0b57cec5SDimitry Andric   //
33*0b57cec5SDimitry Andric   const TargetLowering &TLI = *DAG.getSubtarget().getTargetLowering();
34*0b57cec5SDimitry Andric   TargetLowering::ArgListTy Args;
35*0b57cec5SDimitry Andric   TargetLowering::ArgListEntry Entry;
36*0b57cec5SDimitry Andric   Entry.Ty = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
37*0b57cec5SDimitry Andric   Entry.Node = Dst;
38*0b57cec5SDimitry Andric   Args.push_back(Entry);
39*0b57cec5SDimitry Andric   Entry.Node = Src;
40*0b57cec5SDimitry Andric   Args.push_back(Entry);
41*0b57cec5SDimitry Andric   Entry.Node = Size;
42*0b57cec5SDimitry Andric   Args.push_back(Entry);
43*0b57cec5SDimitry Andric 
44*0b57cec5SDimitry Andric   const char *SpecialMemcpyName =
45*0b57cec5SDimitry Andric       "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes";
46*0b57cec5SDimitry Andric   const MachineFunction &MF = DAG.getMachineFunction();
47*0b57cec5SDimitry Andric   bool LongCalls = MF.getSubtarget<HexagonSubtarget>().useLongCalls();
48*0b57cec5SDimitry Andric   unsigned Flags = LongCalls ? HexagonII::HMOTF_ConstExtended : 0;
49*0b57cec5SDimitry Andric 
50*0b57cec5SDimitry Andric   TargetLowering::CallLoweringInfo CLI(DAG);
51*0b57cec5SDimitry Andric   CLI.setDebugLoc(dl)
52*0b57cec5SDimitry Andric       .setChain(Chain)
53*0b57cec5SDimitry Andric       .setLibCallee(
54*0b57cec5SDimitry Andric           TLI.getLibcallCallingConv(RTLIB::MEMCPY),
55*0b57cec5SDimitry Andric           Type::getVoidTy(*DAG.getContext()),
56*0b57cec5SDimitry Andric           DAG.getTargetExternalSymbol(
57*0b57cec5SDimitry Andric               SpecialMemcpyName, TLI.getPointerTy(DAG.getDataLayout()), Flags),
58*0b57cec5SDimitry Andric           std::move(Args))
59*0b57cec5SDimitry Andric       .setDiscardResult();
60*0b57cec5SDimitry Andric 
61*0b57cec5SDimitry Andric   std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
62*0b57cec5SDimitry Andric   return CallResult.second;
63*0b57cec5SDimitry Andric }
64