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