ca.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /*
  7. * C O M P A C T A S S E M B L Y L A N G U A G E G E N E R A T I O N
  8. *
  9. */
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <em_pseu.h>
  14. #include <em_mes.h>
  15. #include "../share/types.h"
  16. #include "ca.h"
  17. #include "../share/debug.h"
  18. #include "../share/global.h"
  19. #include "../share/lset.h"
  20. #include "../share/files.h"
  21. #include "../share/map.h"
  22. #include "../share/alloc.h"
  23. #include "../share/get.h"
  24. #include "ca_put.h"
  25. /* This phase transforms the Intermediate Code of the global optimizer
  26. * to 'standard' compact assembly language, which will be processed
  27. * by the code generator.
  28. */
  29. short dlength;
  30. dblock_p* dmap;
  31. char** dnames, **pnames; /* Dynamically allocated arrays of strings.
  32. * pnames[i] contains a pointer to the name
  33. * of the procedure with proc_id i.
  34. */
  35. STATIC line_p get_ca_lines(lf, p_out)
  36. FILE* lf;
  37. proc_p* p_out;
  38. {
  39. /* Read lines of EM text and link them.
  40. * Register messages are outputted immediately after the PRO.
  41. */
  42. line_p head, *pp, l;
  43. line_p headm, *mp;
  44. arg_p a;
  45. curinp = lf; /* EM input file */
  46. pp = &head;
  47. mp = &headm;
  48. headm = (line_p)0;
  49. while (TRUE)
  50. {
  51. l = read_line(p_out);
  52. if (feof(curinp))
  53. break;
  54. assert(l != (line_p)0);
  55. if (INSTR(l) == ps_end && INSTR(head) != ps_pro)
  56. {
  57. /* Delete end pseudo after data-unit */
  58. oldline(l);
  59. break;
  60. }
  61. if (INSTR(l) == ps_mes && l->l_a.la_arg->a_a.a_offset == ms_reg)
  62. {
  63. /* l is a register message */
  64. if (l->l_a.la_arg->a_next == (arg_p)0)
  65. {
  66. /* register message without arguments */
  67. oldline(l);
  68. }
  69. else
  70. {
  71. *mp = l;
  72. mp = &l->l_next;
  73. }
  74. }
  75. else
  76. {
  77. *pp = l;
  78. pp = &l->l_next;
  79. }
  80. if (INSTR(l) == ps_end)
  81. {
  82. break;
  83. }
  84. }
  85. *pp = (line_p)0;
  86. if (head != (line_p)0 && INSTR(head) == ps_pro)
  87. {
  88. /* append register message without arguments to list */
  89. l = newline(OPLIST);
  90. l->l_instr = ps_mes;
  91. a = ARG(l) = newarg(ARGOFF);
  92. a->a_a.a_offset = ms_reg;
  93. *mp = l;
  94. l->l_next = head->l_next;
  95. head->l_next = headm;
  96. }
  97. else
  98. {
  99. assert(headm == (line_p)0);
  100. }
  101. return head;
  102. }
  103. STATIC int makedmap(dbl)
  104. dblock_p dbl;
  105. {
  106. /* construct the dmap table */
  107. dblock_p d;
  108. int cnt;
  109. /* determine the length of the table */
  110. cnt = 0;
  111. for (d = dbl; d != (dblock_p)0; d = d->d_next)
  112. cnt++;
  113. dmap = (dblock_p*)newmap(cnt);
  114. for (d = dbl; d != (dblock_p)0; d = d->d_next)
  115. {
  116. assert(d->d_id <= cnt);
  117. dmap[d->d_id] = d;
  118. }
  119. return cnt;
  120. }
  121. STATIC getdnames(dumpd)
  122. FILE* dumpd;
  123. {
  124. /* Read the names of the datalabels from
  125. * the dump file.
  126. */
  127. char str[IDL + 1];
  128. int id;
  129. dnames = (char**)newmap(dlength);
  130. for (;;)
  131. {
  132. if (fscanf(dumpd, "%d %s", &id, str) == EOF)
  133. return;
  134. assert(id <= dlength);
  135. dnames[id] = (char*)newcore(strlen(str) + 1);
  136. strcpy(dnames[id], str);
  137. }
  138. }
  139. STATIC getpnames(dumpp)
  140. FILE* dumpp;
  141. {
  142. /* Read the names of the procedures from
  143. * the dump file.
  144. */
  145. char str[IDL + 1];
  146. int id;
  147. pnames = (char**)newmap(plength);
  148. for (;;)
  149. {
  150. if (fscanf(dumpp, "%d %s", &id, str) == EOF)
  151. return;
  152. assert(id <= plength);
  153. pnames[id] = (char*)newcore(strlen(str) + 1);
  154. strcpy(pnames[id], str);
  155. }
  156. }
  157. STATIC new_name(s) char** s;
  158. {
  159. static int nn = 0;
  160. char buf[20];
  161. int len = strlen(*s);
  162. oldcore(*s, len + 1);
  163. buf[0] = '_';
  164. buf[1] = 'I';
  165. buf[2] = 'I';
  166. sprintf(&buf[3], "%d", nn);
  167. nn++;
  168. *s = (char*)newcore(strlen(buf) + 1);
  169. strcpy(*s, buf);
  170. }
  171. STATIC uniq_names()
  172. {
  173. /* The names of all internal procedures and data blocks
  174. * are made different. As the optimizer combines several
  175. * modules into one, there may be name conflicts between
  176. * procedures or data blocks that were internal in
  177. * different source modules.
  178. */
  179. proc_p p;
  180. dblock_p d;
  181. for (p = fproc; p != (proc_p)0; p = p->p_next)
  182. {
  183. if (!(p->p_flags1 & PF_EXTERNAL))
  184. {
  185. new_name(&(pnames[p->p_id]));
  186. }
  187. }
  188. for (d = fdblock; d != (dblock_p)0; d = d->d_next)
  189. {
  190. if (!(d->d_flags1 & DF_EXTERNAL) && dnames[d->d_id])
  191. {
  192. new_name(&(dnames[d->d_id]));
  193. }
  194. }
  195. }
  196. main(argc, argv) int argc;
  197. char* argv[];
  198. {
  199. /* CA does not output proctable etc. files. Instead, its
  200. * pname_out and dname_out arguments contain the names of the
  201. * dump files created by IC.
  202. */
  203. struct files* files = findfiles(argc, argv);
  204. FILE* f, *f2; /* The EM input and output. */
  205. FILE* df, *pf; /* The dump files */
  206. line_p lnp;
  207. /* The names of the input files of every phase are passed as
  208. * arguments to the phase. First come the input file names,
  209. * then the output file names. We use a one-letter convention
  210. * to denote the type of file:
  211. * p: procedure table file
  212. * d: data table file
  213. * l: EM text file (lines of EM instructions)
  214. * b: basic block file (Control Flow Graph file)
  215. */
  216. /* The input file names */
  217. char* pname_in = argv[1];
  218. char* dname_in = argv[2];
  219. char* lname_in = argv[3];
  220. char* bname_in = argv[4];
  221. /* The output file names */
  222. char* pname_out = argv[5];
  223. char* dname_out = argv[6];
  224. char* lname_out = argv[7];
  225. char* bname_out = argv[8];
  226. fproc = getptable(pname_in); /* proc table */
  227. fdblock = getdtable(dname_in); /* data block table */
  228. dlength = makedmap(fdblock); /* allocate dmap table */
  229. df = openfile(dname_out, "r");
  230. getdnames(df);
  231. fclose(df);
  232. pf = openfile(pname_out, "r");
  233. getpnames(pf);
  234. fclose(pf);
  235. uniq_names();
  236. f = openfile(lname_in, "r");
  237. f2 = stdout;
  238. cputmagic(f2); /* write magic number */
  239. while ((lnp = get_ca_lines(f, &curproc)) != (line_p)0)
  240. {
  241. cputlines(lnp, f2);
  242. }
  243. fclose(f);
  244. fclose(f2);
  245. exit(0);
  246. }