Pristine Ack-5.5
[Ack-5.5.git] / util / ncgg / coerc.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 #ifndef NORCSID
6 static char rcsid[]= "$Id: coerc.c,v 0.6 1994/06/24 10:37:00 ceriel Exp $";
7 #endif
8
9 #include "assert.h"
10 #include "param.h"
11 #include "set.h"
12 #include "property.h"
13 #include "reg.h"
14 #include "token.h"
15 #include "varinfo.h"
16 #include "iocc.h"
17 #include <cgg_cg.h>
18 #include "pseudo.h"
19 #include "extern.h"
20
21 extern set_t l_sets[];
22
23 int nmoves;
24 move_t l_moves[MAXMOVES];
25 short posmoves[MAXREGS+MAXTOKENS][SETSIZE];
26
27 n_move(s1,e1,s2,e2,vi) struct varinfo *vi; {
28         register move_p mp;
29         register i,j;
30
31         NEXT(nmoves,MAXMOVES,"Moves");
32         mp = &l_moves[nmoves-1];
33         mp->m_set1 = s1;
34         mp->m_expr1 = e1;
35         mp->m_set2 = s2;
36         mp->m_expr2 = e2;
37         mp->m_cindex = codeindex;
38         dopattern(0,VI_NULL,VI_NULL,vi,VI_NULL,VI_NULL);
39         if (mp->m_expr1!=0 || mp->m_expr2!=0)
40                 return;
41         for (i=0;i<MAXREGS+MAXTOKENS;i++)
42             if (BIT(l_sets[mp->m_set1].set_val,i))
43                 for(j=0;j<SETSIZE;j++)
44                     posmoves[i][j] |= l_sets[mp->m_set2].set_val[j];
45 }
46
47 existmove(from,sp) iocc_t from; short *sp; {
48         register i;
49
50         for (i=0;i<MAXREGS+MAXTOKENS;i++)
51             if(BIT(from.in_set,i))
52                 if (!subset(sp,posmoves[i],SETSIZE))
53                         return(0);
54         return(1);
55 }
56
57 existalmove(from,prpno) iocc_t from; {
58         short s[SETSIZE];
59         register i;
60         
61         for (i=0;i<SETSIZE;i++)
62                 s[i] = i<SZOFSET(MAXREGS) ? l_props[prpno].pr_regset[i] : 0;
63         return(existmove(from,s));
64 }
65
66 struct varinfo *gen_move(from,to) iocc_t from,to; {
67         register struct varinfo *vp;
68
69         if (existmove(from,to.in_set)==0) {
70                 error("No such move defined");
71                 return(VI_NULL);
72         }
73         NEW(vp,struct varinfo);
74         vp->vi_int[0] = INSMOVE;
75         vp->vi_int[1] = from.in_index;
76         vp->vi_int[2] = to.in_index;
77         return(vp);
78 }
79
80 int ntests;
81 test_t l_tests[MAXTESTS];
82 short postests[SETSIZE];
83
84 n_test(s,e,vi) struct varinfo *vi; {
85         register test_p tp;
86         register i;
87
88         NEXT(ntests,MAXTESTS,"Tests");
89         tp = &l_tests[ntests-1];
90         tp->t_set = s;
91         tp->t_expr = e; 
92         tp->t_cindex = codeindex;
93         dopattern(0,VI_NULL,VI_NULL,vi,VI_NULL,VI_NULL);
94         if (tp->t_expr!=0)
95                 return;
96         for(i=0;i<SETSIZE;i++)
97                 postests[i] |= l_sets[tp->t_set].set_val[i];
98 }
99
100 struct varinfo *gen_test(from) iocc_t from; {
101         register struct varinfo *vp;
102
103         if (!subset(from.in_set,postests,SETSIZE)) {
104                 error("No such test");
105                 return(0);
106         }
107         NEW(vp,struct varinfo);
108         vp->vi_int[0] = INSTEST;
109         vp->vi_int[1] = from.in_index;
110         return(vp);
111 }
112
113 struct varinfo *gen_label(arg) int arg; {
114         register struct varinfo *vp;
115
116         NEW(vp,struct varinfo);
117         vp->vi_int[0] = INSLABDEF;
118         vp->vi_int[1] = arg;
119         return(vp);
120 }
121
122 struct varinfo *gen_preturn() {
123         register struct varinfo *vp;
124
125         NEW(vp,struct varinfo);
126         vp->vi_int[0] = INSPRETURN;
127         return(vp);
128 }
129
130 struct varinfo *gen_tlab(n) {
131         register struct varinfo *vp;
132
133         assert(n>=0 && n<=9);
134         NEW(vp,struct varinfo);
135         vp->vi_int[0] = INSTLAB;
136         vp->vi_int[1] = n;
137         return(vp);
138 }
139
140 int nstacks;
141 c1_t l_stacks[MAXSTACKS];
142 set_t ustackset,cstackset;
143
144 n_stack(s,e,p,vi) struct varinfo *vi; {
145         register c1_p c1p;
146         register short *sp;
147         register i;
148
149         NEXT(nstacks,MAXSTACKS,"Stacks");
150         c1p= & l_stacks[nstacks-1];
151         c1p->c1_texpno = s;
152         c1p->c1_expr = e;
153         c1p->c1_prop = p;
154         c1p->c1_codep = codeindex;
155         dopattern(0,VI_NULL,VI_NULL,vi,VI_NULL,VI_NULL);
156
157         if (e==0 && p== -1)
158                 sp = ustackset.set_val;
159         else
160                 sp = cstackset.set_val;
161         for(i=0;i<SETSIZE;i++)
162                 sp[i] |= l_sets[s].set_val[i];
163 }
164
165 checkstacking(sp) register short *sp; {
166         register i;
167         register short *chkset;
168         char *warn;
169
170         if (subset(sp,ustackset.set_val,SETSIZE))
171                 return;
172         chkset = ustackset.set_val; warn = "";
173         for (i=1;i<nregs;i++)
174                 if (BIT(sp,i) && !BIT(chkset,i))
175                         error("No %sstacking rule for register %s",warn,
176                                 l_regs[i].ri_name);
177         for(;i<nregs+MAXTOKENS;i++)
178                 if (BIT(sp,i) && !BIT(chkset,i))
179                         error("No %sstacking rule for token %s",warn,
180                                 l_tokens[i-nregs]->tk_name);
181 }
182
183 int ncoercs;
184 c3_t l_coercs[MAXCOERCS];
185 set_t unstackset;
186
187 /*VARARGS5*/
188
189 n_coerc(ti,be,al,ge,rp,in) struct varinfo *al,*ge,*rp; iocc_t in; {
190         register c3_p c3p;
191         register i;
192         register struct varinfo *vi;
193
194         if (ti!=0) {
195                 for(i=0,vi=rp;vi!=0;vi=vi->vi_next,i++)
196                         ;
197                 if (i>1) {
198                         n_split(ti,be,al,ge,rp,i);
199                         return;
200                 } else {
201                         if (i==0) {
202                                 error("Coercion should have a result!");
203                                 return;
204                         }
205                 }
206         } else {
207                 NEW(rp,struct varinfo);
208                 rp->vi_next = 0;
209                 rp->vi_int[0] = in.in_index;
210         }
211         if (nallreg>1)
212                 error("More than 1 register may not be allocated");
213         NEXT(ncoercs,MAXCOERCS,"Coercions");
214         c3p = & l_coercs[ncoercs-1];
215         c3p->c3_texpno = ti;
216         c3p->c3_expr = be;
217         c3p->c3_prop = nallreg==0 ? -1 : allreg[0];
218         c3p->c3_repl = rp->vi_int[0];
219         c3p->c3_codep = codeindex;
220         dopattern(ti==0,VI_NULL,al,ge,rp,VI_NULL);
221         if (ti==0)
222                 for(i=0;i<SETSIZE;i++)
223                         unstackset.set_val[i] |= in.in_set[i];
224         freevi(rp);
225 }
226
227 checkunstacking(setno) {
228         register short *sp;
229         register i;
230         short hallset[SETSIZE];
231         
232         sp = l_sets[setno].set_val;
233         for (i=0;i<SETSIZE;i++)
234                 hallset[i]=sp[i]&unstackset.set_val[i];
235         nexthall(hallset);
236 }
237
238 int nsplit,maxsplit;
239 c2_t l_split[MAXSPLCOERC];
240
241 n_split(ti,be,al,ge,rp,n) struct varinfo *al,*ge,*rp; {
242         register c2_p c2p;
243         register i;
244         register struct varinfo *vi;
245
246         NEXT(nsplit,MAXSPLCOERC,"Splitting coercions");
247         c2p = &l_split[nsplit-1];
248         if (n>MAXSPLIT) {
249                 error("Maximum split factor is %d",MAXSPLIT);
250                 n = MAXSPLIT;
251         }
252         if (n>maxsplit) maxsplit=n;
253         c2p->c2_texpno = ti;
254         c2p->c2_expr = be;
255         if (nallreg)
256                 error("No register uses allowed in splitting coercion");
257         c2p->c2_nsplit = n;
258         for (i=0,vi=rp; i<n; i++,vi=vi->vi_next)
259                 c2p->c2_repl[i] = vi->vi_int[0];
260         c2p->c2_codep = codeindex;
261         dopattern(0,VI_NULL,al,ge,rp,VI_NULL);
262 }