Merge "[MIPS64] libc/libm support"

This commit is contained in:
Elliott Hughes 2014-02-07 00:23:21 +00:00 committed by Gerrit Code Review
commit 8a80a23c93
38 changed files with 3901 additions and 38 deletions

View File

@ -481,10 +481,11 @@ libc_common_src_files += \
endif # arm64
ifeq ($(TARGET_ARCH),mips)
ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),mips mips64))
libc_common_src_files += \
bionic/memchr.c \
bionic/memcmp.c \
bionic/memmove.c \
bionic/memrchr.c \
bionic/strchr.cpp \
bionic/strnlen.c \
@ -507,7 +508,7 @@ libc_common_src_files += \
upstream-freebsd/lib/libc/string/wcsrchr.c \
upstream-freebsd/lib/libc/string/wmemcmp.c \
endif # mips
endif # mips || mips64
ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86_64))
libc_common_src_files += \
@ -618,7 +619,7 @@ ifeq ($(TARGET_ARCH),arm)
libc_crt_target_cflags += -mthumb-interwork
endif # arm
ifeq ($(TARGET_ARCH),mips)
ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),mips mips64))
ifneq ($(ARCH_MIPS_HAS_FPU),true)
libc_common_cflags += -DSOFTFLOAT
endif
@ -683,7 +684,7 @@ ifeq ($(TARGET_ARCH),arm64)
libc_crt_target_so_cflags :=
libc_crt_target_crtbegin_file := $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin.c
endif
ifeq ($(TARGET_ARCH),mips)
ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),mips mips64))
libc_crt_target_so_cflags := -fPIC
libc_crt_target_crtbegin_file := $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin.c
endif

View File

@ -6,7 +6,6 @@ _LIBC_ARCH_COMMON_SRC_FILES := \
arch-mips/bionic/futex_mips.S \
arch-mips/bionic/__get_sp.S \
arch-mips/bionic/memcmp16.S \
arch-mips/bionic/memmove.c \
arch-mips/bionic/_setjmp.S \
arch-mips/bionic/setjmp.S \
arch-mips/bionic/__set_tls.c \

View File

@ -0,0 +1,99 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <machine/asm.h>
#include <asm/unistd.h>
#include <linux/errno.h>
#include <linux/sched.h>
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
FRAMESZ = MKFSIZ(NARGSAVE,0)
FRAME_ARG = 0*REGSZ
FRAME_FN = 1*REGSZ
#else
FRAMESZ = MKFSIZ(0,3)
FRAME_GP = FRAMESZ-1*REGSZ
FRAME_ARG = FRAMESZ-2*REGSZ
FRAME_FN = FRAMESZ-3*REGSZ
#endif
// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
.text
LEAF(__bionic_clone,FRAMESZ)
PTR_SUBU sp, FRAMESZ # allocate stack frame
SETUP_GP64(FRAME_GP,__bionic_clone)
SAVE_GP(FRAME_GP)
# set up child stack
PTR_SUBU a1,FRAMESZ
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
PTR_L t0,FRAMESZ+5*REGSZ(sp) # fn
PRL_L t1,FRAMESZ+6*REGSZ(sp) # arg
PTR_S t0,FRAME_FN(a1) # fn
PTR_S t1,FRAME_ARG(a1) # arg
#else
PTR_L t0,FRAME_GP(sp) # copy gp to child stack
PTR_S t0,FRAME_GP(a1)
PTR_S a5,FRAME_FN(a1) # fn
PTR_S a6,FRAME_ARG(a1) # arg
# endif
# remainder of arguments are correct for clone system call
LI v0,__NR_clone
syscall
move a0,v0
bnez a3,.L__error_bc
beqz v0,.L__thread_start_bc
RESTORE_GP64
PTR_ADDU sp,FRAMESZ
j ra
.L__thread_start_bc:
# void __bionic_clone_entry(int (*func)(void*), void *arg)
PTR_L a0,FRAME_FN(sp) # fn
PTR_L a1,FRAME_ARG(sp) # arg
LA t9,__bionic_clone_entry
RESTORE_GP64
/*
* For O32 etc the child stack must have space for a0..a3 to be stored
* For N64 etc, the child stack can be restored to the original value
*/
#if !((_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32))
PTR_ADDU sp,FRAMESZ
#endif
j t9
.L__error_bc:
LA t9,__set_errno
RESTORE_GP64
PTR_ADDU sp,FRAMESZ
j t9
END(__bionic_clone)

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
.text
/* void *__get_sp(void) */
.type __get_sp, @function
.global __get_sp
.align 4
.ent __get_sp
__get_sp:
move $v0, $sp
j $ra
.end __get_sp

View File

@ -25,20 +25,11 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <string.h>
#include <strings.h>
#include <pthread.h>
void *memmove(void *dst, const void *src, size_t n)
extern int __set_thread_area(void *u_info);
int __set_tls(void *ptr)
{
const char *p = src;
char *q = dst;
/* We can use the optimized memcpy if the destination is completely below the
* source (i.e. q + n <= p), or if it is completely over it (i.e. q >= p+n).
*/
if (__builtin_expect((q + n < p) || (q >= p + n), 1)) {
return memcpy(dst, src, n);
} else {
bcopy(src, dst, n);
return dst;
}
return __set_thread_area(ptr);
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <asm/unistd.h>
.text
// void _exit_with_stack_teardown(void* stackBase, size_t stackSize)
.type _exit_with_stack_teardown, @function
.global _exit_with_stack_teardown
.align 4
.ent _exit_with_stack_teardown
_exit_with_stack_teardown:
li $v0, __NR_munmap
syscall
// If munmap failed, we ignore the failure and exit anyway.
li $a0, 0
li $v0, __NR_exit
syscall
// The exit syscall does not return.
.end _exit_with_stack_teardown

View File

@ -0,0 +1,188 @@
/* $OpenBSD: _setjmp.S,v 1.4 2005/08/07 16:40:15 espie Exp $ */
/*
* Copyright (c) 2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Opsycon AB nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <machine/asm.h>
#include <machine/regnum.h>
#include <machine/signal.h>
/*
* _setjmp, _longjmp (not restoring signal state)
*
* XXX FPSET should probably be taken from SR setting. hmmm...
* GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
*
*/
FRAMESZ= MKFSIZ(0,4)
GPOFF= FRAMESZ-2*REGSZ
#define FPREG64_S(FPR, OFF, BASE) \
swc1 FPR, OFF(BASE) ; \
mfhc1 t0, FPR ; \
sw t0, OFF+4(BASE) ;
#define FPREG64_L(FPR, OFF, BASE) \
lw t0, OFF+4(BASE) ; \
lw t1, OFF(BASE) ; \
mtc1 t1, FPR ; \
mthc1 t0, FPR ; \
LEAF(_setjmp, FRAMESZ)
PTR_SUBU sp, FRAMESZ
SETUP_GP64(GPOFF, _setjmp)
SAVE_GP(GPOFF)
.set noreorder
#if defined(__mips64)
dli v0, 0xACEDBADE # sigcontext magic number
#else
li v0, 0xACEDBADE # sigcontext magic number
#endif
REG_S v0, SC_REGS+ZERO*REGSZ(a0)
REG_S s0, SC_REGS+S0*REGSZ(a0)
REG_S s1, SC_REGS+S1*REGSZ(a0)
REG_S s2, SC_REGS+S2*REGSZ(a0)
REG_S s3, SC_REGS+S3*REGSZ(a0)
REG_S s4, SC_REGS+S4*REGSZ(a0)
REG_S s5, SC_REGS+S5*REGSZ(a0)
REG_S s6, SC_REGS+S6*REGSZ(a0)
REG_S s7, SC_REGS+S7*REGSZ(a0)
REG_S s8, SC_REGS+S8*REGSZ(a0)
REG_L v0, GPOFF(sp)
REG_S v0, SC_REGS+GP*REGSZ(a0)
PTR_ADDU v0, sp, FRAMESZ
REG_S v0, SC_REGS+SP*REGSZ(a0)
REG_S ra, SC_PC(a0)
#if !defined(SOFTFLOAT)
li v0, 1 # be nice if we could tell
REG_S v0, SC_FPUSED(a0) # sc_fpused = 1
cfc1 v0, $31
#if _MIPS_FPSET == 32
FPREG64_S($f20, SC_FPREGS+((F20-F0)*REGSZ_FP), a0)
FPREG64_S($f21, SC_FPREGS+((F21-F0)*REGSZ_FP), a0)
FPREG64_S($f22, SC_FPREGS+((F22-F0)*REGSZ_FP), a0)
FPREG64_S($f23, SC_FPREGS+((F23-F0)*REGSZ_FP), a0)
FPREG64_S($f24, SC_FPREGS+((F24-F0)*REGSZ_FP), a0)
FPREG64_S($f25, SC_FPREGS+((F25-F0)*REGSZ_FP), a0)
FPREG64_S($f26, SC_FPREGS+((F26-F0)*REGSZ_FP), a0)
FPREG64_S($f27, SC_FPREGS+((F27-F0)*REGSZ_FP), a0)
FPREG64_S($f28, SC_FPREGS+((F28-F0)*REGSZ_FP), a0)
FPREG64_S($f29, SC_FPREGS+((F29-F0)*REGSZ_FP), a0)
FPREG64_S($f30, SC_FPREGS+((F30-F0)*REGSZ_FP), a0)
FPREG64_S($f31, SC_FPREGS+((F31-F0)*REGSZ_FP), a0)
#else
swc1 $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
swc1 $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
swc1 $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
swc1 $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
swc1 $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
swc1 $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
swc1 $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
swc1 $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
swc1 $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
swc1 $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
swc1 $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
swc1 $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
#endif
REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
#endif /* !SOFTFLOAT */
RESTORE_GP64
PTR_ADDU sp, FRAMESZ
j ra
move v0, zero
END(_setjmp)
LEAF(_longjmp, FRAMESZ)
PTR_SUBU sp, FRAMESZ
SETUP_GP64(GPOFF, _longjmp)
SAVE_GP(GPOFF)
.set noreorder
REG_L v0, SC_REGS+ZERO*REGSZ(a0)
bne v0, 0xACEDBADE, botch # jump if error
REG_L ra, SC_PC(a0)
REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
REG_L s0, SC_REGS+S0*REGSZ(a0)
REG_L s1, SC_REGS+S1*REGSZ(a0)
REG_L s2, SC_REGS+S2*REGSZ(a0)
REG_L s3, SC_REGS+S3*REGSZ(a0)
REG_L s4, SC_REGS+S4*REGSZ(a0)
REG_L s5, SC_REGS+S5*REGSZ(a0)
REG_L s6, SC_REGS+S6*REGSZ(a0)
REG_L s7, SC_REGS+S7*REGSZ(a0)
REG_L s8, SC_REGS+S8*REGSZ(a0)
REG_L gp, SC_REGS+GP*REGSZ(a0)
REG_L sp, SC_REGS+SP*REGSZ(a0)
#if !defined(SOFTFLOAT)
ctc1 v0, $31
#if _MIPS_FPSET == 32
FPREG64_L($f20, SC_FPREGS+((F20-F0)*REGSZ_FP), a0)
FPREG64_L($f21, SC_FPREGS+((F21-F0)*REGSZ_FP), a0)
FPREG64_L($f22, SC_FPREGS+((F22-F0)*REGSZ_FP), a0)
FPREG64_L($f23, SC_FPREGS+((F23-F0)*REGSZ_FP), a0)
FPREG64_L($f24, SC_FPREGS+((F24-F0)*REGSZ_FP), a0)
FPREG64_L($f25, SC_FPREGS+((F25-F0)*REGSZ_FP), a0)
FPREG64_L($f26, SC_FPREGS+((F26-F0)*REGSZ_FP), a0)
FPREG64_L($f27, SC_FPREGS+((F27-F0)*REGSZ_FP), a0)
FPREG64_L($f28, SC_FPREGS+((F28-F0)*REGSZ_FP), a0)
FPREG64_L($f29, SC_FPREGS+((F29-F0)*REGSZ_FP), a0)
FPREG64_L($f30, SC_FPREGS+((F30-F0)*REGSZ_FP), a0)
FPREG64_L($f31, SC_FPREGS+((F31-F0)*REGSZ_FP), a0)
#else
lwc1 $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
lwc1 $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
lwc1 $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
lwc1 $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
lwc1 $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
lwc1 $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
lwc1 $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
lwc1 $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
lwc1 $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
lwc1 $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
lwc1 $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
lwc1 $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
#endif
#endif /* !SOFTFLOAT */
bne a1, zero, 1f
nop
li a1, 1 # never return 0!
1:
j ra
move v0, a1
botch:
jal longjmperror
nop
jal abort
nop
RESTORE_GP64
PTR_ADDU sp, FRAMESZ
END(_longjmp)

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2013 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
extern void *__dso_handle;
extern int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
__attribute__ ((visibility ("hidden")))
int atexit(void (*func)(void))
{
return (__cxa_atexit((void (*)(void *))func, (void *)0, &__dso_handle));
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
.text
#include <machine/asm.h>
/*
* void bzero(void *s, size_t n);
*/
LEAF(bzero,0)
SETUP_GP64(t0,bzero)
move a2,a1
move a1,zero
LA t9,memset
RESTORE_GP64
j t9
END(bzero)

View File

@ -0,0 +1,99 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
#include <sys/cachectl.h>
#ifdef DEBUG
#include "private/libc_logging.h"
#define XLOG(...) __libc_format_log(ANDROID_LOG_DEBUG,"libc-cacheflush",__VA_ARGS__)
#endif
/*
* Linux historically defines a cacheflush(3) routine for MIPS
* with this signature:
* int cacheflush(char *addr, int nbytes, int cache);
*
* Android defines an alternate cacheflush routine which exposes the
* ARM system call interface:
* int cacheflush (long start, long end, long flags)
*
* This is an attempt to maintain compatibility between the historical MIPS
* usage for software previously ported to MIPS and Android specific
* uses of cacheflush()
*
* Use the gcc __clear_cache builtin if possible. This will generate inline synci
* instructions if available or call _flush_cache(start, len, BCACHE) directly
*/
#if defined (__GNUC__)
#define GCC_VERSION ((__GNUC__*10000) + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
#endif
/* This is the Android signature */
int cacheflush (long start, long end, long /*flags*/) {
if (end < start) {
/*
* It looks like this is really MIPS style cacheflush call
* start => addr
* end => nbytes
*/
#ifdef DEBUG
static int warned = 0;
if (!warned) {
XLOG("called with (start,len) instead of (start,end)");
warned = 1;
}
#endif
end += start;
}
#if !defined(ARCH_MIPS_USE_FLUSHCACHE_SYSCALL) && \
defined(GCC_VERSION) && (GCC_VERSION >= 40300)
#if (__mips_isa_rev >= 2) && (GCC_VERSION < 40403)
/*
* Modify "start" and "end" to avoid GCC 4.3.0-4.4.2 bug in
* mips_expand_synci_loop that may execute synci one more time.
* "start" points to the first byte of the cache line.
* "end" points to the last byte of the line before the last cache line.
* Because size is always a multiple of 4, this is safe to set
* "end" to the last byte.
*/
{
int lineSize;
asm("rdhwr %0, $1" : "=r" (lineSize));
start = start & (-lineSize);
end = (end & (-lineSize)) - 1;
}
#endif
__builtin___clear_cache((char *)start, (char *)end);
#else
_flush_cache((char *)start, end-start, BCACHE);
#endif
return 0;
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2013 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "../../bionic/libc_init_common.h"
#include <stddef.h>
#include <stdint.h>
__attribute__ ((section (".preinit_array")))
void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
__attribute__ ((section (".init_array")))
void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
__attribute__ ((section (".fini_array")))
void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
__LIBC_HIDDEN__ void do_mips_start(void *raw_args) {
structors_array_t array;
array.preinit_array = &__PREINIT_ARRAY__;
array.init_array = &__INIT_ARRAY__;
array.fini_array = &__FINI_ARRAY__;
__libc_init(raw_args, NULL, &main, &array);
}
/*
* This function prepares the return address with a branch-and-link
* instruction (bal) and then uses a .cpsetup to compute the Global
* Offset Table (GOT) pointer ($gp). The $gp is then used to load
* the address of _do_mips_start() into $t9 just before calling it.
* Terminating the stack with a NULL return address.
*/
__asm__ (
" .set push \n"
" \n"
" .text \n"
" .align 4 \n"
" .type __start,@function \n"
" .globl __start \n"
" .globl _start \n"
" \n"
" .ent __start \n"
"__start: \n"
" _start: \n"
" .frame $sp,32,$0 \n"
" .mask 0x80000000,-8 \n"
" \n"
" move $a0, $sp \n"
" daddiu $sp, $sp, -32 \n"
" \n"
" .set noreorder \n"
" bal 1f \n"
" nop \n"
"1: \n"
" .cpsetup $ra,16,1b \n"
" .set reorder \n"
" \n"
" sd $0, 24($sp) \n"
" jal do_mips_start \n"
" \n"
"2: b 2b \n"
" .end __start \n"
" \n"
" .set pop \n"
);
#include "../../arch-common/bionic/__dso_handle.h"
#include "atexit.h"

View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2013 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
extern void __cxa_finalize(void *);
extern void *__dso_handle;
__attribute__((visibility("hidden"),destructor))
void __on_dlclose() {
__cxa_finalize(&__dso_handle);
}
#include "../../arch-common/bionic/__dso_handle_so.h"
#include "atexit.h"

View File

@ -0,0 +1,145 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <machine/asm.h>
#include <private/bionic_asm.h>
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
FRAMESZ = MKFSIZ(NARGSAVE+2,0)
FRAME_A4 = 4*REGSZ
FRAME_A5 = 5*REGSZ
#else
FRAMESZ = 0
#endif
// int __futex_wait(volatile void* ftx, int val, const struct timespec* timeout)
LEAF(__futex_wait, FRAMESZ)
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
PTR_SUBU sp, FRAMESZ
REG_S $0,FRAME_A5(sp) /* val3 */
REG_S $0,FRAME_A4(sp) /* addr2 */
#else
move a5,$0 /* val3 */
move a4,$0 /* addr2 */
#endif
move a3,a2 /* timespec */
move a2,a1 /* val */
LI a1,FUTEX_WAIT /* op */
# move a0,a0 /* ftx */
LI v0,__NR_futex
syscall
neg v0 /* Negate errno */
bnez a3,1f /* Check for error */
move v0,$0 /* Return 0 if no error */
1:
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
PTR_ADDU sp,FRAMESZ
#endif
j ra
END(__futex_wait)
// int __futex_wake(volatile void* ftx, int count)
LEAF(__futex_wake,FRAMESZ)
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
PTR_SUBU sp, FRAMESZ
REG_S $0,FRAME_A5(sp) /* val3 */
REG_S $0,FRAME_A4(sp) /* addr2 */
#else
move a5,$0 /* val3 */
move a4,$0 /* addr2 */
#endif
move a3,$0 /* timespec */
move a2,a1 /* val */
LI a1,FUTEX_WAKE /* op */
# move a0,a0 /* ftx */
LI v0,__NR_futex
syscall
neg v0 /* Negate errno */
bnez a3,1f /* Check for error */
move v0,$0 /* Return 0 if no error */
1:
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
PTR_ADDU sp,FRAMESZ
#endif
j ra
END(__futex_wake)
// int __futex_syscall3(volatile void* ftx, int op, int count)
LEAF(__futex_syscall3,FRAMESZ)
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
PTR_SUBU sp, FRAMESZ
REG_S $0,FRAME_A5(sp) /* val3 */
REG_S $0,FRAME_A4(sp) /* addr2 */
#else
move a5,$0 /* val3 */
move a4,$0 /* addr2 */
#endif
move a3,$0 /* timespec */
# move a2,a2 /* val */
# move a1,a1 /* op */
# move a0,a0 /* ftx */
LI v0,__NR_futex
syscall
neg v0 /* Negate errno */
bnez a3,1f /* Check for error */
move v0,$0 /* Return 0 if no error */
1:
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
PTR_ADDU sp,FRAMESZ
#endif
j ra
END(__futex_syscall3)
// int __futex_syscall4(volatile void* ftx, int op, int val, const struct timespec* timeout)
LEAF(__futex_syscall4,FRAMESZ)
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
PTR_SUBU sp, FRAMESZ
REG_S $0,FRAME_A5(sp) /* val3 */
REG_S $0,FRAME_A4(sp) /* addr2 */
#else
move a5,$0 /* val3 */
move a4,$0 /* addr2 */
#endif
# move a3,a3 /* timespec */
# move a2,a2 /* val */
# move a1,a1 /* op */
# move a0,a0 /* ftx */
LI v0,__NR_futex
syscall
neg v0 /* Negate errno */
bnez a3,1f /* Check for error */
move v0,$0 /* Return 0 if no error */
1:
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
PTR_ADDU sp,FRAMESZ
#endif
j ra
END(__futex_syscall4)

View File

@ -0,0 +1,97 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* The MIPS64 getdents64() system call is only present in 3.10+ kernels.
* If the getdents64() system call is not available fall back to using
* getdents() and modify the result to be compatible with getdents64().
*/
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
/* The mips_getdents type is 64bit clean */
struct mips_dirent {
uint64_t d_ino; /* Inode number */
uint64_t d_off; /* Offset to next mips_dirent */
uint16_t d_reclen; /* Length of this mips_dirent */
char d_name[]; /* Filename (null-terminated) */
/* length is actually (d_reclen - 2 -
offsetof(struct mips_dirent, d_name) */
// char pad; /* Zero padding byte */
// char d_type; /* File type (only since Linux 2.6.4; offset is (d_reclen - 1)) */
};
extern "C" int __getdents64(unsigned int fd, struct dirent *dirp, unsigned int count);
extern "C" int __getdents(unsigned int fd, struct mips_dirent *dirp, unsigned int count);
int getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
{
int r;
int oerrno = errno;
/* Use getdents64() if it is available */
r = __getdents64(fd, dirp, count);
if (r >= 0 || errno != ENOSYS)
return r;
/* Fallback to getdents() */
errno = oerrno;
r = __getdents(fd, (struct mips_dirent *)dirp, count);
if (r > 0) {
char *p;
char type;
union dirents {
struct mips_dirent m;
struct dirent d;
} *u;
p = (char *)dirp;
do {
u = (union dirents *)p;
/* This should not happen, but just in case... */
if (p + u->m.d_reclen > (char *)dirp + r)
break;
/* shuffle the dirent */
type = *(p + u->m.d_reclen - 1);
memmove(u->d.d_name, u->m.d_name,
u->m.d_reclen - 2 - offsetof(struct mips_dirent, d_name) + 1);
u->d.d_type = type;
p += u->m.d_reclen;
} while (p < (char *)dirp + r);
}
return r;
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
.text
#include <machine/asm.h>
/*
* u4 __memcmp16(const u2* s0, const u2* s1, size_t count);
*/
LEAF(__memcmp16,0)
move t0,$0
move t1,$0
beqz a2,.L_done /* 0 length string */
beq a0,a1,.L_done /* strings are identical */
/* Unoptimised... */
1: lhu t0,0(a0)
lhu t1,0(a1)
PTR_ADDU a1,2
bne t0,t1,.L_done
PTR_ADDU a0,2
SUBU a2,1
bnez a2,1b
.L_done:
SUBU v0,t0,t1
j ra
END(__memcmp16)

View File

@ -0,0 +1,211 @@
/* $OpenBSD: setjmp.S,v 1.5 2005/08/07 16:40:15 espie Exp $ */
/*
* Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Opsycon AB nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <machine/asm.h>
#include <machine/regnum.h>
#include <machine/signal.h>
/*
* setjmp, longjmp implementation for libc. this code depends
* on the layout of the struct sigcontext in machine/signal.h.
*
*/
FRAMESZ= MKFSIZ(2,6)
A1OFF= FRAMESZ-4*REGSZ
A0OFF= FRAMESZ-3*REGSZ
GPOFF= FRAMESZ-2*REGSZ
RAOFF= FRAMESZ-1*REGSZ
#define FPREG64_S(FPR, OFF, BASE) \
swc1 FPR, OFF(BASE) ; \
mfhc1 t0, FPR ; \
sw t0, OFF+4(BASE) ;
#define FPREG64_L(FPR, OFF, BASE) \
lw t0, OFF+4(BASE) ; \
lw t1, OFF(BASE) ; \
mtc1 t1, FPR ; \
mthc1 t0, FPR ; \
NON_LEAF(setjmp, FRAMESZ, ra)
.mask 0x80000000, RAOFF
PTR_SUBU sp, FRAMESZ # allocate stack frame
SETUP_GP64(GPOFF, setjmp)
SAVE_GP(GPOFF)
.set reorder
REG_S ra, RAOFF(sp) # save state
REG_S a0, A0OFF(sp)
move a0, zero # get current signal mask
jal sigblock
REG_L v1, A0OFF(sp) # v1 = jmpbuf
REG_S v0, SC_MASK(v1) # save sc_mask = sigblock(0)
REG_L a0, A0OFF(sp) # restore jmpbuf
REG_L ra, RAOFF(sp)
REG_S ra, SC_PC(a0) # sc_pc = return address
#if defined(__mips64)
dli v0, 0xACEDBADE # sigcontext magic number
#else
li v0, 0xACEDBADE # sigcontext magic number
#endif
REG_S v0, SC_REGS+ZERO*REGSZ(a0)
REG_S s0, SC_REGS+S0*REGSZ(a0)
REG_S s1, SC_REGS+S1*REGSZ(a0)
REG_S s2, SC_REGS+S2*REGSZ(a0)
REG_S s3, SC_REGS+S3*REGSZ(a0)
REG_S s4, SC_REGS+S4*REGSZ(a0)
REG_S s5, SC_REGS+S5*REGSZ(a0)
REG_S s6, SC_REGS+S6*REGSZ(a0)
REG_S s7, SC_REGS+S7*REGSZ(a0)
REG_S s8, SC_REGS+S8*REGSZ(a0)
REG_L v0, GPOFF(sp)
REG_S v0, SC_REGS+GP*REGSZ(a0)
PTR_ADDU v0, sp, FRAMESZ
REG_S v0, SC_REGS+SP*REGSZ(a0)
#if !defined(SOFTFLOAT)
li v0, 1 # be nice if we could tell
REG_S v0, SC_FPUSED(a0) # sc_fpused = 1
cfc1 v0, $31
#if _MIPS_FPSET == 32
FPREG64_S($f20, SC_FPREGS+((F20-F0)*REGSZ_FP), a0)
FPREG64_S($f21, SC_FPREGS+((F21-F0)*REGSZ_FP), a0)
FPREG64_S($f22, SC_FPREGS+((F22-F0)*REGSZ_FP), a0)
FPREG64_S($f23, SC_FPREGS+((F23-F0)*REGSZ_FP), a0)
FPREG64_S($f24, SC_FPREGS+((F24-F0)*REGSZ_FP), a0)
FPREG64_S($f25, SC_FPREGS+((F25-F0)*REGSZ_FP), a0)
FPREG64_S($f26, SC_FPREGS+((F26-F0)*REGSZ_FP), a0)
FPREG64_S($f27, SC_FPREGS+((F27-F0)*REGSZ_FP), a0)
FPREG64_S($f28, SC_FPREGS+((F28-F0)*REGSZ_FP), a0)
FPREG64_S($f29, SC_FPREGS+((F29-F0)*REGSZ_FP), a0)
FPREG64_S($f30, SC_FPREGS+((F30-F0)*REGSZ_FP), a0)
FPREG64_S($f31, SC_FPREGS+((F31-F0)*REGSZ_FP), a0)
#else
swc1 $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
swc1 $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
swc1 $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
swc1 $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
swc1 $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
swc1 $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
swc1 $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
swc1 $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
swc1 $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
swc1 $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
swc1 $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
swc1 $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
#endif
REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
#endif /* !SOFTFLOAT */
move v0, zero
RESTORE_GP64
PTR_ADDU sp, FRAMESZ
j ra
botch:
jal longjmperror
jal abort
RESTORE_GP64
PTR_ADDU sp, FRAMESZ
END(setjmp)
LEAF(longjmp, FRAMESZ)
PTR_SUBU sp, FRAMESZ
SETUP_GP64(GPOFF, longjmp)
SAVE_GP(GPOFF)
.set reorder
sw a1, A1OFF(sp)
sw a0, A0OFF(sp)
lw a0, SC_MASK(a0)
jal sigsetmask
lw a0, A0OFF(sp)
lw a1, A1OFF(sp)
.set noreorder
REG_L v0, SC_REGS+ZERO*REGSZ(a0)
bne v0, 0xACEDBADE, botch # jump if error
REG_L ra, SC_PC(a0)
REG_L s0, SC_REGS+S0*REGSZ(a0)
REG_L s1, SC_REGS+S1*REGSZ(a0)
REG_L s2, SC_REGS+S2*REGSZ(a0)
REG_L s3, SC_REGS+S3*REGSZ(a0)
REG_L s4, SC_REGS+S4*REGSZ(a0)
REG_L s5, SC_REGS+S5*REGSZ(a0)
REG_L s6, SC_REGS+S6*REGSZ(a0)
REG_L s7, SC_REGS+S7*REGSZ(a0)
REG_L s8, SC_REGS+S8*REGSZ(a0)
REG_L gp, SC_REGS+GP*REGSZ(a0)
REG_L sp, SC_REGS+SP*REGSZ(a0)
#if !defined(SOFTFLOAT)
REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
ctc1 v0, $31
#if _MIPS_FPSET == 32
FPREG64_L($f20, SC_FPREGS+((F20-F0)*REGSZ_FP), a0)
FPREG64_L($f21, SC_FPREGS+((F21-F0)*REGSZ_FP), a0)
FPREG64_L($f22, SC_FPREGS+((F22-F0)*REGSZ_FP), a0)
FPREG64_L($f23, SC_FPREGS+((F23-F0)*REGSZ_FP), a0)
FPREG64_L($f24, SC_FPREGS+((F24-F0)*REGSZ_FP), a0)
FPREG64_L($f25, SC_FPREGS+((F25-F0)*REGSZ_FP), a0)
FPREG64_L($f26, SC_FPREGS+((F26-F0)*REGSZ_FP), a0)
FPREG64_L($f27, SC_FPREGS+((F27-F0)*REGSZ_FP), a0)
FPREG64_L($f28, SC_FPREGS+((F28-F0)*REGSZ_FP), a0)
FPREG64_L($f29, SC_FPREGS+((F29-F0)*REGSZ_FP), a0)
FPREG64_L($f30, SC_FPREGS+((F30-F0)*REGSZ_FP), a0)
FPREG64_L($f31, SC_FPREGS+((F31-F0)*REGSZ_FP), a0)
#else
lwc1 $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
lwc1 $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
lwc1 $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
lwc1 $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
lwc1 $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
lwc1 $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
lwc1 $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
lwc1 $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
lwc1 $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
lwc1 $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
lwc1 $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
lwc1 $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
#endif
#endif /* !SOFTFLOAT */
bne a1, zero, 1f
nop
li a1, 1 # never return 0!
1:
j ra
move v0, a1
END(longjmp)

View File

@ -0,0 +1,77 @@
/* $OpenBSD: sigsetjmp.S,v 1.5 2005/08/07 16:40:15 espie Exp $ */
/*-
* Copyright (c) 1991, 1993, 1995,
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Havard Eidnes.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <machine/asm.h>
#include <machine/regnum.h>
#include <machine/setjmp.h>
/*
* trampolines for sigsetjmp and siglongjmp save and restore mask.
*
*/
FRAMESZ= MKFSIZ(1,1)
GPOFF= FRAMESZ-2*REGSZ
LEAF(sigsetjmp, FRAMESZ)
PTR_SUBU sp, FRAMESZ
SETUP_GP64(GPOFF, sigsetjmp)
.set reorder
REG_S a1, (_JBLEN*REGSZ)(a0) # save "savemask"
bne a1, 0x0, 1f # do saving of signal mask?
LA t9, _setjmp
RESTORE_GP64
PTR_ADDU sp, FRAMESZ
jr t9
1: LA t9, setjmp
RESTORE_GP64
PTR_ADDU sp, FRAMESZ
jr t9
END(sigsetjmp)
LEAF(siglongjmp, FRAMESZ)
PTR_SUBU sp, FRAMESZ
SETUP_GP64(GPOFF, siglongjmp)
.set reorder
REG_L t0, (_JBLEN*REGSZ)(a0) # get "savemask"
bne t0, 0x0, 1f # restore signal mask?
LA t9, _longjmp
RESTORE_GP64
PTR_ADDU sp, FRAMESZ
jr t9
1:
LA t9, longjmp
RESTORE_GP64
PTR_ADDU sp, FRAMESZ
jr t9
END(siglongjmp)

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2013 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <machine/asm.h>
#include <asm/unistd.h>
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
FRAMESZ = MKFSIZ(6,0)
#else
FRAMESZ = MKFSIZ(0,1)
FRAME_GP = FRAMESZ-1*REGSZ
#endif
LEAF(syscall,FRAMESZ)
PTR_SUBU sp, FRAMESZ # allocate stack frame
SETUP_GP64(FRAME_GP,syscall)
SAVE_GP(FRAME_GP)
move v0, a0 # syscall number to v0
move a0, a1 # shift args down
move a1, a2
move a2, a3
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
REG_L a3, FRAMESZ+4*REGSZ(sp)
REG_L t0, FRAMESZ+5*REGSZ(sp)
REG_L t1, FRAMESZ+6*REGSZ(sp)
REG_S t0, 4*REGSZ(sp)
REG_S t1, 5*REGSZ(sp)
#else
move a3, a4
move a4, a5
REG_L a5, FRAMESZ(sp)
#endif
syscall
move a0, v0
bnez a3, 1f
RESTORE_GP64
PTR_ADDU sp, FRAMESZ
j ra
1:
LA t9,__set_errno
RESTORE_GP64
PTR_ADDU sp, FRAMESZ
j t9
END(syscall)

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <machine/asm.h>
#include <asm/unistd.h>
#include <linux/sched.h>
// TODO: mips' uapi signal.h is missing #ifndef __ASSEMBLY__.
// #include <asm/signal.h>
#define SIGCHLD 18
.text
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
FRAMESZ = MKFSIZ(5,0)
#else
FRAMESZ = MKFSIZ(0,0)
#endif
LEAF(vfork,FRAMESZ)
#if FRAMESZ!=0
PTR_SUBU sp, FRAMESZ
#endif
SETUP_GP64(a5,vfork)
LI a0, (CLONE_VM | CLONE_VFORK | SIGCHLD)
move a1, $0
move a2, $0
move a3, $0
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
REG_S $0, 4*REGSZ(sp)
#else
move a4, $0
#endif
LI v0, __NR_clone
syscall
#if FRAMESZ!=0
PTR_ADDU sp,FRAMESZ
#endif
move a0, v0
bnez a3, 1f
RESTORE_GP64
j ra
1:
LA t9,__set_errno
RESTORE_GP64
j t9
END(vfork)

View File

@ -0,0 +1,305 @@
/* $OpenBSD: asm.h,v 1.7 2004/10/20 12:49:15 pefo Exp $ */
/*
* Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _MIPS64_ASM_H
#define _MIPS64_ASM_H
#include <machine/regdef.h>
#ifdef NEED_OLD_RM7KFIX
#define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
#else
#define ITLBNOPFIX nop;nop;nop;nop
#endif
#define _MIPS_ISA_MIPS1 1 /* R2000/R3000 */
#define _MIPS_ISA_MIPS2 2 /* R4000/R6000 */
#define _MIPS_ISA_MIPS3 3 /* R4000 */
#define _MIPS_ISA_MIPS4 4 /* TFP (R1x000) */
#ifdef __linux__
#define _MIPS_ISA_MIPS5 5
#define _MIPS_ISA_MIPS32 6
#define _MIPS_ISA_MIPS64 7
#else
#define _MIPS_ISA_MIPS32 32 /* MIPS32 */
#endif
#if !defined(ABICALLS) && !defined(_NO_ABICALLS)
#define ABICALLS .abicalls
#endif
#if defined(ABICALLS) && !defined(_KERNEL)
ABICALLS
#endif
#define _C_LABEL(x) x /* XXX Obsolete but keep for a while */
#if !defined(__MIPSEL__) && !defined(__MIPSEB__)
#error "__MIPSEL__ or __MIPSEB__ must be defined"
#endif
/*
* Define how to access unaligned data word
*/
#if defined(__MIPSEL__)
#define LWLO lwl
#define LWHI lwr
#define SWLO swl
#define SWHI swr
#define LDLO ldl
#define LDHI ldr
#define SDLO sdl
#define SDHI sdr
#endif
#if defined(__MIPSEB__)
#define LWLO lwr
#define LWHI lwl
#define SWLO swr
#define SWHI swl
#define LDLO ldr
#define LDHI ldl
#define SDLO sdr
#define SDHI sdl
#endif
/*
* Define programming environment for ABI.
*/
#if defined(ABICALLS) && !defined(_KERNEL) && !defined(_STANDALONE)
#ifndef _MIPS_SIM
#define _MIPS_SIM 1
#define _ABIO32 1
#endif
#ifndef _MIPS_ISA
#define _MIPS_ISA 2
#define _MIPS_ISA_MIPS2 2
#endif
#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
#define NARGSAVE 4
#define SETUP_GP \
.set noreorder; \
.cpload t9; \
.set reorder;
#define SAVE_GP(x) \
.cprestore x
#define SETUP_GP64(gpoff, name)
#define RESTORE_GP64
#endif
#if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)
#define NARGSAVE 0
#define SETUP_GP
#define SAVE_GP(x)
#define SETUP_GP64(gpoff, name) \
.cpsetup t9, gpoff, name
#define RESTORE_GP64 \
.cpreturn
#endif
#define MKFSIZ(narg,locals) (((narg+locals)*REGSZ+31)&(~31))
#else /* defined(ABICALLS) && !defined(_KERNEL) */
#define NARGSAVE 4
#define SETUP_GP
#define SAVE_GP(x)
#define ALIGNSZ 16 /* Stack layout alignment */
#define FRAMESZ(sz) (((sz) + (ALIGNSZ-1)) & ~(ALIGNSZ-1))
#endif
/*
* Basic register operations based on selected ISA
*/
#if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || _MIPS_ISA == _MIPS_ISA_MIPS32)
#define REGSZ 4 /* 32 bit mode register size */
#define LOGREGSZ 2 /* log rsize */
#define REG_S sw
#define REG_L lw
#define CF_SZ 24 /* Call frame size */
#define CF_ARGSZ 16 /* Call frame arg size */
#define CF_RA_OFFS 20 /* Call ra save offset */
#endif
#if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || _MIPS_ISA == _MIPS_ISA_MIPS64)
#define REGSZ 8 /* 64 bit mode register size */
#define LOGREGSZ 3 /* log rsize */
#define REG_S sd
#define REG_L ld
#define CF_SZ 48 /* Call frame size (multiple of ALIGNSZ) */
#define CF_ARGSZ 32 /* Call frame arg size */
#define CF_RA_OFFS 40 /* Call ra save offset */
#endif
#define REGSZ_FP 8 /* 64 bit FP register size */
#ifndef __LP64__
#define PTR_L lw
#define PTR_S sw
#define PTR_SUB sub
#define PTR_ADD add
#define PTR_SUBU subu
#define PTR_ADDU addu
#define LI li
#define LA la
#define PTR_SLL sll
#define PTR_SRL srl
#define PTR_VAL .word
#else
#define PTR_L ld
#define PTR_S sd
#define PTR_ADD dadd
#define PTR_SUB dsub
#define PTR_SUBU dsubu
#define PTR_ADDU daddu
#define LI dli
#define LA dla
#define PTR_SLL dsll
#define PTR_SRL dsrl
#define PTR_VAL .dword
#endif
/*
* Define -pg profile entry code.
*/
#if defined(XGPROF) || defined(XPROF)
#define MCOUNT \
PTR_SUBU sp, sp, 64; \
SAVE_GP(16); \
sd ra, 56(sp); \
sd gp, 48(sp); \
.set noat; \
.set noreorder; \
move AT, ra; \
jal _mcount; \
PTR_SUBU sp, sp, 16; \
ld ra, 56(sp); \
PTR_ADDU sp, sp, 64; \
.set reorder; \
.set at;
#else
#define MCOUNT
#endif
/*
* LEAF(x, fsize)
*
* Declare a leaf routine.
*/
#define LEAF(x, fsize) \
.align 3; \
.globl x; \
.ent x, 0; \
x: ; \
.frame sp, fsize, ra; \
SETUP_GP \
MCOUNT
#define ALEAF(x) \
.globl x; \
x:
/*
* NLEAF(x)
*
* Declare a non-profiled leaf routine.
*/
#define NLEAF(x, fsize) \
.align 3; \
.globl x; \
.ent x, 0; \
x: ; \
.frame sp, fsize, ra; \
SETUP_GP
/*
* NON_LEAF(x)
*
* Declare a non-leaf routine (a routine that makes other C calls).
*/
#define NON_LEAF(x, fsize, retpc) \
.align 3; \
.globl x; \
.ent x, 0; \
x: ; \
.frame sp, fsize, retpc; \
SETUP_GP \
MCOUNT
/*
* NNON_LEAF(x)
*
* Declare a non-profiled non-leaf routine
* (a routine that makes other C calls).
*/
#define NNON_LEAF(x, fsize, retpc) \
.align 3; \
.globl x; \
.ent x, 0; \
x: ; \
.frame sp, fsize, retpc \
SETUP_GP
/*
* END(x)
*
* Mark end of a procedure.
*/
#define END(x) \
.end x
/*
* Macros to panic and printf from assembly language.
*/
#define PANIC(msg) \
LA a0, 9f; \
jal panic; \
nop ; \
MSG(msg)
#define PRINTF(msg) \
LA a0, 9f; \
jal printf; \
nop ; \
MSG(msg)
#define MSG(msg) \
.rdata; \
9: .asciiz msg; \
.text
#define ASMSTR(str) \
.asciiz str; \
.align 3
#endif /* !_MIPS_ASM_H */

View File

@ -0,0 +1,196 @@
/* $NetBSD: elf_machdep.h,v 1.15 2011/03/15 07:39:22 matt Exp $ */
#ifndef _MIPS_ELF_MACHDEP_H_
#define _MIPS_ELF_MACHDEP_H_
#ifdef _LP64
#define ARCH_ELFSIZE 64 /* MD native binary size */
#else
#define ARCH_ELFSIZE 32 /* MD native binary size */
#endif
#if ELFSIZE == 32
#define ELF32_MACHDEP_ID_CASES \
case EM_MIPS: \
break;
#define ELF32_MACHDEP_ID EM_MIPS
#elif ELFSIZE == 64
#define ELF64_MACHDEP_ID_CASES \
case EM_MIPS: \
break;
#define ELF64_MACHDEP_ID EM_MIPS
#endif
/* mips relocs. */
#define R_MIPS_NONE 0
#define R_MIPS_16 1
#define R_MIPS_32 2
#define R_MIPS_REL32 3
#define R_MIPS_REL R_MIPS_REL32
#define R_MIPS_26 4
#define R_MIPS_HI16 5 /* high 16 bits of symbol value */
#define R_MIPS_LO16 6 /* low 16 bits of symbol value */
#define R_MIPS_GPREL16 7 /* GP-relative reference */
#define R_MIPS_LITERAL 8 /* Reference to literal section */
#define R_MIPS_GOT16 9 /* Reference to global offset table */
#define R_MIPS_GOT R_MIPS_GOT16
#define R_MIPS_PC16 10 /* 16 bit PC relative reference */
#define R_MIPS_CALL16 11 /* 16 bit call thru glbl offset tbl */
#define R_MIPS_CALL R_MIPS_CALL16
#define R_MIPS_GPREL32 12
/* 13, 14, 15 are not defined at this point. */
#define R_MIPS_UNUSED1 13
#define R_MIPS_UNUSED2 14
#define R_MIPS_UNUSED3 15
/*
* The remaining relocs are apparently part of the 64-bit Irix ELF ABI.
*/
#define R_MIPS_SHIFT5 16
#define R_MIPS_SHIFT6 17
#define R_MIPS_64 18
#define R_MIPS_GOT_DISP 19
#define R_MIPS_GOT_PAGE 20
#define R_MIPS_GOT_OFST 21
#define R_MIPS_GOT_HI16 22
#define R_MIPS_GOT_LO16 23
#define R_MIPS_SUB 24
#define R_MIPS_INSERT_A 25
#define R_MIPS_INSERT_B 26
#define R_MIPS_DELETE 27
#define R_MIPS_HIGHER 28
#define R_MIPS_HIGHEST 29
#define R_MIPS_CALL_HI16 30
#define R_MIPS_CALL_LO16 31
#define R_MIPS_SCN_DISP 32
#define R_MIPS_REL16 33
#define R_MIPS_ADD_IMMEDIATE 34
#define R_MIPS_PJUMP 35
#define R_MIPS_RELGOT 36
#define R_MIPS_JALR 37
/* TLS relocations */
#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */
#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */
#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */
#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */
#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */
#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */
#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */
#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */
#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */
#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */
#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */
#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
#define R_MIPS_max 51
#define R_TYPE(name) __CONCAT(R_MIPS_,name)
#define R_MIPS16_min 100
#define R_MIPS16_26 100
#define R_MIPS16_GPREL 101
#define R_MIPS16_GOT16 102
#define R_MIPS16_CALL16 103
#define R_MIPS16_HI16 104
#define R_MIPS16_LO16 105
#define R_MIPS16_max 106
/* mips dynamic tags */
#define DT_MIPS_RLD_VERSION 0x70000001
#define DT_MIPS_TIME_STAMP 0x70000002
#define DT_MIPS_ICHECKSUM 0x70000003
#define DT_MIPS_IVERSION 0x70000004
#define DT_MIPS_FLAGS 0x70000005
#define DT_MIPS_BASE_ADDRESS 0x70000006
#define DT_MIPS_CONFLICT 0x70000008
#define DT_MIPS_LIBLIST 0x70000009
#define DT_MIPS_CONFLICTNO 0x7000000b
#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* number of local got ents */
#define DT_MIPS_LIBLISTNO 0x70000010
#define DT_MIPS_SYMTABNO 0x70000011 /* number of .dynsym entries */
#define DT_MIPS_UNREFEXTNO 0x70000012
#define DT_MIPS_GOTSYM 0x70000013 /* first dynamic sym in got */
#define DT_MIPS_HIPAGENO 0x70000014
#define DT_MIPS_RLD_MAP 0x70000016 /* address of loader map */
/*
* ELF Flags
*/
#define EF_MIPS_PIC 0x00000002 /* Contains PIC code */
#define EF_MIPS_CPIC 0x00000004 /* STD PIC calling sequence */
#define EF_MIPS_ABI2 0x00000020 /* N32 */
#define EF_MIPS_ARCH_ASE 0x0f000000 /* Architectural extensions */
#define EF_MIPS_ARCH_MDMX 0x08000000 /* MDMX multimedia extension */
#define EF_MIPS_ARCH_M16 0x04000000 /* MIPS-16 ISA extensions */
#define EF_MIPS_ARCH 0xf0000000 /* Architecture field */
#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code */
#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code */
#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code */
#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code */
#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code */
#define EF_MIPS_ARCH_32 0x50000000 /* -mips32 code */
#define EF_MIPS_ARCH_64 0x60000000 /* -mips64 code */
#define EF_MIPS_ARCH_32R2 0x70000000 /* -mips32r2 code */
#define EF_MIPS_ARCH_64R2 0x80000000 /* -mips64r2 code */
#define EF_MIPS_ABI 0x0000f000
#define EF_MIPS_ABI_O32 0x00001000
#define EF_MIPS_ABI_O64 0x00002000
#define EF_MIPS_ABI_EABI32 0x00003000
#define EF_MIPS_ABI_EABI64 0x00004000
#if defined(__MIPSEB__)
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF64_MACHDEP_ENDIANNESS ELFDATA2MSB
#elif defined(__MIPSEL__)
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2LSB
#define ELF64_MACHDEP_ENDIANNESS ELFDATA2LSB
#elif !defined(HAVE_NBTOOL_CONFIG_H)
#error neither __MIPSEL__ nor __MIPSEB__ are defined.
#endif
#ifdef _KERNEL
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
#endif
#ifdef COMPAT_16
/*
* Up to 1.6, the ELF dynamic loader (ld.elf_so) was not relocatable.
* Tell the kernel ELF exec code not to try relocating the interpreter
* for dynamically-linked ELF binaries.
*/
#define ELF_INTERP_NON_RELOCATABLE
#endif /* COMPAT_16 */
/*
* We need to be able to include the ELF header so we can pick out the
* ABI being used.
*/
#ifdef ELFSIZE
#define ELF_MD_PROBE_FUNC ELFNAME2(mips_netbsd,probe)
#define ELF_MD_COREDUMP_SETUP ELFNAME2(coredump,setup)
#endif
struct exec_package;
int mips_netbsd_elf32_probe(struct lwp *, struct exec_package *, void *, char *,
vaddr_t *);
void coredump_elf32_setup(struct lwp *, void *);
int mips_netbsd_elf64_probe(struct lwp *, struct exec_package *, void *, char *,
vaddr_t *);
void coredump_elf64_setup(struct lwp *, void *);
#endif /* _KERNEL */
#endif /* _MIPS_ELF_MACHDEP_H_ */

View File

@ -0,0 +1,70 @@
/* $OpenBSD: endian.h,v 1.5 2006/02/27 23:35:59 miod Exp $ */
/*
* Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _MIPS64_ENDIAN_H_
#define _MIPS64_ENDIAN_H_
#ifdef __GNUC__
#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
#define __swap16md(x) ({ \
register uint16_t _x = (x); \
register uint16_t _r; \
__asm volatile ("wsbh %0, %1" : "=r" (_r) : "r" (_x)); \
_r; \
})
#define __swap32md(x) ({ \
register uint32_t _x = (x); \
register uint32_t _r; \
__asm volatile ("wsbh %0, %1; rotr %0, %0, 16" : "=r" (_r) : "r" (_x)); \
_r; \
})
#define __swap64md(x) ({ \
uint64_t _swap64md_x = (x); \
(uint64_t) __swap32md(_swap64md_x >> 32) | \
(uint64_t) __swap32md(_swap64md_x & 0xffffffff) << 32; \
})
/* Tell sys/endian.h we have MD variants of the swap macros. */
#define MD_SWAP
#endif /* __mips32r2__ */
#endif /* __GNUC__ */
#if defined(__MIPSEB__)
#define _BYTE_ORDER _BIG_ENDIAN
#else
#define _BYTE_ORDER _LITTLE_ENDIAN
#endif
#define __STRICT_ALIGNMENT
#include <sys/types.h>
#include <sys/endian.h>
#endif /* _MIPS64_ENDIAN_H_ */

View File

@ -0,0 +1,188 @@
/* $OpenBSD: exec.h,v 1.1 2004/10/18 19:05:36 grange Exp $ */
/*
* Copyright (c) 1996-2004 Per Fogelstrom, Opsycon AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _MIPS64_EXEC_H_
#define _MIPS64_EXEC_H_
#define __LDPGSZ 4096
/*
* Define what exec "formats" we should handle.
*/
#define NATIVE_EXEC_ELF
#define NATIVE_ELFSIZE 64
#define EXEC_SCRIPT
/*
* If included from sys/exec.h define kernels ELF format.
*/
#ifdef __LP64__
#define ARCH_ELFSIZE 64
#define DB_ELFSIZE 64
#define ELF_TARG_CLASS ELFCLASS64
#else
#define ARCH_ELFSIZE 32
#define DB_ELFSIZE 32
#define ELF_TARG_CLASS ELFCLASS32
#endif
#if defined(__MIPSEB__)
#define ELF_TARG_DATA ELFDATA2MSB
#else
#define ELF_TARG_DATA ELFDATA2LSB
#endif
#define ELF_TARG_MACH EM_MIPS
#define _NLIST_DO_ELF
#if defined(_LP64)
#define _KERN_DO_ELF64
#if defined(COMPAT_O32)
#define _KERN_DO_ELF
#endif
#else
#define _KERN_DO_ELF
#endif
/* Information taken from MIPS ABI supplemental */
/* Architecture dependent Segment types - p_type */
#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
/* Architecture dependent d_tag field for Elf32_Dyn. */
#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime Linker Interface ID */
#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */
#define DT_MIPS_ICHECKSUM 0x70000003 /* Cksum of ext. str. and com. sizes */
#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */
#define DT_MIPS_FLAGS 0x70000005 /* Flags */
#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Segment base address */
#define DT_MIPS_CONFLICT 0x70000008 /* Adr of .conflict section */
#define DT_MIPS_LIBLIST 0x70000009 /* Address of .liblist section */
#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local .GOT entries */
#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of .conflict entries */
#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of .liblist entries */
#define DT_MIPS_SYMTABNO 0x70000011 /* Number of .dynsym entries */
#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */
#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in .dynsym */
#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */
#define DT_MIPS_RLD_MAP 0x70000016 /* Address of debug map pointer */
#define DT_PROCNUM (DT_MIPS_RLD_MAP - DT_LOPROC + 1)
/*
* Legal values for e_flags field of Elf32_Ehdr.
*/
#define EF_MIPS_NOREORDER 0x00000001 /* .noreorder was used */
#define EF_MIPS_PIC 0x00000002 /* Contains PIC code */
#define EF_MIPS_CPIC 0x00000004 /* Uses PIC calling sequence */
#define EF_MIPS_ABI2 0x00000020 /* -n32 on Irix 6 */
#define EF_MIPS_32BITMODE 0x00000100 /* 64 bit in 32 bit mode... */
#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */
#define E_MIPS_ARCH_1 0x00000000
#define E_MIPS_ARCH_2 0x10000000
#define E_MIPS_ARCH_3 0x20000000
#define E_MIPS_ARCH_4 0x30000000
#define EF_MIPS_ABI 0x0000f000 /* ABI level */
#define E_MIPS_ABI_NONE 0x00000000 /* ABI level not set */
#define E_MIPS_ABI_O32 0x00001000
#define E_MIPS_ABI_O64 0x00002000
#define E_MIPS_ABI_EABI32 0x00004000
#define E_MIPS_ABI_EABI64 0x00004000
/*
* Mips special sections.
*/
#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */
#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */
#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */
/*
* Legal values for sh_type field of Elf32_Shdr.
*/
#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */
#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */
#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */
#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */
#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information */
#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */
/*
* Legal values for sh_flags field of Elf32_Shdr.
*/
#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */
#if 0
/*
* Entries found in sections of type SHT_MIPS_GPTAB.
*/
typedef union {
struct {
Elf32_Word gt_current_g_value; /* -G val used in compilation */
Elf32_Word gt_unused; /* Not used */
} gt_header; /* First entry in section */
struct {
Elf32_Word gt_g_value; /* If this val were used for -G */
Elf32_Word gt_bytes; /* This many bytes would be used */
} gt_entry; /* Subsequent entries in section */
} Elf32_gptab;
/*
* Entry found in sections of type SHT_MIPS_REGINFO.
*/
typedef struct {
Elf32_Word ri_gprmask; /* General registers used */
Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */
Elf32_Sword ri_gp_value; /* $gp register value */
} Elf32_RegInfo;
#endif
/*
* Mips relocations.
*/
#define R_MIPS_NONE 0 /* No reloc */
#define R_MIPS_16 1 /* Direct 16 bit */
#define R_MIPS_32 2 /* Direct 32 bit */
#define R_MIPS_REL32 3 /* PC relative 32 bit */
#define R_MIPS_26 4 /* Direct 26 bit shifted */
#define R_MIPS_HI16 5 /* High 16 bit */
#define R_MIPS_LO16 6 /* Low 16 bit */
#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
#define R_MIPS_PC16 10 /* PC relative 16 bit */
#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
#define R_MIPS_64 18
#define R_MIPS_REL32_64 ((R_MIPS_64 << 8) | R_MIPS_REL32)
#endif /* !_MIPS64_EXEC_H_ */

View File

@ -0,0 +1,169 @@
/* $OpenBSD: ieee.h,v 1.4 2010/01/23 19:11:21 miod Exp $ */
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ieee.h 8.1 (Berkeley) 6/11/93
*/
/*
* ieee.h defines the machine-dependent layout of the machine's IEEE
* floating point. It does *not* define (yet?) any of the rounding
* mode bits, exceptions, and so forth.
*/
/*
* Define the number of bits in each fraction and exponent.
*
* k k+1
* Note that 1.0 x 2 == 0.1 x 2 and that denorms are represented
*
* (-exp_bias+1)
* as fractions that look like 0.fffff x 2 . This means that
*
* -126
* the number 0.10000 x 2 , for instance, is the same as the normalized
*
* -127 -128
* float 1.0 x 2 . Thus, to represent 2 , we need one leading zero
*
* -129
* in the fraction; to represent 2 , we need two, and so on. This
*
* (-exp_bias-fracbits+1)
* implies that the smallest denormalized number is 2
*
* for whichever format we are talking about: for single precision, for
*
* -126 -149
* instance, we get .00000000000000000000001 x 2 , or 1.0 x 2 , and
*
* -149 == -127 - 23 + 1.
*/
#define SNG_EXPBITS 8
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
#define DBL_FRACHBITS 20
#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#define EXT_EXPBITS 15
#define EXT_FRACHBITS 16
#define EXT_FRACHMBITS 32
#define EXT_FRACLMBITS 32
#define EXT_FRACLBITS 32
#define EXT_FRACBITS 112
#define EXT_IMPLICIT_NBIT
#define EXT_TO_ARRAY32(p, a) do { \
(a)[0] = (uint32_t)(p)->ext_fracl; \
(a)[1] = (uint32_t)(p)->ext_fraclm; \
(a)[2] = (uint32_t)(p)->ext_frachm; \
(a)[3] = (uint32_t)(p)->ext_frach; \
} while(0)
struct ieee_single {
#ifdef __MIPSEB__
u_int sng_sign:1;
u_int sng_exp:8;
u_int sng_frac:23;
#else
u_int sng_frac:23;
u_int sng_exp:8;
u_int sng_sign:1;
#endif
};
struct ieee_double {
#ifdef __MIPSEB__
u_int dbl_sign:1;
u_int dbl_exp:11;
u_int dbl_frach:20;
u_int dbl_fracl;
#else
u_int dbl_fracl;
u_int dbl_frach:20;
u_int dbl_exp:11;
u_int dbl_sign:1;
#endif
};
struct ieee_ext {
#ifdef __MIPSEB__
u_int ext_sign:1;
u_int ext_exp:15;
u_int ext_frach:16;
u_int ext_frachm;
u_int ext_fraclm;
u_int ext_fracl;
#else
u_int ext_fracl;
u_int ext_fraclm;
u_int ext_frachm;
u_int ext_frach:16;
u_int ext_exp:15;
u_int ext_sign:1;
#endif
};
/*
* Floats whose exponent is in [1..INFNAN) (of whatever type) are
* `normal'. Floats whose exponent is INFNAN are either Inf or NaN.
* Floats whose exponent is zero are either zero (iff all fraction
* bits are zero) or subnormal values.
*
* A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
* high fraction; if the bit is set, it is a `quiet NaN'.
*/
#define SNG_EXP_INFNAN 255
#define DBL_EXP_INFNAN 2047
#define EXT_EXP_INFNAN 32767
#if 0
#define SNG_QUIETNAN (1 << 22)
#define DBL_QUIETNAN (1 << 19)
#define EXT_QUIETNAN (1 << 15)
#endif
/*
* Exponent biases.
*/
#define SNG_EXP_BIAS 127
#define DBL_EXP_BIAS 1023
#define EXT_EXP_BIAS 16383

View File

@ -0,0 +1,62 @@
/* $OpenBSD: limits.h,v 1.5 2007/05/07 20:51:07 kettenis Exp $ */
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)limits.h 8.3 (Berkeley) 1/4/94
*/
#ifndef _MIPS_LIMITS_H_
#define _MIPS_LIMITS_H_
#include <sys/cdefs.h>
#define MB_LEN_MAX 6 /* Allow 31 bit UTF2 */
#ifndef SIZE_MAX
#define SIZE_MAX ULONG_MAX /* max value for a size_t */
#endif
#define SSIZE_MAX LONG_MAX /* max value for a ssize_t */
#if __BSD_VISIBLE
#define SIZE_T_MAX ULONG_MAX /* max value for a size_t (historic) */
/* Quads and longs are the same on mips64 */
#define UQUAD_MAX (ULONG_MAX) /* max value for a uquad_t */
#define QUAD_MAX (LONG_MAX) /* max value for a quad_t */
#define QUAD_MIN (LONG_MIN) /* min value for a quad_t */
#endif /* __BSD_VISIBLE */
#define LONGLONG_BIT 64
#define LONGLONG_MIN (-9223372036854775807LL-1)
#define LONGLONG_MAX 9223372036854775807LL
#define ULONGLONG_MAX 18446744073709551615ULL
#endif /* !_MIPS_LIMITS_H_ */

View File

@ -0,0 +1,99 @@
/* $OpenBSD: regdef.h,v 1.3 2005/08/07 07:29:44 miod Exp $ */
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ralph Campbell. This file is derived from the MIPS RISC
* Architecture book by Gerry Kane.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)regdef.h 8.1 (Berkeley) 6/10/93
*/
#ifndef _MIPS_REGDEF_H_
#define _MIPS_REGDEF_H_
#if (_MIPS_SIM == _ABI64) && !defined(__mips_n64)
#define __mips_n64 1
#endif
#if (_MIPS_SIM == _ABIN32) && !defined(__mips_n32)
#define __mips_n32 1
#endif
#define zero $0 /* always zero */
#define AT $at /* assembler temp */
#define v0 $2 /* return value */
#define v1 $3
#define a0 $4 /* argument registers */
#define a1 $5
#define a2 $6
#define a3 $7
#if defined(__mips_n32) || defined(__mips_n64)
#define a4 $8 /* expanded register arguments */
#define a5 $9
#define a6 $10
#define a7 $11
#define ta0 $8 /* alias */
#define ta1 $9
#define ta2 $10
#define ta3 $11
#define t0 $12 /* temp registers (not saved across subroutine calls) */
#define t1 $13
#define t2 $14
#define t3 $15
#else
#define t0 $8 /* temp registers (not saved across subroutine calls) */
#define t1 $9
#define t2 $10
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define ta0 $12 /* alias */
#define ta1 $13
#define ta2 $14
#define ta3 $15
#endif
#define s0 $16 /* saved across subroutine calls (callee saved) */
#define s1 $17
#define s2 $18
#define s3 $19
#define s4 $20
#define s5 $21
#define s6 $22
#define s7 $23
#define t8 $24 /* two more temp registers */
#define t9 $25
#define k0 $26 /* kernel temporary */
#define k1 $27
#define gp $28 /* global pointer */
#define sp $29 /* stack pointer */
#define s8 $30 /* one more callee saved */
#define ra $31 /* return address */
#endif /* !_MIPS_REGDEF_H_ */

View File

@ -0,0 +1,119 @@
/* $OpenBSD: regnum.h,v 1.3 2004/08/10 20:28:13 deraadt Exp $ */
/*
* Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _MIPS64_REGNUM_H_
#define _MIPS64_REGNUM_H_
/*
* Location of the saved registers relative to ZERO.
* Usage is p->p_regs[XX].
*/
#define ZERO 0
#define AST 1
#define V0 2
#define V1 3
#define A0 4
#define A1 5
#define A2 6
#define A3 7
#define T0 8
#define T1 9
#define T2 10
#define T3 11
#define T4 12
#define T5 13
#define T6 14
#define T7 15
#define S0 16
#define S1 17
#define S2 18
#define S3 19
#define S4 20
#define S5 21
#define S6 22
#define S7 23
#define T8 24
#define T9 25
#define K0 26
#define K1 27
#define GP 28
#define SP 29
#define S8 30
#define RA 31
#define SR 32
#define PS SR /* alias for SR */
#define MULLO 33
#define MULHI 34
#define BADVADDR 35
#define CAUSE 36
#define PC 37
#define IC 38
#define CPL 39
#define NUMSAVEREGS 40 /* Number of registers saved in trap */
#define FPBASE NUMSAVEREGS
#define F0 (FPBASE+0)
#define F1 (FPBASE+1)
#define F2 (FPBASE+2)
#define F3 (FPBASE+3)
#define F4 (FPBASE+4)
#define F5 (FPBASE+5)
#define F6 (FPBASE+6)
#define F7 (FPBASE+7)
#define F8 (FPBASE+8)
#define F9 (FPBASE+9)
#define F10 (FPBASE+10)
#define F11 (FPBASE+11)
#define F12 (FPBASE+12)
#define F13 (FPBASE+13)
#define F14 (FPBASE+14)
#define F15 (FPBASE+15)
#define F16 (FPBASE+16)
#define F17 (FPBASE+17)
#define F18 (FPBASE+18)
#define F19 (FPBASE+19)
#define F20 (FPBASE+20)
#define F21 (FPBASE+21)
#define F22 (FPBASE+22)
#define F23 (FPBASE+23)
#define F24 (FPBASE+24)
#define F25 (FPBASE+25)
#define F26 (FPBASE+26)
#define F27 (FPBASE+27)
#define F28 (FPBASE+28)
#define F29 (FPBASE+29)
#define F30 (FPBASE+30)
#define F31 (FPBASE+31)
#define FSR (FPBASE+32)
#define NUMFPREGS 33
#define NREGS (NUMSAVEREGS + NUMFPREGS)
#endif /* !_MIPS64_REGNUM_H_ */

View File

@ -0,0 +1,10 @@
/* $OpenBSD: setjmp.h,v 1.2 2004/08/10 21:10:56 pefo Exp $ */
/* Public domain */
#ifndef _MIPS_SETJMP_H_
#define _MIPS_SETJMP_H_
#define _JBLEN 157 /* size, in longs, of a jmp_buf */
#endif /* !_MIPS_SETJMP_H_ */

View File

@ -0,0 +1,53 @@
/* $OpenBSD: signal.h,v 1.8 2006/01/09 18:18:37 millert Exp $ */
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ralph Campbell.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)signal.h 8.1 (Berkeley) 6/10/93
*/
#ifndef _MIPS_SIGNAL_H_
#define _MIPS_SIGNAL_H_
#include <machine/asm.h>
#define SC_REGMASK (0*REGSZ)
#define SC_STATUS (1*REGSZ)
#define SC_PC (2*REGSZ)
#define SC_REGS (SC_PC+8)
#define SC_FPREGS (SC_REGS+32*8)
#define SC_ACX (SC_FPREGS+32*REGSZ_FP)
#define SC_USED_MATH (SC_ACX+3*REGSZ)
/* OpenBSD compatibility */
#define SC_MASK SC_REGMASK
#define SC_FPUSED SC_USED_MATH
#endif /* !_MIPS_SIGNAL_H_ */

View File

@ -0,0 +1,28 @@
_LIBC_ARCH_COMMON_SRC_FILES := \
arch-mips64/bionic/__bionic_clone.S \
arch-mips64/bionic/bzero.S \
arch-mips64/bionic/cacheflush.cpp \
arch-mips64/bionic/_exit_with_stack_teardown.S \
arch-mips64/bionic/futex_mips.S \
arch-mips64/bionic/__get_sp.S \
arch-mips64/bionic/getdents.cpp \
arch-mips64/bionic/memcmp16.S \
arch-mips64/bionic/_setjmp.S \
arch-mips64/bionic/setjmp.S \
arch-mips64/bionic/__set_tls.c \
arch-mips64/bionic/sigsetjmp.S \
arch-mips64/bionic/syscall.S \
arch-mips64/bionic/vfork.S \
# FIXME TODO
## _LIBC_ARCH_COMMON_SRC_FILES += arch-mips64/string/memcpy.S
## _LIBC_ARCH_COMMON_SRC_FILES += arch-mips64/string/memset.S
## _LIBC_ARCH_COMMON_SRC_FILES += arch-mips64/string/mips_strlen.c
_LIBC_ARCH_COMMON_SRC_FILES += bionic/memcpy.c
_LIBC_ARCH_COMMON_SRC_FILES += bionic/memset.c
_LIBC_ARCH_COMMON_SRC_FILES += string/strlen.c
_LIBC_ARCH_STATIC_SRC_FILES := \
bionic/dl_iterate_phdr_static.c \
_LIBC_ARCH_DYNAMIC_SRC_FILES :=

View File

@ -0,0 +1,423 @@
/*
* Copyright (c) 2009
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/************************************************************************
*
* memcpy.S
* Version: "043009"
*
************************************************************************/
/************************************************************************
* Include files
************************************************************************/
#include "machine/asm.h"
/*
* This routine could be optimized for MIPS64. The current code only
* uses MIPS32 instructions.
*/
#if defined(__MIPSEB__)
# define LWHI lwl /* high part is left in big-endian */
# define SWHI swl /* high part is left in big-endian */
# define LWLO lwr /* low part is right in big-endian */
# define SWLO swr /* low part is right in big-endian */
#endif
#if defined(__MIPSEL__)
# define LWHI lwr /* high part is right in little-endian */
# define SWHI swr /* high part is right in little-endian */
# define LWLO lwl /* low part is left in big-endian */
# define SWLO swl /* low part is left in big-endian */
#endif
LEAF(memcpy,0)
.set noreorder
.set noat
/*
* Below we handle the case where memcpy is called with overlapping src and dst.
* Although memcpy is not required to handle this case, some parts of Android like Skia
* rely on such usage. We call memmove to handle such cases.
*/
subu t0,a0,a1
sra AT,t0,31
xor t1,t0,AT
subu t0,t1,AT
sltu AT,t0,a2
beq AT,zero,.Lmemcpy
la t9,memmove
jr t9
nop
.Lmemcpy:
slti AT,a2,8
bne AT,zero,.Llast8
move v0,a0 # memcpy returns the dst pointer
# Test if the src and dst are word-aligned, or can be made word-aligned
xor t8,a1,a0
andi t8,t8,0x3 # t8 is a0/a1 word-displacement
bne t8,zero,.Lunaligned
negu a3,a0
andi a3,a3,0x3 # we need to copy a3 bytes to make a0/a1 aligned
beq a3,zero,.Lchk16w # when a3=0 then the dst (a0) is word-aligned
subu a2,a2,a3 # now a2 is the remining bytes count
LWHI t8,0(a1)
addu a1,a1,a3
SWHI t8,0(a0)
addu a0,a0,a3
# Now the dst/src are mutually word-aligned with word-aligned addresses
.Lchk16w:
andi t8,a2,0x3f # any whole 64-byte chunks?
# t8 is the byte count after 64-byte chunks
beq a2,t8,.Lchk8w # if a2==t8, no 64-byte chunks
# There will be at most 1 32-byte chunk after it
subu a3,a2,t8 # subtract from a2 the reminder
# Here a3 counts bytes in 16w chunks
addu a3,a0,a3 # Now a3 is the final dst after 64-byte chunks
addu t0,a0,a2 # t0 is the "past the end" address
# When in the loop we exercise "pref 30,x(a0)", the a0+x should not be past
# the "t0-32" address
# This means: for x=128 the last "safe" a0 address is "t0-160"
# Alternatively, for x=64 the last "safe" a0 address is "t0-96"
# In the current version we will use "pref 30,128(a0)", so "t0-160" is the limit
subu t9,t0,160 # t9 is the "last safe pref 30,128(a0)" address
pref 0,0(a1) # bring the first line of src, addr 0
pref 0,32(a1) # bring the second line of src, addr 32
pref 0,64(a1) # bring the third line of src, addr 64
pref 30,32(a0) # safe, as we have at least 64 bytes ahead
# In case the a0 > t9 don't use "pref 30" at all
sgtu v1,a0,t9
bgtz v1,.Lloop16w # skip "pref 30,64(a0)" for too short arrays
nop
# otherwise, start with using pref30
pref 30,64(a0)
.Lloop16w:
pref 0,96(a1)
lw t0,0(a1)
bgtz v1,.Lskip_pref30_96 # skip "pref 30,96(a0)"
lw t1,4(a1)
pref 30,96(a0) # continue setting up the dest, addr 96
.Lskip_pref30_96:
lw t2,8(a1)
lw t3,12(a1)
lw t4,16(a1)
lw t5,20(a1)
lw t6,24(a1)
lw t7,28(a1)
pref 0,128(a1) # bring the next lines of src, addr 128
sw t0,0(a0)
sw t1,4(a0)
sw t2,8(a0)
sw t3,12(a0)
sw t4,16(a0)
sw t5,20(a0)
sw t6,24(a0)
sw t7,28(a0)
lw t0,32(a1)
bgtz v1,.Lskip_pref30_128 # skip "pref 30,128(a0)"
lw t1,36(a1)
pref 30,128(a0) # continue setting up the dest, addr 128
.Lskip_pref30_128:
lw t2,40(a1)
lw t3,44(a1)
lw t4,48(a1)
lw t5,52(a1)
lw t6,56(a1)
lw t7,60(a1)
pref 0, 160(a1) # bring the next lines of src, addr 160
sw t0,32(a0)
sw t1,36(a0)
sw t2,40(a0)
sw t3,44(a0)
sw t4,48(a0)
sw t5,52(a0)
sw t6,56(a0)
sw t7,60(a0)
addiu a0,a0,64 # adding 64 to dest
sgtu v1,a0,t9
bne a0,a3,.Lloop16w
addiu a1,a1,64 # adding 64 to src
move a2,t8
# Here we have src and dest word-aligned but less than 64-bytes to go
.Lchk8w:
pref 0, 0x0(a1)
andi t8,a2,0x1f # is there a 32-byte chunk?
# the t8 is the reminder count past 32-bytes
beq a2,t8,.Lchk1w # when a2=t8, no 32-byte chunk
nop
lw t0,0(a1)
lw t1,4(a1)
lw t2,8(a1)
lw t3,12(a1)
lw t4,16(a1)
lw t5,20(a1)
lw t6,24(a1)
lw t7,28(a1)
addiu a1,a1,32
sw t0,0(a0)
sw t1,4(a0)
sw t2,8(a0)
sw t3,12(a0)
sw t4,16(a0)
sw t5,20(a0)
sw t6,24(a0)
sw t7,28(a0)
addiu a0,a0,32
.Lchk1w:
andi a2,t8,0x3 # now a2 is the reminder past 1w chunks
beq a2,t8,.Llast8
subu a3,t8,a2 # a3 is count of bytes in 1w chunks
addu a3,a0,a3 # now a3 is the dst address past the 1w chunks
# copying in words (4-byte chunks)
.LwordCopy_loop:
lw t3,0(a1) # the first t3 may be equal t0 ... optimize?
addiu a1,a1,4
addiu a0,a0,4
bne a0,a3,.LwordCopy_loop
sw t3,-4(a0)
# For the last (<8) bytes
.Llast8:
blez a2,.Lleave
addu a3,a0,a2 # a3 is the last dst address
.Llast8loop:
lb v1,0(a1)
addiu a1,a1,1
addiu a0,a0,1
bne a0,a3,.Llast8loop
sb v1,-1(a0)
.Lleave:
j ra
nop
#
# UNALIGNED case
#
.Lunaligned:
# got here with a3="negu a0"
andi a3,a3,0x3 # test if the a0 is word aligned
beqz a3,.Lua_chk16w
subu a2,a2,a3 # bytes left after initial a3 bytes
LWHI v1,0(a1)
LWLO v1,3(a1)
addu a1,a1,a3 # a3 may be here 1, 2 or 3
SWHI v1,0(a0)
addu a0,a0,a3 # below the dst will be word aligned (NOTE1)
.Lua_chk16w:
andi t8,a2,0x3f # any whole 64-byte chunks?
# t8 is the byte count after 64-byte chunks
beq a2,t8,.Lua_chk8w # if a2==t8, no 64-byte chunks
# There will be at most 1 32-byte chunk after it
subu a3,a2,t8 # subtract from a2 the reminder
# Here a3 counts bytes in 16w chunks
addu a3,a0,a3 # Now a3 is the final dst after 64-byte chunks
addu t0,a0,a2 # t0 is the "past the end" address
subu t9,t0,160 # t9 is the "last safe pref 30,128(a0)" address
pref 0,0(a1) # bring the first line of src, addr 0
pref 0,32(a1) # bring the second line of src, addr 32
pref 0,64(a1) # bring the third line of src, addr 64
pref 30,32(a0) # safe, as we have at least 64 bytes ahead
# In case the a0 > t9 don't use "pref 30" at all
sgtu v1,a0,t9
bgtz v1,.Lua_loop16w # skip "pref 30,64(a0)" for too short arrays
nop
# otherwise, start with using pref30
pref 30,64(a0)
.Lua_loop16w:
pref 0,96(a1)
LWHI t0,0(a1)
LWLO t0,3(a1)
LWHI t1,4(a1)
bgtz v1,.Lua_skip_pref30_96
LWLO t1,7(a1)
pref 30,96(a0) # continue setting up the dest, addr 96
.Lua_skip_pref30_96:
LWHI t2,8(a1)
LWLO t2,11(a1)
LWHI t3,12(a1)
LWLO t3,15(a1)
LWHI t4,16(a1)
LWLO t4,19(a1)
LWHI t5,20(a1)
LWLO t5,23(a1)
LWHI t6,24(a1)
LWLO t6,27(a1)
LWHI t7,28(a1)
LWLO t7,31(a1)
pref 0,128(a1) # bring the next lines of src, addr 128
sw t0,0(a0)
sw t1,4(a0)
sw t2,8(a0)
sw t3,12(a0)
sw t4,16(a0)
sw t5,20(a0)
sw t6,24(a0)
sw t7,28(a0)
LWHI t0,32(a1)
LWLO t0,35(a1)
LWHI t1,36(a1)
bgtz v1,.Lua_skip_pref30_128
LWLO t1,39(a1)
pref 30,128(a0) # continue setting up the dest, addr 128
.Lua_skip_pref30_128:
LWHI t2,40(a1)
LWLO t2,43(a1)
LWHI t3,44(a1)
LWLO t3,47(a1)
LWHI t4,48(a1)
LWLO t4,51(a1)
LWHI t5,52(a1)
LWLO t5,55(a1)
LWHI t6,56(a1)
LWLO t6,59(a1)
LWHI t7,60(a1)
LWLO t7,63(a1)
pref 0, 160(a1) # bring the next lines of src, addr 160
sw t0,32(a0)
sw t1,36(a0)
sw t2,40(a0)
sw t3,44(a0)
sw t4,48(a0)
sw t5,52(a0)
sw t6,56(a0)
sw t7,60(a0)
addiu a0,a0,64 # adding 64 to dest
sgtu v1,a0,t9
bne a0,a3,.Lua_loop16w
addiu a1,a1,64 # adding 64 to src
move a2,t8
# Here we have src and dest word-aligned but less than 64-bytes to go
.Lua_chk8w:
pref 0, 0x0(a1)
andi t8,a2,0x1f # is there a 32-byte chunk?
# the t8 is the reminder count
beq a2,t8,.Lua_chk1w # when a2=t8, no 32-byte chunk
nop
LWHI t0,0(a1)
LWLO t0,3(a1)
LWHI t1,4(a1)
LWLO t1,7(a1)
LWHI t2,8(a1)
LWLO t2,11(a1)
LWHI t3,12(a1)
LWLO t3,15(a1)
LWHI t4,16(a1)
LWLO t4,19(a1)
LWHI t5,20(a1)
LWLO t5,23(a1)
LWHI t6,24(a1)
LWLO t6,27(a1)
LWHI t7,28(a1)
LWLO t7,31(a1)
addiu a1,a1,32
sw t0,0(a0)
sw t1,4(a0)
sw t2,8(a0)
sw t3,12(a0)
sw t4,16(a0)
sw t5,20(a0)
sw t6,24(a0)
sw t7,28(a0)
addiu a0,a0,32
.Lua_chk1w:
andi a2,t8,0x3 # now a2 is the reminder past 1w chunks
beq a2,t8,.Lua_smallCopy
subu a3,t8,a2 # a3 is count of bytes in 1w chunks
addu a3,a0,a3 # now a3 is the dst address past the 1w chunks
# copying in words (4-byte chunks)
.Lua_wordCopy_loop:
LWHI v1,0(a1)
LWLO v1,3(a1)
addiu a1,a1,4
addiu a0,a0,4 # note: dst=a0 is word aligned here, see NOTE1
bne a0,a3,.Lua_wordCopy_loop
sw v1,-4(a0)
# Now less than 4 bytes (value in a2) left to copy
.Lua_smallCopy:
beqz a2,.Lleave
addu a3,a0,a2 # a3 is the last dst address
.Lua_smallCopy_loop:
lb v1,0(a1)
addiu a1,a1,1
addiu a0,a0,1
bne a0,a3,.Lua_smallCopy_loop
sb v1,-1(a0)
j ra
nop
.set at
.set reorder
END(memcpy)
/************************************************************************
* Implementation : Static functions
************************************************************************/

View File

@ -0,0 +1,323 @@
/*
* Copyright (c) 2009
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/************************************************************************
*
* memset.S, version "64h" with 1 cache line horizon for "pref 30" and 14 nops
* Version: "043009"
*
************************************************************************/
/************************************************************************
* Include files
************************************************************************/
#include "machine/asm.h"
/*
* This routine could be optimized for MIPS64. The current code only
* uses MIPS32 instructions.
*/
#if defined(__MIPSEB__)
# define SWHI swl /* high part is left in big-endian */
# define SWLO swr /* low part is right in big-endian */
#endif
#if defined(__MIPSEL__)
# define SWHI swr /* high part is right in little-endian */
# define SWLO swl /* low part is left in little-endian */
#endif
#if !(defined(XGPROF) || defined(XPROF))
#undef SETUP_GP
#define SETUP_GP
#endif
#ifdef NDEBUG
#define DBG #
#else
#define DBG
#endif
/*
* void _memset16(uint16_t* dst, uint16_t value, size_t size);
*/
LEAF(_memset16,0)
.set noreorder
DBG /* Check parameters */
DBG andi t0,a0,1 # a0 must be halfword aligned
DBG tne t0,zero
DBG andi t2,a2,1 # a2 must be even
DBG tne t2,zero
#ifdef FIXARGS
# ensure count is even
#if (__mips==32) && (__mips_isa_rev>=2)
ins a2,zero,0,1
#else
ori a2,1
xori a2,1
#endif
#endif
#if (__mips==32) && (__mips_isa_rev>=2)
ins a1,a1,16,16
#else
andi a1,0xffff
sll t3,a1,16
or a1,t3
#endif
beqz a2,.Ldone
andi t1,a0,2
beqz t1,.Lalignok
addu t0,a0,a2 # t0 is the "past the end" address
sh a1,0(a0) # store one halfword to get aligned
addu a0,2
subu a2,2
.Lalignok:
slti t1,a2,4 # .Laligned for 4 or more bytes
beqz t1,.Laligned
sne t1,a2,2 # one more halfword?
bnez t1,.Ldone
nop
sh a1,0(a0)
.Ldone:
j ra
nop
.set reorder
END(_memset16)
/*
* void _memset32(uint32_t* dst, uint32_t value, size_t size);
*/
LEAF(_memset32,0)
.set noreorder
DBG /* Check parameters */
DBG andi t0,a0,3 # a0 must be word aligned
DBG tne t0,zero
DBG andi t2,a2,3 # a2 must be a multiple of 4 bytes
DBG tne t2,zero
#ifdef FIXARGS
# ensure count is a multiple of 4
#if (__mips==32) && (__mips_isa_rev>=2)
ins $a2,$0,0,2
#else
ori a2,3
xori a2,3
#endif
#endif
bnez a2,.Laligned # any work to do?
addu t0,a0,a2 # t0 is the "past the end" address
j ra
nop
.set reorder
END(_memset32)
LEAF(memset,0)
.set noreorder
.set noat
addu t0,a0,a2 # t0 is the "past the end" address
slti AT,a2,4 # is a2 less than 4?
bne AT,zero,.Llast4 # if yes, go to last4
move v0,a0 # memset returns the dst pointer
beq a1,zero,.Lset0
subu v1,zero,a0
# smear byte into 32 bit word
#if (__mips==32) && (__mips_isa_rev>=2)
ins a1, a1, 8, 8 # Replicate fill byte into half-word.
ins a1, a1, 16, 16 # Replicate fill byte into word.
#else
and a1,0xff
sll AT,a1,8
or a1,AT
sll AT,a1,16
or a1,AT
#endif
.Lset0:
andi v1,v1,0x3 # word-unaligned address?
beq v1,zero,.Laligned # v1 is the unalignment count
subu a2,a2,v1
SWHI a1,0(a0)
addu a0,a0,v1
# Here we have the "word-aligned" a0 (until the "last4")
.Laligned:
andi t8,a2,0x3f # any 64-byte chunks?
# t8 is the byte count past 64-byte chunks
beq a2,t8,.Lchk8w # when a2==t8, no 64-byte chunks
# There will be at most 1 32-byte chunk then
subu a3,a2,t8 # subtract from a2 the reminder
# Here a3 counts bytes in 16w chunks
addu a3,a0,a3 # Now a3 is the final dst after 64-byte chunks
# Find out, if there are any 64-byte chunks after which will be still at least
# 96 bytes left. The value "96" is calculated as needed buffer for
# "pref 30,64(a0)" prefetch, which can be used as "pref 30,0(a0)" after
# incrementing "a0" by 64.
# For "a2" below 160 there will be no such "pref 30 safe" 64-byte chunk.
#
sltiu v1,a2,160
bgtz v1,.Lloop16w_nopref30 # skip "pref 30,0(a0)"
subu t7,a2,96 # subtract "pref 30 unsafe" region
# below we have at least 1 64-byte chunk which is "pref 30 safe"
andi t6,t7,0x3f # t6 is past "64-byte safe chunks" reminder
subu t5,t7,t6 # subtract from t7 the reminder
# Here t5 counts bytes in 16w "safe" chunks
addu t4,a0,t5 # Now t4 is the dst after 64-byte "safe" chunks
# Don't use "pref 30,0(a0)" for a0 in a "middle" of a cache line
# pref 30,0(a0)
# Here we are in the region, where it is safe to use "pref 30,64(a0)"
.Lloop16w:
addiu a0,a0,64
pref 30,-32(a0) # continue setting up the dest, addr 64-32
sw a1,-64(a0)
sw a1,-60(a0)
sw a1,-56(a0)
sw a1,-52(a0)
sw a1,-48(a0)
sw a1,-44(a0)
sw a1,-40(a0)
sw a1,-36(a0)
nop
nop # the extra nop instructions help to balance
nop # cycles needed for "store" + "fill" + "evict"
nop # For 64byte store there are needed 8 fill
nop # and 8 evict cycles, i.e. at least 32 instr.
nop
nop
pref 30,0(a0) # continue setting up the dest, addr 64-0
sw a1,-32(a0)
sw a1,-28(a0)
sw a1,-24(a0)
sw a1,-20(a0)
sw a1,-16(a0)
sw a1,-12(a0)
sw a1,-8(a0)
sw a1,-4(a0)
nop
nop
nop
nop # NOTE: adding 14 nop-s instead of 12 nop-s
nop # gives better results for "fast" memory
nop
bne a0,t4,.Lloop16w
nop
beq a0,a3,.Lchk8w # maybe no more 64-byte chunks?
nop # this "delayed slot" is useless ...
.Lloop16w_nopref30: # there could be up to 3 "64-byte nopref30" chunks
addiu a0,a0,64
sw a1,-64(a0)
sw a1,-60(a0)
sw a1,-56(a0)
sw a1,-52(a0)
sw a1,-48(a0)
sw a1,-44(a0)
sw a1,-40(a0)
sw a1,-36(a0)
sw a1,-32(a0)
sw a1,-28(a0)
sw a1,-24(a0)
sw a1,-20(a0)
sw a1,-16(a0)
sw a1,-12(a0)
sw a1,-8(a0)
bne a0,a3,.Lloop16w_nopref30
sw a1,-4(a0)
.Lchk8w: # t8 here is the byte count past 64-byte chunks
andi t7,t8,0x1f # is there a 32-byte chunk?
# the t7 is the reminder count past 32-bytes
beq t8,t7,.Lchk1w # when t8==t7, no 32-byte chunk
move a2,t7
sw a1,0(a0)
sw a1,4(a0)
sw a1,8(a0)
sw a1,12(a0)
sw a1,16(a0)
sw a1,20(a0)
sw a1,24(a0)
sw a1,28(a0)
addiu a0,a0,32
.Lchk1w:
andi t8,a2,0x3 # now t8 is the reminder past 1w chunks
beq a2,t8,.Llast4aligned
subu a3,a2,t8 # a3 is the count of bytes in 1w chunks
addu a3,a0,a3 # now a3 is the dst address past the 1w chunks
# copying in words (4-byte chunks)
.LwordCopy_loop:
addiu a0,a0,4
bne a0,a3,.LwordCopy_loop
sw a1,-4(a0)
# store last 0-3 bytes
# this will repeat the last store if the memset finishes on a word boundary
.Llast4aligned:
j ra
SWLO a1,-1(t0)
.Llast4:
beq a0,t0,.Llast4e
.Llast4l:
addiu a0,a0,1
bne a0,t0,.Llast4l
sb a1,-1(a0)
.Llast4e:
j ra
nop
.set at
.set reorder
END(memset)
/************************************************************************
* Implementation : Static functions
************************************************************************/

View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 2010 MIPS Technologies, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with
* the distribution.
* * Neither the name of MIPS Technologies Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MIPS_STRING_OPS_H
#define __MIPS_STRING_OPS_H
/* This definition of the byte bitfields uses the
assumption that the layout of the bitfields is
equivalent to the layout in memory. Generally,
for the MIPS ABIs, this is true. If you compile
the strcmp.c file with -DSMOKE_TEST_NEW_STRCMP,
this assumption will be tested.
Also, regardless of char signedness, ANSI C dictates that
strcmp() treats each character as unsigned char. For
strlen and the like, signedness doesn't matter.
Also, this code assumes that there are 8-bits per 'char'. */
#if __mips64
typedef struct bits
{
unsigned long B0:8, B1:8, B2:8, B3:8, B4:8, B5:8, B6:8, B7:8;
} bits_t;
#else
typedef struct bits
{
unsigned long B0:8, B1:8, B2:8, B3:8;
} bits_t;
#endif
#ifndef _ULW
/* for MIPS GCC, there is no unaligned builtins - so this code forces
the compiler to treat the pointer access as unaligned. */
struct ulw
{
unsigned long b;
} __attribute__ ((packed));
#define _ULW(__x) ((struct ulw *) ((char *)(&__x)))->b;
#endif
/* This union assumes that small structures can be in registers. If
not, then memory accesses will be done - not optimal, but ok. */
typedef union
{
unsigned long v;
bits_t b;
} bitfields_t;
#ifndef detect_zero
/* __mips_dsp, __mips_dspr2, and __mips64 are predefined by
the compiler, based on command line options. */
#if (__mips_dsp || __mips_dspr2) && !__mips64
#define __mips_using_dsp 1
/* DSP 4-lane (8 unsigned bits per line) subtract and saturate
* Intrinsic operation. How this works:
* Given a 4-byte string of "ABC\0", subtract this as
* an unsigned integer from 0x01010101:
* 0x01010101
* - 0x41424300
* -----------
( 0xbfbebe01 <-- answer without saturation
* 0x00000001 <-- answer with saturation
* When this 4-lane vector is treated as an unsigned int value,
* a non-zero answer indicates the presence of a zero in the
* original 4-byte argument. */
typedef signed char v4i8 __attribute__ ((vector_size (4)));
#define detect_zero(__x,__y,__01s,__80s)\
((unsigned) __builtin_mips_subu_s_qb((v4i8) __01s,(v4i8) __x))
/* sets all 4 lanes to requested byte. */
#define set_byte_lanes(__x) ((unsigned) __builtin_mips_repl_qb(__x))
/* sets all 4 lanes to 0x01. */
#define def_and_set_01(__x) unsigned long __x = (unsigned) __builtin_mips_repl_qb(0x01)
/* sets all 4 lanes to 0x80. Not needed when subu_s.qb used. */
#define def_and_set_80(__x) /* do nothing */
#else
/* this version, originally published in the 80's, uses
a reverse-carry-set like determination of the zero byte.
The steps are, for __x = 0x31ff0001:
__x - _01s = 0x30fdff00
~__x = 0xce00fffe
((__x - _01s) & ~__x) = 0x0000ff00
x & _80s = 0x00008000 <- byte 3 was zero
Some implementaions naively assume that characters are
always 7-bit unsigned ASCII. With that assumption, the
"& ~x" is usually discarded. Since character strings
are 8-bit, the and is needed to catch the case of
a false positive when the byte is 0x80. */
#define detect_zero(__x,__y,_01s,_80s)\
((unsigned) (((__x) - _01s) & ~(__x)) & _80s)
#if __mips64
#define def_and_set_80(__x) unsigned long __x = 0x8080808080808080ul
#define def_and_set_01(__x) unsigned long __x = 0x0101010101010101ul
#else
#define def_and_set_80(__x) unsigned long __x = 0x80808080ul
#define def_and_set_01(__x) unsigned long __x = 0x01010101ul
#endif
#endif
#endif
/* dealing with 'void *' conversions without using extra variables. */
#define get_byte(__x,__idx) (((unsigned char *) (__x))[__idx])
#define set_byte(__x,__idx,__fill) ((unsigned char *) (__x))[__idx] = (__fill)
#define get_word(__x,__idx) (((unsigned long *) (__x))[__idx])
#define set_word(__x,__idx,__fill) ((unsigned long *) (__x))[__idx] = (__fill)
#define inc_ptr_as(__type,__x,__inc) __x = (void *) (((__type) __x) + (__inc))
#define cvt_ptr_to(__type,__x) ((__type) (__x))
#endif

View File

@ -0,0 +1,224 @@
/*
* Copyright (c) 2010 MIPS Technologies, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with
* the distribution.
* * Neither the name of MIPS Technologies Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include "mips-string-ops.h"
#define do_strlen_word(__av) {\
if (detect_zero(x,x,_01s,_80s)) break;\
x = __av;\
cnt += sizeof (unsigned);\
}
#define do_strlen_byte(__x) {\
if ((bx.b.B##__x) == 0) break;\
++cnt;\
}
#if SMOKE_TEST_MIPS_STRLEN
#define strlen my_strlen
#endif
size_t
strlen (const char *_a)
{
int cnt = 0;
unsigned long x;
/* align the string to word boundary so we can do word at a time. */
if ((cvt_ptr_to (unsigned long, _a) & (sizeof (unsigned long) - 1)) != 0)
{
if ((cvt_ptr_to (unsigned long, _a) & 1) != 0)
{
if (get_byte (_a, 0) == 0)
return cnt;
/* set bit 1 so 2-bytes are checked and incremented. */
inc_ptr_as (char *, _a, 1);
++cnt;
}
if ((cvt_ptr_to (unsigned long, _a) & 2) != 0)
{
if (get_byte (_a, 0) == 0)
return cnt + 0;
if (get_byte (_a, 1) == 0)
return cnt + 1;
inc_ptr_as (char *, _a, 2);
cnt += 2;
}
}
#if __mips64
#error strlen: mips64 check for 4-byte alignment not implemented.
#endif
if (1)
{
def_and_set_01 (_01s);
def_and_set_80 (_80s);
/* as advantagous as it is to performance, this code cannot pre-load
the following word, nor can it prefetch the next line at the start
of the loop since the string can be at the end of a page with the
following page unmapped. There are tests in the suite to catch
any attempt to go beyond the current word. */
x = get_word (_a, 0);
while (1)
{
/* doing 8 words should cover most strings. */
do_strlen_word (get_word (_a, 1));
do_strlen_word (get_word (_a, 2));
do_strlen_word (get_word (_a, 3));
do_strlen_word (get_word (_a, 4));
do_strlen_word (get_word (_a, 5));
do_strlen_word (get_word (_a, 6));
do_strlen_word (get_word (_a, 7));
do_strlen_word (get_word (_a, 8));
inc_ptr_as (unsigned long*, _a, 8);
}
}
while (1)
{
/* pull apart the last word processed and find the zero. */
bitfields_t bx;
bx.v = x;
#if __mips64
do_strlen_byte (0);
do_strlen_byte (1);
do_strlen_byte (2);
do_strlen_byte (3);
do_strlen_byte (4);
do_strlen_byte (5);
do_strlen_byte (6);
#else
do_strlen_byte (0);
do_strlen_byte (1);
do_strlen_byte (2);
#endif
/* last byte is zero */
break;
}
return cnt;
}
#undef do_strlen_byte
#undef do_strlen_word
#if SMOKE_TEST_MIPS_STRLEN
#include <stdio.h>
char str1[] = "DHRYSTONE PROGRAM, 1'ST STRING";
char str2[] = "DHRYSTONE PROGRAM, 2'ST STRING";
char str3[] = "another string";
char str4[] = "another";
char str5[] = "somes tring";
char str6[] = "somes_tring";
char str7[16], str8[16];
static char *
chk (unsigned long mine, unsigned long libs, int *errors)
{
static char answer[1024];
char *result = mine == libs ? "PASS" : "FAIL";
sprintf (answer, "new_strlen=%d: lib_strlen=%d: %s!", mine, libs, result);
if (mine != libs)
(*errors)++;
return answer;
}
int
main (int argc, char **argv)
{
int errors = 0;
/* set -1 in one position */
str6[5] = 0xff;
/* set zero in same position with junk in following 3 */
str7[0] = str8[0] = 0;
str7[1] = 0xff;
str7[2] = 'a';
str7[3] = 2;
str8[1] = 's';
str8[2] = -2;
str8[3] = 0;
fprintf (stderr, "========== mips_strlen%s test...\n",
argv[0] ? argv[0] : "unknown strlen");
#define P(__x,__y) {\
int a = my_strlen(__x + __y);\
int b = (strlen)(__x + __y) /* library version */;\
fprintf(stderr,"%s+%d: %s\n",#__x,__y,chk(a,b,&errors));\
}
P (str1, 0);
P (str1, 1);
P (str1, 2);
P (str1, 3);
P (str2, 0);
P (str2, 1);
P (str2, 2);
P (str2, 3);
P (str3, 0);
P (str3, 1);
P (str3, 2);
P (str3, 3);
P (str4, 0);
P (str4, 1);
P (str4, 2);
P (str4, 3);
P (str5, 0);
P (str5, 1);
P (str5, 2);
P (str5, 3);
P (str6, 0);
P (str6, 1);
P (str6, 2);
P (str6, 3);
P (str7, 0);
P (str7, 1);
P (str7, 2);
P (str7, 3);
P (str8, 0);
P (str8, 1);
P (str8, 2);
P (str8, 3);
return errors;
}
#endif

View File

@ -62,24 +62,24 @@ struct stat {
};
#elif defined(__mips__)
struct stat {
unsigned long st_dev;
unsigned long __pad0[3];
unsigned int st_dev;
unsigned int __pad0[3];
unsigned long long st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned long st_uid;
unsigned long st_gid;
unsigned long st_rdev;
unsigned long __pad1[3];
unsigned int st_uid;
unsigned int st_gid;
unsigned int st_rdev;
unsigned int __pad1[3];
long long st_size;
unsigned long st_atime;
unsigned long st_atime_nsec;
unsigned long st_mtime;
unsigned long st_mtime_nsec;
unsigned long st_ctime;
unsigned long st_ctime_nsec;
unsigned long st_blksize;
unsigned long __pad2;
unsigned int st_atime;
unsigned int st_atime_nsec;
unsigned int st_mtime;
unsigned int st_mtime_nsec;
unsigned int st_ctime;
unsigned int st_ctime_nsec;
unsigned int st_blksize;
unsigned int __pad2;
unsigned long long st_blocks;
};
#elif defined(__x86_64__)

View File

@ -38,7 +38,7 @@ __BEGIN_DECLS
typedef struct { int __val[2]; } __fsid_t;
typedef __fsid_t fsid_t;
#if defined(__LP64__)
#if defined(__aarch64__) || defined(__x86_64__)
struct statfs {
uint64_t f_type;
uint64_t f_bsize;
@ -53,6 +53,22 @@ struct statfs {
uint64_t f_flags;
uint64_t f_spare[4];
};
#elif defined(__mips__) && defined(__LP64__)
/* 64-bit MIPS. */
struct statfs {
uint64_t f_type;
uint64_t f_bsize;
uint64_t f_frsize; /* Fragment size - unsupported. */
uint64_t f_blocks;
uint64_t f_bfree;
uint64_t f_files;
uint64_t f_ffree;
uint64_t f_bavail;
fsid_t f_fsid;
uint64_t f_namelen;
uint64_t f_flags;
uint64_t f_spare[5];
};
#elif defined(__mips__)
/* 32-bit MIPS (corresponds to the kernel's statfs64 type). */
struct statfs {

View File

@ -254,6 +254,10 @@ LOCAL_CFLAGS_mips := -fno-builtin-rintf -fno-builtin-rint
LOCAL_C_INCLUDES_mips := $(LOCAL_PATH)/mips
LOCAL_SRC_FILES_mips := mips/fenv.c
LOCAL_CFLAGS_mips64 := -fno-builtin-rintf -fno-builtin-rint
LOCAL_C_INCLUDES_mips64 := $(LOCAL_PATH)/mips
LOCAL_SRC_FILES_mips64 := mips/fenv.c
include $(BUILD_STATIC_LIBRARY)
#

View File

@ -30,23 +30,49 @@ union IEEEl2bits {
long double e;
struct {
#ifndef __MIPSEB__
#if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)
unsigned long manl :64;
unsigned long manh :48;
unsigned int exp :15;
unsigned int sign :1;
#else
unsigned int manl :32;
unsigned int manh :20;
unsigned int exp :11;
unsigned int sign :1;
#endif
#else
unsigned int sign :1;
unsigned int exp :11;
unsigned int manh :20;
unsigned int manl :32;
#if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)
unsigned int sign :1;
unsigned int exp :15;
unsigned long manh :48;
unsigned long manl :64;
#else
unsigned int sign :1;
unsigned int exp :11;
unsigned int manh :20;
unsigned int manl :32;
#endif
#endif
} bits;
};
#define LDBL_NBIT 0
#define mask_nbit_l(u) ((void)0)
#define LDBL_IMPLICIT_NBIT
#if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)
#define LDBL_MANH_SIZE 48
#define LDBL_MANL_SIZE 64
#define LDBL_TO_ARRAY32(u, a) do { \
(a)[0] = (uint32_t)(u).bits.manl; \
(a)[1] = (uint32_t)((u).bits.manl >> 32); \
(a)[2] = (uint32_t)(u).bits.manh; \
(a)[3] = (uint32_t)((u).bits.manh >> 32); \
} while(0)
#else
#define LDBL_MANH_SIZE 20
#define LDBL_MANL_SIZE 32
@ -54,3 +80,4 @@ union IEEEl2bits {
(a)[0] = (uint32_t)(u).bits.manl; \
(a)[1] = (uint32_t)(u).bits.manh; \
} while(0)
#endif