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