// File: /workspace/github_cpp_makefile_star2_O2/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, 0x10(%rsp)
testq %rdx, %rdx
je 0x3d356
movq %rdx, %r15
movq %rsi, %r14
leaq 0x43212(%rip), %rsi     # 0x80480
leaq 0x43233(%rip), %rdx     # 0x804a8
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x3d2a2
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 0x3cbbe
leaq 0x431d7(%rip), %rsi     # 0x80480
leaq 0x431e0(%rip), %rdx     # 0x80490
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x3d2d0
addq $0x58, %rbx
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
jmp 0x3d374
leaq 0x431a9(%rip), %rsi     # 0x80480
leaq 0x43212(%rip), %rdx     # 0x804f0
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x3d314
movq %rax, %r13
leaq 0x58(%rbx), %r12
leaq 0x10(%rsp), %rsi
movq %r12, %rdi
callq 0x40b46
testq %rax, %rax
je 0x3d3ab
leaq 0x10(%rsp), %rsi
movq %r12, %rdi
jmp 0x3d374
leaq 0x43165(%rip), %rsi     # 0x80480
leaq 0x431b6(%rip), %rdx     # 0x804d8
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
jne 0x3d439
leaq 0x43144(%rip), %rsi     # 0x80480
leaq 0x4317d(%rip), %rdx     # 0x804c0
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
jne 0x3d439
leaq 0x58(%rbx), %r14
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x40b46
testq %rax, %rax
je 0x3d37e
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x407fe
movq (%rax), %r15
jmp 0x3d399
movq %rbx, %rdi
callq 0x3cb82
movq %rax, %r15
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x407fe
movq %r15, (%rax)
movq %r15, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
callq 0x3cb82
movq %rax, %r15
movl 0x48(%r13), %ebp
cmpq $0x3, %rbp
ja 0x3d405
pushq $0x28
popq %rdi
callq 0x8250
movq %rax, %r13
pushq $0x18
popq %rdi
callq 0x8250
movq 0x38(%rbx), %rcx
movq (%rcx,%rbp,8), %rcx
movb $0x0, (%rax)
andl $0x0, 0x4(%rax)
movq %rcx, 0x8(%rax)
andq $0x0, 0x10(%rax)
pushq $0x1
popq %r9
movq %r13, %rdi
movq %r15, %rsi
movq %rax, %rdx
movq %r14, %rcx
xorl %r8d, %r8d
callq 0x3fbc8
jmp 0x3d42c
movq 0x38(%rbx), %rax
movq 0x68(%rax), %r8
leal -0x10(,%rbp,4), %r9d
movl $0x1, (%rsp)
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
movq %r15, %rcx
callq 0x3cd7e
leaq 0x10(%rsp), %rsi
movq %r12, %rdi
jmp 0x3d391
movq 0x43ba8(%rip), %rdi     # 0x80fe8
leaq 0x18ca1(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x1c3a1(%rip), %rsi     # 0x597f4
movq %rax, %rdi
callq 0x8240
leaq 0x19ebe(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x138, %esi            # imm = 0x138
callq 0x84b0
movq %rax, %rdi
callq 0x8170
movl $0xff, %edi
callq 0x8300
movq %rax, %rbx
pushq $0x28
popq %rsi
movq %r13, %rdi
callq 0x8260
movq %rbx, %rdi
callq 0x84d0
nop