When evaluating a constant into an index make sure to clear bit 4.

When evaluating an expression into an index register bit 4 is used
to determine if the expression had any X/Z bits. In the case of a
constant immediate value this can not happen so make sure the bit
is cleared.
This commit is contained in:
Cary R 2008-09-17 16:18:17 -07:00 committed by Stephen Williams
parent 3ba9e945d7
commit 2d1e0b3ade
1 changed files with 36 additions and 34 deletions

View File

@ -124,11 +124,13 @@ static void eval_logic_into_integer(ivl_expr_t expr, unsigned ix)
{
long imm = get_number_immediate(expr);
if (imm >= 0) {
fprintf(vvp_out, " %%ix/load %u, %ld;\n", ix, imm);
fprintf(vvp_out, " %%ix/load %u, %ld;\n", ix, imm);
} else {
fprintf(vvp_out, " %%ix/load %u, 0; loading %ld\n", ix, imm);
fprintf(vvp_out, " %%ix/sub %u, %ld;\n", ix, -imm);
fprintf(vvp_out, " %%ix/load %u, 0; loading %ld\n", ix, imm);
fprintf(vvp_out, " %%ix/sub %u, %ld;\n", ix, -imm);
}
/* This can not have have a X/Z value so clear bit 4. */
fprintf(vvp_out, " %%mov 4, 0, 1;\n");
}
break;
@ -144,7 +146,7 @@ static void eval_logic_into_integer(ivl_expr_t expr, unsigned ix)
if (ivl_signal_type(sig) == IVL_SIT_REG) {
struct vector_info rv;
rv = draw_eval_expr(expr, 0);
fprintf(vvp_out, " %%ix/get %u, %u, %u;\n",
fprintf(vvp_out, " %%ix/get %u, %u, %u;\n",
ix, rv.base, rv.wid);
clr_vector(rv);
break;
@ -1273,9 +1275,9 @@ static struct vector_info draw_sub_immediate(ivl_expr_t le,
vvp_errors += 1;
}
fprintf(vvp_out, " %%mov %u, %u, %u;\n", tmp, lv.base, wid);
fprintf(vvp_out, " %%mov %u, %u, %u;\n", tmp, lv.base, wid);
lv.base = tmp;
fprintf(vvp_out, " %%subi %u, %lu, %u;\n", lv.base, imm, wid);
fprintf(vvp_out, " %%subi %u, %lu, %u;\n", lv.base, imm, wid);
break;
case 2:
@ -1284,7 +1286,7 @@ static struct vector_info draw_sub_immediate(ivl_expr_t le,
break;
default:
fprintf(vvp_out, " %%subi %u, %lu, %u;\n", lv.base, imm, wid);
fprintf(vvp_out, " %%subi %u, %lu, %u;\n", lv.base, imm, wid);
break;
}
@ -1305,7 +1307,7 @@ static struct vector_info draw_mul_immediate(ivl_expr_t le,
if (imm == 0)
return lv;
fprintf(vvp_out, " %%muli %u, %lu, %u;\n", lv.base, imm, lv.wid);
fprintf(vvp_out, " %%muli %u, %lu, %u;\n", lv.base, imm, lv.wid);
return lv;
}
@ -1677,7 +1679,7 @@ static struct vector_info draw_number_expr(ivl_expr_t exp, unsigned wid)
instruction. */
if ((!number_is_unknown(exp)) && number_is_immediate(exp, IMM_WID,0)) {
unsigned long val = get_number_immediate(exp);
fprintf(vvp_out, " %%movi %u, %lu, %u;\n", res.base, val, wid);
fprintf(vvp_out, " %%movi %u, %lu, %u;\n", res.base, val, wid);
return res;
}
@ -1709,7 +1711,7 @@ static struct vector_info draw_number_expr(ivl_expr_t exp, unsigned wid)
if (val_bits >= IMM_WID
|| (val_bits>0 && src != 0)
|| (val_bits>0 && idx+1==nwid)) {
fprintf(vvp_out, " %%movi %u, %lu, %u;\n",
fprintf(vvp_out, " %%movi %u, %lu, %u;\n",
val_addr, val, val_bits);
val_addr += val_bits;
val_bits = 0;
@ -1723,7 +1725,7 @@ static struct vector_info draw_number_expr(ivl_expr_t exp, unsigned wid)
if (bits[idx+cnt] != bits[idx])
break;
fprintf(vvp_out, " %%mov %u, %c, %u;\n", val_addr, src, cnt);
fprintf(vvp_out, " %%mov %u, %c, %u;\n", val_addr, src, cnt);
val_addr += cnt;
idx += cnt-1;
}
@ -1834,13 +1836,13 @@ static struct vector_info draw_realnum_expr(ivl_expr_t exp, unsigned wid)
continue;
}
fprintf(vvp_out, " %%mov %u, %d, %u;\n", addr, bit, run);
fprintf(vvp_out, " %%mov %u, %d, %u;\n", addr, bit, run);
addr += run;
run = 1;
bit = next_bit;
}
fprintf(vvp_out, " %%mov %u, %d, %u;\n", addr, bit, run);
fprintf(vvp_out, " %%mov %u, %d, %u;\n", addr, bit, run);
return res;
@ -1938,14 +1940,14 @@ static struct vector_info draw_string_expr(ivl_expr_t exp, unsigned wid)
}
}
}
fprintf(vvp_out, " %%movi %u, %u, %u;\n", res.base+idx,bits,trans);
fprintf(vvp_out, " %%movi %u, %u, %u;\n", res.base+idx,bits,trans);
idx += trans;
}
/* Pad the number up to the expression width. */
if (idx < wid)
fprintf(vvp_out, " %%mov %u, 0, %u;\n", res.base+idx, wid-idx);
fprintf(vvp_out, " %%mov %u, 0, %u;\n", res.base+idx, wid-idx);
if (res.base >= 8)
save_expression_lookaside(res.base, exp, wid);
@ -1978,9 +1980,9 @@ void pad_expr_in_place(ivl_expr_t exp, struct vector_info res, unsigned swid)
/* The %movi is faster for larger widths, but for very
small counts, the %mov is faster. */
if (count > 4)
fprintf(vvp_out, " %%movi %u, 0, %u;\n", base, count);
fprintf(vvp_out, " %%movi %u, 0, %u;\n", base, count);
else
fprintf(vvp_out, " %%mov %u, 0, %u;\n", base, count);
fprintf(vvp_out, " %%mov %u, 0, %u;\n", base, count);
}
}
@ -2013,15 +2015,15 @@ static void draw_signal_dest(ivl_expr_t exp, struct vector_info res,
draw_eval_expr_into_integer(ix, 3);
if (add_index < 0) {
fprintf(vvp_out, " %%load/av %u, v%p, %u;\n",
fprintf(vvp_out, " %%load/av %u, v%p, %u;\n",
res.base, sig, swid);
pad_expr_in_place(exp, res, swid);
} else {
const char*sign_flag = (add_index>0)? "/s" : "";
/* Add an immediate value to an array value. */
fprintf(vvp_out, " %%ix/load 0, %lu;\n", immediate);
fprintf(vvp_out, " %%load/avp0%s %u, v%p, %u;\n",
fprintf(vvp_out, " %%ix/load 0, %lu;\n", immediate);
fprintf(vvp_out, " %%load/avp0%s %u, v%p, %u;\n",
sign_flag, res.base, sig, res.wid);
}
return;
@ -2032,8 +2034,8 @@ static void draw_signal_dest(ivl_expr_t exp, struct vector_info res,
assert(add_index < 0);
int tmp = allocate_word();
fprintf(vvp_out, " %%load/wr %d, v%p_%u;\n", tmp, sig, word);
fprintf(vvp_out, " %%cvt/vr %u, %d, %u;\n", res.base, tmp, res.wid);
fprintf(vvp_out, " %%load/wr %d, v%p_%u;\n", tmp, sig, word);
fprintf(vvp_out, " %%cvt/vr %u, %d, %u;\n", res.base, tmp, res.wid);
clr_word(tmp);
} else if (add_index >= 0) {
@ -2044,8 +2046,8 @@ static void draw_signal_dest(ivl_expr_t exp, struct vector_info res,
if (immediate >= 0) {
fprintf(vvp_out, " %%ix/load 0, %lu;\n", immediate);
} else {
fprintf(vvp_out, " %%ix/load 0, 0; immediate=%ld\n", immediate);
fprintf(vvp_out, " %%ix/sub 0, %ld;\n", -immediate);
fprintf(vvp_out, " %%ix/load 0, 0; immediate=%ld\n", immediate);
fprintf(vvp_out, " %%ix/sub 0, %ld;\n", -immediate);
}
fprintf(vvp_out, " %%load/vp0%s %u, v%p_%u, %u;\n", sign_flag,
res.base, sig,word, res.wid);
@ -2109,7 +2111,7 @@ static struct vector_info draw_select_array(ivl_expr_t sube,
shiv = draw_eval_expr(bit_idx, STUFF_OK_XZ|STUFF_OK_RO);
draw_eval_expr_into_integer(ix, 3);
fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", shiv.base, shiv.wid);
fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", shiv.base, shiv.wid);
if (shiv.base >= 8)
clr_vector(shiv);
@ -2124,7 +2126,7 @@ static struct vector_info draw_select_array(ivl_expr_t sube,
}
for (idx = 0 ; idx < wid ; idx += 1) {
fprintf(vvp_out, " %%load/avx.p %u, v%p, 0;\n", res.base+idx, sig);
fprintf(vvp_out, " %%load/avx.p %u, v%p, 0;\n", res.base+idx, sig);
}
return res;
@ -2169,7 +2171,7 @@ static struct vector_info draw_select_signal(ivl_expr_t sube,
res.base = allocate_vector(wid);
res.wid = wid;
assert(res.base);
fprintf(vvp_out, " %%load/v %u, v%p_%u, %u; Only need %u of %u bits\n",
fprintf(vvp_out, " %%load/v %u, v%p_%u, %u; Only need %u of %u bits\n",
res.base, sig, use_word, bit_wid, bit_wid, ivl_expr_width(sube));
save_signal_lookaside(res.base, sig, use_word, bit_wid);
@ -2192,10 +2194,10 @@ static struct vector_info draw_select_signal(ivl_expr_t sube,
if (use_wid > bit_wid)
use_wid = bit_wid;
fprintf(vvp_out, " %%load/x1p %u, v%p_%u, %u;\n",
fprintf(vvp_out, " %%load/x1p %u, v%p_%u, %u;\n",
res.base, sig, use_word, use_wid);
if (use_wid < res.wid)
fprintf(vvp_out, " %%movi %u, 0, %u;\n",
fprintf(vvp_out, " %%movi %u, 0, %u;\n",
res.base + use_wid, res.wid - use_wid);
return res;
@ -2583,15 +2585,15 @@ static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid)
result a 1. */
if (res.base == 1) {
res.base = allocate_vector(wid);
fprintf(vvp_out, " %%movi %d, 1, %u;\n",
fprintf(vvp_out, " %%movi %d, 1, %u;\n",
res.base, res.wid);
break;
}
fprintf(vvp_out, " %%cmpi/s %d, 0, %u;\n", res.base, res.wid);
fprintf(vvp_out, " %%jmp/0xz T_%u.%u, 5;\n", thread_count, local_count);
fprintf(vvp_out, " %%inv %d, %u;\n", res.base, res.wid);
fprintf(vvp_out, " %%addi %d, 1, %u;\n", res.base, res.wid);
fprintf(vvp_out, " %%cmpi/s %d, 0, %u;\n", res.base, res.wid);
fprintf(vvp_out, " %%jmp/0xz T_%u.%u, 5;\n", thread_count, local_count);
fprintf(vvp_out, " %%inv %d, %u;\n", res.base, res.wid);
fprintf(vvp_out, " %%addi %d, 1, %u;\n", res.base, res.wid);
fprintf(vvp_out, "T_%u.%u ;\n", thread_count, local_count);
local_count += 1;
break;