+2015-01-15 Sandra Loosemore <sandra@codesourcery.com>
+
+ PR target/59710
+ * doc/invoke.texi (Option Summary): Document new Nios II
+ -mgpopt= syntax.
+ (Nios II Options): Likewise.
+ * config/nios2/nios2.opt: Add -mgpopt= option support.
+ Modify existing -mgpopt and -mno-gpopt options to be aliases.
+ * config/nios2/nios2-opts.h (enum nios2_gpopt_type): New.
+ * config/nios2/nios2.c (nios2_option_override): Adjust
+ -mgpopt defaulting.
+ (nios2_in_small_data_p): Return true for explicit small data
+ sections even with -G0.
+ (nios2_symbol_ref_in_small_data_p): Adjust to handle new -mgpopt=
+ option choices.
+
2015-01-15 Jan Hubicka <hubicka@ucw.cz>
PR ipa/64612
#ifndef NIOS2_OPTS_H
#define NIOS2_OPTS_H
+/* Enumerate the possible -mgpopt choices. */
+enum nios2_gpopt_type
+{
+ gpopt_unspecified = -1,
+ gpopt_none,
+ gpopt_local,
+ gpopt_global,
+ gpopt_data,
+ gpopt_all
+};
+
+
/* Enumeration of all FPU insn codes. */
#define N2FPU_ALL_CODES \
N2FPU_CODE(fadds) N2FPU_CODE(fsubs) N2FPU_CODE(fmuls) N2FPU_CODE(fdivs) \
= (global_options_set.x_g_switch_value
? g_switch_value : NIOS2_DEFAULT_GVALUE);
- /* Default to -mgpopt unless -fpic or -fPIC. */
- if (TARGET_GPOPT == -1 && flag_pic)
- TARGET_GPOPT = 0;
+ if (nios2_gpopt_option == gpopt_unspecified)
+ {
+ /* Default to -mgpopt unless -fpic or -fPIC. */
+ if (flag_pic)
+ nios2_gpopt_option = gpopt_none;
+ else
+ nios2_gpopt_option = gpopt_local;
+ }
/* If we don't have mul, we don't have mulx either! */
if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
if (DECL_SECTION_NAME (exp))
{
const char *section = DECL_SECTION_NAME (exp);
- if (nios2_section_threshold > 0
- && nios2_small_section_name_p (section))
+ if (nios2_small_section_name_p (section))
return true;
}
else
bool
nios2_symbol_ref_in_small_data_p (rtx sym)
{
+ tree decl;
+
gcc_assert (GET_CODE (sym) == SYMBOL_REF);
- return
- (TARGET_GPOPT
- /* GP-relative access cannot be used for externally defined symbols,
- because the compilation unit that defines the symbol may place it
- in a section that cannot be reached from GP. */
- && !SYMBOL_REF_EXTERNAL_P (sym)
- /* True if a symbol is both small and not weak. */
- && SYMBOL_REF_SMALL_P (sym)
- && !(SYMBOL_REF_DECL (sym) && DECL_WEAK (SYMBOL_REF_DECL (sym)))
- /* TLS variables are not accessed through the GP. */
- && SYMBOL_REF_TLS_MODEL (sym) == 0);
+ decl = SYMBOL_REF_DECL (sym);
+ /* TLS variables are not accessed through the GP. */
+ if (SYMBOL_REF_TLS_MODEL (sym) != 0)
+ return false;
+
+ /* If the user has explicitly placed the symbol in a small data section
+ via an attribute, generate gp-relative addressing even if the symbol
+ is external, weak, or larger than we'd automatically put in the
+ small data section. OTOH, if the symbol is located in some
+ non-small-data section, we can't use gp-relative accesses on it
+ unless the user has requested gpopt_data or gpopt_all. */
+
+ switch (nios2_gpopt_option)
+ {
+ case gpopt_none:
+ /* Don't generate a gp-relative addressing mode if that's been
+ disabled. */
+ return false;
+
+ case gpopt_local:
+ /* Use GP-relative addressing for small data symbols that are
+ not external or weak, plus any symbols that have explicitly
+ been placed in a small data section. */
+ if (decl && DECL_SECTION_NAME (decl))
+ return nios2_small_section_name_p (DECL_SECTION_NAME (decl));
+ return (SYMBOL_REF_SMALL_P (sym)
+ && !SYMBOL_REF_EXTERNAL_P (sym)
+ && !(decl && DECL_WEAK (decl)));
+
+ case gpopt_global:
+ /* Use GP-relative addressing for small data symbols, even if
+ they are external or weak. Note that SYMBOL_REF_SMALL_P
+ is also true of symbols that have explicitly been placed
+ in a small data section. */
+ return SYMBOL_REF_SMALL_P (sym);
+
+ case gpopt_data:
+ /* Use GP-relative addressing for all data symbols regardless
+ of the object size, but not for code symbols. This option
+ is equivalent to the user asserting that the entire data
+ section is accessible from the GP. */
+ return !SYMBOL_REF_FUNCTION_P (sym);
+
+ case gpopt_all:
+ /* Use GP-relative addressing for everything, including code.
+ Effectively, the user has asserted that the entire program
+ fits within the 64K range of the GP offset. */
+ return true;
+
+ default:
+ /* We shouldn't get here. */
+ return false;
+ }
}
/* Implement TARGET_SECTION_TYPE_FLAGS. */
Target Report RejectNegative Undocumented InverseMask(BYPASS_CACHE_VOLATILE)
Volatile memory accesses do not use I/O load/store instructions
+mgpopt=
+Target RejectNegative Joined Enum(nios2_gpopt_type) Var(nios2_gpopt_option) Init(gpopt_unspecified)
+Enable/disable GP-relative addressing.
+
+Enum
+Name(nios2_gpopt_type) Type(enum nios2_gpopt_type)
+Valid options for GP-relative addressing (for -mgpopt):
+
+EnumValue
+Enum(nios2_gpopt_type) String(none) Value(gpopt_none)
+
+EnumValue
+Enum(nios2_gpopt_type) String(local) Value(gpopt_local)
+
+EnumValue
+Enum(nios2_gpopt_type) String(global) Value(gpopt_global)
+
+EnumValue
+Enum(nios2_gpopt_type) String(data) Value(gpopt_data)
+
+EnumValue
+Enum(nios2_gpopt_type) String(all) Value(gpopt_all)
+
mgpopt
-Target Report Var(TARGET_GPOPT) Init(-1)
-Use GP-relative addressing to access small data
+Target Report RejectNegative Var(nios2_gpopt_option, gpopt_local)
+Equivalent to -mgpopt=local.
+
+mno-gpopt
+Target Report RejectNegative Var(nios2_gpopt_option, gpopt_none)
+Equivalent to -mgpopt=none.
meb
Target Report RejectNegative Mask(BIG_ENDIAN)
-mex9 -mctor-dtor -mrelax}
@emph{Nios II Options}
-@gccoptlist{-G @var{num} -mgpopt -mno-gpopt -mel -meb @gol
+@gccoptlist{-G @var{num} -mgpopt=@var{option} -mgpopt -mno-gpopt @gol
+-mel -meb @gol
-mno-bypass-cache -mbypass-cache @gol
-mno-cache-volatile -mcache-volatile @gol
-mno-fast-sw-div -mfast-sw-div @gol
into the small data or BSS sections instead of the normal data or BSS
sections. The default value of @var{num} is 8.
+@item -mgpopt=@var{option}
@item -mgpopt
@itemx -mno-gpopt
@opindex mgpopt
@opindex mno-gpopt
-Generate (do not generate) GP-relative accesses for objects in the
-small data or BSS sections. The default is @option{-mgpopt} except
-when @option{-fpic} or @option{-fPIC} is specified to generate
-position-independent code. Note that the Nios II ABI does not permit
-GP-relative accesses from shared libraries.
+Generate (do not generate) GP-relative accesses. The following
+@var{option} names are recognized:
+
+@table @samp
+
+@item none
+Do not generate GP-relative accesses.
+
+@item local
+Generate GP-relative accesses for small data objects that are not
+external or weak. Also use GP-relative addressing for objects that
+have been explicitly placed in a small data section via a @code{section}
+attribute.
+
+@item global
+As for @samp{local}, but also generate GP-relative accesses for
+small data objects that are external or weak. If you use this option,
+you must ensure that all parts of your program (including libraries) are
+compiled with the same @option{-G} setting.
+
+@item data
+Generate GP-relative accesses for all data objects in the program. If you
+use this option, the entire data and BSS segments
+of your program must fit in 64K of memory and you must use an appropriate
+linker script to allocate them within the addressible range of the
+global pointer.
+
+@item all
+Generate GP-relative addresses for function pointers as well as data
+pointers. If you use this option, the entire text, data, and BSS segments
+of your program must fit in 64K of memory and you must use an appropriate
+linker script to allocate them within the addressible range of the
+global pointer.
+
+@end table
+
+@option{-mgpopt} is equivalent to @option{-mgpopt=local}, and
+@option{-mno-gpopt} is equivalent to @option{-mgpopt=none}.
+
+The default is @option{-mgpopt} except when @option{-fpic} or
+@option{-fPIC} is specified to generate position-independent code.
+Note that the Nios II ABI does not permit GP-relative accesses from
+shared libraries.
You may need to specify @option{-mno-gpopt} explicitly when building
programs that include large amounts of small data, including large
+2015-01-15 Sandra Loosemore <sandra@codesourcery.com>
+
+ PR target/59710
+ * gcc.target/nios2/gpopt-all.c: New test case.
+ * gcc.target/nios2/gpopt-local.c: New test case.
+ * gcc.target/nios2/gpopt-global.c: New test case.
+ * gcc.target/nios2/gpopt-data.c: New test case.
+ * gcc.target/nios2/gpopt-none.c: New test case.
+
2015-01-15 Jakub Jelinek <jakub@redhat.com>
* g++.dg/ubsan/vptr-1.C: New test.
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -mgpopt=all" } */
+
+extern int a __attribute__ ((section (".sdata")));
+static volatile int b __attribute__ ((section (".sdata"))) = 1;
+extern int c __attribute__ ((section (".data")));
+static volatile int d __attribute__ ((section (".data"))) = 2;
+
+extern int e;
+static volatile int f = 3;
+
+volatile int g __attribute__ ((weak)) = 4;
+
+extern int h[100];
+static int i[100];
+static int j[100] __attribute__ ((section (".sdata")));
+
+typedef int (*ftype) (int);
+extern int foo (int);
+
+extern int bar (int, int*, int*, int*, ftype);
+
+int baz (void)
+{
+ return bar (a + b + c + d + e + f + g, h, i, j, foo);
+}
+
+/* { dg-final { scan-assembler "%gprel\\(a\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(b\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(c\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(d\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(e\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(f\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(g\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(h\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(i\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(j\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(foo\\)" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -mgpopt=data" } */
+
+extern int a __attribute__ ((section (".sdata")));
+static volatile int b __attribute__ ((section (".sdata"))) = 1;
+extern int c __attribute__ ((section (".data")));
+static volatile int d __attribute__ ((section (".data"))) = 2;
+
+extern int e;
+static volatile int f = 3;
+
+volatile int g __attribute__ ((weak)) = 4;
+
+extern int h[100];
+static int i[100];
+static int j[100] __attribute__ ((section (".sdata")));
+
+typedef int (*ftype) (int);
+extern int foo (int);
+
+extern int bar (int, int*, int*, int*, ftype);
+
+int baz (void)
+{
+ return bar (a + b + c + d + e + f + g, h, i, j, foo);
+}
+
+/* { dg-final { scan-assembler "%gprel\\(a\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(b\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(c\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(d\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(e\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(f\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(g\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(h\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(i\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(j\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(foo\\)" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -mgpopt=global" } */
+
+extern int a __attribute__ ((section (".sdata")));
+static volatile int b __attribute__ ((section (".sdata"))) = 1;
+extern int c __attribute__ ((section (".data")));
+static volatile int d __attribute__ ((section (".data"))) = 2;
+
+extern int e;
+static volatile int f = 3;
+
+volatile int g __attribute__ ((weak)) = 4;
+
+extern int h[100];
+static int i[100];
+static int j[100] __attribute__ ((section (".sdata")));
+
+typedef int (*ftype) (int);
+extern int foo (int);
+
+extern int bar (int, int*, int*, int*, ftype);
+
+int baz (void)
+{
+ return bar (a + b + c + d + e + f + g, h, i, j, foo);
+}
+
+/* { dg-final { scan-assembler "%gprel\\(a\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(b\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(c\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(d\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(e\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(f\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(g\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(h\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(i\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(j\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(foo\\)" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -mgpopt=local" } */
+
+extern int a __attribute__ ((section (".sdata")));
+static volatile int b __attribute__ ((section (".sdata"))) = 1;
+extern int c __attribute__ ((section (".data")));
+static volatile int d __attribute__ ((section (".data"))) = 2;
+
+extern int e;
+static volatile int f = 3;
+
+volatile int g __attribute__ ((weak)) = 4;
+
+extern int h[100];
+static int i[100];
+static int j[100] __attribute__ ((section (".sdata")));
+
+typedef int (*ftype) (int);
+extern int foo (int);
+
+extern int bar (int, int*, int*, int*, ftype);
+
+int baz (void)
+{
+ return bar (a + b + c + d + e + f + g, h, i, j, foo);
+}
+
+/* { dg-final { scan-assembler "%gprel\\(a\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(b\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(c\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(d\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(e\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(f\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(g\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(h\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(i\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(j\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(foo\\)" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -mgpopt=none" } */
+
+extern int a __attribute__ ((section (".sdata")));
+static volatile int b __attribute__ ((section (".sdata"))) = 1;
+extern int c __attribute__ ((section (".data")));
+static volatile int d __attribute__ ((section (".data"))) = 2;
+
+extern int e;
+static volatile int f = 3;
+
+volatile int g __attribute__ ((weak)) = 4;
+
+extern int h[100];
+static int i[100];
+static int j[100] __attribute__ ((section (".sdata")));
+
+typedef int (*ftype) (int);
+extern int foo (int);
+
+extern int bar (int, int*, int*, int*, ftype);
+
+int baz (void)
+{
+ return bar (a + b + c + d + e + f + g, h, i, j, foo);
+}
+
+/* { dg-final { scan-assembler-not "%gprel\\(a\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(b\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(c\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(d\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(e\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(f\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(g\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(h\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(i\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(j\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(foo\\)" } } */