// File: /workspace/github_c_makefile_star2_O0/samtools[P]htslib/htscodecs/htscodecs/tokenise_name3.c
// Function: compress
static int compress(uint8_t *in, uint64_t in_len, enum name_type type,
                    int level, int use_arith,
                    uint8_t *out, uint64_t *out_len) {
    uint64_t best_sz = UINT64_MAX;
    uint64_t olen = *out_len;
    int ret = -1;

    // Map levels 1-9 to 0-4, for parameter lookup in R[] below
    level = (level-1)/2;
    if (level<0) level=0;
    if (level>4) level=4;

    // rANS4x16pr and arith_dynamic parameters to explore.
    // We brute force these, so fast levels test 1 setting and slow test more
    int R[5][N_ALL][7] = {
        {   // -1
            /* TYPE     */ {1, 128},
            /* ALPHA    */ {1, 129},
            /* CHAR     */ {1, 0},
            /* DIGITS0  */ {1, 8},
            /* DZLEN    */ {1, 0},
            /* DUP      */ {1, 8},
            /* DIFF     */ {1, 8},
            /* DIGITS   */ {1, 8},
            /* DDELTA   */ {1, 0},
            /* DDELTA0  */ {1, 128},
            /* MATCH    */ {1, 0},
            /* NOP      */ {1, 0},
            /* END      */ {1, 0}
        },

        {   // -3
            /* TYPE     */ {2, 192,0},
            /* ALPHA    */ {2, 129,1},
            /* CHAR     */ {1, 0},
            /* DIGITS0  */ {2, 128+8,0}, // size%4==0
            /* DZLEN    */ {1, 0},
            /* DUP      */ {1, 192+8},   // size%4==0
            /* DIFF     */ {1, 128+8},   // size%4==0
            /* DIGITS   */ {1, 192+8},   // size%4==0
            /* DDELTA   */ {1, 0},
            /* DDELTA0  */ {1, 128},
            /* MATCH    */ {1, 0},
            /* NOP      */ {1, 0},
            /* END      */ {1, 0}
        },

        {   // -5
            /* TYPE     */ {2, 192,0},
            /* ALPHA    */ {4, 1,128,0,129},
            /* CHAR     */ {1, 0},
            /* DIGITS0  */ {2, 200,0},
            /* DZLEN    */ {1, 0},
            /* DUP      */ {1, 200},
            /* DIFF     */ {2, 192,200},
            /* DIGITS   */ {2, 132,201},
            /* DDELTA   */ {1, 0},
            /* DDELTA0  */ {1, 128},
            /* MATCH    */ {1, 0},
            /* NOP      */ {1, 0},
            /* END      */ {1, 0}
        },

        {   // -7
            /* TYPE     */ {3, 193,0,1},
            /* ALPHA    */ {5, 128, 1,128,0,129},
            /* CHAR     */ {2, 1,0},
            /* DIGITS0  */ {2, 200,0},    // or 201,0
            /* DZLEN    */ {1, 0},
            /* DUP      */ {1, 201},
            /* DIFF     */ {2, 192,200},  // or 192,201
            /* DIGITS   */ {2, 132, 201}, // +bz2 here and -9
            /* DDELTA   */ {1, 0},
            /* DDELTA0  */ {1, 128},
            /* MATCH    */ {1, 0},
            /* NOP      */ {1, 0},
            /* END      */ {1, 0}
        },

        {   // -9
            /* TYPE     */ {6, 192,0,1,  65,  193,132},
            /* ALPHA    */ {4, 132, 1, 0,129},
            /* CHAR     */ {3, 1,0,192},
            /* DIGITS0  */ {4, 201,0, 192,64},
            /* DZLEN    */ {3, 0,128,1},
            /* DUP      */ {1, 201},
            /* DIFF     */ {3, 192,  201,65},
            /* DIGITS   */ {6, 132, 201,1,  192,129,  193},
            /* DDELTA   */ {3, 1,0,  192},
            /* DDELTA0  */ {3, 192,1,  0},
            /* MATCH    */ {1, 0},
            /* NOP      */ {1, 0},
            /* END      */ {1, 0}
        },
    };
    // Minor tweak to level 3 DIGITS if arithmetic, to use O(201) instead.
    if (use_arith) R[1][N_DIGITS][1]=201;

    int *meth = R[level][type];

    int last = 0, m;
    uint8_t best_static[8192];
    uint8_t *best_dat = best_static;
    for (m = 1; m <= meth[0]; m++) {
        *out_len = olen;

        if (!use_arith && (meth[m] & 4))
            meth[m] &= ~4;

        if (in_len % 4 != 0 && (meth[m] & 8))
            continue;

        last = 0;
        if (use_arith) {
            if (arith_encode(in, in_len, out, out_len, meth[m]) <0)
                goto err;
        } else {
            if (rans_encode(in, in_len, out, out_len, meth[m]) < 0)
                goto err;
        }

        if (best_sz > *out_len) {
            best_sz = *out_len;
            last = 1;

            if (m+1 > meth[0])
                // no need to memcpy if we're not going to overwrite out
                break;

            if (best_sz > 8192 && best_dat == best_static) {
                // No need to realloc as best_sz only ever decreases
                best_dat = malloc(best_sz);
                if (!best_dat)
                    return -1;
            }
            memcpy(best_dat, out, best_sz);
        }
    }

    if (!last)
        memcpy(out, best_dat, best_sz);
    *out_len = best_sz;
    ret = 0;

 err:
    if (best_dat != best_static)
        free(best_dat);

    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2780, %rsp           # imm = 0x2780
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movq %r9, -0x30(%rbp)
movq $-0x1, -0x38(%rbp)
movq 0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movl $0xffffffff, -0x44(%rbp) # imm = 0xFFFFFFFF
movl -0x20(%rbp), %eax
subl $0x1, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jge 0xca8fd
movl $0x0, -0x20(%rbp)
cmpl $0x4, -0x20(%rbp)
jle 0xca90a
movl $0x4, -0x20(%rbp)
leaq -0x760(%rbp), %rdi
leaq 0x2c2b8(%rip), %rsi     # 0xf6bd0
movl $0x71c, %edx            # imm = 0x71C
callq 0x43b0
cmpl $0x0, -0x24(%rbp)
je 0xca932
movl $0xc9, -0x52c(%rbp)
movslq -0x20(%rbp), %rcx
leaq -0x760(%rbp), %rax
imulq $0x16c, %rcx, %rcx      # imm = 0x16C
addq %rcx, %rax
movslq -0x1c(%rbp), %rcx
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x768(%rbp)
movl $0x0, -0x76c(%rbp)
leaq -0x2770(%rbp), %rax
movq %rax, -0x2778(%rbp)
movl $0x1, -0x770(%rbp)
movl -0x770(%rbp), %eax
movq -0x768(%rbp), %rcx
cmpl (%rcx), %eax
jg 0xcab1e
movq -0x40(%rbp), %rcx
movq 0x10(%rbp), %rax
movq %rcx, (%rax)
cmpl $0x0, -0x24(%rbp)
jne 0xca9d1
movq -0x768(%rbp), %rax
movslq -0x770(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0xca9d1
movq -0x768(%rbp), %rax
movslq -0x770(%rbp), %rcx
movl (%rax,%rcx,4), %edx
andl $-0x5, %edx
movl %edx, (%rax,%rcx,4)
movq -0x18(%rbp), %rax
andq $0x3, %rax
cmpq $0x0, %rax
je 0xca9fd
movq -0x768(%rbp), %rax
movslq -0x770(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0xca9fd
jmp 0xcab0a
movl $0x0, -0x76c(%rbp)
cmpl $0x0, -0x24(%rbp)
je 0xcaa40
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq 0x10(%rbp), %rcx
movq -0x768(%rbp), %rax
movslq -0x770(%rbp), %r8
movl (%rax,%r8,4), %r8d
callq 0xcd4e0
cmpl $0x0, %eax
jge 0xcaa3e
jmp 0xcab4d
jmp 0xcaa73
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq 0x10(%rbp), %rcx
movq -0x768(%rbp), %rax
movslq -0x770(%rbp), %r8
movl (%rax,%r8,4), %r8d
callq 0xcd590
cmpl $0x0, %eax
jge 0xcaa71
jmp 0xcab4d
jmp 0xcaa73
movq -0x38(%rbp), %rax
movq 0x10(%rbp), %rcx
cmpq (%rcx), %rax
jbe 0xcab08
movq 0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movl $0x1, -0x76c(%rbp)
movl -0x770(%rbp), %eax
addl $0x1, %eax
movq -0x768(%rbp), %rcx
cmpl (%rcx), %eax
jle 0xcaaaf
jmp 0xcab1e
cmpq $0x2000, -0x38(%rbp)    # imm = 0x2000
jbe 0xcaaf4
movq -0x2778(%rbp), %rax
leaq -0x2770(%rbp), %rcx
cmpq %rcx, %rax
jne 0xcaaf4
movq -0x38(%rbp), %rdi
callq 0x4650
movq %rax, -0x2778(%rbp)
cmpq $0x0, -0x2778(%rbp)
jne 0xcaaf2
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xcab72
jmp 0xcaaf4
movq -0x2778(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x43b0
jmp 0xcab0a
movl -0x770(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x770(%rbp)
jmp 0xca97b
cmpl $0x0, -0x76c(%rbp)
jne 0xcab3b
movq -0x30(%rbp), %rdi
movq -0x2778(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x43b0
movq -0x38(%rbp), %rcx
movq 0x10(%rbp), %rax
movq %rcx, (%rax)
movl $0x0, -0x44(%rbp)
movq -0x2778(%rbp), %rax
leaq -0x2770(%rbp), %rcx
cmpq %rcx, %rax
je 0xcab6c
movq -0x2778(%rbp), %rdi
callq 0x45a0
movl -0x44(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x2780, %rsp           # imm = 0x2780
popq %rbp
retq
nop