home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / gnu / gzip-1.2.4-src.lha / src / amiga / gzip-1.2.4 / match.S < prev    next >
Text File  |  1993-06-11  |  12KB  |  380 lines

  1. /* match.s -- optional optimized asm version of longest match in deflate.c
  2.  * Copyright (C) 1992-1993 Jean-loup Gailly
  3.  * This is free software; you can redistribute it and/or modify it under the
  4.  * terms of the GNU General Public License, see the file COPYING.
  5.  *
  6.  * The 68020 version has been written by Francesco Potorti` <pot@cnuce.cnr.it>
  7.  * with adaptations by Carsten Steger <stegerc@informatik.tu-muenchen.de>,
  8.  * Andreas Schwab <schwab@lamothe.informatik.uni-dortmund.de> and
  9.  * Kristoffer Eriksson <ske@pkmab.se>
  10.  */
  11.  
  12. /* $Id: match.S,v 0.14 1993/06/11 18:33:24 jloup Exp $ */
  13.  
  14. /* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
  15.  * external symbols with an underline character '_'.
  16.  */
  17. #ifdef NO_UNDERLINE
  18. #  define _prev             prev
  19. #  define _window           window
  20. #  define _match_start        match_start
  21. #  define _prev_length        prev_length
  22. #  define _good_match        good_match
  23. #  define _nice_match        nice_match
  24. #  define _strstart        strstart
  25. #  define _max_chain_length max_chain_length
  26.  
  27. #  define _match_init       match_init
  28. #  define _longest_match    longest_match
  29. #endif
  30.  
  31. #ifdef DYN_ALLOC
  32.   error: DYN_ALLOC not yet supported in match.s
  33. #endif
  34.  
  35. #if defined(i386) || defined(_I386)
  36.  
  37. /* This version is for 386 Unix or OS/2 in 32 bit mode.
  38.  * Warning: it uses the AT&T syntax: mov source,dest
  39.  * This file is only optional. If you want to force the C version,
  40.  * add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string.
  41.  * If you have reduced WSIZE in gzip.h, then change its value below.
  42.  * This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
  43.  */
  44.  
  45.     .file   "match.S"
  46.  
  47. #define MAX_MATCH    258
  48. #define MAX_MATCH2    $128 /* MAX_MATCH/2-1 */
  49. #define MIN_MATCH    3
  50. #define    WSIZE    $32768
  51. #define MAX_DIST    WSIZE - MAX_MATCH - MIN_MATCH - 1
  52.  
  53.     .globl    _match_init
  54.     .globl  _longest_match
  55.  
  56.     .text
  57.  
  58. _match_init:
  59.     ret
  60.  
  61. /*-----------------------------------------------------------------------
  62.  * Set match_start to the longest match starting at the given string and
  63.  * return its length. Matches shorter or equal to prev_length are discarded,
  64.  * in which case the result is equal to prev_length and match_start is
  65.  * garbage.
  66.  * IN assertions: cur_match is the head of the hash chain for the current
  67.  *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
  68.  */
  69.  
  70. _longest_match:    /* int longest_match(cur_match) */
  71.  
  72. #define cur_match   20(%esp)
  73.      /* return address */               /* esp+16 */
  74.         push    %ebp                    /* esp+12 */
  75.         push    %edi                    /* esp+8  */
  76.     push    %esi                    /* esp+4  */
  77.     push    %ebx            /* esp    */
  78.  
  79. /*
  80.  *      match        equ esi
  81.  *      scan         equ edi
  82.  *      chain_length equ ebp
  83.  *      best_len     equ ebx
  84.  *      limit        equ edx
  85.  */
  86.     mov     cur_match,%esi
  87.         mov     _max_chain_length,%ebp /* chain_length = max_chain_length */
  88.     mov     _strstart,%edi
  89.     mov     %edi,%edx
  90.     sub    MAX_DIST,%edx          /* limit = strstart-MAX_DIST */
  91.     jae    limit_ok
  92.     sub    %edx,%edx              /* limit = NIL */
  93. limit_ok:
  94.         add    $2+_window,%edi        /* edi = offset(window+strstart+2) */
  95.         mov    _prev_length,%ebx      /* best_len = prev_length */
  96.         movw     -3(%ebx,%edi),%ax      /* ax = scan[best_len-1..best_len] */
  97.         movw     -2(%edi),%cx           /* cx = scan[0..1] */
  98.     cmp    _good_match,%ebx       /* do we have a good match already? */
  99.         jb      do_scan
  100.     shr     $2,%ebp                /* chain_length >>= 2 */
  101.         jmp     do_scan
  102.  
  103.         .align  4
  104. long_loop:
  105. /* at this point, edi == scan+2, esi == cur_match */
  106.         movw    -3(%ebx,%edi),%ax       /* ax = scan[best_len-1..best_len] */
  107.         movw     -2(%edi),%cx           /* cx = scan[0..1] */
  108. short_loop:
  109. /*
  110.  * at this point, di == scan+2, si == cur_match,
  111.  * ax = scan[best_len-1..best_len] and cx = scan[0..1]
  112.  */
  113.         and     WSIZE-1, %esi
  114.         movw    _prev(%esi,%esi),%si    /* cur_match = prev[cur_match] */
  115.                                         /* top word of esi is still 0 */
  116.         cmp     %edx,%esi        /* cur_match <= limit ? */
  117.         jbe     the_end
  118.         dec     %ebp                    /* --chain_length */
  119.         jz      the_end
  120. do_scan:
  121.         cmpw    _window-1(%ebx,%esi),%ax/* check match at best_len-1 */
  122.         jne     short_loop
  123.         cmpw    _window(%esi),%cx       /* check min_match_length match */
  124.         jne     short_loop
  125.  
  126.         lea     _window+2(%esi),%esi    /* si = match */
  127.         mov     %edi,%eax               /* ax = scan+2 */
  128.         mov     MAX_MATCH2,%ecx         /* scan for at most MAX_MATCH bytes */
  129.         rep;    cmpsw                   /* loop until mismatch */
  130.         je      maxmatch                /* match of length MAX_MATCH? */
  131. mismatch:
  132.         movb    -2(%edi),%cl        /* mismatch on first or second byte? */
  133.         subb    -2(%esi),%cl        /* cl = 0 if first bytes equal */
  134.         xchg    %edi,%eax           /* edi = scan+2, eax = end of scan */
  135.         sub     %edi,%eax           /* eax = len */
  136.     sub    %eax,%esi           /* esi = cur_match + 2 + offset(window) */
  137.     sub    $2+_window,%esi     /* esi = cur_match */
  138.         subb    $1,%cl              /* set carry if cl == 0 (cannot use DEC) */
  139.         adc     $0,%eax             /* eax = carry ? len+1 : len */
  140.         cmp     %ebx,%eax           /* len > best_len ? */
  141.         jle     long_loop
  142.         mov     %esi,_match_start       /* match_start = cur_match */
  143.         mov     %eax,%ebx               /* ebx = best_len = len */
  144.         cmp     _nice_match,%eax        /* len >= nice_match ? */
  145.         jl      long_loop
  146. the_end:
  147.         mov     %ebx,%eax               /* result = eax = best_len */
  148.     pop     %ebx
  149.         pop     %esi
  150.         pop     %edi
  151.         pop     %ebp
  152.         ret
  153. maxmatch:
  154.         cmpsb
  155.         jmp     mismatch
  156.  
  157. #else
  158.  
  159. /* ======================== 680x0 version ================================= */
  160.  
  161. #if defined(m68k)||defined(mc68k)||defined(__mc68000__)||defined(__MC68000__)
  162. #  ifndef mc68000
  163. #    define mc68000
  164. #  endif
  165. #endif
  166.  
  167. #if defined(__mc68020__) || defined(__MC68020__) || defined(sysV68)
  168. #  ifndef mc68020
  169. #    define mc68020
  170. #  endif
  171. #endif
  172.  
  173. #if defined(mc68020) || defined(mc68000)
  174.  
  175. #if (defined(mc68020) || defined(NeXT)) && !defined(UNALIGNED_OK)
  176. #  define UNALIGNED_OK
  177. #endif
  178.  
  179. #ifdef sysV68  /* Try Motorola Delta style */
  180.  
  181. #  define GLOBAL(symbol)    global    symbol
  182. #  define TEXT            text
  183. #  define FILE(filename)    file    filename
  184. #  define invert_maybe(src,dst)    dst,src
  185. #  define imm(data)        &data
  186. #  define reg(register)        %register
  187.  
  188. #  define addl            add.l
  189. #  define addql            addq.l
  190. #  define blos            blo.b
  191. #  define bhis            bhi.b
  192. #  define bras            bra.b
  193. #  define clrl            clr.l
  194. #  define cmpmb            cmpm.b
  195. #  define cmpw            cmp.w
  196. #  define cmpl            cmp.l
  197. #  define lslw            lsl.w
  198. #  define lsrl            lsr.l
  199. #  define movel            move.l
  200. #  define movew            move.w
  201. #  define moveb            move.b
  202. #  define moveml        movem.l
  203. #  define subl            sub.l
  204. #  define subw            sub.w
  205. #  define subql            subq.l
  206.  
  207. #  define IndBase(bd,An)    (bd,An)
  208. #  define IndBaseNdxl(bd,An,Xn)    (bd,An,Xn.l)
  209. #  define IndBaseNdxw(bd,An,Xn)    (bd,An,Xn.w)
  210. #  define predec(An)        -(An)
  211. #  define postinc(An)        (An)+
  212.  
  213. #else /* default style (Sun 3, NeXT, Amiga, Atari) */
  214.  
  215. #  define GLOBAL(symbol)    .globl    symbol
  216. #  define TEXT            .text
  217. #  define FILE(filename)    .even
  218. #  define invert_maybe(src,dst)    src,dst
  219. #  if defined(sun) || defined(mc68k)
  220. #    define imm(data)        #data
  221. #  else
  222. #    define imm(data)        \#data
  223. #  endif
  224. #  define reg(register)        register
  225.  
  226. #  define blos            bcss
  227. #  if defined(sun) || defined(mc68k)
  228. #    define movel        movl
  229. #    define movew        movw
  230. #    define moveb        movb
  231. #  endif
  232. #  define IndBase(bd,An)    An@(bd)
  233. #  define IndBaseNdxl(bd,An,Xn)    An@(bd,Xn:l)
  234. #  define IndBaseNdxw(bd,An,Xn)    An@(bd,Xn:w)
  235. #  define predec(An)        An@-
  236. #  define postinc(An)        An@+
  237.  
  238. #endif    /* styles */
  239.  
  240. #define Best_Len    reg(d0)        /* unsigned */
  241. #define Cur_Match    reg(d1)        /* Ipos */
  242. #define Loop_Counter    reg(d2)        /* int */
  243. #define Scan_Start    reg(d3)        /* unsigned short */
  244. #define Scan_End    reg(d4)        /* unsigned short */
  245. #define Limit        reg(d5)        /* IPos */
  246. #define Chain_Length    reg(d6)        /* unsigned */
  247. #define Scan_Test    reg(d7)
  248. #define Scan        reg(a0)        /* *uch */
  249.