scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit e7ca69b68ebc64e8bea02198105838ac8726e528
parent 8f1d626650ad8f6c77a6fdc12a8e49d35a7ca77e
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 27 Jul 2015 12:44:18 +0200

Move simplify() and usimplify() to expr.c

These functions are more about how expressions are built than
about the Node data structure, and they are called only
in expr.c, so it is more logical to have them in expr.c and
avoid namespace pollution.

Diffstat:
cc1/cc1.h | 3---
cc1/code.c | 197-------------------------------------------------------------------------------
cc1/expr.c | 229+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
3 files changed, 213 insertions(+), 216 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -328,15 +328,12 @@ extern Node *varnode(Symbol *sym); extern Node *constnode(Symbol *sym); extern Node *sizeofnode(Type *tp); extern void freetree(Node *np); -extern Node *simplify(unsigned char, Type *tp, Node *lp, Node *rp); -extern Node *usimplify(unsigned char op, Type *tp, Node *np); #define BTYPE(np) ((np)->type->op) /* expr.c */ extern Node *expr(void), *negate(Node *np), *constexpr(void); extern Node *convert(Node *np, Type *tp1, char iscast); extern Node *iszero(Node *np), *eval(Node *np), *iconstexpr(void); -extern bool isnodecmp(int op); /* cpp.c */ extern void icpp(void); diff --git a/cc1/code.c b/cc1/code.c @@ -383,200 +383,3 @@ sizeofnode(Type *tp) sym->u.i = tp->size; return constnode(sym); } - -#define SYMICMP(sym, val) (((sym)->type->sign) ? \ - (sym)->u.i == (val) : (sym)->u.u == (val)) - -#define FOLDINT(sym, ls, rs, op) (((sym)->type->sign) ? \ - ((sym)->u.i = ((ls)->u.i op (rs)->u.i)) : \ - ((sym)->u.u = ((ls)->u.u op (rs)->u.u))) - -#define CMPISYM(sym, ls, rs, op) (((sym)->type->sign) ? \ - ((ls)->u.i op (rs)->u.i) : ((ls)->u.u op (rs)->u.u)) - -Node * -simplify(unsigned char op, Type *tp, Node *lp, Node *rp) -{ - Symbol *sym, *ls, *rs, aux; - - if (!lp->constant || !rp->constant) - goto no_simplify; - ls = lp->sym, rs = rp->sym; - aux.type = tp; - - /* TODO: Add overflow checkings */ - - if (isnodecmp(op)) { - /* - * Comparision nodes have integer type - * but the operands can have different - * type. - */ - switch (BTYPE(lp)) { - case INT: goto cmp_integers; - case FLOAT: goto cmp_floats; - default: goto no_simplify; - } - } - - switch (tp->op) { - case INT: - cmp_integers: - switch (op) { - case OADD: - FOLDINT(&aux, ls, rs, +); - break; - case OSUB: - FOLDINT(&aux, ls, rs, -); - break; - case OMUL: - FOLDINT(&aux, ls, rs, *); - break; - case ODIV: - if (SYMICMP(&aux, 0)) - goto division_by_0; - FOLDINT(&aux, ls, rs, /); - break; - case OMOD: - if (SYMICMP(&aux, 0)) - goto division_by_0; - FOLDINT(&aux, ls, rs, %); - break; - case OSHL: - FOLDINT(&aux, ls, rs, <<); - break; - case OSHR: - FOLDINT(&aux, ls, rs, >>); - break; - case OBAND: - FOLDINT(&aux, ls, rs, &); - break; - case OBXOR: - FOLDINT(&aux, ls, rs, ^); - break; - case OBOR: - FOLDINT(&aux, ls, rs, |); - break; - case OAND: - FOLDINT(&aux, ls, rs, &&); - break; - case OOR: - FOLDINT(&aux, ls, rs, ||); - break; - case OLT: - aux.u.i = CMPISYM(&aux, ls, rs, <); - break; - case OGT: - aux.u.i = CMPISYM(&aux, ls, rs, >); - break; - case OGE: - aux.u.i = CMPISYM(&aux, ls, rs, >=); - break; - case OLE: - aux.u.i = CMPISYM(&aux, ls, rs, <=); - break; - case OEQ: - aux.u.i = CMPISYM(&aux, ls, rs, ==); - break; - case ONE: - aux.u.i = CMPISYM(&aux, ls, rs, !=); - break; - } - break; - case FLOAT: - cmp_floats: - switch (op) { - case OADD: - aux.u.f = ls->u.f + rs->u.f; - break; - case OSUB: - aux.u.f = ls->u.f - rs->u.f; - break; - case OMUL: - aux.u.f = ls->u.f * rs->u.f; - break; - case ODIV: - if (rs->u.f == 0.0) - goto division_by_0; - aux.u.f = ls->u.f / rs->u.f; - break; - case OLT: - aux.u.i = ls->u.f < rs->u.f; - break; - case OGT: - aux.u.i = ls->u.f > rs->u.f; - break; - case OGE: - aux.u.i = ls->u.f >= rs->u.f; - break; - case OLE: - aux.u.i = ls->u.f <= rs->u.f; - break; - case OEQ: - aux.u.i = ls->u.f == rs->u.f; - break; - case ONE: - aux.u.i = ls->u.f != rs->u.f; - break; - } - break; - default: - goto no_simplify; - } - - sym = newsym(NS_IDEN); - sym->type = tp; - sym->u = aux.u; - return constnode(sym); - -division_by_0: - warn("division by 0"); - -no_simplify: - return node(op, tp, lp, rp); -} - -#define UFOLDINT(sym, ls, op) (((sym)->type->sign) ? \ - ((sym)->u.i = (op (ls)->u.i)) : \ - ((sym)->u.u = (op (ls)->u.u))) - -Node * -usimplify(unsigned char op, Type *tp, Node *np) -{ - Symbol *sym, *ns, aux; - - if (!np->constant) - goto no_simplify; - ns = np->sym; - aux.type = tp; - - switch (tp->op) { - case INT: - switch (op) { - case ONEG: - UFOLDINT(&aux, ns, -); - break; - case OCPL: - UFOLDINT(&aux, ns, ~); - break; - default: - goto no_simplify; - } - break; - case FLOAT: - if (op != ONEG) - goto no_simplify; - aux.u.f = -ns->u.f; - break; - default: - goto no_simplify; - } - - sym = newsym(NS_IDEN); - sym->type = tp; - sym->u = aux.u; - return constnode(sym); - -no_simplify: - return node(op, tp, np, NULL); -} diff --git a/cc1/expr.c b/cc1/expr.c @@ -10,6 +10,219 @@ extern Symbol *zero, *one; Node *expr(void); +static bool +isnodecmp(int op) +{ + switch (op) { + case OEQ: + case ONE: + case OLT: + case OGE: + case OLE: + case OGT: + return 1; + default: + return 0; + } +} + +#define SYMICMP(sym, val) (((sym)->type->sign) ? \ + (sym)->u.i == (val) : (sym)->u.u == (val)) + +#define FOLDINT(sym, ls, rs, op) (((sym)->type->sign) ? \ + ((sym)->u.i = ((ls)->u.i op (rs)->u.i)) : \ + ((sym)->u.u = ((ls)->u.u op (rs)->u.u))) + +#define CMPISYM(sym, ls, rs, op) (((sym)->type->sign) ? \ + ((ls)->u.i op (rs)->u.i) : ((ls)->u.u op (rs)->u.u)) + +static Node * +simplify(unsigned char op, Type *tp, Node *lp, Node *rp) +{ + Symbol *sym, *ls, *rs, aux; + + if (!lp->constant || !rp->constant) + goto no_simplify; + ls = lp->sym, rs = rp->sym; + aux.type = tp; + + /* TODO: Add overflow checkings */ + + if (isnodecmp(op)) { + /* + * Comparision nodes have integer type + * but the operands can have different + * type. + */ + switch (BTYPE(lp)) { + case INT: goto cmp_integers; + case FLOAT: goto cmp_floats; + default: goto no_simplify; + } + } + + switch (tp->op) { + case INT: + cmp_integers: + switch (op) { + case OADD: + FOLDINT(&aux, ls, rs, +); + break; + case OSUB: + FOLDINT(&aux, ls, rs, -); + break; + case OMUL: + FOLDINT(&aux, ls, rs, *); + break; + case ODIV: + if (SYMICMP(&aux, 0)) + goto division_by_0; + FOLDINT(&aux, ls, rs, /); + break; + case OMOD: + if (SYMICMP(&aux, 0)) + goto division_by_0; + FOLDINT(&aux, ls, rs, %); + break; + case OSHL: + FOLDINT(&aux, ls, rs, <<); + break; + case OSHR: + FOLDINT(&aux, ls, rs, >>); + break; + case OBAND: + FOLDINT(&aux, ls, rs, &); + break; + case OBXOR: + FOLDINT(&aux, ls, rs, ^); + break; + case OBOR: + FOLDINT(&aux, ls, rs, |); + break; + case OAND: + FOLDINT(&aux, ls, rs, &&); + break; + case OOR: + FOLDINT(&aux, ls, rs, ||); + break; + case OLT: + aux.u.i = CMPISYM(&aux, ls, rs, <); + break; + case OGT: + aux.u.i = CMPISYM(&aux, ls, rs, >); + break; + case OGE: + aux.u.i = CMPISYM(&aux, ls, rs, >=); + break; + case OLE: + aux.u.i = CMPISYM(&aux, ls, rs, <=); + break; + case OEQ: + aux.u.i = CMPISYM(&aux, ls, rs, ==); + break; + case ONE: + aux.u.i = CMPISYM(&aux, ls, rs, !=); + break; + } + break; + case FLOAT: + cmp_floats: + switch (op) { + case OADD: + aux.u.f = ls->u.f + rs->u.f; + break; + case OSUB: + aux.u.f = ls->u.f - rs->u.f; + break; + case OMUL: + aux.u.f = ls->u.f * rs->u.f; + break; + case ODIV: + if (rs->u.f == 0.0) + goto division_by_0; + aux.u.f = ls->u.f / rs->u.f; + break; + case OLT: + aux.u.i = ls->u.f < rs->u.f; + break; + case OGT: + aux.u.i = ls->u.f > rs->u.f; + break; + case OGE: + aux.u.i = ls->u.f >= rs->u.f; + break; + case OLE: + aux.u.i = ls->u.f <= rs->u.f; + break; + case OEQ: + aux.u.i = ls->u.f == rs->u.f; + break; + case ONE: + aux.u.i = ls->u.f != rs->u.f; + break; + } + break; + default: + goto no_simplify; + } + + sym = newsym(NS_IDEN); + sym->type = tp; + sym->u = aux.u; + return constnode(sym); + +division_by_0: + warn("division by 0"); + +no_simplify: + return node(op, tp, lp, rp); +} + +#define UFOLDINT(sym, ls, op) (((sym)->type->sign) ? \ + ((sym)->u.i = (op (ls)->u.i)) : \ + ((sym)->u.u = (op (ls)->u.u))) + +static Node * +usimplify(unsigned char op, Type *tp, Node *np) +{ + Symbol *sym, *ns, aux; + + if (!np->constant) + goto no_simplify; + ns = np->sym; + aux.type = tp; + + switch (tp->op) { + case INT: + switch (op) { + case ONEG: + UFOLDINT(&aux, ns, -); + break; + case OCPL: + UFOLDINT(&aux, ns, ~); + break; + default: + goto no_simplify; + } + break; + case FLOAT: + if (op != ONEG) + goto no_simplify; + aux.u.f = -ns->u.f; + break; + default: + goto no_simplify; + } + + sym = newsym(NS_IDEN); + sym->type = tp; + sym->u = aux.u; + return constnode(sym); + +no_simplify: + return node(op, tp, np, NULL); +} + static Node * promote(Node *np) { @@ -303,22 +516,6 @@ negate(Node *np) return np; } -bool -isnodecmp(int op) -{ - switch (op) { - case OEQ: - case ONE: - case OLT: - case OGE: - case OLE: - case OGT: - return 1; - default: - return 0; - } -} - static Node * exp2cond(Node *np, char neg) {