Annotation of coherent/d/bin/as/asmexpr.c, revision 1.1

1.1     ! root        1: #include "asm.h"
        !             2: 
        !             3: expr(esp, n)
        !             4: register struct expr *esp;
        !             5: {
        !             6:        register c, p;
        !             7:        address lv, rv;
        !             8:        int lt, rt;
        !             9:        struct expr re;
        !            10: 
        !            11:        term(esp);
        !            12:        for (;;) {
        !            13:                c = getnb();
        !            14:                if (ctype[c] != BINOP)
        !            15:                        break;
        !            16:                if (c == '|')
        !            17:                        p = 10;
        !            18:                else if (c == '*')
        !            19:                        p = 9;
        !            20:                else
        !            21:                        p = 8;
        !            22:                if (p <= n)
        !            23:                        break;
        !            24:                expr(&re, p);
        !            25:                lt = esp->e_type;
        !            26:                lv = esp->e_addr;
        !            27:                rt = re.e_type;
        !            28:                rv = re.e_addr;
        !            29:                if (c == '|') {
        !            30:                        if (rt != E_ACON)
        !            31:                                aerr("non constant in segment construction");
        !            32:                        switch (lt) {
        !            33:                        case E_ACON:
        !            34:                                esp->e_type = E_ASEG;
        !            35:                                esp->e_base.e_segn = lv;
        !            36:                                break;
        !            37: 
        !            38:                        case E_SYM:
        !            39:                                esp->e_type = E_SEG;
        !            40:                                break;
        !            41: 
        !            42:                        default:
        !            43:                                aerr("bad segment construction");
        !            44:                        }
        !            45:                        esp->e_addr = rv;
        !            46:                        continue;
        !            47:                }
        !            48:                if (c == '^') {
        !            49:                        if ((esp->e_type = rt) == E_DIR)
        !            50:                                esp->e_base.e_lp = re.e_base.e_lp;
        !            51:                        else if (rt==E_SYM || rt==E_SEG)
        !            52:                                esp->e_base.e_sp = re.e_base.e_sp;
        !            53:                        else if (rt == E_ASEG)
        !            54:                                esp->e_base.e_segn = re.e_base.e_segn;
        !            55:                        continue;
        !            56:                }
        !            57:                if (c == '+') {
        !            58:                        if (lt == E_ACON) {
        !            59:                                esp->e_type = rt;
        !            60:                                if (rt == E_ASEG)
        !            61:                                        esp->e_base.e_segn = re.e_base.e_segn;
        !            62:                                else if (rt == E_DIR)
        !            63:                                        esp->e_base.e_lp = re.e_base.e_lp;
        !            64:                                else if (rt==E_SYM || rt==E_SEG)
        !            65:                                        esp->e_base.e_sp = re.e_base.e_sp;
        !            66:                        } else if (rt != E_ACON)
        !            67:                                rerr("add of 2 non constants");
        !            68:                        esp->e_addr += rv;
        !            69:                        continue;
        !            70:                }
        !            71:                if (c == '-') {
        !            72:                        if (lt == E_ACON) {
        !            73:                                if (rt != E_ACON)
        !            74:                                        rerr("constant - non-constant");
        !            75:                        } else if (rt != E_ACON) {
        !            76:                                if (lt!=E_DIR || rt!=E_DIR || 
        !            77:                                    esp->e_base.e_lp!=re.e_base.e_lp)
        !            78:                                        rerr("cannot fold this expression");
        !            79:                                esp->e_type = E_ACON;
        !            80:                        }
        !            81:                        esp->e_addr -= rv;
        !            82:                        continue;
        !            83:                }
        !            84:                if (c == '*') {
        !            85:                        if (lt!=E_ACON || rt!=E_ACON)
        !            86:                                aerr("non-constant in multiply");
        !            87:                        esp->e_addr *= rv;
        !            88:                        continue;
        !            89:                }
        !            90:                fprintf(stderr, "Internal error, c=%d in expr.\n", c);
        !            91:                exit( 1);
        !            92:        }
        !            93:        unget(c);
        !            94: }
        !            95: 
        !            96: address
        !            97: absexpr()
        !            98: {
        !            99:        struct expr e;
        !           100: 
        !           101:        expr(&e, 0);
        !           102:        abscheck(&e);
        !           103:        return (e.e_addr);
        !           104: }
        !           105: 
        !           106: term(esp)
        !           107: register struct expr *esp;
        !           108: {
        !           109:        register c;
        !           110:        address  n;
        !           111:        char id[NCPLN];
        !           112:        struct sym  *sp;
        !           113:        struct tsym *tp;
        !           114:        int r, v;
        !           115: 
        !           116:        if ((c=getnb()) == '[') {
        !           117:                expr(esp, 0);
        !           118:                if (getnb() != ']')
        !           119:                        qerr("missing ']'");
        !           120:                return;
        !           121:        }
        !           122:        if (c == '-') {
        !           123:                expr(esp, 100);
        !           124:                abscheck(esp);
        !           125:                esp->e_addr = -esp->e_addr;
        !           126:                return;
        !           127:        }
        !           128:        if (c == '~') {
        !           129:                expr(esp, 100);
        !           130:                abscheck(esp);
        !           131:                esp->e_addr = ~esp->e_addr;
        !           132:                return;
        !           133:        }
        !           134:        if (c == '\'') {
        !           135:                esp->e_type = E_ACON;
        !           136:                esp->e_addr = getmap(-1);
        !           137:                return;
        !           138:        }
        !           139:        esp->e_type = E_ACON;
        !           140:        esp->e_addr = 0;
        !           141:        if (ctype[c] == DIGIT) {
        !           142:                r = 10;
        !           143:                if (c == '0') {
        !           144:                        r = 8;
        !           145:                        if ((c = *ip) != 0)
        !           146:                                ++ip;
        !           147:                        if (c == 'x') {
        !           148:                                r = 16;
        !           149:                                if ((c = *ip) != 0)
        !           150:                                        ++ip;
        !           151:                        }
        !           152:                }
        !           153:                n = 0;
        !           154:                while ((v=digit(c, r)) >= 0) {
        !           155:                        n = r*n + v;
        !           156:                        if ((c = *ip) != 0)
        !           157:                                ++ip;
        !           158:                }
        !           159:                if (c=='f' || c=='b') {
        !           160:                        if (n < 10) {
        !           161:                                if (c == 'f')
        !           162:                                        tp = tsymp[n].tp_fp; else
        !           163:                                        tp = tsymp[n].tp_bp;
        !           164:                                if (tp != NULL) {
        !           165:                                        esp->e_type = E_DIR;
        !           166:                                        esp->e_base.e_lp = tp->t_lp;
        !           167:                                        esp->e_addr = tp->t_addr;
        !           168:                                        return;
        !           169:                                }
        !           170:                        }
        !           171:                        err('u', "undefined local symbol");
        !           172:                        return;
        !           173:                }
        !           174:                if (c != 0)
        !           175:                        --ip;
        !           176:                esp->e_addr = n;
        !           177:                return;
        !           178:        }
        !           179:        if (ctype[c] == LETTER) {
        !           180:                getid(id, c);
        !           181:                if ((sp=lookup(id, gflag)) != NULL) {
        !           182:                        if (sp->s_kind == S_NEW) {
        !           183:                                if ((sp->s_flag&S_GBL) != 0) {
        !           184:                                        esp->e_type = E_SYM;
        !           185:                                        esp->e_base.e_sp = sp;
        !           186:                                        return;
        !           187:                                }
        !           188:                                uerr(id);
        !           189:                                return;
        !           190:                        }
        !           191:                        esp->e_type = sp->s_type;
        !           192:                        esp->e_addr = sp->s_addr;
        !           193:                        if (sp->s_type == E_ASEG)
        !           194:                                esp->e_base.e_segn = sp->s_base.s_segn;
        !           195:                        else if (sp->s_type == E_DIR)
        !           196:                                esp->e_base.e_lp = sp->s_base.s_lp;
        !           197:                        else if (sp->s_type==E_SYM || sp->s_type==E_SEG)
        !           198:                                esp->e_base.e_sp = sp->s_base.s_sp;
        !           199:                        return;
        !           200:                }
        !           201:                uerr(id);
        !           202:                return;
        !           203:        }
        !           204:        qerr("invalid symbol");
        !           205: }
        !           206: 
        !           207: /*
        !           208:  * Look for an optional floating point register specification
        !           209:  * and store an appropriate e_mode value through ep.
        !           210:  * No operand: store ST and return 0.
        !           211:  * One operand: store reg and return 1.
        !           212:  */
        !           213: fp_reg(ep)
        !           214: register struct expr *ep;
        !           215: {
        !           216:        register c;
        !           217:        char id[NCPLN];
        !           218:        struct sym  *sp;
        !           219: 
        !           220:        ep->e_mode = ST;
        !           221:        if (ctype[c=getnb()] == LETTER) {
        !           222:                getid(id, c);
        !           223:                if ((sp=lookup(id, 0)) != NULL) {
        !           224:                        if ((sp->s_addr&MMASK) != ST) {
        !           225:                                qerr("invalid floating-point register");
        !           226:                                return(0);
        !           227:                        }
        !           228:                        ep->e_mode = sp->s_addr;
        !           229:                        return(1);
        !           230:                }
        !           231:                uerr(id);
        !           232:                return(0);
        !           233:        }
        !           234:        unget(c);
        !           235:        return(0);
        !           236: }
        !           237: 
        !           238: /*
        !           239:  * Look for one or two optional floating point register operands
        !           240:  * and store appropriate e_mode values through ep1, ep2.
        !           241:  * Return a flag indicating whether any operands were supplied.
        !           242:  * No operand: store ST1, ST, return 0.
        !           243:  * One operand: store reg1, ST, return 1.
        !           244:  * Two operands: store reg1, reg2, return 1; at least one must be ST.
        !           245:  */
        !           246: fp_reg2(ep1, ep2)
        !           247: register struct expr *ep1, *ep2;
        !           248: {
        !           249:        register int c;
        !           250: 
        !           251:        ep2->e_mode = ST;
        !           252:        if (fp_reg(ep1)) {
        !           253:                if ((c = getnb()) == ',') {
        !           254:                        if (!fp_reg(ep2)
        !           255:                          || (ep1->e_mode != ST && ep2->e_mode != ST))
        !           256:                                qerr("invalid floating-point register");
        !           257:                }
        !           258:                else
        !           259:                        unget(c);
        !           260:                return(1);
        !           261:        }
        !           262:        else {
        !           263:                ep1->e_mode = ST1;
        !           264:                return(0);
        !           265:        }
        !           266: }
        !           267: 
        !           268: digit(c, r)
        !           269: register c, r;
        !           270: {
        !           271:        if (r == 16) {
        !           272:                if (c>='A' && c<='F')
        !           273:                        return (c-'A'+10);
        !           274:                if (c>='a' && c<='f')
        !           275:                        return (c-'a'+10);
        !           276:        }
        !           277:        if (c>='0' && c<='9')
        !           278:                return (c - '0');
        !           279:        return (-1);
        !           280: }
        !           281: 
        !           282: abscheck(esp)
        !           283: register struct expr *esp;
        !           284: {
        !           285:        if (esp->e_type != E_ACON) {
        !           286:                rerr("expected constant");
        !           287:                esp->e_type = E_ACON;
        !           288:        }
        !           289: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.