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

unix.superglobalmegacorp.com

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