Interdata_v6/usr/source/as/as5.c
/*
* Assembler symbol table management
*
*
* Copyright (C) 1978, Richard Miller
*/
#define EXTERN extern
#include "as.h"
#define NSYM 100 /* initial no. of symbols */
#define SYMINC 100 /* increment for symtab expansion */
#define HASHSIZE 199 /* size of hashed index to symtab
should be prime for best distribution */
/*
* Hashing function for symbol table index:
* defined as a macro for speed
*/
#define hash(name) ((((unsigned *)name)[0]+((unsigned *)name)[1])%HASHSIZE)
struct symbol *hashtab[HASHSIZE]; /* index to symbol table */
extern struct optab opcodes[]; /* built-in opcodes */
extern struct symbol predefs[]; /* pre-defined symbols */
/*
* Initialize symbol table:
* - enter opcodes into hashed index
* - allocate initial space for user-defined symbols
* - initialize predefined symbols
*/
syminit()
{
register struct symbol *sp, **hp;
register struct optab *op;
for (op = opcodes; op->name[0]; op++) {
hp = &hashtab[hash(op->name)];
op->next = *hp;
*hp = op;
}
nextsym = usymtab = sbrk(0);
brk(symtop = nextsym + NSYM);
for (sp = predefs; sp->name[0]; sp++) {
enter(sp->name);
cursym->type = sp->type;
cursym->value = sp->value;
}
}
/*
* Append symbol table to object file
*/
symout()
{
register struct symbol *sp;
register char c, *p;
seek(ofile, symseek, 0);
for (sp = usymtab; sp < nextsym; sp++) {
/*
* relocate
*/
switch (sp->type&SSEG) {
case SCOMN:
/* change common block members to absolute */
sp->type = SABS;
break;
case SBSS:
sp->value += hdr.dsize;
case SDATA:
sp->value += hdr.tsize;
}
write(ofile, sp->name, 16);
}
}
/*
* Look up symbol name in symbuf in hash-indexed symbol table
* flag = 0: opcode expected
* 1: user symbol expected
* 2: user symbol expected; enter into index if not found
*
* returns 0: symbol was not previously defined
* 1: symbol was previously defined
* cursym: points to symbol table entry
*/
symlook(flag)
{
register struct symbol *sym, *sp, *lp, **hp;
lp = hp = &hashtab[hash(&symbuf)];
for (sp = *hp; sp; lp = sp, sp = sp->next) {
if (((int *)sp->name)[0] == ((int *)&symbuf)[0] &&
((int *)sp->name)[1] == ((int *)&symbuf)[1]) {
if (flag) {
if (sp < usymtab)
continue;
} else
if (sp >= usymtab)
continue;
/*
* Move symbol to the front of the chain so it will
* be found sooner next time.
*/
if (lp != hp) {
lp->next = sp->next;
sp->next = *hp;
*hp = sp;
}
cursym = sp;
return(1);
}
}
/*
* Enter new symbol into symbol table and index
*/
if (flag > 1) {
sym = nextsym;
if (++nextsym > symtop)
brk(symtop += SYMINC);
((int *)sym->name)[0] = ((int *)&symbuf)[0];
((int *)sym->name)[1] = ((int *)&symbuf)[1];
sym->next = *hp;
*hp = cursym = sym;
}
return(0);
}
/*
* Enter a symbol name into the symbol table
*/
enter(name)
register char *name;
{
register i;
for (i=0; i<8; i++)
if (symbuf[i] = *name)
name++;
symlook(2);
}