@@ -588,20 +588,36 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
588588 /* dst = dst % src */
589589 case BPF_ALU | BPF_MOD | BPF_X :
590590 case BPF_ALU64 | BPF_MOD | BPF_X :
591- emit_zext_32 (ctx , dst , is32 );
592- move_reg (ctx , t1 , src );
593- emit_zext_32 (ctx , t1 , is32 );
594- emit_insn (ctx , moddu , dst , dst , t1 );
595- emit_zext_32 (ctx , dst , is32 );
591+ if (!off ) {
592+ emit_zext_32 (ctx , dst , is32 );
593+ move_reg (ctx , t1 , src );
594+ emit_zext_32 (ctx , t1 , is32 );
595+ emit_insn (ctx , moddu , dst , dst , t1 );
596+ emit_zext_32 (ctx , dst , is32 );
597+ } else {
598+ emit_sext_32 (ctx , dst , is32 );
599+ move_reg (ctx , t1 , src );
600+ emit_sext_32 (ctx , t1 , is32 );
601+ emit_insn (ctx , modd , dst , dst , t1 );
602+ emit_sext_32 (ctx , dst , is32 );
603+ }
596604 break ;
597605
598606 /* dst = dst % imm */
599607 case BPF_ALU | BPF_MOD | BPF_K :
600608 case BPF_ALU64 | BPF_MOD | BPF_K :
601- move_imm (ctx , t1 , imm , is32 );
602- emit_zext_32 (ctx , dst , is32 );
603- emit_insn (ctx , moddu , dst , dst , t1 );
604- emit_zext_32 (ctx , dst , is32 );
609+ if (!off ) {
610+ move_imm (ctx , t1 , imm , is32 );
611+ emit_zext_32 (ctx , dst , is32 );
612+ emit_insn (ctx , moddu , dst , dst , t1 );
613+ emit_zext_32 (ctx , dst , is32 );
614+ } else {
615+ move_imm (ctx , t1 , imm , false);
616+ emit_sext_32 (ctx , t1 , is32 );
617+ emit_sext_32 (ctx , dst , is32 );
618+ emit_insn (ctx , modd , dst , dst , t1 );
619+ emit_sext_32 (ctx , dst , is32 );
620+ }
605621 break ;
606622
607623 /* dst = -dst */
0 commit comments