Annotation of 40BSD/cmd/as/asscan.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1980 Regents of the University of California */
                      2: static char sccsid[] = "@(#)asscan.c 4.6 9/8/80";
                      3: #include <stdio.h>
                      4: #include "as.h"
                      5: #include "asscan.h"
                      6: 
                      7: /*
                      8:  *     NOTE:
                      9:  *             This version of the assembler does not use fread and fwrite
                     10:  *     for the token buffering.  The token buffers are integrals of BUFSIZ
                     11:  *     at all times, so we use direct read and write.  fread and fwrite
                     12:  *     as supplied from BTL in stdio are HORRENDOUSLY inefficient,
                     13:  *     as they use putchar for each character, nested two deep in loops.
                     14:  */
                     15: #define writeTEST(pointer, size, nelements, ioptr) \
                     16:        write(ioptr->_file, pointer, nelements * size) != nelements * size
                     17: 
                     18: #define readTEST(pointer, size, nelements, ioptr) \
                     19:        read(ioptr->_file, pointer, nelements * size) != nelements * size
                     20: /*
                     21:  *     Variables to manage the token buffering.
                     22:  *     We scan (lexically analyze) a large number of tokens, and
                     23:  *     then parse all of the tokens in the scan buffer.
                     24:  *     This reduces procedure call overhead when the parser
                     25:  *     demands a token, allows for an efficient reread during
                     26:  *     the second pass, and confuses the line number reporting
                     27:  *     for errors encountered in the scanner and in the parser.
                     28:  */
                     29: #define TOKDALLOP      8
                     30: struct tokbufdesc *bufstart;   /*where the buffer list begins*/
                     31: struct tokbufdesc *buftail;    /*last one on the list*/
                     32: struct tokbufdesc *emptybuf;   /*the one being filled*/
                     33: /*
                     34:  *     If we are using VM, during the second pass we reclaim the used
                     35:  *     token buffers for saving the relocation information
                     36:  */
                     37: struct tokbufdesc *tok_free;   /* free pool */
                     38: struct tokbufdesc *tok_temp;   /* temporary for doing list manipulation */
                     39: /*
                     40:  *     Other token buffer managers
                     41:  */
                     42: int    bufno;                  /*which buffer number: 0,1 for tmp file*/
                     43: struct         tokbufdesc tokbuf[2];   /*our initial increment of buffers*/
                     44: ptrall tokptr;                 /*where the current token comes from*/
                     45: ptrall tokub;                  /*the last token in the current token buffer*/
                     46: 
                     47: /*
                     48:  *     Variables to manage the string buffering
                     49:  *     declared in asscan.h.
                     50:  */
                     51: int    strno;                  /*the current string being filled*/
                     52: struct strdesc strbuf[3];      /*the string buffers; the first for nulls*/
                     53: struct strdesc *strptr;        /*current string buffer being filled*/
                     54:        
                     55: inittmpfile()
                     56: {
                     57:        if (passno == 1){
                     58:                if (useVM){
                     59:                        bufstart = &tokbuf[0];
                     60:                        buftail = &tokbuf[1];
                     61:                        bufstart->tok_next = buftail;
                     62:                        buftail->tok_next = 0;
                     63:                }
                     64:                tokbuf[0].tok_count = -1;
                     65:                tokbuf[1].tok_count = -1;
                     66:        }
                     67:        tok_temp = 0;
                     68:        tok_free = 0;
                     69:        bufno = 0;
                     70:        emptybuf = &tokbuf[bufno];
                     71:        tokptr = 0;
                     72:        tokub = 0;
                     73: }
                     74: 
                     75: closetmpfile()
                     76: {
                     77:        if (passno == 1){
                     78:                if (useVM){
                     79:                        emptybuf->toks[emptybuf->tok_count++] = PARSEEOF;
                     80:                } else {
                     81:                        /*
                     82:                         *      Clean up the buffers that haven't been
                     83:                         *      written out yet
                     84:                         */
                     85:                        if (tokbuf[bufno ^ 1].tok_count >= 0){
                     86:                                if (writeTEST((char *)&tokbuf[bufno ^ 1], sizeof *emptybuf, 1, tmpfil)){
                     87:                                  badwrite:
                     88:                                        yyerror("Unexpected end of file writing the interpass tmp file");
                     89:                                exit(2);
                     90:                                }
                     91:                        }
                     92:                        /*
                     93:                         *      Ensure that we will read an End of file,
                     94:                         *      if there are more than one file names
                     95:                         *      in the argument list
                     96:                         */
                     97:                        tokbuf[bufno].toks[tokbuf[bufno].tok_count++] = PARSEEOF;
                     98:                        if (writeTEST((char *)&tokbuf[bufno], sizeof *emptybuf, 1, tmpfil))
                     99:                                goto badwrite;
                    100:                }
                    101:        }       /*end of being pass 1*/
                    102: }
                    103: 
                    104: #define bstrlg(from, length) \
                    105:        *(lgtype *)from = length; \
                    106:        (char *)from += sizeof(lgtype) + length 
                    107: 
                    108: #define bstrfromto(from,to) \
                    109:        *(lgtype *)from = (char *)to - (char *)from - sizeof(lgtype); \
                    110:        (char *)from += sizeof(lgtype) + (char *)to - (char *)from
                    111: 
                    112: #define eatstrlg(from) \
                    113:        (char *)from +=  sizeof(lgtype) + *(lgtype *)from
                    114: 
                    115: #define bskiplg(from, length) \
                    116:        *(lgtype *)from = length; \
                    117:        (char *)from += sizeof(lgtype) + length
                    118: 
                    119: #define bskipfromto(from, to) \
                    120:        *(lgtype *)from = (toktype *)to - (toktype *)from - sizeof(lgtype); \
                    121:        (char *)from += sizeof (lgtype) + (toktype *)to - (toktype *)from
                    122: 
                    123: #define eatskiplg(from) \
                    124:        (toktype *)from += sizeof(lgtype) + *(lgtype *)from
                    125: 
                    126: #ifdef DEBUG
                    127:        ptrall  firsttoken;
                    128: #endif DEBUG
                    129: 
                    130: extern int             yylval;         /*global communication with parser*/
                    131: static int             Lastjxxx;       /*this ONLY shuts up cc; see below*/
                    132: 
                    133: toktype yylex()
                    134: {
                    135:        register        ptrall  bufptr; 
                    136:        register        toktype         val;    
                    137:        register        struct  exp     *locxp;
                    138: 
                    139:        bufptr = tokptr;                /*copy in the global value*/
                    140:    top:
                    141:        if (bufptr < tokub){
                    142:                gtoken(val, bufptr);
                    143:                switch(yylval = val){
                    144:                case    PARSEEOF :
                    145:                                yylval = val = PARSEEOF;
                    146:                                break;
                    147:                case    BFINT:
                    148:                case    INT:
                    149:                                if (xp >= &explist[NEXP])
                    150:                                     yyerror("Too many expressions; try simplyfing");
                    151:                                else
                    152:                                    locxp = xp++;
                    153:                                glong(locxp->e_xvalue, bufptr);
                    154:                                locxp->e_yvalue = 0;
                    155:                          makevalue:
                    156:                                locxp->e_xtype = XABS;
                    157:                                locxp->e_xloc = 0;
                    158:                                locxp->e_xname = NULL;
                    159:                                yylval = (int)locxp;
                    160:                                break;
                    161:                case    FLTNUM: 
                    162:                                if (xp >= &explist[NEXP])
                    163:                                     yyerror("Too many expressions; try simplyfing");
                    164:                                else
                    165:                                    locxp = xp++;
                    166:                                gdouble( ( (union Double *)locxp)->dvalue, bufptr);
                    167:                                goto makevalue;
                    168:                case    QUAD:
                    169:                                if (xp >= &explist[NEXP])
                    170:                                     yyerror("Too many expressions; try simplyfing");
                    171:                                else
                    172:                                    locxp = xp++;
                    173:                                glong(locxp->e_xvalue, bufptr);
                    174:                                glong(locxp->e_yvalue, bufptr);
                    175:                                yylval = val = INT;
                    176:                                goto makevalue;
                    177:                case    NAME:
                    178:                                gptr(yylval, bufptr);
                    179:                                lastnam = (struct symtab *)yylval;
                    180:                                break;
                    181:                case    SIZESPEC:
                    182:                case    REG:
                    183:                case    INSTn:
                    184:                case    INST0:
                    185:                                gchar(yylval, bufptr);
                    186:                                break;
                    187:                case    IJXXX:
                    188:                                gchar(yylval, bufptr);
                    189:                                /* We can't cast Lastjxxx into (int *) here.. */
                    190:                                gptr(Lastjxxx, bufptr);
                    191:                                lastjxxx = (struct symtab *)Lastjxxx;
                    192:                                break;
                    193:                case    ILINESKIP:
                    194:                                gint(yylval, bufptr);
                    195:                                lineno += yylval;
                    196:                                goto top;
                    197:                case    SKIP:   
                    198:                                eatskiplg(bufptr);
                    199:                                goto top;
                    200:                case    VOID:   
                    201:                                goto top;
                    202:                case    STRING:
                    203:                                strptr = &strbuf[strno ^= 1];
                    204:                                strptr->str_lg = *((lgtype *)bufptr);
                    205:                                movestr(&strptr->str[0],
                    206:                                        (char *)bufptr + sizeof(lgtype),
                    207:                                        strptr->str_lg);
                    208:                                eatstrlg(bufptr);
                    209:                                yylval = (int)strptr;
                    210:                                break;
                    211:                case    ISTAB:
                    212:                case    ISTABSTR:
                    213:                case    ISTABNONE:
                    214:                case    ISTABDOT:
                    215:                case    IALIGN:
                    216:                                gptr(yylval, bufptr);
                    217:                                break;
                    218:                } 
                    219: #ifdef DEBUG
                    220:                if (toktrace){
                    221:                char    *tok_to_name();
                    222:                printf("P: %d T#: %4d, %s ",
                    223:                        passno, bufptr -  firsttoken, tok_to_name(val));
                    224:                switch(val){
                    225:                case    INT:    printf("val %d",
                    226:                                        ((struct exp *)yylval)->e_xvalue);
                    227:                                break;
                    228:                case    BFINT:  printf("val %d",
                    229:                                        ((struct exp *)yylval)->e_xvalue);
                    230:                                break;
                    231:                case    QUAD:   printf("val[msd] = 0x%x, val[lsd] = 0x%x.",
                    232:                                ((struct exp *)yylval)->e_xvalue,
                    233:                                ((struct exp *)yylval)->e_yvalue);
                    234:                                break;
                    235:                case    FLTNUM: printf("value %20.17f",
                    236:                                ((union Double *)yylval)->dvalue);
                    237:                                break;
                    238:                case    NAME:   printf("\"%.8s\"",
                    239:                                        ((struct symtab *)yylval)->s_name);
                    240:                                break;
                    241:                case    REG:    printf(" r%d",
                    242:                                        yylval);
                    243:                                break;
                    244:                case    IJXXX:
                    245:                case    INST0:  
                    246:                case    INSTn:  printf("%.8s",
                    247:                                        itab[0xFF &yylval]->s_name);
                    248:                                break;
                    249:                case    STRING: printf("length %d ",
                    250:                                        ((struct strdesc *)yylval)->str_lg);
                    251:                                printf("value\"%s\"",
                    252:                                        ((struct strdesc *)yylval)->str);
                    253:                                break;
                    254:                }               /*end of the debug switch*/
                    255:                printf("\n");
                    256:                }
                    257: #endif DEBUG
                    258: 
                    259:        } else {        /* start a new buffer */
                    260:            if (useVM){
                    261:                if (passno == 2){
                    262:                        tok_temp = emptybuf->tok_next;
                    263:                        emptybuf->tok_next = tok_free;
                    264:                        tok_free = emptybuf;
                    265:                        emptybuf = tok_temp;
                    266:                } else {
                    267:                        emptybuf = emptybuf->tok_next;
                    268:                }
                    269:                bufno += 1;
                    270:                if (emptybuf == 0){
                    271:                        struct  tokbufdesc *newdallop;
                    272:                        int     i;
                    273:                        if (passno == 2)
                    274:                                goto badread;
                    275:                        emptybuf = newdallop = (struct tokbufdesc *)
                    276:                          Calloc(TOKDALLOP, sizeof (struct tokbufdesc));
                    277:                        for (i=0; i < TOKDALLOP; i++){
                    278:                                buftail->tok_next = newdallop;
                    279:                                buftail = newdallop;
                    280:                                newdallop += 1;
                    281:                        }
                    282:                        buftail->tok_next = 0;
                    283:                }       /*end of need to get more buffers*/
                    284:                (toktype *)bufptr = &(emptybuf->toks[0]);
                    285:                if (passno == 1)
                    286:                        scan_dot_s(emptybuf);
                    287:            } else {    /*don't use VM*/
                    288:                bufno ^= 1;
                    289:                emptybuf = &tokbuf[bufno];
                    290:                ((toktype *)bufptr) = &(emptybuf->toks[0]);
                    291:                if (passno == 1){
                    292:                        /*
                    293:                         *      First check if there are things to write
                    294:                         *      out at all
                    295:                         */
                    296:                        if (emptybuf->tok_count >= 0){
                    297:                            if (writeTEST((char *)emptybuf, sizeof *emptybuf, 1, tmpfil)){
                    298:                              badwrite:
                    299:                                yyerror("Unexpected end of file writing the interpass tmp file");
                    300:                                exit(2);
                    301:                            }
                    302:                        }
                    303:                        scan_dot_s(emptybuf);
                    304:                } else {        /*pass 2*/
                    305:                    if (readTEST((char *)emptybuf, sizeof *emptybuf, 1, tmpfil)){
                    306:                         badread:
                    307:                             yyerror("Unexpected end of file while reading the interpass tmp file");
                    308:                             exit(1);
                    309:                    }
                    310:                }
                    311:            }   /*end of using a real live file*/
                    312:            (char *)tokub = (char *)bufptr + emptybuf->tok_count;
                    313: #ifdef DEBUG
                    314:            firsttoken = bufptr;
                    315:            if (debug)
                    316:                printf("created buffernumber %d with %d tokens\n",
                    317:                        bufno, emptybuf->tok_count);
                    318: #endif DEBUG
                    319:            goto top;
                    320:        }       /*end of reading/creating a new buffer*/
                    321:        tokptr = bufptr;                /*copy back the global value*/
                    322:        return(val);
                    323: }      /*end of yylex*/
                    324: 
                    325: 
                    326: buildskip(from, to)
                    327:        register        ptrall  from, to;
                    328: {
                    329:        int     diff;
                    330:        register        int     frombufno;
                    331:        register        struct  tokbufdesc *middlebuf;
                    332:        /*
                    333:         *      check if from and to are in the same buffer
                    334:         *      from and to DIFFER BY AT MOST 1 buffer and to is
                    335:         *      always ahead of from, with to being in the buffer emptybuf
                    336:         *      points to.
                    337:         *      The hard part here is accounting for the case where the
                    338:         *      skip is to cross a buffer boundary; we must construct
                    339:         *      two skips.
                    340:         *
                    341:         *      Figure out where the buffer boundary between from and to is
                    342:         *      It's easy in VM, as buffers increase to high memory, but
                    343:         *      w/o VM, we alternate between two buffers, and want
                    344:         *      to look at the exact middle of the contiguous buffer region.
                    345:         */
                    346:        middlebuf = useVM ? emptybuf : &tokbuf[1];
                    347:        if (  ( (toktype *)from > (toktype *)middlebuf)
                    348:            ^ ( (toktype *)to > (toktype *)middlebuf)
                    349:           ){   /*split across a buffer boundary*/
                    350:                ptoken(from, SKIP);
                    351:                /*
                    352:                 *      Set the skip so it lands someplace beyond
                    353:                 *      the end of this buffer.
                    354:                 *      When we pull this skip out in the second pass,
                    355:                 *      we will temporarily move the current pointer
                    356:                 *      out beyond the end of the buffer, but immediately
                    357:                 *      do a compare and fail the compare, and then reset
                    358:                 *      all the pointers correctly to point into the next buffer.
                    359:                 */
                    360:                bskiplg(from,  TOKBUFLG + 1);
                    361:                /*
                    362:                 *      Now, force from to be in the same buffer as to
                    363:                 */
                    364:                (toktype *)from = (toktype *)&(emptybuf->toks[0]);
                    365:        }
                    366:        /*
                    367:         *      Now, to and from are in the same buffer
                    368:         */
                    369:        if (from > to)
                    370:                yyerror("Internal error: bad skip construction");
                    371:        else {
                    372:                if ( (diff = (toktype *)to - (toktype *)from) >= 
                    373:                        (sizeof(toktype) + sizeof(lgtype) + 1)) {
                    374:                                ptoken(from, SKIP);
                    375:                                bskipfromto(from, to);
                    376:                } else {
                    377:                        for ( ; diff > 0; --diff)
                    378:                                ptoken(from, VOID);
                    379:                }
                    380:        }
                    381: }
                    382: 
                    383: movestr(to, from, lg)
                    384:        register        char    *to, *from;
                    385:        register        int     lg;
                    386: {
                    387:        if (lg <= 0) return;
                    388:        do
                    389:                *to++ = *from++;
                    390:        while (--lg);
                    391: }
                    392: static int     newfflag = 0;
                    393: static char    *newfname;
                    394: int    scanlineno;             /*the scanner's linenumber*/
                    395: 
                    396: new_dot_s(namep)
                    397:        char    *namep;
                    398: {
                    399:        newfflag = 1;
                    400:        newfname = namep;
                    401:        dotsname = namep;
                    402:        lineno = 1;
                    403:        scanlineno = 1;
                    404: }
                    405: 
                    406: /*
                    407:  *     Maps characters to their use in assembly language
                    408:  */
                    409: #define EOFCHAR        (-1)
                    410: #define        NEEDCHAR (-2)
                    411: 
                    412: readonly short type[] = {
                    413:        NEEDSBUF,               /*fill up the input buffer*/
                    414:        SCANEOF,                /*hit the hard end of file*/
                    415:        SP,     BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,   /*\0..^G*/
                    416:        BADCHAR,SP,     NL,     BADCHAR,BADCHAR,SP,     BADCHAR,BADCHAR,   /*BS..SI*/
                    417:        BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,   /*DLE..ETB*/
                    418:        BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,   /*CAN..US*/
                    419:        SP,     ORNOT,  DQ,     SH,     LITOP,  REGOP,  AND,    SQ,  /*sp .. '*/
                    420:        LP,     RP,     MUL,    PLUS,   CM,     MINUS,  ALPH,   DIV, /*( .. /*/
                    421:        DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG, /*0 .. 7*/
                    422:        DIG,    DIG,    COLON,  SEMI,   LSH,    BADCHAR,RSH,    BADCHAR, /*8 .. ?*/
                    423:        BADCHAR,ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*@ .. G*/
                    424:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*H .. BADCHAR*/
                    425:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*P .. V*/
                    426:        ALPH,   ALPH,   ALPH,   LB,     BADCHAR,RB,     XOR,    ALPH,/*W .. _*/
                    427:        SIZEQUOTE,ALPH, ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*` .. g*/
                    428:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*h .. o*/
                    429:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*p .. v*/
                    430:        ALPH,   ALPH,   ALPH,   BADCHAR,IOR,    BADCHAR,TILDE,  BADCHAR,/*x .. del*/
                    431: };
                    432: 
                    433: /*
                    434:  *     The table of possible uses for each character to test set inclusion.
                    435:  *     Different than the above table, which knows about tokens yylex
                    436:  *     is to return.
                    437:  */
                    438: #define        HEXFLAG         01              /* 'x' or 'X' */
                    439: #define        HEXLDIGIT       02              /* 'a' .. 'f' */
                    440: #define        HEXUDIGIT       04              /* 'A' .. 'F' */
                    441: #define        ALPHA           010             /* 'A' .. 'Z', 'a' .. 'z', '_'*/
                    442: #define        DIGIT           020             /* '0' .. '9' */
                    443: #define        FLOATEXP        040             /* 'd' 'e' 'D' 'E' */
                    444: #define        SIGN            0100            /* '+' .. '-'*/
                    445: #define        REGDIGIT        0200            /* '0' .. '5' */
                    446: #define        SZSPECBEGIN     0400            /* 'b', 'B', 'l', 'L', 'w', 'W' */
                    447: #define        POINT           01000           /* '.' */
                    448: #define        SPACE           02000           /* '\t' or ' ' */
                    449: #define        BSESCAPE        04000           /* bnrtf */
                    450: #define        STRESCAPE       010000          /* '"', '\\', '\n' */
                    451: #define        OCTDIGIT        020000          /* '0' .. '7' */
                    452: #define        FLOATFLAG       040000          /* 'd', 'D', 'f', 'F' */
                    453:                                                /*after leading 0*/
                    454: 
                    455: readonly short charsets[] = {
                    456:        0,      0,      0,      0,      0,      0,      0,      0,   /*\0..^G*/
                    457:        0,      SPACE,  STRESCAPE,0,    0,      0,      0,      0,   /*BS..SI*/
                    458:        0,      0,      0,      0,      0,      0,      0,      0,   /*DLE..ETB*/
                    459:        0,      0,      0,      0,      0,      0,      0,      0,   /*CAN..US*/
                    460: /* dollar is an alpha character */
                    461:        SPACE,  0,      STRESCAPE,0,    ALPHA,  0,      0,      0,   /*sp.. '*/
                    462:        0,      0,      0,      SIGN,   0,      SIGN,   POINT+ALPHA,0, /*( .. /*/
                    463:        DIGIT+REGDIGIT+OCTDIGIT,        DIGIT+REGDIGIT+OCTDIGIT,     /*0..1*/
                    464:        DIGIT+REGDIGIT+OCTDIGIT,        DIGIT+REGDIGIT+OCTDIGIT,     /*2..3*/
                    465:        DIGIT+REGDIGIT+OCTDIGIT,        DIGIT+REGDIGIT+OCTDIGIT,     /*4..5*/
                    466:        DIGIT+OCTDIGIT,                 DIGIT+OCTDIGIT,              /*6..7*/
                    467:        DIGIT,  DIGIT,  0,      0,      0,      0,      0,      0,   /*8..?*/
                    468:        0,                                                           /*@*/
                    469:        ALPHA+HEXUDIGIT,ALPHA+HEXUDIGIT+SZSPECBEGIN,                 /*A..B*/
                    470:        ALPHA+HEXUDIGIT,ALPHA+HEXUDIGIT+FLOATEXP+FLOATFLAG,          /*C..D*/
                    471:        ALPHA+HEXUDIGIT+FLOATEXP,ALPHA+HEXUDIGIT+FLOATFLAG,          /*E..F*/
                    472:        ALPHA,                                                       /*G*/
                    473:        ALPHA,                  ALPHA,  ALPHA,  ALPHA,               /*H..K*/
                    474:        ALPHA+SZSPECBEGIN,      ALPHA,  ALPHA,  ALPHA,               /*L..O*/
                    475:        ALPHA,                  ALPHA,  ALPHA,  ALPHA,               /*P..S*/
                    476:        ALPHA,                  ALPHA,  ALPHA,  ALPHA+SZSPECBEGIN,   /*T..W*/
                    477:        ALPHA+HEXFLAG,  ALPHA,  ALPHA,  0,STRESCAPE,0,  0,      ALPHA,/*X.._*/
                    478: 
                    479:        0,
                    480:        ALPHA+HEXLDIGIT,ALPHA+HEXLDIGIT+BSESCAPE+SZSPECBEGIN,         /*a..b*/
                    481:        ALPHA+HEXLDIGIT,ALPHA+HEXLDIGIT+FLOATEXP+FLOATFLAG,           /*c..d*/
                    482:        ALPHA+HEXLDIGIT+FLOATEXP,ALPHA+HEXLDIGIT+BSESCAPE+FLOATFLAG,  /*e..f*/
                    483:        ALPHA,                                                        /*g*/
                    484:        ALPHA,                  ALPHA,  ALPHA,          ALPHA,        /*h..k*/
                    485:        ALPHA+SZSPECBEGIN,      ALPHA,  ALPHA+BSESCAPE, ALPHA,        /*l..o*/
                    486:        ALPHA,                  ALPHA,  ALPHA+BSESCAPE, ALPHA,        /*p..s*/
                    487:        ALPHA+BSESCAPE,         ALPHA,  ALPHA,          ALPHA+SZSPECBEGIN,/*t..w*/
                    488:        ALPHA+HEXFLAG,  ALPHA,  ALPHA,  0,0,    0,      0,      0,    /*x..del*/
                    489: 0};
                    490: 
                    491: #define        INCHARSET(val, kind) (charsets[val] & (kind) )
                    492: static toktype oval = NL;
                    493: 
                    494: #define        NINBUFFERS      2
                    495: #define        INBUFLG         NINBUFFERS*BUFSIZ + 2
                    496:        /*
                    497:         *      We have two input buffers; the first one is reserved
                    498:         *      for catching the tail of a line split across a buffer
                    499:         *      boundary; the other one are used for snarfing a buffer
                    500:         *      worth of .s source.
                    501:         */
                    502: static char    inbuffer[INBUFLG];
                    503: static char    *InBufPtr = 0;
                    504: 
                    505: #ifdef getchar
                    506: #undef         getchar
                    507: #endif
                    508: #define        getchar() *inbufptr++
                    509: 
                    510: #ifdef ungetc
                    511: #undef         ungetc
                    512: #endif
                    513: #define        ungetc(char) *--inbufptr = char
                    514: 
                    515: /*
                    516:  *     fill the inbuffer from the standard input.
                    517:  *     Assert: there are always n COMPLETE! lines in the buffer area.
                    518:  *     Assert: there is always a \n terminating the last line
                    519:  *             in the buffer area.
                    520:  *     Assert: after the \n, there is an EOFCHAR (hard end of file)
                    521:  *             or a NEEDCHAR (end of buffer)
                    522:  *     Assert: fgets always null pads the string it reads.
                    523:  *     Assert: no ungetc's are done at the end of a line or at the
                    524:  *             beginning of a line.
                    525:  *     
                    526:  *     We read a complete buffer of characters in one single read.
                    527:  *     We then back scan within this buffer to find the end of the
                    528:  *     last complete line, and force the assertions, and save a pointer
                    529:  *     to the incomplete line.
                    530:  *     The next call to fillinbuffer will move the unread characters
                    531:  *     to the end of the first buffer, and then read another two buffers,
                    532:  *     completing the cycle.
                    533:  */
                    534: 
                    535: static char    p_swapped = '\0';                       
                    536: static char    *p_start = &inbuffer[NINBUFFERS * BUFSIZ];
                    537: static char    *p_stop = &inbuffer[NINBUFFERS * BUFSIZ];
                    538: char *fillinbuffer()
                    539: {
                    540:        register        char    *to;
                    541:        register        char    *from;
                    542:                        char    *inbufptr;
                    543:        int             nread;
                    544: 
                    545:        *p_start = p_swapped;
                    546:        inbufptr = &inbuffer[1*BUFSIZ] - (p_stop - p_start);
                    547: 
                    548:        for (to = inbufptr, from = p_start; from < p_stop;)
                    549:                *to++ = *from++;
                    550:        /*
                    551:         *      Now, go read two full buffers (hopefully)
                    552:         */
                    553:        nread = read(stdin->_file, &inbuffer[1*BUFSIZ], (NINBUFFERS - 1)*BUFSIZ);
                    554:        if (nread == 0)
                    555:                return(0);
                    556:        p_stop = from = &inbuffer[1*BUFSIZ + nread];
                    557:        *from = '\0';
                    558:        while (*--from != '\n')         /* back over the partial line */
                    559:                continue;
                    560:        from++;                         /* first char of partial line */
                    561:        p_start = from;
                    562:        p_swapped = *p_start;
                    563:        *p_start = NEEDCHAR;            /* force assertion */
                    564:        return(inbufptr);
                    565: }
                    566: 
                    567: scan_dot_s(bufferbox)
                    568:        struct tokbufdesc *bufferbox;
                    569: {
                    570:        register int            yylval;/*lexical value*/
                    571:        register toktype        val;    /*the value returned; the character read*/
                    572:        register int    base;           /*the base of the number also counter*/
                    573:        register        char    *cp;    
                    574:        register        char    *inbufptr;
                    575:        register        struct          symtab  *op;
                    576:        register        unsigned        char    tag;
                    577:        int             forb;
                    578: 
                    579:        register        ptrall  bufptr;         /*where to stuff tokens*/
                    580:                        ptrall  lgbackpatch;    /*where to stuff a string length*/
                    581:                        ptrall  bufub;          /*where not to stuff tokens*/
                    582:        register        int     maxstrlg;       /*how long a string can be*/
                    583:                        long    intval;         /*value of int*/
                    584:                        char    fltchr[64];     /*buffer for floating values*/
                    585:                union   Double  fltval;         /*floating value returned*/
                    586:                struct  Quad    quadval;        /*quad returned from immediate constant */
                    587:                        int     linescrossed;   /*when doing strings and comments*/
                    588: 
                    589:        (toktype *)bufptr = (toktype *) & (bufferbox->toks[0]); 
                    590:        (toktype *)bufub = &(bufferbox->toks[AVAILTOKS]);
                    591: 
                    592:        inbufptr = InBufPtr;
                    593:        if (inbufptr == 0){
                    594:                inbufptr = fillinbuffer();
                    595:                if (inbufptr == 0){     /*end of file*/
                    596:                  endoffile:
                    597:                        inbufptr = 0;
                    598:                        ptoken(bufptr, PARSEEOF);
                    599:                        goto done;
                    600:                }
                    601:        }
                    602: 
                    603:        if (newfflag){
                    604:                ptoken(bufptr, IFILE);
                    605:                ptoken(bufptr, STRING);
                    606:                val = strlen(newfname) + 1;
                    607:                movestr( (char *)&( ( (lgtype *)bufptr)[1]), newfname, val);
                    608:                bstrlg(bufptr, val);
                    609: 
                    610:                ptoken(bufptr, ILINENO);
                    611:                ptoken(bufptr, INT);
                    612:                pint(bufptr,  1);
                    613:                newfflag = 0;
                    614:        }
                    615: 
                    616:        while (bufptr < bufub){
                    617:    loop:
                    618:         switch(yylval = (type+2)[val = getchar()]) {
                    619:        case SCANEOF:
                    620:                inbufptr = 0;
                    621:                goto endoffile;
                    622: 
                    623:        case NEEDSBUF:
                    624:                inbufptr = fillinbuffer();
                    625:                if (inbufptr == 0)
                    626:                        goto endoffile;
                    627:                goto loop;
                    628: 
                    629:        case DIV:               /*process C style comments*/
                    630:                if ( (val = getchar()) == '*') {  /*comment prelude*/
                    631:                        int     incomment;
                    632:                        linescrossed = 0;
                    633:                        incomment = 1;
                    634:                        val = getchar();        /*skip over the * */
                    635:                        do{
                    636:                                while ( (val != '*') &&
                    637:                                        (val != '\n') &&
                    638:                                        (val != EOFCHAR) &&
                    639:                                        (val != NEEDCHAR))
                    640:                                                val = getchar();
                    641:                                if (val == '\n'){
                    642:                                        scanlineno++;
                    643:                                        linescrossed++;
                    644:                                } else
                    645:                                if (val == EOFCHAR)
                    646:                                        goto endoffile;
                    647:                                if (val == NEEDCHAR){
                    648:                                        inbufptr = fillinbuffer();
                    649:                                        if (inbufptr == 0)
                    650:                                                goto endoffile;
                    651:                                        lineno++;
                    652:                                        incomment = 1;
                    653:                                        val = getchar(); /*pull in the new char*/
                    654:                                } else {        /*its a star */
                    655:                                        val = getchar();
                    656:                                        incomment = val != '/';
                    657:                                }
                    658:                        } while (incomment);
                    659:                        val = ILINESKIP;
                    660:                        yylval = linescrossed;
                    661:                        goto ret;
                    662:                } else {        /*just an ordinary DIV*/
                    663:                        ungetc(val);
                    664:                        val = yylval = DIV;
                    665:                        goto ret;
                    666:                }
                    667:        case SH:
                    668:                if (oval == NL){
                    669:                        /*
                    670:                         *      Attempt to recognize a C preprocessor
                    671:                         *      style comment '^#[ \t]*[0-9]*[ \t]*".*"
                    672:                         */
                    673:                        val = getchar();        /*bump the #*/
                    674:                        while (INCHARSET(val, SPACE))
                    675:                                val = getchar();/*bump white */
                    676:                        if (INCHARSET(val, DIGIT)){
                    677:                                intval = 0;
                    678:                                while(INCHARSET(val, DIGIT)){
                    679:                                        intval = intval *10 + val - '0';
                    680:                                        val = getchar();
                    681:                                }
                    682:                                while (INCHARSET(val, SPACE))
                    683:                                        val = getchar();
                    684:                                if (val == '"'){
                    685:                                        ptoken(bufptr, ILINENO);
                    686:                                        ptoken(bufptr, INT);
                    687:                                        pint(bufptr, intval - 1);
                    688:                                        ptoken(bufptr, IFILE);
                    689:                                        /*
                    690:                                         *      The '"' has already been
                    691:                                         *      munched
                    692:                                         *      
                    693:                                         *      eatstr will not eat
                    694:                                         *      the trailing \n, so
                    695:                                         *      it is given to the parser
                    696:                                         *      and counted.
                    697:                                         */
                    698:                                        goto eatstr;
                    699:                                }
                    700:                        }
                    701:                }
                    702:                /*
                    703:                 *      Well, its just an ordinary decadent comment
                    704:                 */
                    705:                while ((val != '\n') && (val != EOFCHAR)) 
                    706:                        val = getchar();
                    707:                if (val == EOFCHAR)
                    708:                        goto endoffile;
                    709:                val = yylval = oval = NL;
                    710:                scanlineno++;
                    711:                goto ret;
                    712: 
                    713:        case NL:
                    714:                scanlineno++;
                    715:                val = yylval;
                    716:                goto ret;
                    717: 
                    718:        case SP:
                    719:                oval = SP;      /*invalidate ^# meta comments*/
                    720:                goto loop;
                    721: 
                    722:        case REGOP:             /* % , could be used as modulo, or register*/
                    723:                val = getchar();
                    724:                if (INCHARSET(val, DIGIT)){
                    725:                        yylval = val-'0';
                    726:                        if (val=='1') {
                    727:                                if (INCHARSET( (val = getchar()), REGDIGIT))
                    728:                                        yylval = 10+val-'0';
                    729:                                else
                    730:                                        ungetc(val);
                    731:                        }
                    732:                        /*
                    733:                         *      God only knows what the original author
                    734:                         *      wanted this undocumented feature to
                    735:                         *      do.
                    736:                         *              %5++ is really  r7
                    737:                         */
                    738:                        while(INCHARSET( (val = getchar()), SIGN)) {
                    739:                                if (val=='+')
                    740:                                        yylval++;
                    741:                                else
                    742:                                        yylval--;
                    743:                        }
                    744:                        ungetc(val);
                    745:                        val = REG;
                    746:                } else {
                    747:                        ungetc(val);
                    748:                        val = REGOP;
                    749:                }
                    750:                goto ret;
                    751: 
                    752:        case ALPH:
                    753:                yylval = val;
                    754:                if (INCHARSET(val, SZSPECBEGIN)){
                    755:                        if( (val = getchar()) == '`' || val == '^'){
                    756:                                yylval |= 0100; /*convert to lower*/
                    757:                                if (yylval == 'b') yylval = 1;
                    758:                                else if (yylval == 'w') yylval = 2;
                    759:                                else if (yylval == 'l') yylval = 4;
                    760:                                else                    yylval = d124;
                    761:                                val = SIZESPEC;
                    762:                                goto ret;
                    763:                        } else {
                    764:                                ungetc(val);
                    765:                                val = yylval;   /*restore first character*/
                    766:                        }
                    767:                }
                    768:                cp = yytext;
                    769:                do {
                    770:                        if (cp < &yytext[NCPS])
                    771:                                *cp++ = val;
                    772:                } while (INCHARSET ( (val = getchar()), ALPHA | DIGIT));
                    773:                *cp = '\0';
                    774:                while (INCHARSET(val, SPACE))
                    775:                        val = getchar();
                    776:                ungetc(val);
                    777:        doit:
                    778:                tag = (op = *lookup(1))->s_tag;
                    779:                if (tag && tag != LABELID){
                    780:                        yylval = ( (struct instab *)op)->i_opcode;
                    781:                        val = op->s_tag ;
                    782:                        goto ret;
                    783:                } else {
                    784:                        /*
                    785:                         *      Its a name... (Labels are subsets ofname)
                    786:                         */
                    787:                        yylval = (int)op;
                    788:                        val = NAME;
                    789:                        goto ret;
                    790:                }
                    791: 
                    792:        case DIG:
                    793:                base = 10;
                    794:                cp = fltchr;
                    795:                intval = 0;
                    796:                if (val=='0') {
                    797:                        val = getchar();
                    798:                        if (val == 'b') {
                    799:                                yylval = -1;
                    800:                                val = BFINT;
                    801:                                goto ret;
                    802:                        } 
                    803:                        if (val == 'f') {
                    804:                                /*
                    805:                                 *      Well, it appears to be a local label
                    806:                                 *      reference, but check to see if
                    807:                                 *      the next character makes it a floating
                    808:                                 *      point constant.
                    809:                                 */
                    810:                                forb = getchar();
                    811:                                ungetc(forb);
                    812:                                if (!(INCHARSET(forb,(DIGIT|SIGN|FLOATEXP|POINT)))){
                    813:                                        yylval = 1;
                    814:                                        val = BFINT;
                    815:                                        goto ret;
                    816:                                }
                    817:                        }
                    818:                        if (INCHARSET(val, HEXFLAG)){
                    819:                                base = 16;
                    820:                        } else
                    821:                        if (INCHARSET(val, FLOATFLAG)){
                    822:                                double atof();
                    823:                                while ( (cp < &fltchr[63]) &&
                    824:                                        INCHARSET(
                    825:                                                (val=getchar()),
                    826:                                                (DIGIT|SIGN|FLOATEXP|POINT)
                    827:                                              )
                    828:                                      ) *cp++ = val;
                    829:                                if (cp == fltchr) {
                    830:                                        yylval = 1;
                    831:                                        val = BFINT;
                    832:                                        goto ret;
                    833:                                }
                    834:                                ungetc(val);
                    835:                                *cp++ = '\0';
                    836:                                fltval.dvalue = atof(fltchr);
                    837:                                val = FLTNUM;
                    838:                                goto ret;
                    839:                        } else {
                    840:                                ungetc(val);
                    841:                                base = 8;
                    842:                        }
                    843:                } else {
                    844:                        forb = getchar();
                    845:                        if (forb == 'f' || forb == 'b') {
                    846:                                yylval = val - '0' + 1;
                    847:                                if (forb == 'b')
                    848:                                        yylval = -yylval;
                    849:                                val = BFINT;
                    850:                                goto ret;
                    851:                        }
                    852:                        ungetc(forb);   /* put back non zero */
                    853:                        goto middle;
                    854:                }
                    855:                while ( (val = getchar()) == '0')
                    856:                        continue;
                    857:                ungetc(val);
                    858:                while ( INCHARSET( (val = getchar()), DIGIT) || 
                    859:                        (base==16 && (INCHARSET(val, HEXLDIGIT|HEXUDIGIT) )
                    860:                           )
                    861:                      ){
                    862:                        if (base==8)
                    863:                                intval <<= 3;
                    864:                        else if (base==10)
                    865:                                intval *= 10;
                    866:                        else {
                    867:                                intval <<= 4;
                    868:                                if (INCHARSET(val, HEXLDIGIT))
                    869:                                        val -= 'a' - 10 - '0';
                    870:                                else if (INCHARSET(val, HEXUDIGIT))
                    871:                                        val -= 'A' - 10 - '0';
                    872:                        }
                    873: middle:
                    874:                        *cp++ = (val -= '0');
                    875:                        intval += val;
                    876:                }
                    877:                ungetc(val);
                    878:                *cp = 0;
                    879:                maxstrlg = cp - fltchr;
                    880:                if (   (maxstrlg > 8)
                    881:                    && (   (   (base == 8)
                    882:                            && (   (maxstrlg>11)
                    883:                                || (   (maxstrlg == 11)
                    884:                                    && (*fltchr > 3)
                    885:                                   )
                    886:                                )
                    887:                           )
                    888:                        || (   (base == 16)
                    889:                            && (maxstrlg > 8)
                    890:                           )
                    891:                        || (   (base == 10)
                    892:                            && (maxstrlg >= 10)
                    893:                           )
                    894:                        )
                    895:                ) {
                    896:                        val = QUAD;
                    897:                        get_quad(base, fltchr, cp, &quadval);
                    898:                } else
                    899:                        val = INT;
                    900:                goto ret;
                    901: 
                    902:        case LSH:
                    903:        case RSH:
                    904:                /*
                    905:                 *      We allow the C style operators
                    906:                 *      << and >>, as well as < and >
                    907:                 */
                    908:                if ( (base = getchar()) != val)
                    909:                        ungetc(base);
                    910:                val = yylval;
                    911:                goto ret;
                    912: 
                    913:        case MINUS:
                    914:                if ( (val = getchar()) =='(')
                    915:                        yylval=val=MP;
                    916:                else {
                    917:                        ungetc(val);
                    918:                        val=MINUS;
                    919:                }
                    920:                goto ret;
                    921: 
                    922:        case SQ:
                    923:                if ((yylval = getchar()) == '\n')
                    924:                        scanlineno++;           /*not entirely correct*/
                    925:                intval = yylval;
                    926:                val = INT;
                    927:                goto ret;
                    928: 
                    929:        case DQ:
                    930:           eatstr:
                    931:                linescrossed = 0;
                    932:                maxstrlg = (char *)bufub - (char *)bufptr;
                    933: 
                    934:                if (maxstrlg < MAXSTRLG) {
                    935:                        ungetc('"');
                    936:                        *(toktype *)bufptr = VOID ;
                    937:                        bufub = bufptr;
                    938:                        goto done;
                    939:                }
                    940:                if (maxstrlg > MAXSTRLG)
                    941:                        maxstrlg = MAXSTRLG;
                    942:                
                    943:                ptoken(bufptr, STRING);
                    944:                lgbackpatch = bufptr;   /*this is where the size goes*/
                    945:                bufptr += sizeof(lgtype);
                    946:                /*
                    947:                 *      bufptr is now set to
                    948:                 *      be stuffed with characters from
                    949:                 *      the input
                    950:                 */
                    951: 
                    952:                while (   (maxstrlg > 0)
                    953:                       && !(INCHARSET( (val = getchar()), STRESCAPE))
                    954:                      ){
                    955:                        stuff:
                    956:                                maxstrlg-= 1;
                    957:                                pchar(bufptr, val);
                    958:                        }
                    959:                if (maxstrlg <= 0){     /*enough characters to fill a string buffer*/
                    960:                        ungetc('"');            /*will read it next*/
                    961:                }
                    962:                else if (val == '"');           /*done*/
                    963:                else if (val == '\n'){
                    964:                        yywarning("New line embedded in a string constant.");
                    965:                        scanlineno++;
                    966:                        linescrossed++;
                    967:                        val = getchar();
                    968:                        if (val == EOFCHAR){
                    969:                          do_eof:
                    970:                                pchar(bufptr, '\n');
                    971:                                ungetc(EOFCHAR);
                    972:                        } else
                    973:                        if (val == NEEDCHAR){
                    974:                                if ( (inbufptr = fillinbuffer()) == 0)
                    975:                                        goto do_eof;
                    976:                                val = '\n';
                    977:                                goto stuff;
                    978:                        } else {        /* simple case */
                    979:                                ungetc(val);
                    980:                                val = '\n';
                    981:                                goto stuff;
                    982:                        }
                    983:                } else {
                    984:                        val = getchar();                /*skip the '\\'*/
                    985:                        if ( INCHARSET(val, BSESCAPE)){
                    986:                                switch (val){
                    987:                                  case 'b':  val = '\b'; goto stuff;
                    988:                                  case 'f':  val = '\f'; goto stuff;
                    989:                                  case 'n':  val = '\n'; goto stuff;
                    990:                                  case 'r':  val = '\r'; goto stuff;
                    991:                                  case 't':  val = '\t'; goto stuff;
                    992:                                }
                    993:                        }
                    994:                        if ( !(INCHARSET(val,OCTDIGIT)) )  goto stuff;
                    995:                        base = 0;
                    996:                        intval = 0;
                    997:                        while ( (base < 3) && (INCHARSET(val, OCTDIGIT))){
                    998:                                base++;intval <<= 3;intval += val - '0';
                    999:                                val = getchar();
                   1000:                        }
                   1001:                        ungetc(val);
                   1002:                        val = (char)intval;
                   1003:                        goto stuff;
                   1004:                }
                   1005:                /*
                   1006:                 *      bufptr now points at the next free slot
                   1007:                 */
                   1008:                bstrfromto(lgbackpatch, bufptr);
                   1009:                if (linescrossed){
                   1010:                        val = ILINESKIP;
                   1011:                        yylval = linescrossed;
                   1012:                        goto ret;
                   1013:                } else
                   1014:                        goto builtval;
                   1015: 
                   1016:        case BADCHAR:
                   1017:                linescrossed = lineno;
                   1018:                lineno = scanlineno;
                   1019:                yyerror("Illegal character mapped: %d, char read:(octal) %o",
                   1020:                        yylval, val);
                   1021:                lineno = linescrossed;
                   1022:                val = BADCHAR;
                   1023:                goto ret;
                   1024: 
                   1025:        default:
                   1026:                val = yylval;
                   1027:                goto ret;
                   1028:        }       /*end of the switch*/
                   1029:        /*
                   1030:         *      here with one token, so stuff it
                   1031:         */
                   1032:        ret:    
                   1033:        oval = val;
                   1034:        ptoken(bufptr, val);
                   1035:        switch(val){
                   1036:                case    ILINESKIP:
                   1037:                                pint(bufptr, yylval);
                   1038:                                break;
                   1039:                case    SIZESPEC:
                   1040:                                pchar(bufptr, yylval);
                   1041:                                break;
                   1042:                case    BFINT:  plong(bufptr, yylval);
                   1043:                                break;
                   1044:                case    INT:    plong(bufptr, intval);
                   1045:                                break;
                   1046:                case    QUAD:   plong(bufptr, quadval.quad_low_long);
                   1047:                                plong(bufptr, quadval.quad_high_long);
                   1048:                                break;
                   1049:                case    FLTNUM: pdouble(bufptr, fltval.dvalue);
                   1050:                                break;
                   1051:                case    NAME:   pptr(bufptr, (int)(struct symtab *)yylval);
                   1052:                                break;
                   1053:                case    REG:    pchar(bufptr, yylval);
                   1054:                                break;  
                   1055:                case    INST0:
                   1056:                case    INSTn:
                   1057:                                pchar(bufptr, yylval);
                   1058:                                break;
                   1059:                case    IJXXX:
                   1060:                                pchar(bufptr, yylval);
                   1061:                                pptr(bufptr, (int)(struct symtab *)symalloc());
                   1062:                                break;
                   1063:                case    ISTAB:
                   1064:                case    ISTABSTR:
                   1065:                case    ISTABNONE:
                   1066:                case    ISTABDOT:
                   1067:                case    IALIGN:
                   1068:                                pptr(bufptr, (int)(struct symtab *)symalloc());
                   1069:                                break;
                   1070:        /*
                   1071:         *      default:
                   1072:         */
                   1073:         }
                   1074:         builtval: ;
                   1075:    }                   /*end of the while to stuff the buffer*/
                   1076:    done:
                   1077:        bufferbox->tok_count = (toktype *)bufptr - &(bufferbox->toks[0]);
                   1078: 
                   1079:        /*
                   1080:         *      This is a real kludge:
                   1081:         *
                   1082:         *      We put the last token in the buffer to be  a MINUS
                   1083:         *      symbol.  This last token will never be picked up
                   1084:         *      in the normal way, but can be looked at during
                   1085:         *      a peekahead look that the short circuit expression
                   1086:         *      evaluator uses to see if an expression is complicated.
                   1087:         *
                   1088:         *      Consider the following situation:
                   1089:         *
                   1090:         *      .word   45              +       47
                   1091:         *        buffer 1      |  buffer 0
                   1092:         *      the peekahead would want to look across the buffer,
                   1093:         *      but will look in the buffer end zone, see the minus, and
                   1094:         *      fail.
                   1095:         */
                   1096:        ptoken(bufptr, MINUS);
                   1097:        InBufPtr = inbufptr;            /*copy this back*/
                   1098: }
                   1099: 
                   1100: struct Quad _quadtemp;
                   1101: get_quad(radix, cp_start, cp_end, quadptr)
                   1102:        int     radix;
                   1103:        char    *cp_start, *cp_end;
                   1104:        struct  Quad *quadptr;
                   1105: {
                   1106:        register                char    *cp = cp_start; /* r11 */
                   1107:        register        struct  Quad    *qp = quadptr;  /* r10 */
                   1108:        register        long    temp;                   /* r9 */
                   1109: 
                   1110:        asm("clrq (r10)");
                   1111:        for (; cp < cp_end; cp++){
                   1112:                switch (radix) {
                   1113:                        case 8:
                   1114:                                asm ("ashq $3, (r10), (r10)");
                   1115:                                break;
                   1116:                        case 16:
                   1117:                                asm ("ashq $4, (r10), (r10)");
                   1118:                                break;
                   1119:                        case 10:
                   1120:                                asm ("ashq      $1, (r10), __quadtemp");
                   1121:                                asm ("ashq      $3, (r10), (r10)");
                   1122:                                asm ("addl2     __quadtemp, (r10)");
                   1123:                                asm ("adwc      __quadtemp+4, 4(r10)");
                   1124:                                break;
                   1125:                }
                   1126:                asm ("cvtbl     (r11), r9");
                   1127:                asm ("addl2     r9, (r10)");
                   1128:                asm ("adwc      $0, 4(r10)");
                   1129:        }
                   1130: }

unix.superglobalmegacorp.com

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