// File: /workspace/github_cpp_makefile_star2_O2/qhan1028[P]JPEG-Decoder/jpeg-decoder.cpp
// Function: fast_idct(short*, int, bool)
void fast_idct(int16_t* vec, int rc, bool by_row){
    const int FACTOR = 1;
    double a = PI / 16.0;

    double c1 = double(FACTOR * cos(4.0 * a));
    double c2 = double(FACTOR * sin(4.0 * a));
    double c3 = double(FACTOR * cos(a));
    double c4 = double(FACTOR * sin(a));
    double c5 = double(FACTOR * cos(2.0 * a));
    double c6 = double(FACTOR * sin(2.0 * a));
    double c7 = double(FACTOR * cos(3.0 * a));
    double c8 = double(FACTOR * sin(3.0 * a));
    double c9 = double(FACTOR * sqrt(2.0));

    int si1[8] = {4, 0, 1, 7, 2, 6, 3, 5};
    double s1[8];

    if(by_row) {
        for (int i = 0; i < 8; i++) {
            s1[i] = (double)(vec[rc * 8 + si1[i]] * 8);
        }
    } else {
        for (int i = 0; i < 8; i++) {
            s1[i] = (double)(vec[si1[i] * 8 + rc] * 8);
        }
    }

    double s2[8];
    s2[0] = (c1 * s1[0] + c2 * s1[1]) * 2.0;
    s2[1] = (c5 * s1[4] + c6 * s1[5]) * 2.0;
    s2[2] = (c1 * s1[1] - c2 * s1[0]) * 2.0;
    s2[3] = (c5 * s1[5] - c6 * s1[4]) * 2.0;
    s2[4] = (c3 * s1[2] + c4 * s1[3]) * 2.0;
    s2[5] = (c7 * s1[6] + c8 * s1[7]) * 2.0;
    s2[6] = (c3 * s1[3] - c4 * s1[2]) * 2.0;
    s2[7] = (c7 * s1[7] - c8 * s1[6]) * 2.0;

    double s3[8];
    s3[0] = (s2[4] + s2[5]) * 0.5;
    s3[1] = (s2[6] - s2[7]) * 0.5;
    s3[2] = s2[0];
    s3[3] = (s2[4] - s2[5]) * 0.5;
    s3[4] = s2[1];
    s3[5] = s2[2];
    s3[6] = s2[3];
    s3[7] = (s2[6] + s2[7]) * 0.5;

    double s4[8];
    s4[0] = s3[0];
    s4[1] = s3[1];
    s4[2] = s3[2];
    s4[3] = s3[4];
    s4[4] = s3[5];
    s4[5] = s3[3] * c9;
    s4[6] = s3[6];
    s4[7] = s3[7] * c9;

    double s5[8];
    s5[0] = (s4[2] + s4[3]) * 0.5;
    s5[1] = s4[0];
    s5[2] = (s4[4] + s4[5]) * 0.5;
    s5[3] = (s4[6] + s4[7]) * 0.5;
    s5[4] = (s4[2] - s4[3]) * 0.5;
    s5[5] = s4[1];
    s5[6] = (s4[4] - s4[5]) * 0.5;
    s5[7] = (s4[6] - s4[7]) * 0.5;

    double d[8];
    d[0] = (s5[0] + s5[1]) * 0.5;
    d[1] = (s5[2] - s5[3]) * 0.5;
    d[2] = (s5[2] + s5[3]) * 0.5;
    d[3] = (s5[4] - s5[5]) * 0.5;
    d[4] = (s5[4] + s5[5]) * 0.5;
    d[5] = (s5[6] + s5[7]) * 0.5;
    d[6] = (s5[6] - s5[7]) * 0.5;
    d[7] = (s5[0] - s5[1]) * 0.5;

    if(by_row) {
        for(int i = 0; i < 8; i++){
            if(d[i] < 0) {
                vec[rc * 8 + i] = (int16_t)((d[i] - 4) / 8);
            } else {
                vec[rc * 8 + i] = (int16_t)((d[i] + 4) / 8);
            }
        }
    }
    else {
        for(int i = 0; i < 8; i++){
            if(d[i] < 0){
                vec[i * 8 + rc] = (int16_t)((d[i] - 4) / 8);
            } else {
                vec[i * 8 + rc] = (int16_t)((d[i] + 4) / 8);
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movslq %esi, %rax
testl %edx, %edx
je 0x2603
leaq (,%rax,8), %rcx
xorl %r8d, %r8d
leaq 0x3ad5(%rip), %r9       # 0x60b0
cmpq $0x20, %r8
je 0x2634
movslq (%r8,%r9), %r10
addq %rcx, %r10
movswl (%rdi,%r10,2), %r10d
shll $0x3, %r10d
cvtsi2sd %r10d, %xmm0
movsd %xmm0, -0x80(%rbp,%r8,2)
addq $0x4, %r8
jmp 0x25db
xorl %ecx, %ecx
leaq 0x3aa4(%rip), %r8       # 0x60b0
cmpq $0x20, %rcx
je 0x2634
movslq (%rcx,%r8), %r9
leaq (%rax,%r9,8), %r9
movswl (%rdi,%r9,2), %r9d
shll $0x3, %r9d
cvtsi2sd %r9d, %xmm0
movsd %xmm0, -0x80(%rbp,%rcx,2)
addq $0x4, %rcx
jmp 0x260c
movsd -0x80(%rbp), %xmm4
movsd -0x78(%rbp), %xmm0
movsd 0x39c2(%rip), %xmm2     # 0x6008
mulsd %xmm0, %xmm2
movsd 0x39be(%rip), %xmm5     # 0x6010
movapd %xmm4, %xmm1
mulsd %xmm5, %xmm1
addsd %xmm2, %xmm1
addsd %xmm1, %xmm1
movsd -0x60(%rbp), %xmm6
movsd -0x58(%rbp), %xmm2
movsd 0x39a4(%rip), %xmm7     # 0x6018
mulsd %xmm2, %xmm7
movsd 0x399f(%rip), %xmm8     # 0x6020
movapd %xmm6, %xmm3
mulsd %xmm8, %xmm3
addsd %xmm7, %xmm3
addsd %xmm3, %xmm3
mulsd 0x398e(%rip), %xmm4     # 0x6028
mulsd %xmm5, %xmm0
addsd %xmm4, %xmm0
addsd %xmm0, %xmm0
mulsd 0x3982(%rip), %xmm6     # 0x6030
mulsd %xmm8, %xmm2
addsd %xmm6, %xmm2
addsd %xmm2, %xmm2
movsd -0x70(%rbp), %xmm4
movsd -0x68(%rbp), %xmm8
movsd 0x396a(%rip), %xmm5     # 0x6038
mulsd %xmm8, %xmm5
movsd 0x3964(%rip), %xmm9     # 0x6040
movapd %xmm4, %xmm6
mulsd %xmm9, %xmm6
addsd %xmm5, %xmm6
addsd %xmm6, %xmm6
movsd -0x50(%rbp), %xmm5
movsd -0x48(%rbp), %xmm7
movsd 0x3948(%rip), %xmm10    # 0x6048
mulsd %xmm7, %xmm10
movsd 0x3942(%rip), %xmm11    # 0x6050
movapd %xmm5, %xmm12
mulsd %xmm11, %xmm12
addsd %xmm10, %xmm12
addsd %xmm12, %xmm12
mulsd 0x392e(%rip), %xmm4     # 0x6058
mulsd %xmm9, %xmm8
addsd %xmm4, %xmm8
addsd %xmm8, %xmm8
mulsd 0x391f(%rip), %xmm5     # 0x6060
mulsd %xmm11, %xmm7
addsd %xmm5, %xmm7
addsd %xmm7, %xmm7
movapd %xmm6, %xmm5
addsd %xmm12, %xmm5
movsd 0x3909(%rip), %xmm4     # 0x6068
mulsd %xmm4, %xmm5
movapd %xmm8, %xmm9
subsd %xmm7, %xmm9
mulsd %xmm4, %xmm9
subsd %xmm12, %xmm6
mulsd %xmm4, %xmm6
addsd %xmm8, %xmm7
mulsd %xmm4, %xmm7
movsd 0x38e3(%rip), %xmm8     # 0x6070
mulsd %xmm8, %xmm6
mulsd %xmm8, %xmm7
movapd %xmm1, %xmm8
addsd %xmm3, %xmm8
mulsd %xmm4, %xmm8
movapd %xmm0, %xmm10
addsd %xmm6, %xmm10
mulsd %xmm4, %xmm10
movapd %xmm2, %xmm11
addsd %xmm7, %xmm11
mulsd %xmm4, %xmm11
subsd %xmm3, %xmm1
mulsd %xmm4, %xmm1
subsd %xmm6, %xmm0
mulsd %xmm4, %xmm0
subsd %xmm7, %xmm2
mulsd %xmm4, %xmm2
movapd %xmm8, %xmm3
addsd %xmm5, %xmm3
mulsd %xmm4, %xmm3
movsd %xmm3, -0x40(%rbp)
movapd %xmm10, %xmm3
subsd %xmm11, %xmm3
mulsd %xmm4, %xmm3
movsd %xmm3, -0x38(%rbp)
addsd %xmm10, %xmm11
mulsd %xmm4, %xmm11
movsd %xmm11, -0x30(%rbp)
movapd %xmm1, %xmm3
subsd %xmm9, %xmm3
mulsd %xmm4, %xmm3
movsd %xmm3, -0x28(%rbp)
addsd %xmm9, %xmm1
mulsd %xmm4, %xmm1
movsd %xmm1, -0x20(%rbp)
movapd %xmm2, %xmm1
addsd %xmm0, %xmm1
mulsd %xmm4, %xmm1
movsd %xmm1, -0x18(%rbp)
subsd %xmm2, %xmm0
mulsd %xmm4, %xmm0
movsd %xmm0, -0x10(%rbp)
subsd %xmm5, %xmm8
mulsd %xmm4, %xmm8
movsd %xmm8, -0x8(%rbp)
testb %dl, %dl
je 0x28ae
shll $0x3, %esi
movslq %esi, %rax
leaq (%rdi,%rax,2), %rax
xorl %ecx, %ecx
xorpd %xmm0, %xmm0
leaq 0x3826(%rip), %rdx      # 0x60a0
movsd 0x37f6(%rip), %xmm1     # 0x6078
cmpq $0x8, %rcx
je 0x28f4
movsd -0x40(%rbp,%rcx,8), %xmm2
xorl %esi, %esi
ucomisd %xmm2, %xmm0
seta %sil
addsd (%rdx,%rsi,8), %xmm2
mulsd %xmm1, %xmm2
cvttsd2si %xmm2, %esi
movw %si, (%rax,%rcx,2)
incq %rcx
jmp 0x2882
leaq (%rdi,%rax,2), %rax
xorl %ecx, %ecx
xorpd %xmm0, %xmm0
leaq 0x37e1(%rip), %rdx      # 0x60a0
movsd 0x37b1(%rip), %xmm1     # 0x6078
cmpq $0x40, %rcx
je 0x28f4
movsd -0x40(%rbp,%rcx), %xmm2
xorl %esi, %esi
ucomisd %xmm2, %xmm0
seta %sil
addsd (%rdx,%rsi,8), %xmm2
mulsd %xmm1, %xmm2
cvttsd2si %xmm2, %esi
movw %si, (%rax,%rcx,2)
addq $0x8, %rcx
jmp 0x28c7
popq %rbp
retq