// File: /workspace/github_c_makefile_star2_O3/Seclabs-htc[P]slip39/trezor-crypto/sha2.c
// Function: sha512_Update
void sha512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
	unsigned int	freespace, usedspace;

	if (len == 0) {
		/* Calling with no data is valid - we do nothing */
		return;
	}

	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
	if (usedspace > 0) {
		/* Calculate how much free space is available in the buffer */
		freespace = SHA512_BLOCK_LENGTH - usedspace;

		if (len >= freespace) {
			/* Fill the buffer completely and process it */
			MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace);
			ADDINC128(context->bitcount, freespace << 3);
			len -= freespace;
			data += freespace;
#if BYTE_ORDER == LITTLE_ENDIAN
			/* Convert TO host byte order */
			for (int j = 0; j < 16; j++) {
				REVERSE64(context->buffer[j],context->buffer[j]);
			}
#endif
			sha512_Transform(context->state, context->buffer, context->state);
		} else {
			/* The buffer is not yet full */
			MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len);
			ADDINC128(context->bitcount, len << 3);
			/* Clean up: */
			usedspace = freespace = 0;
			return;
		}
	}
	while (len >= SHA512_BLOCK_LENGTH) {
		/* Process as many complete blocks as we can */
		MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH);
#if BYTE_ORDER == LITTLE_ENDIAN
		/* Convert TO host byte order */
		for (int j = 0; j < 16; j++) {
			REVERSE64(context->buffer[j],context->buffer[j]);
		}
#endif
		sha512_Transform(context->state, context->buffer, context->state);
		ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
		len -= SHA512_BLOCK_LENGTH;
		data += SHA512_BLOCK_LENGTH;
	}
	if (len > 0) {
		/* There's left-overs, so save 'em */
		MEMCPY_BCOPY(context->buffer, data, len);
		ADDINC128(context->bitcount, len << 3);
	}
	/* Clean up: */
	usedspace = freespace = 0;
}

// Assembly:
testq %rdx, %rdx
je 0x97f6
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %r13
movq %rsi, %r14
movq %rdi, %rbx
movl 0x40(%rdi), %eax
shrl $0x3, %eax
andl $0x7f, %eax
je 0x970c
movl $0x80, %r12d
subl %eax, %r12d
movq %r13, %r15
movl %eax, %eax
leaq (%rbx,%rax), %rdi
addq $0x50, %rdi
subq %r12, %r15
jae 0x9711
movq %r14, %rsi
movq %r13, %rdx
callq 0x8080
shlq $0x3, %r13
addq %r13, 0x40(%rbx)
jb 0x97e4
jmp 0x97e8
movq %r13, %r15
jmp 0x9759
movq %r14, %rsi
movq %r12, %rdx
callq 0x8080
leal (,%r12,8), %eax
addq %rax, 0x40(%rbx)
jae 0x972e
incq 0x48(%rbx)
leaq 0x50(%rbx), %rsi
movl $0xa, %eax
movq (%rbx,%rax,8), %rcx
bswapq %rcx
movq %rcx, (%rbx,%rax,8)
incq %rax
cmpq $0x1a, %rax
jne 0x9737
addq %r12, %r14
movq %rbx, %rdi
movq %rbx, %rdx
callq 0x9449
cmpq $0x80, %r15
jb 0x97c6
leaq 0x50(%rbx), %r12
movl $0x80, %edx
movq %r12, %rdi
movq %r14, %rsi
callq 0x8080
movl $0xa, %eax
movq (%rbx,%rax,8), %rcx
bswapq %rcx
movq %rcx, (%rbx,%rax,8)
incq %rax
cmpq $0x1a, %rax
jne 0x977b
movq %rbx, %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x9449
movq 0x40(%rbx), %rax
leaq 0x400(%rax), %rcx
movq %rcx, 0x40(%rbx)
cmpq $-0x401, %rax           # imm = 0xFBFF
jbe 0x97b8
incq 0x48(%rbx)
addq $-0x80, %r15
subq $-0x80, %r14
cmpq $0x7f, %r15
ja 0x9766
testq %r15, %r15
je 0x97e8
leaq 0x50(%rbx), %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x8080
shlq $0x3, %r15
addq %r15, 0x40(%rbx)
jae 0x97e8
incq 0x48(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq