AstArraySel* insertImplicit(AstNode* nodep, unsigned start, unsigned count) { // Insert any implicit slices as explicit slices (ArraySel nodes). // Return a new pointer to replace nodep() in the ArraySel. UINFO(9," insertImplicit (start="<<start<<",c="<<count<<") "<<nodep<<endl); AstVarRef* refp = nodep->user1p()->castNode()->castVarRef(); if (!refp) nodep->v3fatalSrc("No VarRef in user1 of node "<<nodep); AstVar* varp = refp->varp(); AstNode* topp = nodep; for (unsigned i = start; i < start + count; ++i) { AstNodeDType* dtypep = varp->dtypep()->dtypeDimensionp(i-1); AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType(); if (!adtypep) nodep->v3fatalSrc("insertImplicit tried to expand an array without an ArrayDType"); vlsint32_t msb = adtypep->msb(); vlsint32_t lsb = adtypep->lsb(); if (lsb > msb) { // Below code assumes big bit endian; just works out if we swap int x = msb; msb = lsb; lsb = x; } UINFO(9," ArraySel-child: "<<topp<<endl); AstArraySel* newp = new AstArraySel(nodep->fileline(), topp, // "lsb-lsb": Arrays are zero-based so index 0 is always lsb new AstConst(nodep->fileline(), lsb-lsb)); if (!newp->dtypep()) { newp->v3fatalSrc("ArraySel dtyping failed when resolving slice"); // see ArraySel constructor } newp->user1p(refp); newp->start(lsb); newp->length(msb - lsb + 1); topp = newp; } return topp->castArraySel(); }
int countClones(AstArraySel* nodep) { // Count how many clones we need to make from this ArraySel int clones = 1; AstNode* fromp = nodep; AstArraySel* selp; do { selp = fromp->castArraySel(); fromp = (selp) ? selp->fromp() : NULL; if (fromp && selp) clones *= selp->length(); } while (fromp && selp); return clones; }
unsigned explicitDimensions(AstArraySel* nodep) { // Find out how many explicit dimensions are in a given ArraySel. unsigned dim = 0; AstNode* fromp = nodep; AstArraySel* selp; do { selp = fromp->castArraySel(); if (!selp) { nodep->user1p(fromp->castVarRef()); selp = NULL; break; } else { fromp = selp->fromp(); if (fromp) ++dim; } } while (fromp && selp); if (!nodep->user1p()) nodep->v3fatalSrc("Couldn't find VarRef under the ArraySel"); return dim; }