Annotation of 41BSD/cmd/as/asparse.c, revision 1.1.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.