scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 0f4ff07f5e70ab058cc15831e24a5f7bce5e97a5
parent 8f5c9ee749a797d0af3c8d2d96c9c3961f8f5544
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 20 Mar 2015 18:21:51 -0400

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.

Diffstat:
Mcc2/cc2.h | 15+++++++++------
Mcc2/cgen.c | 18+++++++++++++++++-
Mcc2/code.c | 16+++++++++++++---
3 files changed, 39 insertions(+), 10 deletions(-)

diff --git 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 @@ struct symbol { char sclass; short off; } v; + Inst *pc; struct { short locals; short params; @@ -85,15 +89,12 @@ struct node { struct node *left, *right; }; -typedef struct inst Inst; -typedef struct addr Addr; struct addr { char kind; union { uint8_t reg; TINT i; - Inst *pc; Symbol *sym; } u; }; @@ -101,6 +102,7 @@ struct addr { struct inst { uint8_t op; Addr from, to; + Symbol *label; Inst *next, *prev; }; @@ -133,7 +135,8 @@ enum { NOP, INC, SUB, - DEC + DEC, + JP }; enum { diff --git 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 @@ static uint8_t pair[] = { [IYL] = IY, [IYH] = IY, [IY] = IY }; -Node regs[] = { +static Node regs[] = { [E] = { .op = REG, .reg = E @@ -351,6 +354,14 @@ assign(Node *np) 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,6 +411,9 @@ void generate(void) { uint8_t size = curfun->u.f.locals; + static short id = 1000; + + retlabel.id = id++; code(PUSH, NULL, &regs[IX]); code(MOV, &regs[IX], &regs[SP]); @@ -415,6 +429,8 @@ generate(void) apply(applycgen); code(MOV, &regs[SP], &regs[IX]); + retlabel.u.pc = pc; + pc->label = &retlabel; code(POP, &regs[IX], NULL); code(RET, NULL, NULL); } diff --git a/cc2/code.c b/cc2/code.c @@ -33,7 +33,8 @@ static void (*instcode[])(void) = { [NOP] = inst0, [INC] = inst1, [SUB] = inst2, - [DEC] = inst1 + [DEC] = inst1, + [JP] = inst1 }; static char *insttext[] = { @@ -49,7 +50,8 @@ static char *insttext[] = { [NOP] = "NOP", [INC] = "INC", [SUB] = "SUB", - [DEC] = "DEC" + [DEC] = "DEC", + [JP] = "JP" }; Inst *pc, *prog; @@ -88,6 +90,7 @@ addr(char op, Node *np, Addr *addr) 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 @@ writeout(void) 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 @@ -164,6 +170,10 @@ addr2txt(uint8_t op, Addr *a) 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); break;