Esempio n. 1
0
/* bbentry - return tree for _prologue(&afunc, &YYlink)' */
static void bbentry(Symbol yylink, Symbol f) {
    static Symbol prologue;

    afunc = genident(STATIC, array(voidptype, 4, 0), GLOBAL);
    if (prologue == 0) {
        prologue = mksymbol(EXTERN, "_prologue", ftype(inttype, voidptype));
        prologue->defined = 0;
    }
    walk(vcall(prologue, voidtype, pointer(idtree(afunc)), pointer(idtree(yylink)), NULL), 0, 0);

}
Esempio n. 2
0
/* tracefinis - complete & generate the trace call to print */
static void tracefinis(Symbol printer) {
	Tree *ap;
	Symbol p;

	*fp = 0;
	p = mkstr(string(fmt));
	for (ap = &args; *ap; ap = &(*ap)->kids[1])
		;
	*ap = tree(ARG+P, charptype, pointer(idtree(p->u.c.loc)), 0);
	walk(calltree(pointer(idtree(printer)), freturn(printer->type), args, NULL), 0, 0);
	args = 0;
	fp = fmtend = 0;
}
Esempio n. 3
0
/* 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;
}
Esempio n. 4
0
/* addrof - address of p */
Tree addrof(Tree p) {
	Tree q = p;

	for (;;)
		switch (generic(q->op)) {
		case RIGHT:
			assert(q->kids[0] || q->kids[1]);
			q = q->kids[1] ? q->kids[1] : q->kids[0];
			continue;
		case ASGN:
			q = q->kids[1];
			continue;
		case COND: {
			Symbol t1 = q->u.sym;
			q->u.sym = 0;
			q = idtree(t1);
			/* fall thru */
			}
		case INDIR:
			if (p == q)
				return q->kids[0];
			q = q->kids[0];
			return tree(RIGHT, q->type, root(p), q);
		default:
			error("addressable object required\n");
			return value(p);
		}
}
Esempio n. 5
0
/* bbincr - build tree to increment execution point at *cp */
static void bbincr(Symbol yycounts, Coordinate* cp, Tree* e) {
    struct map* mp = maplist->x;
    Tree t;

    /* append *cp to source map */
    if (mp->size >= NELEMS(mp->u)) {
        NEW(mp, PERM);
        mp->size = 0;
        maplist = append(mp, maplist);
    }
    if (IR->little_endian) {
        mp->u[mp->size].le.x = cp->x;
        mp->u[mp->size].le.y = cp->y;
        mp->u[mp->size++].le.index = bbfile(cp->file);
    } else {
        mp->u[mp->size].be.x = cp->x;
        mp->u[mp->size].be.y = cp->y;
        mp->u[mp->size++].be.index = bbfile(cp->file);
    }
    t = incr('+', rvalue((*optree['+'])(ADD, pointer(idtree(yycounts)),
                                        consttree(npoints++, inttype))), consttree(1, inttype));
    if (*e)
        *e = tree(RIGHT, (*e)->type, t, *e);
    else
        *e = t;
}
Esempio n. 6
0
File: stab.c Progetto: bhanug/cdb
/* call_hook - called at function calls.
If *e is a call, call_hook changes the expression to the equivalent of
the C expression

	(tos.ip = i, *e)

where i is the stopping point index for the execution point of the
expression in which the call appears.
*/
static void call_hook(void *cl, Coordinate *cp, Tree *e) {
	assert(*e);
	*e = tree(RIGHT, (*e)->type,
		asgntree(ASGN,
			field(lvalue(idtree(tos)), string("ip")),
			cnsttree(inttype, Seq_length(pickle->spoints))),
		*e);
}
Esempio n. 7
0
File: stmt.c Progetto: 0culus/ioq3
static void cmp(int op, Symbol p, long n, int lab) {
	Type ty = signedint(p->type);

	listnodes(eqtree(op,
			cast(idtree(p), ty),
			cnsttree(ty, n)),
		lab, 0);
}
Esempio n. 8
0
/* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */
Tree asgn(Symbol p, Tree e) {
	if (isarray(p->type))
		e = tree(ASGN+B, p->type, idtree(p),
			tree(INDIR+B, e->type, e, NULL));
	else {
		Type ty = p->type;
		p->type = unqual(p->type);
		if (isstruct(p->type) && p->type->u.sym->u.s.cfields) {
			p->type->u.sym->u.s.cfields = 0;
			e = asgntree(ASGN, idtree(p), e);
			p->type->u.sym->u.s.cfields = 1;
		} else
			e = asgntree(ASGN, idtree(p), e);
		p->type = ty;
	}
	return e;
}
Esempio n. 9
0
void retcode(Tree p) {
	Type ty;

	if (p == NULL) {
		if (events.returns)
			apply(events.returns, cfunc, NULL);
		return;
	}
	p = pointer(p);
	ty = assign(freturn(cfunc->type), p);
	if (ty == NULL) {
		error("illegal return type; found `%t' expected `%t'\n",
			p->type, freturn(cfunc->type));
		return;
	}
	p = cast(p, ty);
	if (retv)
		{
			if (iscallb(p))
				p = tree(RIGHT, p->type,
					tree(CALL+B, p->type,
						p->kids[0]->kids[0], idtree(retv)),
					rvalue(idtree(retv)));
			else {
				Type ty = retv->type->type;
				assert(isstruct(ty));
				if (ty->u.sym->u.s.cfields) {
					ty->u.sym->u.s.cfields = 0;
					p = asgntree(ASGN, rvalue(idtree(retv)), p);
					ty->u.sym->u.s.cfields = 1;
				} else
					p = asgntree(ASGN, rvalue(idtree(retv)), p);
			}
			walk(p, 0, 0);
			if (events.returns)
				apply(events.returns, cfunc, rvalue(idtree(retv)));
			return;
		}
	if (events.returns)
		{
			Symbol t1 = genident(AUTO, p->type, level);
			addlocal(t1);
			walk(asgn(t1, p), 0, 0);
			apply(events.returns, cfunc, idtree(t1));
			p = idtree(t1);
		}
	if (!isfloat(p->type))
		p = cast(p, promote(p->type));
	if (isptr(p->type))
		{
			Symbol q = localaddr(p);
			if (q && (q->computed || q->generated))
				warning("pointer to a %s is an illegal return value\n",
					q->scope == PARAM ? "parameter" : "local");
			else if (q)
				warning("pointer to %s `%s' is an illegal return value\n",
					q->scope == PARAM ? "parameter" : "local", q->name);
		}
	walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0);
}
Esempio n. 10
0
/* bbexit - return tree for _epilogue(&afunc)' */
static void bbexit(Symbol yylink, Symbol f, Tree e) {
    static Symbol epilogue;

    if (epilogue == 0) {
        epilogue = mksymbol(EXTERN, "_epilogue", ftype(inttype, voidptype));
        epilogue->defined = 0;
    }
    walk(vcall(epilogue, voidtype, pointer(idtree(afunc)), NULL), 0, 0);
}
Esempio n. 11
0
/* tracereturn - generate code to trace return e */
static void tracereturn(Symbol printer, Symbol f, Tree e) {
	appendstr(f->name); appendstr("#");
	tracevalue(idtree(frameno), 0);
	appendstr(" returned");
	if (freturn(f->type) != voidtype && e) {
		appendstr(" ");
		tracevalue(e, 0);
	}
	appendstr("\n");
	tracefinis(printer);
}
Esempio n. 12
0
Tree calltree(Tree f, Type ty, Tree args, Symbol t3) {
	Tree p;

	if (args)
		f = tree(RIGHT, f->type, args, f);
	if (isstruct(ty))
		assert(t3),
		p = tree(RIGHT, ty,
			tree(CALL+B, ty, f, addrof(idtree(t3))),
			idtree(t3));
	else {
		Type rty = ty;
		if (isenum(ty))
			rty = unqual(ty)->type;
		if (!isfloat(rty))
			rty = promote(rty);
		p = tree(mkop(CALL, rty), rty, f, NULL);
		if (isptr(ty) || p->type->size > ty->size)
			p = cast(p, ty);
	}
	return p;
}
Esempio n. 13
0
/* tracecall - generate code to trace entry to f */
static void tracecall(Symbol printer, Symbol f, void *ignore) {
	int i;
	Symbol counter = genident(STATIC, inttype, GLOBAL);

	defglobal(counter, BSS);
	(*IR->space)(counter->type->size);
	frameno = genident(AUTO, inttype, level);
	addlocal(frameno);
	appendstr(f->name); appendstr("#");
	tracevalue(asgn(frameno, incr(INCR, idtree(counter), consttree(1, inttype))), 0);
	appendstr("(");
	for (i = 0; f->u.f.callee[i]; i++) {
		if (i)
			appendstr(",");
		appendstr(f->u.f.callee[i]->name); appendstr("=");
		tracevalue(idtree(f->u.f.callee[i]), 0);
	}
	if (variadic(f->type))
		appendstr(",...");
	appendstr(") called\n");
	tracefinis(printer);
}
Esempio n. 14
0
File: stab.c Progetto: bhanug/cdb
/* entry_hook - called an function entry */
static void entry_hook(void *cl, Symbol cfunc) {
	static int nfuncs;
	Type ty;

	/*
	Simulate the declaration of an sframe structure,
	but without the tag.
	*/
	ty = newstruct(STRUCT, "");
#define addfield(name,t) \
	ty->size = roundup(ty->size, t->align);\
	if (ty->align < t->align) ty->align = t->align; \
	newfield(string(name), ty, t)->offset = ty->size; \
	ty->size += t->size
	addfield("up",    voidptype);
	addfield("down",  voidptype);
	addfield("func",  inttype);
	addfield("module",inttype);
	addfield("ip",    inttype);     
#undef addfield
	ty->size = roundup(ty->size, ty->align);
	ty->u.sym->defined = 1;
	ty->u.sym->generated = 1;
	tos = genident(AUTO, ty, LOCAL);
	addlocal(tos);
	tos->defined = 1;
	/*
	 Generated the assignments to the shadow
	 frame fields.
	*/
#define set(name,e) walk(asgntree(ASGN,field(lvalue(idtree(tos)),string(#name)),(e)),0,0)
	set(down,       idtree(nub_tos));
	set(func,       cnsttree(inttype, symboluid(cfunc)));
	set(module,     cnsttree(inttype, uname));
#undef set
	walk(asgn(nub_tos, lvalue(idtree(tos))), 0, 0);
	foreach(identifiers, PARAM, setoffset, tos);
}
Esempio n. 15
0
Tree asgntree(int op, Tree l, Tree r) {
    Type aty, ty;

    r = pointer(r);
    ty = assign(l->type, r);
    if (ty)
        r = cast(r, ty);
    else {
        typeerror(ASGN, l, r);
        if (r->type == voidtype)
            r = retype(r, inttype);
        ty = r->type;
    }
    if (l->op != FIELD)
        l = lvalue(l);
    aty = l->type;
    if (isptr(aty))
        aty = unqual(aty)->type;
    if (isconst(aty)
            || (isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)) {
        if (isaddrop(l->op)
                && !l->u.sym->computed && !l->u.sym->generated)
            error("assignment to const identifier `%s'\n",
                  l->u.sym->name);
        else
            error("assignment to const location\n");
    }
    if (l->op == FIELD) {
        long n = 8 * l->u.field->type->size - fieldsize(l->u.field);
        if (n > 0 && isunsigned(l->u.field->type))
            r = bittree(BAND, r,
                        cnsttree(r->type, (unsigned long)fieldmask(l->u.field)));
        else if (n > 0) {
            if (r->op == CNST + I) {
                n = r->u.v.i;
                if (n & (1 << (fieldsize(l->u.field) - 1)))
                    n |= ~0UL << fieldsize(l->u.field);
                r = cnsttree(r->type, n);
            } else
                r = shtree(RSH,
                           shtree(LSH, r, cnsttree(inttype, n)),
                           cnsttree(inttype, n));
        }
    }
    if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
        return tree(RIGHT, ty,
                    tree(CALL + B, ty, r->kids[0]->kids[0], l),
                    idtree(l->u.sym));
    return tree(mkop(op, ty), ty, l, r);
}
Esempio n. 16
0
Tree vcall(Symbol func, Type ty, ...) {
	va_list ap;
	Tree args = NULL, e, f = pointer(idtree(func)), r = NULL;

	assert(isfunc(func->type));
	if (ty == NULL)
		ty = freturn(func->type);
	va_start(ap, ty);
	while ((e = va_arg(ap, Tree)) != NULL) {
		if (hascall(e))
			r = r == NULL ? e : tree(RIGHT, voidtype, r, e);
		args = tree(mkop(ARG, e->type), e->type, e, args);
	}
	va_end(ap);
	if (r != NULL)
		args = tree(RIGHT, voidtype, r, args);
	return calltree(f, ty, args, NULL);
}
Esempio n. 17
0
File: stab.c Progetto: bhanug/cdb
/* point_hook - called at each execution point */
static void point_hook(void *cl, Coordinate *cp, Tree *e) {
	Tree t;
	
	/*
	add breakpoint test to *e:
	(_Nub_bpflags[i] != 0 && _Nub_bp(i), *e)
	*/
	t = tree(AND, voidtype,
		(*optree[NEQ])(NE,
			rvalue((*optree['+'])(ADD,
				pointer(idtree(nub_bpflags)),
				cnsttree(inttype, Seq_length(pickle->spoints)))),
			cnsttree(inttype, 0L)),
		vcall(nub_bp, voidtype, cnsttree(inttype, Seq_length(pickle->spoints)), NULL));
	if (*e)
		*e = tree(RIGHT, (*e)->type, t, *e);
	else
		*e = t;
	Seq_addhi(pickle->spoints,
		  sym_spoint(sym_coordinate(cp->file ? cp->file : string(""), cp->x, cp->y), tail()));
}
Esempio n. 18
0
File: stmt.c Progetto: 0culus/ioq3
void swcode(Swtch swp, int b[], int lb, int ub) {
	int hilab, lolab, l, u, k = (lb + ub)/2;
	long *v = swp->values;

	if (k > lb && k < ub) {
		lolab = genlabel(1);
		hilab = genlabel(1);
	} else if (k > lb) {
		lolab = genlabel(1);
		hilab = swp->deflab->u.l.label;
	} else if (k < ub) {
		lolab = swp->deflab->u.l.label;
		hilab = genlabel(1);
	} else
		lolab = hilab = swp->deflab->u.l.label;
	l = b[k];
	u = b[k+1] - 1;
	if (u - l + 1 <= 3)
		{
			int i;
			for (i = l; i <= u; i++)
				cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label);
			if (k > lb && k < ub)
				cmp(GT, swp->sym, v[u], hilab);
			else if (k > lb)
				cmp(GT, swp->sym, v[u], hilab);
			else if (k < ub)
				cmp(LT, swp->sym, v[l], lolab);
			else
				assert(lolab == hilab),
				branch(lolab);
			walk(NULL, 0, 0);
		}
	else {
		Tree e;
		Type ty = signedint(swp->sym->type);
		Symbol table = genident(STATIC,
			array(voidptype, u - l + 1, 0), GLOBAL);
		(*IR->defsymbol)(table);
		if (!isunsigned(swp->sym->type) || v[l] != 0)
			cmp(LT, swp->sym, v[l], lolab);
		cmp(GT, swp->sym, v[u], hilab);
		e = (*optree['-'])(SUB, cast(idtree(swp->sym), ty), cnsttree(ty, v[l]));
		if (e->type->size < unsignedptr->size)
			e = cast(e, unsignedlong);
		walk(tree(JUMP, voidtype,
			rvalue((*optree['+'])(ADD, pointer(idtree(table)), e)), NULL),
			0, 0);
		code(Switch);
		codelist->u.swtch.table = table;
		codelist->u.swtch.sym = swp->sym;
		codelist->u.swtch.deflab = swp->deflab;
		codelist->u.swtch.size = u - l + 1;
		codelist->u.swtch.values = &v[l];
		codelist->u.swtch.labels = &swp->labels[l];
		if (v[u] - v[l] + 1 >= 10000)
			warning("switch generates a huge table\n");
	}
	if (k > lb) {
		assert(lolab != swp->deflab->u.l.label);
		definelab(lolab);
		swcode(swp, b, lb, k - 1);
	}
	if (k < ub) {
		assert(hilab != swp->deflab->u.l.label);
		definelab(hilab);
		swcode(swp, b, k + 1, ub);
	}
}
Esempio n. 19
0
File: stab.c Progetto: bhanug/cdb
/* return_hook - called at return statements.
For return *e, return_hook changes the expression to be the equivalent of
the C expression

	(_Nub_tos = tos.down, *e)
*/
static void return_hook(void *cl, Symbol cfunc, Tree *e) {
	walk(asgn(nub_tos, field(lvalue(idtree(tos)), string("down"))), 0, 0);
}
Esempio n. 20
0
Tree call(Tree f, Type fty, Coordinate src) {
	int n = 0;
	Tree args = NULL, r = NULL, e;
	Type *proto, rty = unqual(freturn(fty));
	Symbol t3 = NULL;

	if (fty->u.f.oldstyle)
		proto = NULL;
	else
		proto = fty->u.f.proto;
	if (hascall(f))
		r = f;
	if (isstruct(rty))
		{
			t3 = temporary(AUTO, unqual(rty));
			if (rty->size == 0)
				error("illegal use of incomplete type `%t'\n", rty);
		}
	if (t != ')')
		for (;;) {
			Tree q = pointer(expr1(0));
			if (proto && *proto && *proto != voidtype)
				{
					Type aty;
					q = value(q);
					aty = assign(*proto, q);
					if (aty)
						q = cast(q, aty);
					else
						error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f),

							q->type, *proto);
					if ((isint(q->type) || isenum(q->type))
					&& q->type->size != inttype->size)
						q = cast(q, promote(q->type));
					++proto;
				}
			else
				{
					if (!fty->u.f.oldstyle && *proto == NULL)
						error("too many arguments to %s\n", funcname(f));
					q = value(q);
					if (isarray(q->type) || q->type->size == 0)
						error("type error in argument %d to %s; `%t' is illegal\n", n + 1, funcname(f), q->type);

					else
						q = cast(q, promote(q->type));
				}
			if (!IR->wants_argb && isstruct(q->type))
				if (iscallb(q))
					q = addrof(q);
				else {
					Symbol t1 = temporary(AUTO, unqual(q->type));
					q = asgn(t1, q);
					q = tree(RIGHT, ptr(t1->type),
						root(q), lvalue(idtree(t1)));
				}
			if (q->type->size == 0)
				q->type = inttype;
			if (hascall(q))
				r = r ? tree(RIGHT, voidtype, r, q) : q;
			args = tree(mkop(ARG, q->type), q->type, q, args);
			n++;
			if (Aflag >= 2 && n == 32)
				warning("more than 31 arguments in a call to %s\n",
					funcname(f));
			if (t != ',')
				break;
			t = gettok();
		}
	expect(')');
	if (proto && *proto && *proto != voidtype)
		error("insufficient number of arguments to %s\n",
			funcname(f));
	if (r)
		args = tree(RIGHT, voidtype, r, args);
	e = calltree(f, rty, args, t3);
	if (events.calls)
		apply(events.calls, &src, &e);
	return e;
}
Esempio n. 21
0
/* tracevalue - append format and argument to print the value of e */
static void tracevalue(Tree e, int lev) {
	Type ty = unqual(e->type);

	switch (ty->op) {
	case INT:
		if (ty == chartype || ty == signedchar)
			appendstr("'\\x%02x'");
		else if (ty == longtype)
			appendstr("0x%ld");
		else
			appendstr("0x%d");
		break;
	case UNSIGNED:
		if (ty == chartype || ty == unsignedchar)
			appendstr("'\\x%02x'");
		else if (ty == unsignedlong)
			appendstr("0x%lx");
		else
			appendstr("0x%x");
		break;
	case FLOAT:
		if (ty == longdouble)
			appendstr("%Lg");
		else
			appendstr("%g");
		break;
	case POINTER:
		if (unqual(ty->type) == chartype
		||  unqual(ty->type) == signedchar
		||  unqual(ty->type) == unsignedchar) {
			static Symbol null;
			if (null == NULL)
				null = mkstr("(null)");
			tracevalue(cast(e, unsignedtype), lev + 1);
			appendstr(" \"%.30s\"");
			e = condtree(e, e, pointer(idtree(null->u.c.loc)));
		} else {
			appendstr("("); appendstr(typestring(ty, "")); appendstr(")0x%x");
		}
		break;
	case STRUCT: {
		Field q;
		appendstr("("); appendstr(typestring(ty, "")); appendstr("){");
		for (q = ty->u.sym->u.s.flist; q; q = q->link) {
			appendstr(q->name); appendstr("=");
			tracevalue(field(addrof(e), q->name), lev + 1);
			if (q->link)
				appendstr(",");
		}
		appendstr("}");
		return;
		}
	case UNION:
		appendstr("("); appendstr(typestring(ty, "")); appendstr("){...}");
		return;
	case ARRAY:
		if (lev && ty->type->size > 0) {
			int i;
			e = pointer(e);
			appendstr("{");
			for (i = 0; i < ty->size/ty->type->size; i++) {
				Tree p = (*optree['+'])(ADD, e, consttree(i, inttype));
				if (isptr(p->type) && isarray(p->type->type))
					p = retype(p, p->type->type);
				else
					p = rvalue(p);
				if (i)
					appendstr(",");
				tracevalue(p, lev + 1);
			}
			appendstr("}");
		} else
			appendstr(typestring(ty, ""));
		return;
	default:
		assert(0);
	}
	e = cast(e, promote(ty));
	args = tree(mkop(ARG,e->type), e->type, e, args);
}