Функция 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"); }