Skip to content

Commit e69eae6

Browse files
Joakim Tjernlundtorvalds
Joakim Tjernlund
authored andcommitted
zlib: make new optimized inflate endian independent
Commit 6846ee5 ("zlib: Fix build of powerpc boot wrapper") made the new optimized inflate only available on arch's that define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS. This patch will again enable the optimization for all arch's by defining our own endian independent version of unaligned access. As an added bonus, arch's that define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS do a plain load instead. Signed-off-by: Joakim Tjernlund <[email protected]> Cc: Anton Blanchard <[email protected]> Cc: Benjamin Herrenschmidt <[email protected]> Cc: David Woodhouse <[email protected]> Cc: Kumar Gala <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 5ceaa2f commit e69eae6

File tree

1 file changed

+30
-40
lines changed

1 file changed

+30
-40
lines changed

lib/zlib_inflate/inffast.c

+30-40
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,6 @@
88
#include "inflate.h"
99
#include "inffast.h"
1010

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-
2611
#ifndef ASMINF
2712

2813
/* Allow machine dependent optimization for post-increment or pre-increment.
@@ -36,14 +21,31 @@
3621
- Pentium III (Anderson)
3722
- M68060 (Nikl)
3823
*/
24+
union uu {
25+
unsigned short us;
26+
unsigned char b[2];
27+
};
28+
29+
/* Endian independed version */
30+
static inline unsigned short
31+
get_unaligned16(const unsigned short *p)
32+
{
33+
union uu mm;
34+
unsigned char *b = (unsigned char *)p;
35+
36+
mm.b[0] = b[0];
37+
mm.b[1] = b[1];
38+
return mm.us;
39+
}
40+
3941
#ifdef POSTINC
4042
# define OFF 0
4143
# define PUP(a) *(a)++
42-
# define UP_UNALIGNED(a) get_unaligned((a)++)
44+
# define UP_UNALIGNED(a) get_unaligned16((a)++)
4345
#else
4446
# define OFF 1
4547
# define PUP(a) *++(a)
46-
# define UP_UNALIGNED(a) get_unaligned(++(a))
48+
# define UP_UNALIGNED(a) get_unaligned16(++(a))
4749
#endif
4850

4951
/*
@@ -256,7 +258,6 @@ void inflate_fast(z_streamp strm, unsigned start)
256258
}
257259
}
258260
else {
259-
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
260261
unsigned short *sout;
261262
unsigned long loops;
262263

@@ -274,22 +275,25 @@ void inflate_fast(z_streamp strm, unsigned start)
274275
sfrom = (unsigned short *)(from - OFF);
275276
loops = len >> 1;
276277
do
278+
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
279+
PUP(sout) = PUP(sfrom);
280+
#else
277281
PUP(sout) = UP_UNALIGNED(sfrom);
282+
#endif
278283
while (--loops);
279284
out = (unsigned char *)sout + OFF;
280285
from = (unsigned char *)sfrom + OFF;
281286
} else { /* dist == 1 or dist == 2 */
282287
unsigned short pat16;
283288

284289
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
290+
if (dist == 1) {
291+
union uu mm;
292+
/* copy one char pattern to both bytes */
293+
mm.us = pat16;
294+
mm.b[0] = mm.b[1];
295+
pat16 = mm.us;
296+
}
293297
loops = len >> 1;
294298
do
295299
PUP(sout) = pat16;
@@ -298,20 +302,6 @@ void inflate_fast(z_streamp strm, unsigned start)
298302
}
299303
if (len & 1)
300304
PUP(out) = PUP(from);
301-
#else /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
302-
from = out - dist; /* copy direct from output */
303-
do { /* minimum length is three */
304-
PUP(out) = PUP(from);
305-
PUP(out) = PUP(from);
306-
PUP(out) = PUP(from);
307-
len -= 3;
308-
} while (len > 2);
309-
if (len) {
310-
PUP(out) = PUP(from);
311-
if (len > 1)
312-
PUP(out) = PUP(from);
313-
}
314-
#endif /* !CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
315305
}
316306
}
317307
else if ((op & 64) == 0) { /* 2nd level distance code */

0 commit comments

Comments
 (0)