xref: /plan9/sys/src/cmd/cc/acid.c (revision d40255d87ccd1acd15b87823a96efd7b6296fadd)
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