diff options
Diffstat (limited to 'frontends')
| -rw-r--r-- | frontends/ast/ast.cc | 2 | ||||
| -rw-r--r-- | frontends/ast/ast.h | 1 | ||||
| -rw-r--r-- | frontends/ast/genrtlil.cc | 8 | ||||
| -rw-r--r-- | frontends/ast/simplify.cc | 14 | ||||
| -rw-r--r-- | frontends/verilog/verilog_parser.y | 4 | 
5 files changed, 22 insertions, 7 deletions
| diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 8daae7dcb..689fa9fb4 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -94,6 +94,7 @@ std::string AST::type2str(AstNodeType type)  	X(AST_TO_BITS)  	X(AST_TO_SIGNED)  	X(AST_TO_UNSIGNED) +	X(AST_SELFSZ)  	X(AST_CONCAT)  	X(AST_REPLICATE)  	X(AST_BIT_NOT) @@ -617,6 +618,7 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const  	if (0) { case AST_POS:         txt = "+";  }  	if (0) { case AST_NEG:         txt = "-";  }  	if (0) { case AST_LOGIC_NOT:   txt = "!";  } +	if (0) { case AST_SELFSZ:      txt = "@selfsz@";  }  		fprintf(f, "%s(", txt.c_str());  		children[0]->dumpVlog(f, "");  		fprintf(f, ")"); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 0baea7b63..8932108e3 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -75,6 +75,7 @@ namespace AST  		AST_TO_BITS,  		AST_TO_SIGNED,  		AST_TO_UNSIGNED, +		AST_SELFSZ,  		AST_CONCAT,  		AST_REPLICATE,  		AST_BIT_NOT, diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 6a39bbc04..37cbb8a83 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -809,6 +809,11 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun  		sign_hint = false;  		break; +	case AST_SELFSZ: +		sub_width_hint = 0; +		children.at(0)->detectSignWidthWorker(sub_width_hint, sign_hint); +		break; +  	case AST_CONCAT:  		for (auto child : children) {  			sub_width_hint = 0; @@ -1267,7 +1272,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)  	// just pass thru the signal. the parent will evaluate the is_signed property and interpret the SigSpec accordingly  	case AST_TO_SIGNED: -	case AST_TO_UNSIGNED: { +	case AST_TO_UNSIGNED: +	case AST_SELFSZ: {  			RTLIL::SigSpec sig = children[0]->genRTLIL();  			if (sig.size() < width_hint)  				sig.extend_u0(width_hint, sign_hint); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index af347b8f1..af5e14217 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -608,6 +608,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  	case AST_TO_BITS:  	case AST_TO_SIGNED:  	case AST_TO_UNSIGNED: +	case AST_SELFSZ:  	case AST_CONCAT:  	case AST_REPLICATE:  	case AST_REDUCE_AND: @@ -1855,8 +1856,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			AstNode *shamt = shift_expr; +			int shamt_width_hint = 0; +			bool shamt_sign_hint = true; +			shamt->detectSignWidth(shamt_width_hint, shamt_sign_hint); +  			int start_bit = children[0]->id2ast->range_right; -			bool use_shift = shamt->is_signed; +			bool use_shift = shamt_sign_hint;  			if (start_bit != 0) {  				shamt = new AstNode(AST_SUB, shamt, mkconst_int(start_bit, true)); @@ -3060,6 +3065,7 @@ replace_fcall_later:;  				}  			}  			break; +		if (0) { case AST_SELFSZ: const_func = RTLIL::const_pos; }  		if (0) { case AST_POS: const_func = RTLIL::const_pos; }  		if (0) { case AST_NEG: const_func = RTLIL::const_neg; }  			if (children[0]->type == AST_CONSTANT) { @@ -3068,10 +3074,10 @@ replace_fcall_later:;  			} else  			if (children[0]->isConst()) {  				newNode = new AstNode(AST_REALVALUE); -				if (type == AST_POS) -					newNode->realvalue = +children[0]->asReal(sign_hint); -				else +				if (type == AST_NEG)  					newNode->realvalue = -children[0]->asReal(sign_hint); +				else +					newNode->realvalue = +children[0]->asReal(sign_hint);  			}  			break;  		case AST_TERNARY: diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 4a5aba79e..903c8e77f 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -645,13 +645,13 @@ non_opt_range:  	} |  	'[' expr TOK_POS_INDEXED expr ']' {  		$$ = new AstNode(AST_RANGE); -		AstNode *expr = new AstNode(AST_CONCAT, $2); +		AstNode *expr = new AstNode(AST_SELFSZ, $2);  		$$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), $4), AstNode::mkconst_int(1, true)));  		$$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));  	} |  	'[' expr TOK_NEG_INDEXED expr ']' {  		$$ = new AstNode(AST_RANGE); -		AstNode *expr = new AstNode(AST_CONCAT, $2); +		AstNode *expr = new AstNode(AST_SELFSZ, $2);  		$$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));  		$$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), AstNode::mkconst_int(1, true)), $4));  	} | | 
