mt-sde (CFLAGS_FOR_TARGET): Add -mno-gpopt.
authorRichard Sandiford <richard@codesourcery.com>
Fri, 7 Sep 2007 07:37:38 +0000 (07:37 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 7 Sep 2007 07:37:38 +0000 (07:37 +0000)
config/
* mt-sde (CFLAGS_FOR_TARGET): Add -mno-gpopt.
(CXXFLAGS_FOR_TARGET): Likewise.

gcc/
* doc/invoke.texi: Document the MIPS -mlocal-sdata, -mextern-sdata
and -mgpopt options.  Adjust the -G documentation to match.
* config/mips/mips.opt (mextern-data, mgpopt, mlocal-data): New.
* config/mips/mips.c (mips_rtx_constant_in_small_data_p): New
function, split out from mips_classify_symbol.  Return false for
!TARGET_LOCAL_SDATA.
(mips_classify_symbol): Call mips_rtx_constant_in_small_data_p.
Only use GP-relative accesses for non-pool symbols if TARGET_GPOPT.
(override_options): Check whether the -mgpopt setting is consistent
with the other flags.
(symbolic_expression_p): Delete.
(mips_select_rtx_section): Use mips_rtx_constant_in_small_data_p
and default_elf_select_rtx_section.
(mips_in_small_data_p): Honor section attributes for MIPS16 too.
Return false for local data unless TARGET_LOCAL_SDATA.  Likewise
external data and TARGET_EXTERN_SDATA.

gcc/testsuite/
* gcc.dg/attr-alias-3.c: Use real asm for MIPS.
* gcc.target/mips/mips.exp (setup_mips_tests): Set mips_forced_gp
and mips_forced_no_er.
(dg-mips-options): Add -mno-abicalls when a small-data option is
specified.  Skip tests with small-data options if mips_forced_gp.
Skip tests with -mexplicit-relocs if mips_forced_no_er.
* gcc.target/mips/sdata-1.c: New test.
* gcc.target/mips/sdata-2.c: Likewise.
* gcc.target/mips/sdata-3.c: Likewise.
* gcc.target/mips/sdata-4.c: Likewise.

From-SVN: r128230

13 files changed:
config/ChangeLog
config/mt-sde
gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/attr-alias-3.c
gcc/testsuite/gcc.target/mips/mips.exp
gcc/testsuite/gcc.target/mips/sdata-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/sdata-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/sdata-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/sdata-4.c [new file with mode: 0644]

index 30cb805b7aa9e39727abfe309b9ff353fe49ac6c..cb0b61a9ad085ea38691076eded200924188213b 100644 (file)
@@ -1,3 +1,8 @@
+2007-09-07  Richard Sandiford  <richard@codesourcery.com>
+
+       * mt-sde (CFLAGS_FOR_TARGET): Add -mno-gpopt.
+       (CXXFLAGS_FOR_TARGET): Likewise.
+
 2007-08-18  Paul Brook  <paul@codesourcery.com>
             Joseph Myers  <joseph@codesourcery.com>
 
index e74616105cfc6809c631e2b68867315d3fb7dbe6..fbdc081fe33fd2b8455b4540c443b36ad651c9c4 100644 (file)
@@ -1,8 +1,10 @@
 # We default to building libraries optimised for size.  We switch off
 # sibling-call optimization to permit interlinking of MIPS16 and
-# non-MIPS16 functions. The -mcode-xonly option allows MIPS16
-# libraries to run on Harvard-style split I/D memories, so long as
-# they have the D-to-I redirect for pc-relative loads.
-
-CFLAGS_FOR_TARGET = -Os -fno-optimize-sibling-calls -mcode-xonly
-CXXFLAGS_FOR_TARGET = -Os -fno-optimize-sibling-calls -mcode-xonly
+# non-MIPS16 functions.  The -mcode-xonly option allows MIPS16 libraries
+# to run on Harvard-style split I/D memories, so long as they have the
+# D-to-I redirect for PC-relative loads.  -mno-gpopt has two purposes:
+# it allows libraries to be used in situations where $gp != our _gp,
+# and it allows them to be built with -G8 while retaining link compability
+# with -G0 and -G4.
+CFLAGS_FOR_TARGET = -Os -fno-optimize-sibling-calls -mcode-xonly -mno-gpopt
+CXXFLAGS_FOR_TARGET = -Os -fno-optimize-sibling-calls -mcode-xonly -mno-gpopt
index 837866a810cbd12cb2216b8ada5d479b18297c21..78b0a9a4e6bbd36129d510db6afd890cb3618b42 100644 (file)
@@ -1,3 +1,22 @@
+2007-09-07  Richard Sandiford  <richard@codesourcery.com>
+
+       * doc/invoke.texi: Document the MIPS -mlocal-sdata, -mextern-sdata
+       and -mgpopt options.  Adjust the -G documentation to match.
+       * config/mips/mips.opt (mextern-data, mgpopt, mlocal-data): New.
+       * config/mips/mips.c (mips_rtx_constant_in_small_data_p): New
+       function, split out from mips_classify_symbol.  Return false for
+       !TARGET_LOCAL_SDATA.
+       (mips_classify_symbol): Call mips_rtx_constant_in_small_data_p.
+       Only use GP-relative accesses for non-pool symbols if TARGET_GPOPT.
+       (override_options): Check whether the -mgpopt setting is consistent
+       with the other flags.
+       (symbolic_expression_p): Delete.
+       (mips_select_rtx_section): Use mips_rtx_constant_in_small_data_p
+       and default_elf_select_rtx_section.
+       (mips_in_small_data_p): Honor section attributes for MIPS16 too.
+       Return false for local data unless TARGET_LOCAL_SDATA.  Likewise
+       external data and TARGET_EXTERN_SDATA.
+
 2007-09-07  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/33303
index cf8c337afa76f63eb0adc3b4f7f684a41256509a..365561829e3771cbb8a12fe0e745169afdfe12f8 100644 (file)
@@ -341,7 +341,6 @@ static void mips_output_function_epilogue (FILE *, HOST_WIDE_INT);
 static void mips_restore_reg (rtx, rtx);
 static void mips_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
                                  HOST_WIDE_INT, tree);
-static int symbolic_expression_p (rtx);
 static section *mips_select_rtx_section (enum machine_mode, rtx,
                                         unsigned HOST_WIDE_INT);
 static section *mips_function_rodata_section (tree);
@@ -1474,6 +1473,17 @@ mips_symbol_binds_local_p (const_rtx x)
          : SYMBOL_REF_LOCAL_P (x));
 }
 
+/* Return true if rtx constants of mode MODE should be put into a small
+   data section.  */
+
+static bool
+mips_rtx_constant_in_small_data_p (enum machine_mode mode)
+{
+  return (!TARGET_EMBEDDED_DATA
+         && TARGET_LOCAL_SDATA
+         && GET_MODE_SIZE (mode) <= mips_section_threshold);
+}
+
 /* Return the method that should be used to access SYMBOL_REF or
    LABEL_REF X in context CONTEXT.  */
 
@@ -1508,14 +1518,14 @@ mips_classify_symbol (const_rtx x, enum mips_symbol_context context)
       if (TARGET_MIPS16_PCREL_LOADS && context == SYMBOL_CONTEXT_MEM)
        return SYMBOL_PC_RELATIVE;
 
-      if (!TARGET_EMBEDDED_DATA
-         && GET_MODE_SIZE (get_pool_mode (x)) <= mips_section_threshold)
+      if (mips_rtx_constant_in_small_data_p (get_pool_mode (x)))
        return SYMBOL_GP_RELATIVE;
     }
 
   /* Do not use small-data accesses for weak symbols; they may end up
      being zero.  */
-  if (SYMBOL_REF_SMALL_P (x)
+  if (TARGET_GPOPT
+      && SYMBOL_REF_SMALL_P (x)
       && !SYMBOL_REF_WEAK (x))
     return SYMBOL_GP_RELATIVE;
 
@@ -5576,21 +5586,14 @@ override_options (void)
     }
 
   if (TARGET_ABICALLS)
-    {
-      /* We need to set flag_pic for executables as well as DSOs
-        because we may reference symbols that are not defined in
-        the final executable.  (MIPS does not use things like
-        copy relocs, for example.)
+    /* We need to set flag_pic for executables as well as DSOs
+       because we may reference symbols that are not defined in
+       the final executable.  (MIPS does not use things like
+       copy relocs, for example.)
 
-        Also, there is a body of code that uses __PIC__ to distinguish
-        between -mabicalls and -mno-abicalls code.  */
-      flag_pic = 1;
-      if (mips_section_threshold > 0)
-       warning (0, "%<-G%> is incompatible with %<-mabicalls%>");
-    }
-
-  if (TARGET_VXWORKS_RTP && mips_section_threshold > 0)
-    warning (0, "-G and -mrtp are incompatible");
+       Also, there is a body of code that uses __PIC__ to distinguish
+       between -mabicalls and -mno-abicalls code.  */
+    flag_pic = 1;
 
   /* -mvr4130-align is a "speed over size" optimization: it usually produces
      faster code, but at the expense of more nops.  Enable it at -O3 and
@@ -5603,6 +5606,29 @@ override_options (void)
   if (optimize_size && (target_flags_explicit & MASK_MEMCPY) == 0)
     target_flags |= MASK_MEMCPY;
 
+  /* If we have a nonzero small-data limit, check that the -mgpopt
+     setting is consistent with the other target flags.  */
+  if (mips_section_threshold > 0)
+    {
+      if (!TARGET_GPOPT)
+       {
+         if (!TARGET_MIPS16 && !TARGET_EXPLICIT_RELOCS)
+           error ("%<-mno-gpopt%> needs %<-mexplicit-relocs%>");
+
+         TARGET_LOCAL_SDATA = false;
+         TARGET_EXTERN_SDATA = false;
+       }
+      else
+       {
+         if (TARGET_VXWORKS_RTP)
+           warning (0, "cannot use small-data accesses for %qs", "-mrtp");
+
+         if (TARGET_ABICALLS)
+           warning (0, "cannot use small-data accesses for %qs",
+                    "-mabicalls");
+       }
+    }
+
 #ifdef MIPS_TFMODE_FORMAT
   REAL_MODE_FORMAT (TFmode) = &MIPS_TFMODE_FORMAT;
 #endif
@@ -8453,54 +8479,17 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
   reload_completed = 0;
 }
 \f
-/* Returns nonzero if X contains a SYMBOL_REF.  */
-
-static int
-symbolic_expression_p (rtx x)
-{
-  if (GET_CODE (x) == SYMBOL_REF)
-    return 1;
-
-  if (GET_CODE (x) == CONST)
-    return symbolic_expression_p (XEXP (x, 0));
-
-  if (UNARY_P (x))
-    return symbolic_expression_p (XEXP (x, 0));
-
-  if (ARITHMETIC_P (x))
-    return (symbolic_expression_p (XEXP (x, 0))
-           || symbolic_expression_p (XEXP (x, 1)));
-
-  return 0;
-}
-
-/* Choose the section to use for the constant rtx expression X that has
-   mode MODE.  */
+/* Implement TARGET_SELECT_RTX_SECTION.  */
 
 static section *
 mips_select_rtx_section (enum machine_mode mode, rtx x,
                         unsigned HOST_WIDE_INT align)
 {
-  if (TARGET_EMBEDDED_DATA)
-    {
-      /* For embedded applications, always put constants in read-only data,
-        in order to reduce RAM usage.  */
-      return mergeable_constant_section (mode, align, 0);
-    }
-  else
-    {
-      /* For hosted applications, always put constants in small data if
-        possible, as this gives the best performance.  */
-      /* ??? Consider using mergeable small data sections.  */
+  /* ??? Consider using mergeable small data sections.  */
+  if (mips_rtx_constant_in_small_data_p (mode))
+    return get_named_section (NULL, ".sdata", 0);
 
-      if (GET_MODE_SIZE (mode) <= (unsigned) mips_section_threshold
-         && mips_section_threshold > 0)
-       return get_named_section (NULL, ".sdata", 0);
-      else if (flag_pic && symbolic_expression_p (x))
-       return get_named_section (NULL, ".data.rel.ro", 3);
-      else
-       return mergeable_constant_section (mode, align, 0);
-    }
+  return default_elf_select_rtx_section (mode, x, align);
 }
 
 /* Implement TARGET_ASM_FUNCTION_RODATA_SECTION.
@@ -8566,7 +8555,7 @@ mips_in_small_data_p (const_tree decl)
 
       /* If a symbol is defined externally, the assembler will use the
         usual -G rules when deciding how to implement macros.  */
-      if (TARGET_EXPLICIT_RELOCS || !DECL_EXTERNAL (decl))
+      if (mips_lo_relocs[SYMBOL_GP_RELATIVE] || !DECL_EXTERNAL (decl))
        return true;
     }
   else if (TARGET_EMBEDDED_DATA)
@@ -8582,6 +8571,19 @@ mips_in_small_data_p (const_tree decl)
        return false;
     }
 
+  /* Enforce -mlocal-sdata.  */
+  if (!TARGET_LOCAL_SDATA && !TREE_PUBLIC (decl))
+    return false;
+
+  /* Enforce -mextern-sdata.  */
+  if (!TARGET_EXTERN_SDATA && DECL_P (decl))
+    {
+      if (DECL_EXTERNAL (decl))
+       return false;
+      if (DECL_COMMON (decl) && DECL_INITIAL (decl) == NULL)
+       return false;
+    }
+
   size = int_size_in_bytes (TREE_TYPE (decl));
   return (size > 0 && size <= mips_section_threshold);
 }
index 7f60bebc7b823a4357b61da1be06349a42660cfd..80fd108204fb07008429714906c88a79c56927e0 100644 (file)
@@ -96,6 +96,10 @@ mexplicit-relocs
 Target Report Mask(EXPLICIT_RELOCS)
 Use NewABI-style %reloc() assembly operators
 
+mextern-sdata
+Target Report Var(TARGET_EXTERN_SDATA) Init(1)
+Use -G for data that is not defined by the current object
+
 mfix-r4000
 Target Report Mask(FIX_R4000)
 Work around certain R4000 errata
@@ -148,6 +152,10 @@ mgp64
 Target Report RejectNegative Mask(64BIT)
 Use 64-bit general registers
 
+mgpopt
+Target Report Var(TARGET_GPOPT) Init(1)
+Use GP-relative addressing to access small data
+
 mhard-float
 Target Report RejectNegative InverseMask(SOFT_FLOAT_ABI, HARD_FLOAT_ABI)
 Allow the use of hardware floating-point ABI and instructions
@@ -164,6 +172,10 @@ mips3d
 Target Report RejectNegative Mask(MIPS3D)
 Use MIPS-3D instructions
 
+mlocal-sdata
+Target Report Var(TARGET_LOCAL_SDATA) Init(1)
+Use -G for object-local data
+
 mlong-calls
 Target Report Var(TARGET_LONG_CALLS)
 Use indirect calls
index 1dce0b71ac8da5061fff7cc9c69917bb656140c5..aafc74c6be2204188c8299268bd09e7b7b3b9536 100644 (file)
@@ -629,7 +629,9 @@ Objective-C and Objective-C++ Dialects}.
 -mpaired-single  -mno-paired-single  -mdmx  -mno-mdmx @gol
 -mips3d  -mno-mips3d  -mmt  -mno-mt @gol
 -mlong64  -mlong32  -msym32  -mno-sym32 @gol
--G@var{num}  -membedded-data  -mno-embedded-data @gol
+-G@var{num}  -mlocal-sdata  -mno-local-sdata @gol
+-mextern-sdata  -mno-extern-sdata  -mgpopt  -mno-gopt @gol
+-membedded-data  -mno-embedded-data @gol
 -muninit-const-in-rodata  -mno-uninit-const-in-rodata @gol
 -mcode-readable=@var{setting} @gol
 -msplit-addresses  -mno-split-addresses @gol
@@ -11850,14 +11852,69 @@ to generate shorter and faster references to symbolic addresses.
 
 @item -G @var{num}
 @opindex G
-@cindex smaller data references (MIPS)
-@cindex gp-relative references (MIPS)
-Put global and static items less than or equal to @var{num} bytes into
-the small data or bss section instead of the normal data or bss section.
-This allows the data to be accessed using a single instruction.
-
-All modules should be compiled with the same @option{-G @var{num}}
-value.
+Put definitions of externally-visible data in a small data section
+if that data is no bigger than @var{num} bytes.  GCC can then access
+the data more efficiently; see @option{-mgpopt} for details.
+
+The default @option{-G} option depends on the configuration.
+
+@item -mlocal-sdata
+@itemx -mno-local-sdata
+@opindex mlocal-sdata
+@opindex mno-local-sdata
+Extend (do not extend) the @option{-G} behavior to local data too,
+such as to static variables in C.  @option{-mlocal-sdata} is the
+default for all configurations.
+
+If the linker complains that an application is using too much small data,
+you might want to try rebuilding the less performance-critical parts with
+@option{-mno-local-sdata}.  You might also want to build large
+libraries with @option{-mno-local-sdata}, so that the libraries leave
+more room for the main program.
+
+@item -mextern-sdata
+@itemx -mno-extern-sdata
+@opindex mextern-sdata
+@opindex mno-extern-sdata
+Assume (do not assume) that externally-defined data will be in
+a small data section if that data is within the @option{-G} limit.
+@option{-mextern-sdata} is the default for all configurations.
+
+If you compile a module @var{Mod} with @option{-mextern-sdata} @option{-G
+@var{num}} @option{-mgpopt}, and @var{Mod} references a variable @var{Var}
+that is no bigger than @var{num} bytes, you must make sure that @var{Var}
+is placed in a small data section.  If @var{Var} is defined by another
+module, you must either compile that module with a high-enough
+@option{-G} setting or attach a @code{section} attribute to @var{Var}'s
+definition.  If @var{Var} is common, you must link the application
+with a high-enough @option{-G} setting.
+
+The easiest way of satisfying these restrictions is to compile
+and link every module with the same @option{-G} option.  However,
+you may wish to build a library that supports several different
+small data limits.  You can do this by compiling the library with
+the highest supported @option{-G} setting and additionally using
+@option{-mno-extern-sdata} to stop the library from making assumptions
+about externally-defined data.
+
+@item -mgpopt
+@itemx -mno-gpopt
+@opindex mgpopt
+@opindex mno-gpopt
+Use (do not use) GP-relative accesses for symbols that are known to be
+in a small data section; see @option{-G}, @option{-mlocal-sdata} and
+@option{-mextern-sdata}.  @option{-mgpopt} is the default for all
+configurations.
+
+@option{-mno-gpopt} is useful for cases where the @code{$gp} register
+might not hold the value of @code{_gp}.  For example, if the code is
+part of a library that might be used in a boot monitor, programs that
+call boot monitor routines will pass an unknown value in @code{$gp}.
+(In such situations, the boot monitor itself would usually be compiled
+with @option{-G0}.)
+
+@option{-mno-gpopt} implies @option{-mno-local-sdata} and
+@option{-mno-extern-sdata}.
 
 @item -membedded-data
 @itemx -mno-embedded-data
index 8771b42e522235c9e12fdf798731429df33f4361..0781fb11700d32f4f080cfca9c66651c4b4ae7b5 100644 (file)
@@ -1,3 +1,16 @@
+2007-09-07  Richard Sandiford  <richard@codesourcery.com>
+
+       * gcc.dg/attr-alias-3.c: Use real asm for MIPS.
+       * gcc.target/mips/mips.exp (setup_mips_tests): Set mips_forced_gp
+       and mips_forced_no_er.
+       (dg-mips-options): Add -mno-abicalls when a small-data option is
+       specified.  Skip tests with small-data options if mips_forced_gp.
+       Skip tests with -mexplicit-relocs if mips_forced_no_er.
+       * gcc.target/mips/sdata-1.c: New test.
+       * gcc.target/mips/sdata-2.c: Likewise.
+       * gcc.target/mips/sdata-3.c: Likewise.
+       * gcc.target/mips/sdata-4.c: Likewise.
+
 2007-09-06  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/33298
index ec82251952548b8bae92bce54f37ffba2f794032..02637b2313e6a7c951da153f7e17d28f6ae23d53 100644 (file)
@@ -52,5 +52,11 @@ extern ftype Af4a __attribute__((alias ("lf4")));
 static ftype *pf4a = &Af4a;
 
 main() {
+#ifdef __mips
+  /* Use real asm for MIPS, to stop the assembler warning about
+     orphaned high-part relocations.  */
+  asm volatile ("lw $2,%0\n\tlw $2,%1" : : "m" (pv4a), "m" (pf4a) : "$2");
+#else
   asm volatile ("" : : "m" (pv4a), "m" (pf4a));
+#endif
 }
index e498430b9473cdc598a93d2d0159df15e556998f..fef509749034b36c034298f7c56212ea278ea9ee 100644 (file)
@@ -38,6 +38,8 @@ load_lib gcc-dg.exp
 #    $mips_forced_abi:  true if the command line uses -mabi=* or -mgp*
 #    $mips_forced_float: true if the command line uses -mhard/soft-float
 #    $mips_forced_le    true if the command line uses -EL or -mel
+#    $mips_forced_gp    true if the command line forces a particular GP mode
+#    $mips_forced_no_er  true if the command line contains -mno-explicit-relocs
 proc setup_mips_tests {} {
     global mips_isa
     global mips_arch
@@ -49,6 +51,8 @@ proc setup_mips_tests {} {
     global mips_forced_abi
     global mips_forced_float
     global mips_forced_le
+    global mips_forced_gp
+    global mips_forced_no_er
 
     global compiler_flags
     global tool
@@ -84,6 +88,8 @@ proc setup_mips_tests {} {
     set mips_forced_abi [regexp -- {(-mgp|-mfp|-mabi)} $compiler_flags]
     set mips_forced_float [regexp -- {-m(hard|soft)-float} $compiler_flags]
     set mips_forced_le [regexp -- {-(EL|mel)[[:>:]]} $compiler_flags]
+    set mips_forced_gp [regexp -- {-(G|m(|no-)((extern|local)-sdata|gpopt)|mabicalls|mrtp)} $compiler_flags]
+    set mips_forced_no_er [regexp -- {-mno-explicit-relocs} $compiler_flags]
 }
 
 # Return true if command-line option FLAG forces 32-bit code.
@@ -124,6 +130,18 @@ proc is_gp32_flag {flag} {
 #    -EB
 #      Select big-endian code.  Skip the test if the multilib flags
 #      force a little-endian target.
+#
+#    -G*
+#    -m(no-)extern-sdata
+#    -m(no-)local-sdata
+#    -m(no-)gpopt
+#      Select the small-data mode, and -mno-abcialls.  Skip the test if
+#      the multilib flags already contain such an option, or specify
+#      something that might be incompatible with them.
+#
+#    -mexplicit-relocs
+#      Select explicit relocations.  Skip the test if the multilib flags
+#      force -mno-explicit-relocs.
 proc dg-mips-options {args} {
     upvar dg-extra-tool-flags extra_tool_flags
     upvar dg-do-what do_what
@@ -138,6 +156,8 @@ proc dg-mips-options {args} {
     global mips_forced_abi
     global mips_forced_float
     global mips_forced_le
+    global mips_forced_gp
+    global mips_forced_no_er
 
     set flags [lindex $args 1]
     set matches 1
@@ -187,6 +207,15 @@ proc dg-mips-options {args} {
            if {$mips_forced_le} {
                set matches 0
            }
+       } elseif {[regexp -- {^-(G|m(|no-)((extern|local)-sdata|gpopt))} $flag]} {
+           append flags " -mno-abicalls"
+           if {$mips_forced_gp} {
+               set matches 0
+           }
+       } elseif {[regexp -- {^-mexplicit-relocs$} $flag]} {
+           if {$mips_forced_no_er} {
+               set matches 0
+           }
        }
     }
     if {$matches} {
diff --git a/gcc/testsuite/gcc.target/mips/sdata-1.c b/gcc/testsuite/gcc.target/mips/sdata-1.c
new file mode 100644 (file)
index 0000000..2acfdef
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-mips-options "-G4 -mexplicit-relocs" } */
+
+/* { dg-final { scan-assembler     "%gp_?rel\\(l4a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(l4b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(l4c\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(e4a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(e4b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(c4\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g4a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g4b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g4c\\)" } } */
+
+/* { dg-final { scan-assembler-not "%gp_?rel\\(l8a\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(l8b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(l8c\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(e8a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(e8b\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(c8\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(g8a\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(g8b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g8c\\)" } } */
+
+static int l4a;
+static int l4b = 1;
+static int __attribute__((section(".sdata"))) l4c;
+extern int e4a;
+extern int __attribute__((section(".sdata"))) e4b;
+int __attribute__((common)) c4;
+int __attribute__((nocommon)) g4a;
+int g4b = 1;
+int __attribute__((section(".sdata"))) g4c = 2;
+
+static int l8a[2];
+static int l8b[2] = { 1, 2 };
+static int __attribute__((section(".sdata"))) l8c[2];
+extern int e8a[2];
+extern int __attribute__((section(".sdata"))) e8b[2];
+int __attribute__((common)) c8[2];
+int __attribute__((nocommon)) g8a[2];
+int g8b[2] = { 1, 2 };
+int __attribute__((section(".sdata"))) g8c[2] = { 1, 2 };
+
+int f32a (void) { return l4a; }
+int f32b (void) { return l4b; }
+int f32c (void) { return l4c; }
+int f32d (void) { return e4a; }
+int f32e (void) { return e4b; }
+int f32f (void) { return c4; }
+int f32g (void) { return g4a; }
+int f32h (void) { return g4b; }
+int f32i (void) { return g4c; }
+
+int f64a (void) { return l8a[0]; }
+int f64b (void) { return l8b[0]; }
+int f64c (void) { return l8c[0]; }
+int f64d (void) { return e8a[0]; }
+int f64e (void) { return e8b[0]; }
+int f64f (void) { return c8[0]; }
+int f64g (void) { return g8a[0]; }
+int f64h (void) { return g8b[0]; }
+int f64i (void) { return g8c[0]; }
diff --git a/gcc/testsuite/gcc.target/mips/sdata-2.c b/gcc/testsuite/gcc.target/mips/sdata-2.c
new file mode 100644 (file)
index 0000000..5479c81
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-mips-options "-G4 -mexplicit-relocs -mno-local-sdata" } */
+
+/* { dg-final { scan-assembler-not "%gp_?rel\\(l4a\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(l4b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(l4c\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(e4a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(e4b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(c4\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g4a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g4b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g4c\\)" } } */
+
+/* { dg-final { scan-assembler-not "%gp_?rel\\(l8a\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(l8b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(l8c\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(e8a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(e8b\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(c8\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(g8a\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(g8b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g8c\\)" } } */
+
+static int l4a;
+static int l4b = 1;
+static int __attribute__((section(".sdata"))) l4c;
+extern int e4a;
+extern int __attribute__((section(".sdata"))) e4b;
+int __attribute__((common)) c4;
+int __attribute__((nocommon)) g4a;
+int g4b = 1;
+int __attribute__((section(".sdata"))) g4c = 2;
+
+static int l8a[2];
+static int l8b[2] = { 1, 2 };
+static int __attribute__((section(".sdata"))) l8c[2];
+extern int e8a[2];
+extern int __attribute__((section(".sdata"))) e8b[2];
+int __attribute__((common)) c8[2];
+int __attribute__((nocommon)) g8a[2];
+int g8b[2] = { 1, 2 };
+int __attribute__((section(".sdata"))) g8c[2] = { 1, 2 };
+
+int f32a (void) { return l4a; }
+int f32b (void) { return l4b; }
+int f32c (void) { return l4c; }
+int f32d (void) { return e4a; }
+int f32e (void) { return e4b; }
+int f32f (void) { return c4; }
+int f32g (void) { return g4a; }
+int f32h (void) { return g4b; }
+int f32i (void) { return g4c; }
+
+int f64a (void) { return l8a[0]; }
+int f64b (void) { return l8b[0]; }
+int f64c (void) { return l8c[0]; }
+int f64d (void) { return e8a[0]; }
+int f64e (void) { return e8b[0]; }
+int f64f (void) { return c8[0]; }
+int f64g (void) { return g8a[0]; }
+int f64h (void) { return g8b[0]; }
+int f64i (void) { return g8c[0]; }
diff --git a/gcc/testsuite/gcc.target/mips/sdata-3.c b/gcc/testsuite/gcc.target/mips/sdata-3.c
new file mode 100644 (file)
index 0000000..3cea3d3
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-mips-options "-G4 -mexplicit-relocs -mno-extern-sdata" } */
+
+/* { dg-final { scan-assembler     "%gp_?rel\\(l4a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(l4b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(l4c\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(e4a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(e4b\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(c4\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g4a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g4b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g4c\\)" } } */
+
+/* { dg-final { scan-assembler-not "%gp_?rel\\(l8a\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(l8b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(l8c\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(e8a\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(e8b\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(c8\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(g8a\\)" } } */
+/* { dg-final { scan-assembler-not "%gp_?rel\\(g8b\\)" } } */
+/* { dg-final { scan-assembler     "%gp_?rel\\(g8c\\)" } } */
+
+static int l4a;
+static int l4b = 1;
+static int __attribute__((section(".sdata"))) l4c;
+extern int e4a;
+extern int __attribute__((section(".sdata"))) e4b;
+int __attribute__((common)) c4;
+int __attribute__((nocommon)) g4a;
+int g4b = 1;
+int __attribute__((section(".sdata"))) g4c = 2;
+
+static int l8a[2];
+static int l8b[2] = { 1, 2 };
+static int __attribute__((section(".sdata"))) l8c[2];
+extern int e8a[2];
+extern int __attribute__((section(".sdata"))) e8b[2];
+int __attribute__((common)) c8[2];
+int __attribute__((nocommon)) g8a[2];
+int g8b[2] = { 1, 2 };
+int __attribute__((section(".sdata"))) g8c[2] = { 1, 2 };
+
+int f32a (void) { return l4a; }
+int f32b (void) { return l4b; }
+int f32c (void) { return l4c; }
+int f32d (void) { return e4a; }
+int f32e (void) { return e4b; }
+int f32f (void) { return c4; }
+int f32g (void) { return g4a; }
+int f32h (void) { return g4b; }
+int f32i (void) { return g4c; }
+
+int f64a (void) { return l8a[0]; }
+int f64b (void) { return l8b[0]; }
+int f64c (void) { return l8c[0]; }
+int f64d (void) { return e8a[0]; }
+int f64e (void) { return e8b[0]; }
+int f64f (void) { return c8[0]; }
+int f64g (void) { return g8a[0]; }
+int f64h (void) { return g8b[0]; }
+int f64i (void) { return g8c[0]; }
diff --git a/gcc/testsuite/gcc.target/mips/sdata-4.c b/gcc/testsuite/gcc.target/mips/sdata-4.c
new file mode 100644 (file)
index 0000000..f88348d
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-mips-options "-G4 -mexplicit-relocs -mno-gpopt" } */
+
+/* { dg-final { scan-assembler-not "%gp_?rel" } } */
+/* { dg-final { scan-assembler-not "\\\$gp" } } */
+
+static int l4a;
+static int l4b = 1;
+static int __attribute__((section(".sdata"))) l4c;
+extern int e4a;
+extern int __attribute__((section(".sdata"))) e4b;
+int __attribute__((common)) c4;
+int __attribute__((nocommon)) g4a;
+int g4b = 1;
+int __attribute__((section(".sdata"))) g4c = 2;
+
+static int l8a[2];
+static int l8b[2] = { 1, 2 };
+static int __attribute__((section(".sdata"))) l8c[2];
+extern int e8a[2];
+extern int __attribute__((section(".sdata"))) e8b[2];
+int __attribute__((common)) c8[2];
+int __attribute__((nocommon)) g8a[2];
+int g8b[2] = { 1, 2 };
+int __attribute__((section(".sdata"))) g8c[2] = { 1, 2 };
+
+int f32a (void) { return l4a; }
+int f32b (void) { return l4b; }
+int f32c (void) { return l4c; }
+int f32d (void) { return e4a; }
+int f32e (void) { return e4b; }
+int f32f (void) { return c4; }
+int f32g (void) { return g4a; }
+int f32h (void) { return g4b; }
+int f32i (void) { return g4c; }
+
+int f64a (void) { return l8a[0]; }
+int f64b (void) { return l8b[0]; }
+int f64c (void) { return l8c[0]; }
+int f64d (void) { return e8a[0]; }
+int f64e (void) { return e8b[0]; }
+int f64f (void) { return c8[0]; }
+int f64g (void) { return g8a[0]; }
+int f64h (void) { return g8b[0]; }
+int f64i (void) { return g8c[0]; }