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:
Chris Metcalf 2011-12-03 21:14:25 -05:00
parent a63c7fa185
commit 63d143a25d
133 changed files with 9310 additions and 0 deletions

134
ChangeLog.tile Normal file
View 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.

View 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
View File

@ -0,0 +1,2 @@
ieee754/dbl-64
ieee754/flt-32

18
sysdeps/tile/Makefile Normal file
View 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
View File

@ -0,0 +1,6 @@
libc {
GLIBC_2.12 {
# name requested by gcc community.
__mcount;
}
}

58
sysdeps/tile/__longjmp.S Normal file
View 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)

View 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
View 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 */

View 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
View File

@ -0,0 +1 @@
#include <sysdeps/ia64/backtrace.c>

View 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")));

View 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 */

View 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
View 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
View 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

View 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 */

View 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

View 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 */

View File

@ -0,0 +1 @@
/* _setjmp is in setjmp.S */

View File

@ -0,0 +1 @@
/* setjmp is in setjmp.S */

31
sysdeps/tile/bzero.S Normal file
View 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)

View 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
View 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
View 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
View 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
View 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
View 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)

View 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
View 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
View 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
View 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;
}

View 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
View 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
View 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)

View 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
View 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
View File

@ -0,0 +1 @@
/* This function is defined in ffs.c. */

22
sysdeps/tile/gccframe.h Normal file
View 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>

View 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]))

View 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
View 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

View 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

View 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

View 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;
}

View 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;
}

View 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))

View 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
View 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
View 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
View 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
View 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
View 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)

View 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
View 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
View 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__ */

View 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 */

View 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

View 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)

View 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)

View 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)

View 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>

View 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)

View 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)

View 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)

View 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

View 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)

View 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)

View File

@ -0,0 +1,3 @@
tile/tilegx
tile
wordsize-32

View File

@ -0,0 +1,3 @@
tile/tilegx
tile
wordsize-64

View File

@ -0,0 +1,2 @@
tile
wordsize-32

View 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 */

View File

@ -0,0 +1,3 @@
/* Determine the wordsize from the preprocessor defines. */
#define __WORDSIZE 32

View 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)

View 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)

View 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)

View 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>

View 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)

View 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)

View 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)

View 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)

View 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
View 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
View 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]

View 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

View File

@ -0,0 +1,11 @@
libc {
GLIBC_2.12 {
_flush_cache;
cacheflush;
fallocate64;
set_dataplane;
}
GLIBC_PRIVATE {
__syscall_error;
}
}

View 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

View 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)

View 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

View 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

View 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. */

View 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. */

View 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)

View 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

View 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

View 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)

View 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

View 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)

View 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

View 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 */

View 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