From a3217db7b2c8c39cad7288a29dfe932ef677dad1 Mon Sep 17 00:00:00 2001 From: steve Date: Tue, 16 Oct 2001 01:26:54 +0000 Subject: [PATCH] Add %div support (Anthony Bybell) --- vvp/codes.h | 6 +- vvp/compile.cc | 6 +- vvp/opcodes.txt | 11 ++- vvp/vthread.cc | 250 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 267 insertions(+), 6 deletions(-) diff --git a/vvp/codes.h b/vvp/codes.h index 5893a84e9..1389c1d45 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.34 2001/08/26 22:59:32 steve Exp $" +#ident "$Id: codes.h,v 1.35 2001/10/16 01:26:54 steve Exp $" #endif @@ -49,6 +49,7 @@ extern bool of_CMPZ(vthread_t thr, vvp_code_t code); extern bool of_DELAY(vthread_t thr, vvp_code_t code); extern bool of_DELAYX(vthread_t thr, vvp_code_t code); extern bool of_DISABLE(vthread_t thr, vvp_code_t code); +extern bool of_DIV(vthread_t thr, vvp_code_t code); extern bool of_END(vthread_t thr, vvp_code_t code); extern bool of_FORK(vthread_t thr, vvp_code_t code); extern bool of_INV(vthread_t thr, vvp_code_t code); @@ -140,6 +141,9 @@ extern vvp_code_t codespace_index(vvp_cpoint_t ptr); /* * $Log: codes.h,v $ + * Revision 1.35 2001/10/16 01:26:54 steve + * Add %div support (Anthony Bybell) + * * Revision 1.34 2001/08/26 22:59:32 steve * Add the assign/x0 and set/x opcodes. * diff --git a/vvp/compile.cc b/vvp/compile.cc index 8d246c4b6..f47c40d07 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.106 2001/10/14 03:41:58 steve Exp $" +#ident "$Id: compile.cc,v 1.107 2001/10/16 01:26:54 steve Exp $" #endif # include "arith.h" @@ -92,6 +92,7 @@ const static struct opcode_table_s opcode_table[] = { { "%cmp/z", of_CMPZ, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%delay", of_DELAY, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%delayx", of_DELAYX, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, + { "%div", of_DIV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%end", of_END, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%inv", of_INV, 2, {OA_BIT1, OA_BIT2, OA_NONE} }, { "%ix/add", of_IX_ADD, 2, {OA_BIT1, OA_NUMBER, OA_NONE} }, @@ -1573,6 +1574,9 @@ vvp_ipoint_t debug_lookup_functor(const char*name) /* * $Log: compile.cc,v $ + * Revision 1.107 2001/10/16 01:26:54 steve + * Add %div support (Anthony Bybell) + * * Revision 1.106 2001/10/14 03:41:58 steve * Handle mode-42 functor init. * diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index bac3fed1f..8099a3b89 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.29 2001/10/10 04:48:12 steve Exp $ + * $Id: opcodes.txt,v 1.30 2001/10/16 01:26:55 steve Exp $ */ @@ -144,6 +144,13 @@ scope. The label identifies the scope in question, and the threads are the threads that are currently within that scope. +* %div , , + +This instruction arithmetically divides the vector by the + vector, and leaves the result in the vector. IF any of +the bits in either vector are x or z, the entire result is x. + + * %fork , This instruction is similar to %jmp, except that it creates a new @@ -256,12 +263,12 @@ destination bit. This function does not do any bounds checking. * %mod , , - This instruction calculates the modulus %r of the left operand, and replaces the left operand with the result. The gives the width of the left and the right vectors, and the left vector is completely replaced with the result. + * %mov , , This instruction copies a vector from one place in register space to diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 3ce7af8a7..bda33d229 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.57 2001/10/14 17:36:19 steve Exp $" +#ident "$Id: vthread.cc,v 1.58 2001/10/16 01:26:55 steve Exp $" #endif # include "vthread.h" @@ -616,6 +616,148 @@ bool of_DISABLE(vthread_t thr, vvp_code_t cp) return true; } +bool of_DIV(vthread_t thr, vvp_code_t cp) +{ + assert(cp->bit_idx1 >= 4); + + if(cp->number <= 8*sizeof(unsigned long)) { + unsigned idx1 = cp->bit_idx1; + unsigned idx2 = cp->bit_idx2; + unsigned long lv = 0, rv = 0; + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) { + unsigned lb = thr_get_bit(thr, idx1); + unsigned rb = thr_get_bit(thr, idx2); + + if ((lb | rb) & 2) + goto x_out; + + lv |= lb << idx; + rv |= rb << idx; + + idx1 += 1; + if (idx2 >= 4) + idx2 += 1; + } + + lv /= rv; + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) { + thr_put_bit(thr, cp->bit_idx1+idx, (lv&1) ? 1 : 0); + lv >>= 1; + } + + return true; + + } else { + + int len=cp->number; + unsigned char *a, *b, *z, *t; + a = new unsigned char[len+1]; + b = new unsigned char[len+1]; + z = new unsigned char[len+1]; + t = new unsigned char[len+1]; + + unsigned char carry; + unsigned char temp; + + int mxa = -1, mxz = -1; + int i; + int current, copylen; + + unsigned idx1 = cp->bit_idx1; + unsigned idx2 = cp->bit_idx2; + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) { + unsigned lb = thr_get_bit(thr, idx1); + unsigned rb = thr_get_bit(thr, idx2); + + if ((lb | rb) & 2) { + delete []t; + delete []z; + delete []b; + delete []a; + goto x_out; + } + + z[idx]=lb; + a[idx]=1-rb; // for 2s complement add.. + + idx1 += 1; + if (idx2 >= 4) + idx2 += 1; + } + z[len]=0; + a[len]=1; + + for(i=0;i=0;i--) { + if(!a[i]) { + mxa=i; + break; + } + } + + for(i=len-1;i>=0;i--) { + if(z[i]) { + mxz=i; + break; + } + } + + if((mxa>mxz)||(mxa==-1)) { + if(mxa==-1) { + fprintf(stderr, "Division By Zero error, exiting.\n"); + exit(255); + } + + goto tally; + } + + copylen = mxa + 2; + current = mxz - mxa; + + while(current > -1) { + carry = 1; + for(i=0;i>1); + } + + if(carry) { + for(i=0;inumber ; idx += 1) { + // n.b., z[] has the remainder... + thr_put_bit(thr, cp->bit_idx1+idx, b[idx]); + } + + delete []t; + delete []z; + delete []b; + delete []a; + return true; + } + + x_out: + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) + thr_put_bit(thr, cp->bit_idx1+idx, 2); + + return true; +} + /* * This terminates the current thread. If there is a parent who is * waiting for me to die, then I schedule it. At any rate, I mark @@ -859,8 +1001,8 @@ bool of_LOAD_X(vthread_t thr, vvp_code_t cp) bool of_MOD(vthread_t thr, vvp_code_t cp) { assert(cp->bit_idx1 >= 4); - assert(cp->number <= 8*sizeof(unsigned long)); +if(cp->number <= 8*sizeof(unsigned long)) { unsigned idx1 = cp->bit_idx1; unsigned idx2 = cp->bit_idx2; unsigned long lv = 0, rv = 0; @@ -889,6 +1031,107 @@ bool of_MOD(vthread_t thr, vvp_code_t cp) return true; +} else { + + int len=cp->number; + unsigned char *a, *z, *t; + a = new unsigned char[len+1]; + z = new unsigned char[len+1]; + t = new unsigned char[len+1]; + + unsigned char carry; + unsigned char temp; + + int mxa = -1, mxz = -1; + int i; + int current, copylen; + + unsigned idx1 = cp->bit_idx1; + unsigned idx2 = cp->bit_idx2; + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) { + unsigned lb = thr_get_bit(thr, idx1); + unsigned rb = thr_get_bit(thr, idx2); + + if ((lb | rb) & 2) { + delete []t; + delete []z; + delete []a; + goto x_out; + } + + z[idx]=lb; + a[idx]=1-rb; // for 2s complement add.. + + idx1 += 1; + if (idx2 >= 4) + idx2 += 1; + } + z[len]=0; + a[len]=1; + + for(i=len-1;i>=0;i--) + { + if(!a[i]) + { + mxa=i; break; + } + } + + for(i=len-1;i>=0;i--) + { + if(z[i]) + { + mxz=i; break; + } + } + + if((mxa>mxz)||(mxa==-1)) + { + if(mxa==-1) + { + fprintf(stderr, "Division By Zero error, exiting.\n"); + exit(255); + } + + goto tally; + } + + copylen = mxa + 2; + current = mxz - mxa; + + while(current > -1) + { + carry = 1; + for(i=0;i>1); + } + + if(carry) + { + for(i=0;inumber ; idx += 1) { + thr_put_bit(thr, cp->bit_idx1+idx, z[idx]); + } + + delete []t; + delete []z; + delete []a; + return true; +} + x_out: for (unsigned idx = 0 ; idx < cp->number ; idx += 1) thr_put_bit(thr, cp->bit_idx1+idx, 2); @@ -1416,6 +1659,9 @@ bool of_ZOMBIE(vthread_t thr, vvp_code_t) /* * $Log: vthread.cc,v $ + * Revision 1.58 2001/10/16 01:26:55 steve + * Add %div support (Anthony Bybell) + * * Revision 1.57 2001/10/14 17:36:19 steve * Forgot to propagate carry. *