Esempio n. 1
0
/*
 * Push a structure on stack as argument.
 * the scratch registers are already free here
 */
static void
starg(NODE *p)
{
#if defined(MACHOABI)
	printf("	subl $%d,%%esp\n", p->n_stsize);
	printf("	subl $4,%%esp\n");
	printf("	pushl $%d\n", p->n_stsize);
	expand(p, 0, "	pushl AL\n");
	expand(p, 0, "	leal 12(%esp),A1\n");
	expand(p, 0, "	pushl A1\n");
	if (kflag) {
		printf("	call L%s$stub\n", EXPREFIX "memcpy");
		addstub(&stublist, EXPREFIX "memcpy");
	} else {
		printf("	call %s\n", EXPREFIX "memcpy");
	}
	printf("	addl $16,%%esp\n");
#else
	NODE *q = p->n_left;

	printf("	subl $%d,%%esp\n", (p->n_stsize + 3) & ~3);
	p->n_left = mklnode(OREG, 0, ESP, INT);
	zzzcode(p, 'Q');
	tfree(p->n_left);
	p->n_left = q;
#endif
}
Esempio n. 2
0
/*
 * Create a reference for an extern variable.
 */
static P1ND *
picext(P1ND *p)
{
	struct attr *ap;

#if defined(ELFABI)
	P1ND *q, *r;
	struct symtab *sp;
	char *name;

	q = tempnode(gotnr, PTR|VOID, 0, 0);
	name = getexname(p->n_sp);

#ifdef GCC_COMPAT
	if ((ap = attr_find(p->n_sp->sap, GCC_ATYP_VISIBILITY)) &&
	    strcmp(ap->sarg(0), "hidden") == 0) {
		/* For hidden vars use GOTOFF */
		sp = picsymtab("", name, "@GOTOFF");
		r = xbcon(0, sp, INT);
		q = buildtree(PLUS, q, r);
		q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
		q->n_sp = p->n_sp; /* for init */
		p1nfree(p);
		return q;
	}
#endif

	sp = picsymtab("", name, "@GOT");
#ifdef GCC_COMPAT
	if (attr_find(p->n_sp->sap, GCC_ATYP_STDCALL) != NULL)
		p->n_sp->sflags |= SSTDCALL;
#endif
	sp->sflags = p->n_sp->sflags & SSTDCALL;
	sp->sap = attr_add(p->n_sp->sap, sp->sap);
	r = xbcon(0, sp, INT);
	q = buildtree(PLUS, q, r);
	q = block(UMUL, q, 0, PTR|VOID, 0, 0);
	q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
	q->n_sp = p->n_sp; /* for init */
	p1nfree(p);
	return q;

#elif defined(MACHOABI)

	P1ND *q, *r;
	struct symtab *sp;
	char buf2[256], *name, *pspn;

	name = getsoname(cftnsp);
	pspn = getexname(p->n_sp);

	if (p->n_sp->sclass == EXTDEF) {
		snprintf(buf2, 256, "-L%s$pb", name);
		sp = picsymtab("", pspn, buf2);
	} else {
		snprintf(buf2, 256, "$non_lazy_ptr-L%s$pb", name);
		sp = picsymtab("L", pspn, buf2);
		addstub(&nlplist, pspn);
	}

	sp->stype = p->n_sp->stype;

	q = tempnode(gotnr, PTR+VOID, 0, 0);
	r = xbcon(0, sp, INT);
	q = buildtree(PLUS, q, r);

	if (p->n_sp->sclass != EXTDEF)
		q = block(UMUL, q, 0, PTR+VOID, 0, 0);
	q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
	q->n_sp = p->n_sp; /* for init */
	p1nfree(p);
	return q;

#else /* defined(PECOFFABI) || defined(AOUTABI) */

	return p;

#endif

}