Annotation of qemu/roms/ipxe/src/arch/i386/prefix/unnrv2b.S, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
        !             3:  *
        !             4:  * This file is free software; you can redistribute it and/or
        !             5:  * modify it under the terms of the GNU General Public License as
        !             6:  * published by the Free Software Foundation; either version 2 of
        !             7:  * the License, or (at your option) any later version.
        !             8:  *
        !             9:  * Originally this code was part of ucl the data compression library
        !            10:  * for upx the ``Ultimate Packer of eXecutables''.
        !            11:  *
        !            12:  * - Converted to gas assembly, and refitted to work with etherboot.
        !            13:  *   Eric Biederman 20 Aug 2002
        !            14:  *
        !            15:  * - Structure modified to be a subroutine call rather than an
        !            16:  *   executable prefix.
        !            17:  *   Michael Brown 30 Mar 2004
        !            18:  *
        !            19:  * - Modified to be compilable as either 16-bit or 32-bit code.
        !            20:  *   Michael Brown 9 Mar 2005
        !            21:  */
        !            22: 
        !            23: FILE_LICENCE ( GPL2_OR_LATER )
        !            24: 
        !            25: /****************************************************************************
        !            26:  * This file provides the decompress() and decompress16() functions
        !            27:  * which can be called in order to decompress an image compressed with
        !            28:  * the nrv2b utility in src/util.
        !            29:  *
        !            30:  * These functions are designed to be called by the prefix.  They are
        !            31:  * position-independent code.
        !            32:  *
        !            33:  * The same basic assembly code is used to compile both
        !            34:  * decompress() and decompress16().
        !            35:  ****************************************************************************
        !            36:  */
        !            37: 
        !            38:        .text
        !            39:        .arch i386
        !            40:        .section ".prefix.lib", "ax", @progbits
        !            41: 
        !            42: #ifdef CODE16
        !            43: /****************************************************************************
        !            44:  * decompress16 (real-mode near call, position independent)
        !            45:  *
        !            46:  * Decompress data in 16-bit mode
        !            47:  *
        !            48:  * Parameters (passed via registers):
        !            49:  *   %ds:%esi - Start of compressed input data
        !            50:  *   %es:%edi - Start of output buffer
        !            51:  * Returns:
        !            52:  *   %ds:%esi - End of compressed input data
        !            53:  *   %es:%edi - End of decompressed output data
        !            54:  *   All other registers are preserved
        !            55:  *
        !            56:  * NOTE: It would be possible to build a smaller version of the
        !            57:  * decompression code for -DKEEP_IT_REAL by using
        !            58:  *    #define REG(x) x
        !            59:  * to use 16-bit registers where possible.  This would impose limits
        !            60:  * that the compressed data size must be in the range [1,65533-%si]
        !            61:  * and the uncompressed data size must be in the range [1,65536-%di]
        !            62:  * (where %si and %di are the input values for those registers).  Note
        !            63:  * particularly that the lower limit is 1, not 0, and that the upper
        !            64:  * limit on the input (compressed) data really is 65533, since the
        !            65:  * algorithm may read up to three bytes beyond the end of the input
        !            66:  * data, since it reads dwords.
        !            67:  ****************************************************************************
        !            68:  */
        !            69: 
        !            70: #define REG(x) e ## x
        !            71: #define ADDR32 addr32
        !            72: 
        !            73:        .code16
        !            74:        .globl  decompress16
        !            75: decompress16:
        !            76:        
        !            77: #else /* CODE16 */
        !            78: 
        !            79: /****************************************************************************
        !            80:  * decompress (32-bit protected-mode near call, position independent)
        !            81:  *
        !            82:  * Parameters (passed via registers):
        !            83:  *   %ds:%esi - Start of compressed input data
        !            84:  *   %es:%edi - Start of output buffer
        !            85:  * Returns:
        !            86:  *   %ds:%esi - End of compressed input data
        !            87:  *   %es:%edi - End of decompressed output data
        !            88:  *   All other registers are preserved
        !            89:  ****************************************************************************
        !            90:  */
        !            91: 
        !            92: #define REG(x) e ## x
        !            93: #define ADDR32
        !            94:        
        !            95:        .code32
        !            96:        .globl  decompress
        !            97: decompress:
        !            98: 
        !            99: #endif /* CODE16 */
        !           100: 
        !           101: #define xAX    REG(ax)
        !           102: #define xCX    REG(cx)
        !           103: #define xBP    REG(bp)
        !           104: #define xSI    REG(si)
        !           105: #define xDI    REG(di)
        !           106: 
        !           107:        /* Save registers */
        !           108:        push    %xAX
        !           109:        pushl   %ebx
        !           110:        push    %xCX
        !           111:        push    %xBP
        !           112:        /* Do the decompression */
        !           113:        cld
        !           114:        xor     %xBP, %xBP
        !           115:        dec     %xBP            /* last_m_off = -1 */
        !           116:        jmp     dcl1_n2b
        !           117:        
        !           118: decompr_literals_n2b:
        !           119:        ADDR32 movsb
        !           120: decompr_loop_n2b:
        !           121:        addl    %ebx, %ebx
        !           122:        jnz     dcl2_n2b
        !           123: dcl1_n2b:
        !           124:        call    getbit32
        !           125: dcl2_n2b:
        !           126:        jc      decompr_literals_n2b
        !           127:        xor     %xAX, %xAX
        !           128:        inc     %xAX            /* m_off = 1 */
        !           129: loop1_n2b:
        !           130:        call    getbit1
        !           131:        adc     %xAX, %xAX      /* m_off = m_off*2 + getbit() */
        !           132:        call    getbit1
        !           133:        jnc     loop1_n2b       /* while(!getbit()) */
        !           134:        sub     $3, %xAX
        !           135:        jb      decompr_ebpeax_n2b      /* if (m_off == 2) goto decompr_ebpeax_n2b ? */
        !           136:        shl     $8, %xAX        
        !           137:        ADDR32 movb (%xSI), %al /* m_off = (m_off - 3)*256 + src[ilen++] */
        !           138:        inc     %xSI
        !           139:        xor     $-1, %xAX
        !           140:        jz      decompr_end_n2b /* if (m_off == 0xffffffff) goto decomp_end_n2b */
        !           141:        mov     %xAX, %xBP      /* last_m_off = m_off ?*/
        !           142: decompr_ebpeax_n2b:
        !           143:        xor     %xCX, %xCX
        !           144:        call    getbit1
        !           145:        adc     %xCX, %xCX      /* m_len = getbit() */
        !           146:        call    getbit1
        !           147:        adc     %xCX, %xCX      /* m_len = m_len*2 + getbit()) */
        !           148:        jnz     decompr_got_mlen_n2b    /* if (m_len == 0) goto decompr_got_mlen_n2b */
        !           149:        inc     %xCX            /* m_len++ */
        !           150: loop2_n2b:
        !           151:        call    getbit1 
        !           152:        adc     %xCX, %xCX      /* m_len = m_len*2 + getbit() */
        !           153:        call    getbit1
        !           154:        jnc     loop2_n2b       /* while(!getbit()) */
        !           155:        inc     %xCX
        !           156:        inc     %xCX            /* m_len += 2 */
        !           157: decompr_got_mlen_n2b:
        !           158:        cmp     $-0xd00, %xBP
        !           159:        adc     $1, %xCX        /* m_len = m_len + 1 + (last_m_off > 0xd00) */
        !           160:        push    %xSI
        !           161:        ADDR32 lea (%xBP,%xDI), %xSI    /* m_pos = dst + olen + -m_off  */
        !           162:        rep
        !           163:        es ADDR32 movsb         /* dst[olen++] = *m_pos++ while(m_len > 0) */
        !           164:        pop     %xSI
        !           165:        jmp     decompr_loop_n2b
        !           166: 
        !           167: 
        !           168: getbit1:
        !           169:        addl    %ebx, %ebx
        !           170:        jnz     1f
        !           171: getbit32:
        !           172:        ADDR32 movl (%xSI), %ebx
        !           173:        sub     $-4, %xSI       /* sets carry flag */
        !           174:        adcl    %ebx, %ebx
        !           175: 1:
        !           176:        ret
        !           177: 
        !           178: decompr_end_n2b:
        !           179:        /* Restore registers and return */
        !           180:        pop     %xBP
        !           181:        pop     %xCX
        !           182:        popl    %ebx
        !           183:        pop     %xAX
        !           184:        ret

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.