// File: /workspace/github_c_makefile_star2_O2/salextpuru[P]speccy-toochain/src/mhmt/mhmt-lz.c
// Function: get_lz_price_hrust
ULONG get_lz_price_hrust(ULONG position, struct lzcode * lzcode)
{
    ULONG varbits,varlen;
    LONG length,disp,tmp;
    length = lzcode->length;
    disp   = lzcode->disp;

    if( disp==0 ) {
        if( length==1 ) {
            return 9; // copy-1-byte

        } else if( (12<=length) && (length<=42) && ( !(length&1) ) ) {
            return 11 + 8*length;

        } else
            goto INVALID_CODE_HRUST;

    } else if( length==(-3) ) { // insertion match!
        if( (-16)<=disp && disp<=(-1) ) {
            return 10+8;

        } else if( (-79)<=disp && disp<(-16) ) {
            return 5+8+8;

        } else
            goto INVALID_CODE_HRUST;

    } else if( length==1 ) {
        if( (-8)<=disp && disp<=(-1) )
            return 6;

        else
            goto INVALID_CODE_HRUST;

    } else if( length==2 ) {
        if( (-32)<=disp && disp<=(-1) ) {
            return 10;

        } else if( (-768)<=disp && disp<(-32) ) {
            return 13;

        } else
            goto INVALID_CODE_HRUST;

    } else if (3<=length && length<=3839 && (-65536)<=disp && disp<=(-1) ) {
        // first, calc influence of length
        if( length<=15 ) { // 3..15
            varlen = 3 + ( (length/3)<<1 );

            if( length==3 )  varlen = 3;

            if( length==15 ) varlen = 11;

        } else if( length<=127 ) { // 16..127
            varlen = 14;

        } else { // 128..3839
            varlen = 14+8;
        }

        // add displacement length
        if( (-32)<=disp ) { // ffe0..ffff
            varlen += 7;

        } else if( (-512)<=disp ) { // fe00..ffdf
            varlen += 10;

        } else { // 0000(-65536)..fdff: -513:-1024, -1025:-2048, -2049:-4096, ... ,-32769:-65536
            // bits:                   12           13           14               18
            varlen += 12;

            if( position>32768 ) {
                varlen += 6; // 8bits

            } else {
                tmp = 1024;

                while( position>(ULONG)tmp ) {
                    varlen++;
                    tmp <<= 1;
                }
            }
        }

        return varlen;

    } else {
INVALID_CODE_HRUST:
        printf("mhmt-lz.c:get_lz_price_hrust(): Found invalid code length=%d, displacement=%d\n",length, disp);
        return 0;
    }
}

// Assembly:
pushq %rbx
movq %rsi, %rax
movl (%rsi), %esi
movl 0x4(%rax), %edx
testl %edx, %edx
je 0x2867
cmpl $0x2, %esi
je 0x2897
cmpl $0x1, %esi
je 0x288e
cmpl $-0x3, %esi
jne 0x28a0
cmpl $-0x11, %edx
jbe 0x28ee
pushq $0x12
jmp 0x28f8
cmpl $0x1, %esi
jne 0x2873
pushq $0x9
jmp 0x28f8
leal -0xc(%rsi), %eax
cmpl $0x1f, %eax
setae %al
movl %esi, %ecx
orb %al, %cl
testb $0x1, %cl
jne 0x28fb
leal 0xb(,%rsi,8), %ebx
jmp 0x290b
cmpl $-0x9, %edx
jbe 0x28fb
pushq $0x6
jmp 0x28f8
cmpl $-0x21, %edx
jbe 0x28dd
pushq $0xa
jmp 0x28f8
leal -0x3(%rsi), %eax
cmpl $0xefd, %eax            # imm = 0xEFD
setae %al
cmpl $0xffff0000, %edx       # imm = 0xFFFF0000
setb %cl
orb %al, %cl
jne 0x28fb
cmpl $0xf, %esi
ja 0x290f
movzbl %sil, %eax
movb $0x3, %cl
divb %cl
addb %al, %al
addb $0x3, %al
movzbl %al, %eax
cmpl $0x3, %esi
cmovel %esi, %eax
cmpl $0xf, %esi
pushq $0xb
popq %rbx
cmovnel %eax, %ebx
jmp 0x291e
leal 0x300(%rdx), %eax
cmpl $0x2e0, %eax            # imm = 0x2E0
jae 0x28fb
pushq $0xd
jmp 0x28f8
leal 0x4f(%rdx), %eax
cmpl $0x3f, %eax
jae 0x28fb
pushq $0x15
popq %rbx
jmp 0x290b
leaq 0x2b27(%rip), %rdi      # 0x5429
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x1040
movl %ebx, %eax
popq %rbx
retq
xorl %eax, %eax
cmpl $0x7f, %esi
seta %al
leal 0xe(,%rax,8), %ebx
cmpl $-0x20, %edx
jb 0x2928
addl $0x7, %ebx
jmp 0x290b
cmpl $0xfffffe00, %edx       # imm = 0xFFFFFE00
jb 0x2935
addl $0xa, %ebx
jmp 0x290b
cmpl $0x8001, %edi           # imm = 0x8001
jb 0x2942
addl $0x12, %ebx
jmp 0x290b
addl $0xc, %ebx
movl $0x400, %eax            # imm = 0x400
cmpl %edi, %eax
jae 0x290b
incl %ebx
addl %eax, %eax
jmp 0x294a