@@ -553,20 +553,36 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
553553 /* dst = dst / src */
554554 case BPF_ALU | BPF_DIV | BPF_X :
555555 case BPF_ALU64 | BPF_DIV | BPF_X :
556- emit_zext_32 (ctx , dst , is32 );
557- move_reg (ctx , t1 , src );
558- emit_zext_32 (ctx , t1 , is32 );
559- emit_insn (ctx , divdu , dst , dst , t1 );
560- emit_zext_32 (ctx , dst , is32 );
556+ if (!off ) {
557+ emit_zext_32 (ctx , dst , is32 );
558+ move_reg (ctx , t1 , src );
559+ emit_zext_32 (ctx , t1 , is32 );
560+ emit_insn (ctx , divdu , dst , dst , t1 );
561+ emit_zext_32 (ctx , dst , is32 );
562+ } else {
563+ emit_sext_32 (ctx , dst , is32 );
564+ move_reg (ctx , t1 , src );
565+ emit_sext_32 (ctx , t1 , is32 );
566+ emit_insn (ctx , divd , dst , dst , t1 );
567+ emit_sext_32 (ctx , dst , is32 );
568+ }
561569 break ;
562570
563571 /* dst = dst / imm */
564572 case BPF_ALU | BPF_DIV | BPF_K :
565573 case BPF_ALU64 | BPF_DIV | BPF_K :
566- move_imm (ctx , t1 , imm , is32 );
567- emit_zext_32 (ctx , dst , is32 );
568- emit_insn (ctx , divdu , dst , dst , t1 );
569- emit_zext_32 (ctx , dst , is32 );
574+ if (!off ) {
575+ move_imm (ctx , t1 , imm , is32 );
576+ emit_zext_32 (ctx , dst , is32 );
577+ emit_insn (ctx , divdu , dst , dst , t1 );
578+ emit_zext_32 (ctx , dst , is32 );
579+ } else {
580+ move_imm (ctx , t1 , imm , false);
581+ emit_sext_32 (ctx , t1 , is32 );
582+ emit_sext_32 (ctx , dst , is32 );
583+ emit_insn (ctx , divd , dst , dst , t1 );
584+ emit_sext_32 (ctx , dst , is32 );
585+ }
570586 break ;
571587
572588 /* dst = dst % src */
0 commit comments