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:
parent
3ba9e945d7
commit
2d1e0b3ade
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue