diff --git a/verinum.cc b/verinum.cc index c5f4be65e..7b466053b 100644 --- a/verinum.cc +++ b/verinum.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2018 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -22,6 +22,7 @@ # include "verinum.h" # include # include +# include # include // Needed to get pow for as_double(). # include // Needed to get snprintf for as_string(). # include @@ -1444,7 +1445,8 @@ verinum operator / (const verinum&left, const verinum&right) if (use_len <= (8*sizeof(long) - 1)) { long l = left.as_long(); long r = right.as_long(); - long v = l / r; + bool overflow = (l == LONG_MIN) && (r == -1); + long v = overflow ? LONG_MIN : l / r; for (unsigned idx = 0 ; idx < use_len ; idx += 1) { result.set(idx, (v & 1)? verinum::V1 : verinum::V0); v >>= 1; @@ -1518,7 +1520,8 @@ verinum operator % (const verinum&left, const verinum&right) /* Use native signed modulus to do the work. */ long l = left.as_long(); long r = right.as_long(); - long v = l % r; + bool overflow = (l == LONG_MIN) && (r == -1); + long v = overflow ? 0 : l % r; for (unsigned idx = 0 ; idx < use_len ; idx += 1) { result.set(idx, (v & 1)? verinum::V1 : verinum::V0); v >>= 1; diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 3bed3ed59..710404062 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -2707,6 +2707,10 @@ bool of_DIV_S(vthread_t thr, vvp_code_t) if (bp[0] == 0) { vvp_vector4_t tmp(wid, BIT4_X); vala = tmp; + } else if (((long)ap[0] == LONG_MIN) && ((long)bp[0] == -1)) { + vvp_vector4_t tmp(wid, BIT4_0); + tmp.set_bit(wid-1, BIT4_1); + vala = tmp; } else { long tmpa = (long) ap[0]; long tmpb = (long) bp[0]; @@ -3996,6 +4000,9 @@ bool of_MOD_S(vthread_t thr, vvp_code_t) if (rv == 0) goto x_out; + if ((lv == LONG_LONG_MIN) && (rv == -1)) + goto zero_out; + /* Sign extend the signed operands when needed. */ if (wid < 8*sizeof(long long)) { if (lv & (1LL << (wid-1))) @@ -4027,6 +4034,9 @@ bool of_MOD_S(vthread_t thr, vvp_code_t) x_out: vala = vvp_vector4_t(wid, BIT4_X); return true; + zero_out: + vala = vvp_vector4_t(wid, BIT4_0); + return true; } /*