xref: /aosp_15_r20/external/llvm/lib/Target/BPF/BPFInstrInfo.td (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker//===-- BPFInstrInfo.td - Target Description for BPF Target ---------------===//
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 describes the BPF instructions in TableGen format.
11*9880d681SAndroid Build Coastguard Worker//
12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Workerinclude "BPFInstrFormats.td"
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker// Instruction Operands and Patterns
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker// These are target-independent nodes, but have target-specific formats.
19*9880d681SAndroid Build Coastguard Workerdef SDT_BPFCallSeqStart : SDCallSeqStart<[SDTCisVT<0, iPTR>]>;
20*9880d681SAndroid Build Coastguard Workerdef SDT_BPFCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
21*9880d681SAndroid Build Coastguard Workerdef SDT_BPFCall         : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
22*9880d681SAndroid Build Coastguard Workerdef SDT_BPFSetFlag      : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>]>;
23*9880d681SAndroid Build Coastguard Workerdef SDT_BPFSelectCC     : SDTypeProfile<1, 5, [SDTCisSameAs<1, 2>,
24*9880d681SAndroid Build Coastguard Worker                                               SDTCisSameAs<0, 4>,
25*9880d681SAndroid Build Coastguard Worker                                               SDTCisSameAs<4, 5>]>;
26*9880d681SAndroid Build Coastguard Workerdef SDT_BPFBrCC         : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,
27*9880d681SAndroid Build Coastguard Worker                                               SDTCisVT<3, OtherVT>]>;
28*9880d681SAndroid Build Coastguard Workerdef SDT_BPFWrapper      : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
29*9880d681SAndroid Build Coastguard Worker                                               SDTCisPtrTy<0>]>;
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Workerdef BPFcall         : SDNode<"BPFISD::CALL", SDT_BPFCall,
32*9880d681SAndroid Build Coastguard Worker                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
33*9880d681SAndroid Build Coastguard Worker                              SDNPVariadic]>;
34*9880d681SAndroid Build Coastguard Workerdef BPFretflag      : SDNode<"BPFISD::RET_FLAG", SDTNone,
35*9880d681SAndroid Build Coastguard Worker                             [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
36*9880d681SAndroid Build Coastguard Workerdef BPFcallseq_start: SDNode<"ISD::CALLSEQ_START", SDT_BPFCallSeqStart,
37*9880d681SAndroid Build Coastguard Worker                             [SDNPHasChain, SDNPOutGlue]>;
38*9880d681SAndroid Build Coastguard Workerdef BPFcallseq_end  : SDNode<"ISD::CALLSEQ_END",   SDT_BPFCallSeqEnd,
39*9880d681SAndroid Build Coastguard Worker                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
40*9880d681SAndroid Build Coastguard Workerdef BPFbrcc         : SDNode<"BPFISD::BR_CC", SDT_BPFBrCC,
41*9880d681SAndroid Build Coastguard Worker                             [SDNPHasChain, SDNPOutGlue, SDNPInGlue]>;
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Workerdef BPFselectcc     : SDNode<"BPFISD::SELECT_CC", SDT_BPFSelectCC, [SDNPInGlue]>;
44*9880d681SAndroid Build Coastguard Workerdef BPFWrapper      : SDNode<"BPFISD::Wrapper", SDT_BPFWrapper>;
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Workerdef brtarget : Operand<OtherVT>;
47*9880d681SAndroid Build Coastguard Workerdef calltarget : Operand<i64>;
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Workerdef u64imm   : Operand<i64> {
50*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printImm64Operand";
51*9880d681SAndroid Build Coastguard Worker}
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Workerdef i64immSExt32 : PatLeaf<(imm),
54*9880d681SAndroid Build Coastguard Worker                [{return isInt<32>(N->getSExtValue()); }]>;
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker// Addressing modes.
57*9880d681SAndroid Build Coastguard Workerdef ADDRri : ComplexPattern<i64, 2, "SelectAddr", [], []>;
58*9880d681SAndroid Build Coastguard Workerdef FIri : ComplexPattern<i64, 2, "SelectFIAddr", [add, or], []>;
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker// Address operands
61*9880d681SAndroid Build Coastguard Workerdef MEMri : Operand<i64> {
62*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printMemOperand";
63*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getMemoryOpValue";
64*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR, i16imm);
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker// Conditional code predicates - used for pattern matching for jump instructions
68*9880d681SAndroid Build Coastguard Workerdef BPF_CC_EQ  : PatLeaf<(imm),
69*9880d681SAndroid Build Coastguard Worker                         [{return (N->getZExtValue() == ISD::SETEQ);}]>;
70*9880d681SAndroid Build Coastguard Workerdef BPF_CC_NE  : PatLeaf<(imm),
71*9880d681SAndroid Build Coastguard Worker                         [{return (N->getZExtValue() == ISD::SETNE);}]>;
72*9880d681SAndroid Build Coastguard Workerdef BPF_CC_GE  : PatLeaf<(imm),
73*9880d681SAndroid Build Coastguard Worker                         [{return (N->getZExtValue() == ISD::SETGE);}]>;
74*9880d681SAndroid Build Coastguard Workerdef BPF_CC_GT  : PatLeaf<(imm),
75*9880d681SAndroid Build Coastguard Worker                         [{return (N->getZExtValue() == ISD::SETGT);}]>;
76*9880d681SAndroid Build Coastguard Workerdef BPF_CC_GTU : PatLeaf<(imm),
77*9880d681SAndroid Build Coastguard Worker                         [{return (N->getZExtValue() == ISD::SETUGT);}]>;
78*9880d681SAndroid Build Coastguard Workerdef BPF_CC_GEU : PatLeaf<(imm),
79*9880d681SAndroid Build Coastguard Worker                         [{return (N->getZExtValue() == ISD::SETUGE);}]>;
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker// jump instructions
82*9880d681SAndroid Build Coastguard Workerclass JMP_RR<bits<4> Opc, string OpcodeStr, PatLeaf Cond>
83*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs), (ins GPR:$dst, GPR:$src, brtarget:$BrDst),
84*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$dst, $src goto $BrDst"),
85*9880d681SAndroid Build Coastguard Worker              [(BPFbrcc i64:$dst, i64:$src, Cond, bb:$BrDst)]> {
86*9880d681SAndroid Build Coastguard Worker  bits<4> op;
87*9880d681SAndroid Build Coastguard Worker  bits<1> BPFSrc;
88*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
89*9880d681SAndroid Build Coastguard Worker  bits<4> src;
90*9880d681SAndroid Build Coastguard Worker  bits<16> BrDst;
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
93*9880d681SAndroid Build Coastguard Worker  let Inst{59} = BPFSrc;
94*9880d681SAndroid Build Coastguard Worker  let Inst{55-52} = src;
95*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
96*9880d681SAndroid Build Coastguard Worker  let Inst{47-32} = BrDst;
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker  let op = Opc;
99*9880d681SAndroid Build Coastguard Worker  let BPFSrc = 1;
100*9880d681SAndroid Build Coastguard Worker  let BPFClass = 5; // BPF_JMP
101*9880d681SAndroid Build Coastguard Worker}
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Workerclass JMP_RI<bits<4> Opc, string OpcodeStr, PatLeaf Cond>
104*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs), (ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
105*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "i\t$dst, $imm goto $BrDst"),
106*9880d681SAndroid Build Coastguard Worker              [(BPFbrcc i64:$dst, i64immSExt32:$imm, Cond, bb:$BrDst)]> {
107*9880d681SAndroid Build Coastguard Worker  bits<4> op;
108*9880d681SAndroid Build Coastguard Worker  bits<1> BPFSrc;
109*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
110*9880d681SAndroid Build Coastguard Worker  bits<16> BrDst;
111*9880d681SAndroid Build Coastguard Worker  bits<32> imm;
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
114*9880d681SAndroid Build Coastguard Worker  let Inst{59} = BPFSrc;
115*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
116*9880d681SAndroid Build Coastguard Worker  let Inst{47-32} = BrDst;
117*9880d681SAndroid Build Coastguard Worker  let Inst{31-0} = imm;
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker  let op = Opc;
120*9880d681SAndroid Build Coastguard Worker  let BPFSrc = 0;
121*9880d681SAndroid Build Coastguard Worker  let BPFClass = 5; // BPF_JMP
122*9880d681SAndroid Build Coastguard Worker}
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Workermulticlass J<bits<4> Opc, string OpcodeStr, PatLeaf Cond> {
125*9880d681SAndroid Build Coastguard Worker  def _rr : JMP_RR<Opc, OpcodeStr, Cond>;
126*9880d681SAndroid Build Coastguard Worker  def _ri : JMP_RI<Opc, OpcodeStr, Cond>;
127*9880d681SAndroid Build Coastguard Worker}
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isTerminator = 1, hasDelaySlot=0 in {
130*9880d681SAndroid Build Coastguard Worker// cmp+goto instructions
131*9880d681SAndroid Build Coastguard Workerdefm JEQ  : J<0x1, "jeq",  BPF_CC_EQ>;
132*9880d681SAndroid Build Coastguard Workerdefm JUGT : J<0x2, "jgt", BPF_CC_GTU>;
133*9880d681SAndroid Build Coastguard Workerdefm JUGE : J<0x3, "jge", BPF_CC_GEU>;
134*9880d681SAndroid Build Coastguard Workerdefm JNE  : J<0x5, "jne",  BPF_CC_NE>;
135*9880d681SAndroid Build Coastguard Workerdefm JSGT : J<0x6, "jsgt", BPF_CC_GT>;
136*9880d681SAndroid Build Coastguard Workerdefm JSGE : J<0x7, "jsge", BPF_CC_GE>;
137*9880d681SAndroid Build Coastguard Worker}
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker// ALU instructions
140*9880d681SAndroid Build Coastguard Workerclass ALU_RI<bits<4> Opc, string OpcodeStr, SDNode OpNode>
141*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs GPR:$dst), (ins GPR:$src2, i64imm:$imm),
142*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "i\t$dst, $imm"),
143*9880d681SAndroid Build Coastguard Worker              [(set GPR:$dst, (OpNode GPR:$src2, i64immSExt32:$imm))]> {
144*9880d681SAndroid Build Coastguard Worker  bits<4> op;
145*9880d681SAndroid Build Coastguard Worker  bits<1> BPFSrc;
146*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
147*9880d681SAndroid Build Coastguard Worker  bits<32> imm;
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
150*9880d681SAndroid Build Coastguard Worker  let Inst{59} = BPFSrc;
151*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
152*9880d681SAndroid Build Coastguard Worker  let Inst{31-0} = imm;
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker  let op = Opc;
155*9880d681SAndroid Build Coastguard Worker  let BPFSrc = 0;
156*9880d681SAndroid Build Coastguard Worker  let BPFClass = 7; // BPF_ALU64
157*9880d681SAndroid Build Coastguard Worker}
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Workerclass ALU_RR<bits<4> Opc, string OpcodeStr, SDNode OpNode>
160*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs GPR:$dst), (ins GPR:$src2, GPR:$src),
161*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$dst, $src"),
162*9880d681SAndroid Build Coastguard Worker              [(set GPR:$dst, (OpNode i64:$src2, i64:$src))]> {
163*9880d681SAndroid Build Coastguard Worker  bits<4> op;
164*9880d681SAndroid Build Coastguard Worker  bits<1> BPFSrc;
165*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
166*9880d681SAndroid Build Coastguard Worker  bits<4> src;
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
169*9880d681SAndroid Build Coastguard Worker  let Inst{59} = BPFSrc;
170*9880d681SAndroid Build Coastguard Worker  let Inst{55-52} = src;
171*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker  let op = Opc;
174*9880d681SAndroid Build Coastguard Worker  let BPFSrc = 1;
175*9880d681SAndroid Build Coastguard Worker  let BPFClass = 7; // BPF_ALU64
176*9880d681SAndroid Build Coastguard Worker}
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Workermulticlass ALU<bits<4> Opc, string OpcodeStr, SDNode OpNode> {
179*9880d681SAndroid Build Coastguard Worker  def _rr : ALU_RR<Opc, OpcodeStr, OpNode>;
180*9880d681SAndroid Build Coastguard Worker  def _ri : ALU_RI<Opc, OpcodeStr, OpNode>;
181*9880d681SAndroid Build Coastguard Worker}
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Workerlet Constraints = "$dst = $src2" in {
184*9880d681SAndroid Build Coastguard Workerlet isAsCheapAsAMove = 1 in {
185*9880d681SAndroid Build Coastguard Worker  defm ADD : ALU<0x0, "add", add>;
186*9880d681SAndroid Build Coastguard Worker  defm SUB : ALU<0x1, "sub", sub>;
187*9880d681SAndroid Build Coastguard Worker  defm OR  : ALU<0x4, "or", or>;
188*9880d681SAndroid Build Coastguard Worker  defm AND : ALU<0x5, "and", and>;
189*9880d681SAndroid Build Coastguard Worker  defm SLL : ALU<0x6, "sll", shl>;
190*9880d681SAndroid Build Coastguard Worker  defm SRL : ALU<0x7, "srl", srl>;
191*9880d681SAndroid Build Coastguard Worker  defm XOR : ALU<0xa, "xor", xor>;
192*9880d681SAndroid Build Coastguard Worker  defm SRA : ALU<0xc, "sra", sra>;
193*9880d681SAndroid Build Coastguard Worker}
194*9880d681SAndroid Build Coastguard Worker  defm MUL : ALU<0x2, "mul", mul>;
195*9880d681SAndroid Build Coastguard Worker  defm DIV : ALU<0x3, "div", udiv>;
196*9880d681SAndroid Build Coastguard Worker}
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Workerclass MOV_RR<string OpcodeStr>
199*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs GPR:$dst), (ins GPR:$src),
200*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$dst, $src"),
201*9880d681SAndroid Build Coastguard Worker              []> {
202*9880d681SAndroid Build Coastguard Worker  bits<4> op;
203*9880d681SAndroid Build Coastguard Worker  bits<1> BPFSrc;
204*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
205*9880d681SAndroid Build Coastguard Worker  bits<4> src;
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
208*9880d681SAndroid Build Coastguard Worker  let Inst{59} = BPFSrc;
209*9880d681SAndroid Build Coastguard Worker  let Inst{55-52} = src;
210*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker  let op = 0xb;     // BPF_MOV
213*9880d681SAndroid Build Coastguard Worker  let BPFSrc = 1;   // BPF_X
214*9880d681SAndroid Build Coastguard Worker  let BPFClass = 7; // BPF_ALU64
215*9880d681SAndroid Build Coastguard Worker}
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Workerclass MOV_RI<string OpcodeStr>
218*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs GPR:$dst), (ins i64imm:$imm),
219*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$dst, $imm"),
220*9880d681SAndroid Build Coastguard Worker              [(set GPR:$dst, (i64 i64immSExt32:$imm))]> {
221*9880d681SAndroid Build Coastguard Worker  bits<4> op;
222*9880d681SAndroid Build Coastguard Worker  bits<1> BPFSrc;
223*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
224*9880d681SAndroid Build Coastguard Worker  bits<32> imm;
225*9880d681SAndroid Build Coastguard Worker
226*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
227*9880d681SAndroid Build Coastguard Worker  let Inst{59} = BPFSrc;
228*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
229*9880d681SAndroid Build Coastguard Worker  let Inst{31-0} = imm;
230*9880d681SAndroid Build Coastguard Worker
231*9880d681SAndroid Build Coastguard Worker  let op = 0xb;     // BPF_MOV
232*9880d681SAndroid Build Coastguard Worker  let BPFSrc = 0;   // BPF_K
233*9880d681SAndroid Build Coastguard Worker  let BPFClass = 7; // BPF_ALU64
234*9880d681SAndroid Build Coastguard Worker}
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Workerclass LD_IMM64<bits<4> Pseudo, string OpcodeStr>
237*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs GPR:$dst), (ins u64imm:$imm),
238*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$dst, $imm"),
239*9880d681SAndroid Build Coastguard Worker              [(set GPR:$dst, (i64 imm:$imm))]> {
240*9880d681SAndroid Build Coastguard Worker
241*9880d681SAndroid Build Coastguard Worker  bits<3> mode;
242*9880d681SAndroid Build Coastguard Worker  bits<2> size;
243*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
244*9880d681SAndroid Build Coastguard Worker  bits<64> imm;
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker  let Inst{63-61} = mode;
247*9880d681SAndroid Build Coastguard Worker  let Inst{60-59} = size;
248*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
249*9880d681SAndroid Build Coastguard Worker  let Inst{55-52} = Pseudo;
250*9880d681SAndroid Build Coastguard Worker  let Inst{47-32} = 0;
251*9880d681SAndroid Build Coastguard Worker  let Inst{31-0} = imm{31-0};
252*9880d681SAndroid Build Coastguard Worker
253*9880d681SAndroid Build Coastguard Worker  let mode = 0;     // BPF_IMM
254*9880d681SAndroid Build Coastguard Worker  let size = 3;     // BPF_DW
255*9880d681SAndroid Build Coastguard Worker  let BPFClass = 0; // BPF_LD
256*9880d681SAndroid Build Coastguard Worker}
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1, isAsCheapAsAMove = 1 in {
259*9880d681SAndroid Build Coastguard Workerdef LD_imm64 : LD_IMM64<0, "ld_64">;
260*9880d681SAndroid Build Coastguard Workerdef MOV_rr : MOV_RR<"mov">;
261*9880d681SAndroid Build Coastguard Workerdef MOV_ri : MOV_RI<"mov">;
262*9880d681SAndroid Build Coastguard Worker}
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Workerdef FI_ri
265*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs GPR:$dst), (ins MEMri:$addr),
266*9880d681SAndroid Build Coastguard Worker               "lea\t$dst, $addr",
267*9880d681SAndroid Build Coastguard Worker               [(set i64:$dst, FIri:$addr)]> {
268*9880d681SAndroid Build Coastguard Worker  // This is a tentative instruction, and will be replaced
269*9880d681SAndroid Build Coastguard Worker  // with MOV_rr and ADD_ri in PEI phase
270*9880d681SAndroid Build Coastguard Worker}
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker
273*9880d681SAndroid Build Coastguard Workerdef LD_pseudo
274*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs GPR:$dst), (ins i64imm:$pseudo, u64imm:$imm),
275*9880d681SAndroid Build Coastguard Worker              "ld_pseudo\t$dst, $pseudo, $imm",
276*9880d681SAndroid Build Coastguard Worker              [(set GPR:$dst, (int_bpf_pseudo imm:$pseudo, imm:$imm))]> {
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker  bits<3> mode;
279*9880d681SAndroid Build Coastguard Worker  bits<2> size;
280*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
281*9880d681SAndroid Build Coastguard Worker  bits<64> imm;
282*9880d681SAndroid Build Coastguard Worker  bits<4> pseudo;
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Worker  let Inst{63-61} = mode;
285*9880d681SAndroid Build Coastguard Worker  let Inst{60-59} = size;
286*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
287*9880d681SAndroid Build Coastguard Worker  let Inst{55-52} = pseudo;
288*9880d681SAndroid Build Coastguard Worker  let Inst{47-32} = 0;
289*9880d681SAndroid Build Coastguard Worker  let Inst{31-0} = imm{31-0};
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Worker  let mode = 0;     // BPF_IMM
292*9880d681SAndroid Build Coastguard Worker  let size = 3;     // BPF_DW
293*9880d681SAndroid Build Coastguard Worker  let BPFClass = 0; // BPF_LD
294*9880d681SAndroid Build Coastguard Worker}
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Worker// STORE instructions
297*9880d681SAndroid Build Coastguard Workerclass STORE<bits<2> SizeOp, string OpcodeStr, list<dag> Pattern>
298*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs), (ins GPR:$src, MEMri:$addr),
299*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$addr, $src"), Pattern> {
300*9880d681SAndroid Build Coastguard Worker  bits<3> mode;
301*9880d681SAndroid Build Coastguard Worker  bits<2> size;
302*9880d681SAndroid Build Coastguard Worker  bits<4> src;
303*9880d681SAndroid Build Coastguard Worker  bits<20> addr;
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker  let Inst{63-61} = mode;
306*9880d681SAndroid Build Coastguard Worker  let Inst{60-59} = size;
307*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = addr{19-16}; // base reg
308*9880d681SAndroid Build Coastguard Worker  let Inst{55-52} = src;
309*9880d681SAndroid Build Coastguard Worker  let Inst{47-32} = addr{15-0}; // offset
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker  let mode = 3;     // BPF_MEM
312*9880d681SAndroid Build Coastguard Worker  let size = SizeOp;
313*9880d681SAndroid Build Coastguard Worker  let BPFClass = 3; // BPF_STX
314*9880d681SAndroid Build Coastguard Worker}
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Workerclass STOREi64<bits<2> Opc, string OpcodeStr, PatFrag OpNode>
317*9880d681SAndroid Build Coastguard Worker    : STORE<Opc, OpcodeStr, [(OpNode i64:$src, ADDRri:$addr)]>;
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Workerdef STW : STOREi64<0x0, "stw", truncstorei32>;
320*9880d681SAndroid Build Coastguard Workerdef STH : STOREi64<0x1, "sth", truncstorei16>;
321*9880d681SAndroid Build Coastguard Workerdef STB : STOREi64<0x2, "stb", truncstorei8>;
322*9880d681SAndroid Build Coastguard Workerdef STD : STOREi64<0x3, "std", store>;
323*9880d681SAndroid Build Coastguard Worker
324*9880d681SAndroid Build Coastguard Worker// LOAD instructions
325*9880d681SAndroid Build Coastguard Workerclass LOAD<bits<2> SizeOp, string OpcodeStr, list<dag> Pattern>
326*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs GPR:$dst), (ins MEMri:$addr),
327*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$dst, $addr"), Pattern> {
328*9880d681SAndroid Build Coastguard Worker  bits<3> mode;
329*9880d681SAndroid Build Coastguard Worker  bits<2> size;
330*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
331*9880d681SAndroid Build Coastguard Worker  bits<20> addr;
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker  let Inst{63-61} = mode;
334*9880d681SAndroid Build Coastguard Worker  let Inst{60-59} = size;
335*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
336*9880d681SAndroid Build Coastguard Worker  let Inst{55-52} = addr{19-16};
337*9880d681SAndroid Build Coastguard Worker  let Inst{47-32} = addr{15-0};
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker  let mode = 3;     // BPF_MEM
340*9880d681SAndroid Build Coastguard Worker  let size = SizeOp;
341*9880d681SAndroid Build Coastguard Worker  let BPFClass = 1; // BPF_LDX
342*9880d681SAndroid Build Coastguard Worker}
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Workerclass LOADi64<bits<2> SizeOp, string OpcodeStr, PatFrag OpNode>
345*9880d681SAndroid Build Coastguard Worker    : LOAD<SizeOp, OpcodeStr, [(set i64:$dst, (OpNode ADDRri:$addr))]>;
346*9880d681SAndroid Build Coastguard Worker
347*9880d681SAndroid Build Coastguard Workerdef LDW : LOADi64<0x0, "ldw", zextloadi32>;
348*9880d681SAndroid Build Coastguard Workerdef LDH : LOADi64<0x1, "ldh", zextloadi16>;
349*9880d681SAndroid Build Coastguard Workerdef LDB : LOADi64<0x2, "ldb", zextloadi8>;
350*9880d681SAndroid Build Coastguard Workerdef LDD : LOADi64<0x3, "ldd", load>;
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Workerclass BRANCH<bits<4> Opc, string OpcodeStr, list<dag> Pattern>
353*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs), (ins brtarget:$BrDst),
354*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$BrDst"), Pattern> {
355*9880d681SAndroid Build Coastguard Worker  bits<4> op;
356*9880d681SAndroid Build Coastguard Worker  bits<16> BrDst;
357*9880d681SAndroid Build Coastguard Worker  bits<1> BPFSrc;
358*9880d681SAndroid Build Coastguard Worker
359*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
360*9880d681SAndroid Build Coastguard Worker  let Inst{59} = BPFSrc;
361*9880d681SAndroid Build Coastguard Worker  let Inst{47-32} = BrDst;
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker  let op = Opc;
364*9880d681SAndroid Build Coastguard Worker  let BPFSrc = 0;
365*9880d681SAndroid Build Coastguard Worker  let BPFClass = 5; // BPF_JMP
366*9880d681SAndroid Build Coastguard Worker}
367*9880d681SAndroid Build Coastguard Worker
368*9880d681SAndroid Build Coastguard Workerclass CALL<string OpcodeStr>
369*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs), (ins calltarget:$BrDst),
370*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$BrDst"), []> {
371*9880d681SAndroid Build Coastguard Worker  bits<4> op;
372*9880d681SAndroid Build Coastguard Worker  bits<32> BrDst;
373*9880d681SAndroid Build Coastguard Worker  bits<1> BPFSrc;
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
376*9880d681SAndroid Build Coastguard Worker  let Inst{59} = BPFSrc;
377*9880d681SAndroid Build Coastguard Worker  let Inst{31-0} = BrDst;
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker  let op = 8;       // BPF_CALL
380*9880d681SAndroid Build Coastguard Worker  let BPFSrc = 0;
381*9880d681SAndroid Build Coastguard Worker  let BPFClass = 5; // BPF_JMP
382*9880d681SAndroid Build Coastguard Worker}
383*9880d681SAndroid Build Coastguard Worker
384*9880d681SAndroid Build Coastguard Worker// Jump always
385*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isTerminator = 1, hasDelaySlot=0, isBarrier = 1 in {
386*9880d681SAndroid Build Coastguard Worker  def JMP : BRANCH<0x0, "jmp", [(br bb:$BrDst)]>;
387*9880d681SAndroid Build Coastguard Worker}
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Worker// Jump and link
390*9880d681SAndroid Build Coastguard Workerlet isCall=1, hasDelaySlot=0, Uses = [R11],
391*9880d681SAndroid Build Coastguard Worker    // Potentially clobbered registers
392*9880d681SAndroid Build Coastguard Worker    Defs = [R0, R1, R2, R3, R4, R5] in {
393*9880d681SAndroid Build Coastguard Worker  def JAL  : CALL<"call">;
394*9880d681SAndroid Build Coastguard Worker}
395*9880d681SAndroid Build Coastguard Worker
396*9880d681SAndroid Build Coastguard Workerclass NOP_I<string OpcodeStr>
397*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs), (ins i32imm:$imm),
398*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$imm"), []> {
399*9880d681SAndroid Build Coastguard Worker  // mov r0, r0 == nop
400*9880d681SAndroid Build Coastguard Worker  bits<4> op;
401*9880d681SAndroid Build Coastguard Worker  bits<1> BPFSrc;
402*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
403*9880d681SAndroid Build Coastguard Worker  bits<4> src;
404*9880d681SAndroid Build Coastguard Worker
405*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
406*9880d681SAndroid Build Coastguard Worker  let Inst{59} = BPFSrc;
407*9880d681SAndroid Build Coastguard Worker  let Inst{55-52} = src;
408*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
409*9880d681SAndroid Build Coastguard Worker
410*9880d681SAndroid Build Coastguard Worker  let op = 0xb;     // BPF_MOV
411*9880d681SAndroid Build Coastguard Worker  let BPFSrc = 1;   // BPF_X
412*9880d681SAndroid Build Coastguard Worker  let BPFClass = 7; // BPF_ALU64
413*9880d681SAndroid Build Coastguard Worker  let src = 0;      // R0
414*9880d681SAndroid Build Coastguard Worker  let dst = 0;      // R0
415*9880d681SAndroid Build Coastguard Worker}
416*9880d681SAndroid Build Coastguard Worker
417*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
418*9880d681SAndroid Build Coastguard Worker  def NOP : NOP_I<"nop">;
419*9880d681SAndroid Build Coastguard Worker
420*9880d681SAndroid Build Coastguard Workerclass RET<string OpcodeStr>
421*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs), (ins),
422*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, ""), [(BPFretflag)]> {
423*9880d681SAndroid Build Coastguard Worker  bits<4> op;
424*9880d681SAndroid Build Coastguard Worker
425*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
426*9880d681SAndroid Build Coastguard Worker  let Inst{59} = 0;
427*9880d681SAndroid Build Coastguard Worker  let Inst{31-0} = 0;
428*9880d681SAndroid Build Coastguard Worker
429*9880d681SAndroid Build Coastguard Worker  let op = 9;       // BPF_EXIT
430*9880d681SAndroid Build Coastguard Worker  let BPFClass = 5; // BPF_JMP
431*9880d681SAndroid Build Coastguard Worker}
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Workerlet isReturn = 1, isTerminator = 1, hasDelaySlot=0, isBarrier = 1,
434*9880d681SAndroid Build Coastguard Worker    isNotDuplicable = 1 in {
435*9880d681SAndroid Build Coastguard Worker  def RET : RET<"ret">;
436*9880d681SAndroid Build Coastguard Worker}
437*9880d681SAndroid Build Coastguard Worker
438*9880d681SAndroid Build Coastguard Worker// ADJCALLSTACKDOWN/UP pseudo insns
439*9880d681SAndroid Build Coastguard Workerlet Defs = [R11], Uses = [R11] in {
440*9880d681SAndroid Build Coastguard Workerdef ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt),
441*9880d681SAndroid Build Coastguard Worker                              "#ADJCALLSTACKDOWN $amt",
442*9880d681SAndroid Build Coastguard Worker                              [(BPFcallseq_start timm:$amt)]>;
443*9880d681SAndroid Build Coastguard Workerdef ADJCALLSTACKUP   : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
444*9880d681SAndroid Build Coastguard Worker                              "#ADJCALLSTACKUP $amt1 $amt2",
445*9880d681SAndroid Build Coastguard Worker                              [(BPFcallseq_end timm:$amt1, timm:$amt2)]>;
446*9880d681SAndroid Build Coastguard Worker}
447*9880d681SAndroid Build Coastguard Worker
448*9880d681SAndroid Build Coastguard Workerlet usesCustomInserter = 1 in {
449*9880d681SAndroid Build Coastguard Worker  def Select : Pseudo<(outs GPR:$dst),
450*9880d681SAndroid Build Coastguard Worker                      (ins GPR:$lhs, GPR:$rhs, i64imm:$imm, GPR:$src, GPR:$src2),
451*9880d681SAndroid Build Coastguard Worker                      "# Select PSEUDO $dst = $lhs $imm $rhs ? $src : $src2",
452*9880d681SAndroid Build Coastguard Worker                      [(set i64:$dst,
453*9880d681SAndroid Build Coastguard Worker                       (BPFselectcc i64:$lhs, i64:$rhs, (i64 imm:$imm), i64:$src, i64:$src2))]>;
454*9880d681SAndroid Build Coastguard Worker}
455*9880d681SAndroid Build Coastguard Worker
456*9880d681SAndroid Build Coastguard Worker// load 64-bit global addr into register
457*9880d681SAndroid Build Coastguard Workerdef : Pat<(BPFWrapper tglobaladdr:$in), (LD_imm64 tglobaladdr:$in)>;
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker// 0xffffFFFF doesn't fit into simm32, optimize common case
460*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (and (i64 GPR:$src), 0xffffFFFF)),
461*9880d681SAndroid Build Coastguard Worker          (SRL_ri (SLL_ri (i64 GPR:$src), 32), 32)>;
462*9880d681SAndroid Build Coastguard Worker
463*9880d681SAndroid Build Coastguard Worker// Calls
464*9880d681SAndroid Build Coastguard Workerdef : Pat<(BPFcall tglobaladdr:$dst), (JAL tglobaladdr:$dst)>;
465*9880d681SAndroid Build Coastguard Workerdef : Pat<(BPFcall imm:$dst), (JAL imm:$dst)>;
466*9880d681SAndroid Build Coastguard Worker
467*9880d681SAndroid Build Coastguard Worker// Loads
468*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi8  ADDRri:$src), (i64 (LDB ADDRri:$src))>;
469*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi16 ADDRri:$src), (i64 (LDH ADDRri:$src))>;
470*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi32 ADDRri:$src), (i64 (LDW ADDRri:$src))>;
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Worker// Atomics
473*9880d681SAndroid Build Coastguard Workerclass XADD<bits<2> SizeOp, string OpcodeStr, PatFrag OpNode>
474*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs GPR:$dst), (ins MEMri:$addr, GPR:$val),
475*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$dst, $addr, $val"),
476*9880d681SAndroid Build Coastguard Worker              [(set GPR:$dst, (OpNode ADDRri:$addr, GPR:$val))]> {
477*9880d681SAndroid Build Coastguard Worker  bits<3> mode;
478*9880d681SAndroid Build Coastguard Worker  bits<2> size;
479*9880d681SAndroid Build Coastguard Worker  bits<4> src;
480*9880d681SAndroid Build Coastguard Worker  bits<20> addr;
481*9880d681SAndroid Build Coastguard Worker
482*9880d681SAndroid Build Coastguard Worker  let Inst{63-61} = mode;
483*9880d681SAndroid Build Coastguard Worker  let Inst{60-59} = size;
484*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = addr{19-16}; // base reg
485*9880d681SAndroid Build Coastguard Worker  let Inst{55-52} = src;
486*9880d681SAndroid Build Coastguard Worker  let Inst{47-32} = addr{15-0}; // offset
487*9880d681SAndroid Build Coastguard Worker
488*9880d681SAndroid Build Coastguard Worker  let mode = 6;     // BPF_XADD
489*9880d681SAndroid Build Coastguard Worker  let size = SizeOp;
490*9880d681SAndroid Build Coastguard Worker  let BPFClass = 3; // BPF_STX
491*9880d681SAndroid Build Coastguard Worker}
492*9880d681SAndroid Build Coastguard Worker
493*9880d681SAndroid Build Coastguard Workerlet Constraints = "$dst = $val" in {
494*9880d681SAndroid Build Coastguard Workerdef XADD32 : XADD<0, "xadd32", atomic_load_add_32>;
495*9880d681SAndroid Build Coastguard Workerdef XADD64 : XADD<3, "xadd64", atomic_load_add_64>;
496*9880d681SAndroid Build Coastguard Worker// undefined def XADD16 : XADD<1, "xadd16", atomic_load_add_16>;
497*9880d681SAndroid Build Coastguard Worker// undefined def XADD8  : XADD<2, "xadd8", atomic_load_add_8>;
498*9880d681SAndroid Build Coastguard Worker}
499*9880d681SAndroid Build Coastguard Worker
500*9880d681SAndroid Build Coastguard Worker// bswap16, bswap32, bswap64
501*9880d681SAndroid Build Coastguard Workerclass BSWAP<bits<32> SizeOp, string OpcodeStr, list<dag> Pattern>
502*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs GPR:$dst), (ins GPR:$src),
503*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t$dst"),
504*9880d681SAndroid Build Coastguard Worker              Pattern> {
505*9880d681SAndroid Build Coastguard Worker  bits<4> op;
506*9880d681SAndroid Build Coastguard Worker  bits<1> BPFSrc;
507*9880d681SAndroid Build Coastguard Worker  bits<4> dst;
508*9880d681SAndroid Build Coastguard Worker  bits<32> imm;
509*9880d681SAndroid Build Coastguard Worker
510*9880d681SAndroid Build Coastguard Worker  let Inst{63-60} = op;
511*9880d681SAndroid Build Coastguard Worker  let Inst{59} = BPFSrc;
512*9880d681SAndroid Build Coastguard Worker  let Inst{51-48} = dst;
513*9880d681SAndroid Build Coastguard Worker  let Inst{31-0} = imm;
514*9880d681SAndroid Build Coastguard Worker
515*9880d681SAndroid Build Coastguard Worker  let op = 0xd;     // BPF_END
516*9880d681SAndroid Build Coastguard Worker  let BPFSrc = 1;   // BPF_TO_BE (TODO: use BPF_TO_LE for big-endian target)
517*9880d681SAndroid Build Coastguard Worker  let BPFClass = 4; // BPF_ALU
518*9880d681SAndroid Build Coastguard Worker  let imm = SizeOp;
519*9880d681SAndroid Build Coastguard Worker}
520*9880d681SAndroid Build Coastguard Worker
521*9880d681SAndroid Build Coastguard Workerlet Constraints = "$dst = $src" in {
522*9880d681SAndroid Build Coastguard Workerdef BSWAP16 : BSWAP<16, "bswap16", [(set GPR:$dst, (srl (bswap GPR:$src), (i64 48)))]>;
523*9880d681SAndroid Build Coastguard Workerdef BSWAP32 : BSWAP<32, "bswap32", [(set GPR:$dst, (srl (bswap GPR:$src), (i64 32)))]>;
524*9880d681SAndroid Build Coastguard Workerdef BSWAP64 : BSWAP<64, "bswap64", [(set GPR:$dst, (bswap GPR:$src))]>;
525*9880d681SAndroid Build Coastguard Worker}
526*9880d681SAndroid Build Coastguard Worker
527*9880d681SAndroid Build Coastguard Workerlet Defs = [R0, R1, R2, R3, R4, R5], Uses = [R6], hasSideEffects = 1,
528*9880d681SAndroid Build Coastguard Worker    hasExtraDefRegAllocReq = 1, hasExtraSrcRegAllocReq = 1, mayLoad = 1 in {
529*9880d681SAndroid Build Coastguard Workerclass LOAD_ABS<bits<2> SizeOp, string OpcodeStr, Intrinsic OpNode>
530*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs), (ins GPR:$skb, i64imm:$imm),
531*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\tr0, $skb.data + $imm"),
532*9880d681SAndroid Build Coastguard Worker              [(set R0, (OpNode GPR:$skb, i64immSExt32:$imm))]> {
533*9880d681SAndroid Build Coastguard Worker  bits<3> mode;
534*9880d681SAndroid Build Coastguard Worker  bits<2> size;
535*9880d681SAndroid Build Coastguard Worker  bits<32> imm;
536*9880d681SAndroid Build Coastguard Worker
537*9880d681SAndroid Build Coastguard Worker  let Inst{63-61} = mode;
538*9880d681SAndroid Build Coastguard Worker  let Inst{60-59} = size;
539*9880d681SAndroid Build Coastguard Worker  let Inst{31-0} = imm;
540*9880d681SAndroid Build Coastguard Worker
541*9880d681SAndroid Build Coastguard Worker  let mode = 1;     // BPF_ABS
542*9880d681SAndroid Build Coastguard Worker  let size = SizeOp;
543*9880d681SAndroid Build Coastguard Worker  let BPFClass = 0; // BPF_LD
544*9880d681SAndroid Build Coastguard Worker}
545*9880d681SAndroid Build Coastguard Worker
546*9880d681SAndroid Build Coastguard Workerclass LOAD_IND<bits<2> SizeOp, string OpcodeStr, Intrinsic OpNode>
547*9880d681SAndroid Build Coastguard Worker    : InstBPF<(outs), (ins GPR:$skb, GPR:$val),
548*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\tr0, $skb.data + $val"),
549*9880d681SAndroid Build Coastguard Worker              [(set R0, (OpNode GPR:$skb, GPR:$val))]> {
550*9880d681SAndroid Build Coastguard Worker  bits<3> mode;
551*9880d681SAndroid Build Coastguard Worker  bits<2> size;
552*9880d681SAndroid Build Coastguard Worker  bits<4> val;
553*9880d681SAndroid Build Coastguard Worker
554*9880d681SAndroid Build Coastguard Worker  let Inst{63-61} = mode;
555*9880d681SAndroid Build Coastguard Worker  let Inst{60-59} = size;
556*9880d681SAndroid Build Coastguard Worker  let Inst{55-52} = val;
557*9880d681SAndroid Build Coastguard Worker
558*9880d681SAndroid Build Coastguard Worker  let mode = 2;     // BPF_IND
559*9880d681SAndroid Build Coastguard Worker  let size = SizeOp;
560*9880d681SAndroid Build Coastguard Worker  let BPFClass = 0; // BPF_LD
561*9880d681SAndroid Build Coastguard Worker}
562*9880d681SAndroid Build Coastguard Worker}
563*9880d681SAndroid Build Coastguard Worker
564*9880d681SAndroid Build Coastguard Workerdef LD_ABS_B : LOAD_ABS<2, "ldabs_b", int_bpf_load_byte>;
565*9880d681SAndroid Build Coastguard Workerdef LD_ABS_H : LOAD_ABS<1, "ldabs_h", int_bpf_load_half>;
566*9880d681SAndroid Build Coastguard Workerdef LD_ABS_W : LOAD_ABS<0, "ldabs_w", int_bpf_load_word>;
567*9880d681SAndroid Build Coastguard Worker
568*9880d681SAndroid Build Coastguard Workerdef LD_IND_B : LOAD_IND<2, "ldind_b", int_bpf_load_byte>;
569*9880d681SAndroid Build Coastguard Workerdef LD_IND_H : LOAD_IND<1, "ldind_h", int_bpf_load_half>;
570*9880d681SAndroid Build Coastguard Workerdef LD_IND_W : LOAD_IND<0, "ldind_w", int_bpf_load_word>;
571