summaryrefslogtreecommitdiff
path: root/frontends/ast
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/ast')
-rw-r--r--frontends/ast/ast.cc1
-rw-r--r--frontends/ast/ast.h1
-rw-r--r--frontends/ast/genrtlil.cc8
-rw-r--r--frontends/ast/simplify.cc12
4 files changed, 22 insertions, 0 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 40f7826f..96608ae3 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -82,6 +82,7 @@ std::string AST::type2str(AstNodeType type)
X(AST_PREFIX)
X(AST_ASSERT)
X(AST_FCALL)
+ X(AST_TO_BITS)
X(AST_TO_SIGNED)
X(AST_TO_UNSIGNED)
X(AST_CONCAT)
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index caae679a..01702c3c 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -61,6 +61,7 @@ namespace AST
AST_ASSERT,
AST_FCALL,
+ AST_TO_BITS,
AST_TO_SIGNED,
AST_TO_UNSIGNED,
AST_CONCAT,
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 6001e278..99d8566d 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -664,6 +664,14 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint)
sign_hint = false;
break;
+ case AST_TO_BITS:
+ while (children[0]->simplify(true, false, false, 1, -1, false) == true) { }
+ if (children[0]->type != AST_CONSTANT)
+ log_error("Left operand of tobits expression is not constant at %s:%d!\n", filename.c_str(), linenum);
+ children[1]->detectSignWidthWorker(sub_width_hint, sign_hint);
+ width_hint = std::max(width_hint, children[0]->bitsAsConst().as_int());
+ break;
+
case AST_TO_SIGNED:
children.at(0)->detectSignWidthWorker(width_hint, sub_sign_hint);
break;
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 5a2d1ae6..f19befe2 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -258,6 +258,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
break;
+ case AST_TO_BITS:
case AST_TO_SIGNED:
case AST_TO_UNSIGNED:
case AST_CONCAT:
@@ -442,6 +443,17 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
goto apply_newNode;
}
+ // evaluate TO_BITS nodes
+ if (type == AST_TO_BITS) {
+ if (children[0]->type != AST_CONSTANT)
+ log_error("Left operand of to_bits expression is not constant at %s:%d!\n", filename.c_str(), linenum);
+ if (children[1]->type != AST_CONSTANT)
+ log_error("Right operand of to_bits expression is not constant at %s:%d!\n", filename.c_str(), linenum);
+ RTLIL::Const new_value = children[1]->bitsAsConst(children[0]->bitsAsConst().as_int(), children[1]->is_signed);
+ newNode = mkconst_bits(new_value.bits, children[1]->is_signed);
+ goto apply_newNode;
+ }
+
// annotate constant ranges
if (type == AST_RANGE) {
bool old_range_valid = range_valid;