diff options
| author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-02-24 14:31:04 -0500 |
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-02-24 14:33:45 -0500 |
| commit | 109d28152b6e9d5de64cd23e3bc08885ccb3d1ef (patch) | |
| tree | b7b8863faa05254781acfb85cc41da3eef467c6b /lib/zlib_inflate/inffast.c | |
| parent | 168cf9af699e87d5a6f44b684583714ecabb8e71 (diff) | |
| parent | 60b341b778cc2929df16c0a504c91621b3c6a4ad (diff) | |
Merge tag 'v2.6.33' for its firewire changes since last branch point
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'lib/zlib_inflate/inffast.c')
| -rw-r--r-- | lib/zlib_inflate/inffast.c | 75 |
1 files changed, 68 insertions, 7 deletions
diff --git a/lib/zlib_inflate/inffast.c b/lib/zlib_inflate/inffast.c index 8550b0c05d00..215447c55261 100644 --- a/lib/zlib_inflate/inffast.c +++ b/lib/zlib_inflate/inffast.c | |||
| @@ -8,6 +8,21 @@ | |||
| 8 | #include "inflate.h" | 8 | #include "inflate.h" |
| 9 | #include "inffast.h" | 9 | #include "inffast.h" |
| 10 | 10 | ||
| 11 | /* Only do the unaligned "Faster" variant when | ||
| 12 | * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is set | ||
| 13 | * | ||
| 14 | * On powerpc, it won't be as we don't include autoconf.h | ||
| 15 | * automatically for the boot wrapper, which is intended as | ||
| 16 | * we run in an environment where we may not be able to deal | ||
| 17 | * with (even rare) alignment faults. In addition, we do not | ||
| 18 | * define __KERNEL__ for arch/powerpc/boot unlike x86 | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
| 22 | #include <asm/unaligned.h> | ||
| 23 | #include <asm/byteorder.h> | ||
| 24 | #endif | ||
| 25 | |||
| 11 | #ifndef ASMINF | 26 | #ifndef ASMINF |
| 12 | 27 | ||
| 13 | /* Allow machine dependent optimization for post-increment or pre-increment. | 28 | /* Allow machine dependent optimization for post-increment or pre-increment. |
| @@ -24,9 +39,11 @@ | |||
| 24 | #ifdef POSTINC | 39 | #ifdef POSTINC |
| 25 | # define OFF 0 | 40 | # define OFF 0 |
| 26 | # define PUP(a) *(a)++ | 41 | # define PUP(a) *(a)++ |
| 42 | # define UP_UNALIGNED(a) get_unaligned((a)++) | ||
| 27 | #else | 43 | #else |
| 28 | # define OFF 1 | 44 | # define OFF 1 |
| 29 | # define PUP(a) *++(a) | 45 | # define PUP(a) *++(a) |
| 46 | # define UP_UNALIGNED(a) get_unaligned(++(a)) | ||
| 30 | #endif | 47 | #endif |
| 31 | 48 | ||
| 32 | /* | 49 | /* |
| @@ -239,18 +256,62 @@ void inflate_fast(z_streamp strm, unsigned start) | |||
| 239 | } | 256 | } |
| 240 | } | 257 | } |
| 241 | else { | 258 | else { |
| 259 | #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
| 260 | unsigned short *sout; | ||
| 261 | unsigned long loops; | ||
| 262 | |||
| 263 | from = out - dist; /* copy direct from output */ | ||
| 264 | /* minimum length is three */ | ||
| 265 | /* Align out addr */ | ||
| 266 | if (!((long)(out - 1 + OFF) & 1)) { | ||
| 267 | PUP(out) = PUP(from); | ||
| 268 | len--; | ||
| 269 | } | ||
| 270 | sout = (unsigned short *)(out - OFF); | ||
| 271 | if (dist > 2) { | ||
| 272 | unsigned short *sfrom; | ||
| 273 | |||
| 274 | sfrom = (unsigned short *)(from - OFF); | ||
| 275 | loops = len >> 1; | ||
| 276 | do | ||
| 277 | PUP(sout) = UP_UNALIGNED(sfrom); | ||
| 278 | while (--loops); | ||
| 279 | out = (unsigned char *)sout + OFF; | ||
| 280 | from = (unsigned char *)sfrom + OFF; | ||
| 281 | } else { /* dist == 1 or dist == 2 */ | ||
| 282 | unsigned short pat16; | ||
| 283 | |||
| 284 | pat16 = *(sout-2+2*OFF); | ||
| 285 | if (dist == 1) | ||
| 286 | #if defined(__BIG_ENDIAN) | ||
| 287 | pat16 = (pat16 & 0xff) | ((pat16 & 0xff) << 8); | ||
| 288 | #elif defined(__LITTLE_ENDIAN) | ||
| 289 | pat16 = (pat16 & 0xff00) | ((pat16 & 0xff00) >> 8); | ||
| 290 | #else | ||
| 291 | #error __BIG_ENDIAN nor __LITTLE_ENDIAN is defined | ||
| 292 | #endif | ||
| 293 | loops = len >> 1; | ||
| 294 | do | ||
| 295 | PUP(sout) = pat16; | ||
| 296 | while (--loops); | ||
| 297 | out = (unsigned char *)sout + OFF; | ||
| 298 | } | ||
| 299 | if (len & 1) | ||
| 300 | PUP(out) = PUP(from); | ||
| 301 | #else /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */ | ||
| 242 | from = out - dist; /* copy direct from output */ | 302 | from = out - dist; /* copy direct from output */ |
| 243 | do { /* minimum length is three */ | 303 | do { /* minimum length is three */ |
| 244 | PUP(out) = PUP(from); | 304 | PUP(out) = PUP(from); |
| 245 | PUP(out) = PUP(from); | 305 | PUP(out) = PUP(from); |
| 246 | PUP(out) = PUP(from); | 306 | PUP(out) = PUP(from); |
| 247 | len -= 3; | 307 | len -= 3; |
| 248 | } while (len > 2); | 308 | } while (len > 2); |
| 249 | if (len) { | 309 | if (len) { |
| 250 | PUP(out) = PUP(from); | 310 | PUP(out) = PUP(from); |
| 251 | if (len > 1) | 311 | if (len > 1) |
| 252 | PUP(out) = PUP(from); | 312 | PUP(out) = PUP(from); |
| 253 | } | 313 | } |
| 314 | #endif /* !CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */ | ||
| 254 | } | 315 | } |
| 255 | } | 316 | } |
| 256 | else if ((op & 64) == 0) { /* 2nd level distance code */ | 317 | else if ((op & 64) == 0) { /* 2nd level distance code */ |
