mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 10:50:07 +00:00
Add sysdeps/tile, sysdeps/unix/sysv/linux/tile.
Changes are tracked in ChangeLog.tile. Also add data/c++-types-tile-linux-gnu.data.
This commit is contained in:
parent
a63c7fa185
commit
63d143a25d
134
ChangeLog.tile
Normal file
134
ChangeLog.tile
Normal file
@ -0,0 +1,134 @@
|
||||
2011-12-03 Chris Metcalf <cmetcalf@tilera.com>
|
||||
|
||||
* data/c++-types-tile-linux-gnu.data: New file.
|
||||
* sysdeps/tile/Implies: New file.
|
||||
* sysdeps/tile/Makefile: New file.
|
||||
* sysdeps/tile/Versions: New file.
|
||||
* sysdeps/tile/__longjmp.S: New file.
|
||||
* sysdeps/tile/__tls_get_addr.S: New file.
|
||||
* sysdeps/tile/_mcount.S: New file.
|
||||
* sysdeps/tile/abort-instr.h: New file.
|
||||
* sysdeps/tile/backtrace.c: New file.
|
||||
* sysdeps/tile/bits/atomic.h: New file.
|
||||
* sysdeps/tile/bits/byteswap.h: New file.
|
||||
* sysdeps/tile/bits/endian.h: New file.
|
||||
* sysdeps/tile/bits/fenv.h: New file.
|
||||
* sysdeps/tile/bits/link.h: New file.
|
||||
* sysdeps/tile/bits/mathdef.h: New file.
|
||||
* sysdeps/tile/bits/mathinline.h: New file.
|
||||
* sysdeps/tile/bits/setjmp.h: New file.
|
||||
* sysdeps/tile/bsd-_setjmp.S: New file.
|
||||
* sysdeps/tile/bsd-setjmp.S: New file.
|
||||
* sysdeps/tile/bzero.S: New file.
|
||||
* sysdeps/tile/dl-lookupcfg.h: New file.
|
||||
* sysdeps/tile/dl-machine.h: New file.
|
||||
* sysdeps/tile/dl-runtime.c: New file.
|
||||
* sysdeps/tile/dl-start.S: New file.
|
||||
* sysdeps/tile/dl-tls.c: New file.
|
||||
* sysdeps/tile/dl-tls.h: New file.
|
||||
* sysdeps/tile/dl-trampoline.S: New file.
|
||||
* sysdeps/tile/elf/start.S: New file.
|
||||
* sysdeps/tile/fegetenv.c: New file.
|
||||
* sysdeps/tile/fegetround.c: New file.
|
||||
* sysdeps/tile/feholdexcpt.c: New file.
|
||||
* sysdeps/tile/fesetenv.c: New file.
|
||||
* sysdeps/tile/fesetround.c: New file.
|
||||
* sysdeps/tile/feupdateenv.c: New file.
|
||||
* sysdeps/tile/ffs.c: New file.
|
||||
* sysdeps/tile/ffsll.c: New file.
|
||||
* sysdeps/tile/gccframe.h: New file.
|
||||
* sysdeps/tile/jmpbuf-offsets.h: New file.
|
||||
* sysdeps/tile/jmpbuf-unwind.h: New file.
|
||||
* sysdeps/tile/ldsodefs.h: New file.
|
||||
* sysdeps/tile/machine-gmon.h: New file.
|
||||
* sysdeps/tile/nptl/Makefile: New file.
|
||||
* sysdeps/tile/nptl/pthread_spin_lock.c: New file.
|
||||
* sysdeps/tile/nptl/pthread_spin_trylock.c: New file.
|
||||
* sysdeps/tile/nptl/pthreaddef.h: New file.
|
||||
* sysdeps/tile/nptl/tcb-offsets.sym: New file.
|
||||
* sysdeps/tile/nptl/tls.h: New file.
|
||||
* sysdeps/tile/preconfigure: New file.
|
||||
* sysdeps/tile/s_fma.c: New file.
|
||||
* sysdeps/tile/s_fmaf.c: New file.
|
||||
* sysdeps/tile/setjmp.S: New file.
|
||||
* sysdeps/tile/shlib-versions: New file.
|
||||
* sysdeps/tile/stackinfo.h: New file.
|
||||
* sysdeps/tile/sysdep.h: New file.
|
||||
* sysdeps/tile/tilegx/bits/atomic.h: New file.
|
||||
* sysdeps/tile/tilegx/bits/wordsize.h: New file.
|
||||
* sysdeps/tile/tilegx/memchr.c: New file.
|
||||
* sysdeps/tile/tilegx/memcpy.c: New file.
|
||||
* sysdeps/tile/tilegx/memset.c: New file.
|
||||
* sysdeps/tile/tilegx/memusage.h: New file.
|
||||
* sysdeps/tile/tilegx/rawmemchr.c: New file.
|
||||
* sysdeps/tile/tilegx/strchr.c: New file.
|
||||
* sysdeps/tile/tilegx/strchrnul.c: New file.
|
||||
* sysdeps/tile/tilegx/string-endian.h: New file.
|
||||
* sysdeps/tile/tilegx/strlen.c: New file.
|
||||
* sysdeps/tile/tilegx/strrchr.c: New file.
|
||||
* sysdeps/tile/tilegx/tilegx32/Implies: New file.
|
||||
* sysdeps/tile/tilegx/tilegx64/Implies: New file.
|
||||
* sysdeps/tile/tilepro/Implies: New file.
|
||||
* sysdeps/tile/tilepro/bits/atomic.h: New file.
|
||||
* sysdeps/tile/tilepro/bits/wordsize.h: New file.
|
||||
* sysdeps/tile/tilepro/memchr.c: New file.
|
||||
* sysdeps/tile/tilepro/memcpy.S: New file.
|
||||
* sysdeps/tile/tilepro/memset.c: New file.
|
||||
* sysdeps/tile/tilepro/memusage.h: New file.
|
||||
* sysdeps/tile/tilepro/rawmemchr.c: New file.
|
||||
* sysdeps/tile/tilepro/strchr.c: New file.
|
||||
* sysdeps/tile/tilepro/strchrnul.c: New file.
|
||||
* sysdeps/tile/tilepro/strlen.c: New file.
|
||||
* sysdeps/tile/tilepro/strrchr.c: New file.
|
||||
* sysdeps/tile/tls-macros.h: New file.
|
||||
* sysdeps/tile/tst-audit.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/Makefile: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/Versions: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/bits/environments.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/bits/local_lim.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/bits/mman.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/bits/mman.h~: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/bits/sigaction.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/bits/siginfo.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/cacheflush.c: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/configure: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/configure.in: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/getcontext.S: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/kernel-features.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/makecontext.c: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/Makefile: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/bits/pthreadtypes.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/bits/semaphore.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/clone.S: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/createthread.c: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/fork.c: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/pt-vfork.S: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/pthread_once.c: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/sysdep-cancel.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/vfork.S: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/nptl/waitpid.S: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/profil-counter.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/set_dataplane.c: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/setcontext.S: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sigcontextinfo.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/swapcontext.S: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sys/cachectl.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sys/dataplane.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sys/procfs.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sys/ptrace.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sys/reg.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sys/ucontext.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sys/user.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/syscall.S: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sysdep.c: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sysdep.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/tilegx/ioctl.S: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/tilegx/ldconfig.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/tilegx/register-dump.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/Implies: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/Implies: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/tilepro/Implies: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/tilepro/ldconfig.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/tilepro/register-dump.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/ucontext_i.h: New file.
|
67
data/c++-types-tile-linux-gnu.data
Normal file
67
data/c++-types-tile-linux-gnu.data
Normal file
@ -0,0 +1,67 @@
|
||||
blkcnt64_t:x
|
||||
blkcnt_t:l
|
||||
blksize_t:i
|
||||
caddr_t:Pc
|
||||
clockid_t:i
|
||||
clock_t:l
|
||||
daddr_t:i
|
||||
dev_t:y
|
||||
fd_mask:l
|
||||
fsblkcnt64_t:y
|
||||
fsblkcnt_t:m
|
||||
fsfilcnt64_t:y
|
||||
fsfilcnt_t:m
|
||||
fsid_t:8__fsid_t
|
||||
gid_t:j
|
||||
id_t:j
|
||||
ino64_t:y
|
||||
ino_t:m
|
||||
int16_t:s
|
||||
int32_t:i
|
||||
int64_t:x
|
||||
int8_t:a
|
||||
intptr_t:i
|
||||
key_t:i
|
||||
loff_t:x
|
||||
mode_t:j
|
||||
nlink_t:j
|
||||
off64_t:x
|
||||
off_t:l
|
||||
pid_t:i
|
||||
pthread_attr_t:14pthread_attr_t
|
||||
pthread_barrier_t:17pthread_barrier_t
|
||||
pthread_barrierattr_t:21pthread_barrierattr_t
|
||||
pthread_cond_t:14pthread_cond_t
|
||||
pthread_condattr_t:18pthread_condattr_t
|
||||
pthread_key_t:j
|
||||
pthread_mutex_t:15pthread_mutex_t
|
||||
pthread_mutexattr_t:19pthread_mutexattr_t
|
||||
pthread_once_t:i
|
||||
pthread_rwlock_t:16pthread_rwlock_t
|
||||
pthread_rwlockattr_t:20pthread_rwlockattr_t
|
||||
pthread_spinlock_t:i
|
||||
pthread_t:m
|
||||
quad_t:x
|
||||
register_t:i
|
||||
rlim64_t:y
|
||||
rlim_t:m
|
||||
sigset_t:10__sigset_t
|
||||
size_t:j
|
||||
socklen_t:j
|
||||
ssize_t:i
|
||||
suseconds_t:l
|
||||
time_t:l
|
||||
u_char:h
|
||||
uid_t:j
|
||||
uint:j
|
||||
u_int:j
|
||||
u_int16_t:t
|
||||
u_int32_t:j
|
||||
u_int64_t:y
|
||||
u_int8_t:h
|
||||
ulong:m
|
||||
u_long:m
|
||||
u_quad_t:y
|
||||
useconds_t:j
|
||||
ushort:t
|
||||
u_short:t
|
2
sysdeps/tile/Implies
Normal file
2
sysdeps/tile/Implies
Normal file
@ -0,0 +1,2 @@
|
||||
ieee754/dbl-64
|
||||
ieee754/flt-32
|
18
sysdeps/tile/Makefile
Normal file
18
sysdeps/tile/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
# We don't support long doubles as a distinct type. We don't need to set
|
||||
# this variable; it's here mostly for documentational purposes.
|
||||
|
||||
long-double-fcts = no
|
||||
|
||||
ifeq ($(subdir),gmon)
|
||||
sysdep_routines += _mcount
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),elf)
|
||||
# Extra shared linker files to link only into dl-allobjs.so.
|
||||
sysdep-rtld-routines += dl-start __tls_get_addr
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),csu)
|
||||
# Avoid .cfi_startproc/endproc markers when creating init and fini pieces.
|
||||
CFLAGS-initfini.s += -fno-asynchronous-unwind-tables
|
||||
endif
|
6
sysdeps/tile/Versions
Normal file
6
sysdeps/tile/Versions
Normal file
@ -0,0 +1,6 @@
|
||||
libc {
|
||||
GLIBC_2.12 {
|
||||
# name requested by gcc community.
|
||||
__mcount;
|
||||
}
|
||||
}
|
58
sysdeps/tile/__longjmp.S
Normal file
58
sysdeps/tile/__longjmp.S
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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>
|
||||
#include <jmpbuf-offsets.h>
|
||||
#include <asm-syntax.h>
|
||||
#include <arch/spr_def.h>
|
||||
|
||||
/* PL to return to via iret in longjmp */
|
||||
#define RETURN_PL 0
|
||||
|
||||
.text
|
||||
ENTRY (__longjmp)
|
||||
FEEDBACK_ENTER(__longjmp)
|
||||
|
||||
#define RESTORE(r) { LD r, r0 ; ADDI_PTR r0, r0, REGSIZE }
|
||||
FOR_EACH_CALLEE_SAVED_REG(RESTORE)
|
||||
|
||||
/* Make longjmp(buf, 0) return "1" instead.
|
||||
At the same time, construct our iret context; we set ICS so
|
||||
we can validly load EX_CONTEXT for iret without being
|
||||
interrupted halfway through. */
|
||||
{
|
||||
LD r2, r0 /* retrieve ICS bit from jmp_buf */
|
||||
movei r3, 1
|
||||
CMPEQI r0, r1, 0
|
||||
}
|
||||
{
|
||||
mtspr INTERRUPT_CRITICAL_SECTION, r3
|
||||
shli r2, r2, SPR_EX_CONTEXT_0_1__ICS_SHIFT
|
||||
}
|
||||
{
|
||||
mtspr EX_CONTEXT_0_0, lr
|
||||
ori r2, r2, RETURN_PL
|
||||
}
|
||||
{
|
||||
or r0, r1, r0
|
||||
mtspr EX_CONTEXT_0_1, r2
|
||||
}
|
||||
iret
|
||||
jrp lr /* Keep the backtracer happy. */
|
||||
END (__longjmp)
|
150
sysdeps/tile/__tls_get_addr.S
Normal file
150
sysdeps/tile/__tls_get_addr.S
Normal file
@ -0,0 +1,150 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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>
|
||||
#include <tls.h>
|
||||
|
||||
#ifdef _LP64
|
||||
#define LOG_SIZEOF_DTV_T 4
|
||||
#else
|
||||
#define LOG_SIZEOF_DTV_T 3
|
||||
#endif
|
||||
|
||||
/* On entry, r0 points to two words, the module and the offset.
|
||||
On return, r0 holds the pointer to the relevant TLS memory.
|
||||
Only registers r25..r29 are clobbered by the call. */
|
||||
|
||||
.text
|
||||
ENTRY (__tls_get_addr)
|
||||
{
|
||||
lnk r25
|
||||
ADDI_PTR r27, tp, DTV_OFFSET
|
||||
}
|
||||
.Llnk:
|
||||
#ifdef __tilegx__
|
||||
{
|
||||
LD_PTR r27, r27 /* r27 = THREAD_DTV() */
|
||||
moveli r26, hw1_last(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
|
||||
}
|
||||
shl16insli r26, r26, hw0(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
|
||||
{
|
||||
ADD_PTR r25, r25, r26
|
||||
LD_PTR r26, r0 /* r26 = ti_module */
|
||||
}
|
||||
#else
|
||||
{
|
||||
LD_PTR r27, r27 /* r27 = THREAD_DTV() */
|
||||
addli r25, r25, lo16(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
|
||||
}
|
||||
{
|
||||
auli r25, r25, ha16(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
|
||||
LD_PTR r26, r0 /* r26 = ti_module */
|
||||
}
|
||||
#endif
|
||||
LD_PTR r25, r25 /* r25 = DL(dl_tls_generation) */
|
||||
{
|
||||
LD_PTR r28, r27 /* r28 = THREAD_DTV()->counter */
|
||||
ADDI_PTR r29, r0, __SIZEOF_POINTER__
|
||||
}
|
||||
{
|
||||
LD_PTR r29, r29 /* r29 = ti_offset */
|
||||
CMPEQ r25, r28, r25 /* r25 nonzero if generation OK */
|
||||
shli r28, r26, LOG_SIZEOF_DTV_T /* byte index into dtv array */
|
||||
}
|
||||
{
|
||||
BEQZ r25, .Lslowpath
|
||||
CMPEQI r25, r26, -1 /* r25 nonzero if ti_module invalid */
|
||||
}
|
||||
{
|
||||
BNEZ r25, .Lslowpath
|
||||
ADD_PTR r28, r28, r27 /* pointer into module array */
|
||||
}
|
||||
LD_PTR r26, r28 /* r26 = module TLS pointer */
|
||||
{
|
||||
ADD_PTR r0, r26, r29
|
||||
jrp lr
|
||||
}
|
||||
|
||||
.Lslowpath:
|
||||
{
|
||||
ST sp, lr
|
||||
ADDLI_PTR r29, sp, - (25 * REGSIZE)
|
||||
}
|
||||
cfi_offset (lr, 0)
|
||||
{
|
||||
ST r29, sp
|
||||
ADDLI_PTR sp, sp, - (26 * REGSIZE)
|
||||
}
|
||||
cfi_def_cfa_offset (26 * REGSIZE)
|
||||
ADDI_PTR r29, sp, (2 * REGSIZE)
|
||||
{ ST r29, r1; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r2; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r3; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r4; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r5; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r6; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r7; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r8; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r9; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r10; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r11; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r12; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r13; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r14; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r15; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r16; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r17; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r18; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r19; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r20; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r21; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r22; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r23; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r24; ADDI_PTR r29, r29, REGSIZE }
|
||||
.hidden __tls_get_addr_slow
|
||||
jal __tls_get_addr_slow
|
||||
ADDI_PTR r29, sp, (2 * REGSIZE)
|
||||
{ LD r1, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r2, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r3, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r4, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r5, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r6, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r7, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r8, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r9, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r10, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r11, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r12, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r13, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r14, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r15, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r16, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r17, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r18, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r19, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r20, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r21, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r22, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r23, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r24, r29; ADDLI_PTR sp, sp, (26 * REGSIZE) }
|
||||
cfi_def_cfa_offset (0)
|
||||
LD lr, sp
|
||||
jrp lr
|
||||
END (__tls_get_addr)
|
88
sysdeps/tile/_mcount.S
Normal file
88
sysdeps/tile/_mcount.S
Normal file
@ -0,0 +1,88 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
Based on work contributed by David Mosberger (davidm@cs.arizona.edu).
|
||||
|
||||
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. */
|
||||
|
||||
/* Assembly stub to invoke __mcount_internal(). Compiler-generated
|
||||
code calls mcount after executing a function's prologue, placing
|
||||
the "lr" register in "r10" for the call. As a result "lr" is the
|
||||
function that invoked mcount, and "r10" is mcount's caller's
|
||||
caller. However, we have to save all the parameter registers here
|
||||
before invoking _mcount_internal. Callee-save and temporary
|
||||
registers need no special attention. We save r10 and restore it to
|
||||
lr on the way out, to properly handle the case of ENTRY() in
|
||||
assembly code, before lr is saved. We use the name __mcount since
|
||||
the gcc community prefers using the reserved namespace. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
.text
|
||||
ENTRY(__mcount)
|
||||
{
|
||||
ST sp, lr
|
||||
ADDI_PTR r29, sp, - (12 * REGSIZE)
|
||||
}
|
||||
cfi_offset (lr, 0)
|
||||
{
|
||||
ADDI_PTR sp, sp, - (13 * REGSIZE)
|
||||
ST r29, sp
|
||||
ADDI_PTR r29, r29, REGSIZE
|
||||
}
|
||||
cfi_def_cfa_offset (13 * REGSIZE)
|
||||
{ ST r29, r0; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r1; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r2; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r3; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r4; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r5; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r6; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r7; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r8; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r9; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ ST r29, r10; ADDI_PTR r29, r29, REGSIZE; move r0, r10 }
|
||||
{
|
||||
move r1, lr
|
||||
jal __mcount_internal
|
||||
}
|
||||
{
|
||||
ADDI_PTR r29, sp, (2 * REGSIZE)
|
||||
}
|
||||
{ LD r0, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r1, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r2, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r3, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r4, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r5, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r6, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r7, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r8, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r9, r29; ADDI_PTR r29, r29, REGSIZE }
|
||||
{ LD r10, r29; ADDI_PTR sp, sp, (13 * REGSIZE) }
|
||||
cfi_def_cfa_offset (0)
|
||||
{
|
||||
LD lr, sp
|
||||
}
|
||||
{
|
||||
move lr, r10
|
||||
jrp lr
|
||||
}
|
||||
END(__mcount)
|
||||
|
||||
#undef mcount
|
||||
weak_alias (__mcount, _mcount) /* exported in gmon/Versions */
|
||||
weak_alias (__mcount, mcount) /* exported in stdlib/Versions */
|
2
sysdeps/tile/abort-instr.h
Normal file
2
sysdeps/tile/abort-instr.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* An instruction which should crash any program is `hlt'. */
|
||||
#define ABORT_INSTRUCTION asm ("ill")
|
1
sysdeps/tile/backtrace.c
Normal file
1
sysdeps/tile/backtrace.c
Normal file
@ -0,0 +1 @@
|
||||
#include <sysdeps/ia64/backtrace.c>
|
87
sysdeps/tile/bits/atomic.h
Normal file
87
sysdeps/tile/bits/atomic.h
Normal file
@ -0,0 +1,87 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
/* The sub-architecture headers provide definitions for these macros
|
||||
that work for "int" and "long" size values only:
|
||||
|
||||
atomic_compare_and_exchange_val_acq()
|
||||
atomic_exchange_acq()
|
||||
atomic_exchange_and_add()
|
||||
atomic_and_val()
|
||||
atomic_or_val()
|
||||
atomic_decrement_if_positive() [tilegx only]
|
||||
|
||||
Here we provide generic definitions true for all Tilera chips. */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <features.h>
|
||||
|
||||
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;
|
||||
|
||||
/* Barrier macro. */
|
||||
#define atomic_full_barrier() __sync_synchronize()
|
||||
|
||||
/* APIs with "release" semantics. */
|
||||
#define atomic_compare_and_exchange_val_rel(mem, n, o) \
|
||||
({ \
|
||||
atomic_full_barrier (); \
|
||||
atomic_compare_and_exchange_val_acq ((mem), (n), (o)); \
|
||||
})
|
||||
#define atomic_compare_and_exchange_bool_rel(mem, n, o) \
|
||||
({ \
|
||||
atomic_full_barrier (); \
|
||||
atomic_compare_and_exchange_bool_acq ((mem), (n), (o)); \
|
||||
})
|
||||
#define atomic_exchange_rel(mem, n) \
|
||||
({ \
|
||||
atomic_full_barrier (); \
|
||||
atomic_exchange_acq ((mem), (n)); \
|
||||
})
|
||||
|
||||
/* Various macros that should just be synonyms. */
|
||||
#define catomic_exchange_and_add atomic_exchange_and_add
|
||||
#define atomic_and(mem, mask) ((void) atomic_and_val ((mem), (mask)))
|
||||
#define catomic_and atomic_and
|
||||
#define atomic_or(mem, mask) ((void) atomic_or_val ((mem), (mask)))
|
||||
#define catomic_or atomic_or
|
||||
|
||||
/* atomic_bit_test_set in terms of atomic_or_val. */
|
||||
#define atomic_bit_test_set(mem, bit) \
|
||||
({ __typeof (*(mem)) __att0_mask = ((__typeof (*(mem))) 1 << (bit)); \
|
||||
atomic_or_val ((mem), __att0_mask) & __att0_mask; })
|
||||
|
||||
/*
|
||||
* This non-existent symbol is called for unsupporrted sizes,
|
||||
* indicating a bug in the caller.
|
||||
*/
|
||||
extern int __atomic_error_bad_argument_size(void)
|
||||
__attribute__ ((warning ("bad sizeof atomic argument")));
|
36
sysdeps/tile/bits/byteswap.h
Normal file
36
sysdeps/tile/bits/byteswap.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
#if !defined _BYTESWAP_H && !defined _NETINET_IN_H && !defined _ENDIAN_H
|
||||
# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef _BITS_BYTESWAP_H
|
||||
#define _BITS_BYTESWAP_H 1
|
||||
|
||||
/* gcc __builtin_bswap64() can constant-fold, etc, so always use it. */
|
||||
#define __bswap_16(x) ((unsigned short)(__builtin_bswap32(x) >> 16))
|
||||
#define __bswap_32(x) ((unsigned int)__builtin_bswap32(x))
|
||||
#define __bswap_64(x) ((unsigned long long)__builtin_bswap64(x))
|
||||
|
||||
#define __bswap_constant_16(x) __bswap_16(x)
|
||||
#define __bswap_constant_32(x) __bswap_32(x)
|
||||
#define __bswap_constant_64(x) __bswap_64(x)
|
||||
|
||||
#endif /* _BITS_BYTESWAP_H */
|
13
sysdeps/tile/bits/endian.h
Normal file
13
sysdeps/tile/bits/endian.h
Normal file
@ -0,0 +1,13 @@
|
||||
/* Set endianness for tile. */
|
||||
|
||||
#ifndef _ENDIAN_H
|
||||
# error "Never use <bits/endian.h> directly; include <endian.h> instead."
|
||||
#endif
|
||||
|
||||
#if defined __BIG_ENDIAN__
|
||||
# define __BYTE_ORDER __BIG_ENDIAN
|
||||
#elif defined __LITTLE_ENDIAN__
|
||||
# define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#else
|
||||
# error "Endianness not declared!!"
|
||||
#endif
|
43
sysdeps/tile/bits/fenv.h
Normal file
43
sysdeps/tile/bits/fenv.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _FENV_H
|
||||
# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
|
||||
#endif
|
||||
|
||||
/* The TILE-Gx hardware does not provide floating-point exception
|
||||
handling, and TILEPro does not support any floating-point operations. */
|
||||
#define FE_ALL_EXCEPT 0
|
||||
|
||||
/* TILE-Gx supports only round-to-nearest. The software
|
||||
floating-point support also acts this way. */
|
||||
enum
|
||||
{
|
||||
FE_TONEAREST = 1,
|
||||
#define FE_TONEAREST FE_TONEAREST
|
||||
};
|
||||
|
||||
/* Type representing exception flags (if there were any). */
|
||||
typedef unsigned int fexcept_t;
|
||||
|
||||
/* Type representing floating-point environment. */
|
||||
typedef unsigned int fenv_t;
|
||||
|
||||
/* If the default argument is used we use this value. */
|
||||
#define FE_DFL_ENV ((__const fenv_t *) -1l)
|
58
sysdeps/tile/bits/link.h
Normal file
58
sysdeps/tile/bits/link.h
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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
|
||||
|
||||
#define __need_int_reg_t
|
||||
#include <arch/abi.h>
|
||||
|
||||
|
||||
/* Registers for entry into PLT. */
|
||||
typedef struct La_tile_regs
|
||||
{
|
||||
__uint_reg_t lr_reg[10];
|
||||
} La_tile_regs;
|
||||
|
||||
/* Return values for calls from PLT. */
|
||||
typedef struct La_tile_retval
|
||||
{
|
||||
/* Up to ten registers can be used for a return value (e.g. small struct). */
|
||||
__uint_reg_t lrv_reg[10];
|
||||
} La_tile_retval;
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
extern ElfW(Addr) la_tile_gnu_pltenter (ElfW(Sym) *__sym, unsigned int __ndx,
|
||||
uintptr_t *__refcook,
|
||||
uintptr_t *__defcook,
|
||||
La_tile_regs *__regs,
|
||||
unsigned int *__flags,
|
||||
const char *__symname,
|
||||
long int *__framesizep);
|
||||
extern unsigned int la_tile_gnu_pltexit (ElfW(Sym) *__sym, unsigned int __ndx,
|
||||
uintptr_t *__refcook,
|
||||
uintptr_t *__defcook,
|
||||
const La_tile_regs *__inregs,
|
||||
La_tile_retval *__outregs,
|
||||
const char *__symname);
|
||||
|
||||
__END_DECLS
|
49
sysdeps/tile/bits/mathdef.h
Normal file
49
sysdeps/tile/bits/mathdef.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
#if !defined _MATH_H && !defined _COMPLEX_H
|
||||
# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
|
||||
#endif
|
||||
|
||||
#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
|
||||
# define _MATH_H_MATHDEF 1
|
||||
|
||||
/* "float" and "double" expressions evaluated as "float" and "double". */
|
||||
typedef float float_t;
|
||||
typedef double double_t;
|
||||
|
||||
/* The values returned by `ilogb' for 0 and NaN respectively. */
|
||||
# define FP_ILOGB0 (-2147483647)
|
||||
# define FP_ILOGBNAN (2147483647)
|
||||
|
||||
/* The GCC 4.6 compiler will define __FP_FAST_FMA{,F,L} if the fma{,f,l}
|
||||
builtins are supported. */
|
||||
# if __FP_FAST_FMA
|
||||
# define FP_FAST_FMA 1
|
||||
# endif
|
||||
|
||||
# if __FP_FAST_FMAF
|
||||
# define FP_FAST_FMAF 1
|
||||
# endif
|
||||
|
||||
# if __FP_FAST_FMAL
|
||||
# define FP_FAST_FMAL 1
|
||||
# endif
|
||||
|
||||
#endif /* ISO C99 */
|
45
sysdeps/tile/bits/mathinline.h
Normal file
45
sysdeps/tile/bits/mathinline.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _MATH_H
|
||||
# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef __extern_always_inline
|
||||
# define __MATH_INLINE __inline
|
||||
#else
|
||||
# define __MATH_INLINE __extern_always_inline
|
||||
#endif
|
||||
|
||||
|
||||
#if defined __USE_ISOC99 && defined __GNUC__
|
||||
|
||||
/* Test for negative number. Used in the signbit() macro. */
|
||||
__MATH_INLINE int
|
||||
__NTH (__signbitf (float __x))
|
||||
{
|
||||
return __builtin_signbitf (__x);
|
||||
}
|
||||
__MATH_INLINE int
|
||||
__NTH (__signbit (double __x))
|
||||
{
|
||||
return __builtin_signbit (__x);
|
||||
}
|
||||
|
||||
#endif
|
37
sysdeps/tile/bits/setjmp.h
Normal file
37
sysdeps/tile/bits/setjmp.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 the machine-dependent type `jmp_buf'. TILE version. */
|
||||
#ifndef _BITS_SETJMP_H
|
||||
#define _BITS_SETJMP_H 1
|
||||
|
||||
#if !defined _SETJMP_H && !defined _PTHREAD_H
|
||||
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef _ASM
|
||||
|
||||
#define __need_int_reg_t
|
||||
#include <arch/abi.h>
|
||||
|
||||
typedef __uint_reg_t __jmp_buf[32];
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* bits/setjmp.h */
|
1
sysdeps/tile/bsd-_setjmp.S
Normal file
1
sysdeps/tile/bsd-_setjmp.S
Normal file
@ -0,0 +1 @@
|
||||
/* _setjmp is in setjmp.S */
|
1
sysdeps/tile/bsd-setjmp.S
Normal file
1
sysdeps/tile/bsd-setjmp.S
Normal file
@ -0,0 +1 @@
|
||||
/* setjmp is in setjmp.S */
|
31
sysdeps/tile/bzero.S
Normal file
31
sysdeps/tile/bzero.S
Normal file
@ -0,0 +1,31 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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
|
||||
ENTRY(__bzero)
|
||||
FEEDBACK_ENTER(__bzero)
|
||||
{
|
||||
move r2, r1
|
||||
move r1, zero
|
||||
}
|
||||
j __memset
|
||||
END(__bzero)
|
||||
weak_alias (__bzero, bzero)
|
28
sysdeps/tile/dl-lookupcfg.h
Normal file
28
sysdeps/tile/dl-lookupcfg.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 DL_UNMAP_IS_SPECIAL
|
||||
|
||||
#include_next <dl-lookupcfg.h>
|
||||
|
||||
struct link_map;
|
||||
|
||||
void internal_function _dl_unmap (struct link_map *map);
|
||||
|
||||
#define DL_UNMAP(map) _dl_unmap (map)
|
918
sysdeps/tile/dl-machine.h
Normal file
918
sysdeps/tile/dl-machine.h
Normal file
@ -0,0 +1,918 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
Based on work contributed by by Carl Pederson & Martin Schwidefsky.
|
||||
|
||||
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_machine_h
|
||||
#define dl_machine_h
|
||||
|
||||
#ifdef __tilegx__
|
||||
#define ELF_MACHINE_NAME "tilegx"
|
||||
#else
|
||||
#define ELF_MACHINE_NAME "tilepro"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
#include <link.h>
|
||||
#include <bits/wordsize.h>
|
||||
#include <arch/icache.h>
|
||||
#include <arch/opcode.h>
|
||||
|
||||
/* Return nonzero iff ELF header is compatible with the running host. */
|
||||
static inline int
|
||||
elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
|
||||
{
|
||||
#if defined __tilegx__
|
||||
if (ehdr->e_machine != EM_TILEGX)
|
||||
return 0;
|
||||
# if __WORDSIZE == 32
|
||||
return (ehdr->e_ident[EI_CLASS] == ELFCLASS32);
|
||||
# else
|
||||
return (ehdr->e_ident[EI_CLASS] == ELFCLASS64);
|
||||
# endif
|
||||
#elif defined __tilepro__
|
||||
return ehdr->e_machine == EM_TILEPRO;
|
||||
#else
|
||||
# error "Unknown tile architecture."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
|
||||
first element of the GOT. This must be inlined in a function which
|
||||
uses global data. */
|
||||
|
||||
static inline ElfW(Addr)
|
||||
elf_machine_dynamic (void)
|
||||
{
|
||||
ElfW(Addr) *got;
|
||||
|
||||
#ifdef __tilegx__
|
||||
ElfW(Addr) tmp;
|
||||
asm( " { lnk %0; moveli %1, hw2_last(_GLOBAL_OFFSET_TABLE_ - 1f) }\n"
|
||||
"1: shl16insli %1, %1, hw1(_GLOBAL_OFFSET_TABLE_ - 1b)\n"
|
||||
" shl16insli %1, %1, hw0(_GLOBAL_OFFSET_TABLE_ - 1b)\n"
|
||||
" add %0, %0, %1"
|
||||
: "=r" (got), "=r" (tmp));
|
||||
#else
|
||||
asm( " lnk %0\n"
|
||||
"1: addli %0, %0, lo16(_GLOBAL_OFFSET_TABLE_ - 1b)\n"
|
||||
" auli %0, %0, ha16(_GLOBAL_OFFSET_TABLE_ - 1b)"
|
||||
: "=r" (got));
|
||||
#endif
|
||||
|
||||
return *got;
|
||||
}
|
||||
|
||||
|
||||
/* Return the run-time load address of the shared object. */
|
||||
static inline ElfW(Addr)
|
||||
elf_machine_load_address (void)
|
||||
{
|
||||
ElfW(Addr) *got;
|
||||
ElfW(Addr) dynamic;
|
||||
|
||||
#ifdef __tilegx__
|
||||
ElfW(Addr) tmp;
|
||||
asm( " lnk %2\n"
|
||||
"1: {\n"
|
||||
" moveli %0, hw2_last(_GLOBAL_OFFSET_TABLE_ - 1b)\n"
|
||||
" moveli %1, hw2_last(_DYNAMIC - 1b)\n"
|
||||
" }\n"
|
||||
" {\n"
|
||||
" shl16insli %0, %0, hw1(_GLOBAL_OFFSET_TABLE_ - 1b)\n"
|
||||
" shl16insli %1, %1, hw1(_DYNAMIC - 1b)\n"
|
||||
" }\n"
|
||||
" {\n"
|
||||
" shl16insli %0, %0, hw0(_GLOBAL_OFFSET_TABLE_ - 1b)\n"
|
||||
" shl16insli %1, %1, hw0(_DYNAMIC - 1b)\n"
|
||||
" }\n"
|
||||
" {\n"
|
||||
" add %0, %0, %2\n"
|
||||
" add %1, %1, %2\n"
|
||||
" }"
|
||||
: "=r" (got), "=r" (dynamic), "=r" (tmp));
|
||||
#else
|
||||
asm( " lnk %0\n"
|
||||
"1: {\n"
|
||||
" addli %0, %0, lo16(_GLOBAL_OFFSET_TABLE_ - 1b)\n"
|
||||
" addli %1, %0, lo16(_DYNAMIC - 1b)\n"
|
||||
" }\n"
|
||||
" {\n"
|
||||
" auli %0, %0, ha16(_GLOBAL_OFFSET_TABLE_ - 1b)\n"
|
||||
" auli %1, %1, ha16(_DYNAMIC - 1b)\n"
|
||||
" }\n"
|
||||
: "=r" (got), "=r" (dynamic));
|
||||
#endif
|
||||
|
||||
return dynamic - *got;
|
||||
}
|
||||
|
||||
/* Flush some range of the instruction cache. If invoked prior to
|
||||
actually setting dl_pagesize, we conservatively use 4KB, which
|
||||
is the smallest page size we could plausibly be running with. */
|
||||
static inline void
|
||||
_dl_flush_icache (const void *addr, unsigned long size)
|
||||
{
|
||||
invalidate_icache (addr, size, GLRO(dl_pagesize) ? : 4096);
|
||||
}
|
||||
|
||||
/* Set up the loaded object described by L so its unrelocated PLT
|
||||
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||
|
||||
static inline int __attribute__ ((unused))
|
||||
elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
{
|
||||
ElfW(Addr) *gotplt;
|
||||
extern void _dl_runtime_resolve (ElfW(Word));
|
||||
extern void _dl_runtime_profile (ElfW(Word));
|
||||
|
||||
if (l->l_info[DT_JMPREL] && lazy)
|
||||
{
|
||||
gotplt = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
|
||||
|
||||
/* The GOT entries for functions in the PLT have not yet been filled
|
||||
in. Their initial contents will arrange when called to put in
|
||||
registers an offset into the .rel.plt section, and gotplt[0], then
|
||||
jump to gotplt[1]. */
|
||||
|
||||
/* Identify this shared object. */
|
||||
gotplt[0] = (ElfW(Addr)) l;
|
||||
|
||||
/* The gotplt[1] entry contains the address of a function which gets
|
||||
called to get the address of a so far unresolved function and jump
|
||||
to it. The profiling extension of the dynamic linker allows to
|
||||
intercept the calls to collect information. In this case we don't
|
||||
store the address in the GOTPLT so that all future calls also end
|
||||
in this function. */
|
||||
if (__builtin_expect (profile, 0))
|
||||
{
|
||||
gotplt[1] = (ElfW(Addr)) &_dl_runtime_profile;
|
||||
|
||||
if (GLRO(dl_profile) != NULL
|
||||
&& _dl_name_match_p (GLRO(dl_profile), l))
|
||||
/* This is the object we are looking for. Say that we really
|
||||
want profiling and the timers are started. */
|
||||
GL(dl_profile_map) = l;
|
||||
}
|
||||
else
|
||||
/* This function will get called to fix up the GOTPLT entry
|
||||
indicated by the offset on the stack, and then jump to the
|
||||
resolved address. */
|
||||
gotplt[1] = (ElfW(Addr)) &_dl_runtime_resolve;
|
||||
}
|
||||
|
||||
return lazy;
|
||||
}
|
||||
|
||||
#if __WORDSIZE == 32
|
||||
/* Mask identifying addresses reserved for the user program,
|
||||
where the dynamic linker should not map anything. */
|
||||
#define ELF_MACHINE_USER_ADDRESS_MASK 0xf8000000UL
|
||||
#endif
|
||||
|
||||
/* Initial entry point code for the dynamic linker.
|
||||
The C function `_dl_start' is the real entry point;
|
||||
its return value is the user program's entry point. */
|
||||
|
||||
#define RTLD_START asm (".globl _dl_start");
|
||||
|
||||
#ifndef RTLD_START_SPECIAL_INIT
|
||||
#define RTLD_START_SPECIAL_INIT /* nothing */
|
||||
#endif
|
||||
|
||||
/* Wrap a generic Tilera relocation type. */
|
||||
#ifdef __tilegx__
|
||||
#define R_TILE(x) R_TILEGX_##x
|
||||
#define __R_TILE_TLS(x,c) R_TILEGX_TLS_##x##c
|
||||
#define _R_TILE_TLS(x,c) __R_TILE_TLS(x,c)
|
||||
#define R_TILE_TLS(x) _R_TILE_TLS(x,__ELF_NATIVE_CLASS)
|
||||
#else
|
||||
#define R_TILE(x) R_TILEPRO_##x
|
||||
#define R_TILE_TLS(x) R_TILEPRO_TLS_##x##32
|
||||
#endif
|
||||
|
||||
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
|
||||
TLS variable, so undefined references 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) \
|
||||
((((type) == R_TILE(JMP_SLOT) || (type) == R_TILE_TLS(DTPMOD) \
|
||||
|| (type) == R_TILE_TLS(DTPOFF) || (type) == R_TILE_TLS(TPOFF)) \
|
||||
* ELF_RTYPE_CLASS_PLT) \
|
||||
| (((type) == R_TILE(COPY)) * ELF_RTYPE_CLASS_COPY))
|
||||
|
||||
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
|
||||
#define ELF_MACHINE_JMP_SLOT R_TILE(JMP_SLOT)
|
||||
|
||||
/* TILE never uses Elf32_Rel relocations. */
|
||||
#define ELF_MACHINE_NO_REL 1
|
||||
|
||||
/* TILE overlaps DT_RELA and DT_PLTREL. */
|
||||
#define ELF_MACHINE_PLTREL_OVERLAP 1
|
||||
|
||||
/* We define an initialization functions. This is called very early in
|
||||
_dl_sysdep_start. */
|
||||
#define DL_PLATFORM_INIT dl_platform_init ()
|
||||
|
||||
static inline void __attribute__ ((unused))
|
||||
dl_platform_init (void)
|
||||
{
|
||||
if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
|
||||
/* Avoid an empty string which would disturb us. */
|
||||
GLRO(dl_platform) = NULL;
|
||||
}
|
||||
|
||||
static inline ElfW(Addr)
|
||||
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
|
||||
const ElfW(Rela) *reloc,
|
||||
ElfW(Addr) *reloc_addr, ElfW(Addr) value)
|
||||
{
|
||||
return *reloc_addr = value;
|
||||
}
|
||||
|
||||
/* Return the final value of a plt relocation. */
|
||||
static inline ElfW(Addr)
|
||||
elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc,
|
||||
ElfW(Addr) value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Support notifying the simulator about new objects. */
|
||||
void internal_function _dl_arch_map_object (struct link_map *l);
|
||||
#define _dl_arch_map_object _dl_arch_map_object
|
||||
|
||||
/* Names of the architecture-specific auditing callback functions. */
|
||||
#define ARCH_LA_PLTENTER tile_gnu_pltenter
|
||||
#define ARCH_LA_PLTEXIT tile_gnu_pltexit
|
||||
|
||||
#endif /* !dl_machine_h */
|
||||
|
||||
|
||||
#ifdef RESOLVE_MAP
|
||||
|
||||
struct reloc_howto
|
||||
{
|
||||
/* Right shift operand by this number of bits. */
|
||||
unsigned char right_shift;
|
||||
|
||||
#ifdef __tilegx__
|
||||
/* If nonzero, this is updating a code bundle. */
|
||||
unsigned char is_bundle_update;
|
||||
#else
|
||||
/* If nonzero, add 0x8000 to the value. */
|
||||
unsigned char add_0x8000;
|
||||
#endif
|
||||
|
||||
/* If nonzero, subtract the containing address from the address. */
|
||||
unsigned char is_pcrel;
|
||||
|
||||
/* Size in bytes, or 0 if this table entry should be ignored. */
|
||||
unsigned char byte_size;
|
||||
};
|
||||
|
||||
/* Relocation information. Cannot contain create_* function pointers
|
||||
because then the table would not be position-independent. */
|
||||
static const struct reloc_howto howto[] =
|
||||
{
|
||||
#ifdef __tilegx__
|
||||
|
||||
# if __WORDSIZE == 32
|
||||
/* The GX -m32 loader only handles 32-bit types, so it will be confused
|
||||
by shifts larger than that. We convert them to just sign-extend;
|
||||
they usually indicate a program bug or missed optimization, but we
|
||||
have to handle them correctly anyway. */
|
||||
# define S32 31
|
||||
# define S48 31
|
||||
# else
|
||||
# define S32 32
|
||||
# define S48 48
|
||||
# endif
|
||||
|
||||
/* R_TILEGX_NONE */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_64 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEGX_32 */ { 0, 0, 0, 4 },
|
||||
/* R_TILEGX_16 */ { 0, 0, 0, 2 },
|
||||
/* R_TILEGX_8 */ { 0, 0, 0, 1 },
|
||||
/* R_TILEGX_64_PCREL */ { 0, 0, 1, 8 },
|
||||
/* R_TILEGX_32_PCREL */ { 0, 0, 1, 4 },
|
||||
/* R_TILEGX_16_PCREL */ { 0, 0, 1, 2 },
|
||||
/* R_TILEGX_8_PCREL */ { 0, 0, 1, 1 },
|
||||
/* R_TILEGX_HW0 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_HW1 */ { 16, 0, 0, 0 },
|
||||
/* R_TILEGX_HW2 */ { S32, 0, 0, 0 },
|
||||
/* R_TILEGX_HW3 */ { S48, 0, 0, 0 },
|
||||
/* R_TILEGX_HW0_LAST */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_HW1_LAST */ { 16, 0, 0, 0 },
|
||||
/* R_TILEGX_HW2_LAST */ { S32, 0, 0, 0 },
|
||||
/* R_TILEGX_COPY */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_GLOB_DAT */ { 0, 0, 0, 8 },
|
||||
/* R_TILEGX_JMP_SLOT */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_RELATIVE */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_BROFF_X1 */ { 3, 1, 1, 8 },
|
||||
/* R_TILEGX_JUMPOFF_X1 */ { 3, 1, 1, 8 },
|
||||
/* R_TILEGX_JUMPOFF_X1_PLT */ { 3, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM8_X0 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM8_Y0 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM8_X1 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM8_Y1 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_DEST_IMM8_X1 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_MT_IMM14_X1 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_MF_IMM14_X1 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_MMSTART_X0 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_MMEND_X0 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_SHAMT_X0 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_SHAMT_X1 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_SHAMT_Y0 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_SHAMT_Y1 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW0 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW0 */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW1 */ { 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW1 */ { 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW2 */ { S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW2 */ { S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW3 */ { S48, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW3 */ { S48, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW0_LAST */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW0_LAST */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW1_LAST */ { 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW1_LAST */ { 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW2_LAST */ { S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW2_LAST */ { S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW0_PCREL */ { 0, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW0_PCREL */ { 0, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW1_PCREL */ { 16, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW1_PCREL */ { 16, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW2_PCREL */ { S32, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW2_PCREL */ { S32, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW3_PCREL */ { S48, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW3_PCREL */ { S48, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW0_LAST_PCREL */ { 0, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW0_LAST_PCREL */ { 0, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW1_LAST_PCREL */ { 16, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW1_LAST_PCREL */ { 16, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW2_LAST_PCREL */ { S32, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW2_LAST_PCREL */ { S32, 1, 1, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW0_GOT */ { 0, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X1_HW0_GOT */ { 0, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X0_HW1_GOT */ { 16, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X1_HW1_GOT */ { 16, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X0_HW2_GOT */ { S32, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X1_HW2_GOT */ { S32, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X0_HW3_GOT */ { S48, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X1_HW3_GOT */ { S48, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X0_HW0_LAST_GOT */ { 0, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X1_HW0_LAST_GOT */ { 0, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X0_HW1_LAST_GOT */ { 16, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X1_HW1_LAST_GOT */ { 16, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X0_HW2_LAST_GOT */ { S32, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X1_HW2_LAST_GOT */ { S32, 1, 0, 0 },
|
||||
/* R_TILEGX_IMM16_X0_HW0_TLS_GD */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW0_TLS_GD */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW1_TLS_GD */ { 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW1_TLS_GD */ { 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW2_TLS_GD */ { S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW2_TLS_GD */ { S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW3_TLS_GD */ { S48, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW3_TLS_GD */ { S48, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD */{ 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD */{ 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD */{ 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD */{ 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW2_LAST_TLS_GD */{ S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW2_LAST_TLS_GD */{ S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW0_TLS_IE */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW0_TLS_IE */ { 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW1_TLS_IE */ { 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW1_TLS_IE */ { 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW2_TLS_IE */ { S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW2_TLS_IE */ { S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW3_TLS_IE */ { S48, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW3_TLS_IE */ { S48, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE */{ 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE */{ 0, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE */{ 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE */{ 16, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X0_HW2_LAST_TLS_IE */{ S32, 1, 0, 8 },
|
||||
/* R_TILEGX_IMM16_X1_HW2_LAST_TLS_IE */{ S32, 1, 0, 8 },
|
||||
/* R_TILEGX_TLS_DTPMOD64 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_TLS_DTPOFF64 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_TLS_TPOFF64 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_TLS_DTPMOD32 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_TLS_DTPOFF32 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEGX_TLS_TPOFF32 */ { 0, 0, 0, 0 }
|
||||
#else
|
||||
/* R_TILEPRO_NONE */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_32 */ { 0, 0, 0, 4 },
|
||||
/* R_TILEPRO_16 */ { 0, 0, 0, 2 },
|
||||
/* R_TILEPRO_8 */ { 0, 0, 0, 1 },
|
||||
/* R_TILEPRO_32_PCREL */ { 0, 0, 1, 4 },
|
||||
/* R_TILEPRO_16_PCREL */ { 0, 0, 1, 2 },
|
||||
/* R_TILEPRO_8_PCREL */ { 0, 0, 1, 1 },
|
||||
/* R_TILEPRO_LO16 */ { 0, 0, 0, 2 },
|
||||
/* R_TILEPRO_HI16 */ { 16, 0, 0, 2 },
|
||||
/* R_TILEPRO_HA16 */ { 16, 1, 0, 2 },
|
||||
/* R_TILEPRO_COPY */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_GLOB_DAT */ { 0, 0, 0, 4 },
|
||||
/* R_TILEPRO_JMP_SLOT */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_RELATIVE */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_BROFF_X1 */ { 3, 0, 1, 8 },
|
||||
/* R_TILEPRO_JOFFLONG_X1 */ { 3, 0, 1, 8 },
|
||||
/* R_TILEPRO_JOFFLONG_X1_PLT */ { 3, 0, 1, 8 },
|
||||
/* R_TILEPRO_IMM8_X0 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM8_Y0 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM8_X1 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM8_Y1 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_MT_IMM15_X1 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_MF_IMM15_X1 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_LO */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_LO */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_HI */ { 16, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_HI */ { 16, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_HA */ { 16, 1, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_HA */ { 16, 1, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_PCREL */ { 0, 0, 1, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_PCREL */ { 0, 0, 1, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_LO_PCREL */ { 0, 0, 1, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_LO_PCREL */ { 0, 0, 1, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_HI_PCREL */ { 16, 0, 1, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_HI_PCREL */ { 16, 0, 1, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_HA_PCREL */ { 16, 1, 1, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_HA_PCREL */ { 16, 1, 1, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_GOT */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_IMM16_X1_GOT */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_IMM16_X0_GOT_LO */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_IMM16_X1_GOT_LO */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_IMM16_X0_GOT_HI */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_IMM16_X1_GOT_HI */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_IMM16_X0_GOT_HA */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_IMM16_X1_GOT_HA */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_MMSTART_X0 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_MMEND_X0 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_MMSTART_X1 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_MMEND_X1 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_SHAMT_X0 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_SHAMT_X1 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_SHAMT_Y0 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_SHAMT_Y1 */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_SN_BROFF */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_SN_IMM8 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_SN_UIMM8 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_SN_BYTE0 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_SN_BYTE1 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_SN_BYTE2 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_SN_BYTE3 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_SN_SPCREL0 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_SN_SPCREL1 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_SN_SPCREL2 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_SN_SPCREL3 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_IMM16_X0_TLS_GD */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_TLS_GD */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_TLS_GD_LO */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_TLS_GD_LO */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_TLS_GD_HI */ { 16, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_TLS_GD_HI */ { 16, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_TLS_GD_HA */ { 16, 1, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_TLS_GD_HA */ { 16, 1, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_TLS_IE */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_TLS_IE */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_TLS_IE_LO */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_TLS_IE_LO */ { 0, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_TLS_IE_HI */ { 16, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_TLS_IE_HI */ { 16, 0, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X0_TLS_IE_HA */ { 16, 1, 0, 8 },
|
||||
/* R_TILEPRO_IMM16_X1_TLS_IE_HA */ { 16, 1, 0, 8 },
|
||||
/* R_TILEPRO_TLS_DTPMOD32 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_TLS_DTPOFF32 */ { 0, 0, 0, 0 },
|
||||
/* R_TILEPRO_TLS_TPOFF32 */ { 0, 0, 0, 0 },
|
||||
#endif
|
||||
};
|
||||
|
||||
#if __ELF_NATIVE_CLASS == 32
|
||||
#define ELFW_R_TYPE ELF32_R_TYPE
|
||||
#define ELFW_ST_TYPE ELF32_ST_TYPE
|
||||
#else
|
||||
#define ELFW_R_TYPE ELF64_R_TYPE
|
||||
#define ELFW_ST_TYPE ELF64_ST_TYPE
|
||||
#endif
|
||||
|
||||
/* 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 ElfW(Rela) *reloc,
|
||||
const ElfW(Sym) *sym, const struct r_found_version *version,
|
||||
void *const reloc_addr_arg, int skip_ifunc)
|
||||
{
|
||||
ElfW(Addr) *const reloc_addr = reloc_addr_arg;
|
||||
const unsigned int r_type = ELFW_R_TYPE (reloc->r_info);
|
||||
|
||||
#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
|
||||
if (__builtin_expect (r_type == R_TILE(RELATIVE), 0))
|
||||
{
|
||||
# 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. */
|
||||
# ifndef SHARED
|
||||
weak_extern (GL(dl_rtld_map));
|
||||
# endif
|
||||
if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
|
||||
# endif
|
||||
*reloc_addr = map->l_addr + reloc->r_addend;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (r_type == R_TILE(NONE), 0))
|
||||
return;
|
||||
|
||||
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
const ElfW(Sym) *const refsym = sym;
|
||||
#endif
|
||||
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||
ElfW(Addr) value;
|
||||
|
||||
if (sym == NULL)
|
||||
value = 0;
|
||||
else if (ELFW_ST_TYPE (sym->st_info) == STT_SECTION)
|
||||
value = map->l_addr; /* like a RELATIVE reloc */
|
||||
else
|
||||
value = sym_map->l_addr + sym->st_value;
|
||||
|
||||
if (sym != NULL
|
||||
&& __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
|
||||
&& __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
|
||||
&& __builtin_expect (!skip_ifunc, 1))
|
||||
value = ((Elf64_Addr (*) (void)) value) ();
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_TILE(JMP_SLOT):
|
||||
elf_machine_fixup_plt (map, 0, reloc, reloc_addr,
|
||||
value + reloc->r_addend);
|
||||
return;
|
||||
|
||||
#ifndef RESOLVE_CONFLICT_FIND_MAP
|
||||
case R_TILE_TLS(DTPMOD):
|
||||
# ifdef RTLD_BOOTSTRAP
|
||||
/* During startup the dynamic linker is always the module
|
||||
with index 1.
|
||||
XXX If this relocation is necessary move before RESOLVE
|
||||
call. */
|
||||
*reloc_addr = 1;
|
||||
# else
|
||||
/* Get the information from the link map returned by the
|
||||
resolv function. */
|
||||
if (sym_map != NULL)
|
||||
*reloc_addr = sym_map->l_tls_modid;
|
||||
# endif
|
||||
return;
|
||||
case R_TILE_TLS(DTPOFF):
|
||||
# ifndef RTLD_BOOTSTRAP
|
||||
/* During relocation all TLS symbols are defined and used.
|
||||
Therefore the offset is already correct. */
|
||||
if (sym != NULL)
|
||||
*reloc_addr = sym->st_value + reloc->r_addend;
|
||||
# endif
|
||||
return;
|
||||
case R_TILE_TLS(TPOFF):
|
||||
# ifdef RTLD_BOOTSTRAP
|
||||
*reloc_addr = sym->st_value + reloc->r_addend + map->l_tls_offset;
|
||||
# else
|
||||
if (sym != NULL)
|
||||
{
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr = (sym->st_value + reloc->r_addend
|
||||
+ sym_map->l_tls_offset);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
#endif /* use TLS */
|
||||
|
||||
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
/* Not needed in dl-conflict.c. */
|
||||
case R_TILE(COPY):
|
||||
if (sym == NULL)
|
||||
/* This can happen in trace mode if an object could not be found. */
|
||||
return;
|
||||
if (__builtin_expect (sym->st_size > refsym->st_size, 0)
|
||||
|| (__builtin_expect (sym->st_size < refsym->st_size, 0)
|
||||
&& __builtin_expect (GLRO(dl_verbose), 0)))
|
||||
{
|
||||
const char *strtab;
|
||||
|
||||
strtab = (const char *) D_PTR (map,l_info[DT_STRTAB]);
|
||||
_dl_error_printf ("%s: Symbol `%s' has different size in shared"
|
||||
" object, consider re-linking\n",
|
||||
rtld_progname ?: "<program name unknown>",
|
||||
strtab + refsym->st_name);
|
||||
}
|
||||
memcpy (reloc_addr_arg, (void *) value,
|
||||
MIN (sym->st_size, refsym->st_size));
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* All remaining relocations must be in the lookup table. */
|
||||
const struct reloc_howto *h = &howto[r_type];
|
||||
if ((unsigned int) r_type >= sizeof howto / sizeof howto[0] ||
|
||||
h->byte_size == 0)
|
||||
{
|
||||
#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
|
||||
/* We add these checks in the version to relocate ld.so only
|
||||
if we are still debugging. */
|
||||
_dl_reloc_bad_type (map, r_type, 0);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
value += reloc->r_addend;
|
||||
|
||||
/* The lookup table entry knows how to perform this reloc. */
|
||||
if (h->is_pcrel)
|
||||
value -= (ElfW(Addr)) reloc_addr;
|
||||
|
||||
#ifndef __tilegx__
|
||||
if (h->add_0x8000)
|
||||
value += 0x8000;
|
||||
#endif
|
||||
|
||||
value >>= h->right_shift;
|
||||
|
||||
switch (h->byte_size)
|
||||
{
|
||||
case 1:
|
||||
*(char *) reloc_addr = value;
|
||||
return;
|
||||
case 2:
|
||||
*(short *) reloc_addr = value;
|
||||
return;
|
||||
case 4:
|
||||
*(int *) reloc_addr = value;
|
||||
return;
|
||||
#ifdef __tilegx__
|
||||
case 8:
|
||||
if (!h->is_bundle_update)
|
||||
{
|
||||
*(ElfW(Addr) *) reloc_addr = value;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* We are updating a bundle, so use the function pointer that
|
||||
swizzles the operand bits into the right location. */
|
||||
|
||||
tile_bundle_bits *p = (tile_bundle_bits *) reloc_addr;
|
||||
tile_bundle_bits bits = *p;
|
||||
|
||||
#define MUNGE(func) do { \
|
||||
bits = ((bits & ~create_##func (-1)) | create_##func (value)); \
|
||||
if (get_##func (bits) != value) \
|
||||
_dl_signal_error (0, map->l_name, NULL, \
|
||||
"relocation value too large for " #func); \
|
||||
} while (0)
|
||||
|
||||
#define MUNGE_NOCHECK(func) \
|
||||
bits = ((bits & ~create_##func (-1)) | create_##func (value))
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
#ifdef __tilegx__
|
||||
case R_TILEGX_BROFF_X1:
|
||||
MUNGE (BrOff_X1);
|
||||
break;
|
||||
case R_TILEGX_JUMPOFF_X1:
|
||||
case R_TILEGX_JUMPOFF_X1_PLT:
|
||||
MUNGE (JumpOff_X1);
|
||||
break;
|
||||
case R_TILEGX_IMM8_X0:
|
||||
MUNGE (Imm8_X0);
|
||||
break;
|
||||
case R_TILEGX_IMM8_Y0:
|
||||
MUNGE (Imm8_Y0);
|
||||
break;
|
||||
case R_TILEGX_IMM8_X1:
|
||||
MUNGE (Imm8_X1);
|
||||
break;
|
||||
case R_TILEGX_IMM8_Y1:
|
||||
MUNGE (Imm8_Y1);
|
||||
break;
|
||||
case R_TILEGX_MT_IMM14_X1:
|
||||
MUNGE (MT_Imm14_X1);
|
||||
break;
|
||||
case R_TILEGX_MF_IMM14_X1:
|
||||
MUNGE (MF_Imm14_X1);
|
||||
break;
|
||||
case R_TILEGX_IMM16_X0_HW0:
|
||||
case R_TILEGX_IMM16_X0_HW1:
|
||||
case R_TILEGX_IMM16_X0_HW2:
|
||||
case R_TILEGX_IMM16_X0_HW3:
|
||||
case R_TILEGX_IMM16_X0_HW0_PCREL:
|
||||
case R_TILEGX_IMM16_X0_HW1_PCREL:
|
||||
case R_TILEGX_IMM16_X0_HW2_PCREL:
|
||||
case R_TILEGX_IMM16_X0_HW3_PCREL:
|
||||
case R_TILEGX_IMM16_X0_HW0_TLS_GD:
|
||||
case R_TILEGX_IMM16_X0_HW0_TLS_IE:
|
||||
MUNGE_NOCHECK (Imm16_X0);
|
||||
break;
|
||||
case R_TILEGX_IMM16_X0_HW0_LAST:
|
||||
case R_TILEGX_IMM16_X0_HW1_LAST:
|
||||
case R_TILEGX_IMM16_X0_HW2_LAST:
|
||||
case R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
|
||||
case R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
|
||||
case R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
|
||||
case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
|
||||
case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
|
||||
case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
|
||||
case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
|
||||
MUNGE (Imm16_X0);
|
||||
break;
|
||||
case R_TILEGX_IMM16_X1_HW0:
|
||||
case R_TILEGX_IMM16_X1_HW1:
|
||||
case R_TILEGX_IMM16_X1_HW2:
|
||||
case R_TILEGX_IMM16_X1_HW3:
|
||||
case R_TILEGX_IMM16_X1_HW0_PCREL:
|
||||
case R_TILEGX_IMM16_X1_HW1_PCREL:
|
||||
case R_TILEGX_IMM16_X1_HW2_PCREL:
|
||||
case R_TILEGX_IMM16_X1_HW3_PCREL:
|
||||
case R_TILEGX_IMM16_X1_HW0_TLS_GD:
|
||||
case R_TILEGX_IMM16_X1_HW0_TLS_IE:
|
||||
MUNGE_NOCHECK (Imm16_X1);
|
||||
break;
|
||||
case R_TILEGX_IMM16_X1_HW0_LAST:
|
||||
case R_TILEGX_IMM16_X1_HW1_LAST:
|
||||
case R_TILEGX_IMM16_X1_HW2_LAST:
|
||||
case R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
|
||||
case R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
|
||||
case R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
|
||||
case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
|
||||
case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
|
||||
case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
|
||||
case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
|
||||
MUNGE (Imm16_X1);
|
||||
break;
|
||||
case R_TILEGX_MMSTART_X0:
|
||||
MUNGE (BFStart_X0);
|
||||
break;
|
||||
case R_TILEGX_MMEND_X0:
|
||||
MUNGE (BFEnd_X0);
|
||||
break;
|
||||
case R_TILEGX_SHAMT_X0:
|
||||
MUNGE (ShAmt_X0);
|
||||
break;
|
||||
case R_TILEGX_SHAMT_X1:
|
||||
MUNGE (ShAmt_X1);
|
||||
break;
|
||||
case R_TILEGX_SHAMT_Y0:
|
||||
MUNGE (ShAmt_Y0);
|
||||
break;
|
||||
case R_TILEGX_SHAMT_Y1:
|
||||
MUNGE (ShAmt_Y1);
|
||||
break;
|
||||
#else
|
||||
case R_TILEPRO_BROFF_X1:
|
||||
MUNGE (BrOff_X1);
|
||||
break;
|
||||
case R_TILEPRO_JOFFLONG_X1:
|
||||
case R_TILEPRO_JOFFLONG_X1_PLT:
|
||||
MUNGE_NOCHECK (JOffLong_X1); /* holds full 32-bit value */
|
||||
break;
|
||||
case R_TILEPRO_IMM8_X0:
|
||||
MUNGE (Imm8_X0);
|
||||
break;
|
||||
case R_TILEPRO_IMM8_Y0:
|
||||
MUNGE (Imm8_Y0);
|
||||
break;
|
||||
case R_TILEPRO_IMM8_X1:
|
||||
MUNGE (Imm8_X1);
|
||||
break;
|
||||
case R_TILEPRO_IMM8_Y1:
|
||||
MUNGE (Imm8_Y1);
|
||||
break;
|
||||
case R_TILEPRO_MT_IMM15_X1:
|
||||
MUNGE (MT_Imm15_X1);
|
||||
break;
|
||||
case R_TILEPRO_MF_IMM15_X1:
|
||||
MUNGE (MF_Imm15_X1);
|
||||
break;
|
||||
case R_TILEPRO_IMM16_X0_LO:
|
||||
case R_TILEPRO_IMM16_X0_HI:
|
||||
case R_TILEPRO_IMM16_X0_HA:
|
||||
case R_TILEPRO_IMM16_X0_LO_PCREL:
|
||||
case R_TILEPRO_IMM16_X0_HI_PCREL:
|
||||
case R_TILEPRO_IMM16_X0_HA_PCREL:
|
||||
case R_TILEPRO_IMM16_X0_TLS_GD_LO:
|
||||
case R_TILEPRO_IMM16_X0_TLS_GD_HI:
|
||||
case R_TILEPRO_IMM16_X0_TLS_GD_HA:
|
||||
case R_TILEPRO_IMM16_X0_TLS_IE_LO:
|
||||
case R_TILEPRO_IMM16_X0_TLS_IE_HI:
|
||||
case R_TILEPRO_IMM16_X0_TLS_IE_HA:
|
||||
MUNGE_NOCHECK (Imm16_X0);
|
||||
break;
|
||||
case R_TILEPRO_IMM16_X0:
|
||||
case R_TILEPRO_IMM16_X0_PCREL:
|
||||
case R_TILEPRO_IMM16_X0_TLS_GD:
|
||||
case R_TILEPRO_IMM16_X0_TLS_IE:
|
||||
MUNGE (Imm16_X0);
|
||||
break;
|
||||
case R_TILEPRO_IMM16_X1_LO:
|
||||
case R_TILEPRO_IMM16_X1_HI:
|
||||
case R_TILEPRO_IMM16_X1_HA:
|
||||
case R_TILEPRO_IMM16_X1_LO_PCREL:
|
||||
case R_TILEPRO_IMM16_X1_HI_PCREL:
|
||||
case R_TILEPRO_IMM16_X1_HA_PCREL:
|
||||
case R_TILEPRO_IMM16_X1_TLS_GD_LO:
|
||||
case R_TILEPRO_IMM16_X1_TLS_GD_HI:
|
||||
case R_TILEPRO_IMM16_X1_TLS_GD_HA:
|
||||
case R_TILEPRO_IMM16_X1_TLS_IE_LO:
|
||||
case R_TILEPRO_IMM16_X1_TLS_IE_HI:
|
||||
case R_TILEPRO_IMM16_X1_TLS_IE_HA:
|
||||
MUNGE_NOCHECK (Imm16_X1);
|
||||
break;
|
||||
case R_TILEPRO_IMM16_X1:
|
||||
case R_TILEPRO_IMM16_X1_PCREL:
|
||||
case R_TILEPRO_IMM16_X1_TLS_GD:
|
||||
case R_TILEPRO_IMM16_X1_TLS_IE:
|
||||
MUNGE (Imm16_X1);
|
||||
break;
|
||||
case R_TILEPRO_MMSTART_X0:
|
||||
MUNGE (MMStart_X0);
|
||||
break;
|
||||
case R_TILEPRO_MMEND_X0:
|
||||
MUNGE (MMEnd_X0);
|
||||
break;
|
||||
case R_TILEPRO_MMSTART_X1:
|
||||
MUNGE (MMStart_X1);
|
||||
break;
|
||||
case R_TILEPRO_MMEND_X1:
|
||||
MUNGE (MMEnd_X1);
|
||||
break;
|
||||
case R_TILEPRO_SHAMT_X0:
|
||||
MUNGE (ShAmt_X0);
|
||||
break;
|
||||
case R_TILEPRO_SHAMT_X1:
|
||||
MUNGE (ShAmt_X1);
|
||||
break;
|
||||
case R_TILEPRO_SHAMT_Y0:
|
||||
MUNGE (ShAmt_Y0);
|
||||
break;
|
||||
case R_TILEPRO_SHAMT_Y1:
|
||||
MUNGE (ShAmt_Y1);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
#undef MUNGE
|
||||
*p = bits;
|
||||
_dl_flush_icache (p, sizeof (*p));
|
||||
}
|
||||
|
||||
auto inline void __attribute__ ((always_inline))
|
||||
elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
|
||||
void *const reloc_addr_arg)
|
||||
{
|
||||
ElfW(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,
|
||||
ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
|
||||
int skip_ifunc)
|
||||
{
|
||||
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
|
||||
|
||||
/* Check for unexpected PLT reloc type. */
|
||||
if (__builtin_expect (r_type == R_TILE(JMP_SLOT), 1))
|
||||
{
|
||||
*(ElfW(Addr) *) (l_addr + reloc->r_offset) += l_addr;
|
||||
}
|
||||
else
|
||||
_dl_reloc_bad_type (map, r_type, 1);
|
||||
}
|
||||
|
||||
#endif /* RESOLVE_MAP */
|
80
sysdeps/tile/dl-runtime.c
Normal file
80
sysdeps/tile/dl-runtime.c
Normal file
@ -0,0 +1,80 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
/* Like x86_64, we pass the index of the relocation and not its offset.
|
||||
In _dl_profile_fixup and _dl_call_pltexit we also use the index.
|
||||
Therefore it is wasteful to compute the offset in the trampoline
|
||||
just to reverse the operation immediately afterwards. */
|
||||
#define reloc_offset reloc_arg * sizeof (PLTREL)
|
||||
#define reloc_index reloc_arg
|
||||
|
||||
#include <elf/dl-runtime.c>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <arch/sim.h>
|
||||
|
||||
/* Support notifying the simulator about new objects. */
|
||||
void internal_function
|
||||
_dl_arch_map_object (struct link_map *l)
|
||||
{
|
||||
int shift;
|
||||
|
||||
#define DLPUTC(c) __insn_mtspr(SPR_SIM_CONTROL, \
|
||||
(SIM_CONTROL_DLOPEN \
|
||||
| ((c) << _SIM_CONTROL_OPERATOR_BITS)))
|
||||
|
||||
/* Write the library address in hex. */
|
||||
DLPUTC ('0');
|
||||
DLPUTC ('x');
|
||||
for (shift = (int) sizeof (unsigned long) * 8 - 4; shift >= 0; shift -= 4)
|
||||
DLPUTC ("0123456789abcdef"[(l->l_map_start >> shift) & 0xF]);
|
||||
DLPUTC (':');
|
||||
|
||||
/* Write the library path, including the terminating '\0'. */
|
||||
for (size_t i = 0;; i++)
|
||||
{
|
||||
DLPUTC (l->l_name[i]);
|
||||
if (l->l_name[i] == '\0')
|
||||
break;
|
||||
}
|
||||
#undef DLPUTC
|
||||
}
|
||||
|
||||
/* Support notifying the simulator about removed objects prior to munmap(). */
|
||||
void internal_function
|
||||
_dl_unmap (struct link_map *l)
|
||||
{
|
||||
int shift;
|
||||
|
||||
#define DLPUTC(c) __insn_mtspr(SPR_SIM_CONTROL, \
|
||||
(SIM_CONTROL_DLCLOSE \
|
||||
| ((c) << _SIM_CONTROL_OPERATOR_BITS)))
|
||||
|
||||
/* Write the library address in hex. */
|
||||
DLPUTC ('0');
|
||||
DLPUTC ('x');
|
||||
for (shift = (int) sizeof (unsigned long) * 8 - 4; shift >= 0; shift -= 4)
|
||||
DLPUTC ("0123456789abcdef"[(l->l_map_start >> shift) & 0xF]);
|
||||
DLPUTC ('\0');
|
||||
#undef DLPUTC
|
||||
|
||||
__munmap ((void *) l->l_map_start, l->l_map_end - l->l_map_start);
|
||||
}
|
||||
|
||||
#define DL_UNMAP(map) _dl_unmap (map)
|
114
sysdeps/tile/dl-start.S
Normal file
114
sysdeps/tile/dl-start.S
Normal file
@ -0,0 +1,114 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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>
|
||||
|
||||
/* Get address of "sym" in "reg" assuming r51 holds ".Llink". */
|
||||
.macro pic_addr reg, sym
|
||||
#ifdef __tilegx__
|
||||
moveli \reg, hw1_last(\sym - .Llink)
|
||||
shl16insli \reg, \reg, hw0(\sym - .Llink)
|
||||
ADD_PTR \reg, r51, \reg
|
||||
#else
|
||||
ADDLI_PTR \reg, r51, lo16(\sym - .Llink)
|
||||
auli \reg, \reg, ha16(\sym - .Llink)
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.text
|
||||
ENTRY (_start)
|
||||
/* Linux starts us with sp pointing at the conventional Elf layout,
|
||||
but we need to allow two 'caller' words for our ABI convention. */
|
||||
{
|
||||
move r52, sp
|
||||
andi sp, sp, -8
|
||||
}
|
||||
cfi_def_cfa_register (r52)
|
||||
{
|
||||
/* Point sp at base of ABI area; point r4 to the caller-sp word. */
|
||||
ADDI_PTR sp, sp, -(2 * REGSIZE)
|
||||
ADDI_PTR r4, sp, -REGSIZE
|
||||
}
|
||||
{
|
||||
/* Save zero for caller sp in our 'caller' save area, and make
|
||||
sure lr has a zero value, to limit backtraces. */
|
||||
move lr, zero
|
||||
ST r4, zero
|
||||
}
|
||||
{
|
||||
move r0, r52
|
||||
jal _dl_start
|
||||
}
|
||||
/* Save returned start of user program address for later. */
|
||||
move r50, r0
|
||||
|
||||
/* See if we were invoked explicitly with the dynamic loader,
|
||||
in which case we have to adjust the argument vector. */
|
||||
lnk r51; .Llink:
|
||||
pic_addr r4, _dl_skip_args
|
||||
LD4U r4, r4
|
||||
BEQZT r4, .Lno_skip
|
||||
|
||||
/* Load the argc word at the initial sp and adjust it.
|
||||
We basically jump "sp" up over the first few argv entries
|
||||
and write "argc" a little higher up in memory, to be the
|
||||
base of the new kernel-initialized stack area. */
|
||||
LD_PTR r0, r52
|
||||
{
|
||||
sub r0, r0, r4
|
||||
SHL_PTR_ADD r52, r4, r52
|
||||
}
|
||||
{
|
||||
ST_PTR r52, r0
|
||||
SHL_PTR_ADD sp, r4, sp
|
||||
}
|
||||
|
||||
.Lno_skip:
|
||||
/* Call_dl_init (_dl_loaded, argc, argv, envp). See elf/start.s
|
||||
for the layout of memory here; r52 is pointing to "+0". */
|
||||
pic_addr r0, _rtld_local
|
||||
{
|
||||
LD_PTR r1, r52 /* load argc in r1 */
|
||||
ADDLI_PTR r2, r52, __SIZEOF_POINTER__ /* point r2 at argv */
|
||||
}
|
||||
{
|
||||
LD_PTR r0, r0 /* yields _rtld_global._ns_loaded */
|
||||
addi r3, r1, 1
|
||||
move lr, zero
|
||||
}
|
||||
{
|
||||
SHL_PTR_ADD r3, r3, r2 /* point r3 at envp */
|
||||
jal _dl_init_internal
|
||||
}
|
||||
|
||||
/* Call user program whose address we saved in r50.
|
||||
We invoke it just like a static binary, but with _dl_fini
|
||||
in r0 so we can distinguish. */
|
||||
|
||||
pic_addr r0, _dl_fini
|
||||
move lr, zero
|
||||
{
|
||||
move sp, r52
|
||||
jr r50
|
||||
}
|
||||
|
||||
/* Tell backtracer to give up (_start has no caller). */
|
||||
info 2 /* INFO_OP_CANNOT_BACKTRACE */
|
||||
|
||||
END (_start)
|
28
sysdeps/tile/dl-tls.c
Normal file
28
sysdeps/tile/dl-tls.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
#ifdef SHARED
|
||||
/* We provide a fast-path version of __tls_get_addr to allow for
|
||||
the normal case to be fast, both by coding the function tightly,
|
||||
and more importantly by fixing its register clobber API so the
|
||||
compiler can avoid having to set up frames, etc., unnecessarily. */
|
||||
#define __tls_get_addr __tls_get_addr_slow
|
||||
#endif
|
||||
|
||||
#include <elf/dl-tls.c>
|
46
sysdeps/tile/dl-tls.h
Normal file
46
sysdeps/tile/dl-tls.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
|
||||
/* Type used for the representation of TLS information in the GOT. */
|
||||
typedef struct
|
||||
{
|
||||
unsigned long int ti_module;
|
||||
unsigned long int ti_offset;
|
||||
} tls_index;
|
||||
|
||||
/* Fast-path function to get a TLS pointer. */
|
||||
extern void *__tls_get_addr (tls_index *ti);
|
||||
|
||||
/* The thread pointer points to the first static TLS block. */
|
||||
#define TLS_TP_OFFSET 0
|
||||
|
||||
/* Dynamic thread vector pointers at the start of each TLS block. */
|
||||
#define TLS_DTV_OFFSET 0
|
||||
|
||||
/* Compute the value for a GOTTPREL reloc. */
|
||||
#define TLS_TPREL_VALUE(sym_map, sym) \
|
||||
((sym_map)->l_tls_offset + (sym)->st_value - TLS_TP_OFFSET)
|
||||
|
||||
/* Compute the value for a DTPREL reloc. */
|
||||
#define TLS_DTPREL_VALUE(sym) \
|
||||
((sym)->st_value - TLS_DTV_OFFSET)
|
||||
|
||||
/* Value used for dtv entries for which the allocation is delayed. */
|
||||
#define TLS_DTV_UNALLOCATED ((void *) -1l)
|
194
sysdeps/tile/dl-trampoline.S
Normal file
194
sysdeps/tile/dl-trampoline.S
Normal file
@ -0,0 +1,194 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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>
|
||||
#include <arch/abi.h>
|
||||
|
||||
/* This function is called via the PLT header, which is called
|
||||
from an individual PLT entry.
|
||||
|
||||
At this point we have several values passed in:
|
||||
|
||||
lr: return address to original user code
|
||||
r28: the tpnt value to pass to _dl_runtime_resolver
|
||||
r29: the PLT index of the invoked jump table entry.
|
||||
|
||||
We set up a frame entry that looks like this (in int_reg_t units):
|
||||
|
||||
+57: r25 return values from function...
|
||||
+56: r24
|
||||
[...]
|
||||
+33: r1
|
||||
+32: r0
|
||||
+31: PLT index
|
||||
+30: tpnt
|
||||
+29: stackframe
|
||||
+28: caller lr
|
||||
+27: r25 arguments to function...
|
||||
+26: r24
|
||||
[...]
|
||||
+3: r1
|
||||
+2: r0
|
||||
+1: standard ABI slot (sp)
|
||||
+0: standard ABI slot (callee lr)
|
||||
|
||||
The entries from "stackframe" up are only used in _dl_profile_resolve.
|
||||
We save and restore r0 through r25, rather than the strictly
|
||||
architected r0 through r9, to support unusual calling conventions;
|
||||
for example, __tls_get_addr takes r0 and returns r0, but promises
|
||||
not to clobber r1 through r24 to support its usual fast path. */
|
||||
|
||||
#define FRAME_SP (1 * REGSIZE)
|
||||
#define FRAME_REGS (2 * REGSIZE)
|
||||
#define FRAME_LR (28 * REGSIZE) /* Must follow FRAME_REGS */
|
||||
#define FRAME_STACKFRAME (29 * REGSIZE)
|
||||
#define FRAME_TPNT (30 * REGSIZE)
|
||||
#define FRAME_INDEX (31 * REGSIZE)
|
||||
#define FRAME_RETVAL (32 * REGSIZE)
|
||||
|
||||
#define FRAME_SIZE_SMALL (30 * REGSIZE)
|
||||
#define FRAME_SIZE_LARGE (58 * REGSIZE)
|
||||
|
||||
#define FOR_EACH_REG(f) \
|
||||
f(r0); f(r1); f(r2); f(r3); \
|
||||
f(r4); f(r5); f(r6); f(r7); \
|
||||
f(r8); f(r9); f(r10); f(r11); \
|
||||
f(r12); f(r13); f(r14); f(r15); \
|
||||
f(r16); f(r17); f(r18); f(r19); \
|
||||
f(r20); f(r21); f(r22); f(r23); \
|
||||
f(r24); f(r25)
|
||||
|
||||
#define SAVE(REG) { ST r27, REG; ADDI_PTR r27, r27, REGSIZE }
|
||||
#define RESTORE(REG) { LD REG, r27; ADDI_PTR r27, r27, REGSIZE }
|
||||
|
||||
.macro dl_resolve, name, profile, framesize
|
||||
.text
|
||||
.global \name
|
||||
.hidden \name
|
||||
/* Note that cpp expands ENTRY(\name) incorrectly. */
|
||||
.type \name,@function
|
||||
.align 8
|
||||
\name:
|
||||
cfi_startproc
|
||||
{
|
||||
ST sp, lr
|
||||
move r26, sp
|
||||
}
|
||||
{
|
||||
ADDLI_PTR sp, sp, -\framesize
|
||||
ADDLI_PTR r27, sp, FRAME_SP - \framesize
|
||||
}
|
||||
cfi_def_cfa_offset (\framesize)
|
||||
{
|
||||
ST r27, r26
|
||||
ADDI_PTR r27, r27, FRAME_REGS - FRAME_SP
|
||||
}
|
||||
FOR_EACH_REG(SAVE)
|
||||
{
|
||||
ST r27, lr
|
||||
ADDLI_PTR r27, sp, FRAME_TPNT
|
||||
}
|
||||
cfi_offset (lr, FRAME_LR - \framesize)
|
||||
.if \profile
|
||||
{
|
||||
move r0, r28 /* tpnt value */
|
||||
ST r27, r28
|
||||
ADDI_PTR r27, r27, FRAME_INDEX - FRAME_TPNT
|
||||
}
|
||||
{
|
||||
move r1, r29 /* PLT index */
|
||||
ST r27, r29
|
||||
}
|
||||
{
|
||||
move r2, lr /* retaddr */
|
||||
ADDI_PTR r3, sp, FRAME_REGS /* La_tile_regs pointer */
|
||||
}
|
||||
{
|
||||
ADDLI_PTR r4, sp, FRAME_STACKFRAME /* framesize pointer */
|
||||
jal _dl_profile_fixup
|
||||
}
|
||||
ADDLI_PTR r28, sp, FRAME_STACKFRAME
|
||||
LD_PTR r28, r28
|
||||
BGTZ r28, 1f
|
||||
.else
|
||||
{
|
||||
move r0, r28 /* tpnt value 1 */
|
||||
move r1, r29 /* PLT index 2 */
|
||||
}
|
||||
jal _dl_fixup
|
||||
.endif
|
||||
{
|
||||
/* Copy aside the return value so we can restore r0 below. */
|
||||
move r29, r0
|
||||
/* Set up r27 to let us start restoring registers. */
|
||||
ADDLI_PTR r27, sp, FRAME_REGS
|
||||
}
|
||||
FOR_EACH_REG(RESTORE)
|
||||
.if \profile
|
||||
ADDLI_PTR r28, sp, FRAME_STACKFRAME
|
||||
LD r28, r28
|
||||
BGTZ r28, 1f
|
||||
.endif
|
||||
{
|
||||
/* Restore original user return address. */
|
||||
LD lr, r27
|
||||
/* Pop off our stack frame. */
|
||||
ADDLI_PTR sp, sp, \framesize
|
||||
}
|
||||
cfi_def_cfa_offset (0)
|
||||
jr r29 /* Transfer control to freshly loaded code. */
|
||||
jrp lr /* Keep backtracer happy. */
|
||||
|
||||
.if \profile
|
||||
1: jalr r29 /* Call resolved function. */
|
||||
{
|
||||
ADDLI_PTR r28, sp, FRAME_TPNT
|
||||
ADDLI_PTR r27, sp, FRAME_RETVAL
|
||||
}
|
||||
FOR_EACH_REG(SAVE)
|
||||
{
|
||||
LD r0, r28
|
||||
ADDI_PTR r28, r28, FRAME_INDEX - FRAME_TPNT
|
||||
}
|
||||
{
|
||||
LD r1, r28
|
||||
ADDLI_PTR r2, sp, FRAME_REGS
|
||||
}
|
||||
{
|
||||
ADDLI_PTR r3, sp, FRAME_RETVAL
|
||||
jal _dl_call_pltexit
|
||||
}
|
||||
{
|
||||
ADDLI_PTR lr, sp, FRAME_LR
|
||||
ADDLI_PTR r27, sp, FRAME_RETVAL
|
||||
}
|
||||
FOR_EACH_REG(RESTORE)
|
||||
{
|
||||
LD lr, lr
|
||||
ADDLI_PTR sp, sp, \framesize
|
||||
}
|
||||
jrp lr
|
||||
.endif
|
||||
END (\name)
|
||||
.endm
|
||||
|
||||
dl_resolve _dl_runtime_resolve, 0, FRAME_SIZE_SMALL
|
||||
#ifndef PROF
|
||||
dl_resolve _dl_runtime_profile, 1, FRAME_SIZE_LARGE
|
||||
#endif
|
184
sysdeps/tile/elf/start.S
Normal file
184
sysdeps/tile/elf/start.S
Normal file
@ -0,0 +1,184 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
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 is the canonical entry point, usually the first thing in the text
|
||||
segment. The ELF standard tells us that the stack is set up like this on
|
||||
entry (the left side is the offset from "sp"), in units of
|
||||
__SIZEOF_POINTER__ entries:
|
||||
|
||||
+0 argc
|
||||
+1 argv[0]
|
||||
...
|
||||
+(argc+1) NULL
|
||||
+(argc+2) envp[0]
|
||||
...
|
||||
NULL
|
||||
... ElfInfo
|
||||
|
||||
The ElfInfo is pairs of key/value long words following the envp
|
||||
pointers and terminated by a zero-valued key.
|
||||
|
||||
Although not mandated by the standard, it happens to be the case
|
||||
that we store the actual argv and envp strings immediately after
|
||||
the ElfInfo data on the stack.
|
||||
|
||||
On entry r0 points to the shared library termination function, or 0
|
||||
if there isn't one.
|
||||
*/
|
||||
|
||||
#include <features.h>
|
||||
#include <sysdep.h>
|
||||
#include <arch/abi.h>
|
||||
|
||||
.text
|
||||
.global _start
|
||||
.type _start,@function
|
||||
.align 8
|
||||
_start:
|
||||
/* Linux starts us with sp pointing at the conventional Elf layout,
|
||||
but we need to allow two "caller" words for our ABI convention. */
|
||||
{
|
||||
/* Load argc (stored as a "long", equivalent to a pointer type). */
|
||||
LD_PTR r1, sp
|
||||
|
||||
/* Save incoming 'sp', which points to the Elf argument block. */
|
||||
move r52, sp
|
||||
}
|
||||
|
||||
{
|
||||
/* Allocate stack frame callee space for __libc_start_main. */
|
||||
ADDI_PTR r12, sp, -(2 * REGSIZE)
|
||||
}
|
||||
|
||||
{
|
||||
/* Get our PC. */
|
||||
lnk r13
|
||||
|
||||
/* sp is not necessarily properly aligned on startup because
|
||||
of the way ld.so pops off leading argv elements. So align it. */
|
||||
andi sp, r12, -8
|
||||
}
|
||||
.Lmy_pc:
|
||||
|
||||
{
|
||||
/* Pass the address of the shared library termination function. */
|
||||
move r5, r0
|
||||
|
||||
/* Compute location where __libc_start_main's caller is supposed to
|
||||
store its frame pointer. */
|
||||
ADDI_PTR r12, sp, REGSIZE
|
||||
|
||||
/* Zero out callee space for return address. Unnecessary but free.
|
||||
This is just paranoia to help backtracing not go awry. */
|
||||
ST sp, zero
|
||||
}
|
||||
{
|
||||
/* Zero out our frame pointer for __libc_start_main. */
|
||||
ST r12, zero
|
||||
|
||||
/* Zero out lr to make __libc_start_main the end of backtrace. */
|
||||
move lr, zero
|
||||
|
||||
/* Compute a pointer to argv. envp will be determined
|
||||
later in __libc_start_main. We set up the first argument
|
||||
(the address of main) below. */
|
||||
ADDI_PTR r2, r52, __SIZEOF_POINTER__
|
||||
}
|
||||
{
|
||||
/* Pass the highest stack address to user code. */
|
||||
ADDI_PTR r6, sp, (2 * REGSIZE)
|
||||
|
||||
/* Pass address of main() in r0, and of our own entry
|
||||
points to .fini and .init in r3 and r4. */
|
||||
#ifdef __tilegx__
|
||||
moveli r0, hw2_last(main - .Lmy_pc)
|
||||
}
|
||||
{
|
||||
moveli r3, hw2_last(__libc_csu_init - .Lmy_pc)
|
||||
shl16insli r0, r0, hw1(main - .Lmy_pc)
|
||||
}
|
||||
{
|
||||
shl16insli r3, r3, hw1(__libc_csu_init - .Lmy_pc)
|
||||
shl16insli r0, r0, hw0(main - .Lmy_pc)
|
||||
}
|
||||
{
|
||||
shl16insli r3, r3, hw0(__libc_csu_init - .Lmy_pc)
|
||||
moveli r4, hw2_last(__libc_csu_fini - .Lmy_pc)
|
||||
}
|
||||
{
|
||||
ADD_PTR r0, r0, r13
|
||||
shl16insli r4, r4, hw1(__libc_csu_fini - .Lmy_pc)
|
||||
}
|
||||
{
|
||||
ADD_PTR r3, r3, r13
|
||||
shl16insli r4, r4, hw0(__libc_csu_fini - .Lmy_pc)
|
||||
}
|
||||
{
|
||||
ADD_PTR r4, r4, r13
|
||||
#else
|
||||
addli r0, r13, lo16(main - .Lmy_pc)
|
||||
}
|
||||
{
|
||||
auli r0, r0, ha16(main - .Lmy_pc)
|
||||
addli r3, r13, lo16(__libc_csu_init - .Lmy_pc)
|
||||
}
|
||||
{
|
||||
auli r3, r3, ha16(__libc_csu_init - .Lmy_pc)
|
||||
addli r4, r13, lo16(__libc_csu_fini - .Lmy_pc)
|
||||
}
|
||||
{
|
||||
auli r4, r4, ha16(__libc_csu_fini - .Lmy_pc)
|
||||
|
||||
#endif
|
||||
|
||||
/* Call the user's main function, and exit with its value.
|
||||
But let the libc call main. */
|
||||
j plt(__libc_start_main)
|
||||
}
|
||||
{
|
||||
/* Tell backtracer to give up (_start has no caller). */
|
||||
info INFO_OP_CANNOT_BACKTRACE
|
||||
}
|
||||
.size _start, .-_start
|
||||
|
||||
/* Define a symbol for the first piece of initialized data. */
|
||||
.data
|
||||
.global __data_start
|
||||
.align 8
|
||||
__data_start:
|
||||
.long 0
|
||||
.weak data_start
|
||||
data_start = __data_start
|
28
sysdeps/tile/fegetenv.c
Normal file
28
sysdeps/tile/fegetenv.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <fenv.h>
|
||||
|
||||
int
|
||||
__fegetenv (fenv_t *envp)
|
||||
{
|
||||
/* As a no-op, this always succeeds. */
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_ver (__fegetenv, fegetenv)
|
26
sysdeps/tile/fegetround.c
Normal file
26
sysdeps/tile/fegetround.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <fenv.h>
|
||||
|
||||
int
|
||||
fegetround (void)
|
||||
{
|
||||
return FE_TONEAREST;
|
||||
}
|
28
sysdeps/tile/feholdexcpt.c
Normal file
28
sysdeps/tile/feholdexcpt.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <fenv.h>
|
||||
|
||||
/* Tile has no exception flags, so this routine can be a no-op. */
|
||||
int
|
||||
feholdexcept (fenv_t *envp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_def (feholdexcept)
|
32
sysdeps/tile/fesetenv.c
Normal file
32
sysdeps/tile/fesetenv.c
Normal file
@ -0,0 +1,32 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <fenv.h>
|
||||
#include <shlib-compat.h>
|
||||
|
||||
/* The only way to get an initialized fenv_t on Tile is with feholdexcept()
|
||||
or via FE_DFL_ENV, either of which restores the environment to its
|
||||
normal state, i.e. FE_DFL_ENV. */
|
||||
int
|
||||
__fesetenv (const fenv_t *envp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_ver (__fesetenv, fesetenv)
|
||||
versioned_symbol (libm, __fesetenv, fesetenv, GLIBC_2_2);
|
27
sysdeps/tile/fesetround.c
Normal file
27
sysdeps/tile/fesetround.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <fenv.h>
|
||||
|
||||
int
|
||||
fesetround (int round)
|
||||
{
|
||||
return (round == FE_TONEAREST) ? 0 : 1;
|
||||
}
|
||||
libm_hidden_def (fesetround)
|
28
sysdeps/tile/feupdateenv.c
Normal file
28
sysdeps/tile/feupdateenv.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <fenv.h>
|
||||
|
||||
/* Tile has no exception flags, so this routine can be a no-op. */
|
||||
int
|
||||
feupdateenv (const fenv_t *envp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_def (feupdateenv)
|
45
sysdeps/tile/ffs.c
Normal file
45
sysdeps/tile/ffs.c
Normal file
@ -0,0 +1,45 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <limits.h>
|
||||
#define ffsl __something_else
|
||||
#include <string.h>
|
||||
|
||||
#undef ffs
|
||||
int
|
||||
__ffs (int x)
|
||||
{
|
||||
return __builtin_ffs (x);
|
||||
}
|
||||
weak_alias (__ffs, ffs)
|
||||
libc_hidden_builtin_def (ffs)
|
||||
|
||||
#undef ffsll
|
||||
int
|
||||
ffsll (long long x)
|
||||
{
|
||||
return __builtin_ffsll (x);
|
||||
}
|
||||
|
||||
#undef ffsl
|
||||
#if ULONG_MAX == UINT_MAX
|
||||
weak_alias (__ffs, ffsl)
|
||||
#else
|
||||
weak_alias (ffsll, ffsl)
|
||||
#endif
|
1
sysdeps/tile/ffsll.c
Normal file
1
sysdeps/tile/ffsll.c
Normal file
@ -0,0 +1 @@
|
||||
/* This function is defined in ffs.c. */
|
22
sysdeps/tile/gccframe.h
Normal file
22
sysdeps/tile/gccframe.h
Normal file
@ -0,0 +1,22 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 FIRST_PSEUDO_REGISTER 64
|
||||
|
||||
#include <sysdeps/generic/gccframe.h>
|
63
sysdeps/tile/jmpbuf-offsets.h
Normal file
63
sysdeps/tile/jmpbuf-offsets.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
/* We don't use most of these symbols; they are here for documentation. */
|
||||
#define JB_R30 0
|
||||
#define JB_R31 1
|
||||
#define JB_R32 2
|
||||
#define JB_R33 3
|
||||
#define JB_R34 4
|
||||
#define JB_R35 5
|
||||
#define JB_R36 6
|
||||
#define JB_R37 7
|
||||
#define JB_R38 8
|
||||
#define JB_R39 9
|
||||
#define JB_R40 10
|
||||
#define JB_R41 11
|
||||
#define JB_R42 12
|
||||
#define JB_R43 13
|
||||
#define JB_R44 14
|
||||
#define JB_R45 15
|
||||
#define JB_R46 16
|
||||
#define JB_R47 17
|
||||
#define JB_R48 18
|
||||
#define JB_R49 19
|
||||
#define JB_R50 20
|
||||
#define JB_R51 21
|
||||
#define JB_FP 22 /* r52 */
|
||||
#define JB_TP 23 /* r53 */
|
||||
#define JB_SP 24 /* r54 */
|
||||
#define JB_PC 25 /* normally LR, r55 */
|
||||
#define JB_ICS 26 /* interrupt critical section bit */
|
||||
|
||||
/* We save space for some extra state to accomodate future changes. */
|
||||
#define JB_LEN 32 /* number of words */
|
||||
|
||||
#define JB_SIZE (JB_LEN * REGSIZE)
|
||||
|
||||
/* Helper macro used by all the setjmp/longjmp assembly code. */
|
||||
#define FOR_EACH_CALLEE_SAVED_REG(f) \
|
||||
.no_require_canonical_reg_names; f(r30); f(r31); \
|
||||
f(r32); f(r33); f(r34); f(r35); f(r36); f(r37); f(r38); f(r39); \
|
||||
f(r40); f(r41); f(r42); f(r43); f(r44); f(r45); f(r46); f(r47); \
|
||||
f(r48); f(r49); f(r50); f(r51); f(r52); f(r53); f(r54); f(r55)
|
||||
|
||||
/* Helper for generic ____longjmp_chk(). */
|
||||
#define JB_FRAME_ADDRESS(buf) \
|
||||
((void *) (unsigned long) (buf[JB_SP]))
|
49
sysdeps/tile/jmpbuf-unwind.h
Normal file
49
sysdeps/tile/jmpbuf-unwind.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
Based on work 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) \
|
||||
((void *) (address) < (void *) 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 longjmp for unwinding. */
|
||||
#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
|
41
sysdeps/tile/ldsodefs.h
Normal file
41
sysdeps/tile/ldsodefs.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _TILE_LDSODEFS_H
|
||||
#define _TILE_LDSODEFS_H 1
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
struct La_tile_regs;
|
||||
struct La_tile_retval;
|
||||
|
||||
#define ARCH_PLTENTER_MEMBERS \
|
||||
ElfW(Addr) (*tile_gnu_pltenter) (ElfW(Sym) *, unsigned int, uintptr_t *, \
|
||||
uintptr_t *, struct La_tile_regs *, \
|
||||
unsigned int *, const char *, \
|
||||
long int *)
|
||||
|
||||
#define ARCH_PLTEXIT_MEMBERS \
|
||||
ElfW(Addr) (*tile_gnu_pltexit) (ElfW(Sym) *, unsigned int, uintptr_t *, \
|
||||
uintptr_t *, struct La_tile_regs *, \
|
||||
struct La_tile_retval *, const char *)
|
||||
|
||||
#include_next <ldsodefs.h>
|
||||
|
||||
#endif
|
26
sysdeps/tile/machine-gmon.h
Normal file
26
sysdeps/tile/machine-gmon.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _MCOUNT_DECL(from, self) \
|
||||
void __mcount_internal (u_long from, u_long self)
|
||||
|
||||
/* Call __mcount_internal with our the return PC for our caller, and
|
||||
the return PC our caller will return to. Empty since we use an
|
||||
assembly stub instead. */
|
||||
#define MCOUNT
|
21
sysdeps/tile/nptl/Makefile
Normal file
21
sysdeps/tile/nptl/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright (C) 2002, 2003 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.
|
||||
|
||||
ifeq ($(subdir),csu)
|
||||
gen-as-const-headers += tcb-offsets.sym
|
||||
endif
|
57
sysdeps/tile/nptl/pthread_spin_lock.c
Normal file
57
sysdeps/tile/nptl/pthread_spin_lock.c
Normal file
@ -0,0 +1,57 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 "pthreadP.h"
|
||||
#include <arch/spr_def.h>
|
||||
#include <atomic.h>
|
||||
|
||||
/* Bound point for bounded exponential backoff */
|
||||
#define BACKOFF_MAX 2048
|
||||
|
||||
/* Initial cycle delay for exponential backoff */
|
||||
#define BACKOFF_START 32
|
||||
|
||||
#ifdef __tilegx__
|
||||
/* Use cmpexch() after the initial fast-path exch to avoid
|
||||
invalidating the cache line of the lock holder. */
|
||||
# define TNS(p) atomic_exchange_acq((p), 1)
|
||||
# define CMPTNS(p) atomic_compare_and_exchange_val_acq((p), 1, 0)
|
||||
#else
|
||||
# define TNS(p) __insn_tns(p)
|
||||
# define CMPTNS(p) __insn_tns(p)
|
||||
# define SPR_CYCLE SPR_CYCLE_LOW /* The low 32 bits are sufficient. */
|
||||
#endif
|
||||
|
||||
int
|
||||
pthread_spin_lock (pthread_spinlock_t *lock)
|
||||
{
|
||||
if (__builtin_expect (TNS (lock) != 0, 0))
|
||||
{
|
||||
unsigned int backoff = BACKOFF_START;
|
||||
while (CMPTNS (lock) != 0)
|
||||
{
|
||||
unsigned int start = __insn_mfspr (SPR_CYCLE);
|
||||
while (__insn_mfspr (SPR_CYCLE) - start < backoff)
|
||||
;
|
||||
if (backoff < BACKOFF_MAX)
|
||||
backoff *= 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
33
sysdeps/tile/nptl/pthread_spin_trylock.c
Normal file
33
sysdeps/tile/nptl/pthread_spin_trylock.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 "pthreadP.h"
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __tilegx__
|
||||
#define TNS(p) __insn_exch4((p), 1)
|
||||
#else
|
||||
#define TNS(p) __insn_tns(p)
|
||||
#endif
|
||||
|
||||
int
|
||||
pthread_spin_trylock (pthread_spinlock_t *lock)
|
||||
{
|
||||
return (TNS (lock) == 0) ? 0 : EBUSY;
|
||||
}
|
42
sysdeps/tile/nptl/pthreaddef.h
Normal file
42
sysdeps/tile/nptl/pthreaddef.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Default stack size. */
|
||||
#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024)
|
||||
|
||||
/* Required stack pointer alignment at beginning. */
|
||||
#define STACK_ALIGN 16
|
||||
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
/* Alignment requirement for TCB. */
|
||||
#define TCB_ALIGNMENT 16
|
||||
|
||||
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
|
||||
/* XXX Until we have a better place keep the definitions here. */
|
||||
|
||||
#define __exit_thread_inline(val) \
|
||||
INLINE_SYSCALL (exit, 1, (val))
|
17
sysdeps/tile/nptl/tcb-offsets.sym
Normal file
17
sysdeps/tile/nptl/tcb-offsets.sym
Normal file
@ -0,0 +1,17 @@
|
||||
#define SHARED /* needed to get struct rtld_global from <ldsodefs.h> */
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
--
|
||||
|
||||
-- Abuse tls.h macros to derive offsets relative to the thread register.
|
||||
#define thread_offsetof(mem) (long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
|
||||
|
||||
MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads)
|
||||
PID_OFFSET thread_offsetof (pid)
|
||||
TID_OFFSET thread_offsetof (tid)
|
||||
POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
|
||||
FEEDBACK_DATA_OFFSET (offsetof (tcbhead_t, feedback_data) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
|
||||
DTV_OFFSET (offsetof (tcbhead_t, dtv) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
|
||||
TLS_GENERATION_OFFSET offsetof (struct rtld_global, _dl_tls_generation)
|
195
sysdeps/tile/nptl/tls.h
Normal file
195
sysdeps/tile/nptl/tls.h
Normal file
@ -0,0 +1,195 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _TLS_H
|
||||
#define _TLS_H 1
|
||||
|
||||
# include <dl-sysdep.h>
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <stdbool.h>
|
||||
# include <stddef.h>
|
||||
# include <stdint.h>
|
||||
|
||||
/* Type for the dtv. */
|
||||
typedef union dtv
|
||||
{
|
||||
size_t counter;
|
||||
struct
|
||||
{
|
||||
void *val;
|
||||
bool is_static;
|
||||
} pointer;
|
||||
} dtv_t;
|
||||
|
||||
#else /* __ASSEMBLER__ */
|
||||
# include <tcb-offsets.h>
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Get system call information. */
|
||||
# include <sysdep.h>
|
||||
|
||||
/* The TP points to the start of the thread blocks. */
|
||||
# define TLS_DTV_AT_TP 1
|
||||
|
||||
/* We use the multiple_threads field in the pthread struct */
|
||||
#define TLS_MULTIPLE_THREADS_IN_TCB 1
|
||||
|
||||
/* Get the thread descriptor definition. */
|
||||
# include <nptl/descr.h>
|
||||
|
||||
/* The stack_guard is accessed directly by GCC -fstack-protector code,
|
||||
so it is a part of public ABI. The dtv and pointer_guard fields
|
||||
are private. */
|
||||
typedef struct
|
||||
{
|
||||
void *feedback_data;
|
||||
uintptr_t pointer_guard;
|
||||
uintptr_t stack_guard;
|
||||
dtv_t *dtv;
|
||||
} tcbhead_t;
|
||||
|
||||
/* This is the size of the initial TCB. Because our TCB is before the thread
|
||||
pointer, we don't need this. */
|
||||
# define TLS_INIT_TCB_SIZE 0
|
||||
|
||||
/* Alignment requirements for the initial TCB. */
|
||||
# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
|
||||
/* This is the size of the TCB. Because our TCB is before the thread
|
||||
pointer, we don't need this. */
|
||||
# define TLS_TCB_SIZE 0
|
||||
|
||||
/* Alignment requirements for the TCB. */
|
||||
# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
|
||||
/* This is the size we need before TCB - actually, it includes the TCB. */
|
||||
# define TLS_PRE_TCB_SIZE \
|
||||
(sizeof (struct pthread) \
|
||||
+ ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
|
||||
|
||||
/* Return the thread descriptor (tp) for the current thread. */
|
||||
register void *__thread_pointer asm ("tp");
|
||||
|
||||
/* The thread pointer (in hardware register tp) points to the end of
|
||||
the TCB. The pthread_descr structure is immediately in front of the TCB. */
|
||||
# define TLS_TCB_OFFSET 0
|
||||
|
||||
/* Install the dtv pointer. The pointer passed is to the element with
|
||||
index -1 which contain the length. */
|
||||
# define INSTALL_DTV(tcbp, dtvp) \
|
||||
(((tcbhead_t *) (tcbp))[-1].dtv = (dtvp) + 1)
|
||||
|
||||
/* Install new dtv for current thread. */
|
||||
# define INSTALL_NEW_DTV(dtv) (THREAD_DTV() = (dtv))
|
||||
|
||||
/* Return dtv of given thread descriptor. */
|
||||
# define GET_DTV(tcbp) (((tcbhead_t *) (tcbp))[-1].dtv)
|
||||
|
||||
/* Code to initially initialize the thread pointer (tp). */
|
||||
# define TLS_INIT_TP(tcbp, secondcall) \
|
||||
(__thread_pointer = (char *)(tcbp) + TLS_TCB_OFFSET, NULL)
|
||||
|
||||
/* Return the address of the dtv for the current thread. */
|
||||
# define THREAD_DTV() \
|
||||
(((tcbhead_t *) (__thread_pointer - TLS_TCB_OFFSET))[-1].dtv)
|
||||
|
||||
/* Return the thread descriptor for the current thread. */
|
||||
# define THREAD_SELF \
|
||||
((struct pthread *) (__thread_pointer \
|
||||
- TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
|
||||
|
||||
/* Magic for libthread_db to know how to do THREAD_SELF. */
|
||||
#ifdef __tilegx__
|
||||
# define DB_THREAD_SELF \
|
||||
REGISTER (64, 64, REG_TP * 8, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
|
||||
#else
|
||||
# define DB_THREAD_SELF \
|
||||
REGISTER (32, 32, REG_TP * 4, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
|
||||
#endif
|
||||
|
||||
/* Read member of the thread descriptor directly. */
|
||||
# define THREAD_GETMEM(descr, member) (descr->member)
|
||||
|
||||
/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
|
||||
# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
(descr->member[idx])
|
||||
|
||||
/* Set member of the thread descriptor directly. */
|
||||
# define THREAD_SETMEM(descr, member, value) \
|
||||
(descr->member = (value))
|
||||
|
||||
/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
|
||||
# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
(descr->member[idx] = (value))
|
||||
|
||||
/* Set the stack guard field in TCB head. */
|
||||
# define THREAD_SET_STACK_GUARD(value) \
|
||||
(((tcbhead_t *) ((char *) __thread_pointer \
|
||||
- TLS_TCB_OFFSET))[-1].stack_guard = (value))
|
||||
# define THREAD_COPY_STACK_GUARD(descr) \
|
||||
(((tcbhead_t *) ((char *) (descr) \
|
||||
+ TLS_PRE_TCB_SIZE))[-1].stack_guard \
|
||||
= ((tcbhead_t *) ((char *) __thread_pointer \
|
||||
- TLS_TCB_OFFSET))[-1].stack_guard)
|
||||
|
||||
/* Set the pointer guard field in TCB head. */
|
||||
# define THREAD_GET_POINTER_GUARD() \
|
||||
(((tcbhead_t *) ((char *) __thread_pointer \
|
||||
- TLS_TCB_OFFSET))[-1].pointer_guard)
|
||||
# define THREAD_SET_POINTER_GUARD(value) \
|
||||
(THREAD_GET_POINTER_GUARD () = (value))
|
||||
# define THREAD_COPY_POINTER_GUARD(descr) \
|
||||
(((tcbhead_t *) ((char *) (descr) \
|
||||
+ TLS_PRE_TCB_SIZE))[-1].pointer_guard \
|
||||
= THREAD_GET_POINTER_GUARD())
|
||||
|
||||
/* l_tls_offset == 0 is perfectly valid on Tile, so we have to use some
|
||||
different value to mean unset l_tls_offset. */
|
||||
# define NO_TLS_OFFSET -1
|
||||
|
||||
/* Get and set the global scope generation counter in struct pthread. */
|
||||
#define THREAD_GSCOPE_FLAG_UNUSED 0
|
||||
#define THREAD_GSCOPE_FLAG_USED 1
|
||||
#define THREAD_GSCOPE_FLAG_WAIT 2
|
||||
#define THREAD_GSCOPE_RESET_FLAG() \
|
||||
do \
|
||||
{ int __res \
|
||||
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
|
||||
THREAD_GSCOPE_FLAG_UNUSED); \
|
||||
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
|
||||
lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
|
||||
} \
|
||||
while (0)
|
||||
#define THREAD_GSCOPE_SET_FLAG() \
|
||||
do \
|
||||
{ \
|
||||
THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \
|
||||
atomic_write_barrier (); \
|
||||
} \
|
||||
while (0)
|
||||
#define THREAD_GSCOPE_WAIT() \
|
||||
GL(dl_wait_lookup_done) ()
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* tls.h */
|
17
sysdeps/tile/preconfigure
Normal file
17
sysdeps/tile/preconfigure
Normal file
@ -0,0 +1,17 @@
|
||||
# This is a -*- sh -*-
|
||||
case "$machine" in
|
||||
tilepro)
|
||||
base_machine=tile machine=tile/tilepro ;;
|
||||
tilegx)
|
||||
base_machine=tile
|
||||
if $CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | grep -q __LP64__; then
|
||||
machine=tile/tilegx/tilegx64
|
||||
else
|
||||
machine=tile/tilegx/tilegx32
|
||||
fi ;;
|
||||
esac
|
||||
case "$machine" in
|
||||
tile*)
|
||||
libc_commonpagesize=0x10000
|
||||
libc_relro_required=yes ;;
|
||||
esac
|
3
sysdeps/tile/s_fma.c
Normal file
3
sysdeps/tile/s_fma.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Although tile uses ieee754/dbl-64, it does not support the
|
||||
rounding modes required to use the standard dbl-64 s_fma.c. */
|
||||
#include <math/s_fma.c>
|
3
sysdeps/tile/s_fmaf.c
Normal file
3
sysdeps/tile/s_fmaf.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Although tile uses ieee754/dbl-64, it does not support the
|
||||
rounding modes required to use the standard dbl-64 s_fmaf.c. */
|
||||
#include <math/s_fmaf.c>
|
47
sysdeps/tile/setjmp.S
Normal file
47
sysdeps/tile/setjmp.S
Normal file
@ -0,0 +1,47 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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>
|
||||
#include <jmpbuf-offsets.h>
|
||||
|
||||
.text
|
||||
|
||||
/* Keep traditional entry points in with sigsetjmp(). */
|
||||
ENTRY(setjmp)
|
||||
{ movei r1, 1; j 1f }
|
||||
END(setjmp)
|
||||
|
||||
ENTRY(_setjmp)
|
||||
{ movei r1, 0; j 1f }
|
||||
END(_setjmp)
|
||||
libc_hidden_def (_setjmp)
|
||||
|
||||
ENTRY(__sigsetjmp)
|
||||
FEEDBACK_ENTER(__sigsetjmp)
|
||||
1:
|
||||
move r2, r0
|
||||
|
||||
#define SAVE(r) { ST r2, r ; ADDI_PTR r2, r2, REGSIZE }
|
||||
FOR_EACH_CALLEE_SAVED_REG(SAVE)
|
||||
|
||||
mfspr r3, INTERRUPT_CRITICAL_SECTION
|
||||
ST r2, r3
|
||||
j plt(__sigjmp_save)
|
||||
jrp lr /* Keep the backtracer happy. */
|
||||
END(__sigsetjmp)
|
2
sysdeps/tile/shlib-versions
Normal file
2
sysdeps/tile/shlib-versions
Normal file
@ -0,0 +1,2 @@
|
||||
# glibc 2.12 was released to customers; 2.15 was the first community version.
|
||||
tile.*-.*-linux-gnu DEFAULT GLIBC_2.12 GLIBC_2.15
|
49
sysdeps/tile/stackinfo.h
Normal file
49
sysdeps/tile/stackinfo.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 file contains a bit of information about the stack allocation
|
||||
of the processor. */
|
||||
|
||||
#ifndef _STACKINFO_H
|
||||
#define _STACKINFO_H 1
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
/* On tile the stack grows down. */
|
||||
#define _STACK_GROWS_DOWN 1
|
||||
|
||||
/* Default to a non-executable stack. */
|
||||
#define DEFAULT_STACK_PERMS (PF_R|PF_W)
|
||||
|
||||
/* Access to the stack pointer. The macros are used in alloca_account
|
||||
for which they need to act as barriers as well, hence the additional
|
||||
(unnecessary) parameters. */
|
||||
#define stackinfo_get_sp() \
|
||||
({ void *p__; asm volatile ("move %0, sp" : "=r" (p__)); p__; })
|
||||
#if defined __tilegx__ && __WORDSIZE == 32
|
||||
#define __stackinfo_sub "subx"
|
||||
#else
|
||||
#define __stackinfo_sub "sub"
|
||||
#endif
|
||||
#define stackinfo_sub_sp(ptr) \
|
||||
({ ptrdiff_t d__; \
|
||||
asm volatile (__stackinfo_sub " %0, %0, sp" : "=r" (d__) : "0" (ptr)); \
|
||||
d__; })
|
||||
|
||||
#endif /* stackinfo.h */
|
120
sysdeps/tile/sysdep.h
Normal file
120
sysdeps/tile/sysdep.h
Normal file
@ -0,0 +1,120 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <sysdeps/generic/sysdep.h>
|
||||
#include <bits/wordsize.h>
|
||||
#include <arch/abi.h>
|
||||
|
||||
#ifndef HAVE_ELF
|
||||
# error "ELF is assumed."
|
||||
#endif
|
||||
|
||||
#ifndef NO_UNDERSCORES
|
||||
# error "User-label prefix (underscore) assumed absent."
|
||||
#endif
|
||||
|
||||
#if defined __ASSEMBLER__ || defined REQUEST_ASSEMBLER_MACROS
|
||||
|
||||
#include <feedback-asm.h>
|
||||
|
||||
/* Make use of .type and .size directives. */
|
||||
#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
|
||||
#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
|
||||
|
||||
/* Define an entry point visible from C. */
|
||||
#define ENTRY(name) \
|
||||
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
|
||||
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
|
||||
.align 8; \
|
||||
C_LABEL(name) \
|
||||
cfi_startproc; \
|
||||
CALL_MCOUNT
|
||||
|
||||
#undef END
|
||||
#define END(name) \
|
||||
cfi_endproc; \
|
||||
ASM_SIZE_DIRECTIVE(name)
|
||||
|
||||
/* Since C identifiers are not normally prefixed with an underscore
|
||||
on this system, the asm identifier `syscall_error' intrudes on the
|
||||
C name space. Make sure we use an innocuous name. */
|
||||
#define syscall_error __syscall_error
|
||||
#define mcount __mcount
|
||||
|
||||
/* If compiled for profiling, call `mcount' at the start of each function.
|
||||
The mcount code requires the caller PC in r10. The `mcount' function
|
||||
sets lr back to the value r10 had on entry when it returns. */
|
||||
#ifdef PROF
|
||||
#define CALL_MCOUNT { move r10, lr; jal mcount }
|
||||
#else
|
||||
#define CALL_MCOUNT /* Do nothing. */
|
||||
#endif
|
||||
|
||||
/* Local label name for asm code. */
|
||||
#define L(name) .L##name
|
||||
|
||||
/* Specify the size in bytes of a machine register. */
|
||||
#ifdef __tilegx__
|
||||
#define REGSIZE 8
|
||||
#else
|
||||
#define REGSIZE 4
|
||||
#endif
|
||||
|
||||
/* Support a limited form of shared assembly between tile and tilegx.
|
||||
The presumption is that LD/ST are used for manipulating registers.
|
||||
Since opcode parsing is case-insensitive, we don't need to provide
|
||||
definitions for these on tilegx. */
|
||||
#ifndef __tilegx__
|
||||
#define LD lw
|
||||
#define LD4U lw
|
||||
#define ST sw
|
||||
#define ST4 sw
|
||||
#define BNEZ bnz
|
||||
#define BEQZ bz
|
||||
#define BEQZT bzt
|
||||
#define BGTZ bgz
|
||||
#define CMPEQI seqi
|
||||
#define CMPEQ seq
|
||||
#define CMOVEQZ mvz
|
||||
#define CMOVNEZ mvnz
|
||||
#endif
|
||||
|
||||
/* Provide "pointer-oriented" instruction variants. These differ not
|
||||
just for tile vs tilegx, but also for tilegx -m64 vs -m32. */
|
||||
#if defined __tilegx__ && __WORDSIZE == 32
|
||||
#define ADD_PTR addx
|
||||
#define ADDI_PTR addxi
|
||||
#define ADDLI_PTR addxli
|
||||
#define LD_PTR ld4s
|
||||
#define ST_PTR st4
|
||||
#define SHL_PTR_ADD shl2add
|
||||
#else
|
||||
#define ADD_PTR add
|
||||
#define ADDI_PTR addi
|
||||
#define ADDLI_PTR addli
|
||||
#define LD_PTR LD
|
||||
#define ST_PTR ST
|
||||
#ifdef __tilegx__
|
||||
#define SHL_PTR_ADD shl3add
|
||||
#else
|
||||
#define SHL_PTR_ADD s2a
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
50
sysdeps/tile/tilegx/bits/atomic.h
Normal file
50
sysdeps/tile/tilegx/bits/atomic.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _BITS_ATOMIC_H
|
||||
#define _BITS_ATOMIC_H 1
|
||||
|
||||
#include <arch/spr_def.h>
|
||||
|
||||
/* Pick appropriate 8- or 4-byte instruction. */
|
||||
#define __atomic_update(mem, v, op) \
|
||||
((__typeof (*(mem))) (__typeof (*(mem) - *(mem))) \
|
||||
((sizeof (*(mem)) == 8) ? \
|
||||
__insn_##op ((void *) (mem), (int64_t) (__typeof((v) - (v))) (v)) : \
|
||||
(sizeof (*(mem)) == 4) ? \
|
||||
__insn_##op##4 ((void *) (mem), (int32_t) (__typeof ((v) - (v))) (v)) : \
|
||||
__atomic_error_bad_argument_size()))
|
||||
|
||||
#define atomic_compare_and_exchange_val_acq(mem, n, o) \
|
||||
({ __insn_mtspr (SPR_CMPEXCH_VALUE, (int64_t) (__typeof ((o) - (o))) (o)); \
|
||||
__atomic_update (mem, n, cmpexch); })
|
||||
#define atomic_exchange_acq(mem, newvalue) \
|
||||
__atomic_update (mem, newvalue, exch)
|
||||
#define atomic_exchange_and_add(mem, value) \
|
||||
__atomic_update (mem, value, fetchadd)
|
||||
#define atomic_and_val(mem, mask) \
|
||||
__atomic_update (mem, mask, fetchand)
|
||||
#define atomic_or_val(mem, mask) \
|
||||
__atomic_update (mem, mask, fetchor)
|
||||
#define atomic_decrement_if_positive(mem) \
|
||||
__atomic_update (mem, -1, fetchaddgez)
|
||||
|
||||
#include <sysdeps/tile/bits/atomic.h>
|
||||
|
||||
#endif /* bits/atomic.h */
|
8
sysdeps/tile/tilegx/bits/wordsize.h
Normal file
8
sysdeps/tile/tilegx/bits/wordsize.h
Normal file
@ -0,0 +1,8 @@
|
||||
/* Determine the wordsize from the preprocessor defines. */
|
||||
|
||||
#ifdef __LP64__
|
||||
# define __WORDSIZE 64
|
||||
# define __WORDSIZE_COMPAT32 1
|
||||
#else
|
||||
# define __WORDSIZE 32
|
||||
#endif
|
74
sysdeps/tile/tilegx/memchr.c
Normal file
74
sysdeps/tile/tilegx/memchr.c
Normal file
@ -0,0 +1,74 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include "string-endian.h"
|
||||
|
||||
void *
|
||||
__memchr (const void *s, int c, size_t n)
|
||||
{
|
||||
const uint64_t *last_word_ptr;
|
||||
const uint64_t *p;
|
||||
const char *last_byte_ptr;
|
||||
uintptr_t s_int;
|
||||
uint64_t goal, before_mask, v, bits;
|
||||
char *ret;
|
||||
|
||||
if (__builtin_expect (n == 0, 0))
|
||||
{
|
||||
/* Don't dereference any memory if the array is empty. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get an aligned pointer. */
|
||||
s_int = (uintptr_t) s;
|
||||
p = (const uint64_t *) (s_int & -8);
|
||||
|
||||
/* Create eight copies of the byte for which we are looking. */
|
||||
goal = 0x0101010101010101ULL * (uint8_t) c;
|
||||
|
||||
/* Read the first word, but munge it so that bytes before the array
|
||||
will not match goal. */
|
||||
before_mask = MASK (s_int);
|
||||
v = (*p | before_mask) ^ (goal & before_mask);
|
||||
|
||||
/* Compute the address of the last byte. */
|
||||
last_byte_ptr = (const char *) s + n - 1;
|
||||
|
||||
/* Compute the address of the word containing the last byte. */
|
||||
last_word_ptr = (const uint64_t *) ((uintptr_t) last_byte_ptr & -8);
|
||||
|
||||
while ((bits = __insn_v1cmpeq (v, goal)) == 0)
|
||||
{
|
||||
if (__builtin_expect (p == last_word_ptr, 0))
|
||||
{
|
||||
/* We already read the last word in the array, so give up. */
|
||||
return NULL;
|
||||
}
|
||||
v = *++p;
|
||||
}
|
||||
|
||||
/* We found a match, but it might be in a byte past the end
|
||||
of the array. */
|
||||
ret = ((char *) p) + (CFZ (bits) >> 3);
|
||||
return (ret <= last_byte_ptr) ? ret : NULL;
|
||||
}
|
||||
weak_alias (__memchr, memchr)
|
||||
libc_hidden_builtin_def (memchr)
|
196
sysdeps/tile/tilegx/memcpy.c
Normal file
196
sysdeps/tile/tilegx/memcpy.c
Normal file
@ -0,0 +1,196 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <arch/chip.h>
|
||||
|
||||
/* Must be 8 bytes in size. */
|
||||
#define word_t uint64_t
|
||||
|
||||
/* How many cache lines ahead should we prefetch? */
|
||||
#define PREFETCH_LINES_AHEAD 3
|
||||
|
||||
void *
|
||||
__memcpy (void *__restrict dstv, const void *__restrict srcv, size_t n)
|
||||
{
|
||||
char *__restrict dst1 = (char *) dstv;
|
||||
const char *__restrict src1 = (const char *) srcv;
|
||||
const char *__restrict src1_end;
|
||||
const char *__restrict prefetch;
|
||||
word_t *__restrict dst8; /* 8-byte pointer to destination memory. */
|
||||
word_t final; /* Final bytes to write to trailing word, if any */
|
||||
long i;
|
||||
|
||||
if (n < 16)
|
||||
{
|
||||
for (; n; n--)
|
||||
*dst1++ = *src1++;
|
||||
return dstv;
|
||||
}
|
||||
|
||||
/* Locate the end of source memory we will copy. Don't prefetch
|
||||
past this. */
|
||||
src1_end = src1 + n - 1;
|
||||
|
||||
/* Prefetch ahead a few cache lines, but not past the end. */
|
||||
prefetch = src1;
|
||||
for (i = 0; i < PREFETCH_LINES_AHEAD; i++)
|
||||
{
|
||||
__insn_prefetch (prefetch);
|
||||
prefetch += CHIP_L2_LINE_SIZE ();
|
||||
prefetch = (prefetch > src1_end) ? prefetch : src1;
|
||||
}
|
||||
|
||||
/* Copy bytes until dst is word-aligned. */
|
||||
for (; (uintptr_t) dst1 & (sizeof (word_t) - 1); n--)
|
||||
*dst1++ = *src1++;
|
||||
|
||||
/* 8-byte pointer to destination memory. */
|
||||
dst8 = (word_t *) dst1;
|
||||
|
||||
if (__builtin_expect ((uintptr_t) src1 & (sizeof (word_t) - 1), 0))
|
||||
{
|
||||
/* Misaligned copy. Copy 8 bytes at a time, but don't bother
|
||||
with other fanciness.
|
||||
TODO: Consider prefetching and using wh64 as well. */
|
||||
|
||||
/* Create an aligned src8. */
|
||||
const word_t *__restrict src8 =
|
||||
(const word_t *) ((uintptr_t) src1 & -sizeof (word_t));
|
||||
word_t b;
|
||||
|
||||
word_t a = *src8++;
|
||||
for (; n >= sizeof (word_t); n -= sizeof (word_t))
|
||||
{
|
||||
b = *src8++;
|
||||
a = __insn_dblalign (a, b, src1);
|
||||
*dst8++ = a;
|
||||
a = b;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
return dstv;
|
||||
|
||||
b = ((const char *) src8 <= src1_end) ? *src8 : 0;
|
||||
|
||||
/* Final source bytes to write to trailing partial word, if any. */
|
||||
final = __insn_dblalign (a, b, src1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Aligned copy. */
|
||||
|
||||
const word_t *__restrict src8 = (const word_t *) src1;
|
||||
|
||||
/* src8 and dst8 are both word-aligned. */
|
||||
if (n >= CHIP_L2_LINE_SIZE ())
|
||||
{
|
||||
/* Copy until 'dst' is cache-line-aligned. */
|
||||
for (; (uintptr_t) dst8 & (CHIP_L2_LINE_SIZE () - 1);
|
||||
n -= sizeof (word_t))
|
||||
*dst8++ = *src8++;
|
||||
|
||||
for (; n >= CHIP_L2_LINE_SIZE ();)
|
||||
{
|
||||
__insn_wh64 (dst8);
|
||||
|
||||
/* Prefetch and advance to next line to prefetch, but
|
||||
don't go past the end. */
|
||||
__insn_prefetch (prefetch);
|
||||
prefetch += CHIP_L2_LINE_SIZE ();
|
||||
prefetch = (prefetch > src1_end) ? prefetch :
|
||||
(const char *) src8;
|
||||
|
||||
/* Copy an entire cache line. Manually unrolled to
|
||||
avoid idiosyncracies of compiler unrolling. */
|
||||
#define COPY_WORD(offset) ({ dst8[offset] = src8[offset]; n -= 8; })
|
||||
COPY_WORD (0);
|
||||
COPY_WORD (1);
|
||||
COPY_WORD (2);
|
||||
COPY_WORD (3);
|
||||
COPY_WORD (4);
|
||||
COPY_WORD (5);
|
||||
COPY_WORD (6);
|
||||
COPY_WORD (7);
|
||||
#if CHIP_L2_LINE_SIZE() != 64
|
||||
# error "Fix code that assumes particular L2 cache line size."
|
||||
#endif
|
||||
|
||||
dst8 += CHIP_L2_LINE_SIZE () / sizeof (word_t);
|
||||
src8 += CHIP_L2_LINE_SIZE () / sizeof (word_t);
|
||||
}
|
||||
}
|
||||
|
||||
for (; n >= sizeof (word_t); n -= sizeof (word_t))
|
||||
*dst8++ = *src8++;
|
||||
|
||||
if (__builtin_expect (n == 0, 1))
|
||||
return dstv;
|
||||
|
||||
final = *src8;
|
||||
}
|
||||
|
||||
/* n != 0 if we get here. Write out any trailing bytes. */
|
||||
dst1 = (char *) dst8;
|
||||
#ifndef __BIG_ENDIAN__
|
||||
if (n & 4)
|
||||
{
|
||||
*(uint32_t *) dst1 = final;
|
||||
dst1 += 4;
|
||||
final >>= 32;
|
||||
n &= 3;
|
||||
}
|
||||
if (n & 2)
|
||||
{
|
||||
*(uint16_t *) dst1 = final;
|
||||
dst1 += 2;
|
||||
final >>= 16;
|
||||
n &= 1;
|
||||
}
|
||||
if (n)
|
||||
*(uint8_t *) dst1 = final;
|
||||
#else
|
||||
if (n & 4)
|
||||
{
|
||||
*(uint32_t *) dst1 = final >> 32;
|
||||
dst1 += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
final >>= 32;
|
||||
}
|
||||
if (n & 2)
|
||||
{
|
||||
*(uint16_t *) dst1 = final >> 16;
|
||||
dst1 += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
final >>= 16;
|
||||
}
|
||||
if (n & 1)
|
||||
*(uint8_t *) dst1 = final >> 8;
|
||||
#endif
|
||||
|
||||
return dstv;
|
||||
}
|
||||
weak_alias (__memcpy, memcpy)
|
||||
libc_hidden_builtin_def (memcpy)
|
151
sysdeps/tile/tilegx/memset.c
Normal file
151
sysdeps/tile/tilegx/memset.c
Normal file
@ -0,0 +1,151 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <arch/chip.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void *
|
||||
__memset (void *s, int c, size_t n)
|
||||
{
|
||||
uint64_t *out64;
|
||||
int n64, to_align64;
|
||||
uint64_t v64;
|
||||
uint8_t *out8 = s;
|
||||
|
||||
/* Experimentation shows that a trivial tight loop is a win up until
|
||||
around a size of 20, where writing a word at a time starts to win. */
|
||||
#define BYTE_CUTOFF 20
|
||||
|
||||
#if BYTE_CUTOFF < 7
|
||||
/* This must be at least at least this big, or some code later
|
||||
on doesn't work. */
|
||||
# error "BYTE_CUTOFF is too small."
|
||||
#endif
|
||||
|
||||
if (n < BYTE_CUTOFF)
|
||||
{
|
||||
/* Strangely, this turns out to be the tightest way to write
|
||||
this loop. */
|
||||
if (n != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Strangely, combining these into one line performs worse. */
|
||||
*out8 = c;
|
||||
out8++;
|
||||
}
|
||||
while (--n != 0);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Align 'out8'. We know n >= 7 so this won't write past the end. */
|
||||
while (((uintptr_t) out8 & 7) != 0)
|
||||
{
|
||||
*out8++ = c;
|
||||
--n;
|
||||
}
|
||||
|
||||
/* Align 'n'. */
|
||||
while (n & 7)
|
||||
out8[--n] = c;
|
||||
|
||||
out64 = (uint64_t *) out8;
|
||||
n64 = n >> 3;
|
||||
|
||||
/* Tile input byte out to 64 bits. */
|
||||
v64 = 0x0101010101010101ULL * (uint8_t) c;
|
||||
|
||||
/* This must be at least 8 or the following loop doesn't work. */
|
||||
#define CACHE_LINE_SIZE_IN_DOUBLEWORDS (CHIP_L2_LINE_SIZE() / 8)
|
||||
|
||||
/* Determine how many words we need to emit before the 'out32'
|
||||
pointer becomes aligned modulo the cache line size. */
|
||||
to_align64 = (-((uintptr_t) out64 >> 3)) &
|
||||
(CACHE_LINE_SIZE_IN_DOUBLEWORDS - 1);
|
||||
|
||||
/* Only bother aligning and using wh64 if there is at least
|
||||
one full cache line to process. This check also prevents
|
||||
overrunning the end of the buffer with alignment words. */
|
||||
if (to_align64 <= n64 - CACHE_LINE_SIZE_IN_DOUBLEWORDS)
|
||||
{
|
||||
int lines_left;
|
||||
|
||||
/* Align out64 mod the cache line size so we can use wh64. */
|
||||
n64 -= to_align64;
|
||||
for (; to_align64 != 0; to_align64--)
|
||||
{
|
||||
*out64 = v64;
|
||||
out64++;
|
||||
}
|
||||
|
||||
/* Use unsigned divide to turn this into a right shift. */
|
||||
lines_left = (unsigned) n64 / CACHE_LINE_SIZE_IN_DOUBLEWORDS;
|
||||
|
||||
do
|
||||
{
|
||||
/* Only wh64 a few lines at a time, so we don't exceed the
|
||||
maximum number of victim lines. */
|
||||
int x = ((lines_left < CHIP_MAX_OUTSTANDING_VICTIMS ()) ? lines_left
|
||||
: CHIP_MAX_OUTSTANDING_VICTIMS ());
|
||||
uint64_t *wh = out64;
|
||||
int i = x;
|
||||
int j;
|
||||
|
||||
lines_left -= x;
|
||||
|
||||
do
|
||||
{
|
||||
__insn_wh64 (wh);
|
||||
wh += CACHE_LINE_SIZE_IN_DOUBLEWORDS;
|
||||
}
|
||||
while (--i);
|
||||
|
||||
for (j = x * (CACHE_LINE_SIZE_IN_DOUBLEWORDS / 4); j != 0; j--)
|
||||
{
|
||||
*out64++ = v64;
|
||||
*out64++ = v64;
|
||||
*out64++ = v64;
|
||||
*out64++ = v64;
|
||||
}
|
||||
}
|
||||
while (lines_left != 0);
|
||||
|
||||
/* We processed all full lines above, so only this many
|
||||
words remain to be processed. */
|
||||
n64 &= CACHE_LINE_SIZE_IN_DOUBLEWORDS - 1;
|
||||
}
|
||||
|
||||
/* Now handle any leftover values. */
|
||||
if (n64 != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
*out64 = v64;
|
||||
out64++;
|
||||
}
|
||||
while (--n64 != 0);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
weak_alias (__memset, memset)
|
||||
libc_hidden_builtin_def (memset)
|
31
sysdeps/tile/tilegx/memusage.h
Normal file
31
sysdeps/tile/tilegx/memusage.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <arch/spr_def.h>
|
||||
|
||||
#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; })
|
||||
|
||||
#define GETTIME(low,high) \
|
||||
{ \
|
||||
uint64_t cycles = __insn_mfspr (SPR_CYCLE); \
|
||||
low = cycles & 0xffffffff; \
|
||||
high = cycles >> 32; \
|
||||
}
|
||||
|
||||
#include <sysdeps/generic/memusage.h>
|
46
sysdeps/tile/tilegx/rawmemchr.c
Normal file
46
sysdeps/tile/tilegx/rawmemchr.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include "string-endian.h"
|
||||
|
||||
void *
|
||||
__rawmemchr (const void *s, int c)
|
||||
{
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint64_t *p = (const uint64_t *) (s_int & -8);
|
||||
|
||||
/* Create eight copies of the byte for which we are looking. */
|
||||
const uint64_t goal = 0x0101010101010101ULL * (uint8_t) c;
|
||||
|
||||
/* Read the first word, but munge it so that bytes before the array
|
||||
will not match goal. */
|
||||
const uint64_t before_mask = MASK (s_int);
|
||||
uint64_t v = (*p | before_mask) ^ (goal & before_mask);
|
||||
|
||||
uint64_t bits;
|
||||
while ((bits = __insn_v1cmpeq (v, goal)) == 0)
|
||||
v = *++p;
|
||||
|
||||
return ((char *) p) + (CFZ (bits) >> 3);
|
||||
}
|
||||
libc_hidden_def (__rawmemchr)
|
||||
weak_alias (__rawmemchr, rawmemchr)
|
68
sysdeps/tile/tilegx/strchr.c
Normal file
68
sysdeps/tile/tilegx/strchr.c
Normal file
@ -0,0 +1,68 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include "string-endian.h"
|
||||
|
||||
#undef strchr
|
||||
|
||||
char *
|
||||
strchr (const char *s, int c)
|
||||
{
|
||||
int z, g;
|
||||
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint64_t *p = (const uint64_t *) (s_int & -8);
|
||||
|
||||
/* Create eight copies of the byte for which we are looking. */
|
||||
const uint64_t goal = 0x0101010101010101ULL * (uint8_t) c;
|
||||
|
||||
/* Read the first aligned word, but force bytes before the string to
|
||||
match neither zero nor goal (we make sure the high bit of each byte
|
||||
is 1, and the low 7 bits are all the opposite of the goal byte). */
|
||||
const uint64_t before_mask = MASK (s_int);
|
||||
uint64_t v = (*p | before_mask) ^ (goal & __insn_v1shrui (before_mask, 1));
|
||||
|
||||
uint64_t zero_matches, goal_matches;
|
||||
while (1)
|
||||
{
|
||||
/* Look for a terminating '\0'. */
|
||||
zero_matches = __insn_v1cmpeqi (v, 0);
|
||||
|
||||
/* Look for the goal byte. */
|
||||
goal_matches = __insn_v1cmpeq (v, goal);
|
||||
|
||||
if (__builtin_expect ((zero_matches | goal_matches) != 0, 0))
|
||||
break;
|
||||
|
||||
v = *++p;
|
||||
}
|
||||
|
||||
z = CFZ (zero_matches);
|
||||
g = CFZ (goal_matches);
|
||||
|
||||
/* If we found c before '\0' we got a match. Note that if c == '\0'
|
||||
then g == z, and we correctly return the address of the '\0'
|
||||
rather than NULL. */
|
||||
return (g <= z) ? ((char *) p) + (g >> 3) : NULL;
|
||||
}
|
||||
weak_alias (strchr, index)
|
||||
libc_hidden_builtin_def (strchr)
|
65
sysdeps/tile/tilegx/strchrnul.c
Normal file
65
sysdeps/tile/tilegx/strchrnul.c
Normal file
@ -0,0 +1,65 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include "string-endian.h"
|
||||
|
||||
char *
|
||||
__strchrnul (const char *s, int c)
|
||||
{
|
||||
int z, g;
|
||||
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint64_t *p = (const uint64_t *) (s_int & -8);
|
||||
|
||||
/* Create eight copies of the byte for which we are looking. */
|
||||
const uint64_t goal = 0x0101010101010101ULL * (uint8_t) c;
|
||||
|
||||
/* Read the first aligned word, but force bytes before the string to
|
||||
match neither zero nor goal (we make sure the high bit of each byte
|
||||
is 1, and the low 7 bits are all the opposite of the goal byte). */
|
||||
const uint64_t before_mask = MASK (s_int);
|
||||
uint64_t v = (*p | before_mask) ^ (goal & __insn_v1shrui (before_mask, 1));
|
||||
|
||||
uint64_t zero_matches, goal_matches;
|
||||
while (1)
|
||||
{
|
||||
/* Look for a terminating '\0'. */
|
||||
zero_matches = __insn_v1cmpeqi (v, 0);
|
||||
|
||||
/* Look for the goal byte. */
|
||||
goal_matches = __insn_v1cmpeq (v, goal);
|
||||
|
||||
if (__builtin_expect ((zero_matches | goal_matches) != 0, 0))
|
||||
break;
|
||||
|
||||
v = *++p;
|
||||
}
|
||||
|
||||
z = CFZ (zero_matches);
|
||||
g = CFZ (goal_matches);
|
||||
|
||||
/* Return a pointer to the NUL or goal, whichever is first. */
|
||||
if (z < g)
|
||||
g = z;
|
||||
return ((char *) p) + (g >> 3);
|
||||
}
|
||||
weak_alias (__strchrnul, strchrnul)
|
36
sysdeps/tile/tilegx/string-endian.h
Normal file
36
sysdeps/tile/tilegx/string-endian.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
/* Provide a mask based on the pointer alignment that
|
||||
sets up non-zero bytes before the beginning of the string.
|
||||
The MASK expression works because shift counts are taken mod 64.
|
||||
Also, specify how to count "first" and "last" bits
|
||||
when the bits have been read as a word. */
|
||||
|
||||
#ifndef __BIG_ENDIAN__
|
||||
#define MASK(x) (__insn_shl(1ULL, (x << 3)) - 1)
|
||||
#define NULMASK(x) ((2ULL << x) - 1)
|
||||
#define CFZ(x) __insn_ctz(x)
|
||||
#define REVCZ(x) __insn_clz(x)
|
||||
#else
|
||||
#define MASK(x) (__insn_shl(-2LL, ((-x << 3) - 1)))
|
||||
#define NULMASK(x) (-2LL << (63 - x))
|
||||
#define CFZ(x) __insn_clz(x)
|
||||
#define REVCZ(x) __insn_ctz(x)
|
||||
#endif
|
40
sysdeps/tile/tilegx/strlen.c
Normal file
40
sysdeps/tile/tilegx/strlen.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include "string-endian.h"
|
||||
|
||||
size_t
|
||||
strlen (const char *s)
|
||||
{
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint64_t *p = (const uint64_t *) (s_int & -8);
|
||||
|
||||
/* Read and MASK the first word. */
|
||||
uint64_t v = *p | MASK (s_int);
|
||||
|
||||
uint64_t bits;
|
||||
while ((bits = __insn_v1cmpeqi (v, 0)) == 0)
|
||||
v = *++p;
|
||||
|
||||
return ((const char *) p) + (CFZ (bits) >> 3) - s;
|
||||
}
|
||||
libc_hidden_builtin_def (strlen)
|
69
sysdeps/tile/tilegx/strrchr.c
Normal file
69
sysdeps/tile/tilegx/strrchr.c
Normal file
@ -0,0 +1,69 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include "string-endian.h"
|
||||
|
||||
char *
|
||||
strrchr (const char *s, int c)
|
||||
{
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint64_t *p = (const uint64_t *) (s_int & -8);
|
||||
|
||||
/* Create eight copies of the byte for which we are looking. */
|
||||
const uint64_t goal = 0x0101010101010101ULL * (uint8_t) c;
|
||||
|
||||
/* Read the first aligned word, but force bytes before the string to
|
||||
match neither zero nor goal (we make sure the high bit of each byte
|
||||
is 1, and the low 7 bits are all the opposite of the goal byte). */
|
||||
const uint64_t before_mask = MASK (s_int);
|
||||
uint64_t v = (*p | before_mask) ^ (goal & __insn_v1shrui (before_mask, 1));
|
||||
const char *found = NULL;
|
||||
uint64_t zero_matches, goal_matches;
|
||||
while (1)
|
||||
{
|
||||
/* Look for a terminating '\0'. */
|
||||
zero_matches = __insn_v1cmpeqi (v, 0);
|
||||
|
||||
/* Look for the goal byte. */
|
||||
goal_matches = __insn_v1cmpeq (v, goal);
|
||||
|
||||
/* If we found the goal, record the last offset. */
|
||||
if (__builtin_expect (goal_matches != 0, 0))
|
||||
{
|
||||
if (__builtin_expect (zero_matches != 0, 0))
|
||||
{
|
||||
/* Clear any goal after the first zero. */
|
||||
int first_nul = CFZ (zero_matches);
|
||||
goal_matches &= NULMASK (first_nul);
|
||||
}
|
||||
if (__builtin_expect (goal_matches != 0, 1))
|
||||
found = ((char *) p) + 7 - (REVCZ (goal_matches) >> 3);
|
||||
}
|
||||
|
||||
if (__builtin_expect (zero_matches != 0, 0))
|
||||
return (char *) found;
|
||||
|
||||
v = *++p;
|
||||
}
|
||||
}
|
||||
weak_alias (strrchr, rindex)
|
||||
libc_hidden_builtin_def (strrchr)
|
3
sysdeps/tile/tilegx/tilegx32/Implies
Normal file
3
sysdeps/tile/tilegx/tilegx32/Implies
Normal file
@ -0,0 +1,3 @@
|
||||
tile/tilegx
|
||||
tile
|
||||
wordsize-32
|
3
sysdeps/tile/tilegx/tilegx64/Implies
Normal file
3
sysdeps/tile/tilegx/tilegx64/Implies
Normal file
@ -0,0 +1,3 @@
|
||||
tile/tilegx
|
||||
tile
|
||||
wordsize-64
|
2
sysdeps/tile/tilepro/Implies
Normal file
2
sysdeps/tile/tilepro/Implies
Normal file
@ -0,0 +1,2 @@
|
||||
tile
|
||||
wordsize-32
|
82
sysdeps/tile/tilepro/bits/atomic.h
Normal file
82
sysdeps/tile/tilepro/bits/atomic.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _BITS_ATOMIC_H
|
||||
#define _BITS_ATOMIC_H 1
|
||||
|
||||
#include <asm/unistd.h>
|
||||
|
||||
/* 32-bit integer compare-and-exchange. */
|
||||
static __inline __attribute__ ((always_inline))
|
||||
int __atomic_cmpxchg_32 (volatile int *mem, int newval, int oldval)
|
||||
{
|
||||
int result;
|
||||
__asm__ __volatile__ ("swint1"
|
||||
: "=R00" (result), "=m" (*mem)
|
||||
: "R10" (__NR_FAST_cmpxchg), "R00" (mem),
|
||||
"R01" (oldval), "R02" (newval), "m" (*mem)
|
||||
: "r20", "r21", "r22", "r23", "r24",
|
||||
"r25", "r26", "r27", "r28", "r29", "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
#define atomic_compare_and_exchange_val_acq(mem, n, o) \
|
||||
((__typeof (*(mem))) \
|
||||
((sizeof (*(mem)) == 4) ? \
|
||||
__atomic_cmpxchg_32 ((int *) (mem), (int) (n), (int) (o)) : \
|
||||
__atomic_error_bad_argument_size()))
|
||||
|
||||
/* Atomically compute:
|
||||
int old = *ptr;
|
||||
*ptr = (old & mask) + addend;
|
||||
return old; */
|
||||
|
||||
static __inline __attribute__ ((always_inline))
|
||||
int __atomic_update_32 (volatile int *mem, int mask, int addend)
|
||||
{
|
||||
int result;
|
||||
__asm__ __volatile__ ("swint1"
|
||||
: "=R00" (result), "=m" (*mem)
|
||||
: "R10" (__NR_FAST_atomic_update), "R00" (mem),
|
||||
"R01" (mask), "R02" (addend), "m" (*mem)
|
||||
: "r20", "r21", "r22", "r23", "r24",
|
||||
"r25", "r26", "r27", "r28", "r29", "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Size-checked verson of __atomic_update_32. */
|
||||
#define __atomic_update(mem, mask, addend) \
|
||||
((__typeof (*(mem))) \
|
||||
((sizeof (*(mem)) == 4) ? \
|
||||
__atomic_update_32 ((int *) (mem), (int) (mask), (int) (addend)) : \
|
||||
__atomic_error_bad_argument_size ()))
|
||||
|
||||
#define atomic_exchange_acq(mem, newvalue) \
|
||||
__atomic_update ((mem), 0, (newvalue))
|
||||
#define atomic_exchange_and_add(mem, value) \
|
||||
__atomic_update ((mem), -1, (value))
|
||||
#define atomic_and_val(mem, mask) \
|
||||
__atomic_update ((mem), (mask), 0)
|
||||
#define atomic_or_val(mem, mask) \
|
||||
({ __typeof (mask) __att1_v = (mask); \
|
||||
__atomic_update ((mem), ~__att1_v, __att1_v); })
|
||||
|
||||
#include <sysdeps/tile/bits/atomic.h>
|
||||
|
||||
#endif /* bits/atomic.h */
|
3
sysdeps/tile/tilepro/bits/wordsize.h
Normal file
3
sysdeps/tile/tilepro/bits/wordsize.h
Normal file
@ -0,0 +1,3 @@
|
||||
/* Determine the wordsize from the preprocessor defines. */
|
||||
|
||||
#define __WORDSIZE 32
|
73
sysdeps/tile/tilepro/memchr.c
Normal file
73
sysdeps/tile/tilepro/memchr.c
Normal file
@ -0,0 +1,73 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void *
|
||||
__memchr (const void *s, int c, size_t n)
|
||||
{
|
||||
const uint32_t *last_word_ptr;
|
||||
const uint32_t *p;
|
||||
const char *last_byte_ptr;
|
||||
uintptr_t s_int;
|
||||
uint32_t goal, before_mask, v, bits;
|
||||
char *ret;
|
||||
|
||||
if (__builtin_expect (n == 0, 0))
|
||||
{
|
||||
/* Don't dereference any memory if the array is empty. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get an aligned pointer. */
|
||||
s_int = (uintptr_t) s;
|
||||
p = (const uint32_t *) (s_int & -4);
|
||||
|
||||
/* Create four copies of the byte for which we are looking. */
|
||||
goal = 0x01010101 * (uint8_t) c;
|
||||
|
||||
/* Read the first word, but munge it so that bytes before the array
|
||||
will not match goal. Note that this shift count expression works
|
||||
because we know shift counts are taken mod 32. */
|
||||
before_mask = (1 << (s_int << 3)) - 1;
|
||||
v = (*p | before_mask) ^ (goal & before_mask);
|
||||
|
||||
/* Compute the address of the last byte. */
|
||||
last_byte_ptr = (const char *) s + n - 1;
|
||||
|
||||
/* Compute the address of the word containing the last byte. */
|
||||
last_word_ptr = (const uint32_t *) ((uintptr_t) last_byte_ptr & -4);
|
||||
|
||||
while ((bits = __insn_seqb (v, goal)) == 0)
|
||||
{
|
||||
if (__builtin_expect (p == last_word_ptr, 0))
|
||||
{
|
||||
/* We already read the last word in the array, so give up. */
|
||||
return NULL;
|
||||
}
|
||||
v = *++p;
|
||||
}
|
||||
|
||||
/* We found a match, but it might be in a byte past the end of the array. */
|
||||
ret = ((char *) p) + (__insn_ctz (bits) >> 3);
|
||||
return (ret <= last_byte_ptr) ? ret : NULL;
|
||||
}
|
||||
weak_alias (__memchr, memchr)
|
||||
libc_hidden_builtin_def (memchr)
|
398
sysdeps/tile/tilepro/memcpy.S
Normal file
398
sysdeps/tile/tilepro/memcpy.S
Normal file
@ -0,0 +1,398 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <arch/chip.h>
|
||||
#include <sysdep.h>
|
||||
|
||||
.text
|
||||
ENTRY (__memcpy)
|
||||
FEEDBACK_ENTER(__memcpy)
|
||||
|
||||
/* r0 is the dest, r1 is the source, r2 is the size. */
|
||||
|
||||
/* Save aside original dest so we can return it at the end. */
|
||||
{ sw sp, lr; move r23, r0; or r4, r0, r1 }
|
||||
cfi_offset (lr, 0)
|
||||
|
||||
/* Check for an empty size. */
|
||||
{ bz r2, .Ldone; andi r4, r4, 3 }
|
||||
|
||||
/* Check for an unaligned source or dest. */
|
||||
{ bnz r4, .Lcopy_unaligned_maybe_many; addli r4, r2, -256 }
|
||||
|
||||
.Lcheck_aligned_copy_size:
|
||||
/* If we are copying < 256 bytes, branch to simple case. */
|
||||
{ blzt r4, .Lcopy_8_check; slti_u r8, r2, 8 }
|
||||
|
||||
/* Copying >= 256 bytes, so jump to complex prefetching loop. */
|
||||
{ andi r6, r1, 63; j .Lcopy_many }
|
||||
|
||||
/* Aligned 4 byte at a time copy loop. */
|
||||
|
||||
.Lcopy_8_loop:
|
||||
/* Copy two words at a time to hide load latency. */
|
||||
{ lw r3, r1; addi r1, r1, 4; slti_u r8, r2, 16 }
|
||||
{ lw r4, r1; addi r1, r1, 4 }
|
||||
{ sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
|
||||
{ sw r0, r4; addi r0, r0, 4; addi r2, r2, -4 }
|
||||
.Lcopy_8_check:
|
||||
{ bzt r8, .Lcopy_8_loop; slti_u r4, r2, 4 }
|
||||
|
||||
/* Copy odd leftover word, if any. */
|
||||
{ bnzt r4, .Lcheck_odd_stragglers }
|
||||
{ lw r3, r1; addi r1, r1, 4 }
|
||||
{ sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
|
||||
|
||||
.Lcheck_odd_stragglers:
|
||||
{ bnz r2, .Lcopy_unaligned_few }
|
||||
|
||||
.Ldone:
|
||||
{ move r0, r23; jrp lr }
|
||||
|
||||
/* Prefetching multiple cache line copy handler (for large transfers). */
|
||||
|
||||
/* Copy words until r1 is cache-line-aligned. */
|
||||
.Lalign_loop:
|
||||
{ lw r3, r1; addi r1, r1, 4 }
|
||||
{ andi r6, r1, 63 }
|
||||
{ sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
|
||||
.Lcopy_many:
|
||||
{ bnzt r6, .Lalign_loop; addi r9, r0, 63 }
|
||||
|
||||
{ addi r3, r1, 60; andi r9, r9, -64 }
|
||||
|
||||
/* No need to prefetch dst, we'll just do the wh64
|
||||
right before we copy a line. */
|
||||
{ lw r5, r3; addi r3, r3, 64; movei r4, 1 }
|
||||
/* Intentionally stall for a few cycles to leave L2 cache alone. */
|
||||
{ bnzt zero, .; move r27, lr }
|
||||
{ lw r6, r3; addi r3, r3, 64 }
|
||||
/* Intentionally stall for a few cycles to leave L2 cache alone. */
|
||||
{ bnzt zero, . }
|
||||
{ lw r7, r3; addi r3, r3, 64 }
|
||||
/* Intentionally stall for a few cycles to leave L2 cache alone. */
|
||||
{ bz zero, .Lbig_loop2 }
|
||||
|
||||
/* On entry to this loop:
|
||||
- r0 points to the start of dst line 0
|
||||
- r1 points to start of src line 0
|
||||
- r2 >= (256 - 60), only the first time the loop trips.
|
||||
- r3 contains r1 + 128 + 60 [pointer to end of source line 2]
|
||||
This is our prefetch address. When we get near the end
|
||||
rather than prefetching off the end this is changed to point
|
||||
to some "safe" recently loaded address.
|
||||
- r5 contains *(r1 + 60) [i.e. last word of source line 0]
|
||||
- r6 contains *(r1 + 64 + 60) [i.e. last word of source line 1]
|
||||
- r9 contains ((r0 + 63) & -64)
|
||||
[start of next dst cache line.] */
|
||||
|
||||
.Lbig_loop:
|
||||
{ jal .Lcopy_line2; add r15, r1, r2 }
|
||||
|
||||
.Lbig_loop2:
|
||||
/* Copy line 0, first stalling until r5 is ready. */
|
||||
{ move r12, r5; lw r16, r1 }
|
||||
{ bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
|
||||
/* Prefetch several lines ahead. */
|
||||
{ lw r5, r3; addi r3, r3, 64 }
|
||||
{ jal .Lcopy_line }
|
||||
|
||||
/* Copy line 1, first stalling until r6 is ready. */
|
||||
{ move r12, r6; lw r16, r1 }
|
||||
{ bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
|
||||
/* Prefetch several lines ahead. */
|
||||
{ lw r6, r3; addi r3, r3, 64 }
|
||||
{ jal .Lcopy_line }
|
||||
|
||||
/* Copy line 2, first stalling until r7 is ready. */
|
||||
{ move r12, r7; lw r16, r1 }
|
||||
{ bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
|
||||
/* Prefetch several lines ahead. */
|
||||
{ lw r7, r3; addi r3, r3, 64 }
|
||||
/* Use up a caches-busy cycle by jumping back to the top of the
|
||||
loop. Might as well get it out of the way now. */
|
||||
{ j .Lbig_loop }
|
||||
|
||||
|
||||
/* On entry:
|
||||
- r0 points to the destination line.
|
||||
- r1 points to the source line.
|
||||
- r3 is the next prefetch address.
|
||||
- r9 holds the last address used for wh64.
|
||||
- r12 = WORD_15
|
||||
- r16 = WORD_0.
|
||||
- r17 == r1 + 16.
|
||||
- r27 holds saved lr to restore.
|
||||
|
||||
On exit:
|
||||
- r0 is incremented by 64.
|
||||
- r1 is incremented by 64, unless that would point to a word
|
||||
beyond the end of the source array, in which case it is redirected
|
||||
to point to an arbitrary word already in the cache.
|
||||
- r2 is decremented by 64.
|
||||
- r3 is unchanged, unless it points to a word beyond the
|
||||
end of the source array, in which case it is redirected
|
||||
to point to an arbitrary word already in the cache.
|
||||
Redirecting is OK since if we are that close to the end
|
||||
of the array we will not come back to this subroutine
|
||||
and use the contents of the prefetched address.
|
||||
- r4 is nonzero iff r2 >= 64.
|
||||
- r9 is incremented by 64, unless it points beyond the
|
||||
end of the last full destination cache line, in which
|
||||
case it is redirected to a "safe address" that can be
|
||||
clobbered (sp - 64)
|
||||
- lr contains the value in r27. */
|
||||
|
||||
/* r26 unused */
|
||||
|
||||
.Lcopy_line:
|
||||
/* TODO: when r3 goes past the end, we would like to redirect it
|
||||
to prefetch the last partial cache line (if any) just once, for the
|
||||
benefit of the final cleanup loop. But we don't want to
|
||||
prefetch that line more than once, or subsequent prefetches
|
||||
will go into the RTF. But then .Lbig_loop should unconditionally
|
||||
branch to top of loop to execute final prefetch, and its
|
||||
nop should become a conditional branch. */
|
||||
|
||||
/* We need two non-memory cycles here to cover the resources
|
||||
used by the loads initiated by the caller. */
|
||||
{ add r15, r1, r2 }
|
||||
.Lcopy_line2:
|
||||
{ slt_u r13, r3, r15; addi r17, r1, 16 }
|
||||
|
||||
/* NOTE: this will stall for one cycle as L1 is busy. */
|
||||
|
||||
/* Fill second L1D line. */
|
||||
{ lw r17, r17; addi r1, r1, 48; mvz r3, r13, r1 } /* r17 = WORD_4 */
|
||||
|
||||
/* Prepare destination line for writing. */
|
||||
{ wh64 r9; addi r9, r9, 64 }
|
||||
|
||||
/* Load seven words that are L1D hits to cover wh64 L2 usage. */
|
||||
|
||||
/* Load the three remaining words from the last L1D line, which
|
||||
we know has already filled the L1D. */
|
||||
{ lw r4, r1; addi r1, r1, 4; addi r20, r1, 16 } /* r4 = WORD_12 */
|
||||
{ lw r8, r1; addi r1, r1, 4; slt_u r13, r20, r15 }/* r8 = WORD_13 */
|
||||
{ lw r11, r1; addi r1, r1, -52; mvz r20, r13, r1 } /* r11 = WORD_14 */
|
||||
|
||||
/* Load the three remaining words from the first L1D line, first
|
||||
stalling until it has filled by "looking at" r16. */
|
||||
{ lw r13, r1; addi r1, r1, 4; move zero, r16 } /* r13 = WORD_1 */
|
||||
{ lw r14, r1; addi r1, r1, 4 } /* r14 = WORD_2 */
|
||||
{ lw r15, r1; addi r1, r1, 8; addi r10, r0, 60 } /* r15 = WORD_3 */
|
||||
|
||||
/* Load second word from the second L1D line, first
|
||||
stalling until it has filled by "looking at" r17. */
|
||||
{ lw r19, r1; addi r1, r1, 4; move zero, r17 } /* r19 = WORD_5 */
|
||||
|
||||
/* Store last word to the destination line, potentially dirtying it
|
||||
for the first time, which keeps the L2 busy for two cycles. */
|
||||
{ sw r10, r12 } /* store(WORD_15) */
|
||||
|
||||
/* Use two L1D hits to cover the sw L2 access above. */
|
||||
{ lw r10, r1; addi r1, r1, 4 } /* r10 = WORD_6 */
|
||||
{ lw r12, r1; addi r1, r1, 4 } /* r12 = WORD_7 */
|
||||
|
||||
/* Fill third L1D line. */
|
||||
{ lw r18, r1; addi r1, r1, 4 } /* r18 = WORD_8 */
|
||||
|
||||
/* Store first L1D line. */
|
||||
{ sw r0, r16; addi r0, r0, 4; add r16, r0, r2 } /* store(WORD_0) */
|
||||
{ sw r0, r13; addi r0, r0, 4; andi r16, r16, -64 } /* store(WORD_1) */
|
||||
{ sw r0, r14; addi r0, r0, 4; slt_u r16, r9, r16 } /* store(WORD_2) */
|
||||
{ sw r0, r15; addi r0, r0, 4; addi r13, sp, -64 } /* store(WORD_3) */
|
||||
|
||||
/* Store second L1D line. */
|
||||
{ sw r0, r17; addi r0, r0, 4; mvz r9, r16, r13 }/* store(WORD_4) */
|
||||
{ sw r0, r19; addi r0, r0, 4 } /* store(WORD_5) */
|
||||
{ sw r0, r10; addi r0, r0, 4 } /* store(WORD_6) */
|
||||
{ sw r0, r12; addi r0, r0, 4 } /* store(WORD_7) */
|
||||
|
||||
{ lw r13, r1; addi r1, r1, 4; move zero, r18 } /* r13 = WORD_9 */
|
||||
{ lw r14, r1; addi r1, r1, 4 } /* r14 = WORD_10 */
|
||||
{ lw r15, r1; move r1, r20 } /* r15 = WORD_11 */
|
||||
|
||||
/* Store third L1D line. */
|
||||
{ sw r0, r18; addi r0, r0, 4 } /* store(WORD_8) */
|
||||
{ sw r0, r13; addi r0, r0, 4 } /* store(WORD_9) */
|
||||
{ sw r0, r14; addi r0, r0, 4 } /* store(WORD_10) */
|
||||
{ sw r0, r15; addi r0, r0, 4 } /* store(WORD_11) */
|
||||
|
||||
/* Store rest of fourth L1D line. */
|
||||
{ sw r0, r4; addi r0, r0, 4 } /* store(WORD_12) */
|
||||
{
|
||||
sw r0, r8 /* store(WORD_13) */
|
||||
addi r0, r0, 4
|
||||
/* Will r2 be > 64 after we subtract 64 below? */
|
||||
shri r4, r2, 7
|
||||
}
|
||||
{
|
||||
sw r0, r11 /* store(WORD_14) */
|
||||
addi r0, r0, 8
|
||||
/* Record 64 bytes successfully copied. */
|
||||
addi r2, r2, -64
|
||||
}
|
||||
|
||||
{ jrp lr; move lr, r27 }
|
||||
|
||||
/* Convey to the backtrace library that the stack frame is
|
||||
size zero, and the real return address is on the stack
|
||||
rather than in 'lr'. */
|
||||
{ info 8 }
|
||||
|
||||
.align 64
|
||||
.Lcopy_unaligned_maybe_many:
|
||||
/* Skip the setup overhead if we aren't copying many bytes. */
|
||||
{ slti_u r8, r2, 20; sub r4, zero, r0 }
|
||||
{ bnzt r8, .Lcopy_unaligned_few; andi r4, r4, 3 }
|
||||
{ bz r4, .Ldest_is_word_aligned; add r18, r1, r2 }
|
||||
|
||||
/* Unaligned 4 byte at a time copy handler. */
|
||||
|
||||
/* Copy single bytes until r0 == 0 mod 4, so we can store words. */
|
||||
.Lalign_dest_loop:
|
||||
{ lb_u r3, r1; addi r1, r1, 1; addi r4, r4, -1 }
|
||||
{ sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
|
||||
{ bnzt r4, .Lalign_dest_loop; andi r3, r1, 3 }
|
||||
|
||||
/* If source and dest are now *both* aligned, do an aligned copy. */
|
||||
{ bz r3, .Lcheck_aligned_copy_size; addli r4, r2, -256 }
|
||||
|
||||
.Ldest_is_word_aligned:
|
||||
|
||||
{ andi r8, r0, 63; lwadd_na r6, r1, 4}
|
||||
{ slti_u r9, r2, 64; bz r8, .Ldest_is_L2_line_aligned }
|
||||
|
||||
/* This copies unaligned words until either there are fewer
|
||||
than 4 bytes left to copy, or until the destination pointer
|
||||
is cache-aligned, whichever comes first.
|
||||
|
||||
On entry:
|
||||
- r0 is the next store address.
|
||||
- r1 points 4 bytes past the load address corresponding to r0.
|
||||
- r2 >= 4
|
||||
- r6 is the next aligned word loaded. */
|
||||
.Lcopy_unaligned_src_words:
|
||||
{ lwadd_na r7, r1, 4; slti_u r8, r2, 4 + 4 }
|
||||
/* stall */
|
||||
{ dword_align r6, r7, r1; slti_u r9, r2, 64 + 4 }
|
||||
{ swadd r0, r6, 4; addi r2, r2, -4 }
|
||||
{ bnz r8, .Lcleanup_unaligned_words; andi r8, r0, 63 }
|
||||
{ bnzt r8, .Lcopy_unaligned_src_words; move r6, r7 }
|
||||
|
||||
/* On entry:
|
||||
- r0 is the next store address.
|
||||
- r1 points 4 bytes past the load address corresponding to r0.
|
||||
- r2 >= 4 (# of bytes left to store).
|
||||
- r6 is the next aligned src word value.
|
||||
- r9 = (r2 < 64U).
|
||||
- r18 points one byte past the end of source memory. */
|
||||
.Ldest_is_L2_line_aligned:
|
||||
|
||||
{
|
||||
/* Not a full cache line remains. */
|
||||
bnz r9, .Lcleanup_unaligned_words
|
||||
move r7, r6
|
||||
}
|
||||
|
||||
/* r2 >= 64 */
|
||||
|
||||
/* Kick off two prefetches, but don't go past the end. */
|
||||
{ addi r3, r1, 63 - 4; addi r8, r1, 64 + 63 - 4 }
|
||||
{ prefetch r3; move r3, r8; slt_u r8, r8, r18 }
|
||||
{ mvz r3, r8, r1; addi r8, r3, 64 }
|
||||
{ prefetch r3; move r3, r8; slt_u r8, r8, r18 }
|
||||
{ mvz r3, r8, r1; movei r17, 0 }
|
||||
|
||||
.Lcopy_unaligned_line:
|
||||
/* Prefetch another line. */
|
||||
{ prefetch r3; addi r15, r1, 60; addi r3, r3, 64 }
|
||||
/* Fire off a load of the last word we are about to copy. */
|
||||
{ lw_na r15, r15; slt_u r8, r3, r18 }
|
||||
|
||||
{ mvz r3, r8, r1; wh64 r0 }
|
||||
|
||||
/* This loop runs twice.
|
||||
|
||||
On entry:
|
||||
- r17 is even before the first iteration, and odd before
|
||||
the second. It is incremented inside the loop. Encountering
|
||||
an even value at the end of the loop makes it stop. */
|
||||
.Lcopy_half_an_unaligned_line:
|
||||
{
|
||||
/* Stall until the last byte is ready. In the steady state this
|
||||
guarantees all words to load below will be in the L2 cache, which
|
||||
avoids shunting the loads to the RTF. */
|
||||
move zero, r15
|
||||
lwadd_na r7, r1, 16
|
||||
}
|
||||
{ lwadd_na r11, r1, 12 }
|
||||
{ lwadd_na r14, r1, -24 }
|
||||
{ lwadd_na r8, r1, 4 }
|
||||
{ lwadd_na r9, r1, 4 }
|
||||
{
|
||||
lwadd_na r10, r1, 8
|
||||
/* r16 = (r2 < 64), after we subtract 32 from r2 below. */
|
||||
slti_u r16, r2, 64 + 32
|
||||
}
|
||||
{ lwadd_na r12, r1, 4; addi r17, r17, 1 }
|
||||
{ lwadd_na r13, r1, 8; dword_align r6, r7, r1 }
|
||||
{ swadd r0, r6, 4; dword_align r7, r8, r1 }
|
||||
{ swadd r0, r7, 4; dword_align r8, r9, r1 }
|
||||
{ swadd r0, r8, 4; dword_align r9, r10, r1 }
|
||||
{ swadd r0, r9, 4; dword_align r10, r11, r1 }
|
||||
{ swadd r0, r10, 4; dword_align r11, r12, r1 }
|
||||
{ swadd r0, r11, 4; dword_align r12, r13, r1 }
|
||||
{ swadd r0, r12, 4; dword_align r13, r14, r1 }
|
||||
{ swadd r0, r13, 4; addi r2, r2, -32 }
|
||||
{ move r6, r14; bbst r17, .Lcopy_half_an_unaligned_line }
|
||||
|
||||
{ bzt r16, .Lcopy_unaligned_line; move r7, r6 }
|
||||
|
||||
/* On entry:
|
||||
- r0 is the next store address.
|
||||
- r1 points 4 bytes past the load address corresponding to r0.
|
||||
- r2 >= 0 (# of bytes left to store).
|
||||
- r7 is the next aligned src word value. */
|
||||
.Lcleanup_unaligned_words:
|
||||
/* Handle any trailing bytes. */
|
||||
{ bz r2, .Lcopy_unaligned_done; slti_u r8, r2, 4 }
|
||||
{ bzt r8, .Lcopy_unaligned_src_words; move r6, r7 }
|
||||
|
||||
/* Move r1 back to the point where it corresponds to r0. */
|
||||
{ addi r1, r1, -4 }
|
||||
|
||||
/* Fall through */
|
||||
|
||||
/* 1 byte at a time copy handler. */
|
||||
|
||||
.Lcopy_unaligned_few:
|
||||
{ lb_u r3, r1; addi r1, r1, 1 }
|
||||
{ sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
|
||||
{ bnzt r2, .Lcopy_unaligned_few }
|
||||
|
||||
.Lcopy_unaligned_done:
|
||||
|
||||
{ move r0, r23; jrp lr }
|
||||
|
||||
END (__memcpy)
|
||||
|
||||
weak_alias (__memcpy, memcpy)
|
||||
libc_hidden_builtin_def (memcpy)
|
152
sysdeps/tile/tilepro/memset.c
Normal file
152
sysdeps/tile/tilepro/memset.c
Normal file
@ -0,0 +1,152 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include <arch/chip.h>
|
||||
|
||||
void *
|
||||
__memset (void *s, int c, size_t n)
|
||||
{
|
||||
uint32_t *out32;
|
||||
int n32;
|
||||
uint32_t v16, v32;
|
||||
uint8_t *out8 = s;
|
||||
int to_align32;
|
||||
|
||||
/* Experimentation shows that a trivial tight loop is a win up until
|
||||
around a size of 20, where writing a word at a time starts to win. */
|
||||
#define BYTE_CUTOFF 20
|
||||
|
||||
#if BYTE_CUTOFF < 3
|
||||
/* This must be at least at least this big, or some code later
|
||||
on doesn't work. */
|
||||
# error "BYTE_CUTOFF is too small."
|
||||
#endif
|
||||
|
||||
if (n < BYTE_CUTOFF)
|
||||
{
|
||||
/* Strangely, this turns out to be the tightest way to write
|
||||
this loop. */
|
||||
if (n != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Strangely, combining these into one line performs worse. */
|
||||
*out8 = c;
|
||||
out8++;
|
||||
}
|
||||
while (--n != 0);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Align 'out8'. We know n >= 3 so this won't write past the end. */
|
||||
while (((uintptr_t) out8 & 3) != 0)
|
||||
{
|
||||
*out8++ = c;
|
||||
--n;
|
||||
}
|
||||
|
||||
/* Align 'n'. */
|
||||
while (n & 3)
|
||||
out8[--n] = c;
|
||||
|
||||
out32 = (uint32_t *) out8;
|
||||
n32 = n >> 2;
|
||||
|
||||
/* Tile input byte out to 32 bits. */
|
||||
v16 = __insn_intlb (c, c);
|
||||
v32 = __insn_intlh (v16, v16);
|
||||
|
||||
/* This must be at least 8 or the following loop doesn't work. */
|
||||
#define CACHE_LINE_SIZE_IN_WORDS (CHIP_L2_LINE_SIZE() / 4)
|
||||
|
||||
/* Determine how many words we need to emit before the 'out32'
|
||||
pointer becomes aligned modulo the cache line size. */
|
||||
to_align32 = (-((uintptr_t) out32 >> 2)) & (CACHE_LINE_SIZE_IN_WORDS - 1);
|
||||
|
||||
/* Only bother aligning and using wh64 if there is at least one full
|
||||
cache line to process. This check also prevents overrunning the
|
||||
end of the buffer with alignment words. */
|
||||
if (to_align32 <= n32 - CACHE_LINE_SIZE_IN_WORDS)
|
||||
{
|
||||
int lines_left;
|
||||
|
||||
/* Align out32 mod the cache line size so we can use wh64. */
|
||||
n32 -= to_align32;
|
||||
for (; to_align32 != 0; to_align32--)
|
||||
{
|
||||
*out32 = v32;
|
||||
out32++;
|
||||
}
|
||||
|
||||
/* Use unsigned divide to turn this into a right shift. */
|
||||
lines_left = (unsigned) n32 / CACHE_LINE_SIZE_IN_WORDS;
|
||||
|
||||
do
|
||||
{
|
||||
/* Only wh64 a few lines at a time, so we don't exceed the
|
||||
maximum number of victim lines. */
|
||||
int x = ((lines_left < CHIP_MAX_OUTSTANDING_VICTIMS ())? lines_left
|
||||
: CHIP_MAX_OUTSTANDING_VICTIMS ());
|
||||
uint32_t *wh = out32;
|
||||
int i = x;
|
||||
int j;
|
||||
|
||||
lines_left -= x;
|
||||
|
||||
do
|
||||
{
|
||||
__insn_wh64 (wh);
|
||||
wh += CACHE_LINE_SIZE_IN_WORDS;
|
||||
}
|
||||
while (--i);
|
||||
|
||||
for (j = x * (CACHE_LINE_SIZE_IN_WORDS / 4); j != 0; j--)
|
||||
{
|
||||
*out32++ = v32;
|
||||
*out32++ = v32;
|
||||
*out32++ = v32;
|
||||
*out32++ = v32;
|
||||
}
|
||||
}
|
||||
while (lines_left != 0);
|
||||
|
||||
/* We processed all full lines above, so only this many words
|
||||
remain to be processed. */
|
||||
n32 &= CACHE_LINE_SIZE_IN_WORDS - 1;
|
||||
}
|
||||
|
||||
/* Now handle any leftover values. */
|
||||
if (n32 != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
*out32 = v32;
|
||||
out32++;
|
||||
}
|
||||
while (--n32 != 0);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
weak_alias (__memset, memset)
|
||||
libc_hidden_builtin_def (memset)
|
30
sysdeps/tile/tilepro/memusage.h
Normal file
30
sysdeps/tile/tilepro/memusage.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <arch/spr_def.h>
|
||||
|
||||
#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; })
|
||||
|
||||
#define GETTIME(low,high) \
|
||||
{ \
|
||||
low = __insn_mfspr (SPR_CYCLE_LOW); \
|
||||
high = __insn_mfspr (SPR_CYCLE_HIGH); \
|
||||
}
|
||||
|
||||
#include <sysdeps/generic/memusage.h>
|
46
sysdeps/tile/tilepro/rawmemchr.c
Normal file
46
sysdeps/tile/tilepro/rawmemchr.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void *
|
||||
__rawmemchr (const void *s, int c)
|
||||
{
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint32_t *p = (const uint32_t *) (s_int & -4);
|
||||
|
||||
/* Create four copies of the byte for which we are looking. */
|
||||
const uint32_t goal = 0x01010101 * (uint8_t) c;
|
||||
|
||||
/* Read the first word, but munge it so that bytes before the array
|
||||
will not match goal. Note that this shift count expression works
|
||||
because we know shift counts are taken mod 32. */
|
||||
const uint32_t before_mask = (1 << (s_int << 3)) - 1;
|
||||
uint32_t v = (*p | before_mask) ^ (goal & before_mask);
|
||||
|
||||
uint32_t bits;
|
||||
while ((bits = __insn_seqb (v, goal)) == 0)
|
||||
v = *++p;
|
||||
|
||||
return ((char *) p) + (__insn_ctz (bits) >> 3);
|
||||
}
|
||||
libc_hidden_def (__rawmemchr)
|
||||
weak_alias (__rawmemchr, rawmemchr)
|
69
sysdeps/tile/tilepro/strchr.c
Normal file
69
sysdeps/tile/tilepro/strchr.c
Normal file
@ -0,0 +1,69 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#undef strchr
|
||||
|
||||
char *
|
||||
strchr (const char *s, int c)
|
||||
{
|
||||
int z, g;
|
||||
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint32_t *p = (const uint32_t *) (s_int & -4);
|
||||
|
||||
/* Create four copies of the byte for which we are looking. */
|
||||
const uint32_t goal = 0x01010101 * (uint8_t) c;
|
||||
|
||||
/* Read the first aligned word, but force bytes before the string to
|
||||
match neither zero nor goal (we make sure the high bit of each
|
||||
byte is 1, and the low 7 bits are all the opposite of the goal
|
||||
byte). Note that this shift count expression works because we
|
||||
know shift counts are taken mod 32. */
|
||||
const uint32_t before_mask = (1 << (s_int << 3)) - 1;
|
||||
uint32_t v = (*p | before_mask) ^ (goal & __insn_shrib (before_mask, 1));
|
||||
|
||||
uint32_t zero_matches, goal_matches;
|
||||
while (1)
|
||||
{
|
||||
/* Look for a terminating '\0'. */
|
||||
zero_matches = __insn_seqb (v, 0);
|
||||
|
||||
/* Look for the goal byte. */
|
||||
goal_matches = __insn_seqb (v, goal);
|
||||
|
||||
if (__builtin_expect ((zero_matches | goal_matches) != 0, 0))
|
||||
break;
|
||||
|
||||
v = *++p;
|
||||
}
|
||||
|
||||
z = __insn_ctz (zero_matches);
|
||||
g = __insn_ctz (goal_matches);
|
||||
|
||||
/* If we found c before '\0' we got a match. Note that if c == '\0'
|
||||
then g == z, and we correctly return the address of the '\0'
|
||||
rather than NULL. */
|
||||
return (g <= z) ? ((char *) p) + (g >> 3) : NULL;
|
||||
}
|
||||
weak_alias (strchr, index)
|
||||
libc_hidden_builtin_def (strchr)
|
66
sysdeps/tile/tilepro/strchrnul.c
Normal file
66
sysdeps/tile/tilepro/strchrnul.c
Normal file
@ -0,0 +1,66 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
char *
|
||||
__strchrnul (const char *s, int c)
|
||||
{
|
||||
int z, g;
|
||||
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint32_t *p = (const uint32_t *) (s_int & -4);
|
||||
|
||||
/* Create four copies of the byte for which we are looking. */
|
||||
const uint32_t goal = 0x01010101 * (uint8_t) c;
|
||||
|
||||
/* Read the first aligned word, but force bytes before the string to
|
||||
match neither zero nor goal (we make sure the high bit of each
|
||||
byte is 1, and the low 7 bits are all the opposite of the goal
|
||||
byte). Note that this shift count expression works because we
|
||||
know shift counts are taken mod 32. */
|
||||
const uint32_t before_mask = (1 << (s_int << 3)) - 1;
|
||||
uint32_t v = (*p | before_mask) ^ (goal & __insn_shrib (before_mask, 1));
|
||||
|
||||
uint32_t zero_matches, goal_matches;
|
||||
while (1)
|
||||
{
|
||||
/* Look for a terminating '\0'. */
|
||||
zero_matches = __insn_seqb (v, 0);
|
||||
|
||||
/* Look for the goal byte. */
|
||||
goal_matches = __insn_seqb (v, goal);
|
||||
|
||||
if (__builtin_expect ((zero_matches | goal_matches) != 0, 0))
|
||||
break;
|
||||
|
||||
v = *++p;
|
||||
}
|
||||
|
||||
z = __insn_ctz (zero_matches);
|
||||
g = __insn_ctz (goal_matches);
|
||||
|
||||
/* Return a pointer to the NUL or goal, whichever is first. */
|
||||
if (z < g)
|
||||
g = z;
|
||||
return ((char *) p) + (g >> 3);
|
||||
}
|
||||
weak_alias (__strchrnul, strchrnul)
|
40
sysdeps/tile/tilepro/strlen.c
Normal file
40
sysdeps/tile/tilepro/strlen.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
size_t
|
||||
strlen (const char *s)
|
||||
{
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint32_t *p = (const uint32_t *) (s_int & -4);
|
||||
|
||||
/* Read the first word, but force bytes before the string to be nonzero.
|
||||
This expression works because we know shift counts are taken mod 32. */
|
||||
uint32_t v = *p | ((1 << (s_int << 3)) - 1);
|
||||
|
||||
uint32_t bits;
|
||||
while ((bits = __insn_seqb (v, 0)) == 0)
|
||||
v = *++p;
|
||||
|
||||
return ((const char *) p) + (__insn_ctz (bits) >> 3) - s;
|
||||
}
|
||||
libc_hidden_builtin_def (strlen)
|
74
sysdeps/tile/tilepro/strrchr.c
Normal file
74
sysdeps/tile/tilepro/strrchr.c
Normal file
@ -0,0 +1,74 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
char *
|
||||
strrchr (const char *s, int c)
|
||||
{
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint32_t *p = (const uint32_t *) (s_int & -4);
|
||||
|
||||
/* Create four copies of the byte for which we are looking. */
|
||||
const uint32_t goal = 0x01010101 * (uint8_t) c;
|
||||
|
||||
/* Read the first aligned word, but force bytes before the string to
|
||||
match neither zero nor goal (we make sure the high bit of each
|
||||
byte is 1, and the low 7 bits are all the opposite of the goal
|
||||
byte). Note that this shift count expression works because we
|
||||
know shift counts are taken mod 32. */
|
||||
const uint32_t before_mask = (1 << (s_int << 3)) - 1;
|
||||
uint32_t v = (*p | before_mask) ^ (goal & __insn_shrib (before_mask, 1));
|
||||
const char *found = NULL;
|
||||
uint32_t zero_matches, goal_matches;
|
||||
while (1)
|
||||
{
|
||||
/* Look for a terminating '\0'. */
|
||||
zero_matches = __insn_seqb (v, 0);
|
||||
|
||||
/* Look for the goal byte. */
|
||||
goal_matches = __insn_seqb (v, goal);
|
||||
|
||||
/* If we found the goal, record the last offset. */
|
||||
if (__builtin_expect (goal_matches != 0, 0))
|
||||
{
|
||||
if (__builtin_expect (zero_matches != 0, 0))
|
||||
{
|
||||
/* Clear any goal after the first zero. */
|
||||
int first_nul = __insn_ctz (zero_matches);
|
||||
/* The number of top bits we need to clear is
|
||||
32 - (first_nul + 8). */
|
||||
int shift_amt = (24 - first_nul);
|
||||
goal_matches <<= shift_amt;
|
||||
goal_matches >>= shift_amt;
|
||||
}
|
||||
if (__builtin_expect (goal_matches != 0, 1))
|
||||
found = ((char *) p) + 3 - (__insn_clz (goal_matches) >> 3);
|
||||
}
|
||||
|
||||
if (__builtin_expect (zero_matches != 0, 0))
|
||||
return (char *) found;
|
||||
|
||||
v = *++p;
|
||||
}
|
||||
}
|
||||
weak_alias (strrchr, rindex)
|
||||
libc_hidden_builtin_def (strrchr)
|
57
sysdeps/tile/tls-macros.h
Normal file
57
sysdeps/tile/tls-macros.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
#ifdef __tilegx__
|
||||
#define TLS_GD_REL "hw0_last_tls_gd"
|
||||
#define TLS_IE_REL "hw0_last_tls_ie"
|
||||
#define LD_TLS "ld_tls"
|
||||
#else
|
||||
#define TLS_GD_REL "tls_gd_lo16"
|
||||
#define TLS_IE_REL "tls_ie_lo16"
|
||||
#define LD_TLS "lw_tls"
|
||||
#endif
|
||||
|
||||
#define TLS_GD(x) \
|
||||
({ \
|
||||
int *__retval; \
|
||||
extern char _GLOBAL_OFFSET_TABLE_[]; \
|
||||
\
|
||||
asm ("addli r0, %1, " TLS_GD_REL "(" #x ")\n\t" \
|
||||
"jal tls_gd_call(" #x ")\n\t" \
|
||||
"addi %0, r0, tls_gd_add(" #x ")" : \
|
||||
"=r" (__retval) : "r" (_GLOBAL_OFFSET_TABLE_) : \
|
||||
"r25", "r26", "r27", "r28", "r29"); \
|
||||
__retval; })
|
||||
|
||||
/* No special support for LD mode. */
|
||||
#define TLS_LD TLS_GD
|
||||
|
||||
#define TLS_IE(x) \
|
||||
({ \
|
||||
int *__retval; \
|
||||
extern char _GLOBAL_OFFSET_TABLE_[]; \
|
||||
\
|
||||
asm ("addli %0, %1, " TLS_IE_REL "(" #x ")\n\t" \
|
||||
LD_TLS " %0, %0, tls_ie_load(" #x ")\n\t" \
|
||||
"add %0, %0, tp" : \
|
||||
"=r" (__retval) : "r" (_GLOBAL_OFFSET_TABLE_)); \
|
||||
__retval; })
|
||||
|
||||
/* No special support for LE mode. */
|
||||
#define TLS_LE TLS_IE
|
24
sysdeps/tile/tst-audit.h
Normal file
24
sysdeps/tile/tst-audit.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 pltenter la_tile_gnu_pltenter
|
||||
#define pltexit la_tile_gnu_pltexit
|
||||
#define La_regs La_tile_regs
|
||||
#define La_retval La_tile_retval
|
||||
#define int_retval lrv_reg[0]
|
15
sysdeps/unix/sysv/linux/tile/Makefile
Normal file
15
sysdeps/unix/sysv/linux/tile/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
ifeq ($(subdir),misc)
|
||||
|
||||
# <sys/reg.h> provides something like x86 compatibility.
|
||||
# New code should probably use <arch/abi.h> instead.
|
||||
sysdep_headers += sys/reg.h
|
||||
|
||||
# MIPS-style cacheflush routine
|
||||
sysdep_headers += sys/cachectl.h
|
||||
sysdep_routines += cacheflush
|
||||
|
||||
# Control dataplane properties of current thread.
|
||||
sysdep_headers += sys/dataplane.h
|
||||
sysdep_routines += set_dataplane
|
||||
|
||||
endif
|
11
sysdeps/unix/sysv/linux/tile/Versions
Normal file
11
sysdeps/unix/sysv/linux/tile/Versions
Normal file
@ -0,0 +1,11 @@
|
||||
libc {
|
||||
GLIBC_2.12 {
|
||||
_flush_cache;
|
||||
cacheflush;
|
||||
fallocate64;
|
||||
set_dataplane;
|
||||
}
|
||||
GLIBC_PRIVATE {
|
||||
__syscall_error;
|
||||
}
|
||||
}
|
101
sysdeps/unix/sysv/linux/tile/bits/environments.h
Normal file
101
sysdeps/unix/sysv/linux/tile/bits/environments.h
Normal file
@ -0,0 +1,101 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _UNISTD_H
|
||||
# error "Never include this file directly. Use <unistd.h> instead"
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
/* This header should define the following symbols under the described
|
||||
situations. A value `1' means that the model is always supported,
|
||||
`-1' means it is never supported. Undefined means it cannot be
|
||||
statically decided.
|
||||
|
||||
_POSIX_V7_ILP32_OFF32 32bit int, long, pointers, and off_t type
|
||||
_POSIX_V7_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type
|
||||
|
||||
_POSIX_V7_LP64_OFF32 64bit long and pointers and 32bit off_t type
|
||||
_POSIX_V7_LPBIG_OFFBIG 64bit long and pointers and large off_t type
|
||||
|
||||
The macros _POSIX_V6_ILP32_OFF32, _POSIX_V6_ILP32_OFFBIG,
|
||||
_POSIX_V6_LP64_OFF32, _POSIX_V6_LPBIG_OFFBIG, _XBS5_ILP32_OFF32,
|
||||
_XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and _XBS5_LPBIG_OFFBIG were
|
||||
used in previous versions of the Unix standard and are available
|
||||
only for compatibility.
|
||||
*/
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
|
||||
/* Environments with 32-bit wide pointers are optionally provided.
|
||||
Therefore following macros aren't defined:
|
||||
# undef _POSIX_V7_ILP32_OFF32
|
||||
# undef _POSIX_V7_ILP32_OFFBIG
|
||||
# undef _POSIX_V6_ILP32_OFF32
|
||||
# undef _POSIX_V6_ILP32_OFFBIG
|
||||
# undef _XBS5_ILP32_OFF32
|
||||
# undef _XBS5_ILP32_OFFBIG
|
||||
and users need to check at runtime. */
|
||||
|
||||
/* We also have no use (for now) for an environment with bigger pointers
|
||||
and offsets. */
|
||||
# define _POSIX_V7_LPBIG_OFFBIG -1
|
||||
# define _POSIX_V6_LPBIG_OFFBIG -1
|
||||
# define _XBS5_LPBIG_OFFBIG -1
|
||||
|
||||
/* By default we have 64-bit wide `long int', pointers and `off_t'. */
|
||||
# define _POSIX_V7_LP64_OFF64 1
|
||||
# define _POSIX_V6_LP64_OFF64 1
|
||||
# define _XBS5_LP64_OFF64 1
|
||||
|
||||
#else /* __WORDSIZE == 32 */
|
||||
|
||||
/* By default we have 32-bit wide `int', `long int', pointers and `off_t'
|
||||
and all platforms support LFS. */
|
||||
# define _POSIX_V7_ILP32_OFF32 1
|
||||
# define _POSIX_V7_ILP32_OFFBIG 1
|
||||
# define _POSIX_V6_ILP32_OFF32 1
|
||||
# define _POSIX_V6_ILP32_OFFBIG 1
|
||||
# define _XBS5_ILP32_OFF32 1
|
||||
# define _XBS5_ILP32_OFFBIG 1
|
||||
|
||||
/* We optionally provide an environment with the above size but an 64-bit
|
||||
side `off_t'. Therefore we don't define _POSIX_V7_ILP32_OFFBIG. */
|
||||
|
||||
/* Environments with 64-bit wide pointers can be provided,
|
||||
so these macros aren't defined:
|
||||
# undef _POSIX_V7_LP64_OFF64
|
||||
# undef _POSIX_V7_LPBIG_OFFBIG
|
||||
# undef _POSIX_V6_LP64_OFF64
|
||||
# undef _POSIX_V6_LPBIG_OFFBIG
|
||||
# undef _XBS5_LP64_OFF64
|
||||
# undef _XBS5_LPBIG_OFFBIG
|
||||
and sysconf tests for it at runtime. */
|
||||
|
||||
#endif /* __WORDSIZE == 32 */
|
||||
|
||||
#ifdef __tilegx__
|
||||
/* Only TILE-Gx has the ability to choose 32- or 64-bit. */
|
||||
#define __ILP32_OFF32_CFLAGS "-m32"
|
||||
#define __ILP32_OFFBIG_CFLAGS "-m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
#define __ILP32_OFF32_LDFLAGS "-m32"
|
||||
#define __ILP32_OFFBIG_LDFLAGS "-m32"
|
||||
#define __LP64_OFF64_CFLAGS "-m64"
|
||||
#define __LP64_OFF64_LDFLAGS "-m64"
|
||||
#endif
|
101
sysdeps/unix/sysv/linux/tile/bits/local_lim.h
Normal file
101
sysdeps/unix/sysv/linux/tile/bits/local_lim.h
Normal file
@ -0,0 +1,101 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
/* The kernel header pollutes the namespace with the NR_OPEN symbol
|
||||
and defines LINK_MAX although filesystems have different maxima. A
|
||||
similar thing is true for OPEN_MAX: the limit can be changed at
|
||||
runtime and therefore the macro must not be defined. Remove this
|
||||
after including the header if necessary. */
|
||||
#ifndef NR_OPEN
|
||||
# define __undef_NR_OPEN
|
||||
#endif
|
||||
#ifndef LINK_MAX
|
||||
# define __undef_LINK_MAX
|
||||
#endif
|
||||
#ifndef OPEN_MAX
|
||||
# define __undef_OPEN_MAX
|
||||
#endif
|
||||
#ifndef ARG_MAX
|
||||
# define __undef_ARG_MAX
|
||||
#endif
|
||||
|
||||
/* The kernel sources contain a file with all the needed information. */
|
||||
#include <linux/limits.h>
|
||||
|
||||
/* Have to remove NR_OPEN? */
|
||||
#ifdef __undef_NR_OPEN
|
||||
# undef NR_OPEN
|
||||
# undef __undef_NR_OPEN
|
||||
#endif
|
||||
/* Have to remove LINK_MAX? */
|
||||
#ifdef __undef_LINK_MAX
|
||||
# undef LINK_MAX
|
||||
# undef __undef_LINK_MAX
|
||||
#endif
|
||||
/* Have to remove OPEN_MAX? */
|
||||
#ifdef __undef_OPEN_MAX
|
||||
# undef OPEN_MAX
|
||||
# undef __undef_OPEN_MAX
|
||||
#endif
|
||||
/* Have to remove ARG_MAX? */
|
||||
#ifdef __undef_ARG_MAX
|
||||
# undef ARG_MAX
|
||||
# undef __undef_ARG_MAX
|
||||
#endif
|
||||
|
||||
/* The number of data keys per process. */
|
||||
#define _POSIX_THREAD_KEYS_MAX 128
|
||||
/* This is the value this implementation supports. */
|
||||
#define PTHREAD_KEYS_MAX 1024
|
||||
|
||||
/* Controlling the iterations of destructors for thread-specific data. */
|
||||
#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
|
||||
/* Number of iterations this implementation does. */
|
||||
#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
|
||||
|
||||
/* The number of threads per process. */
|
||||
#define _POSIX_THREAD_THREADS_MAX 64
|
||||
/* We have no predefined limit on the number of threads. */
|
||||
#undef PTHREAD_THREADS_MAX
|
||||
|
||||
/* Maximum amount by which a process can descrease its asynchronous I/O
|
||||
priority level. */
|
||||
#define AIO_PRIO_DELTA_MAX 20
|
||||
|
||||
/* Minimum size for a thread. At least two pages for systems with 64k
|
||||
pages. */
|
||||
#define PTHREAD_STACK_MIN 131072
|
||||
|
||||
/* Maximum number of timer expiration overruns. */
|
||||
#define DELAYTIMER_MAX 2147483647
|
||||
|
||||
/* Maximum tty name length. */
|
||||
#define TTY_NAME_MAX 32
|
||||
|
||||
/* Maximum login name length. This is arbitrary. */
|
||||
#define LOGIN_NAME_MAX 256
|
||||
|
||||
/* Maximum host name length. */
|
||||
#define HOST_NAME_MAX 64
|
||||
|
||||
/* Maximum message queue priority level. */
|
||||
#define MQ_PRIO_MAX 32768
|
||||
|
||||
/* Maximum value the semaphore can have. */
|
||||
#define SEM_VALUE_MAX (2147483647)
|
110
sysdeps/unix/sysv/linux/tile/bits/mman.h
Normal file
110
sysdeps/unix/sysv/linux/tile/bits/mman.h
Normal file
@ -0,0 +1,110 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _SYS_MMAN_H
|
||||
# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
|
||||
#endif
|
||||
|
||||
/* The following definitions basically come from the kernel headers.
|
||||
But the kernel header is not namespace clean. */
|
||||
|
||||
|
||||
/* Protections are chosen from these bits, OR'd together. The
|
||||
implementation does not necessarily support PROT_EXEC or PROT_WRITE
|
||||
without PROT_READ. The only guarantees are that no writing will be
|
||||
allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
|
||||
|
||||
#define PROT_READ 0x1 /* Page can be read. */
|
||||
#define PROT_WRITE 0x2 /* Page can be written. */
|
||||
#define PROT_EXEC 0x4 /* Page can be executed. */
|
||||
#define PROT_NONE 0x0 /* Page can not be accessed. */
|
||||
#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
|
||||
growsdown vma (mprotect only). */
|
||||
#define PROT_GROWSUP 0x02000000 /* Extend change to start of
|
||||
growsup vma (mprotect only). */
|
||||
|
||||
/* Sharing types (must choose one and only one of these). */
|
||||
#define MAP_SHARED 0x01 /* Share changes. */
|
||||
#define MAP_PRIVATE 0x02 /* Changes are private. */
|
||||
#ifdef __USE_MISC
|
||||
# define MAP_TYPE 0x0f /* Mask for type of mapping. */
|
||||
#endif
|
||||
|
||||
/* Other flags. */
|
||||
#define MAP_FIXED 0x10 /* Interpret addr exactly. */
|
||||
#ifdef __USE_MISC
|
||||
# define MAP_FILE 0
|
||||
# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
|
||||
# define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#ifdef __USE_MISC
|
||||
/* These are Linux-specific. */
|
||||
# define MAP_NONBLOCK 0x00080 /* Do not block on IO. */
|
||||
# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
|
||||
# define MAP_STACK MAP_GROWSDOWN /* Provide convenience alias. */
|
||||
# define MAP_LOCKED 0x00200 /* Lock the mapping. */
|
||||
# define MAP_NORESERVE 0x00400 /* Don't check for reservations. */
|
||||
# define MAP_DENYWRITE 0x00800 /* ETXTBSY */
|
||||
# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */
|
||||
# define MAP_POPULATE 0x00040 /* Populate (prefault) pagetables. */
|
||||
# define MAP_HUGETLB 0x04000 /* Create huge page mapping. */
|
||||
#endif
|
||||
|
||||
/* Flags to `msync'. */
|
||||
#define MS_ASYNC 1 /* Sync memory asynchronously. */
|
||||
#define MS_SYNC 4 /* Synchronous memory sync. */
|
||||
#define MS_INVALIDATE 2 /* Invalidate the caches. */
|
||||
|
||||
/* Flags for `mlockall'. */
|
||||
#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
|
||||
#define MCL_FUTURE 2 /* Lock all additions to address
|
||||
space. */
|
||||
|
||||
/* Flags for `mremap'. */
|
||||
#ifdef __USE_GNU
|
||||
# define MREMAP_MAYMOVE 1
|
||||
# define MREMAP_FIXED 2
|
||||
#endif
|
||||
|
||||
/* Advice to `madvise'. */
|
||||
#ifdef __USE_BSD
|
||||
# define MADV_NORMAL 0 /* No further special treatment. */
|
||||
# define MADV_RANDOM 1 /* Expect random page references. */
|
||||
# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define MADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define MADV_DONTNEED 4 /* Don't need these pages. */
|
||||
# define MADV_REMOVE 9 /* Remove these pages and resources. */
|
||||
# define MADV_DONTFORK 10 /* Do not inherit across fork. */
|
||||
# define MADV_DOFORK 11 /* Do inherit across fork. */
|
||||
# define MADV_MERGEABLE 12 /* KSM may merge identical pages. */
|
||||
# define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages. */
|
||||
# define MADV_HUGEPAGE 14 /* Worth backing with hugepages. */
|
||||
# define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages. */
|
||||
# define MADV_HWPOISON 100 /* Poison a page for testing. */
|
||||
#endif
|
||||
|
||||
/* The POSIX people had to invent similar names for the same things. */
|
||||
#ifdef __USE_XOPEN2K
|
||||
# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
|
||||
# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
|
||||
# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
|
||||
#endif
|
173
sysdeps/unix/sysv/linux/tile/bits/mman.h~
Normal file
173
sysdeps/unix/sysv/linux/tile/bits/mman.h~
Normal file
@ -0,0 +1,173 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _SYS_MMAN_H
|
||||
# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
|
||||
#endif
|
||||
|
||||
/* The following definitions basically come from the kernel headers.
|
||||
But the kernel header is not namespace clean. */
|
||||
|
||||
|
||||
/* Protections are chosen from these bits, OR'd together. The
|
||||
implementation does not necessarily support PROT_EXEC or PROT_WRITE
|
||||
without PROT_READ. The only guarantees are that no writing will be
|
||||
allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
|
||||
|
||||
#define PROT_READ 0x1 /* Page can be read. */
|
||||
#define PROT_WRITE 0x2 /* Page can be written. */
|
||||
#define PROT_EXEC 0x4 /* Page can be executed. */
|
||||
#define PROT_NONE 0x0 /* Page can not be accessed. */
|
||||
#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
|
||||
growsdown vma (mprotect only). */
|
||||
#define PROT_GROWSUP 0x02000000 /* Extend change to start of
|
||||
growsup vma (mprotect only). */
|
||||
|
||||
/* Sharing types (must choose one and only one of these). */
|
||||
#define MAP_SHARED 0x01 /* Share changes. */
|
||||
#define MAP_PRIVATE 0x02 /* Changes are private. */
|
||||
#ifdef __USE_MISC
|
||||
# define MAP_TYPE 0x0f /* Mask for type of mapping. */
|
||||
#endif
|
||||
|
||||
/* Other flags. */
|
||||
#define MAP_FIXED 0x10 /* Interpret addr exactly. */
|
||||
#ifdef __USE_MISC
|
||||
# define MAP_FILE 0
|
||||
# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
|
||||
# define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#ifdef __USE_MISC
|
||||
/* These are Linux-specific. */
|
||||
# define MAP_NONBLOCK 0x00080 /* Do not block on IO. */
|
||||
# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
|
||||
# define MAP_STACK MAP_GROWSDOWN /* Provide convenience alias. */
|
||||
# define MAP_LOCKED 0x00200 /* Lock the mapping. */
|
||||
# define MAP_NORESERVE 0x00400 /* Don't check for reservations. */
|
||||
# define MAP_DENYWRITE 0x00800 /* ETXTBSY */
|
||||
# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */
|
||||
# define MAP_POPULATE 0x00040 /* Populate (prefault) pagetables. */
|
||||
# define MAP_HUGETLB 0x04000 /* Create huge page mapping. */
|
||||
#endif
|
||||
|
||||
/* Specify the "home cache" for the page explicitly. The home cache is
|
||||
the cache of one particular "home" cpu, which is used as a coherence
|
||||
point for normal cached operations. Normally the kernel chooses for
|
||||
you, but you can use the MAP_CACHE_HOME_xxx flags to override.
|
||||
|
||||
User code should not use any symbols with a leading "_" as they are
|
||||
implementation specific and may change from release to release
|
||||
without warning. */
|
||||
|
||||
/* Implementation details; do not use directly. */
|
||||
#define _MAP_CACHE_INCOHERENT 0x40000
|
||||
#define _MAP_CACHE_HOME 0x80000
|
||||
#define _MAP_CACHE_HOME_SHIFT 20
|
||||
#define _MAP_CACHE_HOME_MASK 0x3ff
|
||||
#define _MAP_CACHE_MKHOME(n) \
|
||||
(_MAP_CACHE_HOME | (((n) & _MAP_CACHE_HOME_MASK) << _MAP_CACHE_HOME_SHIFT))
|
||||
|
||||
/* Set the home cache to the specified cpu. */
|
||||
#define MAP_CACHE_HOME(n) _MAP_CACHE_MKHOME(n)
|
||||
|
||||
/* Set the home cache to the current cpu. */
|
||||
#define _MAP_CACHE_HOME_HERE (_MAP_CACHE_HOME_MASK - 0)
|
||||
#define MAP_CACHE_HOME_HERE _MAP_CACHE_MKHOME(_MAP_CACHE_HOME_HERE)
|
||||
|
||||
/* Request no on-chip home, i.e. read from memory. Invalid with PROT_WRITE. */
|
||||
#define _MAP_CACHE_HOME_NONE (_MAP_CACHE_HOME_MASK - 1)
|
||||
#define MAP_CACHE_HOME_NONE _MAP_CACHE_MKHOME(_MAP_CACHE_HOME_NONE)
|
||||
|
||||
/* Request no on-chip home, and allow incoherent PROT_WRITE mappings. */
|
||||
#define MAP_CACHE_INCOHERENT (_MAP_CACHE_INCOHERENT | MAP_CACHE_HOME_NONE)
|
||||
|
||||
/* Force the system to choose a single home cache, on a cpu of its choice. */
|
||||
#define _MAP_CACHE_HOME_SINGLE (_MAP_CACHE_HOME_MASK - 2)
|
||||
#define MAP_CACHE_HOME_SINGLE _MAP_CACHE_MKHOME(_MAP_CACHE_HOME_SINGLE)
|
||||
|
||||
/* Create a mapping that follows the task when it migrates. */
|
||||
#define _MAP_CACHE_HOME_TASK (_MAP_CACHE_HOME_MASK - 3)
|
||||
#define MAP_CACHE_HOME_TASK _MAP_CACHE_MKHOME(_MAP_CACHE_HOME_TASK)
|
||||
|
||||
/* Create a hash-for-home mapping. */
|
||||
#define _MAP_CACHE_HOME_HASH (_MAP_CACHE_HOME_MASK - 4)
|
||||
#define MAP_CACHE_HOME_HASH _MAP_CACHE_MKHOME(_MAP_CACHE_HOME_HASH)
|
||||
|
||||
/* Specify local caching attributes for the mapping. Normally the kernel
|
||||
chooses whether to use the local cache, but these flags can be used
|
||||
to override the kernel. */
|
||||
|
||||
/* Disable use of local L2 (on tile64, true for any writable mapping). */
|
||||
#define MAP_CACHE_NO_L2 0x20000
|
||||
|
||||
/* Disable use of local L1 (on tile64, ignored; L1 is disabled with L2). */
|
||||
#define MAP_CACHE_NO_L1 0x08000
|
||||
|
||||
/* Convenience alias that should be used for forward compatibility. */
|
||||
#define MAP_CACHE_NO_LOCAL (MAP_CACHE_NO_L1 | MAP_CACHE_NO_L2)
|
||||
|
||||
/* Convenience alias for direct-to-RAM mappings. */
|
||||
#define MAP_CACHE_NONE (MAP_CACHE_HOME_NONE | MAP_CACHE_NO_LOCAL)
|
||||
|
||||
/* Arrange for this mapping to take priority in the cache. */
|
||||
#define MAP_CACHE_PRIORITY 0x02000
|
||||
|
||||
/* Environment variable that controls hash-for-home in user programs. */
|
||||
#define MAP_CACHE_HASH_ENV_VAR "LD_CACHE_HASH"
|
||||
|
||||
/* Flags to `msync'. */
|
||||
#define MS_ASYNC 1 /* Sync memory asynchronously. */
|
||||
#define MS_SYNC 4 /* Synchronous memory sync. */
|
||||
#define MS_INVALIDATE 2 /* Invalidate the caches. */
|
||||
|
||||
/* Flags for `mlockall'. */
|
||||
#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
|
||||
#define MCL_FUTURE 2 /* Lock all additions to address
|
||||
space. */
|
||||
|
||||
/* Flags for `mremap'. */
|
||||
#ifdef __USE_GNU
|
||||
# define MREMAP_MAYMOVE 1
|
||||
# define MREMAP_FIXED 2
|
||||
#endif
|
||||
|
||||
/* Advice to `madvise'. */
|
||||
#ifdef __USE_BSD
|
||||
# define MADV_NORMAL 0 /* No further special treatment. */
|
||||
# define MADV_RANDOM 1 /* Expect random page references. */
|
||||
# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define MADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define MADV_DONTNEED 4 /* Don't need these pages. */
|
||||
# define MADV_REMOVE 9 /* Remove these pages and resources. */
|
||||
# define MADV_DONTFORK 10 /* Do not inherit across fork. */
|
||||
# define MADV_DOFORK 11 /* Do inherit across fork. */
|
||||
# define MADV_MERGEABLE 12 /* KSM may merge identical pages. */
|
||||
# define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages. */
|
||||
# define MADV_HWPOISON 100 /* Poison a page for testing. */
|
||||
#endif
|
||||
|
||||
/* The POSIX people had to invent similar names for the same things. */
|
||||
#ifdef __USE_XOPEN2K
|
||||
# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
|
||||
# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
|
||||
# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
|
||||
#endif
|
78
sysdeps/unix/sysv/linux/tile/bits/sigaction.h
Normal file
78
sysdeps/unix/sysv/linux/tile/bits/sigaction.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _SIGNAL_H
|
||||
# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
|
||||
#endif
|
||||
|
||||
/* Structure describing the action to be taken when a signal arrives. */
|
||||
struct sigaction
|
||||
{
|
||||
/* Signal handler. */
|
||||
#ifdef __USE_POSIX199309
|
||||
union
|
||||
{
|
||||
/* Used if SA_SIGINFO is not set. */
|
||||
__sighandler_t sa_handler;
|
||||
/* Used if SA_SIGINFO is set. */
|
||||
void (*sa_sigaction) (int, siginfo_t *, void *);
|
||||
}
|
||||
__sigaction_handler;
|
||||
# define sa_handler __sigaction_handler.sa_handler
|
||||
# define sa_sigaction __sigaction_handler.sa_sigaction
|
||||
#else
|
||||
__sighandler_t sa_handler;
|
||||
#endif
|
||||
|
||||
/* Additional set of signals to be blocked. */
|
||||
__sigset_t sa_mask;
|
||||
|
||||
/* Special flags. */
|
||||
int sa_flags;
|
||||
|
||||
/* Restore handler. */
|
||||
void (*sa_restorer) (void);
|
||||
};
|
||||
|
||||
/* Bits in `sa_flags'. */
|
||||
#define SA_NOCLDSTOP 1 /* Don't send SIGCHLD when children stop. */
|
||||
#define SA_NOCLDWAIT 2 /* Don't create zombie on child death. */
|
||||
#define SA_SIGINFO 4 /* Invoke signal-catching function with
|
||||
three arguments instead of one. */
|
||||
#if defined __USE_UNIX98 || defined __USE_MISC
|
||||
# define SA_NOPTRACE 0x02000000 /* Don't ptrace this signal. */
|
||||
# define SA_ONSTACK 0x08000000 /* Use signal stack by using `sa_restorer'. */
|
||||
# define SA_RESTART 0x10000000 /* Restart syscall on signal return. */
|
||||
# define SA_NODEFER 0x40000000 /* Don't automatically block the signal when
|
||||
its handler is being executed. */
|
||||
# define SA_RESETHAND 0x80000000 /* Reset to SIG_DFL on entry to handler. */
|
||||
#endif
|
||||
#ifdef __USE_MISC
|
||||
# define SA_INTERRUPT 0x20000000 /* Historical no-op. */
|
||||
|
||||
/* Some aliases for the SA_ constants. */
|
||||
# define SA_NOMASK SA_NODEFER
|
||||
# define SA_ONESHOT SA_RESETHAND
|
||||
# define SA_STACK SA_ONSTACK
|
||||
#endif
|
||||
|
||||
/* Values for the HOW argument to `sigprocmask'. */
|
||||
#define SIG_BLOCK 0 /* Block signals. */
|
||||
#define SIG_UNBLOCK 1 /* Unblock signals. */
|
||||
#define SIG_SETMASK 2 /* Set the set of blocked signals. */
|
319
sysdeps/unix/sysv/linux/tile/bits/siginfo.h
Normal file
319
sysdeps/unix/sysv/linux/tile/bits/siginfo.h
Normal file
@ -0,0 +1,319 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t \
|
||||
&& !defined __need_sigevent_t
|
||||
# error "Never include this file directly. Use <signal.h> instead"
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#if (!defined __have_sigval_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t \
|
||||
|| defined __need_sigevent_t))
|
||||
# define __have_sigval_t 1
|
||||
|
||||
/* Type for data associated with a signal. */
|
||||
typedef union sigval
|
||||
{
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
} sigval_t;
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
|
||||
# define __SI_MAX_SIZE 128
|
||||
# if __WORDSIZE == 64
|
||||
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
|
||||
# else
|
||||
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
|
||||
# endif
|
||||
|
||||
typedef struct siginfo
|
||||
{
|
||||
int si_signo; /* Signal number. */
|
||||
int si_errno; /* If non-zero, an errno value associated with
|
||||
this signal, as defined in <errno.h>. */
|
||||
int si_code; /* Signal code. */
|
||||
|
||||
union
|
||||
{
|
||||
int _pad[__SI_PAD_SIZE];
|
||||
|
||||
/* kill(). */
|
||||
struct
|
||||
{
|
||||
__pid_t si_pid; /* Sending process ID. */
|
||||
__uid_t si_uid; /* Real user ID of sending process. */
|
||||
} _kill;
|
||||
|
||||
/* POSIX.1b timers. */
|
||||
struct
|
||||
{
|
||||
int si_tid; /* Timer ID. */
|
||||
int si_overrun; /* Overrun count. */
|
||||
sigval_t si_sigval; /* Signal value. */
|
||||
} _timer;
|
||||
|
||||
/* POSIX.1b signals. */
|
||||
struct
|
||||
{
|
||||
__pid_t si_pid; /* Sending process ID. */
|
||||
__uid_t si_uid; /* Real user ID of sending process. */
|
||||
sigval_t si_sigval; /* Signal value. */
|
||||
} _rt;
|
||||
|
||||
/* SIGCHLD. */
|
||||
struct
|
||||
{
|
||||
__pid_t si_pid; /* Which child. */
|
||||
__uid_t si_uid; /* Real user ID of sending process. */
|
||||
int si_status; /* Exit value or signal. */
|
||||
__clock_t si_utime;
|
||||
__clock_t si_stime;
|
||||
} _sigchld;
|
||||
|
||||
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
|
||||
struct
|
||||
{
|
||||
void *si_addr; /* Faulting insn/memory ref. */
|
||||
int si_trapno; /* TRAP # which caused the signal */
|
||||
} _sigfault;
|
||||
|
||||
/* SIGPOLL. */
|
||||
struct
|
||||
{
|
||||
long int si_band; /* Band event for SIGPOLL. */
|
||||
int si_fd;
|
||||
} _sigpoll;
|
||||
} _sifields;
|
||||
} siginfo_t;
|
||||
|
||||
|
||||
/* X/Open requires some more fields with fixed names. */
|
||||
# define si_pid _sifields._kill.si_pid
|
||||
# define si_uid _sifields._kill.si_uid
|
||||
# define si_timerid _sifields._timer.si_tid
|
||||
# define si_overrun _sifields._timer.si_overrun
|
||||
# define si_status _sifields._sigchld.si_status
|
||||
# define si_utime _sifields._sigchld.si_utime
|
||||
# define si_stime _sifields._sigchld.si_stime
|
||||
# define si_value _sifields._rt.si_sigval
|
||||
# define si_int _sifields._rt.si_sigval.sival_int
|
||||
# define si_ptr _sifields._rt.si_sigval.sival_ptr
|
||||
# define si_addr _sifields._sigfault.si_addr
|
||||
# define si_trapno _sifields._sigfault.si_trapno
|
||||
# define si_band _sifields._sigpoll.si_band
|
||||
# define si_fd _sifields._sigpoll.si_fd
|
||||
|
||||
|
||||
/* Values for `si_code'. Positive values are reserved for kernel-generated
|
||||
signals. */
|
||||
enum
|
||||
{
|
||||
SI_ASYNCNL = -60, /* Sent by asynch name lookup completion. */
|
||||
# define SI_ASYNCNL SI_ASYNCNL
|
||||
SI_TKILL = -6, /* Sent by tkill. */
|
||||
# define SI_TKILL SI_TKILL
|
||||
SI_SIGIO, /* Sent by queued SIGIO. */
|
||||
# define SI_SIGIO SI_SIGIO
|
||||
SI_ASYNCIO, /* Sent by AIO completion. */
|
||||
# define SI_ASYNCIO SI_ASYNCIO
|
||||
SI_MESGQ, /* Sent by real time mesq state change. */
|
||||
# define SI_MESGQ SI_MESGQ
|
||||
SI_TIMER, /* Sent by timer expiration. */
|
||||
# define SI_TIMER SI_TIMER
|
||||
SI_QUEUE, /* Sent by sigqueue. */
|
||||
# define SI_QUEUE SI_QUEUE
|
||||
SI_USER, /* Sent by kill, sigsend, raise. */
|
||||
# define SI_USER SI_USER
|
||||
SI_KERNEL = 0x80 /* Send by kernel. */
|
||||
#define SI_KERNEL SI_KERNEL
|
||||
};
|
||||
|
||||
|
||||
/* `si_code' values for SIGILL signal. */
|
||||
enum
|
||||
{
|
||||
ILL_ILLOPC = 1, /* Illegal opcode. */
|
||||
# define ILL_ILLOPC ILL_ILLOPC
|
||||
ILL_ILLOPN, /* Illegal operand. */
|
||||
# define ILL_ILLOPN ILL_ILLOPN
|
||||
ILL_ILLADR, /* Illegal addressing mode. */
|
||||
# define ILL_ILLADR ILL_ILLADR
|
||||
ILL_ILLTRP, /* Illegal trap. */
|
||||
# define ILL_ILLTRP ILL_ILLTRP
|
||||
ILL_PRVOPC, /* Privileged opcode. */
|
||||
# define ILL_PRVOPC ILL_PRVOPC
|
||||
ILL_PRVREG, /* Privileged register. */
|
||||
# define ILL_PRVREG ILL_PRVREG
|
||||
ILL_COPROC, /* Coprocessor error. */
|
||||
# define ILL_COPROC ILL_COPROC
|
||||
ILL_BADSTK, /* Internal stack error. */
|
||||
# define ILL_BADSTK ILL_BADSTK
|
||||
ILL_DBLFLT, /* Double fault. */
|
||||
# define ILL_DBLFLT ILL_DBLFLT
|
||||
ILL_HARDWALL /* User networks hardwall violation. */
|
||||
# define ILL_HARDWALL ILL_HARDWALL
|
||||
};
|
||||
|
||||
/* `si_code' values for SIGFPE signal. */
|
||||
enum
|
||||
{
|
||||
FPE_INTDIV = 1, /* Integer divide by zero. */
|
||||
# define FPE_INTDIV FPE_INTDIV
|
||||
FPE_INTOVF, /* Integer overflow. */
|
||||
# define FPE_INTOVF FPE_INTOVF
|
||||
FPE_FLTDIV, /* Floating point divide by zero. */
|
||||
# define FPE_FLTDIV FPE_FLTDIV
|
||||
FPE_FLTOVF, /* Floating point overflow. */
|
||||
# define FPE_FLTOVF FPE_FLTOVF
|
||||
FPE_FLTUND, /* Floating point underflow. */
|
||||
# define FPE_FLTUND FPE_FLTUND
|
||||
FPE_FLTRES, /* Floating point inexact result. */
|
||||
# define FPE_FLTRES FPE_FLTRES
|
||||
FPE_FLTINV, /* Floating point invalid operation. */
|
||||
# define FPE_FLTINV FPE_FLTINV
|
||||
FPE_FLTSUB /* Subscript out of range. */
|
||||
# define FPE_FLTSUB FPE_FLTSUB
|
||||
};
|
||||
|
||||
/* `si_code' values for SIGSEGV signal. */
|
||||
enum
|
||||
{
|
||||
SEGV_MAPERR = 1, /* Address not mapped to object. */
|
||||
# define SEGV_MAPERR SEGV_MAPERR
|
||||
SEGV_ACCERR /* Invalid permissions for mapped object. */
|
||||
# define SEGV_ACCERR SEGV_ACCERR
|
||||
};
|
||||
|
||||
/* `si_code' values for SIGBUS signal. */
|
||||
enum
|
||||
{
|
||||
BUS_ADRALN = 1, /* Invalid address alignment. */
|
||||
# define BUS_ADRALN BUS_ADRALN
|
||||
BUS_ADRERR, /* Non-existant physical address. */
|
||||
# define BUS_ADRERR BUS_ADRERR
|
||||
BUS_OBJERR /* Object specific hardware error. */
|
||||
# define BUS_OBJERR BUS_OBJERR
|
||||
};
|
||||
|
||||
/* `si_code' values for SIGTRAP signal. */
|
||||
enum
|
||||
{
|
||||
TRAP_BRKPT = 1, /* Process breakpoint. */
|
||||
# define TRAP_BRKPT TRAP_BRKPT
|
||||
TRAP_TRACE /* Process trace trap. */
|
||||
# define TRAP_TRACE TRAP_TRACE
|
||||
};
|
||||
|
||||
/* `si_code' values for SIGCHLD signal. */
|
||||
enum
|
||||
{
|
||||
CLD_EXITED = 1, /* Child has exited. */
|
||||
# define CLD_EXITED CLD_EXITED
|
||||
CLD_KILLED, /* Child was killed. */
|
||||
# define CLD_KILLED CLD_KILLED
|
||||
CLD_DUMPED, /* Child terminated abnormally. */
|
||||
# define CLD_DUMPED CLD_DUMPED
|
||||
CLD_TRAPPED, /* Traced child has trapped. */
|
||||
# define CLD_TRAPPED CLD_TRAPPED
|
||||
CLD_STOPPED, /* Child has stopped. */
|
||||
# define CLD_STOPPED CLD_STOPPED
|
||||
CLD_CONTINUED /* Stopped child has continued. */
|
||||
# define CLD_CONTINUED CLD_CONTINUED
|
||||
};
|
||||
|
||||
/* `si_code' values for SIGPOLL signal. */
|
||||
enum
|
||||
{
|
||||
POLL_IN = 1, /* Data input available. */
|
||||
# define POLL_IN POLL_IN
|
||||
POLL_OUT, /* Output buffers available. */
|
||||
# define POLL_OUT POLL_OUT
|
||||
POLL_MSG, /* Input message available. */
|
||||
# define POLL_MSG POLL_MSG
|
||||
POLL_ERR, /* I/O error. */
|
||||
# define POLL_ERR POLL_ERR
|
||||
POLL_PRI, /* High priority input available. */
|
||||
# define POLL_PRI POLL_PRI
|
||||
POLL_HUP /* Device disconnected. */
|
||||
# define POLL_HUP POLL_HUP
|
||||
};
|
||||
|
||||
# undef __need_siginfo_t
|
||||
#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
|
||||
|
||||
|
||||
#if (defined _SIGNAL_H || defined __need_sigevent_t) \
|
||||
&& !defined __have_sigevent_t
|
||||
# define __have_sigevent_t 1
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
# define __SIGEV_MAX_SIZE 64
|
||||
# if __WORDSIZE == 64
|
||||
# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
|
||||
# else
|
||||
# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 3)
|
||||
# endif
|
||||
|
||||
typedef struct sigevent
|
||||
{
|
||||
sigval_t sigev_value;
|
||||
int sigev_signo;
|
||||
int sigev_notify;
|
||||
|
||||
union
|
||||
{
|
||||
int _pad[__SIGEV_PAD_SIZE];
|
||||
|
||||
/* When SIGEV_SIGNAL and SIGEV_THREAD_ID set, LWP ID of the
|
||||
thread to receive the signal. */
|
||||
__pid_t _tid;
|
||||
|
||||
struct
|
||||
{
|
||||
void (*_function) (sigval_t); /* Function to start. */
|
||||
void *_attribute; /* Really pthread_attr_t. */
|
||||
} _sigev_thread;
|
||||
} _sigev_un;
|
||||
} sigevent_t;
|
||||
|
||||
/* POSIX names to access some of the members. */
|
||||
# define sigev_notify_function _sigev_un._sigev_thread._function
|
||||
# define sigev_notify_attributes _sigev_un._sigev_thread._attribute
|
||||
|
||||
/* `sigev_notify' values. */
|
||||
enum
|
||||
{
|
||||
SIGEV_SIGNAL = 0, /* Notify via signal. */
|
||||
# define SIGEV_SIGNAL SIGEV_SIGNAL
|
||||
SIGEV_NONE, /* Other notification: meaningless. */
|
||||
# define SIGEV_NONE SIGEV_NONE
|
||||
SIGEV_THREAD, /* Deliver via thread creation. */
|
||||
# define SIGEV_THREAD SIGEV_THREAD
|
||||
|
||||
SIGEV_THREAD_ID = 4 /* Send signal to specific thread. */
|
||||
#define SIGEV_THREAD_ID SIGEV_THREAD_ID
|
||||
};
|
||||
|
||||
#endif /* have _SIGNAL_H. */
|
35
sysdeps/unix/sysv/linux/tile/cacheflush.c
Normal file
35
sysdeps/unix/sysv/linux/tile/cacheflush.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Flush cache(s). */
|
||||
int
|
||||
_flush_cache (char *addr, const int nbytes, const int op)
|
||||
{
|
||||
#ifdef __NR_cacheflush
|
||||
return INLINE_SYSCALL (cacheflush, 3, addr, nbytes, op);
|
||||
#else
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
weak_alias (_flush_cache, cacheflush)
|
4
sysdeps/unix/sysv/linux/tile/configure
vendored
Normal file
4
sysdeps/unix/sysv/linux/tile/configure
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
|
||||
# Local configure fragment for sysdeps/unix/sysv/linux/tile.
|
||||
|
||||
arch_minimum_kernel=2.6.32
|
4
sysdeps/unix/sysv/linux/tile/configure.in
Normal file
4
sysdeps/unix/sysv/linux/tile/configure.in
Normal file
@ -0,0 +1,4 @@
|
||||
GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
|
||||
# Local configure fragment for sysdeps/unix/sysv/linux/tile.
|
||||
|
||||
arch_minimum_kernel=2.6.32
|
96
sysdeps/unix/sysv/linux/tile/getcontext.S
Normal file
96
sysdeps/unix/sysv/linux/tile/getcontext.S
Normal file
@ -0,0 +1,96 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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>
|
||||
#include <arch/abi.h>
|
||||
|
||||
#include "ucontext_i.h"
|
||||
|
||||
/* int getcontext (ucontext_t *ucp) */
|
||||
|
||||
.text
|
||||
ENTRY (__getcontext)
|
||||
FEEDBACK_ENTER(__getcontext)
|
||||
|
||||
/* Save the callee-saved GPRs. There's no need to save the
|
||||
caller-saved GPRs since the eventual setcontext() or
|
||||
swapcontext() will assume those registers are all dead.
|
||||
Save value "1" to uc_flags to later recognize getcontext(). */
|
||||
{ movei r11, 1; ADDI_PTR r10, r0, UC_FLAGS_OFFSET }
|
||||
{ ST r10, r11; addli r10, r0, UC_REG(30) }
|
||||
{ ST r10, r30; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r31; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r32; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r33; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r34; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r35; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r36; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r37; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r38; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r39; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r40; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r41; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r42; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r43; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r44; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r45; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r46; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r47; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r48; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r49; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r50; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r51; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, r52; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, tp; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, sp; ADDI_PTR r10, r10, REGSIZE }
|
||||
{ ST r10, lr; ADDI_PTR r10, r10, REGSIZE }
|
||||
lnk r11 /* Point PC at the "jrp lr" instruction. */
|
||||
addli r11, r11, .Lreturn - .
|
||||
{ ST r10, r11; ADDI_PTR r10, r10, REGSIZE }
|
||||
mfspr r11, INTERRUPT_CRITICAL_SECTION
|
||||
{
|
||||
ST r10, r11
|
||||
movei r1, 0
|
||||
}
|
||||
|
||||
/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG / 8) */
|
||||
{
|
||||
movei r3, _NSIG / 8
|
||||
addli r2, r0, UC_SIGMASK_OFFSET
|
||||
}
|
||||
{
|
||||
movei r0, SIG_BLOCK
|
||||
moveli TREG_SYSCALL_NR_NAME, __NR_rt_sigprocmask
|
||||
}
|
||||
swint1
|
||||
BNEZ r1, .Lsyscall_error
|
||||
|
||||
.Lreturn:
|
||||
{
|
||||
movei r0, 0
|
||||
jrp lr
|
||||
}
|
||||
|
||||
.Lsyscall_error:
|
||||
j SYSCALL_ERROR_NAME
|
||||
|
||||
END (__getcontext)
|
||||
.hidden __getcontext
|
||||
|
||||
weak_alias (__getcontext, getcontext)
|
44
sysdeps/unix/sysv/linux/tile/kernel-features.h
Normal file
44
sysdeps/unix/sysv/linux/tile/kernel-features.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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. */
|
||||
|
||||
|
||||
/* TILE glibc support starts with 2.6.36, guaranteeing many kernel features. */
|
||||
#define __ASSUME_NEW_GETRLIMIT_SYSCALL 1
|
||||
#define __ASSUME_TRUNCATE64_SYSCALL 1
|
||||
#define __ASSUME_MMAP2_SYSCALL 1
|
||||
#define __ASSUME_STAT64_SYSCALL 1
|
||||
#define __ASSUME_FCNTL64 1
|
||||
#define __ASSUME_CLONE_THREAD_FLAGS 1
|
||||
#define __ASSUME_TGKILL 1
|
||||
#define __ASSUME_UTIMES 1
|
||||
#define __ASSUME_FADVISE64_64_SYSCALL 1
|
||||
#define __ASSUME_O_CLOEXEC 1
|
||||
#define __ASSUME_SOCK_CLOEXEC 1
|
||||
#define __ASSUME_IN_NONBLOCK 1
|
||||
#define __ASSUME_PIPE2 1
|
||||
#define __ASSUME_EVENTFD2 1
|
||||
#define __ASSUME_SIGNALFD4 1
|
||||
#define __ASSUME_ACCEPT4 1
|
||||
#define __ASSUME_DUP3 1
|
||||
|
||||
#include_next <kernel-features.h>
|
||||
|
||||
/* Define this if your 32-bit syscall API requires 64-bit register
|
||||
pairs to start with an even-number register. */
|
||||
#define __ASSUME_ALIGNED_REGISTER_PAIRS 1
|
68
sysdeps/unix/sysv/linux/tile/makecontext.c
Normal file
68
sysdeps/unix/sysv/linux/tile/makecontext.c
Normal file
@ -0,0 +1,68 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <ucontext.h>
|
||||
#include <arch/abi.h>
|
||||
|
||||
void
|
||||
__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
|
||||
{
|
||||
extern void __startcontext (void);
|
||||
uint_reg_t *sp, *args;
|
||||
va_list ap;
|
||||
int i;
|
||||
|
||||
/* Initialize the top of stack. */
|
||||
sp = (uint_reg_t *) ((((intptr_t) ucp->uc_stack.ss_sp
|
||||
+ ucp->uc_stack.ss_size) & -16L) - 16);
|
||||
|
||||
/* Allow room for memory-passed arguments if necessary. */
|
||||
if (argc > 10)
|
||||
sp -= 2 + (argc - 10);
|
||||
|
||||
sp[0] = sp[1] = 0;
|
||||
|
||||
/* Set parameters. */
|
||||
va_start (ap, argc);
|
||||
args = &ucp->uc_mcontext.gregs[0];
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (i == 10)
|
||||
args = &sp[2];
|
||||
*args++ = va_arg (ap, long);
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
/* Pass (*func) to __startcontext in pc. */
|
||||
ucp->uc_mcontext.pc = (long) func;
|
||||
|
||||
/* Set stack pointer. */
|
||||
ucp->uc_mcontext.sp = (long) sp;
|
||||
|
||||
/* Set the return address to trampoline. */
|
||||
ucp->uc_mcontext.lr = (long) __startcontext;
|
||||
|
||||
/* Pass ucp->uc_link to __start_context in r30. */
|
||||
ucp->uc_mcontext.gregs[30] = (long) ucp->uc_link;
|
||||
}
|
||||
weak_alias (__makecontext, makecontext)
|
7
sysdeps/unix/sysv/linux/tile/nptl/Makefile
Normal file
7
sysdeps/unix/sysv/linux/tile/nptl/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# pull in __syscall_error routine
|
||||
libpthread-routines += sysdep
|
||||
|
||||
ifeq ($(subdir),nptl)
|
||||
# Avoid .cfi_startproc/endproc markers when creating init and fini pieces.
|
||||
CFLAGS-pt-initfini.s += -fno-asynchronous-unwind-tables
|
||||
endif
|
221
sysdeps/unix/sysv/linux/tile/nptl/bits/pthreadtypes.h
Normal file
221
sysdeps/unix/sysv/linux/tile/nptl/bits/pthreadtypes.h
Normal file
@ -0,0 +1,221 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Based on work contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
|
||||
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 _BITS_PTHREADTYPES_H
|
||||
#define _BITS_PTHREADTYPES_H 1
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
# define __SIZEOF_PTHREAD_ATTR_T 56
|
||||
# define __SIZEOF_PTHREAD_MUTEX_T 40
|
||||
# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
|
||||
# define __SIZEOF_PTHREAD_COND_T 48
|
||||
# define __SIZEOF_PTHREAD_CONDATTR_T 4
|
||||
# define __SIZEOF_PTHREAD_RWLOCK_T 56
|
||||
# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
|
||||
# define __SIZEOF_PTHREAD_BARRIER_T 32
|
||||
# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
|
||||
#else
|
||||
# define __SIZEOF_PTHREAD_ATTR_T 36
|
||||
# define __SIZEOF_PTHREAD_MUTEX_T 24
|
||||
# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
|
||||
# define __SIZEOF_PTHREAD_COND_T 48
|
||||
# define __SIZEOF_PTHREAD_CONDATTR_T 4
|
||||
# define __SIZEOF_PTHREAD_RWLOCK_T 32
|
||||
# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
|
||||
# define __SIZEOF_PTHREAD_BARRIER_T 20
|
||||
# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
|
||||
#endif
|
||||
|
||||
|
||||
/* Thread identifiers. The structure of the attribute type is not
|
||||
exposed on purpose. */
|
||||
typedef unsigned long int pthread_t;
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
char __size[__SIZEOF_PTHREAD_ATTR_T];
|
||||
long int __align;
|
||||
} pthread_attr_t;
|
||||
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
typedef struct __pthread_internal_list
|
||||
{
|
||||
struct __pthread_internal_list *__prev;
|
||||
struct __pthread_internal_list *__next;
|
||||
} __pthread_list_t;
|
||||
#else
|
||||
typedef struct __pthread_internal_slist
|
||||
{
|
||||
struct __pthread_internal_slist *__next;
|
||||
} __pthread_slist_t;
|
||||
#endif
|
||||
|
||||
|
||||
/* Data structures for mutex handling. The structure of the attribute
|
||||
type is not exposed on purpose. */
|
||||
typedef union
|
||||
{
|
||||
struct __pthread_mutex_s
|
||||
{
|
||||
int __lock;
|
||||
unsigned int __count;
|
||||
int __owner;
|
||||
#if __WORDSIZE == 64
|
||||
unsigned int __nusers;
|
||||
#endif
|
||||
/* KIND must stay at this position in the structure to maintain
|
||||
binary compatibility. */
|
||||
int __kind;
|
||||
#if __WORDSIZE == 64
|
||||
int __spins;
|
||||
__pthread_list_t __list;
|
||||
# define __PTHREAD_MUTEX_HAVE_PREV 1
|
||||
#else
|
||||
unsigned int __nusers;
|
||||
__extension__ union
|
||||
{
|
||||
int __spins;
|
||||
__pthread_slist_t __list;
|
||||
};
|
||||
#endif
|
||||
} __data;
|
||||
char __size[__SIZEOF_PTHREAD_MUTEX_T];
|
||||
long int __align;
|
||||
} pthread_mutex_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
|
||||
int __align;
|
||||
} pthread_mutexattr_t;
|
||||
|
||||
|
||||
/* Data structure for conditional variable handling. The structure of
|
||||
the attribute type is not exposed on purpose. */
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
int __lock;
|
||||
unsigned int __futex;
|
||||
__extension__ unsigned long long int __total_seq;
|
||||
__extension__ unsigned long long int __wakeup_seq;
|
||||
__extension__ unsigned long long int __woken_seq;
|
||||
void *__mutex;
|
||||
unsigned int __nwaiters;
|
||||
unsigned int __broadcast_seq;
|
||||
} __data;
|
||||
char __size[__SIZEOF_PTHREAD_COND_T];
|
||||
__extension__ long long int __align;
|
||||
} pthread_cond_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
char __size[__SIZEOF_PTHREAD_CONDATTR_T];
|
||||
int __align;
|
||||
} pthread_condattr_t;
|
||||
|
||||
|
||||
/* Keys for thread-specific data */
|
||||
typedef unsigned int pthread_key_t;
|
||||
|
||||
|
||||
/* Once-only execution */
|
||||
typedef int pthread_once_t;
|
||||
|
||||
|
||||
#if defined __USE_UNIX98 || defined __USE_XOPEN2K
|
||||
/* Data structure for read-write lock variable handling. The
|
||||
structure of the attribute type is not exposed on purpose. */
|
||||
typedef union
|
||||
{
|
||||
# if __WORDSIZE == 64
|
||||
struct
|
||||
{
|
||||
int __lock;
|
||||
unsigned int __nr_readers;
|
||||
unsigned int __readers_wakeup;
|
||||
unsigned int __writer_wakeup;
|
||||
unsigned int __nr_readers_queued;
|
||||
unsigned int __nr_writers_queued;
|
||||
int __writer;
|
||||
int __shared;
|
||||
unsigned long int __pad1;
|
||||
unsigned long int __pad2;
|
||||
/* FLAGS must stay at this position in the structure to maintain
|
||||
binary compatibility. */
|
||||
unsigned int __flags;
|
||||
} __data;
|
||||
# else
|
||||
struct
|
||||
{
|
||||
int __lock;
|
||||
unsigned int __nr_readers;
|
||||
unsigned int __readers_wakeup;
|
||||
unsigned int __writer_wakeup;
|
||||
unsigned int __nr_readers_queued;
|
||||
unsigned int __nr_writers_queued;
|
||||
/* FLAGS must stay at this position in the structure to maintain
|
||||
binary compatibility. */
|
||||
unsigned char __flags;
|
||||
unsigned char __shared;
|
||||
unsigned char __pad1;
|
||||
unsigned char __pad2;
|
||||
int __writer;
|
||||
} __data;
|
||||
# endif
|
||||
char __size[__SIZEOF_PTHREAD_RWLOCK_T];
|
||||
long int __align;
|
||||
} pthread_rwlock_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
|
||||
long int __align;
|
||||
} pthread_rwlockattr_t;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __USE_XOPEN2K
|
||||
/* POSIX spinlock data type. */
|
||||
typedef volatile int pthread_spinlock_t;
|
||||
|
||||
|
||||
/* POSIX barriers data type. The structure of the type is
|
||||
deliberately not exposed. */
|
||||
typedef union
|
||||
{
|
||||
char __size[__SIZEOF_PTHREAD_BARRIER_T];
|
||||
long int __align;
|
||||
} pthread_barrier_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
|
||||
int __align;
|
||||
} pthread_barrierattr_t;
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* bits/pthreadtypes.h */
|
42
sysdeps/unix/sysv/linux/tile/nptl/bits/semaphore.h
Normal file
42
sysdeps/unix/sysv/linux/tile/nptl/bits/semaphore.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
Based on work contributed by Ulrich Drepper <drepper@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. */
|
||||
|
||||
#ifndef _SEMAPHORE_H
|
||||
# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
# define __SIZEOF_SEM_T 32
|
||||
#else
|
||||
# define __SIZEOF_SEM_T 16
|
||||
#endif
|
||||
|
||||
|
||||
/* Value returned if `sem_open' failed. */
|
||||
#define SEM_FAILED ((sem_t *) 0)
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
char __size[__SIZEOF_SEM_T];
|
||||
long int __align;
|
||||
} sem_t;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user