ref: 061575df4ee33bf59cd7ab7f82af38798391bd53
parent: 23597ee476bd27f80b8f3f88c7ba5811ee2e94b7
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Mar 21 02:22:44 EDT 2015
Add neg and cpl operations These unary operations are very similar between them, so it was easy to implement them together.
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -139,7 +139,9 @@
JP,
AND,
OR,
- XOR
+ XOR,
+ CPL,
+ NEG
};
enum {
--- a/cc2/cgen.c
+++ b/cc2/cgen.c
@@ -250,6 +250,24 @@
case OASSIG:
allocreg(np);
break;
+ case ONEG:
+ case OCPL:
+ switch (np->op) {
+ case REG:
+ if (np->reg == A)
+ break;
+ /* PASSTHROUGH */
+ case PAR:
+ case AUTO:
+ case CONST:
+ case MEM:
+ case INDEX:
+ accum(np);
+ break;
+ default:
+ abort();
+ }
+ break;
case OADD:
case OSUB:
case OBAND:
@@ -394,6 +412,39 @@
{
}
+static void
+cpl(Node *np)
+{
+
+ Node *lp = np->left;
+ uint8_t op;
+
+ switch (np->type.size) {
+ case 1:
+ move(lp, np);
+ switch (np->op) {
+ case OCPL:
+ op = CPL;
+ break;
+ case ONEG:
+ op = NEG;
+ break;
+ default:
+ abort();
+ }
+ code(op, lp, NULL);
+ if ((np->op = lp->op) == REG) {
+ np->reg = lp->reg;
+ reguse[A] = np;
+ }
+ np->sym = lp->sym;
+ lp->used = 1;
+ break;
+ default:
+ abort();
+ }
+}
+
static void (*opnodes[])(Node *) = {
[OADD] = add,
[OSUB] = add,
@@ -406,7 +457,9 @@
[PAR] = nop,
[OBOR] = add,
[OBAND] = add,
- [OBXOR] = add
+ [OBXOR] = add,
+ [OCPL] = cpl,
+ [ONEG] = cpl
};
static void
--- a/cc2/code.c
+++ b/cc2/code.c
@@ -37,7 +37,10 @@
[JP] = inst1,
[AND] = inst2,
[OR] = inst2,
- [XOR] = inst2
+ [XOR] = inst2,
+ [CPL] = inst1,
+ [NEG] = inst1
+
};
static char *insttext[] = {
@@ -57,7 +60,9 @@
[JP] = "JP",
[AND] = "AND",
[OR] = "OR",
- [XOR] = "XOR"
+ [XOR] = "XOR",
+ [CPL] = "CPL",
+ [NEG] = "NEG"
};
Inst *pc, *prog;