// File: /workspace/github_c_makefile_star2_O1/tvlabs[P]edge264/./edge264_bitstream.c
// Function: get_bytes
static inline size_t get_bytes(Edge264GetBits *gb, int nbytes)
{
	static const i8x16 shuf[8] = {
		{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1},
		{0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1},
		{0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1},
		{0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1},
		{0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1},
		{0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1},
		{0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1},
		{0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, -1},
	};
	
	// load 16 bytes without reading past aligned buffer boundaries
	const uint8_t *CPB = gb->CPB;
	const uint8_t *end = gb->end;
	intptr_t diff = CPB - end;
	u8x16 v;
	if (__builtin_expect(diff <= -14, 1)) {
		v = load128(CPB - 2);
	} else if (diff < 0) {
		const uint8_t *p = minp(CPB - 2, (uint8_t *)((uintptr_t)(end - 1) & -16));
		v = shrv128(shlv128(load128(p), p + 16 - end), min(14 + diff, 16));
	} else {
		gb->CPB = CPB + nbytes;
		return 0;
	}
	
	// make a bitmask for the positions of 00n escape sequences and iterate on it
	u8x16 eq0 = v == 0;
	u8x16 x = shr128(v, 2);
	#if defined(__SSE2__)
		unsigned esc = movemask(eq0 & shr128(eq0, 1) & (x <= 3));
		if (__builtin_expect(esc, 0)) {
			while (esc & ((1 << nbytes) - 1)) {
				int i = __builtin_ctz(esc);
				esc = (esc & (esc - 1)) >> 1;
				if (CPB[i] <3) { // delimiter sequence, set end to its first byte
					gb->end = CPB + i - 2;
					x &= ~shlv128(set8(-1), i);
					break; // we cannot iterate more since now x differs from esc
				}
				// otherwise this is an emulation_prevention_three_byte -> remove it
				x = shuffle(x, shuf[i]);
				CPB++;
			}
		}
	#elif defined(__ARM_NEON)
		uint64_t esc = (uint64_t)vshrn_n_u16(eq0 & shr128(eq0, 1) & (x <= 3), 4);
		if (__builtin_expect(esc, 0)) {
			esc &= 0x8888888888888888ULL;
			while (esc & ((1ULL << (nbytes << 2)) - 1)) {
				int i = __builtin_ctzll(esc) >> 2;
				esc = (esc & (esc - 1)) >> 4;
				if (CPB[i] <3) { // delimiter sequence, set end to its first byte
					gb->end = CPB + i - 2;
					x &= ~shlv128(set8(-1), i);
					break; // we cannot iterate more since now x differs from esc
				}
				// otherwise this is an emulation_prevention_three_byte -> remove it
				x = shuffle(x, shuf[i]);
				CPB++;
			}
		}
	#endif
	
	// increment CPB and return the requested bytes in upper part of the result
	gb->CPB = CPB + nbytes;
	#if SIZE_BIT == 32
		return big_endian32(((i32x4)x)[0]);
	#elif SIZE_BIT == 64
		return big_endian64(((i64x2)x)[0]);
	#endif
}

// Assembly:
pushq %rbx
movq (%rdi), %rax
movq 0x8(%rdi), %rdx
movq %rax, %rcx
subq %rdx, %rcx
cmpq $-0xe, %rcx
jg 0x16e0f
vmovdqu -0x2(%rax), %xmm1
vpxor %xmm0, %xmm0, %xmm0
vpcmpeqb %xmm0, %xmm1, %xmm2
vpsrldq $0x2, %xmm1, %xmm0      # xmm0 = xmm1[2,3,4,5,6,7,8,9,10,11,12,13,14,15],zero,zero
vpsrldq $0x1, %xmm2, %xmm2      # xmm2 = xmm2[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],zero
vpbroadcastb 0x1cdb8(%rip), %xmm3 # 0x33b9c
vpcmpltub %xmm3, %xmm0, %k1
vptestnmb %xmm1, %xmm1, %k0 {%k1}
vpmovb2m %xmm2, %k1
ktestw %k1, %k0
jne 0x16e24
movl %esi, %ecx
addq %rax, %rcx
movq %rcx, (%rdi)
vmovq %xmm0, %rax
bswapq %rax
popq %rbx
retq
testq %rcx, %rcx
js 0x16ea6
movl %esi, %ecx
addq %rcx, %rax
movq %rax, (%rdi)
xorl %eax, %eax
jmp 0x16e0d
kandw %k1, %k0, %k0
kmovd %k0, %ecx
movzwl %cx, %edx
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
shlxl %esi, %ecx, %ecx
notl %ecx
leaq 0x200ee(%rip), %r8      # 0x36f30
leaq 0x1d2e7(%rip), %r9      # 0x34130
vpcmpeqd %xmm1, %xmm1, %xmm1
testl %ecx, %edx
je 0x16dfd
tzcntl %edx, %r11d
movb (%rax,%r11), %r10b
cmpb $0x2, %r10b
jbe 0x16e6f
shll $0x4, %r11d
vpshufb (%r11,%r8), %xmm0, %xmm0
incq %rax
jmp 0x16e8b
leaq (%rax,%r11), %rbx
addq $-0x2, %rbx
movq %rbx, 0x8(%rdi)
movq %r9, %rbx
subq %r11, %rbx
vpshufb 0x10(%rbx), %xmm1, %xmm2
vpandn %xmm0, %xmm2, %xmm0
leal 0x7fffffff(%rdx), %r11d
andl %edx, %r11d
shrl %r11d
movl %r11d, %edx
cmpb $0x2, %r10b
ja 0x16e4d
jmp 0x16dfd
leaq -0x2(%rax), %r8
leaq -0x1(%rdx), %r9
andq $-0x10, %r9
cmpq %r9, %r8
cmovsq %r8, %r9
vmovdqu (%r9), %xmm0
subq %r9, %rdx
leaq 0x1d268(%rip), %r8      # 0x34130
vpshufb (%rdx,%r8), %xmm0, %xmm0
addl $0xe, %ecx
cmpl $0x10, %ecx
movl $0x10, %edx
cmovll %ecx, %edx
movslq %edx, %rcx
vpshufb 0x10(%rcx,%r8), %xmm0, %xmm1
jmp 0x16dc9