aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/netronome/nfp/bpf/jit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/bpf/jit.c')
-rw-r--r--drivers/net/ethernet/netronome/nfp/bpf/jit.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
index 97d33bb4d84d..662cbc21d909 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
@@ -2382,6 +2382,49 @@ static int neg_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
2382 return 0; 2382 return 0;
2383} 2383}
2384 2384
2385static int __ashr_imm(struct nfp_prog *nfp_prog, u8 dst, u8 shift_amt)
2386{
2387 /* Set signedness bit (MSB of result). */
2388 emit_alu(nfp_prog, reg_none(), reg_a(dst), ALU_OP_OR, reg_imm(0));
2389 emit_shf(nfp_prog, reg_both(dst), reg_none(), SHF_OP_ASHR, reg_b(dst),
2390 SHF_SC_R_SHF, shift_amt);
2391 wrp_immed(nfp_prog, reg_both(dst + 1), 0);
2392
2393 return 0;
2394}
2395
2396static int ashr_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
2397{
2398 const struct bpf_insn *insn = &meta->insn;
2399 u64 umin, umax;
2400 u8 dst, src;
2401
2402 dst = insn->dst_reg * 2;
2403 umin = meta->umin_src;
2404 umax = meta->umax_src;
2405 if (umin == umax)
2406 return __ashr_imm(nfp_prog, dst, umin);
2407
2408 src = insn->src_reg * 2;
2409 /* NOTE: the first insn will set both indirect shift amount (source A)
2410 * and signedness bit (MSB of result).
2411 */
2412 emit_alu(nfp_prog, reg_none(), reg_a(src), ALU_OP_OR, reg_b(dst));
2413 emit_shf_indir(nfp_prog, reg_both(dst), reg_none(), SHF_OP_ASHR,
2414 reg_b(dst), SHF_SC_R_SHF);
2415 wrp_immed(nfp_prog, reg_both(dst + 1), 0);
2416
2417 return 0;
2418}
2419
2420static int ashr_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
2421{
2422 const struct bpf_insn *insn = &meta->insn;
2423 u8 dst = insn->dst_reg * 2;
2424
2425 return __ashr_imm(nfp_prog, dst, insn->imm);
2426}
2427
2385static int shl_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) 2428static int shl_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
2386{ 2429{
2387 const struct bpf_insn *insn = &meta->insn; 2430 const struct bpf_insn *insn = &meta->insn;
@@ -3286,6 +3329,8 @@ static const instr_cb_t instr_cb[256] = {
3286 [BPF_ALU | BPF_DIV | BPF_K] = div_imm, 3329 [BPF_ALU | BPF_DIV | BPF_K] = div_imm,
3287 [BPF_ALU | BPF_NEG] = neg_reg, 3330 [BPF_ALU | BPF_NEG] = neg_reg,
3288 [BPF_ALU | BPF_LSH | BPF_K] = shl_imm, 3331 [BPF_ALU | BPF_LSH | BPF_K] = shl_imm,
3332 [BPF_ALU | BPF_ARSH | BPF_X] = ashr_reg,
3333 [BPF_ALU | BPF_ARSH | BPF_K] = ashr_imm,
3289 [BPF_ALU | BPF_END | BPF_X] = end_reg32, 3334 [BPF_ALU | BPF_END | BPF_X] = end_reg32,
3290 [BPF_LD | BPF_IMM | BPF_DW] = imm_ld8, 3335 [BPF_LD | BPF_IMM | BPF_DW] = imm_ld8,
3291 [BPF_LD | BPF_ABS | BPF_B] = data_ld1, 3336 [BPF_LD | BPF_ABS | BPF_B] = data_ld1,