1 #include "cc.h" 2 3 static char *kwd[] = 4 { 5 "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn", 6 "$delete", "$do", "$else", "$eval", "$head", "$if", 7 "$local", "$loop", "$return", "$tail", "$then", 8 "$union", "$whatis", "$while", 9 }; 10 11 char* 12 amap(char *s) 13 { 14 int i, bot, top, new; 15 16 bot = 0; 17 top = bot + nelem(kwd) - 1; 18 while(bot <= top){ 19 new = bot + (top - bot)/2; 20 i = strcmp(kwd[new]+1, s); 21 if(i == 0) 22 return kwd[new]; 23 24 if(i < 0) 25 bot = new + 1; 26 else 27 top = new - 1; 28 } 29 return s; 30 } 31 32 Sym* 33 acidsue(Type *t) 34 { 35 int h; 36 Sym *s; 37 38 if(t != T) 39 for(h=0; h<nelem(hash); h++) 40 for(s = hash[h]; s != S; s = s->link) 41 if(s->suetag && s->suetag->link == t) 42 return s; 43 return 0; 44 } 45 46 Sym* 47 acidfun(Type *t) 48 { 49 int h; 50 Sym *s; 51 52 for(h=0; h<nelem(hash); h++) 53 for(s = hash[h]; s != S; s = s->link) 54 if(s->type == t) 55 return s; 56 return 0; 57 } 58 59 char acidchar[NTYPE]; 60 Init acidcinit[] = 61 { 62 TCHAR, 'C', 0, 63 TUCHAR, 'b', 0, 64 TSHORT, 'd', 0, 65 TUSHORT, 'u', 0, 66 TLONG, 'D', 0, 67 TULONG, 'U', 0, 68 TVLONG, 'V', 0, 69 TUVLONG, 'W', 0, 70 TFLOAT, 'f', 0, 71 TDOUBLE, 'F', 0, 72 TARRAY, 'a', 0, 73 TIND, 'X', 0, 74 -1, 0, 0, 75 }; 76 77 static void 78 acidinit(void) 79 { 80 Init *p; 81 82 for(p=acidcinit; p->code >= 0; p++) 83 acidchar[p->code] = p->value; 84 85 acidchar[TINT] = acidchar[TLONG]; 86 acidchar[TUINT] = acidchar[TULONG]; 87 if(types[TINT]->width != types[TLONG]->width) { 88 acidchar[TINT] = acidchar[TSHORT]; 89 acidchar[TUINT] = acidchar[TUSHORT]; 90 if(types[TINT]->width != types[TSHORT]->width) 91 warn(Z, "acidmember int not long or short"); 92 } 93 if(types[TIND]->width == types[TUVLONG]->width) 94 acidchar[TIND] = 'Y'; 95 96 } 97 98 void 99 acidmember(Type *t, long off, int flag) 100 { 101 Sym *s, *s1; 102 Type *l; 103 static int acidcharinit = 0; 104 105 if(acidcharinit == 0) { 106 acidinit(); 107 acidcharinit = 1; 108 } 109 s = t->sym; 110 switch(t->etype) { 111 default: 112 Bprint(&outbuf, " T%d\n", t->etype); 113 break; 114 115 case TIND: 116 if(s == S) 117 break; 118 if(flag) { 119 for(l=t; l->etype==TIND; l=l->link) 120 ; 121 if(typesu[l->etype]) { 122 s1 = acidsue(l->link); 123 if(s1 != S) { 124 Bprint(&outbuf, " 'A' %s %ld %s;\n", 125 amap(s1->name), 126 t->offset+off, amap(s->name)); 127 break; 128 } 129 } 130 } else { 131 Bprint(&outbuf, 132 "\tprint(\"\t%s\t\", addr.%s\\X, \"\\n\");\n", 133 amap(s->name), amap(s->name)); 134 break; 135 } 136 137 case TINT: 138 case TUINT: 139 case TCHAR: 140 case TUCHAR: 141 case TSHORT: 142 case TUSHORT: 143 case TLONG: 144 case TULONG: 145 case TVLONG: 146 case TUVLONG: 147 case TFLOAT: 148 case TDOUBLE: 149 case TARRAY: 150 if(s == S) 151 break; 152 if(flag) { 153 Bprint(&outbuf, " '%c' %ld %s;\n", 154 acidchar[t->etype], t->offset+off, amap(s->name)); 155 } else { 156 Bprint(&outbuf, "\tprint(\"\t%s\t\", addr.%s, \"\\n\");\n", 157 amap(s->name), amap(s->name)); 158 } 159 break; 160 161 case TSTRUCT: 162 case TUNION: 163 s1 = acidsue(t->link); 164 if(s1 == S) 165 break; 166 if(flag) { 167 if(s == S) { 168 Bprint(&outbuf, " {\n"); 169 for(l = t->link; l != T; l = l->down) 170 acidmember(l, t->offset+off, flag); 171 Bprint(&outbuf, " };\n"); 172 } else { 173 Bprint(&outbuf, " %s %ld %s;\n", 174 amap(s1->name), 175 t->offset+off, amap(s->name)); 176 } 177 } else { 178 if(s != S) { 179 Bprint(&outbuf, "\tprint(\"%s %s {\\n\");\n", 180 amap(s1->name), amap(s->name)); 181 Bprint(&outbuf, "\t%s(addr.%s);\n", 182 amap(s1->name), amap(s->name)); 183 Bprint(&outbuf, "\tprint(\"}\\n\");\n"); 184 } else { 185 Bprint(&outbuf, "\tprint(\"%s {\\n\");\n", 186 amap(s1->name)); 187 Bprint(&outbuf, "\t\t%s(addr+%ld);\n", 188 amap(s1->name), t->offset+off); 189 Bprint(&outbuf, "\tprint(\"}\\n\");\n"); 190 } 191 } 192 break; 193 } 194 } 195 196 void 197 acidtype(Type *t) 198 { 199 Sym *s; 200 Type *l; 201 Io *i; 202 int n; 203 char *an; 204 205 if(!debug['a']) 206 return; 207 if(debug['a'] > 1) { 208 n = 0; 209 for(i=iostack; i; i=i->link) 210 n++; 211 if(n > 1) 212 return; 213 } 214 s = acidsue(t->link); 215 if(s == S) 216 return; 217 switch(t->etype) { 218 default: 219 Bprint(&outbuf, "T%d\n", t->etype); 220 return; 221 222 case TUNION: 223 case TSTRUCT: 224 if(debug['s']) 225 goto asmstr; 226 an = amap(s->name); 227 Bprint(&outbuf, "sizeof%s = %ld;\n", an, t->width); 228 Bprint(&outbuf, "aggr %s\n{\n", an); 229 for(l = t->link; l != T; l = l->down) 230 acidmember(l, 0, 1); 231 Bprint(&outbuf, "};\n\n"); 232 233 Bprint(&outbuf, "defn\n%s(addr) {\n\tcomplex %s addr;\n", an, an); 234 for(l = t->link; l != T; l = l->down) 235 acidmember(l, 0, 0); 236 Bprint(&outbuf, "};\n\n"); 237 break; 238 asmstr: 239 if(s == S) 240 break; 241 for(l = t->link; l != T; l = l->down) 242 if(l->sym != S) 243 Bprint(&outbuf, "#define\t%s.%s\t%ld\n", 244 s->name, 245 l->sym->name, 246 l->offset); 247 break; 248 } 249 } 250 251 void 252 acidvar(Sym *s) 253 { 254 int n; 255 Io *i; 256 Type *t; 257 Sym *s1, *s2; 258 259 if(!debug['a'] || debug['s']) 260 return; 261 if(debug['a'] > 1) { 262 n = 0; 263 for(i=iostack; i; i=i->link) 264 n++; 265 if(n > 1) 266 return; 267 } 268 t = s->type; 269 while(t && t->etype == TIND) 270 t = t->link; 271 if(t == T) 272 return; 273 if(t->etype == TENUM) { 274 Bprint(&outbuf, "%s = ", amap(s->name)); 275 if(!typefd[t->etype]) 276 Bprint(&outbuf, "%lld;\n", s->vconst); 277 else 278 Bprint(&outbuf, "%f\n;", s->fconst); 279 return; 280 } 281 if(!typesu[t->etype]) 282 return; 283 s1 = acidsue(t->link); 284 if(s1 == S) 285 return; 286 switch(s->class) { 287 case CAUTO: 288 case CPARAM: 289 s2 = acidfun(thisfn); 290 if(s2) 291 Bprint(&outbuf, "complex %s %s:%s;\n", 292 amap(s1->name), amap(s2->name), amap(s->name)); 293 break; 294 295 case CSTATIC: 296 case CEXTERN: 297 case CGLOBL: 298 case CLOCAL: 299 Bprint(&outbuf, "complex %s %s;\n", 300 amap(s1->name), amap(s->name)); 301 break; 302 } 303 } 304