Annotation of researchv9/cmd/sun/c2/operand.c, revision 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.