home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / xplatfrm / tierra / instruct.c < prev    next >
C/C++ Source or Header  |  1992-04-26  |  23KB  |  718 lines

  1. /* instruct.c  28-10-91  instruction set for the Tierra simulator */
  2. /** Tierra Simulator V3.0: Copyright (c) 1991 Thomas S. Ray **/
  3.  
  4. #include "license.h"
  5.  
  6. #ifndef lint
  7. static char     sccsid[] = "@(#)instruct.c    1.22     9/19/91";
  8. #endif
  9.  
  10. #include "tierra.h"
  11. #include "extern.h"
  12.  
  13. void nop(ci)
  14. I32s  ci;
  15. {   (cells + ci)->c.fl = 0; }
  16.  
  17. void or1(ci) /* flip low order bit of destination register */
  18. I32s  ci;
  19. {   Pcells  ce = cells + ci;
  20.  
  21.     *(is.dreg) ^= (1 + flaw(ci));
  22.     if(is.dmod)
  23.     {   *(is.dreg) = mo(*(is.dreg),is.dmod);
  24.         is.dmod = 0;
  25.     }
  26.     else if(is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran))
  27.     {   *(is.dreg) = is.dval;
  28.         is.dran = 0;
  29.         SetFlag(ce); return ;
  30.     }
  31.     ce->c.fl = 0;
  32. }
  33.  
  34. void shl(ci)
  35. I32s  ci;
  36. {   Pcells  ce = cells + ci;
  37.  
  38.     *(is.dreg) <<= (1 + flaw(ci));
  39.     if(is.dmod)
  40.     {   *(is.dreg) = mo(*(is.dreg),is.dmod);
  41.         is.dmod = 0;
  42.     }
  43.     else if(is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran))
  44.     {   *(is.dreg) = is.dval;
  45.         is.dran = 0;
  46.         SetFlag(ce); return ;
  47.     }
  48.     ce->c.fl = 0;
  49. }
  50.  
  51. void if_cz(ci) /* execute next instruction only if cx == 0 */
  52. I32s  ci;
  53. {   Pcells  ce = cells + ci;
  54.  
  55.     if(is.sval + flaw(ci))
  56.         is.iip = 2;
  57.     ce->c.fl = 0;
  58. }
  59.  
  60. void math(ci)
  61. I32s  ci;
  62. {   Pcells  ce = cells + ci;
  63.  
  64.     *(is.dreg) = is.sval + is.sval2 + flaw(ci);
  65.     if(is.dmod)
  66.     {   *(is.dreg) = mo(*(is.dreg),is.dmod);
  67.         is.dmod = 0;
  68.     }
  69.     else if(is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran))
  70.     {   *(is.dreg) = is.dval;
  71.         is.dran = 0;
  72.         SetFlag(ce); return ;
  73.     }
  74.     ce->c.fl = 0;
  75. }
  76.  
  77. void push(ci)
  78. I32s  ci;
  79. {   Pcells  ce = cells + ci;
  80.  
  81.     ce->c.sp = ++ce->c.sp % STACK_SIZE;
  82.     ce->c.st[ce->c.sp] = is.sval; ce->c.fl = 0;
  83. }
  84.  
  85. void pop(ci)
  86. I32s  ci;
  87. {   Pcells  ce = cells + ci;
  88.  
  89.     if(is.dran && (ce->c.st[ce->c.sp] >  is.dran ||
  90.                    ce->c.st[ce->c.sp] < -is.dran))
  91.     {   is.dran = 0;
  92.         SetFlag(ce); return ;
  93.     }
  94.     *(is.dreg) = ce->c.st[ce->c.sp];
  95.     if(!ce->c.sp) ce->c.sp = STACK_SIZE - 1; /* decrement stack pointer */
  96.     else --ce->c.sp;
  97.     if(is.dmod)
  98.     {   *(is.dreg) = mo(*(is.dreg),is.dmod);
  99.         is.dmod = 0;
  100.     }
  101.     ce->c.fl = 0;
  102. }
  103.  
  104. void tcall(ci) /* call template */
  105. I32s  ci;
  106. {   push(ci);
  107.     adr(ci);
  108. }
  109.  
  110. void call(ci) /* call address */
  111. I32s  ci;
  112. {   push(ci);
  113.     movdd(ci);
  114. }
  115.  
  116. void mov(ci)
  117. I32s ci;
  118. {   switch(is.mode)
  119.     {   case 0: movdd(ci); break; /*   direct destination,   direct source */
  120.         case 1: movdi(ci); break; /*   direct destination, indirect source */
  121.         case 2: movid(ci); break; /* indirect destination,   direct source */
  122.         case 3: movii(ci); break; /* indirect destination, indirect source */
  123.     }
  124. }
  125.  
  126. void movdd(ci)
  127. I32s ci;
  128. {   Pcells  ce = (cells + ci);
  129.  
  130.     *(is.dreg) = is.sval + flaw(ci);
  131.     if(is.dmod)
  132.     {   *(is.dreg) = mo(*(is.dreg),is.dmod);
  133.         is.dmod = 0;
  134.     }
  135.     else if(is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran))
  136.     {   *(is.dreg) = is.dval;
  137.         is.dran = 0;
  138.         SetFlag(ce); return ;
  139.     }
  140.     ce->c.fl = 0; 
  141. }
  142.  
  143. void movdi(ci)
  144. I32s ci;
  145. {   Pcells  ce = (cells + ci);
  146.  
  147.     if((IsInsideCell(ce,is.sval) || !is.sins->read) &&
  148.         (0 <= is.sval && is.sval < SoupSize))
  149.     {   *(is.dreg) = is.sins->inst + flaw(ci);
  150.         ce->c.fl = 0; 
  151.     }
  152.     else { SetFlag(ce); return ; }
  153.     if(is.dmod)
  154.     {   *(is.dreg) = mo(*(is.dreg),is.dmod);
  155.         is.dmod = 0;
  156.     }
  157.     else if(is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran))
  158.     {   *(is.dreg) = is.dval;
  159.         is.dran = 0;
  160.         SetFlag(ce); return ;
  161.     }
  162. }
  163.  
  164. void movid(ci)
  165. I32s ci;
  166. {   Pcells  ce = (cells + ci);
  167.  
  168.     if((IsInsideCell(ce,is.dval) || !is.dins->write) &&
  169.         (0 <= is.dval && is.dval < SoupSize))
  170.     {   is.dins->inst = is.sval + flaw(ci);
  171.         ce->c.fl = 0;
  172.     }
  173.     else SetFlag(ce);
  174. }
  175.  
  176. void movii(ci)
  177. I32s ci;
  178. {   Pcells  ce = (cells + ci), ct;
  179.     Pgl     tgl, ogl;
  180.     I32s    ti;
  181.     I32u    who;
  182.  
  183.     if ((!is.dins->write || IsInsideCell(ce,is.dval)) &&
  184.         (!is.sins->read  || IsInsideCell(ce,is.sval)) &&
  185.         (0 <= is.dval && is.dval < SoupSize) &&
  186.         (0 <= is.sval && is.sval < SoupSize))
  187.     {   if(is.dval >= ce->md.p && is.dval <= ce->md.p + ce->md.s)
  188.             ce->d.mov_daught++;
  189.         is.dins->inst = is.sins->inst;
  190.         if(RateMovMut && ++CountMovMut >= RateMovMut)
  191.         {   mut_site(soup + ad(is.dval), is.dtra);
  192.             CountMovMut = tlrand() % RateMovMut;
  193.             TotMovMut++;
  194.         }
  195.         ce->c.fl = 0;
  196.         if(WatchMov)
  197.             GenExMov(ci, is.dval, is.sval);
  198.     }
  199.     else SetFlag(ce);
  200. }
  201.  
  202. void adr(ci) /* is.dreg  = address of instruction after target template */
  203. I32s  ci;    /* is.dreg2 = template size */
  204.              /* is.sval2 = size of template */
  205.              /* is.dval  = start address for forward search */
  206.              /* is.dval2 = start address for backward search */
  207.              /* is.mode  = search direction: 0 out, 1 forward, 2 backward */
  208.              /* is.mode2 = match style: 0 = complement, 1 = direct */
  209. {   Pcells  ce = cells + ci;
  210.     Ind     adrt;
  211.  
  212.     if(!is.sval2) { SetFlag(ce); return ; } /* source template missing */
  213.     if(!is.mode)     /* outward search */
  214.         adrt = template(is.dval,is.dval2,is.sval2,'o',is.mode2,ci); 
  215.     if(is.mode == 1) /* forward search */
  216.         adrt = template(is.dval,is.dval2,is.sval2,'f',is.mode2,ci); 
  217.     if(is.mode == 2) /* backward search */
  218.         adrt = template(is.dval,is.dval2,is.sval2,'b',is.mode2,ci); 
  219.     if(adrt < 0) /* target template not found */
  220.     {   is.iip = is.sval2 + 1; /* skip ip over source template */
  221.         SetFlag(ce); return ;
  222.     }
  223.     *(is.dreg) = adrt;
  224.     *(is.dreg2) = is.sval2;
  225.     if(is.dmod)
  226.     {   *(is.dreg) = mo(*(is.dreg),is.dmod);
  227.         is.dmod = 0;
  228.     }
  229.     else if(is.dran && (*(is.dreg) > is.dran || *(is.dreg) < -is.dran))
  230.     {   *(is.dreg) = is.dval;
  231.         is.dran = 0;
  232.         SetFlag(ce); return ;
  233.     }
  234.     if(is.dmod2)
  235.     {   *(is.dreg2) = mo(*(is.dreg2),is.dmod2);
  236.         is.dmod2 = 0;
  237.     }
  238.     else if(is.dran2 && (*(is.dreg2) > is.dran2 || *(is.dreg2) < -is.dran2))
  239.     {   *(is.dreg2) = is.dval2;
  240.         is.dran2 = 0;
  241.         SetFlag(ce); return ;
  242.     }
  243.     ce->c.fl = 0; return ;
  244. }
  245.  
  246. void mal(ci)  /* allocate space for a new cell */
  247. I32s  ci;
  248. {   Pcells  ce = cells + ci;
  249.     Ind   p;
  250.     I32s  size, osize;
  251.  
  252.     if(is.sval <= 0 || is.sval == ce->md.s || is.sval > MaxMalMult*ce->mm.s)
  253.     {   ce->c.fl = 1; return ; }
  254.     is.sval2 = size = (I32s) is.sval + flaw(ci);
  255.     if(!size) return ;
  256.     if(ce->md.s)
  257.     {
  258. #ifdef ERROR
  259.         if(ce->md.p < 0 || ce->md.p >= SoupSize)
  260.         {   sprintf(mes[0],"Tierra mal() error 1");
  261.             if (!hangup)
  262.                 FEMessage(1);
  263.             else
  264.             {   sprintf(mes[1],"system being saved to disk");
  265.                 FEMessage(2);
  266.             }
  267.             while(hangup) ;
  268.             WriteSoup(1);
  269.             exit(0);
  270.         }
  271. #endif
  272.         MemDealloc(ce->md.p,ce->md.s);
  273.         ce->d.mov_daught = 0;
  274.         ce->md.s = 0;
  275.     }
  276.     osize = size;
  277.     p = MemAlloc(&size);
  278.     while(!size && osize < 3 * AverageSize)
  279.     {   reaper(1);
  280.         size = osize;
  281.         p = MemAlloc(&size);
  282.     }
  283. #ifdef ERROR
  284.     if(p < 0 || p >= SoupSize)
  285.     {   sprintf(mes[0],"Tierra mal error 2");
  286.         if (!hangup)
  287.             FEMessage(1);
  288.         else
  289.         {   sprintf(mes[1],"system being saved to disk");
  290.             FEMessage(2);
  291.         }
  292.         while(hangup) ;
  293.         WriteSoup(1);
  294.         exit(0);
  295.     }
  296. #endif
  297.     if(!size) { ce->c.fl = 1; return ; }
  298.     *(is.dreg) = ce->md.p = ad(p); ce->md.s = size; ce->c.fl = 0;
  299.     DownReperIf(ci);
  300. }
  301.  
  302. void chmode(ci)
  303. I32s ci;
  304.     /* is.sval  = location of chmoded block */
  305.     /* is.sval2 = size of chmoded block */
  306.     /* is.dtra  = track being chmoded */
  307.     /* is.mode  = chmod mode, unix notation, e.g. 7 = full protection */
  308.     /*          1 bit = execute, 2 bit = write, 4 bit = read */
  309.     /* only owner of memory has chmod privelages */
  310. {   Pcells  ce = cells + ci;
  311.     Ind     a = 0, t;
  312.     I8s     exec, write, read;
  313.  
  314.     exec = IsBit(is.mode,0); write = IsBit(is.mode,1); read =IsBit(is.mode,2);
  315.     while(a < is.sval2)
  316.     {   t = ad(is.sval + a);
  317.         if(IsInsideCell(ce, t))
  318.         {   soup[t][is.dtra].exec  = exec;
  319.             soup[t][is.dtra].write = write;
  320.             soup[t][is.dtra].read  = read;
  321.         }
  322.         else SetFlag(ce);
  323.         a++;
  324.     }
  325.     ce->c.fl = 0;
  326. }
  327.  
  328. void malchm(ci)
  329. I32s ci;
  330. {   /* is.sval = requested size of block, is.sval2 = flawed size of block */
  331.     /* is.dreg = location of block */
  332.     mal(ci);
  333.     is.sval = *(is.dreg);
  334.     /* is.sval  = location of chmoded block */
  335.     /* is.sval2 = size of chmoded block */
  336.     /* is.dtra  = track being chmoded */
  337.     /* is.mode  = chmod mode, unix notation, e.g. 7 = full protection */
  338.     chmode(ci);
  339. }
  340.  
  341. void divide(ci)
  342. I32s ci;
  343. {   Pcells ce = (cells+ci);
  344.     Pcells  nc;  /* pointer to the new cell */
  345.     I32s ni = 2;
  346.  
  347.     if (ce->md.s < MinCellSize || ce->d.mov_daught < (I32s) (ce->md.s *
  348.         MovPropThrDiv) || !ce->d.mov_daught)
  349.     {   ce->c.fl = 1; return;}
  350.     if (DivSameSiz)
  351.     {   if (ce->mm.s != ce->md.s)
  352.            { ce->c.fl = 1; return; }
  353.         if (DivSameGen &&
  354.            !IsSameGen(ce->mm.s, soup + ce->md.p, soup + ce->mm.p))
  355.            { ce->c.fl = 1; return; }
  356.     }
  357.     switch(is.mode)
  358.     {   case 0: /* create cpu */
  359.         {   if(ce->d.ni < 0) /* if there is no cpu (first call to div 0) */
  360.             {   if(++NumCells > CellsSize - 2)
  361.                 {   CheckCells();
  362.                     ce = cells + ci;
  363.                 }
  364.                 while((cells + ni)->ld) /* find unoccupied cell struct */
  365.                 {   ni++;
  366. #ifdef ERROR
  367.                     if(ni >= CellsSize)
  368.                     {   sprintf(mes[0],"Tierra DIV error A0, exiting");
  369.                         if (!hangup)
  370.                             FEMessage(1);
  371.                         else
  372.                         {   sprintf(mes[1],"system being saved to disk");
  373.                             FEMessage(2);
  374.                         }
  375.                         while(hangup) ;
  376.                         WriteSoup(1);
  377.                         exit(0);
  378.                     }
  379. #endif
  380.                 }
  381.                 nc = cells + ni;
  382.                 InitCell(ni);
  383.                 nc->ld = 1;
  384.                 nc->mm = ce->md;
  385.                 nc->c.ip = nc->mm.p;
  386.                 nc->d.dm = 1;
  387.                 ce->d.ni = ni;
  388.             }
  389.             else /* if there is a cpu (second call to div 0) */
  390.             {   ni = ce->d.ni;
  391.                 nc = cells + ni;
  392.                 if(nc->d.is) /* call to div 0 after call to div 1 */
  393.                 {   RmvFrmSlicer(ni);
  394.                     nc->d.is = 0;
  395.                 }
  396.                 else /* two sequential calls to div 0, error */
  397.         {   ce->c.fl = 1; return; }
  398.             }
  399.             break;
  400.         }
  401.         case 1: /* start cpu */
  402.         {   if(ce->d.ni < 0) /* if there is no cpu, div 1 before div 0 */
  403.             {   if(++NumCells > CellsSize - 2)
  404.                 {   CheckCells();
  405.                     ce = cells + ci;
  406.                 }
  407.                 while((cells + ni)->ld) /* find unoccupied cell struct */
  408.                 {   ni++;
  409. #ifdef ERROR
  410.                     if(ni >= CellsSize)
  411.                     {   sprintf(mes[0],"Tierra DIV error B0, exiting");
  412.                         if (!hangup)
  413.                             FEMessage(1);
  414.                         else
  415.                         {   sprintf(mes[1],"system being saved to disk");
  416.                             FEMessage(2);
  417.                         }
  418.                         while(hangup) ;
  419.                         WriteSoup(1);
  420.                         exit(0);
  421.                     }
  422. #endif
  423.                 }
  424.                 nc = cells + ni;
  425.                 InitCell(ni);
  426.                 nc->ld = 1;
  427.                 nc->mm = ce->md;
  428.                 nc->c.ip = nc->mm.p;
  429.                 nc->d.dm = 1;
  430.                 ce->d.ni = ni;
  431.             }
  432.             else /* if there is already a cpu, make pointers to it */
  433.             {   ni = ce->d.ni;
  434.                 nc = cells + ni;
  435.             }
  436.             if(nc->d.is) /* 2nd call to div 1, cpu is already started */
  437.             {   RmvFrmSlicer(ni);
  438.                 nc->d.is = 0;
  439.             }
  440.             else /* not 2nd call to div 1, cpu is not already started */
  441.             {   EntBotSlicer(ni);
  442.                 nc->d.is = 1;
  443.             }
  444.             break;
  445.         }
  446.         case 2: /* split */
  447.         {   if(ce->d.ni < 0) /* if there is no cpu, div 2 before div 0 */
  448.             {   if(++NumCells > CellsSize - 2)
  449.                 {   CheckCells();
  450.                     ce = cells + ci;
  451.                 }
  452.                 while((cells + ni)->ld) /* find unoccupied cell struct */
  453.                 {   ni++;
  454. #ifdef ERROR
  455.                     if(ni >= CellsSize)
  456.                     {   sprintf(mes[0],"Tierra DIV error C0, exiting");
  457.                         if (!hangup)
  458.                             FEMessage(1);
  459.                         else
  460.                         {   sprintf(mes[1],"system being saved to disk");
  461.                             FEMessage(2);
  462.                         }
  463.                         while(hangup) ;
  464.                         WriteSoup(1);
  465.                         exit(0);
  466.                     }
  467. #endif
  468.                 }
  469.                 nc = cells + ni;
  470.                 InitCell(ni);
  471.                 nc->ld = 1;
  472.                 nc->mm = ce->md;
  473.                 nc->c.ip = nc->mm.p;
  474.             }
  475.             else
  476.             {   ni = ce->d.ni;
  477.                 nc = cells + ni;
  478.             }
  479.             if(!nc->d.is) /* no slicer, div CX before div BX */
  480.             {   EntBotSlicer(ni);
  481.                 nc->d.is = 1;
  482.             }
  483.             ce->md.s = ce->md.p = 0;
  484.             ce->d.ni = -1; /* clean up if AX or BX before CX */
  485.             nc->d.dm = 0;
  486.             EntBotReaper(ni);
  487.             DownReperIf(ci);
  488.             DivideBookeep(ci, ni);
  489.         }
  490.     }
  491.     ce->c.fl = 0; 
  492. }
  493.  
  494. void CheckCells() /* check and adjust memory allocation if necessary */
  495. {   I32s   j, oCellsSize = CellsSize;
  496.     I8s    buf[80];
  497.  
  498.     sprintf(mes[0],"in_div CheckCells: realloc, NumCells = %ld", NumCells);
  499.     sprintf(buf,"    old CellsSize = %ld  ", CellsSize);
  500.     CellsSize = (I32s) CellsSize * 1.6;
  501.     if(NumCells > CellsSize - 2) CellsSize += 12;
  502.     cells = (Pcells) threalloc((I8s Hp) cells,
  503.             (I32u) CellsSize * (I32u) sizeof(struct cell));
  504.     if(cells == NULL)
  505.     {   sprintf(mes[0],"Tierra instructions realloc error, exiting");
  506.         if (!hangup)
  507.             FEMessage(1);
  508.         else
  509.         {   sprintf(mes[1],"system being saved to disk");
  510.             FEMessage(2);
  511.         }
  512.         while(hangup) ;
  513.         WriteSoup(1);
  514.         exit(0);
  515.     }
  516.     sprintf(mes[1],"%s new CellsSize = %ld", buf, CellsSize);
  517.     FEMessage(2);
  518. #ifdef __TURBOC__
  519.     sprintf(mes[0],"coreleft = %lu  divide (cells)", coreleft());
  520.     FEMessage(1);
  521. #endif
  522.     for(j = oCellsSize; j < CellsSize; j++)
  523.         InitCell(j);
  524. }
  525.  
  526. I32s flaw(ci)
  527. I32s  ci;
  528. {   CountFlaw++;
  529.     if(RateFlaw && CountFlaw >= RateFlaw)
  530.     {   CountFlaw = tlrand() % RateFlaw;
  531.         TotFlaw++;
  532.         (cells + ci)->d.flaw++;
  533.         if(tcrand() % 2) return 1;
  534.         return -1;
  535.     }
  536.     return 0;
  537. }
  538.  
  539. Ind template(f, b, tz, dir, mode, ci) /*search in specified direction for */
  540.   /* nop template return address, returns address of instruction following */
  541.   /* target template, i.e., target + tz */
  542.   /* NOTE: ce->c.ip must point to the instruction (agent) being executed */
  543. Ind   f;    /* starting address for forward search */
  544. Ind   b;    /* starting address for backward search */
  545. I32s  tz;   /* template size */
  546. I8s   dir;  /* direction of search, f = forward, b = backward, o = out */
  547. I8s   mode; /* match mode: 0 = complement, 1 = direct */
  548. I32s  ci;   /* which cell */
  549. {   Ind   o, l = 1, adrt;
  550.     I32s  i = 0, match;
  551.     I8s   df, db;
  552.     Pgl   tgl;
  553.     Pcells  ce = cells + ci;
  554.  
  555.     if((tz < MinTemplSize) || (tz > SoupSize))
  556.     {   adrt = -1;
  557.         goto finish;
  558.     }
  559.     if(dir == 'o') df = db = 1;        /* both directions */
  560.     if(dir == 'f') { df = 1; db = 0; } /* forward only */
  561.     if(dir == 'b') { df = 0; db = 1; } /* backwards only */
  562.     o = ad(ce->c.ip + 1);
  563.     while(1)
  564.     {   while(1)/*this skips sections of codes that are not templates (NOPs)*/
  565.         {   /* forward */
  566.         if(df && (soup[f][ce->c.tr].inst == 0 
  567.             || soup[f][ce->c.tr].inst == 1)) break;
  568.             else { f++; f = ad(f); }
  569.         /* backward */
  570.             if(db && (soup[b][ce->c.tr].inst == 0 
  571.             || soup[b][ce->c.tr].inst == 1)) break;
  572.             else { b--; b = ad(b); }
  573.         }
  574.         match = 1; /* forward */
  575.         if(df && (soup[f][ce->c.tr].inst == 0 
  576.         || soup[f][ce->c.tr].inst == 1)) /* if NOPs */
  577.         {   if(!mode) /* compliment match mode */
  578.         {   for(i = 0; i < tz; i++) /* over the full template size */
  579.                 {   if(soup[ad(o + i)][ce->c.tr].inst 
  580.                 + soup[ad(f + i)][ce->c.tr].inst != 1)
  581.                     { match = 0; break; }
  582.                 }
  583.             }
  584.         else /* direct match mode */
  585.         {   for(i = 0; i < tz; i++) /* over the full template size */
  586.                 {   if(soup[ad(o + i)][ce->c.tr].inst 
  587.                 - soup[ad(f + i)][ce->c.tr].inst != 0)
  588.                     { match = 0; break; }
  589.                 }
  590.             }
  591.             if(match)
  592.             {   f += flaw(ci);
  593.                 adrt = ad(f + tz);
  594.                 goto finish;
  595.             }
  596.         }
  597.         match = 1; /* backward */
  598.         if(db && (soup[b][ce->c.tr].inst == 0 
  599.         || soup[b][ce->c.tr].inst == 1)) /* if NOPs */
  600.         {   if(!mode) /* compliment match mode */
  601.         {   for(i = 0; i < tz; i++) /* over the full template size */
  602.                 {   if(soup[ad(o + i)][ce->c.tr].inst 
  603.                 + soup[ad(b + i)][ce->c.tr].inst != 1)
  604.                     { match = 0; break; }
  605.                 }
  606.         }
  607.         else /* direct match mode */
  608.         {   for(i = 0; i < tz; i++) /* over the full template size */
  609.                 {   if(soup[ad(o + i)][ce->c.tr].inst 
  610.                 - soup[ad(b + i)][ce->c.tr].inst != 0)
  611.                     { match = 0; break; }
  612.                 }
  613.             }
  614.             if(match)
  615.             {   b += flaw(ci);
  616.                 adrt = ad(b + tz);
  617.                 goto finish;
  618.             }
  619.         }      /* increment search pointers, backward and forward */
  620.         if(db) { b--; b = ad(b); } if(df) { f++; f = ad(f); } l++;
  621.         if(l > Search_limit) /* if we exceed the search limit abort */
  622.         {   adrt = -1;
  623.             goto finish;
  624.         }
  625.     }
  626.     finish:
  627.     if(1 && WatchTem) tgl = (sl + ce->d.gli.si)->g + ce->d.gli.gi;
  628.     if(1 && WatchTem && adrt >= 0 && !ce->d.flaw && !ce->d.mut &&
  629.         ce->mm.p <= ce->c.ip && ce->c.ip < (ce->mm.p + ce->mm.s) &&
  630.         IsBit(tgl->bits,0))
  631.         GenExTemp(ad(adrt - tz), ci, tz);
  632.     return adrt; /* address of instruction following target template */
  633. }
  634.  
  635. Ind btemplate(f, b, tz, dir, mode, ci) /*search in specified direction for */
  636.     /* binary template return address, returns address of instruction */
  637.     /* following target template, i.e., target + tz */
  638.     /* NOTE: ce->c.ip must point to the instruction (agent) being executed */
  639. Ind   f;    /* starting address for forward search */
  640. Ind   b;    /* starting address for backward search */
  641. I32s  tz;   /* template size */
  642. I8s   dir;  /* direction of search, f = forward, b = backward, o = out */
  643. I8s   mode; /* match mode: 0 = complement, 1 = direct */
  644. I32s  ci;   /* which cell */
  645. {   Ind   o, l = 1, adrt;
  646.     I32s  i = 0, match;
  647.     I8s   df, db;
  648.     Pgl   tgl;
  649.     Pcells  ce = cells + ci;
  650.  
  651.     if((tz < MinTemplSize) || (tz > SoupSize))
  652.     {   adrt = -1;
  653.         goto finish;
  654.     }
  655.     if(dir == 'o') df = db = 1;        /* both directions */
  656.     if(dir == 'f') { df = 1; db = 0; } /* forward only */
  657.     if(dir == 'b') { df = 0; db = 1; } /* backwards only */
  658.     o = ad(ce->c.ip + 1);
  659.     while(1)
  660.     {   match = 1;
  661.         if(df) /* if direction forwards */
  662.         {   if(!mode) /* compliment match mode */
  663.             {   for(i = 0; i < tz; i++) /* for full template size */
  664.                 {   if((soup[ad(o + i)][ce->c.tr].inst 
  665.                         ^ soup[ad(f + i)][ce->c.tr].inst) == 31)
  666.                     { match = 0; break; }
  667.                 }
  668.             }
  669.             else /* direct match mode */
  670.             {   for(i = 0; i < tz; i++) /* for full template size */
  671.                 {   if(soup[ad(o + i)][ce->c.tr].inst 
  672.                         == soup[ad(f + i)][ce->c.tr].inst)
  673.                     { match = 0; break; }
  674.                 }
  675.             }
  676.             if(match)
  677.             {   f += flaw(ci);
  678.                 adrt = ad(f + tz);
  679.                 goto finish;
  680.             }
  681.         }
  682.         if(db) /* if direction backwards */
  683.         {   match = 1;
  684.             if(!mode) /* compliment match mode */
  685.             {   for(i = 0; i < tz; i++) /* for full template size */
  686.                 {   if((soup[ad(o + i)][ce->c.tr].inst 
  687.                         ^ soup[ad(b + i)][ce->c.tr].inst) == 31)
  688.                     { match = 0; break; }
  689.                 }
  690.             }
  691.             else /* direct match mode */
  692.             {   for(i = 0; i < tz; i++) /* for full template size */
  693.                 {   if(soup[ad(o + i)][ce->c.tr].inst 
  694.                         == soup[ad(b + i)][ce->c.tr].inst)
  695.                     { match = 0; break; }
  696.                 }
  697.             }
  698.             if(match)
  699.             {   b += flaw(ci);
  700.                 adrt = ad(b + tz);
  701.                 goto finish;
  702.             }
  703.         }      /* increment search pointers, backward and forward */
  704.         if(db) { b--; b = ad(b); } if(df) { f++; f = ad(f); } l++;
  705.         if(l > Search_limit)
  706.         {   adrt = -1;
  707.             goto finish;
  708.         }
  709.     }
  710.     finish:
  711.     if(1 && WatchTem) tgl = (sl + ce->d.gli.si)->g + ce->d.gli.gi;
  712.     if(1 && WatchTem && adrt >= 0 && !ce->d.flaw && !ce->d.mut &&
  713.         ce->mm.p <= ce->c.ip && ce->c.ip < (ce->mm.p + ce->mm.s) &&
  714.         IsBit(tgl->bits,0))
  715.         GenExTemp(ad(adrt - tz), ci, tz);
  716.     return adrt; /* address of instruction following target template */
  717. }
  718.