Internals: Prep for #2597. No functional change intended
This commit is contained in:
parent
9655e287ab
commit
6e7b07c794
|
|
@ -1709,39 +1709,7 @@ private:
|
||||||
width = 1;
|
width = 1;
|
||||||
}
|
}
|
||||||
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, PRELIM).p());
|
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, PRELIM).p());
|
||||||
AstBasicDType* underDtp = VN_CAST(nodep->lhsp()->dtypep(), BasicDType);
|
castSized(nodep, nodep->lhsp(), width); // lhsp may change
|
||||||
if (!underDtp) underDtp = nodep->lhsp()->dtypep()->basicp();
|
|
||||||
if (!underDtp) {
|
|
||||||
nodep->v3warn(E_UNSUPPORTED,
|
|
||||||
"Unsupported: Size-changing cast on non-basic data type");
|
|
||||||
underDtp = VN_CAST(nodep->findLogicBoolDType(), BasicDType);
|
|
||||||
}
|
|
||||||
// A cast propagates its size to the lower expression and is included in the maximum
|
|
||||||
// width, so 23'(1'b1 + 1'b1) uses 23-bit math, but 1'(2'h2 * 2'h1) uses two-bit math.
|
|
||||||
// However the output width is exactly that requested.
|
|
||||||
// So two steps, first do the calculation's width (max of the two widths)
|
|
||||||
{
|
|
||||||
int calcWidth = std::max(width, underDtp->width());
|
|
||||||
AstNodeDType* calcDtp
|
|
||||||
= (underDtp->isFourstate()
|
|
||||||
? nodep->findLogicDType(calcWidth, calcWidth, underDtp->numeric())
|
|
||||||
: nodep->findBitDType(calcWidth, calcWidth, underDtp->numeric()));
|
|
||||||
nodep->dtypep(calcDtp);
|
|
||||||
// We ignore warnings as that is sort of the point of a cast
|
|
||||||
iterateCheck(nodep, "Cast expr", nodep->lhsp(), CONTEXT, FINAL, calcDtp,
|
|
||||||
EXTEND_EXP, false);
|
|
||||||
}
|
|
||||||
// if (debug()) nodep->dumpTree(cout, " CastSizeClc: ");
|
|
||||||
// Next step, make the proper output width
|
|
||||||
{
|
|
||||||
AstNodeDType* outDtp
|
|
||||||
= (underDtp->isFourstate()
|
|
||||||
? nodep->findLogicDType(width, width, underDtp->numeric())
|
|
||||||
: nodep->findBitDType(width, width, underDtp->numeric()));
|
|
||||||
nodep->dtypep(outDtp);
|
|
||||||
// We ignore warnings as that is sort of the point of a cast
|
|
||||||
widthCheckSized(nodep, "Cast expr", nodep->lhsp(), outDtp, EXTEND_EXP, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (m_vup->final()) {
|
if (m_vup->final()) {
|
||||||
// CastSize not needed once sizes determined
|
// CastSize not needed once sizes determined
|
||||||
|
|
@ -1751,6 +1719,42 @@ private:
|
||||||
}
|
}
|
||||||
// if (debug()) nodep->dumpTree(cout, " CastSizeOut: ");
|
// if (debug()) nodep->dumpTree(cout, " CastSizeOut: ");
|
||||||
}
|
}
|
||||||
|
void castSized(AstNode* nodep, AstNode* underp, int width) {
|
||||||
|
AstBasicDType* underDtp = VN_CAST(underp->dtypep(), BasicDType);
|
||||||
|
if (!underDtp) underDtp = underp->dtypep()->basicp();
|
||||||
|
if (!underDtp) {
|
||||||
|
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Size-changing cast on non-basic data type");
|
||||||
|
underDtp = VN_CAST(nodep->findLogicBoolDType(), BasicDType);
|
||||||
|
}
|
||||||
|
UASSERT_OBJ(underp == nodep->op1p(), nodep, "Assuming op1 is cast value");
|
||||||
|
// A cast propagates its size to the lower expression and is included in the maximum
|
||||||
|
// width, so 23'(1'b1 + 1'b1) uses 23-bit math, but 1'(2'h2 * 2'h1) uses two-bit math.
|
||||||
|
// However the output width is exactly that requested.
|
||||||
|
// So two steps, first do the calculation's width (max of the two widths)
|
||||||
|
{
|
||||||
|
int calcWidth = std::max(width, underDtp->width());
|
||||||
|
AstNodeDType* calcDtp
|
||||||
|
= (underDtp->isFourstate()
|
||||||
|
? nodep->findLogicDType(calcWidth, calcWidth, underDtp->numeric())
|
||||||
|
: nodep->findBitDType(calcWidth, calcWidth, underDtp->numeric()));
|
||||||
|
nodep->dtypep(calcDtp);
|
||||||
|
// We ignore warnings as that is sort of the point of a cast
|
||||||
|
iterateCheck(nodep, "Cast expr", underp, CONTEXT, FINAL, calcDtp, EXTEND_EXP, false);
|
||||||
|
VL_DANGLING(underp);
|
||||||
|
underp = nodep->op1p(); // Above asserts that op1 was underp pre-relink
|
||||||
|
}
|
||||||
|
// if (debug()) nodep->dumpTree(cout, " CastSizeClc: ");
|
||||||
|
// Next step, make the proper output width
|
||||||
|
{
|
||||||
|
AstNodeDType* outDtp = (underDtp->isFourstate()
|
||||||
|
? nodep->findLogicDType(width, width, underDtp->numeric())
|
||||||
|
: nodep->findBitDType(width, width, underDtp->numeric()));
|
||||||
|
nodep->dtypep(outDtp);
|
||||||
|
// We ignore warnings as that is sort of the point of a cast
|
||||||
|
widthCheckSized(nodep, "Cast expr", underp, outDtp, EXTEND_EXP, false);
|
||||||
|
VL_DANGLING(underp);
|
||||||
|
}
|
||||||
|
}
|
||||||
virtual void visit(AstVar* nodep) override {
|
virtual void visit(AstVar* nodep) override {
|
||||||
// if (debug()) nodep->dumpTree(cout, " InitPre: ");
|
// if (debug()) nodep->dumpTree(cout, " InitPre: ");
|
||||||
// Must have deterministic constant width
|
// Must have deterministic constant width
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue