[hackers] [scc] Extend sign in constant casts || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Mon, 7 Sep 2015 23:44:57 +0200 (CEST)

commit 153d5c396bcf4e67cb2937f06f59c6346b57c4bf
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Mon Sep 7 23:27:58 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Mon Sep 7 23:27:58 2015 +0200

    Extend sign in constant casts
    
    Since we are doing all the operations in bigger integer types,
    we need to operate over quantities when we deal with signed types,
    so it means that we have to do sign extension when the higher
    bit of the result is 1.

diff --git a/cc1/fold.c b/cc1/fold.c
index eac3d24..78fd807 100644
--- a/cc1/fold.c
+++ b/cc1/fold.c
_AT_@ -498,7 +498,7 @@ simplify(int op, Type *tp, Node *lp, Node *rp)
 Node *
 castcode(Node *np, Type *newtp)
 {
- TUINT mask;
+ TUINT negmask, mask, u;
         Type *oldtp = np->type;
         Symbol aux, *sym, *osym = np->sym;
 
_AT_@ -509,33 +509,31 @@ castcode(Node *np, Type *newtp)
         case PTR:
         case INT:
         case ENUM:
- mask = ones(newtp->size);
                 switch (oldtp->op) {
                 case PTR:
                 case INT:
                 case ENUM:
- if (newtp->sign == oldtp->sign)
- aux.u = osym->u;
- if (newtp->sign && !oldtp->sign)
- aux.u.i = osym->u.u & mask;
- else if (!newtp->sign && oldtp->sign)
- aux.u.u = osym->u.u & mask;
+ u = (oldtp->sign) ? osym->u.i : osym->u.u;
                         break;
                 case FLOAT:
- if (newtp->sign) {
- aux.u.i = osym->u.f;
- aux.u.i &= mask;
- } else {
- aux.u.u = osym->u.f;
- aux.u.u &= mask;
- }
+ u = osym->u.f;
                         break;
                 default:
                         goto noconstant;
                 }
+ mask = ones(newtp->size);
+ if (newtp->sign) {
+ negmask = ~mask;
+ u &= 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 floar type */
+ /* FIXME: The cast can be from another float type */
                 aux.u.f = (oldtp->sign) ? osym->u.i : osym->u.u;
                 break;
         default:
Received on Mon Sep 07 2015 - 23:44:57 CEST

This archive was generated by hypermail 2.3.0 : Mon Sep 07 2015 - 23:48:18 CEST