// File: /workspace/github_cpp_makefile_star2_O2/Alcaro[P]bridges/arlib/base64dec.cpp
// Function: base64_dec_raw(arrayvieww<unsigned char>, cstring)
size_t base64_dec_raw(arrayvieww<uint8_t> out, cstring text)
{
	uint8_t * outptr = out.ptr();
	const char * in = (char*)text.bytes().ptr();
	const char * inend = in + text.length();
	
	int final_chunk = 3;
	const char * in_real;
	
	while (in <= inend-4)
	{
		uint8_t c1 = in[0];
		uint8_t c2 = in[1];
		uint8_t c3 = in[2];
		uint8_t c4 = in[3];
		if (UNLIKELY((c1|c2|c3|c4) >= 0x80)) return 0;
		c1 = decode[c1];
		c2 = decode[c2];
		c3 = decode[c3];
		c4 = decode[c4];
		in += 4;
		
	space_again:
		if (UNLIKELY((c1|c2|c3|c4) >= 0x80))
		{
			if ((c1|c2|c3|c4) == SP)
			{
				if (in == inend) return 0;
				if (c1 == SP) { c1 = c2; c2 = SP; }
				if (c2 == SP) { c2 = c3; c3 = SP; }
				if (c3 == SP) { c3 = c4; c4 = SP; }
				c4 = *in++;
				if (c4 & 0x80) return 0;
				c4 = decode[c4];
				goto space_again;
			}
			if (c4 == PA)
			{
				in_real = in; // some goofy tricks to get a few instructions out of the fast path
				in = inend;
				final_chunk = 2;
				c4 = 0;
				if (c3 == PA)
				{
					final_chunk = 1;
					c3 = 0;
					if (c2&15) return 0; // reject padded data where the bits of the partial byte aren't zero
				}
				if (c3&3) return 0;
			}
			
			if ((c1|c2|c3|c4) >= 0x80) return 0;
		}
		
		uint32_t outraw = (c1<<18) | (c2<<12) | (c3<<6) | (c4<<0);
		outptr[0] = outraw>>16;
		outptr[1] = outraw>>8;
		outptr[2] = outraw>>0;
		outptr += 3;
	}
	
	if (final_chunk != 3)
	{
		in = in_real;
		outptr = outptr-3 + final_chunk;
	}
	while (in < inend && (uint8_t)*in < 0x80 && decode[(uint8_t)*in] == SP) in++;
	
	if (in != inend) return 0;
	return outptr-out.ptr();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
leaq -0x10(%rsp), %rax
movq %rsi, (%rax)
movq %rdx, 0x8(%rax)
movq %rdx, %rcx
shrq $0x38, %rcx
xorl $0xf, %ecx
testq %rdx, %rdx
cmovnsq %rax, %rsi
movq %rdi, -0x18(%rsp)
movq (%rdi), %rbx
cmovsq %rdx, %rcx
movl %ecx, %eax
leaq (%rsi,%rax), %r12
leaq (%rsi,%rax), %r8
addq $-0x4, %r8
movl $0x3, %eax
movl %eax, -0x1c(%rsp)
xorl %eax, %eax
leaq 0x23a11(%rip), %r11     # 0x28180
cmpq %r8, %rsi
ja 0x48b1
movzbl (%rsi), %ecx
movzbl 0x1(%rsi), %edx
movzbl 0x2(%rsi), %r10d
movb 0x3(%rsi), %r9b
movl %edx, %edi
orl %ecx, %edi
orb %r10b, %dil
orb %r9b, %dil
js 0x48f2
movb (%rcx,%r11), %cl
movb (%rdx,%r11), %bpl
movb (%r10,%r11), %r15b
addq $0x4, %rsi
movzbl %r9b, %edx
movb (%rdx,%r11), %r13b
movzbl %cl, %r10d
movzbl %bpl, %edx
movl %edx, %ecx
orl %r10d, %ecx
movl %r13d, %edi
orb %r15b, %dil
movzbl %dil, %edi
orl %ecx, %edi
cmpl $0x80, %edi
jb 0x4885
cmpl $0xff, %edi
jne 0x4825
cmpq %r12, %rsi
je 0x48f2
movl $0xff, %r9d
cmpl %r9d, %r10d
movl %r10d, %ecx
cmovel %edx, %ecx
cmovel %r10d, %edx
cmpb $-0x1, %dl
movzbl %r15b, %edi
cmovel %edi, %edx
cmovel %r9d, %edi
cmpb $-0x1, %dil
movzbl %r13b, %r15d
cmovnel %edi, %r15d
movb (%rsi), %r9b
incq %rsi
movl %edx, %ebp
testb %r9b, %r9b
jns 0x47a8
jmp 0x48f2
cmpb $0x3d, %r9b
jne 0x4851
cmpb $-0x7f, %r15b
jne 0x4859
xorl %r15d, %r15d
movq %r12, %r9
movl $0x1, %edi
movl %edi, -0x1c(%rsp)
movl $0x0, %r13d
testb $0xf, %bpl
je 0x486e
jmp 0x48e6
movq %rsi, %r9
movq %r14, %rsi
jmp 0x486e
xorl %r13d, %r13d
movq %r12, %r9
movl $0x2, %edi
movl %edi, -0x1c(%rsp)
testb $0x3, %r15b
jne 0x48e6
movq %rsi, %r14
movl %r13d, %esi
orb %r15b, %sil
movzbl %sil, %esi
orl %esi, %ecx
movq %r9, %rsi
cmpl $0x7f, %ecx
ja 0x48f2
shll $0x12, %r10d
shll $0xc, %edx
orl %edx, %r10d
movzbl %r15b, %ecx
shll $0x6, %ecx
orl %ecx, %edx
shrl $0x10, %r10d
movb %r10b, (%rbx)
movb %dh, 0x1(%rbx)
orb %r13b, %cl
movb %cl, 0x2(%rbx)
addq $0x3, %rbx
jmp 0x476f
movl -0x1c(%rsp), %eax
cmpl $0x3, %eax
movl %eax, %eax
leaq -0x3(%rbx,%rax), %rax
cmoveq %rsi, %r14
cmoveq %rbx, %rax
cmpq %r12, %r14
jae 0x48e1
movsbq (%r14), %rcx
testq %rcx, %rcx
js 0x48e1
cmpb $-0x1, (%rcx,%r11)
jne 0x48e1
incq %r14
jmp 0x48c7
cmpq %r12, %r14
je 0x48ea
xorl %eax, %eax
jmp 0x48f2
movq -0x18(%rsp), %rcx
subq (%rcx), %rax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq