X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Ftranslate.c;h=ce55bf98d0952b20dd3cf5462f64c874bff55bbd;hb=c8dbc5be471a345886b5463714e9a83d1bdf5812;hp=cb036c14207179cf48cf34a1e28453e2e08b227a;hpb=60fe410ce8c940b42a341f8dfebd365b76a77c14;p=ia32rtools.git diff --git a/tools/translate.c b/tools/translate.c index cb036c1..ce55bf9 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -474,6 +474,8 @@ static int guess_lmod_from_c_type(enum opr_lenmod *lmod, "uint8_t", "int8_t", "char", "unsigned __int8", "__int8", "BYTE", "_BYTE", "CHAR", "_UNKNOWN", + // structures.. deal the same as with _UNKNOWN for now + "CRITICAL_SECTION", }; const char *n; int i; @@ -625,8 +627,10 @@ static int parse_operand(struct parsed_opr *opr, if (wordc_in == 2) { if (IS(words[w], "offset")) { opr->type = OPT_OFFSET; + opr->lmod = OPLM_DWORD; strcpy(opr->name, words[w + 1]); - return wordc; + pp = proto_parse(g_fhdr, opr->name, 1); + goto do_label; } if (IS(words[w], "(offset")) { p = strchr(words[w + 1], ')'); @@ -3391,8 +3395,12 @@ tailcall: pfomask = 1 << po->pfo; } - if (tmp_op->op == OP_ADD && po->pfo == PFO_C) - need_tmp64 = 1; + if (tmp_op->op == OP_ADD && po->pfo == PFO_C) { + propagate_lmod(tmp_op, &tmp_op->operand[0], + &tmp_op->operand[1]); + if (tmp_op->operand[0].lmod == OPLM_DWORD) + need_tmp64 = 1; + } } if (pfomask) { tmp_op->pfomask |= pfomask; @@ -3413,7 +3421,8 @@ tailcall: else if (po->op == OP_MUL || (po->op == OP_IMUL && po->operand_cnt == 1)) { - need_tmp64 = 1; + if (po->operand[0].lmod == OPLM_DWORD) + need_tmp64 = 1; } else if (po->op == OP_CALL) { pp = po->pp; @@ -3476,6 +3485,25 @@ tailcall: } } } + else if (po->op == OP_MOV && po->operand[0].pp != NULL + && po->operand[1].pp != NULL) + { + // = offset + if ((po->operand[1].pp->is_func || po->operand[1].pp->is_fptr) + && !IS_START(po->operand[1].name, "off_")) + { + if (!po->operand[0].pp->is_fptr) + ferr(po, "%s not declared as fptr when it should be\n", + po->operand[0].name); + if (pp_cmp_func(po->operand[0].pp, po->operand[1].pp)) { + pp_print(buf1, sizeof(buf1), po->operand[0].pp); + pp_print(buf2, sizeof(buf2), po->operand[1].pp); + fnote(po, "var: %s\n", buf1); + fnote(po, "func: %s\n", buf2); + ferr(po, "^ mismatch\n"); + } + } + } else if (po->op == OP_RET && !IS(g_func_pp->ret_type.name, "void")) regmask |= 1 << xAX; else if (po->op == OP_DIV || po->op == OP_IDIV) { @@ -4180,13 +4208,22 @@ tailcall: assert_operand_cnt(2); propagate_lmod(po, &po->operand[0], &po->operand[1]); if (pfomask & (1 << PFO_C)) { - fprintf(fout, " tmp64 = (u64)%s + %s;\n", - out_src_opr_u32(buf1, sizeof(buf1), po, &po->operand[0]), - out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[1])); - fprintf(fout, " cond_c = tmp64 >> 32;\n"); - fprintf(fout, " %s = (u32)tmp64;", - out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0])); - strcat(g_comment, "add64"); + out_src_opr_u32(buf1, sizeof(buf1), po, &po->operand[0]); + out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[1]); + if (po->operand[0].lmod == OPLM_DWORD) { + fprintf(fout, " tmp64 = (u64)%s + %s;\n", buf1, buf2); + fprintf(fout, " cond_c = tmp64 >> 32;\n"); + fprintf(fout, " %s = (u32)tmp64;", + out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0])); + strcat(g_comment, "add64"); + } + else { + fprintf(fout, " cond_c = ((u32)%s + %s) >> %d;\n", + buf1, buf2, lmod_bytes(po, po->operand[0].lmod) * 8); + fprintf(fout, " %s += %s;", + out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]), + buf2); + } pfomask &= ~(1 << PFO_C); output_std_flags(fout, po, &pfomask, buf1); last_arith_dst = &po->operand[0]; @@ -4279,11 +4316,24 @@ tailcall: // fallthrough case OP_MUL: assert_operand_cnt(1); - strcpy(buf1, po->op == OP_IMUL ? "(s64)(s32)" : "(u64)"); - fprintf(fout, " tmp64 = %seax * %s%s;\n", buf1, buf1, - out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[0])); - fprintf(fout, " edx = tmp64 >> 32;\n"); - fprintf(fout, " eax = tmp64;"); + switch (po->operand[0].lmod) { + case OPLM_DWORD: + strcpy(buf1, po->op == OP_IMUL ? "(s64)(s32)" : "(u64)"); + fprintf(fout, " tmp64 = %seax * %s%s;\n", buf1, buf1, + out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[0])); + fprintf(fout, " edx = tmp64 >> 32;\n"); + fprintf(fout, " eax = tmp64;"); + break; + case OPLM_BYTE: + strcpy(buf1, po->op == OP_IMUL ? "(s16)(s8)" : "(u16)(u8)"); + fprintf(fout, " LOWORD(eax) = %seax * %s;", buf1, + out_src_opr(buf2, sizeof(buf2), po, &po->operand[0], + buf1, 0)); + break; + default: + ferr(po, "TODO: unhandled mul type\n"); + break; + } last_arith_dst = NULL; delayed_flag_op = NULL; break;