scc

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

commit 034a823e68386a5e18bac3d796658fbf87f7654f
parent 51cf75b9b31e81acf9570ab07cc59fe95408816f
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sun, 26 Jul 2015 08:09:26 +0200

Simplify float nodes

Diffstat:
Mcc1/cc1.h | 1+
Mcc1/code.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Minc/cc.h | 7+++----
3 files changed, 64 insertions(+), 36 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -48,6 +48,7 @@ struct symbol { union { TINT i; TUINT u; + TFLOAT f; char *s; unsigned char token; } u; diff --git a/cc1/code.c b/cc1/code.c @@ -394,83 +394,108 @@ sizeofnode(Type *tp) Node * simplify(unsigned char op, Type *tp, Node *lp, Node *rp) { - Symbol *sym, *ls, *rs; + 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 */ switch (tp->op) { case INT: - sym = newsym(NS_IDEN); - sym->type = tp; switch (op) { case OADD: - FOLDINT(sym, ls, rs, +); + FOLDINT(&aux, ls, rs, +); break; case OSUB: - FOLDINT(sym, ls, rs, -); + FOLDINT(&aux, ls, rs, -); break; case OMUL: - FOLDINT(sym, ls, rs, *); + FOLDINT(&aux, ls, rs, *); break; case ODIV: - if (SYMICMP(sym, 0)) + if (SYMICMP(&aux, 0)) goto division_by_0; - FOLDINT(sym, ls, rs, /); + FOLDINT(&aux, ls, rs, /); break; case OMOD: - if (SYMICMP(sym, 0)) + if (SYMICMP(&aux, 0)) goto division_by_0; - FOLDINT(sym, ls, rs, %); + FOLDINT(&aux, ls, rs, %); break; case OSHL: - FOLDINT(sym, ls, rs, <<); + FOLDINT(&aux, ls, rs, <<); break; case OSHR: - FOLDINT(sym, ls, rs, >>); + FOLDINT(&aux, ls, rs, >>); break; + /* + * FIXME: comparision nodes are integers + * but it doesn't mean the operands are + * integers too + */ case OLT: - FOLDINT(sym, ls, rs, <); + FOLDINT(&aux, ls, rs, <); break; case OGT: - FOLDINT(sym, ls, rs, >); + FOLDINT(&aux, ls, rs, >); break; case OGE: - FOLDINT(sym, ls, rs, >=); + FOLDINT(&aux, ls, rs, >=); break; case OLE: - FOLDINT(sym, ls, rs, <=); + FOLDINT(&aux, ls, rs, <=); break; case OEQ: - FOLDINT(sym, ls, rs, ==); + FOLDINT(&aux, ls, rs, ==); break; case ONE: - FOLDINT(sym, ls, rs, !=); + FOLDINT(&aux, ls, rs, !=); break; case OBAND: - FOLDINT(sym, ls, rs, &); + FOLDINT(&aux, ls, rs, &); break; case OBXOR: - FOLDINT(sym, ls, rs, ^); + FOLDINT(&aux, ls, rs, ^); break; case OBOR: - FOLDINT(sym, ls, rs, |); + FOLDINT(&aux, ls, rs, |); break; case OAND: - FOLDINT(sym, ls, rs, &&); + FOLDINT(&aux, ls, rs, &&); break; case OOR: - FOLDINT(sym, ls, rs, ||); + FOLDINT(&aux, ls, rs, ||); break; } break; case FLOAT: - /* TODO: Add simplification of 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; + } + break; default: goto no_simplify; } + sym = newsym(NS_IDEN); + sym->type = tp; + sym->u = aux.u; return constnode(sym); division_by_0: @@ -487,35 +512,38 @@ no_simplify: Node * usimplify(unsigned char op, Type *tp, Node *np) { - Symbol *sym, *ns; + 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: - sym = newsym(NS_IDEN); - sym->type = tp; - UFOLDINT(sym, ns, -); + UFOLDINT(&aux, ns, -); break; case OCPL: - sym = newsym(NS_IDEN); - sym->type = tp; - UFOLDINT(sym, ns, ~); + UFOLDINT(&aux, ns, ~); break; default: goto no_simplify; } break; case FLOAT: - /* TODO: implement floats */ + 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: diff --git a/inc/cc.h b/inc/cc.h @@ -7,10 +7,9 @@ typedef unsigned bool; #endif #endif -#define TINT short -#define TUINT unsigned short -#define TLONG long -#define TULONG unsigned long +#define TINT long +#define TUINT unsigned long +#define TFLOAT double #define RANK_BOOL 0 #define RANK_SCHAR 1