X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Ftranslate.c;h=67211e9c6335f88852f97a0549720384eed4aa6e;hb=c7ed83dd918585832e3c9001dabdb7375518d635;hp=e3d8f5bb6e23c65d0676de38a1b5fcc24e5cb88c;hpb=092f64e1941e7eb188ce00d301e5734d53e3974c;p=ia32rtools.git diff --git a/tools/translate.c b/tools/translate.c index e3d8f5b..67211e9 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -128,9 +128,10 @@ struct parsed_opr { unsigned int size_mismatch:1; // type override differs from C unsigned int size_lt:1; // type override is larger than C unsigned int had_ds:1; // had ds: prefix + const struct parsed_proto *pp; // for OPT_LABEL int reg; unsigned int val; - char name[256]; + char name[112]; }; struct parsed_op { @@ -148,7 +149,7 @@ struct parsed_op { int cc_scratch; // scratch storage during analysis int bt_i; // branch target for branches struct parsed_data *btj;// branch targets for jumptables - struct parsed_proto *pp; + struct parsed_proto *pp;// parsed_proto for OP_CALL void *datap; }; @@ -507,6 +508,24 @@ static int guess_lmod_from_c_type(enum opr_lenmod *lmod, return 0; } +static char *default_cast_to(char *buf, size_t buf_size, + struct parsed_opr *opr) +{ + buf[0] = 0; + + if (!opr->is_ptr) + return buf; + if (opr->pp == NULL || opr->pp->type.name == NULL + || opr->pp->is_fptr) + { + snprintf(buf, buf_size, "%s", "(void *)"); + return buf; + } + + snprintf(buf, buf_size, "(%s)", opr->pp->type.name); + return buf; +} + static enum opr_type lmod_from_directive(const char *d) { if (IS(d, "dd")) @@ -699,6 +718,7 @@ do_label: } opr->is_array = pp->type.is_array; } + opr->pp = pp; if (opr->lmod == OPLM_UNSPEC) guess_lmod_from_name(opr); @@ -3807,9 +3827,10 @@ tailcall: assert_operand_cnt(2); propagate_lmod(po, &po->operand[0], &po->operand[1]); out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]); + default_cast_to(buf3, sizeof(buf3), &po->operand[0]); fprintf(fout, " %s = %s;", buf1, out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], - po->operand[0].is_ptr ? "(void *)" : "", 0)); + buf3, 0)); break; case OP_LEA: @@ -3853,9 +3874,11 @@ tailcall: out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], "", 0)); fprintf(fout, " %s = %s;", out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]), - out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], "", 0)); - fprintf(fout, " %s = tmp;", - out_dst_opr(buf1, sizeof(buf1), po, &po->operand[1])); + out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], + default_cast_to(buf3, sizeof(buf3), &po->operand[0]), 0)); + fprintf(fout, " %s = %stmp;", + out_dst_opr(buf1, sizeof(buf1), po, &po->operand[1]), + default_cast_to(buf3, sizeof(buf3), &po->operand[1])); snprintf(g_comment, sizeof(g_comment), "xchg"); break; @@ -4544,7 +4567,7 @@ tailcall: fprintf(fout, " %s = %s;", buf1, out_src_opr(buf2, sizeof(buf2), tmp_op, &tmp_op->operand[0], - po->operand[0].is_ptr ? "(void *)" : "", 0)); + default_cast_to(buf3, sizeof(buf3), &po->operand[0]), 0)); break; } else if (g_func_pp->is_userstack) { @@ -4745,6 +4768,9 @@ static void scan_ahead(FILE *fasm) add_func_chunk(fasm, words[0], asmln); } + else if (IS_START(p, "; sctend")) + break; + continue; } // *p == ';' @@ -4790,6 +4816,7 @@ int main(int argc, char *argv[]) int eq_alloc; int verbose = 0; int multi_seg = 0; + int end = 0; int arg_out; int arg; int pi = 0; @@ -5020,6 +5047,11 @@ parse_words: if (IS_START(p, "; sctproto:")) { sctproto = strdup(p + 11); } + else if (IS_START(p, "; sctend")) { + end = 1; + if (!pending_endp) + break; + } } if (wordc == 0) { @@ -5040,7 +5072,7 @@ parse_words: do_pending_endp: // do delayed endp processing to collect switch jumptables if (pending_endp) { - if (in_func && !skip_func && wordc >= 2 + if (in_func && !skip_func && !end && wordc >= 2 && ((words[0][0] == 'd' && words[0][2] == 0) || (words[1][0] == 'd' && words[1][2] == 0))) { @@ -5123,6 +5155,9 @@ do_pending_endp: } g_func_pd_cnt = 0; pd = NULL; + + if (end) + break; if (wordc == 0) continue; } @@ -5187,8 +5222,12 @@ do_pending_endp: } if (wordc == 2 && IS(words[1], "ends")) { - if (!multi_seg) + if (!multi_seg) { + end = 1; + if (pending_endp) + goto do_pending_endp; break; + } // scan for next text segment while (fgets(line, sizeof(line), fasm)) {