commit e2fc11a0790f840a9f0f0ce59878f0f0a55fc52d Author: Roberto E. Vargas Caballero <roberto.var...@igrid-td.com> AuthorDate: Wed Apr 13 08:48:46 2016 +0200 Commit: Roberto E. Vargas Caballero <roberto.var...@igrid-td.com> CommitDate: Wed Apr 13 08:48:46 2016 +0200
[cc2-qbe] First implementation of cgen() for qbe This first version of cgen is the version that is showing how all the architectures must deal with the asm generation. In the case of qbe, we are not writing real asm code but qbe intermediate language. diff --git a/cc2/arch/amd64-sysv/cgen.c b/cc2/arch/amd64-sysv/cgen.c index 54e3ed2..191ed06 100644 --- a/cc2/arch/amd64-sysv/cgen.c +++ b/cc2/arch/amd64-sysv/cgen.c @@ -2,8 +2,8 @@ #include "arch.h" #include "../../cc2.h" -void -generate(void) +Node * +cgen(Node *np) { } diff --git a/cc2/arch/i386-sysv/cgen.c b/cc2/arch/i386-sysv/cgen.c index 54e3ed2..191ed06 100644 --- a/cc2/arch/i386-sysv/cgen.c +++ b/cc2/arch/i386-sysv/cgen.c @@ -2,8 +2,8 @@ #include "arch.h" #include "../../cc2.h" -void -generate(void) +Node * +cgen(Node *np) { } diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c index 43236e1..e01e716 100644 --- a/cc2/arch/qbe/cgen.c +++ b/cc2/arch/qbe/cgen.c @@ -1,10 +1,117 @@ +#include <stdlib.h> + #include "arch.h" #include "../../cc2.h" -void -generate(void) +enum sflags { + ISTMP = 1, + ISCONS = 2 +}; + +static Node * +load(Node *np) +{ + Node *new; + Symbol *sym; + + new = newnode(); + sym = getsym(TMPSYM); + sym->type = np->type; + new->u.sym = sym; + new->op = OLOAD; + new->left = np; + new->type = np->type; + new->flags |= ISTMP; + return new; +} + +Node * +cgen(Node *np) { + Node *l, *r; + Symbol *sym; + int op; + + if (!np) + return NULL; + + l = cgen(np->left); + r = cgen(np->right); + + switch (op = np->op) { + case OREG: + case OSTRING: + abort(); + case OCONST: + case OLABEL: + np->flags |= ISCONS; + case OPAR: + case OMEM: + case OAUTO: + return np; + case OADD: + case OSUB: + case OMUL: + case OMOD: + case ODIV: + case OSHL: + case OSHR: + case OLT: + case OGT: + case OLE: + case OGE: + case OEQ: + case ONE: + case OBAND: + case OBOR: + case OBXOR: + case OCPL: + if ((l->flags & (ISTMP|ISCONS)) == 0) + np->left = load(l); + if ((r->flags & (ISTMP|ISCONS)) == 0) + np->right = load(r); + sym = getsym(TMPSYM); + sym->type = np->type; + np->flags |= ISTMP; + np->u.sym = sym; + np->op = OTMP; + code(op, np, np->left, np->right); + return np; + case ONOP: + case OBLOOP: + case OELOOP: + return NULL; + case ONEG: + case OADDR: + case OPTR: + case OCAST: + case OINC: + case ODEC: + abort(); + case OASSIG: + code(op, l, l, r); + return r; + case OCALL: + case OFIELD: + case OCOMMA: + case OASK: + case OCOLON: + case OAND: + case OOR: + abort(); + case OBRANCH: + case OJMP: + code(op, NULL, l, r); + return NULL; + case ORET: + case OCASE: + case ODEFAULT: + case OTABLE: + case OSWITCH: + default: + abort(); + } } /* diff --git a/cc2/arch/z80/cgen.c b/cc2/arch/z80/cgen.c index 95067f9..d0402e0 100644 --- a/cc2/arch/z80/cgen.c +++ b/cc2/arch/z80/cgen.c @@ -2,8 +2,8 @@ #include "arch.h" #include "../../cc2.h" -void -generate(void) +Node * +cgen(Node *np) { } diff --git a/cc2/cc2.h b/cc2/cc2.h index 4f9a205..e0de200 100644 --- a/cc2/cc2.h +++ b/cc2/cc2.h @@ -39,6 +39,7 @@ enum op { STRING = '"', LABEL = 'L', INDEX = 'I', + OTMP = 'T', /* storage class */ GLOB = 'G', EXTRN = 'X', @@ -51,6 +52,7 @@ enum op { OREG = 'R', OCONST = '#', OSTRING = '"', + OLOAD = 'D', OLABEL = 'L', OADD = '+', OSUB = '-', @@ -81,7 +83,6 @@ enum op { OAND = 'a', OOR = 'o', OPTR = '@', - OSYM = 'i', OCAST = 'g', OINC = 'i', ODEC = 'd', @@ -111,6 +112,7 @@ enum nerrors { ESTACKU, /* stack underflow */ ELNLINE, /* line too long */ EFERROR, /* error reading from file:%s*/ + EBADID, /* incorrect symbol id */ ENUMERR }; @@ -145,6 +147,7 @@ struct node { Type type; char complex; char address; + unsigned char flags; union { TUINT i; char reg; @@ -183,7 +186,7 @@ extern void optimize(void); /* cgen.c */ extern Node *sethi(Node *np); -extern void generate(void); +extern Node *cgen(Node *np); /* peep.c */ extern void peephole(void); @@ -191,6 +194,7 @@ extern void peephole(void); /* code.c */ extern void data(Node *np); extern void writeout(void), endinit(void), newfun(void); +extern void code(int op, Node *to, Node *from1, Node *from2); extern void defvar(Symbol *), defpar(Symbol *), defglobal(Symbol *); /* node.c */ @@ -202,7 +206,8 @@ extern Node *newnode(void); extern Symbol *curfun; /* symbol.c */ -extern Symbol *getsym(int id); +#define TMPSYM 0 +extern Symbol *getsym(unsigned id); extern void popctx(void); extern void pushctx(void); extern void freesym(Symbol *sym); diff --git a/cc2/code.c b/cc2/code.c index f19abb1..80173f7 100644 --- a/cc2/code.c +++ b/cc2/code.c @@ -26,7 +26,7 @@ nextpc(void) pc = new; } -void +static void addr(int op, Node *np, Addr *addr) { switch (addr->kind = np->op) { diff --git a/cc2/main.c b/cc2/main.c index 561e2b5..5ea38f0 100644 --- a/cc2/main.c +++ b/cc2/main.c @@ -40,7 +40,7 @@ main(void) parse(); optimize(); apply(sethi); - generate(); + apply(cgen); peephole(); writeout(); } diff --git a/cc2/node.c b/cc2/node.c index 21594f3..67da0ad 100644 --- a/cc2/node.c +++ b/cc2/node.c @@ -1,5 +1,6 @@ #include <stdlib.h> +#include <string.h> #include "../inc/cc.h" @@ -39,11 +40,7 @@ newnode(void) np = freep; freep = np->left; - np->right = NULL; - np->left = NULL; - np->stmt = NULL; - np->label = NULL; - return np; + return memset(np, 0, sizeof(np)); } void diff --git a/cc2/symbol.c b/cc2/symbol.c index 3b7b90b..f3bed3b 100644 --- a/cc2/symbol.c +++ b/cc2/symbol.c @@ -1,4 +1,5 @@ +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -43,10 +44,13 @@ popctx(void) } Symbol * -getsym(int id) +getsym(unsigned id) { Symbol **htab, *sym; + if (id > USHRT_MAX) + error(EBADID); + htab = &symtab[id & NR_SYMHASH-1]; for (sym = *htab; sym; sym = sym->h_next) { if (sym->id > 0 && sym->id == id)