diff options
Diffstat (limited to 'sysdeps/s390/s390-64')
31 files changed, 2137 insertions, 0 deletions
diff --git a/sysdeps/s390/s390-64/Dist b/sysdeps/s390/s390-64/Dist new file mode 100644 index 0000000000..f25a6dc50c --- /dev/null +++ b/sysdeps/s390/s390-64/Dist @@ -0,0 +1,3 @@ +s390x-mcount.S +machine-gmon.h +fpu/fenv_libc.h diff --git a/sysdeps/s390/s390-64/Implies b/sysdeps/s390/s390-64/Implies new file mode 100644 index 0000000000..b3f92020c5 --- /dev/null +++ b/sysdeps/s390/s390-64/Implies @@ -0,0 +1,4 @@ +wordsize-64 +ieee754 +ieee754/dbl-64 +ieee754/flt-32 diff --git a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile new file mode 100644 index 0000000000..179c122de7 --- /dev/null +++ b/sysdeps/s390/s390-64/Makefile @@ -0,0 +1,11 @@ +pic-ccflag = -fPIC + +ifeq ($(subdir),gmon) +sysdep_routines += s390x-mcount +endif + +ifeq ($(subdir),elf) +CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused +CFLAGS-dl-load.c += -Wno-unused +CFLAGS-dl-reloc.c += -Wno-unused +endif diff --git a/sysdeps/s390/s390-64/__longjmp.c b/sysdeps/s390/s390-64/__longjmp.c new file mode 100644 index 0000000000..d194024dde --- /dev/null +++ b/sysdeps/s390/s390-64/__longjmp.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2001 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <sysdep.h> +#include <setjmp.h> +#include <bits/setjmp.h> +#include <stdlib.h> +#include <unistd.h> + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. */ +void +__longjmp (__jmp_buf env, int val) +{ + /* Restore registers and jump back. */ + asm volatile ("lgr %%r2,%0\n\t" /* Put val in grp 2. */ + "ld %%f7,104(%1)\n\t" + "ld %%f5,96(%1)\n\t" + "ld %%f3,88(%1)\n\t" + "ld %%f1,80(%1)\n\t" + "lmg %%r6,%%r15,0(%1)\n\t" + "br %%r14" + : : "r" (val == 0 ? 1 : val), + "a" (env) : "2" ); + + /* Avoid `volatile function does return' warnings. */ + for (;;); +} + diff --git a/sysdeps/s390/s390-64/add_n.S b/sysdeps/s390/s390-64/add_n.S new file mode 100644 index 0000000000..734b7736e5 --- /dev/null +++ b/sysdeps/s390/s390-64/add_n.S @@ -0,0 +1,63 @@ +/* Add two limb vectors of the same length > 0 and store sum in a third + limb vector. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU MP Library. + + The GNU MP Library is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + The GNU MP 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with the GNU MP Library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +/* + INPUT PARAMETERS + res_ptr %r2 + s1_ptr %r3 + s2_ptr %r4 + size %r5 +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(__mpn_add_n) + stg %r6,48(%r15) # save register 6 + slgr %r1,%r1 + lghi %r0,1 # cannot use ahi to add carry, use alr +.L0: lg %r6,0(%r1,%r3) # .L0 -> no carry from last add + alg %r6,0(%r1,%r4) + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brc 3,.L3 +.L1: brct %r5,.L0 + slgr %r2,%r2 # no last carry to return + j .Lexit +.L2: lg %r6,0(%r1,%r3) # .L2 -> carry from last add + alg %r6,0(%r1,%r4) + brc 3,.L4 + algr %r6,%r0 # no carry yet, add carry from last add + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brc 12,.L1 # new carry ? +.L3: brct %r5,.L2 + lgr %r2,%r0 # return last carry + j .Lexit +.L4: algr %r6,%r0 # already a carry, add carry from last add + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brct %r5,.L2 + lgr %r2,%r0 # return last carry +.Lexit: lg %r6,48(%r15) # restore register 6 + br %r14 +END(__mpn_add_n) diff --git a/sysdeps/s390/s390-64/atomicity.h b/sysdeps/s390/s390-64/atomicity.h new file mode 100644 index 0000000000..039496e905 --- /dev/null +++ b/sysdeps/s390/s390-64/atomicity.h @@ -0,0 +1,76 @@ +/* Low-level functions for atomic operations. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _ATOMICITY_H +#define _ATOMICITY_H 1 + +#include <inttypes.h> + +static inline int +__attribute__ ((unused)) +exchange_and_add (volatile uint32_t *mem, int val) +{ + int result; + __asm__ __volatile__( + " L %0,%2\n" + " LA 2,%1\n" + "0: LR 0,%0\n" + " AR 0,%3\n" + " CS %0,0,0(2)\n" + " JL 0b" + : "=&d" (result), "=m" (*mem) + : "1" (*mem), "d" (val) : "0", "1", "2" ); + return result; +} + +static inline void +__attribute__ ((unused)) +atomic_add (volatile uint32_t *mem, int val) +{ + __asm__ __volatile__( + " LA 2,%0\n" + "0: L 0,%1\n" + " LR 1,0\n" + " AR 1,%2\n" + " CS 0,1,0(2)\n" + " JL 0b" + : "=m" (*mem) : "0" (*mem), "d" (val) : "0", "1", "2" ); +} + +static inline int +__attribute__ ((unused)) +compare_and_swap (volatile long int *p, long int oldval, long int newval) +{ + int retval; + + __asm__ __volatile__( + " la 1,%1\n" + " lgr 0,%2\n" + " csg 0,%3,0(1)\n" + " ipm %0\n" + " srl %0,28\n" + "0:" + : "=&r" (retval), "+m" (*p) + : "d" (oldval) , "d" (newval) + : "memory", "0", "1", "cc"); + return !retval; +} + +#endif /* atomicity.h */ diff --git a/sysdeps/s390/s390-64/backtrace.c b/sysdeps/s390/s390-64/backtrace.c new file mode 100644 index 0000000000..15ab214875 --- /dev/null +++ b/sysdeps/s390/s390-64/backtrace.c @@ -0,0 +1,81 @@ +/* Return backtrace of current program state. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <execinfo.h> +#include <stddef.h> + + +/* This is a global variable set at program start time. It marks the + highest used stack address. */ +extern void *__libc_stack_end; + + +/* This is the stack layout we see for every non-leaf function. + size offset + %r15 -> +------------------+ + 8 | back chain | 0 + 8 | end of stack | 8 + 32 | scratch | 16 + 80 | save area r6-r15 | 48 + 16 | save area f4,f6 | 128 + 16 | empty | 144 + +------------------+ + r14 in the save area holds the return address. +*/ + +struct layout +{ + long back_chain; + long end_of_stack; + long scratch[4]; + long save_grps[10]; + long save_fp[2]; + long empty[2]; +}; + +int +__backtrace (array, size) + void **array; + int size; +{ + /* We assume that all the code is generated with frame pointers set. */ + struct layout *stack; + int cnt = 0; + + asm ("LGR %0,%%r15" : "=d" (stack) ); + /* We skip the call to this function, it makes no sense to record it. */ + stack = (struct layout *) stack->back_chain; + while (cnt < size) + { + if (stack == NULL || (void *) stack > __libc_stack_end) + /* This means the address is out of range. Note that for the + toplevel we see a frame pointer with value NULL which clearly is + out of range. */ + break; + + array[cnt++] = stack->save_grps[9]; + + stack = (struct layout *) stack->back_chain; + } + + return cnt; +} +weak_alias (__backtrace, backtrace) + diff --git a/sysdeps/s390/s390-64/bcopy.S b/sysdeps/s390/s390-64/bcopy.S new file mode 100644 index 0000000000..5cb02b3162 --- /dev/null +++ b/sysdeps/s390/s390-64/bcopy.S @@ -0,0 +1,61 @@ +/* bcopy -- copy a block from source to destination. 64 bit S/390 version. + This file is part of the GNU C Library. + Copyright (C) 2001 Free Software Foundation, Inc. + 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 Library General Public License as + published by the Free Software Foundation ; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* INPUT PARAMETERS + %r2 = address of source + %r3 = address of destination + %r4 = number of bytes to copy. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(__bcopy) + clgr %r2,%r3 # check against destructive overlap + jnl .L0 + lgr %r1,%r2 + algr %r1,%r4 + clgr %r1,%r3 + jh .L2 +.L0: + lgr %r5,%r4 # source length + lgr %r4,%r2 # source address + sgr %r1,%r1 # set pad byte to zero + lgr %r2,%r3 # set destination + lgr %r3,%r5 # destination length = source length +.L1: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend + jo .L1 + br %r14 +.L2: # destructive overlay, can not use mvcle + lgr %r1,%r2 # bcopy is called with source,dest + lgr %r2,%r3 # memmove with dest,source! Oh, well... + lgr %r3,%r1 +#ifdef PIC + jg memmove@PLT +#else + jg memmove +#endif + +END(__bcopy) + +#ifndef NO_WEAK_ALIAS +weak_alias (__bcopy, bcopy) +#endif + diff --git a/sysdeps/s390/s390-64/bits/byteswap.h b/sysdeps/s390/s390-64/bits/byteswap.h new file mode 100644 index 0000000000..71b33f0d85 --- /dev/null +++ b/sysdeps/s390/s390-64/bits/byteswap.h @@ -0,0 +1,93 @@ +/* Macros to swap the order of bytes in integer values. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if !defined _BYTESWAP_H && !defined _NETINET_IN_H +# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead." +#endif + +#define __bswap_constant_16(x) \ + ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) + +/* Swap bytes in 16 bit value. */ +#if defined __GNUC__ && __GNUC__ >= 2 +# define __bswap_16(x) \ + (__extension__ \ + ({ unsigned short int __v; \ + if (__builtin_constant_p (x)) \ + __v = __bswap_constant_16 (x); \ + else { \ + unsigned short int __tmp = (unsigned short int) (x); \ + __asm__ __volatile__ ( \ + "lrvh %0,%1" \ + : "=&d" (__v) : "m" (__tmp) ); \ + } \ + __v; })) +#else +/* This is better than nothing. */ +#define __bswap_16(x) __bswap_constant_16 (x) +#endif + +/* Swap bytes in 32 bit value. */ +#define __bswap_constant_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +#if defined __GNUC__ && __GNUC__ >= 2 +# define __bswap_32(x) \ + (__extension__ \ + ({ unsigned int __v; \ + if (__builtin_constant_p (x)) \ + __v = __bswap_constant_32 (x); \ + else { \ + unsigned int __tmp = (unsigned int) (x); \ + __asm__ __volatile__ ( \ + "lrv %0,%1" \ + : "=&d" (__v) : "m" (__tmp)); \ + } \ + __v; })) +#else +# define __bswap_32(x) __bswap_constant_32 (x) +#endif + +/* Swap bytes in 64 bit value. */ +#define __bswap_constant_64(x) \ + ((((x)&0xff00000000000000) >> 56) | (((x)&0x00ff000000000000) >> 40) | \ + (((x)&0x0000ff0000000000) >> 24) | (((x)&0x000000ff00000000) >> 8) | \ + (((x)&0x00000000ff000000) << 8) | (((x)&0x0000000000ff0000) << 24) | \ + (((x)&0x000000000000ff00) << 40) | (((x)&0x00000000000000ff) << 56)) + +#if defined __GNUC__ && __GNUC__ >= 2 +# define __bswap_64(x) \ + (__extension__ \ + ({ unsigned long __w; \ + if (__builtin_constant_p (x)) \ + __w = __bswap_constant_64 (x); \ + else { \ + unsigned long __tmp = (unsigned long) (x); \ + __asm__ __volatile__ ( \ + "lrvg %0,%1" \ + : "=&d" (__w) : "m" (__tmp)); \ + } \ + __w; })) +#else +# define __bswap_64(x) __bswap_constant_64 (x) +#endif + + diff --git a/sysdeps/s390/s390-64/bits/huge_val.h b/sysdeps/s390/s390-64/bits/huge_val.h new file mode 100644 index 0000000000..f6fd431953 --- /dev/null +++ b/sysdeps/s390/s390-64/bits/huge_val.h @@ -0,0 +1,69 @@ +/* `HUGE_VAL' constants for 64 bit S/390 (where it is infinity). + Used by <stdlib.h> and <math.h> functions for overflow. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _MATH_H +# error "Never use <bits/huge_val.h> directly; include <math.h> instead." +#endif + +#include <features.h> + +/* IEEE positive infinity (-HUGE_VAL is negative infinity). */ + +#if __GNUC_PREREQ(2,96) +# define HUGE_VAL (__extension__ 0x1.0p2047) +#else +# define __HUGE_VAL_bytes { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } + +# define __huge_val_t union { unsigned char __c[8]; double __d; } +# ifdef __GNUC__ +# define HUGE_VAL (__extension__ \ + ((__huge_val_t) { __c: __HUGE_VAL_bytes }).__d) +# else /* Not GCC. */ +static __huge_val_t __huge_val = { __HUGE_VAL_bytes }; +# define HUGE_VAL (__huge_val.__d) +# endif /* GCC. */ +#endif /* GCC 2.95 */ + + +/* ISO C 99 extensions: (float) HUGE_VALF and (long double) HUGE_VALL. */ + +#ifdef __USE_ISOC99 + +# if __GNUC_PREREQ(2,96) +# define HUGE_VALF (__extension__ 0x1.0p255f) +# define HUGE_VALL (__extension__ 0x1.0p255f) +# else +# define __HUGE_VALF_bytes { 0x7f, 0x80, 0, 0 } +# define __huge_valf_t union { unsigned char __c[4]; float __f; } +# ifdef __GNUC__ +# define HUGE_VALF (__extension__ \ + ((__huge_valf_t) { __c: __HUGE_VALF_bytes }).__f) +# else /* Not GCC. */ +static __huge_valf_t __huge_valf = { __HUGE_VALF_bytes }; +# define HUGE_VALF (__huge_valf.__f) +# endif /* GCC. */ + +/* On 390 there is no 'long double' format. Make it the same as 'double' */ +# define HUGE_VALL HUGE_VAL + +# endif /* GCC 2.95 */ + +#endif /* __USE_ISOC99. */ diff --git a/sysdeps/s390/s390-64/bits/setjmp.h b/sysdeps/s390/s390-64/bits/setjmp.h new file mode 100644 index 0000000000..d5c7d564e1 --- /dev/null +++ b/sysdeps/s390/s390-64/bits/setjmp.h @@ -0,0 +1,53 @@ +/* Copyright (C) 2001 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Define the machine-dependent type `jmp_buf'. 64 bit S/390 version. */ + +#ifndef __S390_SETJMP_H__ +#define __S390_SETJMP_H__ + +#define __JB_GPR6 0 +#define __JB_GPR7 1 +#define __JB_GPR8 2 +#define __JB_GPR9 3 +#define __JB_GPR10 4 +#define __JB_GPR11 5 +#define __JB_GPR12 6 +#define __JB_GPR13 7 +#define __JB_GPR14 8 +#define __JB_GPR15 9 + +#ifndef _ASM + +typedef struct { + /* We save registers 6-15. */ + long int gregs[10]; + + /* We save fpu registers 4 and 6. */ + long fpregs[8]; +} __jmp_buf[1]; + +#endif + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((int) (address) < (jmpbuf)->gregs[__JB_GPR15]) + +#endif /* __S390_SETJMP_H__ */ + diff --git a/sysdeps/s390/s390-64/bits/string.h b/sysdeps/s390/s390-64/bits/string.h new file mode 100644 index 0000000000..7acc2b128f --- /dev/null +++ b/sysdeps/s390/s390-64/bits/string.h @@ -0,0 +1,153 @@ +/* Optimized, inlined string functions. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _STRING_H +# error "Never use <bits/string.h> directly; include <string.h> instead." +#endif + +/* The s390 processors can access unaligned multi-byte variables. */ +#define _STRING_ARCH_unaligned 1 + +/* We only provide optimizations if the user selects them and if + GNU CC is used. */ +#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \ + && defined __GNUC__ && __GNUC__ >= 2 + +#ifndef __STRING_INLINE +# ifdef __cplusplus +# define __STRING_INLINE inline +# else +# define __STRING_INLINE extern __inline +# endif +#endif + +#define _HAVE_STRING_ARCH_strlen 1 +#ifndef _FORCE_INLINES +__STRING_INLINE size_t +strlen (__const char *__str) +{ + size_t __len; + + __asm__ __volatile__ (" sgr 0,0\n" + " lgr %0,%1\n" + "0: srst 0,%0\n" + " jo 0b\n" + " lgr %0,0\n" + " sgr %0,%1" + : "=&a" (__len) : "a" (__str) + : "cc", "0" ); + return __len; +} +#endif + +/* Copy SRC to DEST. */ +#define _HAVE_STRING_ARCH_strcpy 1 +#ifndef _FORCE_INLINES +__STRING_INLINE char * +strcpy (char *__dest, __const char *__src) +{ + char *tmp = __dest; + + __asm__ __volatile__ (" sgr 0,0\n" + "0: mvst %0,%1\n" + " jo 0b" + : "+&a" (__dest), "+&a" (__src) : + : "cc", "memory", "0" ); + return tmp; +} +#endif + +#define _HAVE_STRING_ARCH_strncpy 1 +#ifndef _FORCE_INLINES +__STRING_INLINE char * +strncpy (char *__dest, __const char *__src, size_t __n) +{ + char *tmp = __dest; + + if (__n <= 0) + return tmp; + __asm__ __volatile (" slgr %0,%1\n" + "0: icm 0,1,0(%1)\n" + " stc 0,0(%0,%1)\n" + " jz 2f\n" + " la %1,1(%1)\n" + " brct %2,0b\n" + " j 3f\n" + "1: la %1,1(%1)\n" + " stc 0,0(%0,%1)\n" + "2: brct %2,1b\n" + "3:" + : "+&a" (__dest), "+&a" (__src), "+&d" (__n) : + : "cc", "memory", "0" ); + return tmp; +} +#endif + +/* Append SRC onto DEST. */ +#define _HAVE_STRING_ARCH_strcat 1 +#ifndef _FORCE_INLINES +__STRING_INLINE char * +strcat(char *__dest, const char *__src) +{ + char *tmp = __dest; + + __asm__ __volatile__ (" sgr 0,0\n" + "0: srst 0,%0\n" + " jo 0b\n" + " lgr %0,0\n" + " sgr 0,0\n" + "1: mvst %0,%1\n" + " jo 1b" + : "+&a" (__dest), "+&a" (__src) : + : "cc", "memory", "0" ); + return tmp; +} +#endif + +/* Append no more than N characters from SRC onto DEST. */ +#define _HAVE_STRING_ARCH_strncat 1 +#ifndef _FORCE_INLINES +__STRING_INLINE char * +strncat (char *__dest, __const char *__src, size_t __n) +{ + char *tmp = __dest; + + if (__n <= 0) + return tmp; + __asm__ __volatile__ (" sgr 0,0\n" + "0: srst 0,%0\n" + " jo 0b\n" + " lgr %0,0\n" + " slgr %0,%1\n" + "1: icm 0,1,0(%1)\n" + " stc 0,0(%0,%1)\n" + " jz 2f\n" + " la %1,1(%1)\n" + " brct %2,1b\n" + " la %0,0(%0,%1)\n" + " xc 0(1,%0),0(%0)\n" + "2:" + : "+&a" (__dest), "+&a" (__src), "+&d" (__n) : + : "cc", "memory", "0" ); + return tmp; +} +#endif + +#endif /* Use string inlines && GNU CC. */ diff --git a/sysdeps/s390/s390-64/bsd-_setjmp.S b/sysdeps/s390/s390-64/bsd-_setjmp.S new file mode 100644 index 0000000000..210b24d63b --- /dev/null +++ b/sysdeps/s390/s390-64/bsd-_setjmp.S @@ -0,0 +1,35 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation ; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 0)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +ENTRY(_setjmp) + slgr %r3,%r3 /* Second argument of zero. */ +#ifdef PIC + jg __sigsetjmp@PLT /* Branch to PLT of __sigsetjmp. */ +#else + jg __sigsetjmp /* Branch to __sigsetjmp. */ +#endif +END (_setjmp) + diff --git a/sysdeps/s390/s390-64/bsd-setjmp.S b/sysdeps/s390/s390-64/bsd-setjmp.S new file mode 100644 index 0000000000..4bded05851 --- /dev/null +++ b/sysdeps/s390/s390-64/bsd-setjmp.S @@ -0,0 +1,34 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation ; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +ENTRY(setjmp) + lghi %r1,1 /* Second argument of one. */ +#ifdef PIC + jg __sigsetjmp@PLT /* Branch to PLT of __sigsetjmp. */ +#else + jg __sigsetjmp /* Branch to __sigsetjmp. */ +#endif +END (setjmp) diff --git a/sysdeps/s390/s390-64/bzero.S b/sysdeps/s390/s390-64/bzero.S new file mode 100644 index 0000000000..7aad19ba60 --- /dev/null +++ b/sysdeps/s390/s390-64/bzero.S @@ -0,0 +1,42 @@ +/* bzero -- set a block of memory to zero. 64 bit S/390 version. + This file is part of the GNU C Library. + Copyright (C) 2001 Free Software Foundation, Inc. + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* INPUT PARAMETERS + %r2 = address of memory area + %r3 = number of bytes to fill. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(__bzero) + ltgr %r3,%r3 + jz .L1 + sgr %r1,%r1 # set pad byte to zero + sgr %r4,%r4 # no source for MVCLE, only a pad byte + sgr %r5,%r5 +.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend + jo .L0 +.L1: br %r14 +END(__bzero) + +#ifndef NO_WEAK_ALIAS +weak_alias (__bzero, bzero) +#endif diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h new file mode 100644 index 0000000000..fd1c752df9 --- /dev/null +++ b/sysdeps/s390/s390-64/dl-machine.h @@ -0,0 +1,434 @@ +/* Machine-dependent ELF dynamic relocation inline functions. + 64 bit S/390 Version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef dl_machine_h +#define dl_machine_h + +#define ELF_MACHINE_NAME "s390x" + +#include <sys/param.h> +#include <string.h> +#include <link.h> + +/* This is an older, now obsolete value. */ +#define EM_S390_OLD 0xA390 + +/* Return nonzero iff E_MACHINE is compatible with the running host. */ +static inline int +elf_machine_matches_host (const Elf64_Ehdr *ehdr) +{ + return (ehdr->e_machine == EM_S390 || ehdr->e_machine == EM_S390_OLD) + && ehdr->e_ident[EI_CLASS] == ELFCLASS64; +} + +/* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ + +static inline Elf64_Addr +elf_machine_dynamic (void) +{ + register Elf64_Addr *got; + + asm( " larl %0,_GLOBAL_OFFSET_TABLE_\n" + : "=&a" (got) : : "0" ); + + return *got; +} + +/* Return the run-time load address of the shared object. */ +static inline Elf64_Addr +elf_machine_load_address (void) +{ + Elf64_Addr addr; + + asm( " larl %0,_dl_start\n" + " larl 1,_GLOBAL_OFFSET_TABLE_\n" + " lghi 2,_dl_start@GOT\n" + " slg %0,0(2,1)" + : "=&d" (addr) : : "1", "2" ); + return addr; +} + +/* Set up the loaded object described by L so its unrelocated PLT + entries will jump to the on-demand fixup code in dl-runtime.c. */ + +static inline int __attribute__ ((unused)) +elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) +{ + extern void _dl_runtime_resolve (Elf64_Word); + extern void _dl_runtime_profile (Elf64_Word); + + if (l->l_info[DT_JMPREL] && lazy) + { + /* The GOT entries for functions in the PLT have not yet been filled + in. Their initial contents will arrange when called to push an + offset into the .rela.plt section, push _GLOBAL_OFFSET_TABLE_[1], + and then jump to _GLOBAL_OFFSET_TABLE[2]. */ + Elf64_Addr *got; + got = (Elf64_Addr *) D_PTR (l, l_info[DT_PLTGOT]); + got[1] = (Elf64_Addr) l; /* Identify this shared object. */ + + /* The got[2] entry contains the address of a function which gets + called to get the address of a so far unresolved function and + jump to it. The profiling extension of the dynamic linker allows + to intercept the calls to collect information. In this case we + don't store the address in the GOT so that all future calls also + end in this function. */ + if (__builtin_expect (profile, 0)) + { + got[2] = (Elf64_Addr) &_dl_runtime_profile; + + if (_dl_name_match_p (_dl_profile, l)) + /* This is the object we are looking for. Say that we really + want profiling and the timers are started. */ + _dl_profile_map = l; + } + else + /* This function will get called to fix up the GOT entry indicated by + the offset on the stack, and then jump to the resolved address. */ + got[2] = (Elf64_Addr) &_dl_runtime_resolve; + } + + return lazy; +} + +/* This code is used in dl-runtime.c to call the `fixup' function + and then redirect to the address it returns. */ + +/* s390: + Arguments are in register. + r2 - r7 holds the original parameters for the function call, fixup + and trampoline code use r0-r5 and r14-15. For the correct function + call r2-r5 and r14-15 must be restored. + Arguments from the PLT are stored at 48(r15) and 56(r15) + and must be moved to r2 and r3 for the fixup call (see elf32-s390.c + in the binutils for the PLT code). + Fixup function address in r2. +*/ +#ifndef PROF +#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ + asm ( "\ + .text\n\ + .globl _dl_runtime_resolve\n\ + .type _dl_runtime_resolve, @function\n\ + .align 16\n\ +_dl_runtime_resolve:\n\ + # save registers\n\ + stmg 2,5,64(15)\n\ + stg 14,96(15)\n\ + lgr 0,15\n\ + aghi 15,-160\n\ + stg 0,0(15)\n\ + # load args saved by PLT\n\ + lmg 2,3,208(15)\n\ + brasl 14,fixup # call fixup + lgr 1,2 # function addr returned in r2\n\ + # restore registers\n\ + aghi 15,160\n\ + lg 14,96(15)\n\ + lmg 2,5,64(15)\n\ + br 1\n\ + .size _dl_runtime_resolve, .-_dl_runtime_resolve\n\ +\n\ + .globl _dl_runtime_profile\n\ + .type _dl_runtime_profile, @function\n\ + .align 16\n\ +_dl_runtime_profile:\n\ + # save registers\n\ + stmg 2,5,64(15)\n\ + stg 14,96(15)\n\ + lgr 0,15\n\ + aghi 15,-160\n\ + stg 0,0(15)\n\ + # load args saved by PLT\n\ + lmg 2,3,208(15)\n\ + # load return address as third parameter\n\ + lgr 4,14\n\ + brasl 14,profile_fixup # call fixup\n\ + lgr 1,2 # function addr returned in r2\n\ + # restore registers\n\ + aghi 15,160\n\ + lg 14,96(15)\n\ + lmg 2,5,64(15)\n\ + br 1\n\ + .size _dl_runtime_profile, .-_dl_runtime_profile\n\ +"); +#else +#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ + asm ( "\ + .text\n\ + .globl _dl_runtime_resolve\n\ + .globl _dl_runtime_profile\n\ + .type _dl_runtime_resolve, @function\n\ + .type _dl_runtime_profile, @function\n\ + .align 16\n\ +_dl_runtime_resolve:\n\ +_dl_runtime_profile:\n\ + # save registers\n\ + stmg 2,5,64(15)\n\ + stg 14,96(15)\n\ + lgr 0,15\n\ + aghi 15,-160\n\ + stg 0,0(15)\n\ + # load args saved by PLT\n\ + lmg 2,3,208(15)\n\ + # load return address as third parameter\n\ + lgr 4,14\n\ + brasl 14,profile_fixup # call fixup\n\ + lgr 1,2 # function addr returned in r2\n\ + # restore registers\n\ + aghi 15,160\n\ + lg 14,96(15)\n\ + lmg 2,5,64(15)\n\ + br 1\n\ + .size _dl_runtime_resolve, .-_dl_runtime_resolve\n\ + .size _dl_runtime_profile, .-_dl_runtime_profile\n\ +"); +#endif + +/* Initial entry point code for the dynamic linker. + The C function `_dl_start' is the real entry point; + its return value is the user program's entry point. */ + +#define RTLD_START asm ("\n\ +.text\n\ +.align 4\n\ +.globl _start\n\ +.globl _dl_start_user\n\ +_start:\n\ + lgr %r2,%r15\n\ + # Alloc stack frame\n\ + aghi %r15,-160\n\ + # Set the back chain to zero\n\ + xc 0(8,%r15),0(%r15)\n\ + # Call _dl_start with %r2 pointing to arg on stack\n\ + brasl %r14,_dl_start # call _dl_start\n\ +_dl_start_user:\n\ + # Save the user entry point address in %r8.\n\ + lgr %r8,%r2\n\ + # Point %r12 at the GOT.\n\ + larl %r12,_GLOBAL_OFFSET_TABLE_\n\ + # Store the highest stack address\n\ + lghi %r1,__libc_stack_end@GOT + lg %r1,0(%r1,%r12)\n\ + stg %r15, 0(%r1)\n\ + # See if we were run as a command with the executable file\n\ + # name as an extra leading argument.\n\ + lghi %r1,_dl_skip_args@GOT + lg %r1,0(%r1,%r12)\n\ + lgf %r1,0(%r1) # load _dl_skip_args\n\ + # Get the original argument count.\n\ + lg %r0,160(%r15)\n\ + # Subtract _dl_skip_args from it.\n\ + sgr %r0,%r1\n\ + # Adjust the stack pointer to skip _dl_skip_args words.\n\ + sllg %r1,%r1,3\n\ + agr %r15,%r1\n\ + # Set the back chain to zero again\n\ + xc 0(8,%r15),0(%r15)\n\ + # Store back the modified argument count.\n\ + stg %r0,160(%r15)\n\ + # The special initializer gets called with the stack just\n\ + # as the application's entry point will see it; it can\n\ + # switch stacks if it moves these contents over.\n\ +" RTLD_START_SPECIAL_INIT "\n\ + # Call the function to run the initializers.\n\ + # Load the parameters:\n\ + # (%r2, %r3, %r4, %r5) = (_dl_loaded, argc, argv, envp)\n\ + lghi %r2,_dl_loaded@GOT + lg %r2,0(%r2,%r12)\n\ + lg %r2,0(%r2)\n\ + lg %r3,160(%r15)\n\ + la %r4,168(%r15)\n\ + lgr %r5,%r3\n\ + sllg %r5,%r5,3\n\ + la %r5,176(%r5,%r15)\n\ + brasl %r14,_dl_init@PLT\n + # Pass our finalizer function to the user in %r14, as per ELF ABI.\n\ + lghi %r14,_dl_fini@GOT + lg %r14,0(%r14,%r12)\n\ + # Free stack frame\n\ + aghi %r15,160\n\ + # Jump to the user's entry point (saved in %r8).\n\ + br %r8\n\ +"); + +#ifndef RTLD_START_SPECIAL_INIT +#define RTLD_START_SPECIAL_INIT /* nothing */ +#endif + +/* Nonzero iff TYPE should not be allowed to resolve to one of + the main executable's symbols, as for a COPY reloc. */ +#define elf_machine_lookup_noexec_p(type) ((type) == R_390_COPY) + +/* Nonzero iff TYPE describes relocation of a PLT entry, so + PLT entries should not be allowed to define the value. */ +#define elf_machine_lookup_noplt_p(type) ((type) == R_390_JMP_SLOT) + +/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ +#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT + +/* The 64 bit S/390 never uses Elf64_Rel relocations. */ +#define ELF_MACHINE_NO_REL 1 + +/* We define an initialization functions. This is called very early in + _dl_sysdep_start. */ +#define DL_PLATFORM_INIT dl_platform_init () + +extern const char *_dl_platform; + +static inline void __attribute__ ((unused)) +dl_platform_init (void) +{ + if (_dl_platform != NULL && *_dl_platform == '\0') + /* Avoid an empty string which would disturb us. */ + _dl_platform = NULL; +} + +static inline Elf64_Addr +elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const Elf64_Rela *reloc, + Elf64_Addr *reloc_addr, Elf64_Addr value) +{ + return *reloc_addr = value; +} + +/* Return the final value of a plt relocation. */ +static inline Elf64_Addr +elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, + Elf64_Addr value) +{ + return value; +} + +#endif /* !dl_machine_h */ + +#ifdef RESOLVE + +/* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +static inline void +elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, + const Elf64_Sym *sym, const struct r_found_version *version, + Elf64_Addr *const reloc_addr) +{ + if (ELF64_R_TYPE (reloc->r_info) == R_390_RELATIVE) { +#ifndef RTLD_BOOTSTRAP + weak_extern (_dl_rtld_map); + if (map != &_dl_rtld_map) /* Already done in rtld itself. */ +#endif + *reloc_addr = map->l_addr + reloc->r_addend; + } + else if (ELF64_R_TYPE (reloc->r_info) != R_390_NONE) + { + const Elf64_Sym *const refsym = sym; + Elf64_Addr value = RESOLVE (&sym, version, ELF64_R_TYPE (reloc->r_info)); + if (sym) + value += sym->st_value; + + switch (ELF64_R_TYPE (reloc->r_info)) + { + case R_390_GLOB_DAT: + case R_390_JMP_SLOT: + *reloc_addr = value + reloc->r_addend; + break; +#ifndef RTLD_BOOTSTRAP + case R_390_COPY: + if (sym == NULL) + /* This can happen in trace mode if an object could not be + found. */ + break; + if (__builtin_expect (sym->st_size > refsym->st_size, 0) + || (__builtin_expect (sym->st_size < refsym->st_size, 0) + && __builtin_expect (_dl_verbose, 0))) + { + const char *strtab; + + strtab = (const char *) D_PTR (map,l_info[DT_STRTAB]); + _dl_error_printf ("\ +%s: Symbol `%s' has different size in shared object, consider re-linking\n", + _dl_argv[0] ?: "<program name unknown>", + strtab + refsym->st_name); + } + memcpy (reloc_addr, (void *) value, MIN (sym->st_size, + refsym->st_size)); + break; + case R_390_64: + *reloc_addr = value + reloc->r_addend; + break; + case R_390_32: + *(unsigned int *) reloc_addr = value + reloc->r_addend; + break; + case R_390_16: + *(unsigned short *) reloc_addr = value + reloc->r_addend; + break; + case R_390_8: + *(char *) reloc_addr = value + reloc->r_addend; + break; + case R_390_PC64: + *reloc_addr = value +reloc->r_addend - (Elf64_Addr) reloc_addr; + break; + case R_390_PC32DBL: + case R_390_PLT32DBL: + *(unsigned int *) reloc_addr = (unsigned int) + ((int) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1); + break; + case R_390_PC32: + *(unsigned int *) reloc_addr = + value + reloc->r_addend - (Elf64_Addr) reloc_addr; + break; + case R_390_PC16DBL: + case R_390_PLT16DBL: + *(unsigned short *) reloc_addr = (unsigned short) + ((short) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1); + break; + case R_390_PC16: + *(unsigned short *) reloc_addr = + value + reloc->r_addend - (Elf64_Addr) reloc_addr; + break; +#endif +#if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG) + default: + /* We add these checks in the version to relocate ld.so only + if we are still debugging. */ + _dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0); + break; +#endif + } + } +} + +static inline void +elf_machine_lazy_rel (struct link_map *map, + Elf64_Addr l_addr, const Elf64_Rela *reloc) +{ + Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + /* Check for unexpected PLT reloc type. */ + if (__builtin_expect (ELF64_R_TYPE (reloc->r_info), R_390_JMP_SLOT) + == R_390_JMP_SLOT) + *reloc_addr += l_addr; + else + _dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1); +} + +#endif /* RESOLVE */ diff --git a/sysdeps/s390/s390-64/elf/bsd-_setjmp.S b/sysdeps/s390/s390-64/elf/bsd-_setjmp.S new file mode 100644 index 0000000000..1417270201 --- /dev/null +++ b/sysdeps/s390/s390-64/elf/bsd-_setjmp.S @@ -0,0 +1 @@ +/* We don't need any code here since the setjmp.S file contains it. */ diff --git a/sysdeps/s390/s390-64/elf/bsd-setjmp.S b/sysdeps/s390/s390-64/elf/bsd-setjmp.S new file mode 100644 index 0000000000..1417270201 --- /dev/null +++ b/sysdeps/s390/s390-64/elf/bsd-setjmp.S @@ -0,0 +1 @@ +/* We don't need any code here since the setjmp.S file contains it. */ diff --git a/sysdeps/s390/s390-64/elf/setjmp.S b/sysdeps/s390/s390-64/elf/setjmp.S new file mode 100644 index 0000000000..ab1931507a --- /dev/null +++ b/sysdeps/s390/s390-64/elf/setjmp.S @@ -0,0 +1,53 @@ +/* setjmp for 64 bit S/390, ELF version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <sysdep.h> +#define _ASM +#define _SETJMP_H +#include <bits/setjmp.h> + + /* We include the BSD entry points here as well but we make + them weak. */ +ENTRY (setjmp) + .weak C_SYMBOL_NAME (setjmp) + lghi %r3,1 /* Second argument of one. */ + j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */ +END (setjmp) + + /* Binary compatibility entry point. */ +ENTRY(_setjmp) + .weak C_SYMBOL_NAME (_setjmp) +ENTRY(__setjmp) + slgr %r3,%r3 /* Second argument of zero. */ + +ENTRY(__sigsetjmp) +.Linternal_sigsetjmp: + stmg %r6,%r15,0(%r2) /* Store registers in jmp_buf. */ + std %f1,80(%r2) + std %f3,88(%r2) + std %f5,96(%r2) + std %f7,104(%r2) +#ifdef PIC + jg __sigjmp_save@PLT /* Branch to PLT of __sigsetjmp. */ +#else + jg __sigjmp_save +#endif +END (__sigsetjmp) + diff --git a/sysdeps/s390/s390-64/elf/start.S b/sysdeps/s390/s390-64/elf/start.S new file mode 100644 index 0000000000..d85c0805a9 --- /dev/null +++ b/sysdeps/s390/s390-64/elf/start.S @@ -0,0 +1,84 @@ +/* Startup code compliant to the 64 bit S/390 ELF ABI. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* + This is the canonical entry point, usually the first thing in the text + segment. Most registers' values are unspecified, except for: + + %r14 Contains a function pointer to be registered with `atexit'. + This is how the dynamic linker arranges to have DT_FINI + functions called for shared libraries that have been loaded + before this code runs. + + %r15 The stack contains the arguments and environment: + 0(%r15) argc + 8(%r15) argv[0] + ... + (8*argc)(%r15) NULL + (8*(argc+1))(%r15) envp[0] + ... + NULL +*/ + + .text + .globl _start +_start: + /* Load argc and argv from stack. */ + la %r4,8(%r15) # get argv + lg %r3,0(%r15) # get argc + + /* Align the stack to a double word boundary. */ + lghi %r0,-16 + ngr %r15,%r0 + + /* Setup a stack frame and a parameter area. */ + aghi %r15,-176 # make room on stack + xc 0(8,%r15),0(%r15) # clear back-chain + + /* Set up arguments for __libc_start_main: + main, argc, argv, envp, _init, _fini, rtld_fini, stack_end + Note that envp will be determined later in __libc_start_main. + */ + stmg %r14,%r15,160(%r15) # store rtld_fini/stack_end to parameter area + la %r7,160(%r15) + larl %r6,_fini # load pointer to _fini + larl %r5,_init # load pointer to _init + larl %r2,main # load pointer to main + + /* Ok, now branch to the libc main routine. */ + brasl %r14,__libc_start_main + + /* Crash if __libc_start_main returns. */ + .word 0 + + /* FIXME: FPU flags or what ?!? */ + + .section .rodata + .globl _fp_hw + .long 3 + .size _fp_hw, 4 + + /* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start diff --git a/sysdeps/s390/s390-64/ffs.c b/sysdeps/s390/s390-64/ffs.c new file mode 100644 index 0000000000..64e0d8911e --- /dev/null +++ b/sysdeps/s390/s390-64/ffs.c @@ -0,0 +1,68 @@ +/* ffs -- find first set bit in a word, counted from least significant end. + 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#define ffsl __something_else +#include <string.h> + +#undef ffs + +/* ffs: find first bit set. This is defined the same way as + the libc and compiler builtin ffs routines, therefore + differs in spirit from the above ffz (man ffs). */ + +int +__ffs (x) + int x; +{ + int r; + + if (x == 0) + return 0; + __asm__(" lr %%r1,%1\n" + " sr %0,%0\n" + " tml %%r1,0xFFFF\n" + " jnz 0f\n" + " ahi %0,16\n" + " srl %%r1,16\n" + "0: tml %%r1,0x00FF\n" + " jnz 1f\n" + " ahi %0,8\n" + " srl %%r1,8\n" + "1: tml %%r1,0x000F\n" + " jnz 2f\n" + " ahi %0,4\n" + " srl %%r1,4\n" + "2: tml %%r1,0x0003\n" + " jnz 3f\n" + " ahi %0,2\n" + " srl %%r1,2\n" + "3: tml %%r1,0x0001\n" + " jnz 4f\n" + " ahi %0,1\n" + "4:" + : "=&d" (r) : "d" (x) : "cc", "1" ); + return r+1; +} + +weak_alias (__ffs, ffs) +#undef ffsl +weak_alias (__ffs, ffsl) + diff --git a/sysdeps/s390/s390-64/initfini.c b/sysdeps/s390/s390-64/initfini.c new file mode 100644 index 0000000000..3d14b0b283 --- /dev/null +++ b/sysdeps/s390/s390-64/initfini.c @@ -0,0 +1,136 @@ +/* Special .init and .fini section support for 64 bit S/390. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Library General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The Library General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This file is compiled into assembly code which is then munged by a sed + script into two files: crti.s and crtn.s. + + * crti.s puts a function prologue at the beginning of the + .init and .fini sections and defines global symbols for + those addresses, so they can be called as functions. + + * crtn.s puts the corresponding function epilogues + in the .init and .fini sections. */ + +__asm__ (" + +#include \"defs.h\" + +/*@HEADER_ENDS*/ + +/*@TESTS_BEGIN*/ + +/*@TESTS_END*/ + +/*@_init_PROLOG_BEGINS*/ + + .section .init +#NO_APP + .align 4 +.globl _init + .type _init,@function +_init: +# leaf function 0 +# automatics 0 +# outgoing args 0 +# need frame pointer 0 +# call alloca 0 +# has varargs 0 +# incoming args (stack) 0 +# function length 36 + STMG 6,15,48(15) + LGR 1,15 + AGHI 15,-160 + STG 1,0(15) + LARL 12,_GLOBAL_OFFSET_TABLE_ + LGHI 1,__gmon_start__@GOT + LG 1,0(1,12) + LTGR 1,1 + JE .L22 + BASR 14,1 +.L22: +#APP + .align 4,0x07 + END_INIT + +/*@_init_PROLOG_ENDS*/ + +/*@_init_EPILOG_BEGINS*/ + .align 4 + .section .init +#NO_APP + .align 4 + LG 4,272(15) + LMG 6,15,208(15) + BR 4 +#APP + END_INIT + +/*@_init_EPILOG_ENDS*/ + +/*@_fini_PROLOG_BEGINS*/ + .section .fini +#NO_APP + .align 4 +.globl _fini + .type _fini,@function +_fini: +# leaf function 0 +# automatics 0 +# outgoing args 0 +# need frame pointer 0 +# call alloca 0 +# has varargs 0 +# incoming args (stack) 0 +# function length 30 + STMG 6,15,48(15) + LGR 1,15 + AGHI 15,-160 + STG 1,0(15) + LARL 12,_GLOBAL_OFFSET_TABLE_ +#APP + .align 4,0x07 + END_FINI + +/*@_fini_PROLOG_ENDS*/ + +/*@_fini_EPILOG_BEGINS*/ + .align 4 + .section .fini +#NO_APP + .align 4 + LG 4,272(15) + LMG 6,15,208(15) + BR 4 +#APP + END_FINI + +/*@_fini_EPILOG_ENDS*/ + +/*@TRAILER_BEGINS*/ +"); diff --git a/sysdeps/s390/s390-64/memchr.S b/sysdeps/s390/s390-64/memchr.S new file mode 100644 index 0000000000..ecf5a5db46 --- /dev/null +++ b/sysdeps/s390/s390-64/memchr.S @@ -0,0 +1,40 @@ +/* Search a character in a block of memory. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* INPUT PARAMETERS + %r2 = address to memory area + %r3 = character to find + %r4 = number of bytes to search. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(memchr) + lghi %r0,0xff + ngr %r0,%r3 + lgr %r1,%r2 + la %r2,0(%r4,%r1) +0: srst %r2,%r1 + jo 0b + brc 13,1f + slgr %r2,%r2 +1: br %r14 +END(memchr) diff --git a/sysdeps/s390/s390-64/memcpy.S b/sysdeps/s390/s390-64/memcpy.S new file mode 100644 index 0000000000..c59d3fbb79 --- /dev/null +++ b/sysdeps/s390/s390-64/memcpy.S @@ -0,0 +1,41 @@ +/* Set a block of memory to some byte value. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* INPUT PARAMETERS + %r2 = address to destination memory area + %r3 = address to source memory area + %r4 = number of bytes to copy. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(memcpy) + ltgr %r5,%r4 + jz .L1 + lgr %r4,%r3 # %r4/%r5 = source ptr/len + lgr %r3,%r5 # %r2/%r3 = dest ptr/len + lgr %r0,%r2 # save source address +.L0: mvcle %r2,%r4,0 # thats it, MVCLE is your friend + jo .L0 + lgr %r2,%r0 # return value is source address +.L1: + br %r14 +END(memset) diff --git a/sysdeps/s390/s390-64/memset.S b/sysdeps/s390/s390-64/memset.S new file mode 100644 index 0000000000..b71c036f72 --- /dev/null +++ b/sysdeps/s390/s390-64/memset.S @@ -0,0 +1,43 @@ +/* Set a block of memory to some byte value. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* INPUT PARAMETERS + %r2 = address of memory area + %r3 = byte to fill memory with + %r4 = number of bytes to fill. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(memset) + ltgr %r4,%r4 + jz .L1 + lgr %r0,%r2 # save source address + lgr %r1,%r3 # move pad byte to R1 + lgr %r3,%r4 + sgr %r4,%r4 # no source for MVCLE, only a pad byte + sgr %r5,%r5 +.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend + jo .L0 + lgr %r2,%r0 # return value is source address +.L1: + br %r14 +END(memset) diff --git a/sysdeps/s390/s390-64/s390x-mcount.S b/sysdeps/s390/s390-64/s390x-mcount.S new file mode 100644 index 0000000000..831af9c552 --- /dev/null +++ b/sysdeps/s390/s390-64/s390x-mcount.S @@ -0,0 +1,72 @@ +/* 64 bit S/390-specific implemetation of profiling support. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com) + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <sysdep.h> + +/* How profiling works on 64 bit S/390: + On the start of each function _mcount is called with the address of a + data word in %r1 (initialized to 0, used for counting). The compiler + with the option -p generates code of the form: + + STM 6,15,24(15) + BRAS 13,.LTN0_0 + .LT0_0: + .LC13: .long .LP0 + .data + .align 4 + .LP0: .long 0 + .text + # function profiler + stg 14,4(15) + lg 1,.LC13-.LT0_0(13) + brasl 14,_mcount + lg 14,4(15) + + The _mcount implementation now has to call __mcount_internal with the + address of .LP0 as first parameter and the return address as second + parameter. &.LP0 was loaded to %r1 and the return address is in %r14. + _mcount may not modify any register. */ + + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(_mcount) + ASM_TYPE_DIRECTIVE(C_SYMBOL_NAME(_mcount), @function) + .align ALIGNARG(4) +C_LABEL(_mcount) + /* Save the caller-clobbered registers. */ + aghi %r15,-224 + stmg %r14,%r5,160(%r15) + lg %r2,232(%r15) # callers address = first parameter + la %r2,0(%r2) # clear bit 0 + la %r3,0(%r14) # callees address = second parameter + +#ifdef PIC + brasl %r14,__mcount_internal@PLT +#else + brasl %r14,__mcount_internal +#endif + + /* Pop the saved registers. Please note that `mcount' has no + return value. */ + lmg %r14,%r5,160(%r15) + ahi %r15,224 + br %r14 + ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount)) + +#undef mcount +weak_alias(_mcount, mcount) diff --git a/sysdeps/s390/s390-64/setjmp.S b/sysdeps/s390/s390-64/setjmp.S new file mode 100644 index 0000000000..32f2bd44be --- /dev/null +++ b/sysdeps/s390/s390-64/setjmp.S @@ -0,0 +1,43 @@ +/* Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _ASM +#define _ASM +#endif + +#include <sysdep.h> +#include <bits/setjmp.h> + +/* Save the current program position in ENV and return 0. */ +/* R2 = pointer to jmp_buf, R3 = savemask. */ + +ENTRY(__sigsetjmp) + stmg %r6,%r15,0(%r2) /* Store registers in jmp_buf. */ + std %f1,80(%r2) + std %f3,88(%r2) + std %f5,96(%r2) + std %f7,104(%r2) +#ifdef PIC + jg __sigjmp_save@PLT /* Tail-call __sigjmp_save. */ +#else + jg __sigjmp_save /* Tail-call __sigjmp_save. */ +#endif +END (__sigsetjmp) + + diff --git a/sysdeps/s390/s390-64/strcpy.S b/sysdeps/s390/s390-64/strcpy.S new file mode 100644 index 0000000000..65a555e10b --- /dev/null +++ b/sysdeps/s390/s390-64/strcpy.S @@ -0,0 +1,35 @@ +/* strcpy - copy a string from source to destination. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation ; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* INPUT PARAMETERS + %r2 = address of destination + %r3 = address of source. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(strcpy) + slgr %r0,%r0 + lgr %r1,%r2 +0: mvst %r1,%r3 + jo 0b + br %r14 +END(strcpy) diff --git a/sysdeps/s390/s390-64/strncpy.S b/sysdeps/s390/s390-64/strncpy.S new file mode 100644 index 0000000000..5ea2cd58b8 --- /dev/null +++ b/sysdeps/s390/s390-64/strncpy.S @@ -0,0 +1,90 @@ +/* strncpy - copy at most n characters from a string from source to + destination. 64 bit S/390 version + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* INPUT PARAMETERS + %r2 = address of destination (dst) + %r3 = address of source (src) + %r4 = max of bytes to copy. */ + +#include "sysdep.h" +#include "asm-syntax.h" + +ENTRY(strncpy) + .text + stg %r2,48(%r15) # save dst pointer + slgr %r2,%r3 # %r3 points to src, %r2+%r3 to dst + lghi %r1,7 + ngr %r1,%r4 # last 3 bits of # bytes + srlg %r4,%r4,3 + ltgr %r4,%r4 # less than 8 bytes to copy ? + jz .L1 + bras %r5,.L0 # enter loop & load address of a 0 + .long 0 +.L0: icmh %r0,8,0(%r3) # first byte + jz .L3 + icmh %r0,4,1(%r3) # second byte + jz .L4 + icmh %r0,2,2(%r3) # third byte + jz .L5 + icmh %r0,1,3(%r3) # fourth byte + jz .L6 + icm %r0,8,4(%r3) # fifth byte + jz .L7 + icm %r0,4,5(%r3) # sixth byte + jz .L8 + icm %r0,2,6(%r3) # seventh byte + jz .L9 + icm %r0,1,7(%r3) # eigth byte + jz .L10 + stg %r0,0(%r2,%r3) # store all eight to dest. + la %r3,8(%r3) + brct %r4,.L0 +.L1: ltgr %r1,%r1 + jz .Lexit +.L2: icm %r0,1,0(%r3) + stc %r0,0(%r2,%r3) + la %r3,1(%r3) + jz .L11 + brct %r1,.L2 + j .Lexit +.L3: icmh %r0,4,0(%r5) +.L4: icmh %r0,2,0(%r5) +.L5: icmh %r0,1,0(%r5) +.L6: icm %r0,8,0(%r5) +.L7: icm %r0,4,0(%r5) +.L8: icm %r0,2,0(%r5) +.L9: icm %r0,1,0(%r5) +.L10: stg %r0,0(%r2,%r3) + la %r3,8(%r3) + aghi %r4,-1 + j .L12 +.L11: aghi %r1,-1 +.L12: sllg %r4,%r4,3 + algr %r4,%r1 + algr %r2,%r3 # start of dst area to be zeroed + lgr %r3,%r4 + slgr %r4,%r4 + slgr %r5,%r5 +.L13: mvcle %r2,%r4,0 # pad dst with zeroes + jo .L13 +.Lexit: lg %r2,48(%r15) # return dst pointer + br %r14 +END(strncpy) diff --git a/sysdeps/s390/s390-64/sub_n.S b/sysdeps/s390/s390-64/sub_n.S new file mode 100644 index 0000000000..183ebb7fed --- /dev/null +++ b/sysdeps/s390/s390-64/sub_n.S @@ -0,0 +1,60 @@ +/* __mpn_sub_n -- Add two limb vectors of the same length > 0 and store + sum in a third limb vector. 64 bit S/390 version. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU MP Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* INPUT PARAMETERS + %r2 = res_ptr + %r3 = s1_ptr + %r4 = s2_ptr + %r5 = size. */ + +#include "sysdep.h" +#include "asm-syntax.h" + +ENTRY(__mpn_sub_n) + stg %r6,48(%r15) # save register 6 + sgr %r1,%r1 + lghi %r0,1 # cannot use ahi to add carry, use slr +.L0: lg %r6,0(%r1,%r3) # .L0 -> no carry from last sub + slg %r6,0(%r1,%r4) + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brc 4,.L3 +.L1: brct %r5,.L0 + slgr %r2,%r2 # no last carry to return + j .Lexit +.L2: lg %r6,0(%r1,%r3) # .L2 -> carry from last sub + slg %r6,0(%r1,%r4) + brc 4,.L4 + slgr %r6,%r0 # no carry yet, add carry from last sub + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brc 11,.L1 # new carry ? +.L3: brct %r5,.L2 + lgr %r2,%r0 # return last carry + j .Lexit +.L4: slgr %r6,%r0 # already a carry, add carry from last sub + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brct %r5,.L2 + lgr %r2,%r0 # return last carry +.Lexit: lg %r6,48(%r15) # restore register 6 + br %r14 +END(__mpn_sub_n) diff --git a/sysdeps/s390/s390-64/sysdep.h b/sysdeps/s390/s390-64/sysdep.h new file mode 100644 index 0000000000..12f8c3a087 --- /dev/null +++ b/sysdeps/s390/s390-64/sysdep.h @@ -0,0 +1,112 @@ +/* Assembler macros for 64 bit S/390. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <sysdeps/generic/sysdep.h> + +#ifdef __ASSEMBLER__ + +/* Syntactic details of assembler. */ + +#ifdef HAVE_ELF + +/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ +#define ALIGNARG(log2) 1<<log2 +/* For ELF we need the `.type' directive to make shared libs work right. */ +#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg; +#define ASM_SIZE_DIRECTIVE(name) .size name,.-name; + +/* In ELF C symbols are asm symbols. */ +#undef NO_UNDERSCORES +#define NO_UNDERSCORES + +#else + +#define ALIGNARG(log2) log2 +#define ASM_TYPE_DIRECTIVE(name,type) /* Nothing is specified. */ +#define ASM_SIZE_DIRECTIVE(name) /* Nothing is specified. */ + +#endif + + +/* Define an entry point visible from C. */ +#define ENTRY(name) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ + .align ALIGNARG(2); \ + C_LABEL(name) \ + CALL_MCOUNT + +#undef END +#define END(name) \ + ASM_SIZE_DIRECTIVE(name) \ + +/* If compiled for profiling, call `mcount' at the start of each function. */ +#ifdef PROF +#ifdef PIC +#define CALL_MCOUNT \ + lgr 0,14 ; larl 1,0f ; brasl 14,_mcount@PLT ; lgr 14,0 ; \ + .data ; .align 4 ; 0: .long 0 ; .text ; +#else +#define CALL_MCOUNT \ + lgr 0,14 ; larl 1,0f ; brasl 14,_mcount ; lgr 14,0 ; \ + .data ; .align 4 ; 0: .long 0 ; .text ; +#endif +#else +#define CALL_MCOUNT /* Do nothing. */ +#endif + +#ifdef NO_UNDERSCORES +/* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +#define syscall_error __syscall_error +#define mcount _mcount +#endif + +#define PSEUDO(name, syscall_name, args) \ +lose: SYSCALL_PIC_SETUP \ + JUMPTARGET(syscall_error) \ + .globl syscall_error; \ + ENTRY (name) \ + DO_CALL (syscall_name, args); \ + jm lose + +#undef PSEUDO_END +#define PSEUDO_END(name) \ + END (name) + +#ifdef PIC +#define JUMPTARGET(name) \ + brasl name##@PLT +#define SYSCALL_PIC_SETUP \ + larl %r12,_GLOBAL_OFFSET_TABLE_ +#else +#define JUMPTARGET(name) \ + brasl name +#define SYSCALL_PIC_SETUP /* Nothing. */ +#endif + +/* Local label name for asm code. */ +#ifndef L +#define L(name) name +#endif + +#endif /* __ASSEMBLER__ */ + |