123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- /*
- * GTools C compiler
- * =================
- * source file :
- * symbol handling (insertion & search)
- *
- * Copyright 2001-2004 Paul Froissart.
- * Credits to Christoph van Wuellen and Matthew Brandt.
- * All commercial rights reserved.
- *
- * This compiler may be redistributed as long there is no
- * commercial interest. The compiler must not be redistributed
- * without its full sources. This notice must stay intact.
- */
- #include "define.h"
- _FILE(__FILE__)
- #include "c.h"
- #include "expr.h"
- #include "gen.h"
- #include "cglbdec.h"
- #ifdef PCH
- #include "pch.h"
- #endif
- #ifdef EXE_OUT
- #ifndef AS
- int exestub_mode CGLOB;
- #endif
- #endif
- HTABLE gsyms CGLOBL, gtags CGLOBL, lsyms CGLOBL, labsyms CGLOBL, ltags CGLOBL;
- void concat(TABLE *dest,TABLE *src) {
- SYM *sp=src->tail,*sp2;
- while (sp) {
- sp2=(SYM *)xalloc((int)sizeof(SYM), _SYM+SYMBOL);
- *sp2=*sp;
- insert(sp2,(HTABLE *)dest);
- sp=sp->prev;
- }
- }
- void hashinit(HTABLE *t) {
- t->hash=0x2489;
- memset(t->h,0,sizeof(t->h));
- }
- void insert(SYM *sp,HTABLE *table) {
- /* if (!strcmp(sp->name,"wrong_calc"))
- uwarn("def!");*/
- if (!table->hash) {
- if (!search(sp->name,0,table)) {
- TABLE *tab=(TABLE *)table;
- if (!tab->head) {
- tab->head = tab->tail = sp;
- sp->prev = 0;
- sp->used = 0;
- } else {
- tab->tail->next = sp;
- sp->prev = tab->tail;
- tab->tail = sp;
- sp->used = 0;
- tab->tail = sp;
- }
- sp->next = 0;
- }
- else uerr(ERR_DUPSYM,sp->name);
- } else {
- int crc=crcN(sp->name);
- #ifdef EXE_OUT
- if (table==&defsyms && sp->name[0]=='E' && !strcmp(sp->name,"EXE_OUT"))
- exestub_mode=1;
- #endif
- if (!search(sp->name,crc,table)) {
- struct htab *tab=&table->h[crc];
- if (!tab->head) {
- tab->head = tab->tail = sp;
- sp->prev = 0;
- sp->used = 0;
- } else {
- tab->tail->next = sp;
- sp->prev = tab->tail;
- tab->tail = sp;
- sp->used = 0;
- tab->tail = sp;
- }
- sp->next = 0;
- }
- else uerr(ERR_DUPSYM,sp->name);
- }
- }
- struct sym *symremove(char *na, HTABLE *tab) {
- SYM *ttail,**prv;
- struct htab *root;
- char *s1,*s2,c;
- if (!tab->hash)
- ierr(TABLE_HASH,2);
- #ifdef PC
- if (tab->hash!=0x2489)
- ierr(TABLE_HASH,1);
- #endif
- prv=&((root=&tab->h[crcN(na)])->tail);
- while ((ttail=*prv)) {
- s1 = ttail->name;
- s2 = na;
- while (*s1++==(c=*s2++)) {
- if (!c) {
- // *prv = ttail->prev;
- if (ttail->next) ttail->next->prev = ttail->prev;
- if (ttail->prev) ttail->prev->next = ttail->next;
- // ttail->next = prv;
- if (root->tail==ttail) root->tail=ttail->prev;
- if (root->head==ttail) root->head=ttail->next;
- /* if (!root->tail)
- root->head=0;*/
- return ttail;
- }
- }
- prv = &(ttail->prev);
- }
- return 0;
- }
- #ifdef PC
- int crcN(char *na) {
- unsigned long crc=-1; int n;
- unsigned char c;
- c=*na++;
- do {
- crc^=c;
- n=crc&7;
- crc=(crc>>n)+(crc<<(32-n));
- } while ((c=*na++));
- crc^=crc>>16;
- crc^=crc>>8;
- return crc & (N_HASH-1);
- }
- #else
- int crcN(char *na);
- asm("crcN:\n"
- " move.l 4(%sp),%a0\n"
- " moveq #-1,%d0\n"
- " move.b (%a0)+,%d1\n"
- "crcN_loop:\n"
- " eor.b %d1,%d0\n"
- " moveq #7,%d1\n"
- " and.w %d0,%d1\n"
- " ror.l %d1,%d0\n"
- " move.b (%a0)+,%d1\n"
- " bne crcN_loop\n"
- " move.w %d0,%d1\n"
- " swap %d0\n"
- " eor.w %d1,%d0\n"
- " move.w %d0,-(%sp)\n"
- " move.b (%sp)+,%d1\n"
- " eor.b %d1,%d0\n"
- " and.w #" N_HASH_AND ",%d0\n"
- " rts");
- #endif
- /*#ifdef PC*/
- struct sym *search(char *na, int crc, HTABLE *tab) {
- char *s1,*s2,c;
- if (!tab->hash) {
- SYM *ttail=((TABLE *)tab)->tail;
- while (ttail) {
- s1 = ttail->name;
- s2 = na;
- while (*s1++==(c=*s2++)) {
- if (!c) return ttail;
- }
- ttail = ttail->prev;
- }
- return 0;
- } else {
- SYM *ttail;
- #ifdef PC
- if (tab->hash!=0x2489)
- ierr(TABLE_HASH,1);
- #endif
- if (crc<0) crc=crcN(na);
- ttail=tab->h[crc].tail;
- while (ttail) {
- s1 = ttail->name;
- s2 = na;
- while (*s1++==(c=*s2++)) {
- if (!c) return ttail;
- }
- ttail = ttail->prev;
- }
- return 0;
- }
- }
- /*#else
- asm("search:
- move.l %a2,-(%sp)
- move.l 8(%sp),%d1
- move.l %d1,%a1
- tst.b (%a1)
- 0: beq 0b
- move.l 12(%sp),%a0
- move.l %a0,%d0
- beq search_end
- search_lp:
- move.l (%a0)+,%a2
- move.l %d1,%a1
- cmpm.b (%a1)+,(%a2)+
- bne search_nxt
- search_lp2:
- move.b (%a1)+,%d0
- beq search_fnd
- cmp.b (%a2)+,%d0
- beq search_lp2
- search_nxt:
- move.l (%a0)+,%a0
- move.l %a0,%d0
- bne search_lp
- search_end:
- move.l (%sp)+,%a2
- rts
- search_fnd:
- tst.b (%a2)+
- bne search_nxt
- subq.l #4,%a0
- move.l (%sp)+,%a2
- rts");
- #endif*/
- struct sym *gsearch(char *na,int crc) {
- struct sym *sp;
- if (!(sp = search(na, crc, &lsyms)))
- sp = search(na, crc, &gsyms);
- return sp;
- }
- void append(struct sym **ptr_sp, HTABLE *table) {
- struct sym *sp1, *sp = *ptr_sp;
- if (table == &gsyms && (sp1 = search(sp->name, -1, table)) != 0) {
- /*
- * The global symbol table has only one level, this means that we
- * only check if the new declaration is compatible with the old one
- */
- if (!eq_type(sp->tp, sp1->tp))
- uerr(ERR_REDECL,sp->name);
- /*
- * The new storage class depends on the old and on the new one.
- */
- if (sp->storage_class == sp1->storage_class) {
- if (sp->storage_class == sc_global) {
- /*
- * This hack sets sp->used to -1 so that decl.c knows to
- * suppress storage allocation
- */
- uwarn("global redeclaration of '%s'", sp->name);
- sp1->used = -1;
- }
- *ptr_sp = sp1; /* caller uses old entry */
- return;
- }
- /*
- * since we use compiler generated label for static data, we must
- * retain sc_static
- */
- if (sp1->storage_class == sc_static) {
- *ptr_sp = sp1; /* caller uses old entry */
- return;
- }
- /*
- * if the new storage class is global, we must update sp1 to generate
- * the .globl directive at the very end and perhaps the size (e.g.
- * for arrays)
- */
- if (sp->storage_class == sc_global) {
- sp1->storage_class = sc_global;
- sp1->tp = sp->tp;
- *ptr_sp = sp1; /* caller uses old entry */
- return;
- }
- /*
- * if the new storage class is static, set it to global (since we may
- * have used the ,real' name and cannot use compiler generated names
- * for this symbol from now on) and set sp->value.i to -1 to prevent
- * it from being exported via .globl directives
- */
- if (sp->storage_class == sc_static) {
- sp1->storage_class = sc_global;
- sp1->value.i = -1;
- *ptr_sp = sp1; /* caller uses old entry */
- return;
- }
- /*
- * last case: global declaration followed by external decl.: just do
- * nothing
- */
- *ptr_sp = sp1; /* caller uses old entry */
- return;
- }
- /* if (table->head == 0) {
- // The table is empty so far...
- table->head = table->tail = sp;
- sp->next = sp->prev = 0;
- sp->used = 0;
- } else {
- table->tail->next = sp;
- sp->prev = table->tail;
- table->tail = sp;
- sp->next = 0;
- sp->used = 0;
- }*/
- if (!table->hash) {
- TABLE *tab=(TABLE *)table;
- if (!tab->head) {
- tab->head = tab->tail = sp;
- sp->prev = 0;
- sp->used = 0;
- } else {
- tab->tail->next = sp;
- sp->prev = tab->tail;
- tab->tail = sp;
- sp->used = 0;
- tab->tail = sp;
- }
- sp->next = 0;
- } else {
- struct htab *tab=&table->h[crcN(sp->name)];
- if (!tab->head) {
- tab->head = tab->tail = sp;
- sp->prev = 0;
- sp->used = 0;
- } else {
- tab->tail->next = sp;
- sp->prev = tab->tail;
- tab->tail = sp;
- sp->used = 0;
- tab->tail = sp;
- }
- sp->next = 0;
- }
- }
- // vim:ts=4:sw=4
|