mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Add verilated asserts that VL_MULS_MAX_WORDS does not overflow (#4781). No functional change intended.
This commit is contained in:
parent
9de6612cde
commit
ca3b5fbe99
@ -444,6 +444,8 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
||||
|
||||
const int uw = VL_WORDS_I(umsbp1); // aka "m" in the algorithm
|
||||
const int vw = VL_WORDS_I(vmsbp1); // aka "n" in the algorithm
|
||||
VL_DEBUG_IFDEF(assert(uw <= VL_MULS_MAX_WORDS););
|
||||
VL_DEBUG_IFDEF(assert(vw <= VL_MULS_MAX_WORDS););
|
||||
|
||||
if (vw == 1) { // Single divisor word breaks rest of algorithm
|
||||
uint64_t k = 0;
|
||||
@ -542,6 +544,8 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
||||
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, const WDataInP lwp,
|
||||
const WDataInP rwp) VL_MT_SAFE {
|
||||
// obits==lbits, rbits can be different
|
||||
const int owords = VL_WORDS_I(obits);
|
||||
VL_DEBUG_IFDEF(assert(owords <= VL_MULS_MAX_WORDS););
|
||||
owp[0] = 1;
|
||||
for (int i = 1; i < VL_WORDS_I(obits); i++) owp[i] = 0;
|
||||
// cppcheck-has-bug-suppress variableScope
|
||||
@ -553,11 +557,11 @@ WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, const WDataInP lw
|
||||
for (int bit = 0; bit < rbits; bit++) {
|
||||
if (bit > 0) { // power = power*power
|
||||
VL_ASSIGN_W(obits, lastpowstore, powstore);
|
||||
VL_MUL_W(VL_WORDS_I(obits), powstore, lastpowstore, lastpowstore);
|
||||
VL_MUL_W(owords, powstore, lastpowstore, lastpowstore);
|
||||
}
|
||||
if (VL_BITISSET_W(rwp, bit)) { // out *= power
|
||||
VL_ASSIGN_W(obits, lastoutstore, owp);
|
||||
VL_MUL_W(VL_WORDS_I(obits), owp, lastoutstore, powstore);
|
||||
VL_MUL_W(owords, owp, lastoutstore, powstore);
|
||||
}
|
||||
}
|
||||
return owp;
|
||||
@ -653,8 +657,10 @@ double VL_ITOR_D_W(int lbits, const WDataInP lwp) VL_PURE {
|
||||
}
|
||||
double VL_ISTOR_D_W(int lbits, const WDataInP lwp) VL_MT_SAFE {
|
||||
if (!VL_SIGN_W(lbits, lwp)) return VL_ITOR_D_W(lbits, lwp);
|
||||
const int words = VL_WORDS_I(lbits);
|
||||
VL_DEBUG_IFDEF(assert(words <= VL_MULS_MAX_WORDS););
|
||||
uint32_t pos[VL_MULS_MAX_WORDS + 1]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||
VL_NEGATE_W(VL_WORDS_I(lbits), pos, lwp);
|
||||
VL_NEGATE_W(words, pos, lwp);
|
||||
_vl_clean_inplace_w(lbits, pos);
|
||||
return -VL_ITOR_D_W(lbits, pos);
|
||||
}
|
||||
|
@ -1032,6 +1032,7 @@ static inline QData VL_MULS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||
static inline WDataOutP VL_MULS_WWW(int lbits, WDataOutP owp, WDataInP const lwp,
|
||||
WDataInP const rwp) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(lbits);
|
||||
VL_DEBUG_IFDEF(assert(words <= VL_MULS_MAX_WORDS););
|
||||
// cppcheck-suppress variableScope
|
||||
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||
// cppcheck-suppress variableScope
|
||||
@ -1102,21 +1103,22 @@ static inline QData VL_MODDIVS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||
|
||||
static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP const lwp,
|
||||
WDataInP const rwp) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(lbits);
|
||||
const EData lsign = VL_SIGN_E(lbits, lwp[words - 1]);
|
||||
const EData rsign = VL_SIGN_E(lbits, rwp[words - 1]);
|
||||
const int lwords = VL_WORDS_I(lbits);
|
||||
const EData lsign = VL_SIGN_E(lbits, lwp[lwords - 1]);
|
||||
const EData rsign = VL_SIGN_E(lbits, rwp[lwords - 1]);
|
||||
VL_DEBUG_IFDEF(assert(lwords <= VL_MULS_MAX_WORDS););
|
||||
// cppcheck-suppress variableScope
|
||||
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||
// cppcheck-suppress variableScope
|
||||
WData rwstore[VL_MULS_MAX_WORDS];
|
||||
WDataInP ltup = lwp;
|
||||
WDataInP rtup = rwp;
|
||||
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp));
|
||||
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp));
|
||||
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, lwstore, lwp));
|
||||
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, rwstore, rwp));
|
||||
if ((lsign && !rsign) || (!lsign && rsign)) {
|
||||
WData qNoSign[VL_MULS_MAX_WORDS];
|
||||
VL_DIV_WWW(lbits, qNoSign, ltup, rtup);
|
||||
_vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), owp, qNoSign));
|
||||
_vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, owp, qNoSign));
|
||||
return owp;
|
||||
} else {
|
||||
return VL_DIV_WWW(lbits, owp, ltup, rtup);
|
||||
@ -1124,21 +1126,22 @@ static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP const lwp
|
||||
}
|
||||
static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp, WDataInP const lwp,
|
||||
WDataInP const rwp) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(lbits);
|
||||
const EData lsign = VL_SIGN_E(lbits, lwp[words - 1]);
|
||||
const EData rsign = VL_SIGN_E(lbits, rwp[words - 1]);
|
||||
const int lwords = VL_WORDS_I(lbits);
|
||||
const EData lsign = VL_SIGN_E(lbits, lwp[lwords - 1]);
|
||||
const EData rsign = VL_SIGN_E(lbits, rwp[lwords - 1]);
|
||||
VL_DEBUG_IFDEF(assert(lwords <= VL_MULS_MAX_WORDS););
|
||||
// cppcheck-suppress variableScope
|
||||
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||
// cppcheck-suppress variableScope
|
||||
WData rwstore[VL_MULS_MAX_WORDS];
|
||||
WDataInP ltup = lwp;
|
||||
WDataInP rtup = rwp;
|
||||
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp));
|
||||
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp));
|
||||
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, lwstore, lwp));
|
||||
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, rwstore, rwp));
|
||||
if (lsign) { // Only dividend sign matters for modulus
|
||||
WData qNoSign[VL_MULS_MAX_WORDS];
|
||||
VL_MODDIV_WWW(lbits, qNoSign, ltup, rtup);
|
||||
_vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), owp, qNoSign));
|
||||
_vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, owp, qNoSign));
|
||||
return owp;
|
||||
} else {
|
||||
return VL_MODDIV_WWW(lbits, owp, ltup, rtup);
|
||||
|
Loading…
Reference in New Issue
Block a user