00001 #include "c.h"
00002 #include <stdio.h>
00003
00004
00005 #define equalp(x) v.x == p->sym.u.c.v.x
00006
00007 struct table {
00008 int level;
00009 Table previous;
00010 struct entry {
00011 struct symbol sym;
00012 struct entry *link;
00013 } *buckets[256];
00014 Symbol all;
00015 };
00016 #define HASHSIZE NELEMS(((Table)0)->buckets)
00017 static struct table
00018 cns = { CONSTANTS },
00019 ext = { GLOBAL },
00020 ids = { GLOBAL },
00021 tys = { GLOBAL };
00022 Table constants = &cns;
00023 Table externals = &ext;
00024 Table identifiers = &ids;
00025 Table globals = &ids;
00026 Table types = &tys;
00027 Table labels;
00028 int level = GLOBAL;
00029 static int tempid;
00030 List loci, symbols;
00031
00032 Table table(Table tp, int level) {
00033 Table new;
00034
00035 NEW0(new, FUNC);
00036 new->previous = tp;
00037 new->level = level;
00038 if (tp)
00039 new->all = tp->all;
00040 return new;
00041 }
00042 void foreach(Table tp, int lev, void (*apply)(Symbol, void *), void *cl) {
00043 assert(tp);
00044 while (tp && tp->level > lev)
00045 tp = tp->previous;
00046 if (tp && tp->level == lev) {
00047 Symbol p;
00048 Coordinate sav;
00049 sav = src;
00050 for (p = tp->all; p && p->scope == lev; p = p->up) {
00051 src = p->src;
00052 (*apply)(p, cl);
00053 }
00054 src = sav;
00055 }
00056 }
00057 void enterscope(void) {
00058 if (++level == LOCAL)
00059 tempid = 0;
00060 }
00061 void exitscope(void) {
00062 rmtypes(level);
00063 if (types->level == level)
00064 types = types->previous;
00065 if (identifiers->level == level) {
00066 if (Aflag >= 2) {
00067 int n = 0;
00068 Symbol p;
00069 for (p = identifiers->all; p && p->scope == level; p = p->up)
00070 if (++n > 127) {
00071 warning("more than 127 identifiers declared in a block\n");
00072 break;
00073 }
00074 }
00075 identifiers = identifiers->previous;
00076 }
00077 assert(level >= GLOBAL);
00078 --level;
00079 }
00080 Symbol install(const char *name, Table *tpp, int level, int arena) {
00081 Table tp = *tpp;
00082 struct entry *p;
00083 unsigned h = (unsigned long)name&(HASHSIZE-1);
00084
00085 assert(level == 0 || level >= tp->level);
00086 if (level > 0 && tp->level < level)
00087 tp = *tpp = table(tp, level);
00088 NEW0(p, arena);
00089 p->sym.name = (char *)name;
00090 p->sym.scope = level;
00091 p->sym.up = tp->all;
00092 tp->all = &p->sym;
00093 p->link = tp->buckets[h];
00094 tp->buckets[h] = p;
00095 return &p->sym;
00096 }
00097 Symbol relocate(const char *name, Table src, Table dst) {
00098 struct entry *p, **q;
00099 Symbol *r;
00100 unsigned h = (unsigned long)name&(HASHSIZE-1);
00101
00102 for (q = &src->buckets[h]; *q; q = &(*q)->link)
00103 if (name == (*q)->sym.name)
00104 break;
00105 assert(*q);
00106
00107
00108
00109
00110 p = *q;
00111 *q = (*q)->link;
00112 for (r = &src->all; *r && *r != &p->sym; r = &(*r)->up)
00113 ;
00114 assert(*r == &p->sym);
00115 *r = p->sym.up;
00116
00117
00118
00119
00120
00121 p->link = dst->buckets[h];
00122 dst->buckets[h] = p;
00123 p->sym.up = dst->all;
00124 dst->all = &p->sym;
00125 return &p->sym;
00126 }
00127 Symbol lookup(const char *name, Table tp) {
00128 struct entry *p;
00129 unsigned h = (unsigned long)name&(HASHSIZE-1);
00130
00131 assert(tp);
00132 do
00133 for (p = tp->buckets[h]; p; p = p->link)
00134 if (name == p->sym.name)
00135 return &p->sym;
00136 while ((tp = tp->previous) != NULL);
00137 return NULL;
00138 }
00139 int genlabel(int n) {
00140 static int label = 1;
00141
00142 label += n;
00143 return label - n;
00144 }
00145 Symbol findlabel(int lab) {
00146 struct entry *p;
00147 unsigned h = lab&(HASHSIZE-1);
00148
00149 for (p = labels->buckets[h]; p; p = p->link)
00150 if (lab == p->sym.u.l.label)
00151 return &p->sym;
00152 NEW0(p, FUNC);
00153 p->sym.name = stringd(lab);
00154 p->sym.scope = LABELS;
00155 p->sym.up = labels->all;
00156 labels->all = &p->sym;
00157 p->link = labels->buckets[h];
00158 labels->buckets[h] = p;
00159 p->sym.generated = 1;
00160 p->sym.u.l.label = lab;
00161 (*IR->defsymbol)(&p->sym);
00162 return &p->sym;
00163 }
00164 Symbol constant(Type ty, Value v) {
00165 struct entry *p;
00166 unsigned h = v.u&(HASHSIZE-1);
00167
00168 ty = unqual(ty);
00169 for (p = constants->buckets[h]; p; p = p->link)
00170 if (eqtype(ty, p->sym.type, 1))
00171 switch (ty->op) {
00172 case INT: if (equalp(i)) return &p->sym; break;
00173 case UNSIGNED: if (equalp(u)) return &p->sym; break;
00174 case FLOAT: if (equalp(d)) return &p->sym; break;
00175 case FUNCTION: if (equalp(g)) return &p->sym; break;
00176 case ARRAY:
00177 case POINTER: if (equalp(p)) return &p->sym; break;
00178 default: assert(0);
00179 }
00180 NEW0(p, PERM);
00181 p->sym.name = vtoa(ty, v);
00182 p->sym.scope = CONSTANTS;
00183 p->sym.type = ty;
00184 p->sym.sclass = STATIC;
00185 p->sym.u.c.v = v;
00186 p->link = constants->buckets[h];
00187 p->sym.up = constants->all;
00188 constants->all = &p->sym;
00189 constants->buckets[h] = p;
00190 if (ty->u.sym && !ty->u.sym->addressed)
00191 (*IR->defsymbol)(&p->sym);
00192 p->sym.defined = 1;
00193 return &p->sym;
00194 }
00195 Symbol intconst(int n) {
00196 Value v;
00197
00198 v.i = n;
00199 return constant(inttype, v);
00200 }
00201 Symbol genident(int scls, Type ty, int lev) {
00202 Symbol p;
00203
00204 NEW0(p, lev >= LOCAL ? FUNC : PERM);
00205 p->name = stringd(genlabel(1));
00206 p->scope = lev;
00207 p->sclass = scls;
00208 p->type = ty;
00209 p->generated = 1;
00210 if (lev == GLOBAL)
00211 (*IR->defsymbol)(p);
00212 return p;
00213 }
00214
00215 Symbol temporary(int scls, Type ty) {
00216 Symbol p;
00217
00218 NEW0(p, FUNC);
00219 p->name = stringd(++tempid);
00220 p->scope = level < LOCAL ? LOCAL : level;
00221 p->sclass = scls;
00222 p->type = ty;
00223 p->temporary = 1;
00224 p->generated = 1;
00225 return p;
00226 }
00227 Symbol newtemp(int sclass, int tc, int size) {
00228 Symbol p = temporary(sclass, btot(tc, size));
00229
00230 (*IR->local)(p);
00231 p->defined = 1;
00232 return p;
00233 }
00234
00235 Symbol allsymbols(Table tp) {
00236 return tp->all;
00237 }
00238
00239 void locus(Table tp, Coordinate *cp) {
00240 loci = append(cp, loci);
00241 symbols = append(allsymbols(tp), symbols);
00242 }
00243
00244 void use(Symbol p, Coordinate src) {
00245 Coordinate *cp;
00246
00247 NEW(cp, PERM);
00248 *cp = src;
00249 p->uses = append(cp, p->uses);
00250 }
00251
00252 Symbol findtype(Type ty) {
00253 Table tp = identifiers;
00254 int i;
00255 struct entry *p;
00256
00257 assert(tp);
00258 do
00259 for (i = 0; i < HASHSIZE; i++)
00260 for (p = tp->buckets[i]; p; p = p->link)
00261 if (p->sym.type == ty && p->sym.sclass == TYPEDEF)
00262 return &p->sym;
00263 while ((tp = tp->previous) != NULL);
00264 return NULL;
00265 }
00266
00267
00268 Symbol mkstr(char *str) {
00269 Value v;
00270 Symbol p;
00271
00272 v.p = str;
00273 p = constant(array(chartype, strlen(v.p) + 1, 0), v);
00274 if (p->u.c.loc == NULL)
00275 p->u.c.loc = genident(STATIC, p->type, GLOBAL);
00276 return p;
00277 }
00278
00279
00280 Symbol mksymbol(int sclass, const char *name, Type ty) {
00281 Symbol p;
00282
00283 if (sclass == EXTERN)
00284 p = install(string(name), &globals, GLOBAL, PERM);
00285 else {
00286 NEW0(p, PERM);
00287 p->name = string(name);
00288 p->scope = GLOBAL;
00289 }
00290 p->sclass = sclass;
00291 p->type = ty;
00292 (*IR->defsymbol)(p);
00293 p->defined = 1;
00294 return p;
00295 }
00296
00297
00298 char *vtoa(Type ty, Value v) {
00299 char buf[50];
00300
00301 ty = unqual(ty);
00302 switch (ty->op) {
00303 case INT: return stringd(v.i);
00304 case UNSIGNED: return stringf((v.u&~0x7FFF) ? "0x%X" : "%U", v.u);
00305 case FLOAT: return stringf("%g", (double)v.d);
00306 case ARRAY:
00307 if (ty->type == chartype || ty->type == signedchar
00308 || ty->type == unsignedchar)
00309 return v.p;
00310 return stringf("%p", v.p);
00311 case POINTER: return stringf("%p", v.p);
00312 case FUNCTION: return stringf("%p", v.g);
00313 }
00314 assert(0); return NULL;
00315 }