]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/crc32c_ppc.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / common / crc32c_ppc.c
1 /* Copyright (C) 2017 International Business Machines Corp.
2 * All rights reserved.
3 *
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.
8 */
9 #define CRC_TABLE
10 #include "acconfig.h"
11 #include "include/int_types.h"
12 #include "crc32c_ppc_constants.h"
13
14 #include <stdlib.h>
15 #include <strings.h>
16
17 #define VMX_ALIGN 16
18 #define VMX_ALIGN_MASK (VMX_ALIGN-1)
19
20 #ifdef REFLECT
21 static unsigned int crc32_align(unsigned int crc, unsigned char const *p,
22 unsigned long len)
23 {
24 while (len--)
25 crc = crc_table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
26 return crc;
27 }
28 #else
29 static unsigned int crc32_align(unsigned int crc, unsigned char const *p,
30 unsigned long len)
31 {
32 while (len--)
33 crc = crc_table[((crc >> 24) ^ *p++) & 0xff] ^ (crc << 8);
34 return crc;
35 }
36 #endif
37
38
39 #ifdef HAVE_POWER8
40 unsigned int __crc32_vpmsum(unsigned int crc, unsigned char const *p,
41 unsigned long len);
42
43 static uint32_t crc32_vpmsum(uint32_t crc, unsigned char const *data,
44 unsigned len)
45 {
46 unsigned int prealign;
47 unsigned int tail;
48
49 #ifdef CRC_XOR
50 crc ^= 0xffffffff;
51 #endif
52
53 if (len < VMX_ALIGN + VMX_ALIGN_MASK) {
54 crc = crc32_align(crc, data, (unsigned long)len);
55 goto out;
56 }
57
58 if ((unsigned long)data & VMX_ALIGN_MASK) {
59 prealign = VMX_ALIGN - ((unsigned long)data & VMX_ALIGN_MASK);
60 crc = crc32_align(crc, data, prealign);
61 len -= prealign;
62 data += prealign;
63 }
64
65 crc = __crc32_vpmsum(crc, data, (unsigned long)len & ~VMX_ALIGN_MASK);
66
67 tail = len & VMX_ALIGN_MASK;
68 if (tail) {
69 data += len & ~VMX_ALIGN_MASK;
70 crc = crc32_align(crc, data, tail);
71 }
72
73 out:
74 #ifdef CRC_XOR
75 crc ^= 0xffffffff;
76 #endif
77
78 return crc;
79 }
80
81 /* This wrapper function works around the fact that crc32_vpmsum
82 * does not gracefully handle the case where the data pointer is NULL. There
83 * may be room for performance improvement here.
84 */
85 uint32_t ceph_crc32c_ppc(uint32_t crc, unsigned char const *data, unsigned len)
86 {
87 unsigned char *buf2;
88
89 if (!data) {
90 buf2 = malloc(len);
91 bzero(buf2, len);
92 crc = crc32_vpmsum(crc, buf2, len);
93 free(buf2);
94 } else {
95 crc = crc32_vpmsum(crc, data, (unsigned long)len);
96 }
97 return crc;
98 }
99
100 #else /* HAVE_POWER8 */
101
102 /* This symbol has to exist on non-ppc architectures (and on legacy
103 * ppc systems using power7 or below) in order to compile properly
104 * there, even though it won't be called.
105 */
106 uint32_t ceph_crc32c_ppc(uint32_t crc, unsigned char const *data, unsigned len)
107 {
108 return 0;
109 }
110
111 #endif /* HAVE_POWER8 */