forked from github/verilator
Fix to zero possibly uninitialized bits in replications (#3815)
This commit is contained in:
parent
2eafd82696
commit
073af8e1f2
@ -1095,12 +1095,13 @@ static char* _vl_vsss_read_bin(FILE* fp, int& floc, const WDataInP fromp, const
|
||||
}
|
||||
return beginp;
|
||||
}
|
||||
static void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits, IData ld) VL_MT_SAFE {
|
||||
for (; nbits && lsb < obits; nbits--, lsb++, ld >>= 1) { VL_ASSIGNBIT_WI(lsb, owp, ld & 1); }
|
||||
static void _vl_vsss_setbit(WDataOutP iowp, int obits, int lsb, int nbits, IData ld) VL_MT_SAFE {
|
||||
for (; nbits && lsb < obits; nbits--, lsb++, ld >>= 1) VL_ASSIGNBIT_WI(lsb, iowp, ld & 1);
|
||||
}
|
||||
static void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp,
|
||||
size_t posstart, size_t posend) VL_MT_SAFE {
|
||||
// Read in base "2^^baseLog2" digits from strp[posstart..posend-1] into owp of size obits.
|
||||
VL_ZERO_W(obits, owp);
|
||||
int lsb = 0;
|
||||
for (int i = 0, pos = static_cast<int>(posend) - 1;
|
||||
i < obits && pos >= static_cast<int>(posstart); --pos) {
|
||||
|
@ -1246,7 +1246,7 @@ static inline void _vl_insert_QQ(QData& lhsr, QData ld, int hbit, int lbit, int
|
||||
const QData insmask = (VL_MASK_Q(hbit - lbit + 1)) << lbit;
|
||||
lhsr = (lhsr & ~insmask) | ((ld << lbit) & (insmask & cleanmask));
|
||||
}
|
||||
static inline void _vl_insert_WI(WDataOutP owp, IData ld, int hbit, int lbit,
|
||||
static inline void _vl_insert_WI(WDataOutP iowp, IData ld, int hbit, int lbit,
|
||||
int rbits = 0) VL_MT_SAFE {
|
||||
const int hoffset = VL_BITBIT_E(hbit);
|
||||
const int loffset = VL_BITBIT_E(lbit);
|
||||
@ -1258,28 +1258,28 @@ static inline void _vl_insert_WI(WDataOutP owp, IData ld, int hbit, int lbit,
|
||||
|
||||
if (hoffset == VL_SIZEBITS_E && loffset == 0) {
|
||||
// Fast and common case, word based insertion
|
||||
owp[VL_BITWORD_E(lbit)] = ld & cleanmask;
|
||||
iowp[VL_BITWORD_E(lbit)] = ld & cleanmask;
|
||||
} else {
|
||||
const EData lde = static_cast<EData>(ld);
|
||||
if (hword == lword) { // know < EData bits because above checks it
|
||||
// Assignment is contained within one word of destination
|
||||
const EData insmask = (VL_MASK_E(hoffset - loffset + 1)) << loffset;
|
||||
owp[lword] = (owp[lword] & ~insmask) | ((lde << loffset) & (insmask & cleanmask));
|
||||
iowp[lword] = (iowp[lword] & ~insmask) | ((lde << loffset) & (insmask & cleanmask));
|
||||
} else {
|
||||
// Assignment crosses a word boundary in destination
|
||||
const EData hinsmask = (VL_MASK_E(hoffset - 0 + 1)) << 0;
|
||||
const EData linsmask = (VL_MASK_E((VL_EDATASIZE - 1) - loffset + 1)) << loffset;
|
||||
const int nbitsonright = VL_EDATASIZE - loffset; // bits that end up in lword
|
||||
owp[lword] = (owp[lword] & ~linsmask) | ((lde << loffset) & linsmask);
|
||||
owp[hword]
|
||||
= (owp[hword] & ~hinsmask) | ((lde >> nbitsonright) & (hinsmask & cleanmask));
|
||||
iowp[lword] = (iowp[lword] & ~linsmask) | ((lde << loffset) & linsmask);
|
||||
iowp[hword]
|
||||
= (iowp[hword] & ~hinsmask) | ((lde >> nbitsonright) & (hinsmask & cleanmask));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// INTERNAL: Stuff large LHS bit 0++ into OUTPUT at specified offset
|
||||
// lwp may be "dirty"
|
||||
static inline void _vl_insert_WW(WDataOutP owp, WDataInP const lwp, int hbit, int lbit,
|
||||
static inline void _vl_insert_WW(WDataOutP iowp, WDataInP const lwp, int hbit, int lbit,
|
||||
int rbits = 0) VL_MT_SAFE {
|
||||
const int hoffset = VL_BITBIT_E(hbit);
|
||||
const int loffset = VL_BITBIT_E(lbit);
|
||||
@ -1294,14 +1294,14 @@ static inline void _vl_insert_WW(WDataOutP owp, WDataInP const lwp, int hbit, in
|
||||
|
||||
if (hoffset == VL_SIZEBITS_E && loffset == 0) {
|
||||
// Fast and common case, word based insertion
|
||||
for (int i = 0; i < (words - 1); ++i) owp[lword + i] = lwp[i];
|
||||
owp[hword] = lwp[words - 1] & cleanmask;
|
||||
for (int i = 0; i < (words - 1); ++i) iowp[lword + i] = lwp[i];
|
||||
iowp[hword] = lwp[words - 1] & cleanmask;
|
||||
} else if (loffset == 0) {
|
||||
// Non-32bit, but nicely aligned, so stuff all but the last word
|
||||
for (int i = 0; i < (words - 1); ++i) owp[lword + i] = lwp[i];
|
||||
for (int i = 0; i < (words - 1); ++i) iowp[lword + i] = lwp[i];
|
||||
// Know it's not a full word as above fast case handled it
|
||||
const EData hinsmask = (VL_MASK_E(hoffset - 0 + 1));
|
||||
owp[hword] = (owp[hword] & ~hinsmask) | (lwp[words - 1] & (hinsmask & cleanmask));
|
||||
iowp[hword] = (iowp[hword] & ~hinsmask) | (lwp[words - 1] & (hinsmask & cleanmask));
|
||||
} else {
|
||||
const EData hinsmask = (VL_MASK_E(hoffset - 0 + 1)) << 0;
|
||||
const EData linsmask = (VL_MASK_E((VL_EDATASIZE - 1) - loffset + 1)) << loffset;
|
||||
@ -1312,22 +1312,22 @@ static inline void _vl_insert_WW(WDataOutP owp, WDataInP const lwp, int hbit, in
|
||||
{ // Lower word
|
||||
const int oword = lword + i;
|
||||
const EData d = lwp[i] << loffset;
|
||||
const EData od = (owp[oword] & ~linsmask) | (d & linsmask);
|
||||
const EData od = (iowp[oword] & ~linsmask) | (d & linsmask);
|
||||
if (oword == hword) {
|
||||
owp[oword] = (owp[oword] & ~hinsmask) | (od & (hinsmask & cleanmask));
|
||||
iowp[oword] = (iowp[oword] & ~hinsmask) | (od & (hinsmask & cleanmask));
|
||||
} else {
|
||||
owp[oword] = od;
|
||||
iowp[oword] = od;
|
||||
}
|
||||
}
|
||||
{ // Upper word
|
||||
const int oword = lword + i + 1;
|
||||
if (oword <= hword) {
|
||||
const EData d = lwp[i] >> nbitsonright;
|
||||
const EData od = (d & ~linsmask) | (owp[oword] & linsmask);
|
||||
const EData od = (d & ~linsmask) | (iowp[oword] & linsmask);
|
||||
if (oword == hword) {
|
||||
owp[oword] = (owp[oword] & ~hinsmask) | (od & (hinsmask & cleanmask));
|
||||
iowp[oword] = (iowp[oword] & ~hinsmask) | (od & (hinsmask & cleanmask));
|
||||
} else {
|
||||
owp[oword] = od;
|
||||
iowp[oword] = od;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1335,11 +1335,11 @@ static inline void _vl_insert_WW(WDataOutP owp, WDataInP const lwp, int hbit, in
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _vl_insert_WQ(WDataOutP owp, QData ld, int hbit, int lbit,
|
||||
static inline void _vl_insert_WQ(WDataOutP iowp, QData ld, int hbit, int lbit,
|
||||
int rbits = 0) VL_MT_SAFE {
|
||||
VlWide<VL_WQ_WORDS_E> lwp;
|
||||
VL_SET_WQ(lwp, ld);
|
||||
_vl_insert_WW(owp, lwp, hbit, lbit, rbits);
|
||||
_vl_insert_WW(iowp, lwp, hbit, lbit, rbits);
|
||||
}
|
||||
|
||||
// EMIT_RULE: VL_REPLICATE: oclean=clean>width32, dirty<=width32; lclean=clean; rclean==clean;
|
||||
@ -1366,6 +1366,9 @@ static inline QData VL_REPLICATE_QII(int lbits, IData ld, IData rep) VL_PURE {
|
||||
static inline WDataOutP VL_REPLICATE_WII(int lbits, WDataOutP owp, IData ld,
|
||||
IData rep) VL_MT_SAFE {
|
||||
owp[0] = ld;
|
||||
// Zeroing all words isn't strictly needed but allows compiler to know
|
||||
// it does not need to preserve data in word(s) not being written
|
||||
for (unsigned i = 1; i < VL_WORDS_I(lbits * rep); ++i) owp[i] = 0;
|
||||
for (unsigned i = 1; i < rep; ++i) {
|
||||
_vl_insert_WI(owp, ld, i * lbits + lbits - 1, i * lbits);
|
||||
}
|
||||
@ -1374,6 +1377,9 @@ static inline WDataOutP VL_REPLICATE_WII(int lbits, WDataOutP owp, IData ld,
|
||||
static inline WDataOutP VL_REPLICATE_WQI(int lbits, WDataOutP owp, QData ld,
|
||||
IData rep) VL_MT_SAFE {
|
||||
VL_SET_WQ(owp, ld);
|
||||
// Zeroing all words isn't strictly needed but allows compiler to know
|
||||
// it does not need to preserve data in word(s) not being written
|
||||
for (unsigned i = 2; i < VL_WORDS_I(lbits * rep); ++i) owp[i] = 0;
|
||||
for (unsigned i = 1; i < rep; ++i) {
|
||||
_vl_insert_WQ(owp, ld, i * lbits + lbits - 1, i * lbits);
|
||||
}
|
||||
@ -1381,7 +1387,10 @@ static inline WDataOutP VL_REPLICATE_WQI(int lbits, WDataOutP owp, QData ld,
|
||||
}
|
||||
static inline WDataOutP VL_REPLICATE_WWI(int lbits, WDataOutP owp, WDataInP const lwp,
|
||||
IData rep) VL_MT_SAFE {
|
||||
for (int i = 0; i < VL_WORDS_I(lbits); ++i) owp[i] = lwp[i];
|
||||
for (unsigned i = 0; i < VL_WORDS_I(lbits); ++i) owp[i] = lwp[i];
|
||||
// Zeroing all words isn't strictly needed but allows compiler to know
|
||||
// it does not need to preserve data in word(s) not being written
|
||||
for (unsigned i = VL_WORDS_I(lbits); i < VL_WORDS_I(lbits * rep); ++i) owp[i] = 0;
|
||||
for (unsigned i = 1; i < rep; ++i) {
|
||||
_vl_insert_WW(owp, lwp, i * lbits + lbits - 1, i * lbits);
|
||||
}
|
||||
@ -1984,17 +1993,17 @@ static inline void VL_ASSIGNSEL_QQ(int rbits, int obits, int lsb, QData& lhsr, Q
|
||||
}
|
||||
// static inline void VL_ASSIGNSEL_IIIW(int obits, int lsb, IData& lhsr, WDataInP const rwp)
|
||||
// VL_MT_SAFE { Illegal, as lhs width >= rhs width
|
||||
static inline void VL_ASSIGNSEL_WI(int rbits, int obits, int lsb, WDataOutP owp,
|
||||
static inline void VL_ASSIGNSEL_WI(int rbits, int obits, int lsb, WDataOutP iowp,
|
||||
IData rhs) VL_MT_SAFE {
|
||||
_vl_insert_WI(owp, rhs, lsb + obits - 1, lsb, rbits);
|
||||
_vl_insert_WI(iowp, rhs, lsb + obits - 1, lsb, rbits);
|
||||
}
|
||||
static inline void VL_ASSIGNSEL_WQ(int rbits, int obits, int lsb, WDataOutP owp,
|
||||
static inline void VL_ASSIGNSEL_WQ(int rbits, int obits, int lsb, WDataOutP iowp,
|
||||
QData rhs) VL_MT_SAFE {
|
||||
_vl_insert_WQ(owp, rhs, lsb + obits - 1, lsb, rbits);
|
||||
_vl_insert_WQ(iowp, rhs, lsb + obits - 1, lsb, rbits);
|
||||
}
|
||||
static inline void VL_ASSIGNSEL_WW(int rbits, int obits, int lsb, WDataOutP owp,
|
||||
static inline void VL_ASSIGNSEL_WW(int rbits, int obits, int lsb, WDataOutP iowp,
|
||||
WDataInP const rwp) VL_MT_SAFE {
|
||||
_vl_insert_WW(owp, rwp, lsb + obits - 1, lsb, rbits);
|
||||
_vl_insert_WW(iowp, rwp, lsb + obits - 1, lsb, rbits);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
Loading…
Reference in New Issue
Block a user