X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Ftranslate.c;h=e2b6d209044287f698adcfb08617a4f913db351e;hb=c0050df6e9d6eb81afacb0fa2d1910293dd2165e;hp=9643c63f2c6d34445290fedbf6047167b68e4625;hpb=ddaf8bd7aa44ee867e43988ba0bb7658dae6e6eb;p=ia32rtools.git diff --git a/tools/translate.c b/tools/translate.c index 9643c63..e2b6d20 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -1451,7 +1451,7 @@ static void check_func_pp(struct parsed_op *po, 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", @@ -2689,6 +2689,17 @@ static void output_std_flags(FILE *fout, struct parsed_op *po, } } +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; @@ -2727,10 +2738,7 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) 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++) { @@ -2740,8 +2748,7 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) // 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) @@ -3213,9 +3220,10 @@ tailcall: && (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; } @@ -3228,6 +3236,10 @@ tailcall: } } 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++) { @@ -3265,8 +3277,7 @@ tailcall: 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)