1/* lzo1x_d.ash -- assembler implementation of the LZO1X decompression algorithm 2 3 This file is part of the LZO real-time data compression library. 4 5 Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer 6 Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer 7 Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer 8 Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer 9 Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer 10 Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer 11 Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer 12 Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer 13 Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer 14 Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer 15 Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer 16 Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer 17 Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer 18 All Rights Reserved. 19 20 The LZO library is free software; you can redistribute it and/or 21 modify it under the terms of the GNU General Public License as 22 published by the Free Software Foundation; either version 2 of 23 the License, or (at your option) any later version. 24 25 The LZO library is distributed in the hope that it will be useful, 26 but WITHOUT ANY WARRANTY; without even the implied warranty of 27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 GNU General Public License for more details. 29 30 You should have received a copy of the GNU General Public License 31 along with the LZO library; see the file COPYING. 32 If not, write to the Free Software Foundation, Inc., 33 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 34 35 Markus F.X.J. Oberhumer 36 <markus@oberhumer.com> 37 http://www.oberhumer.com/opensource/lzo/ 38 */ 39 40 41#if !defined(LZO1X) && !defined(LZO1Y) 42# define LZO1X 43#endif 44 45#if defined(LZO_FAST) 46# define NN 3 47#else 48# define NN 0 49#endif 50 51 52/*********************************************************************** 53// init 54************************************************************************/ 55 56 xorl %eax,%eax 57 xorl %ebx,%ebx /* high bits 9-32 stay 0 */ 58 lodsb 59 cmpb $17,%al 60 jbe .L01 61 subb $17-NN,%al 62#if defined(LZO_FAST) 63 jmp .LFLR 64#else 65 cmpb $4,%al 66 jae .LFLR 67#if 1 68 TEST_OP((%edi,%eax),%edx) 69 TEST_IP((%esi,%eax),%edx) 70 movl %eax,%ecx 71 jmp .LFLR2 72#else 73 jmp .LFLR3 74#endif 75#endif 76 77 78/*********************************************************************** 79// literal run 80************************************************************************/ 81 820: addl N_255,%eax 83 TEST_IP(18(%esi,%eax),%edx) /* minimum */ 841: movb (%esi),%bl 85 incl %esi 86 orb %bl,%bl 87 jz 0b 88 leal 18+NN(%eax,%ebx),%eax 89 jmp 3f 90 91 92 ALIGN3 93.L00: 94#ifdef LZO_DEBUG 95 andl $0xffffff00,%eax ; jnz .L_assert_fail 96 andl $0xffffff00,%ebx ; jnz .L_assert_fail 97 xorl %eax,%eax ; xorl %ebx,%ebx 98 xorl %ecx,%ecx ; xorl %edx,%edx 99#endif 100 TEST_IP_R(%esi) 101 LODSB 102.L01: 103 cmpb $16,%al 104 jae .LMATCH 105 106/* a literal run */ 107 orb %al,%al 108 jz 1b 109 addl $3+NN,%eax 1103: 111.LFLR: 112 TEST_OP(-NN(%edi,%eax),%edx) 113 TEST_IP(-NN(%esi,%eax),%edx) 114#if defined(LZO_FAST) 115 movl %eax,%ecx 116 NOTL_3(%eax) 117 shrl $2,%ecx 118 andl N_3,%eax 119 COPYL(%esi,%edi,%edx) 120 subl %eax,%esi 121 subl %eax,%edi 122#else 123 movl %eax,%ecx 124 shrl $2,%eax 125 andl N_3,%ecx 126 COPYL_C(%esi,%edi,%edx,%eax) 127.LFLR2: 128 rep 129 movsb 130#endif 131 132#ifdef LZO_DEBUG 133 andl $0xffffff00,%eax ; jnz .L_assert_fail 134 andl $0xffffff00,%ebx ; jnz .L_assert_fail 135 xorl %eax,%eax ; xorl %ebx,%ebx 136 xorl %ecx,%ecx ; xorl %edx,%edx 137#endif 138 LODSB 139 cmpb $16,%al 140 jae .LMATCH 141 142 143/*********************************************************************** 144// R1 145************************************************************************/ 146 147 TEST_OP(3(%edi),%edx) 148 shrl $2,%eax 149 movb (%esi),%bl 150#if defined(LZO1X) 151 leal -0x801(%edi),%edx 152#elif defined(LZO1Y) 153 leal -0x401(%edi),%edx 154#endif 155 leal (%eax,%ebx,4),%eax 156 incl %esi 157 subl %eax,%edx 158 TEST_LOOKBEHIND(%edx) 159#if defined(LZO_FAST) 160 movl (%edx),%ecx 161 movl %ecx,(%edi) 162#else 163 movb (%edx),%al 164 movb %al,(%edi) 165 movb 1(%edx),%al 166 movb %al,1(%edi) 167 movb 2(%edx),%al 168 movb %al,2(%edi) 169#endif 170 addl N_3,%edi 171 jmp .LMDONE 172 173 174/*********************************************************************** 175// M2 176************************************************************************/ 177 178 ALIGN3 179.LMATCH: 180 cmpb $64,%al 181 jb .LM3MATCH 182 183/* a M2 match */ 184 movl %eax,%ecx 185 shrl $2,%eax 186 leal -1(%edi),%edx 187#if defined(LZO1X) 188 andl $7,%eax 189 movb (%esi),%bl 190 shrl $5,%ecx 191 leal (%eax,%ebx,8),%eax 192#elif defined(LZO1Y) 193 andl N_3,%eax 194 movb (%esi),%bl 195 shrl $4,%ecx 196 leal (%eax,%ebx,4),%eax 197#endif 198 incl %esi 199 subl %eax,%edx 200 201#if defined(LZO_FAST) 202#if defined(LZO1X) 203 addl $1+3,%ecx 204#elif defined(LZO1Y) 205 addl $2,%ecx 206#endif 207#else 208#if defined(LZO1X) 209 incl %ecx 210#elif defined(LZO1Y) 211 decl %ecx 212#endif 213#endif 214 215 cmpl N_3,%eax 216 jae .LCOPYLONG 217 jmp .LCOPYBYTE 218 219 220/*********************************************************************** 221// M3 222************************************************************************/ 223 2240: addl N_255,%eax 225 TEST_IP(3(%esi),%edx) /* minimum */ 2261: movb (%esi),%bl 227 incl %esi 228 orb %bl,%bl 229 jz 0b 230 leal 33+NN(%eax,%ebx),%ecx 231 xorl %eax,%eax 232 jmp 3f 233 234 235 ALIGN3 236.LM3MATCH: 237 cmpb $32,%al 238 jb .LM4MATCH 239 240/* a M3 match */ 241 andl $31,%eax 242 jz 1b 243 lea 2+NN(%eax),%ecx 2443: 245#ifdef LZO_DEBUG 246 andl $0xffff0000,%eax ; jnz .L_assert_fail 247#endif 248 movw (%esi),%ax 249 leal -1(%edi),%edx 250 shrl $2,%eax 251 addl $2,%esi 252 subl %eax,%edx 253 254 cmpl N_3,%eax 255 jb .LCOPYBYTE 256 257 258/*********************************************************************** 259// copy match 260************************************************************************/ 261 262 ALIGN1 263.LCOPYLONG: /* copy match using longwords */ 264 TEST_LOOKBEHIND(%edx) 265#if defined(LZO_FAST) 266 leal -3(%edi,%ecx),%eax 267 shrl $2,%ecx 268 TEST_OP_R(%eax) 269 COPYL(%edx,%edi,%ebx) 270 movl %eax,%edi 271 xorl %ebx,%ebx 272#else 273 TEST_OP((%edi,%ecx),%eax) 274 movl %ecx,%ebx 275 shrl $2,%ebx 276 jz 2f 277 COPYL_C(%edx,%edi,%eax,%ebx) 278 andl N_3,%ecx 279 jz 1f 2802: COPYB_C(%edx,%edi,%al,%ecx) 2811: 282#endif 283 284.LMDONE: 285 movb -2(%esi),%al 286 andl N_3,%eax 287 jz .L00 288.LFLR3: 289 TEST_OP((%edi,%eax),%edx) 290 TEST_IP((%esi,%eax),%edx) 291#if defined(LZO_FAST) 292 movl (%esi),%edx 293 addl %eax,%esi 294 movl %edx,(%edi) 295 addl %eax,%edi 296#else 297 COPYB_C(%esi,%edi,%cl,%eax) 298#endif 299 300#ifdef LZO_DEBUG 301 andl $0xffffff00,%eax ; jnz .L_assert_fail 302 andl $0xffffff00,%ebx ; jnz .L_assert_fail 303 xorl %eax,%eax ; xorl %ebx,%ebx 304 xorl %ecx,%ecx ; xorl %edx,%edx 305#endif 306 LODSB 307 jmp .LMATCH 308 309 310 ALIGN3 311.LCOPYBYTE: /* copy match using bytes */ 312 TEST_LOOKBEHIND(%edx) 313 TEST_OP(-NN(%edi,%ecx),%eax) 314 xchgl %edx,%esi 315#if defined(LZO_FAST) 316 subl N_3,%ecx 317#endif 318 rep 319 movsb 320 movl %edx,%esi 321 jmp .LMDONE 322 323 324/*********************************************************************** 325// M4 326************************************************************************/ 327 3280: addl N_255,%ecx 329 TEST_IP(3(%esi),%edx) /* minimum */ 3301: movb (%esi),%bl 331 incl %esi 332 orb %bl,%bl 333 jz 0b 334 leal 9+NN(%ebx,%ecx),%ecx 335 jmp 3f 336 337 338 ALIGN3 339.LM4MATCH: 340 cmpb $16,%al 341 jb .LM1MATCH 342 343/* a M4 match */ 344 movl %eax,%ecx 345 andl $8,%eax 346 shll $13,%eax /* save in bit 16 */ 347 andl $7,%ecx 348 jz 1b 349 addl $2+NN,%ecx 3503: 351#ifdef LZO_DEBUG 352 movl %eax,%edx ; andl $0xfffe0000,%edx ; jnz .L_assert_fail 353#endif 354 movw (%esi),%ax 355 addl $2,%esi 356 leal -0x4000(%edi),%edx 357 shrl $2,%eax 358 jz .LEOF 359 subl %eax,%edx 360 jmp .LCOPYLONG 361 362 363/*********************************************************************** 364// M1 365************************************************************************/ 366 367 ALIGN3 368.LM1MATCH: 369/* a M1 match */ 370 TEST_OP(2(%edi),%edx) 371 shrl $2,%eax 372 movb (%esi),%bl 373 leal -1(%edi),%edx 374 leal (%eax,%ebx,4),%eax 375 incl %esi 376 subl %eax,%edx 377 TEST_LOOKBEHIND(%edx) 378 379 movb (%edx),%al /* we must use this because edx can be edi-1 */ 380 movb %al,(%edi) 381 movb 1(%edx),%bl 382 movb %bl,1(%edi) 383 addl $2,%edi 384 jmp .LMDONE 385 386 387/*********************************************************************** 388// 389************************************************************************/ 390 391.LEOF: 392/**** xorl %eax,%eax eax=0 from above */ 393 394 cmpl $3+NN,%ecx /* ecx must be 3/6 */ 395 setnz %al 396 397 398/* 399vi:ts=4 400*/ 401 402

