xref: /aosp_15_r20/external/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- BPFISelDAGToDAG.cpp - A dag to dag inst selector for BPF ----------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file defines a DAG pattern matching instruction selector for BPF,
11*9880d681SAndroid Build Coastguard Worker // converting from a legalized dag to a BPF dag.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "BPF.h"
16*9880d681SAndroid Build Coastguard Worker #include "BPFRegisterInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "BPFSubtarget.h"
18*9880d681SAndroid Build Coastguard Worker #include "BPFTargetMachine.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineConstantPool.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/SelectionDAGISel.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IntrinsicInst.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
30*9880d681SAndroid Build Coastguard Worker using namespace llvm;
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "bpf-isel"
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker // Instruction Selector Implementation
35*9880d681SAndroid Build Coastguard Worker namespace {
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker class BPFDAGToDAGISel : public SelectionDAGISel {
38*9880d681SAndroid Build Coastguard Worker public:
BPFDAGToDAGISel(BPFTargetMachine & TM)39*9880d681SAndroid Build Coastguard Worker   explicit BPFDAGToDAGISel(BPFTargetMachine &TM) : SelectionDAGISel(TM) {}
40*9880d681SAndroid Build Coastguard Worker 
getPassName() const41*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override {
42*9880d681SAndroid Build Coastguard Worker     return "BPF DAG->DAG Pattern Instruction Selection";
43*9880d681SAndroid Build Coastguard Worker   }
44*9880d681SAndroid Build Coastguard Worker 
45*9880d681SAndroid Build Coastguard Worker private:
46*9880d681SAndroid Build Coastguard Worker // Include the pieces autogenerated from the target description.
47*9880d681SAndroid Build Coastguard Worker #include "BPFGenDAGISel.inc"
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker   void Select(SDNode *N) override;
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker   // Complex Pattern for address selection.
52*9880d681SAndroid Build Coastguard Worker   bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset);
53*9880d681SAndroid Build Coastguard Worker   bool SelectFIAddr(SDValue Addr, SDValue &Base, SDValue &Offset);
54*9880d681SAndroid Build Coastguard Worker };
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker // ComplexPattern used on BPF Load/Store instructions
SelectAddr(SDValue Addr,SDValue & Base,SDValue & Offset)58*9880d681SAndroid Build Coastguard Worker bool BPFDAGToDAGISel::SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) {
59*9880d681SAndroid Build Coastguard Worker   // if Address is FI, get the TargetFrameIndex.
60*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Addr);
61*9880d681SAndroid Build Coastguard Worker   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
62*9880d681SAndroid Build Coastguard Worker     Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
63*9880d681SAndroid Build Coastguard Worker     Offset = CurDAG->getTargetConstant(0, DL, MVT::i64);
64*9880d681SAndroid Build Coastguard Worker     return true;
65*9880d681SAndroid Build Coastguard Worker   }
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
68*9880d681SAndroid Build Coastguard Worker       Addr.getOpcode() == ISD::TargetGlobalAddress)
69*9880d681SAndroid Build Coastguard Worker     return false;
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker   // Addresses of the form Addr+const or Addr|const
72*9880d681SAndroid Build Coastguard Worker   if (CurDAG->isBaseWithConstantOffset(Addr)) {
73*9880d681SAndroid Build Coastguard Worker     ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
74*9880d681SAndroid Build Coastguard Worker     if (isInt<32>(CN->getSExtValue())) {
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker       // If the first operand is a FI, get the TargetFI Node
77*9880d681SAndroid Build Coastguard Worker       if (FrameIndexSDNode *FIN =
78*9880d681SAndroid Build Coastguard Worker               dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
79*9880d681SAndroid Build Coastguard Worker         Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
80*9880d681SAndroid Build Coastguard Worker       else
81*9880d681SAndroid Build Coastguard Worker         Base = Addr.getOperand(0);
82*9880d681SAndroid Build Coastguard Worker 
83*9880d681SAndroid Build Coastguard Worker       Offset = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64);
84*9880d681SAndroid Build Coastguard Worker       return true;
85*9880d681SAndroid Build Coastguard Worker     }
86*9880d681SAndroid Build Coastguard Worker   }
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker   Base   = Addr;
89*9880d681SAndroid Build Coastguard Worker   Offset = CurDAG->getTargetConstant(0, DL, MVT::i64);
90*9880d681SAndroid Build Coastguard Worker   return true;
91*9880d681SAndroid Build Coastguard Worker }
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker // ComplexPattern used on BPF FI instruction
SelectFIAddr(SDValue Addr,SDValue & Base,SDValue & Offset)94*9880d681SAndroid Build Coastguard Worker bool BPFDAGToDAGISel::SelectFIAddr(SDValue Addr, SDValue &Base, SDValue &Offset) {
95*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Addr);
96*9880d681SAndroid Build Coastguard Worker 
97*9880d681SAndroid Build Coastguard Worker   if (!CurDAG->isBaseWithConstantOffset(Addr))
98*9880d681SAndroid Build Coastguard Worker     return false;
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker   // Addresses of the form Addr+const or Addr|const
101*9880d681SAndroid Build Coastguard Worker   ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
102*9880d681SAndroid Build Coastguard Worker   if (isInt<32>(CN->getSExtValue())) {
103*9880d681SAndroid Build Coastguard Worker 
104*9880d681SAndroid Build Coastguard Worker     // If the first operand is a FI, get the TargetFI Node
105*9880d681SAndroid Build Coastguard Worker     if (FrameIndexSDNode *FIN =
106*9880d681SAndroid Build Coastguard Worker             dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
107*9880d681SAndroid Build Coastguard Worker       Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
108*9880d681SAndroid Build Coastguard Worker     else
109*9880d681SAndroid Build Coastguard Worker       return false;
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker     Offset = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64);
112*9880d681SAndroid Build Coastguard Worker     return true;
113*9880d681SAndroid Build Coastguard Worker   }
114*9880d681SAndroid Build Coastguard Worker 
115*9880d681SAndroid Build Coastguard Worker   return false;
116*9880d681SAndroid Build Coastguard Worker }
117*9880d681SAndroid Build Coastguard Worker 
Select(SDNode * Node)118*9880d681SAndroid Build Coastguard Worker void BPFDAGToDAGISel::Select(SDNode *Node) {
119*9880d681SAndroid Build Coastguard Worker   unsigned Opcode = Node->getOpcode();
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker   // Dump information about the Node being selected
122*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Selecting: "; Node->dump(CurDAG); dbgs() << '\n');
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker   // If we have a custom node, we already have selected!
125*9880d681SAndroid Build Coastguard Worker   if (Node->isMachineOpcode()) {
126*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << '\n');
127*9880d681SAndroid Build Coastguard Worker     return;
128*9880d681SAndroid Build Coastguard Worker   }
129*9880d681SAndroid Build Coastguard Worker 
130*9880d681SAndroid Build Coastguard Worker   // tablegen selection should be handled here.
131*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
132*9880d681SAndroid Build Coastguard Worker   default: break;
133*9880d681SAndroid Build Coastguard Worker   case ISD::SDIV: {
134*9880d681SAndroid Build Coastguard Worker     DebugLoc Empty;
135*9880d681SAndroid Build Coastguard Worker     const DebugLoc &DL = Node->getDebugLoc();
136*9880d681SAndroid Build Coastguard Worker     if (DL != Empty)
137*9880d681SAndroid Build Coastguard Worker       errs() << "Error at line " << DL.getLine() << ": ";
138*9880d681SAndroid Build Coastguard Worker     else
139*9880d681SAndroid Build Coastguard Worker       errs() << "Error: ";
140*9880d681SAndroid Build Coastguard Worker     errs() << "Unsupport signed division for DAG: ";
141*9880d681SAndroid Build Coastguard Worker     Node->dump(CurDAG);
142*9880d681SAndroid Build Coastguard Worker     errs() << "Please convert to unsigned div/mod.\n";
143*9880d681SAndroid Build Coastguard Worker     break;
144*9880d681SAndroid Build Coastguard Worker   }
145*9880d681SAndroid Build Coastguard Worker   case ISD::INTRINSIC_W_CHAIN: {
146*9880d681SAndroid Build Coastguard Worker     unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
147*9880d681SAndroid Build Coastguard Worker     switch (IntNo) {
148*9880d681SAndroid Build Coastguard Worker     case Intrinsic::bpf_load_byte:
149*9880d681SAndroid Build Coastguard Worker     case Intrinsic::bpf_load_half:
150*9880d681SAndroid Build Coastguard Worker     case Intrinsic::bpf_load_word: {
151*9880d681SAndroid Build Coastguard Worker       SDLoc DL(Node);
152*9880d681SAndroid Build Coastguard Worker       SDValue Chain = Node->getOperand(0);
153*9880d681SAndroid Build Coastguard Worker       SDValue N1 = Node->getOperand(1);
154*9880d681SAndroid Build Coastguard Worker       SDValue Skb = Node->getOperand(2);
155*9880d681SAndroid Build Coastguard Worker       SDValue N3 = Node->getOperand(3);
156*9880d681SAndroid Build Coastguard Worker 
157*9880d681SAndroid Build Coastguard Worker       SDValue R6Reg = CurDAG->getRegister(BPF::R6, MVT::i64);
158*9880d681SAndroid Build Coastguard Worker       Chain = CurDAG->getCopyToReg(Chain, DL, R6Reg, Skb, SDValue());
159*9880d681SAndroid Build Coastguard Worker       Node = CurDAG->UpdateNodeOperands(Node, Chain, N1, R6Reg, N3);
160*9880d681SAndroid Build Coastguard Worker       break;
161*9880d681SAndroid Build Coastguard Worker     }
162*9880d681SAndroid Build Coastguard Worker     }
163*9880d681SAndroid Build Coastguard Worker     break;
164*9880d681SAndroid Build Coastguard Worker   }
165*9880d681SAndroid Build Coastguard Worker 
166*9880d681SAndroid Build Coastguard Worker   case ISD::FrameIndex: {
167*9880d681SAndroid Build Coastguard Worker     int FI = cast<FrameIndexSDNode>(Node)->getIndex();
168*9880d681SAndroid Build Coastguard Worker     EVT VT = Node->getValueType(0);
169*9880d681SAndroid Build Coastguard Worker     SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
170*9880d681SAndroid Build Coastguard Worker     unsigned Opc = BPF::MOV_rr;
171*9880d681SAndroid Build Coastguard Worker     if (Node->hasOneUse()) {
172*9880d681SAndroid Build Coastguard Worker       CurDAG->SelectNodeTo(Node, Opc, VT, TFI);
173*9880d681SAndroid Build Coastguard Worker       return;
174*9880d681SAndroid Build Coastguard Worker     }
175*9880d681SAndroid Build Coastguard Worker     ReplaceNode(Node, CurDAG->getMachineNode(Opc, SDLoc(Node), VT, TFI));
176*9880d681SAndroid Build Coastguard Worker     return;
177*9880d681SAndroid Build Coastguard Worker   }
178*9880d681SAndroid Build Coastguard Worker   }
179*9880d681SAndroid Build Coastguard Worker 
180*9880d681SAndroid Build Coastguard Worker   // Select the default instruction
181*9880d681SAndroid Build Coastguard Worker   SelectCode(Node);
182*9880d681SAndroid Build Coastguard Worker }
183*9880d681SAndroid Build Coastguard Worker 
createBPFISelDag(BPFTargetMachine & TM)184*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createBPFISelDag(BPFTargetMachine &TM) {
185*9880d681SAndroid Build Coastguard Worker   return new BPFDAGToDAGISel(TM);
186*9880d681SAndroid Build Coastguard Worker }
187