// File: /workspace/github_c_makefile_star2_O3/BernardTatin[P]s7sh/s7.c
// Function: protected_list_copy
static s7_pointer protected_list_copy(s7_scheme *sc, s7_pointer a)
    {
        s7_pointer slow, fast, p;
#if S7_DEBUGGING
#define wrap_return(W) do {fast = W; W = sc->nil; return(check_wrap_return(sc, fast));} while (0)
#else
#define wrap_return(W) do {fast = W; W = sc->nil; return(fast);} while (0)
#endif

        sc->w = cons(sc, car(a), sc->nil);
        p = sc->w;

        slow = fast = cdr(a);
        while (true)
        {
            if (!is_pair(fast))
            {
                if (is_null(fast))
                    wrap_return(sc->w);
                set_cdr(p, fast);
                wrap_return(sc->w);
            }

            set_cdr(p, cons(sc, car(fast), sc->nil));
            p = cdr(p);

            fast = cdr(fast);
            if (!is_pair(fast))
            {
                if (is_null(fast))
                    wrap_return(sc->w);
                set_cdr(p, fast);
                wrap_return(sc->w);
            }
            /* if unrolled further, it's a lot slower? */
            set_cdr(p, cons(sc, car(fast), sc->nil));
            p = cdr(p);

            fast = cdr(fast);
            slow = cdr(slow);
            if (fast == slow)
            {
                /* try to preserve the original cyclic structure */
                s7_pointer p1, f1, p2, f2;
                set_match_pair(a);
                for (p1 = sc->w, f1 = a; !(is_matched_pair(cdr(f1))); f1 = cdr(f1), p1 = cdr(p1))
                    set_match_pair(f1);
                for (p2 = sc->w, f2 = a; cdr(f1) != f2; f2 = cdr(f2), p2 = cdr(p2))
                    clear_match_pair(f2);
                for (f1 = f2; is_pair(f1); f1 = cdr(f1), f2 = cdr(f2))
                {
                    clear_match_pair(f1);
                    f1 = cdr(f1);
                    clear_match_pair(f1);
                    if (f1 == f2) break;
                }
                clear_match_pair(a);
                if (is_null(p1))
                    set_cdr(p2, p2);
                else set_cdr(p1, p2);
                wrap_return(sc->w);
            }
        }
        wrap_return(sc->w);
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r13
movq %rdi, %rbx
movq 0x8(%rsi), %r15
movq 0x90(%rdi), %rax
movq 0x110(%rdi), %r14
cmpq 0x98(%rdi), %rax
ja 0x8f2b5
movq %rbx, %rdi
callq 0xa550
movq 0x90(%rbx), %rax
leaq -0x8(%rax), %rcx
movq %rcx, 0x90(%rbx)
movq -0x8(%rax), %r12
movq $0x200001, (%r12)       # imm = 0x200001
movq %r15, 0x8(%r12)
movq %r14, 0x10(%r12)
movq %r12, 0x4d8(%rbx)
movq %r13, (%rsp)
movq 0x10(%r13), %r13
movq %r13, %r15
cmpb $0x1, (%r13)
jne 0x8f3f6
movq 0x8(%r13), %rdx
movq 0x90(%rbx), %rax
movq 0x110(%rbx), %r14
cmpq 0x98(%rbx), %rax
ja 0x8f323
movq %rbx, %rdi
movq %rdx, %rbp
callq 0xa550
movq %rbp, %rdx
movq 0x90(%rbx), %rax
leaq -0x8(%rax), %rcx
movq %rcx, 0x90(%rbx)
movq -0x8(%rax), %rbp
movq $0x200001, (%rbp)       # imm = 0x200001
movq %rdx, 0x8(%rbp)
movq %r14, 0x10(%rbp)
movq %rbp, 0x10(%r12)
movq 0x10(%r13), %r13
cmpb $0x1, (%r13)
jne 0x8f409
movq 0x8(%r13), %rdx
movq 0x90(%rbx), %rax
movq 0x110(%rbx), %r14
cmpq 0x98(%rbx), %rax
ja 0x8f386
movq %rbx, %rdi
movq %rdx, %r12
callq 0xa550
movq %r12, %rdx
movq 0x90(%rbx), %rax
leaq -0x8(%rax), %rcx
movq %rcx, 0x90(%rbx)
movq -0x8(%rax), %r12
movq $0x200001, (%r12)       # imm = 0x200001
movq %rdx, 0x8(%r12)
movq %r14, 0x10(%r12)
movq %r12, 0x10(%rbp)
movq 0x10(%r13), %r13
movq 0x10(%r15), %r15
cmpq %r15, %r13
jne 0x8f2e8
movq (%rsp), %rdi
orb $-0x80, 0x1(%rdi)
movq 0x4d8(%rbx), %rax
movq 0x10(%rdi), %rsi
cmpw $0x0, (%rsi)
js 0x8f41b
movq %rdi, %rdx
orb $-0x80, 0x1(%rdx)
movq %rsi, %rdx
movq 0x10(%rax), %rax
movq 0x10(%rsi), %rsi
cmpw $0x0, (%rsi)
jns 0x8f3d8
movq 0x4d8(%rbx), %rcx
jmp 0x8f421
movq 0x110(%rbx), %rcx
cmpq %rcx, %r13
je 0x8f481
movq %r13, 0x10(%r12)
jmp 0x8f47a
movq 0x110(%rbx), %rcx
cmpq %rcx, %r13
je 0x8f481
movq %r13, 0x10(%rbp)
jmp 0x8f47a
movq %rax, %rcx
movq %rdi, %rdx
cmpq %rdi, %rsi
je 0x8f43d
movq %rdi, %rsi
andb $0x7f, 0x1(%rsi)
movq 0x10(%rsi), %rsi
movq 0x10(%rcx), %rcx
cmpq %rsi, 0x10(%rdx)
jne 0x8f429
jmp 0x8f440
movq %rdi, %rsi
cmpb $0x1, (%rsi)
jne 0x8f467
movq %rsi, %rdx
andb $0x7f, 0x1(%rdx)
movq 0x10(%rdx), %rdx
andw $0x7fff, (%rdx)         # imm = 0x7FFF
cmpq %rsi, %rdx
je 0x8f467
movq 0x10(%rdx), %rdx
movq 0x10(%rsi), %rsi
cmpb $0x1, (%rdx)
je 0x8f448
andb $0x7f, 0x1(%rdi)
cmpq 0x110(%rbx), %rax
cmoveq %rcx, %rax
movq %rcx, 0x10(%rax)
movq 0x110(%rbx), %rcx
movq 0x4d8(%rbx), %rax
movq %rcx, 0x4d8(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq