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