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