summaryrefslogtreecommitdiff
path: root/win32/lm32_lcc.asm
diff options
context:
space:
mode:
Diffstat (limited to 'win32/lm32_lcc.asm')
-rw-r--r--win32/lm32_lcc.asm174
1 files changed, 174 insertions, 0 deletions
diff --git a/win32/lm32_lcc.asm b/win32/lm32_lcc.asm
new file mode 100644
index 0000000..0450fe3
--- /dev/null
+++ b/win32/lm32_lcc.asm
@@ -0,0 +1,174 @@
+;===========================================================================
+; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 1999-Oct-05 or later
+; (the contents of which are also included in zip.h) for terms of use.
+; If, for some reason, both of these files are missing, the Info-ZIP license
+; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+;===========================================================================
+; match32.asm by Jean-loup Gailly.
+
+; match32.asm, optimized version of longest_match() in deflate.c
+; To be used only with 32 bit flat model. To simplify the code, the option
+; -DDYN_ALLOC is not supported.
+; This file is only optional. If you don't have an assembler, use the
+; C version (add -DNO_ASM to CFLAGS in makefile and remove match.o
+; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is
+; assembled with an equivalent -DWSIZE=<whatever>.
+;
+; Win32 (Windows NT) version - 1994/04/13 by Steve Salisbury
+; * works with Microsoft MASM 6.1X and Microsoft Visual C++ / 32-bit edition
+;
+; The code in this file has been copied verbatim from match32.{asm|S};
+; only the assembler syntax and metacommands have been adapted to
+; the habits of the free LCC-Win32 C compiler package.
+; IMPORTANT NOTE to the Info-ZIP editors:
+; The TAB characters in this source file are required by the parser of
+; the LCC-Win32 assembler program and MUST NOT be removed!!
+;
+;==============================================================================
+;
+; Do NOT assemble this source if external crc32 routine from zlib gets used.
+;
+
+
+;/* This version is for 386 Unix or OS/2 in 32 bit mode.
+; * Warning: it uses the AT&T syntax: mov source,dest
+; * This file is only optional. If you want to force the C version,
+; * add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string.
+; * If you have reduced WSIZE in (g)zip.h, then make sure this is
+; * assembled with an equivalent -DWSIZE=<whatever>.
+; * This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
+; */
+
+ .text
+ .file "match.S"
+
+
+ .text
+ .type _match_init,function
+
+_match_init:
+ ret
+_$98:
+ .size _match_init,_$98-_match_init
+ .globl _match_init
+
+;/*-----------------------------------------------------------------------
+; * Set match_start to the longest match starting at the given string and
+; * return its length. Matches shorter or equal to prev_length are discarded,
+; * in which case the result is equal to prev_length and match_start is
+; * garbage.
+; * IN assertions: cur_match is the head of the hash chain for the current
+; * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+; */
+
+ .align 4
+ .type _longest_match,function
+
+_longest_match: ;/* int longest_match(cur_match) */
+
+; cur_match equ 20(%esp)
+; /* return address */ /* esp+16 */
+ push %ebp
+ push %edi
+;/* esp+8 */
+ push %esi
+;/* esp+4 */
+ push %ebx
+;/* esp */
+
+;/*
+; * match equ esi
+; * scan equ edi
+; * chain_length equ ebp
+; * best_len equ ebx
+; * limit equ edx
+; */
+ mov 20(%esp),%esi
+ mov _strstart,%edx
+ mov _max_chain_length,%ebp
+ mov %edx,%edi
+ sub $(32768-262),%edx
+ cld
+ jae limit_ok
+ sub %edx,%edx
+limit_ok:
+ add $2+_window,%edi
+ mov _prev_length,%ebx
+ movw -2(%edi),%cx
+ movw -3(%ebx,%edi),%ax
+ cmp _good_match,%ebx
+ jb do_scan
+ shr $2,%ebp
+ jmp do_scan
+
+ .align 4
+long_loop:
+;/* at this point, edi == scan+2, esi == cur_match */
+ movw -3(%ebx,%edi),%ax
+ movw -2(%edi),%cx
+short_loop:
+;/*
+; * at this point, di == scan+2, si == cur_match,
+; * ax = scan[best_len-1..best_len] and cx = scan[0..1]
+; */
+ and $(32768-1), %esi
+ dec %ebp
+ movw _prev(,%esi,2),%si
+ jz the_end
+ cmp %edx,%esi
+ jbe the_end
+do_scan:
+ cmpw _window-1(%ebx,%esi),%ax
+ jne short_loop
+ cmpw _window(%esi),%cx
+ jne short_loop
+
+ add $2+_window,%esi
+ mov $((258>>1)-1),%ecx
+ mov %edi,%eax
+ repe; cmpsw
+;/* loop until mismatch */
+ je maxmatch
+;/* match of length MAX_MATCH? */
+mismatch:
+ movb -2(%edi),%cl
+ xchg %edi,%eax
+ subb -2(%esi),%cl
+ sub %edi,%eax
+ sub $2+_window,%esi
+ sub %eax,%esi
+ subb $1,%cl
+ adc $0,%eax
+ cmp %ebx,%eax
+ jle long_loop
+ mov %esi,_match_start
+ mov %eax,%ebx
+ cmp _nice_match,%eax
+; /* len >= nice_match ? */
+ jl long_loop
+the_end:
+ mov %ebx,%eax
+ pop %ebx
+ pop %esi
+ pop %edi
+ pop %ebp
+ ret
+ .align 4
+maxmatch:
+ cmpsb
+ jmp mismatch
+_$99:
+
+ .size _longest_match,_$99-_longest_match
+ .globl _longest_match
+
+ .extern _nice_match
+ .extern _good_match
+ .extern _max_chain_length
+ .extern _match_start
+ .extern _strstart
+ .extern _prev_length
+ .extern _prev
+ .extern _window