1 /*
2 Copyright 2011 Google Inc. All Rights Reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above
11 copyright notice, this list of conditions and the following disclaimer
12 in the documentation and/or other materials provided with the
13 distribution.
14 * Neither the name of Google Inc. nor the names of its
15 contributors may be used to endorse or promote products derived from
16 this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 Various stubs for the open-source version of Snappy.
31
32 File modified for the Linux Kernel by
33 Zeev Tarantov <zeev.tarantov@gmail.com>
34
35 File modified for Sereal by
36 Steffen Mueller <smueller@cpan.org>
37 */
38
39 #ifndef CSNAPPY_INTERNAL_H_
40 #define CSNAPPY_INTERNAL_H_
41
42 #include "csnappy_compat.h"
43
44 #ifndef __KERNEL__
45 #include "csnappy_internal_userspace.h"
46 #include <string.h>
47 #else
48
49 #include <linux/types.h>
50 #include <linux/string.h>
51 #include <linux/compiler.h>
52 #include <asm/byteorder.h>
53 #include <asm/unaligned.h>
54
55 #if (defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)) || \
56 (!defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN))
57 #error either __LITTLE_ENDIAN or __BIG_ENDIAN must be defined
58 #endif
59 #if defined(__LITTLE_ENDIAN)
60 #define __BYTE_ORDER __LITTLE_ENDIAN
61 #else
62 #define __BYTE_ORDER __BIG_ENDIAN
63 #endif
64
65 #ifdef DEBUG
66 #define DCHECK(cond) if (!(cond)) \
67 printk(KERN_DEBUG "assert failed @ %s:%i\n", \
68 __FILE__, __LINE__)
69 #else
70 #define DCHECK(cond)
71 #endif
72
73 #define UNALIGNED_LOAD16(_p) get_unaligned((const uint16_t *)(_p))
74 #define UNALIGNED_LOAD32(_p) get_unaligned((const uint32_t *)(_p))
75 #define UNALIGNED_LOAD64(_p) get_unaligned((const uint64_t *)(_p))
76 #define UNALIGNED_STORE16(_p, _val) put_unaligned((_val), (uint16_t *)(_p))
77 #define UNALIGNED_STORE32(_p, _val) put_unaligned((_val), (uint32_t *)(_p))
78 #define UNALIGNED_STORE64(_p, _val) put_unaligned((_val), (uint64_t *)(_p))
79
80 #define FindLSBSetNonZero(n) __builtin_ctz(n)
81 #define FindLSBSetNonZero64(n) __builtin_ctzll(n)
82
83 #endif /* __KERNEL__ */
84
85 #if (!defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)) || ! defined(__BYTE_ORDER)
86 # error either __LITTLE_ENDIAN or __BIG_ENDIAN, plus __BYTE_ORDER must be defined
87 #endif
88
89 #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) || defined(__ARMV6__) || \
90 defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
91 # define ARCH_ARM_HAVE_UNALIGNED
92 #endif
93
94
UnalignedCopy64(const void * src,void * dst)95 static INLINE void UnalignedCopy64(const void *src, void *dst) {
96 #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(ARCH_ARM_HAVE_UNALIGNED) || defined(__aarch64__)
97 if ((sizeof(void *) == 8) || (sizeof(long) == 8)) {
98 UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src));
99 } else {
100 /* This can be more efficient than UNALIGNED_LOAD64 + UNALIGNED_STORE64
101 on some platforms, in particular ARM. */
102 const uint8_t *src_bytep = (const uint8_t *)src;
103 uint8_t *dst_bytep = (uint8_t *)dst;
104
105 UNALIGNED_STORE32(dst_bytep, UNALIGNED_LOAD32(src_bytep));
106 UNALIGNED_STORE32(dst_bytep + 4, UNALIGNED_LOAD32(src_bytep + 4));
107 }
108 #else
109 const uint8_t *src_bytep = (const uint8_t *)src;
110 uint8_t *dst_bytep = (uint8_t *)dst;
111 dst_bytep[0] = src_bytep[0];
112 dst_bytep[1] = src_bytep[1];
113 dst_bytep[2] = src_bytep[2];
114 dst_bytep[3] = src_bytep[3];
115 dst_bytep[4] = src_bytep[4];
116 dst_bytep[5] = src_bytep[5];
117 dst_bytep[6] = src_bytep[6];
118 dst_bytep[7] = src_bytep[7];
119 #endif
120 }
121
122 #if defined(__arm__)
123 #if defined(ARCH_ARM_HAVE_UNALIGNED)
get_unaligned_le(const void * p,uint32_t n)124 static INLINE uint32_t get_unaligned_le(const void *p, uint32_t n)
125 {
126 uint32_t wordmask = (1U << (8 * n)) - 1;
127 return get_unaligned_le32(p) & wordmask;
128 }
129 #else
130 extern uint32_t get_unaligned_le_armv5(const void *p, uint32_t n);
131 #define get_unaligned_le get_unaligned_le_armv5
132 #endif
133 #else
get_unaligned_le(const void * p,uint32_t n)134 static INLINE uint32_t get_unaligned_le(const void *p, uint32_t n)
135 {
136 /* Mapping from i in range [0,4] to a mask to extract the bottom 8*i bits */
137 static const uint32_t wordmask[] = {
138 0u, 0xffu, 0xffffu, 0xffffffu, 0xffffffffu
139 };
140 return get_unaligned_le32(p) & wordmask[n];
141 }
142 #endif
143
144 #define DCHECK_EQ(a, b) DCHECK(((a) == (b)))
145 #define DCHECK_NE(a, b) DCHECK(((a) != (b)))
146 #define DCHECK_GT(a, b) DCHECK(((a) > (b)))
147 #define DCHECK_GE(a, b) DCHECK(((a) >= (b)))
148 #define DCHECK_LT(a, b) DCHECK(((a) < (b)))
149 #define DCHECK_LE(a, b) DCHECK(((a) <= (b)))
150
151 enum {
152 LITERAL = 0,
153 COPY_1_BYTE_OFFSET = 1, /* 3 bit length + 3 bits of offset in opcode */
154 COPY_2_BYTE_OFFSET = 2,
155 COPY_4_BYTE_OFFSET = 3
156 };
157
158 #endif /* CSNAPPY_INTERNAL_H_ */
159