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 // Exception handling support.
58 Register getExceptionPointerRegister(ExceptionHandling EH,
59 const Constant *) const override {
60 return BPF::R0;
61 }
62 Register getExceptionSelectorRegister(ExceptionHandling EH,
63 const Constant *) const override {
64 return BPF::R0;
65 }
66
67 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override;
68
69 unsigned getJumpTableEncoding() const override;
70
71private:
72 // Control Instruction Selection Features
73 bool HasAlu32;
74 bool HasJmp32;
75 bool HasJmpExt;
76 bool HasMovsx;
77
78 // Allows Misalignment
79 bool AllowsMisalignedMemAccess;
80
81 SDValue LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const;
82 SDValue LowerShiftParts(SDValue Op, SelectionDAG &DAG) const;
83 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
84 SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
85 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
86 SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) const;
87 SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
88 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
89 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
90 SDValue LowerTRAP(SDValue Op, SelectionDAG &DAG) const;
91 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
92 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
93
94 template <class NodeTy>
95 SDValue getAddr(NodeTy *N, SelectionDAG &DAG, unsigned Flags = 0) const;
96
97 // Lower the result values of a call, copying them out of physregs into vregs
98 SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
99 CallingConv::ID CallConv, bool IsVarArg,
100 const SmallVectorImpl<ISD::InputArg> &Ins,
101 const SDLoc &DL, SelectionDAG &DAG,
102 SmallVectorImpl<SDValue> &InVals) const;
103
104 // Lower a call into CALLSEQ_START - BPFISD:CALL - CALLSEQ_END chain
105 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
106 SmallVectorImpl<SDValue> &InVals) const override;
107
108 // Lower incoming arguments, copy physregs into vregs
109 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
110 bool IsVarArg,
111 const SmallVectorImpl<ISD::InputArg> &Ins,
112 const SDLoc &DL, SelectionDAG &DAG,
113 SmallVectorImpl<SDValue> &InVals) const override;
114
115 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
116 const SmallVectorImpl<ISD::OutputArg> &Outs,
117 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
118 SelectionDAG &DAG) const override;
119
120 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
121 SelectionDAG &DAG) const override;
122
123 bool isIntDivCheap(EVT VT, AttributeList Attr) const override {
124 return false;
125 }
126
127 bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
128 Type *Ty) const override {
129 return true;
130 }
131
132 // Prevent reducing load width during SelectionDag phase.
133 // Otherwise, we may transform the following
134 // ctx = ctx + reloc_offset
135 // ... (*(u32 *)ctx) & 0x8000...
136 // to
137 // ctx = ctx + reloc_offset
138 // ... (*(u8 *)(ctx + 1)) & 0x80 ...
139 // which will be rejected by the verifier.
140 bool
141 shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT,
142 std::optional<unsigned> ByteOffset) const override {
143 return false;
144 }
145
146 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
147 Type *Ty, unsigned AS,
148 Instruction *I = nullptr) const override;
149
150 // isTruncateFree - Return true if it's free to truncate a value of
151 // type Ty1 to type Ty2. e.g. On BPF at alu32 mode, it's free to truncate
152 // a i64 value in register R1 to i32 by referencing its sub-register W1.
153 bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
154 bool isTruncateFree(EVT VT1, EVT VT2) const override;
155
156 // For 32bit ALU result zext to 64bit is free.
157 bool isZExtFree(Type *Ty1, Type *Ty2) const override;
158 bool isZExtFree(EVT VT1, EVT VT2) const override;
159 bool isZExtFree(SDValue Val, EVT VT2) const override;
160
161 unsigned EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB, unsigned Reg,
162 bool isSigned) const;
163
164 MachineBasicBlock * EmitInstrWithCustomInserterMemcpy(MachineInstr &MI,
165 MachineBasicBlock *BB)
166 const;
167 MachineBasicBlock *
168 EmitInstrWithCustomInserterLDimm64(MachineInstr &MI,
169 MachineBasicBlock *BB) const;
170
171 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
172 bool IsVarArg,
173 const SmallVectorImpl<ISD::OutputArg> &Outs,
174 LLVMContext &Context, const Type *RetTy) const override;
175};
176}
177
178#endif
179