@@ -1,5 +1,6 @@
ifeq ($(subdir),string)
-sysdep_routines += stpcpy-generic stpcpy-ual
+sysdep_routines += stpcpy-generic stpcpy-ual memcpy-generic memcpy-ual
CFLAGS-stpcpy-ual.c += -mno-strict-align
+CFLAGS-memcpy-ual.c += -mno-strict-align
endif
new file mode 100644
@@ -0,0 +1,27 @@
+/* Multiarch memcpy 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 (memcpy) __memcpy_generic attribute_hidden;
+
+#define MEMCPY __memcpy_generic
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+
+#include <string/memcpy.c>
new file mode 100644
@@ -0,0 +1,50 @@
+/* Multiarch memcpy 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>
+
+extern __typeof (memcpy) __memcpy_ual attribute_hidden;
+
+#include "wordcopy-ual-inline.c"
+
+#define OPSIZ (sizeof (op_t))
+
+void *
+__memcpy_ual (void *dest, const void *src, size_t len)
+{
+ unsigned long int dstp = (long int) dest;
+ unsigned long int srcp = (long int) src;
+
+ /* If there not too few bytes to copy, use word copy. */
+ if (len >= OP_T_THRES)
+ {
+ /* Copy just a few bytes to make DSTP aligned. Not needed with
+ unaligned access support, but it improves the performance. */
+ len -= (-dstp) % OPSIZ;
+ BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+ _wordcopy_fwd_ual (dstp, srcp, len / OPSIZ);
+ dstp += len & -OPSIZ;
+ srcp += len & -OPSIZ;
+ len %= OPSIZ;
+ }
+
+ BYTE_COPY_FWD (dstp, srcp, len);
+
+ return dest;
+}
new file mode 100644
@@ -0,0 +1,39 @@
+/* Multiple versions of memcpy. 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)
+# undef memcpy
+# define memcpy __redirect_memcpy
+# include <string.h>
+# undef memcpy
+
+extern __typeof (__redirect_memcpy) __libc_memcpy;
+
+extern __typeof (__redirect_memcpy) __memcpy_generic attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_ual attribute_hidden;
+
+# include <loongarch-features.h>
+# define INIT_ARCH()
+
+libc_ifunc (__libc_memcpy,
+ LOONGARCH_HAVE_UAL ? __memcpy_ual : __memcpy_generic);
+strong_alias (__libc_memcpy, memcpy);
+libc_hidden_ver (__libc_memcpy, memcpy)
+#else
+# include <string/memcpy.c>
+#endif
new file mode 100644
@@ -0,0 +1,31 @@
+/* Reuse subroutine from string/wordcopy.c for LoongArch unaligned access.
+ 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 <sys/cdefs.h>
+
+static __always_inline void _wordcopy_fwd_ual (long int, long int, size_t);
+static void _nouse_1 (long int, long int, size_t) __attribute__ ((unused));
+static void _nouse_2 (long int, long int, size_t) __attribute__ ((unused));
+static void _nouse_3 (long int, long int, size_t) __attribute__ ((unused));
+
+#define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_ual
+#define WORDCOPY_BWD_ALIGNED _nouse_1
+#define WORDCOPY_FWD_DEST_ALIGNED _nouse_2
+#define WORDCOPY_BWD_DEST_ALIGNED _nouse_3
+
+#include <string/wordcopy.c>