// File: JMMackenzie[P]binary_to_jass/compress_integer_elias_gamma_simd_vb.cpp
// Function: JASS::compress_integer_elias_gamma_simd_vb::decode(unsigned int*, unsigned long, void const*, unsigned long)
void compress_integer_elias_gamma_simd_vb::decode(integer *decoded, size_t integers_to_decode, const void *source_as_void, size_t source_length)
		{
		__m256i mask;
		const uint8_t *source = (const uint8_t *)source_as_void;
		size_t vb_length = *(const uint32_t *)source_as_void;
		const uint8_t *end_of_source = (const uint8_t *)source_as_void + source_length - vb_length;
		source += sizeof(uint32_t);
		__m256i *into = (__m256i *)decoded;
		uint64_t selector = 0;
		__m256i payload1;
		__m256i payload2;

		while (1)
			{
			if (selector == 0)
				{
				if (source >= end_of_source)
					break;
				selector = *(uint32_t *)source;
				payload1 = _mm256_loadu_si256((__m256i *)(source + 4));
				payload2 = _mm256_loadu_si256((__m256i *)(source + 36));
				source += 68;
				}

			uint32_t width = (uint32_t)find_first_set_bit(selector);
			mask = _mm256_loadu_si256((__m256i *)mask_set[width]);
			_mm256_storeu_si256(into, _mm256_and_si256(payload1, mask));
			_mm256_storeu_si256(into + 1, _mm256_and_si256(payload2, mask));
			payload1 = _mm256_srli_epi32(payload1, width);
			payload2 = _mm256_srli_epi32(payload2, width);

			into += 2;
			selector >>= width;
			}

		if (vb_length != 0)
			compress_integer_variable_byte::decode((integer *)into, vb_length, source, vb_length);
		}

// Assembly:
pushq %rbp
movq %rsp, %rbp
andq $-0x20, %rsp
subq $0x2a0, %rsp            # imm = 0x2A0
movq %rdi, 0xe0(%rsp)
movq %rsi, 0xd8(%rsp)
movq %rdx, 0xd0(%rsp)
movq %rcx, 0xc8(%rsp)
movq %r8, 0xc0(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0xc8(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0xc8(%rsp), %rax
movl (%rax), %eax
movq %rax, 0x90(%rsp)
movq 0xc8(%rsp), %rax
addq 0xc0(%rsp), %rax
xorl %ecx, %ecx
subq 0x90(%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x88(%rsp)
movq 0x98(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x98(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x80(%rsp)
movq $0x0, 0x78(%rsp)
cmpq $0x0, 0x78(%rsp)
jne 0x3017aa
movq 0x98(%rsp), %rax
cmpq 0x88(%rsp), %rax
jb 0x30173b
jmp 0x30194e
movq 0x98(%rsp), %rax
movl (%rax), %eax
movq %rax, 0x78(%rsp)
movq 0x98(%rsp), %rax
addq $0x4, %rax
movq %rax, 0xf8(%rsp)
movq 0xf8(%rsp), %rax
vmovdqu (%rax), %ymm0
vmovdqa %ymm0, 0x40(%rsp)
movq 0x98(%rsp), %rax
addq $0x24, %rax
movq %rax, 0xf0(%rsp)
movq 0xf0(%rsp), %rax
vmovdqu (%rax), %ymm0
vmovdqa %ymm0, 0x20(%rsp)
movq 0x98(%rsp), %rax
addq $0x44, %rax
movq %rax, 0x98(%rsp)
movq 0x78(%rsp), %rdi
vzeroupper
callq 0x301a00
movl %eax, 0x1c(%rsp)
movl 0x1c(%rsp), %eax
movl %eax, %ecx
leaq 0x2d78(%rip), %rax      # 0x304540
shlq $0x6, %rcx
addq %rcx, %rax
movq %rax, 0xe8(%rsp)
movq 0xe8(%rsp), %rax
vmovdqu (%rax), %ymm0
vmovdqa %ymm0, 0xa0(%rsp)
movq 0x80(%rsp), %rax
vmovdqa 0x40(%rsp), %ymm1
vmovdqa 0xa0(%rsp), %ymm0
vmovdqa %ymm1, 0x1e0(%rsp)
vmovdqa %ymm0, 0x1c0(%rsp)
vmovdqa 0x1e0(%rsp), %ymm0
vpand 0x1c0(%rsp), %ymm0, %ymm0
movq %rax, 0x178(%rsp)
vmovdqa %ymm0, 0x140(%rsp)
vmovdqa 0x140(%rsp), %ymm0
movq 0x178(%rsp), %rax
vmovdqu %ymm0, (%rax)
movq 0x80(%rsp), %rax
addq $0x20, %rax
vmovdqa 0x20(%rsp), %ymm1
vmovdqa 0xa0(%rsp), %ymm0
vmovdqa %ymm1, 0x1a0(%rsp)
vmovdqa %ymm0, 0x180(%rsp)
vmovdqa 0x1a0(%rsp), %ymm0
vpand 0x180(%rsp), %ymm0, %ymm0
movq %rax, 0x138(%rsp)
vmovdqa %ymm0, 0x100(%rsp)
vmovdqa 0x100(%rsp), %ymm0
movq 0x138(%rsp), %rax
vmovdqu %ymm0, (%rax)
vmovdqa 0x40(%rsp), %ymm0
movl 0x1c(%rsp), %eax
vmovdqa %ymm0, 0x260(%rsp)
movl %eax, 0x25c(%rsp)
vmovdqa 0x260(%rsp), %ymm0
movl 0x25c(%rsp), %eax
vmovd %eax, %xmm1
vpsrld %xmm1, %ymm0, %ymm0
vmovdqa %ymm0, 0x40(%rsp)
vmovdqa 0x20(%rsp), %ymm0
movl 0x1c(%rsp), %eax
vmovdqa %ymm0, 0x220(%rsp)
movl %eax, 0x21c(%rsp)
vmovdqa 0x220(%rsp), %ymm0
movl 0x21c(%rsp), %eax
vmovd %eax, %xmm1
vpsrld %xmm1, %ymm0, %ymm0
vmovdqa %ymm0, 0x20(%rsp)
movq 0x80(%rsp), %rax
addq $0x40, %rax
movq %rax, 0x80(%rsp)
movl 0x1c(%rsp), %ecx
movq 0x78(%rsp), %rax
movl %ecx, %ecx
shrq %cl, %rax
movq %rax, 0x78(%rsp)
jmp 0x301718
cmpq $0x0, 0x90(%rsp)
je 0x301986
movq 0x10(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x90(%rsp), %rdx
movq 0x98(%rsp), %rcx
movq 0x90(%rsp), %r8
vzeroupper
callq 0x301a30
movq %rbp, %rsp
popq %rbp
vzeroupper
retq
nop