From e3734e2b7bd9870e8263ef6640536a6aa305edfc Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 31 Oct 2020 19:35:03 +0200 Subject: [PATCH] JIT LSL/LSR temporary shift count equals 32 fix. --- jit/compemu_midfunc_x86.cpp | 33 ++++++++++++++++++++++++++++++++- jit/compemu_midfunc_x86.h | 3 ++- jit/gencomp.cpp | 31 +++++++++++++++++++++++-------- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/jit/compemu_midfunc_x86.cpp b/jit/compemu_midfunc_x86.cpp index afb99034..b4295522 100644 --- a/jit/compemu_midfunc_x86.cpp +++ b/jit/compemu_midfunc_x86.cpp @@ -116,7 +116,25 @@ MIDFUNC(0,duplicate_carry,(void)) log_vwrite(FLAGX); } -MIDFUNC(3,setcc_for_cntzero,(RR4 /* cnt */, RR4 data, int size)) +MIDFUNC(0,clear_overflow,(void)) +{ + make_flags_live_internal(); + raw_pushfl(); + + // clear OF flag + // and dword [esp],~0x0800 + emit_byte(0x81); + emit_byte(0x24); + emit_byte(0x24); + emit_byte(0xff); + emit_byte(0xf7); + emit_byte(0xff); + emit_byte(0xff); + + raw_popfl(); +} + +MIDFUNC(3,setcc_for_cntzero,(RR4 /* cnt */, RR4 data, int size, int ov)) { uae_u8 *branchadd; uae_u8 *branchadd2; @@ -125,6 +143,19 @@ MIDFUNC(3,setcc_for_cntzero,(RR4 /* cnt */, RR4 data, int size)) make_flags_live_internal(); raw_pushfl(); + + if (ov) { + // clear OF flag + // and dword [esp],~0x0800 + emit_byte(0x81); + emit_byte(0x24); + emit_byte(0x24); + emit_byte(0xff); + emit_byte(0xf7); + emit_byte(0xff); + emit_byte(0xff); + } + /* * shift count can only be in CL register; see shrl_b_rr */ diff --git a/jit/compemu_midfunc_x86.h b/jit/compemu_midfunc_x86.h index 82b75415..a5b6df56 100644 --- a/jit/compemu_midfunc_x86.h +++ b/jit/compemu_midfunc_x86.h @@ -186,7 +186,8 @@ DECLARE_MIDFUNC(xor_b(RW1 d, RR1 s)); DECLARE_MIDFUNC(live_flags(void)); DECLARE_MIDFUNC(dont_care_flags(void)); DECLARE_MIDFUNC(duplicate_carry(void)); -DECLARE_MIDFUNC(setcc_for_cntzero(RR4 d, RR4 data, int size)); +DECLARE_MIDFUNC(setcc_for_cntzero(RR4 d, RR4 data, int size, int ov)); +DECLARE_MIDFUNC(clear_overflow(void)); DECLARE_MIDFUNC(restore_carry(void)); DECLARE_MIDFUNC(start_needflags(void)); DECLARE_MIDFUNC(end_needflags(void)); diff --git a/jit/gencomp.cpp b/jit/gencomp.cpp index dd7518fb..7dfde616 100644 --- a/jit/gencomp.cpp +++ b/jit/gencomp.cpp @@ -2372,7 +2372,7 @@ gen_opcode(unsigned int opcode) comprintf("\tlive_flags();\n"); comprintf("\tend_needflags();\n"); if (curi->smode != immi) - comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d, 0);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); else comprintf("\tduplicate_carry();\n"); comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); @@ -2453,7 +2453,7 @@ gen_opcode(unsigned int opcode) comprintf("\tlive_flags();\n"); comprintf("\tend_needflags();\n"); if (curi->smode != immi) - comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d, 0);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); else comprintf("\tduplicate_carry();\n"); comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); @@ -2485,11 +2485,17 @@ gen_opcode(unsigned int opcode) if (curi->smode != immi) { uses_cmov; start_brace(); + comprintf("\tint cdata2 = scratchie++;\n"); comprintf("\tint cdata = scratchie++;\n"); comprintf("\tint tmpcnt=scratchie++;\n"); comprintf("\tmov_l_rr(tmpcnt,cnt);\n"); comprintf("\tand_l_ri(tmpcnt,63);\n"); comprintf("\tmov_l_ri(cdata, 0);\n"); + + comprintf("\tmov_l_ri(cdata2, 32);\n"); + comprintf("\tcmp_l(tmpcnt, cdata2);\n"); + comprintf("\tcmov_l_rr(tmpcnt, cdata, NATIVE_CC_EQ);\n"); + switch (curi->size) { case sz_byte: comprintf("\ttest_l_ri(tmpcnt, 0x38);\n"); @@ -2524,10 +2530,11 @@ gen_opcode(unsigned int opcode) if (!noflags) { comprintf("\tlive_flags();\n"); comprintf("\tend_needflags();\n"); - if (curi->smode != immi) - comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); - else + if (curi->smode != immi) { + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d, 0);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + } else { comprintf("\tduplicate_carry();\n"); + } comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); } genastore("data", curi->dmode, "dstreg", curi->size, "data"); @@ -2557,11 +2564,17 @@ gen_opcode(unsigned int opcode) if (curi->smode != immi) { uses_cmov; start_brace(); + comprintf("\tint cdata2 = scratchie++;\n"); comprintf("\tint cdata = scratchie++;\n"); comprintf("\tint tmpcnt = scratchie++;\n"); comprintf("\tmov_l_rr(tmpcnt,cnt);\n"); comprintf("\tand_l_ri(tmpcnt,63);\n"); comprintf("\tmov_l_ri(cdata, 0);\n"); + + comprintf("\tmov_l_ri(cdata2, 32);\n"); + comprintf("\tcmp_l(tmpcnt, cdata2);\n"); + comprintf("\tcmov_l_rr(tmpcnt, cdata, NATIVE_CC_EQ);\n"); + switch (curi->size) { case sz_byte: comprintf("\ttest_l_ri(tmpcnt, 0x38);\n"); @@ -2596,10 +2609,12 @@ gen_opcode(unsigned int opcode) if (!noflags) { comprintf("\tlive_flags();\n"); comprintf("\tend_needflags();\n"); - if (curi->smode != immi) - comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); - else + if (curi->smode != immi) { + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d, 1);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + } else { + comprintf("\tclear_overflow();\n"); comprintf("\tduplicate_carry();\n"); + } comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); } genastore("data", curi->dmode, "dstreg", curi->size, "data"); -- 2.47.3