From 7a3f382517cfc0f2b676dc6704b423e7b167b565 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 22 Jan 2019 07:33:27 +0100 Subject: [PATCH] Fix corner case of checked div/mod on x86 (#10406) Fixes #10377 --- lib/system/arithm.nim | 44 ++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim index 69c5587996..a875e95a7e 100644 --- a/lib/system/arithm.nim +++ b/lib/system/arithm.nim @@ -197,26 +197,40 @@ when asmVersion and not defined(gcc) and not defined(llvm_gcc): proc divInt(a, b: int): int {.compilerProc, asmNoStackFrame.} = asm """ - mov eax, ecx - mov ecx, edx - xor edx, edx - idiv ecx - jno theEnd - call `raiseOverflow` - theEnd: + test edx, edx + jne L_NOT_ZERO + call `raiseDivByZero` + L_NOT_ZERO: + cmp ecx, 0x80000000 + jne L_DO_DIV + cmp edx, -1 + jne L_DO_DIV + call `raiseOverflow` + L_DO_DIV: + mov eax, ecx + mov ecx, edx + cdq + idiv ecx ret """ proc modInt(a, b: int): int {.compilerProc, asmNoStackFrame.} = asm """ - mov eax, ecx - mov ecx, edx - xor edx, edx - idiv ecx - jno theEnd - call `raiseOverflow` - theEnd: - mov eax, edx + test edx, edx + jne L_NOT_ZERO + call `raiseDivByZero` + L_NOT_ZERO: + cmp ecx, 0x80000000 + jne L_DO_DIV + cmp edx, -1 + jne L_DO_DIV + call `raiseOverflow` + L_DO_DIV: + mov eax, ecx + mov ecx, edx + cdq + idiv ecx + mov eax, edx ret """