Improved parsing of large integer constants

This commit is contained in:
Clifford Wolf 2014-06-15 08:48:17 +02:00
parent 48dc6ab98d
commit 7f57bc8385
1 changed files with 28 additions and 11 deletions

View File

@ -52,6 +52,8 @@ static int my_decimal_div_by_two(std::vector<uint8_t> &digits)
carry = digits[i] % 2; carry = digits[i] % 2;
digits[i] /= 2; digits[i] /= 2;
} }
while (!digits.empty() && !digits.front())
digits.erase(digits.begin());
return carry; return carry;
} }
@ -90,10 +92,15 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le
if (base == 10) { if (base == 10) {
data.clear(); data.clear();
if (len_in_bits < 0) if (len_in_bits < 0) {
len_in_bits = ceil(digits.size()/log10(2)); while (!digits.empty())
for (int i = 0; i < len_in_bits; i++) data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0);
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; return;
} }
@ -151,20 +158,24 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type)
str = code.c_str(); str = code.c_str();
char *endptr; char *endptr;
long intval = strtol(str, &endptr, 10); long len_in_bits = strtol(str, &endptr, 10);
// Simple 32 bit integer // Simple base-10 integer
if (*endptr == 0) if (*endptr == 0) {
return AstNode::mkconst_int(intval, true); 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);
}
// unsized constant // unsized constant
if (str == endptr) if (str == endptr)
intval = -1; len_in_bits = -1;
// The "<bits>'s?[bodh]<digits>" syntax // The "<bits>'s?[bodh]<digits>" syntax
if (*endptr == '\'') if (*endptr == '\'')
{ {
int len_in_bits = intval;
std::vector<RTLIL::State> data; std::vector<RTLIL::State> data;
bool is_signed = false; bool is_signed = false;
if (*(endptr+1) == 's') { if (*(endptr+1) == 's') {
@ -188,6 +199,12 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type)
default: default:
return NULL; 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); return AstNode::mkconst_bits(data, is_signed);
} }