From: Richard Henderson <[email protected]>
Signed-off-by: Richard Henderson <[email protected]>
(cherry picked from commit c66fe5b04d643d013e97cbbede5b736b56a667d4)
(Mjt: adjust across make=>meson conversion in tcg tests)
Signed-off-by: Michael Tokarev <[email protected]>
diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
index 97c0f021902..118eaf7896a 100644
--- a/tests/tcg/s390x/Makefile.target
+++ b/tests/tcg/s390x/Makefile.target
@@ -51,6 +51,7 @@ TESTS+=ts
TESTS+=ex-smc
TESTS+=divide-to-integer
TESTS+=stckf
+TESTS+=issue4449
cdsg: CFLAGS+=-pthread
cdsg: LDFLAGS+=-pthread
diff --git a/tests/tcg/s390x/issue4449.c b/tests/tcg/s390x/issue4449.c
new file mode 100644
index 00000000000..0c9c80e8cac
--- /dev/null
+++ b/tests/tcg/s390x/issue4449.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <assert.h>
+
+#define CASE(name, old, cst, sh) \
+ static void __attribute__((noinline)) case_##name(void) { \
+ unsigned long t1, got; \
+ __asm__("lhi %0," #cst "\n\t" /* low 32 known, high not */ \
+ "lghi %1," #old "\n\t" /* whole register constant */ \
+ "sllk %1,%0," #sh "\n\t" /* 32-bit write = deposit */ \
+ "brc 15,1f\n\t" /* ends the translation block */ \
+ "nop\n" \
+ "1:" \
+ : "=r"(t1), "=r"(got) : : ); \
+ unsigned long want = (unsigned)(cst) << (sh); \
+ assert(got == want); \
+ }
+
+CASE(a, 256, 128, 1);
+CASE(b, 128, 128, 0);
+CASE(c, 512, 128, 2);
+CASE(d, 2, 1, 1);
+
+int main()
+{
+ case_a();
+ case_b();
+ case_c();
+ case_d();
+ return 0;
+}
--
2.47.3