// File: /workspace/github_c_makefile_star2_O0/cogbee[P]vmir-latest/src/vmir_transform.c
// Function: legalize_aggregate
static void
legalize_aggregate(ir_unit_t *iu, ir_value_t *iv)
{
  const int num_values = iv->iv_num_values;
  const ir_valuetype_t *values = iv->iv_data;
  assert(num_values > 1);

  ir_value_instr_t *ivi;
  while((ivi = LIST_FIRST(&iv->iv_instructions)) != NULL) {
    const int rel = ivi->ivi_relation;
    ir_instr_t *ii = ivi->ivi_instr;
    ivi_destroy(ivi);

    switch(ii->ii_class) {
    case IR_IC_MOVE:
      legalize_aggregate_move(iu, (ir_instr_move_t *)ii);
      continue;
    case IR_IC_INSERTVAL:
      legalize_aggregate_insertval(iu, (ir_instr_insertval_t *)ii);
      continue;
    case IR_IC_SELECT:
      legalize_aggregate_select(iu, (ir_instr_select_t *)ii);
      continue;
    default:
      break;
    }

    switch(rel) {
    case IVI_OUTPUT:
      // Instructions writing to this value get a multiple return value array
      ii->ii_rets = malloc(sizeof(ir_valuetype_t) * num_values);
      memcpy(ii->ii_rets, values, sizeof(ir_valuetype_t) * num_values);
      ii->ii_ret.value = -num_values;

      for(int i = 0; i < num_values; i++)
        value_bind_instr(value_get(iu, values[i].value), ii, IVI_OUTPUT);
      break;

    case IVI_INPUT:
      // Deal with instructions reading from this value
      // Typically transform operations into moves (which in turn will
      // most likely get eliminated by register coalescing later on)

      switch(ii->ii_class) {
      case IR_IC_EXTRACTVAL:
        {
          ir_instr_extractval_t *iie = (ir_instr_extractval_t *)ii;

          if(iie->num_indicies != 1) {
            parser_error(iu, "Unable to legalize extractval with %d indices",
                         iie->num_indicies);
          }

          ii->ii_class = IR_IC_MOVE;
          ir_valuetype_t v = values[iie->indicies[0]];
          ((ir_instr_move_t *)ii)->value = v;
          value_bind_instr(value_get(iu, v.value), ii, IVI_INPUT);
        }
        break;

      case IR_IC_STORE:
        {
          ir_instr_store_t *st = (ir_instr_store_t *)ii;
          const ir_type_t *aggty = type_get(iu, st->value.type);
          assert(aggty->it_code == IR_TYPE_STRUCT);
          assert(aggty->it_struct.num_elements == num_values);

          st->value = values[0];
          value_bind_instr(value_get(iu, st->value.value), ii, IVI_INPUT);
          for(int i = 1; i < num_values; i++) {
            ir_instr_store_t *st2 = instr_add_after(sizeof(ir_instr_store_t),
                                                    IR_IC_STORE, ii);
            st2->value = values[i];
            value_bind_instr(value_get(iu, st2->value.value), ii, IVI_INPUT);
            st2->ptr = st->ptr;
            st2->immediate_offset = st->immediate_offset + aggty->it_struct.elements[i].offset;
          }
        }
        break;

      case IR_IC_RESUME:
        {
          ir_instr_resume_t *st = (ir_instr_resume_t *)ii;
          st->num_values = num_values;
          assert(num_values < MAX_RESUME_VALUES);
          for(int i = 0; i < num_values; i++) {
            st->values[i] = values[i];
            value_bind_instr(value_get(iu, st->values[i].value), ii, IVI_INPUT);
          }
        }
        break;

      default:
        parser_error(iu, "Unable to legalize aggregate value as input to %s",
                     instr_str(iu, ii, 0));
        break;
      }
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl 0x30(%rax), %eax
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x20(%rbp)
cmpl $0x1, -0x14(%rbp)
jle 0x287e1
jmp 0x28800
leaq 0x170bf(%rip), %rdi     # 0x3f8a7
leaq 0x16bfe(%rip), %rsi     # 0x3f3ed
movl $0xa79, %edx            # imm = 0xA79
leaq 0x170bb(%rip), %rcx     # 0x3f8b6
callq 0x31c0
jmp 0x28802
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0x28c01
movq -0x28(%rbp), %rax
movl 0x30(%rax), %eax
movl %eax, -0x2c(%rbp)
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rdi
callq 0x1cc50
movq -0x38(%rbp), %rax
movl 0x28(%rax), %eax
movl %eax, -0x80(%rbp)
subl $0xe, %eax
je 0x2887a
jmp 0x28848
movl -0x80(%rbp), %eax
subl $0x11, %eax
je 0x2886b
jmp 0x28852
movl -0x80(%rbp), %eax
subl $0x15, %eax
jne 0x2888c
jmp 0x2885c
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x28c10
jmp 0x28802
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x28cf0
jmp 0x28802
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x28e80
jmp 0x28802
jmp 0x2888e
movl -0x2c(%rbp), %eax
movl %eax, -0x84(%rbp)
testl %eax, %eax
je 0x28933
jmp 0x288a1
movl -0x84(%rbp), %eax
subl $0x1, %eax
jne 0x28bfc
jmp 0x288b2
movslq -0x14(%rbp), %rdi
shlq $0x3, %rdi
callq 0x3360
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x20(%rbp), %rsi
movslq -0x14(%rbp), %rdx
shlq $0x3, %rdx
callq 0x3330
xorl %ecx, %ecx
subl -0x14(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, 0x2c(%rax)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x2892e
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
movl (%rax,%rcx,8), %esi
callq 0x20ee0
movq %rax, %rdi
movq -0x38(%rbp), %rsi
movl $0x1, %edx
callq 0x20e00
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x288f6
jmp 0x28bfc
movq -0x38(%rbp), %rax
movl 0x28(%rax), %eax
movl %eax, -0x88(%rbp)
subl $0x5, %eax
je 0x289ee
jmp 0x2894b
movl -0x88(%rbp), %eax
subl $0x10, %eax
je 0x2896c
jmp 0x28958
movl -0x88(%rbp), %eax
subl $0x13, %eax
je 0x28b2b
jmp 0x28bbc
movq -0x38(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpl $0x1, 0x60(%rax)
je 0x289a4
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rax
movl 0x60(%rax), %r8d
leaq 0x16a5c(%rip), %rsi     # 0x3f3ed
movl $0xaa6, %edx            # imm = 0xAA6
leaq 0x16f4c(%rip), %rcx     # 0x3f8e9
movb $0x0, %al
callq 0x18220
movq -0x38(%rbp), %rax
movl $0x15, 0x28(%rax)
movq -0x20(%rbp), %rax
movq -0x48(%rbp), %rcx
movslq 0x64(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x50(%rbp)
movq -0x38(%rbp), %rax
movq -0x50(%rbp), %rcx
movq %rcx, 0x58(%rax)
movq -0x8(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x20ee0
movq %rax, %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
callq 0x20e00
jmp 0x28bfa
movq -0x38(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rax
movl 0x64(%rax), %esi
callq 0x1ee20
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x28a15
jmp 0x28a34
leaq 0x16efb(%rip), %rdi     # 0x3f917
leaq 0x169ca(%rip), %rsi     # 0x3f3ed
movl $0xab4, %edx            # imm = 0xAB4
leaq 0x16e87(%rip), %rcx     # 0x3f8b6
callq 0x31c0
movq -0x60(%rbp), %rax
movl 0x18(%rax), %eax
cmpl -0x14(%rbp), %eax
jne 0x28a42
jmp 0x28a61
leaq 0x16eef(%rip), %rdi     # 0x3f938
leaq 0x1699d(%rip), %rsi     # 0x3f3ed
movl $0xab5, %edx            # imm = 0xAB5
leaq 0x16e5a(%rip), %rcx     # 0x3f8b6
callq 0x31c0
movq -0x58(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rcx
movq %rcx, 0x60(%rax)
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rax
movl 0x60(%rax), %esi
callq 0x20ee0
movq %rax, %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
callq 0x20e00
movl $0x1, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x28b26
movq -0x38(%rbp), %rdx
movl $0x70, %edi
movl $0x5, %esi
callq 0x265e0
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq -0x20(%rbp), %rcx
movslq -0x64(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movq %rcx, 0x60(%rax)
movq -0x8(%rbp), %rdi
movq -0x70(%rbp), %rax
movl 0x60(%rax), %esi
callq 0x20ee0
movq %rax, %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
callq 0x20e00
movq -0x70(%rbp), %rax
movq -0x58(%rbp), %rcx
movq 0x58(%rcx), %rcx
movq %rcx, 0x58(%rax)
movq -0x58(%rbp), %rax
movl 0x68(%rax), %ecx
movq -0x60(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x64(%rbp), %rdx
addl 0x4(%rax,%rdx,8), %ecx
movq -0x70(%rbp), %rax
movl %ecx, 0x68(%rax)
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x28a95
jmp 0x28bfa
movq -0x38(%rbp), %rax
movq %rax, -0x78(%rbp)
movl -0x14(%rbp), %ecx
movq -0x78(%rbp), %rax
movl %ecx, 0x58(%rax)
cmpl $0x8, -0x14(%rbp)
jge 0x28b45
jmp 0x28b64
leaq 0x16e18(%rip), %rdi     # 0x3f964
leaq 0x1689a(%rip), %rsi     # 0x3f3ed
movl $0xac8, %edx            # imm = 0xAC8
leaq 0x16d57(%rip), %rcx     # 0x3f8b6
callq 0x31c0
movl $0x0, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x28bba
movq -0x78(%rbp), %rax
movslq -0x7c(%rbp), %rcx
movq -0x20(%rbp), %rdx
movslq -0x7c(%rbp), %rsi
movq (%rdx,%rsi,8), %rdx
movq %rdx, 0x5c(%rax,%rcx,8)
movq -0x8(%rbp), %rdi
movq -0x78(%rbp), %rax
movslq -0x7c(%rbp), %rcx
movl 0x5c(%rax,%rcx,8), %esi
callq 0x20ee0
movq %rax, %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
callq 0x20e00
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x28b6b
jmp 0x28bfa
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
callq 0x225c0
movq -0x90(%rbp), %rdi
movq %rax, %r8
leaq 0x16806(%rip), %rsi     # 0x3f3ed
movl $0xad2, %edx            # imm = 0xAD2
leaq 0x16d90(%rip), %rcx     # 0x3f983
movb $0x0, %al
callq 0x18220
jmp 0x28bfc
jmp 0x28802
addq $0x90, %rsp
popq %rbp
retq
nopw (%rax,%rax)