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
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..d6b7b0933b
--- /dev/null
+++ b/tests/tcg/s390x/mie3-sel.c
@@ -0,0 +1,42 @@
+#include <stdint.h>
+
+
+#define F_EPI "stg %%r0, %[res] " : [res] "+m" (res) : : "r0", "r2", "r3"
+
+#define F_PRO asm ( \
+ "lg %%r2, %[a]\n" \
+ "lg %%r3, %[b]\n" \
+ "lg %%r0, %[c]\n" \
+ "ltgr %%r0, %%r0" \
+ : : [a] "m" (a), \
+ [b] "m" (b), \
+ [c] "m" (c) \
+ : "r0", "r2", "r3", "r4")
+
+
+
+#define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
+{ uint64_t res = 0; F_PRO ; ASM ; return res; }
+
+
+Fi3 (_selre, asm("selre %%r0, %%r3, %%r2\n" F_EPI))
+Fi3 (_selgrz, asm("selgrz %%r0, %%r3, %%r2\n" F_EPI))
+Fi3 (_selfhrnz, asm("selfhrnz %%r0, %%r3, %%r2\n" F_EPI))
+
+
+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(0x004400000044ull, 0x000400000004ull, c);
+
+ if ((0xFFFFFFFF00000066ull != a) ||
+ (0x0000F00D00000005ull != b) ||
+ (0x00000004FFFFFFFFull != c))
+ {
+ return 1;
+ }
+ return 0;
+}
+
--
2.32.0
On 2/17/22 13:17, David Miller wrote:
> +#define F_PRO asm ( \
> + "lg %%r2, %[a]\n" \
> + "lg %%r3, %[b]\n" \
> + "lg %%r0, %[c]\n" \
> + "ltgr %%r0, %%r0" \
> + : : [a] "m" (a), \
> + [b] "m" (b), \
> + [c] "m" (c) \
> + : "r0", "r2", "r3", "r4")
> +
> +
> +
> +#define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
> +{ uint64_t res = 0; F_PRO ; ASM ; return res; }
> +
> +
> +Fi3 (_selre, asm("selre %%r0, %%r3, %%r2\n" F_EPI))
> +Fi3 (_selgrz, asm("selgrz %%r0, %%r3, %%r2\n" F_EPI))
> +Fi3 (_selfhrnz, asm("selfhrnz %%r0, %%r3, %%r2\n" F_EPI))
You can't split these two asm, lest the ltgr and sel not be adjacent, and the flags not
having the correct value when we arrive at the sel.
No test for popcnt, seeing as there's a bug in m3?
r~
> No test for popcnt, seeing as there's a bug in m3?
Originally popcnt was not in the task list, it was added later.
> You can't split these two asm, lest the ltgr and sel not be adjacent, and the flags not
> having the correct value when we arrive at the sel.
This was tested, both gcc and clang assemble multiple 'asm' statements
into a single block as long as there are no C statements between.
I'm happy to change it.
On Wed, Feb 23, 2022 at 2:45 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 2/17/22 13:17, David Miller wrote:
> > +#define F_PRO asm ( \
> > + "lg %%r2, %[a]\n" \
> > + "lg %%r3, %[b]\n" \
> > + "lg %%r0, %[c]\n" \
> > + "ltgr %%r0, %%r0" \
> > + : : [a] "m" (a), \
> > + [b] "m" (b), \
> > + [c] "m" (c) \
> > + : "r0", "r2", "r3", "r4")
> > +
> > +
> > +
> > +#define Fi3(S, ASM) uint64_t S(uint64_t a, uint64_t b, uint64_t c) \
> > +{ uint64_t res = 0; F_PRO ; ASM ; return res; }
> > +
> > +
> > +Fi3 (_selre, asm("selre %%r0, %%r3, %%r2\n" F_EPI))
> > +Fi3 (_selgrz, asm("selgrz %%r0, %%r3, %%r2\n" F_EPI))
> > +Fi3 (_selfhrnz, asm("selfhrnz %%r0, %%r3, %%r2\n" F_EPI))
>
> You can't split these two asm, lest the ltgr and sel not be adjacent, and the flags not
> having the correct value when we arrive at the sel.
>
> No test for popcnt, seeing as there's a bug in m3?
>
>
> r~
© 2016 - 2026 Red Hat, Inc.