// File: /workspace/github_cpp_makefile_star2_O2/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 %rcx, 0x40(%rsp)
movq %rsi, %r15
movq %rdi, 0x8(%rsp)
cmpl %r8d, %edx
movq %rdx, 0x50(%rsp)
cmovll %edx, %r8d
movl %r8d, %r12d
leal -0x1(%r12), %r8d
andl %r12d, %r8d
jne 0x9683
testl %r12d, %r12d
je 0x985e
movslq %r12d, %rax
shlq $0x5, %rax
movq 0x8(%rsp), %r13
subq %rax, %r13
xorl %ebx, %ebx
testl %r12d, %r12d
cmovgl %r12d, %ebx
movq 0x40(%rsp), %rbp
movq %rbx, 0x48(%rsp)
subq $0x1, %rbx
jb 0x96d6
movq %rbp, %rdi
movq %r13, %rsi
callq 0x4164
addq $0x20, %rbp
addq $0x20, %r13
jmp 0x96bb
movq 0x8(%rsp), %rax
leaq 0x20(%rax), %rbx
cmpq %r15, %rbx
jae 0x971a
movl (%rbx), %eax
xorl %r14d, %r14d
cmpl -0x20(%rbx), %eax
setl %r14b
shll $0x5, %r14d
leaq (%rbx,%r14), %rsi
addq $-0x20, %rsi
leaq -0x60(%rbx), %rdi
callq 0x4164
movq %rbx, %rsi
subq %r14, %rsi
leaq -0x40(%rbx), %rdi
callq 0x4164
addq $0x40, %rbx
jmp 0x96df
movl %r15d, %eax
subl 0x8(%rsp), %eax
testb $0x20, %al
je 0x9732
leaq -0x20(%r15), %rsi
leaq -0x60(%r15), %rdi
callq 0x4164
addq $-0x40, 0x8(%rsp)
addq $-0x40, %r15
pushq $0x2
popq %r13
movq %r12, 0x38(%rsp)
cmpl %r12d, %r13d
jge 0x9833
leal (,%r13,2), %eax
movl %eax, 0x1c(%rsp)
movslq %eax, %rbp
shlq $0x5, %rbp
movq %r15, %rbx
subq %rbp, %rbx
movslq %r13d, %rcx
movq %rcx, %rax
negq %rax
movq %rax, 0x30(%rsp)
movq %r15, 0x20(%rsp)
movq %r15, %r12
movq 0x8(%rsp), %r13
subq %r13, %r12
movq %rcx, %r14
shlq $0x5, %r14
movq %r14, 0x10(%rsp)
negq %r14
movq %rcx, 0x28(%rsp)
movq %rcx, %r15
shlq $0x6, %r15
cmpq %rbx, %r13
ja 0x97c6
movq 0x10(%rsp), %rax
leaq (%rax,%r13), %rsi
leaq (%r15,%r13), %rdx
leaq (%r14,%r13), %rcx
movq %r13, %rdi
callq 0xa0cf
addq %rbp, %r13
subq %rbp, %r12
jmp 0x97a0
sarq $0x5, %r12
cmpq 0x28(%rsp), %r12
jle 0x9812
movq 0x10(%rsp), %rax
leaq (%rax,%r13), %rsi
movq %r13, %rcx
subq %rax, %rcx
movq %r13, %rdi
movq 0x20(%rsp), %r15
movq %r15, %rdx
callq 0xa0cf
movq 0x38(%rsp), %r12
movq 0x30(%rsp), %rax
shlq $0x5, %rax
addq %rax, 0x8(%rsp)
addq %rax, %r15
movl 0x1c(%rsp), %eax
movl %eax, %r13d
jmp 0x9745
movq 0x20(%rsp), %r15
movq 0x38(%rsp), %r12
cmpq %r15, %r13
jae 0x97f5
leaq (%r14,%r13), %rdi
movq %r13, %rsi
callq 0x4164
addq $0x20, %r13
jmp 0x981c
shlq $0x5, 0x48(%rsp)
xorl %ebx, %ebx
cmpq %rbx, 0x48(%rsp)
je 0x9996
movq 0x40(%rsp), %rax
leaq (%rax,%rbx), %rsi
leaq (%r15,%rbx), %rdi
callq 0x4164
addq $0x20, %rbx
jmp 0x983b
movq 0x8(%rsp), %rax
leaq 0x20(%rax), %rbx
cmpq %r15, %rbx
jae 0x98a2
movl (%rbx), %eax
xorl %r14d, %r14d
cmpl -0x20(%rbx), %eax
setl %r14b
leaq -0x60(%rbx), %rdi
shll $0x5, %r14d
leaq (%rbx,%r14), %rsi
addq $-0x20, %rsi
callq 0xa092
movq %rbx, %rsi
subq %r14, %rsi
leaq -0x40(%rbx), %rdi
callq 0xa092
addq $0x40, %rbx
jmp 0x9867
movl %r15d, %eax
subl 0x8(%rsp), %eax
testb $0x20, %al
je 0x98ba
leaq -0x20(%r15), %rdi
leaq -0x60(%r15), %rsi
callq 0xa092
addq $-0x40, 0x8(%rsp)
addq $-0x40, %r15
pushq $0x2
popq %r13
jmp 0x9996
leal (,%r13,2), %eax
movl %eax, 0x1c(%rsp)
movslq %eax, %rbp
shlq $0x5, %rbp
movq %r15, %rbx
subq %rbp, %rbx
movslq %r13d, %r13
movq %r13, %rax
negq %rax
movq %rax, 0x30(%rsp)
movq 0x8(%rsp), %r12
subq %r12, %r15
movq %r13, %r14
shlq $0x5, %r14
movq %r14, 0x10(%rsp)
negq %r14
movq %r13, 0x28(%rsp)
shlq $0x6, %r13
cmpq %rbx, %r12
ja 0x993a
movq 0x10(%rsp), %rax
leaq (%r12,%rax), %rsi
leaq (%r12,%r13), %rdx
leaq (%r12,%r14), %rcx
movq %r12, %rdi
callq 0xa147
subq %rbp, %r15
addq %rbp, %r12
jmp 0x9914
sarq $0x5, %r15
cmpq 0x28(%rsp), %r15
jle 0x9966
movq 0x10(%rsp), %rax
leaq (%r12,%rax), %rsi
movq %r12, %rcx
subq %rax, %rcx
movq %r12, %rdi
movq 0x20(%rsp), %r15
movq %r15, %rdx
callq 0xa147
jmp 0x997e
movq %r12, %rdi
subq 0x10(%rsp), %rdi
movq %r12, %rsi
movq 0x20(%rsp), %r15
movq %r15, %rdx
callq 0x9ff3
movq 0x30(%rsp), %rax
shlq $0x5, %rax
addq %rax, 0x8(%rsp)
addq %rax, %r15
movl 0x1c(%rsp), %eax
movl %eax, %r13d
cmpl 0x50(%rsp), %r13d
movq %r15, 0x20(%rsp)
jl 0x98cd
movq %r15, %rax
subq 0x8(%rsp), %rax
sarq $0x5, %rax
movq 0x50(%rsp), %rsi
leal (%rsi,%rsi), %ecx
movslq %ecx, %rbx
cqto
idivq %rbx
movq %rdx, %r12
movq %rdx, %rax
shlq $0x5, %rax
movq %r15, %rdi
movq %rax, %rbp
subq %rax, %rdi
movslq %esi, %r14
cmpl %esi, %r12d
jle 0x99f5
movq %r14, %rcx
shlq $0x5, %rcx
leaq (%rdi,%rcx), %rsi
addq %r15, %rcx
movq %r15, %rdx
callq 0xa1bd
jmp 0x9a07
movq %r14, %rdx
shlq $0x5, %rdx
addq %r15, %rdx
movq %r15, %rsi
callq 0x9ff3
imulq $0x60, %r14, %rax
addq %rbx, %r12
shlq $0x5, %r12
subq %r12, %rax
movq %rax, 0x10(%rsp)
shlq $0x5, %rbx
movq %rbx, %r12
negq %r12
movq %rbx, %rax
movq %r14, %rbx
shlq $0x6, %rbx
movq %rbp, %r15
subq %rbp, %rbx
subq %rax, %rbx
shlq $0x5, %r14
subq %rbp, %r14
subq %rax, %r14
negq %r15
movq %r15, %r13
subq %rax, %r15
movq 0x20(%rsp), %rbp
movq %rbp, %rax
addq %r13, %rax
cmpq 0x8(%rsp), %rax
jbe 0x9a7b
leaq (%r15,%rbp), %rdi
leaq (%r14,%rbp), %rsi
leaq (%rbx,%rbp), %rdx
movq 0x10(%rsp), %rax
leaq (%rax,%rbp), %rcx
callq 0xa1bd
addq %r12, %rbp
jmp 0x9a4f
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq