shithub: scc

Download patch

ref: 18071c940a707f9de54540e4ddbb405bbf8cba19
parent: 4f3e4465ccb3e7c611c7996793abefe399787983
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu Jul 23 13:44:23 EDT 2015

Simplify unary expressions

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -327,6 +327,7 @@
 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);
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -463,8 +463,6 @@
 		case OOR:
 			FOLDINT(sym, ls, rs, ||);
 			break;
-		default:
-			abort();
 		}
 		break;
 	case FLOAT:
@@ -480,4 +478,46 @@
 
 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);
 }
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -90,7 +90,7 @@
 	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 @@
 	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 *