diff --git a/vvp/codes.h b/vvp/codes.h index 92898ab57..b94d82d4b 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.42 2002/05/31 04:09:58 steve Exp $" +#ident "$Id: codes.h,v 1.43 2002/05/31 20:04:22 steve Exp $" #endif @@ -75,6 +75,7 @@ extern bool of_LOAD_X(vthread_t thr, vvp_code_t code); extern bool of_MOD(vthread_t thr, vvp_code_t code); extern bool of_MOV(vthread_t thr, vvp_code_t code); extern bool of_MUL(vthread_t thr, vvp_code_t code); +extern bool of_MULI(vthread_t thr, vvp_code_t code); extern bool of_NANDR(vthread_t thr, vvp_code_t code); extern bool of_NOOP(vthread_t thr, vvp_code_t code); extern bool of_NORR(vthread_t thr, vvp_code_t code); @@ -154,6 +155,9 @@ extern vvp_code_t codespace_index(vvp_cpoint_t ptr); /* * $Log: codes.h,v $ + * Revision 1.43 2002/05/31 20:04:22 steve + * Add the %muli instruction. + * * Revision 1.42 2002/05/31 04:09:58 steve * Slight improvement in %mov performance. * diff --git a/vvp/compile.cc b/vvp/compile.cc index 794af114d..e1f21dbc5 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.128 2002/05/29 16:29:34 steve Exp $" +#ident "$Id: compile.cc,v 1.129 2002/05/31 20:04:22 steve Exp $" #endif # include "arith.h" @@ -117,6 +117,7 @@ const static struct opcode_table_s opcode_table[] = { { "%mod", of_MOD, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%mov", of_MOV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%mul", of_MUL, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, + { "%muli", of_MULI, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%nand/r", of_NANDR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%noop", of_NOOP, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%nor/r", of_NORR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, @@ -1412,6 +1413,9 @@ vvp_ipoint_t debug_lookup_functor(const char*name) /* * $Log: compile.cc,v $ + * Revision 1.129 2002/05/31 20:04:22 steve + * Add the %muli instruction. + * * Revision 1.128 2002/05/29 16:29:34 steve * Add %addi, which is faster to simulate. * diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index d15205bbf..15004c7f8 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.35 2002/05/29 16:29:34 steve Exp $ + * $Id: opcodes.txt,v 1.36 2002/05/31 20:04:22 steve Exp $ */ @@ -323,6 +323,12 @@ are x or z, the result is x. Otherwise, the result is the arithmetic product. +* %muli , , + +This instruction is the same as %mul, but the second operand is an +immediate value that is padded to the width of the result. + + * %nor/r , , The %nor/r instruction is a reduction nor. That is, the is a diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 2fbbb8440..d07e61c3d 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.76 2002/05/31 04:09:58 steve Exp $" +#ident "$Id: vthread.cc,v 1.77 2002/05/31 20:04:22 steve Exp $" #endif # include "vthread.h" @@ -1613,6 +1613,106 @@ bool of_MUL(vthread_t thr, vvp_code_t cp) return true; } +bool of_MULI(vthread_t thr, vvp_code_t cp) +{ + assert(cp->bit_idx[0] >= 4); + + /* If the value fits into a native unsigned long, then make an + unsigned long variable with the numbers, to a native + multiply, and work with that. */ + + if(cp->number <= 8*sizeof(unsigned long)) { + unsigned idx1 = cp->bit_idx[0]; + unsigned long lv = 0, rv = cp->bit_idx[1]; + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) { + unsigned lb = thr_get_bit(thr, idx1); + + if (lb & 2) + goto x_out; + + lv |= lb << idx; + + idx1 += 1; + } + + lv *= rv; + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) { + thr_put_bit(thr, cp->bit_idx[0]+idx, (lv&1) ? 1 : 0); + lv >>= 1; + } + + return true; + } + + /* number is too large for local long, so do bitwise + multiply. */ + + unsigned idx1; idx1 = cp->bit_idx[0]; + unsigned imm; imm = cp->bit_idx[1]; + + unsigned char *a, *b, *sum; + a = new unsigned char[cp->number]; + b = new unsigned char[cp->number]; + sum = new unsigned char[cp->number]; + + int mxa; mxa = -1; + int mxb; mxb = -1; + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) { + unsigned lb = thr_get_bit(thr, idx1); + unsigned rb = imm & 1; + + imm >>= 1; + + if (lb & 2) { + delete[]sum; + delete[]b; + delete[]a; + goto x_out; + } + + if((a[idx] = lb)) mxa=idx+1; + if((b[idx] = rb)) mxb=idx; + sum[idx]=0; + + idx1 += 1; + } + +// do "unsigned ZZ sum = a * b" the hard way.. + for(int i=0;i<=mxb;i++) { + if(b[i]) { + unsigned char carry=0; + unsigned char temp; + + for(int j=0;j<=mxa;j++) { + if(i+j>=(int)cp->number) break; + temp=sum[i+j]+a[j]+carry; + sum[i+j]=(temp&1); + carry=(temp>>1); + } + } + } + + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) { + thr_put_bit(thr, cp->bit_idx[0]+idx, sum[idx]); + } + + delete[]sum; + delete[]b; + delete[]a; + + return true; + + x_out: + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) + thr_put_bit(thr, cp->bit_idx[0]+idx, 2); + + return true; +} + bool of_NOOP(vthread_t thr, vvp_code_t cp) { return true; @@ -2065,6 +2165,9 @@ bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp) /* * $Log: vthread.cc,v $ + * Revision 1.77 2002/05/31 20:04:22 steve + * Add the %muli instruction. + * * Revision 1.76 2002/05/31 04:09:58 steve * Slight improvement in %mov performance. *