]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
LoongArch: BPF: Support signed mod instructions
authorHengqi Chen <hengqi.chen@gmail.com>
Wed, 8 Nov 2023 06:12:21 +0000 (14:12 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Wed, 8 Nov 2023 06:12:21 +0000 (14:12 +0800)
Add support for signed mod instructions.

Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/net/bpf_jit.c

index 7c0d129b82a4a45f6e404c676b27da8e85619d1a..169ff8b3915e6cc955cccf839c1b717b7f3e1bfd 100644 (file)
@@ -588,20 +588,36 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
        /* dst = dst % src */
        case BPF_ALU | BPF_MOD | BPF_X:
        case BPF_ALU64 | BPF_MOD | BPF_X:
-               emit_zext_32(ctx, dst, is32);
-               move_reg(ctx, t1, src);
-               emit_zext_32(ctx, t1, is32);
-               emit_insn(ctx, moddu, dst, dst, t1);
-               emit_zext_32(ctx, dst, is32);
+               if (!off) {
+                       emit_zext_32(ctx, dst, is32);
+                       move_reg(ctx, t1, src);
+                       emit_zext_32(ctx, t1, is32);
+                       emit_insn(ctx, moddu, dst, dst, t1);
+                       emit_zext_32(ctx, dst, is32);
+               } else {
+                       emit_sext_32(ctx, dst, is32);
+                       move_reg(ctx, t1, src);
+                       emit_sext_32(ctx, t1, is32);
+                       emit_insn(ctx, modd, dst, dst, t1);
+                       emit_sext_32(ctx, dst, is32);
+               }
                break;
 
        /* dst = dst % imm */
        case BPF_ALU | BPF_MOD | BPF_K:
        case BPF_ALU64 | BPF_MOD | BPF_K:
-               move_imm(ctx, t1, imm, is32);
-               emit_zext_32(ctx, dst, is32);
-               emit_insn(ctx, moddu, dst, dst, t1);
-               emit_zext_32(ctx, dst, is32);
+               if (!off) {
+                       move_imm(ctx, t1, imm, is32);
+                       emit_zext_32(ctx, dst, is32);
+                       emit_insn(ctx, moddu, dst, dst, t1);
+                       emit_zext_32(ctx, dst, is32);
+               } else {
+                       move_imm(ctx, t1, imm, false);
+                       emit_sext_32(ctx, t1, is32);
+                       emit_sext_32(ctx, dst, is32);
+                       emit_insn(ctx, modd, dst, dst, t1);
+                       emit_sext_32(ctx, dst, is32);
+               }
                break;
 
        /* dst = -dst */