// File: /workspace/github_cpp_makefile_star2_O2/acliusBackHome[P]kamaya/dist/IR.cpp
// Function: IR::exprEmit(ParseExpression const&, ParseType const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, ParseTree&, unsigned long, unsigned long)
void IR::exprEmit(const ParseExpression &init_expr, const ParseType &this_type,
                  const string &symbol, ParseTree &tree, size_t node_id,
                  size_t scope_id) {
  if (init_expr.is_const()) {
    string arg1 = getConstValueStr(init_expr);
    string result = address2pointer(init_expr.get_address());
    if (scope_id == 0) {
      // 在静态数据段生成，字符串(TODO)也在此生成
      dataEmit(symbol, this_type.get_size(), arg1, node_id);
    } else {
      // 在栈中分配
      gen(":=", arg1, "_", result, node_id);
    }
  } else {
    ExpressionType exp_type = init_expr.get_expr_type();
    string op = "_", arg1 = "_", arg2 = "_", result = "_";
    switch (exp_type) {
    // 双目运算符
    case ExpressionType::E_ADD:
      op = "+";
      break;
    case ExpressionType::E_SUB:
      op = "-";
      break;
    case ExpressionType::E_MUL:
      op = "*";
      break;
    case ExpressionType::E_DIV:
      op = "/";
      break;
    case ExpressionType::E_MOD:
      op = "%";
      break;
    case ExpressionType::E_POW:
      op = "^";
      break;
    case ExpressionType::E_LOGIC_OR:
      op = "||";
      break;
    case ExpressionType::E_LOGIC_AND:
      op = "&&";
      break;
    case ExpressionType::E_G:
      op = ">";
      break;
    case ExpressionType::E_GE:
      op = ">=";
      break;
    case ExpressionType::E_EQUAL:
      op = "==";
      break;
    case ExpressionType::E_NE:
      op = "!=";
      break;
    case ExpressionType::E_L:
      op = "<";
      break;
    case ExpressionType::E_LE:
      op = "<=";
      break;
    case ExpressionType::E_GET_ITEM: {
      getItemEmit(init_expr, this_type, symbol, tree, node_id, scope_id);
      return;
    }
    default:
      break;
    }
    if (op != "_") {
      const ParseExpression &right =
          ParseExpression::get_expression(init_expr.get_child(1));
      if (right.is_const()) {
        arg2 = getConstValueStr(right);
      } else {
        arg2 = address2pointer(right.get_address());
      }
    }
    switch (exp_type) {
    case ExpressionType::E_VAR: {
      return;
    }
    case ExpressionType::E_FUN: {
      gen("call", "_", "_", (init_expr.get_functions()[0])->get_symbol(),
          node_id);
      gen(":=", "eax", "_", address2pointer(init_expr.get_address()), node_id);
      return;
    }
    case ExpressionType::E_NOT:
      op = "!";
      break;
    case ExpressionType::E_ASSIGN: {
      // 赋值表达式
      assignEmit(init_expr.get_child(0), init_expr.get_child(1));
      const ParseExpression &left =
          ParseExpression::get_expression(init_expr.get_child(0));
      const ParseExpression &right =
          ParseExpression::get_expression(init_expr.get_child(1));
      string arg1, result;
      result = address2pointer(left.get_address());
      if (right.is_const()) {
        arg1 = getConstValueStr(right);
      } else {
        arg1 = address2pointer(right.get_address());
      }
      gen(":=", arg1, "_", result, node_id);
      return;
    }
    case ExpressionType::E_UNDEFINED: // 应该不会跑到这里
      if (scope_id == 0) {
        dataUndefinedEmit(symbol, this_type.get_size(), node_id);
      }
      // 这个表达式非常特别
      return;
    default:

      break;
    }
    if (op != "_") {
      const ParseExpression &left =
          ParseExpression::get_expression(init_expr.get_child(0));
      if (left.is_const()) {
        arg1 = getConstValueStr(left);
      } else {
        arg1 = address2pointer(left.get_address());
      }
    }
    result = address2pointer(init_expr.get_address());
    if (op != "_") {
      gen(op, arg1, arg2, result, node_id);
    } else {
      throw ParseException(ExceptionCode::EX_NOT_IMPLEMENTED,
                           "other exp type " + to_string(exp_type));
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x128, %rsp            # imm = 0x128
movq %r9, -0x40(%rbp)
movq %rcx, %r13
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, -0x38(%rbp)
movq %rsi, %rdi
callq 0x24972
testb %al, %al
je 0x332b3
leaq -0xc0(%rbp), %rdi
movq %r15, %rsi
callq 0x32b54
movq %r15, %rdi
callq 0x24c42
leaq -0x120(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq %rax, %rdx
callq 0xd2ea
cmpq $0x0, 0x10(%rbp)
je 0x33352
leaq 0x70ee(%rip), %rsi      # 0x3a349
leaq -0x100(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x4130
leaq 0x7430(%rip), %rsi      # 0x3a6a2
leaq -0x140(%rbp), %rdi
leaq -0xa0(%rbp), %rdx
callq 0x4130
leaq -0x100(%rbp), %rsi
leaq -0xc0(%rbp), %rdx
leaq -0x140(%rbp), %rcx
leaq -0x120(%rbp), %r8
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %r9
callq 0x32694
jmp 0x33873
movq %r15, %rdi
callq 0x26408
movl %eax, %r12d
leaq 0x73dd(%rip), %rsi      # 0x3a6a2
leaq -0xc0(%rbp), %rdi
leaq -0x120(%rbp), %rdx
callq 0x4130
leaq 0x73c3(%rip), %rsi      # 0x3a6a2
leaq -0x120(%rbp), %rdi
leaq -0x100(%rbp), %rdx
callq 0x4130
leaq 0x73a9(%rip), %rsi      # 0x3a6a2
leaq -0x100(%rbp), %rdi
leaq -0x140(%rbp), %rdx
callq 0x4130
leaq 0x738f(%rip), %rsi      # 0x3a6a2
leaq -0x140(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x4130
leal -0x4(%r12), %eax
cmpl $0x14, %eax
ja 0x33401
leaq 0x959c(%rip), %rcx      # 0x3c8d4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x38(%rbp), %rdi
movq %r15, %rsi
callq 0x33058
jmp 0x33873
movq %rbx, %rdi
callq 0x21bec
leaq -0xc0(%rbp), %rcx
movq -0x38(%rbp), %rdi
movq %r13, %rsi
movq %rax, %rdx
movq -0x40(%rbp), %r8
callq 0x32c88
jmp 0x3388b
leaq 0x4cc0(%rip), %rsi      # 0x38040
jmp 0x333f5
leaq 0x4cc1(%rip), %rsi      # 0x3804a
jmp 0x333f5
leaq 0x4cc0(%rip), %rsi      # 0x38052
jmp 0x333f5
leaq 0x7e6d(%rip), %rsi      # 0x3b208
jmp 0x333f5
leaq 0x6fa3(%rip), %rsi      # 0x3a347
jmp 0x333f5
leaq 0x4ca1(%rip), %rsi      # 0x3804e
jmp 0x333f5
leaq 0x5af3(%rip), %rsi      # 0x38ea9
jmp 0x333f5
leaq 0x53dc(%rip), %rsi      # 0x3879b
jmp 0x333f5
leaq 0x6f97(%rip), %rsi      # 0x3a35f
jmp 0x333f5
leaq 0x4c72(%rip), %rsi      # 0x38043
jmp 0x333f5
leaq 0x6f69(%rip), %rsi      # 0x3a343
jmp 0x333f5
leaq 0x6f62(%rip), %rsi      # 0x3a345
jmp 0x333f5
leaq 0x4bb0(%rip), %rsi      # 0x37f9c
jmp 0x333f5
leaq 0x6f67(%rip), %rsi      # 0x3a35c
leaq -0xc0(%rbp), %rdi
callq 0x4550
leaq 0x729a(%rip), %rsi      # 0x3a6a2
leaq -0xc0(%rbp), %rdi
callq 0x31b63
testb %al, %al
je 0x3347b
pushq $0x1
popq %rsi
movq %r15, %rdi
callq 0x25ffa
movq %rax, %rdi
callq 0x247e8
movq %rax, %r14
movq %rax, %rdi
callq 0x24972
testb %al, %al
je 0x33448
leaq -0x60(%rbp), %rdi
movq %r14, %rsi
callq 0x32b54
jmp 0x33460
movq %r14, %rdi
callq 0x24c42
leaq -0x60(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq %rax, %rdx
callq 0xd2ea
leaq -0x100(%rbp), %rdi
leaq -0x60(%rbp), %r14
movq %r14, %rsi
callq 0x4340
movq %r14, %rdi
callq 0x4598
testl %r12d, %r12d
je 0x336f1
cmpl $0x1, %r12d
je 0x33873
cmpl $0x19, %r12d
je 0x3363a
cmpl $0xb, %r12d
je 0x335d6
cmpl $0x2, %r12d
jne 0x335e9
leaq 0x7580(%rip), %rsi      # 0x3aa33
leaq -0x60(%rbp), %rdi
leaq -0x2a(%rbp), %rdx
callq 0x4130
leaq 0x71db(%rip), %rsi      # 0x3a6a2
leaq -0xa0(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x4130
leaq 0x71c4(%rip), %rsi      # 0x3a6a2
leaq -0x80(%rbp), %rdi
leaq -0x2b(%rbp), %rdx
callq 0x4130
movq %r15, %rdi
callq 0x25f34
movq (%rax), %rax
movq (%rax), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x276f6
leaq -0x60(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
leaq -0x80(%rbp), %rcx
leaq -0xe0(%rbp), %r8
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %r9
callq 0x32694
leaq -0xe0(%rbp), %rdi
callq 0x4598
leaq -0x80(%rbp), %rdi
callq 0x4598
leaq -0xa0(%rbp), %rdi
callq 0x4598
leaq -0x60(%rbp), %rdi
callq 0x4598
leaq 0x6df0(%rip), %rsi      # 0x3a349
leaq -0x60(%rbp), %rdi
leaq -0x2a(%rbp), %rdx
callq 0x4130
leaq 0x91d6(%rip), %rsi      # 0x3c743
leaq -0xa0(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x4130
leaq 0x711e(%rip), %rsi      # 0x3a6a2
leaq -0x80(%rbp), %rdi
leaq -0x2b(%rbp), %rdx
callq 0x4130
movq %r15, %rdi
callq 0x24c42
movq -0x38(%rbp), %rbx
leaq -0xe0(%rbp), %rdi
movq %rbx, %rsi
movq %rax, %rdx
callq 0xd2ea
leaq -0x60(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
leaq -0x80(%rbp), %rcx
leaq -0xe0(%rbp), %r8
movq %rbx, %rdi
movq -0x40(%rbp), %r9
callq 0x32694
jmp 0x33849
leaq 0x6d85(%rip), %rsi      # 0x3a362
leaq -0xc0(%rbp), %rdi
callq 0x4550
leaq 0x70b2(%rip), %rsi      # 0x3a6a2
leaq -0xc0(%rbp), %rdi
callq 0x31b63
testb %al, %al
je 0x3374f
movq %r15, %rdi
xorl %esi, %esi
callq 0x25ffa
movq %rax, %rdi
callq 0x247e8
movq %rax, %rbx
movq %rax, %rdi
callq 0x24972
testb %al, %al
je 0x3371c
leaq -0x60(%rbp), %rdi
movq %rbx, %rsi
callq 0x32b54
jmp 0x33734
movq %r15, %rdi
xorl %esi, %esi
callq 0x25ffa
pushq $0x1
popq %rsi
movq %r15, %rdi
callq 0x25ffa
movq %r15, %rdi
xorl %esi, %esi
callq 0x25ffa
movq %rax, %rdi
callq 0x247e8
movq %rax, %r12
pushq $0x1
popq %rsi
movq %r15, %rdi
callq 0x25ffa
movq %rax, %rdi
callq 0x247e8
movq %rax, %rbx
leaq -0x50(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorl %ecx, %ecx
movb %cl, (%rax)
leaq -0x90(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb %cl, (%rax)
movq %r12, %rdi
callq 0x24c42
leaq -0x80(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq %rax, %rdx
callq 0xd2ea
leaq -0xa0(%rbp), %rdi
leaq -0x80(%rbp), %r14
movq %r14, %rsi
callq 0x4340
movq %r14, %rdi
callq 0x4598
movq %rbx, %rdi
callq 0x24972
testb %al, %al
je 0x337cb
leaq -0x80(%rbp), %rdi
movq %rbx, %rsi
callq 0x32b54
jmp 0x337e3
cmpq $0x0, 0x10(%rbp)
jne 0x33873
movq %rbx, %rdi
callq 0x21bec
movq -0x38(%rbp), %rdi
movq %r13, %rsi
movq %rax, %rdx
movq -0x40(%rbp), %rcx
callq 0x32db2
jmp 0x33873
movq %rbx, %rdi
callq 0x24c42
leaq -0x60(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq %rax, %rdx
callq 0xd2ea
leaq -0x120(%rbp), %rdi
leaq -0x60(%rbp), %rbx
movq %rbx, %rsi
callq 0x4340
movq %rbx, %rdi
callq 0x4598
movq %r15, %rdi
callq 0x24c42
leaq -0x60(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq %rax, %rdx
callq 0xd2ea
leaq -0x140(%rbp), %rdi
leaq -0x60(%rbp), %rbx
movq %rbx, %rsi
callq 0x4340
movq %rbx, %rdi
callq 0x4598
leaq 0x6f19(%rip), %rsi      # 0x3a6a2
leaq -0xc0(%rbp), %rdi
callq 0x31b63
testb %al, %al
je 0x338b5
leaq -0xc0(%rbp), %rsi
leaq -0x120(%rbp), %rdx
leaq -0x100(%rbp), %rcx
leaq -0x140(%rbp), %r8
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %r9
callq 0x32694
jmp 0x33873
movq %rbx, %rdi
callq 0x24c42
leaq -0x80(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq %rax, %rdx
callq 0xd2ea
leaq -0x60(%rbp), %rdi
leaq -0x80(%rbp), %rbx
movq %rbx, %rsi
callq 0x4340
movq %rbx, %rdi
callq 0x4598
leaq 0x6b47(%rip), %rsi      # 0x3a349
leaq -0x80(%rbp), %rdi
leaq -0x2a(%rbp), %rdx
callq 0x4130
leaq 0x6e8c(%rip), %rsi      # 0x3a6a2
leaq -0xe0(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x4130
leaq -0x80(%rbp), %rsi
leaq -0x60(%rbp), %rdx
leaq -0xe0(%rbp), %rcx
leaq -0xa0(%rbp), %r8
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %r9
callq 0x32694
leaq -0xe0(%rbp), %rdi
callq 0x4598
leaq -0x80(%rbp), %rdi
callq 0x4598
leaq -0xa0(%rbp), %rdi
callq 0x4598
leaq -0x60(%rbp), %rdi
callq 0x4598
leaq -0x140(%rbp), %rdi
callq 0x4598
leaq -0x100(%rbp), %rdi
callq 0x4598
leaq -0x120(%rbp), %rdi
callq 0x4598
leaq -0xc0(%rbp), %rdi
callq 0x4598
addq $0x128, %rsp            # imm = 0x128
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x28
popq %rdi
callq 0x4180
movq %rax, %r14
leaq -0xa0(%rbp), %rdi
movl %r12d, %esi
callq 0xc8ff
leaq 0x9138(%rip), %rsi      # 0x3ca0e
leaq -0x60(%rbp), %rdi
leaq -0xa0(%rbp), %rdx
callq 0xc837
movb $0x1, %r15b
pushq $0x13
popq %rsi
leaq -0x60(%rbp), %rdx
movq %r14, %rdi
callq 0x2b53c
xorl %r15d, %r15d
leaq 0x1f46e(%rip), %rsi     # 0x52d70
leaq -0x27061(%rip), %rdx    # 0xc8a8
movq %r14, %rdi
callq 0x44e0
jmp 0x33981
movq %rax, %rbx
leaq -0x60(%rbp), %rdi
callq 0x4598
jmp 0x33927
movq %rax, %rbx
movb $0x1, %r15b
leaq -0xa0(%rbp), %rdi
callq 0x4598
testb %r15b, %r15b
jne 0x33955
jmp 0x339d6
jmp 0x339d3
jmp 0x33963
jmp 0x33988
jmp 0x33963
jmp 0x33981
jmp 0x33981
jmp 0x33981
jmp 0x33981
jmp 0x33976
movq %rax, %rbx
movq %r14, %rdi
callq 0x4220
jmp 0x339d6
jmp 0x339d3
jmp 0x339d3
movq %rax, %rbx
leaq -0xe0(%rbp), %rdi
callq 0x4598
jmp 0x3398b
jmp 0x33981
movq %rax, %rbx
jmp 0x339a0
jmp 0x339d3
jmp 0x339d3
jmp 0x33988
movq %rax, %rbx
jmp 0x33994
jmp 0x339d3
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
callq 0x4598
leaq -0xa0(%rbp), %rdi
callq 0x4598
leaq -0x60(%rbp), %rdi
callq 0x4598
jmp 0x339d6
jmp 0x339d3
jmp 0x339d3
jmp 0x339d3
jmp 0x339d3
jmp 0x339d3
jmp 0x339bb
jmp 0x339c0
jmp 0x339c0
movq %rax, %rbx
jmp 0x339e2
movq %rax, %rbx
jmp 0x339ee
jmp 0x339ce
movq %rax, %rbx
jmp 0x33a06
jmp 0x339d3
movq %rax, %rbx
jmp 0x339fa
movq %rax, %rbx
leaq -0x140(%rbp), %rdi
callq 0x4598
leaq -0x100(%rbp), %rdi
callq 0x4598
leaq -0x120(%rbp), %rdi
callq 0x4598
leaq -0xc0(%rbp), %rdi
callq 0x4598
movq %rbx, %rdi
callq 0x4500