mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +02:00
clang-format remaining sources. No functional change.
This commit is contained in:
+178
-180
@@ -65,13 +65,16 @@ private:
|
||||
AstNodeDType* m_errp; // Node that was found, for error reporting if not known type
|
||||
AstNodeDType* m_dtypep; // Data type for the 'from' slice
|
||||
VNumRange m_fromRange; // Numeric range bounds for the 'from' slice
|
||||
FromData(AstNodeDType* errp, AstNodeDType* dtypep, const VNumRange& fromRange)
|
||||
{ m_errp = errp; m_dtypep = dtypep; m_fromRange = fromRange; }
|
||||
FromData(AstNodeDType* errp, AstNodeDType* dtypep, const VNumRange& fromRange) {
|
||||
m_errp = errp;
|
||||
m_dtypep = dtypep;
|
||||
m_fromRange = fromRange;
|
||||
}
|
||||
~FromData() {}
|
||||
};
|
||||
FromData fromDataForArray(AstNode* nodep, AstNode* basefromp) {
|
||||
// What is the data type and information for this SEL-ish's from()?
|
||||
UINFO(9," fromData start ddtypep = "<<basefromp<<endl);
|
||||
UINFO(9, " fromData start ddtypep = " << basefromp << endl);
|
||||
VNumRange fromRange; // constructs to isRanged(false)
|
||||
while (basefromp) {
|
||||
if (VN_IS(basefromp, AttrOf)) {
|
||||
@@ -83,33 +86,29 @@ private:
|
||||
UASSERT_OBJ(basefromp && basefromp->dtypep(), nodep, "Select with no from dtype");
|
||||
AstNodeDType* ddtypep = basefromp->dtypep()->skipRefp();
|
||||
AstNodeDType* errp = ddtypep;
|
||||
UINFO(9," fromData.ddtypep = "<<ddtypep<<endl);
|
||||
UINFO(9, " fromData.ddtypep = " << ddtypep << endl);
|
||||
if (const AstNodeArrayDType* adtypep = VN_CAST(ddtypep, NodeArrayDType)) {
|
||||
fromRange = adtypep->declRange();
|
||||
}
|
||||
else if (VN_IS(ddtypep, AssocArrayDType)) {
|
||||
}
|
||||
else if (VN_IS(ddtypep, DynArrayDType)) {
|
||||
}
|
||||
else if (VN_IS(ddtypep, QueueDType)) {
|
||||
}
|
||||
else if (const AstNodeUOrStructDType* adtypep = VN_CAST(ddtypep, NodeUOrStructDType)) {
|
||||
} else if (VN_IS(ddtypep, AssocArrayDType)) {
|
||||
} else if (VN_IS(ddtypep, DynArrayDType)) {
|
||||
} else if (VN_IS(ddtypep, QueueDType)) {
|
||||
} else if (const AstNodeUOrStructDType* adtypep = VN_CAST(ddtypep, NodeUOrStructDType)) {
|
||||
fromRange = adtypep->declRange();
|
||||
}
|
||||
else if (AstBasicDType* adtypep = VN_CAST(ddtypep, BasicDType)) {
|
||||
} else if (AstBasicDType* adtypep = VN_CAST(ddtypep, BasicDType)) {
|
||||
if (adtypep->isString() && VN_IS(nodep, SelBit)) {
|
||||
} else if (adtypep->isRanged()) {
|
||||
UASSERT_OBJ(!(adtypep->rangep()
|
||||
&& (!VN_IS(adtypep->rangep()->msbp(), Const)
|
||||
|| !VN_IS(adtypep->rangep()->lsbp(), Const))),
|
||||
nodep, "Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep)
|
||||
UASSERT_OBJ(
|
||||
!(adtypep->rangep()
|
||||
&& (!VN_IS(adtypep->rangep()->msbp(), Const)
|
||||
|| !VN_IS(adtypep->rangep()->lsbp(), Const))),
|
||||
nodep,
|
||||
"Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep)
|
||||
fromRange = adtypep->declRange();
|
||||
} else {
|
||||
nodep->v3error("Illegal bit or array select; type does not have a bit range, or "
|
||||
<< "bad dimension: data type is " << errp->prettyDTypeNameQ());
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
nodep->v3error("Illegal bit or array select; type already selected, or bad dimension: "
|
||||
<< "data type is " << errp->prettyDTypeNameQ());
|
||||
}
|
||||
@@ -123,7 +122,7 @@ private:
|
||||
return lhsp;
|
||||
} else if (VN_IS(lhsp, Const)) {
|
||||
// Optional vs just making add/sub below, but saves constification some work
|
||||
V3Number num (lhsp, lhsp->width());
|
||||
V3Number num(lhsp, lhsp->width());
|
||||
num.opSub(VN_CAST(lhsp, Const)->num(), V3Number(lhsp, 32, rhs));
|
||||
num.isSigned(lhsp->isSigned());
|
||||
AstNode* newp = new AstConst(lhsp->fileline(), num);
|
||||
@@ -135,8 +134,9 @@ private:
|
||||
newp->dtypeFrom(lhsp);
|
||||
return newp;
|
||||
} else { // rhs < 0;
|
||||
AstNode* newp = new AstAdd(lhsp->fileline(), lhsp,
|
||||
new AstConst(lhsp->fileline(), AstConst::Unsized32(), -rhs));
|
||||
AstNode* newp
|
||||
= new AstAdd(lhsp->fileline(), lhsp,
|
||||
new AstConst(lhsp->fileline(), AstConst::Unsized32(), -rhs));
|
||||
// We must make sure sub gets sign of original value, not from the constant
|
||||
newp->dtypeFrom(lhsp);
|
||||
return newp;
|
||||
@@ -145,9 +145,8 @@ private:
|
||||
AstNode* newSubNeg(vlsint32_t lhs, AstNode* rhsp) {
|
||||
// Return lhs-rhs
|
||||
// We must make sure sub gets sign of original value
|
||||
AstNode* newp = new AstSub(rhsp->fileline(),
|
||||
new AstConst(rhsp->fileline(), AstConst::Unsized32(), lhs),
|
||||
rhsp);
|
||||
AstNode* newp = new AstSub(
|
||||
rhsp->fileline(), new AstConst(rhsp->fileline(), AstConst::Unsized32(), lhs), rhsp);
|
||||
newp->dtypeFrom(rhsp); // Important as AstSub default is lhs's sign
|
||||
return newp;
|
||||
}
|
||||
@@ -176,13 +175,13 @@ private:
|
||||
|
||||
AstNodeDType* sliceDType(AstPackArrayDType* nodep, int msb, int lsb) {
|
||||
// Return slice needed for msb/lsb, either as original dtype or a new slice dtype
|
||||
if (nodep->declRange().elements() == (msb-lsb+1) // Extracting whole of original array
|
||||
if (nodep->declRange().elements() == (msb - lsb + 1) // Extracting whole of original array
|
||||
&& nodep->declRange().lo() == lsb) {
|
||||
return nodep;
|
||||
} else {
|
||||
// Need a slice data type, which is an array of the extracted
|
||||
// type, but with (presumably) different size
|
||||
VNumRange newRange (msb, lsb, nodep->declRange().littleEndian());
|
||||
VNumRange newRange(msb, lsb, nodep->declRange().littleEndian());
|
||||
AstNodeDType* vardtypep
|
||||
= new AstPackArrayDType(nodep->fileline(),
|
||||
nodep->subDTypep(), // Need to strip off array reference
|
||||
@@ -198,85 +197,78 @@ private:
|
||||
virtual void visit(AstSelBit* nodep) VL_OVERRIDE {
|
||||
// Select of a non-width specified part of an array, i.e. "array[2]"
|
||||
// This select style has a lsb and msb (no user specified width)
|
||||
UINFO(6,"SELBIT "<<nodep<<endl);
|
||||
if (debug()>=9) nodep->backp()->dumpTree(cout, "--SELBT0: ");
|
||||
UINFO(6, "SELBIT " << nodep << endl);
|
||||
if (debug() >= 9) nodep->backp()->dumpTree(cout, "--SELBT0: ");
|
||||
// lhsp/rhsp do not need to be constant
|
||||
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting
|
||||
if (debug()>=9) nodep->dumpTree(cout, "--SELBT2: ");
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "--SELBT2: ");
|
||||
FromData fromdata = fromDataForArray(nodep, fromp);
|
||||
AstNodeDType* ddtypep = fromdata.m_dtypep;
|
||||
VNumRange fromRange = fromdata.m_fromRange;
|
||||
UINFO(6," ddtypep "<<ddtypep<<endl);
|
||||
UINFO(6, " ddtypep " << ddtypep << endl);
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(ddtypep, UnpackArrayDType)) {
|
||||
// SELBIT(array, index) -> ARRAYSEL(array, index)
|
||||
AstNode* subp = rhsp;
|
||||
if (fromRange.lo()!=0 || fromRange.hi()<0) {
|
||||
if (fromRange.lo() != 0 || fromRange.hi() < 0) {
|
||||
subp = newSubNeg(subp, fromRange.lo());
|
||||
}
|
||||
AstArraySel* newp = new AstArraySel(nodep->fileline(),
|
||||
fromp, subp);
|
||||
AstArraySel* newp = new AstArraySel(nodep->fileline(), fromp, subp);
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference
|
||||
if (debug()>=9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
// SELBIT(array, index) -> SEL(array, index*width-of-subindex, width-of-subindex)
|
||||
AstNode* subp = rhsp;
|
||||
if (fromRange.lo()!=0 || fromRange.hi()<0) {
|
||||
if (fromRange.lo() != 0 || fromRange.hi() < 0) {
|
||||
if (fromRange.littleEndian()) {
|
||||
subp = newSubNeg(fromRange.hi(), subp);
|
||||
} else {
|
||||
subp = newSubNeg(subp, fromRange.lo());
|
||||
}
|
||||
}
|
||||
UASSERT_OBJ(!(!fromRange.elements()
|
||||
|| (adtypep->width() % fromRange.elements())!=0), adtypep,
|
||||
"Array extraction with width miscomputed "
|
||||
<<adtypep->width()<<"/"<<fromRange.elements());
|
||||
UASSERT_OBJ(!(!fromRange.elements() || (adtypep->width() % fromRange.elements()) != 0),
|
||||
adtypep,
|
||||
"Array extraction with width miscomputed " << adtypep->width() << "/"
|
||||
<< fromRange.elements());
|
||||
int elwidth = adtypep->width() / fromRange.elements();
|
||||
AstSel* newp
|
||||
= new AstSel(nodep->fileline(),
|
||||
fromp,
|
||||
new AstMul(nodep->fileline(),
|
||||
new AstConst(nodep->fileline(),
|
||||
AstConst::Unsized32(), elwidth),
|
||||
subp),
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), elwidth));
|
||||
AstSel* newp = new AstSel(
|
||||
nodep->fileline(), fromp,
|
||||
new AstMul(nodep->fileline(),
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), elwidth), subp),
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), elwidth));
|
||||
newp->declRange(fromRange);
|
||||
newp->declElWidth(elwidth);
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference
|
||||
if (debug()>=9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else if (AstAssocArrayDType* adtypep = VN_CAST(ddtypep, AssocArrayDType)) {
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (AstAssocArrayDType* adtypep = VN_CAST(ddtypep, AssocArrayDType)) {
|
||||
// SELBIT(array, index) -> ASSOCSEL(array, index)
|
||||
AstNode* subp = rhsp;
|
||||
AstAssocSel* newp = new AstAssocSel(nodep->fileline(),
|
||||
fromp, subp);
|
||||
AstAssocSel* newp = new AstAssocSel(nodep->fileline(), fromp, subp);
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference
|
||||
if (debug()>=9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else if (AstDynArrayDType* adtypep = VN_CAST(ddtypep, DynArrayDType)) {
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (AstDynArrayDType* adtypep = VN_CAST(ddtypep, DynArrayDType)) {
|
||||
// SELBIT(array, index) -> CMETHODCALL(queue, "at", index)
|
||||
AstNode* subp = rhsp;
|
||||
AstCMethodHard* newp = new AstCMethodHard(nodep->fileline(),
|
||||
fromp, "at", subp);
|
||||
AstCMethodHard* newp = new AstCMethodHard(nodep->fileline(), fromp, "at", subp);
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference
|
||||
if (debug()>=9) newp->dumpTree(cout, "--SELBTq: ");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else if (AstQueueDType* adtypep = VN_CAST(ddtypep, QueueDType)) {
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTq: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (AstQueueDType* adtypep = VN_CAST(ddtypep, QueueDType)) {
|
||||
// SELBIT(array, index) -> CMETHODCALL(queue, "at", index)
|
||||
AstNode* subp = rhsp;
|
||||
AstCMethodHard* newp = new AstCMethodHard(nodep->fileline(),
|
||||
fromp, "at", subp);
|
||||
AstCMethodHard* newp = new AstCMethodHard(nodep->fileline(), fromp, "at", subp);
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference
|
||||
if (debug()>=9) newp->dumpTree(cout, "--SELBTq: ");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else if (VN_IS(ddtypep, BasicDType) && ddtypep->isString()) {
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTq: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(ddtypep, BasicDType) && ddtypep->isString()) {
|
||||
// SELBIT(string, index) -> GETC(string, index)
|
||||
AstNodeVarRef* varrefp = VN_CAST(fromp, NodeVarRef);
|
||||
if (!varrefp) nodep->v3error("Unsupported: String array operation on non-variable");
|
||||
@@ -291,29 +283,25 @@ private:
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(ddtypep, BasicDType)) {
|
||||
// SELBIT(range, index) -> SEL(array, index, 1)
|
||||
AstSel* newp = new AstSel(nodep->fileline(),
|
||||
fromp,
|
||||
newSubLsbOf(rhsp, fromRange),
|
||||
AstSel* newp = new AstSel(nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange),
|
||||
// Unsized so width from user
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
|
||||
newp->declRange(fromRange);
|
||||
UINFO(6," new "<<newp<<endl);
|
||||
if (debug()>=9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else if (VN_IS(ddtypep, NodeUOrStructDType)) { // A bit from the packed struct
|
||||
UINFO(6, " new " << newp << endl);
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(ddtypep, NodeUOrStructDType)) { // A bit from the packed struct
|
||||
// SELBIT(range, index) -> SEL(array, index, 1)
|
||||
AstSel* newp = new AstSel(nodep->fileline(),
|
||||
fromp,
|
||||
newSubLsbOf(rhsp, fromRange),
|
||||
AstSel* newp = new AstSel(nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange),
|
||||
// Unsized so width from user
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
|
||||
newp->declRange(fromRange);
|
||||
UINFO(6," new "<<newp<<endl);
|
||||
if (debug()>=9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else { // NULL=bad extract, or unknown node type
|
||||
UINFO(6, " new " << newp << endl);
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else { // NULL=bad extract, or unknown node type
|
||||
nodep->v3error("Illegal bit or array select; type already selected, or bad dimension: "
|
||||
<< "data type is" << fromdata.m_errp->prettyDTypeNameQ());
|
||||
// How to recover? We'll strip a dimension.
|
||||
@@ -326,20 +314,22 @@ private:
|
||||
// Select of a range specified part of an array, i.e. "array[2:3]"
|
||||
// SELEXTRACT(from,msb,lsb) -> SEL(from, lsb, 1+msb-lsb)
|
||||
// This select style has a (msb or lsb) and width
|
||||
UINFO(6,"SELEXTRACT "<<nodep<<endl);
|
||||
//if (debug()>=9) nodep->dumpTree(cout, "--SELEX0: ");
|
||||
UINFO(6, "SELEXTRACT " << nodep << endl);
|
||||
// if (debug() >= 9) nodep->dumpTree(cout, "--SELEX0: ");
|
||||
// Below 2 lines may change nodep->widthp()
|
||||
V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node
|
||||
V3Const::constifyParamsEdit(nodep->msbp()); // May relink pointed to node
|
||||
//if (debug()>=9) nodep->dumpTree(cout, "--SELEX3: ");
|
||||
checkConstantOrReplace(nodep->lsbp(), "First value of [a:b] isn't a constant, maybe you want +: or -:");
|
||||
checkConstantOrReplace(nodep->msbp(), "Second value of [a:b] isn't a constant, maybe you want +: or -:");
|
||||
// if (debug() >= 9) nodep->dumpTree(cout, "--SELEX3: ");
|
||||
checkConstantOrReplace(nodep->lsbp(),
|
||||
"First value of [a:b] isn't a constant, maybe you want +: or -:");
|
||||
checkConstantOrReplace(nodep->msbp(),
|
||||
"Second value of [a:b] isn't a constant, maybe you want +: or -:");
|
||||
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* msbp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* lsbp = nodep->thsp()->unlinkFrBack();
|
||||
vlsint32_t msb = VN_CAST(msbp, Const)->toSInt();
|
||||
vlsint32_t lsb = VN_CAST(lsbp, Const)->toSInt();
|
||||
vlsint32_t elem = (msb>lsb) ? (msb-lsb+1) : (lsb-msb+1);
|
||||
vlsint32_t elem = (msb > lsb) ? (msb - lsb + 1) : (lsb - msb + 1);
|
||||
FromData fromdata = fromDataForArray(nodep, fromp);
|
||||
AstNodeDType* ddtypep = fromdata.m_dtypep;
|
||||
VNumRange fromRange = fromdata.m_fromRange;
|
||||
@@ -347,90 +337,101 @@ private:
|
||||
// Slice extraction
|
||||
if (fromRange.elements() == elem
|
||||
&& fromRange.lo() == lsb) { // Extracting whole of original array
|
||||
nodep->replaceWith(fromp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
nodep->replaceWith(fromp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (fromRange.elements() == 1) { // Extracting single element
|
||||
AstArraySel* newp = new AstArraySel(nodep->fileline(), fromp, lsbp);
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else { // Slice
|
||||
AstSliceSel* newp = new AstSliceSel(nodep->fileline(), fromp,
|
||||
VNumRange(VNumRange::LeftRight(),
|
||||
msb, lsb));
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
VNumRange(VNumRange::LeftRight(), msb, lsb));
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
}
|
||||
else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
} else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
// SELEXTRACT(array, msb, lsb) -> SEL(array,
|
||||
// lsb*width-of-subindex, width-of-subindex*(msb-lsb))
|
||||
UASSERT_OBJ(!(!fromRange.elements()
|
||||
|| (adtypep->width() % fromRange.elements())!=0), adtypep,
|
||||
"Array extraction with width miscomputed "
|
||||
<<adtypep->width()<<"/"<<fromRange.elements());
|
||||
UASSERT_OBJ(!(!fromRange.elements() || (adtypep->width() % fromRange.elements()) != 0),
|
||||
adtypep,
|
||||
"Array extraction with width miscomputed " << adtypep->width() << "/"
|
||||
<< fromRange.elements());
|
||||
if (fromRange.littleEndian()) {
|
||||
// Below code assumes big bit endian; just works out if we swap
|
||||
int x = msb; msb = lsb; lsb = x;
|
||||
int x = msb;
|
||||
msb = lsb;
|
||||
lsb = x;
|
||||
}
|
||||
if (lsb > msb) {
|
||||
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["
|
||||
<<lsb<<":"<<msb<<"]");
|
||||
int x = msb; msb = lsb; lsb = x;
|
||||
nodep->v3error("["
|
||||
<< msb << ":" << lsb
|
||||
<< "] Range extract has backward bit ordering, perhaps you wanted ["
|
||||
<< lsb << ":" << msb << "]");
|
||||
int x = msb;
|
||||
msb = lsb;
|
||||
lsb = x;
|
||||
}
|
||||
int elwidth = adtypep->width() / fromRange.elements();
|
||||
AstSel* newp = new AstSel(nodep->fileline(),
|
||||
fromp,
|
||||
new AstMul(nodep->fileline(), newSubLsbOf(lsbp, fromRange),
|
||||
new AstConst(nodep->fileline(),
|
||||
AstConst::Unsized32(), elwidth)),
|
||||
new AstConst(nodep->fileline(),
|
||||
AstConst::Unsized32(), (msb-lsb+1)*elwidth));
|
||||
AstSel* newp = new AstSel(
|
||||
nodep->fileline(), fromp,
|
||||
new AstMul(nodep->fileline(), newSubLsbOf(lsbp, fromRange),
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), elwidth)),
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), (msb - lsb + 1) * elwidth));
|
||||
newp->declRange(fromRange);
|
||||
newp->declElWidth(elwidth);
|
||||
newp->dtypeFrom(sliceDType(adtypep, msb, lsb));
|
||||
//if (debug()>=9) newp->dumpTree(cout, "--EXTBTn: ");
|
||||
// if (debug() >= 9) newp->dumpTree(cout, "--EXTBTn: ");
|
||||
UASSERT_OBJ(newp->widthMin() == newp->widthConst(), nodep, "Width mismatch");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else if (VN_IS(ddtypep, BasicDType)) {
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(ddtypep, BasicDType)) {
|
||||
if (fromRange.littleEndian()) {
|
||||
// Below code assumes big bit endian; just works out if we swap
|
||||
int x = msb; msb = lsb; lsb = x;
|
||||
int x = msb;
|
||||
msb = lsb;
|
||||
lsb = x;
|
||||
}
|
||||
if (lsb > msb) {
|
||||
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["
|
||||
<<lsb<<":"<<msb<<"]");
|
||||
int x = msb; msb = lsb; lsb = x;
|
||||
nodep->v3error("["
|
||||
<< msb << ":" << lsb
|
||||
<< "] Range extract has backward bit ordering, perhaps you wanted ["
|
||||
<< lsb << ":" << msb << "]");
|
||||
int x = msb;
|
||||
msb = lsb;
|
||||
lsb = x;
|
||||
}
|
||||
AstNode* widthp = new AstConst(msbp->fileline(),
|
||||
AstConst::Unsized32(), // Unsized so width from user
|
||||
msb +1-lsb);
|
||||
AstSel* newp = new AstSel(nodep->fileline(),
|
||||
fromp,
|
||||
newSubLsbOf(lsbp, fromRange),
|
||||
widthp);
|
||||
msb + 1 - lsb);
|
||||
AstSel* newp
|
||||
= new AstSel(nodep->fileline(), fromp, newSubLsbOf(lsbp, fromRange), widthp);
|
||||
newp->declRange(fromRange);
|
||||
UINFO(6," new "<<newp<<endl);
|
||||
//if (debug()>=9) newp->dumpTree(cout, "--SELEXnew: ");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else if (VN_IS(ddtypep, NodeUOrStructDType)) {
|
||||
UINFO(6, " new " << newp << endl);
|
||||
// if (debug() >= 9) newp->dumpTree(cout, "--SELEXnew: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(ddtypep, NodeUOrStructDType)) {
|
||||
// Classes aren't little endian
|
||||
if (lsb > msb) {
|
||||
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["
|
||||
<<lsb<<":"<<msb<<"]");
|
||||
int x = msb; msb = lsb; lsb = x;
|
||||
nodep->v3error("["
|
||||
<< msb << ":" << lsb
|
||||
<< "] Range extract has backward bit ordering, perhaps you wanted ["
|
||||
<< lsb << ":" << msb << "]");
|
||||
int x = msb;
|
||||
msb = lsb;
|
||||
lsb = x;
|
||||
}
|
||||
AstNode* widthp = new AstConst(msbp->fileline(),
|
||||
AstConst::Unsized32(), // Unsized so width from user
|
||||
msb +1-lsb);
|
||||
AstSel* newp = new AstSel(nodep->fileline(),
|
||||
fromp,
|
||||
newSubLsbOf(lsbp, fromRange),
|
||||
widthp);
|
||||
msb + 1 - lsb);
|
||||
AstSel* newp
|
||||
= new AstSel(nodep->fileline(), fromp, newSubLsbOf(lsbp, fromRange), widthp);
|
||||
newp->declRange(fromRange);
|
||||
UINFO(6," new "<<newp<<endl);
|
||||
//if (debug()>=9) newp->dumpTree(cout, "--SELEXnew: ");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else { // NULL=bad extract, or unknown node type
|
||||
UINFO(6, " new " << newp << endl);
|
||||
// if (debug() >= 9) newp->dumpTree(cout, "--SELEXnew: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else { // NULL=bad extract, or unknown node type
|
||||
nodep->v3error("Illegal range select; type already selected, or bad dimension: "
|
||||
<< "data type is " << fromdata.m_errp->prettyDTypeNameQ());
|
||||
UINFO(1, " Related ddtype: " << ddtypep << endl);
|
||||
@@ -447,38 +448,40 @@ private:
|
||||
void replaceSelPlusMinus(AstNodePreSel* nodep) {
|
||||
// Select of a range specified with +: or -:, i.e. "array[2+:3], [2-:3]"
|
||||
// This select style has a lsb and width
|
||||
UINFO(6,"SELPLUS/MINUS "<<nodep<<endl);
|
||||
UINFO(6, "SELPLUS/MINUS " << nodep << endl);
|
||||
// Below 2 lines may change nodep->widthp()
|
||||
if (debug()>=9) nodep->dumpTree(cout, "--SELPM0: ");
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "--SELPM0: ");
|
||||
V3Const::constifyParamsEdit(nodep->thsp()); // May relink pointed to node
|
||||
checkConstantOrReplace(nodep->thsp(), "Width of :+ or :- bit extract isn't a constant");
|
||||
if (debug()>=9) nodep->dumpTree(cout, "--SELPM3: ");
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "--SELPM3: ");
|
||||
// Now replace it with an AstSel
|
||||
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* widthp = nodep->thsp()->unlinkFrBack();
|
||||
int width = VN_CAST(widthp, Const)->toSInt();
|
||||
if (width > (1<<28)) nodep->v3error("Width of :+ or :- is huge; vector of over 1billion bits: "
|
||||
<<widthp->prettyName());
|
||||
if (width<0) nodep->v3error("Width of :+ or :- is < 0: "<<widthp->prettyName());
|
||||
if (width > (1 << 28)) {
|
||||
nodep->v3error("Width of :+ or :- is huge; vector of over 1billion bits: "
|
||||
<< widthp->prettyName());
|
||||
}
|
||||
if (width < 0) nodep->v3error("Width of :+ or :- is < 0: " << widthp->prettyName());
|
||||
FromData fromdata = fromDataForArray(nodep, fromp);
|
||||
AstNodeDType* ddtypep = fromdata.m_dtypep;
|
||||
VNumRange fromRange = fromdata.m_fromRange;
|
||||
if (VN_IS(ddtypep, BasicDType)
|
||||
|| VN_IS(ddtypep, PackArrayDType)
|
||||
if (VN_IS(ddtypep, BasicDType) || VN_IS(ddtypep, PackArrayDType)
|
||||
|| (VN_IS(ddtypep, NodeUOrStructDType)
|
||||
&& VN_CAST(ddtypep, NodeUOrStructDType)->packedUnsup())) {
|
||||
int elwidth = 1;
|
||||
AstNode* newwidthp = widthp;
|
||||
if (const AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
elwidth = adtypep->width() / fromRange.elements();
|
||||
newwidthp = new AstConst(nodep->fileline(), AstConst::Unsized32(), width * elwidth);
|
||||
newwidthp
|
||||
= new AstConst(nodep->fileline(), AstConst::Unsized32(), width * elwidth);
|
||||
}
|
||||
AstNode* newlsbp = NULL;
|
||||
if (VN_IS(nodep, SelPlus)) {
|
||||
if (fromRange.littleEndian()) {
|
||||
// SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width)
|
||||
newlsbp = newSubNeg((fromRange.hi()-width+1), rhsp);
|
||||
newlsbp = newSubNeg((fromRange.hi() - width + 1), rhsp);
|
||||
} else {
|
||||
// SELPLUS(from,lsb,width) -> SEL(from, lsb-vector_lsb, width)
|
||||
newlsbp = newSubNeg(rhsp, fromRange.lo());
|
||||
@@ -489,22 +492,23 @@ private:
|
||||
newlsbp = newSubNeg(fromRange.hi(), rhsp);
|
||||
} else {
|
||||
// SELMINUS(from,msb,width) -> SEL(from, msb-(width-1)-lsb#)
|
||||
newlsbp = newSubNeg(rhsp, fromRange.lo()+(width-1));
|
||||
newlsbp = newSubNeg(rhsp, fromRange.lo() + (width - 1));
|
||||
}
|
||||
} else {
|
||||
nodep->v3fatalSrc("Bad Case");
|
||||
}
|
||||
if (elwidth != 1) newlsbp = new AstMul(nodep->fileline(), newlsbp,
|
||||
new AstConst(nodep->fileline(), elwidth));
|
||||
AstSel* newp = new AstSel(nodep->fileline(),
|
||||
fromp, newlsbp, newwidthp);
|
||||
if (elwidth != 1) {
|
||||
newlsbp = new AstMul(nodep->fileline(), newlsbp,
|
||||
new AstConst(nodep->fileline(), elwidth));
|
||||
}
|
||||
AstSel* newp = new AstSel(nodep->fileline(), fromp, newlsbp, newwidthp);
|
||||
newp->declRange(fromRange);
|
||||
newp->declElWidth(elwidth);
|
||||
UINFO(6," new "<<newp<<endl);
|
||||
if (debug()>=9) newp->dumpTree(cout, "--SELNEW: ");
|
||||
nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
else { // NULL=bad extract, or unknown node type
|
||||
UINFO(6, " new " << newp << endl);
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELNEW: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else { // NULL=bad extract, or unknown node type
|
||||
nodep->v3error("Illegal +: or -: select; type already selected, or bad dimension: "
|
||||
<< "data type is " << fromdata.m_errp->prettyDTypeNameQ());
|
||||
// How to recover? We'll strip a dimension.
|
||||
@@ -516,12 +520,8 @@ private:
|
||||
if (!rhsp->backp()) { VL_DO_DANGLING(pushDeletep(rhsp), rhsp); }
|
||||
if (!widthp->backp()) { VL_DO_DANGLING(pushDeletep(widthp), widthp); }
|
||||
}
|
||||
virtual void visit(AstSelPlus* nodep) VL_OVERRIDE {
|
||||
replaceSelPlusMinus(nodep);
|
||||
}
|
||||
virtual void visit(AstSelMinus* nodep) VL_OVERRIDE {
|
||||
replaceSelPlusMinus(nodep);
|
||||
}
|
||||
virtual void visit(AstSelPlus* nodep) VL_OVERRIDE { replaceSelPlusMinus(nodep); }
|
||||
virtual void visit(AstSelMinus* nodep) VL_OVERRIDE { replaceSelPlusMinus(nodep); }
|
||||
// If adding new visitors, ensure V3Width's visit(TYPE) calls into here
|
||||
|
||||
//--------------------
|
||||
@@ -534,9 +534,7 @@ private:
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
WidthSelVisitor() {}
|
||||
AstNode* mainAcceptEdit(AstNode* nodep) {
|
||||
return iterateSubtreeReturnEdits(nodep);
|
||||
}
|
||||
AstNode* mainAcceptEdit(AstNode* nodep) { return iterateSubtreeReturnEdits(nodep); }
|
||||
virtual ~WidthSelVisitor() {}
|
||||
};
|
||||
|
||||
@@ -544,7 +542,7 @@ public:
|
||||
// Width class functions
|
||||
|
||||
AstNode* V3Width::widthSelNoIterEdit(AstNode* nodep) {
|
||||
UINFO(4,__FUNCTION__<<": "<<nodep<<endl);
|
||||
UINFO(4, __FUNCTION__ << ": " << nodep << endl);
|
||||
WidthSelVisitor visitor;
|
||||
nodep = visitor.mainAcceptEdit(nodep);
|
||||
return nodep;
|
||||
|
||||
Reference in New Issue
Block a user