]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/crc32c_ppc.c
1 /* Copyright (C) 2017 International Business Machines Corp.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
10 #define FAST_ZERO_TABLE
13 #include "include/int_types.h"
14 #include "crc32c_ppc_constants.h"
21 #define VMX_ALIGN_MASK (VMX_ALIGN-1)
24 static unsigned int crc32_align(unsigned int crc
, unsigned char const *p
,
28 crc
= crc_table
[(crc
^ *p
++) & 0xff] ^ (crc
>> 8);
32 static unsigned int crc32_align(unsigned int crc
, unsigned char const *p
,
36 crc
= crc_table
[((crc
>> 24) ^ *p
++) & 0xff] ^ (crc
<< 8);
42 static inline unsigned long polynomial_multiply(unsigned int a
, unsigned int b
) {
43 vector
unsigned int va
= {a
, 0, 0, 0};
44 vector
unsigned int vb
= {b
, 0, 0, 0};
45 vector
unsigned long vt
;
47 __asm__("vpmsumw %0,%1,%2" : "=v"(vt
) : "v"(va
), "v"(vb
));
52 unsigned int barrett_reduction(unsigned long val
);
54 static inline unsigned int gf_multiply(unsigned int a
, unsigned int b
) {
55 return barrett_reduction(polynomial_multiply(a
, b
));
58 unsigned int append_zeros(unsigned int crc
, unsigned long length
) {
63 crc
= gf_multiply(crc
, crc_zero
[i
]);
73 unsigned int __crc32_vpmsum(unsigned int crc
, unsigned char const *p
,
76 static uint32_t crc32_vpmsum(uint32_t crc
, unsigned char const *data
,
79 unsigned int prealign
;
86 if (len
< VMX_ALIGN
+ VMX_ALIGN_MASK
) {
87 crc
= crc32_align(crc
, data
, (unsigned long)len
);
91 if ((unsigned long)data
& VMX_ALIGN_MASK
) {
92 prealign
= VMX_ALIGN
- ((unsigned long)data
& VMX_ALIGN_MASK
);
93 crc
= crc32_align(crc
, data
, prealign
);
98 crc
= __crc32_vpmsum(crc
, data
, (unsigned long)len
& ~VMX_ALIGN_MASK
);
100 tail
= len
& VMX_ALIGN_MASK
;
102 data
+= len
& ~VMX_ALIGN_MASK
;
103 crc
= crc32_align(crc
, data
, tail
);
114 /* This wrapper function works around the fact that crc32_vpmsum
115 * does not gracefully handle the case where the data pointer is NULL.
117 uint32_t ceph_crc32c_ppc(uint32_t crc
, unsigned char const *data
, unsigned len
)
120 /* Handle the NULL buffer case. */
122 crc
= reverse_bits(crc
);
125 crc
= append_zeros(crc
, len
);
128 crc
= reverse_bits(crc
);
131 /* Handle the valid buffer case. */
132 crc
= crc32_vpmsum(crc
, data
, (unsigned long)len
);
137 #else /* HAVE_POWER8 */
139 /* This symbol has to exist on non-ppc architectures (and on legacy
140 * ppc systems using power7 or below) in order to compile properly
141 * there, even though it won't be called.
143 uint32_t ceph_crc32c_ppc(uint32_t crc
, unsigned char const *data
, unsigned len
)
148 #endif /* HAVE_POWER8 */