From e58870339c53952fe27de1fad0ffc194703c2edf Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Thu, 29 Feb 1996 02:53:44 +0000 Subject: [PATCH] varasm.c (enum in_section): Define in_bss if BSS_SECTION_ASM_OP is defined. * varasm.c (enum in_section): Define in_bss if BSS_SECTION_ASM_OP is defined. (bss_section,asm_output_bss,asm_output_aligned_bss): New functions. (assemble_variable): Delete redundant test for too large an object. Rewrite test for uninitialized variables. Use new macros ASM_OUTPUT{,_ALIGNED}_BSS if defined to output global uninitialized but not common variables. From-SVN: r11364 --- gcc/varasm.c | 139 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 125 insertions(+), 14 deletions(-) diff --git a/gcc/varasm.c b/gcc/varasm.c index b0f5d1bd2f7..f9f5dd0f0c6 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -146,13 +146,14 @@ static int output_addressed_constants PROTO((tree)); static void bc_assemble_integer PROTO((tree, int)); static void output_constructor PROTO((tree, int)); +static enum in_section { no_section, in_text, in_data, in_named +#ifdef BSS_SECTION_ASM_OP + , in_bss +#endif #ifdef EXTRA_SECTIONS -static enum in_section {no_section, in_text, in_data, in_named, EXTRA_SECTIONS} in_section - = no_section; -#else -static enum in_section {no_section, in_text, in_data, in_named} in_section - = no_section; + , EXTRA_SECTIONS #endif +} in_section = no_section; /* Return a non-zero value if DECL has a section attribute. */ #define IN_NAMED_SECTION(DECL) \ @@ -268,6 +269,76 @@ named_section (decl, name) } } +#ifdef BSS_SECTION_ASM_OP + +/* Tell the assembler to switch to the bss section. */ + +void +bss_section (decl, name) +{ + if (in_section != in_bss) + { + if (output_bytecode) + bc_data (); + else + { +#ifdef SHARED_BSS_SECTION_ASM_OP + if (flag_shared_data) + fprintf (asm_out_file, "%s\n", SHARED_BSS_SECTION_ASM_OP); + else +#endif + fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP); + } + + in_section = in_bss; + } +} + +#ifdef ASM_OUTPUT_BSS + +/* Utility function for ASM_OUTPUT_BSS for targets to use if + they don't support alignments in .bss. + ??? It is believed that this function will work in most cases so such + support is localized here. */ + +static void +asm_output_bss (file, name, size, rounded) + FILE *file; + char *name; + int size, rounded; +{ + ASM_GLOBALIZE_LABEL (file, name); + bss_section (); + ASM_OUTPUT_LABEL (file, name); + ASM_OUTPUT_SKIP (file, rounded); +} + +#endif + +#ifdef ASM_OUTPUT_ALIGNED_BSS + +/* Utility function for targets to use in implementing + ASM_OUTPUT_ALIGNED_BSS. + ??? It is believed that this function will work in most cases so such + support is localized here. */ + +static void +asm_output_aligned_bss (file, name, size, align) + FILE *file; + char *name; + int size, align; +{ + ASM_GLOBALIZE_LABEL (file, name); + bss_section (); + ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT)); + ASM_OUTPUT_LABEL (file, name); + ASM_OUTPUT_SKIP (file, size); +} + +#endif + +#endif /* BSS_SECTION_ASM_OP */ + /* Switch to the section for function DECL. If DECL is NULL_TREE, switch to the text section. @@ -305,7 +376,12 @@ variable_section (decl, reloc) error_mark_node is used by the C front end to indicate that the initializer has not been seen yet. In this case, we assume that - the initializer must be constant. */ + the initializer must be constant. + + C++ uses error_mark_node for variables that have complicated + initializers, but these variables go in BSS so we won't be called + for them. */ + #ifdef SELECT_SECTION SELECT_SECTION (decl, reloc); #else @@ -1134,16 +1210,19 @@ assemble_variable (decl, top_level, at_end, dont_output_data) initializer equal to zero. (Section 3.7.2) -fno-common gives strict ANSI behavior. Usually you don't want it. This matters only for variables with external linkage. */ - if ((! flag_no_common || ! TREE_PUBLIC (decl)) + + if ((DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node) + /* If the target can't output uninitialized but not common global data + in .bss, then we have to use .data. */ +#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS) + && (! flag_no_common || ! TREE_PUBLIC (decl)) && DECL_COMMON (decl) - && ! dont_output_data - && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node)) +#endif + && ! dont_output_data) { int size = TREE_INT_CST_LOW (size_tree); int rounded = size; - if (TREE_INT_CST_HIGH (size_tree) != 0) - error_with_decl (decl, "size of variable `%s' is too large"); /* Don't allocate zero bytes of common, since that means "undefined external" in the linker. */ if (size == 0) rounded = 1; @@ -1174,11 +1253,18 @@ assemble_variable (decl, top_level, at_end, dont_output_data) while we are doing our final traversal of the chain of file-scope declarations. */ -#if 0 +#if 0 /* ??? We should either delete this or add a comment describing what + it was intended to do and why we shouldn't delete it. */ if (flag_shared_data) data_section (); #endif - if (TREE_PUBLIC (decl)) + + if (TREE_PUBLIC (decl) +#if defined (ASM_OUTPUT_BSS) || defined (ASM_OUTPUT_ALIGNED_BSS) + && DECL_COMMON (decl) + && ! flag_no_common +#endif + ) { #ifdef ASM_OUTPUT_SHARED_COMMON if (flag_shared_data) @@ -1199,6 +1285,29 @@ assemble_variable (decl, top_level, at_end, dont_output_data) #endif } } +#if defined (ASM_OUTPUT_BSS) || defined (ASM_OUTPUT_ALIGNED_BSS) + else if (TREE_PUBLIC (decl)) + { +#ifdef ASM_OUTPUT_SHARED_BSS + if (flag_shared_data) + ASM_OUTPUT_SHARED_BSS (asm_out_file, name, size, rounded); + else +#endif + if (output_bytecode) + { + BC_OUTPUT_BSS (asm_out_file, name, size, rounded); + } + else + { +#ifdef ASM_OUTPUT_ALIGNED_BSS + ASM_OUTPUT_ALIGNED_BSS (asm_out_file, name, size, + DECL_ALIGN (decl)); +#else + ASM_OUTPUT_BSS (asm_out_file, name, size, rounded); +#endif + } + } +#endif /* ASM_OUTPUT_BSS || ASM_OUTPUT_ALIGNED_BSS */ else { #ifdef ASM_OUTPUT_SHARED_LOCAL @@ -1223,7 +1332,9 @@ assemble_variable (decl, top_level, at_end, dont_output_data) goto finish; } - /* Handle initialized definitions. */ + /* Handle initialized definitions. + Also handle uninitialized global definitions if -fno-common and the + target doesn't support ASM_OUTPUT_BSS. */ /* First make the assembler name(s) global if appropriate. */ if (TREE_PUBLIC (decl) && DECL_NAME (decl)) -- 2.30.2