Commit b8898790 by Richard Sandiford Committed by Richard Sandiford

elf64.h (TARGET_ASM_UNIQUE_SECTION): Delete.

	* config/mips/elf64.h (TARGET_ASM_UNIQUE_SECTION): Delete.
	(EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Delete.
	(SECTION_FUNCTION_TEMPLATE): Delete.
	* config/mips/elf.h: As for elf64.h.
	(ASM_OUTPUT_ALIGNED_BSS): Use named_section rather than sbss_section.
	* config/mips/linux.h: As for elf.h
	* config/mips/iris6gld.h (TARGET_ASM_UNIQUE_SECTION): Delete.
	* config/mips/iris6.h (EXTRA_SECTIONS): Delete.
	(EXTRA_SECTION_FUNCTIONS): Remove sdata_section.  Remove the handling
	of in_sdata from current_section_name and current_section_flags.
	* config/mips/iris6gld.h (TARGET_ASM_UNIQUE_SECTION): Delete.
	* config/mips/mips.h (sdata_section, sbss_section): Remove prototypes.
	(MASK_GP_OPT, TARGET_GP_OPT): Delete.
	(MASK_NO_FUSED_MADD): Use MASK_GP_OPT's old value.
	(TARGET_SWITCHES): Neuter gpOPT, gpopt, no-gpOPT and no-gpopt.
	(SMALL_DATA_SECTION, EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Remove.
	* config/mips/mips.c (TARGET_IN_SMALL_DATA_P): Override.
	(TARGET_SECTION_TYPE_FLAGS): Override if TARGET_IRIX6.
	(mips_classify_symbol): Use SYMBOL_REF_SMALL_P.
	(override_options): Remove setting of MASK_GPOPT.
	(mips_output_external): Use mips_in_small_data_p to check whether a
	symbol needs an .extern directive.  Don't emit such directives for
	TARGET_EXPLICIT_RELOCS.
	(mips_declare_object): Update accordingly.
	(mips_select_rtx_section): Call named_section rather than
	SMALL_DATA_SECTION.
	(mips_select_section): Use default_elf_section_section for everything
	except .text string constants.
	(mips_in_small_data_p): New function.
	(mips_encode_section_info): Remove small data handling.
	(mips_unique_section): Delete.
	(iris6_section_type_flags): New function.
	* doc/tm.texi: Remove documentation of -mgpopt and -mhalf-pic.

From-SVN: r69090
parent c5ffd36c
2003-07-08 Richard Sandiford <rsandifo@redhat.com>
* config/mips/elf64.h (TARGET_ASM_UNIQUE_SECTION): Delete.
(EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Delete.
(SECTION_FUNCTION_TEMPLATE): Delete.
* config/mips/elf.h: As for elf64.h.
(ASM_OUTPUT_ALIGNED_BSS): Use named_section rather than sbss_section.
* config/mips/linux.h: As for elf.h
* config/mips/iris6gld.h (TARGET_ASM_UNIQUE_SECTION): Delete.
* config/mips/iris6.h (EXTRA_SECTIONS): Delete.
(EXTRA_SECTION_FUNCTIONS): Remove sdata_section. Remove the handling
of in_sdata from current_section_name and current_section_flags.
* config/mips/iris6gld.h (TARGET_ASM_UNIQUE_SECTION): Delete.
* config/mips/mips.h (sdata_section, sbss_section): Remove prototypes.
(MASK_GP_OPT, TARGET_GP_OPT): Delete.
(MASK_NO_FUSED_MADD): Use MASK_GP_OPT's old value.
(TARGET_SWITCHES): Neuter gpOPT, gpopt, no-gpOPT and no-gpopt.
(SMALL_DATA_SECTION, EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Remove.
* config/mips/mips.c (TARGET_IN_SMALL_DATA_P): Override.
(TARGET_SECTION_TYPE_FLAGS): Override if TARGET_IRIX6.
(mips_classify_symbol): Use SYMBOL_REF_SMALL_P.
(override_options): Remove setting of MASK_GPOPT.
(mips_output_external): Use mips_in_small_data_p to check whether a
symbol needs an .extern directive. Don't emit such directives for
TARGET_EXPLICIT_RELOCS.
(mips_declare_object): Update accordingly.
(mips_select_rtx_section): Call named_section rather than
SMALL_DATA_SECTION.
(mips_select_section): Use default_elf_section_section for everything
except .text string constants.
(mips_in_small_data_p): New function.
(mips_encode_section_info): Remove small data handling.
(mips_unique_section): Delete.
(iris6_section_type_flags): New function.
* doc/tm.texi: Remove documentation of -mgpopt and -mhalf-pic.
2003-07-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 2003-07-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR Target/11453 PR Target/11453
......
...@@ -94,7 +94,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -94,7 +94,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do { \ do { \
if (SIZE > 0 && SIZE <= (unsigned HOST_WIDE_INT)mips_section_threshold)\ if (SIZE > 0 && SIZE <= (unsigned HOST_WIDE_INT)mips_section_threshold)\
sbss_section (); \ named_section (0, ".sbss", 0); \
else \ else \
bss_section (); \ bss_section (); \
ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \ ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \
...@@ -183,28 +183,6 @@ do { \ ...@@ -183,28 +183,6 @@ do { \
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1) #define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
#define TARGET_ASM_UNIQUE_SECTION mips_unique_section
/* A list of other sections which the compiler might be "in" at any
given time. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_sdata, in_sbss
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP) \
SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP)
#define SECTION_FUNCTION_TEMPLATE(FN, ENUM, OP) \
void FN () \
{ \
if (in_section != ENUM) \
{ \
fprintf (asm_out_file, "%s\n", OP); \
in_section = ENUM; \
} \
}
/* On elf, we *do* have support for the .init and .fini sections, and we /* On elf, we *do* have support for the .init and .fini sections, and we
can put stuff in there to be executed before and after `main'. We let can put stuff in there to be executed before and after `main'. We let
crtstuff.c and other files know this by defining the following symbols. crtstuff.c and other files know this by defining the following symbols.
......
...@@ -142,27 +142,6 @@ do { \ ...@@ -142,27 +142,6 @@ do { \
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1) #define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
#define TARGET_ASM_UNIQUE_SECTION mips_unique_section
/* A list of other sections which the compiler might be "in" at any
given time. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_sdata
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP)
#define SECTION_FUNCTION_TEMPLATE(FN, ENUM, OP) \
void FN () \
{ \
if (in_section != ENUM) \
{ \
fprintf (asm_out_file, "%s\n", OP); \
in_section = ENUM; \
} \
}
/* On elf, we *do* have support for the .init and .fini sections, and we /* On elf, we *do* have support for the .init and .fini sections, and we
can put stuff in there to be executed before and after `main'. We let can put stuff in there to be executed before and after `main'. We let
crtstuff.c and other files know this by defining the following symbols. crtstuff.c and other files know this by defining the following symbols.
......
...@@ -281,30 +281,11 @@ Boston, MA 02111-1307, USA. */ ...@@ -281,30 +281,11 @@ Boston, MA 02111-1307, USA. */
? READONLY_DATA_SECTION_ASM_OP_64 \ ? READONLY_DATA_SECTION_ASM_OP_64 \
: READONLY_DATA_SECTION_ASM_OP_32) : READONLY_DATA_SECTION_ASM_OP_32)
/* A default list of other sections which we might be "in" at any given /* Define functions to read the name and flags of the current section.
time. For targets that use additional sections (e.g. .tdesc) you They are used by iris6_asm_output_align. */
should override this definition in the target-specific file which
includes this file. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_sdata
/* A default list of extra section function definitions. For targets
that use additional sections (e.g. .tdesc) you should override this
definition in the target-specific file which includes this file. */
#undef EXTRA_SECTION_FUNCTIONS #undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \ #define EXTRA_SECTION_FUNCTIONS \
void \
sdata_section () \
{ \
if (in_section != in_sdata) \
{ \
fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP); \
in_section = in_sdata; \
} \
} \
\
const char * \ const char * \
current_section_name () \ current_section_name () \
{ \ { \
...@@ -313,7 +294,6 @@ current_section_name () \ ...@@ -313,7 +294,6 @@ current_section_name () \
case no_section: return NULL; \ case no_section: return NULL; \
case in_text: return ".text"; \ case in_text: return ".text"; \
case in_data: return ".data"; \ case in_data: return ".data"; \
case in_sdata: return ".sdata"; \
case in_bss: return ".bss"; \ case in_bss: return ".bss"; \
case in_readonly_data: \ case in_readonly_data: \
if (mips_abi != ABI_32 && mips_abi != ABI_O64) \ if (mips_abi != ABI_32 && mips_abi != ABI_O64) \
...@@ -334,7 +314,6 @@ current_section_flags () \ ...@@ -334,7 +314,6 @@ current_section_flags () \
case no_section: return 0; \ case no_section: return 0; \
case in_text: return SECTION_CODE; \ case in_text: return SECTION_CODE; \
case in_data: return SECTION_WRITE; \ case in_data: return SECTION_WRITE; \
case in_sdata: return SECTION_WRITE | SECTION_SMALL; \
case in_bss: return SECTION_WRITE | SECTION_BSS; \ case in_bss: return SECTION_WRITE | SECTION_BSS; \
case in_readonly_data: return 0; \ case in_readonly_data: return 0; \
case in_named: return get_named_section_flags (in_named_name); \ case in_named: return get_named_section_flags (in_named_name); \
......
...@@ -49,4 +49,3 @@ Boston, MA 02111-1307, USA. */ ...@@ -49,4 +49,3 @@ Boston, MA 02111-1307, USA. */
/* The GNU linker supports one-only sections. */ /* The GNU linker supports one-only sections. */
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1) #define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
#define TARGET_ASM_UNIQUE_SECTION mips_unique_section
...@@ -47,7 +47,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -47,7 +47,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do { \ do { \
if (SIZE > 0 && (long)(SIZE) <= mips_section_threshold) \ if (SIZE > 0 && (long)(SIZE) <= mips_section_threshold) \
sbss_section (); \ named_section (0, ".sbss", 0); \
else \ else \
bss_section (); \ bss_section (); \
ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \ ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \
...@@ -78,28 +78,6 @@ do { \ ...@@ -78,28 +78,6 @@ do { \
mips_declare_object (FILE, NAME, "", ":\n", 0); \ mips_declare_object (FILE, NAME, "", ":\n", 0); \
} while (0) } while (0)
#define TARGET_ASM_UNIQUE_SECTION mips_unique_section
/* A list of other sections which the compiler might be "in" at any
given time. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_sdata, in_sbss
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP) \
SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP)
#define SECTION_FUNCTION_TEMPLATE(FN, ENUM, OP) \
void FN () \
{ \
if (in_section != ENUM) \
{ \
fprintf (asm_out_file, "%s\n", OP); \
in_section = ENUM; \
} \
}
#undef TARGET_VERSION #undef TARGET_VERSION
#if TARGET_ENDIAN_DEFAULT == 0 #if TARGET_ENDIAN_DEFAULT == 0
#define TARGET_VERSION fprintf (stderr, " (MIPSel GNU/Linux with ELF)"); #define TARGET_VERSION fprintf (stderr, " (MIPSel GNU/Linux with ELF)");
......
...@@ -282,6 +282,8 @@ static hashval_t iris_section_align_entry_hash PARAMS ((const void *)); ...@@ -282,6 +282,8 @@ static hashval_t iris_section_align_entry_hash PARAMS ((const void *));
static int iris6_section_align_1 PARAMS ((void **, void *)); static int iris6_section_align_1 PARAMS ((void **, void *));
static void iris6_file_start PARAMS ((void)); static void iris6_file_start PARAMS ((void));
static void iris6_file_end PARAMS ((void)); static void iris6_file_end PARAMS ((void));
static unsigned int iris6_section_type_flags PARAMS ((tree, const char *,
int));
#endif #endif
static int mips_adjust_cost PARAMS ((rtx, rtx, rtx, int)); static int mips_adjust_cost PARAMS ((rtx, rtx, rtx, int));
static int mips_issue_rate PARAMS ((void)); static int mips_issue_rate PARAMS ((void));
...@@ -289,13 +291,12 @@ static int mips_issue_rate PARAMS ((void)); ...@@ -289,13 +291,12 @@ static int mips_issue_rate PARAMS ((void));
static struct machine_function * mips_init_machine_status PARAMS ((void)); static struct machine_function * mips_init_machine_status PARAMS ((void));
static void mips_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT)) static void mips_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT))
ATTRIBUTE_UNUSED; ATTRIBUTE_UNUSED;
static void mips_unique_section PARAMS ((tree, int))
ATTRIBUTE_UNUSED;
static void mips_select_rtx_section PARAMS ((enum machine_mode, rtx, static void mips_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT)); unsigned HOST_WIDE_INT));
static int mips_use_dfa_pipeline_interface PARAMS ((void)); static int mips_use_dfa_pipeline_interface PARAMS ((void));
static bool mips_rtx_costs PARAMS ((rtx, int, int, int *)); static bool mips_rtx_costs PARAMS ((rtx, int, int, int *));
static int mips_address_cost PARAMS ((rtx)); static int mips_address_cost PARAMS ((rtx));
static bool mips_in_small_data_p PARAMS ((tree));
static void mips_encode_section_info PARAMS ((tree, rtx, int)); static void mips_encode_section_info PARAMS ((tree, rtx, int));
static void mips_file_start PARAMS ((void)); static void mips_file_start PARAMS ((void));
static void mips_file_end PARAMS ((void)); static void mips_file_end PARAMS ((void));
...@@ -888,6 +889,8 @@ const struct mips_cpu_info mips_cpu_info_table[] = { ...@@ -888,6 +889,8 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
#undef TARGET_ENCODE_SECTION_INFO #undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO mips_encode_section_info #define TARGET_ENCODE_SECTION_INFO mips_encode_section_info
#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P mips_in_small_data_p
#undef TARGET_MACHINE_DEPENDENT_REORG #undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG mips_reorg #define TARGET_MACHINE_DEPENDENT_REORG mips_reorg
...@@ -904,6 +907,11 @@ const struct mips_cpu_info mips_cpu_info_table[] = { ...@@ -904,6 +907,11 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
#ifdef TARGET_IRIX6
#undef TARGET_SECTION_TYPE_FLAGS
#define TARGET_SECTION_TYPE_FLAGS iris6_section_type_flags
#endif
struct gcc_target targetm = TARGET_INITIALIZER; struct gcc_target targetm = TARGET_INITIALIZER;
/* If X is one of the constants described by mips_constant_type, /* If X is one of the constants described by mips_constant_type,
...@@ -995,10 +1003,13 @@ mips_classify_symbol (x) ...@@ -995,10 +1003,13 @@ mips_classify_symbol (x)
return SYMBOL_GOT_LOCAL; return SYMBOL_GOT_LOCAL;
} }
if (SYMBOL_REF_SMALL_P (x))
return SYMBOL_SMALL_DATA;
if (TARGET_ABICALLS) if (TARGET_ABICALLS)
return (SYMBOL_REF_FLAG (x) ? SYMBOL_GOT_LOCAL : SYMBOL_GOT_GLOBAL); return (SYMBOL_REF_FLAG (x) ? SYMBOL_GOT_LOCAL : SYMBOL_GOT_GLOBAL);
return (SYMBOL_REF_FLAG (x) ? SYMBOL_SMALL_DATA : SYMBOL_GENERAL); return SYMBOL_GENERAL;
} }
...@@ -4852,11 +4863,6 @@ override_options () ...@@ -4852,11 +4863,6 @@ override_options ()
mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE; mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE;
if (mips_section_threshold <= 0)
target_flags &= ~MASK_GPOPT;
else if (optimize)
target_flags |= MASK_GPOPT;
/* Interpret -mabi. */ /* Interpret -mabi. */
mips_abi = MIPS_ABI_DEFAULT; mips_abi = MIPS_ABI_DEFAULT;
if (mips_abi_string != 0) if (mips_abi_string != 0)
...@@ -5057,10 +5063,7 @@ override_options () ...@@ -5057,10 +5063,7 @@ override_options ()
do this, it was very invasive and fragile. It no longer seems do this, it was very invasive and fragile. It no longer seems
worth the effort. */ worth the effort. */
if (!TARGET_EXPLICIT_RELOCS && !TARGET_GAS) if (!TARGET_EXPLICIT_RELOCS && !TARGET_GAS)
{ mips_section_threshold = 0;
mips_section_threshold = 0;
target_flags &= ~MASK_GPOPT;
}
/* -membedded-pic is a form of PIC code suitable for embedded /* -membedded-pic is a form of PIC code suitable for embedded
systems. All calls are made using PC relative addressing, and systems. All calls are made using PC relative addressing, and
...@@ -5906,16 +5909,13 @@ mips_assemble_integer (x, size, aligned_p) ...@@ -5906,16 +5909,13 @@ mips_assemble_integer (x, size, aligned_p)
return default_assemble_integer (x, size, aligned_p); return default_assemble_integer (x, size, aligned_p);
} }
/* If optimizing for the global pointer, keep track of all of the externs, so /* When using assembler macros, keep track of all of small-data externs
that at the end of the file, we can emit the appropriate .extern so that mips_file_end can emit the appropriate declarations for them.
declaration for them, before writing out the text section. We assume all
names passed to us are in the permanent obstack, so they will be valid at
the end of the compilation.
If we have -G 0, or the extern size is unknown, or the object is in a user In most cases it would be safe (though pointless) to emit .externs
specified section that is not .sbss/.sdata, don't bother emitting the for other symbols too. One exception is when an object is within
.externs. In the case of user specified sections this behavior is the -G limit but declared by the user to be in a section other
required as otherwise GAS will think the object lives in .sbss/.sdata. */ than .sbss or .sdata. */
int int
mips_output_external (file, decl, name) mips_output_external (file, decl, name)
...@@ -5924,21 +5924,13 @@ mips_output_external (file, decl, name) ...@@ -5924,21 +5924,13 @@ mips_output_external (file, decl, name)
const char *name; const char *name;
{ {
register struct extern_list *p; register struct extern_list *p;
int len;
tree section_name;
if (TARGET_GP_OPT if (!TARGET_EXPLICIT_RELOCS && mips_in_small_data_p (decl))
&& TREE_CODE (decl) != FUNCTION_DECL
&& !DECL_COMDAT (decl)
&& (len = int_size_in_bytes (TREE_TYPE (decl))) > 0
&& ((section_name = DECL_SECTION_NAME (decl)) == NULL
|| strcmp (TREE_STRING_POINTER (section_name), ".sbss") == 0
|| strcmp (TREE_STRING_POINTER (section_name), ".sdata") == 0))
{ {
p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list)); p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
p->next = extern_head; p->next = extern_head;
p->name = name; p->name = name;
p->size = len; p->size = int_size_in_bytes (TREE_TYPE (decl));
extern_head = p; extern_head = p;
} }
...@@ -6250,8 +6242,9 @@ mips_file_end () ...@@ -6250,8 +6242,9 @@ mips_file_end ()
} }
} }
/* Emit either a label, .comm, or .lcomm directive, and mark that the symbol /* Emit either a label, .comm, or .lcomm directive. When using assembler
is used, so that we don't emit an .extern for it in mips_file_end. */ macros, mark the symbol as written so that mips_file_end won't emit an
.extern for it. */
void void
mips_declare_object (stream, name, init_string, final_string, size) mips_declare_object (stream, name, init_string, final_string, size)
...@@ -6265,7 +6258,7 @@ mips_declare_object (stream, name, init_string, final_string, size) ...@@ -6265,7 +6258,7 @@ mips_declare_object (stream, name, init_string, final_string, size)
assemble_name (stream, name); assemble_name (stream, name);
fprintf (stream, final_string, size); /* ":\n", ",%u\n", ",%u\n" */ fprintf (stream, final_string, size); /* ":\n", ",%u\n", ",%u\n" */
if (TARGET_GP_OPT) if (!TARGET_EXPLICIT_RELOCS)
{ {
tree name_tree = get_identifier (name); tree name_tree = get_identifier (name);
TREE_ASM_WRITTEN (name_tree) = 1; TREE_ASM_WRITTEN (name_tree) = 1;
...@@ -7812,11 +7805,11 @@ mips_select_rtx_section (mode, x, align) ...@@ -7812,11 +7805,11 @@ mips_select_rtx_section (mode, x, align)
if (GET_MODE_SIZE (mode) <= (unsigned) mips_section_threshold if (GET_MODE_SIZE (mode) <= (unsigned) mips_section_threshold
&& mips_section_threshold > 0) && mips_section_threshold > 0)
SMALL_DATA_SECTION (); named_section (0, ".sdata", 0);
else if (flag_pic && symbolic_expression_p (x)) else if (flag_pic && symbolic_expression_p (x))
{ {
if (targetm.have_named_sections) if (targetm.have_named_sections)
named_section (NULL_TREE, ".data.rel.ro", 3); named_section (0, ".data.rel.ro", 3);
else else
data_section (); data_section ();
} }
...@@ -7826,9 +7819,7 @@ mips_select_rtx_section (mode, x, align) ...@@ -7826,9 +7819,7 @@ mips_select_rtx_section (mode, x, align)
} }
/* Choose the section to use for DECL. RELOC is true if its value contains /* Choose the section to use for DECL. RELOC is true if its value contains
any relocatable expression. any relocatable expression. */
??? This would be fixed by implementing targetm.is_small_data_p. */
static void static void
mips_select_section (decl, reloc, align) mips_select_section (decl, reloc, align)
...@@ -7836,8 +7827,6 @@ mips_select_section (decl, reloc, align) ...@@ -7836,8 +7827,6 @@ mips_select_section (decl, reloc, align)
int reloc; int reloc;
unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED; unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
{ {
int size = int_size_in_bytes (TREE_TYPE (decl));
if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16) if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16)
&& TREE_CODE (decl) == STRING_CST && TREE_CODE (decl) == STRING_CST
&& !flag_writable_strings) && !flag_writable_strings)
...@@ -7846,54 +7835,66 @@ mips_select_section (decl, reloc, align) ...@@ -7846,54 +7835,66 @@ mips_select_section (decl, reloc, align)
For mips16 code, put strings in the text section so that a PC For mips16 code, put strings in the text section so that a PC
relative load instruction can be used to get their address. */ relative load instruction can be used to get their address. */
text_section (); text_section ();
else if (TARGET_EMBEDDED_DATA) else
default_elf_select_section (decl, reloc, align);
}
/* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
access DECL using %gp_rel(...)($gp). */
static bool
mips_in_small_data_p (decl)
tree decl;
{
HOST_WIDE_INT size;
if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
return false;
if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
{ {
/* For embedded applications, always put an object in read-only data const char *name;
if possible, in order to reduce RAM usage. */
/* Reject anything that isn't in a known small-data section. */
if (((TREE_CODE (decl) == VAR_DECL name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
&& TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl) if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
&& DECL_INITIAL (decl) return false;
&& (DECL_INITIAL (decl) == error_mark_node
|| TREE_CONSTANT (DECL_INITIAL (decl)))) /* If a symbol is defined externally, the assembler will use the
/* Deal with calls from output_constant_def_contents. */ usual -G rules when deciding how to implement macros. */
|| (TREE_CODE (decl) != VAR_DECL if (TARGET_EXPLICIT_RELOCS || !DECL_EXTERNAL (decl))
&& (TREE_CODE (decl) != STRING_CST return true;
|| !flag_writable_strings)))
&& ! (flag_pic && reloc))
readonly_data_section ();
else if (size > 0 && size <= mips_section_threshold)
SMALL_DATA_SECTION ();
else
data_section ();
} }
else else if (TARGET_EMBEDDED_DATA)
{ {
/* For hosted applications, always put an object in small data if /* Don't put constants into the small data section: we want them
possible, as this gives the best performance. */ to be in ROM rather than RAM. */
if (TREE_CODE (decl) != VAR_DECL)
return false;
if (size > 0 && size <= mips_section_threshold) if (TREE_READONLY (decl)
SMALL_DATA_SECTION (); && !TREE_SIDE_EFFECTS (decl)
else if (((TREE_CODE (decl) == VAR_DECL && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
&& TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl) return false;
&& DECL_INITIAL (decl)
&& (DECL_INITIAL (decl) == error_mark_node
|| TREE_CONSTANT (DECL_INITIAL (decl))))
/* Deal with calls from output_constant_def_contents. */
|| (TREE_CODE (decl) != VAR_DECL
&& (TREE_CODE (decl) != STRING_CST
|| !flag_writable_strings)))
&& ! (flag_pic && reloc))
readonly_data_section ();
else
data_section ();
} }
else if (TARGET_MIPS16)
{
/* Alhough it seems strange to have separate rules for -mips16,
this behaviour is long-standing. */
if (TREE_PUBLIC (decl)
&& (DECL_COMMON (decl)
|| DECL_ONE_ONLY (decl)
|| DECL_WEAK (decl)))
return false;
}
size = int_size_in_bytes (TREE_TYPE (decl));
return (size > 0 && size <= mips_section_threshold);
} }
/* When optimizing for the $gp pointer, SYMBOL_REF_FLAG is set for all
small objects.
When generating embedded PIC code, SYMBOL_REF_FLAG is set for /* When generating embedded PIC code, SYMBOL_REF_FLAG is set for
symbols which are not in the .text section. symbols which are not in the .text section.
When generating mips16 code, SYMBOL_REF_FLAG is set for string When generating mips16 code, SYMBOL_REF_FLAG is set for string
...@@ -7902,20 +7903,8 @@ mips_select_section (decl, reloc, align) ...@@ -7902,20 +7903,8 @@ mips_select_section (decl, reloc, align)
whether we need to split the constant table, and need not be whether we need to split the constant table, and need not be
precisely correct. precisely correct.
When not mips16 code nor embedded PIC, if a symbol is in a When generating -mabicalls code, SYMBOL_REF_FLAG is set if we
gp addressable section, SYMBOL_REF_FLAG is set prevent gcc from should treat the symbol as SYMBOL_GOT_LOCAL. */
splitting the reference so that gas can generate a gp relative
reference.
When TARGET_EMBEDDED_DATA is set, we assume that all const
variables will be stored in ROM, which is too far from %gp to use
%gprel addressing. Note that (1) we include "extern const"
variables in this, which mips_select_section doesn't, and (2) we
can't always tell if they're really const (they might be const C++
objects with non-const constructors), so we err on the side of
caution and won't use %gprel anyway (otherwise we'd have to defer
this decision to the linker/loader). The handling of extern consts
is why the DECL_INITIAL macros differ from mips_select_section. */
static void static void
mips_encode_section_info (decl, rtl, first) mips_encode_section_info (decl, rtl, first)
...@@ -7957,16 +7946,7 @@ mips_encode_section_info (decl, rtl, first) ...@@ -7957,16 +7946,7 @@ mips_encode_section_info (decl, rtl, first)
} }
} }
if (TARGET_EMBEDDED_DATA if (TARGET_EMBEDDED_PIC)
&& (TREE_CODE (decl) == VAR_DECL
&& TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl))
&& (!DECL_INITIAL (decl)
|| TREE_CONSTANT (DECL_INITIAL (decl))))
{
SYMBOL_REF_FLAG (symbol) = 0;
}
else if (TARGET_EMBEDDED_PIC)
{ {
if (TREE_CODE (decl) == VAR_DECL) if (TREE_CODE (decl) == VAR_DECL)
SYMBOL_REF_FLAG (symbol) = 1; SYMBOL_REF_FLAG (symbol) = 1;
...@@ -8008,32 +7988,7 @@ mips_encode_section_info (decl, rtl, first) ...@@ -8008,32 +7988,7 @@ mips_encode_section_info (decl, rtl, first)
SYMBOL_REF_FLAG (symbol) = 1; SYMBOL_REF_FLAG (symbol) = 1;
} }
else if (TREE_CODE (decl) == VAR_DECL default_encode_section_info (decl, rtl, first);
&& DECL_SECTION_NAME (decl) != NULL_TREE
&& (0 == strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
".sdata")
|| 0 == strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
".sbss")))
{
SYMBOL_REF_FLAG (symbol) = 1;
}
/* We can not perform GP optimizations on variables which are in
specific sections, except for .sdata and .sbss which are
handled above. */
else if (TARGET_GP_OPT && TREE_CODE (decl) == VAR_DECL
&& DECL_SECTION_NAME (decl) == NULL_TREE
&& ! (TARGET_MIPS16 && TREE_PUBLIC (decl)
&& (DECL_COMMON (decl)
|| DECL_ONE_ONLY (decl)
|| DECL_WEAK (decl))))
{
int size = int_size_in_bytes (TREE_TYPE (decl));
if (size > 0 && size <= mips_section_threshold)
SYMBOL_REF_FLAG (symbol) = 1;
}
} }
...@@ -10243,81 +10198,6 @@ mips_adjust_cost (insn, link, dep, cost) ...@@ -10243,81 +10198,6 @@ mips_adjust_cost (insn, link, dep, cost)
return cost; return cost;
} }
/* ??? This could be replaced with the default elf version if
TARGET_IS_SMALL_DATA_P is set properly. */
static void
mips_unique_section (decl, reloc)
tree decl;
int reloc;
{
int len, size, sec;
const char *name, *prefix;
char *string;
static const char *const prefixes[4][2] = {
{ ".text.", ".gnu.linkonce.t." },
{ ".rodata.", ".gnu.linkonce.r." },
{ ".data.", ".gnu.linkonce.d." },
{ ".sdata.", ".gnu.linkonce.s." }
};
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
name = (* targetm.strip_name_encoding) (name);
size = int_size_in_bytes (TREE_TYPE (decl));
/* Determine the base section we are interested in:
0=text, 1=rodata, 2=data, 3=sdata, [4=bss]. */
if (TREE_CODE (decl) == FUNCTION_DECL)
sec = 0;
else if (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node)
sec = 2;
else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16)
&& TREE_CODE (decl) == STRING_CST
&& !flag_writable_strings)
{
/* For embedded position independent code, put constant
strings in the text section, because the data section
is limited to 64K in size. For mips16 code, put
strings in the text section so that a PC relative load
instruction can be used to get their address. */
sec = 0;
}
else if (TARGET_EMBEDDED_DATA)
{
/* For embedded applications, always put an object in
read-only data if possible, in order to reduce RAM
usage. */
if (decl_readonly_section (decl, reloc))
sec = 1;
else if (size > 0 && size <= mips_section_threshold)
sec = 3;
else
sec = 2;
}
else
{
/* For hosted applications, always put an object in
small data if possible, as this gives the best
performance. */
if (size > 0 && size <= mips_section_threshold)
sec = 3;
else if (decl_readonly_section (decl, reloc))
sec = 1;
else
sec = 2;
}
prefix = prefixes[sec][DECL_ONE_ONLY (decl)];
len = strlen (name) + strlen (prefix);
string = alloca (len + 1);
sprintf (string, "%s%s", prefix, name);
DECL_SECTION_NAME (decl) = build_string (len, string);
}
unsigned int unsigned int
mips_hard_regno_nregs (regno, mode) mips_hard_regno_nregs (regno, mode)
int regno; int regno;
...@@ -10585,6 +10465,32 @@ iris6_file_end () ...@@ -10585,6 +10465,32 @@ iris6_file_end ()
mips_file_end (); mips_file_end ();
} }
/* Implement TARGET_SECTION_TYPE_FLAGS. Make sure that .sdata and
.sbss sections get the SECTION_SMALL flag: this isn't set by the
default code. */
static unsigned int
iris6_section_type_flags (decl, section, relocs_p)
tree decl;
const char *section;
int relocs_p;
{
unsigned int flags;
flags = default_section_type_flags (decl, section, relocs_p);
if (strcmp (section, ".sdata") == 0
|| strcmp (section, ".sbss") == 0
|| strncmp (section, ".gnu.linkonce.s.", 16) == 0
|| strncmp (section, ".gnu.linkonce.sb.", 17) == 0)
flags |= SECTION_SMALL;
return flags;
}
#endif /* TARGET_IRIX6 */ #endif /* TARGET_IRIX6 */
#include "gt-mips.h" #include "gt-mips.h"
...@@ -148,10 +148,6 @@ extern const struct mips_cpu_info mips_cpu_info_table[]; ...@@ -148,10 +148,6 @@ extern const struct mips_cpu_info mips_cpu_info_table[];
extern const struct mips_cpu_info *mips_arch_info; extern const struct mips_cpu_info *mips_arch_info;
extern const struct mips_cpu_info *mips_tune_info; extern const struct mips_cpu_info *mips_tune_info;
/* Functions to change what output section we are using. */
extern void sdata_section PARAMS ((void));
extern void sbss_section PARAMS ((void));
/* Macros to silence warnings about numbers being signed in traditional /* Macros to silence warnings about numbers being signed in traditional
C and unsigned in ISO C when compiled on 32-bit hosts. */ C and unsigned in ISO C when compiled on 32-bit hosts. */
...@@ -168,7 +164,8 @@ extern void sbss_section PARAMS ((void)); ...@@ -168,7 +164,8 @@ extern void sbss_section PARAMS ((void));
#define MASK_INT64 0x00000001 /* ints are 64 bits */ #define MASK_INT64 0x00000001 /* ints are 64 bits */
#define MASK_LONG64 0x00000002 /* longs are 64 bits */ #define MASK_LONG64 0x00000002 /* longs are 64 bits */
#define MASK_SPLIT_ADDR 0x00000004 /* Address splitting is enabled. */ #define MASK_SPLIT_ADDR 0x00000004 /* Address splitting is enabled. */
#define MASK_GPOPT 0x00000008 /* Optimize for global pointer */ #define MASK_NO_FUSED_MADD 0x00000008 /* Don't generate floating point
multiply-add operations. */
#define MASK_GAS 0x00000010 /* Gas used instead of MIPS as */ #define MASK_GAS 0x00000010 /* Gas used instead of MIPS as */
#define MASK_NAME_REGS 0x00000020 /* Use MIPS s/w reg name convention */ #define MASK_NAME_REGS 0x00000020 /* Use MIPS s/w reg name convention */
#define MASK_EXPLICIT_RELOCS 0x00000040 /* Use relocation operators. */ #define MASK_EXPLICIT_RELOCS 0x00000040 /* Use relocation operators. */
...@@ -193,8 +190,6 @@ extern void sbss_section PARAMS ((void)); ...@@ -193,8 +190,6 @@ extern void sbss_section PARAMS ((void));
#define MASK_UNINIT_CONST_IN_RODATA \ #define MASK_UNINIT_CONST_IN_RODATA \
0x00800000 /* Store uninitialized 0x00800000 /* Store uninitialized
consts in rodata */ consts in rodata */
#define MASK_NO_FUSED_MADD 0x01000000 /* Don't generate floating point
multiply-add operations. */
/* Debug switches, not documented */ /* Debug switches, not documented */
#define MASK_DEBUG 0 /* unused */ #define MASK_DEBUG 0 /* unused */
...@@ -237,9 +232,6 @@ extern void sbss_section PARAMS ((void)); ...@@ -237,9 +232,6 @@ extern void sbss_section PARAMS ((void));
/* Reg. Naming in .s ($21 vs. $a0) */ /* Reg. Naming in .s ($21 vs. $a0) */
#define TARGET_NAME_REGS (target_flags & MASK_NAME_REGS) #define TARGET_NAME_REGS (target_flags & MASK_NAME_REGS)
/* Optimize for Sdata/Sbss */
#define TARGET_GP_OPT (target_flags & MASK_GPOPT)
/* call memcpy instead of inline code */ /* call memcpy instead of inline code */
#define TARGET_MEMCPY (target_flags & MASK_MEMCPY) #define TARGET_MEMCPY (target_flags & MASK_MEMCPY)
...@@ -532,14 +524,14 @@ extern void sbss_section PARAMS ((void)); ...@@ -532,14 +524,14 @@ extern void sbss_section PARAMS ((void));
N_("Use symbolic register names")}, \ N_("Use symbolic register names")}, \
{"no-rnames", -MASK_NAME_REGS, \ {"no-rnames", -MASK_NAME_REGS, \
N_("Don't use symbolic register names")}, \ N_("Don't use symbolic register names")}, \
{"gpOPT", MASK_GPOPT, \ {"gpOPT", 0, \
N_("Use GP relative sdata/sbss sections")}, \ N_("Use GP relative sdata/sbss sections (now ignored)")}, \
{"gpopt", MASK_GPOPT, \ {"gpopt", 0, \
N_("Use GP relative sdata/sbss sections")}, \ N_("Use GP relative sdata/sbss sections (now ignored)")}, \
{"no-gpOPT", -MASK_GPOPT, \ {"no-gpOPT", 0, \
N_("Don't use GP relative sdata/sbss sections")}, \ N_("Don't use GP relative sdata/sbss sections (now ignored)")}, \
{"no-gpopt", -MASK_GPOPT, \ {"no-gpopt", 0, \
N_("Don't use GP relative sdata/sbss sections")}, \ N_("Don't use GP relative sdata/sbss sections (now ignored)")}, \
{"stats", 0, \ {"stats", 0, \
N_("Output compiler statistics (now ignored)")}, \ N_("Output compiler statistics (now ignored)")}, \
{"no-stats", 0, \ {"no-stats", 0, \
...@@ -3863,35 +3855,6 @@ do { \ ...@@ -3863,35 +3855,6 @@ do { \
#undef READONLY_DATA_SECTION_ASM_OP #undef READONLY_DATA_SECTION_ASM_OP
#define READONLY_DATA_SECTION_ASM_OP "\t.rdata" /* read-only data */ #define READONLY_DATA_SECTION_ASM_OP "\t.rdata" /* read-only data */
#define SMALL_DATA_SECTION sdata_section
/* What other sections we support other than the normal .data/.text. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_sdata
/* Define the additional functions to select our additional sections. */
/* on the MIPS it is not a good idea to put constants in the text
section, since this defeats the sdata/data mechanism. This is
especially true when -O is used. In this case an effort is made to
address with faster (gp) register relative addressing, which can
only get at sdata and sbss items (there is no stext !!) However,
if the constant is too large for sdata, and it's readonly, it
will go into the .rdata section. */
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
void \
sdata_section () \
{ \
if (in_section != in_sdata) \
{ \
fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP); \
in_section = in_sdata; \
} \
}
/* Given a decl node or constant node, choose the section to output it in /* Given a decl node or constant node, choose the section to output it in
and select that section. */ and select that section. */
......
...@@ -465,14 +465,13 @@ in the following sections. ...@@ -465,14 +465,13 @@ in the following sections.
@gccoptlist{-mabicalls -march=@var{cpu-type} -mtune=@var{cpu=type} @gol @gccoptlist{-mabicalls -march=@var{cpu-type} -mtune=@var{cpu=type} @gol
-mcpu=@var{cpu-type} -membedded-data -muninit-const-in-rodata @gol -mcpu=@var{cpu-type} -membedded-data -muninit-const-in-rodata @gol
-membedded-pic -mfp32 -mfp64 -mfused-madd -mno-fused-madd @gol -membedded-pic -mfp32 -mfp64 -mfused-madd -mno-fused-madd @gol
-mgas -mgp32 -mgp64 @gol -mgas -mgp32 -mgp64 -mhard-float -mint64 -mips1 @gol
-mgpopt -mhalf-pic -mhard-float -mint64 -mips1 @gol
-mips2 -mips3 -mips4 -mips32 -mips32r2 -mips64 @gol -mips2 -mips3 -mips4 -mips32 -mips32r2 -mips64 @gol
-mlong64 -mlong32 -mlong-calls -mmemcpy @gol -mlong64 -mlong32 -mlong-calls -mmemcpy @gol
-mmips-as -mmips-tfile -mno-abicalls @gol -mmips-as -mmips-tfile -mno-abicalls @gol
-mno-embedded-data -mno-uninit-const-in-rodata @gol -mno-embedded-data -mno-uninit-const-in-rodata @gol
-mno-embedded-pic -mno-gpopt -mno-long-calls @gol -mno-embedded-pic -mno-long-calls @gol
-mno-memcpy -mno-mips-tfile -mno-rnames -mno-stats @gol -mno-memcpy -mno-mips-tfile -mno-rnames @gol
-mrnames -msoft-float @gol -mrnames -msoft-float @gol
-m4650 -msingle-float -mmad @gol -m4650 -msingle-float -mmad @gol
-EL -EB -G @var{num} -nocpp @gol -EL -EB -G @var{num} -nocpp @gol
...@@ -7962,16 +7961,6 @@ names for the registers, instead of the hardware names (ie, @var{a0} ...@@ -7962,16 +7961,6 @@ names for the registers, instead of the hardware names (ie, @var{a0}
instead of @var{$4}). The only known assembler that supports this option instead of @var{$4}). The only known assembler that supports this option
is the Algorithmics assembler. is the Algorithmics assembler.
@item -mgpopt
@itemx -mno-gpopt
@opindex mgpopt
@opindex mno-gpopt
The @option{-mgpopt} switch says to write all of the data declarations
before the instructions in the text section, this allows the MIPS
assembler to generate one word memory references instead of using two
words for short global or static data items. This is on by default if
optimization is selected.
@item -mmemcpy @item -mmemcpy
@itemx -mno-memcpy @itemx -mno-memcpy
@opindex mmemcpy @opindex mmemcpy
...@@ -8026,13 +8015,6 @@ loading up a function's address into a register before the call. ...@@ -8026,13 +8015,6 @@ loading up a function's address into a register before the call.
You need to use this switch, if you call outside of the current You need to use this switch, if you call outside of the current
512 megabyte segment to functions that are not through pointers. 512 megabyte segment to functions that are not through pointers.
@item -mhalf-pic
@itemx -mno-half-pic
@opindex mhalf-pic
@opindex mno-half-pic
Put pointers to extern references into the data section and load them
up, rather than put the references in the text section.
@item -membedded-pic @item -membedded-pic
@itemx -mno-embedded-pic @itemx -mno-embedded-pic
@opindex membedded-pic @opindex membedded-pic
......
2003-07-08 Richard Sandiford <rsandifo@redhat.com>
* gcc.dg/compat/sdata-section.h: New file.
* gcc.dg/compat/sdata-1_{x,y,main}.c: New test.
* gcc.dg/torture/mips-sdata-1.c: New test.
2003-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> 2003-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/11030 PR c++/11030
......
/* Check that sdata qualification doesn't produce out-of-range relocations
and that compilers agree on the way these declarations are handled. */
extern void sdata_1_x (void);
extern void exit (int);
int
main ()
{
sdata_1_x ();
exit (0);
}
#include "sdata-section.h"
struct s { int x; int y[4]; };
extern struct s small_struct SDATA_SECTION;
/* Test "load address" operations. */
int *xaddr (void) { return &small_struct.x; }
int *yaddr (int i) { return &small_struct.y[i]; }
void sdata_1_x (void)
{
int i;
/* Test direct accesses. */
small_struct.x = 5;
for (i = 0; i < 4; i++)
small_struct.y[i] = i + 42;
if (*xaddr () != 5)
abort ();
for (i = 0; i < 4; i++)
if (*yaddr (i) != i + 42)
abort ();
}
#include "sdata-section.h"
struct s { int x; int y[4]; };
struct s small_struct SDATA_SECTION;
#ifdef __mips
#define SDATA_SECTION __attribute__((__section__(".sdata")))
#else
#define SDATA_SECTION
#endif
/* Check that sdata-accesses are applied regardless of size or ABI. */
/* { dg-options -mexplicit-relocs } */
/* { dg-do compile { target mips*-*-* } } */
struct s { int x[4]; };
struct s my_struct __attribute__((__section__(".sdata")));
int f() { return my_struct.x[3]; }
/* { dg-final { scan-assembler {gp_?rel\(my_struct} } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment