/* * 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 }
/* * 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 }