145 lines
2.7 KiB
C
145 lines
2.7 KiB
C
#include "libqbe.h"
|
|
#include <getopt.h>
|
|
#include <stdio.h>
|
|
|
|
Target T;
|
|
|
|
char debug['Z'+1] = {
|
|
['P'] = 0, /* parsing */
|
|
['M'] = 0, /* memory optimization */
|
|
['N'] = 0, /* ssa construction */
|
|
['C'] = 0, /* copy elimination */
|
|
['F'] = 0, /* constant folding */
|
|
['A'] = 0, /* abi lowering */
|
|
['I'] = 0, /* instruction selection */
|
|
['L'] = 0, /* liveness */
|
|
['S'] = 0, /* spilling */
|
|
['R'] = 0, /* reg. allocation */
|
|
};
|
|
|
|
static FILE *outf;
|
|
static int dbg;
|
|
|
|
static void
|
|
data(Dat *d)
|
|
{
|
|
if (dbg)
|
|
return;
|
|
emitdat(d, outf);
|
|
if (d->type == DEnd) {
|
|
fputs("/* end data */\n\n", outf);
|
|
freeall();
|
|
}
|
|
}
|
|
|
|
static void
|
|
func(Fn *fn)
|
|
{
|
|
uint n;
|
|
|
|
if (dbg)
|
|
fprintf(stderr, "**** Function %s ****", fn->name);
|
|
if (debug['P']) {
|
|
fprintf(stderr, "\n> After parsing:\n");
|
|
printfn(fn, stderr);
|
|
}
|
|
T.abi0(fn);
|
|
fillrpo(fn);
|
|
fillpreds(fn);
|
|
filluse(fn);
|
|
promote(fn);
|
|
filluse(fn);
|
|
ssa(fn);
|
|
filluse(fn);
|
|
ssacheck(fn);
|
|
fillalias(fn);
|
|
loadopt(fn);
|
|
filluse(fn);
|
|
fillalias(fn);
|
|
coalesce(fn);
|
|
filluse(fn);
|
|
ssacheck(fn);
|
|
copy(fn);
|
|
filluse(fn);
|
|
fold(fn);
|
|
T.abi1(fn);
|
|
simpl(fn);
|
|
fillpreds(fn);
|
|
filluse(fn);
|
|
T.isel(fn);
|
|
fillrpo(fn);
|
|
filllive(fn);
|
|
fillloop(fn);
|
|
fillcost(fn);
|
|
spill(fn);
|
|
rega(fn);
|
|
fillrpo(fn);
|
|
simpljmp(fn);
|
|
fillpreds(fn);
|
|
fillrpo(fn);
|
|
assert(fn->rpo[0] == fn->start);
|
|
for (n=0;; n++)
|
|
if (n == fn->nblk-1) {
|
|
fn->rpo[n]->link = 0;
|
|
break;
|
|
} else
|
|
fn->rpo[n]->link = fn->rpo[n+1];
|
|
if (!dbg) {
|
|
T.emitfn(fn, outf);
|
|
fprintf(outf, "/* end function %s */\n\n", fn->name);
|
|
} else
|
|
fprintf(stderr, "\n");
|
|
freeall();
|
|
}
|
|
|
|
static void
|
|
dbgfile(char *fn)
|
|
{
|
|
emitdbgfile(fn, outf);
|
|
}
|
|
|
|
const char*
|
|
qbe_gen(Target target, const char* ssa)
|
|
{
|
|
T = target;
|
|
FILE *inf = tmpfile();
|
|
fputs(ssa, inf);
|
|
rewind(inf);
|
|
outf = tmpfile();
|
|
char* f = "-";
|
|
|
|
parse(inf, f, dbgfile, data, func);
|
|
fclose(inf);
|
|
|
|
if (!dbg)
|
|
T.emitfin(outf);
|
|
|
|
fseek(outf, 0, SEEK_END);
|
|
long size = ftell(outf);
|
|
fseek(outf, 0, SEEK_SET);
|
|
|
|
char* buf = malloc(size + 1);
|
|
fread(buf, size, 1, outf);
|
|
buf[size] = '\0';
|
|
|
|
fclose(outf);
|
|
|
|
return buf;
|
|
}
|
|
|
|
void
|
|
qbe_emit(const char* filename, const char* assembly) {
|
|
char cc[255];
|
|
snprintf(cc, 255, "cc -x assembler -o %s -", filename);
|
|
|
|
FILE* cc_pipe = popen(cc, "w");
|
|
if(fputs(assembly, cc_pipe) == EOF) {
|
|
perror("fputs");
|
|
}
|
|
pclose(cc_pipe);
|
|
}
|
|
|
|
void
|
|
qbe_gen_and_emit(Target target, const char* filename, const char* ssa) {
|
|
qbe_emit(filename, qbe_gen(target, ssa));
|
|
}
|