// File: /workspace/github_c_makefile_star2_O3/RodionGork[P]tinyscheme/scheme.c
// Function: gc
static void gc(scheme * sc, pointer a, pointer b) {
  pointer p;
  int i;

  if (sc->gc_verbose) {
    putstr(sc, "gc...");
  }

  /* mark system globals */
  mark(sc->oblist);
  mark(sc->global_env);

  /* mark current registers */
  mark(sc->args);
  mark(sc->envir);
  mark(sc->code);
  dump_stack_mark(sc);
  mark(sc->value);
  mark(sc->inport);
  mark(sc->save_inport);
  mark(sc->outport);
  mark(sc->loadport);

  /* Mark recent objects the interpreter doesn't know about yet. */
  mark(car(sc->sink));
  /* Mark any older stuff above nested C calls */
  mark(sc->c_nest);

  /* mark variables a, b */
  mark(a);
  mark(b);

  /* garbage collect */
  clrmark(sc->NIL);
  sc->fcells = 0;
  sc->free_cell = sc->NIL;
  /* free-list is kept sorted by address so as to maintain consecutive
     ranges, if possible, for use with vectors. Here we scan the cells
     (which are also kept sorted by address) downwards to build the
     free-list in sorted order.
   */
  for (i = sc->last_cell_seg; i >= 0; i--) {
    p = sc->cell_seg[i] + cell_segsize;
    while (--p >= sc->cell_seg[i]) {
      if (is_mark(p)) {
        clrmark(p);
      } else {
        /* reclaim cell */
        if (typeflag(p) != 0) {
          finalize_cell(sc, p);
          typeflag(p) = 0;
          car(p) = sc->NIL;
        }
        ++sc->fcells;
        cdr(p) = sc->free_cell;
        sc->free_cell = p;
      }
    }
  }

  if (sc->gc_verbose) {
    char msg[80];
    sprintf(msg, "done: %ld cells were recovered.\n", sc->fcells);
    putstr(sc, msg);
  }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x50, %rsp
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
cmpb $0x0, 0xa98(%rdi)
je 0x5795
leaq 0x8b2a(%rip), %rsi      # 0xe2b7
movq %rbx, %rdi
callq 0x4b32
movq 0xf8(%rbx), %rdi
callq 0xc914
movq 0x100(%rbx), %rdi
callq 0xc914
movq 0x30(%rbx), %rdi
callq 0xc914
movq 0x38(%rbx), %rdi
callq 0xc914
movq 0x40(%rbx), %rdi
callq 0xc914
movq 0x48(%rbx), %rdi
callq 0xc914
movq 0xec0(%rbx), %rdi
callq 0xc914
movq 0x170(%rbx), %rdi
callq 0xc914
movq 0x180(%rbx), %rdi
callq 0xc914
movq 0x178(%rbx), %rdi
callq 0xc914
movq 0x188(%rbx), %rdi
callq 0xc914
movq 0x70(%rbx), %rax
movq 0x8(%rax), %rdi
callq 0xc914
movq 0x108(%rbx), %rdi
callq 0xc914
movq %r15, %rdi
callq 0xc914
movq %r14, %rdi
callq 0xc914
movq 0x90(%rbx), %rax
andl $0x7fff, (%rax)         # imm = 0x7FFF
movq $0x0, 0x168(%rbx)
movq %rax, 0x160(%rbx)
movslq 0x28(%rbx), %r14
testq %r14, %r14
js 0x5926
movq 0x20(%rbx), %rcx
movq (%rcx,%r14,8), %rdx
movslq 0xd92b(%rip), %rsi      # 0x1319c
leaq (%rsi,%rsi,2), %rsi
leaq (%rdx,%rsi,8), %r15
addq $-0x18, %r15
cmpq %rdx, %r15
jb 0x5916
movl (%r15), %edx
testw %dx, %dx
js 0x58a5
testl %edx, %edx
je 0x58ef
andl $0x1f, %edx
cmpl $0xa, %edx
je 0x58b0
cmpl $0x1, %edx
jne 0x58d6
movq 0x8(%r15), %rdi
jmp 0x58d3
andl $0x7fff, %edx           # imm = 0x7FFF
movl %edx, (%r15)
jmp 0x5908
movq 0x8(%r15), %rsi
testb $0x1, (%rsi)
je 0x58d0
cmpl $0x0, 0x10(%rsi)
je 0x58d0
movq %rbx, %rdi
movl $0x30, %edx
callq 0xb407
movq 0x8(%r15), %rsi
movq %rsi, %rdi
callq *0x8(%rbx)
movl $0x0, (%r15)
movq 0x90(%rbx), %rax
movq %rax, 0x8(%r15)
movq 0x160(%rbx), %rax
incq 0x168(%rbx)
movq %rax, 0x10(%r15)
movq %r15, 0x160(%rbx)
movq 0x20(%rbx), %rcx
movq %r15, %rax
addq $-0x18, %r15
cmpq (%rcx,%r14,8), %r15
jae 0x5886
leaq -0x1(%r14), %rdx
testq %r14, %r14
movq %rdx, %r14
jg 0x5866
cmpb $0x0, 0xa98(%rbx)
je 0x5955
movq 0x168(%rbx), %rdx
leaq 0x8980(%rip), %rsi      # 0xe2bd
movq %rsp, %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x4290
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4b32
addq $0x50, %rsp
popq %rbx
popq %r14
popq %r15
retq