// File: /workspace/github_c_makefile_star2_O0/sharmaeklavya2[P]cerplag/compile_x86.c
// Function: compile_instr_to_x86
void compile_instr_to_x86(const IRInstr* inode, X86Code* ocode) {
    if(!check_arg(inode->arg1)) return;
    if(!check_arg(inode->arg2)) return;
    if(!check_arg(inode->res)) return;
    switch(inode->op) {
        case OP_MOV:
            op_addr_to_addr(ocode, X86_OP_mov, inode->res, inode->arg1);
            break;
        case OP_PLUS:
        case OP_MINUS:
        case OP_AND:
        case OP_OR:
            op_addr_to_reg(ocode, X86_OP_mov, 0, inode->arg1);
            op_addr_to_reg(ocode, get_opcode(inode->op), 0, inode->arg2);
            op_reg_to_addr(ocode, X86_OP_mov, inode->res, 0);
            break;
        case OP_UMINUS: {
            x86_code_append(ocode, x86_instr_new2(X86_OP_xor, "rax", "rax"));
            op_addr_to_reg(ocode, X86_OP_sub, 0, inode->arg1);
            op_reg_to_addr(ocode, X86_OP_mov, inode->res, 0);
            break;
        }
        case OP_INC:
            op_apply(ocode, X86_OP_inc, inode->res);
            break;
        case OP_MUL:
            op_addr_to_reg(ocode, X86_OP_mov, 0, inode->arg1);
            op_addr_to_reg(ocode, X86_OP_mov, 2, inode->arg2);
            x86_code_append(ocode, x86_instr_new2(X86_OP_imul, std_regs[2][TYPE_INTEGER], NULL));
            op_reg_to_addr(ocode, X86_OP_mov, inode->res, 0);
            break;
        case OP_DIV:
            op_addr_to_reg(ocode, X86_OP_mov, 0, inode->arg1);
            x86_code_append(ocode, x86_instr_new(X86_OP_cwd));
            op_addr_to_reg(ocode, X86_OP_mov, 2, inode->arg2);
            x86_code_append(ocode, x86_instr_new2(X86_OP_idiv, std_regs[2][TYPE_INTEGER], NULL));
            op_reg_to_addr(ocode, X86_OP_mov, inode->res, 0);
            break;

        case OP_EQ:
        case OP_NE:
        case OP_LT:
        case OP_LE:
        case OP_GT:
        case OP_GE:
            op_addr_to_addr(ocode, X86_OP_cmp, inode->arg1, inode->arg2);
            op_apply(ocode, get_setcode(inode->op), inode->res);
            break;
        case OP_OUTPUT: {
            int size = inode->arg1->size;
            enable_output(inode->arg1->type, size);
            if(size == 0) {
                op_addr_to_reg(ocode, X86_OP_mov, 2, inode->arg1);
                snprintf(temp_str, TEMP_STR_SIZE, "print_%s", TYPE_STRS[inode->arg1->type]);
                x86_code_append(ocode, x86_instr_new2(X86_OP_call, temp_str, NULL));
            }
            else {
                op_addr_to_reg(ocode, X86_OP_lea, 3, inode->arg1);
                snprintf(temp_str, TEMP_STR_SIZE, "%d", size);
                x86_code_append(ocode, x86_instr_new2(X86_OP_mov, "rdx", temp_str));
                snprintf(temp_str, TEMP_STR_SIZE, "print_%s_array", TYPE_STRS[inode->arg1->type]);
                x86_code_append(ocode, x86_instr_new2(X86_OP_call, temp_str, NULL));
            }
            break;
        }
        case OP_INPUT: {
            int size = inode->res->size;
            if(size == 0) size = 1;
            enable_input(inode->res->type);
            op_addr_to_reg(ocode, X86_OP_lea, 3, inode->res);
            snprintf(temp_str, TEMP_STR_SIZE, "%d", size);
            x86_code_append(ocode, x86_instr_new2(X86_OP_mov, "rdx", temp_str));
            snprintf(temp_str, TEMP_STR_SIZE, "read_%s_array", TYPE_STRS[inode->res->type]);
            x86_code_append(ocode, x86_instr_new2(X86_OP_call, temp_str, NULL));
            break;
        }

        case OP_LABEL:
        case OP_JUMP:
        case OP_JUMP0:
        case OP_JUMP1:
        case OP_JNE:
        case OP_JG: {
            snprintf(temp_str, TEMP_STR_SIZE, "L%d", inode->label);
            x86_op_t opcode = get_branch_opcode(inode->op);
            if(inode->arg1 != NULL) {
                load_index_if_needed(ocode, inode->arg1, "si");
                X86Instr* onode = x86_instr_new(X86_OP_cmp);
                addr_to_x86_arg(inode->arg1, onode->arg1, true, "rsi");
                if(inode->arg2 != NULL) {
                    snprintf(onode->arg2, X86_ARG_SIZE, "%d", inode->arg2->imm.i);
                }
                else {
                    strcpy(onode->arg2, "0");
                }
                x86_code_append(ocode, onode);
            }
            x86_code_append(ocode, x86_instr_new2(opcode, temp_str, NULL));
            break;
        }
        default:
            break;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x11760
testb $0x1, %al
jne 0x11969
jmp 0x11f5c
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x11760
testb $0x1, %al
jne 0x1197f
jmp 0x11f5c
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x11760
testb $0x1, %al
jne 0x11995
jmp 0x11f5c
movq -0x8(%rbp), %rax
movl (%rax), %eax
movq %rax, -0x30(%rbp)
subq $0x16, %rax
ja 0x11f5a
movq -0x30(%rbp), %rax
leaq 0x435c(%rip), %rcx      # 0x15d10
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdx
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
xorl %esi, %esi
callq 0x11600
jmp 0x11f5c
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
xorl %edx, %edx
movl %edx, %esi
callq 0x114e0
movq -0x10(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %edi
callq 0x11860
movq -0x38(%rbp), %rdi
movl %eax, %esi
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rcx
xorl %edx, %edx
callq 0x114e0
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdx
xorl %ecx, %ecx
movl %ecx, %esi
callq 0x11570
jmp 0x11f5c
movq -0x10(%rbp), %rax
movq %rax, -0x40(%rbp)
movl $0x6, %edi
leaq 0x447b(%rip), %rdx      # 0x15ec3
movq %rdx, %rsi
callq 0x10a20
movq -0x40(%rbp), %rdi
movq %rax, %rsi
callq 0x10e70
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
movl $0x3, %esi
xorl %edx, %edx
callq 0x114e0
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdx
xorl %ecx, %ecx
movl %ecx, %esi
callq 0x11570
jmp 0x11f5c
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdx
movl $0xb, %esi
callq 0x116f0
jmp 0x11f5c
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
xorl %edx, %edx
movl %edx, %esi
callq 0x114e0
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rcx
xorl %esi, %esi
movl $0x2, %edx
callq 0x114e0
movq -0x10(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0x4, %edi
leaq 0xe436(%rip), %rsi      # 0x1ff20
addq $0x50, %rsi
addq $0xa, %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x10a20
movq -0x48(%rbp), %rdi
movq %rax, %rsi
callq 0x10e70
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdx
xorl %ecx, %ecx
movl %ecx, %esi
callq 0x11570
jmp 0x11f5c
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
xorl %edx, %edx
movl %edx, %esi
callq 0x114e0
movq -0x10(%rbp), %rax
movq %rax, -0x58(%rbp)
movl $0xa, %edi
callq 0x109f0
movq -0x58(%rbp), %rdi
movq %rax, %rsi
callq 0x10e70
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rcx
xorl %esi, %esi
movl $0x2, %edx
callq 0x114e0
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movl $0x5, %edi
leaq 0xe3a0(%rip), %rsi      # 0x1ff20
addq $0x50, %rsi
addq $0xa, %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x10a20
movq -0x50(%rbp), %rdi
movq %rax, %rsi
callq 0x10e70
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdx
xorl %ecx, %ecx
movl %ecx, %esi
callq 0x11570
jmp 0x11f5c
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rcx
movl $0x7, %esi
callq 0x11600
movq -0x10(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %edi
callq 0x117f0
movq -0x60(%rbp), %rdi
movl %eax, %esi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdx
callq 0x116f0
jmp 0x11f5c
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x18(%rax), %edi
movl -0x14(%rbp), %esi
callq 0x110d0
cmpl $0x0, -0x14(%rbp)
jne 0x11c9f
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
xorl %esi, %esi
movl $0x2, %edx
callq 0x114e0
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x18(%rax), %eax
movl %eax, %ecx
leaq 0x8f8d(%rip), %rax      # 0x1abe0
movq (%rax,%rcx,8), %rcx
leaq 0xe362(%rip), %rdi      # 0x1ffc0
movl $0x32, %esi
leaq 0x425d(%rip), %rdx      # 0x15ec7
movb $0x0, %al
callq 0x30b0
movq -0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movl $0x1a, %edi
leaq 0xe33b(%rip), %rsi      # 0x1ffc0
xorl %eax, %eax
movl %eax, %edx
callq 0x10a20
movq -0x68(%rbp), %rdi
movq %rax, %rsi
callq 0x10e70
jmp 0x11d5b
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
movl $0x1, %esi
movl $0x3, %edx
callq 0x114e0
movl -0x14(%rbp), %ecx
leaq 0xe2fc(%rip), %rdi      # 0x1ffc0
movl $0x32, %esi
leaq 0x2db8(%rip), %rdx      # 0x14a88
movb $0x0, %al
callq 0x30b0
movq -0x10(%rbp), %rax
movq %rax, -0x78(%rbp)
xorl %edi, %edi
leaq 0x41e8(%rip), %rsi      # 0x15ed0
leaq 0xe2d1(%rip), %rdx      # 0x1ffc0
callq 0x10a20
movq -0x78(%rbp), %rdi
movq %rax, %rsi
callq 0x10e70
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x18(%rax), %eax
movl %eax, %ecx
leaq 0x8ecc(%rip), %rax      # 0x1abe0
movq (%rax,%rcx,8), %rcx
leaq 0xe2a1(%rip), %rdi      # 0x1ffc0
movl $0x32, %esi
leaq 0x41a9(%rip), %rdx      # 0x15ed4
movb $0x0, %al
callq 0x30b0
movq -0x10(%rbp), %rax
movq %rax, -0x70(%rbp)
movl $0x1a, %edi
leaq 0xe27a(%rip), %rsi      # 0x1ffc0
xorl %eax, %eax
movl %eax, %edx
callq 0x10a20
movq -0x70(%rbp), %rdi
movq %rax, %rsi
callq 0x10e70
jmp 0x11f5c
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
jne 0x11d7b
movl $0x1, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x18(%rax), %edi
callq 0x11120
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rcx
movl $0x1, %esi
movl $0x3, %edx
callq 0x114e0
movl -0x18(%rbp), %ecx
leaq 0xe210(%rip), %rdi      # 0x1ffc0
movl $0x32, %esi
leaq 0x2ccc(%rip), %rdx      # 0x14a88
movb $0x0, %al
callq 0x30b0
movq -0x10(%rbp), %rax
movq %rax, -0x88(%rbp)
xorl %edi, %edi
leaq 0x40f9(%rip), %rsi      # 0x15ed0
leaq 0xe1e2(%rip), %rdx      # 0x1ffc0
callq 0x10a20
movq -0x88(%rbp), %rdi
movq %rax, %rsi
callq 0x10e70
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x18(%rax), %eax
movl %eax, %ecx
leaq 0x8dda(%rip), %rax      # 0x1abe0
movq (%rax,%rcx,8), %rcx
leaq 0xe1af(%rip), %rdi      # 0x1ffc0
movl $0x32, %esi
leaq 0x40c6(%rip), %rdx      # 0x15ee3
movb $0x0, %al
callq 0x30b0
movq -0x10(%rbp), %rax
movq %rax, -0x80(%rbp)
movl $0x1a, %edi
leaq 0xe188(%rip), %rsi      # 0x1ffc0
xorl %eax, %eax
movl %eax, %edx
callq 0x10a20
movq -0x80(%rbp), %rdi
movq %rax, %rsi
callq 0x10e70
jmp 0x11f5c
movq -0x8(%rbp), %rax
movl 0x30(%rax), %ecx
leaq 0xe160(%rip), %rdi      # 0x1ffc0
movl $0x32, %esi
leaq 0x4085(%rip), %rdx      # 0x15ef1
movb $0x0, %al
callq 0x30b0
movq -0x8(%rbp), %rax
movl (%rax), %edi
callq 0x118d0
movl %eax, -0x1c(%rbp)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x11f2b
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x3ff8(%rip), %rdx      # 0x15e9b
callq 0x11450
movl $0x7, %edi
callq 0x109f0
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x28(%rbp), %rsi
addq $0x4, %rsi
movl $0x1, %edx
leaq 0x3fc8(%rip), %rcx      # 0x15e9a
callq 0x111a0
movq -0x8(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x11f0a
movq -0x28(%rbp), %rdi
addq $0x22, %rdi
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movl 0x30(%rax), %ecx
movl $0x1e, %esi
leaq 0x2b87(%rip), %rdx      # 0x14a88
movb $0x0, %al
callq 0x30b0
jmp 0x11f1e
movq -0x28(%rbp), %rdi
addq $0x22, %rdi
leaq 0x3fdf(%rip), %rsi      # 0x15ef8
callq 0x3050
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x10e70
movq -0x10(%rbp), %rax
movq %rax, -0x90(%rbp)
movl -0x1c(%rbp), %edi
leaq 0xe080(%rip), %rsi      # 0x1ffc0
xorl %eax, %eax
movl %eax, %edx
callq 0x10a20
movq -0x90(%rbp), %rdi
movq %rax, %rsi
callq 0x10e70
jmp 0x11f5c
jmp 0x11f5c
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)