@@ -398,6 +398,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
398398 Insn :: FixnumGe { left, right } => gen_fixnum_ge ( asm, opnd ! ( left) , opnd ! ( right) ) ,
399399 Insn :: FixnumAnd { left, right } => gen_fixnum_and ( asm, opnd ! ( left) , opnd ! ( right) ) ,
400400 Insn :: FixnumOr { left, right } => gen_fixnum_or ( asm, opnd ! ( left) , opnd ! ( right) ) ,
401+ & Insn :: FixnumMod { left, right, state } => gen_fixnum_mod ( jit, asm, opnd ! ( left) , opnd ! ( right) , & function. frame_state ( state) ) ,
401402 Insn :: IsNil { val } => gen_isnil ( asm, opnd ! ( val) ) ,
402403 & Insn :: IsMethodCfunc { val, cd, cfunc, state : _ } => gen_is_method_cfunc ( jit, asm, opnd ! ( val) , cd, cfunc) ,
403404 & Insn :: IsBitEqual { left, right } => gen_is_bit_equal ( asm, opnd ! ( left) , opnd ! ( right) ) ,
@@ -447,7 +448,6 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
447448 & Insn :: LoadIvarExtended { self_val, id, index } => gen_load_ivar_extended ( asm, opnd ! ( self_val) , id, index) ,
448449 & Insn :: ArrayMax { state, .. }
449450 | & Insn :: FixnumDiv { state, .. }
450- | & Insn :: FixnumMod { state, .. }
451451 | & Insn :: Throw { state, .. }
452452 => return Err ( state) ,
453453 } ;
@@ -1460,6 +1460,13 @@ fn gen_fixnum_or(asm: &mut Assembler, left: lir::Opnd, right: lir::Opnd) -> lir:
14601460 asm. or ( left, right)
14611461}
14621462
1463+ fn gen_fixnum_mod ( jit : & mut JITState , asm : & mut Assembler , left : lir:: Opnd , right : lir:: Opnd , state : & FrameState ) -> lir:: Opnd {
1464+ // Check for left % 0, which raises ZeroDivisionError
1465+ asm. cmp ( right, Opnd :: from ( VALUE :: fixnum_from_usize ( 0 ) ) ) ;
1466+ asm. je ( side_exit ( jit, state, FixnumModByZero ) ) ;
1467+ asm_ccall ! ( asm, rb_fix_mod_fix, left, right)
1468+ }
1469+
14631470// Compile val == nil
14641471fn gen_isnil ( asm : & mut Assembler , val : lir:: Opnd ) -> lir:: Opnd {
14651472 asm. cmp ( val, Qnil . into ( ) ) ;
0 commit comments