Pristine Ack-5.5
[Ack-5.5.git] / util / opt / backward.c
1 #ifndef NORCSID
2 static char rcsid[] = "$Id: backward.c,v 2.12 1994/06/24 10:39:46 ceriel Exp $";
3 #endif
4
5 #include "param.h"
6 #include "types.h"
7 #include "tes.h"
8 #include "assert.h"
9 #include "line.h"
10 #include "lookup.h"
11 #include "alloc.h"
12 #include "proinf.h"
13 #include <em_spec.h>
14 #include <em_pseu.h>
15 #include <em_mnem.h>
16 #include <em_mes.h>
17 #include "ext.h"
18
19 /*
20  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
21  * See the copyright notice in the ACK home directory, in the file "Copyright".
22  *
23  * Author: Hans van Staveren
24  */
25
26 #define local(x)        ((((x)->s_flags&SYMKNOWN) == 0 && \
27                           ((x)->s_flags &= ~ SYMGLOBAL)),\
28                          (x)->s_flags |= SYMSEEN)
29 #define global(x)       ((((x)->s_flags&SYMKNOWN) == 0 && \
30                           ((x)->s_flags |= SYMGLOBAL)), \
31                          (x)->s_flags |= SYMSEEN)
32
33 #define DTYPHOL 1
34 #define DTYPBSS 2
35 #define DTYPCON 3
36 #define DTYPROM 4
37 byte    curdtyp;
38 bool    goodrom;
39 short   curfrag = 3;    /* see also peephole.c */
40 offset rombuf[MAXROM];
41 int     rc;
42
43 extern offset aoff();
44
45 backward() {
46         register line_p lnp;
47         line_p  next;
48         register arg_p ap;
49         line_p i,p;
50         int n;
51         register sym_p sp;
52
53         i = p = (line_p) 0;
54         curdtyp=0;
55         for (lnp = curpro.lastline; lnp != (line_p) 0; lnp = next) {
56                 next = lnp->l_next;
57                 switch(lnp->l_optyp) {
58                 case OPSYMBOL:
59                         global(lnp->l_a.la_sp);
60                         break;
61                 case OPSVAL:
62                         global(lnp->l_a.la_sval.lasv_sp);
63                         break;
64                 case OPLVAL:
65                         global(lnp->l_a.la_lval.lalv_sp);
66                         break;
67                 case OPLIST:
68                         ap = lnp->l_a.la_arg;
69                         while (ap != (arg_p) 0 ) {
70                                 switch(ap->a_typ) {
71                                 case ARGSYM:
72                                         global(ap->a_a.a_sp);
73                                         break;
74                                 case ARGVAL:
75                                         global(ap->a_a.a_val.av_sp);
76                                 }
77                                 ap = ap->a_next;
78                         }
79                         break;
80                 }
81
82                 /*
83                  * references to symbols are processed now.
84                  * for plain instructions nothing else is needed
85                  */
86
87                 switch(lnp->l_instr&BMASK) {
88                 /*
89                  * count all local occurences for register counts;
90                  * op_lal is omitted and not by accident.
91                  */
92                 case op_del:
93                 case op_inl:
94                 case op_ldl:
95                 case op_lil:
96                 case op_lol:
97                 case op_sdl:
98                 case op_sil:
99                 case op_stl:
100                 case op_zrl:
101                         switch(lnp->l_optyp) {
102                         case OPNO:
103                         case OPNUMLAB:
104                         case OPSYMBOL:
105                         case OPSVAL:
106                         case OPLVAL:
107                         case OPLIST:
108                                 break;
109                         case OPOFFSET:
110                                 incregusage(lnp->l_a.la_offset);
111                                 break;
112                         case OPSHORT:
113                                 incregusage((offset)lnp->l_a.la_short);
114                                 break;
115                         default:
116                                 incregusage((offset)(lnp->l_optyp&BMASK)-Z_OPMINI);
117                                 break;
118                         }
119                         /* fall through !! */
120                 default:
121                         assert((lnp->l_instr&BMASK)<=op_last);
122                         lnp->l_next = i;
123                         i = lnp;
124                         continue;
125                 case ps_sym:
126                         sp = lnp->l_a.la_sp;
127                         local(sp);
128                         if (curdtyp == DTYPROM && goodrom) {
129                                 sp->s_rom = newrom();
130                                 for (n=0;n<rc;n++)
131                                         sp->s_rom[n] = rombuf[n];
132                         }
133                         sp->s_frag = curfrag;
134                         break;
135                 case ps_hol:
136                         curdtyp = DTYPHOL;
137                         curfrag++;
138                         break;
139                 case ps_bss:
140                         curdtyp = DTYPBSS;
141                         curfrag++;
142                         break;
143                 case ps_con:
144                         if (curdtyp != DTYPCON) {
145                                 curdtyp = DTYPCON;
146                                 curfrag++;
147                         }
148                         break;
149                 case ps_rom:
150                         if (curdtyp != DTYPROM) {
151                                 curdtyp = DTYPROM;
152                                 curfrag++;
153                         }
154                         ap = lnp->l_a.la_arg;
155                         rc = 0;
156                         while (ap != (arg_p) 0 && rc < MAXROM) {
157                                 if (ap->a_typ == ARGOFF) {
158                                         rombuf[rc++] = ap->a_a.a_offset;
159                                         ap = ap->a_next;
160                                 } else
161                                         ap = (arg_p) 0;
162                         }
163                         goodrom = (rc >= 2);
164                         break;
165                 case ps_mes:
166                         if (prodepth != 0 &&
167                             ((int) aoff(lnp->l_a.la_arg, 0) == ms_std ||
168                              (int) aoff(lnp->l_a.la_arg, 0) == ms_stb ||
169                              (int) aoff(lnp->l_a.la_arg, 0) == ms_ego)) {
170                                 lnp->l_next = i;
171                                 i = lnp;
172                                 continue;
173                         }
174                         break;
175                 case ps_inp:
176                 case ps_ina:
177                         local(lnp->l_a.la_sp);
178                 case ps_exp:
179                 case ps_exa:
180                 case ps_exc:
181                         oldline(lnp);
182                         continue;
183                 }
184                 lnp->l_next = p;
185                 p = lnp;
186         }
187         if (prodepth != 0)
188                 local(curpro.symbol);
189         instrs = i; pseudos = p; curpro.lastline = (line_p) 0;
190 }