From: Dimitris Panokostas Date: Mon, 1 Jun 2026 17:06:40 +0000 (+0200) Subject: fix: handle ARM64 JIT MOVEM predec base X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=fc7cd462b14cf942c29b220f399c27ca85c93568;p=francis%2Fwinuae.git fix: handle ARM64 JIT MOVEM predec base --- diff --git a/jit/arm/compemu_arm.cpp b/jit/arm/compemu_arm.cpp index 541f54c2..72de3359 100644 --- a/jit/arm/compemu_arm.cpp +++ b/jit/arm/compemu_arm.cpp @@ -11581,7 +11581,7 @@ uae_u32 REGPARAM2 op_48a0_0_comp_ff(uae_u32 opcode) { int i; signed char offset = 0; int srca = dstreg + 8; - if (!special_mem) { + if (!special_mem && !(mask & (1 << (7 - dstreg)))) { int native = alloc_scratch(); get_n_addr(srca, native); for (i = 0; i < 16; i++) { @@ -11592,10 +11592,15 @@ uae_u32 REGPARAM2 op_48a0_0_comp_ff(uae_u32 opcode) { } lea_l_brr(8 + dstreg, srca, (uae_s32) offset); } else { + int base = alloc_scratch(); + lea_l_brr(base, srca, -2); for (i = 0; i < 16; i++) { if ((mask >> i) & 1) { + int value = 15 - i; arm_SUB_l_ri8(srca, 2); - writeword(srca, 15 - i); + if (value == srca) + value = base; + writeword(srca, value); } } mov_l_rr(8 + dstreg, srca); @@ -11788,7 +11793,7 @@ uae_u32 REGPARAM2 op_48e0_0_comp_ff(uae_u32 opcode) { int i; signed char offset = 0; int srca = dstreg + 8; - if (!special_mem) { + if (!special_mem && !(mask & (1 << (7 - dstreg)))) { int native = alloc_scratch(); get_n_addr(srca, native); for (i = 0; i < 16; i++) { @@ -11799,10 +11804,15 @@ uae_u32 REGPARAM2 op_48e0_0_comp_ff(uae_u32 opcode) { } lea_l_brr(8 + dstreg, srca, (uae_s32) offset); } else { + int base = alloc_scratch(); + lea_l_brr(base, srca, -4); for (i = 0; i < 16; i++) { if ((mask >> i) & 1) { + int value = 15 - i; arm_SUB_l_ri8(srca, 4); - writelong(srca, 15 - i); + if (value == srca) + value = base; + writelong(srca, value); } } mov_l_rr(8 + dstreg, srca); @@ -38767,7 +38777,7 @@ uae_u32 REGPARAM2 op_48a0_0_comp_nf(uae_u32 opcode) { int i; signed char offset = 0; int srca = dstreg + 8; - if (!special_mem) { + if (!special_mem && !(mask & (1 << (7 - dstreg)))) { int native = alloc_scratch(); get_n_addr(srca, native); for (i = 0; i < 16; i++) { @@ -38778,10 +38788,15 @@ uae_u32 REGPARAM2 op_48a0_0_comp_nf(uae_u32 opcode) { } lea_l_brr(8 + dstreg, srca, (uae_s32) offset); } else { + int base = alloc_scratch(); + lea_l_brr(base, srca, -2); for (i = 0; i < 16; i++) { if ((mask >> i) & 1) { + int value = 15 - i; arm_SUB_l_ri8(srca, 2); - writeword(srca, 15 - i); + if (value == srca) + value = base; + writeword(srca, value); } } mov_l_rr(8 + dstreg, srca); @@ -38973,7 +38988,7 @@ uae_u32 REGPARAM2 op_48e0_0_comp_nf(uae_u32 opcode) { int i; signed char offset = 0; int srca = dstreg + 8; - if (!special_mem) { + if (!special_mem && !(mask & (1 << (7 - dstreg)))) { int native = alloc_scratch(); get_n_addr(srca, native); for (i = 0; i < 16; i++) { @@ -38984,10 +38999,15 @@ uae_u32 REGPARAM2 op_48e0_0_comp_nf(uae_u32 opcode) { } lea_l_brr(8 + dstreg, srca, (uae_s32) offset); } else { + int base = alloc_scratch(); + lea_l_brr(base, srca, -4); for (i = 0; i < 16; i++) { if ((mask >> i) & 1) { + int value = 15 - i; arm_SUB_l_ri8(srca, 4); - writelong(srca, 15 - i); + if (value == srca) + value = base; + writelong(srca, value); } } mov_l_rr(8 + dstreg, srca); diff --git a/jit/arm/gencomp_arm.c b/jit/arm/gencomp_arm.c index 90ef1374..43526914 100644 --- a/jit/arm/gencomp_arm.c +++ b/jit/arm/gencomp_arm.c @@ -741,55 +741,97 @@ static void genmovemle(uae_u16 opcode) { genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); - comprintf("\tget_n_addr(srca,native,scratchie);\n"); - - if (table68k[opcode].dmode != Apdi) { - comprintf("\tfor (i=0;i<16;i++) {\n" - "\t\tif ((mask>>i)&1) {\n"); + if (table68k[opcode].dmode == Apdi) { + comprintf("\tif (!special_mem && !(mask & (1 << (7 - dstreg)))) {\n"); + comprintf("\t\tget_n_addr(srca,native,scratchie);\n"); + comprintf("\t\tfor (i=0;i<16;i++) {\n" + "\t\t\tif ((mask>>i)&1) {\n"); + switch (table68k[opcode].size) { + case sz_long: + comprintf("\t\t\t\toffset-=4;\n" + "\t\t\t\tmov_l_rr(tmp,15-i);\n" + "\t\t\t\tmid_bswap_32(tmp);\n" + "\t\t\t\tmov_l_Rr(native,tmp,offset);\n"); + break; + case sz_word: + comprintf("\t\t\t\toffset-=2;\n" + "\t\t\t\tmov_l_rr(tmp,15-i);\n" + "\t\t\t\tmid_bswap_16(tmp);\n" + "\t\t\t\tmov_w_Rr(native,tmp,offset);\n"); + break; + default: + assert(0); + break; + } + comprintf("\t\t\t}\n" + "\t\t}\n"); + comprintf("\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n"); + comprintf("\t} else {\n"); switch (table68k[opcode].size) { case sz_long: - comprintf("\t\t\tmov_l_rr(tmp,i);\n" - "\t\t\tmid_bswap_32(tmp);\n" - "\t\t\tmov_l_Rr(native,tmp,offset);\n" - "\t\t\toffset+=4;\n"); + comprintf("\t\tint base=scratchie++;\n" + "\t\tlea_l_brr(base,srca,-4);\n"); break; case sz_word: - comprintf("\t\t\tmov_l_rr(tmp,i);\n" - "\t\t\tmid_bswap_16(tmp);\n" - "\t\t\tmov_w_Rr(native,tmp,offset);\n" - "\t\t\toffset+=2;\n"); + comprintf("\t\tint base=scratchie++;\n" + "\t\tlea_l_brr(base,srca,-2);\n"); break; default: assert(0); break; } - } else { /* Pre-decrement */ - comprintf("\tfor (i=0;i<16;i++) {\n" - "\t\tif ((mask>>i)&1) {\n"); + comprintf("\t\tfor (i=0;i<16;i++) {\n" + "\t\t\tif ((mask>>i)&1) {\n"); switch (table68k[opcode].size) { case sz_long: - comprintf("\t\t\toffset-=4;\n" - "\t\t\tmov_l_rr(tmp,15-i);\n" - "\t\t\tmid_bswap_32(tmp);\n" - "\t\t\tmov_l_Rr(native,tmp,offset);\n"); + comprintf("\t\t\t\tint value=15-i;\n" + "\t\t\t\tsub_l_ri(srca,4);\n" + "\t\t\t\tif (value == srca)\n" + "\t\t\t\t\tvalue=base;\n" + "\t\t\t\twritelong(srca,value);\n"); break; case sz_word: - comprintf("\t\t\toffset-=2;\n" - "\t\t\tmov_l_rr(tmp,15-i);\n" - "\t\t\tmid_bswap_16(tmp);\n" - "\t\t\tmov_w_Rr(native,tmp,offset);\n"); + comprintf("\t\t\t\tint value=15-i;\n" + "\t\t\t\tsub_l_ri(srca,2);\n" + "\t\t\t\tif (value == srca)\n" + "\t\t\t\t\tvalue=base;\n" + "\t\t\t\twriteword(srca,value);\n"); break; default: assert(0); break; } + comprintf("\t\t\t}\n" + "\t\t}\n"); + comprintf("\t\tmov_l_rr(8+dstreg,srca);\n"); + comprintf("\t}\n"); + return; + } + + comprintf("\tget_n_addr(srca,native,scratchie);\n"); + + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch (table68k[opcode].size) { + case sz_long: + comprintf("\t\t\tmov_l_rr(tmp,i);\n" + "\t\t\tmid_bswap_32(tmp);\n" + "\t\t\tmov_l_Rr(native,tmp,offset);\n" + "\t\t\toffset+=4;\n"); + break; + case sz_word: + comprintf("\t\t\tmov_l_rr(tmp,i);\n" + "\t\t\tmid_bswap_16(tmp);\n" + "\t\t\tmov_w_Rr(native,tmp,offset);\n" + "\t\t\toffset+=2;\n"); + break; + default: + assert(0); + break; } comprintf("\t\t}\n" "\t}"); - if (table68k[opcode].dmode == Apdi) { - comprintf("\t\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n"); - } } static void duplicate_carry(void) {