1//===-- BPFISelLowering.h - BPF DAG Lowering Interface ----------*- 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 interfaces that BPF uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_BPF_BPFISELLOWERING_H
15#define LLVM_LIB_TARGET_BPF_BPFISELLOWERING_H
16
17#include "BPF.h"
18#include "llvm/CodeGen/SelectionDAG.h"
19#include "llvm/CodeGen/TargetLowering.h"
20
21namespace llvm {
22class BPFSubtarget;
23
24class BPFTargetLowering : public TargetLowering {
25public:
26 explicit BPFTargetLowering(const TargetMachine &TM, const BPFSubtarget &STI);
27
28 // Provide custom lowering hooks for some operations.
29 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
30
31 // This method decides whether folding a constant offset
32 // with the given GlobalAddress is legal.
33 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
34
35 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned, Align,
36 MachineMemOperand::Flags,
37 unsigned *) const override;
38
39 BPFTargetLowering::ConstraintType
40 getConstraintType(StringRef Constraint) const override;
41
42 std::pair<unsigned, const TargetRegisterClass *>
43 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
44 StringRef Constraint, MVT VT) const override;
45
46 MachineBasicBlock *
47 EmitInstrWithCustomInserter(MachineInstr &MI,
48 MachineBasicBlock *BB) const override;
49
50 bool getHasAlu32() const { return HasAlu32; }
51 bool getHasJmp32() const { return HasJmp32; }
52 bool getHasJmpExt() const { return HasJmpExt; }
53
54 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
55 EVT VT) const override;
56
57 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override;
58
59 unsigned getJumpTableEncoding() const override;
60
61private:
62 // Control Instruction Selection Features
63 bool HasAlu32;
64 bool HasJmp32;
65 bool HasJmpExt;
66 bool HasMovsx;
67
68 // Allows Misalignment
69 bool AllowsMisalignedMemAccess;
70
71 SDValue LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const;
72 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
73 SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
74 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
75 SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) const;
76 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
77 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
78 SDValue LowerTRAP(SDValue Op, SelectionDAG &DAG) const;
79 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
80 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
81
82 template <class NodeTy>
83 SDValue getAddr(NodeTy *N, SelectionDAG &DAG, unsigned Flags = 0) const;
84
85 // Lower the result values of a call, copying them out of physregs into vregs
86 SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
87 CallingConv::ID CallConv, bool IsVarArg,
88 const SmallVectorImpl<ISD::InputArg> &Ins,
89 const SDLoc &DL, SelectionDAG &DAG,
90 SmallVectorImpl<SDValue> &InVals) const;
91
92 // Maximum number of arguments to a call
93 static const size_t MaxArgs;
94
95 // Lower a call into CALLSEQ_START - BPFISD:CALL - CALLSEQ_END chain
96 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
97 SmallVectorImpl<SDValue> &InVals) const override;
98
99 // Lower incoming arguments, copy physregs into vregs
100 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
101 bool IsVarArg,
102 const SmallVectorImpl<ISD::InputArg> &Ins,
103 const SDLoc &DL, SelectionDAG &DAG,
104 SmallVectorImpl<SDValue> &InVals) const override;
105
106 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
107 const SmallVectorImpl<ISD::OutputArg> &Outs,
108 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
109 SelectionDAG &DAG) const override;
110
111 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
112 SelectionDAG &DAG) const override;
113
114 EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
115 const AttributeList &FuncAttributes) const override {
116 return Op.size() >= 8 ? MVT::i64 : MVT::i32;
117 }
118
119 bool isIntDivCheap(EVT VT, AttributeList Attr) const override {
120 return false;
121 }
122
123 bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
124 Type *Ty) const override {
125 return true;
126 }
127
128 // Prevent reducing load width during SelectionDag phase.
129 // Otherwise, we may transform the following
130 // ctx = ctx + reloc_offset
131 // ... (*(u32 *)ctx) & 0x8000...
132 // to
133 // ctx = ctx + reloc_offset
134 // ... (*(u8 *)(ctx + 1)) & 0x80 ...
135 // which will be rejected by the verifier.
136 bool
137 shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT,
138 std::optional<unsigned> ByteOffset) const override {
139 return false;
140 }
141
142 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
143 Type *Ty, unsigned AS,
144 Instruction *I = nullptr) const override;
145
146 // isTruncateFree - Return true if it's free to truncate a value of
147 // type Ty1 to type Ty2. e.g. On BPF at alu32 mode, it's free to truncate
148 // a i64 value in register R1 to i32 by referencing its sub-register W1.
149 bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
150 bool isTruncateFree(EVT VT1, EVT VT2) const override;
151
152 // For 32bit ALU result zext to 64bit is free.
153 bool isZExtFree(Type *Ty1, Type *Ty2) const override;
154 bool isZExtFree(EVT VT1, EVT VT2) const override;
155 bool isZExtFree(SDValue Val, EVT VT2) const override;
156
157 unsigned EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB, unsigned Reg,
158 bool isSigned) const;
159
160 MachineBasicBlock * EmitInstrWithCustomInserterMemcpy(MachineInstr &MI,
161 MachineBasicBlock *BB)
162 const;
163 MachineBasicBlock *
164 EmitInstrWithCustomInserterLDimm64(MachineInstr &MI,
165 MachineBasicBlock *BB) const;
166};
167}
168
169#endif
170