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;
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,
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);
%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
/*
%left LCOMM
%left LEQ LNE LLE LGE LLT LGT
%left '+' '-' '|' '^'
-%left '*' '/' '%' '&' LLSH LRSH
+%left '*' '/' '%' '&' LLSH LRSH LANDNOT
/*
* resolve { vs condition in favor of condition
{
$$ = nod(OAND, $1, $3);
}
+| expr LANDNOT expr
+ {
+ $$ = nod(OANDNOT, $1, $3);
+ }
| expr LLSH expr
{
$$ = nod(OLSH, $1, $3);
c = LANDAND;
goto lx;
}
+ if(c1 == '^') {
+ c = LANDNOT;
+ c1 = getc();
+ if(c1 == '=') {
+ c = OANDNOT;
+ goto asop;
+ }
+ break;
+ }
if(c1 == '=') {
c = OAND;
goto asop;
}
}
+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)
{
[OADDR] = "ADDR",
[OADD] = "ADD",
[OANDAND] = "ANDAND",
+ [OANDNOT] = "ANDNOT",
[OAND] = "AND",
[OARRAY] = "ARRAY",
[OASOP] = "ASOP",
case OMOD:
case OAND:
+ case OANDNOT:
case OOR:
case OXOR:
case OANDAND:
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:
case OGE:
case OGT:
case OADD:
- case OASOP:
if(istype(n->left->type, TSTRING)) {
indir(n, stringop(n, top));
goto ret;
}
+ break;
}
break;
case OLSH:
case ORSH:
case OAND:
+ case OANDNOT:
case OOR:
case OXOR:
case OMOD: