1 /* $Id: il3_subst.c,v 1.6 1994/06/24 10:26:01 ceriel Exp $ */
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".
6 /* I N L I N E S U B S T I T U T I O N
8 * I L 3 _ S U B S T . C
13 #include "../share/types.h"
15 #include "../share/debug.h"
16 #include "../share/alloc.h"
17 #include "../share/global.h"
18 #include "../share/lset.h"
19 #include "../share/get.h"
22 #include "il3_change.h"
23 #include "il3_subst.h"
25 STATIC line_p fetch_text(lf,c)
29 /* Read the EM text of the called procedure.
30 * We use random access I/O here.
38 mesregs = Lempty_set();
39 fseek(lf,c->cl_proc->P_LADDR,0);
41 assert (p == c->cl_proc);
50 line_p scan_to_cal(lines,n)
54 /* Find the n-th CAL instruction */
58 for (l = lines; l != (line_p) 0; l = l->l_next) {
59 if (INSTR(l) == op_cal) {
60 if (--n == 0) return l;
63 return (line_p) 0; /* CAL not found */
68 substitute(lf,c,cal,firstline)
73 /* Perform in line substitution of the call described
74 * by c. The EM text of the called routine is fetched
75 * and modified, the calling sequence is changed,
76 * the modified routine is put at the place of the call
77 * and all global information (proctable etc.) is kept
82 offset ab_off, lb_off;
83 line_p startscan, ncal;
88 ab_off = - curproc->p_localbytes;
89 /* offset of temporaries for parameters
90 * that are not expanded in line.
92 chg_callseq(c,cal,&l);
93 /* Change the calling sequence; l points to the place
94 * where the expanded text must be put
96 text = fetch_text(lf,c); /* fetch EM text of called routine */
97 lb_off = - curproc->p_localbytes;
98 /* offset of temps. for locals of called proc. */
99 curproc->p_localbytes += c->cl_proc->P_ORGLOCALS;
100 /* locals of called routine are put in stack frame of caller */
101 if (!FALLTHROUGH(c->cl_proc)) {
102 /* The called proc contains one or more RETurns
103 * somewhere in the middle of its text; these
104 * should be changed into a jump to the end
105 * of the text. We create a label for this
106 * purpose (if there was no one already).
108 lab = make_label(l,curproc);
110 modify(text,c,lab,ab_off,lb_off,curproc->p_nrlabels);
111 curproc->p_nrlabels += c->cl_proc->P_ORGLABELS;
112 insert(text,l,firstline);
113 /* insert text; instructions are put after l, pseudos
114 * are put at beginning of caller.
116 /* Now take care of the nested calls */
117 startscan = l->l_next;
119 for (nc = c->cl_car; nc != (call_p) 0; nc = nc->cl_cdr) {
120 mod_actuals(nc,c,lab,ab_off,lb_off,curproc->p_nrlabels);
121 ncal = scan_to_cal(startscan,nc->cl_id - lastcid);
122 assert(ncal != (line_p) 0);
123 startscan = scan_to_cal(ncal->l_next,1);
125 substitute(lf,nc,ncal,firstline);