// File: UTSASRG[P]Guarder/rng/sse2rng.c
// Function: rand_sse(unsigned int*)
void rand_sse( unsigned int* result )
{
		__attribute__(( aligned (16) )) __m128i cur_seed_split;
		__attribute__(( aligned (16) )) __m128i multiplier;
		__attribute__(( aligned (16) )) __m128i adder;
		__attribute__(( aligned (16) )) __m128i mod_mask;
		__attribute__(( aligned (16) )) __m128i sra_mask;
		__attribute__(( aligned (16) )) __m128i sseresult;
		__attribute__(( aligned (16) )) static const unsigned int mult[4] =
				{ 214013, 17405, 214013, 69069 };
		__attribute__(( aligned (16) )) static const unsigned int gadd[4] =
				{ 2531011, 10395331, 13737667, 1 };
		__attribute__(( aligned (16) )) static const unsigned int mask[4] =
				{ 0xFFFFFFFF, 0, 0xFFFFFFFF, 0 };
		__attribute__(( aligned (16) )) static const unsigned int masklo[4] =
				{ 0x00007FFF, 0x00007FFF, 0x00007FFF, 0x00007FFF };
		adder = _mm_load_si128( (__m128i*) gadd);
		multiplier = _mm_load_si128( (__m128i*) mult);
		mod_mask = _mm_load_si128( (__m128i*) mask);
		sra_mask = _mm_load_si128( (__m128i*) masklo);
		cur_seed_split = _mm_shuffle_epi32( cur_seed, _MM_SHUFFLE( 2, 3, 0, 1 ) );
		cur_seed = _mm_mul_epu32( cur_seed, multiplier );
		multiplier = _mm_shuffle_epi32( multiplier, _MM_SHUFFLE( 2, 3, 0, 1 ) );
		cur_seed_split = _mm_mul_epu32( cur_seed_split, multiplier );
		cur_seed = _mm_and_si128( cur_seed, mod_mask);
		cur_seed_split = _mm_and_si128( cur_seed_split, mod_mask );
		cur_seed_split = _mm_shuffle_epi32( cur_seed_split, _MM_SHUFFLE( 2, 3, 0, 1 ) );
		cur_seed = _mm_or_si128( cur_seed, cur_seed_split );
		cur_seed = _mm_add_epi32( cur_seed, adder);
		#ifdef COMPATABILITY
		// Add the lines below if you wish to reduce your results to 16-bit vals...
		sseresult = _mm_srai_epi32( cur_seed, 16);
		sseresult = _mm_and_si128( sseresult, sra_mask );
		_mm_storeu_si128( (__m128i*) result, sseresult );
		return;
		#endif
		_mm_storeu_si128( (__m128i*) result, cur_seed);
		return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1d0, %rsp            # imm = 0x1D0
movq %rdi, -0x148(%rbp)
leaq 0x21f7(%rip), %rax      # 0xdb40
movq %rax, -0x128(%rbp)
movq -0x128(%rbp), %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x180(%rbp)
leaq 0x21c8(%rip), %rax      # 0xdb30
movq %rax, -0x130(%rbp)
movq -0x130(%rbp), %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x170(%rbp)
leaq 0x21c9(%rip), %rax      # 0xdb50
movq %rax, -0x138(%rbp)
movq -0x138(%rbp), %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x190(%rbp)
leaq 0x21ba(%rip), %rax      # 0xdb60
movq %rax, -0x140(%rbp)
movq -0x140(%rbp), %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x1a0(%rbp)
leaq 0x5503(%rip), %rdi      # 0x10ec8
callq 0x5850
movaps 0x10(%rax), %xmm0
pshufd $0xb1, %xmm0, %xmm0     # xmm0 = xmm0[1,0,3,2]
movaps %xmm0, -0x160(%rbp)
movaps 0x10(%rax), %xmm1
movaps -0x170(%rbp), %xmm0
movaps %xmm1, -0xf0(%rbp)
movaps %xmm0, -0x100(%rbp)
movaps -0xf0(%rbp), %xmm0
movaps -0x100(%rbp), %xmm1
pmuludq %xmm1, %xmm0
movaps %xmm0, 0x10(%rax)
movaps -0x170(%rbp), %xmm0
pshufd $0xb1, %xmm0, %xmm0     # xmm0 = xmm0[1,0,3,2]
movaps %xmm0, -0x170(%rbp)
movaps -0x160(%rbp), %xmm1
movaps -0x170(%rbp), %xmm0
movaps %xmm1, -0x110(%rbp)
movaps %xmm0, -0x120(%rbp)
movaps -0x110(%rbp), %xmm0
movaps -0x120(%rbp), %xmm1
pmuludq %xmm1, %xmm0
movaps %xmm0, -0x160(%rbp)
movaps 0x10(%rax), %xmm1
movaps -0x190(%rbp), %xmm0
movaps %xmm1, -0x90(%rbp)
movaps %xmm0, -0xa0(%rbp)
movaps -0x90(%rbp), %xmm0
movaps -0xa0(%rbp), %xmm1
pand %xmm1, %xmm0
movaps %xmm0, 0x10(%rax)
movaps -0x160(%rbp), %xmm1
movaps -0x190(%rbp), %xmm0
movaps %xmm1, -0xb0(%rbp)
movaps %xmm0, -0xc0(%rbp)
movaps -0xb0(%rbp), %xmm0
movaps -0xc0(%rbp), %xmm1
pand %xmm1, %xmm0
movaps %xmm0, -0x160(%rbp)
movaps -0x160(%rbp), %xmm0
pshufd $0xb1, %xmm0, %xmm0     # xmm0 = xmm0[1,0,3,2]
movdqa %xmm0, -0x160(%rbp)
leaq 0x53e9(%rip), %rdi      # 0x10ec8
callq 0x5850
leaq 0x10(%rax), %rax
movdqa (%rax), %xmm1
movdqa -0x160(%rbp), %xmm0
movdqa %xmm1, -0x70(%rbp)
movdqa %xmm0, -0x80(%rbp)
movdqa -0x70(%rbp), %xmm0
por -0x80(%rbp), %xmm0
movaps %xmm0, -0x1d0(%rbp)
leaq 0x53af(%rip), %rdi      # 0x10ec8
callq 0x5850
movaps -0x1d0(%rbp), %xmm0
leaq 0x10(%rax), %rax
movdqa %xmm0, (%rax)
leaq 0x5391(%rip), %rdi      # 0x10ec8
callq 0x5850
leaq 0x10(%rax), %rax
movdqa (%rax), %xmm1
movdqa -0x180(%rbp), %xmm0
movdqa %xmm1, -0x50(%rbp)
movdqa %xmm0, -0x60(%rbp)
movdqa -0x50(%rbp), %xmm0
movdqa -0x60(%rbp), %xmm1
paddd %xmm1, %xmm0
movaps %xmm0, -0x1c0(%rbp)
leaq 0x5353(%rip), %rdi      # 0x10ec8
callq 0x5850
movaps -0x1c0(%rbp), %xmm0
leaq 0x10(%rax), %rax
movdqa %xmm0, (%rax)
leaq 0x5335(%rip), %rdi      # 0x10ec8
callq 0x5850
leaq 0x10(%rax), %rax
movdqa (%rax), %xmm0
movdqa %xmm0, -0x30(%rbp)
movl $0x10, -0x34(%rbp)
movdqa -0x30(%rbp), %xmm0
movl -0x34(%rbp), %eax
movd %eax, %xmm1
psrad %xmm1, %xmm0
movdqa %xmm0, -0x1b0(%rbp)
movdqa -0x1b0(%rbp), %xmm1
movdqa -0x1a0(%rbp), %xmm0
movdqa %xmm1, -0xd0(%rbp)
movdqa %xmm0, -0xe0(%rbp)
movdqa -0xd0(%rbp), %xmm0
pand -0xe0(%rbp), %xmm0
movdqa %xmm0, -0x1b0(%rbp)
movq -0x148(%rbp), %rax
movdqa -0x1b0(%rbp), %xmm0
movq %rax, -0x8(%rbp)
movdqa %xmm0, -0x20(%rbp)
movdqa -0x20(%rbp), %xmm0
movq -0x8(%rbp), %rax
movdqu %xmm0, (%rax)
addq $0x1d0, %rsp            # imm = 0x1D0
popq %rbp
retq