Fix huge shifts to zero with -Wno-WIDTH, bug766.

This commit is contained in:
Wilson Snyder 2014-05-15 21:49:43 -04:00
parent 1f2abb9c0f
commit d3049d9c89
4 changed files with 28 additions and 6 deletions

View File

@ -9,7 +9,7 @@ indicates the contributor was also the author of the fix; Thanks!
*** Support SV 2012 package import before port list.
**** Fix huge shifts to zero with -Wno-WIDTH, bug765. [Clifford Wolf]
**** Fix huge shifts to zero with -Wno-WIDTH, bug765, bug766. [Clifford Wolf]
**** Fix gate primitives with arrays and non-arrayed pins.

View File

@ -1125,8 +1125,10 @@ V3Number& V3Number::opShiftR (const V3Number& lhs, const V3Number& rhs) {
if (rhs.isFourState()) return setAllBitsX();
setZero();
uint32_t rhsval = rhs.toUInt();
for (int bit=0; bit<this->width(); bit++) {
setBit(bit,lhs.bitIs(bit + rhsval));
if (rhsval < (uint32_t)lhs.width()) {
for (int bit=0; bit<this->width(); bit++) {
setBit(bit,lhs.bitIs(bit + rhsval));
}
}
return *this;
}
@ -1138,8 +1140,14 @@ V3Number& V3Number::opShiftRS (const V3Number& lhs, const V3Number& rhs) {
if (rhs.isFourState()) return setAllBitsX();
setZero();
uint32_t rhsval = rhs.toUInt();
for (int bit=0; bit<this->width(); bit++) {
setBit(bit,lhs.bitIsExtend(bit + rhsval));
if (rhsval < (uint32_t)lhs.width()) {
for (int bit=0; bit<this->width(); bit++) {
setBit(bit,lhs.bitIsExtend(bit + rhsval));
}
} else {
for (int bit=0; bit<this->width(); bit++) {
setBit(bit,lhs.bitIsExtend(lhs.width()-1));
}
}
return *this;
}

View File

@ -60,13 +60,14 @@ public:
}
private:
char bitIs (int bit) const {
if (bit>=m_width) {
if (bit>=m_width || bit<0) {
// We never sign extend
return '0';
}
return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0)
| ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); }
char bitIsExtend (int bit) const {
if (bit<0) return '0';
if (bit>=m_width) {
bit = m_width-1;
// We do sign extend
@ -76,22 +77,28 @@ private:
return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0)
| ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); }
bool bitIs0 (int bit) const {
if (bit<0) return false;
if (bit>=m_width) return !bitIsXZ(m_width-1);
return ( (m_value[bit/32] & (1UL<<(bit&31)))==0 && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); }
bool bitIs1 (int bit) const {
if (bit<0) return false;
if (bit>=m_width) return false;
return ( (m_value[bit/32] & (1UL<<(bit&31))) && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); }
bool bitIs1Extend (int bit) const {
if (bit<0) return false;
if (bit>=m_width) return bitIs1Extend(m_width-1);
return ( (m_value[bit/32] & (1UL<<(bit&31))) && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); }
bool bitIsX (int bit) const {
if (bit<0) return false;
if (bit>=m_width) return bitIsZ(m_width-1);
return ( (m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); }
bool bitIsXZ(int bit) const {
if (bit<0) return false;
if (bit>=m_width) return bitIsXZ(m_width-1);
return ( (m_valueX[bit/32] & (1UL<<(bit&31))) && 1);
}
bool bitIsZ (int bit) const {
if (bit<0) return false;
if (bit>=m_width) return bitIsZ(m_width-1);
return ( (~m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); }
uint32_t bitsValue(int lsb, int nbits) const {

View File

@ -15,6 +15,8 @@
reg [2:0] w3_u;
reg [3:0] w4_u;
reg [4:0] w5_u;
reg [15:0] w16a_u;
reg [15:0] w16_u;
real r;
reg signed [4:0] bug754_a;
@ -116,6 +118,11 @@
w4_u = (w3_u >> 2'b11) >> 1;
`checkh(w4_u, 4'b0000);
// bug766
w16a_u = 16'h1234;
w16_u = (w16a_u >> 16) >>> 32'h7ffffff1;
`checkh(w16_u, 16'h0000);
if (fail) $stop;
$write("*-* All Finished *-*\n");
$finish;