Annotation of 3BSD/cmd/as/asparse.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #include <stdio.h>
                      3: #include <a.out.h>
                      4: #include "as.h"
                      5: #include "asexpr.h"
                      6: #include "asscan.h"
                      7: #include "assyms.h"
                      8: 
                      9: extern struct  exp     usedot[];/*information on the dot for each seg*/
                     10: struct exp     *dotp = &usedot[0];     /*current dot*/
                     11: int    anyerrs;
                     12: 
                     13: int    passno  = 1;
                     14: 
                     15: FILE   *tmpfil;
                     16: FILE   *relfil;                /*relocation info sent here*/
                     17: FILE   *txtfil;                /*text (for any text #) sent here*/
                     18: 
                     19: int    hshused;                /*hash slots consumed */
                     20: long   tsize;
                     21: long   dsize;
                     22: 
                     23: long   bitfield;
                     24: int    bitoff;
                     25: 
                     26: /*
                     27:  *     The following three variables are communication between various
                     28:  *     modules to special case a number of things.  They are properly
                     29:  *     categorized as hacks.
                     30:  */
                     31: struct symtab *lastnam;        /*last name seen by the lexical analyzer*/
                     32: int    exprisname;             /*last factor in an expression was a name*/
                     33: int    droppedLP;              /*one is analyzing an expression beginning with*/
                     34:                                /*a left parenthesis, which has already been*/
                     35:                                /*shifted. (Used to parse (<expr>)(rn)*/
                     36: 
                     37: char   yytext[NCPS+2];
                     38: static char    Dotsname[32];
                     39: 
                     40: struct exp     *xp;            /*next free expression slot, used by expr.c*/
                     41: 
                     42: int    yylval;                 /*the lexical value; sloppy typing*/
                     43: 
                     44: extern         ptrall tokptr;  /*points to current token being eaten*/
                     45: extern int     d124;
                     46: 
                     47: int    yyparse()
                     48: {
                     49:        register        struct  exp     *locxp;
                     50:                        /*
                     51:                         *      loc1xp and ptrloc1xp are used in the
                     52:                         *      expression lookahead
                     53:                         */
                     54:                        struct  exp     *loc1xp;        /*must be non register*/
                     55:                        struct  exp     **ptrloc1xp = & loc1xp;
                     56:                        struct  exp     *pval;          /*hacking expr:expr*/
                     57: 
                     58:        register        struct  symtab  *np;
                     59:        register        int             argcnt;
                     60: 
                     61:        register        int             val;            /*what yylex gives*/
                     62:        register        int             auxval;         /*saves val*/
                     63: 
                     64:        register        struct  arg     *ap;            /*first free argument*/
                     65: 
                     66:                        struct  symtab  *p;
                     67:        register        struct  symtab  *stpt;
                     68: 
                     69:                        struct  strdesc *stringp;       /*handles string lists*/
                     70: 
                     71:                        int             regno;          /*handles arguments*/
                     72:                        int             *ptrregno = &regno;
                     73:                        int             sawmul;         /*saw * */
                     74:                        int             sawindex;       /*saw [rn]*/
                     75:                        int             sawsize;
                     76:                        int             seg_type;       /*the kind of segment: data or text*/
                     77:                        int             seg_number;     /*the segment number*/
                     78:                        long            space_value;    /*how much .space needs*/
                     79: 
                     80:                        int             field_width;    /*how wide a field is to be*/
                     81:                        int             field_value;    /*the value to stuff in a field*/
                     82:                        char            *stabname;      /*name of stab dealing with*/
                     83:                        ptrall          stabstart;      /*where the stab starts in the buffer*/
                     84: 
                     85:        xp = explist;
                     86:        ap = arglist;
                     87: 
                     88:        val = yylex();
                     89:        while (val != PARSEEOF){
                     90:                while (INTOKSET(val, LINSTBEGIN)){
                     91:                        if (val == NL){
                     92:                                lineno++;
                     93:                                shift;
                     94:                        } else
                     95:                        if (val == SEMI) 
                     96:                                shift;
                     97:                        else {  /*its a name, so we have a label (hopefully*/
                     98:                                if (val != NAME){
                     99:                                        ERROR("Name expected for a label");
                    100:                                }
                    101:                                np = (struct symtab *)yylval;
                    102:                                shiftover(NAME);
                    103:                                shiftover(COLON);
                    104:                                flushfield(NBPW/4);
                    105:                                if ((np->type&XTYPE)!=XUNDEF) {
                    106:                                        if(  (np->type&XTYPE)!=dotp->xtype 
                    107:                                           || np->value!=dotp->xvalue
                    108:                                           || (  (passno==1)
                    109:                                               &&(np->index != dotp->xloc)
                    110:                                              )
                    111:                                          ){
                    112: #ifndef DEBUG
                    113:                                                if (np->name[0] != 'L')
                    114: #endif
                    115:                                                {
                    116:                                                        yyerror("%.8s redefined", np->name);
                    117: #ifdef DEBUG
                    118:                                                        printf("name.value=%d, dotp->xvalue=%d\n",
                    119:                                                        np->value, dotp->xvalue);
                    120: #endif
                    121:                                                }
                    122:                                        }
                    123:                                }
                    124:                                np->type &= ~(XTYPE|XFORW);
                    125:                                np->type |= dotp->xtype;
                    126:                                np->value = dotp->xvalue;
                    127:                                if (passno == 1){
                    128:                                        np->index = dotp-usedot;
                    129:                                        if (np->name[0] == 'L'){
                    130:                                                nlabels++;
                    131:                                        }
                    132:                                        np->tag = LABELID;
                    133:                                }
                    134:                        }       /*end of this being a label*/
                    135:                }       /*end of to consuming all labels, NLs and SEMIS */ 
                    136: 
                    137:                xp = explist;
                    138:                ap = arglist;
                    139: 
                    140:                /*
                    141:                 *      process the INSTRUCTION body
                    142:                 */
                    143:            switch(val){
                    144:                default:
                    145:                        ERROR("Unrecognized instruction or directive");
                    146: 
                    147:                case IABORT:
                    148:                        shift;
                    149:                        sawabort();
                    150:                        /*NOTREACHED*/
                    151:                        break;
                    152: 
                    153:                case PARSEEOF:
                    154:                        tokptr -= sizeof(toktype);
                    155:                        *tokptr++ = VOID;
                    156:                        tokptr[1] = VOID;
                    157:                        tokptr[2] = PARSEEOF;
                    158:                        break;
                    159:                
                    160:                case IFILE:
                    161:                        shift;
                    162:                        stringp = (struct strdesc *)yylval;
                    163:                        shiftover(STRING);
                    164:                        dotsname = &Dotsname[0];
                    165:                        movestr(dotsname, stringp->str,
                    166:                                stringp->str_lg >= 32? 32 :stringp->str_lg);
                    167:                        dotsname[stringp->str_lg] = '\0';
                    168: #ifdef DEBUG
                    169:                        if (debug)
                    170:                                printf("(from parser) Now considered to be in file %s\n",
                    171:                                        dotsname);
                    172: #endif
                    173:                        break;
                    174:                
                    175:                case ILINENO:
                    176:                        shift;          /*over the ILINENO*/
                    177:                        expr(locxp, val);
                    178:                        lineno = locxp->xvalue;
                    179: #ifdef DEBUG
                    180:                        if (debug)
                    181:                                printf("Now considered to be on line number %d\n",
                    182:                                lineno);
                    183: #endif
                    184:                        break;
                    185: 
                    186:                case ISET: {    /* .set  <name> , <expr> */
                    187:                        shift;
                    188:                        np = (struct symtab *)yylval;
                    189:                        shiftover(NAME);
                    190:                        shiftover(CM);
                    191:                        expr(locxp, val);
                    192:                        np->type &= (XXTRN|XFORW);
                    193:                        np->type |= locxp->xtype&(XTYPE|XFORW);
                    194:                        np->value = locxp->xvalue;
                    195:                        if (passno==1)
                    196:                                np->index = locxp->xloc;
                    197:                        if ((locxp->xtype&XTYPE) == XUNDEF)
                    198:                                yyerror("Illegal set?");
                    199:                        break;
                    200:                }       /*end of case ISET*/
                    201: 
                    202:                case ILSYM: {   /*.lsym name , expr */
                    203:                        shift;
                    204:                        np = (struct symtab *)yylval;
                    205:                        shiftover(NAME);
                    206:                        shiftover(CM);
                    207:                        expr(locxp, val);
                    208:                        /*
                    209:                         *      Build the unique occurance of the
                    210:                         *      symbol.
                    211:                         *      The character scanner will have
                    212:                         *      already entered it into the symbol
                    213:                         *      table, but we should remove it
                    214:                         */
                    215:                        if (passno == 1){
                    216:                                stpt = (struct symtab *)symalloc();
                    217:                                movestr(stpt->name, np->name, NCPS);
                    218:                                np->tag = OBSOLETE;     /*invalidate original */
                    219:                                nforgotten++;
                    220:                                np = stpt;
                    221:                                if (locxp->xtype != XABS) 
                    222:                                        ("Illegal lsym");
                    223:                                np->value=locxp->xvalue;
                    224:                                np->type=XABS;
                    225:                                np->tag = ILSYM;
                    226:                        }
                    227:                        break;
                    228:                }       /*end of case ILSYM*/
                    229: 
                    230:                case IGLOBAL: { /*.globl <name> */
                    231:                        shift;
                    232:                        np = (struct symtab *)yylval;
                    233:                        shiftover(NAME);
                    234:                        np->type |= XXTRN;
                    235:                        break;
                    236:                }       /*end of case IGLOBAL*/
                    237: 
                    238:                case IDATA:     /*.data [ <expr> ] */
                    239:                case ITEXT: {   /*.text [ <expr> ] */
                    240:                        seg_type = -val;
                    241:                        shift;
                    242:                        if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
                    243:                                expr(locxp, val);
                    244:                                seg_type = -seg_type;   /*now, it is positive*/
                    245:                        }
                    246: 
                    247:                        if (seg_type < 0) {     /*there wasn't an associated expr*/
                    248:                                seg_number = 0;
                    249:                                seg_type = -seg_type;
                    250:                        } else {
                    251:                                if (locxp->xtype != XABS || (seg_number=locxp->xvalue) >= NLOC) {
                    252:                                        yyerror("illegal location counter");
                    253:                                        seg_number = 0;
                    254:                                }
                    255:                        }
                    256:                        if (seg_type == IDATA)
                    257:                                seg_number += NLOC;
                    258:                        flushfield(NBPW/4);
                    259:                        dotp = &usedot[seg_number];
                    260:                        if (passno==2) {        /* go salt away in pass 2*/
                    261:                                if (usefile[seg_number] == NULL) {
                    262:                                        tmpn2[TMPC] = 'a'+seg_number;
                    263:                                        if ((usefile[seg_number] =
                    264:                                           fopen(tmpn2, "w"))==NULL) {
                    265:                                                yyerror("cannot create temp %s", tmpn2);
                    266:                                                delexit();
                    267:                                        }
                    268: 
                    269:                                        tmpn3[TMPC] = 'a'+seg_number;
                    270:                                        if ((rusefile[seg_number] =
                    271:                                           fopen(tmpn3, "w"))==NULL) {
                    272: 
                    273:                                                yyerror("cannot create temp %s",
                    274:                                                   tmpn3);
                    275:                                        }
                    276:                                }
                    277:                                txtfil = usefile[seg_number];
                    278:                                relfil = rusefile[seg_number];
                    279:                        }
                    280: 
                    281:                        break;
                    282:                }       /*end of case .TEXT and .DATA*/
                    283: 
                    284:                /*
                    285:                 *      Storage filler directives:
                    286:                 *
                    287:                 *      .byte   [<exprlist>]
                    288:                 *
                    289:                 *      exprlist:  empty | exprlist outexpr
                    290:                 *      outexpr:   <expr> | <expr> : <expr>
                    291:                 */
                    292:                case IBYTE:     curlen = NBPW/4; goto elist;
                    293: 
                    294:                case IINT:
                    295:                case ILONG:     curlen = NBPW;   goto elist;
                    296: 
                    297:                case IWORD: {   
                    298:                        curlen = NBPW/2;
                    299:                   elist:
                    300:                        seg_type = val;
                    301:                        shift;
                    302: 
                    303:                        /*
                    304:                         *      This processes an expression list 
                    305:                         */
                    306:                        if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
                    307:                                do{
                    308:                                        /*
                    309:                                         *      expression list consists of a list of :
                    310:                                         *      <expr>
                    311:                                         *      <expr> : <expr> 
                    312:                                         *              (pack expr2 into expr1 bits
                    313:                                         */
                    314:                                        expr(locxp, val);
                    315:                                        /*
                    316:                                         *      now, pointing at the next token
                    317:                                         */
                    318:                                        if (val == COLON){
                    319:                                                shiftover(COLON);
                    320:                                                expr(pval, val);
                    321:                                                if (locxp->xtype != XABS)
                    322:                                                  yyerror("Width not absolute");
                    323:                                                field_width = locxp->xvalue;
                    324:                                                locxp = pval;
                    325:                                                if (bitoff + field_width >
                    326:                                                  curlen)
                    327:                                                        flushfield(curlen);
                    328:                                                if (field_width > curlen)
                    329:                                                        yyerror("Expression crosses field boundary");
                    330:                                        } /*value being colon*/
                    331:                                        else {
                    332:                                                field_width = curlen;
                    333:                                                flushfield(curlen);
                    334:                                        }
                    335: 
                    336:                                         if ((locxp->xtype&XTYPE)!=XABS) {
                    337:                                                if (bitoff)
                    338:                                                        yyerror("Illegal relocation in field");
                    339:                                                field_width=LEN1+!PCREL;
                    340:                                                if (curlen==NBPW)
                    341:                                                        field_width = LEN4 + !PCREL;
                    342:                                                if (curlen==NBPW/2)
                    343:                                                        field_width = LEN2 + !PCREL;
                    344:                                                /*
                    345:                                                 *      Save relocation information for this non absolute
                    346:                                                 *      symbol:
                    347:                                                 *      pass 1: saves enough space for the value, and
                    348:                                                 *              fixes dotp.
                    349:                                                 *      pass 2: writes the address info in ld compatable
                    350:                                                 *              format onto one of the relfiles
                    351:                                                 */
                    352:                                                outrel(&locxp->xvalue,
                    353:                                                        field_width,
                    354:                                                        locxp->xtype,
                    355:                                                        locxp->xname);
                    356:                                        } else {
                    357:                                                field_value = locxp->xvalue & ( (1L << field_width)-1);
                    358:                                                bitfield |= field_value << bitoff;
                    359:                                                bitoff += field_width;
                    360:                                        }
                    361:                                        if ( auxval = (val == CM)) shift;
                    362:                                } while (auxval);
                    363:                        }       /*existed an expression  at all*/
                    364: 
                    365:                        flushfield(curlen);
                    366:                        if ( ( curlen == NBPW/4) && bitoff)
                    367:                                dotp->xvalue ++;
                    368:                        break;
                    369:                }       /*end of case IBYTE, IWORD, ILONG, IINT*/
                    370:                
                    371:                case ISPACE: {  /* .space <expr> */
                    372:                        shift;
                    373:                        expr(locxp, val);
                    374:                        if (locxp->xtype != XABS)
                    375:                                yyerror("Space size not absolute");
                    376:                        space_value = locxp->xvalue;
                    377:                  ospace:
                    378:                        flushfield(NBPW/4);
                    379:                        while (space_value > 96){
                    380:                                outs(strbuf[2].str, 96);
                    381:                                space_value -= 96;
                    382:                        }
                    383:                        outs(strbuf[2].str, space_value);
                    384:                        break;
                    385:                }       /*end of case ISPACE*/
                    386:                
                    387:                case IASCII:    /* .ascii [ <stringlist> ] */
                    388:                case IASCIZ: {  /* .asciz [ <stringlist> ] */
                    389:                        auxval = val;
                    390:                        shift;
                    391: 
                    392:                        /*
                    393:                         *      Code to consume a string list
                    394:                         *
                    395:                         *      stringlist: empty | STRING | stringlist STRING
                    396:                         */
                    397:                        while (val ==  STRING){
                    398:                                flushfield(NBPW/4);
                    399:                                if (bitoff)
                    400:                                  dotp->xvalue++;
                    401:                                stringp = (struct strdesc *)yylval;
                    402:                                outs(stringp->str, stringp->str_lg);
                    403:                                shift;          /*over the STRING*/
                    404:                                if (val == CM)  /*could be a split string*/
                    405:                                        shift;
                    406:                        }
                    407: 
                    408:                        if (auxval == IASCIZ){
                    409:                                flushfield(NBPW/4);
                    410:                                outb(0);
                    411:                        }
                    412:                        break;
                    413:                }       /*end of case IASCII and IASIZ*/
                    414:                        
                    415:                case IORG: {    /* .org <expr> */
                    416:                        shift;
                    417:                        expr(locxp, val);
                    418: 
                    419:                        if (locxp->xtype==XABS)
                    420:                                orgwarn++;
                    421:                        else if (locxp->xtype!=dotp->xtype)
                    422:                                yyerror("Illegal expression to set origin");
                    423:                        space_value = locxp->xvalue - dotp->xvalue;
                    424:                        if (space_value < 0)
                    425:                                yyerror("Backwards 'org'");
                    426:                        goto ospace;
                    427:                        break;
                    428:                }       /*end of case IORG*/
                    429:                
                    430:                /*
                    431:                 *
                    432:                 *      Process stabs.  Stabs are created only by the f77
                    433:                 *      and the C compiler with the -g flag set.
                    434:                 *      We only look at the stab ONCE, during pass 1, and
                    435:                 *      virtually remove the stab from the intermediate file
                    436:                 *      so it isn't seen during pass2.  This makes for some
                    437:                 *      hairy processing to handle labels occuring in
                    438:                 *      stab entries, but since most expressions in the
                    439:                 *      stab are integral we save lots of time in the second
                    440:                 *      pass by not looking at the stabs.
                    441:                 *      A stab that is tagged floating will be bumped during
                    442:                 *      the jxxx resolution phase.  A stab tagged fixed will
                    443:                 *      not be be bumped.
                    444:                 *
                    445:                 *      .stab:  Old fashioned stabs
                    446:                 *      .stabn: For stabs without names
                    447:                 *      .stabs: For stabs with string names
                    448:                 *      .stabd: For stabs for line numbers or bracketing,
                    449:                 *              without a string name, without
                    450:                 *              a final expression.  The value of the
                    451:                 *              final expression is taken to be  the current
                    452:                 *              location counter, and is patched by the 2nd pass
                    453:                 *
                    454:                 *      .stab{<expr>,}*8,<expr>, <expr>, <expr>, <expr>
                    455:                 *      .stabn           <expr>, <expr>, <expr>, <expr>
                    456:                 *      .stabs   STRING, <expr>, <expr>, <expr>, <expr>
                    457:                 *      .stabd           <expr>, <expr>, <expr> # . 
                    458:                 */
                    459:                case ISTAB: {
                    460:                        stabname = ".stab";
                    461:                        if (passno == 2)        goto errorfix;
                    462:                        stpt = (struct symtab *)yylval;
                    463:                        /*
                    464:                         *      Make a pointer to the .stab slot.
                    465:                         *      There is a pointer in the way (stpt), and
                    466:                         *      tokptr points to the next token.
                    467:                         */
                    468:                        stabstart = tokptr;
                    469:                        (char *)stabstart -= sizeof(struct symtab *);
                    470:                        (char *)stabstart -= sizeof(toktype);
                    471:                        shift;
                    472:                        for (argcnt = 0; argcnt < 8; argcnt++){
                    473:                                expr(locxp, val);
                    474:                                stpt->name[argcnt] = locxp->xvalue;
                    475:                                shiftover(CM);
                    476:                        }
                    477:                  tailstab:
                    478:                        expr(locxp, val);
                    479:                        if (! (locxp->xvalue & STABTYPS)){
                    480:                                yyerror("Invalid type in %s",stabname);
                    481:                                goto errorfix;
                    482:                        }
                    483:                        stpt->ptype = locxp->xvalue;
                    484:                        shiftover(CM);
                    485:                        expr(locxp, val);
                    486:                        stpt->other = locxp->xvalue;
                    487:                        shiftover(CM);
                    488:                        expr(locxp, val);
                    489:                        stpt->desc = locxp->xvalue;
                    490:                        shiftover(CM);
                    491:                        exprisname = 0;
                    492:                        expr(locxp, val);
                    493:                        p = locxp->xname;
                    494:                        if (p == NULL) {        /*absolute expr to begin with*/
                    495:                                stpt->value = locxp->xvalue;
                    496:                                stpt->index = dotp - usedot;
                    497:                                if (exprisname){
                    498:                                        switch(stpt->ptype){
                    499:                                                case N_GSYM:
                    500:                                                case N_FNAME:
                    501:                                                case N_RSYM:
                    502:                                                case N_SSYM:
                    503:                                                case N_LSYM:
                    504:                                                case N_PSYM:
                    505:                                                case N_BCOMM:
                    506:                                                case N_ECOMM:
                    507:                                                case N_LENG:
                    508:                                                        stpt->tag = STABFIXED;
                    509:                                                        break;
                    510:                                                default:
                    511:                                                        stpt->tag = STABFLOATING;
                    512:                                                        break;
                    513:                                        }
                    514:                                } else
                    515:                                        stpt->tag = STABFIXED;
                    516:                        }
                    517:                        else {          /*really have a name*/
                    518:                                stpt->dest = locxp->xname;
                    519:                                stpt->index = p->index;
                    520:                                stpt->type = p->type | STABFLAG;
                    521:                                /*
                    522:                                 *      We will assign a more accruate
                    523:                                 *      guess of locxp's location when
                    524:                                 *      we sort the symbol table
                    525:                                 *      The final value of value is
                    526:                                 *      given by stabfix()
                    527:                                 */
                    528:                                stpt->tag = STABFLOAT;
                    529: #ifdef DSTAB
                    530:                                printf("FORWARD REF FOR %s...\n", stabname);
                    531:                                printf("value (xname) = %x value(value(xname) = %x\n",
                    532:                                        stpt->dest,stpt->dest->value);
                    533:                                printf("name: %.8s\n\n",
                    534:                                        (stpt->dest)->name);
                    535: #endif
                    536:                        }
                    537:                        /*
                    538:                         *      tokptr now points at one token beyond
                    539:                         *      the current token stored in val and yylval,
                    540:                         *      which are the next tokens after the end of
                    541:                         *      this .stab directive.  This next token must
                    542:                         *      be either a SEMI or NL, so is of width just
                    543:                         *      one.  Therefore, to point to the next token
                    544:                         *      after the end of this stab, just back up one..
                    545:                         */
                    546:                        buildskip(stabstart, (char *)tokptr - sizeof(toktype));
                    547:                        break;  /*end of the .stab*/
                    548:                }       /*end of ISTAB*/
                    549:                
                    550:                case ISTABDOT:  {
                    551:                        stabname = ".stabd";
                    552:                        stpt = (struct symtab *)yylval;
                    553:                        /*
                    554:                         *      We clobber everything after the
                    555:                         *      .stabd and its pointer... we MUST
                    556:                         *      be able to get back to this .stabd
                    557:                         *      so that we can resolve its final value
                    558:                         */
                    559:                        stabstart = tokptr;
                    560:                        shift;          /*over the ISTABDOT*/
                    561:                        if (passno == 1){
                    562:                                expr(locxp, val);
                    563:                                if (! (locxp->xvalue & STABTYPS)){
                    564:                                        yyerror("Invalid type in .stabd");
                    565:                                        goto errorfix;
                    566:                                }
                    567:                                stpt->ptype = locxp->xvalue;
                    568:                                shiftover(CM);
                    569:                                expr(locxp, val);
                    570:                                stpt->other = locxp->xvalue;
                    571:                                shiftover(CM);
                    572:                                expr(locxp, val);
                    573:                                stpt->desc = locxp->xvalue;
                    574:                                /*
                    575:                                 *
                    576:                                 *      Now, clobber everything but the
                    577:                                 *      .stabd pseudo and the pointer
                    578:                                 *      to its symbol table entry
                    579:                                 *      tokptr points to the next token,
                    580:                                 *      build the skip up to this
                    581:                                 */
                    582:                                buildskip(stabstart, (toktype *)tokptr - sizeof(toktype));
                    583:                        }
                    584:                        /*
                    585:                         *      pass 1: Assign a good guess for its position
                    586:                         *              (ensures they are sorted into right place)/
                    587:                         *      pass 2: Fix the actual value
                    588:                         */
                    589:                        stpt->value = dotp->xvalue;
                    590:                        stpt->index = dotp - usedot;
                    591:                        stpt->tag = STABFLOAT;  /*although it has no effect in pass 2*/
                    592:                        break;
                    593:                }       /*end of case ISTABDOT*/
                    594: 
                    595:                case ISTABNONE:         stabname = ".stabn"; goto shortstab;
                    596: 
                    597:                case ISTABSTR: {        stabname = ".stabs";
                    598:                   shortstab:
                    599:                        auxval = val;
                    600:                        if (passno == 2) goto errorfix;
                    601:                        stpt = (struct symtab *)yylval;
                    602:                        stabstart = tokptr;
                    603:                        (char *)stabstart -= sizeof(struct symtab *);
                    604:                        (char *)stabstart -= sizeof(toktype);
                    605:                        shift;
                    606:                        if (auxval == ISTABSTR){
                    607:                                stringp = (struct strdesc *)yylval;
                    608:                                shiftover(STRING);
                    609:                                auxval = stringp->str_lg > NCPS ? NCPS : stringp->str_lg;
                    610:                                shiftover(CM);
                    611:                        } else {
                    612:                                stringp = &(strbuf[2]);
                    613:                                auxval = NCPS;
                    614:                        }
                    615:                        movestr(stpt->name, stringp->str, auxval);
                    616:                        goto tailstab;
                    617:                        break;
                    618:                }       /*end of case ISTABSTR and ISTABN*/
                    619:                
                    620:                case ICOMM:     /* .comm  <name> , <expr> */
                    621:                case ILCOMM: {  /* .lcomm <name> , <expr> */
                    622:                        auxval = val;
                    623:                        shift;
                    624:                        np = (struct symtab *)yylval;
                    625:                        shiftover(NAME);
                    626:                        shiftover(CM);
                    627:                        expr(locxp, val);
                    628: 
                    629:                        if (locxp->xtype != XABS)
                    630:                                yyerror("comm size not absolute");
                    631:                        if (passno==1 && (np->type&XTYPE)!=XUNDEF)
                    632:                                yyerror("Redefinition of %.8s", np->name);
                    633:                        if (passno==1) {
                    634:                                np->value = locxp->xvalue;
                    635:                                if (auxval == ICOMM)
                    636:                                        np->type |= XXTRN;
                    637:                                else {
                    638:                                        np->type &= ~XTYPE;
                    639:                                        np->type |= XBSS;
                    640:                                }
                    641:                        }
                    642:                        break;
                    643:                }       /*end of case ICOMM and ILCOMM*/
                    644:                
                    645:                case IALIGN: {          /* .align <expr> */
                    646:                        stpt = (struct symtab *)yylval;
                    647:                        shift;
                    648:                        expr(locxp, val);
                    649:                        jalign(locxp, stpt);
                    650:                        break;
                    651:                }       /*end of case IALIGN*/
                    652:                
                    653:                case INST0: {           /* instructions w/o arguments*/
                    654:                        insout(yylval, 0, 0);
                    655:                        shift;  
                    656:                        break;
                    657:                }       /*end of case INST0*/
                    658:                
                    659:                case INSTn:             /* instructions with arguments*/
                    660:                case IJXXX: {           /* UNIX style jump instructions */
                    661:                        auxval = val;
                    662:                        seg_type = yylval;
                    663:                        /*
                    664:                         *      Code to process an argument list
                    665:                         */
                    666:                        ap = arglist;
                    667:                        xp = explist;   /*must be set before bring in the first token*/
                    668: 
                    669:                        shift;          /*and bring in the first token for the arg list*/
                    670: 
                    671:                        for (argcnt = 1; argcnt <= 6; argcnt++, ap++){
                    672:                                /*
                    673:                                 *      code to process an argument proper
                    674:                                 */
                    675:                            sawindex  = sawmul = sawsize = 0;
                    676:                            {
                    677:                                switch(val) {
                    678: 
                    679:                                   default: {
                    680:                                      disp:
                    681:                                        if( !(INTOKSET(val,
                    682:                                                 EBEGOPS
                    683:                                                +YUKKYEXPRBEG
                    684:                                                +SAFEEXPRBEG)) ) {
                    685:                                                ERROR("expression expected");
                    686:                                        }
                    687:                                        expr(ap->xp,val);
                    688:                                  overdisp:
                    689:                                        if ( val == LP || sawsize){
                    690:                                                shiftover(LP);
                    691:                                                findreg(regno);
                    692:                                                shiftover(RP);
                    693:                                                ap->atype = ADISP;
                    694:                                                ap->areg1 = regno;
                    695:                                        } else {
                    696:                                                ap->atype = AEXP;
                    697:                                                ap->areg1 = 0;
                    698:                                        }
                    699:                                        goto index;
                    700:                                   }    /*end of the default action*/
                    701: 
                    702:                                   case SIZESPEC: {
                    703:                                     sizespec:
                    704:                                        sawsize = yylval;
                    705:                                        shift;
                    706:                                        goto disp;
                    707:                                   }
                    708: 
                    709:                                   case REG:
                    710:                                   case REGOP: {
                    711:                                        findreg(regno);
                    712:                                        ap->atype = AREG;
                    713:                                        ap->areg1 = regno;
                    714:                                        break;
                    715:                                   }    /*end of case REG*/
                    716:                                    
                    717:                                   case MUL: {
                    718:                                        sawmul = 1;
                    719:                                        shift;
                    720:                                        if (val == LP) goto base;
                    721:                                        if (val == LITOP) goto imm;
                    722:                                        if (val == SIZESPEC) goto sizespec;
                    723:                                        if (INTOKSET(val,
                    724:                                                 EBEGOPS
                    725:                                                +YUKKYEXPRBEG
                    726:                                                +SAFEEXPRBEG)) goto disp;
                    727:                                        ERROR("expression, '(' or '$' expected");
                    728:                                        break;
                    729:                                   }    /*end of case MUL*/
                    730: 
                    731:                                   case LP: {
                    732:                                     base:
                    733:                                        shift;  /*consume the LP*/
                    734:                                        /*
                    735:                                         *      hack the ambiguity of
                    736:                                         *      movl (expr) (rn), ...
                    737:                                         *      note that (expr) could also
                    738:                                         *      be (rn) (by special hole in the
                    739:                                         *      grammar), which we ensure
                    740:                                         *      means register indirection, instead
                    741:                                         *      of an expression with value n
                    742:                                         */
                    743:                                        if (val != REG && val != REGOP){
                    744:                                                droppedLP = 1;
                    745:                                                val = exprparse(val, &(ap->xp));
                    746:                                                droppedLP = 0;
                    747:                                                goto overdisp;
                    748:                                        }
                    749:                                        findreg(regno);
                    750:                                        shiftover(RP);
                    751:                                        if (val == PLUS){
                    752:                                                shift;
                    753:                                                ap->atype = AINCR;
                    754:                                        } else
                    755:                                                ap->atype = ABASE;
                    756:                                        ap->areg1 = regno;
                    757:                                        goto index;
                    758:                                   }    /*end of case LP*/
                    759: 
                    760:                                   case LITOP: {
                    761:                                      imm:
                    762:                                        shift;
                    763:                                        expr(locxp, val);
                    764:                                        ap->atype = AIMM;
                    765:                                        ap->areg1 = 0;
                    766:                                        ap->xp = locxp;
                    767:                                        goto index;
                    768:                                   }    /*end of case LITOP*/
                    769: 
                    770:                                   case MP: {
                    771:                                        shift;  /* -(reg) */
                    772:                                        findreg(regno);
                    773:                                        shiftover(RP);
                    774:                                        ap->atype = ADECR;
                    775:                                        ap->areg1 = regno;
                    776:                          index:                        /*look for [reg] */
                    777:                                        if (val == LB){
                    778:                                                shift;
                    779:                                                findreg(regno);
                    780:                                                shiftover(RB);
                    781:                                                sawindex = 1;
                    782:                                                ap->areg2 = regno;
                    783:                                        }
                    784:                                        break;
                    785:                                     }          /*end of case MP*/
                    786: 
                    787:                                }       /*end of the switch to process an arg*/
                    788:                            }   /*end of processing an argument*/
                    789: 
                    790:                            if (sawmul){
                    791:                                        /*
                    792:                                         * Make a concession for *(%r)
                    793:                                         * meaning *0(%r) 
                    794:                                         */
                    795:                                        if (ap->atype == ABASE) {
                    796:                                                ap->atype = ADISP;
                    797:                                                xp->xtype = XABS;
                    798:                                                xp->xvalue = 0;
                    799:                                                xp->xloc = 0;
                    800:                                                ap->xp = xp++;
                    801:                                        }
                    802:                                        ap->atype |= ASTAR;
                    803:                                        sawmul = 0;
                    804:                            }
                    805:                            if (sawindex){
                    806:                                ap->atype |= AINDX;
                    807:                                sawindex = 0;
                    808:                            }
                    809:                            ap->dispsize = sawsize == 0 ? d124 : sawsize;
                    810:                                if (val != CM) break;
                    811:                                shiftover(CM);
                    812:                        }       /*processing all the arguments*/
                    813: 
                    814:                        if (argcnt > 6){
                    815:                                yyerror("More than 6 arguments");
                    816:                                goto errorfix;
                    817:                        }
                    818: 
                    819:                        insout(seg_type, arglist,
                    820:                                auxval == INSTn ? argcnt : - argcnt);
                    821:                        break;
                    822:                }       /*end of case INSTn and IJXXX*/
                    823:                
                    824:                case IFLOAT:    curlen = 4;     goto floatlist;
                    825: 
                    826:                case IDOUBLE: {
                    827:                        curlen = 8;
                    828:                  floatlist:    
                    829:                        /*
                    830:                         *      eat a list of floating point numbers
                    831:                         */
                    832:                        shift;
                    833:                        if (val == FLTNUM){
                    834:                                do{
                    835:                                        if (val == CM) shift;
                    836:                                        if (val != FLTNUM) {
                    837:                                          ERROR("floating number expected");
                    838:                                        }
                    839:                                        dotp->xvalue += curlen;
                    840:                                        if (passno == 2)
                    841:                                           fwrite(
                    842:                                             &(((struct exp *)yylval)->doubval.dvalue),
                    843:                                             1, curlen, txtfil);
                    844:                                        shift;
                    845:                                } while (val == CM);
                    846:                        }
                    847:                        break;
                    848:                }       /*end of case IFLOAT and IDOUBLE*/
                    849: 
                    850:            }   /*end of the switch for looking at each reserved word*/
                    851: 
                    852:                /*
                    853:                 *      If got here, then one has no syntax errors!
                    854:                 */
                    855:                continue;
                    856: 
                    857:                /*
                    858:                 *      got here by either requesting to skip to the
                    859:                 *      end of this statement, or by erroring out and
                    860:                 *      wanting to apply panic mode recovery
                    861:                 */
                    862:           errorfix: {
                    863: #ifdef DEBUG
                    864:                if (debug)
                    865:                        printf("Discarding tokens from here:\n");
                    866: #endif
                    867:                                while (    (val != NL) 
                    868:                                        && (val != SEMI) 
                    869:                                        && (val != PARSEEOF)
                    870:                                      ){
                    871: #ifdef DEBUG
                    872:                                        if (debug)
                    873:                                                printf("****>>>>\t");
                    874: #endif
                    875:                                        shift;
                    876:                                }
                    877:                                if (val == NL)
                    878:                                        lineno++;
                    879: #ifdef DEBUG
                    880:                if (debug)
                    881:                        printf("To here.\n");
                    882: #endif
                    883:                        shift;
                    884:                     }
                    885: 
                    886:        }       /*end of the loop to read the entire file, line by line*/
                    887: 
                    888: 
                    889: }      /*end of yyparse*/
                    890:        
                    891: /*
                    892:  *     Process a register declaration of the form
                    893:  *     % <expr>
                    894:  *
                    895:  *     Note:
                    896:  *             The scanner has already processed funny registers of the form
                    897:  *     %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional
                    898:  *     preceding zero digit).  If there was any space between the % and
                    899:  *     the digit, the scanner wouldn't have recognized it, so we
                    900:  *     hack it out here.
                    901:  */
                    902: int funnyreg(val, regnoback)           /*what the read head will sit on*/
                    903:        int     val;                    /*what the read head is sitting on*/
                    904:        int     *regnoback;             /*call by return*/
                    905: {
                    906:        register        struct  exp *locxp;
                    907:                        struct  exp *loc1xp;
                    908:                        struct  exp **ptrloc1xp = & loc1xp;
                    909: 
                    910:        expr(locxp, val);       /*and leave the current read head with value*/
                    911:        if ( (passno == 2) &&
                    912:            (   locxp->xtype & XTYPE != XABS
                    913:             || locxp->xvalue < 0
                    914:             || locxp->xvalue >= 16 
                    915:            )
                    916:          ){
                    917:                yyerror("Illegal register");
                    918:                return(0);
                    919:        }
                    920:        *regnoback = locxp->xvalue;
                    921:        return(val);
                    922: } 
                    923: 
                    924: /* VARARGS 1*/
                    925: yyerror(s, a1, a2)
                    926:        char    *s;
                    927: {
                    928:        FILE            *sink;
                    929: 
                    930: #ifdef DEBUG
                    931:        sink = stdout;
                    932: #else
                    933:        sink = stderr;
                    934: #endif
                    935: 
                    936:        if (anyerrs == 0 && ! silent) 
                    937:                fprintf(sink, "Assembler:\n");
                    938:        anyerrs++;
                    939:        if (silent) return;
                    940:        
                    941:        fprintf(sink, "\"%s\", line %d: ", dotsname, lineno);
                    942:        fprintf(sink, s, a1, a2);
                    943:        fprintf(sink, "\n");
                    944: }

unix.superglobalmegacorp.com

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