// File: /workspace/github_c_makefile_star2_O0/cogbee[P]vmir-latest/src/vmir_transform.c
// Function: replace_gep_with_lea
static ir_instr_t *
replace_gep_with_lea(ir_unit_t *iu, ir_instr_gep_t *ii)
{
  int immediate_offset = 0;
  ir_valuetype_t value_offset = {-1, -1};
  int value_offset_multiply = 0;

  ir_valuetype_t baseptr = ii->baseptr;

  for(int j = 0; j < ii->num_indicies; j++) {
    int curtype = ii->indicies[j].type;
    const ir_type_t *cur = type_get(iu, curtype);
    const ir_value_t *op = value_get(iu, ii->indicies[j].value.value);
    int x;

    switch(cur->it_code) {
    case IR_TYPE_POINTER:

      switch(op->iv_class) {
      case IR_VC_CONSTANT:
        immediate_offset += value_get_const32(iu, op) *
          type_sizeof(iu, cur->it_pointer.pointee);
        break;

      case IR_VC_TEMPORARY:
      case IR_VC_REGFRAME:

        if(value_offset.value != -1)
          abort();

        value_offset = ii->indicies[j].value;
        value_offset_multiply =
          type_sizeof(iu, cur->it_pointer.pointee);
        break;
      default:
        parser_error(iu, "GEP: Can't handle class %d as pointee",
                     op->iv_class);
      }
      break;

    case IR_TYPE_STRUCT:
      switch(op->iv_class) {
      case IR_VC_CONSTANT:
        x = value_get_const32(iu, op);
        if(x >= cur->it_struct.num_elements)
          parser_error(iu, "Bad index %d info struct", x);

        immediate_offset += cur->it_struct.elements[x].offset;
        break;

      default:
        parser_error(iu, "Bad index class %d for struct",
                     op->iv_class);
      }
      break;

    case IR_TYPE_ARRAY:
      switch(op->iv_class) {
      case IR_VC_CONSTANT:
        immediate_offset += value_get_const32(iu, op) *
          type_sizeof(iu, cur->it_array.element_type);
        break;

      case IR_VC_TEMPORARY:
      case IR_VC_REGFRAME:

        if(value_offset.value != -1) {
          baseptr = emit_interim_lea(iu, baseptr,
                                     value_offset, value_offset_multiply,
                                     ii, curtype);
        }

        value_offset = ii->indicies[j].value;
        cur = type_get(iu, curtype);
        value_offset_multiply = type_sizeof(iu, cur->it_array.element_type);
        break;

      default:
        parser_error(iu, "GEP: Can't handle class %d as array index",
                     op->iv_class);
      }
      cur = type_get(iu, cur->it_array.element_type);
      break;
    default:
      parser_error(iu, "Unable to GEP for value type %d",
                   cur->it_code);
    }
  }

  ir_instr_lea_t *lea =
    instr_add_before(sizeof(ir_instr_lea_t), IR_IC_LEA, &ii->super);

  lea->super.ii_ret = ii->super.ii_ret;
  value_bind_return_value(iu, &lea->super);

  lea->baseptr = baseptr;

  registerify(iu, &lea->super, &lea->baseptr);

  lea->immediate_offset = immediate_offset;
  lea->value_offset = value_offset;
  lea->value_offset_multiply = value_offset_multiply;

  instr_destroy(&ii->super);
  return &lea->super;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movq 0x18b4a(%rip), %rax     # 0x3e078
movq %rax, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x5c(%rax), %rax
movq %rax, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x58(%rcx), %eax
jge 0x25839
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
movl 0x6c(%rax,%rcx,4), %eax
movl %eax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %esi
callq 0x1ee20
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
movl 0x64(%rax,%rcx,4), %esi
callq 0x20ee0
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
testl %eax, %eax
je 0x2567c
jmp 0x255af
movl -0x5c(%rbp), %eax
subl $0xa, %eax
je 0x25709
jmp 0x255bd
movl -0x5c(%rbp), %eax
subl $0xb, %eax
jne 0x25804
jmp 0x255cb
movq -0x40(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x60(%rbp)
subl $0x3, %eax
je 0x255e8
jmp 0x255db
movl -0x60(%rbp), %eax
addl $-0x4, %eax
subl $0x2, %eax
jb 0x25618
jmp 0x25652
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x261a0
movl %eax, -0x64(%rbp)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x1ecd0
movl %eax, %ecx
movl -0x64(%rbp), %eax
imull %ecx, %eax
addl -0x14(%rbp), %eax
movl %eax, -0x14(%rbp)
jmp 0x25677
cmpl $-0x1, -0x1c(%rbp)
je 0x25623
callq 0x3050
movq -0x10(%rbp), %rax
addq $0x64, %rax
movslq -0x2c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rax
movq %rax, -0x1c(%rbp)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x1ecd0
movl %eax, -0x20(%rbp)
jmp 0x25677
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rax
movl (%rax), %r8d
leaq 0x19d89(%rip), %rsi     # 0x3f3ed
movl $0x79, %edx
leaq 0x19d92(%rip), %rcx     # 0x3f402
movb $0x0, %al
callq 0x18220
jmp 0x25829
movq -0x40(%rbp), %rax
movl (%rax), %eax
subl $0x3, %eax
jne 0x256df
jmp 0x25689
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x261a0
movl %eax, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq -0x38(%rbp), %rcx
cmpl 0x18(%rcx), %eax
jl 0x256c7
movq -0x8(%rbp), %rdi
movl -0x44(%rbp), %r8d
leaq 0x19d39(%rip), %rsi     # 0x3f3ed
movl $0x82, %edx
leaq 0x19d68(%rip), %rcx     # 0x3f428
movb $0x0, %al
callq 0x18220
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x44(%rbp), %rcx
movl 0x4(%rax,%rcx,8), %eax
addl -0x14(%rbp), %eax
movl %eax, -0x14(%rbp)
jmp 0x25704
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rax
movl (%rax), %r8d
leaq 0x19cfc(%rip), %rsi     # 0x3f3ed
movl $0x89, %edx
leaq 0x19d44(%rip), %rcx     # 0x3f441
movb $0x0, %al
callq 0x18220
jmp 0x25829
movq -0x40(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x68(%rbp)
subl $0x3, %eax
je 0x25729
jmp 0x25719
movl -0x68(%rbp), %eax
addl $-0x4, %eax
subl $0x2, %eax
jb 0x2575c
jmp 0x257c9
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x261a0
movl %eax, -0x6c(%rbp)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0xc(%rax), %esi
callq 0x1ecd0
movl %eax, %ecx
movl -0x6c(%rbp), %eax
imull %ecx, %eax
addl -0x14(%rbp), %eax
movl %eax, -0x14(%rbp)
jmp 0x257ee
cmpl $-0x1, -0x1c(%rbp)
je 0x2578a
movq -0x8(%rbp), %rdi
movl -0x20(%rbp), %ecx
movq -0x10(%rbp), %r8
movl -0x30(%rbp), %r9d
movq -0x28(%rbp), %rsi
movq -0x1c(%rbp), %rdx
callq 0x262c0
movq %rax, -0x4c(%rbp)
movq -0x4c(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
addq $0x64, %rax
movslq -0x2c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rax
movq %rax, -0x1c(%rbp)
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %esi
callq 0x1ee20
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0xc(%rax), %esi
callq 0x1ecd0
movl %eax, -0x20(%rbp)
jmp 0x257ee
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rax
movl (%rax), %r8d
leaq 0x19c12(%rip), %rsi     # 0x3f3ed
movl $0xa4, %edx
leaq 0x19c78(%rip), %rcx     # 0x3f45f
movb $0x0, %al
callq 0x18220
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0xc(%rax), %esi
callq 0x1ee20
movq %rax, -0x38(%rbp)
jmp 0x25829
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movl (%rax), %r8d
leaq 0x19bd7(%rip), %rsi     # 0x3f3ed
movl $0xaa, %edx
leaq 0x19c67(%rip), %rcx     # 0x3f489
movb $0x0, %al
callq 0x18220
jmp 0x2582b
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x2554c
movq -0x10(%rbp), %rdx
movl $0x70, %edi
movl $0x14, %esi
callq 0x26380
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x2c(%rcx), %rcx
movq %rcx, 0x2c(%rax)
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x20cf0
movq -0x58(%rbp), %rax
movq -0x28(%rbp), %rcx
movq %rcx, 0x58(%rax)
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
movq -0x58(%rbp), %rdx
addq $0x58, %rdx
callq 0x26400
movl -0x14(%rbp), %ecx
movq -0x58(%rbp), %rax
movl %ecx, 0x60(%rax)
movq -0x58(%rbp), %rax
movq -0x1c(%rbp), %rcx
movq %rcx, 0x64(%rax)
movl -0x20(%rbp), %ecx
movq -0x58(%rbp), %rax
movl %ecx, 0x6c(%rax)
movq -0x10(%rbp), %rdi
callq 0x1cad0
movq -0x58(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)