// File: 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:
subq $0x128, %rsp            # imm = 0x128
movq %rdi, 0x118(%rsp)
movq %rsi, 0x110(%rsp)
movq %rdx, 0x108(%rsp)
movq 0x118(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x108(%rsp), %rax
movq %rax, 0xa0(%rsp)
cmpq $0x0, %rax
je 0xabfee
movq 0xa0(%rsp), %rdi
leaq 0x9f4fc(%rip), %rsi     # 0x14b4d0
leaq 0x9f51d(%rip), %rdx     # 0x14b4f8
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x90(%rsp)
jmp 0xabffa
xorl %eax, %eax
movq %rax, 0x90(%rsp)
jmp 0xabffa
movq 0x90(%rsp), %rax
movq %rax, 0x100(%rsp)
cmpq $0x0, 0x100(%rsp)
je 0xac058
movq 0x110(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x100(%rsp), %rdi
callq 0x5e800
movq 0x98(%rsp), %rdi
movq 0x88(%rsp), %rsi
movl %eax, %edx
xorl %ecx, %ecx
callq 0xaaff0
movq %rax, 0x120(%rsp)
jmp 0xac51c
movq 0x108(%rsp), %rax
movq %rax, 0x80(%rsp)
cmpq $0x0, %rax
je 0xac094
movq 0x80(%rsp), %rdi
leaq 0x9f453(%rip), %rsi     # 0x14b4d0
leaq 0x9f45c(%rip), %rdx     # 0x14b4e0
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x78(%rsp)
jmp 0xac09d
xorl %eax, %eax
movq %rax, 0x78(%rsp)
jmp 0xac09d
movq 0x78(%rsp), %rax
movq %rax, 0xf8(%rsp)
cmpq $0x0, 0xf8(%rsp)
je 0xac0de
movq 0x98(%rsp), %rdi
addq $0x58, %rdi
leaq 0x108(%rsp), %rsi
callq 0xb2460
movq (%rax), %rax
movq %rax, 0x120(%rsp)
jmp 0xac51c
movq 0x108(%rsp), %rax
movq %rax, 0x70(%rsp)
cmpq $0x0, %rax
je 0xac114
movq 0x70(%rsp), %rdi
leaq 0x9f3d3(%rip), %rsi     # 0x14b4d0
leaq 0x9f43c(%rip), %rdx     # 0x14b540
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x68(%rsp)
jmp 0xac11d
xorl %eax, %eax
movq %rax, 0x68(%rsp)
jmp 0xac11d
movq 0x68(%rsp), %rax
movq %rax, 0xf0(%rsp)
cmpq $0x0, 0xf0(%rsp)
je 0xac363
movq 0x98(%rsp), %rdi
addq $0x58, %rdi
leaq 0x108(%rsp), %rsi
callq 0xb24b0
movq 0x98(%rsp), %rdi
movq %rax, 0xe8(%rsp)
addq $0x58, %rdi
callq 0xb24e0
movq %rax, 0xe0(%rsp)
leaq 0xe8(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0xb2490
testb $0x1, %al
jne 0xac18e
jmp 0xac1b7
movq 0x98(%rsp), %rdi
addq $0x58, %rdi
leaq 0x108(%rsp), %rsi
callq 0xb2460
movq (%rax), %rax
movq %rax, 0x120(%rsp)
jmp 0xac51c
movq 0x98(%rsp), %rdi
callq 0xaaf80
movq %rax, 0xd8(%rsp)
movq 0xf0(%rsp), %rdi
callq 0x5e910
movl %eax, 0xd4(%rsp)
cmpl $0x4, 0xd4(%rsp)
jae 0xac2bd
movl $0x28, %edi
callq 0x8340
movq %rax, 0x50(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x58(%rsp)
movl $0x18, %edi
callq 0x8340
movq %rax, 0x60(%rsp)
jmp 0xac21b
movq 0x98(%rsp), %rdi
addq $0x38, %rdi
movl 0xd4(%rsp), %eax
movl %eax, %esi
callq 0xcd90
movq 0x60(%rsp), %rdi
movq (%rax), %rsi
callq 0x78090
jmp 0xac244
movq 0x60(%rsp), %rdx
movq 0x58(%rsp), %rsi
movq 0x50(%rsp), %rdi
movq 0x110(%rsp), %rcx
xorl %r8d, %r8d
movl $0x1, %r9d
callq 0xb2060
jmp 0xac26b
jmp 0xac320
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc8(%rsp)
movl %eax, 0xc4(%rsp)
jmp 0xac2a9
movq 0x60(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc8(%rsp)
movl %eax, 0xc4(%rsp)
movl $0x18, %esi
callq 0x8350
movq 0x50(%rsp), %rdi
movl $0x28, %esi
callq 0x8350
jmp 0xac52c
movq 0x98(%rsp), %rdi
movq 0x110(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x48(%rsp)
addq $0x38, %rdi
movl $0xd, %esi
callq 0xcd90
movq 0x98(%rsp), %rdi
movq 0x40(%rsp), %rsi
movq 0x48(%rsp), %rcx
movq (%rax), %r8
movl 0xd4(%rsp), %r9d
subl $0x4, %r9d
shll $0x2, %r9d
xorl %edx, %edx
movl $0x1, (%rsp)
callq 0xab3d0
movq 0x98(%rsp), %rdi
movq 0xd8(%rsp), %rax
movq %rax, 0x38(%rsp)
addq $0x58, %rdi
leaq 0x108(%rsp), %rsi
callq 0xb2460
movq 0x38(%rsp), %rcx
movq %rcx, (%rax)
movq 0xd8(%rsp), %rax
movq %rax, 0x120(%rsp)
jmp 0xac51c
movq 0x108(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
je 0xac399
movq 0x30(%rsp), %rdi
leaq 0x9f14e(%rip), %rsi     # 0x14b4d0
leaq 0x9f19f(%rip), %rdx     # 0x14b528
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x28(%rsp)
jmp 0xac3a2
xorl %eax, %eax
movq %rax, 0x28(%rsp)
jmp 0xac3a2
movq 0x28(%rsp), %rax
cmpq $0x0, %rax
jne 0xac3f7
movq 0x108(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0xac3e3
movq 0x20(%rsp), %rdi
leaq 0x9f104(%rip), %rsi     # 0x14b4d0
leaq 0x9f13d(%rip), %rdx     # 0x14b510
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x18(%rsp)
jmp 0xac3ec
xorl %eax, %eax
movq %rax, 0x18(%rsp)
jmp 0xac3ec
movq 0x18(%rsp), %rax
cmpq $0x0, %rax
je 0xac44e
movq 0x9fbea(%rip), %rdi     # 0x14bfe8
leaq 0x4dcf3(%rip), %rsi     # 0xfa0f8
callq 0x8330
movq %rax, %rdi
leaq 0x515b5(%rip), %rsi     # 0xfd9c9
callq 0x8330
movq %rax, %rdi
leaq 0x4efc7(%rip), %rsi     # 0xfb3ea
callq 0x8330
movq %rax, %rdi
movl $0x138, %esi            # imm = 0x138
callq 0x8650
movq %rax, %rdi
movq 0x9fb41(%rip), %rsi     # 0x14bf80
callq 0x8380
movl $0xff, %edi
callq 0x8460
movq 0x98(%rsp), %rdi
addq $0x58, %rdi
leaq 0x108(%rsp), %rsi
callq 0xb24b0
movq 0x98(%rsp), %rdi
movq %rax, 0xb8(%rsp)
addq $0x58, %rdi
callq 0xb24e0
movq %rax, 0xb0(%rsp)
leaq 0xb8(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0xb2490
testb $0x1, %al
jne 0xac4a3
jmp 0xac4c9
movq 0x98(%rsp), %rdi
addq $0x58, %rdi
leaq 0x108(%rsp), %rsi
callq 0xb2460
movq (%rax), %rax
movq %rax, 0x120(%rsp)
jmp 0xac51c
movq 0x98(%rsp), %rdi
callq 0xaaf80
movq 0x98(%rsp), %rdi
movq %rax, 0xa8(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, 0x10(%rsp)
addq $0x58, %rdi
leaq 0x108(%rsp), %rsi
callq 0xb2460
movq 0x10(%rsp), %rcx
movq %rcx, (%rax)
movq 0xa8(%rsp), %rax
movq %rax, 0x120(%rsp)
movq 0x120(%rsp), %rax
addq $0x128, %rsp            # imm = 0x128
retq
movq 0xc8(%rsp), %rdi
callq 0x8670
nopl (%rax)