diff options
Diffstat (limited to 'sysdeps/s390/s390-32')
34 files changed, 2355 insertions, 0 deletions
diff --git a/sysdeps/s390/s390-32/Dist b/sysdeps/s390/s390-32/Dist new file mode 100644 index 0000000000..fdba667f31 --- /dev/null +++ b/sysdeps/s390/s390-32/Dist @@ -0,0 +1,3 @@ +s390-mcount.S +machine-gmon.h +fpu/fenv_libc.h diff --git a/sysdeps/s390/s390-32/Implies b/sysdeps/s390/s390-32/Implies new file mode 100644 index 0000000000..71bec4de0c --- /dev/null +++ b/sysdeps/s390/s390-32/Implies @@ -0,0 +1,4 @@ +wordsize-32 +ieee754 +ieee754/dbl-64 +ieee754/flt-32 diff --git a/sysdeps/s390/s390-32/Makefile b/sysdeps/s390/s390-32/Makefile new file mode 100644 index 0000000000..057862d91b --- /dev/null +++ b/sysdeps/s390/s390-32/Makefile @@ -0,0 +1,11 @@ +pic-ccflag = -fpic + +ifeq ($(subdir),gmon) +sysdep_routines += s390-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-32/Versions b/sysdeps/s390/s390-32/Versions new file mode 100644 index 0000000000..2b020f8f58 --- /dev/null +++ b/sysdeps/s390/s390-32/Versions @@ -0,0 +1,6 @@ +libc { + GLIBC_2.0 { + # Functions from libgcc. + __divdi3; __moddi3; __udivdi3; __umoddi3; + } +} diff --git a/sysdeps/s390/s390-32/__longjmp.c b/sysdeps/s390/s390-32/__longjmp.c new file mode 100644 index 0000000000..3020abd810 --- /dev/null +++ b/sysdeps/s390/s390-32/__longjmp.c @@ -0,0 +1,43 @@ +/* Copyright (C) 2000, 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 ("lr %%r2,%0\n\t" /* PUT val in grp 2. */ + "ld %%f6,48(%1)\n\t" + "ld %%f4,40(%1)\n\t" + "lm %%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-32/add_n.S b/sysdeps/s390/s390-32/add_n.S new file mode 100644 index 0000000000..76160733a1 --- /dev/null +++ b/sysdeps/s390/s390-32/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) 2000, 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) + st %r6,24(%r15) # save register 6 + sr %r1,%r1 + lhi %r0,1 # cannot use ahi to add carry, use alr +.L0: l %r6,0(%r1,%r3) # .L0 -> no carry from last add + al %r6,0(%r1,%r4) + st %r6,0(%r1,%r2) + la %r1,4(0,%r1) + brc 3,.L3 +.L1: brct %r5,.L0 + slr %r2,%r2 # no last carry to return + j .Lexit +.L2: l %r6,0(%r1,%r3) # .L2 -> carry from last add + al %r6,0(%r1,%r4) + brc 3,.L4 + alr %r6,%r0 # no carry yet, add carry from last add + st %r6,0(%r1,%r2) + la %r1,4(0,%r1) + brc 12,.L1 # new carry ? +.L3: brct %r5,.L2 + lr %r2,%r0 # return last carry + j .Lexit +.L4: alr %r6,%r0 # already a carry, add carry from last add + st %r6,0(%r1,%r2) + la %r1,4(0,%r1) + brct %r5,.L2 + lr %r2,%r0 # return last carry +.Lexit: l %r6,24(%r15) # restore register 6 + br %r14 +END(__mpn_add_n) diff --git a/sysdeps/s390/s390-32/addmul_1.S b/sysdeps/s390/s390-32/addmul_1.S new file mode 100644 index 0000000000..5a7ccf8640 --- /dev/null +++ b/sysdeps/s390/s390-32/addmul_1.S @@ -0,0 +1,58 @@ +/* S390 __mpn_addmul_1 -- Multiply a limb vector with a limb and add + the result to a second limb vector. + Copyright (C) 2000, 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 + sizeP %r4 + s2_limb %r5 +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(__mpn_addmul_1) + st %r6,24(%r15) + slr %r6,%r6 # cy_limb = 0 +.L0: icm %r1,15,0(%r3) # get s1_ptr[i] + mr %r0,%r5 # umul_ppmm(prod_high,prod_low,s1_ptr[j],s2_limb) + jnm .L1 + alr %r0,%r5 +.L1: ltr %r5,%r5 + jnm .L2 + al %r0,0(%r3) +.L2: alr %r1,%r6 # prod_low += cy_limb + lr %r6,%r0 # cy_limb = prod_high + brc 12,.L3 + ahi %r6,1 # + (prod_low < cy_limb) +.L3: al %r1,0(%r2) # prod_low += res_ptr[i] + brc 12,.L4 + ahi %r6,1 # cy_limb++ +.L4: st %r1,0(%r2) + la %r2,4(0,%r2) + la %r3,4(0,%r3) + brct %r4,.L0 + lr %r2,%r6 # return cy_limb + l %r6,24(%r15) +.Lexit: br %r14 +END(__mpn_addmul_1) diff --git a/sysdeps/s390/s390-32/atomicity.h b/sysdeps/s390/s390-32/atomicity.h new file mode 100644 index 0000000000..f56388afc0 --- /dev/null +++ b/sysdeps/s390/s390-32/atomicity.h @@ -0,0 +1,76 @@ +/* Low-level functions for atomic operations. S390 version. + Copyright (C) 2000, 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" + " lr 0,%2\n" + " cs 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-32/backtrace.c b/sysdeps/s390/s390-32/backtrace.c new file mode 100644 index 0000000000..8e3ca7ecca --- /dev/null +++ b/sysdeps/s390/s390-32/backtrace.c @@ -0,0 +1,81 @@ +/* Return backtrace of current program state. + Copyright (C) 2000, 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 -> +------------------+ + 4 | back chain | 0 + 4 | end of stack | 4 + 8 | glue | 8 + 8 | scratch | 16 + 40 | save area r6-r15 | 24 + 16 | save area f4,f6 | 64 + 16 | empty | 80 + +------------------+ + r14 in the save area holds the return address. +*/ + +struct layout +{ + int back_chain; + int end_of_stack; + int glue[2]; + int scratch[2]; + int save_grps[10]; + int save_fp[4]; + int 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 ("LR %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-32/bcopy.S b/sysdeps/s390/s390-32/bcopy.S new file mode 100644 index 0000000000..8bf5bbbefa --- /dev/null +++ b/sysdeps/s390/s390-32/bcopy.S @@ -0,0 +1,69 @@ +/* bcopy -- copy a block from source to destination. For IBM S390 + This file is part of the GNU C Library. + Copyright (C) 2000, 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. */ + +/* + * R2 = address of source + * R3 = address of destination + * R4 = number of bytes to copy + */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(__bcopy) + clr %r2,%r3 # check against destructive overlap + jnl .L0 + lr %r1,%r2 + alr %r1,%r4 + clr %r1,%r3 + jh .L2 +.L0: + lr %r5,%r4 # source length + lr %r4,%r2 # source address + sr %r1,%r1 # set pad byte to zero + lr %r2,%r3 # set destination + lr %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 + lr %r1,%r2 # bcopy is called with source,dest + lr %r2,%r3 # memmove with dest,source! Oh, well... + lr %r3,%r1 + basr %r1,0 +.L3: +#ifdef PIC + al %r1,.L4-.L3(%r1) # get address of global offset table + # load address of memmove + l %r1,memmove@GOT12(%r1) + br %r1 +.L4: .long _GLOBAL_OFFSET_TABLE_-.L3 +#else + al %r1,.L4-.L3(%r1) # load address of memmove + br %r1 # jump to memmove +.L4: .long memmove-.L3 +#endif + +END(__bcopy) + +#ifndef NO_WEAK_ALIAS +weak_alias (__bcopy, bcopy) +#endif diff --git a/sysdeps/s390/s390-32/bits/byteswap.h b/sysdeps/s390/s390-32/bits/byteswap.h new file mode 100644 index 0000000000..cc6cf41428 --- /dev/null +++ b/sysdeps/s390/s390-32/bits/byteswap.h @@ -0,0 +1,86 @@ +/* Macros to swap the order of bytes in integer values. s390 version. + Copyright (C) 2000, 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__ ( \ + "sr %0,%0\n" \ + "la 1,%1\n" \ + "icm %0,2,1(1)\n" \ + "ic %0,0(1)" \ + : "=&d" (__v) : "m" (__tmp) : "1"); \ + } \ + __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__ ( \ + "la 1,%1\n" \ + "icm %0,8,3(1)\n" \ + "icm %0,4,2(1)\n" \ + "icm %0,2,1(1)\n" \ + "ic %0,0(1)" \ + : "=&d" (__v) : "m" (__tmp) : "1"); \ + } \ + __v; })) +#else +# define __bswap_32(x) __bswap_constant_32 (x) +#endif + +#if defined __GNUC__ && __GNUC__ >= 2 +/* Swap bytes in 64 bit value. */ +# define __bswap_64(x) \ + __extension__ \ + ({ union { unsigned long long int __ll; \ + unsigned long int __l[2]; } __w, __r; \ + __w.__ll = (x); \ + __r.__l[0] = __bswap_32 (__w.__l[1]); \ + __r.__l[1] = __bswap_32 (__w.__l[0]); \ + __r.__ll; }) +#endif diff --git a/sysdeps/s390/s390-32/bits/huge_val.h b/sysdeps/s390/s390-32/bits/huge_val.h new file mode 100644 index 0000000000..65e0fe2487 --- /dev/null +++ b/sysdeps/s390/s390-32/bits/huge_val.h @@ -0,0 +1,73 @@ +/* `HUGE_VAL' constants for s390 (where it is infinity). + Used by <stdlib.h> and <math.h> functions for overflow. + Copyright (C) 2000, 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-32/bits/setjmp.h b/sysdeps/s390/s390-32/bits/setjmp.h new file mode 100644 index 0000000000..d3afbe5f07 --- /dev/null +++ b/sysdeps/s390/s390-32/bits/setjmp.h @@ -0,0 +1,52 @@ +/* Copyright (C) 2000, 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'. IBM s390 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[4]; +} __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-32/bits/string.h b/sysdeps/s390/s390-32/bits/string.h new file mode 100644 index 0000000000..7474244a1d --- /dev/null +++ b/sysdeps/s390/s390-32/bits/string.h @@ -0,0 +1,154 @@ +/* Optimized, inlined string functions. s390 version. + Copyright (C) 2000, 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__ (" sr 0,0\n" + " lr %0,%1\n" + "0: srst 0,%0\n" + " jo 0b\n" + " lr %0,0\n" + " sr %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__ (" sr 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 (" slr %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__ (" sr 0,0\n" + "0: srst 0,%0\n" + " jo 0b\n" + " lr %0,0\n" + " sr 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__ (" sr 0,0\n" + "0: srst 0,%0\n" + " jo 0b\n" + " lr %0,0\n" + " slr %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-32/bsd-_setjmp.S b/sysdeps/s390/s390-32/bsd-_setjmp.S new file mode 100644 index 0000000000..db07a3d103 --- /dev/null +++ b/sysdeps/s390/s390-32/bsd-_setjmp.S @@ -0,0 +1,46 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. s390 version. + Copyright (C) 2000, 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) +#ifdef PIC + /* We cannot use the PLT, because it requires that %r12 be set, but + we can't save and restore our caller's value. Instead, we do an + indirect jump through the GOT. */ + basr %r1,0 +.L0: al %r1,.L1 - .L0(0,%r1) /* get address of global offset table */ + /* get address of __sigjmp_save from got */ + l %r1,__sigjmp_save@GOT12(0,%r1) + lhi %r3,0 /* second argument of one */ + br %r1 +.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0 +#else + basr %r1,0 +.L0: l %r1,.L1 - .L0(0,%r1) /* load address of __sigsetjmp */ + lhi %r3,0 /* second argument of zero */ + br %r1 /* branch to __sigsetjmp */ +.L1: .long __sigsetjmp +#endif +END (_setjmp) diff --git a/sysdeps/s390/s390-32/bsd-setjmp.S b/sysdeps/s390/s390-32/bsd-setjmp.S new file mode 100644 index 0000000000..e2463196f0 --- /dev/null +++ b/sysdeps/s390/s390-32/bsd-setjmp.S @@ -0,0 +1,46 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. s390 version. + Copyright (C) 2000, 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) +#ifdef PIC + /* We cannot use the PLT, because it requires that %r12 be set, but + we can't save and restore our caller's value. Instead, we do an + indirect jump through the GOT. */ + basr %r1,0 +.L0: al %r1,.L1 - .L0(0,%r1) /* get address of global offset table */ + /* get address of __sigjmp_save from got */ + l %r1,__sigjmp_save@GOT12(0,%r1) + lhi %r3,1 /* second argument of one */ + br %r1 +.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0 +#else + basr %r1,0 +.L0: l %r1,.L1 - .L0(0,%r1) /* load address of __sigsetjmp */ + lhi %r3,1 /* second argument of zero */ + br %r1 /* branch to __sigsetjmp */ +.L1: .long __sigsetjmp +#endif +END (setjmp) diff --git a/sysdeps/s390/s390-32/bzero.S b/sysdeps/s390/s390-32/bzero.S new file mode 100644 index 0000000000..b6d9811b9d --- /dev/null +++ b/sysdeps/s390/s390-32/bzero.S @@ -0,0 +1,43 @@ +/* bzero -- set a block of memory to zero. IBM S390 version + This file is part of the GNU C Library. + Copyright (C) 2000, 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. */ + +/* + * R2 = address to memory area + * R3 = number of bytes to fill + */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(__bzero) + ltr %r3,%r3 + jz .L1 + sr %r1,%r1 # set pad byte to zero + sr %r4,%r4 # no source for MVCLE, only a pad byte + sr %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-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h new file mode 100644 index 0000000000..93613b023b --- /dev/null +++ b/sysdeps/s390/s390-32/dl-machine.h @@ -0,0 +1,454 @@ +/* Machine-dependent ELF dynamic relocation inline functions. S390 Version. + Copyright (C) 2000, 2001 Free Software Foundation, Inc. + Contributed by Carl Pederson & Martin Schwidefsky. + 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 "s390" + +#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 ELF header is compatible with the running host. */ +static inline int +elf_machine_matches_host (const Elf32_Ehdr *ehdr) +{ + return (ehdr->e_machine == EM_S390 || ehdr->e_machine == EM_S390_OLD) + && ehdr->e_ident[EI_CLASS] == ELFCLASS32; +} + + +/* 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 Elf32_Addr +elf_machine_dynamic (void) +{ + register Elf32_Addr *got; + + asm( " bras %0,2f\n" + "1: .long _GLOBAL_OFFSET_TABLE_-1b\n" + "2: al %0,0(%0)" + : "=&a" (got) : : "0" ); + + return *got; +} + + +/* Return the run-time load address of the shared object. */ +static inline Elf32_Addr +elf_machine_load_address (void) +{ + Elf32_Addr addr; + + asm( " bras 1,2f\n" + "1: .long _GLOBAL_OFFSET_TABLE_ - 1b\n" + " .long _dl_start - 1b - 0x80000000\n" + "2: l %0,4(1)\n" + " ar %0,1\n" + " al 1,0(1)\n" + " sl %0,_dl_start@GOT12(1)" + : "=&d" (addr) : : "1" ); + 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 (Elf32_Word); + extern void _dl_runtime_profile (Elf32_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 .rel.plt section, push _GLOBAL_OFFSET_TABLE_[1], + and then jump to _GLOBAL_OFFSET_TABLE[2]. */ + Elf32_Addr *got; + got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]); + got[1] = (Elf32_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] = (Elf32_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] = (Elf32_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 24(r15) and 28(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\ + stm 2,5,32(15)\n\ + st 14,48(15)\n\ + lr 0,15\n\ + ahi 15,-96\n\ + st 0,0(15)\n\ + # load args saved by PLT\n\ + lm 2,3,120(15)\n\ + basr 1,0\n\ +0: ahi 1,1f-0b\n\ + l 14,0(1)\n\ + bas 14,0(14,1) # call fixup\n\ + lr 1,2 # function addr returned in r2\n\ + # restore registers\n\ + ahi 15,96\n\ + l 14,48(15)\n\ + lm 2,5,32(15)\n\ + br 1\n\ +1: .long fixup-1b\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\ + stm 2,5,32(15)\n\ + st 14,48(15)\n\ + lr 0,15\n\ + ahi 15,-96\n\ + st 0,0(15)\n\ + # load args saved by PLT\n\ + lm 2,3,120(15)\n\ + # load return address as third parameter\n\ + lr 4,14\n\ + basr 1,0\n\ +0: ahi 1,1f-0b\n\ + l 14,0(1)\n\ + bas 14,0(14,1) # call fixup\n\ + lr 1,2 # function addr returned in r2\n\ + # restore registers\n\ + ahi 15,96\n\ + l 14,48(15)\n\ + lm 2,5,32(15)\n\ + br 1\n\ +1: .long profile_fixup-1b\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\ + stm 2,5,32(15)\n\ + st 14,48(15)\n\ + lr 0,15\n\ + ahi 15,-96\n\ + st 0,0(15)\n\ + # load args saved by PLT\n\ + lm 2,3,120(15)\n\ + # load return address as third parameter\n\ + lr 4,14\n\ + basr 1,0\n\ +0: ahi 1,1f-0b\n\ + l 14,0(1)\n\ + bas 14,0(14,1) # call fixup\n\ + lr 1,2 # function addr returned in r2\n\ + # restore registers\n\ + ahi 15,96\n\ + l 14,48(15)\n\ + lm 2,5,32(15)\n\ + br 1\n\ +1: .long fixup-1b\n\ + .size _dl_runtime_resolve, .-_dl_runtime_resolve\n\ + .size _dl_runtime_profile, .-_dl_runtime_profile\n\ +"); +#endif + +/* Mask identifying addresses reserved for the user program, + where the dynamic linker should not map anything. */ +#define ELF_MACHINE_USER_ADDRESS_MASK 0xf8000000UL + +/* 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\ + basr %r13,0\n\ +.L0: ahi %r13,.Llit-.L0\n\ + lr %r2,%r15\n\ + # Alloc stack frame\n\ + ahi %r15,-96\n\ + # Set the back chain to zero\n\ + xc 0(4,%r15),0(%r15)\n\ + # Call _dl_start with %r2 pointing to arg on stack\n\ + l %r14,.Ladr1-.Llit(%r13)\n\ + bas %r14,0(%r14,%r13) # call _dl_start\n\ +_dl_start_user:\n\ + # Save the user entry point address in %r8.\n\ + lr %r8,%r2\n\ + # Point %r12 at the GOT.\n\ + l %r12,.Ladr0-.Llit(%r13)\n\ + ar %r12,%r13\n\ + # Store the highest stack address\n\ + l %r1,__libc_stack_end@GOT(%r12)\n\ + st %r15, 0(%r1)\n\ + # See if we were run as a command with the executable file\n\ + # name as an extra leading argument.\n\ + l %r1,_dl_skip_args@GOT12(0,%r12)\n\ + l %r1,0(%r1) # load _dl_skip_args\n\ + # Get the original argument count.\n\ + l %r0,96(%r15)\n\ + # Subtract _dl_skip_args from it.\n\ + sr %r0,%r1\n\ + # Adjust the stack pointer to skip _dl_skip_args words.\n\ + sll %r1,2\n\ + ar %r15,%r1\n\ + # Set the back chain to zero again\n\ + xc 0(4,%r15),0(%r15)\n\ + # Store back the modified argument count.\n\ + st %r0,96(%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\ + l %r2,_dl_loaded@GOT(%r12)\n\ + l %r2,0(%r2)\n\ + l %r3,96(%r15)\n\ + la %r4,100(%r15)\n\ + lr %r5,%r3\n\ + sll %r5,2\n\ + la %r5,104(%r5,%r15)\n\ + l %r1,.Ladr4-.Llit(%r13)\n\ + bas %r14,0(%r1,%r13)\n\ + # Pass our finalizer function to the user in %r14, as per ELF ABI.\n\ + l %r14,_dl_fini@GOT(%r12)\n\ + # Free stack frame\n\ + ahi %r15,96\n\ + # Jump to the user's entry point (saved in %r8).\n\ + br %r8\n\ +.Llit:\n\ +.Ladr0: .long _GLOBAL_OFFSET_TABLE_-.Llit\n\ +.Ladr1: .long _dl_start-.Llit\n\ +.Ladr4: .long _dl_init@PLT-.Llit\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 S390 never uses Elf32_Rel relocations. */ +#define ELF_MACHINE_NO_REL 1 + +/* The S390 overlaps DT_RELA and DT_PLTREL. */ +#define ELF_MACHINE_PLTREL_OVERLAP 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 Elf32_Addr +elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const Elf32_Rela *reloc, + Elf32_Addr *reloc_addr, Elf32_Addr value) +{ + return *reloc_addr = value; +} + +/* Return the final value of a plt relocation. */ +static inline Elf32_Addr +elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + Elf32_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 Elf32_Rela *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, + Elf32_Addr *const reloc_addr) +{ + if (ELF32_R_TYPE (reloc->r_info) == R_390_RELATIVE) { +#ifndef RTLD_BOOTSTRAP + if (map != &_dl_rtld_map) /* Already done in rtld itself. */ +#endif + *reloc_addr = map->l_addr + reloc->r_addend; + } + else if (ELF32_R_TYPE (reloc->r_info) != R_390_NONE) + { + const Elf32_Sym *const refsym = sym; + Elf32_Addr value = RESOLVE (&sym, version, ELF32_R_TYPE (reloc->r_info)); + if (sym) + value += sym->st_value; + + switch (ELF32_R_TYPE (reloc->r_info)) + { + 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_GLOB_DAT: + case R_390_JMP_SLOT: + *reloc_addr = value; + break; + case R_390_32: + { +#ifndef RTLD_BOOTSTRAP + /* This is defined in rtld.c, but nowhere in the static + libc.a; make the reference weak so static programs can + still link. This declaration cannot be done when + compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP) because + rtld.c contains the common defn for _dl_rtld_map, which + is incompatible with a weak decl in the same file. */ + weak_extern (_dl_rtld_map); + if (map == &_dl_rtld_map) + /* Undo the relocation done here during bootstrapping. + Now we will relocate it anew, possibly using a + binding found in the user program or a loaded library + rather than the dynamic linker's built-in definitions + used while loading those libraries. */ + value -= map->l_addr + refsym->st_value; +#endif + *reloc_addr = value + reloc->r_addend; + break; + } + + case R_390_PC32: + *reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr; + break; + case R_390_NONE: + break; + default: + _dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0); + break; + } + } +} + + +static inline void +elf_machine_lazy_rel (struct link_map *map, + Elf32_Addr l_addr, const Elf32_Rela *reloc) +{ + Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + /* Check for unexpected PLT reloc type. */ + if (__builtin_expect (ELF32_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-32/elf/bsd-_setjmp.S b/sysdeps/s390/s390-32/elf/bsd-_setjmp.S new file mode 100644 index 0000000000..1417270201 --- /dev/null +++ b/sysdeps/s390/s390-32/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-32/elf/bsd-setjmp.S b/sysdeps/s390/s390-32/elf/bsd-setjmp.S new file mode 100644 index 0000000000..1417270201 --- /dev/null +++ b/sysdeps/s390/s390-32/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-32/elf/setjmp.S b/sysdeps/s390/s390-32/elf/setjmp.S new file mode 100644 index 0000000000..fd0a169c4c --- /dev/null +++ b/sysdeps/s390/s390-32/elf/setjmp.S @@ -0,0 +1,61 @@ +/* setjmp for s390, ELF version. + Copyright (C) 2000 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) + lhi %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) + lhi %r3,0 /* second argument of zero */ + +ENTRY(__sigsetjmp) +.Linternal_sigsetjmp: + stm %r6,%r15,0(%r2) /* store registers in jmp_buf */ + std %f4,40(%r2) + std %f6,48(%r2) +#ifdef PIC + /* We cannot use the PLT, because it requires that %r12 be set, but + we can't save and restore our caller's value. Instead, we do an + indirect jump through the GOT. */ + basr %r1,0 +.L0: al %r1,.L1 - .L0(0,%r1) /* get address of global offset table */ + /* get address of __sigjmp_save from got */ + l %r1,__sigjmp_save@GOT12(0,%r1) + br %r1 +.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0 +#else + basr %r1,0 +.L0: l %r1,.L1-.L0(0,%r1) /* load address of __sigjmp_save */ + br %r1 /* tail-call __sigjmp_save */ +.L1: .long __sigjmp_save +#endif +END (__sigsetjmp) diff --git a/sysdeps/s390/s390-32/elf/start.S b/sysdeps/s390/s390-32/elf/start.S new file mode 100644 index 0000000000..7313b92e08 --- /dev/null +++ b/sysdeps/s390/s390-32/elf/start.S @@ -0,0 +1,95 @@ +/* Startup code compliant to the ELF s390 ABI. + Copyright (C) 2000, 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 + 4(%r15) argv[0] + ... + (4*argc)(%r15) NULL + (4*(argc+1))(%r15) envp[0] + ... + NULL +*/ + + .text + .globl _start +_start: + /* Setup pointer to literal pool of _start */ + basr %r13,0 +.L0: ahi %r13,.Llit-.L0 + + /* load argc and argv from stack */ + la %r4,4(%r15) # get argv + l %r3,0(%r15) # get argc + + /* align the stack to a double word boundary */ + lhi %r0,-8 + nr %r15,%r0 + + /* Setup a stack frame and a parameter area */ + ahi %r15,-104 # make room on stack + xc 0(4,%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 + */ + stm %r14,%r15,96(%r15) # store rtld_fini/stack_end to parameter area + la %r7,96(%r15) + l %r6,.L2-.Llit(%r13) # load pointer to _fini + l %r5,.L1-.Llit(%r13) # load pointer to _init + l %r2,.L3-.Llit(%r13) # load pointer to main + + /* ok, now branch to the libc main routine */ + l %r1,.L4-.Llit(%r13) + basr %r14,%r1 + + /* crash if __libc_start_main returns */ + .word 0 + +.Llit: +.L1: .long _init +.L2: .long _fini +.L3: .long main +.L4: .long __libc_start_main + +/* 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-32/ffs.c b/sysdeps/s390/s390-32/ffs.c new file mode 100644 index 0000000000..12f265d7b2 --- /dev/null +++ b/sysdeps/s390/s390-32/ffs.c @@ -0,0 +1,68 @@ +/* ffs -- find first set bit in a word, counted from least significant end. + This file is part of the GNU C Library. + Copyright (C) 2000, 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. */ + +#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-32/initfini.c b/sysdeps/s390/s390-32/initfini.c new file mode 100644 index 0000000000..f6dfc3244b --- /dev/null +++ b/sysdeps/s390/s390-32/initfini.c @@ -0,0 +1,149 @@ +/* Special .init and .fini section support for S/390. + Copyright (C) 2000, 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. + + 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 + STM 6,15,24(15) + BRAS 13,.LTN1_0 +.LT1_0: +.LC14: + .long __gmon_start__@GOT +.LC15: + .long _GLOBAL_OFFSET_TABLE_-.LT1_0 +.LTN1_0: + LR 1,15 + AHI 15,-96 + ST 1,0(15) + L 12,.LC15-.LT1_0(13) + AR 12,13 + L 1,.LC14-.LT1_0(13) + L 1,0(1,12) + LTR 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 + L 4,152(15) + LM 6,15,120(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 + STM 6,15,24(15) + BRAS 13,.LTN2_0 +.LT2_0: +.LC17: + .long _GLOBAL_OFFSET_TABLE_-.LT2_0 +.LTN2_0: + LR 1,15 + AHI 15,-96 + ST 1,0(15) + L 12,.LC17-.LT2_0(13) + AR 12,13 +#APP + .align 4,0x07 + END_FINI + +/*@_fini_PROLOG_ENDS*/ + +/*@_fini_EPILOG_BEGINS*/ + .align 4 + .section .fini +#NO_APP + .align 4 + L 4,152(15) + LM 6,15,120(15) + BR 4 +#APP + END_FINI + +/*@_fini_EPILOG_ENDS*/ + +/*@TRAILER_BEGINS*/ +"); diff --git a/sysdeps/s390/s390-32/memchr.S b/sysdeps/s390/s390-32/memchr.S new file mode 100644 index 0000000000..81cefefd55 --- /dev/null +++ b/sysdeps/s390/s390-32/memchr.S @@ -0,0 +1,40 @@ +/* Search a character in a block of memory. For IBM S390 + Copyright (C) 2000, 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. */ + +/* + * 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) + lhi %r0,0xff + nr %r0,%r3 + lr %r1,%r2 + la %r2,0(%r4,%r1) +0: srst %r2,%r1 + jo 0b + brc 13,1f + slr %r2,%r2 +1: br %r14 +END(memchr) diff --git a/sysdeps/s390/s390-32/memcpy.S b/sysdeps/s390/s390-32/memcpy.S new file mode 100644 index 0000000000..4bbec7c633 --- /dev/null +++ b/sysdeps/s390/s390-32/memcpy.S @@ -0,0 +1,41 @@ +/* Set a block of memory to some byte value. For IBM S390 + Copyright (C) 2000, 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. */ + +/* + * 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) + ltr %r5,%r4 + jz .L1 + lr %r4,%r3 # %r4/%r5 = source ptr/len + lr %r3,%r5 # %r2/%r3 = dest ptr/len + lr %r0,%r2 # save source address +.L0: mvcle %r2,%r4,0 # thats it, MVCLE is your friend + jo .L0 + lr %r2,%r0 # return value is source address +.L1: + br %r14 +END(memset) diff --git a/sysdeps/s390/s390-32/memset.S b/sysdeps/s390/s390-32/memset.S new file mode 100644 index 0000000000..047b14c2be --- /dev/null +++ b/sysdeps/s390/s390-32/memset.S @@ -0,0 +1,43 @@ +/* Set a block of memory to some byte value. For IBM S390 + Copyright (C) 2000, 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. */ + +/* + * R2 = address to memory area + * R3 = byte to fill memory with + * R4 = number of bytes to fill + */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(memset) + ltr %r4,%r4 + jz .L1 + lr %r0,%r2 # save source address + lr %r1,%r3 # move pad byte to R1 + lr %r3,%r4 + sr %r4,%r4 # no source for MVCLE, only a pad byte + sr %r5,%r5 +.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend + jo .L0 + lr %r2,%r0 # return value is source address +.L1: + br %r14 +END(memset) diff --git a/sysdeps/s390/s390-32/mul_1.S b/sysdeps/s390/s390-32/mul_1.S new file mode 100644 index 0000000000..48009719d0 --- /dev/null +++ b/sysdeps/s390/s390-32/mul_1.S @@ -0,0 +1,55 @@ +/* __mpn_mul_1 -- Multiply a limb vector with a limb and store + the result in a second limb vector. + Copyright (C) 2000, 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 + size %r4 + s2_limb %r5 +*/ + +#include <sysdep.h> +#include "asm-syntax.h" + + .text +ENTRY(__mpn_mul_1) + st %r6,24(%r15) + slr %r6,%r6 # cy_limb = 0 +.L0: icm %r1,15,0(%r3) # get s1_ptr[i] + mr %r0,%r5 # umul_ppmm(prod_high,prod_low,s1_ptr[j],s2_limb) + jnm .L1 + alr %r0,%r5 +.L1: ltr %r5,%r5 + jnm .L2 + al %r0,0(%r3) +.L2: alr %r1,%r6 # prod_low += cy_limb + lr %r6,%r0 # cy_limb = prod_high + brc 12,.L3 + ahi %r6,1 # + (prod_low < cy_limb) +.L3: st %r1,0(%r2) + la %r2,4(0,%r2) + la %r3,4(0,%r3) + brct %r4,.L0 + lr %r2,%r6 # return cy_limb + l %r6,24(%r15) +.Lexit: br %r14 +END(__mpn_mul_1) diff --git a/sysdeps/s390/s390-32/s390-mcount.S b/sysdeps/s390/s390-32/s390-mcount.S new file mode 100644 index 0000000000..6896291157 --- /dev/null +++ b/sysdeps/s390/s390-32/s390-mcount.S @@ -0,0 +1,84 @@ +/* S/390-specific implemetation of profiling support. + Copyright (C) 2000, 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 <sysdep.h> + +/* + * How profiling works on 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: + * .LC12: .long _mcount + * .LC13: .long .LP0 + * .data + * .align 4 + * .LP0: .long 0 + * .text + * # function profiler + * st 14,4(15) + * l 14,.LC12-.LT0_0(13) + * l 1,.LC13-.LT0_0(13) + * basr 14,14 + * l 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. */ + ahi %r15,-128 + stm %r14,%r5,96(%r15) + l %r2,132(%r15) # callers address = first parameter + la %r2,0(%r2) # clear bit 0 + la %r3,0(%r14) # callees address = second parameter + +#ifdef PIC + bras %r14,0f + .long _GLOBAL_OFFSET_TABLE_-. +0: al %r14,0(%r14) + l %r14,__mcount_internal@GOT(%r14) +#else + bras %r14,0f + .long __mcount_internal +0: l %r14,0(%r14) +#endif + basr %r14,%r14 + + /* + * Pop the saved registers. Please note that `mcount' has no + * return value. + */ + lm %r14,%r5,96(%r15) + ahi %r15,128 + br %r14 + ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount)) + +#undef mcount +weak_alias(_mcount, mcount) diff --git a/sysdeps/s390/s390-32/setjmp.S b/sysdeps/s390/s390-32/setjmp.S new file mode 100644 index 0000000000..23d1039a19 --- /dev/null +++ b/sysdeps/s390/s390-32/setjmp.S @@ -0,0 +1,51 @@ +/* + Copyright (C) 2000, 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) + stm %r6,%r15,0(%r2) /* store registers in jmp_buf */ + std %f4,40(%r2) + std %f6,48(%r2) +#ifdef PIC + /* We cannot use the PLT, because it requires that %r12 be set, but + we can't save and restore our caller's value. Instead, we do an + indirect jump through the GOT. */ + basr %r1,0 +.L0: al %r1,.L1 - .L0(0,%r1) /* get address of global offset table */ + /* get address of __sigjmp_save from got */ + l %r1,__sigjmp_save@GOT12(0,%r1) + br %r1 +.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0 +#else + basr %r1,0 +.L0: l %r1,.L1-.L0(0,%r1) /* load address of __sigjmp_save */ + br %r1 /* tail-call __sigjmp_save */ +.L1: .long __sigjmp_save +#endif +END (__sigsetjmp) diff --git a/sysdeps/s390/s390-32/strcpy.S b/sysdeps/s390/s390-32/strcpy.S new file mode 100644 index 0000000000..cd8600c184 --- /dev/null +++ b/sysdeps/s390/s390-32/strcpy.S @@ -0,0 +1,36 @@ +/* strcpy - copy a string from source to destination. For IBM S390 + This file is part of the GNU C Library. + Copyright (C) 2000, 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. */ + +/* + * R2 = address of destination + * R3 = address of source + */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(strcpy) + slr %r0,%r0 + lr %r1,%r2 +0: mvst %r1,%r3 + jo 0b + br %r14 +END(strcpy) diff --git a/sysdeps/s390/s390-32/strncpy.S b/sysdeps/s390/s390-32/strncpy.S new file mode 100644 index 0000000000..1286526cc6 --- /dev/null +++ b/sysdeps/s390/s390-32/strncpy.S @@ -0,0 +1,79 @@ +/* strncpy - copy at most n characters from a string from source to + destination. For IBM S390 + This file is part of the GNU C Library. + Copyright (C) 2000, 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. */ + +/* + * 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 + st %r2,24(%r15) # save dst pointer + slr %r2,%r3 # %r3 points to src, %r2+%r3 to dst + lhi %r1,3 + nr %r1,%r4 # last 2 bits of # bytes + srl %r4,2 + ltr %r4,%r4 # less than 4 bytes to copy ? + jz .L1 + bras %r5,.L0 # enter loop & load address of a 0 + .long 0 +.L0: icm %r0,8,0(%r3) # first byte + jz .L3 + icm %r0,4,1(%r3) # second byte + jz .L4 + icm %r0,2,2(%r3) # third byte + jz .L5 + icm %r0,1,3(%r3) # fourth byte + jz .L6 + st %r0,0(%r2,%r3) # store all four to dest. + la %r3,4(%r3) + brct %r4,.L0 +.L1: ltr %r1,%r1 + jz .Lexit +.L2: icm %r0,1,0(%r3) + stc %r0,0(%r2,%r3) + la %r3,1(%r3) + jz .L7 + brct %r1,.L2 + j .Lexit +.L3: icm %r0,4,0(%r5) +.L4: icm %r0,2,0(%r5) +.L5: icm %r0,1,0(%r5) +.L6: st %r0,0(%r2,%r3) + la %r3,4(%r3) + ahi %r4,-1 + j .L8 +.L7: ahi %r1,-1 +.L8: sll %r4,2 + alr %r4,%r1 + alr %r2,%r3 # start of dst area to be zeroed + lr %r3,%r4 + slr %r4,%r4 + slr %r5,%r5 +.L9: mvcle %r2,%r4,0 # pad dst with zeroes + jo .L9 +.Lexit: l %r2,24(%r15) # return dst pointer + br %r14 +END(strncpy) diff --git a/sysdeps/s390/s390-32/sub_n.S b/sysdeps/s390/s390-32/sub_n.S new file mode 100644 index 0000000000..dd182434cf --- /dev/null +++ b/sysdeps/s390/s390-32/sub_n.S @@ -0,0 +1,62 @@ +/* __mpn_sub_n -- Add two limb vectors of the same length > 0 and store + sum in a third limb vector. + Copyright (C) 2000, 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" + +ENTRY(__mpn_sub_n) + st %r6,24(%r15) # save register 6 + sr %r1,%r1 + lhi %r0,1 # cannot use ahi to add carry, use slr +.L0: l %r6,0(%r1,%r3) # .L0 -> no carry from last sub + sl %r6,0(%r1,%r4) + st %r6,0(%r1,%r2) + la %r1,4(0,%r1) + brc 4,.L3 +.L1: brct %r5,.L0 + slr %r2,%r2 # no last carry to return + j .Lexit +.L2: l %r6,0(%r1,%r3) # .L2 -> carry from last sub + sl %r6,0(%r1,%r4) + brc 4,.L4 + slr %r6,%r0 # no carry yet, add carry from last sub + st %r6,0(%r1,%r2) + la %r1,4(0,%r1) + brc 11,.L1 # new carry ? +.L3: brct %r5,.L2 + lr %r2,%r0 # return last carry + j .Lexit +.L4: slr %r6,%r0 # already a carry, add carry from last sub + st %r6,0(%r1,%r2) + la %r1,4(0,%r1) + brct %r5,.L2 + lr %r2,%r0 # return last carry +.Lexit: l %r6,24(%r15) # restore register 6 + br %r14 +END(__mpn_sub_n) diff --git a/sysdeps/s390/s390-32/sysdep.h b/sysdeps/s390/s390-32/sysdep.h new file mode 100644 index 0000000000..a05b83cede --- /dev/null +++ b/sysdeps/s390/s390-32/sysdep.h @@ -0,0 +1,121 @@ +/* Assembler macros for s390. + Copyright (C) 2000, 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 \ + lr 0,14 ; bras 14,.+12 ; .long _GLOBAL_OFFSET_TABLE_ - . ; .long 0f-. ; \ + lr 1,14 ; al 1,4(14) ; al 14,0(14) ; l 14,_mcount@GOT(14) ; \ + basr 14,14 ; lr 14,0 ; .data ; .align 4 ; 0: .long 0 ; .text ; +#else +#define CALL_MCOUNT \ + lr 0,14 ; bras 14,.+12 ; .long _mcount ; .long 0f ; \ + l 1,4(14) ; l 14,0(14) ; basr 14,14 ; lr 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) \ + basr %r1,0 \ +0: al %r1,1f-0b(0,%r1) \ + br %r1 \ +1: .long name##@PLT - 0b +#define SYSCALL_PIC_SETUP \ + bras %r12,1f \ +0: .long _GLOBAL_OFFSET_TABLE_-0b \ +1: al %r12,0(%r12) +#else +#define JUMPTARGET(name) \ + basr %r1,0 \ +0: al %r1,1f-0b(0,%r1) \ + br %r1 \ +1: .long name - 0b +#define SYSCALL_PIC_SETUP /* Nothing. */ +#endif + +/* Local label name for asm code. */ +#ifndef L +#define L(name) name +#endif + +#endif /* __ASSEMBLER__ */ |