summaryrefslogtreecommitdiff
path: root/libc/string/cris/strncpy.c
diff options
context:
space:
mode:
authorPeter Kjellerstedt <peter.kjellerstedt@axis.com>2007-11-21 12:34:41 +0000
committerPeter Kjellerstedt <peter.kjellerstedt@axis.com>2007-11-21 12:34:41 +0000
commit90f1927f14e9cdbae37981af728af8e727838069 (patch)
treea501f0526428f3c1e3f1150496b5e87fbb2c88c0 /libc/string/cris/strncpy.c
parentb0f709e6c8c87833dda6701adfd4857bcba7e7fb (diff)
Added optimized versions of strcpy() and strncpy() for CRIS/CRISv32.
Diffstat (limited to 'libc/string/cris/strncpy.c')
-rw-r--r--libc/string/cris/strncpy.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/libc/string/cris/strncpy.c b/libc/string/cris/strncpy.c
new file mode 100644
index 000000000..93a6608bc
--- /dev/null
+++ b/libc/string/cris/strncpy.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2006-2007 Axis Communications AB
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <string.h>
+
+libc_hidden_proto(memset)
+
+libc_hidden_proto(strncpy)
+char *strncpy(char *dest, const char *src, size_t count)
+{
+ char *ret = dest;
+ unsigned long himagic = 0x80808080L;
+ unsigned long lomagic = 0x01010101L;
+
+ while (count && (unsigned long)src & (sizeof src - 1))
+ {
+ count--;
+ if (!(*dest++ = *src++))
+ {
+ goto finalize;
+ }
+ }
+
+ while (count >= sizeof (unsigned long))
+ {
+ unsigned long value = *(unsigned long*)src;
+ unsigned long magic;
+
+ if ((magic = (value - lomagic) & himagic))
+ {
+ if (magic & ~value)
+ {
+ break;
+ }
+ }
+
+ *(unsigned long*)dest = value;
+ dest += sizeof (unsigned long);
+ src += sizeof (unsigned long);
+ count -= sizeof (unsigned long);
+ }
+
+ while (count)
+ {
+ count--;
+ if (!(*dest++ = *src++))
+ break;
+ }
+
+finalize:
+ if (count)
+ {
+ memset(dest, '\0', count);
+ }
+
+ return ret;
+}
+libc_hidden_def(strncpy)