summaryrefslogtreecommitdiff
path: root/src/cmd/gc/const.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/const.c')
-rw-r--r--src/cmd/gc/const.c32
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):