which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@5403 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			164 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
		
			Executable File
		
	
	
	
	
| /*
 | |
|  * crc_i386.S, optimized CRC calculation function for Zip and UnZip, not
 | |
|  * copyrighted by Paul Kienitz and Christian Spieler.  Last revised 10 Nov 96.
 | |
|  *
 | |
|  * GRR 961110:  incorporated Scott Field optimizations from win32/crc_i386.asm
 | |
|  *              => overall 6% speedup in "unzip -tq" on 9MB zipfile (486-66)
 | |
|  *
 | |
|  * FLAT memory model assumed.  Calling interface:
 | |
|  *   - args are pushed onto the stack from right to left,
 | |
|  *   - return value is given in the EAX register,
 | |
|  *   - all other registers (with exception of EFLAGS) are preserved. (With
 | |
|  *     GNU C 2.7.x, %edx and %ecx are `scratch' registers, but preserving
 | |
|  *     them nevertheless does only cost 4 single byte instructions.)
 | |
|  *
 | |
|  * This source generates the function
 | |
|  * ulg crc32(ulg oldcrc, ZCONST uch *text, ulg textlen).
 | |
|  *
 | |
|  * The loop unroolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
 | |
|  * This results in shorter code at the expense of reduced performance.
 | |
|  */
 | |
| 
 | |
| /* This file is NOT used in conjunction with zlib. */
 | |
| #ifndef USE_ZLIB
 | |
| 
 | |
| /* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
 | |
|  * external symbols with an underline character '_'.
 | |
|  */
 | |
| #if defined(NO_UNDERLINE) || defined(__ELF__)
 | |
| #  define _crc32            crc32
 | |
| #  define _get_crc_table    get_crc_table
 | |
| #endif
 | |
| /* Use 16-byte alignment if your assembler supports it. Warning: gas
 | |
|  * uses a log(x) parameter (.align 4 means 16-byte alignment). On SVR4
 | |
|  * the parameter is a number of bytes.
 | |
|  */
 | |
| #ifndef ALIGNMENT
 | |
| #  define ALIGNMENT .align 4,0x90
 | |
| #endif
 | |
| 
 | |
| #if defined(i386) || defined(_i386) || defined(_I386) || defined(__i386)
 | |
| 
 | |
| /* This version is for 386 Unix, OS/2, MSDOS in 32 bit mode (gcc & gas).
 | |
|  * Warning: it uses the AT&T syntax: mov source,dest
 | |
|  * This file is only optional. If you want to use the C version,
 | |
|  * remove -DASM_CRC from CFLAGS in Makefile and set OBJA to an empty string.
 | |
|  */
 | |
| 
 | |
|                 .file   "crc_i386.S"
 | |
| 
 | |
| #if defined(NO_STD_STACKFRAME) && defined(USE_STD_STACKFRAME)
 | |
| #  undef USE_STACKFRAME
 | |
| #else
 | |
|    /* The default is to use standard stack frame entry, because it
 | |
|     * results in smaller code!
 | |
|     */
 | |
| #  ifndef USE_STD_STACKFRAME
 | |
| #    define USE_STD_STACKFRAME
 | |
| #  endif
 | |
| #endif
 | |
| 
 | |
| #ifdef USE_STD_STACKFRAME
 | |
| #  define _STD_ENTRY    pushl   %ebp ; movl   %esp,%ebp
 | |
| #  define arg1  8(%ebp)
 | |
| #  define arg2  12(%ebp)
 | |
| #  define arg3  16(%ebp)
 | |
| #  define _STD_LEAVE    popl    %ebp
 | |
| #else /* !USE_STD_STACKFRAME */
 | |
| #  define _STD_ENTRY
 | |
| #  define arg1  24(%esp)
 | |
| #  define arg2  28(%esp)
 | |
| #  define arg3  32(%esp)
 | |
| #  define _STD_LEAVE
 | |
| #endif /* ?USE_STD_STACKFRAME */
 | |
| 
 | |
| /*
 | |
|  * This is the loop body of the CRC32 cruncher.
 | |
|  * registers modified:
 | |
|  *   ebx  : crc value "c"
 | |
|  *   esi  : pointer to next data byte "text++"
 | |
|  * registers read:
 | |
|  *   edi  : pointer to base of crc_table array
 | |
|  * scratch registers:
 | |
|  *   eax  : requires upper three bytes of eax = 0, uses al
 | |
|  */
 | |
| #define Do_CRC \
 | |
|                 movb    (%esi),%al          ;/* al <-- *text                */\
 | |
|                 incl    %esi                ;/* text++                      */\
 | |
|                 xorb    %bl,%al             ;/* (c ^ *text++) & 0xFF        */\
 | |
|                 shrl    $8,%ebx             ;/* c = (c >> 8)                */\
 | |
|                 xorl    (%edi,%eax,4),%ebx  ;/*  ^table[(c^(*text++))&0xFF] */
 | |
| 
 | |
| 
 | |
|                 .text
 | |
| 
 | |
|                 .globl  _crc32
 | |
| 
 | |
| _crc32:                         /* ulg crc32(ulg crc, uch *text, extent len) */
 | |
|                 _STD_ENTRY
 | |
|                 pushl   %edi
 | |
|                 pushl   %esi
 | |
|                 pushl   %ebx
 | |
|                 pushl   %edx
 | |
|                 pushl   %ecx
 | |
| 
 | |
|                 movl    arg2,%esi            /* 2nd arg: uch *text           */
 | |
|                 subl    %eax,%eax            /* > if (!text)                 */
 | |
|                 testl   %esi,%esi            /* >   return 0;                */
 | |
|                 jz      fine                 /* > else {                     */
 | |
|                 call    _get_crc_table
 | |
|                 movl    %eax,%edi
 | |
|                 movl    arg1,%ebx            /* 1st arg: ulg crc             */
 | |
|                 subl    %eax,%eax            /* eax=0; al usable as dword */
 | |
|                 movl    arg3,%ecx            /* 3rd arg: extent textlen      */
 | |
|                 notl    %ebx                 /* >   c = ~crc;                */
 | |
| 
 | |
| #ifndef  NO_UNROLLED_LOOPS
 | |
|                 movl    %ecx,%edx            /* save textlen in edx          */
 | |
|                 andl    $7,%edx              /* edx = textlen % 8            */
 | |
|                 shrl    $3,%ecx              /* ecx = textlen / 8            */
 | |
|                 jz      No_Eights
 | |
| /*  align loop head at start of 486 internal cache line !! */
 | |
|                 ALIGNMENT
 | |
| Next_Eight:
 | |
|                  Do_CRC
 | |
|                  Do_CRC
 | |
|                  Do_CRC
 | |
|                  Do_CRC
 | |
|                  Do_CRC
 | |
|                  Do_CRC
 | |
|                  Do_CRC
 | |
|                  Do_CRC
 | |
|                 decl    %ecx
 | |
|                 jnz     Next_Eight
 | |
| 
 | |
| No_Eights:
 | |
|                 movl    %edx,%ecx
 | |
| #endif /* NO_UNROLLED_LOOPS */
 | |
| 
 | |
|                 jecxz   bail                 /* > if (textlen)               */
 | |
| /* align loop head at start of 486 internal cache line !! */
 | |
|                 ALIGNMENT
 | |
| loupe:                                       /* >   do {                     */
 | |
|                  Do_CRC                      /*       c = CRC32(c, *text++); */
 | |
|                 decl    %ecx                 /* >   } while (--textlen);     */
 | |
|                 jnz     loupe
 | |
| 
 | |
| bail:                                        /* > }                          */
 | |
|                 movl    %ebx,%eax
 | |
|                 notl    %eax                 /* > return ~c;                 */
 | |
| fine:
 | |
|                 popl    %ecx
 | |
|                 popl    %edx
 | |
|                 popl    %ebx
 | |
|                 popl    %esi
 | |
|                 popl    %edi
 | |
|                 _STD_LEAVE
 | |
|                 ret
 | |
| 
 | |
| #else
 | |
|  error: this asm version is for 386 only
 | |
| #endif /* i386 || _i386 || _I386 || __i386 */
 | |
| 
 | |
| #endif /* !USE_ZLIB */
 |