--- target-i386/helper.c Sat Jul 23 16:23:17 2005 +++ target-i386/helper.c Sat Jul 23 15:13:34 2005 @@ -1209,13 +1209,13 @@ void raise_exception(int exception_index #ifdef BUGGY_GCC_DIV64 /* gcc 2.95.4 on PowerPC does not seem to like using __udivdi3, so we call it from another function */ -uint32_t div32(uint32_t *q_ptr, uint64_t num, uint32_t den) +uint32_t div32(uint64_t *q_ptr, uint64_t num, uint32_t den) { *q_ptr = num / den; return num % den; } -int32_t idiv32(int32_t *q_ptr, int64_t num, int32_t den) +int32_t idiv32(int64_t *q_ptr, int64_t num, int32_t den) { *q_ptr = num / den; return num % den; @@ -1224,8 +1224,8 @@ int32_t idiv32(int32_t *q_ptr, int64_t n void helper_divl_EAX_T0(void) { - unsigned int den, q, r; - uint64_t num; + unsigned int den, r; + uint64_t num, q; num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); den = T0; @@ -1238,14 +1238,17 @@ void helper_divl_EAX_T0(void) q = (num / den); r = (num % den); #endif + if (q > 0xffffffff) { + raise_exception(EXCP00_DIVZ); + } EAX = (uint32_t)q; EDX = (uint32_t)r; } void helper_idivl_EAX_T0(void) { - int den, q, r; - int64_t num; + int den, r; + int64_t num, q; num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); den = T0; @@ -1258,6 +1262,9 @@ void helper_idivl_EAX_T0(void) q = (num / den); r = (num % den); #endif + if (q > 0x7fffffff || q < -0x7fffffff) { + raise_exception(EXCP00_DIVZ); + } EAX = (uint32_t)q; EDX = (uint32_t)r; } --- target-i386/op.c Sat Jul 23 16:23:17 2005 +++ target-i386/op.c Sat Jul 23 13:55:13 2005 @@ -328,7 +328,6 @@ void OPPROTO op_imulq_T0_T1(void) #endif /* division, flags are undefined */ -/* XXX: add exceptions for overflow */ void OPPROTO op_divb_AL_T0(void) { @@ -341,6 +340,9 @@ void OPPROTO op_divb_AL_T0(void) } q = (num / den) & 0xff; r = (num % den) & 0xff; + if (q > 0xff) { + raise_exception(EXCP00_DIVZ); + } EAX = (EAX & ~0xffff) | (r << 8) | q; } @@ -355,6 +357,9 @@ void OPPROTO op_idivb_AL_T0(void) } q = (num / den) & 0xff; r = (num % den) & 0xff; + if (q > 0x7f || q < -0x7f) { + raise_exception(EXCP00_DIVZ); + } EAX = (EAX & ~0xffff) | (r << 8) | q; } @@ -369,6 +374,9 @@ void OPPROTO op_divw_AX_T0(void) } q = (num / den) & 0xffff; r = (num % den) & 0xffff; + if (q > 0xffff) { + raise_exception(EXCP00_DIVZ); + } EAX = (EAX & ~0xffff) | q; EDX = (EDX & ~0xffff) | r; } @@ -384,6 +392,9 @@ void OPPROTO op_idivw_AX_T0(void) } q = (num / den) & 0xffff; r = (num % den) & 0xffff; + if (q > 0x7fff || q < -0x7fff) { + raise_exception(EXCP00_DIVZ); + } EAX = (EAX & ~0xffff) | q; EDX = (EDX & ~0xffff) | r; }