11 #define O(op, t, cf) [O##op]={#op, t, cf},    76 static char *kwmap[
Ntok] = {
   111 static char lexh[1 << (32-
M)];
   139     fprintf(stderr, 
"%s:%d: ", inpath, lnum);
   140     vfprintf(stderr, s, ap);
   141     fprintf(stderr, 
"\n");
   158     assert(
Ntok <= CHAR_MAX);
   159     for (i=0; i<
Ntok; ++i)
   161             h = 
hash(kwmap[i])*
K >> 
M;
   162             assert(lexh[h] == 
Txxx);
   179     case '+': c = fgetc(inf);
   182         n = 10*n + (c - 
'0');
   184     } 
while (
'0' <= c && c <= 
'9');
   188     return *(int64_t *)&n;
   221         if (fscanf(inf, 
"_%f", &tokval.flts) != 1)
   225         if (fscanf(inf, 
"_%lf", &tokval.fltd) != 1)
   241         while ((c=fgetc(inf)) != 
'\n' && c != EOF)
   247     if (isdigit(c) || c == 
'-' || c == 
'+') {
   249         tokval.num = getint();
   258                 err(
"unterminated string");
   259             vgrow(&tokval.str, i+1);
   260             if (c == 
'"' && !esc) {
   264             esc = (c == 
'\\' && !esc);
   269 Alpha:      c = fgetc(inf);
   270     if (!isalpha(c) && c != 
'.' && c != 
'_')
   271         err(
"invalid character %c (%d)", c, c);
   275             err(
"identifier too long");
   278     } 
while (isalpha(c) || c == 
'$' || c == 
'.' || c == 
'_' || isdigit(c));
   285     t = lexh[
hash(tok)*
K >> 
M];
   286     if (t == 
Txxx || strcmp(kwmap[t], tok) != 0) {
   287         err(
"unknown keyword %s", tok);
   316     while ((t = next()) == 
Tnl)
   324     static char *ttoa[] = {
   335     char buf[128], *s1, *s2;
   341     s1 = ttoa[t] ? ttoa[t] : 
"??";
   342     s2 = ttoa[t1] ? ttoa[t1] : 
"??";
   343     sprintf(buf, 
"%s expected, got %s instead", s1, s2);
   353         if (strcmp(v, curf->
tmp[t].
name) == 0)
   366     memset(&c, 0, 
sizeof c);
   369         return tmpref(tokval.str);
   372         c.
bits.
i = tokval.num;
   376         c.
bits.
s = tokval.flts;
   381         c.
bits.
d = tokval.fltd;
   388         for (i=0; i<curf->
ncon; i++)
   405         if (strcmp(tokval.str, 
typ[i].
name) == 0)
   407     err(
"undefined type :%s", tokval.str);
   415         err(
"invalid class specifier");
   417         *tyn = findtyp(ntyp);
   433     int k, ty, env, hasenv;
   440             err(
"too many instructions (1)");
   441         env = peek() == 
Tenv;
   449             err(
"invalid argument");
   451             err(
"only one environment allowed");
   452         if (!arg && rtype(r) != 
RTmp)
   453             err(
"invalid function parameter");
   475     if (next() == 
Tdots) {
   489     for (b=blkh[h]; b; b=b->
dlink)
   490         if (strcmp(b->
name, name) == 0)
   494     strcpy(b->
name, name);
   521         err(
"label or } expected");
   533         err(
"label, instruction or jump expected");
   539         b = findblk(tokval.str);
   546             err(
"multiple definitions of block @%s", b->
name);
   563                 err(
"invalid return value");
   574             err(
"invalid argument for jnz jump");
   579         curb->
s1 = findblk(tokval.str);
   583             curb->
s2 = findblk(tokval.str);
   586             err(
"invalid jump to the start node");
   592     r = tmpref(tokval.str);
   599             err(
"unexpected phi instruction");
   621         err(
"size class must be w, l, s, or d");
   623         err(
"invalid instruction");
   628                 err(
"too many arguments");
   631                 blk[i] = findblk(tokval.str);
   635                 err(
"invalid instruction argument");
   641                 err(
", or end of line expected");
   648             err(
"too many instructions (2)");
   657         phi = 
alloc(
sizeof *phi);
   660         memcpy(phi->
arg, arg, i * 
sizeof arg[0]);
   661         memcpy(phi->
blk, blk, i * 
sizeof blk[0]);
   670 usecheck(
Ref r, 
int k, 
Fn *fn)
   695             if (rtype(i->
to) == 
RTmp) {
   698                     err(
"temporary %%%s is assigned with"   699                         " multiple types", t->
name);
   704         for (n=0; n<b->
npred; n++)
   709             for (n=0; n<p->
narg; n++) {
   711                 if (bshas(ppb, p->
blk[n]->
id))
   712                     err(
"multiple entries for @%s in phi %%%s",
   714                 if (!usecheck(p->
arg[n], k, fn))
   715                     err(
"invalid type for operand %%%s in phi %%%s",
   720                 err(
"predecessors not matched in phi %%%s", t->
name);
   723             for (n=0; n<2; n++) {
   728                     err(
"invalid instruction type in %s",
   730                 if (rtype(r) == 
RType)
   732                 if (rtype(r) != -1 && k == 
Kx)
   733                     err(
"no %s operand expected in %s",
   734                         n == 1 ? 
"second" : 
"first",
   736                 if (rtype(r) == -1 && k != 
Kx)
   737                     err(
"missing %s operand in %s",
   738                         n == 1 ? 
"second" : 
"first",
   740                 if (!usecheck(r, k, fn))
   741                     err(
"invalid type for %s operand %%%s in %s",
   742                         n == 1 ? 
"second" : 
"first",
   748                 if (!usecheck(r, 
Kl, fn))
   755             err(
"invalid type for jump argument %%%s in block @%s",
   758             err(
"block @%s is used undefined", b->
s1->
name);
   760             err(
"block @%s is used undefined", b->
s2->
name);
   774     curf = 
alloc(
sizeof *curf);
   779     for (i=0; i<
Tmp0; ++i)
   780         if (
T.fpr0 <= i && i < 
T.fpr0 + 
T.nfpr)
   786     blink = &curf->
start;
   789         rcls = parsecls(&curf->
retty);
   793         err(
"function name expected");
   794     strcpy(curf->
name, tokval.str);
   795     curf->
vararg = parserefl(0);
   797         err(
"function body must start with {");
   803         err(
"empty function");
   805         err(
"last block misses jump");
   810     for (b=0; b; b=b->
link)
   812     for (i=0; i<
BMask+1; ++i)
   819 parsefields(
Field *fld, 
Typ *ty, 
int t)
   822     int n, c, a, al, 
type;
   831         default: 
err(
"invalid type member specifier");
   832         case Td: 
type = 
Fd; s = 8; a = 3; 
break;
   833         case Tl: 
type = 
Fl; s = 8; a = 3; 
break;
   834         case Ts: 
type = 
Fs; s = 4; a = 2; 
break;
   835         case Tw: 
type = 
Fw; s = 4; a = 2; 
break;
   836         case Th: 
type = 
Fh; s = 2; a = 1; 
break;
   837         case Tb: 
type = 
Fb; s = 1; a = 0; 
break;
   840             ty1 = &
typ[findtyp(ntyp-1)];
   866         for (; c>0 && n<
NField; c--, n++) {
   875         err(
", or } expected");
   880     ty->
size = (sz + a - 1) & -a;
   900     if (nextnl() != 
Ttyp ||  nextnl() != 
Teq)
   901         err(
"type name and then = expected");
   902     strcpy(ty->
name, tokval.str);
   905         if (nextnl() != 
Tint)
   906             err(
"alignment expected");
   907         for (al=0; tokval.num /= 2; al++)
   913         err(
"type body must start with {");
   917         ty->
size = tokval.num;
   919             err(
"dark types need alignment");
   929                 err(
"invalid union member");
   931             parsefields(ty->
fields[n++], ty, nextnl());
   935         parsefields(ty->
fields[n++], ty, t);
   945     d->
u.
ref.nam = tokval.str;
   951             err(
"invalid token after offset in ref");
   952         d->
u.
ref.off = tokval.num;
   960     d->
u.
str = tokval.str;
   964 parsedat(
void cb(
Dat *), 
int export)
   975     if (nextnl() != 
Tglo || nextnl() != 
Teq)
   976         err(
"data name, then = expected");
   977     strcpy(s, tokval.str);
   980         if (nextnl() != 
Tint)
   981             err(
"alignment expected");
   983         d.
u.
num = tokval.num;
   992         err(
"expected data contents in { .. }");
   995         default: 
err(
"invalid size specifier %c in data", tokval.chr);
   997         case Tl: d.
type = DL; 
break;
   998         case Tw: d.
type = DW; 
break;
   999         case Th: d.
type = DH; 
break;
  1000         case Tb: d.
type = DB; 
break;
  1001         case Ts: d.
type = DW; 
break;
  1002         case Td: d.
type = DL; 
break;
  1003         case Tz: d.
type = DZ; 
break;
  1009             memset(&d.
u, 0, 
sizeof d.
u);
  1011                 d.
u.
flts = tokval.flts;
  1012             else if (t == 
Tfltd)
  1013                 d.
u.
fltd = tokval.fltd;
  1015                 d.
u.
num = tokval.num;
  1021                 err(
"constant literal expected");
  1028             err(
", or } expected");
  1046 parse(FILE *f, 
char *path, 
void (*data)(
Dat *), 
void (*func)(
Fn *))
  1061             err(
"top-level definition expected");
  1067                 func(parsefn(export));
  1070             else if (t == 
Tdata) {
  1072                 parsedat(data, export);
  1076                 err(
"export can only qualify data and function");
  1088 printcon(
Con *c, FILE *f)
  1096             fprintf(f, 
"%+"PRIi64, c->
bits.
i);
  1100             fprintf(f, 
"s_%f", c->
bits.
s);
  1101         else if (c->
flt == 2)
  1102             fprintf(f, 
"d_%lf", c->
bits.
d);
  1104             fprintf(f, 
"%"PRIi64, c->
bits.
i);
  1118             fprintf(f, 
"R%d", r.
val);
  1123         printcon(&fn->
con[r.
val], f);
  1126         fprintf(f, 
"S%d", (r.
val&(1<<28)) ? r.
val-(1<<29) : r.
val);
  1129         fprintf(f, 
"%04x", r.
val);
  1142         if (!req(m->
base, 
R)) {
  1151             fprintf(f, 
"%d * ", m->
scale);
  1162     static char ktoc[] = 
"wlsd";
  1163     static char *jtoa[
NJmp] = {
  1164     #define X(j) [J##j] = #j,  1174         fprintf(f, 
"export ");
  1175     fprintf(f, 
"function $%s() {\n", fn->
name);
  1177         fprintf(f, 
"@%s\n", b->
name);
  1178         for (p=b->
phi; p; p=p->
link) {
  1181             fprintf(f, 
" =%c phi ", ktoc[p->
cls]);
  1184                 fprintf(f, 
"@%s ", p->
blk[n]->
name);
  1186                 if (n == p->
narg-1) {
  1195             if (!req(i->
to, 
R)) {
  1197                 fprintf(f, 
" =%c ", ktoc[i->
cls]);
  1212                     fputc(ktoc[i->
cls], f);
  1214             if (!req(i->
arg[0], 
R)) {
  1218             if (!req(i->
arg[1], 
R)) {
  1231             fprintf(f, 
"\t%s", jtoa[b->
jmp.
type]);
  1242                 fprintf(f, 
"\tjmp @%s\n", b->
s1->
name);
  1245             fprintf(f, 
"\t%s ", jtoa[b->
jmp.
type]);
 
#define X(NMemArgs, SetsZeroFlag, LeavesFlags)
Blk * start
Указатель на блок функции, являющийся её входной точкой 
int ncon
Размер массива con. 
void parse(FILE *f, char *path, void(*data)(Dat *), void(*func)(Fn *))
Парсит файл с программой на QBE IL. 
Структура, хранящая информацию об инструкциях. 
int clsmerge(short *, short)
int retty
index in typ[], -1 if no aggregate return 
void * vnew(ulong, size_t, Pool)
struct Typ::Field(* fields)[NField+1]
void printfn(Fn *fn, FILE *f)
Con * con
Массив используемых функцией констант 
void bsinit(BSet *, uint)
Структура, хранящая описание переменных (более подробное описание переменной ищите в Tmp)...
Содержит информацию о переменной 
Tmp * tmp
Массив используемых функцией переменных 
int ntmp
Размер массива tmp. 
Непосредственно информация о базовом блоке. 
void idup(Ins **, Ins *, ulong)
int bsequal(BSet *, BSet *)
char name[NString]
Имя переменной 
Op optab[NOp]
Массив всех операций. 
void vgrow(void *, ulong)
uint nblk
Количество блоков в функции 
void printref(Ref r, Fn *fn, FILE *f)
Blk ** rpo
Ссылка на массив блоков, пронумерованных в порядке Reverse-Post Order, заполняется функцией fillrpo...
int nmem
Размер массива mem. 
Номер (в массиве Fn->tmp) первой не регистровой переменной 
char name[NString]
Имя функции 
Ref newtmp(char *, int, Fn *)
#define T(a, b, c, d, e, f, g, h)
Структура, хранящая в себе информацию о функции 
Структура, хранящая информацию об операции.