il3_subst.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. /* I N L I N E S U B S T I T U T I O N
  7. *
  8. * I L 3 _ S U B S T . C
  9. */
  10. #include <stdio.h>
  11. #include <em_mnem.h>
  12. #include "../share/types.h"
  13. #include "il.h"
  14. #include "../share/debug.h"
  15. #include "../share/alloc.h"
  16. #include "../share/global.h"
  17. #include "../share/lset.h"
  18. #include "../share/get.h"
  19. #include "il_aux.h"
  20. #include "il3_aux.h"
  21. #include "il3_change.h"
  22. #include "il3_subst.h"
  23. STATIC line_p fetch_text(lf,c)
  24. FILE *lf;
  25. call_p c;
  26. {
  27. /* Read the EM text of the called procedure.
  28. * We use random access I/O here.
  29. */
  30. line_p l;
  31. proc_p p;
  32. lset savmes;
  33. savmes = mesregs;
  34. mesregs = Lempty_set();
  35. fseek(lf,c->cl_proc->P_LADDR,0);
  36. l = get_text(lf,&p);
  37. assert (p == c->cl_proc);
  38. Ldeleteset(mesregs);
  39. mesregs = savmes;
  40. return l;
  41. }
  42. line_p scan_to_cal(lines,n)
  43. line_p lines;
  44. short n;
  45. {
  46. /* Find the n-th CAL instruction */
  47. register line_p l;
  48. for (l = lines; l != (line_p) 0; l = l->l_next) {
  49. if (INSTR(l) == op_cal) {
  50. if (--n == 0) return l;
  51. }
  52. }
  53. return (line_p) 0; /* CAL not found */
  54. }
  55. substitute(lf,c,cal,firstline)
  56. FILE *lf;
  57. call_p c;
  58. line_p cal,firstline;
  59. {
  60. /* Perform in line substitution of the call described
  61. * by c. The EM text of the called routine is fetched
  62. * and modified, the calling sequence is changed,
  63. * the modified routine is put at the place of the call
  64. * and all global information (proctable etc.) is kept
  65. * up to date.
  66. */
  67. line_p l, text, lab;
  68. offset ab_off, lb_off;
  69. line_p startscan, ncal;
  70. short lastcid;
  71. call_p nc;
  72. Ssubst++;
  73. ab_off = - curproc->p_localbytes;
  74. /* offset of temporaries for parameters
  75. * that are not expanded in line.
  76. */
  77. chg_callseq(c,cal,&l);
  78. /* Change the calling sequence; l points to the place
  79. * where the expanded text must be put
  80. */
  81. text = fetch_text(lf,c); /* fetch EM text of called routine */
  82. lb_off = - curproc->p_localbytes;
  83. /* offset of temps. for locals of called proc. */
  84. curproc->p_localbytes += c->cl_proc->P_ORGLOCALS;
  85. /* locals of called routine are put in stack frame of caller */
  86. if (!FALLTHROUGH(c->cl_proc)) {
  87. /* The called proc contains one or more RETurns
  88. * somewhere in the middle of its text; these
  89. * should be changed into a jump to the end
  90. * of the text. We create a label for this
  91. * purpose (if there was no one already).
  92. */
  93. lab = make_label(l,curproc);
  94. }
  95. modify(text,c,lab,ab_off,lb_off,curproc->p_nrlabels);
  96. curproc->p_nrlabels += c->cl_proc->P_ORGLABELS;
  97. insert(text,l,firstline);
  98. /* insert text; instructions are put after l, pseudos
  99. * are put at beginning of caller.
  100. */
  101. /* Now take care of the nested calls */
  102. startscan = l->l_next;
  103. lastcid = 0;
  104. for (nc = c->cl_car; nc != (call_p) 0; nc = nc->cl_cdr) {
  105. mod_actuals(nc,c,lab,ab_off,lb_off,curproc->p_nrlabels);
  106. ncal = scan_to_cal(startscan,nc->cl_id - lastcid);
  107. assert(ncal != (line_p) 0);
  108. startscan = scan_to_cal(ncal->l_next,1);
  109. lastcid = nc->cl_id;
  110. substitute(lf,nc,ncal,firstline);
  111. }
  112. }