// File: ddunbar[P]PDSample/RNG.cpp
// Function: RNG::RNG(unsigned long*, int)
RNG::RNG(unsigned long init_key[], int key_length)
{
    int i, j, k;
	seed(19650218UL);
    i=1; j=0;
    k = (N>key_length ? N : key_length);
    for (; k; k--) {
        mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
          + init_key[j] + j; /* non linear */
        mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
        i++; j++;
        if (i>=N) { mt[0] = mt[N-1]; i=1; }
        if (j>=key_length) j=0;
    }
    for (k=N-1; k; k--) {
        mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
          - i; /* non linear */
        mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
        i++;
        if (i>=N) { mt[0] = mt[N-1]; i=1; }
    }

    mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ 
}

// Assembly:
subq $0x38, %rsp
movq %rdi, 0x30(%rsp)
movq %rsi, 0x28(%rsp)
movl %edx, 0x24(%rsp)
movq 0x30(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movl $0x12bd6aa, %esi        # imm = 0x12BD6AA
callq 0x2710
movl $0x1, 0x20(%rsp)
movl $0x0, 0x1c(%rsp)
movslq 0x24(%rsp), %rcx
movl $0x270, %eax            # imm = 0x270
cmpq %rcx, %rax
jle 0x2821
movl $0x270, %eax            # imm = 0x270
movq %rax, 0x8(%rsp)
jmp 0x282b
movslq 0x24(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rax
movl %eax, 0x18(%rsp)
cmpl $0x0, 0x18(%rsp)
je 0x290e
movq 0x10(%rsp), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rdx
movl 0x20(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rcx
movl 0x20(%rsp), %esi
subl $0x1, %esi
movslq %esi, %rsi
movq (%rax,%rsi,8), %rsi
shrq $0x1e, %rsi
xorq %rsi, %rcx
imulq $0x19660d, %rcx, %rcx   # imm = 0x19660D
xorq %rcx, %rdx
movq 0x28(%rsp), %rcx
movslq 0x1c(%rsp), %rsi
addq (%rcx,%rsi,8), %rdx
movslq 0x1c(%rsp), %rcx
addq %rcx, %rdx
movslq 0x20(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movslq 0x20(%rsp), %rcx
movabsq $0xffffffff, %rdx       # imm = 0xFFFFFFFF
andq (%rax,%rcx,8), %rdx
movq %rdx, (%rax,%rcx,8)
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
movslq 0x20(%rsp), %rax
cmpq $0x270, %rax            # imm = 0x270
jl 0x28ea
movq 0x10(%rsp), %rax
movq 0x1378(%rax), %rcx
movq %rcx, (%rax)
movl $0x1, 0x20(%rsp)
movl 0x1c(%rsp), %eax
cmpl 0x24(%rsp), %eax
jl 0x28fc
movl $0x0, 0x1c(%rsp)
jmp 0x28fe
movl 0x18(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x18(%rsp)
jmp 0x2834
movl $0x26f, 0x18(%rsp)      # imm = 0x26F
cmpl $0x0, 0x18(%rsp)
je 0x29c5
movq 0x10(%rsp), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rdx
movl 0x20(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rcx
movl 0x20(%rsp), %esi
subl $0x1, %esi
movslq %esi, %rsi
movq (%rax,%rsi,8), %rsi
shrq $0x1e, %rsi
xorq %rsi, %rcx
imulq $0x5d588b65, %rcx, %rcx # imm = 0x5D588B65
xorq %rcx, %rdx
movslq 0x20(%rsp), %rcx
subq %rcx, %rdx
movslq 0x20(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movslq 0x20(%rsp), %rcx
movabsq $0xffffffff, %rdx       # imm = 0xFFFFFFFF
andq (%rax,%rcx,8), %rdx
movq %rdx, (%rax,%rcx,8)
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
movslq 0x20(%rsp), %rax
cmpq $0x270, %rax            # imm = 0x270
jl 0x29b3
movq 0x10(%rsp), %rax
movq 0x1378(%rax), %rcx
movq %rcx, (%rax)
movl $0x1, 0x20(%rsp)
jmp 0x29b5
movl 0x18(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x18(%rsp)
jmp 0x2916
movq 0x10(%rsp), %rax
movl $0x80000000, %ecx       # imm = 0x80000000
movq %rcx, (%rax)
addq $0x38, %rsp
retq
nopw (%rax,%rax)