// File: /workspace/github_c_makefile_star2_O0/deplinenoise[P]vlink/t_amigahunk.c
// Function: reloc_hunk
static void reloc_hunk(struct GlobalVars *gv,FILE *f,
                       struct LinkedSection *sec,uint32_t relhunk,
                       uint8_t rtype,uint16_t rsize)
/* generate an AmigaDOS/EHF relocation hunk for a specific reloc type */
{
  struct Reloc *nextrel,*rel=(struct Reloc *)sec->relocs.first;
  struct list **rlist=alloc(gv->nsecs*sizeof(struct list *));
  int *rcnt=alloczero(gv->nsecs*sizeof(int)); /* reloc cnt for all sect. */
  bool hunk_required=FALSE,small_offsets=TRUE;
  lword chkmask,rmask=makemask(rsize);
  uint16_t rpos=0;
  int i;

  for (i=0; i<gv->nsecs; i++) {  /* empty reloc lists for each section */
    rlist[i] = alloc(sizeof(struct list));
    initlist(rlist[i]);
  }

  /* EHF-PowerPC relocations need special treatment */
  if (rsize == 24) {
    rpos = 6;
    rmask = 0x3ffffff;
    chkmask = 0x3fffffc;
  }
  else if (rsize == 14) {
    rpos = 16;
    rmask = 0xffff;
    chkmask = 0xfffc;
  }
  else
    chkmask = rmask;

  while (nextrel = (struct Reloc *)rel->n.next) {
    struct RelocInsert *ri;
    int newrcnt;

    if (rel->rtype==rtype && (ri=rel->insert)!=NULL) {
      if (ri->bpos==rpos && ri->bsiz==rsize && (ri->mask&rmask)==chkmask) {
        /* move reloc node of correct type into relocssect's rlist */
        remnode(&rel->n);
        addtail(rlist[rel->relocsect.lnk->index],&rel->n);
        newrcnt = ++rcnt[rel->relocsect.lnk->index];
        rel->offset += rpos >> 3;
        if (gv->reloctab_format == RTAB_SHORTOFF) {
          if (rel->offset>=0x10000 || newrcnt>=0x10000)
            small_offsets = FALSE; /* no short-reloc hunk would be possible */
        }
        hunk_required = TRUE;
      }
    }
    rel = nextrel;
  }

  if (hunk_required) {  /* there's at least one relocation */

    if (relhunk==HUNK_ABSRELOC32 &&
        gv->reloctab_format==RTAB_SHORTOFF && small_offsets) {
      /* Make a short hunk with 16-bit offsets.
         For executables, HUNK_DREL32 is used instead of the correct
         HUNK_RELOC32SHORT to be compatible with OS2.0 */
      int cnt=0;

      if (gv->dest_object)
        fwrite32be(f,HUNK_RELOC32SHORT);
      else
        fwrite32be(f,HUNK_DREL32);
      for (i=0; i<gv->nsecs; i++) {
        if (rcnt[i]) {
          fwrite16be(f,(uint16_t)rcnt[i]);  /* number of relocations */
          fwrite16be(f,(uint16_t)i);  /* section index */
          cnt += 2;

          /* store relocation offsets */
          while(rel = (struct Reloc *)remhead(rlist[i])) {
            fwrite16be(f,(uint16_t)rel->offset);
            cnt++;
          }
        }
      }
      /* no more relocation entries */
      if (cnt & 1)  /* 0-word for 32-bit alignment */
        fwrite16be(f,0);
      else
        fwrite32be(f,0);
    }

    else {
      /* all other relocation hunks */
      fwrite32be(f,relhunk);  /* reloc hunk id */
      for (i=0; i<gv->nsecs; i++) {
        while (rcnt[i]) {
          /* never write more than 65536 relocs at once - there is a bug */
          /* in dos.library which rejects the executable file otherwise */
          int n = (rcnt[i]>0x10000) ? 0x10000 : rcnt[i];

          fwrite32be(f,(uint32_t)n);  /* number of relocations */
          fwrite32be(f,(uint32_t)i);  /* section index */
          rcnt[i] -= n;

          /* store relocation offsets */
          while (n--) {
            if (rel = (struct Reloc *)remhead(rlist[i])) {
              fwrite32be(f,(uint32_t)rel->offset);
            }
          }
        }
      }
      fwrite32be(f,0);  /* no more relocation entries */
    }
  }

  /* free dynamically allocated rlists and rcnt array */
  for (i=0; i<gv->nsecs; free(rlist[i++]));
  free(rcnt);
}

// Assembly:
subq $0x98, %rsp
movl %r8d, 0x8(%rsp)
movl %ecx, %eax
movl 0x8(%rsp), %ecx
movl %eax, 0xc(%rsp)
movq %rdx, %rax
movl 0xc(%rsp), %edx
movq %rax, 0x10(%rsp)
movq %rsi, %rax
movq 0x10(%rsp), %rsi
movq %rax, 0x18(%rsp)
movq %rdi, %r8
movq 0x18(%rsp), %rdi
movw %r9w, %ax
movq %r8, 0x90(%rsp)
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
movl %edx, 0x7c(%rsp)
movb %cl, 0x7b(%rsp)
movw %ax, 0x78(%rsp)
movq 0x80(%rsp), %rax
movq 0x80(%rax), %rax
movq %rax, 0x68(%rsp)
movq 0x90(%rsp), %rax
movslq 0x1d8(%rax), %rdi
shlq $0x3, %rdi
callq 0x71f0
movq %rax, 0x60(%rsp)
movq 0x90(%rsp), %rax
movslq 0x1d8(%rax), %rdi
shlq $0x2, %rdi
callq 0x7290
movq %rax, 0x58(%rsp)
movl $0x0, 0x54(%rsp)
movl $0x1, 0x50(%rsp)
movzwl 0x78(%rsp), %eax
movl %eax, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
subq $0x1, %rax
movq %rax, 0x40(%rsp)
movw $0x0, 0x3e(%rsp)
movl $0x0, 0x38(%rsp)
movl 0x38(%rsp), %eax
movq 0x90(%rsp), %rcx
cmpl 0x1d8(%rcx), %eax
jge 0x1e0a6
movl $0x18, %edi
callq 0x71f0
movq %rax, %rdx
movq 0x60(%rsp), %rax
movslq 0x38(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movq 0x60(%rsp), %rax
movslq 0x38(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x7330
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x1e057
movzwl 0x78(%rsp), %eax
cmpl $0x18, %eax
jne 0x1e0cb
movw $0x6, 0x3e(%rsp)
movq $0x3ffffff, 0x40(%rsp)  # imm = 0x3FFFFFF
movq $0x3fffffc, 0x48(%rsp)  # imm = 0x3FFFFFC
jmp 0x1e0fc
movzwl 0x78(%rsp), %eax
cmpl $0xe, %eax
jne 0x1e0f0
movw $0x10, 0x3e(%rsp)
movq $0xffff, 0x40(%rsp)     # imm = 0xFFFF
movq $0xfffc, 0x48(%rsp)     # imm = 0xFFFC
jmp 0x1e0fa
movq 0x40(%rsp), %rax
movq %rax, 0x48(%rsp)
jmp 0x1e0fc
jmp 0x1e0fe
movq 0x68(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x70(%rsp)
cmpq $0x0, %rax
je 0x1e236
movq 0x68(%rsp), %rax
movzbl 0x38(%rax), %eax
movzbl 0x7b(%rsp), %ecx
cmpl %ecx, %eax
jne 0x1e227
movq 0x68(%rsp), %rax
movq 0x30(%rax), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
je 0x1e227
movq 0x30(%rsp), %rax
movzwl 0x8(%rax), %eax
movzwl 0x3e(%rsp), %ecx
cmpl %ecx, %eax
jne 0x1e225
movq 0x30(%rsp), %rax
movzwl 0xa(%rax), %eax
movzwl 0x78(%rsp), %ecx
cmpl %ecx, %eax
jne 0x1e225
movq 0x30(%rsp), %rax
movq 0x10(%rax), %rax
andq 0x40(%rsp), %rax
cmpq 0x48(%rsp), %rax
jne 0x1e225
movq 0x68(%rsp), %rdi
callq 0x7530
movq 0x60(%rsp), %rax
movq 0x68(%rsp), %rcx
movq 0x18(%rcx), %rcx
movslq 0x10(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
movq 0x68(%rsp), %rsi
callq 0x7470
movq 0x58(%rsp), %rcx
movq 0x68(%rsp), %rax
movq 0x18(%rax), %rax
movslq 0x10(%rax), %rdx
movl (%rcx,%rdx,4), %eax
addl $0x1, %eax
movl %eax, (%rcx,%rdx,4)
movl %eax, 0x2c(%rsp)
movzwl 0x3e(%rsp), %eax
sarl $0x3, %eax
movslq %eax, %rcx
movq 0x68(%rsp), %rax
addq 0x20(%rax), %rcx
movq %rcx, 0x20(%rax)
movq 0x90(%rsp), %rax
movzbl 0x6e(%rax), %eax
cmpl $0x4, %eax
jne 0x1e21d
movq 0x68(%rsp), %rax
cmpq $0x10000, 0x20(%rax)    # imm = 0x10000
jae 0x1e213
cmpl $0x10000, 0x2c(%rsp)    # imm = 0x10000
jl 0x1e21b
movl $0x0, 0x50(%rsp)
jmp 0x1e21d
movl $0x1, 0x54(%rsp)
jmp 0x1e227
movq 0x70(%rsp), %rax
movq %rax, 0x68(%rsp)
jmp 0x1e0fe
cmpl $0x0, 0x54(%rsp)
je 0x1e4cc
cmpl $0x3ec, 0x7c(%rsp)      # imm = 0x3EC
jne 0x1e3a4
movq 0x90(%rsp), %rax
movzbl 0x6e(%rax), %eax
cmpl $0x4, %eax
jne 0x1e3a4
cmpl $0x0, 0x50(%rsp)
je 0x1e3a4
movl $0x0, 0x28(%rsp)
movq 0x90(%rsp), %rax
cmpl $0x0, 0x54(%rax)
je 0x1e299
movq 0x88(%rsp), %rdi
movl $0x3fc, %esi            # imm = 0x3FC
callq 0x84d0
jmp 0x1e2ab
movq 0x88(%rsp), %rdi
movl $0x3f7, %esi            # imm = 0x3F7
callq 0x84d0
movl $0x0, 0x38(%rsp)
movl 0x38(%rsp), %eax
movq 0x90(%rsp), %rcx
cmpl 0x1d8(%rcx), %eax
jge 0x1e373
movq 0x58(%rsp), %rax
movslq 0x38(%rsp), %rcx
cmpl $0x0, (%rax,%rcx,4)
je 0x1e361
movq 0x88(%rsp), %rdi
movq 0x58(%rsp), %rax
movslq 0x38(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movzwl %ax, %esi
callq 0x8560
movq 0x88(%rsp), %rdi
movl 0x38(%rsp), %eax
movzwl %ax, %esi
callq 0x8560
movl 0x28(%rsp), %eax
addl $0x2, %eax
movl %eax, 0x28(%rsp)
movq 0x60(%rsp), %rax
movslq 0x38(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x74d0
movq %rax, 0x68(%rsp)
cmpq $0x0, %rax
je 0x1e35f
movq 0x88(%rsp), %rdi
movq 0x68(%rsp), %rax
movq 0x20(%rax), %rax
movzwl %ax, %esi
callq 0x8560
movl 0x28(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x28(%rsp)
jmp 0x1e31b
jmp 0x1e361
jmp 0x1e363
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x1e2b3
movl 0x28(%rsp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x1e390
movq 0x88(%rsp), %rdi
xorl %esi, %esi
callq 0x8560
jmp 0x1e39f
movq 0x88(%rsp), %rdi
xorl %esi, %esi
callq 0x84d0
jmp 0x1e4ca
movq 0x88(%rsp), %rdi
movl 0x7c(%rsp), %esi
callq 0x84d0
movl $0x0, 0x38(%rsp)
movl 0x38(%rsp), %eax
movq 0x90(%rsp), %rcx
cmpl 0x1d8(%rcx), %eax
jge 0x1e4bb
jmp 0x1e3d7
movq 0x58(%rsp), %rax
movslq 0x38(%rsp), %rcx
cmpl $0x0, (%rax,%rcx,4)
je 0x1e4a9
movq 0x58(%rsp), %rax
movslq 0x38(%rsp), %rcx
cmpl $0x10000, (%rax,%rcx,4) # imm = 0x10000
jle 0x1e409
movl $0x10000, %eax          # imm = 0x10000
movl %eax, 0x4(%rsp)
jmp 0x1e41a
movq 0x58(%rsp), %rax
movslq 0x38(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x4(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x24(%rsp)
movq 0x88(%rsp), %rdi
movl 0x24(%rsp), %esi
callq 0x84d0
movq 0x88(%rsp), %rdi
movl 0x38(%rsp), %esi
callq 0x84d0
movl 0x24(%rsp), %esi
movq 0x58(%rsp), %rax
movslq 0x38(%rsp), %rcx
movl (%rax,%rcx,4), %edx
subl %esi, %edx
movl %edx, (%rax,%rcx,4)
movl 0x24(%rsp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, 0x24(%rsp)
cmpl $0x0, %eax
je 0x1e4a4
movq 0x60(%rsp), %rax
movslq 0x38(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x74d0
movq %rax, 0x68(%rsp)
cmpq $0x0, %rax
je 0x1e4a2
movq 0x88(%rsp), %rdi
movq 0x68(%rsp), %rax
movq 0x20(%rax), %rax
movl %eax, %esi
callq 0x84d0
jmp 0x1e45a
jmp 0x1e3d7
jmp 0x1e4ab
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x1e3bd
movq 0x88(%rsp), %rdi
xorl %esi, %esi
callq 0x84d0
jmp 0x1e4cc
movl $0x0, 0x38(%rsp)
movl 0x38(%rsp), %eax
movq 0x90(%rsp), %rcx
cmpl 0x1d8(%rcx), %eax
jge 0x1e50a
jmp 0x1e4ea
movq 0x60(%rsp), %rax
movl 0x38(%rsp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, 0x38(%rsp)
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
callq 0x5030
jmp 0x1e4d4
movq 0x58(%rsp), %rdi
callq 0x5030
addq $0x98, %rsp
retq
nopl (%rax)