[11/20] alpha: add assembly mempcpy sharing the ev6 memcpy

Message ID 169c689ace6b5b034c5517a34d1b68dd517d867a.1786497497.git.mattst88@gmail.com (mailing list archive)
State Superseded
Headers
Series alpha: tune the memory and string routines, and add IFUNC dispatch |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed

Commit Message

Matt Turner Aug. 12, 2026, 1:19 a.m. UTC
  Alpha had no assembly mempcpy and used the generic C.  mempcpy differs from
memcpy only in its return value (dest + n rather than dest), so build it from
the ev6 memcpy with USE_AS_MEMPCPY, following the established convention used
by other architectures.

memcpy.S gains two small, behaviour-preserving changes so it can be reused:
the entry computes the return value through USE_AS_MEMPCPY, and the misaligned
path now derives its working dest pointer and alignment from the (still
original) $16 instead of $0, freeing $0 to carry dest + n for mempcpy.  The
plain memcpy path is unchanged ($0 == $16 on entry).
---
 sysdeps/alpha/alphaev6/memcpy.S  | 13 ++++++++++---
 sysdeps/alpha/alphaev6/mempcpy.S | 27 +++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 3 deletions(-)
 create mode 100644 sysdeps/alpha/alphaev6/mempcpy.S
  

Comments

Adhemerval Zanella Netto Aug. 12, 2026, 8:58 p.m. UTC | #1
On 11/08/26 22:19, Matt Turner wrote:
> Alpha had no assembly mempcpy and used the generic C.  mempcpy differs from
> memcpy only in its return value (dest + n rather than dest), so build it from
> the ev6 memcpy with USE_AS_MEMPCPY, following the established convention used
> by other architectures.
> 
> memcpy.S gains two small, behaviour-preserving changes so it can be reused:
> the entry computes the return value through USE_AS_MEMPCPY, and the misaligned
> path now derives its working dest pointer and alignment from the (still
> original) $16 instead of $0, freeing $0 to carry dest + n for mempcpy.  The
> plain memcpy path is unchanged ($0 == $16 on entry).

Do we really need to essentially duplicate the memcpy code for this optimization?
The alpha ABI cost us a bit more instruction for the function call (compare to
aarch64 for instance), but it does cost a lot less i-cache.

The aarch64 uses the generic mempcpy.c and it seems not be a problem.

> ---
>  sysdeps/alpha/alphaev6/memcpy.S  | 13 ++++++++++---
>  sysdeps/alpha/alphaev6/mempcpy.S | 27 +++++++++++++++++++++++++++
>  2 files changed, 37 insertions(+), 3 deletions(-)
>  create mode 100644 sysdeps/alpha/alphaev6/mempcpy.S
> 
> diff --git ./sysdeps/alpha/alphaev6/memcpy.S ./sysdeps/alpha/alphaev6/memcpy.S
> index d5b72d4961..d11138420d 100644
> --- ./sysdeps/alpha/alphaev6/memcpy.S
> +++ ./sysdeps/alpha/alphaev6/memcpy.S
> @@ -40,7 +40,11 @@
>  ENTRY(memcpy)
>  	.prologue 0
>  
> -	mov	$16, $0			# E : copy dest to return
> +#ifdef USE_AS_MEMPCPY
> +	addq	$16, $18, $0		# E : mempcpy returns dest + n
> +#else
> +	mov	$16, $0			# E : memcpy returns dest
> +#endif
>  	ble	$18, $nomoredata	# U : done with the copy?
>  	xor	$16, $17, $1		# E : are source and dest alignments the same?
>  	and	$1, 7, $1		# E : are they the same mod 8?
> @@ -289,8 +293,9 @@ $tail_bytes:
>  	nop				# E :
>  
>  $misaligned:
> -	mov	$0, $4			# E : dest temp
> -	and	$0, 7, $1		# E : dest alignment mod8
> +	mov	$16, $4			# E : dest temp (orig dest still in $16 here;
> +					#     $0 may hold dest+n for mempcpy)
> +	and	$16, 7, $1		# E : dest alignment mod8
>  	beq	$1, $dest_0mod8		# U : life doesn't totally suck
>  	nop
>  
> @@ -367,4 +372,6 @@ $nomoredata:
>  	nop				# E :
>  
>  END(memcpy)
> +#ifndef USE_AS_MEMPCPY
>  libc_hidden_builtin_def (memcpy)
> +#endif
> diff --git ./sysdeps/alpha/alphaev6/mempcpy.S ./sysdeps/alpha/alphaev6/mempcpy.S
> new file mode 100644
> index 0000000000..95385e4111
> --- /dev/null
> +++ ./sysdeps/alpha/alphaev6/mempcpy.S
> @@ -0,0 +1,27 @@
> +/* Copyright (C) 2026 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/>.  */
> +
> +/* mempcpy is the ev6 memcpy with USE_AS_MEMPCPY, which only changes the
> +   return value (dest + n instead of dest) and the exported symbol.  */
> +
> +#define USE_AS_MEMPCPY
> +#define memcpy __mempcpy
> +#include <sysdeps/alpha/alphaev6/memcpy.S>
> +
> +libc_hidden_def (__mempcpy)
> +weak_alias (__mempcpy, mempcpy)
> +libc_hidden_builtin_def (mempcpy)
  

Patch

diff --git ./sysdeps/alpha/alphaev6/memcpy.S ./sysdeps/alpha/alphaev6/memcpy.S
index d5b72d4961..d11138420d 100644
--- ./sysdeps/alpha/alphaev6/memcpy.S
+++ ./sysdeps/alpha/alphaev6/memcpy.S
@@ -40,7 +40,11 @@ 
 ENTRY(memcpy)
 	.prologue 0
 
-	mov	$16, $0			# E : copy dest to return
+#ifdef USE_AS_MEMPCPY
+	addq	$16, $18, $0		# E : mempcpy returns dest + n
+#else
+	mov	$16, $0			# E : memcpy returns dest
+#endif
 	ble	$18, $nomoredata	# U : done with the copy?
 	xor	$16, $17, $1		# E : are source and dest alignments the same?
 	and	$1, 7, $1		# E : are they the same mod 8?
@@ -289,8 +293,9 @@  $tail_bytes:
 	nop				# E :
 
 $misaligned:
-	mov	$0, $4			# E : dest temp
-	and	$0, 7, $1		# E : dest alignment mod8
+	mov	$16, $4			# E : dest temp (orig dest still in $16 here;
+					#     $0 may hold dest+n for mempcpy)
+	and	$16, 7, $1		# E : dest alignment mod8
 	beq	$1, $dest_0mod8		# U : life doesn't totally suck
 	nop
 
@@ -367,4 +372,6 @@  $nomoredata:
 	nop				# E :
 
 END(memcpy)
+#ifndef USE_AS_MEMPCPY
 libc_hidden_builtin_def (memcpy)
+#endif
diff --git ./sysdeps/alpha/alphaev6/mempcpy.S ./sysdeps/alpha/alphaev6/mempcpy.S
new file mode 100644
index 0000000000..95385e4111
--- /dev/null
+++ ./sysdeps/alpha/alphaev6/mempcpy.S
@@ -0,0 +1,27 @@ 
+/* Copyright (C) 2026 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/>.  */
+
+/* mempcpy is the ev6 memcpy with USE_AS_MEMPCPY, which only changes the
+   return value (dest + n instead of dest) and the exported symbol.  */
+
+#define USE_AS_MEMPCPY
+#define memcpy __mempcpy
+#include <sysdeps/alpha/alphaev6/memcpy.S>
+
+libc_hidden_def (__mempcpy)
+weak_alias (__mempcpy, mempcpy)
+libc_hidden_builtin_def (mempcpy)