// File: /workspace/github_cpp_makefile_star2_O3/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, %r14
movq %rdi, %r15
cmpl %r8d, %edx
movq %rdx, 0x38(%rsp)
cmovll %edx, %r8d
movl %r8d, %ebp
leal -0x1(%rbp), %r8d
andl %ebp, %r8d
jne 0xbd2d
testl %ebp, %ebp
je 0xc00d
movl %ebp, %r13d
jle 0xbd9b
movq %r13, %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 0xbd7a
incq %r9
addq $0x20, %rsi
addq $0x20, %rdx
cmpq %r13, %r9
jne 0xbd5c
leaq 0x20(%r15), %rax
cmpq %r14, %rax
jae 0xbe50
leaq -0x38(%r15), %r12
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, (%r12,%r11,4)
incq %r11
cmpq $0x6, %r11
jne 0xbde5
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 0xbe22
addq $0x40, %rax
addq $0x40, %r12
addq $0x40, %rdx
addq $0x40, %rsi
addq $0x40, %rdi
cmpq %r14, %rax
jb 0xbdb8
movl %r14d, %eax
subl %r15d, %eax
testb $0x20, %al
je 0xbe74
movq -0x20(%r14), %rax
movq %rax, -0x60(%r14)
movups -0x18(%r14), %xmm0
movups %xmm0, -0x58(%r14)
movq -0x8(%r14), %rax
movq %rax, -0x48(%r14)
movq %r13, 0x40(%rsp)
movq %rcx, 0x48(%rsp)
addq $-0x40, %r15
addq $-0x40, %r14
movl $0x2, %r10d
cmpl $0x3, %ebp
jl 0xbfb1
movq %rbp, 0x50(%rsp)
movl %r10d, %eax
movslq %r10d, %rcx
movq %rcx, 0x10(%rsp)
addl %eax, %eax
movl %eax, 0x8(%rsp)
movslq %eax, %rbp
shlq $0x5, %rbp
movq %r14, 0x18(%rsp)
movq %r14, %rbx
subq %rbp, %rbx
movq %r15, %r13
movq %r15, (%rsp)
cmpq %rbx, %r15
ja 0xbeff
movq 0x10(%rsp), %r14
movq %r14, %r15
shlq $0x5, %r15
movq %r15, %r12
negq %r12
shlq $0x6, %r14
movq (%rsp), %r13
leaq (%r15,%r13), %rsi
leaq (%r14,%r13), %rdx
leaq (%r12,%r13), %rcx
movq %r13, %rdi
callq 0xcbd9
addq %rbp, %r13
cmpq %rbx, %r13
jbe 0xbee3
movq 0x18(%rsp), %r14
movq %r14, %rax
subq %r13, %rax
sarq $0x5, %rax
movq 0x10(%rsp), %rsi
movq %rsi, %rbp
negq %rbp
cmpq %rsi, %rax
jle 0xbf45
shlq $0x5, %rsi
addq %r13, %rsi
movq %rbp, %rcx
shlq $0x5, %rcx
addq %r13, %rcx
movq %r13, %rdi
movq %r14, %rdx
callq 0xcbd9
movq (%rsp), %r15
movl 0x8(%rsp), %r10d
jmp 0xbf99
cmpq %r14, %r13
movq (%rsp), %r15
movl 0x8(%rsp), %r10d
jae 0xbf99
shlq $0x5, %rsi
movq %r13, %rax
subq %rsi, %rax
movq %rbp, %rcx
shlq $0x5, %rcx
movl (%r13), %edx
movl %edx, (%r13,%rcx)
movl 0x4(%r13), %edx
movl %edx, 0x4(%r13,%rcx)
movl $0x2, %edx
movl (%r13,%rdx,4), %esi
movl %esi, (%rax,%rdx,4)
incq %rdx
cmpq $0x8, %rdx
jne 0xbf7b
addq $0x20, %r13
addq $0x20, %rax
cmpq %r14, %r13
jb 0xbf64
shlq $0x5, %rbp
addq %rbp, %r15
addq %rbp, %r14
movq 0x50(%rsp), %rbp
cmpl %ebp, %r10d
jl 0xbe9a
testl %ebp, %ebp
jle 0xc27f
xorl %eax, %eax
movq 0x48(%rsp), %r8
movq %r8, %rcx
movq %r14, %rdx
movq 0x40(%rsp), %r9
movq %rax, %rsi
shlq $0x5, %rsi
movl (%r8,%rsi), %edi
movl %edi, (%r14,%rsi)
movl 0x4(%r8,%rsi), %edi
movl %edi, 0x4(%r14,%rsi)
movl $0x2, %esi
movl (%rcx,%rsi,4), %edi
movl %edi, (%rdx,%rsi,4)
incq %rsi
cmpq $0x8, %rsi
jne 0xbfe9
incq %rax
addq $0x20, %rdx
addq $0x20, %rcx
cmpq %r9, %rax
jne 0xbfcb
jmp 0xc27f
movq %r15, %r13
leaq 0x20(%r15), %rax
cmpq %r14, %rax
jae 0xc139
leaq -0x38(%r13), %rcx
leaq 0x8(%r13), %rdx
leaq -0x18(%r13), %rsi
leaq 0x28(%r13), %rdi
movq %r14, %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), %ebp
movq -0x48(%rax), %r14
movq %r14, 0x30(%rsp)
movups -0x58(%rax), %xmm0
movaps %xmm0, 0x20(%rsp)
movl (%r10), %r14d
movl %r14d, -0x60(%rax)
movl 0x4(%r10), %r14d
movl %r14d, -0x5c(%rax)
addq %rdx, %r11
xorl %r14d, %r14d
movl (%r11,%r14,4), %r15d
movl %r15d, (%rcx,%r14,4)
incq %r14
cmpq $0x6, %r14
jne 0xc07a
xorl %r14d, %r14d
cmpl %r8d, %r9d
setl %r14b
movl %ebx, (%r10)
movl %ebp, 0x4(%r10)
movq 0x30(%rsp), %r8
movq %r8, 0x18(%r10)
movaps 0x20(%rsp), %xmm0
movups %xmm0, 0x8(%r10)
shll $0x5, %r14d
movq %rax, %r8
subq %r14, %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 %r14, %rbx
xorl %r14d, %r14d
movl (%rbx,%r14,4), %ebp
movl %ebp, (%rsi,%r14,4)
incq %r14
cmpq $0x6, %r14
jne 0xc0ef
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, %r14
cmpq %r12, %rax
jb 0xc02d
movl %r14d, %eax
movq %r13, %r15
subl %r15d, %eax
testb $0x20, %al
je 0xc19c
movl -0x20(%r14), %eax
movl -0x1c(%r14), %ecx
movq -0x8(%r14), %rdx
movq %rdx, 0x30(%rsp)
movups -0x18(%r14), %xmm0
movaps %xmm0, 0x20(%rsp)
movq -0x60(%r14), %rdx
movq %rdx, -0x20(%r14)
leaq -0x58(%r14), %rdx
movq $-0x18, %rsi
movl -0x40(%r14,%rsi), %edi
movl %edi, (%r14,%rsi)
addq $0x4, %rsi
jne 0xc174
movl %eax, -0x60(%r14)
movl %ecx, -0x5c(%r14)
movq 0x30(%rsp), %rax
movq %rax, 0x10(%rdx)
movaps 0x20(%rsp), %xmm0
movups %xmm0, (%rdx)
addq $-0x40, %r15
addq $-0x40, %r14
movl $0x2, %r10d
jmp 0xc27f
movl %r10d, %eax
movslq %r10d, %rcx
movq %rcx, 0x10(%rsp)
addl %eax, %eax
movl %eax, 0x8(%rsp)
movslq %eax, %r13
shlq $0x5, %r13
movq %r14, 0x18(%rsp)
movq %r14, %rbx
subq %r13, %rbx
movq %r15, %r12
movq %r15, (%rsp)
cmpq %rbx, %r15
ja 0xc214
movq 0x10(%rsp), %r15
movq %r15, %rbp
shlq $0x5, %rbp
movq %rbp, %r14
negq %r14
shlq $0x6, %r15
movq (%rsp), %r12
leaq (%r12,%rbp), %rsi
leaq (%r12,%r15), %rdx
leaq (%r12,%r14), %rcx
movq %r12, %rdi
callq 0xcc89
addq %r13, %r12
cmpq %rbx, %r12
jbe 0xc1f8
movq 0x18(%rsp), %r14
movq %r14, %rax
subq %r12, %rax
sarq $0x5, %rax
movq 0x10(%rsp), %r13
cmpq %r13, %rax
jle 0xc24e
movq %r13, %rax
shlq $0x5, %rax
leaq (%r12,%rax), %rsi
negq %r13
movq %r12, %rcx
subq %rax, %rcx
movq %r12, %rdi
movq %r14, %rdx
callq 0xcc89
jmp 0xc26c
movq %r13, %rbx
negq %rbx
shlq $0x5, %r13
movq %r12, %rdi
subq %r13, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0xcafb
movq %rbx, %r13
movq (%rsp), %r15
shlq $0x5, %r13
addq %r13, %r15
addq %r13, %r14
movl 0x8(%rsp), %r10d
cmpl 0x38(%rsp), %r10d
jl 0xc1af
movq %r14, %rax
subq %r15, %rax
sarq $0x5, %rax
movq 0x38(%rsp), %rsi
leal (%rsi,%rsi), %ecx
movslq %ecx, %r12
cqto
idivq %r12
movq %rdx, %rax
shlq $0x5, %rax
movq %r14, %r13
movq %rax, 0x8(%rsp)
subq %rax, %r13
movslq %esi, %rcx
movq %rdx, (%rsp)
movq %rcx, %rbx
cmpl %esi, %edx
jle 0xc2df
shlq $0x5, %rcx
leaq (%rcx,%r13), %rsi
addq %r14, %rcx
movq %r13, %rdi
movq %r14, %rbp
movq %r14, %rdx
callq 0xcddb
jmp 0xc2f7
movq %rcx, %rdx
shlq $0x5, %rdx
addq %r14, %rdx
movq %r13, %rdi
movq %r14, %rbp
movq %r14, %rsi
callq 0xcafb
cmpq %r15, %r13
jbe 0xc378
movq 0x8(%rsp), %rcx
movq %rcx, %r14
negq %r14
movq (%rsp), %rdx
addq %r12, %rdx
shlq $0x5, %r12
movq %r12, %rax
negq %rax
movq %rax, (%rsp)
movq %rbx, %rdi
shlq $0x5, %rbx
movq %r12, %rax
leaq (%rbx,%rbx,2), %r8
shlq $0x5, %rdx
subq %rdx, %r8
movq %r8, 0x18(%rsp)
shlq $0x6, %rdi
subq %rcx, %rdi
subq %r12, %rdi
movq %rdi, %r12
subq %rcx, %rbx
subq %rax, %rbx
movq %r14, %r13
subq %rax, %r14
leaq (%r14,%rbp), %rdi
leaq (%rbx,%rbp), %rsi
leaq (%r12,%rbp), %rdx
movq 0x18(%rsp), %rax
leaq (%rax,%rbp), %rcx
callq 0xcddb
addq (%rsp), %rbp
movq %rbp, %rax
addq %r13, %rax
cmpq %r15, %rax
ja 0xc34f
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq