Add %div support (Anthony Bybell)

This commit is contained in:
steve 2001-10-16 01:26:54 +00:00
parent 42dab181cd
commit a3217db7b2
4 changed files with 267 additions and 6 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #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_DELAY(vthread_t thr, vvp_code_t code);
extern bool of_DELAYX(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_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_END(vthread_t thr, vvp_code_t code);
extern bool of_FORK(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); 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 $ * $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 * Revision 1.34 2001/08/26 22:59:32 steve
* Add the assign/x0 and set/x opcodes. * Add the assign/x0 and set/x opcodes.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "arith.h" # 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} }, { "%cmp/z", of_CMPZ, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%delay", of_DELAY, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%delay", of_DELAY, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%delayx", of_DELAYX, 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} }, { "%end", of_END, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%inv", of_INV, 2, {OA_BIT1, OA_BIT2, OA_NONE} }, { "%inv", of_INV, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%ix/add", of_IX_ADD, 2, {OA_BIT1, OA_NUMBER, 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 $ * $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 * Revision 1.106 2001/10/14 03:41:58 steve
* Handle mode-42 functor init. * Handle mode-42 functor init.
* *

View File

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com) * 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. the threads that are currently within that scope.
* %div <bit-l>, <bit-r>, <wid>
This instruction arithmetically divides the <bit-l> vector by the
<bit-r> vector, and leaves the result in the <bit-l> vector. IF any of
the bits in either vector are x or z, the entire result is x.
* %fork <code-label>, <scope-label> * %fork <code-label>, <scope-label>
This instruction is similar to %jmp, except that it creates a new 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 <bit-l>, <bit-r>, <wid> * %mod <bit-l>, <bit-r>, <wid>
This instruction calculates the modulus %r of the left operand, and This instruction calculates the modulus %r of the left operand, and
replaces the left operand with the result. The <wid> gives the width replaces the left operand with the result. The <wid> gives the width
of the left and the right vectors, and the left vector is completely of the left and the right vectors, and the left vector is completely
replaced with the result. replaced with the result.
* %mov <dst>, <src>, <wid> * %mov <dst>, <src>, <wid>
This instruction copies a vector from one place in register space to This instruction copies a vector from one place in register space to

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "vthread.h" # include "vthread.h"
@ -616,6 +616,148 @@ bool of_DISABLE(vthread_t thr, vvp_code_t cp)
return true; 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<len+1;i++) {
b[i]=0;
}
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<copylen;i++) {
temp = z[i+current] + a[i] + carry;
t[i] = (temp&1);
carry = (temp>>1);
}
if(carry) {
for(i=0;i<copylen;i++) {
z[i+current] = t[i];
}
b[current] = 1;
}
current--;
}
tally:
for (unsigned idx = 0 ; idx < cp->number ; 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 * 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 * 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) bool of_MOD(vthread_t thr, vvp_code_t cp)
{ {
assert(cp->bit_idx1 >= 4); 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 idx1 = cp->bit_idx1;
unsigned idx2 = cp->bit_idx2; unsigned idx2 = cp->bit_idx2;
unsigned long lv = 0, rv = 0; unsigned long lv = 0, rv = 0;
@ -889,6 +1031,107 @@ bool of_MOD(vthread_t thr, vvp_code_t cp)
return true; 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<copylen;i++)
{
temp = z[i+current] + a[i] + carry;
t[i] = (temp&1);
carry = (temp>>1);
}
if(carry)
{
for(i=0;i<copylen;i++)
{
z[i+current] = t[i];
}
}
current--;
}
tally:
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
thr_put_bit(thr, cp->bit_idx1+idx, z[idx]);
}
delete []t;
delete []z;
delete []a;
return true;
}
x_out: x_out:
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
thr_put_bit(thr, cp->bit_idx1+idx, 2); 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 $ * $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 * Revision 1.57 2001/10/14 17:36:19 steve
* Forgot to propagate carry. * Forgot to propagate carry.
* *