diff options
author | Michael Meissner <meissner@gcc.gnu.org> | 1996-05-09 17:41:03 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 1996-05-09 17:41:03 +0000 |
commit | d940798813cdab349a9dde7fb5e3e57433158c5e (patch) | |
tree | 05c07ef158c41fd7ac35c38844157c80d067dedc /gcc/config/rs6000/rs6000.c | |
parent | 0821c881a28809b77b4b77d65a7b5d31ba6202e3 (diff) | |
download | gcc-d940798813cdab349a9dde7fb5e3e57433158c5e.tar.gz |
Add fine grain control to -msdata
From-SVN: r11959
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 106 |
1 files changed, 96 insertions, 10 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 0924cf4a165..2ebd552ccaa 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -82,6 +82,12 @@ int rs6000_pic_labelno; /* 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. */ @@ -224,6 +230,16 @@ output_options (file, f_options, f_len, W_options, W_len) 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); } @@ -1014,12 +1030,11 @@ small_data_operand (op, mode) 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; @@ -1040,6 +1055,10 @@ small_data_operand (op, mode) return 0; return 1; + +#else + return 0; +#endif } @@ -2080,8 +2099,8 @@ ccr_bit (op, scc_p) /* 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 @@ -4609,20 +4628,18 @@ rs6000_select_section (decl, reloc) || (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 @@ -4632,6 +4649,75 @@ rs6000_select_section (decl, reloc) else const_section (); } + + + +/* 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 */ |