Remove some dead code in tgt-vvp.

This commit is contained in:
Stephen Williams 2014-01-13 17:45:44 -08:00
parent 1905264061
commit 079065ea73
1 changed files with 10 additions and 551 deletions

View File

@ -414,6 +414,7 @@ static struct vector_info draw_eq_immediate(ivl_expr_t expr, unsigned ewid,
* This handles the special case that the operands of the comparison
* are real valued expressions.
*/
#if 0
static struct vector_info draw_binary_expr_eq_real(ivl_expr_t expr)
{
struct vector_info res;
@ -443,6 +444,15 @@ static struct vector_info draw_binary_expr_eq_real(ivl_expr_t expr)
return res;
}
#else
static struct vector_info draw_binary_expr_eq_real(ivl_expr_t expr)
{
struct vector_info res = {0, 0};
fprintf(vvp_out, " ; draw_binary_expr_real: dead code\n");
vvp_errors += 1;
return res;
}
#endif
static struct vector_info draw_binary_expr_eq_string(ivl_expr_t expr)
{
@ -753,117 +763,6 @@ static struct vector_info draw_binary_expr_land(ivl_expr_t expr, unsigned wid)
return lv;
}
static struct vector_info draw_binary_expr_lor(ivl_expr_t expr, unsigned wid,
int stuff_ok_flag)
{
ivl_expr_t le = ivl_expr_oper1(expr);
ivl_expr_t re = ivl_expr_oper2(expr);
struct vector_info lv;
struct vector_info rv;
lv = draw_eval_expr(le, STUFF_OK_XZ);
/* if the left operand has width, then evaluate the single-bit
logical equivalent. */
if ((lv.base >= 4) && (lv.wid > 1)) {
struct vector_info tmp;
clr_vector(lv);
tmp.base = allocate_vector(1);
tmp.wid = 1;
assert(tmp.base);
fprintf(vvp_out, " %%or/r %u, %u, %u;\n", tmp.base,
lv.base, lv.wid);
lv = tmp;
}
/* 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
logical equivalent. */
if ((rv.base >= 4) && (rv.wid > 1)) {
struct vector_info tmp;
clr_vector(rv);
tmp.base = allocate_vector(1);
tmp.wid = 1;
assert(tmp.base);
fprintf(vvp_out, " %%or/r %u, %u, %u;\n", tmp.base,
rv.base, rv.wid);
rv = tmp;
}
if (lv.base < 4) {
if (rv.base < 4) {
unsigned lb = lv.base;
unsigned rb = rv.base;
if ((lb == 0) && (rb == 0)) {
lv.base = 0;
} else if ((lb == 1) || (rb == 1)) {
lv.base = 1;
} else {
lv.base = 2;
}
} else if (lv.base==0) {
lv = rv;
} else {
fprintf(vvp_out, " %%or %u, %u, 1;\n", rv.base, lv.base);
lv = rv;
}
} else if (rv.base == 0) {
; /* Just return lv. */
} 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);
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 (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;
}
/* Write the result into a zero-padded result. */
{ unsigned base = allocate_vector(wid);
if (base == 0) {
fprintf(stderr, "%s:%u: vvp.tgt error: "
"Unable to allocate %u thread bits "
"for result of padded logical OR.\n",
ivl_expr_file(expr), ivl_expr_lineno(expr), wid);
vvp_errors += 1;
}
fprintf(vvp_out, " %%mov %u, %u, 1;\n", base, lv.base);
if (lv.base >= 8) clr_vector(lv);
lv.base = base;
lv.wid = wid;
fprintf(vvp_out, " %%pad %u, 0, %u;\n", base+1, wid-1);
}
return lv;
}
static struct vector_info draw_binary_expr_le_real(ivl_expr_t expr)
{
struct vector_info res;
@ -1181,423 +1080,6 @@ static struct vector_info draw_binary_expr_le(ivl_expr_t expr,
return lv;
}
static struct vector_info draw_logic_immediate(ivl_expr_t expr,
ivl_expr_t le,
ivl_expr_t re,
unsigned wid)
{
struct vector_info lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ);
assert(number_is_immediate(re, IMM_WID, 0));
assert(! number_is_unknown(re));
unsigned long imm = get_number_immediate(re);
assert(lv.base >= 4);
switch (ivl_expr_opcode(expr)) {
case '&':
fprintf(vvp_out, " %%andi %u, %lu, %u;\n", lv.base, imm, lv.wid);
break;
default:
assert(0);
break;
}
return lv;
}
static struct vector_info draw_binary_expr_logic(ivl_expr_t expr,
unsigned wid)
{
ivl_expr_t le = ivl_expr_oper1(expr);
ivl_expr_t re = ivl_expr_oper2(expr);
struct vector_info lv;
struct vector_info rv;
if (ivl_expr_opcode(expr) == '&') {
if (number_is_immediate(re, IMM_WID, 0) && !number_is_unknown(re))
return draw_logic_immediate(expr, le, re, wid);
if (number_is_immediate(le, IMM_WID, 0) && !number_is_unknown(le))
return draw_logic_immediate(expr, re, le, wid);
}
lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ);
rv = draw_eval_expr_wid(re, wid, STUFF_OK_XZ);
/* The result goes into the left operand, and that is returned
as the result. The instructions do not allow the lv value
to be a constant bit, so we either switch the operands, or
copy the vector into a new area. */
if (lv.base < 4) {
if (rv.base > 4) {
struct vector_info tmp = lv;
lv = rv;
rv = tmp;
} else {
struct vector_info tmp;
tmp.base = allocate_vector(lv.wid);
tmp.wid = lv.wid;
if (tmp.base == 0) {
fprintf(stderr, "%s:%u: vvp.tgt error: "
"Unable to allocate %u thread bits "
"for result of binary logic.\n",
ivl_expr_file(expr), ivl_expr_lineno(expr),
wid);
vvp_errors += 1;
}
fprintf(vvp_out, " %%mov %u, %u, %u;\n",
tmp.base, lv.base, tmp.wid);
lv = tmp;
}
}
switch (ivl_expr_opcode(expr)) {
case '&':
fprintf(vvp_out, " %%and %u, %u, %u;\n",
lv.base, rv.base, wid);
break;
case '|':
fprintf(vvp_out, " %%or %u, %u, %u;\n",
lv.base, rv.base, wid);
break;
case '^':
fprintf(vvp_out, " %%xor %u, %u, %u;\n",
lv.base, rv.base, wid);
break;
case 'A': /* NAND (~&) */
fprintf(vvp_out, " %%nand %u, %u, %u;\n",
lv.base, rv.base, wid);
break;
case 'O': /* NOR (~|) */
fprintf(vvp_out, " %%nor %u, %u, %u;\n",
lv.base, rv.base, wid);
break;
case 'X': /* exclusive nor (~^) */
fprintf(vvp_out, " %%xnor %u, %u, %u;\n",
lv.base, rv.base, wid);
break;
default:
assert(0);
}
clr_vector(rv);
return lv;
}
static struct vector_info draw_load_add_immediate(ivl_expr_t le,
ivl_expr_t re,
unsigned wid,
int signed_flag)
{
struct vector_info lv;
long imm;
assert(! number_is_unknown(re));
assert(number_is_immediate(re, IMM_WID, 1));
imm = get_number_immediate(re);
lv.base = allocate_vector(wid);
lv.wid = wid;
if (lv.base == 0) {
fprintf(stderr, "%s:%u: vvp.tgt error: "
"Unable to allocate %u thread bits "
"for result of addition.\n",
ivl_expr_file(le), ivl_expr_lineno(le), wid);
vvp_errors += 1;
}
/* Load the signal value with a %load that adds the index
register to the value being loaded. */
draw_signal_dest(le, lv, signed_flag, imm);
return lv;
}
static struct vector_info draw_add_immediate(ivl_expr_t le,
ivl_expr_t re,
unsigned wid)
{
struct vector_info lv;
unsigned long imm;
lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ);
assert(lv.wid == wid);
assert(! number_is_unknown(re));
assert(number_is_immediate(re, IMM_WID, 0));
imm = get_number_immediate(re);
/* This shouldn't generally happen, because the elaborator
should take care of simple constant propagation like this,
but it doesn't have to and it is easy to catch here. */
if (imm == 0)
return lv;
switch (lv.base) {
case 0: /* Left expression is 0. */
lv.base = allocate_vector(wid);
if (lv.base == 0) {
fprintf(stderr, "%s:%u: vvp.tgt error: "
"Unable to allocate %u thread bits "
"for result of addition.\n",
ivl_expr_file(re), ivl_expr_lineno(re), wid);
vvp_errors += 1;
}
fprintf(vvp_out, " %%movi %u, %lu %u;\n", lv.base, imm, wid);
break;
case 1: /* Left expression is 1...1 (i.e. -1) */
imm -= 1;
if (imm == 0) {
lv.base = 0;
} else {
lv.base = allocate_vector(wid);
if (lv.base == 0) {
fprintf(stderr, "%s:%u: vvp.tgt error: "
"Unable to allocate %u thread bits "
"for result of addition.\n",
ivl_expr_file(re), ivl_expr_lineno(re), wid);
vvp_errors += 1;
}
fprintf(vvp_out, " %%movi %u, %lu %u;\n", lv.base, imm, wid);
}
break;
case 2: /* Left expression is 'bx or 'bz */
case 3:
lv.base = 2;
break;
default: /* The regular case. */
fprintf(vvp_out, " %%addi %u, %lu, %u;\n", lv.base, imm, wid);
break;
}
return lv;
}
/*
* The subi is restricted to imm operands that are <= 16 bits wide.
*/
static struct vector_info draw_sub_immediate(ivl_expr_t le,
ivl_expr_t re,
unsigned wid)
{
struct vector_info lv;
unsigned long imm;
unsigned tmp;
lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ);
assert(lv.wid == wid);
assert(! number_is_unknown(re));
assert(number_is_immediate(re, IMM_WID, 0));
imm = get_number_immediate(re);
if (imm == 0)
return lv;
switch (lv.base) {
case 0:
case 1:
tmp = allocate_vector(wid);
if (tmp == 0) {
fprintf(stderr, "%s:%u: vvp.tgt error: "
"Unable to allocate %u thread bits "
"for result of subtraction.\n",
ivl_expr_file(le), ivl_expr_lineno(le), wid);
vvp_errors += 1;
}
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);
break;
case 2:
case 3:
lv.base = 2;
break;
default:
fprintf(vvp_out, " %%subi %u, %lu, %u;\n", lv.base, imm, wid);
break;
}
return lv;
}
static struct vector_info draw_mul_immediate(ivl_expr_t le,
ivl_expr_t re,
unsigned wid)
{
struct vector_info lv;
unsigned long imm;
lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ);
assert(lv.wid == wid);
assert(! number_is_unknown(re));
assert(number_is_immediate(re, IMM_WID, 0));
imm = get_number_immediate(re);
if (imm == 0)
return lv;
fprintf(vvp_out, " %%muli %u, %lu, %u;\n", lv.base, imm, lv.wid);
return lv;
}
static struct vector_info draw_binary_expr_arith(ivl_expr_t expr, unsigned wid)
{
ivl_expr_t le = ivl_expr_oper1(expr);
ivl_expr_t re = ivl_expr_oper2(expr);
struct vector_info lv;
struct vector_info rv;
int signed_flag = ivl_expr_signed(le) && ivl_expr_signed(re) ? 1 : 0;
const char*sign_string = signed_flag ? "/s" : "";
if ((ivl_expr_opcode(expr) == '+')
&& (ivl_expr_type(le) == IVL_EX_SIGNAL)
&& (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(expr) == '+')
&& (ivl_expr_type(le) == IVL_EX_SIGNAL)
&& (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(expr) == '+')
&& (ivl_expr_type(re) == IVL_EX_SIGNAL)
&& (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(expr) == '+')
&& (ivl_expr_type(re) == IVL_EX_SIGNAL)
&& (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(expr) == '+')
&& (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(expr) == '+')
&& (ivl_expr_type(re) == IVL_EX_NUMBER)
&& (! number_is_unknown(re))
&& number_is_immediate(re, IMM_WID, 0))
return draw_add_immediate(le, re, wid);
if ((ivl_expr_opcode(expr) == '-')
&& (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(expr) == '-')
&& (ivl_expr_type(re) == IVL_EX_NUMBER)
&& (! number_is_unknown(re))
&& number_is_immediate(re, IMM_WID, 0))
return draw_sub_immediate(le, re, wid);
if ((ivl_expr_opcode(expr) == '*')
&& (ivl_expr_type(re) == IVL_EX_NUMBER)
&& (! number_is_unknown(re))
&& number_is_immediate(re, IMM_WID, 0))
return draw_mul_immediate(le, re, wid);
lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ);
rv = draw_eval_expr_wid(re, wid, STUFF_OK_XZ|STUFF_OK_RO);
if (lv.wid != wid) {
fprintf(stderr, "XXXX ivl_expr_opcode(expr) = %c,"
" lv.wid=%u, wid=%u\n", ivl_expr_opcode(expr),
lv.wid, wid);
}
assert(lv.wid == wid);
assert(rv.wid == wid);
/* The arithmetic instructions replace the left operand with
the result. If the left operand is a replicated constant,
then I need to make a writable copy so that the
instruction can operate. */
if (lv.base < 4) {
struct vector_info tmp;
tmp.base = allocate_vector(wid);
tmp.wid = wid;
if (tmp.base == 0) {
fprintf(stderr, "%s:%u: vvp.tgt error: "
"Unable to allocate %u thread bits "
"for result of arithmetic expression.\n",
ivl_expr_file(expr), ivl_expr_lineno(expr), wid);
vvp_errors += 1;
}
fprintf(vvp_out, " %%mov %u, %u, %u;\n", tmp.base,
lv.base, wid);
lv = tmp;
}
switch (ivl_expr_opcode(expr)) {
case '+':
fprintf(vvp_out, " %%add %u, %u, %u;\n", lv.base, rv.base, wid);
break;
case '-':
fprintf(vvp_out, " %%sub %u, %u, %u;\n", lv.base, rv.base, wid);
break;
case '*':
fprintf(vvp_out, " %%mul %u, %u, %u;\n", lv.base, rv.base, wid);
break;
case '/':
fprintf(vvp_out, " %%div%s %u, %u, %u;\n", sign_string,
lv.base, rv.base, wid);
break;
case '%':
fprintf(vvp_out, " %%mod%s %u, %u, %u;\n", sign_string,
lv.base, rv.base, wid);
break;
case 'p':
if (ivl_expr_signed(le) || ivl_expr_signed(re)) {
fprintf(vvp_out, " %%pow/s %u, %u, %u;\n",
lv.base, rv.base, wid);
} else {
fprintf(vvp_out, " %%pow %u, %u, %u;\n",
lv.base, rv.base, wid);
}
break;
default:
assert(0);
}
clr_vector(rv);
return lv;
}
static struct vector_info draw_binary_expr(ivl_expr_t expr,
unsigned wid,
int stuff_ok_flag)
@ -1626,29 +1108,6 @@ static struct vector_info draw_binary_expr(ivl_expr_t expr,
stuff_ok_used_flag = 1;
break;
case '+':
case '-':
case '*':
case '/':
case '%':
case 'p':
rv = draw_binary_expr_arith(expr, wid);
break;
case 'o': /* || (logical or) */
rv = draw_binary_expr_lor(expr, wid, stuff_ok_flag);
stuff_ok_used_flag = 1;
break;
case '&':
case '|':
case '^':
case 'A': /* NAND (~&) */
case 'O': /* NOR (~|) */
case 'X': /* XNOR (~^) */
rv = draw_binary_expr_logic(expr, wid);
break;
default:
fprintf(stderr, "vvp.tgt error: draw_binary_expr: unsupported binary (%c)\n",
ivl_expr_opcode(expr));