// File: /workspace/github_cpp_makefile_star2_O1/Baobaobear[P]sort/./grailsort.hpp
// Function: void Mrrl::grail_BuildBlocks<baobao::TestClass*, baobao::TestClass*, std::less<baobao::TestClass>>(baobao::TestClass*, baobao::TestClass*, int, baobao::TestClass*, int, std::less<baobao::TestClass>)
void grail_BuildBlocks(RandomAccessIterator beg, RandomAccessIterator end, int K, RandomAccessBufferIterator extbuf, int LExtBuf, Comp compare) {
    int h, restk, kbuf;
    kbuf = K < LExtBuf ? K : LExtBuf;
    while (kbuf&(kbuf - 1)) kbuf &= kbuf - 1;  // max power or 2 - just in case

    if (kbuf) {
        //memcpy(extbuf, &*(beg - kbuf), kbuf * sizeof(value_type)); // TODO
        for (int i = 0; i < kbuf; ++i)
        {
            *(extbuf + i) = *(beg - kbuf + i);
        }
        for (RandomAccessIterator m = beg + 1; m < end; m += 2) {
            int u = 0;
            if (compare(*m, *(m - 1))) u = 1;
            *(m - 3) = *(m - 1 + u);
            *(m - 2) = *(m - u);
        }
        if ((end - beg) % 2) *(end - 3) = *(end - 1);
        beg -= 2; end -= 2;
        for (h = 2; h < kbuf; h *= 2) {
            RandomAccessIterator p0 = beg;
            RandomAccessIterator p1 = end - 2 * h;
            while (p0 <= p1) {
                grail_MergeLeftWithXBuf(p0, p0 + h, p0 + h + h, p0 - h, compare);
                p0 += 2 * h;
            }
            if (end - p0 > h) {
                grail_MergeLeftWithXBuf(p0, p0 + h, end, p0 - h, compare);
            }
            else {
                for (; p0 < end; p0++) *(p0 - h) = *p0;
            }
            beg -= h; end -= h;
        }
        //memcpy(&*end, extbuf, kbuf * sizeof(value_type)); // TODO
        for (int i = 0; i < kbuf; ++i)
        {
            *(end + i) = *(extbuf + i);
        }
    }
    else {
        for (RandomAccessIterator m = beg + 1; m < end; m += 2) {
            int u = 0;
            if (compare(*m, *(m - 1))) u = 1;
            grail_swap1(m - 3, m - 1 + u);
            grail_swap1(m - 2, m - u);
        }
        if ((end - beg) % 2) grail_swap1(end - 1, end - 3);
        beg -= 2; end -= 2;
        h = 2;
    }
    for (; h < K; h *= 2) {
        RandomAccessIterator p0 = beg;
        RandomAccessIterator p1 = end - 2 * h;
        while (p0 <= p1) {
            grail_MergeLeft(p0, p0 + h, p0 + h + h, p0 - h, compare);
            p0 += 2 * h;
        }
        if (end - p0 > h) {
            grail_MergeLeft(p0, p0 + h, end, p0 - h, compare);
        }
        else grail_rotate(p0 - h, p0, end);
        beg -= h; end -= h;
    }
    restk = (end - beg) % (2 * K);
    RandomAccessIterator p = end - restk;
    if (restk <= K) grail_rotate(p, p + restk, p + restk + K);
    else grail_MergeRight(p, p + K, p + restk, p + restk + K, compare);
    while (p > beg) {
        p -= 2 * K;
        grail_MergeRight(p, p + K, p + K + K, p + K + K + K, compare);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rsi, %rbp
movq %rdi, %r15
cmpl %r8d, %edx
movq %rdx, 0x38(%rsp)
cmovll %edx, %r8d
movl %r8d, %r13d
leal -0x1(%r13), %r8d
andl %r13d, %r8d
jne 0xbf2f
testl %r13d, %r13d
je 0xc210
movl %r13d, %r12d
jle 0xbf9e
movq %r12, %rdx
shlq $0x5, %rdx
movq %r15, %rax
subq %rdx, %rax
xorl %r9d, %r9d
movq %rax, %rdx
movq %rcx, %rsi
movq %r9, %rdi
shlq $0x5, %rdi
movl (%rax,%rdi), %r8d
movl %r8d, (%rcx,%rdi)
movl 0x4(%rax,%rdi), %r8d
movl %r8d, 0x4(%rcx,%rdi)
movl $0x2, %edi
movl (%rdx,%rdi,4), %r8d
movl %r8d, (%rsi,%rdi,4)
incq %rdi
cmpq $0x8, %rdi
jne 0xbf7d
incq %r9
addq $0x20, %rsi
addq $0x20, %rdx
cmpq %r12, %r9
jne 0xbf5f
leaq 0x20(%r15), %rax
cmpq %rbp, %rax
jae 0xc053
leaq -0x38(%r15), %r14
leaq 0x8(%r15), %rdx
leaq -0x18(%r15), %rsi
leaq 0x28(%r15), %rdi
movl -0x20(%rax), %r8d
movl (%rax), %r9d
xorl %r10d, %r10d
cmpl %r8d, %r9d
setl %r10b
shll $0x5, %r10d
movl -0x20(%rax,%r10), %r11d
movl %r11d, -0x60(%rax)
movl -0x1c(%rax,%r10), %r11d
movl %r11d, -0x5c(%rax)
addq %rdx, %r10
xorl %r11d, %r11d
movl (%r10,%r11,4), %ebx
movl %ebx, (%r14,%r11,4)
incq %r11
cmpq $0x6, %r11
jne 0xbfe8
xorl %r10d, %r10d
cmpl %r8d, %r9d
setl %r10b
shll $0x5, %r10d
movq %rax, %r8
subq %r10, %r8
movl (%r8), %r9d
movl %r9d, -0x40(%rax)
movl 0x4(%r8), %r8d
movl %r8d, -0x3c(%rax)
movq %rdi, %r8
subq %r10, %r8
xorl %r9d, %r9d
movl (%r8,%r9,4), %r10d
movl %r10d, (%rsi,%r9,4)
incq %r9
cmpq $0x6, %r9
jne 0xc025
addq $0x40, %rax
addq $0x40, %r14
addq $0x40, %rdx
addq $0x40, %rsi
addq $0x40, %rdi
cmpq %rbp, %rax
jb 0xbfbb
movl %ebp, %eax
subl %r15d, %eax
testb $0x20, %al
je 0xc074
movq -0x20(%rbp), %rax
movq %rax, -0x60(%rbp)
movups -0x18(%rbp), %xmm0
movups %xmm0, -0x58(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x48(%rbp)
movq %r12, 0x40(%rsp)
movq %rcx, 0x48(%rsp)
addq $-0x40, %r15
addq $-0x40, %rbp
movl $0x2, %r10d
cmpl $0x3, %r13d
jl 0xc1b4
movq %r13, 0x50(%rsp)
movl %r10d, %eax
movslq %r10d, %rcx
movq %rcx, 0x10(%rsp)
addl %eax, %eax
movl %eax, 0xc(%rsp)
movslq %eax, %r14
shlq $0x5, %r14
movq %rbp, 0x18(%rsp)
movq %rbp, %rbx
subq %r14, %rbx
movq %r15, %r13
movq %r15, (%rsp)
cmpq %rbx, %r15
ja 0xc102
movq 0x10(%rsp), %rbp
movq %rbp, %r15
shlq $0x5, %r15
movq %r15, %r12
negq %r12
shlq $0x6, %rbp
movq (%rsp), %r13
leaq (%r15,%r13), %rsi
movq %r13, %rdx
addq %rbp, %rdx
leaq (%r12,%r13), %rcx
movq %r13, %rdi
callq 0xcdb4
addq %r14, %r13
cmpq %rbx, %r13
jbe 0xc0e4
movq 0x18(%rsp), %rbp
movq %rbp, %rax
subq %r13, %rax
sarq $0x5, %rax
movq 0x10(%rsp), %rbx
cmpq %rbx, %rax
jle 0xc142
movq %rbx, %rax
shlq $0x5, %rax
leaq (%rax,%r13), %rsi
movq %r13, %rcx
subq %rax, %rcx
movq %r13, %rdi
movq %rbp, %rdx
callq 0xcdb4
movq (%rsp), %r15
movl 0xc(%rsp), %r10d
jmp 0xc19c
cmpq %rbp, %r13
movq (%rsp), %r15
movl 0xc(%rsp), %r10d
jae 0xc19c
movq %rbx, %rax
negq %rax
movq %rbx, %rdx
shlq $0x5, %rdx
movq %r13, %rcx
subq %rdx, %rcx
shlq $0x5, %rax
movl (%r13), %edx
movl %edx, (%r13,%rax)
movl 0x4(%r13), %edx
movl %edx, 0x4(%r13,%rax)
movl $0x2, %edx
movl (%r13,%rdx,4), %esi
movl %esi, (%rcx,%rdx,4)
incq %rdx
cmpq $0x8, %rdx
jne 0xc17e
addq $0x20, %r13
addq $0x20, %rcx
cmpq %rbp, %r13
jb 0xc167
shlq $0x5, %rbx
subq %rbx, %r15
subq %rbx, %rbp
movq 0x50(%rsp), %r13
cmpl %r13d, %r10d
jl 0xc09b
testl %r13d, %r13d
jle 0xc471
xorl %eax, %eax
movq 0x48(%rsp), %r8
movq %r8, %rcx
movq %rbp, %rdx
movq 0x40(%rsp), %r9
movq %rax, %rsi
shlq $0x5, %rsi
movl (%r8,%rsi), %edi
movl %edi, (%rbp,%rsi)
movl 0x4(%r8,%rsi), %edi
movl %edi, 0x4(%rbp,%rsi)
movl $0x2, %esi
movl (%rcx,%rsi,4), %edi
movl %edi, (%rdx,%rsi,4)
incq %rsi
cmpq $0x8, %rsi
jne 0xc1ec
incq %rax
addq $0x20, %rdx
addq $0x20, %rcx
cmpq %r9, %rax
jne 0xc1cf
jmp 0xc471
movq %r15, %r13
leaq 0x20(%r15), %rax
cmpq %rbp, %rax
jae 0xc33b
leaq -0x38(%r13), %rcx
leaq 0x8(%r13), %rdx
leaq -0x18(%r13), %rsi
leaq 0x28(%r13), %rdi
movq %rbp, %r12
movl -0x20(%rax), %r8d
movl (%rax), %r9d
xorl %r11d, %r11d
cmpl %r8d, %r9d
setl %r11b
shll $0x5, %r11d
leaq (%rax,%r11), %r10
addq $-0x20, %r10
movl -0x60(%rax), %ebx
movl -0x5c(%rax), %r14d
movq -0x48(%rax), %r15
movq %r15, 0x30(%rsp)
movups -0x58(%rax), %xmm0
movaps %xmm0, 0x20(%rsp)
movl (%r10), %ebp
movl %ebp, -0x60(%rax)
movl 0x4(%r10), %ebp
movl %ebp, -0x5c(%rax)
addq %rdx, %r11
xorl %r15d, %r15d
movl (%r11,%r15,4), %ebp
movl %ebp, (%rcx,%r15,4)
incq %r15
cmpq $0x6, %r15
jne 0xc27c
xorl %r15d, %r15d
cmpl %r8d, %r9d
setl %r15b
movl %ebx, (%r10)
movl %r14d, 0x4(%r10)
movq 0x30(%rsp), %r8
movq %r8, 0x18(%r10)
movaps 0x20(%rsp), %xmm0
movups %xmm0, 0x8(%r10)
shll $0x5, %r15d
movq %rax, %r8
subq %r15, %r8
movl -0x40(%rax), %r9d
movl -0x3c(%rax), %r10d
movq -0x28(%rax), %r11
movq %r11, 0x30(%rsp)
movups -0x38(%rax), %xmm0
movaps %xmm0, 0x20(%rsp)
movl (%r8), %r11d
movl %r11d, -0x40(%rax)
movl 0x4(%r8), %r11d
movl %r11d, -0x3c(%rax)
leaq 0x8(%r8), %r11
movq %rdi, %rbx
subq %r15, %rbx
xorl %r14d, %r14d
movl (%rbx,%r14,4), %ebp
movl %ebp, (%rsi,%r14,4)
incq %r14
cmpq $0x6, %r14
jne 0xc2f1
movl %r9d, (%r8)
movl %r10d, 0x4(%r8)
movq 0x30(%rsp), %r8
movq %r8, 0x10(%r11)
movaps 0x20(%rsp), %xmm0
movups %xmm0, (%r11)
addq $0x40, %rax
addq $0x40, %rcx
addq $0x40, %rdx
addq $0x40, %rsi
addq $0x40, %rdi
movq %r12, %rbp
cmpq %r12, %rax
jb 0xc230
movl %ebp, %eax
movq %r13, %r15
subl %r15d, %eax
testb $0x20, %al
je 0xc397
movl -0x20(%rbp), %eax
movl -0x1c(%rbp), %ecx
movq -0x8(%rbp), %rdx
movq %rdx, 0x30(%rsp)
movups -0x18(%rbp), %xmm0
movaps %xmm0, 0x20(%rsp)
movq -0x60(%rbp), %rdx
movq %rdx, -0x20(%rbp)
leaq -0x58(%rbp), %rdx
movq $-0x18, %rsi
movl -0x40(%rbp,%rsi), %edi
movl %edi, (%rbp,%rsi)
addq $0x4, %rsi
jne 0xc372
movl %eax, -0x60(%rbp)
movl %ecx, -0x5c(%rbp)
movq 0x30(%rsp), %rax
movq %rax, 0x10(%rdx)
movaps 0x20(%rsp), %xmm0
movups %xmm0, (%rdx)
addq $-0x40, %r15
addq $-0x40, %rbp
movl $0x2, %r10d
jmp 0xc471
movl %r10d, %eax
movslq %r10d, %rcx
movq %rcx, 0x10(%rsp)
addl %eax, %eax
movl %eax, 0xc(%rsp)
movslq %eax, %r14
shlq $0x5, %r14
movq %rbp, 0x18(%rsp)
movq %rbp, %rbx
subq %r14, %rbx
movq %r15, %r12
movq %r15, (%rsp)
cmpq %rbx, %r15
ja 0xc40f
movq 0x10(%rsp), %rbp
movq %rbp, %r15
shlq $0x5, %r15
movq %r15, %r13
negq %r13
shlq $0x6, %rbp
movq (%rsp), %r12
leaq (%r12,%r15), %rsi
leaq (%r12,%rbp), %rdx
leaq (%r12,%r13), %rcx
movq %r12, %rdi
callq 0xce64
addq %r14, %r12
cmpq %rbx, %r12
jbe 0xc3f3
movq 0x18(%rsp), %rbp
movq %rbp, %rax
subq %r12, %rax
sarq $0x5, %rax
movq 0x10(%rsp), %rbx
cmpq %rbx, %rax
jle 0xc446
movq %rbx, %rax
shlq $0x5, %rax
leaq (%r12,%rax), %rsi
movq %r12, %rcx
subq %rax, %rcx
movq %r12, %rdi
movq %rbp, %rdx
callq 0xce64
jmp 0xc45e
movq %rbx, %rax
shlq $0x5, %rax
movq %r12, %rdi
subq %rax, %rdi
movq %r12, %rsi
movq %rbp, %rdx
callq 0xccd6
movq (%rsp), %r15
shlq $0x5, %rbx
subq %rbx, %r15
subq %rbx, %rbp
movl 0xc(%rsp), %r10d
cmpl 0x38(%rsp), %r10d
jl 0xc3aa
movq %rbp, %rax
subq %r15, %rax
sarq $0x5, %rax
movq 0x38(%rsp), %rsi
leal (%rsi,%rsi), %ecx
movslq %ecx, %r14
cqto
idivq %r14
movq %rdx, %r12
shlq $0x5, %r12
movq %rbp, %r13
subq %r12, %r13
movslq %esi, %rcx
movq %rdx, (%rsp)
movq %rcx, %rbx
cmpl %esi, %edx
jle 0xc4c9
shlq $0x5, %rcx
leaq (%rcx,%r13), %rsi
addq %rbp, %rcx
movq %r13, %rdi
movq %rbp, %rdx
callq 0xcfb6
jmp 0xc4de
movq %rcx, %rdx
shlq $0x5, %rdx
addq %rbp, %rdx
movq %r13, %rdi
movq %rbp, %rsi
callq 0xccd6
cmpq %r15, %r13
jbe 0xc56d
movq %r15, %rdx
movq %r12, %rsi
negq %rsi
movq (%rsp), %rcx
addq %r14, %rcx
shlq $0x5, %r14
movq %r14, %rax
negq %rax
movq %rax, (%rsp)
movq %rbx, %r15
shlq $0x5, %r15
movq %r12, %rax
leaq (%r15,%r15,2), %rdi
shlq $0x5, %rcx
subq %rcx, %rdi
movq %rdi, 0x18(%rsp)
shlq $0x6, %rbx
subq %r12, %rbx
subq %r14, %rbx
movq %rbx, %r12
subq %rax, %r15
subq %r14, %r15
movq %r14, %rax
movq %rsi, %r13
movq %rsi, %r14
subq %rax, %r14
leaq (%r14,%rbp), %rdi
leaq (%r15,%rbp), %rsi
movq %rdx, %rbx
leaq (%r12,%rbp), %rdx
movq 0x18(%rsp), %rax
leaq (%rax,%rbp), %rcx
callq 0xcfb6
movq %rbx, %rdx
addq (%rsp), %rbp
movq %rbp, %rax
addq %r13, %rax
cmpq %rbx, %rax
ja 0xc53e
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq