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:
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