#include "expr.h"
#include "hard-reg-set.h"
#include "regs.h"
-#include "output.h"
#include "real.h"
+#include "output.h"
#include "toplev.h"
#include "hashtab.h"
#include "c-pragma.h"
#endif /* BSS_SECTION_ASM_OP */
static hashval_t const_str_htab_hash PARAMS ((const void *x));
static int const_str_htab_eq PARAMS ((const void *x, const void *y));
-static void asm_emit_uninitialised PARAMS ((tree, const char*, int, int));
+static bool asm_emit_uninitialised PARAMS ((tree, const char*, int, int));
static void resolve_unique_section PARAMS ((tree, int, int));
static void mark_weak PARAMS ((tree));
\f
const char *name;
int size ATTRIBUTE_UNUSED, rounded;
{
- ASM_GLOBALIZE_LABEL (file, name);
+ (*targetm.asm_out.globalize_label) (file, name);
bss_section ();
#ifdef ASM_DECLARE_OBJECT_NAME
last_assemble_variable_decl = decl;
const char *name;
int size, align;
{
- ASM_GLOBALIZE_LABEL (file, name);
+ (*targetm.asm_out.globalize_label) (file, name);
bss_section ();
ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
#ifdef ASM_DECLARE_OBJECT_NAME
char *name;
p = (* targetm.strip_name_encoding) (fnname);
- name = permalloc (strlen (p) + 1);
- strcpy (name, p);
+ name = xstrdup (p);
if (! DECL_WEAK (decl) && ! DECL_ONE_ONLY (decl))
first_global_object_name = name;
#endif
#endif
-static void
+static bool
asm_emit_uninitialised (decl, name, size, rounded)
tree decl;
const char *name;
}
destination = asm_dest_local;
+ /* ??? We should handle .bss via select_section mechanisms rather than
+ via special target hooks. That would eliminate this special case. */
if (TREE_PUBLIC (decl))
{
-#if defined ASM_EMIT_BSS
- if (! DECL_COMMON (decl))
+ if (!DECL_COMMON (decl))
+#ifdef ASM_EMIT_BSS
destination = asm_dest_bss;
- else
+#else
+ return false;
#endif
+ else
destination = asm_dest_common;
}
abort ();
}
- return;
+ return true;
}
/* Assemble everything that is needed for a variable or function declaration.
char *xname;
p = (* targetm.strip_name_encoding) (name);
- xname = permalloc (strlen (p) + 1);
- strcpy (xname, p);
+ xname = xstrdup (p);
first_global_object_name = xname;
}
if (DECL_COMMON (decl))
sorry ("thread-local COMMON data not implemented");
}
-#ifndef ASM_EMIT_BSS
- /* If the target can't output uninitialized but not common global data
- in .bss, then we have to use .data. */
- /* ??? We should handle .bss via select_section mechanisms rather than
- via special target hooks. That would eliminate this special case. */
- else if (!DECL_COMMON (decl))
- ;
-#endif
else if (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node
|| (flag_zero_initialized_in_bss
rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
* (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
-/* Don't continue this line--convex cc version 4.1 would lose. */
#if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_DECL_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS)
if ((unsigned HOST_WIDE_INT) DECL_ALIGN (decl) / BITS_PER_UNIT > rounded)
warning_with_decl
(decl, "requested alignment for %s is greater than implemented alignment of %d",rounded);
#endif
- asm_emit_uninitialised (decl, name, size, rounded);
-
- return;
+ /* If the target cannot output uninitialized but not common global data
+ in .bss, then we have to use .data, so fall through. */
+ if (asm_emit_uninitialised (decl, name, size, rounded))
+ return;
}
/* Handle initialized definitions.
#endif
}
-/* Declare the label NAME global. */
-
-void
-assemble_global (name)
- const char *name ATTRIBUTE_UNUSED;
-{
- ASM_GLOBALIZE_LABEL (asm_out_file, name);
-}
-
/* Assemble a label named NAME. */
void
} GTY ((tag ("0"))) di;
/* The max vector size we have is 8 wide. This should be enough. */
- HOST_WIDE_INT veclo[16];
- HOST_WIDE_INT vechi[16];
+ struct rtx_const_vec {
+ HOST_WIDE_INT veclo;
+ HOST_WIDE_INT vechi;
+ } GTY ((tag ("2"))) vec[16];
} GTY ((desc ("%1.kind >= RTX_INT"), descbits ("1"))) un;
};
l1 && l2;
l1 = TREE_CHAIN (l1), l2 = TREE_CHAIN (l2))
{
- /* Check that each value is the same... */
+ /* Check that each value is the same... */
if (! compare_constant (TREE_VALUE (l1), TREE_VALUE (l2)))
return 0;
/* ... and that they apply to the same fields! */
elt = CONST_VECTOR_ELT (x, i);
if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
{
- value->un.veclo[i] = (HOST_WIDE_INT) INTVAL (elt);
- value->un.vechi[i] = 0;
+ value->un.vec[i].veclo = (HOST_WIDE_INT) INTVAL (elt);
+ value->un.vec[i].vechi = 0;
}
else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
{
- value->un.veclo[i] = (HOST_WIDE_INT) CONST_DOUBLE_LOW (elt);
- value->un.vechi[i] = (HOST_WIDE_INT) CONST_DOUBLE_HIGH (elt);
+ value->un.vec[i].veclo = (HOST_WIDE_INT) CONST_DOUBLE_LOW (elt);
+ value->un.vec[i].vechi = (HOST_WIDE_INT) CONST_DOUBLE_HIGH (elt);
}
else
abort ();
}
}
- if (value->kind > RTX_DOUBLE && value->un.addr.base != 0)
+ if (value->kind > RTX_VECTOR && value->un.addr.base != 0)
switch (GET_CODE (value->un.addr.base))
{
#if 0
}
#endif
- ASM_GLOBALIZE_LABEL (asm_out_file, name);
+ (*targetm.asm_out.globalize_label) (asm_out_file, name);
}
/* Emit an assembler directive to make the symbol for DECL an alias to
VISIBILITY_TYPE. */
void
-assemble_visibility (decl, visibility_type)
+default_assemble_visibility (decl, visibility_type)
tree decl;
const char *visibility_type ATTRIBUTE_UNUSED;
{
const char *name;
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ name = (* targetm.strip_name_encoding)
+ (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
#ifdef HAVE_GAS_HIDDEN
fprintf (asm_out_file, "\t.%s\t%s\n", visibility_type, name);
{
const char *type
= TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (visibility)));
- assemble_visibility (decl, type);
+ (* targetm.asm_out.visibility) (decl, type);
}
}
const char *name;
int reloc;
{
+ return default_section_type_flags_1 (decl, name, reloc, flag_pic);
+}
+
+unsigned int
+default_section_type_flags_1 (decl, name, reloc, shlib)
+ tree decl;
+ const char *name;
+ int reloc;
+ int shlib;
+{
unsigned int flags;
if (decl && TREE_CODE (decl) == FUNCTION_DECL)
flags = SECTION_CODE;
- else if (decl && DECL_READONLY_SECTION (decl, reloc))
+ else if (decl && decl_readonly_section_1 (decl, reloc, shlib))
flags = 0;
else
flags = SECTION_WRITE;
if (DECL_P (decl))
{
- if (DECL_READONLY_SECTION (decl, reloc))
+ if (decl_readonly_section (decl, reloc))
readonly = true;
}
else if (TREE_CODE (decl) == CONSTRUCTOR)
SECCAT_RODATA_MERGE_STR,
SECCAT_RODATA_MERGE_STR_INIT,
SECCAT_RODATA_MERGE_CONST,
+ SECCAT_SRODATA,
SECCAT_DATA,
SECCAT_TBSS
};
-static enum section_category categorize_decl_for_section PARAMS ((tree, int));
+static enum section_category
+categorize_decl_for_section PARAMS ((tree, int, int));
static enum section_category
-categorize_decl_for_section (decl, reloc)
+categorize_decl_for_section (decl, reloc, shlib)
tree decl;
int reloc;
+ int shlib;
{
enum section_category ret;
|| TREE_SIDE_EFFECTS (decl)
|| ! TREE_CONSTANT (DECL_INITIAL (decl)))
{
- if (flag_pic && (reloc & 2))
+ if (shlib && (reloc & 2))
ret = SECCAT_DATA_REL;
- else if (flag_pic && reloc)
+ else if (shlib && reloc)
ret = SECCAT_DATA_REL_LOCAL;
else
ret = SECCAT_DATA;
}
- else if (flag_pic && (reloc & 2))
+ else if (shlib && (reloc & 2))
ret = SECCAT_DATA_REL_RO;
- else if (flag_pic && reloc)
+ else if (shlib && reloc)
ret = SECCAT_DATA_REL_RO_LOCAL;
else if (flag_merge_constants < 2)
/* C and C++ don't allow different variables to share the same
}
else if (TREE_CODE (decl) == CONSTRUCTOR)
{
- if ((flag_pic && reloc)
+ if ((shlib && reloc)
|| TREE_SIDE_EFFECTS (decl)
|| ! TREE_CONSTANT (decl))
ret = SECCAT_DATA;
{
if (ret == SECCAT_BSS)
ret = SECCAT_SBSS;
+ else if (targetm.have_srodata_section && ret == SECCAT_RODATA)
+ ret = SECCAT_SRODATA;
else
ret = SECCAT_SDATA;
}
return ret;
}
+bool
+decl_readonly_section (decl, reloc)
+ tree decl;
+ int reloc;
+{
+ return decl_readonly_section_1 (decl, reloc, flag_pic);
+}
+
+bool
+decl_readonly_section_1 (decl, reloc, shlib)
+ tree decl;
+ int reloc;
+ int shlib;
+{
+ switch (categorize_decl_for_section (decl, reloc, shlib))
+ {
+ case SECCAT_RODATA:
+ case SECCAT_RODATA_MERGE_STR:
+ case SECCAT_RODATA_MERGE_STR_INIT:
+ case SECCAT_RODATA_MERGE_CONST:
+ case SECCAT_SRODATA:
+ return true;
+ break;
+ default:
+ return false;
+ break;
+ }
+}
+
/* Select a section based on the above categorization. */
void
int reloc;
unsigned HOST_WIDE_INT align;
{
- switch (categorize_decl_for_section (decl, reloc))
+ default_elf_select_section_1 (decl, reloc, align, flag_pic);
+}
+
+void
+default_elf_select_section_1 (decl, reloc, align, shlib)
+ tree decl;
+ int reloc;
+ unsigned HOST_WIDE_INT align;
+ int shlib;
+{
+ switch (categorize_decl_for_section (decl, reloc, shlib))
{
case SECCAT_TEXT:
/* We're not supposed to be called on FUNCTION_DECLs. */
case SECCAT_RODATA_MERGE_CONST:
mergeable_constant_section (DECL_MODE (decl), align, 0);
break;
+ case SECCAT_SRODATA:
+ named_section (NULL_TREE, ".sdata2", reloc);
+ break;
case SECCAT_DATA:
data_section ();
break;
tree decl;
int reloc;
{
+ default_unique_section_1 (decl, reloc, flag_pic);
+}
+
+void
+default_unique_section_1 (decl, reloc, shlib)
+ tree decl;
+ int reloc;
+ int shlib;
+{
bool one_only = DECL_ONE_ONLY (decl);
const char *prefix, *name;
size_t nlen, plen;
char *string;
- switch (categorize_decl_for_section (decl, reloc))
+ switch (categorize_decl_for_section (decl, reloc, shlib))
{
case SECCAT_TEXT:
prefix = one_only ? ".gnu.linkonce.t." : ".text.";
case SECCAT_RODATA_MERGE_CONST:
prefix = one_only ? ".gnu.linkonce.r." : ".rodata.";
break;
+ case SECCAT_SRODATA:
+ prefix = one_only ? ".gnu.linkonce.s2." : ".sdata2.";
+ break;
case SECCAT_DATA:
case SECCAT_DATA_REL:
case SECCAT_DATA_REL_LOCAL:
default_binds_local_p (exp)
tree exp;
{
+ return default_binds_local_p_1 (exp, flag_pic);
+}
+
+bool
+default_binds_local_p_1 (exp, shlib)
+ tree exp;
+ int shlib;
+{
bool local_p;
/* A non-decl is an entry in the constant pool. */
local_p = false;
/* If PIC, then assume that any global name can be overridden by
symbols resolved from other modules. */
- else if (flag_pic)
+ else if (shlib)
local_p = false;
/* Uninitialized COMMON variable may be unified with symbols
resolved from other modules. */
return local_p;
}
+/* Default function to output code that will globalize a label. A
+ target must define GLOBAL_ASM_OP or provide it's own function to
+ globalize a label. */
+#ifdef GLOBAL_ASM_OP
+void
+default_globalize_label (stream, name)
+ FILE * stream;
+ const char *name;
+{
+ fputs (GLOBAL_ASM_OP, stream);
+ assemble_name (stream, name);
+ putc ('\n', stream);
+}
+#endif /* GLOBAL_ASM_OP */
+
#include "gt-varasm.h"