diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/config.gcc | 16 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 7 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 10 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 8 | ||||
-rw-r--r-- | gcc/config/mips/sde.h | 13 | ||||
-rw-r--r-- | gcc/config/mips/sdemtk.h | 108 | ||||
-rw-r--r-- | gcc/config/mips/sdemtk.opt | 24 | ||||
-rw-r--r-- | gcc/config/mips/t-sdemtk | 26 | ||||
-rwxr-xr-x | gcc/configure | 2 | ||||
-rw-r--r-- | gcc/configure.ac | 2 | ||||
-rw-r--r-- | gcc/gthr-mipssde.h | 227 |
12 files changed, 442 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 109aa16d295..418aba5234d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2007-09-14 Nigel Stephens <nigel@mips.com> + David Ung <davidu@mips.com> + Thiemo Seufer <ths@mips.com> + Richard Sandiford <richard@codesourcery.com> + + * config.gcc (mips*-sde-elf*): Add support for the SDE C libraries. + * configure.ac: Add a mipssde threading type. + * configure: Regenerate. + * config/mips/sdemtk.h: New file. + * config/mips/t-sdemtk: Likewise. + * config/mips/sdemtk.opt: Likewise. + * gthr-mipssde.h: Likewise. + * config/mips/sde.h (FUNCTION_PROFILER): Move to config/mips/sdemtk.h. + * config/mips/mips.h (MIPS_SAVE_REG_FOR_PROFILING_P): New macro. + (MIPS_ICACHE_SYNC): New macro, split from ... + * config/mips/mips.md (clear_cache): ...here. + * config/mips/mips.c (mips_save_reg_p): Check + MIPS_SAVE_REG_FOR_PROFILING_P on profiled functions. + (build_mips16_function_stub): Use targetm.strip_name_encoding. + (build_mips16_call_stub): Likewise. + 2007-09-14 Richard Sandiford <richard@codesourcery.com> * Makefile.in (stmp-int-hdrs): Depend on fixinc_list. diff --git a/gcc/config.gcc b/gcc/config.gcc index 6101365138c..e512b249290 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1688,6 +1688,22 @@ mips*-*-openbsd*) mips*-sde-elf*) tm_file="elfos.h ${tm_file} mips/elf.h mips/sde.h" tmake_file="mips/t-sde mips/t-libgcc-mips16" + case "${with_newlib}" in + yes) + # newlib / libgloss. + ;; + *) + # MIPS toolkit libraries. + tm_file="$tm_file mips/sdemtk.h" + tmake_file="$tmake_file mips/t-sdemtk" + extra_options="$extra_options mips/sdemtk.opt" + case ${enable_threads} in + "" | yes | mipssde) + thread_file='mipssde' + ;; + esac + ;; + esac case ${target} in mipsisa32r2*) tm_defines="MIPS_ISA_DEFAULT=33 MIPS_ABI_DEFAULT=ABI_32" diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 410f7d7a7c7..5c26195dc23 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -7473,6 +7473,10 @@ mips_save_reg_p (unsigned int regno) if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) return true; + /* Check for registers that must be saved for FUNCTION_PROFILER. */ + if (current_function_profile && MIPS_SAVE_REG_FOR_PROFILING_P (regno)) + return true; + /* We need to save the incoming return address if it is ever clobbered within the function, if __builtin_eh_return is being used to set a different return address, or if a stub is being used to return a @@ -9701,6 +9705,7 @@ build_mips16_function_stub (FILE *file) unsigned int f; fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); + fnname = targetm.strip_name_encoding (fnname); secname = (char *) alloca (strlen (fnname) + 20); sprintf (secname, ".mips16.fn.%s", fnname); stubname = (char *) alloca (strlen (fnname) + 20); @@ -9937,7 +9942,7 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code) /* We know the function we are going to call. If we have already built a stub, we don't need to do anything further. */ - fnname = XSTR (fn, 0); + fnname = targetm.strip_name_encoding (XSTR (fn, 0)); for (l = mips16_stubs; l != NULL; l = l->next) if (strcmp (l->name, fnname) == 0) break; diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index c8cad32133f..55e605a8c06 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2152,6 +2152,9 @@ typedef struct mips_args { fprintf (FILE, "\t.set\tat\n"); \ } +/* The profiler preserves all interesting registers, including $31. */ +#define MIPS_SAVE_REG_FOR_PROFILING_P(REGNO) false + /* No mips port has ever used the profiler counter word, so don't emit it or the label for it. */ @@ -2227,6 +2230,13 @@ typedef struct mips_args { #define CACHE_FLUSH_FUNC "_flush_cache" #endif +#define MIPS_ICACHE_SYNC(ADDR, SIZE) \ + /* Flush both caches. We need to flush the data cache in case \ + the system has a write-back cache. */ \ + emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mips_cache_flush_func), \ + 0, VOIDmode, 3, ADDR, Pmode, SIZE, Pmode, \ + GEN_INT (3), TYPE_MODE (integer_type_node)) + /* A C statement to initialize the variable parts of a trampoline. ADDR is an RTX for the address of the trampoline; FNADDR is an RTX for the address of the nested function; STATIC_CHAIN is an diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 299980657ec..842fa082b34 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -4274,12 +4274,8 @@ { rtx len = gen_reg_rtx (Pmode); emit_insn (gen_sub3_insn (len, operands[1], operands[0])); - /* Flush both caches. We need to flush the data cache in case - the system has a write-back cache. */ - emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mips_cache_flush_func), - 0, VOIDmode, 3, operands[0], Pmode, len, Pmode, - GEN_INT (3), TYPE_MODE (integer_type_node)); - } + MIPS_ICACHE_SYNC (operands[0], len); + } DONE; }") diff --git a/gcc/config/mips/sde.h b/gcc/config/mips/sde.h index 7573bd62b46..35a8ad1718c 100644 --- a/gcc/config/mips/sde.h +++ b/gcc/config/mips/sde.h @@ -130,19 +130,6 @@ Boston, MA 02111-1307, USA. */ #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 #endif -/* This version of _mcount does not pop 2 words from the stack. */ -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ - { \ - fprintf (FILE, "\t.set\tnoat\n"); \ - /* MIPS16 code passes saved $ra in $v1 instead of $at. */ \ - fprintf (FILE, "\tmove\t%s,%s\n", \ - reg_names[GP_REG_FIRST + (TARGET_MIPS16 ? 3 : 1)], \ - reg_names[GP_REG_FIRST + 31]); \ - fprintf (FILE, "\tjal\t_mcount\n"); \ - fprintf (FILE, "\t.set\tat\n"); \ - } - /* Force all .init and .fini entries to be 32-bit, not mips16, so that in a mixed environment they are all the same mode. The crti.asm and crtn.asm files will also be compiled as 32-bit due to the diff --git a/gcc/config/mips/sdemtk.h b/gcc/config/mips/sdemtk.h new file mode 100644 index 00000000000..9d20b471902 --- /dev/null +++ b/gcc/config/mips/sdemtk.h @@ -0,0 +1,108 @@ +/* Definitions of target machine for GNU compiler. + MIPS SDE version, for use with the SDE C library rather than newlib. + Copyright (C) 2007 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_assert ("system=sde"); \ + builtin_assert ("system=posix"); \ + builtin_define ("__SDE_MIPS__"); \ + \ + /* Deprecated: use __mips_isa_rev >= 2. */ \ + if (ISA_MIPS32R2) \ + builtin_define ("__mipsr2"); \ + \ + /* Deprecated: use __mips_fpr == 64. */ \ + if (TARGET_FLOAT64) \ + builtin_define ("__mipsfp64"); \ + \ + if (TARGET_NO_FLOAT) \ + { \ + builtin_define ("__NO_FLOAT"); \ + builtin_define ("__mips_no_float"); \ + } \ + else if (TARGET_SOFT_FLOAT_ABI) \ + builtin_define ("__SOFT_FLOAT"); \ + else if (TARGET_SINGLE_FLOAT) \ + builtin_define ("__SINGLE_FLOAT"); \ + \ + if (TARGET_BIG_ENDIAN) \ + { \ + builtin_assert ("endian=big"); \ + builtin_assert ("cpu=mipseb"); \ + } \ + else \ + { \ + builtin_assert ("endian=little"); \ + builtin_assert ("cpu=mipsel"); \ + } \ + } \ + while (0) + +#undef SUBTARGET_OVERRIDE_OPTIONS +#define SUBTARGET_OVERRIDE_OPTIONS \ + do \ + { \ + if (TARGET_NO_FLOAT) \ + { \ + target_flags |= MASK_SOFT_FLOAT_ABI; \ + target_flags_explicit |= MASK_SOFT_FLOAT_ABI; \ + } \ + } \ + while (0) + +/* For __clear_cache in libgcc2.c. */ +#ifdef IN_LIBGCC2 +extern void mips_sync_icache (void *beg, unsigned long len); +#undef CLEAR_INSN_CACHE +#define CLEAR_INSN_CACHE(beg, end) \ + mips_sync_icache (beg, end - beg) +#endif + +/* For mips_cache_flush_func in mips.opt. */ +#undef CACHE_FLUSH_FUNC +#define CACHE_FLUSH_FUNC "mips_sync_icache" + +/* For inline code which needs to sync the icache and dcache, + noting that the SDE library takes arguments (address, size). */ +#undef MIPS_ICACHE_SYNC +#define MIPS_ICACHE_SYNC(ADDR, SIZE) \ + emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mips_cache_flush_func), \ + 0, VOIDmode, 2, ADDR, Pmode, \ + SIZE, TYPE_MODE (sizetype)) + +/* This version of _mcount does not pop 2 words from the stack. */ +#undef FUNCTION_PROFILER +#define FUNCTION_PROFILER(FILE, LABELNO) \ + { \ + fprintf (FILE, "\t.set\tnoat\n"); \ + /* MIPS16 code passes saved $ra in $v1 instead of $at. */ \ + fprintf (FILE, "\tmove\t%s,%s\n", \ + reg_names[GP_REG_FIRST + (TARGET_MIPS16 ? 3 : 1)], \ + reg_names[GP_REG_FIRST + 31]); \ + fprintf (FILE, "\tjal\t_mcount\n"); \ + fprintf (FILE, "\t.set\tat\n"); \ + } + +/* ...nor does the call sequence preserve $31. */ +#undef MIPS_SAVE_REG_FOR_PROFILING_P +#define MIPS_SAVE_REG_FOR_PROFILING_P(REGNO) ((REGNO) == GP_REG_FIRST + 31) diff --git a/gcc/config/mips/sdemtk.opt b/gcc/config/mips/sdemtk.opt new file mode 100644 index 00000000000..1f7531bed91 --- /dev/null +++ b/gcc/config/mips/sdemtk.opt @@ -0,0 +1,24 @@ +; Options for the MIPS SDE configuration. +; +; Copyright (C) 2007 Free Software Foundation, Inc. +; +; This file is part of GCC. +; +; GCC is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License as published by the Free +; Software Foundation; either version 2, or (at your option) any later +; version. +; +; GCC is distributed in the hope that it will be useful, but WITHOUT +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +; License for more details. +; +; You should have received a copy of the GNU General Public License +; along with GCC; see the file COPYING. If not, write to the Free +; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +; 02110-1301, USA. + +mno-float +Target Report RejectNegative Var(TARGET_NO_FLOAT) +Prevent the use of all floating-point operations diff --git a/gcc/config/mips/t-sdemtk b/gcc/config/mips/t-sdemtk new file mode 100644 index 00000000000..5169dee53b3 --- /dev/null +++ b/gcc/config/mips/t-sdemtk @@ -0,0 +1,26 @@ +# Override newlib settings in t-sde and set up for building +# against SDE header files and libraries. + +MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 msoft-float/mno-float/mfp64 +MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips16 sof nof f64 + +# Remove stdarg.h and stddef.h from USER_H. +USER_H = $(srcdir)/ginclude/float.h \ + $(srcdir)/ginclude/iso646.h \ + $(srcdir)/ginclude/stdbool.h \ + $(srcdir)/ginclude/varargs.h \ + $(EXTRA_HEADERS) + +# Don't run fixinclude +STMP_FIXINC = stmp-sdefixinc +stmp-sdefixinc: gsyslimits.h + rm -rf include; mkdir include + chmod a+rx include + rm -f include/syslimits.h + cp $(srcdir)/gsyslimits.h include/syslimits.h + chmod a+r include/syslimits.h + $(STAMP) stmp-sdefixinc + +# Don't build FPBIT and DPBIT; we'll be using the SDE soft-float library. +FPBIT = +DPBIT = diff --git a/gcc/configure b/gcc/configure index 06477542263..a1928534aae 100755 --- a/gcc/configure +++ b/gcc/configure @@ -12445,7 +12445,7 @@ case ${enable_threads} in target_thread_file='single' ;; aix | dce | gnat | irix | posix | posix95 | rtems | \ - single | solaris | vxworks | win32 ) + single | solaris | vxworks | win32 | mipssde) target_thread_file=${enable_threads} ;; *) diff --git a/gcc/configure.ac b/gcc/configure.ac index fae5ec0d9f3..9627d36e363 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1342,7 +1342,7 @@ case ${enable_threads} in target_thread_file='single' ;; aix | dce | gnat | irix | posix | posix95 | rtems | \ - single | solaris | vxworks | win32 ) + single | solaris | vxworks | win32 | mipssde) target_thread_file=${enable_threads} ;; *) diff --git a/gcc/gthr-mipssde.h b/gcc/gthr-mipssde.h new file mode 100644 index 00000000000..28111e3929e --- /dev/null +++ b/gcc/gthr-mipssde.h @@ -0,0 +1,227 @@ +/* MIPS SDE threads compatibility routines for libgcc2 and libobjc. */ +/* Compile this one with gcc. */ +/* Copyright (C) 2006, 2007 Free Software Foundation, Inc. + Contributed by Nigel Stephens <nigel@mips.com> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +#ifndef GCC_GTHR_MIPSSDE_H +#define GCC_GTHR_MIPSSDE_H + +/* MIPS SDE threading API specific definitions. + Easy, since the interface is pretty much one-to-one. */ + +#define __GTHREADS 1 + +#include <sdethread.h> +#include <unistd.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef __sdethread_key_t __gthread_key_t; +typedef __sdethread_once_t __gthread_once_t; +typedef __sdethread_mutex_t __gthread_mutex_t; + +typedef struct { + long depth; + __sdethread_t owner; + __sdethread_mutex_t actual; +} __gthread_recursive_mutex_t; + +#define __GTHREAD_MUTEX_INIT __SDETHREAD_MUTEX_INITIALIZER("gthr") +#define __GTHREAD_ONCE_INIT __SDETHREAD_ONCE_INIT +static inline int +__gthread_recursive_mutex_init_function(__gthread_recursive_mutex_t *mutex); +#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function + +#if SUPPORTS_WEAK && GTHREAD_USE_WEAK +# define __gthrw(name) \ + static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))); +# define __gthrw_(name) __gthrw_ ## name +#else +# define __gthrw(name) +# define __gthrw_(name) name +#endif + +__gthrw(__sdethread_once) +__gthrw(__sdethread_key_create) +__gthrw(__sdethread_key_delete) +__gthrw(__sdethread_getspecific) +__gthrw(__sdethread_setspecific) + +__gthrw(__sdethread_self) + +__gthrw(__sdethread_mutex_lock) +__gthrw(__sdethread_mutex_trylock) +__gthrw(__sdethread_mutex_unlock) + +__gthrw(__sdethread_mutex_init) + +__gthrw(__sdethread_threading) + +#if SUPPORTS_WEAK && GTHREAD_USE_WEAK + +static inline int +__gthread_active_p (void) +{ + return !!(void *)&__sdethread_threading; +} + +#else /* not SUPPORTS_WEAK */ + +static inline int +__gthread_active_p (void) +{ + return 1; +} + +#endif /* SUPPORTS_WEAK */ + +static inline int +__gthread_once (__gthread_once_t *once, void (*func) (void)) +{ + if (__gthread_active_p ()) + return __gthrw_(__sdethread_once) (once, func); + else + return -1; +} + +static inline int +__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) +{ + return __gthrw_(__sdethread_key_create) (key, dtor); +} + +static inline int +__gthread_key_delete (__gthread_key_t key) +{ + return __gthrw_(__sdethread_key_delete) (key); +} + +static inline void * +__gthread_getspecific (__gthread_key_t key) +{ + return __gthrw_(__sdethread_getspecific) (key); +} + +static inline int +__gthread_setspecific (__gthread_key_t key, const void *ptr) +{ + return __gthrw_(__sdethread_setspecific) (key, ptr); +} + +static inline int +__gthread_mutex_lock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return __gthrw_(__sdethread_mutex_lock) (mutex); + else + return 0; +} + +static inline int +__gthread_mutex_trylock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return __gthrw_(__sdethread_mutex_trylock) (mutex); + else + return 0; +} + +static inline int +__gthread_mutex_unlock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return __gthrw_(__sdethread_mutex_unlock) (mutex); + else + return 0; +} + +static inline int +__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) +{ + mutex->depth = 0; + mutex->owner = __gthrw_(__sdethread_self) (); + return __gthrw_(__sdethread_mutex_init) (&mutex->actual, NULL); +} + +static inline int +__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex) +{ + if (__gthread_active_p ()) + { + __sdethread_t me = __gthrw_(__sdethread_self) (); + + if (mutex->owner != me) + { + __gthrw_(__sdethread_mutex_lock) (&mutex->actual); + mutex->owner = me; + } + + mutex->depth++; + } + return 0; +} + +static inline int +__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex) +{ + if (__gthread_active_p ()) + { + __sdethread_t me = __gthrw_(__sdethread_self) (); + + if (mutex->owner != me) + { + if (__gthrw_(__sdethread_mutex_trylock) (&mutex->actual)) + return 1; + mutex->owner = me; + } + + mutex->depth++; + } + return 0; +} + +static inline int +__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex) +{ + if (__gthread_active_p ()) + { + if (--mutex->depth == 0) + { + mutex->owner = (__sdethread_t) 0; + __gthrw_(__sdethread_mutex_unlock) (&mutex->actual); + } + } + return 0; +} + +#ifdef __cplusplus +} +#endif + +#endif /* ! GCC_GTHR_MIPSSDE_H */ |