/* Which abi to adhere to */
char *rs6000_abi_name = RS6000_ABI_NAME;
+
+/* Semantics of the small data area */
+enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
+
+/* Which small data model to use */
+char *rs6000_sdata_name = (char *)0;
#endif
/* Whether a System V.4 varargs area was created. */
if (rs6000_select[j].string != (char *)0)
pos = output_option (file, rs6000_select[j].name, rs6000_select[j].string, pos);
+#ifdef USING_SVR4_H
+ switch (rs6000_sdata)
+ {
+ case SDATA_NONE: pos = output_option (file, "-msdata=", "none", pos); break;
+ case SDATA_DATA: pos = output_option (file, "-msdata=", "data", pos); break;
+ case SDATA_SYSV: pos = output_option (file, "-msdata=", "sysv", pos); break;
+ case SDATA_EABI: pos = output_option (file, "-msdata=", "eabi", pos); break;
+ }
+#endif
+
fputs ("\n\n", file);
}
rtx op;
enum machine_mode mode;
{
+#ifdef TARGET_SDATA
rtx sym_ref, const_part;
-#ifdef TARGET_SDATA
- if (!TARGET_SDATA)
+ if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
return 0;
-#endif
if (DEFAULT_ABI != ABI_V4 /* && DEFAULT_ABI != ABI_SOLARIS */)
return 0;
return 0;
return 1;
+
+#else
+ return 0;
+#endif
}
\f
\f
/* Print an operand. Recognize special options, documented below. */
-#ifdef TARGET_EABI
-#define SMALL_DATA_RELOC ((TARGET_EABI) ? "sda21" : "sdarel")
+#ifdef TARGET_SDATA
+#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
#else
#define SMALL_DATA_RELOC "sda21"
#endif
|| (DECL_INITIAL (decl) != error_mark_node
&& !TREE_CONSTANT (DECL_INITIAL (decl))))
{
- if (TARGET_SDATA && (size > 0) && (size <= g_switch_value))
+ if (rs6000_sdata != SDATA_NONE && (size > 0) && (size <= g_switch_value))
sdata_section ();
else
data_section ();
}
else
{
- if (TARGET_SDATA && (size > 0) && (size <= g_switch_value))
+ if (rs6000_sdata != SDATA_NONE && (size > 0) && (size <= g_switch_value))
{
-#ifdef TARGET_EABI
- if (TARGET_EABI)
+ if (rs6000_sdata == SDATA_EABI)
sdata2_section ();
else
-#endif
sdata_section (); /* System V doesn't have .sdata2/.sbss2 */
}
else
else
const_section ();
}
+
+\f
+
+/* If we are referencing a function that is static or is known to be
+ in this file, make the SYMBOL_REF special. We can use this to indicate
+ that we can branch to this function without emitting a no-op after the
+ call. For real AIX and NT calling sequences, we also replace the
+ function name with the real name (1 or 2 leading .'s), rather than
+ the function descriptor name. This saves a lot of overriding code
+ to readd the prefixes. */
+
+void
+rs6000_encode_section_info (decl)
+ tree decl;
+{
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ rtx sym_ref = XEXP (DECL_RTL (decl), 0);
+ if (TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl))
+ SYMBOL_REF_FLAG (sym_ref) = 1;
+
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
+ {
+ char *prefix = (DEFAULT_ABI == ABI_AIX) ? "." : "..";
+ char *str = permalloc (strlen (prefix) + 1
+ + strlen (XSTR (sym_ref, 0)));
+ strcpy (str, prefix);
+ strcat (str, XSTR (sym_ref, 0));
+ XSTR (sym_ref, 0) = str;
+ }
+ }
+ else if (rs6000_sdata != SDATA_NONE
+ && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
+ && TREE_CODE (decl) == VAR_DECL)
+ {
+ int size = int_size_in_bytes (TREE_TYPE (decl));
+ tree section_name = DECL_SECTION_NAME (decl);
+ char *name = (char *)0;
+ int len = 0;
+
+ if (section_name)
+ {
+ if (TREE_CODE (section_name) == STRING_CST)
+ {
+ name = TREE_STRING_POINTER (section_name);
+ len = TREE_STRING_LENGTH (section_name);
+ }
+ else
+ abort ();
+ }
+
+ if ((size > 0 && size <= g_switch_value)
+ || (name
+ && ((len == sizeof (".sdata")-1 && strcmp (name, ".sdata") == 0)
+ || (len == sizeof (".sdata2")-1 && strcmp (name, ".sdata2") == 0)
+ || (len == sizeof (".sbss")-1 && strcmp (name, ".sbss") == 0)
+ || (len == sizeof (".sbss2")-1 && strcmp (name, ".sbss2") == 0)
+ || (len == sizeof (".PPC.EMB.sdata0")-1 && strcmp (name, ".PPC.EMB.sdata0") == 0)
+ || (len == sizeof (".PPC.EMB.sbss0")-1 && strcmp (name, ".PPC.EMB.sbss0") == 0))))
+ {
+ rtx sym_ref = XEXP (DECL_RTL (decl), 0);
+ char *str = permalloc (2 + strlen (XSTR (sym_ref, 0)));
+ strcpy (str, "@");
+ strcat (str, XSTR (sym_ref, 0));
+ XSTR (sym_ref, 0) = str;
+ }
+ }
+}
+
#endif /* USING_SVR4_H */
\f
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* eABI local switches -- put here rather than eabi.h, so the switches
- can be tested in macros. */
+/* Small data support types */
+enum rs6000_sdata_type {
+ SDATA_NONE, /* no small data support */
+ SDATA_DATA, /* just put data in .sbss/.sdata, don't use relocs */
+ SDATA_SYSV, /* Use r13 to point to .sdata/.sbss */
+ SDATA_EABI /* Use r13 like above, r2 points to .sdata2/.sbss2 */
+};
+extern enum rs6000_sdata_type rs6000_sdata;
+
+/* V.4/eabi switches */
#define MASK_NO_BITFIELD_TYPE 0x40000000 /* Set PCC_BITFIELD_TYPE_MATTERS to 0 */
#define MASK_STRICT_ALIGN 0x20000000 /* Set STRICT_ALIGNMENT to 1. */
#define MASK_RELOCATABLE 0x10000000 /* GOT pointers are PC relative */
-#define MASK_SDATA 0x08000000 /* use eabi .sdata/.sdata2/.sbss relocations */
+#define MASK_SDATA 0x08000000 /* use small data areas */
#define MASK_LITTLE_ENDIAN 0x04000000 /* target is little endian */
#define MASK_REGNAMES 0x02000000 /* use alternate register names. */
#define MASK_PROTOTYPE 0x01000000 /* Only prototyped fcns pass variable args */
{ "relocatable", -MASK_SDATA }, \
{ "no-relocatable", -MASK_RELOCATABLE }, \
{ "relocatable-lib", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
+ { "relocatable-lib", -MASK_SDATA }, \
{ "no-relocatable-lib", -MASK_RELOCATABLE }, \
{ "sdata", MASK_SDATA }, \
{ "no-sdata", -MASK_SDATA }, \
{ "emb", 0 }, \
{ "newlib", 0 },
-/* Which abi to adhere to */
-extern char *rs6000_abi_name;
-
/* Default ABI to use */
#define RS6000_ABI_NAME "sysv"
-#define SUBTARGET_OPTIONS {"call-", &rs6000_abi_name}
+/* Strings provided by SUBTARGET_OPTIONS */
+extern char *rs6000_abi_name;
+extern char *rs6000_sdata_name;
+
+#define SUBTARGET_OPTIONS \
+ { "call-", &rs6000_abi_name}, \
+ { "sdata=", &rs6000_sdata_name}
/* Max # of bytes for variables to automatically be put into the .sdata
or .sdata2 sections. */
error ("Bad value for -mcall-%s", rs6000_abi_name); \
} \
\
- /* CYGNUS LOCAL -fcombine-statics vs. -msdata */ \
- if (TARGET_SDATA) \
- flag_combine_statics = 0; \
- /* END CYGNUS LOCAL -fcombine-statics vs. -msdata */ \
+ if (rs6000_sdata_name) \
+ { \
+ target_flags |= MASK_SDATA; \
+ if (!strcmp (rs6000_sdata_name, "none")) \
+ { \
+ rs6000_sdata = SDATA_NONE; \
+ target_flags &= ~MASK_SDATA; \
+ } \
+ else if (!strcmp (rs6000_sdata_name, "data")) \
+ rs6000_sdata = SDATA_DATA; \
+ else if (!strcmp (rs6000_sdata_name, "default")) \
+ rs6000_sdata = (TARGET_EABI) ? SDATA_EABI : SDATA_SYSV; \
+ else if (!strcmp (rs6000_sdata_name, "sysv")) \
+ rs6000_sdata = SDATA_SYSV; \
+ else if (!strcmp (rs6000_sdata_name, "eabi")) \
+ rs6000_sdata = SDATA_EABI; \
+ else \
+ error ("Bad value for -msdata=%s", rs6000_sdata_name); \
+ } \
+ else if (TARGET_SDATA) \
+ rs6000_sdata = (TARGET_EABI) ? SDATA_EABI : SDATA_SYSV; \
+ else if (!TARGET_RELOCATABLE && !flag_pic \
+ && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) \
+ { \
+ rs6000_sdata = SDATA_DATA; \
+ target_flags |= MASK_SDATA; \
+ } \
+ else \
+ rs6000_sdata = SDATA_NONE; \
\
- if (TARGET_RELOCATABLE && TARGET_SDATA) \
+ if (TARGET_RELOCATABLE && \
+ (rs6000_sdata == SDATA_EABI || rs6000_sdata == SDATA_SYSV)) \
{ \
target_flags &= ~MASK_SDATA; \
+ rs6000_sdata = SDATA_NONE; \
error ("-mrelocatable and -msdata are incompatible."); \
} \
\
to readd the prefixes. */
#undef ENCODE_SECTION_INFO
-#define ENCODE_SECTION_INFO(DECL) \
- do { \
- if (TREE_CODE (DECL) == FUNCTION_DECL) \
- { \
- rtx sym_ref = XEXP (DECL_RTL (DECL), 0); \
- if (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL)) \
- SYMBOL_REF_FLAG (sym_ref) = 1; \
- \
- if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT) \
- { \
- char *prefix = (DEFAULT_ABI == ABI_AIX) ? "." : ".."; \
- char *str = permalloc (strlen (prefix) + 1 \
- + strlen (XSTR (sym_ref, 0))); \
- strcpy (str, prefix); \
- strcat (str, XSTR (sym_ref, 0)); \
- XSTR (sym_ref, 0) = str; \
- } \
- } \
- else if (TARGET_SDATA \
- && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \
- && TREE_CODE (DECL) == VAR_DECL) \
- { \
- int size = int_size_in_bytes (TREE_TYPE (DECL)); \
- tree section_name = DECL_SECTION_NAME (DECL); \
- char *name = ((section_name) \
- ? IDENTIFIER_POINTER (section_name) \
- : (char *)0); \
- \
- if ((size > 0 && size <= 8) \
- || (name \
- && (strcmp (name, ".sdata") == 0 \
- || strcmp (name, ".sdata2") == 0 \
- || strcmp (name, ".sbss") == 0 \
- || strcmp (name, ".sbss2") == 0 \
- || strcmp (name, ".PPC.EMB.sdata0") == 0 \
- || strcmp (name, ".PPC.EMB.sbss0") == 0))) \
- { \
- rtx sym_ref = XEXP (DECL_RTL (DECL), 0); \
- char *str = permalloc (2 + strlen (XSTR (sym_ref, 0))); \
- strcpy (str, "@"); \
- strcat (str, XSTR (sym_ref, 0)); \
- XSTR (sym_ref, 0) = str; \
- } \
- } \
- } while (0)
+#define ENCODE_SECTION_INFO(DECL) rs6000_encode_section_info (DECL)
+
+extern void rs6000_encode_section_info ();
/* This macro gets just the user-specified name
out of the string in a SYMBOL_REF. Discard
#undef ASM_SPEC
#define ASM_SPEC "-u %(asm_cpu) %{mregnames} \
%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
-%{mrelocatable} %{mrelocatable-lib} %{memb} %{msdata: -memb} \
+%{mrelocatable} %{mrelocatable-lib} \
+%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb} \
%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian} \
%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
%{mcall-solaris: -mlittle} %{mcall-linux: -mbig} }}}}"
%{mcall-solaris: -mlittle } \
%{mcall-linux: -mbig} }}}} \
%{mcall-solaris: -mregnames } \
+%{mno-sdata: -msdata=none } \
%{meabi: %{!mcall-*: -mcall-sysv }} \
%{!meabi: %{!mno-eabi: \
%{mcall-solaris: -mno-eabi } \