summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/gc/const.c3
-rw-r--r--src/cmd/gc/go.h3
-rw-r--r--src/cmd/gc/go.y8
-rw-r--r--src/cmd/gc/lex.c9
-rw-r--r--src/cmd/gc/mparith2.c34
-rw-r--r--src/cmd/gc/subr.c1
-rw-r--r--src/cmd/gc/walk.c18
7 files changed, 72 insertions, 4 deletions
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c
index 85d8a1ded..116341cdf 100644
--- a/src/cmd/gc/const.c
+++ b/src/cmd/gc/const.c
@@ -314,6 +314,9 @@ evconst(Node *n)
case TUP(OAND, Wlitint):
mpandfixfix(xval, nr->val.u.xval);
break;
+ case TUP(OANDNOT, Wlitint):
+ mpandnotfixfix(xval, nr->val.u.xval);
+ break;
case TUP(OXOR, Wlitint):
mpxorfixfix(xval, nr->val.u.xval);
break;
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index dd5798196..c87cf05ef 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -314,7 +314,7 @@ enum
OANDAND,
OEQ, ONE, OLT, OLE, OGE, OGT,
OADD, OSUB, OOR, OXOR,
- OMUL, ODIV, OMOD, OLSH, ORSH, OAND,
+ OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT,
OINC, ODEC, // placeholders - not used
OFUNC,
OLABEL,
@@ -610,6 +610,7 @@ void mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d);
void mpdivfract(Mpint *a, Mpint *b);
void mpnegfix(Mpint *a);
void mpandfixfix(Mpint *a, Mpint *b);
+void mpnotandfixfix(Mpint *a, Mpint *b);
void mplshfixfix(Mpint *a, Mpint *b);
void mporfixfix(Mpint *a, Mpint *b);
void mprshfixfix(Mpint *a, Mpint *b);
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index 7635e163c..87e8e53f7 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -25,7 +25,7 @@
%token <sym> LNIL LTRUE LFALSE LIOTA
%token LOROR LANDAND LEQ LNE LLE LLT LGE LGT
-%token LLSH LRSH LINC LDEC LCOMM
+%token LLSH LRSH LINC LDEC LCOMM LANDNOT
%token LIGNORE
/*
@@ -87,7 +87,7 @@
%left LCOMM
%left LEQ LNE LLE LGE LLT LGT
%left '+' '-' '|' '^'
-%left '*' '/' '%' '&' LLSH LRSH
+%left '*' '/' '%' '&' LLSH LRSH LANDNOT
/*
* resolve { vs condition in favor of condition
@@ -766,6 +766,10 @@ expr:
{
$$ = nod(OAND, $1, $3);
}
+| expr LANDNOT expr
+ {
+ $$ = nod(OANDNOT, $1, $3);
+ }
| expr LLSH expr
{
$$ = nod(OLSH, $1, $3);
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index 179d0518e..23717d341 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -654,6 +654,15 @@ l0:
c = LANDAND;
goto lx;
}
+ if(c1 == '^') {
+ c = LANDNOT;
+ c1 = getc();
+ if(c1 == '=') {
+ c = OANDNOT;
+ goto asop;
+ }
+ break;
+ }
if(c1 == '=') {
c = OAND;
goto asop;
diff --git a/src/cmd/gc/mparith2.c b/src/cmd/gc/mparith2.c
index f7c2ea2c2..622a7c58d 100644
--- a/src/cmd/gc/mparith2.c
+++ b/src/cmd/gc/mparith2.c
@@ -407,6 +407,40 @@ mpandfixfix(Mpint *a, Mpint *b)
}
void
+mpandnotfixfix(Mpint *a, Mpint *b)
+{
+ int i;
+ long x, *a1, *b1;
+
+ if(a->ovf || b->ovf) {
+ warn("ovf in mpandnotfixfix");
+ mpmovecfix(a, 0);
+ a->ovf = 1;
+ return;
+ }
+ if(a->neg) {
+ a->neg = 0;
+ mpneg(a);
+ }
+ if(b->neg)
+ mpneg(b);
+
+ a1 = &a->a[0];
+ b1 = &b->a[0];
+ for(i=0; i<Mpprec; i++) {
+ x = *a1 & ~*b1++;
+ *a1++ = x;
+ }
+
+ if(b->neg)
+ mpneg(b);
+ if(x & Mpsign) {
+ a->neg = 1;
+ mpneg(a);
+ }
+}
+
+void
mpxorfixfix(Mpint *a, Mpint *b)
{
int i;
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index bfc090a2c..723937b2d 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -643,6 +643,7 @@ opnames[] =
[OADDR] = "ADDR",
[OADD] = "ADD",
[OANDAND] = "ANDAND",
+ [OANDNOT] = "ANDNOT",
[OAND] = "AND",
[OARRAY] = "ARRAY",
[OASOP] = "ASOP",
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 4652a75f8..b8821e6f7 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -667,6 +667,7 @@ loop:
case OMOD:
case OAND:
+ case OANDNOT:
case OOR:
case OXOR:
case OANDAND:
@@ -700,6 +701,20 @@ loop:
goto badt;
switch(n->op) {
+ case OANDNOT:
+ n->op = OAND;
+ n->right = nod(OCOM, n->right, N);
+ n->right->type = n->right->left->type;
+ break;
+
+ case OASOP:
+ if(n->etype == OANDNOT) {
+ n->etype = OAND;
+ n->right = nod(OCOM, n->right, N);
+ n->right->type = n->right->left->type;
+ break;
+ }
+
case OEQ:
case ONE:
case OLT:
@@ -707,11 +722,11 @@ loop:
case OGE:
case OGT:
case OADD:
- case OASOP:
if(istype(n->left->type, TSTRING)) {
indir(n, stringop(n, top));
goto ret;
}
+ break;
}
break;
@@ -1070,6 +1085,7 @@ loop:
case OLSH:
case ORSH:
case OAND:
+ case OANDNOT:
case OOR:
case OXOR:
case OMOD: