Pristine Ack-5.5
[Ack-5.5.git] / util / ncgg / instruct.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: instruct.c,v 0.5 1994/06/24 10:37:26 ceriel Exp $";
7 #endif
8
9 #include "param.h"
10 #include "instruct.h"
11 #include "pseudo.h"
12 #include "varinfo.h"
13 #include "set.h"
14 #include "expr.h"
15 #include "iocc.h"
16 #include <cgg_cg.h>
17 #include "extern.h"
18
19 extern int niops;
20 extern iocc_t iops[];
21 extern inproc;
22
23 extern set_t l_sets[];
24 extern inst_t l_instances[];
25
26 extern expr_t subreg_expr(),regno_expr();
27
28 struct varinfo * setcoco(n) {
29         struct varinfo *vi;
30         
31         NEW(vi,struct varinfo);
32         vi->vi_next = VI_NULL;
33         vi->vi_int[0] = INSSETCC;
34         vi->vi_int[1] = n;
35         return(vi);
36 }
37
38 struct varinfo * generase(n) {
39         struct varinfo *vi;
40
41         NEW(vi,struct varinfo);
42         vi->vi_next = VI_NULL;
43         vi->vi_int[0] = INSERASE;
44         vi->vi_int[1] = n;
45         return(vi);
46 }
47
48 struct varinfo * genremove(n) {
49         struct varinfo *vi;
50
51         NEW(vi,struct varinfo);
52         vi->vi_next = VI_NULL;
53         vi->vi_int[0] = INSREMOVE;
54         vi->vi_int[1] = n;
55         return(vi);
56 }
57
58 onlyreg(argno) {
59         register bitno;
60         register short *sp;
61         
62         if (! argno) argno++;
63         sp = l_sets[tokpatset[argno-1]].set_val;
64         for(bitno=nregs;bitno<nregs+ntokens;bitno++)
65                 if (BIT(sp,bitno))
66                         return(0);
67         return(1);
68 }
69
70 makescratch(argno) {
71         set_t s;
72
73         if (! argno) argno++;
74         if (tokpatro[argno-1])
75                 error("Instruction destroys %%%d, not allowed here",argno);
76         s = l_sets[tokpatset[argno-1]];
77         BIC(s.set_val,0);
78         tokpatset[argno-1] = setlookup(s);
79 }
80
81 struct varinfo *gen_inst(ident,star) char *ident; {
82         register struct varinfo *vi,*retval,*eravi;
83         register instr_p ip;
84         register struct operand *op;
85         register i;
86         register inst_p insta;
87         
88         if (star && !inproc)
89                 error("Variable instruction only allowed inside proc");
90         for (ip=l_instr;ip<l_instr+ninstr;ip++) {
91                 if(strcmp(ident,ip->i_name))
92                         continue;
93                 if (ip->i_nops!=niops)
94                         continue;
95                 for(i=0,op=ip->i_oplist;i<niops;i++,op=op->o_next) {
96                         if (!subset(iops[i].in_set,l_sets[op->o_setno].set_val,SETSIZE))
97                                 goto cont;
98                 }
99                 goto found;             /* oh well, one more won't hurt */
100             cont:;
101         }
102         error("Such an \"%s\" does not exist",ident);
103         return(0);
104 found:
105         NEW(vi,struct varinfo);
106         vi->vi_int[0] = ip-l_instr;
107         vi->vi_int[1] = star;
108         vi->vi_next=0;
109         retval = vi;
110         for(i=0;i<niops;i++) {
111                 NEW(vi->vi_vi,struct varinfo);
112                 vi=vi->vi_vi;
113                 vi->vi_int[0] = iops[i].in_index;
114         }
115         vi->vi_vi = 0;
116         vi = retval;
117         for(i=0,op=ip->i_oplist;i<niops;i++,op=op->o_next) {
118             if(op->o_adorn&AD_CC) {
119                 vi->vi_next = setcoco(iops[i].in_index);
120                 vi=vi->vi_next;
121             }
122             switch(op->o_adorn&AD_RWMASK) {
123             default:
124                 /* Nothing possible to do */
125                 break;
126             case AD_RO:
127                 /* It might be possible to do something
128                  * here but not now.
129                  */
130                 break;
131             case AD_RW:
132             case AD_WO:
133                 /* Treated the same for now */
134                 insta = &l_instances[iops[i].in_index];
135                 switch(insta->in_which) {
136                 case IN_COPY:
137                         if(insta->in_info[1]==0 && !onlyreg(insta->in_info[0]))
138                                 break;
139                         makescratch(insta->in_info[0]);
140                         vi->vi_next = generase(
141                                        ex_lookup(
142                                         EX_SUBREG,insta->in_info[0],
143                                                   insta->in_info[1]
144                                        )
145                                       );
146                         vi = vi->vi_next;
147                         break;
148                 case IN_MEMB:
149                         vi->vi_next = generase(
150                                        ex_lookup(
151                                         EX_TOKFIELD,insta->in_info[0],
152                                                     insta->in_info[1]
153                                        )
154                                       );
155                         vi=vi->vi_next;
156                         break;
157                 case IN_RIDENT:
158                         vi->vi_next = generase(
159                                        ex_lookup(
160                                         EX_REG,insta->in_info[0],0
161                                        )
162                                       );
163                         vi = vi->vi_next;
164                         break;
165                 case IN_ALLOC:
166                         vi->vi_next = generase(
167                                        ex_lookup(
168                                         EX_ALLREG,insta->in_info[0]+1,
169                                                   insta->in_info[1]
170                                        )
171                                       );
172                         vi = vi->vi_next;
173                         break;
174                 case IN_S_DESCR:
175                 case IN_D_DESCR:
176                         { int temp;
177
178                         temp=ex_lookup(EX_REGVAR,insta->in_info[1],0);
179                         vi->vi_next = generase(temp);
180                         vi = vi->vi_next;
181                         vi->vi_next = genremove(temp);
182                         vi = vi->vi_next;
183                         break;
184                         }
185                 }
186                 break;
187             }
188         }
189         for (eravi=ip->i_erases;eravi != VI_NULL;eravi=eravi->vi_next) {
190                 if (eravi->vi_int[0] < 0)
191                         vi->vi_next = setcoco(0);
192                 else {
193                         vi->vi_next = generase(eravi->vi_int[0]);
194                         vi=vi->vi_next;
195                         vi->vi_next = genremove(eravi->vi_int[0]);
196                 }
197                 vi=vi->vi_next;
198         }
199         return(retval);
200 }