diff --git a/libc/Android.mk b/libc/Android.mk index 1a5bdfa77..46dd8d632 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -441,9 +441,8 @@ libc_common_src_files += \ libc_static_common_src_files += \ bionic/pthread.c \ -# this is needed for static versions of libc libc_arch_static_src_files := \ - arch-x86/bionic/dl_iterate_phdr_static.c + bionic/dl_iterate_phdr_static.c libc_arch_dynamic_src_files := else # !x86 diff --git a/libc/arch-mips/bionic/__dso_handle.S b/libc/arch-mips/bionic/__dso_handle.S new file mode 100644 index 000000000..3e801284f --- /dev/null +++ b/libc/arch-mips/bionic/__dso_handle.S @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 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 __dso_handle global variable is used by static +# C++ constructors and destructors in the binary. +# See http://www.codesourcery.com/public/cxx-abi/abi.html#dso-dtor +# + .section .bss + .align 4 + +#ifndef CRT_LEGACY_WORKAROUND + .hidden __dso_handle +#endif + + .globl __dso_handle +__dso_handle: + .long 0 diff --git a/libc/arch-mips/bionic/__dso_handle_so.S b/libc/arch-mips/bionic/__dso_handle_so.S new file mode 100644 index 000000000..77a5d7fba --- /dev/null +++ b/libc/arch-mips/bionic/__dso_handle_so.S @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2010 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 __dso_handle global variable is used by static +# C++ constructors and destructors in the binary. +# See http://www.codesourcery.com/public/cxx-abi/abi.html#dso-dtor +# + .data + .align 4 + .hidden __dso_handle + .globl __dso_handle +__dso_handle: + .long __dso_handle diff --git a/libc/arch-mips/bionic/__get_sp.S b/libc/arch-mips/bionic/__get_sp.S new file mode 100644 index 000000000..834c89d82 --- /dev/null +++ b/libc/arch-mips/bionic/__get_sp.S @@ -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 diff --git a/libc/arch-mips/bionic/__get_tls.c b/libc/arch-mips/bionic/__get_tls.c new file mode 100644 index 000000000..d1cdf0e54 --- /dev/null +++ b/libc/arch-mips/bionic/__get_tls.c @@ -0,0 +1,37 @@ +/* + * 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. + */ +void* __get_tls(void) +{ + register void *tls asm("v1"); + asm (".set push\n\t" + ".set mips32r2\n\t" + "rdhwr %0,$29\n\t" + ".set pop" + : "=r"(tls)); + return tls; +} diff --git a/libc/arch-mips/bionic/__set_tls.c b/libc/arch-mips/bionic/__set_tls.c new file mode 100644 index 000000000..38e3a505f --- /dev/null +++ b/libc/arch-mips/bionic/__set_tls.c @@ -0,0 +1,35 @@ +/* + * 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 + +extern int __set_thread_area(void *u_info); + +int __set_tls(void *ptr) +{ + return __set_thread_area(ptr); +} diff --git a/libc/arch-mips/bionic/_exit_with_stack_teardown.S b/libc/arch-mips/bionic/_exit_with_stack_teardown.S new file mode 100644 index 000000000..9974e842b --- /dev/null +++ b/libc/arch-mips/bionic/_exit_with_stack_teardown.S @@ -0,0 +1,51 @@ +/* + * 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 + + .text + +/* void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode) */ + + .type _exit_with_stack_teardown, @function + .global _exit_with_stack_teardown + .align 4 + .ent _exit_with_stack_teardown +_exit_with_stack_teardown: + move $s0,$a2 /* preserve retCode for exit() call */ + + li $v0,__NR_munmap + syscall /* the stack is destroyed by this call */ + move $a0,$s0 + li $v0,__NR_exit + syscall + + /* exit() should never return, cause a crash if it does */ + move $a0,$0 + lw $a0,($a0) + .end _exit_with_stack_teardown diff --git a/libc/arch-mips/bionic/_setjmp.S b/libc/arch-mips/bionic/_setjmp.S new file mode 100644 index 000000000..e7083ae29 --- /dev/null +++ b/libc/arch-mips/bionic/_setjmp.S @@ -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 +#include +#include + +/* + * _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) + diff --git a/libc/arch-mips/bionic/atexit.S b/libc/arch-mips/bionic/atexit.S new file mode 100644 index 000000000..7f0c82088 --- /dev/null +++ b/libc/arch-mips/bionic/atexit.S @@ -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 + .globl atexit + .hidden atexit + .type atexit, @function + .align 4 + .ent atexit +atexit: + .set noreorder + .cpload $t9 + .set reorder + la $t9, __cxa_atexit + move $a1, $0 + la $a2, __dso_handle + j $t9 + .size atexit, .-atexit + .end atexit diff --git a/libc/arch-mips/bionic/bzero.S b/libc/arch-mips/bionic/bzero.S new file mode 100644 index 000000000..67393455a --- /dev/null +++ b/libc/arch-mips/bionic/bzero.S @@ -0,0 +1,45 @@ +/* + * 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 bzero(void *s, size_t n); + */ + .type bzero, @function + .global bzero + .align 4 + .ent bzero + .set noreorder +bzero: + .cpload $t9 + move $a2,$a1 + la $t9,memset + j $t9 + move $a1,$zero + .end bzero + diff --git a/libc/arch-mips/bionic/cacheflush.c b/libc/arch-mips/bionic/cacheflush.c new file mode 100644 index 000000000..05085b623 --- /dev/null +++ b/libc/arch-mips/bionic/cacheflush.c @@ -0,0 +1,101 @@ +/* + * 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 +#include + +#ifdef DEBUG +#include +#define XLOG(...) \ + __libc_android_log_print(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; +} diff --git a/libc/arch-mips/bionic/clone.S b/libc/arch-mips/bionic/clone.S new file mode 100644 index 000000000..30fef8dc8 --- /dev/null +++ b/libc/arch-mips/bionic/clone.S @@ -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 +#include +#include + + .text + .type __pthread_clone, @function + .global __pthread_clone + .align 4 + .ent __pthread_clone + +/* + * int __pthread_clone(int (*fn)(void*), void *child_stack, + * int flags, void *arg); + */ + +__pthread_clone: + .set noreorder + .cpload $t9 + .set reorder + + # set up child stack + subu $a1,16 + sw $a0,0($a1) # fn + sw $a3,4($a1) # arg +# sw $a1+16,8($a1) # tls + + /* + * int sys_clone(int flags, void *child_stack, int *parent_tidptr, + * struct user_desc *newtls, int *child_tidptr); + */ + + move $a0,$a2 # flags +# move $a1,$a1 # child_stack + move $a2,$0 # parent_tidptr + move $a3,$0 # user_desc + and $a0,~(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID) + # make sure the kernel doesn't access child_tidptr + + li $v0,__NR_clone + syscall + + bnez $a3,.L__error + + beqz $v0,.L__thread_start + + j $ra + +.L__thread_start: + lw $a0,0($sp) # fn + lw $a1,4($sp) # arg + addu $a2,$sp,16 # tls + + # void __thread_entry(int (*func)(void*), void *arg, void *tls) + la $t9, __thread_entry + j $t9 + +.L__error: + move $a0,$v0 + la $t9,__set_errno + j $t9 + + .end __pthread_clone + + + # + # This function is defined as: + # + # pid_t __bionic_clone( int flags, void *child_stack, + # pid_t *pid, void *tls, pid_t *ctid, + # int (*fn)(void *), void* arg ); + # + # NOTE: This is not the same signature than the GLibc + # __clone function here !! Placing 'fn' and 'arg' + # at the end of the parameter list makes the + # implementation much simpler. + # + .text + .type __bionic_clone, @function + .global __bionic_clone + .align 4 + .ent __bionic_clone +__bionic_clone: + .set noreorder + .cpload $t9 + .set reorder + + # set up child stack + subu $a1,16 + lw $t0,20($sp) # fn + lw $t1,24($sp) # arg + sw $t0,0($a1) # fn + sw $t1,4($a1) # arg + + # remainder of arguments are correct for clone system call + li $v0,__NR_clone + syscall + + bnez $a3,.L__error_bc + + beqz $v0,.L__thread_start_bc + + j $ra + +.L__thread_start_bc: + lw $a0,0($sp) # fn + lw $a1,4($sp) # arg + + # void __bionic_clone_entry(int (*func)(void*), void *arg) + la $t9,__bionic_clone_entry + j $t9 + +.L__error_bc: + move $a0,$v0 + la $t9,__set_errno + j $t9 + + .end __bionic_clone + diff --git a/libc/arch-mips/bionic/crtbegin.S b/libc/arch-mips/bionic/crtbegin.S new file mode 100644 index 000000000..d85d52ce0 --- /dev/null +++ b/libc/arch-mips/bionic/crtbegin.S @@ -0,0 +1,160 @@ +/* + * 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 + .align 4 + .type __start,@function + .globl __start + .globl _start + +# this is the small startup code that is first run when +# any executable that is statically-linked with Bionic +# runs. +# +# it's purpose is to call __libc_init with appropriate +# arguments, which are: +# +# - the address of the raw data block setup by the Linux +# kernel ELF loader +# +# - address of an "onexit" function, not used on any +# platform supported by Bionic +# +# - address of the "main" function of the program. +# +# - address of the constructor list +# + + .ent __start +__start: +_start: + bal 1f +1: + .set noreorder + .cpload $ra + .set reorder + + move $a0, $sp + move $a1, $0 + la $a2, main + la $a3, 1f + subu $sp, 32 + la $t9, __libc_init + j $t9 + .end __start + +1: .long __PREINIT_ARRAY__ + .long __INIT_ARRAY__ + .long __FINI_ARRAY__ + .long __CTOR_LIST__ + .long __DTOR_LIST__ + + .section .preinit_array, "aw" + .type __PREINIT_ARRAY__, @object + .globl __PREINIT_ARRAY__ +__PREINIT_ARRAY__: + .long -1 + + .section .init_array, "aw" + .type __INIT_ARRAY__, @object + .globl __INIT_ARRAY__ +__INIT_ARRAY__: + .long -1 + + .section .fini_array, "aw" + .type __FINI_ARRAY__, @object + .globl __FINI_ARRAY__ +__FINI_ARRAY__: + .long -1 + .long __do_global_dtors_aux + + .section .ctors, "aw" + .type __CTOR_LIST__, @object + .globl __CTOR_LIST__ +__CTOR_LIST__: + .long -1 + + .section .dtors, "aw" + .type __DTOR_LIST__, @object + .globl __DTOR_LIST__ +__DTOR_LIST__: + .long -1 + + .abicalls + .text + .align 2 + .set nomips16 + .ent __do_global_dtors_aux + .type __do_global_dtors_aux, @function +__do_global_dtors_aux: + .frame $sp,32,$31 # vars= 0, regs= 1/0, args= 16, gp= 8 + .mask 0x80000000,-4 + .fmask 0x00000000,0 + .set noreorder + .cpload $25 + .set nomacro + addiu $sp,$sp,-32 + sw $31,28($sp) + .cprestore 16 + lw $2,%got(completed.1269)($28) + lbu $2,%lo(completed.1269)($2) + bne $2,$0,$L8 + nop + +$L4: + lw $2,%got(__cxa_finalize)($28) + beq $2,$0,$L6 + nop + + lw $2,%got(__dso_handle)($28) + lw $4,0($2) + lw $25,%call16(__cxa_finalize)($28) + .reloc 1f,R_MIPS_JALR,__cxa_finalize +1: jalr $25 + nop + + lw $28,16($sp) +$L6: + lw $2,%got(completed.1269)($28) + li $3,1 # 0x1 + sb $3,%lo(completed.1269)($2) +$L8: + lw $31,28($sp) + addiu $sp,$sp,32 + j $31 + nop + + .set macro + .set reorder + .end __do_global_dtors_aux + .size __do_global_dtors_aux, .-__do_global_dtors_aux + .local completed.1269 + .comm completed.1269,1,1 + .weak __cxa_finalize + +#include "__dso_handle.S" +#include "atexit.S" diff --git a/libc/arch-mips/bionic/crtbegin_so.S b/libc/arch-mips/bionic/crtbegin_so.S new file mode 100644 index 000000000..377888a01 --- /dev/null +++ b/libc/arch-mips/bionic/crtbegin_so.S @@ -0,0 +1,94 @@ +/* + * 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. + */ + .section .init_array, "aw" + .type __INIT_ARRAY__, @object + .globl __INIT_ARRAY__ +__INIT_ARRAY__: + .long -1 + + .section .fini_array, "aw" + .type __FINI_ARRAY__, @object + .globl __FINI_ARRAY__ +__FINI_ARRAY__: + .long -1 + .long __do_global_dtors_aux + + .abicalls + .text + .align 2 + .set nomips16 + .ent __do_global_dtors_aux + .type __do_global_dtors_aux, @function +__do_global_dtors_aux: + .frame $sp,32,$31 # vars= 0, regs= 1/0, args= 16, gp= 8 + .mask 0x80000000,-4 + .fmask 0x00000000,0 + .set noreorder + .cpload $25 + .set nomacro + addiu $sp,$sp,-32 + sw $31,28($sp) + .cprestore 16 + lw $2,%got(completed.1269)($28) + lbu $2,%lo(completed.1269)($2) + bne $2,$0,$L8 + nop + +$L4: + lw $2,%got(__cxa_finalize)($28) + beq $2,$0,$L6 + nop + + lw $2,%got(__dso_handle)($28) + lw $4,0($2) + lw $25,%call16(__cxa_finalize)($28) + .reloc 1f,R_MIPS_JALR,__cxa_finalize +1: jalr $25 + nop + + lw $28,16($sp) +$L6: + lw $2,%got(completed.1269)($28) + li $3,1 # 0x1 + sb $3,%lo(completed.1269)($2) +$L8: + lw $31,28($sp) + addiu $sp,$sp,32 + j $31 + nop + + .set macro + .set reorder + .end __do_global_dtors_aux + .size __do_global_dtors_aux, .-__do_global_dtors_aux + .local completed.1269 + .comm completed.1269,1,1 + .weak __cxa_finalize + +#include "__dso_handle_so.S" +#include "atexit.S" diff --git a/libc/arch-mips/bionic/crtend.S b/libc/arch-mips/bionic/crtend.S new file mode 100644 index 000000000..7a319be21 --- /dev/null +++ b/libc/arch-mips/bionic/crtend.S @@ -0,0 +1,47 @@ +/* + * 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. + */ + + .section .preinit_array, "aw" + .long 0 + + .section .init_array, "aw" + .long 0 + + .section .fini_array, "aw" + .long 0 + + .section .ctors, "aw" + .type __CTOR_END__, @object +__CTOR_END__: + .long 0 + + .section .dtors, "aw" + .type __DTOR_END__, @object +__DTOR_END__: + .long 0 + diff --git a/libc/arch-mips/bionic/crtend_so.S b/libc/arch-mips/bionic/crtend_so.S new file mode 100644 index 000000000..f09c42708 --- /dev/null +++ b/libc/arch-mips/bionic/crtend_so.S @@ -0,0 +1,5 @@ + .section .init_array, "aw" + .long 0 + + .section .fini_array, "aw" + .long 0 diff --git a/libc/arch-mips/bionic/ffs.S b/libc/arch-mips/bionic/ffs.S new file mode 100644 index 000000000..ef38b2a37 --- /dev/null +++ b/libc/arch-mips/bionic/ffs.S @@ -0,0 +1,92 @@ +/* $NetBSD: ffs.S,v 1.5 2003/04/05 23:08:52 bjh21 Exp $ */ +/* + * Copyright (c) 2001 Christopher Gilbert + * 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. The name of the company nor the name of the author 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 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. + */ + +/* + * ffs - find first set bit, this algorithm isolates the first set + * bit, then multiplies the number by 0x0450fbaf which leaves the top + * 6 bits as an index into the table. This algorithm should be a win + * over the checking each bit in turn as per the C compiled version. + * + * This is the ffs algorithm devised by d.seal and posted to comp.sys.arm on + * 16 Feb 1994. + */ + + .text + + .ent ffs + .type ffs, @function + .global ffs + .align 4 + .set noreorder +ffs: +#if (__mips==32) + subu $t0,$0,$a0 + and $a0,$t0 + clz $t0,$a0 + li $v0,32 + j $ra + subu $v0,$t0 +#else +/* Size of the ffs routine in bytes + * This is used to index .L_ffs_table from $t9 + * FIXME: there must be a better way to do this + */ +#define FFSSIZE 12*4 + subu $t0,$0,$a0 + and $a0,$t0 + /* + * now a0 has at most one set bit, call this X + * if X = 0, all further instructions are skipped + */ + sll $t0,$a0,4 /* t0 = X * 0x00000010 */ + or $a0,$t0 /* a0 = X * 0x00000011 */ + sll $t0,$a0,6 /* t0 = X * 0x00000440 */ + or $a0,$t0 /* a0 = X * 0x00000451 */ + sll $t0,$a0,16 /* t0 = X * 0x04510000 */ + subu $a0,$t0,$a0 /* a0 = X * 0x0450fbaf */ + + /* now lookup in table indexed on top 6 bits of a0 */ + srl $a0,25 + addu $t9,$a0 + j $ra + lbu $v0,FFSSIZE($t9) +.L_ffs_table: +/* 0 1 2 3 4 5 6 7 */ + .byte 0, 1, 2, 13, 3, 7, 0, 14 /* 0- 7 */ + .byte 4, 0, 8, 0, 0, 0, 0, 15 /* 8-15 */ + .byte 11, 5, 0, 0, 9, 0, 0, 26 /* 16-23 */ + .byte 0, 0, 0, 0, 0, 22, 28, 16 /* 24-31 */ + .byte 32, 12, 6, 0, 0, 0, 0, 0 /* 32-39 */ + .byte 10, 0, 0, 25, 0, 0, 21, 27 /* 40-47 */ + .byte 31, 0, 0, 0, 0, 24, 0, 20 /* 48-55 */ + .byte 30, 0, 23, 19, 29, 18, 17, 0 /* 56-63 */ + +#endif + .end ffs diff --git a/libc/arch-mips/bionic/futex_mips.S b/libc/arch-mips/bionic/futex_mips.S new file mode 100644 index 000000000..2a953caf0 --- /dev/null +++ b/libc/arch-mips/bionic/futex_mips.S @@ -0,0 +1,142 @@ +/* + * 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 + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + +/* + * __futex_wait(*ftx, val, *timespec) + * futex_syscall(*ftx, op, val, *timespec, *addr2, val3) + */ + .type __futex_wait, @function + .global __futex_wait + .align 4 + .ent __futex_wait +__futex_wait: + subu $sp,4*6 + sw $0,20($sp) /* val3 */ + sw $0,16($sp) /* addr2 */ + move $a3,$a2 /* timespec */ + move $a2,$a1 /* val */ + li $a1,FUTEX_WAIT /* op */ +# move $a0,$a0 /* ftx */ + li $v0,__NR_futex + syscall + .set noreorder + bnez $a3, 1f /* Check for error */ + neg $v0 /* Negate error number if it's valid */ + move $v0,$0 /* Otherwise return 0 */ +1: + .set reorder + addu $sp,4*6 + j $ra + .end __futex_wait + +/* + * int __futex_wake(volatile void *ftx, int count) + * int futex_syscall(*ftx, op, val, *timespec, *addr2, val3) + */ + .type __futex_wake, @function + .globl __futex_wake + .align 4 + .ent __futex_wake +__futex_wake: + subu $sp,4*6 + sw $0,20($sp) /* val3 */ + sw $0,16($sp) /* addr2 */ + move $a3,$0 /* timespec */ + move $a2,$a1 /* val */ + li $a1,FUTEX_WAKE /* op */ +# move $a0,$a0 /* ftx */ + li $v0,__NR_futex + syscall + .set noreorder + bnez $a3, 1f /* Check for error */ + neg $v0 /* Negate error number if it's valid */ + move $v0,$0 /* Otherwise return 0 */ +1: + .set reorder + addu $sp,4*6 + j $ra + .end __futex_wake + +/* __futex_syscall3(*ftx, op, val) + * futex_syscall(*ftx, op, val, *timespec, *addr2, val3) + */ + .type __futex_syscall3, @function + .global __futex_syscall3 + .align 4 + .ent __futex_syscall3 +__futex_syscall3: + subu $sp,4*6 + sw $0,20($sp) /* val3 */ + sw $0,16($sp) /* addr2 */ + move $a3,$0 /* timespec */ +# move $a2,$a2 /* val */ +# li $a1,$a1 /* op */ +# move $a0,$a0 /* ftx */ + li $v0,__NR_futex + syscall + .set noreorder + bnez $a3, 1f /* Check for error */ + neg $v0 /* Negate error number if it's valid */ + move $v0,$0 /* Otherwise return 0 */ +1: + .set reorder + addu $sp,4*6 + j $ra + .end __futex_syscall3 + +/* __futex_syscall4(*ftx, op, val) + * futex_syscall(*ftx, op, val, *timespec, *addr2, val3) + */ + .type __futex_syscall4, @function + .global __futex_syscall4 + .align 4 + .ent __futex_syscall4 +__futex_syscall4: + subu $sp,4*6 + sw $0,20($sp) /* val3 */ + sw $0,16($sp) /* addr2 */ +# move $a3,$a3 /* timespec */ +# move $a2,$a2 /* val */ +# li $a1,$a1 /* op */ +# move $a0,$a0 /* ftx */ + li $v0,__NR_futex + syscall + .set noreorder + bnez $a3, 1f /* Check for error */ + neg $v0 /* Negate error number if it's valid */ + move $v0,$0 /* Otherwise return 0 */ +1: + .set reorder + addu $sp,4*6 + j $ra + .end __futex_syscall4 diff --git a/libc/arch-mips/bionic/memcmp16.S b/libc/arch-mips/bionic/memcmp16.S new file mode 100644 index 000000000..a2b254439 --- /dev/null +++ b/libc/arch-mips/bionic/memcmp16.S @@ -0,0 +1,55 @@ +/* + * 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 + +/* + * u4 __memcmp16(const u2* s0, const u2* s1, size_t count); + */ + .type __memcmp16, @function + .global __memcmp16 + .align 4 + .ent __memcmp16 +__memcmp16: + li $t0,0 + li $t1,0 + beqz $a2,done /* 0 length string */ + beq $a0,$a1,done /* strings are identical */ + + /* Unoptimised... */ +1: lhu $t0,0($a0) + lhu $t1,0($a1) + addu $a1,2 + bne $t0,$t1,done + addu $a0,2 + subu $a2,1 + bnez $a2,1b + +done: + subu $v0,$t0,$t1 + j $ra + .end __memcmp16 diff --git a/libc/arch-mips/bionic/memmove.c b/libc/arch-mips/bionic/memmove.c new file mode 100644 index 000000000..1f4522b0c --- /dev/null +++ b/libc/arch-mips/bionic/memmove.c @@ -0,0 +1,44 @@ +/* + * 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 +#include + +void *memmove(void *dst, const void *src, size_t n) +{ + 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; + } +} diff --git a/libc/arch-mips/bionic/pipe.S b/libc/arch-mips/bionic/pipe.S new file mode 100644 index 000000000..85565692a --- /dev/null +++ b/libc/arch-mips/bionic/pipe.S @@ -0,0 +1,49 @@ +/* + * 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 + + .text + +/* int pipe(int[]) */ + + .type pipe,@function + .global pipe + .align 4 + .ent pipe +pipe: + .set noreorder + + li $v0,__NR_pipe + syscall /* syscall returns results in v0,v1 */ + + sw $v0,0($a0) + sw $v1,4($a0) + j $ra + move $v0,$zero + .end pipe diff --git a/libc/arch-mips/bionic/setjmp.S b/libc/arch-mips/bionic/setjmp.S new file mode 100644 index 000000000..7c21195b6 --- /dev/null +++ b/libc/arch-mips/bionic/setjmp.S @@ -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 +#include +#include + +/* + * 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) diff --git a/libc/arch-mips/bionic/sigsetjmp.S b/libc/arch-mips/bionic/sigsetjmp.S new file mode 100644 index 000000000..b05454c28 --- /dev/null +++ b/libc/arch-mips/bionic/sigsetjmp.S @@ -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 +#include +#include + +/* + * 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) diff --git a/libc/arch-mips/bionic/vfork.S b/libc/arch-mips/bionic/vfork.S new file mode 100644 index 000000000..2e2e4ff83 --- /dev/null +++ b/libc/arch-mips/bionic/vfork.S @@ -0,0 +1,56 @@ +/* + * 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 + + .text + +/* int vfork() implemented using clone() */ + + .type vfork, @function + .global vfork + .align 4 + .ent vfork +vfork: + .set noreorder + .cpload $t9 + + li $a0, 0x4112 /* CLONE_VM | CLONE_VFORK | SIGCHLD */ + move $a1, $sp + li $v0, __NR_clone + syscall + bnez $a3,1f + nop + + j $ra + nop +1: + la $t9,__set_errno + j $t9 + move $a0,$v0 + .end vfork diff --git a/libc/arch-mips/include/endian.h b/libc/arch-mips/include/endian.h new file mode 100644 index 000000000..6d4ca4e82 --- /dev/null +++ b/libc/arch-mips/include/endian.h @@ -0,0 +1,77 @@ +/* $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_ + +#if defined(__MIPSEL__) +#define _BYTE_ORDER _LITTLE_ENDIAN +#endif +#if defined(__MIPSEB__) +#define _BYTE_ORDER _BIG_ENDIAN +#endif + +#if !defined(_BYTE_ORDER) && !defined(lint) +#error "__MIPSEL__ or __MIPSEB__ must be defined to define BYTE_ORDER!!!" +#endif + +#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__ */ + + +#include + +#define __STRICT_ALIGNMENT + +#endif /* _MIPS64_ENDIAN_H_ */ diff --git a/libc/arch-mips/include/machine/_types.h b/libc/arch-mips/include/machine/_types.h new file mode 100644 index 000000000..1cc6c21a1 --- /dev/null +++ b/libc/arch-mips/include/machine/_types.h @@ -0,0 +1,145 @@ +/* $OpenBSD: _types.h,v 1.5 2008/07/21 20:50:54 martynas Exp $ */ + +/*- + * Copyright (c) 1990, 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. + * + * @(#)types.h 8.3 (Berkeley) 1/5/94 + * @(#)ansi.h 8.2 (Berkeley) 1/4/94 + */ + +#ifndef _MIPS64__TYPES_H_ +#define _MIPS64__TYPES_H_ + +/* + * We need to handle the various ISA levels for sizes. + */ +#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) */ + +/* 7.18.1.1 Exact-width integer types */ +typedef __signed char __int8_t; +typedef unsigned char __uint8_t; +typedef short __int16_t; +typedef unsigned short __uint16_t; +typedef int __int32_t; +typedef unsigned int __uint32_t; +/* LONGLONG */ +typedef long long __int64_t; +/* LONGLONG */ +typedef unsigned long long __uint64_t; + +/* 7.18.1.2 Minimum-width integer types */ +typedef __int8_t __int_least8_t; +typedef __uint8_t __uint_least8_t; +typedef __int16_t __int_least16_t; +typedef __uint16_t __uint_least16_t; +typedef __int32_t __int_least32_t; +typedef __uint32_t __uint_least32_t; +typedef __int64_t __int_least64_t; +typedef __uint64_t __uint_least64_t; + +/* 7.18.1.3 Fastest minimum-width integer types */ +typedef __int32_t __int_fast8_t; +typedef __uint32_t __uint_fast8_t; +typedef __int32_t __int_fast16_t; +typedef __uint32_t __uint_fast16_t; +typedef __int32_t __int_fast32_t; +typedef __uint32_t __uint_fast32_t; +typedef __int64_t __int_fast64_t; +typedef __uint64_t __uint_fast64_t; + +/* 7.18.1.4 Integer types capable of holding object pointers */ +typedef long __intptr_t; +typedef unsigned long __uintptr_t; + +/* 7.18.1.5 Greatest-width integer types */ +typedef __int64_t __intmax_t; +typedef __uint64_t __uintmax_t; + +/* Register size */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4) +typedef __int64_t __register_t; +typedef __int64_t f_register_t; /* XXX */ +#else +typedef __int32_t __register_t; +typedef __int32_t f_register_t; /* XXX */ +#endif + +/* VM system types */ +typedef unsigned long __vaddr_t; +typedef unsigned long __paddr_t; +typedef unsigned long __vsize_t; +typedef unsigned long __psize_t; + +/* Standard system types */ +typedef int __clock_t; +typedef int __clockid_t; +typedef double __double_t; +typedef float __float_t; +typedef long long __off_t; +typedef long __ptrdiff_t; +/*typedef unsigned long __size_t;*/ +typedef long __ssize_t; +typedef int __time_t; +typedef int __timer_t; +#if defined(__GNUC__) && __GNUC__ >= 3 +typedef __builtin_va_list __va_list; +#else +typedef char * __va_list; +#endif + +/* Wide character support types */ +#ifndef __cplusplus +typedef int __wchar_t; +#endif +typedef int __wint_t; +typedef int __rune_t; +typedef void * __wctrans_t; +typedef void * __wctype_t; + +#ifdef __MIPSEB__ +#define _BYTE_ORDER _BIG_ENDIAN +#else +#define _BYTE_ORDER _LITTLE_ENDIAN +#endif + +#if defined(_KERNEL) +typedef struct label_t { + __register_t val[14]; +} label_t; +#endif + +/* XXX check why this still has to be defined. pmap.c issue? */ +#define __SWAP_BROKEN + +/* Feature test macros */ +#define __HAVE_TIMECOUNTER + +#endif /* _MIPS64__TYPES_H_ */ diff --git a/libc/arch-mips/include/machine/asm.h b/libc/arch-mips/include/machine/asm.h new file mode 100644 index 000000000..43dbc09a8 --- /dev/null +++ b/libc/arch-mips/include/machine/asm.h @@ -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 + +#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) +#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, 32; \ + SAVE_GP(16); \ + sw ra, 28(sp); \ + sw gp, 24(sp); \ + .set noat; \ + .set noreorder; \ + move AT, ra; \ + jal _mcount; \ + PTR_SUBU sp, sp, 8; \ + lw ra, 28(sp); \ + PTR_ADDU sp, sp, 32; \ + .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 */ diff --git a/libc/arch-mips/include/machine/cdefs.h b/libc/arch-mips/include/machine/cdefs.h new file mode 100644 index 000000000..d52376ae1 --- /dev/null +++ b/libc/arch-mips/include/machine/cdefs.h @@ -0,0 +1,47 @@ +/* $OpenBSD: cdefs.h,v 1.4 2006/01/10 00:04:04 millert Exp $ */ + +/* + * Copyright (c) 2002-2003 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 _MIPS_CDEFS_H_ +#define _MIPS_CDEFS_H_ + +#if defined(lint) +#define __indr_reference(sym,alias) __lint_equal__(sym,alias) +#define __warn_references(sym,msg) +#define __weak_alias(alias,sym) __lint_equal__(sym,alias) +#elif defined(__GNUC__) && defined(__STDC__) +#define __weak_alias(alias,sym) \ + __asm__(".weak " __STRING(alias) " ; " \ + __STRING(alias) " = " __STRING(sym)) +#define __warn_references(sym,msg) \ + __asm__(".section .gnu.warning." __STRING(sym) \ + " ; .ascii \"" msg "\" ; .text") +#define __indr_references(sym,msg) /* nothing */ +#endif + +#endif /* !_MIPS_CDEFS_H_ */ diff --git a/libc/arch-mips/include/machine/exec.h b/libc/arch-mips/include/machine/exec.h new file mode 100644 index 000000000..3c63f7435 --- /dev/null +++ b/libc/arch-mips/include/machine/exec.h @@ -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_ */ diff --git a/libc/arch-mips/include/machine/ieee.h b/libc/arch-mips/include/machine/ieee.h new file mode 100644 index 000000000..520a77b7c --- /dev/null +++ b/libc/arch-mips/include/machine/ieee.h @@ -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 diff --git a/libc/arch-mips/include/machine/internal_types.h b/libc/arch-mips/include/machine/internal_types.h new file mode 100644 index 000000000..529079fc9 --- /dev/null +++ b/libc/arch-mips/include/machine/internal_types.h @@ -0,0 +1,8 @@ +/* $OpenBSD: internal_types.h,v 1.1 2004/08/06 20:56:02 pefo Exp $ */ +/* Public domain */ +#ifndef _MIPS64_INTERNAL_TYPES_H_ +#define _MIPS64_INTERNAL_TYPES_H_ + +/* Machine special type definitions */ + +#endif diff --git a/libc/arch-mips/include/machine/kernel.h b/libc/arch-mips/include/machine/kernel.h new file mode 100644 index 000000000..69ad40cd1 --- /dev/null +++ b/libc/arch-mips/include/machine/kernel.h @@ -0,0 +1,42 @@ +/* + * 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. + */ +#ifndef _ARCH_MIPS_KERNEL_H +#define _ARCH_MIPS_KERNEL_H + +/* this file contains kernel-specific definitions that were optimized out of + our processed kernel headers, but still useful nonetheless... */ + +typedef unsigned long __kernel_blkcnt_t; +typedef unsigned long __kernel_blksize_t; + +/* these aren't really defined by the kernel headers though... */ +typedef unsigned long __kernel_fsblkcnt_t; +typedef unsigned long __kernel_fsfilcnt_t; +typedef unsigned int __kernel_id_t; + +#endif /* _ARCH_MIPS_KERNEL_H */ diff --git a/libc/arch-mips/include/machine/limits.h b/libc/arch-mips/include/machine/limits.h new file mode 100644 index 000000000..339444dec --- /dev/null +++ b/libc/arch-mips/include/machine/limits.h @@ -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 + +#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_ */ diff --git a/libc/arch-mips/include/machine/regdef.h b/libc/arch-mips/include/machine/regdef.h new file mode 100644 index 000000000..ae1839239 --- /dev/null +++ b/libc/arch-mips/include/machine/regdef.h @@ -0,0 +1,92 @@ +/* $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_ + +#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_ */ diff --git a/libc/arch-mips/include/machine/regnum.h b/libc/arch-mips/include/machine/regnum.h new file mode 100644 index 000000000..bfe128047 --- /dev/null +++ b/libc/arch-mips/include/machine/regnum.h @@ -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_ */ diff --git a/libc/arch-mips/include/machine/setjmp.h b/libc/arch-mips/include/machine/setjmp.h new file mode 100644 index 000000000..55ba7bebb --- /dev/null +++ b/libc/arch-mips/include/machine/setjmp.h @@ -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_ */ diff --git a/libc/arch-mips/include/machine/signal.h b/libc/arch-mips/include/machine/signal.h new file mode 100644 index 000000000..4efb856f0 --- /dev/null +++ b/libc/arch-mips/include/machine/signal.h @@ -0,0 +1,147 @@ +/* $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 + +#if !defined(__LANGUAGE_ASSEMBLY) +#include + +/* + * Machine-dependent signal definitions + */ +typedef int sig_atomic_t; + +#if __BSD_VISIBLE || __XPG_VISIBLE >= 420 + +/* + * Information pushed on stack when a signal is delivered. + * This is used by the kernel to restore state following + * execution of the signal handler. It is also made available + * to the handler to allow it to restore state properly if + * a non-standard exit is performed. + */ + +#if defined(__ANDROID__) + +/* + * The Linux and OpenBSD sigcontext structures are slightly different + * This is the Linux O32 ABI compatible sigcontext + */ + +struct sigcontext { + unsigned int sc_regmask; + unsigned int sc_status; + unsigned long long sc_pc; + unsigned long long sc_regs[32]; + unsigned long long sc_fpregs[32]; + unsigned int sc_acx; + unsigned int sc_fpc_csr; + unsigned int sc_fpc_eir; + unsigned int sc_used_math; + unsigned int sc_dsp; + unsigned long long sc_mdhi; + unsigned long long sc_mdlo; + unsigned long sc_hi1; + unsigned long sc_lo1; + unsigned long sc_hi2; + unsigned long sc_lo2; + unsigned long sc_hi3; + unsigned long sc_lo3; +}; + +#else + +struct sigcontext { + long sc_onstack; /* sigstack state to restore */ + long sc_mask; /* signal mask to restore */ + __register_t sc_pc; /* pc at time of signal */ + __register_t sc_regs[32]; /* processor regs 0 to 31 */ + __register_t mullo; /* mullo and mulhi registers... */ + __register_t mulhi; /* mullo and mulhi registers... */ + f_register_t sc_fpregs[33]; /* fp regs 0 to 31 and csr */ + long sc_fpused; /* fp has been used */ + long sc_fpc_eir; /* floating point exception instruction reg */ + long xxx[8]; /* XXX reserved */ +}; +#endif +#endif /* __BSD_VISIBLE || __XPG_VISIBLE >= 420 */ + +#else /* __LANGUAGE_ASSEMBLY */ + +#ifdef __ANDROID__ + +#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_FPC_CSR (SC_ACX+1*REGSZ) +#define SC_FPC_EIR (SC_ACX+2*REGSZ) +#define SC_USED_MATH (SC_ACX+3*REGSZ) +#define SC_DSP (SC_ACX+4*REGSZ) +#define SC_MDHI (SC_ACX+5*REGSZ) +#define SC_MDLO (SC_MDHI+8) +#define SC_HI1 (SC_MDLO+8) +#define SC_LO1 (SC_HI1+1*REGSZ) +#define SC_HI2 (SC_HI1+2*REGSZ) +#define SC_LO2 (SC_HI1+3*REGSZ) +#define SC_HI3 (SC_HI1+4*REGSZ) +#define SC_LO3 (SC_HI1+5*REGSZ) +/* OpenBSD compatibility */ +#define SC_MASK SC_REGMASK +#define SC_FPUSED SC_USED_MATH + +#else + +#define SC_ONSTACK (0 * REGSZ) +#define SC_MASK (1 * REGSZ) +#define SC_PC (2 * REGSZ) +#define SC_REGS (3 * REGSZ) +#define SC_MULLO (35 * REGSZ) +#define SC_MULHI (36 * REGSZ) +#define SC_FPREGS (37 * REGSZ) +#define SC_FPUSED (70 * REGSZ) +#define SC_FPC_EIR (71 * REGSZ) + +#endif /* __ANDROID__ */ + +#endif /* __LANGUAGE_ASSEMBLY */ + +#endif /* !_MIPS_SIGNAL_H_ */ diff --git a/libc/arch-mips/string/memcpy.S b/libc/arch-mips/string/memcpy.S new file mode 100644 index 000000000..aabdfcfdc --- /dev/null +++ b/libc/arch-mips/string/memcpy.S @@ -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 + ************************************************************************/ diff --git a/libc/arch-mips/string/memset.S b/libc/arch-mips/string/memset.S new file mode 100644 index 000000000..a1c5055c4 --- /dev/null +++ b/libc/arch-mips/string/memset.S @@ -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 + ************************************************************************/ + diff --git a/libc/arch-mips/string/mips-string-ops.h b/libc/arch-mips/string/mips-string-ops.h new file mode 100644 index 000000000..50f7e3a9f --- /dev/null +++ b/libc/arch-mips/string/mips-string-ops.h @@ -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 B0:8, B1:8, B2:8, B3:8, B4:8, B5:8, B6:8, B7:8; +} bits_t; +#else +typedef struct bits +{ + unsigned 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 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 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 __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 __x = 0x8080808080808080ul +#define def_and_set_01(__x) unsigned __x = 0x0101010101010101ul +#else +#define def_and_set_80(__x) unsigned __x = 0x80808080ul +#define def_and_set_01(__x) unsigned __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 *) (__x))[__idx]) +#define set_word(__x,__idx,__fill) ((unsigned *) (__x))[__idx] = (__fill) +#define inc_ptr_as(__type,__x,__inc) __x = (void *) (((__type) __x) + (__inc)) +#define cvt_ptr_to(__type,__x) ((__type) (__x)) + +#endif diff --git a/libc/arch-mips/string/mips_strlen.c b/libc/arch-mips/string/mips_strlen.c new file mode 100644 index 000000000..9fb7e6a85 --- /dev/null +++ b/libc/arch-mips/string/mips_strlen.c @@ -0,0 +1,223 @@ +/* + * 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 "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 + +int +strlen (const void *_a) +{ + int cnt = 0; + unsigned x; + + /* align the string to word boundary so we can do word at a time. */ + if ((cvt_ptr_to (unsigned, _a) & (sizeof (unsigned) - 1)) != 0) + { + if ((cvt_ptr_to (unsigned, _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, _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 *, _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 +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 mine, unsigned 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 diff --git a/libc/arch-x86/bionic/dl_iterate_phdr_static.c b/libc/arch-x86/bionic/dl_iterate_phdr_static.c deleted file mode 100644 index fd1210682..000000000 --- a/libc/arch-x86/bionic/dl_iterate_phdr_static.c +++ /dev/null @@ -1,74 +0,0 @@ -/* bionic/arch-x86/bionic/dl_iterate_phdr_static.c -** -** Copyright 2006, The Android Open Source Project -** -** 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 Google 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 Google 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 Google 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. -*/ - -#include -#include - -/* TODO: Move this into a header that linker.h can also pull it in. - * Silly to have same struct in 2 places. This is temporary. */ -struct dl_phdr_info -{ - Elf32_Addr dlpi_addr; - const char *dlpi_name; - const Elf32_Phdr *dlpi_phdr; - Elf32_Half dlpi_phnum; -}; - -/* Dynamic binaries get this from the dynamic linker (system/linker), which - * we don't pull in for static bins. We also don't have a list of so's to - * iterate over, since there's really only a single monolithic blob of - * code/data. - * - * All we need to do is to find where the executable is in memory, and grab the - * phdr and phnum from there. - */ - -/* ld provides this to us in the default link script */ -extern void *__executable_start; - -int -dl_iterate_phdr(int (*cb)(struct dl_phdr_info *info, size_t size, void *data), - void *data) -{ - struct dl_phdr_info dl_info; - Elf32_Ehdr *ehdr = (Elf32_Ehdr *) &__executable_start; - Elf32_Phdr *phdr = (Elf32_Phdr *)((unsigned long)ehdr + ehdr->e_phoff); - - /* TODO: again, copied from linker.c. Find a better home for this - * later. */ - if (ehdr->e_ident[EI_MAG0] != ELFMAG0) return -1; - if (ehdr->e_ident[EI_MAG1] != ELFMAG1) return -1; - if (ehdr->e_ident[EI_MAG2] != ELFMAG2) return -1; - if (ehdr->e_ident[EI_MAG3] != ELFMAG3) return -1; - - dl_info.dlpi_addr = 0; - dl_info.dlpi_name = NULL; - dl_info.dlpi_phdr = phdr; - dl_info.dlpi_phnum = ehdr->e_phnum; - return cb(&dl_info, sizeof (struct dl_phdr_info), data); -} - diff --git a/libc/bionic/dl_iterate_phdr_static.c b/libc/bionic/dl_iterate_phdr_static.c new file mode 100644 index 000000000..4eecff6fc --- /dev/null +++ b/libc/bionic/dl_iterate_phdr_static.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2006 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 +#include + +/* TODO: Move this into a header that linker.h can also pull it in. + * Silly to have same struct in 2 places. This is temporary. */ +struct dl_phdr_info +{ + Elf32_Addr dlpi_addr; + const char *dlpi_name; + const Elf32_Phdr *dlpi_phdr; + Elf32_Half dlpi_phnum; +}; + +/* Dynamic binaries get this from the dynamic linker (system/linker), which + * we don't pull in for static bins. We also don't have a list of so's to + * iterate over, since there's really only a single monolithic blob of + * code/data. + * + * All we need to do is to find where the executable is in memory, and grab the + * phdr and phnum from there. + */ + +/* ld provides this to us in the default link script */ +extern void *__executable_start; + +int +dl_iterate_phdr(int (*cb)(struct dl_phdr_info *info, size_t size, void *data), + void *data) +{ + struct dl_phdr_info dl_info; + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) &__executable_start; + Elf32_Phdr *phdr = (Elf32_Phdr *)((unsigned long)ehdr + ehdr->e_phoff); + + /* TODO: again, copied from linker.c. Find a better home for this + * later. */ + if (ehdr->e_ident[EI_MAG0] != ELFMAG0) return -1; + if (ehdr->e_ident[EI_MAG1] != ELFMAG1) return -1; + if (ehdr->e_ident[EI_MAG2] != ELFMAG2) return -1; + if (ehdr->e_ident[EI_MAG3] != ELFMAG3) return -1; + + dl_info.dlpi_addr = 0; + dl_info.dlpi_name = NULL; + dl_info.dlpi_phdr = phdr; + dl_info.dlpi_phnum = ehdr->e_phnum; + return cb(&dl_info, sizeof (struct dl_phdr_info), data); +} diff --git a/libc/include/sys/cachectl.h b/libc/include/sys/cachectl.h new file mode 100644 index 000000000..57e6ae787 --- /dev/null +++ b/libc/include/sys/cachectl.h @@ -0,0 +1,36 @@ +/* + * 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. + */ +#ifndef _SYS_CACHECTL_H +#define _SYS_CACHECTL_H 1 + +#ifdef __mips__ +#include +extern int __cachectl (void *addr, __const int nbytes, __const int op); +extern int _flush_cache (char *addr, __const int nbytes, __const int op); +#endif +#endif /* sys/cachectl.h */