diff options
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp')
| -rw-r--r-- | drivers/net/ethernet/netronome/nfp/bpf/jit.c | 45 |
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 | ||
| 2385 | static 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 | |||
| 2396 | static 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 | |||
| 2420 | static 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 | |||
| 2385 | static int shl_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) | 2428 | static 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, |
