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
EmitTargetCodeForMemcpy(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Dst,SDValue Src,SDValue Size,Align Alignment,bool isVolatile,bool AlwaysInline,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo) const190b57cec5SDimitry 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