scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 10faf603cace3ffda21153466dfbd9e672bcf656
parent a48a176171b40b974a7c5a284c2356d26ffdf7ad
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon,  7 Sep 2015 11:37:24 +0200

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

Diffstat:
Mcc1/cc1.h | 1+
Mcc1/code.c | 2+-
Mcc1/expr.c | 5++++-
Mcc1/fold.c | 25++++++++++++++-----------
Mcc1/tests/test019.c | 4++--
5 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -363,6 +363,7 @@ extern void freetree(Node *np); /* 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); diff --git a/cc1/code.c b/cc1/code.c @@ -192,7 +192,7 @@ emitconst(Node *np) 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: /* diff --git a/cc1/expr.c b/cc1/expr.c @@ -14,6 +14,7 @@ cmpnode(Node *np, TUINT val) { Symbol *sym; Type *tp; + TUINT mask, nodeval; if (!np || !np->constant) return 0; @@ -23,7 +24,9 @@ cmpnode(Node *np, TUINT val) 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; } diff --git 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 @@ rshi(TINT l, TINT r, Type *tp) 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 @@ identity(int *op, Node *lp, Node *rp) return NULL; case OBAND: /* i & ~0 => i */ - if (cmpnode(rp, ~0)) + if (cmpnode(rp, -1)) goto free_right; return NULL; case OMOD: diff --git a/cc1/tests/test019.c b/cc1/tests/test019.c @@ -22,8 +22,8 @@ A2 I i 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