75 lines
1.4 KiB
ArmAsm
75 lines
1.4 KiB
ArmAsm
#include "macros.inc"
|
|
.set noat
|
|
.set noreorder
|
|
.set gp=64
|
|
|
|
.data
|
|
|
|
glabel g_RngSeed
|
|
.dword 0xab8d9f7781280783
|
|
|
|
.text
|
|
|
|
/**
|
|
* u32 random(void)
|
|
*
|
|
* Generate a random number between 0 and 4294967295.
|
|
*/
|
|
glabel random
|
|
lui $a0, %hi(g_RngSeed)
|
|
ld $a0, %lo(g_RngSeed)($a0)
|
|
lui $at, %hi(g_RngSeed)
|
|
dsll32 $a2, $a0, 31
|
|
dsll $a1, $a0, 31
|
|
dsrl $a2, $a2, 31
|
|
dsrl32 $a1, $a1, 0
|
|
dsll32 $a0, $a0, 12
|
|
or $a2, $a2, $a1
|
|
dsrl32 $a0, $a0, 0
|
|
xor $a2, $a2, $a0
|
|
dsrl $a0, $a2, 20
|
|
andi $a0, $a0, 0xfff
|
|
xor $a0, $a0, $a2
|
|
dsll32 $v0, $a0, 0
|
|
sd $a0, %lo(g_RngSeed)($at)
|
|
jr $ra
|
|
dsra32 $v0, $v0, 0
|
|
|
|
/**
|
|
* void rngSetSeed(u32 seed)
|
|
*
|
|
* Set the given seed as the RNG seed. Add 1 to make sure it isn't 0.
|
|
*/
|
|
glabel rngSetSeed
|
|
daddiu $a0, $a0, 1
|
|
lui $at, %hi(g_RngSeed)
|
|
sd $a0, %lo(g_RngSeed)($at)
|
|
jr $ra
|
|
li $a0, 0
|
|
|
|
/**
|
|
* u32 rngRotateSeed(u64 *value);
|
|
*
|
|
* Rotate the given seed using the same algorithm as random().
|
|
*
|
|
* Store the new 64-bit seed at the pointed address and return the same seed
|
|
* cast as a u32.
|
|
*/
|
|
glabel rngRotateSeed
|
|
ld $a3, 0($a0)
|
|
dsll32 $a2, $a3, 31
|
|
dsll $a1, $a3, 31
|
|
dsrl $a2, $a2, 31
|
|
dsrl32 $a1, $a1, 0
|
|
dsll32 $a3, $a3, 12
|
|
or $a2, $a2, $a1
|
|
dsrl32 $a3, $a3, 0
|
|
xor $a2, $a2, $a3
|
|
dsrl $a3, $a2, 20
|
|
andi $a3, $a3, 0xfff
|
|
xor $a3, $a3, $a2
|
|
dsll32 $v0, $a3, 0
|
|
sd $a3, 0($a0)
|
|
jr $ra
|
|
dsra32 $v0, $v0, 0
|