// File: /workspace/github_c_makefile_star2_O3/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 %rbx
movq 0x18(%rdi), %rcx
movq 0x20(%rdi), %r11
movq (%rdi), %r8
movq 0x8(%rdi), %r9
movq 0x10(%rdi), %rdx
cmpq $-0x10000, %rcx         # imm = 0xFFFF0000
setne %r10b
je 0x93a6
testq %rcx, %rcx
jle 0x949f
movl $0x2, %eax
cmpq $0x640, %rcx            # imm = 0x640
ja 0x95c3
imull $0x5c29, %ecx, %eax     # imm = 0x5C29
movzwl %ax, %ebx
movl $0x3, %eax
cmpl $0xa3d, %ebx            # imm = 0xA3D
ja 0x95c3
cmpq $-0x10000, %r11         # imm = 0xFFFF0000
jne 0x9451
cmpq $-0x10000, %r9          # imm = 0xFFFF0000
je 0x93d4
testq %r9, %r9
jle 0x94b3
movl $0x8, %eax
testb $0x7, %r9b
jne 0x95c3
cmpq $-0x10000, %r8          # imm = 0xFFFF0000
je 0x93f5
testq %r8, %r8
jle 0x94bd
movl $0xa, %eax
testb $0x7, %r8b
jne 0x95c3
cmpq $-0x10000, %rdx         # imm = 0xFFFF0000
setne %r11b
testq %rdx, %rdx
setle %bl
movl $0xb, %eax
testb %bl, %r11b
jne 0x95c3
movq $-0x10000, %rax         # imm = 0xFFFF0000
cmpq %rax, %r8
sete %r11b
cmpq %rax, %r9
sete %bl
orb %r11b, %bl
jne 0x94c7
leaq (%r8,%r9), %r11
testb %r10b, %r10b
je 0x9522
movl $0xc, %eax
cmpq %r11, %rcx
je 0x9582
jmp 0x95c3
testq %r11, %r11
jle 0x94a9
movl $0x5, %eax
cmpq $0x40, %r11
ja 0x95c3
cmpq $-0x10000, %rcx         # imm = 0xFFFF0000
setne %bl
leaq (%r11,%r11,4), %rax
leaq (%rax,%rax,4), %r10
cmpq %r10, %rcx
setne %r11b
movl $0x6, %eax
testb %r11b, %bl
jne 0x95c3
cmpq $-0x10000, %rcx         # imm = 0xFFFF0000
cmoveq %r10, %rcx
movb $0x1, %r10b
jmp 0x93b3
movl $0x1, %eax
jmp 0x95c3
movl $0x4, %eax
jmp 0x95c3
movl $0x7, %eax
jmp 0x95c3
movl $0x9, %eax
jmp 0x95c3
cmpq %rax, %r8
setne %r11b
cmpq %rax, %r9
setne %al
testb %r10b, %r10b
movl $0x640, %r10d           # imm = 0x640
cmoveq %r10, %rcx
cmpb %r11b, %al
je 0x9543
movq %rcx, %rax
subq %r8, %rax
movq $-0x10000, %r10         # imm = 0xFFFF0000
cmpq %r10, %r9
cmoveq %rax, %r9
movq %rcx, %rax
subq %r9, %rax
cmpq %r10, %r8
cmoveq %rax, %r8
leaq (%r9,%r9), %rax
cmpq $0x5, %r9
movl $0x8, %r11d
cmovgeq %rax, %r11
cmpq %r10, %rdx
cmoveq %r11, %rdx
jmp 0x9582
leaq (%r9,%r9), %rax
cmpq $0x5, %r9
movl $0x8, %ecx
cmovgeq %rax, %rcx
cmpq $-0x10000, %rdx         # imm = 0xFFFF0000
cmoveq %rcx, %rdx
movq %r11, %rcx
jmp 0x9582
leal (%rcx,%rcx,8), %eax
cltq
imulq $0x51eb851f, %rax, %rax # imm = 0x51EB851F
movq %rax, %r8
shrq $0x3f, %r8
sarq $0x23, %rax
addl %r8d, %eax
movslq %eax, %r9
movq %rcx, %r8
subq %r9, %r8
cmpq $-0x10000, %rdx         # imm = 0xFFFF0000
jne 0x9582
movq %r8, %rax
shrq %rax
cmpq $0x12, %r8
movl $0x8, %edx
cmovgeq %rax, %rdx
movq %r9, 0x8(%rsi)
movq %r9, 0x8(%rdi)
movq %r8, (%rsi)
movq %r8, (%rdi)
movq %rdx, 0x10(%rsi)
movq %rdx, 0x10(%rdi)
movq %rcx, 0x18(%rdi)
movabsq $-0x5c28f5c28f5c28f5, %rdx # imm = 0xA3D70A3D70A3D70B
movq %rcx, %rax
imulq %rdx
addq %rcx, %rdx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x4, %rdx
addq %rax, %rdx
movq %rdx, 0x20(%rdi)
xorl %eax, %eax
popq %rbx
retq
nopl (%rax)