Annotation of researchv9/cmd/sun/c2/operand.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)operand.c 1.1 86/02/03 Copyr 1985 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include "as.h"
                     10: #include <ctype.h>
                     11: 
                     12: short cinfo[128] = {
                     13:        ERR,    ERR,    ERR,    ERR,    ERR,    ERR,    ERR,    ERR,
                     14:        ERR,    SPC,    EOL,    SPC,    SPC,    SPC,    ERR,    ERR,
                     15:        ERR,    ERR,    ERR,    ERR,    ERR,    ERR,    ERR,    ERR,
                     16:        ERR,    ERR,    ERR,    ERR,    ERR,    ERR,    ERR,    ERR,
                     17:        SPC,    ERR,    QUO,    IMM,    S+T,    ERR,    ERR,    ERR,
                     18:        LP,     RP,     MUL,    ADD,    COM,    SUB,    S+T,    DIV,
                     19:        D+T,    D+T,    D+T,    D+T,    D+T,    D+T,    D+T,    D+T,
                     20:        D+T,    D+T,    COL,    EOL,    ERR,    EQL,    ERR,    ERR,
                     21:        IND,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,
                     22:        S+T,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,
                     23:        S+T,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,
                     24:        S+T,    S+T,    S+T,    ERR,    ERR,    ERR,    ERR,    S+T,
                     25:        ERR,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,
                     26:        S+T,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,
                     27:        S+T,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,    S+T,
                     28:        S+T,    S+T,    S+T,    LB,     EOL,    RB,     NOT,    S+T
                     29: };  
                     30: 
                     31: /* for local labels: ``[0-9]:'', and references ``[0-9][bh]'' */
                     32: #if AS
                     33: char *ll_format = "*%c%06d";
                     34: #else C2
                     35: char *ll_format = "LX%c%06d";
                     36: #endif
                     37: 
                     38: int   ll_val[10];
                     39: 
                     40: static struct suffix {
                     41:     int                indx_sx;        /* index register */
                     42:     int                scale_sx;       /* index scaling  */
                     43:     long       disp_sx;        /* displacement   */
                     44:     struct sym_bkt *sym_sx;    /* symbolic displacement */
                     45:     unsigned   flags_sx;       /* see below      */
                     46: } fix [2];
                     47: 
                     48: static struct suffix zero_suffix = {  0  };
                     49: 
                     50: /* flags_sx values */
                     51: #define SX_INDXW       1       /* word-size index specified */
                     52: #define SX_INDXL       2       /* long-size index specified */
                     53: #define SX_DISPW       4       /* word-size displacement specified */
                     54: #define SX_DISPL       8       /* long-size displacement specified */
                     55: #define SX_GOTINDEX    020     /* index register specified */
                     56: #define SX_GOTDISP     040     /* displacement specified */
                     57: #if C2
                     58: #define SX_CXDISP      0100    /* displacement is complex */
                     59: #endif
                     60: 
                     61: static struct oper zero_oper  = { T_NULL, 0, 0, NULL, 0, 0, 0};
                     62: 
                     63: char *suffix(), *exp(), *term(), *scan_reg_or_immed();
                     64: char * scan_float();
                     65: double atof();
                     66: 
                     67: /* 
                     68:  * Fetches operand value and register subfields and loads them into
                     69:  * the operand structure. This routine will fetch only one set of value
                     70:  * and register subfields. It will move line pointer to first untouched char.
                     71:  */
                     72: char *
                     73: soperand(lptr,opnd)
                     74:        register char *lptr;
                     75:        struct oper *opnd;
                     76: {
                     77:        struct oper   spare_oper;
                     78:        int v;
                     79: 
                     80:        *opnd = zero_oper;
                     81:        spare_oper = zero_oper;
                     82: 
                     83:        if ((v=cinfo[*lptr]) == IMM) {
                     84:                lptr = exp(++lptr,opnd);
                     85:                if (opnd->type_o == T_REG) 
                     86:                        PROG_ERROR(E_REG);
                     87:                if (opnd->type_o == T_FLOAT)
                     88:                    /* immediate value is floating-point */
                     89:                    opnd->flags_o |= O_FLOAT; 
                     90:                opnd->type_o = T_IMMED;
                     91:        } else if (v == IND) {
                     92:            /* index mode, omitted base */
                     93:            /* expecting LP next        */
                     94:            lptr += 1;
                     95:            skipb(lptr);
                     96:            if (cinfo[*lptr] == LP)
                     97:                goto index_mode;
                     98:            else
                     99:                PROG_ERROR(E_OPERAND);
                    100:        } else { 
                    101:            lptr = exp(lptr,opnd);
                    102:            skipb(lptr);
                    103:            switch (opnd->type_o){
                    104:            case T_REG:
                    105:                switch (cinfo[*lptr]){
                    106:                case COL:       
                    107:                        /* should be a register pair */
                    108:                        lptr = exp( ++lptr, &spare_oper);
                    109:                        if (spare_oper.type_o != T_REG)
                    110:                            PROG_ERROR(E_OPERAND);
                    111: #if AS
                    112:                        if (!ext_instruction_set)
                    113:                            PROG_ERROR(E_OPERAND);
                    114: #endif
                    115:                        opnd->type_o = T_REGPAIR;
                    116:                        opnd->reg_o = spare_oper.value_o;
                    117:                        break;
                    118:                case IND:
                    119:                        if (!(areg(opnd->value_o)||pcreg(opnd->value_o)))
                    120:                            PROG_ERROR(E_OPERAND);
                    121:                        lptr += 1;
                    122:                        skipb(lptr);
                    123:                        switch (cinfo[*lptr]){
                    124:                        default:
                    125:                            opnd->type_o = T_DEFER;
                    126:                            break;
                    127:                        case ADD:
                    128:                            opnd->type_o = T_POSTINC;
                    129:                            lptr++;
                    130:                            break;
                    131:                        case SUB:
                    132:                            opnd->type_o = T_PREDEC;
                    133:                            lptr++;
                    134:                            break;
                    135:                        case LP:
                    136:                            /* defer or indexing coming up here */
                    137:                index_mode:
                    138:                            lptr = suffix( lptr, &fix[0] );
                    139:                            if (cinfo[*lptr] != IND){
                    140:                                simplify1( opnd, &fix[0] );
                    141:                            } else {
                    142:                                lptr = suffix( ++lptr, &fix[1] );
                    143:                                simplify2( opnd, &fix[0], &fix[1] );
                    144:                            }
                    145:                            break;
                    146:                        case IND:
                    147:                            lptr = suffix( ++lptr, &fix[1] );
                    148:                            simplify2( opnd, &zero_suffix, &fix[1] );
                    149:                            break;
                    150:                        }
                    151: #if AS
                    152:                        if (opnd->type_o == T_INDEX && !ext_instruction_set)
                    153:                            if ( (opnd->flags_o&(O_BSUPRESS|O_INDIRECT|O_WDISP|O_LDISP)) ||
                    154:                            opnd->scale_o != 1 || !(opnd->flags_o&O_PREINDEX))
                    155:                                PROG_ERROR( E_OPERAND );
                    156: #endif
                    157:                        /* flow through */
                    158:                default:
                    159:                        break;
                    160:                }
                    161:                break; 
                    162:            case T_NORMAL:
                    163:                if  (cinfo[*lptr] == COL ){
                    164:                    switch (*++lptr) { 
                    165:                        case 'W':
                    166:                        case 'w': opnd->type_o = T_ABSS;
                    167:                                  lptr++;
                    168:                                  break;
                    169:                        case 'L':
                    170:                        case 'l': opnd->type_o = T_ABSL;
                    171:                                  lptr++;
                    172:                                  break;
                    173:                    }
                    174:                }
                    175:                if (cinfo[*lptr] == IND)
                    176:                    goto index_mode;
                    177:                break; 
                    178:            }
                    179:     }
                    180:     skipb( lptr );
                    181:     if ( cinfo[ *lptr ] == LB ) {
                    182:        /* oh, boy, bitfields */
                    183:        opnd->flags_o |= O_BFLD;
                    184:        spare_oper = zero_oper;
                    185:        lptr = scan_reg_or_immed( lptr+1, &spare_oper);
                    186:        v = spare_oper.value_o;
                    187:        if (spare_oper.type_o == T_REG){
                    188:            opnd->flags_o |= O_BFOREG;
                    189:        } else if ((spare_oper.sym_o && !(spare_oper.sym_o->attr_s&S_DEF)) || v < 0 || v > 31){
                    190:            PROG_ERROR(E_CONSTANT);
                    191:        }
                    192:        opnd->bfoffset_o = v;
                    193:        skipb( lptr );
                    194:        if ( cinfo[ *lptr ] == COL)
                    195:            lptr ++;
                    196:        else
                    197:            PROG_ERROR(E_OPERAND);
                    198:        spare_oper = zero_oper;
                    199:        lptr = scan_reg_or_immed( lptr, &spare_oper);
                    200:        v = spare_oper.value_o;
                    201:        if (spare_oper.type_o == T_REG){
                    202:            opnd->flags_o |= O_BFWREG;
                    203:        } else if ((spare_oper.sym_o && !(spare_oper.sym_o->attr_s&S_DEF)) || v < 0 || v > 31){
                    204:            PROG_ERROR(E_CONSTANT);
                    205:        }
                    206:        opnd->bfwidth_o = v;
                    207:        skipb( lptr );
                    208:        if ( cinfo[ *lptr ] == RB )
                    209:            lptr++;
                    210:        else
                    211:            PROG_ERROR(E_OPERAND);
                    212:     }
                    213:     return(lptr);
                    214: } /* end soperand */
                    215: 
                    216: static char * 
                    217: scan_reg_or_immed( lptr, o )
                    218:     register char *lptr;
                    219:     register struct oper *o;
                    220: {
                    221:     skipb( lptr );
                    222:     if (cinfo[*lptr] == IMM) {
                    223:            lptr = exp(++lptr,o);
                    224:            if (o->type_o == T_REG) 
                    225:                    PROG_ERROR(E_REG);
                    226:            if (o->sym_o && !(o->sym_o->attr_s&S_DEF))
                    227:                    PROG_ERROR(E_REG);
                    228:            o->type_o = T_IMMED;
                    229:     } else {
                    230:        lptr = exp( lptr, o );
                    231:        if ( o->type_o != T_REG || o->value_o > D7REG)
                    232:            PROG_ERROR(E_OPERAND);
                    233:     }
                    234:     return lptr;
                    235: }
                    236: 
                    237: static char *
                    238: opt_length( lptr, fp, wflag, lflag )
                    239:     register char * lptr;
                    240:     struct suffix * fp;
                    241: {
                    242:     char * save = lptr;
                    243:     if (cinfo[ *lptr ] == COL){
                    244:        lptr++;
                    245:        skipb( lptr );
                    246:        switch ( *lptr ){
                    247:        case 'l':
                    248:        case 'L':
                    249:                fp->flags_sx |= lflag;
                    250:                lptr++;
                    251:                break;
                    252:        case 'w':
                    253:        case 'W':
                    254:                fp->flags_sx |= wflag;
                    255:                lptr++;
                    256:                break;
                    257:        default: return save; /* : yes, length, no: may be scale */
                    258:        }
                    259:     }
                    260:     return lptr;
                    261: }
                    262: static char *
                    263: opt_scale( lptr, fp )
                    264:     char * lptr;
                    265:     struct suffix * fp;
                    266: {
                    267:     fp->scale_sx = 1;
                    268:     if (cinfo[ *lptr ] == COL){
                    269:        lptr++;
                    270:        skipb( lptr );
                    271:        switch ( *lptr ){
                    272:        case '1':
                    273:        case '2':
                    274:        case '4':
                    275:        case '8':
                    276:                fp->scale_sx = *lptr - '0';
                    277:                lptr++;
                    278:                break;
                    279:        default: PROG_ERROR(E_OPERAND);
                    280:        }
                    281:     }
                    282:     return lptr;
                    283: }
                    284: 
                    285: static char *
                    286: suffix( lptr, fixp )
                    287:     register char * lptr;
                    288:     register struct suffix * fixp;
                    289: {
                    290:     /*
                    291:      * scan for open paran. look for displacement, optional length
                    292:      * specifier, then index register, optional length specifier, optional
                    293:      * scale specifier.
                    294:      * fill in suffix structure with what we find.
                    295:      */
                    296:     struct oper o;
                    297:     o = zero_oper;
                    298:     *fixp = zero_suffix;
                    299:     skipb( lptr );
                    300:     if (cinfo[ *lptr ] == LP )
                    301:        lptr += 1;
                    302:     else
                    303:        return lptr; /* guess that null suffix might be ok */
                    304:     lptr = exp( lptr , &o );
                    305:     if ( o.type_o == T_NORMAL ){
                    306:        fixp->disp_sx = o.value_o;
                    307:        fixp->sym_sx = o.sym_o;
                    308:        fixp->flags_sx |= SX_GOTDISP;
                    309: #if C2
                    310:        if (o.flags_o&O_COMPLEX)
                    311:            fixp->flags_sx |= SX_CXDISP;
                    312: #endif
                    313:        lptr = opt_length( lptr, fixp, SX_DISPW, SX_DISPL );
                    314:        skipb( lptr );
                    315:        if (cinfo[ *lptr ] ==  COM)
                    316:            lptr = exp( ++lptr, &o );
                    317:        else
                    318:            goto scan_rp;
                    319:     }
                    320:     /* now we're talking index */
                    321:     if ( o.type_o != T_REG ){
                    322:        PROG_ERROR( E_OPERAND);
                    323:     }
                    324:     fixp->flags_sx |= SX_GOTINDEX;
                    325:     fixp->indx_sx = o.value_o;
                    326:     lptr = opt_length( lptr, fixp, SX_INDXW, SX_INDXL );
                    327:     lptr = opt_scale( lptr, fixp );
                    328: scan_rp:
                    329:     skipb( lptr );
                    330:     if (cinfo[ *lptr ] == RP)
                    331:        lptr ++;
                    332:     else
                    333:        PROG_ERROR( E_OPERAND);
                    334:     return lptr;
                    335: }
                    336: 
                    337: static
                    338: simplify1( oper, fp )
                    339:     register struct oper * oper;
                    340:     register struct suffix *fp;
                    341: {
                    342:     register bval = oper->value_o;
                    343:     /* we have some form of deferred or indexed addressing here */
                    344:     /* try to make the best of it.                              */
                    345:     /*
                    346:      * examples are:
                    347:      *    a0@(disp)
                    348:      *    a0@(disp,d0:w:2)
                    349:      *    a0@(d0:w:2)
                    350:      *    pc@(disp)
                    351:      *    pc@(disp,d0:w:2)
                    352:      *    pc@(d0:w:2)
                    353:      *      @(d0)
                    354:      *      @(disp,d0)
                    355:      */
                    356:     switch (oper->type_o){
                    357:     case T_REG:
                    358:        if( !(fp->flags_sx&(SX_GOTINDEX|SX_DISPL)) ){
                    359:            /* displacement mode */
                    360:            oper->type_o = T_DISPL;
                    361:            oper->reg_o = bval;
                    362:            oper->value_o = fp->disp_sx;
                    363:            oper->sym_o = fp->sym_sx;
                    364:        } else {
                    365:            /* index mode */
                    366: imode:
                    367:            oper->type_o = T_INDEX;
                    368:            oper->reg_o = bval;
                    369:            oper->disp_o = fp->disp_sx;
                    370:            oper->sym_o = fp->sym_sx;
                    371:            if (fp->flags_sx&SX_GOTINDEX){
                    372:                oper->value_o = fp->indx_sx;
                    373:                oper->scale_o = fp->scale_sx;
                    374:                if (fp->flags_sx&SX_INDXW)
                    375:                    oper->flags_o|= O_WINDEX|O_PREINDEX;
                    376:                else 
                    377:                    oper->flags_o|= O_LINDEX|O_PREINDEX;
                    378:            } else {
                    379:                oper->value_o = 0;
                    380:                oper->scale_o = 0;
                    381:            }
                    382:            if (fp->flags_sx & SX_DISPL)
                    383:                oper->flags_o|= O_LDISP;
                    384:            else if (fp->flags_sx & SX_DISPW)
                    385:                oper->flags_o|= O_WDISP;
                    386:            /* else short form indexing */
                    387:        }
                    388:        break;
                    389:     case T_NULL:
                    390:        /* @(disp,d0)                 */
                    391:        /* @(d0)                      */
                    392:        /* index mode, supressed base */
                    393:        oper->type_o= T_INDEX;
                    394:        oper->flags_o|= O_BSUPRESS;
                    395:        oper->reg_o = A0REG; /* Supress THIS register */
                    396:        oper->disp_o= fp->disp_sx;
                    397:        oper->sym_o= fp->sym_sx;
                    398:        if(fp->flags_sx & SX_DISPL)
                    399:           oper->flags_o |= O_LDISP;
                    400:        else if (fp->flags_sx & SX_DISPW)
                    401:           oper->flags_o |= O_WDISP;
                    402:     do_index:
                    403:        if (fp->flags_sx & SX_GOTINDEX){
                    404:            oper->value_o = fp->indx_sx;
                    405:            oper->scale_o = fp->scale_sx;
                    406:            if (fp->flags_sx & (SX_INDXW) )
                    407:                oper->flags_o |= O_PREINDEX|O_WINDEX;
                    408:            else
                    409:                oper->flags_o |= O_PREINDEX|O_LINDEX;
                    410:        } else {
                    411:            oper->value_o = 0;
                    412:            oper->scale_o = 0;
                    413:        }
                    414:        break;
                    415:     case T_ABSS:
                    416:        oper->flags_o = O_WDISP;
                    417:        goto normal;
                    418:     case T_ABSL:
                    419:        oper->flags_o = O_LDISP;
                    420:        goto normal;
                    421:     case T_NORMAL:
                    422:        /* disp@                        */
                    423:        /* disp@(d0)                    */
                    424:        /* index mode, supressed base   */
                    425:        oper->flags_o = 0;
                    426:     normal:
                    427:        oper->type_o = T_INDEX;
                    428:        oper->flags_o|= O_BSUPRESS;
                    429:        oper->reg_o = A0REG; /* Supress THIS register */
                    430:        oper->disp_o = oper->value_o;
                    431:        if (fp->flags_sx&SX_GOTDISP)
                    432:            PROG_ERROR(E_OPERAND);
                    433:        goto do_index;
                    434:     default:
                    435:            PROG_ERROR(E_OPERAND);
                    436:     }
                    437: #if C2
                    438:     if (fp->flags_sx&SX_CXDISP)
                    439:        oper->flags_o |= O_COMPLEX;
                    440: #endif
                    441: }
                    442: 
                    443: static
                    444: simplify2( oper, fp, dfp )
                    445:     register struct oper * oper;
                    446:              struct suffix *fp;
                    447:     register struct suffix *dfp;
                    448: {
                    449:     /*
                    450:      * we have a memory indirect operand.
                    451:      * examples:
                    452:      * a0@(disp:l,d0:l:4)@(disp:w)
                    453:      *  a0@(disp)@(disp,d0:l:4)
                    454:      *  a0@@
                    455:      *    @(disp,d0)@(disp)
                    456:      *    @(d0)@
                    457:      *    @(disp)@
                    458:      *    @(disp,d0)@
                    459:      *   @(disp)@(d0)
                    460:      */
                    461:     simplify1( oper, fp );
                    462:     if (oper->type_o == T_DISPL){
                    463:        oper->type_o = T_INDEX;
                    464:        oper->disp_o = oper->value_o;
                    465:        oper->value_o = 0;
                    466:     }
                    467:     /* now build on that with second suffix */
                    468:     oper->flags_o |= O_INDIRECT;
                    469:     oper->disp2_o = dfp->disp_sx;
                    470:     oper->sym2_o  = dfp->sym_sx;
                    471:     if (dfp->flags_sx & SX_DISPL)
                    472:        oper->flags_o |= O_LDISP2;
                    473:     else if (dfp->flags_sx & SX_DISPW)
                    474:        oper->flags_o |= O_WDISP2;
                    475:     if (dfp->flags_sx & SX_GOTINDEX){
                    476:        if (oper->flags_o&O_PREINDEX)
                    477:            PROG_ERROR(E_OPERAND);
                    478:        oper->value_o = dfp->indx_sx;
                    479:        oper->flags_o |= O_POSTINDEX;
                    480:        oper->scale_o = dfp->scale_sx;
                    481:        if (dfp->flags_sx&SX_INDXW)
                    482:            oper->flags_o |= O_WINDEX;
                    483:        else
                    484:            oper->flags_o |= O_LINDEX;
                    485:     }
                    486: 
                    487: #if C2
                    488:     if (fp->flags_sx&SX_CXDISP)
                    489:        oper->flags_o |= O_COMPLEX2;
                    490: #endif
                    491: }
                    492: 
                    493: /* read expression */
                    494: char *
                    495: exp(lptr, arg1)
                    496:     register char *lptr;
                    497:     register struct oper *arg1;
                    498: {
                    499:     struct oper arg2;          /* holds value of right hand term */
                    500:     register int i;
                    501:     static struct oper zero_opr;
                    502: #if AS
                    503: #   define MKCOMPLEX( op )
                    504: #endif
                    505: #if C2
                    506: #   define MKCOMPLEX( op ) if (arg1->sym_o&&arg2.sym_o || \
                    507:     arg1->flags_o&O_COMPLEX || arg2.flags_o&O_COMPLEX){ \
                    508:        ocomplex( op, arg1, &arg2 ); continue; \
                    509:     }
                    510: #endif
                    511: 
                    512:     skipb(lptr);               /* Find the operator */
                    513:     i = cinfo[*lptr];
                    514:     if (i==EOL || i==COM){        /* nil operand is zero */
                    515:        arg1->sym_o = NULL;
                    516:         arg1->value_o = 0;
                    517:         return(lptr);
                    518:     }
                    519:     lptr = term( lptr, arg1 );
                    520: 
                    521:     while (1) {
                    522:          arg2 = zero_opr;
                    523:          skipb(lptr);
                    524:          switch (cinfo[*lptr]) {
                    525:            case ADD:   lptr = term( ++lptr, &arg2 );
                    526:                        if (arg1->type_o==T_REG || arg2.type_o==T_REG) 
                    527:                            break;
                    528: #if AS
                    529:                        if (arg1->sym_o && arg2.sym_o) 
                    530:                            if (pass==2) break;
                    531: #endif
                    532:                        MKCOMPLEX( ADD );
                    533:                        if (arg2.sym_o) 
                    534:                            arg1->sym_o = arg2.sym_o;
                    535:                        arg1->value_o += arg2.value_o;
                    536:                        arg1->flags_o |= arg2.flags_o&O_COMPLEX;
                    537:                        continue;
                    538: 
                    539:            case MUL:   lptr = term(++lptr,&arg2);
                    540:                        if (arg1->type_o==T_REG || arg2.type_o==T_REG) 
                    541:                            break;
                    542: #if AS
                    543:                        if (arg1->sym_o || arg2.sym_o) 
                    544:                            if (pass==2) break;
                    545: #endif
                    546:                        MKCOMPLEX( MUL );
                    547:                        arg1->value_o *= arg2.value_o;
                    548:                        arg1->flags_o |= arg2.flags_o&O_COMPLEX;
                    549:                        continue;
                    550: 
                    551:            case DIV:   lptr = term( ++lptr, &arg2 );
                    552:                        if (arg1->type_o==T_REG || arg2.type_o==T_REG) 
                    553:                            break;
                    554: #if AS
                    555:                        if (arg1->sym_o || arg2.sym_o) 
                    556:                            if (pass==2) break;
                    557:                           else if (arg2.value_o == 0) arg2.value_o = 1;
                    558: #endif
                    559:                        MKCOMPLEX( DIV );
                    560:                        arg1->value_o /= arg2.value_o;
                    561:                        arg1->flags_o |= arg2.flags_o&O_COMPLEX;
                    562:                        continue;
                    563: 
                    564:            case SUB:   lptr = term( ++lptr, &arg2 );
                    565:                        if (arg1->type_o==T_REG || arg2.type_o==T_REG) 
                    566:                            break;
                    567:                        if (arg2.sym_o){        /* if B is relocatable, */
                    568:                           if (arg1->sym_o){    /* and A is relocatable, */
                    569: #if AS
                    570:                               if (arg2.sym_o->csect_s != arg1->sym_o->csect_s
                    571:                               && pass == 2){
                    572:                                   break;  /* break into error */
                    573:                               } else {   
                    574:                                    /* result is absolute (no offset) */
                    575:                                    arg1->sym_o = NULL; 
                    576:                                    /* but not a simple address for sdi's */
                    577:                                    arg1->flags_o |= O_COMPLEX; 
                    578:                               }
                    579: #endif
                    580: #if C2
                    581:                                /* operand cannot be understood at this time */
                    582:                                ocomplex( SUB, arg1, &arg2 );
                    583:                                continue;
                    584: #endif
                    585:                           } 
                    586:                            else break;    /* if B rel., and A is not, */
                    587:                                           /* then break into relocation error */
                    588:                        }
                    589:                        arg1->value_o -= arg2.value_o;
                    590:                        continue;
                    591: 
                    592:            default:    return(lptr);
                    593:          }
                    594:        PROG_ERROR(E_RELOCATE);
                    595:        return(lptr);
                    596:     }
                    597: #undef MKCOMPLEX
                    598: } /* end exp <read expression> */
                    599: 
                    600: /* read term: either symbol, constant, or unary minus */
                    601: char *
                    602: term( lptr, vp )
                    603:        register char *lptr;
                    604:        register struct oper *vp;
                    605: {
                    606:        register struct sym_bkt *sbp;
                    607:        register int base = 10;
                    608:        register long val;
                    609:        register char *p;
                    610:        register int i;
                    611:        char savechar, *t;
                    612:        char token[50];
                    613: 
                    614:        skipb(lptr);
                    615:        i = cinfo[*lptr];
                    616: 
                    617:        /* here for number */
                    618:        if (i & D){
                    619:                p = lptr;
                    620:                val = 0;
                    621:                if (*lptr == '0'){ 
                    622:                        lptr++;
                    623:                        switch( *lptr){
                    624:                        case 'x':
                    625:                        case 'X':
                    626:                                lptr++; 
                    627:                                /* hexidecimal number */
                    628:                                while (1){
                    629:                                        if (cinfo[*lptr] & D)
                    630:                                                val = val*16 + *lptr++ - '0';
                    631:                                        else if (*lptr>='A' && *lptr<='F')
                    632:                                                val = val*16 + *lptr++ - 'A' + 10;
                    633:                                        else if (*lptr>='a' && *lptr<='f')
                    634:                                                val = val*16 + *lptr++ - 'a' + 10;
                    635:                                        else break;
                    636:                                }
                    637:                                break;
                    638:                        case 'f':
                    639:                                /*
                    640:                                 * be careful not to confuse the floating-point
                    641:                                 * constant 0f0.0 with the local label reference                                 * 0f .
                    642:                                 * for legitimate floating constants, the next
                    643:                                 * character can be a digit, a decimal point,
                    644:                                 * a negative sign, or one of the letters
                    645:                                 * 'n', 'N', 'i', or 'I'.
                    646:                                 */
                    647:                                switch (*(lptr+1)){
                    648:                                case '0':case '1':case '2':case '3':case '4':
                    649:                                case '5': case '6':case '7':case '8':case '9':
                    650:                                case '.': case '-': case '+':
                    651:                                case 'n':case 'N': case 'i':case 'I':
                    652:                                    break;
                    653:                                default:
                    654:                                    val = 0;
                    655:                                    goto got_a_number;
                    656:                                }
                    657:                                /* FALL THROUGH */
                    658:                        case 'F':
                    659:                        case 'R':
                    660:                        case 'r':
                    661:                                lptr = scan_float( lptr, vp );
                    662:                                return (lptr);
                    663:                        default:
                    664:                                /* octal number */
                    665:                                while (cinfo[*lptr] & D){
                    666:                                        if (*lptr == '8' || *lptr == '9')
                    667:                                                PROG_ERROR(E_CONSTANT);
                    668:                                        val = val*8 + *lptr++ - '0';
                    669:                                }
                    670:                        }
                    671:                } else {
                    672:                        /* decimal number */
                    673:                        while (cinfo[*lptr] & D)
                    674:                                val = val*10 + *lptr++ - '0';
                    675:                }
                    676:            got_a_number:
                    677:                if (*lptr == '$')
                    678:                        { lptr = p; goto sym; }
                    679:                if (*lptr == 'b' || *lptr == 'f'){
                    680:                        /* local label reference, of form [0-9][bh] */
                    681:                        /* single digits only                       */
                    682:                        if (lptr > p+1 ){
                    683:                            PROG_ERROR(E_SYMLEN);
                    684:                        }
                    685:                        val = ll_val[*p-'0'] + (*lptr++=='f');
                    686:                        if (val < 0 ) PROG_ERROR(E_SYMDEF);
                    687:                        sprintf(token, ll_format, *p, val);
                    688:                        sbp = lookup(token);
                    689:                        goto sym2;
                    690: 
                    691:                }
                    692:                vp->value_o = val;
                    693:                vp->sym_o = NULL;
                    694:                vp->type_o = T_NORMAL;
                    695:                return(lptr);
                    696:        }
                    697: 
                    698:        /* here for symbol name */
                    699:        if (i & S) {
                    700: sym:           t = lptr;
                    701:                while (cinfo[*lptr] & T)
                    702:                        lptr++;
                    703:                savechar = *lptr;
                    704:                *lptr = '\0';     
                    705:                sbp = lookup(t);                /* find its symbol bucket */
                    706:                *lptr = savechar;
                    707: sym2:
                    708: #if C2
                    709:                 sbp->nuse_s++;
                    710: #endif
                    711:                if (sbp->attr_s & S_DEF
                    712: #if C2
                    713:                && sbp->csect_s == C_UNDEF
                    714: #endif
                    715:                ){
                    716:                        /* if it's defined, use its value */
                    717:                        vp->value_o = sbp->value_s;
                    718:                } else 
                    719:                        vp->value_o = 0;
                    720:                if (sbp->attr_s & S_REG){
                    721:                        vp->type_o = T_REG;
                    722:                        vp->sym_o  = NULL;
                    723:                } else {
                    724:                        vp->sym_o = ((sbp->attr_s & S_DEF) &&
                    725:                            (sbp->csect_s == C_UNDEF )) ? 0 : sbp;
                    726:                        vp->type_o = T_NORMAL;
                    727:                }
                    728:                return(lptr);
                    729:        }
                    730: 
                    731:        /* check for unary minus */
                    732:        if (i == SUB) {
                    733:                lptr = term(++lptr,vp);
                    734:                if (vp->sym_o){
                    735: #if AS
                    736:                    PROG_ERROR(E_RELOCATE);
                    737: #endif
                    738: #if C2
                    739:                    if (vp->sym_o){
                    740:                        ocomplex( SUB, vp, 0);
                    741:                        return(lptr);
                    742:                    }
                    743: #endif
                    744:                }
                    745:                vp->value_o = -(vp->value_o);
                    746:                return(lptr);
                    747:        }
                    748: 
                    749:        /* check for complement */
                    750:        if (i == NOT) {
                    751:                lptr = term(++lptr,vp);
                    752:                if (vp->sym_o){
                    753: #if AS
                    754:                    PROG_ERROR(E_RELOCATE);
                    755: #endif
                    756: #if C2
                    757:                    if (vp->sym_o){
                    758:                        ocomplex( NOT, vp, 0);
                    759:                        return(lptr);
                    760:                    }
                    761: #endif
                    762:                }
                    763:                vp->value_o = ~(vp->value_o);
                    764:                return(lptr);
                    765:        }
                    766: 
                    767:        /* here for string */
                    768:        if (i == QUO) {
                    769:                vp->stringval_o = lptr+1;
                    770:                /* scan over the quoted string, being careful of \-stuff */
                    771:                do{
                    772:                        i = *++lptr;
                    773:                        if (i=='\\')
                    774:                        switch (i = *++lptr){
                    775:                        case '"': i = '\\'; /* fake-out loop test by covering up \"*/
                    776:                        }
                    777:                }while (i!='\n' && i!='"');
                    778:                if (i == '\n'){
                    779:                        PROG_ERROR(E_STRING);
                    780:                }
                    781:                *lptr++ = 0;
                    782:                vp->sym_o = NULL;
                    783:                vp->type_o = T_STRING;
                    784:                return(lptr);
                    785:        }
                    786: 
                    787:        /* new, improved kluge -- parens !! */
                    788:        if (i==LP) {
                    789:                lptr = exp(++lptr, vp);
                    790:                skipb(lptr);
                    791:                if ((i=cinfo[*lptr]) == RP) {
                    792:                        lptr++;
                    793:                } else {
                    794:                        PROG_ERROR( E_PAREN );
                    795:                }
                    796:                return( lptr );
                    797:        }
                    798: 
                    799:        PROG_ERROR(E_TERM);
                    800:        return(lptr);
                    801: } /* end term */
                    802: 
                    803: char *
                    804: scan_float( lptr, vp )
                    805:     register char * lptr;
                    806:     struct oper *vp;
                    807: {
                    808:     /*
                    809:      * lptr address a string which is a 'd' or an 'f', followed
                    810:      * by a floating-point number. The latter looks like:
                    811:      *     [+-]nan( [0-9a-f]+ )
                    812:      * or  [+-]inf
                    813:      * or  [+-][0-9]+[.[0-9]+][e[+-][0-9]+]
                    814:      * in the latter case, we call atof to do the conversion work.
                    815:      * We do not take great care in syntax checking the number.
                    816:      */
                    817:     int s=0;
                    818:     union{ double d; float f; int x[2]; } fp;
                    819:     unsigned nanno, nanno2;
                    820:     register char *nbegin;
                    821:     char c;
                    822: 
                    823:     lptr++; /* skip the f */
                    824:     nbegin = lptr;
                    825: again:
                    826:     switch ( *lptr++){
                    827:     case '+':  if (s) goto bad_num; s = 1; goto again;
                    828:     case '-':  if (s) goto bad_num; s = -1; goto again;
                    829:     case 'N':
                    830:     case 'n': /* nan */
                    831:        if (*lptr++ != 'a') goto bad_num;
                    832:        if (*lptr++ != 'n') goto bad_num;
                    833:        if (*lptr++ != '(') goto bad_num;
                    834:        nanno = nanno2 = 0;
                    835:        while( isxdigit(c = *lptr++)){
                    836:            if (isdigit(c)) c -= '0';
                    837:            else if (isupper(c)) c -= 'a'-10;
                    838:            else c -= 'A'-10;
                    839:            nanno2 = (nanno2 << 8) | (nanno >> 24);
                    840:            nanno = (nanno<<8) | c;
                    841:        }
                    842:        if (c != ')') goto bad_num;
                    843:        goto make_indef;
                    844:            
                    845:     case 'I':
                    846:     case 'i':  /* inf */
                    847:        if (*lptr++ != 'n') goto bad_num;
                    848:        if (*lptr++ != 'f') goto bad_num;
                    849:        if (strncmp(lptr,"inity",5) == 0)
                    850:                lptr += 5;
                    851:        nanno = nanno2 = 0;
                    852:     make_indef:
                    853:        fp.x[0] = ((s<0)?0xfff00000:0x7ff00000) | nanno2;
                    854:        fp.x[1] = nanno;
                    855:        break;
                    856:     case '0': case '1': case '2': case '3': case '4':
                    857:     case '5': case '6': case '7': case '8': case '9': 
                    858:        /* scan for more digits */
                    859:        while( isdigit( c = *lptr++ ) )
                    860:            continue;
                    861:        if (c != '.' )
                    862:            goto scan_exp;
                    863:        /* FALL THROUGH */
                    864:     case '.':
                    865:        /* scan for more digits */
                    866:        while( isdigit( c = *lptr++ ) )
                    867:            continue;
                    868:     scan_exp:
                    869:        s = 0;
                    870:        switch(c){
                    871:        case '+':
                    872:        case '-':
                    873:            s = 1;
                    874:            /* FALL THROUGH */
                    875:        case 'e':
                    876:        case 'E':
                    877:            switch ( c= *lptr++ ){
                    878:            case '+':
                    879:            case '-':
                    880:                if (s) goto bad_num;
                    881:                c = *lptr++;
                    882:                /* FALL THROUGH */
                    883:            default:
                    884:                s = 0; /* count chars: 0 is not ok */
                    885:                while( isdigit(c) ){
                    886:                    c = *lptr++;
                    887:                    s++;
                    888:                }
                    889:                if (s == 0) goto bad_num;
                    890:                break;
                    891:            }
                    892:            break;
                    893:        }
                    894:        fp.d = atof( nbegin );
                    895:        lptr--;
                    896:        break;
                    897:     default:
                    898:     bad_num:
                    899:        PROG_ERROR( E_BADCHAR );
                    900:        return lptr;
                    901:     }
                    902:     vp->fval_o = fp.d;
                    903:     vp->type_o = T_FLOAT;
                    904:     return lptr;
                    905: }
                    906: 
                    907: 
                    908: static void
                    909: printoffset( value, sym, cmplx )
                    910:     int value;
                    911:     struct sym_bkt *sym;
                    912:     int cmplx;
                    913: {
                    914:     register struct optree *ot;
                    915:     register char c = '?';
                    916:     struct oper *op;
                    917:     if (cmplx){
                    918:         ot = (struct optree*)sym;
                    919:         if (ot->right_t == NULL){
                    920:             /* unary operation */
                    921:             switch(ot->op_t){
                    922:             case SUB: c = '-'; break;
                    923:             case NOT: c = '~'; break;
                    924:             }
                    925:             printf("%c(",c);
                    926:             op=ot->left_t;
                    927:             printoffset(op->value_o, op->sym_o, op->flags_o&O_COMPLEX);
                    928:             putchar(')');
                    929:         } else {
                    930:             /* binary */
                    931:             putchar('(');
                    932:             op=ot->left_t;
                    933:             printoffset(op->value_o, op->sym_o, op->flags_o&O_COMPLEX);
                    934:             switch(ot->op_t){
                    935:             case ADD: c = '+'; break;
                    936:             case SUB: c = '-'; break;
                    937:             case MUL: c = '*'; break;
                    938:             case DIV: c = '/'; break;
                    939:             }
                    940:             printf(")%c(", c);
                    941:             op=ot->right_t;;
                    942:             printoffset(op->value_o, op->sym_o, op->flags_o&O_COMPLEX);
                    943:             putchar(')');
                    944:         }
                    945:         return;
                    946:     }
                    947:     if (sym != NULL){
                    948:         fputs(sym->name_s, stdout);
                    949:         if (value)
                    950:             printf("+%d", value);
                    951:     } else {
                    952:         printf("%d", value);
                    953:     }
                    954: }
                    955: 
                    956: 
                    957: char *rnames[] = {
                    958:     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
                    959:     "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", 
                    960:     "fp0","fp1","fp2","fp3","fp4","fp5","fp6","fp7",
                    961:     "cc", "fcc", "pc", "sr", "usp", "sfc", "dfc", "vbr", 
                    962:     "cacr", "caar", "msp", "isp", "fpc", "fps", "fpi"
                    963: };
                    964: 
                    965: static void
                    966: printindex( o )
                    967:     register struct oper *o;
                    968: {
                    969:     printf("%s:%c", rnames[o->value_o], o->flags_o&O_WINDEX ? 'w' : 'l');
                    970:     if (o->scale_o != 1) printf(":%d", o->scale_o);
                    971: }
                    972: 
                    973: printoperand( o )
                    974:     register struct oper *o;
                    975: {
                    976:     switch (o->type_o){
                    977:     case T_REG:                printf("%s",   rnames[o->value_o]); break;
                    978:     case T_DEFER:      printf("%s@",  rnames[o->value_o]); break;
                    979:     case T_POSTINC:    printf("%s@+", rnames[o->value_o]); break;
                    980:     case T_PREDEC:     printf("%s@-", rnames[o->value_o]); break;
                    981:     case T_DISPL:      printf("%s@(", rnames[o->reg_o]);
                    982:                        printoffset(o->value_o, o->sym_o, o->flags_o&O_COMPLEX);
                    983:                        putchar(')');
                    984:                        break;
                    985:     case T_INDEX:      
                    986:                        if (!(o->flags_o&O_BSUPRESS)){
                    987:                            printf("%s@", rnames[o->reg_o]);
                    988:                        }
                    989:                        putchar('(');
                    990:                        printoffset(o->disp_o, o->sym_o, o->flags_o&O_COMPLEX);
                    991:                        if (o->flags_o & O_WDISP) fputs(":w", stdout);
                    992:                        else if (o->flags_o & O_LDISP) fputs(":l", stdout);
                    993:                        if (o->flags_o&O_PREINDEX){
                    994:                            putchar(',');
                    995:                            printindex( o );
                    996:                        }
                    997:                        putchar(')');
                    998:                        if (o->flags_o&O_INDIRECT){
                    999:                            putchar('@');
                   1000:                            if (o->disp2_o || o->sym2_o || o->flags_o&O_POSTINDEX){
                   1001:                                putchar('(');
                   1002:                                if (o->disp2_o || o->sym2_o ){
                   1003:                                    printoffset(o->disp2_o, o->sym2_o, o->flags_o&O_COMPLEX2);
                   1004:                                    if (o->flags_o&O_POSTINDEX)
                   1005:                                        putchar(',');
                   1006:                                }
                   1007:                                if (o->flags_o&O_POSTINDEX){
                   1008:                                    printindex( o );
                   1009:                                }
                   1010:                                putchar(')');
                   1011:                            }
                   1012:                        }
                   1013:                        break;
                   1014:     case T_ABSS:
                   1015:     case T_ABSL:
                   1016:                        printoffset(o->value_o, o->sym_o, o->flags_o&O_COMPLEX);
                   1017:                        fputs( (o->type_o == T_ABSS) ? ":w" : ":l", stdout);
                   1018:                        break;
                   1019:     case T_IMMED:
                   1020:                        putchar('#');
                   1021:                        if (o->flags_o & O_FLOAT) goto float_val;
                   1022:                        /* FALL THROUGH */
                   1023:     case T_NORMAL:
                   1024:                        printoffset(o->value_o, o->sym_o, o->flags_o&O_COMPLEX);
                   1025:                        break;
                   1026:     case T_STRING:
                   1027:                        printf("\"%s\"", o->stringval_o);
                   1028:                        break;
                   1029:     case T_REGPAIR:    printf("%s:%s", rnames[o->value_o],rnames[o->reg_o]);
                   1030:                        break;
                   1031: float_val:
                   1032:     case T_FLOAT:      printf("0r%.17e", o->fval_o); 
                   1033:                        break;
                   1034:     default:
                   1035:                        printf("UNKNOWN(%d)", o->type_o);
                   1036:                        break;
                   1037:     }
                   1038:     if (o->flags_o&O_BFLD){
                   1039:        /* bit field */
                   1040:        /* first the offset part */
                   1041:        if (o->flags_o&O_BFOREG)
                   1042:            printf("{%s:",rnames[o->bfoffset_o]);
                   1043:        else
                   1044:            printf("{#%d:",o->bfoffset_o);
                   1045:        /* then the width part */
                   1046:        if (o->flags_o&O_BFWREG)
                   1047:            printf("%s}",rnames[o->bfwidth_o]);
                   1048:        else
                   1049:            printf("#%d}",o->bfwidth_o);
                   1050:     }
                   1051: }

unix.superglobalmegacorp.com

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