shithub: scc

Download patch

ref: 7fba4ee75f2cfe1c2988e49bfa9158594503e678
parent: ea965d122903adb6bf9da6c7100468f9796a2b62
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Feb 3 06:03:28 EST 2017

[cc1] Move castcode() from fold.c to expr.c

This function was only used in expr.c and it is not related
to the code in fold.c.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -420,7 +420,6 @@
 
 /* fold.c */
 extern Node *simplify(int op, Type *tp, Node *lp, Node *rp);
-extern Node *castcode(Node *np, Type *newtp);
 extern TUINT ones(int nbytes);
 
 /* expr.c */
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -240,6 +240,64 @@
 	if (op == OADD)
 		return np;
 	return simplify(op, np->type, np, NULL);
+	return node(op, np->type, np, NULL);
+}
+
+/* TODO: check validity of types */
+static Node *
+castcode(Node *np, Type *newtp)
+{
+	TUINT negmask, mask, u;
+	Type *oldtp = np->type;
+	Symbol aux, *sym, *osym = np->sym;
+
+	if (!(np->flags & NCONST))
+		goto noconstant;
+
+	switch (newtp->op) {
+	case PTR:
+	case INT:
+	case ENUM:
+		switch (oldtp->op) {
+		case PTR:
+		case INT:
+		case ENUM:
+			u = (oldtp->prop & TSIGNED) ? osym->u.i : osym->u.u;
+			break;
+		case FLOAT:
+			oldtp = newtp;
+			u = osym->u.f;
+			break;
+		default:
+			goto noconstant;
+		}
+		mask = ones(newtp->size);
+		if (newtp->prop & TSIGNED) {
+			negmask = ~mask;
+			if (u & (negmask >> 1) & mask)
+				u |= negmask;
+			aux.u.i = u;
+		} else {
+			aux.u.u = u & mask;
+		}
+		break;
+	case FLOAT:
+		/* FIXME: The cast can be from another float type */
+		aux.u.f = (oldtp->prop & TSIGNED) ? osym->u.i : osym->u.u;
+		break;
+	default:
+		goto noconstant;
+	}
+
+	sym = newsym(NS_IDEN, NULL);
+	np->type = sym->type = newtp;
+	np->sym = sym;
+	sym->u = aux.u;
+
+	return np;
+
+noconstant:
+	return node(OCAST, newtp, np, NULL);
 }
 
 Node *