// File: /workspace/github_cpp_makefile_star2_O3/DiplIngFrankGerlach[P]MST/./aes/aes.c
// Function: aes_decrypt
void aes_decrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize)
{
	BYTE state[4][4];

	// Copy the input to the state.
	state[0][0] = in[0];
	state[1][0] = in[1];
	state[2][0] = in[2];
	state[3][0] = in[3];
	state[0][1] = in[4];
	state[1][1] = in[5];
	state[2][1] = in[6];
	state[3][1] = in[7];
	state[0][2] = in[8];
	state[1][2] = in[9];
	state[2][2] = in[10];
	state[3][2] = in[11];
	state[0][3] = in[12];
	state[1][3] = in[13];
	state[2][3] = in[14];
	state[3][3] = in[15];

	// Perform the necessary number of rounds. The round key is added first.
	// The last round does not perform the MixColumns step.
	if (keysize > 128) {
		if (keysize > 192) {
			AddRoundKey(state,&key[56]);
			InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[52]);InvMixColumns(state);
			InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[48]);InvMixColumns(state);
		}
		else {
			AddRoundKey(state,&key[48]);
		}
		InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[44]);InvMixColumns(state);
		InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[40]);InvMixColumns(state);
	}
	else {
		AddRoundKey(state,&key[40]);
	}
	InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[36]);InvMixColumns(state);
	InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[32]);InvMixColumns(state);
	InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[28]);InvMixColumns(state);
	InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[24]);InvMixColumns(state);
	InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[20]);InvMixColumns(state);
	InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[16]);InvMixColumns(state);
	InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[12]);InvMixColumns(state);
	InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[8]);InvMixColumns(state);
	InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[4]);InvMixColumns(state);
	InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[0]);

	// Copy the state to the output array.
	out[0] = state[0][0];
	out[1] = state[1][0];
	out[2] = state[2][0];
	out[3] = state[3][0];
	out[4] = state[0][1];
	out[5] = state[1][1];
	out[6] = state[2][1];
	out[7] = state[3][1];
	out[8] = state[0][2];
	out[9] = state[1][2];
	out[10] = state[2][2];
	out[11] = state[3][2];
	out[12] = state[0][3];
	out[13] = state[1][3];
	out[14] = state[2][3];
	out[15] = state[3][3];
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rdx, %r14
movq %rsi, %rbx
movdqu (%rdi), %xmm0
pxor %xmm1, %xmm1
movdqa %xmm0, %xmm2
punpckhbw %xmm1, %xmm2    # xmm2 = xmm2[8],xmm1[8],xmm2[9],xmm1[9],xmm2[10],xmm1[10],xmm2[11],xmm1[11],xmm2[12],xmm1[12],xmm2[13],xmm1[13],xmm2[14],xmm1[14],xmm2[15],xmm1[15]
pshufd $0xe7, %xmm2, %xmm3     # xmm3 = xmm2[3,1,2,3]
pshuflw $0x72, %xmm3, %xmm3     # xmm3 = xmm3[2,0,3,1,4,5,6,7]
punpcklbw %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
pshufd $0xe7, %xmm0, %xmm1     # xmm1 = xmm0[3,1,2,3]
pshuflw $0x72, %xmm1, %xmm1     # xmm1 = xmm1[2,0,3,1,4,5,6,7]
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
pshufd $0xe8, %xmm2, %xmm2     # xmm2 = xmm2[0,2,2,3]
pshuflw $0xd8, %xmm2, %xmm2     # xmm2 = xmm2[0,2,1,3,4,5,6,7]
pshufd $0xe8, %xmm0, %xmm0     # xmm0 = xmm0[0,2,2,3]
pshuflw $0xd8, %xmm0, %xmm0     # xmm0 = xmm0[0,2,1,3,4,5,6,7]
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
packuswb %xmm1, %xmm0
movdqa %xmm0, (%rsp)
cmpl $0x81, %ecx
jl 0x1c6b
cmpl $0xc1, %ecx
jb 0x1c7f
leaq 0xe0(%r14), %rsi
movq %rsp, %r15
movq %r15, %rdi
callq 0x2a95
movq 0x4(%r15), %xmm0
pxor %xmm1, %xmm1
punpcklbw %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0xd0(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x33f8(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0xc0(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
jmp 0x1c8e
leaq 0xa0(%r14), %rsi
movq %rsp, %rdi
callq 0x2a95
jmp 0x1d4f
leaq 0xc0(%r14), %rsi
movq %rsp, %rdi
callq 0x2a95
movq %rsp, %r15
movq 0x4(%r15), %xmm0
pxor %xmm1, %xmm1
punpcklbw %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0xb0(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x3312(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0xa0(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq %rsp, %r15
movq 0x4(%r15), %xmm0
pxor %xmm1, %xmm1
punpcklbw %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0x90(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x3251(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0x80(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x31f2(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0x70(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x3196(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0x60(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x313a(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0x50(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x30de(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0x40(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x3082(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0x30(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x3026(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0x20(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x2fca(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
leaq 0x10(%r14), %rsi
movq %r15, %rdi
callq 0x2a95
movq %r15, %rdi
callq 0x2fec
movq 0x4(%r15), %xmm0
punpcklbw 0x2f6e(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3],xmm0[4],mem[4],xmm0[5],mem[5],xmm0[6],mem[6],xmm0[7],mem[7]
pshuflw $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2,4,5,6,7]
pshufd $0xb4, %xmm0, %xmm0     # xmm0 = xmm0[0,1,3,2]
packuswb %xmm0, %xmm0
movq %xmm0, 0x4(%r15)
movd 0xc(%r15), %xmm0
movdqa %xmm0, %xmm1
psrld $0x8, %xmm1
pslld $0x18, %xmm0
por %xmm1, %xmm0
movd %xmm0, 0xc(%r15)
movq %r15, %rdi
callq 0x2c62
movq %r15, %rdi
movq %r14, %rsi
callq 0x2a95
movdqa (%r15), %xmm0
movdqa %xmm0, %xmm1
pxor %xmm3, %xmm3
punpckhbw %xmm3, %xmm1    # xmm1 = xmm1[8],xmm3[8],xmm1[9],xmm3[9],xmm1[10],xmm3[10],xmm1[11],xmm3[11],xmm1[12],xmm3[12],xmm1[13],xmm3[13],xmm1[14],xmm3[14],xmm1[15],xmm3[15]
pshufd $0xe7, %xmm1, %xmm2     # xmm2 = xmm1[3,1,2,3]
pshuflw $0x72, %xmm2, %xmm2     # xmm2 = xmm2[2,0,3,1,4,5,6,7]
punpcklbw %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3],xmm0[4],xmm3[4],xmm0[5],xmm3[5],xmm0[6],xmm3[6],xmm0[7],xmm3[7]
pshufd $0xe7, %xmm0, %xmm3     # xmm3 = xmm0[3,1,2,3]
pshuflw $0x72, %xmm3, %xmm3     # xmm3 = xmm3[2,0,3,1,4,5,6,7]
punpckldq %xmm2, %xmm3    # xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
pshufd $0xe8, %xmm1, %xmm1     # xmm1 = xmm1[0,2,2,3]
pshuflw $0xd8, %xmm1, %xmm1     # xmm1 = xmm1[0,2,1,3,4,5,6,7]
pshufd $0xe8, %xmm0, %xmm0     # xmm0 = xmm0[0,2,2,3]
pshuflw $0xd8, %xmm0, %xmm0     # xmm0 = xmm0[0,2,1,3,4,5,6,7]
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
packuswb %xmm3, %xmm0
movdqu %xmm0, (%rbx)
addq $0x10, %rsp
popq %rbx
popq %r14
popq %r15
retq