diff options
Diffstat (limited to 'sysdeps/s390')
47 files changed, 2850 insertions, 0 deletions
diff --git a/sysdeps/s390/Dist b/sysdeps/s390/Dist new file mode 100644 index 0000000000..49292153c4 --- /dev/null +++ b/sysdeps/s390/Dist @@ -0,0 +1,2 @@ +s390-mcount.S +machine-gmon.h diff --git a/sysdeps/s390/Implies b/sysdeps/s390/Implies new file mode 100644 index 0000000000..71bec4de0c --- /dev/null +++ b/sysdeps/s390/Implies @@ -0,0 +1,4 @@ +wordsize-32 +ieee754 +ieee754/dbl-64 +ieee754/flt-32 diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile new file mode 100644 index 0000000000..057862d91b --- /dev/null +++ b/sysdeps/s390/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/__longjmp.c b/sysdeps/s390/__longjmp.c new file mode 100644 index 0000000000..7606aefce2 --- /dev/null +++ b/sysdeps/s390/__longjmp.c @@ -0,0 +1,43 @@ +/* Copyright (C) 2000 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) +{ + unsigned int result; + + /* Restore registers and jump back */ + asm volatile("lr %%r2,%0\n\t" /* put val in grp 2 */ + "lm %%r6,%%r15,%1\n\t" + "br %%r14" + : : "r" (val == 0 ? 1 : val), + "m" (env->gregs[JB_GPR6]) : "2" ); + + /* Avoid `volatile function does return' warnings. */ + for (;;); +} diff --git a/sysdeps/s390/abort-instr.h b/sysdeps/s390/abort-instr.h new file mode 100644 index 0000000000..6544b2d618 --- /dev/null +++ b/sysdeps/s390/abort-instr.h @@ -0,0 +1,2 @@ +/* An op-code of 0 should crash any program. */ +#define ABORT_INSTRUCTION asm (".word 0") diff --git a/sysdeps/s390/add_n.S b/sysdeps/s390/add_n.S new file mode 100644 index 0000000000..4b7d8418c9 --- /dev/null +++ b/sysdeps/s390/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 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/addmul_1.S b/sysdeps/s390/addmul_1.S new file mode 100644 index 0000000000..c98a4c1524 --- /dev/null +++ b/sysdeps/s390/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 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/asm-syntax.h b/sysdeps/s390/asm-syntax.h new file mode 100644 index 0000000000..5e050f77f9 --- /dev/null +++ b/sysdeps/s390/asm-syntax.h @@ -0,0 +1,42 @@ +/* Definitions for S/390 syntax variations. + Copyright (C) 1992, 1994, 1995, 1997, 2000 Free Software Foundation, Inc. + + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in 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. */ + +#undef ALIGN +#if defined NOLOG_ALIGN || defined HAVE_ELF +# define ALIGN(log) .align 1<<log +#else +# define ALIGN(log) .align log +#endif + +#undef L +#ifdef __ELF__ +# ifdef __STDC__ +# define L(body) .L##body +# else +# define L(body) .L/**/body +# endif +#else +# ifdef __STDC__ +# define L(body) L##body +# else +# define L(body) L/**/body +# endif +#endif diff --git a/sysdeps/s390/atomicity.h b/sysdeps/s390/atomicity.h new file mode 100644 index 0000000000..0c97f405ef --- /dev/null +++ b/sysdeps/s390/atomicity.h @@ -0,0 +1,74 @@ +/* Low-level functions for atomic operations. S390 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. */ + +#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__( + " cs %2,%3,%1\n" + " ipm %0\n" + " srl %0,28\n" + "0:" + : "=&r" (retval), "+m" (*p) + : "d" (oldval) , "d" (newval) + : "memory", "cc"); + return !retval; +} + +#endif /* atomicity.h */ diff --git a/sysdeps/s390/backtrace.c b/sysdeps/s390/backtrace.c new file mode 100644 index 0000000000..5e7f802810 --- /dev/null +++ b/sysdeps/s390/backtrace.c @@ -0,0 +1,81 @@ +/* Return backtrace of current program state. + 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 <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/bcopy.S b/sysdeps/s390/bcopy.S new file mode 100644 index 0000000000..dafe9ee186 --- /dev/null +++ b/sysdeps/s390/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 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/bits/byteswap.h b/sysdeps/s390/bits/byteswap.h new file mode 100644 index 0000000000..ad20e97dc6 --- /dev/null +++ b/sysdeps/s390/bits/byteswap.h @@ -0,0 +1,86 @@ +/* Macros to swap the order of bytes in integer values. s390 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. */ + +#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/bits/endian.h b/sysdeps/s390/bits/endian.h new file mode 100644 index 0000000000..ac27f0119a --- /dev/null +++ b/sysdeps/s390/bits/endian.h @@ -0,0 +1,7 @@ +/* s390 is big-endian */ + +#ifndef _ENDIAN_H +# error "Never use <bits/endian.h> directly; include <endian.h> instead." +#endif + +#define __BYTE_ORDER __BIG_ENDIAN diff --git a/sysdeps/s390/bits/huge_val.h b/sysdeps/s390/bits/huge_val.h new file mode 100644 index 0000000000..0c8264c90f --- /dev/null +++ b/sysdeps/s390/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 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/bits/setjmp.h b/sysdeps/s390/bits/setjmp.h new file mode 100644 index 0000000000..e778e9c6d5 --- /dev/null +++ b/sysdeps/s390/bits/setjmp.h @@ -0,0 +1,52 @@ +/* Copyright (C) 2000 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 long fpregs[2]; +} __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/bits/string.h b/sysdeps/s390/bits/string.h new file mode 100644 index 0000000000..4aeb146f3e --- /dev/null +++ b/sysdeps/s390/bits/string.h @@ -0,0 +1,140 @@ +/* Optimized, inlined string functions. s390 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. */ + +#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 + +#ifdef __cplusplus +# define __STRING_INLINE inline +#else +# define __STRING_INLINE extern __inline +#endif + +#define _HAVE_STRING_ARCH_strlen 1 +__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; +} + +/* Copy SRC to DEST. */ +#define _HAVE_STRING_ARCH_strcpy 1 +__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; +} + +#define _HAVE_STRING_ARCH_strncpy 1 +__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; +} + +/* Append SRC onto DEST. */ +#define _HAVE_STRING_ARCH_strcat 1 +__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; +} + +/* Append no more than N characters from SRC onto DEST. */ +#define _HAVE_STRING_ARCH_strncat 1 +__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" + "2:" + : "+&a" (__dest), "+&a" (__src), "+&d" (__n) : + : "cc", "memory", "0" ); + return tmp; +} + +#endif /* Use string inlines && GNU CC. */ diff --git a/sysdeps/s390/bsd-_setjmp.S b/sysdeps/s390/bsd-_setjmp.S new file mode 100644 index 0000000000..2b664409de --- /dev/null +++ b/sysdeps/s390/bsd-_setjmp.S @@ -0,0 +1,46 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. s390 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. */ + +/* 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/bsd-setjmp.S b/sysdeps/s390/bsd-setjmp.S new file mode 100644 index 0000000000..ab5aa0c663 --- /dev/null +++ b/sysdeps/s390/bsd-setjmp.S @@ -0,0 +1,46 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. s390 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. */ + +/* 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/bzero.S b/sysdeps/s390/bzero.S new file mode 100644 index 0000000000..4d0db82fa0 --- /dev/null +++ b/sysdeps/s390/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 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/dl-machine.h b/sysdeps/s390/dl-machine.h new file mode 100644 index 0000000000..3cab824ce2 --- /dev/null +++ b/sysdeps/s390/dl-machine.h @@ -0,0 +1,464 @@ +/* Machine-dependent ELF dynamic relocation inline functions. S390 Version. + Copyright (C) 2000 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> + + +/* Return nonzero iff E_MACHINE is compatible with the running host. */ +static inline int +elf_machine_matches_host (Elf32_Half e_machine) +{ + switch (e_machine) + { + case EM_S390: + return 1; + default: + return 0; + } +} + + +/* 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 + +/* The PLT uses Elf32_Rela relocs. */ +#define elf_machine_relplt elf_machine_rela + +/* 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 describes relocation of a PLT entry, so + PLT entries should not be allowed to define the value. */ +#define elf_machine_pltrel_p(type) ((type) == R_390_JMP_SLOT) + +/* 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_sysdep_error (_dl_argv[0] ?: "<program name unknown>", + ": Symbol `", strtab + refsym->st_name, + "' has different size in shared object, " + "consider re-linking\n", NULL); + } + 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/elf/bsd-_setjmp.S b/sysdeps/s390/elf/bsd-_setjmp.S new file mode 100644 index 0000000000..1417270201 --- /dev/null +++ b/sysdeps/s390/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/elf/bsd-setjmp.S b/sysdeps/s390/elf/bsd-setjmp.S new file mode 100644 index 0000000000..1417270201 --- /dev/null +++ b/sysdeps/s390/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/elf/setjmp.S b/sysdeps/s390/elf/setjmp.S new file mode 100644 index 0000000000..952cba2102 --- /dev/null +++ b/sysdeps/s390/elf/setjmp.S @@ -0,0 +1,58 @@ +/* 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 __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) + stm %r6,%r15,0(%r2) /* store registers in jmp_buf */ +#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/elf/start.S b/sysdeps/s390/elf/start.S new file mode 100644 index 0000000000..1455572af8 --- /dev/null +++ b/sysdeps/s390/elf/start.S @@ -0,0 +1,95 @@ +/* Startup code compliant to the ELF s390 ABI. + 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. */ + +/* + 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/ffs.c b/sysdeps/s390/ffs.c new file mode 100644 index 0000000000..b6ed821e58 --- /dev/null +++ b/sysdeps/s390/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 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/fpu/bits/fenv.h b/sysdeps/s390/fpu/bits/fenv.h new file mode 100644 index 0000000000..81732b9972 --- /dev/null +++ b/sysdeps/s390/fpu/bits/fenv.h @@ -0,0 +1,90 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Denis Joseph Barrow (djbarrow@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. + + */ + +#ifndef _FENV_H +# error "Never use <bits/fenv.h> directly; include <fenv.h> instead." +#endif + +/* Define bits representing the exception. We use the bit positions + of the appropriate bits in the FPU control word. */ +enum + { + FE_INVALID = 0x80, +#define FE_INVALID FE_INVALID + FE_DIVBYZERO = 0x40, +#define FE_DIVBYZERO FE_DIVBYZERO + FE_OVERFLOW = 0x20, +#define FE_OVERFLOW FE_OVERFLOW + FE_UNDERFLOW = 0x10, +#define FE_UNDERFLOW FE_UNDERFLOW + FE_INEXACT = 0x08 +#define FE_INEXACT FE_INEXACT + }; +/* We dont use the y bit of the DXC in the floating point control register + * as glibc has no FE encoding for fe inexact incremented + * or fe inexact truncated. + * We currently use the flag bits in the fpc + * as these are sticky for feholdenv & feupdatenv as it is defined + * in the HP Manpages. + */ + + +#define FE_ALL_EXCEPT \ + (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) + +enum + { + FE_TONEAREST = 0, +#define FE_TONEAREST FE_TONEAREST + FE_DOWNWARD = 0x3, +#define FE_DOWNWARD FE_DOWNWARD + FE_UPWARD = 0x2, +#define FE_UPWARD FE_UPWARD + FE_TOWARDZERO = 0x1 +#define FE_TOWARDZERO FE_TOWARDZERO + }; + +#define FPC_EXCEPTION_MASK_SHIFT 24 +#define FPC_FLAGS_SHIFT 16 +#define FPC_DXC_SHIFT 8 +#define FPC_NOT_FPU_EXCEPTION 0x300 + + +/* Type representing exception flags. */ +typedef unsigned int fexcept_t; /* size of fpc */ + + +/* Type representing floating-point environment. This function corresponds + to the layout of the block written by the `fstenv'. */ +typedef struct +{ + fexcept_t fpc; + void *ieee_instruction_pointer; + /* failing instruction for ieee exceptions */ +} fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((fenv_t *) -1) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exceptions are masked. */ +#define FE_NOMASK_ENV ((fenv_t *) -2) +#endif diff --git a/sysdeps/s390/fpu/fclrexcpt.c b/sysdeps/s390/fpu/fclrexcpt.c new file mode 100644 index 0000000000..aa159fd282 --- /dev/null +++ b/sysdeps/s390/fpu/fclrexcpt.c @@ -0,0 +1,40 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 2000 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. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + fexcept_t temp; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + _FPU_GETCW(temp); + /* Clear the relevant bits. */ + temp &= ~((excepts<<FPC_DXC_SHIFT)|(excepts<<FPC_FLAGS_SHIFT)); + + /* Put the new data in effect. */ + _FPU_SETCW(temp); + + /* Success. */ + return 0; +} diff --git a/sysdeps/s390/fpu/fegetround.c b/sysdeps/s390/fpu/fegetround.c new file mode 100644 index 0000000000..3742588629 --- /dev/null +++ b/sysdeps/s390/fpu/fegetround.c @@ -0,0 +1,35 @@ +/* Return current rounding direction. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Denis Joseph Barrow (djbarrow@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 <fenv.h> +#include <fpu_control.h> + +int +fegetround (void) +{ + fexcept_t cw; + + _FPU_GETCW(cw); + + return cw & FPC_RM_MASK; +} + + diff --git a/sysdeps/s390/fpu/fesetround.c b/sysdeps/s390/fpu/fesetround.c new file mode 100644 index 0000000000..ba8c1b0be3 --- /dev/null +++ b/sysdeps/s390/fpu/fesetround.c @@ -0,0 +1,37 @@ +/* Set current rounding direction. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Denis Joseph Barrow (djbarrow@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 <fenv.h> +#include <fpu_control.h> + +int +fesetround (int round) +{ + if ((round|FPC_RM_MASK) != FPC_RM_MASK) + { + /* ROUND is not a valid rounding mode. */ + return 1; + } + __asm__ volatile ("srnm 0(%0)" + : + : "a" (round)); + + return 0; +} diff --git a/sysdeps/s390/fpu/fgetexcptflg.c b/sysdeps/s390/fpu/fgetexcptflg.c new file mode 100644 index 0000000000..d4a49d6731 --- /dev/null +++ b/sysdeps/s390/fpu/fgetexcptflg.c @@ -0,0 +1,46 @@ +/* Store current representation for exceptions. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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. + + Contributed by: + Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) +*/ + +#include <fenv.h> +#include <fpu_control.h> + +int fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fexcept_t temp,newexcepts; + + /* Get the current exceptions. */ + _FPU_GETCW(temp); + newexcepts=((excepts<<FPC_DXC_SHIFT)|(excepts<<FPC_FLAGS_SHIFT)); + *flagp = temp & newexcepts; + + /* Success. */ + return 0; +} + + + + + + + diff --git a/sysdeps/s390/fpu/fpu_control.h b/sysdeps/s390/fpu/fpu_control.h new file mode 100644 index 0000000000..7552cfa8ff --- /dev/null +++ b/sysdeps/s390/fpu/fpu_control.h @@ -0,0 +1,47 @@ +/* FPU control word definitions. Stub version. + Copyright (C) 1999 Free Software Foundation, Inc. + Contributed by + Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) and + 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 _FPU_CONTROL_H +# define _FPU_CONTROL_H + +# include <features.h> + +/* These bits are reserved are not changed. */ +# define _FPU_RESERVED 0x070700FC + +/* The fdlibm code requires no interrupts for exceptions. Don't + change the rounding mode, it would break long double I/O! */ +#define _FPU_DEFAULT 0x00000000 /* Default value. */ + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Macros for accessing the hardware control word. */ +#define _FPU_GETCW(cw) __asm__ volatile ("efpc %0,0" : "=d" (cw)) +#define _FPU_SETCW(cw) __asm__ volatile ("sfpc %0,0" : : "d" (cw)) + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* _FPU_CONTROL_H */ + + + diff --git a/sysdeps/s390/gmp-mparam.h b/sysdeps/s390/gmp-mparam.h new file mode 100644 index 0000000000..8de5b8de14 --- /dev/null +++ b/sysdeps/s390/gmp-mparam.h @@ -0,0 +1,29 @@ +/* gmp-mparam.h -- Compiler/machine parameter header file. + Copyright (C) 2000 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 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 BITS_PER_MP_LIMB 32 +#define BYTES_PER_MP_LIMB 4 +#define BITS_PER_LONGINT 32 +#define BITS_PER_INT 32 +#define BITS_PER_SHORTINT 16 +#define BITS_PER_CHAR 8 + +#define IEEE_DOUBLE_BIG_ENDIAN 0 diff --git a/sysdeps/s390/ldbl2mpn.c b/sysdeps/s390/ldbl2mpn.c new file mode 100644 index 0000000000..631fe2eab4 --- /dev/null +++ b/sysdeps/s390/ldbl2mpn.c @@ -0,0 +1,101 @@ +/* Copyright (C) 1995, 1996, 1997 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. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" +#include "ieee754.h" +#include <float.h> +#include <stdlib.h> + +/* Convert a `long double' in IEEE854 standard double-precision format to a + multi-precision integer representing the significand scaled up by its + number of bits (64 for long double) and an integral power of two + (MPN frexpl). */ + +mp_size_t +__mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, + int *expt, int *is_neg, + long double value) +{ + union ieee854_long_double u; + u.d = value; + + *is_neg = u.ieee.negative; + *expt = (int) u.ieee.exponent - IEEE854_LONG_DOUBLE_BIAS; + +#if BITS_PER_MP_LIMB == 32 + res_ptr[0] = u.ieee.mantissa1; /* Low-order 32 bits of fraction. */ + res_ptr[1] = u.ieee.mantissa0; /* High-order 32 bits. */ + #define N 2 +#elif BITS_PER_MP_LIMB == 64 + /* Hopefully the compiler will combine the two bitfield extracts + and this composition into just the original quadword extract. */ + res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; + #define N 1 +#else + #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" +#endif + + if (u.ieee.exponent == 0) + { + /* A biased exponent of zero is a special case. + Either it is a zero or it is a denormal number. */ + if (res_ptr[0] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=2. */ + /* It's zero. */ + *expt = 0; + else + { + /* It is a denormal number, meaning it has no implicit leading + one bit, and its exponent is in fact the format minimum. */ + int cnt; + + /* One problem with Intel's 80-bit format is that the explicit + leading one in the normalized representation has to be zero + for denormalized number. If it is one, the number is according + to Intel's specification an invalid number. We make the + representation unique by explicitly clearing this bit. */ + res_ptr[N - 1] &= ~(1L << ((LDBL_MANT_DIG - 1) % BITS_PER_MP_LIMB)); + + if (res_ptr[N - 1] != 0) + { + count_leading_zeros (cnt, res_ptr[N - 1]); + if (cnt != 0) + { +#if N == 2 + res_ptr[N - 1] = res_ptr[N - 1] << cnt + | (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt)); + res_ptr[0] <<= cnt; +#else + res_ptr[N - 1] <<= cnt; +#endif + } + *expt = LDBL_MIN_EXP - 1 - cnt; + } + else + { + count_leading_zeros (cnt, res_ptr[0]); + res_ptr[N - 1] = res_ptr[0] << cnt; + res_ptr[0] = 0; + *expt = LDBL_MIN_EXP - 1 - BITS_PER_MP_LIMB - cnt; + } + } + } + + return N; +} diff --git a/sysdeps/s390/machine-gmon.h b/sysdeps/s390/machine-gmon.h new file mode 100644 index 0000000000..019baae46e --- /dev/null +++ b/sysdeps/s390/machine-gmon.h @@ -0,0 +1,36 @@ +/* s390-specific implementation of profiling support. + Copyright (C) 2000 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. */ + +#include <sysdep.h> + +/* We need a special version of the `mcount' function since for S/390 it + must not clobber any register. */ + +/* We must not pollute the global namespace. */ +#define mcount_internal __mcount_internal + +void mcount_internal (u_long frompc, u_long selfpc); + +#define _MCOUNT_DECL(frompc, selfpc) \ +void mcount_internal (u_long frompc, u_long selfpc) + + +/* Define MCOUNT as empty since we have the implementation in another + file. */ +#define MCOUNT diff --git a/sysdeps/s390/memchr.S b/sysdeps/s390/memchr.S new file mode 100644 index 0000000000..72b4682745 --- /dev/null +++ b/sysdeps/s390/memchr.S @@ -0,0 +1,40 @@ +/* Search a character in a block of memory. For IBM S390 + Copyright (C) 2000 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/memcpy.S b/sysdeps/s390/memcpy.S new file mode 100644 index 0000000000..94119ea0e1 --- /dev/null +++ b/sysdeps/s390/memcpy.S @@ -0,0 +1,41 @@ +/* Set a block of memory to some byte value. For IBM S390 + Copyright (C) 2000 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/memset.S b/sysdeps/s390/memset.S new file mode 100644 index 0000000000..e917fe031b --- /dev/null +++ b/sysdeps/s390/memset.S @@ -0,0 +1,43 @@ +/* Set a block of memory to some byte value. For IBM S390 + Copyright (C) 2000 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/memusage.h b/sysdeps/s390/memusage.h new file mode 100644 index 0000000000..d34f42c44f --- /dev/null +++ b/sysdeps/s390/memusage.h @@ -0,0 +1,21 @@ +/* Copyright (C) 2000 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 GETSP() ({ register uintptr_t stack_ptr asm ("15"); stack_ptr; }) + +#include <sysdeps/generic/memusage.h> diff --git a/sysdeps/s390/mul_1.S b/sysdeps/s390/mul_1.S new file mode 100644 index 0000000000..1804114741 --- /dev/null +++ b/sysdeps/s390/mul_1.S @@ -0,0 +1,55 @@ +/* i80386 __mpn_mul_1 -- Multiply a limb vector with a limb and store + the result in a second limb vector. + Copyright (C) 2000 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-mcount.S b/sysdeps/s390/s390-mcount.S new file mode 100644 index 0000000000..e7c16b7052 --- /dev/null +++ b/sysdeps/s390/s390-mcount.S @@ -0,0 +1,84 @@ +/* S/390-specific implemetation of profiling support. + Copyright (C) 2000 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/setjmp.S b/sysdeps/s390/setjmp.S new file mode 100644 index 0000000000..af3d3601f4 --- /dev/null +++ b/sysdeps/s390/setjmp.S @@ -0,0 +1,55 @@ +/* + 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. */ + +#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 */ + +/* Binary compatibility entry point. */ + +ENTRY(__setjmp) + sr %r3,%r3 /* set savemask to zero */ +END (__setjmp) + +ENTRY(__sigsetjmp) + stm %r6,%r15,0(%r2) /* store registers in jmp_buf */ +#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/stackinfo.h b/sysdeps/s390/stackinfo.h new file mode 100644 index 0000000000..f1bd9bd5e7 --- /dev/null +++ b/sysdeps/s390/stackinfo.h @@ -0,0 +1,28 @@ +/* Copyright (C) 2000 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. */ + +/* This file contains a bit of information about the stack allocation + of the processor. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +/* On s390 the stack grows down. */ +#define _STACK_GROWS_DOWN 1 + +#endif /* stackinfo.h */ diff --git a/sysdeps/s390/strcpy.S b/sysdeps/s390/strcpy.S new file mode 100644 index 0000000000..fedefd8f31 --- /dev/null +++ b/sysdeps/s390/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 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/strncpy.S b/sysdeps/s390/strncpy.S new file mode 100644 index 0000000000..823eeb4f5e --- /dev/null +++ b/sysdeps/s390/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 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/sub_n.S b/sysdeps/s390/sub_n.S new file mode 100644 index 0000000000..5eee0fb13d --- /dev/null +++ b/sysdeps/s390/sub_n.S @@ -0,0 +1,62 @@ +/* i80386 __mpn_sub_n -- Add two limb vectors of the same length > 0 and store + sum in a third limb vector. + Copyright (C) 2000 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/sys/ucontext.h b/sysdeps/s390/sys/ucontext.h new file mode 100644 index 0000000000..c00bb5c786 --- /dev/null +++ b/sysdeps/s390/sys/ucontext.h @@ -0,0 +1,95 @@ +/* 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. */ + +/* System V/s390 ABI compliant context switching support. */ + +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include <features.h> +#include <signal.h> + +/* Type for general register. */ +typedef int greg_t; + +/* Number of general registers. */ +#define NGREG 16 + +/* Number of each register is the `greg_t gregs[NREG]' array. */ +enum +{ + R_GPR0 = 0, +#define R_GPR0 R_GPR0 + R_GPR1 = 1, +#define R_GPR1 R_GPR1 + R_GPR2 = 2, +#define R_GPR2 R_GPR2 + R_GPR3 = 3, +#define R_GPR3 R_GPR3 + R_GPR4 = 4, +#define R_GPR4 R_GPR4 + R_GPR5 = 5, +#define R_GPR5 R_GPR5 + R_GPR6 = 6, +#define R_GPR6 R_GPR6 + R_GPR7 = 7, +#define R_GPR7 R_GPR7 + R_GPR8 = 8, +#define R_GPR8 R_GPR8 + R_GPR9 = 9, +#define R_GPR9 R_GPR9 + R_GPRA = 10, +#define R_GPRA R_GPRA + R_GPRB = 11, +#define R_GPRB R_GPRB + R_GPRC = 12, +#define R_GPRC R_GPRC + R_GPRD = 13, +#define R_GPRD R_GPRD + R_GPRE = 14, +#define R_GPRE R_GPRE + R_GPRF = 15 +#define R_GPRF R_GPRF +}; + +/* Structure to describe FPU registers. */ +typedef long long fpreg_t; + +/* Context to describe whole processor state. */ +typedef struct +{ + int version; + greg_t gregs[NGREG]; + fpreg_t fpregs[16]; +} mcontext_t; + +#define MCONTEXT_VERSION 1 + +/* Userlevel context. */ +typedef struct ucontext +{ + unsigned long int uc_flags; + struct ucontext *uc_links; + __sigset_t uc_sigmask; + stack_t uc_stack; + mcontext_t uc_mcontext; + long int uc_filler[170]; +} ucontext_t; + +#endif /* sys/ucontext.h */ diff --git a/sysdeps/s390/sysdep.h b/sysdeps/s390/sysdep.h new file mode 100644 index 0000000000..6915379de4 --- /dev/null +++ b/sysdeps/s390/sysdep.h @@ -0,0 +1,121 @@ +/* Assembler macros for s390. + 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 <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__ */ |