1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
peripherals: 0.863
performance: 0.813
files: 0.805
arm: 0.770
register: 0.770
debug: 0.753
socket: 0.727
PID: 0.724
hypervisor: 0.719
boot: 0.713
ppc: 0.682
architecture: 0.674
kernel: 0.667
graphic: 0.664
TCG: 0.662
risc-v: 0.657
permissions: 0.656
network: 0.647
vnc: 0.639
virtual: 0.620
semantic: 0.610
VMM: 0.590
device: 0.584
x86: 0.579
mistranslation: 0.564
user-level: 0.561
i386: 0.543
KVM: 0.512
assembly: 0.492
m68k: fpu: fmovem with multiple control registers has incorrect in memory order
Description of problem:
It looks like the order of reading/writing registers is currently incorrect for `fmovem` with multiple fpu control registers.
According to the manual:
```
The
registers are always moved in the same order, regardless of the addressing mode
used; the floating-point control register is moved first, followed by the floating-point
status register, and the floating-point instruction address register is moved last.
```
Current QEMU reads/writes them in the reverse order which is fine for most things but the test cases in 147bug compare against data that is in its binary and expects the data generated in memory by the CPU to match what is in it's binary.
Maybe something like this is needed:
``` diff
commit 466e8ead0115b6535e89aa2715f171112444b294 (HEAD -> m68kdt)
Author: Daniel Palmer <daniel@thingy.jp>
Date: Tue Aug 13 09:52:54 2024 +0900
fix fmovem ordering
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 92dc9d8563..64ff2df06e 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4924,8 +4924,8 @@ static void gen_op_fmove_fcr(CPUM68KState *env, DisasContext *s,
*/
if (is_write && mode == 4) {
- for (i = 2; i >= 0; i--, mask >>= 1) {
- if (mask & 1) {
+ for (i = 2; i >= 0; i--, mask <<= 1) {
+ if (mask & 0b100) {
gen_qemu_store_fcr(s, addr, 1 << i);
if (mask != 1) {
tcg_gen_subi_i32(addr, addr, opsize_bytes(OS_LONG));
@@ -4934,8 +4934,8 @@ static void gen_op_fmove_fcr(CPUM68KState *env, DisasContext *s,
}
tcg_gen_mov_i32(AREG(insn, 0), addr);
} else {
- for (i = 0; i < 3; i++, mask >>= 1) {
- if (mask & 1) {
+ for (i = 2; i >= 0; i--, mask <<= 1) {
+ if (mask & 0b100) {
if (is_write) {
gen_qemu_store_fcr(s, addr, 1 << i);
} else {
```
|