scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 18071c940a707f9de54540e4ddbb405bbf8cba19
parent 4f3e4465ccb3e7c611c7996793abefe399787983
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 23 Jul 2015 17:44:23 +0200

Simplify unary expressions

Diffstat:
Mcc1/cc1.h | 1+
Mcc1/code.c | 44++++++++++++++++++++++++++++++++++++++++++--
Mcc1/expr.c | 4++--
3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -327,6 +327,7 @@ 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); /* expr.c */ extern Node *expr(void), *negate(Node *np), *constexpr(void); diff --git a/cc1/code.c b/cc1/code.c @@ -463,8 +463,6 @@ simplify(unsigned char op, Type *tp, Node *lp, Node *rp) case OOR: FOLDINT(sym, ls, rs, ||); break; - default: - abort(); } break; case FLOAT: @@ -481,3 +479,45 @@ 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; + + if (!np->constant) + goto no_simplify; + ns = np->sym; + + switch (tp->op) { + case INT: + switch (op) { + case ONEG: + sym = newsym(NS_IDEN); + sym->type = tp; + UFOLDINT(sym, ns, -); + break; + case OCPL: + sym = newsym(NS_IDEN); + sym->type = tp; + UFOLDINT(sym, ns, ~); + break; + default: + goto no_simplify; + } + break; + case FLOAT: + /* TODO: implement floats */ + default: + goto no_simplify; + } + + return constnode(sym); + +no_simplify: + return node(op, tp, np, NULL); +} diff --git a/cc1/expr.c b/cc1/expr.c @@ -90,7 +90,7 @@ numericaluop(char op, Node *np) case FLOAT: if (op == OADD) return np; - return node(op, np->type, np, NULL); + return usimplify(op, np->type, np); default: error("unary operator requires integer operand"); } @@ -102,7 +102,7 @@ integeruop(char op, Node *np) np = eval(np); if (BTYPE(np) != INT) error("unary operator requires integer operand"); - return node(op, np->type, np, NULL); + return usimplify(op, np->type, np); } static Node *