// File: tonymugen[P]sampleSNPs/random.cpp
// Function: sampFiles::RanDraw::RanDraw()
RanDraw::RanDraw(){
	string error;
	
	unsigned int eax;
	unsigned int ebx;
	unsigned int ecx;
	unsigned int edx;
	
	unsigned int leaf    = 0;
	unsigned int subleaf = 0;
	
	// first look at vendor info
	asm volatile ("cpuid;"
				  : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
				  : "a" (leaf), "c" (subleaf)
				  );
	
	if ( !(
		(memcmp(reinterpret_cast<char*>(&ebx), "Genu", 4) && memcmp(reinterpret_cast<char*>(&edx), "ineI", 4) && memcmp(reinterpret_cast<char*>(&ecx), "ntel", 4)) ||
		(memcmp(reinterpret_cast<char*>(&ebx), "Auth", 4) && memcmp(reinterpret_cast<char*>(&edx), "enti", 4) && memcmp(reinterpret_cast<char*>(&ecx), "cAMD", 4))
		)) {
		error = "CPU_unsupported";
		throw error;
	}
	
	
	// now test for RDRAND. bit 30 of ECX when CPUINFO invoked with EAX set to 01H
	leaf = 0x1;
	asm volatile ("cpuid;"
				  : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
				  : "a" (leaf), "c" (subleaf)
				  );
	
	if ( (ecx & 0x40000000) == 0x40000000) { // bit mask 0x40000000 for the 30th bit
		_rng = new GenerateHR(); // have hardware random numbers
	} else {
		_rng = new GenerateMT(); // use MT
	}

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
subq $0x78, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x60(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x44d0
movl $0x0, -0x44(%rbp)
movl $0x0, -0x48(%rbp)
movl -0x44(%rbp), %eax
movl -0x48(%rbp), %ecx
cpuid
movl %eax, -0x34(%rbp)
movl %ebx, -0x38(%rbp)
movl %ecx, -0x3c(%rbp)
movl %edx, -0x40(%rbp)
movl -0x38(%rbp), %eax
subl $0x756e6547, %eax       # imm = 0x756E6547
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x223fd
movl -0x40(%rbp), %eax
subl $0x49656e69, %eax       # imm = 0x49656E69
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x223fd
movl -0x3c(%rbp), %eax
subl $0x6c65746e, %eax       # imm = 0x6C65746E
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x2248f
movl -0x38(%rbp), %eax
subl $0x68747541, %eax       # imm = 0x68747541
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x22436
movl -0x40(%rbp), %eax
subl $0x69746e65, %eax       # imm = 0x69746E65
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x22436
movl -0x3c(%rbp), %eax
subl $0x444d4163, %eax       # imm = 0x444D4163
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x2248f
leaq 0x1d1f(%rip), %rsi      # 0x2415c
leaq -0x30(%rbp), %rdi
callq 0x44c0
jmp 0x22448
movl $0x20, %edi
callq 0x4180
movq %rax, %rdi
movq %rdi, -0x68(%rbp)
leaq -0x30(%rbp), %rsi
callq 0x41d0
movq -0x68(%rbp), %rdi
leaq 0x9423(%rip), %rsi      # 0x2b890
movq 0x9b44(%rip), %rdx      # 0x2bfb8
callq 0x45c0
jmp 0x22563
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x22551
movl $0x1, -0x44(%rbp)
movl -0x44(%rbp), %eax
movl -0x48(%rbp), %ecx
cpuid
movl %eax, -0x34(%rbp)
movl %ebx, -0x38(%rbp)
movl %ecx, -0x3c(%rbp)
movl %edx, -0x40(%rbp)
movl -0x3c(%rbp), %eax
andl $0x40000000, %eax       # imm = 0x40000000
cmpl $0x40000000, %eax       # imm = 0x40000000
jne 0x224fd
movl $0x8, %edi
callq 0x4330
movq %rax, -0x70(%rbp)
jmp 0x224c9
movq -0x70(%rbp), %rdi
callq 0x22c70
jmp 0x224d4
movq -0x60(%rbp), %rax
movq -0x70(%rbp), %rcx
movq %rcx, (%rax)
jmp 0x22541
movq -0x70(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
movl $0x8, %esi
callq 0x4340
jmp 0x22551
movl $0x9d8, %edi            # imm = 0x9D8
callq 0x4330
movq %rax, -0x78(%rbp)
jmp 0x2250d
movq -0x78(%rbp), %rdi
callq 0x22030
jmp 0x22518
movq -0x60(%rbp), %rax
movq -0x78(%rbp), %rcx
movq %rcx, (%rax)
jmp 0x22541
movq -0x78(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
movl $0x9d8, %esi            # imm = 0x9D8
callq 0x4340
jmp 0x22551
leaq -0x30(%rbp), %rdi
callq 0x46d8
addq $0x78, %rsp
popq %rbx
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0x46d8
movq -0x50(%rbp), %rdi
callq 0x4610
nopw %cs:(%rax,%rax)