xref: /plan9/sys/src/cmd/cc/pickle.c (revision b94bb474148e9d24a82a427863d9c9eb4c20f4ae)
180ee5cbfSDavid du Colombier #include "cc.h"
280ee5cbfSDavid du Colombier 
380ee5cbfSDavid du Colombier static char *kwd[] =
480ee5cbfSDavid du Colombier {
580ee5cbfSDavid du Colombier 	"$adt", "$aggr", "$append", "$complex", "$defn",
680ee5cbfSDavid du Colombier 	"$delete", "$do", "$else", "$eval", "$head", "$if",
780ee5cbfSDavid du Colombier 	"$local", "$loop", "$return", "$tail", "$then",
880ee5cbfSDavid du Colombier 	"$union", "$whatis", "$while",
980ee5cbfSDavid du Colombier };
10*b94bb474SDavid du Colombier static char picklestr[] = "\tpickle(s, un, ";
1180ee5cbfSDavid du Colombier 
1280ee5cbfSDavid du Colombier static char*
pmap(char * s)1380ee5cbfSDavid du Colombier pmap(char *s)
1480ee5cbfSDavid du Colombier {
1580ee5cbfSDavid du Colombier 	int i, bot, top, new;
1680ee5cbfSDavid du Colombier 
1780ee5cbfSDavid du Colombier 	bot = 0;
1880ee5cbfSDavid du Colombier 	top = bot + nelem(kwd) - 1;
1980ee5cbfSDavid du Colombier 	while(bot <= top){
2080ee5cbfSDavid du Colombier 		new = bot + (top - bot)/2;
2180ee5cbfSDavid du Colombier 		i = strcmp(kwd[new]+1, s);
2280ee5cbfSDavid du Colombier 		if(i == 0)
2380ee5cbfSDavid du Colombier 			return kwd[new];
2480ee5cbfSDavid du Colombier 
2580ee5cbfSDavid du Colombier 		if(i < 0)
2680ee5cbfSDavid du Colombier 			bot = new + 1;
2780ee5cbfSDavid du Colombier 		else
2880ee5cbfSDavid du Colombier 			top = new - 1;
2980ee5cbfSDavid du Colombier 	}
3080ee5cbfSDavid du Colombier 	return s;
3180ee5cbfSDavid du Colombier }
3280ee5cbfSDavid du Colombier 
3380ee5cbfSDavid du Colombier Sym*
picklesue(Type * t)3480ee5cbfSDavid du Colombier picklesue(Type *t)
3580ee5cbfSDavid du Colombier {
3680ee5cbfSDavid du Colombier 	int h;
3780ee5cbfSDavid du Colombier 	Sym *s;
3880ee5cbfSDavid du Colombier 
3980ee5cbfSDavid du Colombier 	if(t != T)
4080ee5cbfSDavid du Colombier 	for(h=0; h<nelem(hash); h++)
4180ee5cbfSDavid du Colombier 		for(s = hash[h]; s != S; s = s->link)
4280ee5cbfSDavid du Colombier 			if(s->suetag && s->suetag->link == t)
4380ee5cbfSDavid du Colombier 				return s;
4480ee5cbfSDavid du Colombier 	return 0;
4580ee5cbfSDavid du Colombier }
4680ee5cbfSDavid du Colombier 
4780ee5cbfSDavid du Colombier Sym*
picklefun(Type * t)4880ee5cbfSDavid du Colombier picklefun(Type *t)
4980ee5cbfSDavid du Colombier {
5080ee5cbfSDavid du Colombier 	int h;
5180ee5cbfSDavid du Colombier 	Sym *s;
5280ee5cbfSDavid du Colombier 
5380ee5cbfSDavid du Colombier 	for(h=0; h<nelem(hash); h++)
5480ee5cbfSDavid du Colombier 		for(s = hash[h]; s != S; s = s->link)
5580ee5cbfSDavid du Colombier 			if(s->type == t)
5680ee5cbfSDavid du Colombier 				return s;
5780ee5cbfSDavid du Colombier 	return 0;
5880ee5cbfSDavid du Colombier }
5980ee5cbfSDavid du Colombier 
6080ee5cbfSDavid du Colombier char	picklechar[NTYPE];
6180ee5cbfSDavid du Colombier Init	picklecinit[] =
6280ee5cbfSDavid du Colombier {
6380ee5cbfSDavid du Colombier 	TCHAR,		'C',	0,
6480ee5cbfSDavid du Colombier 	TUCHAR,		'b',	0,
6580ee5cbfSDavid du Colombier 	TSHORT,		'd',	0,
6680ee5cbfSDavid du Colombier 	TUSHORT,		'u',	0,
6780ee5cbfSDavid du Colombier 	TLONG,		'D',	0,
6880ee5cbfSDavid du Colombier 	TULONG,		'U',	0,
6980ee5cbfSDavid du Colombier 	TVLONG,		'V',	0,
7080ee5cbfSDavid du Colombier 	TUVLONG,	'W',	0,
7180ee5cbfSDavid du Colombier 	TFLOAT,		'f',	0,
7280ee5cbfSDavid du Colombier 	TDOUBLE,		'F',	0,
7380ee5cbfSDavid du Colombier 	TARRAY,		'a',	0,
7480ee5cbfSDavid du Colombier 	TIND,		'X',	0,
7580ee5cbfSDavid du Colombier 	-1,		0,	0,
7680ee5cbfSDavid du Colombier };
7780ee5cbfSDavid du Colombier 
7880ee5cbfSDavid du Colombier static void
pickleinit(void)7980ee5cbfSDavid du Colombier pickleinit(void)
8080ee5cbfSDavid du Colombier {
8180ee5cbfSDavid du Colombier 	Init *p;
8280ee5cbfSDavid du Colombier 
8380ee5cbfSDavid du Colombier 	for(p=picklecinit; p->code >= 0; p++)
8480ee5cbfSDavid du Colombier 		picklechar[p->code] = p->value;
8580ee5cbfSDavid du Colombier 
8680ee5cbfSDavid du Colombier 	picklechar[TINT] = picklechar[TLONG];
8780ee5cbfSDavid du Colombier 	picklechar[TUINT] = picklechar[TULONG];
8880ee5cbfSDavid du Colombier 	if(types[TINT]->width != types[TLONG]->width) {
8980ee5cbfSDavid du Colombier 		picklechar[TINT] = picklechar[TSHORT];
9080ee5cbfSDavid du Colombier 		picklechar[TUINT] = picklechar[TUSHORT];
9180ee5cbfSDavid du Colombier 		if(types[TINT]->width != types[TSHORT]->width)
9280ee5cbfSDavid du Colombier 			warn(Z, "picklemember int not long or short");
9380ee5cbfSDavid du Colombier 	}
9480ee5cbfSDavid du Colombier 
9580ee5cbfSDavid du Colombier }
9680ee5cbfSDavid du Colombier 
9780ee5cbfSDavid du Colombier void
picklemember(Type * t,long off)9880ee5cbfSDavid du Colombier picklemember(Type *t, long off)
9980ee5cbfSDavid du Colombier {
10080ee5cbfSDavid du Colombier 	Sym *s, *s1;
10180ee5cbfSDavid du Colombier 	static int picklecharinit = 0;
10280ee5cbfSDavid du Colombier 
10380ee5cbfSDavid du Colombier 	if(picklecharinit == 0) {
10480ee5cbfSDavid du Colombier 		pickleinit();
10580ee5cbfSDavid du Colombier 		picklecharinit = 1;
10680ee5cbfSDavid du Colombier 	}
10780ee5cbfSDavid du Colombier 	s = t->sym;
10880ee5cbfSDavid du Colombier 	switch(t->etype) {
10980ee5cbfSDavid du Colombier 	default:
11080ee5cbfSDavid du Colombier 		Bprint(&outbuf, "	T%d\n", t->etype);
11180ee5cbfSDavid du Colombier 		break;
11280ee5cbfSDavid du Colombier 
11380ee5cbfSDavid du Colombier 	case TIND:
11480ee5cbfSDavid du Colombier 		if(s == S)
11580ee5cbfSDavid du Colombier 			Bprint(&outbuf,
11639734e7eSDavid du Colombier 				"%s\"p\", (char*)addr+%ld+_i*%ld);\n",
11739734e7eSDavid du Colombier 				picklestr, t->offset+off, t->width);
11880ee5cbfSDavid du Colombier 		else
11980ee5cbfSDavid du Colombier 			Bprint(&outbuf,
12039734e7eSDavid du Colombier 				"%s\"p\", &addr->%s);\n",
12139734e7eSDavid du Colombier 				picklestr, pmap(s->name));
12280ee5cbfSDavid du Colombier 		break;
12380ee5cbfSDavid du Colombier 
12480ee5cbfSDavid du Colombier 	case TINT:
12580ee5cbfSDavid du Colombier 	case TUINT:
12680ee5cbfSDavid du Colombier 	case TCHAR:
12780ee5cbfSDavid du Colombier 	case TUCHAR:
12880ee5cbfSDavid du Colombier 	case TSHORT:
12980ee5cbfSDavid du Colombier 	case TUSHORT:
13080ee5cbfSDavid du Colombier 	case TLONG:
13180ee5cbfSDavid du Colombier 	case TULONG:
13280ee5cbfSDavid du Colombier 	case TVLONG:
13380ee5cbfSDavid du Colombier 	case TUVLONG:
13480ee5cbfSDavid du Colombier 	case TFLOAT:
13580ee5cbfSDavid du Colombier 	case TDOUBLE:
13680ee5cbfSDavid du Colombier 		if(s == S)
13739734e7eSDavid du Colombier 			Bprint(&outbuf, "%s\"%c\", (char*)addr+%ld+_i*%ld);\n",
13839734e7eSDavid du Colombier 				picklestr, picklechar[t->etype], t->offset+off, t->width);
13980ee5cbfSDavid du Colombier 		else
14039734e7eSDavid du Colombier 			Bprint(&outbuf, "%s\"%c\", &addr->%s);\n",
14139734e7eSDavid du Colombier 				picklestr, picklechar[t->etype], pmap(s->name));
14280ee5cbfSDavid du Colombier 		break;
14380ee5cbfSDavid du Colombier 	case TARRAY:
14480ee5cbfSDavid du Colombier 		Bprint(&outbuf, "\tfor(_i = 0; _i < %ld; _i++) {\n\t",
14580ee5cbfSDavid du Colombier 			t->width/t->link->width);
14680ee5cbfSDavid du Colombier 		picklemember(t->link, t->offset+off);
14780ee5cbfSDavid du Colombier 		Bprint(&outbuf, "\t}\n\t_i = 0;\n\tUSED(_i);\n");
14880ee5cbfSDavid du Colombier 		break;
14980ee5cbfSDavid du Colombier 
15080ee5cbfSDavid du Colombier 	case TSTRUCT:
15180ee5cbfSDavid du Colombier 	case TUNION:
15280ee5cbfSDavid du Colombier 		s1 = picklesue(t->link);
15380ee5cbfSDavid du Colombier 		if(s1 == S)
15480ee5cbfSDavid du Colombier 			break;
15580ee5cbfSDavid du Colombier 		if(s == S) {
156*b94bb474SDavid du Colombier 			Bprint(&outbuf, "\tpickle_%s(s, un, (%s*)((char*)addr+%ld+_i*%ld));\n",
15780ee5cbfSDavid du Colombier 				pmap(s1->name), pmap(s1->name), t->offset+off, t->width);
15880ee5cbfSDavid du Colombier 		} else {
159*b94bb474SDavid du Colombier 			Bprint(&outbuf, "\tpickle_%s(s, un, &addr->%s);\n",
16080ee5cbfSDavid du Colombier 				pmap(s1->name), pmap(s->name));
16180ee5cbfSDavid du Colombier 		}
16280ee5cbfSDavid du Colombier 		break;
16380ee5cbfSDavid du Colombier 	}
16480ee5cbfSDavid du Colombier }
16580ee5cbfSDavid du Colombier 
16680ee5cbfSDavid du Colombier void
pickletype(Type * t)16780ee5cbfSDavid du Colombier pickletype(Type *t)
16880ee5cbfSDavid du Colombier {
16980ee5cbfSDavid du Colombier 	Sym *s;
17080ee5cbfSDavid du Colombier 	Type *l;
17180ee5cbfSDavid du Colombier 	Io *i;
17280ee5cbfSDavid du Colombier 	int n;
17380ee5cbfSDavid du Colombier 	char *an;
17480ee5cbfSDavid du Colombier 
17580ee5cbfSDavid du Colombier 	if(!debug['P'])
17680ee5cbfSDavid du Colombier 		return;
17780ee5cbfSDavid du Colombier 	if(debug['P'] > 1) {
17880ee5cbfSDavid du Colombier 		n = 0;
17980ee5cbfSDavid du Colombier 		for(i=iostack; i; i=i->link)
18080ee5cbfSDavid du Colombier 			n++;
18180ee5cbfSDavid du Colombier 		if(n > 1)
18280ee5cbfSDavid du Colombier 			return;
18380ee5cbfSDavid du Colombier 	}
18480ee5cbfSDavid du Colombier 	s = picklesue(t->link);
18580ee5cbfSDavid du Colombier 	if(s == S)
18680ee5cbfSDavid du Colombier 		return;
18780ee5cbfSDavid du Colombier 	switch(t->etype) {
18880ee5cbfSDavid du Colombier 	default:
18980ee5cbfSDavid du Colombier 		Bprint(&outbuf, "T%d\n", t->etype);
19080ee5cbfSDavid du Colombier 		return;
19180ee5cbfSDavid du Colombier 
19280ee5cbfSDavid du Colombier 	case TUNION:
19380ee5cbfSDavid du Colombier 	case TSTRUCT:
19480ee5cbfSDavid du Colombier 		if(debug['s'])
19580ee5cbfSDavid du Colombier 			goto asmstr;
19680ee5cbfSDavid du Colombier 		an = pmap(s->name);
19780ee5cbfSDavid du Colombier 
198*b94bb474SDavid du Colombier 		Bprint(&outbuf, "void\npickle_%s(void *s, int un, %s *addr)\n{\n\tint _i = 0;\n\n\tUSED(_i);\n", an, an);
19980ee5cbfSDavid du Colombier 		for(l = t->link; l != T; l = l->down)
20080ee5cbfSDavid du Colombier 			picklemember(l, 0);
201*b94bb474SDavid du Colombier 		Bprint(&outbuf, "}\n\n");
20280ee5cbfSDavid du Colombier 		break;
20380ee5cbfSDavid du Colombier 	asmstr:
20480ee5cbfSDavid du Colombier 		if(s == S)
20580ee5cbfSDavid du Colombier 			break;
20680ee5cbfSDavid du Colombier 		for(l = t->link; l != T; l = l->down)
20780ee5cbfSDavid du Colombier 			if(l->sym != S)
20880ee5cbfSDavid du Colombier 				Bprint(&outbuf, "#define\t%s.%s\t%ld\n",
20980ee5cbfSDavid du Colombier 					s->name,
21080ee5cbfSDavid du Colombier 					l->sym->name,
21180ee5cbfSDavid du Colombier 					l->offset);
21280ee5cbfSDavid du Colombier 		break;
21380ee5cbfSDavid du Colombier 	}
21480ee5cbfSDavid du Colombier }
21580ee5cbfSDavid du Colombier 
21680ee5cbfSDavid du Colombier void
picklevar(Sym * s)21780ee5cbfSDavid du Colombier picklevar(Sym *s)
21880ee5cbfSDavid du Colombier {
21980ee5cbfSDavid du Colombier 	int n;
22080ee5cbfSDavid du Colombier 	Io *i;
22180ee5cbfSDavid du Colombier 	Type *t;
22280ee5cbfSDavid du Colombier 	Sym *s1, *s2;
22380ee5cbfSDavid du Colombier 
22480ee5cbfSDavid du Colombier 	if(!debug['P'] || debug['s'])
22580ee5cbfSDavid du Colombier 		return;
22680ee5cbfSDavid du Colombier 	if(debug['P'] > 1) {
22780ee5cbfSDavid du Colombier 		n = 0;
22880ee5cbfSDavid du Colombier 		for(i=iostack; i; i=i->link)
22980ee5cbfSDavid du Colombier 			n++;
23080ee5cbfSDavid du Colombier 		if(n > 1)
23180ee5cbfSDavid du Colombier 			return;
23280ee5cbfSDavid du Colombier 	}
23380ee5cbfSDavid du Colombier 	t = s->type;
23480ee5cbfSDavid du Colombier 	while(t && t->etype == TIND)
23580ee5cbfSDavid du Colombier 		t = t->link;
23680ee5cbfSDavid du Colombier 	if(t == T)
23780ee5cbfSDavid du Colombier 		return;
23880ee5cbfSDavid du Colombier 	if(t->etype == TENUM) {
23980ee5cbfSDavid du Colombier 		Bprint(&outbuf, "%s = ", pmap(s->name));
24080ee5cbfSDavid du Colombier 		if(!typefd[t->etype])
24180ee5cbfSDavid du Colombier 			Bprint(&outbuf, "%lld;\n", s->vconst);
24280ee5cbfSDavid du Colombier 		else
24380ee5cbfSDavid du Colombier 			Bprint(&outbuf, "%f\n;", s->fconst);
24480ee5cbfSDavid du Colombier 		return;
24580ee5cbfSDavid du Colombier 	}
24680ee5cbfSDavid du Colombier 	if(!typesu[t->etype])
24780ee5cbfSDavid du Colombier 		return;
24880ee5cbfSDavid du Colombier 	s1 = picklesue(t->link);
24980ee5cbfSDavid du Colombier 	if(s1 == S)
25080ee5cbfSDavid du Colombier 		return;
25180ee5cbfSDavid du Colombier 	switch(s->class) {
25280ee5cbfSDavid du Colombier 	case CAUTO:
25380ee5cbfSDavid du Colombier 	case CPARAM:
25480ee5cbfSDavid du Colombier 		s2 = picklefun(thisfn);
25580ee5cbfSDavid du Colombier 		if(s2)
25680ee5cbfSDavid du Colombier 			Bprint(&outbuf, "complex %s %s:%s;\n",
25780ee5cbfSDavid du Colombier 				pmap(s1->name), pmap(s2->name), pmap(s->name));
25880ee5cbfSDavid du Colombier 		break;
25980ee5cbfSDavid du Colombier 
26080ee5cbfSDavid du Colombier 	case CSTATIC:
26180ee5cbfSDavid du Colombier 	case CEXTERN:
26280ee5cbfSDavid du Colombier 	case CGLOBL:
26380ee5cbfSDavid du Colombier 	case CLOCAL:
26480ee5cbfSDavid du Colombier 		Bprint(&outbuf, "complex %s %s;\n",
26580ee5cbfSDavid du Colombier 			pmap(s1->name), pmap(s->name));
26680ee5cbfSDavid du Colombier 		break;
26780ee5cbfSDavid du Colombier 	}
26880ee5cbfSDavid du Colombier }
269