Pristine Ack-5.5
[Ack-5.5.git] / util / ncgg / subr.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: subr.c,v 0.7 1994/06/24 10:38:23 ceriel Exp $";
7 #endif
8
9 #include "param.h"
10 #include "reg.h"
11 #include "lookup.h"
12 #include "property.h"
13 #include "expr.h"
14 #include "set.h"
15 #include "varinfo.h"
16 #include "instruct.h"
17 #include "token.h"
18 #include "regvar.h"
19 #include <cgg_cg.h>
20 #include "extern.h"
21
22 n_proc(name) char *name; {
23         register symbol *sy_p;
24         extern int npatbytes;
25
26         sy_p = lookup(name,symproc,newsymbol);
27         sy_p->sy_value.syv_procoff = npatbytes + 1;
28 }
29
30 struct varinfo *
31 make_erase(name) char *name; {
32         expr_t e,ident_expr();
33         struct varinfo *result;
34
35         e = ident_expr(name);
36         if (e.ex_typ != TYPREG)
37                 error("Register name required here");
38         NEW(result,struct varinfo);
39         result->vi_next = VI_NULL;
40         result->vi_int[0] = e.ex_index;
41         return(result);
42 }
43
44 n_instr(name,asname,oplist,eraselist,cost)
45 char *name,*asname;
46 operand *oplist;
47 struct varinfo *eraselist,*cost;
48 {
49         register instrno;
50         register cc_count;
51         register instr_p ip;
52
53         instrno = NEXT(ninstr,MAXINSTR,"Instructions");
54         ip = &l_instr[instrno];
55         ip->i_name = name;
56         ip->i_asname = strlookup(asname!=0 ? asname : name);
57         ip->i_nops = 0;
58         ip->i_oplist = oplist;
59         ip->i_erases = eraselist;
60         if (cost==0) {
61                 ip->i_cost.ct_space = 0;
62                 ip->i_cost.ct_time = 0;
63         } else {
64                 ip->i_cost.ct_space = cost->vi_int[0];
65                 ip->i_cost.ct_space = cost->vi_int[1];
66         }
67         for (cc_count=0; oplist!=0; oplist = oplist->o_next) {
68                 ip->i_nops++;
69                 if(oplist->o_adorn&AD_CC)
70                         cc_count++;
71         }
72         while (eraselist!=VI_NULL) {
73                 if (eraselist->vi_int[0] == -1 && cc_count)
74                         error("Instruction can't both set and break the condition codes");
75                 eraselist=eraselist->vi_next;
76         }
77         if (cc_count>1)
78                 error("No instruction can set condition codes more than once");
79 }
80
81 n_set(name,number) char *name; {
82         register symbol *sy_p;
83
84         sy_p = lookup(name,symset,newsymbol);
85         sy_p->sy_value.syv_setno = number;
86 }
87
88 n_tok(name,atts,size,cost,format)
89 char *name;
90 struct varinfo *atts,*cost,*format;
91 {
92         register symbol *sy_p;
93         register token_p tp;
94         register struct varinfo *vip;
95         int i;
96         int tokno;
97         int thistokensize;
98         char formstr[50],smallstr[2];
99
100         sy_p = lookup(name,symtok,newsymbol);
101         NEW(tp,token_t);
102         tokno = NEXT(ntokens,MAXTOKENS,"Tokens");
103         sy_p->sy_value.syv_tokno = tokno;
104         l_tokens[tokno] = tp;
105         tp->tk_name = sy_p->sy_name;
106         tp->tk_size = size;
107         if (cost != 0) {
108                 tp->tk_cost.ct_space = cost->vi_int[0];
109                 tp->tk_cost.ct_time  = cost->vi_int[1];
110         } else {
111                 tp->tk_cost.ct_space = 0;
112                 tp->tk_cost.ct_time  = 0;
113         }
114         for(i=0,vip=atts;i<MAXATT && vip!=0;i++,vip=vip->vi_next) {
115                 tp->tk_att[i].ta_type = vip->vi_int[0];
116                 tp->tk_att[i].ta_name = vip->vi_str[0];
117                 vip->vi_str[0]=0;
118         }
119         thistokensize=i;
120         if (i>maxtokensize)
121                 maxtokensize=i;
122         if (vip!=0)
123                 error("More then %d attributes, rest discarded",MAXATT);
124         for(;i<MAXATT;i++)
125                 tp->tk_att[i].ta_type= -3;
126         if (format!=0) {
127                 formstr[0] = 0;
128                 for (vip=format;vip!=0;vip=vip->vi_next) {
129                         if (vip->vi_int[0]==0)
130                                 strcat(formstr,vip->vi_str[0]);
131                         else {
132                                 for(i=0;i<thistokensize;i++) {
133                                         if (strcmp(vip->vi_str[0],tp->tk_att[i].ta_name)==0) {
134                                                 smallstr[0] = i+1;
135                                                 smallstr[1] = 0;
136                                                 strcat(formstr,smallstr);
137                                                 break;
138                                         }
139                                 }
140                                 if (i==thistokensize)
141                                         error("%s not a known attribute",
142                                                 vip->vi_str[0]);
143                         }
144                 }
145                 tp->tk_format = strlookup(formstr);
146         } else
147                 tp->tk_format = -1;
148 }
149
150 checkprintformat(n) {
151         register short *s;
152         register i;
153         extern set_t l_sets[];
154         
155         s= l_sets[n].set_val;
156         for(i=nregs;i<nregs+ntokens;i++)
157                 if (BIT(s,i) && l_tokens[i-nregs]->tk_format<0)
158                         error("Token %s in set does not have printformat",
159                                 l_tokens[i-nregs]->tk_name);
160 }
161
162 n_prop(name,size) char *name; int size; {
163         int propno;
164         register symbol *sp;
165
166         propno = NEXT(nprops,MAXPROPS,"Properties");
167         sp = lookup(name,symprop,newsymbol);
168         sp->sy_value.syv_propno = propno;
169         if (size <= 0) {
170                 error("Size of property must be >0");
171                 size = wordsize;
172         }
173         l_props[propno].pr_size = size;
174 }
175
176 prophall(n) {
177         register i;
178         short hallset[SETSIZE];
179         
180         if (n < 0) return;
181         for(i=0;i<SETSIZE;i++)
182                 hallset[i] = i<SZOFSET(MAXREGS) ? l_props[n].pr_regset[i] : 0;
183         nexthall(hallset);
184 }
185
186 n_reg(name,printstring,nmemb,member1,member2) char *name,*printstring; {
187         register symbol *sy_p;
188         register reginfo *ri_p;
189         int regno;
190
191         sy_p = lookup(name,symreg,newsymbol);
192         sy_p->sy_value.syv_regno = regno = NEXT(nregs,MAXREGS,"Number of registers");
193         ri_p = &l_regs[regno];
194         ri_p->ri_name = mystrcpy(name);
195         ri_p->ri_repr = printstring!=0 ? mystrcpy(printstring) : ri_p->ri_name;
196         ri_p->ri_memb[0] = member1;
197         ri_p->ri_memb[1] = member2;
198         if (nmemb>maxmembers)
199                 maxmembers=nmemb;
200         return(regno);
201 }
202
203 make_const() {
204
205         wordsize = cmustbeset("EM_WSIZE");
206         pointersize = cmustbeset("EM_PSIZE");
207 }
208
209 cmustbeset(ident) char *ident; {
210
211         return(lookup(ident,symconst,mustexist)->sy_value.syv_cstval);
212 }
213
214 n_const(ident,val) char *ident; {
215         register symbol *sy_p;
216
217         sy_p = lookup(ident,symconst,newsymbol);
218         sy_p->sy_value.syv_cstval = val;
219 }
220
221 n_sconst(ident,val) char *ident,*val; {
222         register symbol *sy_p;
223
224         sy_p = lookup(ident,symsconst,newsymbol);
225         sy_p->sy_value.syv_stringno = strlookup(val);
226 }
227
228 regline(rl,pl,rv) varinfo *rl,*pl; {
229         register varinfo *rrl,*rpl;
230         register short *sp;
231         register reginfo *regp;
232         int thissize;
233         int propno;
234
235         for(rrl=rl;rrl!=0;rrl=rrl->vi_next) {
236                 regp = &l_regs[rrl->vi_int[0]];
237                 thissize = 0;
238                 for(rpl=pl;rpl!=0;rpl=rpl->vi_next) {
239                         propno = rpl->vi_int[0];
240                         sp= l_props[propno].pr_regset;
241                         BIS(sp,rrl->vi_int[0]);
242                         if (thissize==0)
243                                 thissize = l_props[propno].pr_size;
244                         else if (thissize!=-1 && thissize!=l_props[propno].pr_size)
245                                 error("Register %s has no clear size",
246                                         regp->ri_name);
247                 }
248                 regp->ri_size = thissize;
249                 regp->ri_class = regclass;
250                 regp->ri_rregvar = rv;
251                 if (rv>=0) {
252                         if (regp->ri_memb[0]!=0)
253                                 error("Register variables may not have subregisters");
254                         rvused |= ANY_REGVAR;
255                         if (regp->ri_size == wordsize)
256                                 rvused |= SL_REGVAR;
257                         else if (regp->ri_size == 2*wordsize)
258                                 rvused |= DL_REGVAR;
259                         if (nregvar[rv]==0)
260                                 rvsize[rv] = regp->ri_size;
261                         else if (rvsize[rv]!=regp->ri_size)
262                                 error("All register variables of one type must have the same size");
263                         NEXT(nregvar[rv],MAXREGVAR,"Register variable");
264                         rvnumbers[rv][nregvar[rv]-1] = rrl->vi_int[0];
265                 }
266         }
267         regclass++;
268 }
269
270 setallreg(vi) struct varinfo *vi; {
271
272         nallreg=0;
273         for(;vi!=0;vi=vi->vi_next) {
274                 if (vi->vi_int[0]<0)
275                         continue;
276                 allreg[nallreg++] = vi->vi_int[0];
277         }
278 }
279
280 freevi(vip) register struct varinfo *vip; {
281         register i;
282         extern char *end;
283
284         if (vip==0)
285                 return;
286         freevi(vip->vi_next);
287         freevi(vip->vi_vi);
288         for (i=0;i<VI_NSTR;i++)
289                 if (vip->vi_str[i]>end)
290                         free((char *) vip->vi_str[i]);
291         free(vip);
292 }
293
294 int myatoi(s) register char *s; {
295         register int base=10;
296         register sum=0;
297
298         if (*s=='0') {
299                 base = 8;
300                 s++;
301                 if (*s=='x') {
302                         base=16;
303                         s++;
304                 }
305         }
306         for (;;) {
307                 switch (*s) {
308                 default:        return(sum);
309                 case '8':
310                 case '9':
311                         if (base==8) error("Bad digit in octal number");
312                 case '0':
313                 case '1':
314                 case '2':
315                 case '3':
316                 case '4':
317                 case '5':
318                 case '6':
319                 case '7':
320                         sum = sum*base + *s++ - '0';
321                         break;
322                 case 'a':
323                 case 'b':
324                 case 'c':
325                 case 'd':
326                 case 'e':
327                 case 'f':
328                         if (base!=16) error("Hexletter in number not expected");
329                         sum = sum*base + 10 + *s++ - 'a';
330                         break;
331                 case 'A':
332                 case 'B':
333                 case 'C':
334                 case 'D':
335                 case 'E':
336                 case 'F':
337                         if (base!=16) error("Hexletter in number not expected");
338                         sum = sum*base + 10 + *s++ - 'A';
339                         break;
340                 }
341         }
342 }
343
344 char *mystrcpy(s) char *s; {
345         register char *p;
346         char *myalloc();
347
348         p=myalloc(strlen(s)+1);
349         strcpy(p,s);
350         return(p);
351 }
352
353 char *myalloc(n) register n; {
354         register char *p,*result;
355         char *malloc();
356
357         result=p=malloc(n);
358         if (p== (char *) 0)
359                 fatal("Out of memory");
360         do *p++=0; while (--n);
361         return(result);
362 }
363
364 chkincl(value,lwb,upb) {
365
366         if (value<lwb || value>upb)
367                 error("Number %d should have been between %d and %d",
368                         value,lwb,upb);
369         return(value);
370 }
371
372 subset(sp1,sp2,setsize) short *sp1,*sp2; {
373         register i;
374
375         for(i=0;i<setsize;i++)
376                 if ( (sp1[i] | sp2[i]) != sp2[i])
377                         return(0);
378         return(1);
379 }
380
381 vilength(vip) register struct varinfo *vip; {
382         register l=0;
383
384         while(vip!=0) {
385                 vip=vip->vi_next;
386                 l++;
387         }
388         return(l);
389 }