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*
amap(char * s)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*
acidsue(Type * t)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*
acidfun(Type * t)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
acidinit(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 if(types[TIND]->width == types[TUVLONG]->width)
94 acidchar[TIND] = 'Y';
95
96 }
97
98 void
acidmember(Type * t,long off,int flag)99 acidmember(Type *t, long off, int flag)
100 {
101 Sym *s, *s1;
102 Type *l;
103 static int acidcharinit = 0;
104
105 if(acidcharinit == 0) {
106 acidinit();
107 acidcharinit = 1;
108 }
109 s = t->sym;
110 switch(t->etype) {
111 default:
112 Bprint(&outbuf, " T%d\n", t->etype);
113 break;
114
115 case TIND:
116 if(s == S)
117 break;
118 if(flag) {
119 for(l=t; l->etype==TIND; l=l->link)
120 ;
121 if(typesu[l->etype]) {
122 s1 = acidsue(l->link);
123 if(s1 != S) {
124 Bprint(&outbuf, " 'A' %s %ld %s;\n",
125 amap(s1->name),
126 t->offset+off, amap(s->name));
127 break;
128 }
129 }
130 } else {
131 Bprint(&outbuf,
132 "\tprint(\"\t%s\t\", addr.%s\\X, \"\\n\");\n",
133 amap(s->name), amap(s->name));
134 break;
135 }
136
137 case TINT:
138 case TUINT:
139 case TCHAR:
140 case TUCHAR:
141 case TSHORT:
142 case TUSHORT:
143 case TLONG:
144 case TULONG:
145 case TVLONG:
146 case TUVLONG:
147 case TFLOAT:
148 case TDOUBLE:
149 case TARRAY:
150 if(s == S)
151 break;
152 if(flag) {
153 Bprint(&outbuf, " '%c' %ld %s;\n",
154 acidchar[t->etype], t->offset+off, amap(s->name));
155 } else {
156 Bprint(&outbuf, "\tprint(\"\t%s\t\", addr.%s, \"\\n\");\n",
157 amap(s->name), amap(s->name));
158 }
159 break;
160
161 case TSTRUCT:
162 case TUNION:
163 s1 = acidsue(t->link);
164 if(s1 == S)
165 break;
166 if(flag) {
167 if(s == S) {
168 Bprint(&outbuf, " {\n");
169 for(l = t->link; l != T; l = l->down)
170 acidmember(l, t->offset+off, flag);
171 Bprint(&outbuf, " };\n");
172 } else {
173 Bprint(&outbuf, " %s %ld %s;\n",
174 amap(s1->name),
175 t->offset+off, amap(s->name));
176 }
177 } else {
178 if(s != S) {
179 Bprint(&outbuf, "\tprint(\"%s %s {\\n\");\n",
180 amap(s1->name), amap(s->name));
181 Bprint(&outbuf, "\t%s(addr.%s);\n",
182 amap(s1->name), amap(s->name));
183 Bprint(&outbuf, "\tprint(\"}\\n\");\n");
184 } else {
185 Bprint(&outbuf, "\tprint(\"%s {\\n\");\n",
186 amap(s1->name));
187 Bprint(&outbuf, "\t\t%s(addr+%ld);\n",
188 amap(s1->name), t->offset+off);
189 Bprint(&outbuf, "\tprint(\"}\\n\");\n");
190 }
191 }
192 break;
193 }
194 }
195
196 void
acidtype(Type * t)197 acidtype(Type *t)
198 {
199 Sym *s;
200 Type *l;
201 Io *i;
202 int n;
203 char *an;
204
205 if(!debug['a'])
206 return;
207 if(debug['a'] > 1) {
208 n = 0;
209 for(i=iostack; i; i=i->link)
210 n++;
211 if(n > 1)
212 return;
213 }
214 s = acidsue(t->link);
215 if(s == S)
216 return;
217 switch(t->etype) {
218 default:
219 Bprint(&outbuf, "T%d\n", t->etype);
220 return;
221
222 case TUNION:
223 case TSTRUCT:
224 if(debug['s'])
225 goto asmstr;
226 an = amap(s->name);
227 Bprint(&outbuf, "sizeof%s = %ld;\n", an, t->width);
228 Bprint(&outbuf, "aggr %s\n{\n", an);
229 for(l = t->link; l != T; l = l->down)
230 acidmember(l, 0, 1);
231 Bprint(&outbuf, "};\n\n");
232
233 Bprint(&outbuf, "defn\n%s(addr) {\n\tcomplex %s addr;\n", an, an);
234 for(l = t->link; l != T; l = l->down)
235 acidmember(l, 0, 0);
236 Bprint(&outbuf, "};\n\n");
237 break;
238 asmstr:
239 if(s == S)
240 break;
241 for(l = t->link; l != T; l = l->down)
242 if(l->sym != S)
243 Bprint(&outbuf, "#define\t%s.%s\t%ld\n",
244 s->name,
245 l->sym->name,
246 l->offset);
247 break;
248 }
249 }
250
251 void
acidvar(Sym * s)252 acidvar(Sym *s)
253 {
254 int n;
255 Io *i;
256 Type *t;
257 Sym *s1, *s2;
258
259 if(!debug['a'] || debug['s'])
260 return;
261 if(debug['a'] > 1) {
262 n = 0;
263 for(i=iostack; i; i=i->link)
264 n++;
265 if(n > 1)
266 return;
267 }
268 t = s->type;
269 while(t && t->etype == TIND)
270 t = t->link;
271 if(t == T)
272 return;
273 if(t->etype == TENUM) {
274 Bprint(&outbuf, "%s = ", amap(s->name));
275 if(!typefd[t->etype])
276 Bprint(&outbuf, "%lld;\n", s->vconst);
277 else
278 Bprint(&outbuf, "%f\n;", s->fconst);
279 return;
280 }
281 if(!typesu[t->etype])
282 return;
283 s1 = acidsue(t->link);
284 if(s1 == S)
285 return;
286 switch(s->class) {
287 case CAUTO:
288 case CPARAM:
289 s2 = acidfun(thisfn);
290 if(s2)
291 Bprint(&outbuf, "complex %s %s:%s;\n",
292 amap(s1->name), amap(s2->name), amap(s->name));
293 break;
294
295 case CSTATIC:
296 case CEXTERN:
297 case CGLOBL:
298 case CLOCAL:
299 Bprint(&outbuf, "complex %s %s;\n",
300 amap(s1->name), amap(s->name));
301 break;
302 }
303 }
304