const struct parsed_proto *pp, const char *pfx)
{
if (pp->argc_reg != 0) {
- if (!g_allow_regfunc)
+ if (!g_allow_regfunc && !pp->is_fastcall)
ferr(po, "%s: reg arg in arg-call unhandled yet\n", pfx);
if (pp->argc_stack > 0 && pp->argc_reg != 2)
ferr(po, "%s: %d reg arg(s) with %d stack arg(s)\n",
}
}
+static void output_pp_attrs(FILE *fout, const struct parsed_proto *pp,
+ int is_noreturn)
+{
+ if (pp->is_fastcall)
+ fprintf(fout, "__fastcall ");
+ else if (pp->is_stdcall && pp->argc_reg == 0)
+ fprintf(fout, "__stdcall ");
+ if (pp->is_noreturn || is_noreturn)
+ fprintf(fout, "noreturn ");
+}
+
static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt)
{
struct parsed_op *po, *delayed_flag_op = NULL, *tmp_op;
ferr(ops, "proto_parse failed for '%s'\n", funcn);
fprintf(fout, "%s ", g_func_pp->ret_type.name);
- if (g_func_pp->is_stdcall && g_func_pp->argc_reg == 0)
- fprintf(fout, "__stdcall ");
- if (g_ida_func_attr & IDAFA_NORETURN)
- fprintf(fout, "noreturn ");
+ output_pp_attrs(fout, g_func_pp, g_ida_func_attr & IDAFA_NORETURN);
fprintf(fout, "%s(", funcn);
for (i = 0; i < g_func_pp->argc; i++) {
// func pointer..
pp = g_func_pp->arg[i].fptr;
fprintf(fout, "%s (", pp->ret_type.name);
- if (pp->is_stdcall && pp->argc_reg == 0)
- fprintf(fout, "__stdcall ");
+ output_pp_attrs(fout, pp, 0);
fprintf(fout, "*a%d)(", i + 1);
for (j = 0; j < pp->argc; j++) {
if (j > 0)
&& (regmask_stack & (1 << xDX))))
{
if (pp->argc_stack != 0
- || ((regmask | regmask_arg) & (1 << xCX)))
+ || ((regmask | regmask_arg) & ((1 << xCX)|(1 << xDX))))
{
pp_insert_reg_arg(pp, "ecx");
+ pp->is_fastcall = 1;
regmask_init |= 1 << xCX;
regmask |= 1 << xCX;
}
}
}
regmask |= regmask_stack;
+
+ // note: __cdecl doesn't fall into is_unresolved category
+ if (pp->argc_stack > 0)
+ pp->is_stdcall = 1;
}
for (arg = 0; arg < pp->argc; arg++) {
snprintf(pp->name, sizeof(pp->name), "icall%d", i);
fprintf(fout, " %s (", pp->ret_type.name);
- if (pp->is_stdcall && pp->argc_reg == 0)
- fprintf(fout, "__stdcall ");
+ output_pp_attrs(fout, pp, 0);
fprintf(fout, "*%s)(", pp->name);
for (j = 0; j < pp->argc; j++) {
if (j > 0)