diff options
Diffstat (limited to 'src/cmd/gc/const.c')
-rw-r--r-- | src/cmd/gc/const.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c index 8b02de9b2..fbb4fa303 100644 --- a/src/cmd/gc/const.c +++ b/src/cmd/gc/const.c @@ -282,8 +282,9 @@ evconst(Node *n) Node *nl, *nr; int32 len; String *str; - int wl, wr, lno; + int wl, wr, lno, et; Val v; + Mpint b; nl = n->left; if(nl == N || nl->type == T) @@ -541,7 +542,34 @@ unary: mpnegfix(v.u.xval); break; case TUP(OCOM, CTINT): - mpcomfix(v.u.xval); + et = Txxx; + if(nl->type != T) + et = nl->type->etype; + + // calculate the mask in b + // result will be (a ^ mask) + switch(et) { + default: + mpmovecfix(&b, -1); + break; + + case TINT8: + case TINT16: + case TINT32: + case TINT64: + case TINT: + et++; // convert to unsigned + // fallthrough + case TUINT8: + case TUINT16: + case TUINT32: + case TUINT64: + case TUINT: + case TUINTPTR: + mpmovefixfix(&b, maxintval[et]); + break; + } + mpxorfixfix(v.u.xval, &b); break; case TUP(OPLUS, CTFLT): |