if (cmd.Operands[o].type == o_mem) {
tmp_ea = cmd.Operands[o].addr;
- flags_t tmp_ea_flags = get_flags_novalue(tmp_ea);
- // ..but base float is ok..
- int is_flt = isDwrd(tmp_ea_flags) || isFloat(tmp_ea_flags);
- if (!is_flt && !isUnknown(tmp_ea_flags))
+ flags_t tmp_flg = get_flags_novalue(tmp_ea);
+ buf[0] = 0;
+ if (isDouble(tmp_flg))
{
- buf[0] = 0;
get_name(ea, tmp_ea, buf, sizeof(buf));
- msg("%x: undefining %x '%s'\n", ea, tmp_ea, buf);
+ msg("%x: converting dbl %x '%s'\n", ea, tmp_ea, buf);
+ doQwrd(tmp_ea, 8);
+ }
+ if (isOwrd(tmp_flg) || isYwrd(tmp_flg) || isTbyt(tmp_flg))
+ {
+ get_name(ea, tmp_ea, buf, sizeof(buf));
+ msg("%x: undefining lrg %x '%s'\n", ea, tmp_ea, buf);
do_unknown(tmp_ea, DOUNK_EXPAND);
}
}
}
// IDA vs masm float/mmx/xmm type incompatibility
- if (isDouble(ea_flags) || isTbyt(ea_flags)
- || isPackReal(ea_flags))
+ if (isDouble(ea_flags))
+ {
+ msg("%x: converting double\n", ea);
+ doQwrd(ea, 8);
+ }
+ else if (isTbyt(ea_flags) || isPackReal(ea_flags))
{
do_undef = 1;
}
f_st0 = (double)(s32)sf.d[0]; // var_20 fild
f_st0 /= (double)(s32)a1; // arg_0
- f_st0 *= *((double *)(u32)&sf.q[1]); // var_18
+ f_st0 *= *(double *)((u32)&sf.q[1]); // var_18
f_st1 = f_st0; f_st0 = (double)(s32)sf.d[0]; // var_20 fild
f_st1 /= f_st0;
f_st0 = f_st1 + f_st0;
- f_st1 = f_st0; f_st0 = *((double *)(u32)&sf.q[1]); // var_18 fld
+ f_st1 = f_st0; f_st0 = *(double *)((u32)&sf.q[1]); // var_18 fld
fs_3 = f_st0; f_st0 = f_st1; // fst
fs_1 = f_st0; // fst
f_st0 = pow(fs_1, fs_3);
- f_sw = f_st0 <= *((double *)(u32)&sf.q[1]) ? 0x4100 : 0; // var_18 z_chk_det
+ f_sw = f_st0 <= *(double *)((u32)&sf.q[1]) ? 0x4100 : 0; // var_18 z_chk_det
eax = 0;
LOWORD(eax) = f_sw;
cond_z = ((u8)((u8)(eax >> 8) & 0x41) == 0);
eax = 0;
LOBYTE(eax) = (cond_z);
f_st1 = f_st0; f_st0 = 1.0;
- f_st0 = *((double *)(u32)&sf.q[1]) / f_st0; // var_18
+ f_st0 = *(double *)((u32)&sf.q[1]) / f_st0; // var_18
{ double t = f_st0; f_st0 = f_st1; f_st1 = t; } // fxch
f_st0 = -f_st0;
f_st0 = f_st1;
f_st0 = f_st1 * log2(f_st0); // fyl2x
f_st1 = f_st0; // fld st
sf.d[0] = (s32)f_st0; f_st0 = f_st1; // var_20 fist
- *((double *)(u32)&sf.q[1]) = f_st0; // var_18 fst
+ *(double *)((u32)&sf.q[1]) = f_st0; // var_18 fst
eax = (s32)f_st0; // ftol
return eax;
}
OPP_ALLSHR,
OPP_FTOL,
OPP_CIPOW,
+ OPP_ABORT,
// undefined
OP_UD2,
};
static int guess_lmod_from_c_type(enum opr_lenmod *lmod,
const struct parsed_type *c_type)
{
+ static const char *qword_types[] = {
+ "uint64_t", "int64_t", "__int64",
+ };
static const char *dword_types[] = {
"uint32_t", "int", "_DWORD", "UINT_PTR", "DWORD",
"WPARAM", "LPARAM", "UINT", "__int32",
}
}
+ for (i = 0; i < ARRAY_SIZE(qword_types); i++) {
+ if (IS(n, qword_types[i])) {
+ *lmod = OPLM_QWORD;
+ return 1;
+ }
+ }
+
return 0;
}
break;
}
out_src_opr(tmp, sizeof(tmp), po, popr, "", 1);
- snprintf(buf, buf_size, "*((%s *)%s)", cast, tmp);
+ snprintf(buf, buf_size, "*(%s *)(%s)", cast, tmp);
break;
default:
reg_use_pass(0, opcnt, cbits, regmask_init, ®mask,
0, ®mask_save, ®mask_init, regmask_arg);
+ need_float_stack = !!(regmask & mxST7_2);
+
// pass7:
// - find flag set ops for their users
// - do unresolved calls
// this might need it's own pass...
if (po->op != OP_FST && po->p_argnum > 0)
save_arg_vars[po->p_arggrp] |= 1 << (po->p_argnum - 1);
+
+ // correct for "full stack" mode late enable
+ if ((po->flags & (OPF_PPUSH|OPF_FPOP)) && need_float_stack)
+ po->flags |= OPF_FSHIFT;
}
float_type = need_double ? "double" : "float";
- need_float_stack = !!(regmask & mxST7_2);
float_st0 = need_float_stack ? "f_st[f_stp & 7]" : "f_st0";
float_st1 = need_float_stack ? "f_st[(f_stp + 1) & 7]" : "f_st1";
strcat(g_comment, " CIpow");
break;
+ case OPP_ABORT:
+ fprintf(fout, " do_skip_code_abort();");
+ break;
+
// mmx
case OP_EMMS:
- strcpy(g_comment, " (emms)");
+ fprintf(fout, " do_emms();");
break;
default:
char *sctproto = NULL;
int in_func = 0;
int pending_endp = 0;
- int skip_func = 0;
+ int skip_code = 0;
+ int skip_code_end = 0;
int skip_warned = 0;
int eq_alloc;
int verbose = 0;
memset(words, 0, sizeof(words));
for (; arg < argc; arg++) {
+ int skip_func = 0;
+
frlist = fopen(argv[arg], "r");
my_assert_not(frlist, NULL);
}
rlist[rlist_len++] = strdup(words[0]);
}
- skip_func = 0;
fclose(frlist);
frlist = NULL;
if (*p != 0 && *p != ';')
aerr("too many words\n");
- // alow asm patches in comments
+ if (skip_code_end) {
+ skip_code_end = 0;
+ skip_code = 0;
+ }
+
+ // allow asm patches in comments
if (*p == ';') {
if (IS_START(p, "; sctpatch:")) {
p = sskip(p + 11);
if (!pending_endp)
break;
}
+ else if (IS_START(p, "; sctskip_start")) {
+ if (in_func && !g_skip_func) {
+ if (!skip_code) {
+ ops[pi].op = OPP_ABORT;
+ ops[pi].asmln = asmln;
+ pi++;
+ }
+ skip_code = 1;
+ }
+ }
+ else if (IS_START(p, "; sctskip_end")) {
+ if (skip_code)
+ skip_code_end = 1;
+ }
}
if (wordc == 0) {
if (!IS(g_func, words[0]))
aerr("endp '%s' while in_func '%s'?\n",
words[0], g_func);
+ if (skip_code)
+ aerr("endp '%s' while skipping code\n", words[0]);
if ((g_ida_func_attr & IDAFA_THUNK) && pi == 1
&& ops[0].op == OP_JMP && ops[0].operand[0].had_ds)
continue;
}
- if (!in_func || g_skip_func) {
+ if (!in_func || g_skip_func || skip_code) {
if (!skip_warned && !g_skip_func && g_labels[pi] != NULL) {
if (verbose)
anote("skipping from '%s'\n", g_labels[pi]);