Skip to content

Commit

Permalink
Update as Wilson advised.
Browse files Browse the repository at this point in the history
  • Loading branch information
yTakatsukasa committed Dec 15, 2019
1 parent bc7e182 commit 987d74a
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 54 deletions.
22 changes: 12 additions & 10 deletions include/verilated.cpp
Expand Up @@ -1826,25 +1826,27 @@ std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE {
return std::string(destout, len);
}

std::string VL_PUTC_NSS(const std::string& lhs, int rhs, vluint8_t ths) VL_PURE {
std::string VL_PUTC_N(const std::string& lhs, IData rhs, CData ths) VL_PURE {
std::string lstring = lhs;
const vlsint32_t rhs_s = rhs; // to signed value
// 6.16.2:str.putc(i, c) does not change the value when i < 0 || i >= str.len() || c == 0
// when evaluating the second condition, i must be positive.
if (0 <= rhs && static_cast<vluint32_t>(rhs) < lhs.length() && ths != 0) lstring[rhs] = ths;
if (0 <= rhs_s && rhs < lhs.length() && ths != 0) lstring[rhs] = ths;
return lstring;
}

vluint8_t VL_GETC_NS(const std::string& lhs, int rhs) VL_PURE {
vluint8_t v = 0;
CData VL_GETC_N(const std::string& lhs, IData rhs) VL_PURE {
CData v = 0;
const vlsint32_t rhs_s = rhs; // to signed value
// 6.16.3:str.getc(i) returns 0 if i < 0 || i >= str.len()
// when evaluating the second condition, i must be positive.
if (0 <= rhs && static_cast<vluint32_t>(rhs) < lhs.length()) v = lhs[rhs];
if (0 <= rhs_s && rhs < lhs.length()) v = lhs[rhs];
return v;
}
std::string VL_SUBSTR_NSS(const std::string& lhs, int rhs, int ths) VL_PURE {

std::string VL_SUBSTR_N(const std::string& lhs, IData rhs, IData ths) VL_PURE {
const vlsint32_t rhs_s = rhs; // to signed value
const vlsint32_t ths_s = ths; // to signed value
// 6.16.8:str.substr(i, j) returns an empty string when i < 0 || j < i || j >= str.len()
// when evaluating the third condition, ths must be positive because 0 <= rhs <= ths is guaranteed by the former two conditions.
if (rhs < 0 || ths < rhs || static_cast<vluint32_t>(ths) >= lhs.length()) return "";
if (rhs_s < 0 || ths_s < rhs_s || ths >= lhs.length()) return "";

// The second parameter of std::string::substr(i, n) is length, not position as SystemVerilog.
return lhs.substr(rhs, ths - rhs + 1);
Expand Down
6 changes: 3 additions & 3 deletions include/verilated_heavy.h
Expand Up @@ -353,9 +353,9 @@ extern IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr)
//======================================================================
// Strings

extern std::string VL_PUTC_NSS(const std::string& lhs, int rhs, vluint8_t ths) VL_PURE;
extern vluint8_t VL_GETC_NS(const std::string& lhs, int rhs) VL_PURE;
extern std::string VL_SUBSTR_NSS(const std::string& lhs, int rhs, int ths) VL_PURE;
extern std::string VL_PUTC_N(const std::string& lhs, IData rhs, CData ths) VL_PURE;
extern CData VL_GETC_N(const std::string& lhs, IData rhs) VL_PURE;
extern std::string VL_SUBSTR_N(const std::string& lhs, IData rhs, IData ths) VL_PURE;

inline IData VL_CMP_NN(const std::string& lhs, const std::string& rhs, bool ignoreCase) VL_PURE {
// SystemVerilog Language Standard does not allow a string variable to contain '\0'.
Expand Down
44 changes: 22 additions & 22 deletions src/V3AstNodes.h
Expand Up @@ -5991,72 +5991,72 @@ class AstHypotD : public AstNodeSystemBiop {
virtual string emitC() { return "hypot(%li,%ri)"; }
};

class AstPutcNSS : public AstNodeTriop {
class AstPutcN : public AstNodeTriop {
// Verilog str.substr()
public:
AstPutcNSS(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* ths) : AstNodeTriop(fl, lhsp, rhsp, ths) {
AstPutcN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* ths) : AstNodeTriop(fl, lhsp, rhsp, ths) {
// This Node returns a new value, so need to be assigned by AstAssign.
dtypeSetString();
}
ASTNODE_NODE_FUNCS(PutcNSS)
ASTNODE_NODE_FUNCS(PutcN)
virtual void numberOperate(V3Number& out, const V3Number& lhs,
const V3Number& rhs, const V3Number& ths) {
out.opPutcNSS(lhs, rhs, ths);
out.opPutcN(lhs, rhs, ths);
}
virtual string name() const { return "putc"; }
virtual string emitVerilog() { return "%k(%l.putc(%r,%t))"; }
virtual string emitC() { return "VL_PUTC_NSS(%li,%ri,%ti)"; }
virtual string emitC() { return "VL_PUTC_N(%li,%ri,%ti)"; }
virtual string emitSimpleOperator() { return ""; }
virtual bool cleanOut() const { return false; }
virtual bool cleanLhs() const { return false; }
virtual bool cleanOut() const { return true; }
virtual bool cleanLhs() const { return true; }
virtual bool cleanRhs() const { return true; }
virtual bool cleanThs() const { return true; }
virtual bool sizeMattersLhs() const { return false; }
virtual bool sizeMattersRhs() const { return false; }
virtual bool sizeMattersThs() const { return false; }
};

class AstGetcNS : public AstNodeBiop {
class AstGetcN : public AstNodeBiop {
// Verilog str.substr()
public:
AstGetcNS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
AstGetcN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetBitSized(8, AstNumeric::UNSIGNED);
}
ASTNODE_NODE_FUNCS(GetcNS)
ASTNODE_NODE_FUNCS(GetcN)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) {
return new AstGetcNS(this->fileline(), lhsp, rhsp);
return new AstGetcN(this->fileline(), lhsp, rhsp);
}
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
out.opGetcNS(lhs, rhs);
out.opGetcN(lhs, rhs);
}
virtual string name() const { return "getc"; }
virtual string emitVerilog() { return "%k(%l.getc(%r))"; }
virtual string emitC() { return "VL_GETC_NS(%li,%ri)"; }
virtual string emitC() { return "VL_GETC_N(%li,%ri)"; }
virtual string emitSimpleOperator() { return ""; }
virtual bool cleanOut() const { return false; }
virtual bool cleanLhs() const { return false; }
virtual bool cleanOut() const { return true; }
virtual bool cleanLhs() const { return true; }
virtual bool cleanRhs() const { return true; }
virtual bool sizeMattersLhs() const { return false; }
virtual bool sizeMattersRhs() const { return false; }
};

class AstSubstrNSS : public AstNodeTriop {
class AstSubstrN : public AstNodeTriop {
// Verilog str.substr()
public:
AstSubstrNSS(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* ths) : AstNodeTriop(fl, lhsp, rhsp, ths) {
AstSubstrN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* ths) : AstNodeTriop(fl, lhsp, rhsp, ths) {
dtypeSetString();
}
ASTNODE_NODE_FUNCS(SubstrNSS)
ASTNODE_NODE_FUNCS(SubstrN)
virtual void numberOperate(V3Number& out, const V3Number& lhs,
const V3Number& rhs, const V3Number& ths) {
out.opSubstrNSS(lhs, rhs, ths);
out.opSubstrN(lhs, rhs, ths);
}
virtual string name() const { return "substr"; }
virtual string emitVerilog() { return "%k(%l.substr(%r,%t))"; }
virtual string emitC() { return "VL_SUBSTR_NSS(%li,%ri,%ti)"; }
virtual string emitC() { return "VL_SUBSTR_N(%li,%ri,%ti)"; }
virtual string emitSimpleOperator() { return ""; }
virtual bool cleanOut() const { return false; }
virtual bool cleanLhs() const { return false; }
virtual bool cleanOut() const { return true; }
virtual bool cleanLhs() const { return true; }
virtual bool cleanRhs() const { return true; }
virtual bool cleanThs() const { return true; }
virtual bool sizeMattersLhs() const { return false; }
Expand Down
4 changes: 2 additions & 2 deletions src/V3Const.cpp
Expand Up @@ -2526,8 +2526,8 @@ class ConstVisitor : public AstNVisitor {
TREEOPV("AstLogIf{$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
TREEOPV("AstLogEq{$lhsp, $rhsp}", "replaceLogEq(nodep)");
// Strings
TREEOPC("AstPutcNSS{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)");
TREEOPC("AstSubstrNSS{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)");
TREEOPC("AstPutcN{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)");
TREEOPC("AstSubstrN{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)");
TREEOPC("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, VN_CAST(nodep->lhsp(), Const)->num().toString())");


Expand Down
2 changes: 1 addition & 1 deletion src/V3EmitC.cpp
Expand Up @@ -644,7 +644,7 @@ class EmitCStmts : public EmitCBaseVisitor {
}
}
virtual void visit(AstNodeTriop* nodep) {
UASSERT(!emitSimpleOk(nodep), "Triop can not be described in a simple way");
UASSERT_OBJ(!emitSimpleOk(nodep), nodep, "Triop cannot be described in a simple way");
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), nodep->thsp());
}
virtual void visit(AstRedXor* nodep) {
Expand Down
6 changes: 3 additions & 3 deletions src/V3EmitCInlines.cpp
Expand Up @@ -62,15 +62,15 @@ class EmitCInlines : EmitCBaseVisitor {
v3Global.needHeavy(true);
iterateChildren(nodep);
}
virtual void visit(AstPutcNSS* nodep) {
virtual void visit(AstPutcN* nodep) {
v3Global.needHeavy(true);
iterateChildren(nodep);
}
virtual void visit(AstGetcNS* nodep) {
virtual void visit(AstGetcN* nodep) {
v3Global.needHeavy(true);
iterateChildren(nodep);
}
virtual void visit(AstSubstrNSS* nodep) {
virtual void visit(AstSubstrN* nodep) {
v3Global.needHeavy(true);
iterateChildren(nodep);
}
Expand Down
6 changes: 3 additions & 3 deletions src/V3Number.cpp
Expand Up @@ -1262,7 +1262,7 @@ V3Number& V3Number::opAtoN(const V3Number& lhs, int base) {
return setLongS(static_cast<vlsint32_t>(v));
}

V3Number& V3Number::opPutcNSS(const V3Number& lhs, const V3Number& rhs, const V3Number& ths) {
V3Number& V3Number::opPutcN(const V3Number& lhs, const V3Number& rhs, const V3Number& ths) {
NUM_ASSERT_OP_ARGS3(lhs, rhs, ths);
NUM_ASSERT_STRING_ARGS1(lhs);

Expand All @@ -1276,7 +1276,7 @@ V3Number& V3Number::opPutcNSS(const V3Number& lhs, const V3Number& rhs, const V3
return setString(lstring);
}

V3Number& V3Number::opGetcNS(const V3Number& lhs, const V3Number& rhs) {
V3Number& V3Number::opGetcN(const V3Number& lhs, const V3Number& rhs) {
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_STRING_ARGS1(lhs);

Expand All @@ -1290,7 +1290,7 @@ V3Number& V3Number::opGetcNS(const V3Number& lhs, const V3Number& rhs) {
return setLong(v);
}

V3Number& V3Number::opSubstrNSS(const V3Number& lhs, const V3Number& rhs, const V3Number& ths) {
V3Number& V3Number::opSubstrN(const V3Number& lhs, const V3Number& rhs, const V3Number& ths) {
NUM_ASSERT_OP_ARGS3(lhs, rhs, ths);
NUM_ASSERT_STRING_ARGS1(lhs);

Expand Down
6 changes: 3 additions & 3 deletions src/V3Number.h
Expand Up @@ -361,9 +361,9 @@ class V3Number {

// "N" - string operations
V3Number& opAtoN (const V3Number& lhs, int base);
V3Number& opPutcNSS (const V3Number& lhs, const V3Number& rhs, const V3Number& ths);
V3Number& opGetcNS (const V3Number& lhs, const V3Number& rhs);
V3Number& opSubstrNSS(const V3Number& lhs, const V3Number& rhs, const V3Number& ths);
V3Number& opPutcN (const V3Number& lhs, const V3Number& rhs, const V3Number& ths);
V3Number& opGetcN (const V3Number& lhs, const V3Number& rhs);
V3Number& opSubstrN (const V3Number& lhs, const V3Number& rhs, const V3Number& ths);
V3Number& opCompareNN(const V3Number& lhs,const V3Number& rhs, bool ignoreCase);
V3Number& opConcatN (const V3Number& lhs, const V3Number& rhs);
V3Number& opReplN (const V3Number& lhs, const V3Number& rhs);
Expand Down
14 changes: 7 additions & 7 deletions src/V3Width.cpp
Expand Up @@ -333,18 +333,18 @@ class WidthVisitor : public AstNVisitor {

// Output integer, input string
virtual void visit(AstLenN* nodep) { visit_Os32_string(nodep); }
virtual void visit(AstPutcNSS* nodep) {
virtual void visit(AstPutcN* nodep) {
// CALLER: str.putc()
UASSERT_OBJ(nodep->rhsp() && nodep->thsp(), nodep, "For ternary ops only!");
if (m_vup && m_vup->prelim()) {
// See similar handling in visit_cmp_eq_gt where created
iterateCheckString(nodep, "LHS", nodep->lhsp(), BOTH);
iterateCheckSigned32(nodep, "RHS", nodep->rhsp(), BOTH);
iterateCheckSigned32(nodep, "THS", nodep->thsp(), BOTH);
nodep->dtypeSetString(); //AstPutcNSS returns the new string to be assigned by AstAssign
nodep->dtypeSetString(); //AstPutcN returns the new string to be assigned by AstAssign
}
}
virtual void visit(AstGetcNS* nodep) {
virtual void visit(AstGetcN* nodep) {
// CALLER: str.getc()
UASSERT_OBJ(nodep->rhsp(), nodep, "For binary ops only!");
if (m_vup && m_vup->prelim()) {
Expand All @@ -354,7 +354,7 @@ class WidthVisitor : public AstNVisitor {
nodep->dtypeSetBitSized(8, AstNumeric::UNSIGNED);
}
}
virtual void visit(AstSubstrNSS* nodep) {
virtual void visit(AstSubstrN* nodep) {
// CALLER: str.substr()
UASSERT_OBJ(nodep->rhsp() && nodep->thsp(), nodep, "For ternary ops only!");
if (m_vup && m_vup->prelim()) {
Expand Down Expand Up @@ -2156,7 +2156,7 @@ class WidthVisitor : public AstNVisitor {
UASSERT_OBJ(ths, nodep, "ths");
AstVarRef* var_ref = new AstVarRef(nodep->fileline(), fromp->varp(), false);
AstNode* newp = new AstAssign(nodep->fileline(), fromp,
new AstPutcNSS(nodep->fileline(), var_ref, rhs, ths));
new AstPutcN(nodep->fileline(), var_ref, rhs, ths));
fromp->lvalue(true);
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
} else if (nodep->name() == "getc" ) {
Expand All @@ -2166,7 +2166,7 @@ class WidthVisitor : public AstNVisitor {
AstNode* rhs = argp0->exprp()->unlinkFrBack();
UASSERT_OBJ(lhs, nodep, "lhs");
UASSERT_OBJ(rhs, nodep, "rhs");
AstNode* newp = new AstGetcNS(nodep->fileline(), lhs, rhs);
AstNode* newp = new AstGetcN(nodep->fileline(), lhs, rhs);
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
} else if (nodep->name() == "substr") {
methodOkArguments(nodep, 2, 2);
Expand All @@ -2175,7 +2175,7 @@ class WidthVisitor : public AstNVisitor {
AstNode* lhs = nodep->fromp()->unlinkFrBack();
AstNode* rhs = argp0->exprp()->unlinkFrBack();
AstNode* ths = argp1->exprp()->unlinkFrBack();
AstNode* newp = new AstSubstrNSS(nodep->fileline(), lhs, rhs, ths);
AstNode* newp = new AstSubstrN(nodep->fileline(), lhs, rhs, ths);
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
} else if (nodep->name() == "atobin"
|| nodep->name() == "atohex"
Expand Down

0 comments on commit 987d74a

Please sign in to comment.