xref: /linux/arch/parisc/net/bpf_jit.h (revision a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0)
1*22de5d62SHelge Deller /* SPDX-License-Identifier: GPL-2.0 */
2*22de5d62SHelge Deller /*
3*22de5d62SHelge Deller  * Common functionality for PARISC32 and PARISC64 BPF JIT compilers
4*22de5d62SHelge Deller  *
5*22de5d62SHelge Deller  * Copyright (c) 2023 Helge Deller <deller@gmx.de>
6*22de5d62SHelge Deller  *
7*22de5d62SHelge Deller  */
8*22de5d62SHelge Deller 
9*22de5d62SHelge Deller #ifndef _BPF_JIT_H
10*22de5d62SHelge Deller #define _BPF_JIT_H
11*22de5d62SHelge Deller 
12*22de5d62SHelge Deller #include <linux/bpf.h>
13*22de5d62SHelge Deller #include <linux/filter.h>
14*22de5d62SHelge Deller #include <asm/cacheflush.h>
15*22de5d62SHelge Deller 
16*22de5d62SHelge Deller #define HPPA_JIT_DEBUG	0
17*22de5d62SHelge Deller #define HPPA_JIT_REBOOT	0
18*22de5d62SHelge Deller #define HPPA_JIT_DUMP	0
19*22de5d62SHelge Deller 
20*22de5d62SHelge Deller #define OPTIMIZE_HPPA	1	/* enable some asm optimizations */
21*22de5d62SHelge Deller // echo 1 > /proc/sys/net/core/bpf_jit_enable
22*22de5d62SHelge Deller 
23*22de5d62SHelge Deller #define HPPA_R(nr)	nr	/* use HPPA register #nr */
24*22de5d62SHelge Deller 
25*22de5d62SHelge Deller enum {
26*22de5d62SHelge Deller 	HPPA_REG_ZERO =	0,	/* The constant value 0 */
27*22de5d62SHelge Deller 	HPPA_REG_R1 =	1,	/* used for addil */
28*22de5d62SHelge Deller 	HPPA_REG_RP =	2,	/* Return address */
29*22de5d62SHelge Deller 
30*22de5d62SHelge Deller 	HPPA_REG_ARG7 =	19,	/* ARG4-7 used in 64-bit ABI */
31*22de5d62SHelge Deller 	HPPA_REG_ARG6 =	20,
32*22de5d62SHelge Deller 	HPPA_REG_ARG5 =	21,
33*22de5d62SHelge Deller 	HPPA_REG_ARG4 =	22,
34*22de5d62SHelge Deller 
35*22de5d62SHelge Deller 	HPPA_REG_ARG3 =	23,	/* ARG0-3 in 32- and 64-bit ABI */
36*22de5d62SHelge Deller 	HPPA_REG_ARG2 =	24,
37*22de5d62SHelge Deller 	HPPA_REG_ARG1 =	25,
38*22de5d62SHelge Deller 	HPPA_REG_ARG0 =	26,
39*22de5d62SHelge Deller 	HPPA_REG_GP =	27,	/* Global pointer */
40*22de5d62SHelge Deller 	HPPA_REG_RET0 =	28,	/* Return value, HI in 32-bit */
41*22de5d62SHelge Deller 	HPPA_REG_RET1 =	29,	/* Return value, LOW in 32-bit */
42*22de5d62SHelge Deller 	HPPA_REG_SP =	30,	/* Stack pointer */
43*22de5d62SHelge Deller 	HPPA_REG_R31 =	31,
44*22de5d62SHelge Deller 
45*22de5d62SHelge Deller #ifdef CONFIG_64BIT
46*22de5d62SHelge Deller 	HPPA_REG_TCC	     = 3,
47*22de5d62SHelge Deller 	HPPA_REG_TCC_SAVED   = 4,
48*22de5d62SHelge Deller 	HPPA_REG_TCC_IN_INIT = HPPA_REG_R31,
49*22de5d62SHelge Deller #else
50*22de5d62SHelge Deller 	HPPA_REG_TCC	     = 18,
51*22de5d62SHelge Deller 	HPPA_REG_TCC_SAVED   = 17,
52*22de5d62SHelge Deller 	HPPA_REG_TCC_IN_INIT = HPPA_REG_R31,
53*22de5d62SHelge Deller #endif
54*22de5d62SHelge Deller 
55*22de5d62SHelge Deller 	HPPA_REG_T0 =	HPPA_REG_R1,	/* Temporaries */
56*22de5d62SHelge Deller 	HPPA_REG_T1 =	HPPA_REG_R31,
57*22de5d62SHelge Deller 	HPPA_REG_T2 =	HPPA_REG_ARG4,
58*22de5d62SHelge Deller #ifndef CONFIG_64BIT
59*22de5d62SHelge Deller 	HPPA_REG_T3 =	HPPA_REG_ARG5,	/* not used in 64-bit */
60*22de5d62SHelge Deller 	HPPA_REG_T4 =	HPPA_REG_ARG6,
61*22de5d62SHelge Deller 	HPPA_REG_T5 =	HPPA_REG_ARG7,
62*22de5d62SHelge Deller #endif
63*22de5d62SHelge Deller };
64*22de5d62SHelge Deller 
65*22de5d62SHelge Deller struct hppa_jit_context {
66*22de5d62SHelge Deller 	struct bpf_prog *prog;
67*22de5d62SHelge Deller 	u32 *insns;		/* HPPA insns */
68*22de5d62SHelge Deller 	int ninsns;
69*22de5d62SHelge Deller 	int reg_seen_collect;
70*22de5d62SHelge Deller 	int reg_seen;
71*22de5d62SHelge Deller 	int body_len;
72*22de5d62SHelge Deller 	int epilogue_offset;
73*22de5d62SHelge Deller 	int prologue_len;
74*22de5d62SHelge Deller 	int *offset;		/* BPF to HPPA */
75*22de5d62SHelge Deller };
76*22de5d62SHelge Deller 
77*22de5d62SHelge Deller #define REG_SET_SEEN(ctx, nr)	{ if (ctx->reg_seen_collect) ctx->reg_seen |= BIT(nr); }
78*22de5d62SHelge Deller #define REG_SET_SEEN_ALL(ctx)	{ if (ctx->reg_seen_collect) ctx->reg_seen = -1; }
79*22de5d62SHelge Deller #define REG_FORCE_SEEN(ctx, nr)	{ ctx->reg_seen |= BIT(nr); }
80*22de5d62SHelge Deller #define REG_WAS_SEEN(ctx, nr)	(ctx->reg_seen & BIT(nr))
81*22de5d62SHelge Deller #define REG_ALL_SEEN(ctx)	(ctx->reg_seen == -1)
82*22de5d62SHelge Deller 
83*22de5d62SHelge Deller #define HPPA_INSN_SIZE		4	/* bytes per HPPA asm instruction */
84*22de5d62SHelge Deller #define REG_SIZE		REG_SZ	/* bytes per native "long" word */
85*22de5d62SHelge Deller 
86*22de5d62SHelge Deller /* subtract hppa displacement on branches which is .+8 */
87*22de5d62SHelge Deller #define HPPA_BRANCH_DISPLACEMENT  2	/* instructions */
88*22de5d62SHelge Deller 
89*22de5d62SHelge Deller /* asm statement indicator to execute delay slot */
90*22de5d62SHelge Deller #define EXEC_NEXT_INSTR	0
91*22de5d62SHelge Deller #define NOP_NEXT_INSTR	1
92*22de5d62SHelge Deller 
93*22de5d62SHelge Deller #define im11(val)	(((u32)(val)) & 0x07ff)
94*22de5d62SHelge Deller 
95*22de5d62SHelge Deller #define hppa_ldil(addr, reg) \
96*22de5d62SHelge Deller 	hppa_t5_insn(0x08, reg, ((u32)(addr)) >> 11)		/* ldil im21,reg */
97*22de5d62SHelge Deller #define hppa_addil(addr, reg) \
98*22de5d62SHelge Deller 	hppa_t5_insn(0x0a, reg, ((u32)(addr)) >> 11)		/* addil im21,reg -> result in gr1 */
99*22de5d62SHelge Deller #define hppa_ldo(im14, reg, target) \
100*22de5d62SHelge Deller 	hppa_t1_insn(0x0d, reg, target, im14)			/* ldo val14(reg),target */
101*22de5d62SHelge Deller #define hppa_ldi(im14, reg) \
102*22de5d62SHelge Deller 	hppa_ldo(im14, HPPA_REG_ZERO, reg)			/* ldi val14,reg */
103*22de5d62SHelge Deller #define hppa_or(reg1, reg2, target) \
104*22de5d62SHelge Deller 	hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x09, target)	/* or reg1,reg2,target */
105*22de5d62SHelge Deller #define hppa_or_cond(reg1, reg2, cond, f, target) \
106*22de5d62SHelge Deller 	hppa_t6_insn(0x02, reg2, reg1, cond, f, 0x09, target)
107*22de5d62SHelge Deller #define hppa_and(reg1, reg2, target) \
108*22de5d62SHelge Deller 	hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x08, target)	/* and reg1,reg2,target */
109*22de5d62SHelge Deller #define hppa_and_cond(reg1, reg2, cond, f, target) \
110*22de5d62SHelge Deller 	hppa_t6_insn(0x02, reg2, reg1, cond, f, 0x08, target)
111*22de5d62SHelge Deller #define hppa_xor(reg1, reg2, target) \
112*22de5d62SHelge Deller 	hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x0a, target)	/* xor reg1,reg2,target */
113*22de5d62SHelge Deller #define hppa_add(reg1, reg2, target) \
114*22de5d62SHelge Deller 	hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x18, target)	/* add reg1,reg2,target */
115*22de5d62SHelge Deller #define hppa_addc(reg1, reg2, target) \
116*22de5d62SHelge Deller 	hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x1c, target)	/* add,c reg1,reg2,target */
117*22de5d62SHelge Deller #define hppa_sub(reg1, reg2, target) \
118*22de5d62SHelge Deller 	hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x10, target)	/* sub reg1,reg2,target */
119*22de5d62SHelge Deller #define hppa_subb(reg1, reg2, target) \
120*22de5d62SHelge Deller 	hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x14, target)	/* sub,b reg1,reg2,target */
121*22de5d62SHelge Deller #define hppa_nop() \
122*22de5d62SHelge Deller 	hppa_or(0,0,0)						/* nop: or 0,0,0 */
123*22de5d62SHelge Deller #define hppa_addi(val11, reg, target) \
124*22de5d62SHelge Deller 	hppa_t7_insn(0x2d, reg, target, val11)			/* addi im11,reg,target */
125*22de5d62SHelge Deller #define hppa_subi(val11, reg, target) \
126*22de5d62SHelge Deller 	hppa_t7_insn(0x25, reg, target, val11)			/* subi im11,reg,target */
127*22de5d62SHelge Deller #define hppa_copy(reg, target) \
128*22de5d62SHelge Deller 	hppa_or(reg, HPPA_REG_ZERO, target)			/* copy reg,target */
129*22de5d62SHelge Deller #define hppa_ldw(val14, reg, target) \
130*22de5d62SHelge Deller 	hppa_t1_insn(0x12, reg, target, val14)			/* ldw im14(reg),target */
131*22de5d62SHelge Deller #define hppa_ldb(val14, reg, target) \
132*22de5d62SHelge Deller 	hppa_t1_insn(0x10, reg, target, val14)			/* ldb im14(reg),target */
133*22de5d62SHelge Deller #define hppa_ldh(val14, reg, target) \
134*22de5d62SHelge Deller 	hppa_t1_insn(0x11, reg, target, val14)			/* ldh im14(reg),target */
135*22de5d62SHelge Deller #define hppa_stw(reg, val14, base) \
136*22de5d62SHelge Deller 	hppa_t1_insn(0x1a, base, reg, val14)			/* stw reg,im14(base) */
137*22de5d62SHelge Deller #define hppa_stb(reg, val14, base) \
138*22de5d62SHelge Deller 	hppa_t1_insn(0x18, base, reg, val14)			/* stb reg,im14(base) */
139*22de5d62SHelge Deller #define hppa_sth(reg, val14, base) \
140*22de5d62SHelge Deller 	hppa_t1_insn(0x19, base, reg, val14)			/* sth reg,im14(base) */
141*22de5d62SHelge Deller #define hppa_stwma(reg, val14, base) \
142*22de5d62SHelge Deller 	hppa_t1_insn(0x1b, base, reg, val14)			/* stw,ma reg,im14(base) */
143*22de5d62SHelge Deller #define hppa_bv(reg, base, nop) \
144*22de5d62SHelge Deller 	hppa_t11_insn(0x3a, base, reg, 0x06, 0, nop)		/* bv(,n) reg(base) */
145*22de5d62SHelge Deller #define hppa_be(offset, base) \
146*22de5d62SHelge Deller 	hppa_t12_insn(0x38, base, offset, 0x00, 1)		/* be,n offset(0,base) */
147*22de5d62SHelge Deller #define hppa_be_l(offset, base, nop) \
148*22de5d62SHelge Deller 	hppa_t12_insn(0x39, base, offset, 0x00, nop)		/* ble(,nop) offset(0,base) */
149*22de5d62SHelge Deller #define hppa_mtctl(reg, cr) \
150*22de5d62SHelge Deller 	hppa_t21_insn(0x00, cr, reg, 0xc2, 0)			/* mtctl reg,cr */
151*22de5d62SHelge Deller #define hppa_mtsar(reg) \
152*22de5d62SHelge Deller 	hppa_mtctl(reg, 11)					/* mtsar reg */
153*22de5d62SHelge Deller #define hppa_zdep(r, p, len, target) \
154*22de5d62SHelge Deller 	hppa_t10_insn(0x35, target, r, 0, 2, p, len)		/* zdep r,a,b,t */
155*22de5d62SHelge Deller #define hppa_shl(r, len, target) \
156*22de5d62SHelge Deller 	hppa_zdep(r, len, len, lo(rd))
157*22de5d62SHelge Deller #define hppa_depwz(r, p, len, target) \
158*22de5d62SHelge Deller 	hppa_t10_insn(0x35, target, r, 0, 3, 31-(p), 32-(len))	/* depw,z r,p,len,ret1 */
159*22de5d62SHelge Deller #define hppa_depwz_sar(reg, target) \
160*22de5d62SHelge Deller 	hppa_t1_insn(0x35, target, reg, 0)			/* depw,z reg,sar,32,target */
161*22de5d62SHelge Deller #define hppa_shrpw_sar(reg, target) \
162*22de5d62SHelge Deller 	hppa_t10_insn(0x34, reg, 0, 0, 0, 0, target)		/* shrpw r0,reg,sar,target */
163*22de5d62SHelge Deller #define hppa_shrpw(r1, r2, p, target) \
164*22de5d62SHelge Deller 	hppa_t10_insn(0x34, r2, r1, 0, 2, 31-(p), target)	/* shrpw r1,r2,p,target */
165*22de5d62SHelge Deller #define hppa_shd(r1, r2, p, target) \
166*22de5d62SHelge Deller 	hppa_t10_insn(0x34, r2, r1, 0, 2, 31-(p), target)	/* shrpw r1,r2,p,tarfer */
167*22de5d62SHelge Deller #define hppa_extrws_sar(reg, target) \
168*22de5d62SHelge Deller 	hppa_t10_insn(0x34, reg, target, 0, 5, 0, 0)		/* extrw,s reg,sar,32,ret0 */
169*22de5d62SHelge Deller #define hppa_extrws(reg, p, len, target) \
170*22de5d62SHelge Deller 	hppa_t10_insn(0x34, reg, target, 0, 7, p, len)		/* extrw,s reg,p,len,target */
171*22de5d62SHelge Deller #define hppa_extru(r, p, len, target) \
172*22de5d62SHelge Deller 	hppa_t10_insn(0x34, r, target, 0, 6, p, 32-(len))
173*22de5d62SHelge Deller #define hppa_shr(r, len, target) \
174*22de5d62SHelge Deller 	hppa_extru(r, 31-(len), 32-(len), target)
175*22de5d62SHelge Deller #define hppa_bl(imm17, rp) \
176*22de5d62SHelge Deller 	hppa_t12_insn(0x3a, rp, imm17, 0x00, 1)			/* bl,n target_addr,rp */
177*22de5d62SHelge Deller #define hppa_sh2add(r1, r2, target) \
178*22de5d62SHelge Deller 	hppa_t6_insn(0x02, r2, r1, 0, 0, 0x1a, target)		/* sh2add r1,r2,target */
179*22de5d62SHelge Deller 
180*22de5d62SHelge Deller #define hppa_combt(r1, r2, target_addr, condition, nop) \
181*22de5d62SHelge Deller 	hppa_t11_insn(IS_ENABLED(CONFIG_64BIT) ? 0x27 : 0x20, \
182*22de5d62SHelge Deller 		r2, r1, condition, target_addr, nop)		/* combt,cond,n r1,r2,addr */
183*22de5d62SHelge Deller #define hppa_beq(r1, r2, target_addr) \
184*22de5d62SHelge Deller 	hppa_combt(r1, r2, target_addr, 1, NOP_NEXT_INSTR)
185*22de5d62SHelge Deller #define hppa_blt(r1, r2, target_addr) \
186*22de5d62SHelge Deller 	hppa_combt(r1, r2, target_addr, 2, NOP_NEXT_INSTR)
187*22de5d62SHelge Deller #define hppa_ble(r1, r2, target_addr) \
188*22de5d62SHelge Deller 	hppa_combt(r1, r2, target_addr, 3, NOP_NEXT_INSTR)
189*22de5d62SHelge Deller #define hppa_bltu(r1, r2, target_addr) \
190*22de5d62SHelge Deller 	hppa_combt(r1, r2, target_addr, 4, NOP_NEXT_INSTR)
191*22de5d62SHelge Deller #define hppa_bleu(r1, r2, target_addr) \
192*22de5d62SHelge Deller 	hppa_combt(r1, r2, target_addr, 5, NOP_NEXT_INSTR)
193*22de5d62SHelge Deller 
194*22de5d62SHelge Deller #define hppa_combf(r1, r2, target_addr, condition, nop) \
195*22de5d62SHelge Deller 	hppa_t11_insn(IS_ENABLED(CONFIG_64BIT) ? 0x2f : 0x22, \
196*22de5d62SHelge Deller 		r2, r1, condition, target_addr, nop)		/* combf,cond,n r1,r2,addr */
197*22de5d62SHelge Deller #define hppa_bne(r1, r2, target_addr) \
198*22de5d62SHelge Deller 	hppa_combf(r1, r2, target_addr, 1, NOP_NEXT_INSTR)
199*22de5d62SHelge Deller #define hppa_bge(r1, r2, target_addr) \
200*22de5d62SHelge Deller 	hppa_combf(r1, r2, target_addr, 2, NOP_NEXT_INSTR)
201*22de5d62SHelge Deller #define hppa_bgt(r1, r2, target_addr) \
202*22de5d62SHelge Deller 	hppa_combf(r1, r2, target_addr, 3, NOP_NEXT_INSTR)
203*22de5d62SHelge Deller #define hppa_bgeu(r1, r2, target_addr) \
204*22de5d62SHelge Deller 	hppa_combf(r1, r2, target_addr, 4, NOP_NEXT_INSTR)
205*22de5d62SHelge Deller #define hppa_bgtu(r1, r2, target_addr) \
206*22de5d62SHelge Deller 	hppa_combf(r1, r2, target_addr, 5, NOP_NEXT_INSTR)
207*22de5d62SHelge Deller 
208*22de5d62SHelge Deller /* 64-bit instructions */
209*22de5d62SHelge Deller #ifdef CONFIG_64BIT
210*22de5d62SHelge Deller #define hppa64_ldd_reg(reg, b, target) \
211*22de5d62SHelge Deller 	hppa_t10_insn(0x03, b, reg, 0, 0, 3<<1, target)
212*22de5d62SHelge Deller #define hppa64_ldd_im5(im5, b, target) \
213*22de5d62SHelge Deller 	hppa_t10_insn(0x03, b, low_sign_unext(im5,5), 0, 1<<2, 3<<1, target)
214*22de5d62SHelge Deller #define hppa64_ldd_im16(im16, b, target) \
215*22de5d62SHelge Deller 	hppa_t10_insn(0x14, b, target, 0, 0, 0, 0) | re_assemble_16(im16)
216*22de5d62SHelge Deller #define hppa64_std_im5(src, im5, b) \
217*22de5d62SHelge Deller 	hppa_t10_insn(0x03, b, src, 0, 1<<2, 0xB<<1, low_sign_unext(im5,5))
218*22de5d62SHelge Deller #define hppa64_std_im16(src, im16, b) \
219*22de5d62SHelge Deller 	hppa_t10_insn(0x1c, b, src, 0, 0, 0, 0) | re_assemble_16(im16)
220*22de5d62SHelge Deller #define hppa64_bl_long(offs22) \
221*22de5d62SHelge Deller 	hppa_t12_L_insn(0x3a, offs22, 1)
222*22de5d62SHelge Deller #define hppa64_mtsarcm(reg) \
223*22de5d62SHelge Deller 	hppa_t21_insn(0x00, 11, reg, 0xc6, 0)
224*22de5d62SHelge Deller #define hppa64_shrpd_sar(reg, target) \
225*22de5d62SHelge Deller 	hppa_t10_insn(0x34, reg, 0, 0, 0, 1<<4, target)
226*22de5d62SHelge Deller #define hppa64_shladd(r1, sa, r2, target) \
227*22de5d62SHelge Deller 	hppa_t6_insn(0x02, r2, r1, 0, 0, 1<<4|1<<3|sa, target)
228*22de5d62SHelge Deller #define hppa64_depdz_sar(reg, target) \
229*22de5d62SHelge Deller 	hppa_t21_insn(0x35, target, reg, 3<<3, 0)
230*22de5d62SHelge Deller #define hppa_extrd_sar(reg, target, se) \
231*22de5d62SHelge Deller 	hppa_t10_insn(0x34, reg, target, 0, 0, 0, 0) | 2<<11 | (se&1)<<10 | 1<<9 | 1<<8
232*22de5d62SHelge Deller #define hppa64_bve_l_rp(base) \
233*22de5d62SHelge Deller 	(0x3a << 26) | (base << 21) | 0xf000
234*22de5d62SHelge Deller #define hppa64_permh_3210(r, target) \
235*22de5d62SHelge Deller 	(0x3e << 26) | (r << 21) | (r << 16) | (target) | 0x00006900
236*22de5d62SHelge Deller #define hppa64_hshl(r, sa, target) \
237*22de5d62SHelge Deller 	(0x3e << 26) | (0 << 21) | (r << 16) | (sa << 6) | (target) | 0x00008800
238*22de5d62SHelge Deller #define hppa64_hshr_u(r, sa, target) \
239*22de5d62SHelge Deller 	(0x3e << 26) | (r << 21) | (0 << 16) | (sa << 6) | (target) | 0x0000c800
240*22de5d62SHelge Deller #endif
241*22de5d62SHelge Deller 
242*22de5d62SHelge Deller struct hppa_jit_data {
243*22de5d62SHelge Deller 	struct bpf_binary_header *header;
244*22de5d62SHelge Deller 	u8 *image;
245*22de5d62SHelge Deller 	struct hppa_jit_context ctx;
246*22de5d62SHelge Deller };
247*22de5d62SHelge Deller 
bpf_fill_ill_insns(void * area,unsigned int size)248*22de5d62SHelge Deller static inline void bpf_fill_ill_insns(void *area, unsigned int size)
249*22de5d62SHelge Deller {
250*22de5d62SHelge Deller 	memset(area, 0, size);
251*22de5d62SHelge Deller }
252*22de5d62SHelge Deller 
bpf_flush_icache(void * start,void * end)253*22de5d62SHelge Deller static inline void bpf_flush_icache(void *start, void *end)
254*22de5d62SHelge Deller {
255*22de5d62SHelge Deller 	flush_icache_range((unsigned long)start, (unsigned long)end);
256*22de5d62SHelge Deller }
257*22de5d62SHelge Deller 
258*22de5d62SHelge Deller /* Emit a 4-byte HPPA instruction. */
emit(const u32 insn,struct hppa_jit_context * ctx)259*22de5d62SHelge Deller static inline void emit(const u32 insn, struct hppa_jit_context *ctx)
260*22de5d62SHelge Deller {
261*22de5d62SHelge Deller 	if (ctx->insns) {
262*22de5d62SHelge Deller 		ctx->insns[ctx->ninsns] = insn;
263*22de5d62SHelge Deller 	}
264*22de5d62SHelge Deller 
265*22de5d62SHelge Deller 	ctx->ninsns++;
266*22de5d62SHelge Deller }
267*22de5d62SHelge Deller 
epilogue_offset(struct hppa_jit_context * ctx)268*22de5d62SHelge Deller static inline int epilogue_offset(struct hppa_jit_context *ctx)
269*22de5d62SHelge Deller {
270*22de5d62SHelge Deller 	int to = ctx->epilogue_offset, from = ctx->ninsns;
271*22de5d62SHelge Deller 
272*22de5d62SHelge Deller 	return (to - from);
273*22de5d62SHelge Deller }
274*22de5d62SHelge Deller 
275*22de5d62SHelge Deller /* Return -1 or inverted cond. */
invert_bpf_cond(u8 cond)276*22de5d62SHelge Deller static inline int invert_bpf_cond(u8 cond)
277*22de5d62SHelge Deller {
278*22de5d62SHelge Deller 	switch (cond) {
279*22de5d62SHelge Deller 	case BPF_JEQ:
280*22de5d62SHelge Deller 		return BPF_JNE;
281*22de5d62SHelge Deller 	case BPF_JGT:
282*22de5d62SHelge Deller 		return BPF_JLE;
283*22de5d62SHelge Deller 	case BPF_JLT:
284*22de5d62SHelge Deller 		return BPF_JGE;
285*22de5d62SHelge Deller 	case BPF_JGE:
286*22de5d62SHelge Deller 		return BPF_JLT;
287*22de5d62SHelge Deller 	case BPF_JLE:
288*22de5d62SHelge Deller 		return BPF_JGT;
289*22de5d62SHelge Deller 	case BPF_JNE:
290*22de5d62SHelge Deller 		return BPF_JEQ;
291*22de5d62SHelge Deller 	case BPF_JSGT:
292*22de5d62SHelge Deller 		return BPF_JSLE;
293*22de5d62SHelge Deller 	case BPF_JSLT:
294*22de5d62SHelge Deller 		return BPF_JSGE;
295*22de5d62SHelge Deller 	case BPF_JSGE:
296*22de5d62SHelge Deller 		return BPF_JSLT;
297*22de5d62SHelge Deller 	case BPF_JSLE:
298*22de5d62SHelge Deller 		return BPF_JSGT;
299*22de5d62SHelge Deller 	}
300*22de5d62SHelge Deller 	return -1;
301*22de5d62SHelge Deller }
302*22de5d62SHelge Deller 
303*22de5d62SHelge Deller 
hppa_offset(int insn,int off,struct hppa_jit_context * ctx)304*22de5d62SHelge Deller static inline signed long hppa_offset(int insn, int off, struct hppa_jit_context *ctx)
305*22de5d62SHelge Deller {
306*22de5d62SHelge Deller 	signed long from, to;
307*22de5d62SHelge Deller 
308*22de5d62SHelge Deller 	off++; /* BPF branch is from PC+1 */
309*22de5d62SHelge Deller 	from = (insn > 0) ? ctx->offset[insn - 1] : 0;
310*22de5d62SHelge Deller 	to = (insn + off > 0) ? ctx->offset[insn + off - 1] : 0;
311*22de5d62SHelge Deller 	return (to - from);
312*22de5d62SHelge Deller }
313*22de5d62SHelge Deller 
314*22de5d62SHelge Deller /* does the signed value fits into a given number of bits ? */
check_bits_int(signed long val,int bits)315*22de5d62SHelge Deller static inline int check_bits_int(signed long val, int bits)
316*22de5d62SHelge Deller {
317*22de5d62SHelge Deller 	return	((val >= 0) && ((val >> bits) == 0)) ||
318*22de5d62SHelge Deller 		 ((val < 0) && (((~((u32)val)) >> (bits-1)) == 0));
319*22de5d62SHelge Deller }
320*22de5d62SHelge Deller 
321*22de5d62SHelge Deller /* can the signed value be used in relative code ? */
relative_bits_ok(signed long val,int bits)322*22de5d62SHelge Deller static inline int relative_bits_ok(signed long val, int bits)
323*22de5d62SHelge Deller {
324*22de5d62SHelge Deller 	return	((val >= 0) && (val < (1UL << (bits-1)))) || /* XXX */
325*22de5d62SHelge Deller 		 ((val < 0) && (((~((unsigned long)val)) >> (bits-1)) == 0)
326*22de5d62SHelge Deller 			    && (val & (1UL << (bits-1))));
327*22de5d62SHelge Deller }
328*22de5d62SHelge Deller 
329*22de5d62SHelge Deller /* can the signed value be used in relative branches ? */
relative_branch_ok(signed long val,int bits)330*22de5d62SHelge Deller static inline int relative_branch_ok(signed long val, int bits)
331*22de5d62SHelge Deller {
332*22de5d62SHelge Deller 	return	((val >= 0) && (val < (1UL << (bits-2)))) || /* XXX */
333*22de5d62SHelge Deller 		 ((val < 0) && (((~((unsigned long)val)) < (1UL << (bits-2))))
334*22de5d62SHelge Deller 			    && (val & (1UL << (bits-1))));
335*22de5d62SHelge Deller }
336*22de5d62SHelge Deller 
337*22de5d62SHelge Deller 
338*22de5d62SHelge Deller #define is_5b_int(val)		check_bits_int(val, 5)
339*22de5d62SHelge Deller 
sign_unext(unsigned x,unsigned len)340*22de5d62SHelge Deller static inline unsigned sign_unext(unsigned x, unsigned len)
341*22de5d62SHelge Deller {
342*22de5d62SHelge Deller 	unsigned len_ones;
343*22de5d62SHelge Deller 
344*22de5d62SHelge Deller 	len_ones = (1 << len) - 1;
345*22de5d62SHelge Deller 	return x & len_ones;
346*22de5d62SHelge Deller }
347*22de5d62SHelge Deller 
low_sign_unext(unsigned x,unsigned len)348*22de5d62SHelge Deller static inline unsigned low_sign_unext(unsigned x, unsigned len)
349*22de5d62SHelge Deller {
350*22de5d62SHelge Deller 	unsigned temp;
351*22de5d62SHelge Deller 	unsigned sign;
352*22de5d62SHelge Deller 
353*22de5d62SHelge Deller 	sign = (x >> (len-1)) & 1;
354*22de5d62SHelge Deller 	temp = sign_unext (x, len-1);
355*22de5d62SHelge Deller 	return (temp << 1) | sign;
356*22de5d62SHelge Deller }
357*22de5d62SHelge Deller 
re_assemble_12(unsigned as12)358*22de5d62SHelge Deller static inline unsigned re_assemble_12(unsigned as12)
359*22de5d62SHelge Deller {
360*22de5d62SHelge Deller 	return ((  (as12 & 0x800) >> 11)
361*22de5d62SHelge Deller 		| ((as12 & 0x400) >> (10 - 2))
362*22de5d62SHelge Deller 		| ((as12 & 0x3ff) << (1 + 2)));
363*22de5d62SHelge Deller }
364*22de5d62SHelge Deller 
re_assemble_14(unsigned as14)365*22de5d62SHelge Deller static inline unsigned re_assemble_14(unsigned as14)
366*22de5d62SHelge Deller {
367*22de5d62SHelge Deller 	return ((  (as14 & 0x1fff) << 1)
368*22de5d62SHelge Deller 		| ((as14 & 0x2000) >> 13));
369*22de5d62SHelge Deller }
370*22de5d62SHelge Deller 
371*22de5d62SHelge Deller #ifdef CONFIG_64BIT
re_assemble_16(unsigned as16)372*22de5d62SHelge Deller static inline unsigned re_assemble_16(unsigned as16)
373*22de5d62SHelge Deller {
374*22de5d62SHelge Deller 	unsigned s, t;
375*22de5d62SHelge Deller 
376*22de5d62SHelge Deller 	/* Unusual 16-bit encoding, for wide mode only.  */
377*22de5d62SHelge Deller 	t = (as16 << 1) & 0xffff;
378*22de5d62SHelge Deller 	s = (as16 & 0x8000);
379*22de5d62SHelge Deller 	return (t ^ s ^ (s >> 1)) | (s >> 15);
380*22de5d62SHelge Deller }
381*22de5d62SHelge Deller #endif
382*22de5d62SHelge Deller 
re_assemble_17(unsigned as17)383*22de5d62SHelge Deller static inline unsigned re_assemble_17(unsigned as17)
384*22de5d62SHelge Deller {
385*22de5d62SHelge Deller 	return ((  (as17 & 0x10000) >> 16)
386*22de5d62SHelge Deller 		| ((as17 & 0x0f800) << (16 - 11))
387*22de5d62SHelge Deller 		| ((as17 & 0x00400) >> (10 - 2))
388*22de5d62SHelge Deller 		| ((as17 & 0x003ff) << (1 + 2)));
389*22de5d62SHelge Deller }
390*22de5d62SHelge Deller 
re_assemble_21(unsigned as21)391*22de5d62SHelge Deller static inline unsigned re_assemble_21(unsigned as21)
392*22de5d62SHelge Deller {
393*22de5d62SHelge Deller 	return ((  (as21 & 0x100000) >> 20)
394*22de5d62SHelge Deller 		| ((as21 & 0x0ffe00) >> 8)
395*22de5d62SHelge Deller 		| ((as21 & 0x000180) << 7)
396*22de5d62SHelge Deller 		| ((as21 & 0x00007c) << 14)
397*22de5d62SHelge Deller 		| ((as21 & 0x000003) << 12));
398*22de5d62SHelge Deller }
399*22de5d62SHelge Deller 
re_assemble_22(unsigned as22)400*22de5d62SHelge Deller static inline unsigned re_assemble_22(unsigned as22)
401*22de5d62SHelge Deller {
402*22de5d62SHelge Deller 	return ((  (as22 & 0x200000) >> 21)
403*22de5d62SHelge Deller 		| ((as22 & 0x1f0000) << (21 - 16))
404*22de5d62SHelge Deller 		| ((as22 & 0x00f800) << (16 - 11))
405*22de5d62SHelge Deller 		| ((as22 & 0x000400) >> (10 - 2))
406*22de5d62SHelge Deller 		| ((as22 & 0x0003ff) << (1 + 2)));
407*22de5d62SHelge Deller }
408*22de5d62SHelge Deller 
409*22de5d62SHelge Deller /* Various HPPA instruction formats. */
410*22de5d62SHelge Deller /* see https://parisc.wiki.kernel.org/images-parisc/6/68/Pa11_acd.pdf, appendix C */
411*22de5d62SHelge Deller 
hppa_t1_insn(u8 opcode,u8 b,u8 r,s16 im14)412*22de5d62SHelge Deller static inline u32 hppa_t1_insn(u8 opcode, u8 b, u8 r, s16 im14)
413*22de5d62SHelge Deller {
414*22de5d62SHelge Deller 	return ((opcode << 26) | (b << 21) | (r << 16) | re_assemble_14(im14));
415*22de5d62SHelge Deller }
416*22de5d62SHelge Deller 
hppa_t5_insn(u8 opcode,u8 tr,u32 val21)417*22de5d62SHelge Deller static inline u32 hppa_t5_insn(u8 opcode, u8 tr, u32 val21)
418*22de5d62SHelge Deller {
419*22de5d62SHelge Deller 	return ((opcode << 26) | (tr << 21) | re_assemble_21(val21));
420*22de5d62SHelge Deller }
421*22de5d62SHelge Deller 
hppa_t6_insn(u8 opcode,u8 r2,u8 r1,u8 c,u8 f,u8 ext6,u16 t)422*22de5d62SHelge Deller static inline u32 hppa_t6_insn(u8 opcode, u8 r2, u8 r1, u8 c, u8 f, u8 ext6, u16 t)
423*22de5d62SHelge Deller {
424*22de5d62SHelge Deller 	return ((opcode << 26) | (r2 << 21) | (r1 << 16) | (c << 13) | (f << 12) |
425*22de5d62SHelge Deller 		(ext6 << 6) | t);
426*22de5d62SHelge Deller }
427*22de5d62SHelge Deller 
428*22de5d62SHelge Deller /* 7. Arithmetic immediate */
hppa_t7_insn(u8 opcode,u8 r,u8 t,u32 im11)429*22de5d62SHelge Deller static inline u32 hppa_t7_insn(u8 opcode, u8 r, u8 t, u32 im11)
430*22de5d62SHelge Deller {
431*22de5d62SHelge Deller 	return ((opcode << 26) | (r << 21) | (t << 16) | low_sign_unext(im11, 11));
432*22de5d62SHelge Deller }
433*22de5d62SHelge Deller 
434*22de5d62SHelge Deller /* 10. Shift instructions */
hppa_t10_insn(u8 opcode,u8 r2,u8 r1,u8 c,u8 ext3,u8 cp,u8 t)435*22de5d62SHelge Deller static inline u32 hppa_t10_insn(u8 opcode, u8 r2, u8 r1, u8 c, u8 ext3, u8 cp, u8 t)
436*22de5d62SHelge Deller {
437*22de5d62SHelge Deller 	return ((opcode << 26) | (r2 << 21) | (r1 << 16) | (c << 13) |
438*22de5d62SHelge Deller 		(ext3 << 10) | (cp << 5) | t);
439*22de5d62SHelge Deller }
440*22de5d62SHelge Deller 
441*22de5d62SHelge Deller /* 11. Conditional branch instructions */
hppa_t11_insn(u8 opcode,u8 r2,u8 r1,u8 c,u32 w,u8 nop)442*22de5d62SHelge Deller static inline u32 hppa_t11_insn(u8 opcode, u8 r2, u8 r1, u8 c, u32 w, u8 nop)
443*22de5d62SHelge Deller {
444*22de5d62SHelge Deller 	u32 ra = re_assemble_12(w);
445*22de5d62SHelge Deller 	// ra = low_sign_unext(w,11) | (w & (1<<10)
446*22de5d62SHelge Deller 	return ((opcode << 26) | (r2 << 21) | (r1 << 16) | (c << 13) | (nop << 1) | ra);
447*22de5d62SHelge Deller }
448*22de5d62SHelge Deller 
449*22de5d62SHelge Deller /* 12. Branch instructions */
hppa_t12_insn(u8 opcode,u8 rp,u32 w,u8 ext3,u8 nop)450*22de5d62SHelge Deller static inline u32 hppa_t12_insn(u8 opcode, u8 rp, u32 w, u8 ext3, u8 nop)
451*22de5d62SHelge Deller {
452*22de5d62SHelge Deller 	return ((opcode << 26) | (rp << 21) | (ext3 << 13) | (nop << 1) | re_assemble_17(w));
453*22de5d62SHelge Deller }
454*22de5d62SHelge Deller 
hppa_t12_L_insn(u8 opcode,u32 w,u8 nop)455*22de5d62SHelge Deller static inline u32 hppa_t12_L_insn(u8 opcode, u32 w, u8 nop)
456*22de5d62SHelge Deller {
457*22de5d62SHelge Deller 	return ((opcode << 26) | (0x05 << 13) | (nop << 1) | re_assemble_22(w));
458*22de5d62SHelge Deller }
459*22de5d62SHelge Deller 
460*22de5d62SHelge Deller /* 21. Move to control register */
hppa_t21_insn(u8 opcode,u8 r2,u8 r1,u8 ext8,u8 t)461*22de5d62SHelge Deller static inline u32 hppa_t21_insn(u8 opcode, u8 r2, u8 r1, u8 ext8, u8 t)
462*22de5d62SHelge Deller {
463*22de5d62SHelge Deller 	return ((opcode << 26) | (r2 << 21) | (r1 << 16) | (ext8 << 5) | t);
464*22de5d62SHelge Deller }
465*22de5d62SHelge Deller 
466*22de5d62SHelge Deller /* Helper functions called by jit code on HPPA32 and HPPA64. */
467*22de5d62SHelge Deller 
468*22de5d62SHelge Deller u64 hppa_div64(u64 div, u64 divisor);
469*22de5d62SHelge Deller u64 hppa_div64_rem(u64 div, u64 divisor);
470*22de5d62SHelge Deller 
471*22de5d62SHelge Deller /* Helper functions that emit HPPA instructions when possible. */
472*22de5d62SHelge Deller 
473*22de5d62SHelge Deller void bpf_jit_build_prologue(struct hppa_jit_context *ctx);
474*22de5d62SHelge Deller void bpf_jit_build_epilogue(struct hppa_jit_context *ctx);
475*22de5d62SHelge Deller 
476*22de5d62SHelge Deller int bpf_jit_emit_insn(const struct bpf_insn *insn, struct hppa_jit_context *ctx,
477*22de5d62SHelge Deller 		      bool extra_pass);
478*22de5d62SHelge Deller 
479*22de5d62SHelge Deller #endif /* _BPF_JIT_H */
480