1 #include <stdbool.h> 2 #include <stdint.h> 3 #include <stdlib.h> 4 #include <string.h> 5 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 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 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 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