Lor takes advantave of STUFF_OK_47
It is ot uncommon for the arguments to logical or to leave stuff in bit registers 4-7. Allow the lor itself to take advantage of that to save some %mov instructions.
This commit is contained in:
parent
bc8b97dbcd
commit
83a7497912
|
|
@ -475,7 +475,7 @@ static struct vector_info draw_binary_expr_eq(ivl_expr_t exp,
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((stuff_ok_flag&STUFF_OK_47) && (wid == 1)) {
|
if ((stuff_ok_flag&STUFF_OK_47) && (ewid == 1)) {
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -584,7 +584,8 @@ static struct vector_info draw_binary_expr_land(ivl_expr_t exp, unsigned wid)
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct vector_info draw_binary_expr_lor(ivl_expr_t exp, unsigned wid)
|
static struct vector_info draw_binary_expr_lor(ivl_expr_t exp, unsigned wid,
|
||||||
|
int stuff_ok_flag)
|
||||||
{
|
{
|
||||||
ivl_expr_t le = ivl_expr_oper1(exp);
|
ivl_expr_t le = ivl_expr_oper1(exp);
|
||||||
ivl_expr_t re = ivl_expr_oper2(exp);
|
ivl_expr_t re = ivl_expr_oper2(exp);
|
||||||
|
|
@ -607,7 +608,9 @@ static struct vector_info draw_binary_expr_lor(ivl_expr_t exp, unsigned wid)
|
||||||
lv = tmp;
|
lv = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = draw_eval_expr(re, STUFF_OK_XZ);
|
/* The right expression may be left in registers 4-7 because
|
||||||
|
I'll be using it immediately. */
|
||||||
|
rv = draw_eval_expr(re, STUFF_OK_XZ|STUFF_OK_47);
|
||||||
|
|
||||||
/* if the right operand has width, then evaluate the single-bit
|
/* if the right operand has width, then evaluate the single-bit
|
||||||
logical equivalent. */
|
logical equivalent. */
|
||||||
|
|
@ -637,20 +640,40 @@ static struct vector_info draw_binary_expr_lor(ivl_expr_t exp, unsigned wid)
|
||||||
lv.base = 2;
|
lv.base = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (lv.base==0) {
|
||||||
|
lv = rv;
|
||||||
} else {
|
} else {
|
||||||
fprintf(vvp_out, " %%or %u, %u, 1;\n", rv.base, lv.base);
|
fprintf(vvp_out, " %%or %u, %u, 1;\n", rv.base, lv.base);
|
||||||
lv = rv;
|
lv = rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (rv.base == 0) {
|
||||||
|
; /* Just return lv. */
|
||||||
} else {
|
} else {
|
||||||
|
if (rv.base >= 8 && lv.base < 8 && !(stuff_ok_flag&STUFF_OK_47)) {
|
||||||
|
/* If STUFF_OK_47 is false, and rv is not in the
|
||||||
|
47 area (and lv is) then plan to or the result
|
||||||
|
into the rv instead. This can case a %mov later. */
|
||||||
|
struct vector_info tmp = lv;
|
||||||
|
lv = rv;
|
||||||
|
rv = tmp;
|
||||||
|
}
|
||||||
fprintf(vvp_out, " %%or %u, %u, 1;\n", lv.base, rv.base);
|
fprintf(vvp_out, " %%or %u, %u, 1;\n", lv.base, rv.base);
|
||||||
clr_vector(rv);
|
if (rv.base >= 8) clr_vector(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wid==1 && (lv.base<4 || lv.base>=8 || (stuff_ok_flag&STUFF_OK_47)))
|
||||||
|
return lv;
|
||||||
|
|
||||||
/* If we only want the single bit result, then we are done. */
|
/* If we only want the single bit result, then we are done. */
|
||||||
if (wid == 1)
|
if (wid == 1) {
|
||||||
|
if (lv.base >= 4 && lv.base < 8) {
|
||||||
|
unsigned tmp = allocate_vector(1);
|
||||||
|
fprintf(vvp_out, " %%mov %u, %u, 1;\n", tmp, lv.base);
|
||||||
|
lv.base = tmp;
|
||||||
|
}
|
||||||
return lv;
|
return lv;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write the result into a zero-padded result. */
|
/* Write the result into a zero-padded result. */
|
||||||
{ unsigned base = allocate_vector(wid);
|
{ unsigned base = allocate_vector(wid);
|
||||||
|
|
@ -663,7 +686,7 @@ static struct vector_info draw_binary_expr_lor(ivl_expr_t exp, unsigned wid)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(vvp_out, " %%mov %u, %u, 1;\n", base, lv.base);
|
fprintf(vvp_out, " %%mov %u, %u, 1;\n", base, lv.base);
|
||||||
clr_vector(lv);
|
if (lv.base >= 8) clr_vector(lv);
|
||||||
lv.base = base;
|
lv.base = base;
|
||||||
lv.wid = wid;
|
lv.wid = wid;
|
||||||
fprintf(vvp_out, " %%mov %u, 0, %u;\n", base+1, wid-1);
|
fprintf(vvp_out, " %%mov %u, 0, %u;\n", base+1, wid-1);
|
||||||
|
|
@ -1503,7 +1526,8 @@ static struct vector_info draw_binary_expr(ivl_expr_t exp,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o': /* || (logical or) */
|
case 'o': /* || (logical or) */
|
||||||
rv = draw_binary_expr_lor(exp, wid);
|
rv = draw_binary_expr_lor(exp, wid, stuff_ok_flag);
|
||||||
|
stuff_ok_used_flag = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '&':
|
case '&':
|
||||||
|
|
@ -1563,7 +1587,6 @@ static struct vector_info draw_concat_expr(ivl_expr_t exp, unsigned wid,
|
||||||
vvp_errors += 1;
|
vvp_errors += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the repeat count. This must be a constant that has been
|
/* Get the repeat count. This must be a constant that has been
|
||||||
evaluated at compile time. The operands will be repeated to
|
evaluated at compile time. The operands will be repeated to
|
||||||
form the result. */
|
form the result. */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue