The e500mc, e5500 and e6500 ignore W in mtfsfi and W/L in mtfsf.
Check that these fields do not select extended FPSCR fields, cause
illegal instruction exceptions or override the ordinary field mask.

Test both W values, all W/L combinations and the Rc variants. Seed ZE
and RN before each instruction so partial and zero field masks verify
that unaffected fields remain intact and selected fields receive the
expected values. Ignore the undefined upper word returned by mffs.

Register the test for e500mc in 32-bit mode and for e5500/e6500 in
64-bit mode, using the shared Book E startup and result handling.

Signed-off-by: Bin Meng <[email protected]>

---

 tests/tcg/ppc/system/fpscr.S     | 75 ++++++++++++++++++++++++++++++++
 tests/tcg/ppc/system/meson.build |  2 +-
 2 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/ppc/system/fpscr.S

diff --git a/tests/tcg/ppc/system/fpscr.S b/tests/tcg/ppc/system/fpscr.S
new file mode 100644
index 0000000000..41e90b1076
--- /dev/null
+++ b/tests/tcg/ppc/system/fpscr.S
@@ -0,0 +1,75 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2026 Process Mission
+ */
+
+#include "macros.inc"
+
+    .macro seed_fpscr
+    mtfsf 255, f2
+    mtfsfi 6, 1                 /* ZE */
+    mtfsfi 7, 2                 /* RN */
+    .endm
+
+    .macro check_fpscr expected
+    mffs f1
+    stfd f1, 8(r4)
+    lwz r11, 12(r4)
+    load32 r12, \expected
+    cmpw r11, r12
+    bne fail
+    .endm
+
+    .macro test_mtfsfi field, value, w, record, expected
+    seed_fpscr
+    .if \record
+    mtfsfi. \field, \value, \w
+    .else
+    mtfsfi \field, \value, \w
+    .endif
+    check_fpscr \expected
+    .endm
+
+    .macro test_mtfsf mask, w, l, record, expected
+    seed_fpscr
+    .if \record
+    mtfsf. \mask, f0, \l, \w
+    .else
+    mtfsf \mask, f0, \l, \w
+    .endif
+    check_fpscr \expected
+    .endm
+
+    .text
+    .globl test_main
+test_main:
+    load_addr r4, scratch
+    lfd f0, 0(r4)               /* Source: upper word 3, lower word 1 */
+    lfd f2, 16(r4)              /* Zero for a reproducible initial FPSCR */
+
+    .irp w, 0, 1
+    .irp record, 0, 1
+    test_mtfsfi 6, 4, \w, \record, 0x42
+    test_mtfsfi 7, 1, \w, \record, 0x11
+    .endr
+    .endr
+
+    .irp w, 0, 1
+    .irp l, 0, 1
+    .irp record, 0, 1
+    /* L must not override the ordinary field mask, and W is ignored */
+    test_mtfsf 0, \w, \l, \record, 0x12
+    test_mtfsf 1, \w, \l, \record, 0x11
+    test_mtfsf 2, \w, \l, \record, 0x02
+    test_mtfsf 255, \w, \l, \record, 0x01
+    .endr
+    .endr
+    .endr
+    b pass
+
+    .data
+    .balign 8
+scratch:
+    .long 3, 1
+    .space 16
diff --git a/tests/tcg/ppc/system/meson.build b/tests/tcg/ppc/system/meson.build
index 1598348656..ad4c257c9a 100644
--- a/tests/tcg/ppc/system/meson.build
+++ b/tests/tcg/ppc/system/meson.build
@@ -11,7 +11,7 @@ ppc_system_cflags = ['-nostdlib', '-ffreestanding', 
'-mcpu=power6',
                      '-Wl,-T', ppc_system_link_script, ppc_system_boot]
 ppc_system_qemu_args = ['-M', 'ppce500', '-accel', 'tcg', '-display', 'none',
                         '-serial', 'stdio', '-monitor', 'none', '-nic', 'none']
-ppc_system_sources = ['unsupported.S']
+ppc_system_sources = ['unsupported.S', 'fpscr.S']
 
 tests = []
 foreach src: ppc_system_sources
-- 
2.53.0


Reply via email to