void genlabel (tree * n) { if (n == NULL) return; if (!isleaf (n)) { if (isleaf (n->left)) n->left->label = 1; else genlabel (n->left); if (isleaf (n->right)) n->right->label = 0; else genlabel (n->right); if(n->right == NULL) n->label = n->left->label; else if (n->right->label != n->left->label) n->label = max (n->right->label, n->left->label); else n->label = n->right->label + 1; } }
/* stabline - emit stab entry for source coordinate *cp */ void stabline(Coordinate *cp) { if (cp->file && cp->file != currentfile) { int lab = genlabel(1); print(".stabs \"%s\",0x%x,0,0,%s%d\n", cp->file, N_SOL, stabprefix, lab); print("%s%d:\n", stabprefix, lab); currentfile = cp->file; } if (IR == &sparcIR) print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y); else { int lab = genlabel(1); print(".stabn 0x%x,0,%d,%s%d-%s\n", N_SLINE, cp->y, stabprefix, lab, cfunc->x.name); print("%s%d:\n", stabprefix, lab); } }
/* stabblock - output a stab entry for '{' or '}' at level lev */ void stabblock(int brace, int lev, Symbol *p) { if (brace == '{') while (*p) stabsym(*p++); if (IR == &sparcIR) print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev); else { int lab = genlabel(1); print(".stabn 0x%x,0,%d,%s%d-%s\n", brace == '{' ? N_LBRAC : N_RBRAC, lev, stabprefix, lab, cfunc->x.name); print("%s%d:\n", stabprefix, lab); } }
static void asdl_progend(void) { dopending(NULL); { int n = checkuid(pickle->interfaces) + Seq_length(pickle->items); if (n != pickle->nuids - 1) fprintf(stderr, "?bogus uid count: have %d should have %d\n", n, pickle->nuids-1); } pickle->nlabels = genlabel(0); write_int((int)(100*(assert(strstr(rcsid, ",v")), strtod(strstr(rcsid, ",v")+2, NULL)) ), stdout); rcc_write_program(pickle, stdout); }
static void I(defsymbol)(Symbol p) { if (p->scope == CONSTANTS) switch (optype(ttob(p->type))) { case I: p->x.name = stringf("%D", p->u.c.v.i); break; case U: p->x.name = stringf("%U", p->u.c.v.u); break; case P: p->x.name = stringf("%U", p->u.c.v.p); break; default: assert(0); } else if (p->scope >= LOCAL && p->sclass == STATIC) p->x.name = stringf("$%d", genlabel(1)); else if (p->scope == LABELS || p->generated) p->x.name = stringf("$%s", p->name); else p->x.name = p->name; }
static void stmtlabel(void) { Symbol p = lookup(token, stmtlabs); if (p == NULL) { p = install(token, &stmtlabs, 0, FUNC); p->scope = LABELS; p->u.l.label = genlabel(1); p->src = src; } if (p->defined) error("redefinition of label `%s' previously defined at %w\n", p->name, &p->src); p->defined = 1; definelab(p->u.l.label); t = gettok(); expect(':'); }
void defsymbol(sSymbol_t p) { if (p->x.name) return; if (p->scope == CONSTANTS) { p->x.name = p->name; if (p->x.name[0]=='0' && p->x.name[1]=='x') { p->x.name[0]=' '; p->x.name[1]='$'; } } else if (p->sclass == STATIC) p->x.name = stringf("L%s%d", NamePrefix, genlabel(1)); else if (p->generated) p->x.name = stringf("L%s%s", NamePrefix, p->name); else p->x.name = stringf("_%s", p->name); p->x.adrmode = 'C'; }
static Tree addrtree(Tree e, long n, Type ty) { Symbol p = e->u.sym, q; if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) NEW0(q, PERM); else NEW0(q, FUNC); q->name = stringd(genlabel(1)); q->sclass = p->sclass; q->scope = p->scope; assert(isptr(ty) || isarray(ty)); q->type = isptr(ty) ? ty->type : ty; q->temporary = p->temporary; q->generated = p->generated; q->addressed = p->addressed; q->computed = 1; q->defined = 1; q->ref = 1; assert(IR->address); if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) { if (p->sclass == AUTO) q->sclass = STATIC; (*IR->address)(q, p, n); } else { Code cp; addlocal(p); cp = code(Address); cp->u.addr.sym = q; cp->u.addr.base = p; cp->u.addr.offset = n; } e = tree(e->op, ty, NULL, NULL); e->u.sym = q; return e; }
static void I(defsymbol)(Symbol p) { if (p->scope == CONSTANTS) switch (optype(ttob(p->type))) { case I: p->x.name = stringf("%D", p->u.c.v.i); break; case U: p->x.name = stringf("%U", p->u.c.v.u); break; case P: p->x.name = stringf("%U", p->u.c.v.p); break; case F: { // JDC: added this to get inline floats floatint_t temp; temp.f = p->u.c.v.d; p->x.name = stringf("%U", temp.ui ); } break;// JDC: added this default: assert(0); } else if (p->scope >= LOCAL && p->sclass == STATIC) p->x.name = stringf("$%d", genlabel(1)); else if (p->scope == LABELS || p->generated) p->x.name = stringf("$%s", p->name); else p->x.name = p->name; }
void statement(int loop, Swtch swp, int lev) { float ref = refinc; if (Aflag >= 2 && lev == 15) warning("more than 15 levels of nested statements\n"); switch (t) { case IF: ifstmt(genlabel(2), loop, swp, lev + 1); break; case WHILE: whilestmt(genlabel(3), swp, lev + 1); break; case DO: dostmt(genlabel(3), swp, lev + 1); expect(';'); break; case FOR: forstmt(genlabel(4), swp, lev + 1); break; case BREAK: walk(NULL, 0, 0); definept(NULL); if (swp && swp->lab > loop) branch(swp->lab + 1); else if (loop) branch(loop + 2); else error("illegal break statement\n"); t = gettok(); expect(';'); break; case CONTINUE: walk(NULL, 0, 0); definept(NULL); if (loop) branch(loop + 1); else error("illegal continue statement\n"); t = gettok(); expect(';'); break; case SWITCH: swstmt(loop, genlabel(2), lev + 1); break; case CASE: { int lab = genlabel(1); if (swp == NULL) error("illegal case label\n"); definelab(lab); while (t == CASE) { static char stop[] = { IF, ID, 0 }; Tree p; t = gettok(); p = constexpr(0); if (generic(p->op) == CNST && isint(p->type)) { if (swp) { needconst++; p = cast(p, swp->sym->type); if (p->type->op == UNSIGNED) p->u.v.i = extend(p->u.v.u, p->type); needconst--; caselabel(swp, p->u.v.i, lab); } } else error("case label must be a constant integer expression\n"); test(':', stop); } statement(loop, swp, lev); } break; case DEFAULT: if (swp == NULL) error("illegal default label\n"); else if (swp->deflab) error("extra default label\n"); else { swp->deflab = findlabel(swp->lab); definelab(swp->deflab->u.l.label); } t = gettok(); expect(':'); statement(loop, swp, lev); break; case RETURN: { Type rty = freturn(cfunc->type); t = gettok(); definept(NULL); if (t != ';') if (rty == voidtype) { error("extraneous return value\n"); expr(0); retcode(NULL); } else retcode(expr(0)); else { if (rty != voidtype) warning("missing return value\n"); retcode(NULL); } branch(cfunc->u.f.label); } expect(';'); break; case '{': compound(loop, swp, lev + 1); break; case ';': definept(NULL); t = gettok(); break; case GOTO: walk(NULL, 0, 0); definept(NULL); t = gettok(); if (t == ID) { Symbol p = lookup(token, stmtlabs); if (p == NULL) { p = install(token, &stmtlabs, 0, FUNC); p->scope = LABELS; p->u.l.label = genlabel(1); p->src = src; } use(p, src); branch(p->u.l.label); t = gettok(); } else error("missing label in goto\n"); expect(';'); break; case ID: if (getchr() == ':') { stmtlabel(); statement(loop, swp, lev); break; } default: definept(NULL); if (kind[t] != ID) { error("unrecognized statement\n"); t = gettok(); } else { Tree e = expr0(0); listnodes(e, 0, 0); if (nodecount == 0 || nodecount > 200) walk(NULL, 0, 0); else if (glevel) walk(NULL, 0, 0); deallocate(STMT); } expect(';'); break; } if (kind[t] != IF && kind[t] != ID && t != '}' && t != EOI) { static char stop[] = { IF, ID, '}', 0 }; error("illegal statement termination\n"); skipto(0, stop); } refinc = ref; }
void swcode(Swtch swp, int b[], int lb, int ub) { int hilab, lolab, l, u, k = (lb + ub)/2; long *v = swp->values; if (k > lb && k < ub) { lolab = genlabel(1); hilab = genlabel(1); } else if (k > lb) { lolab = genlabel(1); hilab = swp->deflab->u.l.label; } else if (k < ub) { lolab = swp->deflab->u.l.label; hilab = genlabel(1); } else lolab = hilab = swp->deflab->u.l.label; l = b[k]; u = b[k+1] - 1; if (u - l + 1 <= 3) { int i; for (i = l; i <= u; i++) cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label); if (k > lb && k < ub) cmp(GT, swp->sym, v[u], hilab); else if (k > lb) cmp(GT, swp->sym, v[u], hilab); else if (k < ub) cmp(LT, swp->sym, v[l], lolab); else assert(lolab == hilab), branch(lolab); walk(NULL, 0, 0); } else { Tree e; Type ty = signedint(swp->sym->type); Symbol table = genident(STATIC, array(voidptype, u - l + 1, 0), GLOBAL); (*IR->defsymbol)(table); if (!isunsigned(swp->sym->type) || v[l] != 0) cmp(LT, swp->sym, v[l], lolab); cmp(GT, swp->sym, v[u], hilab); e = (*optree['-'])(SUB, cast(idtree(swp->sym), ty), cnsttree(ty, v[l])); if (e->type->size < unsignedptr->size) e = cast(e, unsignedlong); walk(tree(JUMP, voidtype, rvalue((*optree['+'])(ADD, pointer(idtree(table)), e)), NULL), 0, 0); code(Switch); codelist->u.swtch.table = table; codelist->u.swtch.sym = swp->sym; codelist->u.swtch.deflab = swp->deflab; codelist->u.swtch.size = u - l + 1; codelist->u.swtch.values = &v[l]; codelist->u.swtch.labels = &swp->labels[l]; if (v[u] - v[l] + 1 >= 10000) warning("switch generates a huge table\n"); } if (k > lb) { assert(lolab != swp->deflab->u.l.label); definelab(lolab); swcode(swp, b, lb, k - 1); } if (k < ub) { assert(hilab != swp->deflab->u.l.label); definelab(hilab); swcode(swp, b, k + 1, ub); } }