kusano 7d535a
/* lzo1x_d.ash -- assembler implementation of the LZO1X decompression algorithm
kusano 7d535a
kusano 7d535a
   This file is part of the LZO real-time data compression library.
kusano 7d535a
kusano 7d535a
   Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   All Rights Reserved.
kusano 7d535a
kusano 7d535a
   The LZO library is free software; you can redistribute it and/or
kusano 7d535a
   modify it under the terms of the GNU General Public License as
kusano 7d535a
   published by the Free Software Foundation; either version 2 of
kusano 7d535a
   the License, or (at your option) any later version.
kusano 7d535a
kusano 7d535a
   The LZO library is distributed in the hope that it will be useful,
kusano 7d535a
   but WITHOUT ANY WARRANTY; without even the implied warranty of
kusano 7d535a
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
kusano 7d535a
   GNU General Public License for more details.
kusano 7d535a
kusano 7d535a
   You should have received a copy of the GNU General Public License
kusano 7d535a
   along with the LZO library; see the file COPYING.
kusano 7d535a
   If not, write to the Free Software Foundation, Inc.,
kusano 7d535a
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
kusano 7d535a
kusano 7d535a
   Markus F.X.J. Oberhumer
kusano 7d535a
   <markus@oberhumer.com></markus@oberhumer.com>
kusano 7d535a
   http://www.oberhumer.com/opensource/lzo/
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
kusano 7d535a
#if !defined(LZO1X) && !defined(LZO1Y)
kusano 7d535a
#  define LZO1X
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#if defined(LZO_FAST)
kusano 7d535a
#  define NN    3
kusano 7d535a
#else
kusano 7d535a
#  define NN    0
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
// init
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
        xorl    %eax,%eax
kusano 7d535a
        xorl    %ebx,%ebx       /* high bits 9-32 stay 0 */
kusano 7d535a
        lodsb
kusano 7d535a
        cmpb    $17,%al
kusano 7d535a
        jbe     .L01
kusano 7d535a
        subb    $17-NN,%al
kusano 7d535a
#if defined(LZO_FAST)
kusano 7d535a
        jmp     .LFLR
kusano 7d535a
#else
kusano 7d535a
        cmpb    $4,%al
kusano 7d535a
        jae     .LFLR
kusano 7d535a
#if 1
kusano 7d535a
        TEST_OP((%edi,%eax),%edx)
kusano 7d535a
        TEST_IP((%esi,%eax),%edx)
kusano 7d535a
        movl    %eax,%ecx
kusano 7d535a
        jmp     .LFLR2
kusano 7d535a
#else
kusano 7d535a
        jmp     .LFLR3
kusano 7d535a
#endif
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
// literal run
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
0:      addl    N_255,%eax
kusano 7d535a
        TEST_IP(18(%esi,%eax),%edx)     /* minimum */
kusano 7d535a
1:      movb    (%esi),%bl
kusano 7d535a
        incl    %esi
kusano 7d535a
        orb     %bl,%bl
kusano 7d535a
        jz      0b
kusano 7d535a
        leal    18+NN(%eax,%ebx),%eax
kusano 7d535a
        jmp     3f
kusano 7d535a
kusano 7d535a
kusano 7d535a
        ALIGN3
kusano 7d535a
.L00:
kusano 7d535a
#ifdef LZO_DEBUG
kusano 7d535a
    andl $0xffffff00,%eax ; jnz .L_assert_fail
kusano 7d535a
    andl $0xffffff00,%ebx ; jnz .L_assert_fail
kusano 7d535a
    xorl %eax,%eax ; xorl %ebx,%ebx
kusano 7d535a
    xorl %ecx,%ecx ; xorl %edx,%edx
kusano 7d535a
#endif
kusano 7d535a
        TEST_IP_R(%esi)
kusano 7d535a
        LODSB
kusano 7d535a
.L01:
kusano 7d535a
        cmpb    $16,%al
kusano 7d535a
        jae     .LMATCH
kusano 7d535a
kusano 7d535a
/* a literal run */
kusano 7d535a
        orb     %al,%al
kusano 7d535a
        jz      1b
kusano 7d535a
        addl    $3+NN,%eax
kusano 7d535a
3:
kusano 7d535a
.LFLR:
kusano 7d535a
        TEST_OP(-NN(%edi,%eax),%edx)
kusano 7d535a
        TEST_IP(-NN(%esi,%eax),%edx)
kusano 7d535a
#if defined(LZO_FAST)
kusano 7d535a
        movl    %eax,%ecx
kusano 7d535a
        NOTL_3(%eax)
kusano 7d535a
        shrl    $2,%ecx
kusano 7d535a
        andl    N_3,%eax
kusano 7d535a
        COPYL(%esi,%edi,%edx)
kusano 7d535a
        subl    %eax,%esi
kusano 7d535a
        subl    %eax,%edi
kusano 7d535a
#else
kusano 7d535a
        movl    %eax,%ecx
kusano 7d535a
        shrl    $2,%eax
kusano 7d535a
        andl    N_3,%ecx
kusano 7d535a
        COPYL_C(%esi,%edi,%edx,%eax)
kusano 7d535a
.LFLR2:
kusano 7d535a
        rep
kusano 7d535a
        movsb
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#ifdef LZO_DEBUG
kusano 7d535a
    andl $0xffffff00,%eax ; jnz .L_assert_fail
kusano 7d535a
    andl $0xffffff00,%ebx ; jnz .L_assert_fail
kusano 7d535a
    xorl %eax,%eax ; xorl %ebx,%ebx
kusano 7d535a
    xorl %ecx,%ecx ; xorl %edx,%edx
kusano 7d535a
#endif
kusano 7d535a
        LODSB
kusano 7d535a
        cmpb    $16,%al
kusano 7d535a
        jae     .LMATCH
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
// R1
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
        TEST_OP(3(%edi),%edx)
kusano 7d535a
        shrl    $2,%eax
kusano 7d535a
        movb    (%esi),%bl
kusano 7d535a
#if defined(LZO1X)
kusano 7d535a
        leal    -0x801(%edi),%edx
kusano 7d535a
#elif defined(LZO1Y)
kusano 7d535a
        leal    -0x401(%edi),%edx
kusano 7d535a
#endif
kusano 7d535a
        leal    (%eax,%ebx,4),%eax
kusano 7d535a
        incl    %esi
kusano 7d535a
        subl    %eax,%edx
kusano 7d535a
        TEST_LOOKBEHIND(%edx)
kusano 7d535a
#if defined(LZO_FAST)
kusano 7d535a
        movl    (%edx),%ecx
kusano 7d535a
        movl    %ecx,(%edi)
kusano 7d535a
#else
kusano 7d535a
        movb    (%edx),%al
kusano 7d535a
        movb    %al,(%edi)
kusano 7d535a
        movb    1(%edx),%al
kusano 7d535a
        movb    %al,1(%edi)
kusano 7d535a
        movb    2(%edx),%al
kusano 7d535a
        movb    %al,2(%edi)
kusano 7d535a
#endif
kusano 7d535a
        addl    N_3,%edi
kusano 7d535a
        jmp     .LMDONE
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
// M2
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
        ALIGN3
kusano 7d535a
.LMATCH:
kusano 7d535a
        cmpb    $64,%al
kusano 7d535a
        jb      .LM3MATCH
kusano 7d535a
kusano 7d535a
/* a M2 match */
kusano 7d535a
        movl    %eax,%ecx
kusano 7d535a
        shrl    $2,%eax
kusano 7d535a
        leal    -1(%edi),%edx
kusano 7d535a
#if defined(LZO1X)
kusano 7d535a
        andl    $7,%eax
kusano 7d535a
        movb    (%esi),%bl
kusano 7d535a
        shrl    $5,%ecx
kusano 7d535a
        leal    (%eax,%ebx,8),%eax
kusano 7d535a
#elif defined(LZO1Y)
kusano 7d535a
        andl    N_3,%eax
kusano 7d535a
        movb    (%esi),%bl
kusano 7d535a
        shrl    $4,%ecx
kusano 7d535a
        leal    (%eax,%ebx,4),%eax
kusano 7d535a
#endif
kusano 7d535a
        incl    %esi
kusano 7d535a
        subl    %eax,%edx
kusano 7d535a
kusano 7d535a
#if defined(LZO_FAST)
kusano 7d535a
#if defined(LZO1X)
kusano 7d535a
        addl    $1+3,%ecx
kusano 7d535a
#elif defined(LZO1Y)
kusano 7d535a
        addl    $2,%ecx
kusano 7d535a
#endif
kusano 7d535a
#else
kusano 7d535a
#if defined(LZO1X)
kusano 7d535a
        incl    %ecx
kusano 7d535a
#elif defined(LZO1Y)
kusano 7d535a
        decl    %ecx
kusano 7d535a
#endif
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
        cmpl    N_3,%eax
kusano 7d535a
        jae     .LCOPYLONG
kusano 7d535a
        jmp     .LCOPYBYTE
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
// M3
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
0:      addl    N_255,%eax
kusano 7d535a
        TEST_IP(3(%esi),%edx)       /* minimum */
kusano 7d535a
1:      movb    (%esi),%bl
kusano 7d535a
        incl    %esi
kusano 7d535a
        orb     %bl,%bl
kusano 7d535a
        jz      0b
kusano 7d535a
        leal    33+NN(%eax,%ebx),%ecx
kusano 7d535a
        xorl    %eax,%eax
kusano 7d535a
        jmp     3f
kusano 7d535a
kusano 7d535a
kusano 7d535a
        ALIGN3
kusano 7d535a
.LM3MATCH:
kusano 7d535a
        cmpb    $32,%al
kusano 7d535a
        jb      .LM4MATCH
kusano 7d535a
kusano 7d535a
/* a M3 match */
kusano 7d535a
        andl    $31,%eax
kusano 7d535a
        jz      1b
kusano 7d535a
        lea     2+NN(%eax),%ecx
kusano 7d535a
3:
kusano 7d535a
#ifdef LZO_DEBUG
kusano 7d535a
    andl $0xffff0000,%eax ; jnz .L_assert_fail
kusano 7d535a
#endif
kusano 7d535a
        movw    (%esi),%ax
kusano 7d535a
        leal    -1(%edi),%edx
kusano 7d535a
        shrl    $2,%eax
kusano 7d535a
        addl    $2,%esi
kusano 7d535a
        subl    %eax,%edx
kusano 7d535a
kusano 7d535a
        cmpl    N_3,%eax
kusano 7d535a
        jb      .LCOPYBYTE
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
// copy match
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
        ALIGN1
kusano 7d535a
.LCOPYLONG:                      /* copy match using longwords */
kusano 7d535a
        TEST_LOOKBEHIND(%edx)
kusano 7d535a
#if defined(LZO_FAST)
kusano 7d535a
        leal    -3(%edi,%ecx),%eax
kusano 7d535a
        shrl    $2,%ecx
kusano 7d535a
        TEST_OP_R(%eax)
kusano 7d535a
        COPYL(%edx,%edi,%ebx)
kusano 7d535a
        movl    %eax,%edi
kusano 7d535a
        xorl    %ebx,%ebx
kusano 7d535a
#else
kusano 7d535a
        TEST_OP((%edi,%ecx),%eax)
kusano 7d535a
        movl    %ecx,%ebx
kusano 7d535a
        shrl    $2,%ebx
kusano 7d535a
        jz      2f
kusano 7d535a
        COPYL_C(%edx,%edi,%eax,%ebx)
kusano 7d535a
        andl    N_3,%ecx
kusano 7d535a
        jz      1f
kusano 7d535a
2:      COPYB_C(%edx,%edi,%al,%ecx)
kusano 7d535a
1:
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
.LMDONE:
kusano 7d535a
        movb    -2(%esi),%al
kusano 7d535a
        andl    N_3,%eax
kusano 7d535a
        jz      .L00
kusano 7d535a
.LFLR3:
kusano 7d535a
        TEST_OP((%edi,%eax),%edx)
kusano 7d535a
        TEST_IP((%esi,%eax),%edx)
kusano 7d535a
#if defined(LZO_FAST)
kusano 7d535a
        movl    (%esi),%edx
kusano 7d535a
        addl    %eax,%esi
kusano 7d535a
        movl    %edx,(%edi)
kusano 7d535a
        addl    %eax,%edi
kusano 7d535a
#else
kusano 7d535a
        COPYB_C(%esi,%edi,%cl,%eax)
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#ifdef LZO_DEBUG
kusano 7d535a
    andl $0xffffff00,%eax ; jnz .L_assert_fail
kusano 7d535a
    andl $0xffffff00,%ebx ; jnz .L_assert_fail
kusano 7d535a
    xorl %eax,%eax ; xorl %ebx,%ebx
kusano 7d535a
    xorl %ecx,%ecx ; xorl %edx,%edx
kusano 7d535a
#endif
kusano 7d535a
        LODSB
kusano 7d535a
        jmp     .LMATCH
kusano 7d535a
kusano 7d535a
kusano 7d535a
        ALIGN3
kusano 7d535a
.LCOPYBYTE:                      /* copy match using bytes */
kusano 7d535a
        TEST_LOOKBEHIND(%edx)
kusano 7d535a
        TEST_OP(-NN(%edi,%ecx),%eax)
kusano 7d535a
        xchgl   %edx,%esi
kusano 7d535a
#if defined(LZO_FAST)
kusano 7d535a
        subl    N_3,%ecx
kusano 7d535a
#endif
kusano 7d535a
        rep
kusano 7d535a
        movsb
kusano 7d535a
        movl    %edx,%esi
kusano 7d535a
        jmp     .LMDONE
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
// M4
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
0:      addl    N_255,%ecx
kusano 7d535a
        TEST_IP(3(%esi),%edx)       /* minimum */
kusano 7d535a
1:      movb    (%esi),%bl
kusano 7d535a
        incl    %esi
kusano 7d535a
        orb     %bl,%bl
kusano 7d535a
        jz      0b
kusano 7d535a
        leal    9+NN(%ebx,%ecx),%ecx
kusano 7d535a
        jmp     3f
kusano 7d535a
kusano 7d535a
kusano 7d535a
        ALIGN3
kusano 7d535a
.LM4MATCH:
kusano 7d535a
        cmpb    $16,%al
kusano 7d535a
        jb      .LM1MATCH
kusano 7d535a
kusano 7d535a
/* a M4 match */
kusano 7d535a
        movl    %eax,%ecx
kusano 7d535a
        andl    $8,%eax
kusano 7d535a
        shll    $13,%eax        /* save in bit 16 */
kusano 7d535a
        andl    $7,%ecx
kusano 7d535a
        jz      1b
kusano 7d535a
        addl    $2+NN,%ecx
kusano 7d535a
3:
kusano 7d535a
#ifdef LZO_DEBUG
kusano 7d535a
    movl %eax,%edx ; andl $0xfffe0000,%edx ; jnz .L_assert_fail
kusano 7d535a
#endif
kusano 7d535a
        movw    (%esi),%ax
kusano 7d535a
        addl    $2,%esi
kusano 7d535a
        leal    -0x4000(%edi),%edx
kusano 7d535a
        shrl    $2,%eax
kusano 7d535a
        jz      .LEOF
kusano 7d535a
        subl    %eax,%edx
kusano 7d535a
        jmp     .LCOPYLONG
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
// M1
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
        ALIGN3
kusano 7d535a
.LM1MATCH:
kusano 7d535a
/* a M1 match */
kusano 7d535a
        TEST_OP(2(%edi),%edx)
kusano 7d535a
        shrl    $2,%eax
kusano 7d535a
        movb    (%esi),%bl
kusano 7d535a
        leal    -1(%edi),%edx
kusano 7d535a
        leal    (%eax,%ebx,4),%eax
kusano 7d535a
        incl    %esi
kusano 7d535a
        subl    %eax,%edx
kusano 7d535a
        TEST_LOOKBEHIND(%edx)
kusano 7d535a
kusano 7d535a
        movb    (%edx),%al      /* we must use this because edx can be edi-1 */
kusano 7d535a
        movb    %al,(%edi)
kusano 7d535a
        movb    1(%edx),%bl
kusano 7d535a
        movb    %bl,1(%edi)
kusano 7d535a
        addl    $2,%edi
kusano 7d535a
        jmp     .LMDONE
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
//
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
.LEOF:
kusano 7d535a
/****   xorl    %eax,%eax          eax=0 from above */
kusano 7d535a
kusano 7d535a
        cmpl    $3+NN,%ecx      /* ecx must be 3/6 */
kusano 7d535a
        setnz   %al
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*
kusano 7d535a
vi:ts=4
kusano 7d535a
*/
kusano 7d535a