[PATCH] m68k: fix CAS2 writeback when Dc1==Dc2

Laurent Vivier posted 1 patch 1 month, 2 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20251226213707.331741-1-laurent@vivier.eu
Maintainers: Laurent Vivier <laurent@vivier.eu>
target/m68k/op_helper.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
[PATCH] m68k: fix CAS2 writeback when Dc1==Dc2
Posted by Laurent Vivier 1 month, 2 weeks ago
According to Programmer's Reference Manual, if Dc1 and Dc2 specify the
same data register and the comparison fails, memory operand 1 is stored
in the data register.

The current helpers wrote Dc1 then Dc2, leaving operand 2 in the shared
register.

Swap the writeback order for cas2w/cas2l so memory operand 1 wins.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target/m68k/op_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index e9c20a8e0322..10266b1e0e8b 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -799,8 +799,8 @@ void HELPER(cas2w)(CPUM68KState *env, uint32_t regs, uint32_t a1, uint32_t a2)
         env->cc_v = c2;
     }
     env->cc_op = CC_OP_CMPW;
-    env->dregs[Dc1] = deposit32(env->dregs[Dc1], 0, 16, l1);
     env->dregs[Dc2] = deposit32(env->dregs[Dc2], 0, 16, l2);
+    env->dregs[Dc1] = deposit32(env->dregs[Dc1], 0, 16, l1);
 }
 
 static void do_cas2l(CPUM68KState *env, uint32_t regs, uint32_t a1, uint32_t a2,
@@ -861,8 +861,8 @@ static void do_cas2l(CPUM68KState *env, uint32_t regs, uint32_t a1, uint32_t a2,
         env->cc_v = c2;
     }
     env->cc_op = CC_OP_CMPL;
-    env->dregs[Dc1] = l1;
     env->dregs[Dc2] = l2;
+    env->dregs[Dc1] = l1;
 }
 
 void HELPER(cas2l)(CPUM68KState *env, uint32_t regs, uint32_t a1, uint32_t a2)
-- 
2.52.0
Re: [PATCH] m68k: fix CAS2 writeback when Dc1==Dc2
Posted by Michael Tokarev 3 weeks, 3 days ago
On 12/27/25 00:37, Laurent Vivier wrote:
> According to Programmer's Reference Manual, if Dc1 and Dc2 specify the
> same data register and the comparison fails, memory operand 1 is stored
> in the data register.
> 
> The current helpers wrote Dc1 then Dc2, leaving operand 2 in the shared
> register.
> 
> Swap the writeback order for cas2w/cas2l so memory operand 1 wins.

This seems to be a qemu-stable material, I'm picking it up.
Please let me know if I shouldn't.

Thanks,

/mjt
Re: [PATCH] m68k: fix CAS2 writeback when Dc1==Dc2
Posted by Richard Henderson 1 month, 1 week ago
On 12/27/25 08:37, Laurent Vivier wrote:
> According to Programmer's Reference Manual, if Dc1 and Dc2 specify the
> same data register and the comparison fails, memory operand 1 is stored
> in the data register.

Where does it say that?

All I see is the pseudocode

CAS2
Destination 1 – Compare 1 → cc;
If Z, Destination 2 – Compare 2 → cc
If Z, Update 1 → Destination 1; Update 2 → Destination 2
Else Destination 1 → Compare 1; Destination 2 → Compare 2

which *suggests* that Dc2 is the final store.


r~

Re: [PATCH] m68k: fix CAS2 writeback when Dc1==Dc2
Posted by Laurent Vivier 1 month, 1 week ago
Le 29/12/2025 à 00:13, Richard Henderson a écrit :
> On 12/27/25 08:37, Laurent Vivier wrote:
>> According to Programmer's Reference Manual, if Dc1 and Dc2 specify the
>> same data register and the comparison fails, memory operand 1 is stored
>> in the data register.
> 
> Where does it say that?
> 
> All I see is the pseudocode
> 
> CAS2
> Destination 1 – Compare 1 → cc;
> If Z, Destination 2 – Compare 2 → cc
> If Z, Update 1 → Destination 1; Update 2 → Destination 2
> Else Destination 1 → Compare 1; Destination 2 → Compare 2
> 
> which *suggests* that Dc2 is the final store.
> 

This suggests but later it's explicit:

MP68000PA/AD REV.1
MOTOROLA M68000 FAMILY Programmer’s Reference Manual
(Includes CPU32 Instructions)
https://www.nxp.com/docs/en/reference-manual/M68000PRM.pdf

CAS/CAS2 Compare and Swap with Operand

P 4-68

Instuction Fields:

Dc1, Dc2 fields — Specify the data registers that contain the test values to be compared
to the first and second memory operands, respectively. If Dc1 and Dc2 specify the
same data register and the comparison fails, memory operand 1 is stored in the
data register.

Thanks,
Laurent
Re: [PATCH] m68k: fix CAS2 writeback when Dc1==Dc2
Posted by Richard Henderson 1 month ago
On 12/30/25 01:31, Laurent Vivier wrote:
> Le 29/12/2025 à 00:13, Richard Henderson a écrit :
>> On 12/27/25 08:37, Laurent Vivier wrote:
>>> According to Programmer's Reference Manual, if Dc1 and Dc2 specify the
>>> same data register and the comparison fails, memory operand 1 is stored
>>> in the data register.
>>
>> Where does it say that?
>>
>> All I see is the pseudocode
>>
>> CAS2
>> Destination 1 – Compare 1 → cc;
>> If Z, Destination 2 – Compare 2 → cc
>> If Z, Update 1 → Destination 1; Update 2 → Destination 2
>> Else Destination 1 → Compare 1; Destination 2 → Compare 2
>>
>> which *suggests* that Dc2 is the final store.
>>
> 
> This suggests but later it's explicit:
> 
> MP68000PA/AD REV.1
> MOTOROLA M68000 FAMILY Programmer’s Reference Manual
> (Includes CPU32 Instructions)
> https://www.nxp.com/docs/en/reference-manual/M68000PRM.pdf
> 
> CAS/CAS2 Compare and Swap with Operand
> 
> P 4-68
> 
> Instuction Fields:
> 
> Dc1, Dc2 fields — Specify the data registers that contain the test values to be compared
> to the first and second memory operands, respectively. If Dc1 and Dc2 specify the
> same data register and the comparison fails, memory operand 1 is stored in the
> data register.
> 
> Thanks,
> Laurent

Right you are.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~