/* bbcall - build tree to set _callsite at call site *cp, emit call site data */ static void bbcall(Symbol yycounts, Coordinate* cp, Tree* e) { static Symbol caller; Value v; union coordinate u; Symbol p = genident(STATIC, array(voidptype, 0, 0), GLOBAL); Tree t = *e; defglobal(p, LIT); defpointer(cp->file ? mkstr(cp->file)->u.c.loc : (Symbol)0); defpointer(mkstr(cfunc->name)->u.c.loc); if (IR->little_endian) { u.le.x = cp->x; u.le.y = cp->y; } else { u.be.x = cp->x; u.be.y = cp->y; } (*IR->defconst)(U, unsignedtype->size, (v.u = u.coord, v)); if (caller == 0) { caller = mksymbol(EXTERN, "_caller", ptr(voidptype)); caller->defined = 0; } if (generic((*e)->op) != CALL) t = (*e)->kids[0]; assert(generic(t->op) == CALL); t = tree(t->op, t->type, tree(RIGHT, t->kids[0]->type, t->kids[0], tree(RIGHT, t->kids[0]->type, asgn(caller, idtree(p)), t->kids[0])), t->kids[1]); if (generic((*e)->op) != CALL) t = tree((*e)->op, (*e)->type, t, (*e)->kids[1]); *e = t; }
/* bbvars - emit definition for basic block counting data */ static void bbvars(Symbol yylink) { int i, j, n = npoints; Value v; struct map** mp; Symbol coords, files, *p; if (!YYcounts && !yylink) return; if (YYcounts) { if (n <= 0) n = 1; YYcounts->type = array(unsignedtype, n, 0); defglobal(YYcounts, BSS); } files = genident(STATIC, array(charptype, 1, 0), GLOBAL); defglobal(files, LIT); for (p = ltov(&filelist, PERM); *p; p++) defpointer((*p)->u.c.loc); defpointer(NULL); coords = genident(STATIC, array(unsignedtype, n, 0), GLOBAL); defglobal(coords, LIT); for (i = n, mp = ltov(&maplist, PERM); *mp; i -= (*mp)->size, mp++) for (j = 0; j < (*mp)->size; j++) (*IR->defconst)(U, unsignedtype->size, (v.u = (*mp)->u[j].coord, v)); if (i > 0) (*IR->space)(i * coords->type->type->size); defpointer(NULL); defglobal(yylink, DATA); defpointer(NULL); (*IR->defconst)(U, unsignedtype->size, (v.u = n, v)); defpointer(YYcounts); defpointer(coords); defpointer(files); defpointer(funclist); }
/* bbfunc - emit function name and src coordinates */ static void bbfunc(Symbol yylink, Symbol f) { Value v; union coordinate u; defglobal(afunc, DATA); defpointer(funclist); defpointer(NULL); defpointer(mkstr(f->name)->u.c.loc); if (IR->little_endian) { u.le.x = f->u.f.pt.x; u.le.y = f->u.f.pt.y; u.le.index = bbfile(f->u.f.pt.file); } else { u.be.x = f->u.f.pt.x; u.be.y = f->u.f.pt.y; u.be.index = bbfile(f->u.f.pt.file); } (*IR->defconst)(U, unsignedtype->size, (v.u = u.coord, v)); funclist = afunc; }
/* emit_value - emits an initialization for the type given by ty */ static int emit_value(int lc, Type ty, ...) { Value v; va_list ap; va_start(ap, ty); if (lc == 0) maxalign = 0; lc = pad(ty->align, lc); switch (ty->op) { case INT: v.i = va_arg(ap, long); break; case UNSIGNED: v.u = va_arg(ap, unsigned long); break; case FLOAT: v.d = va_arg(ap, long double); break; case POINTER: defpointer(va_arg(ap, Symbol)); return lc + ty->size; default: assert(0); } va_end(ap); (*IR->defconst)(ty->op, ty->size, v); return lc + ty->size; }