shithub: scc

Download patch

ref: 149b464dcae2f20abdfed12cf9f7f78ed7596772
parent: fee4eeac3d4259a138bf98212c72faf394fcd379
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Jul 21 13:56:59 EDT 2015

Add fold of constants in add and sub operators

This is the first step towards constant expressions resolution.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -23,6 +23,7 @@
 	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 @@
 	unsigned char token;
 	short flags;
 	union {
-		int i;
+		TINT i;
+		TUINT u;
 		char *s;
 		unsigned char token;
 	} u;
@@ -320,6 +322,7 @@
 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);
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -124,6 +124,15 @@
 	[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 @@
 	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;
 }
 
@@ -358,4 +361,56 @@
 	sym->type = sizettype;
 	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);
 }
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -685,6 +685,7 @@
 		}
 		next();
 		np = arithmetic(op, np, mul());
+		np = simplify(np);
 	}
 }
 
--- a/cc1/types.c
+++ b/cc1/types.c
@@ -42,6 +42,7 @@
 		.defined = 1,
 		.size = 1,
 		.align = 1,
+		.sign = 1,
 		.n.rank = RANK_SCHAR
 	},
 	{      /* 4 = uchartype */
@@ -58,6 +59,7 @@
 		.defined = 1,
 		.size = 1,
 		.align = 1,
+		.sign = 1,
 		.n.rank = RANK_CHAR
 	},
 	{       /* 6 = ushortype */
@@ -74,6 +76,7 @@
 		.defined = 1,
 		.size = 2,
 		.align = 1,
+		.sign = 1,
 		.n.rank = RANK_SHORT
 	},
 	{       /* 8 = uinttype */
@@ -90,6 +93,7 @@
 		.defined = 1,
 		.size = 2,
 		.align = 1,
+		.sign = 1,
 		.n.rank = RANK_INT
 	},
 	{      /* 10 = longtype */
@@ -98,6 +102,7 @@
 		.defined = 1,
 		.size = 4,
 		.align = 1,
+		.sign = 1,
 		.n.rank = RANK_LONG
 	},
 	{       /* 11 = ulongtype */
@@ -122,6 +127,7 @@
 		.defined = 1,
 		.size = 8,
 		.align = 1,
+		.sign = 1,
 		.n.rank = RANK_LLONG
 	},
 	{       /* 14 = floattype */
--- a/inc/cc.h
+++ b/inc/cc.h
@@ -8,7 +8,9 @@
 #endif
 
 #define TINT short
+#define TUINT unsigned short
 #define TLONG long
+#define TULONG unsigned long
 
 #define RANK_BOOL    0
 #define RANK_SCHAR   1