/*******************************************************************************
* Copyright 2019 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/jit_generator.hpp"

#include "cpu/x64/gemm/f32/common_f32.hpp"
#include "cpu/x64/gemm/f32/jit_avx512_core_f32_copy_at_kern_autogen.hpp"

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

jit_avx512_core_f32_copy_at_kern_t::jit_avx512_core_f32_copy_at_kern_t()
    : jit_generator_t(jit_name()) {}

void jit_avx512_core_f32_copy_at_kern_t::generate() {
    Xbyak::Label l1f80;
    Xbyak::Label l22b8;
    Xbyak::Label l2a5c;
    Xbyak::Label l4000;

    preamble();
#ifdef _WIN32
    auto stacksize = get_size_of_abi_save_regs();
    mov(ALPHA, ptr[ARG_ALPHA]);
    mov(B, ptr[ARG_B]);
#endif

    mov(M, qword[M]);
    mov(N, qword[N]);
    mov(LDA, qword[LDA]);
    generate_part1(l4000, l2a5c, l22b8, l1f80);
    generate_part2(l4000, l2a5c, l22b8, l1f80);

    postamble();
}
void jit_avx512_core_f32_copy_at_kern_t::generate_part1(
        const Xbyak::Label &l4000, const Xbyak::Label &l2a5c,
        const Xbyak::Label &l22b8, const Xbyak::Label &l1f80) {
    Xbyak::Label l1d30;
    Xbyak::Label l1d0c;
    Xbyak::Label l1cfc;
    Xbyak::Label l1aac;
    Xbyak::Label l1844;
    Xbyak::Label l14d8;
    Xbyak::Label l14bc;
    Xbyak::Label l149c;
    Xbyak::Label l1494;
    Xbyak::Label l1490;
    Xbyak::Label l146c;
    Xbyak::Label l143c;
    Xbyak::Label l13fc;
    Xbyak::Label l13dc;
    Xbyak::Label l13d8;
    Xbyak::Label l13a8;
    Xbyak::Label l1374;
    Xbyak::Label l1334;
    Xbyak::Label l1314;
    Xbyak::Label l1310;
    Xbyak::Label l12cc;
    Xbyak::Label l1280;
    Xbyak::Label l1220;
    Xbyak::Label l1200;
    Xbyak::Label l11fc;
    Xbyak::Label l118c;
    Xbyak::Label l1118;
    Xbyak::Label l1078;
    Xbyak::Label l1054;
    Xbyak::Label l1050;
    Xbyak::Label lf84;
    Xbyak::Label leb4;
    Xbyak::Label ld9c;
    Xbyak::Label ld78;
    Xbyak::Label ld74;
    Xbyak::Label lbf4;
    Xbyak::Label la68;
    Xbyak::Label l848;
    Xbyak::Label l824;
    Xbyak::Label l814;
    Xbyak::Label l5dc;
    Xbyak::Label l398;
    Xbyak::Label l74;
    Xbyak::Label l58;

    sub(A, 0x0);
    sub(B, -128);
    shl(LDA, 0x2);
    lea(LDA3, ptr[LDA + LDA * 2]);
    vbroadcastss(zmm6, dword[ALPHA]);
    vpcmpeqb(xmm3, xmm3, xmm3);
    vpsrld(xmm3, xmm3, 0x17);
    vpslld(xmm3, xmm3, 0x19);
    vpsrld(xmm3, xmm3, 0x2);
    vpcmpeqb(xmm4, xmm4, xmm4);
    vpslld(xmm4, xmm4, 0x1f);
    vbroadcastss(zmm4, xmm4);
    vucomiss(xmm6, xmm3);
    jne(l149c, T_NEAR);
    cmp(N, 0x30);
    jl(l824, T_NEAR);
    align(4);

    L(l58);
    mov(A1, A);
    mov(I, LDA);
    imul(I, I, 0x30);
    add(A, I);
    mov(I, M);
    sar(I, 0x2);
    jle(l398, T_NEAR);
    align(4);

    L(l74);
    vmovups(xmm4, xword[A1]);
    vmovups(xmm5, xword[A1 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A1 + LDA * 8]);
    vmovups(xmm5, xword[A1 + LDA3 * 4]);
    lea(A2, ptr[A1 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vmovups(zword[B - 0x80], zmm0);
    vmovups(zword[B + 0x40], zmm1);
    vmovups(zword[B + 0x100], zmm2);
    vmovups(zword[B + 0x1c0], zmm3);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    lea(A2, ptr[A2 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vmovups(zword[B - 0x40], zmm0);
    vmovups(zword[B + 0x80], zmm1);
    vmovups(zword[B + 0x140], zmm2);
    vmovups(zword[B + 0x200], zmm3);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    lea(A2, ptr[A2 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vmovups(zword[B], zmm0);
    vmovups(zword[B + 0xc0], zmm1);
    vmovups(zword[B + 0x180], zmm2);
    vmovups(zword[B + 0x240], zmm3);
    sub(A1, -16);
    sub(B, -768);
    dec(I);
    jg(l74, T_NEAR);
    align(4);

    L(l398);
    test(M, 0x2);
    jle(l5dc, T_NEAR);
    vmovsd(xmm0, qword[A1]);
    vmovsd(xmm1, qword[A1 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A1 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A1 + LDA3 * 1]);
    lea(A2, ptr[A1 + LDA * 4]);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm2, 0x20);
    vperm2f128(ymm1, ymm1, ymm3, 0x20);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm4, qword[A2]);
    vmovsd(xmm5, qword[A2 + LDA * 1]);
    vmovhps(xmm4, xmm4, qword[A2 + LDA * 2]);
    vmovhps(xmm5, xmm5, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm2, ymm4, 0x20);
    vperm2f128(ymm3, ymm3, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm2, 0x44);
    vshuff32x4(zmm1, zmm1, zmm3, 0x44);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm1, zmm0, zmm1);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vmovups(zword[B - 0x80], zmm0);
    vmovups(zword[B + 0x40], zmm1);
    vmovsd(xmm0, qword[A2]);
    vmovsd(xmm1, qword[A2 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A2 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm2, 0x20);
    vperm2f128(ymm1, ymm1, ymm3, 0x20);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm4, qword[A2]);
    vmovsd(xmm5, qword[A2 + LDA * 1]);
    vmovhps(xmm4, xmm4, qword[A2 + LDA * 2]);
    vmovhps(xmm5, xmm5, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm2, ymm4, 0x20);
    vperm2f128(ymm3, ymm3, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm2, 0x44);
    vshuff32x4(zmm1, zmm1, zmm3, 0x44);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm1, zmm0, zmm1);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vmovups(zword[B - 0x40], zmm0);
    vmovups(zword[B + 0x80], zmm1);
    vmovsd(xmm0, qword[A2]);
    vmovsd(xmm1, qword[A2 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A2 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm2, 0x20);
    vperm2f128(ymm1, ymm1, ymm3, 0x20);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm4, qword[A2]);
    vmovsd(xmm5, qword[A2 + LDA * 1]);
    vmovhps(xmm4, xmm4, qword[A2 + LDA * 2]);
    vmovhps(xmm5, xmm5, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm2, ymm4, 0x20);
    vperm2f128(ymm3, ymm3, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm2, 0x44);
    vshuff32x4(zmm1, zmm1, zmm3, 0x44);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm1, zmm0, zmm1);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vmovups(zword[B], zmm0);
    vmovups(zword[B + 0xc0], zmm1);
    sub(A1, -8);
    sub(B, -384);
    align(4);

    L(l5dc);
    test(M, 0x1);
    jle(l814, T_NEAR);
    vmovss(xmm0, dword[A1]);
    vmovss(xmm1, dword[A1 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A1 + LDA * 2]);
    vmovss(xmm3, dword[A1 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A1 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x80], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x60], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x40], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x20], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B + 0x20], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    sub(A1, -4);
    sub(B, -192);
    align(4);

    L(l814);
    sub(N, 0x30);
    cmp(N, 0x30);
    jge(l58, T_NEAR);
    align(4);

    L(l824);
    cmp(N, 0x20);
    jl(ld78, T_NEAR);
    mov(A1, A);
    mov(I, LDA);
    imul(I, I, 0x20);
    add(A, I);
    mov(I, M);
    sar(I, 0x2);
    jle(la68, T_NEAR);
    align(4);

    L(l848);
    vmovups(xmm4, xword[A1]);
    vmovups(xmm5, xword[A1 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A1 + LDA * 8]);
    vmovups(xmm5, xword[A1 + LDA3 * 4]);
    lea(A2, ptr[A1 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vmovups(zword[B - 0x80], zmm0);
    vmovups(zword[B], zmm1);
    vmovups(zword[B + 0x80], zmm2);
    vmovups(zword[B + 0x100], zmm3);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    lea(A2, ptr[A2 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vmovups(zword[B - 0x40], zmm0);
    vmovups(zword[B + 0x40], zmm1);
    vmovups(zword[B + 0xc0], zmm2);
    vmovups(zword[B + 0x140], zmm3);
    sub(A1, -16);
    sub(B, -512);
    dec(I);
    jg(l848, T_NEAR);
    align(4);

    L(la68);
    test(M, 0x2);
    jle(lbf4, T_NEAR);
    vmovsd(xmm0, qword[A1]);
    vmovsd(xmm1, qword[A1 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A1 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A1 + LDA3 * 1]);
    lea(A2, ptr[A1 + LDA * 4]);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm2, 0x20);
    vperm2f128(ymm1, ymm1, ymm3, 0x20);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm4, qword[A2]);
    vmovsd(xmm5, qword[A2 + LDA * 1]);
    vmovhps(xmm4, xmm4, qword[A2 + LDA * 2]);
    vmovhps(xmm5, xmm5, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm2, ymm4, 0x20);
    vperm2f128(ymm3, ymm3, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm2, 0x44);
    vshuff32x4(zmm1, zmm1, zmm3, 0x44);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm1, zmm0, zmm1);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vmovups(zword[B - 0x80], zmm0);
    vmovups(zword[B], zmm1);
    vmovsd(xmm0, qword[A2]);
    vmovsd(xmm1, qword[A2 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A2 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm2, 0x20);
    vperm2f128(ymm1, ymm1, ymm3, 0x20);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm4, qword[A2]);
    vmovsd(xmm5, qword[A2 + LDA * 1]);
    vmovhps(xmm4, xmm4, qword[A2 + LDA * 2]);
    vmovhps(xmm5, xmm5, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm2, ymm4, 0x20);
    vperm2f128(ymm3, ymm3, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm2, 0x44);
    vshuff32x4(zmm1, zmm1, zmm3, 0x44);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm1, zmm0, zmm1);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vmovups(zword[B - 0x40], zmm0);
    vmovups(zword[B + 0x40], zmm1);
    sub(A1, -8);
    sub(B, -256);
    align(4);

    L(lbf4);
    test(M, 0x1);
    jle(ld74, T_NEAR);
    vmovss(xmm0, dword[A1]);
    vmovss(xmm1, dword[A1 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A1 + LDA * 2]);
    vmovss(xmm3, dword[A1 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A1 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x80], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x60], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x40], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x20], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    sub(A1, -4);
    sub(B, -128);
    align(4);

    L(ld74);
    sub(N, 0x20);
    align(4);

    L(ld78);
    cmp(N, 0x10);
    jl(l1054, T_NEAR);
    mov(A1, A);
    mov(I, LDA);
    imul(I, I, 0x10);
    add(A, I);
    mov(I, M);
    sar(I, 0x2);
    jle(leb4, T_NEAR);
    align(4);

    L(ld9c);
    vmovups(xmm4, xword[A1]);
    vmovups(xmm5, xword[A1 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A1 + LDA * 8]);
    vmovups(xmm5, xword[A1 + LDA3 * 4]);
    lea(A2, ptr[A1 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vmovups(zword[B - 0x80], zmm0);
    vmovups(zword[B - 0x40], zmm1);
    vmovups(zword[B], zmm2);
    vmovups(zword[B + 0x40], zmm3);
    sub(A1, -16);
    sub(B, -256);
    dec(I);
    jg(ld9c, T_NEAR);
    align(4);

    L(leb4);
    test(M, 0x2);
    jle(lf84, T_NEAR);
    vmovsd(xmm0, qword[A1]);
    vmovsd(xmm1, qword[A1 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A1 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A1 + LDA3 * 1]);
    lea(A2, ptr[A1 + LDA * 4]);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm2, 0x20);
    vperm2f128(ymm1, ymm1, ymm3, 0x20);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm4, qword[A2]);
    vmovsd(xmm5, qword[A2 + LDA * 1]);
    vmovhps(xmm4, xmm4, qword[A2 + LDA * 2]);
    vmovhps(xmm5, xmm5, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm2, ymm4, 0x20);
    vperm2f128(ymm3, ymm3, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm2, 0x44);
    vshuff32x4(zmm1, zmm1, zmm3, 0x44);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm1, zmm0, zmm1);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vmovups(zword[B - 0x80], zmm0);
    vmovups(zword[B - 0x40], zmm1);
    sub(A1, -8);
    sub(B, -128);
    align(4);

    L(lf84);
    test(M, 0x1);
    jle(l1050, T_NEAR);
    vmovss(xmm0, dword[A1]);
    vmovss(xmm1, dword[A1 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A1 + LDA * 2]);
    vmovss(xmm3, dword[A1 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A1 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x80], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x60], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    sub(A1, -4);
    sub(B, -64);
    align(4);

    L(l1050);
    sub(N, 0x10);
    align(4);

    L(l1054);
    cmp(N, 0x8);
    jl(l1200, T_NEAR);
    mov(A1, A);
    mov(I, LDA);
    imul(I, I, 0x8);
    add(A, I);
    mov(I, M);
    sar(I, 0x2);
    jle(l1118, T_NEAR);
    align(4);

    L(l1078);
    vmovups(xmm0, xword[A1]);
    vmovups(xmm4, xword[A1 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm4, 0x20);
    lea(A2, ptr[A1 + LDA * 1]);
    vmovups(xmm1, xword[A2]);
    vmovups(xmm4, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm1, ymm4, 0x20);
    add(A2, LDA);
    vmovups(xmm2, xword[A2]);
    vmovups(xmm4, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm2, ymm4, 0x20);
    add(A2, LDA);
    vmovups(xmm3, xword[A2]);
    vmovups(xmm4, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm3, ymm4, 0x20);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA * 4]);
    vunpcklps(ymm4, ymm0, ymm1);
    vunpckhps(ymm5, ymm0, ymm1);
    vunpcklps(ymm1, ymm2, ymm3);
    vunpckhps(ymm3, ymm2, ymm3);
    vunpcklpd(ymm0, ymm4, ymm1);
    vunpckhpd(ymm1, ymm4, ymm1);
    vunpcklpd(ymm2, ymm5, ymm3);
    vunpckhpd(ymm3, ymm5, ymm3);
    vmovups(yword[B - 0x80], ymm0);
    vmovups(yword[B - 0x60], ymm1);
    vmovups(yword[B - 0x40], ymm2);
    vmovups(yword[B - 0x20], ymm3);
    sub(A1, -16);
    sub(B, -128);
    dec(I);
    jg(l1078, T_NEAR);
    align(4);

    L(l1118);
    test(M, 0x2);
    jle(l118c, T_NEAR);
    vmovsd(xmm0, qword[A1]);
    vmovsd(xmm1, qword[A1 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A1 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A1 + LDA3 * 1]);
    lea(A2, ptr[A1 + LDA * 4]);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm2, 0x20);
    vperm2f128(ymm1, ymm1, ymm3, 0x20);
    vunpcklps(ymm4, ymm0, ymm1);
    vunpckhps(ymm1, ymm0, ymm1);
    vunpcklpd(ymm0, ymm4, ymm1);
    vunpckhpd(ymm1, ymm4, ymm1);
    vmovups(yword[B - 0x80], ymm0);
    vmovups(yword[B - 0x60], ymm1);
    sub(A1, -8);
    sub(B, -64);
    align(4);

    L(l118c);
    test(M, 0x1);
    jle(l11fc, T_NEAR);
    vmovss(xmm0, dword[A1]);
    vmovss(xmm1, dword[A1 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A1 + LDA * 2]);
    vmovss(xmm3, dword[A1 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A1 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vmovups(yword[B - 0x80], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    sub(A1, -4);
    sub(B, -32);
    align(4);

    L(l11fc);
    sub(N, 0x8);
    align(4);

    L(l1200);
    cmp(N, 0x4);
    jl(l1314, T_NEAR);
    mov(A1, A);
    mov(I, LDA);
    imul(I, I, 0x4);
    add(A, I);
    mov(I, M);
    sar(I, 0x2);
    jle(l1280, T_NEAR);
    align(4);

    L(l1220);
    vmovups(xmm0, xword[A1]);
    vmovups(xmm1, xword[A1 + LDA * 1]);
    vmovups(xmm2, xword[A1 + LDA * 2]);
    vmovups(xmm3, xword[A1 + LDA3 * 1]);
    vunpcklps(xmm4, xmm0, xmm1);
    vunpckhps(xmm5, xmm0, xmm1);
    vunpcklps(xmm1, xmm2, xmm3);
    vunpckhps(xmm3, xmm2, xmm3);
    vunpcklpd(xmm0, xmm4, xmm1);
    vunpckhpd(xmm1, xmm4, xmm1);
    vunpcklpd(xmm2, xmm5, xmm3);
    vunpckhpd(xmm3, xmm5, xmm3);
    vmovups(xword[B - 0x80], xmm0);
    vmovups(xword[B - 0x70], xmm1);
    vmovups(xword[B - 0x60], xmm2);
    vmovups(xword[B - 0x50], xmm3);
    lea(A2, ptr[A1 + LDA * 4]);
    sub(A1, -16);
    sub(B, -64);
    dec(I);
    jg(l1220, T_NEAR);
    align(4);

    L(l1280);
    test(M, 0x2);
    jle(l12cc, T_NEAR);
    vmovsd(xmm0, qword[A1]);
    vmovsd(xmm1, qword[A1 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A1 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A1 + LDA3 * 1]);
    vunpcklps(xmm4, xmm0, xmm1);
    vunpckhps(xmm1, xmm0, xmm1);
    vunpcklpd(xmm0, xmm4, xmm1);
    vunpckhpd(xmm1, xmm4, xmm1);
    vmovups(xword[B - 0x80], xmm0);
    vmovups(xword[B - 0x70], xmm1);
    lea(A2, ptr[A1 + LDA * 4]);
    sub(A1, -8);
    sub(B, -32);
    align(4);

    L(l12cc);
    test(M, 0x1);
    jle(l1310, T_NEAR);
    vmovss(xmm0, dword[A1]);
    vmovss(xmm1, dword[A1 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A1 + LDA * 2]);
    vmovss(xmm3, dword[A1 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vmovups(xword[B - 0x80], xmm0);
    lea(A2, ptr[A1 + LDA * 4]);
    sub(A1, -4);
    sub(B, -16);
    align(4);

    L(l1310);
    sub(N, 0x4);
    align(4);

    L(l1314);
    cmp(N, 0x2);
    jl(l13dc, T_NEAR);
    mov(A1, A);
    mov(I, LDA);
    imul(I, I, 0x2);
    add(A, I);
    mov(I, M);
    sar(I, 0x2);
    jle(l1374, T_NEAR);
    align(4);

    L(l1334);
    vmovups(xmm0, xword[A1]);
    vmovups(xmm1, xword[A1 + LDA * 1]);
    vunpcklps(xmm4, xmm0, xmm1);
    vunpckhps(xmm1, xmm0, xmm1);
    vmovaps(xmm0, xmm4);
    vmovlps(qword[B - 0x80], xmm0);
    vmovhps(qword[B - 0x78], xmm0);
    vmovlps(qword[B - 0x70], xmm1);
    vmovhps(qword[B - 0x68], xmm1);
    lea(A2, ptr[A1 + LDA * 2]);
    sub(A1, -16);
    sub(B, -32);
    dec(I);
    jg(l1334, T_NEAR);
    align(4);

    L(l1374);
    test(M, 0x2);
    jle(l13a8, T_NEAR);
    vmovsd(xmm0, qword[A1]);
    vmovsd(xmm1, qword[A1 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovlps(qword[B - 0x80], xmm0);
    vmovhps(qword[B - 0x78], xmm0);
    lea(A2, ptr[A1 + LDA * 2]);
    sub(A1, -8);
    sub(B, -16);
    align(4);

    L(l13a8);
    test(M, 0x1);
    jle(l13d8, T_NEAR);
    vmovss(xmm0, dword[A1]);
    vmovss(xmm1, dword[A1 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovlps(qword[B - 0x80], xmm0);
    lea(A2, ptr[A1 + LDA * 2]);
    sub(A1, -4);
    sub(B, -8);
    align(4);

    L(l13d8);
    sub(N, 0x2);
    align(4);

    L(l13dc);
    cmp(N, 0x1);
    jl(l1494, T_NEAR);
    mov(A1, A);
    mov(I, LDA);
    imul(I, I, 0x1);
    add(A, I);
    mov(I, M);
    sar(I, 0x2);
    jle(l143c, T_NEAR);
    align(4);

    L(l13fc);
    vmovups(xmm0, xword[A1]);
    vpshufd(xmm1, xmm0, 0x55);
    vpshufd(xmm2, xmm0, 0xaa);
    vpshufd(xmm3, xmm0, 0xff);
    vmovss(dword[B - 0x80], xmm0);
    vmovss(dword[B - 0x7c], xmm1);
    vmovss(dword[B - 0x78], xmm2);
    vmovss(dword[B - 0x74], xmm3);
    lea(A2, ptr[A1 + LDA * 1]);
    sub(A1, -16);
    sub(B, -16);
    dec(I);
    jg(l13fc, T_NEAR);
    align(4);

    L(l143c);
    test(M, 0x2);
    jle(l146c, T_NEAR);
    vmovsd(xmm0, qword[A1]);
    vpshufd(xmm1, xmm0, 0x55);
    vmovss(dword[B - 0x80], xmm0);
    vmovss(dword[B - 0x7c], xmm1);
    lea(A2, ptr[A1 + LDA * 1]);
    sub(A1, -8);
    sub(B, -8);
    align(4);

    L(l146c);
    test(M, 0x1);
    jle(l1490, T_NEAR);
    vmovss(xmm0, dword[A1]);
    vmovss(dword[B - 0x80], xmm0);
    lea(A2, ptr[A1 + LDA * 1]);
    sub(A1, -4);
    sub(B, -4);
    align(4);

    L(l1490);
    sub(N, 0x1);
    align(4);

    L(l1494);
    jmp(l4000, T_NEAR);
    align(4);

    L(l149c);
    vxorps(xmm3, xmm3, xmm4);
    vucomiss(xmm6, xmm3);
    jne(l2a5c, T_NEAR);
    vmovaps(zmm6, zmm4);
    cmp(N, 0x30);
    jl(l1d0c, T_NEAR);
    align(4);

    L(l14bc);
    mov(A1, A);
    mov(I, LDA);
    imul(I, I, 0x30);
    add(A, I);
    mov(I, M);
    sar(I, 0x2);
    jle(l1844, T_NEAR);
    align(4);

    L(l14d8);
    vmovups(xmm4, xword[A1]);
    vmovups(xmm5, xword[A1 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A1 + LDA * 8]);
    vmovups(xmm5, xword[A1 + LDA3 * 4]);
    lea(A2, ptr[A1 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vpxorq(zmm0, zmm6, zmm0);
    vpxorq(zmm1, zmm6, zmm1);
    vpxorq(zmm2, zmm6, zmm2);
    vpxorq(zmm3, zmm6, zmm3);
    vmovups(zword[B - 0x80], zmm0);
    vmovups(zword[B + 0x40], zmm1);
    vmovups(zword[B + 0x100], zmm2);
    vmovups(zword[B + 0x1c0], zmm3);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    lea(A2, ptr[A2 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vpxorq(zmm0, zmm6, zmm0);
    vpxorq(zmm1, zmm6, zmm1);
    vpxorq(zmm2, zmm6, zmm2);
    vpxorq(zmm3, zmm6, zmm3);
    vmovups(zword[B - 0x40], zmm0);
    vmovups(zword[B + 0x80], zmm1);
    vmovups(zword[B + 0x140], zmm2);
    vmovups(zword[B + 0x200], zmm3);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    lea(A2, ptr[A2 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vpxorq(zmm0, zmm6, zmm0);
    vpxorq(zmm1, zmm6, zmm1);
    vpxorq(zmm2, zmm6, zmm2);
    vpxorq(zmm3, zmm6, zmm3);
    vmovups(zword[B], zmm0);
    vmovups(zword[B + 0xc0], zmm1);
    vmovups(zword[B + 0x180], zmm2);
    vmovups(zword[B + 0x240], zmm3);
    sub(A1, -16);
    sub(B, -768);
    dec(I);
    jg(l14d8, T_NEAR);
    align(4);

    L(l1844);
    test(M, 0x2);
    jle(l1aac, T_NEAR);
    vmovsd(xmm0, qword[A1]);
    vmovsd(xmm1, qword[A1 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A1 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A1 + LDA3 * 1]);
    lea(A2, ptr[A1 + LDA * 4]);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm2, 0x20);
    vperm2f128(ymm1, ymm1, ymm3, 0x20);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm4, qword[A2]);
    vmovsd(xmm5, qword[A2 + LDA * 1]);
    vmovhps(xmm4, xmm4, qword[A2 + LDA * 2]);
    vmovhps(xmm5, xmm5, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm2, ymm4, 0x20);
    vperm2f128(ymm3, ymm3, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm2, 0x44);
    vshuff32x4(zmm1, zmm1, zmm3, 0x44);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm1, zmm0, zmm1);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vpxorq(zmm0, zmm6, zmm0);
    vpxorq(zmm1, zmm6, zmm1);
    vmovups(zword[B - 0x80], zmm0);
    vmovups(zword[B + 0x40], zmm1);
    vmovsd(xmm0, qword[A2]);
    vmovsd(xmm1, qword[A2 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A2 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm2, 0x20);
    vperm2f128(ymm1, ymm1, ymm3, 0x20);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm4, qword[A2]);
    vmovsd(xmm5, qword[A2 + LDA * 1]);
    vmovhps(xmm4, xmm4, qword[A2 + LDA * 2]);
    vmovhps(xmm5, xmm5, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm2, ymm4, 0x20);
    vperm2f128(ymm3, ymm3, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm2, 0x44);
    vshuff32x4(zmm1, zmm1, zmm3, 0x44);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm1, zmm0, zmm1);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vpxorq(zmm0, zmm6, zmm0);
    vpxorq(zmm1, zmm6, zmm1);
    vmovups(zword[B - 0x40], zmm0);
    vmovups(zword[B + 0x80], zmm1);
    vmovsd(xmm0, qword[A2]);
    vmovsd(xmm1, qword[A2 + LDA * 1]);
    vmovhps(xmm0, xmm0, qword[A2 + LDA * 2]);
    vmovhps(xmm1, xmm1, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm0, ymm2, 0x20);
    vperm2f128(ymm1, ymm1, ymm3, 0x20);
    vmovsd(xmm2, qword[A2]);
    vmovsd(xmm3, qword[A2 + LDA * 1]);
    vmovhps(xmm2, xmm2, qword[A2 + LDA * 2]);
    vmovhps(xmm3, xmm3, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovsd(xmm4, qword[A2]);
    vmovsd(xmm5, qword[A2 + LDA * 1]);
    vmovhps(xmm4, xmm4, qword[A2 + LDA * 2]);
    vmovhps(xmm5, xmm5, qword[A2 + LDA3 * 1]);
    lea(A2, ptr[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm2, ymm4, 0x20);
    vperm2f128(ymm3, ymm3, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm2, 0x44);
    vshuff32x4(zmm1, zmm1, zmm3, 0x44);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm1, zmm0, zmm1);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vpxorq(zmm0, zmm6, zmm0);
    vpxorq(zmm1, zmm6, zmm1);
    vmovups(zword[B], zmm0);
    vmovups(zword[B + 0xc0], zmm1);
    sub(A1, -8);
    sub(B, -384);
    align(4);

    L(l1aac);
    test(M, 0x1);
    jle(l1cfc, T_NEAR);
    vmovss(xmm0, dword[A1]);
    vmovss(xmm1, dword[A1 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A1 + LDA * 2]);
    vmovss(xmm3, dword[A1 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A1 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vxorps(ymm0, ymm6, ymm0);
    vmovups(yword[B - 0x80], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vxorps(ymm0, ymm6, ymm0);
    vmovups(yword[B - 0x60], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vxorps(ymm0, ymm6, ymm0);
    vmovups(yword[B - 0x40], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vxorps(ymm0, ymm6, ymm0);
    vmovups(yword[B - 0x20], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vxorps(ymm0, ymm6, ymm0);
    vmovups(yword[B], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm4, xmm0, xmm2);
    lea(A2, ptr[A2 + LDA * 4]);
    vmovss(xmm0, dword[A2]);
    vmovss(xmm1, dword[A2 + LDA * 1]);
    vunpcklps(xmm0, xmm0, xmm1);
    vmovss(xmm2, dword[A2 + LDA * 2]);
    vmovss(xmm3, dword[A2 + LDA3 * 1]);
    vunpcklps(xmm2, xmm2, xmm3);
    vunpcklpd(xmm0, xmm0, xmm2);
    vperm2f128(ymm0, ymm0, ymm4, 0x2);
    vxorps(ymm0, ymm6, ymm0);
    vmovups(yword[B + 0x20], ymm0);
    lea(A2, ptr[A2 + LDA * 4]);
    sub(A1, -4);
    sub(B, -192);
    align(4);

    L(l1cfc);
    sub(N, 0x30);
    cmp(N, 0x30);
    jge(l14bc, T_NEAR);
    align(4);

    L(l1d0c);
    cmp(N, 0x20);
    jl(l22b8, T_NEAR);
    mov(A1, A);
    mov(I, LDA);
    imul(I, I, 0x20);
    add(A, I);
    mov(I, M);
    sar(I, 0x2);
    jle(l1f80, T_NEAR);
    align(4);

    L(l1d30);
    vmovups(xmm4, xword[A1]);
    vmovups(xmm5, xword[A1 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A1 + LDA * 8]);
    vmovups(xmm5, xword[A1 + LDA3 * 4]);
    lea(A2, ptr[A1 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vpxorq(zmm0, zmm6, zmm0);
    vpxorq(zmm1, zmm6, zmm1);
    vpxorq(zmm2, zmm6, zmm2);
    vpxorq(zmm3, zmm6, zmm3);
    vmovups(zword[B - 0x80], zmm0);
    vmovups(zword[B], zmm1);
    vmovups(zword[B + 0x80], zmm2);
    vmovups(zword[B + 0x100], zmm3);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm0, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    lea(A2, ptr[A2 + LDA * 1]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm0, zmm0, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm1, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm1, zmm1, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm2, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    add(A2, LDA);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm2, zmm2, zmm4, 0x44);
    vmovups(xmm4, xword[A2]);
    vmovups(xmm5, xword[A2 + LDA * 4]);
    vperm2f128(ymm3, ymm4, ymm5, 0x20);
    vmovups(xmm4, xword[A2 + LDA * 8]);
    vmovups(xmm5, xword[A2 + LDA3 * 4]);
    vperm2f128(ymm4, ymm4, ymm5, 0x20);
    vshuff32x4(zmm3, zmm3, zmm4, 0x44);
    add(A2, LDA);
    lea(A2, ptr[A2 + LDA3 * 4]);
    vunpcklps(zmm4, zmm0, zmm1);
    vunpckhps(zmm5, zmm0, zmm1);
    vunpcklps(zmm1, zmm2, zmm3);
    vunpckhps(zmm3, zmm2, zmm3);
    vunpcklpd(zmm0, zmm4, zmm1);
    vunpckhpd(zmm1, zmm4, zmm1);
    vunpcklpd(zmm2, zmm5, zmm3);
    vunpckhpd(zmm3, zmm5, zmm3);
    vpxorq(zmm0, zmm6, zmm0);
    vpxorq(zmm1, zmm6, zmm1);
    vpxorq(zmm2, zmm6, zmm2);
    vpxorq(zmm3, zmm6, zmm3);
    vmovups(zword[B - 0x40], zmm0);
    vmovups(zword[B + 0x40], zmm1);
    vmovups(zword[B + 0xc0], zmm2);
    vmovups(zword[B + 0x140], zmm3);
    sub(A1, -16);
    sub(B, -512);
    dec(I);
    jg(l1d30, T_NEAR);
    align(4);
}

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