xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
10b57cec5SDimitry Andric //===-- HexagonSelectionDAGInfo.cpp - Hexagon SelectionDAG Info -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the HexagonSelectionDAGInfo class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "HexagonTargetMachine.h"
140b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAG.h"
150b57cec5SDimitry Andric using namespace llvm;
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #define DEBUG_TYPE "hexagon-selectiondag-info"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric SDValue HexagonSelectionDAGInfo::EmitTargetCodeForMemcpy(
200b57cec5SDimitry Andric     SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
21*5ffd83dbSDimitry Andric     SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
220b57cec5SDimitry Andric     MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
230b57cec5SDimitry Andric   ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
24*5ffd83dbSDimitry Andric   if (AlwaysInline || Alignment < Align(4) || !ConstantSize)
250b57cec5SDimitry Andric     return SDValue();
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric   uint64_t SizeVal = ConstantSize->getZExtValue();
280b57cec5SDimitry Andric   if (SizeVal < 32 || (SizeVal % 8) != 0)
290b57cec5SDimitry Andric     return SDValue();
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric   // Special case aligned memcpys with size >= 32 bytes and a multiple of 8.
320b57cec5SDimitry Andric   //
330b57cec5SDimitry Andric   const TargetLowering &TLI = *DAG.getSubtarget().getTargetLowering();
340b57cec5SDimitry Andric   TargetLowering::ArgListTy Args;
350b57cec5SDimitry Andric   TargetLowering::ArgListEntry Entry;
360b57cec5SDimitry Andric   Entry.Ty = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
370b57cec5SDimitry Andric   Entry.Node = Dst;
380b57cec5SDimitry Andric   Args.push_back(Entry);
390b57cec5SDimitry Andric   Entry.Node = Src;
400b57cec5SDimitry Andric   Args.push_back(Entry);
410b57cec5SDimitry Andric   Entry.Node = Size;
420b57cec5SDimitry Andric   Args.push_back(Entry);
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   const char *SpecialMemcpyName =
450b57cec5SDimitry Andric       "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes";
460b57cec5SDimitry Andric   const MachineFunction &MF = DAG.getMachineFunction();
470b57cec5SDimitry Andric   bool LongCalls = MF.getSubtarget<HexagonSubtarget>().useLongCalls();
480b57cec5SDimitry Andric   unsigned Flags = LongCalls ? HexagonII::HMOTF_ConstExtended : 0;
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   TargetLowering::CallLoweringInfo CLI(DAG);
510b57cec5SDimitry Andric   CLI.setDebugLoc(dl)
520b57cec5SDimitry Andric       .setChain(Chain)
530b57cec5SDimitry Andric       .setLibCallee(
540b57cec5SDimitry Andric           TLI.getLibcallCallingConv(RTLIB::MEMCPY),
550b57cec5SDimitry Andric           Type::getVoidTy(*DAG.getContext()),
560b57cec5SDimitry Andric           DAG.getTargetExternalSymbol(
570b57cec5SDimitry Andric               SpecialMemcpyName, TLI.getPointerTy(DAG.getDataLayout()), Flags),
580b57cec5SDimitry Andric           std::move(Args))
590b57cec5SDimitry Andric       .setDiscardResult();
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
620b57cec5SDimitry Andric   return CallResult.second;
630b57cec5SDimitry Andric }
64