xref: /aosp_15_r20/external/mesa3d/src/nouveau/compiler/acorn/lib.rs (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 // Copyright © 2022 Collabora, Ltd.
2 // SPDX-License-Identifier: MIT
3 
4 // Generated by random.org
5 const INIT_DATA: [u16; 64] = [
6     8235, 45378, 61861, 23858, 42241, 27301, 23697, 15333, 52828, 39161, 46572,
7     7478, 11198, 4926, 21736, 23781, 37217, 20323, 32754, 61367, 12882, 35352,
8     29343, 26458, 62858, 44415, 35786, 58466, 45062, 30330, 30350, 35134,
9     28228, 36077, 26793, 27223, 52219, 52544, 3565, 56253, 40962, 40833, 35607,
10     46482, 64735, 31252, 44165, 40273, 46825, 15929, 27160, 1106, 59035, 48146,
11     47365, 19901, 37178, 35614, 29628, 23344, 11328, 60105, 28727, 344,
12 ];
13 
14 /// An implementation of the ACORN random number generator
15 ///
16 /// See also http://acorn.wikramaratna.org/concept.html
17 ///
18 /// This isn't cryptographically secure but it's easy and fast and good enough
19 /// for generating test data.  More importantly, we own the implementation so it
20 /// won't change with random library or compiler upgrades.
21 pub struct Acorn {
22     y_n: [u64; Self::K],
23 }
24 
25 impl Acorn {
26     const ORD: usize = 60;
27     const K: usize = 16;
28 
new() -> Self29     pub fn new() -> Self {
30         let mut y_0 = [0_u64; Self::K];
31         for m in 0..Self::K {
32             y_0[m] |= u64::from(INIT_DATA[m * 4 + 0]) << 0;
33             y_0[m] |= u64::from(INIT_DATA[m * 4 + 1]) << 16;
34             y_0[m] |= u64::from(INIT_DATA[m * 4 + 2]) << 32;
35             y_0[m] |= u64::from(INIT_DATA[m * 4 + 3]) << 48;
36             y_0[m] &= (1u64 << Self::ORD) - 1;
37         }
38         // For good randomness, the seed should be odd
39         assert!(y_0[0] % 2 == 1);
40         Acorn { y_n: y_0 }
41     }
42 
next_u60(&mut self) -> u6443     fn next_u60(&mut self) -> u64 {
44         // y_n[0] remains uncanged
45         for m in 1..Self::K {
46             // We go in increasing M so y_n[m] is y_(n-1)[m] when we read it but
47             // self.y_n[m - 1] is what it says it is
48             self.y_n[m] = (self.y_n[m] + self.y_n[m - 1]) % (1 << Self::ORD);
49         }
50         self.y_n[Self::K - 1]
51     }
52 
get_uint(&mut self, bits: usize) -> u6453     pub fn get_uint(&mut self, bits: usize) -> u64 {
54         if bits <= Self::ORD {
55             self.next_u60() >> (Self::ORD - bits)
56         } else {
57             let hi = self.next_u60() << (bits - Self::ORD);
58             hi | self.get_uint(bits - Self::ORD)
59         }
60     }
61 
get_bool(&mut self) -> bool62     pub fn get_bool(&mut self) -> bool {
63         self.get_uint(1) != 0
64     }
65 
get_u8(&mut self) -> u866     pub fn get_u8(&mut self) -> u8 {
67         self.get_uint(8) as u8
68     }
69 
get_u16(&mut self) -> u1670     pub fn get_u16(&mut self) -> u16 {
71         self.get_uint(16) as u16
72     }
73 
get_u32(&mut self) -> u3274     pub fn get_u32(&mut self) -> u32 {
75         self.get_uint(32) as u32
76     }
77 
get_u64(&mut self) -> u6478     pub fn get_u64(&mut self) -> u64 {
79         self.get_uint(64)
80     }
81 }
82