Annotation of researchv9/cmd/sun/as/scan.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)scan.c 1.1 86/02/03 Copyr 1984 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1984 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include "as.h"
                     10: #include "scan.h" 
                     11: #include <sys/signal.h>
                     12: 
                     13: /* process lines from source file, returns when EOF detected */
                     14: 
                     15: #define LSIZE  4*BUFSIZ+2      /* max size of input line + fudge */
                     16: 
                     17: 
                     18: char *sassign(),*exp(),*term();
                     19: struct ins_bkt * sopcode();
                     20: int slabel();
                     21: 
                     22: char iline[LSIZE];     /* current input line resides */
                     23: int  line_no;          /* current input line number */
                     24: char code[CODE_MAX];   /* where generated code is stored */
                     25: long dot;              /* offset in current csect */
                     26: int  bc;               /* size of code for current line */
                     27: int  opshow = 0;
                     28: long break_line = -1, break_pass = 1;
                     29: 
                     30: /* for local labels: ``[0-9]:'', and references ``[0-9][bh]'' */
                     31: extern int   ll_val[10];
                     32: extern char * ll_format;
                     33: 
                     34: sexit(){
                     35:        exit(3);
                     36: }
                     37: 
                     38: main(argc,argv)
                     39:        char *argv[];
                     40: {
                     41:        stabkt_head = stabkt_tail = NULL;      /* initialize stabs/d  symbol table */
                     42:        signal( SIGINT, sexit );
                     43:        init(argc,argv);                       /* Initialization */
                     44:        scan();                                /* 1st pass through .s file */
                     45:        prog_end();                            /* end of 1st pass          */
                     46: 
                     47:        /*
                     48:        * Resolve the unresolved addresses in .stabs and .stabd directives.
                     49:        * .stabs type 0x24 (N_Fun for procedure name), 0x26 (N_STSYM for static
                     50:        * symbol), and 0x64 (N_SO for source file name) have a labeled-address
                     51:        * tagged in the directive in the last field "value".  These addresses
                     52:        * have to be resolved during or before the 2nd Pass (in this version
                     53:        * resolved before the second pass).
                     54:        */
                     55: 
                     56:        scan();                        /* 2nd pass through .s file */
                     57:        prog_end();                    /* end of 2nd pass          */
                     58:        exit(errors? -1: 0);
                     59: } /* end main */
                     60: 
                     61: scan()
                     62: {
                     63:        register int i;
                     64:        register char *p;        /* pointer into input line */
                     65:        char *token;             /* pointer to beginning of last token */
                     66:        struct ins_bkt * opindex;/* index of opcode on current line */
                     67:        struct oper exp_arg ;    /* argument for exp */
                     68: 
                     69:        /* setup stupid local-lable array */
                     70:        for( i = 0; i < 10; ll_val[i++] = -1 ) ;
                     71: 
                     72: one_more_file:
                     73:        while (iline[LSIZE-2]='\0', fgets(iline,LSIZE,source_file[current_file]) == iline) {
                     74:              line_no++;
                     75:              if (line_no == break_line && pass == break_pass) break_here();
                     76:              /* a cheap way to find if the line was too long */
                     77:              if (iline[LSIZE-2] != '\0'){ PROG_ERROR(E_LINELONG); continue; }
                     78:              p = iline;
                     79: 
                     80:              /* see what's the first thing on the line. if newline or comment
                     81:               * char just ignore line all together.  if start of symbol see
                     82:               * what follows.  otherwise error.
                     83:               */
                     84:  restart:      skipb(p);
                     85:              i = cinfo[*p];    /* see what we know about next char */
                     86:              /* hack to make # in col 1 a comment -- for cpp leavings */
                     87:              if (i == EOL || i == IMM) {
                     88:                  /* further hack to make ; in line act as seperator. */
                     89:                  if (*p == ';'){ p++; goto restart;}
                     90:                  continue;
                     91:              }
                     92:              if (!(i & (S|D))) { PROG_ERROR(E_BADCHAR); continue; }
                     93:              bc = 0;
                     94:              code_length = 0;
                     95: 
                     96:              /* what follows is either label or opcode, gobble it up */
                     97:              token = p;
                     98:              skips(p);
                     99:              skipb(p);
                    100:              i = cinfo[*p];
                    101: 
                    102:              /* if next char is ":", this is label definition */
                    103:              if (i == COL) { p++; slabel(token); goto restart; }
                    104: 
                    105:              /* if next char is "=", this is label assignment */
                    106:              if (i == EQL) {
                    107:                    p = sassign(++p,token);
                    108:                    if (cinfo[*p] != EOL) PROG_ERROR(E_BADCHAR);
                    109:                    goto update;
                    110:              }
                    111:  
                    112:               /* check for cpid following op code */
                    113:  
                    114:                 if (i == IND)
                    115:                         {    
                    116:                         *p = ' ' ;      /* Blank out the @ sign. */
                    117:                         p = p + 1 ;     /* Increment pointer past @. */
                    118:                         p = exp(p, &exp_arg) ; /* Evaluate current cpid.*/
                    119:                         current_cpid = exp_arg.value_o ;
                    120:                         skipb(p) ;      /* Skip blanks to next field. */
                    121:                         }
                    122:                 else
                    123:                         current_cpid = implicit_cpid ;
                    124: 
                    125: 
                    126:              /* otherwise this must be opcode, find its index */
                    127:              if ((opindex = sopcode(token)) == 0) {
                    128:                PROG_ERROR(E_OPCODE);
                    129:                continue;
                    130:              }
                    131: 
                    132:              if (i == EOL) { numops = 0; goto doins; }
                    133: 
                    134:              /* keep reading operands until we run out of room or hit EOL */
                    135:              for (numops = 1; numops <= OPERANDS_MAX; numops++) {
                    136:                    p = soperand(p,&operands[numops-1]);
                    137:                    if (opshow) printop(&operands[numops-1]);
                    138:                    skipb(p);
                    139:                    i = cinfo[*p];
                    140:                    if (i == COM) { p++; skipb(p); continue; }
                    141:                    if (i == EOL) goto doins;
                    142:                    PROG_ERROR(E_OPERAND);
                    143:                    goto next;
                    144:              }
                    145:              PROG_ERROR(E_NUMOPS);
                    146:   next:              continue;
                    147: 
                    148:   doins:      instruction(opindex);
                    149:   update:     dot += bc;
                    150:              dot_bkt->value_s = dot;
                    151:          
                    152:              /* hack to make ; in line act as seperator. */
                    153:              if (*p == ';'){ p++; goto restart;}
                    154:        }
                    155:        if (pass == 1)
                    156:                rewind(source_file[current_file]);
                    157:        if (current_file < file_count-1) {
                    158:                current_file++;
                    159:                goto one_more_file;};
                    160: } /* end Scan */
                    161: 
                    162: /* lookup token in opcode hash table, return 0 if not found */
                    163: struct ins_bkt * 
                    164: sopcode(token)
                    165:   register char *token;
                    166: {
                    167:   register struct ins_ptr *ipp;
                    168:   char *mnem = token;
                    169:   char savechar;
                    170: 
                    171:   /* make asciz version of mnemonic */
                    172:   while (cinfo[*token] & T) token++;
                    173:   savechar = *token;
                    174:   *token = '\0';
                    175: 
                    176:   /* look through appropriate hash bucket */
                    177:   ipp = ins_hash_tab[hash(mnem)];
                    178:   while (ipp) { 
                    179:        if (strcmp(ipp->name_p,mnem) == 0) break;
                    180:          ipp = ipp->next_p;
                    181:        }
                    182:   *token = savechar;
                    183: 
                    184:   if( ipp == 0) return 0;
                    185:   return(ipp->this_p);
                    186: } /* end sopcode */
                    187: 
                    188: /* handle definition of label */
                    189: slabel(t)
                    190:     char * t;
                    191: {
                    192:     register char *token = t;
                    193:     register char *p;
                    194:     struct sym_bkt *sbp;
                    195:     char nextc;
                    196:     static char ltoken[20];
                    197: 
                    198:     /* make asciz version of label */
                    199:     p = token;
                    200:     while (cinfo[*p] & T) p++;
                    201:     nextc = *p; /* may be a , a + a \n ... */
                    202:     *p = '\0';
                    203: 
                    204:     /* look for numeric-only labels, as opposed to numeric-$ labels */
                    205:     if ( (p == token+1) && (cinfo[token[0]]&D)){
                    206:        sprintf( ltoken, ll_format, token[0], ++ll_val[token[0]-'0'] );
                    207:        token=ltoken;
                    208:     }
                    209: 
                    210:     /* find/enter symbol in the symbol table */
                    211:     sbp = lookup(token);
                    212: 
                    213:     /* on pass 1 look for multiply defined symbols.  if ok, label
                    214:        value is dot in current csect
                    215:     */
                    216: #ifdef EBUG
                    217:     if (debflag)
                    218:        printf("Label %s, line %d offset 0x%X\n", sbp->name_s, line_no, dot );
                    219: #endif
                    220:     if (pass==1) { 
                    221:        if (sbp->attr_s & (S_LABEL|S_REG)) {
                    222:                prog_error(E_MULTSYM);
                    223:        }
                    224:         sbp->attr_s |= S_LABEL | S_DEC | S_DEF;
                    225:         sbp->csect_s = cur_csect_name;
                    226:        if (cur_csect_name == C_TEXT)
                    227:            ntlabels += 1;      /* count text labels */
                    228:         sbp->value_s = dot;
                    229:     } 
                    230:     else if (sbp->csect_s!=cur_csect_name || sbp->value_s!=dot){
                    231:        prog_error(E_PHASE);
                    232: #ifdef EBUG
                    233:        if (debflag)
                    234:            printf("    was 0x%x, but is 0x%x\n", sbp->value_s, dot);
                    235: #endif
                    236:     }
                    237: 
                    238:     if (!(cinfo[t[0]] & D)) 
                    239:        last_symbol = sbp;
                    240: 
                    241: /* fprintf(stderr,"slabel(%s) = %ld\n",token,Dot); */
                    242: 
                    243:     *p = nextc; /* replace next character before proceeding */
                    244: } /* end slabel */
                    245: 
                    246: /* handle assignment to a label, return updated line pointer */
                    247: char *
                    248: sassign(lptr,token)
                    249:   register char *token;
                    250:   register char *lptr;
                    251: {
                    252:   register char *p;
                    253:   register struct sym_bkt *sbp;
                    254:   struct oper value;
                    255:   char nextc;
                    256: 
                    257:   /* make asciz version of label */
                    258:   p = token;
                    259:   while (cinfo[*p] & T) p++;
                    260:   nextc = *p;
                    261:   *p = '\0';
                    262: 
                    263:   /* find/enter symbol in the symbol table, and get its new value */
                    264:   sbp = lookup(token);
                    265:   lptr = exp(lptr,&value);
                    266: 
                    267:   /* if assignment is to dot, we'll treat it specially */
                    268:   if (sbp == dot_bkt) {
                    269:        int deltadot;
                    270:        static char zed[1024];
                    271:        if (value.sym_o && value.sym_o->csect_s!=cur_csect_name)
                    272:            PROG_ERROR(E_OPERAND);
                    273:        deltadot = value.value_o - dot;
                    274:        if (deltadot<0)
                    275:            PROG_ERROR(E_OPERAND);
                    276: 
                    277:        operands[0].value_o = deltadot;
                    278:        skip_op( NULL );
                    279:   } else {
                    280:        sbp->value_s = value.value_o;
                    281:        sbp->csect_s = (value.sym_o!=NULL) ? value.sym_o->csect_s : C_UNDEF;
                    282:        if (sbp->csect_s  == C_TEXT)
                    283:            ntlabels += 1;      /* count text labels */
                    284:        if (sbp->attr_s & S_LABEL) {
                    285:             PROG_ERROR(E_EQUALS);
                    286:        } else if (value.type_o == T_REG)
                    287:            sbp->attr_s = (sbp->attr_s&S_EXT) | S_REG | S_DEC | S_DEF;
                    288:        else
                    289:            sbp->attr_s = (sbp->attr_s&S_EXT)  |
                    290:                ((value.sym_o!=NULL) ?
                    291:                 (value.sym_o->attr_s & ~(S_LABEL|S_PERM)): (S_DEC | S_DEF));
                    292:    }
                    293: 
                    294:    if (opshow) fprintf(stderr,"sassign(%s) = %ld, %ld\n",
                    295:        token, value.value_o, sbp->attr_s);
                    296: 
                    297:     *p = nextc;
                    298: 
                    299:     /* return update line pointer */
                    300:     skipb(lptr);
                    301:     return(lptr);
                    302: } /* end sassign */
                    303: 
                    304: /* hashing routine for Symbol and Instruction hash tables */
                    305: hash(s)
                    306:        register char *s;
                    307: {
                    308:        register int i = 0;
                    309: 
                    310:        while (*s) i = i*10 + *s++ - ' ';
                    311:        i = i % HASH_MAX;
                    312:        return(i<0 ? i+HASH_MAX : i);
                    313: } /* end hash */
                    314: 
                    315: break_here(){ }

unix.superglobalmegacorp.com

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