Pristine Ack-5.5
[Ack-5.5.git] / util / opt / process.c
1 #ifndef NORCSID
2 static char rcsid[] = "$Id: process.c,v 2.11 1994/06/24 10:40:42 ceriel Exp $";
3 #endif
4
5 #include "param.h"
6 #include "types.h"
7 #include "tes.h"
8 #include "assert.h"
9 #include <em_spec.h>
10 #include <em_pseu.h>
11 #include "alloc.h"
12 #include "line.h"
13 #include "lookup.h"
14 #include "proinf.h"
15 #include "ext.h"
16
17 /*
18  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
19  * See the copyright notice in the ACK home directory, in the file "Copyright".
20  *
21  * Author: Hans van Staveren
22  */
23
24 process() {
25
26         if (wordsize == 0 || pointersize == 0)
27                 error("No MES EMX encountered");
28         backward();                     /* reverse and cleanup list */
29         symknown();                     /* symbol scope is now known */
30         if (!nflag)
31                 symvalue();             /* give symbols value */
32         if (prodepth != 0) {
33                 if (!nflag) {
34                     int npasses = 0;
35                     bool madeopt;
36
37                     checklocs();        /* check definition of locals */
38                     do {
39                         madeopt = peephole();   /* local optimization */
40                         relabel();      /* relabel local labels */
41                         flow();         /* throw away unreachable code */
42                     } while (madeopt && ++npasses < 5000);
43                     assert(!madeopt);
44                 }
45                 do_tes();               /* top elt. size computation phase */
46                 outpro();               /* generate PRO pseudo */
47                 outregs();              /* generate MES ms_reg pseudos */
48                 outtes();               /* generate MES ms_tes pseudos */
49         }
50         putlines(pseudos);              /* pseudos first */
51         if (prodepth != 0) {
52                 putlines(instrs);       /* instructions next */
53                 outend();               /* generate END pseudo */
54                 cleanlocals();          /* forget instruction labels */
55         } else if(instrs != (line_p) 0)
56                 error("instructions outside procedure");
57 #ifdef COREDEBUG
58         coreverbose();
59 #endif
60 }
61
62 relabel() {
63         register num_p *npp,np,tp;
64         register num_p repl,ttp;
65
66         /*
67          * For each label find its final destination after crossjumping.
68          * Care has to be taken to prevent a loop in the program to
69          * cause same in the optimizer.
70          */
71
72         for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
73                 for (np = *npp; np != (num_p) 0; np = np->n_next) {
74                         assert(! np->n_line ||
75                            ((np->n_line->l_instr&BMASK) == op_lab
76                             && np->n_line->l_a.la_np == np));
77                         for(tp=np; (tp->n_flags&(NUMKNOWN|NUMMARK))==0;
78                                    tp = tp->n_repl)
79                                 tp->n_flags |= NUMMARK;
80                         repl = tp->n_repl;
81                         for(tp=np; tp->n_flags&NUMMARK; tp = ttp) {
82                                 ttp = tp->n_repl;
83                                 tp->n_repl = repl;
84                                 tp->n_flags &= ~ NUMMARK;
85                                 tp->n_flags |=   NUMKNOWN;
86                         }
87                 }
88         for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
89                 for (np = *npp; np != (num_p) 0; np = np->n_next) {
90                         np->n_flags &= ~(NUMKNOWN|NUMSCAN|NUMREACH);
91                         np->n_jumps = 0;
92                 }
93 }
94
95 symknown() {
96         register sym_p *spp,sp;
97
98         for (spp = symhash; spp < &symhash[NSYMHASH]; spp++)
99                 for (sp = *spp; sp != (sym_p) 0; sp = sp->s_next)
100                         if (sp->s_flags & SYMSEEN)
101                                 sp->s_flags |= SYMKNOWN;
102 }
103
104 cleanlocals() {
105         register num_p *npp,np,tp;
106
107         for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++) {
108                 np = *npp;
109                 while (np != (num_p) 0) {
110                         tp = np->n_next;
111                         oldnum(np);
112                         np = tp;
113                 }
114                 *npp = (num_p) 0;
115         }
116 }
117
118 checklocs() {
119         register num_p *npp,np;
120
121         for (npp=curpro.numhash; npp < & curpro.numhash[NNUMHASH]; npp++)
122                 for (np = *npp; np != (num_p) 0; np=np->n_next)
123                         if (np->n_line == (line_p) 0)
124                                 error("local label %u undefined",
125                                         (unsigned) np->n_number);
126 }
127
128 offset align(count,alignment) offset count,alignment; {
129
130         assert(alignment==1||alignment==2||alignment==4);
131         return((count+alignment-1)&~(alignment-1));
132 }
133
134 symvalue() {
135         register line_p lp;
136         register sym_p sp;
137         register arg_p ap;
138         register argb_p abp;
139         short curfrag = 0;
140         offset count;
141
142         for (lp=pseudos; lp != (line_p) 0; lp = lp->l_next)
143         switch(lp->l_instr&BMASK) {
144         default:
145                 assert(FALSE);
146         case ps_sym:
147                 sp = lp->l_a.la_sp;
148                 if (sp->s_frag != curfrag) {
149                         count = 0;
150                         curfrag = sp->s_frag;
151                 }
152                 count = align(count,wordsize);
153                 sp->s_value = count;
154                 break;
155         case ps_bss:
156         case ps_hol:
157                 /* nothing to do, all bss pseudos are in diff frags */
158         case ps_mes:
159                 break;
160         case ps_con:
161         case ps_rom:
162                 for (ap=lp->l_a.la_arg; ap  != (arg_p) 0; ap = ap->a_next)
163                 switch(ap->a_typ) {
164                 default:
165                         assert(FALSE);
166                 case ARGOFF:
167                         count = align(count,wordsize)+wordsize;
168                         break;
169                 case ARGNUM:
170                 case ARGSYM:
171                 case ARGVAL:
172                         count = align(count,wordsize)+pointersize;
173                         break;
174                 case ARGICN:
175                 case ARGUCN:
176                 case ARGFCN:
177                         if (ap->a_a.a_con.ac_length < wordsize)
178                                 count = align(count,(offset)ap->a_a.a_con.ac_length);
179                         else
180                                 count = align(count,wordsize);
181                         count += ap->a_a.a_con.ac_length;
182                         break;
183                 case ARGSTR:
184                         for (abp = &ap->a_a.a_string; abp != (argb_p) 0;
185                              abp = abp->ab_next)
186                                 count += abp->ab_index;
187                         break;
188                 }
189         }
190 }
191
192 do_tes()
193 {
194         register line_p insptr = instrs, oldlin = NULL, oldlin2 = NULL;
195
196         init_state();
197         tes_pseudos();
198         while (insptr != NULL) {
199                 tes_instr(insptr, oldlin, oldlin2);
200                 oldlin2 = oldlin;
201                 oldlin = insptr;
202                 insptr = insptr->l_next;
203         }
204 }