CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/ext/sfmt19937/SFMT-common.h
Views: 1401
1
#pragma once
2
/**
3
* @file SFMT-common.h
4
*
5
* @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom
6
* number generator with jump function. This file includes common functions
7
* used in random number generation and jump.
8
*
9
* @author Mutsuo Saito (Hiroshima University)
10
* @author Makoto Matsumoto (The University of Tokyo)
11
*
12
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
13
* University.
14
* Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima
15
* University and The University of Tokyo.
16
* All rights reserved.
17
*
18
* The 3-clause BSD License is applied to this software, see
19
* LICENSE.txt
20
*/
21
#ifndef SFMT_COMMON_H
22
#define SFMT_COMMON_H
23
24
#if defined(__cplusplus)
25
extern "C" {
26
#endif
27
28
#include "SFMT.h"
29
30
inline static void do_recursion(w128_t * r, w128_t * a, w128_t * b,
31
w128_t * c, w128_t * d);
32
33
inline static void rshift128(w128_t *out, w128_t const *in, int shift);
34
inline static void lshift128(w128_t *out, w128_t const *in, int shift);
35
36
/**
37
* This function simulates SIMD 128-bit right shift by the standard C.
38
* The 128-bit integer given in in is shifted by (shift * 8) bits.
39
* This function simulates the LITTLE ENDIAN SIMD.
40
* @param out the output of this function
41
* @param in the 128-bit data to be shifted
42
* @param shift the shift value
43
*/
44
#ifdef ONLY64
45
inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
46
uint64_t th, tl, oh, ol;
47
48
th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
49
tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
50
51
oh = th >> (shift * 8);
52
ol = tl >> (shift * 8);
53
ol |= th << (64 - shift * 8);
54
out->u[0] = (uint32_t)(ol >> 32);
55
out->u[1] = (uint32_t)ol;
56
out->u[2] = (uint32_t)(oh >> 32);
57
out->u[3] = (uint32_t)oh;
58
}
59
#else
60
inline static void rshift128(w128_t *out, w128_t const *in, int shift)
61
{
62
uint64_t th, tl, oh, ol;
63
64
th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
65
tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
66
67
oh = th >> (shift * 8);
68
ol = tl >> (shift * 8);
69
ol |= th << (64 - shift * 8);
70
out->u[1] = (uint32_t)(ol >> 32);
71
out->u[0] = (uint32_t)ol;
72
out->u[3] = (uint32_t)(oh >> 32);
73
out->u[2] = (uint32_t)oh;
74
}
75
#endif
76
/**
77
* This function simulates SIMD 128-bit left shift by the standard C.
78
* The 128-bit integer given in in is shifted by (shift * 8) bits.
79
* This function simulates the LITTLE ENDIAN SIMD.
80
* @param out the output of this function
81
* @param in the 128-bit data to be shifted
82
* @param shift the shift value
83
*/
84
#ifdef ONLY64
85
inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
86
uint64_t th, tl, oh, ol;
87
88
th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
89
tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
90
91
oh = th << (shift * 8);
92
ol = tl << (shift * 8);
93
oh |= tl >> (64 - shift * 8);
94
out->u[0] = (uint32_t)(ol >> 32);
95
out->u[1] = (uint32_t)ol;
96
out->u[2] = (uint32_t)(oh >> 32);
97
out->u[3] = (uint32_t)oh;
98
}
99
#else
100
inline static void lshift128(w128_t *out, w128_t const *in, int shift)
101
{
102
uint64_t th, tl, oh, ol;
103
104
th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
105
tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
106
107
oh = th << (shift * 8);
108
ol = tl << (shift * 8);
109
oh |= tl >> (64 - shift * 8);
110
out->u[1] = (uint32_t)(ol >> 32);
111
out->u[0] = (uint32_t)ol;
112
out->u[3] = (uint32_t)(oh >> 32);
113
out->u[2] = (uint32_t)oh;
114
}
115
#endif
116
/**
117
* This function represents the recursion formula.
118
* @param r output
119
* @param a a 128-bit part of the internal state array
120
* @param b a 128-bit part of the internal state array
121
* @param c a 128-bit part of the internal state array
122
* @param d a 128-bit part of the internal state array
123
*/
124
#ifdef ONLY64
125
inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
126
w128_t *d) {
127
w128_t x;
128
w128_t y;
129
130
lshift128(&x, a, SFMT_SL2);
131
rshift128(&y, c, SFMT_SR2);
132
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SFMT_SR1) & SFMT_MSK2) ^ y.u[0]
133
^ (d->u[0] << SFMT_SL1);
134
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SFMT_SR1) & SFMT_MSK1) ^ y.u[1]
135
^ (d->u[1] << SFMT_SL1);
136
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SFMT_SR1) & SFMT_MSK4) ^ y.u[2]
137
^ (d->u[2] << SFMT_SL1);
138
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SFMT_SR1) & SFMT_MSK3) ^ y.u[3]
139
^ (d->u[3] << SFMT_SL1);
140
}
141
#else
142
inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b,
143
w128_t *c, w128_t *d)
144
{
145
w128_t x;
146
w128_t y;
147
148
lshift128(&x, a, SFMT_SL2);
149
rshift128(&y, c, SFMT_SR2);
150
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SFMT_SR1) & SFMT_MSK1)
151
^ y.u[0] ^ (d->u[0] << SFMT_SL1);
152
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SFMT_SR1) & SFMT_MSK2)
153
^ y.u[1] ^ (d->u[1] << SFMT_SL1);
154
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SFMT_SR1) & SFMT_MSK3)
155
^ y.u[2] ^ (d->u[2] << SFMT_SL1);
156
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SFMT_SR1) & SFMT_MSK4)
157
^ y.u[3] ^ (d->u[3] << SFMT_SL1);
158
}
159
#endif
160
#endif
161
162
#if defined(__cplusplus)
163
}
164
#endif
165
166