// File: /workspace/github_cpp_makefile_star2_O3/luooofan[P]hblzbd_compiler/src/Pass/generate_arm_from_ssa.cpp
// Function: GenerateArmFromSSA::ResolveValue2Reg(ArmBasicBlock*, Value*)
Reg* GenerateArmFromSSA::ResolveValue2Reg(ArmBasicBlock* armbb, Value* val) {
  if (auto src_val = dynamic_cast<ConstantInt*>(val)) {
    return ResolveImm2Reg(armbb, src_val->GetImm());
  } else if (auto src_val = dynamic_cast<GlobalVariable*>(val)) {
    // 如果是全局量 在函数prologue中会把其地址或基址记录在var map中 直接返回地址即可
    return var_map[val];
  }
  // else if (auto src_val = dynamic_cast<UndefVariable*>(val)) {
  // val->Print(std::cout);// MyAssert(0);
  // 测例中会出现UB 但是测例用给定的输入数据不会有UB e.g. int c; while(c...){...} return c;
  // 暂时和普通变量同处理
  //}
  else if (auto src_val = dynamic_cast<Argument*>(val)) {
    // 如果能在var map中找到 说明这是一次对参数的使用 返回即可 返回的寄存器中存的可能是参数变量值 也可能是数组参数的基址
    if (var_map.find(val) != var_map.end()) {
      return var_map[val];
    }
    // 找不到 此时执行流肯定在addprologue中 根据是第几个参数 产生mov或者ldr语句 把参数都放到寄存器里 并记录到var map中
    else {
      Reg* vreg = NewVirtualReg();
      auto arg_no = src_val->GetArgNo();
      if (arg_no < 4) {
        new Move(vreg, new Operand2(machine_regs[arg_no]), armbb);
      } else {  // NOTE: 寄存器分配后修改的时候应该是+=最终的stack_size+push的大小
        GenImmLdrStrInst(armbb, LdrStr::OpKind::LDR, vreg, machine_regs[ArmReg::sp], /*4 lr +*/ (arg_no - 4) * 4, true);
      }
      var_map[val] = vreg;
      return vreg;
    }
  } else if (dynamic_cast<FunctionValue*>(val) || dynamic_cast<BasicBlockValue*>(val)) {
    MyAssert(0);
  } else {
    // 先在var map中找 找到直接返回 没找到(意味着定值)就记录映射并返回
    if (var_map.find(val) != var_map.end()) {
      return var_map[val];
    } else {
      Reg* vreg = NewVirtualReg();
      var_map[val] = vreg;
      return vreg;
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movq %rdx, 0x8(%rsp)
testq %rdx, %rdx
je 0x4cb2c
movq %rdx, %r15
movq %rsi, %r14
leaq 0x41a3c(%rip), %rsi     # 0x8e480
leaq 0x41a5d(%rip), %rdx     # 0x8e4a8
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x4ca78
movl 0x48(%rax), %edx
movq %rbx, %rdi
movq %r14, %rsi
xorl %ecx, %ecx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4c00e
leaq 0x41a01(%rip), %rsi     # 0x8e480
leaq 0x41a0a(%rip), %rdx     # 0x8e490
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x4caa6
addq $0x58, %rbx
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
jmp 0x4cb4a
leaq 0x419d3(%rip), %rsi     # 0x8e480
leaq 0x41a3c(%rip), %rdx     # 0x8e4f0
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x4caea
movq %rax, %r13
leaq 0x58(%rbx), %r12
leaq 0x8(%rsp), %rsi
movq %r12, %rdi
callq 0x50f52
testq %rax, %rax
je 0x4cbb4
leaq 0x8(%rsp), %rsi
movq %r12, %rdi
jmp 0x4cb4a
leaq 0x4198f(%rip), %rsi     # 0x8e480
leaq 0x419e0(%rip), %rdx     # 0x8e4d8
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
jne 0x4cca3
leaq 0x4196e(%rip), %rsi     # 0x8e480
leaq 0x419a7(%rip), %rdx     # 0x8e4c0
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
jne 0x4cca3
leaq 0x58(%rbx), %r14
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x50f52
testq %rax, %rax
je 0x4cb54
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x50cc0
movq (%rax), %r15
jmp 0x4cba2
movl $0x40, %edi
callq 0x8290
movq %rax, %r15
movl 0x50(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x50(%rbx)
leaq 0x30(%r15), %rcx
movq %rcx, (%r15)
movq $0x1, 0x8(%r15)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%r15)
movl $0x3f800000, 0x20(%r15) # imm = 0x3F800000
movups %xmm0, 0x28(%r15)
movl %eax, 0x38(%r15)
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x50cc0
movq %r15, (%rax)
movq %r15, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x40, %edi
callq 0x8290
movq %rax, %r15
movl 0x50(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x50(%rbx)
leaq 0x30(%r15), %rcx
movq %rcx, (%r15)
movq $0x1, 0x8(%r15)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%r15)
movl $0x3f800000, 0x20(%r15) # imm = 0x3F800000
movups %xmm0, 0x28(%r15)
movl %eax, 0x38(%r15)
movl 0x48(%r13), %r13d
cmpq $0x3, %r13
ja 0x4cc6f
movl $0x28, %edi
callq 0x8290
movq %rax, 0x10(%rsp)
movl $0x18, %edi
callq 0x8290
movq %rax, %rbp
movq 0x38(%rbx), %rax
movq (%rax,%r13,8), %rax
movb $0x0, (%rbp)
movl $0x0, 0x4(%rbp)
movq %rax, 0x8(%rbp)
movq $0x0, 0x10(%rbp)
movq 0x10(%rsp), %rdi
movq %r14, %rsi
movl $0x1, %edx
callq 0xa41e
leaq 0x408a0(%rip), %rax     # 0x8d4f0
leaq 0x10(%rax), %rcx
movq 0x10(%rsp), %rdi
movq %rcx, (%rdi)
movw $0x0, 0x14(%rdi)
movq %r15, 0x18(%rdi)
movq %rbp, 0x20(%rdi)
callq *0x28(%rax)
jmp 0x4cc96
movq 0x38(%rbx), %rax
movq 0x68(%rax), %r8
leal -0x10(,%r13,4), %r9d
movl $0x1, (%rsp)
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
movq %r15, %rcx
callq 0x4c2b4
leaq 0x8(%rsp), %rsi
movq %r12, %rdi
jmp 0x4cb9a
movq 0x4233e(%rip), %rdi     # 0x8efe8
leaq 0x214b7(%rip), %rsi     # 0x6e168
callq 0x8280
leaq 0x24bd7(%rip), %rsi     # 0x71894
movq %rax, %rdi
callq 0x8280
leaq 0x226f4(%rip), %rsi     # 0x6f3c0
movq %rax, %rdi
callq 0x8280
movq %rax, %rdi
movl $0x138, %esi            # imm = 0x138
callq 0x8520
movq %rax, %rdi
callq 0x8180
movl $0xff, %edi
callq 0x8380
movq %rax, %rbx
movl $0x28, %esi
movq 0x10(%rsp), %rdi
callq 0x82a0
movq %rbx, %rdi
callq 0x8540
nop