Check that numbers fit into the correct immediate width (32 bits).

Even on 64 bit machines immediate values should be limited to
32 bits so that the a.out file will run correctly on a 32 bit
machine. This patch fixes a number of places where the code
generator was not checking for/observing this.
This commit is contained in:
Cary R 2008-10-06 16:22:34 -07:00 committed by Stephen Williams
parent fd4018cb33
commit 9cb62a4d64
4 changed files with 47 additions and 28 deletions

View File

@ -69,7 +69,7 @@ static int is_fixed_memory_word(ivl_expr_t net)
if (ivl_signal_type(sig) == IVL_SIT_REG)
return 0;
if (number_is_immediate(ivl_expr_oper1(net), 8*sizeof(unsigned), 0))
if (number_is_immediate(ivl_expr_oper1(net), IMM_WID, 0))
return 1;
return 0;
@ -108,8 +108,7 @@ static int get_vpi_taskfunc_signal_arg(struct args_info *result,
ivl_expr_t word_ex = ivl_expr_oper1(expr);
if (word_ex) {
/* Some array select have been evaluated. */
if (number_is_immediate(word_ex,
8*sizeof(unsigned), 0)) {
if (number_is_immediate(word_ex,IMM_WID, 0)) {
use_word = get_number_immediate(word_ex);
word_ex = 0;
}
@ -129,8 +128,7 @@ static int get_vpi_taskfunc_signal_arg(struct args_info *result,
ivl_expr_t word_ex = ivl_expr_oper1(expr);
if (word_ex) {
/* Some array select have been evaluated. */
if (number_is_immediate(word_ex,
8*sizeof(unsigned), 0)) {
if (number_is_immediate(word_ex, IMM_WID, 0)) {
use_word = get_number_immediate(word_ex);
word_ex = 0;
}

View File

@ -65,6 +65,15 @@ int number_is_immediate(ivl_expr_t ex, unsigned lim_wid, int negative_ok_flag)
&& ivl_expr_type(ex) != IVL_EX_ULONG)
return 0;
if (ivl_expr_type(ex) == IVL_EX_ULONG) {
long imm;
if (lim_wid >= 8*sizeof(long)) return 1;
/* At this point we know that lim_wid is smaller than a long. */
imm = labs(ivl_expr_uvalue(ex));
if (imm < (1L<<lim_wid)) return 1;
else return 0;
}
bits = ivl_expr_bits(ex);
if (ivl_expr_signed(ex) && bits[nbits-1]=='1')
@ -97,13 +106,13 @@ long get_number_immediate(ivl_expr_t ex)
case '0':
break;
case '1':
assert(idx < 8*sizeof(imm));
assert(idx < IMM_WID);
imm |= 1L << idx;
break;
default:
assert(0);
}
if (ivl_expr_signed(ex) && bits[nbits-1]=='1' && nbits < 8*sizeof(imm))
if (ivl_expr_signed(ex) && bits[nbits-1]=='1' && nbits < IMM_WID)
imm |= -1L << nbits;
break;
}
@ -122,6 +131,7 @@ static void eval_logic_into_integer(ivl_expr_t expr, unsigned ix)
case IVL_EX_NUMBER:
case IVL_EX_ULONG:
{
assert(number_is_immediate(expr, IMM_WID, 1));
long imm = get_number_immediate(expr);
if (imm >= 0) {
fprintf(vvp_out, " %%ix/load %u, %ld;\n", ix, imm);
@ -154,7 +164,7 @@ static void eval_logic_into_integer(ivl_expr_t expr, unsigned ix)
}
ixe = ivl_expr_oper1(expr);
if (number_is_immediate(ixe, 8*sizeof(unsigned long), 0))
if (number_is_immediate(ixe, IMM_WID, 0))
word = get_number_immediate(ixe);
else {
struct vector_info rv;
@ -1326,36 +1336,44 @@ static struct vector_info draw_binary_expr_arith(ivl_expr_t exp, unsigned wid)
if ((ivl_expr_opcode(exp) == '+')
&& (ivl_expr_type(le) == IVL_EX_SIGNAL)
&& (ivl_expr_type(re) == IVL_EX_ULONG))
&& (ivl_expr_type(re) == IVL_EX_ULONG)
&& number_is_immediate(re, IMM_WID, 1))
return draw_load_add_immediate(le, re, wid, signed_flag);
if ((ivl_expr_opcode(exp) == '+')
&& (ivl_expr_type(le) == IVL_EX_SIGNAL)
&& (ivl_expr_type(re) == IVL_EX_NUMBER))
&& (ivl_expr_type(re) == IVL_EX_NUMBER)
&& (! number_is_unknown(re))
&& number_is_immediate(re, IMM_WID, 1))
return draw_load_add_immediate(le, re, wid, signed_flag);
if ((ivl_expr_opcode(exp) == '+')
&& (ivl_expr_type(re) == IVL_EX_SIGNAL)
&& (ivl_expr_type(le) == IVL_EX_ULONG))
&& (ivl_expr_type(le) == IVL_EX_ULONG)
&& number_is_immediate(re, IMM_WID, 1))
return draw_load_add_immediate(re, le, wid, signed_flag);
if ((ivl_expr_opcode(exp) == '+')
&& (ivl_expr_type(re) == IVL_EX_SIGNAL)
&& (ivl_expr_type(le) == IVL_EX_NUMBER))
&& (ivl_expr_type(le) == IVL_EX_NUMBER)
&& (! number_is_unknown(le))
&& number_is_immediate(le, IMM_WID, 1))
return draw_load_add_immediate(re, le, wid, signed_flag);
if ((ivl_expr_opcode(exp) == '+')
&& (ivl_expr_type(re) == IVL_EX_ULONG))
&& (ivl_expr_type(re) == IVL_EX_ULONG)
&& number_is_immediate(re, IMM_WID, 0))
return draw_add_immediate(le, re, wid);
if ((ivl_expr_opcode(exp) == '+')
&& (ivl_expr_type(re) == IVL_EX_NUMBER)
&& (! number_is_unknown(re))
&& number_is_immediate(re, 8*sizeof(unsigned long), 0))
&& number_is_immediate(re, IMM_WID, 0))
return draw_add_immediate(le, re, wid);
if ((ivl_expr_opcode(exp) == '-')
&& (ivl_expr_type(re) == IVL_EX_ULONG))
&& (ivl_expr_type(re) == IVL_EX_ULONG)
&& number_is_immediate(re, IMM_WID, 0))
return draw_sub_immediate(le, re, wid);
if ((ivl_expr_opcode(exp) == '-')
@ -2159,7 +2177,7 @@ static struct vector_info draw_select_signal(ivl_expr_t sube,
ivl_expr_t ix = ivl_expr_oper1(sube);
if (ivl_signal_type(sig)==IVL_SIT_REG
|| !number_is_immediate(ix, 8*sizeof(unsigned long),0))
|| !number_is_immediate(ix, IMM_WID, 0))
return draw_select_array(sube, bit_idx, bit_wid, wid);
/* The index is constant, so we can return to direct

View File

@ -34,7 +34,7 @@ static unsigned long word_alloc_mask = 0x0f;
int allocate_word()
{
int res = 4;
int max = 8*sizeof(word_alloc_mask);
int max = IMM_WID;
while (res < max && (1U << res) & word_alloc_mask)
res += 1;
@ -46,7 +46,7 @@ int allocate_word()
void clr_word(int res)
{
int max = 8*sizeof(word_alloc_mask);
int max = IMM_WID;
assert(res < max);
word_alloc_mask &= ~ (1U << res);
}
@ -183,7 +183,7 @@ static int draw_number_real(ivl_expr_t exp)
carry = 1;
}
for (idx = 0 ; idx < wid && idx < 8*sizeof(mant) ; idx += 1) {
for (idx = 0 ; idx < wid && idx < IMM_WID ; idx += 1) {
mask <<= 1;
int cur_bit = bits[idx] == '1'? 1 : 0;
@ -198,7 +198,7 @@ static int draw_number_real(ivl_expr_t exp)
}
for ( ; idx < wid ; idx += 1) {
if (ivl_expr_signed(exp) && (bits[idx] == bits[8*sizeof(mant)-1]))
if (ivl_expr_signed(exp) && (bits[idx] == bits[IMM_WID-1]))
continue;
if (bits[idx] == '0')
@ -358,7 +358,7 @@ static int draw_signal_real_real(ivl_expr_t exp)
if (ivl_signal_dimensions(sig) > 0) {
ivl_expr_t ix = ivl_expr_oper1(exp);
if (!number_is_immediate(ix, 8*sizeof(word), 0)) {
if (!number_is_immediate(ix, IMM_WID, 0)) {
/* XXXX Need to generate a %load/ar instruction. */
assert(0);
return res;

View File

@ -95,7 +95,7 @@ static void set_to_lvariable(ivl_lval_t lval,
/* If the word index is a constant expression, then evaluate
it to select the word, and pay no further heed to the
expression itself. */
if (word_ix && number_is_immediate(word_ix, 8*sizeof(use_word), 0)) {
if (word_ix && number_is_immediate(word_ix, IMM_WID, 0)) {
use_word = get_number_immediate(word_ix);
word_ix = 0;
}
@ -568,11 +568,12 @@ static int show_stmt_assign_nb_real(ivl_statement_t net)
if (ivl_signal_dimensions(sig) > 0) {
word_ix = ivl_lval_idx(lval);
assert(word_ix);
assert(number_is_immediate(word_ix, 8*sizeof(use_word), 0));
assert(number_is_immediate(word_ix, IMM_WID, 0));
use_word = get_number_immediate(word_ix);
}
if (del && (ivl_expr_type(del) == IVL_EX_ULONG)) {
assert(number_is_immediate(del, IMM_WID, 0));
delay = ivl_expr_uvalue(del);
del = 0;
}
@ -616,6 +617,7 @@ static int show_stmt_assign_nb(ivl_statement_t net)
ivl_expr_t cnt = ivl_stmt_cond_expr(net);
unsigned long count = 1;
if (cnt && (ivl_expr_type(cnt) == IVL_EX_ULONG)) {
assert(number_is_immediate(cnt, IMM_WID, 0));
count = ivl_expr_uvalue(cnt);
cnt = 0;
}
@ -667,6 +669,7 @@ static int show_stmt_assign_nb(ivl_statement_t net)
}
if (del && (ivl_expr_type(del) == IVL_EX_ULONG)) {
assert(number_is_immediate(del, IMM_WID, 0));
delay = ivl_expr_uvalue(del);
del = 0;
}
@ -1012,7 +1015,7 @@ static void force_vector_to_lval(ivl_statement_t net, struct vector_info rvec)
}
if (word_idx != 0) {
assert(number_is_immediate(word_idx, 8*sizeof(unsigned long), 0));
assert(number_is_immediate(word_idx, IMM_WID, 0));
use_word = get_number_immediate(word_idx);
}
@ -1086,12 +1089,12 @@ static void force_link_rval(ivl_statement_t net, ivl_expr_t rval)
/* At least for now, only handle force to fixed words of an array. */
if ((lword_idx = ivl_lval_idx(lval)) != 0) {
assert(number_is_immediate(lword_idx, 8*sizeof(unsigned long), 0));
assert(number_is_immediate(lword_idx, IMM_WID, 0));
use_lword = get_number_immediate(lword_idx);
}
if ((rword_idx = ivl_expr_oper1(rval)) != 0) {
assert(number_is_immediate(rword_idx, 8*sizeof(unsigned long), 0));
assert(number_is_immediate(rword_idx, IMM_WID, 0));
use_rword = get_number_immediate(rword_idx);
}
@ -1179,7 +1182,7 @@ static int show_stmt_deassign(ivl_statement_t net)
}
if (word_idx != 0) {
assert(number_is_immediate(word_idx, 8*sizeof(use_word), 0));
assert(number_is_immediate(word_idx, IMM_WID, 0));
use_word = get_number_immediate(word_idx);
}
@ -1483,7 +1486,7 @@ static int show_stmt_release(ivl_statement_t net)
}
if (word_idx != 0) {
assert(number_is_immediate(word_idx, 8*sizeof(use_word), 0));
assert(number_is_immediate(word_idx, IMM_WID, 0));
use_word = get_number_immediate(word_idx);
}