Darwin: various fixes
[valgrind.git] / none / tests / amd64 / rdseed.c
blob784c4e96ea14e95e5015e8e7e7c7f4ee1b698030
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <assert.h>
5 #include "tests/malloc.h"
7 typedef unsigned char UChar;
8 typedef unsigned int UInt;
9 typedef unsigned long int UWord;
10 typedef unsigned long long int ULong;
12 // What can we actually test here? The instructions take no input and
13 // produce output which is by definition totally random. So apart from
14 // not simply failing insn decode, there's nothing much to test.
16 // Get 10 values of each size, and check that they are not all the same
17 // (otherwise something's obviously wrong). Now, statistically, it's
18 // highly unlikely that they are all the same. For 10 16 bit ints, the
19 // probability of them being all the same is (I'd guess) (2^-16) ^ (10-1),
20 // that is, 2^-144.
22 ULong do_rdseed64 ( void )
24 while (1) {
25 ULong res = 0;
26 ULong cflag = 0;
27 __asm__ __volatile__(
28 "movabsq $0x5555555555555555, %%r11 ; "
29 "movq $0, %%r12 ; "
30 "rdseed %%r11 ; "
31 "setc %%r12b ; "
32 "movq %%r11, %0 ; "
33 "movq %%r12, %1"
34 : "=r"(res), "=r"(cflag) : : "r11", "r12"
36 if (cflag == 1)
37 return res;
39 /*NOTREACHED*/
42 ULong do_rdseed32 ( void )
44 while (1) {
45 ULong res = 0;
46 ULong cflag = 0;
47 __asm__ __volatile__(
48 "movabsq $0x5555555555555555, %%r11 ; "
49 "movq $0, %%r12 ; "
50 "rdseed %%r11d ; "
51 "setc %%r12b ; "
52 "movq %%r11, %0 ; "
53 "movq %%r12, %1"
54 : "=r"(res), "=r"(cflag) : : "r11", "r12"
56 if (cflag == 1)
57 return res;
59 /*NOTREACHED*/
62 ULong do_rdseed16 ( void )
64 while (1) {
65 ULong res = 0;
66 ULong cflag = 0;
67 __asm__ __volatile__(
68 "movabsq $0x5555555555555555, %%r11 ; "
69 "movq $0, %%r12 ; "
70 "rdseed %%r11w ; "
71 "setc %%r12b ; "
72 "movq %%r11, %0 ; "
73 "movq %%r12, %1"
74 : "=r"(res), "=r"(cflag) : : "r11", "r12"
76 if (cflag == 1)
77 return res;
79 /*NOTREACHED*/
82 void do_test ( ULong(*fn)(void),
83 ULong mask
84 /* with 1s indicating the random bits in the result */ )
86 ULong arr[10];
87 for (UInt i = 0; i < 10; i++) {
88 arr[i] = fn();
91 // They really should all be different (to an extremely high probabilty.
92 // See comment above.
93 int allSame = 1/*true*/; // really, a Bool
94 for (UInt i = 1; i < 10; i++) {
95 if (arr[i] != arr[0]) {
96 allSame = 0/*false*/;
97 break;
100 assert(!allSame);
102 // The 0/32/48 leading bits of the result should have a particular value,
103 // depending on the insn. So print them, with the random part masked out.
104 for (UInt i = 0; i < 10; i++) {
105 printf("0x%016llx\n", arr[i] & ~mask);
107 printf("\n");
110 int main ( void )
112 do_test( do_rdseed64, 0xFFFFFFFFFFFFFFFFULL );
113 do_test( do_rdseed32, 0x00000000FFFFFFFFULL );
114 do_test( do_rdseed16, 0x000000000000FFFFULL );
115 return 0;