xref: /qemu/tests/tcg/s390x/mie3-mvcrl.c (revision bfde1be8)
1bfde1be8SIlya Leoshkevich #include <stdbool.h>
2e2c3fb06SDavid Miller #include <stdint.h>
3bfde1be8SIlya Leoshkevich #include <stdlib.h>
4e2c3fb06SDavid Miller #include <string.h>
5e2c3fb06SDavid Miller 
mvcrl(const char * dst,const char * src,size_t len)6bfde1be8SIlya Leoshkevich static void mvcrl(const char *dst, const char *src, size_t len)
7e2c3fb06SDavid Miller {
8bfde1be8SIlya Leoshkevich     register long r0 asm("r0") = len;
9bfde1be8SIlya Leoshkevich 
10e2c3fb06SDavid Miller     asm volatile (
11e2c3fb06SDavid Miller         ".insn sse, 0xE50A00000000, 0(%[dst]), 0(%[src])"
12bfde1be8SIlya Leoshkevich         : : [dst] "d" (dst), [src] "d" (src), "r" (r0)
13bfde1be8SIlya Leoshkevich         : "memory");
14e2c3fb06SDavid Miller }
15e2c3fb06SDavid Miller 
test(void)16bfde1be8SIlya Leoshkevich static bool test(void)
17e2c3fb06SDavid Miller {
18e2c3fb06SDavid Miller     const char *alpha = "abcdefghijklmnop";
19e2c3fb06SDavid Miller 
20e2c3fb06SDavid Miller     /* array missing 'i' */
21e2c3fb06SDavid Miller     char tstr[17] = "abcdefghjklmnop\0";
22e2c3fb06SDavid Miller 
23e2c3fb06SDavid Miller     /* mvcrl reference use: 'open a hole in an array' */
24bfde1be8SIlya Leoshkevich     mvcrl(tstr + 9, tstr + 8, 8);
25e2c3fb06SDavid Miller 
26e2c3fb06SDavid Miller     /* place missing 'i' */
27e2c3fb06SDavid Miller     tstr[8] = 'i';
28e2c3fb06SDavid Miller 
29bfde1be8SIlya Leoshkevich     return strncmp(alpha, tstr, 16ul) == 0;
30bfde1be8SIlya Leoshkevich }
31bfde1be8SIlya Leoshkevich 
test_bad_r0(void)32bfde1be8SIlya Leoshkevich static bool test_bad_r0(void)
33bfde1be8SIlya Leoshkevich {
34bfde1be8SIlya Leoshkevich     char src[256] = { 0 };
35bfde1be8SIlya Leoshkevich 
36bfde1be8SIlya Leoshkevich     /*
37bfde1be8SIlya Leoshkevich      * PoP says: Bits 32-55 of general register 0 should contain zeros;
38bfde1be8SIlya Leoshkevich      * otherwise, the program may not operate compatibly in the future.
39bfde1be8SIlya Leoshkevich      *
40bfde1be8SIlya Leoshkevich      * Try it anyway in order to check whether this would crash QEMU itself.
41bfde1be8SIlya Leoshkevich      */
42bfde1be8SIlya Leoshkevich     mvcrl(src, src, (size_t)-1);
43bfde1be8SIlya Leoshkevich 
44bfde1be8SIlya Leoshkevich     return true;
45bfde1be8SIlya Leoshkevich }
46bfde1be8SIlya Leoshkevich 
main(void)47bfde1be8SIlya Leoshkevich int main(void)
48bfde1be8SIlya Leoshkevich {
49bfde1be8SIlya Leoshkevich     bool ok = true;
50bfde1be8SIlya Leoshkevich 
51bfde1be8SIlya Leoshkevich     ok &= test();
52bfde1be8SIlya Leoshkevich     ok &= test_bad_r0();
53bfde1be8SIlya Leoshkevich 
54bfde1be8SIlya Leoshkevich     return ok ? EXIT_SUCCESS : EXIT_FAILURE;
55e2c3fb06SDavid Miller }
56