commit f6ede3c51c169d6115b12de5cce5b1881d0b3247
parent 0b5080ef495991eb73e8d946285a14d1ca143409
Author: Roberto E. Vargas Caballero <Roberto E. Vargas Caballero>
Date: Fri, 22 Apr 2016 00:03:16 +0200
Merge remote-tracking branch 'origin/master'
Diffstat:
6 files changed, 115 insertions(+), 29 deletions(-)
diff --git a/cc2/arch/qbe/arch.h b/cc2/arch/qbe/arch.h
@@ -5,8 +5,19 @@
#define TSIZE unsigned long
enum asmop {
- ASLOAD,
- ASASSIG,
+ ASSTB,
+ ASSTH,
+ ASSTW,
+ ASSTL,
+ ASSTS,
+ ASSTD,
+
+ ASLDB,
+ ASLDH,
+ ASLDW,
+ ASLDL,
+ ASLDS,
+ ASLDD,
ASADDW,
ASSUBW,
diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c
@@ -107,11 +107,30 @@ static Node *
load(Node *np)
{
Node *new;
+ int op;
+ Type *tp = &np->type;
new = tmpnode(newnode());
new->left = np;
- new->type = np->type;
- code(ASLOAD, new, np, NULL);
+ new->type = *tp;
+
+ switch (tp->size) {
+ case 1:
+ op = ASLDB;
+ break;
+ case 2:
+ op = ASLDH;
+ break;
+ case 4:
+ op = (tp->flags & INTF) ? ASLDW : ASLDS;
+ break;
+ case 8:
+ op = (tp->flags & INTF) ? ASLDL : ASLDD;
+ break;
+ default:
+ abort();
+ }
+ code(op, new, np, NULL);
return new;
}
@@ -133,7 +152,6 @@ cgen(Node *np)
tp = &np->type;
switch (np->op) {
- case OREG:
case OSTRING:
abort();
case OCONST:
@@ -182,8 +200,7 @@ cgen(Node *np)
l = np->left = load(l);
if ((r->flags & (ISTMP|ISCONS)) == 0)
r = np->right = load(r);
- tmpnode(np);
- code(op, np, l, r);
+ code(op, tmpnode(np), l, r);
return np;
case ONOP:
case OBLOOP:
@@ -198,7 +215,23 @@ cgen(Node *np)
case ODEC:
abort();
case OASSIG:
- code(ASASSIG, l, r, NULL);
+ switch (tp->size) {
+ case 1:
+ op = ASSTB;
+ break;
+ case 2:
+ op = ASSTH;
+ break;
+ case 4:
+ op = (tp->flags & INTF) ? ASSTW : ASSTS;
+ break;
+ case 8:
+ op = (tp->flags & INTF) ? ASSTL : ASSTD;
+ break;
+ default:
+ abort();
+ }
+ code(op, l, r, NULL);
return r;
case OCALL:
case OFIELD:
diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c
@@ -16,8 +16,19 @@ static struct opdata {
char *txt;
char letter;
} optbl [] = {
- [ASLOAD] = {.fun = load, .txt = "load", .letter = 'w'},
- [ASASSIG] = {.fun = store, .txt = "store", .letter = 'w'},
+ [ASLDB] = {.fun = load, .txt = "load", .letter = 'b'},
+ [ASLDH] = {.fun = load, .txt = "load", .letter = 'h'},
+ [ASLDW] = {.fun = load, .txt = "load", .letter = 'w'},
+ [ASLDL] = {.fun = load, .txt = "load", .letter = 'l'},
+ [ASLDS] = {.fun = load, .txt = "load", .letter = 's'},
+ [ASLDD] = {.fun = load, .txt = "load", .letter = 'd'},
+
+ [ASSTB] = {.fun = store, .txt = "store", .letter = 'b'},
+ [ASSTH] = {.fun = store, .txt = "store", .letter = 'h'},
+ [ASSTW] = {.fun = store, .txt = "store", .letter = 'w'},
+ [ASSTL] = {.fun = store, .txt = "store", .letter = 'l'},
+ [ASSTS] = {.fun = store, .txt = "store", .letter = 's'},
+ [ASSTD] = {.fun = store, .txt = "store", .letter = 'd'},
[ASADDW] = {.fun = binary, .txt = "add", .letter = 'w'},
[ASSUBW] = {.fun = binary, .txt = "sub", .letter = 'w'},
@@ -250,31 +261,53 @@ data(Node *np)
putchar('\n');
}
+static void
+alloc(Symbol *sym)
+{
+ Type *tp = &sym->type;
+
+ printf("\t%s %s=\talloc%lld\t%lld\n",
+ symname(sym), size2asm(tp),
+ (long long) tp->size, (long long) tp->align);
+}
+
void
writeout(void)
{
Symbol *p;
Type *tp;
- char *sep;
+ char *sep, *name;
if (curfun->kind == SGLOB)
fputs("export ", stdout);
- printf("function %s %s(", size2asm(&curfun->rtype), symname(curfun));
+ printf("function %s %s(", size2asm(&rtype), symname(curfun));
+ /* declare formal parameters */
for (sep = "", p = locals; p; p = p->next, sep = ",") {
if ((p->type.flags & PARF) == 0)
break;
- printf("%s%s %s", sep, size2asm(&p->type), symname(p));
+ printf("%s%s %s.val", sep, size2asm(&p->type), symname(p));
}
- puts(")");
+ puts(")\n{");
+
+ /* allocate stack space for parameters */
+ for (p = locals; p && (p->type.flags & PARF) == 0; p = p->next)
+ alloc(p);
- for ( ; p && p->id != TMPSYM; p = p->next) {
+ /* allocate stack space for local variables) */
+ for ( ; p && p->id != TMPSYM; p = p->next)
+ alloc(p);
+
+ /* store formal parameters in parameters */
+ for (p = locals; p; p = p->next) {
tp = &p->type;
- printf("\t%s %s=\talloc%lld\t%lld\n",
- symname(p), size2asm(tp),
- (long long) tp->size, (long long) tp->align);
+ if ((tp->flags & PARF) == 0)
+ break;
+ name = symname(p);
+ printf("\t\tstore%s\t%s.val,%s\n", size2asm(tp), name, name);
}
+ /* emit assembler instructions */
for (pc = prog; pc; pc = pc->next) {
if (pc->label)
printf("%s:\n", symname(pc->label));
@@ -312,18 +345,23 @@ binary(void)
static void
store(void)
{
- printf("\t\t%s%c\t", optbl[pc->op].txt, 'w'),
- fputs(addr2txt(&pc->from1), stdout);
- putchar(',');
- fputs(addr2txt(&pc->to), stdout);
- putchar('\n');
+ struct opdata *p = &optbl[pc->op];
+ char to[ADDR_LEN], from[ADDR_LEN];
+
+ strcpy(to, addr2txt(&pc->to));
+ strcpy(from, addr2txt(&pc->from1));
+ printf("\t\t%s%c\t%s,%s\n", p->txt, p->letter, from, to);
}
static void
load(void)
{
- printf("\t%s %c=\t", addr2txt(&pc->to), 'w');
- printf("%s\t%s\n", optbl[pc->op].txt, addr2txt(&pc->from1));
+ struct opdata *p = &optbl[pc->op];
+ char to[ADDR_LEN], from[ADDR_LEN];
+
+ strcpy(to, addr2txt(&pc->to));
+ strcpy(from, addr2txt(&pc->from1));
+ printf("\t%s %c=\t%s\t%s\n", to, p->letter, p->txt, from);
}
void
diff --git a/cc2/cc2.h b/cc2/cc2.h
@@ -132,7 +132,6 @@ struct type {
struct symbol {
Type type;
- Type rtype;
unsigned short id;
unsigned short numid;
char *name;
@@ -208,7 +207,6 @@ extern void cleannodes(void);
extern void delnode(Node *np);
extern void deltree(Node *np);
extern Node *newnode(void);
-extern Symbol *curfun;
/* symbol.c */
#define TMPSYM 0
@@ -218,5 +216,7 @@ extern void pushctx(void);
extern void freesym(Symbol *sym);
/* globals */
+extern Type rtype;
+extern Symbol *curfun;
extern Symbol *locals;
extern Inst *pc, *prog;
diff --git a/cc2/node.c b/cc2/node.c
@@ -10,6 +10,7 @@
#define NNODES 32
Symbol *curfun;
+Type rtype;
struct arena {
Node *mem;
diff --git a/cc2/parser.c b/cc2/parser.c
@@ -181,10 +181,13 @@ static void
symbol(char *token, union tokenop u)
{
Node *np;
+ Symbol *sym;
sclass = u.op >> 8;
np = newnode();
- np->u.sym = getsym(atoi(token+1));
+ sym = getsym(atoi(token+1));
+ np->u.sym = sym;
+ np->type = sym->type;
np->op = u.op & 0xFF;
push(np);
}
@@ -534,7 +537,7 @@ vardecl(void)
sym->name = name;
sym->type = *tp;
if (tp->flags & FUNF)
- sym->rtype = *rp;
+ rtype = *rp;
sym->kind = sclass;
if (ininit)