/* * Called with a function call with arguments as argument. * This is done early in buildtree() and only done once. */ NODE * funcode(NODE *p) { NODE *r, *l; /* Fix function call arguments. On vax, just add funarg */ for (r = p->n_right; r->n_op == CM; r = r->n_left) { if (r->n_right->n_op != STARG) { r->n_right = intprom(r->n_right); r->n_right = block(FUNARG, r->n_right, NIL, r->n_right->n_type, r->n_right->n_df, r->n_right->n_ap); } } if (r->n_op != STARG) { l = talloc(); *l = *r; r->n_op = FUNARG; r->n_left = l; r->n_left = intprom(r->n_left); r->n_type = r->n_left->n_type; } return p; }
/* * Called with a function call with arguments as argument. * This is done early in buildtree() and only done once. * Returns p. */ NODE * funcode(NODE *p) { extern int gotnr; #ifdef GCC_COMPAT struct attr *ap; #endif NODE *r, *l; TWORD t = DECREF(DECREF(p->n_left->n_type)); int stcall; stcall = ISSOU(t); /* * We may have to prepend: * - Hidden arg0 for struct return (in reg or on stack). * - ebx in case of PIC code. */ /* Fix function call arguments. On x86, just add funarg */ for (r = p->n_right; r->n_op == CM; r = r->n_left) { if (r->n_right->n_op != STARG) { r->n_right = intprom(r->n_right); r->n_right = block(FUNARG, r->n_right, NIL, r->n_right->n_type, r->n_right->n_df, r->n_right->n_ap); } } if (r->n_op != STARG) { l = talloc(); *l = *r; r->n_op = FUNARG; r->n_left = l; r->n_left = intprom(r->n_left); r->n_type = r->n_left->n_type; } if (stcall) { /* Prepend a placeholder for struct address. */ /* Use BP, can never show up under normal circumstances */ l = talloc(); *l = *r; r->n_op = CM; r->n_right = l; r->n_type = INT; l = block(REG, 0, 0, INCREF(VOID), 0, 0); regno(l) = BP; l = block(FUNARG, l, 0, INCREF(VOID), 0, 0); r->n_left = l; } #ifdef GCC_COMPAT if ((ap = attr_find(p->n_left->n_ap, GCC_ATYP_REGPARM))) rparg = ap->iarg(0); else #endif rparg = 0; regcvt = 0; if (rparg) listf(p->n_right, addreg); return p; }