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
This commit is contained in:
@@ -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.",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))))
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
));
|
||||
|
||||
// ========================================================
|
||||
|
||||
@@ -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<F: Fn(VReg) -> 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 => {
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -23,12 +23,6 @@ impl<T> IsaBuilder<T> {
|
||||
pub fn new(lookup: fn(Triple) -> Result<Builder<T>>) -> 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")
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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"
|
||||
)),
|
||||
}
|
||||
|
||||
|
||||
@@ -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<T>(result: Result<T>, expected: Trap) {
|
||||
match result {
|
||||
Ok(_) => panic!("expected failure"),
|
||||
Err(e) => {
|
||||
if let Some(code) = e.downcast_ref::<Trap>() {
|
||||
if *code == expected {
|
||||
return;
|
||||
}
|
||||
}
|
||||
panic!("unexpected error {e:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user