// File: /workspace/github_cpp_makefile_star2_O1/ruankotovich[P]B-Tree/src/secondarybtree.cpp
// Function: SecondaryBTree::insertRecursive(SecondaryBTreeDataMap&, SecondaryBTreeNodeReinterpret*, int, _IO_FILE*)
SecondaryBTreeRecursionResponse SecondaryBTree::insertRecursive(SecondaryBTreeDataMap& key, SecondaryBTreeNodeReinterpret* nodeReinterpretation, int offset, FILE* indexFile)
{
    for (unsigned short i = 0; i < nodeReinterpretation->node.count; ++i) {
        if (nodeReinterpretation->node.keys[i] == key) return SUCCESSFUL_TREE_INSERTION;
    }

    if (nodeReinterpretation->node.isLeaf()) {

        if (nodeReinterpretation->node.hasRoom()) {
            nodeReinterpretation->node.insert(key);
            writeBackNode(&nodeReinterpretation->node, offset, indexFile);
            return SUCCESSFUL_TREE_INSERTION;
        }

        SecondaryBTreeNode* splitLeaf = new SecondaryBTreeNode(SECONDARY_MAX_KEYS);
        SecondaryBTreeDataMap promoted;

        // elege o promoted e manipula os vetores resultantes da operação do splitLeaf.
        SecondaryBTreeDataMap leftMiddleKey = nodeReinterpretation->node.keys[SECONDARY_LEFT_MIDDLE_KEY];
        SecondaryBTreeDataMap rightMiddleKey = nodeReinterpretation->node.keys[SECONDARY_RIGHT_MIDDLE_KEY];

        splitLeaf->count = nodeReinterpretation->node.count = SECONDARY_HALF_MAX_KEYS;

        switch (relativeKeyPosition(key, leftMiddleKey, rightMiddleKey)) {
        case RELATIVE_LEFT: {
            promoted = leftMiddleKey;
            --nodeReinterpretation->node.count;

            nodeReinterpretation->node.insert(key);

            for (int i = SECONDARY_HALF_MAX_KEYS, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                splitLeaf->keys[j] = nodeReinterpretation->node.keys[i];
            }
        } // não esquecer de manipular os blockPointes para nós não-folha
        break;

        case RELATIVE_RIGHT: {
            promoted = rightMiddleKey;
            --splitLeaf->count;

            for (int i = SECONDARY_RIGHT_MIDDLE_KEY + 1, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                splitLeaf->keys[j] = nodeReinterpretation->node.keys[i];
            } // não esquecer de manipular os blockPointes para nós não-folha

            splitLeaf->insert(key);
        } break;

        case RELATIVE_MIDDLE: {
            promoted = key;

            for (int i = SECONDARY_HALF_MAX_KEYS, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                splitLeaf->keys[j] = nodeReinterpretation->node.keys[i];
            }
        } // não esquecer de manipular os blockPointes para nós não-folha

        break;
        }

        writeBackNode(&nodeReinterpretation->node, offset, indexFile);
        int offset = writeNewNode(splitLeaf, indexFile);

        delete splitLeaf; // deleta da memória principal pois já foi salvo no disco

        // return { true, { promoted, offset } };
        return SecondaryBTreeRecursionResponse(true, promoted, offset);
    }
    //key.key[299] = '\0';
    int result = upperBound(nodeReinterpretation->node.keys, nodeReinterpretation->node.count, key); // [TROCAR]

    //auto resultPair = u(nodeReinterpretation->node.keys, nodeReinterpretation->node.count, key);
    int childNodeOffset;

    if (result >= nodeReinterpretation->node.count) {
        childNodeOffset = result;
        result = nodeReinterpretation->node.count - 1;
    }

    childNodeOffset = ((key < nodeReinterpretation->node.keys[result]) ? nodeReinterpretation->node.blockPointers[result] : nodeReinterpretation->node.blockPointers[result + 1]);

    SecondaryBTreeNodeReinterpret* retrieveNode = new SecondaryBTreeNodeReinterpret();
    fseek(indexFile, sizeof(AbstractBlock_t) * childNodeOffset, SEEK_SET);
    fread(&retrieveNode->block, sizeof(AbstractBlock_t), 1, indexFile);

    auto resultRecursion = insertRecursive(key, retrieveNode, childNodeOffset, indexFile);
    delete retrieveNode;

    if (resultRecursion.hasBeenSplit) { // caso em que veio um valor promovido e um blockPointer
        //caso 1 - tem espaço para inserir o promovido
        if (nodeReinterpretation->node.hasRoom()) {
            //o + 1 é para não realizar essa soma em toda iteração do for logo abaixo
            int rightIndexInserted = nodeReinterpretation->node.insert(resultRecursion.promotedKey) + 1;

            for (unsigned short i = nodeReinterpretation->node.countPointers; i > rightIndexInserted; --i) {
                nodeReinterpretation->node.blockPointers[i] = nodeReinterpretation->node.blockPointers[i - 1];
            }

            nodeReinterpretation->node.blockPointers[rightIndexInserted] = resultRecursion.newBlockOffset;
            ++nodeReinterpretation->node.countPointers;

            writeBackNode(&nodeReinterpretation->node, offset, indexFile);
        } else { // caso 2 - não tem espaço para inserir o promovido -> fazer o split com remanejamento de chaves
            SecondaryBTreeNodeReinterpret* split = new SecondaryBTreeNodeReinterpret();
            SecondaryBTreeDataMap promoted;

            // elege o promoted e manipula os vetores resultantes da operação do split.
            SecondaryBTreeDataMap leftMiddleKey = nodeReinterpretation->node.keys[SECONDARY_LEFT_MIDDLE_KEY];
            SecondaryBTreeDataMap rightMiddleKey = nodeReinterpretation->node.keys[SECONDARY_RIGHT_MIDDLE_KEY];

            split->node.count = nodeReinterpretation->node.count = SECONDARY_HALF_MAX_KEYS; // remoção lógica exatamente na metade

            //como está cheio, vai metade dos elementos para cada bloco, contnado com o split.
            // se vai metade, haverá metade + 1 ponteiros para bloco preenchidos.
            split->node.countPointers = nodeReinterpretation->node.countPointers = SECONDARY_HALF_MAX_KEYS + 1;

            switch (relativeKeyPosition(resultRecursion.promotedKey, leftMiddleKey, rightMiddleKey)) {
            case RELATIVE_LEFT: {
                promoted = leftMiddleKey;

                --nodeReinterpretation->node.count;

                // índice do ponteiro mais à direita do vetor blockPointers
                int greaterNodeBlockPointer = nodeReinterpretation->node.blockPointers[nodeReinterpretation->node.countPointers - 1]; // a subtração tem a ver com índice

                //índice em que foi inserido o promovido no nó já existente
                int rightIndexInserted = nodeReinterpretation->node.insert(resultRecursion.promotedKey) + 1;

                //remanejar os blockPoints
                for (int i = nodeReinterpretation->node.countPointers - 1; i > rightIndexInserted; --i) {
                    nodeReinterpretation->node.blockPointers[i] = nodeReinterpretation->node.blockPointers[i - 1];
                }

                nodeReinterpretation->node.blockPointers[rightIndexInserted] = resultRecursion.newBlockOffset;

                for (int i = SECONDARY_HALF_MAX_KEYS, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                    split->node.keys[j] = nodeReinterpretation->node.keys[i];
                    split->node.blockPointers[j + 1] = nodeReinterpretation->node.blockPointers[i + 1];
                } // não esquecer de manipular os blockPointes para nós não-folha

                split->node.blockPointers[0] = greaterNodeBlockPointer;
            } break;

            case RELATIVE_RIGHT: {
                promoted = rightMiddleKey;
                --split->node.count;
                // não é preciso modificar o countPointers nem o count do node aqui porque eles já foram atribuidos ali em cima,
                // então a remoção lógica já foi feita

                for (int i = SECONDARY_RIGHT_MIDDLE_KEY + 1, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                    split->node.keys[j] = nodeReinterpretation->node.keys[i];
                    split->node.blockPointers[j] = nodeReinterpretation->node.blockPointers[i];
                } // não esquecer de manipular os blockPointes para nós não-folha/

                split->node.blockPointers[SECONDARY_HALF_MAX_KEYS - 1] = nodeReinterpretation->node.blockPointers[SECONDARY_MAX_KEYS];
                int rightIndexInserted = split->node.insert(resultRecursion.promotedKey) + 1;

                //remanejar os blockPoints
                for (unsigned short i = split->node.countPointers - 1; i > rightIndexInserted; --i) {
                    split->node.blockPointers[i] = split->node.blockPointers[i - 1];
                }

                split->node.blockPointers[rightIndexInserted] = resultRecursion.newBlockOffset;
            } break;

            case RELATIVE_MIDDLE: {
                promoted = resultRecursion.promotedKey;

                for (int i = SECONDARY_HALF_MAX_KEYS, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                    split->node.keys[j] = nodeReinterpretation->node.keys[i];
                    split->node.blockPointers[j + 1] = nodeReinterpretation->node.blockPointers[i + 1];
                } // não esquecer de manipular os blockPointes para nós não-folha
                split->node.blockPointers[0] = resultRecursion.newBlockOffset;
            } break;
            }

            writeBackNode(&nodeReinterpretation->node, offset, indexFile);
            int offset = writeNewNode(&split->node, indexFile);
            delete split; // deleta da memória principal pois já foi salvo no disco
            return SecondaryBTreeRecursionResponse(true, promoted, offset);
        }
    }

    return SUCCESSFUL_TREE_INSERTION;
    // return SecondaryBTreeRecursionResponse(false, 0, 0);
    // return { false, { 0, 0 } };*/
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4f8, %rsp            # imm = 0x4F8
movq %r9, 0x10(%rsp)
movl %r8d, 0x4(%rsp)
movq %rdx, %r15
movq %rdi, 0x18(%rsp)
movq %rcx, 0x20(%rsp)
movzwl (%rcx), %r14d
testq %r14, %r14
setne %bl
movq %rsi, %r12
je 0x1be7
movq 0x20(%rsp), %rax
leaq 0x4(%rax), %rdi
movq %r15, %rsi
callq 0x1100
testl %eax, %eax
je 0x1bca
movq %r12, %rsi
movq 0x20(%rsp), %rax
leaq 0x134(%rax), %rbx
leaq -0x1(%r14), %r13
xorl %ebp, %ebp
cmpq %rbp, %r13
je 0x1be7
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1100
movq %r12, %rsi
addq $0x130, %rbx            # imm = 0x130
incq %rbp
testl %eax, %eax
jne 0x1ba3
cmpq %r14, %rbp
setb %bl
movl $0x138, %edx            # imm = 0x138
movq 0x18(%rsp), %rdi
movq %r12, %rsi
callq 0x1090
movq %r12, %rsi
testb %bl, %bl
jne 0x23e8
movq %r15, 0x8(%rsp)
movq 0x20(%rsp), %r15
cmpw $0x0, 0x2(%r15)
je 0x1d9a
leaq 0x4(%r15), %rbx
leaq 0x30(%rsp), %rbp
movl $0x130, %edx            # imm = 0x130
movq %rbp, %rdi
movq %rsi, 0x28(%rsp)
movq 0x8(%rsp), %r13
movq %r13, %rsi
callq 0x1090
imulq $0x130, %r14, %rax      # imm = 0x130
leaq (%r15,%rax), %rsi
addq $0x4, %rsi
movq %rbx, %rdi
movq %rbp, %rdx
callq 0x2793
subq %rbx, %rax
shrq $0x4, %rax
imull $0x286bca1b, %eax, %eax # imm = 0x286BCA1B
movzwl (%r15), %ecx
leal -0x1(%rcx), %edx
cmpl %ecx, %eax
cmovll %eax, %edx
movslq %edx, %rbx
imulq $0x130, %rbx, %rax      # imm = 0x130
leaq (%r15,%rax), %rsi
addq $0x4, %rsi
movq %r13, %rdi
callq 0x1100
leal 0x1(%rbx), %ecx
testl %eax, %eax
movslq %ecx, %rax
cmovsq %rbx, %rax
movslq 0xe44(%r15,%rax,4), %rbp
movl $0x1000, %edi           # imm = 0x1000
callq 0x10b0
movq %rax, %rbx
movl $0x0, (%rax)
movq %rbp, %rsi
shlq $0xc, %rsi
movq 0x10(%rsp), %r13
movq %r13, %rdi
xorl %edx, %edx
callq 0x10d0
movl $0x1000, %esi           # imm = 0x1000
movl $0x1, %edx
movq %rbx, %rdi
movq %r13, %rcx
callq 0x1110
leaq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
movq %rsi, %r14
movq 0x8(%rsp), %rdx
movq %rbx, %rcx
movl %ebp, %r8d
movq %r13, %r9
callq 0x1b42
movl $0x1000, %esi           # imm = 0x1000
movq %rbx, %rdi
callq 0x10c0
leaq 0x30(%rsp), %rax
cmpb $0x1, (%rax)
jne 0x1d83
cmpw $0xb, (%r15)
ja 0x1f12
leaq 0x34(%rsp), %rsi
movq %r15, %rdi
callq 0x1976
incl %eax
movzwl 0x2(%r15), %ecx
movzwl %cx, %esi
cmpl %esi, %eax
jae 0x1d40
movl %ecx, %edx
decl %esi
movl 0xe44(%r15,%rsi,4), %esi
movzwl %dx, %edi
movl %esi, 0xe44(%r15,%rdi,4)
decl %edx
movzwl %dx, %esi
cmpl %esi, %eax
jb 0x1d22
movl 0x164(%rsp), %edx
movl %eax, %eax
movl %edx, 0xe44(%r15,%rax,4)
incl %ecx
movw %cx, 0x2(%r15)
movslq 0x4(%rsp), %rsi
shlq $0xc, %rsi
movq %r13, %rdi
xorl %edx, %edx
callq 0x10d0
movl $0x1000, %esi           # imm = 0x1000
movl $0x1, %edx
movq %r15, %rdi
movq %r13, %rcx
callq 0x1180
movq %r12, %r14
movl $0x138, %edx            # imm = 0x138
movq 0x18(%rsp), %rdi
movq %r14, %rsi
callq 0x1090
jmp 0x23e8
cmpw $0xb, %r14w
ja 0x1e00
movq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rsi, %r14
movq 0x8(%rsp), %rsi
callq 0x1976
movslq 0x4(%rsp), %rsi
shlq $0xc, %rsi
movq 0x10(%rsp), %rbx
movq %rbx, %rdi
xorl %edx, %edx
callq 0x10d0
movl $0x1000, %esi           # imm = 0x1000
movl $0x1, %edx
movq %r15, %rdi
movq %rbx, %rcx
callq 0x1180
movl $0x138, %edx            # imm = 0x138
movq 0x18(%rsp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1090
movq %rbx, %rax
jmp 0x23ed
movl $0xe78, %edi            # imm = 0xE78
callq 0x10b0
movq %rax, %r13
movl $0x0, (%rax)
movq 0x20(%rsp), %r15
leaq 0x5f4(%r15), %r14
leaq 0x30(%rsp), %rbx
movl $0x130, %edx            # imm = 0x130
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0x724(%r15), %rbp
leaq 0x29c(%rsp), %rdi
movl $0x130, %edx            # imm = 0x130
movq %rbp, %rsi
callq 0x1090
movw $0x6, %ax
movw %ax, (%r15)
movw %ax, (%r13)
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
callq 0x1100
movb $-0x1, %cl
testl %eax, %eax
js 0x1e87
leaq 0x29c(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x1100
testl %eax, %eax
setg %cl
testb %cl, %cl
je 0x2095
movzbl %cl, %eax
leaq 0x16c(%rsp), %rdi
movl $0x12c, %edx            # imm = 0x12C
cmpl $0x1, %eax
jne 0x20f4
movq %rbp, %rsi
callq 0x1090
movl 0x3c8(%rsp), %r14d
movw $0x5, (%r13)
leaq 0x854(%r15), %rbx
xorl %ebp, %ebp
leaq (%rbx,%rbp), %rsi
leaq 0x4(,%rbp), %rdi
addq %r13, %rdi
movl $0x12c, %edx            # imm = 0x12C
callq 0x1090
movl 0x12c(%rbx,%rbp), %eax
movl %eax, 0x130(%r13,%rbp)
addq $0x130, %rbp            # imm = 0x130
cmpq $0x5f0, %rbp            # imm = 0x5F0
jne 0x1ec8
movq %r13, %rdi
movq 0x8(%rsp), %rsi
callq 0x1976
jmp 0x2153
movl $0x1000, %edi           # imm = 0x1000
callq 0x10b0
movq %rax, %r12
movl $0x0, (%rax)
leaq 0x5f4(%r15), %rbp
leaq 0x29c(%rsp), %rbx
movl $0x130, %edx            # imm = 0x130
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x1090
leaq 0x724(%r15), %r13
leaq 0x16c(%rsp), %rdi
movl $0x130, %edx            # imm = 0x130
movq %r13, %rsi
callq 0x1090
movw $0x6, %ax
movw %ax, (%r15)
movw %ax, (%r12)
movw $0x7, %ax
movw %ax, 0x2(%r15)
movw %ax, 0x2(%r12)
leaq 0x34(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1100
movb $-0x1, %cl
testl %eax, %eax
js 0x1fa7
leaq 0x16c(%rsp), %rsi
movq %r14, %rdi
callq 0x1100
testl %eax, %eax
setg %cl
testb %cl, %cl
je 0x21f4
movzbl %cl, %eax
leaq 0x3cc(%rsp), %rdi
movl $0x12c, %edx            # imm = 0x12C
cmpl $0x1, %eax
jne 0x2275
movq %r13, %rsi
callq 0x1090
movl 0x298(%rsp), %ebp
movw $0x5, (%r12)
movl $0x391, %r14d           # imm = 0x391
movl $0x215, %r13d           # imm = 0x215
leaq (%r15,%r13,4), %rbx
leaq (%r12,%r13,4), %rdi
addq $-0x850, %rdi           # imm = 0xF7B0
movl $0x12c, %edx            # imm = 0x12C
movq %rbx, %rsi
callq 0x1090
movl 0x12c(%rbx), %eax
movl %eax, -0x724(%r12,%r13,4)
movl 0x1c(%r15,%r14,4), %eax
movl %eax, (%r12,%r14,4)
incq %r14
addq $0x4c, %r13
cmpq $0x391, %r13            # imm = 0x391
jne 0x1fea
movl 0xe74(%r15), %eax
movl %eax, 0xe58(%r12)
movq %r12, %rdi
leaq 0x34(%rsp), %rsi
callq 0x1976
incl %eax
movzwl 0x2(%r12), %ecx
leal -0x1(%rcx), %edx
movzwl %dx, %edx
cmpl %edx, %eax
jae 0x207f
addl $-0x2, %ecx
leal 0x1(%rcx), %esi
decl %edx
movl 0xe44(%r12,%rdx,4), %edx
movzwl %si, %esi
movl %edx, 0xe44(%r12,%rsi,4)
movzwl %cx, %edx
decl %ecx
cmpl %edx, %eax
jb 0x205e
movl 0x164(%rsp), %ecx
movl %eax, %eax
movl %ecx, 0xe44(%r12,%rax,4)
jmp 0x234a
leaq 0x16c(%rsp), %rdi
movl $0x12c, %edx            # imm = 0x12C
movq 0x8(%rsp), %rbx
movq %rbx, %rsi
callq 0x1090
movl 0x12c(%rbx), %r14d
movq %r13, %rbx
addq $0x4, %rbx
xorl %r12d, %r12d
leaq (%r12,%rbp), %rsi
leaq (%rbx,%r12), %rdi
movl $0x12c, %edx            # imm = 0x12C
callq 0x1090
movl 0x12c(%rbp,%r12), %eax
movl %eax, 0x12c(%rbx,%r12)
addq $0x130, %r12            # imm = 0x130
cmpq $0x720, %r12            # imm = 0x720
jne 0x20c0
jmp 0x2153
movq %r14, %rsi
callq 0x1090
movl 0x15c(%rsp), %r14d
movw $0x5, (%r15)
movq %r15, %rdi
movq 0x8(%rsp), %rsi
callq 0x1976
movq %r13, %rbx
addq $0x4, %rbx
xorl %r12d, %r12d
leaq (%r12,%rbp), %rsi
leaq (%rbx,%r12), %rdi
movl $0x12c, %edx            # imm = 0x12C
callq 0x1090
movl 0x12c(%rbp,%r12), %eax
movl %eax, 0x12c(%rbx,%r12)
addq $0x130, %r12            # imm = 0x130
cmpq $0x720, %r12            # imm = 0x720
jne 0x2121
movslq 0x4(%rsp), %rsi
shlq $0xc, %rsi
movq 0x10(%rsp), %rbx
movq %rbx, %rdi
xorl %edx, %edx
callq 0x10d0
movl $0x1000, %esi           # imm = 0x1000
movl $0x1, %edx
movq %r15, %rdi
movq %rbx, %rcx
callq 0x1180
movq %rbx, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x10d0
movl $0x1000, %esi           # imm = 0x1000
movl $0x1, %edx
movq %r13, %rdi
movq %rbx, %rcx
callq 0x1180
movq %rbx, %rdi
callq 0x1030
movq %rax, %rbx
shrq $0xc, %rbx
decl %ebx
movl $0xe78, %esi            # imm = 0xE78
movq %r13, %rdi
callq 0x10c0
movq 0x18(%rsp), %r15
movb $0x1, (%r15)
movl %ebx, 0x134(%r15)
leaq 0x4(%r15), %rdi
leaq 0x16c(%rsp), %rsi
movl $0x12c, %edx            # imm = 0x12C
callq 0x1090
movl %r14d, 0x130(%r15)
jmp 0x23e8
leaq 0x3cc(%rsp), %rdi
movl $0x12c, %edx            # imm = 0x12C
movq %r14, %rsi
callq 0x1090
movl 0x160(%rsp), %ebp
leaq 0x850(%r15), %rbx
movl $0x392, %r14d           # imm = 0x392
xorl %r13d, %r13d
leaq (%rbx,%r13), %rsi
addq $-0x12c, %rsi           # imm = 0xFED4
leaq (%r12,%r13), %rdi
addq $0x4, %rdi
movl $0x12c, %edx            # imm = 0x12C
callq 0x1090
movl 0x850(%r15,%r13), %eax
movl %eax, 0x130(%r12,%r13)
movl 0x18(%r15,%r14,4), %eax
movl %eax, (%r12,%r14,4)
addq $0x130, %r13            # imm = 0x130
incq %r14
cmpq $0x720, %r13            # imm = 0x720
jne 0x2220
movl 0x164(%rsp), %eax
jmp 0x2342
movq %rbp, %rsi
callq 0x1090
movl 0x3c8(%rsp), %ebp
movw $0x5, (%r15)
movl 0xe5c(%r15), %eax
movl %eax, 0x8(%rsp)
movq %r15, %rdi
movq %r14, %rsi
callq 0x1976
incl %eax
movzwl 0x2(%r15), %esi
leal -0x1(%rsi), %edx
movl %eax, %ecx
cmpl %eax, %edx
jle 0x22d7
movl %edx, %eax
movl $0xfffffffe, %edx       # imm = 0xFFFFFFFE
addq %rsi, %rdx
movl %edx, %esi
movl 0xe44(%r15,%rsi,4), %esi
movl %esi, 0xe44(%r15,%rax,4)
decq %rax
decq %rdx
cmpq %rcx, %rax
jg 0x22ba
movl 0x164(%rsp), %eax
movl %eax, 0xe44(%r15,%rcx,4)
leaq 0x850(%r15), %r14
movl $0x392, %r13d           # imm = 0x392
xorl %ebx, %ebx
leaq (%r14,%rbx), %rsi
addq $-0x12c, %rsi           # imm = 0xFED4
leaq (%r12,%rbx), %rdi
addq $0x4, %rdi
movl $0x12c, %edx            # imm = 0x12C
callq 0x1090
movl 0x850(%r15,%rbx), %eax
movl %eax, 0x130(%r12,%rbx)
movl 0x18(%r15,%r13,4), %eax
movl %eax, (%r12,%r13,4)
addq $0x130, %rbx            # imm = 0x130
incq %r13
cmpq $0x720, %rbx            # imm = 0x720
jne 0x22f5
movl 0x8(%rsp), %eax
movl %eax, 0xe44(%r12)
movq 0x10(%rsp), %rbx
movl 0x4(%rsp), %eax
movslq %eax, %rsi
shlq $0xc, %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x10d0
movl $0x1000, %esi           # imm = 0x1000
movl $0x1, %edx
movq %r15, %rdi
movq %rbx, %rcx
callq 0x1180
movq %rbx, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x10d0
movl $0x1000, %esi           # imm = 0x1000
movl $0x1, %edx
movq %r12, %rdi
movq %rbx, %rcx
callq 0x1180
movq %rbx, %rdi
callq 0x1030
movq %rax, %rbx
shrq $0xc, %rbx
decl %ebx
movl $0x1000, %esi           # imm = 0x1000
movq %r12, %rdi
callq 0x10c0
movq 0x18(%rsp), %r14
movb $0x1, (%r14)
movl %ebx, 0x134(%r14)
leaq 0x4(%r14), %rdi
leaq 0x3cc(%rsp), %rsi
movl $0x12c, %edx            # imm = 0x12C
callq 0x1090
movl %ebp, 0x130(%r14)
movq 0x18(%rsp), %rax
addq $0x4f8, %rsp            # imm = 0x4F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop