X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Ftranslate.c;h=f85d5befbba1b86931b8d1fcce121fd9c7803b3c;hb=206c0727041648e9545d16b25e591880f2c58f79;hp=e7fd5c73e6de091d9faf19be848e2c990aa1a64c;hpb=8c83cc48a2090b018cb39a629454b5e9608ba4d8;p=ia32rtools.git diff --git a/tools/translate.c b/tools/translate.c index e7fd5c7..f85d5be 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -157,6 +157,7 @@ enum op_op { OPP_ALLSHR, OPP_FTOL, OPP_CIPOW, + OPP_ABORT, // undefined OP_UD2, }; @@ -620,6 +621,9 @@ static int guess_lmod_from_name(struct parsed_opr *opr) 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", @@ -668,6 +672,13 @@ static int guess_lmod_from_c_type(enum opr_lenmod *lmod, } } + for (i = 0; i < ARRAY_SIZE(qword_types); i++) { + if (IS(n, qword_types[i])) { + *lmod = OPLM_QWORD; + return 1; + } + } + return 0; } @@ -1724,14 +1735,12 @@ static struct parsed_equ *equ_find(struct parsed_op *po, const char *name, *extra_offs = 0; namelen = strlen(name); - p = strchr(name, '+'); + p = strpbrk(name, "+-"); if (p != NULL) { namelen = p - name; if (namelen <= 0) ferr(po, "equ parse failed for '%s'\n", name); - if (IS_START(p, "0x")) - p += 2; *extra_offs = strtol(p, &endp, 16); if (*endp != 0) ferr(po, "equ parse failed for '%s'\n", name); @@ -1856,7 +1865,6 @@ static int stack_frame_access(struct parsed_op *po, int offset = 0; int retval = -1; int sf_ofs; - int lim; if (po->flags & OPF_EBP_S) ferr(po, "stack_frame_access while ebp is scratch\n"); @@ -1987,8 +1995,7 @@ static int stack_frame_access(struct parsed_op *po, g_stack_frame_used = 1; sf_ofs = g_stack_fsz + offset; - lim = (ofs_reg[0] != 0) ? -4 : 0; - if (offset > 0 || sf_ofs < lim) + if (ofs_reg[0] == 0 && (offset > 0 || sf_ofs < 0)) ferr(po, "bp_stack offset %d/%d\n", offset, g_stack_fsz); if (is_lea) @@ -2310,7 +2317,7 @@ static char *out_src_opr_float(char *buf, size_t buf_size, 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: @@ -5586,6 +5593,8 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) 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 @@ -5793,10 +5802,13 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) // 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"; @@ -7446,9 +7458,13 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) 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: @@ -8566,7 +8582,8 @@ int main(int argc, char *argv[]) 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; @@ -8632,6 +8649,8 @@ int main(int argc, char *argv[]) memset(words, 0, sizeof(words)); for (; arg < argc; arg++) { + int skip_func = 0; + frlist = fopen(argv[arg], "r"); my_assert_not(frlist, NULL); @@ -8663,7 +8682,6 @@ int main(int argc, char *argv[]) } rlist[rlist_len++] = strdup(words[0]); } - skip_func = 0; fclose(frlist); frlist = NULL; @@ -8846,7 +8864,12 @@ parse_words: 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); @@ -8862,6 +8885,20 @@ parse_words: 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) { @@ -9001,6 +9038,8 @@ do_pending_endp: 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) @@ -9068,7 +9107,7 @@ do_pending_endp: 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]);