// File: /workspace/github_c_makefile_star2_O0/cogbee[P]vmir-latest/src/vmir_vm.c
// Function: emit_lea
static void
emit_lea(ir_unit_t *iu, ir_instr_lea_t *ii)
{
  const ir_value_t *    ret = value_get(iu, ii->super.ii_ret.value);
  const ir_value_t *baseptr = value_get(iu, ii->baseptr.value);

  if(ii->value_offset.value == -1) {

    // Lea with immediate offset is same as add32 with constant
    emit_op2(iu, VM_ADD_R32C, value_reg(ret), value_reg(baseptr));
    emit_i32(iu, ii->immediate_offset);

  } else {
    const ir_value_t *off = value_get(iu, ii->value_offset.value);

    if(legalize_type(type_get(iu, ii->value_offset.type)) != IR_TYPE_INT32) {
      parser_error(iu, "LEA: Can't handle %s as offset register",
                   type_str_index(iu, ii->value_offset.type));
    }

    assert(ii->value_offset_multiply != 0);

    int fb = ffs(ii->value_offset_multiply) - 1;
    if((1 << fb) == ii->value_offset_multiply) {

      if(ii->immediate_offset) {
        emit_op4(iu, VM_LEA_R32_SHL_OFF,
                 value_reg(ret), value_reg(baseptr), value_reg(off), fb);
        emit_i32(iu, ii->immediate_offset);
        return;
      }

      if(fb == 2) {
        emit_op3(iu, VM_LEA_R32_SHL2,
               value_reg(ret), value_reg(baseptr), value_reg(off));
        return;
      }
      emit_op4(iu, VM_LEA_R32_SHL,
               value_reg(ret), value_reg(baseptr), value_reg(off), fb);
      return;
    }

    emit_op3(iu, VM_LEA_R32_MUL_OFF,
             value_reg(ret), value_reg(baseptr), value_reg(off));
    emit_i32(iu, ii->value_offset_multiply);
    emit_i32(iu, ii->immediate_offset);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %esi
callq 0x20ee0
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %esi
callq 0x20ee0
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
cmpl $-0x1, 0x64(%rax)
jne 0x2f050
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rdi
callq 0x321a0
movw %ax, -0x2e(%rbp)
movq -0x20(%rbp), %rdi
callq 0x321a0
movq -0x38(%rbp), %rdi
movw -0x2e(%rbp), %cx
movl $0x35, %esi
movzwl %cx, %edx
movzwl %ax, %ecx
callq 0x324a0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x60(%rax), %esi
callq 0x2b450
jmp 0x2f29c
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x64(%rax), %esi
callq 0x20ee0
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x68(%rax), %esi
callq 0x1ee20
movq %rax, %rdi
callq 0x45d0
cmpl $0x5, %eax
je 0x2f0ba
movq -0x8(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x68(%rax), %esi
callq 0x22560
movq -0x40(%rbp), %rdi
movq %rax, %r8
leaq 0x10e78(%rip), %rsi     # 0x3ff1f
movl $0xf66, %edx            # imm = 0xF66
leaq 0x112fa(%rip), %rcx     # 0x403ad
movb $0x0, %al
callq 0x18220
movq -0x10(%rbp), %rax
cmpl $0x0, 0x6c(%rax)
je 0x2f0c6
jmp 0x2f0e5
leaq 0x11308(%rip), %rdi     # 0x403d5
leaq 0x10e4b(%rip), %rsi     # 0x3ff1f
movl $0xf69, %edx            # imm = 0xF69
leaq 0x11314(%rip), %rcx     # 0x403f4
callq 0x31c0
movq -0x10(%rbp), %rax
movl 0x6c(%rax), %edi
callq 0x3340
subl $0x1, %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movq -0x10(%rbp), %rcx
cmpl 0x6c(%rcx), %eax
jne 0x2f231
movq -0x10(%rbp), %rax
cmpl $0x0, 0x60(%rax)
je 0x2f183
movq -0x8(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x18(%rbp), %rdi
callq 0x321a0
movw %ax, -0x44(%rbp)
movq -0x20(%rbp), %rdi
callq 0x321a0
movw %ax, -0x42(%rbp)
movq -0x28(%rbp), %rdi
callq 0x321a0
movq -0x50(%rbp), %rdi
movw -0x44(%rbp), %dx
movw -0x42(%rbp), %cx
movw %ax, %r8w
movl -0x2c(%rbp), %eax
movl $0x183, %esi            # imm = 0x183
movzwl %dx, %edx
movzwl %cx, %ecx
movzwl %r8w, %r8d
movzwl %ax, %r9d
callq 0x32e90
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x60(%rax), %esi
callq 0x2b450
jmp 0x2f29c
cmpl $0x2, -0x2c(%rbp)
jne 0x2f1d9
movq -0x8(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x18(%rbp), %rdi
callq 0x321a0
movw %ax, -0x54(%rbp)
movq -0x20(%rbp), %rdi
callq 0x321a0
movw %ax, -0x52(%rbp)
movq -0x28(%rbp), %rdi
callq 0x321a0
movq -0x60(%rbp), %rdi
movw -0x54(%rbp), %dx
movw -0x52(%rbp), %cx
movl $0x182, %esi            # imm = 0x182
movzwl %dx, %edx
movzwl %cx, %ecx
movzwl %ax, %r8d
callq 0x32430
jmp 0x2f29c
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x18(%rbp), %rdi
callq 0x321a0
movw %ax, -0x64(%rbp)
movq -0x20(%rbp), %rdi
callq 0x321a0
movw %ax, -0x62(%rbp)
movq -0x28(%rbp), %rdi
callq 0x321a0
movq -0x70(%rbp), %rdi
movw -0x64(%rbp), %dx
movw -0x62(%rbp), %cx
movw %ax, %r8w
movl -0x2c(%rbp), %eax
movl $0x181, %esi            # imm = 0x181
movzwl %dx, %edx
movzwl %cx, %ecx
movzwl %r8w, %r8d
movzwl %ax, %r9d
callq 0x32e90
jmp 0x2f29c
movq -0x8(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x18(%rbp), %rdi
callq 0x321a0
movw %ax, -0x74(%rbp)
movq -0x20(%rbp), %rdi
callq 0x321a0
movw %ax, -0x72(%rbp)
movq -0x28(%rbp), %rdi
callq 0x321a0
movq -0x80(%rbp), %rdi
movw -0x74(%rbp), %dx
movw -0x72(%rbp), %cx
movl $0x184, %esi            # imm = 0x184
movzwl %dx, %edx
movzwl %cx, %ecx
movzwl %ax, %r8d
callq 0x32430
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x6c(%rax), %esi
callq 0x2b450
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x60(%rax), %esi
callq 0x2b450
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)