/*******************************************************************************
* Copyright 2019-2024 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#include "cpu/x64/gemm/f32/common_f32.hpp"
#include "cpu/x64/gemm/f32/jit_avx_kernel_sgemm_kern_autogen.hpp"
#include "cpu/x64/jit_generator.hpp"

namespace dnnl {
namespace impl {
namespace cpu {
namespace x64 {

jit_avx_kernel_sgemm_kern::jit_avx_kernel_sgemm_kern()
    : jit_generator(jit_name()) {}

void jit_avx_kernel_sgemm_kern::generate() {
    Xbyak::Label l1efc;
    Xbyak::Label l1f44;
    Xbyak::Label l1f48;

    preamble();
    auto stacksize = get_size_of_abi_save_regs();
#ifdef _WIN32
    mov(A, ptr[OLD_A]);
    mov(B, ptr[OLD_B]);
#endif
    mov(C, ptr[OLD_C]);
    mov(LDC, ptr[OLD_LDC]);

    jit_avx_kernel_sgemm_kern::generate_part1(l1efc, l1f44, l1f48);
    jit_avx_kernel_sgemm_kern::generate_part2(l1efc, l1f44, l1f48);

    postamble();
}

void jit_avx_kernel_sgemm_kern::generate_part1(const Xbyak::Label &l1efc,
        const Xbyak::Label &l1f44, const Xbyak::Label &l1f48) {
    std::vector<Xbyak::Label> labels(44);

    mov(M, qword[M]);
    mov(N, qword[N]);
    mov(K, qword[K]);
    shl(LDC, 0x2);
    sub(A, -128);
    sub(B, -128);
    mov(J, M);
    cmp(J, 0x10);
    jl(labels[1], T_NEAR);
    align(4);

    L(labels[27]);
    mov(AA, K);
    imul(AA, AA, 0x40);
    add(AA, A);
    mov(CO1, C);
    add(C, 0x40);
    mov(BO, B);
    mov(I, N);
    cmp(I, 0x4);
    jl(labels[28], T_NEAR);
    align(4);

    L(labels[30]);
    vxorps(ymm8, ymm8, ymm8);
    vbroadcastf128(ymm2, xword[BO - 0x80]);
    vxorps(ymm9, ymm9, ymm9);
    vmovups(ymm0, yword[A - 0x80]);
    vxorps(ymm10, ymm10, ymm10);
    vmovups(ymm1, yword[A - 0x60]);
    vxorps(ymm11, ymm11, ymm11);
    lea(CO2, ptr[CO1 + LDC * 2 + 0x0]);
    vxorps(ymm12, ymm12, ymm12);
    vxorps(ymm13, ymm13, ymm13);
    vxorps(ymm14, ymm14, ymm14);
    vxorps(ymm15, ymm15, ymm15);
    mov(AO, A);
    mov(H, K);
    sar(H, 0x2);
    jle(labels[24], T_NEAR);
    sub(H, 0x1e);
    jle(labels[22], T_NEAR);
    align(4);

    L(labels[38]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x60]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x50]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO + 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO + 0x60]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x40]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO + 0x80]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0xa0]);
    sub(AO, -256);
    sub(BO, -64);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[38], T_NEAR);
    align(4);

    L(labels[22]);
    prefetcht0(byte[CO1 + 0x3c]);
    prefetcht0(byte[CO1 + LDC * 1 + 0x3c]);
    prefetcht0(byte[CO2 + 0x3c]);
    prefetcht0(byte[CO2 + LDC * 1 + 0x3c]);
    add(H, 0x1e);
    align(4);

    L(labels[23]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x60]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x50]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO + 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO + 0x60]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x40]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO + 0x80]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0xa0]);
    sub(AO, -256);
    sub(BO, -64);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[23], T_NEAR);
    align(4);

    L(labels[24]);
    mov(H, K);
    and_(H, 0x3);
    je(labels[26], T_NEAR);
    align(4);

    L(labels[25]);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm8, ymm8, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm9, ymm9, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm10, ymm10, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm11, ymm11, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm15, ymm15, ymm7);
    vmovups(ymm0, yword[AO - 0x40]);
    vmovups(ymm1, yword[AO - 0x20]);
    vbroadcastf128(ymm2, xword[BO - 0x70]);
    sub(AO, -64);
    sub(BO, -16);
    dec(H);
    jg(labels[25], T_NEAR);
    align(4);

    L(labels[26]);
    vblendps(ymm0, ymm8, ymm9, 0xaa);
    vblendps(ymm1, ymm8, ymm9, 0x55);
    vblendps(ymm2, ymm10, ymm11, 0xaa);
    vblendps(ymm3, ymm10, ymm11, 0x55);
    vblendps(ymm8, ymm0, ymm2, 0xcc);
    vblendps(ymm9, ymm1, ymm3, 0xcc);
    vblendps(ymm10, ymm0, ymm2, 0x33);
    vblendps(ymm11, ymm1, ymm3, 0x33);
    vblendps(ymm0, ymm12, ymm13, 0xaa);
    vblendps(ymm1, ymm12, ymm13, 0x55);
    vblendps(ymm2, ymm14, ymm15, 0xaa);
    vblendps(ymm3, ymm14, ymm15, 0x55);
    vblendps(ymm12, ymm0, ymm2, 0xcc);
    vblendps(ymm13, ymm1, ymm3, 0xcc);
    vblendps(ymm14, ymm0, ymm2, 0x33);
    vblendps(ymm15, ymm1, ymm3, 0x33);
    vmovups(ymm0, yword[CO1 + 0x0]);
    vaddps(ymm8, ymm0, ymm8);
    vmovups(yword[CO1 + 0x0], ymm8);
    vmovups(ymm1, yword[CO1 + 0x20]);
    vaddps(ymm12, ymm1, ymm12);
    vmovups(yword[CO1 + 0x20], ymm12);
    vmovups(ymm0, yword[CO1 + LDC * 1 + 0x0]);
    vaddps(ymm9, ymm0, ymm9);
    vmovups(yword[CO1 + LDC * 1 + 0x0], ymm9);
    vmovups(ymm1, yword[CO1 + LDC * 1 + 0x20]);
    vaddps(ymm13, ymm1, ymm13);
    vmovups(yword[CO1 + LDC * 1 + 0x20], ymm13);
    vmovups(ymm0, yword[CO2]);
    vaddps(ymm10, ymm0, ymm10);
    vmovups(yword[CO2], ymm10);
    vmovups(ymm1, yword[CO2 + 0x20]);
    vaddps(ymm14, ymm1, ymm14);
    vmovups(yword[CO2 + 0x20], ymm14);
    vmovups(ymm0, yword[CO2 + LDC * 1]);
    vaddps(ymm11, ymm0, ymm11);
    vmovups(yword[CO2 + LDC * 1], ymm11);
    vmovups(ymm1, yword[CO2 + LDC * 1 + 0x20]);
    vaddps(ymm15, ymm1, ymm15);
    vmovups(yword[CO2 + LDC * 1 + 0x20], ymm15);
    lea(CO1, ptr[CO1 + LDC * 4 + 0x0]);
    sub(I, 0x4);
    cmp(I, 0x4);
    jge(labels[30], T_NEAR);
    align(4);

    L(labels[28]);
    test(I, 0x2);
    jle(labels[36], T_NEAR);
    vxorps(ymm8, ymm8, ymm8);
    vbroadcastf128(ymm2, xword[BO - 0x80]);
    vxorps(ymm9, ymm9, ymm9);
    vmovups(ymm0, yword[A - 0x80]);
    vxorps(ymm10, ymm10, ymm10);
    vmovups(ymm1, yword[A - 0x60]);
    vxorps(ymm11, ymm11, ymm11);
    lea(CO2, ptr[CO1 + LDC * 2 + 0x0]);
    vxorps(ymm12, ymm12, ymm12);
    vxorps(ymm13, ymm13, ymm13);
    vxorps(ymm14, ymm14, ymm14);
    vxorps(ymm15, ymm15, ymm15);
    mov(AO, A);
    mov(H, K);
    sar(H, 0x2);
    jle(labels[33], T_NEAR);
    sub(H, 0x1e);
    jle(labels[31], T_NEAR);
    align(4);

    L(labels[29]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x78]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x68]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO + 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO + 0x60]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x60]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO + 0x80]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0xa0]);
    sub(AO, -256);
    sub(BO, -32);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[29], T_NEAR);
    align(4);

    L(labels[31]);
    prefetcht0(byte[CO1 + 0x3c]);
    prefetcht0(byte[CO1 + LDC * 1 + 0x3c]);
    add(H, 0x1e);
    align(4);

    L(labels[32]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x78]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x68]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO + 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO + 0x60]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x60]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO + 0x80]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0xa0]);
    sub(AO, -256);
    sub(BO, -32);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[32], T_NEAR);
    align(4);

    L(labels[33]);
    mov(H, K);
    and_(H, 0x3);
    je(labels[35], T_NEAR);
    align(4);

    L(labels[34]);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm8, ymm8, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm9, ymm9, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm10, ymm10, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm11, ymm11, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm15, ymm15, ymm7);
    vmovups(ymm0, yword[AO - 0x40]);
    vmovups(ymm1, yword[AO - 0x20]);
    vbroadcastf128(ymm2, xword[BO - 0x78]);
    sub(AO, -64);
    sub(BO, -8);
    dec(H);
    jg(labels[34], T_NEAR);
    align(4);

    L(labels[35]);
    vblendps(ymm0, ymm8, ymm9, 0xaa);
    vblendps(ymm1, ymm8, ymm9, 0x55);
    vblendps(ymm2, ymm10, ymm11, 0xaa);
    vblendps(ymm3, ymm10, ymm11, 0x55);
    vblendps(ymm8, ymm0, ymm2, 0xcc);
    vblendps(ymm9, ymm1, ymm3, 0xcc);
    vblendps(ymm10, ymm0, ymm2, 0x33);
    vblendps(ymm11, ymm1, ymm3, 0x33);
    vblendps(ymm0, ymm12, ymm13, 0xaa);
    vblendps(ymm1, ymm12, ymm13, 0x55);
    vblendps(ymm2, ymm14, ymm15, 0xaa);
    vblendps(ymm3, ymm14, ymm15, 0x55);
    vblendps(ymm12, ymm0, ymm2, 0xcc);
    vblendps(ymm13, ymm1, ymm3, 0xcc);
    vblendps(ymm14, ymm0, ymm2, 0x33);
    vblendps(ymm15, ymm1, ymm3, 0x33);
    vmovups(ymm0, yword[CO1 + 0x0]);
    vaddps(ymm8, ymm0, ymm8);
    vmovups(yword[CO1 + 0x0], ymm8);
    vmovups(ymm1, yword[CO1 + 0x20]);
    vaddps(ymm12, ymm1, ymm12);
    vmovups(yword[CO1 + 0x20], ymm12);
    vmovups(ymm0, yword[CO1 + LDC * 1 + 0x0]);
    vaddps(ymm9, ymm0, ymm9);
    vmovups(yword[CO1 + LDC * 1 + 0x0], ymm9);
    vmovups(ymm1, yword[CO1 + LDC * 1 + 0x20]);
    vaddps(ymm13, ymm1, ymm13);
    vmovups(yword[CO1 + LDC * 1 + 0x20], ymm13);
    lea(CO1, ptr[CO1 + LDC * 2 + 0x0]);
    align(4);

    L(labels[36]);
    test(I, 0x1);
    jle(labels[0], T_NEAR);
    vxorps(ymm8, ymm8, ymm8);
    vbroadcastf128(ymm2, xword[BO - 0x80]);
    vxorps(ymm9, ymm9, ymm9);
    vmovups(ymm0, yword[A - 0x80]);
    vxorps(ymm10, ymm10, ymm10);
    vmovups(ymm1, yword[A - 0x60]);
    vxorps(ymm11, ymm11, ymm11);
    lea(CO2, ptr[CO1 + LDC * 2 + 0x0]);
    vxorps(ymm12, ymm12, ymm12);
    vxorps(ymm13, ymm13, ymm13);
    vxorps(ymm14, ymm14, ymm14);
    vxorps(ymm15, ymm15, ymm15);
    mov(AO, A);
    mov(H, K);
    sar(H, 0x2);
    jle(labels[41], T_NEAR);
    sub(H, 0x1e);
    jle(labels[39], T_NEAR);
    align(4);

    L(labels[37]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x7c]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x78]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x74]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO + 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO + 0x60]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO + 0x80]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0xa0]);
    sub(AO, -256);
    sub(BO, -16);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[37], T_NEAR);
    align(4);

    L(labels[39]);
    prefetcht0(byte[CO1 + 0x3c]);
    add(H, 0x1e);
    align(4);

    L(labels[40]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x7c]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x78]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x74]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO + 0x40]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO + 0x60]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO + 0x80]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0xa0]);
    sub(AO, -256);
    sub(BO, -16);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[40], T_NEAR);
    align(4);

    L(labels[41]);
    mov(H, K);
    and_(H, 0x3);
    je(labels[43], T_NEAR);
    align(4);

    L(labels[42]);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm8, ymm8, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm9, ymm9, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm10, ymm10, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm11, ymm11, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm15, ymm15, ymm7);
    vmovups(ymm0, yword[AO - 0x40]);
    vmovups(ymm1, yword[AO - 0x20]);
    vbroadcastf128(ymm2, xword[BO - 0x7c]);
    sub(AO, -64);
    sub(BO, -4);
    dec(H);
    jg(labels[42], T_NEAR);
    align(4);

    L(labels[43]);
    vblendps(ymm0, ymm8, ymm9, 0xaa);
    vblendps(ymm1, ymm8, ymm9, 0x55);
    vblendps(ymm2, ymm10, ymm11, 0xaa);
    vblendps(ymm3, ymm10, ymm11, 0x55);
    vblendps(ymm8, ymm0, ymm2, 0xcc);
    vblendps(ymm9, ymm1, ymm3, 0xcc);
    vblendps(ymm10, ymm0, ymm2, 0x33);
    vblendps(ymm11, ymm1, ymm3, 0x33);
    vblendps(ymm0, ymm12, ymm13, 0xaa);
    vblendps(ymm1, ymm12, ymm13, 0x55);
    vblendps(ymm2, ymm14, ymm15, 0xaa);
    vblendps(ymm3, ymm14, ymm15, 0x55);
    vblendps(ymm12, ymm0, ymm2, 0xcc);
    vblendps(ymm13, ymm1, ymm3, 0xcc);
    vblendps(ymm14, ymm0, ymm2, 0x33);
    vblendps(ymm15, ymm1, ymm3, 0x33);
    vmovups(ymm0, yword[CO1 + 0x0]);
    vaddps(ymm8, ymm0, ymm8);
    vmovups(yword[CO1 + 0x0], ymm8);
    vmovups(ymm1, yword[CO1 + 0x20]);
    vaddps(ymm12, ymm1, ymm12);
    vmovups(yword[CO1 + 0x20], ymm12);
    lea(CO1, ptr[CO1 + LDC * 1 + 0x0]);
    align(4);

    L(labels[0]);
    mov(A, AO);
    sub(J, 0x10);
    cmp(J, 0x10);
    jge(labels[27], T_NEAR);
    align(4);

    L(labels[1]);
    test(J, 0x8);
    jle(l1f48, T_NEAR);
    mov(AA, K);
    imul(AA, AA, 0x20);
    add(AA, A);
    mov(CO1, C);
    add(C, 0x20);
    mov(BO, B);
    mov(I, N);
    cmp(I, 0x4);
    jl(labels[9], T_NEAR);
    align(4);

    L(labels[2]);
    vxorps(ymm8, ymm8, ymm8);
    vbroadcastf128(ymm2, xword[BO - 0x80]);
    vxorps(ymm9, ymm9, ymm9);
    vmovups(ymm0, yword[A - 0x80]);
    vxorps(ymm10, ymm10, ymm10);
    vmovups(ymm1, yword[A - 0x60]);
    vxorps(ymm11, ymm11, ymm11);
    lea(CO2, ptr[CO1 + LDC * 2 + 0x0]);
    vxorps(ymm12, ymm12, ymm12);
    vxorps(ymm13, ymm13, ymm13);
    vxorps(ymm14, ymm14, ymm14);
    vxorps(ymm15, ymm15, ymm15);
    mov(AO, A);
    mov(H, K);
    sar(H, 0x2);
    jle(labels[6], T_NEAR);
    sub(H, 0x1e);
    jle(labels[4], T_NEAR);
    align(4);

    L(labels[3]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x60]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x40]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x60]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x50]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x20]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x40]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    sub(AO, -128);
    sub(BO, -64);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[3], T_NEAR);
    align(4);

    L(labels[4]);
    prefetcht0(byte[CO1 + 0x1c]);
    prefetcht0(byte[CO1 + LDC * 1 + 0x1c]);
    prefetcht0(byte[CO2 + 0x1c]);
    prefetcht0(byte[CO2 + LDC * 1 + 0x1c]);
    add(H, 0x1e);
    align(4);

    L(labels[5]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x60]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x40]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x60]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x50]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x20]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x40]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    sub(AO, -128);
    sub(BO, -64);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[5], T_NEAR);
    align(4);

    L(labels[6]);
    mov(H, K);
    and_(H, 0x3);
    je(labels[8], T_NEAR);
    align(4);

    L(labels[7]);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm8, ymm8, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm9, ymm9, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm10, ymm10, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm11, ymm11, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm15, ymm15, ymm7);
    vmovups(ymm0, yword[AO - 0x60]);
    vmovups(ymm1, yword[AO - 0x40]);
    vbroadcastf128(ymm2, xword[BO - 0x70]);
    sub(AO, -32);
    sub(BO, -16);
    dec(H);
    jg(labels[7], T_NEAR);
    align(4);

    L(labels[8]);
    vblendps(ymm0, ymm8, ymm9, 0xaa);
    vblendps(ymm1, ymm8, ymm9, 0x55);
    vblendps(ymm2, ymm10, ymm11, 0xaa);
    vblendps(ymm3, ymm10, ymm11, 0x55);
    vblendps(ymm8, ymm0, ymm2, 0xcc);
    vblendps(ymm9, ymm1, ymm3, 0xcc);
    vblendps(ymm10, ymm0, ymm2, 0x33);
    vblendps(ymm11, ymm1, ymm3, 0x33);
    vmovups(ymm0, yword[CO1 + 0x0]);
    vaddps(ymm8, ymm0, ymm8);
    vmovups(yword[CO1 + 0x0], ymm8);
    vmovups(ymm0, yword[CO1 + LDC * 1 + 0x0]);
    vaddps(ymm9, ymm0, ymm9);
    vmovups(yword[CO1 + LDC * 1 + 0x0], ymm9);
    vmovups(ymm0, yword[CO2]);
    vaddps(ymm10, ymm0, ymm10);
    vmovups(yword[CO2], ymm10);
    vmovups(ymm0, yword[CO2 + LDC * 1]);
    vaddps(ymm11, ymm0, ymm11);
    vmovups(yword[CO2 + LDC * 1], ymm11);
    lea(CO1, ptr[CO1 + LDC * 4 + 0x0]);
    sub(I, 0x4);
    cmp(I, 0x4);
    jge(labels[2], T_NEAR);
    align(4);

    L(labels[9]);
    test(I, 0x2);
    jle(labels[16], T_NEAR);
    vxorps(ymm8, ymm8, ymm8);
    vbroadcastf128(ymm2, xword[BO - 0x80]);
    vxorps(ymm9, ymm9, ymm9);
    vmovups(ymm0, yword[A - 0x80]);
    vxorps(ymm10, ymm10, ymm10);
    vmovups(ymm1, yword[A - 0x60]);
    vxorps(ymm11, ymm11, ymm11);
    lea(CO2, ptr[CO1 + LDC * 2 + 0x0]);
    vxorps(ymm12, ymm12, ymm12);
    vxorps(ymm13, ymm13, ymm13);
    vxorps(ymm14, ymm14, ymm14);
    vxorps(ymm15, ymm15, ymm15);
    mov(AO, A);
    mov(H, K);
    sar(H, 0x2);
    jle(labels[13], T_NEAR);
    sub(H, 0x1e);
    jle(labels[11], T_NEAR);
    align(4);

    L(labels[10]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x78]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x60]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x40]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x68]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x20]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x60]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    sub(AO, -128);
    sub(BO, -32);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[10], T_NEAR);
    align(4);

    L(labels[11]);
    prefetcht0(byte[CO1 + 0x1c]);
    prefetcht0(byte[CO1 + LDC * 1 + 0x1c]);
    add(H, 0x1e);
    align(4);

    L(labels[12]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x78]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x60]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x40]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x68]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x20]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x60]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    sub(AO, -128);
    sub(BO, -32);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[12], T_NEAR);
    align(4);

    L(labels[13]);
    mov(H, K);
    and_(H, 0x3);
    je(labels[15], T_NEAR);
    align(4);

    L(labels[14]);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm8, ymm8, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm9, ymm9, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm10, ymm10, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm11, ymm11, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm15, ymm15, ymm7);
    vmovups(ymm0, yword[AO - 0x60]);
    vmovups(ymm1, yword[AO - 0x40]);
    vbroadcastf128(ymm2, xword[BO - 0x78]);
    sub(AO, -32);
    sub(BO, -8);
    dec(H);
    jg(labels[14], T_NEAR);
    align(4);

    L(labels[15]);
    vblendps(ymm0, ymm8, ymm9, 0xaa);
    vblendps(ymm1, ymm8, ymm9, 0x55);
    vblendps(ymm2, ymm10, ymm11, 0xaa);
    vblendps(ymm3, ymm10, ymm11, 0x55);
    vblendps(ymm8, ymm0, ymm2, 0xcc);
    vblendps(ymm9, ymm1, ymm3, 0xcc);
    vblendps(ymm10, ymm0, ymm2, 0x33);
    vblendps(ymm11, ymm1, ymm3, 0x33);
    vmovups(ymm0, yword[CO1 + 0x0]);
    vaddps(ymm8, ymm0, ymm8);
    vmovups(yword[CO1 + 0x0], ymm8);
    vmovups(ymm0, yword[CO1 + LDC * 1 + 0x0]);
    vaddps(ymm9, ymm0, ymm9);
    vmovups(yword[CO1 + LDC * 1 + 0x0], ymm9);
    lea(CO1, ptr[CO1 + LDC * 2 + 0x0]);
    align(4);

    L(labels[16]);
    test(I, 0x1);
    jle(l1f44, T_NEAR);
    vxorps(ymm8, ymm8, ymm8);
    vbroadcastf128(ymm2, xword[BO - 0x80]);
    vxorps(ymm9, ymm9, ymm9);
    vmovups(ymm0, yword[A - 0x80]);
    vxorps(ymm10, ymm10, ymm10);
    vmovups(ymm1, yword[A - 0x60]);
    vxorps(ymm11, ymm11, ymm11);
    lea(CO2, ptr[CO1 + LDC * 2 + 0x0]);
    vxorps(ymm12, ymm12, ymm12);
    vxorps(ymm13, ymm13, ymm13);
    vxorps(ymm14, ymm14, ymm14);
    vxorps(ymm15, ymm15, ymm15);
    mov(AO, A);
    mov(H, K);
    sar(H, 0x2);
    jle(labels[20], T_NEAR);
    sub(H, 0x1e);
    jle(labels[18], T_NEAR);
    align(4);

    L(labels[17]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x7c]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x60]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x40]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x78]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x74]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x20]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    sub(AO, -128);
    sub(BO, -16);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[17], T_NEAR);
    align(4);

    L(labels[18]);
    prefetcht0(byte[CO1 + 0x1c]);
    add(H, 0x1e);
    align(4);

    L(labels[19]);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x180]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    prefetcht0(byte[BO + 0x100]);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x7c]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x60]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO - 0x40]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x1c0]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x78]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    prefetcht0(byte[AA - 0x80]);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO - 0x40]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO - 0x20]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm2, ymm0);
    prefetcht0(byte[AO + 0x200]);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm3, xword[BO - 0x74]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm6, ymm2, ymm0);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm6, ymm2, ymm0);
    vmovups(ymm0, yword[AO - 0x20]);
    vmulps(ymm7, ymm2, ymm1);
    vmovups(ymm1, yword[AO]);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    vmulps(ymm6, ymm3, ymm0);
    prefetcht0(byte[AO + 0x240]);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm8, ymm8, ymm6);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm9, ymm9, ymm6);
    vbroadcastf128(ymm2, xword[BO - 0x70]);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm3, ymm3, 0x1b);
    vmulps(ymm6, ymm3, ymm0);
    vmulps(ymm7, ymm3, ymm1);
    vaddps(ymm10, ymm10, ymm6);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm3, ymm3, 0xb1);
    add(AA, 0x4);
    vmulps(ymm6, ymm3, ymm0);
    vmovups(ymm0, yword[AO]);
    vmulps(ymm7, ymm3, ymm1);
    vmovups(ymm1, yword[AO + 0x20]);
    sub(AO, -128);
    sub(BO, -16);
    vaddps(ymm11, ymm11, ymm6);
    vaddps(ymm15, ymm15, ymm7);
    sub(H, 0x1);
    jg(labels[19], T_NEAR);
    align(4);

    L(labels[20]);
    mov(H, K);
    and_(H, 0x3);
    je(l1efc, T_NEAR);
    align(4);

    L(labels[21]);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm8, ymm8, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm12, ymm12, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm9, ymm9, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm13, ymm13, ymm7);
    vpermilps(ymm2, ymm2, 0x1b);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm10, ymm10, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm14, ymm14, ymm7);
    vpermilps(ymm2, ymm2, 0xb1);
    vmulps(ymm7, ymm2, ymm0);
    vaddps(ymm11, ymm11, ymm7);
    vmulps(ymm7, ymm2, ymm1);
    vaddps(ymm15, ymm15, ymm7);
    vmovups(ymm0, yword[AO - 0x60]);
    vmovups(ymm1, yword[AO - 0x40]);
    vbroadcastf128(ymm2, xword[BO - 0x7c]);
    sub(AO, -32);
    sub(BO, -4);
    dec(H);
    jg(labels[21], T_NEAR);
    align(4);
}

} // namespace x64
} // namespace cpu
} // namespace impl
} // namespace dnnl
