2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
11 static char rcs_id[] = "$Id: ass70.c,v 2.6 1994/06/24 10:15:20 ceriel Exp $" ;
15 ** utilities of EM1-assembler/loader
21 * glohash returns an index in table and leaves a stepsize in globstep
25 static int glohash(aname,size) char *aname; {
31 * Computes a hash-value from a string.
32 * Algorithm is adding all the characters after shifting some way.
35 for(sum=i=0,p=aname;*p;i += 3)
36 sum += (*p++)<<(i&07);
38 globstep = (sum / size) % (size - 7) + 7;
43 * lookup idname in labeltable , if it is not there enter it
44 * return index in labeltable
47 glob_t *glo2lookup(name,status) char *name; {
49 return(glolookup(name,status,mglobs,oursize->n_mlab));
52 glob_t *xglolookup(name,status) char *name; {
54 return(glolookup(name,status,xglobs,oursize->n_glab));
57 static void findext(g) glob_t *g ; {
60 x = xglolookup(g->g_name,ENTERING);
61 if (x && (x->g_status&DEF)) {
63 g->g_val.g_addr = x->g_val.g_addr;
68 glob_t *glolookup(name,status,table,size)
69 char *name; /* name */
70 int status; /* kind of lookup */
71 glob_t *table; /* which table to use */
72 int size; /* size for hash */
79 * lookup global symbol name in specified table.
80 * Various actions are taken depending on status.
83 * Lookup or enter the symbol, check for mult. def.
85 * Lookup the symbol, export if not known.
87 * Enter symbol local to the module.
89 * Enter symbol visable from every module.
91 * Lookup the symbol, return 0 if not found.
93 * Lookup or enter the symbol, don't check
96 rem = glohash(name,size);
99 while (g->g_name != 0 && strcmp(name,g->g_name) != 0) {
102 fatal("global label table overflow");
103 rem = (rem + globstep) % size;
106 if (g->g_name == 0) {
108 * This symbol is shining new.
109 * Enter it in table except for status = SEARCHING
111 if (status == SEARCHING)
113 g->g_name = (char *) getarea((unsigned) (strlen(name) + 1));
114 strcpy(g->g_name,name);
120 case SEARCHING: /* nothing special */
124 if (!new && (g->g_status&EXT))
125 werror("INA must be first occurrence of '%s'",name);
127 case EXTERNING: /* lookup in other table */
129 * The If statement is removed to be friendly
130 * to Backend writers having to deal with assemblers
131 * not following our conventions.
133 error("EXA must be first occurrence of '%s'",name);
137 case DEFINING: /* Thou shalt not redefine */
139 error("global symbol '%s' redefined",name);
148 fatal("bad status in glolookup");
153 locl_t *loclookup(an,status) {
154 register locl_t *lbp,*l_lbp;
155 register unsigned num;
158 if ( !pstate.s_locl ) fatal("label outside procedure");
160 if ( num/LOCLABSIZE>255 ) fatal("local label number too large");
161 hinum = num/LOCLABSIZE;
162 l_lbp= lbp= &(*pstate.s_locl)[num%LOCLABSIZE];
163 if ( lbp->l_defined==EMPTY ) {
166 while ( lbp!= lbp_cast 0 && lbp->l_hinum != hinum ) {
171 if ( lbp == lbp_cast 0 ) {
172 if ( l_lbp->l_defined!=EMPTY ) {
173 lbp = lbp_cast getarea(sizeof *lbp);
174 l_lbp->l_chain= lbp ;
176 lbp->l_chain= lbp_cast 0 ;
178 lbp->l_defined = (status==OCCURRING ? NO : YES);
179 lbp->l_min= line_num;
181 if (status == DEFINING) {
182 if (lbp->l_defined == YES)
183 error("multiple defined local symbol");
185 lbp->l_defined = YES;
187 if ( status==DEFINING ) lbp->l_min= line_num ;
191 proc_t *prolookup(name,status) char *name; {
196 * Look up a procedure name according to status
198 * PRO_OCC: Occurrence
199 * Search both tables, local table first.
200 * If not found, enter in global table
202 * Enter symbol in local table.
203 * PRO_DEF: Definition
204 * Define local procedure.
206 * Enter symbol in global table.
208 * The EXT bit in this table indicates the the name is used
209 * as external in this module.
214 p = searchproc(name,mprocs,oursize->n_mproc);
219 p = searchproc(name,xprocs,oursize->n_xproc);
228 p = searchproc(name,xprocs,oursize->n_xproc);
229 if (p->p_name && (p->p_status&EXT) )
230 error("pro '%s' conflicting use",name);
232 p = searchproc(name,mprocs,oursize->n_mproc);
234 werror("INP must be first occurrence of '%s'",name);
238 p = searchproc(name,mprocs,oursize->n_mproc);
240 error("pro '%s' exists already localy",name);
241 p = searchproc(name,xprocs,oursize->n_xproc);
244 * The If statement is removed to be friendly
245 * to Backend writers having to deal with assemblers
246 * not following our conventions.
247 if ( p->p_status&EXT )
248 werror("EXP must be first occurrence of '%s'",
258 p = searchproc(name,xprocs,oursize->n_xproc);
259 if (p->p_name && (p->p_status&EXT) ) {
261 error("global pro '%s' redeclared",name);
267 p = searchproc(name,mprocs,oursize->n_mproc);
270 error("local pro '%s' redeclared",
279 fatal("bad status in prolookup");
281 return(enterproc(name,pstat,p));
284 proc_t *searchproc(name,table,size)
293 * return a pointer into table to the place where the procedure
294 * name is or should be if in the table.
297 rem = glohash(name,size);
300 while (p->p_name != 0 && strcmp(name,p->p_name) != 0) {
303 fatal("procedure table overflow");
304 rem = (rem + globstep) % size;
310 proc_t *enterproc(name,status,place)
317 * Enter the procedure name into the table at place place.
318 * Place had better be computed by searchproc().
321 * At this point the procedure gets assigned a number.
322 * This number is used as a parameter of cal and in some
323 * other ways. There exists a 1-1 correspondence between
324 * procedures and numbers.
325 * Two local procedures with the same name in different
326 * modules have different numbers.
330 p->p_name = (char *) getarea((unsigned) (strlen(name) + 1));
331 strcpy(p->p_name,name);
332 p->p_status = status;
333 if (procnum>=oursize->n_proc)
334 fatal("too many procedures");
335 p->p_num = procnum++;