mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-08 17:42:12 +03:00
2.5-18.1
This commit is contained in:
@@ -1 +0,0 @@
|
||||
sys/trap.h
|
@@ -1,3 +1,6 @@
|
||||
# The Sparc `long double' is a distinct type we support.
|
||||
long-double-fcts = yes
|
||||
|
||||
ifeq ($(subdir),db2)
|
||||
CPPFLAGS += -DHAVE_SPINLOCKS=1 -DHAVE_ASSEM_SPARC_GCC=1
|
||||
endif
|
||||
|
100
sysdeps/sparc/bits/link.h
Normal file
100
sysdeps/sparc/bits/link.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/* Machine-specific audit interfaces for dynamic linker. SPARC version.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _LINK_H
|
||||
# error "Never include <bits/link.h> directly; use <link.h> instead."
|
||||
#endif
|
||||
|
||||
#if __WORDSIZE == 32
|
||||
|
||||
typedef struct La_sparc32_regs
|
||||
{
|
||||
uint32_t lr_lreg[8]; /* %l0 through %l7 */
|
||||
uint32_t lr_reg[6]; /* %o0 through %o5 */
|
||||
uint32_t lr_sp; /* %o6 */
|
||||
uint32_t lr_ra; /* %o7 */
|
||||
uint32_t lr_struct; /* Pass-by-reference struct pointer */
|
||||
} La_sparc32_regs;
|
||||
|
||||
typedef struct La_sparc32_retval
|
||||
{
|
||||
uint32_t lrv_reg[2]; /* %o0 and %o1 */
|
||||
double lrv_fpreg[2]; /* %f0 and %f2 */
|
||||
} La_sparc32_retval;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct La_sparc64_regs
|
||||
{
|
||||
uint64_t lr_lreg[8]; /* %l0 through %l7 */
|
||||
uint64_t lr_reg[6]; /* %o0 through %o5 */
|
||||
uint64_t lr_sp; /* %o6 */
|
||||
uint64_t lr_ra; /* %o7 */
|
||||
double lr_fpreg[16]; /* %f0 through %f30 */
|
||||
} La_sparc64_regs;
|
||||
|
||||
typedef struct La_sparc64_retval
|
||||
{
|
||||
uint64_t lrv_reg[4]; /* %o0 through %o3 */
|
||||
double lrv_fprev[4]; /* %f0 through %f8 */
|
||||
} La_sparc64_retval;
|
||||
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#if __WORDSIZE == 32
|
||||
|
||||
extern Elf32_Addr la_sparc32_gnu_pltenter (Elf32_Sym *__sym,
|
||||
unsigned int __ndx,
|
||||
uintptr_t *__refcook,
|
||||
uintptr_t *__defcook,
|
||||
La_sparc32_regs *__regs,
|
||||
unsigned int *__flags,
|
||||
const char *__symname,
|
||||
long int *__framesizep);
|
||||
extern unsigned int la_sparc32_gnu_pltexit (Elf32_Sym *__sym,
|
||||
unsigned int __ndx,
|
||||
uintptr_t *__refcook,
|
||||
uintptr_t *__defcook,
|
||||
const La_sparc32_regs *__inregs,
|
||||
La_sparc32_retval *__outregs,
|
||||
const char *symname);
|
||||
|
||||
#else
|
||||
|
||||
extern Elf64_Addr la_sparc64_gnu_pltenter (Elf64_Sym *__sym,
|
||||
unsigned int __ndx,
|
||||
uintptr_t *__refcook,
|
||||
uintptr_t *__defcook,
|
||||
La_sparc64_regs *__regs,
|
||||
unsigned int *__flags,
|
||||
const char *__symname,
|
||||
long int *__framesizep);
|
||||
extern unsigned int la_sparc64_gnu_pltexit (Elf64_Sym *__sym,
|
||||
unsigned int __ndx,
|
||||
uintptr_t *__refcook,
|
||||
uintptr_t *__defcook,
|
||||
const La_sparc64_regs *__inregs,
|
||||
La_sparc64_retval *__outregs,
|
||||
const char *symname);
|
||||
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1997, 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1997, 1998, 1999, 2000, 2004, 2006
|
||||
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
|
||||
@@ -55,14 +56,3 @@ typedef double double_t;
|
||||
# define FP_ILOGBNAN (2147483647)
|
||||
|
||||
#endif /* ISO C99 */
|
||||
|
||||
#ifndef __NO_LONG_DOUBLE_MATH
|
||||
|
||||
# if __WORDSIZE == 32
|
||||
/* Signal that in 32bit ABI we do not really have a `long double'.
|
||||
The disables the declaration of all the `long double' function
|
||||
variants. */
|
||||
# define __NO_LONG_DOUBLE_MATH 1
|
||||
# endif
|
||||
|
||||
#endif
|
62
sysdeps/sparc/dl-procinfo.c
Normal file
62
sysdeps/sparc/dl-procinfo.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/* Data for Linux/sparc version of processor capability information.
|
||||
Copyright (C) 2002,2003,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* This information must be kept in sync with the _DL_HWCAP_COUNT
|
||||
definition in procinfo.h.
|
||||
|
||||
If anything should be added here check whether the size of each string
|
||||
is still ok with the given array size.
|
||||
|
||||
All the #ifdefs in the definitions ar equite irritating but
|
||||
necessary if we want to avoid duplicating the information. There
|
||||
are three different modes:
|
||||
|
||||
- PROCINFO_DECL is defined. This means we are only interested in
|
||||
declarations.
|
||||
|
||||
- PROCINFO_DECL is not defined:
|
||||
|
||||
+ if SHARED is defined the file is included in an array
|
||||
initializer. The .element = { ... } syntax is needed.
|
||||
|
||||
+ if SHARED is not defined a normal array initialization is
|
||||
needed.
|
||||
*/
|
||||
|
||||
#ifndef PROCINFO_CLASS
|
||||
#define PROCINFO_CLASS
|
||||
#endif
|
||||
|
||||
#if !defined PROCINFO_DECL && defined SHARED
|
||||
._dl_sparc_cap_flags
|
||||
#else
|
||||
PROCINFO_CLASS const char _dl_sparc_cap_flags[7][7]
|
||||
#endif
|
||||
#ifndef PROCINFO_DECL
|
||||
= { "flush", "stbar", "swap", "muldiv", "v9", "ultra3", "v9v" }
|
||||
#endif
|
||||
#if !defined SHARED || defined PROCINFO_DECL
|
||||
;
|
||||
#else
|
||||
,
|
||||
#endif
|
||||
|
||||
#undef PROCINFO_DECL
|
||||
#undef PROCINFO_CLASS
|
79
sysdeps/sparc/dl-procinfo.h
Normal file
79
sysdeps/sparc/dl-procinfo.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* Linux/sparc version of processor capability information handling macros.
|
||||
Copyright (C) 1999,2000,2001,2002,2003,2004,2006
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jj@ultra.linux.cz>, 1999.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _DL_PROCINFO_H
|
||||
#define _DL_PROCINFO_H 1
|
||||
|
||||
#include <ldsodefs.h>
|
||||
|
||||
#define _DL_HWCAP_COUNT 7
|
||||
|
||||
static inline int
|
||||
__attribute__ ((unused))
|
||||
_dl_procinfo (int word)
|
||||
{
|
||||
int i;
|
||||
|
||||
_dl_printf ("AT_HWCAP: ");
|
||||
|
||||
for (i = 0; i < _DL_HWCAP_COUNT; ++i)
|
||||
if (word & (1 << i))
|
||||
_dl_printf (" %s", GLRO(dl_sparc_cap_flags)[i]);
|
||||
|
||||
_dl_printf ("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
__attribute__ ((unused))
|
||||
_dl_hwcap_string (int idx)
|
||||
{
|
||||
return GLRO(dl_sparc_cap_flags)[idx];
|
||||
};
|
||||
|
||||
static inline int
|
||||
__attribute__ ((unused, always_inline))
|
||||
_dl_string_hwcap (const char *str)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < _DL_HWCAP_COUNT; i++)
|
||||
{
|
||||
if (strcmp (str, GLRO(dl_sparc_cap_flags) [i]) == 0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
#define HWCAP_IMPORTANT_V9 (__WORDSIZE == 64 ? 0 : HWCAP_SPARC_V9)
|
||||
#define HWCAP_IMPORTANT (HWCAP_IMPORTANT_V9 | HWCAP_SPARC_ULTRA3 \
|
||||
| HWCAP_SPARC_BLKINIT)
|
||||
|
||||
/* There are no different platforms defined. */
|
||||
#define _dl_platform_string(idx) ""
|
||||
|
||||
/* There're no platforms to filter out. */
|
||||
#define _DL_HWCAP_PLATFORM 0
|
||||
|
||||
#define _dl_string_platform(str) (-1)
|
||||
|
||||
#endif /* dl-procinfo.h */
|
@@ -1,5 +1,5 @@
|
||||
/* System-specific settings for dynamic linker code. SPARC version.
|
||||
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003, 2004, 2005 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
|
||||
@@ -17,25 +17,8 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _DL_SYSDEP_H
|
||||
#define _DL_SYSDEP_H 1
|
||||
|
||||
/* This macro must be defined to either 0 or 1.
|
||||
|
||||
If 1, then an errno global variable hidden in ld.so will work right with
|
||||
all the errno-using libc code compiled for ld.so, and there is never a
|
||||
need to share the errno location with libc. This is appropriate only if
|
||||
all the libc functions that ld.so uses are called without PLT and always
|
||||
get the versions linked into ld.so rather than the libc ones. */
|
||||
|
||||
#ifdef IS_IN_rtld
|
||||
# define RTLD_PRIVATE_ERRNO 1
|
||||
#else
|
||||
# define RTLD_PRIVATE_ERRNO 0
|
||||
#endif
|
||||
#include_next <dl-sysdep.h>
|
||||
|
||||
/* _dl_argv cannot be attribute_relro, because _dl_start_user
|
||||
might write into it after _dl_start returns. */
|
||||
#define DL_ARGV_NOT_RELRO 1
|
||||
|
||||
#endif /* dl-sysdep.h */
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/* Inline math functions for SPARC.
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2004, 2006
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>.
|
||||
|
||||
@@ -36,23 +37,52 @@
|
||||
|
||||
# if __WORDSIZE == 32
|
||||
|
||||
# define __unordered_cmp(x, y) \
|
||||
# ifndef __NO_LONG_DOUBLE_MATH
|
||||
|
||||
# define __unordered_cmp(x, y) \
|
||||
(__extension__ \
|
||||
({ unsigned __r; \
|
||||
if (sizeof(x) == 4 && sizeof(y) == 4) \
|
||||
if (sizeof (x) == 4 && sizeof (y) == 4) \
|
||||
{ \
|
||||
float __x = (x); float __y = (y); \
|
||||
__asm__("fcmps %1,%2; st %%fsr, %0" : "=m" (__r) : "f" (__x), \
|
||||
"f" (__y) : "cc"); \
|
||||
__asm__ ("fcmps %1,%2; st %%fsr, %0" : "=m" (__r) : "f" (__x), \
|
||||
"f" (__y) : "cc"); \
|
||||
} \
|
||||
else if (sizeof (x) <= 8 && sizeof (y) <= 8) \
|
||||
{ \
|
||||
double __x = (x); double __y = (y); \
|
||||
__asm__ ("fcmpd\t%1,%2\n\tst\t%%fsr,%0" : "=m" (__r) : "f" (__x), \
|
||||
"f" (__y) : "cc"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
long double __x = (x); long double __y = (y); \
|
||||
extern int _Q_cmp (const long double a, const long double b); \
|
||||
__r = _Q_cmp (__x, __y) << 10; \
|
||||
} \
|
||||
__r; }))
|
||||
|
||||
# else
|
||||
|
||||
# define __unordered_cmp(x, y) \
|
||||
(__extension__ \
|
||||
({ unsigned __r; \
|
||||
if (sizeof (x) == 4 && sizeof (y) == 4) \
|
||||
{ \
|
||||
float __x = (x); float __y = (y); \
|
||||
__asm__ ("fcmps %1,%2; st %%fsr, %0" : "=m" (__r) : "f" (__x), \
|
||||
"f" (__y) : "cc"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
double __x = (x); double __y = (y); \
|
||||
__asm__("fcmpd\t%1,%2\n\tst\t%%fsr,%0" : "=m" (__r) : "f" (__x), \
|
||||
"f" (__y) : "cc"); \
|
||||
__asm__ ("fcmpd\t%1,%2\n\tst\t%%fsr,%0" : "=m" (__r) : "f" (__x), \
|
||||
"f" (__y) : "cc"); \
|
||||
} \
|
||||
__r; }))
|
||||
|
||||
# endif
|
||||
|
||||
# define isgreater(x, y) ((__unordered_cmp (x, y) & (3 << 10)) == (2 << 10))
|
||||
# define isgreaterequal(x, y) ((__unordered_cmp (x, y) & (1 << 10)) == 0)
|
||||
# define isless(x, y) ((__unordered_cmp (x, y) & (3 << 10)) == (1 << 10))
|
||||
@@ -65,22 +95,22 @@
|
||||
# define __unordered_v9cmp(x, y, op, qop) \
|
||||
(__extension__ \
|
||||
({ unsigned __r; \
|
||||
if (sizeof(x) == 4 && sizeof(y) == 4) \
|
||||
if (sizeof (x) == 4 && sizeof (y) == 4) \
|
||||
{ \
|
||||
float __x = (x); float __y = (y); \
|
||||
__asm__("fcmps\t%%fcc3,%1,%2\n\tmov" op "\t%%fcc3,1,%0" \
|
||||
: "=r" (__r) : "f" (__x), "f" (__y), "0" (0) : "cc"); \
|
||||
__asm__ ("fcmps\t%%fcc3,%1,%2\n\tmov" op "\t%%fcc3,1,%0" \
|
||||
: "=r" (__r) : "f" (__x), "f" (__y), "0" (0) : "cc"); \
|
||||
} \
|
||||
else if (sizeof(x) <= 8 && sizeof(y) <= 8) \
|
||||
else if (sizeof (x) <= 8 && sizeof (y) <= 8) \
|
||||
{ \
|
||||
double __x = (x); double __y = (y); \
|
||||
__asm__("fcmpd\t%%fcc3,%1,%2\n\tmov" op "\t%%fcc3,1,%0" \
|
||||
: "=r" (__r) : "f" (__x), "f" (__y), "0" (0) : "cc"); \
|
||||
__asm__ ("fcmpd\t%%fcc3,%1,%2\n\tmov" op "\t%%fcc3,1,%0" \
|
||||
: "=r" (__r) : "f" (__x), "f" (__y), "0" (0) : "cc"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
long double __x = (x); long double __y = (y); \
|
||||
extern int _Qp_cmp(const long double *a, const long double *b); \
|
||||
extern int _Qp_cmp (const long double *a, const long double *b); \
|
||||
__r = qop; \
|
||||
} \
|
||||
__r; }))
|
||||
@@ -127,11 +157,20 @@ __NTH (__signbit (double __x))
|
||||
return __u.__i[0] < 0;
|
||||
}
|
||||
|
||||
# ifndef __NO_LONG_DOUBLE_MATH
|
||||
__MATH_INLINE int
|
||||
__NTH (__signbitl (long double __x))
|
||||
{
|
||||
__extension__ union { long double __l; int __i[4]; } __u = { __l: __x };
|
||||
return __u.__i[0] < 0;
|
||||
}
|
||||
# else
|
||||
__MATH_INLINE int
|
||||
__NTH (__signbitl (long double __x))
|
||||
{
|
||||
return __signbit ((double)__x);
|
||||
}
|
||||
# endif
|
||||
|
||||
# else /* sparc64 */
|
||||
|
||||
@@ -180,6 +219,13 @@ __NTH (sqrtl (long double __x))
|
||||
_Qp_sqrt (&__r, &__x);
|
||||
return __r;
|
||||
}
|
||||
# elif !defined __NO_LONG_DOUBLE_MATH
|
||||
__MATH_INLINE long double
|
||||
sqrtl (long double __x) __THROW
|
||||
{
|
||||
extern long double _Q_sqrt (__const__ long double);
|
||||
return _Q_sqrt (__x);
|
||||
}
|
||||
# endif /* sparc64 */
|
||||
|
||||
# endif /* !__NO_MATH_INLINES && !GCC 3.2+ */
|
||||
@@ -211,6 +257,13 @@ __ieee754_sqrtl (long double __x)
|
||||
_Qp_sqrt(&__r, &__x);
|
||||
return __r;
|
||||
}
|
||||
# elif !defined __NO_LONG_DOUBLE_MATH
|
||||
__MATH_INLINE long double
|
||||
__ieee754_sqrtl (long double __x)
|
||||
{
|
||||
extern long double _Q_sqrt (__const__ long double);
|
||||
return _Q_sqrt (__x);
|
||||
}
|
||||
# endif /* sparc64 */
|
||||
# endif /* __LIBC_INTERNAL_MATH_INLINES */
|
||||
# endif /* gcc 2.8+ */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Store current floating-point environment and clear exceptions.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 2005 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
|
||||
@@ -33,3 +33,4 @@ feholdexcept (fenv_t *envp)
|
||||
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_def (feholdexcept)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Set current rounding direction.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 2005 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
|
||||
@@ -35,3 +35,4 @@ fesetround (int round)
|
||||
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_def (fesetround)
|
||||
|
@@ -25,12 +25,12 @@
|
||||
int
|
||||
__feraiseexcept (int excepts)
|
||||
{
|
||||
static volatile double sink;
|
||||
static const struct {
|
||||
double zero, one, max, min, sixteen, pi;
|
||||
} c = {
|
||||
0.0, 1.0, DBL_MAX, DBL_MIN, 16.0, M_PI
|
||||
};
|
||||
double d;
|
||||
|
||||
/* Raise exceptions represented by EXPECTS. But we must raise only
|
||||
one signal at a time. It is important the if the overflow/underflow
|
||||
@@ -39,24 +39,44 @@ __feraiseexcept (int excepts)
|
||||
|
||||
/* First: invalid exception. */
|
||||
if ((FE_INVALID & excepts) != 0)
|
||||
/* One example of a invalid operation is 0/0. */
|
||||
sink = c.zero / c.zero;
|
||||
{
|
||||
/* One example of a invalid operation is 0/0. */
|
||||
__asm ("" : "=e" (d) : "0" (c.zero));
|
||||
d /= c.zero;
|
||||
__asm __volatile ("" : : "e" (d));
|
||||
}
|
||||
|
||||
/* Next: division by zero. */
|
||||
if ((FE_DIVBYZERO & excepts) != 0)
|
||||
sink = c.one / c.zero;
|
||||
{
|
||||
__asm ("" : "=e" (d) : "0" (c.one));
|
||||
d /= c.zero;
|
||||
__asm __volatile ("" : : "e" (d));
|
||||
}
|
||||
|
||||
/* Next: overflow. */
|
||||
if ((FE_OVERFLOW & excepts) != 0)
|
||||
sink = c.max * c.max;
|
||||
{
|
||||
__asm ("" : "=e" (d) : "0" (c.max));
|
||||
d *= d;
|
||||
__asm __volatile ("" : : "e" (d));
|
||||
}
|
||||
|
||||
/* Next: underflow. */
|
||||
if ((FE_UNDERFLOW & excepts) != 0)
|
||||
sink = c.min / c.sixteen;
|
||||
{
|
||||
__asm ("" : "=e" (d) : "0" (c.min));
|
||||
d /= c.sixteen;
|
||||
__asm __volatile ("" : : "e" (d));
|
||||
}
|
||||
|
||||
/* Last: inexact. */
|
||||
if ((FE_INEXACT & excepts) != 0)
|
||||
sink = c.one / c.pi;
|
||||
{
|
||||
__asm ("" : "=e" (d) : "0" (c.one));
|
||||
d /= c.pi;
|
||||
__asm __volatile ("" : : "e" (d));
|
||||
}
|
||||
|
||||
/* Success. */
|
||||
return 0;
|
||||
|
@@ -1,9 +0,0 @@
|
||||
dotmul.S
|
||||
umul.S
|
||||
divrem.m4
|
||||
sdiv.S
|
||||
udiv.S
|
||||
rem.S
|
||||
urem.S
|
||||
alloca.S
|
||||
ieee754.h
|
@@ -1,5 +1,6 @@
|
||||
wordsize-32
|
||||
# SPARC uses IEEE 754 floating point.
|
||||
ieee754/flt-32
|
||||
ieee754/ldbl-128
|
||||
ieee754/dbl-64
|
||||
ieee754/flt-32
|
||||
sparc/sparc32/soft-fp
|
||||
|
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1991, 93, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1993, 1996, 1997, 1998, 1999, 2000, 2006
|
||||
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
|
||||
@@ -18,9 +19,7 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
#define _ASM 1
|
||||
#define _SETJMP_H
|
||||
#include <bits/setjmp.h>
|
||||
#include <jmpbuf-offsets.h>
|
||||
#define ENV(base,reg) [%base + (reg * 4)]
|
||||
#define ST_FLUSH_WINDOWS 3
|
||||
#define RW_FP [%fp + 0x48]
|
||||
@@ -30,6 +29,9 @@ ENTRY(__longjmp)
|
||||
use them while unwinding frames and their register windows. */
|
||||
|
||||
ld ENV(o0,JB_FP), %g3 /* Cache target FP in register %g3. */
|
||||
#ifdef PTR_DEMANGLE
|
||||
PTR_DEMANGLE (%g3, %g3, %g4)
|
||||
#endif
|
||||
mov %o0, %g1 /* ENV in %g1 */
|
||||
orcc %o1, %g0, %g2 /* VAL in %g2 */
|
||||
be,a 0f /* Branch if zero; else skip delay slot. */
|
||||
@@ -62,8 +64,15 @@ LOC(thread):
|
||||
* windows.
|
||||
*/
|
||||
ta ST_FLUSH_WINDOWS
|
||||
#ifdef PTR_DEMANGLE
|
||||
ld ENV(g1,JB_PC), %g5 /* Set return PC. */
|
||||
ld ENV(g1,JB_SP), %g1 /* Set saved SP on restore below. */
|
||||
PTR_DEMANGLE2 (%o7, %g5, %g4)
|
||||
PTR_DEMANGLE2 (%fp, %g1, %g4)
|
||||
#else
|
||||
ld ENV(g1,JB_PC), %o7 /* Set return PC. */
|
||||
ld ENV(g1,JB_SP), %fp /* Set saved SP on restore below. */
|
||||
#endif
|
||||
sub %fp, 64, %sp /* Allocate a register frame. */
|
||||
st %g3, RW_FP /* Set saved FP on restore below. */
|
||||
retl
|
||||
@@ -71,10 +80,17 @@ LOC(thread):
|
||||
|
||||
LOC(found):
|
||||
/* We have unwound register windows so %fp matches the target. */
|
||||
#ifdef PTR_DEMANGLE
|
||||
PTR_DEMANGLE2 (%sp, %o0, %g4)
|
||||
#else
|
||||
mov %o0, %sp /* OK, install new SP. */
|
||||
#endif
|
||||
|
||||
LOC(sp_ok):
|
||||
ld ENV(g1,JB_PC), %o0 /* Extract target return PC. */
|
||||
#ifdef PTR_DEMANGLE
|
||||
PTR_DEMANGLE2 (%o0, %o0, %g4)
|
||||
#endif
|
||||
jmp %o0 + 8 /* Return there. */
|
||||
mov %g2, %o0 /* Delay slot: set return value. */
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Atomic operations. sparc32 version.
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
|
||||
@@ -21,6 +21,34 @@
|
||||
#ifndef _BITS_ATOMIC_H
|
||||
#define _BITS_ATOMIC_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int8_t atomic8_t;
|
||||
typedef uint8_t uatomic8_t;
|
||||
typedef int_fast8_t atomic_fast8_t;
|
||||
typedef uint_fast8_t uatomic_fast8_t;
|
||||
|
||||
typedef int16_t atomic16_t;
|
||||
typedef uint16_t uatomic16_t;
|
||||
typedef int_fast16_t atomic_fast16_t;
|
||||
typedef uint_fast16_t uatomic_fast16_t;
|
||||
|
||||
typedef int32_t atomic32_t;
|
||||
typedef uint32_t uatomic32_t;
|
||||
typedef int_fast32_t atomic_fast32_t;
|
||||
typedef uint_fast32_t uatomic_fast32_t;
|
||||
|
||||
typedef int64_t atomic64_t;
|
||||
typedef uint64_t uatomic64_t;
|
||||
typedef int_fast64_t atomic_fast64_t;
|
||||
typedef uint_fast64_t uatomic_fast64_t;
|
||||
|
||||
typedef intptr_t atomicptr_t;
|
||||
typedef uintptr_t uatomicptr_t;
|
||||
typedef intmax_t atomic_max_t;
|
||||
typedef uintmax_t uatomic_max_t;
|
||||
|
||||
|
||||
/* We have no compare and swap, just test and set.
|
||||
The following implementation contends on 64 global locks
|
||||
per library and assumes no variable will be accessed using atomic.h
|
||||
@@ -41,22 +69,65 @@ volatile unsigned char __sparc32_atomic_locks[64]
|
||||
unsigned int __idx = (((long) addr >> 2) ^ ((long) addr >> 12)) \
|
||||
& 63; \
|
||||
do \
|
||||
__asm ("ldstub %1, %0" \
|
||||
: "=r" (__old_lock), \
|
||||
"=m" (__sparc32_atomic_locks[__idx]) \
|
||||
: "m" (__sparc32_atomic_locks[__idx])); \
|
||||
__asm __volatile ("ldstub %1, %0" \
|
||||
: "=r" (__old_lock), \
|
||||
"=m" (__sparc32_atomic_locks[__idx]) \
|
||||
: "m" (__sparc32_atomic_locks[__idx]) \
|
||||
: "memory"); \
|
||||
while (__old_lock); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define __sparc32_atomic_do_unlock(addr) \
|
||||
do \
|
||||
__sparc32_atomic_locks[(((long) addr >> 2) \
|
||||
^ ((long) addr >> 12)) & 63] = 0; \
|
||||
{ \
|
||||
__sparc32_atomic_locks[(((long) addr >> 2) \
|
||||
^ ((long) addr >> 12)) & 63] = 0; \
|
||||
__asm __volatile ("" ::: "memory"); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define __sparc32_atomic_do_lock24(addr) \
|
||||
do \
|
||||
{ \
|
||||
unsigned int __old_lock; \
|
||||
do \
|
||||
__asm __volatile ("ldstub %1, %0" \
|
||||
: "=r" (__old_lock), "=m" (*(addr)) \
|
||||
: "m" (*(addr)) \
|
||||
: "memory"); \
|
||||
while (__old_lock); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define __sparc32_atomic_do_unlock24(addr) \
|
||||
do \
|
||||
{ \
|
||||
*(char *) (addr) = 0; \
|
||||
__asm __volatile ("" ::: "memory"); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
#ifndef SHARED
|
||||
# define __v9_compare_and_exchange_val_32_acq(mem, newval, oldval) \
|
||||
({ \
|
||||
register __typeof (*(mem)) __acev_tmp __asm ("%g6"); \
|
||||
register __typeof (mem) __acev_mem __asm ("%g1") = (mem); \
|
||||
register __typeof (*(mem)) __acev_oldval __asm ("%g5"); \
|
||||
__acev_tmp = (newval); \
|
||||
__acev_oldval = (oldval); \
|
||||
/* .word 0xcde05005 is cas [%g1], %g5, %g6. Can't use cas here though, \
|
||||
because as will then mark the object file as V8+ arch. */ \
|
||||
__asm __volatile (".word 0xcde05005" \
|
||||
: "+r" (__acev_tmp), "=m" (*__acev_mem) \
|
||||
: "r" (__acev_oldval), "m" (*__acev_mem), \
|
||||
"r" (__acev_mem) : "memory"); \
|
||||
__acev_tmp; })
|
||||
#endif
|
||||
|
||||
/* The only basic operation needed is compare and exchange. */
|
||||
#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
|
||||
#define __v7_compare_and_exchange_val_acq(mem, newval, oldval) \
|
||||
({ __typeof (mem) __acev_memp = (mem); \
|
||||
__typeof (*mem) __acev_ret; \
|
||||
__typeof (*mem) __acev_newval = (newval); \
|
||||
@@ -68,7 +139,7 @@ volatile unsigned char __sparc32_atomic_locks[64]
|
||||
__sparc32_atomic_do_unlock (__acev_memp); \
|
||||
__acev_ret; })
|
||||
|
||||
#define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
|
||||
#define __v7_compare_and_exchange_bool_acq(mem, newval, oldval) \
|
||||
({ __typeof (mem) __aceb_memp = (mem); \
|
||||
int __aceb_ret; \
|
||||
__typeof (*mem) __aceb_newval = (newval); \
|
||||
@@ -82,4 +153,175 @@ volatile unsigned char __sparc32_atomic_locks[64]
|
||||
__sparc32_atomic_do_unlock (__aceb_memp); \
|
||||
__aceb_ret; })
|
||||
|
||||
#define __v7_exchange_acq(mem, newval) \
|
||||
({ __typeof (mem) __acev_memp = (mem); \
|
||||
__typeof (*mem) __acev_ret; \
|
||||
__typeof (*mem) __acev_newval = (newval); \
|
||||
\
|
||||
__sparc32_atomic_do_lock (__acev_memp); \
|
||||
__acev_ret = *__acev_memp; \
|
||||
*__acev_memp = __acev_newval; \
|
||||
__sparc32_atomic_do_unlock (__acev_memp); \
|
||||
__acev_ret; })
|
||||
|
||||
#define __v7_exchange_and_add(mem, value) \
|
||||
({ __typeof (mem) __acev_memp = (mem); \
|
||||
__typeof (*mem) __acev_ret; \
|
||||
\
|
||||
__sparc32_atomic_do_lock (__acev_memp); \
|
||||
__acev_ret = *__acev_memp; \
|
||||
*__acev_memp = __acev_ret + (value); \
|
||||
__sparc32_atomic_do_unlock (__acev_memp); \
|
||||
__acev_ret; })
|
||||
|
||||
/* Special versions, which guarantee that top 8 bits of all values
|
||||
are cleared and use those bits as the ldstub lock. */
|
||||
#define __v7_compare_and_exchange_val_24_acq(mem, newval, oldval) \
|
||||
({ __typeof (mem) __acev_memp = (mem); \
|
||||
__typeof (*mem) __acev_ret; \
|
||||
__typeof (*mem) __acev_newval = (newval); \
|
||||
\
|
||||
__sparc32_atomic_do_lock24 (__acev_memp); \
|
||||
__acev_ret = *__acev_memp & 0xffffff; \
|
||||
if (__acev_ret == (oldval)) \
|
||||
*__acev_memp = __acev_newval; \
|
||||
else \
|
||||
__sparc32_atomic_do_unlock24 (__acev_memp); \
|
||||
__asm __volatile ("" ::: "memory"); \
|
||||
__acev_ret; })
|
||||
|
||||
#define __v7_exchange_24_rel(mem, newval) \
|
||||
({ __typeof (mem) __acev_memp = (mem); \
|
||||
__typeof (*mem) __acev_ret; \
|
||||
__typeof (*mem) __acev_newval = (newval); \
|
||||
\
|
||||
__sparc32_atomic_do_lock24 (__acev_memp); \
|
||||
__acev_ret = *__acev_memp & 0xffffff; \
|
||||
*__acev_memp = __acev_newval; \
|
||||
__asm __volatile ("" ::: "memory"); \
|
||||
__acev_ret; })
|
||||
|
||||
#ifdef SHARED
|
||||
|
||||
/* When dynamically linked, we assume pre-v9 libraries are only ever
|
||||
used on pre-v9 CPU. */
|
||||
# define __atomic_is_v9 0
|
||||
|
||||
# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
|
||||
__v7_compare_and_exchange_val_acq (mem, newval, oldval)
|
||||
|
||||
# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
|
||||
__v7_compare_and_exchange_bool_acq (mem, newval, oldval)
|
||||
|
||||
# define atomic_exchange_acq(mem, newval) \
|
||||
__v7_exchange_acq (mem, newval)
|
||||
|
||||
# define atomic_exchange_and_add(mem, value) \
|
||||
__v7_exchange_and_add (mem, value)
|
||||
|
||||
# define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \
|
||||
({ \
|
||||
if (sizeof (*mem) != 4) \
|
||||
abort (); \
|
||||
__v7_compare_and_exchange_val_24_acq (mem, newval, oldval); })
|
||||
|
||||
# define atomic_exchange_24_rel(mem, newval) \
|
||||
({ \
|
||||
if (sizeof (*mem) != 4) \
|
||||
abort (); \
|
||||
__v7_exchange_24_rel (mem, newval); })
|
||||
|
||||
#else
|
||||
|
||||
/* In libc.a/libpthread.a etc. we don't know if we'll be run on
|
||||
pre-v9 or v9 CPU. To be interoperable with dynamically linked
|
||||
apps on v9 CPUs e.g. with process shared primitives, use cas insn
|
||||
on v9 CPUs and ldstub on pre-v9. */
|
||||
|
||||
/* Avoid <ldsodefs.h> include here. */
|
||||
extern uint64_t _dl_hwcap __attribute__((weak));
|
||||
# define __ATOMIC_HWCAP_SPARC_V9 16
|
||||
# define __atomic_is_v9 \
|
||||
(__builtin_expect (&_dl_hwcap != 0, 1) \
|
||||
&& __builtin_expect (_dl_hwcap & __ATOMIC_HWCAP_SPARC_V9, \
|
||||
__ATOMIC_HWCAP_SPARC_V9))
|
||||
|
||||
# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
|
||||
({ \
|
||||
__typeof (*mem) __acev_wret; \
|
||||
if (sizeof (*mem) != 4) \
|
||||
abort (); \
|
||||
if (__atomic_is_v9) \
|
||||
__acev_wret \
|
||||
= __v9_compare_and_exchange_val_32_acq (mem, newval, oldval);\
|
||||
else \
|
||||
__acev_wret \
|
||||
= __v7_compare_and_exchange_val_acq (mem, newval, oldval); \
|
||||
__acev_wret; })
|
||||
|
||||
# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
|
||||
({ \
|
||||
int __acev_wret; \
|
||||
if (sizeof (*mem) != 4) \
|
||||
abort (); \
|
||||
if (__atomic_is_v9) \
|
||||
{ \
|
||||
__typeof (oldval) __acev_woldval = (oldval); \
|
||||
__acev_wret \
|
||||
= __v9_compare_and_exchange_val_32_acq (mem, newval, \
|
||||
__acev_woldval) \
|
||||
!= __acev_woldval; \
|
||||
} \
|
||||
else \
|
||||
__acev_wret \
|
||||
= __v7_compare_and_exchange_bool_acq (mem, newval, oldval); \
|
||||
__acev_wret; })
|
||||
|
||||
# define atomic_exchange_rel(mem, newval) \
|
||||
({ \
|
||||
__typeof (*mem) __acev_wret; \
|
||||
if (sizeof (*mem) != 4) \
|
||||
abort (); \
|
||||
if (__atomic_is_v9) \
|
||||
{ \
|
||||
__typeof (mem) __acev_wmemp = (mem); \
|
||||
__typeof (*(mem)) __acev_wval = (newval); \
|
||||
do \
|
||||
__acev_wret = *__acev_wmemp; \
|
||||
while (__builtin_expect \
|
||||
(__v9_compare_and_exchange_val_32_acq (__acev_wmemp,\
|
||||
__acev_wval, \
|
||||
__acev_wret) \
|
||||
!= __acev_wret, 0)); \
|
||||
} \
|
||||
else \
|
||||
__acev_wret = __v7_exchange_acq (mem, newval); \
|
||||
__acev_wret; })
|
||||
|
||||
# define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \
|
||||
({ \
|
||||
__typeof (*mem) __acev_wret; \
|
||||
if (sizeof (*mem) != 4) \
|
||||
abort (); \
|
||||
if (__atomic_is_v9) \
|
||||
__acev_wret \
|
||||
= __v9_compare_and_exchange_val_32_acq (mem, newval, oldval);\
|
||||
else \
|
||||
__acev_wret \
|
||||
= __v7_compare_and_exchange_val_24_acq (mem, newval, oldval);\
|
||||
__acev_wret; })
|
||||
|
||||
# define atomic_exchange_24_rel(mem, newval) \
|
||||
({ \
|
||||
__typeof (*mem) __acev_w24ret; \
|
||||
if (sizeof (*mem) != 4) \
|
||||
abort (); \
|
||||
if (__atomic_is_v9) \
|
||||
__acev_w24ret = atomic_exchange_rel (mem, newval); \
|
||||
else \
|
||||
__acev_w24ret = __v7_exchange_24_rel (mem, newval); \
|
||||
__acev_w24ret; })
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* bits/atomic.h */
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1997, 1998, 2005, 2006 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
|
||||
@@ -22,17 +22,6 @@
|
||||
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
|
||||
#endif
|
||||
|
||||
#if defined __USE_MISC || defined _ASM
|
||||
# define JB_SP 0
|
||||
# define JB_FP 1
|
||||
# define JB_PC 2
|
||||
#endif
|
||||
|
||||
#ifndef _ASM
|
||||
typedef int __jmp_buf[3];
|
||||
#endif
|
||||
|
||||
/* Test if longjmp to JMPBUF would unwind the frame
|
||||
containing a local variable at ADDRESS. */
|
||||
#define _JMPBUF_UNWINDS(jmpbuf, address) \
|
||||
((int) (address) < (jmpbuf)[JB_SP])
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Machine-dependent ELF dynamic relocation inline functions. SPARC version.
|
||||
Copyright (C) 1996-2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2003, 2004, 2005, 2006 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
|
||||
@@ -40,13 +40,6 @@
|
||||
#define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
|
||||
#define OPCODE_BA 0x30800000 /* b,a ?; add PC-rel word address */
|
||||
|
||||
/* Use a different preload file when running in 32-bit emulation mode
|
||||
on a 64-bit host. */
|
||||
#define LD_SO_PRELOAD ((GLRO(dl_hwcap) & HWCAP_SPARC_V9) \
|
||||
? "/etc/ld.so.preload32" \
|
||||
: "/etc/ld.so.preload")
|
||||
|
||||
|
||||
/* Return nonzero iff ELF header is compatible with the running host. */
|
||||
static inline int
|
||||
elf_machine_matches_host (const Elf32_Ehdr *ehdr)
|
||||
@@ -131,30 +124,31 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
bits of %g1 with an offset into the .rela.plt section and jump to
|
||||
the beginning of the PLT. */
|
||||
plt = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
|
||||
if (! profile)
|
||||
rfunc = (Elf32_Addr) &_dl_runtime_resolve;
|
||||
else
|
||||
if (__builtin_expect(profile, 0))
|
||||
{
|
||||
rfunc = (Elf32_Addr) &_dl_runtime_profile;
|
||||
|
||||
if (_dl_name_match_p (GLRO(dl_profile), l))
|
||||
if (GLRO(dl_profile) != NULL
|
||||
&& _dl_name_match_p (GLRO(dl_profile), l))
|
||||
GL(dl_profile_map) = l;
|
||||
}
|
||||
else
|
||||
{
|
||||
rfunc = (Elf32_Addr) &_dl_runtime_resolve;
|
||||
}
|
||||
|
||||
/* The beginning of the PLT does:
|
||||
|
||||
save %sp, -64, %sp
|
||||
pltpc: call _dl_runtime_resolve
|
||||
nop
|
||||
sethi %hi(_dl_runtime_{resolve,profile}), %g2
|
||||
pltpc: jmpl %g2 + %lo(_dl_runtime_{resolve,profile}), %g2
|
||||
nop
|
||||
.word MAP
|
||||
|
||||
This saves the register window containing the arguments, and the
|
||||
PC value (pltpc) implicitly saved in %o7 by the call points near the
|
||||
The PC value (pltpc) saved in %g2 by the jmpl points near the
|
||||
location where we store the link_map pointer for this object. */
|
||||
|
||||
plt[0] = OPCODE_SAVE_SP;
|
||||
/* Construct PC-relative word address. */
|
||||
plt[1] = OPCODE_CALL | ((rfunc - (Elf32_Addr) &plt[1]) >> 2);
|
||||
plt[0] = 0x05000000 | ((rfunc >> 10) & 0x003fffff);
|
||||
plt[1] = 0x85c0a000 | (rfunc & 0x3ff);
|
||||
plt[2] = OPCODE_NOP; /* Fill call delay slot. */
|
||||
plt[3] = (Elf32_Addr) l;
|
||||
if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0)
|
||||
@@ -190,39 +184,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
return lazy;
|
||||
}
|
||||
|
||||
/* This code is used in dl-runtime.c to call the `fixup' function
|
||||
and then redirect to the address it returns. */
|
||||
#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \
|
||||
asm ( "\
|
||||
.text\n\
|
||||
.globl " #tramp_name "\n\
|
||||
.type " #tramp_name ", @function\n\
|
||||
.align 32\n\
|
||||
" #tramp_name ":\n\
|
||||
/* Set up the arguments to fixup --\n\
|
||||
%o0 = link_map out of plt0\n\
|
||||
%o1 = offset of reloc entry\n\
|
||||
%o2 = return address */\n\
|
||||
ld [%o7 + 8], %o0\n\
|
||||
srl %g1, 10, %o1\n\
|
||||
mov %i7, %o2\n\
|
||||
call " #fixup_name "\n\
|
||||
sub %o1, 4*12, %o1\n\
|
||||
jmp %o0\n\
|
||||
restore\n\
|
||||
.size " #tramp_name ", . - " #tramp_name "\n\
|
||||
.previous")
|
||||
|
||||
#ifndef PROF
|
||||
#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup);
|
||||
#else
|
||||
#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_profile, fixup);
|
||||
#endif
|
||||
|
||||
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
|
||||
PLT entries should not be allowed to define the value.
|
||||
ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
|
||||
@@ -406,18 +367,25 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
|
||||
|
||||
#endif /* dl_machine_h */
|
||||
|
||||
#ifdef RESOLVE
|
||||
#define ARCH_LA_PLTENTER sparc32_gnu_pltenter
|
||||
#define ARCH_LA_PLTEXIT sparc32_gnu_pltexit
|
||||
|
||||
#ifdef RESOLVE_MAP
|
||||
|
||||
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
|
||||
MAP is the object containing the reloc. */
|
||||
|
||||
static inline void
|
||||
auto inline void
|
||||
__attribute__ ((always_inline))
|
||||
elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
const Elf32_Sym *sym, const struct r_found_version *version,
|
||||
void *const reloc_addr_arg)
|
||||
{
|
||||
Elf32_Addr *const reloc_addr = reloc_addr_arg;
|
||||
const Elf32_Sym *const refsym = sym;
|
||||
Elf32_Addr value;
|
||||
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
|
||||
struct link_map *sym_map = NULL;
|
||||
|
||||
#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
|
||||
/* This is defined in rtld.c, but nowhere in the static libc.a; make the
|
||||
@@ -428,6 +396,9 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
weak_extern (_dl_rtld_map);
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (r_type == R_SPARC_NONE, 0))
|
||||
return;
|
||||
|
||||
#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
|
||||
if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0))
|
||||
{
|
||||
@@ -435,165 +406,148 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
if (map != &_dl_rtld_map) /* Already done in rtld itself. */
|
||||
# endif
|
||||
*reloc_addr += map->l_addr + reloc->r_addend;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef RESOLVE_CONFLICT_FIND_MAP
|
||||
if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0)
|
||||
&& sym->st_shndx != SHN_UNDEF)
|
||||
{
|
||||
value = map->l_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||
value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
|
||||
}
|
||||
#else
|
||||
value = 0;
|
||||
#endif
|
||||
|
||||
value += reloc->r_addend; /* Assume copy relocs have zero addend. */
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
const Elf32_Sym *const refsym = sym;
|
||||
# ifdef USE_TLS
|
||||
struct link_map *sym_map;
|
||||
# endif
|
||||
#endif
|
||||
Elf32_Addr value;
|
||||
#ifndef RESOLVE_CONFLICT_FIND_MAP
|
||||
if (sym->st_shndx != SHN_UNDEF &&
|
||||
ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
|
||||
case R_SPARC_COPY:
|
||||
if (sym == NULL)
|
||||
/* This can happen in trace mode if an object could not be
|
||||
found. */
|
||||
break;
|
||||
if (sym->st_size > refsym->st_size
|
||||
|| (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
|
||||
{
|
||||
value = map->l_addr;
|
||||
# if defined USE_TLS && !defined RTLD_BOOTSTRAP
|
||||
sym_map = map;
|
||||
# endif
|
||||
}
|
||||
else
|
||||
{
|
||||
# if defined USE_TLS && !defined RTLD_BOOTSTRAP
|
||||
sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||
value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
|
||||
# else
|
||||
value = RESOLVE (&sym, version, r_type);
|
||||
if (sym)
|
||||
value += sym->st_value;
|
||||
# endif
|
||||
}
|
||||
#else
|
||||
value = 0;
|
||||
#endif
|
||||
value += reloc->r_addend; /* Assume copy relocs have zero addend. */
|
||||
const char *strtab;
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
case R_SPARC_COPY:
|
||||
if (sym == NULL)
|
||||
/* This can happen in trace mode if an object could not be
|
||||
found. */
|
||||
break;
|
||||
if (sym->st_size > refsym->st_size
|
||||
|| (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
|
||||
{
|
||||
const char *strtab;
|
||||
|
||||
strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
_dl_error_printf ("\
|
||||
strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
_dl_error_printf ("\
|
||||
%s: Symbol `%s' has different size in shared object, consider re-linking\n",
|
||||
rtld_progname ?: "<program name unknown>",
|
||||
strtab + refsym->st_name);
|
||||
}
|
||||
memcpy (reloc_addr_arg, (void *) value,
|
||||
MIN (sym->st_size, refsym->st_size));
|
||||
break;
|
||||
rtld_progname ?: "<program name unknown>",
|
||||
strtab + refsym->st_name);
|
||||
}
|
||||
memcpy (reloc_addr_arg, (void *) value,
|
||||
MIN (sym->st_size, refsym->st_size));
|
||||
break;
|
||||
#endif
|
||||
case R_SPARC_GLOB_DAT:
|
||||
case R_SPARC_32:
|
||||
*reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_JMP_SLOT:
|
||||
/* At this point we don't need to bother with thread safety,
|
||||
so we can optimize the first instruction of .plt out. */
|
||||
sparc_fixup_plt (reloc, reloc_addr, value, 0);
|
||||
break;
|
||||
case R_SPARC_GLOB_DAT:
|
||||
case R_SPARC_32:
|
||||
*reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_JMP_SLOT:
|
||||
/* At this point we don't need to bother with thread safety,
|
||||
so we can optimize the first instruction of .plt out. */
|
||||
sparc_fixup_plt (reloc, reloc_addr, value, 0);
|
||||
break;
|
||||
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
|
||||
&& !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
case R_SPARC_TLS_DTPMOD32:
|
||||
/* Get the information from the link map returned by the
|
||||
resolv function. */
|
||||
if (sym_map != NULL)
|
||||
*reloc_addr = sym_map->l_tls_modid;
|
||||
break;
|
||||
case R_SPARC_TLS_DTPOFF32:
|
||||
/* During relocation all TLS symbols are defined and used.
|
||||
Therefore the offset is already correct. */
|
||||
*reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
|
||||
break;
|
||||
case R_SPARC_TLS_TPOFF32:
|
||||
/* The offset is negative, forward from the thread pointer. */
|
||||
/* We know the offset of object the symbol is contained in.
|
||||
It is a negative value which will be added to the
|
||||
thread pointer. */
|
||||
if (sym != NULL)
|
||||
{
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr = sym->st_value - sym_map->l_tls_offset
|
||||
+ reloc->r_addend;
|
||||
}
|
||||
break;
|
||||
case R_SPARC_TLS_DTPMOD32:
|
||||
/* Get the information from the link map returned by the
|
||||
resolv function. */
|
||||
if (sym_map != NULL)
|
||||
*reloc_addr = sym_map->l_tls_modid;
|
||||
break;
|
||||
case R_SPARC_TLS_DTPOFF32:
|
||||
/* During relocation all TLS symbols are defined and used.
|
||||
Therefore the offset is already correct. */
|
||||
*reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
|
||||
break;
|
||||
case R_SPARC_TLS_TPOFF32:
|
||||
/* The offset is negative, forward from the thread pointer. */
|
||||
/* We know the offset of object the symbol is contained in.
|
||||
It is a negative value which will be added to the
|
||||
thread pointer. */
|
||||
if (sym != NULL)
|
||||
{
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr = sym->st_value - sym_map->l_tls_offset
|
||||
+ reloc->r_addend;
|
||||
}
|
||||
break;
|
||||
# ifndef RTLD_BOOTSTRAP
|
||||
case R_SPARC_TLS_LE_HIX22:
|
||||
case R_SPARC_TLS_LE_LOX10:
|
||||
if (sym != NULL)
|
||||
{
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
value = sym->st_value - sym_map->l_tls_offset
|
||||
+ reloc->r_addend;
|
||||
if (r_type == R_SPARC_TLS_LE_HIX22)
|
||||
*reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10);
|
||||
else
|
||||
*reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff)
|
||||
| 0x1c00;
|
||||
}
|
||||
break;
|
||||
case R_SPARC_TLS_LE_HIX22:
|
||||
case R_SPARC_TLS_LE_LOX10:
|
||||
if (sym != NULL)
|
||||
{
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
value = sym->st_value - sym_map->l_tls_offset
|
||||
+ reloc->r_addend;
|
||||
if (r_type == R_SPARC_TLS_LE_HIX22)
|
||||
*reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10);
|
||||
else
|
||||
*reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff)
|
||||
| 0x1c00;
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
#endif
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
case R_SPARC_8:
|
||||
*(char *) reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_16:
|
||||
*(short *) reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_DISP8:
|
||||
*(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_DISP16:
|
||||
*(short *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_DISP32:
|
||||
*reloc_addr = (value - (Elf32_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_LO10:
|
||||
*reloc_addr = (*reloc_addr & ~0x3ff) | (value & 0x3ff);
|
||||
break;
|
||||
case R_SPARC_WDISP30:
|
||||
*reloc_addr = ((*reloc_addr & 0xc0000000)
|
||||
| ((value - (unsigned int) reloc_addr) >> 2));
|
||||
break;
|
||||
case R_SPARC_HI22:
|
||||
*reloc_addr = (*reloc_addr & 0xffc00000) | (value >> 10);
|
||||
break;
|
||||
case R_SPARC_UA16:
|
||||
((unsigned char *) reloc_addr_arg) [0] = value >> 8;
|
||||
((unsigned char *) reloc_addr_arg) [1] = value;
|
||||
break;
|
||||
case R_SPARC_UA32:
|
||||
((unsigned char *) reloc_addr_arg) [0] = value >> 24;
|
||||
((unsigned char *) reloc_addr_arg) [1] = value >> 16;
|
||||
((unsigned char *) reloc_addr_arg) [2] = value >> 8;
|
||||
((unsigned char *) reloc_addr_arg) [3] = value;
|
||||
break;
|
||||
case R_SPARC_8:
|
||||
*(char *) reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_16:
|
||||
*(short *) reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_DISP8:
|
||||
*(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_DISP16:
|
||||
*(short *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_DISP32:
|
||||
*reloc_addr = (value - (Elf32_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_LO10:
|
||||
*reloc_addr = (*reloc_addr & ~0x3ff) | (value & 0x3ff);
|
||||
break;
|
||||
case R_SPARC_WDISP30:
|
||||
*reloc_addr = ((*reloc_addr & 0xc0000000)
|
||||
| ((value - (unsigned int) reloc_addr) >> 2));
|
||||
break;
|
||||
case R_SPARC_HI22:
|
||||
*reloc_addr = (*reloc_addr & 0xffc00000) | (value >> 10);
|
||||
break;
|
||||
case R_SPARC_UA16:
|
||||
((unsigned char *) reloc_addr_arg) [0] = value >> 8;
|
||||
((unsigned char *) reloc_addr_arg) [1] = value;
|
||||
break;
|
||||
case R_SPARC_UA32:
|
||||
((unsigned char *) reloc_addr_arg) [0] = value >> 24;
|
||||
((unsigned char *) reloc_addr_arg) [1] = value >> 16;
|
||||
((unsigned char *) reloc_addr_arg) [2] = value >> 8;
|
||||
((unsigned char *) reloc_addr_arg) [3] = value;
|
||||
break;
|
||||
#endif
|
||||
case R_SPARC_NONE: /* Alright, Wilbur. */
|
||||
break;
|
||||
#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
|
||||
default:
|
||||
_dl_reloc_bad_type (map, r_type, 0);
|
||||
break;
|
||||
default:
|
||||
_dl_reloc_bad_type (map, r_type, 0);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
auto inline void
|
||||
__attribute__ ((always_inline))
|
||||
elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
|
||||
void *const reloc_addr_arg)
|
||||
{
|
||||
@@ -601,7 +555,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
|
||||
*reloc_addr += l_addr + reloc->r_addend;
|
||||
}
|
||||
|
||||
static inline void
|
||||
auto inline void
|
||||
__attribute__ ((always_inline))
|
||||
elf_machine_lazy_rel (struct link_map *map,
|
||||
Elf32_Addr l_addr, const Elf32_Rela *reloc)
|
||||
{
|
||||
@@ -617,4 +572,4 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RESOLVE */
|
||||
#endif /* RESOLVE_MAP */
|
||||
|
184
sysdeps/sparc/sparc32/dl-trampoline.S
Normal file
184
sysdeps/sparc/sparc32/dl-trampoline.S
Normal file
@@ -0,0 +1,184 @@
|
||||
/* PLT trampolines. Sparc 32-bit version.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
.text
|
||||
.align 32
|
||||
|
||||
/* %g1: PLT offset loaded by PLT entry
|
||||
* %g2: callers PC, which is PLT0 + 4, and we store the
|
||||
* link map at PLT0 + 12, therefore we add 8 to get
|
||||
* the address of the link map
|
||||
*/
|
||||
.globl _dl_runtime_resolve
|
||||
.type _dl_runtime_resolve, @function
|
||||
_dl_runtime_resolve:
|
||||
cfi_startproc
|
||||
|
||||
save %sp, -104, %sp
|
||||
cfi_def_cfa_register(%fp)
|
||||
cfi_window_save
|
||||
cfi_register (%o7, %i7)
|
||||
|
||||
ld [%g2 + 8], %o0
|
||||
srl %g1, 10, %o1
|
||||
call _dl_fixup
|
||||
sub %o1, 4*12, %o1
|
||||
jmp %o0
|
||||
restore
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _dl_runtime_resolve, .-_dl_runtime_resolve
|
||||
|
||||
/* For the profiling cases we pass in our stack frame
|
||||
* as the base of the La_sparc64_regs, so it looks
|
||||
* like:
|
||||
* %l0 %sp
|
||||
* ...
|
||||
* %l7 %sp + (7 * 8)
|
||||
* %i0 %sp + (8 * 8)
|
||||
* ...
|
||||
* %i7 %sp + (15 * 8)
|
||||
* %f0 %sp + (16 * 8)
|
||||
* %f16 %sp + (31 * 8)
|
||||
* framesize %sp + (32 * 8)
|
||||
*/
|
||||
|
||||
.globl _dl_profile_save_regs
|
||||
.type _dl_profile_save_regs, @function
|
||||
_dl_profile_save_regs:
|
||||
cfi_startproc
|
||||
|
||||
std %l0, [%sp + ( 0 * 8)]
|
||||
std %l2, [%sp + ( 1 * 8)]
|
||||
std %l4, [%sp + ( 2 * 8)]
|
||||
std %l6, [%sp + ( 3 * 8)]
|
||||
std %i0, [%sp + ( 4 * 8)]
|
||||
std %i2, [%sp + ( 5 * 8)]
|
||||
std %i4, [%sp + ( 6 * 8)]
|
||||
std %i6, [%sp + ( 7 * 8)]
|
||||
ld [%sp + (8 * 8)], %l4
|
||||
retl
|
||||
st %l4, [%sp + (8 * 8)]
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _dl_profile_save_regs, .-_dl_profile_save_regs
|
||||
|
||||
/* If we are going to call pltexit, then we must replicate
|
||||
* the caller's stack frame.
|
||||
* %o0: PLT resolved function address
|
||||
*/
|
||||
.globl _dl_profile_invoke
|
||||
.type _dl_profile_invoke, @function
|
||||
_dl_profile_invoke:
|
||||
cfi_startproc
|
||||
|
||||
sub %sp, %l0, %sp
|
||||
1:
|
||||
srl %l0, 3, %l7
|
||||
mov %o0, %l1
|
||||
mov %i0, %o0
|
||||
mov %i1, %o1
|
||||
mov %i2, %o2
|
||||
mov %i3, %o3
|
||||
mov %i4, %o4
|
||||
mov %i5, %o5
|
||||
mov %fp, %l2
|
||||
mov %sp, %l3
|
||||
1: ldd [%l2], %g2
|
||||
add %l2, 0x8, %l2
|
||||
subcc %l7, 1, %l7
|
||||
std %g2, [%l3]
|
||||
bne 1b
|
||||
add %l3, 0x8, %l3
|
||||
|
||||
jmpl %l1, %o7
|
||||
nop
|
||||
|
||||
std %o0, [%sp + ( 9 * 8)]
|
||||
std %f0, [%sp + (10 * 8)]
|
||||
|
||||
mov %l5, %o0
|
||||
mov %l6, %o1
|
||||
add %sp, %l0, %o2
|
||||
call _dl_call_pltexit
|
||||
add %sp, (16 * 8), %o3
|
||||
|
||||
ldd [%sp + (9 * 8)], %i0
|
||||
|
||||
jmpl %i7 + 8, %g0
|
||||
restore
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _dl_profile_invoke, .-_dl_profile_invoke
|
||||
|
||||
/* %g1: PLT offset loaded by PLT entry
|
||||
* %g2: callers PC, which is PLT0 + 4, and we store the
|
||||
* link map at PLT0 + 12, therefore we add 8 to get
|
||||
* the address of the link map
|
||||
*/
|
||||
.align 32
|
||||
.globl _dl_runtime_profile
|
||||
.type _dl_runtime_profile, @function
|
||||
_dl_runtime_profile:
|
||||
cfi_startproc
|
||||
|
||||
cmp %fp, 0
|
||||
be,a 1f
|
||||
mov 104, %g3
|
||||
sub %fp, %sp, %g3
|
||||
1: save %sp, -104, %sp
|
||||
cfi_def_cfa_register(%fp)
|
||||
cfi_window_save
|
||||
cfi_register(%o7, %i7)
|
||||
|
||||
ld [%g2 + 8], %o0
|
||||
srl %g1, 10, %o1
|
||||
mov %i7, %o2
|
||||
sub %o1, 4*12, %o1
|
||||
|
||||
mov %g3, %l0
|
||||
mov %o0, %l5
|
||||
mov %o1, %l6
|
||||
|
||||
call _dl_profile_save_regs
|
||||
nop
|
||||
|
||||
mov %sp, %o3
|
||||
call _dl_profile_fixup
|
||||
add %sp, (9 * 8), %o4
|
||||
|
||||
ld [%sp + (9 * 8)], %o1
|
||||
cmp %o1, 0
|
||||
bgeu 1f
|
||||
nop
|
||||
|
||||
call _dl_profile_invoke
|
||||
nop
|
||||
|
||||
1: jmp %o0
|
||||
restore
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _dl_runtime_profile, .-_dl_runtime_profile
|
@@ -48,6 +48,7 @@
|
||||
.global _start
|
||||
.type _start,#function
|
||||
_start:
|
||||
cfi_startproc
|
||||
|
||||
#ifdef SHARED
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7
|
||||
@@ -59,6 +60,7 @@ _start:
|
||||
drop their arguments. */
|
||||
mov %g0, %fp
|
||||
sub %sp, 6*4, %sp
|
||||
cfi_adjust_cfa_offset(6*4)
|
||||
|
||||
/* Extract the arguments and environment as encoded on the stack. The
|
||||
argument info starts after one register window (16 words) past the SP. */
|
||||
@@ -91,4 +93,12 @@ _start:
|
||||
/* Die very horribly if exit returns. */
|
||||
unimp
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _start, .-_start
|
||||
|
||||
/* Define a symbol for the first piece of initialized data. */
|
||||
.data
|
||||
.globl __data_start
|
||||
__data_start:
|
||||
weak_alias (__data_start, data_start)
|
||||
|
1
sysdeps/sparc/sparc32/fpu/e_sqrtl.c
Normal file
1
sysdeps/sparc/sparc32/fpu/e_sqrtl.c
Normal file
@@ -0,0 +1 @@
|
||||
/* __ieee754_sqrtl is defined in q_sqrt.c. */
|
File diff suppressed because it is too large
Load Diff
11
sysdeps/sparc/sparc32/fpu/s_fabs.c
Normal file
11
sysdeps/sparc/sparc32/fpu/s_fabs.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <math.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
|
||||
double __fabs (double x)
|
||||
{
|
||||
return __builtin_fabs (x);
|
||||
}
|
||||
weak_alias (__fabs, fabs)
|
||||
#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
|
||||
compat_symbol (libm, __fabs, fabsl, GLIBC_2_0);
|
||||
#endif
|
29
sysdeps/sparc/sparc32/fpu/s_fabsf.S
Normal file
29
sysdeps/sparc/sparc32/fpu/s_fabsf.S
Normal file
@@ -0,0 +1,29 @@
|
||||
/* Float absolute value, sparc32 version.
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
ENTRY (__fabsf)
|
||||
st %o0, [%sp+64]
|
||||
ld [%sp+64], %f0
|
||||
retl
|
||||
fabss %f0, %f0
|
||||
END (__fabsf)
|
||||
weak_alias (__fabsf, fabsf)
|
8
sysdeps/sparc/sparc32/fpu/s_fabsl.c
Normal file
8
sysdeps/sparc/sparc32/fpu/s_fabsl.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <math.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
|
||||
long double __fabsl (long double x)
|
||||
{
|
||||
return __builtin_fabsl (x);
|
||||
}
|
||||
long_double_symbol (libm, __fabsl, fabsl);
|
22
sysdeps/sparc/sparc32/jmpbuf-offsets.h
Normal file
22
sysdeps/sparc/sparc32/jmpbuf-offsets.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* Private macros for accessing __jmp_buf contents. SPARC version.
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define JB_SP 0
|
||||
#define JB_FP 1
|
||||
#define JB_PC 2
|
48
sysdeps/sparc/sparc32/jmpbuf-unwind.h
Normal file
48
sysdeps/sparc/sparc32/jmpbuf-unwind.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <jmpbuf-offsets.h>
|
||||
#include <stdint.h>
|
||||
#include <unwind.h>
|
||||
#include <sysdep.h>
|
||||
|
||||
/* Test if longjmp to JMPBUF would unwind the frame
|
||||
containing a local variable at ADDRESS. */
|
||||
#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
|
||||
((int) (address) < demangle ((jmpbuf)[JB_SP]))
|
||||
|
||||
#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
|
||||
_JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
|
||||
|
||||
static inline uintptr_t __attribute__ ((unused))
|
||||
_jmpbuf_sp (__jmp_buf regs)
|
||||
{
|
||||
uintptr_t sp = regs[JB_SP];
|
||||
#ifdef PTR_DEMANGLE
|
||||
PTR_DEMANGLE (sp);
|
||||
#endif
|
||||
return sp;
|
||||
}
|
||||
|
||||
#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
|
||||
((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
|
||||
|
||||
/* We use the normal lobngjmp for unwinding. */
|
||||
#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
|
@@ -32,7 +32,15 @@
|
||||
|
||||
.text
|
||||
.align 4
|
||||
0: cmp %o2, 0
|
||||
ENTRY(__memchr)
|
||||
andcc %o1, 0xff, %o1
|
||||
sll %o1, 8, %g6
|
||||
andcc %o0, 3, %g0
|
||||
or %o1, %g6, %g6
|
||||
sll %g6, 16, %o3
|
||||
be 10f
|
||||
or %o3, %g6, %g2
|
||||
cmp %o2, 0
|
||||
be 9f
|
||||
sethi %hi(0x80808080), %o4
|
||||
ldub [%o0], %g4
|
||||
@@ -64,16 +72,7 @@
|
||||
clr %o0
|
||||
1: retl
|
||||
sub %o0, 1, %o0
|
||||
|
||||
ENTRY(__memchr)
|
||||
andcc %o1, 0xff, %o1
|
||||
sll %o1, 8, %g6
|
||||
andcc %o0, 3, %g0
|
||||
or %o1, %g6, %g6
|
||||
sll %g6, 16, %o3
|
||||
bne 0b
|
||||
or %o3, %g6, %g2
|
||||
sethi %hi(0x80808080), %o4
|
||||
10: sethi %hi(0x80808080), %o4
|
||||
or %o4, %lo(0x80808080), %o3
|
||||
4: sethi %hi(0x01010101), %o5
|
||||
5: and %o2, 3, %g1
|
||||
|
@@ -146,28 +146,12 @@
|
||||
.text
|
||||
.align 4
|
||||
|
||||
70: andcc %o1, 1, %g0
|
||||
be 4f
|
||||
andcc %o1, 2, %g0
|
||||
|
||||
ldub [%o1 - 1], %g2
|
||||
sub %o1, 1, %o1
|
||||
stb %g2, [%o0 - 1]
|
||||
sub %o2, 1, %o2
|
||||
be 3f
|
||||
sub %o0, 1, %o0
|
||||
4: lduh [%o1 - 2], %g2
|
||||
sub %o1, 2, %o1
|
||||
sth %g2, [%o0 - 2]
|
||||
sub %o2, 2, %o2
|
||||
b 3f
|
||||
sub %o0, 2, %o0
|
||||
|
||||
ENTRY(bcopy)
|
||||
mov %o0, %o3
|
||||
mov %o1, %o0
|
||||
mov %o3, %o1
|
||||
END(bcopy)
|
||||
|
||||
ENTRY(memmove)
|
||||
cmp %o0, %o1
|
||||
st %o0, [%sp + 64]
|
||||
@@ -185,8 +169,26 @@ ENTRY(memmove)
|
||||
cmp %o2, 15
|
||||
bleu 91f
|
||||
andcc %o1, 3, %g0
|
||||
bne 70b
|
||||
3: andcc %o1, 4, %g0
|
||||
be 3f
|
||||
nop
|
||||
|
||||
andcc %o1, 1, %g0
|
||||
be 4f
|
||||
andcc %o1, 2, %g0
|
||||
|
||||
ldub [%o1 - 1], %g2
|
||||
sub %o1, 1, %o1
|
||||
stb %g2, [%o0 - 1]
|
||||
sub %o2, 1, %o2
|
||||
be 3f
|
||||
sub %o0, 1, %o0
|
||||
4: lduh [%o1 - 2], %g2
|
||||
sub %o1, 2, %o1
|
||||
sth %g2, [%o0 - 2]
|
||||
sub %o2, 2, %o2
|
||||
sub %o0, 2, %o0
|
||||
|
||||
3: andcc %o1, 4, %g0
|
||||
|
||||
be 2f
|
||||
mov %o2, %g1
|
||||
|
@@ -152,4 +152,4 @@ ENTRY(memset)
|
||||
END(memset)
|
||||
libc_hidden_builtin_def (memset)
|
||||
|
||||
weak_alias(__bzero, bzero)
|
||||
weak_alias (__bzero, bzero)
|
||||
|
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1991, 93, 94, 96, 97, 98, 2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1993, 1994, 1996, 1997, 1998, 2002, 2006
|
||||
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
|
||||
@@ -19,9 +20,7 @@
|
||||
#include <sysdep.h>
|
||||
#include <sys/trap.h>
|
||||
|
||||
#define _ASM 1
|
||||
#define _SETJMP_H
|
||||
#include <bits/setjmp.h>
|
||||
#include <jmpbuf-offsets.h>
|
||||
|
||||
ENTRY(_setjmp)
|
||||
b 1f
|
||||
@@ -39,9 +38,18 @@ ENTRY (__sigsetjmp)
|
||||
a tail-call for simplicity; it always returns zero. */
|
||||
ta ST_FLUSH_WINDOWS
|
||||
|
||||
#ifdef PTR_MANGLE
|
||||
PTR_MANGLE (%g1, %o7, %g4)
|
||||
PTR_MANGLE2 (%g2, %sp, %g4)
|
||||
PTR_MANGLE2 (%g3, %fp, %g4)
|
||||
st %g1, [%o0 + (JB_PC * 4)]
|
||||
st %g2, [%o0 + (JB_SP * 4)]
|
||||
st %g3, [%o0 + (JB_FP * 4)]
|
||||
#else
|
||||
st %o7, [%o0 + (JB_PC * 4)]
|
||||
st %sp, [%o0 + (JB_SP * 4)]
|
||||
st %fp, [%o0 + (JB_FP * 4)]
|
||||
#endif
|
||||
|
||||
mov %o7, %g1
|
||||
call __sigjmp_save
|
||||
|
@@ -1,28 +0,0 @@
|
||||
q_add.c
|
||||
q_cmp.c
|
||||
q_cmpe.c
|
||||
q_div.c
|
||||
q_dtoq.c
|
||||
q_feq.c
|
||||
q_fge.c
|
||||
q_fgt.c
|
||||
q_fle.c
|
||||
q_flt.c
|
||||
q_fne.c
|
||||
q_itoq.c
|
||||
q_mul.c
|
||||
q_neg.c
|
||||
q_qtod.c
|
||||
q_qtoi.c
|
||||
q_qtos.c
|
||||
q_qtoui.c
|
||||
q_qtoux.c
|
||||
q_qtox.c
|
||||
q_sqrt.c
|
||||
q_stoq.c
|
||||
q_sub.c
|
||||
q_uitoq.c
|
||||
q_util.c
|
||||
q_uxtoq.c
|
||||
q_xtoq.c
|
||||
sfp-machine.h
|
@@ -1,6 +1,6 @@
|
||||
# Software floating-point emulation.
|
||||
# Makefile for SPARC v8 long double utility functions (_Q_*).
|
||||
# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999, 2000, 2006 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
# Contributed by Jakub Jelinek (jj@ultra.linux.cz).
|
||||
#
|
||||
@@ -20,13 +20,11 @@
|
||||
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
# 02111-1307 USA.
|
||||
|
||||
# Currently gcc does not support TFmode long double on sparc32
|
||||
# so these routines are not used.
|
||||
#ifeq ($(subdir),soft-fp)
|
||||
#sparc32-quad-routines := q_add q_cmp q_cmpe q_div q_dtoq q_feq q_fge \
|
||||
# q_fgt q_fle q_flt q_fne q_itoq q_mul q_neg q_qtod q_qtoi \
|
||||
# q_qtos q_qtoui q_qtoux q_qtox q_sqrt q_stoq q_sub q_uitoq \
|
||||
# q_uxtoq q_xtoq q_util
|
||||
#sysdep_routines += $(sparc32-quad-routines)
|
||||
#
|
||||
#endif
|
||||
ifeq ($(subdir),soft-fp)
|
||||
sparc32-quad-routines := q_add q_cmp q_cmpe q_div q_dtoq q_feq q_fge \
|
||||
q_fgt q_fle q_flt q_fne q_itoq q_mul q_neg q_qtod q_qtoi \
|
||||
q_qtos q_qtou q_qtoull q_qtoll q_sqrt q_stoq q_sub q_utoq \
|
||||
q_ulltoq q_lltoq q_util
|
||||
sysdep_routines += $(sparc32-quad-routines)
|
||||
|
||||
endif
|
||||
|
8
sysdeps/sparc/sparc32/soft-fp/Versions
Normal file
8
sysdeps/sparc/sparc32/soft-fp/Versions
Normal file
@@ -0,0 +1,8 @@
|
||||
libc {
|
||||
GLIBC_2.4 {
|
||||
_Q_add; _Q_cmp; _Q_cmpe; _Q_div; _Q_dtoq; _Q_feq; _Q_fge; _Q_fgt;
|
||||
_Q_fle; _Q_flt; _Q_fne; _Q_itoq; _Q_mul; _Q_neg; _Q_qtod; _Q_qtoi;
|
||||
_Q_qtos; _Q_qtou; _Q_qtoull; _Q_qtoll; _Q_sqrt; _Q_stoq; _Q_sub;
|
||||
_Q_utoq; _Q_ulltoq; _Q_lltoq;
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return a + b
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -30,10 +30,10 @@ long double _Q_add(const long double a, const long double b)
|
||||
long double c;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_Q(A, a);
|
||||
FP_UNPACK_Q(B, b);
|
||||
FP_UNPACK_SEMIRAW_Q(A, a);
|
||||
FP_UNPACK_SEMIRAW_Q(B, b);
|
||||
FP_ADD_Q(C, A, B);
|
||||
FP_PACK_Q(c, C);
|
||||
FP_PACK_SEMIRAW_Q(c, C);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return c;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return a / b
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -35,5 +35,5 @@ long double _Q_div(const long double a, const long double b)
|
||||
FP_DIV_Q(C, A, B);
|
||||
FP_PACK_Q(c, C);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return long double;
|
||||
return c;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (long double)(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -32,13 +32,13 @@ long double _Q_dtoq(const double a)
|
||||
long double c;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_D(A, a);
|
||||
FP_UNPACK_RAW_D(A, a);
|
||||
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
|
||||
FP_CONV(Q,D,4,2,C,A);
|
||||
FP_EXTEND(Q,D,4,2,C,A);
|
||||
#else
|
||||
FP_CONV(Q,D,2,1,C,A);
|
||||
FP_EXTEND(Q,D,2,1,C,A);
|
||||
#endif
|
||||
FP_PACK_Q(c, C);
|
||||
FP_PACK_RAW_Q(c, C);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return c;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (long double)(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -30,8 +30,8 @@ long double _Q_itoq(const int a)
|
||||
int b = a;
|
||||
long double c;
|
||||
|
||||
FP_FROM_INT_Q(C, b, 32, int);
|
||||
FP_PACK_Q(c, C);
|
||||
FP_FROM_INT_Q(C, b, 32, unsigned int);
|
||||
FP_PACK_RAW_Q(c, C);
|
||||
FP_CLEAR_EXCEPTIONS;
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return c;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (long double)a
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -23,15 +23,15 @@
|
||||
#include "soft-fp.h"
|
||||
#include "quad.h"
|
||||
|
||||
long double _Q_xtoq(const long long a)
|
||||
long double _Q_lltoq(const long long a)
|
||||
{
|
||||
FP_DECL_EX;
|
||||
FP_DECL_Q(C);
|
||||
long double c;
|
||||
long long b = a;
|
||||
|
||||
FP_FROM_INT_Q(C, b, 64, long long);
|
||||
FP_PACK_Q(c, C);
|
||||
FP_FROM_INT_Q(C, b, 64, unsigned long long);
|
||||
FP_PACK_RAW_Q(c, C);
|
||||
FP_CLEAR_EXCEPTIONS;
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return c;
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (double)a
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -32,13 +32,13 @@ double _Q_qtod(const long double a)
|
||||
double r;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_Q(A, a);
|
||||
FP_UNPACK_SEMIRAW_Q(A, a);
|
||||
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
|
||||
FP_CONV(D,Q,2,4,R,A);
|
||||
FP_TRUNC(D,Q,2,4,R,A);
|
||||
#else
|
||||
FP_CONV(D,Q,1,2,R,A);
|
||||
FP_TRUNC(D,Q,1,2,R,A);
|
||||
#endif
|
||||
FP_PACK_D(r, R);
|
||||
FP_PACK_SEMIRAW_D(r, R);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (int)a
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -28,9 +28,9 @@ int _Q_qtoi(const long double a)
|
||||
{
|
||||
FP_DECL_EX;
|
||||
FP_DECL_Q(A);
|
||||
int r;
|
||||
unsigned int r;
|
||||
|
||||
FP_UNPACK_Q(A, a);
|
||||
FP_UNPACK_RAW_Q(A, a);
|
||||
FP_TO_INT_Q(r, A, 32, 1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (long)a
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Return (long long)a
|
||||
Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -24,13 +24,13 @@
|
||||
#include "soft-fp.h"
|
||||
#include "quad.h"
|
||||
|
||||
long long _Q_qtox(const long double a)
|
||||
long long _Q_qtoll(const long double a)
|
||||
{
|
||||
FP_DECL_EX;
|
||||
FP_DECL_Q(A);
|
||||
long long r;
|
||||
unsigned long long r;
|
||||
|
||||
FP_UNPACK_Q(A, a);
|
||||
FP_UNPACK_RAW_Q(A, a);
|
||||
FP_TO_INT_Q(r, A, 64, 1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (float)a
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -32,13 +32,13 @@ float _Q_qtos(const long double a)
|
||||
float r;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_Q(A, a);
|
||||
FP_UNPACK_SEMIRAW_Q(A, a);
|
||||
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
|
||||
FP_CONV(S,Q,1,4,R,A);
|
||||
FP_TRUNC(S,Q,1,4,R,A);
|
||||
#else
|
||||
FP_CONV(S,Q,1,2,R,A);
|
||||
FP_TRUNC(S,Q,1,2,R,A);
|
||||
#endif
|
||||
FP_PACK_S(r, R);
|
||||
FP_PACK_SEMIRAW_S(r, R);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (unsigned int)a
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -24,13 +24,13 @@
|
||||
#include "soft-fp.h"
|
||||
#include "quad.h"
|
||||
|
||||
unsigned int _Q_qtoui(const long double a)
|
||||
unsigned int _Q_qtou(const long double a)
|
||||
{
|
||||
FP_DECL_EX;
|
||||
FP_DECL_Q(A);
|
||||
unsigned int r;
|
||||
|
||||
FP_UNPACK_Q(A, a);
|
||||
FP_UNPACK_RAW_Q(A, a);
|
||||
FP_TO_INT_Q(r, A, 32, -1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (unsigned long)a
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Return (unsigned long long)a
|
||||
Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -24,13 +24,13 @@
|
||||
#include "soft-fp.h"
|
||||
#include "quad.h"
|
||||
|
||||
unsigned long long _Q_qtoux(const long double a)
|
||||
unsigned long long _Q_qtoull(const long double a)
|
||||
{
|
||||
FP_DECL_EX;
|
||||
FP_DECL_Q(A);
|
||||
unsigned long long r;
|
||||
|
||||
FP_UNPACK_Q(A, a);
|
||||
FP_UNPACK_RAW_Q(A, a);
|
||||
FP_TO_INT_Q(r, A, 64, -1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return sqrtl(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -36,3 +36,4 @@ long double _Q_sqrt(const long double a)
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return c;
|
||||
}
|
||||
strong_alias (_Q_sqrt, __ieee754_sqrtl);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
c = (long double)(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -31,13 +31,13 @@ long double _Q_stoq(const float a)
|
||||
FP_DECL_Q(C);
|
||||
long double c;
|
||||
|
||||
FP_UNPACK_S(A, a);
|
||||
FP_UNPACK_RAW_S(A, a);
|
||||
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
|
||||
FP_CONV(Q,S,4,1,C,A);
|
||||
FP_EXTEND(Q,S,4,1,C,A);
|
||||
#else
|
||||
FP_CONV(Q,S,2,1,C,A);
|
||||
FP_EXTEND(Q,S,2,1,C,A);
|
||||
#endif
|
||||
FP_PACK_Q(c, C);
|
||||
FP_PACK_RAW_Q(c, C);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return c;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
c = a - b
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -30,10 +30,10 @@ long double _Q_sub(const long double a, const long double b)
|
||||
long double c;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_Q(A, a);
|
||||
FP_UNPACK_Q(B, b);
|
||||
FP_UNPACK_SEMIRAW_Q(A, a);
|
||||
FP_UNPACK_SEMIRAW_Q(B, b);
|
||||
FP_SUB_Q(C, A, B);
|
||||
FP_PACK_Q(c, C);
|
||||
FP_PACK_SEMIRAW_Q(c, C);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return c;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (long double)(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -23,15 +23,15 @@
|
||||
#include "soft-fp.h"
|
||||
#include "quad.h"
|
||||
|
||||
long double _Q_uxtoq(const unsigned long long a)
|
||||
long double _Q_ulltoq(const unsigned long long a)
|
||||
{
|
||||
FP_DECL_EX;
|
||||
FP_DECL_Q(C);
|
||||
long double c;
|
||||
unsigned long long b = a;
|
||||
|
||||
FP_FROM_INT_Q(C, b, 64, long long);
|
||||
FP_PACK_Q(c, C);
|
||||
FP_FROM_INT_Q(C, b, 64, unsigned long long);
|
||||
FP_PACK_RAW_Q(c, C);
|
||||
FP_CLEAR_EXCEPTIONS;
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return c;
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
c = (long double)(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -23,15 +23,15 @@
|
||||
#include "soft-fp.h"
|
||||
#include "quad.h"
|
||||
|
||||
long double _Q_uitoq(const unsigned int a)
|
||||
long double _Q_utoq(const unsigned int a)
|
||||
{
|
||||
FP_DECL_EX;
|
||||
FP_DECL_Q(C);
|
||||
long double c;
|
||||
unsigned int b = a;
|
||||
|
||||
FP_FROM_INT_Q(C, b, 32, int);
|
||||
FP_PACK_Q(c, C);
|
||||
FP_FROM_INT_Q(C, b, 32, unsigned int);
|
||||
FP_PACK_RAW_Q(c, C);
|
||||
FP_CLEAR_EXCEPTIONS;
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return c;
|
@@ -1,6 +1,6 @@
|
||||
/* Machine-dependent software floating-point definitions.
|
||||
Sparc userland (_Q_*) version.
|
||||
Copyright (C) 1997,1998,1999, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1998,1999, 2002, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com),
|
||||
Jakub Jelinek (jj@ultra.linux.cz) and
|
||||
@@ -22,6 +22,7 @@
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <fpu_control.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define _FP_W_TYPE_SIZE 32
|
||||
#define _FP_W_TYPE unsigned long
|
||||
@@ -208,14 +209,5 @@ do { \
|
||||
" : : "r" (___Q_numbers) : "f30"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
__asm__ __volatile__("\
|
||||
mov %0, %%o0\n\
|
||||
mov %%o7, %%g1\n\
|
||||
call ___Q_simulate_exceptions\n\
|
||||
mov %%g1, %%o7\
|
||||
" : : "r" (_fex) : \
|
||||
"g1", "g2", "g3", "g4", "g5", "o0", \
|
||||
"o1", "o2", "o3", "o4", "o5", "cc"); \
|
||||
} \
|
||||
___Q_simulate_exceptions (_fex); \
|
||||
} while (0)
|
||||
|
@@ -1,6 +0,0 @@
|
||||
urem.S
|
||||
umul.S
|
||||
udiv.S
|
||||
sdiv.S
|
||||
rem.S
|
||||
dotmul.S
|
@@ -1,7 +0,0 @@
|
||||
dotmul.S
|
||||
hp-timing.c
|
||||
rem.S
|
||||
sdiv.S
|
||||
udiv.S
|
||||
umul.S
|
||||
urem.S
|
@@ -1,5 +1,5 @@
|
||||
/* Atomic operations. sparcv9 version.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
|
||||
@@ -59,7 +59,7 @@ typedef uintmax_t uatomic_max_t;
|
||||
__asm __volatile ("cas [%4], %2, %0" \
|
||||
: "=r" (__acev_tmp), "=m" (*__acev_mem) \
|
||||
: "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \
|
||||
"0" (newval)); \
|
||||
"0" (newval) : "memory"); \
|
||||
__acev_tmp; })
|
||||
|
||||
/* This can be implemented if needed. */
|
||||
@@ -74,11 +74,17 @@ typedef uintmax_t uatomic_max_t;
|
||||
if (sizeof (*(mem)) == 4) \
|
||||
__asm ("swap %0, %1" \
|
||||
: "=m" (*__memp), "=r" (__oldval) \
|
||||
: "m" (*__memp), "1" (__value)); \
|
||||
: "m" (*__memp), "1" (__value) : "memory"); \
|
||||
else \
|
||||
abort (); \
|
||||
__oldval; })
|
||||
|
||||
#define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \
|
||||
atomic_compare_and_exchange_val_acq (mem, newval, oldval)
|
||||
|
||||
#define atomic_exchange_24_rel(mem, newval) \
|
||||
atomic_exchange_rel (mem, newval)
|
||||
|
||||
#define atomic_full_barrier() \
|
||||
__asm __volatile ("membar #LoadLoad | #LoadStore" \
|
||||
" | #StoreLoad | #StoreStore" : : : "memory")
|
||||
|
@@ -1 +0,0 @@
|
||||
sparc/sparc32/sparcv9
|
2
sysdeps/sparc/sparc32/sparcv9v/memcpy.S
Normal file
2
sysdeps/sparc/sparc32/sparcv9v/memcpy.S
Normal file
@@ -0,0 +1,2 @@
|
||||
#define XCC icc
|
||||
#include <sparc64/sparcv9v/memcpy.S>
|
2
sysdeps/sparc/sparc32/sparcv9v/memset.S
Normal file
2
sysdeps/sparc/sparc32/sparcv9v/memset.S
Normal file
@@ -0,0 +1,2 @@
|
||||
#define XCC icc
|
||||
#include <sparc64/sparcv9v/memset.S>
|
@@ -38,7 +38,13 @@
|
||||
|
||||
.text
|
||||
.align 4
|
||||
10: ldub [%o1], %o5
|
||||
|
||||
ENTRY(__stpcpy)
|
||||
andcc %o1, 3, %g0
|
||||
be 20f
|
||||
sethi %hi(0x80808080), %o4
|
||||
|
||||
ldub [%o1], %o5
|
||||
stb %o5, [%o0]
|
||||
cmp %o5, 0
|
||||
add %o0, 1, %o0
|
||||
@@ -67,11 +73,7 @@
|
||||
1: retl
|
||||
add %o0, -1, %o0
|
||||
|
||||
ENTRY(__stpcpy)
|
||||
andcc %o1, 3, %g0
|
||||
bne 10b
|
||||
sethi %hi(0x80808080), %o4
|
||||
or %o4, %lo(0x80808080), %o3
|
||||
20: or %o4, %lo(0x80808080), %o3
|
||||
4: sethi %hi(0x01010101), %o4
|
||||
5: or %o4, %lo(0x01010101), %o2
|
||||
6: andcc %o0, 3, %g0
|
||||
@@ -160,6 +162,6 @@ ENTRY(__stpcpy)
|
||||
nop
|
||||
END(__stpcpy)
|
||||
|
||||
weak_alias(__stpcpy, stpcpy)
|
||||
weak_alias (__stpcpy, stpcpy)
|
||||
libc_hidden_def (__stpcpy)
|
||||
libc_hidden_builtin_def (stpcpy)
|
||||
|
@@ -38,36 +38,14 @@
|
||||
|
||||
.text
|
||||
.align 4
|
||||
10: cmp %o4, 2
|
||||
be 1f
|
||||
cmp %o4, 3
|
||||
ldub [%o1], %o5
|
||||
add %o1, 1, %o1
|
||||
stb %o5, [%o0]
|
||||
be 3f
|
||||
cmp %o5, 0
|
||||
be 0f
|
||||
add %o0, 1, %o0
|
||||
1: lduh [%o1], %o5
|
||||
add %o1, 2, %o1
|
||||
srl %o5, 8, %o4
|
||||
cmp %o4, 0
|
||||
stb %o4, [%o0]
|
||||
bne,a 2f
|
||||
stb %o5, [%o0 + 1]
|
||||
retl
|
||||
mov %g2, %o0
|
||||
2: andcc %o5, 0xff, %o5
|
||||
bne 4f
|
||||
add %o0, 2, %o0
|
||||
retl
|
||||
mov %g2, %o0
|
||||
3: bne 4f
|
||||
add %o0, 1, %o0
|
||||
retl
|
||||
mov %g2, %o0
|
||||
|
||||
11: ldub [%o0], %o5
|
||||
ENTRY(strcat)
|
||||
mov %o0, %g2
|
||||
andcc %o0, 3, %g0
|
||||
be 30f
|
||||
sethi %hi(0x80808080), %o4
|
||||
|
||||
ldub [%o0], %o5
|
||||
cmp %o5, 0
|
||||
be 1f
|
||||
add %o0, 1, %o0
|
||||
@@ -93,12 +71,7 @@
|
||||
b 3f
|
||||
sub %o0, 1, %o0
|
||||
|
||||
ENTRY(strcat)
|
||||
mov %o0, %g2
|
||||
andcc %o0, 3, %g0
|
||||
bne 11b
|
||||
sethi %hi(0x80808080), %o4
|
||||
or %o4, %lo(0x80808080), %o3
|
||||
30: or %o4, %lo(0x80808080), %o3
|
||||
7: sethi %hi(0x01010101), %o4
|
||||
8: or %o4, %lo(0x01010101), %o2
|
||||
9: ld [%o0], %o5
|
||||
@@ -128,8 +101,39 @@ ENTRY(strcat)
|
||||
ld [%o0], %o5
|
||||
sub %o0, 1, %o0
|
||||
3: andcc %o1, 3, %o4
|
||||
bne 10b
|
||||
4: andcc %o0, 3, %g3
|
||||
be 4f
|
||||
nop
|
||||
|
||||
cmp %o4, 2
|
||||
be 11f
|
||||
cmp %o4, 3
|
||||
ldub [%o1], %o5
|
||||
add %o1, 1, %o1
|
||||
stb %o5, [%o0]
|
||||
be 13f
|
||||
cmp %o5, 0
|
||||
be 0f
|
||||
add %o0, 1, %o0
|
||||
11: lduh [%o1], %o5
|
||||
add %o1, 2, %o1
|
||||
srl %o5, 8, %o4
|
||||
cmp %o4, 0
|
||||
stb %o4, [%o0]
|
||||
bne,a 12f
|
||||
stb %o5, [%o0 + 1]
|
||||
retl
|
||||
mov %g2, %o0
|
||||
12: andcc %o5, 0xff, %o5
|
||||
bne 4f
|
||||
add %o0, 2, %o0
|
||||
retl
|
||||
mov %g2, %o0
|
||||
13: bne 4f
|
||||
add %o0, 1, %o0
|
||||
retl
|
||||
mov %g2, %o0
|
||||
|
||||
4: andcc %o0, 3, %g3
|
||||
bne 12f
|
||||
1: ld [%o1], %o5
|
||||
add %o1, 4, %o1
|
||||
|
@@ -39,36 +39,6 @@
|
||||
|
||||
.text
|
||||
.align 4
|
||||
10: ldub [%o0], %g4
|
||||
cmp %g4, %o1
|
||||
be 1f
|
||||
add %o0, 1, %o0
|
||||
cmp %g4, 0
|
||||
be 9f
|
||||
andcc %o0, 3, %g0
|
||||
be 4f
|
||||
or %o4, %lo(0x80808080), %o3
|
||||
ldub [%o0], %g4
|
||||
cmp %g4, %o1
|
||||
be 1f
|
||||
add %o0, 1, %o0
|
||||
cmp %g4, 0
|
||||
be 9f
|
||||
andcc %o0, 3, %g0
|
||||
be 5f
|
||||
sethi %hi(0x01010101), %o5
|
||||
ldub [%o0], %g4
|
||||
cmp %g4, %o1
|
||||
be 1f
|
||||
add %o0, 1, %o0
|
||||
cmp %g4, 0
|
||||
be 9f
|
||||
or %o5, %lo(0x01010101), %o2
|
||||
b 6f
|
||||
ld [%o0], %g4
|
||||
1: retl
|
||||
sub %o0, 1, %o0
|
||||
|
||||
ENTRY(strchr)
|
||||
andcc %o1, 0xff, %o1
|
||||
be 12f
|
||||
@@ -77,9 +47,40 @@ ENTRY(strchr)
|
||||
or %o1, %o2, %o2
|
||||
sethi %hi(0x80808080), %o4
|
||||
sll %o2, 16, %o3
|
||||
bne 10b
|
||||
be 13f
|
||||
or %o3, %o2, %g2
|
||||
or %o4, %lo(0x80808080), %o3
|
||||
|
||||
ldub [%o0], %g4
|
||||
cmp %g4, %o1
|
||||
be 11f
|
||||
add %o0, 1, %o0
|
||||
cmp %g4, 0
|
||||
be 9f
|
||||
andcc %o0, 3, %g0
|
||||
be 4f
|
||||
or %o4, %lo(0x80808080), %o3
|
||||
ldub [%o0], %g4
|
||||
cmp %g4, %o1
|
||||
be 11f
|
||||
add %o0, 1, %o0
|
||||
cmp %g4, 0
|
||||
be 9f
|
||||
andcc %o0, 3, %g0
|
||||
be 5f
|
||||
sethi %hi(0x01010101), %o5
|
||||
ldub [%o0], %g4
|
||||
cmp %g4, %o1
|
||||
be 11f
|
||||
add %o0, 1, %o0
|
||||
cmp %g4, 0
|
||||
be 9f
|
||||
or %o5, %lo(0x01010101), %o2
|
||||
b 6f
|
||||
ld [%o0], %g4
|
||||
11: retl
|
||||
sub %o0, 1, %o0
|
||||
|
||||
13: or %o4, %lo(0x80808080), %o3
|
||||
4: sethi %hi(0x01010101), %o5
|
||||
5: or %o5, %lo(0x01010101), %o2
|
||||
7: ld [%o0], %g4
|
||||
@@ -278,7 +279,7 @@ ENTRY(strrchr)
|
||||
mov %o5, %o0
|
||||
END(strrchr)
|
||||
|
||||
weak_alias(strchr, index)
|
||||
weak_alias(strrchr, rindex)
|
||||
weak_alias (strchr, index)
|
||||
weak_alias (strrchr, rindex)
|
||||
libc_hidden_builtin_def (strchr)
|
||||
libc_hidden_builtin_def (strrchr)
|
||||
|
@@ -38,7 +38,13 @@
|
||||
|
||||
.text
|
||||
.align 4
|
||||
10: ldub [%o0], %o4
|
||||
|
||||
ENTRY(strcmp)
|
||||
andcc %o0, 3, %g0
|
||||
be 13f
|
||||
sethi %hi(0x80808080), %g1
|
||||
|
||||
ldub [%o0], %o4
|
||||
add %o0, 1, %o0
|
||||
ldub [%o1], %o5
|
||||
cmp %o4, 0
|
||||
@@ -76,11 +82,7 @@
|
||||
2: retl
|
||||
mov %o4, %o0
|
||||
|
||||
ENTRY(strcmp)
|
||||
andcc %o0, 3, %g0
|
||||
bne 10b
|
||||
sethi %hi(0x80808080), %g1
|
||||
or %g1, %lo(0x80808080), %o3
|
||||
13: or %g1, %lo(0x80808080), %o3
|
||||
4: sethi %hi(0x01010101), %g1
|
||||
5: andcc %o1, 3, %g2
|
||||
bne 12f
|
||||
|
@@ -38,7 +38,14 @@
|
||||
|
||||
.text
|
||||
.align 4
|
||||
1: ldub [%o1], %o5
|
||||
|
||||
ENTRY(strcpy)
|
||||
mov %o0, %g2
|
||||
andcc %o1, 3, %g0
|
||||
be 10f
|
||||
sethi %hi(0x80808080), %o4
|
||||
|
||||
ldub [%o1], %o5
|
||||
stb %o5, [%o0]
|
||||
cmp %o5, 0
|
||||
add %o0, 1, %o0
|
||||
@@ -65,12 +72,7 @@
|
||||
b 6f
|
||||
andcc %o0, 3, %g3
|
||||
|
||||
ENTRY(strcpy)
|
||||
mov %o0, %g2
|
||||
andcc %o1, 3, %g0
|
||||
bne 1b
|
||||
sethi %hi(0x80808080), %o4
|
||||
or %o4, %lo(0x80808080), %o3
|
||||
10: or %o4, %lo(0x80808080), %o3
|
||||
4: sethi %hi(0x01010101), %o4
|
||||
5: andcc %o0, 3, %g3
|
||||
6: bne 10f
|
||||
|
@@ -38,39 +38,41 @@
|
||||
|
||||
.text
|
||||
.align 4
|
||||
10: ldub [%o0], %o5
|
||||
|
||||
ENTRY(strlen)
|
||||
mov %o0, %o1
|
||||
andcc %o0, 3, %g0
|
||||
be 20f
|
||||
sethi %hi(0x80808080), %o4
|
||||
|
||||
ldub [%o0], %o5
|
||||
cmp %o5, 0
|
||||
be 1f
|
||||
be 21f
|
||||
add %o0, 1, %o0
|
||||
andcc %o0, 3, %g0
|
||||
be 4f
|
||||
or %o4, %lo(0x80808080), %o3
|
||||
ldub [%o0], %o5
|
||||
cmp %o5, 0
|
||||
be 2f
|
||||
be 22f
|
||||
add %o0, 1, %o0
|
||||
andcc %o0, 3, %g0
|
||||
be 5f
|
||||
sethi %hi(0x01010101), %o4
|
||||
ldub [%o0], %o5
|
||||
cmp %o5, 0
|
||||
be 3f
|
||||
be 23f
|
||||
add %o0, 1, %o0
|
||||
b 11f
|
||||
or %o4, %lo(0x01010101), %o2
|
||||
1: retl
|
||||
21: retl
|
||||
mov 0, %o0
|
||||
2: retl
|
||||
22: retl
|
||||
mov 1, %o0
|
||||
3: retl
|
||||
23: retl
|
||||
mov 2, %o0
|
||||
|
||||
ENTRY(strlen)
|
||||
mov %o0, %o1
|
||||
andcc %o0, 3, %g0
|
||||
bne 10b
|
||||
sethi %hi(0x80808080), %o4
|
||||
or %o4, %lo(0x80808080), %o3
|
||||
20: or %o4, %lo(0x80808080), %o3
|
||||
4: sethi %hi(0x01010101), %o4
|
||||
5: or %o4, %lo(0x01010101), %o2
|
||||
11: ld [%o0], %o5
|
||||
|
@@ -1 +0,0 @@
|
||||
hp-timing.c
|
@@ -1,6 +1,3 @@
|
||||
# The Sparc `long double' is a distinct type we support.
|
||||
long-double-fcts = yes
|
||||
|
||||
ifeq ($(subdir),csu)
|
||||
sysdep_routines += hp-timing
|
||||
elide-routines.os += hp-timing
|
||||
|
@@ -5,3 +5,10 @@ libc {
|
||||
__align_cpy_8; __align_cpy_16;
|
||||
}
|
||||
}
|
||||
libm {
|
||||
GLIBC_2.1 {
|
||||
# A generic bug got this omitted from other configurations' version
|
||||
# sets, but we always had it.
|
||||
exp2l;
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Atomic operations. sparc64 version.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
|
||||
@@ -59,7 +59,7 @@ typedef uintmax_t uatomic_max_t;
|
||||
__asm __volatile ("cas [%4], %2, %0" \
|
||||
: "=r" (__acev_tmp), "=m" (*__acev_mem) \
|
||||
: "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \
|
||||
"0" (newval)); \
|
||||
"0" (newval) : "memory"); \
|
||||
__acev_tmp; })
|
||||
|
||||
#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
|
||||
@@ -69,7 +69,7 @@ typedef uintmax_t uatomic_max_t;
|
||||
__asm __volatile ("casx [%4], %2, %0" \
|
||||
: "=r" (__acev_tmp), "=m" (*__acev_mem) \
|
||||
: "r" ((long) (oldval)), "m" (*__acev_mem), \
|
||||
"r" (__acev_mem), "0" ((long) (newval))); \
|
||||
"r" (__acev_mem), "0" ((long) (newval)) : "memory"); \
|
||||
__acev_tmp; })
|
||||
|
||||
#define atomic_exchange_acq(mem, newvalue) \
|
||||
@@ -80,7 +80,7 @@ typedef uintmax_t uatomic_max_t;
|
||||
if (sizeof (*(mem)) == 4) \
|
||||
__asm ("swap %0, %1" \
|
||||
: "=m" (*__memp), "=r" (__oldval) \
|
||||
: "m" (*__memp), "1" (__value)); \
|
||||
: "m" (*__memp), "1" (__value) : "memory"); \
|
||||
else \
|
||||
{ \
|
||||
__val = *__memp; \
|
||||
@@ -94,6 +94,12 @@ typedef uintmax_t uatomic_max_t;
|
||||
} \
|
||||
__oldval; })
|
||||
|
||||
#define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \
|
||||
atomic_compare_and_exchange_val_acq (mem, newval, oldval)
|
||||
|
||||
#define atomic_exchange_24_rel(mem, newval) \
|
||||
atomic_exchange_rel (mem, newval)
|
||||
|
||||
#define atomic_full_barrier() \
|
||||
__asm __volatile ("membar #LoadLoad | #LoadStore" \
|
||||
" | #StoreLoad | #StoreStore" : : : "memory")
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Machine-dependent ELF dynamic relocation inline functions. Sparc64 version.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
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 "sparc64"
|
||||
|
||||
#include <string.h>
|
||||
@@ -88,7 +91,7 @@ elf_machine_load_address (void)
|
||||
|
||||
/* We have 4 cases to handle. And we code different code sequences
|
||||
for each one. I love V9 code models... */
|
||||
static inline void
|
||||
static inline void __attribute__ ((always_inline))
|
||||
sparc64_fixup_plt (struct link_map *map, const Elf64_Rela *reloc,
|
||||
Elf64_Addr *reloc_addr, Elf64_Addr value,
|
||||
Elf64_Addr high, int t)
|
||||
@@ -212,7 +215,7 @@ sparc64_fixup_plt (struct link_map *map, const Elf64_Rela *reloc,
|
||||
}
|
||||
}
|
||||
|
||||
static inline Elf64_Addr
|
||||
static inline Elf64_Addr __attribute__ ((always_inline))
|
||||
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
|
||||
const Elf64_Rela *reloc,
|
||||
Elf64_Addr *reloc_addr, Elf64_Addr value)
|
||||
@@ -233,236 +236,21 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
|
||||
return value;
|
||||
}
|
||||
|
||||
#ifdef RESOLVE
|
||||
|
||||
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
|
||||
MAP is the object containing the reloc. */
|
||||
|
||||
static inline void
|
||||
elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
|
||||
const Elf64_Sym *sym, const struct r_found_version *version,
|
||||
void *const reloc_addr_arg)
|
||||
{
|
||||
Elf64_Addr *const reloc_addr = reloc_addr_arg;
|
||||
const unsigned long int r_type = ELF64_R_TYPE_ID (reloc->r_info);
|
||||
|
||||
#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
|
||||
if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0))
|
||||
*reloc_addr = map->l_addr + reloc->r_addend;
|
||||
# ifndef RTLD_BOOTSTRAP
|
||||
else if (r_type == R_SPARC_NONE) /* Who is Wilbur? */
|
||||
return;
|
||||
# endif
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
const Elf64_Sym *const refsym = sym;
|
||||
#endif
|
||||
Elf64_Addr value;
|
||||
#ifndef RESOLVE_CONFLICT_FIND_MAP
|
||||
if (sym->st_shndx != SHN_UNDEF &&
|
||||
ELF64_ST_BIND (sym->st_info) == STB_LOCAL)
|
||||
value = map->l_addr;
|
||||
else
|
||||
{
|
||||
value = RESOLVE (&sym, version, r_type);
|
||||
if (sym)
|
||||
value += sym->st_value;
|
||||
}
|
||||
#else
|
||||
value = 0;
|
||||
#endif
|
||||
value += reloc->r_addend; /* Assume copy relocs have zero addend. */
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
case R_SPARC_COPY:
|
||||
if (sym == NULL)
|
||||
/* This can happen in trace mode if an object could not be
|
||||
found. */
|
||||
break;
|
||||
if (sym->st_size > refsym->st_size
|
||||
|| (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
|
||||
{
|
||||
const char *strtab;
|
||||
|
||||
strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
_dl_error_printf ("\
|
||||
%s: Symbol `%s' has different size in shared object, consider re-linking\n",
|
||||
rtld_progname ?: "<program name unknown>",
|
||||
strtab + refsym->st_name);
|
||||
}
|
||||
memcpy (reloc_addr_arg, (void *) value,
|
||||
MIN (sym->st_size, refsym->st_size));
|
||||
break;
|
||||
#endif
|
||||
case R_SPARC_64:
|
||||
case R_SPARC_GLOB_DAT:
|
||||
*reloc_addr = value;
|
||||
break;
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
case R_SPARC_8:
|
||||
*(char *) reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_16:
|
||||
*(short *) reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_32:
|
||||
*(unsigned int *) reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_DISP8:
|
||||
*(char *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_DISP16:
|
||||
*(short *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_DISP32:
|
||||
*(unsigned int *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_WDISP30:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & 0xc0000000) |
|
||||
((value - (Elf64_Addr) reloc_addr) >> 2));
|
||||
break;
|
||||
|
||||
/* MEDLOW code model relocs */
|
||||
case R_SPARC_LO10:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & ~0x3ff) |
|
||||
(value & 0x3ff));
|
||||
break;
|
||||
case R_SPARC_HI22:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & 0xffc00000) |
|
||||
(value >> 10));
|
||||
break;
|
||||
case R_SPARC_OLO10:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & ~0x1fff) |
|
||||
(((value & 0x3ff) + ELF64_R_TYPE_DATA (reloc->r_info)) & 0x1fff));
|
||||
break;
|
||||
|
||||
/* MEDMID code model relocs */
|
||||
case R_SPARC_H44:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & 0xffc00000) |
|
||||
(value >> 22));
|
||||
break;
|
||||
case R_SPARC_M44:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & ~0x3ff) |
|
||||
((value >> 12) & 0x3ff));
|
||||
break;
|
||||
case R_SPARC_L44:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & ~0xfff) |
|
||||
(value & 0xfff));
|
||||
break;
|
||||
|
||||
/* MEDANY code model relocs */
|
||||
case R_SPARC_HH22:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & 0xffc00000) |
|
||||
(value >> 42));
|
||||
break;
|
||||
case R_SPARC_HM10:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & ~0x3ff) |
|
||||
((value >> 32) & 0x3ff));
|
||||
break;
|
||||
case R_SPARC_LM22:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & 0xffc00000) |
|
||||
((value >> 10) & 0x003fffff));
|
||||
break;
|
||||
#endif
|
||||
case R_SPARC_JMP_SLOT:
|
||||
#ifdef RESOLVE_CONFLICT_FIND_MAP
|
||||
/* R_SPARC_JMP_SLOT conflicts against .plt[32768+]
|
||||
relocs should be turned into R_SPARC_64 relocs
|
||||
in .gnu.conflict section.
|
||||
r_addend non-zero does not mean it is a .plt[32768+]
|
||||
reloc, instead it is the actual address of the function
|
||||
to call. */
|
||||
sparc64_fixup_plt (NULL, reloc, reloc_addr, value, 0, 0);
|
||||
#else
|
||||
sparc64_fixup_plt (map, reloc, reloc_addr, value,
|
||||
reloc->r_addend, 0);
|
||||
#endif
|
||||
break;
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
case R_SPARC_UA16:
|
||||
((unsigned char *) reloc_addr_arg) [0] = value >> 8;
|
||||
((unsigned char *) reloc_addr_arg) [1] = value;
|
||||
break;
|
||||
case R_SPARC_UA32:
|
||||
((unsigned char *) reloc_addr_arg) [0] = value >> 24;
|
||||
((unsigned char *) reloc_addr_arg) [1] = value >> 16;
|
||||
((unsigned char *) reloc_addr_arg) [2] = value >> 8;
|
||||
((unsigned char *) reloc_addr_arg) [3] = value;
|
||||
break;
|
||||
case R_SPARC_UA64:
|
||||
if (! ((long) reloc_addr_arg & 3))
|
||||
{
|
||||
/* Common in .eh_frame */
|
||||
((unsigned int *) reloc_addr_arg) [0] = value >> 32;
|
||||
((unsigned int *) reloc_addr_arg) [1] = value;
|
||||
break;
|
||||
}
|
||||
((unsigned char *) reloc_addr_arg) [0] = value >> 56;
|
||||
((unsigned char *) reloc_addr_arg) [1] = value >> 48;
|
||||
((unsigned char *) reloc_addr_arg) [2] = value >> 40;
|
||||
((unsigned char *) reloc_addr_arg) [3] = value >> 32;
|
||||
((unsigned char *) reloc_addr_arg) [4] = value >> 24;
|
||||
((unsigned char *) reloc_addr_arg) [5] = value >> 16;
|
||||
((unsigned char *) reloc_addr_arg) [6] = value >> 8;
|
||||
((unsigned char *) reloc_addr_arg) [7] = value;
|
||||
break;
|
||||
#endif
|
||||
#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
|
||||
default:
|
||||
_dl_reloc_bad_type (map, r_type, 0);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
|
||||
void *const reloc_addr_arg)
|
||||
{
|
||||
Elf64_Addr *const reloc_addr = reloc_addr_arg;
|
||||
*reloc_addr = l_addr + reloc->r_addend;
|
||||
}
|
||||
|
||||
static inline void
|
||||
elf_machine_lazy_rel (struct link_map *map,
|
||||
Elf64_Addr l_addr, const Elf64_Rela *reloc)
|
||||
{
|
||||
switch (ELF64_R_TYPE (reloc->r_info))
|
||||
{
|
||||
case R_SPARC_NONE:
|
||||
break;
|
||||
case R_SPARC_JMP_SLOT:
|
||||
break;
|
||||
default:
|
||||
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RESOLVE */
|
||||
|
||||
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
|
||||
PLT entries should not be allowed to define the value.
|
||||
ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
|
||||
of the main executable's symbols, as for a COPY reloc. */
|
||||
#define elf_machine_type_class(type) \
|
||||
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
|
||||
# define elf_machine_type_class(type) \
|
||||
((((type) == R_SPARC_JMP_SLOT \
|
||||
|| ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64)) \
|
||||
* ELF_RTYPE_CLASS_PLT) \
|
||||
| (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY))
|
||||
#else
|
||||
# define elf_machine_type_class(type) \
|
||||
((((type) == R_SPARC_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
|
||||
| (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY))
|
||||
#endif
|
||||
|
||||
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
|
||||
#define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT
|
||||
@@ -487,74 +275,67 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
extern void _dl_runtime_profile_1 (void);
|
||||
Elf64_Addr res0_addr, res1_addr;
|
||||
unsigned int *plt = (void *) D_PTR (l, l_info[DT_PLTGOT]);
|
||||
int i = 0;
|
||||
|
||||
if (! profile)
|
||||
if (__builtin_expect(profile, 0))
|
||||
{
|
||||
res0_addr = (Elf64_Addr) &_dl_runtime_profile_0;
|
||||
res1_addr = (Elf64_Addr) &_dl_runtime_profile_1;
|
||||
|
||||
if (GLRO(dl_profile) != NULL
|
||||
&& _dl_name_match_p (GLRO(dl_profile), l))
|
||||
GL(dl_profile_map) = l;
|
||||
}
|
||||
else
|
||||
{
|
||||
res0_addr = (Elf64_Addr) &_dl_runtime_resolve_0;
|
||||
res1_addr = (Elf64_Addr) &_dl_runtime_resolve_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
res0_addr = (Elf64_Addr) &_dl_runtime_profile_0;
|
||||
res1_addr = (Elf64_Addr) &_dl_runtime_profile_1;
|
||||
if (_dl_name_match_p (GLRO(dl_profile), l))
|
||||
GL(dl_profile_map) = l;
|
||||
}
|
||||
|
||||
/* PLT0 looks like:
|
||||
|
||||
save %sp, -192, %sp
|
||||
sethi %hh(_dl_runtime_{resolve,profile}_0), %l0
|
||||
sethi %lm(_dl_runtime_{resolve,profile}_0), %l1
|
||||
or %l0, %hm(_dl_runtime_{resolve,profile}_0), %l0
|
||||
or %l1, %lo(_dl_runtime_{resolve,profile}_0), %l1
|
||||
sllx %l0, 32, %l0
|
||||
jmpl %l0 + %l1, %l6
|
||||
sethi %hi(0xffc00), %l2
|
||||
sethi %uhi(_dl_runtime_{resolve,profile}_0), %g4
|
||||
sethi %hi(_dl_runtime_{resolve,profile}_0), %g5
|
||||
or %g4, %ulo(_dl_runtime_{resolve,profile}_0), %g4
|
||||
or %g5, %lo(_dl_runtime_{resolve,profile}_0), %g5
|
||||
sllx %g4, 32, %g4
|
||||
add %g4, %g5, %g5
|
||||
jmpl %g5, %g4
|
||||
nop
|
||||
*/
|
||||
|
||||
plt[0] = 0x9de3bf40;
|
||||
plt[1] = 0x21000000 | (res0_addr >> (64 - 22));
|
||||
plt[2] = 0x23000000 | ((res0_addr >> 10) & 0x003fffff);
|
||||
plt[3] = 0xa0142000 | ((res0_addr >> 32) & 0x3ff);
|
||||
plt[4] = 0xa2146000 | (res0_addr & 0x3ff);
|
||||
plt[5] = 0xa12c3020;
|
||||
plt[6] = 0xadc40011;
|
||||
plt[7] = 0x250003ff;
|
||||
plt[0] = 0x09000000 | (res0_addr >> (64 - 22));
|
||||
plt[1] = 0x0b000000 | ((res0_addr >> 10) & 0x003fffff);
|
||||
plt[2] = 0x88112000 | ((res0_addr >> 32) & 0x3ff);
|
||||
plt[3] = 0x8a116000 | (res0_addr & 0x3ff);
|
||||
plt[4] = 0x89293020;
|
||||
plt[5] = 0x8a010005;
|
||||
plt[6] = 0x89c14000;
|
||||
plt[7] = 0x01000000;
|
||||
|
||||
/* PLT1 looks like:
|
||||
|
||||
save %sp, -192, %sp
|
||||
sethi %hh(_dl_runtime_{resolve,profile}_1), %l0
|
||||
sethi %lm(_dl_runtime_{resolve,profile}_1), %l1
|
||||
or %l0, %hm(_dl_runtime_{resolve,profile}_1), %l0
|
||||
or %l1, %lo(_dl_runtime_{resolve,profile}_1), %l1
|
||||
sllx %l0, 32, %l0
|
||||
jmpl %l0 + %l1, %l6
|
||||
srlx %g1, 12, %o1
|
||||
sethi %uhi(_dl_runtime_{resolve,profile}_1), %g4
|
||||
sethi %hi(_dl_runtime_{resolve,profile}_1), %g5
|
||||
or %g4, %ulo(_dl_runtime_{resolve,profile}_1), %g4
|
||||
or %g5, %lo(_dl_runtime_{resolve,profile}_1), %g5
|
||||
sllx %g4, 32, %g4
|
||||
add %g4, %g5, %g5
|
||||
jmpl %g5, %g4
|
||||
nop
|
||||
*/
|
||||
|
||||
plt[8 + 0] = 0x9de3bf40;
|
||||
if (__builtin_expect (((res1_addr + 4) >> 32) & 0x3ff, 0))
|
||||
i = 1;
|
||||
else
|
||||
res1_addr += 4;
|
||||
plt[8 + 1] = 0x21000000 | (res1_addr >> (64 - 22));
|
||||
plt[8 + 2] = 0x23000000 | ((res1_addr >> 10) & 0x003fffff);
|
||||
if (__builtin_expect (i, 0))
|
||||
plt[8 + 3] = 0xa0142000 | ((res1_addr >> 32) & 0x3ff);
|
||||
else
|
||||
plt[8 + 3] = 0xa12c3020;
|
||||
plt[8 + 4] = 0xa2146000 | (res1_addr & 0x3ff);
|
||||
if (__builtin_expect (i, 0))
|
||||
plt[8 + 5] = 0xa12c3020;
|
||||
plt[8 + 5 + i] = 0xadc40011;
|
||||
plt[8 + 6 + i] = 0x9330700c;
|
||||
plt[8] = 0x09000000 | (res1_addr >> (64 - 22));
|
||||
plt[9] = 0x0b000000 | ((res1_addr >> 10) & 0x003fffff);
|
||||
plt[10] = 0x88112000 | ((res1_addr >> 32) & 0x3ff);
|
||||
plt[11] = 0x8a116000 | (res1_addr & 0x3ff);
|
||||
plt[12] = 0x89293020;
|
||||
plt[13] = 0x8a010005;
|
||||
plt[14] = 0x89c14000;
|
||||
plt[15] = 0x01000000;
|
||||
|
||||
/* Now put the magic cookie at the beginning of .PLT2
|
||||
Entry .PLT3 is unused by this implementation. */
|
||||
*((struct link_map **)(&plt[16 + 0])) = l;
|
||||
*((struct link_map **)(&plt[16])) = l;
|
||||
|
||||
if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0)
|
||||
|| __builtin_expect (l->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL, 0))
|
||||
@@ -601,68 +382,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
return lazy;
|
||||
}
|
||||
|
||||
/* This code is used in dl-runtime.c to call the `fixup' function
|
||||
and then redirect to the address it returns. */
|
||||
#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \
|
||||
asm ("\n" \
|
||||
" .text\n" \
|
||||
" .globl " #tramp_name "_0\n" \
|
||||
" .type " #tramp_name "_0, @function\n" \
|
||||
" .align 32\n" \
|
||||
"\t" #tramp_name "_0:\n" \
|
||||
" ! sethi %hi(1047552), %l2 - Done in .PLT0\n" \
|
||||
" ldx [%l6 + 32 + 8], %o0\n" \
|
||||
" sub %g1, %l6, %l0\n" \
|
||||
" xor %l2, -1016, %l2\n" \
|
||||
" sethi %hi(5120), %l3 ! 160 * 32\n" \
|
||||
" add %l0, %l2, %l0\n" \
|
||||
" sethi %hi(32768), %l4\n" \
|
||||
" udivx %l0, %l3, %l3\n" \
|
||||
" sllx %l3, 2, %l1\n" \
|
||||
" add %l1, %l3, %l1\n" \
|
||||
" sllx %l1, 10, %l2\n" \
|
||||
" sub %l4, 4, %l4 ! No thanks to Sun for not obeying their own ABI\n" \
|
||||
" sllx %l1, 5, %l1\n" \
|
||||
" sub %l0, %l2, %l0\n" \
|
||||
" udivx %l0, 24, %l0\n" \
|
||||
" add %l0, %l4, %l0\n" \
|
||||
" add %l1, %l0, %l1\n" \
|
||||
" add %l1, %l1, %l0\n" \
|
||||
" add %l0, %l1, %l0\n" \
|
||||
" mov %i7, %o2\n" \
|
||||
" call " #fixup_name "\n" \
|
||||
" sllx %l0, 3, %o1\n" \
|
||||
" jmp %o0\n" \
|
||||
" restore\n" \
|
||||
" .size " #tramp_name "_0, . - " #tramp_name "_0\n" \
|
||||
"\n" \
|
||||
" .globl " #tramp_name "_1\n" \
|
||||
" .type " #tramp_name "_1, @function\n" \
|
||||
" ! tramp_name_1 + 4 needs to be .align 32\n" \
|
||||
"\t" #tramp_name "_1:\n" \
|
||||
" sub %l6, 4, %l6\n" \
|
||||
" ! srlx %g1, 12, %o1 - Done in .PLT1\n" \
|
||||
" ldx [%l6 + 12], %o0\n" \
|
||||
" add %o1, %o1, %o3\n" \
|
||||
" sub %o1, 96, %o1 ! No thanks to Sun for not obeying their own ABI\n" \
|
||||
" mov %i7, %o2\n" \
|
||||
" call " #fixup_name "\n" \
|
||||
" add %o1, %o3, %o1\n" \
|
||||
" jmp %o0\n" \
|
||||
" restore\n" \
|
||||
" .size " #tramp_name "_1, . - " #tramp_name "_1\n" \
|
||||
" .previous\n");
|
||||
|
||||
#ifndef PROF
|
||||
#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup);
|
||||
#else
|
||||
#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_profile, fixup);
|
||||
#endif
|
||||
|
||||
/* The PLT uses Elf64_Rela relocs. */
|
||||
#define elf_machine_relplt elf_machine_rela
|
||||
|
||||
@@ -763,3 +482,291 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
" add %sp, 6*8, %sp\n" \
|
||||
" .size _dl_start_user, . - _dl_start_user\n" \
|
||||
" .previous\n");
|
||||
|
||||
#endif /* dl_machine_h */
|
||||
|
||||
#define ARCH_LA_PLTENTER sparc64_gnu_pltenter
|
||||
#define ARCH_LA_PLTEXIT sparc64_gnu_pltexit
|
||||
|
||||
#ifdef RESOLVE_MAP
|
||||
|
||||
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
|
||||
MAP is the object containing the reloc. */
|
||||
|
||||
auto inline void
|
||||
__attribute__ ((always_inline))
|
||||
elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
|
||||
const Elf64_Sym *sym, const struct r_found_version *version,
|
||||
void *const reloc_addr_arg)
|
||||
{
|
||||
Elf64_Addr *const reloc_addr = reloc_addr_arg;
|
||||
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
const Elf64_Sym *const refsym = sym;
|
||||
#endif
|
||||
Elf64_Addr value;
|
||||
const unsigned long int r_type = ELF64_R_TYPE_ID (reloc->r_info);
|
||||
#if !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
struct link_map *sym_map = NULL;
|
||||
#endif
|
||||
|
||||
#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (r_type == R_SPARC_NONE, 0))
|
||||
return;
|
||||
|
||||
#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
|
||||
if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0))
|
||||
{
|
||||
# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
|
||||
if (map != &_dl_rtld_map) /* Already done in rtld itself. */
|
||||
# endif
|
||||
*reloc_addr += map->l_addr + reloc->r_addend;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef RESOLVE_CONFLICT_FIND_MAP
|
||||
if (__builtin_expect (ELF64_ST_BIND (sym->st_info) == STB_LOCAL, 0)
|
||||
&& sym->st_shndx != SHN_UNDEF)
|
||||
{
|
||||
value = map->l_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||
value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
|
||||
}
|
||||
#else
|
||||
value = 0;
|
||||
#endif
|
||||
|
||||
value += reloc->r_addend; /* Assume copy relocs have zero addend. */
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
case R_SPARC_COPY:
|
||||
if (sym == NULL)
|
||||
/* This can happen in trace mode if an object could not be
|
||||
found. */
|
||||
break;
|
||||
if (sym->st_size > refsym->st_size
|
||||
|| (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
|
||||
{
|
||||
const char *strtab;
|
||||
|
||||
strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
_dl_error_printf ("\
|
||||
%s: Symbol `%s' has different size in shared object, consider re-linking\n",
|
||||
rtld_progname ?: "<program name unknown>",
|
||||
strtab + refsym->st_name);
|
||||
}
|
||||
memcpy (reloc_addr_arg, (void *) value,
|
||||
MIN (sym->st_size, refsym->st_size));
|
||||
break;
|
||||
#endif
|
||||
case R_SPARC_64:
|
||||
case R_SPARC_GLOB_DAT:
|
||||
*reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_JMP_SLOT:
|
||||
#ifdef RESOLVE_CONFLICT_FIND_MAP
|
||||
/* R_SPARC_JMP_SLOT conflicts against .plt[32768+]
|
||||
relocs should be turned into R_SPARC_64 relocs
|
||||
in .gnu.conflict section.
|
||||
r_addend non-zero does not mean it is a .plt[32768+]
|
||||
reloc, instead it is the actual address of the function
|
||||
to call. */
|
||||
sparc64_fixup_plt (NULL, reloc, reloc_addr, value, 0, 0);
|
||||
#else
|
||||
sparc64_fixup_plt (map, reloc, reloc_addr, value, reloc->r_addend, 0);
|
||||
#endif
|
||||
break;
|
||||
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
|
||||
&& !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
case R_SPARC_TLS_DTPMOD64:
|
||||
/* Get the information from the link map returned by the
|
||||
resolv function. */
|
||||
if (sym_map != NULL)
|
||||
*reloc_addr = sym_map->l_tls_modid;
|
||||
break;
|
||||
case R_SPARC_TLS_DTPOFF64:
|
||||
/* During relocation all TLS symbols are defined and used.
|
||||
Therefore the offset is already correct. */
|
||||
*reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
|
||||
break;
|
||||
case R_SPARC_TLS_TPOFF64:
|
||||
/* The offset is negative, forward from the thread pointer. */
|
||||
/* We know the offset of object the symbol is contained in.
|
||||
It is a negative value which will be added to the
|
||||
thread pointer. */
|
||||
if (sym != NULL)
|
||||
{
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr = sym->st_value - sym_map->l_tls_offset
|
||||
+ reloc->r_addend;
|
||||
}
|
||||
break;
|
||||
# ifndef RTLD_BOOTSTRAP
|
||||
case R_SPARC_TLS_LE_HIX22:
|
||||
case R_SPARC_TLS_LE_LOX10:
|
||||
if (sym != NULL)
|
||||
{
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
value = sym->st_value - sym_map->l_tls_offset
|
||||
+ reloc->r_addend;
|
||||
if (r_type == R_SPARC_TLS_LE_HIX22)
|
||||
*reloc_addr = (*reloc_addr & 0xffc00000)
|
||||
| (((~value) >> 10) & 0x3fffff);
|
||||
else
|
||||
*reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff)
|
||||
| 0x1c00;
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
#endif
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
case R_SPARC_8:
|
||||
*(char *) reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_16:
|
||||
*(short *) reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_32:
|
||||
*(unsigned int *) reloc_addr = value;
|
||||
break;
|
||||
case R_SPARC_DISP8:
|
||||
*(char *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_DISP16:
|
||||
*(short *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_DISP32:
|
||||
*(unsigned int *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
|
||||
break;
|
||||
case R_SPARC_WDISP30:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & 0xc0000000) |
|
||||
(((value - (Elf64_Addr) reloc_addr) >> 2) & 0x3fffffff));
|
||||
break;
|
||||
|
||||
/* MEDLOW code model relocs */
|
||||
case R_SPARC_LO10:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & ~0x3ff) |
|
||||
(value & 0x3ff));
|
||||
break;
|
||||
case R_SPARC_HI22:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & 0xffc00000) |
|
||||
((value >> 10) & 0x3fffff));
|
||||
break;
|
||||
case R_SPARC_OLO10:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & ~0x1fff) |
|
||||
(((value & 0x3ff) + ELF64_R_TYPE_DATA (reloc->r_info)) & 0x1fff));
|
||||
break;
|
||||
|
||||
/* MEDMID code model relocs */
|
||||
case R_SPARC_H44:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & 0xffc00000) |
|
||||
((value >> 22) & 0x3fffff));
|
||||
break;
|
||||
case R_SPARC_M44:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & ~0x3ff) |
|
||||
((value >> 12) & 0x3ff));
|
||||
break;
|
||||
case R_SPARC_L44:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & ~0xfff) |
|
||||
(value & 0xfff));
|
||||
break;
|
||||
|
||||
/* MEDANY code model relocs */
|
||||
case R_SPARC_HH22:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & 0xffc00000) |
|
||||
(value >> 42));
|
||||
break;
|
||||
case R_SPARC_HM10:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & ~0x3ff) |
|
||||
((value >> 32) & 0x3ff));
|
||||
break;
|
||||
case R_SPARC_LM22:
|
||||
*(unsigned int *) reloc_addr =
|
||||
((*(unsigned int *)reloc_addr & 0xffc00000) |
|
||||
((value >> 10) & 0x003fffff));
|
||||
break;
|
||||
case R_SPARC_UA16:
|
||||
((unsigned char *) reloc_addr_arg) [0] = value >> 8;
|
||||
((unsigned char *) reloc_addr_arg) [1] = value;
|
||||
break;
|
||||
case R_SPARC_UA32:
|
||||
((unsigned char *) reloc_addr_arg) [0] = value >> 24;
|
||||
((unsigned char *) reloc_addr_arg) [1] = value >> 16;
|
||||
((unsigned char *) reloc_addr_arg) [2] = value >> 8;
|
||||
((unsigned char *) reloc_addr_arg) [3] = value;
|
||||
break;
|
||||
case R_SPARC_UA64:
|
||||
if (! ((long) reloc_addr_arg & 3))
|
||||
{
|
||||
/* Common in .eh_frame */
|
||||
((unsigned int *) reloc_addr_arg) [0] = value >> 32;
|
||||
((unsigned int *) reloc_addr_arg) [1] = value;
|
||||
break;
|
||||
}
|
||||
((unsigned char *) reloc_addr_arg) [0] = value >> 56;
|
||||
((unsigned char *) reloc_addr_arg) [1] = value >> 48;
|
||||
((unsigned char *) reloc_addr_arg) [2] = value >> 40;
|
||||
((unsigned char *) reloc_addr_arg) [3] = value >> 32;
|
||||
((unsigned char *) reloc_addr_arg) [4] = value >> 24;
|
||||
((unsigned char *) reloc_addr_arg) [5] = value >> 16;
|
||||
((unsigned char *) reloc_addr_arg) [6] = value >> 8;
|
||||
((unsigned char *) reloc_addr_arg) [7] = value;
|
||||
break;
|
||||
#endif
|
||||
#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
|
||||
default:
|
||||
_dl_reloc_bad_type (map, r_type, 0);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
auto inline void
|
||||
__attribute__ ((always_inline))
|
||||
elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
|
||||
void *const reloc_addr_arg)
|
||||
{
|
||||
Elf64_Addr *const reloc_addr = reloc_addr_arg;
|
||||
*reloc_addr = l_addr + reloc->r_addend;
|
||||
}
|
||||
|
||||
auto inline void
|
||||
__attribute__ ((always_inline))
|
||||
elf_machine_lazy_rel (struct link_map *map,
|
||||
Elf64_Addr l_addr, const Elf64_Rela *reloc)
|
||||
{
|
||||
switch (ELF64_R_TYPE (reloc->r_info))
|
||||
{
|
||||
case R_SPARC_NONE:
|
||||
break;
|
||||
case R_SPARC_JMP_SLOT:
|
||||
break;
|
||||
default:
|
||||
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RESOLVE_MAP */
|
||||
|
327
sysdeps/sparc/sparc64/dl-trampoline.S
Normal file
327
sysdeps/sparc/sparc64/dl-trampoline.S
Normal file
@@ -0,0 +1,327 @@
|
||||
/* PLT trampolines. Sparc 64-bit version.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
.text
|
||||
.align 32
|
||||
|
||||
/* %g1: PLT offset loaded by PLT entry
|
||||
* %g4: callers PC, which is PLT0 + 24, therefore we
|
||||
* add (32 + 8) to get the address of PLT2 which
|
||||
* is where the magic cookie is stored
|
||||
*/
|
||||
.globl _dl_runtime_resolve_0
|
||||
.type _dl_runtime_resolve_0, @function
|
||||
_dl_runtime_resolve_0:
|
||||
cfi_startproc
|
||||
|
||||
save %sp, -192, %sp
|
||||
cfi_def_cfa_register(%fp)
|
||||
cfi_window_save
|
||||
cfi_register(%o7, %i7)
|
||||
|
||||
sethi %hi(1047552), %l2
|
||||
ldx [%g4 + 32 + 8], %o0
|
||||
sub %g1, %g4, %l0
|
||||
xor %l2, -1016, %l2
|
||||
sethi %hi(5120), %l3 /* 160 * 32 */
|
||||
add %l0, %l2, %l0
|
||||
sethi %hi(32768), %l4
|
||||
udivx %l0, %l3, %l3
|
||||
sllx %l3, 2, %l1
|
||||
add %l1, %l3, %l1
|
||||
sllx %l1, 10, %l2
|
||||
sub %l4, 4, %l4
|
||||
sllx %l1, 5, %l1
|
||||
sub %l0, %l2, %l0
|
||||
udivx %l0, 24, %l0
|
||||
add %l0, %l4, %l0
|
||||
add %l1, %l0, %l1
|
||||
add %l1, %l1, %l0
|
||||
add %l0, %l1, %l0
|
||||
call _dl_fixup
|
||||
sllx %l0, 3, %o1
|
||||
jmp %o0
|
||||
restore
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _dl_runtime_resolve_0, .-_dl_runtime_resolve_0
|
||||
|
||||
/* %g1: PLT offset loaded by PLT entry
|
||||
* %g4: callers PC, which is PLT1 + 24, therefore we
|
||||
* add 8 to get the address of PLT2 which
|
||||
* is where the magic cookie is stored
|
||||
*/
|
||||
.globl _dl_runtime_resolve_1
|
||||
.type _dl_runtime_resolve_1, @function
|
||||
_dl_runtime_resolve_1:
|
||||
cfi_startproc
|
||||
|
||||
save %sp, -192, %sp
|
||||
cfi_def_cfa_register(%fp)
|
||||
cfi_window_save
|
||||
cfi_register(%o7, %i7)
|
||||
|
||||
srlx %g1, 12, %o1
|
||||
ldx [%g4 + 8], %o0
|
||||
add %o1, %o1, %o3
|
||||
sub %o1, 96, %o1
|
||||
call _dl_fixup
|
||||
add %o1, %o3, %o1
|
||||
jmp %o0
|
||||
restore
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _dl_runtime_resolve_1, .-_dl_runtime_resolve_1
|
||||
|
||||
/* For the profiling cases we pass in our stack frame
|
||||
* as the base of the La_sparc64_regs, so it looks
|
||||
* like:
|
||||
* %l0 %sp
|
||||
* ...
|
||||
* %l7 %sp + (7 * 8)
|
||||
* %i0 %sp + (8 * 8)
|
||||
* ...
|
||||
* %i7 %sp + (15 * 8)
|
||||
* %f0 %sp + (16 * 8)
|
||||
* %f16 %sp + (31 * 8)
|
||||
* framesize %sp + (32 * 8)
|
||||
*/
|
||||
|
||||
.globl _dl_profile_save_regs
|
||||
.type _dl_profile_save_regs, @function
|
||||
_dl_profile_save_regs:
|
||||
cfi_startproc
|
||||
|
||||
stx %l0, [%sp + STACK_BIAS + ( 0 * 8)]
|
||||
stx %l1, [%sp + STACK_BIAS + ( 1 * 8)]
|
||||
stx %l2, [%sp + STACK_BIAS + ( 2 * 8)]
|
||||
stx %l3, [%sp + STACK_BIAS + ( 3 * 8)]
|
||||
stx %l4, [%sp + STACK_BIAS + ( 4 * 8)]
|
||||
stx %l5, [%sp + STACK_BIAS + ( 5 * 8)]
|
||||
stx %l6, [%sp + STACK_BIAS + ( 6 * 8)]
|
||||
stx %l7, [%sp + STACK_BIAS + ( 7 * 8)]
|
||||
stx %i0, [%sp + STACK_BIAS + ( 8 * 8)]
|
||||
stx %i1, [%sp + STACK_BIAS + ( 9 * 8)]
|
||||
stx %i2, [%sp + STACK_BIAS + (10 * 8)]
|
||||
stx %i3, [%sp + STACK_BIAS + (11 * 8)]
|
||||
stx %i4, [%sp + STACK_BIAS + (12 * 8)]
|
||||
stx %i5, [%sp + STACK_BIAS + (13 * 8)]
|
||||
stx %i6, [%sp + STACK_BIAS + (14 * 8)]
|
||||
stx %i7, [%sp + STACK_BIAS + (15 * 8)]
|
||||
std %f0, [%sp + STACK_BIAS + (16 * 8)]
|
||||
std %f2, [%sp + STACK_BIAS + (17 * 8)]
|
||||
std %f4, [%sp + STACK_BIAS + (18 * 8)]
|
||||
std %f6, [%sp + STACK_BIAS + (19 * 8)]
|
||||
std %f8, [%sp + STACK_BIAS + (20 * 8)]
|
||||
std %f10, [%sp + STACK_BIAS + (21 * 8)]
|
||||
std %f12, [%sp + STACK_BIAS + (22 * 8)]
|
||||
std %f14, [%sp + STACK_BIAS + (23 * 8)]
|
||||
std %f16, [%sp + STACK_BIAS + (24 * 8)]
|
||||
std %f18, [%sp + STACK_BIAS + (25 * 8)]
|
||||
std %f20, [%sp + STACK_BIAS + (26 * 8)]
|
||||
std %f22, [%sp + STACK_BIAS + (27 * 8)]
|
||||
std %f24, [%sp + STACK_BIAS + (28 * 8)]
|
||||
std %f26, [%sp + STACK_BIAS + (29 * 8)]
|
||||
std %f28, [%sp + STACK_BIAS + (30 * 8)]
|
||||
retl
|
||||
std %f30, [%sp + STACK_BIAS + (31 * 8)]
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _dl_profile_save_regs, .-_dl_profile_save_regs
|
||||
|
||||
/* If we are going to call pltexit, then we must replicate
|
||||
* the caller's stack frame.
|
||||
* %o0: PLT resolved function address
|
||||
*/
|
||||
.globl _dl_profile_invoke
|
||||
.type _dl_profile_invoke, @function
|
||||
_dl_profile_invoke:
|
||||
cfi_startproc
|
||||
|
||||
sub %sp, %l0, %sp
|
||||
1:
|
||||
srlx %l0, 3, %l7
|
||||
mov %o0, %l1
|
||||
mov %i0, %o0
|
||||
mov %i1, %o1
|
||||
mov %i2, %o2
|
||||
mov %i3, %o3
|
||||
mov %i4, %o4
|
||||
mov %i5, %o5
|
||||
add %fp, STACK_BIAS, %l2
|
||||
add %sp, STACK_BIAS, %l3
|
||||
1: ldx [%l2], %l4
|
||||
add %l2, 0x8, %l2
|
||||
subcc %l7, 1, %l7
|
||||
stx %l4, [%l3]
|
||||
bne,pt %xcc, 1b
|
||||
add %l3, 0x8, %l3
|
||||
|
||||
jmpl %l1, %o7
|
||||
nop
|
||||
|
||||
stx %o0, [%sp + STACK_BIAS + (16 * 8)]
|
||||
stx %o1, [%sp + STACK_BIAS + (17 * 8)]
|
||||
stx %o2, [%sp + STACK_BIAS + (18 * 8)]
|
||||
stx %o3, [%sp + STACK_BIAS + (19 * 8)]
|
||||
std %f0, [%sp + STACK_BIAS + (20 * 8)]
|
||||
std %f2, [%sp + STACK_BIAS + (21 * 8)]
|
||||
std %f4, [%sp + STACK_BIAS + (22 * 8)]
|
||||
std %f8, [%sp + STACK_BIAS + (23 * 8)]
|
||||
|
||||
mov %l5, %o0
|
||||
mov %l6, %o1
|
||||
add %sp, %l0, %o2
|
||||
add %sp, STACK_BIAS + (16 * 8), %o3
|
||||
call _dl_call_pltexit
|
||||
add %o2, STACK_BIAS, %o2
|
||||
|
||||
ldx [%sp + STACK_BIAS + (16 * 8)], %i0
|
||||
ldx [%sp + STACK_BIAS + (17 * 8)], %i1
|
||||
ldx [%sp + STACK_BIAS + (18 * 8)], %i2
|
||||
ldx [%sp + STACK_BIAS + (19 * 8)], %i3
|
||||
|
||||
jmpl %i7 + 8, %g0
|
||||
restore
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _dl_profile_invoke, .-_dl_profile_invoke
|
||||
|
||||
/* %g1: PLT offset loaded by PLT entry
|
||||
* %g4: callers PC, which is PLT0 + 24, therefore we
|
||||
* add (32 + 8) to get the address of PLT2 which
|
||||
* is where the magic cookie is stored
|
||||
*/
|
||||
.align 32
|
||||
.globl _dl_runtime_profile_0
|
||||
.type _dl_runtime_profile_0, @function
|
||||
_dl_runtime_profile_0:
|
||||
cfi_startproc
|
||||
|
||||
brz,a,pn %fp, 1f
|
||||
mov 192, %g5
|
||||
sub %fp, %sp, %g5
|
||||
1: save %sp, -336, %sp
|
||||
cfi_def_cfa_register(%fp)
|
||||
cfi_window_save
|
||||
cfi_register(%o7, %i7)
|
||||
|
||||
sethi %hi(1047552), %l2
|
||||
ldx [%g4 + 32 + 8], %o0
|
||||
sub %g1, %g4, %l0
|
||||
xor %l2, -1016, %l2
|
||||
sethi %hi(5120), %l3 /* 160 * 32 */
|
||||
add %l0, %l2, %l0
|
||||
sethi %hi(32768), %l4
|
||||
udivx %l0, %l3, %l3
|
||||
sllx %l3, 2, %l1
|
||||
add %l1, %l3, %l1
|
||||
sllx %l1, 10, %l2
|
||||
sub %l4, 4, %l4
|
||||
sllx %l1, 5, %l1
|
||||
sub %l0, %l2, %l0
|
||||
udivx %l0, 24, %l0
|
||||
add %l0, %l4, %l0
|
||||
add %l1, %l0, %l1
|
||||
add %l1, %l1, %l0
|
||||
add %l0, %l1, %l0
|
||||
|
||||
mov %i7, %o2
|
||||
sllx %l0, 3, %o1
|
||||
|
||||
mov %g5, %l0
|
||||
mov %o0, %l5
|
||||
mov %o1, %l6
|
||||
|
||||
call _dl_profile_save_regs
|
||||
nop
|
||||
|
||||
add %sp, STACK_BIAS, %o3
|
||||
call _dl_profile_fixup
|
||||
add %sp, (STACK_BIAS + (32 * 8)), %o4
|
||||
|
||||
ldx [%sp + STACK_BIAS + (32 * 8)], %o1
|
||||
brgez,pt %o1, 1f
|
||||
nop
|
||||
|
||||
call _dl_profile_invoke
|
||||
nop
|
||||
|
||||
1: jmp %o0
|
||||
restore
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _dl_runtime_profile_0, .-_dl_runtime_profile_0
|
||||
|
||||
/* %g1: PLT offset loaded by PLT entry
|
||||
* %g4: callers PC, which is PLT1 + 24, therefore we
|
||||
* add 8 to get the address of PLT2 which
|
||||
* is where the magic cookie is stored
|
||||
*/
|
||||
.globl _dl_runtime_profile_1
|
||||
.type _dl_runtime_profile_1, @function
|
||||
_dl_runtime_profile_1:
|
||||
cfi_startproc
|
||||
|
||||
brz,a,pn %fp, 1f
|
||||
mov 192, %g5
|
||||
sub %fp, %sp, %g5
|
||||
1: save %sp, -336, %sp
|
||||
cfi_def_cfa_register(%fp)
|
||||
cfi_window_save
|
||||
cfi_register(%o7, %i7)
|
||||
|
||||
srlx %g1, 12, %o1
|
||||
ldx [%g4 + 8], %o0
|
||||
add %o1, %o1, %o3
|
||||
sub %o1, 96, %o1
|
||||
mov %i7, %o2
|
||||
add %o1, %o3, %o1
|
||||
|
||||
mov %g5, %l0
|
||||
mov %o0, %l5
|
||||
mov %o1, %l6
|
||||
|
||||
call _dl_profile_save_regs
|
||||
nop
|
||||
|
||||
add %sp, STACK_BIAS, %o3
|
||||
call _dl_profile_fixup
|
||||
add %sp, (STACK_BIAS + (32 * 8)), %o4
|
||||
|
||||
ldx [%sp + STACK_BIAS + (32 * 8)], %o1
|
||||
brgez,pt %o1, 1f
|
||||
nop
|
||||
|
||||
call _dl_profile_invoke
|
||||
nop
|
||||
|
||||
1: jmp %o0
|
||||
restore
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _dl_runtime_resolve_1, .-_dl_runtime_resolve_1
|
@@ -48,6 +48,7 @@
|
||||
.global _start
|
||||
.type _start,#function
|
||||
_start:
|
||||
cfi_startproc
|
||||
|
||||
#ifdef SHARED
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7
|
||||
@@ -59,6 +60,7 @@ _start:
|
||||
drop their arguments. */
|
||||
mov %g0, %fp
|
||||
sub %sp, 6*8, %sp
|
||||
cfi_adjust_cfa_offset(6*8)
|
||||
|
||||
/* Extract the arguments and environment as encoded on the stack. The
|
||||
argument info starts after one register window (16 words) past the SP,
|
||||
@@ -92,4 +94,12 @@ _start:
|
||||
/* Die very horribly if exit returns. */
|
||||
illtrap 0
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.size _start, .-_start
|
||||
|
||||
/* Define a symbol for the first piece of initialized data. */
|
||||
.data
|
||||
.globl __data_start
|
||||
__data_start:
|
||||
weak_alias (__data_start, data_start)
|
||||
|
@@ -33,14 +33,14 @@ ildouble: 1
|
||||
ldouble: 1
|
||||
|
||||
# cacosh
|
||||
Test "Real part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i":
|
||||
Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
|
||||
double: 1
|
||||
float: 7
|
||||
idouble: 1
|
||||
ifloat: 7
|
||||
ildouble: 5
|
||||
ldouble: 5
|
||||
Test "Imaginary part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i":
|
||||
Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
|
||||
double: 1
|
||||
float: 3
|
||||
idouble: 1
|
||||
@@ -465,6 +465,11 @@ ifloat: 2
|
||||
ildouble: 1
|
||||
ldouble: 1
|
||||
|
||||
# exp2
|
||||
Test "exp2 (10) == 1024":
|
||||
ildouble: 2
|
||||
ldouble: 2
|
||||
|
||||
# expm1
|
||||
Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
|
||||
double: 1
|
||||
@@ -1192,6 +1197,10 @@ ifloat: 2
|
||||
ildouble: 1
|
||||
ldouble: 1
|
||||
|
||||
Function: "exp2":
|
||||
ildouble: 2
|
||||
ldouble: 2
|
||||
|
||||
Function: "expm1":
|
||||
double: 1
|
||||
float: 1
|
||||
|
37
sysdeps/sparc/sparc64/jmpbuf-unwind.h
Normal file
37
sysdeps/sparc/sparc64/jmpbuf-unwind.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by David S. Miller <davem@davemloft.net>, 2005.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdint.h>
|
||||
#include <unwind.h>
|
||||
|
||||
/* Test if longjmp to JMPBUF would unwind the frame
|
||||
containing a local variable at ADDRESS. */
|
||||
#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
|
||||
((unsigned long int) (address) < (jmpbuf)->uc_mcontext.mc_fp + 2047)
|
||||
|
||||
#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
|
||||
_JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
|
||||
|
||||
#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
|
||||
((uintptr_t) (_address) - (_adj) \
|
||||
< (uintptr_t) (_jmpbuf)[0].uc_mcontext.mc_fp + 2047 - (_adj))
|
||||
|
||||
/* We use the normal lobngjmp for unwinding. */
|
||||
#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
|
@@ -139,5 +139,5 @@ ENTRY(memcmp)
|
||||
END(memcmp)
|
||||
|
||||
#undef bcmp
|
||||
weak_alias(memcmp, bcmp)
|
||||
weak_alias (memcmp, bcmp)
|
||||
libc_hidden_builtin_def (memcmp)
|
||||
|
@@ -209,6 +209,7 @@ ENTRY(bcopy)
|
||||
END(bcopy)
|
||||
|
||||
.align 32
|
||||
ENTRY(__memcpy_large)
|
||||
200: be,pt %xcc, 201f /* CTI */
|
||||
andcc %o0, 0x38, %g5 /* IEU1 Group */
|
||||
mov 8, %g1 /* IEU0 */
|
||||
@@ -443,6 +444,7 @@ END(bcopy)
|
||||
stb %o5, [%o0 - 1] /* Store */
|
||||
209: retl
|
||||
mov %g4, %o0
|
||||
END(__memcpy_large)
|
||||
|
||||
#ifdef USE_BPR
|
||||
|
||||
@@ -698,6 +700,7 @@ ENTRY(memcpy)
|
||||
END(memcpy)
|
||||
|
||||
.align 32
|
||||
ENTRY(__memmove_slowpath)
|
||||
228: andcc %o2, 1, %g0 /* IEU1 Group */
|
||||
be,pt %icc, 2f+4 /* CTI */
|
||||
1: ldub [%o1 - 1], %o5 /* LOAD Group */
|
||||
@@ -718,6 +721,7 @@ END(memcpy)
|
||||
mov %g4, %o0
|
||||
219: retl
|
||||
nop
|
||||
END(__memmove_slowpath)
|
||||
|
||||
.align 32
|
||||
ENTRY(memmove)
|
||||
@@ -914,8 +918,8 @@ ENTRY(memmove)
|
||||
END(memmove)
|
||||
|
||||
#ifdef USE_BPR
|
||||
weak_alias(memcpy, __align_cpy_1)
|
||||
weak_alias(memcpy, __align_cpy_2)
|
||||
weak_alias (memcpy, __align_cpy_1)
|
||||
weak_alias (memcpy, __align_cpy_2)
|
||||
#endif
|
||||
libc_hidden_builtin_def (memcpy)
|
||||
libc_hidden_builtin_def (memmove)
|
||||
|
@@ -312,4 +312,4 @@ ENTRY(__bzero)
|
||||
mov %o5, %o0
|
||||
END(__bzero)
|
||||
|
||||
weak_alias(__bzero, bzero)
|
||||
weak_alias (__bzero, bzero)
|
||||
|
@@ -1,32 +0,0 @@
|
||||
qp_add.c
|
||||
qp_cmp.c
|
||||
qp_cmpe.c
|
||||
qp_div.c
|
||||
qp_dtoq.c
|
||||
qp_feq.c
|
||||
qp_fge.c
|
||||
qp_fgt.c
|
||||
qp_fle.c
|
||||
qp_flt.c
|
||||
qp_fne.c
|
||||
qp_itoq.c
|
||||
qp_mul.c
|
||||
qp_neg.S
|
||||
qp_qtod.c
|
||||
qp_qtoi.c
|
||||
qp_qtos.c
|
||||
qp_qtoui.c
|
||||
qp_qtoux.c
|
||||
qp_qtox.c
|
||||
qp_sqrt.c
|
||||
qp_stoq.c
|
||||
qp_sub.c
|
||||
qp_uitoq.c
|
||||
qp_util.c
|
||||
qp_uxtoq.c
|
||||
qp_xtoq.c
|
||||
s_frexpl.c
|
||||
s_ilogbl.c
|
||||
s_scalblnl.c
|
||||
s_scalbnl.c
|
||||
sfp-machine.h
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
(*c) = (*a) + (*b)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -29,10 +29,10 @@ void _Qp_add(long double *c, const long double *a, const long double *b)
|
||||
FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_QP(A, a);
|
||||
FP_UNPACK_QP(B, b);
|
||||
FP_UNPACK_SEMIRAW_QP(A, a);
|
||||
FP_UNPACK_SEMIRAW_QP(B, b);
|
||||
FP_ADD_Q(C, A, B);
|
||||
FP_PACK_QP(c, C);
|
||||
FP_PACK_SEMIRAW_QP(c, C);
|
||||
QP_HANDLE_EXCEPTIONS(__asm (
|
||||
" ldd [%1], %%f52\n"
|
||||
" ldd [%1+8], %%f54\n"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
(*c) = (long double)(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -31,13 +31,13 @@ void _Qp_dtoq(long double *c, const double a)
|
||||
FP_DECL_Q(C);
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_D(A, a);
|
||||
FP_UNPACK_RAW_D(A, a);
|
||||
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
|
||||
FP_CONV(Q,D,4,2,C,A);
|
||||
FP_EXTEND(Q,D,4,2,C,A);
|
||||
#else
|
||||
FP_CONV(Q,D,2,1,C,A);
|
||||
FP_EXTEND(Q,D,2,1,C,A);
|
||||
#endif
|
||||
FP_PACK_QP(c, C);
|
||||
FP_PACK_RAW_QP(c, C);
|
||||
QP_HANDLE_EXCEPTIONS(__asm (
|
||||
" fdtoq %1, %%f60\n"
|
||||
" std %%f60, [%0]\n"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
(*c) = (long double)(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -29,7 +29,7 @@ void _Qp_itoq(long double *c, const int a)
|
||||
FP_DECL_Q(C);
|
||||
int b = a;
|
||||
|
||||
FP_FROM_INT_Q(C, b, 32, int);
|
||||
FP_PACK_QP(c, C);
|
||||
FP_FROM_INT_Q(C, b, 32, unsigned int);
|
||||
FP_PACK_RAW_QP(c, C);
|
||||
QP_NO_EXCEPTIONS;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (double)(*a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -32,13 +32,13 @@ double _Qp_qtod(const long double *a)
|
||||
double r;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_QP(A, a);
|
||||
FP_UNPACK_SEMIRAW_QP(A, a);
|
||||
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
|
||||
FP_CONV(D,Q,2,4,R,A);
|
||||
FP_TRUNC(D,Q,2,4,R,A);
|
||||
#else
|
||||
FP_CONV(D,Q,1,2,R,A);
|
||||
FP_TRUNC(D,Q,1,2,R,A);
|
||||
#endif
|
||||
FP_PACK_D(r, R);
|
||||
FP_PACK_SEMIRAW_D(r, R);
|
||||
QP_HANDLE_EXCEPTIONS(__asm (
|
||||
" ldd [%1], %%f52\n"
|
||||
" ldd [%1+8], %%f54\n"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (int)(*a)
|
||||
Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999, 2004, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -28,10 +28,10 @@ int _Qp_qtoi(const long double *a)
|
||||
{
|
||||
FP_DECL_EX;
|
||||
FP_DECL_Q(A);
|
||||
int r;
|
||||
unsigned int r;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_QP(A, a);
|
||||
FP_UNPACK_RAW_QP(A, a);
|
||||
FP_TO_INT_Q(r, A, 32, 1);
|
||||
QP_HANDLE_EXCEPTIONS(
|
||||
int rx;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (float)(*a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -32,13 +32,13 @@ float _Qp_qtos(const long double *a)
|
||||
float r;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_QP(A, a);
|
||||
FP_UNPACK_SEMIRAW_QP(A, a);
|
||||
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
|
||||
FP_CONV(S,Q,1,4,R,A);
|
||||
FP_TRUNC(S,Q,1,4,R,A);
|
||||
#else
|
||||
FP_CONV(S,Q,1,2,R,A);
|
||||
FP_TRUNC(S,Q,1,2,R,A);
|
||||
#endif
|
||||
FP_PACK_S(r, R);
|
||||
FP_PACK_SEMIRAW_S(r, R);
|
||||
|
||||
QP_HANDLE_EXCEPTIONS(__asm (
|
||||
" ldd [%1], %%f52\n"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (unsigned int)(*a)
|
||||
Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999, 2004, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -31,7 +31,7 @@ unsigned int _Qp_qtoui(const long double *a)
|
||||
unsigned int r;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_QP(A, a);
|
||||
FP_UNPACK_RAW_QP(A, a);
|
||||
FP_TO_INT_Q(r, A, 32, -1);
|
||||
QP_HANDLE_EXCEPTIONS(
|
||||
int rx;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (unsigned long)(*a)
|
||||
Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999, 2004, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -31,7 +31,7 @@ unsigned long _Qp_qtoux(const long double *a)
|
||||
unsigned long r;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_QP(A, a);
|
||||
FP_UNPACK_RAW_QP(A, a);
|
||||
FP_TO_INT_Q(r, A, 64, -1);
|
||||
QP_HANDLE_EXCEPTIONS(
|
||||
unsigned long rx;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
Return (long)(*a)
|
||||
Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1999, 2004, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -28,10 +28,10 @@ long _Qp_qtox(const long double *a)
|
||||
{
|
||||
FP_DECL_EX;
|
||||
FP_DECL_Q(A);
|
||||
long r;
|
||||
unsigned long r;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_QP(A, a);
|
||||
FP_UNPACK_RAW_QP(A, a);
|
||||
FP_TO_INT_Q(r, A, 64, 1);
|
||||
QP_HANDLE_EXCEPTIONS(
|
||||
long rx;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
(*c) = (long double)(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -31,13 +31,13 @@ void _Qp_stoq(long double *c, const float a)
|
||||
FP_DECL_Q(C);
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_S(A, a);
|
||||
FP_UNPACK_RAW_S(A, a);
|
||||
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
|
||||
FP_CONV(Q,S,4,1,C,A);
|
||||
FP_EXTEND(Q,S,4,1,C,A);
|
||||
#else
|
||||
FP_CONV(Q,S,2,1,C,A);
|
||||
FP_EXTEND(Q,S,2,1,C,A);
|
||||
#endif
|
||||
FP_PACK_QP(c, C);
|
||||
FP_PACK_RAW_QP(c, C);
|
||||
QP_HANDLE_EXCEPTIONS(__asm (
|
||||
" fstoq %1, %%f60\n"
|
||||
" std %%f60, [%0]\n"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
(*c) = (*a) - (*b)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -29,10 +29,10 @@ void _Qp_sub(long double *c, const long double *a, const long double *b)
|
||||
FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_QP(A, a);
|
||||
FP_UNPACK_QP(B, b);
|
||||
FP_UNPACK_SEMIRAW_QP(A, a);
|
||||
FP_UNPACK_SEMIRAW_QP(B, b);
|
||||
FP_SUB_Q(C, A, B);
|
||||
FP_PACK_QP(c, C);
|
||||
FP_PACK_SEMIRAW_QP(c, C);
|
||||
QP_HANDLE_EXCEPTIONS(__asm (
|
||||
" ldd [%1], %%f52\n"
|
||||
" ldd [%1+8], %%f54\n"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
(*c) = (long double)(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -29,7 +29,7 @@ void _Qp_uitoq(long double *c, const unsigned int a)
|
||||
FP_DECL_Q(C);
|
||||
unsigned int b = a;
|
||||
|
||||
FP_FROM_INT_Q(C, b, 32, int);
|
||||
FP_PACK_QP(c, C);
|
||||
FP_FROM_INT_Q(C, b, 32, unsigned int);
|
||||
FP_PACK_RAW_QP(c, C);
|
||||
QP_NO_EXCEPTIONS;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
(*c) = (long double)(a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -29,7 +29,7 @@ void _Qp_uxtoq(long double *c, const unsigned long a)
|
||||
FP_DECL_Q(C);
|
||||
unsigned long b = a;
|
||||
|
||||
FP_FROM_INT_Q(C, b, 64, long);
|
||||
FP_PACK_QP(c, C);
|
||||
FP_FROM_INT_Q(C, b, 64, unsigned long);
|
||||
FP_PACK_RAW_QP(c, C);
|
||||
QP_NO_EXCEPTIONS;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Software floating-point emulation.
|
||||
(*c) = (long double)(*a)
|
||||
Copyright (C) 1997,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com) and
|
||||
Jakub Jelinek (jj@ultra.linux.cz).
|
||||
@@ -29,7 +29,7 @@ void _Qp_xtoq(long double *c, const long a)
|
||||
FP_DECL_Q(C);
|
||||
long b = a;
|
||||
|
||||
FP_FROM_INT_Q(C, b, 64, long);
|
||||
FP_PACK_QP(c, C);
|
||||
FP_FROM_INT_Q(C, b, 64, unsigned long);
|
||||
FP_PACK_RAW_QP(c, C);
|
||||
QP_NO_EXCEPTIONS;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Machine-dependent software floating-point definitions.
|
||||
Sparc64 userland (_Q_* and _Qp_*) version.
|
||||
Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 1999, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson (rth@cygnus.com),
|
||||
Jakub Jelinek (jj@ultra.linux.cz) and
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <fpu_control.h>
|
||||
#include <fenv.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define _FP_W_TYPE_SIZE 64
|
||||
#define _FP_W_TYPE unsigned long
|
||||
|
@@ -600,11 +600,11 @@ ENTRY(memmove)
|
||||
END(memmove)
|
||||
|
||||
#ifdef USE_BPR
|
||||
weak_alias(memcpy, __align_cpy_1)
|
||||
weak_alias(memcpy, __align_cpy_2)
|
||||
weak_alias(memcpy, __align_cpy_4)
|
||||
weak_alias(memcpy, __align_cpy_8)
|
||||
weak_alias(memcpy, __align_cpy_16)
|
||||
weak_alias (memcpy, __align_cpy_1)
|
||||
weak_alias (memcpy, __align_cpy_2)
|
||||
weak_alias (memcpy, __align_cpy_4)
|
||||
weak_alias (memcpy, __align_cpy_8)
|
||||
weak_alias (memcpy, __align_cpy_16)
|
||||
#endif
|
||||
libc_hidden_builtin_def (memcpy)
|
||||
libc_hidden_builtin_def (memmove)
|
||||
|
593
sysdeps/sparc/sparc64/sparcv9v/memcpy.S
Normal file
593
sysdeps/sparc/sparc64/sparcv9v/memcpy.S
Normal file
@@ -0,0 +1,593 @@
|
||||
/* Copy SIZE bytes from SRC to DEST. For SUN4V Niagara.
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by David S. Miller (davem@davemloft.net)
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
#define ASI_BLK_INIT_QUAD_LDD_P 0xe2
|
||||
#define ASI_P 0x80
|
||||
#define ASI_PNF 0x82
|
||||
|
||||
#define LOAD(type,addr,dest) type##a [addr] ASI_P, dest
|
||||
#define LOAD_TWIN(addr_reg,dest0,dest1) \
|
||||
ldda [addr_reg] ASI_BLK_INIT_QUAD_LDD_P, dest0
|
||||
|
||||
#define STORE(type,src,addr) type src, [addr]
|
||||
#define STORE_INIT(src,addr) stxa src, [addr] %asi
|
||||
|
||||
#ifndef XCC
|
||||
#define USE_BPR
|
||||
#define XCC xcc
|
||||
#endif
|
||||
|
||||
.register %g2,#scratch
|
||||
.register %g3,#scratch
|
||||
.register %g6,#scratch
|
||||
|
||||
.text
|
||||
.align 32
|
||||
|
||||
ENTRY(bcopy)
|
||||
sub %o1, %o0, %o4
|
||||
mov %o0, %g4
|
||||
cmp %o4, %o2
|
||||
mov %o1, %o0
|
||||
bgeu,pt %XCC, 100f
|
||||
mov %g4, %o1
|
||||
#ifndef USE_BPR
|
||||
srl %o2, 0, %o2
|
||||
#endif
|
||||
brnz,pn %o2, 220f
|
||||
add %o0, %o2, %o0
|
||||
retl
|
||||
nop
|
||||
END(bcopy)
|
||||
|
||||
.align 32
|
||||
ENTRY(memcpy)
|
||||
100: /* %o0=dst, %o1=src, %o2=len */
|
||||
mov %o0, %g5
|
||||
cmp %o2, 0
|
||||
be,pn %XCC, 85f
|
||||
218: or %o0, %o1, %o3
|
||||
cmp %o2, 16
|
||||
blu,a,pn %XCC, 80f
|
||||
or %o3, %o2, %o3
|
||||
|
||||
/* 2 blocks (128 bytes) is the minimum we can do the block
|
||||
* copy with. We need to ensure that we'll iterate at least
|
||||
* once in the block copy loop. At worst we'll need to align
|
||||
* the destination to a 64-byte boundary which can chew up
|
||||
* to (64 - 1) bytes from the length before we perform the
|
||||
* block copy loop.
|
||||
*/
|
||||
cmp %o2, (2 * 64)
|
||||
blu,pt %XCC, 70f
|
||||
andcc %o3, 0x7, %g0
|
||||
|
||||
/* %o0: dst
|
||||
* %o1: src
|
||||
* %o2: len (known to be >= 128)
|
||||
*
|
||||
* The block copy loops will use %o4/%o5,%g2/%g3 as
|
||||
* temporaries while copying the data.
|
||||
*/
|
||||
|
||||
LOAD(prefetch, %o1, #one_read)
|
||||
wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
|
||||
|
||||
/* Align destination on 64-byte boundary. */
|
||||
andcc %o0, (64 - 1), %o4
|
||||
be,pt %XCC, 2f
|
||||
sub %o4, 64, %o4
|
||||
sub %g0, %o4, %o4 ! bytes to align dst
|
||||
sub %o2, %o4, %o2
|
||||
1: subcc %o4, 1, %o4
|
||||
LOAD(ldub, %o1, %g1)
|
||||
STORE(stb, %g1, %o0)
|
||||
add %o1, 1, %o1
|
||||
bne,pt %XCC, 1b
|
||||
add %o0, 1, %o0
|
||||
|
||||
/* If the source is on a 16-byte boundary we can do
|
||||
* the direct block copy loop. If it is 8-byte aligned
|
||||
* we can do the 16-byte loads offset by -8 bytes and the
|
||||
* init stores offset by one register.
|
||||
*
|
||||
* If the source is not even 8-byte aligned, we need to do
|
||||
* shifting and masking (basically integer faligndata).
|
||||
*
|
||||
* The careful bit with init stores is that if we store
|
||||
* to any part of the cache line we have to store the whole
|
||||
* cacheline else we can end up with corrupt L2 cache line
|
||||
* contents. Since the loop works on 64-bytes of 64-byte
|
||||
* aligned store data at a time, this is easy to ensure.
|
||||
*/
|
||||
2:
|
||||
andcc %o1, (16 - 1), %o4
|
||||
andn %o2, (64 - 1), %g1 ! block copy loop iterator
|
||||
sub %o2, %g1, %o2 ! final sub-block copy bytes
|
||||
be,pt %XCC, 50f
|
||||
cmp %o4, 8
|
||||
be,a,pt %XCC, 10f
|
||||
sub %o1, 0x8, %o1
|
||||
|
||||
/* Neither 8-byte nor 16-byte aligned, shift and mask. */
|
||||
mov %g1, %o4
|
||||
and %o1, 0x7, %g1
|
||||
sll %g1, 3, %g1
|
||||
mov 64, %o3
|
||||
andn %o1, 0x7, %o1
|
||||
LOAD(ldx, %o1, %g2)
|
||||
sub %o3, %g1, %o3
|
||||
sllx %g2, %g1, %g2
|
||||
|
||||
#define SWIVEL_ONE_DWORD(SRC, TMP1, TMP2, PRE_VAL, PRE_SHIFT, POST_SHIFT, DST)\
|
||||
LOAD(ldx, SRC, TMP1); \
|
||||
srlx TMP1, PRE_SHIFT, TMP2; \
|
||||
or TMP2, PRE_VAL, TMP2; \
|
||||
STORE_INIT(TMP2, DST); \
|
||||
sllx TMP1, POST_SHIFT, PRE_VAL;
|
||||
|
||||
1: add %o1, 0x8, %o1
|
||||
SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x00)
|
||||
add %o1, 0x8, %o1
|
||||
SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x08)
|
||||
add %o1, 0x8, %o1
|
||||
SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x10)
|
||||
add %o1, 0x8, %o1
|
||||
SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x18)
|
||||
add %o1, 32, %o1
|
||||
LOAD(prefetch, %o1, #one_read)
|
||||
sub %o1, 32 - 8, %o1
|
||||
SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x20)
|
||||
add %o1, 8, %o1
|
||||
SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x28)
|
||||
add %o1, 8, %o1
|
||||
SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x30)
|
||||
add %o1, 8, %o1
|
||||
SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x38)
|
||||
subcc %o4, 64, %o4
|
||||
bne,pt %XCC, 1b
|
||||
add %o0, 64, %o0
|
||||
|
||||
#undef SWIVEL_ONE_DWORD
|
||||
|
||||
srl %g1, 3, %g1
|
||||
ba,pt %XCC, 60f
|
||||
add %o1, %g1, %o1
|
||||
|
||||
10: /* Destination is 64-byte aligned, source was only 8-byte
|
||||
* aligned but it has been subtracted by 8 and we perform
|
||||
* one twin load ahead, then add 8 back into source when
|
||||
* we finish the loop.
|
||||
*/
|
||||
LOAD_TWIN(%o1, %o4, %o5)
|
||||
1: add %o1, 16, %o1
|
||||
LOAD_TWIN(%o1, %g2, %g3)
|
||||
add %o1, 16 + 32, %o1
|
||||
LOAD(prefetch, %o1, #one_read)
|
||||
sub %o1, 32, %o1
|
||||
STORE_INIT(%o5, %o0 + 0x00) ! initializes cache line
|
||||
STORE_INIT(%g2, %o0 + 0x08)
|
||||
LOAD_TWIN(%o1, %o4, %o5)
|
||||
add %o1, 16, %o1
|
||||
STORE_INIT(%g3, %o0 + 0x10)
|
||||
STORE_INIT(%o4, %o0 + 0x18)
|
||||
LOAD_TWIN(%o1, %g2, %g3)
|
||||
add %o1, 16, %o1
|
||||
STORE_INIT(%o5, %o0 + 0x20)
|
||||
STORE_INIT(%g2, %o0 + 0x28)
|
||||
LOAD_TWIN(%o1, %o4, %o5)
|
||||
STORE_INIT(%g3, %o0 + 0x30)
|
||||
STORE_INIT(%o4, %o0 + 0x38)
|
||||
subcc %g1, 64, %g1
|
||||
bne,pt %XCC, 1b
|
||||
add %o0, 64, %o0
|
||||
|
||||
ba,pt %XCC, 60f
|
||||
add %o1, 0x8, %o1
|
||||
|
||||
50: /* Destination is 64-byte aligned, and source is 16-byte
|
||||
* aligned.
|
||||
*/
|
||||
1: LOAD_TWIN(%o1, %o4, %o5)
|
||||
add %o1, 16, %o1
|
||||
LOAD_TWIN(%o1, %g2, %g3)
|
||||
add %o1, 16 + 32, %o1
|
||||
LOAD(prefetch, %o1, #one_read)
|
||||
sub %o1, 32, %o1
|
||||
STORE_INIT(%o4, %o0 + 0x00) ! initializes cache line
|
||||
STORE_INIT(%o5, %o0 + 0x08)
|
||||
LOAD_TWIN(%o1, %o4, %o5)
|
||||
add %o1, 16, %o1
|
||||
STORE_INIT(%g2, %o0 + 0x10)
|
||||
STORE_INIT(%g3, %o0 + 0x18)
|
||||
LOAD_TWIN(%o1, %g2, %g3)
|
||||
add %o1, 16, %o1
|
||||
STORE_INIT(%o4, %o0 + 0x20)
|
||||
STORE_INIT(%o5, %o0 + 0x28)
|
||||
STORE_INIT(%g2, %o0 + 0x30)
|
||||
STORE_INIT(%g3, %o0 + 0x38)
|
||||
subcc %g1, 64, %g1
|
||||
bne,pt %XCC, 1b
|
||||
add %o0, 64, %o0
|
||||
/* fall through */
|
||||
|
||||
60:
|
||||
/* %o2 contains any final bytes still needed to be copied
|
||||
* over. If anything is left, we copy it one byte at a time.
|
||||
*/
|
||||
wr %g0, ASI_PNF, %asi
|
||||
brz,pt %o2, 85f
|
||||
sub %o0, %o1, %o3
|
||||
ba,a,pt %XCC, 90f
|
||||
|
||||
.align 64
|
||||
70: /* 16 < len <= 64 */
|
||||
bne,pn %XCC, 75f
|
||||
sub %o0, %o1, %o3
|
||||
|
||||
72:
|
||||
andn %o2, 0xf, %o4
|
||||
and %o2, 0xf, %o2
|
||||
1: subcc %o4, 0x10, %o4
|
||||
LOAD(ldx, %o1, %o5)
|
||||
add %o1, 0x08, %o1
|
||||
LOAD(ldx, %o1, %g1)
|
||||
sub %o1, 0x08, %o1
|
||||
STORE(stx, %o5, %o1 + %o3)
|
||||
add %o1, 0x8, %o1
|
||||
STORE(stx, %g1, %o1 + %o3)
|
||||
bgu,pt %XCC, 1b
|
||||
add %o1, 0x8, %o1
|
||||
73: andcc %o2, 0x8, %g0
|
||||
be,pt %XCC, 1f
|
||||
nop
|
||||
sub %o2, 0x8, %o2
|
||||
LOAD(ldx, %o1, %o5)
|
||||
STORE(stx, %o5, %o1 + %o3)
|
||||
add %o1, 0x8, %o1
|
||||
1: andcc %o2, 0x4, %g0
|
||||
be,pt %XCC, 1f
|
||||
nop
|
||||
sub %o2, 0x4, %o2
|
||||
LOAD(lduw, %o1, %o5)
|
||||
STORE(stw, %o5, %o1 + %o3)
|
||||
add %o1, 0x4, %o1
|
||||
1: cmp %o2, 0
|
||||
be,pt %XCC, 85f
|
||||
nop
|
||||
ba,pt %XCC, 90f
|
||||
nop
|
||||
|
||||
75:
|
||||
andcc %o0, 0x7, %g1
|
||||
sub %g1, 0x8, %g1
|
||||
be,pn %icc, 2f
|
||||
sub %g0, %g1, %g1
|
||||
sub %o2, %g1, %o2
|
||||
|
||||
1: subcc %g1, 1, %g1
|
||||
LOAD(ldub, %o1, %o5)
|
||||
STORE(stb, %o5, %o1 + %o3)
|
||||
bgu,pt %icc, 1b
|
||||
add %o1, 1, %o1
|
||||
|
||||
2: add %o1, %o3, %o0
|
||||
andcc %o1, 0x7, %g1
|
||||
bne,pt %icc, 8f
|
||||
sll %g1, 3, %g1
|
||||
|
||||
cmp %o2, 16
|
||||
bgeu,pt %icc, 72b
|
||||
nop
|
||||
ba,a,pt %XCC, 73b
|
||||
|
||||
8: mov 64, %o3
|
||||
andn %o1, 0x7, %o1
|
||||
LOAD(ldx, %o1, %g2)
|
||||
sub %o3, %g1, %o3
|
||||
andn %o2, 0x7, %o4
|
||||
sllx %g2, %g1, %g2
|
||||
1: add %o1, 0x8, %o1
|
||||
LOAD(ldx, %o1, %g3)
|
||||
subcc %o4, 0x8, %o4
|
||||
srlx %g3, %o3, %o5
|
||||
or %o5, %g2, %o5
|
||||
STORE(stx, %o5, %o0)
|
||||
add %o0, 0x8, %o0
|
||||
bgu,pt %icc, 1b
|
||||
sllx %g3, %g1, %g2
|
||||
|
||||
srl %g1, 3, %g1
|
||||
andcc %o2, 0x7, %o2
|
||||
be,pn %icc, 85f
|
||||
add %o1, %g1, %o1
|
||||
ba,pt %XCC, 90f
|
||||
sub %o0, %o1, %o3
|
||||
|
||||
.align 64
|
||||
80: /* 0 < len <= 16 */
|
||||
andcc %o3, 0x3, %g0
|
||||
bne,pn %XCC, 90f
|
||||
sub %o0, %o1, %o3
|
||||
|
||||
1:
|
||||
subcc %o2, 4, %o2
|
||||
LOAD(lduw, %o1, %g1)
|
||||
STORE(stw, %g1, %o1 + %o3)
|
||||
bgu,pt %XCC, 1b
|
||||
add %o1, 4, %o1
|
||||
|
||||
85: retl
|
||||
mov %g5, %o0
|
||||
|
||||
.align 32
|
||||
90:
|
||||
subcc %o2, 1, %o2
|
||||
LOAD(ldub, %o1, %g1)
|
||||
STORE(stb, %g1, %o1 + %o3)
|
||||
bgu,pt %XCC, 90b
|
||||
add %o1, 1, %o1
|
||||
retl
|
||||
mov %g5, %o0
|
||||
|
||||
END(memcpy)
|
||||
|
||||
#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
|
||||
ldx [%src - offset - 0x20], %t0; \
|
||||
ldx [%src - offset - 0x18], %t1; \
|
||||
ldx [%src - offset - 0x10], %t2; \
|
||||
ldx [%src - offset - 0x08], %t3; \
|
||||
stw %t0, [%dst - offset - 0x1c]; \
|
||||
srlx %t0, 32, %t0; \
|
||||
stw %t0, [%dst - offset - 0x20]; \
|
||||
stw %t1, [%dst - offset - 0x14]; \
|
||||
srlx %t1, 32, %t1; \
|
||||
stw %t1, [%dst - offset - 0x18]; \
|
||||
stw %t2, [%dst - offset - 0x0c]; \
|
||||
srlx %t2, 32, %t2; \
|
||||
stw %t2, [%dst - offset - 0x10]; \
|
||||
stw %t3, [%dst - offset - 0x04]; \
|
||||
srlx %t3, 32, %t3; \
|
||||
stw %t3, [%dst - offset - 0x08];
|
||||
|
||||
#define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
|
||||
ldx [%src - offset - 0x20], %t0; \
|
||||
ldx [%src - offset - 0x18], %t1; \
|
||||
ldx [%src - offset - 0x10], %t2; \
|
||||
ldx [%src - offset - 0x08], %t3; \
|
||||
stx %t0, [%dst - offset - 0x20]; \
|
||||
stx %t1, [%dst - offset - 0x18]; \
|
||||
stx %t2, [%dst - offset - 0x10]; \
|
||||
stx %t3, [%dst - offset - 0x08]; \
|
||||
ldx [%src - offset - 0x40], %t0; \
|
||||
ldx [%src - offset - 0x38], %t1; \
|
||||
ldx [%src - offset - 0x30], %t2; \
|
||||
ldx [%src - offset - 0x28], %t3; \
|
||||
stx %t0, [%dst - offset - 0x40]; \
|
||||
stx %t1, [%dst - offset - 0x38]; \
|
||||
stx %t2, [%dst - offset - 0x30]; \
|
||||
stx %t3, [%dst - offset - 0x28];
|
||||
|
||||
#define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
|
||||
ldx [%src + offset + 0x00], %t0; \
|
||||
ldx [%src + offset + 0x08], %t1; \
|
||||
stw %t0, [%dst + offset + 0x04]; \
|
||||
srlx %t0, 32, %t2; \
|
||||
stw %t2, [%dst + offset + 0x00]; \
|
||||
stw %t1, [%dst + offset + 0x0c]; \
|
||||
srlx %t1, 32, %t3; \
|
||||
stw %t3, [%dst + offset + 0x08];
|
||||
|
||||
#define RMOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1) \
|
||||
ldx [%src + offset + 0x00], %t0; \
|
||||
ldx [%src + offset + 0x08], %t1; \
|
||||
stx %t0, [%dst + offset + 0x00]; \
|
||||
stx %t1, [%dst + offset + 0x08];
|
||||
|
||||
.align 32
|
||||
228: andcc %o2, 1, %g0
|
||||
be,pt %icc, 2f+4
|
||||
1: ldub [%o1 - 1], %o5
|
||||
sub %o1, 1, %o1
|
||||
sub %o0, 1, %o0
|
||||
subcc %o2, 1, %o2
|
||||
be,pn %xcc, 229f
|
||||
stb %o5, [%o0]
|
||||
2: ldub [%o1 - 1], %o5
|
||||
sub %o0, 2, %o0
|
||||
ldub [%o1 - 2], %g5
|
||||
sub %o1, 2, %o1
|
||||
subcc %o2, 2, %o2
|
||||
stb %o5, [%o0 + 1]
|
||||
bne,pt %xcc, 2b
|
||||
stb %g5, [%o0]
|
||||
229: retl
|
||||
mov %g4, %o0
|
||||
out: retl
|
||||
mov %g5, %o0
|
||||
|
||||
.align 32
|
||||
ENTRY(memmove)
|
||||
mov %o0, %g5
|
||||
#ifndef USE_BPR
|
||||
srl %o2, 0, %o2
|
||||
#endif
|
||||
brz,pn %o2, out
|
||||
sub %o0, %o1, %o4
|
||||
cmp %o4, %o2
|
||||
bgeu,pt %XCC, 218b
|
||||
mov %o0, %g4
|
||||
add %o0, %o2, %o0
|
||||
220: add %o1, %o2, %o1
|
||||
cmp %o2, 15
|
||||
bleu,pn %xcc, 228b
|
||||
andcc %o0, 7, %g2
|
||||
sub %o0, %o1, %g5
|
||||
andcc %g5, 3, %o5
|
||||
bne,pn %xcc, 232f
|
||||
andcc %o1, 3, %g0
|
||||
be,a,pt %xcc, 236f
|
||||
andcc %o1, 4, %g0
|
||||
andcc %o1, 1, %g0
|
||||
be,pn %xcc, 4f
|
||||
andcc %o1, 2, %g0
|
||||
ldub [%o1 - 1], %g2
|
||||
sub %o1, 1, %o1
|
||||
sub %o0, 1, %o0
|
||||
sub %o2, 1, %o2
|
||||
be,pn %xcc, 5f
|
||||
stb %g2, [%o0]
|
||||
4: lduh [%o1 - 2], %g2
|
||||
sub %o1, 2, %o1
|
||||
sub %o0, 2, %o0
|
||||
sub %o2, 2, %o2
|
||||
sth %g2, [%o0]
|
||||
5: andcc %o1, 4, %g0
|
||||
236: be,a,pn %xcc, 2f
|
||||
andcc %o2, -128, %g6
|
||||
lduw [%o1 - 4], %g5
|
||||
sub %o1, 4, %o1
|
||||
sub %o0, 4, %o0
|
||||
sub %o2, 4, %o2
|
||||
stw %g5, [%o0]
|
||||
andcc %o2, -128, %g6
|
||||
2: be,pn %xcc, 235f
|
||||
andcc %o0, 4, %g0
|
||||
be,pn %xcc, 282f + 4
|
||||
5: RMOVE_BIGCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
|
||||
RMOVE_BIGCHUNK(o1, o0, 0x20, g1, g3, g5, o5)
|
||||
RMOVE_BIGCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
|
||||
RMOVE_BIGCHUNK(o1, o0, 0x60, g1, g3, g5, o5)
|
||||
subcc %g6, 128, %g6
|
||||
sub %o1, 128, %o1
|
||||
bne,pt %xcc, 5b
|
||||
sub %o0, 128, %o0
|
||||
235: andcc %o2, 0x70, %g6
|
||||
41: be,pn %xcc, 280f
|
||||
andcc %o2, 8, %g0
|
||||
|
||||
279: rd %pc, %o5
|
||||
sll %g6, 1, %g5
|
||||
sub %o1, %g6, %o1
|
||||
sub %o5, %g5, %o5
|
||||
jmpl %o5 + %lo(280f - 279b), %g0
|
||||
sub %o0, %g6, %o0
|
||||
RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g5, o5)
|
||||
RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g5, o5)
|
||||
RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g5, o5)
|
||||
RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g5, o5)
|
||||
RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g5, o5)
|
||||
RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g5, o5)
|
||||
RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g5, o5)
|
||||
280: be,pt %xcc, 281f
|
||||
andcc %o2, 4, %g0
|
||||
ldx [%o1 - 8], %g2
|
||||
sub %o0, 8, %o0
|
||||
stw %g2, [%o0 + 4]
|
||||
sub %o1, 8, %o1
|
||||
srlx %g2, 32, %g2
|
||||
stw %g2, [%o0]
|
||||
281: be,pt %xcc, 1f
|
||||
andcc %o2, 2, %g0
|
||||
lduw [%o1 - 4], %g2
|
||||
sub %o1, 4, %o1
|
||||
stw %g2, [%o0 - 4]
|
||||
sub %o0, 4, %o0
|
||||
1: be,pt %xcc, 1f
|
||||
andcc %o2, 1, %g0
|
||||
lduh [%o1 - 2], %g2
|
||||
sub %o1, 2, %o1
|
||||
sth %g2, [%o0 - 2]
|
||||
sub %o0, 2, %o0
|
||||
1: be,pt %xcc, 211f
|
||||
nop
|
||||
ldub [%o1 - 1], %g2
|
||||
stb %g2, [%o0 - 1]
|
||||
211: retl
|
||||
mov %g4, %o0
|
||||
|
||||
282: RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
|
||||
RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
|
||||
subcc %g6, 128, %g6
|
||||
sub %o1, 128, %o1
|
||||
bne,pt %xcc, 282b
|
||||
sub %o0, 128, %o0
|
||||
andcc %o2, 0x70, %g6
|
||||
be,pn %xcc, 284f
|
||||
andcc %o2, 8, %g0
|
||||
|
||||
283: rd %pc, %o5
|
||||
sub %o1, %g6, %o1
|
||||
sub %o5, %g6, %o5
|
||||
jmpl %o5 + %lo(284f - 283b), %g0
|
||||
sub %o0, %g6, %o0
|
||||
RMOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3)
|
||||
RMOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3)
|
||||
RMOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3)
|
||||
RMOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3)
|
||||
RMOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3)
|
||||
RMOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3)
|
||||
RMOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3)
|
||||
284: be,pt %xcc, 285f
|
||||
andcc %o2, 4, %g0
|
||||
ldx [%o1 - 8], %g2
|
||||
sub %o0, 8, %o0
|
||||
sub %o1, 8, %o1
|
||||
stx %g2, [%o0]
|
||||
285: be,pt %xcc, 1f
|
||||
andcc %o2, 2, %g0
|
||||
lduw [%o1 - 4], %g2
|
||||
sub %o0, 4, %o0
|
||||
sub %o1, 4, %o1
|
||||
stw %g2, [%o0]
|
||||
1: be,pt %xcc, 1f
|
||||
andcc %o2, 1, %g0
|
||||
lduh [%o1 - 2], %g2
|
||||
sub %o0, 2, %o0
|
||||
sub %o1, 2, %o1
|
||||
sth %g2, [%o0]
|
||||
1: be,pt %xcc, 1f
|
||||
nop
|
||||
ldub [%o1 - 1], %g2
|
||||
stb %g2, [%o0 - 1]
|
||||
1: retl
|
||||
mov %g4, %o0
|
||||
|
||||
232: ldub [%o1 - 1], %g5
|
||||
sub %o1, 1, %o1
|
||||
sub %o0, 1, %o0
|
||||
subcc %o2, 1, %o2
|
||||
bne,pt %xcc, 232b
|
||||
stb %g5, [%o0]
|
||||
234: retl
|
||||
mov %g4, %o0
|
||||
END(memmove)
|
||||
|
||||
#ifdef USE_BPR
|
||||
weak_alias (memcpy, __align_cpy_1)
|
||||
weak_alias (memcpy, __align_cpy_2)
|
||||
weak_alias (memcpy, __align_cpy_4)
|
||||
weak_alias (memcpy, __align_cpy_8)
|
||||
weak_alias (memcpy, __align_cpy_16)
|
||||
#endif
|
||||
libc_hidden_builtin_def (memcpy)
|
||||
libc_hidden_builtin_def (memmove)
|
127
sysdeps/sparc/sparc64/sparcv9v/memset.S
Normal file
127
sysdeps/sparc/sparc64/sparcv9v/memset.S
Normal file
@@ -0,0 +1,127 @@
|
||||
/* Set a block of memory to some byte value. For SUN4V Niagara.
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by David S. Miller (davem@davemloft.net)
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
#define ASI_BLK_INIT_QUAD_LDD_P 0xe2
|
||||
#define ASI_P 0x80
|
||||
#define ASI_PNF 0x82
|
||||
|
||||
#ifndef XCC
|
||||
#define USE_BPR
|
||||
#define XCC xcc
|
||||
#endif
|
||||
|
||||
.register %g2,#scratch
|
||||
|
||||
.text
|
||||
.align 32
|
||||
|
||||
ENTRY(memset)
|
||||
/* %o0=buf, %o1=pat, %o2=len */
|
||||
and %o1, 0xff, %o3
|
||||
mov %o2, %o1
|
||||
sllx %o3, 8, %g1
|
||||
or %g1, %o3, %o2
|
||||
sllx %o2, 16, %g1
|
||||
or %g1, %o2, %o2
|
||||
sllx %o2, 32, %g1
|
||||
ba,pt %XCC, 1f
|
||||
or %g1, %o2, %o2
|
||||
END(memset)
|
||||
|
||||
ENTRY(__bzero)
|
||||
clr %o2
|
||||
1: brz,pn %o1, 90f
|
||||
mov %o0, %o3
|
||||
|
||||
wr %g0, ASI_P, %asi
|
||||
|
||||
cmp %o1, 15
|
||||
bl,pn %icc, 70f
|
||||
andcc %o0, 0x7, %g1
|
||||
be,pt %XCC, 2f
|
||||
mov 8, %g2
|
||||
sub %g2, %g1, %g1
|
||||
sub %o1, %g1, %o1
|
||||
1: stba %o2, [%o0 + 0x00] %asi
|
||||
subcc %g1, 1, %g1
|
||||
bne,pt %XCC, 1b
|
||||
add %o0, 1, %o0
|
||||
2: cmp %o1, 128
|
||||
bl,pn %icc, 60f
|
||||
andcc %o0, (64 - 1), %g1
|
||||
be,pt %XCC, 40f
|
||||
mov 64, %g2
|
||||
sub %g2, %g1, %g1
|
||||
sub %o1, %g1, %o1
|
||||
1: stxa %o2, [%o0 + 0x00] %asi
|
||||
subcc %g1, 8, %g1
|
||||
bne,pt %XCC, 1b
|
||||
add %o0, 8, %o0
|
||||
|
||||
40:
|
||||
wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
|
||||
andn %o1, (64 - 1), %g1
|
||||
sub %o1, %g1, %o1
|
||||
50:
|
||||
stxa %o2, [%o0 + 0x00] %asi
|
||||
stxa %o2, [%o0 + 0x08] %asi
|
||||
stxa %o2, [%o0 + 0x10] %asi
|
||||
stxa %o2, [%o0 + 0x18] %asi
|
||||
stxa %o2, [%o0 + 0x20] %asi
|
||||
stxa %o2, [%o0 + 0x28] %asi
|
||||
stxa %o2, [%o0 + 0x30] %asi
|
||||
stxa %o2, [%o0 + 0x38] %asi
|
||||
subcc %g1, 64, %g1
|
||||
bne,pt %XCC, 50b
|
||||
add %o0, 64, %o0
|
||||
|
||||
wr %g0, ASI_P, %asi
|
||||
brz,pn %o1, 80f
|
||||
60:
|
||||
andncc %o1, 0x7, %g1
|
||||
be,pn %XCC, 2f
|
||||
sub %o1, %g1, %o1
|
||||
1: stxa %o2, [%o0 + 0x00] %asi
|
||||
subcc %g1, 8, %g1
|
||||
bne,pt %XCC, 1b
|
||||
add %o0, 8, %o0
|
||||
2: brz,pt %o1, 80f
|
||||
nop
|
||||
|
||||
70:
|
||||
1: stba %o2, [%o0 + 0x00] %asi
|
||||
subcc %o1, 1, %o1
|
||||
bne,pt %icc, 1b
|
||||
add %o0, 1, %o0
|
||||
|
||||
/* fallthrough */
|
||||
|
||||
80:
|
||||
wr %g0, ASI_PNF, %asi
|
||||
|
||||
90:
|
||||
retl
|
||||
mov %o3, %o0
|
||||
END(__bzero)
|
||||
|
||||
libc_hidden_builtin_def (memset)
|
||||
weak_alias (__bzero, bzero)
|
Reference in New Issue
Block a user