// File: luooofan[P]hblzbd_compiler/src/Pass/generate_arm_from_ssa.cpp
// Function: GenerateArmFromSSA::AddPrologue(ArmFunction*, FunctionValue*)
void GenerateArmFromSSA::AddPrologue(ArmFunction* func, FunctionValue* func_val) {
  MyAssert(func->bb_list_.front() == prologue);

  // push {lr}
  auto push_inst = new PushPop(PushPop::OpKind::PUSH, prologue);
  push_inst->reg_list_.push_back(machine_regs[ArmReg::lr]);

  // sub sp,sp,#0    放进sp_fixup中 等待寄存器分配完成后修改该值
  auto op2 = ResolveImm2Operand2(prologue, 0, true);
  MyAssert(!op2->is_imm_);
  new BinaryInst(BiOp::SUB, machine_regs[ArmReg::sp], machine_regs[ArmReg::sp], op2, prologue);

  // TODO:
  // 可以把prologue单独当作一个基本块 把原来第一个bb的idom指向prologue 并维护其他关系
  // 取参数和全局变量到一个vreg中的操作可以放到在该函数内其所有使用的最小公共祖先基本块的末尾(dom tree)
  // 这样应该能在一定程度上优化寄存器分配
  // mov args to vreg
  for (auto arg : func_val->GetArgList()) {
    ResolveValue2Reg(prologue, arg);
  }

  // load global var address to vreg
  // NOTE: 全局量都是地址 全局变量的偏移都是0 全局数组的偏移可变
  for (auto glob_var : func_val->GetFunction()->GetUsedGlobVarList()) {
    Reg* rglo = NewVirtualReg();
    var_map[glob_var] = rglo;
    new LdrPseudo(rglo, glob_var->GetName(), prologue);
  }
}

// Assembly:
subq $0xe8, %rsp
movq %rdi, 0xe0(%rsp)
movq %rsi, 0xd8(%rsp)
movq %rdx, 0xd0(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0xd8(%rsp), %rdi
addq $0x38, %rdi
callq 0x81bf0
movq 0x58(%rsp), %rcx
movq (%rax), %rax
cmpq 0x108(%rcx), %rax
je 0xad125
movq 0x9ef13(%rip), %rdi     # 0x14bfe8
leaq 0x4d01c(%rip), %rsi     # 0xfa0f8
callq 0x8330
movq %rax, %rdi
leaq 0x508de(%rip), %rsi     # 0xfd9c9
callq 0x8330
movq %rax, %rdi
leaq 0x4e2f0(%rip), %rsi     # 0xfb3ea
callq 0x8330
movq %rax, %rdi
movl $0x14e, %esi            # imm = 0x14E
callq 0x8650
movq %rax, %rdi
movq 0x9ee6a(%rip), %rsi     # 0x14bf80
callq 0x8380
movl $0xff, %edi
callq 0x8460
movl $0x30, %edi
callq 0x8340
movq %rax, %rdi
movq 0x58(%rsp), %rax
movq %rdi, %rcx
movq %rcx, 0x50(%rsp)
movq 0x108(%rax), %rdx
xorl %esi, %esi
callq 0xb2510
jmp 0xad14f
movq 0x58(%rsp), %rdi
movq 0x50(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0xc8(%rsp), %rax
addq $0x18, %rax
movq %rax, 0x48(%rsp)
addq $0x38, %rdi
movl $0xe, %esi
callq 0xcd90
movq 0x48(%rsp), %rdi
movq %rax, %rsi
callq 0x7d1c0
movq 0x58(%rsp), %rdi
movq 0x108(%rdi), %rsi
xorl %edx, %edx
movl $0x1, %ecx
callq 0xab2c0
movq %rax, 0xb0(%rsp)
movq 0xb0(%rsp), %rax
testb $0x1, (%rax)
je 0xad239
movq 0x9ee27(%rip), %rdi     # 0x14bfe8
leaq 0x4cf30(%rip), %rsi     # 0xfa0f8
callq 0x8330
movq %rax, %rdi
leaq 0x507f2(%rip), %rsi     # 0xfd9c9
callq 0x8330
movq %rax, %rdi
leaq 0x4e204(%rip), %rsi     # 0xfb3ea
callq 0x8330
movq %rax, %rdi
movl $0x156, %esi            # imm = 0x156
callq 0x8650
movq %rax, %rdi
movq 0x9ed7e(%rip), %rsi     # 0x14bf80
callq 0x8380
movl $0xff, %edi
callq 0x8460
movq 0x50(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc0(%rsp)
movl %eax, 0xbc(%rsp)
movl $0x30, %esi
callq 0x8350
jmp 0xad4b6
movl $0x38, %edi
callq 0x8340
movq 0x58(%rsp), %rdi
movq %rax, 0x38(%rsp)
movq %rax, 0x20(%rsp)
addq $0x38, %rdi
movq %rdi, 0x28(%rsp)
movl $0xd, %esi
movq %rsi, 0x30(%rsp)
callq 0xcd90
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rsi
movq (%rax), %rax
movq %rax, 0x40(%rsp)
callq 0xcd90
movq 0x38(%rsp), %rdi
movq 0x40(%rsp), %rdx
movq %rax, %rcx
movq 0x58(%rsp), %rax
movq (%rcx), %rcx
movq 0xb0(%rsp), %r8
movq 0x108(%rax), %r9
movl $0x1, %esi
callq 0xb23b0
jmp 0xad2b1
movq 0xd0(%rsp), %rdi
callq 0xa1120
movq %rax, 0xa8(%rsp)
movq 0xa8(%rsp), %rdi
callq 0xa1130
movq %rax, 0xa0(%rsp)
movq 0xa8(%rsp), %rdi
callq 0xa1160
movq %rax, 0x98(%rsp)
leaq 0xa0(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0xa1190
testb $0x1, %al
jne 0xad30b
jmp 0xad373
leaq 0xa0(%rsp), %rdi
callq 0xa11b0
movq 0x58(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x90(%rsp)
movq 0x108(%rdi), %rsi
movq 0x90(%rsp), %rdx
callq 0xabf80
leaq 0xa0(%rsp), %rdi
callq 0xa11e0
jmp 0xad2f0
movq 0x20(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc0(%rsp)
movl %eax, 0xbc(%rsp)
movl $0x38, %esi
callq 0x8350
jmp 0xad4b6
movq 0xd0(%rsp), %rdi
callq 0x5e2a0
movq %rax, %rdi
callq 0xa1200
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
callq 0x62b10
movq %rax, 0x80(%rsp)
movq 0x88(%rsp), %rdi
callq 0x62b40
movq %rax, 0x78(%rsp)
leaq 0x80(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x62b70
testb $0x1, %al
jne 0xad3d2
jmp 0xad4ae
leaq 0x80(%rsp), %rdi
callq 0x62b90
movq 0x58(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x70(%rsp)
callq 0xaaf80
movq 0x58(%rsp), %rdi
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rax
movq %rax, (%rsp)
addq $0x58, %rdi
movq 0x70(%rsp), %rax
movq %rax, 0x60(%rsp)
leaq 0x60(%rsp), %rsi
callq 0xb2570
movq (%rsp), %rcx
movq %rcx, (%rax)
movl $0x48, %edi
callq 0x8340
movq %rax, 0x8(%rsp)
movq 0x68(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x70(%rsp), %rdi
callq 0x5e770
movq %rax, 0x18(%rsp)
jmp 0xad44d
movq 0x18(%rsp), %rdx
movq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
movq 0x58(%rsp), %rax
movq 0x108(%rax), %rcx
movl $0x1, %r8d
callq 0xb25a0
jmp 0xad475
jmp 0xad477
leaq 0x80(%rsp), %rdi
callq 0x62bb0
jmp 0xad3b7
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc0(%rsp)
movl %eax, 0xbc(%rsp)
movl $0x48, %esi
callq 0x8350
jmp 0xad4b6
addq $0xe8, %rsp
retq
movq 0xc0(%rsp), %rdi
callq 0x8670
nopw %cs:(%rax,%rax)