Annotation of qemu/roms/ipxe/src/arch/i386/prefix/unnrv2b.S, revision 1.1.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.