Fix implicit casts in assignments (part 4).
This patch fixes a few issues/bugs that showed up when testing the fixes for implicit casts: 1. Make the compile-time implementation of $abs, $min, and $max match the run-time behaviour (system functions can't be polymorphic). 2. Correctly set the type (signed/unsigned) of the result of an assignment inside a constant user function (the LHS should not inherit the type of the RHS). 3. Fix a bug in the verinum(double) constructor (insufficient bits were allocated in the case where the double value rounded up to the next power of two).
This commit is contained in:
parent
faece5816c
commit
e8d4039175
40
eval_tree.cc
40
eval_tree.cc
|
|
@ -1812,23 +1812,19 @@ NetExpr* NetESFunc::evaluate_abs_(const NetExpr*arg_) const
|
|||
NetExpr*res = 0;
|
||||
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg_);
|
||||
if (tmpi) {
|
||||
verinum arg = tmpi->value();
|
||||
if (arg.is_negative()) {
|
||||
arg = v_not(arg) + verinum(1);
|
||||
}
|
||||
res = new NetEConst(arg);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
const NetECReal*tmpr = dynamic_cast<const NetECReal*>(arg_);
|
||||
if (tmpr) {
|
||||
double arg = tmpr->value().as_double();
|
||||
if (tmpi || tmpr) {
|
||||
double arg;
|
||||
if (tmpi) {
|
||||
arg = tmpi->value().as_double();
|
||||
} else {
|
||||
arg = tmpr->value().as_double();
|
||||
}
|
||||
res = new NetECReal(verireal(fabs(arg)));
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
eval_debug(this, res, tmpr != 0);
|
||||
eval_debug(this, res, true);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1842,23 +1838,7 @@ NetExpr* NetESFunc::evaluate_min_max_(ID id, const NetExpr*arg0_,
|
|||
|
||||
NetExpr*res = 0;
|
||||
|
||||
if (tmpi0 && tmpi1) {
|
||||
verinum arg0 = tmpi0->value();
|
||||
verinum arg1 = tmpi1->value();
|
||||
switch (id) {
|
||||
case MIN:
|
||||
res = new NetEConst( arg0 < arg1 ? arg0 : arg1);
|
||||
break;
|
||||
case MAX:
|
||||
res = new NetEConst( arg0 < arg1 ? arg1 : arg0);
|
||||
break;
|
||||
default:
|
||||
ivl_assert(*this, 0);
|
||||
break;
|
||||
}
|
||||
ivl_assert(*this, res);
|
||||
|
||||
} else if ((tmpi0 || tmpr0) && (tmpi1 || tmpr1)) {
|
||||
if ((tmpi0 || tmpr0) && (tmpi1 || tmpr1)) {
|
||||
double arg0, arg1;
|
||||
if (tmpi0) {
|
||||
arg0 = tmpi0->value().as_double();
|
||||
|
|
@ -1884,7 +1864,7 @@ NetExpr* NetESFunc::evaluate_min_max_(ID id, const NetExpr*arg0_,
|
|||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
eval_debug(this, res, tmpr0 || tmpr1);
|
||||
eval_debug(this, res, true);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -170,6 +170,8 @@ bool NetAssign::evaluate_function(const LineInfo&loc,
|
|||
delete base_result;
|
||||
delete rval_result;
|
||||
rval_result = new NetEConst(lval_v);
|
||||
} else {
|
||||
rval_result->cast_signed(lval->sig()->get_signed());
|
||||
}
|
||||
|
||||
if (ptr->second)
|
||||
|
|
|
|||
|
|
@ -192,6 +192,10 @@ verinum::verinum(double val, bool)
|
|||
val = -val;
|
||||
}
|
||||
|
||||
/* Round to the nearest integer now, as this may increase the
|
||||
number of bits we need to allocate. */
|
||||
val = round(val);
|
||||
|
||||
/* Get the exponent and fractional part of the number. */
|
||||
fraction = frexp(val, &exponent);
|
||||
nbits_ = exponent+1;
|
||||
|
|
@ -222,7 +226,6 @@ verinum::verinum(double val, bool)
|
|||
bits_[idx] = (bits&1) ? V1 : V0;
|
||||
bits >>= 1;
|
||||
}
|
||||
if (fraction >= 0.5) *this = *this + const_one;
|
||||
} else {
|
||||
for (int wd = nwords; wd >= 0; wd -= 1) {
|
||||
unsigned long bits = (unsigned long) fraction;
|
||||
|
|
@ -235,7 +238,6 @@ verinum::verinum(double val, bool)
|
|||
}
|
||||
fraction = ldexp(fraction, BITS_IN_LONG);
|
||||
}
|
||||
if (fraction >= ldexp(0.5, BITS_IN_LONG)) *this = *this + const_one;
|
||||
}
|
||||
|
||||
/* Convert a negative number if needed. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue