shithub: scc

Download patch

ref: 10faf603cace3ffda21153466dfbd9e672bcf656
parent: a48a176171b40b974a7c5a284c2356d26ffdf7ad
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Sep 7 07:37:24 EDT 2015

Fix interger constants size

These constant were incorrectly emitted, because the size of the target type
was ignored, so negative number generated different quantities.
There were also another problem related to the fact that comparisions were
always done in the host type, that may be bigger than the target type..

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -363,6 +363,7 @@
 /* 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 */
 extern Node *expr(void), *negate(Node *np), *constexpr(void);
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -192,7 +192,7 @@
 	case PTR:
 	case INT:
 		u = (tp->sign) ? (TUINT) sym->u.i : sym->u.u;
-		printf("#%c%lX", np->type->letter, sym->u.i);
+		printf("#%c%lX", np->type->letter, sym->u.i & ones(tp->size));
 		break;
 	case ARY:
 		/*
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -14,6 +14,7 @@
 {
 	Symbol *sym;
 	Type *tp;
+	TUINT mask, nodeval;
 
 	if (!np || !np->constant)
 		return 0;
@@ -23,7 +24,9 @@
 	switch (tp->op) {
 	case PTR:
 	case INT:
-		return ((tp->sign) ? sym->u.i : sym->u.u) == val;
+		mask = (val > 1) ? ones(np->type->size) : -1;
+		nodeval = (tp->sign) ? sym->u.i : sym->u.u;
+		return (nodeval & mask) == (val & mask);
 	case FLOAT:
 		return sym->u.f == val;
 	}
--- a/cc1/fold.c
+++ b/cc1/fold.c
@@ -4,6 +4,19 @@
 #include "../inc/cc.h"
 #include "cc1.h"
 
+
+/* TODO: Add ENUM in the cases */
+
+TUINT
+ones(int nbytes)
+{
+	TUINT v;
+
+	for (v = 0; nbytes--; v |= 255)
+		v <<= 8;
+	return v;
+}
+
 static bool
 addi(TINT l, TINT r, Type *tp)
 {
@@ -135,16 +148,6 @@
 	return 1;
 }
 
-static TUINT
-ones(int n)
-{
-	TUINT v;
-
-	for (v = 1; n--; v |= 1)
-		v <<= 1;
-	return v;
-}
-
 static bool
 foldint(int op, Symbol *res, TINT l, TINT r)
 {
@@ -462,7 +465,7 @@
 		return NULL;
 	case OBAND:
 		/* i & ~0 => i */
-		if (cmpnode(rp, ~0))
+		if (cmpnode(rp, -1))
 			goto free_right;
 		return NULL;
 	case OMOD:
--- a/cc1/tests/test019.c
+++ b/cc1/tests/test019.c
@@ -22,8 +22,8 @@
 	A2	#I4	:I
 	A2	#IC	:I
 	A2	#I8	:I
-	A2	#IFFFFFFFD	:I
-	A2	#IFFFFFFF3	:I
+	A2	#IFFFD	:I
+	A2	#IFFF3	:I
 	A2	#I1	:I
 	A2	#I0	:I
 	A2	#I0	:I