// File: luooofan[P]hblzbd_compiler/src/Pass/generate_arm_from_ssa.cpp
// Function: GenerateArmFromSSA::GenerateArmBasicBlocks(ArmFunction*, SSAFunction*, std::unordered_map<SSABasicBlock*, ArmBasicBlock*, std::hash<SSABasicBlock*>, std::equal_to<SSABasicBlock*>, std::allocator<std::pair<SSABasicBlock* const, ArmBasicBlock*>>>&)
void GenerateArmFromSSA::GenerateArmBasicBlocks(ArmFunction* armfunc, SSAFunction* func,
                                                std::unordered_map<SSABasicBlock*, ArmBasicBlock*>& bb_map) {
  armfunc->bb_list_.reserve(func->GetBBList().size() + 2);
  // create prologue and epilogue
  prologue = new ArmBasicBlock("." + armfunc->name_ + ".prologue.bb");
  prologue->func_ = armfunc;
  epilogue = new ArmBasicBlock("." + armfunc->name_ + ".epilogue.bb");
  epilogue->func_ = armfunc;
  armfunc->bb_list_.push_back(prologue);

  // create armbb according to irbb
  for (auto bb : func->GetBBList()) {
    // ArmBasicBlock* armbb = new ArmBasicBlock(&(bb->GetLabel()));  // FIXME
    ArmBasicBlock* armbb = new ArmBasicBlock();
    bool set_label = false;
    for (auto use : bb->GetValue()->GetUses()) {
      if (nullptr == dynamic_cast<PhiInst*>(use->GetUser())) set_label = true;
    }
    if (set_label) armbb->label_ = bb->GetLabel();
    bb_map.insert({bb, armbb});
    armfunc->bb_list_.push_back(armbb);
    armbb->func_ = armfunc;
  }

  // maintain pred and succ
  if (armfunc->bb_list_.size() > 1) {
    prologue->succ_.push_back(armfunc->bb_list_[1]);
    armfunc->bb_list_[1]->pred_.push_back(prologue);
  }
  for (auto bb : func->GetBBList()) {
    auto armbb = bb_map[bb];
    for (auto pred : bb->GetPredBB()) {
      armbb->pred_.push_back(bb_map[pred]);
    }
    for (auto succ : bb->GetSuccBB()) {
      armbb->succ_.push_back(bb_map[succ]);
    }
  }
}

// Assembly:
subq $0x1e8, %rsp            # imm = 0x1E8
movq %rdi, 0x1e0(%rsp)
movq %rsi, 0x1d8(%rsp)
movq %rdx, 0x1d0(%rsp)
movq %rcx, 0x1c8(%rsp)
movq 0x1e0(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x1d8(%rsp), %rax
addq $0x38, %rax
movq %rax, 0x48(%rsp)
movq 0x1d0(%rsp), %rdi
callq 0x62c10
movq %rax, %rdi
callq 0xb27d0
movq 0x48(%rsp), %rdi
movq %rax, %rsi
addq $0x2, %rsi
callq 0xb26c0
movl $0x158, %edi            # imm = 0x158
callq 0x8340
movq %rax, 0x50(%rsp)
movb $0x1, 0x17b(%rsp)
movq 0x1d8(%rsp), %rdx
addq $0x8, %rdx
leaq 0x50074(%rip), %rsi     # 0xfd8c9
leaq 0x188(%rsp), %rdi
callq 0x37520
jmp 0xad864
leaq 0x50181(%rip), %rdx     # 0xfd9ec
leaq 0x1a8(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0xcbd0
jmp 0xad882
movq 0x50(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0xb2800
jmp 0xad896
movq 0x40(%rsp), %rax
movq 0x50(%rsp), %rcx
movb $0x0, 0x17b(%rsp)
movq %rcx, 0x108(%rax)
leaq 0x1a8(%rsp), %rdi
callq 0x8728
leaq 0x188(%rsp), %rdi
callq 0x8728
movq 0x40(%rsp), %rax
movq 0x1d8(%rsp), %rcx
movq 0x108(%rax), %rax
movq %rcx, 0x28(%rax)
movl $0x158, %edi            # imm = 0x158
callq 0x8340
movq %rax, 0x38(%rsp)
movb $0x1, 0x137(%rsp)
movq 0x1d8(%rsp), %rdx
addq $0x8, %rdx
leaq 0x4ffbe(%rip), %rsi     # 0xfd8c9
leaq 0x138(%rsp), %rdi
callq 0x37520
jmp 0xad91a
leaq 0x500d8(%rip), %rdx     # 0xfd9f9
leaq 0x158(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0xcbd0
jmp 0xad938
movq 0x38(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0xb2800
jmp 0xad94c
movq 0x40(%rsp), %rax
movq 0x38(%rsp), %rcx
movb $0x0, 0x137(%rsp)
movq %rcx, 0x110(%rax)
leaq 0x158(%rsp), %rdi
callq 0x8728
leaq 0x138(%rsp), %rdi
callq 0x8728
movq 0x40(%rsp), %rsi
movq 0x1d8(%rsp), %rcx
movq 0x110(%rsi), %rax
movq %rcx, 0x28(%rax)
movq 0x1d8(%rsp), %rdi
addq $0x38, %rdi
addq $0x108, %rsi            # imm = 0x108
callq 0xb2640
movq 0x1d0(%rsp), %rdi
callq 0x62c10
movq %rax, 0x128(%rsp)
movq 0x128(%rsp), %rdi
callq 0x62c80
movq %rax, 0x120(%rsp)
movq 0x128(%rsp), %rdi
callq 0x62cb0
movq %rax, 0x118(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x118(%rsp), %rsi
callq 0x68fc0
testb $0x1, %al
jne 0xada0c
jmp 0xadd16
leaq 0x120(%rsp), %rdi
callq 0x62d20
movq (%rax), %rax
movq %rax, 0x110(%rsp)
movl $0x158, %edi            # imm = 0x158
callq 0x8340
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x30(%rsp)
callq 0xb28a0
jmp 0xada40
movq 0x30(%rsp), %rax
movq %rax, 0x108(%rsp)
movb $0x0, 0x107(%rsp)
movq 0x110(%rsp), %rdi
callq 0x8ee70
movq %rax, %rdi
callq 0x5e2d0
movq %rax, 0xf8(%rsp)
movq 0xf8(%rsp), %rdi
callq 0x5e160
movq %rax, 0xf0(%rsp)
movq 0xf8(%rsp), %rdi
callq 0x5e1b0
movq %rax, 0xe8(%rsp)
leaq 0xf0(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x5e190
testb $0x1, %al
jne 0xadaba
jmp 0xadc61
leaq 0xf0(%rsp), %rdi
callq 0x5e1e0
movq (%rax), %rax
movq %rax, 0xe0(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x60410
movq %rax, 0x28(%rsp)
cmpq $0x0, %rax
je 0xadc30
movq 0x28(%rsp), %rdi
leaq 0x9db16(%rip), %rsi     # 0x14b610
leaq 0x9dd8f(%rip), %rdx     # 0x14b890
xorl %eax, %eax
movl %eax, %ecx
callq 0x8410
movq %rax, 0x20(%rsp)
jmp 0xadc39
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x180(%rsp)
movl %eax, 0x17c(%rsp)
jmp 0xadb6e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x180(%rsp)
movl %eax, 0x17c(%rsp)
jmp 0xadb61
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x180(%rsp)
movl %eax, 0x17c(%rsp)
leaq 0x1a8(%rsp), %rdi
callq 0x8728
leaq 0x188(%rsp), %rdi
callq 0x8728
testb $0x1, 0x17b(%rsp)
jne 0xadb7a
jmp 0xadb89
movq 0x50(%rsp), %rdi
movl $0x158, %esi            # imm = 0x158
callq 0x8350
jmp 0xadf83
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x180(%rsp)
movl %eax, 0x17c(%rsp)
jmp 0xadbe8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x180(%rsp)
movl %eax, 0x17c(%rsp)
jmp 0xadbdb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x180(%rsp)
movl %eax, 0x17c(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x8728
leaq 0x138(%rsp), %rdi
callq 0x8728
testb $0x1, 0x137(%rsp)
jne 0xadbf4
jmp 0xadc03
movq 0x38(%rsp), %rdi
movl $0x158, %esi            # imm = 0x158
callq 0x8350
jmp 0xadf83
movq 0x30(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x180(%rsp)
movl %eax, 0x17c(%rsp)
movl $0x158, %esi            # imm = 0x158
callq 0x8350
jmp 0xadf83
xorl %eax, %eax
movq %rax, 0x20(%rsp)
jmp 0xadc39
movq 0x20(%rsp), %rcx
xorl %eax, %eax
cmpq %rcx, %rax
jne 0xadc4d
movb $0x1, 0x107(%rsp)
jmp 0xadc4f
leaq 0xf0(%rsp), %rdi
callq 0x5e280
jmp 0xada9c
testb $0x1, 0x107(%rsp)
je 0xadc8c
movq 0x110(%rsp), %rdi
callq 0xb2940
movq %rax, %rsi
movq 0x108(%rsp), %rdi
addq $0x8, %rdi
callq 0x8050
movq 0x1c8(%rsp), %rax
movq %rax, 0x18(%rsp)
leaq 0xd0(%rsp), %rdi
leaq 0x110(%rsp), %rsi
leaq 0x108(%rsp), %rdx
callq 0xb29a0
movq 0x18(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0xb2950
movq %rax, 0xc0(%rsp)
movb %dl, 0xc8(%rsp)
movq 0x1d8(%rsp), %rdi
addq $0x38, %rdi
leaq 0x108(%rsp), %rsi
callq 0xb2640
movq 0x1d8(%rsp), %rcx
movq 0x108(%rsp), %rax
movq %rcx, 0x28(%rax)
leaq 0x120(%rsp), %rdi
callq 0x62ce0
jmp 0xad9ee
movq 0x1d8(%rsp), %rdi
addq $0x38, %rdi
callq 0x81bd0
cmpq $0x1, %rax
jbe 0xadd93
movq 0x40(%rsp), %rax
movq 0x108(%rax), %rax
addq $0x60, %rax
movq %rax, 0x10(%rsp)
movq 0x1d8(%rsp), %rdi
addq $0x38, %rdi
movl $0x1, %esi
callq 0xb29d0
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0xb2640
movq 0x1d8(%rsp), %rdi
addq $0x38, %rdi
movl $0x1, %esi
callq 0xb29d0
movq 0x40(%rsp), %rsi
movq (%rax), %rdi
addq $0x48, %rdi
addq $0x108, %rsi            # imm = 0x108
callq 0xb2640
movq 0x1d0(%rsp), %rdi
callq 0x62c10
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x62c80
movq %rax, 0xb0(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x62cb0
movq %rax, 0xa8(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x68fc0
testb $0x1, %al
jne 0xaddf0
jmp 0xadf7b
leaq 0xb0(%rsp), %rdi
callq 0x62d20
movq (%rax), %rax
movq %rax, 0xa0(%rsp)
movq 0x1c8(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0xb29f0
movq (%rax), %rax
movq %rax, 0x98(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x62710
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rdi
callq 0x62720
movq %rax, 0x88(%rsp)
movq 0x90(%rsp), %rdi
callq 0x62750
movq %rax, 0x80(%rsp)
leaq 0x88(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x62780
testb $0x1, %al
jne 0xade82
jmp 0xaded6
leaq 0x88(%rsp), %rdi
callq 0x627a0
movq (%rax), %rax
movq %rax, 0x78(%rsp)
movq 0x98(%rsp), %rax
addq $0x48, %rax
movq %rax, 0x8(%rsp)
movq 0x1c8(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0xb29f0
movq 0x8(%rsp), %rdi
movq %rax, %rsi
callq 0xb2640
leaq 0x88(%rsp), %rdi
callq 0x627f0
jmp 0xade67
movq 0xa0(%rsp), %rdi
callq 0x62810
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rdi
callq 0x62720
movq %rax, 0x68(%rsp)
movq 0x70(%rsp), %rdi
callq 0x62750
movq %rax, 0x60(%rsp)
leaq 0x68(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x62780
testb $0x1, %al
jne 0xadf1b
jmp 0xadf67
leaq 0x68(%rsp), %rdi
callq 0x627a0
movq (%rax), %rax
movq %rax, 0x58(%rsp)
movq 0x98(%rsp), %rax
addq $0x60, %rax
movq %rax, (%rsp)
movq 0x1c8(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0xb29f0
movq (%rsp), %rdi
movq %rax, %rsi
callq 0xb2640
leaq 0x68(%rsp), %rdi
callq 0x627f0
jmp 0xadf06
jmp 0xadf69
leaq 0xb0(%rsp), %rdi
callq 0x62ce0
jmp 0xaddd2
addq $0x1e8, %rsp            # imm = 0x1E8
retq
movq 0x180(%rsp), %rdi
callq 0x8670