summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaymaekers Luca <luca@spacehb.net>2025-11-12 18:52:38 +0100
committerRaymaekers Luca <luca@spacehb.net>2025-11-12 18:52:38 +0100
commitd4f6774c172ac1e7c193fc4e89230c873d179c2b (patch)
tree049b855ac7b68482dc9e1e35b339f5b4d18d675b
parente20d69ffb1f5676bb7960ac4d71c1013e4582149 (diff)
checkpoint
-rwxr-xr-xbuild/haversine_generatorbin0 -> 24224 bytes
-rwxr-xr-xbuild/sim86bin66448 -> 62024 bytes
-rwxr-xr-xbuild/sim86_metabin181968 -> 177488 bytes
-rw-r--r--computerenhance.md161
-rw-r--r--project.4coder4
-rwxr-xr-xsrc/haversine/build.sh36
-rw-r--r--src/haversine/haversine_generator.cpp138
-rw-r--r--src/haversine/haversine_random.h107
l---------src/haversine/libs/lr/lr.h1
l---------src/haversine/libs/lr/lr_macros.h1
l---------src/haversine/libs/lr/lr_platform.h1
l---------src/haversine/libs/lr/lr_types.h1
-rw-r--r--src/haversine/libs/pcg/pcg-advance-128.c64
-rw-r--r--src/haversine/libs/pcg/pcg-advance-16.c62
-rw-r--r--src/haversine/libs/pcg/pcg-advance-32.c62
-rw-r--r--src/haversine/libs/pcg/pcg-advance-64.c62
-rw-r--r--src/haversine/libs/pcg/pcg-advance-8.c62
-rw-r--r--src/haversine/libs/pcg/pcg-global-32.c56
-rw-r--r--src/haversine/libs/pcg/pcg-global-64.c59
-rw-r--r--src/haversine/libs/pcg/pcg-output-128.c64
-rw-r--r--src/haversine/libs/pcg/pcg-output-16.c60
-rw-r--r--src/haversine/libs/pcg/pcg-output-32.c62
-rw-r--r--src/haversine/libs/pcg/pcg-output-64.c70
-rw-r--r--src/haversine/libs/pcg/pcg-output-8.c60
-rw-r--r--src/haversine/libs/pcg/pcg-rngs-128.c337
-rw-r--r--src/haversine/libs/pcg/pcg-rngs-16.c183
-rw-r--r--src/haversine/libs/pcg/pcg-rngs-32.c187
-rw-r--r--src/haversine/libs/pcg/pcg-rngs-64.c232
-rw-r--r--src/haversine/libs/pcg/pcg-rngs-8.c128
-rw-r--r--src/haversine/libs/pcg/pcg.c16
-rw-r--r--src/haversine/libs/pcg/pcg_variants.h2213
-rw-r--r--src/haversine/listing_065.cpp39
-rw-r--r--src/sim86/bin/generated/generated.cpp0
-rwxr-xr-xsrc/sim86/bin/tmux.sh (renamed from src/tmux.sh)0
-rwxr-xr-xsrc/sim86/build.sh (renamed from src/build.sh)13
-rw-r--r--src/sim86/clocks_table.inl (renamed from src/clocks_table.inl)0
-rw-r--r--src/sim86/generated/generated.cpp (renamed from src/generated/generated.cpp)0
-rw-r--r--src/sim86/libs/metadesk/md.c (renamed from src/libs/metadesk/md.c)0
-rw-r--r--src/sim86/libs/metadesk/md.h (renamed from src/libs/metadesk/md.h)0
-rw-r--r--src/sim86/libs/metadesk/md_stb_sprintf.h (renamed from src/libs/metadesk/md_stb_sprintf.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86.h (renamed from src/libs/reference_decoder/sim86.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_decode.cpp (renamed from src/libs/reference_decoder/sim86_decode.cpp)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_decode.h (renamed from src/libs/reference_decoder/sim86_decode.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_instruction.cpp (renamed from src/libs/reference_decoder/sim86_instruction.cpp)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_instruction.h (renamed from src/libs/reference_decoder/sim86_instruction.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_instruction_table.cpp (renamed from src/libs/reference_decoder/sim86_instruction_table.cpp)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_instruction_table.h (renamed from src/libs/reference_decoder/sim86_instruction_table.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_instruction_table.inl (renamed from src/libs/reference_decoder/sim86_instruction_table.inl)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_lib.cpp (renamed from src/libs/reference_decoder/sim86_lib.cpp)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_memory.cpp (renamed from src/libs/reference_decoder/sim86_memory.cpp)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_memory.h (renamed from src/libs/reference_decoder/sim86_memory.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_text_table.cpp (renamed from src/libs/reference_decoder/sim86_text_table.cpp)0
-rw-r--r--src/sim86/sim86.cpp (renamed from src/sim86.cpp)0
-rw-r--r--src/sim86/sim86.h (renamed from src/sim86.h)0
-rw-r--r--src/sim86/sim86.mdesk (renamed from src/sim86.mdesk)0
-rw-r--r--src/sim86/sim86_meta.c (renamed from src/sim86_meta.c)1
-rw-r--r--src/sim86/sim86_shared.h (renamed from src/sim86_shared.h)0
57 files changed, 4450 insertions, 92 deletions
diff --git a/build/haversine_generator b/build/haversine_generator
new file mode 100755
index 0000000..d8f36ac
--- /dev/null
+++ b/build/haversine_generator
Binary files differ
diff --git a/build/sim86 b/build/sim86
index 3777fdb..20ae3aa 100755
--- a/build/sim86
+++ b/build/sim86
Binary files differ
diff --git a/build/sim86_meta b/build/sim86_meta
index d01767d..070aa32 100755
--- a/build/sim86_meta
+++ b/build/sim86_meta
Binary files differ
diff --git a/computerenhance.md b/computerenhance.md
index 8eaa819..ed7c73a 100644
--- a/computerenhance.md
+++ b/computerenhance.md
@@ -2,11 +2,11 @@
# 2. [Performance-Aware Programming Series Begins February 1st](https://www.computerenhance.com/p/performance-aware-programming-series)
# 3. [Welcome to the Performance-Aware Programming Series!](https://www.computerenhance.com/p/welcome-to-the-performance-aware)
-# Optimization
+## Optimization
optimization = Maximizing performance of software on hardware.
- used to be complicated (years ago) = traditional
-# Problem
+## Problem
People think performance is:
- not worth it
- too hard
@@ -14,19 +14,19 @@ People think performance is:
True for traditional optimzation.
- actually results in extremely slow programming.
-# What
+## What
Only learning about how performance works is enough.
- What decisions affect performance?
-# Affecting performance
+## Affecting performance
1. amount of instructions: reduce number of instructions
2. speed of instructions: make CPU process instructions faster
-# Decline
+## Decline
- CPUs became more complicated.
- unaware of the resulting instructions of higher-level languages
-# Solution
+## Solution
- Keep result of instructions in mind, not code
- Learn what the maximum speed of something should be
@@ -58,7 +58,7 @@ Python had 180x instructions and was 130x slower.
# 5. [Instructions Per Clock](https://www.computerenhance.com/p/instructions-per-clock)
*speed of instructions*
-# IPC/ILP
+## IPC/ILP
- **Instructions Per Clock**
- instructions per clock cycle
- specific to one instruction
@@ -101,7 +101,7 @@ CPUs are designed for more computation so boosting IPL in a loop that
does not do a lot of computation will bring less benefits.
# 6. [Monday Q&A (2023-02-05)](https://www.computerenhance.com/p/monday-q-and-a-2023-02-05)
-# JIT
+## JIT
- compile code "upfront"
- have extra information
- knows context in which it is compiled
@@ -114,7 +114,7 @@ Waste:
JAVA may have waste as well, but the bytecode was designed as
"something that could be executed faster".
-# No test harness yet.
+## No test harness yet.
Read Time Stamp Counter (rtsc):
- allows to read chip-wide counter
- dangerous against turbo boosts
@@ -125,7 +125,7 @@ We have to move by stage so we can focus on everything step by step.
The reality is that there already is a well grown userbase.
- who cares! We will make it performant.
-# Micro-OPs go to execution ports
+## Micro-OPs go to execution ports
- each port can do X operations
- different instructions can be contenders for a port
- looking at the port usage will show for unrolling a loop
@@ -133,23 +133,16 @@ The reality is that there already is a well grown userbase.
- sometimes there is a limit on how instructions can be sent
-# Unrolling
+## Unrolling
- most compilers can unroll the loop for you
- clang can screw this up
-# Why *minimum* adds per cycle
+## Why *minimum* adds per cycle
- thinking about "opportunities"
-- mean, median will not find out the average
-- + fastest you can show what you are pointing to
- - mean + fastest
-- analyzing the behaviour of the hardware
-- *stars need to align*
-- when using fastest you converge to the analysis
-- *educational*
-- mean and medium or for "mixtures"
- - used together for fastest when optimizing
-
+- mean & median will not converge to the actual cycle count the CPU can do them.
+- *fastest* will get to the actual adds/cycle the CPU can do
+- median & mean gives you typical behavior
Assembly -> Micro-OPs -> CPU
@@ -167,19 +160,19 @@ input[2]
input[3]
input += 4
```
-# Three-based addition:
+## Three-based addition:
- common technique to work out a dependency chain
# 7. [Single Instruction, Multiple Data](https://www.computerenhance.com/p/single-instruction-multiple-data)
*Amount of instructions*
-# SIMD
+## SIMD
- *Single Instruction, Multiple Data*
- One instruction can act on multiple data
- SSE in x64
- can be used together with IPC
-# PADDD
+## PADDD
- Packed ADD D-word
- "Wide" instruction
- can use multiple accumulators
@@ -187,7 +180,7 @@ input += 4
- e.g. extracting dependency chains
- ![vector example](img/vector_paddd.png)
-# Subsets
+## Subsets
|---------+-----------+-----------|
| subset | bit width | supported |
|---------+-----------+-----------|
@@ -200,7 +193,7 @@ input += 4
- Making smaller instructions can use bit width.
- Typical that you cannot get full x improvements (x2, x4, ...)
-# Difficulty
+## Difficulty
- SIMD does not care about how data is organized
- easy with adds
@@ -217,49 +210,49 @@ Because there are many dependencies on loads it is very important.
- *Cache*!
- Way faster than main memory (DIMMs)
-# Cache
+## Cache
- Register file :
- produce values really quickly and feed them to registers
- maximum speed
- few hundred values at most
# 9. [Monday Q&A #2 (2023-02-12)](https://www.computerenhance.com/p/monday-q-and-a-2-2023-02-12)
-# Why would the register renamer not solve the dependencies?
+## Why would the register renamer not solve the dependencies?
- Because there is a "literal" dependency
- *register renamer* fixes "fake" dependencies
-# Python over cpp
+## Python over cpp
- cpp is quite bad, but allows control over the output
- python is good for sketching and libraries
-# Hardware jungle
+## Hardware jungle
- Coding towards the minimum specification
- generally true
- Design hotspots for platforms (e.g. Xbox, PS5, ...)
- vectorizable, enough in loop for IPC
- focus on things that work on all CPUs
-# More complicated loops
+## More complicated loops
- For now it's demonstrations
- everything can be optimized (:
-# How can you tell if you are wasteful?
+## How can you tell if you are wasteful?
- profiling
- "how much time spending in this loop?"
-# Lanes and bottlenecks during design
+## Lanes and bottlenecks during design
- how many of "those" can I do per second
- which is the limiting factor = bottleneck
-# Asymptotic performance
+## Asymptotic performance
- also important
-# Power usage reduction
+## Power usage reduction
- in general achieved through reduced instructions
- same thing the *majority* of the time
- reducing waste
-# Signed and unsigned integers
+## Signed and unsigned integers
- are the same because of *two's complement*
- except for:
- mul/div/gt
@@ -267,14 +260,14 @@ Because there are many dependencies on loads it is very important.
- name of instructions tells the compiler which instruction to use
- unsigned/signed is not needed and could be replaced by a different operator
-# Can compilers SIMD?
+## Can compilers SIMD?
- gcc and clang are agressive at vectorization
- generally better than nothing
-# SIMD: AMD vs Intel
+## SIMD: AMD vs Intel
- no. (long-term)
-# Are unused registers ignored?
+## Are unused registers ignored?
- modern chips (CPU/GPU) have two types of registers:
- Scalar
- slot
@@ -287,7 +280,7 @@ Because there are many dependencies on loads it is very important.
- tip: *SIMD if you can*
-# CPU vs GPU
+## CPU vs GPU
- GPUs are the same for parallellism but with different trade-offs
- 1024bit Vectors / Wide execution units
- CPU
@@ -306,33 +299,33 @@ Because there are many dependencies on loads it is very important.
- Switch can be difficult (talkin between both)
- unless APU
-# Non-deterministic architectures
+## Non-deterministic architectures
- You cannot depend on timings
- Potentially depends on the room's temperature
- Things run until they cannot melt
-# Arm
+## Arm
- everything transfers
- Instructions name change
-# SIMD without SIMD
+## SIMD without SIMD
- leave one bit for overflow
- SIMD registers handle overflows and carrying
-# Slowdown when 256/512 registers
+## Slowdown when 256/512 registers
- Most machines downclocks when using AVX
-# Hardware Jungle: SIMD edition
+## Hardware Jungle: SIMD edition
- 'cpu_id' tells what instructions sets the CPU supports
- set function pointers accordingly
- SHIM?
-# Micro-OP debugging
+## Micro-OP debugging
- assembly instructions are a layer of debugging on top of micro-OPs
- You cannot micro-op debug
-# Out-of-order CPUs
+## Out-of-order CPUs
- only if no one can tell the order was violated
- inside a window
- limited:
@@ -341,7 +334,7 @@ Because there are many dependencies on loads it is very important.
- rolling window
- waiting for instructions to be done
-# SIMD dataset requirements
+## SIMD dataset requirements
- "Shot"
- "Tail"
- You can padd you inputs
@@ -353,22 +346,22 @@ Because there are many dependencies on loads it is very important.
- Vector: VLen (Vector Length) says how much elements
- Scaler loop in worst case scenario
-# Cost of SIMD
+## Cost of SIMD
- 128 can always be used
- clock penalty goes away over time
- more latent
-# Latency vs Pipelining
+## Latency vs Pipelining
- Latency can be beaten by pipelining
- if the instructions are independent then the latency does not matter
-# Instructions Limits
+## Instructions Limits
- there is a limit on the number of micro-ops a cycle
- 5 micro-ops cannot be adds
- load tides up the execution port
- Registers are next to the lanes
-# Cache control
+## Cache control
- responsive, guesses
- "hints"
- prefetch instruction :: tries to get the memory in cache
@@ -380,13 +373,13 @@ Because there are many dependencies on loads it is very important.
- only matters when you have data you *do* want to cache
-# Data going around cache
+## Data going around cache
- bandwith is way bigger than the amount that needs to be passed through
- bandwith becomes narrower
- [cache_wideness][img/cache_wideness.png]
- the place having the data decides the bandwith
-# Prefetches
+## Prefetches
- hardware and software
- hardware ::
- looks at the pattern of pages
@@ -394,16 +387,16 @@ Because there are many dependencies on loads it is very important.
- eliminates latency
- throughput stays the same (cache bandwith)
-# Other programs
+## Other programs
- processor does not care about *what* it caches
- you lose depending on the core
- programms waking up takes up cache
- speed decrease is not in ^2 but size of bytes per cycle
-# Cache runtime
+## Cache runtime
- The slower the routine, the less the cache is important
-# Cache lines
+## Cache lines
- every 64 bytes
- being memory aligned penalties :: (not very high)
- 4096B (page boundaries)
@@ -413,17 +406,17 @@ Because there are many dependencies on loads it is very important.
- best to use all the cache lines (all 64 bytes)
- via data structures
-# Checking the cache
+## Checking the cache
- checking and getting happens in one instruction
-# Cache fights
+## Cache fights
- in multithreaded beware of shared caching
- pulling in the cache can evict the current data
-# L1 cache supremacy
+## L1 cache supremacy
- constrained by distance
-# Instructions in cache
+## Instructions in cache
- Front end ::
- ICache
- Back end ::
@@ -432,11 +425,11 @@ Because there are many dependencies on loads it is very important.
- Unpredicted instructions can slow down the program
- In L2/L3 cache instructions take space.
-# Performance for different sizes
+## Performance for different sizes
- smaller sizes are more likely to be cached
- if the cache is *primed* then yes
-# Cache behaviour
+## Cache behaviour
- branch predictor :: which way
- sophisticated
- hardware prefetcher :: which memory is going to be touched
@@ -444,15 +437,15 @@ Because there are many dependencies on loads it is very important.
- not smart
- "warmed up"
-# Persistent cache
+## Persistent cache
- OS wipes out with new memory map
-# Ask for cache
+## Ask for cache
- Evict train
- evict, ask L2, evict, ask L3, evict ask memory, fill evicts
- DMA (Direct Memory Acces)
-# Inclusive vs Exclusive Caches
+## Inclusive vs Exclusive Caches
- exclusive cache ::
- data is not in L2
- only when evicted from L1
@@ -463,20 +456,20 @@ Because there are many dependencies on loads it is very important.
# 10. [Multithreading](https://www.computerenhance.com/p/multithreading)
*Increasing speed of instructions*
-# Multithreading
+## Multithreading
- Core :: different computers
- physical
- Threads :: interface to access cores through the OS
- OS
-# Speeding up
+## Speeding up
- not x2 x4, actually account cache for speed up
- more SIMD registers, instructions cache, ...
- shared caches add up
- memory bandwidth can be bottleneck
- sometimes does not add up
-# Forcing out of memory
+## Forcing out of memory
- bandwith does not increase a lot when using main memory
- depending on the chip
- L3 cache and main memory are shared (not big speed ups)
@@ -484,11 +477,11 @@ Because there are many dependencies on loads it is very important.
# 11. [Python Revisited](https://www.computerenhance.com/p/python-revisited)
Assembly is what determines the speed.
-# Python
+## Python
- doing every sum in python is slow
- numpy is faster when you have supplied the array with a type
# 12. [Monday Q&A #3 (2023-02-20)](https://www.computerenhance.com/p/monday-q-and-a-3-2023-02-20)
-# Hyperthreading & Branch prediction
+## Hyperthreading & Branch prediction
- hyperthreads ::
- [[./img/hyperthreading.png][hyperthreading]]
- polling for more than one instructions
@@ -508,26 +501,26 @@ Assembly is what determines the speed.
- IPC: more execution ports filled
-# Multithreaded
+## Multithreaded
- code so that threads do not talk to each other
- communication is a mistake
- sync the code
-# Max multiplier mulitthreading
+## Max multiplier mulitthreading
- fetching memory is slower than computation
- look at all-core-bandwith
- total bandwith to all cores
- divided by cores = max memory per cycle
-# Logical processors vs Cores
+## Logical processors vs Cores
- Cores = computers
- Logical processors
- OS / threads / instruction streams
-# thread count > L1 cache
+## thread count > L1 cache
- oversubscription ::
- when the program asks for more threads than available
- lot of eviction
@@ -537,11 +530,11 @@ Assembly is what determines the speed.
- OS tries to run thread as long as possible
-# Green thread / fibers
+## Green thread / fibers
- software control swapping of the OS
-# Multithreadeding with disks
+## Multithreadeding with disks
- micromanagement
- when CPU has to decrypt
- depends on how disk works
@@ -549,7 +542,7 @@ Assembly is what determines the speed.
- threads can make non blocking code
-# How to get memory bandwidth
+## How to get memory bandwidth
- https://github.com/cmuratori/blandwidth
# 13. [The Haversine Distance Problem](https://www.computerenhance.com/p/the-haversine-distance-problem)
@@ -565,20 +558,20 @@ Assembly is what determines the speed.
The 8086 instruction set architecture is easier.
- Better for understanding concepts.
-# Register
+## Register
- place to store information
- 16 bits on the 8086
-# Operations
+## Operations
1. load memory
- copy into register
2. compute
3. write to memory
-# Instruction Decode
+## Instruction Decode
Turning the instruction stream into hardware operations.
-# Instructions
+## Instructions
- mov ::
- move, but actually a /copy/
- are assembled into binary that the /Instruction Decoder/ can use to
@@ -641,7 +634,7 @@ Special case when MOD is 00 and R/M is 110 -> 16 bit displacement.
Immediately (available) value.
-# Assignment
+## Assignment
Also implement memory to register.
- going to have to read the displacement bits (DISP)
diff --git a/project.4coder b/project.4coder
index 24c2c82..ba9d137 100644
--- a/project.4coder
+++ b/project.4coder
@@ -1,5 +1,5 @@
version(2);
-project_name = "sim8086";
+project_name = "Computer Enhance";
patterns = {
"*.c",
"*.mdesk",
@@ -17,7 +17,7 @@ blacklist_patterns = {
paths =
{
{ .path = ".", .recursive = false, .relative = true, },
- { .path = "src", .recursive = true , .relative = true, },
+ { .path = "src/haversine", .recursive = true , .relative = true, },
};
load_paths = {
diff --git a/src/haversine/build.sh b/src/haversine/build.sh
new file mode 100755
index 0000000..38170c0
--- /dev/null
+++ b/src/haversine/build.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+cd "$(dirname "$(readlink -f "$0")")"
+
+Build="../../build"
+mkdir -p "$Build"
+mkdir -p generated
+
+Compiler="clang"
+
+CompilerFlags="
+-g
+-fdiagnostics-absolute-paths
+-nostdinc++
+"
+
+WarningFlags="
+-Wall
+-Wextra
+-Wno-unused-label
+-Wno-unused-variable
+-Wno-unused-function
+-Wno-unused-value
+-Wno-unused-but-set-variable
+-Wno-missing-field-initializers
+-Wno-write-strings
+-Wno-unused-parameter
+"
+
+LinkerFlags="-lm"
+
+printf '[debug mode]\n'
+printf '[%s build]\n' "$Compiler"
+$Compiler $CompilerFlags $WarningFlags $LinkerFlags \
+ -o "$Build"/haversine_generator \
+ haversine_generator.cpp \ No newline at end of file
diff --git a/src/haversine/haversine_generator.cpp b/src/haversine/haversine_generator.cpp
new file mode 100644
index 0000000..c3f7561
--- /dev/null
+++ b/src/haversine/haversine_generator.cpp
@@ -0,0 +1,138 @@
+#include "libs/lr/lr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#define MemoryCopy memcpy
+
+#include "listing_065.cpp"
+
+#include "haversine_random.h"
+
+enum generation_method : u32
+{
+ Method_Uniform,
+ Method_Cluster
+};
+
+int main(int ArgsCount, char *Args[], char *Env[])
+{
+ // 1. haversine_generator [uniform/cluster] [random seed] [number of pairs to generate]
+
+ if(ArgsCount >= 4)
+ {
+ u32 Method = 0;
+ u64 RandomSeed = 0;;
+ u64 PairsCount = 0;
+ b32 Error = false;
+
+ if(!strcmp(Args[1], "uniform"))
+ {
+ Method = Method_Uniform;
+ }
+ else if(!strcmp(Args[1], "cluster"))
+ {
+ Method = Method_Cluster;
+ }
+ else
+ {
+ Error = true;
+ }
+
+ RandomSeed = atoll(Args[2]);
+
+ if(RandomSeed == 0)
+ {
+ if(Args[2][0] == '0')
+ {
+ RandomSeed = 0;
+ }
+ else
+ {
+ Error = true;
+ }
+ }
+
+ PairsCount = atoll(Args[3]);
+ if(PairsCount == 0)
+ {
+ Error = true;
+ }
+
+ if(!Error)
+ {
+ printf("Method: %s\n"
+ "Random seed: %lu\n"
+ "Pairs count: %lu\n"
+ , Args[1], RandomSeed, PairsCount);
+
+ // Generate pairs in the following format.
+ //
+ // {
+ // "pairs":
+ // [
+ // { "x0": ..., "y0": ..., "x1": ..., "y1": ... },
+ // { "x0": ..., "y0": ..., "x1": ..., "y1": ... }
+ // ]
+ // }
+ //
+
+ FILE *Out = fopen("out.json", "wb");
+ char *JsonHeader =
+ "{\n"
+ " \"pairs\":\n"
+ " [\n";
+ char *JsonFooter =
+ " ]\n"
+ "}\n";
+
+ fprintf(Out, "%s", JsonHeader);
+
+ pcg64_random_t RNG = {};
+ pcg64_srandom_r(&RNG, RandomSeed, RandomSeed);
+
+ f64 AverageSum = 0;
+ f64 TotalSum = 0;
+ for(u64 PairsIndex = 0;
+ PairsIndex < PairsCount;
+ PairsIndex++)
+ {
+ b32 LastPair = false;
+
+ f64 X0 = RandomBetween(&RNG, -180.0, 180.0);
+ f64 Y0 = RandomBetween(&RNG, -360.0, 360.0);
+ f64 X1 = RandomBetween(&RNG, -180.0, 180.0);
+ f64 Y1 = RandomBetween(&RNG, -360.0, 360.0);
+
+ f64 Sum = ReferenceHaversine(X0, Y0, X1, Y1, 6372.8);
+ TotalSum += Sum;
+
+ // NOTE(luca): A double's mantissa is 52 bits. 2^52 - 1 is 4503599627370495 which has
+ // 16 digits.
+ fprintf(Out,
+ " { \"x0\": %.15f, \"y0\": %.15f, \"x1\": %.15f, \"y1\": %.15f }\n",
+ X0, Y0, X1, Y1);
+
+ }
+ AverageSum = TotalSum / (f64)PairsCount;
+
+ fprintf(Out, "%s", JsonFooter);
+
+ printf("Average sum: %f\n", AverageSum);
+ }
+ else
+ {
+ printf("Usage: %s [uniform/cluster] [random seed] [number of pairs to generate]\n",
+ Args[0]);
+ }
+ }
+ else
+ {
+ printf("Usage: %s [uniform/cluster] [random seed] [number of pairs to generate]\n",
+ Args[0]);
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/src/haversine/haversine_random.h b/src/haversine/haversine_random.h
new file mode 100644
index 0000000..b7c545e
--- /dev/null
+++ b/src/haversine/haversine_random.h
@@ -0,0 +1,107 @@
+
+#include <math.h>
+
+#include "libs/pcg/pcg.c"
+
+#define CountLeadingZeroes64(Value) __builtin_clzll(Value)
+
+u64
+RandomU64(pcg64_random_t *RNG)
+{
+ u64 Result = pcg64_random_r(RNG);
+ return Result;
+}
+
+//~ Random 64 bit float
+
+// From: https://mumble.net/~campbell/tmp/random_real.c
+/*
+ * Copyright (c) 2014, Taylor R Campbell
+*
+* Verbatim copying and distribution of this entire article are
+* permitted worldwide, without royalty, in any medium, provided
+* this notice, and the copyright notice, are preserved.
+*
+*/
+
+/*
+ * random_real: Generate a stream of bits uniformly at random and
+ * interpret it as the fractional part of the binary expansion of a
+ * number in [0, 1], 0.00001010011111010100...; then round it.
+ */
+f64
+RandomF64(pcg64_random_t *RNG)
+{
+ s32 Exponent = -64;
+ u64 Significand;
+ umm Shift;
+
+ /*
+ * Read zeros into the exponent until we hit a one; the rest
+ * will go into the significand.
+ */
+ while((Significand = RandomU64(RNG)) == 0)
+ {
+ Exponent -= 64;
+ /*
+ * If the exponent falls below -1074 = emin + 1 - p,
+ * the exponent of the smallest subnormal, we are
+ * guaranteed the result will be rounded to zero. This
+ * case is so unlikely it will happen in realistic
+ * terms only if RandomU64 is broken.
+ */
+ if ((Exponent < -1074))
+ return 0;
+ }
+
+ /*
+ * There is a 1 somewhere in significand, not necessarily in
+ * the most significant position. If there are leading zeros,
+ * shift them into the exponent and refill the less-significant
+ * bits of the significand. Can't predict one way or another
+ * whether there are leading zeros: there's a fifty-fifty
+ * chance, if RandomU64() is uniformly distributed.
+ */
+ Shift = CountLeadingZeroes64(Significand);
+ if (Shift != 0) {
+ Exponent -= Shift;
+ Significand <<= Shift;
+ Significand |= (RandomU64(RNG) >> (64 - Shift));
+ }
+
+ /*
+ * Set the sticky bit, since there is almost surely another 1
+ * in the bit stream. Otherwise, we might round what looks
+ * like a tie to even when, almost surely, were we to look
+ * further in the bit stream, there would be a 1 breaking the
+ * tie.
+ */
+ Significand |= 1;
+
+ /*
+ * Finally, convert to f64 (rounding) and scale by
+ * 2^exponent.
+ */
+ return ldexp((f64)Significand, Exponent);
+}
+
+f64
+RandomUnilateral(pcg64_random_t *RNG)
+{
+ return RandomF64(RNG);
+}
+
+f64
+RandomBilateral(pcg64_random_t *RNG)
+{
+ f64 Result = 2.0*RandomUnilateral(RNG) - 1.0;
+ return Result;
+}
+
+f64
+RandomBetween(pcg64_random_t *RNG, f64 Min, f64 Max)
+{
+ f64 Range = Max - Min;
+ f64 Result = Min + RandomUnilateral(RNG)*Range;
+ return Result;
+} \ No newline at end of file
diff --git a/src/haversine/libs/lr/lr.h b/src/haversine/libs/lr/lr.h
new file mode 120000
index 0000000..49fb375
--- /dev/null
+++ b/src/haversine/libs/lr/lr.h
@@ -0,0 +1 @@
+/home/aluc/proj/lr/lr.h \ No newline at end of file
diff --git a/src/haversine/libs/lr/lr_macros.h b/src/haversine/libs/lr/lr_macros.h
new file mode 120000
index 0000000..530249a
--- /dev/null
+++ b/src/haversine/libs/lr/lr_macros.h
@@ -0,0 +1 @@
+/home/aluc/proj/lr/lr_macros.h \ No newline at end of file
diff --git a/src/haversine/libs/lr/lr_platform.h b/src/haversine/libs/lr/lr_platform.h
new file mode 120000
index 0000000..e387ee2
--- /dev/null
+++ b/src/haversine/libs/lr/lr_platform.h
@@ -0,0 +1 @@
+/home/aluc/proj/lr/lr_platform.h \ No newline at end of file
diff --git a/src/haversine/libs/lr/lr_types.h b/src/haversine/libs/lr/lr_types.h
new file mode 120000
index 0000000..6d2fa08
--- /dev/null
+++ b/src/haversine/libs/lr/lr_types.h
@@ -0,0 +1 @@
+/home/aluc/proj/lr/lr_types.h \ No newline at end of file
diff --git a/src/haversine/libs/pcg/pcg-advance-128.c b/src/haversine/libs/pcg/pcg-advance-128.c
new file mode 100644
index 0000000..be72009
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-advance-128.c
@@ -0,0 +1,64 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Repetative C code is derived using C preprocessor metaprogramming
+ * techniques.
+ */
+
+#include "pcg_variants.h"
+
+/* Multi-step advance functions (jump-ahead, jump-back)
+ *
+ * The method used here is based on Brown, "Random Number Generation
+ * with Arbitrary Stride,", Transactions of the American Nuclear
+ * Society (Nov. 1994). The algorithm is very similar to fast
+ * exponentiation.
+ *
+ * Even though delta is an unsigned integer, we can pass a
+ * signed integer to go backwards, it just goes "the long way round".
+ */
+
+#if PCG_HAS_128BIT_OPS
+pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, pcg128_t cur_mult,
+ pcg128_t cur_plus)
+{
+ pcg128_t acc_mult = 1u;
+ pcg128_t acc_plus = 0u;
+ while (delta > 0) {
+ if (delta & 1) {
+ acc_mult *= cur_mult;
+ acc_plus = acc_plus * cur_mult + cur_plus;
+ }
+ cur_plus = (cur_mult + 1) * cur_plus;
+ cur_mult *= cur_mult;
+ delta /= 2;
+ }
+ return acc_mult * state + acc_plus;
+}
+#endif
+
diff --git a/src/haversine/libs/pcg/pcg-advance-16.c b/src/haversine/libs/pcg/pcg-advance-16.c
new file mode 100644
index 0000000..11461d9
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-advance-16.c
@@ -0,0 +1,62 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Repetative C code is derived using C preprocessor metaprogramming
+ * techniques.
+ */
+
+#include "pcg_variants.h"
+
+/* Multi-step advance functions (jump-ahead, jump-back)
+ *
+ * The method used here is based on Brown, "Random Number Generation
+ * with Arbitrary Stride,", Transactions of the American Nuclear
+ * Society (Nov. 1994). The algorithm is very similar to fast
+ * exponentiation.
+ *
+ * Even though delta is an unsigned integer, we can pass a
+ * signed integer to go backwards, it just goes "the long way round".
+ */
+
+uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta, uint16_t cur_mult,
+ uint16_t cur_plus)
+{
+ uint16_t acc_mult = 1u;
+ uint16_t acc_plus = 0u;
+ while (delta > 0) {
+ if (delta & 1) {
+ acc_mult *= cur_mult;
+ acc_plus = acc_plus * cur_mult + cur_plus;
+ }
+ cur_plus = (cur_mult + 1) * cur_plus;
+ cur_mult *= cur_mult;
+ delta /= 2;
+ }
+ return acc_mult * state + acc_plus;
+}
+
diff --git a/src/haversine/libs/pcg/pcg-advance-32.c b/src/haversine/libs/pcg/pcg-advance-32.c
new file mode 100644
index 0000000..76f35fc
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-advance-32.c
@@ -0,0 +1,62 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Repetative C code is derived using C preprocessor metaprogramming
+ * techniques.
+ */
+
+#include "pcg_variants.h"
+
+/* Multi-step advance functions (jump-ahead, jump-back)
+ *
+ * The method used here is based on Brown, "Random Number Generation
+ * with Arbitrary Stride,", Transactions of the American Nuclear
+ * Society (Nov. 1994). The algorithm is very similar to fast
+ * exponentiation.
+ *
+ * Even though delta is an unsigned integer, we can pass a
+ * signed integer to go backwards, it just goes "the long way round".
+ */
+
+uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta, uint32_t cur_mult,
+ uint32_t cur_plus)
+{
+ uint32_t acc_mult = 1u;
+ uint32_t acc_plus = 0u;
+ while (delta > 0) {
+ if (delta & 1) {
+ acc_mult *= cur_mult;
+ acc_plus = acc_plus * cur_mult + cur_plus;
+ }
+ cur_plus = (cur_mult + 1) * cur_plus;
+ cur_mult *= cur_mult;
+ delta /= 2;
+ }
+ return acc_mult * state + acc_plus;
+}
+
diff --git a/src/haversine/libs/pcg/pcg-advance-64.c b/src/haversine/libs/pcg/pcg-advance-64.c
new file mode 100644
index 0000000..8210e75
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-advance-64.c
@@ -0,0 +1,62 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Repetative C code is derived using C preprocessor metaprogramming
+ * techniques.
+ */
+
+#include "pcg_variants.h"
+
+/* Multi-step advance functions (jump-ahead, jump-back)
+ *
+ * The method used here is based on Brown, "Random Number Generation
+ * with Arbitrary Stride,", Transactions of the American Nuclear
+ * Society (Nov. 1994). The algorithm is very similar to fast
+ * exponentiation.
+ *
+ * Even though delta is an unsigned integer, we can pass a
+ * signed integer to go backwards, it just goes "the long way round".
+ */
+
+uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, uint64_t cur_mult,
+ uint64_t cur_plus)
+{
+ uint64_t acc_mult = 1u;
+ uint64_t acc_plus = 0u;
+ while (delta > 0) {
+ if (delta & 1) {
+ acc_mult *= cur_mult;
+ acc_plus = acc_plus * cur_mult + cur_plus;
+ }
+ cur_plus = (cur_mult + 1) * cur_plus;
+ cur_mult *= cur_mult;
+ delta /= 2;
+ }
+ return acc_mult * state + acc_plus;
+}
+
diff --git a/src/haversine/libs/pcg/pcg-advance-8.c b/src/haversine/libs/pcg/pcg-advance-8.c
new file mode 100644
index 0000000..8280958
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-advance-8.c
@@ -0,0 +1,62 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Repetative C code is derived using C preprocessor metaprogramming
+ * techniques.
+ */
+
+#include "pcg_variants.h"
+
+/* Multi-step advance functions (jump-ahead, jump-back)
+ *
+ * The method used here is based on Brown, "Random Number Generation
+ * with Arbitrary Stride,", Transactions of the American Nuclear
+ * Society (Nov. 1994). The algorithm is very similar to fast
+ * exponentiation.
+ *
+ * Even though delta is an unsigned integer, we can pass a
+ * signed integer to go backwards, it just goes "the long way round".
+ */
+
+uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult,
+ uint8_t cur_plus)
+{
+ uint8_t acc_mult = 1u;
+ uint8_t acc_plus = 0u;
+ while (delta > 0) {
+ if (delta & 1) {
+ acc_mult *= cur_mult;
+ acc_plus = acc_plus * cur_mult + cur_plus;
+ }
+ cur_plus = (cur_mult + 1) * cur_plus;
+ cur_mult *= cur_mult;
+ delta /= 2;
+ }
+ return acc_mult * state + acc_plus;
+}
+
diff --git a/src/haversine/libs/pcg/pcg-global-32.c b/src/haversine/libs/pcg/pcg-global-32.c
new file mode 100644
index 0000000..8c18e48
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-global-32.c
@@ -0,0 +1,56 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+static pcg32_random_t pcg32_global = PCG32_INITIALIZER;
+
+uint32_t pcg32_random()
+{
+ return pcg32_random_r(&pcg32_global);
+}
+
+uint32_t pcg32_boundedrand(uint32_t bound)
+{
+ return pcg32_boundedrand_r(&pcg32_global, bound);
+}
+
+void pcg32_srandom(uint64_t seed, uint64_t seq)
+{
+ pcg32_srandom_r(&pcg32_global, seed, seq);
+}
+
+void pcg32_advance(uint64_t delta)
+{
+ return pcg32_advance_r(&pcg32_global, delta);
+}
+
diff --git a/src/haversine/libs/pcg/pcg-global-64.c b/src/haversine/libs/pcg/pcg-global-64.c
new file mode 100644
index 0000000..26aa677
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-global-64.c
@@ -0,0 +1,59 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+#if PCG_HAS_128BIT_OPS
+
+static pcg64_random_t pcg64_global = PCG64_INITIALIZER;
+
+uint64_t pcg64_random()
+{
+ return pcg64_random_r(&pcg64_global);
+}
+
+uint64_t pcg64_boundedrand(uint64_t bound)
+{
+ return pcg64_boundedrand_r(&pcg64_global, bound);
+}
+
+void pcg64_srandom(pcg128_t seed, pcg128_t seq)
+{
+ pcg64_srandom_r(&pcg64_global, seed, seq);
+}
+
+void pcg64_advance(pcg128_t delta)
+{
+ pcg64_advance_r(&pcg64_global, delta);
+}
+
+#endif
diff --git a/src/haversine/libs/pcg/pcg-output-128.c b/src/haversine/libs/pcg/pcg-output-128.c
new file mode 100644
index 0000000..cb2142e
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-output-128.c
@@ -0,0 +1,64 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/*
+ * Rotate helper functions.
+ */
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot);
+#endif
+
+/*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+// XSH RS
+
+// XSH RR
+
+// RXS M XS
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state);
+#endif
+
+// XSL RR (only defined for >= 64 bits)
+
+// XSL RR RR (only defined for >= 64 bits)
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state);
+#endif
+
diff --git a/src/haversine/libs/pcg/pcg-output-16.c b/src/haversine/libs/pcg/pcg-output-16.c
new file mode 100644
index 0000000..c593f67
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-output-16.c
@@ -0,0 +1,60 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/*
+ * Rotate helper functions.
+ */
+
+extern inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot);
+
+/*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+// XSH RS
+
+extern inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state);
+
+// XSH RR
+
+extern inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state);
+
+// RXS M XS
+
+extern inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state);
+
+// XSL RR (only defined for >= 64 bits)
+
+// XSL RR RR (only defined for >= 64 bits)
+
diff --git a/src/haversine/libs/pcg/pcg-output-32.c b/src/haversine/libs/pcg/pcg-output-32.c
new file mode 100644
index 0000000..e291c36
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-output-32.c
@@ -0,0 +1,62 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/*
+ * Rotate helper functions.
+ */
+
+extern inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot);
+
+/*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+// XSH RS
+
+extern inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state);
+
+// XSH RR
+
+extern inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state);
+
+// RXS M XS
+
+extern inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state);
+
+// XSL RR (only defined for >= 64 bits)
+
+extern inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state);
+
+// XSL RR RR (only defined for >= 64 bits)
+
diff --git a/src/haversine/libs/pcg/pcg-output-64.c b/src/haversine/libs/pcg/pcg-output-64.c
new file mode 100644
index 0000000..8c6b7e4
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-output-64.c
@@ -0,0 +1,70 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/*
+ * Rotate helper functions.
+ */
+
+extern inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot);
+
+/*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+// XSH RS
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state);
+#endif
+
+// XSH RR
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state);
+#endif
+
+// RXS M XS
+
+extern inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state);
+
+// XSL RR (only defined for >= 64 bits)
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state);
+#endif
+
+// XSL RR RR (only defined for >= 64 bits)
+
+extern inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state);
+
diff --git a/src/haversine/libs/pcg/pcg-output-8.c b/src/haversine/libs/pcg/pcg-output-8.c
new file mode 100644
index 0000000..83fe449
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-output-8.c
@@ -0,0 +1,60 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/*
+ * Rotate helper functions.
+ */
+
+extern inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot);
+
+/*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+// XSH RS
+
+extern inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state);
+
+// XSH RR
+
+extern inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state);
+
+// RXS M XS
+
+extern inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state);
+
+// XSL RR (only defined for >= 64 bits)
+
+// XSL RR RR (only defined for >= 64 bits)
+
diff --git a/src/haversine/libs/pcg/pcg-rngs-128.c b/src/haversine/libs/pcg/pcg-rngs-128.c
new file mode 100644
index 0000000..8023589
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-rngs-128.c
@@ -0,0 +1,337 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_oneseq_128_step_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_oneseq_128_advance_r(struct pcg_state_128* rng,
+ pcg128_t delta);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_mcg_128_step_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_mcg_128_advance_r(struct pcg_state_128* rng,
+ pcg128_t delta);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_unique_128_step_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_unique_128_advance_r(struct pcg_state_128* rng,
+ pcg128_t delta);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128* rng,
+ pcg128_t delta);
+#endif
+
+/* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_oneseq_128_srandom_r(struct pcg_state_128* rng,
+ pcg128_t initstate);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_mcg_128_srandom_r(struct pcg_state_128* rng,
+ pcg128_t initstate);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_unique_128_srandom_r(struct pcg_state_128* rng,
+ pcg128_t initstate);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128* rng,
+ pcg128_t initstate,
+ pcg128_t initseq);
+#endif
+
+/* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+/* Generation functions for XSH RS */
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, uint64_t bound);
+#endif
+
+/* Generation functions for XSH RR */
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, uint64_t bound);
+#endif
+
+/* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128* rng,
+ pcg128_t bound);
+#endif
+
+/* Generation functions for XSL RR (only defined for "large" types) */
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, uint64_t bound);
+#endif
+
+/* Generation functions for XSL RR RR (only defined for "large" types) */
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128* rng,
+ pcg128_t bound);
+#endif
+
diff --git a/src/haversine/libs/pcg/pcg-rngs-16.c b/src/haversine/libs/pcg/pcg-rngs-16.c
new file mode 100644
index 0000000..6d4e9b6
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-rngs-16.c
@@ -0,0 +1,183 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+extern inline void pcg_oneseq_16_step_r(struct pcg_state_16* rng);
+
+extern inline void pcg_oneseq_16_advance_r(struct pcg_state_16* rng,
+ uint16_t delta);
+
+extern inline void pcg_mcg_16_step_r(struct pcg_state_16* rng);
+
+extern inline void pcg_mcg_16_advance_r(struct pcg_state_16* rng,
+ uint16_t delta);
+
+extern inline void pcg_unique_16_step_r(struct pcg_state_16* rng);
+
+extern inline void pcg_unique_16_advance_r(struct pcg_state_16* rng,
+ uint16_t delta);
+
+extern inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16* rng);
+
+extern inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16* rng,
+ uint16_t delta);
+
+/* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+extern inline void pcg_oneseq_16_srandom_r(struct pcg_state_16* rng,
+ uint16_t initstate);
+
+extern inline void pcg_mcg_16_srandom_r(struct pcg_state_16* rng,
+ uint16_t initstate);
+
+extern inline void pcg_unique_16_srandom_r(struct pcg_state_16* rng,
+ uint16_t initstate);
+
+extern inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16* rng,
+ uint16_t initstate,
+ uint16_t initseq);
+
+/* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+/* Generation functions for XSH RS */
+
+extern inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+extern inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+extern inline uint8_t
+pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16* rng);
+
+extern inline uint8_t
+pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint8_t bound);
+
+extern inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+/* Generation functions for XSH RR */
+
+extern inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+extern inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+extern inline uint8_t
+pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16* rng);
+
+extern inline uint8_t
+pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint8_t bound);
+
+extern inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+/* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+extern inline uint16_t
+pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng);
+
+extern inline uint16_t
+pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,
+ uint16_t bound);
+
+extern inline uint16_t
+pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng);
+
+extern inline uint16_t
+pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,
+ uint16_t bound);
+
+extern inline uint16_t
+pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16* rng);
+
+extern inline uint16_t
+pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint16_t bound);
+
+/* Generation functions for XSL RR (only defined for "large" types) */
+
+/* Generation functions for XSL RR RR (only defined for "large" types) */
+
diff --git a/src/haversine/libs/pcg/pcg-rngs-32.c b/src/haversine/libs/pcg/pcg-rngs-32.c
new file mode 100644
index 0000000..1c8da7e
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-rngs-32.c
@@ -0,0 +1,187 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+extern inline void pcg_oneseq_32_step_r(struct pcg_state_32* rng);
+
+extern inline void pcg_oneseq_32_advance_r(struct pcg_state_32* rng,
+ uint32_t delta);
+
+extern inline void pcg_mcg_32_step_r(struct pcg_state_32* rng);
+
+extern inline void pcg_mcg_32_advance_r(struct pcg_state_32* rng,
+ uint32_t delta);
+
+extern inline void pcg_unique_32_step_r(struct pcg_state_32* rng);
+
+extern inline void pcg_unique_32_advance_r(struct pcg_state_32* rng,
+ uint32_t delta);
+
+extern inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32* rng);
+
+extern inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32* rng,
+ uint32_t delta);
+
+/* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+extern inline void pcg_oneseq_32_srandom_r(struct pcg_state_32* rng,
+ uint32_t initstate);
+
+extern inline void pcg_mcg_32_srandom_r(struct pcg_state_32* rng,
+ uint32_t initstate);
+
+extern inline void pcg_unique_32_srandom_r(struct pcg_state_32* rng,
+ uint32_t initstate);
+
+extern inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32* rng,
+ uint32_t initstate,
+ uint32_t initseq);
+
+/* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+/* Generation functions for XSH RS */
+
+extern inline uint16_t
+pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+extern inline uint16_t
+pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+extern inline uint16_t
+pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32* rng);
+
+extern inline uint16_t
+pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint16_t bound);
+
+extern inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+/* Generation functions for XSH RR */
+
+extern inline uint16_t
+pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+extern inline uint16_t
+pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+extern inline uint16_t
+pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32* rng);
+
+extern inline uint16_t
+pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint16_t bound);
+
+extern inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+/* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+extern inline uint32_t
+pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng);
+
+extern inline uint32_t
+pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,
+ uint32_t bound);
+
+extern inline uint32_t
+pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng);
+
+extern inline uint32_t
+pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,
+ uint32_t bound);
+
+extern inline uint32_t
+pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32* rng);
+
+extern inline uint32_t
+pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint32_t bound);
+
+/* Generation functions for XSL RR (only defined for "large" types) */
+
+/* Generation functions for XSL RR RR (only defined for "large" types) */
+
diff --git a/src/haversine/libs/pcg/pcg-rngs-64.c b/src/haversine/libs/pcg/pcg-rngs-64.c
new file mode 100644
index 0000000..cc0ff2c
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-rngs-64.c
@@ -0,0 +1,232 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+extern inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng);
+
+extern inline void pcg_oneseq_64_advance_r(struct pcg_state_64* rng,
+ uint64_t delta);
+
+extern inline void pcg_mcg_64_step_r(struct pcg_state_64* rng);
+
+extern inline void pcg_mcg_64_advance_r(struct pcg_state_64* rng,
+ uint64_t delta);
+
+extern inline void pcg_unique_64_step_r(struct pcg_state_64* rng);
+
+extern inline void pcg_unique_64_advance_r(struct pcg_state_64* rng,
+ uint64_t delta);
+
+extern inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64* rng);
+
+extern inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64* rng,
+ uint64_t delta);
+
+/* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+extern inline void pcg_oneseq_64_srandom_r(struct pcg_state_64* rng,
+ uint64_t initstate);
+
+extern inline void pcg_mcg_64_srandom_r(struct pcg_state_64* rng,
+ uint64_t initstate);
+
+extern inline void pcg_unique_64_srandom_r(struct pcg_state_64* rng,
+ uint64_t initstate);
+
+extern inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64* rng,
+ uint64_t initstate,
+ uint64_t initseq);
+
+/* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+/* Generation functions for XSH RS */
+
+extern inline uint32_t
+pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64* rng);
+
+extern inline uint32_t
+pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound);
+
+extern inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+/* Generation functions for XSH RR */
+
+extern inline uint32_t
+pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64* rng);
+
+extern inline uint32_t
+pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound);
+
+extern inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+/* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+extern inline uint64_t
+pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng);
+
+extern inline uint64_t
+pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound);
+
+extern inline uint64_t
+pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng);
+
+extern inline uint64_t
+pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound);
+
+extern inline uint64_t
+pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64* rng);
+
+extern inline uint64_t
+pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint64_t bound);
+
+/* Generation functions for XSL RR (only defined for "large" types) */
+
+extern inline uint32_t
+pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64* rng);
+
+extern inline uint32_t
+pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound);
+
+extern inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+/* Generation functions for XSL RR RR (only defined for "large" types) */
+
+extern inline uint64_t
+pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng);
+
+extern inline uint64_t
+pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound);
+
+extern inline uint64_t
+pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng);
+
+extern inline uint64_t
+pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound);
+
+extern inline uint64_t
+pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64* rng);
+
+extern inline uint64_t
+pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint64_t bound);
+
diff --git a/src/haversine/libs/pcg/pcg-rngs-8.c b/src/haversine/libs/pcg/pcg-rngs-8.c
new file mode 100644
index 0000000..8779aac
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-rngs-8.c
@@ -0,0 +1,128 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+extern inline void pcg_oneseq_8_step_r(struct pcg_state_8* rng);
+
+extern inline void pcg_oneseq_8_advance_r(struct pcg_state_8* rng,
+ uint8_t delta);
+
+extern inline void pcg_mcg_8_step_r(struct pcg_state_8* rng);
+
+extern inline void pcg_mcg_8_advance_r(struct pcg_state_8* rng, uint8_t delta);
+
+extern inline void pcg_unique_8_step_r(struct pcg_state_8* rng);
+
+extern inline void pcg_unique_8_advance_r(struct pcg_state_8* rng,
+ uint8_t delta);
+
+extern inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8* rng);
+
+extern inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8* rng,
+ uint8_t delta);
+
+/* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+extern inline void pcg_oneseq_8_srandom_r(struct pcg_state_8* rng,
+ uint8_t initstate);
+
+extern inline void pcg_mcg_8_srandom_r(struct pcg_state_8* rng,
+ uint8_t initstate);
+
+extern inline void pcg_unique_8_srandom_r(struct pcg_state_8* rng,
+ uint8_t initstate);
+
+extern inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8* rng,
+ uint8_t initstate, uint8_t initseq);
+
+/* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+/* Generation functions for XSH RS */
+
+/* Generation functions for XSH RR */
+
+/* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+extern inline uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8* rng);
+
+extern inline uint8_t
+pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8* rng, uint8_t bound);
+
+extern inline uint8_t
+pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8* rng);
+
+extern inline uint8_t
+pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8* rng,
+ uint8_t bound);
+
+/* Generation functions for XSL RR (only defined for "large" types) */
+
+/* Generation functions for XSL RR RR (only defined for "large" types) */
+
diff --git a/src/haversine/libs/pcg/pcg.c b/src/haversine/libs/pcg/pcg.c
new file mode 100644
index 0000000..cf29e6d
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg.c
@@ -0,0 +1,16 @@
+#include "pcg_variants.h"
+#include "pcg-advance-128.c"
+#include "pcg-advance-16.c"
+#include "pcg-advance-32.c"
+#include "pcg-advance-64.c"
+#include "pcg-advance-8.c"
+#include "pcg-output-128.c"
+#include "pcg-output-16.c"
+#include "pcg-output-32.c"
+#include "pcg-output-64.c"
+#include "pcg-output-8.c"
+#include "pcg-rngs-128.c"
+#include "pcg-rngs-16.c"
+#include "pcg-rngs-32.c"
+#include "pcg-rngs-64.c"
+#include "pcg-rngs-8.c"
diff --git a/src/haversine/libs/pcg/pcg_variants.h b/src/haversine/libs/pcg/pcg_variants.h
new file mode 100644
index 0000000..83edae8
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg_variants.h
@@ -0,0 +1,2213 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Much of the derivation was performed mechanically. In particular, the
+ * output functions were generated by compiling the C++ output functions
+ * into LLVM bitcode and then transforming that using the LLVM C backend
+ * (from https://github.com/draperlaboratory/llvm-cbe), and then
+ * postprocessing and hand editing the output.
+ *
+ * Much of the remaining code was generated by C-preprocessor metaprogramming.
+ */
+
+#ifndef PCG_VARIANTS_H_INCLUDED
+#define PCG_VARIANTS_H_INCLUDED 1
+
+#include <inttypes.h>
+
+#if __SIZEOF_INT128__
+typedef __uint128_t pcg128_t;
+#define PCG_128BIT_CONSTANT(high,low) \
+((((pcg128_t)high) << 64) + low)
+#define PCG_HAS_128BIT_OPS 1
+#else
+#error "non"
+#endif
+
+#if __GNUC_GNU_INLINE__ && !defined(__cplusplus)
+#error Nonstandard GNU inlining semanatics. Compile with -std=c99 or better.
+// We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE
+// but better to just reject ancient C code.
+#endif
+
+#if __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Rotate helper functions.
+ */
+
+ inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot)
+ {
+ /* Unfortunately, clang is kinda pathetic when it comes to properly
+ * recognizing idiomatic rotate code, so for clang we actually provide
+ * assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss.
+ */
+#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
+ asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+ return value;
+#else
+ return (value >> rot) | (value << ((- rot) & 7));
+#endif
+ }
+
+ inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot)
+ {
+#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
+ asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+ return value;
+#else
+ return (value >> rot) | (value << ((- rot) & 15));
+#endif
+ }
+
+ inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot)
+ {
+#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
+ asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+ return value;
+#else
+ return (value >> rot) | (value << ((- rot) & 31));
+#endif
+ }
+
+ inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot)
+ {
+#if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__
+ // For whatever reason, clang actually *does* generator rotq by
+ // itself, so we don't need this code.
+ asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+ return value;
+#else
+ return (value >> rot) | (value << ((- rot) & 63));
+#endif
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot)
+ {
+ return (value >> rot) | (value << ((- rot) & 127));
+ }
+#endif
+
+ /*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+ // XSH RS
+
+ inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state)
+ {
+ return (uint8_t)(((state >> 7u) ^ state) >> ((state >> 14u) + 3u));
+ }
+
+ inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state)
+ {
+ return (uint16_t)(((state >> 11u) ^ state) >> ((state >> 30u) + 11u));
+ }
+
+ inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state)
+ {
+
+ return (uint32_t)(((state >> 22u) ^ state) >> ((state >> 61u) + 22u));
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state)
+ {
+ return (uint64_t)(((state >> 43u) ^ state) >> ((state >> 124u) + 45u));
+ }
+#endif
+
+ // XSH RR
+
+ inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state)
+ {
+ return pcg_rotr_8(((state >> 5u) ^ state) >> 5u, state >> 13u);
+ }
+
+ inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state)
+ {
+ return pcg_rotr_16(((state >> 10u) ^ state) >> 12u, state >> 28u);
+ }
+
+ inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state)
+ {
+ return pcg_rotr_32(((state >> 18u) ^ state) >> 27u, state >> 59u);
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state)
+ {
+ return pcg_rotr_64(((state >> 29u) ^ state) >> 58u, state >> 122u);
+ }
+#endif
+
+ // RXS M XS
+
+ inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state)
+ {
+ uint8_t word = ((state >> ((state >> 6u) + 2u)) ^ state) * 217u;
+ return (word >> 6u) ^ word;
+ }
+
+ inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state)
+ {
+ uint16_t word = ((state >> ((state >> 13u) + 3u)) ^ state) * 62169u;
+ return (word >> 11u) ^ word;
+ }
+
+ inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state)
+ {
+ uint32_t word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
+ return (word >> 22u) ^ word;
+ }
+
+ inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state)
+ {
+ uint64_t word = ((state >> ((state >> 59u) + 5u)) ^ state)
+ * 12605985483714917081ull;
+ return (word >> 43u) ^ word;
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state)
+ {
+ pcg128_t word = ((state >> ((state >> 122u) + 6u)) ^ state)
+ * (PCG_128BIT_CONSTANT(17766728186571221404ULL,
+ 12605985483714917081ULL));
+ // 327738287884841127335028083622016905945
+ return (word >> 86u) ^ word;
+ }
+#endif
+
+ // XSL RR (only defined for >= 64 bits)
+
+ inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state)
+ {
+ return pcg_rotr_32(((uint32_t)(state >> 32u)) ^ (uint32_t)state,
+ state >> 59u);
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state)
+ {
+ return pcg_rotr_64(((uint64_t)(state >> 64u)) ^ (uint64_t)state,
+ state >> 122u);
+ }
+#endif
+
+ // XSL RR RR (only defined for >= 64 bits)
+
+ inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state)
+ {
+ uint32_t rot1 = (uint32_t)(state >> 59u);
+ uint32_t high = (uint32_t)(state >> 32u);
+ uint32_t low = (uint32_t)state;
+ uint32_t xored = high ^ low;
+ uint32_t newlow = pcg_rotr_32(xored, rot1);
+ uint32_t newhigh = pcg_rotr_32(high, newlow & 31u);
+ return (((uint64_t)newhigh) << 32u) | newlow;
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state)
+ {
+ uint32_t rot1 = (uint32_t)(state >> 122u);
+ uint64_t high = (uint64_t)(state >> 64u);
+ uint64_t low = (uint64_t)state;
+ uint64_t xored = high ^ low;
+ uint64_t newlow = pcg_rotr_64(xored, rot1);
+ uint64_t newhigh = pcg_rotr_64(high, newlow & 63u);
+ return (((pcg128_t)newhigh) << 64u) | newlow;
+ }
+#endif
+
+#define PCG_DEFAULT_MULTIPLIER_8 141U
+#define PCG_DEFAULT_MULTIPLIER_16 12829U
+#define PCG_DEFAULT_MULTIPLIER_32 747796405U
+#define PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL
+
+#define PCG_DEFAULT_INCREMENT_8 77U
+#define PCG_DEFAULT_INCREMENT_16 47989U
+#define PCG_DEFAULT_INCREMENT_32 2891336453U
+#define PCG_DEFAULT_INCREMENT_64 1442695040888963407ULL
+
+#if PCG_HAS_128BIT_OPS
+#define PCG_DEFAULT_MULTIPLIER_128 \
+PCG_128BIT_CONSTANT(2549297995355413924ULL,4865540595714422341ULL)
+#define PCG_DEFAULT_INCREMENT_128 \
+PCG_128BIT_CONSTANT(6364136223846793005ULL,1442695040888963407ULL)
+#endif
+
+ /*
+ * Static initialization constants (if you can't call srandom for some
+ * bizarre reason).
+ */
+
+#if PCG_HAS_128BIT_OPS
+#define PCG_STATE_ONESEQ_8_INITIALIZER { 0xd7U }
+#define PCG_STATE_ONESEQ_16_INITIALIZER { 0x20dfU }
+#define PCG_STATE_ONESEQ_32_INITIALIZER { 0x46b56677U }
+#define PCG_STATE_ONESEQ_64_INITIALIZER { 0x4d595df4d0f33173ULL }
+#define PCG_STATE_ONESEQ_128_INITIALIZER \
+{ PCG_128BIT_CONSTANT(0xb8dc10e158a92392ULL, 0x98046df007ec0a53ULL) }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+#define PCG_STATE_UNIQUE_8_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER
+#define PCG_STATE_UNIQUE_16_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER
+#define PCG_STATE_UNIQUE_32_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER
+#define PCG_STATE_UNIQUE_64_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER
+#define PCG_STATE_UNIQUE_128_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER
+#endif
+
+#if PCG_HAS_128BIT_OPS
+#define PCG_STATE_MCG_8_INITIALIZER { 0xe5U }
+#define PCG_STATE_MCG_16_INITIALIZER { 0xa5e5U }
+#define PCG_STATE_MCG_32_INITIALIZER { 0xd15ea5e5U }
+#define PCG_STATE_MCG_64_INITIALIZER { 0xcafef00dd15ea5e5ULL }
+#define PCG_STATE_MCG_128_INITIALIZER \
+{ PCG_128BIT_CONSTANT(0x0000000000000000ULL, 0xcafef00dd15ea5e5ULL) }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+#define PCG_STATE_SETSEQ_8_INITIALIZER { 0x9bU, 0xdbU }
+#define PCG_STATE_SETSEQ_16_INITIALIZER { 0xe39bU, 0x5bdbU }
+#define PCG_STATE_SETSEQ_32_INITIALIZER { 0xec02d89bU, 0x94b95bdbU }
+#define PCG_STATE_SETSEQ_64_INITIALIZER \
+{ 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL }
+#define PCG_STATE_SETSEQ_128_INITIALIZER \
+{ PCG_128BIT_CONSTANT(0x979c9a98d8462005ULL, 0x7d3e9cb6cfe0549bULL), \
+PCG_128BIT_CONSTANT(0x0000000000000001ULL, 0xda3e39cb94b95bdbULL) }
+#endif
+
+ /* Representations for the oneseq, mcg, and unique variants */
+
+ struct pcg_state_8 {
+ uint8_t state;
+ };
+
+ struct pcg_state_16 {
+ uint16_t state;
+ };
+
+ struct pcg_state_32 {
+ uint32_t state;
+ };
+
+ struct pcg_state_64 {
+ uint64_t state;
+ };
+
+#if PCG_HAS_128BIT_OPS
+ struct pcg_state_128 {
+ pcg128_t state;
+ };
+#endif
+
+ /* Representations setseq variants */
+
+ struct pcg_state_setseq_8 {
+ uint8_t state;
+ uint8_t inc;
+ };
+
+ struct pcg_state_setseq_16 {
+ uint16_t state;
+ uint16_t inc;
+ };
+
+ struct pcg_state_setseq_32 {
+ uint32_t state;
+ uint32_t inc;
+ };
+
+ struct pcg_state_setseq_64 {
+ uint64_t state;
+ uint64_t inc;
+ };
+
+#if PCG_HAS_128BIT_OPS
+ struct pcg_state_setseq_128 {
+ pcg128_t state;
+ pcg128_t inc;
+ };
+#endif
+
+ /* Multi-step advance functions (jump-ahead, jump-back) */
+
+ extern uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult,
+ uint8_t cur_plus);
+ extern uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta,
+ uint16_t cur_mult, uint16_t cur_plus);
+ extern uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta,
+ uint32_t cur_mult, uint32_t cur_plus);
+ extern uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta,
+ uint64_t cur_mult, uint64_t cur_plus);
+
+#if PCG_HAS_128BIT_OPS
+ extern pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta,
+ pcg128_t cur_mult, pcg128_t cur_plus);
+#endif
+
+ /* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+ inline void pcg_oneseq_8_step_r(struct pcg_state_8* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8
+ + PCG_DEFAULT_INCREMENT_8;
+ }
+
+ inline void pcg_oneseq_8_advance_r(struct pcg_state_8* rng, uint8_t delta)
+ {
+ rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,
+ PCG_DEFAULT_INCREMENT_8);
+ }
+
+ inline void pcg_mcg_8_step_r(struct pcg_state_8* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8;
+ }
+
+ inline void pcg_mcg_8_advance_r(struct pcg_state_8* rng, uint8_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 0u);
+ }
+
+ inline void pcg_unique_8_step_r(struct pcg_state_8* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8
+ + (uint8_t)(((intptr_t)rng) | 1u);
+ }
+
+ inline void pcg_unique_8_advance_r(struct pcg_state_8* rng, uint8_t delta)
+ {
+ rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,
+ (uint8_t)(((intptr_t)rng) | 1u));
+ }
+
+ inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + rng->inc;
+ }
+
+ inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8* rng,
+ uint8_t delta)
+ {
+ rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,
+ rng->inc);
+ }
+
+ inline void pcg_oneseq_16_step_r(struct pcg_state_16* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16
+ + PCG_DEFAULT_INCREMENT_16;
+ }
+
+ inline void pcg_oneseq_16_advance_r(struct pcg_state_16* rng, uint16_t delta)
+ {
+ rng->state = pcg_advance_lcg_16(
+ rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, PCG_DEFAULT_INCREMENT_16);
+ }
+
+ inline void pcg_mcg_16_step_r(struct pcg_state_16* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16;
+ }
+
+ inline void pcg_mcg_16_advance_r(struct pcg_state_16* rng, uint16_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, 0u);
+ }
+
+ inline void pcg_unique_16_step_r(struct pcg_state_16* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16
+ + (uint16_t)(((intptr_t)rng) | 1u);
+ }
+
+ inline void pcg_unique_16_advance_r(struct pcg_state_16* rng, uint16_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16,
+ (uint16_t)(((intptr_t)rng) | 1u));
+ }
+
+ inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 + rng->inc;
+ }
+
+ inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16* rng,
+ uint16_t delta)
+ {
+ rng->state = pcg_advance_lcg_16(rng->state, delta,
+ PCG_DEFAULT_MULTIPLIER_16, rng->inc);
+ }
+
+ inline void pcg_oneseq_32_step_r(struct pcg_state_32* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32
+ + PCG_DEFAULT_INCREMENT_32;
+ }
+
+ inline void pcg_oneseq_32_advance_r(struct pcg_state_32* rng, uint32_t delta)
+ {
+ rng->state = pcg_advance_lcg_32(
+ rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, PCG_DEFAULT_INCREMENT_32);
+ }
+
+ inline void pcg_mcg_32_step_r(struct pcg_state_32* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32;
+ }
+
+ inline void pcg_mcg_32_advance_r(struct pcg_state_32* rng, uint32_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, 0u);
+ }
+
+ inline void pcg_unique_32_step_r(struct pcg_state_32* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32
+ + (uint32_t)(((intptr_t)rng) | 1u);
+ }
+
+ inline void pcg_unique_32_advance_r(struct pcg_state_32* rng, uint32_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32,
+ (uint32_t)(((intptr_t)rng) | 1u));
+ }
+
+ inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 + rng->inc;
+ }
+
+ inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32* rng,
+ uint32_t delta)
+ {
+ rng->state = pcg_advance_lcg_32(rng->state, delta,
+ PCG_DEFAULT_MULTIPLIER_32, rng->inc);
+ }
+
+ inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64
+ + PCG_DEFAULT_INCREMENT_64;
+ }
+
+ inline void pcg_oneseq_64_advance_r(struct pcg_state_64* rng, uint64_t delta)
+ {
+ rng->state = pcg_advance_lcg_64(
+ rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, PCG_DEFAULT_INCREMENT_64);
+ }
+
+ inline void pcg_mcg_64_step_r(struct pcg_state_64* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64;
+ }
+
+ inline void pcg_mcg_64_advance_r(struct pcg_state_64* rng, uint64_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, 0u);
+ }
+
+ inline void pcg_unique_64_step_r(struct pcg_state_64* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64
+ + (uint64_t)(((intptr_t)rng) | 1u);
+ }
+
+ inline void pcg_unique_64_advance_r(struct pcg_state_64* rng, uint64_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64,
+ (uint64_t)(((intptr_t)rng) | 1u));
+ }
+
+ inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + rng->inc;
+ }
+
+ inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64* rng,
+ uint64_t delta)
+ {
+ rng->state = pcg_advance_lcg_64(rng->state, delta,
+ PCG_DEFAULT_MULTIPLIER_64, rng->inc);
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_oneseq_128_step_r(struct pcg_state_128* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128
+ + PCG_DEFAULT_INCREMENT_128;
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_oneseq_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128,
+ PCG_DEFAULT_INCREMENT_128);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_mcg_128_step_r(struct pcg_state_128* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128;
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_mcg_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)
+ {
+ rng->state = pcg_advance_lcg_128(rng->state, delta,
+ PCG_DEFAULT_MULTIPLIER_128, 0u);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_unique_128_step_r(struct pcg_state_128* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128
+ + (pcg128_t)(((intptr_t)rng) | 1u);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_unique_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128,
+ (pcg128_t)(((intptr_t)rng) | 1u));
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + rng->inc;
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128* rng,
+ pcg128_t delta)
+ {
+ rng->state = pcg_advance_lcg_128(rng->state, delta,
+ PCG_DEFAULT_MULTIPLIER_128, rng->inc);
+ }
+#endif
+
+ /* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+ inline void pcg_oneseq_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)
+ {
+ rng->state = 0U;
+ pcg_oneseq_8_step_r(rng);
+ rng->state += initstate;
+ pcg_oneseq_8_step_r(rng);
+ }
+
+ inline void pcg_mcg_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)
+ {
+ rng->state = initstate | 1u;
+ }
+
+ inline void pcg_unique_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)
+ {
+ rng->state = 0U;
+ pcg_unique_8_step_r(rng);
+ rng->state += initstate;
+ pcg_unique_8_step_r(rng);
+ }
+
+ inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8* rng,
+ uint8_t initstate, uint8_t initseq)
+ {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_setseq_8_step_r(rng);
+ rng->state += initstate;
+ pcg_setseq_8_step_r(rng);
+ }
+
+ inline void pcg_oneseq_16_srandom_r(struct pcg_state_16* rng,
+ uint16_t initstate)
+ {
+ rng->state = 0U;
+ pcg_oneseq_16_step_r(rng);
+ rng->state += initstate;
+ pcg_oneseq_16_step_r(rng);
+ }
+
+ inline void pcg_mcg_16_srandom_r(struct pcg_state_16* rng, uint16_t initstate)
+ {
+ rng->state = initstate | 1u;
+ }
+
+ inline void pcg_unique_16_srandom_r(struct pcg_state_16* rng,
+ uint16_t initstate)
+ {
+ rng->state = 0U;
+ pcg_unique_16_step_r(rng);
+ rng->state += initstate;
+ pcg_unique_16_step_r(rng);
+ }
+
+ inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16* rng,
+ uint16_t initstate, uint16_t initseq)
+ {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_setseq_16_step_r(rng);
+ rng->state += initstate;
+ pcg_setseq_16_step_r(rng);
+ }
+
+ inline void pcg_oneseq_32_srandom_r(struct pcg_state_32* rng,
+ uint32_t initstate)
+ {
+ rng->state = 0U;
+ pcg_oneseq_32_step_r(rng);
+ rng->state += initstate;
+ pcg_oneseq_32_step_r(rng);
+ }
+
+ inline void pcg_mcg_32_srandom_r(struct pcg_state_32* rng, uint32_t initstate)
+ {
+ rng->state = initstate | 1u;
+ }
+
+ inline void pcg_unique_32_srandom_r(struct pcg_state_32* rng,
+ uint32_t initstate)
+ {
+ rng->state = 0U;
+ pcg_unique_32_step_r(rng);
+ rng->state += initstate;
+ pcg_unique_32_step_r(rng);
+ }
+
+ inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32* rng,
+ uint32_t initstate, uint32_t initseq)
+ {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_setseq_32_step_r(rng);
+ rng->state += initstate;
+ pcg_setseq_32_step_r(rng);
+ }
+
+ inline void pcg_oneseq_64_srandom_r(struct pcg_state_64* rng,
+ uint64_t initstate)
+ {
+ rng->state = 0U;
+ pcg_oneseq_64_step_r(rng);
+ rng->state += initstate;
+ pcg_oneseq_64_step_r(rng);
+ }
+
+ inline void pcg_mcg_64_srandom_r(struct pcg_state_64* rng, uint64_t initstate)
+ {
+ rng->state = initstate | 1u;
+ }
+
+ inline void pcg_unique_64_srandom_r(struct pcg_state_64* rng,
+ uint64_t initstate)
+ {
+ rng->state = 0U;
+ pcg_unique_64_step_r(rng);
+ rng->state += initstate;
+ pcg_unique_64_step_r(rng);
+ }
+
+ inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64* rng,
+ uint64_t initstate, uint64_t initseq)
+ {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_setseq_64_step_r(rng);
+ rng->state += initstate;
+ pcg_setseq_64_step_r(rng);
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_oneseq_128_srandom_r(struct pcg_state_128* rng,
+ pcg128_t initstate)
+ {
+ rng->state = 0U;
+ pcg_oneseq_128_step_r(rng);
+ rng->state += initstate;
+ pcg_oneseq_128_step_r(rng);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_mcg_128_srandom_r(struct pcg_state_128* rng, pcg128_t initstate)
+ {
+ rng->state = initstate | 1u;
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_unique_128_srandom_r(struct pcg_state_128* rng,
+ pcg128_t initstate)
+ {
+ rng->state = 0U;
+ pcg_unique_128_step_r(rng);
+ rng->state += initstate;
+ pcg_unique_128_step_r(rng);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128* rng,
+ pcg128_t initstate, pcg128_t initseq)
+ {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_setseq_128_step_r(rng);
+ rng->state += initstate;
+ pcg_setseq_128_step_r(rng);
+ }
+#endif
+
+ /* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+ /* Generation functions for XSH RS */
+
+ inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_oneseq_16_step_r(rng);
+ return pcg_output_xsh_rs_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_oneseq_16_xsh_rs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_oneseq_32_step_r(rng);
+ return pcg_output_xsh_rs_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_oneseq_32_xsh_rs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_oneseq_64_step_r(rng);
+ return pcg_output_xsh_rs_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_oneseq_64_xsh_rs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_oneseq_128_step_r(rng);
+ return pcg_output_xsh_rs_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_oneseq_128_xsh_rs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_unique_16_step_r(rng);
+ return pcg_output_xsh_rs_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_unique_16_xsh_rs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_unique_32_step_r(rng);
+ return pcg_output_xsh_rs_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_unique_32_xsh_rs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_unique_64_step_r(rng);
+ return pcg_output_xsh_rs_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_unique_64_xsh_rs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_unique_128_step_r(rng);
+ return pcg_output_xsh_rs_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_unique_128_xsh_rs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_setseq_16_step_r(rng);
+ return pcg_output_xsh_rs_16_8(oldstate);
+ }
+
+ inline uint8_t
+ pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_setseq_16_xsh_rs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t
+ pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_setseq_32_step_r(rng);
+ return pcg_output_xsh_rs_32_16(oldstate);
+ }
+
+ inline uint16_t
+ pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_setseq_32_xsh_rs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t
+ pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_setseq_64_step_r(rng);
+ return pcg_output_xsh_rs_64_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_setseq_64_xsh_rs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128* rng)
+ {
+ pcg_setseq_128_step_r(rng);
+ return pcg_output_xsh_rs_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_setseq_128_xsh_rs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_mcg_16_step_r(rng);
+ return pcg_output_xsh_rs_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_mcg_16_xsh_rs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_mcg_32_step_r(rng);
+ return pcg_output_xsh_rs_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_mcg_32_xsh_rs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_mcg_64_step_r(rng);
+ return pcg_output_xsh_rs_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_mcg_64_xsh_rs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_mcg_128_step_r(rng);
+ return pcg_output_xsh_rs_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_mcg_128_xsh_rs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ /* Generation functions for XSH RR */
+
+ inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_oneseq_16_step_r(rng);
+ return pcg_output_xsh_rr_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_oneseq_16_xsh_rr_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_oneseq_32_step_r(rng);
+ return pcg_output_xsh_rr_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_oneseq_32_xsh_rr_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_oneseq_64_step_r(rng);
+ return pcg_output_xsh_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_oneseq_64_xsh_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_oneseq_128_step_r(rng);
+ return pcg_output_xsh_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_oneseq_128_xsh_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_unique_16_step_r(rng);
+ return pcg_output_xsh_rr_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_unique_16_xsh_rr_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_unique_32_step_r(rng);
+ return pcg_output_xsh_rr_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_unique_32_xsh_rr_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_unique_64_step_r(rng);
+ return pcg_output_xsh_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_unique_64_xsh_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_unique_128_step_r(rng);
+ return pcg_output_xsh_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_unique_128_xsh_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_setseq_16_step_r(rng);
+ return pcg_output_xsh_rr_16_8(oldstate);
+ }
+
+ inline uint8_t
+ pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_setseq_16_xsh_rr_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t
+ pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_setseq_32_step_r(rng);
+ return pcg_output_xsh_rr_32_16(oldstate);
+ }
+
+ inline uint16_t
+ pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_setseq_32_xsh_rr_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t
+ pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_setseq_64_step_r(rng);
+ return pcg_output_xsh_rr_64_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_setseq_64_xsh_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128* rng)
+ {
+ pcg_setseq_128_step_r(rng);
+ return pcg_output_xsh_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_setseq_128_xsh_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_mcg_16_step_r(rng);
+ return pcg_output_xsh_rr_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_mcg_16_xsh_rr_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_mcg_32_step_r(rng);
+ return pcg_output_xsh_rr_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_mcg_32_xsh_rr_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_mcg_64_step_r(rng);
+ return pcg_output_xsh_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_mcg_64_xsh_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_mcg_128_step_r(rng);
+ return pcg_output_xsh_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_mcg_128_xsh_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ /* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+ inline uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8* rng)
+ {
+ uint8_t oldstate = rng->state;
+ pcg_oneseq_8_step_r(rng);
+ return pcg_output_rxs_m_xs_8_8(oldstate);
+ }
+
+ inline uint8_t pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_oneseq_8_rxs_m_xs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_oneseq_16_step_r(rng);
+ return pcg_output_rxs_m_xs_16_16(oldstate);
+ }
+
+ inline uint16_t
+ pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_oneseq_16_rxs_m_xs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_oneseq_32_step_r(rng);
+ return pcg_output_rxs_m_xs_32_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_oneseq_32_rxs_m_xs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint64_t pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_oneseq_64_step_r(rng);
+ return pcg_output_rxs_m_xs_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_oneseq_64_rxs_m_xs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng)
+ {
+ pcg_oneseq_128_step_r(rng);
+ return pcg_output_rxs_m_xs_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_oneseq_128_rxs_m_xs_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint16_t pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_unique_16_step_r(rng);
+ return pcg_output_rxs_m_xs_16_16(oldstate);
+ }
+
+ inline uint16_t
+ pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_unique_16_rxs_m_xs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_unique_32_step_r(rng);
+ return pcg_output_rxs_m_xs_32_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_unique_32_rxs_m_xs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint64_t pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_unique_64_step_r(rng);
+ return pcg_output_rxs_m_xs_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_unique_64_rxs_m_xs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng)
+ {
+ pcg_unique_128_step_r(rng);
+ return pcg_output_rxs_m_xs_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_unique_128_rxs_m_xs_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8* rng)
+ {
+ uint8_t oldstate = rng->state;
+ pcg_setseq_8_step_r(rng);
+ return pcg_output_rxs_m_xs_8_8(oldstate);
+ }
+
+ inline uint8_t
+ pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_setseq_8_rxs_m_xs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t
+ pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_setseq_16_step_r(rng);
+ return pcg_output_rxs_m_xs_16_16(oldstate);
+ }
+
+ inline uint16_t
+ pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_setseq_16_rxs_m_xs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t
+ pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_setseq_32_step_r(rng);
+ return pcg_output_rxs_m_xs_32_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_setseq_32_rxs_m_xs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint64_t
+ pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_setseq_64_step_r(rng);
+ return pcg_output_rxs_m_xs_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_setseq_64_rxs_m_xs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128* rng)
+ {
+ pcg_setseq_128_step_r(rng);
+ return pcg_output_rxs_m_xs_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_setseq_128_rxs_m_xs_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ /* Generation functions for XSL RR (only defined for "large" types) */
+
+ inline uint32_t pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_oneseq_64_step_r(rng);
+ return pcg_output_xsl_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_oneseq_64_xsl_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_oneseq_128_step_r(rng);
+ return pcg_output_xsl_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_oneseq_128_xsl_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint32_t pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_unique_64_step_r(rng);
+ return pcg_output_xsl_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_unique_64_xsl_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_unique_128_step_r(rng);
+ return pcg_output_xsl_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_unique_128_xsl_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint32_t
+ pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_setseq_64_step_r(rng);
+ return pcg_output_xsl_rr_64_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_setseq_64_xsl_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128* rng)
+ {
+ pcg_setseq_128_step_r(rng);
+ return pcg_output_xsl_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_setseq_128_xsl_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_mcg_64_step_r(rng);
+ return pcg_output_xsl_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_mcg_64_xsl_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_mcg_128_step_r(rng);
+ return pcg_output_xsl_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_mcg_128_xsl_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ /* Generation functions for XSL RR RR (only defined for "large" types) */
+
+ inline uint64_t pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_oneseq_64_step_r(rng);
+ return pcg_output_xsl_rr_rr_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_oneseq_64_xsl_rr_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng)
+ {
+ pcg_oneseq_128_step_r(rng);
+ return pcg_output_xsl_rr_rr_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_oneseq_128_xsl_rr_rr_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint64_t pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_unique_64_step_r(rng);
+ return pcg_output_xsl_rr_rr_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_unique_64_xsl_rr_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng)
+ {
+ pcg_unique_128_step_r(rng);
+ return pcg_output_xsl_rr_rr_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_unique_128_xsl_rr_rr_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint64_t
+ pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_setseq_64_step_r(rng);
+ return pcg_output_xsl_rr_rr_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_setseq_64_xsl_rr_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128* rng)
+ {
+ pcg_setseq_128_step_r(rng);
+ return pcg_output_xsl_rr_rr_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_setseq_128_xsl_rr_rr_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ //// Typedefs
+ typedef struct pcg_state_setseq_64 pcg32_random_t;
+ typedef struct pcg_state_64 pcg32s_random_t;
+ typedef struct pcg_state_64 pcg32u_random_t;
+ typedef struct pcg_state_64 pcg32f_random_t;
+ //// random_r
+#define pcg32_random_r pcg_setseq_64_xsh_rr_32_random_r
+#define pcg32s_random_r pcg_oneseq_64_xsh_rr_32_random_r
+#define pcg32u_random_r pcg_unique_64_xsh_rr_32_random_r
+#define pcg32f_random_r pcg_mcg_64_xsh_rs_32_random_r
+ //// boundedrand_r
+#define pcg32_boundedrand_r pcg_setseq_64_xsh_rr_32_boundedrand_r
+#define pcg32s_boundedrand_r pcg_oneseq_64_xsh_rr_32_boundedrand_r
+#define pcg32u_boundedrand_r pcg_unique_64_xsh_rr_32_boundedrand_r
+#define pcg32f_boundedrand_r pcg_mcg_64_xsh_rs_32_boundedrand_r
+ //// srandom_r
+#define pcg32_srandom_r pcg_setseq_64_srandom_r
+#define pcg32s_srandom_r pcg_oneseq_64_srandom_r
+#define pcg32u_srandom_r pcg_unique_64_srandom_r
+#define pcg32f_srandom_r pcg_mcg_64_srandom_r
+ //// advance_r
+#define pcg32_advance_r pcg_setseq_64_advance_r
+#define pcg32s_advance_r pcg_oneseq_64_advance_r
+#define pcg32u_advance_r pcg_unique_64_advance_r
+#define pcg32f_advance_r pcg_mcg_64_advance_r
+
+#if PCG_HAS_128BIT_OPS
+ //// Typedefs
+ typedef struct pcg_state_setseq_128 pcg64_random_t;
+ typedef struct pcg_state_128 pcg64s_random_t;
+ typedef struct pcg_state_128 pcg64u_random_t;
+ typedef struct pcg_state_128 pcg64f_random_t;
+ //// random_r
+#define pcg64_random_r pcg_setseq_128_xsl_rr_64_random_r
+#define pcg64s_random_r pcg_oneseq_128_xsl_rr_64_random_r
+#define pcg64u_random_r pcg_unique_128_xsl_rr_64_random_r
+#define pcg64f_random_r pcg_mcg_128_xsl_rr_64_random_r
+ //// boundedrand_r
+#define pcg64_boundedrand_r pcg_setseq_128_xsl_rr_64_boundedrand_r
+#define pcg64s_boundedrand_r pcg_oneseq_128_xsl_rr_64_boundedrand_r
+#define pcg64u_boundedrand_r pcg_unique_128_xsl_rr_64_boundedrand_r
+#define pcg64f_boundedrand_r pcg_mcg_128_xsl_rr_64_boundedrand_r
+ //// srandom_r
+#define pcg64_srandom_r pcg_setseq_128_srandom_r
+#define pcg64s_srandom_r pcg_oneseq_128_srandom_r
+#define pcg64u_srandom_r pcg_unique_128_srandom_r
+#define pcg64f_srandom_r pcg_mcg_128_srandom_r
+ //// advance_r
+#define pcg64_advance_r pcg_setseq_128_advance_r
+#define pcg64s_advance_r pcg_oneseq_128_advance_r
+#define pcg64u_advance_r pcg_unique_128_advance_r
+#define pcg64f_advance_r pcg_mcg_128_advance_r
+#endif
+
+ //// Typedefs
+ typedef struct pcg_state_8 pcg8si_random_t;
+ typedef struct pcg_state_16 pcg16si_random_t;
+ typedef struct pcg_state_32 pcg32si_random_t;
+ typedef struct pcg_state_64 pcg64si_random_t;
+ //// random_r
+#define pcg8si_random_r pcg_oneseq_8_rxs_m_xs_8_random_r
+#define pcg16si_random_r pcg_oneseq_16_rxs_m_xs_16_random_r
+#define pcg32si_random_r pcg_oneseq_32_rxs_m_xs_32_random_r
+#define pcg64si_random_r pcg_oneseq_64_rxs_m_xs_64_random_r
+ //// boundedrand_r
+#define pcg8si_boundedrand_r pcg_oneseq_8_rxs_m_xs_8_boundedrand_r
+#define pcg16si_boundedrand_r pcg_oneseq_16_rxs_m_xs_16_boundedrand_r
+#define pcg32si_boundedrand_r pcg_oneseq_32_rxs_m_xs_32_boundedrand_r
+#define pcg64si_boundedrand_r pcg_oneseq_64_rxs_m_xs_64_boundedrand_r
+ //// srandom_r
+#define pcg8si_srandom_r pcg_oneseq_8_srandom_r
+#define pcg16si_srandom_r pcg_oneseq_16_srandom_r
+#define pcg32si_srandom_r pcg_oneseq_32_srandom_r
+#define pcg64si_srandom_r pcg_oneseq_64_srandom_r
+ //// advance_r
+#define pcg8si_advance_r pcg_oneseq_8_advance_r
+#define pcg16si_advance_r pcg_oneseq_16_advance_r
+#define pcg32si_advance_r pcg_oneseq_32_advance_r
+#define pcg64si_advance_r pcg_oneseq_64_advance_r
+
+#if PCG_HAS_128BIT_OPS
+ typedef struct pcg_state_128 pcg128si_random_t;
+#define pcg128si_random_r pcg_oneseq_128_rxs_m_xs_128_random_r
+#define pcg128si_boundedrand_r pcg_oneseq_128_rxs_m_xs_128_boundedrand_r
+#define pcg128si_srandom_r pcg_oneseq_128_srandom_r
+#define pcg128si_advance_r pcg_oneseq_128_advance_r
+#endif
+
+ //// Typedefs
+ typedef struct pcg_state_setseq_8 pcg8i_random_t;
+ typedef struct pcg_state_setseq_16 pcg16i_random_t;
+ typedef struct pcg_state_setseq_32 pcg32i_random_t;
+ typedef struct pcg_state_setseq_64 pcg64i_random_t;
+ //// random_r
+#define pcg8i_random_r pcg_setseq_8_rxs_m_xs_8_random_r
+#define pcg16i_random_r pcg_setseq_16_rxs_m_xs_16_random_r
+#define pcg32i_random_r pcg_setseq_32_rxs_m_xs_32_random_r
+#define pcg64i_random_r pcg_setseq_64_rxs_m_xs_64_random_r
+ //// boundedrand_r
+#define pcg8i_boundedrand_r pcg_setseq_8_rxs_m_xs_8_boundedrand_r
+#define pcg16i_boundedrand_r pcg_setseq_16_rxs_m_xs_16_boundedrand_r
+#define pcg32i_boundedrand_r pcg_setseq_32_rxs_m_xs_32_boundedrand_r
+#define pcg64i_boundedrand_r pcg_setseq_64_rxs_m_xs_64_boundedrand_r
+ //// srandom_r
+#define pcg8i_srandom_r pcg_setseq_8_srandom_r
+#define pcg16i_srandom_r pcg_setseq_16_srandom_r
+#define pcg32i_srandom_r pcg_setseq_32_srandom_r
+#define pcg64i_srandom_r pcg_setseq_64_srandom_r
+ //// advance_r
+#define pcg8i_advance_r pcg_setseq_8_advance_r
+#define pcg16i_advance_r pcg_setseq_16_advance_r
+#define pcg32i_advance_r pcg_setseq_32_advance_r
+#define pcg64i_advance_r pcg_setseq_64_advance_r
+
+#if PCG_HAS_128BIT_OPS
+ typedef struct pcg_state_setseq_128 pcg128i_random_t;
+#define pcg128i_random_r pcg_setseq_128_rxs_m_xs_128_random_r
+#define pcg128i_boundedrand_r pcg_setseq_128_rxs_m_xs_128_boundedrand_r
+#define pcg128i_srandom_r pcg_setseq_128_srandom_r
+#define pcg128i_advance_r pcg_setseq_128_advance_r
+#endif
+
+ extern uint32_t pcg32_random();
+ extern uint32_t pcg32_boundedrand(uint32_t bound);
+ extern void pcg32_srandom(uint64_t seed, uint64_t seq);
+ extern void pcg32_advance(uint64_t delta);
+
+#if PCG_HAS_128BIT_OPS
+ extern uint64_t pcg64_random();
+ extern uint64_t pcg64_boundedrand(uint64_t bound);
+ extern void pcg64_srandom(pcg128_t seed, pcg128_t seq);
+ extern void pcg64_advance(pcg128_t delta);
+#endif
+
+ /*
+ * Static initialization constants (if you can't call srandom for some
+ * bizarre reason).
+ */
+
+#define PCG32_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER
+#define PCG32U_INITIALIZER PCG_STATE_UNIQUE_64_INITIALIZER
+#define PCG32S_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER
+#define PCG32F_INITIALIZER PCG_STATE_MCG_64_INITIALIZER
+
+#if PCG_HAS_128BIT_OPS
+#define PCG64_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER
+#define PCG64U_INITIALIZER PCG_STATE_UNIQUE_128_INITIALIZER
+#define PCG64S_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER
+#define PCG64F_INITIALIZER PCG_STATE_MCG_128_INITIALIZER
+#endif
+
+#if PCG_HAS_128BIT_OPS
+#define PCG8SI_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER
+#define PCG16SI_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER
+#define PCG32SI_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER
+#define PCG64SI_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER
+#define PCG128SI_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER
+#endif
+
+#if PCG_HAS_128BIT_OPS
+#define PCG8I_INITIALIZER PCG_STATE_SETSEQ_8_INITIALIZER
+#define PCG16I_INITIALIZER PCG_STATE_SETSEQ_16_INITIALIZER
+#define PCG32I_INITIALIZER PCG_STATE_SETSEQ_32_INITIALIZER
+#define PCG64I_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER
+#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER
+#endif
+
+#if __cplusplus
+}
+#endif
+
+#endif // PCG_VARIANTS_H_INCLUDED
+
diff --git a/src/haversine/listing_065.cpp b/src/haversine/listing_065.cpp
new file mode 100644
index 0000000..86e087c
--- /dev/null
+++ b/src/haversine/listing_065.cpp
@@ -0,0 +1,39 @@
+#include <math.h>
+
+static f64 Square(f64 A)
+{
+ f64 Result = (A*A);
+ return Result;
+}
+
+static f64 RadiansFromDegrees(f64 Degrees)
+{
+ f64 Result = 0.01745329251994329577 * Degrees;
+ return Result;
+}
+
+// NOTE(casey): EarthRadius is generally expected to be 6372.8
+static f64 ReferenceHaversine(f64 X0, f64 Y0, f64 X1, f64 Y1, f64 EarthRadius)
+{
+ /* NOTE(casey): This is not meant to be a "good" way to calculate the Haversine distance.
+ Instead, it attempts to follow, as closely as possible, the formula used in the real-world
+ question on which these homework exercises are loosely based.
+ */
+
+ f64 lat1 = Y0;
+ f64 lat2 = Y1;
+ f64 lon1 = X0;
+ f64 lon2 = X1;
+
+ f64 dLat = RadiansFromDegrees(lat2 - lat1);
+ f64 dLon = RadiansFromDegrees(lon2 - lon1);
+ lat1 = RadiansFromDegrees(lat1);
+ lat2 = RadiansFromDegrees(lat2);
+
+ f64 a = Square(sin(dLat/2.0)) + cos(lat1)*cos(lat2)*Square(sin(dLon/2));
+ f64 c = 2.0*asin(sqrt(a));
+
+ f64 Result = EarthRadius * c;
+
+ return Result;
+}
diff --git a/src/sim86/bin/generated/generated.cpp b/src/sim86/bin/generated/generated.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/sim86/bin/generated/generated.cpp
diff --git a/src/tmux.sh b/src/sim86/bin/tmux.sh
index 78845a9..78845a9 100755
--- a/src/tmux.sh
+++ b/src/sim86/bin/tmux.sh
diff --git a/src/build.sh b/src/sim86/build.sh
index 7726aee..74f6828 100755
--- a/src/build.sh
+++ b/src/sim86/build.sh
@@ -1,9 +1,9 @@
#!/bin/sh
-ThisDir="$(dirname "$(readlink -f "$0")")"
-cd "$ThisDir"
+cd "$(dirname "$(readlink -f "$0")")"
-mkdir -p ../build
+Build="../../build"
+mkdir -p "$Build"
mkdir -p generated
Compiler="clang"
@@ -30,12 +30,13 @@ WarningFlags="
printf '[metadata generation]\n'
$Compiler $CompilerFlags $WarningFlags \
- -o ../build/sim86_meta \
+ -o "$Build"/sim86_meta \
sim86_meta.c
-../build/sim86_meta ./sim86.mdesk > ./generated/generated.cpp
+"$Build"/sim86_meta ./sim86.mdesk > ./generated/generated.cpp
+printf '[debug mode]\n'
printf '[%s build]\n' "$Compiler"
Source="sim86.cpp"
$Compiler $CompilerFlags $WarningFlags \
- -o ../build/sim86 \
+ -o "$Build"/sim86 \
sim86.cpp
diff --git a/src/clocks_table.inl b/src/sim86/clocks_table.inl
index 2c07bb3..2c07bb3 100644
--- a/src/clocks_table.inl
+++ b/src/sim86/clocks_table.inl
diff --git a/src/generated/generated.cpp b/src/sim86/generated/generated.cpp
index 0f457a1..0f457a1 100644
--- a/src/generated/generated.cpp
+++ b/src/sim86/generated/generated.cpp
diff --git a/src/libs/metadesk/md.c b/src/sim86/libs/metadesk/md.c
index 6be1e69..6be1e69 100644
--- a/src/libs/metadesk/md.c
+++ b/src/sim86/libs/metadesk/md.c
diff --git a/src/libs/metadesk/md.h b/src/sim86/libs/metadesk/md.h
index faad8e3..faad8e3 100644
--- a/src/libs/metadesk/md.h
+++ b/src/sim86/libs/metadesk/md.h
diff --git a/src/libs/metadesk/md_stb_sprintf.h b/src/sim86/libs/metadesk/md_stb_sprintf.h
index 4758435..4758435 100644
--- a/src/libs/metadesk/md_stb_sprintf.h
+++ b/src/sim86/libs/metadesk/md_stb_sprintf.h
diff --git a/src/libs/reference_decoder/sim86.h b/src/sim86/libs/reference_decoder/sim86.h
index b065a0e..b065a0e 100644
--- a/src/libs/reference_decoder/sim86.h
+++ b/src/sim86/libs/reference_decoder/sim86.h
diff --git a/src/libs/reference_decoder/sim86_decode.cpp b/src/sim86/libs/reference_decoder/sim86_decode.cpp
index dc084d5..dc084d5 100644
--- a/src/libs/reference_decoder/sim86_decode.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_decode.cpp
diff --git a/src/libs/reference_decoder/sim86_decode.h b/src/sim86/libs/reference_decoder/sim86_decode.h
index 534ce2d..534ce2d 100644
--- a/src/libs/reference_decoder/sim86_decode.h
+++ b/src/sim86/libs/reference_decoder/sim86_decode.h
diff --git a/src/libs/reference_decoder/sim86_instruction.cpp b/src/sim86/libs/reference_decoder/sim86_instruction.cpp
index 34fcf1f..34fcf1f 100644
--- a/src/libs/reference_decoder/sim86_instruction.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_instruction.cpp
diff --git a/src/libs/reference_decoder/sim86_instruction.h b/src/sim86/libs/reference_decoder/sim86_instruction.h
index 191635a..191635a 100644
--- a/src/libs/reference_decoder/sim86_instruction.h
+++ b/src/sim86/libs/reference_decoder/sim86_instruction.h
diff --git a/src/libs/reference_decoder/sim86_instruction_table.cpp b/src/sim86/libs/reference_decoder/sim86_instruction_table.cpp
index be3ec82..be3ec82 100644
--- a/src/libs/reference_decoder/sim86_instruction_table.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_instruction_table.cpp
diff --git a/src/libs/reference_decoder/sim86_instruction_table.h b/src/sim86/libs/reference_decoder/sim86_instruction_table.h
index ed8aea8..ed8aea8 100644
--- a/src/libs/reference_decoder/sim86_instruction_table.h
+++ b/src/sim86/libs/reference_decoder/sim86_instruction_table.h
diff --git a/src/libs/reference_decoder/sim86_instruction_table.inl b/src/sim86/libs/reference_decoder/sim86_instruction_table.inl
index 576c0f6..576c0f6 100644
--- a/src/libs/reference_decoder/sim86_instruction_table.inl
+++ b/src/sim86/libs/reference_decoder/sim86_instruction_table.inl
diff --git a/src/libs/reference_decoder/sim86_lib.cpp b/src/sim86/libs/reference_decoder/sim86_lib.cpp
index 6971eb2..6971eb2 100644
--- a/src/libs/reference_decoder/sim86_lib.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_lib.cpp
diff --git a/src/libs/reference_decoder/sim86_memory.cpp b/src/sim86/libs/reference_decoder/sim86_memory.cpp
index 1d58ede..1d58ede 100644
--- a/src/libs/reference_decoder/sim86_memory.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_memory.cpp
diff --git a/src/libs/reference_decoder/sim86_memory.h b/src/sim86/libs/reference_decoder/sim86_memory.h
index 4e790dc..4e790dc 100644
--- a/src/libs/reference_decoder/sim86_memory.h
+++ b/src/sim86/libs/reference_decoder/sim86_memory.h
diff --git a/src/libs/reference_decoder/sim86_text_table.cpp b/src/sim86/libs/reference_decoder/sim86_text_table.cpp
index e90a649..e90a649 100644
--- a/src/libs/reference_decoder/sim86_text_table.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_text_table.cpp
diff --git a/src/sim86.cpp b/src/sim86/sim86.cpp
index 7c444bd..7c444bd 100644
--- a/src/sim86.cpp
+++ b/src/sim86/sim86.cpp
diff --git a/src/sim86.h b/src/sim86/sim86.h
index 24068e2..24068e2 100644
--- a/src/sim86.h
+++ b/src/sim86/sim86.h
diff --git a/src/sim86.mdesk b/src/sim86/sim86.mdesk
index 0635110..0635110 100644
--- a/src/sim86.mdesk
+++ b/src/sim86/sim86.mdesk
diff --git a/src/sim86_meta.c b/src/sim86/sim86_meta.c
index c8fe8f3..37fe0c3 100644
--- a/src/sim86_meta.c
+++ b/src/sim86/sim86_meta.c
@@ -1,3 +1,4 @@
+
#if __clang__
# define COMPILER_CLANG 1
#elif _MSC_VER
diff --git a/src/sim86_shared.h b/src/sim86/sim86_shared.h
index 7a54beb..7a54beb 100644
--- a/src/sim86_shared.h
+++ b/src/sim86/sim86_shared.h