From 9cb62a4d643c1b4e388ffd036427df0a443328b9 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 6 Oct 2008 16:22:34 -0700 Subject: [PATCH] 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. --- tgt-vvp/draw_vpi.c | 8 +++----- tgt-vvp/eval_expr.c | 40 +++++++++++++++++++++++++++++----------- tgt-vvp/eval_real.c | 10 +++++----- tgt-vvp/vvp_process.c | 17 ++++++++++------- 4 files changed, 47 insertions(+), 28 deletions(-) diff --git a/tgt-vvp/draw_vpi.c b/tgt-vvp/draw_vpi.c index 0e8cc5252..b742ff3fb 100644 --- a/tgt-vvp/draw_vpi.c +++ b/tgt-vvp/draw_vpi.c @@ -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; } diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index ea67f4051..aeb77ce60 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -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<= 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 diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 3bd34c8ab..de9ce577e 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -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; diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 5815cbbe5..1d643454f 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -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); }