// File: sergiosvieira[P]ptd2ns2/rng.cc
// Function: RNG::set_seed(RNG::RNGSources, int)
void RNG::set_seed(RNGSources source, int seed) {
	/* The following predefined seeds are evenly spaced around
	 * the 2^31 cycle.  Each is approximately 33,000,000 elements
	 * apart.
	 */
#define N_SEEDS_ 64
	static long predef_seeds[N_SEEDS_] = { 1973272912L, 188312339L,
			1072664641L, 694388766L, 2009044369L, 934100682L, 1972392646L,
			1936856304L, 1598189534L, 1822174485L, 1871883252L, 558746720L,
			605846893L, 1384311643L, 2081634991L, 1644999263L, 773370613L,
			358485174L, 1996632795L, 1000004583L, 1769370802L, 1895218768L,
			186872697L, 1859168769L, 349544396L, 1996610406L, 222735214L,
			1334983095L, 144443207L, 720236707L, 762772169L, 437720306L,
			939612284L, 425414105L, 1998078925L, 981631283L, 1024155645L,
			822780843L, 701857417L, 960703545L, 2101442385L, 2125204119L,
			2041095833L, 89865291L, 898723423L, 1859531344L, 764283187L,
			1349341884L, 678622600L, 778794064L, 1319566104L, 1277478588L,
			538474442L, 683102175L, 999157082L, 985046914L, 722594620L,
			1695858027L, 1700738670L, 1995749838L, 1147024708L, 346983590L,
			565528207L, 513791680L };
	static long heuristic_sequence = 0;

	switch (source) {
	case RAW_SEED_SOURCE:
		if (seed <= 0 || (unsigned int) seed >= MAXINT) // Wei Ye
			abort();
		// use it as it is
		break;
	case PREDEF_SEED_SOURCE:
		if (seed < 0 || seed >= N_SEEDS_)
			abort();
		seed = predef_seeds[seed];
		break;
	case HEURISTIC_SEED_SOURCE:
		timeval tv;
		gettimeofday(&tv, 0);
		heuristic_sequence++; // Always make sure we're different than last time.
		seed = (tv.tv_sec ^ tv.tv_usec ^ (heuristic_sequence << 8))
				& 0x7fffffff;
		break;
	};
	// set it
	// NEEDSWORK: should we throw out known bad seeds?
	// (are there any?)
	if (seed < 0)
		seed = -seed;
#ifdef OLD_RNG
	stream_.set_seed(seed);
#else
	set_seed(seed);
#endif /* OLD_RNG */

	// Toss away the first few values of heuristic seed.
	// In practice this makes sequential heuristic seeds
	// generate different first values.
	//
	// How many values to throw away should be the subject
	// of careful analysis.  Until then, I just throw away
	// ``a bunch''.  --johnh
	if (source == HEURISTIC_SEED_SOURCE) {
		int i;
		for (i = 0; i < 128; i++) {
#ifdef OLD_RNG			
			stream_.next();
#else
			next();
#endif /* OLD_RNG */
		};
	};
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x30(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x28(%rbp)
testl %eax, %eax
je 0x738a
jmp 0x7376
movl -0x28(%rbp), %eax
subl $0x1, %eax
je 0x73a0
jmp 0x7380
movl -0x28(%rbp), %eax
subl $0x2, %eax
je 0x73c5
jmp 0x7403
cmpl $0x0, -0x10(%rbp)
jle 0x7399
cmpl $0x7fffffff, -0x10(%rbp) # imm = 0x7FFFFFFF
jb 0x739e
callq 0x3100
jmp 0x7403
cmpl $0x0, -0x10(%rbp)
jl 0x73ac
cmpl $0x40, -0x10(%rbp)
jl 0x73b1
callq 0x3100
movslq -0x10(%rbp), %rcx
leaq 0x7ed4(%rip), %rax      # 0xf290
movq (%rax,%rcx,8), %rax
movl %eax, -0x10(%rbp)
jmp 0x7403
leaq -0x20(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3300
movq 0x8127(%rip), %rax      # 0xf500
addq $0x1, %rax
movq %rax, 0x811c(%rip)      # 0xf500
movq -0x20(%rbp), %rax
xorq -0x18(%rbp), %rax
movq 0x810d(%rip), %rcx      # 0xf500
shlq $0x8, %rcx
xorq %rcx, %rax
andq $0x7fffffff, %rax       # imm = 0x7FFFFFFF
movl %eax, -0x10(%rbp)
cmpl $0x0, -0x10(%rbp)
jge 0x7411
xorl %eax, %eax
subl -0x10(%rbp), %eax
movl %eax, -0x10(%rbp)
movq -0x30(%rbp), %rdi
movslq -0x10(%rbp), %rsi
callq 0x7450
cmpl $0x2, -0xc(%rbp)
jne 0x744a
movl $0x0, -0x24(%rbp)
cmpl $0x80, -0x24(%rbp)
jge 0x7448
movq -0x30(%rbp), %rdi
callq 0x74e0
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x742b
jmp 0x744a
addq $0x30, %rsp
popq %rbp
retq