Annotation of 40BSD/cmd/as/asparse.c, revision 1.1

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

unix.superglobalmegacorp.com

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