[4/5] LoongArch: Multiarch stpcpy for unaligned access

Message ID 20230415112340.38431-5-xry111@xry111.site
State New
Headers
Series LoongArch: Multiarch string and memory copy routines for unaligned access |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent

Commit Message

Xi Ruoyao April 15, 2023, 11:23 a.m. UTC
  When the CPU supports unaligned access, we can align the src pointer
first (to avoid a segmentation fault if a small source string is located
at the end of a page), then just copy the string pretending both src and
dest are aligned.
---
 sysdeps/loongarch/multiarch/Makefile         |  5 +++
 sysdeps/loongarch/multiarch/stpcpy-generic.c | 25 ++++++++++++
 sysdeps/loongarch/multiarch/stpcpy-ual.c     | 43 ++++++++++++++++++++
 sysdeps/loongarch/multiarch/stpcpy.c         | 37 +++++++++++++++++
 4 files changed, 110 insertions(+)
 create mode 100644 sysdeps/loongarch/multiarch/Makefile
 create mode 100644 sysdeps/loongarch/multiarch/stpcpy-generic.c
 create mode 100644 sysdeps/loongarch/multiarch/stpcpy-ual.c
 create mode 100644 sysdeps/loongarch/multiarch/stpcpy.c
  

Patch

diff --git a/sysdeps/loongarch/multiarch/Makefile b/sysdeps/loongarch/multiarch/Makefile
new file mode 100644
index 0000000000..958752bcbd
--- /dev/null
+++ b/sysdeps/loongarch/multiarch/Makefile
@@ -0,0 +1,5 @@ 
+ifeq ($(subdir),string)
+sysdep_routines += stpcpy-generic stpcpy-ual
+
+CFLAGS-stpcpy-ual.c += -mno-strict-align
+endif
diff --git a/sysdeps/loongarch/multiarch/stpcpy-generic.c b/sysdeps/loongarch/multiarch/stpcpy-generic.c
new file mode 100644
index 0000000000..487388372f
--- /dev/null
+++ b/sysdeps/loongarch/multiarch/stpcpy-generic.c
@@ -0,0 +1,25 @@ 
+/* Multiarch stpcpy for LoongArch.  Generic version.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+extern __typeof (stpcpy) __stpcpy_generic attribute_hidden;
+
+#define STPCPY __stpcpy_generic
+
+#include <string/stpcpy.c>
diff --git a/sysdeps/loongarch/multiarch/stpcpy-ual.c b/sysdeps/loongarch/multiarch/stpcpy-ual.c
new file mode 100644
index 0000000000..9cd13e7fef
--- /dev/null
+++ b/sysdeps/loongarch/multiarch/stpcpy-ual.c
@@ -0,0 +1,43 @@ 
+/* Multiarch stpcpy for LoongArch.  Unaligned access version.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+static __typeof (stpcpy) __stpcpy_unused __attribute__ ((unused));
+extern __typeof (stpcpy) __stpcpy_ual attribute_hidden;
+
+#define STPCPY __stpcpy_unused
+
+#include <string/stpcpy.c>
+
+char *
+__stpcpy_ual (char *dest, const char *src)
+{
+  /* Copy just a few bytes to make SRC aligned.  It's needed not to trigger
+     a segmentation fault when a short string is at the end of a segment.  */
+  size_t len = (-(uintptr_t) src) % OPSIZ;
+  for (; len != 0; len--, ++dest)
+    {
+      char c = *src++;
+      *dest = c;
+      if (c == '\0')
+	return dest;
+    }
+
+  return stpcpy_aligned_loop ((op_t *) dest, (const op_t *) src);
+}
diff --git a/sysdeps/loongarch/multiarch/stpcpy.c b/sysdeps/loongarch/multiarch/stpcpy.c
new file mode 100644
index 0000000000..58bfb1c89d
--- /dev/null
+++ b/sysdeps/loongarch/multiarch/stpcpy.c
@@ -0,0 +1,37 @@ 
+/* Multiple versions of stpcpy.  LoongArch version.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#if defined SHARED && IS_IN (libc)
+# define __NO_STRING_INLINES
+# define NO_MEMPCPY_STPCPY_REDIRECT
+# include <string.h>
+
+extern __typeof (__stpcpy) __stpcpy_generic attribute_hidden;
+extern __typeof (__stpcpy) __stpcpy_ual attribute_hidden;
+
+# include <loongarch-features.h>
+# define INIT_ARCH()
+
+libc_ifunc_hidden (__stpcpy, __stpcpy,
+		   LOONGARCH_HAVE_UAL ? __stpcpy_ual : __stpcpy_generic);
+weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
+libc_hidden_def (stpcpy)
+#else
+# include <string/stpcpy.c>
+#endif