home *** CD-ROM | disk | FTP | other *** search
- /* instruct.c 28-10-91 instruction set for the Tierra simulator */
- /** Tierra Simulator V3.0: Copyright (c) 1991 Thomas S. Ray **/
-
- #include "license.h"
-
- #ifndef lint
- static char sccsid[] = "@(#)instruct.c 1.22 9/19/91";
- #endif
-
- #include "tierra.h"
- #include "extern.h"
-
- void nop(ci)
- I32s ci;
- { (cells + ci)->c.fl = 0; }
-
- void or1(ci) /* flip low order bit of destination register */
- I32s ci;
- { Pcells ce = cells + ci;
-
- *(is.dreg) ^= (1 + flaw(ci));
- 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) = is.dval;
- is.dran = 0;
- SetFlag(ce); return ;
- }
- ce->c.fl = 0;
- }
-
- void shl(ci)
- I32s ci;
- { Pcells ce = cells + ci;
-
- *(is.dreg) <<= (1 + flaw(ci));
- 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) = is.dval;
- is.dran = 0;
- SetFlag(ce); return ;
- }
- ce->c.fl = 0;
- }
-
- void if_cz(ci) /* execute next instruction only if cx == 0 */
- I32s ci;
- { Pcells ce = cells + ci;
-
- if(is.sval + flaw(ci))
- is.iip = 2;
- ce->c.fl = 0;
- }
-
- void math(ci)
- I32s ci;
- { Pcells ce = cells + ci;
-
- *(is.dreg) = is.sval + is.sval2 + flaw(ci);
- 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) = is.dval;
- is.dran = 0;
- SetFlag(ce); return ;
- }
- ce->c.fl = 0;
- }
-
- void push(ci)
- I32s ci;
- { Pcells ce = cells + ci;
-
- ce->c.sp = ++ce->c.sp % STACK_SIZE;
- ce->c.st[ce->c.sp] = is.sval; ce->c.fl = 0;
- }
-
- void pop(ci)
- I32s ci;
- { Pcells ce = cells + ci;
-
- if(is.dran && (ce->c.st[ce->c.sp] > is.dran ||
- ce->c.st[ce->c.sp] < -is.dran))
- { is.dran = 0;
- SetFlag(ce); return ;
- }
- *(is.dreg) = ce->c.st[ce->c.sp];
- 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;
- }
- ce->c.fl = 0;
- }
-
- void tcall(ci) /* call template */
- I32s ci;
- { push(ci);
- adr(ci);
- }
-
- void call(ci) /* call address */
- I32s ci;
- { push(ci);
- movdd(ci);
- }
-
- void mov(ci)
- I32s ci;
- { switch(is.mode)
- { case 0: movdd(ci); break; /* direct destination, direct source */
- case 1: movdi(ci); break; /* direct destination, indirect source */
- case 2: movid(ci); break; /* indirect destination, direct source */
- case 3: movii(ci); break; /* indirect destination, indirect source */
- }
- }
-
- void movdd(ci)
- I32s ci;
- { Pcells ce = (cells + ci);
-
- *(is.dreg) = is.sval + flaw(ci);
- 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) = is.dval;
- is.dran = 0;
- SetFlag(ce); return ;
- }
- ce->c.fl = 0;
- }
-
- void movdi(ci)
- I32s ci;
- { Pcells ce = (cells + ci);
-
- if((IsInsideCell(ce,is.sval) || !is.sins->read) &&
- (0 <= is.sval && is.sval < SoupSize))
- { *(is.dreg) = is.sins->inst + flaw(ci);
- ce->c.fl = 0;
- }
- else { SetFlag(ce); return ; }
- 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) = is.dval;
- is.dran = 0;
- SetFlag(ce); return ;
- }
- }
-
- void movid(ci)
- I32s ci;
- { Pcells ce = (cells + ci);
-
- if((IsInsideCell(ce,is.dval) || !is.dins->write) &&
- (0 <= is.dval && is.dval < SoupSize))
- { is.dins->inst = is.sval + flaw(ci);
- ce->c.fl = 0;
- }
- else SetFlag(ce);
- }
-
- void movii(ci)
- I32s ci;
- { Pcells ce = (cells + ci), ct;
- Pgl tgl, ogl;
- I32s ti;
- I32u who;
-
- if ((!is.dins->write || IsInsideCell(ce,is.dval)) &&
- (!is.sins->read || IsInsideCell(ce,is.sval)) &&
- (0 <= is.dval && is.dval < SoupSize) &&
- (0 <= is.sval && is.sval < SoupSize))
- { if(is.dval >= ce->md.p && is.dval <= ce->md.p + ce->md.s)
- ce->d.mov_daught++;
- is.dins->inst = is.sins->inst;
- if(RateMovMut && ++CountMovMut >= RateMovMut)
- { mut_site(soup + ad(is.dval), is.dtra);
- CountMovMut = tlrand() % RateMovMut;
- TotMovMut++;
- }
- ce->c.fl = 0;
- if(WatchMov)
- GenExMov(ci, is.dval, is.sval);
- }
- else SetFlag(ce);
- }
-
- void adr(ci) /* is.dreg = address of instruction after target template */
- I32s ci; /* is.dreg2 = template size */
- /* is.sval2 = size of template */
- /* is.dval = start address for forward search */
- /* is.dval2 = start address for backward search */
- /* is.mode = search direction: 0 out, 1 forward, 2 backward */
- /* is.mode2 = match style: 0 = complement, 1 = direct */
- { Pcells ce = cells + ci;
- Ind adrt;
-
- if(!is.sval2) { SetFlag(ce); return ; } /* source template missing */
- if(!is.mode) /* outward search */
- adrt = template(is.dval,is.dval2,is.sval2,'o',is.mode2,ci);
- if(is.mode == 1) /* forward search */
- adrt = template(is.dval,is.dval2,is.sval2,'f',is.mode2,ci);
- if(is.mode == 2) /* backward search */
- adrt = template(is.dval,is.dval2,is.sval2,'b',is.mode2,ci);
- if(adrt < 0) /* target template not found */
- { is.iip = is.sval2 + 1; /* skip ip over source template */
- SetFlag(ce); return ;
- }
- *(is.dreg) = adrt;
- *(is.dreg2) = is.sval2;
- 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) = is.dval;
- is.dran = 0;
- SetFlag(ce); return ;
- }
- if(is.dmod2)
- { *(is.dreg2) = mo(*(is.dreg2),is.dmod2);
- is.dmod2 = 0;
- }
- else if(is.dran2 && (*(is.dreg2) > is.dran2 || *(is.dreg2) < -is.dran2))
- { *(is.dreg2) = is.dval2;
- is.dran2 = 0;
- SetFlag(ce); return ;
- }
- ce->c.fl = 0; return ;
- }
-
- void mal(ci) /* allocate space for a new cell */
- I32s ci;
- { Pcells ce = cells + ci;
- Ind p;
- I32s size, osize;
-
- if(is.sval <= 0 || is.sval == ce->md.s || is.sval > MaxMalMult*ce->mm.s)
- { ce->c.fl = 1; return ; }
- is.sval2 = size = (I32s) is.sval + flaw(ci);
- if(!size) return ;
- if(ce->md.s)
- {
- #ifdef ERROR
- if(ce->md.p < 0 || ce->md.p >= SoupSize)
- { sprintf(mes[0],"Tierra mal() error 1");
- if (!hangup)
- FEMessage(1);
- else
- { sprintf(mes[1],"system being saved to disk");
- FEMessage(2);
- }
- while(hangup) ;
- WriteSoup(1);
- exit(0);
- }
- #endif
- MemDealloc(ce->md.p,ce->md.s);
- ce->d.mov_daught = 0;
- ce->md.s = 0;
- }
- osize = size;
- p = MemAlloc(&size);
- while(!size && osize < 3 * AverageSize)
- { reaper(1);
- size = osize;
- p = MemAlloc(&size);
- }
- #ifdef ERROR
- if(p < 0 || p >= SoupSize)
- { sprintf(mes[0],"Tierra mal error 2");
- if (!hangup)
- FEMessage(1);
- else
- { sprintf(mes[1],"system being saved to disk");
- FEMessage(2);
- }
- while(hangup) ;
- WriteSoup(1);
- exit(0);
- }
- #endif
- if(!size) { ce->c.fl = 1; return ; }
- *(is.dreg) = ce->md.p = ad(p); ce->md.s = size; ce->c.fl = 0;
- DownReperIf(ci);
- }
-
- void chmode(ci)
- I32s ci;
- /* is.sval = location of chmoded block */
- /* is.sval2 = size of chmoded block */
- /* is.dtra = track being chmoded */
- /* is.mode = chmod mode, unix notation, e.g. 7 = full protection */
- /* 1 bit = execute, 2 bit = write, 4 bit = read */
- /* only owner of memory has chmod privelages */
- { Pcells ce = cells + ci;
- Ind a = 0, t;
- I8s exec, write, read;
-
- exec = IsBit(is.mode,0); write = IsBit(is.mode,1); read =IsBit(is.mode,2);
- while(a < is.sval2)
- { t = ad(is.sval + a);
- if(IsInsideCell(ce, t))
- { soup[t][is.dtra].exec = exec;
- soup[t][is.dtra].write = write;
- soup[t][is.dtra].read = read;
- }
- else SetFlag(ce);
- a++;
- }
- ce->c.fl = 0;
- }
-
- void malchm(ci)
- I32s ci;
- { /* is.sval = requested size of block, is.sval2 = flawed size of block */
- /* is.dreg = location of block */
- mal(ci);
- is.sval = *(is.dreg);
- /* is.sval = location of chmoded block */
- /* is.sval2 = size of chmoded block */
- /* is.dtra = track being chmoded */
- /* is.mode = chmod mode, unix notation, e.g. 7 = full protection */
- chmode(ci);
- }
-
- void divide(ci)
- I32s ci;
- { Pcells ce = (cells+ci);
- Pcells nc; /* pointer to the new cell */
- I32s ni = 2;
-
- if (ce->md.s < MinCellSize || ce->d.mov_daught < (I32s) (ce->md.s *
- MovPropThrDiv) || !ce->d.mov_daught)
- { ce->c.fl = 1; return;}
- if (DivSameSiz)
- { if (ce->mm.s != ce->md.s)
- { ce->c.fl = 1; return; }
- if (DivSameGen &&
- !IsSameGen(ce->mm.s, soup + ce->md.p, soup + ce->mm.p))
- { ce->c.fl = 1; return; }
- }
- switch(is.mode)
- { case 0: /* create cpu */
- { if(ce->d.ni < 0) /* if there is no cpu (first call to div 0) */
- { if(++NumCells > CellsSize - 2)
- { CheckCells();
- ce = cells + ci;
- }
- while((cells + ni)->ld) /* find unoccupied cell struct */
- { ni++;
- #ifdef ERROR
- if(ni >= CellsSize)
- { sprintf(mes[0],"Tierra DIV error A0, exiting");
- if (!hangup)
- FEMessage(1);
- else
- { sprintf(mes[1],"system being saved to disk");
- FEMessage(2);
- }
- while(hangup) ;
- WriteSoup(1);
- exit(0);
- }
- #endif
- }
- nc = cells + ni;
- InitCell(ni);
- nc->ld = 1;
- nc->mm = ce->md;
- nc->c.ip = nc->mm.p;
- nc->d.dm = 1;
- ce->d.ni = ni;
- }
- else /* if there is a cpu (second call to div 0) */
- { ni = ce->d.ni;
- nc = cells + ni;
- if(nc->d.is) /* call to div 0 after call to div 1 */
- { RmvFrmSlicer(ni);
- nc->d.is = 0;
- }
- else /* two sequential calls to div 0, error */
- { ce->c.fl = 1; return; }
- }
- break;
- }
- case 1: /* start cpu */
- { if(ce->d.ni < 0) /* if there is no cpu, div 1 before div 0 */
- { if(++NumCells > CellsSize - 2)
- { CheckCells();
- ce = cells + ci;
- }
- while((cells + ni)->ld) /* find unoccupied cell struct */
- { ni++;
- #ifdef ERROR
- if(ni >= CellsSize)
- { sprintf(mes[0],"Tierra DIV error B0, exiting");
- if (!hangup)
- FEMessage(1);
- else
- { sprintf(mes[1],"system being saved to disk");
- FEMessage(2);
- }
- while(hangup) ;
- WriteSoup(1);
- exit(0);
- }
- #endif
- }
- nc = cells + ni;
- InitCell(ni);
- nc->ld = 1;
- nc->mm = ce->md;
- nc->c.ip = nc->mm.p;
- nc->d.dm = 1;
- ce->d.ni = ni;
- }
- else /* if there is already a cpu, make pointers to it */
- { ni = ce->d.ni;
- nc = cells + ni;
- }
- if(nc->d.is) /* 2nd call to div 1, cpu is already started */
- { RmvFrmSlicer(ni);
- nc->d.is = 0;
- }
- else /* not 2nd call to div 1, cpu is not already started */
- { EntBotSlicer(ni);
- nc->d.is = 1;
- }
- break;
- }
- case 2: /* split */
- { if(ce->d.ni < 0) /* if there is no cpu, div 2 before div 0 */
- { if(++NumCells > CellsSize - 2)
- { CheckCells();
- ce = cells + ci;
- }
- while((cells + ni)->ld) /* find unoccupied cell struct */
- { ni++;
- #ifdef ERROR
- if(ni >= CellsSize)
- { sprintf(mes[0],"Tierra DIV error C0, exiting");
- if (!hangup)
- FEMessage(1);
- else
- { sprintf(mes[1],"system being saved to disk");
- FEMessage(2);
- }
- while(hangup) ;
- WriteSoup(1);
- exit(0);
- }
- #endif
- }
- nc = cells + ni;
- InitCell(ni);
- nc->ld = 1;
- nc->mm = ce->md;
- nc->c.ip = nc->mm.p;
- }
- else
- { ni = ce->d.ni;
- nc = cells + ni;
- }
- if(!nc->d.is) /* no slicer, div CX before div BX */
- { EntBotSlicer(ni);
- nc->d.is = 1;
- }
- ce->md.s = ce->md.p = 0;
- ce->d.ni = -1; /* clean up if AX or BX before CX */
- nc->d.dm = 0;
- EntBotReaper(ni);
- DownReperIf(ci);
- DivideBookeep(ci, ni);
- }
- }
- ce->c.fl = 0;
- }
-
- void CheckCells() /* check and adjust memory allocation if necessary */
- { I32s j, oCellsSize = CellsSize;
- I8s buf[80];
-
- sprintf(mes[0],"in_div CheckCells: realloc, NumCells = %ld", NumCells);
- sprintf(buf," old CellsSize = %ld ", CellsSize);
- CellsSize = (I32s) CellsSize * 1.6;
- if(NumCells > CellsSize - 2) CellsSize += 12;
- cells = (Pcells) threalloc((I8s Hp) cells,
- (I32u) CellsSize * (I32u) sizeof(struct cell));
- if(cells == NULL)
- { sprintf(mes[0],"Tierra instructions realloc error, exiting");
- if (!hangup)
- FEMessage(1);
- else
- { sprintf(mes[1],"system being saved to disk");
- FEMessage(2);
- }
- while(hangup) ;
- WriteSoup(1);
- exit(0);
- }
- sprintf(mes[1],"%s new CellsSize = %ld", buf, CellsSize);
- FEMessage(2);
- #ifdef __TURBOC__
- sprintf(mes[0],"coreleft = %lu divide (cells)", coreleft());
- FEMessage(1);
- #endif
- for(j = oCellsSize; j < CellsSize; j++)
- InitCell(j);
- }
-
- I32s flaw(ci)
- I32s ci;
- { CountFlaw++;
- if(RateFlaw && CountFlaw >= RateFlaw)
- { CountFlaw = tlrand() % RateFlaw;
- TotFlaw++;
- (cells + ci)->d.flaw++;
- if(tcrand() % 2) return 1;
- return -1;
- }
- return 0;
- }
-
- Ind template(f, b, tz, dir, mode, ci) /*search in specified direction for */
- /* nop template return address, returns address of instruction following */
- /* target template, i.e., target + tz */
- /* NOTE: ce->c.ip must point to the instruction (agent) being executed */
- Ind f; /* starting address for forward search */
- Ind b; /* starting address for backward search */
- I32s tz; /* template size */
- I8s dir; /* direction of search, f = forward, b = backward, o = out */
- I8s mode; /* match mode: 0 = complement, 1 = direct */
- I32s ci; /* which cell */
- { Ind o, l = 1, adrt;
- I32s i = 0, match;
- I8s df, db;
- Pgl tgl;
- Pcells ce = cells + ci;
-
- if((tz < MinTemplSize) || (tz > SoupSize))
- { adrt = -1;
- goto finish;
- }
- if(dir == 'o') df = db = 1; /* both directions */
- if(dir == 'f') { df = 1; db = 0; } /* forward only */
- if(dir == 'b') { df = 0; db = 1; } /* backwards only */
- o = ad(ce->c.ip + 1);
- while(1)
- { while(1)/*this skips sections of codes that are not templates (NOPs)*/
- { /* forward */
- if(df && (soup[f][ce->c.tr].inst == 0
- || soup[f][ce->c.tr].inst == 1)) break;
- else { f++; f = ad(f); }
- /* backward */
- if(db && (soup[b][ce->c.tr].inst == 0
- || soup[b][ce->c.tr].inst == 1)) break;
- else { b--; b = ad(b); }
- }
- match = 1; /* forward */
- if(df && (soup[f][ce->c.tr].inst == 0
- || soup[f][ce->c.tr].inst == 1)) /* if NOPs */
- { if(!mode) /* compliment match mode */
- { for(i = 0; i < tz; i++) /* over the full template size */
- { if(soup[ad(o + i)][ce->c.tr].inst
- + soup[ad(f + i)][ce->c.tr].inst != 1)
- { match = 0; break; }
- }
- }
- else /* direct match mode */
- { for(i = 0; i < tz; i++) /* over the full template size */
- { if(soup[ad(o + i)][ce->c.tr].inst
- - soup[ad(f + i)][ce->c.tr].inst != 0)
- { match = 0; break; }
- }
- }
- if(match)
- { f += flaw(ci);
- adrt = ad(f + tz);
- goto finish;
- }
- }
- match = 1; /* backward */
- if(db && (soup[b][ce->c.tr].inst == 0
- || soup[b][ce->c.tr].inst == 1)) /* if NOPs */
- { if(!mode) /* compliment match mode */
- { for(i = 0; i < tz; i++) /* over the full template size */
- { if(soup[ad(o + i)][ce->c.tr].inst
- + soup[ad(b + i)][ce->c.tr].inst != 1)
- { match = 0; break; }
- }
- }
- else /* direct match mode */
- { for(i = 0; i < tz; i++) /* over the full template size */
- { if(soup[ad(o + i)][ce->c.tr].inst
- - soup[ad(b + i)][ce->c.tr].inst != 0)
- { match = 0; break; }
- }
- }
- if(match)
- { b += flaw(ci);
- adrt = ad(b + tz);
- goto finish;
- }
- } /* increment search pointers, backward and forward */
- if(db) { b--; b = ad(b); } if(df) { f++; f = ad(f); } l++;
- if(l > Search_limit) /* if we exceed the search limit abort */
- { adrt = -1;
- goto finish;
- }
- }
- finish:
- if(1 && WatchTem) tgl = (sl + ce->d.gli.si)->g + ce->d.gli.gi;
- if(1 && WatchTem && adrt >= 0 && !ce->d.flaw && !ce->d.mut &&
- ce->mm.p <= ce->c.ip && ce->c.ip < (ce->mm.p + ce->mm.s) &&
- IsBit(tgl->bits,0))
- GenExTemp(ad(adrt - tz), ci, tz);
- return adrt; /* address of instruction following target template */
- }
-
- Ind btemplate(f, b, tz, dir, mode, ci) /*search in specified direction for */
- /* binary template return address, returns address of instruction */
- /* following target template, i.e., target + tz */
- /* NOTE: ce->c.ip must point to the instruction (agent) being executed */
- Ind f; /* starting address for forward search */
- Ind b; /* starting address for backward search */
- I32s tz; /* template size */
- I8s dir; /* direction of search, f = forward, b = backward, o = out */
- I8s mode; /* match mode: 0 = complement, 1 = direct */
- I32s ci; /* which cell */
- { Ind o, l = 1, adrt;
- I32s i = 0, match;
- I8s df, db;
- Pgl tgl;
- Pcells ce = cells + ci;
-
- if((tz < MinTemplSize) || (tz > SoupSize))
- { adrt = -1;
- goto finish;
- }
- if(dir == 'o') df = db = 1; /* both directions */
- if(dir == 'f') { df = 1; db = 0; } /* forward only */
- if(dir == 'b') { df = 0; db = 1; } /* backwards only */
- o = ad(ce->c.ip + 1);
- while(1)
- { match = 1;
- if(df) /* if direction forwards */
- { if(!mode) /* compliment match mode */
- { for(i = 0; i < tz; i++) /* for full template size */
- { if((soup[ad(o + i)][ce->c.tr].inst
- ^ soup[ad(f + i)][ce->c.tr].inst) == 31)
- { match = 0; break; }
- }
- }
- else /* direct match mode */
- { for(i = 0; i < tz; i++) /* for full template size */
- { if(soup[ad(o + i)][ce->c.tr].inst
- == soup[ad(f + i)][ce->c.tr].inst)
- { match = 0; break; }
- }
- }
- if(match)
- { f += flaw(ci);
- adrt = ad(f + tz);
- goto finish;
- }
- }
- if(db) /* if direction backwards */
- { match = 1;
- if(!mode) /* compliment match mode */
- { for(i = 0; i < tz; i++) /* for full template size */
- { if((soup[ad(o + i)][ce->c.tr].inst
- ^ soup[ad(b + i)][ce->c.tr].inst) == 31)
- { match = 0; break; }
- }
- }
- else /* direct match mode */
- { for(i = 0; i < tz; i++) /* for full template size */
- { if(soup[ad(o + i)][ce->c.tr].inst
- == soup[ad(b + i)][ce->c.tr].inst)
- { match = 0; break; }
- }
- }
- if(match)
- { b += flaw(ci);
- adrt = ad(b + tz);
- goto finish;
- }
- } /* increment search pointers, backward and forward */
- if(db) { b--; b = ad(b); } if(df) { f++; f = ad(f); } l++;
- if(l > Search_limit)
- { adrt = -1;
- goto finish;
- }
- }
- finish:
- if(1 && WatchTem) tgl = (sl + ce->d.gli.si)->g + ce->d.gli.gi;
- if(1 && WatchTem && adrt >= 0 && !ce->d.flaw && !ce->d.mut &&
- ce->mm.p <= ce->c.ip && ce->c.ip < (ce->mm.p + ce->mm.s) &&
- IsBit(tgl->bits,0))
- GenExTemp(ad(adrt - tz), ci, tz);
- return adrt; /* address of instruction following target template */
- }
-