|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T i ┃
Length: 6270 (0x187e) Types: TextFile Names: »instructions.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/asm/instructions.c«
#include "asm.h" int choiceinstr (ins) int ins; { choicedef *chpt; int num, i, fits; Long value; static char *opdpt; if (label && *label) insert (label, (long) lc, &o_none, curseg, NO); chpt = (choicedef *)optab[ins].class; num = chpt->field; for (opdpt = opd; num > 1; num --) { opdpt = index (opdpt, ','); if (opdpt == NULL) { reporterr (E_NOPS); return (0); } opdpt++; } value = expr (&opdpt, &i, YES); fits = i ? NO : (value >= chpt->lorange && value <= chpt->hirange && curseg == exprseg); if ((i = opsrch ((fits ? chpt->rname : chpt->nname), optab, instrlen)) >= 0) { (optab[i].action) (i); } else { reporterr (E_ILLOP); } return (0); } int geninstr (ins) int ins; { static Acc cons = ~0L; int nargs, length, i, j, k; opdclass *oclass; insclass *iclass; Word itemtemp, obuf[MAXBYTPERINS]; Acc mask; char *nextopd; itemu item; if (label && *label) insert (label, (long) lc, &o_none, curseg, NO); iclass = optab[ins].class; length = iclass->length; if (pass == 2) { nargs = iclass->mopds; for (i = 0; i < MAXBYTPERINS; i++) obuf[i] = 0; item.l = optab[ins].mask; for (i = 0; i < MINBYTES; i++) obuf[i] = item.s[i]; item.l = 0L; nextopd = opd; for (j = 0; j < nargs; j++) { if (j != 0) { if (*nextopd != ',') { reporterr (E_NOPS); } else { nextopd++; } } oclass = iclass->type[j]; item.l = expr (&nextopd, &ignerr, NO) + oclass->offset - (oclass->relative ? lc : 0); mask = cons >> (LONGLEN - oclass->length); if (item.l < 0L && !oclass->signed) reporterr (E_NEG); if (((item.ls < 0L && oclass->signed) ? -item.ls : item.ls) & ~mask) reporterr (E_TOOBIG); item.l &= mask; if (oclass->byteswapped) { itemtemp = item.s[BYTPERLONG - 2]; item.s[BYTPERLONG - 2] = item.s[BYTPERLONG - 1]; item.s[BYTPERLONG - 1] = itemtemp; } i = LONGLEN - 8 - iclass->offset[j]; item.l <<= (i % 8); i /= 8; k = 0; if (i < 0) k = -i, i = 0; for (; k < MAXBYTPERINS && i < BYTPERLONG; k++, i++) #ifdef NORMBYTE obuf[k] |= item.s[i]; #else obuf[k] |= item.s[BYTPERLONG-1-i]; #endif } if (optop) { optional (optop, obuf); free (optop); } putoutbin (obuf, length); listit (linecopy, lc, obuf, length); } lc += length; return (0); } long expr (string, errind, test) char **string; int *errind; int test; { long exp, val; int op, err; int uniop = 0; segmnt *seg1, *seg2; *errind = NO; if (**string == '-') uniop = 1; else if (**string == '~') uniop = 2; if (uniop) (*string)++; exp = getval(string, &err, test, &seg1); if (err) goto errorexit; if (uniop == 2) exp = ~exp; else if (uniop == 1) exp = -exp; while (!isdelim(**string)) { if ((op = getop (string)) == NOOP) { if (!test) reporterr (E_EXPR); errorexit: for (; !isdelim (**string); *string++) ; *errind = YES; return (0); } val = getval (string, &err, test, &seg2); if (err) goto errorexit; if (seg1 && seg2 && seg1 != seg2 && pass == 1) reporterr (E_SEG); switch (op) { case PLUS: exp += val; break; case MINUS: exp -= val; break; case MULT: exp *= val; break; case DIV: exp /= val; break; case MOD: exp %= val; break; case OR: exp |= val; break; case AND: exp &= val; break; case EXOR: exp ^= val; break; case SHLF: exp <<= val; break; case SHRT: exp >>= val; break; default: if (!test) reporterr (E_EXPR); } seg1 = seg2; } exprseg = seg1; return (exp); } /* Snag literals and variable names. The literal classes are: [digit]....[digit] unsigned decimal number 0[hexdigit]...[hexdigit]unsigned hexadecimal number $ current location counter '[char] single character, right just, zero fill "[char][char] character pair Returns a 16 bit value. Unary operations taken care of in expr; byte swapping done if required by geninstr. */ long getval (strpt, errorret, test, segment) segmnt **segment; char **strpt; int *errorret; int test; { long total; char name[33], *npt; int i; *segment = (segmnt *) 0; *errorret = 0; total = 0L; if (isdigit (**strpt)) { if (**strpt == '0') { while (isxdigit (**strpt)) { total *= 16; total += xtod (**strpt); (*strpt)++; } } else { while (isdigit (**strpt)) { total *= 10; total += (Long)(**strpt - '0'); (*strpt)++; } } } else if (islabel (**strpt)) { npt = name; while (islabel (**strpt)) { *npt++ = **strpt; (*strpt)++; } *npt = '\0'; if ((i = lookup (name)) == -1) { if (pass == 2) if (!test) reporterr (E_UNDEF); *errorret = 1; total = 0L; } else { total = symtab[i].value; if (pass == 2 && symtab[i].segp) total += (symtab[i].segp)->start; *segment = symtab[i].segp; } } else if (**strpt == '\'') { (*strpt)++; if (**strpt == '\\') { (*strpt)++; total = escape (strpt); } else { total = **strpt; (*strpt)++; } } else if (**strpt == '"') { (*strpt)++; if (**strpt == '\\') { (*strpt)++; total = escape (strpt); } else { total = **strpt; (*strpt)++; } total <<= 8; if (**strpt == '\\') { (*strpt)++; total |= escape (strpt); } else { total |= **strpt; (*strpt)++; } } else if (**strpt == '$') { total = lc; *segment = curseg; (*strpt)++; } else { if (!test) reporterr (E_EXPR); *errorret = 1; } return (total); } char escape (st) char **st; { switch (*((*st)++)) { case 'b': return ('\b'); case 'n': return ('\n'); case 'r': return ('\r'); case '^': return ('\033'); case 'f': return ('\f'); case 't': return ('\t'); case '?': return ('\177'); case '\\': return ('\\'); default: (*st)--; if (isxdigit (**st) && isxdigit (*(*st + 1))) { *st += 2; return (xtod (*(*st - 2)) << 4 | xtod (*(*st - 1))); } else { return (*(*st++)); } } } int xtod (c) char c; { return ((int) c - (c > '9' ? (c > 'F' ? 'W' : '7') : '0')); } int getop (string) char **string; { static char ops[] = OPSTRING; char *k; for (k = ops; *k; k++) if (*k == **string) { (*string)++; return ((int) (k - ops)); } (*string)++; return (NOOP); }