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