From: notaz Date: Fri, 7 Feb 2014 01:17:48 +0000 (+0200) Subject: translate: pop stack align improvement, xchg X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=108e9fe39266c84343aa6f49c4fa7c73579461b9;p=ia32rtools.git translate: pop stack align improvement, xchg --- diff --git a/tools/translate.c b/tools/translate.c index 1fd5e47..e45ee00 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -55,6 +55,7 @@ enum op_op { OP_LEA, OP_MOVZX, OP_MOVSX, + OP_XCHG, OP_NOT, OP_CDQ, OP_STOS, @@ -726,6 +727,7 @@ static const struct { { "lea", OP_LEA, 2, 2, OPF_DATA }, { "movzx",OP_MOVZX, 2, 2, OPF_DATA }, { "movsx",OP_MOVSX, 2, 2, OPF_DATA }, + { "xchg", OP_XCHG, 2, 2, OPF_DATA }, { "not", OP_NOT, 1, 1, OPF_DATA }, { "cdq", OP_CDQ, 0, 0, OPF_DATA }, { "stosb",OP_STOS, 0, 0, OPF_DATA }, @@ -933,6 +935,11 @@ static void parse_op(struct parsed_op *op, char words[16][256], int wordc) op->regmask_dst = op->regmask_src; break; + case OP_XCHG: + op->regmask_src |= op->regmask_dst; + op->regmask_dst |= op->regmask_src; + break; + case OP_JECXZ: op->operand_cnt = 1; op->regmask_src = 1 << xCX; @@ -2319,12 +2326,15 @@ static int scan_for_esp_adjust(int i, int opcnt, int *adj) ferr(&ops[i], "unaligned esp adjust: %x\n", *adj); return i; } - else if (po->op == OP_PUSH) { + else if (po->op == OP_PUSH && !(po->flags & OPF_RMD)) { //if (first_pop == -1) // first_pop = -2; // none *adj -= lmod_bytes(po, po->operand[0].lmod); } else if (po->op == OP_POP && !(po->flags & OPF_RMD)) { + // seems like msvc only uses 'pop ecx' for stack realignment.. + if (po->operand[0].type != OPT_REG || po->operand[0].reg != xCX) + break; if (first_pop == -1 && *adj >= 0) first_pop = i; *adj += lmod_bytes(po, po->operand[0].lmod); @@ -2340,10 +2350,7 @@ static int scan_for_esp_adjust(int i, int opcnt, int *adj) } } - if (*adj <= 8 && first_pop >= 0 && ops[first_pop].op == OP_POP - && ops[first_pop].operand[0].type == OPT_REG - && ops[first_pop].operand[0].reg == xCX) - { + if (first_pop >= 0) { // probably 'pop ecx' was used.. return first_pop; } @@ -2788,6 +2795,7 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) enum parsed_flag_op pfo; int save_arg_vars = 0; int cmp_result_vars = 0; + int need_tmp_var = 0; int need_mul_var = 0; int had_decl = 0; int label_pending = 0; @@ -3330,6 +3338,9 @@ tailcall: { need_mul_var = 1; } + else if (po->op == OP_XCHG) { + need_tmp_var = 1; + } else if (po->op == OP_CALL) { pp = po->datap; if (pp == NULL) @@ -3534,6 +3545,11 @@ tailcall: } } + if (need_tmp_var) { + fprintf(fout, " u32 tmp;\n"); + had_decl = 1; + } + if (need_mul_var) { fprintf(fout, " u64 mul_tmp;\n"); had_decl = 1; @@ -3672,6 +3688,19 @@ tailcall: buf3, 0)); break; + case OP_XCHG: + assert_operand_cnt(2); + propagate_lmod(po, &po->operand[0], &po->operand[1]); + fprintf(fout, " tmp = %s;", + 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])); + snprintf(g_comment, sizeof(g_comment), "xchg"); + break; + case OP_NOT: assert_operand_cnt(1); out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]);