// File: /workspace/github_cpp_makefile_star2_O1/baziotis[P]minijava-cpp/llvm.cpp
// Function: cgen_start_method(Method*, char const*, bool)
void cgen_start_method(Method *method, const char *class_name, bool is_main_method) {
    reset_lbl();
    // Emit function prototype
    emit("define ");
    cgen_print_lltype(method->ret_type);

    if (!is_main_method) {
      emit(" @%s__%s(", class_name, method->id);
    } else {
      emit(" @main(", class_name, method->id);
    }
    
    // Emit `this` pointer.
    size_t param_len = method->param_len;
    emit("i8* %%0");
    if (param_len)
      emit(", ");
    

    // Initialize parameters with registers and also
    // print them as part of the method prototype.
    // We're starting from 1, because register 0
    // is always reserved for the 'this' pointer.
    // Set a register _only_ for the parameters.
    size_t local_reg_counter = 1;
    size_t param_counter;
    for (param_counter = 0; param_counter < param_len; ++param_counter) {
        Local *local = method->locals[param_counter];
        // Print
        cgen_print_lltype(local->type);
        emit(" %%%ld", local_reg_counter);
        if (param_counter != param_len - 1) {
          emit(", ");
        }
        // Initialize
        local->kind = (int)LOCAL_KIND::PARAM;
        local->llval = register_llv(local_reg_counter, {});
        local->index = param_counter;
        ++local_reg_counter;
    }
    set_reg(local_reg_counter);

    // Start of body of method
    emit(") {\n");

    // Initialize locals. Locals initially get a
    // register that is a pointer to some memory
    // that can hold the value. It's only when they're
    // first used that the value is loaded into a reg.
    // So, initialize them with this pointer and also
    // generate allocas.
    size_t locals_len = method->locals.len;
    size_t var_counter = param_counter;
    for (; var_counter < locals_len; ++var_counter) {
        Local *local = method->locals[var_counter];
        local->kind = (int)LOCAL_KIND::VAR;
        local->index = var_counter;
        // Initialize all the values to 0.
        local->llval = const_llv(0, {});
    }

    llvm_label_t entry_lbl = llvm_label_t("entry");
    llvm_gen_lbl(entry_lbl);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %rbx
movq $0x0, 0x14055(%rip) # 0x19a30
leaq 0xbcf3(%rip), %rdi      # 0x116d5
xorl %eax, %eax
callq 0x479d
movq 0x8(%rbx), %rdi
callq 0x4b55
movq (%rbx), %rdx
leaq 0xbceb(%rip), %rax      # 0x116e7
leaq 0xbcda(%rip), %rdi      # 0x116dd
testl %ebp, %ebp
cmovneq %rax, %rdi
movq %r14, %rsi
xorl %eax, %eax
callq 0x479d
movq 0x10(%rbx), %r13
leaq 0xbcd1(%rip), %rdi      # 0x116ef
xorl %eax, %eax
callq 0x479d
testq %r13, %r13
je 0x5ab9
leaq 0xd38a(%rip), %rdi      # 0x12dbf
xorl %eax, %eax
callq 0x479d
leaq -0x1(%r13), %rbp
movl $0x1, %r14d
movq %r14, %r12
movq 0x30(%rbx), %rax
movq -0x8(%rax,%r14,8), %r15
movq 0x8(%r15), %rdi
callq 0x4b55
leaq 0xbc95(%rip), %rdi      # 0x116f7
movq %r14, %rsi
xorl %eax, %eax
callq 0x479d
decq %r14
cmpq %rbp, %r14
je 0x5a82
leaq 0xd344(%rip), %rdi      # 0x12dbf
xorl %eax, %eax
callq 0x479d
movb $0x1, 0x38(%r15)
movl $0x2, 0x10(%r15)
movq $0x0, 0x18(%r15)
movl $0x0, 0x20(%r15)
leaq 0x1(%r14), %rax
movq %rax, 0x28(%r15)
movq %r14, 0x30(%r15)
addq $0x2, %r14
cmpq %r13, %rax
jne 0x5a46
incq %r12
jmp 0x5ac2
movl $0x1, %r12d
xorl %r13d, %r13d
movq %r12, 0x13f5f(%rip)     # 0x19a28
leaq 0xbc2e(%rip), %rdi      # 0x116fe
xorl %ebp, %ebp
xorl %eax, %eax
callq 0x479d
movq 0x38(%rbx), %rax
cmpq %rax, %r13
jae 0x5b0f
movq 0x30(%rbx), %rcx
movq (%rcx,%r13,8), %rcx
movb $0x3, 0x38(%rcx)
movq %r13, 0x30(%rcx)
movl $0x1, 0x10(%rcx)
movq $0x0, 0x18(%rcx)
movl %ebp, 0x20(%rcx)
movl %ebp, 0x28(%rcx)
incq %r13
cmpq %r13, %rax
jne 0x5ae2
leaq 0xb9dd(%rip), %rdi      # 0x114f3
leaq 0xbbe6(%rip), %rbx      # 0x11703
movq %rbx, %rsi
xorl %eax, %eax
callq 0x479d
movq %rbx, 0x13e8a(%rip)     # 0x199b8
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq