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;
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);
}