diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index d646e3e33..1bf83b817 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: eval_expr.c,v 1.78 2002/09/18 04:29:55 steve Exp $" +#ident "$Id: eval_expr.c,v 1.79 2002/09/24 04:20:32 steve Exp $" #endif # include "vvp_priv.h" @@ -162,27 +162,28 @@ unsigned long get_number_immediate(ivl_expr_t ex) } /* - * The xz_ok_flag is true if the output is going to be further + * The STUFF_OK_XZ bit is true if the output is going to be further * processed so that x and z values are equivilent. This may allow for * new optimizations. */ static struct vector_info draw_eq_immediate(ivl_expr_t exp, unsigned ewid, ivl_expr_t le, ivl_expr_t re, - int xz_ok_flag) + int stuff_ok_flag) { unsigned wid; struct vector_info lv; unsigned long imm = get_number_immediate(re); wid = ivl_expr_width(le); - lv = draw_eval_expr_wid(le, wid, xz_ok_flag); + lv = draw_eval_expr_wid(le, wid, stuff_ok_flag); switch (ivl_expr_opcode(exp)) { case 'E': /* === */ fprintf(vvp_out, " %%cmpi/u %u, %lu, %u;\n", lv.base, imm, wid); - clr_vector(lv); + if (lv.base >= 8) + clr_vector(lv); lv.base = 6; lv.wid = 1; break; @@ -191,12 +192,13 @@ static struct vector_info draw_eq_immediate(ivl_expr_t exp, unsigned ewid, /* If this is a single bit being compared to 1, and the output doesn't care about x vs z, then just return the value itself. */ - if (xz_ok_flag && (lv.wid == 1) && (imm == 1)) + if ((stuff_ok_flag&STUFF_OK_XZ) && (lv.wid == 1) && (imm == 1)) break; fprintf(vvp_out, " %%cmpi/u %u, %lu, %u;\n", lv.base, imm, wid); - clr_vector(lv); + if (lv.base >= 8) + clr_vector(lv); lv.base = 4; lv.wid = 1; break; @@ -204,7 +206,8 @@ static struct vector_info draw_eq_immediate(ivl_expr_t exp, unsigned ewid, case 'N': /* !== */ fprintf(vvp_out, " %%cmpi/u %u, %lu, %u;\n", lv.base, imm, wid); - clr_vector(lv); + if (lv.base >= 8) + clr_vector(lv); lv.base = 6; lv.wid = 1; fprintf(vvp_out, " %%inv 6, 1;\n"); @@ -214,12 +217,13 @@ static struct vector_info draw_eq_immediate(ivl_expr_t exp, unsigned ewid, /* If this is a single bit being compared to 0, and the output doesn't care about x vs z, then just return the value itself. */ - if (xz_ok_flag && (lv.wid == 1) && (imm == 0)) + if ((stuff_ok_flag&STUFF_OK_XZ) && (lv.wid == 1) && (imm == 0)) break; fprintf(vvp_out, " %%cmpi/u %u, %lu, %u;\n", lv.base, imm, wid); - clr_vector(lv); + if (lv.base >= 8) + clr_vector(lv); lv.base = 4; lv.wid = 1; fprintf(vvp_out, " %%inv 4, 1;\n"); @@ -229,6 +233,11 @@ static struct vector_info draw_eq_immediate(ivl_expr_t exp, unsigned ewid, assert(0); } + /* In the special case that 47 bits are ok, and this really is + a single bit value, then we are done. */ + if ((lv.wid == 1) && (ewid == 1) && (stuff_ok_flag&STUFF_OK_47)) + return lv; + /* Move the result out out the 4-7 bit that the compare uses. This is because that bit may be clobbered by other expressions. */ @@ -256,7 +265,7 @@ static struct vector_info draw_eq_immediate(ivl_expr_t exp, unsigned ewid, static struct vector_info draw_binary_expr_eq(ivl_expr_t exp, unsigned ewid, - int xz_ok_flag) + int stuff_ok_flag) { ivl_expr_t le = ivl_expr_oper1(exp); ivl_expr_t re = ivl_expr_oper2(exp); @@ -268,19 +277,19 @@ static struct vector_info draw_binary_expr_eq(ivl_expr_t exp, if ((ivl_expr_type(re) == IVL_EX_ULONG) && (0 == (ivl_expr_uvalue(re) & ~0xffff))) - return draw_eq_immediate(exp, ewid, le, re, xz_ok_flag); + return draw_eq_immediate(exp, ewid, le, re, stuff_ok_flag); if ((ivl_expr_type(re) == IVL_EX_NUMBER) && (! number_is_unknown(re)) && number_is_immediate(re, 16)) - return draw_eq_immediate(exp, ewid, le, re, xz_ok_flag); + return draw_eq_immediate(exp, ewid, le, re, stuff_ok_flag); wid = ivl_expr_width(le); if (ivl_expr_width(re) > wid) wid = ivl_expr_width(re); - lv = draw_eval_expr_wid(le, wid, xz_ok_flag); - rv = draw_eval_expr_wid(re, wid, xz_ok_flag); + lv = draw_eval_expr_wid(le, wid, stuff_ok_flag&STUFF_OK_XZ); + rv = draw_eval_expr_wid(re, wid, stuff_ok_flag&STUFF_OK_XZ); switch (ivl_expr_opcode(exp)) { case 'E': /* === */ @@ -346,6 +355,10 @@ static struct vector_info draw_binary_expr_eq(ivl_expr_t exp, assert(0); } + if ((stuff_ok_flag&STUFF_OK_47) && (wid == 1)) { + return lv; + } + /* Move the result out out the 4-7 bit that the compare uses. This is because that bit may be clobbered by other expressions. */ @@ -369,7 +382,7 @@ static struct vector_info draw_binary_expr_land(ivl_expr_t exp, unsigned wid) struct vector_info rv; - lv = draw_eval_expr(le, 1); + lv = draw_eval_expr(le, STUFF_OK_XZ); if ((lv.base >= 4) && (lv.wid > 1)) { struct vector_info tmp; @@ -381,7 +394,7 @@ static struct vector_info draw_binary_expr_land(ivl_expr_t exp, unsigned wid) lv = tmp; } - rv = draw_eval_expr(re, 1); + rv = draw_eval_expr(re, STUFF_OK_XZ); if ((rv.base >= 4) && (rv.wid > 1)) { struct vector_info tmp; clr_vector(rv); @@ -441,7 +454,7 @@ static struct vector_info draw_binary_expr_lor(ivl_expr_t exp, unsigned wid) struct vector_info lv; struct vector_info rv; - lv = draw_eval_expr_wid(le, wid, 1); + lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ); /* if the left operand has width, then evaluate the single-bit logical equivilent. */ @@ -455,7 +468,7 @@ static struct vector_info draw_binary_expr_lor(ivl_expr_t exp, unsigned wid) lv = tmp; } - rv = draw_eval_expr_wid(re, wid, 1); + rv = draw_eval_expr_wid(re, wid, STUFF_OK_XZ); /* if the right operand has width, then evaluate the single-bit logical equivilent. */ @@ -511,7 +524,9 @@ static struct vector_info draw_binary_expr_lor(ivl_expr_t exp, unsigned wid) return lv; } -static struct vector_info draw_binary_expr_le(ivl_expr_t exp, unsigned wid) +static struct vector_info draw_binary_expr_le(ivl_expr_t exp, + unsigned wid, + int stuff_ok_flag) { ivl_expr_t le = ivl_expr_oper1(exp); ivl_expr_t re = ivl_expr_oper2(exp); @@ -525,8 +540,8 @@ static struct vector_info draw_binary_expr_le(ivl_expr_t exp, unsigned wid) if (ivl_expr_width(re) > owid) owid = ivl_expr_width(re); - lv = draw_eval_expr_wid(le, owid, 1); - rv = draw_eval_expr_wid(re, owid, 1); + lv = draw_eval_expr_wid(le, owid, STUFF_OK_XZ); + rv = draw_eval_expr_wid(re, owid, STUFF_OK_XZ); switch (ivl_expr_opcode(exp)) { case 'G': @@ -562,6 +577,12 @@ static struct vector_info draw_binary_expr_le(ivl_expr_t exp, unsigned wid) clr_vector(lv); clr_vector(rv); + if ((stuff_ok_flag&STUFF_OK_47) && (wid == 1)) { + lv.base = 5; + lv.wid = wid; + return lv; + } + /* Move the result out out the 4-7 bit that the compare uses. This is because that bit may be clobbered by other expressions. */ @@ -585,8 +606,8 @@ static struct vector_info draw_binary_expr_logic(ivl_expr_t exp, struct vector_info lv; struct vector_info rv; - lv = draw_eval_expr_wid(le, wid, 1); - rv = draw_eval_expr_wid(re, wid, 1); + 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 @@ -728,7 +749,7 @@ static struct vector_info draw_add_immediate(ivl_expr_t le, struct vector_info lv; unsigned long imm; - lv = draw_eval_expr_wid(le, wid, 1); + lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ); assert(lv.wid == wid); imm = get_number_immediate(re); @@ -765,7 +786,7 @@ static struct vector_info draw_sub_immediate(ivl_expr_t le, struct vector_info lv; unsigned long imm; - lv = draw_eval_expr_wid(le, wid, 1); + lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ); assert(lv.wid == wid); imm = get_number_immediate(re); @@ -783,7 +804,7 @@ static struct vector_info draw_mul_immediate(ivl_expr_t le, struct vector_info lv; unsigned long imm; - lv = draw_eval_expr_wid(le, wid, 1); + lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ); assert(lv.wid == wid); imm = get_number_immediate(re); @@ -829,8 +850,8 @@ static struct vector_info draw_binary_expr_arith(ivl_expr_t exp, unsigned wid) && number_is_immediate(re, 16)) return draw_mul_immediate(le, re, wid); - lv = draw_eval_expr_wid(le, wid, 1); - rv = draw_eval_expr_wid(re, wid, 1); + lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ); + rv = draw_eval_expr_wid(re, wid, STUFF_OK_XZ); assert(lv.wid == wid); assert(rv.wid == wid); @@ -882,7 +903,7 @@ static struct vector_info draw_binary_expr_arith(ivl_expr_t exp, unsigned wid) static struct vector_info draw_binary_expr(ivl_expr_t exp, unsigned wid, - int xz_ok_flag) + int stuff_ok_flag) { struct vector_info rv; @@ -895,14 +916,14 @@ static struct vector_info draw_binary_expr(ivl_expr_t exp, case 'e': /* == */ case 'N': /* !== */ case 'n': /* != */ - rv = draw_binary_expr_eq(exp, wid, xz_ok_flag); + rv = draw_binary_expr_eq(exp, wid, stuff_ok_flag); break; case '<': case '>': case 'L': /* <= */ case 'G': /* >= */ - rv = draw_binary_expr_le(exp, wid); + rv = draw_binary_expr_le(exp, wid, stuff_ok_flag); break; case '+': @@ -1296,7 +1317,7 @@ static struct vector_info draw_select_expr(ivl_expr_t exp, unsigned wid) /* Evaluate the bit select base expression and store the result into index register 0. */ - shiv = draw_eval_expr(shift, 1); + shiv = draw_eval_expr(shift, STUFF_OK_XZ); fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", shiv.base, shiv.wid); clr_vector(shiv); @@ -1340,7 +1361,7 @@ static struct vector_info draw_ternary_expr(ivl_expr_t exp, unsigned wid) lab_false = local_count++; lab_out = local_count++; - tmp = draw_eval_expr(cond, 1); + tmp = draw_eval_expr(cond, STUFF_OK_XZ); clr_vector(tmp); if ((tmp.base >= 4) && (tmp.wid > 1)) { @@ -1621,7 +1642,7 @@ static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid) switch (ivl_expr_opcode(exp)) { case '~': - res = draw_eval_expr_wid(sub, wid, 1); + res = draw_eval_expr_wid(sub, wid, STUFF_OK_XZ); switch (res.base) { case 0: res.base = 1; @@ -1644,7 +1665,7 @@ static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid) complement of the number. That is the 1's complement (bitwise invert) with a 1 added in. Note that the %sub subtracts -1 (1111...) to get %add of +1. */ - res = draw_eval_expr_wid(sub, wid, 1); + res = draw_eval_expr_wid(sub, wid, STUFF_OK_XZ); switch (res.base) { case 0: res.base = 0; @@ -1664,7 +1685,7 @@ static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid) break; case '!': - res = draw_eval_expr(sub, 1); + res = draw_eval_expr(sub, STUFF_OK_XZ); if (res.wid > 1) { /* a ! on a vector is implemented with a reduction nor. Generate the result into the first bit of @@ -1767,7 +1788,7 @@ static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid) } struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid, - int xz_ok_flag) + int stuff_ok_flag) { struct vector_info res; @@ -1786,7 +1807,7 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid, break; case IVL_EX_BINARY: - res = draw_binary_expr(exp, wid, xz_ok_flag); + res = draw_binary_expr(exp, wid, stuff_ok_flag); break; case IVL_EX_BITSEL: @@ -1833,13 +1854,16 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid, return res; } -struct vector_info draw_eval_expr(ivl_expr_t exp, int xz_ok_flag) +struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag) { - return draw_eval_expr_wid(exp, ivl_expr_width(exp), xz_ok_flag); + return draw_eval_expr_wid(exp, ivl_expr_width(exp), stuff_ok_flag); } /* * $Log: eval_expr.c,v $ + * Revision 1.79 2002/09/24 04:20:32 steve + * Allow results in register bits 47 in certain cases. + * * Revision 1.78 2002/09/18 04:29:55 steve * Add support for binary NOR operator. * diff --git a/tgt-vvp/vvp_priv.h b/tgt-vvp/vvp_priv.h index 2d79c8d42..4ed900e02 100644 --- a/tgt-vvp/vvp_priv.h +++ b/tgt-vvp/vvp_priv.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_priv.h,v 1.20 2002/09/13 03:12:50 steve Exp $" +#ident "$Id: vvp_priv.h,v 1.21 2002/09/24 04:20:32 steve Exp $" #endif # include "ivl_target.h" @@ -84,18 +84,27 @@ extern void draw_input_from_net(ivl_nexus_t nex); * the vector with clr_vector so that the code generator can reuse * those bits. * - * The xz_ok_flag is normally false. Set it to true if the result is - * going to be further processed so that x and z values are treated - * identically. + * The stuff_ok_flag is normally empty. Bits in the bitmask are set + * true in cases where certain special situations are allows. This + * might allow deeper expressions to make assumptions about the + * caller. + * + * STUFF_OK_XZ -- This bit is set if the code processing the result + * doesn't distinguish between x and z values. + * + * STUFF_OK_47 -- This bit is set if the node is allowed to leave a + * result in any of the 4-7 vthread bits. */ struct vector_info { unsigned short base; unsigned short wid; }; -extern struct vector_info draw_eval_expr(ivl_expr_t exp, int xz_ok_flag); +extern struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag); extern struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned w, - int xz_ok_flag); + int stuff_ok_flag); +#define STUFF_OK_XZ 0x0001 +#define STUFF_OK_47 0x0002 /* * This function draws code to evaluate the index expression exp for @@ -120,6 +129,9 @@ extern unsigned thread_count; /* * $Log: vvp_priv.h,v $ + * Revision 1.21 2002/09/24 04:20:32 steve + * Allow results in register bits 47 in certain cases. + * * Revision 1.20 2002/09/13 03:12:50 steve * Optimize ==1 when in context where x vs z doesnt matter. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 475747487..71161d443 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_process.c,v 1.68 2002/09/13 03:12:50 steve Exp $" +#ident "$Id: vvp_process.c,v 1.69 2002/09/24 04:20:32 steve Exp $" #endif # include "vvp_priv.h" @@ -651,7 +651,7 @@ static int show_stmt_condit(ivl_statement_t net, ivl_scope_t sscope) int rc = 0; unsigned lab_false, lab_out; ivl_expr_t exp = ivl_stmt_cond_expr(net); - struct vector_info cond = draw_eval_expr(exp, 1); + struct vector_info cond = draw_eval_expr(exp, STUFF_OK_XZ|STUFF_OK_47); assert(cond.wid == 1); @@ -662,7 +662,8 @@ static int show_stmt_condit(ivl_statement_t net, ivl_scope_t sscope) thread_count, lab_false, cond.base); /* Done with the condition expression. */ - clr_vector(cond); + if (cond.base >= 8) + clr_vector(cond); if (ivl_stmt_cond_true(net)) rc += show_statement(ivl_stmt_cond_true(net), sscope); @@ -960,13 +961,14 @@ static int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope) /* Draw the evaluation of the condition expression, and test the result. If the expression evaluates to false, then branch to the out label. */ - cvec = draw_eval_expr(ivl_stmt_cond_expr(net), 1); + cvec = draw_eval_expr(ivl_stmt_cond_expr(net), STUFF_OK_XZ|STUFF_OK_47); if (cvec.wid > 1) cvec = reduction_or(cvec); fprintf(vvp_out, " %%jmp/0xz T_%d.%d, %u;\n", thread_count, out_label, cvec.base); - clr_vector(cvec); + if (cvec.base >= 8) + clr_vector(cvec); /* Draw the body of the loop. */ rc += show_statement(ivl_stmt_sub_stmt(net), sscope); @@ -1302,6 +1304,9 @@ int draw_func_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.69 2002/09/24 04:20:32 steve + * Allow results in register bits 47 in certain cases. + * * Revision 1.68 2002/09/13 03:12:50 steve * Optimize ==1 when in context where x vs z doesnt matter. *