summaryrefslogtreecommitdiffstats
path: root/src/common/crc32c_intel_fast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/crc32c_intel_fast.c')
-rw-r--r--src/common/crc32c_intel_fast.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/common/crc32c_intel_fast.c b/src/common/crc32c_intel_fast.c
new file mode 100644
index 000000000..28bd93416
--- /dev/null
+++ b/src/common/crc32c_intel_fast.c
@@ -0,0 +1,51 @@
+#include "acconfig.h"
+#include "common/crc32c_intel_baseline.h"
+
+extern unsigned int crc32_iscsi_00(unsigned char const *buffer, uint64_t len, uint64_t crc) asm("crc32_iscsi_00");
+extern unsigned int crc32_iscsi_zero_00(unsigned char const *buffer, uint64_t len, uint64_t crc) asm("crc32_iscsi_zero_00");
+
+#ifdef HAVE_NASM_X64
+
+uint32_t ceph_crc32c_intel_fast(uint32_t crc, unsigned char const *buffer, unsigned len)
+{
+ uint32_t v;
+ unsigned left;
+
+ if (!buffer)
+ {
+ return crc32_iscsi_zero_00(buffer, len, crc);
+ }
+
+ /*
+ * the crc32_iscsi_00 method reads past buffer+len (because it
+ * reads full words) which makes valgrind unhappy. don't do
+ * that.
+ */
+ if (len < 16)
+ return ceph_crc32c_intel_baseline(crc, buffer, len);
+ left = ((unsigned long)buffer + len) & 7;
+ len -= left;
+ v = crc32_iscsi_00(buffer, len, crc);
+ if (left)
+ v = ceph_crc32c_intel_baseline(v, buffer + len, left);
+ return v;
+}
+
+int ceph_crc32c_intel_fast_exists(void)
+{
+ return 1;
+}
+
+#else
+
+int ceph_crc32c_intel_fast_exists(void)
+{
+ return 0;
+}
+
+uint32_t ceph_crc32c_intel_fast(uint32_t crc, unsigned char const *buffer, unsigned len)
+{
+ return 0;
+}
+
+#endif