symbol.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * GTools C compiler
  3. * =================
  4. * source file :
  5. * symbol handling (insertion & search)
  6. *
  7. * Copyright 2001-2004 Paul Froissart.
  8. * Credits to Christoph van Wuellen and Matthew Brandt.
  9. * All commercial rights reserved.
  10. *
  11. * This compiler may be redistributed as long there is no
  12. * commercial interest. The compiler must not be redistributed
  13. * without its full sources. This notice must stay intact.
  14. */
  15. #include "define.h"
  16. _FILE(__FILE__)
  17. #include "c.h"
  18. #include "expr.h"
  19. #include "gen.h"
  20. #include "cglbdec.h"
  21. #ifdef PCH
  22. #include "pch.h"
  23. #endif
  24. #ifdef EXE_OUT
  25. #ifndef AS
  26. int exestub_mode CGLOB;
  27. #endif
  28. #endif
  29. HTABLE gsyms CGLOBL, gtags CGLOBL, lsyms CGLOBL, labsyms CGLOBL, ltags CGLOBL;
  30. void concat(TABLE *dest,TABLE *src) {
  31. SYM *sp=src->tail,*sp2;
  32. while (sp) {
  33. sp2=(SYM *)xalloc((int)sizeof(SYM), _SYM+SYMBOL);
  34. *sp2=*sp;
  35. insert(sp2,(HTABLE *)dest);
  36. sp=sp->prev;
  37. }
  38. }
  39. void hashinit(HTABLE *t) {
  40. t->hash=0x2489;
  41. memset(t->h,0,sizeof(t->h));
  42. }
  43. void insert(SYM *sp,HTABLE *table) {
  44. /* if (!strcmp(sp->name,"wrong_calc"))
  45. uwarn("def!");*/
  46. if (!table->hash) {
  47. if (!search(sp->name,0,table)) {
  48. TABLE *tab=(TABLE *)table;
  49. if (!tab->head) {
  50. tab->head = tab->tail = sp;
  51. sp->prev = 0;
  52. sp->used = 0;
  53. } else {
  54. tab->tail->next = sp;
  55. sp->prev = tab->tail;
  56. tab->tail = sp;
  57. sp->used = 0;
  58. tab->tail = sp;
  59. }
  60. sp->next = 0;
  61. }
  62. else uerr(ERR_DUPSYM,sp->name);
  63. } else {
  64. int crc=crcN(sp->name);
  65. #ifdef EXE_OUT
  66. if (table==&defsyms && sp->name[0]=='E' && !strcmp(sp->name,"EXE_OUT"))
  67. exestub_mode=1;
  68. #endif
  69. if (!search(sp->name,crc,table)) {
  70. struct htab *tab=&table->h[crc];
  71. if (!tab->head) {
  72. tab->head = tab->tail = sp;
  73. sp->prev = 0;
  74. sp->used = 0;
  75. } else {
  76. tab->tail->next = sp;
  77. sp->prev = tab->tail;
  78. tab->tail = sp;
  79. sp->used = 0;
  80. tab->tail = sp;
  81. }
  82. sp->next = 0;
  83. }
  84. else uerr(ERR_DUPSYM,sp->name);
  85. }
  86. }
  87. struct sym *symremove(char *na, HTABLE *tab) {
  88. SYM *ttail,**prv;
  89. struct htab *root;
  90. char *s1,*s2,c;
  91. if (!tab->hash)
  92. ierr(TABLE_HASH,2);
  93. #ifdef PC
  94. if (tab->hash!=0x2489)
  95. ierr(TABLE_HASH,1);
  96. #endif
  97. prv=&((root=&tab->h[crcN(na)])->tail);
  98. while ((ttail=*prv)) {
  99. s1 = ttail->name;
  100. s2 = na;
  101. while (*s1++==(c=*s2++)) {
  102. if (!c) {
  103. // *prv = ttail->prev;
  104. if (ttail->next) ttail->next->prev = ttail->prev;
  105. if (ttail->prev) ttail->prev->next = ttail->next;
  106. // ttail->next = prv;
  107. if (root->tail==ttail) root->tail=ttail->prev;
  108. if (root->head==ttail) root->head=ttail->next;
  109. /* if (!root->tail)
  110. root->head=0;*/
  111. return ttail;
  112. }
  113. }
  114. prv = &(ttail->prev);
  115. }
  116. return 0;
  117. }
  118. #ifdef PC
  119. int crcN(char *na) {
  120. unsigned long crc=-1; int n;
  121. unsigned char c;
  122. c=*na++;
  123. do {
  124. crc^=c;
  125. n=crc&7;
  126. crc=(crc>>n)+(crc<<(32-n));
  127. } while ((c=*na++));
  128. crc^=crc>>16;
  129. crc^=crc>>8;
  130. return crc & (N_HASH-1);
  131. }
  132. #else
  133. int crcN(char *na);
  134. asm("crcN:\n"
  135. " move.l 4(%sp),%a0\n"
  136. " moveq #-1,%d0\n"
  137. " move.b (%a0)+,%d1\n"
  138. "crcN_loop:\n"
  139. " eor.b %d1,%d0\n"
  140. " moveq #7,%d1\n"
  141. " and.w %d0,%d1\n"
  142. " ror.l %d1,%d0\n"
  143. " move.b (%a0)+,%d1\n"
  144. " bne crcN_loop\n"
  145. " move.w %d0,%d1\n"
  146. " swap %d0\n"
  147. " eor.w %d1,%d0\n"
  148. " move.w %d0,-(%sp)\n"
  149. " move.b (%sp)+,%d1\n"
  150. " eor.b %d1,%d0\n"
  151. " and.w #" N_HASH_AND ",%d0\n"
  152. " rts");
  153. #endif
  154. /*#ifdef PC*/
  155. struct sym *search(char *na, int crc, HTABLE *tab) {
  156. char *s1,*s2,c;
  157. if (!tab->hash) {
  158. SYM *ttail=((TABLE *)tab)->tail;
  159. while (ttail) {
  160. s1 = ttail->name;
  161. s2 = na;
  162. while (*s1++==(c=*s2++)) {
  163. if (!c) return ttail;
  164. }
  165. ttail = ttail->prev;
  166. }
  167. return 0;
  168. } else {
  169. SYM *ttail;
  170. #ifdef PC
  171. if (tab->hash!=0x2489)
  172. ierr(TABLE_HASH,1);
  173. #endif
  174. if (crc<0) crc=crcN(na);
  175. ttail=tab->h[crc].tail;
  176. while (ttail) {
  177. s1 = ttail->name;
  178. s2 = na;
  179. while (*s1++==(c=*s2++)) {
  180. if (!c) return ttail;
  181. }
  182. ttail = ttail->prev;
  183. }
  184. return 0;
  185. }
  186. }
  187. /*#else
  188. asm("search:
  189. move.l %a2,-(%sp)
  190. move.l 8(%sp),%d1
  191. move.l %d1,%a1
  192. tst.b (%a1)
  193. 0: beq 0b
  194. move.l 12(%sp),%a0
  195. move.l %a0,%d0
  196. beq search_end
  197. search_lp:
  198. move.l (%a0)+,%a2
  199. move.l %d1,%a1
  200. cmpm.b (%a1)+,(%a2)+
  201. bne search_nxt
  202. search_lp2:
  203. move.b (%a1)+,%d0
  204. beq search_fnd
  205. cmp.b (%a2)+,%d0
  206. beq search_lp2
  207. search_nxt:
  208. move.l (%a0)+,%a0
  209. move.l %a0,%d0
  210. bne search_lp
  211. search_end:
  212. move.l (%sp)+,%a2
  213. rts
  214. search_fnd:
  215. tst.b (%a2)+
  216. bne search_nxt
  217. subq.l #4,%a0
  218. move.l (%sp)+,%a2
  219. rts");
  220. #endif*/
  221. struct sym *gsearch(char *na,int crc) {
  222. struct sym *sp;
  223. if (!(sp = search(na, crc, &lsyms)))
  224. sp = search(na, crc, &gsyms);
  225. return sp;
  226. }
  227. void append(struct sym **ptr_sp, HTABLE *table) {
  228. struct sym *sp1, *sp = *ptr_sp;
  229. if (table == &gsyms && (sp1 = search(sp->name, -1, table)) != 0) {
  230. /*
  231. * The global symbol table has only one level, this means that we
  232. * only check if the new declaration is compatible with the old one
  233. */
  234. if (!eq_type(sp->tp, sp1->tp))
  235. uerr(ERR_REDECL,sp->name);
  236. /*
  237. * The new storage class depends on the old and on the new one.
  238. */
  239. if (sp->storage_class == sp1->storage_class) {
  240. if (sp->storage_class == sc_global) {
  241. /*
  242. * This hack sets sp->used to -1 so that decl.c knows to
  243. * suppress storage allocation
  244. */
  245. uwarn("global redeclaration of '%s'", sp->name);
  246. sp1->used = -1;
  247. }
  248. *ptr_sp = sp1; /* caller uses old entry */
  249. return;
  250. }
  251. /*
  252. * since we use compiler generated label for static data, we must
  253. * retain sc_static
  254. */
  255. if (sp1->storage_class == sc_static) {
  256. *ptr_sp = sp1; /* caller uses old entry */
  257. return;
  258. }
  259. /*
  260. * if the new storage class is global, we must update sp1 to generate
  261. * the .globl directive at the very end and perhaps the size (e.g.
  262. * for arrays)
  263. */
  264. if (sp->storage_class == sc_global) {
  265. sp1->storage_class = sc_global;
  266. sp1->tp = sp->tp;
  267. *ptr_sp = sp1; /* caller uses old entry */
  268. return;
  269. }
  270. /*
  271. * if the new storage class is static, set it to global (since we may
  272. * have used the ,real' name and cannot use compiler generated names
  273. * for this symbol from now on) and set sp->value.i to -1 to prevent
  274. * it from being exported via .globl directives
  275. */
  276. if (sp->storage_class == sc_static) {
  277. sp1->storage_class = sc_global;
  278. sp1->value.i = -1;
  279. *ptr_sp = sp1; /* caller uses old entry */
  280. return;
  281. }
  282. /*
  283. * last case: global declaration followed by external decl.: just do
  284. * nothing
  285. */
  286. *ptr_sp = sp1; /* caller uses old entry */
  287. return;
  288. }
  289. /* if (table->head == 0) {
  290. // The table is empty so far...
  291. table->head = table->tail = sp;
  292. sp->next = sp->prev = 0;
  293. sp->used = 0;
  294. } else {
  295. table->tail->next = sp;
  296. sp->prev = table->tail;
  297. table->tail = sp;
  298. sp->next = 0;
  299. sp->used = 0;
  300. }*/
  301. if (!table->hash) {
  302. TABLE *tab=(TABLE *)table;
  303. if (!tab->head) {
  304. tab->head = tab->tail = sp;
  305. sp->prev = 0;
  306. sp->used = 0;
  307. } else {
  308. tab->tail->next = sp;
  309. sp->prev = tab->tail;
  310. tab->tail = sp;
  311. sp->used = 0;
  312. tab->tail = sp;
  313. }
  314. sp->next = 0;
  315. } else {
  316. struct htab *tab=&table->h[crcN(sp->name)];
  317. if (!tab->head) {
  318. tab->head = tab->tail = sp;
  319. sp->prev = 0;
  320. sp->used = 0;
  321. } else {
  322. tab->tail->next = sp;
  323. sp->prev = tab->tail;
  324. tab->tail = sp;
  325. sp->used = 0;
  326. tab->tail = sp;
  327. }
  328. sp->next = 0;
  329. }
  330. }
  331. // vim:ts=4:sw=4