Функция printfn
Функция printfn(Fn *fn, FILE *f) - функция, реализованная в Си интерфейсе QBE. Располагается в файле parse.c и "подключается" в all.h.
Назначение[править]
printfn осуществляет печать функции fn в виде кода на QBE.
Исходный код[править]
Функция printfn из parse.c
void printfn(Fn *fn, FILE *f)
{
static char ktoc[] = "wlsd";
static char *jtoa[NJmp] = {
#define X(j) [J##j] = #j,
JMPS(X)
#undef X
};
Blk *b;
Phi *p;
Ins *i;
uint n;
if (fn->export)
fprintf(f, "export ");
fprintf(f, "function $%s() {\n", fn->name);
for (b=fn->start; b; b=b->link) {
fprintf(f, "@%s\n", b->name);
for (p=b->phi; p; p=p->link) {
fprintf(f, "\t");
printref(p->to, fn, f);
fprintf(f, " =%c phi ", ktoc[p->cls]);
assert(p->narg);
for (n=0;; n++) {
fprintf(f, "@%s ", p->blk[n]->name);
printref(p->arg[n], fn, f);
if (n == p->narg-1) {
fprintf(f, "\n");
break;
} else
fprintf(f, ", ");
}
}
for (i=b->ins; i-b->ins < b->nins; i++) {
fprintf(f, "\t");
if (!req(i->to, R)) {
printref(i->to, fn, f);
fprintf(f, " =%c ", ktoc[i->cls]);
}
assert(optab[i->op].name);
fprintf(f, "%s", optab[i->op].name);
if (req(i->to, R))
switch (i->op) {
case Oarg:
case Oswap:
case Oxcmp:
case Oacmp:
case Oacmn:
case Oafcmp:
case Oxtest:
case Oxdiv:
case Oxidiv:
fputc(ktoc[i->cls], f);
}
if (!req(i->arg[0], R)) {
fprintf(f, " ");
printref(i->arg[0], fn, f);
}
if (!req(i->arg[1], R)) {
fprintf(f, ", ");
printref(i->arg[1], fn, f);
}
fprintf(f, "\n");
}
switch (b->jmp.type) {
case Jret0:
case Jretw:
case Jretl:
case Jrets:
case Jretd:
case Jretc:
fprintf(f, "\t%s", jtoa[b->jmp.type]);
if (b->jmp.type != Jret0 || !req(b->jmp.arg, R)) {
fprintf(f, " ");
printref(b->jmp.arg, fn, f);
}
if (b->jmp.type == Jretc)
fprintf(f, ", :%s", typ[fn->retty].name);
fprintf(f, "\n");
break;
case Jjmp:
if (b->s1 != b->link)
fprintf(f, "\tjmp @%s\n", b->s1->name);
break;
default:
fprintf(f, "\t%s ", jtoa[b->jmp.type]);
if (b->jmp.type == Jjnz) {
printref(b->jmp.arg, fn, f);
fprintf(f, ", ");
}
fprintf(f, "@%s, @%s\n", b->s1->name, b->s2->name);
break;
}
}
fprintf(f, "}\n");
}