// File: /workspace/github_c_makefile_star2_O3/mjosaarinen[P]brutus/crypto_aead/twine80n6t4clocv2/vperm/twine.h
// Function: Keyschedule80
void Keyschedule80(const unsigned char sk[80/8])
{
	lsbox = LOAD(S);
	usbox = SHL4(lsbox);

	int	i;
	unsigned char	tmp[80/4];
	unsigned char	wk[4];

	for(i=0; i<(80/4); i+=2)
	{
		tmp[i] = sk[i/2] >> 4;
		tmp[i+1] = sk[i/2] & 0x0f;
	}

	for(i=0; ; i+=2)
	{
		//ek for two rounds
		ek[i][0] = tmp[1];
		ek[i][1] = tmp[3];
		ek[i][2] = tmp[4];
		ek[i][3] = tmp[6];
		ek[i][4] = tmp[13];
		ek[i][5] = tmp[14];
		ek[i][6] = tmp[15];
		ek[i][7] = tmp[16];

		ek[i+1][0] = tmp[5];
		ek[i+1][1] = tmp[7] ^ CON_H[i];
		ek[i+1][2] = tmp[8];
		ek[i+1][3] = tmp[10];
		ek[i+1][4] = tmp[17];
		ek[i+1][5] = tmp[18];
		ek[i+1][6] = tmp[19] ^ CON_L[i];
		ek[i+1][7] = tmp[1] ^ S[tmp[0]];

		//to the last two rounds
		if(i == (ROUND-2))
			break;

		//rotations for two rounds
		wk[3] = tmp[4] ^ S[tmp[16]];
		wk[0] = tmp[5] ^ S[wk[3]];
		wk[1] = tmp[6];
		wk[2] = ek[i+1][1];

		tmp[4] = tmp[12];
		tmp[5] = tmp[13];
		tmp[6] = tmp[14];
		tmp[7] = tmp[15];

		tmp[12] = ek[i+1][7];
		tmp[13] = tmp[2];
		tmp[14] = tmp[3];
		tmp[15] = tmp[0] ^ CON_L[i+1];

		tmp[0] = tmp[8] ^ S[ek[i+1][7]];
		tmp[1] = tmp[9];
		tmp[2] = tmp[10];
		tmp[3] = tmp[11] ^ CON_H[i+1];

		tmp[8] = tmp[16];
		tmp[9] = tmp[17];
		tmp[10] = tmp[18];
		tmp[11] = tmp[19] ^ CON_L[i];

		tmp[16] = wk[0];
		tmp[17] = wk[1];
		tmp[18] = wk[2];
		tmp[19] = wk[3];
	}

	for(i = 0; i < ROUND; i++)
	{
#ifndef TWINE_OPTIMIZED
		rks[i] = LOADS(ek[i]);
		rks[i] = SHR8(XOR(MASK4L(rks[i]), MASK4U(SHL4(rks[i]))));
#else
        /* key setup for the optimized implementation */
		rks[i] = LOAD64(ek[i]);
		switch(i%4){
			case 0:
				rks[i] = PSHUFB(rks[i], _mm_setr_epi8(0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7));
				break;
			case 1:
				rks[i] = PSHUFB(rks[i], _mm_setr_epi8(0,2,6,4,3,1,5,7,0,2,6,4,3,1,5,7));
				break;
			case 2:
				rks[i] = PSHUFB(rks[i], _mm_setr_epi8(0,6,5,3,4,2,1,7,0,6,5,3,4,2,1,7));
				break;
			case 3:
				rks[i] = PSHUFB(rks[i], _mm_setr_epi8(0,5,1,4,3,6,2,7,0,5,1,4,3,6,2,7));
				break;
		}
#endif
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
vmovaps 0x1f95(%rip), %xmm0     # 0x3210
movq 0x3d5e(%rip), %rax      # 0x4fe0
vmovaps %xmm0, (%rax)
vmovaps 0x1f92(%rip), %xmm0     # 0x3220
movq 0x3d13(%rip), %rax      # 0x4fa8
vmovaps %xmm0, (%rax)
movq $-0x2, %rax
movb (%rdi), %cl
movl %ecx, %edx
shrb $0x4, %dl
movb %dl, -0x16(%rsp,%rax)
andb $0xf, %cl
movb %cl, -0x15(%rsp,%rax)
addq $0x2, %rax
incq %rdi
cmpq $0x12, %rax
jb 0x12a0
movb -0x18(%rsp), %al
movb %al, -0x1f(%rsp)
movb -0x17(%rsp), %al
movb %al, -0x1c(%rsp)
movb -0x15(%rsp), %al
movb %al, -0x21(%rsp)
movb -0x14(%rsp), %bpl
movb -0x12(%rsp), %al
movb %al, -0x20(%rsp)
movb -0xb(%rsp), %al
movb %al, -0x1e(%rsp)
movb -0xa(%rsp), %r11b
movb -0x9(%rsp), %al
movb %al, -0x1a(%rsp)
movb -0x8(%rsp), %r13b
movb -0x13(%rsp), %r12b
movb -0x11(%rsp), %al
movb %al, -0x1b(%rsp)
movb -0x10(%rsp), %r9b
movb -0xe(%rsp), %al
movb %al, -0x22(%rsp)
movb -0x7(%rsp), %al
movb %al, -0x23(%rsp)
movb -0x6(%rsp), %r15b
movb -0x5(%rsp), %al
movb -0xc(%rsp), %dl
movl $0x1, %r14d
movq 0x3c8e(%rip), %r8       # 0x4fc8
movb -0x16(%rsp), %r10b
movb -0xf(%rsp), %bl
movb -0xd(%rsp), %cl
movb %cl, -0x1d(%rsp)
movb %dl, -0x19(%rsp)
movb -0x1c(%rsp), %dl
movb %dl, -0x8(%r8,%r14,8)
movzbl -0x1f(%rsp), %ecx
movq 0x3c8c(%rip), %rdi      # 0x4ff0
xorb (%rdi,%rcx), %dl
movl %r11d, %edi
movl %r15d, %ecx
movl %r10d, %r11d
movl %ebx, %esi
movb -0x21(%rsp), %r10b
movb %r10b, -0x7(%r8,%r14,8)
movb %bpl, -0x6(%r8,%r14,8)
movb -0x20(%rsp), %r10b
movb %r10b, -0x5(%r8,%r14,8)
movb -0x1e(%rsp), %r10b
movb %r10b, -0x4(%r8,%r14,8)
movb %dil, -0x3(%r8,%r14,8)
movb -0x1a(%rsp), %bl
movb %bl, -0x2(%r8,%r14,8)
movb %r13b, -0x1(%r8,%r14,8)
movb %r12b, (%r8,%r14,8)
movb -0x1b(%rsp), %r15b
movq 0x3c40(%rip), %r10      # 0x4ff8
xorb -0x1(%r10,%r14), %r15b
movb %r15b, 0x1(%r8,%r14,8)
movb %r9b, 0x2(%r8,%r14,8)
movb -0x22(%rsp), %r10b
movb %r10b, 0x3(%r8,%r14,8)
movb -0x23(%rsp), %r10b
movb %r10b, 0x4(%r8,%r14,8)
movb %cl, 0x5(%r8,%r14,8)
movq 0x3bd1(%rip), %r10      # 0x4fb8
xorb -0x1(%r10,%r14), %al
movb %al, 0x6(%r8,%r14,8)
movb %dl, 0x7(%r8,%r14,8)
cmpq $0x23, %r14
je 0x14ab
movzbl %r13b, %r10d
movb %sil, -0x1c(%rsp)
movl %r13d, %esi
movq 0x3bdd(%rip), %r13      # 0x4ff0
xorb (%r13,%r10), %bpl
movb %bl, -0x1b(%rsp)
movb -0x1f(%rsp), %r10b
movq 0x3b90(%rip), %rbx      # 0x4fb8
xorb (%rbx,%r14), %r10b
movzbl %dl, %ebx
xorb (%r13,%rbx), %r9b
movzbl %bpl, %ebx
movb %r10b, -0x1a(%rsp)
movb %r9b, -0x1f(%rsp)
movl %esi, %r9d
xorb (%r13,%rbx), %r12b
movl %r11d, %esi
movb -0x21(%rsp), %r11b
movb -0x1d(%rsp), %r10b
movq 0x3b9a(%rip), %rbx      # 0x4ff8
xorb (%rbx,%r14), %r10b
addq $0x2, %r14
movb %r10b, -0x21(%rsp)
movb %al, -0x1d(%rsp)
movb -0x23(%rsp), %bl
movb -0x22(%rsp), %r10b
movl %ebp, %eax
movb -0x20(%rsp), %r8b
movb %r8b, -0x23(%rsp)
movq 0x3b3d(%rip), %r8       # 0x4fc8
movb %cl, -0x22(%rsp)
movl %r12d, %r13d
movb -0x1e(%rsp), %r12b
movb %sil, -0x1e(%rsp)
movb %dil, -0x20(%rsp)
movb -0x19(%rsp), %bpl
jmp 0x134b
xorl %ecx, %ecx
vmovq (%r8,%rcx,8), %xmm0
movq 0x3ae6(%rip), %rdx      # 0x4fa0
xorl %edi, %edi
andl $0x3, %edi
leaq 0x1b3e(%rip), %rsi      # 0x3004
movslq (%rsi,%rdi,4), %rdi
addq %rsi, %rdi
jmpq *%rdi
addq $0x10, %rdx
vmovq (%r8,%rcx,8), %xmm0
movl %ecx, %edi
andl $0x3, %edi
movslq (%rsi,%rdi,4), %rdi
addq %rsi, %rdi
jmpq *%rdi
vpbroadcastq %xmm0, %xmm0
jmp 0x150d
vpshufb 0x1d39(%rip), %xmm0, %xmm0 # 0x3230
jmp 0x150d
vpshufb 0x1d4e(%rip), %xmm0, %xmm0 # 0x3250
jmp 0x150d
vpshufb 0x1d33(%rip), %xmm0, %xmm0 # 0x3240
vmovdqa %xmm0, (%rdx)
incq %rcx
cmpq $0x24, %rcx
jne 0x14cf
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq