summaryrefslogtreecommitdiff
path: root/extra/crc32-vpmsum/crc32_wrapper.ic
diff options
context:
space:
mode:
Diffstat (limited to 'extra/crc32-vpmsum/crc32_wrapper.ic')
-rw-r--r--extra/crc32-vpmsum/crc32_wrapper.ic52
1 files changed, 52 insertions, 0 deletions
diff --git a/extra/crc32-vpmsum/crc32_wrapper.ic b/extra/crc32-vpmsum/crc32_wrapper.ic
new file mode 100644
index 00000000000..750e971f83e
--- /dev/null
+++ b/extra/crc32-vpmsum/crc32_wrapper.ic
@@ -0,0 +1,52 @@
+#ifdef __powerpc__
+
+
+#define VMX_ALIGN 16
+#define VMX_ALIGN_MASK (VMX_ALIGN-1)
+
+static unsigned int crc32_align(unsigned int crc, unsigned char *p,
+ unsigned long len)
+{
+ while (len--)
+ crc = crc_table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ return crc;
+}
+
+unsigned int __F(unsigned int crc, unsigned char *p,
+ unsigned long len);
+
+unsigned int F(unsigned int crc, unsigned char *p,
+ unsigned long len)
+{
+ unsigned int prealign;
+ unsigned int tail;
+
+ crc ^= 0xffffffff;
+
+ if (len < VMX_ALIGN + VMX_ALIGN_MASK) {
+ crc = crc32_align(crc, p, len);
+ goto out;
+ }
+
+ if ((unsigned long)p & VMX_ALIGN_MASK) {
+ prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK);
+ crc = crc32_align(crc, p, prealign);
+ len -= prealign;
+ p += prealign;
+ }
+
+ crc = __F(crc, p, len & ~VMX_ALIGN_MASK);
+
+ tail = len & VMX_ALIGN_MASK;
+ if (tail) {
+ p += len & ~VMX_ALIGN_MASK;
+ crc = crc32_align(crc, p, tail);
+ }
+
+out:
+ crc ^= 0xffffffff;
+
+ return crc;
+}
+
+#endif /* __powerpc__ */