mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	Improved parsing of large integer constants
This commit is contained in:
		
							parent
							
								
									48dc6ab98d
								
							
						
					
					
						commit
						7f57bc8385
					
				
					 1 changed files with 28 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -52,6 +52,8 @@ static int my_decimal_div_by_two(std::vector<uint8_t> &digits)
 | 
			
		|||
		carry = digits[i] % 2;
 | 
			
		||||
		digits[i] /= 2;
 | 
			
		||||
	}
 | 
			
		||||
	while (!digits.empty() && !digits.front())
 | 
			
		||||
		digits.erase(digits.begin());
 | 
			
		||||
	return carry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -90,10 +92,15 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le
 | 
			
		|||
 | 
			
		||||
	if (base == 10) {
 | 
			
		||||
		data.clear();
 | 
			
		||||
		if (len_in_bits < 0)
 | 
			
		||||
			len_in_bits = ceil(digits.size()/log10(2));
 | 
			
		||||
		for (int i = 0; i < len_in_bits; i++)
 | 
			
		||||
			data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0);
 | 
			
		||||
		if (len_in_bits < 0) {
 | 
			
		||||
			while (!digits.empty())
 | 
			
		||||
				data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0);
 | 
			
		||||
			while (data.size() < 32)
 | 
			
		||||
				data.push_back(RTLIL::S0);
 | 
			
		||||
		} else {
 | 
			
		||||
			for (int i = 0; i < len_in_bits; i++)
 | 
			
		||||
				data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0);
 | 
			
		||||
		}
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -151,20 +158,24 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type)
 | 
			
		|||
	str = code.c_str();
 | 
			
		||||
 | 
			
		||||
	char *endptr;
 | 
			
		||||
	long intval = strtol(str, &endptr, 10);
 | 
			
		||||
	long len_in_bits = strtol(str, &endptr, 10);
 | 
			
		||||
 | 
			
		||||
	// Simple base-10 integer
 | 
			
		||||
	if (*endptr == 0) {
 | 
			
		||||
		std::vector<RTLIL::State> data;
 | 
			
		||||
		my_strtobin(data, str, -1, 10, case_type);
 | 
			
		||||
		if (data.back() == RTLIL::S1)
 | 
			
		||||
			data.push_back(RTLIL::S0);
 | 
			
		||||
		return AstNode::mkconst_bits(data, true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Simple 32 bit integer
 | 
			
		||||
	if (*endptr == 0)
 | 
			
		||||
		return AstNode::mkconst_int(intval, true);
 | 
			
		||||
	
 | 
			
		||||
	// unsized constant
 | 
			
		||||
	if (str == endptr)
 | 
			
		||||
		intval = -1;
 | 
			
		||||
		len_in_bits = -1;
 | 
			
		||||
 | 
			
		||||
	// The "<bits>'s?[bodh]<digits>" syntax
 | 
			
		||||
	if (*endptr == '\'')
 | 
			
		||||
	{
 | 
			
		||||
		int len_in_bits = intval;
 | 
			
		||||
		std::vector<RTLIL::State> data;
 | 
			
		||||
		bool is_signed = false;
 | 
			
		||||
		if (*(endptr+1) == 's') {
 | 
			
		||||
| 
						 | 
				
			
			@ -188,6 +199,12 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type)
 | 
			
		|||
		default:
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		if (len_in_bits < 0) {
 | 
			
		||||
			if (is_signed && data.back() == RTLIL::S1)
 | 
			
		||||
				data.push_back(RTLIL::S0);
 | 
			
		||||
			while (data.size() < 32)
 | 
			
		||||
				data.push_back(RTLIL::S0);
 | 
			
		||||
		}
 | 
			
		||||
		return AstNode::mkconst_bits(data, is_signed);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue