ref: 36a3a5fa99dc4887ca46c7807436ad44da19422f
dir: /8/isel.c/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "parse.h"
#include "gen.h"
#include "asm.h"
typedef struct Isel Isel;
struct Isel {
Insn **il;
size_t ni;
};
char *regnames[] = {
#define Reg(r, name) name,
#include "regs.def"
#undef Reg
};
char *insnfmts[] = {
#define Insn(val, fmt, attr) fmt,
#include "insns.def"
#undef Insn
};
void selexpr(Node *n)
{
switch (exprop(n)) {
case Obad:
case Oadd:
case Osub:
case Omul:
case Odiv:
case Omod:
case Oneg:
case Obor:
case Oband:
case Obxor:
case Obsl:
case Obsr:
case Obnot:
case Opreinc:
case Opostinc:
case Opredec:
case Opostdec:
case Oaddr:
case Oderef:
case Olor:
case Oland:
case Olnot:
case Oeq:
case One:
case Ogt:
case Oge:
case Olt:
case Ole:
case Oasn:
case Oaddeq:
case Osubeq:
case Omuleq:
case Odiveq:
case Omodeq:
case Oboreq:
case Obandeq:
case Obxoreq:
case Obsleq:
case Obsreq:
case Oidx:
case Oslice:
case Omemb:
case Osize:
case Ocall:
case Ocast:
case Oret:
case Ojmp:
case Ocjmp:
case Ovar:
case Olit:
case Olbl:
break;
}
}
void ilbl(Isel *s, char *name)
{
}
void locprint(FILE *fd, Loc *l)
{
switch (l->type) {
case Loclbl:
fprintf(fd, "%s", l->lbl);
break;
case Locreg:
fprintf(fd, "%s", regnames[l->reg]);
break;
case Locmem:
case Locmeml:
if (l->type == Locmem) {
if (l->mem.constdisp)
fprintf(fd, "%ld", l->mem.constdisp);
} else {
if (l->mem.lbldisp)
fprintf(fd, "%s", l->mem.lbldisp);
}
if (l->mem.base)
fprintf(fd, "(%s", regnames[l->mem.base]);
if (l->mem.idx)
fprintf(fd, ",%s", regnames[l->mem.idx]);
if (l->mem.base)
fprintf(fd, ")");
break;
break;
case Loclit:
break;
}
}
void modeprint(FILE *fd, Loc *l)
{
char mode[] = {'b', 's', 'l', 'q'};
fputc(mode[l->mode], fd);
}
void iprintf(FILE *fd, Insn *insn)
{
char *p;
int i;
int modeidx;
p = insnfmts[insn->op];
for (; *p; p++) {
if (*p != '%') {
fputc(*p, fd);
continue;
}
/* %-formating */
p++;
switch (*p) {
case '\0':
goto done;
case 'r':
case 'm':
case 'l':
case 'x':
case 'v':
locprint(fd, &insn->args[i]);
i++;
break;
case 't':
default:
if (isdigit(*p))
modeidx = strtol(p, &p, 10);
else
modeidx = 0;
modeprint(fd, &insn->args[modeidx]);
break;
}
}
done:
return;
}
void isel(Node *n)
{
struct Isel is = {0,};
switch (n->type) {
case Nlbl:
ilbl(&is, n->lbl.name);
break;
case Nexpr:
selexpr(n);
break;
case Ndecl:
break;
default:
die("Bad node type in isel()");
break;
}
}