diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index ad865524c..04ec06260 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 */ #if !defined(WINNT) -#ident "$Id: eval_expr.c,v 1.59 2002/05/07 03:49:58 steve Exp $" +#ident "$Id: eval_expr.c,v 1.60 2002/05/29 16:29:34 steve Exp $" #endif # include "vvp_priv.h" @@ -539,6 +539,45 @@ static struct vector_info draw_binary_expr_lrs(ivl_expr_t exp, unsigned wid) 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 = 0; + unsigned idx; + + lv = draw_eval_expr_wid(le, wid); + assert(lv.wid == wid); + + switch (ivl_expr_type(re)) { + case IVL_EX_ULONG: + imm = ivl_expr_uvalue(re); + break; + + case IVL_EX_NUMBER: { + const char*bits = ivl_expr_bits(re); + unsigned nbits = ivl_expr_width(re); + for (idx = 0 ; idx < nbits ; idx += 1) switch (bits[idx]){ + case '0': + break; + case '1': + imm |= 1 << idx; + break; + default: + assert(0); + } + break; + } + + default: + assert(0); + } + + assert(0 == (imm & ~0xffffUL)); + fprintf(vvp_out, " %%addi %u, %lu, %u;\n", lv.base, imm, wid); + return lv; +} static struct vector_info draw_binary_expr_arith(ivl_expr_t exp, unsigned wid) { @@ -550,6 +589,14 @@ static struct vector_info draw_binary_expr_arith(ivl_expr_t exp, unsigned wid) const char*sign_string = ivl_expr_signed(exp)? "/s" : ""; + if ((ivl_expr_opcode(exp) == '+') + && (ivl_expr_type(re) == IVL_EX_ULONG)) + return draw_add_immediate(le, re, wid); + + if ((ivl_expr_opcode(exp) == '+') + && (ivl_expr_type(re) == IVL_EX_NUMBER)) + return draw_add_immediate(le, re, wid); + lv = draw_eval_expr_wid(le, wid); rv = draw_eval_expr_wid(re, wid); @@ -1512,6 +1559,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp) /* * $Log: eval_expr.c,v $ + * Revision 1.60 2002/05/29 16:29:34 steve + * Add %addi, which is faster to simulate. + * * Revision 1.59 2002/05/07 03:49:58 steve * Handle x case of unary ! properly. * diff --git a/vvp/codes.h b/vvp/codes.h index 3d0c44565..0b3838348 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: codes.h,v 1.40 2002/04/21 22:29:49 steve Exp $" +#ident "$Id: codes.h,v 1.41 2002/05/29 16:29:34 steve Exp $" #endif @@ -36,6 +36,7 @@ typedef bool (*vvp_code_fun)(vthread_t thr, vvp_code_t code); * access to the thread context. */ extern bool of_ADD(vthread_t thr, vvp_code_t code); +extern bool of_ADDI(vthread_t thr, vvp_code_t code); extern bool of_AND(vthread_t thr, vvp_code_t code); extern bool of_ANDR(vthread_t thr, vvp_code_t code); extern bool of_ASSIGN(vthread_t thr, vvp_code_t code); @@ -153,6 +154,9 @@ extern vvp_code_t codespace_index(vvp_cpoint_t ptr); /* * $Log: codes.h,v $ + * Revision 1.41 2002/05/29 16:29:34 steve + * Add %addi, which is faster to simulate. + * * Revision 1.40 2002/04/21 22:29:49 steve * Add the assign/d instruction for computed delays. * diff --git a/vvp/compile.cc b/vvp/compile.cc index 50d39cc43..794af114d 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: compile.cc,v 1.127 2002/05/10 16:00:57 steve Exp $" +#ident "$Id: compile.cc,v 1.128 2002/05/29 16:29:34 steve Exp $" #endif # include "arith.h" @@ -80,6 +80,7 @@ struct opcode_table_s { const static struct opcode_table_s opcode_table[] = { { "%add", of_ADD, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, + { "%addi", of_ADDI, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%and", of_AND, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%and/r", of_ANDR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%assign", of_ASSIGN, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, @@ -1411,6 +1412,9 @@ vvp_ipoint_t debug_lookup_functor(const char*name) /* * $Log: compile.cc,v $ + * Revision 1.128 2002/05/29 16:29:34 steve + * Add %addi, which is faster to simulate. + * * Revision 1.127 2002/05/10 16:00:57 steve * Support scope iterate over vpiNet,vpiReg/vpiMemory. * diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index a38bc79e4..d15205bbf 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1,7 +1,7 @@ /* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * - * $Id: opcodes.txt,v 1.34 2002/04/21 22:29:49 steve Exp $ + * $Id: opcodes.txt,v 1.35 2002/05/29 16:29:34 steve Exp $ */ @@ -30,6 +30,12 @@ sum. See also the %sub instruction. +* %addi , , + +This instruction adds the immediate value (no x or z bits) into the +left vector. The imm value is limited to 16 significant bits, but it +is zero extended to match any width. + * %and , , Perform the bitwise AND of the two vectors, and store the result in diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 939f84cba..eaabf343a 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vthread.cc,v 1.73 2002/05/27 00:53:10 steve Exp $" +#ident "$Id: vthread.cc,v 1.74 2002/05/29 16:29:34 steve Exp $" #endif # include "vthread.h" @@ -383,6 +383,64 @@ bool of_ADD(vthread_t thr, vvp_code_t cp) return true; } +/* + * This is %addi, add-immediate. The first value is a vector, the + * second value is the immediate value in the bin_idx[1] position. The + * immediate value can be up to 16 bits, which are then padded to the + * width of the vector with zero. + */ +bool of_ADDI(vthread_t thr, vvp_code_t cp) +{ + assert(cp->bit_idx[0] >= 4); + + unsigned word_count = (cp->number+CPU_BITS-1)/CPU_BITS; + + unsigned long*lva = vector_to_array(thr, cp->bit_idx[0], cp->number); + unsigned long*lvb; + if (lva == 0) + goto x_out; + + lvb = new unsigned long[word_count]; + + lvb[0] = cp->bit_idx[1]; + for (unsigned idx = 1 ; idx < word_count ; idx += 1) + lvb[idx] = 0; + + unsigned long carry; + carry = 0; + for (unsigned idx = 0 ; (idx*CPU_BITS) < cp->number ; idx += 1) { + + unsigned long tmp = lvb[idx] + carry; + unsigned long sum = lva[idx] + tmp; + carry = 0; + if (tmp < lvb[idx]) + carry = 1; + if (sum < tmp) + carry = 1; + if (sum < lva[idx]) + carry = 1; + lva[idx] = sum; + } + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) { + unsigned bit = lva[idx/CPU_BITS] >> (idx % CPU_BITS); + thr_put_bit(thr, cp->bit_idx[0]+idx, (bit&1) ? 1 : 0); + } + + delete[]lva; + delete[]lvb; + + return true; + + x_out: + delete[]lva; + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) + thr_put_bit(thr, cp->bit_idx[0]+idx, 2); + + return true; +} + bool of_ASSIGN(vthread_t thr, vvp_code_t cp) { unsigned char bit_val = thr_get_bit(thr, cp->bit_idx[1]); @@ -1913,6 +1971,9 @@ bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp) /* * $Log: vthread.cc,v $ + * Revision 1.74 2002/05/29 16:29:34 steve + * Add %addi, which is faster to simulate. + * * Revision 1.73 2002/05/27 00:53:10 steve * Able to disable thread self. *