📄 instruct.c
字号:
/* instruct.c 9-9-92 instruction set for the Tierra Simulator *//* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */#ifndef lintstatic char sccsid[] = "@(#)instruct.c 1.22 9/19/91";#endif#include "license.h"#include "tierra.h"#include "extern.h"#ifdef ALCOMM#include "tmonitor.h"#include "trequest.h"#endif /* ALCOMM */#ifdef MEM_CHK#include <memcheck.h>#endif /* MEM_CHK *//* takes no arguments, returns no values (except clears flag) */void nop(ce) /* no operation */Pcells ce;{ ce->c.fl = 0; }#if INST == 2/* void regorder(ce) adjust register order * is.sval = the number of the register that will go to the top */void regorder(ce) /* adjust register order */Pcells ce;{ pushst(ce); is.sval += flaw(ce); ce->c.re[NUMREG] = mo(is.sval, NUMREG); ce->c.fl = 0;}void pushst(ce) /* called by regorder() */Pcells ce;{ I16s i; for (i = (2 * NUMREG) - 1; i > NUMREG; i--) ce->c.re[i] = ce->c.re[i - 1];/* ce->c.re[7] = ce->c.re[6]; ce->c.re[6] = ce->c.re[5]; ce->c.re[5] = ce->c.re[4];*/}#endif /* INST == 2 */#if INST == 3/* takes no arguments, returns no values (except clears flag) */void rollu(ce)Pcells ce;{ I32s tvar; I16s i; tvar = ce->c.re[i = NUMREG - 1] + flaw(ce); for (; i > 0; i--) ce->c.re[i] = ce->c.re[i - 1] + flaw(ce); ce->c.re[0] = tvar; ce->c.fl = 0;}/* takes no arguments, returns no values (except clears flag) */void rolld(ce)Pcells ce;{ I32s tvar; I16s i; tvar = ce->c.re[0] + flaw(ce); for (i = 0; i < NUMREG - 1; i++) ce->c.re[i] = ce->c.re[i + 1] + flaw(ce); ce->c.re[NUMREG - 1] = tvar; ce->c.fl = 0;}/* takes no arguments, returns no values (except clears flag) */void enter(ce)Pcells ce;{ I32s tvar; I16s i; for (i = NUMREG - 1; i > 0; i--) ce->c.re[i] = ce->c.re[i - 1] + flaw(ce); ce->c.re[0] += flaw(ce); ce->c.fl = 0;}/* takes no arguments, returns no values (except clears flag) */void exch(ce)Pcells ce;{ I32s tvar; tvar = ce->c.re[0] + flaw(ce); ce->c.re[0] = ce->c.re[1] + flaw(ce); ce->c.re[1] = tvar; ce->c.fl = 0;}/* void math3(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce); * is.dreg = destination register, where calculation will be stored * is.sval = a value that will be added to is.sval2 and placed in dest reg * is.sval2 = a value that will be added to is.sval and placed in dest reg * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register */void math3(ce) /* add two numbers and store them in a register, shift down */Pcells ce;{ I16s i; math(ce); for (i = 1; i < NUMREG - 1; i++) ce->c.re[i] = ce->c.re[i + 1] + flaw(ce);}void pop3(ce)Pcells ce;{ I16s i; for (i = NUMREG - 1; i > 0; i--) ce->c.re[i] = ce->c.re[i - 1] + flaw(ce); pop(ce);}/* void movdd3(ce) *(is.dreg) = is.sval + flaw(ce); * is.dreg = destination register, where moved value will be placed * is.sval = value to be placed in the dest reg * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register */void movdd3(ce) /* inter-register mov, and push up stack */Pcells ce;{ I16s i; for (i = NUMREG - 1; i > 0; i--) ce->c.re[i] = ce->c.re[i - 1] + flaw(ce); movdd(ce);}void adr3(ce) /* find address of a template */Pcells ce;{ I32s tval; if (!is.sval2) { *(is.dreg) = is.sval; /* source template missing *//* SetFlag(ce); */ return; } tval = 3 + flaw(ce); ce->c.re[mo(tval, NUMREG)] = ce->c.re[0] + flaw(ce); adr(ce);}void malchm3(ce)Pcells ce;{ I16s i; for (i = NUMREG - 1; i > 0; i--) ce->c.re[i] = ce->c.re[i - 1] + flaw(ce); malchm(ce);}#endif /* INST == 3 */#if INST != 1/* void not(ce) *(is.dreg) = ~(is.sval) + flaw(ce); * is.dreg = destination register * is.sval = value whose bits will be flipped and put in dest reg * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register */void not(ce) /* flip all bits of destination register */Pcells ce;{ *(is.dreg) = ~(is.sval) + flaw(ce); if (is.dmod) { *(is.dreg) = mo(*(is.dreg), is.dmod); is.dmod = 0; } else if (is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran)) { *(is.dreg) = 0; is.dran = 0; } ce->c.fl = 0;}/* void put(ce) write a value to the output buffer * ce->c.pb[PUTBUFSIZ] == pointer to next output value to be written * ce->c.pb[PUTBUFSIZ + 1] == pointer to next output value to be read * ce->c.pb[PUTBUFSIZ + 2] == number of unread output values * * is.dcel = destination cell, in whose buffer the value will be put * is.dreg = destination "register" in the put buffer * is.dval3 = destination for address returned by adr() * is.mode3 = #ifdef ICC: 0 = broadcast to other cells' get buffer * 1 = write to other cell's get buffer * #ifndef ICC: write to own put buffer (prayer) * * #ifndef ICC specify the values used by movdd(): * is.dreg = destination register, where moved value will be placed * is.sval = value to be placed in the dest reg * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register * * #ifdef ICC specify the values used by adr(): * void adr(ce) find address of a template * is.mode = search mode: 1 = forward, 2 = backward, 0 = outward * is.mode2 = preference: 1 = forward, 2 = backward, and return for * direction found: 1 = forward, 2 = backward, 3 = both, 0 = none * is.dval = starting address for forward search * is.dval2 = starting address for backward search * is.dreg = destination register where target address will be stored * is.dreg2 = destination register where template size will be stored * is.dreg3 = destination register where offset of target will be stored * is.sval = return address if template size = 0 * is.sval2 = template size, 0 = no template * is.sval3 = search limit, and return for distance actually searched * is.dmod = modulus value for is.dreg * is.dmod2 = modulus value for is.dreg2 * is.dmod3 = modulus value for is.dreg3 * is.dran = range to maintain for is.dreg * is.dran2 = range to maintain for is.dreg2 * is.dran3 = range to maintain for is.dreg3 */void put(ce) /* write a value to the output buffer */Pcells ce;{ Pcells dc = is.dcel; I32s ta, lpl = Put_limit; I8s tmode2 = is.mode2, md; if (is.dreg == &BitBucket) { SetFlag(ce); return; }#ifdef ICC if (is.mode3) /* write to other cell's get buffer */ Write2Get(dc, is.sval); else { adr(ce); if (!ce->c.fl) do /* broadcast to other cells' get buffer */ { if (is.mode2 == 1 || is.mode2 == 3) { ta = is.dval - 1; if (is.dcel = FindPutCell(ad(ta))) { Write2Get(is.dcel, is.sval); } } if (is.mode2 == 2 || is.mode2 == 3) { ta = is.dval2 - 1; if (is.dcel = FindPutCell(ad(ta))) { Write2Get(is.dcel, is.sval); } } is.mode2 = tmode2; lpl -= is.sval3; is.sval3 = lpl; is.dval++; is.dval2--; adr(ce); } while (!ce->c.fl); }#else /* ICC */ /* write to own put buffer */ movdd(ce); ce->c.pb[PUTBUFSIZ] = ++(ce->c.pb[PUTBUFSIZ]) % PUTBUFSIZ; ce->c.pb[PUTBUFSIZ + 2] = 1 + ((++(ce->c.pb[PUTBUFSIZ + 2]) - 1) % PUTBUFSIZ);#endif /* ICC */ ce->c.fl = 0;}Pcells FindPutCell(adre)I32s adre;{ Pcells ce; I8s md;#if PLOIDY == 1 if(strcmp(id[soup[adre].inst].mn, "get")#else /* PLOIDY > 1 */ if(strcmp(id[soup[adre][ce->d.tr].inst].mn, "get")#endif /* PLOIDY > 1 */ || adre < 0 || adre >= SoupSize || IsFree(adre)) ce = NULL; else { WhichCell(adre, &ce, &md);/* if (md == 'd') ce = NULL;*/ } return ce;}I8s ReadFPut(ce, value) /* for god to read the data in the output buffer */Pcells ce;I32s *value;{ if (ce->c.pb[PUTBUFSIZ + 2]) { *value = ce->c.pb[ce->c.pb[PUTBUFSIZ + 1]]; --(ce->c.pb[PUTBUFSIZ + 2]); ce->c.pb[PUTBUFSIZ + 1] = ++(ce->c.pb[PUTBUFSIZ + 1]) % PUTBUFSIZ; return 1; } return 0;}/* void get(ce) read a value from the input buffer * ce->c.gb[GETBUFSIZ] == pointer to next input value to be read * ce->c.gb[GETBUFSIZ + 1] == pointer to next input value to be written * ce->c.gb[GETBUFSIZ + 2] == number of unread input values * * also specify the values used by movdd(): * is.dreg = destination register, where moved value will be placed * is.sval = value to be placed in the dest reg * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register */void get(ce) /* read a value from the input buffer */Pcells ce;{ if (ce->c.gb[GETBUFSIZ + 2]) { movdd(ce); --(ce->c.gb[GETBUFSIZ + 2]); ce->c.gb[GETBUFSIZ] = ++(ce->c.gb[GETBUFSIZ]) % GETBUFSIZ; } ce->c.fl = 0;}void Write2Get(ce, value) /* place value in input buffer of cell ce */Pcells ce;I32s value;{ ce->c.gb[ce->c.gb[GETBUFSIZ + 1]] = value; ce->c.gb[GETBUFSIZ + 1] = ++(ce->c.gb[GETBUFSIZ + 1]) % GETBUFSIZ; ce->c.gb[GETBUFSIZ + 2] = 1 + ((++(ce->c.gb[GETBUFSIZ + 2]) - 1) % GETBUFSIZ);}void Broad2Get(value) /* broadcast value to input buffer of all cells */I32s value;{ Pcells ce = ThisSlice; do { Write2Get(ce, value); ce = &cells[ce->q.n_time.a][ce->q.n_time.i]; } while (ce != ThisSlice);} #endif /* INST != 1 *//* void not0(ce) *(is.dreg) ^= (1 + flaw(ce)); * is.dreg = destination register, whose bit will be flipped * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register */void not0(ce) /* flip low order bit of destination register */Pcells ce;{ *(is.dreg) ^= (1 + flaw(ce)); if (is.dmod) { *(is.dreg) = mo(*(is.dreg), is.dmod); is.dmod = 0; } else if (is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran)) { *(is.dreg) = 0; is.dran = 0; } ce->c.fl = 0;}/* void shl(ce) *(is.dreg) <<= (Reg) (1 + flaw(ce)); * is.dreg = destination register, whose bits will be shifted left * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register */void shl(ce) /* shift left all bits in register */Pcells ce;{ *(is.dreg) <<= (Reg) (1 + flaw(ce)); if (is.dmod) { *(is.dreg) = mo(*(is.dreg), is.dmod); is.dmod = 0; } else if (is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran)) { *(is.dreg) = 0; is.dran = 0; } ce->c.fl = 0;}/* void ifz(ce) if (is.sval + flaw(ce)) is.iip = is.sval2; * is.sval = value to test for zero * is.sval2 = amount to increment IP if is.sval == 0 * is.iip = amount to increment IP if is.sval != 0 */void ifz(ce) /* execute or skip next instruction, if is.sval == 0 */Pcells ce;{ if (is.sval + flaw(ce)) /* is.sval2 = 2 to skip next instruction */ is.iip = is.sval2; /* is.sval2 = 1 to execute next instruction */ ce->c.fl = 0;}/* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce); * is.dreg = destination register, where calculation will be stored * is.sval = a value that will be added to is.sval2 and placed in dest reg * is.sval2 = a value that will be added to is.sval and placed in dest reg * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register */void math(ce) /* add two numbers and store them in a register */Pcells ce;{ *(is.dreg) = is.sval + is.sval2 + flaw(ce); if (is.dmod) { *(is.dreg) = mo(*(is.dreg), is.dmod); is.dmod = 0; } else if (is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran)) { *(is.dreg) = 0; is.dran = 0; } ce->c.fl = 0;}/* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE; * ce->c.st[ce->c.sp] = is.sval + flaw(ce); * is.sval = value to be pushed onto the stack */void push(ce) /* push a value onto the stack */Pcells ce;{ ce->c.sp = ++ce->c.sp % STACK_SIZE; ce->c.st[ce->c.sp] = is.sval + flaw(ce); ce->c.fl = 0;}/* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce); * if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp; * is.dreg = destination register, where value popped off stack will go * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register */void pop(ce) /* pop a value from the stack into a register */Pcells ce;{ *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce); if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; /* decrement stack pointer */ else --ce->c.sp; if (is.dmod) { *(is.dreg) = mo(*(is.dreg), is.dmod); is.dmod = 0; } else if (is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran)) { *(is.dreg) = 0; is.dran = 0; } ce->c.fl = 0;}/* void adr(ce) find address of a template * is.mode = search mode: 1 = forward, 2 = backward, 0 = outward * is.mode2 = preference: 1 = forward, 2 = backward, and return for * direction found: 1 = forward, 2 = backward, 3 = both, 0 = none * is.dval = starting address for forward search * is.dval2 = starting address for backward search * is.dreg = destination register where target address will be stored * is.dreg2 = destination register where template size will be stored * is.dreg3 = destination register where offset of target will be stored * is.sval = return address if template size = 0 * is.sval2 = template size, 0 = no template * is.sval3 = search limit, and return for distance actually searched * is.dmod = modulus value for is.dreg * is.dmod2 = modulus value for is.dreg2 * is.dmod3 = modulus value for is.dreg3 * is.dran = range to maintain for is.dreg * is.dran2 = range to maintain for is.dreg2 * is.dran3 = range to maintain for is.dreg3 *//* void push(ce) * is.sval = value to be pushed onto the stack */void tcall(ce) /* call template */Pcells ce;{ adr(ce); push(ce);}/* specify the values used by movdd(): * is.dreg = destination register, where moved value will be placed * is.sval = value to be placed in the dest reg * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register *//* void push(ce) * is.sval = value to be pushed onto the stack */void call(ce) /* call address */Pcells ce;{ movdd(ce); push(ce);}/* void mov(ce) move some data * is.mode = form of mov to use * see specific movs below for other passed values */void mov(ce) /* move some data */Pcells ce;{ switch (is.mode) { case 0: movdd(ce); break; /* direct destination, direct source */ case 1: movdi(ce); break; /* direct destination, indirect source */ case 2: movid(ce); break; /* indirect destination, direct source */ case 3: movii(ce); break; /* indirect destination, indirect source */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -