// File: /workspace/github_c_makefile_star2_O0/samtools[P]htslib/cram/cram_codecs.c
// Function: cram_xdelta_encode_flush
int cram_xdelta_encode_flush(cram_codec *c) {
    int r = -1;
    cram_block *b = cram_new_block(0, 0);
    if (!b)
        return -1;

    switch (c->u.e_xdelta.word_size) {
    case 2: {
        // Delta + zigzag transform.
        // Subtracting two 8-bit values has a 9-bit result (-255 to 255).
        // However think of it as turning a wheel clockwise or anti-clockwise.
        // If it has 256 gradations then a -ve rotation followed by a +ve
        // rotation of the same amount reverses it regardless.
        //
        // Similarly the zig-zag transformation doesn't invent any extra bits,
        // so the entire thing can be done in-situ.  This may permit faster
        // SIMD loops if we break apart the steps.

        // uint16_t last = 0, d;
        // for (i = 0; i < n; i++) {
        //     d = io[i] - last;
        //     last = io[i];
        //     io[i] = zigzag16(vd);
        // }

        // --- vs ---

        // for (i = n-1; i >= 1; i--)
        //     io[i] -= io[i-1];
        // for (i = 0; i < n; i++)
        //     io[i] = zigzag16(io[i]);

        // varint: need array variant for speed here.
        // With zig-zag
        int i, n = BLOCK_SIZE(c->out)/2;;
        uint16_t *dat = (uint16_t *)BLOCK_DATA(c->out), last = 0;

        if (n*2 < BLOCK_SIZE(c->out)) {
            // half word
            last = *(uint8_t *)dat;
            c->vv->varint_put32_blk(b, zigzag16(last));
            dat = (uint16_t *)(((uint8_t *)dat)+1);
        }

        for (i = 0; i < n; i++) {
            uint16_t d = dat[i] - last; // possibly unaligned
            last = dat[i];
            c->vv->varint_put32_blk(b, zigzag16(d));
        }

        break;
    }

    case 4: {
        int i, n = BLOCK_SIZE(c->out)/4;;
        uint32_t *dat = (uint32_t *)BLOCK_DATA(c->out), last = 0;

        for (i = 0; i < n; i++) {
            uint32_t d = dat[i] - last;
            last = dat[i];
            c->vv->varint_put32_blk(b, zigzag32(d));
        }

        break;
    }

    case 1: {
        int i, n = BLOCK_SIZE(c->out);;
        uint8_t *dat = (uint8_t *)BLOCK_DATA(c->out), last = 0;

        for (i = 0; i < n; i++) {
            uint32_t d = dat[i] - last;
            last = dat[i];
            c->vv->varint_put32_blk(b, zigzag8(d));
        }

        break;
    }

    default:
        goto err;
    }

    if (c->u.e_xdelta.sub_codec->encode(NULL, c->u.e_xdelta.sub_codec,
                                      (char *)b->data, b->byte))
        goto err;

    r = 0;

 err:
    cram_free_block(b);
    return r;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x10(%rbp)
movl $0xffffffff, -0x14(%rbp) # imm = 0xFFFFFFFF
xorl %esi, %esi
movl %esi, %edi
callq 0x6ede0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0xe6226
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xe64e5
movq -0x10(%rbp), %rax
movzbl 0x68(%rax), %eax
movl %eax, -0x6c(%rbp)
subl $0x1, %eax
je 0xe63fe
jmp 0xe623c
movl -0x6c(%rbp), %eax
subl $0x2, %eax
je 0xe6257
jmp 0xe6246
movl -0x6c(%rbp), %eax
subl $0x4, %eax
je 0xe635e
jmp 0xe649e
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x30(%rax), %rax
shrq %rax
movl %eax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
movq %rax, -0x30(%rbp)
movw $0x0, -0x32(%rbp)
movl -0x28(%rbp), %eax
shll %eax
cltq
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rcx
cmpq 0x30(%rcx), %rax
jae 0xe62dc
movq -0x30(%rbp), %rax
movzbl (%rax), %eax
movw %ax, -0x32(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x58(%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x80(%rbp)
movswl -0x32(%rbp), %edi
callq 0xe6500
movq -0x80(%rbp), %rdi
movw %ax, %cx
movq -0x78(%rbp), %rax
movzwl %cx, %esi
callq *%rax
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x28(%rbp), %eax
jge 0xe6359
movq -0x30(%rbp), %rax
movslq -0x24(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
movzwl -0x32(%rbp), %ecx
subl %ecx, %eax
movw %ax, -0x34(%rbp)
movq -0x30(%rbp), %rax
movslq -0x24(%rbp), %rcx
movw (%rax,%rcx,2), %ax
movw %ax, -0x32(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x58(%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x90(%rbp)
movswl -0x34(%rbp), %edi
callq 0xe6500
movq -0x90(%rbp), %rdi
movw %ax, %cx
movq -0x88(%rbp), %rax
movzwl %cx, %esi
callq *%rax
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0xe62e3
jmp 0xe64a0
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x30(%rax), %rax
shrq $0x2, %rax
movl %eax, -0x3c(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
movq %rax, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0xe63f9
movq -0x48(%rbp), %rax
movslq -0x38(%rbp), %rcx
movl (%rax,%rcx,4), %eax
subl -0x4c(%rbp), %eax
movl %eax, -0x50(%rbp)
movq -0x48(%rbp), %rax
movslq -0x38(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x4c(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x58(%rax), %rax
movq %rax, -0x98(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0xa0(%rbp)
movl -0x50(%rbp), %edi
callq 0xe6520
movq -0xa0(%rbp), %rdi
movl %eax, %esi
movq -0x98(%rbp), %rax
callq *%rax
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0xe638f
jmp 0xe64a0
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x30(%rax), %rax
movl %eax, -0x58(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
movq %rax, -0x60(%rbp)
movb $0x0, -0x61(%rbp)
movl $0x0, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x58(%rbp), %eax
jge 0xe649c
movq -0x60(%rbp), %rax
movslq -0x54(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movzbl -0x61(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x68(%rbp)
movq -0x60(%rbp), %rax
movslq -0x54(%rbp), %rcx
movb (%rax,%rcx), %al
movb %al, -0x61(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x58(%rax), %rax
movq %rax, -0xa8(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0xb0(%rbp)
movl -0x68(%rbp), %eax
movsbl %al, %edi
callq 0xe6540
movq -0xb0(%rbp), %rdi
movb %al, %cl
movq -0xa8(%rbp), %rax
movzbl %cl, %esi
callq *%rax
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0xe6428
jmp 0xe64a0
jmp 0xe64d6
movq -0x10(%rbp), %rax
movq 0x78(%rax), %rax
movq 0x30(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x78(%rcx), %rsi
movq -0x20(%rbp), %rcx
movq 0x20(%rcx), %rdx
movq -0x20(%rbp), %rcx
movq 0x30(%rcx), %rcx
xorl %edi, %edi
callq *%rax
cmpl $0x0, %eax
je 0xe64cf
jmp 0xe64d6
movl $0x0, -0x14(%rbp)
movq -0x20(%rbp), %rdi
callq 0x6f940
movl -0x14(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)