commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject svn commit: r1084288 [12/15] - in /commons/sandbox/runtime/trunk/src/main/native: ./ include/acr/ os/ os/aix/ os/bsdx/ os/darwin/ os/hpux/ os/linux/ os/solaris/ os/unix/ os/win32/ port/ srclib/ srclib/bzip2/ srclib/zlib/ srclib/zlib/unix/ srclib/zlib/w...
Date Tue, 22 Mar 2011 18:36:21 GMT
Added: commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/unix/i686-match.S
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/unix/i686-match.S?rev=1084288&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/unix/i686-match.S (added)
+++ commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/unix/i686-match.S Tue Mar 22 18:36:19 2011
@@ -0,0 +1,343 @@
+/* match.S -- x86 assembly version of the zlib longest_match() function.
+ * Optimized for the Intel 686 chips (PPro and later).
+ *
+ * Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the author be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef NO_UNDERLINE
+#define	match_init	_match_init
+#define	longest_match	_longest_match
+#endif
+
+#define	MAX_MATCH	(258)
+#define	MIN_MATCH	(3)
+#define	MIN_LOOKAHEAD	(MAX_MATCH + MIN_MATCH + 1)
+#define	MAX_MATCH_8	((MAX_MATCH + 7) & ~7)
+
+/* stack frame offsets */
+
+#define	chainlenwmask		0	/* high word: current chain len	*/
+					/* low word: s->wmask		*/
+#define	window			4	/* local copy of s->window	*/
+#define	windowbestlen		8	/* s->window + bestlen		*/
+#define	scanstart		16	/* first two bytes of string	*/
+#define	scanend			12	/* last two bytes of string	*/
+#define	scanalign		20	/* dword-misalignment of string	*/
+#define	nicematch		24	/* a good enough match size	*/
+#define	bestlen			28	/* size of best match so far	*/
+#define	scan			32	/* ptr to string wanting match	*/
+
+#define	LocalVarsSize		(36)
+/*	saved ebx		36 */
+/*	saved edi		40 */
+/*	saved esi		44 */
+/*	saved ebp		48 */
+/*	return address		52 */
+#define	deflatestate		56	/* the function arguments	*/
+#define	curmatch		60
+
+/* All the +zlib1222add offsets are due to the addition of fields
+ *  in zlib in the deflate_state structure since the asm code was first written
+ * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+ * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+ * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+ */
+
+#define zlib1222add		(8)
+
+#define	dsWSize			(36+zlib1222add)
+#define	dsWMask			(44+zlib1222add)
+#define	dsWindow		(48+zlib1222add)
+#define	dsPrev			(56+zlib1222add)
+#define	dsMatchLen		(88+zlib1222add)
+#define	dsPrevMatch		(92+zlib1222add)
+#define	dsStrStart		(100+zlib1222add)
+#define	dsMatchStart		(104+zlib1222add)
+#define	dsLookahead		(108+zlib1222add)
+#define	dsPrevLen		(112+zlib1222add)
+#define	dsMaxChainLen		(116+zlib1222add)
+#define	dsGoodMatch		(132+zlib1222add)
+#define	dsNiceMatch		(136+zlib1222add)
+
+
+.file "match.S"
+
+.globl	match_init, longest_match
+
+.text
+
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
+
+longest_match:
+
+/* Save registers that the compiler may be using, and adjust %esp to	*/
+/* make room for our stack frame.					*/
+
+		pushl	%ebp
+		pushl	%edi
+		pushl	%esi
+		pushl	%ebx
+		subl	$LocalVarsSize, %esp
+
+/* Retrieve the function arguments. %ecx will hold cur_match		*/
+/* throughout the entire function. %edx will hold the pointer to the	*/
+/* deflate_state structure during the function's setup (before		*/
+/* entering the main loop).						*/
+
+		movl	deflatestate(%esp), %edx
+		movl	curmatch(%esp), %ecx
+
+/* uInt wmask = s->w_mask;						*/
+/* unsigned chain_length = s->max_chain_length;				*/
+/* if (s->prev_length >= s->good_match) {				*/
+/*     chain_length >>= 2;						*/
+/* }									*/
+
+		movl	dsPrevLen(%edx), %eax
+		movl	dsGoodMatch(%edx), %ebx
+		cmpl	%ebx, %eax
+		movl	dsWMask(%edx), %eax
+		movl	dsMaxChainLen(%edx), %ebx
+		jl	LastMatchGood
+		shrl	$2, %ebx
+LastMatchGood:
+
+/* chainlen is decremented once beforehand so that the function can	*/
+/* use the sign flag instead of the zero flag for the exit test.	*/
+/* It is then shifted into the high word, to make room for the wmask	*/
+/* value, which it will always accompany.				*/
+
+		decl	%ebx
+		shll	$16, %ebx
+		orl	%eax, %ebx
+		movl	%ebx, chainlenwmask(%esp)
+
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;	*/
+
+		movl	dsNiceMatch(%edx), %eax
+		movl	dsLookahead(%edx), %ebx
+		cmpl	%eax, %ebx
+		jl	LookaheadLess
+		movl	%eax, %ebx
+LookaheadLess:	movl	%ebx, nicematch(%esp)
+
+/* register Bytef *scan = s->window + s->strstart;			*/
+
+		movl	dsWindow(%edx), %esi
+		movl	%esi, window(%esp)
+		movl	dsStrStart(%edx), %ebp
+		lea	(%esi,%ebp), %edi
+		movl	%edi, scan(%esp)
+
+/* Determine how many bytes the scan ptr is off from being		*/
+/* dword-aligned.							*/
+
+		movl	%edi, %eax
+		negl	%eax
+		andl	$3, %eax
+		movl	%eax, scanalign(%esp)
+
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?			*/
+/*     s->strstart - (IPos)MAX_DIST(s) : NIL;				*/
+
+		movl	dsWSize(%edx), %eax
+		subl	$MIN_LOOKAHEAD, %eax
+		subl	%eax, %ebp
+		jg	LimitPositive
+		xorl	%ebp, %ebp
+LimitPositive:
+
+/* int best_len = s->prev_length;					*/
+
+		movl	dsPrevLen(%edx), %eax
+		movl	%eax, bestlen(%esp)
+
+/* Store the sum of s->window + best_len in %esi locally, and in %esi.	*/
+
+		addl	%eax, %esi
+		movl	%esi, windowbestlen(%esp)
+
+/* register ush scan_start = *(ushf*)scan;				*/
+/* register ush scan_end   = *(ushf*)(scan+best_len-1);			*/
+/* Posf *prev = s->prev;						*/
+
+		movzwl	(%edi), %ebx
+		movl	%ebx, scanstart(%esp)
+		movzwl	-1(%edi,%eax), %ebx
+		movl	%ebx, scanend(%esp)
+		movl	dsPrev(%edx), %edi
+
+/* Jump into the main loop.						*/
+
+		movl	chainlenwmask(%esp), %edx
+		jmp	LoopEntry
+
+.balign 16
+
+/* do {
+ *     match = s->window + cur_match;
+ *     if (*(ushf*)(match+best_len-1) != scan_end ||
+ *         *(ushf*)match != scan_start) continue;
+ *     [...]
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
+ *          && --chain_length != 0);
+ *
+ * Here is the inner loop of the function. The function will spend the
+ * majority of its time in this loop, and majority of that time will
+ * be spent in the first ten instructions.
+ *
+ * Within this loop:
+ * %ebx = scanend
+ * %ecx = curmatch
+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+ * %esi = windowbestlen - i.e., (window + bestlen)
+ * %edi = prev
+ * %ebp = limit
+ */
+LookupLoop:
+		andl	%edx, %ecx
+		movzwl	(%edi,%ecx,2), %ecx
+		cmpl	%ebp, %ecx
+		jbe	LeaveNow
+		subl	$0x00010000, %edx
+		js	LeaveNow
+LoopEntry:	movzwl	-1(%esi,%ecx), %eax
+		cmpl	%ebx, %eax
+		jnz	LookupLoop
+		movl	window(%esp), %eax
+		movzwl	(%eax,%ecx), %eax
+		cmpl	scanstart(%esp), %eax
+		jnz	LookupLoop
+
+/* Store the current value of chainlen.					*/
+
+		movl	%edx, chainlenwmask(%esp)
+
+/* Point %edi to the string under scrutiny, and %esi to the string we	*/
+/* are hoping to match it up with. In actuality, %esi and %edi are	*/
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is	*/
+/* initialized to -(MAX_MATCH_8 - scanalign).				*/
+
+		movl	window(%esp), %esi
+		movl	scan(%esp), %edi
+		addl	%ecx, %esi
+		movl	scanalign(%esp), %eax
+		movl	$(-MAX_MATCH_8), %edx
+		lea	MAX_MATCH_8(%edi,%eax), %edi
+		lea	MAX_MATCH_8(%esi,%eax), %esi
+
+/* Test the strings for equality, 8 bytes at a time. At the end,
+ * adjust %edx so that it is offset to the exact byte that mismatched.
+ *
+ * We already know at this point that the first three bytes of the
+ * strings match each other, and they can be safely passed over before
+ * starting the compare loop. So what this code does is skip over 0-3
+ * bytes, as much as necessary in order to dword-align the %edi
+ * pointer. (%esi will still be misaligned three times out of four.)
+ *
+ * It should be confessed that this loop usually does not represent
+ * much of the total running time. Replacing it with a more
+ * straightforward "rep cmpsb" would not drastically degrade
+ * performance.
+ */
+LoopCmps:
+		movl	(%esi,%edx), %eax
+		xorl	(%edi,%edx), %eax
+		jnz	LeaveLoopCmps
+		movl	4(%esi,%edx), %eax
+		xorl	4(%edi,%edx), %eax
+		jnz	LeaveLoopCmps4
+		addl	$8, %edx
+		jnz	LoopCmps
+		jmp	LenMaximum
+LeaveLoopCmps4:	addl	$4, %edx
+LeaveLoopCmps:	testl	$0x0000FFFF, %eax
+		jnz	LenLower
+		addl	$2, %edx
+		shrl	$16, %eax
+LenLower:	subb	$1, %al
+		adcl	$0, %edx
+
+/* Calculate the length of the match. If it is longer than MAX_MATCH,	*/
+/* then automatically accept it as the best possible match and leave.	*/
+
+		lea	(%edi,%edx), %eax
+		movl	scan(%esp), %edi
+		subl	%edi, %eax
+		cmpl	$MAX_MATCH, %eax
+		jge	LenMaximum
+
+/* If the length of the match is not longer than the best match we	*/
+/* have so far, then forget it and return to the lookup loop.		*/
+
+		movl	deflatestate(%esp), %edx
+		movl	bestlen(%esp), %ebx
+		cmpl	%ebx, %eax
+		jg	LongerMatch
+		movl	windowbestlen(%esp), %esi
+		movl	dsPrev(%edx), %edi
+		movl	scanend(%esp), %ebx
+		movl	chainlenwmask(%esp), %edx
+		jmp	LookupLoop
+
+/*         s->match_start = cur_match;					*/
+/*         best_len = len;						*/
+/*         if (len >= nice_match) break;				*/
+/*         scan_end = *(ushf*)(scan+best_len-1);			*/
+
+LongerMatch:	movl	nicematch(%esp), %ebx
+		movl	%eax, bestlen(%esp)
+		movl	%ecx, dsMatchStart(%edx)
+		cmpl	%ebx, %eax
+		jge	LeaveNow
+		movl	window(%esp), %esi
+		addl	%eax, %esi
+		movl	%esi, windowbestlen(%esp)
+		movzwl	-1(%edi,%eax), %ebx
+		movl	dsPrev(%edx), %edi
+		movl	%ebx, scanend(%esp)
+		movl	chainlenwmask(%esp), %edx
+		jmp	LookupLoop
+
+/* Accept the current string, with the maximum possible length.		*/
+
+LenMaximum:	movl	deflatestate(%esp), %edx
+		movl	$MAX_MATCH, bestlen(%esp)
+		movl	%ecx, dsMatchStart(%edx)
+
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;		*/
+/* return s->lookahead;							*/
+
+LeaveNow:
+		movl	deflatestate(%esp), %edx
+		movl	bestlen(%esp), %ebx
+		movl	dsLookahead(%edx), %eax
+		cmpl	%eax, %ebx
+		jg	LookaheadRet
+		movl	%ebx, %eax
+LookaheadRet:
+
+/* Restore the stack and return from whence we came.			*/
+
+		addl	$LocalVarsSize, %esp
+		popl	%ebx
+		popl	%esi
+		popl	%edi
+		popl	%ebp
+match_init:	ret

Added: commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/gvmat64.asm
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/gvmat64.asm?rev=1084288&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/gvmat64.asm (added)
+++ commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/gvmat64.asm Tue Mar 22 18:36:19 2011
@@ -0,0 +1,553 @@
+;uInt longest_match_x64(
+;    deflate_state *s,
+;    IPos cur_match);                             /* current match */
+
+; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86_64
+;  (AMD64 on Athlon 64, Opteron, Phenom
+;     and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)
+; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+;
+; File written by Gilles Vollant, by converting to assembly the longest_match
+;  from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
+;
+;  and by taking inspiration on asm686 with masm, optimised assembly code
+;        from Brian Raiter, written 1998
+;
+;  This software is provided 'as-is', without any express or implied
+;  warranty.  In no event will the authors be held liable for any damages
+;  arising from the use of this software.
+;
+;  Permission is granted to anyone to use this software for any purpose,
+;  including commercial applications, and to alter it and redistribute it
+;  freely, subject to the following restrictions:
+;
+;  1. The origin of this software must not be misrepresented; you must not
+;     claim that you wrote the original software. If you use this software
+;     in a product, an acknowledgment in the product documentation would be
+;     appreciated but is not required.
+;  2. Altered source versions must be plainly marked as such, and must not be
+;     misrepresented as being the original software
+;  3. This notice may not be removed or altered from any source distribution.
+;
+;
+;
+;         http://www.zlib.net
+;         http://www.winimage.com/zLibDll
+;         http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; to compile this file for infozip Zip, I use option:
+;   ml64.exe /Flgvmat64 /c /Zi /DINFOZIP gvmat64.asm
+;
+; to compile this file for zLib, I use option:
+;   ml64.exe /Flgvmat64 /c /Zi gvmat64.asm
+; Be carrefull to adapt zlib1222add below to your version of zLib
+;   (if you use a version of zLib before 1.0.4 or after 1.2.2.2, change
+;    value of zlib1222add later)
+;
+; This file compile with Microsoft Macro Assembler (x64) for AMD64
+;
+;   ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK
+;
+;   (you can get Windows WDK with ml64 for AMD64 from
+;      http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)
+;
+
+
+;uInt longest_match(s, cur_match)
+;    deflate_state *s;
+;    IPos cur_match;                             /* current match */
+.code
+longest_match PROC
+
+
+;LocalVarsSize   equ 88
+ LocalVarsSize   equ 72
+
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
+; free register :  r14,r15
+; register can be saved : rsp
+
+ chainlenwmask   equ  rsp + 8 - LocalVarsSize    ; high word: current chain len
+                                                 ; low word: s->wmask
+;window          equ  rsp + xx - LocalVarsSize   ; local copy of s->window ; stored in r10
+;windowbestlen   equ  rsp + xx - LocalVarsSize   ; s->window + bestlen , use r10+r11
+;scanstart       equ  rsp + xx - LocalVarsSize   ; first two bytes of string ; stored in r12w
+;scanend         equ  rsp + xx - LocalVarsSize   ; last two bytes of string use ebx
+;scanalign       equ  rsp + xx - LocalVarsSize   ; dword-misalignment of string r13
+;bestlen         equ  rsp + xx - LocalVarsSize   ; size of best match so far -> r11d
+;scan            equ  rsp + xx - LocalVarsSize   ; ptr to string wanting match -> r9
+IFDEF INFOZIP
+ELSE
+ nicematch       equ  (rsp + 16 - LocalVarsSize) ; a good enough match size
+ENDIF
+
+save_rdi        equ  rsp + 24 - LocalVarsSize
+save_rsi        equ  rsp + 32 - LocalVarsSize
+save_rbx        equ  rsp + 40 - LocalVarsSize
+save_rbp        equ  rsp + 48 - LocalVarsSize
+save_r12        equ  rsp + 56 - LocalVarsSize
+save_r13        equ  rsp + 64 - LocalVarsSize
+;save_r14        equ  rsp + 72 - LocalVarsSize
+;save_r15        equ  rsp + 80 - LocalVarsSize
+
+
+; summary of register usage
+; scanend     ebx
+; scanendw    bx
+; chainlenwmask   edx
+; curmatch    rsi
+; curmatchd   esi
+; windowbestlen   r8
+; scanalign   r9
+; scanalignd  r9d
+; window      r10
+; bestlen     r11
+; bestlend    r11d
+; scanstart   r12d
+; scanstartw  r12w
+; scan        r13
+; nicematch   r14d
+; limit       r15
+; limitd      r15d
+; prev        rcx
+
+;  all the +4 offsets are due to the addition of pending_buf_size (in zlib
+;  in the deflate_state structure since the asm code was first written
+;  (if you compile with zlib 1.0.4 or older, remove the +4).
+;  Note : these value are good with a 8 bytes boundary pack structure
+
+
+    MAX_MATCH           equ     258
+    MIN_MATCH           equ     3
+    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)
+
+
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+;  all the +zlib1222add offsets are due to the addition of fields
+;  in zlib in the deflate_state structure since the asm code was first written
+;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+
+
+IFDEF INFOZIP
+
+_DATA   SEGMENT
+COMM    window_size:DWORD
+; WMask ; 7fff
+COMM    window:BYTE:010040H
+COMM    prev:WORD:08000H
+; MatchLen : unused
+; PrevMatch : unused
+COMM    strstart:DWORD
+COMM    match_start:DWORD
+; Lookahead : ignore
+COMM    prev_length:DWORD ; PrevLen
+COMM    max_chain_length:DWORD
+COMM    good_match:DWORD
+COMM    nice_match:DWORD
+prev_ad equ OFFSET prev
+window_ad equ OFFSET window
+nicematch equ nice_match
+_DATA ENDS
+WMask equ 07fffh
+
+ELSE
+
+  IFNDEF zlib1222add
+    zlib1222add equ 8
+  ENDIF
+dsWSize         equ 56+zlib1222add+(zlib1222add/2)
+dsWMask         equ 64+zlib1222add+(zlib1222add/2)
+dsWindow        equ 72+zlib1222add
+dsPrev          equ 88+zlib1222add
+dsMatchLen      equ 128+zlib1222add
+dsPrevMatch     equ 132+zlib1222add
+dsStrStart      equ 140+zlib1222add
+dsMatchStart    equ 144+zlib1222add
+dsLookahead     equ 148+zlib1222add
+dsPrevLen       equ 152+zlib1222add
+dsMaxChainLen   equ 156+zlib1222add
+dsGoodMatch     equ 172+zlib1222add
+dsNiceMatch     equ 176+zlib1222add
+
+window_size     equ [ rcx + dsWSize]
+WMask           equ [ rcx + dsWMask]
+window_ad       equ [ rcx + dsWindow]
+prev_ad         equ [ rcx + dsPrev]
+strstart        equ [ rcx + dsStrStart]
+match_start     equ [ rcx + dsMatchStart]
+Lookahead       equ [ rcx + dsLookahead] ; 0ffffffffh on infozip
+prev_length     equ [ rcx + dsPrevLen]
+max_chain_length equ [ rcx + dsMaxChainLen]
+good_match      equ [ rcx + dsGoodMatch]
+nice_match      equ [ rcx + dsNiceMatch]
+ENDIF
+
+; parameter 1 in r8(deflate state s), param 2 in rdx (cur match)
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+;   rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.
+
+
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+
+;;; Retrieve the function arguments. r8d will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
+
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
+
+        mov [save_rdi],rdi
+        mov [save_rsi],rsi
+        mov [save_rbx],rbx
+        mov [save_rbp],rbp
+IFDEF INFOZIP
+        mov r8d,ecx
+ELSE
+        mov r8d,edx
+ENDIF
+        mov [save_r12],r12
+        mov [save_r13],r13
+;        mov [save_r14],r14
+;        mov [save_r15],r15
+
+
+;;; uInt wmask = s->w_mask;
+;;; unsigned chain_length = s->max_chain_length;
+;;; if (s->prev_length >= s->good_match) {
+;;;     chain_length >>= 2;
+;;; }
+
+        mov edi, prev_length
+        mov esi, good_match
+        mov eax, WMask
+        mov ebx, max_chain_length
+        cmp edi, esi
+        jl  LastMatchGood
+        shr ebx, 2
+LastMatchGood:
+
+;;; chainlen is decremented once beforehand so that the function can
+;;; use the sign flag instead of the zero flag for the exit test.
+;;; It is then shifted into the high word, to make room for the wmask
+;;; value, which it will always accompany.
+
+        dec ebx
+        shl ebx, 16
+        or  ebx, eax
+
+;;; on zlib only
+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+IFDEF INFOZIP
+        mov [chainlenwmask], ebx
+; on infozip nice_match = [nice_match]
+ELSE
+        mov eax, nice_match
+        mov [chainlenwmask], ebx
+        mov r10d, Lookahead
+        cmp r10d, eax
+        cmovnl r10d, eax
+        mov [nicematch],r10d
+ENDIF
+
+;;; register Bytef *scan = s->window + s->strstart;
+        mov r10, window_ad
+        mov ebp, strstart
+        lea r13, [r10 + rbp]
+
+;;; Determine how many bytes the scan ptr is off from being
+;;; dword-aligned.
+
+         mov r9,r13
+         neg r13
+         and r13,3
+
+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;
+IFDEF INFOZIP
+        mov eax,07efah ; MAX_DIST = (WSIZE-MIN_LOOKAHEAD) (0x8000-(3+8+1))
+ELSE
+        mov eax, window_size
+        sub eax, MIN_LOOKAHEAD
+ENDIF
+        xor edi,edi
+        sub ebp, eax
+
+        mov r11d, prev_length
+
+        cmovng ebp,edi
+
+;;; int best_len = s->prev_length;
+
+
+;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+       lea  rsi,[r10+r11]
+
+;;; register ush scan_start = *(ushf*)scan;
+;;; register ush scan_end   = *(ushf*)(scan+best_len-1);
+;;; Posf *prev = s->prev;
+
+        movzx r12d,word ptr [r9]
+        movzx ebx, word ptr [r9 + r11 - 1]
+
+        mov rdi, prev_ad
+
+;;; Jump into the main loop.
+
+        mov edx, [chainlenwmask]
+
+        cmp bx,word ptr [rsi + r8 - 1]
+        jz  LookupLoopIsZero
+
+LookupLoop1:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+        jbe LeaveNow
+        sub edx, 00010000h
+        js  LeaveNow
+
+LoopEntry1:
+        cmp bx,word ptr [rsi + r8 - 1]
+        jz  LookupLoopIsZero
+
+LookupLoop2:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+        jbe LeaveNow
+        sub edx, 00010000h
+        js  LeaveNow
+
+LoopEntry2:
+        cmp bx,word ptr [rsi + r8 - 1]
+        jz  LookupLoopIsZero
+
+LookupLoop4:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+        jbe LeaveNow
+        sub edx, 00010000h
+        js  LeaveNow
+
+LoopEntry4:
+
+        cmp bx,word ptr [rsi + r8 - 1]
+        jnz LookupLoop1
+        jmp LookupLoopIsZero
+
+
+;;; do {
+;;;     match = s->window + cur_match;
+;;;     if (*(ushf*)(match+best_len-1) != scan_end ||
+;;;         *(ushf*)match != scan_start) continue;
+;;;     [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;;          && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; r8d = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+
+LookupLoop:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+        jbe LeaveNow
+        sub edx, 00010000h
+        js  LeaveNow
+
+LoopEntry:
+
+        cmp bx,word ptr [rsi + r8 - 1]
+        jnz LookupLoop1
+LookupLoopIsZero:
+        cmp     r12w, word ptr [r10 + r8]
+        jnz LookupLoop1
+
+
+;;; Store the current value of chainlen.
+        mov [chainlenwmask], edx
+
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+
+        lea rsi,[r8+r10]
+        mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8)
+        lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8]
+        lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8]
+
+        prefetcht1 [rsi+rdx]
+        prefetcht1 [rdi+rdx]
+
+
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust rdx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (rsi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+
+
+LoopCmps:
+        mov rax, [rsi + rdx]
+        xor rax, [rdi + rdx]
+        jnz LeaveLoopCmps
+
+        mov rax, [rsi + rdx + 8]
+        xor rax, [rdi + rdx + 8]
+        jnz LeaveLoopCmps8
+
+
+        mov rax, [rsi + rdx + 8+8]
+        xor rax, [rdi + rdx + 8+8]
+        jnz LeaveLoopCmps16
+
+        add rdx,8+8+8
+
+        jnz short LoopCmps
+        jmp short LenMaximum
+LeaveLoopCmps16: add rdx,8
+LeaveLoopCmps8: add rdx,8
+LeaveLoopCmps:
+
+        test    eax, 0000FFFFh
+        jnz LenLower
+
+        test eax,0ffffffffh
+
+        jnz LenLower32
+
+        add rdx,4
+        shr rax,32
+        or ax,ax
+        jnz LenLower
+
+LenLower32:
+        shr eax,16
+        add rdx,2
+LenLower:   sub al, 1
+        adc rdx, 0
+;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+;;; then automatically accept it as the best possible match and leave.
+
+        lea rax, [rdi + rdx]
+        sub rax, r9
+        cmp eax, MAX_MATCH
+        jge LenMaximum
+
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+;///////////////////////////////////
+
+        cmp eax, r11d
+        jg  LongerMatch
+
+        lea rsi,[r10+r11]
+
+        mov rdi, prev_ad
+        mov edx, [chainlenwmask]
+        jmp LookupLoop
+
+;;;         s->match_start = cur_match;
+;;;         best_len = len;
+;;;         if (len >= nice_match) break;
+;;;         scan_end = *(ushf*)(scan+best_len-1);
+
+LongerMatch:
+        mov r11d, eax
+        mov match_start, r8d
+        cmp eax, [nicematch]
+        jge LeaveNow
+
+        lea rsi,[r10+rax]
+
+        movzx   ebx, word ptr [r9 + rax - 1]
+        mov rdi, prev_ad
+        mov edx, [chainlenwmask]
+        jmp LookupLoop
+
+;;; Accept the current string, with the maximum possible length.
+
+LenMaximum:
+        mov r11d,MAX_MATCH
+        mov match_start, r8d
+
+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+;;; return s->lookahead;
+
+LeaveNow:
+IFDEF INFOZIP
+        mov eax,r11d
+ELSE
+        mov eax, Lookahead
+        cmp r11d, eax
+        cmovng eax, r11d
+ENDIF
+
+;;; Restore the stack and return from whence we came.
+
+
+        mov rsi,[save_rsi]
+        mov rdi,[save_rdi]
+        mov rbx,[save_rbx]
+        mov rbp,[save_rbp]
+        mov r12,[save_r12]
+        mov r13,[save_r13]
+;        mov r14,[save_r14]
+;        mov r15,[save_r15]
+
+
+        ret 0
+; please don't remove this string !
+; Your can freely use gvmat64 in any free or commercial app
+; but it is far better don't remove the string in the binary!
+    db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
+longest_match   ENDP
+
+match_init PROC
+  ret 0
+match_init ENDP
+
+
+END

Added: commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffas32.asm
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffas32.asm?rev=1084288&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffas32.asm (added)
+++ commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffas32.asm Tue Mar 22 18:36:19 2011
@@ -0,0 +1,1083 @@
+;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding
+; *
+; * inffas32.asm is derivated from inffas86.c, with translation of assembly code
+; *
+; * Copyright (C) 1995-2003 Mark Adler
+; * For conditions of distribution and use, see copyright notice in zlib.h
+; *
+; * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+; * Please use the copyright conditions above.
+; *
+; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
+; * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at
+; * the moment.  I have successfully compiled and tested this code with gcc2.96,
+; * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S
+; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
+; * enabled.  I will attempt to merge the MMX code into this version.  Newer
+; * versions of this and inffast.S can be found at
+; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
+; *
+; * 2005 : modification by Gilles Vollant
+; */
+; For Visual C++ 4.x and higher and ML 6.x and higher
+;   ml.exe is in directory \MASM611C of Win95 DDK
+;   ml.exe is also distributed in http://www.masm32.com/masmdl.htm
+;    and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/
+;
+;
+;   compile with command line option
+;   ml  /coff /Zi /c /Flinffas32.lst inffas32.asm
+
+;   if you define NO_GZIP (see inflate.h), compile with
+;   ml  /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm
+
+
+; zlib122sup is 0 fort zlib 1.2.2.1 and lower
+; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head
+;        in inflate_state in inflate.h)
+zlib1222sup      equ    8
+
+
+IFDEF GUNZIP
+  INFLATE_MODE_TYPE    equ 11
+  INFLATE_MODE_BAD     equ 26
+ELSE
+  IFNDEF NO_GUNZIP
+    INFLATE_MODE_TYPE    equ 11
+    INFLATE_MODE_BAD     equ 26
+  ELSE
+    INFLATE_MODE_TYPE    equ 3
+    INFLATE_MODE_BAD     equ 17
+  ENDIF
+ENDIF
+
+
+; 75 "inffast.S"
+;FILE "inffast.S"
+
+;;;GLOBAL _inflate_fast
+
+;;;SECTION .text
+
+
+
+	.586p
+	.mmx
+
+	name	inflate_fast_x86
+	.MODEL	FLAT
+
+_DATA			segment
+inflate_fast_use_mmx:
+	dd	1
+
+
+_TEXT			segment
+PUBLIC _inflate_fast
+
+ALIGN 4
+_inflate_fast:
+	jmp inflate_fast_entry
+
+
+
+ALIGN 4
+	db	'Fast decoding Code from Chris Anderson'
+	db	0
+
+ALIGN 4
+invalid_literal_length_code_msg:
+	db	'invalid literal/length code'
+	db	0
+
+ALIGN 4
+invalid_distance_code_msg:
+	db	'invalid distance code'
+	db	0
+
+ALIGN 4
+invalid_distance_too_far_msg:
+	db	'invalid distance too far back'
+	db	0
+
+
+ALIGN 4
+inflate_fast_mask:
+dd	0
+dd	1
+dd	3
+dd	7
+dd	15
+dd	31
+dd	63
+dd	127
+dd	255
+dd	511
+dd	1023
+dd	2047
+dd	4095
+dd	8191
+dd	16383
+dd	32767
+dd	65535
+dd	131071
+dd	262143
+dd	524287
+dd	1048575
+dd	2097151
+dd	4194303
+dd	8388607
+dd	16777215
+dd	33554431
+dd	67108863
+dd	134217727
+dd	268435455
+dd	536870911
+dd	1073741823
+dd	2147483647
+dd	4294967295
+
+
+mode_state	 equ	0	;/* state->mode	*/
+wsize_state	 equ	(32+zlib1222sup)	;/* state->wsize */
+write_state	 equ	(36+4+zlib1222sup)	;/* state->write */
+window_state	 equ	(40+4+zlib1222sup)	;/* state->window */
+hold_state	 equ	(44+4+zlib1222sup)	;/* state->hold	*/
+bits_state	 equ	(48+4+zlib1222sup)	;/* state->bits	*/
+lencode_state	 equ	(64+4+zlib1222sup)	;/* state->lencode */
+distcode_state	 equ	(68+4+zlib1222sup)	;/* state->distcode */
+lenbits_state	 equ	(72+4+zlib1222sup)	;/* state->lenbits */
+distbits_state	 equ	(76+4+zlib1222sup)	;/* state->distbits */
+
+
+;;SECTION .text
+; 205 "inffast.S"
+;GLOBAL	inflate_fast_use_mmx
+
+;SECTION .data
+
+
+; GLOBAL inflate_fast_use_mmx:object
+;.size inflate_fast_use_mmx, 4
+; 226 "inffast.S"
+;SECTION .text
+
+ALIGN 4
+inflate_fast_entry:
+	push  edi
+	push  esi
+	push  ebp
+	push  ebx
+	pushfd
+	sub  esp,64
+	cld
+
+
+
+
+	mov  esi, [esp+88]
+	mov  edi, [esi+28]
+
+
+
+
+
+
+
+	mov  edx, [esi+4]
+	mov  eax, [esi+0]
+
+	add  edx,eax
+	sub  edx,11
+
+	mov  [esp+44],eax
+	mov  [esp+20],edx
+
+	mov  ebp, [esp+92]
+	mov  ecx, [esi+16]
+	mov  ebx, [esi+12]
+
+	sub  ebp,ecx
+	neg  ebp
+	add  ebp,ebx
+
+	sub  ecx,257
+	add  ecx,ebx
+
+	mov  [esp+60],ebx
+	mov  [esp+40],ebp
+	mov  [esp+16],ecx
+; 285 "inffast.S"
+	mov  eax, [edi+lencode_state]
+	mov  ecx, [edi+distcode_state]
+
+	mov  [esp+8],eax
+	mov  [esp+12],ecx
+
+	mov  eax,1
+	mov  ecx, [edi+lenbits_state]
+	shl  eax,cl
+	dec  eax
+	mov  [esp+0],eax
+
+	mov  eax,1
+	mov  ecx, [edi+distbits_state]
+	shl  eax,cl
+	dec  eax
+	mov  [esp+4],eax
+
+	mov  eax, [edi+wsize_state]
+	mov  ecx, [edi+write_state]
+	mov  edx, [edi+window_state]
+
+	mov  [esp+52],eax
+	mov  [esp+48],ecx
+	mov  [esp+56],edx
+
+	mov  ebp, [edi+hold_state]
+	mov  ebx, [edi+bits_state]
+; 321 "inffast.S"
+	mov  esi, [esp+44]
+	mov  ecx, [esp+20]
+	cmp  ecx,esi
+	ja   L_align_long
+
+	add  ecx,11
+	sub  ecx,esi
+	mov  eax,12
+	sub  eax,ecx
+	lea  edi, [esp+28]
+	rep movsb
+	mov  ecx,eax
+	xor  eax,eax
+	rep stosb
+	lea  esi, [esp+28]
+	mov  [esp+20],esi
+	jmp  L_is_aligned
+
+
+L_align_long:
+	test  esi,3
+	jz   L_is_aligned
+	xor  eax,eax
+	mov  al, [esi]
+	inc  esi
+	mov  ecx,ebx
+	add  ebx,8
+	shl  eax,cl
+	or  ebp,eax
+	jmp L_align_long
+
+L_is_aligned:
+	mov  edi, [esp+60]
+; 366 "inffast.S"
+L_check_mmx:
+	cmp  dword ptr [inflate_fast_use_mmx],2
+	je   L_init_mmx
+	ja   L_do_loop
+
+	push  eax
+	push  ebx
+	push  ecx
+	push  edx
+	pushfd
+	mov  eax, [esp]
+	xor  dword ptr [esp],0200000h
+
+
+
+
+	popfd
+	pushfd
+	pop  edx
+	xor  edx,eax
+	jz   L_dont_use_mmx
+	xor  eax,eax
+	cpuid
+	cmp  ebx,0756e6547h
+	jne  L_dont_use_mmx
+	cmp  ecx,06c65746eh
+	jne  L_dont_use_mmx
+	cmp  edx,049656e69h
+	jne  L_dont_use_mmx
+	mov  eax,1
+	cpuid
+	shr  eax,8
+	and  eax,15
+	cmp  eax,6
+	jne  L_dont_use_mmx
+	test  edx,0800000h
+	jnz  L_use_mmx
+	jmp  L_dont_use_mmx
+L_use_mmx:
+	mov  dword ptr [inflate_fast_use_mmx],2
+	jmp  L_check_mmx_pop
+L_dont_use_mmx:
+	mov  dword ptr [inflate_fast_use_mmx],3
+L_check_mmx_pop:
+	pop  edx
+	pop  ecx
+	pop  ebx
+	pop  eax
+	jmp  L_check_mmx
+; 426 "inffast.S"
+ALIGN 4
+L_do_loop:
+; 437 "inffast.S"
+	cmp  bl,15
+	ja   L_get_length_code
+
+	xor  eax,eax
+	lodsw
+	mov  cl,bl
+	add  bl,16
+	shl  eax,cl
+	or  ebp,eax
+
+L_get_length_code:
+	mov  edx, [esp+0]
+	mov  ecx, [esp+8]
+	and  edx,ebp
+	mov  eax, [ecx+edx*4]
+
+L_dolen:
+
+
+
+
+
+
+	mov  cl,ah
+	sub  bl,ah
+	shr  ebp,cl
+
+
+
+
+
+
+	test  al,al
+	jnz   L_test_for_length_base
+
+	shr  eax,16
+	stosb
+
+L_while_test:
+
+
+	cmp  [esp+16],edi
+	jbe  L_break_loop
+
+	cmp  [esp+20],esi
+	ja   L_do_loop
+	jmp  L_break_loop
+
+L_test_for_length_base:
+; 502 "inffast.S"
+	mov  edx,eax
+	shr  edx,16
+	mov  cl,al
+
+	test  al,16
+	jz   L_test_for_second_level_length
+	and  cl,15
+	jz   L_save_len
+	cmp  bl,cl
+	jae  L_add_bits_to_len
+
+	mov  ch,cl
+	xor  eax,eax
+	lodsw
+	mov  cl,bl
+	add  bl,16
+	shl  eax,cl
+	or  ebp,eax
+	mov  cl,ch
+
+L_add_bits_to_len:
+	mov  eax,1
+	shl  eax,cl
+	dec  eax
+	sub  bl,cl
+	and  eax,ebp
+	shr  ebp,cl
+	add  edx,eax
+
+L_save_len:
+	mov  [esp+24],edx
+
+
+L_decode_distance:
+; 549 "inffast.S"
+	cmp  bl,15
+	ja   L_get_distance_code
+
+	xor  eax,eax
+	lodsw
+	mov  cl,bl
+	add  bl,16
+	shl  eax,cl
+	or  ebp,eax
+
+L_get_distance_code:
+	mov  edx, [esp+4]
+	mov  ecx, [esp+12]
+	and  edx,ebp
+	mov  eax, [ecx+edx*4]
+
+
+L_dodist:
+	mov  edx,eax
+	shr  edx,16
+	mov  cl,ah
+	sub  bl,ah
+	shr  ebp,cl
+; 584 "inffast.S"
+	mov  cl,al
+
+	test  al,16
+	jz  L_test_for_second_level_dist
+	and  cl,15
+	jz  L_check_dist_one
+	cmp  bl,cl
+	jae  L_add_bits_to_dist
+
+	mov  ch,cl
+	xor  eax,eax
+	lodsw
+	mov  cl,bl
+	add  bl,16
+	shl  eax,cl
+	or  ebp,eax
+	mov  cl,ch
+
+L_add_bits_to_dist:
+	mov  eax,1
+	shl  eax,cl
+	dec  eax
+	sub  bl,cl
+	and  eax,ebp
+	shr  ebp,cl
+	add  edx,eax
+	jmp  L_check_window
+
+L_check_window:
+; 625 "inffast.S"
+	mov  [esp+44],esi
+	mov  eax,edi
+	sub  eax, [esp+40]
+
+	cmp  eax,edx
+	jb   L_clip_window
+
+	mov  ecx, [esp+24]
+	mov  esi,edi
+	sub  esi,edx
+
+	sub  ecx,3
+	mov  al, [esi]
+	mov  [edi],al
+	mov  al, [esi+1]
+	mov  dl, [esi+2]
+	add  esi,3
+	mov  [edi+1],al
+	mov  [edi+2],dl
+	add  edi,3
+	rep movsb
+
+	mov  esi, [esp+44]
+	jmp  L_while_test
+
+ALIGN 4
+L_check_dist_one:
+	cmp  edx,1
+	jne  L_check_window
+	cmp  [esp+40],edi
+	je  L_check_window
+
+	dec  edi
+	mov  ecx, [esp+24]
+	mov  al, [edi]
+	sub  ecx,3
+
+	mov  [edi+1],al
+	mov  [edi+2],al
+	mov  [edi+3],al
+	add  edi,4
+	rep stosb
+
+	jmp  L_while_test
+
+ALIGN 4
+L_test_for_second_level_length:
+
+
+
+
+	test  al,64
+	jnz   L_test_for_end_of_block
+
+	mov  eax,1
+	shl  eax,cl
+	dec  eax
+	and  eax,ebp
+	add  eax,edx
+	mov  edx, [esp+8]
+	mov  eax, [edx+eax*4]
+	jmp  L_dolen
+
+ALIGN 4
+L_test_for_second_level_dist:
+
+
+
+
+	test  al,64
+	jnz   L_invalid_distance_code
+
+	mov  eax,1
+	shl  eax,cl
+	dec  eax
+	and  eax,ebp
+	add  eax,edx
+	mov  edx, [esp+12]
+	mov  eax, [edx+eax*4]
+	jmp  L_dodist
+
+ALIGN 4
+L_clip_window:
+; 721 "inffast.S"
+	mov  ecx,eax
+	mov  eax, [esp+52]
+	neg  ecx
+	mov  esi, [esp+56]
+
+	cmp  eax,edx
+	jb   L_invalid_distance_too_far
+
+	add  ecx,edx
+	cmp  dword ptr [esp+48],0
+	jne  L_wrap_around_window
+
+	sub  eax,ecx
+	add  esi,eax
+; 749 "inffast.S"
+	mov  eax, [esp+24]
+	cmp  eax,ecx
+	jbe  L_do_copy1
+
+	sub  eax,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,edx
+	jmp  L_do_copy1
+
+	cmp  eax,ecx
+	jbe  L_do_copy1
+
+	sub  eax,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,edx
+	jmp  L_do_copy1
+
+L_wrap_around_window:
+; 793 "inffast.S"
+	mov  eax, [esp+48]
+	cmp  ecx,eax
+	jbe  L_contiguous_in_window
+
+	add  esi, [esp+52]
+	add  esi,eax
+	sub  esi,ecx
+	sub  ecx,eax
+
+
+	mov  eax, [esp+24]
+	cmp  eax,ecx
+	jbe  L_do_copy1
+
+	sub  eax,ecx
+	rep movsb
+	mov  esi, [esp+56]
+	mov  ecx, [esp+48]
+	cmp  eax,ecx
+	jbe  L_do_copy1
+
+	sub  eax,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,edx
+	jmp  L_do_copy1
+
+L_contiguous_in_window:
+; 836 "inffast.S"
+	add  esi,eax
+	sub  esi,ecx
+
+
+	mov  eax, [esp+24]
+	cmp  eax,ecx
+	jbe  L_do_copy1
+
+	sub  eax,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,edx
+
+L_do_copy1:
+; 862 "inffast.S"
+	mov  ecx,eax
+	rep movsb
+
+	mov  esi, [esp+44]
+	jmp  L_while_test
+; 878 "inffast.S"
+ALIGN 4
+L_init_mmx:
+	emms
+
+
+
+
+
+	movd mm0,ebp
+	mov  ebp,ebx
+; 896 "inffast.S"
+	movd mm4,dword ptr [esp+0]
+	movq mm3,mm4
+	movd mm5,dword ptr [esp+4]
+	movq mm2,mm5
+	pxor mm1,mm1
+	mov  ebx, [esp+8]
+	jmp  L_do_loop_mmx
+
+ALIGN 4
+L_do_loop_mmx:
+	psrlq mm0,mm1
+
+	cmp  ebp,32
+	ja  L_get_length_code_mmx
+
+	movd mm6,ebp
+	movd mm7,dword ptr [esi]
+	add  esi,4
+	psllq mm7,mm6
+	add  ebp,32
+	por mm0,mm7
+
+L_get_length_code_mmx:
+	pand mm4,mm0
+	movd eax,mm4
+	movq mm4,mm3
+	mov  eax, [ebx+eax*4]
+
+L_dolen_mmx:
+	movzx  ecx,ah
+	movd mm1,ecx
+	sub  ebp,ecx
+
+	test  al,al
+	jnz L_test_for_length_base_mmx
+
+	shr  eax,16
+	stosb
+
+L_while_test_mmx:
+
+
+	cmp  [esp+16],edi
+	jbe L_break_loop
+
+	cmp  [esp+20],esi
+	ja L_do_loop_mmx
+	jmp L_break_loop
+
+L_test_for_length_base_mmx:
+
+	mov  edx,eax
+	shr  edx,16
+
+	test  al,16
+	jz  L_test_for_second_level_length_mmx
+	and  eax,15
+	jz L_decode_distance_mmx
+
+	psrlq mm0,mm1
+	movd mm1,eax
+	movd ecx,mm0
+	sub  ebp,eax
+	and  ecx, [inflate_fast_mask+eax*4]
+	add  edx,ecx
+
+L_decode_distance_mmx:
+	psrlq mm0,mm1
+
+	cmp  ebp,32
+	ja L_get_dist_code_mmx
+
+	movd mm6,ebp
+	movd mm7,dword ptr [esi]
+	add  esi,4
+	psllq mm7,mm6
+	add  ebp,32
+	por mm0,mm7
+
+L_get_dist_code_mmx:
+	mov  ebx, [esp+12]
+	pand mm5,mm0
+	movd eax,mm5
+	movq mm5,mm2
+	mov  eax, [ebx+eax*4]
+
+L_dodist_mmx:
+
+	movzx  ecx,ah
+	mov  ebx,eax
+	shr  ebx,16
+	sub  ebp,ecx
+	movd mm1,ecx
+
+	test  al,16
+	jz L_test_for_second_level_dist_mmx
+	and  eax,15
+	jz L_check_dist_one_mmx
+
+L_add_bits_to_dist_mmx:
+	psrlq mm0,mm1
+	movd mm1,eax
+	movd ecx,mm0
+	sub  ebp,eax
+	and  ecx, [inflate_fast_mask+eax*4]
+	add  ebx,ecx
+
+L_check_window_mmx:
+	mov  [esp+44],esi
+	mov  eax,edi
+	sub  eax, [esp+40]
+
+	cmp  eax,ebx
+	jb L_clip_window_mmx
+
+	mov  ecx,edx
+	mov  esi,edi
+	sub  esi,ebx
+
+	sub  ecx,3
+	mov  al, [esi]
+	mov  [edi],al
+	mov  al, [esi+1]
+	mov  dl, [esi+2]
+	add  esi,3
+	mov  [edi+1],al
+	mov  [edi+2],dl
+	add  edi,3
+	rep movsb
+
+	mov  esi, [esp+44]
+	mov  ebx, [esp+8]
+	jmp  L_while_test_mmx
+
+ALIGN 4
+L_check_dist_one_mmx:
+	cmp  ebx,1
+	jne  L_check_window_mmx
+	cmp  [esp+40],edi
+	je   L_check_window_mmx
+
+	dec  edi
+	mov  ecx,edx
+	mov  al, [edi]
+	sub  ecx,3
+
+	mov  [edi+1],al
+	mov  [edi+2],al
+	mov  [edi+3],al
+	add  edi,4
+	rep stosb
+
+	mov  ebx, [esp+8]
+	jmp  L_while_test_mmx
+
+ALIGN 4
+L_test_for_second_level_length_mmx:
+	test  al,64
+	jnz L_test_for_end_of_block
+
+	and  eax,15
+	psrlq mm0,mm1
+	movd ecx,mm0
+	and  ecx, [inflate_fast_mask+eax*4]
+	add  ecx,edx
+	mov  eax, [ebx+ecx*4]
+	jmp L_dolen_mmx
+
+ALIGN 4
+L_test_for_second_level_dist_mmx:
+	test  al,64
+	jnz L_invalid_distance_code
+
+	and  eax,15
+	psrlq mm0,mm1
+	movd ecx,mm0
+	and  ecx, [inflate_fast_mask+eax*4]
+	mov  eax, [esp+12]
+	add  ecx,ebx
+	mov  eax, [eax+ecx*4]
+	jmp  L_dodist_mmx
+
+ALIGN 4
+L_clip_window_mmx:
+
+	mov  ecx,eax
+	mov  eax, [esp+52]
+	neg  ecx
+	mov  esi, [esp+56]
+
+	cmp  eax,ebx
+	jb  L_invalid_distance_too_far
+
+	add  ecx,ebx
+	cmp  dword ptr [esp+48],0
+	jne  L_wrap_around_window_mmx
+
+	sub  eax,ecx
+	add  esi,eax
+
+	cmp  edx,ecx
+	jbe  L_do_copy1_mmx
+
+	sub  edx,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,ebx
+	jmp  L_do_copy1_mmx
+
+	cmp  edx,ecx
+	jbe  L_do_copy1_mmx
+
+	sub  edx,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,ebx
+	jmp  L_do_copy1_mmx
+
+L_wrap_around_window_mmx:
+
+	mov  eax, [esp+48]
+	cmp  ecx,eax
+	jbe  L_contiguous_in_window_mmx
+
+	add  esi, [esp+52]
+	add  esi,eax
+	sub  esi,ecx
+	sub  ecx,eax
+
+
+	cmp  edx,ecx
+	jbe  L_do_copy1_mmx
+
+	sub  edx,ecx
+	rep movsb
+	mov  esi, [esp+56]
+	mov  ecx, [esp+48]
+	cmp  edx,ecx
+	jbe  L_do_copy1_mmx
+
+	sub  edx,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,ebx
+	jmp  L_do_copy1_mmx
+
+L_contiguous_in_window_mmx:
+
+	add  esi,eax
+	sub  esi,ecx
+
+
+	cmp  edx,ecx
+	jbe  L_do_copy1_mmx
+
+	sub  edx,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,ebx
+
+L_do_copy1_mmx:
+
+
+	mov  ecx,edx
+	rep movsb
+
+	mov  esi, [esp+44]
+	mov  ebx, [esp+8]
+	jmp  L_while_test_mmx
+; 1174 "inffast.S"
+L_invalid_distance_code:
+
+
+
+
+
+	mov  ecx, invalid_distance_code_msg
+	mov  edx,INFLATE_MODE_BAD
+	jmp  L_update_stream_state
+
+L_test_for_end_of_block:
+
+
+
+
+
+	test  al,32
+	jz  L_invalid_literal_length_code
+
+	mov  ecx,0
+	mov  edx,INFLATE_MODE_TYPE
+	jmp  L_update_stream_state
+
+L_invalid_literal_length_code:
+
+
+
+
+
+	mov  ecx, invalid_literal_length_code_msg
+	mov  edx,INFLATE_MODE_BAD
+	jmp  L_update_stream_state
+
+L_invalid_distance_too_far:
+
+
+
+	mov  esi, [esp+44]
+	mov  ecx, invalid_distance_too_far_msg
+	mov  edx,INFLATE_MODE_BAD
+	jmp  L_update_stream_state
+
+L_update_stream_state:
+
+	mov  eax, [esp+88]
+	test  ecx,ecx
+	jz  L_skip_msg
+	mov  [eax+24],ecx
+L_skip_msg:
+	mov  eax, [eax+28]
+	mov  [eax+mode_state],edx
+	jmp  L_break_loop
+
+ALIGN 4
+L_break_loop:
+; 1243 "inffast.S"
+	cmp  dword ptr [inflate_fast_use_mmx],2
+	jne  L_update_next_in
+
+
+
+	mov  ebx,ebp
+
+L_update_next_in:
+; 1266 "inffast.S"
+	mov  eax, [esp+88]
+	mov  ecx,ebx
+	mov  edx, [eax+28]
+	shr  ecx,3
+	sub  esi,ecx
+	shl  ecx,3
+	sub  ebx,ecx
+	mov  [eax+12],edi
+	mov  [edx+bits_state],ebx
+	mov  ecx,ebx
+
+	lea  ebx, [esp+28]
+	cmp  [esp+20],ebx
+	jne  L_buf_not_used
+
+	sub  esi,ebx
+	mov  ebx, [eax+0]
+	mov  [esp+20],ebx
+	add  esi,ebx
+	mov  ebx, [eax+4]
+	sub  ebx,11
+	add  [esp+20],ebx
+
+L_buf_not_used:
+	mov  [eax+0],esi
+
+	mov  ebx,1
+	shl  ebx,cl
+	dec  ebx
+
+
+
+
+
+	cmp  dword ptr [inflate_fast_use_mmx],2
+	jne  L_update_hold
+
+
+
+	psrlq mm0,mm1
+	movd ebp,mm0
+
+	emms
+
+L_update_hold:
+
+
+
+	and  ebp,ebx
+	mov  [edx+hold_state],ebp
+
+
+
+
+	mov  ebx, [esp+20]
+	cmp  ebx,esi
+	jbe  L_last_is_smaller
+
+	sub  ebx,esi
+	add  ebx,11
+	mov  [eax+4],ebx
+	jmp  L_fixup_out
+L_last_is_smaller:
+	sub  esi,ebx
+	neg  esi
+	add  esi,11
+	mov  [eax+4],esi
+
+
+
+
+L_fixup_out:
+
+	mov  ebx, [esp+16]
+	cmp  ebx,edi
+	jbe  L_end_is_smaller
+
+	sub  ebx,edi
+	add  ebx,257
+	mov  [eax+16],ebx
+	jmp  L_done
+L_end_is_smaller:
+	sub  edi,ebx
+	neg  edi
+	add  edi,257
+	mov  [eax+16],edi
+
+
+
+
+
+L_done:
+	add  esp,64
+	popfd
+	pop  ebx
+	pop  ebp
+	pop  esi
+	pop  edi
+	ret
+
+_TEXT	ends
+end

Added: commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffas8664.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffas8664.c?rev=1084288&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffas8664.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffas8664.c Tue Mar 22 18:36:19 2011
@@ -0,0 +1,186 @@
+/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding
+ * version for AMD64 on Windows using Microsoft C compiler
+ *
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+ * Please use the copyright conditions above.
+ *
+ * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant
+ *
+ * inffas8664.c call function inffas8664fnc in inffasx64.asm
+ *  inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
+ *
+ * Dec-29-2003 -- I added AMD64 inflate asm support.  This version is also
+ * slightly quicker on x86 systems because, instead of using rep movsb to copy
+ * data, it uses rep movsw, which moves data in 2-byte chunks instead of single
+ * bytes.  I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
+ * from http://fedora.linux.duke.edu/fc1_x86_64
+ * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
+ * 1GB ram.  The 64-bit version is about 4% faster than the 32-bit version,
+ * when decompressing mozilla-source-1.3.tar.gz.
+ *
+ * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
+ * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at
+ * the moment.  I have successfully compiled and tested this code with gcc2.96,
+ * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S
+ * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
+ * enabled.  I will attempt to merge the MMX code into this version.  Newer
+ * versions of this and inffast.S can be found at
+ * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
+ *
+ */
+
+#include <stdio.h>
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* Mark Adler's comments from inffast.c: */
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+
+
+
+    typedef struct inffast_ar {
+/* 64   32                               x86  x86_64 */
+/* ar offset                              register */
+/*  0    0 */ void *esp;                /* esp save */
+/*  8    4 */ void *ebp;                /* ebp save */
+/* 16    8 */ unsigned char FAR *in;    /* esi rsi  local strm->next_in */
+/* 24   12 */ unsigned char FAR *last;  /*     r9   while in < last */
+/* 32   16 */ unsigned char FAR *out;   /* edi rdi  local strm->next_out */
+/* 40   20 */ unsigned char FAR *beg;   /*          inflate()'s init next_out */
+/* 48   24 */ unsigned char FAR *end;   /*     r10  while out < end */
+/* 56   28 */ unsigned char FAR *window;/*          size of window, wsize!=0 */
+/* 64   32 */ code const FAR *lcode;    /* ebp rbp  local strm->lencode */
+/* 72   36 */ code const FAR *dcode;    /*     r11  local strm->distcode */
+/* 80   40 */ size_t /*unsigned long */hold;       /* edx rdx  local strm->hold */
+/* 88   44 */ unsigned bits;            /* ebx rbx  local strm->bits */
+/* 92   48 */ unsigned wsize;           /*          window size */
+/* 96   52 */ unsigned write;           /*          window write index */
+/*100   56 */ unsigned lmask;           /*     r12  mask for lcode */
+/*104   60 */ unsigned dmask;           /*     r13  mask for dcode */
+/*108   64 */ unsigned len;             /*     r14  match length */
+/*112   68 */ unsigned dist;            /*     r15  match distance */
+/*116   72 */ unsigned status;          /*          set when state chng*/
+    } type_ar;
+#ifdef ASMINF
+
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    type_ar ar;
+    void inffas8664fnc(struct inffast_ar * par);
+
+
+
+#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64))
+#define PAD_AVAIL_IN 6
+#define PAD_AVAIL_OUT 258
+#else
+#define PAD_AVAIL_IN 5
+#define PAD_AVAIL_OUT 257
+#endif
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+
+    ar.in = strm->next_in;
+    ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
+    ar.out = strm->next_out;
+    ar.beg = ar.out - (start - strm->avail_out);
+    ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
+    ar.wsize = state->wsize;
+    ar.write = state->wnext;
+    ar.window = state->window;
+    ar.hold = state->hold;
+    ar.bits = state->bits;
+    ar.lcode = state->lencode;
+    ar.dcode = state->distcode;
+    ar.lmask = (1U << state->lenbits) - 1;
+    ar.dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+
+    /* align in on 1/2 hold size boundary */
+    while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
+        ar.hold += (unsigned long)*ar.in++ << ar.bits;
+        ar.bits += 8;
+    }
+
+    inffas8664fnc(&ar);
+
+    if (ar.status > 1) {
+        if (ar.status == 2)
+            strm->msg = "invalid literal/length code";
+        else if (ar.status == 3)
+            strm->msg = "invalid distance code";
+        else
+            strm->msg = "invalid distance too far back";
+        state->mode = BAD;
+    }
+    else if ( ar.status == 1 ) {
+        state->mode = TYPE;
+    }
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    ar.len = ar.bits >> 3;
+    ar.in -= ar.len;
+    ar.bits -= ar.len << 3;
+    ar.hold &= (1U << ar.bits) - 1;
+
+    /* update state and return */
+    strm->next_in = ar.in;
+    strm->next_out = ar.out;
+    strm->avail_in = (unsigned)(ar.in < ar.last ?
+                                PAD_AVAIL_IN + (ar.last - ar.in) :
+                                PAD_AVAIL_IN - (ar.in - ar.last));
+    strm->avail_out = (unsigned)(ar.out < ar.end ?
+                                 PAD_AVAIL_OUT + (ar.end - ar.out) :
+                                 PAD_AVAIL_OUT - (ar.out - ar.end));
+    state->hold = (unsigned long)ar.hold;
+    state->bits = ar.bits;
+    return;
+}
+
+#endif

Propchange: commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffas8664.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffasx64.asm
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffasx64.asm?rev=1084288&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffasx64.asm (added)
+++ commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/inffasx64.asm Tue Mar 22 18:36:19 2011
@@ -0,0 +1,396 @@
+; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding
+; version for AMD64 on Windows using Microsoft C compiler
+;
+; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
+; inffasx64.asm is called by inffas8664.c, which contain more info.
+
+
+; to compile this file, I use option
+;   ml64.exe /Flinffasx64 /c /Zi inffasx64.asm
+;   with Microsoft Macro Assembler (x64) for AMD64
+;
+
+; This file compile with Microsoft Macro Assembler (x64) for AMD64
+;
+;   ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK
+;
+;   (you can get Windows WDK with ml64 for AMD64 from
+;      http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)
+;
+
+
+.code
+inffas8664fnc PROC
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+;   rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch.
+
+
+	mov [rsp-8],rsi
+	mov [rsp-16],rdi
+	mov [rsp-24],r12
+	mov [rsp-32],r13
+	mov [rsp-40],r14
+	mov [rsp-48],r15
+	mov [rsp-56],rbx
+
+	mov rax,rcx
+
+	mov	[rax+8], rbp       ; /* save regs rbp and rsp */
+	mov	[rax], rsp
+
+	mov	rsp, rax          ; /* make rsp point to &ar */
+
+	mov	rsi, [rsp+16]      ; /* rsi  = in */
+	mov	rdi, [rsp+32]      ; /* rdi  = out */
+	mov	r9, [rsp+24]       ; /* r9   = last */
+	mov	r10, [rsp+48]      ; /* r10  = end */
+	mov	rbp, [rsp+64]      ; /* rbp  = lcode */
+	mov	r11, [rsp+72]      ; /* r11  = dcode */
+	mov	rdx, [rsp+80]      ; /* rdx  = hold */
+	mov	ebx, [rsp+88]      ; /* ebx  = bits */
+	mov	r12d, [rsp+100]    ; /* r12d = lmask */
+	mov	r13d, [rsp+104]    ; /* r13d = dmask */
+                                          ; /* r14d = len */
+                                          ; /* r15d = dist */
+
+
+	cld
+	cmp	r10, rdi
+	je	L_one_time           ; /* if only one decode left */
+	cmp	r9, rsi
+
+    jne L_do_loop
+
+
+L_one_time:
+	mov	r8, r12           ; /* r8 = lmask */
+	cmp	bl, 32
+	ja	L_get_length_code_one_time
+
+	lodsd                         ; /* eax = *(uint *)in++ */
+	mov	cl, bl            ; /* cl = bits, needs it for shifting */
+	add	bl, 32             ; /* bits += 32 */
+	shl	rax, cl
+	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */
+	jmp	L_get_length_code_one_time
+
+ALIGN 4
+L_while_test:
+	cmp	r10, rdi
+	jbe	L_break_loop
+	cmp	r9, rsi
+	jbe	L_break_loop
+
+L_do_loop:
+	mov	r8, r12           ; /* r8 = lmask */
+	cmp	bl, 32
+	ja	L_get_length_code    ; /* if (32 < bits) */
+
+	lodsd                         ; /* eax = *(uint *)in++ */
+	mov	cl, bl            ; /* cl = bits, needs it for shifting */
+	add	bl, 32             ; /* bits += 32 */
+	shl	rax, cl
+	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */
+
+L_get_length_code:
+	and	r8, rdx            ; /* r8 &= hold */
+	mov	eax, [rbp+r8*4]  ; /* eax = lcode[hold & lmask] */
+
+	mov	cl, ah            ; /* cl = this.bits */
+	sub	bl, ah            ; /* bits -= this.bits */
+	shr	rdx, cl           ; /* hold >>= this.bits */
+
+	test	al, al
+	jnz	L_test_for_length_base ; /* if (op != 0) 45.7% */
+
+	mov	r8, r12            ; /* r8 = lmask */
+	shr	eax, 16            ; /* output this.val char */
+	stosb
+
+L_get_length_code_one_time:
+	and	r8, rdx            ; /* r8 &= hold */
+	mov	eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */
+
+L_dolen:
+	mov	cl, ah            ; /* cl = this.bits */
+	sub	bl, ah            ; /* bits -= this.bits */
+	shr	rdx, cl           ; /* hold >>= this.bits */
+
+	test	al, al
+	jnz	L_test_for_length_base ; /* if (op != 0) 45.7% */
+
+	shr	eax, 16            ; /* output this.val char */
+	stosb
+	jmp	L_while_test
+
+ALIGN 4
+L_test_for_length_base:
+	mov	r14d, eax         ; /* len = this */
+	shr	r14d, 16           ; /* len = this.val */
+	mov	cl, al
+
+	test	al, 16
+	jz	L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */
+	and	cl, 15             ; /* op &= 15 */
+	jz	L_decode_distance    ; /* if (!op) */
+
+L_add_bits_to_len:
+	sub	bl, cl
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax
+	and	eax, edx          ; /* eax &= hold */
+	shr	rdx, cl
+	add	r14d, eax         ; /* len += hold & mask[op] */
+
+L_decode_distance:
+	mov	r8, r13           ; /* r8 = dmask */
+	cmp	bl, 32
+	ja	L_get_distance_code  ; /* if (32 < bits) */
+
+	lodsd                         ; /* eax = *(uint *)in++ */
+	mov	cl, bl            ; /* cl = bits, needs it for shifting */
+	add	bl, 32             ; /* bits += 32 */
+	shl	rax, cl
+	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */
+
+L_get_distance_code:
+	and	r8, rdx           ; /* r8 &= hold */
+	mov	eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */
+
+L_dodist:
+	mov	r15d, eax         ; /* dist = this */
+	shr	r15d, 16           ; /* dist = this.val */
+	mov	cl, ah
+	sub	bl, ah            ; /* bits -= this.bits */
+	shr	rdx, cl           ; /* hold >>= this.bits */
+	mov	cl, al            ; /* cl = this.op */
+
+	test	al, 16             ; /* if ((op & 16) == 0) */
+	jz	L_test_for_second_level_dist
+	and	cl, 15             ; /* op &= 15 */
+	jz	L_check_dist_one
+
+L_add_bits_to_dist:
+	sub	bl, cl
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax                 ; /* (1 << op) - 1 */
+	and	eax, edx          ; /* eax &= hold */
+	shr	rdx, cl
+	add	r15d, eax         ; /* dist += hold & ((1 << op) - 1) */
+
+L_check_window:
+	mov	r8, rsi           ; /* save in so from can use it's reg */
+	mov	rax, rdi
+	sub	rax, [rsp+40]      ; /* nbytes = out - beg */
+
+	cmp	eax, r15d
+	jb	L_clip_window        ; /* if (dist > nbytes) 4.2% */
+
+	mov	ecx, r14d         ; /* ecx = len */
+	mov	rsi, rdi
+	sub	rsi, r15          ; /* from = out - dist */
+
+	sar	ecx, 1
+	jnc	L_copy_two           ; /* if len % 2 == 0 */
+
+	rep     movsw
+	mov	al, [rsi]
+	mov	[rdi], al
+	inc	rdi
+
+	mov	rsi, r8           ; /* move in back to %rsi, toss from */
+	jmp	L_while_test
+
+L_copy_two:
+	rep     movsw
+	mov	rsi, r8           ; /* move in back to %rsi, toss from */
+	jmp	L_while_test
+
+ALIGN 4
+L_check_dist_one:
+	cmp	r15d, 1            ; /* if dist 1, is a memset */
+	jne	L_check_window
+	cmp	[rsp+40], rdi      ; /* if out == beg, outside window */
+	je	L_check_window
+
+	mov	ecx, r14d         ; /* ecx = len */
+	mov	al, [rdi-1]
+	mov	ah, al
+
+	sar	ecx, 1
+	jnc	L_set_two
+	mov	[rdi], al
+	inc	rdi
+
+L_set_two:
+	rep     stosw
+	jmp	L_while_test
+
+ALIGN 4
+L_test_for_second_level_length:
+	test	al, 64
+	jnz	L_test_for_end_of_block ; /* if ((op & 64) != 0) */
+
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax
+	and	eax, edx         ; /* eax &= hold */
+	add	eax, r14d        ; /* eax += len */
+	mov	eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/
+	jmp	L_dolen
+
+ALIGN 4
+L_test_for_second_level_dist:
+	test	al, 64
+	jnz	L_invalid_distance_code ; /* if ((op & 64) != 0) */
+
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax
+	and	eax, edx         ; /* eax &= hold */
+	add	eax, r15d        ; /* eax += dist */
+	mov	eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/
+	jmp	L_dodist
+
+ALIGN 4
+L_clip_window:
+	mov	ecx, eax         ; /* ecx = nbytes */
+	mov	eax, [rsp+92]     ; /* eax = wsize, prepare for dist cmp */
+	neg	ecx                ; /* nbytes = -nbytes */
+
+	cmp	eax, r15d
+	jb	L_invalid_distance_too_far ; /* if (dist > wsize) */
+
+	add	ecx, r15d         ; /* nbytes = dist - nbytes */
+	cmp	dword ptr [rsp+96], 0
+	jne	L_wrap_around_window ; /* if (write != 0) */
+
+	mov	rsi, [rsp+56]     ; /* from  = window */
+	sub	eax, ecx         ; /* eax  -= nbytes */
+	add	rsi, rax         ; /* from += wsize - nbytes */
+
+	mov	eax, r14d        ; /* eax = len */
+	cmp	r14d, ecx
+	jbe	L_do_copy           ; /* if (nbytes >= len) */
+
+	sub	eax, ecx         ; /* eax -= nbytes */
+	rep     movsb
+	mov	rsi, rdi
+	sub	rsi, r15         ; /* from = &out[ -dist ] */
+	jmp	L_do_copy
+
+ALIGN 4
+L_wrap_around_window:
+	mov	eax, [rsp+96]     ; /* eax = write */
+	cmp	ecx, eax
+	jbe	L_contiguous_in_window ; /* if (write >= nbytes) */
+
+	mov	esi, [rsp+92]     ; /* from  = wsize */
+	add	rsi, [rsp+56]     ; /* from += window */
+	add	rsi, rax         ; /* from += write */
+	sub	rsi, rcx         ; /* from -= nbytes */
+	sub	ecx, eax         ; /* nbytes -= write */
+
+	mov	eax, r14d        ; /* eax = len */
+	cmp	eax, ecx
+	jbe	L_do_copy           ; /* if (nbytes >= len) */
+
+	sub	eax, ecx         ; /* len -= nbytes */
+	rep     movsb
+	mov	rsi, [rsp+56]     ; /* from = window */
+	mov	ecx, [rsp+96]     ; /* nbytes = write */
+	cmp	eax, ecx
+	jbe	L_do_copy           ; /* if (nbytes >= len) */
+
+	sub	eax, ecx         ; /* len -= nbytes */
+	rep     movsb
+	mov	rsi, rdi
+	sub	rsi, r15         ; /* from = out - dist */
+	jmp	L_do_copy
+
+ALIGN 4
+L_contiguous_in_window:
+	mov	rsi, [rsp+56]     ; /* rsi = window */
+	add	rsi, rax
+	sub	rsi, rcx         ; /* from += write - nbytes */
+
+	mov	eax, r14d        ; /* eax = len */
+	cmp	eax, ecx
+	jbe	L_do_copy           ; /* if (nbytes >= len) */
+
+	sub	eax, ecx         ; /* len -= nbytes */
+	rep     movsb
+	mov	rsi, rdi
+	sub	rsi, r15         ; /* from = out - dist */
+	jmp	L_do_copy           ; /* if (nbytes >= len) */
+
+ALIGN 4
+L_do_copy:
+	mov	ecx, eax         ; /* ecx = len */
+	rep     movsb
+
+	mov	rsi, r8          ; /* move in back to %esi, toss from */
+	jmp	L_while_test
+
+L_test_for_end_of_block:
+	test	al, 32
+	jz	L_invalid_literal_length_code
+	mov	dword ptr [rsp+116], 1
+	jmp	L_break_loop_with_status
+
+L_invalid_literal_length_code:
+	mov	dword ptr [rsp+116], 2
+	jmp	L_break_loop_with_status
+
+L_invalid_distance_code:
+	mov	dword ptr [rsp+116], 3
+	jmp	L_break_loop_with_status
+
+L_invalid_distance_too_far:
+	mov	dword ptr [rsp+116], 4
+	jmp	L_break_loop_with_status
+
+L_break_loop:
+	mov	dword ptr [rsp+116], 0
+
+L_break_loop_with_status:
+; /* put in, out, bits, and hold back into ar and pop esp */
+	mov	[rsp+16], rsi     ; /* in */
+	mov	[rsp+32], rdi     ; /* out */
+	mov	[rsp+88], ebx     ; /* bits */
+	mov	[rsp+80], rdx     ; /* hold */
+
+	mov	rax, [rsp]       ; /* restore rbp and rsp */
+	mov	rbp, [rsp+8]
+	mov	rsp, rax
+
+
+
+	mov rsi,[rsp-8]
+	mov rdi,[rsp-16]
+	mov r12,[rsp-24]
+	mov r13,[rsp-32]
+	mov r14,[rsp-40]
+	mov r15,[rsp-48]
+	mov rbx,[rsp-56]
+
+    ret 0
+;          :
+;          : "m" (ar)
+;          : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
+;            "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
+;    );
+
+inffas8664fnc 	ENDP
+;_TEXT	ENDS
+END

Added: commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/match686.asm
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/match686.asm?rev=1084288&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/match686.asm (added)
+++ commons/sandbox/runtime/trunk/src/main/native/srclib/zlib/win32/match686.asm Tue Mar 22 18:36:19 2011
@@ -0,0 +1,478 @@
+; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86
+; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+; File written by Gilles Vollant, by converting match686.S from Brian Raiter
+; for MASM. This is as assembly version of longest_match
+;  from Jean-loup Gailly in deflate.c
+;
+;         http://www.zlib.net
+;         http://www.winimage.com/zLibDll
+;         http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; For Visual C++ 4.x and higher and ML 6.x and higher
+;   ml.exe is distributed in
+;  http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64
+;
+; this file contain two implementation of longest_match
+;
+;  this longest_match was written by Brian raiter (1998), optimized for Pentium Pro
+;   (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom)
+;
+;  for using an assembly version of longest_match, you need define ASMV in project
+;
+;    compile the asm file running
+;           ml /coff /Zi /c /Flmatch686.lst match686.asm
+;    and do not include match686.obj in your project
+;
+; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for
+;  Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor
+;  with autoselect (with cpu detection code)
+;  if you want support the old pentium optimization, you can still use these version
+;
+; this file is not optimized for old pentium, but it compatible with all x86 32 bits
+; processor (starting 80386)
+;
+;
+; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2
+
+;uInt longest_match(s, cur_match)
+;    deflate_state *s;
+;    IPos cur_match;                             /* current match */
+
+    NbStack         equ     76
+    cur_match       equ     dword ptr[esp+NbStack-0]
+    str_s           equ     dword ptr[esp+NbStack-4]
+; 5 dword on top (ret,ebp,esi,edi,ebx)
+    adrret          equ     dword ptr[esp+NbStack-8]
+    pushebp         equ     dword ptr[esp+NbStack-12]
+    pushedi         equ     dword ptr[esp+NbStack-16]
+    pushesi         equ     dword ptr[esp+NbStack-20]
+    pushebx         equ     dword ptr[esp+NbStack-24]
+
+    chain_length    equ     dword ptr [esp+NbStack-28]
+    limit           equ     dword ptr [esp+NbStack-32]
+    best_len        equ     dword ptr [esp+NbStack-36]
+    window          equ     dword ptr [esp+NbStack-40]
+    prev            equ     dword ptr [esp+NbStack-44]
+    scan_start      equ      word ptr [esp+NbStack-48]
+    wmask           equ     dword ptr [esp+NbStack-52]
+    match_start_ptr equ     dword ptr [esp+NbStack-56]
+    nice_match      equ     dword ptr [esp+NbStack-60]
+    scan            equ     dword ptr [esp+NbStack-64]
+
+    windowlen       equ     dword ptr [esp+NbStack-68]
+    match_start     equ     dword ptr [esp+NbStack-72]
+    strend          equ     dword ptr [esp+NbStack-76]
+    NbStackAdd      equ     (NbStack-24)
+
+    .386p
+
+    name    gvmatch
+    .MODEL  FLAT
+
+
+
+;  all the +zlib1222add offsets are due to the addition of fields
+;  in zlib in the deflate_state structure since the asm code was first written
+;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+
+    zlib1222add         equ     8
+
+;  Note : these value are good with a 8 bytes boundary pack structure
+    dep_chain_length    equ     74h+zlib1222add
+    dep_window          equ     30h+zlib1222add
+    dep_strstart        equ     64h+zlib1222add
+    dep_prev_length     equ     70h+zlib1222add
+    dep_nice_match      equ     88h+zlib1222add
+    dep_w_size          equ     24h+zlib1222add
+    dep_prev            equ     38h+zlib1222add
+    dep_w_mask          equ     2ch+zlib1222add
+    dep_good_match      equ     84h+zlib1222add
+    dep_match_start     equ     68h+zlib1222add
+    dep_lookahead       equ     6ch+zlib1222add
+
+
+_TEXT                   segment
+
+IFDEF NOUNDERLINE
+            public  longest_match
+            public  match_init
+ELSE
+            public  _longest_match
+            public  _match_init
+ENDIF
+
+    MAX_MATCH           equ     258
+    MIN_MATCH           equ     3
+    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)
+
+
+
+MAX_MATCH       equ     258
+MIN_MATCH       equ     3
+MIN_LOOKAHEAD   equ     (MAX_MATCH + MIN_MATCH + 1)
+MAX_MATCH_8_     equ     ((MAX_MATCH + 7) AND 0FFF0h)
+
+
+;;; stack frame offsets
+
+chainlenwmask   equ  esp + 0    ; high word: current chain len
+                    ; low word: s->wmask
+window      equ  esp + 4    ; local copy of s->window
+windowbestlen   equ  esp + 8    ; s->window + bestlen
+scanstart   equ  esp + 16   ; first two bytes of string
+scanend     equ  esp + 12   ; last two bytes of string
+scanalign   equ  esp + 20   ; dword-misalignment of string
+nicematch   equ  esp + 24   ; a good enough match size
+bestlen     equ  esp + 28   ; size of best match so far
+scan        equ  esp + 32   ; ptr to string wanting match
+
+LocalVarsSize   equ 36
+;   saved ebx   byte esp + 36
+;   saved edi   byte esp + 40
+;   saved esi   byte esp + 44
+;   saved ebp   byte esp + 48
+;   return address  byte esp + 52
+deflatestate    equ  esp + 56   ; the function arguments
+curmatch    equ  esp + 60
+
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+dsWSize     equ 36+zlib1222add
+dsWMask     equ 44+zlib1222add
+dsWindow    equ 48+zlib1222add
+dsPrev      equ 56+zlib1222add
+dsMatchLen  equ 88+zlib1222add
+dsPrevMatch equ 92+zlib1222add
+dsStrStart  equ 100+zlib1222add
+dsMatchStart    equ 104+zlib1222add
+dsLookahead equ 108+zlib1222add
+dsPrevLen   equ 112+zlib1222add
+dsMaxChainLen   equ 116+zlib1222add
+dsGoodMatch equ 132+zlib1222add
+dsNiceMatch equ 136+zlib1222add
+
+
+;;; match686.asm -- Pentium-Pro-optimized version of longest_match()
+;;; Written for zlib 1.1.2
+;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
+;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
+;;;
+;;
+;;  This software is provided 'as-is', without any express or implied
+;;  warranty.  In no event will the authors be held liable for any damages
+;;  arising from the use of this software.
+;;
+;;  Permission is granted to anyone to use this software for any purpose,
+;;  including commercial applications, and to alter it and redistribute it
+;;  freely, subject to the following restrictions:
+;;
+;;  1. The origin of this software must not be misrepresented; you must not
+;;     claim that you wrote the original software. If you use this software
+;;     in a product, an acknowledgment in the product documentation would be
+;;     appreciated but is not required.
+;;  2. Altered source versions must be plainly marked as such, and must not be
+;;     misrepresented as being the original software
+;;  3. This notice may not be removed or altered from any source distribution.
+;;
+
+;GLOBAL _longest_match, _match_init
+
+
+;SECTION    .text
+
+;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
+
+;_longest_match:
+    IFDEF NOUNDERLINE
+    longest_match       proc near
+    ELSE
+    _longest_match      proc near
+    ENDIF
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+        push    ebp
+        push    edi
+        push    esi
+        push    ebx
+        sub esp, LocalVarsSize
+
+;;; Retrieve the function arguments. ecx will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+        mov edx, [deflatestate]
+        mov ecx, [curmatch]
+
+;;; uInt wmask = s->w_mask;
+;;; unsigned chain_length = s->max_chain_length;
+;;; if (s->prev_length >= s->good_match) {
+;;;     chain_length >>= 2;
+;;; }
+
+        mov eax, [edx + dsPrevLen]
+        mov ebx, [edx + dsGoodMatch]
+        cmp eax, ebx
+        mov eax, [edx + dsWMask]
+        mov ebx, [edx + dsMaxChainLen]
+        jl  LastMatchGood
+        shr ebx, 2
+LastMatchGood:
+
+;;; chainlen is decremented once beforehand so that the function can
+;;; use the sign flag instead of the zero flag for the exit test.
+;;; It is then shifted into the high word, to make room for the wmask
+;;; value, which it will always accompany.
+
+        dec ebx
+        shl ebx, 16
+        or  ebx, eax
+        mov [chainlenwmask], ebx
+
+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+        mov eax, [edx + dsNiceMatch]
+        mov ebx, [edx + dsLookahead]
+        cmp ebx, eax
+        jl  LookaheadLess
+        mov ebx, eax
+LookaheadLess:  mov [nicematch], ebx
+
+;;; register Bytef *scan = s->window + s->strstart;
+
+        mov esi, [edx + dsWindow]
+        mov [window], esi
+        mov ebp, [edx + dsStrStart]
+        lea edi, [esi + ebp]
+        mov [scan], edi
+
+;;; Determine how many bytes the scan ptr is off from being
+;;; dword-aligned.
+
+        mov eax, edi
+        neg eax
+        and eax, 3
+        mov [scanalign], eax
+
+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;
+
+        mov eax, [edx + dsWSize]
+        sub eax, MIN_LOOKAHEAD
+        sub ebp, eax
+        jg  LimitPositive
+        xor ebp, ebp
+LimitPositive:
+
+;;; int best_len = s->prev_length;
+
+        mov eax, [edx + dsPrevLen]
+        mov [bestlen], eax
+
+;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+        add esi, eax
+        mov [windowbestlen], esi
+
+;;; register ush scan_start = *(ushf*)scan;
+;;; register ush scan_end   = *(ushf*)(scan+best_len-1);
+;;; Posf *prev = s->prev;
+
+        movzx   ebx, word ptr [edi]
+        mov [scanstart], ebx
+        movzx   ebx, word ptr [edi + eax - 1]
+        mov [scanend], ebx
+        mov edi, [edx + dsPrev]
+
+;;; Jump into the main loop.
+
+        mov edx, [chainlenwmask]
+        jmp short LoopEntry
+
+align 4
+
+;;; do {
+;;;     match = s->window + cur_match;
+;;;     if (*(ushf*)(match+best_len-1) != scan_end ||
+;;;         *(ushf*)match != scan_start) continue;
+;;;     [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;;          && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; ecx = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+
+LookupLoop:
+        and ecx, edx
+        movzx   ecx, word ptr [edi + ecx*2]
+        cmp ecx, ebp
+        jbe LeaveNow
+        sub edx, 00010000h
+        js  LeaveNow
+LoopEntry:  movzx   eax, word ptr [esi + ecx - 1]
+        cmp eax, ebx
+        jnz LookupLoop
+        mov eax, [window]
+        movzx   eax, word ptr [eax + ecx]
+        cmp eax, [scanstart]
+        jnz LookupLoop
+
+;;; Store the current value of chainlen.
+
+        mov [chainlenwmask], edx
+
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+
+        mov esi, [window]
+        mov edi, [scan]
+        add esi, ecx
+        mov eax, [scanalign]
+        mov edx, 0fffffef8h; -(MAX_MATCH_8)
+        lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]
+        lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]
+
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust edx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (esi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+
+LoopCmps:
+        mov eax, [esi + edx]
+        xor eax, [edi + edx]
+        jnz LeaveLoopCmps
+        mov eax, [esi + edx + 4]
+        xor eax, [edi + edx + 4]
+        jnz LeaveLoopCmps4
+        add edx, 8
+        jnz LoopCmps
+        jmp short LenMaximum
+LeaveLoopCmps4: add edx, 4
+LeaveLoopCmps:  test    eax, 0000FFFFh
+        jnz LenLower
+        add edx,  2
+        shr eax, 16
+LenLower:   sub al, 1
+        adc edx, 0
+
+;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+;;; then automatically accept it as the best possible match and leave.
+
+        lea eax, [edi + edx]
+        mov edi, [scan]
+        sub eax, edi
+        cmp eax, MAX_MATCH
+        jge LenMaximum
+
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+
+        mov edx, [deflatestate]
+        mov ebx, [bestlen]
+        cmp eax, ebx
+        jg  LongerMatch
+        mov esi, [windowbestlen]
+        mov edi, [edx + dsPrev]
+        mov ebx, [scanend]
+        mov edx, [chainlenwmask]
+        jmp LookupLoop
+
+;;;         s->match_start = cur_match;
+;;;         best_len = len;
+;;;         if (len >= nice_match) break;
+;;;         scan_end = *(ushf*)(scan+best_len-1);
+
+LongerMatch:    mov ebx, [nicematch]
+        mov [bestlen], eax
+        mov [edx + dsMatchStart], ecx
+        cmp eax, ebx
+        jge LeaveNow
+        mov esi, [window]
+        add esi, eax
+        mov [windowbestlen], esi
+        movzx   ebx, word ptr [edi + eax - 1]
+        mov edi, [edx + dsPrev]
+        mov [scanend], ebx
+        mov edx, [chainlenwmask]
+        jmp LookupLoop
+
+;;; Accept the current string, with the maximum possible length.
+
+LenMaximum: mov edx, [deflatestate]
+        mov dword ptr [bestlen], MAX_MATCH
+        mov [edx + dsMatchStart], ecx
+
+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+;;; return s->lookahead;
+
+LeaveNow:
+        mov edx, [deflatestate]
+        mov ebx, [bestlen]
+        mov eax, [edx + dsLookahead]
+        cmp ebx, eax
+        jg  LookaheadRet
+        mov eax, ebx
+LookaheadRet:
+
+;;; Restore the stack and return from whence we came.
+
+        add esp, LocalVarsSize
+        pop ebx
+        pop esi
+        pop edi
+        pop ebp
+
+        ret
+; please don't remove this string !
+; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary!
+    db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah
+
+
+    IFDEF NOUNDERLINE
+    longest_match       endp
+    ELSE
+    _longest_match      endp
+    ENDIF
+
+    IFDEF NOUNDERLINE
+    match_init      proc near
+                    ret
+    match_init      endp
+    ELSE
+    _match_init     proc near
+                    ret
+    _match_init     endp
+    ENDIF
+
+
+_TEXT   ends
+end



Mime
View raw message