[hackers] [scc] [cc1 cc2] Do not apply DeMorgan to logic operators || Roberto E. Vargas Caballero
commit 4f8980c62a63c938a957a469bae8fa9ed88e399f
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Wed Aug 10 15:04:46 2016 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Wed Aug 10 15:11:55 2016 +0200
[cc1 cc2] Do not apply DeMorgan to logic operators
Applying the DeMorgan rules is more complex that the code was making,
because it means that we have to negate all the comparision nodes
recursively. The best option is to create a new logic negation node
and do not try to fold anything.
diff --git a/cc1/cc1.h b/cc1/cc1.h
index 3d9634d..83d1179 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -200,6 +200,7 @@ enum op {
OBAND,
OBXOR,
OBOR,
+ OSNEG,
ONEG,
OCPL,
OAND,
diff --git a/cc1/code.c b/cc1/code.c
index c410545..c856e8e 100644
--- a/cc1/code.c
+++ b/cc1/code.c
_AT_@ -50,7 +50,8 @@ char *optxt[] = {
[OA_XOR] = ":^",
[OA_OR] = ":|",
[OADDR] = "'",
- [ONEG] = "_",
+ [OSNEG] = "_",
+ [ONEG] = "n",
[OCPL] = "~",
[OAND] = "a",
[OOR] = "o",
_AT_@ -104,6 +105,7 @@ void (*opcode[])(unsigned, void *) = {
[OA_XOR] = emitbin,
[OA_OR] = emitbin,
[OADDR] = emitbin,
+ [OSNEG] = emitbin,
[ONEG] = emitbin,
[OCPL] = emitbin,
[OAND] = emitbin,
diff --git a/cc1/expr.c b/cc1/expr.c
index a6c9282..0f17ec3 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
_AT_@ -37,22 +37,6 @@ cmpnode(Node *np, TUINT val)
return 0;
}
-int
-isnodecmp(int op)
-{
- switch (op) {
- case OEQ:
- case ONE:
- case OLT:
- case OGE:
- case OLE:
- case OGT:
- return 1;
- default:
- return 0;
- }
-}
-
static Node *
promote(Node *np)
{
_AT_@ -251,7 +235,7 @@ numericaluop(char op, Node *np)
if (!(np->type->prop & TARITH))
error("unary operator requires numerical operand");
np = promote(np);
- if (op == ONEG && np->op == ONEG)
+ if (op == OSNEG && np->op == OSNEG)
return np->left;
if (op == OADD)
return np;
_AT_@ -413,8 +397,6 @@ int
negop(int op)
{
switch (op) {
- case OAND: return OOR;
- case OOR: return OAND;
case OEQ: return ONE;
case ONE: return OEQ;
case OLT: return OGE;
_AT_@ -429,11 +411,32 @@ negop(int op)
Node *
negate(Node *np)
{
- if (np->op == OSYM) {
+ int op = np->op;
+
+ switch (np->op) {
+ case OSYM:
assert(np->flags&NCONST && np->type->prop&TINTEGER);
np->sym = (np->sym->u.i) ? zero : one;
- } else {
- np->op = negop(np->op);
+ break;
+ case OOR:
+ case OAND:
+ if (np->op == ONEG) {
+ Node *new = np->left;
+ free(np);
+ return new;
+ }
+ np = node(ONEG, inttype, np, NULL);
+ break;
+ case OEQ:
+ case ONE:
+ case OLT:
+ case OGE:
+ case OLE:
+ case OGT:
+ np->op = negop(op);
+ break;
+ default:
+ abort();
}
return np;
_AT_@ -444,11 +447,21 @@ exp2cond(Node *np, char neg)
{
if (np->type->prop & TAGGREG) {
errorp("used struct/union type value where scalar is required");
- np = constnode(zero);
+ return constnode(zero);
}
- if (isnodecmp(np->op))
+ switch (np->op) {
+ case OOR:
+ case OAND:
+ case OEQ:
+ case ONE:
+ case OLT:
+ case OGE:
+ case OLE:
+ case OGT:
return (neg) ? negate(np) : np;
- return compare((neg) ? OEQ : ONE, np, constnode(zero));
+ default:
+ return compare((neg) ? OEQ : ONE, np, constnode(zero));
+ }
}
static Node *
_AT_@ -827,7 +840,7 @@ unary(int needdecay)
switch (yytoken) {
case '!': op = 0; fun = negation; break;
case '+': op = OADD; fun = numericaluop; break;
- case '-': op = ONEG; fun = numericaluop; break;
+ case '-': op = OSNEG; fun = numericaluop; break;
case '~': op = OCPL; fun = integeruop; break;
case '&': op = OADDR; fun = address; break;
case '*': op = OPTR; fun = content; break;
diff --git a/cc1/fold.c b/cc1/fold.c
index 88bd7a2..f2e5306 100644
--- a/cc1/fold.c
+++ b/cc1/fold.c
_AT_@ -188,7 +188,8 @@ foldint(int op, Symbol *res, TINT l, TINT r)
case OLE: i = l <= r; break;
case OEQ: i = l == r; break;
case ONE: i = l != r; break;
- case ONEG: i = -l; break;
+ case ONEG: i = !l; break;
+ case OSNEG: i = -l; break;
case OCPL: i = ~l; break;
default: return 0;
}
_AT_@ -213,7 +214,8 @@ folduint(int op, Symbol *res, TUINT l, TUINT r)
case OBAND: u = l & r; break;
case OBXOR: u = l ^ r; break;
case OBOR: u = l | r; break;
- case ONEG: u = -l; break;
+ case ONEG: u = !l; break;
+ case OSNEG: u = -l; break;
case OCPL: u = ~l; break;
case OAND: i = l && r; goto sign;
case OOR: i = l || r; goto sign;
diff --git a/cc2/cc2.h b/cc2/cc2.h
index 83f3f61..95a1a7c 100644
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
_AT_@ -81,7 +81,7 @@ enum op {
OBXOR = '^',
OCPL = '~',
OASSIG = ':',
- ONEG = '_',
+ OSNEG = '_',
OCALL = 'c',
OPAR = 'p',
OFIELD = '.',
_AT_@ -91,6 +91,7 @@ enum op {
OADDR = '\'',
OAND = 'a',
OOR = 'o',
+ ONEG = 'n',
OPTR = '_AT_',
OCAST = 'g',
OINC = 'i',
diff --git a/cc2/parser.c b/cc2/parser.c
index bf3fa25..3dd0c57 100644
--- a/cc2/parser.c
+++ b/cc2/parser.c
_AT_@ -92,11 +92,12 @@ static struct decoc {
['\t'] = { stmt, NULL, 0},
['~'] = { NULL, unary, .u.op = OCPL},
- ['_'] = { NULL, unary, .u.op = ONEG},
+ ['_'] = { NULL, unary, .u.op = OSNEG},
['\''] = { NULL, unary, .u.op = OADDR},
['_AT_'] = { NULL, unary, .u.op = OPTR},
['g'] = { NULL, unary, .u.op = OCAST},
['p'] = { NULL, unary, .u.op = OPAR},
+ ['n'] = { NULL, unary, .u.op = ONEG},
['a'] = { NULL, binary, .u.op = OAND},
['o'] = { NULL, binary, .u.op = OOR},
Received on Wed Aug 10 2016 - 15:13:03 CEST
This archive was generated by hypermail 2.3.0
: Wed Aug 10 2016 - 15:24:13 CEST