// File: /workspace/github_cpp_makefile_star2_O3/ushitora-anqou[P]aqtfhe2/./aqtfhe2.hpp
// Function: aqtfhe2::tlwe_lvl0<aqtfhe2::params::CGGI16>::gate_bootstrapping_to_lvl1(std::vector<aqtfhe2::trgswfft_lvl1<aqtfhe2::params::CGGI16>, std::allocator<aqtfhe2::trgswfft_lvl1<aqtfhe2::params::CGGI16>>> const&) const
tlwe_lvl1<P> gate_bootstrapping_to_lvl1(
        const std::vector<trgswfft_lvl1<P>> &bkfftlvl01) const
    {
        constexpr uint32_t n = P::n(), N = P::N();

        uint32_t bara =
            2 * N - detail::mod_switch_from_torus32(2 * N, data_[n]);
        trlwe_lvl1<P> acc = rotated_test_vector(bara), tmp0, tmp1;
        for (size_t i = 0; i < n; i++) {
            bara = detail::mod_switch_from_torus32(2 * N, data_[i]);
            if (bara == 0)
                continue;
            acc.polynomial_mul_by_xai_minus_one(/* out */ tmp0, bara);
            tmp0.trgswfft_external_product(/* out */ tmp1, bkfftlvl01[i]);
            for (size_t i = 0; i < N; i++) {
                acc.poly0_[i] += tmp1.poly0_[i];
                acc.poly1_[i] += tmp1.poly1_[i];
            }
        }

        return acc.sample_extract_index(0);
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x7018, %rsp           # imm = 0x7018
movl 0x7d0(%rsi), %eax
movabsq $0x10000000000000, %rcx # imm = 0x10000000000000
movq %rdx, 0x8(%rsp)
movl $0x800, %edx            # imm = 0x800
leaq 0x10(%rsp), %r14
movq %rdi, (%rsp)
movq %rsi, %r15
movq %r14, %rdi
shlq $0x20, %rax
addq %rcx, %rax
shrq $0x35, %rax
subl %eax, %edx
callq 0x5f1e
movl $0x1000, %r13d          # imm = 0x1000
leaq 0x5018(%rsp), %rbp
leaq (%rbp,%r13), %rbx
addq %r14, %r13
xorl %r14d, %r14d
movl (%r15,%r14,4), %r12d
movabsq $0x10000000000000, %rax # imm = 0x10000000000000
shlq $0x20, %r12
addq %rax, %r12
shrq $0x35, %r12
je 0x5cef
leaq 0x10(%rsp), %rdx
movq %rbp, %rdi
movl %r12d, %esi
vzeroupper
callq 0x6412
movq %rbx, %rdi
movl %r12d, %esi
movq %r13, %rdx
callq 0x6412
movq 0x8(%rsp), %rax
movq %r14, %rdx
shlq $0x10, %rdx
leaq 0x3018(%rsp), %rsi
movq %rbp, %rdi
addq (%rax), %rdx
callq 0x608a
movq $-0x400, %rax           # imm = 0xFC00
vmovdqu64 0x1010(%rsp,%rax,4), %zmm0
vpaddd 0x4018(%rsp,%rax,4), %zmm0, %zmm0
vmovdqu64 %zmm0, 0x1010(%rsp,%rax,4)
vmovdqu64 0x2010(%rsp,%rax,4), %zmm0
vpaddd 0x5018(%rsp,%rax,4), %zmm0, %zmm0
vmovdqu64 %zmm0, 0x2010(%rsp,%rax,4)
addq $0x10, %rax
jne 0x5ca7
incq %r14
cmpq $0x1f4, %r14            # imm = 0x1F4
jne 0x5c41
vpmovsxbq 0x23c7(%rip), %zmm0 # 0x80d0
vpmovsxbq 0x23c5(%rip), %zmm1 # 0x80d8
vpbroadcastq 0x23c3(%rip), %zmm2 # 0x80e0
leaq 0xfd0(%rsp), %rax
vpxor %xmm3, %xmm3, %xmm3
movl -0xfc0(%rax), %ecx
movl %ecx, 0x2010(%rsp)
xorl %ecx, %ecx
vpbroadcastq %rcx, %zmm4
vporq %zmm0, %zmm4, %zmm5
vporq %zmm1, %zmm4, %zmm4
vpcmpltuq %zmm2, %zmm4, %k0
vpcmpltuq %zmm2, %zmm5, %k1
kunpckbw %k0, %k1, %k1
vpmovm2d %k1, %zmm4
vpshufd $0x1b, %zmm4, %zmm4     # zmm4 = zmm4[3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12]
vshufi64x2 $0x1b, %zmm4, %zmm4, %zmm4 # zmm4 = zmm4[6,7,4,5,2,3,0,1]
vpmovd2m %zmm4, %k2
vmovdqu32 (%rax), %zmm4 {%k2} {z}
addq $-0x40, %rax
vpshufd $0x1b, %zmm4, %zmm4     # zmm4 = zmm4[3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12]
vpsubd %zmm4, %zmm3, %zmm4
vshufi64x2 $0x1b, %zmm4, %zmm4, %zmm4 # zmm4 = zmm4[6,7,4,5,2,3,0,1]
vmovdqu32 %zmm4, 0x2014(%rsp,%rcx,4) {%k1}
addq $0x10, %rcx
cmpq $0x400, %rcx            # imm = 0x400
jne 0x5d38
movq (%rsp), %rbx
movl 0x1010(%rsp), %eax
leaq 0x2010(%rsp), %rsi
movl $0x1004, %edx           # imm = 0x1004
movq %rbx, %rdi
movl %eax, 0x1000(%rsi)
vzeroupper
callq 0x2130
movq %rbx, %rax
addq $0x7018, %rsp           # imm = 0x7018
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq