]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/acid.c
merge
[plan9front.git] / sys / src / cmd / cc / acid.c
1 #include "cc.h"
2
3 static char *kwd[] =
4 {
5         "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn",
6         "$delete", "$do", "$else", "$eval", "$head", "$if",
7         "$local", "$loop", "$return", "$tail", "$then",
8         "$union", "$whatis", "$while",
9 };
10
11 char*
12 amap(char *s)
13 {
14         int i, bot, top, new;
15
16         bot = 0;
17         top = bot + nelem(kwd) - 1;
18         while(bot <= top){
19                 new = bot + (top - bot)/2;
20                 i = strcmp(kwd[new]+1, s);
21                 if(i == 0)
22                         return kwd[new];
23
24                 if(i < 0)
25                         bot = new + 1;
26                 else
27                         top = new - 1;
28         }
29         return s;
30 }
31
32 Sym*
33 acidsue(Type *t)
34 {
35         int h;
36         Sym *s;
37
38         if(t != T)
39         for(h=0; h<nelem(hash); h++)
40                 for(s = hash[h]; s != S; s = s->link)
41                         if(s->suetag && s->suetag->link == t)
42                                 return s;
43         return 0;
44 }
45
46 Sym*
47 acidfun(Type *t)
48 {
49         int h;
50         Sym *s;
51
52         for(h=0; h<nelem(hash); h++)
53                 for(s = hash[h]; s != S; s = s->link)
54                         if(s->type == t)
55                                 return s;
56         return 0;
57 }
58
59 char    acidchar[NTYPE];
60 Init    acidcinit[] =
61 {
62         TCHAR,          'C',    0,
63         TUCHAR,         'b',    0,
64         TSHORT,         'd',    0,
65         TUSHORT,        'u',    0,
66         TLONG,          'D',    0,
67         TULONG,         'U',    0,
68         TVLONG,         'V',    0,
69         TUVLONG,        'W',    0,
70         TFLOAT,         'f',    0,
71         TDOUBLE,        'F',    0,
72         TARRAY,         'a',    0,
73         TIND,           'X',    0,
74         -1,             0,      0,
75 };
76
77 static void
78 acidinit(void)
79 {
80         Init *p;
81
82         for(p=acidcinit; p->code >= 0; p++)
83                 acidchar[p->code] = p->value;
84
85         acidchar[TINT] = acidchar[TLONG];
86         acidchar[TUINT] = acidchar[TULONG];
87         if(types[TINT]->width != types[TLONG]->width) {
88                 acidchar[TINT] = acidchar[TSHORT];
89                 acidchar[TUINT] = acidchar[TUSHORT];
90                 if(types[TINT]->width != types[TSHORT]->width)
91                         warn(Z, "acidmember int not long or short");
92         }
93         
94 }
95
96 void
97 acidmember(Type *t, long off, int flag)
98 {
99         Sym *s, *s1;
100         Type *l;
101         static int acidcharinit = 0;
102
103         if(acidcharinit == 0) {
104                 acidinit();
105                 acidcharinit = 1;
106         }
107         s = t->sym;
108         switch(t->etype) {
109         default:
110                 Bprint(&outbuf, "       T%d\n", t->etype);
111                 break;
112
113         case TIND:
114                 if(s == S)
115                         break;
116                 if(flag) {
117                         for(l=t; l->etype==TIND; l=l->link)
118                                 ;
119                         if(typesu[l->etype]) {
120                                 s1 = acidsue(l->link);
121                                 if(s1 != S) {
122                                         Bprint(&outbuf, "       'A' %s %ld %s;\n",
123                                                 amap(s1->name),
124                                                 t->offset+off, amap(s->name));
125                                         break;
126                                 }
127                         }
128                 } else {
129                         Bprint(&outbuf,
130                                 "\tprint(\"\t%s\t\", addr.%s\\X, \"\\n\");\n",
131                                 amap(s->name), amap(s->name));
132                         break;
133                 }
134
135         case TINT:
136         case TUINT:
137         case TCHAR:
138         case TUCHAR:
139         case TSHORT:
140         case TUSHORT:
141         case TLONG:
142         case TULONG:
143         case TVLONG:
144         case TUVLONG:
145         case TFLOAT:
146         case TDOUBLE:
147         case TARRAY:
148                 if(s == S)
149                         break;
150                 if(flag) {
151                         Bprint(&outbuf, "       '%c' %ld %s;\n",
152                         acidchar[t->etype], t->offset+off, amap(s->name));
153                 } else {
154                         Bprint(&outbuf, "\tprint(\"\t%s\t\", addr.%s, \"\\n\");\n",
155                                 amap(s->name), amap(s->name));
156                 }
157                 break;
158
159         case TSTRUCT:
160         case TUNION:
161                 s1 = acidsue(t->link);
162                 if(s1 == S)
163                         break;
164                 if(flag) {
165                         if(s == S) {
166                                 Bprint(&outbuf, "       {\n");
167                                 for(l = t->link; l != T; l = l->down)
168                                         acidmember(l, t->offset+off, flag);
169                                 Bprint(&outbuf, "       };\n");
170                         } else {
171                                 Bprint(&outbuf, "       %s %ld %s;\n",
172                                         amap(s1->name),
173                                         t->offset+off, amap(s->name));
174                         }
175                 } else {
176                         if(s != S) {
177                                 Bprint(&outbuf, "\tprint(\"%s %s {\\n\");\n",
178                                         amap(s1->name), amap(s->name));
179                                 Bprint(&outbuf, "\t%s(addr.%s);\n",
180                                         amap(s1->name), amap(s->name));
181                                 Bprint(&outbuf, "\tprint(\"}\\n\");\n");
182                         } else {
183                                 Bprint(&outbuf, "\tprint(\"%s {\\n\");\n",
184                                         amap(s1->name));
185                                 Bprint(&outbuf, "\t\t%s(addr+%ld);\n",
186                                         amap(s1->name), t->offset+off);
187                                 Bprint(&outbuf, "\tprint(\"}\\n\");\n");
188                         }
189                 }
190                 break;
191         }
192 }
193
194 void
195 acidtype(Type *t)
196 {
197         Sym *s;
198         Type *l;
199         Io *i;
200         int n;
201         char *an;
202
203         if(!debug['a'])
204                 return;
205         if(debug['a'] > 1) {
206                 n = 0;
207                 for(i=iostack; i; i=i->link)
208                         n++;
209                 if(n > 1)
210                         return;
211         }
212         s = acidsue(t->link);
213         if(s == S)
214                 return;
215         switch(t->etype) {
216         default:
217                 Bprint(&outbuf, "T%d\n", t->etype);
218                 return;
219
220         case TUNION:
221         case TSTRUCT:
222                 if(debug['s'])
223                         goto asmstr;
224                 an = amap(s->name);
225                 Bprint(&outbuf, "sizeof%s = %ld;\n", an, t->width);
226                 Bprint(&outbuf, "aggr %s\n{\n", an);
227                 for(l = t->link; l != T; l = l->down)
228                         acidmember(l, 0, 1);
229                 Bprint(&outbuf, "};\n\n");
230
231                 Bprint(&outbuf, "defn\n%s(addr) {\n\tcomplex %s addr;\n", an, an);
232                 for(l = t->link; l != T; l = l->down)
233                         acidmember(l, 0, 0);
234                 Bprint(&outbuf, "};\n\n");
235                 break;
236         asmstr:
237                 if(s == S)
238                         break;
239                 for(l = t->link; l != T; l = l->down)
240                         if(l->sym != S)
241                                 Bprint(&outbuf, "#define\t%s.%s\t%ld\n",
242                                         s->name,
243                                         l->sym->name,
244                                         l->offset);
245                 break;
246         }
247 }
248
249 void
250 acidvar(Sym *s)
251 {
252         int n;
253         Io *i;
254         Type *t;
255         Sym *s1, *s2;
256
257         if(!debug['a'] || debug['s'])
258                 return;
259         if(debug['a'] > 1) {
260                 n = 0;
261                 for(i=iostack; i; i=i->link)
262                         n++;
263                 if(n > 1)
264                         return;
265         }
266         t = s->type;
267         while(t && t->etype == TIND)
268                 t = t->link;
269         if(t == T)
270                 return;
271         if(t->etype == TENUM) {
272                 Bprint(&outbuf, "%s = ", amap(s->name));
273                 if(!typefd[t->etype])
274                         Bprint(&outbuf, "%lld;\n", s->vconst);
275                 else
276                         Bprint(&outbuf, "%f\n;", s->fconst);
277                 return;
278         }
279         if(!typesu[t->etype])
280                 return;
281         s1 = acidsue(t->link);
282         if(s1 == S)
283                 return;
284         switch(s->class) {
285         case CAUTO:
286         case CPARAM:
287                 s2 = acidfun(thisfn);
288                 if(s2)
289                         Bprint(&outbuf, "complex %s %s:%s;\n",
290                                 amap(s1->name), amap(s2->name), amap(s->name));
291                 break;
292         
293         case CSTATIC:
294         case CEXTERN:
295         case CGLOBL:
296         case CLOCAL:
297                 Bprint(&outbuf, "complex %s %s;\n",
298                         amap(s1->name), amap(s->name));
299                 break;
300         }
301 }