acid.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "cc.h"
  10. static char *kwd[] =
  11. {
  12. "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn",
  13. "$delete", "$do", "$else", "$eval", "$head", "$if",
  14. "$local", "$loop", "$return", "$tail", "$then",
  15. "$union", "$whatis", "$while",
  16. };
  17. char*
  18. amap(char *s)
  19. {
  20. int i, bot, top, new;
  21. bot = 0;
  22. top = bot + nelem(kwd) - 1;
  23. while(bot <= top){
  24. new = bot + (top - bot)/2;
  25. i = strcmp(kwd[new]+1, s);
  26. if(i == 0)
  27. return kwd[new];
  28. if(i < 0)
  29. bot = new + 1;
  30. else
  31. top = new - 1;
  32. }
  33. return s;
  34. }
  35. Sym*
  36. acidsue(Type *t)
  37. {
  38. int h;
  39. Sym *s;
  40. if(t != T)
  41. for(h=0; h<nelem(hash); h++)
  42. for(s = hash[h]; s != S; s = s->link)
  43. if(s->suetag && s->suetag->link == t)
  44. return s;
  45. return 0;
  46. }
  47. Sym*
  48. acidfun(Type *t)
  49. {
  50. int h;
  51. Sym *s;
  52. for(h=0; h<nelem(hash); h++)
  53. for(s = hash[h]; s != S; s = s->link)
  54. if(s->type == t)
  55. return s;
  56. return 0;
  57. }
  58. char acidchar[NTYPE];
  59. Init acidcinit[] =
  60. {
  61. {TCHAR, 'C', 0},
  62. {TUCHAR, 'b', 0},
  63. {TSHORT, 'd', 0},
  64. {TUSHORT, 'u', 0},
  65. {TLONG, 'D', 0},
  66. {TULONG, 'U', 0},
  67. {TVLONG, 'V', 0},
  68. {TUVLONG, 'W', 0},
  69. {TFLOAT, 'f', 0},
  70. {TDOUBLE, 'F', 0},
  71. {TARRAY, 'a', 0},
  72. {TIND, 'X', 0},
  73. {-1, 0, 0},
  74. };
  75. static void
  76. acidinit(void)
  77. {
  78. Init *p;
  79. for(p=acidcinit; p->code >= 0; p++)
  80. acidchar[p->code] = p->value;
  81. acidchar[TINT] = acidchar[TLONG];
  82. acidchar[TUINT] = acidchar[TULONG];
  83. if(types[TINT]->width != types[TLONG]->width) {
  84. acidchar[TINT] = acidchar[TSHORT];
  85. acidchar[TUINT] = acidchar[TUSHORT];
  86. if(types[TINT]->width != types[TSHORT]->width)
  87. warn(Z, "acidmember int not long or short");
  88. }
  89. if(types[TIND]->width == types[TUVLONG]->width)
  90. acidchar[TIND] = 'Y';
  91. }
  92. void
  93. acidmember(Type *t, long off, int flag)
  94. {
  95. Sym *s, *s1;
  96. Type *l;
  97. static int acidcharinit = 0;
  98. if(acidcharinit == 0) {
  99. acidinit();
  100. acidcharinit = 1;
  101. }
  102. s = t->sym;
  103. switch(t->etype) {
  104. default:
  105. Bprint(&outbuf, " T%d\n", t->etype);
  106. break;
  107. case TIND:
  108. if(s == S)
  109. break;
  110. if(flag) {
  111. for(l=t; l->etype==TIND; l=l->link)
  112. ;
  113. if(typesu[l->etype]) {
  114. s1 = acidsue(l->link);
  115. if(s1 != S) {
  116. Bprint(&outbuf, " 'A' %s %ld %s;\n",
  117. amap(s1->name),
  118. t->offset+off, amap(s->name));
  119. break;
  120. }
  121. }
  122. } else {
  123. Bprint(&outbuf,
  124. "\tprint(\"\t%s\t\", addr.%s\\X, \"\\n\");\n",
  125. amap(s->name), amap(s->name));
  126. break;
  127. }
  128. case TINT:
  129. case TUINT:
  130. case TCHAR:
  131. case TUCHAR:
  132. case TSHORT:
  133. case TUSHORT:
  134. case TLONG:
  135. case TULONG:
  136. case TVLONG:
  137. case TUVLONG:
  138. case TFLOAT:
  139. case TDOUBLE:
  140. case TARRAY:
  141. if(s == S)
  142. break;
  143. if(flag) {
  144. Bprint(&outbuf, " '%c' %ld %s;\n",
  145. acidchar[t->etype], t->offset+off, amap(s->name));
  146. } else {
  147. Bprint(&outbuf, "\tprint(\"\t%s\t\", addr.%s, \"\\n\");\n",
  148. amap(s->name), amap(s->name));
  149. }
  150. break;
  151. case TSTRUCT:
  152. case TUNION:
  153. s1 = acidsue(t->link);
  154. if(s1 == S)
  155. break;
  156. if(flag) {
  157. if(s == S) {
  158. Bprint(&outbuf, " {\n");
  159. for(l = t->link; l != T; l = l->down)
  160. acidmember(l, t->offset+off, flag);
  161. Bprint(&outbuf, " };\n");
  162. } else {
  163. Bprint(&outbuf, " %s %ld %s;\n",
  164. amap(s1->name),
  165. t->offset+off, amap(s->name));
  166. }
  167. } else {
  168. if(s != S) {
  169. Bprint(&outbuf, "\tprint(\"%s %s {\\n\");\n",
  170. amap(s1->name), amap(s->name));
  171. Bprint(&outbuf, "\t%s(addr.%s);\n",
  172. amap(s1->name), amap(s->name));
  173. Bprint(&outbuf, "\tprint(\"}\\n\");\n");
  174. } else {
  175. Bprint(&outbuf, "\tprint(\"%s {\\n\");\n",
  176. amap(s1->name));
  177. Bprint(&outbuf, "\t\t%s(addr+%ld);\n",
  178. amap(s1->name), t->offset+off);
  179. Bprint(&outbuf, "\tprint(\"}\\n\");\n");
  180. }
  181. }
  182. break;
  183. }
  184. }
  185. void
  186. acidtype(Type *t)
  187. {
  188. Sym *s;
  189. Type *l;
  190. Io *i;
  191. int n;
  192. char *an;
  193. if(!debug['a'])
  194. return;
  195. if(debug['a'] > 1) {
  196. n = 0;
  197. for(i=iostack; i; i=i->link)
  198. n++;
  199. if(n > 1)
  200. return;
  201. }
  202. s = acidsue(t->link);
  203. if(s == S)
  204. return;
  205. switch(t->etype) {
  206. default:
  207. Bprint(&outbuf, "T%d\n", t->etype);
  208. return;
  209. case TUNION:
  210. case TSTRUCT:
  211. if(debug['s'])
  212. goto asmstr;
  213. an = amap(s->name);
  214. Bprint(&outbuf, "sizeof%s = %ld;\n", an, t->width);
  215. Bprint(&outbuf, "aggr %s\n{\n", an);
  216. for(l = t->link; l != T; l = l->down)
  217. acidmember(l, 0, 1);
  218. Bprint(&outbuf, "};\n\n");
  219. Bprint(&outbuf, "defn\n%s(addr) {\n\tcomplex %s addr;\n", an, an);
  220. for(l = t->link; l != T; l = l->down)
  221. acidmember(l, 0, 0);
  222. Bprint(&outbuf, "};\n\n");
  223. break;
  224. asmstr:
  225. if(s == S)
  226. break;
  227. for(l = t->link; l != T; l = l->down)
  228. if(l->sym != S)
  229. Bprint(&outbuf, "#define\t%s.%s\t%ld\n",
  230. s->name,
  231. l->sym->name,
  232. l->offset);
  233. break;
  234. }
  235. }
  236. void
  237. acidvar(Sym *s)
  238. {
  239. int n;
  240. Io *i;
  241. Type *t;
  242. Sym *s1, *s2;
  243. if(!debug['a'] || debug['s'])
  244. return;
  245. if(debug['a'] > 1) {
  246. n = 0;
  247. for(i=iostack; i; i=i->link)
  248. n++;
  249. if(n > 1)
  250. return;
  251. }
  252. t = s->type;
  253. while(t && t->etype == TIND)
  254. t = t->link;
  255. if(t == T)
  256. return;
  257. if(t->etype == TENUM) {
  258. Bprint(&outbuf, "%s = ", amap(s->name));
  259. if(!typefd[t->etype])
  260. Bprint(&outbuf, "%lld;\n", s->vconst);
  261. else
  262. Bprint(&outbuf, "%f\n;", s->fconst);
  263. return;
  264. }
  265. if(!typesu[t->etype])
  266. return;
  267. s1 = acidsue(t->link);
  268. if(s1 == S)
  269. return;
  270. switch(s->class) {
  271. case CAUTO:
  272. case CPARAM:
  273. s2 = acidfun(thisfn);
  274. if(s2)
  275. Bprint(&outbuf, "complex %s %s:%s;\n",
  276. amap(s1->name), amap(s2->name), amap(s->name));
  277. break;
  278. case CSTATIC:
  279. case CEXTERN:
  280. case CGLOBL:
  281. case CLOCAL:
  282. Bprint(&outbuf, "complex %s %s;\n",
  283. amap(s1->name), amap(s->name));
  284. break;
  285. }
  286. }