Annotation of coherent/d/bin/as/asmexpr.c, revision 1.1.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.