scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit d18a15e95c494b77c30156593ceba045ead2bd8e
parent e5165d704e5d8d7c7ee23bb884f2aacf6cb722a4
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 15 Apr 2016 15:56:20 +0200

[cc2-qbe] Begin to emit instructions

This code is totally unstested, but it defines how we can emit
instructions for QBE. Comparisions instructions and divisions
even emit incorrect text strings, but after this point is easy
to begin hacking.

Diffstat:
cc2/arch/qbe/cgen.c | 2+-
cc2/arch/qbe/code.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
cc2/cc2.h | 5++++-
cc2/code.c | 2+-
cc2/node.c | 2+-
cc2/parser.c | 6+++---
6 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c @@ -46,7 +46,6 @@ cgen(Node *np) case OCONST: case OLABEL: np->flags |= ISCONS; - case OPAR: case OMEM: case OAUTO: return np; @@ -82,6 +81,7 @@ cgen(Node *np) case OBLOOP: case OELOOP: return NULL; + case OPAR: case ONEG: case OADDR: case OPTR: diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c @@ -6,6 +6,30 @@ #include "../../cc2.h" #include "../../../inc/sizes.h" +static void inst3(void); + +static struct opdata { + void (*fun)(void); + char *txt; +} optbl [] = { + [OADD] = {.fun = inst3, .txt = "add"}, + [OSUB] = {.fun = inst3, .txt = "sub"}, + [OMUL] = {.fun = inst3, .txt = "mul"}, + [OMOD] = {.fun = inst3, .txt = "rem"}, + [ODIV] = {.fun = inst3, .txt = "div"}, + [OSHL] = {.fun = inst3, .txt = "shl"}, + [OSHR] = {.fun = inst3, .txt = "shr"}, + [OLT] = {.fun = inst3, .txt = "clt"}, + [OGT] = {.fun = inst3, .txt = "cgt"}, + [OLE] = {.fun = inst3, .txt = "cle"}, + [OGE] = {.fun = inst3, .txt = "cge"}, + [OEQ] = {.fun = inst3, .txt = "ceq"}, + [ONE] = {.fun = inst3, .txt = "cne"}, + [OBAND] = {.fun = inst3, .txt = "and"}, + [OBOR] = {.fun = inst3, .txt = "or"}, + [OBXOR] = {.fun = inst3, .txt = "xor"} +}; + /* * : is for user-defined Aggregate Types * $ is for globals (represented by a pointer) @@ -181,10 +205,38 @@ writeout(void) symname(p), size2asm(tp), tp->size, tp->align); } + for (pc = prog; pc; pc = pc->next) { + if (pc->label) + printf("%s:\n", symname(pc->label)); + (*optbl[pc->op].fun)(); + } puts("}"); } +static char * +addr2txt(Addr *a) +{ + static char buff[40]; + + switch (a->kind) { + case AUTO: + case LABEL: + return symname(a->u.sym); + default: + abort(); + } +} + +static void +inst3(void) +{ + printf("\t%s %c= %s\t%s,%s\n", + addr2txt(&pc->to), + optbl[pc->op].txt, + addr2txt(&pc->from1), addr2txt(&pc->from2)); +} + void endinit(void) { diff --git a/cc2/cc2.h b/cc2/cc2.h @@ -138,7 +138,8 @@ struct symbol { char kind; union { TSIZE off; - Node *label; + Node *nlabel; + Inst *ilabel; } u; Symbol *next; Symbol *h_next; @@ -173,6 +174,7 @@ struct addr { struct inst { char op; + Symbol *label; Addr from1, from2, to; Inst *next, *prev; }; @@ -216,3 +218,4 @@ extern void freesym(Symbol *sym); /* globals */ extern Symbol *locals; +extern Inst *pc, *prog; diff --git a/cc2/code.c b/cc2/code.c @@ -4,7 +4,7 @@ #include "arch.h" #include "cc2.h" -static Inst *pc, *prog; +Inst *pc, *prog; static void nextpc(void) diff --git a/cc2/node.c b/cc2/node.c @@ -80,6 +80,6 @@ apply(Node *(*fun)(Node *)) if (!curfun) return; - for (np = curfun->u.label; np; np = np->stmt) + for (np = curfun->u.nlabel; np; np = np->stmt) (*fun)(np); } diff --git a/cc2/parser.c b/cc2/parser.c @@ -587,14 +587,14 @@ labeldcl(void) delnode(np); nextline(); stmtp->label = sym; - sym->u.label = stmtp; + sym->u.nlabel = stmtp; } static void addstmt(Node *np) { - if (!curfun->u.label) - curfun->u.label = np; + if (!curfun->u.nlabel) + curfun->u.nlabel = np; else stmtp->stmt = np; stmtp = np;