// File: /workspace/github_c_makefile_star2_O1/maandree[P]libkeccak/spec/libkeccak_degeneralise_spec.c
// Function: libkeccak_degeneralise_spec
int
libkeccak_degeneralise_spec(struct libkeccak_generalised_spec *restrict spec, struct libkeccak_spec *restrict output_spec)
{
	long int state_size, word_size, capacity, bitrate, output;
	int have_state_size = spec->state_size != LIBKECCAK_GENERALISED_SPEC_AUTOMATIC;
	int have_word_size  = spec->word_size  != LIBKECCAK_GENERALISED_SPEC_AUTOMATIC;
	int have_capacity   = spec->capacity   != LIBKECCAK_GENERALISED_SPEC_AUTOMATIC;
	int have_bitrate    = spec->bitrate    != LIBKECCAK_GENERALISED_SPEC_AUTOMATIC;
	int have_output     = spec->output     != LIBKECCAK_GENERALISED_SPEC_AUTOMATIC;


	if (have_state_size) {
		state_size = spec->state_size;
		if (state_size <= 0)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_NONPOSITIVE;
		if (state_size > 1600)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_TOO_LARGE;
		if (state_size % 25)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_MOD_25;
	}

	if (have_word_size) {
		word_size = spec->word_size;
		if (word_size <= 0)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_NONPOSITIVE;
		if (word_size > 64)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_WORD_TOO_LARGE;		
		if (have_state_size && state_size != word_size * 25)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_WORD_INCOHERENCY;
		else if (!have_state_size) {
			have_state_size = 1;
			state_size = word_size * 25;
		}
	}

	if (have_capacity) {
		capacity = spec->capacity;
		if (capacity <= 0)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_NONPOSITIVE;
		if (capacity & 7)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_CAPACITY_MOD_8;
	}

	if (have_bitrate) {
		bitrate = spec->bitrate;
		if (bitrate <= 0)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_NONPOSITIVE;
		if (bitrate & 7)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_BITRATE_MOD_8;
	}

	if (have_output) {
		output = spec->output;
		if (output <= 0)
			return LIBKECCAK_GENERALISED_SPEC_ERROR_OUTPUT_NONPOSITIVE;
	}


	if (have_bitrate + have_capacity == 2) {
		if (!have_state_size) {
			state_size = bitrate + capacity;
			output = deft(output, capacity * 2L <= 8 ? 8 : capacity * 2L);
		} else if (state_size != bitrate + capacity) {
			return LIBKECCAK_GENERALISED_SPEC_ERROR_STATE_BITRATE_CAPACITY_INCONSISTENCY;
		}
	} else if (have_bitrate + have_capacity == 1) {
		state_size = deft(state_size, 1600L);
		capacity = deft(capacity, state_size - bitrate);
		bitrate = deft(bitrate, state_size - capacity);
		output = deft(output, capacity * 2L <= 8 ? 8 : capacity * 2L);
	} else {
		state_size = deft(state_size, 1600L);
		capacity = state_size * 9 / 25;
		bitrate = state_size - capacity;
		output = deft(output, bitrate / 2L <= 8 ? 8 : bitrate / 2L);
	}


	spec->capacity   = output_spec->capacity = capacity;
	spec->bitrate    = output_spec->bitrate  = bitrate;
	spec->output     = output_spec->output   = output;
	spec->state_size = state_size;
	spec->word_size  = state_size / 25;

	return 0;
}

// Assembly:
pushq %r14
pushq %rbx
movq 0x18(%rdi), %rcx
movq 0x20(%rdi), %r10
movq (%rdi), %r8
movq 0x8(%rdi), %rdx
movq 0x10(%rdi), %r9
cmpq $-0x10000, %rcx         # imm = 0xFFFF0000
setne %r11b
je 0x8d48
testq %rcx, %rcx
jle 0x8e4a
movl $0x2, %eax
cmpq $0x640, %rcx            # imm = 0x640
jg 0x8f60
movabsq $-0x70a3d70a3d70a3d7, %rbx # imm = 0x8F5C28F5C28F5C29
imulq %rcx, %rbx
movl $0x3, %eax
movabsq $0xa3d70a3d70a3d70, %r14 # imm = 0xA3D70A3D70A3D70
cmpq %r14, %rbx
ja 0x8f60
cmpq $-0x10000, %r10         # imm = 0xFFFF0000
jne 0x8dfc
cmpq $-0x10000, %rdx         # imm = 0xFFFF0000
je 0x8d75
testq %rdx, %rdx
jle 0x8e5e
movl $0x8, %eax
testb $0x7, %dl
jne 0x8f60
cmpq $-0x10000, %r8          # imm = 0xFFFF0000
je 0x8d96
testq %r8, %r8
jle 0x8e68
movl $0xa, %eax
testb $0x7, %r8b
jne 0x8f60
cmpq $-0x10000, %r9          # imm = 0xFFFF0000
setne %r10b
testq %r9, %r9
setle %bl
movl $0xb, %eax
testb %bl, %r10b
jne 0x8f60
movq $-0x10000, %rax         # imm = 0xFFFF0000
cmpq %rax, %r8
sete %r10b
cmpq %rax, %rdx
sete %bl
orb %r10b, %bl
movabsq $-0x5c28f5c28f5c28f5, %r10 # imm = 0xA3D70A3D70A3D70B
jne 0x8e72
leaq (%r8,%rdx), %rbx
testb %r11b, %r11b
je 0x8eca
movl $0xc, %eax
cmpq %rbx, %rcx
je 0x8f29
jmp 0x8f60
testq %r10, %r10
jle 0x8e54
movl $0x5, %eax
cmpq $0x40, %r10
jg 0x8f60
cmpq $-0x10000, %rcx         # imm = 0xFFFF0000
setne %r11b
leaq (%r10,%r10,4), %rax
leaq (%rax,%rax,4), %r10
cmpq %r10, %rcx
setne %bl
movl $0x6, %eax
testb %bl, %r11b
jne 0x8f60
cmpq $-0x10000, %rcx         # imm = 0xFFFF0000
cmoveq %r10, %rcx
movb $0x1, %r11b
jmp 0x8d55
movl $0x1, %eax
jmp 0x8f60
movl $0x4, %eax
jmp 0x8f60
movl $0x7, %eax
jmp 0x8f60
movl $0x9, %eax
jmp 0x8f60
cmpq %rax, %r8
setne %bl
cmpq %rax, %rdx
setne %al
testb %r11b, %r11b
movl $0x640, %r11d           # imm = 0x640
cmoveq %r11, %rcx
cmpb %bl, %al
je 0x8eeb
movq %rcx, %rax
subq %r8, %rax
movq $-0x10000, %r11         # imm = 0xFFFF0000
cmpq %r11, %rdx
cmoveq %rax, %rdx
movq %rcx, %rax
subq %rdx, %rax
cmpq %r11, %r8
cmoveq %rax, %r8
leaq (%rdx,%rdx), %rax
cmpq $0x5, %rdx
movl $0x8, %ebx
cmovgeq %rax, %rbx
cmpq %r11, %r9
cmoveq %rbx, %r9
jmp 0x8f29
leaq (%rdx,%rdx), %rax
cmpq $0x5, %rdx
movl $0x8, %ecx
cmovgeq %rax, %rcx
cmpq $-0x10000, %r9          # imm = 0xFFFF0000
cmoveq %rcx, %r9
movq %rbx, %rcx
jmp 0x8f29
leaq (%rcx,%rcx,8), %r8
movq %r8, %rax
imulq %r10
addq %r8, %rdx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x4, %rdx
addq %rax, %rdx
movq %rcx, %r8
subq %rdx, %r8
cmpq $-0x10000, %r9          # imm = 0xFFFF0000
jne 0x8f29
movq %r8, %rax
shrq %rax
cmpq $0x12, %r8
movl $0x8, %r9d
cmovgeq %rax, %r9
movq %rdx, 0x8(%rsi)
movq %rdx, 0x8(%rdi)
movq %r8, (%rsi)
movq %r8, (%rdi)
movq %r9, 0x10(%rsi)
movq %r9, 0x10(%rdi)
movq %rcx, 0x18(%rdi)
movq %rcx, %rax
imulq %r10
addq %rcx, %rdx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x4, %rdx
addq %rax, %rdx
movq %rdx, 0x20(%rdi)
xorl %eax, %eax
popq %rbx
popq %r14
retq