static int g_stack_clear_start; // in dwords
static int g_stack_clear_len;
static int g_regmask_init;
+static int g_regmask_rm;
static int g_skip_func;
static int g_allow_regfunc;
static int g_allow_user_icall;
}
// declare normal registers
- regmask_now = regmask & ~regmask_arg;
+ regmask_now = regmask & ~regmask_arg & ~g_regmask_rm;
regmask_now &= ~(1 << xSP);
if (regmask_now & 0x00ff) {
for (reg = 0; reg < 8; reg++) {
}
// pass4:
- // - remove dead labels
// - handle push <const>/pop pairs
for (i = 0; i < opcnt; i++)
{
- if (g_labels[i] != NULL && g_label_refs[i].i == -1) {
- free(g_labels[i]);
- g_labels[i] = NULL;
- }
-
po = &ops[i];
if (po->flags & (OPF_RMD|OPF_DONE))
continue;
argc_normal++;
regmask_dep = 0;
}
- else if (regmask_dep && (fp->is_stdcall || fp->argc_stack == 0)
- && (regmask_dep & ~(mxCX | mxDX)) == 0)
+ else if ((regmask_dep == (mxCX | mxDX)
+ && (fp->is_stdcall || fp->argc_stack == 0))
+ || (regmask_dep == mxCX && fp->argc_stack == 0))
{
fprintf(fout, " __fastcall ");
if (!(regmask_dep & (1 << xDX)) && fp->argc_stack == 0)
static const char *attrs[] = {
"clear_sf",
"clear_regmask",
+ "rm_regmask",
};
// parse manual attribute-list comment
else if (i == 1)
// clear_regmask=<mask>
ret = sscanf(p, "=%x%n", &g_regmask_init, &j) + 1;
+ else if (i == 2)
+ // rm_regmask=<mask>
+ ret = sscanf(p, "=%x%n", &g_regmask_rm, &j) + 1;
if (ret < 2) {
anote("unparsed attr value: %s\n", p);
break;
g_stack_clear_start = 0;
g_stack_clear_len = 0;
g_regmask_init = 0;
+ g_regmask_rm = 0;
skip_warned = 0;
g_skip_func = 0;
g_func[0] = 0;