|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)scan.c 1.1 86/02/03 Copyr 1985 Sun Micro"; ! 3: #endif ! 4: ! 5: /* ! 6: * Copyright (c) 1985 by Sun Microsystems, Inc. ! 7: */ ! 8: ! 9: #include "as.h" ! 10: ! 11: /* process lines from source file, returns when EOF detected */ ! 12: ! 13: #define LSIZE 4*BUFSIZ+2 /* max size of input line + fudge */ ! 14: ! 15: char *sassign(),*sdefer(),*exp(),*term(); ! 16: struct ins_bkt * sopcode(); ! 17: int slabel(); ! 18: ! 19: char iline[LSIZE]; /* current input line resides */ ! 20: int line_no; /* current input line number */ ! 21: char code[CODE_MAX]; /* where generated code is stored */ ! 22: long dot; /* offset in current csect */ ! 23: int bc; /* size of code for current line */ ! 24: int opshow = 0; ! 25: long break_line = -1, break_pass = 1; ! 26: ! 27: /* for local labels: ``[0-9]:'', and references ``[0-9][bh]'' */ ! 28: extern char *ll_format; ! 29: extern int ll_val[10]; ! 30: ! 31: scan() ! 32: { ! 33: register int i; ! 34: register char *p; /* pointer into input line */ ! 35: char *token; /* pointer to beginning of last token */ ! 36: struct ins_bkt * opindex;/* index of opcode on current line */ ! 37: # ifdef C2 ! 38: char *docomment(); ! 39: # endif ! 40: ! 41: #ifdef AS ! 42: /* setup stupid local-lable array */ ! 43: for( i = 0; i < 10; ll_val[i++] = -1 ) ; ! 44: #endif ! 45: ! 46: while (iline[LSIZE-2]='\0', fgets(iline,LSIZE,stdin) == iline) { ! 47: line_no++; ! 48: #ifdef AS ! 49: if (line_no == break_line && pass == break_pass) break_here(); ! 50: #endif ! 51: #ifdef C2 ! 52: if (line_no == break_line ) break_here(); ! 53: #endif ! 54: /* a cheap way to find if the line was too long */ ! 55: if (iline[LSIZE-2] != '\0'){ PROG_ERROR(E_LINELONG); continue; } ! 56: p = iline; ! 57: ! 58: /* see what's the first thing on the line. if newline or comment ! 59: * char just ignore line all together. if start of symbol see ! 60: * what follows. otherwise error. ! 61: */ ! 62: restart: skipb(p); ! 63: i = cinfo[*p]; /* see what we know about next char */ ! 64: /* hack to make # in col 1 a comment -- for cpp leavings */ ! 65: if (i == EOL || i == IMM) { ! 66: /* further hack to make ; in line act as seperator. */ ! 67: if (*p == ';'){ p++; goto restart;} ! 68: # ifdef C2 ! 69: p = docomment(p); ! 70: if (p==NULL) ! 71: return 1; /* special return */ ! 72: # endif ! 73: continue; ! 74: } ! 75: if (!(i & (S|D))) { PROG_ERROR(E_BADCHAR); continue; } ! 76: bc = 0; ! 77: # ifdef AS ! 78: code_length = 0; ! 79: # endif ! 80: ! 81: /* what follows is either label or opcode, gobble it up */ ! 82: token = p; ! 83: skips(p); ! 84: skipb(p); ! 85: i = cinfo[*p]; ! 86: ! 87: /* if next char is ":", this is label definition */ ! 88: if (i == COL) { p++; slabel(token); goto restart; } ! 89: ! 90: /* if next char is "=", this is label assignment */ ! 91: if (i == EQL) { ! 92: p = sassign(++p,token); ! 93: if (cinfo[*p] != EOL) PROG_ERROR(E_BADCHAR); ! 94: /* hack to make ; in line act as seperator. */ ! 95: if (*p == ';'){ p++; goto restart;} ! 96: continue; ! 97: } ! 98: ! 99: /* otherwise this must be opcode, find its index */ ! 100: if ((opindex = sopcode(token)) == 0) { ! 101: PROG_ERROR(E_OPCODE); ! 102: continue; ! 103: } ! 104: ! 105: if (i == EOL) { numops = 0; goto doins; } ! 106: ! 107: /* keep reading operands until we run out of room or hit EOL */ ! 108: for (numops = 1; numops <= OPERANDS_MAX; numops++) { ! 109: p = soperand(p,&operands[numops-1]); ! 110: skipb(p); ! 111: i = cinfo[*p]; ! 112: if (i == COM) { p++; skipb(p); continue; } ! 113: if (i == EOL) goto doins; ! 114: PROG_ERROR(E_OPERAND); ! 115: goto next; ! 116: } ! 117: PROG_ERROR(E_NUMOPS); ! 118: next: continue; ! 119: ! 120: doins: ! 121: instruction(opindex); ! 122: dot += bc; ! 123: dot_bkt->value_s = dot; ! 124: ! 125: /* hack to make ; in line act as seperator. */ ! 126: if (*p == ';'){ p++; goto restart;} ! 127: } ! 128: return 0; /* normal exit */ ! 129: } /* end Scan */ ! 130: ! 131: /* lookup token in opcode hash table, return 0 if not found */ ! 132: struct ins_bkt * ! 133: sopcode(token) ! 134: register char *token; ! 135: { ! 136: register struct ins_ptr *ipp; ! 137: char *mnem = token; ! 138: char savechar; ! 139: ! 140: /* make asciz version of mnemonic */ ! 141: while (cinfo[*token] & T) token++; ! 142: savechar = *token; ! 143: *token = '\0'; ! 144: ! 145: /* look through appropriate hash bucket */ ! 146: ipp = ins_hash_tab[hash(mnem)]; ! 147: while (ipp) { ! 148: if (strcmp(ipp->name_p,mnem) == 0) break; ! 149: ipp = ipp->next_p; ! 150: } ! 151: *token = savechar; ! 152: ! 153: if( ipp == 0) return 0; ! 154: return(ipp->this_p); ! 155: } /* end sopcode */ ! 156: ! 157: ! 158: /* handle assignment to a label, return updated line pointer */ ! 159: char * ! 160: sassign(lptr,token) ! 161: register char *token; ! 162: register char *lptr; ! 163: { ! 164: register char *p; ! 165: register struct sym_bkt *sbp; ! 166: struct oper value; ! 167: char nextc; ! 168: static struct oper zero_oper = { T_NULL, 0, 0, 0, 0, NULL}; ! 169: ! 170: /* make asciz version of label */ ! 171: p = token; ! 172: while (cinfo[*p] & T) p++; ! 173: nextc = *p; ! 174: *p = '\0'; ! 175: value = zero_oper; ! 176: ! 177: /* find/enter symbol in the symbol table, and get its new value */ ! 178: sbp = lookup(token); ! 179: lptr = exp(lptr,&value); ! 180: ! 181: /* if assignment is to dot, we'll treat it specially */ ! 182: if (sbp == dot_bkt) { ! 183: #ifdef AS ! 184: int deltadot; ! 185: #endif AS ! 186: if (value.sym_o && value.sym_o->csect_s!=cur_csect_name) ! 187: PROG_ERROR(E_OPERAND); ! 188: #ifdef AS ! 189: deltadot = value.value_o - dot; ! 190: if (deltadot<0) ! 191: PROG_ERROR(E_OPERAND); ! 192: operands[0].value_o = deltadot; ! 193: skip_op( NULL ); ! 194: #endif ! 195: } else { ! 196: if (value.sym_o != NULL) { ! 197: sbp->value_s = value.sym_o->value_s; ! 198: } else { ! 199: sbp->value_s = value.value_o; ! 200: } ! 201: sbp->csect_s = (value.sym_o!=NULL) ? value.sym_o->csect_s : C_UNDEF; ! 202: if (sbp->attr_s & S_LABEL) { ! 203: PROG_ERROR(E_EQUALS); ! 204: } else if (value.type_o == T_REG) ! 205: sbp->attr_s = (sbp->attr_s&S_EXT) | S_REG | S_DEC | S_DEF; ! 206: else ! 207: sbp->attr_s = (sbp->attr_s&S_EXT) | ! 208: ((value.sym_o!=NULL) ? ! 209: (value.sym_o->attr_s & ~(S_LABEL|S_PERM)): (S_DEC | S_DEF)); ! 210: } ! 211: ! 212: if (opshow) fprintf(stderr,"sassign(%s) = %ld, %ld\n", ! 213: token, value.value_o, sbp->attr_s); ! 214: #if C2 ! 215: /* echo assignment immediately. RHS involving (.) will break. Fix later */ ! 216: printf(" %s = ", sbp->name_s); ! 217: printoperand( &value ); ! 218: putchar('\n'); ! 219: #endif ! 220: ! 221: *p = nextc; ! 222: ! 223: /* return update line pointer */ ! 224: skipb(lptr); ! 225: return(lptr); ! 226: } /* end sassign */ ! 227: ! 228: /* hashing routine for Symbol and Instruction hash tables */ ! 229: hash(s) ! 230: register char *s; ! 231: { ! 232: register int i = 0; ! 233: ! 234: while (*s) i = i*10 + *s++ - ' '; ! 235: i = i % HASH_MAX; ! 236: return(i<0 ? i+HASH_MAX : i); ! 237: } /* end hash */ ! 238: ! 239: ! 240: break_here(){ }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.