Internals: Favor preincrements. No functional change.

This commit is contained in:
Wilson Snyder
2025-05-09 21:20:35 -04:00
parent c2d289dc71
commit 7191a0ba8b
11 changed files with 126 additions and 126 deletions
+93 -93
View File
@@ -128,7 +128,7 @@ V3Number::V3Number(AstNode* nodep, const AstNodeDType* nodedtypep) {
void V3Number::create(const char* sourcep) {
m_data.setLogic();
const char* value_startp = sourcep;
for (const char* cp = sourcep; *cp; cp++) {
for (const char* cp = sourcep; *cp; ++cp) {
if (*cp == '\'') {
value_startp = cp + 1;
break;
@@ -141,21 +141,21 @@ void V3Number::create(const char* sourcep) {
if (value_startp != sourcep) { // Has a '
string widthn;
const char* cp = sourcep;
for (; *cp; cp++) {
for (; *cp; ++cp) {
if (*cp == '\'') {
cp++;
++cp;
break;
}
if (*cp != '_') widthn += *cp;
}
while (*cp == '_') cp++;
if (*cp && std::tolower(*cp) == 's') {
cp++;
++cp;
isSigned(true);
}
if (*cp) {
base = *cp;
cp++;
++cp;
}
value_startp = cp;
@@ -221,14 +221,14 @@ void V3Number::create(const char* sourcep) {
int base_align = 1;
if (std::tolower(base) == 'd') {
// Ignore leading zeros so we don't issue too many digit errors when lots of leading 0's
while (*value_startp == '_' || *value_startp == '0') value_startp++;
while (*value_startp == '_' || *value_startp == '0') ++value_startp;
// Convert decimal number to hex
int olen = 0;
uint32_t val = 0;
int got_x = 0;
int got_z = 0;
int got_01 = 0;
for (const char* cp = value_startp; *cp; cp++) {
for (const char* cp = value_startp; *cp; ++cp) {
switch (std::tolower(*cp)) {
case '0': // FALLTHRU
case '1': // FALLTHRU
@@ -254,10 +254,10 @@ void V3Number::create(const char* sourcep) {
opAdd(product, addend);
if (product.bitsValue(width(), 4)) { // Overflowed
warnTooMany(sourcep);
while (*(cp + 1)) cp++; // Skip ahead so don't get multiple warnings
while (*(cp + 1)) ++cp; // Skip ahead so don't get multiple warnings
}
}
olen++;
++olen;
got_01 = 1;
break;
}
@@ -344,7 +344,7 @@ void V3Number::create(const char* sourcep) {
case '7': setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); break;
case '8': setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); break;
case '9': setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); break;
case 'a': setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); break;
case 'a': setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); break;
case 'b': setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); break;
case 'c': setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); break;
case 'd': setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); break;
@@ -379,7 +379,7 @@ void V3Number::create(const char* sourcep) {
// This fixes 2'bx to become 2'bxx.
while (obit <= width() && obit && bitIsXZ(obit - 1)) {
setBit(obit, bitIs(obit - 1));
obit++;
++obit;
}
opCleanThis(true);
@@ -428,24 +428,24 @@ int V3Number::log2bQuad(uint64_t num) {
// Setters
V3Number& V3Number::setZero() {
for (int i = 0; i < words(); i++) m_data.num()[i] = {0, 0};
for (int i = 0; i < words(); ++i) m_data.num()[i] = {0, 0};
return *this;
}
V3Number& V3Number::setQuad(uint64_t value) {
for (int i = 0; i < words(); i++) m_data.num()[i] = {0, 0};
for (int i = 0; i < words(); ++i) m_data.num()[i] = {0, 0};
m_data.num()[0].m_value = value & 0xffffffffULL;
if (width() > 32) m_data.num()[1].m_value = (value >> 32ULL) & 0xffffffffULL;
opCleanThis();
return *this;
}
V3Number& V3Number::setLong(uint32_t value) {
for (int i = 0; i < words(); i++) m_data.num()[i] = {0, 0};
for (int i = 0; i < words(); ++i) m_data.num()[i] = {0, 0};
m_data.num()[0].m_value = value;
opCleanThis();
return *this;
}
V3Number& V3Number::setLongS(int32_t value) {
for (int i = 0; i < words(); i++) m_data.num()[i] = {0, 0};
for (int i = 0; i < words(); ++i) m_data.num()[i] = {0, 0};
union {
uint32_t u;
int32_t s;
@@ -465,35 +465,35 @@ V3Number& V3Number::setDouble(double value) {
} u;
u.d = value;
(void)u.d;
for (int i = 2; i < words(); i++) m_data.num()[i] = {0, 0};
for (int i = 2; i < words(); ++i) m_data.num()[i] = {0, 0};
m_data.num()[0].m_value = u.u[0];
m_data.num()[1].m_value = u.u[1];
return *this;
}
V3Number& V3Number::setSingleBits(char value) {
for (int i = 1 /*upper*/; i < words(); i++) m_data.num()[i] = {0, 0};
for (int i = 1 /*upper*/; i < words(); ++i) m_data.num()[i] = {0, 0};
m_data.num()[0] = {(value == '1' || value == 'x' || value == 1 || value == 3),
(value == 'z' || value == 'x' || value == 2 || value == 3)};
return *this;
}
V3Number& V3Number::setAllBits0() {
for (int i = 0; i < words(); i++) m_data.num()[i] = {0, 0};
for (int i = 0; i < words(); ++i) m_data.num()[i] = {0, 0};
return *this;
}
V3Number& V3Number::setAllBits1() {
for (int i = 0; i < words(); i++) m_data.num()[i] = {~0U, 0};
for (int i = 0; i < words(); ++i) m_data.num()[i] = {~0U, 0};
opCleanThis();
return *this;
}
V3Number& V3Number::setAllBitsX() {
// Use setAllBitsXRemoved if calling this based on a non-X/Z input value such as divide by zero
for (int i = 0; i < words(); i++) m_data.num()[i] = {~0U, ~0U};
for (int i = 0; i < words(); ++i) m_data.num()[i] = {~0U, ~0U};
opCleanThis();
return *this;
}
V3Number& V3Number::setAllBitsZ() {
for (int i = 0; i < words(); i++) m_data.num()[i] = {0, ~0U};
for (int i = 0; i < words(); ++i) m_data.num()[i] = {0, ~0U};
opCleanThis();
return *this;
}
@@ -512,7 +512,7 @@ V3Number& V3Number::setAllBitsXRemoved() {
}
V3Number& V3Number::setValue1() {
m_data.num()[0] = {1, 0};
for (int i = 1; i < words(); i++) m_data.num()[i] = {0, 0};
for (int i = 1; i < words(); ++i) m_data.num()[i] = {0, 0};
return *this;
}
@@ -524,7 +524,7 @@ void V3Number::setBitX0(int bit) {
V3Number& V3Number::setMask(int nbits, int lsb) {
setZero();
for (int bit = lsb; bit < lsb + nbits; bit++) setBit(bit, 1);
for (int bit = lsb; bit < lsb + nbits; ++bit) setBit(bit, 1);
return *this;
}
@@ -759,7 +759,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const VL_MT_STAB
// Spec says always drop leading zeros, this isn't quite right, we space pad.
int bit = width() - 1;
bool start = true;
while ((bit % 8) != 7) bit++;
while ((bit % 8) != 7) ++bit;
for (; bit >= 0; bit -= 8) {
const int v = bitsValue(bit - 7, 8);
if (!start || v) {
@@ -784,7 +784,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const VL_MT_STAB
// a very wide mantissa, we use log2(2**mantissabits)/log2(10),
// which is (+1.0 is for rounding bias):
double dchars = mantissabits / 3.321928094887362 + 1.0;
if (issigned) dchars++; // space for sign
if (issigned) ++dchars; // space for sign
fmtsize = cvtToStr(int(dchars));
}
bool hasXZ = false;
@@ -833,7 +833,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const VL_MT_STAB
// 'l' // Library - converted to text by V3LinkResolve
// 'p' // Packed - converted to another code by V3Width
case 'u': { // Packed 2-state
for (int i = 0; i < words(); i++) {
for (int i = 0; i < words(); ++i) {
const uint32_t v = m_data.num()[i].m_value;
str += static_cast<char>((v >> 0) & 0xff);
str += static_cast<char>((v >> 8) & 0xff);
@@ -843,7 +843,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const VL_MT_STAB
return str;
}
case 'z': { // Packed 4-state
for (int i = 0; i < words(); i++) {
for (int i = 0; i < words(); ++i) {
const ValueAndX v = m_data.num()[i];
str += static_cast<char>((v.m_value >> 0) & 0xff);
str += static_cast<char>((v.m_value >> 8) & 0xff);
@@ -1039,7 +1039,7 @@ uint8_t V3Number::dataByte(int byte) const {
bool V3Number::isAllZ() const VL_MT_SAFE {
if (isDouble() || isString()) return false;
for (int i = 0; i < width(); i++) {
for (int i = 0; i < width(); ++i) {
if (!bitIsZ(i)) return false;
}
return true;
@@ -1056,7 +1056,7 @@ bool V3Number::isAllX() const VL_MT_SAFE {
}
bool V3Number::isEqZero() const VL_MT_SAFE {
if (isString()) return m_data.str().empty();
for (int i = 0; i < words(); i++) {
for (int i = 0; i < words(); ++i) {
const ValueAndX v = m_data.num()[i];
if (v.m_value || v.m_valueX) return false;
}
@@ -1064,21 +1064,21 @@ bool V3Number::isEqZero() const VL_MT_SAFE {
}
bool V3Number::isNeqZero() const {
if (isString()) return !m_data.str().empty();
for (int i = 0; i < words(); i++) {
for (int i = 0; i < words(); ++i) {
const ValueAndX v = m_data.num()[i];
if (v.m_value & ~v.m_valueX) return true;
}
return false;
}
bool V3Number::isBitsZero(int msb, int lsb) const {
for (int i = lsb; i <= msb; i++) {
for (int i = lsb; i <= msb; ++i) {
if (VL_UNLIKELY(!bitIs0(i))) return false;
}
return true;
}
bool V3Number::isEqOne() const {
if (m_data.num()[0].m_value != 1 || m_data.num()[0].m_valueX) return false;
for (int i = 1; i < words(); i++) {
for (int i = 1; i < words(); ++i) {
const ValueAndX v = m_data.num()[i];
if (v.m_value || v.m_valueX) return false;
}
@@ -1087,7 +1087,7 @@ bool V3Number::isEqOne() const {
bool V3Number::isEqAllOnes(int optwidth) const {
// Correct number of zero bits/width matters
if (!optwidth) optwidth = width();
for (int bit = 0; bit < optwidth; bit++) {
for (int bit = 0; bit < optwidth; ++bit) {
if (!bitIs1(bit)) return false;
}
return true;
@@ -1101,7 +1101,7 @@ bool V3Number::isFourState() const VL_MT_SAFE {
}
bool V3Number::isAnyX() const VL_MT_SAFE {
if (isDouble() || isString()) return false;
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (bitIsX(bit)) return true;
}
return false;
@@ -1109,14 +1109,14 @@ bool V3Number::isAnyX() const VL_MT_SAFE {
bool V3Number::isAnyXZ() const { return isAnyX() || isAnyZ(); }
bool V3Number::isAnyZ() const VL_MT_SAFE {
if (isDouble() || isString()) return false;
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (bitIsZ(bit)) return true;
}
return false;
}
bool V3Number::isLtXZ(const V3Number& rhs) const {
// Include X/Z in comparisons for sort ordering
for (int bit = 0; bit < std::max(width(), rhs.width()); bit++) {
for (int bit = 0; bit < std::max(width(), rhs.width()); ++bit) {
if (bitIs1(bit) && rhs.bitIs0(bit)) return true;
if (rhs.bitIs1(bit) && bitIs0(bit)) return false;
if (bitIsXZ(bit)) return true;
@@ -1183,8 +1183,8 @@ uint32_t V3Number::countBits(const V3Number& ctrl1, const V3Number& ctrl2,
uint32_t V3Number::countOnes() const {
int n = 0;
for (int bit = 0; bit < width(); bit++) {
if (bitIs1(bit)) n++;
for (int bit = 0; bit < width(); ++bit) {
if (bitIs1(bit)) ++n;
}
return n;
}
@@ -1203,7 +1203,7 @@ V3Number& V3Number::opBitsNonX(const V3Number& lhs) { // 0/1->1, X/Z->0
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
setZero();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (lhs.bitIs0(bit) || lhs.bitIs1(bit)) setBit(bit, 1);
}
return *this;
@@ -1213,7 +1213,7 @@ V3Number& V3Number::opBitsOne(const V3Number& lhs) { // 1->1, 0/X/Z->0
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
setZero();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (lhs.bitIs1(bit)) setBit(bit, 1);
}
return *this;
@@ -1223,7 +1223,7 @@ V3Number& V3Number::opBitsXZ(const V3Number& lhs) { // 0/1->1, X/Z->0
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
setZero();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (lhs.bitIsXZ(bit)) setBit(bit, 1);
}
return *this;
@@ -1233,7 +1233,7 @@ V3Number& V3Number::opBitsZ(const V3Number& lhs) { // 0/1->1, X/Z->0
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
setZero();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (lhs.bitIsZ(bit)) setBit(bit, 1);
}
return *this;
@@ -1247,7 +1247,7 @@ V3Number& V3Number::opRedOr(const V3Number& lhs) {
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
char outc = 0;
for (int bit = 0; bit < lhs.width(); bit++) {
for (int bit = 0; bit < lhs.width(); ++bit) {
if (lhs.bitIs1(bit)) {
return setSingleBits(1);
} else if (lhs.bitIs0(bit)) {
@@ -1264,7 +1264,7 @@ V3Number& V3Number::opRedAnd(const V3Number& lhs) {
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
char outc = 1;
for (int bit = 0; bit < lhs.width(); bit++) {
for (int bit = 0; bit < lhs.width(); ++bit) {
if (lhs.bitIs0(bit)) {
return setSingleBits(0);
} else if (lhs.bitIs1(bit)) {
@@ -1280,7 +1280,7 @@ V3Number& V3Number::opRedXor(const V3Number& lhs) {
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
char outc = 0;
for (int bit = 0; bit < lhs.width(); bit++) {
for (int bit = 0; bit < lhs.width(); ++bit) {
if (lhs.bitIs1(bit)) {
if (outc == 1) {
outc = 0;
@@ -1349,7 +1349,7 @@ V3Number& V3Number::opLogNot(const V3Number& lhs) {
NUM_ASSERT_LOGIC_ARGS1(lhs);
// op i, 1 bit return
char outc = 1;
for (int bit = 0; bit < lhs.width(); bit++) {
for (int bit = 0; bit < lhs.width(); ++bit) {
if (lhs.bitIs1(bit)) {
outc = 0;
goto last;
@@ -1368,7 +1368,7 @@ V3Number& V3Number::opNot(const V3Number& lhs) {
NUM_ASSERT_LOGIC_ARGS1(lhs);
// op i, L(lhs) bit return
setZero();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (lhs.bitIs0(bit)) {
setBit(bit, 1);
} else if (lhs.bitIsXZ(bit)) {
@@ -1383,7 +1383,7 @@ V3Number& V3Number::opAnd(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
// i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
setZero();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (lhs.bitIs1(bit) && rhs.bitIs1(bit)) {
setBit(bit, 1);
} else if (lhs.bitIs0(bit) || rhs.bitIs0(bit)) { // 0
@@ -1399,7 +1399,7 @@ V3Number& V3Number::opOr(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
// i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
setZero();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (lhs.bitIs1(bit) || rhs.bitIs1(bit)) {
setBit(bit, 1);
} else if (lhs.bitIs0(bit) && rhs.bitIs0(bit)) {
@@ -1416,7 +1416,7 @@ V3Number& V3Number::opXor(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
setZero();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (lhs.bitIs1(bit) && rhs.bitIs0(bit)) {
setBit(bit, 1);
} else if (lhs.bitIs0(bit) && rhs.bitIs1(bit)) {
@@ -1439,13 +1439,13 @@ V3Number& V3Number::opConcat(const V3Number& lhs, const V3Number& rhs) {
v3warn(WIDTHCONCAT, "Unsized numbers/parameters not allowed in concatenations.");
}
int obit = 0;
for (int bit = 0; bit < rhs.width(); bit++) {
for (int bit = 0; bit < rhs.width(); ++bit) {
setBit(obit, rhs.bitIs(bit));
obit++;
++obit;
}
for (int bit = 0; bit < lhs.width(); bit++) {
for (int bit = 0; bit < lhs.width(); ++bit) {
setBit(obit, lhs.bitIs(bit));
obit++;
++obit;
}
return *this;
}
@@ -1504,7 +1504,7 @@ V3Number& V3Number::opStreamL(const V3Number& lhs, const V3Number& rhs) {
const int ssize = std::min(rhs.toUInt(), static_cast<unsigned>(lhs.width()));
for (int istart = 0; istart < lhs.width(); istart += ssize) {
const int ostart = std::max(0, lhs.width() - ssize - istart);
for (int bit = 0; bit < ssize && bit < lhs.width() - istart; bit++) {
for (int bit = 0; bit < ssize && bit < lhs.width() - istart; ++bit) {
setBit(ostart + bit, lhs.bitIs(istart + bit));
}
}
@@ -1517,14 +1517,14 @@ V3Number& V3Number::opLogAnd(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
char loutc = 0;
char routc = 0;
for (int bit = 0; bit < lhs.width(); bit++) {
for (int bit = 0; bit < lhs.width(); ++bit) {
if (lhs.bitIs1(bit)) {
loutc = 1;
break;
}
if (lhs.bitIsXZ(bit) && loutc == 0) loutc = 'x';
}
for (int bit = 0; bit < rhs.width(); bit++) {
for (int bit = 0; bit < rhs.width(); ++bit) {
if (rhs.bitIs1(bit)) {
routc = 1;
break;
@@ -1542,14 +1542,14 @@ V3Number& V3Number::opLogOr(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
char outc = 0;
for (int bit = 0; bit < lhs.width(); bit++) {
for (int bit = 0; bit < lhs.width(); ++bit) {
if (lhs.bitIs1(bit)) {
outc = 1;
goto last;
}
if (lhs.bitIsXZ(bit) && outc == 0) outc = 'x';
}
for (int bit = 0; bit < rhs.width(); bit++) {
for (int bit = 0; bit < rhs.width(); ++bit) {
if (rhs.bitIs1(bit)) {
outc = 1;
goto last;
@@ -1658,7 +1658,7 @@ V3Number& V3Number::opEq(const V3Number& lhs, const V3Number& rhs) {
if (lhs.isString()) return opEqN(lhs, rhs);
if (lhs.isDouble()) return opEqD(lhs, rhs);
char outc = 1;
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); ++bit) {
if (lhs.bitIs1(bit) && rhs.bitIs0(bit)) {
outc = 0;
goto last;
@@ -1680,7 +1680,7 @@ V3Number& V3Number::opNeq(const V3Number& lhs, const V3Number& rhs) {
if (lhs.isString()) return opNeqN(lhs, rhs);
if (lhs.isDouble()) return opNeqD(lhs, rhs);
char outc = 0;
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); ++bit) {
if (lhs.bitIs1(bit) && rhs.bitIs0(bit)) {
outc = 1;
goto last;
@@ -1721,7 +1721,7 @@ V3Number& V3Number::opCaseNeq(const V3Number& lhs, const V3Number& rhs) {
} else if (lhs.isDouble()) {
return opNeqD(lhs, rhs);
}
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); ++bit) {
if (lhs.bitIs(bit) != rhs.bitIs(bit)) {
outc = 1;
goto last;
@@ -1735,7 +1735,7 @@ V3Number& V3Number::opWildEq(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
char outc = 1;
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); ++bit) {
if (!rhs.bitIsXZ(bit)) {
if (lhs.bitIs(bit) != rhs.bitIs(bit)) {
outc = 0;
@@ -1752,7 +1752,7 @@ V3Number& V3Number::opWildNeq(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
char outc = 0;
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); ++bit) {
if (!rhs.bitIsXZ(bit)) {
if (lhs.bitIs(bit) != rhs.bitIs(bit)) {
outc = 1;
@@ -1770,7 +1770,7 @@ V3Number& V3Number::opGt(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
char outc = 0;
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); ++bit) {
if (lhs.bitIs1(bit) && rhs.bitIs0(bit)) outc = 1;
if (rhs.bitIs1(bit) && lhs.bitIs0(bit)) outc = 0;
if (lhs.bitIsXZ(bit)) outc = 'x';
@@ -1796,7 +1796,7 @@ V3Number& V3Number::opGtS(const V3Number& lhs, const V3Number& rhs) {
outc = 0; // - !> +
} else {
// both positive or negative, normal >
for (int bit = 0; bit < std::max(lhs.width() - 1, rhs.width() - 1); bit++) {
for (int bit = 0; bit < std::max(lhs.width() - 1, rhs.width() - 1); ++bit) {
if (lhs.bitIs1Extend(bit) && rhs.bitIs0(bit)) outc = 1;
if (rhs.bitIs1Extend(bit) && lhs.bitIs0(bit)) outc = 0;
if (lhs.bitIsXZ(bit)) outc = 'x';
@@ -1834,12 +1834,12 @@ V3Number& V3Number::opShiftR(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
if (rhs.isFourState()) return setAllBitsX();
setZero();
for (int bit = 32; bit < rhs.width(); bit++) {
for (int bit = 32; bit < rhs.width(); ++bit) {
if (rhs.bitIs1(bit)) return *this; // shift of over 2^32 must be zero
}
const uint32_t rhsval = rhs.toUInt();
if (rhsval < static_cast<uint32_t>(lhs.width())) {
for (int bit = 0; bit < width(); bit++) setBit(bit, lhs.bitIs(bit + rhsval));
for (int bit = 0; bit < width(); ++bit) setBit(bit, lhs.bitIs(bit + rhsval));
}
return *this;
}
@@ -1853,8 +1853,8 @@ V3Number& V3Number::opShiftRS(const V3Number& lhs, const V3Number& rhs, uint32_t
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
if (rhs.isFourState()) return setAllBitsX();
setZero();
for (int bit = 32; bit < rhs.width(); bit++) {
for (int sbit = 0; sbit < width(); sbit++) {
for (int bit = 32; bit < rhs.width(); ++bit) {
for (int sbit = 0; sbit < width(); ++sbit) {
setBit(sbit, lhs.bitIs(lbits - 1)); // 0/1/X/Z
}
if (rhs.bitIs1(lbits - 1)) setAllBits1(); // -1 else 0
@@ -1862,11 +1862,11 @@ V3Number& V3Number::opShiftRS(const V3Number& lhs, const V3Number& rhs, uint32_t
}
const uint32_t rhsval = rhs.toUInt();
if (rhsval < static_cast<uint32_t>(lhs.width())) {
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
setBit(bit, lhs.bitIsExtend(bit + rhsval, lbits));
}
} else {
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
setBit(bit, lhs.bitIs(lbits - 1)); // 0/1/X/Z
}
}
@@ -1879,11 +1879,11 @@ V3Number& V3Number::opShiftL(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
if (rhs.isFourState()) return setAllBitsX();
setZero();
for (int bit = 32; bit < rhs.width(); bit++) {
for (int bit = 32; bit < rhs.width(); ++bit) {
if (rhs.bitIs1(bit)) return *this; // shift of over 2^32 must be zero
}
const uint32_t rhsval = rhs.toUInt();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (bit >= static_cast<int>(rhsval)) setBit(bit, lhs.bitIs(bit - rhsval));
}
return *this;
@@ -1912,7 +1912,7 @@ V3Number& V3Number::opAdd(const V3Number& lhs, const V3Number& rhs) {
setZero();
// Addem
uint64_t carry = 0;
for (int word = 0; word < words(); word++) {
for (int word = 0; word < words(); ++word) {
const uint64_t lwordval = lhs.m_data.num()[word].m_value;
const uint64_t rwordval = rhs.m_data.num()[word].m_value;
const uint64_t sum = lwordval + rwordval + carry;
@@ -1942,14 +1942,14 @@ V3Number& V3Number::opMul(const V3Number& lhs, const V3Number& rhs) {
setQuad(lhs.toUQuad() * rhs.toUQuad());
opCleanThis(); // Mult produces extra bits in result
} else {
for (int lword = 0; lword < lhs.words(); lword++) {
for (int lword = 0; lword < lhs.words(); ++lword) {
const uint64_t lwordval = static_cast<uint64_t>(lhs.m_data.num()[lword].m_value);
if (lwordval == 0) continue;
for (int rword = 0; rword < rhs.words(); rword++) {
for (int rword = 0; rword < rhs.words(); ++rword) {
const uint64_t rwordval = static_cast<uint64_t>(rhs.m_data.num()[rword].m_value);
if (rwordval == 0) continue;
uint64_t mul = lwordval * rwordval;
for (int qword = lword + rword; qword < words(); qword++) {
for (int qword = lword + rword; qword < words(); ++qword) {
mul += static_cast<uint64_t>(m_data.num()[qword].m_value);
m_data.num()[qword].m_value = (mul & 0xffffffffULL);
mul = (mul >> 32ULL) & 0xffffffffULL;
@@ -2093,8 +2093,8 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
uint32_t vn[VL_MULS_MAX_WORDS + 1]; // v normalized
// Zero for ease of debugging and to save having to zero for shifts
for (int i = 0; i < words; i++) m_data.num()[i].m_value = 0;
for (int i = 0; i < words + 1; i++) { un[i] = vn[i] = 0; } // +1 as vn may get extra word
for (int i = 0; i < words; ++i) m_data.num()[i].m_value = 0;
for (int i = 0; i < words + 1; ++i) { un[i] = vn[i] = 0; } // +1 as vn may get extra word
// Algorithm requires divisor MSB to be set
// Copy and shift to normalize divisor so MSB of vn[vw-1] is set
@@ -2139,7 +2139,7 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
int64_t t = 0; // Must be signed
uint64_t k = 0;
for (int i = 0; i < vw; i++) {
for (int i = 0; i < vw; ++i) {
const uint64_t p = qhat * vn[i]; // Multiply by estimate
t = un[i + j] - k - (p & 0xFFFFFFFFULL); // Subtract
un[i + j] = t;
@@ -2153,7 +2153,7 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
// Over subtracted; correct by adding back
m_data.num()[j].m_value--;
k = 0;
for (int i = 0; i < vw; i++) {
for (int i = 0; i < vw; ++i) {
t = static_cast<uint64_t>(un[i + j]) + static_cast<uint64_t>(vn[i]) + k;
un[i + j] = t;
k = t >> 32ULL;
@@ -2168,10 +2168,10 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
if (is_modulus) { // modulus
// Need to reverse normalization on copy to output
for (int i = 0; i < vw; i++) {
for (int i = 0; i < vw; ++i) {
m_data.num()[i].m_value = (un[i] >> s) | (shift_mask & (un[i + 1] << (32 - s)));
}
for (int i = vw; i < words; i++) m_data.num()[i].m_value = 0;
for (int i = vw; i < words; ++i) m_data.num()[i].m_value = 0;
opCleanThis();
UINFO(9, " opmoddiv-mod " << lhs << " " << rhs << " now=" << *this << endl);
return *this;
@@ -2209,7 +2209,7 @@ V3Number& V3Number::opPow(const V3Number& lhs, const V3Number& rhs, bool lsign,
m_data.num()[0].m_value = 1;
V3Number power(&lhs, width());
power.opAssign(lhs);
for (int bit = 0; bit < rhs.width(); bit++) {
for (int bit = 0; bit < rhs.width(); ++bit) {
if (bit > 0) { // power = power*power
V3Number lastPower(&lhs, width());
lastPower.opAssign(power);
@@ -2241,7 +2241,7 @@ V3Number& V3Number::opBufIf1(const V3Number& ens, const V3Number& if1s) {
NUM_ASSERT_OP_ARGS2(ens, if1s);
NUM_ASSERT_LOGIC_ARGS2(ens, if1s);
setZero();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (ens.bitIs1(bit)) {
setBit(bit, if1s.bitIs(bit));
} else {
@@ -2273,7 +2273,7 @@ V3Number& V3Number::opAssignNonXZ(const V3Number& lhs, bool ignoreXZ) {
} else if (lhs.isDouble()) {
setDouble(lhs.toDouble());
} else {
for (int bit = 0; bit < this->width(); bit++) {
for (int bit = 0; bit < this->width(); ++bit) {
setBit(bit, ignoreXZ ? lhs.bitIs1(bit) : lhs.bitIs(bit));
}
}
@@ -2302,7 +2302,7 @@ V3Number& V3Number::opExtendS(const V3Number& lhs, uint32_t lbits) {
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
setZero();
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
const char extendWith = lhs.bitIsExtend(bit, lbits);
setBit(bit, extendWith);
}
@@ -2314,7 +2314,7 @@ V3Number& V3Number::opExtendXZ(const V3Number& lhs, uint32_t lbits) {
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
setZero();
for (int bit = 0; bit < width(); bit++) setBit(bit, lhs.bitIsExtend(bit, lbits));
for (int bit = 0; bit < width(); ++bit) setBit(bit, lhs.bitIsExtend(bit, lbits));
return *this;
}
@@ -2347,7 +2347,7 @@ V3Number& V3Number::opSel(const V3Number& lhs, uint32_t msbval, uint32_t lsbval)
NUM_ASSERT_LOGIC_ARGS1(lhs);
setZero();
int ibit = lsbval;
for (int bit = 0; bit < width(); bit++) {
for (int bit = 0; bit < width(); ++bit) {
if (ibit >= 0 && ibit < lhs.width() && ibit <= static_cast<int>(msbval)) {
setBit(bit, lhs.bitIs(ibit));
} else {
@@ -2368,13 +2368,13 @@ V3Number& V3Number::opSelInto(const V3Number& lhs, int lsbval, int width) {
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
int ibit = 0;
for (int bit = lsbval; bit < lsbval + width; bit++) {
for (int bit = lsbval; bit < lsbval + width; ++bit) {
if (ibit >= 0 && ibit < lhs.width()) {
setBit(bit, lhs.bitIs(ibit));
} else {
setBitX0(bit);
}
ibit++;
++ibit;
}
return *this;
}
@@ -2544,7 +2544,7 @@ V3Number& V3Number::opReplN(const V3Number& lhs, uint32_t rhsval) {
NUM_ASSERT_STRING_ARGS1(lhs);
string out;
out.reserve(lhs.toString().length() * rhsval);
for (unsigned times = 0; times < rhsval; times++) out += lhs.toString();
for (unsigned times = 0; times < rhsval; ++times) out += lhs.toString();
return setString(out);
}
V3Number& V3Number::opToLowerN(const V3Number& lhs) {