xref: /plan9/sys/src/cmd/cc/acid.c (revision e464c1a8ab92b21c6d197ac77fea0db90efa611e)
1219b2ee8SDavid du Colombier #include "cc.h"
2219b2ee8SDavid du Colombier 
3219b2ee8SDavid du Colombier static char *kwd[] =
4219b2ee8SDavid du Colombier {
5*e464c1a8SDavid 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*
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*
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*
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
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 	}
937dd7cddfSDavid du Colombier 
947dd7cddfSDavid du Colombier }
957dd7cddfSDavid du Colombier 
96219b2ee8SDavid du Colombier void
97219b2ee8SDavid du Colombier acidmember(Type *t, long off, int flag)
98219b2ee8SDavid du Colombier {
99219b2ee8SDavid du Colombier 	Sym *s, *s1;
100219b2ee8SDavid du Colombier 	Type *l;
1017dd7cddfSDavid du Colombier 	static int acidcharinit = 0;
102219b2ee8SDavid du Colombier 
1037dd7cddfSDavid du Colombier 	if(acidcharinit == 0) {
1047dd7cddfSDavid du Colombier 		acidinit();
1057dd7cddfSDavid du Colombier 		acidcharinit = 1;
1067dd7cddfSDavid du Colombier 	}
107219b2ee8SDavid du Colombier 	s = t->sym;
108219b2ee8SDavid du Colombier 	switch(t->etype) {
109219b2ee8SDavid du Colombier 	default:
110219b2ee8SDavid du Colombier 		Bprint(&outbuf, "	T%d\n", t->etype);
111219b2ee8SDavid du Colombier 		break;
112219b2ee8SDavid du Colombier 
113219b2ee8SDavid du Colombier 	case TIND:
114219b2ee8SDavid du Colombier 		if(s == S)
115219b2ee8SDavid du Colombier 			break;
116219b2ee8SDavid du Colombier 		if(flag) {
117219b2ee8SDavid du Colombier 			for(l=t; l->etype==TIND; l=l->link)
118219b2ee8SDavid du Colombier 				;
119219b2ee8SDavid du Colombier 			if(typesu[l->etype]) {
120219b2ee8SDavid du Colombier 				s1 = acidsue(l->link);
121219b2ee8SDavid du Colombier 				if(s1 != S) {
122219b2ee8SDavid du Colombier 					Bprint(&outbuf, "	'A' %s %ld %s;\n",
123219b2ee8SDavid du Colombier 						amap(s1->name),
124219b2ee8SDavid du Colombier 						t->offset+off, amap(s->name));
125219b2ee8SDavid du Colombier 					break;
126219b2ee8SDavid du Colombier 				}
127219b2ee8SDavid du Colombier 			}
128219b2ee8SDavid du Colombier 		} else {
1297dd7cddfSDavid du Colombier 			Bprint(&outbuf,
1307dd7cddfSDavid du Colombier 				"\tprint(\"\t%s\t\", addr.%s\\X, \"\\n\");\n",
131219b2ee8SDavid du Colombier 				amap(s->name), amap(s->name));
132219b2ee8SDavid du Colombier 			break;
133219b2ee8SDavid du Colombier 		}
134219b2ee8SDavid du Colombier 
1357dd7cddfSDavid du Colombier 	case TINT:
1367dd7cddfSDavid du Colombier 	case TUINT:
137219b2ee8SDavid du Colombier 	case TCHAR:
138219b2ee8SDavid du Colombier 	case TUCHAR:
139219b2ee8SDavid du Colombier 	case TSHORT:
140219b2ee8SDavid du Colombier 	case TUSHORT:
141219b2ee8SDavid du Colombier 	case TLONG:
142219b2ee8SDavid du Colombier 	case TULONG:
143219b2ee8SDavid du Colombier 	case TVLONG:
144219b2ee8SDavid du Colombier 	case TUVLONG:
145219b2ee8SDavid du Colombier 	case TFLOAT:
146219b2ee8SDavid du Colombier 	case TDOUBLE:
147219b2ee8SDavid du Colombier 	case TARRAY:
148219b2ee8SDavid du Colombier 		if(s == S)
149219b2ee8SDavid du Colombier 			break;
150219b2ee8SDavid du Colombier 		if(flag) {
151219b2ee8SDavid du Colombier 			Bprint(&outbuf, "	'%c' %ld %s;\n",
152219b2ee8SDavid du Colombier 			acidchar[t->etype], t->offset+off, amap(s->name));
153219b2ee8SDavid du Colombier 		} else {
154219b2ee8SDavid du Colombier 			Bprint(&outbuf, "\tprint(\"\t%s\t\", addr.%s, \"\\n\");\n",
155219b2ee8SDavid du Colombier 				amap(s->name), amap(s->name));
156219b2ee8SDavid du Colombier 		}
157219b2ee8SDavid du Colombier 		break;
158219b2ee8SDavid du Colombier 
159219b2ee8SDavid du Colombier 	case TSTRUCT:
160219b2ee8SDavid du Colombier 	case TUNION:
161219b2ee8SDavid du Colombier 		s1 = acidsue(t->link);
162219b2ee8SDavid du Colombier 		if(s1 == S)
163219b2ee8SDavid du Colombier 			break;
164219b2ee8SDavid du Colombier 		if(flag) {
165219b2ee8SDavid du Colombier 			if(s == S) {
166219b2ee8SDavid du Colombier 				Bprint(&outbuf, "	{\n");
167219b2ee8SDavid du Colombier 				for(l = t->link; l != T; l = l->down)
168219b2ee8SDavid du Colombier 					acidmember(l, t->offset+off, flag);
169219b2ee8SDavid du Colombier 				Bprint(&outbuf, "	};\n");
170219b2ee8SDavid du Colombier 			} else {
171219b2ee8SDavid du Colombier 				Bprint(&outbuf, "	%s %ld %s;\n",
172219b2ee8SDavid du Colombier 					amap(s1->name),
173219b2ee8SDavid du Colombier 					t->offset+off, amap(s->name));
174219b2ee8SDavid du Colombier 			}
175219b2ee8SDavid du Colombier 		} else {
176219b2ee8SDavid du Colombier 			if(s != S) {
177219b2ee8SDavid du Colombier 				Bprint(&outbuf, "\tprint(\"%s %s {\\n\");\n",
178219b2ee8SDavid du Colombier 					amap(s1->name), amap(s->name));
179219b2ee8SDavid du Colombier 				Bprint(&outbuf, "\t%s(addr.%s);\n",
180219b2ee8SDavid du Colombier 					amap(s1->name), amap(s->name));
181219b2ee8SDavid du Colombier 				Bprint(&outbuf, "\tprint(\"}\\n\");\n");
182219b2ee8SDavid du Colombier 			} else {
183219b2ee8SDavid du Colombier 				Bprint(&outbuf, "\tprint(\"%s {\\n\");\n",
184219b2ee8SDavid du Colombier 					amap(s1->name));
1857dd7cddfSDavid du Colombier 				Bprint(&outbuf, "\t\t%s(addr+%ld);\n",
186219b2ee8SDavid du Colombier 					amap(s1->name), t->offset+off);
187219b2ee8SDavid du Colombier 				Bprint(&outbuf, "\tprint(\"}\\n\");\n");
188219b2ee8SDavid du Colombier 			}
189219b2ee8SDavid du Colombier 		}
190219b2ee8SDavid du Colombier 		break;
191219b2ee8SDavid du Colombier 	}
192219b2ee8SDavid du Colombier }
193219b2ee8SDavid du Colombier 
194219b2ee8SDavid du Colombier void
195219b2ee8SDavid du Colombier acidtype(Type *t)
196219b2ee8SDavid du Colombier {
197219b2ee8SDavid du Colombier 	Sym *s;
198219b2ee8SDavid du Colombier 	Type *l;
199219b2ee8SDavid du Colombier 	Io *i;
200219b2ee8SDavid du Colombier 	int n;
201219b2ee8SDavid du Colombier 	char *an;
202219b2ee8SDavid du Colombier 
203219b2ee8SDavid du Colombier 	if(!debug['a'])
204219b2ee8SDavid du Colombier 		return;
205219b2ee8SDavid du Colombier 	if(debug['a'] > 1) {
206219b2ee8SDavid du Colombier 		n = 0;
207219b2ee8SDavid du Colombier 		for(i=iostack; i; i=i->link)
208219b2ee8SDavid du Colombier 			n++;
209219b2ee8SDavid du Colombier 		if(n > 1)
210219b2ee8SDavid du Colombier 			return;
211219b2ee8SDavid du Colombier 	}
212219b2ee8SDavid du Colombier 	s = acidsue(t->link);
213219b2ee8SDavid du Colombier 	if(s == S)
214219b2ee8SDavid du Colombier 		return;
215219b2ee8SDavid du Colombier 	switch(t->etype) {
216219b2ee8SDavid du Colombier 	default:
217219b2ee8SDavid du Colombier 		Bprint(&outbuf, "T%d\n", t->etype);
218219b2ee8SDavid du Colombier 		return;
219219b2ee8SDavid du Colombier 
220219b2ee8SDavid du Colombier 	case TUNION:
221219b2ee8SDavid du Colombier 	case TSTRUCT:
222219b2ee8SDavid du Colombier 		if(debug['s'])
223219b2ee8SDavid du Colombier 			goto asmstr;
224219b2ee8SDavid du Colombier 		an = amap(s->name);
2257dd7cddfSDavid du Colombier 		Bprint(&outbuf, "sizeof%s = %ld;\n", an, t->width);
226219b2ee8SDavid du Colombier 		Bprint(&outbuf, "aggr %s\n{\n", an);
227219b2ee8SDavid du Colombier 		for(l = t->link; l != T; l = l->down)
228219b2ee8SDavid du Colombier 			acidmember(l, 0, 1);
229219b2ee8SDavid du Colombier 		Bprint(&outbuf, "};\n\n");
230219b2ee8SDavid du Colombier 
231219b2ee8SDavid du Colombier 		Bprint(&outbuf, "defn\n%s(addr) {\n\tcomplex %s addr;\n", an, an);
232219b2ee8SDavid du Colombier 		for(l = t->link; l != T; l = l->down)
233219b2ee8SDavid du Colombier 			acidmember(l, 0, 0);
234219b2ee8SDavid du Colombier 		Bprint(&outbuf, "};\n\n");
235219b2ee8SDavid du Colombier 		break;
236219b2ee8SDavid du Colombier 	asmstr:
237219b2ee8SDavid du Colombier 		if(s == S)
238219b2ee8SDavid du Colombier 			break;
239219b2ee8SDavid du Colombier 		for(l = t->link; l != T; l = l->down)
240219b2ee8SDavid du Colombier 			if(l->sym != S)
241219b2ee8SDavid du Colombier 				Bprint(&outbuf, "#define\t%s.%s\t%ld\n",
242219b2ee8SDavid du Colombier 					s->name,
243219b2ee8SDavid du Colombier 					l->sym->name,
244219b2ee8SDavid du Colombier 					l->offset);
245219b2ee8SDavid du Colombier 		break;
246219b2ee8SDavid du Colombier 	}
247219b2ee8SDavid du Colombier }
248219b2ee8SDavid du Colombier 
249219b2ee8SDavid du Colombier void
250219b2ee8SDavid du Colombier acidvar(Sym *s)
251219b2ee8SDavid du Colombier {
252219b2ee8SDavid du Colombier 	int n;
253219b2ee8SDavid du Colombier 	Io *i;
254219b2ee8SDavid du Colombier 	Type *t;
255219b2ee8SDavid du Colombier 	Sym *s1, *s2;
256219b2ee8SDavid du Colombier 
257219b2ee8SDavid du Colombier 	if(!debug['a'] || debug['s'])
258219b2ee8SDavid du Colombier 		return;
259219b2ee8SDavid du Colombier 	if(debug['a'] > 1) {
260219b2ee8SDavid du Colombier 		n = 0;
261219b2ee8SDavid du Colombier 		for(i=iostack; i; i=i->link)
262219b2ee8SDavid du Colombier 			n++;
263219b2ee8SDavid du Colombier 		if(n > 1)
264219b2ee8SDavid du Colombier 			return;
265219b2ee8SDavid du Colombier 	}
266219b2ee8SDavid du Colombier 	t = s->type;
267219b2ee8SDavid du Colombier 	while(t && t->etype == TIND)
268219b2ee8SDavid du Colombier 		t = t->link;
269219b2ee8SDavid du Colombier 	if(t == T)
270219b2ee8SDavid du Colombier 		return;
2717dd7cddfSDavid du Colombier 	if(t->etype == TENUM) {
2727dd7cddfSDavid du Colombier 		Bprint(&outbuf, "%s = ", amap(s->name));
2737dd7cddfSDavid du Colombier 		if(!typefd[t->etype])
2747dd7cddfSDavid du Colombier 			Bprint(&outbuf, "%lld;\n", s->vconst);
2757dd7cddfSDavid du Colombier 		else
2767dd7cddfSDavid du Colombier 			Bprint(&outbuf, "%f\n;", s->fconst);
2777dd7cddfSDavid du Colombier 		return;
2787dd7cddfSDavid du Colombier 	}
279219b2ee8SDavid du Colombier 	if(!typesu[t->etype])
280219b2ee8SDavid du Colombier 		return;
281219b2ee8SDavid du Colombier 	s1 = acidsue(t->link);
282219b2ee8SDavid du Colombier 	if(s1 == S)
283219b2ee8SDavid du Colombier 		return;
284219b2ee8SDavid du Colombier 	switch(s->class) {
285219b2ee8SDavid du Colombier 	case CAUTO:
286219b2ee8SDavid du Colombier 	case CPARAM:
287219b2ee8SDavid du Colombier 		s2 = acidfun(thisfn);
288219b2ee8SDavid du Colombier 		if(s2)
289219b2ee8SDavid du Colombier 			Bprint(&outbuf, "complex %s %s:%s;\n",
290219b2ee8SDavid du Colombier 				amap(s1->name), amap(s2->name), amap(s->name));
291219b2ee8SDavid du Colombier 		break;
292219b2ee8SDavid du Colombier 
293219b2ee8SDavid du Colombier 	case CSTATIC:
294219b2ee8SDavid du Colombier 	case CEXTERN:
295219b2ee8SDavid du Colombier 	case CGLOBL:
296219b2ee8SDavid du Colombier 	case CLOCAL:
297219b2ee8SDavid du Colombier 		Bprint(&outbuf, "complex %s %s;\n",
298219b2ee8SDavid du Colombier 			amap(s1->name), amap(s->name));
299219b2ee8SDavid du Colombier 		break;
300219b2ee8SDavid du Colombier 	}
301219b2ee8SDavid du Colombier }
302