1219b2ee8SDavid du Colombier #include "cc.h"
2219b2ee8SDavid du Colombier
3219b2ee8SDavid du Colombier static char *kwd[] =
4219b2ee8SDavid du Colombier {
5e464c1a8SDavid du Colombier "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn",
6219b2ee8SDavid du Colombier "$delete", "$do", "$else", "$eval", "$head", "$if",
7219b2ee8SDavid du Colombier "$local", "$loop", "$return", "$tail", "$then",
8219b2ee8SDavid du Colombier "$union", "$whatis", "$while",
9219b2ee8SDavid du Colombier };
10219b2ee8SDavid du Colombier
11219b2ee8SDavid du Colombier char*
amap(char * s)12219b2ee8SDavid du Colombier amap(char *s)
13219b2ee8SDavid du Colombier {
14219b2ee8SDavid du Colombier int i, bot, top, new;
15219b2ee8SDavid du Colombier
16219b2ee8SDavid du Colombier bot = 0;
17219b2ee8SDavid du Colombier top = bot + nelem(kwd) - 1;
18219b2ee8SDavid du Colombier while(bot <= top){
19219b2ee8SDavid du Colombier new = bot + (top - bot)/2;
20219b2ee8SDavid du Colombier i = strcmp(kwd[new]+1, s);
21219b2ee8SDavid du Colombier if(i == 0)
22219b2ee8SDavid du Colombier return kwd[new];
23219b2ee8SDavid du Colombier
24219b2ee8SDavid du Colombier if(i < 0)
25219b2ee8SDavid du Colombier bot = new + 1;
26219b2ee8SDavid du Colombier else
27219b2ee8SDavid du Colombier top = new - 1;
28219b2ee8SDavid du Colombier }
29219b2ee8SDavid du Colombier return s;
30219b2ee8SDavid du Colombier }
31219b2ee8SDavid du Colombier
32219b2ee8SDavid du Colombier Sym*
acidsue(Type * t)33219b2ee8SDavid du Colombier acidsue(Type *t)
34219b2ee8SDavid du Colombier {
35219b2ee8SDavid du Colombier int h;
36219b2ee8SDavid du Colombier Sym *s;
37219b2ee8SDavid du Colombier
38219b2ee8SDavid du Colombier if(t != T)
39219b2ee8SDavid du Colombier for(h=0; h<nelem(hash); h++)
40219b2ee8SDavid du Colombier for(s = hash[h]; s != S; s = s->link)
41219b2ee8SDavid du Colombier if(s->suetag && s->suetag->link == t)
42219b2ee8SDavid du Colombier return s;
43219b2ee8SDavid du Colombier return 0;
44219b2ee8SDavid du Colombier }
45219b2ee8SDavid du Colombier
46219b2ee8SDavid du Colombier Sym*
acidfun(Type * t)47219b2ee8SDavid du Colombier acidfun(Type *t)
48219b2ee8SDavid du Colombier {
49219b2ee8SDavid du Colombier int h;
50219b2ee8SDavid du Colombier Sym *s;
51219b2ee8SDavid du Colombier
52219b2ee8SDavid du Colombier for(h=0; h<nelem(hash); h++)
53219b2ee8SDavid du Colombier for(s = hash[h]; s != S; s = s->link)
54219b2ee8SDavid du Colombier if(s->type == t)
55219b2ee8SDavid du Colombier return s;
56219b2ee8SDavid du Colombier return 0;
57219b2ee8SDavid du Colombier }
58219b2ee8SDavid du Colombier
597dd7cddfSDavid du Colombier char acidchar[NTYPE];
607dd7cddfSDavid du Colombier Init acidcinit[] =
61219b2ee8SDavid du Colombier {
627dd7cddfSDavid du Colombier TCHAR, 'C', 0,
637dd7cddfSDavid du Colombier TUCHAR, 'b', 0,
647dd7cddfSDavid du Colombier TSHORT, 'd', 0,
657dd7cddfSDavid du Colombier TUSHORT, 'u', 0,
667dd7cddfSDavid du Colombier TLONG, 'D', 0,
677dd7cddfSDavid du Colombier TULONG, 'U', 0,
687dd7cddfSDavid du Colombier TVLONG, 'V', 0,
697dd7cddfSDavid du Colombier TUVLONG, 'W', 0,
707dd7cddfSDavid du Colombier TFLOAT, 'f', 0,
717dd7cddfSDavid du Colombier TDOUBLE, 'F', 0,
727dd7cddfSDavid du Colombier TARRAY, 'a', 0,
737dd7cddfSDavid du Colombier TIND, 'X', 0,
747dd7cddfSDavid du Colombier -1, 0, 0,
75219b2ee8SDavid du Colombier };
76219b2ee8SDavid du Colombier
777dd7cddfSDavid du Colombier static void
acidinit(void)787dd7cddfSDavid du Colombier acidinit(void)
797dd7cddfSDavid du Colombier {
807dd7cddfSDavid du Colombier Init *p;
817dd7cddfSDavid du Colombier
827dd7cddfSDavid du Colombier for(p=acidcinit; p->code >= 0; p++)
837dd7cddfSDavid du Colombier acidchar[p->code] = p->value;
847dd7cddfSDavid du Colombier
857dd7cddfSDavid du Colombier acidchar[TINT] = acidchar[TLONG];
867dd7cddfSDavid du Colombier acidchar[TUINT] = acidchar[TULONG];
877dd7cddfSDavid du Colombier if(types[TINT]->width != types[TLONG]->width) {
887dd7cddfSDavid du Colombier acidchar[TINT] = acidchar[TSHORT];
897dd7cddfSDavid du Colombier acidchar[TUINT] = acidchar[TUSHORT];
907dd7cddfSDavid du Colombier if(types[TINT]->width != types[TSHORT]->width)
917dd7cddfSDavid du Colombier warn(Z, "acidmember int not long or short");
927dd7cddfSDavid du Colombier }
93*d40255d8SDavid du Colombier if(types[TIND]->width == types[TUVLONG]->width)
94*d40255d8SDavid du Colombier acidchar[TIND] = 'Y';
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier }
977dd7cddfSDavid du Colombier
98219b2ee8SDavid du Colombier void
acidmember(Type * t,long off,int flag)99219b2ee8SDavid du Colombier acidmember(Type *t, long off, int flag)
100219b2ee8SDavid du Colombier {
101219b2ee8SDavid du Colombier Sym *s, *s1;
102219b2ee8SDavid du Colombier Type *l;
1037dd7cddfSDavid du Colombier static int acidcharinit = 0;
104219b2ee8SDavid du Colombier
1057dd7cddfSDavid du Colombier if(acidcharinit == 0) {
1067dd7cddfSDavid du Colombier acidinit();
1077dd7cddfSDavid du Colombier acidcharinit = 1;
1087dd7cddfSDavid du Colombier }
109219b2ee8SDavid du Colombier s = t->sym;
110219b2ee8SDavid du Colombier switch(t->etype) {
111219b2ee8SDavid du Colombier default:
112219b2ee8SDavid du Colombier Bprint(&outbuf, " T%d\n", t->etype);
113219b2ee8SDavid du Colombier break;
114219b2ee8SDavid du Colombier
115219b2ee8SDavid du Colombier case TIND:
116219b2ee8SDavid du Colombier if(s == S)
117219b2ee8SDavid du Colombier break;
118219b2ee8SDavid du Colombier if(flag) {
119219b2ee8SDavid du Colombier for(l=t; l->etype==TIND; l=l->link)
120219b2ee8SDavid du Colombier ;
121219b2ee8SDavid du Colombier if(typesu[l->etype]) {
122219b2ee8SDavid du Colombier s1 = acidsue(l->link);
123219b2ee8SDavid du Colombier if(s1 != S) {
124219b2ee8SDavid du Colombier Bprint(&outbuf, " 'A' %s %ld %s;\n",
125219b2ee8SDavid du Colombier amap(s1->name),
126219b2ee8SDavid du Colombier t->offset+off, amap(s->name));
127219b2ee8SDavid du Colombier break;
128219b2ee8SDavid du Colombier }
129219b2ee8SDavid du Colombier }
130219b2ee8SDavid du Colombier } else {
1317dd7cddfSDavid du Colombier Bprint(&outbuf,
1327dd7cddfSDavid du Colombier "\tprint(\"\t%s\t\", addr.%s\\X, \"\\n\");\n",
133219b2ee8SDavid du Colombier amap(s->name), amap(s->name));
134219b2ee8SDavid du Colombier break;
135219b2ee8SDavid du Colombier }
136219b2ee8SDavid du Colombier
1377dd7cddfSDavid du Colombier case TINT:
1387dd7cddfSDavid du Colombier case TUINT:
139219b2ee8SDavid du Colombier case TCHAR:
140219b2ee8SDavid du Colombier case TUCHAR:
141219b2ee8SDavid du Colombier case TSHORT:
142219b2ee8SDavid du Colombier case TUSHORT:
143219b2ee8SDavid du Colombier case TLONG:
144219b2ee8SDavid du Colombier case TULONG:
145219b2ee8SDavid du Colombier case TVLONG:
146219b2ee8SDavid du Colombier case TUVLONG:
147219b2ee8SDavid du Colombier case TFLOAT:
148219b2ee8SDavid du Colombier case TDOUBLE:
149219b2ee8SDavid du Colombier case TARRAY:
150219b2ee8SDavid du Colombier if(s == S)
151219b2ee8SDavid du Colombier break;
152219b2ee8SDavid du Colombier if(flag) {
153219b2ee8SDavid du Colombier Bprint(&outbuf, " '%c' %ld %s;\n",
154219b2ee8SDavid du Colombier acidchar[t->etype], t->offset+off, amap(s->name));
155219b2ee8SDavid du Colombier } else {
156219b2ee8SDavid du Colombier Bprint(&outbuf, "\tprint(\"\t%s\t\", addr.%s, \"\\n\");\n",
157219b2ee8SDavid du Colombier amap(s->name), amap(s->name));
158219b2ee8SDavid du Colombier }
159219b2ee8SDavid du Colombier break;
160219b2ee8SDavid du Colombier
161219b2ee8SDavid du Colombier case TSTRUCT:
162219b2ee8SDavid du Colombier case TUNION:
163219b2ee8SDavid du Colombier s1 = acidsue(t->link);
164219b2ee8SDavid du Colombier if(s1 == S)
165219b2ee8SDavid du Colombier break;
166219b2ee8SDavid du Colombier if(flag) {
167219b2ee8SDavid du Colombier if(s == S) {
168219b2ee8SDavid du Colombier Bprint(&outbuf, " {\n");
169219b2ee8SDavid du Colombier for(l = t->link; l != T; l = l->down)
170219b2ee8SDavid du Colombier acidmember(l, t->offset+off, flag);
171219b2ee8SDavid du Colombier Bprint(&outbuf, " };\n");
172219b2ee8SDavid du Colombier } else {
173219b2ee8SDavid du Colombier Bprint(&outbuf, " %s %ld %s;\n",
174219b2ee8SDavid du Colombier amap(s1->name),
175219b2ee8SDavid du Colombier t->offset+off, amap(s->name));
176219b2ee8SDavid du Colombier }
177219b2ee8SDavid du Colombier } else {
178219b2ee8SDavid du Colombier if(s != S) {
179219b2ee8SDavid du Colombier Bprint(&outbuf, "\tprint(\"%s %s {\\n\");\n",
180219b2ee8SDavid du Colombier amap(s1->name), amap(s->name));
181219b2ee8SDavid du Colombier Bprint(&outbuf, "\t%s(addr.%s);\n",
182219b2ee8SDavid du Colombier amap(s1->name), amap(s->name));
183219b2ee8SDavid du Colombier Bprint(&outbuf, "\tprint(\"}\\n\");\n");
184219b2ee8SDavid du Colombier } else {
185219b2ee8SDavid du Colombier Bprint(&outbuf, "\tprint(\"%s {\\n\");\n",
186219b2ee8SDavid du Colombier amap(s1->name));
1877dd7cddfSDavid du Colombier Bprint(&outbuf, "\t\t%s(addr+%ld);\n",
188219b2ee8SDavid du Colombier amap(s1->name), t->offset+off);
189219b2ee8SDavid du Colombier Bprint(&outbuf, "\tprint(\"}\\n\");\n");
190219b2ee8SDavid du Colombier }
191219b2ee8SDavid du Colombier }
192219b2ee8SDavid du Colombier break;
193219b2ee8SDavid du Colombier }
194219b2ee8SDavid du Colombier }
195219b2ee8SDavid du Colombier
196219b2ee8SDavid du Colombier void
acidtype(Type * t)197219b2ee8SDavid du Colombier acidtype(Type *t)
198219b2ee8SDavid du Colombier {
199219b2ee8SDavid du Colombier Sym *s;
200219b2ee8SDavid du Colombier Type *l;
201219b2ee8SDavid du Colombier Io *i;
202219b2ee8SDavid du Colombier int n;
203219b2ee8SDavid du Colombier char *an;
204219b2ee8SDavid du Colombier
205219b2ee8SDavid du Colombier if(!debug['a'])
206219b2ee8SDavid du Colombier return;
207219b2ee8SDavid du Colombier if(debug['a'] > 1) {
208219b2ee8SDavid du Colombier n = 0;
209219b2ee8SDavid du Colombier for(i=iostack; i; i=i->link)
210219b2ee8SDavid du Colombier n++;
211219b2ee8SDavid du Colombier if(n > 1)
212219b2ee8SDavid du Colombier return;
213219b2ee8SDavid du Colombier }
214219b2ee8SDavid du Colombier s = acidsue(t->link);
215219b2ee8SDavid du Colombier if(s == S)
216219b2ee8SDavid du Colombier return;
217219b2ee8SDavid du Colombier switch(t->etype) {
218219b2ee8SDavid du Colombier default:
219219b2ee8SDavid du Colombier Bprint(&outbuf, "T%d\n", t->etype);
220219b2ee8SDavid du Colombier return;
221219b2ee8SDavid du Colombier
222219b2ee8SDavid du Colombier case TUNION:
223219b2ee8SDavid du Colombier case TSTRUCT:
224219b2ee8SDavid du Colombier if(debug['s'])
225219b2ee8SDavid du Colombier goto asmstr;
226219b2ee8SDavid du Colombier an = amap(s->name);
2277dd7cddfSDavid du Colombier Bprint(&outbuf, "sizeof%s = %ld;\n", an, t->width);
228219b2ee8SDavid du Colombier Bprint(&outbuf, "aggr %s\n{\n", an);
229219b2ee8SDavid du Colombier for(l = t->link; l != T; l = l->down)
230219b2ee8SDavid du Colombier acidmember(l, 0, 1);
231219b2ee8SDavid du Colombier Bprint(&outbuf, "};\n\n");
232219b2ee8SDavid du Colombier
233219b2ee8SDavid du Colombier Bprint(&outbuf, "defn\n%s(addr) {\n\tcomplex %s addr;\n", an, an);
234219b2ee8SDavid du Colombier for(l = t->link; l != T; l = l->down)
235219b2ee8SDavid du Colombier acidmember(l, 0, 0);
236219b2ee8SDavid du Colombier Bprint(&outbuf, "};\n\n");
237219b2ee8SDavid du Colombier break;
238219b2ee8SDavid du Colombier asmstr:
239219b2ee8SDavid du Colombier if(s == S)
240219b2ee8SDavid du Colombier break;
241219b2ee8SDavid du Colombier for(l = t->link; l != T; l = l->down)
242219b2ee8SDavid du Colombier if(l->sym != S)
243219b2ee8SDavid du Colombier Bprint(&outbuf, "#define\t%s.%s\t%ld\n",
244219b2ee8SDavid du Colombier s->name,
245219b2ee8SDavid du Colombier l->sym->name,
246219b2ee8SDavid du Colombier l->offset);
247219b2ee8SDavid du Colombier break;
248219b2ee8SDavid du Colombier }
249219b2ee8SDavid du Colombier }
250219b2ee8SDavid du Colombier
251219b2ee8SDavid du Colombier void
acidvar(Sym * s)252219b2ee8SDavid du Colombier acidvar(Sym *s)
253219b2ee8SDavid du Colombier {
254219b2ee8SDavid du Colombier int n;
255219b2ee8SDavid du Colombier Io *i;
256219b2ee8SDavid du Colombier Type *t;
257219b2ee8SDavid du Colombier Sym *s1, *s2;
258219b2ee8SDavid du Colombier
259219b2ee8SDavid du Colombier if(!debug['a'] || debug['s'])
260219b2ee8SDavid du Colombier return;
261219b2ee8SDavid du Colombier if(debug['a'] > 1) {
262219b2ee8SDavid du Colombier n = 0;
263219b2ee8SDavid du Colombier for(i=iostack; i; i=i->link)
264219b2ee8SDavid du Colombier n++;
265219b2ee8SDavid du Colombier if(n > 1)
266219b2ee8SDavid du Colombier return;
267219b2ee8SDavid du Colombier }
268219b2ee8SDavid du Colombier t = s->type;
269219b2ee8SDavid du Colombier while(t && t->etype == TIND)
270219b2ee8SDavid du Colombier t = t->link;
271219b2ee8SDavid du Colombier if(t == T)
272219b2ee8SDavid du Colombier return;
2737dd7cddfSDavid du Colombier if(t->etype == TENUM) {
2747dd7cddfSDavid du Colombier Bprint(&outbuf, "%s = ", amap(s->name));
2757dd7cddfSDavid du Colombier if(!typefd[t->etype])
2767dd7cddfSDavid du Colombier Bprint(&outbuf, "%lld;\n", s->vconst);
2777dd7cddfSDavid du Colombier else
2787dd7cddfSDavid du Colombier Bprint(&outbuf, "%f\n;", s->fconst);
2797dd7cddfSDavid du Colombier return;
2807dd7cddfSDavid du Colombier }
281219b2ee8SDavid du Colombier if(!typesu[t->etype])
282219b2ee8SDavid du Colombier return;
283219b2ee8SDavid du Colombier s1 = acidsue(t->link);
284219b2ee8SDavid du Colombier if(s1 == S)
285219b2ee8SDavid du Colombier return;
286219b2ee8SDavid du Colombier switch(s->class) {
287219b2ee8SDavid du Colombier case CAUTO:
288219b2ee8SDavid du Colombier case CPARAM:
289219b2ee8SDavid du Colombier s2 = acidfun(thisfn);
290219b2ee8SDavid du Colombier if(s2)
291219b2ee8SDavid du Colombier Bprint(&outbuf, "complex %s %s:%s;\n",
292219b2ee8SDavid du Colombier amap(s1->name), amap(s2->name), amap(s->name));
293219b2ee8SDavid du Colombier break;
294219b2ee8SDavid du Colombier
295219b2ee8SDavid du Colombier case CSTATIC:
296219b2ee8SDavid du Colombier case CEXTERN:
297219b2ee8SDavid du Colombier case CGLOBL:
298219b2ee8SDavid du Colombier case CLOCAL:
299219b2ee8SDavid du Colombier Bprint(&outbuf, "complex %s %s;\n",
300219b2ee8SDavid du Colombier amap(s1->name), amap(s->name));
301219b2ee8SDavid du Colombier break;
302219b2ee8SDavid du Colombier }
303219b2ee8SDavid du Colombier }
304