OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.23/] [lcc/] [src/] [stmt.c] - Diff between revs 4 and 157

Only display areas with differences | Details | Blame | View Log

Rev 4 Rev 157
#include "c.h"
#include "c.h"
 
 
static char rcsid[] = "$Id: stmt.c,v 1.1 2002/08/28 23:12:46 drh Exp $";
static char rcsid[] = "$Id: stmt.c,v 1.1 2002/08/28 23:12:46 drh Exp $";
 
 
#define SWSIZE 512
#define SWSIZE 512
 
 
#define den(i,j) ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1))
#define den(i,j) ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1))
 
 
struct code codehead = { Start };
struct code codehead = { Start };
Code codelist = &codehead;
Code codelist = &codehead;
float density = 0.5;
float density = 0.5;
Table stmtlabs;
Table stmtlabs;
 
 
static int foldcond(Tree e1, Tree e2);
static int foldcond(Tree e1, Tree e2);
static void caselabel(Swtch, long, int);
static void caselabel(Swtch, long, int);
static void cmp(int, Symbol, long, int);
static void cmp(int, Symbol, long, int);
static Tree conditional(int);
static Tree conditional(int);
static void dostmt(int, Swtch, int);
static void dostmt(int, Swtch, int);
static int equal(Symbol, Symbol);
static int equal(Symbol, Symbol);
static void forstmt(int, Swtch, int);
static void forstmt(int, Swtch, int);
static void ifstmt(int, int, Swtch, int);
static void ifstmt(int, int, Swtch, int);
static Symbol localaddr(Tree);
static Symbol localaddr(Tree);
static void stmtlabel(void);
static void stmtlabel(void);
static void swstmt(int, int, int);
static void swstmt(int, int, int);
static void whilestmt(int, Swtch, int);
static void whilestmt(int, Swtch, int);
Code code(int kind) {
Code code(int kind) {
        Code cp;
        Code cp;
 
 
        if (!reachable(kind))
        if (!reachable(kind))
                warning("unreachable code\n");
                warning("unreachable code\n");
 
 
        NEW(cp, FUNC);
        NEW(cp, FUNC);
        cp->kind = kind;
        cp->kind = kind;
        cp->prev = codelist;
        cp->prev = codelist;
        cp->next = NULL;
        cp->next = NULL;
        codelist->next = cp;
        codelist->next = cp;
        codelist = cp;
        codelist = cp;
        return cp;
        return cp;
}
}
int reachable(int kind) {
int reachable(int kind) {
        Code cp;
        Code cp;
 
 
        if (kind > Start) {
        if (kind > Start) {
                Code cp;
                Code cp;
                for (cp = codelist; cp->kind < Label; )
                for (cp = codelist; cp->kind < Label; )
                        cp = cp->prev;
                        cp = cp->prev;
                if (cp->kind == Jump || cp->kind == Switch)
                if (cp->kind == Jump || cp->kind == Switch)
                        return 0;
                        return 0;
        }
        }
        return 1;
        return 1;
}
}
void addlocal(Symbol p) {
void addlocal(Symbol p) {
        if (!p->defined) {
        if (!p->defined) {
                code(Local)->u.var = p;
                code(Local)->u.var = p;
                p->defined = 1;
                p->defined = 1;
                p->scope = level;
                p->scope = level;
        }
        }
}
}
void definept(Coordinate *p) {
void definept(Coordinate *p) {
        Code cp = code(Defpoint);
        Code cp = code(Defpoint);
 
 
        cp->u.point.src = p ? *p : src;
        cp->u.point.src = p ? *p : src;
        cp->u.point.point = npoints;
        cp->u.point.point = npoints;
        if (ncalled > 0) {
        if (ncalled > 0) {
                int n = findcount(cp->u.point.src.file,
                int n = findcount(cp->u.point.src.file,
                        cp->u.point.src.x, cp->u.point.src.y);
                        cp->u.point.src.x, cp->u.point.src.y);
                if (n > 0)
                if (n > 0)
                        refinc = (float)n/ncalled;
                        refinc = (float)n/ncalled;
        }
        }
        if (glevel > 2) locus(identifiers, &cp->u.point.src);
        if (glevel > 2) locus(identifiers, &cp->u.point.src);
        if (events.points && reachable(Gen))
        if (events.points && reachable(Gen))
                {
                {
                        Tree e = NULL;
                        Tree e = NULL;
                        apply(events.points, &cp->u.point.src, &e);
                        apply(events.points, &cp->u.point.src, &e);
                        if (e)
                        if (e)
                                listnodes(e, 0, 0);
                                listnodes(e, 0, 0);
                }
                }
}
}
void statement(int loop, Swtch swp, int lev) {
void statement(int loop, Swtch swp, int lev) {
        float ref = refinc;
        float ref = refinc;
 
 
        if (Aflag >= 2 && lev == 15)
        if (Aflag >= 2 && lev == 15)
                warning("more than 15 levels of nested statements\n");
                warning("more than 15 levels of nested statements\n");
        switch (t) {
        switch (t) {
        case IF:       ifstmt(genlabel(2), loop, swp, lev + 1);
        case IF:       ifstmt(genlabel(2), loop, swp, lev + 1);
 break;
 break;
        case WHILE:    whilestmt(genlabel(3), swp, lev + 1); break;
        case WHILE:    whilestmt(genlabel(3), swp, lev + 1); break;
        case DO:       dostmt(genlabel(3), swp, lev + 1); expect(';');
        case DO:       dostmt(genlabel(3), swp, lev + 1); expect(';');
                                        break;
                                        break;
 
 
        case FOR:      forstmt(genlabel(4), swp, lev + 1);
        case FOR:      forstmt(genlabel(4), swp, lev + 1);
 break;
 break;
        case BREAK:    walk(NULL, 0, 0);
        case BREAK:    walk(NULL, 0, 0);
                       definept(NULL);
                       definept(NULL);
                       if (swp && swp->lab > loop)
                       if (swp && swp->lab > loop)
                        branch(swp->lab + 1);
                        branch(swp->lab + 1);
                       else if (loop)
                       else if (loop)
                        branch(loop + 2);
                        branch(loop + 2);
                       else
                       else
                        error("illegal break statement\n");
                        error("illegal break statement\n");
                       t = gettok(); expect(';');
                       t = gettok(); expect(';');
                                           break;
                                           break;
 
 
        case CONTINUE: walk(NULL, 0, 0);
        case CONTINUE: walk(NULL, 0, 0);
                       definept(NULL);
                       definept(NULL);
                       if (loop)
                       if (loop)
                        branch(loop + 1);
                        branch(loop + 1);
                       else
                       else
                        error("illegal continue statement\n");
                        error("illegal continue statement\n");
                       t = gettok(); expect(';');
                       t = gettok(); expect(';');
                                              break;
                                              break;
 
 
        case SWITCH:   swstmt(loop, genlabel(2), lev + 1);
        case SWITCH:   swstmt(loop, genlabel(2), lev + 1);
 break;
 break;
        case CASE:     {
        case CASE:     {
                        int lab = genlabel(1);
                        int lab = genlabel(1);
                        if (swp == NULL)
                        if (swp == NULL)
                                error("illegal case label\n");
                                error("illegal case label\n");
                        definelab(lab);
                        definelab(lab);
                        while (t == CASE) {
                        while (t == CASE) {
                                static char stop[] = { IF, ID, 0 };
                                static char stop[] = { IF, ID, 0 };
                                Tree p;
                                Tree p;
                                t = gettok();
                                t = gettok();
                                p = constexpr(0);
                                p = constexpr(0);
                                if (generic(p->op) == CNST && isint(p->type)) {
                                if (generic(p->op) == CNST && isint(p->type)) {
                                        if (swp) {
                                        if (swp) {
                                                needconst++;
                                                needconst++;
                                                p = cast(p, swp->sym->type);
                                                p = cast(p, swp->sym->type);
                                                if (p->type->op == UNSIGNED)
                                                if (p->type->op == UNSIGNED)
                                                        p->u.v.i = extend(p->u.v.u, p->type);
                                                        p->u.v.i = extend(p->u.v.u, p->type);
                                                needconst--;
                                                needconst--;
                                                caselabel(swp, p->u.v.i, lab);
                                                caselabel(swp, p->u.v.i, lab);
                                        }
                                        }
                                } else
                                } else
                                        error("case label must be a constant integer expression\n");
                                        error("case label must be a constant integer expression\n");
 
 
                                test(':', stop);
                                test(':', stop);
                        }
                        }
                        statement(loop, swp, lev);
                        statement(loop, swp, lev);
                       } break;
                       } break;
        case DEFAULT:  if (swp == NULL)
        case DEFAULT:  if (swp == NULL)
                        error("illegal default label\n");
                        error("illegal default label\n");
                       else if (swp->deflab)
                       else if (swp->deflab)
                        error("extra default label\n");
                        error("extra default label\n");
                       else {
                       else {
                        swp->deflab = findlabel(swp->lab);
                        swp->deflab = findlabel(swp->lab);
                        definelab(swp->deflab->u.l.label);
                        definelab(swp->deflab->u.l.label);
                       }
                       }
                       t = gettok();
                       t = gettok();
                       expect(':');
                       expect(':');
                       statement(loop, swp, lev); break;
                       statement(loop, swp, lev); break;
        case RETURN:   {
        case RETURN:   {
                        Type rty = freturn(cfunc->type);
                        Type rty = freturn(cfunc->type);
                        t = gettok();
                        t = gettok();
                        definept(NULL);
                        definept(NULL);
                        if (t != ';')
                        if (t != ';')
                                if (rty == voidtype) {
                                if (rty == voidtype) {
                                        error("extraneous return value\n");
                                        error("extraneous return value\n");
                                        expr(0);
                                        expr(0);
                                        retcode(NULL);
                                        retcode(NULL);
                                } else
                                } else
                                        retcode(expr(0));
                                        retcode(expr(0));
                        else {
                        else {
                                if (rty != voidtype) {
                                if (rty != voidtype) {
                                        warning("missing return value\n");
                                        warning("missing return value\n");
                                        retcode(cnsttree(inttype, 0L));
                                        retcode(cnsttree(inttype, 0L));
                                } else
                                } else
                                        retcode(NULL);
                                        retcode(NULL);
                        }
                        }
                        branch(cfunc->u.f.label);
                        branch(cfunc->u.f.label);
                       } expect(';');
                       } expect(';');
                                            break;
                                            break;
 
 
        case '{':      compound(loop, swp, lev + 1); break;
        case '{':      compound(loop, swp, lev + 1); break;
        case ';':      definept(NULL); t = gettok(); break;
        case ';':      definept(NULL); t = gettok(); break;
        case GOTO:     walk(NULL, 0, 0);
        case GOTO:     walk(NULL, 0, 0);
                       definept(NULL);
                       definept(NULL);
                       t = gettok();
                       t = gettok();
                       if (t == ID) {
                       if (t == ID) {
                        Symbol p = lookup(token, stmtlabs);
                        Symbol p = lookup(token, stmtlabs);
                        if (p == NULL) {
                        if (p == NULL) {
                                p = install(token, &stmtlabs, 0, FUNC);
                                p = install(token, &stmtlabs, 0, FUNC);
                                p->scope = LABELS;
                                p->scope = LABELS;
                                p->u.l.label = genlabel(1);
                                p->u.l.label = genlabel(1);
                                p->src = src;
                                p->src = src;
                        }
                        }
                        use(p, src);
                        use(p, src);
                        branch(p->u.l.label);
                        branch(p->u.l.label);
                        t = gettok();
                        t = gettok();
                       } else
                       } else
                        error("missing label in goto\n"); expect(';');
                        error("missing label in goto\n"); expect(';');
                                          break;
                                          break;
 
 
        case ID:       if (getchr() == ':') {
        case ID:       if (getchr() == ':') {
                        stmtlabel();
                        stmtlabel();
                        statement(loop, swp, lev);
                        statement(loop, swp, lev);
                        break;
                        break;
                       }
                       }
        default:       definept(NULL);
        default:       definept(NULL);
                       if (kind[t] != ID) {
                       if (kind[t] != ID) {
                        error("unrecognized statement\n");
                        error("unrecognized statement\n");
                        t = gettok();
                        t = gettok();
                       } else {
                       } else {
                        Tree e = expr0(0);
                        Tree e = expr0(0);
                        listnodes(e, 0, 0);
                        listnodes(e, 0, 0);
                        if (nodecount == 0 || nodecount > 200)
                        if (nodecount == 0 || nodecount > 200)
                                walk(NULL, 0, 0);
                                walk(NULL, 0, 0);
                        else if (glevel) walk(NULL, 0, 0);
                        else if (glevel) walk(NULL, 0, 0);
                        deallocate(STMT);
                        deallocate(STMT);
                       } expect(';');
                       } expect(';');
                                                break;
                                                break;
 
 
        }
        }
        if (kind[t] != IF && kind[t] != ID
        if (kind[t] != IF && kind[t] != ID
        && t != '}' && t != EOI) {
        && t != '}' && t != EOI) {
                static char stop[] = { IF, ID, '}', 0 };
                static char stop[] = { IF, ID, '}', 0 };
                error("illegal statement termination\n");
                error("illegal statement termination\n");
                skipto(0, stop);
                skipto(0, stop);
        }
        }
        refinc = ref;
        refinc = ref;
}
}
 
 
static void ifstmt(int lab, int loop, Swtch swp, int lev) {
static void ifstmt(int lab, int loop, Swtch swp, int lev) {
        t = gettok();
        t = gettok();
        expect('(');
        expect('(');
        definept(NULL);
        definept(NULL);
        walk(conditional(')'), 0, lab);
        walk(conditional(')'), 0, lab);
        refinc /= 2.0;
        refinc /= 2.0;
        statement(loop, swp, lev);
        statement(loop, swp, lev);
        if (t == ELSE) {
        if (t == ELSE) {
                branch(lab + 1);
                branch(lab + 1);
                t = gettok();
                t = gettok();
                definelab(lab);
                definelab(lab);
                statement(loop, swp, lev);
                statement(loop, swp, lev);
                if (findlabel(lab + 1)->ref)
                if (findlabel(lab + 1)->ref)
                        definelab(lab + 1);
                        definelab(lab + 1);
        } else
        } else
                definelab(lab);
                definelab(lab);
}
}
static Tree conditional(int tok) {
static Tree conditional(int tok) {
        Tree p = expr(tok);
        Tree p = expr(tok);
 
 
        if (Aflag > 1 && isfunc(p->type))
        if (Aflag > 1 && isfunc(p->type))
                warning("%s used in a conditional expression\n",
                warning("%s used in a conditional expression\n",
                        funcname(p));
                        funcname(p));
        return cond(p);
        return cond(p);
}
}
static void stmtlabel(void) {
static void stmtlabel(void) {
        Symbol p = lookup(token, stmtlabs);
        Symbol p = lookup(token, stmtlabs);
 
 
        if (p == NULL) {
        if (p == NULL) {
                p = install(token, &stmtlabs, 0, FUNC);
                p = install(token, &stmtlabs, 0, FUNC);
                p->scope = LABELS;
                p->scope = LABELS;
                p->u.l.label = genlabel(1);
                p->u.l.label = genlabel(1);
                p->src = src;
                p->src = src;
        }
        }
        if (p->defined)
        if (p->defined)
                error("redefinition of label `%s' previously defined at %w\n", p->name, &p->src);
                error("redefinition of label `%s' previously defined at %w\n", p->name, &p->src);
 
 
        p->defined = 1;
        p->defined = 1;
        definelab(p->u.l.label);
        definelab(p->u.l.label);
        t = gettok();
        t = gettok();
        expect(':');
        expect(':');
}
}
static void forstmt(int lab, Swtch swp, int lev) {
static void forstmt(int lab, Swtch swp, int lev) {
        int once = 0;
        int once = 0;
        Tree e1 = NULL, e2 = NULL, e3 = NULL;
        Tree e1 = NULL, e2 = NULL, e3 = NULL;
        Coordinate pt2, pt3;
        Coordinate pt2, pt3;
 
 
        t = gettok();
        t = gettok();
        expect('(');
        expect('(');
        definept(NULL);
        definept(NULL);
        if (kind[t] == ID)
        if (kind[t] == ID)
                e1 = texpr(expr0, ';', FUNC);
                e1 = texpr(expr0, ';', FUNC);
        else
        else
                expect(';');
                expect(';');
        walk(e1, 0, 0);
        walk(e1, 0, 0);
        pt2 = src;
        pt2 = src;
        refinc *= 10.0;
        refinc *= 10.0;
        if (kind[t] == ID)
        if (kind[t] == ID)
                e2 = texpr(conditional, ';', FUNC);
                e2 = texpr(conditional, ';', FUNC);
        else
        else
                expect(';');
                expect(';');
        pt3 = src;
        pt3 = src;
        if (kind[t] == ID)
        if (kind[t] == ID)
                e3 = texpr(expr0, ')', FUNC);
                e3 = texpr(expr0, ')', FUNC);
        else {
        else {
                static char stop[] = { IF, ID, '}', 0 };
                static char stop[] = { IF, ID, '}', 0 };
                test(')', stop);
                test(')', stop);
        }
        }
        if (e2) {
        if (e2) {
                once = foldcond(e1, e2);
                once = foldcond(e1, e2);
                if (!once)
                if (!once)
                        branch(lab + 3);
                        branch(lab + 3);
        }
        }
        definelab(lab);
        definelab(lab);
        statement(lab, swp, lev);
        statement(lab, swp, lev);
        definelab(lab + 1);
        definelab(lab + 1);
        definept(&pt3);
        definept(&pt3);
        if (e3)
        if (e3)
                walk(e3, 0, 0);
                walk(e3, 0, 0);
        if (e2) {
        if (e2) {
                if (!once)
                if (!once)
                        definelab(lab + 3);
                        definelab(lab + 3);
                definept(&pt2);
                definept(&pt2);
                walk(e2, lab, 0);
                walk(e2, lab, 0);
        } else {
        } else {
                definept(&pt2);
                definept(&pt2);
                branch(lab);
                branch(lab);
        }
        }
        if (findlabel(lab + 2)->ref)
        if (findlabel(lab + 2)->ref)
                definelab(lab + 2);
                definelab(lab + 2);
}
}
static void swstmt(int loop, int lab, int lev) {
static void swstmt(int loop, int lab, int lev) {
        Tree e;
        Tree e;
        struct swtch sw;
        struct swtch sw;
        Code head, tail;
        Code head, tail;
 
 
        t = gettok();
        t = gettok();
        expect('(');
        expect('(');
        definept(NULL);
        definept(NULL);
        e = expr(')');
        e = expr(')');
        if (!isint(e->type)) {
        if (!isint(e->type)) {
                error("illegal type `%t' in switch expression\n",
                error("illegal type `%t' in switch expression\n",
                        e->type);
                        e->type);
                e = retype(e, inttype);
                e = retype(e, inttype);
        }
        }
        e = cast(e, promote(e->type));
        e = cast(e, promote(e->type));
        if (generic(e->op) == INDIR && isaddrop(e->kids[0]->op)
        if (generic(e->op) == INDIR && isaddrop(e->kids[0]->op)
        && e->kids[0]->u.sym->type == e->type
        && e->kids[0]->u.sym->type == e->type
        && !isvolatile(e->kids[0]->u.sym->type)) {
        && !isvolatile(e->kids[0]->u.sym->type)) {
                sw.sym = e->kids[0]->u.sym;
                sw.sym = e->kids[0]->u.sym;
                walk(NULL, 0, 0);
                walk(NULL, 0, 0);
        } else {
        } else {
                sw.sym = genident(REGISTER, e->type, level);
                sw.sym = genident(REGISTER, e->type, level);
                addlocal(sw.sym);
                addlocal(sw.sym);
                walk(asgn(sw.sym, e), 0, 0);
                walk(asgn(sw.sym, e), 0, 0);
        }
        }
        head = code(Switch);
        head = code(Switch);
        sw.lab = lab;
        sw.lab = lab;
        sw.deflab = NULL;
        sw.deflab = NULL;
        sw.ncases = 0;
        sw.ncases = 0;
        sw.size = SWSIZE;
        sw.size = SWSIZE;
        sw.values = newarray(SWSIZE, sizeof *sw.values, FUNC);
        sw.values = newarray(SWSIZE, sizeof *sw.values, FUNC);
        sw.labels = newarray(SWSIZE, sizeof *sw.labels, FUNC);
        sw.labels = newarray(SWSIZE, sizeof *sw.labels, FUNC);
        refinc /= 10.0;
        refinc /= 10.0;
        statement(loop, &sw, lev);
        statement(loop, &sw, lev);
        if (sw.deflab == NULL) {
        if (sw.deflab == NULL) {
                sw.deflab = findlabel(lab);
                sw.deflab = findlabel(lab);
                definelab(lab);
                definelab(lab);
                if (sw.ncases == 0)
                if (sw.ncases == 0)
                        warning("switch statement with no cases\n");
                        warning("switch statement with no cases\n");
        }
        }
        if (findlabel(lab + 1)->ref)
        if (findlabel(lab + 1)->ref)
                definelab(lab + 1);
                definelab(lab + 1);
        tail = codelist;
        tail = codelist;
        codelist = head->prev;
        codelist = head->prev;
        codelist->next = head->prev = NULL;
        codelist->next = head->prev = NULL;
        if (sw.ncases > 0)
        if (sw.ncases > 0)
                swgen(&sw);
                swgen(&sw);
        branch(lab);
        branch(lab);
        head->next->prev = codelist;
        head->next->prev = codelist;
        codelist->next = head->next;
        codelist->next = head->next;
        codelist = tail;
        codelist = tail;
}
}
static void caselabel(Swtch swp, long val, int lab) {
static void caselabel(Swtch swp, long val, int lab) {
        int k;
        int k;
 
 
        if (swp->ncases >= swp->size)
        if (swp->ncases >= swp->size)
                {
                {
                long   *vals = swp->values;
                long   *vals = swp->values;
                Symbol *labs = swp->labels;
                Symbol *labs = swp->labels;
                swp->size *= 2;
                swp->size *= 2;
                swp->values = newarray(swp->size, sizeof *swp->values, FUNC);
                swp->values = newarray(swp->size, sizeof *swp->values, FUNC);
                swp->labels = newarray(swp->size, sizeof *swp->labels, FUNC);
                swp->labels = newarray(swp->size, sizeof *swp->labels, FUNC);
                for (k = 0; k < swp->ncases; k++) {
                for (k = 0; k < swp->ncases; k++) {
                        swp->values[k] = vals[k];
                        swp->values[k] = vals[k];
                        swp->labels[k] = labs[k];
                        swp->labels[k] = labs[k];
                }
                }
                }
                }
        k = swp->ncases;
        k = swp->ncases;
        for ( ; k > 0 && swp->values[k-1] >= val; k--) {
        for ( ; k > 0 && swp->values[k-1] >= val; k--) {
                swp->values[k] = swp->values[k-1];
                swp->values[k] = swp->values[k-1];
                swp->labels[k] = swp->labels[k-1];
                swp->labels[k] = swp->labels[k-1];
        }
        }
        if (k < swp->ncases && swp->values[k] == val)
        if (k < swp->ncases && swp->values[k] == val)
                error("duplicate case label `%d'\n", val);
                error("duplicate case label `%d'\n", val);
        swp->values[k] = val;
        swp->values[k] = val;
        swp->labels[k] = findlabel(lab);
        swp->labels[k] = findlabel(lab);
        ++swp->ncases;
        ++swp->ncases;
        if (Aflag >= 2 && swp->ncases == 258)
        if (Aflag >= 2 && swp->ncases == 258)
                warning("more than 257 cases in a switch\n");
                warning("more than 257 cases in a switch\n");
}
}
void swgen(Swtch swp) {
void swgen(Swtch swp) {
        int *buckets, k, n;
        int *buckets, k, n;
        long *v = swp->values;
        long *v = swp->values;
 
 
        buckets = newarray(swp->ncases + 1,
        buckets = newarray(swp->ncases + 1,
                sizeof *buckets, FUNC);
                sizeof *buckets, FUNC);
        for (n = k = 0; k < swp->ncases; k++, n++) {
        for (n = k = 0; k < swp->ncases; k++, n++) {
                buckets[n] = k;
                buckets[n] = k;
                while (n > 0 && den(n-1, k) >= density)
                while (n > 0 && den(n-1, k) >= density)
                        n--;
                        n--;
        }
        }
        buckets[n] = swp->ncases;
        buckets[n] = swp->ncases;
        swcode(swp, buckets, 0, n - 1);
        swcode(swp, buckets, 0, n - 1);
}
}
void swcode(Swtch swp, int b[], int lb, int ub) {
void swcode(Swtch swp, int b[], int lb, int ub) {
        int hilab, lolab, l, u, k = (lb + ub)/2;
        int hilab, lolab, l, u, k = (lb + ub)/2;
        long *v = swp->values;
        long *v = swp->values;
 
 
        if (k > lb && k < ub) {
        if (k > lb && k < ub) {
                lolab = genlabel(1);
                lolab = genlabel(1);
                hilab = genlabel(1);
                hilab = genlabel(1);
        } else if (k > lb) {
        } else if (k > lb) {
                lolab = genlabel(1);
                lolab = genlabel(1);
                hilab = swp->deflab->u.l.label;
                hilab = swp->deflab->u.l.label;
        } else if (k < ub) {
        } else if (k < ub) {
                lolab = swp->deflab->u.l.label;
                lolab = swp->deflab->u.l.label;
                hilab = genlabel(1);
                hilab = genlabel(1);
        } else
        } else
                lolab = hilab = swp->deflab->u.l.label;
                lolab = hilab = swp->deflab->u.l.label;
        l = b[k];
        l = b[k];
        u = b[k+1] - 1;
        u = b[k+1] - 1;
        if (u - l + 1 <= 3)
        if (u - l + 1 <= 3)
                {
                {
                        int i;
                        int i;
                        for (i = l; i <= u; i++)
                        for (i = l; i <= u; i++)
                                cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label);
                                cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label);
                        if (k > lb && k < ub)
                        if (k > lb && k < ub)
                                cmp(GT, swp->sym, v[u], hilab);
                                cmp(GT, swp->sym, v[u], hilab);
                        else if (k > lb)
                        else if (k > lb)
                                cmp(GT, swp->sym, v[u], hilab);
                                cmp(GT, swp->sym, v[u], hilab);
                        else if (k < ub)
                        else if (k < ub)
                                cmp(LT, swp->sym, v[l], lolab);
                                cmp(LT, swp->sym, v[l], lolab);
                        else
                        else
                                assert(lolab == hilab),
                                assert(lolab == hilab),
                                branch(lolab);
                                branch(lolab);
                        walk(NULL, 0, 0);
                        walk(NULL, 0, 0);
                }
                }
        else {
        else {
                Tree e;
                Tree e;
                Type ty = signedint(swp->sym->type);
                Type ty = signedint(swp->sym->type);
                Symbol table = genident(STATIC,
                Symbol table = genident(STATIC,
                        array(voidptype, u - l + 1, 0), GLOBAL);
                        array(voidptype, u - l + 1, 0), GLOBAL);
                (*IR->defsymbol)(table);
                (*IR->defsymbol)(table);
                if (!isunsigned(swp->sym->type) || v[l] != 0)
                if (!isunsigned(swp->sym->type) || v[l] != 0)
                        cmp(LT, swp->sym, v[l], lolab);
                        cmp(LT, swp->sym, v[l], lolab);
                cmp(GT, swp->sym, v[u], hilab);
                cmp(GT, swp->sym, v[u], hilab);
                e = (*optree['-'])(SUB, cast(idtree(swp->sym), ty), cnsttree(ty, v[l]));
                e = (*optree['-'])(SUB, cast(idtree(swp->sym), ty), cnsttree(ty, v[l]));
                if (e->type->size < unsignedptr->size)
                if (e->type->size < unsignedptr->size)
                        e = cast(e, unsignedlong);
                        e = cast(e, unsignedlong);
                walk(tree(JUMP, voidtype,
                walk(tree(JUMP, voidtype,
                        rvalue((*optree['+'])(ADD, pointer(idtree(table)), e)), NULL),
                        rvalue((*optree['+'])(ADD, pointer(idtree(table)), e)), NULL),
                        0, 0);
                        0, 0);
                code(Switch);
                code(Switch);
                codelist->u.swtch.table = table;
                codelist->u.swtch.table = table;
                codelist->u.swtch.sym = swp->sym;
                codelist->u.swtch.sym = swp->sym;
                codelist->u.swtch.deflab = swp->deflab;
                codelist->u.swtch.deflab = swp->deflab;
                codelist->u.swtch.size = u - l + 1;
                codelist->u.swtch.size = u - l + 1;
                codelist->u.swtch.values = &v[l];
                codelist->u.swtch.values = &v[l];
                codelist->u.swtch.labels = &swp->labels[l];
                codelist->u.swtch.labels = &swp->labels[l];
                if (v[u] - v[l] + 1 >= 10000)
                if (v[u] - v[l] + 1 >= 10000)
                        warning("switch generates a huge table\n");
                        warning("switch generates a huge table\n");
        }
        }
        if (k > lb) {
        if (k > lb) {
                assert(lolab != swp->deflab->u.l.label);
                assert(lolab != swp->deflab->u.l.label);
                definelab(lolab);
                definelab(lolab);
                swcode(swp, b, lb, k - 1);
                swcode(swp, b, lb, k - 1);
        }
        }
        if (k < ub) {
        if (k < ub) {
                assert(hilab != swp->deflab->u.l.label);
                assert(hilab != swp->deflab->u.l.label);
                definelab(hilab);
                definelab(hilab);
                swcode(swp, b, k + 1, ub);
                swcode(swp, b, k + 1, ub);
        }
        }
}
}
static void cmp(int op, Symbol p, long n, int lab) {
static void cmp(int op, Symbol p, long n, int lab) {
        Type ty = signedint(p->type);
        Type ty = signedint(p->type);
 
 
        listnodes(eqtree(op,
        listnodes(eqtree(op,
                        cast(idtree(p), ty),
                        cast(idtree(p), ty),
                        cnsttree(ty, n)),
                        cnsttree(ty, n)),
                lab, 0);
                lab, 0);
}
}
void retcode(Tree p) {
void retcode(Tree p) {
        Type ty;
        Type ty;
 
 
        if (p == NULL) {
        if (p == NULL) {
                if (events.returns)
                if (events.returns)
                        apply(events.returns, cfunc, NULL);
                        apply(events.returns, cfunc, NULL);
                return;
                return;
        }
        }
        p = pointer(p);
        p = pointer(p);
        ty = assign(freturn(cfunc->type), p);
        ty = assign(freturn(cfunc->type), p);
        if (ty == NULL) {
        if (ty == NULL) {
                error("illegal return type; found `%t' expected `%t'\n",
                error("illegal return type; found `%t' expected `%t'\n",
                        p->type, freturn(cfunc->type));
                        p->type, freturn(cfunc->type));
                return;
                return;
        }
        }
        p = cast(p, ty);
        p = cast(p, ty);
        if (retv)
        if (retv)
                {
                {
                        if (iscallb(p))
                        if (iscallb(p))
                                p = tree(RIGHT, p->type,
                                p = tree(RIGHT, p->type,
                                        tree(CALL+B, p->type,
                                        tree(CALL+B, p->type,
                                                p->kids[0]->kids[0], idtree(retv)),
                                                p->kids[0]->kids[0], idtree(retv)),
                                        rvalue(idtree(retv)));
                                        rvalue(idtree(retv)));
                        else {
                        else {
                                Type ty = retv->type->type;
                                Type ty = retv->type->type;
                                assert(isstruct(ty));
                                assert(isstruct(ty));
                                if (ty->u.sym->u.s.cfields) {
                                if (ty->u.sym->u.s.cfields) {
                                        ty->u.sym->u.s.cfields = 0;
                                        ty->u.sym->u.s.cfields = 0;
                                        p = asgntree(ASGN, rvalue(idtree(retv)), p);
                                        p = asgntree(ASGN, rvalue(idtree(retv)), p);
                                        ty->u.sym->u.s.cfields = 1;
                                        ty->u.sym->u.s.cfields = 1;
                                } else
                                } else
                                        p = asgntree(ASGN, rvalue(idtree(retv)), p);
                                        p = asgntree(ASGN, rvalue(idtree(retv)), p);
                        }
                        }
                        walk(p, 0, 0);
                        walk(p, 0, 0);
                        if (events.returns)
                        if (events.returns)
                                apply(events.returns, cfunc, rvalue(idtree(retv)));
                                apply(events.returns, cfunc, rvalue(idtree(retv)));
                        return;
                        return;
                }
                }
        if (events.returns)
        if (events.returns)
                {
                {
                        Symbol t1 = genident(AUTO, p->type, level);
                        Symbol t1 = genident(AUTO, p->type, level);
                        addlocal(t1);
                        addlocal(t1);
                        walk(asgn(t1, p), 0, 0);
                        walk(asgn(t1, p), 0, 0);
                        apply(events.returns, cfunc, idtree(t1));
                        apply(events.returns, cfunc, idtree(t1));
                        p = idtree(t1);
                        p = idtree(t1);
                }
                }
        if (!isfloat(p->type))
        if (!isfloat(p->type))
                p = cast(p, promote(p->type));
                p = cast(p, promote(p->type));
        if (isptr(p->type))
        if (isptr(p->type))
                {
                {
                        Symbol q = localaddr(p);
                        Symbol q = localaddr(p);
                        if (q && (q->computed || q->generated))
                        if (q && (q->computed || q->generated))
                                warning("pointer to a %s is an illegal return value\n",
                                warning("pointer to a %s is an illegal return value\n",
                                        q->scope == PARAM ? "parameter" : "local");
                                        q->scope == PARAM ? "parameter" : "local");
                        else if (q)
                        else if (q)
                                warning("pointer to %s `%s' is an illegal return value\n",
                                warning("pointer to %s `%s' is an illegal return value\n",
                                        q->scope == PARAM ? "parameter" : "local", q->name);
                                        q->scope == PARAM ? "parameter" : "local", q->name);
                }
                }
        walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0);
        walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0);
}
}
void definelab(int lab) {
void definelab(int lab) {
        Code cp;
        Code cp;
        Symbol p = findlabel(lab);
        Symbol p = findlabel(lab);
 
 
        assert(lab);
        assert(lab);
        walk(NULL, 0, 0);
        walk(NULL, 0, 0);
        code(Label)->u.forest = newnode(LABEL+V, NULL, NULL, p);
        code(Label)->u.forest = newnode(LABEL+V, NULL, NULL, p);
        for (cp = codelist->prev; cp->kind <= Label; )
        for (cp = codelist->prev; cp->kind <= Label; )
                cp = cp->prev;
                cp = cp->prev;
        while (   cp->kind == Jump
        while (   cp->kind == Jump
               && cp->u.forest->kids[0]
               && cp->u.forest->kids[0]
               && specific(cp->u.forest->kids[0]->op) == ADDRG+P
               && specific(cp->u.forest->kids[0]->op) == ADDRG+P
               && cp->u.forest->kids[0]->syms[0] == p) {
               && cp->u.forest->kids[0]->syms[0] == p) {
                assert(cp->u.forest->kids[0]->syms[0]->u.l.label == lab);
                assert(cp->u.forest->kids[0]->syms[0]->u.l.label == lab);
                p->ref--;
                p->ref--;
                assert(cp->next);
                assert(cp->next);
                assert(cp->prev);
                assert(cp->prev);
                cp->prev->next = cp->next;
                cp->prev->next = cp->next;
                cp->next->prev = cp->prev;
                cp->next->prev = cp->prev;
                cp = cp->prev;
                cp = cp->prev;
                while (cp->kind <= Label)
                while (cp->kind <= Label)
                        cp = cp->prev;
                        cp = cp->prev;
        }
        }
}
}
Node jump(int lab) {
Node jump(int lab) {
        Symbol p = findlabel(lab);
        Symbol p = findlabel(lab);
 
 
        p->ref++;
        p->ref++;
        return newnode(JUMP+V, newnode(ADDRG+ttob(voidptype), NULL, NULL, p),
        return newnode(JUMP+V, newnode(ADDRG+ttob(voidptype), NULL, NULL, p),
                NULL, NULL);
                NULL, NULL);
}
}
void branch(int lab) {
void branch(int lab) {
        Code cp;
        Code cp;
        Symbol p = findlabel(lab);
        Symbol p = findlabel(lab);
 
 
        assert(lab);
        assert(lab);
        walk(NULL, 0, 0);
        walk(NULL, 0, 0);
        code(Label)->u.forest = jump(lab);
        code(Label)->u.forest = jump(lab);
        for (cp = codelist->prev; cp->kind < Label; )
        for (cp = codelist->prev; cp->kind < Label; )
                cp = cp->prev;
                cp = cp->prev;
        while (   cp->kind == Label
        while (   cp->kind == Label
               && cp->u.forest->op == LABEL+V
               && cp->u.forest->op == LABEL+V
               && !equal(cp->u.forest->syms[0], p)) {
               && !equal(cp->u.forest->syms[0], p)) {
                equatelab(cp->u.forest->syms[0], p);
                equatelab(cp->u.forest->syms[0], p);
                assert(cp->next);
                assert(cp->next);
                assert(cp->prev);
                assert(cp->prev);
                cp->prev->next = cp->next;
                cp->prev->next = cp->next;
                cp->next->prev = cp->prev;
                cp->next->prev = cp->prev;
                cp = cp->prev;
                cp = cp->prev;
                while (cp->kind < Label)
                while (cp->kind < Label)
                        cp = cp->prev;
                        cp = cp->prev;
        }
        }
        if (cp->kind == Jump || cp->kind == Switch) {
        if (cp->kind == Jump || cp->kind == Switch) {
                p->ref--;
                p->ref--;
                codelist->prev->next = NULL;
                codelist->prev->next = NULL;
                codelist = codelist->prev;
                codelist = codelist->prev;
        } else {
        } else {
                codelist->kind = Jump;
                codelist->kind = Jump;
                if (cp->kind == Label
                if (cp->kind == Label
                &&  cp->u.forest->op == LABEL+V
                &&  cp->u.forest->op == LABEL+V
                &&  equal(cp->u.forest->syms[0], p))
                &&  equal(cp->u.forest->syms[0], p))
                        warning("source code specifies an infinite loop\n");
                        warning("source code specifies an infinite loop\n");
        }
        }
}
}
void equatelab(Symbol old, Symbol new) {
void equatelab(Symbol old, Symbol new) {
        assert(old->u.l.equatedto == NULL);
        assert(old->u.l.equatedto == NULL);
        old->u.l.equatedto = new;
        old->u.l.equatedto = new;
        new->ref++;
        new->ref++;
}
}
static int equal(Symbol lprime, Symbol dst) {
static int equal(Symbol lprime, Symbol dst) {
        assert(dst && lprime);
        assert(dst && lprime);
        for ( ; dst; dst = dst->u.l.equatedto)
        for ( ; dst; dst = dst->u.l.equatedto)
                if (lprime == dst)
                if (lprime == dst)
                        return 1;
                        return 1;
        return 0;
        return 0;
}
}
/* dostmt - do statement while ( expression ) */
/* dostmt - do statement while ( expression ) */
static void dostmt(int lab, Swtch swp, int lev) {
static void dostmt(int lab, Swtch swp, int lev) {
        refinc *= 10.0;
        refinc *= 10.0;
        t = gettok();
        t = gettok();
        definelab(lab);
        definelab(lab);
        statement(lab, swp, lev);
        statement(lab, swp, lev);
        definelab(lab + 1);
        definelab(lab + 1);
        expect(WHILE);
        expect(WHILE);
        expect('(');
        expect('(');
        definept(NULL);
        definept(NULL);
        walk(conditional(')'), lab, 0);
        walk(conditional(')'), lab, 0);
        if (findlabel(lab + 2)->ref)
        if (findlabel(lab + 2)->ref)
                definelab(lab + 2);
                definelab(lab + 2);
}
}
 
 
/* foldcond - check if initial test in for(e1;e2;e3) S is necessary */
/* foldcond - check if initial test in for(e1;e2;e3) S is necessary */
static int foldcond(Tree e1, Tree e2) {
static int foldcond(Tree e1, Tree e2) {
        int op = generic(e2->op);
        int op = generic(e2->op);
        Symbol v;
        Symbol v;
 
 
        if (e1 == 0 || e2 == 0)
        if (e1 == 0 || e2 == 0)
                return 0;
                return 0;
        if (generic(e1->op) == ASGN && isaddrop(e1->kids[0]->op)
        if (generic(e1->op) == ASGN && isaddrop(e1->kids[0]->op)
        && generic(e1->kids[1]->op) == CNST) {
        && generic(e1->kids[1]->op) == CNST) {
                v = e1->kids[0]->u.sym;
                v = e1->kids[0]->u.sym;
                e1 = e1->kids[1];
                e1 = e1->kids[1];
        } else
        } else
                return 0;
                return 0;
        if ((op==LE || op==LT || op==EQ || op==NE || op==GT || op==GE)
        if ((op==LE || op==LT || op==EQ || op==NE || op==GT || op==GE)
        && generic(e2->kids[0]->op) == INDIR
        && generic(e2->kids[0]->op) == INDIR
        && e2->kids[0]->kids[0]->u.sym == v
        && e2->kids[0]->kids[0]->u.sym == v
        && e2->kids[1]->op == e1->op) {
        && e2->kids[1]->op == e1->op) {
                e1 = simplify(op, e2->type, e1, e2->kids[1]);
                e1 = simplify(op, e2->type, e1, e2->kids[1]);
                if (e1->op == CNST+I)
                if (e1->op == CNST+I)
                        return e1->u.v.i;
                        return e1->u.v.i;
        }
        }
        return 0;
        return 0;
}
}
 
 
/* localaddr - returns q if p yields the address of local/parameter q; otherwise returns 0 */
/* localaddr - returns q if p yields the address of local/parameter q; otherwise returns 0 */
static Symbol localaddr(Tree p) {
static Symbol localaddr(Tree p) {
        if (p == NULL)
        if (p == NULL)
                return NULL;
                return NULL;
        switch (generic(p->op)) {
        switch (generic(p->op)) {
        case INDIR: case CALL: case ARG:
        case INDIR: case CALL: case ARG:
                return NULL;
                return NULL;
        case ADDRL: case ADDRF:
        case ADDRL: case ADDRF:
                return p->u.sym;
                return p->u.sym;
        case RIGHT: case ASGN:
        case RIGHT: case ASGN:
                if (p->kids[1])
                if (p->kids[1])
                        return localaddr(p->kids[1]);
                        return localaddr(p->kids[1]);
                return localaddr(p->kids[0]);
                return localaddr(p->kids[0]);
        case COND: {
        case COND: {
                Symbol q;
                Symbol q;
                assert(p->kids[1] && p->kids[1]->op == RIGHT);
                assert(p->kids[1] && p->kids[1]->op == RIGHT);
                if ((q = localaddr(p->kids[1]->kids[0])) != NULL)
                if ((q = localaddr(p->kids[1]->kids[0])) != NULL)
                        return q;
                        return q;
                return localaddr(p->kids[1]->kids[1]);
                return localaddr(p->kids[1]->kids[1]);
                }
                }
        default: {
        default: {
                Symbol q;
                Symbol q;
                if (p->kids[0] && (q = localaddr(p->kids[0])) != NULL)
                if (p->kids[0] && (q = localaddr(p->kids[0])) != NULL)
                        return q;
                        return q;
                return localaddr(p->kids[1]);
                return localaddr(p->kids[1]);
                }
                }
        }
        }
}
}
 
 
/* whilestmt - while ( expression ) statement */
/* whilestmt - while ( expression ) statement */
static void whilestmt(int lab, Swtch swp, int lev) {
static void whilestmt(int lab, Swtch swp, int lev) {
        Coordinate pt;
        Coordinate pt;
        Tree e;
        Tree e;
 
 
        refinc *= 10.0;
        refinc *= 10.0;
        t = gettok();
        t = gettok();
        expect('(');
        expect('(');
        walk(NULL, 0, 0);
        walk(NULL, 0, 0);
        pt = src;
        pt = src;
        e = texpr(conditional, ')', FUNC);
        e = texpr(conditional, ')', FUNC);
        branch(lab + 1);
        branch(lab + 1);
        definelab(lab);
        definelab(lab);
        statement(lab, swp, lev);
        statement(lab, swp, lev);
        definelab(lab + 1);
        definelab(lab + 1);
        definept(&pt);
        definept(&pt);
        walk(e, lab, 0);
        walk(e, lab, 0);
        if (findlabel(lab + 2)->ref)
        if (findlabel(lab + 2)->ref)
                definelab(lab + 2);
                definelab(lab + 2);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.