// File: /workspace/github_c_makefile_star2_O0/salextpuru[P]speccy-toochain/src/mhmt/mhmt-emit.c
// Function: emit_megalz
ULONG emit_megalz(struct optchain * optch, ULONG actual_len)
{
    ULONG position;
    LONG length;
    LONG disp;
    LONG max_disp; // maximum encountered displacement
    ULONG varbits,varlen;
    ULONG success = 1;
    max_disp = 0;

    // some checks
    if( !optch ) {
        printf("mhmt-emit.c:emit_megalz() - NULL passed!\n");
        return 0;
    }

    // initialize
    success = success && emit_file(NULL, EMIT_FILE_INIT);
    success = success && emit_byte(0, EMIT_BYTE_INIT);
    success = success && emit_bits(0, EMIT_BITS_INIT);
    // copy first byte as-is
    success = success && emit_file( wrk.indata, 1);
    // go emitting codes
    position = 1;

    while( (position<actual_len) && success ) {
        length = optch[position].code.length;
        disp   = optch[position].code.disp;

        if( length==0 ) {
            printf("mhmt-emit.c:emit_megalz() - encountered stop-code in optimal chain before emitting all data!\n");
            return 0;

        } else if( length==1 ) { // either copy-byte or len=1 code
            if( disp==0 ) { // copy-byte (%1<byte>)
                success = success && emit_bits( 0x80000000, 1 );
                success = success && emit_byte( wrk.indata[position], EMIT_BYTE_ADD );

            } else if( (-8)<=disp && disp<=(-1) ) { // len=1, disp=-1..-8 (%000abc)
                success = success && emit_bits( 0x00000000,   3 );
                success = success && emit_bits( disp<<(32-3), 3 );

                if( max_disp > disp ) max_disp = disp;

            } else
                goto INVALID_CODE_MEGALZ;

        } else if( length==2 ) {
            if( (-256)<=disp && disp<=(-1) ) { // %001<byte>
                success = success && emit_bits( 0x20000000, 3 );
                success = success && emit_byte( (UBYTE)(0x00FF & disp), EMIT_BYTE_ADD );

                if( max_disp > disp ) max_disp = disp;

            } else
                goto INVALID_CODE_MEGALZ;

        } else if( 3<=length && length<=255 ) {
            // length coding
            if( length==3 ) { // %010
                success = success && emit_bits( 0x40000000, 3 );

            } else { // length==4..255, %011
                success = success && emit_bits( 0x60000000, 3 );
                // calculate size of variable bits
                varlen = 0;
                varbits = (length-2)>>1;

                while( varbits ) {
                    varbits >>= 1;
                    varlen++;
                }

                varbits = length-2-(1<<varlen); // prepare length coding
                success = success && emit_bits(       1<<(32-varlen), varlen );
                success = success && emit_bits( varbits<<(32-varlen), varlen );
            }

            // displacement coding
            if( (-256)<=disp && disp<=(-1) ) {
                success = success && emit_bits( 0, 1 );
                success = success && emit_byte( (UBYTE)(0x00ff & disp), EMIT_BYTE_ADD );

                if( max_disp > disp ) max_disp = disp;

            } else if( (-4352)<=disp && disp<(-256) ) {
                success = success && emit_bits( 0x80000000, 1 );
                success = success && emit_bits( (0x0F00&(disp+0x0100))<<20, 4 );
                success = success && emit_byte( (UBYTE)(0x00FF & disp), EMIT_BYTE_ADD );

                if( max_disp > disp ) max_disp = disp;

            } else
                goto INVALID_CODE_MEGALZ;

        } else {
INVALID_CODE_MEGALZ:
            printf("mhmt-emit.c:emit_megalz() - invalid code: length=%d, displacement=%d\n",length,disp);
            return 0;
        }

        position += length;
    }

    // stop-code
    success = success && emit_bits( 0x60100000, 12 );
    success = success && emit_bits( 0, EMIT_BITS_FINISH ); // this also flushes emit_byte()
    success = success && emit_file( NULL, EMIT_FILE_FINISH );

    if( success )
        printf("Maximum displacement actually used is %d.\n",-max_disp);

    return success;
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x38(%rsp)
movl %esi, 0x34(%rsp)
movl $0x1, 0x18(%rsp)
movl $0x0, 0x24(%rsp)
cmpq $0x0, 0x38(%rsp)
jne 0x1260
leaq 0x7db8(%rip), %rdi      # 0x9004
movb $0x0, %al
callq 0x1040
movl $0x0, 0x44(%rsp)
jmp 0x1941
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x17(%rsp)
je 0x1285
xorl %eax, %eax
movl %eax, %edi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x1950
cmpl $0x0, %eax
setne %al
movb %al, 0x17(%rsp)
movb 0x17(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x16(%rsp)
je 0x12b2
xorl %esi, %esi
movl %esi, %edi
callq 0x1b30
cmpl $0x0, %eax
setne %al
movb %al, 0x16(%rsp)
movb 0x16(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x15(%rsp)
je 0x12e2
xorl %edi, %edi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0x15(%rsp)
movb 0x15(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x14(%rsp)
je 0x131b
leaq 0xd09d(%rip), %rax      # 0xe3a0
movq 0x40(%rax), %rdi
movl $0x1, %esi
callq 0x1950
cmpl $0x0, %eax
setne %al
movb %al, 0x14(%rsp)
movb 0x14(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
movl $0x1, 0x30(%rsp)
movl 0x30(%rsp), %ecx
xorl %eax, %eax
cmpl 0x34(%rsp), %ecx
movb %al, 0x13(%rsp)
jae 0x134c
cmpl $0x0, 0x18(%rsp)
setne %al
movb %al, 0x13(%rsp)
movb 0x13(%rsp), %al
testb $0x1, %al
jne 0x1359
jmp 0x188f
movq 0x38(%rsp), %rax
movl 0x30(%rsp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl %eax, 0x2c(%rsp)
movq 0x38(%rsp), %rax
movl 0x30(%rsp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, 0x28(%rsp)
cmpl $0x0, 0x2c(%rsp)
jne 0x13a8
leaq 0x7c9a(%rip), %rdi      # 0x902e
movb $0x0, %al
callq 0x1040
movl $0x0, 0x44(%rsp)
jmp 0x1941
cmpl $0x1, 0x2c(%rsp)
jne 0x14ce
cmpl $0x0, 0x28(%rsp)
jne 0x1433
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x12(%rsp)
je 0x13e0
movl $0x80000000, %edi       # imm = 0x80000000
movl $0x1, %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0x12(%rsp)
movb 0x12(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x11(%rsp)
je 0x1421
leaq 0xcf9f(%rip), %rax      # 0xe3a0
movq 0x40(%rax), %rax
movl 0x30(%rsp), %ecx
movl $0x2, %esi
movzbl (%rax,%rcx), %edi
callq 0x1b30
cmpl $0x0, %eax
setne %al
movb %al, 0x11(%rsp)
movb 0x11(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
jmp 0x14c9
movl $0xfffffff8, %eax       # imm = 0xFFFFFFF8
cmpl 0x28(%rsp), %eax
jg 0x14c2
cmpl $-0x1, 0x28(%rsp)
jg 0x14c2
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x10(%rsp)
je 0x146c
xorl %edi, %edi
movl $0x3, %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0x10(%rsp)
movb 0x10(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0xf(%rsp)
je 0x14a1
movl 0x28(%rsp), %edi
shll $0x1d, %edi
movl $0x3, %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
movl 0x24(%rsp), %eax
cmpl 0x28(%rsp), %eax
jle 0x14c0
movl 0x28(%rsp), %eax
movl %eax, 0x24(%rsp)
jmp 0x14c7
jmp 0x1855
jmp 0x14c9
jmp 0x187c
cmpl $0x2, 0x2c(%rsp)
jne 0x157e
movl $0xffffff00, %eax       # imm = 0xFFFFFF00
cmpl 0x28(%rsp), %eax
jg 0x1574
cmpl $-0x1, 0x28(%rsp)
jg 0x1574
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0xe(%rsp)
je 0x1519
movl $0x20000000, %edi       # imm = 0x20000000
movl $0x3, %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0xe(%rsp)
movb 0xe(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0xd(%rsp)
je 0x1553
movl 0x28(%rsp), %eax
andl $0xff, %eax
movl $0x2, %esi
movzbl %al, %edi
callq 0x1b30
cmpl $0x0, %eax
setne %al
movb %al, 0xd(%rsp)
movb 0xd(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
movl 0x24(%rsp), %eax
cmpl 0x28(%rsp), %eax
jle 0x1572
movl 0x28(%rsp), %eax
movl %eax, 0x24(%rsp)
jmp 0x1579
jmp 0x1855
jmp 0x187a
movl $0x3, %eax
cmpl 0x2c(%rsp), %eax
jg 0x1853
cmpl $0xff, 0x2c(%rsp)
jg 0x1853
cmpl $0x3, 0x2c(%rsp)
jne 0x15da
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0xc(%rsp)
je 0x15c8
movl $0x40000000, %edi       # imm = 0x40000000
movl $0x3, %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0xc(%rsp)
movb 0xc(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
jmp 0x16d3
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0xb(%rsp)
je 0x1600
movl $0x60000000, %edi       # imm = 0x60000000
movl $0x3, %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0xb(%rsp)
movb 0xb(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
movl $0x0, 0x1c(%rsp)
movl 0x2c(%rsp), %eax
subl $0x2, %eax
sarl %eax
movl %eax, 0x20(%rsp)
cmpl $0x0, 0x20(%rsp)
je 0x1640
movl 0x20(%rsp), %eax
shrl %eax
movl %eax, 0x20(%rsp)
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x1622
movl 0x2c(%rsp), %eax
subl $0x2, %eax
movl 0x1c(%rsp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
subl %ecx, %eax
movl %eax, 0x20(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0xa(%rsp)
je 0x168a
movl $0x20, %ecx
subl 0x1c(%rsp), %ecx
movl $0x1, %edi
shll %cl, %edi
movl 0x1c(%rsp), %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0xa(%rsp)
movb 0xa(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x9(%rsp)
je 0x16c6
movl 0x20(%rsp), %edi
movl $0x20, %ecx
subl 0x1c(%rsp), %ecx
shll %cl, %edi
movl 0x1c(%rsp), %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0x9(%rsp)
movb 0x9(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
movl $0xffffff00, %eax       # imm = 0xFFFFFF00
cmpl 0x28(%rsp), %eax
jg 0x176e
cmpl $-0x1, 0x28(%rsp)
jg 0x176e
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x8(%rsp)
je 0x1710
xorl %edi, %edi
movl $0x1, %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0x8(%rsp)
movb 0x8(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x7(%rsp)
je 0x174a
movl 0x28(%rsp), %eax
andl $0xff, %eax
movl $0x2, %esi
movzbl %al, %edi
callq 0x1b30
cmpl $0x0, %eax
setne %al
movb %al, 0x7(%rsp)
movb 0x7(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
movl 0x24(%rsp), %eax
cmpl 0x28(%rsp), %eax
jle 0x1769
movl 0x28(%rsp), %eax
movl %eax, 0x24(%rsp)
jmp 0x1851
movl $0xffffef00, %eax       # imm = 0xFFFFEF00
cmpl 0x28(%rsp), %eax
jg 0x184d
cmpl $0xffffff00, 0x28(%rsp) # imm = 0xFFFFFF00
jge 0x184d
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x6(%rsp)
je 0x17b1
movl $0x80000000, %edi       # imm = 0x80000000
movl $0x1, %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0x6(%rsp)
movb 0x6(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x5(%rsp)
je 0x17f2
movl 0x28(%rsp), %edi
addl $0x100, %edi            # imm = 0x100
andl $0xf00, %edi            # imm = 0xF00
shll $0x14, %edi
movl $0x4, %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0x5(%rsp)
movb 0x5(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x4(%rsp)
je 0x182c
movl 0x28(%rsp), %eax
andl $0xff, %eax
movl $0x2, %esi
movzbl %al, %edi
callq 0x1b30
cmpl $0x0, %eax
setne %al
movb %al, 0x4(%rsp)
movb 0x4(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
movl 0x24(%rsp), %eax
cmpl 0x28(%rsp), %eax
jle 0x184b
movl 0x28(%rsp), %eax
movl %eax, 0x24(%rsp)
jmp 0x184f
jmp 0x1855
jmp 0x1851
jmp 0x1878
jmp 0x1855
movl 0x2c(%rsp), %esi
movl 0x28(%rsp), %edx
leaq 0x7828(%rip), %rdi      # 0x908c
movb $0x0, %al
callq 0x1040
movl $0x0, 0x44(%rsp)
jmp 0x1941
jmp 0x187a
jmp 0x187c
jmp 0x187e
movl 0x2c(%rsp), %eax
addl 0x30(%rsp), %eax
movl %eax, 0x30(%rsp)
jmp 0x1330
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x3(%rsp)
je 0x18b5
movl $0x60100000, %edi       # imm = 0x60100000
movl $0xc, %esi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0x3(%rsp)
movb 0x3(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x2(%rsp)
je 0x18e2
xorl %esi, %esi
movl %esi, %edi
callq 0x1ce0
cmpl $0x0, %eax
setne %al
movb %al, 0x2(%rsp)
movb 0x2(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x18(%rsp)
movb %al, 0x1(%rsp)
je 0x1911
xorl %eax, %eax
movl %eax, %edi
xorl %esi, %esi
callq 0x1950
cmpl $0x0, %eax
setne %al
movb %al, 0x1(%rsp)
movb 0x1(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
cmpl $0x0, 0x18(%rsp)
je 0x1939
xorl %esi, %esi
subl 0x24(%rsp), %esi
leaq 0x77a0(%rip), %rdi      # 0x90d2
movb $0x0, %al
callq 0x1040
movl 0x18(%rsp), %eax
movl %eax, 0x44(%rsp)
movl 0x44(%rsp), %eax
addq $0x48, %rsp
retq
nopw (%rax,%rax)