Skip to content

Commit fde3183

Browse files
sm00thmpe
authored andcommitted
powerpc64/bpf: jit support for signed division and modulo
Add jit support for sign division and modulo. Tested using test_bpf module. Signed-off-by: Artem Savkov <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://msgid.link/[email protected]
1 parent 597b171 commit fde3183

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

arch/powerpc/include/asm/ppc-opcode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@
536536
#define PPC_RAW_MULI(d, a, i) (0x1c000000 | ___PPC_RT(d) | ___PPC_RA(a) | IMM_L(i))
537537
#define PPC_RAW_DIVW(d, a, b) (0x7c0003d6 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
538538
#define PPC_RAW_DIVWU(d, a, b) (0x7c000396 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
539+
#define PPC_RAW_DIVD(d, a, b) (0x7c0003d2 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
539540
#define PPC_RAW_DIVDU(d, a, b) (0x7c000392 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
540541
#define PPC_RAW_DIVDE(t, a, b) (0x7c000352 | ___PPC_RT(t) | ___PPC_RA(a) | ___PPC_RB(b))
541542
#define PPC_RAW_DIVDE_DOT(t, a, b) (0x7c000352 | ___PPC_RT(t) | ___PPC_RA(a) | ___PPC_RB(b) | 0x1)

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -510,20 +510,33 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
510510
case BPF_ALU | BPF_DIV | BPF_X: /* (u32) dst /= (u32) src */
511511
case BPF_ALU | BPF_MOD | BPF_X: /* (u32) dst %= (u32) src */
512512
if (BPF_OP(code) == BPF_MOD) {
513-
EMIT(PPC_RAW_DIVWU(tmp1_reg, dst_reg, src_reg));
513+
if (off)
514+
EMIT(PPC_RAW_DIVW(tmp1_reg, dst_reg, src_reg));
515+
else
516+
EMIT(PPC_RAW_DIVWU(tmp1_reg, dst_reg, src_reg));
517+
514518
EMIT(PPC_RAW_MULW(tmp1_reg, src_reg, tmp1_reg));
515519
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, tmp1_reg));
516520
} else
517-
EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, src_reg));
521+
if (off)
522+
EMIT(PPC_RAW_DIVW(dst_reg, dst_reg, src_reg));
523+
else
524+
EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, src_reg));
518525
goto bpf_alu32_trunc;
519526
case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */
520527
case BPF_ALU64 | BPF_MOD | BPF_X: /* dst %= src */
521528
if (BPF_OP(code) == BPF_MOD) {
522-
EMIT(PPC_RAW_DIVDU(tmp1_reg, dst_reg, src_reg));
529+
if (off)
530+
EMIT(PPC_RAW_DIVD(tmp1_reg, dst_reg, src_reg));
531+
else
532+
EMIT(PPC_RAW_DIVDU(tmp1_reg, dst_reg, src_reg));
523533
EMIT(PPC_RAW_MULD(tmp1_reg, src_reg, tmp1_reg));
524534
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, tmp1_reg));
525535
} else
526-
EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, src_reg));
536+
if (off)
537+
EMIT(PPC_RAW_DIVD(dst_reg, dst_reg, src_reg));
538+
else
539+
EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, src_reg));
527540
break;
528541
case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
529542
case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */
@@ -544,19 +557,31 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
544557
switch (BPF_CLASS(code)) {
545558
case BPF_ALU:
546559
if (BPF_OP(code) == BPF_MOD) {
547-
EMIT(PPC_RAW_DIVWU(tmp2_reg, dst_reg, tmp1_reg));
560+
if (off)
561+
EMIT(PPC_RAW_DIVW(tmp2_reg, dst_reg, tmp1_reg));
562+
else
563+
EMIT(PPC_RAW_DIVWU(tmp2_reg, dst_reg, tmp1_reg));
548564
EMIT(PPC_RAW_MULW(tmp1_reg, tmp1_reg, tmp2_reg));
549565
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, tmp1_reg));
550566
} else
551-
EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, tmp1_reg));
567+
if (off)
568+
EMIT(PPC_RAW_DIVW(dst_reg, dst_reg, tmp1_reg));
569+
else
570+
EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, tmp1_reg));
552571
break;
553572
case BPF_ALU64:
554573
if (BPF_OP(code) == BPF_MOD) {
555-
EMIT(PPC_RAW_DIVDU(tmp2_reg, dst_reg, tmp1_reg));
574+
if (off)
575+
EMIT(PPC_RAW_DIVD(tmp2_reg, dst_reg, tmp1_reg));
576+
else
577+
EMIT(PPC_RAW_DIVDU(tmp2_reg, dst_reg, tmp1_reg));
556578
EMIT(PPC_RAW_MULD(tmp1_reg, tmp1_reg, tmp2_reg));
557579
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, tmp1_reg));
558580
} else
559-
EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, tmp1_reg));
581+
if (off)
582+
EMIT(PPC_RAW_DIVD(dst_reg, dst_reg, tmp1_reg));
583+
else
584+
EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, tmp1_reg));
560585
break;
561586
}
562587
goto bpf_alu32_trunc;

0 commit comments

Comments
 (0)