diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2023-07-24 18:06:36 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2023-07-24 18:06:36 +0100 |
commit | 3ee44ec72753ec0ff05ad1569dfa609203d722b2 (patch) | |
tree | 18e8d71f8d07e39af3c1a27ae81be54b91934078 | |
parent | 7d1d6a0c1996963c50dfc62e037284225d985d59 (diff) | |
parent | bd39b7b5f34c2f6b9272bf281ee0324cb07fc3ee (diff) |
Merge tag 'pull-request-2023-07-24' of https://gitlab.com/thuth/qemu into staging
* Fix emulation of s390x instructions: CKSM, CLM, ICM, MC, CLGEBR(A)
* Remove useless and non-working s390x migration avocado tests
* Fix loongarch CSRRD CPUID instruction when running on s390x hosts
* Disable flaky s390x virtio-gpu test by default
# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmS+q4IRHHRodXRoQHJl
# ZGhhdC5jb20ACgkQLtnXdP5wLbXB9xAAhF6bV23f1C9SHTWpxoN8oDYqJ3ZRR/D2
# z/4RHzXC5icw4jWPXG/zf19a+TT5UA03HFqvXbFlEtLVLF1/RY2wDnQbHJd2msRX
# YwvqE9SVoxbS3Jy+FS6XQ69WmPNoz01x+BIG5ig/jzXdOPZmylfik+1eAmHNHvcF
# GNCvdFwDzAZnB7N7y973BRnYn73CXBk3ap3UnnX/PaFD9k7DowTW5HB4ej/Uydwl
# z71/NbZhjgKYNpWgPYCI0Mypmz8b870o0VJxEJO9/1pWYLOoUcy/BKdOeGr3vqqO
# cduRL2c78Xd2RaUt4TgYmsZKkLazcG37XnQ5iaewDctTjfjuL5Oss16SO0WTut3p
# 8DtJHZCwD+0GcnbdFxyy7qdFmW2jgqsJtIPtnZs29ruEXnl0iyovjw38/J4kgBrF
# eHY+X2AyvlXI6zNkRMjKp+ltAkVx1vXbedM/bfaEcSBiKAI/OlV0Y1slX7+K14pR
# ITGOmBEG+yytMDnanzZKdN1DlBJMbGFYg9MctL7/yEwtD9vTl7gc66JhqcndkmCg
# VXSvqN8ECXPRbeNyZQZP+weXQydpkk3ndVIlSUrWpWsJtj0GDQOt+iK/KWcQ+AkS
# TXXp2OKM/mC+z6pdODsn/EoLl0toeDjpZFu27t/AvglNkmDFneY72LrtSwKgYHsi
# OJpjY1zCoxM=
# =Q+jQ
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 24 Jul 2023 17:49:06 BST
# gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg: issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg: aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5
* tag 'pull-request-2023-07-24' of https://gitlab.com/thuth/qemu:
tests/avocado/machine_s390_ccw_virtio: Skip the flaky virtio-gpu test by default
target/loongarch: Fix the CSRRD CPUID instruction on big endian hosts
tests/avocado/migration: Remove the malfunctioning s390x tests
tests/tcg/s390x: Test VCKSM
tests/tcg/s390x: Test STPQ
tests/tcg/s390x: Test MC
tests/tcg/s390x: Test ICM
tests/tcg/s390x: Test CLM
tests/tcg/s390x: Test CLGEBR and CGEBRA
tests/tcg/s390x: Test CKSM
target/s390x: Fix assertion failure in VFMIN/VFMAX with type 13
target/s390x: Make MC raise specification exception when class >= 16
target/s390x: Fix ICM with M3=0
target/s390x: Fix CONVERT TO LOGICAL/FIXED with out-of-range inputs
target/s390x: Fix CLM with M3=0
target/s390x: Make CKSM raise an exception if R2 is odd
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | target/loongarch/cpu.h | 1 | ||||
-rw-r--r-- | target/loongarch/csr_helper.c | 9 | ||||
-rw-r--r-- | target/loongarch/helper.h | 1 | ||||
-rw-r--r-- | target/loongarch/insn_trans/trans_privileged.c.inc | 8 | ||||
-rw-r--r-- | target/s390x/tcg/excp_helper.c | 2 | ||||
-rw-r--r-- | target/s390x/tcg/fpu_helper.c | 3 | ||||
-rw-r--r-- | target/s390x/tcg/insn-data.h.inc | 2 | ||||
-rw-r--r-- | target/s390x/tcg/mem_helper.c | 5 | ||||
-rw-r--r-- | target/s390x/tcg/translate.c | 16 | ||||
-rw-r--r-- | target/s390x/tcg/translate_vx.c.inc | 2 | ||||
-rw-r--r-- | tests/avocado/machine_s390_ccw_virtio.py | 51 | ||||
-rw-r--r-- | tests/avocado/migration.py | 18 | ||||
-rw-r--r-- | tests/tcg/s390x/Makefile.softmmu-target | 5 | ||||
-rw-r--r-- | tests/tcg/s390x/Makefile.target | 6 | ||||
-rw-r--r-- | tests/tcg/s390x/cgebra.c | 32 | ||||
-rw-r--r-- | tests/tcg/s390x/cksm.S | 29 | ||||
-rw-r--r-- | tests/tcg/s390x/clgebr.c | 32 | ||||
-rw-r--r-- | tests/tcg/s390x/clm.S | 29 | ||||
-rw-r--r-- | tests/tcg/s390x/icm.S | 32 | ||||
-rw-r--r-- | tests/tcg/s390x/mc.S | 56 | ||||
-rw-r--r-- | tests/tcg/s390x/stpq.S | 20 | ||||
-rw-r--r-- | tests/tcg/s390x/vcksm.c | 31 | ||||
-rw-r--r-- | tests/tcg/s390x/vx.h | 2 |
23 files changed, 337 insertions, 55 deletions
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index ed04027af1..fa371ca8ba 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -342,6 +342,7 @@ typedef struct CPUArchState { uint64_t CSR_DBG; uint64_t CSR_DERA; uint64_t CSR_DSAVE; + uint64_t CSR_CPUID; #ifndef CONFIG_USER_ONLY LoongArchTLB tlb[LOONGARCH_TLB_MAX]; diff --git a/target/loongarch/csr_helper.c b/target/loongarch/csr_helper.c index 6526367946..55341551a5 100644 --- a/target/loongarch/csr_helper.c +++ b/target/loongarch/csr_helper.c @@ -35,6 +35,15 @@ target_ulong helper_csrrd_pgd(CPULoongArchState *env) return v; } +target_ulong helper_csrrd_cpuid(CPULoongArchState *env) +{ + LoongArchCPU *lac = env_archcpu(env); + + env->CSR_CPUID = CPU(lac)->cpu_index; + + return env->CSR_CPUID; +} + target_ulong helper_csrrd_tval(CPULoongArchState *env) { LoongArchCPU *cpu = env_archcpu(env); diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index b9de77d926..ffb1e0b0bf 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -98,6 +98,7 @@ DEF_HELPER_1(rdtime_d, i64, env) #ifndef CONFIG_USER_ONLY /* CSRs helper */ DEF_HELPER_1(csrrd_pgd, i64, env) +DEF_HELPER_1(csrrd_cpuid, i64, env) DEF_HELPER_1(csrrd_tval, i64, env) DEF_HELPER_2(csrwr_estat, i64, env, tl) DEF_HELPER_2(csrwr_asid, i64, env, tl) diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc b/target/loongarch/insn_trans/trans_privileged.c.inc index 02bca7ca23..9c9de090f0 100644 --- a/target/loongarch/insn_trans/trans_privileged.c.inc +++ b/target/loongarch/insn_trans/trans_privileged.c.inc @@ -99,13 +99,7 @@ static const CSRInfo csr_info[] = { CSR_OFF(PWCH), CSR_OFF(STLBPS), CSR_OFF(RVACFG), - [LOONGARCH_CSR_CPUID] = { - .offset = (int)offsetof(CPUState, cpu_index) - - (int)offsetof(LoongArchCPU, env), - .flags = CSRFL_READONLY, - .readfn = NULL, - .writefn = NULL - }, + CSR_OFF_FUNCS(CPUID, CSRFL_READONLY, gen_helper_csrrd_cpuid, NULL), CSR_OFF_FLAGS(PRCFG1, CSRFL_READONLY), CSR_OFF_FLAGS(PRCFG2, CSRFL_READONLY), CSR_OFF_FLAGS(PRCFG3, CSRFL_READONLY), diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c index 228aa9f237..3da337f7c7 100644 --- a/target/s390x/tcg/excp_helper.c +++ b/target/s390x/tcg/excp_helper.c @@ -639,7 +639,7 @@ void monitor_event(CPUS390XState *env, void HELPER(monitor_call)(CPUS390XState *env, uint64_t monitor_code, uint32_t monitor_class) { - g_assert(monitor_class <= 0xff); + g_assert(monitor_class <= 0xf); if (env->cregs[8] & (0x8000 >> monitor_class)) { monitor_event(env, monitor_code, monitor_class, GETPC()); diff --git a/target/s390x/tcg/fpu_helper.c b/target/s390x/tcg/fpu_helper.c index 4b7fa58af3..3d941ed2d2 100644 --- a/target/s390x/tcg/fpu_helper.c +++ b/target/s390x/tcg/fpu_helper.c @@ -52,7 +52,8 @@ uint8_t s390_softfloat_exc_to_ieee(unsigned int exc) s390_exc |= (exc & float_flag_divbyzero) ? S390_IEEE_MASK_DIVBYZERO : 0; s390_exc |= (exc & float_flag_overflow) ? S390_IEEE_MASK_OVERFLOW : 0; s390_exc |= (exc & float_flag_underflow) ? S390_IEEE_MASK_UNDERFLOW : 0; - s390_exc |= (exc & float_flag_inexact) ? S390_IEEE_MASK_INEXACT : 0; + s390_exc |= (exc & (float_flag_inexact | float_flag_invalid_cvti)) ? + S390_IEEE_MASK_INEXACT : 0; return s390_exc; } diff --git a/target/s390x/tcg/insn-data.h.inc b/target/s390x/tcg/insn-data.h.inc index 457ed25d2f..86a509b0ac 100644 --- a/target/s390x/tcg/insn-data.h.inc +++ b/target/s390x/tcg/insn-data.h.inc @@ -157,7 +157,7 @@ C(0xb2fa, NIAI, E, EH, 0, 0, 0, 0, 0, 0) /* CHECKSUM */ - C(0xb241, CKSM, RRE, Z, r1_o, ra2, new, r1_32, cksm, 0) + C(0xb241, CKSM, RRE, Z, r1_o, ra2_E, new, r1_32, cksm, 0) /* COPY SIGN */ F(0xb372, CPSDR, RRF_b, FPSSH, f3, f2, new, f1, cps, 0, IF_AFP1 | IF_AFP2 | IF_AFP3) diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c index f417fb1183..84103251b9 100644 --- a/target/s390x/tcg/mem_helper.c +++ b/target/s390x/tcg/mem_helper.c @@ -667,6 +667,11 @@ uint32_t HELPER(clm)(CPUS390XState *env, uint32_t r1, uint32_t mask, HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1, mask, addr); + if (!mask) { + /* Recognize access exceptions for the first byte */ + probe_read(env, addr, 1, cpu_mmu_index(env, false), ra); + } + while (mask) { if (mask & 8) { uint8_t d = cpu_ldub_data_ra(env, addr, ra); diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 6661b27efa..84d76f1cea 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -2515,6 +2515,12 @@ static DisasJumpType op_icm(DisasContext *s, DisasOps *o) ccm = ((1ull << len) - 1) << pos; break; + case 0: + /* Recognize access exceptions for the first byte. */ + tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_UB); + gen_op_movi_cc(s, 0); + return DISAS_NEXT; + default: /* This is going to be a sequence of loads and inserts. */ pos = base + 32 - 8; @@ -3171,9 +3177,9 @@ static DisasJumpType op_lcbb(DisasContext *s, DisasOps *o) static DisasJumpType op_mc(DisasContext *s, DisasOps *o) { - const uint16_t monitor_class = get_field(s, i2); + const uint8_t monitor_class = get_field(s, i2); - if (monitor_class & 0xff00) { + if (monitor_class & 0xf0) { gen_program_exception(s, PGM_SPECIFICATION); return DISAS_NORETURN; } @@ -5779,6 +5785,12 @@ static void in2_ra2(DisasContext *s, DisasOps *o) } #define SPEC_in2_ra2 0 +static void in2_ra2_E(DisasContext *s, DisasOps *o) +{ + return in2_ra2(s, o); +} +#define SPEC_in2_ra2_E SPEC_r2_even + static void in2_a2(DisasContext *s, DisasOps *o) { int x2 = have_field(s, x2) ? get_field(s, x2) : 0; diff --git a/target/s390x/tcg/translate_vx.c.inc b/target/s390x/tcg/translate_vx.c.inc index 43dfbfd03f..f8df121d3d 100644 --- a/target/s390x/tcg/translate_vx.c.inc +++ b/target/s390x/tcg/translate_vx.c.inc @@ -3047,7 +3047,7 @@ static DisasJumpType op_vfmax(DisasContext *s, DisasOps *o) const uint8_t m5 = get_field(s, m5); gen_helper_gvec_3_ptr *fn; - if (m6 == 5 || m6 == 6 || m6 == 7 || m6 > 13) { + if (m6 == 5 || m6 == 6 || m6 == 7 || m6 >= 13) { gen_program_exception(s, PGM_SPECIFICATION); return DISAS_NORETURN; } diff --git a/tests/avocado/machine_s390_ccw_virtio.py b/tests/avocado/machine_s390_ccw_virtio.py index 78152f2ad1..e7a2a20ba6 100644 --- a/tests/avocado/machine_s390_ccw_virtio.py +++ b/tests/avocado/machine_s390_ccw_virtio.py @@ -159,7 +159,6 @@ class S390CCWVirtioMachine(QemuSystemTest): 'MemTotal: 115640 kB') - @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') def test_s390x_fedora(self): """ @@ -229,31 +228,35 @@ class S390CCWVirtioMachine(QemuSystemTest): # writing to the framebuffer. Since the PPM is uncompressed, we then # can simply read the written "magic bytes" back from the PPM file to # check whether the framebuffer is working as expected. - self.log.info("Test screendump of virtio-gpu device") - exec_command_and_wait_for_pattern(self, + # Unfortunately, this test is flaky, so we don't run it by default + if os.getenv('QEMU_TEST_FLAKY_TESTS'): + self.log.info("Test screendump of virtio-gpu device") + exec_command_and_wait_for_pattern(self, 'while ! (dmesg | grep gpudrmfb) ; do sleep 1 ; done', 'virtio_gpudrmfb frame buffer device') - exec_command_and_wait_for_pattern(self, - 'echo -e "\e[?25l" > /dev/tty0', ':/#') - exec_command_and_wait_for_pattern(self, 'for ((i=0;i<250;i++)); do ' - 'echo " The qu ick fo x j ump s o ver a laz y d og" >> fox.txt;' - 'done', - ':/#') - exec_command_and_wait_for_pattern(self, - 'dd if=fox.txt of=/dev/fb0 bs=1000 oflag=sync,nocache ; rm fox.txt', - '12+0 records out') - with tempfile.NamedTemporaryFile(suffix='.ppm', - prefix='qemu-scrdump-') as ppmfile: - self.vm.command('screendump', filename=ppmfile.name) - ppmfile.seek(0) - line = ppmfile.readline() - self.assertEqual(line, b"P6\n") - line = ppmfile.readline() - self.assertEqual(line, b"1280 800\n") - line = ppmfile.readline() - self.assertEqual(line, b"255\n") - line = ppmfile.readline(256) - self.assertEqual(line, b"The quick fox jumps over a lazy dog\n") + exec_command_and_wait_for_pattern(self, + 'echo -e "\e[?25l" > /dev/tty0', ':/#') + exec_command_and_wait_for_pattern(self, 'for ((i=0;i<250;i++)); do ' + 'echo " The qu ick fo x j ump s o ver a laz y d og" >> fox.txt;' + 'done', + ':/#') + exec_command_and_wait_for_pattern(self, + 'dd if=fox.txt of=/dev/fb0 bs=1000 oflag=sync,nocache ; rm fox.txt', + '12+0 records out') + with tempfile.NamedTemporaryFile(suffix='.ppm', + prefix='qemu-scrdump-') as ppmfile: + self.vm.command('screendump', filename=ppmfile.name) + ppmfile.seek(0) + line = ppmfile.readline() + self.assertEqual(line, b"P6\n") + line = ppmfile.readline() + self.assertEqual(line, b"1280 800\n") + line = ppmfile.readline() + self.assertEqual(line, b"255\n") + line = ppmfile.readline(256) + self.assertEqual(line, b"The quick fox jumps over a lazy dog\n") + else: + self.log.info("Skipped flaky screendump of virtio-gpu device test") # Hot-plug a virtio-crypto device and see whether it gets accepted self.log.info("Test hot-plug virtio-crypto device") diff --git a/tests/avocado/migration.py b/tests/avocado/migration.py index 8b2ec0e3c4..fdc1d234fb 100644 --- a/tests/avocado/migration.py +++ b/tests/avocado/migration.py @@ -134,21 +134,3 @@ class PPC64(MigrationTest): def test_migration_with_exec(self): self.migration_with_exec() - - -@skipUnless('s390x' in os.uname()[4], "host != target") -class S390X(MigrationTest): - """ - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - :avocado: tags=cpu:qemu - """ - - def test_migration_with_tcp_localhost(self): - self.migration_with_tcp_localhost() - - def test_migration_with_unix(self): - self.migration_with_unix() - - def test_migration_with_exec(self): - self.migration_with_exec() diff --git a/tests/tcg/s390x/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target index 242c7b0f83..76345b6e64 100644 --- a/tests/tcg/s390x/Makefile.softmmu-target +++ b/tests/tcg/s390x/Makefile.softmmu-target @@ -16,13 +16,18 @@ LDFLAGS=-nostdlib -static ASM_TESTS = \ bal \ + cksm \ + clm \ exrl-ssm-early \ + icm \ sam \ lpsw \ lpswe-early \ lra \ + mc \ ssm-early \ stosm-early \ + stpq \ unaligned-lowcore include $(S390X_SRC)/pgm-specification.mak diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target index 19fbbc6e53..1fc9809907 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -39,12 +39,17 @@ TESTS+=mxdb TESTS+=epsw TESTS+=larl TESTS+=mdeb +TESTS+=cgebra +TESTS+=clgebr cdsg: CFLAGS+=-pthread cdsg: LDFLAGS+=-pthread rxsbg: CFLAGS+=-O2 +cgebra: LDFLAGS+=-lm +clgebr: LDFLAGS+=-lm + include $(S390X_SRC)/pgm-specification.mak $(PGM_SPECIFICATION_TESTS): pgm-specification-user.o $(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-user.o @@ -53,6 +58,7 @@ TESTS += $(PGM_SPECIFICATION_TESTS) Z13_TESTS=vistr Z13_TESTS+=lcbb Z13_TESTS+=locfhr +Z13_TESTS+=vcksm $(Z13_TESTS): CFLAGS+=-march=z13 -O2 TESTS+=$(Z13_TESTS) diff --git a/tests/tcg/s390x/cgebra.c b/tests/tcg/s390x/cgebra.c new file mode 100644 index 0000000000..f91e10d2d3 --- /dev/null +++ b/tests/tcg/s390x/cgebra.c @@ -0,0 +1,32 @@ +/* + * Test the CGEBRA instruction. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <assert.h> +#include <fenv.h> +#include <stdlib.h> + +int main(void) +{ + float r2 = 1E+300; + long long r1; + int cc; + + feclearexcept(FE_ALL_EXCEPT); + asm("cgebra %[r1],%[m3],%[r2],%[m4]\n" + "ipm %[cc]\n" + : [r1] "=r" (r1) + , [cc] "=r" (cc) + : [m3] "i" (5) /* round toward 0 */ + , [r2] "f" (r2) + , [m4] "i" (8) /* bit 0 is set, but must be ignored; XxC is not set */ + : "cc"); + cc >>= 28; + + assert(r1 == 0x7fffffffffffffffLL); + assert(cc == 3); + assert(fetestexcept(FE_ALL_EXCEPT) == (FE_INVALID | FE_INEXACT)); + + return EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/cksm.S b/tests/tcg/s390x/cksm.S new file mode 100644 index 0000000000..563fd3d233 --- /dev/null +++ b/tests/tcg/s390x/cksm.S @@ -0,0 +1,29 @@ + .org 0x8e +program_interruption_code: + .org 0x1d0 /* program new PSW */ + .quad 0,pgm + .org 0x200 /* lowcore padding */ + .globl _start +_start: + lmg %r0,%r1,cksm_args + cksm %r2,%r0 + c %r2,cksm_exp + jne failure + .insn rre,0xb2410000,%r2,%r15 /* cksm %r2,%r15 */ +failure: + lpswe failure_psw +pgm: + chhsi program_interruption_code,6 /* specification exception? */ + jne failure + lpswe success_psw +cksm_args: + .quad cksm_buf, 16 +cksm_buf: + .quad 0xaaaabbbbcccc0000, 0x12345678 +cksm_exp: + .long 0x89ab1234 + .align 8 +success_psw: + .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */ +failure_psw: + .quad 0x2000000000000,0 /* disabled wait */ diff --git a/tests/tcg/s390x/clgebr.c b/tests/tcg/s390x/clgebr.c new file mode 100644 index 0000000000..d491899b56 --- /dev/null +++ b/tests/tcg/s390x/clgebr.c @@ -0,0 +1,32 @@ +/* + * Test the CLGEBR instruction. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <assert.h> +#include <fenv.h> +#include <stdlib.h> + +int main(void) +{ + float r2 = -1; + long long r1; + int cc; + + feclearexcept(FE_ALL_EXCEPT); + asm("clgebr %[r1],%[m3],%[r2],%[m4]\n" + "ipm %[cc]\n" + : [r1] "=r" (r1) + , [cc] "=r" (cc) + : [m3] "i" (5) /* round toward 0 */ + , [r2] "f" (r2) + , [m4] "i" (8) /* bit 0 is set, but must be ignored; XxC is not set */ + : "cc"); + cc >>= 28; + + assert(r1 == 0); + assert(cc == 3); + assert(fetestexcept(FE_ALL_EXCEPT) == (FE_INVALID | FE_INEXACT)); + + return EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/clm.S b/tests/tcg/s390x/clm.S new file mode 100644 index 0000000000..17156a81f2 --- /dev/null +++ b/tests/tcg/s390x/clm.S @@ -0,0 +1,29 @@ + .org 0x8e +program_interruption_code: + .org 0x1d0 /* program new PSW */ + .quad 0,pgm + .org 0x200 /* lowcore padding */ + .globl _start +_start: + lgrl %r0,op1 + clm %r0,6,op2 + jle failure + lgrl %r1,bad_addr + clm %r0,0,0(%r1) +failure: + lpswe failure_psw +pgm: + chhsi program_interruption_code,5 /* addressing exception? */ + jne failure + lpswe success_psw + .align 8 +op1: + .quad 0x1234567887654321 +op2: + .quad 0x3456789abcdef012 +bad_addr: + .quad 0xffffffff00000000 +success_psw: + .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */ +failure_psw: + .quad 0x2000000000000,0 /* disabled wait */ diff --git a/tests/tcg/s390x/icm.S b/tests/tcg/s390x/icm.S new file mode 100644 index 0000000000..d24d1f52fb --- /dev/null +++ b/tests/tcg/s390x/icm.S @@ -0,0 +1,32 @@ + .org 0x8e +program_interruption_code: + .org 0x1d0 /* program new PSW */ + .quad 0,pgm + .org 0x200 /* lowcore padding */ + .globl _start +_start: + lgrl %r0,op1 + icm %r0,10,op2 + cg %r0,exp + jne failure + lgrl %r1,bad_addr + icm %r0,0,0(%r1) +failure: + lpswe failure_psw +pgm: + chhsi program_interruption_code,5 /* addressing exception? */ + jne failure + lpswe success_psw + .align 8 +op1: + .quad 0x1234567887654321 +op2: + .quad 0x0011223344556677 +exp: + .quad 0x1234567800651121 +bad_addr: + .quad 0xffffffff00000000 +success_psw: + .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */ +failure_psw: + .quad 0x2000000000000,0 /* disabled wait */ diff --git a/tests/tcg/s390x/mc.S b/tests/tcg/s390x/mc.S new file mode 100644 index 0000000000..e7466bb4b5 --- /dev/null +++ b/tests/tcg/s390x/mc.S @@ -0,0 +1,56 @@ + .org 0x8d +ilc: + .org 0x8e +program_interruption_code: + .org 0x94 +monitor_class: + .org 0xb0 +monitor_code: + .org 0x150 +program_old_psw: + .org 0x1d0 /* program new PSW */ + .quad 0x180000000,pgm /* 64-bit mode */ + .org 0x200 /* lowcore padding */ + .globl _start +_start: + stctg %c8,%c8,c8 /* enable only monitor class 1 */ + mvhhi c8+6,0x4000 + lctlg %c8,%c8,c8 +mc_nop: + mc 123,0 +mc_monitor_event: + mc 321,1 + j failure +mc_specification: + mc 333,16 + j failure +pgm: + lgrl %r0,program_old_psw+8 /* ilc adjustment */ + llgc %r1,ilc + sgr %r0,%r1 + larl %r1,mc_monitor_event /* dispatch based on old PSW */ + cgrje %r0,%r1,pgm_monitor_event + larl %r1,mc_specification + cgrje %r0,%r1,pgm_specification + j failure +pgm_monitor_event: + chhsi program_interruption_code,0x40 /* monitor event? */ + jne failure + chhsi monitor_class,1 /* class from mc_monitor_event? */ + jne failure + cghsi monitor_code,321 /* code from mc_monitor_event? */ + jne failure + j mc_specification /* next test */ +pgm_specification: + chhsi program_interruption_code,6 /* specification exception? */ + jne failure + lpswe success_psw +failure: + lpswe failure_psw + .align 8 +c8: + .quad 0 +success_psw: + .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */ +failure_psw: + .quad 0x2000000000000,0 /* disabled wait */ diff --git a/tests/tcg/s390x/stpq.S b/tests/tcg/s390x/stpq.S new file mode 100644 index 0000000000..687a52eafa --- /dev/null +++ b/tests/tcg/s390x/stpq.S @@ -0,0 +1,20 @@ + .org 0x200 /* lowcore padding */ + .globl _start +_start: + lgrl %r0,value + lgrl %r1,value+8 + stpq %r0,stored_value + clc stored_value(16),value + jne failure + lpswe success_psw +failure: + lpswe failure_psw + .align 16 +value: + .quad 0x1234567887654321, 0x8765432112345678 +stored_value: + .quad 0, 0 +success_psw: + .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */ +failure_psw: + .quad 0x2000000000000,0 /* disabled wait */ diff --git a/tests/tcg/s390x/vcksm.c b/tests/tcg/s390x/vcksm.c new file mode 100644 index 0000000000..452daaae6c --- /dev/null +++ b/tests/tcg/s390x/vcksm.c @@ -0,0 +1,31 @@ +/* + * Test the VCKSM instruction. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include "vx.h" + +int main(void) +{ + S390Vector v1; + S390Vector v2 = { + .d[0] = 0xb2261c8140edce49ULL, + .d[1] = 0x387bf5a433af39d1ULL, + }; + S390Vector v3 = { + .d[0] = 0x73b03d2c7f9e654eULL, + .d[1] = 0x23d74e51fb479877ULL, + }; + S390Vector exp = {.d[0] = 0xdedd7f8eULL, .d[1] = 0ULL}; + + asm volatile("vcksm %[v1],%[v2],%[v3]" + : [v1] "=v" (v1.v) + : [v2] "v" (v2.v) + , [v3] "v" (v3.v)); + assert(memcmp(&v1, &exp, sizeof(v1)) == 0); + + return EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/vx.h b/tests/tcg/s390x/vx.h index 02e7fd518a..00701dbe35 100644 --- a/tests/tcg/s390x/vx.h +++ b/tests/tcg/s390x/vx.h @@ -1,6 +1,8 @@ #ifndef QEMU_TESTS_S390X_VX_H #define QEMU_TESTS_S390X_VX_H +#include <stdint.h> + typedef union S390Vector { uint64_t d[2]; /* doubleword */ uint32_t w[4]; /* word */ |