static void emit_func_call(Node *node) { SAVE; int opos = stackpos; bool isptr = (node->type == AST_FUNCPTR_CALL); Ctype *ftype = isptr ? node->fptr->ctype->ptr : node->ftype; List *ints = make_list(); List *floats = make_list(); List *rest = make_list(); classify_args(ints, floats, rest, node->args); save_arg_regs(list_len(ints), list_len(floats)); bool padding = stackpos % 16; if (padding) { emit("sub $8, %%rsp"); stackpos += 8; } emit_args(list_reverse(rest)); if (isptr) { emit_expr(node->fptr); push("rax"); } emit_args(ints); emit_args(floats); pop_float_args(list_len(floats)); pop_int_args(list_len(ints)); if (isptr) pop("r11"); if (ftype->hasva) emit("mov $%d, %%eax", list_len(floats)); if (isptr) emit("call *%%r11"); else emit("call %s", node->fname); maybe_booleanize_retval(node->ctype); if (list_len(rest) > 0) { emit("add $%d, %%rsp", list_len(rest) * 8); stackpos -= list_len(rest) * 8; } if (padding) { emit("add $8, %%rsp"); stackpos -= 8; } restore_arg_regs(list_len(ints), list_len(floats)); assert(opos == stackpos); }
static void emit_func_call(Node *node) { SAVE; int opos = stackpos; bool isptr = (node->kind == AST_FUNCPTR_CALL); Type *ftype = isptr ? node->fptr->ty->ptr : node->ftype; Vector *ints = make_vector(); Vector *floats = make_vector(); Vector *rest = make_vector(); classify_args(ints, floats, rest, node->args); save_arg_regs(vec_len(ints), vec_len(floats)); bool padding = stackpos % 16; if (padding) { emit("sub $8, #rsp"); stackpos += 8; } int restsize = emit_args(vec_reverse(rest)); if (isptr) { emit_expr(node->fptr); push("rax"); } emit_args(ints); emit_args(floats); pop_float_args(vec_len(floats)); pop_int_args(vec_len(ints)); if (isptr) pop("r11"); if (ftype->hasva) emit("mov $%u, #eax", vec_len(floats)); if (isptr) emit("call *#r11"); else emit("call %s", node->fname); maybe_booleanize_retval(node->ty); if (restsize > 0) { emit("add $%d, #rsp", restsize); stackpos -= restsize; } if (padding) { emit("add $8, #rsp"); stackpos -= 8; } restore_arg_regs(vec_len(ints), vec_len(floats)); assert(opos == stackpos); }