diff options
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/bpf/jit.c')
-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, |