Pristine Ack-5.5
[Ack-5.5.git] / util / ncgg / expr.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: expr.c,v 0.4 1994/06/24 10:37:14 ceriel Exp $";
7 #endif
8
9 #include "assert.h"
10 #include "param.h"
11 #include "set.h"
12 #include "reg.h"
13 #include "lookup.h"
14 #include "token.h"
15 #include "property.h"
16 #include "expr.h"
17 #include "regvar.h"
18 #include <cgg_cg.h>
19 #include "extern.h"
20
21 extern set_t l_sets[];
22
23 i_expr(e) expr_t e; {
24
25         if (e.ex_typ != TYPINT)
26                 error("Expression should be integer");
27         return(e.ex_index);
28 }
29
30 b_expr(e) expr_t e; {
31         if (e.ex_typ != TYPBOOL)
32                 error("Expression should be boolean");
33         return(e.ex_index);
34 }
35
36 expr_t make_expr(type,operator,op1,op2) {
37         expr_t result;
38
39         result.ex_typ=type;
40         result.ex_index=ex_lookup(operator,op1,op2);
41         return(result);
42 }
43
44 expr_t regno_expr(regno) {
45         expr_t result;
46         register i;
47
48         result.ex_typ = TYPREG;
49         result.ex_index = ex_lookup(EX_REG,regno,0);
50         for (i=0;i<SZOFSET(MAXREGS);i++)
51                 result.ex_regset[i] = 0;
52         BIS(result.ex_regset,regno);
53         return(result);
54 }
55
56 expr_t ident_expr(name) char *name; {
57         register symbol *sy_p;
58
59         sy_p = lookup(name,symany,mustexist);
60         if (sy_p->sy_type==symconst)
61                 return(make_expr(TYPINT,EX_CON,
62                            (int) (sy_p->sy_value.syv_cstval&0xFFFF),
63                            (int) (sy_p->sy_value.syv_cstval>>16)));
64         else if (sy_p->sy_type==symsconst)
65                 return(make_expr(TYPADDR,EX_STRING,sy_p->sy_value.syv_stringno,0));
66         else if (sy_p->sy_type!=symreg)
67                 error("Wrong type of identifier %s",name);
68         return(regno_expr(sy_p->sy_value.syv_regno));
69 }
70
71 expr_t subreg_expr(tokarg,subreg) {
72         expr_t result;
73
74         result.ex_typ = TYPREG;
75         subregset(l_sets[tokpatset[tokarg > 0 ? tokarg-1 : tokarg]].set_val,
76                   subreg,result.ex_regset);
77         result.ex_index = ex_lookup(EX_SUBREG,tokarg,subreg);
78         return(result);
79 }
80
81 subregset(sp,subreg,regset) register short *sp; register short *regset; {
82         register i;
83         register reginfo *rp;
84
85         for (i=0;i<SZOFSET(MAXREGS);i++)
86                 regset[i]=0;
87         for (i=1;i<nregs;i++)   if (BIT(sp,i)) {
88                 if(subreg) {
89                         rp = &l_regs[i];
90                         if (rp->ri_memb[subreg-1]==0)
91                                 error("Register %s in set has no member %d",
92                                         rp->ri_name,subreg);
93                         BIS(regset,rp->ri_memb[subreg-1]);
94                 } else
95                         BIS(regset,i);
96         }
97         for(;i<nregs+MAXTOKENS;i++) if(BIT(sp,i))
98                 error("Set contains %s, which is not a register",
99                         l_tokens[i-nregs]->tk_name);
100 }
101
102 membset(setno,name,regset,appearance,restyp,typp)
103 char *name,*appearance;
104 short *regset;
105 int *typp;
106 {
107         register short *sp;
108         register token_p tp;
109         register i,j,k;
110         int thistyp;
111         int typesdiffer=0;
112         int res_j= -1;
113
114         if (setno < 0) return 0;
115         sp = l_sets[setno].set_val;
116         for (i=1;i<nregs;i++) if (BIT(sp,i)) {
117                 error("Set in %s contains %s, which is not a token",
118                         appearance,l_regs[i].ri_name);
119                 break;
120         }
121         for (i=0;i<SZOFSET(MAXREGS);i++)
122                 regset[i] = 0;
123         for (i=nregs;i<nregs+MAXTOKENS;i++) if (BIT(sp,i)) {
124                 tp = l_tokens[i-nregs];
125                 for(j=0;j<MAXATT &&
126                         (tp->tk_att[j].ta_type == -3 ||
127                          strcmp(tp->tk_att[j].ta_name,name));j++)
128                         ;
129                 if (j==MAXATT)
130                         error("Token %s does not contain %s",tp->tk_name,name);
131                 else if (j!=res_j && res_j != -1)
132                         typesdiffer=1;
133                 else {
134                         res_j = j;
135                         thistyp = tp->tk_att[j].ta_type;
136                         if (thistyp== -2) {
137                                 if (restyp!=TYPADDR && restyp!=0)
138                                         typesdiffer=1;
139                                 else
140                                         restyp=TYPADDR;
141                         } else if (thistyp== -1) {
142                                 if (restyp!=TYPINT && restyp!=0)
143                                         typesdiffer=1;
144                                 else
145                                         restyp=TYPINT;
146                         } else {
147                                 if (restyp!=TYPREG && restyp!=0)
148                                         typesdiffer=1;
149                                 else {
150                                         restyp=TYPREG;
151                                         for(k=0;k<SZOFSET(MAXREGS);k++)
152                                                 regset[k] |=
153                                                     l_props[tp->tk_att[j].ta_type].pr_regset[k];
154                                 }
155                         }
156                 }
157         }
158         if (typesdiffer)
159                 error("%s is not a valid expression; types differ in the set",
160                         appearance);
161         *typp = restyp==0 ? TYPINT : restyp;
162         return(res_j == -1 ? 0 : res_j);
163 }
164
165 expr_t memb_expr(setno,name,appearance,tokarg) char *name,*appearance; {
166         expr_t result;
167         int res_j;
168
169         res_j = membset(setno,name,result.ex_regset,appearance,0,&result.ex_typ);
170         result.ex_index = ex_lookup(EX_TOKFIELD,tokarg,res_j+1);
171         return(result);
172 }
173
174 expr_t tokm_expr(tokarg,name) char *name; {
175         char app[100];
176         int tokarg1 = tokarg > 0 ? tokarg : 1;
177
178         sprintf(app,"%%%d.%s",tokarg1,name);
179         return(memb_expr(tokpatset[tokarg1-1],name,app,tokarg));
180 }
181
182 expr_t perc_ident_expr(name) char *name; {
183         char app[100];
184
185         sprintf(app,"%%%s",name);
186         return(memb_expr(cursetno,name,app,0));
187 }
188
189 expr_t all_expr(all_no,subreg) {
190         set_t localset;
191         register i;
192         register short *sp;
193         expr_t result;
194
195         sp = l_props[allreg[all_no]].pr_regset;
196         for (i=0;i<SETSIZE;i++)
197                 localset.set_val[i] = i<SZOFSET(MAXREGS) ? sp[i] : 0;
198         subregset(localset.set_val,subreg,result.ex_regset);
199         result.ex_typ = TYPREG;
200         result.ex_index = ex_lookup(EX_ALLREG,all_no+1,subreg);
201         return(result);
202 }
203
204 eq2expr(e1,e2) expr_t e1,e2; {
205
206         if (e1.ex_typ != e2.ex_typ)
207                 error("Expressions around == should have equal type");
208         switch (e1.ex_typ) {
209         default: assert(0);
210         case TYPBOOL:
211                 error("== on booleans not implemented");
212         case TYPINT:
213                 return(EX_NCPEQ);
214         case TYPADDR:
215                 return(EX_SCPEQ);
216         case TYPREG:
217                 return(EX_RCPEQ);
218         }
219 }
220
221 ne2expr(e1,e2) expr_t e1,e2; {
222
223         if (e1.ex_typ != e2.ex_typ)
224                 error("Expressions around != should have equal type");
225         switch (e1.ex_typ) {
226         default: assert(0);
227         case TYPBOOL:
228                 error("!= on booleans not implemented");
229         case TYPINT:
230                 return(EX_NCPNE);
231         case TYPADDR:
232                 return(EX_SCPNE);
233         case TYPREG:
234                 return(EX_RCPNE);
235         }
236 }
237
238 expr_t sum_expr(e1,e2) expr_t e1,e2; {
239         int operator,op1,op2;
240         expr_t result;
241
242         operator = EX_CAT; op1 = e1.ex_index; op2 = e2.ex_index;
243         if (e1.ex_typ==e2.ex_typ) {
244                 result.ex_typ = e1.ex_typ;
245                 if (e1.ex_typ == TYPINT)
246                         operator = EX_PLUS;
247                 else if (e1.ex_typ != TYPADDR)
248                         error("+ is not implemented on this type");
249         } else {
250                 result.ex_typ = TYPADDR;
251                 if (e1.ex_typ != TYPADDR) {
252                         if (e1.ex_typ!=TYPINT)
253                                 error("Wrong left operand of +");
254                         op1 = ex_lookup(EX_TOSTRING,op1,0);
255                 }
256                 if (e2.ex_typ != TYPADDR) {
257                         if (e2.ex_typ!=TYPINT)
258                                 error("Wrong right operand of +");
259                         op2 = ex_lookup(EX_TOSTRING,op2,0);
260                 }
261         }
262         result.ex_index=ex_lookup(operator,op1,op2);
263         return(result);
264 }
265
266 expr_t iextoaddr(e) expr_t e; {
267         expr_t result;
268
269         result.ex_typ = TYPADDR;
270         result.ex_index = ex_lookup(EX_TOSTRING,e.ex_index,0);
271         return(result);
272 }
273
274 expr_t regvar_expr(e,regtyp) expr_t e; {
275         expr_t result;
276         register i;
277         
278         result = make_expr(TYPREG,EX_REGVAR,i_expr(e),0);
279         for(i=0;i<SZOFSET(MAXREGS);i++)
280                 result.ex_regset[i]=0;
281         for(i=0;i<nregvar[regtyp];i++)
282                 BIS(result.ex_regset,rvnumbers[regtyp][i]);
283         return(result);
284 }
285                 
286 /*
287  * Node table lookup part
288  */
289
290 node_t nodes[MAXNODES];
291 int nnodes=0;
292
293 initnodes() {
294
295         nodes[0].ex_operator = EX_CON;
296         nodes[0].ex_lnode = 0;
297         nodes[0].ex_rnode = 0;
298         nnodes++;
299 }
300
301 ex_lookup(operator,lnode,rnode) {
302         register node_p p;
303
304         for(p=nodes+1;p< &nodes[nnodes];p++) {
305                 if (p->ex_operator != operator)
306                         continue;
307                 if (p->ex_lnode != lnode)
308                         continue;
309                 if (p->ex_rnode != rnode)
310                         continue;
311                 return(p-nodes);
312         }
313         NEXT(nnodes,MAXNODES,"Node");
314         p->ex_operator = operator;
315         p->ex_lnode = lnode;
316         p->ex_rnode = rnode;
317         return(p-nodes);
318 }