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