X(AST_ASSIGN_LE)
X(AST_CASE)
X(AST_COND)
+ X(AST_CONDX)
+ X(AST_CONDZ)
X(AST_DEFAULT)
X(AST_FOR)
X(AST_WHILE)
break;
case AST_CASE:
- fprintf(f, "%s" "case (", indent.c_str());
+ if (!children.empty() && children[0]->type == AST_CONDX)
+ fprintf(f, "%s" "casex (", indent.c_str());
+ else if (!children.empty() && children[0]->type == AST_CONDZ)
+ fprintf(f, "%s" "casez (", indent.c_str());
+ else
+ fprintf(f, "%s" "case (", indent.c_str());
children[0]->dumpVlog(f, "");
fprintf(f, ")\n");
for (size_t i = 1; i < children.size(); i++) {
break;
case AST_COND:
+ case AST_CONDX:
+ case AST_CONDZ:
for (auto child : children) {
if (child->type == AST_BLOCK) {
fprintf(f, ":\n");
AST_ASSIGN_LE,
AST_CASE,
AST_COND,
+ AST_CONDX,
+ AST_CONDZ,
AST_DEFAULT,
AST_FOR,
AST_WHILE,
case AST_CASE:
for (auto child : ast->children)
if (child != ast->children[0]) {
- log_assert(child->type == AST_COND);
+ log_assert(child->type == AST_COND || child->type == AST_CONDX || child->type == AST_CONDZ);
collect_lvalues(reg, child, type_eq, type_le, false);
}
break;
case AST_COND:
+ case AST_CONDX:
+ case AST_CONDZ:
case AST_ALWAYS:
case AST_INITIAL:
for (auto child : ast->children)
{
if (child == ast->children[0])
continue;
- log_assert(child->type == AST_COND);
+ log_assert(child->type == AST_COND || child->type == AST_CONDX || child->type == AST_CONDZ);
subst_lvalue_map.save();
subst_rvalue_map.save();
}
}
+ if (type == AST_CONDX && children.size() > 0 && children.at(0)->type == AST_CONSTANT) {
+ for (auto &bit : children.at(0)->bits)
+ if (bit == State::Sz || bit == State::Sx)
+ bit = State::Sa;
+ }
+
+ if (type == AST_CONDZ && children.size() > 0 && children.at(0)->type == AST_CONSTANT) {
+ for (auto &bit : children.at(0)->bits)
+ if (bit == State::Sz)
+ bit = State::Sa;
+ }
+
if (const_fold && type == AST_CASE)
{
while (children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
new_children.push_back(children[0]);
for (int i = 1; i < GetSize(children); i++) {
AstNode *child = children[i];
- log_assert(child->type == AST_COND);
+ log_assert(child->type == AST_COND || child->type == AST_CONDX || child->type == AST_CONDZ);
for (auto v : child->children) {
if (v->type == AST_DEFAULT)
goto keep_const_cond;
AstNode *selected_case = NULL;
for (size_t i = 1; i < children.size(); i++)
{
- log_assert(children.at(i)->type == AST_COND);
+ log_assert(children.at(i)->type == AST_COND || children.at(i)->type == AST_CONDX || children.at(i)->type == AST_CONDZ);
AstNode *this_genblock = NULL;
for (auto child : children.at(i)->children) {
for (size_t i = 1; i < stmt->children.size(); i++)
{
bool found_match = false;
- log_assert(stmt->children.at(i)->type == AST_COND);
+ log_assert(stmt->children.at(i)->type == AST_COND || stmt->children.at(i)->type == AST_CONDX || stmt->children.at(i)->type == AST_CONDZ);
if (stmt->children.at(i)->children.front()->type == AST_DEFAULT) {
sel_case = stmt->children.at(i)->children.back();
case_item:
{
- AstNode *node = new AstNode(AST_COND);
+ AstNode *node = new AstNode(
+ case_type_stack.size() && case_type_stack.back() == 'x' ? AST_CONDX :
+ case_type_stack.size() && case_type_stack.back() == 'z' ? AST_CONDZ : AST_COND);
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
} case_select {
gen_case_item:
{
- AstNode *node = new AstNode(AST_COND);
+ AstNode *node = new AstNode(
+ case_type_stack.size() && case_type_stack.back() == 'x' ? AST_CONDX :
+ case_type_stack.size() && case_type_stack.back() == 'z' ? AST_CONDZ : AST_COND);
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
} case_select {