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