ref: 0f4ff07f5e70ab058cc15831e24a5f7bce5e97a5
parent: 8f5c9ee749a797d0af3c8d2d96c9c3961f8f5544
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Mar 20 14:21:51 EDT 2015
Add JP assembler instruction This instruction is needed for return statements. This version is oriented to text output, because it is very useful now, but in some moment we will change it.
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -42,13 +42,16 @@
typedef struct symbol Symbol;
typedef struct node Node;
+typedef struct inst Inst;
+typedef struct addr Addr;
+typedef struct type Type;
-typedef struct {
+struct type {
unsigned short size;
uint8_t align;
char letter;
uint8_t flags;
-} Type;
+};
struct symbol {
unsigned short id;
@@ -65,6 +68,7 @@
char sclass;
short off;
} v;
+ Inst *pc;
struct {
short locals;
short params;
@@ -85,8 +89,6 @@
struct node *left, *right;
};
-typedef struct inst Inst;
-typedef struct addr Addr;
struct addr {
char kind;
@@ -93,7 +95,6 @@
union {
uint8_t reg;
TINT i;
- Inst *pc;
Symbol *sym;
} u;
};
@@ -101,6 +102,7 @@
struct inst {
uint8_t op;
Addr from, to;
+ Symbol *label;
Inst *next, *prev;
};
@@ -133,7 +135,8 @@
NOP,
INC,
SUB,
- DEC
+ DEC,
+ JP
};
enum {
--- a/cc2/cgen.c
+++ b/cc2/cgen.c
@@ -6,6 +6,9 @@
#include "../inc/cc.h"
#include "cc2.h"
+static Symbol retlabel = {
+ .kind = LABEL
+};
static Node *reguse[NPAIRS];
static uint8_t upper[] = {[DE] = D, [HL] = H, [BC] = B, [IY] = IYH};
@@ -18,7 +21,7 @@
[IYL] = IY, [IYH] = IY, [IY] = IY
};
-Node regs[] = {
+static Node regs[] = {
[E] = {
.op = REG,
.reg = E
@@ -351,6 +354,14 @@
static void
ret(Node *np)
{
+ static Node retnode = {
+ .op = LABEL,
+ .sym = &retlabel
+ };
+
+ if (np->left)
+ accum(np->left);
+ code(JP, &retnode, NULL);
}
static void (*opnodes[])(Node *) = {
@@ -400,7 +411,10 @@
generate(void)
{
uint8_t size = curfun->u.f.locals;
+ static short id = 1000;
+ retlabel.id = id++;
+
code(PUSH, NULL, ®s[IX]);
code(MOV, ®s[IX], ®s[SP]);
if (size > 6) {
@@ -415,6 +429,8 @@
apply(applycgen);
code(MOV, ®s[SP], ®s[IX]);
+ retlabel.u.pc = pc;
+ pc->label = &retlabel;
code(POP, ®s[IX], NULL);
code(RET, NULL, NULL);
}
--- a/cc2/code.c
+++ b/cc2/code.c
@@ -33,7 +33,8 @@
[NOP] = inst0,
[INC] = inst1,
[SUB] = inst2,
- [DEC] = inst1
+ [DEC] = inst1,
+ [JP] = inst1
};
static char *insttext[] = {
@@ -49,7 +50,8 @@
[NOP] = "NOP",
[INC] = "INC",
[SUB] = "SUB",
- [DEC] = "DEC"
+ [DEC] = "DEC",
+ [JP] = "JP"
};
Inst *pc, *prog;
@@ -88,6 +90,7 @@
case AUTO:
addr->u.i = np->sym->u.v.off;
break;
+ case LABEL:
case MEM:
addr->u.sym = np->sym;
break;
@@ -144,8 +147,11 @@
if (!prog)
return;
- for (pc = prog; pc; pc = pc->next)
+ for (pc = prog; pc; pc = pc->next) {
+ if (pc->label)
+ printf("L%d:", pc->label->id);
(*instcode[pc->op])();
+ }
}
static void
@@ -163,6 +169,10 @@
case PAR:
case AUTO:
printf("(IX%+d)", a->u.i);
+ break;
+ case LABEL:
+ sym = a->u.sym;
+ printf("L%d", sym->id);
break;
case INDEX:
fputs("(HL)", stdout);