ref: 4f26471416516e201f2d0efdfb87f601a5682134
parent: a0758440d875f800b9cd5e9d726cc568a8633a43
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Sep 16 14:57:40 EDT 2014
Add generation of additions This is a first attemp to generate additions, that generate code only for very simple cases, and even destroy the stack, but it is usable to can check another parts, as for example the offset of local variables in the stack.
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -36,6 +36,7 @@
union {
Symbol *sym;
TINT imm;
+ char reg;
} u;
struct node *left, *right;
} Node;
--- a/cc2/cgen.c
+++ b/cc2/cgen.c
@@ -9,7 +9,7 @@
#include <stdio.h>
-
+/* TODO: Change emit to code */
enum {
PUSH, POP, LD, ADD, RET, ADDI, LDI, ADDR, ADDX, ADCX, LDX,
LDFX
@@ -157,15 +157,16 @@
Symbol *sym;
char reg;
+ reg = allocreg(np);
+
switch (np->op) {
case AUTO:
sym = np->u.sym;
switch (tp->size) {
case 1:
- emit(LDFX, allocreg(np), sym->u.v.off);
+ emit(LDFX, reg, sym->u.v.off);
break;
case 2:
- reg = allocreg(np);
emit(LDFX, lower(reg), IX, sym->u.v.off);
emit(LDFX, upper(reg), IX, sym->u.v.off+1);
break;
@@ -178,9 +179,23 @@
default:
abort();
}
+ /* TODO: Update symbol if necessary */
+ np->op = REG;
+ np->u.reg = reg;
}
static void
+conmute(Node *np)
+{
+ Node *p, *q;
+
+ p = np->left;
+ q = np->right;
+ np->left = q;
+ np->right = p;
+}
+
+static void
cgen(Node *np)
{
Node *lp, *rp;
@@ -210,7 +225,40 @@
cgen(q);
}
+ assert(lp && lp->op == REG || rp && rp->op == REG);
switch (np->op) {
+ case OADD:
+ switch (np->type->size) {
+ case 1:
+ if (rp->u.reg == A) {
+ conmute(np);
+ lp = np->left;
+ rp = np->right;
+ } else if (lp->u.reg != A) {
+ /* TODO: Move A to variable */
+ emit(PUSH, AF);
+ emit(LD, A, lp->u.reg);
+ }
+ emit(ADD, A, rp->u.reg);
+ break;
+ case 2:
+ if (rp->u.reg == HL || rp->u.reg == IY) {
+ conmute(np);
+ lp = np->left;
+ rp = np->right;
+ } else if (lp->u.reg != HL || lp->u.reg != IY) {
+ /* TODO: Move HL to variable */
+ emit(PUSH, HL);
+ emit(LD, H, upper(lp->u.reg));
+ emit(LD, L, lower(lp->u.reg));
+ }
+ emit(ADD, HL, rp->u.reg);
+ break;
+ case 4:
+ case 8:
+ abort();
+ }
+ break;
default:
abort();
}