📄 parse3.c
字号:
/* parse3.c 9-9-92 parser functions for instruction set 3 *//* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */#if INST == 3/* in INST == 3, the array of registers maps into the registers ax, bx, cx, dx as follows: c.re[0] = ax, c.re[1] = bx, c.re[2] = cx, c.re[3] = dx {0x00, "nop0", nop, pnop}, {0x01, "nop1", nop, pnop}, {0x02, "rollu", rollu, pnop}, {0x03, "rolld", rolld, pnop}, {0x04, "enter", enter, pnop}, {0x05, "exch", exch, pnop}, {0x06, "movdi", movdi, pmovdi}, {0x07, "movid", movid, pmovid}, {0x08, "movii", movii, pmovii}, {0x09, "push", push, ppush}, {0x0a, "pop", pop, ppop}, {0x0b, "put", put, pput}, {0x0c, "get", get, pget}, {0x0d, "inc", math, pinc}, {0x0e, "dec", math, pdec}, {0x0f, "add", math3, padd}, {0x10, "sub", math3, psub}, {0x11, "zero", movdd3, pzero}, {0x12, "shl", shl, pshl}, {0x13, "not0", not0, pnot0}, {0x14, "not", not, pnot}, {0x15, "rand", movdd3, prand}, {0x16, "ifz", ifz, pifz}, {0x17, "iffl", ifz, piffl}, {0x18, "jmp", adr, ptjmp}, {0x19, "jmpb", adr, ptjmpb}, {0x1a, "call", tcall, ptcall}, {0x1b, "adr", adr3, padr}, {0x1c, "adrb", adr3, padrb}, {0x1d, "adrf", adr3, padrf}, {0x1e, "mal", malchm, pmal}, {0x1f, "divide", divide, pdivide}*/void pnop(ce) /* do nothing */Pcells ce;{ is.iip = is.dib = 1; }/* void movdi(ce) is.dins->inst = is.sval + flaw(ce); * is.dval = address of destination instruction * is.dins = pointer to destination instruction * is.sval = value to be moved to destination instruction * is.sval2 = original value of destination instruction */void pmovdi(ce) /* soup [AX] = BX */Pcells ce;{ I32s tval; is.iip = is.dib = 1; if (is.eins->exec) return ; tval = flaw(ce); tval = ce->c.re[mo(tval,NUMREG)] + flaw(ce); is.dval = ad(tval); tval = 1 + flaw(ce); is.sval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);#if PLOIDY == 1 is.dins = &soup[is.dval];#else /* PLOIDY > 1 */ is.dins = &soup[is.dval][ce->d.tr];#endif /* PLOIDY > 1 */ is.sval2 = is.dins->inst;}/* void movid(ce) *(is.dreg) = is.sins->inst + flaw(ce); * is.sins = pointer to source instruction * is.sval = address of source instruction * is.dreg = destination register, where moved value will be placed * is.dmod = value by which to modulus destination register * is.dran = range within which to contain destination register */void pmovid(ce) /* AX = soup [BX] */Pcells ce;{ I32s tval; is.iip = is.dib = 1; if (is.eins->exec) return ; tval = flaw(ce); is.dreg = &(ce->c.re[mo(tval, NUMREG)]); tval = 1 + flaw(ce); tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce); is.sval = ad(tval);#if PLOIDY == 1 is.sins = &soup[is.sval];#else /* PLOIDY > 1 */ is.sins = &soup[is.sval][ce->d.tr];#endif /* PLOIDY > 1 */ is.dran = SoupSize;}/* void movii(ce) is.dins->inst = is.sins->inst; * is.dval = address of destination instruction * is.sval = address of source instruction * is.dins = pointer to destination instruction * is.sins = pointer to source instruction * is.dtra = track of destination instruction * is.sval2 = original value of destination instruction */void pmovii(ce) /* soup [AX] = soup [BX] */Pcells ce;{ I32s tval; is.iip = is.dib = 1; if (is.eins->exec) return ; tval = flaw(ce); tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce); is.dval = ad(tval); tval = 1 + flaw(ce); tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce); is.sval = ad(tval);#if PLOIDY == 1 is.dins = &soup[is.dval]; is.sins = &soup[is.sval];#else /* PLOIDY > 1 */ is.dins = &soup[is.dval][ce->d.tr]; is.sins = &soup[is.sval][ce->d.tr];#endif /* PLOIDY > 1 */ is.dtra = ce->d.tr; is.sval2 = is.dins->inst;#ifdef HSEX if (ce->d.x_over_addr) { if ((!ce->d.mov_daught) && (!FindMate(ce))) ce->d.x_over_addr = ce->d.mate_addr = 0; else UseMate(ce); }#endif}/* 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 ppush(ce) /* push AX onto stack */Pcells ce;{ I32s tval; is.iip = is.dib = 1; if (is.eins->exec) return ; tval = flaw(ce); is.sval = ce->c.re[mo(tval, NUMREG)];}/* 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 ppop(ce) /* pop AX off of stack */Pcells ce;{ I32s tval; is.iip = is.dib = 1; if (is.eins->exec) return ; tval = flaw(ce); is.dreg = &(ce->c.re[mo(tval, NUMREG)]); is.dran = SoupSize;}/* 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) * is.sval = value to be placed in the dest reg * * #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 pput(ce) /* write AX to output port; or if put template, put to input */Pcells ce; /* port of creature(s) with complementary get template */{ I32s a, s = 0, adre, tval; Pcells dc; I8s md; is.iip = is.dib = 1; if (is.eins->exec) return ;#ifdef ICC a = ad(ce->c.ip + 1); /* a = address of start of template */ while(1) /* find size of template, s = size */ {#if PLOIDY == 1 if(soup[ad(a + s)].inst != Nop0 && soup[ad(a + s)].inst != Nop1)#else /* PLOIDY > 1 */ if(soup[ad(a + s)][ce->d.tr].inst != Nop0 && soup[ad(a + s)][ce->d.tr].inst != Nop1)#endif /* PLOIDY > 1 */ break; s++; } tval = flaw(ce); is.sval = ce->c.re[mo(tval, NUMREG)]; if (s) { is.dreg = &is.dval3; /* dest register for address */ is.dreg2 = &BitBucket; /* dest reg for template size */ is.dreg3 = &BitBucket; /* dest reg for offset */ is.sval2 = s; is.sval3 = Put_limit; is.dval = ce->mm.p + ce->mm.s; is.dval2 = ce->mm.p - 1; is.mode = 0; is.mode2 = 1; is.mode3 = 0; is.iip = s + 1; } else { tval = 1 + flaw(ce); tval = ce->c.re[mo(tval, NUMREG)]; tval = ad(tval); if (!IsFree(tval)) WhichCell(tval, &is.dcel, &md); else is.dreg = &BitBucket; is.mode3 = 1; }#else /* ICC */ tval = flaw(ce); is.sval = ce->c.re[mo(tval, NUMREG)]; is.dreg = &ce->c.pb[ce->c.pb[PUTBUFSIZ]];#endif /* ICC */}/* void get(ce) *(is.dreg) = is.sval + flaw(ce); * 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 * * specify the values used by movdd(): * void movdd(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 pget(ce) /* read from input port into AX */Pcells ce;{ I32s a, tval; is.iip = is.dib = 1; if (is.eins->exec) return ; tval = flaw(ce); is.dreg = &(ce->c.re[mo(tval, NUMREG)]); is.sval = ce->c.gb[ce->c.gb[GETBUFSIZ]]; is.dran = SoupSize; a = ad(ce->c.ip + 1); /* a = address of start of template */ while(1) /* find size of template, s = size */ {#if PLOIDY == 1 if(soup[ad(a)].inst != Nop0 && soup[ad(a)].inst != Nop1)#else /* PLOIDY > 1 */ if(soup[ad(a)][ce->d.tr].inst != Nop0 && soup[ad(a)][ce->d.tr].inst != Nop1)#endif /* PLOIDY > 1 */ break; a++; is.iip++; }}/* 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 pinc(ce) /* AX++ */Pcells ce;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -