// File: /workspace/github_cpp_makefile_star2_O2/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
andq $0x0, 0x13845(%rip)     # 0x18a30
leaq 0xa401(%rip), %rdi      # 0xf5f3
xorl %eax, %eax
callq 0x42fe
movq 0x8(%rbx), %rdi
callq 0x465e
movq (%rbx), %rdx
leaq 0xa3f9(%rip), %rax      # 0xf605
leaq 0xa3e8(%rip), %rdi      # 0xf5fb
testl %ebp, %ebp
cmovneq %rax, %rdi
movq %r14, %rsi
xorl %eax, %eax
callq 0x42fe
movq 0x10(%rbx), %r13
leaq 0xa3df(%rip), %rdi      # 0xf60d
xorl %eax, %eax
callq 0x42fe
testq %r13, %r13
je 0x5248
leaq 0xbadf(%rip), %rdi      # 0x10d20
xorl %eax, %eax
callq 0x42fe
leaq -0x1(%r13), %rbp
xorl %r12d, %r12d
cmpq %r12, %r13
je 0x52b2
leaq 0x1(%r12), %r15
movq 0x30(%rbx), %rax
movq (%rax,%r12,8), %r14
movq 0x8(%r14), %rdi
callq 0x465e
leaq 0xa3a4(%rip), %rdi      # 0xf615
movq %r15, %rsi
xorl %eax, %eax
callq 0x42fe
cmpq %r12, %rbp
je 0x528e
leaq 0xba99(%rip), %rdi      # 0x10d20
xorl %eax, %eax
callq 0x42fe
movb $0x1, 0x38(%r14)
movl $0x2, 0x10(%r14)
andq $0x0, 0x18(%r14)
andl $0x0, 0x20(%r14)
movq %r15, 0x28(%r14)
movq %r12, 0x30(%r14)
movq %r15, %r12
jmp 0x524f
incq %r12
movq %r12, 0x1376c(%rip)     # 0x18a28
leaq 0xa359(%rip), %rdi      # 0xf61c
xorl %eax, %eax
callq 0x42fe
movq 0x38(%rbx), %rax
cmpq %rax, %r13
jae 0x52fc
movq 0x30(%rbx), %rcx
movq (%rcx,%r13,8), %rcx
movb $0x3, 0x38(%rcx)
movq %r13, 0x30(%rcx)
movl $0x1, 0x10(%rcx)
andq $0x0, 0x18(%rcx)
andl $0x0, 0x20(%rcx)
andl $0x0, 0x28(%rcx)
incq %r13
jmp 0x52ce
leaq 0xa31e(%rip), %rdi      # 0xf621
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4d51