Replace rand48 with std::linear_congruential_engine in simulator (#110)
diff --git a/src/aarch64/logic-aarch64.cc b/src/aarch64/logic-aarch64.cc
index 4d50568..e1416ea 100644
--- a/src/aarch64/logic-aarch64.cc
+++ b/src/aarch64/logic-aarch64.cc
@@ -168,11 +168,12 @@
uint64_t Simulator::GenerateRandomTag(uint16_t exclude) {
- uint64_t rtag = nrand48(rand_state_) >> 28;
+ // Generate a 4 bit integer from a 48bit random number
+ uint64_t rtag = rand_gen_() >> 44;
VIXL_ASSERT(IsUint4(rtag));
if (exclude == 0) {
- exclude = nrand48(rand_state_) >> 27;
+ exclude = rand_gen_() >> 44;
}
// TODO: implement this to better match the specification, which calls for a
@@ -7487,7 +7488,7 @@
// Non-faulting loads are allowed to fail arbitrarily. To stress user
// code, fail a random element in roughly one in eight full-vector loads.
- uint32_t rnd = static_cast<uint32_t>(jrand48(rand_state_));
+ uint32_t rnd = static_cast<uint32_t>(rand_gen_());
int fake_fault_at_lane = rnd % (LaneCountFromFormat(vform) * 8);
for (int i = 0; i < LaneCountFromFormat(vform); i++) {
diff --git a/src/aarch64/simulator-aarch64.cc b/src/aarch64/simulator-aarch64.cc
index 83d1649..9f5c56d 100644
--- a/src/aarch64/simulator-aarch64.cc
+++ b/src/aarch64/simulator-aarch64.cc
@@ -594,9 +594,8 @@
guard_pages_ = false;
// Initialize the common state of RNDR and RNDRRS.
- uint16_t seed[3] = {11, 22, 33};
- VIXL_STATIC_ASSERT(sizeof(seed) == sizeof(rand_state_));
- memcpy(rand_state_, seed, sizeof(rand_state_));
+ uint64_t seed = (11 + (22 << 16) + (static_cast<uint64_t>(33) << 32));
+ rand_gen_.seed(seed);
// Initialize all bits of pseudo predicate register to true.
LogicPRegister ones(pregister_all_true_);
@@ -6947,8 +6946,8 @@
break;
case RNDR:
case RNDRRS: {
- uint64_t high = jrand48(rand_state_);
- uint64_t low = jrand48(rand_state_);
+ uint64_t high = rand_gen_();
+ uint64_t low = rand_gen_();
uint64_t rand_num = (high << 32) | (low & 0xffffffff);
WriteXRegister(instr->GetRt(), rand_num);
// Simulate successful random number generation.
diff --git a/src/aarch64/simulator-aarch64.h b/src/aarch64/simulator-aarch64.h
index 6e36246..0a8d2fe 100644
--- a/src/aarch64/simulator-aarch64.h
+++ b/src/aarch64/simulator-aarch64.h
@@ -29,6 +29,7 @@
#include <memory>
#include <mutex>
+#include <random>
#include <unordered_map>
#include <vector>
@@ -5431,11 +5432,15 @@
CPUFeaturesAuditor cpu_features_auditor_;
std::vector<CPUFeatures> saved_cpu_features_;
- // State for *rand48 functions, used to simulate randomness with repeatable
+ // linear_congruential_engine, used to simulate randomness with repeatable
// behaviour (so that tests are deterministic). This is used to simulate RNDR
// and RNDRRS, as well as to simulate a source of entropy for architecturally
// undefined behaviour.
- uint16_t rand_state_[3];
+ std::linear_congruential_engine<uint64_t,
+ 0x5DEECE66D,
+ 0xB,
+ static_cast<uint64_t>(1) << 48>
+ rand_gen_;
// A configurable size of SVE vector registers.
unsigned vector_length_;