diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2012-07-12 13:04:55 +0200 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2012-07-19 15:46:34 +0200 |
commit | 08f43f9bbf97c03ec4d2754c69fd9d7efce6ef96 (patch) | |
tree | 17318764c9e7b5e6c151def3bdab1fc30af377ed /sysdeps/s390/s390-32/memcpy.S | |
parent | a98430587c57da2832fa9abe336c5a8f8137e89c (diff) | |
download | glibc-08f43f9bbf97c03ec4d2754c69fd9d7efce6ef96.tar.gz |
S/390: Add support for STT_GNU_IFUNC symbols.
Add support for STT_GNU_IFUNC symbols and the new R_390_IRELATIVE
relocation. Provide optimized version of memcpy, memset, and memcmp
for z10 and z196.
Diffstat (limited to 'sysdeps/s390/s390-32/memcpy.S')
-rw-r--r-- | sysdeps/s390/s390-32/memcpy.S | 90 |
1 files changed, 57 insertions, 33 deletions
diff --git a/sysdeps/s390/s390-32/memcpy.S b/sysdeps/s390/s390-32/memcpy.S index b2a688ea36..90cc4cbf71 100644 --- a/sysdeps/s390/s390-32/memcpy.S +++ b/sysdeps/s390/s390-32/memcpy.S @@ -1,7 +1,6 @@ /* memcpy - copy a block from source to destination. S/390 version. - Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. + Copyright (C) 2012 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -17,42 +16,67 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ + +#include "sysdep.h" +#include "asm-syntax.h" + /* INPUT PARAMETERS %r2 = address of destination memory area %r3 = address of source memory area %r4 = number of bytes to copy. */ -#include "sysdep.h" -#include "asm-syntax.h" - - .text +#ifdef USE_MULTIARCH +ENTRY(memcpy_g5) +#else ENTRY(memcpy) - ltr %r4,%r4 - jz .L3 - ahi %r4,-1 # length - 1 - lr %r1,%r2 # copy destination address - lr %r5,%r4 - srl %r5,8 - ltr %r5,%r5 # < 256 bytes to move ? - jz .L1 - chi %r5,255 # > 1MB to move ? - jh .L4 -.L0: mvc 0(256,%r1),0(%r3) # move in 256 byte chunks - la %r1,256(%r1) - la %r3,256(%r3) - brct %r5,.L0 -.L1: bras %r5,.L2 # setup base pointer for execute - mvc 0(1,%r1),0(%r3) # instruction for execute -.L2: ex %r4,0(%r5) # execute mvc with length ((%r4)&255)+1 -.L3: br %r14 - # data copies > 1MB are faster with mvcle. -.L4: ahi %r4,1 # length + 1 - lr %r5,%r4 # source length - lr %r4,%r3 # source address - lr %r3,%r5 # destination length = source length -.L5: mvcle %r2,%r4,0 # thats it, MVCLE is your friend - jo .L5 - lr %r2,%r1 # return destination address - br %r14 +#endif + .machine "g5" + st %r13,52(%r15) + .cfi_offset 13, -44 + basr %r13,0 +.L_G5_16: + ltr %r4,%r4 + je .L_G5_4 + ahi %r4,-1 + lr %r5,%r4 + srl %r5,8 + ltr %r5,%r5 + lr %r1,%r2 + jne .L_G5_12 + ex %r4,.L_G5_17-.L_G5_16(%r13) +.L_G5_4: + l %r13,52(%r15) + br %r14 +.L_G5_13: + chi %r5,4096 # Switch to mvcle for copies >1MB + jh memcpy_mvcle +.L_G5_12: + mvc 0(256,%r1),0(%r3) + la %r1,256(%r1) + la %r3,256(%r3) + brct %r5,.L_G5_12 + ex %r4,.L_G5_17-.L_G5_16(%r13) + j .L_G5_4 +.L_G5_17: + mvc 0(1,%r1),0(%r3) +#ifdef USE_MULTIARCH +END(memcpy_g5) +#else END(memcpy) libc_hidden_builtin_def (memcpy) +#endif + +ENTRY(memcpy_mvcle) + # Using as standalone function will result in unexpected + # results since the length field is incremented by 1 in order to + # compensate the changes already done in the functions above. + ahi %r4,1 # length + 1 + lr %r5,%r4 # source length + lr %r4,%r3 # source address + lr %r3,%r5 # destination length = source length +.L_MVCLE_1: + mvcle %r2,%r4,0 # thats it, MVCLE is your friend + jo .L_MVCLE_1 + lr %r2,%r1 # return destination address + br %r14 +END(memcpy_mvcle) |