1//===-- ARMSelectionDAGInfo.h - ARM SelectionDAG Info -----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the ARM subclass for SelectionDAGTargetInfo.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_ARM_ARMSELECTIONDAGINFO_H
14#define LLVM_LIB_TARGET_ARM_ARMSELECTIONDAGINFO_H
15
16#include "MCTargetDesc/ARMAddressingModes.h"
17#include "llvm/CodeGen/RuntimeLibcallUtil.h"
18#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
19
20#define GET_SDNODE_ENUM
21#include "ARMGenSDNodeInfo.inc"
22
23namespace llvm {
24namespace ARMISD {
25
26enum NodeType : unsigned {
27 DYN_ALLOC = GENERATED_OPCODE_END, // Dynamic allocation on the stack.
28
29 MVESEXT, // Legalization aids for extending a vector into two/four vectors.
30 MVEZEXT, // or truncating two/four vectors into one. Eventually becomes
31 MVETRUNC, // stack store/load sequence, if not optimized to anything else.
32
33 // Operands of the standard BUILD_VECTOR node are not legalized, which
34 // is fine if BUILD_VECTORs are always lowered to shuffles or other
35 // operations, but for ARM some BUILD_VECTORs are legal as-is and their
36 // operands need to be legalized. Define an ARM-specific version of
37 // BUILD_VECTOR for this purpose.
38 BUILD_VECTOR,
39
40 // Vector load N-element structure to all lanes:
41 FIRST_MEMORY_OPCODE,
42 VLD1DUP = FIRST_MEMORY_OPCODE,
43 VLD2DUP,
44 VLD3DUP,
45 VLD4DUP,
46
47 // NEON loads with post-increment base updates:
48 VLD1_UPD,
49 VLD2_UPD,
50 VLD3_UPD,
51 VLD4_UPD,
52 VLD2LN_UPD,
53 VLD3LN_UPD,
54 VLD4LN_UPD,
55 VLD1DUP_UPD,
56 VLD2DUP_UPD,
57 VLD3DUP_UPD,
58 VLD4DUP_UPD,
59 VLD1x2_UPD,
60 VLD1x3_UPD,
61 VLD1x4_UPD,
62
63 // NEON stores with post-increment base updates:
64 VST1_UPD,
65 VST3_UPD,
66 VST2LN_UPD,
67 VST3LN_UPD,
68 VST4LN_UPD,
69 VST1x2_UPD,
70 VST1x3_UPD,
71 VST1x4_UPD,
72 LAST_MEMORY_OPCODE = VST1x4_UPD,
73};
74
75} // namespace ARMISD
76
77namespace ARM_AM {
78 static inline ShiftOpc getShiftOpcForNode(unsigned Opcode) {
79 switch (Opcode) {
80 default: return ARM_AM::no_shift;
81 case ISD::SHL: return ARM_AM::lsl;
82 case ISD::SRL: return ARM_AM::lsr;
83 case ISD::SRA: return ARM_AM::asr;
84 case ISD::ROTR: return ARM_AM::ror;
85 //case ISD::ROTL: // Only if imm -> turn into ROTR.
86 // Can't handle RRX here, because it would require folding a flag into
87 // the addressing mode. :( This causes us to miss certain things.
88 //case ARMISD::RRX: return ARM_AM::rrx;
89 }
90 }
91} // end namespace ARM_AM
92
93class ARMSelectionDAGInfo : public SelectionDAGGenTargetInfo {
94public:
95 ARMSelectionDAGInfo();
96
97 const char *getTargetNodeName(unsigned Opcode) const override;
98
99 bool isTargetMemoryOpcode(unsigned Opcode) const override;
100
101 void verifyTargetNode(const SelectionDAG &DAG,
102 const SDNode *N) const override;
103
104 SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
105 SDValue Chain, SDValue Dst, SDValue Src,
106 SDValue Size, Align Alignment,
107 bool isVolatile, bool AlwaysInline,
108 MachinePointerInfo DstPtrInfo,
109 MachinePointerInfo SrcPtrInfo) const override;
110
111 SDValue
112 EmitTargetCodeForMemmove(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain,
113 SDValue Dst, SDValue Src, SDValue Size,
114 Align Alignment, bool isVolatile,
115 MachinePointerInfo DstPtrInfo,
116 MachinePointerInfo SrcPtrInfo) const override;
117
118 // Adjust parameters for memset, see RTABI section 4.3.4
119 SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl,
120 SDValue Chain, SDValue Op1, SDValue Op2,
121 SDValue Op3, Align Alignment, bool isVolatile,
122 bool AlwaysInline,
123 MachinePointerInfo DstPtrInfo) const override;
124
125 SDValue EmitSpecializedLibcall(SelectionDAG &DAG, const SDLoc &dl,
126 SDValue Chain, SDValue Dst, SDValue Src,
127 SDValue Size, unsigned Align,
128 RTLIB::Libcall LC) const;
129};
130
131} // namespace llvm
132
133#endif
134