diff mbox series

[v7,3/4] tests/tcg/s390x: Tests for Miscellaneous-Instruction-Extensions Facility 3

Message ID 20220223223117.66660-4-dmiller423@gmail.com
State New
Headers show
Series s390x: Add partial z15 support and tests | expand

Commit Message

David Miller Feb. 23, 2022, 10:31 p.m. UTC
tests/tcg/s390x/mie3-compl.c: [N]*K instructions
tests/tcg/s390x/mie3-mvcrl.c: MVCRL instruction
tests/tcg/s390x/mie3-sel.c:  SELECT instruction

Signed-off-by: David Miller <dmiller423@gmail.com>
---
 tests/tcg/s390x/Makefile.target |  5 ++-
 tests/tcg/s390x/mie3-compl.c    | 55 +++++++++++++++++++++++++++++++++
 tests/tcg/s390x/mie3-mvcrl.c    | 31 +++++++++++++++++++
 tests/tcg/s390x/mie3-sel.c      | 42 +++++++++++++++++++++++++
 4 files changed, 132 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/s390x/mie3-compl.c
 create mode 100644 tests/tcg/s390x/mie3-mvcrl.c
 create mode 100644 tests/tcg/s390x/mie3-sel.c

Comments

Richard Henderson Feb. 23, 2022, 11:43 p.m. UTC | #1
On 2/23/22 12:31, David Miller wrote:
> +#define F_EPI "stg %%r0, %[res] " : [res] "+m" (res) : : "r0", "r2", "r3"
> +
> +#define F_PRO    asm ( \
> +    "llihf %%r0,801\n" \
> +    "lg %%r2, %[a]\n"  \
> +    "lg %%r3, %[b] "   \
> +    : : [a] "m" (a),   \
> +        [b] "m" (b)    \
> +    : "r2", "r3")
> +
> +#define FbinOp(S, ASM) uint64_t S(uint64_t a, uint64_t b) \
> +{ uint64_t res = 0; F_PRO; ASM; return res; }
> +
> +/* AND WITH COMPLEMENT */
> +FbinOp(_ncrk,  asm("ncrk  %%r0, %%r3, %%r2\n" F_EPI))
> +FbinOp(_ncgrk, asm("ncgrk %%r0, %%r3, %%r2\n" F_EPI))

Better written as

   asm("ncrk %0, %3, %2" : "=&r"(res) : "r"(a), "r"(b) : "cc");

and drop F_PRO and F_EPI.  Use the asm constraints properly to place the operands.

> +/* NAND */
> +FbinOp(_nnrk,  asm("nnrk  %%r0, %%r3, %%r2\n" F_EPI))
> +FbinOp(_nngrk, asm("nngrk %%r0, %%r3, %%r2\n" F_EPI))
> +
> +/* NOT XOR */
> +FbinOp(_nxrk,  asm("nxrk  %%r0, %%r3, %%r2\n" F_EPI))
> +FbinOp(_nxgrk, asm("nxgrk %%r0, %%r3, %%r2\n" F_EPI))
> +
> +/* NOR */
> +FbinOp(_nork,  asm("nork  %%r0, %%r3, %%r2\n" F_EPI))
> +FbinOp(_nogrk, asm("nogrk %%r0, %%r3, %%r2\n" F_EPI))
> +
> +/* OR WITH COMPLEMENT */
> +FbinOp(_ocrk,  asm("ocrk  %%r0, %%r3, %%r2\n" F_EPI))
> +FbinOp(_ocgrk, asm("ocgrk %%r0, %%r3, %%r2\n" F_EPI))

Similarly.

> +++ b/tests/tcg/s390x/mie3-sel.c
> @@ -0,0 +1,42 @@
> +#include <stdint.h>
> +
> +
> +#define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
> +{                       \
> +uint64_t res = 0;       \
> +asm (                   \
> +    "lg %%r2, %[a]\n"   \
> +    "lg %%r3, %[b]\n"   \
> +    "lg %%r0, %[c]\n"   \
> +    "ltgr %%r0, %%r0\n" \
> +    ASM                 \
> +    "stg %%r0, %[res] " \
> +    : [res] "=m" (res)  \
> +    : [a] "m" (a),      \
> +      [b] "m" (b),      \
> +      [c] "m" (c)       \
> +    : "r0", "r2",       \
> +      "r3", "r4"        \
> +    );                  \
> +    return res;         \
> +}
> +
> +
> +Fi3 (_selre,    "selre    %%r0, %%r3, %%r2\n")
> +Fi3 (_selgrz,   "selgrz   %%r0, %%r3, %%r2\n")
> +Fi3 (_selfhrnz, "selfhrnz %%r0, %%r3, %%r2\n")

Similarly:

   asm("ltgr %3, %3; selre %0, %2, %1"
       : "=&r"(res) : "r"(a), "r"(b), "r"(c) : "cc");

Although none of this is going to work with .insn.  We *ought* to be able to use the 
debian11 update plus a change to tests/tcg/configure.sh to detect host support for 
-march=z15 to drop that change.


r~
Richard Henderson Feb. 23, 2022, 11:44 p.m. UTC | #2
On 2/23/22 13:43, Richard Henderson wrote:
> Although none of this is going to work with .insn...

I beg your pardon, this is incorrect: .insn does have fields for the register arguments.


r~
Thomas Huth Feb. 28, 2022, 10:14 a.m. UTC | #3
On 24/02/2022 00.43, Richard Henderson wrote:
> On 2/23/22 12:31, David Miller wrote:
>> +#define F_EPI "stg %%r0, %[res] " : [res] "+m" (res) : : "r0", "r2", "r3"
>> +
>> +#define F_PRO    asm ( \
>> +    "llihf %%r0,801\n" \
>> +    "lg %%r2, %[a]\n"  \
>> +    "lg %%r3, %[b] "   \
>> +    : : [a] "m" (a),   \
>> +        [b] "m" (b)    \
>> +    : "r2", "r3")
>> +
>> +#define FbinOp(S, ASM) uint64_t S(uint64_t a, uint64_t b) \
>> +{ uint64_t res = 0; F_PRO; ASM; return res; }
>> +
>> +/* AND WITH COMPLEMENT */
>> +FbinOp(_ncrk,  asm("ncrk  %%r0, %%r3, %%r2\n" F_EPI))
>> +FbinOp(_ncgrk, asm("ncgrk %%r0, %%r3, %%r2\n" F_EPI))
> 
> Better written as
> 
>    asm("ncrk %0, %3, %2" : "=&r"(res) : "r"(a), "r"(b) : "cc");

I agree with Richard, especially since it's kind of "dangerous" to chain 
multiple asm() statements (without "volatile") and hoping that the compiler 
keeps the values in the registers in between (without reordering the 
statements).

Anyway, since I'll be away for most the rest of the week and we already have 
soft-freeze next week, I'd like to get this fixed for my pull request that I 
plan later for today or tomorrow, so I now went ahead and modified the code 
to look like this:

#define FbinOp(S, ASM) uint64_t S(uint64_t a, uint64_t b) \
{ \
     uint64_t res = 0; \
     asm ("llihf %[res],801\n" ASM \
          : [res]"=&r"(res) : [a]"r"(a), [b]"r"(b) : "cc"); \
     return res; \
}

/* AND WITH COMPLEMENT */
FbinOp(_ncrk,  ".insn rrf, 0xB9F50000, %[res], %[b], %[a], 0\n")
FbinOp(_ncgrk, ".insn rrf, 0xB9E50000, %[res], %[b], %[a], 0\n")

/* NAND */
FbinOp(_nnrk,  ".insn rrf, 0xB9740000, %[res], %[b], %[a], 0\n")
FbinOp(_nngrk, ".insn rrf, 0xB9640000, %[res], %[b], %[a], 0\n")

/* NOT XOR */
FbinOp(_nxrk,  ".insn rrf, 0xB9770000, %[res], %[b], %[a], 0\n")
FbinOp(_nxgrk, ".insn rrf, 0xB9670000, %[res], %[b], %[a], 0\n")

/* NOR */
FbinOp(_nork,  ".insn rrf, 0xB9760000, %[res], %[b], %[a], 0\n")
FbinOp(_nogrk, ".insn rrf, 0xB9660000, %[res], %[b], %[a], 0\n")

/* OR WITH COMPLEMENT */
FbinOp(_ocrk,  ".insn rrf, 0xB9750000, %[res], %[b], %[a], 0\n")
FbinOp(_ocgrk, ".insn rrf, 0xB9650000, %[res], %[b], %[a], 0\n")

Full patch can be seen here:

https://gitlab.com/thuth/qemu/-/commit/38af118ea2fef0c473

I hope that's ok for everybody?

  Thomas
David Hildenbrand Feb. 28, 2022, 10:39 a.m. UTC | #4
On 28.02.22 11:14, Thomas Huth wrote:
> On 24/02/2022 00.43, Richard Henderson wrote:
>> On 2/23/22 12:31, David Miller wrote:
>>> +#define F_EPI "stg %%r0, %[res] " : [res] "+m" (res) : : "r0", "r2", "r3"
>>> +
>>> +#define F_PRO    asm ( \
>>> +    "llihf %%r0,801\n" \
>>> +    "lg %%r2, %[a]\n"  \
>>> +    "lg %%r3, %[b] "   \
>>> +    : : [a] "m" (a),   \
>>> +        [b] "m" (b)    \
>>> +    : "r2", "r3")
>>> +
>>> +#define FbinOp(S, ASM) uint64_t S(uint64_t a, uint64_t b) \
>>> +{ uint64_t res = 0; F_PRO; ASM; return res; }
>>> +
>>> +/* AND WITH COMPLEMENT */
>>> +FbinOp(_ncrk,  asm("ncrk  %%r0, %%r3, %%r2\n" F_EPI))
>>> +FbinOp(_ncgrk, asm("ncgrk %%r0, %%r3, %%r2\n" F_EPI))
>>
>> Better written as
>>
>>    asm("ncrk %0, %3, %2" : "=&r"(res) : "r"(a), "r"(b) : "cc");
> 
> I agree with Richard, especially since it's kind of "dangerous" to chain 
> multiple asm() statements (without "volatile") and hoping that the compiler 
> keeps the values in the registers in between (without reordering the 
> statements).
> 
> Anyway, since I'll be away for most the rest of the week and we already have 
> soft-freeze next week, I'd like to get this fixed for my pull request that I 
> plan later for today or tomorrow, so I now went ahead and modified the code 
> to look like this:
> 
> #define FbinOp(S, ASM) uint64_t S(uint64_t a, uint64_t b) \
> { \
>      uint64_t res = 0; \
>      asm ("llihf %[res],801\n" ASM \
>           : [res]"=&r"(res) : [a]"r"(a), [b]"r"(b) : "cc"); \
>      return res; \
> }
> 
> /* AND WITH COMPLEMENT */
> FbinOp(_ncrk,  ".insn rrf, 0xB9F50000, %[res], %[b], %[a], 0\n")
> FbinOp(_ncgrk, ".insn rrf, 0xB9E50000, %[res], %[b], %[a], 0\n")
> 
> /* NAND */
> FbinOp(_nnrk,  ".insn rrf, 0xB9740000, %[res], %[b], %[a], 0\n")
> FbinOp(_nngrk, ".insn rrf, 0xB9640000, %[res], %[b], %[a], 0\n")
> 
> /* NOT XOR */
> FbinOp(_nxrk,  ".insn rrf, 0xB9770000, %[res], %[b], %[a], 0\n")
> FbinOp(_nxgrk, ".insn rrf, 0xB9670000, %[res], %[b], %[a], 0\n")
> 
> /* NOR */
> FbinOp(_nork,  ".insn rrf, 0xB9760000, %[res], %[b], %[a], 0\n")
> FbinOp(_nogrk, ".insn rrf, 0xB9660000, %[res], %[b], %[a], 0\n")
> 
> /* OR WITH COMPLEMENT */
> FbinOp(_ocrk,  ".insn rrf, 0xB9750000, %[res], %[b], %[a], 0\n")
> FbinOp(_ocgrk, ".insn rrf, 0xB9650000, %[res], %[b], %[a], 0\n")
> 
> Full patch can be seen here:
> 
> https://gitlab.com/thuth/qemu/-/commit/38af118ea2fef0c473
> 
> I hope that's ok for everybody?

Fine with me.
Richard Henderson Feb. 28, 2022, 5:59 p.m. UTC | #5
On 2/28/22 00:14, Thomas Huth wrote:
> Full patch can be seen here:
> 
> https://gitlab.com/thuth/qemu/-/commit/38af118ea2fef0c473


> static inline void mvcrl_8(const char *dst, const char *src)
> {
>     asm volatile (
>     "llill %%r0, 8\n"
>     ".insn sse, 0xE50A00000000, 0(%[dst]), 0(%[src])"
>     : : [dst] "d" (dst), [src] "d" (src)
>     : "memory");
> }

Need clobber of r0 here.

> #define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
> {                            \
>     uint64_t res = 0;        \
>     asm (                    \
>          "lg %%r2, %[a]\n"   \
>          "lg %%r3, %[b]\n"   \
>          "lg %%r0, %[c]\n"   \
>          "ltgr %%r0, %%r0\n" \
>          ASM                 \
>          "stg %%r0, %[res] " \
>          : [res] "=m" (res)  \
>          : [a] "m" (a),      \
>            [b] "m" (b),      \
>            [c] "m" (c)       \
>          : "r0", "r2",       \
>            "r3", "r4"        \
>     );                       \
>     return res;              \
> }
> 
> Fi3 (_selre,     ".insn rrf, 0xB9F00000, %%r0, %%r3, %%r2, 8\n")
> Fi3 (_selgrz,    ".insn rrf, 0xB9E30000, %%r0, %%r3, %%r2, 8\n")
> Fi3 (_selfhrnz,  ".insn rrf, 0xB9C00000, %%r0, %%r3, %%r2, 7\n")

This isn't actively broken, but could use the same treatment as NCRK et al:

#define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
{                            \
     uint64_t res;            \
     asm("ltgr %[c], %[c]\n\t" ASM
         : [res] "=&r" (res)
         : [a] "r" (a), [b] "r" (b), [c] "r" (c)
         : "cc");
     return res;
}

Fi3(_selre,   ".insn rrf, 0xB9F00000, %[res], %[a], %[b], 8")

etc.


r~
David Miller Feb. 28, 2022, 6:31 p.m. UTC | #6
Had it on my TODO list for this morning, thank you.

On Mon, Feb 28, 2022 at 12:59 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 2/28/22 00:14, Thomas Huth wrote:
> > Full patch can be seen here:
> >
> > https://gitlab.com/thuth/qemu/-/commit/38af118ea2fef0c473
>
>
> > static inline void mvcrl_8(const char *dst, const char *src)
> > {
> >     asm volatile (
> >     "llill %%r0, 8\n"
> >     ".insn sse, 0xE50A00000000, 0(%[dst]), 0(%[src])"
> >     : : [dst] "d" (dst), [src] "d" (src)
> >     : "memory");
> > }
>
> Need clobber of r0 here.
>
> > #define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
> > {                            \
> >     uint64_t res = 0;        \
> >     asm (                    \
> >          "lg %%r2, %[a]\n"   \
> >          "lg %%r3, %[b]\n"   \
> >          "lg %%r0, %[c]\n"   \
> >          "ltgr %%r0, %%r0\n" \
> >          ASM                 \
> >          "stg %%r0, %[res] " \
> >          : [res] "=m" (res)  \
> >          : [a] "m" (a),      \
> >            [b] "m" (b),      \
> >            [c] "m" (c)       \
> >          : "r0", "r2",       \
> >            "r3", "r4"        \
> >     );                       \
> >     return res;              \
> > }
> >
> > Fi3 (_selre,     ".insn rrf, 0xB9F00000, %%r0, %%r3, %%r2, 8\n")
> > Fi3 (_selgrz,    ".insn rrf, 0xB9E30000, %%r0, %%r3, %%r2, 8\n")
> > Fi3 (_selfhrnz,  ".insn rrf, 0xB9C00000, %%r0, %%r3, %%r2, 7\n")
>
> This isn't actively broken, but could use the same treatment as NCRK et al:
>
> #define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
> {                            \
>      uint64_t res;            \
>      asm("ltgr %[c], %[c]\n\t" ASM
>          : [res] "=&r" (res)
>          : [a] "r" (a), [b] "r" (b), [c] "r" (c)
>          : "cc");
>      return res;
> }
>
> Fi3(_selre,   ".insn rrf, 0xB9F00000, %[res], %[a], %[b], 8")
>
> etc.
>
>
> r~
>
Thomas Huth March 1, 2022, 10:24 a.m. UTC | #7
On 28/02/2022 19.31, David Miller wrote:
> Had it on my TODO list for this morning, thank you.

Thanks! Please send it as additional patch on top of my s390x-next, since I 
already sent a pull request for the other patches yesterday:

  https://gitlab.com/thuth/qemu/-/commits/s390x-next/

> On Mon, Feb 28, 2022 at 12:59 PM Richard Henderson 
> <richard.henderson@linaro.org <mailto:richard.henderson@linaro.org>> wrote:
> 
>     On 2/28/22 00:14, Thomas Huth wrote:
>      > Full patch can be seen here:
>      >
>      > https://gitlab.com/thuth/qemu/-/commit/38af118ea2fef0c473
>     <https://gitlab.com/thuth/qemu/-/commit/38af118ea2fef0c473>
> 
> 
>      > static inline void mvcrl_8(const char *dst, const char *src)
>      > {
>      >     asm volatile (
>      >     "llill %%r0, 8\n"
>      >     ".insn sse, 0xE50A00000000, 0(%[dst]), 0(%[src])"
>      >     : : [dst] "d" (dst), [src] "d" (src)
>      >     : "memory");
>      > }
> 
>     Need clobber of r0 here.

Right. This test fails with Clang, indeed, as I discovered today, since 
Clang uses r0 more often than GCC, as it seems. I've already sent some 
patches for some other tests today, so there'll be another s390x pull 
request next week for TCG tests fixups :-)

  Thomas


>      > #define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
>      > {                            \
>      >     uint64_t res = 0;        \
>      >     asm (                    \
>      >          "lg %%r2, %[a]\n"   \
>      >          "lg %%r3, %[b]\n"   \
>      >          "lg %%r0, %[c]\n"   \
>      >          "ltgr %%r0, %%r0\n" \
>      >          ASM                 \
>      >          "stg %%r0, %[res] " \
>      >          : [res] "=m" (res)  \
>      >          : [a] "m" (a),      \
>      >            [b] "m" (b),      \
>      >            [c] "m" (c)       \
>      >          : "r0", "r2",       \
>      >            "r3", "r4"        \
>      >     );                       \
>      >     return res;              \
>      > }
>      >
>      > Fi3 (_selre,     ".insn rrf, 0xB9F00000, %%r0, %%r3, %%r2, 8\n")
>      > Fi3 (_selgrz,    ".insn rrf, 0xB9E30000, %%r0, %%r3, %%r2, 8\n")
>      > Fi3 (_selfhrnz,  ".insn rrf, 0xB9C00000, %%r0, %%r3, %%r2, 7\n")
> 
>     This isn't actively broken, but could use the same treatment as NCRK et al:
> 
>     #define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
>     {                            \
>           uint64_t res;            \
>           asm("ltgr %[c], %[c]\n\t" ASM
>               : [res] "=&r" (res)
>               : [a] "r" (a), [b] "r" (b), [c] "r" (c)
>               : "cc");
>           return res;
>     }
> 
>     Fi3(_selre,   ".insn rrf, 0xB9F00000, %[res], %[a], %[b], 8")
> 
>     etc.
> 
> 
>     r~
>
David Miller March 1, 2022, 5:02 p.m. UTC | #8
>On 28/02/2022 19.31, David Miller wrote:
> > Had it on my TODO list for this morning, thank you.

> Thanks! Please send it as additional patch on top of my s390x-next, since
I
> already sent a pull request for the other patches yesterday:
>
>  https://gitlab.com/thuth/qemu/-/commits/s390x-next/

Partial misread yesterday,  I was on mobile and saw that you had modified
the patch to stage.

I will look at it now,  as soon as gitlab comes back up,  it's been
problematic lately.


- David Miller
diff mbox series

Patch

diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
index 1a7238b4eb..54e67446aa 100644
--- a/tests/tcg/s390x/Makefile.target
+++ b/tests/tcg/s390x/Makefile.target
@@ -1,12 +1,15 @@ 
 S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
 VPATH+=$(S390X_SRC)
-CFLAGS+=-march=zEC12 -m64
+CFLAGS+=-march=z15 -m64
 TESTS+=hello-s390x
 TESTS+=csst
 TESTS+=ipm
 TESTS+=exrl-trt
 TESTS+=exrl-trtr
 TESTS+=pack
+TESTS+=mie3-compl
+TESTS+=mie3-mvcrl
+TESTS+=mie3-sel
 TESTS+=mvo
 TESTS+=mvc
 TESTS+=shift
diff --git a/tests/tcg/s390x/mie3-compl.c b/tests/tcg/s390x/mie3-compl.c
new file mode 100644
index 0000000000..98281ee683
--- /dev/null
+++ b/tests/tcg/s390x/mie3-compl.c
@@ -0,0 +1,55 @@ 
+#include <stdint.h>
+
+
+#define F_EPI "stg %%r0, %[res] " : [res] "+m" (res) : : "r0", "r2", "r3"
+
+#define F_PRO    asm ( \
+    "llihf %%r0,801\n" \
+    "lg %%r2, %[a]\n"  \
+    "lg %%r3, %[b] "   \
+    : : [a] "m" (a),   \
+        [b] "m" (b)    \
+    : "r2", "r3")
+
+#define FbinOp(S, ASM) uint64_t S(uint64_t a, uint64_t b) \
+{ uint64_t res = 0; F_PRO; ASM; return res; }
+
+/* AND WITH COMPLEMENT */
+FbinOp(_ncrk,  asm("ncrk  %%r0, %%r3, %%r2\n" F_EPI))
+FbinOp(_ncgrk, asm("ncgrk %%r0, %%r3, %%r2\n" F_EPI))
+
+/* NAND */
+FbinOp(_nnrk,  asm("nnrk  %%r0, %%r3, %%r2\n" F_EPI))
+FbinOp(_nngrk, asm("nngrk %%r0, %%r3, %%r2\n" F_EPI))
+
+/* NOT XOR */
+FbinOp(_nxrk,  asm("nxrk  %%r0, %%r3, %%r2\n" F_EPI))
+FbinOp(_nxgrk, asm("nxgrk %%r0, %%r3, %%r2\n" F_EPI))
+
+/* NOR */
+FbinOp(_nork,  asm("nork  %%r0, %%r3, %%r2\n" F_EPI))
+FbinOp(_nogrk, asm("nogrk %%r0, %%r3, %%r2\n" F_EPI))
+
+/* OR WITH COMPLEMENT */
+FbinOp(_ocrk,  asm("ocrk  %%r0, %%r3, %%r2\n" F_EPI))
+FbinOp(_ocgrk, asm("ocgrk %%r0, %%r3, %%r2\n" F_EPI))
+
+
+int main(int argc, char *argv[])
+{
+    if (_ncrk(0xFF88, 0xAA11)  != 0x0000032100000011ull ||
+        _nnrk(0xFF88, 0xAA11)  != 0x00000321FFFF55FFull ||
+        _nork(0xFF88, 0xAA11)  != 0x00000321FFFF0066ull ||
+        _nxrk(0xFF88, 0xAA11)  != 0x00000321FFFFAA66ull ||
+        _ocrk(0xFF88, 0xAA11)  != 0x00000321FFFFAA77ull ||
+        _ncgrk(0xFF88, 0xAA11) != 0x0000000000000011ull ||
+        _nngrk(0xFF88, 0xAA11) != 0xFFFFFFFFFFFF55FFull ||
+        _nogrk(0xFF88, 0xAA11) != 0xFFFFFFFFFFFF0066ull ||
+        _nxgrk(0xFF88, 0xAA11) != 0xFFFFFFFFFFFFAA66ull ||
+        _ocgrk(0xFF88, 0xAA11) != 0xFFFFFFFFFFFFAA77ull)
+    {
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/s390x/mie3-mvcrl.c b/tests/tcg/s390x/mie3-mvcrl.c
new file mode 100644
index 0000000000..81cf3ad702
--- /dev/null
+++ b/tests/tcg/s390x/mie3-mvcrl.c
@@ -0,0 +1,31 @@ 
+#include <stdint.h>
+#include <string.h>
+
+
+static inline void mvcrl_8(const char *dst, const char *src)
+{
+    asm volatile (
+    "llill %%r0, 8\n"
+    "mvcrl 0(%[dst]), 0(%[src])\n"
+    : : [dst] "d" (dst), [src] "d" (src)
+    : "memory");
+}
+
+
+int main(int argc, char *argv[])
+{
+    const char *alpha = "abcdefghijklmnop";
+
+    /* array missing 'i' */
+    char tstr[17] = "abcdefghjklmnop\0" ;
+
+    /* mvcrl reference use: 'open a hole in an array' */
+    mvcrl_8(tstr + 9, tstr + 8);
+
+    /* place missing 'i' */
+    tstr[8] = 'i';
+
+    return strncmp(alpha, tstr, 16ul);
+}
+
+
diff --git a/tests/tcg/s390x/mie3-sel.c b/tests/tcg/s390x/mie3-sel.c
new file mode 100644
index 0000000000..2e99e00b47
--- /dev/null
+++ b/tests/tcg/s390x/mie3-sel.c
@@ -0,0 +1,42 @@ 
+#include <stdint.h>
+
+
+#define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
+{                       \
+uint64_t res = 0;       \
+asm (                   \
+    "lg %%r2, %[a]\n"   \
+    "lg %%r3, %[b]\n"   \
+    "lg %%r0, %[c]\n"   \
+    "ltgr %%r0, %%r0\n" \
+    ASM                 \
+    "stg %%r0, %[res] " \
+    : [res] "=m" (res)  \
+    : [a] "m" (a),      \
+      [b] "m" (b),      \
+      [c] "m" (c)       \
+    : "r0", "r2",       \
+      "r3", "r4"        \
+    );                  \
+    return res;         \
+}
+
+
+Fi3 (_selre,    "selre    %%r0, %%r3, %%r2\n")
+Fi3 (_selgrz,   "selgrz   %%r0, %%r3, %%r2\n")
+Fi3 (_selfhrnz, "selfhrnz %%r0, %%r3, %%r2\n")
+
+
+int main(int argc, char *argv[])
+{
+    uint64_t a = ~0, b = ~0, c = ~0;
+    a =    _selre(0x066600000066ull, 0x066600000006ull, a);
+    b =   _selgrz(0xF00D00000005ull, 0xF00D00000055ull, b);
+    c = _selfhrnz(0x043200000044ull, 0x065400000004ull, c);
+
+    return (int) (
+        (0xFFFFFFFF00000066ull != a) ||
+        (0x0000F00D00000005ull != b) ||
+        (0x00000654FFFFFFFFull != c) );
+}
+