* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / bcc / table.c
blob166c143a6647f751f87afafeed57ebe7993bc614
1 /* table.c - table handler for bcc */
3 /* Copyright (C) 1992 Bruce Evans */
5 /* Can I now get rid of EXPRLEVEL? Yes, except expression symbols must
6 * usually be set to some level different from OFFKLUDGELEVEL.
7 */
9 #include "bcc.h"
10 #include "align.h"
11 #include "gencode.h"
12 #include "os.h"
13 #include "parse.h"
14 #include "reg.h"
15 #include "sc.h"
16 #include "scan.h"
17 #include "sizes.h"
18 #include "type.h"
20 #undef EXTERN
21 #define EXTERN
22 #include "table.h"
24 #define GOLDEN 157 /* GOLDEN/HASHTABSIZE approx golden ratio */
25 #define HASHTABSIZE 256
26 #define MARKER ((unsigned) 0x18C396A5L) /* lint everywhere it is used */
27 #ifdef VERY_SMALL_MEMORY
28 #define MAXEXPR 125
29 #else
30 #define MAXEXPR 500
31 #endif
32 #define MAXLOCAL 100
33 #define NKEYWORDS 39
34 #ifdef NOFLOAT
35 #define NSCALTYPES 10
36 #else
37 #define NSCALTYPES 12
38 #endif
39 #define STACKSPACE 256 /* punt for normal recursions - switch extra */
41 struct keywordstruct
43 char *kwname;
44 sym_t kwcode;
47 #ifdef HOLDSTRINGS
48 struct string
50 struct string *snext;
51 char *sptr;
52 char *stop;
53 label_no slabel;
55 #endif
57 struct typedatastruct
59 char *tdname;
60 bool_t tdkeyscalar;
61 scalar_t tdscalar;
62 smalin_t tdsize;
63 struct typestruct **tdtypeptr;
66 PRIVATE struct symstruct exprsyms[MAXEXPR];
67 PRIVATE struct symstruct *hashtab[HASHTABSIZE];
68 /* depends on zero init */
69 #ifdef HOLDSTRINGS
70 PRIVATE struct string *laststring; /* last in list of strings */
71 /* depends on NULL init */
72 #endif
73 PUBLIC struct symstruct locsyms[MAXLOCAL];
75 PRIVATE struct symstruct constemplate =
77 CONSTANT, /* storage */
78 0, /* indcount */
79 0, /* flags */
80 EXPRLEVEL, /* level */
81 NULL, /* next */
82 NULL, /* prev */
83 NULL, /* type, init later to itype */
84 /* offset is a union, set every time constemplate is used */
85 /* name is a union, namea member is constant "\0" */
88 PRIVATE struct keywordstruct keywords[NKEYWORDS] =
90 { "enum", ENUMDECL, },
91 { "struct", STRUCTDECL, },
92 { "union", UNIONDECL, },
93 { "unsigned", UNSIGNDECL, },
94 { "signed", SIGNDECL, },
96 { "auto", AUTODECL, },
97 { "extern", EXTERNDECL, },
98 { "register", REGDECL, },
99 { "static", STATICDECL, },
101 { "typedef", TYPEDEFDECL, },
103 { "asm", ASMSYM, },
104 { "break", BREAKSYM, },
105 { "case", CASESYM, },
106 { "continue", CONTSYM, },
107 { "default", DEFAULTSYM, },
108 { "do", DOSYM, },
109 { "else", ELSESYM, },
110 { "for", FORSYM, },
111 { "goto", GOTOSYM, },
112 { "if", IFSYM, },
113 { "return", RETURNSYM, },
114 { "sizeof", SIZEOFSYM, },
115 { "switch", SWITCHSYM, },
116 { "while", WHILESYM, },
118 { "#asm", ASMCNTL, },
119 { "#define", DEFINECNTL, },
120 { "#elif", ELIFCNTL, },
121 { "#else", ELSECNTL, },
122 { "#endasm", ENDASMCNTL, },
123 { "#endif", ENDIFCNTL, },
124 { "#if", IFCNTL, },
125 { "#ifdef", IFDEFCNTL, },
126 { "#include", INCLUDECNTL, },
127 { "#ifndef", IFNDEFCNTL, },
128 { "#line", LINECNTL, },
129 { "#undef", UNDEFCNTL, },
130 { "#warning", WARNINGCNTL, },
131 { "#error", ERRORCNTL, },
133 { "defined", DEFINEDSYM, }, /* should be deactivated except in #if's */
136 PRIVATE struct typedatastruct scaltypes[NSCALTYPES] =
138 { "void", TRUE, 0, 0, &vtype, }, /* first - addkeyword uses vtype */
139 { "char", TRUE, CHAR, 1, &ctype, },
140 { "char", FALSE, UNSIGNED | CHAR, 1, &uctype, },
141 { "char", FALSE, CHAR, 1, &sctype, },
142 { "short", TRUE, SHORT, 2, &stype, },
143 { "short", FALSE, UNSIGNED | SHORT, 2, &ustype, },
144 { "int", TRUE, INT, 2, &itype, },
145 { "int", FALSE, UNSIGNED | INT, 2, &uitype, },
146 { "long", TRUE, LONG | DLONG, 4, &ltype, },
147 { "long", FALSE, UNSIGNED | LONG | DLONG, 4, &ultype, },
148 #ifndef NOFLOAT
149 { "float", TRUE, FLOAT, 4, &fltype, },
150 { "double", TRUE, DOUBLE, 8, &dtype, },
151 #endif
154 FORWARD struct symstruct *addkeyword P((char *name, sym_pt code));
155 FORWARD void heapcorrupterror P((void));
157 PUBLIC struct symstruct *addglb(name, type)
158 char *name;
159 struct typestruct *type;
161 struct symstruct **hashptr;
162 struct symstruct *oldsymptr = NULL; /* for -Wall */
163 register struct symstruct *symptr;
165 hashptr = gethashptr(name);
166 symptr = *hashptr;
167 while (symptr != NULL)
169 oldsymptr = symptr;
170 symptr = symptr->next;
172 symptr = qmalloc(sizeof (struct symstruct) + strlen(name));
173 #ifdef TS
174 ++ts_n_global;
175 ts_size_global += sizeof (struct symstruct) + strlen(name);
176 #endif
177 addsym(name, type, symptr);
178 symptr->storage = GLOBAL;
179 symptr->level = GLBLEVEL;
180 if (*hashptr == NULL)
182 *hashptr = symptr;
183 symptr->prev = hashptr;
185 else
187 oldsymptr->next = symptr;
188 symptr->prev = &oldsymptr->next;
190 return symptr;
193 PRIVATE struct symstruct *addkeyword(name, code)
194 char *name;
195 sym_pt code;
197 struct symstruct *symptr;
199 (symptr = addglb(name, vtype))->flags = KEYWORD;
200 symptr->offset.offsym = code;
201 return symptr;
204 PUBLIC struct symstruct *addloc(name, type)
205 char *name;
206 struct typestruct *type;
208 struct symstruct **hashptr;
209 register struct symstruct *symptr;
211 hashptr = gethashptr(name);
212 symptr = *hashptr;
213 while (symptr != NULL)
214 symptr = symptr->next;
215 symptr = locptr;
216 locptr = (struct symstruct *) align(&symptr->name.namea[strlen(name) + 1]);
217 if (locptr >= &locsyms[MAXLOCAL])
218 limiterror("too many local symbols (101)");
219 addsym(name, type, symptr);
220 if (type->constructor == FUNCTION)
221 symptr->storage = GLOBAL;
222 else
223 symptr->storage = LOCAL;
224 symptr->level = level;
225 if (*hashptr != NULL)
227 symptr->next = *hashptr;
228 symptr->next->prev = &symptr->next;
230 *hashptr = symptr;
231 symptr->prev = hashptr;
232 return symptr;
235 PUBLIC struct symstruct *addlorg(name, type)
236 char *name;
237 struct typestruct *type;
239 if (level != GLBLEVEL)
240 return addloc(name, type);
241 return addglb(name, type);
244 PUBLIC void addsym(name, type, symptr)
245 char *name;
246 struct typestruct *type;
247 register struct symstruct *symptr;
249 if (type->constructor & (ARRAY | FUNCTION))
250 symptr->indcount = 0;
251 else
252 symptr->indcount = 1;
253 symptr->flags = 0;
254 symptr->next = NULL;
255 symptr->type = type;
256 symptr->offset.offi = 0;
257 strcpy(symptr->name.namea, name);
260 PUBLIC struct symstruct *constsym(longconst)
261 value_t longconst;
263 register struct symstruct *symptr;
265 symptr = exprsym(&constemplate);
266 symptr->offset.offv = longconst;
267 return symptr;
270 PUBLIC void delsym(symptr)
271 register struct symstruct *symptr;
273 if ((*(symptr->prev) = symptr->next) != NULL)
274 symptr->next->prev = symptr->prev;
277 /* dumpglbs() - define locations of globals and reserve space for them */
279 PUBLIC void dumpglbs()
281 int i;
282 register struct symstruct *symptr;
283 register struct typestruct *type;
285 #ifdef TS
286 extern char *brksize;
287 struct ts
289 char *what;
290 uvalue_t *where;
292 static struct ts ts[] =
294 "ts_n_newtypelist ", &ts_n_newtypelist,
295 "ts_s_newtypelist ", &ts_s_newtypelist,
296 "ts_n_filename_term ", &ts_n_filename_term,
297 "ts_s_filename_term ", &ts_s_filename_term,
298 "ts_n_filename ", &ts_n_filename,
299 "ts_s_filename ", &ts_s_filename,
300 "ts_s_filename_tot ", &ts_s_filename_tot,
301 "ts_n_pathname ", &ts_n_pathname,
302 "ts_s_pathname ", &ts_s_pathname,
303 "ts_s_pathname_tot ", &ts_s_pathname_tot,
304 "ts_n_inputbuf ", &ts_n_inputbuf,
305 "ts_s_inputbuf ", &ts_s_inputbuf,
306 "ts_s_inputbuf_tot ", &ts_s_inputbuf_tot,
307 "ts_n_includelist ", &ts_n_includelist,
308 "ts_s_includelist ", &ts_s_includelist,
309 "ts_s_outputbuf ", &ts_s_outputbuf,
310 "ts_n_macstring_ident ", &ts_n_macstring_ident,
311 "ts_n_macstring_ordinary ", &ts_n_macstring_ordinary,
312 "ts_n_macstring_param ", &ts_n_macstring_param,
313 "ts_n_macstring_quoted ", &ts_n_macstring_quoted,
314 "ts_n_macstring_term ", &ts_n_macstring_term,
315 "ts_s_macstring ", &ts_s_macstring,
316 "ts_n_defines ", &ts_n_defines,
317 "ts_s_defines ", &ts_s_defines,
318 "ts_n_macparam ", &ts_n_macparam,
319 "ts_s_macparam ", &ts_s_macparam,
320 "ts_s_macparam_tot ", &ts_s_macparam_tot,
321 "ts_n_macparam_string_ordinary ", &ts_n_macparam_string_ordinary,
322 "ts_n_macparam_string_quoted ", &ts_n_macparam_string_quoted,
323 "ts_n_macparam_string_term ", &ts_n_macparam_string_term,
324 "ts_s_macparam_string ", &ts_s_macparam_string,
325 "ts_s_macparam_string_tot ", &ts_s_macparam_string_tot,
326 "ts_s_macparam_string_alloced ", &ts_s_macparam_string_alloced,
327 "ts_s_macparam_string_alloced_tot ", &ts_s_macparam_string_alloced_tot,
328 "ts_s_fakeline ", &ts_s_fakeline,
329 "ts_s_fakeline_tot ", &ts_s_fakeline_tot,
330 "ts_n_string ", &ts_n_string,
331 "ts_n_case ", &ts_n_case,
332 "ts_n_case_realloc ", &ts_n_case_realloc,
333 "ts_s_case ", &ts_s_case,
334 "ts_s_case_tot ", &ts_s_case_tot,
335 "ts_n_structname ", &ts_n_structname,
336 "ts_s_structname ", &ts_s_structname,
337 "ts_n_type ", &ts_n_type,
338 "ts_s_type ", &ts_s_type,
339 "ts_n_global ", &ts_n_global,
340 "ts_size_global ", &ts_size_global,
341 "ts_n_holdstr ", &ts_n_holdstr,
342 "ts_size_holdstr ", &ts_size_holdstr,
343 "ts_n_growobj ", &ts_n_growobj,
344 "ts_size_growobj_wasted ", &ts_size_growobj_wasted,
345 "ts_n_growheap ", &ts_n_growheap,
346 "ts_s_growheap ", &ts_s_growheap,
348 struct ts *tp;
350 for (tp = &ts[0]; tp < &ts[sizeof ts / sizeof ts[0]]; ++tp)
352 comment();
353 outstr(tp->what);
354 outstr("");
355 outuvalue(*tp->where);
356 outnl();
358 comment();
359 outstr("brksize ");
360 outhex((uvalue_t) brksize);
361 outnl();
362 #endif
364 #ifndef DIRECTPAGE
365 bssseg();
366 #endif
367 for (i = 0; i < HASHTABSIZE; ++i)
368 for (symptr = hashtab[i]; symptr != NULL; symptr = symptr->next)
369 if (symptr->storage == GLOBAL && !(symptr->flags & EXTERNAL)
370 && *symptr->name.namea >= 'A' && symptr->flags <= MAXDUMPFLAG
371 /* Don't access type unless flags <= MAXDUMPFLAG, because
372 * type is punned to a symbol pointer for the label chain
373 * and might be null.
375 && symptr->type->constructor != FUNCTION)
377 #ifdef DIRECTPAGE
378 if (symptr->flags & DIRECTPAGE)
379 dpseg();
380 else
381 dseg();
382 #endif
383 type = symptr->type;
384 if (symptr->flags & STATIC)
385 lcommon(symptr->name.namea);
386 else
387 common(symptr->name.namea);
388 outnhex(type->typesize);
390 if (printf_fp)
391 globl("__xfpcvt");
392 if (scanf_fp)
393 globl("__xfptvc");
396 /* dumplocs() - define offsets of current locals */
398 PUBLIC void dumplocs()
400 register struct symstruct *symptr;
401 int i;
403 #ifdef ASM_USES_CALLEE_REGS
404 if (framep && optimise && !callersaves) {
405 regfuse |= callee1mask;
406 outnstr("! Assuming #asm uses all callee saves registers");
408 #endif
410 for (i = 0; i < HASHTABSIZE; ++i)
411 for (symptr = hashtab[i]; symptr != NULL; symptr = symptr->next)
412 if (symptr->storage == LOCAL)
413 set(symptr->name.namea, symptr->offset.offi - sp);
416 #ifdef HOLDSTRINGS
418 /* dumpstrings() - dump held-up strings */
420 PUBLIC void dumpstrings()
422 struct string *stringp;
424 dseg();
425 for (stringp = laststring; stringp != NULL; stringp = stringp->snext)
427 outnlabel(stringp->slabel);
428 defstr(stringp->sptr, stringp->stop, TRUE);
429 dataoffset += stringp->stop - stringp->sptr + 1;
433 #endif
435 PUBLIC struct symstruct *exprsym(symptr)
436 struct symstruct *symptr;
438 register struct symstruct *newsymptr;
440 newsymptr = exprptr++;
441 if (exprptr >= &exprsyms[MAXEXPR])
442 #if MAXEXPR == 500
443 limiterror("expression too complex (501 symbols)");
444 #else
445 limiterror("expression too complex (MAXEXPR)");
446 #endif
447 *newsymptr = *symptr;
448 newsymptr->level = EXPRLEVEL;
449 newsymptr->name.namep = symptr->name.namea;
450 return newsymptr;
453 PUBLIC struct symstruct *findlorg(name)
454 char *name;
456 struct symstruct *symptr;
458 symptr = *gethashptr(name);
459 while (symptr != NULL && (strcmp(symptr->name.namea, name) != 0 ||
460 symptr->flags == STRUCTNAME))
461 symptr = symptr->next;
462 return symptr;
465 PUBLIC struct symstruct *findstruct(name)
466 char *name;
468 struct symstruct *symptr;
470 symptr = *gethashptr(name);
471 while (symptr != NULL && (symptr->flags != STRUCTNAME ||
472 strcmp(symptr->name.namea, name) != 0))
473 symptr = symptr->next;
474 return symptr;
477 /* convert name to a hash table ptr */
479 PUBLIC struct symstruct **gethashptr(sname)
480 char *sname;
482 register int hashval;
483 register char *rsname;
485 hashval = 0;
486 rsname = sname;
487 #if 1
488 while (*rsname)
489 hashval = hashval * 2 + *rsname++;
490 #else
491 hashval = rsname[0];
492 if (rsname[1] != 0)
493 hashval = (rsname[2] << 2) ^ rsname[1] ^ (rsname[0] << 1);
494 else
495 hashval = rsname[0];
496 #endif
497 return hashtab + ((hashval * GOLDEN) & (HASHTABSIZE - 1));
500 PRIVATE void heapcorrupterror()
502 outofmemoryerror(" (heap corrupt - stack overflow?)");
505 #ifdef HOLDSTRINGS
507 /* hold string for dumping at end, to avoid mixing it with other data */
509 PUBLIC label_no holdstr(sptr, stop)
510 char *sptr;
511 char *stop;
513 register struct string *stringp;
515 stringp = qmalloc(sizeof *stringp);
516 #ifdef TS
517 ++ts_n_holdstr;
518 ts_size_holdstr += sizeof *stringp;
519 #endif
520 stringp->snext = laststring;
521 stringp->sptr = sptr;
522 stringp->stop = stop;
523 laststring = stringp;
524 return stringp->slabel = getlabel();
527 #endif /* HOLDSTRINGS */
529 PUBLIC void newlevel()
531 if (*(unsigned *) chartop != MARKER)
532 heapcorrupterror();
533 if (level >= MAXLEVEL)
534 limiterror("compound statements nested too deeply (126 levels)");
535 else
536 ++level;
539 PUBLIC void oldlevel()
541 register struct symstruct *symptr;
543 if (*(unsigned *) chartop != MARKER)
544 heapcorrupterror();
545 if (level == 0)
546 bugerror("not in a compound statement");
547 else
548 --level;
549 for (symptr = &locsyms[0]; symptr < locptr;
550 symptr = (struct symstruct *)
551 align(&symptr->name.namea[strlen(symptr->name.namea) + 1]))
552 if (symptr->level > level)
553 delsym(symptr);
556 PUBLIC void ourfree(ptr)
557 void *ptr;
559 free(ptr);
562 PUBLIC void *ourmalloc(nbytes)
563 unsigned nbytes;
565 void *ptr;
567 if ((ptr = malloc(nbytes)) == NULL)
568 outofmemoryerror("");
569 return ptr;
572 PUBLIC void outofmemoryerror(message)
573 char *message;
575 error2error("compiler out of memory", message);
577 #ifdef __AS386_16__
579 unsigned size;
580 char *ptr;
582 for (size = 0x1000; size != 0; --size)
583 if ((ptr = malloc(size)) != NULL)
585 outstr("found free memory at ");
586 outuvalue((uvalue_t) ptr);
587 outstr(" size ");
588 outuvalue((uvalue_t) size);
589 outnl();
592 #endif
594 finishup();
597 PUBLIC void *growobject(object, extra)
598 void *object;
599 unsigned extra;
601 /* size_t */ unsigned oblength;
603 /* It would be nice to realloc the previous memory if it can be left in
604 * the same place. Since a realloc that moves the memory can almost be
605 * relied on to mess up pointers before *obptr, and since malloc(extra)
606 * would be unlikely to produce memory adjoining chartop, it is not
607 * clear how to do this.
609 #ifdef TS
610 ts_size_growobj_wasted += chartop - (char *) object;
611 #endif
612 oblength = (/* size_t */ unsigned) (charptr - (char *) object);
613 growheap(oblength + extra);
614 #ifdef TS
615 ++ts_n_growobj;
616 #endif
617 memcpy(charptr, object, oblength);
618 object = charptr;
619 charptr += oblength;
620 return object;
623 #define ALLOC_UNIT ((unsigned) 0x400)
624 #ifdef S_ALIGNMENT
625 #define ALLOC_OVERHEAD (S_ALIGNMENT - 1 + sizeof (unsigned))
626 #else
627 #define ALLOC_OVERHEAD (sizeof (unsigned))
628 #endif
630 PUBLIC void growheap(size)
631 unsigned size;
633 register char *newptr;
635 if ((newptr = malloc(size += ALLOC_UNIT + ALLOC_OVERHEAD)) == NULL
636 && (newptr = malloc(size -= ALLOC_UNIT)) == NULL)
637 outofmemoryerror("");
638 #ifdef TS
639 ++ts_n_growheap;
640 ts_s_growheap += size;
641 #endif
642 charptr = newptr;
643 newptr = (char *) align(newptr + size - ALLOC_OVERHEAD);
644 chartop = newptr;
645 char1top = newptr - 1;
646 char3top = newptr - 3;
647 *(unsigned *) newptr = MARKER;
650 PUBLIC void *qmalloc(size)
651 unsigned size;
653 register char *ptr;
655 if ((charptr = (char *) align(charptr)) + size > chartop)
656 growheap(size);
657 ptr = charptr;
658 charptr += size;
659 return ptr;
662 PUBLIC void swapsym(sym1, sym2)
663 struct symstruct *sym1;
664 struct symstruct *sym2;
666 struct symstruct swaptemp;
668 swaptemp = *sym1;
669 *sym1 = *sym2;
670 *sym2 = swaptemp;
673 PUBLIC void syminit()
675 struct keywordstruct *kwptr;
676 struct typedatastruct *tdptr;
677 struct typestruct *type;
679 exprptr = exprsyms;
680 locptr = locsyms;
681 for (tdptr = scaltypes; tdptr < scaltypes + NSCALTYPES; ++tdptr)
683 (*tdptr->tdtypeptr = type = newtype())->scalar = tdptr->tdscalar;
684 type->alignmask = ~((type->typesize = tdptr->tdsize) - 1) |
685 alignmask;
686 type->tname = tdptr->tdname;
687 if (tdptr->tdkeyscalar)
688 addkeyword(tdptr->tdname, TYPEDECL)->type = type;
690 for (kwptr = keywords; kwptr < keywords + NKEYWORDS; ++kwptr)
691 addkeyword(kwptr->kwname, kwptr->kwcode);
692 constemplate.type = itype;