// File: /workspace/github_c_makefile_star2_O3/alexj136[P]minijit/src/ncodegen.c
// Function: ncode_gen
NCodeLinkable *ncode_gen(ICodeOperationVector *ops) {

    // Allocate space to store the generated ncode. Allocate enough space such
    // that if every instruction were the longest type, there would be exactly
    // enough space for the generated code.
    int ncode_buf_size = sizeof(byte) * ((ICodeOperationVector_size(ops) *
            JUMPLINK_x86_64_size) + x86_64_preamble_size);
    byte *ncode_buf = challoc(ncode_buf_size);
    int ncode_buf_alloc_idx = 0;
    int icode_idx;
    LinkTargetVector *link_targets = LinkTargetVector_init();
    IntRefVector *label_map = IntRefVector_init();

    // Include the preamble
    write_x86_64_preamble(ncode_buf + ncode_buf_alloc_idx, NULL, NULL);
    ncode_buf_alloc_idx += x86_64_preamble_size;

    // Loop writes the instructions in place and records the link locations to
    // be filled in later
    for(icode_idx = 0; icode_idx < ICodeOperationVector_size(ops);
            icode_idx++) {

        ICodeOperation *cur_instr = ICodeOperationVector_get(ops, icode_idx);
        int opc = cur_instr->opc;
        int arg1 = cur_instr->arg1;
        int arg2 = cur_instr->arg2;

        if(opc == MOVE) {
            write_x86_64_MOVE(ncode_buf + ncode_buf_alloc_idx, arg1, arg2);
            ncode_buf_alloc_idx += MOVE_x86_64_size;
        }
        else if(opc == LOAD) {
            write_x86_64_LOAD(ncode_buf + ncode_buf_alloc_idx, arg1, arg2);
            ncode_buf_alloc_idx += LOAD_x86_64_size;
        }
        else if(opc == STORE) {
            write_x86_64_STORE(ncode_buf + ncode_buf_alloc_idx, arg1, arg2);
            ncode_buf_alloc_idx += STORE_x86_64_size;
        }
        else if(opc == ADD) {
            write_x86_64_ADD(ncode_buf + ncode_buf_alloc_idx, arg1, arg2);
            ncode_buf_alloc_idx += ADD_x86_64_size;
        }
        else if(opc == SUB) {
            write_x86_64_SUB(ncode_buf + ncode_buf_alloc_idx, arg1, arg2);
            ncode_buf_alloc_idx += SUB_x86_64_size;
        }
        else if(opc == LOADIMM) {
            write_x86_64_LOADIMM(ncode_buf + ncode_buf_alloc_idx, arg1, arg2);
            ncode_buf_alloc_idx += LOADIMM_x86_64_size;
        }
        else if(opc == JUMP) {
            write_x86_64_JUMP(ncode_buf + ncode_buf_alloc_idx, NULL);
            LinkTargetVector_append(link_targets, LinkTarget_init(
                    ncode_buf_alloc_idx + JUMP_x86_64_address_offset, arg1));
            ncode_buf_alloc_idx += JUMP_x86_64_size;
        }
        else if(opc == JUMPCOND) {
            write_x86_64_JUMPCOND(ncode_buf + ncode_buf_alloc_idx, NULL, arg2);
            LinkTargetVector_append(link_targets, LinkTarget_init(
                    ncode_buf_alloc_idx + JUMPCOND_x86_64_address_offset,
                    arg1));
            ncode_buf_alloc_idx += JUMPCOND_x86_64_size;
        }
        else if(opc == JUMPLINK) {
            write_x86_64_JUMPLINK(ncode_buf + ncode_buf_alloc_idx, NULL);
            LinkTargetVector_append(link_targets, LinkTarget_init(
                    ncode_buf_alloc_idx + JUMPLINK_x86_64_address_offset,
                    arg1));
            ncode_buf_alloc_idx += JUMPLINK_x86_64_size;
        }
        else if(opc == JUMPADDR) {
            write_x86_64_JUMPADDR(ncode_buf + ncode_buf_alloc_idx, arg1);
            ncode_buf_alloc_idx += JUMPADDR_x86_64_size;
        }
        else if(opc == LABEL) {
            IntRefVector_append(label_map, IntRef_init(ncode_buf_alloc_idx));
        }
        else if(opc == HALT) {
            write_x86_64_HALT(ncode_buf + ncode_buf_alloc_idx);
            ncode_buf_alloc_idx += HALT_x86_64_size;
        }
    }

    return NCodeLinkable_init(ncode_buf, ncode_buf_size, link_targets,
            label_map);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
callq 0x1420e
leal (%rax,%rax,4), %ecx
leal (%rax,%rcx,4), %ecx
leal (%rax,%rcx), %edi
addl $0x2e, %edi
movl %edi, -0x3c(%rbp)
callq 0x62ec
movq %rax, %r15
movl $0x10, %edi
callq 0x62ec
movq %rax, %r14
movabsq $0xa00000000, %rax      # imm = 0xA00000000
movq %rax, (%r14)
movl $0x50, %edi
callq 0x62ec
movq %r14, -0x30(%rbp)
movq %rax, 0x8(%r14)
xorl %r14d, %r14d
xorl %eax, %eax
callq 0x75bc
movq %rax, -0x48(%rbp)
movq %r15, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x17003
movq %rbx, %rdi
callq 0x1420e
testl %eax, %eax
jle 0x18535
movl $0x2e, %r13d
movq %r15, -0x38(%rbp)
movq %rbx, %rdi
movl %r14d, %esi
callq 0x144a1
movl (%rax), %ecx
cmpq $0xb, %rcx
ja 0x18521
movl 0x4(%rax), %r12d
movl 0x8(%rax), %edx
leaq 0x4684(%rip), %rsi      # 0x1ca44
movslq (%rsi,%rcx,4), %rax
addq %rsi, %rax
jmpq *%rax
movslq %r13d, %rdi
addq %r15, %rdi
movl %r12d, %esi
callq 0x1710a
jmp 0x1842b
movslq %r13d, %r13
leaq (%r15,%r13), %rdi
callq 0x172f7
incl %r13d
jmp 0x18521
movslq %r13d, %rdi
addq %r15, %rdi
movl %r12d, %esi
callq 0x17148
jmp 0x1842b
movslq %r13d, %rdi
addq %r15, %rdi
movl %r12d, %esi
callq 0x172da
jmp 0x1842b
movslq %r13d, %rdi
addq %r15, %rdi
movl %r12d, %esi
callq 0x17186
jmp 0x1847d
movslq %r13d, %rdi
addq %r15, %rdi
movl %r12d, %esi
callq 0x17129
addl $0x2, %r13d
jmp 0x18521
movslq %r13d, %rdi
addq %r15, %rdi
xorl %esi, %esi
callq 0x171f5
leal 0xb(%r13), %r15d
movl $0x8, %edi
callq 0x62ec
movl %r15d, (%rax)
movq -0x38(%rbp), %r15
movl %r12d, 0x4(%rax)
movq -0x30(%rbp), %rdi
movq %rax, %rsi
callq 0x17467
addl $0x15, %r13d
jmp 0x18521
movslq %r13d, %rdi
addq %r15, %rdi
movl %r12d, %esi
callq 0x17165
addl $0x3, %r13d
jmp 0x18521
movslq %r13d, %rdi
addq %r15, %rdi
movl %r12d, %esi
callq 0x170d3
addl $0x5, %r13d
jmp 0x18521
movslq %r13d, %rdi
addq %r15, %rdi
xorl %esi, %esi
callq 0x171a5
leal 0x2(%r13), %r15d
movl $0x8, %edi
callq 0x62ec
movl %r15d, (%rax)
movq -0x38(%rbp), %r15
movl %r12d, 0x4(%rax)
movq -0x30(%rbp), %rdi
movq %rax, %rsi
callq 0x17467
addl $0xc, %r13d
jmp 0x18521
movl %r13d, %edi
callq 0x6647
movq -0x48(%rbp), %rdi
movq %rax, %rsi
callq 0x76a6
jmp 0x18521
movslq %r13d, %rdi
addq %r15, %rdi
xorl %esi, %esi
callq 0x17274
leal 0xc(%r13), %r15d
movl $0x8, %edi
callq 0x62ec
movl %r15d, (%rax)
movq -0x38(%rbp), %r15
movl %r12d, 0x4(%rax)
movq -0x30(%rbp), %rdi
movq %rax, %rsi
callq 0x17467
addl $0x16, %r13d
incl %r14d
movq %rbx, %rdi
callq 0x1420e
cmpl %eax, %r14d
jl 0x1839b
movl $0x20, %edi
callq 0x62ec
movq %r15, (%rax)
movl -0x3c(%rbp), %ecx
movl %ecx, 0x8(%rax)
movq -0x30(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x48(%rbp), %rcx
movq %rcx, 0x18(%rax)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq