scc

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

commit 149b464dcae2f20abdfed12cf9f7f78ed7596772
parent fee4eeac3d4259a138bf98212c72faf394fcd379
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 21 Jul 2015 17:56:59 +0200

Add fold of constants in add and sub operators

This is the first step towards constant expressions resolution.

Diffstat:
cc1/cc1.h | 5++++-
cc1/code.c | 69++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
cc1/expr.c | 1+
cc1/types.c | 6++++++
inc/cc.h | 2++
5 files changed, 75 insertions(+), 8 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -23,6 +23,7 @@ struct type { unsigned char ns; char letter; /* letter of the type */ bool defined; /* type defined */ + bool sign; /* signess of the type */ size_t size; /* sizeof the type */ size_t align; /* align of the type */ Type *type; /* base type */ @@ -43,7 +44,8 @@ struct symbol { unsigned char token; short flags; union { - int i; + TINT i; + TUINT u; char *s; unsigned char token; } u; @@ -320,6 +322,7 @@ extern Node *varnode(Symbol *sym); extern Node *constnode(Symbol *sym); extern Node *sizeofnode(Type *tp); extern void freetree(Node *np); +extern Node *simplify(Node *np); /* expr.c */ extern Node *expr(void), *negate(Node *np), *constexpr(void); diff --git a/cc1/code.c b/cc1/code.c @@ -124,6 +124,15 @@ void (*opcode[])(unsigned, void *) = { [OSWITCH] = emitswitch }; +static Node *simple_sub(Node *), *simple_add(Node *); + +static Node *(*opsimp[])(Node *) = { + [OADD] = simple_add, + [OSUB] = simple_sub + +}; + + void freetree(Node *np) { @@ -310,16 +319,10 @@ node(unsigned op, Type *tp, Node *lp, Node *rp) np->op = op; np->type = tp; np->sym = NULL; - np->symbol = np->lvalue = 0; - np->constant = 1; + np->constant = np->symbol = np->lvalue = 0; np->left = lp; np->right = rp; - if (lp) - np->constant &= lp->constant; - if (rp) - np->constant &= rp->constant; - return np; } @@ -359,3 +362,55 @@ sizeofnode(Type *tp) sym->u.i = tp->size; return constnode(sym); } + +static Node * +simple_add(Node *np) +{ + Node *lp = np->left, *rp = np->right; + Type *tp = np->type; + Symbol *sym, *ls = lp->sym, *rs = rp->sym; + + switch (tp->op) { + case INT: + sym = newsym(NS_IDEN); + sym->type = tp; + if (tp->sign) + sym->u.i = ls->u.i + rs->u.i; + else + sym->u.u = ls->u.u + rs->u.u; + freetree(np); + return constnode(sym); + default: + return np; + } +} + +static Node * +simple_sub(Node *np) +{ + Node *lp = np->left, *rp = np->right; + Type *tp = np->type; + Symbol *sym, *ls = lp->sym, *rs = rp->sym; + + switch (tp->op) { + case INT: + sym = newsym(NS_IDEN); + sym->type = tp; + if (tp->sign) + sym->u.i = ls->u.i - rs->u.i; + else + sym->u.u = ls->u.u - rs->u.u; + freetree(np); + return constnode(sym); + default: + return np; + } +} + +Node * +simplify(Node *np) +{ + if (!np->left->constant || !np->right->constant) + return np; + return (*opsimp[np->op])(np); +} diff --git a/cc1/expr.c b/cc1/expr.c @@ -685,6 +685,7 @@ add(void) } next(); np = arithmetic(op, np, mul()); + np = simplify(np); } } diff --git a/cc1/types.c b/cc1/types.c @@ -42,6 +42,7 @@ static Type types[] = { .defined = 1, .size = 1, .align = 1, + .sign = 1, .n.rank = RANK_SCHAR }, { /* 4 = uchartype */ @@ -58,6 +59,7 @@ static Type types[] = { .defined = 1, .size = 1, .align = 1, + .sign = 1, .n.rank = RANK_CHAR }, { /* 6 = ushortype */ @@ -74,6 +76,7 @@ static Type types[] = { .defined = 1, .size = 2, .align = 1, + .sign = 1, .n.rank = RANK_SHORT }, { /* 8 = uinttype */ @@ -90,6 +93,7 @@ static Type types[] = { .defined = 1, .size = 2, .align = 1, + .sign = 1, .n.rank = RANK_INT }, { /* 10 = longtype */ @@ -98,6 +102,7 @@ static Type types[] = { .defined = 1, .size = 4, .align = 1, + .sign = 1, .n.rank = RANK_LONG }, { /* 11 = ulongtype */ @@ -122,6 +127,7 @@ static Type types[] = { .defined = 1, .size = 8, .align = 1, + .sign = 1, .n.rank = RANK_LLONG }, { /* 14 = floattype */ diff --git a/inc/cc.h b/inc/cc.h @@ -8,7 +8,9 @@ typedef unsigned bool; #endif #define TINT short +#define TUINT unsigned short #define TLONG long +#define TULONG unsigned long #define RANK_BOOL 0 #define RANK_SCHAR 1