From 5ae8575296d5b524cde42ad10badf8c89945105a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Mar 2023 19:18:45 -0500 Subject: [PATCH] x64: Take SIGFPE signals for divide traps (#6026) * x64: Take SIGFPE signals for divide traps Prior to this commit Wasmtime would configure `avoid_div_traps=true` unconditionally for Cranelift. This, for the division-based instructions, would change emitted code to explicitly trap on trap conditions instead of letting the `div` x86 instruction trap. There's no specific reason for Wasmtime, however, to specifically avoid traps in the `div` instruction. This means that the extra generated branches on x86 aren't necessary since the `div` and `idiv` instructions already trap for similar conditions as wasm requires. This commit instead disables the `avoid_div_traps` setting for Wasmtime's usage of Cranelift. Subsequently the codegen rules were updated slightly: * When `avoid_div_traps=true`, traps are no longer emitted for `div` instructions. * The `udiv`/`urem` instructions now list their trap as divide-by-zero instead of integer overflow. * The lowering for `sdiv` was updated to still explicitly check for zero but the integer overflow case is deferred to the instruction itself. * The lowering of `srem` no longer checks for zero and the listed trap for the `div` instruction is a divide-by-zero. This means that the codegen for `udiv` and `urem` no longer have any branches. The codegen for `sdiv` removes one branch but keeps the zero-check to differentiate the two kinds of traps. The codegen for `srem` removes one branch but keeps the -1 check since the semantics of `srem` mismatch with the semantics of `idiv` with a -1 divisor (specifically for INT_MIN). This is unlikely to have really all that much of a speedup but was something I noticed during #6008 which seemed like it'd be good to clean up. Plus Wasmtime's signal handling was already set up to catch `SIGFPE`, it was just never firing. * Remove the `avoid_div_traps` cranelift setting With no known users currently removing this should be possible and helps simplify the x64 backend. * x64: GC more support for avoid_div_traps Remove the `validate_sdiv_divisor*` pseudo-instructions and clean up some of the ISLE rules now that `div` is allowed to itself trap unconditionally. * x64: Store div trap code in instruction itself * Keep divisors in registers, not in memory Don't accidentally fold multiple traps together * Handle EXC_ARITHMETIC on macos * Update emit tests * Update winch and tests --- cranelift/codegen/meta/src/shared/settings.rs | 13 - cranelift/codegen/src/isa/s390x/inst.isle | 4 - cranelift/codegen/src/isa/s390x/lower.isle | 39 +- cranelift/codegen/src/isa/s390x/lower/isle.rs | 9 - cranelift/codegen/src/isa/x64/inst.isle | 64 +- cranelift/codegen/src/isa/x64/inst/emit.rs | 66 +- .../codegen/src/isa/x64/inst/emit_tests.rs | 18 +- cranelift/codegen/src/isa/x64/inst/mod.rs | 52 +- cranelift/codegen/src/isa/x64/lower.isle | 119 ++- cranelift/codegen/src/machinst/isle.rs | 4 - cranelift/codegen/src/prelude_lower.isle | 3 - cranelift/codegen/src/settings.rs | 1 - .../filetests/isa/s390x/div-traps.clif | 727 ------------------ .../filetests/isa/x64/div-checks.clif | 6 +- .../filetests/isa/x64/sdiv-checked.clif | 285 ------- .../filetests/filetests/isa/x64/sdiv.clif | 36 +- .../filetests/isa/x64/srem-checked.clif | 300 -------- .../filetests/filetests/isa/x64/srem.clif | 8 +- .../filetests/isa/x64/udiv-checked.clif | 264 ------- .../filetests/filetests/isa/x64/udiv.clif | 8 +- .../filetests/filetests/isa/x64/udivrem.clif | 16 +- .../filetests/isa/x64/urem-checked.clif | 280 ------- .../filetests/filetests/isa/x64/urem.clif | 8 +- .../filetests/runtests/div-checks.clif | 7 +- .../filetests/filetests/runtests/srem.clif | 2 - .../filetests/filetests/runtests/urem.clif | 5 - crates/cranelift-shared/src/isa_builder.rs | 6 - crates/runtime/src/traphandlers/macos.rs | 4 +- crates/wasmtime/src/engine.rs | 3 +- crates/wasmtime/src/engine/serialization.rs | 9 +- tests/all/traps.rs | 94 +++ winch/codegen/src/isa/x64/asm.rs | 63 +- .../filetests/x64/i32_divs/const.wat | 13 +- .../filetests/x64/i32_divs/one_zero.wat | 13 +- .../filetests/x64/i32_divs/overflow.wat | 13 +- .../filetests/x64/i32_divs/params.wat | 15 +- .../filetests/x64/i32_divs/zero_zero.wat | 13 +- .../filetests/x64/i32_divu/const.wat | 11 +- .../filetests/x64/i32_divu/one_zero.wat | 11 +- .../filetests/x64/i32_divu/params.wat | 13 +- .../filetests/x64/i32_divu/signed.wat | 11 +- .../filetests/x64/i32_divu/zero_zero.wat | 11 +- .../filetests/x64/i32_rems/const.wat | 21 +- .../filetests/x64/i32_rems/one_zero.wat | 21 +- .../filetests/x64/i32_rems/overflow.wat | 21 +- .../filetests/x64/i32_rems/params.wat | 23 +- .../filetests/x64/i32_rems/zero_zero.wat | 21 +- .../filetests/x64/i32_remu/const.wat | 13 +- .../filetests/x64/i32_remu/one_zero.wat | 13 +- .../filetests/x64/i32_remu/params.wat | 15 +- .../filetests/x64/i32_remu/signed.wat | 13 +- .../filetests/x64/i32_remu/zero_zero.wat | 13 +- .../filetests/x64/i64_divs/const.wat | 15 +- .../filetests/x64/i64_divs/one_zero.wat | 15 +- .../filetests/x64/i64_divs/overflow.wat | 15 +- .../filetests/x64/i64_divs/params.wat | 17 +- .../filetests/x64/i64_divs/zero_zero.wat | 15 +- .../filetests/x64/i64_divu/const.wat | 11 +- .../filetests/x64/i64_divu/one_zero.wat | 11 +- .../filetests/x64/i64_divu/params.wat | 13 +- .../filetests/x64/i64_divu/signed.wat | 11 +- .../filetests/x64/i64_divu/zero_zero.wat | 11 +- .../filetests/x64/i64_rems/const.wat | 21 +- .../filetests/x64/i64_rems/one_zero.wat | 21 +- .../filetests/x64/i64_rems/overflow.wat | 21 +- .../filetests/x64/i64_rems/params.wat | 23 +- .../filetests/x64/i64_rems/zero_zero.wat | 21 +- .../filetests/x64/i64_remu/const.wat | 13 +- .../filetests/x64/i64_remu/one_zero.wat | 13 +- .../filetests/x64/i64_remu/params.wat | 15 +- .../filetests/x64/i64_remu/signed.wat | 13 +- .../filetests/x64/i64_remu/zero_zero.wat | 13 +- 72 files changed, 505 insertions(+), 2624 deletions(-) delete mode 100644 cranelift/filetests/filetests/isa/s390x/div-traps.clif delete mode 100644 cranelift/filetests/filetests/isa/x64/sdiv-checked.clif delete mode 100644 cranelift/filetests/filetests/isa/x64/srem-checked.clif delete mode 100644 cranelift/filetests/filetests/isa/x64/udiv-checked.clif delete mode 100644 cranelift/filetests/filetests/isa/x64/urem-checked.clif diff --git a/cranelift/codegen/meta/src/shared/settings.rs b/cranelift/codegen/meta/src/shared/settings.rs index 2db1f13034..e68412183a 100644 --- a/cranelift/codegen/meta/src/shared/settings.rs +++ b/cranelift/codegen/meta/src/shared/settings.rs @@ -97,19 +97,6 @@ pub(crate) fn define() -> SettingGroup { false, ); - settings.add_bool( - "avoid_div_traps", - "Generate explicit checks around native division instructions to avoid their trapping.", - r#" - Generate explicit checks around native division instructions to - avoid their trapping. - - On ISAs like ARM where the native division instructions don't trap, - this setting has no effect - explicit checks are always inserted. - "#, - false, - ); - settings.add_bool( "enable_float", "Enable the use of floating-point instructions.", diff --git a/cranelift/codegen/src/isa/s390x/inst.isle b/cranelift/codegen/src/isa/s390x/inst.isle index 4330b33e01..92a9560372 100644 --- a/cranelift/codegen/src/isa/s390x/inst.isle +++ b/cranelift/codegen/src/isa/s390x/inst.isle @@ -1446,10 +1446,6 @@ (decl vxrs_ext2_disabled () Type) (extern extractor vxrs_ext2_disabled vxrs_ext2_disabled) -(decl allow_div_traps () Type) -(extern extractor allow_div_traps allow_div_traps) - - ;; Helpers for SIMD lane number operations ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; There are two ways to map vector types onto the SIMD vector registers diff --git a/cranelift/codegen/src/isa/s390x/lower.isle b/cranelift/codegen/src/isa/s390x/lower.isle index 965074fa69..1db1e8de32 100644 --- a/cranelift/codegen/src/isa/s390x/lower.isle +++ b/cranelift/codegen/src/isa/s390x/lower.isle @@ -536,7 +536,6 @@ (rule (lower (has_type (fits_in_64 ty) (udiv x y))) (let (;; Look at the divisor to determine whether we need to generate ;; an explicit division-by zero check. - (DZcheck bool (zero_divisor_check_needed y)) ;; Load up the dividend, by loading the input (possibly zero- ;; extended) input into the low half of the register pair, ;; and setting the high half to zero. @@ -545,10 +544,6 @@ ;; Load up the divisor, zero-extended if necessary. (ext_y Reg (put_in_reg_zext32 y)) (ext_ty Type (ty_ext32 ty)) - ;; Now actually perform the division-by zero check if necessary. - ;; This cannot be done earlier than here, because the check - ;; requires an already extended divisor value. - (_ Reg (maybe_trap_if_zero_divisor DZcheck ext_ty ext_y)) ;; Emit the actual divide instruction. (pair RegPair (udivmod ext_ty ext_x ext_y))) ;; The quotient can be found in the low half of the result. @@ -557,38 +552,13 @@ ;; Implement `urem`. Same as `udiv`, but finds the remainder in ;; the high half of the result register pair instead. (rule (lower (has_type (fits_in_64 ty) (urem x y))) - (let ((DZcheck bool (zero_divisor_check_needed y)) - (ext_x RegPair (regpair (imm (ty_ext32 ty) 0) + (let ((ext_x RegPair (regpair (imm (ty_ext32 ty) 0) (put_in_reg_zext32 x))) (ext_y Reg (put_in_reg_zext32 y)) (ext_ty Type (ty_ext32 ty)) - (_ Reg (maybe_trap_if_zero_divisor DZcheck ext_ty ext_y)) (pair RegPair (udivmod ext_ty ext_x ext_y))) (copy_reg ty (regpair_hi pair)))) -;; Determine whether we need to perform a divide-by-zero-check. -;; -;; If the `avoid_div_traps` flag is false, we never need to perform -;; that check; we can rely on the divide instruction itself to trap. -;; -;; If the `avoid_div_traps` flag is true, we perform the check explicitly. -;; This still can be omittted if the divisor is a non-zero immediate. -(decl zero_divisor_check_needed (Value) bool) -(rule 2 (zero_divisor_check_needed (i64_from_value x)) - (if (i64_nonzero x)) - $false) -(rule 1 (zero_divisor_check_needed (value_type (allow_div_traps))) $false) -(rule 0 (zero_divisor_check_needed _) $true) - -;; Perform the divide-by-zero check if required. -;; This is simply a compare-and-trap of the (extended) divisor against 0. -(decl maybe_trap_if_zero_divisor (bool Type Reg) Reg) -(rule (maybe_trap_if_zero_divisor $false _ _) (invalid_reg)) -(rule (maybe_trap_if_zero_divisor $true ext_ty reg) - (icmps_simm16_and_trap ext_ty reg 0 - (intcc_as_cond (IntCC.Equal)) - (trap_code_division_by_zero))) - ;;;; Rules for `sdiv` and `srem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -610,15 +580,12 @@ (rule (lower (has_type (fits_in_64 ty) (sdiv x y))) (let (;; Look at the divisor to determine whether we need to generate ;; explicit division-by-zero and/or integer-overflow checks. - (DZcheck bool (zero_divisor_check_needed y)) (OFcheck bool (div_overflow_check_needed y)) ;; Load up the dividend (sign-extended to 64-bit) (ext_x Reg (put_in_reg_sext64 x)) ;; Load up the divisor (sign-extended if necessary). (ext_y Reg (put_in_reg_sext32 y)) (ext_ty Type (ty_ext32 ty)) - ;; Perform division-by-zero check (same as for `udiv`). - (_ Reg (maybe_trap_if_zero_divisor DZcheck ext_ty ext_y)) ;; Perform integer-overflow check if necessary. (_ Reg (maybe_trap_if_sdiv_overflow OFcheck ext_ty ty ext_x ext_y)) ;; Emit the actual divide instruction. @@ -630,12 +597,10 @@ ;; the high half of the result register pair instead. Also, handle ;; the integer overflow case differently, see below. (rule (lower (has_type (fits_in_64 ty) (srem x y))) - (let ((DZcheck bool (zero_divisor_check_needed y)) - (OFcheck bool (div_overflow_check_needed y)) + (let ((OFcheck bool (div_overflow_check_needed y)) (ext_x Reg (put_in_reg_sext64 x)) (ext_y Reg (put_in_reg_sext32 y)) (ext_ty Type (ty_ext32 ty)) - (_ Reg (maybe_trap_if_zero_divisor DZcheck ext_ty ext_y)) (checked_x Reg (maybe_avoid_srem_overflow OFcheck ext_ty ext_x ext_y)) (pair RegPair (sdivmod ext_ty checked_x ext_y))) (copy_reg ty (regpair_hi pair)))) diff --git a/cranelift/codegen/src/isa/s390x/lower/isle.rs b/cranelift/codegen/src/isa/s390x/lower/isle.rs index 7baf0f5cf5..f32d38b79a 100644 --- a/cranelift/codegen/src/isa/s390x/lower/isle.rs +++ b/cranelift/codegen/src/isa/s390x/lower/isle.rs @@ -291,15 +291,6 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, S390xBackend> { Box::new(symbol_reloc.clone()) } - #[inline] - fn allow_div_traps(&mut self, _: Type) -> Option<()> { - if !self.backend.flags.avoid_div_traps() { - Some(()) - } else { - None - } - } - #[inline] fn mie2_enabled(&mut self, _: Type) -> Option<()> { if self.backend.isa_flags.has_mie2() { diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle index b0cf19ccc4..69b926f826 100644 --- a/cranelift/codegen/src/isa/x64/inst.isle +++ b/cranelift/codegen/src/isa/x64/inst.isle @@ -63,6 +63,7 @@ ;; instruction. (Div (size OperandSize) ;; 2, 4, or 8 (sign DivSignedness) + (trap TrapCode) (divisor GprMem) (dividend_lo Gpr) (dividend_hi Gpr) @@ -71,6 +72,7 @@ ;; Same as `Div`, but for 8-bits where the regalloc behavior is different (Div8 (sign DivSignedness) + (trap TrapCode) (divisor GprMem) (dividend Gpr) (dst WritableGpr)) @@ -103,29 +105,6 @@ (divisor Gpr) (dst WritableGpr)) - ;; Validates that the `divisor` can be safely divided into the - ;; `dividend`. - ;; - ;; This is a separate pseudo-instruction because it has some jumps in - ;; ways that can't be modeled otherwise with instructions right now. This - ;; will trap if the `divisor` is zero or if it's -1 and `dividend` is - ;; INT_MIN for the associated type. - ;; - ;; Note that 64-bit types must use `ValidateSdivDivisor64`. - (ValidateSdivDivisor (size OperandSize) - (dividend Gpr) - (divisor Gpr)) - - ;; Same as `ValidateSdivDivisor` but for 64-bit types. - ;; - ;; This is a distinct instruction because the emission in `emit.rs` - ;; requires a temporary register to load an immediate into, hence the - ;; `tmp` field in this instruction not present in the non-64-bit one. - (ValidateSdivDivisor64 (dividend Gpr) - (divisor Gpr) - (tmp WritableGpr)) - - ;; Do a sign-extend based on the sign of the value in rax into rdx: (cwd ;; cdq cqo) or al into ah: (cbw) (SignExtendData (size OperandSize) ;; 1, 2, 4, or 8 @@ -4506,32 +4485,32 @@ dst)) ;; Helper for creating `Div8` instructions -(decl x64_div8 (Gpr GprMem DivSignedness) Gpr) -(rule (x64_div8 dividend divisor sign) +(decl x64_div8 (Gpr GprMem DivSignedness TrapCode) Gpr) +(rule (x64_div8 dividend divisor sign trap) (let ((dst WritableGpr (temp_writable_gpr)) - (_ Unit (emit (MInst.Div8 sign divisor dividend dst)))) + (_ Unit (emit (MInst.Div8 sign trap divisor dividend dst)))) dst)) ;; Helper for creating `Div` instructions ;; ;; Two registers are returned through `ValueRegs` where the first is the ;; quotient and the second is the remainder. -(decl x64_div (Gpr Gpr GprMem OperandSize DivSignedness) ValueRegs) -(rule (x64_div dividend_lo dividend_hi divisor size sign) +(decl x64_div (Gpr Gpr GprMem OperandSize DivSignedness TrapCode) ValueRegs) +(rule (x64_div dividend_lo dividend_hi divisor size sign trap) (let ((dst_quotient WritableGpr (temp_writable_gpr)) (dst_remainder WritableGpr (temp_writable_gpr)) - (_ Unit (emit (MInst.Div size sign divisor dividend_lo dividend_hi dst_quotient dst_remainder)))) + (_ Unit (emit (MInst.Div size sign trap divisor dividend_lo dividend_hi dst_quotient dst_remainder)))) (value_regs dst_quotient dst_remainder))) ;; Helper for `Div`, returning the quotient and discarding the remainder. -(decl x64_div_quotient (Gpr Gpr GprMem OperandSize DivSignedness) ValueRegs) -(rule (x64_div_quotient dividend_lo dividend_hi divisor size sign) - (value_regs_get (x64_div dividend_lo dividend_hi divisor size sign) 0)) +(decl x64_div_quotient (Gpr Gpr GprMem OperandSize DivSignedness TrapCode) ValueRegs) +(rule (x64_div_quotient dividend_lo dividend_hi divisor size sign trap) + (value_regs_get (x64_div dividend_lo dividend_hi divisor size sign trap) 0)) ;; Helper for `Div`, returning the remainder and discarding the quotient. -(decl x64_div_remainder (Gpr Gpr GprMem OperandSize DivSignedness) ValueRegs) -(rule (x64_div_remainder dividend_lo dividend_hi divisor size sign) - (value_regs_get (x64_div dividend_lo dividend_hi divisor size sign) 1)) +(decl x64_div_remainder (Gpr Gpr GprMem OperandSize DivSignedness TrapCode) ValueRegs) +(rule (x64_div_remainder dividend_lo dividend_hi divisor size sign trap) + (value_regs_get (x64_div dividend_lo dividend_hi divisor size sign trap) 1)) ;; Helper for creating `SignExtendData` instructions (decl x64_sign_extend_data (Gpr OperandSize) Gpr) @@ -4540,21 +4519,6 @@ (_ Unit (emit (MInst.SignExtendData size src dst)))) dst)) -;; Helper for creating `ValidateSdivDivisor` instructions. -(decl validate_sdiv_divisor (OperandSize Gpr Gpr) Gpr) -(rule (validate_sdiv_divisor size dividend divisor) - (let ((_ Unit (emit (MInst.ValidateSdivDivisor size dividend divisor)))) - divisor)) - -;; Helper for creating `ValidateSdivDivisor64` instructions. -(decl validate_sdiv_divisor64 (Gpr Gpr) Gpr) -(rule (validate_sdiv_divisor64 dividend divisor) - (let ( - (tmp WritableGpr (temp_writable_gpr)) - (_ Unit (emit (MInst.ValidateSdivDivisor64 dividend divisor tmp))) - ) - divisor)) - ;;;; Pinned Register ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (decl read_pinned_gpr () Gpr) diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs index 64c07f1e8c..3e19d33440 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit.rs @@ -400,7 +400,18 @@ pub(crate) fn emit( emit_std_enc_enc(sink, prefix, opcode, 1, subopcode, enc_src, rex_flags) } - Inst::Div { sign, divisor, .. } | Inst::Div8 { sign, divisor, .. } => { + Inst::Div { + sign, + trap, + divisor, + .. + } + | Inst::Div8 { + sign, + trap, + divisor, + .. + } => { let divisor = divisor.clone().to_reg_mem().with_allocs(allocs); let size = match inst { Inst::Div { @@ -438,7 +449,7 @@ pub(crate) fn emit( OperandSize::Size64 => (0xF7, LegacyPrefixes::None), }; - sink.add_trap(TrapCode::IntegerDivisionByZero); + sink.add_trap(*trap); let subopcode = match sign { DivSignedness::Signed => 7, @@ -613,6 +624,7 @@ pub(crate) fn emit( let inst = match size { OperandSize::Size8 => Inst::div8( DivSignedness::Signed, + TrapCode::IntegerDivisionByZero, RegMem::reg(divisor), Gpr::new(regs::rax()).unwrap(), Writable::from_reg(Gpr::new(regs::rax()).unwrap()), @@ -620,6 +632,7 @@ pub(crate) fn emit( _ => Inst::div( size, DivSignedness::Signed, + TrapCode::IntegerDivisionByZero, RegMem::reg(divisor), Gpr::new(regs::rax()).unwrap(), Gpr::new(regs::rdx()).unwrap(), @@ -632,55 +645,6 @@ pub(crate) fn emit( sink.bind_label(done_label); } - Inst::ValidateSdivDivisor { - dividend, divisor, .. - } - | Inst::ValidateSdivDivisor64 { - dividend, divisor, .. - } => { - let orig_inst = &inst; - let divisor = allocs.next(divisor.to_reg()); - let dividend = allocs.next(dividend.to_reg()); - let size = match inst { - Inst::ValidateSdivDivisor { size, .. } => *size, - _ => OperandSize::Size64, - }; - - // First trap if the divisor is zero - let inst = Inst::cmp_rmi_r(size, RegMemImm::imm(0), divisor); - inst.emit(&[], sink, info, state); - let inst = Inst::trap_if(CC::Z, TrapCode::IntegerDivisionByZero); - inst.emit(&[], sink, info, state); - - // Now check if the divisor is -1. If it is then additionally - // check if the dividend is INT_MIN. If it isn't then jump to the - // end. If both conditions here are true then trap. - let inst = Inst::cmp_rmi_r(size, RegMemImm::imm(0xffffffff), divisor); - inst.emit(&[], sink, info, state); - let done = sink.get_label(); - one_way_jmp(sink, CC::NZ, done); - let int_min = match orig_inst { - Inst::ValidateSdivDivisor64 { tmp, .. } => { - let tmp = allocs.next(tmp.to_reg().to_reg()); - let inst = Inst::imm(size, i64::MIN as u64, Writable::from_reg(tmp)); - inst.emit(&[], sink, info, state); - RegMemImm::reg(tmp) - } - _ => RegMemImm::imm(match size { - OperandSize::Size8 => 0x80, - OperandSize::Size16 => 0x8000, - OperandSize::Size32 => 0x80000000, - OperandSize::Size64 => unreachable!(), - }), - }; - let inst = Inst::cmp_rmi_r(size, int_min, dividend); - inst.emit(&[], sink, info, state); - let inst = Inst::trap_if(CC::Z, TrapCode::IntegerOverflow); - inst.emit(&[], sink, info, state); - - sink.bind_label(done); - } - Inst::Imm { dst_size, simm64, diff --git a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs index 7e258bb8fe..ee759d1a10 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs @@ -1750,6 +1750,7 @@ fn test_x64_emit() { Inst::div( OperandSize::Size32, DivSignedness::Signed, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::rsi()), Gpr::new(regs::rax()).unwrap(), Gpr::new(regs::rdx()).unwrap(), @@ -1757,12 +1758,13 @@ fn test_x64_emit() { WritableGpr::from_reg(Gpr::new(regs::rdx()).unwrap()), ), "F7FE", - "idiv %eax, %edx, %esi, %eax, %edx", + "idiv %eax, %edx, %esi, %eax, %edx ; trap=int_divz", )); insns.push(( Inst::div( OperandSize::Size64, DivSignedness::Signed, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::r15()), Gpr::new(regs::rax()).unwrap(), Gpr::new(regs::rdx()).unwrap(), @@ -1770,12 +1772,13 @@ fn test_x64_emit() { WritableGpr::from_reg(Gpr::new(regs::rdx()).unwrap()), ), "49F7FF", - "idiv %rax, %rdx, %r15, %rax, %rdx", + "idiv %rax, %rdx, %r15, %rax, %rdx ; trap=int_divz", )); insns.push(( Inst::div( OperandSize::Size32, DivSignedness::Unsigned, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::r14()), Gpr::new(regs::rax()).unwrap(), Gpr::new(regs::rdx()).unwrap(), @@ -1783,12 +1786,13 @@ fn test_x64_emit() { WritableGpr::from_reg(Gpr::new(regs::rdx()).unwrap()), ), "41F7F6", - "div %eax, %edx, %r14d, %eax, %edx", + "div %eax, %edx, %r14d, %eax, %edx ; trap=int_divz", )); insns.push(( Inst::div( OperandSize::Size64, DivSignedness::Unsigned, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::rdi()), Gpr::new(regs::rax()).unwrap(), Gpr::new(regs::rdx()).unwrap(), @@ -1796,27 +1800,29 @@ fn test_x64_emit() { WritableGpr::from_reg(Gpr::new(regs::rdx()).unwrap()), ), "48F7F7", - "div %rax, %rdx, %rdi, %rax, %rdx", + "div %rax, %rdx, %rdi, %rax, %rdx ; trap=int_divz", )); insns.push(( Inst::div8( DivSignedness::Unsigned, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::rax()), Gpr::new(regs::rax()).unwrap(), WritableGpr::from_reg(Gpr::new(regs::rax()).unwrap()), ), "F6F0", - "div %al, %al, %al", + "div %al, %al, %al ; trap=int_divz", )); insns.push(( Inst::div8( DivSignedness::Unsigned, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::rsi()), Gpr::new(regs::rax()).unwrap(), WritableGpr::from_reg(Gpr::new(regs::rax()).unwrap()), ), "40F6F6", - "div %al, %sil, %al", + "div %al, %sil, %al ; trap=int_divz", )); // ======================================================== diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs index 77689c6424..84455dc208 100644 --- a/cranelift/codegen/src/isa/x64/inst/mod.rs +++ b/cranelift/codegen/src/isa/x64/inst/mod.rs @@ -73,8 +73,6 @@ impl Inst { | Inst::CallUnknown { .. } | Inst::CheckedSRemSeq { .. } | Inst::CheckedSRemSeq8 { .. } - | Inst::ValidateSdivDivisor { .. } - | Inst::ValidateSdivDivisor64 { .. } | Inst::Cmove { .. } | Inst::CmpRmiR { .. } | Inst::CvtFloatToSintSeq { .. } @@ -225,6 +223,7 @@ impl Inst { pub(crate) fn div( size: OperandSize, sign: DivSignedness, + trap: TrapCode, divisor: RegMem, dividend_lo: Gpr, dividend_hi: Gpr, @@ -235,6 +234,7 @@ impl Inst { Inst::Div { size, sign, + trap, divisor: GprMem::new(divisor).unwrap(), dividend_lo, dividend_hi, @@ -245,6 +245,7 @@ impl Inst { pub(crate) fn div8( sign: DivSignedness, + trap: TrapCode, divisor: RegMem, dividend: Gpr, dst: WritableGpr, @@ -252,6 +253,7 @@ impl Inst { divisor.assert_regclass_is(RegClass::Int); Inst::Div8 { sign, + trap, divisor: GprMem::new(divisor).unwrap(), dividend, dst, @@ -548,10 +550,6 @@ impl Inst { Inst::JmpUnknown { target } } - pub(crate) fn trap_if(cc: CC, trap_code: TrapCode) -> Inst { - Inst::TrapIf { cc, trap_code } - } - /// Choose which instruction to use for loading a register value from memory. For loads smaller /// than 64 bits, this method expects a way to extend the value (i.e. [ExtKind::SignExtend], /// [ExtKind::ZeroExtend]); loads with no extension necessary will ignore this. @@ -771,6 +769,7 @@ impl PrettyPrint for Inst { Inst::Div { size, sign, + trap, divisor, dividend_lo, dividend_hi, @@ -785,7 +784,7 @@ impl PrettyPrint for Inst { let dst_remainder = pretty_print_reg(dst_remainder.to_reg().to_reg(), size.to_bytes(), allocs); format!( - "{} {}, {}, {}, {}, {}", + "{} {}, {}, {}, {}, {} ; trap={trap}", ljustify(match sign { DivSignedness::Signed => "idiv".to_string(), DivSignedness::Unsigned => "div".to_string(), @@ -800,6 +799,7 @@ impl PrettyPrint for Inst { Inst::Div8 { sign, + trap, divisor, dividend, dst, @@ -808,7 +808,7 @@ impl PrettyPrint for Inst { let dividend = pretty_print_reg(dividend.to_reg(), 1, allocs); let dst = pretty_print_reg(dst.to_reg().to_reg(), 1, allocs); format!( - "{} {dividend}, {divisor}, {dst}", + "{} {dividend}, {divisor}, {dst} ; trap={trap}", ljustify(match sign { DivSignedness::Signed => "idiv".to_string(), DivSignedness::Unsigned => "div".to_string(), @@ -874,27 +874,6 @@ impl PrettyPrint for Inst { format!("checked_srem_seq {dividend}, {divisor}, {dst}") } - Inst::ValidateSdivDivisor { - dividend, - divisor, - size, - } => { - let dividend = pretty_print_reg(dividend.to_reg(), size.to_bytes(), allocs); - let divisor = pretty_print_reg(divisor.to_reg(), size.to_bytes(), allocs); - format!("validate_sdiv_divisor {dividend}, {divisor}") - } - - Inst::ValidateSdivDivisor64 { - dividend, - divisor, - tmp, - } => { - let dividend = pretty_print_reg(dividend.to_reg(), 8, allocs); - let divisor = pretty_print_reg(divisor.to_reg(), 8, allocs); - let tmp = pretty_print_reg(tmp.to_reg().to_reg(), 8, allocs); - format!("validate_sdiv_divisor {dividend}, {divisor} {tmp}") - } - Inst::SignExtendData { size, src, dst } => { let src = pretty_print_reg(src.to_reg(), size.to_bytes(), allocs); let dst = pretty_print_reg(dst.to_reg().to_reg(), size.to_bytes(), allocs); @@ -1917,21 +1896,6 @@ fn x64_get_operands VReg>(inst: &Inst, collector: &mut OperandCol collector.reg_fixed_def(dst_hi.to_writable_reg(), regs::rdx()); src2.get_operands(collector); } - Inst::ValidateSdivDivisor { - dividend, divisor, .. - } => { - collector.reg_use(divisor.to_reg()); - collector.reg_use(dividend.to_reg()); - } - Inst::ValidateSdivDivisor64 { - dividend, - divisor, - tmp, - } => { - collector.reg_use(divisor.to_reg()); - collector.reg_use(dividend.to_reg()); - collector.reg_early_def(tmp.to_writable_reg()); - } Inst::SignExtendData { size, src, dst } => { match size { OperandSize::Size8 => { diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle index 083566d03b..99adfb7cfd 100644 --- a/cranelift/codegen/src/isa/x64/lower.isle +++ b/cranelift/codegen/src/isa/x64/lower.isle @@ -3503,13 +3503,20 @@ ;; Rules for `udiv` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; NB: a `RegMem` divisor, while allowed in the instruction encoding, isn't +;; used right now to prevent a possibly-trapping load getting folded into the +;; `div` instruction. Ideally non-trapping loads would get folded, however, or +;; alternatively Wasmtime/Cranelift would grow support for multiple traps on +;; a single opcode and the signal kind would differentiate at runtime. + ;; The inputs to the `div` instruction are different for 8-bit division so ;; it needs a special case here since the instruction being crafted has a ;; different shape. (rule 2 (lower (udiv a @ (value_type $I8) b)) (x64_div8 (extend_to_gpr a $I32 (ExtendKind.Zero)) - (nonzero_divisor $I8 b) - (DivSignedness.Unsigned))) + (put_in_gpr b) + (DivSignedness.Unsigned) + (TrapCode.IntegerDivisionByZero))) ;; 16-to-64-bit division is all done with a similar instruction and the only ;; tricky requirement here is that when div traps are disallowed the divisor @@ -3517,29 +3524,40 @@ (rule 1 (lower (udiv a @ (value_type (fits_in_64 ty)) b)) (x64_div_quotient a (imm $I64 0) - (nonzero_divisor ty b) + (put_in_gpr b) (raw_operand_size_of_type ty) - (DivSignedness.Unsigned))) + (DivSignedness.Unsigned) + (TrapCode.IntegerDivisionByZero))) -;; Helper to place `Value` into a `Gpr` while possibly trapping if it's zero. +;; Rules for `sdiv` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(rule 2 (lower (sdiv a @ (value_type $I8) b)) + (x64_div8 (x64_sign_extend_data a (OperandSize.Size8)) + (nonzero_sdiv_divisor $I8 b) + (DivSignedness.Signed) + (TrapCode.IntegerOverflow))) + +(rule 1 (lower (sdiv a @ (value_type (fits_in_64 ty)) b)) + (let ( + (a Gpr a) + (size OperandSize (raw_operand_size_of_type ty)) + ) + (x64_div_quotient a + (x64_sign_extend_data a size) + (nonzero_sdiv_divisor ty b) + size + (DivSignedness.Signed) + (TrapCode.IntegerOverflow)))) + +;; Checks to make sure that the input `Value` is a non-zero value for `sdiv`. ;; -;; If the `avoid_div_traps=true` codegen setting is specified then the value -;; is checked for zero and a trap happens before the value is returned as a -;; register here. -(decl nonzero_divisor (Type Value) Gpr) - -;; As a special-case if the divisor is a constant number which is nonzero then -;; no matter what there's no checks necessary. -(rule 2 (nonzero_divisor ty (iconst (u64_from_imm64 (u64_nonzero n)))) +;; This is required to differentiate the divide-by-zero trap from the +;; integer-overflow trap, the two trapping conditions of signed division. +(decl nonzero_sdiv_divisor (Type Value) Reg) +(rule 1 (nonzero_sdiv_divisor ty (iconst imm)) + (if-let n (safe_divisor_from_imm64 ty imm)) (imm ty n)) - -;; No checks necessary when `avoid_div_traps=false` -(rule 1 (nonzero_divisor ty val) - (if-let $false (avoid_div_traps)) - val) - -;; Base case traps if `val` is zero by using a `test` + `trap_if` combo -(rule (nonzero_divisor ty val) +(rule 0 (nonzero_sdiv_divisor ty val) (let ( (val Reg val) (_ InstOutput (side_effect (with_flags_side_effect @@ -3548,64 +3566,26 @@ ) val)) -;; Rules for `sdiv` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(rule 2 (lower (sdiv a @ (value_type $I8) b)) - (let ( - (a Gpr (x64_sign_extend_data a (OperandSize.Size8))) - ) - (x64_div8 a (safe_sdiv_divisor $I8 a b) (DivSignedness.Signed)))) - -(rule 1 (lower (sdiv a @ (value_type (fits_in_64 ty)) b)) - (let ( - (a Gpr a) - (size OperandSize (raw_operand_size_of_type ty)) - (b Gpr (safe_sdiv_divisor ty a b)) - ) - (x64_div_quotient a (x64_sign_extend_data a size) b size (DivSignedness.Signed)))) - -;; Similar to `nonzero_divisor` except this checks to make sure that the divisor -;; provided as a `Value` is safe to divide into the dividend `Gpr` provided. -(decl safe_sdiv_divisor (Type Gpr Value) Reg) - -;; If the divisor is a constant that isn't 0 or -1, then it's always safe so -;; materialize it into a register. -(rule 3 (safe_sdiv_divisor ty a (iconst imm)) - (if-let n (safe_divisor_from_imm64 ty imm)) - (imm ty n)) - -;; With `avoid_div_traps=false` the divisor can be plumbed through. -;; -;; Note that CLIF semantics dictate that division-by-zero and INT_MIN/-1 both -;; trap, but this matches the hardware semantics of `idiv` on x64 so they're -;; fine to get plumbed through as-is. -(rule 2 (safe_sdiv_divisor ty a b) - (if-let $false (avoid_div_traps)) - b) - -;; The base cases here rely on some pseudo-instructions to do the checks to -;; jump around with labels and such. -(rule 1 (safe_sdiv_divisor $I64 a b) (validate_sdiv_divisor64 a b)) -(rule 0 (safe_sdiv_divisor ty a b) (validate_sdiv_divisor (raw_operand_size_of_type ty) a b)) - ;; Rules for `urem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; The remainder is in AH, so take the result of the division and right-shift ;; by 8. (rule 2 (lower (urem a @ (value_type $I8) b)) (let ( - (a Gpr (extend_to_gpr a $I32 (ExtendKind.Zero))) - (b Gpr (nonzero_divisor $I8 b)) - (result Gpr (x64_div8 a b (DivSignedness.Unsigned))) + (result Gpr (x64_div8 (extend_to_gpr a $I32 (ExtendKind.Zero)) + (put_in_gpr b) ;; see `udiv` for why not `gpr_mem` + (DivSignedness.Unsigned) + (TrapCode.IntegerDivisionByZero))) ) (x64_shr $I64 result (Imm8Reg.Imm8 8)))) (rule 1 (lower (urem a @ (value_type (fits_in_64 ty)) b)) (x64_div_remainder a (imm $I64 0) - (nonzero_divisor ty b) + (put_in_gpr b) ;; see `udiv` for why not `gpr_mem` (raw_operand_size_of_type ty) - (DivSignedness.Unsigned))) + (DivSignedness.Unsigned) + (TrapCode.IntegerDivisionByZero))) ;; Rules for `srem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -3618,7 +3598,7 @@ (if-let n (safe_divisor_from_imm64 $I8 imm)) (let ( (a Gpr (x64_sign_extend_data a (OperandSize.Size8))) - (result Gpr (x64_div8 a (imm $I8 n) (DivSignedness.Signed))) + (result Gpr (x64_div8 a (imm $I8 n) (DivSignedness.Signed) (TrapCode.IntegerDivisionByZero))) ) (x64_shr $I64 result (Imm8Reg.Imm8 8)))) @@ -3633,19 +3613,18 @@ (x64_sign_extend_data a size) (imm ty n) size - (DivSignedness.Signed)))) + (DivSignedness.Signed) + (TrapCode.IntegerDivisionByZero)))) (rule 1 (lower (srem a @ (value_type $I8) b)) (let ( (a Gpr (x64_sign_extend_data a (OperandSize.Size8))) - (b Gpr (nonzero_divisor $I8 b)) ) (x64_shr $I64 (x64_checked_srem_seq8 a b) (Imm8Reg.Imm8 8)))) (rule (lower (srem a @ (value_type ty) b)) (let ( (a Gpr a) - (b Gpr (nonzero_divisor ty b)) (size OperandSize (raw_operand_size_of_type ty)) (hi Gpr (x64_sign_extend_data a size)) (tmp ValueRegs (x64_checked_srem_seq size a hi b)) diff --git a/cranelift/codegen/src/machinst/isle.rs b/cranelift/codegen/src/machinst/isle.rs index ca39d0feb3..867102c32d 100644 --- a/cranelift/codegen/src/machinst/isle.rs +++ b/cranelift/codegen/src/machinst/isle.rs @@ -285,10 +285,6 @@ macro_rules! isle_lower_prelude_methods { } } - fn avoid_div_traps(&mut self) -> bool { - self.backend.flags().avoid_div_traps() - } - #[inline] fn tls_model(&mut self, _: Type) -> TlsModel { self.backend.flags().tls_model() diff --git a/cranelift/codegen/src/prelude_lower.isle b/cranelift/codegen/src/prelude_lower.isle index 8db2f73556..eab34154e0 100644 --- a/cranelift/codegen/src/prelude_lower.isle +++ b/cranelift/codegen/src/prelude_lower.isle @@ -530,9 +530,6 @@ ;;;; Helpers for accessing compilation flags ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(decl pure avoid_div_traps () bool) -(extern constructor avoid_div_traps avoid_div_traps) - ;; This definition should be kept up to date with the values defined in ;; cranelift/codegen/meta/src/shared/settings.rs (type TlsModel extern (enum (None) (ElfGd) (Macho) (Coff))) diff --git a/cranelift/codegen/src/settings.rs b/cranelift/codegen/src/settings.rs index 5485779de8..44d2504dff 100644 --- a/cranelift/codegen/src/settings.rs +++ b/cranelift/codegen/src/settings.rs @@ -532,7 +532,6 @@ use_egraphs = true enable_verifier = true is_pic = false use_colocated_libcalls = false -avoid_div_traps = false enable_float = true enable_nan_canonicalization = false enable_pinned_reg = false diff --git a/cranelift/filetests/filetests/isa/s390x/div-traps.clif b/cranelift/filetests/filetests/isa/s390x/div-traps.clif deleted file mode 100644 index 5b776de46c..0000000000 --- a/cranelift/filetests/filetests/isa/s390x/div-traps.clif +++ /dev/null @@ -1,727 +0,0 @@ -test compile precise-output -set avoid_div_traps=1 -target s390x - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; SDIV -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -function %sdiv_i64(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = sdiv.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; cgite %r3, 0 -; llihf %r4, 2147483647 -; iilf %r4, 4294967295 -; xgr %r4, %r2 -; lgr %r5, %r2 -; ngr %r4, %r3 -; lgr %r2, %r3 -; cgite %r4, -1 -; lgr %r4, %r2 -; lgr %r3, %r5 -; dsgr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; cgite %r3, 0 ; trap: int_divz -; llihf %r4, 0x7fffffff -; iilf %r4, 0xffffffff -; xgr %r4, %r2 -; lgr %r5, %r2 -; ngr %r4, %r3 -; lgr %r2, %r3 -; cgite %r4, -1 ; trap: int_ovf -; lgr %r4, %r2 -; lgr %r3, %r5 -; dsgr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 2 - v2 = sdiv.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r3, %r2 -; lghi %r4, 2 -; dsgr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r3, %r2 -; lghi %r4, 2 -; dsgr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i32(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = sdiv.i32 v0, v1 - return v2 -} - -; VCode: -; stmg %r7, %r15, 56(%r15) -; block0: -; lgfr %r5, %r2 -; lgr %r7, %r5 -; cite %r3, 0 -; iilf %r5, 2147483647 -; lgr %r4, %r7 -; xrk %r2, %r5, %r4 -; nrk %r4, %r2, %r3 -; lgr %r5, %r3 -; cite %r4, -1 -; lgr %r3, %r7 -; dsgfr %r2, %r5 -; lgr %r2, %r3 -; lmg %r7, %r15, 56(%r15) -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; stmg %r7, %r15, 0x38(%r15) -; block1: ; offset 0x6 -; lgfr %r5, %r2 -; lgr %r7, %r5 -; cite %r3, 0 ; trap: int_divz -; iilf %r5, 0x7fffffff -; lgr %r4, %r7 -; xrk %r2, %r5, %r4 -; nrk %r4, %r2, %r3 -; lgr %r5, %r3 -; cite %r4, -1 ; trap: int_ovf -; lgr %r3, %r7 -; dsgfr %r2, %r5 ; trap: int_divz -; lgr %r2, %r3 -; lmg %r7, %r15, 0x38(%r15) -; br %r14 - -function %sdiv_i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 2 - v2 = sdiv.i32 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgfr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgfr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i16(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = sdiv.i16 v0, v1 - return v2 -} - -; VCode: -; block0: -; lghr %r5, %r2 -; lhr %r4, %r3 -; cite %r4, 0 -; lhi %r2, 32767 -; lgr %r3, %r5 -; xrk %r5, %r2, %r3 -; nrk %r2, %r5, %r4 -; cite %r2, -1 -; dsgfr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lghr %r5, %r2 -; lhr %r4, %r3 -; cite %r4, 0 ; trap: int_divz -; lhi %r2, 0x7fff -; lgr %r3, %r5 -; xrk %r5, %r2, %r3 -; nrk %r2, %r5, %r4 -; cite %r2, -1 ; trap: int_ovf -; dsgfr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 2 - v2 = sdiv.i16 v0, v1 - return v2 -} - -; VCode: -; block0: -; lghr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lghr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i8(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = sdiv.i8 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgbr %r5, %r2 -; lbr %r4, %r3 -; cite %r4, 0 -; lhi %r2, 127 -; lgr %r3, %r5 -; xrk %r5, %r2, %r3 -; nrk %r2, %r5, %r4 -; cite %r2, -1 -; dsgfr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgbr %r5, %r2 -; lbr %r4, %r3 -; cite %r4, 0 ; trap: int_divz -; lhi %r2, 0x7f -; lgr %r3, %r5 -; xrk %r5, %r2, %r3 -; nrk %r2, %r5, %r4 -; cite %r2, -1 ; trap: int_ovf -; dsgfr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 2 - v2 = sdiv.i8 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgbr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgbr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i64(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = udiv.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r5, %r2 -; lghi %r2, 0 -; cgite %r3, 0 -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlgr %r2, %r5 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r5, %r2 -; lghi %r2, 0 -; cgite %r3, 0 ; trap: int_divz -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlgr %r2, %r5 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 2 - v2 = udiv.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r3, %r2 -; lghi %r2, 0 -; lghi %r4, 2 -; dlgr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r3, %r2 -; lghi %r2, 0 -; lghi %r4, 2 -; dlgr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i32(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = udiv.i32 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r5, %r2 -; lhi %r2, 0 -; cite %r3, 0 -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlr %r2, %r5 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r5, %r2 -; lhi %r2, 0 -; cite %r3, 0 ; trap: int_divz -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlr %r2, %r5 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 2 - v2 = udiv.i32 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r3, %r2 -; lhi %r2, 0 -; lhi %r4, 2 -; dlr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r3, %r2 -; lhi %r2, 0 -; lhi %r4, 2 -; dlr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i16(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = udiv.i16 v0, v1 - return v2 -} - -; VCode: -; stmg %r8, %r15, 64(%r15) -; block0: -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llhr %r3, %r2 -; lgr %r5, %r4 -; llhr %r5, %r5 -; cite %r5, 0 -; lgr %r2, %r8 -; dlr %r2, %r5 -; lgr %r2, %r3 -; lmg %r8, %r15, 64(%r15) -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; stmg %r8, %r15, 0x40(%r15) -; block1: ; offset 0x6 -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llhr %r3, %r2 -; lgr %r5, %r4 -; llhr %r5, %r5 -; cite %r5, 0 ; trap: int_divz -; lgr %r2, %r8 -; dlr %r2, %r5 ; trap: int_divz -; lgr %r2, %r3 -; lmg %r8, %r15, 0x40(%r15) -; br %r14 - -function %udiv_i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 2 - v2 = udiv.i16 v0, v1 - return v2 -} - -; VCode: -; block0: -; lhi %r4, 0 -; lgr %r5, %r4 -; llhr %r3, %r2 -; lhi %r4, 2 -; lgr %r2, %r5 -; dlr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lhi %r4, 0 -; lgr %r5, %r4 -; llhr %r3, %r2 -; lhi %r4, 2 -; lgr %r2, %r5 -; dlr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i8(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = udiv.i8 v0, v1 - return v2 -} - -; VCode: -; stmg %r8, %r15, 64(%r15) -; block0: -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llcr %r3, %r2 -; lgr %r5, %r4 -; llcr %r5, %r5 -; cite %r5, 0 -; lgr %r2, %r8 -; dlr %r2, %r5 -; lgr %r2, %r3 -; lmg %r8, %r15, 64(%r15) -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; stmg %r8, %r15, 0x40(%r15) -; block1: ; offset 0x6 -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llcr %r3, %r2 -; lgr %r5, %r4 -; llcr %r5, %r5 -; cite %r5, 0 ; trap: int_divz -; lgr %r2, %r8 -; dlr %r2, %r5 ; trap: int_divz -; lgr %r2, %r3 -; lmg %r8, %r15, 0x40(%r15) -; br %r14 - -function %udiv_i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 2 - v2 = udiv.i8 v0, v1 - return v2 -} - -; VCode: -; block0: -; lhi %r4, 0 -; lgr %r5, %r4 -; llcr %r3, %r2 -; lhi %r4, 2 -; lgr %r2, %r5 -; dlr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lhi %r4, 0 -; lgr %r5, %r4 -; llcr %r3, %r2 -; lhi %r4, 2 -; lgr %r2, %r5 -; dlr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %srem_i64(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = srem.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; cgite %r3, 0 -; cghi %r3, -1 -; lgr %r4, %r3 -; lgr %r3, %r2 -; locghie %r3, 0 -; dsgr %r2, %r4 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; cgite %r3, 0 ; trap: int_divz -; cghi %r3, -1 -; lgr %r4, %r3 -; lgr %r3, %r2 -; locghie %r3, 0 -; dsgr %r2, %r4 ; trap: int_divz -; br %r14 - -function %srem_i32(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = srem.i32 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r5, %r3 -; lgfr %r3, %r2 -; lgr %r2, %r5 -; cite %r2, 0 -; dsgfr %r2, %r2 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r5, %r3 -; lgfr %r3, %r2 -; lgr %r2, %r5 -; cite %r2, 0 ; trap: int_divz -; dsgfr %r2, %r2 ; trap: int_divz -; br %r14 - -function %srem_i16(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = srem.i16 v0, v1 - return v2 -} - -; VCode: -; block0: -; lghr %r5, %r2 -; lgr %r2, %r5 -; lhr %r4, %r3 -; cite %r4, 0 -; lgr %r3, %r2 -; dsgfr %r2, %r4 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lghr %r5, %r2 -; lgr %r2, %r5 -; lhr %r4, %r3 -; cite %r4, 0 ; trap: int_divz -; lgr %r3, %r2 -; dsgfr %r2, %r4 ; trap: int_divz -; br %r14 - -function %srem_i8(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = srem.i8 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgbr %r5, %r2 -; lgr %r2, %r5 -; lbr %r4, %r3 -; cite %r4, 0 -; lgr %r3, %r2 -; dsgfr %r2, %r4 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgbr %r5, %r2 -; lgr %r2, %r5 -; lbr %r4, %r3 -; cite %r4, 0 ; trap: int_divz -; lgr %r3, %r2 -; dsgfr %r2, %r4 ; trap: int_divz -; br %r14 - -function %urem_i64(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = urem.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r5, %r2 -; lghi %r2, 0 -; cgite %r3, 0 -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlgr %r2, %r5 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r5, %r2 -; lghi %r2, 0 -; cgite %r3, 0 ; trap: int_divz -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlgr %r2, %r5 ; trap: int_divz -; br %r14 - -function %urem_i32(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = urem.i32 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r5, %r2 -; lhi %r2, 0 -; cite %r3, 0 -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlr %r2, %r5 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r5, %r2 -; lhi %r2, 0 -; cite %r3, 0 ; trap: int_divz -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlr %r2, %r5 ; trap: int_divz -; br %r14 - -function %urem_i16(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = urem.i16 v0, v1 - return v2 -} - -; VCode: -; stmg %r8, %r15, 64(%r15) -; block0: -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llhr %r3, %r2 -; lgr %r5, %r4 -; llhr %r5, %r5 -; cite %r5, 0 -; lgr %r2, %r8 -; dlr %r2, %r5 -; lmg %r8, %r15, 64(%r15) -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; stmg %r8, %r15, 0x40(%r15) -; block1: ; offset 0x6 -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llhr %r3, %r2 -; lgr %r5, %r4 -; llhr %r5, %r5 -; cite %r5, 0 ; trap: int_divz -; lgr %r2, %r8 -; dlr %r2, %r5 ; trap: int_divz -; lmg %r8, %r15, 0x40(%r15) -; br %r14 - -function %urem_i8(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = urem.i8 v0, v1 - return v2 -} - -; VCode: -; stmg %r8, %r15, 64(%r15) -; block0: -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llcr %r3, %r2 -; lgr %r5, %r4 -; llcr %r5, %r5 -; cite %r5, 0 -; lgr %r2, %r8 -; dlr %r2, %r5 -; lmg %r8, %r15, 64(%r15) -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; stmg %r8, %r15, 0x40(%r15) -; block1: ; offset 0x6 -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llcr %r3, %r2 -; lgr %r5, %r4 -; llcr %r5, %r5 -; cite %r5, 0 ; trap: int_divz -; lgr %r2, %r8 -; dlr %r2, %r5 ; trap: int_divz -; lmg %r8, %r15, 0x40(%r15) -; br %r14 - diff --git a/cranelift/filetests/filetests/isa/x64/div-checks.clif b/cranelift/filetests/filetests/isa/x64/div-checks.clif index 381a66b63c..9dd90788c0 100644 --- a/cranelift/filetests/filetests/isa/x64/div-checks.clif +++ b/cranelift/filetests/filetests/isa/x64/div-checks.clif @@ -1,10 +1,8 @@ test compile precise-output -set avoid_div_traps=false target x86_64 -;; We should get the checked-div/rem sequence (`srem` pseudoinst below) even -;; when `avoid_div_traps` above is false (i.e. even when the host is normally -;; willing to accept SIGFPEs as Wasm traps). The machine will SIGFPE in some +;; We should get the checked-div/rem sequence (`srem` pseudoinst below). +;; The machine will SIGFPE in some ;; cases when `srem` is valid (specifically -INT_MIN % -1). function %i8(i8, i8) -> i8 { diff --git a/cranelift/filetests/filetests/isa/x64/sdiv-checked.clif b/cranelift/filetests/filetests/isa/x64/sdiv-checked.clif deleted file mode 100644 index 7505a30789..0000000000 --- a/cranelift/filetests/filetests/isa/x64/sdiv-checked.clif +++ /dev/null @@ -1,285 +0,0 @@ -test compile precise-output -set avoid_div_traps=true -target x86_64 - -function %f1(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cbw %al, %al -; validate_sdiv_divisor %sil, %al -; idiv %al, %sil, %al -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cbtw -; cmpb $0, %sil -; jne 0x15 -; ud2 ; trap: int_divz -; cmpb $0xff, %sil -; jne 0x2a -; cmpb $0x80, %al -; jne 0x2a -; ud2 ; trap: int_ovf -; idivb %sil ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f2(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; validate_sdiv_divisor %si, %di -; movq %rdi, %rax -; cwd %ax, %dx -; idiv %ax, %dx, %si, %ax, %dx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; cmpw $0, %si -; jne 0x10 -; ud2 ; trap: int_divz -; cmpw $-1, %si -; jne 0x27 -; cmpw $0x8000, %di -; jne 0x27 -; ud2 ; trap: int_ovf -; movq %rdi, %rax -; cwtd -; idivw %si ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f3(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; validate_sdiv_divisor %esi, %edi -; movq %rdi, %rax -; cdq %eax, %edx -; idiv %eax, %edx, %esi, %eax, %edx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; cmpl $0, %esi -; jne 0xf -; ud2 ; trap: int_divz -; cmpl $-1, %esi -; jne 0x26 -; cmpl $0x80000000, %edi -; jne 0x26 -; ud2 ; trap: int_ovf -; movq %rdi, %rax -; cltd -; idivl %esi ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f4(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; validate_sdiv_divisor %rsi, %rdi %rcx -; movq %rdi, %rax -; cqo %rax, %rdx -; idiv %rax, %rdx, %rsi, %rax, %rdx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; cmpq $0, %rsi -; jne 0x10 -; ud2 ; trap: int_divz -; cmpq $-1, %rsi -; jne 0x2f -; movabsq $9223372036854775808, %rcx -; cmpq %rcx, %rdi -; jne 0x2f -; ud2 ; trap: int_ovf -; movq %rdi, %rax -; cqto -; idivq %rsi ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 17 - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cbw %al, %al -; movl $17, %edx -; idiv %al, %dl, %al -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cbtw -; movl $0x11, %edx -; idivb %dl ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 17 - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl $17, %ecx -; movq %rdi, %rax -; cwd %ax, %dx -; idiv %ax, %dx, %cx, %ax, %dx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movl $0x11, %ecx -; movq %rdi, %rax -; cwtd -; idivw %cx ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 17 - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl $17, %ecx -; movq %rdi, %rax -; cdq %eax, %edx -; idiv %eax, %edx, %ecx, %eax, %edx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movl $0x11, %ecx -; movq %rdi, %rax -; cltd -; idivl %ecx ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 17 - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl $17, %ecx -; movq %rdi, %rax -; cqo %rax, %rdx -; idiv %rax, %rdx, %rcx, %rax, %rdx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movl $0x11, %ecx -; movq %rdi, %rax -; cqto -; idivq %rcx ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - diff --git a/cranelift/filetests/filetests/isa/x64/sdiv.clif b/cranelift/filetests/filetests/isa/x64/sdiv.clif index 657a1e7fa4..f20b17d0b4 100644 --- a/cranelift/filetests/filetests/isa/x64/sdiv.clif +++ b/cranelift/filetests/filetests/isa/x64/sdiv.clif @@ -13,7 +13,9 @@ block0(v0: i8, v1: i8): ; block0: ; movq %rdi, %rax ; cbw %al, %al -; idiv %al, %sil, %al +; testb %sil, %sil +; jnz ; ud2 int_divz ; +; idiv %al, %sil, %al ; trap=int_ovf ; movq %rbp, %rsp ; popq %rbp ; ret @@ -25,7 +27,10 @@ block0(v0: i8, v1: i8): ; block1: ; offset 0x4 ; movq %rdi, %rax ; cbtw -; idivb %sil ; trap: int_divz +; testb %sil, %sil +; jne 0x14 +; ud2 ; trap: int_divz +; idivb %sil ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp ; retq @@ -42,7 +47,9 @@ block0(v0: i16, v1: i16): ; block0: ; movq %rdi, %rax ; cwd %ax, %dx -; idiv %ax, %dx, %si, %ax, %dx +; testw %si, %si +; jnz ; ud2 int_divz ; +; idiv %ax, %dx, %si, %ax, %dx ; trap=int_ovf ; movq %rbp, %rsp ; popq %rbp ; ret @@ -54,7 +61,10 @@ block0(v0: i16, v1: i16): ; block1: ; offset 0x4 ; movq %rdi, %rax ; cwtd -; idivw %si ; trap: int_divz +; testw %si, %si +; jne 0x14 +; ud2 ; trap: int_divz +; idivw %si ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp ; retq @@ -71,7 +81,9 @@ block0(v0: i32, v1: i32): ; block0: ; movq %rdi, %rax ; cdq %eax, %edx -; idiv %eax, %edx, %esi, %eax, %edx +; testl %esi, %esi +; jnz ; ud2 int_divz ; +; idiv %eax, %edx, %esi, %eax, %edx ; trap=int_ovf ; movq %rbp, %rsp ; popq %rbp ; ret @@ -83,7 +95,10 @@ block0(v0: i32, v1: i32): ; block1: ; offset 0x4 ; movq %rdi, %rax ; cltd -; idivl %esi ; trap: int_divz +; testl %esi, %esi +; jne 0x12 +; ud2 ; trap: int_divz +; idivl %esi ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp ; retq @@ -100,7 +115,9 @@ block0(v0: i64, v1: i64): ; block0: ; movq %rdi, %rax ; cqo %rax, %rdx -; idiv %rax, %rdx, %rsi, %rax, %rdx +; testq %rsi, %rsi +; jnz ; ud2 int_divz ; +; idiv %rax, %rdx, %rsi, %rax, %rdx ; trap=int_ovf ; movq %rbp, %rsp ; popq %rbp ; ret @@ -112,7 +129,10 @@ block0(v0: i64, v1: i64): ; block1: ; offset 0x4 ; movq %rdi, %rax ; cqto -; idivq %rsi ; trap: int_divz +; testq %rsi, %rsi +; jne 0x14 +; ud2 ; trap: int_divz +; idivq %rsi ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp ; retq diff --git a/cranelift/filetests/filetests/isa/x64/srem-checked.clif b/cranelift/filetests/filetests/isa/x64/srem-checked.clif deleted file mode 100644 index e4bb829b3a..0000000000 --- a/cranelift/filetests/filetests/isa/x64/srem-checked.clif +++ /dev/null @@ -1,300 +0,0 @@ -test compile precise-output -set avoid_div_traps=true -target x86_64 - -function %f1(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cbw %al, %al -; testb %sil, %sil -; jnz ; ud2 int_divz ; -; checked_srem_seq %al, %sil, %al -; shrq $8, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cbtw -; testb %sil, %sil -; jne 0x14 -; ud2 ; trap: int_divz -; cmpb $0xff, %sil -; jne 0x28 -; movl $0, %eax -; jmp 0x2b -; idivb %sil ; trap: int_divz -; shrq $8, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f2(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; testw %si, %si -; jnz ; ud2 int_divz ; -; movq %rdi, %rax -; cwd %ax, %dx -; checked_srem_seq %ax, %dx, %si, %ax, %dx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; testw %si, %si -; jne 0xf -; ud2 ; trap: int_divz -; movq %rdi, %rax -; cwtd -; cmpw $-1, %si -; jne 0x28 -; movl $0, %edx -; jmp 0x2b -; idivw %si ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f3(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; testl %esi, %esi -; jnz ; ud2 int_divz ; -; movq %rdi, %rax -; cdq %eax, %edx -; checked_srem_seq %eax, %edx, %esi, %eax, %edx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; testl %esi, %esi -; jne 0xe -; ud2 ; trap: int_divz -; movq %rdi, %rax -; cltd -; cmpl $-1, %esi -; jne 0x25 -; movl $0, %edx -; jmp 0x27 -; idivl %esi ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f4(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; testq %rsi, %rsi -; jnz ; ud2 int_divz ; -; movq %rdi, %rax -; cqo %rax, %rdx -; checked_srem_seq %rax, %rdx, %rsi, %rax, %rdx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; testq %rsi, %rsi -; jne 0xf -; ud2 ; trap: int_divz -; movq %rdi, %rax -; cqto -; cmpq $-1, %rsi -; jne 0x28 -; movl $0, %edx -; jmp 0x2b -; idivq %rsi ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 17 - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cbw %al, %al -; movl $17, %edx -; idiv %al, %dl, %al -; shrq $8, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cbtw -; movl $0x11, %edx -; idivb %dl ; trap: int_divz -; shrq $8, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 17 - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cwd %ax, %dx -; movl $17, %r8d -; idiv %ax, %dx, %r8w, %ax, %dx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cwtd -; movl $0x11, %r8d -; idivw %r8w ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 17 - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cdq %eax, %edx -; movl $17, %r8d -; idiv %eax, %edx, %r8d, %eax, %edx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cltd -; movl $0x11, %r8d -; idivl %r8d ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 17 - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cqo %rax, %rdx -; movl $17, %r8d -; idiv %rax, %rdx, %r8, %rax, %rdx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cqto -; movl $0x11, %r8d -; idivq %r8 ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - diff --git a/cranelift/filetests/filetests/isa/x64/srem.clif b/cranelift/filetests/filetests/isa/x64/srem.clif index 973a9f0bee..14ed4efeed 100644 --- a/cranelift/filetests/filetests/isa/x64/srem.clif +++ b/cranelift/filetests/filetests/isa/x64/srem.clif @@ -155,7 +155,7 @@ block0(v0: i8): ; movq %rdi, %rax ; cbw %al, %al ; movl $17, %edx -; idiv %al, %dl, %al +; idiv %al, %dl, %al ; trap=int_divz ; shrq $8, %rax, %rax ; movq %rbp, %rsp ; popq %rbp @@ -189,7 +189,7 @@ block0(v0: i16): ; movq %rdi, %rax ; cwd %ax, %dx ; movl $17, %r8d -; idiv %ax, %dx, %r8w, %ax, %dx +; idiv %ax, %dx, %r8w, %ax, %dx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -223,7 +223,7 @@ block0(v0: i32): ; movq %rdi, %rax ; cdq %eax, %edx ; movl $17, %r8d -; idiv %eax, %edx, %r8d, %eax, %edx +; idiv %eax, %edx, %r8d, %eax, %edx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -257,7 +257,7 @@ block0(v0: i64): ; movq %rdi, %rax ; cqo %rax, %rdx ; movl $17, %r8d -; idiv %rax, %rdx, %r8, %rax, %rdx +; idiv %rax, %rdx, %r8, %rax, %rdx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp diff --git a/cranelift/filetests/filetests/isa/x64/udiv-checked.clif b/cranelift/filetests/filetests/isa/x64/udiv-checked.clif deleted file mode 100644 index 4eec243fb1..0000000000 --- a/cranelift/filetests/filetests/isa/x64/udiv-checked.clif +++ /dev/null @@ -1,264 +0,0 @@ -test compile precise-output -set avoid_div_traps=true -target x86_64 - -function %f1(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movzbl %dil, %eax -; testb %sil, %sil -; jnz ; ud2 int_divz ; -; div %al, %sil, %al -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movzbl %dil, %eax -; testb %sil, %sil -; jne 0x13 -; ud2 ; trap: int_divz -; divb %sil ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f2(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testw %si, %si -; jnz ; ud2 int_divz ; -; div %ax, %dx, %si, %ax, %dx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testw %si, %si -; jne 0x15 -; ud2 ; trap: int_divz -; divw %si ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f3(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testl %esi, %esi -; jnz ; ud2 int_divz ; -; div %eax, %edx, %esi, %eax, %edx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testl %esi, %esi -; jne 0x14 -; ud2 ; trap: int_divz -; divl %esi ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f4(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testq %rsi, %rsi -; jnz ; ud2 int_divz ; -; div %rax, %rdx, %rsi, %rax, %rdx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testq %rsi, %rsi -; jne 0x15 -; ud2 ; trap: int_divz -; divq %rsi ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 17 - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movzbl %dil, %eax -; movl $17, %edx -; div %al, %dl, %al -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movzbl %dil, %eax -; movl $0x11, %edx -; divb %dl ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 17 - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %ax, %dx, %r8w, %ax, %dx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divw %r8w ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 17 - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %eax, %edx, %r8d, %eax, %edx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divl %r8d ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 17 - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %rax, %rdx, %r8, %rax, %rdx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divq %r8 ; trap: int_divz -; movq %rbp, %rsp -; popq %rbp -; retq - diff --git a/cranelift/filetests/filetests/isa/x64/udiv.clif b/cranelift/filetests/filetests/isa/x64/udiv.clif index 391abff20a..bf3ec0820f 100644 --- a/cranelift/filetests/filetests/isa/x64/udiv.clif +++ b/cranelift/filetests/filetests/isa/x64/udiv.clif @@ -12,7 +12,7 @@ block0(v0: i8, v1: i8): ; movq %rsp, %rbp ; block0: ; movzbl %dil, %eax -; div %al, %sil, %al +; div %al, %sil, %al ; trap=int_divz ; movq %rbp, %rsp ; popq %rbp ; ret @@ -40,7 +40,7 @@ block0(v0: i16, v1: i16): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %ax, %dx, %si, %ax, %dx +; div %ax, %dx, %si, %ax, %dx ; trap=int_divz ; movq %rbp, %rsp ; popq %rbp ; ret @@ -69,7 +69,7 @@ block0(v0: i32, v1: i32): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %eax, %edx, %esi, %eax, %edx +; div %eax, %edx, %esi, %eax, %edx ; trap=int_divz ; movq %rbp, %rsp ; popq %rbp ; ret @@ -98,7 +98,7 @@ block0(v0: i64, v1: i64): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %rax, %rdx, %rsi, %rax, %rdx +; div %rax, %rdx, %rsi, %rax, %rdx ; trap=int_divz ; movq %rbp, %rsp ; popq %rbp ; ret diff --git a/cranelift/filetests/filetests/isa/x64/udivrem.clif b/cranelift/filetests/filetests/isa/x64/udivrem.clif index d0368a430b..4d0708e899 100644 --- a/cranelift/filetests/filetests/isa/x64/udivrem.clif +++ b/cranelift/filetests/filetests/isa/x64/udivrem.clif @@ -15,10 +15,10 @@ block0(v0: i8, v1: i8): ; movq %rsp, %rbp ; block0: ; movzbl %dil, %eax -; div %al, %sil, %al +; div %al, %sil, %al ; trap=int_divz ; movq %rax, %r11 ; movzbl %dil, %eax -; div %al, %sil, %al +; div %al, %sil, %al ; trap=int_divz ; movq %rax, %rdx ; shrq $8, %rdx, %rdx ; movq %r11, %rax @@ -56,11 +56,11 @@ block0(v0: i16, v1: i16): ; block0: ; xorq %rdx, %rdx, %rdx ; movq %rdi, %rax -; div %ax, %dx, %si, %ax, %dx +; div %ax, %dx, %si, %ax, %dx ; trap=int_divz ; movq %rax, %rcx ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %ax, %dx, %si, %ax, %dx +; div %ax, %dx, %si, %ax, %dx ; trap=int_divz ; movq %rcx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -96,11 +96,11 @@ block0(v0: i32, v1: i32): ; block0: ; xorq %rdx, %rdx, %rdx ; movq %rdi, %rax -; div %eax, %edx, %esi, %eax, %edx +; div %eax, %edx, %esi, %eax, %edx ; trap=int_divz ; movq %rax, %rcx ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %eax, %edx, %esi, %eax, %edx +; div %eax, %edx, %esi, %eax, %edx ; trap=int_divz ; movq %rcx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -136,11 +136,11 @@ block0(v0: i64, v1: i64): ; block0: ; xorq %rdx, %rdx, %rdx ; movq %rdi, %rax -; div %rax, %rdx, %rsi, %rax, %rdx +; div %rax, %rdx, %rsi, %rax, %rdx ; trap=int_divz ; movq %rax, %rcx ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %rax, %rdx, %rsi, %rax, %rdx +; div %rax, %rdx, %rsi, %rax, %rdx ; trap=int_divz ; movq %rcx, %rax ; movq %rbp, %rsp ; popq %rbp diff --git a/cranelift/filetests/filetests/isa/x64/urem-checked.clif b/cranelift/filetests/filetests/isa/x64/urem-checked.clif deleted file mode 100644 index df6e20e1c3..0000000000 --- a/cranelift/filetests/filetests/isa/x64/urem-checked.clif +++ /dev/null @@ -1,280 +0,0 @@ -test compile precise-output -set avoid_div_traps=true -target x86_64 - -function %f1(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movzbl %dil, %eax -; testb %sil, %sil -; jnz ; ud2 int_divz ; -; div %al, %sil, %al -; shrq $8, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movzbl %dil, %eax -; testb %sil, %sil -; jne 0x13 -; ud2 ; trap: int_divz -; divb %sil ; trap: int_divz -; shrq $8, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f2(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testw %si, %si -; jnz ; ud2 int_divz ; -; div %ax, %dx, %si, %ax, %dx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testw %si, %si -; jne 0x15 -; ud2 ; trap: int_divz -; divw %si ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f3(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testl %esi, %esi -; jnz ; ud2 int_divz ; -; div %eax, %edx, %esi, %eax, %edx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testl %esi, %esi -; jne 0x14 -; ud2 ; trap: int_divz -; divl %esi ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f4(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testq %rsi, %rsi -; jnz ; ud2 int_divz ; -; div %rax, %rdx, %rsi, %rax, %rdx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testq %rsi, %rsi -; jne 0x15 -; ud2 ; trap: int_divz -; divq %rsi ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 17 - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movzbl %dil, %eax -; movl $17, %edx -; div %al, %dl, %al -; shrq $8, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movzbl %dil, %eax -; movl $0x11, %edx -; divb %dl ; trap: int_divz -; shrq $8, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 17 - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %ax, %dx, %r8w, %ax, %dx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divw %r8w ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 17 - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %eax, %edx, %r8d, %eax, %edx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divl %r8d ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 17 - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %rax, %rdx, %r8, %rax, %rdx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divq %r8 ; trap: int_divz -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - diff --git a/cranelift/filetests/filetests/isa/x64/urem.clif b/cranelift/filetests/filetests/isa/x64/urem.clif index 63daeaade0..7cf1970413 100644 --- a/cranelift/filetests/filetests/isa/x64/urem.clif +++ b/cranelift/filetests/filetests/isa/x64/urem.clif @@ -12,7 +12,7 @@ block0(v0: i8, v1: i8): ; movq %rsp, %rbp ; block0: ; movzbl %dil, %eax -; div %al, %sil, %al +; div %al, %sil, %al ; trap=int_divz ; shrq $8, %rax, %rax ; movq %rbp, %rsp ; popq %rbp @@ -42,7 +42,7 @@ block0(v0: i16, v1: i16): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %ax, %dx, %si, %ax, %dx +; div %ax, %dx, %si, %ax, %dx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -73,7 +73,7 @@ block0(v0: i32, v1: i32): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %eax, %edx, %esi, %eax, %edx +; div %eax, %edx, %esi, %eax, %edx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -104,7 +104,7 @@ block0(v0: i64, v1: i64): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %rax, %rdx, %rsi, %rax, %rdx +; div %rax, %rdx, %rsi, %rax, %rdx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp diff --git a/cranelift/filetests/filetests/runtests/div-checks.clif b/cranelift/filetests/filetests/runtests/div-checks.clif index 3a854adbad..2c385fa197 100644 --- a/cranelift/filetests/filetests/runtests/div-checks.clif +++ b/cranelift/filetests/filetests/runtests/div-checks.clif @@ -1,13 +1,8 @@ test run -set avoid_div_traps=false target aarch64 target s390x target x86_64 -target riscv64 - - -; Tests that the `avoid_div_traps` flag prevents a trap when {s,u}rem is called -; with INT_MIN % -1. +target riscv64 function %i8(i8, i8) -> i8 { block0(v0: i8, v1: i8): diff --git a/cranelift/filetests/filetests/runtests/srem.clif b/cranelift/filetests/filetests/runtests/srem.clif index 96b0f95fe9..6d0a6217f9 100644 --- a/cranelift/filetests/filetests/runtests/srem.clif +++ b/cranelift/filetests/filetests/runtests/srem.clif @@ -1,7 +1,5 @@ test interpret test run -; Test these inputs without div traps, it shouldn't affect normal inputs -set avoid_div_traps target aarch64 target s390x target x86_64 diff --git a/cranelift/filetests/filetests/runtests/urem.clif b/cranelift/filetests/filetests/runtests/urem.clif index f0b6bb0673..8ab17fc4ef 100644 --- a/cranelift/filetests/filetests/runtests/urem.clif +++ b/cranelift/filetests/filetests/runtests/urem.clif @@ -4,11 +4,6 @@ target aarch64 target s390x target x86_64 target riscv64 -; Test these inputs without div traps, it shouldn't affect normal inputs -set avoid_div_traps -target aarch64 -target s390x -target x86_64 function %urem_i64(i64, i64) -> i64 { block0(v0: i64,v1: i64): diff --git a/crates/cranelift-shared/src/isa_builder.rs b/crates/cranelift-shared/src/isa_builder.rs index d15abe9929..ad16bb8e85 100644 --- a/crates/cranelift-shared/src/isa_builder.rs +++ b/crates/cranelift-shared/src/isa_builder.rs @@ -23,12 +23,6 @@ impl IsaBuilder { pub fn new(lookup: fn(Triple) -> Result>) -> Self { let mut flags = settings::builder(); - // There are two possible traps for division, and this way - // we get the proper one if code traps. - flags - .enable("avoid_div_traps") - .expect("should be valid flag"); - // We don't use probestack as a stack limit mechanism flags .set("enable_probestack", "false") diff --git a/crates/runtime/src/traphandlers/macos.rs b/crates/runtime/src/traphandlers/macos.rs index b8047e03a2..da2cdac91a 100644 --- a/crates/runtime/src/traphandlers/macos.rs +++ b/crates/runtime/src/traphandlers/macos.rs @@ -244,7 +244,7 @@ unsafe fn handle_exception(request: &mut ExceptionRequest) -> bool { // First make sure that this exception is one that we actually expect to // get raised by wasm code. All other exceptions we safely ignore. match request.body.exception as u32 { - EXC_BAD_ACCESS | EXC_BAD_INSTRUCTION => {} + EXC_BAD_ACCESS | EXC_BAD_INSTRUCTION | EXC_ARITHMETIC => {} _ => return false, } @@ -424,7 +424,7 @@ pub fn lazy_per_thread_init() { let this_thread = mach_thread_self(); let kret = thread_set_exception_ports( this_thread, - EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION, + EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC, WASMTIME_PORT, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, mach_addons::THREAD_STATE_NONE, diff --git a/crates/wasmtime/src/engine.rs b/crates/wasmtime/src/engine.rs index 9523278f54..de7ba922d8 100644 --- a/crates/wasmtime/src/engine.rs +++ b/crates/wasmtime/src/engine.rs @@ -350,7 +350,7 @@ impl Engine { /// currently rely on the compiler informing us of all settings, including /// those disabled. Settings then fall in a few buckets: /// - /// * Some settings must be enabled, such as `avoid_div_traps`. + /// * Some settings must be enabled, such as `preserve_frame_pointers`. /// * Some settings must have a particular value, such as /// `libcall_call_conv`. /// * Some settings do not matter as to their value, such as `opt_level`. @@ -364,7 +364,6 @@ impl Engine { // These settings must all have be enabled, since their value // can affect the way the generated code performs or behaves at // runtime. - "avoid_div_traps" => *value == FlagValue::Bool(true), "libcall_call_conv" => *value == FlagValue::Enum("isa_default".into()), "preserve_frame_pointers" => *value == FlagValue::Bool(true), "enable_probestack" => *value == FlagValue::Bool(crate::config::probestack_supported(target.architecture)), diff --git a/crates/wasmtime/src/engine/serialization.rs b/crates/wasmtime/src/engine/serialization.rs index 36063b4950..f8b2f83e8e 100644 --- a/crates/wasmtime/src/engine/serialization.rs +++ b/crates/wasmtime/src/engine/serialization.rs @@ -489,9 +489,10 @@ mod test { let engine = Engine::default(); let mut metadata = Metadata::new(&engine); - metadata - .shared_flags - .insert("avoid_div_traps".to_string(), FlagValue::Bool(false)); + metadata.shared_flags.insert( + "preserve_frame_pointers".to_string(), + FlagValue::Bool(false), + ); match metadata.check_compatible(&engine) { Ok(_) => unreachable!(), @@ -500,7 +501,7 @@ mod test { compilation settings of module incompatible with native host Caused by: - setting \"avoid_div_traps\" is configured to Bool(false) which is not supported" + setting \"preserve_frame_pointers\" is configured to Bool(false) which is not supported" )), } diff --git a/tests/all/traps.rs b/tests/all/traps.rs index ae62280c6e..ccceb71163 100644 --- a/tests/all/traps.rs +++ b/tests/all/traps.rs @@ -1185,3 +1185,97 @@ fn host_return_error_no_backtrace() -> Result<()> { assert!(f.call(&mut store, ()).is_err()); Ok(()) } + +#[test] +fn div_plus_load_reported_right() -> Result<()> { + let engine = Engine::default(); + let mut store = Store::new(&engine, ()); + let module = Module::new( + &engine, + r#" + (module + (memory (export "memory") 1) + (func (export "i32.div_s") (param i32 i32) (result i32) + (i32.div_s (local.get 0) (i32.load (local.get 1)))) + (func (export "i32.div_u") (param i32 i32) (result i32) + (i32.div_u (local.get 0) (i32.load (local.get 1)))) + (func (export "i32.rem_s") (param i32 i32) (result i32) + (i32.rem_s (local.get 0) (i32.load (local.get 1)))) + (func (export "i32.rem_u") (param i32 i32) (result i32) + (i32.rem_u (local.get 0) (i32.load (local.get 1)))) + ) + "#, + )?; + let instance = Instance::new(&mut store, &module, &[])?; + let memory = instance.get_memory(&mut store, "memory").unwrap(); + let i32_div_s = instance.get_typed_func::<(i32, i32), i32>(&mut store, "i32.div_s")?; + let i32_div_u = instance.get_typed_func::<(u32, u32), u32>(&mut store, "i32.div_u")?; + let i32_rem_s = instance.get_typed_func::<(i32, i32), i32>(&mut store, "i32.rem_s")?; + let i32_rem_u = instance.get_typed_func::<(u32, u32), u32>(&mut store, "i32.rem_u")?; + + memory.write(&mut store, 0, &1i32.to_le_bytes()).unwrap(); + memory.write(&mut store, 4, &0i32.to_le_bytes()).unwrap(); + memory.write(&mut store, 8, &(-1i32).to_le_bytes()).unwrap(); + + assert_eq!(i32_div_s.call(&mut store, (100, 0))?, 100); + assert_eq!(i32_div_u.call(&mut store, (101, 0))?, 101); + assert_eq!(i32_rem_s.call(&mut store, (102, 0))?, 0); + assert_eq!(i32_rem_u.call(&mut store, (103, 0))?, 0); + + assert_trap( + i32_div_s.call(&mut store, (100, 4)), + Trap::IntegerDivisionByZero, + ); + assert_trap( + i32_div_u.call(&mut store, (100, 4)), + Trap::IntegerDivisionByZero, + ); + assert_trap( + i32_rem_s.call(&mut store, (100, 4)), + Trap::IntegerDivisionByZero, + ); + assert_trap( + i32_rem_u.call(&mut store, (100, 4)), + Trap::IntegerDivisionByZero, + ); + + assert_trap( + i32_div_s.call(&mut store, (i32::MIN, 8)), + Trap::IntegerOverflow, + ); + assert_eq!(i32_rem_s.call(&mut store, (i32::MIN, 8))?, 0); + + assert_trap( + i32_div_s.call(&mut store, (100, 100_000)), + Trap::MemoryOutOfBounds, + ); + assert_trap( + i32_div_u.call(&mut store, (100, 100_000)), + Trap::MemoryOutOfBounds, + ); + assert_trap( + i32_rem_s.call(&mut store, (100, 100_000)), + Trap::MemoryOutOfBounds, + ); + assert_trap( + i32_rem_u.call(&mut store, (100, 100_000)), + Trap::MemoryOutOfBounds, + ); + + return Ok(()); + + #[track_caller] + fn assert_trap(result: Result, expected: Trap) { + match result { + Ok(_) => panic!("expected failure"), + Err(e) => { + if let Some(code) = e.downcast_ref::() { + if *code == expected { + return; + } + } + panic!("unexpected error {e:?}"); + } + } + } +} diff --git a/winch/codegen/src/isa/x64/asm.rs b/winch/codegen/src/isa/x64/asm.rs index f60dde22d6..c6a2548c86 100644 --- a/winch/codegen/src/isa/x64/asm.rs +++ b/winch/codegen/src/isa/x64/asm.rs @@ -282,34 +282,13 @@ impl Assembler { /// caller has correctly allocated the dividend as `(rdx:rax)` and /// accounted for the quotient to be stored in `rax`. pub fn div(&mut self, divisor: Reg, dst: (Reg, Reg), kind: DivKind, size: OperandSize) { - match kind { - // Signed division goes through a pseudo-instruction to validate - // the divisor followed by a sign extension to initialize `rdx`. + let trap = match kind { + // Signed division has two trapping conditions, integer overflow and + // divide-by-zero. Check for divide-by-zero explicitly and let the + // hardware detect overflow. + // + // The dividend is sign extended to initialize `rdx`. DivKind::Signed => { - if size == OperandSize::S64 { - self.emit(Inst::ValidateSdivDivisor64 { - dividend: dst.0.into(), - divisor: divisor.into(), - tmp: regs::scratch().into(), - }); - } else { - self.emit(Inst::ValidateSdivDivisor { - dividend: dst.0.into(), - divisor: divisor.into(), - size: size.into(), - }); - } - self.emit(Inst::SignExtendData { - size: size.into(), - src: dst.0.into(), - dst: dst.1.into(), - }); - } - - // Unsigned division only needs to check for 0 and then the `rdx` - // divisor_hi is initialized with zero through an xor-against-itself - // op. - DivKind::Unsigned => { self.emit(Inst::CmpRmiR { size: size.into(), src: GprMemImm::new(RegMemImm::imm(0)).unwrap(), @@ -320,6 +299,20 @@ impl Assembler { cc: CC::Z, trap_code: TrapCode::IntegerDivisionByZero, }); + self.emit(Inst::SignExtendData { + size: size.into(), + src: dst.0.into(), + dst: dst.1.into(), + }); + TrapCode::IntegerOverflow + } + + // Unsigned division only traps in one case, on divide-by-zero, so + // defer that to the trap opcode. + // + // The divisor_hi reg is initialized with zero through an + // xor-against-itself op. + DivKind::Unsigned => { self.emit(Inst::AluRmiR { size: size.into(), op: AluRmiROpcode::Xor, @@ -327,11 +320,13 @@ impl Assembler { src2: dst.1.into(), dst: dst.1.into(), }); + TrapCode::IntegerDivisionByZero } - } + }; self.emit(Inst::Div { sign: kind.into(), size: size.into(), + trap, divisor: GprMem::new(RegMem::reg(divisor.into())).unwrap(), dividend_lo: dst.0.into(), dividend_hi: dst.1.into(), @@ -348,17 +343,6 @@ impl Assembler { /// caller has correctly allocated the dividend as `(rdx:rax)` and /// accounted for the remainder to be stored in `rdx`. pub fn rem(&mut self, divisor: Reg, dst: (Reg, Reg), kind: RemKind, size: OperandSize) { - // First check for zero and explicitly trap. - self.emit(Inst::CmpRmiR { - size: size.into(), - src: GprMemImm::new(RegMemImm::imm(0)).unwrap(), - dst: divisor.into(), - opcode: CmpOpcode::Cmp, - }); - self.emit(Inst::TrapIf { - cc: CC::Z, - trap_code: TrapCode::IntegerDivisionByZero, - }); match kind { // Signed remainder goes through a pseudo-instruction which has // some internal branching. The `dividend_hi`, or `rdx`, is @@ -391,6 +375,7 @@ impl Assembler { }); self.emit(Inst::Div { sign: DivSignedness::Unsigned, + trap: TrapCode::IntegerDivisionByZero, size: size.into(), divisor: GprMem::new(RegMem::reg(divisor.into())).unwrap(), dividend_lo: dst.0.into(), diff --git a/winch/filetests/filetests/x64/i32_divs/const.wat b/winch/filetests/filetests/x64/i32_divs/const.wat index c32078198f..cd9be27f2d 100644 --- a/winch/filetests/filetests/x64/i32_divs/const.wat +++ b/winch/filetests/filetests/x64/i32_divs/const.wat @@ -14,12 +14,7 @@ ;; e: 83f900 cmp ecx, 0 ;; 11: 0f8502000000 jne 0x19 ;; 17: 0f0b ud2 -;; 19: 83f9ff cmp ecx, -1 -;; 1c: 0f850e000000 jne 0x30 -;; 22: 81f800000080 cmp eax, 0x80000000 -;; 28: 0f8502000000 jne 0x30 -;; 2e: 0f0b ud2 -;; 30: 99 cdq -;; 31: f7f9 idiv ecx -;; 33: 5d pop rbp -;; 34: c3 ret +;; 19: 99 cdq +;; 1a: f7f9 idiv ecx +;; 1c: 5d pop rbp +;; 1d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divs/one_zero.wat b/winch/filetests/filetests/x64/i32_divs/one_zero.wat index 1ef0d78855..6b3094ea65 100644 --- a/winch/filetests/filetests/x64/i32_divs/one_zero.wat +++ b/winch/filetests/filetests/x64/i32_divs/one_zero.wat @@ -14,12 +14,7 @@ ;; e: 83f900 cmp ecx, 0 ;; 11: 0f8502000000 jne 0x19 ;; 17: 0f0b ud2 -;; 19: 83f9ff cmp ecx, -1 -;; 1c: 0f850e000000 jne 0x30 -;; 22: 81f800000080 cmp eax, 0x80000000 -;; 28: 0f8502000000 jne 0x30 -;; 2e: 0f0b ud2 -;; 30: 99 cdq -;; 31: f7f9 idiv ecx -;; 33: 5d pop rbp -;; 34: c3 ret +;; 19: 99 cdq +;; 1a: f7f9 idiv ecx +;; 1c: 5d pop rbp +;; 1d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divs/overflow.wat b/winch/filetests/filetests/x64/i32_divs/overflow.wat index 7f2499a1b8..33c7d05bb9 100644 --- a/winch/filetests/filetests/x64/i32_divs/overflow.wat +++ b/winch/filetests/filetests/x64/i32_divs/overflow.wat @@ -14,12 +14,7 @@ ;; e: 83f900 cmp ecx, 0 ;; 11: 0f8502000000 jne 0x19 ;; 17: 0f0b ud2 -;; 19: 83f9ff cmp ecx, -1 -;; 1c: 0f850e000000 jne 0x30 -;; 22: 81f800000080 cmp eax, 0x80000000 -;; 28: 0f8502000000 jne 0x30 -;; 2e: 0f0b ud2 -;; 30: 99 cdq -;; 31: f7f9 idiv ecx -;; 33: 5d pop rbp -;; 34: c3 ret +;; 19: 99 cdq +;; 1a: f7f9 idiv ecx +;; 1c: 5d pop rbp +;; 1d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divs/params.wat b/winch/filetests/filetests/x64/i32_divs/params.wat index ec999077ba..cc3c25b8c1 100644 --- a/winch/filetests/filetests/x64/i32_divs/params.wat +++ b/winch/filetests/filetests/x64/i32_divs/params.wat @@ -17,13 +17,8 @@ ;; 16: 83f900 cmp ecx, 0 ;; 19: 0f8502000000 jne 0x21 ;; 1f: 0f0b ud2 -;; 21: 83f9ff cmp ecx, -1 -;; 24: 0f850e000000 jne 0x38 -;; 2a: 81f800000080 cmp eax, 0x80000000 -;; 30: 0f8502000000 jne 0x38 -;; 36: 0f0b ud2 -;; 38: 99 cdq -;; 39: f7f9 idiv ecx -;; 3b: 4883c408 add rsp, 8 -;; 3f: 5d pop rbp -;; 40: c3 ret +;; 21: 99 cdq +;; 22: f7f9 idiv ecx +;; 24: 4883c408 add rsp, 8 +;; 28: 5d pop rbp +;; 29: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divs/zero_zero.wat b/winch/filetests/filetests/x64/i32_divs/zero_zero.wat index 807b7f7eb8..7158174ad6 100644 --- a/winch/filetests/filetests/x64/i32_divs/zero_zero.wat +++ b/winch/filetests/filetests/x64/i32_divs/zero_zero.wat @@ -14,12 +14,7 @@ ;; e: 83f900 cmp ecx, 0 ;; 11: 0f8502000000 jne 0x19 ;; 17: 0f0b ud2 -;; 19: 83f9ff cmp ecx, -1 -;; 1c: 0f850e000000 jne 0x30 -;; 22: 81f800000080 cmp eax, 0x80000000 -;; 28: 0f8502000000 jne 0x30 -;; 2e: 0f0b ud2 -;; 30: 99 cdq -;; 31: f7f9 idiv ecx -;; 33: 5d pop rbp -;; 34: c3 ret +;; 19: 99 cdq +;; 1a: f7f9 idiv ecx +;; 1c: 5d pop rbp +;; 1d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divu/const.wat b/winch/filetests/filetests/x64/i32_divu/const.wat index 3ba1c3dbb8..a2bbfd0140 100644 --- a/winch/filetests/filetests/x64/i32_divu/const.wat +++ b/winch/filetests/filetests/x64/i32_divu/const.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b90a000000 mov ecx, 0xa ;; 9: b814000000 mov eax, 0x14 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 5d pop rbp -;; 1e: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divu/one_zero.wat b/winch/filetests/filetests/x64/i32_divu/one_zero.wat index 938f787785..3f3de081ea 100644 --- a/winch/filetests/filetests/x64/i32_divu/one_zero.wat +++ b/winch/filetests/filetests/x64/i32_divu/one_zero.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b801000000 mov eax, 1 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 5d pop rbp -;; 1e: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divu/params.wat b/winch/filetests/filetests/x64/i32_divu/params.wat index e732e05bc8..a566659c18 100644 --- a/winch/filetests/filetests/x64/i32_divu/params.wat +++ b/winch/filetests/filetests/x64/i32_divu/params.wat @@ -14,11 +14,8 @@ ;; c: 893424 mov dword ptr [rsp], esi ;; f: 8b0c24 mov ecx, dword ptr [rsp] ;; 12: 8b442404 mov eax, dword ptr [rsp + 4] -;; 16: 83f900 cmp ecx, 0 -;; 19: 0f8502000000 jne 0x21 -;; 1f: 0f0b ud2 -;; 21: 31d2 xor edx, edx -;; 23: f7f1 div ecx -;; 25: 4883c408 add rsp, 8 -;; 29: 5d pop rbp -;; 2a: c3 ret +;; 16: 31d2 xor edx, edx +;; 18: f7f1 div ecx +;; 1a: 4883c408 add rsp, 8 +;; 1e: 5d pop rbp +;; 1f: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divu/signed.wat b/winch/filetests/filetests/x64/i32_divu/signed.wat index ce39cff780..a0b91f279f 100644 --- a/winch/filetests/filetests/x64/i32_divu/signed.wat +++ b/winch/filetests/filetests/x64/i32_divu/signed.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b9ffffffff mov ecx, 0xffffffff ;; 9: b8ffffffff mov eax, 0xffffffff -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 5d pop rbp -;; 1e: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divu/zero_zero.wat b/winch/filetests/filetests/x64/i32_divu/zero_zero.wat index 418d084329..e78558a668 100644 --- a/winch/filetests/filetests/x64/i32_divu/zero_zero.wat +++ b/winch/filetests/filetests/x64/i32_divu/zero_zero.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b800000000 mov eax, 0 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 5d pop rbp -;; 1e: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i32_rems/const.wat b/winch/filetests/filetests/x64/i32_rems/const.wat index 1edb0d8962..221b810c52 100644 --- a/winch/filetests/filetests/x64/i32_rems/const.wat +++ b/winch/filetests/filetests/x64/i32_rems/const.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b905000000 mov ecx, 5 ;; 9: b807000000 mov eax, 7 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 99 cdq -;; 1a: 83f9ff cmp ecx, -1 -;; 1d: 0f850a000000 jne 0x2d -;; 23: ba00000000 mov edx, 0 -;; 28: e902000000 jmp 0x2f -;; 2d: f7f9 idiv ecx -;; 2f: 4889d0 mov rax, rdx -;; 32: 5d pop rbp -;; 33: c3 ret +;; e: 99 cdq +;; f: 83f9ff cmp ecx, -1 +;; 12: 0f850a000000 jne 0x22 +;; 18: ba00000000 mov edx, 0 +;; 1d: e902000000 jmp 0x24 +;; 22: f7f9 idiv ecx +;; 24: 4889d0 mov rax, rdx +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i32_rems/one_zero.wat b/winch/filetests/filetests/x64/i32_rems/one_zero.wat index 3b618c3c10..d8569b3c09 100644 --- a/winch/filetests/filetests/x64/i32_rems/one_zero.wat +++ b/winch/filetests/filetests/x64/i32_rems/one_zero.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b801000000 mov eax, 1 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 99 cdq -;; 1a: 83f9ff cmp ecx, -1 -;; 1d: 0f850a000000 jne 0x2d -;; 23: ba00000000 mov edx, 0 -;; 28: e902000000 jmp 0x2f -;; 2d: f7f9 idiv ecx -;; 2f: 4889d0 mov rax, rdx -;; 32: 5d pop rbp -;; 33: c3 ret +;; e: 99 cdq +;; f: 83f9ff cmp ecx, -1 +;; 12: 0f850a000000 jne 0x22 +;; 18: ba00000000 mov edx, 0 +;; 1d: e902000000 jmp 0x24 +;; 22: f7f9 idiv ecx +;; 24: 4889d0 mov rax, rdx +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i32_rems/overflow.wat b/winch/filetests/filetests/x64/i32_rems/overflow.wat index b42f2ce35d..fcfed25828 100644 --- a/winch/filetests/filetests/x64/i32_rems/overflow.wat +++ b/winch/filetests/filetests/x64/i32_rems/overflow.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b9ffffffff mov ecx, 0xffffffff ;; 9: b800000080 mov eax, 0x80000000 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 99 cdq -;; 1a: 83f9ff cmp ecx, -1 -;; 1d: 0f850a000000 jne 0x2d -;; 23: ba00000000 mov edx, 0 -;; 28: e902000000 jmp 0x2f -;; 2d: f7f9 idiv ecx -;; 2f: 4889d0 mov rax, rdx -;; 32: 5d pop rbp -;; 33: c3 ret +;; e: 99 cdq +;; f: 83f9ff cmp ecx, -1 +;; 12: 0f850a000000 jne 0x22 +;; 18: ba00000000 mov edx, 0 +;; 1d: e902000000 jmp 0x24 +;; 22: f7f9 idiv ecx +;; 24: 4889d0 mov rax, rdx +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i32_rems/params.wat b/winch/filetests/filetests/x64/i32_rems/params.wat index 752f5abee9..cfa264e0ff 100644 --- a/winch/filetests/filetests/x64/i32_rems/params.wat +++ b/winch/filetests/filetests/x64/i32_rems/params.wat @@ -14,16 +14,13 @@ ;; c: 893424 mov dword ptr [rsp], esi ;; f: 8b0c24 mov ecx, dword ptr [rsp] ;; 12: 8b442404 mov eax, dword ptr [rsp + 4] -;; 16: 83f900 cmp ecx, 0 -;; 19: 0f8502000000 jne 0x21 -;; 1f: 0f0b ud2 -;; 21: 99 cdq -;; 22: 83f9ff cmp ecx, -1 -;; 25: 0f850a000000 jne 0x35 -;; 2b: ba00000000 mov edx, 0 -;; 30: e902000000 jmp 0x37 -;; 35: f7f9 idiv ecx -;; 37: 4889d0 mov rax, rdx -;; 3a: 4883c408 add rsp, 8 -;; 3e: 5d pop rbp -;; 3f: c3 ret +;; 16: 99 cdq +;; 17: 83f9ff cmp ecx, -1 +;; 1a: 0f850a000000 jne 0x2a +;; 20: ba00000000 mov edx, 0 +;; 25: e902000000 jmp 0x2c +;; 2a: f7f9 idiv ecx +;; 2c: 4889d0 mov rax, rdx +;; 2f: 4883c408 add rsp, 8 +;; 33: 5d pop rbp +;; 34: c3 ret diff --git a/winch/filetests/filetests/x64/i32_rems/zero_zero.wat b/winch/filetests/filetests/x64/i32_rems/zero_zero.wat index 01358814fb..5fff7d4a68 100644 --- a/winch/filetests/filetests/x64/i32_rems/zero_zero.wat +++ b/winch/filetests/filetests/x64/i32_rems/zero_zero.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b800000000 mov eax, 0 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 99 cdq -;; 1a: 83f9ff cmp ecx, -1 -;; 1d: 0f850a000000 jne 0x2d -;; 23: ba00000000 mov edx, 0 -;; 28: e902000000 jmp 0x2f -;; 2d: f7f9 idiv ecx -;; 2f: 4889d0 mov rax, rdx -;; 32: 5d pop rbp -;; 33: c3 ret +;; e: 99 cdq +;; f: 83f9ff cmp ecx, -1 +;; 12: 0f850a000000 jne 0x22 +;; 18: ba00000000 mov edx, 0 +;; 1d: e902000000 jmp 0x24 +;; 22: f7f9 idiv ecx +;; 24: 4889d0 mov rax, rdx +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i32_remu/const.wat b/winch/filetests/filetests/x64/i32_remu/const.wat index bbcb387cb6..0a48c6c4c7 100644 --- a/winch/filetests/filetests/x64/i32_remu/const.wat +++ b/winch/filetests/filetests/x64/i32_remu/const.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b905000000 mov ecx, 5 ;; 9: b807000000 mov eax, 7 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 4889d0 mov rax, rdx -;; 20: 5d pop rbp -;; 21: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 4889d0 mov rax, rdx +;; 15: 5d pop rbp +;; 16: c3 ret diff --git a/winch/filetests/filetests/x64/i32_remu/one_zero.wat b/winch/filetests/filetests/x64/i32_remu/one_zero.wat index 404264c863..4b3975ab17 100644 --- a/winch/filetests/filetests/x64/i32_remu/one_zero.wat +++ b/winch/filetests/filetests/x64/i32_remu/one_zero.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b801000000 mov eax, 1 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 4889d0 mov rax, rdx -;; 20: 5d pop rbp -;; 21: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 4889d0 mov rax, rdx +;; 15: 5d pop rbp +;; 16: c3 ret diff --git a/winch/filetests/filetests/x64/i32_remu/params.wat b/winch/filetests/filetests/x64/i32_remu/params.wat index 9d6a2e632e..714217d78e 100644 --- a/winch/filetests/filetests/x64/i32_remu/params.wat +++ b/winch/filetests/filetests/x64/i32_remu/params.wat @@ -14,12 +14,9 @@ ;; c: 893424 mov dword ptr [rsp], esi ;; f: 8b0c24 mov ecx, dword ptr [rsp] ;; 12: 8b442404 mov eax, dword ptr [rsp + 4] -;; 16: 83f900 cmp ecx, 0 -;; 19: 0f8502000000 jne 0x21 -;; 1f: 0f0b ud2 -;; 21: 31d2 xor edx, edx -;; 23: f7f1 div ecx -;; 25: 4889d0 mov rax, rdx -;; 28: 4883c408 add rsp, 8 -;; 2c: 5d pop rbp -;; 2d: c3 ret +;; 16: 31d2 xor edx, edx +;; 18: f7f1 div ecx +;; 1a: 4889d0 mov rax, rdx +;; 1d: 4883c408 add rsp, 8 +;; 21: 5d pop rbp +;; 22: c3 ret diff --git a/winch/filetests/filetests/x64/i32_remu/signed.wat b/winch/filetests/filetests/x64/i32_remu/signed.wat index f886e5ac7c..85e83eb0ab 100644 --- a/winch/filetests/filetests/x64/i32_remu/signed.wat +++ b/winch/filetests/filetests/x64/i32_remu/signed.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b9ffffffff mov ecx, 0xffffffff ;; 9: b8ffffffff mov eax, 0xffffffff -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 4889d0 mov rax, rdx -;; 20: 5d pop rbp -;; 21: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 4889d0 mov rax, rdx +;; 15: 5d pop rbp +;; 16: c3 ret diff --git a/winch/filetests/filetests/x64/i32_remu/zero_zero.wat b/winch/filetests/filetests/x64/i32_remu/zero_zero.wat index 4654eafd47..c60bac6e36 100644 --- a/winch/filetests/filetests/x64/i32_remu/zero_zero.wat +++ b/winch/filetests/filetests/x64/i32_remu/zero_zero.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b800000000 mov eax, 0 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 4889d0 mov rax, rdx -;; 20: 5d pop rbp -;; 21: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 4889d0 mov rax, rdx +;; 15: 5d pop rbp +;; 16: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divs/const.wat b/winch/filetests/filetests/x64/i64_divs/const.wat index 840f1ad5f9..4f2d67cb27 100644 --- a/winch/filetests/filetests/x64/i64_divs/const.wat +++ b/winch/filetests/filetests/x64/i64_divs/const.wat @@ -14,14 +14,7 @@ ;; 12: 4883f900 cmp rcx, 0 ;; 16: 0f8502000000 jne 0x1e ;; 1c: 0f0b ud2 -;; 1e: 4883f9ff cmp rcx, -1 -;; 22: 0f8515000000 jne 0x3d -;; 28: 49bb0000000000000080 -;; movabs r11, 0x8000000000000000 -;; 32: 4c39d8 cmp rax, r11 -;; 35: 0f8502000000 jne 0x3d -;; 3b: 0f0b ud2 -;; 3d: 4899 cqo -;; 3f: 48f7f9 idiv rcx -;; 42: 5d pop rbp -;; 43: c3 ret +;; 1e: 4899 cqo +;; 20: 48f7f9 idiv rcx +;; 23: 5d pop rbp +;; 24: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divs/one_zero.wat b/winch/filetests/filetests/x64/i64_divs/one_zero.wat index c274f531e0..3c01564341 100644 --- a/winch/filetests/filetests/x64/i64_divs/one_zero.wat +++ b/winch/filetests/filetests/x64/i64_divs/one_zero.wat @@ -14,14 +14,7 @@ ;; 12: 4883f900 cmp rcx, 0 ;; 16: 0f8502000000 jne 0x1e ;; 1c: 0f0b ud2 -;; 1e: 4883f9ff cmp rcx, -1 -;; 22: 0f8515000000 jne 0x3d -;; 28: 49bb0000000000000080 -;; movabs r11, 0x8000000000000000 -;; 32: 4c39d8 cmp rax, r11 -;; 35: 0f8502000000 jne 0x3d -;; 3b: 0f0b ud2 -;; 3d: 4899 cqo -;; 3f: 48f7f9 idiv rcx -;; 42: 5d pop rbp -;; 43: c3 ret +;; 1e: 4899 cqo +;; 20: 48f7f9 idiv rcx +;; 23: 5d pop rbp +;; 24: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divs/overflow.wat b/winch/filetests/filetests/x64/i64_divs/overflow.wat index 18630116b1..0161afa14a 100644 --- a/winch/filetests/filetests/x64/i64_divs/overflow.wat +++ b/winch/filetests/filetests/x64/i64_divs/overflow.wat @@ -15,14 +15,7 @@ ;; 15: 4883f900 cmp rcx, 0 ;; 19: 0f8502000000 jne 0x21 ;; 1f: 0f0b ud2 -;; 21: 4883f9ff cmp rcx, -1 -;; 25: 0f8515000000 jne 0x40 -;; 2b: 49bb0000000000000080 -;; movabs r11, 0x8000000000000000 -;; 35: 4c39d8 cmp rax, r11 -;; 38: 0f8502000000 jne 0x40 -;; 3e: 0f0b ud2 -;; 40: 4899 cqo -;; 42: 48f7f9 idiv rcx -;; 45: 5d pop rbp -;; 46: c3 ret +;; 21: 4899 cqo +;; 23: 48f7f9 idiv rcx +;; 26: 5d pop rbp +;; 27: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divs/params.wat b/winch/filetests/filetests/x64/i64_divs/params.wat index d52e28cff6..ee29c99b5e 100644 --- a/winch/filetests/filetests/x64/i64_divs/params.wat +++ b/winch/filetests/filetests/x64/i64_divs/params.wat @@ -17,15 +17,8 @@ ;; 1a: 4883f900 cmp rcx, 0 ;; 1e: 0f8502000000 jne 0x26 ;; 24: 0f0b ud2 -;; 26: 4883f9ff cmp rcx, -1 -;; 2a: 0f8515000000 jne 0x45 -;; 30: 49bb0000000000000080 -;; movabs r11, 0x8000000000000000 -;; 3a: 4c39d8 cmp rax, r11 -;; 3d: 0f8502000000 jne 0x45 -;; 43: 0f0b ud2 -;; 45: 4899 cqo -;; 47: 48f7f9 idiv rcx -;; 4a: 4883c410 add rsp, 0x10 -;; 4e: 5d pop rbp -;; 4f: c3 ret +;; 26: 4899 cqo +;; 28: 48f7f9 idiv rcx +;; 2b: 4883c410 add rsp, 0x10 +;; 2f: 5d pop rbp +;; 30: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divs/zero_zero.wat b/winch/filetests/filetests/x64/i64_divs/zero_zero.wat index 4a08ab1053..8206994510 100644 --- a/winch/filetests/filetests/x64/i64_divs/zero_zero.wat +++ b/winch/filetests/filetests/x64/i64_divs/zero_zero.wat @@ -14,14 +14,7 @@ ;; 12: 4883f900 cmp rcx, 0 ;; 16: 0f8502000000 jne 0x1e ;; 1c: 0f0b ud2 -;; 1e: 4883f9ff cmp rcx, -1 -;; 22: 0f8515000000 jne 0x3d -;; 28: 49bb0000000000000080 -;; movabs r11, 0x8000000000000000 -;; 32: 4c39d8 cmp rax, r11 -;; 35: 0f8502000000 jne 0x3d -;; 3b: 0f0b ud2 -;; 3d: 4899 cqo -;; 3f: 48f7f9 idiv rcx -;; 42: 5d pop rbp -;; 43: c3 ret +;; 1e: 4899 cqo +;; 20: 48f7f9 idiv rcx +;; 23: 5d pop rbp +;; 24: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divu/const.wat b/winch/filetests/filetests/x64/i64_divu/const.wat index c44bc60915..ba7bf6507a 100644 --- a/winch/filetests/filetests/x64/i64_divu/const.wat +++ b/winch/filetests/filetests/x64/i64_divu/const.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c10a000000 mov rcx, 0xa ;; b: 48c7c014000000 mov rax, 0x14 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 5d pop rbp -;; 25: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 5d pop rbp +;; 19: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divu/one_zero.wat b/winch/filetests/filetests/x64/i64_divu/one_zero.wat index 7c5accf236..13ed678151 100644 --- a/winch/filetests/filetests/x64/i64_divu/one_zero.wat +++ b/winch/filetests/filetests/x64/i64_divu/one_zero.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c001000000 mov rax, 1 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 5d pop rbp -;; 25: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 5d pop rbp +;; 19: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divu/params.wat b/winch/filetests/filetests/x64/i64_divu/params.wat index 8dfbdbe85b..2c4e612b02 100644 --- a/winch/filetests/filetests/x64/i64_divu/params.wat +++ b/winch/filetests/filetests/x64/i64_divu/params.wat @@ -14,11 +14,8 @@ ;; d: 48893424 mov qword ptr [rsp], rsi ;; 11: 488b0c24 mov rcx, qword ptr [rsp] ;; 15: 488b442408 mov rax, qword ptr [rsp + 8] -;; 1a: 4883f900 cmp rcx, 0 -;; 1e: 0f8502000000 jne 0x26 -;; 24: 0f0b ud2 -;; 26: 4831d2 xor rdx, rdx -;; 29: 48f7f1 div rcx -;; 2c: 4883c410 add rsp, 0x10 -;; 30: 5d pop rbp -;; 31: c3 ret +;; 1a: 4831d2 xor rdx, rdx +;; 1d: 48f7f1 div rcx +;; 20: 4883c410 add rsp, 0x10 +;; 24: 5d pop rbp +;; 25: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divu/signed.wat b/winch/filetests/filetests/x64/i64_divu/signed.wat index af7cc2d208..28208571a6 100644 --- a/winch/filetests/filetests/x64/i64_divu/signed.wat +++ b/winch/filetests/filetests/x64/i64_divu/signed.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c1ffffffff mov rcx, 0xffffffffffffffff ;; b: 48c7c0ffffffff mov rax, 0xffffffffffffffff -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 5d pop rbp -;; 25: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 5d pop rbp +;; 19: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divu/zero_zero.wat b/winch/filetests/filetests/x64/i64_divu/zero_zero.wat index 458e4965af..e8c119a9ae 100644 --- a/winch/filetests/filetests/x64/i64_divu/zero_zero.wat +++ b/winch/filetests/filetests/x64/i64_divu/zero_zero.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c000000000 mov rax, 0 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 5d pop rbp -;; 25: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 5d pop rbp +;; 19: c3 ret diff --git a/winch/filetests/filetests/x64/i64_rems/const.wat b/winch/filetests/filetests/x64/i64_rems/const.wat index f8e1c34395..ad6182c231 100644 --- a/winch/filetests/filetests/x64/i64_rems/const.wat +++ b/winch/filetests/filetests/x64/i64_rems/const.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c105000000 mov rcx, 5 ;; b: 48c7c007000000 mov rax, 7 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4899 cqo -;; 20: 4883f9ff cmp rcx, -1 -;; 24: 0f850a000000 jne 0x34 -;; 2a: ba00000000 mov edx, 0 -;; 2f: e903000000 jmp 0x37 -;; 34: 48f7f9 idiv rcx -;; 37: 4889d0 mov rax, rdx -;; 3a: 5d pop rbp -;; 3b: c3 ret +;; 12: 4899 cqo +;; 14: 4883f9ff cmp rcx, -1 +;; 18: 0f850a000000 jne 0x28 +;; 1e: ba00000000 mov edx, 0 +;; 23: e903000000 jmp 0x2b +;; 28: 48f7f9 idiv rcx +;; 2b: 4889d0 mov rax, rdx +;; 2e: 5d pop rbp +;; 2f: c3 ret diff --git a/winch/filetests/filetests/x64/i64_rems/one_zero.wat b/winch/filetests/filetests/x64/i64_rems/one_zero.wat index 3ef0f3289f..0ac94edd6e 100644 --- a/winch/filetests/filetests/x64/i64_rems/one_zero.wat +++ b/winch/filetests/filetests/x64/i64_rems/one_zero.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c001000000 mov rax, 1 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4899 cqo -;; 20: 4883f9ff cmp rcx, -1 -;; 24: 0f850a000000 jne 0x34 -;; 2a: ba00000000 mov edx, 0 -;; 2f: e903000000 jmp 0x37 -;; 34: 48f7f9 idiv rcx -;; 37: 4889d0 mov rax, rdx -;; 3a: 5d pop rbp -;; 3b: c3 ret +;; 12: 4899 cqo +;; 14: 4883f9ff cmp rcx, -1 +;; 18: 0f850a000000 jne 0x28 +;; 1e: ba00000000 mov edx, 0 +;; 23: e903000000 jmp 0x2b +;; 28: 48f7f9 idiv rcx +;; 2b: 4889d0 mov rax, rdx +;; 2e: 5d pop rbp +;; 2f: c3 ret diff --git a/winch/filetests/filetests/x64/i64_rems/overflow.wat b/winch/filetests/filetests/x64/i64_rems/overflow.wat index d3c69a9c63..6de1bfe75d 100644 --- a/winch/filetests/filetests/x64/i64_rems/overflow.wat +++ b/winch/filetests/filetests/x64/i64_rems/overflow.wat @@ -12,15 +12,12 @@ ;; 4: 48c7c1ffffffff mov rcx, 0xffffffffffffffff ;; b: 48b80000000000000080 ;; movabs rax, 0x8000000000000000 -;; 15: 4883f900 cmp rcx, 0 -;; 19: 0f8502000000 jne 0x21 -;; 1f: 0f0b ud2 -;; 21: 4899 cqo -;; 23: 4883f9ff cmp rcx, -1 -;; 27: 0f850a000000 jne 0x37 -;; 2d: ba00000000 mov edx, 0 -;; 32: e903000000 jmp 0x3a -;; 37: 48f7f9 idiv rcx -;; 3a: 4889d0 mov rax, rdx -;; 3d: 5d pop rbp -;; 3e: c3 ret +;; 15: 4899 cqo +;; 17: 4883f9ff cmp rcx, -1 +;; 1b: 0f850a000000 jne 0x2b +;; 21: ba00000000 mov edx, 0 +;; 26: e903000000 jmp 0x2e +;; 2b: 48f7f9 idiv rcx +;; 2e: 4889d0 mov rax, rdx +;; 31: 5d pop rbp +;; 32: c3 ret diff --git a/winch/filetests/filetests/x64/i64_rems/params.wat b/winch/filetests/filetests/x64/i64_rems/params.wat index 9851aa14c4..222b54efa0 100644 --- a/winch/filetests/filetests/x64/i64_rems/params.wat +++ b/winch/filetests/filetests/x64/i64_rems/params.wat @@ -14,16 +14,13 @@ ;; d: 48893424 mov qword ptr [rsp], rsi ;; 11: 488b0c24 mov rcx, qword ptr [rsp] ;; 15: 488b442408 mov rax, qword ptr [rsp + 8] -;; 1a: 4883f900 cmp rcx, 0 -;; 1e: 0f8502000000 jne 0x26 -;; 24: 0f0b ud2 -;; 26: 4899 cqo -;; 28: 4883f9ff cmp rcx, -1 -;; 2c: 0f850a000000 jne 0x3c -;; 32: ba00000000 mov edx, 0 -;; 37: e903000000 jmp 0x3f -;; 3c: 48f7f9 idiv rcx -;; 3f: 4889d0 mov rax, rdx -;; 42: 4883c410 add rsp, 0x10 -;; 46: 5d pop rbp -;; 47: c3 ret +;; 1a: 4899 cqo +;; 1c: 4883f9ff cmp rcx, -1 +;; 20: 0f850a000000 jne 0x30 +;; 26: ba00000000 mov edx, 0 +;; 2b: e903000000 jmp 0x33 +;; 30: 48f7f9 idiv rcx +;; 33: 4889d0 mov rax, rdx +;; 36: 4883c410 add rsp, 0x10 +;; 3a: 5d pop rbp +;; 3b: c3 ret diff --git a/winch/filetests/filetests/x64/i64_rems/zero_zero.wat b/winch/filetests/filetests/x64/i64_rems/zero_zero.wat index 3a745e384a..e3f24719a8 100644 --- a/winch/filetests/filetests/x64/i64_rems/zero_zero.wat +++ b/winch/filetests/filetests/x64/i64_rems/zero_zero.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c000000000 mov rax, 0 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4899 cqo -;; 20: 4883f9ff cmp rcx, -1 -;; 24: 0f850a000000 jne 0x34 -;; 2a: ba00000000 mov edx, 0 -;; 2f: e903000000 jmp 0x37 -;; 34: 48f7f9 idiv rcx -;; 37: 4889d0 mov rax, rdx -;; 3a: 5d pop rbp -;; 3b: c3 ret +;; 12: 4899 cqo +;; 14: 4883f9ff cmp rcx, -1 +;; 18: 0f850a000000 jne 0x28 +;; 1e: ba00000000 mov edx, 0 +;; 23: e903000000 jmp 0x2b +;; 28: 48f7f9 idiv rcx +;; 2b: 4889d0 mov rax, rdx +;; 2e: 5d pop rbp +;; 2f: c3 ret diff --git a/winch/filetests/filetests/x64/i64_remu/const.wat b/winch/filetests/filetests/x64/i64_remu/const.wat index 3b86a6769f..101877d134 100644 --- a/winch/filetests/filetests/x64/i64_remu/const.wat +++ b/winch/filetests/filetests/x64/i64_remu/const.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c105000000 mov rcx, 5 ;; b: 48c7c007000000 mov rax, 7 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 4889d0 mov rax, rdx -;; 27: 5d pop rbp -;; 28: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 4889d0 mov rax, rdx +;; 1b: 5d pop rbp +;; 1c: c3 ret diff --git a/winch/filetests/filetests/x64/i64_remu/one_zero.wat b/winch/filetests/filetests/x64/i64_remu/one_zero.wat index e31033b33c..5af4f5989b 100644 --- a/winch/filetests/filetests/x64/i64_remu/one_zero.wat +++ b/winch/filetests/filetests/x64/i64_remu/one_zero.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c001000000 mov rax, 1 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 4889d0 mov rax, rdx -;; 27: 5d pop rbp -;; 28: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 4889d0 mov rax, rdx +;; 1b: 5d pop rbp +;; 1c: c3 ret diff --git a/winch/filetests/filetests/x64/i64_remu/params.wat b/winch/filetests/filetests/x64/i64_remu/params.wat index 773debc841..4d6d4abce4 100644 --- a/winch/filetests/filetests/x64/i64_remu/params.wat +++ b/winch/filetests/filetests/x64/i64_remu/params.wat @@ -14,12 +14,9 @@ ;; d: 48893424 mov qword ptr [rsp], rsi ;; 11: 488b0c24 mov rcx, qword ptr [rsp] ;; 15: 488b442408 mov rax, qword ptr [rsp + 8] -;; 1a: 4883f900 cmp rcx, 0 -;; 1e: 0f8502000000 jne 0x26 -;; 24: 0f0b ud2 -;; 26: 4831d2 xor rdx, rdx -;; 29: 48f7f1 div rcx -;; 2c: 4889d0 mov rax, rdx -;; 2f: 4883c410 add rsp, 0x10 -;; 33: 5d pop rbp -;; 34: c3 ret +;; 1a: 4831d2 xor rdx, rdx +;; 1d: 48f7f1 div rcx +;; 20: 4889d0 mov rax, rdx +;; 23: 4883c410 add rsp, 0x10 +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i64_remu/signed.wat b/winch/filetests/filetests/x64/i64_remu/signed.wat index 77b1859824..2556ecfcc8 100644 --- a/winch/filetests/filetests/x64/i64_remu/signed.wat +++ b/winch/filetests/filetests/x64/i64_remu/signed.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c1ffffffff mov rcx, 0xffffffffffffffff ;; b: 48c7c0ffffffff mov rax, 0xffffffffffffffff -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 4889d0 mov rax, rdx -;; 27: 5d pop rbp -;; 28: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 4889d0 mov rax, rdx +;; 1b: 5d pop rbp +;; 1c: c3 ret diff --git a/winch/filetests/filetests/x64/i64_remu/zero_zero.wat b/winch/filetests/filetests/x64/i64_remu/zero_zero.wat index df358d9227..18983cd085 100644 --- a/winch/filetests/filetests/x64/i64_remu/zero_zero.wat +++ b/winch/filetests/filetests/x64/i64_remu/zero_zero.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c000000000 mov rax, 0 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 4889d0 mov rax, rdx -;; 27: 5d pop rbp -;; 28: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 4889d0 mov rax, rdx +;; 1b: 5d pop rbp +;; 1c: c3 ret