Annotation of 43BSDReno/pgrm/as.vax/asparse.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)asparse.c  5.3 (Berkeley) 11/17/86";
                      9: #endif not lint
                     10: 
                     11: #include <stdio.h>
                     12: #include "as.h"
                     13: #include "asscan.h"
                     14: #include "assyms.h"
                     15: #include "asexpr.h"
                     16: 
                     17: int    lgensym[10];
                     18: char   genref[10];
                     19: 
                     20: long   bitfield;
                     21: int    bitoff;
                     22: int    curlen;                 /* current length of literals */
                     23: 
                     24: /*
                     25:  *     The following three variables are communication between various
                     26:  *     modules to special case a number of things.  They are properly
                     27:  *     categorized as hacks.
                     28:  */
                     29: extern struct  symtab *lastnam;/*last name seen by the lexical analyzer*/
                     30: int    exprisname;             /*last factor in an expression was a name*/
                     31: int    droppedLP;              /*one is analyzing an expression beginning with*/
                     32:                                /*a left parenthesis, which has already been*/
                     33:                                /*shifted. (Used to parse (<expr>)(rn)*/
                     34: 
                     35: char   yytext[NCPName+2];      /*the lexical image*/
                     36: int    yylval;                 /*the lexical value; sloppy typing*/
                     37: struct Opcode          yyopcode;       /* lexical value for an opcode */
                     38: Bignum yybignum;               /* lexical value for a big number */
                     39: /*
                     40:  *     Expression and argument managers
                     41:  */
                     42: struct exp     *xp;            /*next free expression slot, used by expr.c*/
                     43: struct exp     explist[NEXP];  /*max of 20 expressions in one opcode*/
                     44: struct arg     arglist[NARG];  /*building up operands in instructions*/
                     45: /*
                     46:  *     Sets to accelerate token discrimination
                     47:  */
                     48: char   tokensets[(LASTTOKEN) - (FIRSTTOKEN) + 1];
                     49: 
                     50: static char    UDotsname[64];  /*name of the assembly source*/
                     51: 
                     52: yyparse()
                     53: {
                     54:        reg     struct  exp     *locxp;
                     55:                /*
                     56:                 *      loc1xp and ptrloc1xp are used in the
                     57:                 *      expression lookahead
                     58:                 */
                     59:                struct  exp     *loc1xp;        /*must be non register*/
                     60:                struct  exp     **ptrloc1xp = & loc1xp;
                     61:                struct  exp     *pval;          /*hacking expr:expr*/
                     62: 
                     63:        reg     struct  symtab  *np;
                     64:        reg     int             argcnt;
                     65: 
                     66:        reg     inttoktype      val;            /*what yylex gives*/
                     67:        reg     inttoktype      auxval;         /*saves val*/
                     68: 
                     69:        reg     struct  arg     *ap;            /*first free argument*/
                     70: 
                     71:        reg     struct  symtab  *p;
                     72:        reg     struct  symtab  *stpt;
                     73: 
                     74:                struct  strdesc *stringp;       /*handles string lists*/
                     75: 
                     76:                int     regno;          /*handles arguments*/
                     77:                int     *ptrregno = &regno;
                     78:                int     sawmul;         /*saw * */
                     79:                int     sawindex;       /*saw [rn]*/
                     80:                int     sawsize;
                     81:                int     seg_type;       /*the kind of segment: data or text*/
                     82:                int     seg_number;     /*the segment number*/
                     83:                int     space_value;    /*how much .space needs*/
                     84:                int     fill_rep;       /*how many reps for .fill */
                     85:                int     fill_size;      /*how many bytes for .fill */
                     86: 
                     87:                int     field_width;    /*how wide a field is to be*/
                     88:                int     field_value;    /*the value to stuff in a field*/
                     89:                char    *stabname;      /*name of stab dealing with*/
                     90:                ptrall  stabstart;      /*where the stab starts in the buffer*/
                     91:                int     reloc_how;      /* how to relocate expressions */
                     92:                int     toconv;         /* how to convert bignums */
                     93:                int     incasetable;    /* set if in a case table */
                     94: 
                     95:        incasetable = 0;
                     96:        xp = explist;
                     97:        ap = arglist;
                     98: 
                     99:        val = yylex();
                    100: 
                    101:     while (val != PARSEEOF){   /* primary loop */
                    102: 
                    103:        while (INTOKSET(val, LINSTBEGIN)){
                    104:                if (val == INT) {
                    105:                        int i = ((struct exp *)yylval)->e_xvalue;
                    106:                        shift;
                    107:                        if (val != COLON){
                    108:                                yyerror("Local label %d is not followed by a ':' for a label definition",
                    109:                                        i);
                    110:                                goto  errorfix;
                    111:                        }
                    112:                        if (i < 0 || i > 9) {
                    113:                                yyerror("Local labels are 0-9");
                    114:                                goto errorfix;
                    115:                        }
                    116:                        (void)sprintf(yytext, "L%d\001%d", i, lgensym[i]);
                    117:                        lgensym[i]++;
                    118:                        genref[i] = 0;
                    119:                        yylval = (int)*lookup(passno == 1);
                    120:                        val = NAME;
                    121:                        np = (struct symtab *)yylval;
                    122:                        goto restlab;
                    123:                }
                    124:                if (val == NL){
                    125:                        lineno++;
                    126:                        shift;
                    127:                } else
                    128:                if (val == SEMI) 
                    129:                        shift;
                    130:                else {  /*its a name, so we have a label or def */
                    131:                        if (val != NAME){
                    132:                                ERROR("Name expected for a label");
                    133:                        }
                    134:                        np = (struct symtab *)yylval;
                    135:                        shiftover(NAME);
                    136:                        if (val != COLON) {
                    137:                                yyerror("\"%s\" is not followed by a ':' for a label definition",
                    138:                                        FETCHNAME(np));
                    139:                                goto  errorfix;
                    140:                        }
                    141: restlab:
                    142:                        shift;
                    143:                        flushfield(NBWD/4);
                    144:                        if ((np->s_type&XTYPE)!=XUNDEF) {
                    145:                                if (  (np->s_type&XTYPE) != dotp->e_xtype 
                    146:                                   || np->s_value != dotp->e_xvalue
                    147:                                   || (   passno == 1
                    148:                                       && np->s_index != dotp->e_xloc) ) {
                    149:                                        if (passno == 1)
                    150:                                                yyerror("%s redefined",
                    151:                                                        FETCHNAME(np));
                    152:                                        else
                    153:                                                yyerror("%s redefined: PHASE ERROR, 1st: %d, 2nd: %d",
                    154:                                                        FETCHNAME(np),
                    155:                                                        np->s_value,
                    156:                                                        dotp->e_xvalue);
                    157:                                }
                    158:                        }
                    159:                        np->s_type &= ~(XTYPE|XFORW);
                    160:                        np->s_type |= dotp->e_xtype;
                    161:                        np->s_value = dotp->e_xvalue;
                    162:                        if (passno == 1){
                    163:                                np->s_index = dotp-usedot;
                    164:                                if (FETCHNAME(np)[0] == 'L'){
                    165:                                        nlabels++;
                    166:                                }
                    167:                                np->s_tag = LABELID;
                    168:                        }
                    169:                }       /*end of this being a label*/
                    170:        }       /*end of consuming all labels, NLs and SEMIS */ 
                    171: 
                    172:        xp = explist;
                    173:        ap = arglist;
                    174: 
                    175:        /*
                    176:         *      process the INSTRUCTION body
                    177:         */
                    178:        switch(val){
                    179: 
                    180:     default:
                    181:        ERROR("Unrecognized instruction or directive");
                    182: 
                    183:    case IABORT:
                    184:        shift;
                    185:        sawabort();
                    186:        /*NOTREACHED*/
                    187:        break;
                    188: 
                    189:    case PARSEEOF:
                    190:        tokptr -= sizeof(bytetoktype);
                    191:        *tokptr++ = VOID;
                    192:        tokptr[1] = VOID;
                    193:        tokptr[2] = PARSEEOF;
                    194:        break;
                    195: 
                    196:    case IFILE:
                    197:        shift;
                    198:        stringp = (struct strdesc *)yylval;
                    199:        shiftover(STRING);
                    200:        dotsname = &UDotsname[0];
                    201:        movestr(dotsname, stringp->sd_string,
                    202:                min(stringp->sd_strlen, sizeof(UDotsname)));
                    203:        break;
                    204: 
                    205:    case ILINENO:
                    206:        shift;          /*over the ILINENO*/
                    207:        expr(locxp, val);
                    208:        lineno = locxp->e_xvalue;
                    209:        break;
                    210: 
                    211:    case ISET:  /* .set  <name> , <expr> */
                    212:        shift;
                    213:        np = (struct symtab *)yylval;
                    214:        shiftover(NAME);
                    215:        shiftover(CM);
                    216:        expr(locxp, val);
                    217:        np->s_type &= (XXTRN|XFORW);
                    218:        np->s_type |= locxp->e_xtype&(XTYPE|XFORW);
                    219:        np->s_value = locxp->e_xvalue;
                    220:        if (passno==1)
                    221:                np->s_index = locxp->e_xloc;
                    222:        if ((locxp->e_xtype&XTYPE) == XUNDEF)
                    223:                yyerror("Illegal set?");
                    224:        break;
                    225: 
                    226:    case ILSYM:         /*.lsym name , expr */
                    227:        shift;
                    228:        np = (struct symtab *)yylval;
                    229:        shiftover(NAME);
                    230:        shiftover(CM);
                    231:        expr(locxp, val);
                    232:        /*
                    233:         *      Build the unique occurance of the
                    234:         *      symbol.
                    235:         *      The character scanner will have
                    236:         *      already entered it into the symbol
                    237:         *      table, but we should remove it
                    238:         */
                    239:        if (passno == 1){
                    240:                stpt = (struct symtab *)symalloc();
                    241:                stpt->s_name = np->s_name;
                    242:                np->s_tag = OBSOLETE;   /*invalidate original */
                    243:                nforgotten++;
                    244:                np = stpt;
                    245:                if ( (locxp->e_xtype & XTYPE) != XABS)
                    246:                        yyerror("Illegal second argument to lsym");
                    247:                np->s_value = locxp->e_xvalue;
                    248:                np->s_type = XABS;
                    249:                np->s_tag = ILSYM;
                    250:        }
                    251:        break;
                    252: 
                    253:    case IGLOBAL:       /*.globl <name> */
                    254:        shift;
                    255:        np = (struct symtab *)yylval;
                    256:        shiftover(NAME);
                    257:        np->s_type |= XXTRN;
                    258:        break;
                    259: 
                    260:    case IDATA:         /*.data [ <expr> ] */
                    261:    case ITEXT:         /*.text [ <expr> ] */
                    262:        seg_type = -val;
                    263:        shift;
                    264:        if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
                    265:                expr(locxp, val);
                    266:                seg_type = -seg_type;   /*now, it is positive*/
                    267:        }
                    268: 
                    269:        if (seg_type < 0) {     /*there wasn't an associated expr*/
                    270:                seg_number = 0;
                    271:                seg_type = -seg_type;
                    272:        } else {
                    273:                if (   ((locxp->e_xtype & XTYPE) != XABS)       /* tekmdp */
                    274:                    || (seg_number = locxp->e_xvalue) >= NLOC) {
                    275:                        yyerror("illegal location counter");
                    276:                        seg_number = 0;
                    277:                }
                    278:        }
                    279:        if (seg_type == IDATA)
                    280:                seg_number += NLOC;
                    281:        flushfield(NBWD/4);
                    282:        dotp = &usedot[seg_number];
                    283:        if (passno==2) {        /* go salt away in pass 2*/
                    284:                txtfil = usefile[seg_number];
                    285:                relfil = rusefile[seg_number];
                    286:        }
                    287:        break;
                    288: 
                    289:        /*
                    290:         *      Storage filler directives:
                    291:         *
                    292:         *      .byte   [<exprlist>]
                    293:         *
                    294:         *      exprlist:  empty | exprlist outexpr
                    295:         *      outexpr:   <expr> | <expr> : <expr>
                    296:         */
                    297:    case IBYTE: curlen = NBWD/4; goto elist;
                    298:    case IWORD: curlen = NBWD/2; goto elist;
                    299:    case IINT:  curlen = NBWD;   goto elist;
                    300:    case ILONG: curlen = NBWD;   goto elist;
                    301: 
                    302:    elist:
                    303:        seg_type = val;
                    304:        shift;
                    305: 
                    306:        /*
                    307:         *      Expression List processing
                    308:         */
                    309:        if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
                    310:            do{
                    311:                /*
                    312:                 *      expression list consists of a list of :
                    313:                 *      <expr>
                    314:                 *      <expr> : <expr> 
                    315:                 *              (pack expr2 into expr1 bits
                    316:                 */
                    317:                expr(locxp, val);
                    318:                /*
                    319:                 *      now, pointing at the next token
                    320:                 */
                    321:                if (val == COLON){
                    322:                        shiftover(COLON);
                    323:                        expr(pval, val);
                    324:                        if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */
                    325:                                yyerror("Width not absolute");
                    326:                        field_width = locxp->e_xvalue;
                    327:                        locxp = pval;
                    328:                        if (bitoff + field_width > curlen)
                    329:                                flushfield(curlen);
                    330:                        if (field_width > curlen)
                    331:                                yyerror("Expression crosses field boundary");
                    332:                } else {
                    333:                        field_width = curlen;
                    334:                        flushfield(curlen);
                    335:                }
                    336: 
                    337:                if ((locxp->e_xtype & XTYPE) != XABS) {
                    338:                        if (bitoff)
                    339:                                yyerror("Illegal relocation in field");
                    340:                        switch(curlen){
                    341:                                case NBWD/4:    reloc_how = TYPB; break;
                    342:                                case NBWD/2:    reloc_how = TYPW; break;
                    343:                                case NBWD:      reloc_how = TYPL; break;
                    344:                        }
                    345:                        if (passno == 1){
                    346:                                dotp->e_xvalue += ty_nbyte[reloc_how];
                    347:                        } else {
                    348:                                outrel(locxp, reloc_how);
                    349:                        }
                    350:                } else {
                    351:                        /*
                    352:                         *      
                    353:                         *      See if we are doing a case instruction.
                    354:                         *      If so, then see if the branch distance,
                    355:                         *      stored as a word,
                    356:                         *      is going to loose sig bits.
                    357:                         */
                    358:                        if (passno == 2 && incasetable){
                    359:                                if (  (locxp->e_xvalue < -32768)
                    360:                                    ||(locxp->e_xvalue > 32767)){
                    361:                                        yyerror("Case will branch too far");
                    362:                                }
                    363:                        }
                    364:                        field_value = locxp->e_xvalue & ( (1L << field_width)-1);
                    365:                        bitfield |= field_value << bitoff;
                    366:                        bitoff += field_width;
                    367:                }
                    368:                xp = explist;
                    369:                if (auxval = (val == CM))
                    370:                        shift;
                    371:            } while (auxval);
                    372:        }       /* there existed an expression at all */
                    373: 
                    374:        flushfield(curlen);
                    375:        if ( ( curlen == NBWD/4) && bitoff)
                    376:                dotp->e_xvalue ++;
                    377:        break;
                    378:        /*end of case IBYTE, IWORD, ILONG, IINT*/
                    379: 
                    380:    case ISPACE:        /* .space <expr> */
                    381:        shift;
                    382:        expr(locxp, val);
                    383:        if ((locxp->e_xtype & XTYPE) != XABS)   /* tekmdp */
                    384:                yyerror("Space size not absolute");
                    385:        space_value = locxp->e_xvalue;
                    386:   ospace:
                    387:        flushfield(NBWD/4);
                    388:        {
                    389:                static char spacebuf[128];
                    390:                while (space_value > sizeof(spacebuf)){
                    391:                        outs(spacebuf, sizeof(spacebuf));
                    392:                        space_value -= sizeof(spacebuf);
                    393:                }
                    394:                outs(spacebuf, space_value);
                    395:        }
                    396:        break;
                    397: 
                    398:        /*
                    399:         *      .fill rep, size, value
                    400:         *      repeat rep times: fill size bytes with (truncated) value
                    401:         *      size must be between 1 and 8
                    402:         */
                    403:    case        IFILL:
                    404:        shift;
                    405:        expr(locxp, val);
                    406:        if ( (locxp->e_xtype & XTYPE) != XABS)  /* tekmdp */
                    407:                yyerror("Fill repetition count not absolute");
                    408:        fill_rep = locxp->e_xvalue;
                    409:        shiftover(CM);
                    410:        expr(locxp, val);
                    411:        if ( (locxp->e_xtype & XTYPE) != XABS)  /* tekmdp */
                    412:                yyerror("Fill size not absolute");
                    413:        fill_size = locxp->e_xvalue;
                    414:        if (fill_size <= 0 || fill_size > 8)
                    415:                yyerror("Fill count not in in 1..8");
                    416:        shiftover(CM);
                    417:        expr(locxp, val);
                    418:        if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS)    /* tekmdp */
                    419:                yyerror("Fill value not absolute");
                    420:        flushfield(NBWD/4);
                    421:        dotp->e_xvalue += fill_rep * fill_size;
                    422:        if (passno == 2) {
                    423:                while(fill_rep-- > 0)
                    424:                        bwrite((char *)&locxp->e_xvalue, fill_size, txtfil);
                    425:        }
                    426:        break;
                    427: 
                    428:    case IASCII:                /* .ascii [ <stringlist> ] */
                    429:    case IASCIZ:        /* .asciz [ <stringlist> ] */
                    430:        auxval = val;
                    431:        shift;
                    432:        /*
                    433:         *      Code to consume a string list
                    434:         *
                    435:         *      stringlist: empty | STRING | stringlist STRING
                    436:         */
                    437:        while (val == STRING){
                    438:                int     mystrlen;
                    439:                flushfield(NBWD/4);
                    440:                if (bitoff)
                    441:                        dotp->e_xvalue++;
                    442:                stringp = (struct strdesc *)yylval;
                    443:                /*
                    444:                 *      utilize the string scanner cheat;
                    445:                 *      the scanner appended a null byte on the string,
                    446:                 *      but didn't charge it to sd_strlen
                    447:                 */
                    448:                mystrlen = stringp->sd_strlen;
                    449:                mystrlen += (auxval == IASCIZ) ? 1 : 0;
                    450:                if (passno == 2){
                    451:                        if (stringp->sd_place & STR_CORE){
                    452:                                outs(stringp->sd_string, mystrlen);
                    453:                        } else {
                    454:                                int     i, nread;
                    455:                                fseek(strfile, stringp->sd_stroff, 0);
                    456:                                for (i = 0; i < mystrlen;/*VOID*/){
                    457:                                        nread = fread(yytext, 1,
                    458:                                                min(mystrlen - i,
                    459:                                                  sizeof(yytext)), strfile);
                    460:                                        outs(yytext, nread);
                    461:                                        i += nread;
                    462:                                }
                    463:                        }
                    464:                } else {
                    465:                        dotp->e_xvalue += mystrlen;
                    466:                }
                    467:                shift;          /*over the STRING*/
                    468:                if (val == CM)  /*could be a split string*/
                    469:                        shift;
                    470:        }
                    471:        break;
                    472:        
                    473:    case IORG:  /* .org <expr> */
                    474:        shift;
                    475:        expr(locxp, val);
                    476: 
                    477:        if ((locxp->e_xtype & XTYPE) == XABS)   /* tekmdp */
                    478:                orgwarn++;
                    479:        else if ((locxp->e_xtype & ~XXTRN) != dotp->e_xtype)
                    480:                yyerror("Illegal expression to set origin");
                    481:        space_value = locxp->e_xvalue - dotp->e_xvalue;
                    482:        if (space_value < 0)
                    483:                yyerror("Backwards 'org'");
                    484:        goto ospace;
                    485:        break;
                    486: 
                    487: /*
                    488:  *
                    489:  *     Process stabs.  Stabs are created only by the f77
                    490:  *     and the C compiler with the -g flag set.
                    491:  *     We only look at the stab ONCE, during pass 1, and
                    492:  *     virtually remove the stab from the intermediate file
                    493:  *     so it isn't seen during pass2.  This makes for some
                    494:  *     hairy processing to handle labels occuring in
                    495:  *     stab entries, but since most expressions in the
                    496:  *     stab are integral we save lots of time in the second
                    497:  *     pass by not looking at the stabs.
                    498:  *     A stab that is tagged floating will be bumped during
                    499:  *     the jxxx resolution phase.  A stab tagged fixed will
                    500:  *     not be be bumped.
                    501:  *
                    502:  *     .stab:  Old fashioned stabs
                    503:  *     .stabn: For stabs without names
                    504:  *     .stabs: For stabs with string names
                    505:  *     .stabd: For stabs for line numbers or bracketing,
                    506:  *             without a string name, without
                    507:  *             a final expression.  The value of the
                    508:  *             final expression is taken to be  the current
                    509:  *             location counter, and is patched by the 2nd pass
                    510:  *
                    511:  *     .stab{<expr>,}*NCPName,<expr>, <expr>, <expr>, <expr>
                    512:  *     .stabn           <expr>, <expr>, <expr>, <expr>
                    513:  *     .stabs   STRING, <expr>, <expr>, <expr>, <expr>
                    514:  *     .stabd           <expr>, <expr>, <expr> # . 
                    515:  */
                    516:    case ISTAB: 
                    517:        yyerror(".stab directive no longer supported");
                    518:        goto errorfix;
                    519: 
                    520:   tailstab:
                    521:        expr(locxp, val);
                    522:        if (! (locxp->e_xvalue & STABTYPS)){
                    523:                yyerror("Invalid type in %s", stabname);
                    524:                goto errorfix;
                    525:        }
                    526:        stpt->s_ptype = locxp->e_xvalue;
                    527:        shiftover(CM);
                    528:        expr(locxp, val);
                    529:        stpt->s_other = locxp->e_xvalue;
                    530:        shiftover(CM);
                    531:        expr(locxp, val);
                    532:        stpt->s_desc = locxp->e_xvalue;
                    533:        shiftover(CM);
                    534:        exprisname = 0;
                    535:        expr(locxp, val);
                    536:        p = locxp->e_xname;
                    537:        if (p == NULL) {        /*absolute expr to begin with*/
                    538:                stpt->s_value = locxp->e_xvalue;
                    539:                stpt->s_index = dotp - usedot;
                    540:                if (exprisname){
                    541:                        stpt->s_type = locxp->e_xtype;
                    542:                        switch(stpt->s_ptype){
                    543:                                case N_LCSYM:
                    544:                                        stpt->s_dest = (struct symtab *)exprisname;
                    545:                                        stpt->s_type |= STABFLAG;
                    546:                                case N_GSYM:
                    547:                                case N_FNAME:
                    548:                                case N_RSYM:
                    549:                                case N_SSYM:
                    550:                                case N_LSYM:
                    551:                                case N_PSYM:
                    552:                                case N_BCOMM:
                    553:                                case N_ECOMM:
                    554:                                case N_LENG:
                    555:                                        stpt->s_tag = STABFIXED;
                    556:                                        break;
                    557:                                default:
                    558:                                        stpt->s_tag = STABFLOATING;
                    559:                                        break;
                    560:                        }
                    561:                } else
                    562:                        stpt->s_tag = STABFIXED;
                    563:        }
                    564:        else {          /*really have a name*/
                    565:                stpt->s_dest = locxp->e_xname;
                    566:                stpt->s_index = p->s_index;
                    567:                stpt->s_type = p->s_type | STABFLAG;
                    568:                /*
                    569:                 *      We will assign a more accruate
                    570:                 *      guess of locxp's location when
                    571:                 *      we sort the symbol table
                    572:                 *      The final value of value is
                    573:                 *      given by stabfix()
                    574:                 */
                    575: /*
                    576:  * For exprs of the form (name + value) one needs to remember locxp->e_xvalue
                    577:  * for use in stabfix. The right place to keep this is in stpt->s_value
                    578:  * however this gets corrupted at an unknown point.
                    579:  * As a bandaid hack the value is preserved in s_desc and s_other (a
                    580:  * short and a char). This destroys these two values and will
                    581:  * be fixed. May 19 ,1983 Alastair Fyfe
                    582:  */
                    583:                if(locxp->e_xvalue) {
                    584:                        stpt->s_other = (locxp->e_xvalue >> 16);
                    585:                        stpt->s_desc =  (locxp->e_xvalue  & 0x0000ffff);
                    586:                        stpt->s_tag = STABFLOATING;
                    587:                }
                    588:        }
                    589:        /*
                    590:         *      tokptr now points at one token beyond
                    591:         *      the current token stored in val and yylval,
                    592:         *      which are the next tokens after the end of
                    593:         *      this .stab directive.  This next token must
                    594:         *      be either a SEMI or NL, so is of width just
                    595:         *      one.  Therefore, to point to the next token
                    596:         *      after the end of this stab, just back up one..
                    597:         */
                    598:        buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
                    599:        break;  /*end of the .stab*/
                    600: 
                    601:    case ISTABDOT:      
                    602:        stabname = ".stabd";
                    603:        stpt = (struct symtab *)yylval;
                    604:        /*
                    605:         *      We clobber everything after the
                    606:         *      .stabd and its pointer... we MUST
                    607:         *      be able to get back to this .stabd
                    608:         *      so that we can resolve its final value
                    609:         */
                    610:        stabstart = tokptr;
                    611:        shift;          /*over the ISTABDOT*/
                    612:        if (passno == 1){
                    613:                expr(locxp, val);
                    614:                if (! (locxp->e_xvalue & STABTYPS)){
                    615:                        yyerror("Invalid type in .stabd");
                    616:                        goto errorfix;
                    617:                }
                    618:                stpt->s_ptype = locxp->e_xvalue;
                    619:                shiftover(CM);
                    620:                expr(locxp, val);
                    621:                stpt->s_other = locxp->e_xvalue;
                    622:                shiftover(CM);
                    623:                expr(locxp, val);
                    624:                stpt->s_desc = locxp->e_xvalue;
                    625:                /*
                    626:                 *
                    627:                 *      Now, clobber everything but the
                    628:                 *      .stabd pseudo and the pointer
                    629:                 *      to its symbol table entry
                    630:                 *      tokptr points to the next token,
                    631:                 *      build the skip up to this
                    632:                 */
                    633:                buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
                    634:        }
                    635:        /*
                    636:         *      pass 1: Assign a good guess for its position
                    637:         *              (ensures they are sorted into right place)/
                    638:         *      pass 2: Fix the actual value
                    639:         */
                    640:        stpt->s_value = dotp->e_xvalue;
                    641:        stpt->s_index = dotp - usedot;
                    642:        stpt->s_tag = STABFLOATING;     /*although it has no effect in pass 2*/
                    643:        break;
                    644: 
                    645:    case ISTABNONE:     stabname = ".stabn"; goto shortstab;
                    646: 
                    647:    case ISTABSTR:      stabname = ".stabs";
                    648:    shortstab:
                    649:        auxval = val;
                    650:        if (passno == 2) goto errorfix;
                    651:        stpt = (struct symtab *)yylval;
                    652:        stabstart = tokptr;
                    653:        (bytetoktype *)stabstart -= sizeof(struct symtab *);
                    654:        (bytetoktype *)stabstart -= sizeof(bytetoktype);
                    655:        shift;
                    656:        if (auxval == ISTABSTR){
                    657:                stringp = (struct strdesc *)yylval;
                    658:                shiftover(STRING);
                    659:                stpt->s_name = (char *)stringp;
                    660:                /*
                    661:                 *      We want the trailing null included in this string.
                    662:                 *      We utilize the cheat the string scanner used,
                    663:                 *      and merely increment the string length
                    664:                 */
                    665:                stringp->sd_strlen += 1;
                    666:                shiftover(CM);
                    667:        } else {
                    668:                stpt->s_name = (char *)savestr("\0", 0, STR_BOTH);
                    669:        }
                    670:        goto tailstab;
                    671:        break;
                    672: 
                    673:    case ICOMM:         /* .comm  <name> , <expr> */
                    674:    case ILCOMM:        /* .lcomm <name> , <expr> */
                    675:        auxval = val;
                    676:        shift;
                    677:        np = (struct symtab *)yylval;
                    678:        shiftover(NAME);
                    679:        shiftover(CM);
                    680:        expr(locxp, val);
                    681: 
                    682:        if ( (locxp->e_xtype & XTYPE) != XABS)  /* tekmdp */
                    683:                yyerror("comm size not absolute");
                    684:        if (passno == 1 && (np->s_type&XTYPE) != XUNDEF)
                    685:                yyerror("Redefinition of %s", FETCHNAME(np));
                    686:        if (passno==1) {
                    687:                np->s_value = locxp->e_xvalue;
                    688:                if (auxval == ICOMM)
                    689:                        np->s_type |= XXTRN;
                    690:                else {
                    691:                        np->s_type &= ~XTYPE;
                    692:                        np->s_type |= XBSS;
                    693:                }
                    694:        }
                    695:        break;
                    696: 
                    697:    case IALIGN:                /* .align <expr> */
                    698:        stpt = (struct symtab *)yylval;
                    699:        shift;
                    700:        expr(locxp, val);
                    701:        jalign(locxp, stpt);
                    702:        break;
                    703: 
                    704:    case INST0:                 /* instructions w/o arguments*/
                    705:        incasetable = 0;
                    706:        insout(yyopcode, (struct arg *)0, 0);
                    707:        shift;  
                    708:        break;
                    709: 
                    710:    case INSTn:         /* instructions with arguments*/
                    711:    case IJXXX:                 /* UNIX style jump instructions */
                    712:        auxval = val;
                    713:        /*
                    714:         *      Code to process an argument list
                    715:         */
                    716:        ap = arglist;
                    717:        xp = explist;   
                    718: 
                    719:        shift;          /* bring in the first token for the arg list*/
                    720: 
                    721:        for (argcnt = 1; argcnt <= 6; argcnt++, ap++){
                    722:                /*
                    723:                 *      code to process an argument proper
                    724:                 */
                    725:            sawindex  = sawmul = sawsize = 0;
                    726:            {
                    727:                switch(val) {
                    728: 
                    729:                   default:
                    730:                     disp:
                    731:                        if( !(INTOKSET(val,
                    732:                                 EBEGOPS
                    733:                                +YUKKYEXPRBEG
                    734:                                +SAFEEXPRBEG)) ) {
                    735:                                ERROR("expression expected");
                    736:                        }
                    737:                        expr(ap->a_xp,val);
                    738:                     overdisp:
                    739:                        if ( val == LP || sawsize){
                    740:                                shiftover(LP);
                    741:                                findreg(regno);
                    742:                                shiftover(RP);
                    743:                                ap->a_atype = ADISP;
                    744:                                ap->a_areg1 = regno;
                    745:                        } else {
                    746:                                ap->a_atype = AEXP;
                    747:                                ap->a_areg1 = 0;
                    748:                        }
                    749:                        goto index;
                    750: 
                    751:                   case SIZESPEC: 
                    752:                     sizespec:
                    753:                        sawsize = yylval;
                    754:                        shift;
                    755:                        goto disp;
                    756: 
                    757:                   case REG:
                    758:                   case REGOP: 
                    759:                        findreg(regno);
                    760:                        ap->a_atype = AREG;
                    761:                        ap->a_areg1 = regno;
                    762:                        break;
                    763:                    
                    764:                   case MUL: 
                    765:                        sawmul = 1;
                    766:                        shift;
                    767:                        if (val == LP) goto base;
                    768:                        if (val == LITOP) goto imm;
                    769:                        if (val == SIZESPEC) goto sizespec;
                    770:                        if (INTOKSET(val,
                    771:                                 EBEGOPS
                    772:                                +YUKKYEXPRBEG
                    773:                                +SAFEEXPRBEG)) goto disp;
                    774:                        ERROR("expression, '(' or '$' expected");
                    775:                        break;
                    776: 
                    777:                   case LP: 
                    778:                     base:
                    779:                        shift;  /*consume the LP*/
                    780:                        /*
                    781:                         *      hack the ambiguity of
                    782:                         *      movl (expr) (rn), ...
                    783:                         *      note that (expr) could also
                    784:                         *      be (rn) (by special hole in the
                    785:                         *      grammar), which we ensure
                    786:                         *      means register indirection, instead
                    787:                         *      of an expression with value n
                    788:                         */
                    789:                        if (val != REG && val != REGOP){
                    790:                                droppedLP = 1;
                    791:                                val = exprparse(val, &(ap->a_xp));
                    792:                                droppedLP = 0;
                    793:                                goto overdisp;
                    794:                        }
                    795:                        findreg(regno);
                    796:                        shiftover(RP);
                    797:                        if (val == PLUS){
                    798:                                shift;
                    799:                                ap->a_atype = AINCR;
                    800:                        } else
                    801:                                ap->a_atype = ABASE;
                    802:                        ap->a_areg1 = regno;
                    803:                        goto index;
                    804: 
                    805:                   case LITOP: 
                    806:                      imm:
                    807:                        shift;
                    808:                        expr(locxp, val);
                    809:                        ap->a_atype = AIMM;
                    810:                        ap->a_areg1 = 0;
                    811:                        ap->a_xp = locxp;
                    812:                        goto index;
                    813: 
                    814:                   case MP: 
                    815:                        shift;  /* -(reg) */
                    816:                        findreg(regno);
                    817:                        shiftover(RP);
                    818:                        ap->a_atype = ADECR;
                    819:                        ap->a_areg1 = regno;
                    820:          index:                        /*look for [reg] */
                    821:                        if (val == LB){
                    822:                                shift;
                    823:                                findreg(regno);
                    824:                                shiftover(RB);
                    825:                                sawindex = 1;
                    826:                                ap->a_areg2 = regno;
                    827:                        }
                    828:                        break;
                    829: 
                    830:                }       /*end of the switch to process an arg*/
                    831:            }   /*end of processing an argument*/
                    832: 
                    833:            if (sawmul){
                    834:                        /*
                    835:                         * Make a concession for *(%r)
                    836:                         * meaning *0(%r) 
                    837:                         */
                    838:                        if (ap->a_atype == ABASE) {
                    839:                                ap->a_atype = ADISP;
                    840:                                xp->e_xtype = XABS;
                    841:                                xp->e_number = Znumber;
                    842:                                xp->e_number.num_tag = TYPL;
                    843:                                xp->e_xloc = 0;
                    844:                                ap->a_xp = xp++;
                    845:                        }
                    846:                        ap->a_atype |= ASTAR;
                    847:                        sawmul = 0;
                    848:            }
                    849:            if (sawindex){
                    850:                ap->a_atype |= AINDX;
                    851:                sawindex = 0;
                    852:            }
                    853:            ap->a_dispsize = sawsize == 0 ? d124 : sawsize;
                    854:                if (val != CM) break;
                    855:                shiftover(CM);
                    856:        }       /*processing all the arguments*/
                    857: 
                    858:        if (argcnt > 6){
                    859:                yyerror("More than 6 arguments");
                    860:                goto errorfix;
                    861:        }
                    862: 
                    863:        /*
                    864:         *      See if this is a case instruction,
                    865:         *      so we can set up tests on the following
                    866:         *      vector of branch displacements
                    867:         */
                    868:        if (yyopcode.Op_eopcode == CORE){
                    869:                switch(yyopcode.Op_popcode){
                    870:                case 0x8f:      /* caseb */
                    871:                case 0xaf:      /* casew */
                    872:                case 0xcf:      /* casel */
                    873:                        incasetable++;
                    874:                        break;
                    875:                default:
                    876:                        incasetable = 0;
                    877:                        break;
                    878:                }
                    879:        }
                    880: 
                    881:        insout(yyopcode, arglist,
                    882:                auxval == INSTn ? argcnt : - argcnt);
                    883:        break;
                    884: 
                    885:    case IQUAD:         toconv = TYPQ;  goto bignumlist;
                    886:    case IOCTA:         toconv = TYPO;  goto bignumlist;
                    887: 
                    888:    case IFFLOAT:       toconv = TYPF;  goto bignumlist;
                    889:    case IDFLOAT:       toconv = TYPD;  goto bignumlist;
                    890:    case IGFLOAT:       toconv = TYPG;  goto bignumlist;
                    891:    case IHFLOAT:       toconv = TYPH;  goto bignumlist;
                    892:    bignumlist: 
                    893:        /*
                    894:         *      eat a list of non 32 bit numbers.
                    895:         *      IQUAD and IOCTA can, possibly, return
                    896:         *      INT's, if the numbers are "small".
                    897:         *
                    898:         *      The value of the numbers is coming back
                    899:         *      as an expression, NOT in yybignum.
                    900:         */
                    901:        shift;  /* over the opener */
                    902:        if ((val == BIGNUM) || (val == INT)){
                    903:                do{
                    904:                        if ((val != BIGNUM) && (val != INT)){
                    905:                                ERROR(ty_float[toconv]
                    906:                                   ? "floating number expected"
                    907:                                   : "integer number expected" );
                    908:                        }
                    909:                        dotp->e_xvalue += ty_nbyte[toconv];
                    910:                        if (passno == 2){
                    911:                                bignumwrite(
                    912:                                        ((struct exp *)yylval)->e_number,
                    913:                                        toconv);
                    914:                        }
                    915:                        xp = explist;
                    916:                        shift;          /* over this number */
                    917:                        if (auxval = (val == CM))
                    918:                                shift;  /* over the comma */
                    919:                } while (auxval);       /* as long as there are commas */
                    920:        }
                    921:        break;
                    922:        /* end of the case for initialized big numbers */
                    923:     }  /*end of the switch for looking at each reserved word*/
                    924: 
                    925:        continue;
                    926: 
                    927:    errorfix: 
                    928:        /*
                    929:         *      got here by either requesting to skip to the
                    930:         *      end of this statement, or by erroring out and
                    931:         *      wanting to apply panic mode recovery
                    932:         */
                    933:        while (    (val != NL) 
                    934:                && (val != SEMI) 
                    935:                && (val != PARSEEOF)
                    936:              ){
                    937:                shift;
                    938:        }
                    939:        if (val == NL)
                    940:                lineno++;
                    941:        shift;
                    942: 
                    943:     }  /*end of the loop to read the entire file, line by line*/
                    944: 
                    945: }      /*end of yyparse*/
                    946:        
                    947: /*
                    948:  *     Process a register declaration of the form
                    949:  *     % <expr>
                    950:  *
                    951:  *     Note:
                    952:  *             The scanner has already processed funny registers of the form
                    953:  *     %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional
                    954:  *     preceding zero digit).  If there was any space between the % and
                    955:  *     the digit, the scanner wouldn't have recognized it, so we
                    956:  *     hack it out here.
                    957:  */
                    958: inttoktype funnyreg(val, regnoback)    /*what the read head will sit on*/
                    959:        inttoktype      val;            /*what the read head is sitting on*/
                    960:        int     *regnoback;             /*call by return*/
                    961: {
                    962:        reg     struct  exp *locxp;
                    963:                struct  exp *loc1xp;
                    964:                struct  exp **ptrloc1xp = & loc1xp;
                    965: 
                    966:        expr(locxp, val);       /*and leave the current read head with value*/
                    967:        if ( (passno == 2) &&
                    968:            (   (locxp->e_xtype & XTYPE) != XABS
                    969:             || (locxp->e_xvalue < 0)
                    970:             || (locxp->e_xvalue >= 16)
                    971:            )
                    972:          ){
                    973:                yyerror("Illegal register");
                    974:                return(0);
                    975:        }
                    976:        *regnoback = locxp->e_xvalue;
                    977:        return(val);
                    978: } 
                    979: /*
                    980:  *     Shift over error
                    981:  */
                    982: shiftoerror(token)
                    983:        int     token;
                    984: {
                    985:        char    *tok_to_name();
                    986:        yyerror("%s expected", tok_to_name(token));
                    987: }
                    988: 
                    989: /*VARARGS1*/
                    990: yyerror(s, a1, a2,a3,a4,a5)
                    991:        char    *s;
                    992: {
                    993: 
                    994: #define        sink stdout
                    995: 
                    996:        if (anyerrs == 0 && anywarnings == 0 && ! silent) 
                    997:                fprintf(sink, "Assembler:\n");
                    998:        anyerrs++;
                    999:        if (silent)
                   1000:                return;
                   1001:        fprintf(sink, "\"%s\", line %d: ", dotsname, lineno);
                   1002:        fprintf(sink, s, a1, a2,a3,a4,a5);
                   1003:        fprintf(sink, "\n");
                   1004: #undef sink
                   1005: }
                   1006: 
                   1007: /*VARARGS1*/
                   1008: yywarning(s, a1, a2,a3,a4,a5)
                   1009:        char    *s;
                   1010: {
                   1011: #define        sink stdout
                   1012:        if (anyerrs == 0 && anywarnings == 0 && ! silent) 
                   1013:                fprintf(sink, "Assembler:\n");
                   1014:        anywarnings++;
                   1015:        if (silent)
                   1016:                return;
                   1017:        fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno);
                   1018:        fprintf(sink, s, a1, a2,a3,a4,a5);
                   1019:        fprintf(sink, "\n");
                   1020: #undef sink
                   1021: }

unix.superglobalmegacorp.com

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