Check the instruction subsets of e500mc, e5500 and e6500 through the
existing TCG test framework. System emulation allows checking SRR0 and
ESR on program exceptions. Run e500mc in 32-bit computation mode and
e5500/e6500 in 64-bit computation mode.

Add shared ppce500 startup code, a linker script and assembly helpers.
Use the existing UART and GPIO power-off devices to report results and
terminate QEMU. Register the system targets in ppc/system and
ppc64/system, sharing the assembly sources.

Test that unsupported floating-point instructions raise precise illegal
instruction exceptions. Also check cmpb, prtyw and prtyd on e500mc.

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

 meson_options.txt                  |  4 ++
 scripts/meson-buildoptions.sh      |  2 +
 tests/tcg/meson.build              |  1 +
 tests/tcg/ppc/meson.build          |  5 ++
 tests/tcg/ppc/system/README        | 22 +++++++
 tests/tcg/ppc/system/boot.S        | 92 ++++++++++++++++++++++++++++++
 tests/tcg/ppc/system/isa.out       |  1 +
 tests/tcg/ppc/system/kernel.ld     | 18 ++++++
 tests/tcg/ppc/system/macros.inc    | 56 ++++++++++++++++++
 tests/tcg/ppc/system/meson.build   | 39 +++++++++++++
 tests/tcg/ppc/system/unsupported.S | 31 ++++++++++
 tests/tcg/ppc64/meson.build        |  2 +
 tests/tcg/ppc64/system/meson.build | 32 +++++++++++
 13 files changed, 305 insertions(+)
 create mode 100644 tests/tcg/ppc/meson.build
 create mode 100644 tests/tcg/ppc/system/README
 create mode 100644 tests/tcg/ppc/system/boot.S
 create mode 100644 tests/tcg/ppc/system/isa.out
 create mode 100644 tests/tcg/ppc/system/kernel.ld
 create mode 100644 tests/tcg/ppc/system/macros.inc
 create mode 100644 tests/tcg/ppc/system/meson.build
 create mode 100644 tests/tcg/ppc/system/unsupported.S
 create mode 100644 tests/tcg/ppc64/system/meson.build

diff --git a/meson_options.txt b/meson_options.txt
index c9247e9de1..c75c8d7db7 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -465,6 +465,10 @@ option('tcg_tests_cross_cc_or1k', type: 'string',
        description: 'cc for or1k tcg tests')
 option('tcg_tests_cross_cflags_or1k', type: 'string',
        description: 'cflags for or1k tcg tests')
+option('tcg_tests_cross_cc_ppc', type: 'string',
+       description: 'cc for ppc tcg tests')
+option('tcg_tests_cross_cflags_ppc', type: 'string',
+       description: 'cflags for ppc tcg tests')
 option('tcg_tests_cross_cc_ppc64', type: 'string',
        description: 'cc for ppc64 tcg tests')
 option('tcg_tests_cross_cflags_ppc64', type: 'string',
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index 064e1429a4..5bac2bcf7c 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -545,6 +545,7 @@ _meson_option_parse() {
     --tcg-tests-cross-cc-mips64r6el=*) quote_sh 
"-Dtcg_tests_cross_cc_mips64r6el=$2" ;;
     --tcg-tests-cross-cc-mipsel=*) quote_sh "-Dtcg_tests_cross_cc_mipsel=$2" ;;
     --tcg-tests-cross-cc-or1k=*) quote_sh "-Dtcg_tests_cross_cc_or1k=$2" ;;
+    --tcg-tests-cross-cc-ppc=*) quote_sh "-Dtcg_tests_cross_cc_ppc=$2" ;;
     --tcg-tests-cross-cc-ppc64=*) quote_sh "-Dtcg_tests_cross_cc_ppc64=$2" ;;
     --tcg-tests-cross-cc-ppc64le=*) quote_sh "-Dtcg_tests_cross_cc_ppc64le=$2" 
;;
     --tcg-tests-cross-cc-riscv64=*) quote_sh "-Dtcg_tests_cross_cc_riscv64=$2" 
;;
@@ -571,6 +572,7 @@ _meson_option_parse() {
     --tcg-tests-cross-cflags-mips64r6el=*) quote_sh 
"-Dtcg_tests_cross_cflags_mips64r6el=$2" ;;
     --tcg-tests-cross-cflags-mipsel=*) quote_sh 
"-Dtcg_tests_cross_cflags_mipsel=$2" ;;
     --tcg-tests-cross-cflags-or1k=*) quote_sh 
"-Dtcg_tests_cross_cflags_or1k=$2" ;;
+    --tcg-tests-cross-cflags-ppc=*) quote_sh "-Dtcg_tests_cross_cflags_ppc=$2" 
;;
     --tcg-tests-cross-cflags-ppc64=*) quote_sh 
"-Dtcg_tests_cross_cflags_ppc64=$2" ;;
     --tcg-tests-cross-cflags-ppc64le=*) quote_sh 
"-Dtcg_tests_cross_cflags_ppc64le=$2" ;;
     --tcg-tests-cross-cflags-riscv64=*) quote_sh 
"-Dtcg_tests_cross_cflags_riscv64=$2" ;;
diff --git a/tests/tcg/meson.build b/tests/tcg/meson.build
index 4c0e30756d..5976540526 100644
--- a/tests/tcg/meson.build
+++ b/tests/tcg/meson.build
@@ -184,6 +184,7 @@ subdir('mipsel')
 subdir('mips64')
 subdir('mips64el')
 subdir('or1k')
+subdir('ppc')
 subdir('ppc64')
 subdir('ppc64le')
 subdir('riscv64')
diff --git a/tests/tcg/ppc/meson.build b/tests/tcg/ppc/meson.build
new file mode 100644
index 0000000000..869b8906c5
--- /dev/null
+++ b/tests/tcg/ppc/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (c) 2026 Process Mission
+
+subdir('system')
diff --git a/tests/tcg/ppc/system/README b/tests/tcg/ppc/system/README
new file mode 100644
index 0000000000..37a0fca951
--- /dev/null
+++ b/tests/tcg/ppc/system/README
@@ -0,0 +1,22 @@
+These Book E ISA tests use the generic tests/tcg build and test runner.
+They run on ppce500 with e500mc, e5500 and e6500 CPU models. System mode
+allows checking SRR0 and ESR on illegal instructions. The ppc target runs
+e500mc in 32-bit computation mode; ppc64 runs e5500/e6500 in 64-bit mode.
+
+The cross compiler builds freestanding ELF32 executables for ppc with
+-m32 and ELF64 executables for ppc64 with -m64. No target libc or
+multilib runtime is needed. The boot stub uses the initial RAM mapping
+provided by ppce500 -kernel, maps the CCSR area, and installs a program
+exception handler. Results go to UART0, and the existing GPIO power-off
+line terminates QEMU. The standard run_and_diff wrapper compares the
+output with isa.out.
+
+Configure QEMU with ppc-softmmu and/or ppc64-softmmu enabled. Compilers
+are found through the usual TCG cross-compiler detection or containers;
+--cross-cc-ppc and --cross-cc-ppc64 can select them explicitly. Run with:
+
+    make check-tcg-ppc-softmmu
+    make check-tcg-ppc64-softmmu
+
+These targets are generated only when configure finds a usable cross
+compiler or container. If missing, check the TCG tests configure summary.
diff --git a/tests/tcg/ppc/system/boot.S b/tests/tcg/ppc/system/boot.S
new file mode 100644
index 0000000000..2176205bcc
--- /dev/null
+++ b/tests/tcg/ppc/system/boot.S
@@ -0,0 +1,92 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2026 Process Mission
+ */
+
+#include "macros.inc"
+
+    .section .text.start, "ax"
+    .globl _start
+_start:
+    /* Map CCSR at VA 0xfe000000 to PA 0xfe0000000 in TLB1[1] */
+    load32 r3, 0x10010000
+    mtspr SPR_BOOKE_MAS0, r3    /* MAS0 */
+    load32 r3, 0xc0000500
+    mtspr SPR_BOOKE_MAS1, r3    /* MAS1: valid, protected, 1 MiB */
+    load32 r3, 0xfe00000a
+    mtspr SPR_BOOKE_MAS2, r3    /* MAS2: cache inhibited, guarded */
+    load32 r3, 0xe000003f
+    mtspr SPR_BOOKE_MAS3, r3    /* MAS3: RPN and permissions */
+    li r3, 15
+    mtspr SPR_BOOKE_MAS7, r3    /* MAS7 */
+    tlbwe
+    isync
+
+    load_addr r3, vectors
+    mtspr SPR_BOOKE_IVPR, r3    /* IVPR */
+    li r3, 0x600
+    mtspr SPR_BOOKE_IVOR6, r3   /* IVOR6: program exception */
+    li r14, 0                   /* No program exception expected */
+
+#ifdef _LP64
+    load32 r3, 0x80002000
+#else
+    li r3, 0x2000
+#endif
+    mtmsr r3                    /* Enable FP and select computation mode */
+    isync
+    b test_main
+
+    .section .vectors, "ax"
+vectors:
+    .space 0x600
+program_exception:
+    mfspr r3, SPR_SRR0          /* SRR0 must name the illegal instruction */
+#ifdef _LP64
+    cmpd r3, r14
+#else
+    cmpw r3, r14
+#endif
+    bne unexpected_exception
+    mfspr r3, SPR_BOOKE_ESR     /* ESR must contain only PIL */
+    load32 r5, 0x08000000
+    cmpw r3, r5
+    bne unexpected_exception
+    mtspr SPR_SRR0, r15
+    rfi
+unexpected_exception:
+    b fail
+
+    .text
+    .globl pass, fail
+pass:
+    load_addr r3, pass_message
+    b report
+fail:
+    load_addr r3, fail_message
+report:
+    load32 r4, 0xfe004500       /* UART0 */
+    rlwinm r4, r4, 0, 0, 31     /* Zero extend the address on 64-bit cores */
+1:
+    lbz r5, 0(r3)
+    cmpwi r5, 0
+    beq 2f
+    stb r5, 0(r4)
+    addi r3, r3, 1
+    b 1b
+2:
+    /* GPIO pin 0 is the ppce500 power-off line */
+    load32 r4, 0xfe0ff000
+    rlwinm r4, r4, 0, 0, 31
+    load32 r5, 0x80000000
+    stw r5, 0(r4)               /* Direction: output */
+    stw r5, 8(r4)               /* Data: assert pin 0 */
+3:
+    b 3b
+
+    .section .rodata
+pass_message:
+    .asciz "ISA:PASS\n"
+fail_message:
+    .asciz "ISA:FAIL\n"
diff --git a/tests/tcg/ppc/system/isa.out b/tests/tcg/ppc/system/isa.out
new file mode 100644
index 0000000000..34dabaf8bb
--- /dev/null
+++ b/tests/tcg/ppc/system/isa.out
@@ -0,0 +1 @@
+ISA:PASS
diff --git a/tests/tcg/ppc/system/kernel.ld b/tests/tcg/ppc/system/kernel.ld
new file mode 100644
index 0000000000..3f18a3e087
--- /dev/null
+++ b/tests/tcg/ppc/system/kernel.ld
@@ -0,0 +1,18 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2026 Process Mission
+ */
+
+ENTRY(_start)
+
+SECTIONS
+{
+    . = 0x100000;
+    .text : { *(.text.start) *(.text) }
+    . = ALIGN(0x10000);
+    .vectors : { *(.vectors) }
+    .rodata : { *(.rodata) }
+    .data : { *(.data) }
+    .bss : { *(.bss) }
+}
diff --git a/tests/tcg/ppc/system/macros.inc b/tests/tcg/ppc/system/macros.inc
new file mode 100644
index 0000000000..ec58f68cbd
--- /dev/null
+++ b/tests/tcg/ppc/system/macros.inc
@@ -0,0 +1,56 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2026 Process Mission
+ */
+
+#define SPR_SRR0         0x01a
+#define SPR_BOOKE_ESR    0x03e
+#define SPR_BOOKE_IVPR   0x03f
+#define SPR_BOOKE_IVOR6  0x196
+#define SPR_BOOKE_MAS0   0x270
+#define SPR_BOOKE_MAS1   0x271
+#define SPR_BOOKE_MAS2   0x272
+#define SPR_BOOKE_MAS3   0x273
+#define SPR_BOOKE_MAS7   0x3b0
+
+    .macro load32 reg, value
+    lis \reg, ((\value) >> 16) & 0xffff
+    ori \reg, \reg, (\value) & 0xffff
+    .endm
+
+    .macro load_addr reg, symbol
+    lis \reg, \symbol@ha
+    addi \reg, \reg, \symbol@l
+    .endm
+
+    .macro load_value reg, value
+#ifdef _LP64
+    load32 \reg, (\value) >> 32
+    sldi \reg, \reg, 32
+    oris \reg, \reg, ((\value) >> 16) & 0xffff
+    ori \reg, \reg, (\value) & 0xffff
+#else
+    load32 \reg, \value
+#endif
+    .endm
+
+    .macro check_value reg, value
+    load_value r12, \value
+#ifdef _LP64
+    cmpd \reg, r12
+#else
+    cmpw \reg, r12
+#endif
+    bne fail
+    .endm
+
+    .macro check_illegal insn:vararg
+    load_addr r14, 1f
+    load_addr r15, 2f
+1:
+    \insn
+    b fail                      /* Executing the instruction is a failure */
+2:
+    li r14, 0
+    .endm
diff --git a/tests/tcg/ppc/system/meson.build b/tests/tcg/ppc/system/meson.build
new file mode 100644
index 0000000000..1598348656
--- /dev/null
+++ b/tests/tcg/ppc/system/meson.build
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (c) 2026 Process Mission
+
+# Shared settings and sources for the ppc and ppc64 system targets
+ppc_system_link_script = files('kernel.ld')[0]
+ppc_system_boot = files('boot.S')[0]
+ppc_system_cflags = ['-nostdlib', '-ffreestanding', '-mcpu=power6',
+                     '-Wa,-mregnames', '-Wa,--noexecstack',
+                     '-Wl,--build-id=none',
+                     '-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']
+
+tests = []
+foreach src: ppc_system_sources
+  tests += {
+    'system/' + src: {
+      'exe_name': fs.stem(src) + '-e500mc-32',
+      'cflags': ppc_system_cflags + ['-m32', '-DE500MC'],
+      'qemu_args': ppc_system_qemu_args + ['-cpu', 'e500mc', '-kernel'],
+      'expected_output': 'system/isa.out',
+    }
+  }
+endforeach
+
+if 'qemu-system-ppc' in emulators
+  tcg_tests += {
+    'ppc-softmmu': {
+      'cc': 'powerpc-linux-gnu-gcc',
+      'cc_dockerfile': 'debian-all-test-cross',
+      'folder': 'ppc',
+      'gdb_arch': 'ppc',
+      'qemu': emulators['qemu-system-ppc'],
+      'tests': tests,
+    }
+  }
+endif
diff --git a/tests/tcg/ppc/system/unsupported.S 
b/tests/tcg/ppc/system/unsupported.S
new file mode 100644
index 0000000000..1737646b35
--- /dev/null
+++ b/tests/tcg/ppc/system/unsupported.S
@@ -0,0 +1,31 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2026 Process Mission
+ */
+
+#include "macros.inc"
+
+    .text
+    .globl test_main
+test_main:
+    /* Valid memory prevents address faults from hiding decode errors */
+    load_addr r4, scratch
+    check_illegal fcpsgn f0, f0, f0
+    check_illegal fcpsgn. f0, f0, f0
+    check_illegal lfiwax f0, 0, r4
+    check_illegal lfdp f0, 0(r4)
+    check_illegal lfdpx f0, 0, r4
+    check_illegal stfdp f0, 0(r4)
+    check_illegal stfdpx f0, 0, r4
+#ifdef E500MC
+    check_illegal cmpb r11, r9, r10
+    check_illegal prtyw r11, r9
+    check_illegal prtyd r11, r9
+#endif
+    b pass
+
+    .data
+    .balign 16
+scratch:
+    .space 16
diff --git a/tests/tcg/ppc64/meson.build b/tests/tcg/ppc64/meson.build
index 8cca4d65a4..6aa79fff28 100644
--- a/tests/tcg/ppc64/meson.build
+++ b/tests/tcg/ppc64/meson.build
@@ -3,6 +3,8 @@ cc_feat_cflags = {
   'power10': '-mcpu=power10',
 }
 
+subdir('system')
+
 tests = []
 
 # Multi arch tests
diff --git a/tests/tcg/ppc64/system/meson.build 
b/tests/tcg/ppc64/system/meson.build
new file mode 100644
index 0000000000..ca398860e3
--- /dev/null
+++ b/tests/tcg/ppc64/system/meson.build
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (c) 2026 Process Mission
+
+ppc64_system_cflags = ppc_system_cflags + ['-m64']
+tests = []
+foreach cpu: ['e5500', 'e6500']
+  sources = ppc_system_sources
+  foreach src: sources
+    tests += {
+      '../ppc/system/' + src: {
+        'exe_name': fs.stem(src) + '-' + cpu + '-64',
+        'cflags': ppc64_system_cflags,
+        'qemu_args': ppc_system_qemu_args + ['-cpu', cpu, '-kernel'],
+        'expected_output': '../ppc/system/isa.out',
+      }
+    }
+  endforeach
+endforeach
+
+if 'qemu-system-ppc64' in emulators
+  tcg_tests += {
+    'ppc64-softmmu': {
+      'cc': 'powerpc64-linux-gnu-gcc',
+      'cc_dockerfile': 'debian-all-test-cross',
+      'folder': 'ppc64',
+      'gdb_arch': 'ppc64',
+      'qemu': emulators['qemu-system-ppc64'],
+      'tests': tests,
+    }
+  }
+endif
-- 
2.53.0


Reply via email to