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


Reply via email to