ref: 1fb38e3bfef9e594f46b257c63ed0acb6c9a1cba
dir: /cc2/code.c/
#include <stdarg.h>
#include <stdlib.h>
#include <inttypes.h>
#include <stdio.h>
#include "../inc/cc.h"
#include "cc2.h"
static char *regnames[] = {
[AF] = "AF",
[HL] = "HL", [DE] = "DE", [BC] = "BC",
[IX] = "IX", [IY] = "IY", [SP] = "SP",
[A] = "A",
[B] = "B", [C] = "C",
[D] = "D", [E] = "E",
[H] = "H", [L] = "L",
[IYL]= "IYL",[IYH]= "IYH"
};
static void inst0(void), inst1(void), inst2(void);
static void (*instcode[])(void) = {
[LDW] = inst2,
[LDL] = inst2,
[LDH] = inst2,
[LDI] = inst2,
[MOV] = inst2,
[ADD] = inst2,
[PUSH] = inst1,
[POP] = inst1,
[RET] = inst0,
[NOP] = inst0,
[INC] = inst1
};
static char *insttext[] = {
[LDW] = "LD",
[LDL] = "LD",
[LDH] = "LD",
[LDI] = "LD",
[MOV] = "LD",
[ADD] = "ADD",
[PUSH] = "PUSH",
[POP] = "POP",
[RET] = "RET",
[NOP] = "NOP",
[INC] = "INC"
};
typedef struct inst Inst;
typedef struct addr Addr;
struct addr {
char kind;
union {
uint8_t reg;
TINT i;
Inst *pc;
Symbol *sym;
} u;
};
struct inst {
char op;
Addr from, to;
Inst *next;
};
Inst *prog, *pc;
Inst *
nextpc(void)
{
Inst *new;
new = xmalloc(sizeof(*new));
if (!pc)
prog = new;
else
pc->next = new;
pc = new;
pc->op = NOP;
pc->to.kind = NONE;
pc->from.kind = NONE;
pc->next = NULL;
return pc;
}
void
addr(char op, Node *np, Addr *addr)
{
switch (addr->kind = np->op) {
case REG:
addr->u.reg = np->reg;
break;
case CONST:
addr->u.i = np->sym->u.imm;
break;
case AUTO:
addr->u.i = np->sym->u.v.off;
break;
case MEM:
addr->u.sym = np->sym;
break;
case INDEX:
break;
default:
abort();
}
}
void
code(uint8_t op, Node *to, Node *from)
{
Inst *ip;
ip = nextpc();
if (from)
addr(op, from, &ip->from);
if (to)
addr(op, to, &ip->to);
ip->op = op;
}
void
writeout(void)
{
if (!prog)
return;
for (pc = prog; pc; pc = pc->next)
(*instcode[pc->op])();
}
static void
addr2txt(char op, Addr *a)
{
Symbol *sym;
char *fmt;
switch (a->kind) {
case REG:
fputs(regnames[a->u.reg], stdout);
break;
case CONST:
printf("%d", a->u.i);
break;
case PAR:
case AUTO:
printf("(IX%+d)", a->u.i);
break;
case INDEX:
fputs("(HL)", stdout);
break;
case MEM:
sym = a->u.sym;
if (sym->name)
printf((op == LDI) ? "%s" : "(%s)", sym);
else
printf((op == LDI) ? "T%u" : "(T%u)", sym->id);
break;
default:
abort();
}
}
static void
inst0(void)
{
printf("\t%s\n", insttext[pc->op]);
}
static void
inst1(void)
{
char op = pc->op;
printf("\t%s\t", insttext[op]);
addr2txt(op, (pc->to.kind != NONE) ? &pc->to : &pc->from);
putchar('\n');
}
static void
inst2(void)
{
char op = pc->op;
printf("\t%s\t", insttext[op]);
addr2txt(op, &pc->to);
putchar(',');
addr2txt(op, &pc->from);
putchar('\n');
}