varasm.c revision 132718
118334Speter/* Output variables, constants and external declarations, for GNU compiler. 290075Sobrien Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 3132718Skan 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. 418334Speter 590075SobrienThis file is part of GCC. 618334Speter 790075SobrienGCC is free software; you can redistribute it and/or modify it under 890075Sobrienthe terms of the GNU General Public License as published by the Free 990075SobrienSoftware Foundation; either version 2, or (at your option) any later 1090075Sobrienversion. 1118334Speter 1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrienfor more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 1990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2090075Sobrien02111-1307, USA. */ 2118334Speter 2218334Speter 2318334Speter/* This file handles generation of all the assembler code 2418334Speter *except* the instructions of a function. 2518334Speter This includes declarations of variables and their initial values. 2618334Speter 2718334Speter We also output the assembler code for constants stored in memory 2818334Speter and are responsible for combining constants with the same value. */ 2918334Speter 3050397Sobrien#include "config.h" 3150397Sobrien#include "system.h" 32132718Skan#include "coretypes.h" 33132718Skan#include "tm.h" 3418334Speter#include "rtl.h" 3518334Speter#include "tree.h" 3618334Speter#include "flags.h" 3718334Speter#include "function.h" 3818334Speter#include "expr.h" 3918334Speter#include "hard-reg-set.h" 4018334Speter#include "regs.h" 41117395Skan#include "real.h" 4290075Sobrien#include "output.h" 4350397Sobrien#include "toplev.h" 4490075Sobrien#include "hashtab.h" 4518334Speter#include "c-pragma.h" 4690075Sobrien#include "ggc.h" 4790075Sobrien#include "langhooks.h" 4890075Sobrien#include "tm_p.h" 4990075Sobrien#include "debug.h" 5090075Sobrien#include "target.h" 51132718Skan#include "cgraph.h" 5218334Speter 5318334Speter#ifdef XCOFF_DEBUGGING_INFO 5490075Sobrien#include "xcoffout.h" /* Needed for external data 5590075Sobrien declarations for e.g. AIX 4.x. */ 5618334Speter#endif 5718334Speter 5850397Sobrien#ifndef TRAMPOLINE_ALIGNMENT 5950397Sobrien#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY 6050397Sobrien#endif 6118334Speter 6218334Speter#ifndef ASM_STABS_OP 6390075Sobrien#define ASM_STABS_OP "\t.stabs\t" 6418334Speter#endif 6518334Speter 6618334Speter/* The (assembler) name of the first globally-visible object output. */ 6790075Sobrienconst char *first_global_object_name; 6890075Sobrienconst char *weak_global_object_name; 6918334Speter 7090075Sobrienstruct addr_const; 71117395Skanstruct constant_descriptor_rtx; 7290075Sobrienstruct rtx_const; 7390075Sobrienstruct pool_constant; 7490075Sobrien 7590075Sobrien#define MAX_RTX_HASH_TABLE 61 7690075Sobrien 77117395Skanstruct varasm_status GTY(()) 7890075Sobrien{ 7990075Sobrien /* Hash facility for making memory-constants 8090075Sobrien from constant rtl-expressions. It is used on RISC machines 8190075Sobrien where immediate integer arguments and constant addresses are restricted 8290075Sobrien so that such constants must be stored in memory. 8390075Sobrien 8490075Sobrien This pool of constants is reinitialized for each function 8590075Sobrien so each function gets its own constants-pool that comes right before 8690075Sobrien it. */ 87117395Skan struct constant_descriptor_rtx ** GTY ((length ("MAX_RTX_HASH_TABLE"))) 88117395Skan x_const_rtx_hash_table; 89117395Skan struct pool_constant ** GTY ((length ("MAX_RTX_HASH_TABLE"))) 90117395Skan x_const_rtx_sym_hash_table; 9190075Sobrien 9290075Sobrien /* Pointers to first and last constant in pool. */ 93117395Skan struct pool_constant *x_first_pool; 94117395Skan struct pool_constant *x_last_pool; 9590075Sobrien 9690075Sobrien /* Current offset in constant pool (does not include any machine-specific 9790075Sobrien header). */ 9890075Sobrien HOST_WIDE_INT x_pool_offset; 99132718Skan 100132718Skan /* Number of tree-constants deferred during the expansion of this 101132718Skan function. */ 102132718Skan unsigned int deferred_constants; 10390075Sobrien}; 10490075Sobrien 10590075Sobrien#define const_rtx_hash_table (cfun->varasm->x_const_rtx_hash_table) 10690075Sobrien#define const_rtx_sym_hash_table (cfun->varasm->x_const_rtx_sym_hash_table) 10790075Sobrien#define first_pool (cfun->varasm->x_first_pool) 10890075Sobrien#define last_pool (cfun->varasm->x_last_pool) 10990075Sobrien#define pool_offset (cfun->varasm->x_pool_offset) 110132718Skan#define n_deferred_constants (cfun->varasm->deferred_constants) 11190075Sobrien 11218334Speter/* Number for making the label on the next 11318334Speter constant that is stored in memory. */ 11418334Speter 115132718Skanstatic GTY(()) int const_labelno; 11618334Speter 11718334Speter/* Carry information from ASM_DECLARE_OBJECT_NAME 11818334Speter to ASM_FINISH_DECLARE_OBJECT. */ 11918334Speter 12018334Speterint size_directive_output; 12118334Speter 12218334Speter/* The last decl for which assemble_variable was called, 12318334Speter if it did ASM_DECLARE_OBJECT_NAME. 12418334Speter If the last call to assemble_variable didn't do that, 12518334Speter this holds 0. */ 12618334Speter 12718334Spetertree last_assemble_variable_decl; 12818334Speter 12990075Sobrien/* RTX_UNCHANGING_P in a MEM can mean it is stored into, for initialization. 13090075Sobrien So giving constant the alias set for the type will allow such 13190075Sobrien initializations to appear to conflict with the load of the constant. We 13290075Sobrien avoid this by giving all constants an alias set for just constants. 13390075Sobrien Since there will be no stores to that alias set, nothing will ever 13490075Sobrien conflict with them. */ 13518334Speter 13690075Sobrienstatic HOST_WIDE_INT const_alias_set; 13718334Speter 138132718Skanstatic const char *strip_reg_name (const char *); 139132718Skanstatic int contains_pointers_p (tree); 140132718Skan#ifdef ASM_OUTPUT_EXTERNAL 141132718Skanstatic bool incorporeal_function_p (tree); 142132718Skan#endif 143132718Skanstatic void decode_addr_const (tree, struct addr_const *); 144132718Skanstatic hashval_t const_desc_hash (const void *); 145132718Skanstatic int const_desc_eq (const void *, const void *); 146132718Skanstatic hashval_t const_hash_1 (const tree); 147132718Skanstatic int compare_constant (const tree, const tree); 148132718Skanstatic tree copy_constant (tree); 149132718Skanstatic void output_constant_def_contents (rtx); 150132718Skanstatic void decode_rtx_const (enum machine_mode, rtx, struct rtx_const *); 151132718Skanstatic unsigned int const_hash_rtx (enum machine_mode, rtx); 152132718Skanstatic int compare_constant_rtx (enum machine_mode, rtx, 153132718Skan struct constant_descriptor_rtx *); 154117395Skanstatic struct constant_descriptor_rtx * record_constant_rtx 155132718Skan (enum machine_mode, rtx); 156132718Skanstatic struct pool_constant *find_pool_constant (struct function *, rtx); 157132718Skanstatic void mark_constant_pool (void); 158132718Skanstatic void mark_constants (rtx); 159132718Skanstatic int mark_constant (rtx *current_rtx, void *data); 160132718Skanstatic void output_addressed_constants (tree); 161132718Skanstatic unsigned HOST_WIDE_INT array_size_for_constructor (tree); 162132718Skanstatic unsigned min_align (unsigned, unsigned); 163132718Skanstatic void output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int); 164132718Skanstatic void globalize_decl (tree); 165132718Skanstatic void maybe_assemble_visibility (tree); 166132718Skanstatic int in_named_entry_eq (const void *, const void *); 167132718Skanstatic hashval_t in_named_entry_hash (const void *); 16850397Sobrien#ifdef ASM_OUTPUT_BSS 169132718Skanstatic void asm_output_bss (FILE *, tree, const char *, 170132718Skan unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT); 17150397Sobrien#endif 17250397Sobrien#ifdef BSS_SECTION_ASM_OP 17350397Sobrien#ifdef ASM_OUTPUT_ALIGNED_BSS 174132718Skanstatic void asm_output_aligned_bss (FILE *, tree, const char *, 175132718Skan unsigned HOST_WIDE_INT, int) 176132718Skan ATTRIBUTE_UNUSED; 17750397Sobrien#endif 17850397Sobrien#endif /* BSS_SECTION_ASM_OP */ 179132718Skanstatic bool asm_emit_uninitialised (tree, const char*, 180132718Skan unsigned HOST_WIDE_INT, 181132718Skan unsigned HOST_WIDE_INT); 182132718Skanstatic void mark_weak (tree); 18318334Speter 184132718Skanenum in_section { no_section, in_text, in_data, in_named 18550397Sobrien#ifdef BSS_SECTION_ASM_OP 18650397Sobrien , in_bss 18750397Sobrien#endif 18890075Sobrien#ifdef CTORS_SECTION_ASM_OP 18990075Sobrien , in_ctors 19050397Sobrien#endif 19190075Sobrien#ifdef DTORS_SECTION_ASM_OP 19290075Sobrien , in_dtors 19390075Sobrien#endif 194117395Skan#ifdef READONLY_DATA_SECTION_ASM_OP 195117395Skan , in_readonly_data 196117395Skan#endif 19718334Speter#ifdef EXTRA_SECTIONS 19850397Sobrien , EXTRA_SECTIONS 19918334Speter#endif 200132718Skan}; 201132718Skanstatic GTY(()) enum in_section in_section = no_section; 20218334Speter 203117395Skan/* Return a nonzero value if DECL has a section attribute. */ 20490075Sobrien#ifndef IN_NAMED_SECTION 20518334Speter#define IN_NAMED_SECTION(DECL) \ 20618334Speter ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ 20718334Speter && DECL_SECTION_NAME (DECL) != NULL_TREE) 20890075Sobrien#endif 20918334Speter 21018334Speter/* Text of section name when in_section == in_named. */ 211132718Skanstatic GTY(()) const char *in_named_name; 21218334Speter 21390075Sobrien/* Hash table of flags that have been used for a particular named section. */ 21490075Sobrien 215132718Skanstruct in_named_entry GTY(()) 21690075Sobrien{ 21790075Sobrien const char *name; 21890075Sobrien unsigned int flags; 21990075Sobrien bool declared; 22090075Sobrien}; 22190075Sobrien 222132718Skanstatic GTY((param_is (struct in_named_entry))) htab_t in_named_htab; 22390075Sobrien 22418334Speter/* Define functions like text_section for any extra sections. */ 22518334Speter#ifdef EXTRA_SECTION_FUNCTIONS 22618334SpeterEXTRA_SECTION_FUNCTIONS 22718334Speter#endif 22818334Speter 22918334Speter/* Tell assembler to switch to text section. */ 23018334Speter 23118334Spetervoid 232132718Skantext_section (void) 23318334Speter{ 23418334Speter if (in_section != in_text) 23518334Speter { 236117395Skan in_section = in_text; 23750397Sobrien fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP); 23818334Speter } 23918334Speter} 24018334Speter 24118334Speter/* Tell assembler to switch to data section. */ 24218334Speter 24318334Spetervoid 244132718Skandata_section (void) 24518334Speter{ 24618334Speter if (in_section != in_data) 24718334Speter { 248117395Skan in_section = in_data; 24950397Sobrien if (flag_shared_data) 25018334Speter { 25118334Speter#ifdef SHARED_SECTION_ASM_OP 25250397Sobrien fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP); 25318334Speter#else 25450397Sobrien fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP); 25518334Speter#endif 25618334Speter } 25750397Sobrien else 25850397Sobrien fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP); 25918334Speter } 26018334Speter} 261117395Skan 26218334Speter/* Tell assembler to switch to read-only data section. This is normally 26318334Speter the text section. */ 26418334Speter 26518334Spetervoid 266132718Skanreadonly_data_section (void) 26718334Speter{ 26818334Speter#ifdef READONLY_DATA_SECTION 26918334Speter READONLY_DATA_SECTION (); /* Note this can call data_section. */ 27018334Speter#else 271117395Skan#ifdef READONLY_DATA_SECTION_ASM_OP 272117395Skan if (in_section != in_readonly_data) 273117395Skan { 274117395Skan in_section = in_readonly_data; 275117395Skan fputs (READONLY_DATA_SECTION_ASM_OP, asm_out_file); 276117395Skan fputc ('\n', asm_out_file); 277117395Skan } 278117395Skan#else 27918334Speter text_section (); 28018334Speter#endif 281117395Skan#endif 28218334Speter} 28318334Speter 28450397Sobrien/* Determine if we're in the text section. */ 28518334Speter 28618334Speterint 287132718Skanin_text_section (void) 28818334Speter{ 28918334Speter return in_section == in_text; 29018334Speter} 29118334Speter 29250397Sobrien/* Determine if we're in the data section. */ 29350397Sobrien 29450397Sobrienint 295132718Skanin_data_section (void) 29650397Sobrien{ 29750397Sobrien return in_section == in_data; 29850397Sobrien} 29950397Sobrien 30090075Sobrien/* Helper routines for maintaining in_named_htab. */ 30190075Sobrien 30290075Sobrienstatic int 303132718Skanin_named_entry_eq (const void *p1, const void *p2) 30490075Sobrien{ 30590075Sobrien const struct in_named_entry *old = p1; 30690075Sobrien const char *new = p2; 30790075Sobrien 30890075Sobrien return strcmp (old->name, new) == 0; 30990075Sobrien} 31090075Sobrien 31190075Sobrienstatic hashval_t 312132718Skanin_named_entry_hash (const void *p) 31390075Sobrien{ 31490075Sobrien const struct in_named_entry *old = p; 31590075Sobrien return htab_hash_string (old->name); 31690075Sobrien} 31790075Sobrien 31890075Sobrien/* If SECTION has been seen before as a named section, return the flags 31990075Sobrien that were used. Otherwise, return 0. Note, that 0 is a perfectly valid 32090075Sobrien set of flags for a section to have, so 0 does not mean that the section 32190075Sobrien has not been seen. */ 32290075Sobrien 32390075Sobrienunsigned int 324132718Skanget_named_section_flags (const char *section) 32590075Sobrien{ 32690075Sobrien struct in_named_entry **slot; 32790075Sobrien 328117395Skan slot = (struct in_named_entry **) 32990075Sobrien htab_find_slot_with_hash (in_named_htab, section, 33090075Sobrien htab_hash_string (section), NO_INSERT); 33190075Sobrien 33290075Sobrien return slot ? (*slot)->flags : 0; 33390075Sobrien} 33490075Sobrien 33590075Sobrien/* Returns true if the section has been declared before. Sets internal 336117395Skan flag on this section in in_named_hash so subsequent calls on this 33790075Sobrien section will return false. */ 33890075Sobrien 33990075Sobrienbool 340132718Skannamed_section_first_declaration (const char *name) 34190075Sobrien{ 34290075Sobrien struct in_named_entry **slot; 34390075Sobrien 344117395Skan slot = (struct in_named_entry **) 345117395Skan htab_find_slot_with_hash (in_named_htab, name, 34690075Sobrien htab_hash_string (name), NO_INSERT); 34790075Sobrien if (! (*slot)->declared) 34890075Sobrien { 34990075Sobrien (*slot)->declared = true; 35090075Sobrien return true; 35190075Sobrien } 352117395Skan else 35390075Sobrien { 35490075Sobrien return false; 35590075Sobrien } 35690075Sobrien} 35790075Sobrien 35890075Sobrien 35990075Sobrien/* Record FLAGS for SECTION. If SECTION was previously recorded with a 36090075Sobrien different set of flags, return false. */ 36190075Sobrien 36290075Sobrienbool 363132718Skanset_named_section_flags (const char *section, unsigned int flags) 36490075Sobrien{ 36590075Sobrien struct in_named_entry **slot, *entry; 36690075Sobrien 367117395Skan slot = (struct in_named_entry **) 36890075Sobrien htab_find_slot_with_hash (in_named_htab, section, 36990075Sobrien htab_hash_string (section), INSERT); 37090075Sobrien entry = *slot; 37190075Sobrien 37290075Sobrien if (!entry) 37390075Sobrien { 374132718Skan entry = ggc_alloc (sizeof (*entry)); 37590075Sobrien *slot = entry; 37690075Sobrien entry->name = ggc_strdup (section); 37790075Sobrien entry->flags = flags; 37890075Sobrien entry->declared = false; 37990075Sobrien } 38090075Sobrien else if (entry->flags != flags) 38190075Sobrien return false; 38290075Sobrien 38390075Sobrien return true; 38490075Sobrien} 38590075Sobrien 38690075Sobrien/* Tell assembler to change to section NAME with attributes FLAGS. */ 38790075Sobrien 38890075Sobrienvoid 389132718Skannamed_section_flags (const char *name, unsigned int flags) 39090075Sobrien{ 39190075Sobrien if (in_section != in_named || strcmp (name, in_named_name) != 0) 39290075Sobrien { 39390075Sobrien if (! set_named_section_flags (name, flags)) 39490075Sobrien abort (); 39590075Sobrien 396117395Skan (*targetm.asm_out.named_section) (name, flags); 39790075Sobrien 39890075Sobrien if (flags & SECTION_FORGET) 39990075Sobrien in_section = no_section; 40090075Sobrien else 40190075Sobrien { 40290075Sobrien in_named_name = ggc_strdup (name); 40390075Sobrien in_section = in_named; 40490075Sobrien } 40590075Sobrien } 40690075Sobrien} 40790075Sobrien 40818334Speter/* Tell assembler to change to section NAME for DECL. 40918334Speter If DECL is NULL, just switch to section NAME. 41050397Sobrien If NAME is NULL, get the name from DECL. 41150397Sobrien If RELOC is 1, the initializer for DECL contains relocs. */ 41218334Speter 41318334Spetervoid 414132718Skannamed_section (tree decl, const char *name, int reloc) 41518334Speter{ 41690075Sobrien unsigned int flags; 41790075Sobrien 41890075Sobrien if (decl != NULL_TREE && !DECL_P (decl)) 41918334Speter abort (); 42018334Speter if (name == NULL) 42118334Speter name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); 42218334Speter 42390075Sobrien flags = (* targetm.section_type_flags) (decl, name, reloc); 42490075Sobrien 42590075Sobrien /* Sanity check user variables for flag changes. Non-user 42696263Sobrien section flag changes will abort in named_section_flags. 42796263Sobrien However, don't complain if SECTION_OVERRIDE is set. 42896263Sobrien We trust that the setter knows that it is safe to ignore 42996263Sobrien the default flags for this decl. */ 43090075Sobrien if (decl && ! set_named_section_flags (name, flags)) 43118334Speter { 43290075Sobrien flags = get_named_section_flags (name); 43396263Sobrien if ((flags & SECTION_OVERRIDE) == 0) 434132718Skan error ("%J%D causes a section type conflict", decl, decl); 43590075Sobrien } 43650397Sobrien 43790075Sobrien named_section_flags (name, flags); 43818334Speter} 43918334Speter 44090075Sobrien/* If required, set DECL_SECTION_NAME to a unique name. */ 44150397Sobrien 442132718Skanvoid 443132718Skanresolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED, 444132718Skan int flag_function_or_data_sections) 44590075Sobrien{ 44690075Sobrien if (DECL_SECTION_NAME (decl) == NULL_TREE 447117395Skan && targetm.have_named_sections 448102780Skan && (flag_function_or_data_sections 449117395Skan || DECL_ONE_ONLY (decl))) 450117395Skan (*targetm.asm_out.unique_section) (decl, reloc); 45190075Sobrien} 45290075Sobrien 45350397Sobrien#ifdef BSS_SECTION_ASM_OP 45450397Sobrien 45550397Sobrien/* Tell the assembler to switch to the bss section. */ 45650397Sobrien 45750397Sobrienvoid 458132718Skanbss_section (void) 45950397Sobrien{ 46050397Sobrien if (in_section != in_bss) 46150397Sobrien { 462132718Skan fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP); 46350397Sobrien in_section = in_bss; 46450397Sobrien } 46550397Sobrien} 46650397Sobrien 46750397Sobrien#ifdef ASM_OUTPUT_BSS 46850397Sobrien 46950397Sobrien/* Utility function for ASM_OUTPUT_BSS for targets to use if 47050397Sobrien they don't support alignments in .bss. 47150397Sobrien ??? It is believed that this function will work in most cases so such 47250397Sobrien support is localized here. */ 47350397Sobrien 47450397Sobrienstatic void 475132718Skanasm_output_bss (FILE *file, tree decl ATTRIBUTE_UNUSED, 476132718Skan const char *name, 477132718Skan unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED, 478132718Skan unsigned HOST_WIDE_INT rounded) 47950397Sobrien{ 480117395Skan (*targetm.asm_out.globalize_label) (file, name); 48150397Sobrien bss_section (); 48250397Sobrien#ifdef ASM_DECLARE_OBJECT_NAME 48350397Sobrien last_assemble_variable_decl = decl; 48450397Sobrien ASM_DECLARE_OBJECT_NAME (file, name, decl); 48550397Sobrien#else 48650397Sobrien /* Standard thing is just output label for the object. */ 48750397Sobrien ASM_OUTPUT_LABEL (file, name); 48850397Sobrien#endif /* ASM_DECLARE_OBJECT_NAME */ 489102780Skan ASM_OUTPUT_SKIP (file, rounded ? rounded : 1); 49050397Sobrien} 49150397Sobrien 49250397Sobrien#endif 49350397Sobrien 49450397Sobrien#ifdef ASM_OUTPUT_ALIGNED_BSS 49550397Sobrien 49650397Sobrien/* Utility function for targets to use in implementing 49750397Sobrien ASM_OUTPUT_ALIGNED_BSS. 49850397Sobrien ??? It is believed that this function will work in most cases so such 49950397Sobrien support is localized here. */ 50050397Sobrien 50150397Sobrienstatic void 502132718Skanasm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED, 503132718Skan const char *name, unsigned HOST_WIDE_INT size, 504132718Skan int align) 50550397Sobrien{ 50650397Sobrien bss_section (); 50750397Sobrien ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT)); 50850397Sobrien#ifdef ASM_DECLARE_OBJECT_NAME 50950397Sobrien last_assemble_variable_decl = decl; 51050397Sobrien ASM_DECLARE_OBJECT_NAME (file, name, decl); 51150397Sobrien#else 51250397Sobrien /* Standard thing is just output label for the object. */ 51350397Sobrien ASM_OUTPUT_LABEL (file, name); 51450397Sobrien#endif /* ASM_DECLARE_OBJECT_NAME */ 51550397Sobrien ASM_OUTPUT_SKIP (file, size ? size : 1); 51650397Sobrien} 51750397Sobrien 51850397Sobrien#endif 51950397Sobrien 52050397Sobrien#endif /* BSS_SECTION_ASM_OP */ 52150397Sobrien 52218334Speter/* Switch to the section for function DECL. 52318334Speter 52418334Speter If DECL is NULL_TREE, switch to the text section. 52518334Speter ??? It's not clear that we will ever be passed NULL_TREE, but it's 52618334Speter safer to handle it. */ 52718334Speter 52818334Spetervoid 529132718Skanfunction_section (tree decl) 53018334Speter{ 53118334Speter if (decl != NULL_TREE 53218334Speter && DECL_SECTION_NAME (decl) != NULL_TREE) 53350397Sobrien named_section (decl, (char *) 0, 0); 53450397Sobrien else 53550397Sobrien text_section (); 53618334Speter} 53750397Sobrien 538117395Skan/* Switch to section for variable DECL. RELOC is the same as the 539117395Skan argument to SELECT_SECTION. */ 54050397Sobrien 54150397Sobrienvoid 542132718Skanvariable_section (tree decl, int reloc) 54350397Sobrien{ 54450397Sobrien if (IN_NAMED_SECTION (decl)) 54550397Sobrien named_section (decl, NULL, reloc); 54650397Sobrien else 547117395Skan (*targetm.asm_out.select_section) (decl, reloc, DECL_ALIGN (decl)); 54850397Sobrien} 54950397Sobrien 55090075Sobrien/* Tell assembler to switch to the section for string merging. */ 55190075Sobrien 55218334Spetervoid 553132718Skanmergeable_string_section (tree decl ATTRIBUTE_UNUSED, 554132718Skan unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED, 555132718Skan unsigned int flags ATTRIBUTE_UNUSED) 55618334Speter{ 557132718Skan if (HAVE_GAS_SHF_MERGE && flag_merge_constants 55890075Sobrien && TREE_CODE (decl) == STRING_CST 55990075Sobrien && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE 56090075Sobrien && align <= 256 56190075Sobrien && TREE_STRING_LENGTH (decl) >= int_size_in_bytes (TREE_TYPE (decl))) 56218334Speter { 56390075Sobrien enum machine_mode mode; 56490075Sobrien unsigned int modesize; 56590075Sobrien const char *str; 56690075Sobrien int i, j, len, unit; 56790075Sobrien char name[30]; 56818334Speter 56990075Sobrien mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (decl))); 57090075Sobrien modesize = GET_MODE_BITSIZE (mode); 57190075Sobrien if (modesize >= 8 && modesize <= 256 57290075Sobrien && (modesize & (modesize - 1)) == 0) 57390075Sobrien { 57490075Sobrien if (align < modesize) 57590075Sobrien align = modesize; 57618334Speter 57790075Sobrien str = TREE_STRING_POINTER (decl); 57890075Sobrien len = TREE_STRING_LENGTH (decl); 57990075Sobrien unit = GET_MODE_SIZE (mode); 58018334Speter 58190075Sobrien /* Check for embedded NUL characters. */ 58290075Sobrien for (i = 0; i < len; i += unit) 58390075Sobrien { 58490075Sobrien for (j = 0; j < unit; j++) 585117395Skan if (str[i + j] != '\0') 58690075Sobrien break; 58790075Sobrien if (j == unit) 58890075Sobrien break; 58990075Sobrien } 59090075Sobrien if (i == len - unit) 59190075Sobrien { 59290075Sobrien sprintf (name, ".rodata.str%d.%d", modesize / 8, 59390075Sobrien (int) (align / 8)); 59490075Sobrien flags |= (modesize / 8) | SECTION_MERGE | SECTION_STRINGS; 59590075Sobrien if (!i && modesize < align) 59690075Sobrien { 59790075Sobrien /* A "" string with requested alignment greater than 59890075Sobrien character size might cause a problem: 59990075Sobrien if some other string required even bigger 60090075Sobrien alignment than "", then linker might think the 60190075Sobrien "" is just part of padding after some other string 60290075Sobrien and not put it into the hash table initially. 60390075Sobrien But this means "" could have smaller alignment 60490075Sobrien than requested. */ 60590075Sobrien#ifdef ASM_OUTPUT_SECTION_START 60690075Sobrien named_section_flags (name, flags); 60790075Sobrien ASM_OUTPUT_SECTION_START (asm_out_file); 60890075Sobrien#else 60990075Sobrien readonly_data_section (); 61018334Speter#endif 61190075Sobrien return; 61290075Sobrien } 61390075Sobrien 61490075Sobrien named_section_flags (name, flags); 61590075Sobrien return; 61690075Sobrien } 61790075Sobrien } 61818334Speter } 619132718Skan 62090075Sobrien readonly_data_section (); 621117395Skan} 62290075Sobrien 62390075Sobrien/* Tell assembler to switch to the section for constant merging. */ 62490075Sobrien 62590075Sobrienvoid 626132718Skanmergeable_constant_section (enum machine_mode mode ATTRIBUTE_UNUSED, 627132718Skan unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED, 628132718Skan unsigned int flags ATTRIBUTE_UNUSED) 62990075Sobrien{ 63090075Sobrien unsigned int modesize = GET_MODE_BITSIZE (mode); 63190075Sobrien 632132718Skan if (HAVE_GAS_SHF_MERGE && flag_merge_constants 63390075Sobrien && mode != VOIDmode 63490075Sobrien && mode != BLKmode 63590075Sobrien && modesize <= align 63690075Sobrien && align >= 8 63790075Sobrien && align <= 256 63890075Sobrien && (align & (align - 1)) == 0) 63950397Sobrien { 64090075Sobrien char name[24]; 64190075Sobrien 64290075Sobrien sprintf (name, ".rodata.cst%d", (int) (align / 8)); 64390075Sobrien flags |= (align / 8) | SECTION_MERGE; 64490075Sobrien named_section_flags (name, flags); 64590075Sobrien return; 646117395Skan } 647132718Skan 64890075Sobrien readonly_data_section (); 64918334Speter} 65090075Sobrien 65118334Speter/* Given NAME, a putative register name, discard any customary prefixes. */ 65218334Speter 65352284Sobrienstatic const char * 654132718Skanstrip_reg_name (const char *name) 65518334Speter{ 65618334Speter#ifdef REGISTER_PREFIX 65718334Speter if (!strncmp (name, REGISTER_PREFIX, strlen (REGISTER_PREFIX))) 65818334Speter name += strlen (REGISTER_PREFIX); 65918334Speter#endif 66018334Speter if (name[0] == '%' || name[0] == '#') 66118334Speter name++; 66218334Speter return name; 66318334Speter} 66418334Speter 66518334Speter/* Decode an `asm' spec for a declaration as a register name. 66618334Speter Return the register number, or -1 if nothing specified, 66718334Speter or -2 if the ASMSPEC is not `cc' or `memory' and is not recognized, 66818334Speter or -3 if ASMSPEC is `cc' and is not recognized, 66918334Speter or -4 if ASMSPEC is `memory' and is not recognized. 67018334Speter Accept an exact spelling or a decimal number. 67118334Speter Prefixes such as % are optional. */ 67218334Speter 67318334Speterint 674132718Skandecode_reg_name (const char *asmspec) 67518334Speter{ 67618334Speter if (asmspec != 0) 67718334Speter { 67818334Speter int i; 67918334Speter 68018334Speter /* Get rid of confusing prefixes. */ 68118334Speter asmspec = strip_reg_name (asmspec); 68290075Sobrien 68318334Speter /* Allow a decimal number as a "register name". */ 68418334Speter for (i = strlen (asmspec) - 1; i >= 0; i--) 68590075Sobrien if (! ISDIGIT (asmspec[i])) 68618334Speter break; 68718334Speter if (asmspec[0] != 0 && i < 0) 68818334Speter { 68918334Speter i = atoi (asmspec); 69018334Speter if (i < FIRST_PSEUDO_REGISTER && i >= 0) 69118334Speter return i; 69218334Speter else 69318334Speter return -2; 69418334Speter } 69518334Speter 69618334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 69718334Speter if (reg_names[i][0] 69818334Speter && ! strcmp (asmspec, strip_reg_name (reg_names[i]))) 69918334Speter return i; 70018334Speter 70118334Speter#ifdef ADDITIONAL_REGISTER_NAMES 70218334Speter { 70390075Sobrien static const struct { const char *const name; const int number; } table[] 70418334Speter = ADDITIONAL_REGISTER_NAMES; 70518334Speter 70690075Sobrien for (i = 0; i < (int) ARRAY_SIZE (table); i++) 70718334Speter if (! strcmp (asmspec, table[i].name)) 70818334Speter return table[i].number; 70918334Speter } 71018334Speter#endif /* ADDITIONAL_REGISTER_NAMES */ 71118334Speter 71218334Speter if (!strcmp (asmspec, "memory")) 71318334Speter return -4; 71418334Speter 71518334Speter if (!strcmp (asmspec, "cc")) 71618334Speter return -3; 71718334Speter 71818334Speter return -2; 71918334Speter } 72018334Speter 72118334Speter return -1; 72218334Speter} 72318334Speter 72490075Sobrien/* Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL. DECL should 72590075Sobrien have static storage duration. In other words, it should not be an 72690075Sobrien automatic variable, including PARM_DECLs. 72718334Speter 72890075Sobrien There is, however, one exception: this function handles variables 72990075Sobrien explicitly placed in a particular register by the user. 73090075Sobrien 73190075Sobrien ASMSPEC, if not 0, is the string which the user specified as the 73290075Sobrien assembler symbol name. 73390075Sobrien 73418334Speter This is never called for PARM_DECL nodes. */ 73518334Speter 73618334Spetervoid 737132718Skanmake_decl_rtl (tree decl, const char *asmspec) 73818334Speter{ 73990075Sobrien const char *name = 0; 74018334Speter int reg_number; 74190075Sobrien rtx x; 74218334Speter 74390075Sobrien /* Check that we are not being given an automatic variable. */ 74490075Sobrien /* A weak alias has TREE_PUBLIC set but not the other bits. */ 74590075Sobrien if (TREE_CODE (decl) == PARM_DECL 74690075Sobrien || TREE_CODE (decl) == RESULT_DECL 74790075Sobrien || (TREE_CODE (decl) == VAR_DECL 74890075Sobrien && !TREE_STATIC (decl) 74990075Sobrien && !TREE_PUBLIC (decl) 75090075Sobrien && !DECL_EXTERNAL (decl) 75190075Sobrien && !DECL_REGISTER (decl))) 75290075Sobrien abort (); 75390075Sobrien /* And that we were not given a type or a label. */ 75490075Sobrien else if (TREE_CODE (decl) == TYPE_DECL 75590075Sobrien || TREE_CODE (decl) == LABEL_DECL) 75690075Sobrien abort (); 75718334Speter 75890075Sobrien /* For a duplicate declaration, we can be called twice on the 75990075Sobrien same DECL node. Don't discard the RTL already made. */ 76090075Sobrien if (DECL_RTL_SET_P (decl)) 76190075Sobrien { 76290075Sobrien /* If the old RTL had the wrong mode, fix the mode. */ 76390075Sobrien if (GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl)) 76490075Sobrien SET_DECL_RTL (decl, adjust_address_nv (DECL_RTL (decl), 76590075Sobrien DECL_MODE (decl), 0)); 76618334Speter 767117395Skan /* ??? Another way to do this would be to maintain a hashed 768117395Skan table of such critters. Instead of adding stuff to a DECL 769117395Skan to give certain attributes to it, we could use an external 770117395Skan hash map from DECL to set of attributes. */ 771117395Skan 77290075Sobrien /* Let the target reassign the RTL if it wants. 77390075Sobrien This is necessary, for example, when one machine specific 77490075Sobrien decl attribute overrides another. */ 775132718Skan (* targetm.encode_section_info) (decl, DECL_RTL (decl), false); 77690075Sobrien return; 77790075Sobrien } 77890075Sobrien 77990075Sobrien reg_number = decode_reg_name (asmspec); 78018334Speter if (reg_number == -2) 78118334Speter { 78290075Sobrien /* ASMSPEC is given, and not the name of a register. Mark the 78390075Sobrien name with a star so assemble_name won't munge it. */ 78490075Sobrien char *starred = alloca (strlen (asmspec) + 2); 78590075Sobrien starred[0] = '*'; 78690075Sobrien strcpy (starred + 1, asmspec); 787132718Skan change_decl_assembler_name (decl, get_identifier (starred)); 78818334Speter } 78918334Speter 790132718Skan name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 791132718Skan 79290075Sobrien if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl)) 79318334Speter { 79418334Speter /* First detect errors in declaring global registers. */ 79590075Sobrien if (reg_number == -1) 796132718Skan error ("%Jregister name not specified for '%D'", decl, decl); 79790075Sobrien else if (reg_number < 0) 798132718Skan error ("%Jinvalid register name for '%D'", decl, decl); 79990075Sobrien else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode) 800132718Skan error ("%Jdata type of '%D' isn't suitable for a register", 801132718Skan decl, decl); 80290075Sobrien else if (! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl)))) 803132718Skan error ("%Jregister specified for '%D' isn't suitable for data type", 804132718Skan decl, decl); 80518334Speter /* Now handle properly declared static register variables. */ 80690075Sobrien else 80718334Speter { 80818334Speter int nregs; 80950397Sobrien 81090075Sobrien if (DECL_INITIAL (decl) != 0 && TREE_STATIC (decl)) 81118334Speter { 81218334Speter DECL_INITIAL (decl) = 0; 81318334Speter error ("global register variable has initial value"); 81418334Speter } 81518334Speter if (TREE_THIS_VOLATILE (decl)) 81618334Speter warning ("volatile register variables don't work as you might wish"); 81718334Speter 81818334Speter /* If the user specified one of the eliminables registers here, 81918334Speter e.g., FRAME_POINTER_REGNUM, we don't want to get this variable 82090075Sobrien confused with that register and be eliminated. This usage is 82190075Sobrien somewhat suspect... */ 82218334Speter 82390075Sobrien SET_DECL_RTL (decl, gen_rtx_raw_REG (DECL_MODE (decl), reg_number)); 82490075Sobrien ORIGINAL_REGNO (DECL_RTL (decl)) = reg_number; 82518334Speter REG_USERVAR_P (DECL_RTL (decl)) = 1; 82618334Speter 82790075Sobrien if (TREE_STATIC (decl)) 82818334Speter { 82918334Speter /* Make this register global, so not usable for anything 83018334Speter else. */ 83190075Sobrien#ifdef ASM_DECLARE_REGISTER_GLOBAL 83290075Sobrien ASM_DECLARE_REGISTER_GLOBAL (asm_out_file, decl, reg_number, name); 83390075Sobrien#endif 83418334Speter nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl)); 83518334Speter while (nregs > 0) 83618334Speter globalize_reg (reg_number + --nregs); 83718334Speter } 83890075Sobrien 83990075Sobrien /* As a register variable, it has no section. */ 84090075Sobrien return; 84118334Speter } 84290075Sobrien } 84318334Speter 84490075Sobrien /* Now handle ordinary static variables and functions (in memory). 84590075Sobrien Also handle vars declared register invalidly. */ 84618334Speter 84790075Sobrien if (reg_number >= 0 || reg_number == -3) 848132718Skan error ("%Jregister name given for non-register variable '%D'", decl, decl); 84918334Speter 85090075Sobrien /* Specifying a section attribute on a variable forces it into a 85190075Sobrien non-.bss section, and thus it cannot be common. */ 85290075Sobrien if (TREE_CODE (decl) == VAR_DECL 85390075Sobrien && DECL_SECTION_NAME (decl) != NULL_TREE 85490075Sobrien && DECL_INITIAL (decl) == NULL_TREE 85590075Sobrien && DECL_COMMON (decl)) 85690075Sobrien DECL_COMMON (decl) = 0; 85718334Speter 858117395Skan /* Variables can't be both common and weak. */ 859117395Skan if (TREE_CODE (decl) == VAR_DECL && DECL_WEAK (decl)) 860117395Skan DECL_COMMON (decl) = 0; 861117395Skan 862132718Skan x = gen_rtx_SYMBOL_REF (Pmode, name); 863132718Skan SYMBOL_REF_WEAK (x) = DECL_WEAK (decl); 864132718Skan SYMBOL_REF_DECL (x) = decl; 86518334Speter 866132718Skan x = gen_rtx_MEM (DECL_MODE (decl), x); 86790075Sobrien if (TREE_CODE (decl) != FUNCTION_DECL) 86890075Sobrien set_mem_attributes (x, decl, 1); 86990075Sobrien SET_DECL_RTL (decl, x); 87090075Sobrien 87190075Sobrien /* Optionally set flags or add text to the name to record information 87290075Sobrien such as that it is a function name. 87390075Sobrien If the name is changed, the macro ASM_OUTPUT_LABELREF 87490075Sobrien will have to know how to strip this information. */ 875132718Skan (* targetm.encode_section_info) (decl, DECL_RTL (decl), true); 87618334Speter} 87718334Speter 87818334Speter/* Make the rtl for variable VAR be volatile. 87918334Speter Use this only for static variables. */ 88018334Speter 88118334Spetervoid 882132718Skanmake_var_volatile (tree var) 88318334Speter{ 88418334Speter if (GET_CODE (DECL_RTL (var)) != MEM) 88518334Speter abort (); 88618334Speter 88718334Speter MEM_VOLATILE_P (DECL_RTL (var)) = 1; 88818334Speter} 88918334Speter 89018334Speter/* Output a string of literal assembler code 89118334Speter for an `asm' keyword used between functions. */ 89218334Speter 89318334Spetervoid 894132718Skanassemble_asm (tree string) 89518334Speter{ 89618334Speter app_enable (); 89718334Speter 89818334Speter if (TREE_CODE (string) == ADDR_EXPR) 89918334Speter string = TREE_OPERAND (string, 0); 90018334Speter 90118334Speter fprintf (asm_out_file, "\t%s\n", TREE_STRING_POINTER (string)); 90218334Speter} 90318334Speter 90490075Sobrien/* Record an element in the table of global destructors. SYMBOL is 90590075Sobrien a SYMBOL_REF of the function to be called; PRIORITY is a number 90690075Sobrien between 0 and MAX_INIT_PRIORITY. */ 90718334Speter 90890075Sobrienvoid 909132718Skandefault_stabs_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED) 91090075Sobrien{ 91190075Sobrien /* Tell GNU LD that this is part of the static destructor set. 91290075Sobrien This will work for any system that uses stabs, most usefully 91390075Sobrien aout systems. */ 91490075Sobrien fprintf (asm_out_file, "%s\"___DTOR_LIST__\",22,0,0,", ASM_STABS_OP); 91590075Sobrien assemble_name (asm_out_file, XSTR (symbol, 0)); 91690075Sobrien fputc ('\n', asm_out_file); 91790075Sobrien} 91818334Speter 91990075Sobrienvoid 920132718Skandefault_named_section_asm_out_destructor (rtx symbol, int priority) 92190075Sobrien{ 92290075Sobrien const char *section = ".dtors"; 92390075Sobrien char buf[16]; 92418334Speter 92590075Sobrien /* ??? This only works reliably with the GNU linker. */ 92690075Sobrien if (priority != DEFAULT_INIT_PRIORITY) 92790075Sobrien { 92890075Sobrien sprintf (buf, ".dtors.%.5u", 92990075Sobrien /* Invert the numbering so the linker puts us in the proper 93090075Sobrien order; constructors are run from right to left, and the 93190075Sobrien linker sorts in increasing order. */ 93290075Sobrien MAX_INIT_PRIORITY - priority); 93390075Sobrien section = buf; 93490075Sobrien } 93590075Sobrien 93690075Sobrien named_section_flags (section, SECTION_WRITE); 93790075Sobrien assemble_align (POINTER_SIZE); 93890075Sobrien assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); 93990075Sobrien} 94090075Sobrien 94190075Sobrien#ifdef DTORS_SECTION_ASM_OP 94218334Spetervoid 943132718Skandtors_section (void) 94418334Speter{ 94590075Sobrien if (in_section != in_dtors) 94618334Speter { 94790075Sobrien in_section = in_dtors; 94890075Sobrien fputs (DTORS_SECTION_ASM_OP, asm_out_file); 94918334Speter fputc ('\n', asm_out_file); 95018334Speter } 95118334Speter} 95218334Speter 95390075Sobrienvoid 954132718Skandefault_dtor_section_asm_out_destructor (rtx symbol, 955132718Skan int priority ATTRIBUTE_UNUSED) 95690075Sobrien{ 95790075Sobrien dtors_section (); 95890075Sobrien assemble_align (POINTER_SIZE); 95990075Sobrien assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); 96090075Sobrien} 96190075Sobrien#endif 96290075Sobrien 96318334Speter/* Likewise for global constructors. */ 96418334Speter 96518334Spetervoid 966132718Skandefault_stabs_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED) 96718334Speter{ 96890075Sobrien /* Tell GNU LD that this is part of the static destructor set. 96990075Sobrien This will work for any system that uses stabs, most usefully 97090075Sobrien aout systems. */ 97190075Sobrien fprintf (asm_out_file, "%s\"___CTOR_LIST__\",22,0,0,", ASM_STABS_OP); 97290075Sobrien assemble_name (asm_out_file, XSTR (symbol, 0)); 97390075Sobrien fputc ('\n', asm_out_file); 97490075Sobrien} 97590075Sobrien 97690075Sobrienvoid 977132718Skandefault_named_section_asm_out_constructor (rtx symbol, int priority) 97890075Sobrien{ 97990075Sobrien const char *section = ".ctors"; 98090075Sobrien char buf[16]; 98190075Sobrien 98290075Sobrien /* ??? This only works reliably with the GNU linker. */ 98390075Sobrien if (priority != DEFAULT_INIT_PRIORITY) 98418334Speter { 98590075Sobrien sprintf (buf, ".ctors.%.5u", 98690075Sobrien /* Invert the numbering so the linker puts us in the proper 98790075Sobrien order; constructors are run from right to left, and the 98890075Sobrien linker sorts in increasing order. */ 98990075Sobrien MAX_INIT_PRIORITY - priority); 99090075Sobrien section = buf; 99118334Speter } 99290075Sobrien 99390075Sobrien named_section_flags (section, SECTION_WRITE); 99490075Sobrien assemble_align (POINTER_SIZE); 99590075Sobrien assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); 99618334Speter} 99718334Speter 99890075Sobrien#ifdef CTORS_SECTION_ASM_OP 99918334Spetervoid 1000132718Skanctors_section (void) 100118334Speter{ 100290075Sobrien if (in_section != in_ctors) 100318334Speter { 100490075Sobrien in_section = in_ctors; 100590075Sobrien fputs (CTORS_SECTION_ASM_OP, asm_out_file); 100618334Speter fputc ('\n', asm_out_file); 100718334Speter } 100890075Sobrien} 100990075Sobrien 101090075Sobrienvoid 1011132718Skandefault_ctor_section_asm_out_constructor (rtx symbol, 1012132718Skan int priority ATTRIBUTE_UNUSED) 101390075Sobrien{ 101490075Sobrien ctors_section (); 101590075Sobrien assemble_align (POINTER_SIZE); 101690075Sobrien assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); 101790075Sobrien} 101818334Speter#endif 101918334Speter 102050397Sobrien/* CONSTANT_POOL_BEFORE_FUNCTION may be defined as an expression with 1021117395Skan a nonzero value if the constant pool should be output before the 102250397Sobrien start of the function, or a zero value if the pool should output 102350397Sobrien after the end of the function. The default is to put it before the 102450397Sobrien start. */ 102550397Sobrien 102650397Sobrien#ifndef CONSTANT_POOL_BEFORE_FUNCTION 102750397Sobrien#define CONSTANT_POOL_BEFORE_FUNCTION 1 102850397Sobrien#endif 102950397Sobrien 1030132718Skan/* DECL is an object (either VAR_DECL or FUNCTION_DECL) which is going 1031132718Skan to be output to assembler. 1032132718Skan Set first_global_object_name and weak_global_object_name as appropriate. */ 1033132718Skan 1034132718Skanvoid 1035132718Skannotice_global_symbol (tree decl) 1036132718Skan{ 1037132718Skan const char **type = &first_global_object_name; 1038132718Skan 1039132718Skan if (first_global_object_name 1040132718Skan || !TREE_PUBLIC (decl) || DECL_EXTERNAL (decl) 1041132718Skan || !DECL_NAME (decl) 1042132718Skan || (TREE_CODE (decl) != FUNCTION_DECL 1043132718Skan && (TREE_CODE (decl) != VAR_DECL 1044132718Skan || (DECL_COMMON (decl) 1045132718Skan && (DECL_INITIAL (decl) == 0 1046132718Skan || DECL_INITIAL (decl) == error_mark_node)))) 1047132718Skan || GET_CODE (DECL_RTL (decl)) != MEM) 1048132718Skan return; 1049132718Skan 1050132718Skan /* We win when global object is found, but it is usefull to know about weak 1051132718Skan symbol as well so we can produce nicer unique names. */ 1052132718Skan if (DECL_WEAK (decl) || DECL_ONE_ONLY (decl)) 1053132718Skan type = &weak_global_object_name; 1054132718Skan 1055132718Skan if (!*type) 1056132718Skan { 1057132718Skan const char *p; 1058132718Skan char *name; 1059132718Skan rtx decl_rtl = DECL_RTL (decl); 1060132718Skan 1061132718Skan p = (* targetm.strip_name_encoding) (XSTR (XEXP (decl_rtl, 0), 0)); 1062132718Skan name = xstrdup (p); 1063132718Skan 1064132718Skan *type = name; 1065132718Skan } 1066132718Skan} 1067132718Skan 106818334Speter/* Output assembler code for the constant pool of a function and associated 106918334Speter with defining the name of the function. DECL describes the function. 107018334Speter NAME is the function's name. For the constant pool, we use the current 107118334Speter constant pool data. */ 107218334Speter 107318334Spetervoid 1074132718Skanassemble_start_function (tree decl, const char *fnname) 107518334Speter{ 107618334Speter int align; 107718334Speter 107818334Speter /* The following code does not need preprocessing in the assembler. */ 107918334Speter 108018334Speter app_disable (); 108118334Speter 108250397Sobrien if (CONSTANT_POOL_BEFORE_FUNCTION) 108350397Sobrien output_constant_pool (fnname, decl); 108418334Speter 1085102780Skan resolve_unique_section (decl, 0, flag_function_sections); 108618334Speter function_section (decl); 108718334Speter 108818334Speter /* Tell assembler to move to target machine's alignment for functions. */ 108918334Speter align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT); 1090104752Skan if (align < force_align_functions_log) 1091104752Skan align = force_align_functions_log; 109218334Speter if (align > 0) 109390075Sobrien { 109490075Sobrien ASM_OUTPUT_ALIGN (asm_out_file, align); 109590075Sobrien } 109618334Speter 109790075Sobrien /* Handle a user-specified function alignment. 109890075Sobrien Note that we still need to align to FUNCTION_BOUNDARY, as above, 109990075Sobrien because ASM_OUTPUT_MAX_SKIP_ALIGN might not do any alignment at all. */ 1100117395Skan if (align_functions_log > align 1101117395Skan && cfun->function_frequency != FUNCTION_FREQUENCY_UNLIKELY_EXECUTED) 110290075Sobrien { 110390075Sobrien#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN 110490075Sobrien ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 1105117395Skan align_functions_log, align_functions - 1); 110690075Sobrien#else 110790075Sobrien ASM_OUTPUT_ALIGN (asm_out_file, align_functions_log); 110890075Sobrien#endif 110990075Sobrien } 111090075Sobrien 111118334Speter#ifdef ASM_OUTPUT_FUNCTION_PREFIX 111218334Speter ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname); 111318334Speter#endif 111418334Speter 111590075Sobrien (*debug_hooks->begin_function) (decl); 111618334Speter 111718334Speter /* Make function name accessible from other files, if appropriate. */ 111818334Speter 111918334Speter if (TREE_PUBLIC (decl)) 112018334Speter { 1121132718Skan notice_global_symbol (decl); 112218334Speter 112396263Sobrien globalize_decl (decl); 1124117395Skan 1125117395Skan maybe_assemble_visibility (decl); 112618334Speter } 112718334Speter 1128132718Skan /* Do any machine/system dependent processing of the function name. */ 112918334Speter#ifdef ASM_DECLARE_FUNCTION_NAME 113018334Speter ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl); 113118334Speter#else 113218334Speter /* Standard thing is just output label for the function. */ 113350397Sobrien ASM_OUTPUT_LABEL (asm_out_file, fnname); 113418334Speter#endif /* ASM_DECLARE_FUNCTION_NAME */ 113518334Speter} 113618334Speter 113718334Speter/* Output assembler code associated with defining the size of the 113818334Speter function. DECL describes the function. NAME is the function's name. */ 113918334Speter 114018334Spetervoid 1141132718Skanassemble_end_function (tree decl, const char *fnname) 114218334Speter{ 114318334Speter#ifdef ASM_DECLARE_FUNCTION_SIZE 114418334Speter ASM_DECLARE_FUNCTION_SIZE (asm_out_file, fnname, decl); 114518334Speter#endif 114650397Sobrien if (! CONSTANT_POOL_BEFORE_FUNCTION) 114750397Sobrien { 114850397Sobrien output_constant_pool (fnname, decl); 114950397Sobrien function_section (decl); /* need to switch back */ 115050397Sobrien } 115118334Speter} 115218334Speter 115318334Speter/* Assemble code to leave SIZE bytes of zeros. */ 115418334Speter 115518334Spetervoid 1156132718Skanassemble_zeros (unsigned HOST_WIDE_INT size) 115718334Speter{ 115852284Sobrien /* Do no output if -fsyntax-only. */ 115952284Sobrien if (flag_syntax_only) 116052284Sobrien return; 116152284Sobrien 116218334Speter#ifdef ASM_NO_SKIP_IN_TEXT 116318334Speter /* The `space' pseudo in the text section outputs nop insns rather than 0s, 116418334Speter so we must output 0s explicitly in the text section. */ 116518334Speter if (ASM_NO_SKIP_IN_TEXT && in_text_section ()) 116618334Speter { 1167132718Skan unsigned HOST_WIDE_INT i; 116890075Sobrien for (i = 0; i < size; i++) 116990075Sobrien assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1); 117018334Speter } 117118334Speter else 117218334Speter#endif 117318334Speter if (size > 0) 117450397Sobrien ASM_OUTPUT_SKIP (asm_out_file, size); 117518334Speter} 117618334Speter 117718334Speter/* Assemble an alignment pseudo op for an ALIGN-bit boundary. */ 117818334Speter 117918334Spetervoid 1180132718Skanassemble_align (int align) 118118334Speter{ 118218334Speter if (align > BITS_PER_UNIT) 118390075Sobrien { 118490075Sobrien ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT)); 118590075Sobrien } 118618334Speter} 118718334Speter 118818334Speter/* Assemble a string constant with the specified C string as contents. */ 118918334Speter 119018334Spetervoid 1191132718Skanassemble_string (const char *p, int size) 119218334Speter{ 119318334Speter int pos = 0; 119418334Speter int maximum = 2000; 119518334Speter 119618334Speter /* If the string is very long, split it up. */ 119718334Speter 119818334Speter while (pos < size) 119918334Speter { 120018334Speter int thissize = size - pos; 120118334Speter if (thissize > maximum) 120218334Speter thissize = maximum; 120318334Speter 120450397Sobrien ASM_OUTPUT_ASCII (asm_out_file, p, thissize); 120518334Speter 120618334Speter pos += thissize; 120718334Speter p += thissize; 120818334Speter } 120918334Speter} 121018334Speter 121118334Speter 121290075Sobrien#if defined ASM_OUTPUT_ALIGNED_DECL_LOCAL 121390075Sobrien#define ASM_EMIT_LOCAL(decl, name, size, rounded) \ 121490075Sobrien ASM_OUTPUT_ALIGNED_DECL_LOCAL (asm_out_file, decl, name, size, DECL_ALIGN (decl)) 121590075Sobrien#else 121690075Sobrien#if defined ASM_OUTPUT_ALIGNED_LOCAL 121790075Sobrien#define ASM_EMIT_LOCAL(decl, name, size, rounded) \ 121890075Sobrien ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, DECL_ALIGN (decl)) 121990075Sobrien#else 122090075Sobrien#define ASM_EMIT_LOCAL(decl, name, size, rounded) \ 122190075Sobrien ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded) 122290075Sobrien#endif 122390075Sobrien#endif 122490075Sobrien 122590075Sobrien#if defined ASM_OUTPUT_ALIGNED_BSS 122690075Sobrien#define ASM_EMIT_BSS(decl, name, size, rounded) \ 122790075Sobrien ASM_OUTPUT_ALIGNED_BSS (asm_out_file, decl, name, size, DECL_ALIGN (decl)) 122890075Sobrien#else 122990075Sobrien#if defined ASM_OUTPUT_BSS 123090075Sobrien#define ASM_EMIT_BSS(decl, name, size, rounded) \ 123190075Sobrien ASM_OUTPUT_BSS (asm_out_file, decl, name, size, rounded) 123290075Sobrien#else 123390075Sobrien#undef ASM_EMIT_BSS 123490075Sobrien#endif 123590075Sobrien#endif 123690075Sobrien 123790075Sobrien#if defined ASM_OUTPUT_ALIGNED_DECL_COMMON 123890075Sobrien#define ASM_EMIT_COMMON(decl, name, size, rounded) \ 123990075Sobrien ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, decl, name, size, DECL_ALIGN (decl)) 124090075Sobrien#else 124190075Sobrien#if defined ASM_OUTPUT_ALIGNED_COMMON 124290075Sobrien#define ASM_EMIT_COMMON(decl, name, size, rounded) \ 124390075Sobrien ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size, DECL_ALIGN (decl)) 124490075Sobrien#else 124590075Sobrien#define ASM_EMIT_COMMON(decl, name, size, rounded) \ 124690075Sobrien ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded) 124790075Sobrien#endif 124890075Sobrien#endif 124990075Sobrien 1250117395Skanstatic bool 1251132718Skanasm_emit_uninitialised (tree decl, const char *name, 1252132718Skan unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED, 1253132718Skan unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED) 125490075Sobrien{ 125590075Sobrien enum 125690075Sobrien { 125790075Sobrien asm_dest_common, 125890075Sobrien asm_dest_bss, 125990075Sobrien asm_dest_local 126090075Sobrien } 126190075Sobrien destination = asm_dest_local; 126290075Sobrien 1263117395Skan /* ??? We should handle .bss via select_section mechanisms rather than 1264117395Skan via special target hooks. That would eliminate this special case. */ 126590075Sobrien if (TREE_PUBLIC (decl)) 126690075Sobrien { 1267117395Skan if (!DECL_COMMON (decl)) 1268117395Skan#ifdef ASM_EMIT_BSS 126990075Sobrien destination = asm_dest_bss; 1270117395Skan#else 1271117395Skan return false; 1272117395Skan#endif 127390075Sobrien else 127490075Sobrien destination = asm_dest_common; 127590075Sobrien } 127690075Sobrien 127796263Sobrien if (destination == asm_dest_bss) 127896263Sobrien globalize_decl (decl); 1279102780Skan resolve_unique_section (decl, 0, flag_data_sections); 128096263Sobrien 128190075Sobrien if (flag_shared_data) 128290075Sobrien { 128390075Sobrien switch (destination) 128490075Sobrien { 128590075Sobrien#ifdef ASM_OUTPUT_SHARED_BSS 128690075Sobrien case asm_dest_bss: 128790075Sobrien ASM_OUTPUT_SHARED_BSS (asm_out_file, decl, name, size, rounded); 128890075Sobrien return; 128990075Sobrien#endif 129090075Sobrien#ifdef ASM_OUTPUT_SHARED_COMMON 129190075Sobrien case asm_dest_common: 129290075Sobrien ASM_OUTPUT_SHARED_COMMON (asm_out_file, name, size, rounded); 129390075Sobrien return; 129490075Sobrien#endif 129590075Sobrien#ifdef ASM_OUTPUT_SHARED_LOCAL 129690075Sobrien case asm_dest_local: 129790075Sobrien ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded); 129890075Sobrien return; 129990075Sobrien#endif 130090075Sobrien default: 130190075Sobrien break; 130290075Sobrien } 130390075Sobrien } 130490075Sobrien 130590075Sobrien switch (destination) 130690075Sobrien { 130790075Sobrien#ifdef ASM_EMIT_BSS 130890075Sobrien case asm_dest_bss: 130990075Sobrien ASM_EMIT_BSS (decl, name, size, rounded); 131090075Sobrien break; 131190075Sobrien#endif 131290075Sobrien case asm_dest_common: 131390075Sobrien ASM_EMIT_COMMON (decl, name, size, rounded); 131490075Sobrien break; 131590075Sobrien case asm_dest_local: 131690075Sobrien ASM_EMIT_LOCAL (decl, name, size, rounded); 131790075Sobrien break; 131890075Sobrien default: 131990075Sobrien abort (); 132090075Sobrien } 132190075Sobrien 1322117395Skan return true; 132390075Sobrien} 132490075Sobrien 132518334Speter/* Assemble everything that is needed for a variable or function declaration. 132618334Speter Not used for automatic variables, and not used for function definitions. 132718334Speter Should not be called for variables of incomplete structure type. 132818334Speter 132918334Speter TOP_LEVEL is nonzero if this variable has file scope. 133018334Speter AT_END is nonzero if this is the special handling, at end of compilation, 133118334Speter to define things that have had only tentative definitions. 133218334Speter DONT_OUTPUT_DATA if nonzero means don't actually output the 133318334Speter initial value (that will be done by the caller). */ 133418334Speter 133518334Spetervoid 1336132718Skanassemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, 1337132718Skan int at_end ATTRIBUTE_UNUSED, int dont_output_data) 133818334Speter{ 133990075Sobrien const char *name; 134050397Sobrien unsigned int align; 134118334Speter int reloc = 0; 134290075Sobrien rtx decl_rtl; 134318334Speter 1344132718Skan if (lang_hooks.decls.prepare_assemble_variable) 1345132718Skan (*lang_hooks.decls.prepare_assemble_variable) (decl); 1346132718Skan 134718334Speter last_assemble_variable_decl = 0; 134818334Speter 134918334Speter /* Normally no need to say anything here for external references, 135018334Speter since assemble_external is called by the language-specific code 135118334Speter when a declaration is first seen. */ 135218334Speter 135318334Speter if (DECL_EXTERNAL (decl)) 135418334Speter return; 135518334Speter 135618334Speter /* Output no assembler code for a function declaration. 135718334Speter Only definitions of functions output anything. */ 135818334Speter 135918334Speter if (TREE_CODE (decl) == FUNCTION_DECL) 136018334Speter return; 136118334Speter 136290075Sobrien /* Do nothing for global register variables. */ 136390075Sobrien if (DECL_RTL_SET_P (decl) && GET_CODE (DECL_RTL (decl)) == REG) 136490075Sobrien { 136590075Sobrien TREE_ASM_WRITTEN (decl) = 1; 136690075Sobrien return; 136790075Sobrien } 136890075Sobrien 136918334Speter /* If type was incomplete when the variable was declared, 137018334Speter see if it is complete now. */ 137118334Speter 137218334Speter if (DECL_SIZE (decl) == 0) 137318334Speter layout_decl (decl, 0); 137418334Speter 137518334Speter /* Still incomplete => don't allocate it; treat the tentative defn 137618334Speter (which is what it must have been) as an `extern' reference. */ 137718334Speter 137818334Speter if (!dont_output_data && DECL_SIZE (decl) == 0) 137918334Speter { 1380132718Skan error ("%Jstorage size of `%D' isn't known", decl, decl); 138118334Speter TREE_ASM_WRITTEN (decl) = 1; 138218334Speter return; 138318334Speter } 138418334Speter 138518334Speter /* The first declaration of a variable that comes through this function 138618334Speter decides whether it is global (in C, has external linkage) 138718334Speter or local (in C, has internal linkage). So do nothing more 138818334Speter if this function has already run. */ 138918334Speter 139018334Speter if (TREE_ASM_WRITTEN (decl)) 139118334Speter return; 139218334Speter 1393117395Skan /* Make sure targetm.encode_section_info is invoked before we set 1394117395Skan ASM_WRITTEN. */ 139590075Sobrien decl_rtl = DECL_RTL (decl); 139690075Sobrien 139718334Speter TREE_ASM_WRITTEN (decl) = 1; 139818334Speter 139952284Sobrien /* Do no output if -fsyntax-only. */ 140052284Sobrien if (flag_syntax_only) 140152284Sobrien return; 140252284Sobrien 140318334Speter app_disable (); 140418334Speter 140590075Sobrien if (! dont_output_data 140690075Sobrien && ! host_integerp (DECL_SIZE_UNIT (decl), 1)) 140718334Speter { 1408132718Skan error ("%Jsize of variable '%D' is too large", decl, decl); 140990075Sobrien return; 141018334Speter } 141118334Speter 141290075Sobrien name = XSTR (XEXP (decl_rtl, 0), 0); 1413132718Skan if (TREE_PUBLIC (decl) && DECL_NAME (decl)) 1414132718Skan notice_global_symbol (decl); 141550397Sobrien 141650397Sobrien /* Compute the alignment of this data. */ 141750397Sobrien 141850397Sobrien align = DECL_ALIGN (decl); 141950397Sobrien 142050397Sobrien /* In the case for initialing an array whose length isn't specified, 142150397Sobrien where we have not yet been able to do the layout, 142250397Sobrien figure out the proper alignment now. */ 142350397Sobrien if (dont_output_data && DECL_SIZE (decl) == 0 142450397Sobrien && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) 142550397Sobrien align = MAX (align, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl)))); 142650397Sobrien 142750397Sobrien /* Some object file formats have a maximum alignment which they support. 142850397Sobrien In particular, a.out format supports a maximum alignment of 4. */ 142950397Sobrien#ifndef MAX_OFILE_ALIGNMENT 143050397Sobrien#define MAX_OFILE_ALIGNMENT BIGGEST_ALIGNMENT 143150397Sobrien#endif 143250397Sobrien if (align > MAX_OFILE_ALIGNMENT) 143350397Sobrien { 1434132718Skan warning ("%Jalignment of '%D' is greater than maximum object " 1435132718Skan "file alignment. Using %d", decl, decl, 1436132718Skan MAX_OFILE_ALIGNMENT/BITS_PER_UNIT); 143750397Sobrien align = MAX_OFILE_ALIGNMENT; 143850397Sobrien } 143950397Sobrien 144050397Sobrien /* On some machines, it is good to increase alignment sometimes. */ 144190075Sobrien if (! DECL_USER_ALIGN (decl)) 144290075Sobrien { 144350397Sobrien#ifdef DATA_ALIGNMENT 144490075Sobrien align = DATA_ALIGNMENT (TREE_TYPE (decl), align); 144550397Sobrien#endif 144650397Sobrien#ifdef CONSTANT_ALIGNMENT 144790075Sobrien if (DECL_INITIAL (decl) != 0 && DECL_INITIAL (decl) != error_mark_node) 1448117395Skan align = CONSTANT_ALIGNMENT (DECL_INITIAL (decl), align); 144950397Sobrien#endif 145090075Sobrien } 145150397Sobrien 145250397Sobrien /* Reset the alignment in case we have made it tighter, so we can benefit 145350397Sobrien from it in get_pointer_alignment. */ 145450397Sobrien DECL_ALIGN (decl) = align; 145590075Sobrien set_mem_align (decl_rtl, align); 145650397Sobrien 1457117395Skan if (TREE_PUBLIC (decl)) 1458117395Skan maybe_assemble_visibility (decl); 1459117395Skan 1460117395Skan /* Output any data that we will need to use the address of. */ 1461117395Skan if (DECL_INITIAL (decl) == error_mark_node) 1462117395Skan reloc = contains_pointers_p (TREE_TYPE (decl)) ? 3 : 0; 1463117395Skan else if (DECL_INITIAL (decl)) 1464132718Skan { 1465132718Skan reloc = compute_reloc_for_constant (DECL_INITIAL (decl)); 1466132718Skan output_addressed_constants (DECL_INITIAL (decl)); 1467132718Skan } 1468117395Skan resolve_unique_section (decl, reloc, flag_data_sections); 1469117395Skan 147018334Speter /* Handle uninitialized definitions. */ 147118334Speter 1472117395Skan /* If the decl has been given an explicit section name, then it 1473117395Skan isn't common, and shouldn't be handled as such. */ 1474117395Skan if (DECL_SECTION_NAME (decl) || dont_output_data) 1475117395Skan ; 1476117395Skan /* We don't implement common thread-local data at present. */ 1477117395Skan else if (DECL_THREAD_LOCAL (decl)) 147818334Speter { 1479117395Skan if (DECL_COMMON (decl)) 1480117395Skan sorry ("thread-local COMMON data not implemented"); 1481117395Skan } 1482117395Skan else if (DECL_INITIAL (decl) == 0 1483117395Skan || DECL_INITIAL (decl) == error_mark_node 1484117395Skan || (flag_zero_initialized_in_bss 1485117395Skan /* Leave constant zeroes in .rodata so they can be shared. */ 1486117395Skan && !TREE_READONLY (decl) 1487117395Skan && initializer_zerop (DECL_INITIAL (decl)))) 1488117395Skan { 148990075Sobrien unsigned HOST_WIDE_INT size = tree_low_cst (DECL_SIZE_UNIT (decl), 1); 149090075Sobrien unsigned HOST_WIDE_INT rounded = size; 149118334Speter 149218334Speter /* Don't allocate zero bytes of common, 149318334Speter since that means "undefined external" in the linker. */ 149490075Sobrien if (size == 0) 149590075Sobrien rounded = 1; 149690075Sobrien 149718334Speter /* Round size up to multiple of BIGGEST_ALIGNMENT bits 149818334Speter so that each uninitialized object starts on such a boundary. */ 149918334Speter rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1; 150018334Speter rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT) 150118334Speter * (BIGGEST_ALIGNMENT / BITS_PER_UNIT)); 150290075Sobrien 150390075Sobrien#if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_DECL_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS) 150490075Sobrien if ((unsigned HOST_WIDE_INT) DECL_ALIGN (decl) / BITS_PER_UNIT > rounded) 1505132718Skan warning ("%Jrequested alignment for '%D' is greater than " 1506132718Skan "implemented alignment of %d", decl, decl, rounded); 150750397Sobrien#endif 150818334Speter 1509117395Skan /* If the target cannot output uninitialized but not common global data 1510117395Skan in .bss, then we have to use .data, so fall through. */ 1511117395Skan if (asm_emit_uninitialised (decl, name, size, rounded)) 1512117395Skan return; 151318334Speter } 151418334Speter 151550397Sobrien /* Handle initialized definitions. 151650397Sobrien Also handle uninitialized global definitions if -fno-common and the 151750397Sobrien target doesn't support ASM_OUTPUT_BSS. */ 151818334Speter 151918334Speter /* First make the assembler name(s) global if appropriate. */ 152018334Speter if (TREE_PUBLIC (decl) && DECL_NAME (decl)) 152196263Sobrien globalize_decl (decl); 152218334Speter 152350397Sobrien /* Switch to the appropriate section. */ 152450397Sobrien variable_section (decl, reloc); 152550397Sobrien 152618334Speter /* dbxout.c needs to know this. */ 152718334Speter if (in_text_section ()) 152818334Speter DECL_IN_TEXT_SECTION (decl) = 1; 152918334Speter 153050397Sobrien /* Output the alignment of this data. */ 153118334Speter if (align > BITS_PER_UNIT) 153290075Sobrien { 153390075Sobrien ASM_OUTPUT_ALIGN (asm_out_file, 153490075Sobrien floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT)); 153590075Sobrien } 153618334Speter 153718334Speter /* Do any machine/system dependent processing of the object. */ 153818334Speter#ifdef ASM_DECLARE_OBJECT_NAME 153918334Speter last_assemble_variable_decl = decl; 154018334Speter ASM_DECLARE_OBJECT_NAME (asm_out_file, name, decl); 154118334Speter#else 154218334Speter /* Standard thing is just output label for the object. */ 154350397Sobrien ASM_OUTPUT_LABEL (asm_out_file, name); 154418334Speter#endif /* ASM_DECLARE_OBJECT_NAME */ 154518334Speter 154618334Speter if (!dont_output_data) 154718334Speter { 154896263Sobrien if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node) 154918334Speter /* Output the actual data. */ 155090075Sobrien output_constant (DECL_INITIAL (decl), 155190075Sobrien tree_low_cst (DECL_SIZE_UNIT (decl), 1), 155290075Sobrien align); 155318334Speter else 155418334Speter /* Leave space for it. */ 155590075Sobrien assemble_zeros (tree_low_cst (DECL_SIZE_UNIT (decl), 1)); 155618334Speter } 155718334Speter} 155818334Speter 155918334Speter/* Return 1 if type TYPE contains any pointers. */ 156018334Speter 156118334Speterstatic int 1562132718Skancontains_pointers_p (tree type) 156318334Speter{ 156418334Speter switch (TREE_CODE (type)) 156518334Speter { 156618334Speter case POINTER_TYPE: 156718334Speter case REFERENCE_TYPE: 156818334Speter /* I'm not sure whether OFFSET_TYPE needs this treatment, 156918334Speter so I'll play safe and return 1. */ 157018334Speter case OFFSET_TYPE: 157118334Speter return 1; 157218334Speter 157318334Speter case RECORD_TYPE: 157418334Speter case UNION_TYPE: 157518334Speter case QUAL_UNION_TYPE: 157618334Speter { 157718334Speter tree fields; 157818334Speter /* For a type that has fields, see if the fields have pointers. */ 157918334Speter for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) 158018334Speter if (TREE_CODE (fields) == FIELD_DECL 158118334Speter && contains_pointers_p (TREE_TYPE (fields))) 158218334Speter return 1; 158318334Speter return 0; 158418334Speter } 158518334Speter 158618334Speter case ARRAY_TYPE: 158718334Speter /* An array type contains pointers if its element type does. */ 158818334Speter return contains_pointers_p (TREE_TYPE (type)); 158918334Speter 159018334Speter default: 159118334Speter return 0; 159218334Speter } 159318334Speter} 159418334Speter 1595132718Skan#ifdef ASM_OUTPUT_EXTERNAL 1596132718Skan/* True if DECL is a function decl for which no out-of-line copy exists. 1597132718Skan It is assumed that DECL's assembler name has been set. */ 1598132718Skan 1599132718Skanstatic bool 1600132718Skanincorporeal_function_p (tree decl) 1601132718Skan{ 1602132718Skan if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl)) 1603132718Skan { 1604132718Skan const char *name; 1605132718Skan 1606132718Skan if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL 1607132718Skan && DECL_FUNCTION_CODE (decl) == BUILT_IN_ALLOCA) 1608132718Skan return true; 1609132718Skan 1610132718Skan name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 1611132718Skan if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0) 1612132718Skan return true; 1613132718Skan } 1614132718Skan return false; 1615132718Skan} 1616132718Skan#endif 1617132718Skan 161818334Speter/* Output something to declare an external symbol to the assembler. 161918334Speter (Most assemblers don't need this, so we normally output nothing.) 162018334Speter Do nothing if DECL is not external. */ 162118334Speter 162218334Spetervoid 1623132718Skanassemble_external (tree decl ATTRIBUTE_UNUSED) 162418334Speter{ 162590075Sobrien /* Because most platforms do not define ASM_OUTPUT_EXTERNAL, the 162690075Sobrien main body of this code is only rarely exercised. To provide some 162790075Sobrien testing, on all platforms, we make sure that the ASM_OUT_FILE is 162890075Sobrien open. If it's not, we should not be calling this function. */ 162990075Sobrien if (!asm_out_file) 163090075Sobrien abort (); 163190075Sobrien 163218334Speter#ifdef ASM_OUTPUT_EXTERNAL 163390075Sobrien if (DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)) 163418334Speter { 163518334Speter rtx rtl = DECL_RTL (decl); 163618334Speter 163718334Speter if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF 1638132718Skan && !SYMBOL_REF_USED (XEXP (rtl, 0)) 1639132718Skan && !incorporeal_function_p (decl)) 164018334Speter { 164118334Speter /* Some systems do require some output. */ 164218334Speter SYMBOL_REF_USED (XEXP (rtl, 0)) = 1; 164318334Speter ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0)); 164418334Speter } 164518334Speter } 164618334Speter#endif 164718334Speter} 164818334Speter 164918334Speter/* Similar, for calling a library function FUN. */ 165018334Speter 165118334Spetervoid 1652132718Skanassemble_external_libcall (rtx fun) 165318334Speter{ 165450397Sobrien /* Declare library function name external when first used, if nec. */ 165550397Sobrien if (! SYMBOL_REF_USED (fun)) 165618334Speter { 165750397Sobrien SYMBOL_REF_USED (fun) = 1; 1658132718Skan (*targetm.asm_out.external_libcall) (fun); 165918334Speter } 166018334Speter} 166118334Speter 166218334Speter/* Assemble a label named NAME. */ 166318334Speter 166418334Spetervoid 1665132718Skanassemble_label (const char *name) 166618334Speter{ 166750397Sobrien ASM_OUTPUT_LABEL (asm_out_file, name); 166818334Speter} 166918334Speter 1670132718Skan/* Set the symbol_referenced flag for ID and notify callgraph code. */ 1671132718Skanvoid 1672132718Skanmark_referenced (tree id) 1673132718Skan{ 1674132718Skan if (!TREE_SYMBOL_REFERENCED (id)) 1675132718Skan { 1676132718Skan struct cgraph_node *node; 1677132718Skan struct cgraph_varpool_node *vnode; 1678132718Skan 1679132718Skan if (!cgraph_global_info_ready) 1680132718Skan { 1681132718Skan node = cgraph_node_for_identifier (id); 1682132718Skan if (node) 1683132718Skan cgraph_mark_needed_node (node); 1684132718Skan } 1685132718Skan 1686132718Skan vnode = cgraph_varpool_node_for_identifier (id); 1687132718Skan if (vnode) 1688132718Skan cgraph_varpool_mark_needed_node (vnode); 1689132718Skan } 1690132718Skan TREE_SYMBOL_REFERENCED (id) = 1; 1691132718Skan} 1692132718Skan 169318334Speter/* Output to FILE a reference to the assembler name of a C-level name NAME. 169418334Speter If NAME starts with a *, the rest of NAME is output verbatim. 169518334Speter Otherwise NAME is transformed in an implementation-defined way 169618334Speter (usually by the addition of an underscore). 169718334Speter Many macros in the tm file are defined to call this function. */ 169818334Speter 169918334Spetervoid 1700132718Skanassemble_name (FILE *file, const char *name) 170118334Speter{ 170290075Sobrien const char *real_name; 170350397Sobrien tree id; 170418334Speter 1705117395Skan real_name = (* targetm.strip_name_encoding) (name); 170618334Speter 170750397Sobrien id = maybe_get_identifier (real_name); 170850397Sobrien if (id) 1709132718Skan mark_referenced (id); 171018334Speter 171118334Speter if (name[0] == '*') 171250397Sobrien fputs (&name[1], file); 171318334Speter else 171450397Sobrien ASM_OUTPUT_LABELREF (file, name); 171518334Speter} 171618334Speter 171718334Speter/* Allocate SIZE bytes writable static space with a gensym name 171818334Speter and return an RTX to refer to its address. */ 171918334Speter 172018334Speterrtx 1721132718Skanassemble_static_space (unsigned HOST_WIDE_INT size) 172218334Speter{ 172318334Speter char name[12]; 172490075Sobrien const char *namestring; 172518334Speter rtx x; 172618334Speter 172718334Speter#if 0 172818334Speter if (flag_shared_data) 172918334Speter data_section (); 173018334Speter#endif 173118334Speter 173218334Speter ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno); 173318334Speter ++const_labelno; 173490075Sobrien namestring = ggc_strdup (name); 173518334Speter 173650397Sobrien x = gen_rtx_SYMBOL_REF (Pmode, namestring); 1737132718Skan SYMBOL_REF_FLAGS (x) = SYMBOL_FLAG_LOCAL; 173818334Speter 173950397Sobrien#ifdef ASM_OUTPUT_ALIGNED_DECL_LOCAL 174050397Sobrien ASM_OUTPUT_ALIGNED_DECL_LOCAL (asm_out_file, NULL_TREE, name, size, 174150397Sobrien BIGGEST_ALIGNMENT); 174250397Sobrien#else 174318334Speter#ifdef ASM_OUTPUT_ALIGNED_LOCAL 174450397Sobrien ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, BIGGEST_ALIGNMENT); 174518334Speter#else 174650397Sobrien { 174750397Sobrien /* Round size up to multiple of BIGGEST_ALIGNMENT bits 174850397Sobrien so that each uninitialized object starts on such a boundary. */ 174990075Sobrien /* Variable `rounded' might or might not be used in ASM_OUTPUT_LOCAL. */ 1750132718Skan unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED 175152284Sobrien = ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1) 175252284Sobrien / (BIGGEST_ALIGNMENT / BITS_PER_UNIT) 175352284Sobrien * (BIGGEST_ALIGNMENT / BITS_PER_UNIT)); 175450397Sobrien ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded); 175550397Sobrien } 175618334Speter#endif 175750397Sobrien#endif 175818334Speter return x; 175918334Speter} 176018334Speter 176118334Speter/* Assemble the static constant template for function entry trampolines. 176218334Speter This is done at most once per compilation. 176318334Speter Returns an RTX for the address of the template. */ 176418334Speter 176548743Sobrien#ifdef TRAMPOLINE_TEMPLATE 176618334Speterrtx 1767132718Skanassemble_trampoline_template (void) 176818334Speter{ 176918334Speter char label[256]; 177090075Sobrien const char *name; 177118334Speter int align; 1772132718Skan rtx symbol; 177318334Speter 177418334Speter /* By default, put trampoline templates in read-only data section. */ 177518334Speter 177618334Speter#ifdef TRAMPOLINE_SECTION 177718334Speter TRAMPOLINE_SECTION (); 177818334Speter#else 177918334Speter readonly_data_section (); 178018334Speter#endif 178118334Speter 178218334Speter /* Write the assembler code to define one. */ 178350397Sobrien align = floor_log2 (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT); 178418334Speter if (align > 0) 178590075Sobrien { 178690075Sobrien ASM_OUTPUT_ALIGN (asm_out_file, align); 178790075Sobrien } 178818334Speter 1789132718Skan (*targetm.asm_out.internal_label) (asm_out_file, "LTRAMP", 0); 179018334Speter TRAMPOLINE_TEMPLATE (asm_out_file); 179118334Speter 179218334Speter /* Record the rtl to refer to it. */ 179318334Speter ASM_GENERATE_INTERNAL_LABEL (label, "LTRAMP", 0); 179490075Sobrien name = ggc_strdup (label); 1795132718Skan symbol = gen_rtx_SYMBOL_REF (Pmode, name); 1796132718Skan SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL; 1797132718Skan 1798132718Skan return symbol; 179918334Speter} 180048743Sobrien#endif 180118334Speter 180290075Sobrien/* A and B are either alignments or offsets. Return the minimum alignment 180390075Sobrien that may be assumed after adding the two together. */ 180418334Speter 180590075Sobrienstatic inline unsigned 1806132718Skanmin_align (unsigned int a, unsigned int b) 180790075Sobrien{ 180890075Sobrien return (a | b) & -(a | b); 180990075Sobrien} 181018334Speter 181190075Sobrien/* Return the assembler directive for creating a given kind of integer 181290075Sobrien object. SIZE is the number of bytes in the object and ALIGNED_P 181390075Sobrien indicates whether it is known to be aligned. Return NULL if the 181490075Sobrien assembly dialect has no such directive. 181590075Sobrien 181690075Sobrien The returned string should be printed at the start of a new line and 181790075Sobrien be followed immediately by the object's initial value. */ 181890075Sobrien 181990075Sobrienconst char * 1820132718Skaninteger_asm_op (int size, int aligned_p) 182118334Speter{ 182290075Sobrien struct asm_int_op *ops; 182318334Speter 182490075Sobrien if (aligned_p) 182590075Sobrien ops = &targetm.asm_out.aligned_op; 182690075Sobrien else 182790075Sobrien ops = &targetm.asm_out.unaligned_op; 182890075Sobrien 182918334Speter switch (size) 183018334Speter { 183118334Speter case 1: 183290075Sobrien return targetm.asm_out.byte_op; 183318334Speter case 2: 183490075Sobrien return ops->hi; 183518334Speter case 4: 183690075Sobrien return ops->si; 183718334Speter case 8: 183890075Sobrien return ops->di; 183918334Speter case 16: 184090075Sobrien return ops->ti; 184190075Sobrien default: 184290075Sobrien return NULL; 184318334Speter } 184490075Sobrien} 184518334Speter 184690075Sobrien/* Use directive OP to assemble an integer object X. Print OP at the 184790075Sobrien start of the line, followed immediately by the value of X. */ 184818334Speter 184990075Sobrienvoid 1850132718Skanassemble_integer_with_op (const char *op, rtx x) 185190075Sobrien{ 185290075Sobrien fputs (op, asm_out_file); 185390075Sobrien output_addr_const (asm_out_file, x); 185490075Sobrien fputc ('\n', asm_out_file); 185590075Sobrien} 185618334Speter 185790075Sobrien/* The default implementation of the asm_out.integer target hook. */ 185818334Speter 185990075Sobrienbool 1860132718Skandefault_assemble_integer (rtx x ATTRIBUTE_UNUSED, 1861132718Skan unsigned int size ATTRIBUTE_UNUSED, 1862132718Skan int aligned_p ATTRIBUTE_UNUSED) 186390075Sobrien{ 186490075Sobrien const char *op = integer_asm_op (size, aligned_p); 186590075Sobrien return op && (assemble_integer_with_op (op, x), true); 186690075Sobrien} 186790075Sobrien 186890075Sobrien/* Assemble the integer constant X into an object of SIZE bytes. ALIGN is 186990075Sobrien the alignment of the integer in bits. Return 1 if we were able to output 1870117395Skan the constant, otherwise 0. If FORCE is nonzero, abort if we can't output 187190075Sobrien the constant. */ 187290075Sobrien 187390075Sobrienbool 1874132718Skanassemble_integer (rtx x, unsigned int size, unsigned int align, int force) 187590075Sobrien{ 187690075Sobrien int aligned_p; 187790075Sobrien 187890075Sobrien aligned_p = (align >= MIN (size * BITS_PER_UNIT, BIGGEST_ALIGNMENT)); 187990075Sobrien 188090075Sobrien /* See if the target hook can handle this kind of object. */ 188190075Sobrien if ((*targetm.asm_out.integer) (x, size, aligned_p)) 188290075Sobrien return true; 188390075Sobrien 188490075Sobrien /* If the object is a multi-byte one, try splitting it up. Split 188590075Sobrien it into words it if is multi-word, otherwise split it into bytes. */ 188690075Sobrien if (size > 1) 188718334Speter { 188890075Sobrien enum machine_mode omode, imode; 188990075Sobrien unsigned int subalign; 189090075Sobrien unsigned int subsize, i; 189118334Speter 189290075Sobrien subsize = size > UNITS_PER_WORD? UNITS_PER_WORD : 1; 189390075Sobrien subalign = MIN (align, subsize * BITS_PER_UNIT); 189490075Sobrien omode = mode_for_size (subsize * BITS_PER_UNIT, MODE_INT, 0); 189590075Sobrien imode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0); 189690075Sobrien 189790075Sobrien for (i = 0; i < size; i += subsize) 189818334Speter { 189990075Sobrien rtx partial = simplify_subreg (omode, x, imode, i); 190090075Sobrien if (!partial || !assemble_integer (partial, subsize, subalign, 0)) 190118334Speter break; 190218334Speter } 190390075Sobrien if (i == size) 190490075Sobrien return true; 190518334Speter 190690075Sobrien /* If we've printed some of it, but not all of it, there's no going 190790075Sobrien back now. */ 190818334Speter if (i > 0) 190918334Speter abort (); 191018334Speter } 191118334Speter 191218334Speter if (force) 191318334Speter abort (); 191418334Speter 191590075Sobrien return false; 191618334Speter} 191718334Speter 191818334Spetervoid 1919132718Skanassemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align) 192018334Speter{ 192190075Sobrien long data[4]; 1922132718Skan int i; 1923132718Skan int bitsize, nelts, nunits, units_per; 192418334Speter 1925132718Skan /* This is hairy. We have a quantity of known size. real_to_target 1926132718Skan will put it into an array of *host* longs, 32 bits per element 1927132718Skan (even if long is more than 32 bits). We need to determine the 1928132718Skan number of array elements that are occupied (nelts) and the number 1929132718Skan of *target* min-addressable units that will be occupied in the 1930132718Skan object file (nunits). We cannot assume that 32 divides the 1931132718Skan mode's bitsize (size * BITS_PER_UNIT) evenly. 193218334Speter 1933132718Skan size * BITS_PER_UNIT is used here to make sure that padding bits 1934132718Skan (which might appear at either end of the value; real_to_target 1935132718Skan will include the padding bits in its output array) are included. */ 193618334Speter 1937132718Skan nunits = GET_MODE_SIZE (mode); 1938132718Skan bitsize = nunits * BITS_PER_UNIT; 1939132718Skan nelts = CEIL (bitsize, 32); 1940132718Skan units_per = 32 / BITS_PER_UNIT; 194118334Speter 1942132718Skan real_to_target (data, &d, mode); 1943132718Skan 1944132718Skan /* Put out the first word with the specified alignment. */ 1945132718Skan assemble_integer (GEN_INT (data[0]), MIN (nunits, units_per), align, 1); 1946132718Skan nunits -= units_per; 1947132718Skan 1948132718Skan /* Subsequent words need only 32-bit alignment. */ 1949132718Skan align = min_align (align, 32); 1950132718Skan 1951132718Skan for (i = 1; i < nelts; i++) 1952132718Skan { 1953132718Skan assemble_integer (GEN_INT (data[i]), MIN (nunits, units_per), align, 1); 1954132718Skan nunits -= units_per; 195518334Speter } 195618334Speter} 195718334Speter 195818334Speter/* Given an expression EXP with a constant value, 195918334Speter reduce it to the sum of an assembler symbol and an integer. 196018334Speter Store them both in the structure *VALUE. 196118334Speter Abort if EXP does not reduce. */ 196218334Speter 1963117395Skanstruct addr_const GTY(()) 196418334Speter{ 196518334Speter rtx base; 196618334Speter HOST_WIDE_INT offset; 196718334Speter}; 196818334Speter 196918334Speterstatic void 1970132718Skandecode_addr_const (tree exp, struct addr_const *value) 197118334Speter{ 197290075Sobrien tree target = TREE_OPERAND (exp, 0); 197390075Sobrien int offset = 0; 197490075Sobrien rtx x; 197518334Speter 197618334Speter while (1) 197718334Speter { 197818334Speter if (TREE_CODE (target) == COMPONENT_REF 197990075Sobrien && host_integerp (byte_position (TREE_OPERAND (target, 1)), 0)) 198090075Sobrien 198118334Speter { 198290075Sobrien offset += int_byte_position (TREE_OPERAND (target, 1)); 198318334Speter target = TREE_OPERAND (target, 0); 198418334Speter } 198590075Sobrien else if (TREE_CODE (target) == ARRAY_REF 198690075Sobrien || TREE_CODE (target) == ARRAY_RANGE_REF) 198718334Speter { 198890075Sobrien offset += (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (target)), 1) 198990075Sobrien * tree_low_cst (TREE_OPERAND (target, 1), 0)); 199018334Speter target = TREE_OPERAND (target, 0); 199118334Speter } 199218334Speter else 199318334Speter break; 199418334Speter } 199518334Speter 199618334Speter switch (TREE_CODE (target)) 199718334Speter { 199818334Speter case VAR_DECL: 199918334Speter case FUNCTION_DECL: 200018334Speter x = DECL_RTL (target); 200118334Speter break; 200218334Speter 200318334Speter case LABEL_DECL: 200450397Sobrien x = gen_rtx_MEM (FUNCTION_MODE, 2005132718Skan gen_rtx_LABEL_REF (VOIDmode, force_label_rtx (target))); 200618334Speter break; 200718334Speter 200818334Speter case REAL_CST: 200918334Speter case STRING_CST: 201018334Speter case COMPLEX_CST: 201118334Speter case CONSTRUCTOR: 201250397Sobrien case INTEGER_CST: 201390075Sobrien x = output_constant_def (target, 1); 201418334Speter break; 201518334Speter 201618334Speter default: 201718334Speter abort (); 201818334Speter } 201918334Speter 202050397Sobrien if (GET_CODE (x) != MEM) 202150397Sobrien abort (); 202250397Sobrien x = XEXP (x, 0); 202318334Speter 202418334Speter value->base = x; 202518334Speter value->offset = offset; 202618334Speter} 202718334Speter 202896263Sobrien/* We do RTX_UNSPEC + XINT (blah), so nothing can go after RTX_UNSPEC. */ 2029117395Skanenum kind { RTX_UNKNOWN, RTX_DOUBLE, RTX_VECTOR, RTX_INT, RTX_UNSPEC }; 2030117395Skanstruct rtx_const GTY(()) 203190075Sobrien{ 203290075Sobrien ENUM_BITFIELD(kind) kind : 16; 203390075Sobrien ENUM_BITFIELD(machine_mode) mode : 16; 2034117395Skan union rtx_const_un { 2035132718Skan REAL_VALUE_TYPE GTY ((tag ("4"))) du; 2036117395Skan struct rtx_const_u_addr { 2037117395Skan rtx base; 2038117395Skan const char *symbol; 2039117395Skan HOST_WIDE_INT offset; 2040117395Skan } GTY ((tag ("1"))) addr; 2041117395Skan struct rtx_const_u_di { 2042117395Skan HOST_WIDE_INT high; 2043117395Skan HOST_WIDE_INT low; 2044117395Skan } GTY ((tag ("0"))) di; 204596263Sobrien 2046117395Skan /* The max vector size we have is 16 wide; two variants for 2047117395Skan integral and floating point vectors. */ 2048117395Skan struct rtx_const_int_vec { 2049117395Skan HOST_WIDE_INT high; 2050117395Skan HOST_WIDE_INT low; 2051117395Skan } GTY ((tag ("2"))) int_vec[16]; 2052117395Skan 2053117395Skan REAL_VALUE_TYPE GTY ((tag ("3"))) fp_vec[8]; 2054117395Skan 2055117395Skan } GTY ((desc ("%1.kind >= RTX_INT"), descbits ("1"))) un; 205690075Sobrien}; 205790075Sobrien 205818334Speter/* Uniquize all constants that appear in memory. 205918334Speter Each constant in memory thus far output is recorded 2060132718Skan in `const_desc_table'. */ 206118334Speter 2062117395Skanstruct constant_descriptor_tree GTY(()) 2063117395Skan{ 2064117395Skan /* A MEM for the constant. */ 206590075Sobrien rtx rtl; 2066117395Skan 2067117395Skan /* The value of the constant. */ 2068117395Skan tree value; 206918334Speter}; 207018334Speter 2071132718Skanstatic GTY((param_is (struct constant_descriptor_tree))) 2072132718Skan htab_t const_desc_htab; 207318334Speter 2074132718Skanstatic struct constant_descriptor_tree * build_constant_desc (tree); 2075132718Skanstatic void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int); 207690075Sobrien 2077132718Skan/* Compute a hash code for a constant expression. */ 207890075Sobrien 207990075Sobrienstatic hashval_t 2080132718Skanconst_desc_hash (const void *ptr) 208190075Sobrien{ 2082132718Skan return const_hash_1 (((struct constant_descriptor_tree *)ptr)->value); 208390075Sobrien} 208490075Sobrien 2085132718Skanstatic hashval_t 2086132718Skanconst_hash_1 (const tree exp) 208790075Sobrien{ 208890075Sobrien const char *p; 2089132718Skan hashval_t hi; 2090117395Skan int len, i; 209190075Sobrien enum tree_code code = TREE_CODE (exp); 209218334Speter 209350397Sobrien /* Either set P and LEN to the address and len of something to hash and 209450397Sobrien exit the switch or return a value. */ 209550397Sobrien 209650397Sobrien switch (code) 209718334Speter { 209850397Sobrien case INTEGER_CST: 209990075Sobrien p = (char *) &TREE_INT_CST (exp); 210090075Sobrien len = sizeof TREE_INT_CST (exp); 210150397Sobrien break; 210250397Sobrien 210350397Sobrien case REAL_CST: 2104117395Skan return real_hash (TREE_REAL_CST_PTR (exp)); 210518334Speter 210650397Sobrien case STRING_CST: 2107132718Skan if (flag_writable_strings) 2108132718Skan { 2109132718Skan p = (char *) &exp; 2110132718Skan len = sizeof exp; 2111132718Skan } 2112132718Skan else 2113132718Skan { 2114132718Skan p = TREE_STRING_POINTER (exp); 2115132718Skan len = TREE_STRING_LENGTH (exp); 2116132718Skan } 211750397Sobrien break; 211818334Speter 211950397Sobrien case COMPLEX_CST: 2120117395Skan return (const_hash_1 (TREE_REALPART (exp)) * 5 2121117395Skan + const_hash_1 (TREE_IMAGPART (exp))); 212218334Speter 212350397Sobrien case CONSTRUCTOR: 212450397Sobrien if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE) 212518334Speter { 212690075Sobrien char *tmp; 212790075Sobrien 212850397Sobrien len = int_size_in_bytes (TREE_TYPE (exp)); 2129132718Skan tmp = alloca (len); 213090075Sobrien get_set_constructor_bytes (exp, (unsigned char *) tmp, len); 213190075Sobrien p = tmp; 213250397Sobrien break; 213318334Speter } 213450397Sobrien else 213550397Sobrien { 213690075Sobrien tree link; 213718334Speter 2138117395Skan hi = 5 + int_size_in_bytes (TREE_TYPE (exp)); 213950397Sobrien 214050397Sobrien for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link)) 214150397Sobrien if (TREE_VALUE (link)) 2142117395Skan hi = hi * 603 + const_hash_1 (TREE_VALUE (link)); 214350397Sobrien 214450397Sobrien return hi; 214550397Sobrien } 214650397Sobrien 214750397Sobrien case ADDR_EXPR: 2148102780Skan case FDESC_EXPR: 214950397Sobrien { 215050397Sobrien struct addr_const value; 215150397Sobrien 215250397Sobrien decode_addr_const (exp, &value); 215350397Sobrien if (GET_CODE (value.base) == SYMBOL_REF) 215450397Sobrien { 215550397Sobrien /* Don't hash the address of the SYMBOL_REF; 215650397Sobrien only use the offset and the symbol name. */ 215750397Sobrien hi = value.offset; 215850397Sobrien p = XSTR (value.base, 0); 215950397Sobrien for (i = 0; p[i] != 0; i++) 216050397Sobrien hi = ((hi * 613) + (unsigned) (p[i])); 216150397Sobrien } 216250397Sobrien else if (GET_CODE (value.base) == LABEL_REF) 216350397Sobrien hi = value.offset + CODE_LABEL_NUMBER (XEXP (value.base, 0)) * 13; 216490075Sobrien else 216590075Sobrien abort (); 216650397Sobrien } 216718334Speter return hi; 216850397Sobrien 216950397Sobrien case PLUS_EXPR: 217050397Sobrien case MINUS_EXPR: 2171117395Skan return (const_hash_1 (TREE_OPERAND (exp, 0)) * 9 2172117395Skan + const_hash_1 (TREE_OPERAND (exp, 1))); 217350397Sobrien 217450397Sobrien case NOP_EXPR: 217550397Sobrien case CONVERT_EXPR: 217650397Sobrien case NON_LVALUE_EXPR: 2177117395Skan return const_hash_1 (TREE_OPERAND (exp, 0)) * 7 + 2; 217890075Sobrien 217950397Sobrien default: 218090075Sobrien /* A language specific constant. Just hash the code. */ 2181117395Skan return code; 218218334Speter } 218318334Speter 2184132718Skan /* Compute hashing function. */ 218518334Speter hi = len; 218618334Speter for (i = 0; i < len; i++) 218750397Sobrien hi = ((hi * 613) + (unsigned) (p[i])); 218818334Speter 218918334Speter return hi; 219018334Speter} 219118334Speter 2192132718Skan/* Wrapper of compare_constant, for the htab interface. */ 2193132718Skanstatic int 2194132718Skanconst_desc_eq (const void *p1, const void *p2) 2195132718Skan{ 2196132718Skan return compare_constant (((struct constant_descriptor_tree *)p1)->value, 2197132718Skan ((struct constant_descriptor_tree *)p2)->value); 2198132718Skan} 2199132718Skan 2200117395Skan/* Compare t1 and t2, and return 1 only if they are known to result in 2201117395Skan the same bit pattern on output. */ 2202117395Skan 220318334Speterstatic int 2204132718Skancompare_constant (const tree t1, const tree t2) 220518334Speter{ 2206117395Skan enum tree_code typecode; 220718334Speter 2208117395Skan if (t1 == NULL_TREE) 2209117395Skan return t2 == NULL_TREE; 2210117395Skan if (t2 == NULL_TREE) 2211117395Skan return 0; 221218334Speter 2213117395Skan if (TREE_CODE (t1) != TREE_CODE (t2)) 221418334Speter return 0; 221518334Speter 2216117395Skan switch (TREE_CODE (t1)) 221718334Speter { 221850397Sobrien case INTEGER_CST: 221918334Speter /* Integer constants are the same only if the same width of type. */ 2220117395Skan if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2))) 222118334Speter return 0; 2222117395Skan return tree_int_cst_equal (t1, t2); 222350397Sobrien 222450397Sobrien case REAL_CST: 222518334Speter /* Real constants are the same only if the same width of type. */ 2226117395Skan if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2))) 222718334Speter return 0; 222850397Sobrien 2229117395Skan return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2)); 223050397Sobrien 223150397Sobrien case STRING_CST: 223218334Speter if (flag_writable_strings) 2233132718Skan return t1 == t2; 223450397Sobrien 2235117395Skan if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))) 223650397Sobrien return 0; 223750397Sobrien 2238117395Skan return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2) 2239117395Skan && ! memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2), 2240117395Skan TREE_STRING_LENGTH (t1))); 224150397Sobrien 2242117395Skan case COMPLEX_CST: 2243117395Skan return (compare_constant (TREE_REALPART (t1), TREE_REALPART (t2)) 2244117395Skan && compare_constant (TREE_IMAGPART (t1), TREE_IMAGPART (t2))); 224550397Sobrien 2246117395Skan case CONSTRUCTOR: 2247117395Skan typecode = TREE_CODE (TREE_TYPE (t1)); 2248117395Skan if (typecode != TREE_CODE (TREE_TYPE (t2))) 224918334Speter return 0; 225018334Speter 2251117395Skan if (typecode == SET_TYPE) 225218334Speter { 2253117395Skan int len = int_size_in_bytes (TREE_TYPE (t2)); 2254117395Skan unsigned char *tmp1, *tmp2; 225550397Sobrien 2256117395Skan if (int_size_in_bytes (TREE_TYPE (t1)) != len) 225718334Speter return 0; 225850397Sobrien 2259132718Skan tmp1 = alloca (len); 2260132718Skan tmp2 = alloca (len); 2261117395Skan 2262117395Skan if (get_set_constructor_bytes (t1, tmp1, len) != NULL_TREE) 2263117395Skan return 0; 2264117395Skan if (get_set_constructor_bytes (t2, tmp2, len) != NULL_TREE) 2265117395Skan return 0; 2266117395Skan 2267122180Skan return memcmp (tmp1, tmp2, len) == 0; 226818334Speter } 226950397Sobrien else 227050397Sobrien { 2271117395Skan tree l1, l2; 227218334Speter 2273117395Skan if (typecode == ARRAY_TYPE) 227490075Sobrien { 2275117395Skan HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1)); 2276117395Skan /* For arrays, check that the sizes all match. */ 2277117395Skan if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)) 2278117395Skan || size_1 == -1 2279117395Skan || size_1 != int_size_in_bytes (TREE_TYPE (t2))) 228090075Sobrien return 0; 228190075Sobrien } 2282117395Skan else 228318334Speter { 2284117395Skan /* For record and union constructors, require exact type 2285117395Skan equality. */ 2286117395Skan if (TREE_TYPE (t1) != TREE_TYPE (t2)) 228718334Speter return 0; 228818334Speter } 228950397Sobrien 2290117395Skan for (l1 = CONSTRUCTOR_ELTS (t1), l2 = CONSTRUCTOR_ELTS (t2); 2291117395Skan l1 && l2; 2292117395Skan l1 = TREE_CHAIN (l1), l2 = TREE_CHAIN (l2)) 229318334Speter { 2294117395Skan /* Check that each value is the same... */ 2295117395Skan if (! compare_constant (TREE_VALUE (l1), TREE_VALUE (l2))) 2296117395Skan return 0; 2297117395Skan /* ... and that they apply to the same fields! */ 2298117395Skan if (typecode == ARRAY_TYPE) 229950397Sobrien { 2300117395Skan if (! compare_constant (TREE_PURPOSE (l1), 2301117395Skan TREE_PURPOSE (l2))) 230250397Sobrien return 0; 230350397Sobrien } 230450397Sobrien else 230550397Sobrien { 2306117395Skan if (TREE_PURPOSE (l1) != TREE_PURPOSE (l2)) 230750397Sobrien return 0; 230850397Sobrien } 230918334Speter } 231050397Sobrien 2311117395Skan return l1 == NULL_TREE && l2 == NULL_TREE; 231218334Speter } 231318334Speter 231450397Sobrien case ADDR_EXPR: 2315102780Skan case FDESC_EXPR: 231650397Sobrien { 2317117395Skan struct addr_const value1, value2; 231850397Sobrien 2319117395Skan decode_addr_const (t1, &value1); 2320117395Skan decode_addr_const (t2, &value2); 2321117395Skan return (value1.offset == value2.offset 2322117395Skan && strcmp (XSTR (value1.base, 0), XSTR (value2.base, 0)) == 0); 232350397Sobrien } 232450397Sobrien 232550397Sobrien case PLUS_EXPR: 232650397Sobrien case MINUS_EXPR: 232752284Sobrien case RANGE_EXPR: 2328117395Skan return (compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)) 2329117395Skan && compare_constant(TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1))); 233050397Sobrien 233150397Sobrien case NOP_EXPR: 233250397Sobrien case CONVERT_EXPR: 233350397Sobrien case NON_LVALUE_EXPR: 2334117395Skan return compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); 233550397Sobrien 233650397Sobrien default: 233790075Sobrien { 2338117395Skan tree nt1, nt2; 2339117395Skan nt1 = (*lang_hooks.expand_constant) (t1); 2340117395Skan nt2 = (*lang_hooks.expand_constant) (t2); 2341117395Skan if (nt1 != t1 || nt2 != t2) 2342117395Skan return compare_constant (nt1, nt2); 234390075Sobrien else 234490075Sobrien return 0; 234590075Sobrien } 234618334Speter } 234718334Speter 2348117395Skan /* Should not get here. */ 2349117395Skan abort (); 235018334Speter} 235118334Speter 2352117395Skan/* Make a copy of the whole tree structure for a constant. This 2353117395Skan handles the same types of nodes that compare_constant handles. */ 235418334Speter 235518334Speterstatic tree 2356132718Skancopy_constant (tree exp) 235718334Speter{ 235818334Speter switch (TREE_CODE (exp)) 235918334Speter { 236018334Speter case ADDR_EXPR: 236118334Speter /* For ADDR_EXPR, we do not want to copy the decl whose address 236218334Speter is requested. We do want to copy constants though. */ 236318334Speter if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == 'c') 236418334Speter return build1 (TREE_CODE (exp), TREE_TYPE (exp), 236518334Speter copy_constant (TREE_OPERAND (exp, 0))); 236618334Speter else 236718334Speter return copy_node (exp); 236818334Speter 236918334Speter case INTEGER_CST: 237018334Speter case REAL_CST: 237118334Speter case STRING_CST: 237218334Speter return copy_node (exp); 237318334Speter 237418334Speter case COMPLEX_CST: 237550397Sobrien return build_complex (TREE_TYPE (exp), 237650397Sobrien copy_constant (TREE_REALPART (exp)), 237718334Speter copy_constant (TREE_IMAGPART (exp))); 237818334Speter 237918334Speter case PLUS_EXPR: 238018334Speter case MINUS_EXPR: 238118334Speter return build (TREE_CODE (exp), TREE_TYPE (exp), 238218334Speter copy_constant (TREE_OPERAND (exp, 0)), 238318334Speter copy_constant (TREE_OPERAND (exp, 1))); 238418334Speter 238518334Speter case NOP_EXPR: 238618334Speter case CONVERT_EXPR: 238750397Sobrien case NON_LVALUE_EXPR: 2388132718Skan case VIEW_CONVERT_EXPR: 238918334Speter return build1 (TREE_CODE (exp), TREE_TYPE (exp), 239018334Speter copy_constant (TREE_OPERAND (exp, 0))); 239118334Speter 239218334Speter case CONSTRUCTOR: 239318334Speter { 239418334Speter tree copy = copy_node (exp); 239518334Speter tree list = copy_list (CONSTRUCTOR_ELTS (exp)); 239618334Speter tree tail; 239718334Speter 239818334Speter CONSTRUCTOR_ELTS (copy) = list; 239918334Speter for (tail = list; tail; tail = TREE_CHAIN (tail)) 240018334Speter TREE_VALUE (tail) = copy_constant (TREE_VALUE (tail)); 240118334Speter if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE) 240218334Speter for (tail = list; tail; tail = TREE_CHAIN (tail)) 240318334Speter TREE_PURPOSE (tail) = copy_constant (TREE_PURPOSE (tail)); 240418334Speter 240518334Speter return copy; 240618334Speter } 240718334Speter 240818334Speter default: 2409117395Skan { 2410117395Skan tree t; 2411117395Skan t = (*lang_hooks.expand_constant) (exp); 2412117395Skan if (t != exp) 2413117395Skan return copy_constant (t); 2414117395Skan else 2415117395Skan abort (); 2416117395Skan } 241718334Speter } 241818334Speter} 241918334Speter 2420132718Skan/* Subroutine of output_constant_def: 2421132718Skan No constant equal to EXP is known to have been output. 2422132718Skan Make a constant descriptor to enter EXP in the hash table. 2423132718Skan Assign the label number and construct RTL to refer to the 2424132718Skan constant's location in memory. 2425132718Skan Caller is responsible for updating the hash table. */ 242618334Speter 2427132718Skanstatic struct constant_descriptor_tree * 2428132718Skanbuild_constant_desc (tree exp) 242918334Speter{ 2430132718Skan rtx symbol; 2431132718Skan rtx rtl; 2432132718Skan char label[256]; 2433132718Skan int labelno; 2434117395Skan struct constant_descriptor_tree *desc; 243518334Speter 2436132718Skan desc = ggc_alloc (sizeof (*desc)); 2437132718Skan if (flag_writable_strings && TREE_CODE (exp) == STRING_CST) 2438132718Skan desc->value = exp; 2439132718Skan else 2440132718Skan desc->value = copy_constant (exp); 2441122180Skan 2442132718Skan /* Create a string containing the label name, in LABEL. */ 2443132718Skan labelno = const_labelno++; 2444132718Skan ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno); 244518334Speter 2446132718Skan /* We have a symbol name; construct the SYMBOL_REF and the MEM. */ 2447132718Skan symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label)); 2448132718Skan SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL; 2449132718Skan SYMBOL_REF_DECL (symbol) = desc->value; 2450132718Skan TREE_CONSTANT_POOL_ADDRESS_P (symbol) = 1; 245118334Speter 2452132718Skan rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), symbol); 2453132718Skan set_mem_attributes (rtl, exp, 1); 2454132718Skan set_mem_alias_set (rtl, 0); 2455132718Skan set_mem_alias_set (rtl, const_alias_set); 245618334Speter 2457132718Skan /* Set flags or add text to the name to record information, such as 2458132718Skan that it is a local symbol. If the name is changed, the macro 2459132718Skan ASM_OUTPUT_LABELREF will have to know how to strip this 2460132718Skan information. This call might invalidate our local variable 2461132718Skan SYMBOL; we can't use it afterward. */ 246218334Speter 2463132718Skan (*targetm.encode_section_info) (exp, rtl, true); 246490075Sobrien 2465132718Skan desc->rtl = rtl; 246690075Sobrien 2467132718Skan return desc; 2468132718Skan} 246990075Sobrien 2470132718Skan/* Return an rtx representing a reference to constant data in memory 2471132718Skan for the constant expression EXP. 247218334Speter 2473132718Skan If assembler code for such a constant has already been output, 2474132718Skan return an rtx to refer to it. 2475132718Skan Otherwise, output such a constant in memory 2476132718Skan and generate an rtx for it. 247790075Sobrien 2478132718Skan If DEFER is nonzero, this constant can be deferred and output only 2479132718Skan if referenced in the function after all optimizations. 248090075Sobrien 2481132718Skan `const_desc_table' records which constants already have label strings. */ 248290075Sobrien 2483132718Skanrtx 2484132718Skanoutput_constant_def (tree exp, int defer) 2485132718Skan{ 2486132718Skan struct constant_descriptor_tree *desc; 2487132718Skan struct constant_descriptor_tree key; 2488132718Skan void **loc; 248918334Speter 2490132718Skan /* Look up EXP in the table of constant descriptors. If we didn't find 2491132718Skan it, create a new one. */ 2492132718Skan key.value = exp; 2493132718Skan loc = htab_find_slot (const_desc_htab, &key, INSERT); 249418334Speter 2495132718Skan desc = *loc; 2496132718Skan if (desc == 0) 249790075Sobrien { 2498132718Skan desc = build_constant_desc (exp); 2499132718Skan *loc = desc; 250090075Sobrien } 250118334Speter 2502132718Skan maybe_output_constant_def_contents (desc, defer); 2503132718Skan return desc->rtl; 2504132718Skan} 250590075Sobrien 2506132718Skan/* Subroutine of output_constant_def: Decide whether or not we need to 2507132718Skan output the constant DESC now, and if so, do it. */ 2508132718Skanstatic void 2509132718Skanmaybe_output_constant_def_contents (struct constant_descriptor_tree *desc, 2510132718Skan int defer) 2511132718Skan{ 2512132718Skan rtx symbol = XEXP (desc->rtl, 0); 2513132718Skan tree exp = desc->value; 251490075Sobrien 2515132718Skan if (flag_syntax_only) 2516132718Skan return; 251718334Speter 2518132718Skan if (TREE_ASM_WRITTEN (exp)) 2519132718Skan /* Already output; don't do it again. */ 2520132718Skan return; 252190075Sobrien 2522132718Skan /* The only constants that cannot safely be deferred, assuming the 2523132718Skan context allows it, are strings under flag_writable_strings. */ 2524132718Skan if (defer && (TREE_CODE (exp) != STRING_CST || !flag_writable_strings)) 2525132718Skan { 2526132718Skan /* Increment n_deferred_constants if it exists. It needs to be at 2527132718Skan least as large as the number of constants actually referred to 2528132718Skan by the function. If it's too small we'll stop looking too early 2529132718Skan and fail to emit constants; if it's too large we'll only look 2530132718Skan through the entire function when we could have stopped earlier. */ 2531132718Skan if (cfun) 2532132718Skan n_deferred_constants++; 2533132718Skan return; 253418334Speter } 253518334Speter 2536132718Skan output_constant_def_contents (symbol); 253718334Speter} 253818334Speter 2539132718Skan/* We must output the constant data referred to by SYMBOL; do so. */ 254018334Speter 254118334Speterstatic void 2542132718Skanoutput_constant_def_contents (rtx symbol) 254318334Speter{ 2544132718Skan tree exp = SYMBOL_REF_DECL (symbol); 2545132718Skan const char *label = XSTR (symbol, 0); 2546122180Skan HOST_WIDE_INT size; 254718334Speter 2548132718Skan /* Make sure any other constants whose addresses appear in EXP 2549132718Skan are assigned label numbers. */ 2550132718Skan int reloc = compute_reloc_for_constant (exp); 2551132718Skan 255290075Sobrien /* Align the location counter as required by EXP's data type. */ 2553132718Skan int align = TYPE_ALIGN (TREE_TYPE (exp)); 255490075Sobrien#ifdef CONSTANT_ALIGNMENT 255590075Sobrien align = CONSTANT_ALIGNMENT (exp, align); 255690075Sobrien#endif 255790075Sobrien 2558132718Skan output_addressed_constants (exp); 2559132718Skan 2560132718Skan /* We are no longer deferring this constant. */ 2561132718Skan TREE_ASM_WRITTEN (exp) = 1; 2562132718Skan 256318334Speter if (IN_NAMED_SECTION (exp)) 256450397Sobrien named_section (exp, NULL, reloc); 256518334Speter else 2566117395Skan (*targetm.asm_out.select_section) (exp, reloc, align); 256718334Speter 256818334Speter if (align > BITS_PER_UNIT) 256990075Sobrien { 257090075Sobrien ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT)); 257190075Sobrien } 257218334Speter 2573122180Skan size = int_size_in_bytes (TREE_TYPE (exp)); 2574122180Skan if (TREE_CODE (exp) == STRING_CST) 2575122180Skan size = MAX (TREE_STRING_LENGTH (exp), size); 2576122180Skan 2577122180Skan /* Do any machine/system dependent processing of the constant. */ 2578122180Skan#ifdef ASM_DECLARE_CONSTANT_NAME 2579132718Skan ASM_DECLARE_CONSTANT_NAME (asm_out_file, label, exp, size); 2580122180Skan#else 2581122180Skan /* Standard thing is just output label for the constant. */ 2582132718Skan ASM_OUTPUT_LABEL (asm_out_file, label); 2583122180Skan#endif /* ASM_DECLARE_CONSTANT_NAME */ 258418334Speter 258518334Speter /* Output the value of EXP. */ 2586122180Skan output_constant (exp, size, align); 258718334Speter} 2588132718Skan 2589132718Skan/* A constant which was deferred in its original location has been 2590132718Skan inserted by the RTL inliner into a different function. The 2591132718Skan current function's deferred constant count must be incremented. */ 2592132718Skanvoid 2593132718Skannotice_rtl_inlining_of_deferred_constant (void) 2594132718Skan{ 2595132718Skan n_deferred_constants++; 2596132718Skan} 2597132718Skan 2598132718Skan/* Look up EXP in the table of constant descriptors. Return the rtl 2599132718Skan if it has been emitted, else null. */ 2600132718Skan 2601132718Skanrtx 2602132718Skanlookup_constant_def (tree exp) 2603132718Skan{ 2604132718Skan struct constant_descriptor_tree *desc; 2605132718Skan struct constant_descriptor_tree key; 2606132718Skan 2607132718Skan key.value = exp; 2608132718Skan desc = htab_find (const_desc_htab, &key); 2609132718Skan 2610132718Skan return (desc ? desc->rtl : NULL_RTX); 2611132718Skan} 261218334Speter 2613117395Skan/* Used in the hash tables to avoid outputting the same constant 2614117395Skan twice. Unlike 'struct constant_descriptor_tree', RTX constants 2615117395Skan are output once per function, not once per file; there seems 2616117395Skan to be no reason for the difference. */ 2617117395Skan 2618117395Skanstruct constant_descriptor_rtx GTY(()) 2619117395Skan{ 2620117395Skan /* More constant_descriptors with the same hash code. */ 2621117395Skan struct constant_descriptor_rtx *next; 2622117395Skan 2623117395Skan /* A MEM for the constant. */ 2624117395Skan rtx rtl; 2625117395Skan 2626117395Skan /* The value of the constant. */ 2627117395Skan struct rtx_const value; 2628117395Skan}; 2629117395Skan 263018334Speter/* Structure to represent sufficient information about a constant so that 263118334Speter it can be output when the constant pool is output, so that function 263218334Speter integration can be done, and to simplify handling on machines that reference 263318334Speter constant pool as base+displacement. */ 263418334Speter 2635117395Skanstruct pool_constant GTY(()) 263618334Speter{ 2637117395Skan struct constant_descriptor_rtx *desc; 2638117395Skan struct pool_constant *next; 2639117395Skan struct pool_constant *next_sym; 264090075Sobrien rtx constant; 264118334Speter enum machine_mode mode; 264218334Speter int labelno; 264390075Sobrien unsigned int align; 264490075Sobrien HOST_WIDE_INT offset; 264550397Sobrien int mark; 264618334Speter}; 264718334Speter 264818334Speter/* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true. 264918334Speter The argument is XSTR (... , 0) */ 265018334Speter 2651117395Skan#define SYMHASH(LABEL) (((unsigned long) (LABEL)) % MAX_RTX_HASH_TABLE) 265218334Speter 265390075Sobrien/* Initialize constant pool hashing for a new function. */ 265418334Speter 265518334Spetervoid 2656132718Skaninit_varasm_status (struct function *f) 265718334Speter{ 265890075Sobrien struct varasm_status *p; 2659132718Skan p = ggc_alloc (sizeof (struct varasm_status)); 266090075Sobrien f->varasm = p; 266190075Sobrien p->x_const_rtx_hash_table 2662132718Skan = ggc_alloc_cleared (MAX_RTX_HASH_TABLE 2663132718Skan * sizeof (struct constant_descriptor_rtx *)); 266490075Sobrien p->x_const_rtx_sym_hash_table 2665132718Skan = ggc_alloc_cleared (MAX_RTX_HASH_TABLE 2666132718Skan * sizeof (struct pool_constant *)); 266718334Speter 266890075Sobrien p->x_first_pool = p->x_last_pool = 0; 266990075Sobrien p->x_pool_offset = 0; 2670132718Skan p->deferred_constants = 0; 267118334Speter} 267218334Speter 267318334Speter 267418334Speter/* Express an rtx for a constant integer (perhaps symbolic) 267518334Speter as the sum of a symbol or label plus an explicit integer. 267618334Speter They are stored into VALUE. */ 267718334Speter 267818334Speterstatic void 2679132718Skandecode_rtx_const (enum machine_mode mode, rtx x, struct rtx_const *value) 268018334Speter{ 268118334Speter /* Clear the whole structure, including any gaps. */ 268290075Sobrien memset (value, 0, sizeof (struct rtx_const)); 268318334Speter 268450397Sobrien value->kind = RTX_INT; /* Most usual kind. */ 268518334Speter value->mode = mode; 268618334Speter 268718334Speter switch (GET_CODE (x)) 268818334Speter { 268918334Speter case CONST_DOUBLE: 269018334Speter value->kind = RTX_DOUBLE; 269118334Speter if (GET_MODE (x) != VOIDmode) 269218334Speter { 2693117395Skan const REAL_VALUE_TYPE *r = CONST_DOUBLE_REAL_VALUE (x); 2694117395Skan 269518334Speter value->mode = GET_MODE (x); 2696117395Skan 2697117395Skan /* Copy the REAL_VALUE_TYPE by members so that we don't 2698117395Skan copy garbage from the original structure into our 2699117395Skan carefully cleaned hashing structure. */ 2700117395Skan value->un.du.class = r->class; 2701117395Skan value->un.du.sign = r->sign; 2702117395Skan switch (r->class) 2703117395Skan { 2704117395Skan case rvc_zero: 2705117395Skan case rvc_inf: 2706117395Skan break; 2707117395Skan case rvc_normal: 2708117395Skan value->un.du.exp = r->exp; 2709132718Skan /* Fall through. */ 2710117395Skan case rvc_nan: 2711117395Skan memcpy (value->un.du.sig, r->sig, sizeof (r->sig)); 2712117395Skan break; 2713117395Skan default: 2714117395Skan abort (); 2715117395Skan } 271618334Speter } 271718334Speter else 271818334Speter { 271918334Speter value->un.di.low = CONST_DOUBLE_LOW (x); 272018334Speter value->un.di.high = CONST_DOUBLE_HIGH (x); 272118334Speter } 272218334Speter break; 272318334Speter 272496263Sobrien case CONST_VECTOR: 272596263Sobrien { 272696263Sobrien int units, i; 272796263Sobrien 272896263Sobrien units = CONST_VECTOR_NUNITS (x); 272996263Sobrien value->kind = RTX_VECTOR; 273096263Sobrien value->mode = mode; 273196263Sobrien 2732117395Skan if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) 273396263Sobrien { 2734117395Skan for (i = 0; i < units; ++i) 273596263Sobrien { 2736117395Skan rtx elt = CONST_VECTOR_ELT (x, i); 2737117395Skan if (GET_CODE (elt) == CONST_INT) 2738117395Skan { 2739117395Skan value->un.int_vec[i].low = INTVAL (elt); 2740117395Skan value->un.int_vec[i].high = 0; 2741117395Skan } 2742117395Skan else 2743117395Skan { 2744117395Skan value->un.int_vec[i].low = CONST_DOUBLE_LOW (elt); 2745117395Skan value->un.int_vec[i].high = CONST_DOUBLE_HIGH (elt); 2746117395Skan } 274796263Sobrien } 2748117395Skan } 2749117395Skan else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) 2750117395Skan { 2751117395Skan for (i = 0; i < units; ++i) 275296263Sobrien { 2753117395Skan const REAL_VALUE_TYPE *r 2754117395Skan = CONST_DOUBLE_REAL_VALUE (CONST_VECTOR_ELT (x, i)); 2755117395Skan REAL_VALUE_TYPE *d = &value->un.fp_vec[i]; 2756117395Skan 2757117395Skan /* Copy the REAL_VALUE_TYPE by members so that we don't 2758117395Skan copy garbage from the original structure into our 2759117395Skan carefully cleaned hashing structure. */ 2760117395Skan d->class = r->class; 2761117395Skan d->sign = r->sign; 2762117395Skan switch (r->class) 2763117395Skan { 2764117395Skan case rvc_zero: 2765117395Skan case rvc_inf: 2766117395Skan break; 2767117395Skan case rvc_normal: 2768117395Skan d->exp = r->exp; 2769132718Skan /* Fall through. */ 2770117395Skan case rvc_nan: 2771117395Skan memcpy (d->sig, r->sig, sizeof (r->sig)); 2772117395Skan break; 2773117395Skan default: 2774117395Skan abort (); 2775117395Skan } 277696263Sobrien } 277796263Sobrien } 2778117395Skan else 2779117395Skan abort (); 278096263Sobrien } 278196263Sobrien break; 278296263Sobrien 278318334Speter case CONST_INT: 278418334Speter value->un.addr.offset = INTVAL (x); 278518334Speter break; 278618334Speter 278718334Speter case SYMBOL_REF: 278818334Speter case LABEL_REF: 278918334Speter case PC: 279018334Speter value->un.addr.base = x; 279118334Speter break; 279218334Speter 279318334Speter case CONST: 279418334Speter x = XEXP (x, 0); 279590075Sobrien if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT) 279618334Speter { 279718334Speter value->un.addr.base = XEXP (x, 0); 279818334Speter value->un.addr.offset = INTVAL (XEXP (x, 1)); 279918334Speter } 280090075Sobrien else if (GET_CODE (x) == MINUS && GET_CODE (XEXP (x, 1)) == CONST_INT) 280118334Speter { 280218334Speter value->un.addr.base = XEXP (x, 0); 280318334Speter value->un.addr.offset = - INTVAL (XEXP (x, 1)); 280418334Speter } 280518334Speter else 280690075Sobrien { 280790075Sobrien value->un.addr.base = x; 280890075Sobrien value->un.addr.offset = 0; 280990075Sobrien } 281018334Speter break; 281118334Speter 281218334Speter default: 281396263Sobrien value->kind = RTX_UNKNOWN; 281496263Sobrien break; 281518334Speter } 281618334Speter 281796263Sobrien if (value->kind == RTX_INT && value->un.addr.base != 0 281896263Sobrien && GET_CODE (value->un.addr.base) == UNSPEC) 2819117395Skan { 282096263Sobrien /* For a simple UNSPEC, the base is set to the 282196263Sobrien operand, the kind field is set to the index of 2822117395Skan the unspec expression. 282396263Sobrien Together with the code below, in case that 2824117395Skan the operand is a SYMBOL_REF or LABEL_REF, 2825117395Skan the address of the string or the code_label 282696263Sobrien is taken as base. */ 282796263Sobrien if (XVECLEN (value->un.addr.base, 0) == 1) 2828117395Skan { 282996263Sobrien value->kind = RTX_UNSPEC + XINT (value->un.addr.base, 1); 283096263Sobrien value->un.addr.base = XVECEXP (value->un.addr.base, 0, 0); 283196263Sobrien } 283296263Sobrien } 283396263Sobrien 2834117395Skan if (value->kind >= RTX_INT && value->un.addr.base != 0) 283518334Speter switch (GET_CODE (value->un.addr.base)) 283618334Speter { 283718334Speter case SYMBOL_REF: 283890075Sobrien /* Use the string's address, not the SYMBOL_REF's address, 283990075Sobrien for the sake of addresses of library routines. */ 2840117395Skan value->un.addr.symbol = XSTR (value->un.addr.base, 0); 2841117395Skan value->un.addr.base = NULL_RTX; 284290075Sobrien break; 284390075Sobrien 284418334Speter case LABEL_REF: 284590075Sobrien /* For a LABEL_REF, compare labels. */ 284618334Speter value->un.addr.base = XEXP (value->un.addr.base, 0); 284790075Sobrien 284850397Sobrien default: 284950397Sobrien break; 285018334Speter } 285118334Speter} 285218334Speter 285318334Speter/* Given a MINUS expression, simplify it if both sides 285418334Speter include the same symbol. */ 285518334Speter 285618334Speterrtx 2857132718Skansimplify_subtraction (rtx x) 285818334Speter{ 285918334Speter struct rtx_const val0, val1; 286018334Speter 286118334Speter decode_rtx_const (GET_MODE (x), XEXP (x, 0), &val0); 286218334Speter decode_rtx_const (GET_MODE (x), XEXP (x, 1), &val1); 286318334Speter 2864117395Skan if (val0.kind >= RTX_INT 286596263Sobrien && val0.kind == val1.kind 2866117395Skan && val0.un.addr.base == val1.un.addr.base 2867117395Skan && val0.un.addr.symbol == val1.un.addr.symbol) 286818334Speter return GEN_INT (val0.un.addr.offset - val1.un.addr.offset); 286996263Sobrien 287018334Speter return x; 287118334Speter} 287218334Speter 287318334Speter/* Compute a hash code for a constant RTL expression. */ 287418334Speter 2875117395Skanstatic unsigned int 2876132718Skanconst_hash_rtx (enum machine_mode mode, rtx x) 287718334Speter{ 2878117395Skan union { 2879117395Skan struct rtx_const value; 2880117395Skan unsigned int data[sizeof(struct rtx_const) / sizeof (unsigned int)]; 2881117395Skan } u; 2882117395Skan 2883117395Skan unsigned int hi; 288490075Sobrien size_t i; 288518334Speter 2886117395Skan decode_rtx_const (mode, x, &u.value); 288718334Speter 2888132718Skan /* Compute hashing function. */ 288918334Speter hi = 0; 2890117395Skan for (i = 0; i < ARRAY_SIZE (u.data); i++) 2891117395Skan hi = hi * 613 + u.data[i]; 289218334Speter 2893117395Skan return hi % MAX_RTX_HASH_TABLE; 289418334Speter} 289518334Speter 289618334Speter/* Compare a constant rtl object X with a constant-descriptor DESC. 289718334Speter Return 1 if DESC describes a constant with the same value as X. */ 289818334Speter 289918334Speterstatic int 2900132718Skancompare_constant_rtx (enum machine_mode mode, rtx x, 2901132718Skan struct constant_descriptor_rtx *desc) 290218334Speter{ 290318334Speter struct rtx_const value; 290418334Speter 290518334Speter decode_rtx_const (mode, x, &value); 290618334Speter 290718334Speter /* Compare constant contents. */ 2908117395Skan return memcmp (&value, &desc->value, sizeof (struct rtx_const)) == 0; 290918334Speter} 291018334Speter 291118334Speter/* Construct a constant descriptor for the rtl-expression X. 291218334Speter It is up to the caller to enter the descriptor in the hash table. */ 291318334Speter 2914117395Skanstatic struct constant_descriptor_rtx * 2915132718Skanrecord_constant_rtx (enum machine_mode mode, rtx x) 291618334Speter{ 2917117395Skan struct constant_descriptor_rtx *ptr; 291818334Speter 2919132718Skan ptr = ggc_alloc (sizeof (*ptr)); 2920117395Skan decode_rtx_const (mode, x, &ptr->value); 292118334Speter 292290075Sobrien return ptr; 292390075Sobrien} 292490075Sobrien 292518334Speter/* Given a constant rtx X, make (or find) a memory constant for its value 292618334Speter and return a MEM rtx to refer to it in memory. */ 292718334Speter 292818334Speterrtx 2929132718Skanforce_const_mem (enum machine_mode mode, rtx x) 293018334Speter{ 293190075Sobrien int hash; 2932117395Skan struct constant_descriptor_rtx *desc; 293318334Speter char label[256]; 2934132718Skan rtx def, symbol; 293590075Sobrien struct pool_constant *pool; 293690075Sobrien unsigned int align; 293718334Speter 2938117395Skan /* If we're not allowed to drop X into the constant pool, don't. */ 2939117395Skan if ((*targetm.cannot_force_const_mem) (x)) 2940117395Skan return NULL_RTX; 2941117395Skan 294218334Speter /* Compute hash code of X. Search the descriptors for that hash code 294390075Sobrien to see if any of them describes X. If yes, we have an rtx to use. */ 294418334Speter hash = const_hash_rtx (mode, x); 294518334Speter for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next) 294618334Speter if (compare_constant_rtx (mode, x, desc)) 2947132718Skan return copy_rtx (desc->rtl); 294818334Speter 294990075Sobrien /* No constant equal to X is known to have been output. 295090075Sobrien Make a constant descriptor to enter X in the hash table 295190075Sobrien and make a MEM for it. */ 295290075Sobrien desc = record_constant_rtx (mode, x); 295390075Sobrien desc->next = const_rtx_hash_table[hash]; 295490075Sobrien const_rtx_hash_table[hash] = desc; 2955117395Skan 295690075Sobrien /* Align the location counter as required by EXP's data type. */ 295790075Sobrien align = GET_MODE_ALIGNMENT (mode == VOIDmode ? word_mode : mode); 295850397Sobrien#ifdef CONSTANT_ALIGNMENT 2959132718Skan { 2960132718Skan tree type = (*lang_hooks.types.type_for_mode) (mode, 0); 2961132718Skan if (type != NULL_TREE) 2962132718Skan align = CONSTANT_ALIGNMENT (make_tree (type, x), align); 2963132718Skan } 296450397Sobrien#endif 296518334Speter 296690075Sobrien pool_offset += (align / BITS_PER_UNIT) - 1; 296790075Sobrien pool_offset &= ~ ((align / BITS_PER_UNIT) - 1); 296818334Speter 296990075Sobrien if (GET_CODE (x) == LABEL_REF) 297090075Sobrien LABEL_PRESERVE_P (XEXP (x, 0)) = 1; 297118334Speter 297290075Sobrien /* Allocate a pool constant descriptor, fill it in, and chain it in. */ 2973132718Skan pool = ggc_alloc (sizeof (struct pool_constant)); 297490075Sobrien pool->desc = desc; 297590075Sobrien pool->constant = x; 297690075Sobrien pool->mode = mode; 297790075Sobrien pool->labelno = const_labelno; 297890075Sobrien pool->align = align; 297990075Sobrien pool->offset = pool_offset; 298090075Sobrien pool->mark = 1; 298190075Sobrien pool->next = 0; 298250397Sobrien 298390075Sobrien if (last_pool == 0) 298490075Sobrien first_pool = pool; 298590075Sobrien else 298690075Sobrien last_pool->next = pool; 2987117395Skan 298890075Sobrien last_pool = pool; 298990075Sobrien pool_offset += GET_MODE_SIZE (mode); 299018334Speter 299190075Sobrien /* Create a string containing the label name, in LABEL. */ 299290075Sobrien ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno); 299374722Sobrien 299490075Sobrien ++const_labelno; 299574722Sobrien 299690075Sobrien /* Construct the SYMBOL_REF and the MEM. */ 299718334Speter 2998132718Skan symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label)); 2999132718Skan SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL; 3000132718Skan 3001132718Skan pool->desc->rtl = def = gen_rtx_MEM (mode, symbol); 3002117395Skan set_mem_attributes (def, (*lang_hooks.types.type_for_mode) (mode, 0), 1); 300390075Sobrien RTX_UNCHANGING_P (def) = 1; 300418334Speter 300590075Sobrien /* Add label to symbol hash table. */ 3006132718Skan hash = SYMHASH (XSTR (symbol, 0)); 300790075Sobrien pool->next_sym = const_rtx_sym_hash_table[hash]; 300890075Sobrien const_rtx_sym_hash_table[hash] = pool; 300918334Speter 301018334Speter /* Mark the symbol_ref as belonging to this constants pool. */ 3011132718Skan CONSTANT_POOL_ADDRESS_P (symbol) = 1; 3012132718Skan SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL; 301318334Speter current_function_uses_const_pool = 1; 301418334Speter 3015132718Skan return copy_rtx (def); 301618334Speter} 301718334Speter 301818334Speter/* Given a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true, return a pointer to 301918334Speter the corresponding pool_constant structure. */ 302018334Speter 302118334Speterstatic struct pool_constant * 3022132718Skanfind_pool_constant (struct function *f, rtx addr) 302318334Speter{ 302490075Sobrien struct pool_constant *pool; 302590075Sobrien const char *label = XSTR (addr, 0); 302618334Speter 302790075Sobrien for (pool = f->varasm->x_const_rtx_sym_hash_table[SYMHASH (label)]; pool; 302890075Sobrien pool = pool->next_sym) 302990075Sobrien if (XSTR (XEXP (pool->desc->rtl, 0), 0) == label) 303090075Sobrien return pool; 303118334Speter 303218334Speter abort (); 303318334Speter} 303418334Speter 303518334Speter/* Given a constant pool SYMBOL_REF, return the corresponding constant. */ 303618334Speter 303718334Speterrtx 3038132718Skanget_pool_constant (rtx addr) 303918334Speter{ 304090075Sobrien return (find_pool_constant (cfun, addr))->constant; 304118334Speter} 304218334Speter 304396263Sobrien/* Given a constant pool SYMBOL_REF, return the corresponding constant 304496263Sobrien and whether it has been output or not. */ 304596263Sobrien 304696263Sobrienrtx 3047132718Skanget_pool_constant_mark (rtx addr, bool *pmarked) 304896263Sobrien{ 304996263Sobrien struct pool_constant *pool = find_pool_constant (cfun, addr); 305096263Sobrien *pmarked = (pool->mark != 0); 305196263Sobrien return pool->constant; 305296263Sobrien} 305396263Sobrien 305490075Sobrien/* Likewise, but for the constant pool of a specific function. */ 305590075Sobrien 305690075Sobrienrtx 3057132718Skanget_pool_constant_for_function (struct function *f, rtx addr) 305890075Sobrien{ 305990075Sobrien return (find_pool_constant (f, addr))->constant; 306090075Sobrien} 306190075Sobrien 306218334Speter/* Similar, return the mode. */ 306318334Speter 306418334Speterenum machine_mode 3065132718Skanget_pool_mode (rtx addr) 306618334Speter{ 306790075Sobrien return (find_pool_constant (cfun, addr))->mode; 306818334Speter} 306918334Speter 307090075Sobrienenum machine_mode 3071132718Skanget_pool_mode_for_function (struct function *f, rtx addr) 307290075Sobrien{ 307390075Sobrien return (find_pool_constant (f, addr))->mode; 307490075Sobrien} 307590075Sobrien 307618334Speter/* Similar, return the offset in the constant pool. */ 307718334Speter 307818334Speterint 3079132718Skanget_pool_offset (rtx addr) 308018334Speter{ 308190075Sobrien return (find_pool_constant (cfun, addr))->offset; 308218334Speter} 308318334Speter 308418334Speter/* Return the size of the constant pool. */ 308518334Speter 308618334Speterint 3087132718Skanget_pool_size (void) 308818334Speter{ 308918334Speter return pool_offset; 309018334Speter} 309118334Speter 309218334Speter/* Write all the constants in the constant pool. */ 309318334Speter 309418334Spetervoid 3095132718Skanoutput_constant_pool (const char *fnname ATTRIBUTE_UNUSED, 3096132718Skan tree fndecl ATTRIBUTE_UNUSED) 309718334Speter{ 309818334Speter struct pool_constant *pool; 309918334Speter rtx x; 3100117395Skan REAL_VALUE_TYPE r; 310118334Speter 310250397Sobrien /* It is possible for gcc to call force_const_mem and then to later 310350397Sobrien discard the instructions which refer to the constant. In such a 310450397Sobrien case we do not need to output the constant. */ 310552284Sobrien mark_constant_pool (); 310650397Sobrien 310718334Speter#ifdef ASM_OUTPUT_POOL_PROLOGUE 310818334Speter ASM_OUTPUT_POOL_PROLOGUE (asm_out_file, fnname, fndecl, pool_offset); 310918334Speter#endif 311018334Speter 311118334Speter for (pool = first_pool; pool; pool = pool->next) 311218334Speter { 311390075Sobrien rtx tmp; 311490075Sobrien 311518334Speter x = pool->constant; 311618334Speter 311750397Sobrien if (! pool->mark) 311850397Sobrien continue; 311950397Sobrien 312018334Speter /* See if X is a LABEL_REF (or a CONST referring to a LABEL_REF) 312118334Speter whose CODE_LABEL has been deleted. This can occur if a jump table 312218334Speter is eliminated by optimization. If so, write a constant of zero 312318334Speter instead. Note that this can also happen by turning the 312418334Speter CODE_LABEL into a NOTE. */ 312590075Sobrien /* ??? This seems completely and utterly wrong. Certainly it's 312690075Sobrien not true for NOTE_INSN_DELETED_LABEL, but I disbelieve proper 312790075Sobrien functioning even with INSN_DELETED_P and friends. */ 312818334Speter 312990075Sobrien tmp = x; 313090075Sobrien switch (GET_CODE (x)) 313190075Sobrien { 313290075Sobrien case CONST: 313390075Sobrien if (GET_CODE (XEXP (x, 0)) != PLUS 313490075Sobrien || GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF) 313590075Sobrien break; 313690075Sobrien tmp = XEXP (XEXP (x, 0), 0); 3137132718Skan /* Fall through. */ 313890075Sobrien 313990075Sobrien case LABEL_REF: 314090075Sobrien tmp = XEXP (x, 0); 314190075Sobrien if (INSN_DELETED_P (tmp) 314290075Sobrien || (GET_CODE (tmp) == NOTE 314390075Sobrien && NOTE_LINE_NUMBER (tmp) == NOTE_INSN_DELETED)) 314490075Sobrien { 314590075Sobrien abort (); 314690075Sobrien x = const0_rtx; 314790075Sobrien } 314890075Sobrien break; 314990075Sobrien 315090075Sobrien default: 315190075Sobrien break; 315290075Sobrien } 315390075Sobrien 315418334Speter /* First switch to correct section. */ 3155117395Skan (*targetm.asm_out.select_rtx_section) (pool->mode, x, pool->align); 315618334Speter 315718334Speter#ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY 315818334Speter ASM_OUTPUT_SPECIAL_POOL_ENTRY (asm_out_file, x, pool->mode, 315918334Speter pool->align, pool->labelno, done); 316018334Speter#endif 316118334Speter 316290075Sobrien assemble_align (pool->align); 316318334Speter 316418334Speter /* Output the label. */ 3165132718Skan (*targetm.asm_out.internal_label) (asm_out_file, "LC", pool->labelno); 316618334Speter 316718334Speter /* Output the value of the constant itself. */ 316818334Speter switch (GET_MODE_CLASS (pool->mode)) 316918334Speter { 317018334Speter case MODE_FLOAT: 317118334Speter if (GET_CODE (x) != CONST_DOUBLE) 317218334Speter abort (); 317318334Speter 3174117395Skan REAL_VALUE_FROM_CONST_DOUBLE (r, x); 3175117395Skan assemble_real (r, pool->mode, pool->align); 317618334Speter break; 317718334Speter 317818334Speter case MODE_INT: 317918334Speter case MODE_PARTIAL_INT: 318090075Sobrien assemble_integer (x, GET_MODE_SIZE (pool->mode), pool->align, 1); 318118334Speter break; 318218334Speter 318396263Sobrien case MODE_VECTOR_FLOAT: 318496263Sobrien { 318596263Sobrien int i, units; 318696263Sobrien rtx elt; 318796263Sobrien 318896263Sobrien if (GET_CODE (x) != CONST_VECTOR) 318996263Sobrien abort (); 319096263Sobrien 319196263Sobrien units = CONST_VECTOR_NUNITS (x); 319296263Sobrien 319396263Sobrien for (i = 0; i < units; i++) 319496263Sobrien { 319596263Sobrien elt = CONST_VECTOR_ELT (x, i); 3196117395Skan REAL_VALUE_FROM_CONST_DOUBLE (r, elt); 3197117395Skan assemble_real (r, GET_MODE_INNER (pool->mode), pool->align); 319896263Sobrien } 319996263Sobrien } 320096263Sobrien break; 320196263Sobrien 3202117395Skan case MODE_VECTOR_INT: 320396263Sobrien { 320496263Sobrien int i, units; 320596263Sobrien rtx elt; 320696263Sobrien 320796263Sobrien if (GET_CODE (x) != CONST_VECTOR) 320896263Sobrien abort (); 320996263Sobrien 321096263Sobrien units = CONST_VECTOR_NUNITS (x); 321196263Sobrien 321296263Sobrien for (i = 0; i < units; i++) 321396263Sobrien { 321496263Sobrien elt = CONST_VECTOR_ELT (x, i); 321596263Sobrien assemble_integer (elt, GET_MODE_UNIT_SIZE (pool->mode), 321696263Sobrien pool->align, 1); 321796263Sobrien } 321896263Sobrien } 321996263Sobrien break; 322096263Sobrien 322118334Speter default: 322218334Speter abort (); 322318334Speter } 322418334Speter 3225117395Skan /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS 3226117395Skan sections have proper size. */ 3227117395Skan if (pool->align > GET_MODE_BITSIZE (pool->mode) 3228117395Skan && in_section == in_named 3229117395Skan && get_named_section_flags (in_named_name) & SECTION_MERGE) 3230117395Skan assemble_align (pool->align); 3231117395Skan 323250397Sobrien#ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY 323318334Speter done: ; 323450397Sobrien#endif 323518334Speter } 323618334Speter 323750397Sobrien#ifdef ASM_OUTPUT_POOL_EPILOGUE 323850397Sobrien ASM_OUTPUT_POOL_EPILOGUE (asm_out_file, fnname, fndecl, pool_offset); 323950397Sobrien#endif 324050397Sobrien 324118334Speter /* Done with this pool. */ 324218334Speter first_pool = last_pool = 0; 324318334Speter} 324450397Sobrien 324550397Sobrien/* Look through the instructions for this function, and mark all the 3246132718Skan entries in the constant pool which are actually being used. Emit 3247132718Skan deferred constants which have indeed been used. */ 324850397Sobrien 324950397Sobrienstatic void 3250132718Skanmark_constant_pool (void) 325150397Sobrien{ 325290075Sobrien rtx insn; 3253117395Skan rtx link; 325450397Sobrien struct pool_constant *pool; 325550397Sobrien 3256132718Skan if (first_pool == 0 && n_deferred_constants == 0) 325750397Sobrien return; 325850397Sobrien 325950397Sobrien for (pool = first_pool; pool; pool = pool->next) 326050397Sobrien pool->mark = 0; 326150397Sobrien 326250397Sobrien for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 326390075Sobrien if (INSN_P (insn)) 326450397Sobrien mark_constants (PATTERN (insn)); 326550397Sobrien 3266117395Skan for (link = current_function_epilogue_delay_list; 3267117395Skan link; 3268117395Skan link = XEXP (link, 1)) 3269117395Skan { 3270117395Skan insn = XEXP (link, 0); 3271117395Skan 3272117395Skan if (INSN_P (insn)) 3273117395Skan mark_constants (PATTERN (insn)); 3274117395Skan } 327590075Sobrien} 327652284Sobrien 327790075Sobrien/* Look through appropriate parts of X, marking all entries in the 327890075Sobrien constant pool which are actually being used. Entries that are only 327990075Sobrien referenced by other constants are also marked as used. Emit 328090075Sobrien deferred strings that are used. */ 328152284Sobrien 328250397Sobrienstatic void 3283132718Skanmark_constants (rtx x) 328450397Sobrien{ 328590075Sobrien int i; 328690075Sobrien const char *format_ptr; 328750397Sobrien 328850397Sobrien if (x == 0) 328950397Sobrien return; 329050397Sobrien 329150397Sobrien if (GET_CODE (x) == SYMBOL_REF) 329250397Sobrien { 329390075Sobrien mark_constant (&x, NULL); 329450397Sobrien return; 329550397Sobrien } 329650397Sobrien 329750397Sobrien /* Insns may appear inside a SEQUENCE. Only check the patterns of 329850397Sobrien insns, not any notes that may be attached. We don't want to mark 329950397Sobrien a constant just because it happens to appear in a REG_EQUIV note. */ 330090075Sobrien if (INSN_P (x)) 330150397Sobrien { 330250397Sobrien mark_constants (PATTERN (x)); 330350397Sobrien return; 330450397Sobrien } 330550397Sobrien 330650397Sobrien format_ptr = GET_RTX_FORMAT (GET_CODE (x)); 330750397Sobrien 330850397Sobrien for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++) 330950397Sobrien { 331050397Sobrien switch (*format_ptr++) 331150397Sobrien { 331250397Sobrien case 'e': 331350397Sobrien mark_constants (XEXP (x, i)); 331450397Sobrien break; 331550397Sobrien 331650397Sobrien case 'E': 331750397Sobrien if (XVEC (x, i) != 0) 331850397Sobrien { 331990075Sobrien int j; 332050397Sobrien 332150397Sobrien for (j = 0; j < XVECLEN (x, i); j++) 332250397Sobrien mark_constants (XVECEXP (x, i, j)); 332350397Sobrien } 332450397Sobrien break; 332550397Sobrien 332650397Sobrien case 'S': 332750397Sobrien case 's': 332850397Sobrien case '0': 332950397Sobrien case 'i': 333050397Sobrien case 'w': 333150397Sobrien case 'n': 333250397Sobrien case 'u': 3333117395Skan case 'B': 333450397Sobrien break; 333550397Sobrien 333650397Sobrien default: 333750397Sobrien abort (); 333850397Sobrien } 333950397Sobrien } 334050397Sobrien} 334190075Sobrien 334290075Sobrien/* Given a SYMBOL_REF CURRENT_RTX, mark it and all constants it refers 334390075Sobrien to as used. Emit referenced deferred strings. This function can 334490075Sobrien be used with for_each_rtx to mark all SYMBOL_REFs in an rtx. */ 334590075Sobrien 334690075Sobrienstatic int 3347132718Skanmark_constant (rtx *current_rtx, void *data ATTRIBUTE_UNUSED) 334890075Sobrien{ 334990075Sobrien rtx x = *current_rtx; 335090075Sobrien 335190075Sobrien if (x == NULL_RTX) 335290075Sobrien return 0; 335390075Sobrien 335490075Sobrien else if (GET_CODE (x) == SYMBOL_REF) 335590075Sobrien { 335690075Sobrien if (CONSTANT_POOL_ADDRESS_P (x)) 335790075Sobrien { 335890075Sobrien struct pool_constant *pool = find_pool_constant (cfun, x); 3359117395Skan if (pool->mark == 0) 3360117395Skan { 3361117395Skan pool->mark = 1; 3362117395Skan for_each_rtx (&(pool->constant), &mark_constant, NULL); 3363117395Skan } 336490075Sobrien else 336590075Sobrien return -1; 336690075Sobrien } 3367132718Skan else if (TREE_CONSTANT_POOL_ADDRESS_P (x)) 336890075Sobrien { 3369132718Skan tree exp = SYMBOL_REF_DECL (x); 3370132718Skan if (!TREE_ASM_WRITTEN (exp)) 337190075Sobrien { 3372132718Skan n_deferred_constants--; 3373132718Skan output_constant_def_contents (x); 337490075Sobrien } 337590075Sobrien } 337690075Sobrien } 337790075Sobrien return 0; 337890075Sobrien} 337918334Speter 3380132718Skan/* Determine what kind of relocations EXP may need. */ 338118334Speter 3382132718Skanint 3383132718Skancompute_reloc_for_constant (tree exp) 338418334Speter{ 3385117395Skan int reloc = 0, reloc2; 338690075Sobrien tree tem; 338718334Speter 338890075Sobrien /* Give the front-end a chance to convert VALUE to something that 338990075Sobrien looks more like a constant to the back-end. */ 339090075Sobrien exp = (*lang_hooks.expand_constant) (exp); 339190075Sobrien 339218334Speter switch (TREE_CODE (exp)) 339318334Speter { 339418334Speter case ADDR_EXPR: 3395102780Skan case FDESC_EXPR: 339690075Sobrien /* Go inside any operations that get_inner_reference can handle and see 339790075Sobrien if what's inside is a constant: no need to do anything here for 339890075Sobrien addresses of variables or functions. */ 339990075Sobrien for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem); 340090075Sobrien tem = TREE_OPERAND (tem, 0)) 340190075Sobrien ; 340218334Speter 340390075Sobrien if (TREE_PUBLIC (tem)) 340490075Sobrien reloc |= 2; 340590075Sobrien else 340690075Sobrien reloc |= 1; 340718334Speter break; 340818334Speter 340918334Speter case PLUS_EXPR: 3410132718Skan reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0)); 3411132718Skan reloc |= compute_reloc_for_constant (TREE_OPERAND (exp, 1)); 341218334Speter break; 341318334Speter 3414117395Skan case MINUS_EXPR: 3415132718Skan reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0)); 3416132718Skan reloc2 = compute_reloc_for_constant (TREE_OPERAND (exp, 1)); 3417117395Skan /* The difference of two local labels is computable at link time. */ 3418117395Skan if (reloc == 1 && reloc2 == 1) 3419117395Skan reloc = 0; 3420117395Skan else 3421117395Skan reloc |= reloc2; 3422117395Skan break; 3423117395Skan 342418334Speter case NOP_EXPR: 342518334Speter case CONVERT_EXPR: 342618334Speter case NON_LVALUE_EXPR: 3427132718Skan reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0)); 342818334Speter break; 342918334Speter 343018334Speter case CONSTRUCTOR: 343190075Sobrien for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem)) 343290075Sobrien if (TREE_VALUE (tem) != 0) 3433132718Skan reloc |= compute_reloc_for_constant (TREE_VALUE (tem)); 343490075Sobrien 343518334Speter break; 343618334Speter 343750397Sobrien default: 343818334Speter break; 343918334Speter } 344018334Speter return reloc; 344118334Speter} 3442132718Skan 3443132718Skan/* Find all the constants whose addresses are referenced inside of EXP, 3444132718Skan and make sure assembler code with a label has been output for each one. 3445132718Skan Indicate whether an ADDR_EXPR has been encountered. */ 3446132718Skan 3447132718Skanstatic void 3448132718Skanoutput_addressed_constants (tree exp) 3449132718Skan{ 3450132718Skan tree tem; 3451132718Skan 3452132718Skan /* Give the front-end a chance to convert VALUE to something that 3453132718Skan looks more like a constant to the back-end. */ 3454132718Skan exp = (*lang_hooks.expand_constant) (exp); 3455132718Skan 3456132718Skan switch (TREE_CODE (exp)) 3457132718Skan { 3458132718Skan case ADDR_EXPR: 3459132718Skan case FDESC_EXPR: 3460132718Skan /* Go inside any operations that get_inner_reference can handle and see 3461132718Skan if what's inside is a constant: no need to do anything here for 3462132718Skan addresses of variables or functions. */ 3463132718Skan for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem); 3464132718Skan tem = TREE_OPERAND (tem, 0)) 3465132718Skan ; 3466132718Skan 3467132718Skan if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c' 3468132718Skan || TREE_CODE (tem) == CONSTRUCTOR) 3469132718Skan output_constant_def (tem, 0); 3470132718Skan break; 3471132718Skan 3472132718Skan case PLUS_EXPR: 3473132718Skan case MINUS_EXPR: 3474132718Skan output_addressed_constants (TREE_OPERAND (exp, 1)); 3475132718Skan /* Fall through. */ 3476132718Skan 3477132718Skan case NOP_EXPR: 3478132718Skan case CONVERT_EXPR: 3479132718Skan case NON_LVALUE_EXPR: 3480132718Skan output_addressed_constants (TREE_OPERAND (exp, 0)); 3481132718Skan break; 3482132718Skan 3483132718Skan case CONSTRUCTOR: 3484132718Skan for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem)) 3485132718Skan if (TREE_VALUE (tem) != 0) 3486132718Skan output_addressed_constants (TREE_VALUE (tem)); 3487132718Skan 3488132718Skan break; 3489132718Skan 3490132718Skan default: 3491132718Skan break; 3492132718Skan } 3493132718Skan} 349418334Speter 349590075Sobrien/* Return nonzero if VALUE is a valid constant-valued expression 349690075Sobrien for use in initializing a static variable; one that can be an 349790075Sobrien element of a "constant" initializer. 349890075Sobrien 349990075Sobrien Return null_pointer_node if the value is absolute; 350090075Sobrien if it is relocatable, return the variable that determines the relocation. 350190075Sobrien We assume that VALUE has been folded as much as possible; 350290075Sobrien therefore, we do not need to check for such things as 350390075Sobrien arithmetic-combinations of integers. */ 350490075Sobrien 350590075Sobrientree 3506132718Skaninitializer_constant_valid_p (tree value, tree endtype) 350790075Sobrien{ 350890075Sobrien /* Give the front-end a chance to convert VALUE to something that 350990075Sobrien looks more like a constant to the back-end. */ 351090075Sobrien value = (*lang_hooks.expand_constant) (value); 351190075Sobrien 351290075Sobrien switch (TREE_CODE (value)) 351390075Sobrien { 351490075Sobrien case CONSTRUCTOR: 351590075Sobrien if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE 351690075Sobrien || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE) 351790075Sobrien && TREE_CONSTANT (value) 351890075Sobrien && CONSTRUCTOR_ELTS (value)) 3519122180Skan { 3520122180Skan tree elt; 3521122180Skan bool absolute = true; 352290075Sobrien 3523122180Skan for (elt = CONSTRUCTOR_ELTS (value); elt; elt = TREE_CHAIN (elt)) 3524122180Skan { 3525122180Skan tree reloc; 3526122180Skan value = TREE_VALUE (elt); 3527122180Skan reloc = initializer_constant_valid_p (value, TREE_TYPE (value)); 3528122180Skan if (!reloc) 3529122180Skan return NULL_TREE; 3530122180Skan if (reloc != null_pointer_node) 3531122180Skan absolute = false; 3532122180Skan } 3533122180Skan /* For a non-absolute relocation, there is no single 3534122180Skan variable that can be "the variable that determines the 3535122180Skan relocation." */ 3536122180Skan return absolute ? null_pointer_node : error_mark_node; 3537122180Skan } 353890075Sobrien 3539122180Skan return TREE_STATIC (value) ? null_pointer_node : NULL_TREE; 3540122180Skan 354190075Sobrien case INTEGER_CST: 354296263Sobrien case VECTOR_CST: 354390075Sobrien case REAL_CST: 354490075Sobrien case STRING_CST: 354590075Sobrien case COMPLEX_CST: 354690075Sobrien return null_pointer_node; 354790075Sobrien 354890075Sobrien case ADDR_EXPR: 354990075Sobrien case FDESC_EXPR: 355090075Sobrien return staticp (TREE_OPERAND (value, 0)) ? TREE_OPERAND (value, 0) : 0; 355190075Sobrien 355290075Sobrien case VIEW_CONVERT_EXPR: 355390075Sobrien case NON_LVALUE_EXPR: 355490075Sobrien return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); 355590075Sobrien 355690075Sobrien case CONVERT_EXPR: 355790075Sobrien case NOP_EXPR: 355890075Sobrien /* Allow conversions between pointer types. */ 355990075Sobrien if (POINTER_TYPE_P (TREE_TYPE (value)) 356090075Sobrien && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) 356190075Sobrien return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); 356290075Sobrien 356390075Sobrien /* Allow conversions between real types. */ 356490075Sobrien if (FLOAT_TYPE_P (TREE_TYPE (value)) 356590075Sobrien && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) 356690075Sobrien return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); 356790075Sobrien 356890075Sobrien /* Allow length-preserving conversions between integer types. */ 356990075Sobrien if (INTEGRAL_TYPE_P (TREE_TYPE (value)) 357090075Sobrien && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))) 357190075Sobrien && (TYPE_PRECISION (TREE_TYPE (value)) 357290075Sobrien == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) 357390075Sobrien return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); 357490075Sobrien 357590075Sobrien /* Allow conversions between other integer types only if 357690075Sobrien explicit value. */ 357790075Sobrien if (INTEGRAL_TYPE_P (TREE_TYPE (value)) 357890075Sobrien && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) 357990075Sobrien { 358090075Sobrien tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0), 358190075Sobrien endtype); 358290075Sobrien if (inner == null_pointer_node) 358390075Sobrien return null_pointer_node; 358490075Sobrien break; 358590075Sobrien } 358690075Sobrien 358790075Sobrien /* Allow (int) &foo provided int is as wide as a pointer. */ 358890075Sobrien if (INTEGRAL_TYPE_P (TREE_TYPE (value)) 358990075Sobrien && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))) 359090075Sobrien && (TYPE_PRECISION (TREE_TYPE (value)) 359190075Sobrien >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) 359290075Sobrien return initializer_constant_valid_p (TREE_OPERAND (value, 0), 359390075Sobrien endtype); 359490075Sobrien 359590075Sobrien /* Likewise conversions from int to pointers, but also allow 359690075Sobrien conversions from 0. */ 3597132718Skan if ((POINTER_TYPE_P (TREE_TYPE (value)) 3598132718Skan || TREE_CODE (TREE_TYPE (value)) == OFFSET_TYPE) 359990075Sobrien && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) 360090075Sobrien { 360190075Sobrien if (integer_zerop (TREE_OPERAND (value, 0))) 360290075Sobrien return null_pointer_node; 360390075Sobrien else if (TYPE_PRECISION (TREE_TYPE (value)) 360490075Sobrien <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))) 360590075Sobrien return initializer_constant_valid_p (TREE_OPERAND (value, 0), 360690075Sobrien endtype); 360790075Sobrien } 360890075Sobrien 3609132718Skan /* Allow conversions to struct or union types if the value 3610132718Skan inside is okay. */ 3611132718Skan if (TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE 3612132718Skan || TREE_CODE (TREE_TYPE (value)) == UNION_TYPE) 361390075Sobrien return initializer_constant_valid_p (TREE_OPERAND (value, 0), 361490075Sobrien endtype); 361590075Sobrien break; 361690075Sobrien 361790075Sobrien case PLUS_EXPR: 361890075Sobrien if (! INTEGRAL_TYPE_P (endtype) 361990075Sobrien || TYPE_PRECISION (endtype) >= POINTER_SIZE) 3620117395Skan { 362190075Sobrien tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), 362290075Sobrien endtype); 362390075Sobrien tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), 362490075Sobrien endtype); 362590075Sobrien /* If either term is absolute, use the other terms relocation. */ 362690075Sobrien if (valid0 == null_pointer_node) 362790075Sobrien return valid1; 362890075Sobrien if (valid1 == null_pointer_node) 362990075Sobrien return valid0; 3630117395Skan } 363190075Sobrien break; 363290075Sobrien 363390075Sobrien case MINUS_EXPR: 363490075Sobrien if (! INTEGRAL_TYPE_P (endtype) 363590075Sobrien || TYPE_PRECISION (endtype) >= POINTER_SIZE) 363690075Sobrien { 363790075Sobrien tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), 363890075Sobrien endtype); 363990075Sobrien tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), 364090075Sobrien endtype); 364190075Sobrien /* Win if second argument is absolute. */ 364290075Sobrien if (valid1 == null_pointer_node) 364390075Sobrien return valid0; 364490075Sobrien /* Win if both arguments have the same relocation. 364590075Sobrien Then the value is absolute. */ 364690075Sobrien if (valid0 == valid1 && valid0 != 0) 364790075Sobrien return null_pointer_node; 364890075Sobrien 364990075Sobrien /* Since GCC guarantees that string constants are unique in the 365090075Sobrien generated code, a subtraction between two copies of the same 365190075Sobrien constant string is absolute. */ 365290075Sobrien if (valid0 && TREE_CODE (valid0) == STRING_CST && 365390075Sobrien valid1 && TREE_CODE (valid1) == STRING_CST && 365490075Sobrien TREE_STRING_POINTER (valid0) == TREE_STRING_POINTER (valid1)) 365590075Sobrien return null_pointer_node; 365690075Sobrien } 365790075Sobrien 365890075Sobrien /* Support differences between labels. */ 365990075Sobrien if (INTEGRAL_TYPE_P (endtype)) 366090075Sobrien { 366190075Sobrien tree op0, op1; 366290075Sobrien op0 = TREE_OPERAND (value, 0); 366390075Sobrien op1 = TREE_OPERAND (value, 1); 366490075Sobrien 366596263Sobrien /* Like STRIP_NOPS except allow the operand mode to widen. 3666132718Skan This works around a feature of fold that simplifies 366796263Sobrien (int)(p1 - p2) to ((int)p1 - (int)p2) under the theory 366896263Sobrien that the narrower operation is cheaper. */ 366996263Sobrien 367096263Sobrien while (TREE_CODE (op0) == NOP_EXPR 367196263Sobrien || TREE_CODE (op0) == CONVERT_EXPR 367296263Sobrien || TREE_CODE (op0) == NON_LVALUE_EXPR) 367396263Sobrien { 367496263Sobrien tree inner = TREE_OPERAND (op0, 0); 367596263Sobrien if (inner == error_mark_node 367696263Sobrien || ! INTEGRAL_MODE_P (TYPE_MODE (TREE_TYPE (inner))) 367796263Sobrien || (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))) 367896263Sobrien > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (inner))))) 367996263Sobrien break; 368096263Sobrien op0 = inner; 368196263Sobrien } 368296263Sobrien 368396263Sobrien while (TREE_CODE (op1) == NOP_EXPR 368496263Sobrien || TREE_CODE (op1) == CONVERT_EXPR 368596263Sobrien || TREE_CODE (op1) == NON_LVALUE_EXPR) 368696263Sobrien { 368796263Sobrien tree inner = TREE_OPERAND (op1, 0); 368896263Sobrien if (inner == error_mark_node 368996263Sobrien || ! INTEGRAL_MODE_P (TYPE_MODE (TREE_TYPE (inner))) 369096263Sobrien || (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op1))) 369196263Sobrien > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (inner))))) 369296263Sobrien break; 369396263Sobrien op1 = inner; 369496263Sobrien } 369596263Sobrien 369690075Sobrien if (TREE_CODE (op0) == ADDR_EXPR 369790075Sobrien && TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL 369890075Sobrien && TREE_CODE (op1) == ADDR_EXPR 369990075Sobrien && TREE_CODE (TREE_OPERAND (op1, 0)) == LABEL_DECL) 370090075Sobrien return null_pointer_node; 370190075Sobrien } 370290075Sobrien break; 370390075Sobrien 370490075Sobrien default: 370590075Sobrien break; 370690075Sobrien } 370790075Sobrien 370890075Sobrien return 0; 370990075Sobrien} 371090075Sobrien 371118334Speter/* Output assembler code for constant EXP to FILE, with no label. 371218334Speter This includes the pseudo-op such as ".int" or ".byte", and a newline. 371318334Speter Assumes output_addressed_constants has been done on EXP already. 371418334Speter 371518334Speter Generate exactly SIZE bytes of assembler data, padding at the end 371618334Speter with zeros if necessary. SIZE must always be specified. 371718334Speter 371818334Speter SIZE is important for structure constructors, 371918334Speter since trailing members may have been omitted from the constructor. 372018334Speter It is also important for initialization of arrays from string constants 372118334Speter since the full length of the string constant might not be wanted. 372218334Speter It is also needed for initialization of unions, where the initializer's 372318334Speter type is just one member, and that may not be as long as the union. 372418334Speter 372518334Speter There a case in which we would fail to output exactly SIZE bytes: 372618334Speter for a structure constructor that wants to produce more than SIZE bytes. 372790075Sobrien But such constructors will never be generated for any possible input. 372818334Speter 372990075Sobrien ALIGN is the alignment of the data in bits. */ 373090075Sobrien 373118334Spetervoid 3732132718Skanoutput_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align) 373318334Speter{ 373490075Sobrien enum tree_code code; 3735132718Skan unsigned HOST_WIDE_INT thissize; 373618334Speter 3737132718Skan /* Some front-ends use constants other than the standard language-independent 373890075Sobrien varieties, but which may still be output directly. Give the front-end a 373990075Sobrien chance to convert EXP to a language-independent representation. */ 374090075Sobrien exp = (*lang_hooks.expand_constant) (exp); 374152284Sobrien 374252284Sobrien if (size == 0 || flag_syntax_only) 374318334Speter return; 374418334Speter 374590075Sobrien /* Eliminate any conversions since we'll be outputting the underlying 374690075Sobrien constant. */ 374790075Sobrien while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR 374890075Sobrien || TREE_CODE (exp) == NON_LVALUE_EXPR 374990075Sobrien || TREE_CODE (exp) == VIEW_CONVERT_EXPR) 375018334Speter exp = TREE_OPERAND (exp, 0); 375118334Speter 375290075Sobrien code = TREE_CODE (TREE_TYPE (exp)); 375390075Sobrien thissize = int_size_in_bytes (TREE_TYPE (exp)); 375490075Sobrien 375518334Speter /* Allow a constructor with no elements for any data type. 375618334Speter This means to fill the space with zeros. */ 375718334Speter if (TREE_CODE (exp) == CONSTRUCTOR && CONSTRUCTOR_ELTS (exp) == 0) 375818334Speter { 375950397Sobrien assemble_zeros (size); 376018334Speter return; 376118334Speter } 376218334Speter 376390075Sobrien if (TREE_CODE (exp) == FDESC_EXPR) 376490075Sobrien { 376590075Sobrien#ifdef ASM_OUTPUT_FDESC 376690075Sobrien HOST_WIDE_INT part = tree_low_cst (TREE_OPERAND (exp, 1), 0); 376790075Sobrien tree decl = TREE_OPERAND (exp, 0); 376890075Sobrien ASM_OUTPUT_FDESC (asm_out_file, decl, part); 376990075Sobrien#else 377090075Sobrien abort (); 377190075Sobrien#endif 377290075Sobrien return; 377390075Sobrien } 377490075Sobrien 377590075Sobrien /* Now output the underlying data. If we've handling the padding, return. 377690075Sobrien Otherwise, break and ensure THISSIZE is the size written. */ 377718334Speter switch (code) 377818334Speter { 377918334Speter case CHAR_TYPE: 378018334Speter case BOOLEAN_TYPE: 378118334Speter case INTEGER_TYPE: 378218334Speter case ENUMERAL_TYPE: 378318334Speter case POINTER_TYPE: 378418334Speter case REFERENCE_TYPE: 3785132718Skan case OFFSET_TYPE: 378618334Speter if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode, 378718334Speter EXPAND_INITIALIZER), 378890075Sobrien size, align, 0)) 378918334Speter error ("initializer for integer value is too complicated"); 379018334Speter break; 379118334Speter 379218334Speter case REAL_TYPE: 379318334Speter if (TREE_CODE (exp) != REAL_CST) 379418334Speter error ("initializer for floating value is not a floating constant"); 379518334Speter 3796132718Skan assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align); 379718334Speter break; 379818334Speter 379918334Speter case COMPLEX_TYPE: 380090075Sobrien output_constant (TREE_REALPART (exp), thissize / 2, align); 380190075Sobrien output_constant (TREE_IMAGPART (exp), thissize / 2, 380290075Sobrien min_align (align, BITS_PER_UNIT * (thissize / 2))); 380318334Speter break; 380418334Speter 380518334Speter case ARRAY_TYPE: 380696263Sobrien case VECTOR_TYPE: 380718334Speter if (TREE_CODE (exp) == CONSTRUCTOR) 380818334Speter { 380990075Sobrien output_constructor (exp, size, align); 381018334Speter return; 381118334Speter } 381218334Speter else if (TREE_CODE (exp) == STRING_CST) 381318334Speter { 3814132718Skan thissize = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp), 3815132718Skan size); 381690075Sobrien assemble_string (TREE_STRING_POINTER (exp), thissize); 381718334Speter } 3818119256Skan else if (TREE_CODE (exp) == VECTOR_CST) 3819119256Skan { 3820119256Skan int elt_size; 3821119256Skan tree link; 3822119256Skan unsigned int nalign; 3823119256Skan enum machine_mode inner; 3824119256Skan 3825119256Skan inner = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (exp))); 3826119256Skan nalign = MIN (align, GET_MODE_ALIGNMENT (inner)); 3827119256Skan 3828119256Skan elt_size = GET_MODE_UNIT_SIZE (TYPE_MODE (TREE_TYPE (exp))); 3829119256Skan 3830119256Skan link = TREE_VECTOR_CST_ELTS (exp); 3831119256Skan output_constant (TREE_VALUE (link), elt_size, align); 3832119256Skan while ((link = TREE_CHAIN (link)) != NULL) 3833119256Skan output_constant (TREE_VALUE (link), elt_size, nalign); 3834119256Skan } 383518334Speter else 383618334Speter abort (); 383718334Speter break; 383818334Speter 383918334Speter case RECORD_TYPE: 384018334Speter case UNION_TYPE: 384118334Speter if (TREE_CODE (exp) == CONSTRUCTOR) 384290075Sobrien output_constructor (exp, size, align); 384318334Speter else 384418334Speter abort (); 384518334Speter return; 384618334Speter 384718334Speter case SET_TYPE: 384818334Speter if (TREE_CODE (exp) == INTEGER_CST) 384918334Speter assemble_integer (expand_expr (exp, NULL_RTX, 385018334Speter VOIDmode, EXPAND_INITIALIZER), 3851117395Skan thissize, align, 1); 385218334Speter else if (TREE_CODE (exp) == CONSTRUCTOR) 385318334Speter { 3854132718Skan unsigned char *buffer = alloca (thissize); 385590075Sobrien if (get_set_constructor_bytes (exp, buffer, thissize)) 385618334Speter abort (); 385790075Sobrien assemble_string ((char *) buffer, thissize); 385818334Speter } 385918334Speter else 386018334Speter error ("unknown set constructor type"); 386118334Speter return; 386250397Sobrien 386390075Sobrien case ERROR_MARK: 386490075Sobrien return; 386590075Sobrien 386650397Sobrien default: 386790075Sobrien abort (); 386818334Speter } 386918334Speter 3870132718Skan if (size > thissize) 3871132718Skan assemble_zeros (size - thissize); 387218334Speter} 387318334Speter 387418334Speter 387590075Sobrien/* Subroutine of output_constructor, used for computing the size of 387690075Sobrien arrays of unspecified length. VAL must be a CONSTRUCTOR of an array 387790075Sobrien type with an unspecified upper bound. */ 387890075Sobrien 387990075Sobrienstatic unsigned HOST_WIDE_INT 3880132718Skanarray_size_for_constructor (tree val) 388190075Sobrien{ 388290075Sobrien tree max_index, i; 388390075Sobrien 388490075Sobrien /* This code used to attempt to handle string constants that are not 388590075Sobrien arrays of single-bytes, but nothing else does, so there's no point in 388690075Sobrien doing it here. */ 388790075Sobrien if (TREE_CODE (val) == STRING_CST) 388890075Sobrien return TREE_STRING_LENGTH (val); 388990075Sobrien 389090075Sobrien max_index = NULL_TREE; 3891117395Skan for (i = CONSTRUCTOR_ELTS (val); i; i = TREE_CHAIN (i)) 389290075Sobrien { 389390075Sobrien tree index = TREE_PURPOSE (i); 389490075Sobrien 389590075Sobrien if (TREE_CODE (index) == RANGE_EXPR) 389690075Sobrien index = TREE_OPERAND (index, 1); 389790075Sobrien if (max_index == NULL_TREE || tree_int_cst_lt (max_index, index)) 389890075Sobrien max_index = index; 389990075Sobrien } 390090075Sobrien 390190075Sobrien if (max_index == NULL_TREE) 390290075Sobrien return 0; 390390075Sobrien 390490075Sobrien /* Compute the total number of array elements. */ 390590075Sobrien i = size_binop (MINUS_EXPR, convert (sizetype, max_index), 390690075Sobrien convert (sizetype, 390790075Sobrien TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (val))))); 390890075Sobrien i = size_binop (PLUS_EXPR, i, convert (sizetype, integer_one_node)); 390990075Sobrien 391090075Sobrien /* Multiply by the array element unit size to find number of bytes. */ 391190075Sobrien i = size_binop (MULT_EXPR, i, TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (val)))); 391290075Sobrien 391390075Sobrien return tree_low_cst (i, 1); 391490075Sobrien} 391590075Sobrien 391690075Sobrien/* Subroutine of output_constant, used for CONSTRUCTORs (aggregate constants). 391718334Speter Generate at least SIZE bytes, padding if necessary. */ 391818334Speter 391918334Speterstatic void 3920132718Skanoutput_constructor (tree exp, unsigned HOST_WIDE_INT size, 3921132718Skan unsigned int align) 392218334Speter{ 392390075Sobrien tree type = TREE_TYPE (exp); 392490075Sobrien tree link, field = 0; 392590075Sobrien tree min_index = 0; 392618334Speter /* Number of bytes output or skipped so far. 392718334Speter In other words, current position within the constructor. */ 392890075Sobrien HOST_WIDE_INT total_bytes = 0; 3929132718Skan /* Nonzero means BYTE contains part of a byte, to be output. */ 393018334Speter int byte_buffer_in_use = 0; 393190075Sobrien int byte = 0; 393218334Speter 393318334Speter if (HOST_BITS_PER_WIDE_INT < BITS_PER_UNIT) 393418334Speter abort (); 393518334Speter 393690075Sobrien if (TREE_CODE (type) == RECORD_TYPE) 393790075Sobrien field = TYPE_FIELDS (type); 393818334Speter 393990075Sobrien if (TREE_CODE (type) == ARRAY_TYPE 394090075Sobrien && TYPE_DOMAIN (type) != 0) 394190075Sobrien min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); 394218334Speter 394318334Speter /* As LINK goes through the elements of the constant, 394418334Speter FIELD goes through the structure fields, if the constant is a structure. 394518334Speter if the constant is a union, then we override this, 394618334Speter by getting the field from the TREE_LIST element. 394752284Sobrien But the constant could also be an array. Then FIELD is zero. 394852284Sobrien 394952284Sobrien There is always a maximum of one element in the chain LINK for unions 395052284Sobrien (even if the initializer in a source program incorrectly contains 395190075Sobrien more one). */ 395218334Speter for (link = CONSTRUCTOR_ELTS (exp); 395318334Speter link; 395418334Speter link = TREE_CHAIN (link), 395518334Speter field = field ? TREE_CHAIN (field) : 0) 395618334Speter { 395718334Speter tree val = TREE_VALUE (link); 395818334Speter tree index = 0; 395918334Speter 396090075Sobrien /* The element in a union constructor specifies the proper field 396190075Sobrien or index. */ 396290075Sobrien if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE 396390075Sobrien || TREE_CODE (type) == QUAL_UNION_TYPE) 396490075Sobrien && TREE_PURPOSE (link) != 0) 396590075Sobrien field = TREE_PURPOSE (link); 396618334Speter 396790075Sobrien else if (TREE_CODE (type) == ARRAY_TYPE) 396818334Speter index = TREE_PURPOSE (link); 396918334Speter 3970132718Skan#ifdef ASM_COMMENT_START 3971132718Skan if (field && flag_verbose_asm) 3972132718Skan fprintf (asm_out_file, "%s %s:\n", 3973132718Skan ASM_COMMENT_START, 3974132718Skan DECL_NAME (field) 3975132718Skan ? IDENTIFIER_POINTER (DECL_NAME (field)) 3976132718Skan : "<anonymous>"); 3977132718Skan#endif 3978132718Skan 397918334Speter /* Eliminate the marker that makes a cast not be an lvalue. */ 398018334Speter if (val != 0) 398118334Speter STRIP_NOPS (val); 398218334Speter 398350397Sobrien if (index && TREE_CODE (index) == RANGE_EXPR) 398418334Speter { 398590075Sobrien unsigned HOST_WIDE_INT fieldsize 398690075Sobrien = int_size_in_bytes (TREE_TYPE (type)); 398790075Sobrien HOST_WIDE_INT lo_index = tree_low_cst (TREE_OPERAND (index, 0), 0); 398890075Sobrien HOST_WIDE_INT hi_index = tree_low_cst (TREE_OPERAND (index, 1), 0); 398950397Sobrien HOST_WIDE_INT index; 399090075Sobrien unsigned int align2 = min_align (align, fieldsize * BITS_PER_UNIT); 399190075Sobrien 399250397Sobrien for (index = lo_index; index <= hi_index; index++) 399350397Sobrien { 399450397Sobrien /* Output the element's initial value. */ 399550397Sobrien if (val == 0) 399650397Sobrien assemble_zeros (fieldsize); 399750397Sobrien else 399890075Sobrien output_constant (val, fieldsize, align2); 399950397Sobrien 400050397Sobrien /* Count its size. */ 400150397Sobrien total_bytes += fieldsize; 400250397Sobrien } 400350397Sobrien } 400450397Sobrien else if (field == 0 || !DECL_BIT_FIELD (field)) 400550397Sobrien { 400618334Speter /* An element that is not a bit-field. */ 400718334Speter 400890075Sobrien unsigned HOST_WIDE_INT fieldsize; 400918334Speter /* Since this structure is static, 401018334Speter we know the positions are constant. */ 401190075Sobrien HOST_WIDE_INT pos = field ? int_byte_position (field) : 0; 401290075Sobrien unsigned int align2; 401390075Sobrien 401418334Speter if (index != 0) 401590075Sobrien pos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (val)), 1) 401690075Sobrien * (tree_low_cst (index, 0) - tree_low_cst (min_index, 0))); 401718334Speter 401818334Speter /* Output any buffered-up bit-fields preceding this element. */ 401918334Speter if (byte_buffer_in_use) 402018334Speter { 402190075Sobrien assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1); 402218334Speter total_bytes++; 402318334Speter byte_buffer_in_use = 0; 402418334Speter } 402518334Speter 402618334Speter /* Advance to offset of this element. 402718334Speter Note no alignment needed in an array, since that is guaranteed 402818334Speter if each element has the proper size. */ 402990075Sobrien if ((field != 0 || index != 0) && pos != total_bytes) 403018334Speter { 403190075Sobrien assemble_zeros (pos - total_bytes); 403290075Sobrien total_bytes = pos; 403318334Speter } 403418334Speter 403590075Sobrien /* Find the alignment of this element. */ 403690075Sobrien align2 = min_align (align, BITS_PER_UNIT * pos); 403790075Sobrien 403818334Speter /* Determine size this element should occupy. */ 403918334Speter if (field) 404018334Speter { 404190075Sobrien fieldsize = 0; 404290075Sobrien 404390075Sobrien /* If this is an array with an unspecified upper bound, 404490075Sobrien the initializer determines the size. */ 404590075Sobrien /* ??? This ought to only checked if DECL_SIZE_UNIT is NULL, 404690075Sobrien but we cannot do this until the deprecated support for 404790075Sobrien initializing zero-length array members is removed. */ 404890075Sobrien if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE 404990075Sobrien && TYPE_DOMAIN (TREE_TYPE (field)) 405090075Sobrien && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field)))) 405118334Speter { 405290075Sobrien fieldsize = array_size_for_constructor (val); 405390075Sobrien /* Given a non-empty initialization, this field had 405490075Sobrien better be last. */ 405590075Sobrien if (fieldsize != 0 && TREE_CHAIN (field) != NULL_TREE) 405690075Sobrien abort (); 405718334Speter } 405890075Sobrien else if (DECL_SIZE_UNIT (field)) 405918334Speter { 406090075Sobrien /* ??? This can't be right. If the decl size overflows 406190075Sobrien a host integer we will silently emit no data. */ 406290075Sobrien if (host_integerp (DECL_SIZE_UNIT (field), 1)) 406390075Sobrien fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1); 406418334Speter } 406518334Speter } 406618334Speter else 406790075Sobrien fieldsize = int_size_in_bytes (TREE_TYPE (type)); 406818334Speter 406918334Speter /* Output the element's initial value. */ 407018334Speter if (val == 0) 407118334Speter assemble_zeros (fieldsize); 407218334Speter else 407390075Sobrien output_constant (val, fieldsize, align2); 407418334Speter 407518334Speter /* Count its size. */ 407618334Speter total_bytes += fieldsize; 407718334Speter } 407818334Speter else if (val != 0 && TREE_CODE (val) != INTEGER_CST) 407918334Speter error ("invalid initial value for member `%s'", 408018334Speter IDENTIFIER_POINTER (DECL_NAME (field))); 408118334Speter else 408218334Speter { 408318334Speter /* Element that is a bit-field. */ 408418334Speter 408590075Sobrien HOST_WIDE_INT next_offset = int_bit_position (field); 408690075Sobrien HOST_WIDE_INT end_offset 408790075Sobrien = (next_offset + tree_low_cst (DECL_SIZE (field), 1)); 408818334Speter 408918334Speter if (val == 0) 409018334Speter val = integer_zero_node; 409118334Speter 409218334Speter /* If this field does not start in this (or, next) byte, 409318334Speter skip some bytes. */ 409418334Speter if (next_offset / BITS_PER_UNIT != total_bytes) 409518334Speter { 409618334Speter /* Output remnant of any bit field in previous bytes. */ 409718334Speter if (byte_buffer_in_use) 409818334Speter { 409990075Sobrien assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1); 410018334Speter total_bytes++; 410118334Speter byte_buffer_in_use = 0; 410218334Speter } 410318334Speter 410418334Speter /* If still not at proper byte, advance to there. */ 410518334Speter if (next_offset / BITS_PER_UNIT != total_bytes) 410618334Speter { 410718334Speter assemble_zeros (next_offset / BITS_PER_UNIT - total_bytes); 410818334Speter total_bytes = next_offset / BITS_PER_UNIT; 410918334Speter } 411018334Speter } 411118334Speter 411218334Speter if (! byte_buffer_in_use) 411318334Speter byte = 0; 411418334Speter 411518334Speter /* We must split the element into pieces that fall within 411618334Speter separate bytes, and combine each byte with previous or 411718334Speter following bit-fields. */ 411818334Speter 411918334Speter /* next_offset is the offset n fbits from the beginning of 412018334Speter the structure to the next bit of this element to be processed. 412118334Speter end_offset is the offset of the first bit past the end of 412218334Speter this element. */ 412318334Speter while (next_offset < end_offset) 412418334Speter { 412518334Speter int this_time; 412618334Speter int shift; 412718334Speter HOST_WIDE_INT value; 412890075Sobrien HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT; 412990075Sobrien HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT; 413018334Speter 413118334Speter /* Advance from byte to byte 413218334Speter within this element when necessary. */ 413318334Speter while (next_byte != total_bytes) 413418334Speter { 413590075Sobrien assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1); 413618334Speter total_bytes++; 413718334Speter byte = 0; 413818334Speter } 413918334Speter 414018334Speter /* Number of bits we can process at once 414118334Speter (all part of the same byte). */ 414218334Speter this_time = MIN (end_offset - next_offset, 414318334Speter BITS_PER_UNIT - next_bit); 414418334Speter if (BYTES_BIG_ENDIAN) 414518334Speter { 414618334Speter /* On big-endian machine, take the most significant bits 414718334Speter first (of the bits that are significant) 414818334Speter and put them into bytes from the most significant end. */ 414918334Speter shift = end_offset - next_offset - this_time; 415090075Sobrien 415118334Speter /* Don't try to take a bunch of bits that cross 415290075Sobrien the word boundary in the INTEGER_CST. We can 415390075Sobrien only select bits from the LOW or HIGH part 415490075Sobrien not from both. */ 415518334Speter if (shift < HOST_BITS_PER_WIDE_INT 415618334Speter && shift + this_time > HOST_BITS_PER_WIDE_INT) 415718334Speter { 415890075Sobrien this_time = shift + this_time - HOST_BITS_PER_WIDE_INT; 415918334Speter shift = HOST_BITS_PER_WIDE_INT; 416018334Speter } 416118334Speter 416218334Speter /* Now get the bits from the appropriate constant word. */ 416318334Speter if (shift < HOST_BITS_PER_WIDE_INT) 416490075Sobrien value = TREE_INT_CST_LOW (val); 416518334Speter else if (shift < 2 * HOST_BITS_PER_WIDE_INT) 416618334Speter { 416718334Speter value = TREE_INT_CST_HIGH (val); 416818334Speter shift -= HOST_BITS_PER_WIDE_INT; 416918334Speter } 417018334Speter else 417118334Speter abort (); 417290075Sobrien 417390075Sobrien /* Get the result. This works only when: 417490075Sobrien 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */ 417518334Speter byte |= (((value >> shift) 417690075Sobrien & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1)) 417718334Speter << (BITS_PER_UNIT - this_time - next_bit)); 417818334Speter } 417918334Speter else 418018334Speter { 418118334Speter /* On little-endian machines, 418218334Speter take first the least significant bits of the value 418318334Speter and pack them starting at the least significant 418418334Speter bits of the bytes. */ 418590075Sobrien shift = next_offset - int_bit_position (field); 418690075Sobrien 418718334Speter /* Don't try to take a bunch of bits that cross 418890075Sobrien the word boundary in the INTEGER_CST. We can 418990075Sobrien only select bits from the LOW or HIGH part 419090075Sobrien not from both. */ 419118334Speter if (shift < HOST_BITS_PER_WIDE_INT 419218334Speter && shift + this_time > HOST_BITS_PER_WIDE_INT) 419390075Sobrien this_time = (HOST_BITS_PER_WIDE_INT - shift); 419418334Speter 419518334Speter /* Now get the bits from the appropriate constant word. */ 419650397Sobrien if (shift < HOST_BITS_PER_WIDE_INT) 419718334Speter value = TREE_INT_CST_LOW (val); 419818334Speter else if (shift < 2 * HOST_BITS_PER_WIDE_INT) 419918334Speter { 420018334Speter value = TREE_INT_CST_HIGH (val); 420118334Speter shift -= HOST_BITS_PER_WIDE_INT; 420218334Speter } 420318334Speter else 420418334Speter abort (); 420590075Sobrien 420690075Sobrien /* Get the result. This works only when: 420790075Sobrien 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */ 420818334Speter byte |= (((value >> shift) 420990075Sobrien & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1)) 421018334Speter << next_bit); 421118334Speter } 421290075Sobrien 421318334Speter next_offset += this_time; 421418334Speter byte_buffer_in_use = 1; 421518334Speter } 421618334Speter } 421718334Speter } 421890075Sobrien 421918334Speter if (byte_buffer_in_use) 422018334Speter { 422190075Sobrien assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1); 422218334Speter total_bytes++; 422318334Speter } 422490075Sobrien 4225132718Skan if ((unsigned HOST_WIDE_INT)total_bytes < size) 422618334Speter assemble_zeros (size - total_bytes); 422718334Speter} 422818334Speter 422996263Sobrien/* This TREE_LIST contains any weak symbol declarations waiting 423096263Sobrien to be emitted. */ 4231117395Skanstatic GTY(()) tree weak_decls; 423290075Sobrien 423396263Sobrien/* Mark DECL as weak. */ 423496263Sobrien 423596263Sobrienstatic void 4236132718Skanmark_weak (tree decl) 423790075Sobrien{ 423896263Sobrien DECL_WEAK (decl) = 1; 423990075Sobrien 424096263Sobrien if (DECL_RTL_SET_P (decl) 424196263Sobrien && GET_CODE (DECL_RTL (decl)) == MEM 424296263Sobrien && XEXP (DECL_RTL (decl), 0) 424396263Sobrien && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF) 424496263Sobrien SYMBOL_REF_WEAK (XEXP (DECL_RTL (decl), 0)) = 1; 424596263Sobrien} 4246117395Skan 424796263Sobrien/* Merge weak status between NEWDECL and OLDDECL. */ 424890075Sobrien 424996263Sobrienvoid 4250132718Skanmerge_weak (tree newdecl, tree olddecl) 425118334Speter{ 425296263Sobrien if (DECL_WEAK (newdecl) == DECL_WEAK (olddecl)) 425396263Sobrien return; 425418334Speter 425596263Sobrien if (DECL_WEAK (newdecl)) 425696263Sobrien { 425796263Sobrien tree wd; 4258117395Skan 425996263Sobrien /* NEWDECL is weak, but OLDDECL is not. */ 426018334Speter 426196263Sobrien /* If we already output the OLDDECL, we're in trouble; we can't 426296263Sobrien go back and make it weak. This error cannot caught in 426396263Sobrien declare_weak because the NEWDECL and OLDDECL was not yet 426496263Sobrien been merged; therefore, TREE_ASM_WRITTEN was not set. */ 4265102780Skan if (TREE_ASM_WRITTEN (olddecl)) 4266132718Skan error ("%Jweak declaration of '%D' must precede definition", 4267132718Skan newdecl, newdecl); 4268102780Skan 4269102780Skan /* If we've already generated rtl referencing OLDDECL, we may 4270102780Skan have done so in a way that will not function properly with 4271102780Skan a weak symbol. */ 4272102780Skan else if (TREE_USED (olddecl) 4273102780Skan && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl))) 4274132718Skan warning ("%Jweak declaration of '%D' after first use results " 4275132718Skan "in unspecified behavior", newdecl, newdecl); 4276102780Skan 427796263Sobrien if (SUPPORTS_WEAK) 427896263Sobrien { 427996263Sobrien /* We put the NEWDECL on the weak_decls list at some point. 428096263Sobrien Replace it with the OLDDECL. */ 428196263Sobrien for (wd = weak_decls; wd; wd = TREE_CHAIN (wd)) 428296263Sobrien if (TREE_VALUE (wd) == newdecl) 428396263Sobrien { 428496263Sobrien TREE_VALUE (wd) = olddecl; 428596263Sobrien break; 428696263Sobrien } 428796263Sobrien /* We may not find the entry on the list. If NEWDECL is a 428896263Sobrien weak alias, then we will have already called 428996263Sobrien globalize_decl to remove the entry; in that case, we do 429096263Sobrien not need to do anything. */ 429196263Sobrien } 429252284Sobrien 429396263Sobrien /* Make the OLDDECL weak; it's OLDDECL that we'll be keeping. */ 429496263Sobrien mark_weak (olddecl); 429596263Sobrien } 429696263Sobrien else 429796263Sobrien /* OLDDECL was weak, but NEWDECL was not explicitly marked as 429896263Sobrien weak. Just update NEWDECL to indicate that it's weak too. */ 429996263Sobrien mark_weak (newdecl); 430052284Sobrien} 430118334Speter 430218334Speter/* Declare DECL to be a weak symbol. */ 430318334Speter 430418334Spetervoid 4305132718Skandeclare_weak (tree decl) 430618334Speter{ 430718334Speter if (! TREE_PUBLIC (decl)) 4308132718Skan error ("%Jweak declaration of '%D' must be public", decl, decl); 430996263Sobrien else if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl)) 4310132718Skan error ("%Jweak declaration of '%D' must precede definition", decl, decl); 431118334Speter else if (SUPPORTS_WEAK) 431296263Sobrien { 431396263Sobrien if (! DECL_WEAK (decl)) 431496263Sobrien weak_decls = tree_cons (NULL, decl, weak_decls); 431596263Sobrien } 431690075Sobrien else 4317132718Skan warning ("%Jweak declaration of '%D' not supported", decl, decl); 431890075Sobrien 431996263Sobrien mark_weak (decl); 432018334Speter} 432118334Speter 432218334Speter/* Emit any pending weak declarations. */ 432318334Speter 432418334Spetervoid 4325132718Skanweak_finish (void) 432618334Speter{ 432796263Sobrien tree t; 432896263Sobrien 4329117395Skan for (t = weak_decls; t; t = TREE_CHAIN (t)) 433018334Speter { 433196263Sobrien tree decl = TREE_VALUE (t); 4332132718Skan#if defined (ASM_WEAKEN_DECL) || defined (ASM_WEAKEN_LABEL) 4333132718Skan const char *const name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 4334132718Skan#endif 433596263Sobrien 433696263Sobrien if (! TREE_USED (decl)) 433796263Sobrien continue; 433896263Sobrien 433996263Sobrien#ifdef ASM_WEAKEN_DECL 434096263Sobrien ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL); 434190075Sobrien#else 434290075Sobrien#ifdef ASM_WEAKEN_LABEL 434396263Sobrien ASM_WEAKEN_LABEL (asm_out_file, name); 434496263Sobrien#else 434596263Sobrien#ifdef ASM_OUTPUT_WEAK_ALIAS 434696263Sobrien warning ("only weak aliases are supported in this configuration"); 434796263Sobrien return; 434890075Sobrien#endif 434990075Sobrien#endif 435096263Sobrien#endif 435118334Speter } 435218334Speter} 435318334Speter 435496263Sobrien/* Emit the assembly bits to indicate that DECL is globally visible. */ 435596263Sobrien 435652284Sobrienstatic void 4357132718Skanglobalize_decl (tree decl) 435852284Sobrien{ 435996263Sobrien const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0); 436090075Sobrien 436196263Sobrien#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) 436296263Sobrien if (DECL_WEAK (decl)) 436352284Sobrien { 436496263Sobrien tree *p, t; 436596263Sobrien 436696263Sobrien#ifdef ASM_WEAKEN_DECL 436796263Sobrien ASM_WEAKEN_DECL (asm_out_file, decl, name, 0); 436896263Sobrien#else 436996263Sobrien ASM_WEAKEN_LABEL (asm_out_file, name); 437096263Sobrien#endif 437196263Sobrien 437296263Sobrien /* Remove this function from the pending weak list so that 437396263Sobrien we do not emit multiple .weak directives for it. */ 437496263Sobrien for (p = &weak_decls; (t = *p) ; ) 437596263Sobrien { 437696263Sobrien if (DECL_ASSEMBLER_NAME (decl) == DECL_ASSEMBLER_NAME (TREE_VALUE (t))) 437796263Sobrien *p = TREE_CHAIN (t); 437896263Sobrien else 437996263Sobrien p = &TREE_CHAIN (t); 438096263Sobrien } 438196263Sobrien return; 438252284Sobrien } 438396263Sobrien#endif 438496263Sobrien 4385117395Skan (*targetm.asm_out.globalize_label) (asm_out_file, name); 438652284Sobrien} 438752284Sobrien 438890075Sobrien/* Emit an assembler directive to make the symbol for DECL an alias to 438990075Sobrien the symbol for TARGET. */ 439090075Sobrien 439118334Spetervoid 4392132718Skanassemble_alias (tree decl, tree target ATTRIBUTE_UNUSED) 439318334Speter{ 439490075Sobrien const char *name; 439518334Speter 439690075Sobrien /* We must force creation of DECL_RTL for debug info generation, even though 439790075Sobrien we don't use it here. */ 439890075Sobrien make_decl_rtl (decl, NULL); 439918334Speter 440090075Sobrien name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 440190075Sobrien 440250397Sobrien#ifdef ASM_OUTPUT_DEF 440318334Speter /* Make name accessible from other files, if appropriate. */ 4404117395Skan 440518334Speter if (TREE_PUBLIC (decl)) 4406117395Skan { 4407117395Skan globalize_decl (decl); 4408117395Skan maybe_assemble_visibility (decl); 4409117395Skan } 441018334Speter 441190075Sobrien#ifdef ASM_OUTPUT_DEF_FROM_DECLS 441290075Sobrien ASM_OUTPUT_DEF_FROM_DECLS (asm_out_file, decl, target); 441390075Sobrien#else 441418334Speter ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target)); 441590075Sobrien#endif 441696263Sobrien#else /* !ASM_OUTPUT_DEF */ 441796263Sobrien#if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL) 4418132718Skan if (DECL_WEAK (decl)) 4419132718Skan { 4420132718Skan tree *p, t; 442196263Sobrien#ifdef ASM_WEAKEN_DECL 4422132718Skan ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target)); 442396263Sobrien#else 4424132718Skan ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target)); 442596263Sobrien#endif 4426132718Skan /* Remove this function from the pending weak list so that 4427132718Skan we do not emit multiple .weak directives for it. */ 4428132718Skan for (p = &weak_decls; (t = *p) ; ) 4429132718Skan if (DECL_ASSEMBLER_NAME (decl) 4430132718Skan == DECL_ASSEMBLER_NAME (TREE_VALUE (t))) 4431132718Skan *p = TREE_CHAIN (t); 4432132718Skan else 4433132718Skan p = &TREE_CHAIN (t); 4434132718Skan } 4435132718Skan else 4436132718Skan warning ("only weak aliases are supported in this configuration"); 4437132718Skan 443850397Sobrien#else 443950397Sobrien warning ("alias definitions not supported in this configuration; ignored"); 444018334Speter#endif 444150397Sobrien#endif 4442102780Skan 4443102780Skan TREE_USED (decl) = 1; 4444102780Skan TREE_ASM_WRITTEN (decl) = 1; 4445102780Skan TREE_ASM_WRITTEN (DECL_ASSEMBLER_NAME (decl)) = 1; 444618334Speter} 444750397Sobrien 4448117395Skan/* Emit an assembler directive to set symbol for DECL visibility to 4449117395Skan the visibility type VIS, which must not be VISIBILITY_DEFAULT. */ 4450117395Skan 4451117395Skanvoid 4452132718Skandefault_assemble_visibility (tree decl, int vis) 4453117395Skan{ 4454117395Skan static const char * const visibility_types[] = { 4455117395Skan NULL, "internal", "hidden", "protected" 4456117395Skan }; 4457117395Skan 4458117395Skan const char *name, *type; 4459117395Skan 4460117395Skan name = (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); 4461117395Skan type = visibility_types[vis]; 4462117395Skan 4463117395Skan#ifdef HAVE_GAS_HIDDEN 4464117395Skan fprintf (asm_out_file, "\t.%s\t", type); 4465117395Skan assemble_name (asm_out_file, name); 4466117395Skan fprintf (asm_out_file, "\n"); 4467117395Skan#else 4468117395Skan warning ("visibility attribute not supported in this configuration; ignored"); 4469117395Skan#endif 4470117395Skan} 4471117395Skan 4472117395Skan/* A helper function to call assemble_visibility when needed for a decl. */ 4473117395Skan 4474117395Skanstatic void 4475132718Skanmaybe_assemble_visibility (tree decl) 4476117395Skan{ 4477132718Skan enum symbol_visibility vis = DECL_VISIBILITY (decl); 4478117395Skan 4479117395Skan if (vis != VISIBILITY_DEFAULT) 4480117395Skan (* targetm.asm_out.visibility) (decl, vis); 4481117395Skan} 4482117395Skan 448350397Sobrien/* Returns 1 if the target configuration supports defining public symbols 448450397Sobrien so that one of them will be chosen at link time instead of generating a 448550397Sobrien multiply-defined symbol error, whether through the use of weak symbols or 448650397Sobrien a target-specific mechanism for having duplicates discarded. */ 448750397Sobrien 448850397Sobrienint 4489132718Skansupports_one_only (void) 449050397Sobrien{ 449150397Sobrien if (SUPPORTS_ONE_ONLY) 449250397Sobrien return 1; 449350397Sobrien return SUPPORTS_WEAK; 449450397Sobrien} 449550397Sobrien 449650397Sobrien/* Set up DECL as a public symbol that can be defined in multiple 449750397Sobrien translation units without generating a linker error. */ 449850397Sobrien 449950397Sobrienvoid 4500132718Skanmake_decl_one_only (tree decl) 450150397Sobrien{ 450250397Sobrien if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) 450350397Sobrien abort (); 450450397Sobrien 450550397Sobrien TREE_PUBLIC (decl) = 1; 450650397Sobrien 4507132718Skan if (SUPPORTS_ONE_ONLY) 450850397Sobrien { 450950397Sobrien#ifdef MAKE_DECL_ONE_ONLY 451050397Sobrien MAKE_DECL_ONE_ONLY (decl); 451150397Sobrien#endif 451250397Sobrien DECL_ONE_ONLY (decl) = 1; 451350397Sobrien } 4514132718Skan else if (TREE_CODE (decl) == VAR_DECL 4515132718Skan && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node)) 4516132718Skan DECL_COMMON (decl) = 1; 451750397Sobrien else if (SUPPORTS_WEAK) 451850397Sobrien DECL_WEAK (decl) = 1; 451950397Sobrien else 452050397Sobrien abort (); 452150397Sobrien} 452290075Sobrien 452390075Sobrienvoid 4524132718Skaninit_varasm_once (void) 452590075Sobrien{ 4526132718Skan in_named_htab = htab_create_ggc (31, in_named_entry_hash, 4527132718Skan in_named_entry_eq, NULL); 4528132718Skan const_desc_htab = htab_create_ggc (1009, const_desc_hash, 4529132718Skan const_desc_eq, NULL); 453090075Sobrien 453190075Sobrien const_alias_set = new_alias_set (); 453290075Sobrien} 453390075Sobrien 4534117395Skanenum tls_model 4535132718Skandecl_tls_model (tree decl) 4536117395Skan{ 4537117395Skan enum tls_model kind; 4538117395Skan tree attr = lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl)); 4539117395Skan bool is_local; 4540117395Skan 4541117395Skan if (attr) 4542117395Skan { 4543117395Skan attr = TREE_VALUE (TREE_VALUE (attr)); 4544117395Skan if (TREE_CODE (attr) != STRING_CST) 4545117395Skan abort (); 4546117395Skan if (!strcmp (TREE_STRING_POINTER (attr), "local-exec")) 4547117395Skan kind = TLS_MODEL_LOCAL_EXEC; 4548117395Skan else if (!strcmp (TREE_STRING_POINTER (attr), "initial-exec")) 4549117395Skan kind = TLS_MODEL_INITIAL_EXEC; 4550117395Skan else if (!strcmp (TREE_STRING_POINTER (attr), "local-dynamic")) 4551117395Skan kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC; 4552117395Skan else if (!strcmp (TREE_STRING_POINTER (attr), "global-dynamic")) 4553117395Skan kind = TLS_MODEL_GLOBAL_DYNAMIC; 4554117395Skan else 4555117395Skan abort (); 4556117395Skan return kind; 4557117395Skan } 4558117395Skan 4559117395Skan is_local = (*targetm.binds_local_p) (decl); 4560117395Skan if (!flag_pic) 4561117395Skan { 4562117395Skan if (is_local) 4563117395Skan kind = TLS_MODEL_LOCAL_EXEC; 4564117395Skan else 4565117395Skan kind = TLS_MODEL_INITIAL_EXEC; 4566117395Skan } 4567117395Skan /* Local dynamic is inefficient when we're not combining the 4568117395Skan parts of the address. */ 4569117395Skan else if (optimize && is_local) 4570117395Skan kind = TLS_MODEL_LOCAL_DYNAMIC; 4571117395Skan else 4572117395Skan kind = TLS_MODEL_GLOBAL_DYNAMIC; 4573117395Skan if (kind < flag_tls_default) 4574117395Skan kind = flag_tls_default; 4575117395Skan 4576117395Skan return kind; 4577117395Skan} 4578117395Skan 457990075Sobrien/* Select a set of attributes for section NAME based on the properties 458090075Sobrien of DECL and whether or not RELOC indicates that DECL's initializer 458190075Sobrien might contain runtime relocations. 458290075Sobrien 458390075Sobrien We make the section read-only and executable for a function decl, 458490075Sobrien read-only for a const data decl, and writable for a non-const data decl. */ 458590075Sobrien 458690075Sobrienunsigned int 4587132718Skandefault_section_type_flags (tree decl, const char *name, int reloc) 458890075Sobrien{ 4589117395Skan return default_section_type_flags_1 (decl, name, reloc, flag_pic); 4590117395Skan} 4591117395Skan 4592117395Skanunsigned int 4593132718Skandefault_section_type_flags_1 (tree decl, const char *name, int reloc, 4594132718Skan int shlib) 4595117395Skan{ 459690075Sobrien unsigned int flags; 459790075Sobrien 459890075Sobrien if (decl && TREE_CODE (decl) == FUNCTION_DECL) 459990075Sobrien flags = SECTION_CODE; 4600117395Skan else if (decl && decl_readonly_section_1 (decl, reloc, shlib)) 460190075Sobrien flags = 0; 460290075Sobrien else 460390075Sobrien flags = SECTION_WRITE; 460490075Sobrien 460590075Sobrien if (decl && DECL_ONE_ONLY (decl)) 460690075Sobrien flags |= SECTION_LINKONCE; 460790075Sobrien 4608117395Skan if (decl && TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) 4609117395Skan flags |= SECTION_TLS | SECTION_WRITE; 4610117395Skan 461190075Sobrien if (strcmp (name, ".bss") == 0 461290075Sobrien || strncmp (name, ".bss.", 5) == 0 461390075Sobrien || strncmp (name, ".gnu.linkonce.b.", 16) == 0 461490075Sobrien || strcmp (name, ".sbss") == 0 461590075Sobrien || strncmp (name, ".sbss.", 6) == 0 4616117395Skan || strncmp (name, ".gnu.linkonce.sb.", 17) == 0 4617117395Skan || strcmp (name, ".tbss") == 0 4618117395Skan || strncmp (name, ".gnu.linkonce.tb.", 17) == 0) 461990075Sobrien flags |= SECTION_BSS; 462090075Sobrien 4621117395Skan if (strcmp (name, ".tdata") == 0 4622117395Skan || strcmp (name, ".tbss") == 0 4623117395Skan || strncmp (name, ".gnu.linkonce.td.", 17) == 0 4624117395Skan || strncmp (name, ".gnu.linkonce.tb.", 17) == 0) 4625117395Skan flags |= SECTION_TLS; 4626117395Skan 4627117395Skan /* These three sections have special ELF types. They are neither 4628117395Skan SHT_PROGBITS nor SHT_NOBITS, so when changing sections we don't 4629117395Skan want to print a section type (@progbits or @nobits). If someone 4630117395Skan is silly enough to emit code or TLS variables to one of these 4631117395Skan sections, then don't handle them specially. */ 4632117395Skan if (!(flags & (SECTION_CODE | SECTION_BSS | SECTION_TLS)) 4633117395Skan && (strcmp (name, ".init_array") == 0 4634117395Skan || strcmp (name, ".fini_array") == 0 4635117395Skan || strcmp (name, ".preinit_array") == 0)) 4636117395Skan flags |= SECTION_NOTYPE; 4637117395Skan 463890075Sobrien return flags; 463990075Sobrien} 464090075Sobrien 464190075Sobrien/* Output assembly to switch to section NAME with attribute FLAGS. 464290075Sobrien Four variants for common object file formats. */ 464390075Sobrien 464490075Sobrienvoid 4645132718Skandefault_no_named_section (const char *name ATTRIBUTE_UNUSED, 4646132718Skan unsigned int flags ATTRIBUTE_UNUSED) 464790075Sobrien{ 464890075Sobrien /* Some object formats don't support named sections at all. The 464990075Sobrien front-end should already have flagged this as an error. */ 465090075Sobrien abort (); 465190075Sobrien} 465290075Sobrien 465390075Sobrienvoid 4654132718Skandefault_elf_asm_named_section (const char *name, unsigned int flags) 465590075Sobrien{ 465690075Sobrien char flagchars[10], *f = flagchars; 465790075Sobrien 465890075Sobrien if (! named_section_first_declaration (name)) 465990075Sobrien { 466090075Sobrien fprintf (asm_out_file, "\t.section\t%s\n", name); 466190075Sobrien return; 466290075Sobrien } 466390075Sobrien 466490075Sobrien if (!(flags & SECTION_DEBUG)) 466590075Sobrien *f++ = 'a'; 466690075Sobrien if (flags & SECTION_WRITE) 466790075Sobrien *f++ = 'w'; 466890075Sobrien if (flags & SECTION_CODE) 466990075Sobrien *f++ = 'x'; 467090075Sobrien if (flags & SECTION_SMALL) 467190075Sobrien *f++ = 's'; 467290075Sobrien if (flags & SECTION_MERGE) 467390075Sobrien *f++ = 'M'; 467490075Sobrien if (flags & SECTION_STRINGS) 467590075Sobrien *f++ = 'S'; 4676117395Skan if (flags & SECTION_TLS) 4677117395Skan *f++ = 'T'; 467890075Sobrien *f = '\0'; 467990075Sobrien 4680117395Skan fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars); 468190075Sobrien 4682117395Skan if (!(flags & SECTION_NOTYPE)) 4683117395Skan { 4684117395Skan const char *type; 4685117395Skan 4686117395Skan if (flags & SECTION_BSS) 4687117395Skan type = "nobits"; 4688117395Skan else 4689117395Skan type = "progbits"; 4690117395Skan 4691117395Skan fprintf (asm_out_file, ",@%s", type); 4692117395Skan 4693117395Skan if (flags & SECTION_ENTSIZE) 4694117395Skan fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE); 4695117395Skan } 4696117395Skan 4697117395Skan putc ('\n', asm_out_file); 469890075Sobrien} 469990075Sobrien 470090075Sobrienvoid 4701132718Skandefault_coff_asm_named_section (const char *name, unsigned int flags) 470290075Sobrien{ 470390075Sobrien char flagchars[8], *f = flagchars; 470490075Sobrien 470590075Sobrien if (flags & SECTION_WRITE) 470690075Sobrien *f++ = 'w'; 470790075Sobrien if (flags & SECTION_CODE) 470890075Sobrien *f++ = 'x'; 470990075Sobrien *f = '\0'; 471090075Sobrien 471190075Sobrien fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars); 471290075Sobrien} 471390075Sobrien 471490075Sobrienvoid 4715132718Skandefault_pe_asm_named_section (const char *name, unsigned int flags) 471690075Sobrien{ 471790075Sobrien default_coff_asm_named_section (name, flags); 471890075Sobrien 471990075Sobrien if (flags & SECTION_LINKONCE) 472090075Sobrien { 472190075Sobrien /* Functions may have been compiled at various levels of 472290075Sobrien optimization so we can't use `same_size' here. 472390075Sobrien Instead, have the linker pick one. */ 472490075Sobrien fprintf (asm_out_file, "\t.linkonce %s\n", 472590075Sobrien (flags & SECTION_CODE ? "discard" : "same_size")); 472690075Sobrien } 472790075Sobrien} 472890075Sobrien 4729117395Skan/* The lame default section selector. */ 4730117395Skan 4731117395Skanvoid 4732132718Skandefault_select_section (tree decl, int reloc, 4733132718Skan unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) 4734117395Skan{ 4735117395Skan bool readonly = false; 4736117395Skan 4737117395Skan if (DECL_P (decl)) 4738117395Skan { 4739117395Skan if (decl_readonly_section (decl, reloc)) 4740117395Skan readonly = true; 4741117395Skan } 4742117395Skan else if (TREE_CODE (decl) == CONSTRUCTOR) 4743117395Skan { 4744117395Skan if (! ((flag_pic && reloc) 4745117395Skan || !TREE_READONLY (decl) 4746117395Skan || TREE_SIDE_EFFECTS (decl) 4747117395Skan || !TREE_CONSTANT (decl))) 4748117395Skan readonly = true; 4749117395Skan } 4750117395Skan else if (TREE_CODE (decl) == STRING_CST) 4751117395Skan readonly = !flag_writable_strings; 4752117395Skan else if (! (flag_pic && reloc)) 4753117395Skan readonly = true; 4754117395Skan 4755117395Skan if (readonly) 4756117395Skan readonly_data_section (); 4757117395Skan else 4758117395Skan data_section (); 4759117395Skan} 4760117395Skan 4761117395Skan/* A helper function for default_elf_select_section and 4762117395Skan default_elf_unique_section. Categorizes the DECL. */ 4763117395Skan 4764117395Skanenum section_category 4765117395Skan{ 4766117395Skan SECCAT_TEXT, 4767117395Skan 4768117395Skan SECCAT_RODATA, 4769117395Skan SECCAT_RODATA_MERGE_STR, 4770117395Skan SECCAT_RODATA_MERGE_STR_INIT, 4771117395Skan SECCAT_RODATA_MERGE_CONST, 4772117395Skan SECCAT_SRODATA, 4773117395Skan 4774117395Skan SECCAT_DATA, 4775117395Skan 4776117395Skan /* To optimize loading of shared programs, define following subsections 4777117395Skan of data section: 4778117395Skan _REL Contains data that has relocations, so they get grouped 4779117395Skan together and dynamic linker will visit fewer pages in memory. 4780117395Skan _RO Contains data that is otherwise read-only. This is useful 4781117395Skan with prelinking as most relocations won't be dynamically 4782117395Skan linked and thus stay read only. 4783117395Skan _LOCAL Marks data containing relocations only to local objects. 4784117395Skan These relocations will get fully resolved by prelinking. */ 4785117395Skan SECCAT_DATA_REL, 4786117395Skan SECCAT_DATA_REL_LOCAL, 4787117395Skan SECCAT_DATA_REL_RO, 4788117395Skan SECCAT_DATA_REL_RO_LOCAL, 4789117395Skan 4790117395Skan SECCAT_SDATA, 4791117395Skan SECCAT_TDATA, 4792117395Skan 4793117395Skan SECCAT_BSS, 4794117395Skan SECCAT_SBSS, 4795117395Skan SECCAT_TBSS 4796117395Skan}; 4797117395Skan 4798117395Skanstatic enum section_category 4799132718Skancategorize_decl_for_section (tree, int, int); 4800117395Skan 4801117395Skanstatic enum section_category 4802132718Skancategorize_decl_for_section (tree decl, int reloc, int shlib) 4803117395Skan{ 4804117395Skan enum section_category ret; 4805117395Skan 4806117395Skan if (TREE_CODE (decl) == FUNCTION_DECL) 4807117395Skan return SECCAT_TEXT; 4808117395Skan else if (TREE_CODE (decl) == STRING_CST) 4809117395Skan { 4810117395Skan if (flag_writable_strings) 4811117395Skan return SECCAT_DATA; 4812117395Skan else 4813117395Skan return SECCAT_RODATA_MERGE_STR; 4814117395Skan } 4815117395Skan else if (TREE_CODE (decl) == VAR_DECL) 4816117395Skan { 4817117395Skan if (DECL_INITIAL (decl) == NULL 4818117395Skan || DECL_INITIAL (decl) == error_mark_node) 4819117395Skan ret = SECCAT_BSS; 4820117395Skan else if (! TREE_READONLY (decl) 4821117395Skan || TREE_SIDE_EFFECTS (decl) 4822117395Skan || ! TREE_CONSTANT (DECL_INITIAL (decl))) 4823117395Skan { 4824117395Skan if (shlib && (reloc & 2)) 4825117395Skan ret = SECCAT_DATA_REL; 4826117395Skan else if (shlib && reloc) 4827117395Skan ret = SECCAT_DATA_REL_LOCAL; 4828117395Skan else 4829117395Skan ret = SECCAT_DATA; 4830117395Skan } 4831117395Skan else if (shlib && (reloc & 2)) 4832117395Skan ret = SECCAT_DATA_REL_RO; 4833117395Skan else if (shlib && reloc) 4834117395Skan ret = SECCAT_DATA_REL_RO_LOCAL; 4835117395Skan else if (reloc || flag_merge_constants < 2) 4836117395Skan /* C and C++ don't allow different variables to share the same 4837117395Skan location. -fmerge-all-constants allows even that (at the 4838117395Skan expense of not conforming). */ 4839117395Skan ret = SECCAT_RODATA; 4840117395Skan else if (TREE_CODE (DECL_INITIAL (decl)) == STRING_CST) 4841117395Skan ret = SECCAT_RODATA_MERGE_STR_INIT; 4842117395Skan else 4843117395Skan ret = SECCAT_RODATA_MERGE_CONST; 4844117395Skan } 4845117395Skan else if (TREE_CODE (decl) == CONSTRUCTOR) 4846117395Skan { 4847117395Skan if ((shlib && reloc) 4848117395Skan || TREE_SIDE_EFFECTS (decl) 4849117395Skan || ! TREE_CONSTANT (decl)) 4850117395Skan ret = SECCAT_DATA; 4851117395Skan else 4852117395Skan ret = SECCAT_RODATA; 4853117395Skan } 4854117395Skan else 4855117395Skan ret = SECCAT_RODATA; 4856117395Skan 4857117395Skan /* There are no read-only thread-local sections. */ 4858117395Skan if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) 4859117395Skan { 4860117395Skan if (ret == SECCAT_BSS) 4861117395Skan ret = SECCAT_TBSS; 4862117395Skan else 4863117395Skan ret = SECCAT_TDATA; 4864117395Skan } 4865117395Skan 4866117395Skan /* If the target uses small data sections, select it. */ 4867117395Skan else if ((*targetm.in_small_data_p) (decl)) 4868117395Skan { 4869117395Skan if (ret == SECCAT_BSS) 4870117395Skan ret = SECCAT_SBSS; 4871117395Skan else if (targetm.have_srodata_section && ret == SECCAT_RODATA) 4872117395Skan ret = SECCAT_SRODATA; 4873117395Skan else 4874117395Skan ret = SECCAT_SDATA; 4875117395Skan } 4876117395Skan 4877117395Skan return ret; 4878117395Skan} 4879117395Skan 4880117395Skanbool 4881132718Skandecl_readonly_section (tree decl, int reloc) 4882117395Skan{ 4883117395Skan return decl_readonly_section_1 (decl, reloc, flag_pic); 4884117395Skan} 4885117395Skan 4886117395Skanbool 4887132718Skandecl_readonly_section_1 (tree decl, int reloc, int shlib) 4888117395Skan{ 4889117395Skan switch (categorize_decl_for_section (decl, reloc, shlib)) 4890117395Skan { 4891117395Skan case SECCAT_RODATA: 4892117395Skan case SECCAT_RODATA_MERGE_STR: 4893117395Skan case SECCAT_RODATA_MERGE_STR_INIT: 4894117395Skan case SECCAT_RODATA_MERGE_CONST: 4895117395Skan case SECCAT_SRODATA: 4896117395Skan return true; 4897117395Skan break; 4898117395Skan default: 4899117395Skan return false; 4900117395Skan break; 4901117395Skan } 4902117395Skan} 4903117395Skan 4904117395Skan/* Select a section based on the above categorization. */ 4905117395Skan 4906117395Skanvoid 4907132718Skandefault_elf_select_section (tree decl, int reloc, 4908132718Skan unsigned HOST_WIDE_INT align) 4909117395Skan{ 4910117395Skan default_elf_select_section_1 (decl, reloc, align, flag_pic); 4911117395Skan} 4912117395Skan 4913117395Skanvoid 4914132718Skandefault_elf_select_section_1 (tree decl, int reloc, 4915132718Skan unsigned HOST_WIDE_INT align, int shlib) 4916117395Skan{ 4917117395Skan switch (categorize_decl_for_section (decl, reloc, shlib)) 4918117395Skan { 4919117395Skan case SECCAT_TEXT: 4920117395Skan /* We're not supposed to be called on FUNCTION_DECLs. */ 4921117395Skan abort (); 4922117395Skan case SECCAT_RODATA: 4923117395Skan readonly_data_section (); 4924117395Skan break; 4925117395Skan case SECCAT_RODATA_MERGE_STR: 4926117395Skan mergeable_string_section (decl, align, 0); 4927117395Skan break; 4928117395Skan case SECCAT_RODATA_MERGE_STR_INIT: 4929117395Skan mergeable_string_section (DECL_INITIAL (decl), align, 0); 4930117395Skan break; 4931117395Skan case SECCAT_RODATA_MERGE_CONST: 4932117395Skan mergeable_constant_section (DECL_MODE (decl), align, 0); 4933117395Skan break; 4934117395Skan case SECCAT_SRODATA: 4935117395Skan named_section (NULL_TREE, ".sdata2", reloc); 4936117395Skan break; 4937117395Skan case SECCAT_DATA: 4938117395Skan data_section (); 4939117395Skan break; 4940117395Skan case SECCAT_DATA_REL: 4941117395Skan named_section (NULL_TREE, ".data.rel", reloc); 4942117395Skan break; 4943117395Skan case SECCAT_DATA_REL_LOCAL: 4944117395Skan named_section (NULL_TREE, ".data.rel.local", reloc); 4945117395Skan break; 4946117395Skan case SECCAT_DATA_REL_RO: 4947117395Skan named_section (NULL_TREE, ".data.rel.ro", reloc); 4948117395Skan break; 4949117395Skan case SECCAT_DATA_REL_RO_LOCAL: 4950117395Skan named_section (NULL_TREE, ".data.rel.ro.local", reloc); 4951117395Skan break; 4952117395Skan case SECCAT_SDATA: 4953117395Skan named_section (NULL_TREE, ".sdata", reloc); 4954117395Skan break; 4955117395Skan case SECCAT_TDATA: 4956117395Skan named_section (NULL_TREE, ".tdata", reloc); 4957117395Skan break; 4958117395Skan case SECCAT_BSS: 4959117395Skan#ifdef BSS_SECTION_ASM_OP 4960117395Skan bss_section (); 4961117395Skan#else 4962117395Skan named_section (NULL_TREE, ".bss", reloc); 4963117395Skan#endif 4964117395Skan break; 4965117395Skan case SECCAT_SBSS: 4966117395Skan named_section (NULL_TREE, ".sbss", reloc); 4967117395Skan break; 4968117395Skan case SECCAT_TBSS: 4969117395Skan named_section (NULL_TREE, ".tbss", reloc); 4970117395Skan break; 4971117395Skan default: 4972117395Skan abort (); 4973117395Skan } 4974117395Skan} 4975117395Skan 4976117395Skan/* Construct a unique section name based on the decl name and the 4977117395Skan categorization performed above. */ 4978117395Skan 4979117395Skanvoid 4980132718Skandefault_unique_section (tree decl, int reloc) 4981117395Skan{ 4982117395Skan default_unique_section_1 (decl, reloc, flag_pic); 4983117395Skan} 4984117395Skan 4985117395Skanvoid 4986132718Skandefault_unique_section_1 (tree decl, int reloc, int shlib) 4987117395Skan{ 4988117395Skan bool one_only = DECL_ONE_ONLY (decl); 4989117395Skan const char *prefix, *name; 4990117395Skan size_t nlen, plen; 4991117395Skan char *string; 4992117395Skan 4993117395Skan switch (categorize_decl_for_section (decl, reloc, shlib)) 4994117395Skan { 4995117395Skan case SECCAT_TEXT: 4996117395Skan prefix = one_only ? ".gnu.linkonce.t." : ".text."; 4997117395Skan break; 4998117395Skan case SECCAT_RODATA: 4999117395Skan case SECCAT_RODATA_MERGE_STR: 5000117395Skan case SECCAT_RODATA_MERGE_STR_INIT: 5001117395Skan case SECCAT_RODATA_MERGE_CONST: 5002117395Skan prefix = one_only ? ".gnu.linkonce.r." : ".rodata."; 5003117395Skan break; 5004117395Skan case SECCAT_SRODATA: 5005117395Skan prefix = one_only ? ".gnu.linkonce.s2." : ".sdata2."; 5006117395Skan break; 5007117395Skan case SECCAT_DATA: 5008117395Skan case SECCAT_DATA_REL: 5009117395Skan case SECCAT_DATA_REL_LOCAL: 5010117395Skan case SECCAT_DATA_REL_RO: 5011117395Skan case SECCAT_DATA_REL_RO_LOCAL: 5012117395Skan prefix = one_only ? ".gnu.linkonce.d." : ".data."; 5013117395Skan break; 5014117395Skan case SECCAT_SDATA: 5015117395Skan prefix = one_only ? ".gnu.linkonce.s." : ".sdata."; 5016117395Skan break; 5017117395Skan case SECCAT_BSS: 5018117395Skan prefix = one_only ? ".gnu.linkonce.b." : ".bss."; 5019117395Skan break; 5020117395Skan case SECCAT_SBSS: 5021117395Skan prefix = one_only ? ".gnu.linkonce.sb." : ".sbss."; 5022117395Skan break; 5023117395Skan case SECCAT_TDATA: 5024117395Skan prefix = one_only ? ".gnu.linkonce.td." : ".tdata."; 5025117395Skan break; 5026117395Skan case SECCAT_TBSS: 5027117395Skan prefix = one_only ? ".gnu.linkonce.tb." : ".tbss."; 5028117395Skan break; 5029117395Skan default: 5030117395Skan abort (); 5031117395Skan } 5032117395Skan plen = strlen (prefix); 5033117395Skan 5034117395Skan name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 5035117395Skan name = (* targetm.strip_name_encoding) (name); 5036117395Skan nlen = strlen (name); 5037117395Skan 5038117395Skan string = alloca (nlen + plen + 1); 5039117395Skan memcpy (string, prefix, plen); 5040117395Skan memcpy (string + plen, name, nlen + 1); 5041117395Skan 5042117395Skan DECL_SECTION_NAME (decl) = build_string (nlen + plen, string); 5043117395Skan} 5044117395Skan 5045117395Skanvoid 5046132718Skandefault_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED, 5047132718Skan rtx x, 5048132718Skan unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) 5049117395Skan{ 5050117395Skan if (flag_pic) 5051117395Skan switch (GET_CODE (x)) 5052117395Skan { 5053117395Skan case CONST: 5054117395Skan case SYMBOL_REF: 5055117395Skan case LABEL_REF: 5056117395Skan data_section (); 5057117395Skan return; 5058117395Skan 5059117395Skan default: 5060117395Skan break; 5061117395Skan } 5062117395Skan 5063117395Skan readonly_data_section (); 5064117395Skan} 5065117395Skan 5066117395Skanvoid 5067132718Skandefault_elf_select_rtx_section (enum machine_mode mode, rtx x, 5068132718Skan unsigned HOST_WIDE_INT align) 5069117395Skan{ 5070117395Skan /* ??? Handle small data here somehow. */ 5071117395Skan 5072117395Skan if (flag_pic) 5073117395Skan switch (GET_CODE (x)) 5074117395Skan { 5075117395Skan case CONST: 5076117395Skan case SYMBOL_REF: 5077117395Skan named_section (NULL_TREE, ".data.rel.ro", 3); 5078117395Skan return; 5079117395Skan 5080117395Skan case LABEL_REF: 5081117395Skan named_section (NULL_TREE, ".data.rel.ro.local", 1); 5082117395Skan return; 5083117395Skan 5084117395Skan default: 5085117395Skan break; 5086117395Skan } 5087117395Skan 5088117395Skan mergeable_constant_section (mode, align, 0); 5089117395Skan} 5090117395Skan 5091132718Skan/* Set the generally applicable flags on the SYMBOL_REF for EXP. */ 5092132718Skan 5093132718Skanvoid 5094132718Skandefault_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED) 5095132718Skan{ 5096132718Skan rtx symbol; 5097132718Skan int flags; 5098132718Skan 5099132718Skan /* Careful not to prod global register variables. */ 5100132718Skan if (GET_CODE (rtl) != MEM) 5101132718Skan return; 5102132718Skan symbol = XEXP (rtl, 0); 5103132718Skan if (GET_CODE (symbol) != SYMBOL_REF) 5104132718Skan return; 5105132718Skan 5106132718Skan flags = 0; 5107132718Skan if (TREE_CODE (decl) == FUNCTION_DECL) 5108132718Skan flags |= SYMBOL_FLAG_FUNCTION; 5109132718Skan if ((*targetm.binds_local_p) (decl)) 5110132718Skan flags |= SYMBOL_FLAG_LOCAL; 5111132718Skan if ((*targetm.in_small_data_p) (decl)) 5112132718Skan flags |= SYMBOL_FLAG_SMALL; 5113132718Skan if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) 5114132718Skan flags |= decl_tls_model (decl) << SYMBOL_FLAG_TLS_SHIFT; 5115132718Skan /* ??? Why is DECL_EXTERNAL ever set for non-PUBLIC names? Without 5116132718Skan being PUBLIC, the thing *must* be defined in this translation unit. 5117132718Skan Prevent this buglet from being propagated into rtl code as well. */ 5118132718Skan if (DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)) 5119132718Skan flags |= SYMBOL_FLAG_EXTERNAL; 5120132718Skan 5121132718Skan SYMBOL_REF_FLAGS (symbol) = flags; 5122132718Skan} 5123132718Skan 5124117395Skan/* By default, we do nothing for encode_section_info, so we need not 5125117395Skan do anything but discard the '*' marker. */ 5126117395Skan 5127117395Skanconst char * 5128132718Skandefault_strip_name_encoding (const char *str) 5129117395Skan{ 5130117395Skan return str + (*str == '*'); 5131117395Skan} 5132117395Skan 5133117395Skan/* Assume ELF-ish defaults, since that's pretty much the most liberal 5134117395Skan wrt cross-module name binding. */ 5135117395Skan 5136117395Skanbool 5137132718Skandefault_binds_local_p (tree exp) 5138117395Skan{ 5139132718Skan return default_binds_local_p_1 (exp, flag_shlib); 5140117395Skan} 5141117395Skan 5142117395Skanbool 5143132718Skandefault_binds_local_p_1 (tree exp, int shlib) 5144117395Skan{ 5145117395Skan bool local_p; 5146117395Skan 5147117395Skan /* A non-decl is an entry in the constant pool. */ 5148117395Skan if (!DECL_P (exp)) 5149117395Skan local_p = true; 5150117395Skan /* Static variables are always local. */ 5151117395Skan else if (! TREE_PUBLIC (exp)) 5152117395Skan local_p = true; 5153117395Skan /* A variable is local if the user tells us so. */ 5154132718Skan else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) 5155117395Skan local_p = true; 5156117395Skan /* Otherwise, variables defined outside this object may not be local. */ 5157117395Skan else if (DECL_EXTERNAL (exp)) 5158117395Skan local_p = false; 5159117395Skan /* Linkonce and weak data are never local. */ 5160117395Skan else if (DECL_ONE_ONLY (exp) || DECL_WEAK (exp)) 5161117395Skan local_p = false; 5162117395Skan /* If PIC, then assume that any global name can be overridden by 5163117395Skan symbols resolved from other modules. */ 5164117395Skan else if (shlib) 5165117395Skan local_p = false; 5166117395Skan /* Uninitialized COMMON variable may be unified with symbols 5167117395Skan resolved from other modules. */ 5168117395Skan else if (DECL_COMMON (exp) 5169117395Skan && (DECL_INITIAL (exp) == NULL 5170117395Skan || DECL_INITIAL (exp) == error_mark_node)) 5171117395Skan local_p = false; 5172117395Skan /* Otherwise we're left with initialized (or non-common) global data 5173117395Skan which is of necessity defined locally. */ 5174117395Skan else 5175117395Skan local_p = true; 5176117395Skan 5177117395Skan return local_p; 5178117395Skan} 5179117395Skan 5180132718Skan/* Determine whether or not a pointer mode is valid. Assume defaults 5181132718Skan of ptr_mode or Pmode - can be overridden. */ 5182132718Skanbool 5183132718Skandefault_valid_pointer_mode (enum machine_mode mode) 5184132718Skan{ 5185132718Skan return (mode == ptr_mode || mode == Pmode); 5186132718Skan} 5187132718Skan 5188117395Skan/* Default function to output code that will globalize a label. A 5189117395Skan target must define GLOBAL_ASM_OP or provide it's own function to 5190117395Skan globalize a label. */ 5191117395Skan#ifdef GLOBAL_ASM_OP 5192117395Skanvoid 5193132718Skandefault_globalize_label (FILE * stream, const char *name) 5194117395Skan{ 5195117395Skan fputs (GLOBAL_ASM_OP, stream); 5196117395Skan assemble_name (stream, name); 5197117395Skan putc ('\n', stream); 5198117395Skan} 5199117395Skan#endif /* GLOBAL_ASM_OP */ 5200132718Skan 5201132718Skan/* This is how to output an internal numbered label where PREFIX is 5202132718Skan the class of label and LABELNO is the number within the class. */ 5203132718Skan 5204132718Skanvoid 5205132718Skandefault_internal_label (FILE *stream, const char *prefix, 5206132718Skan unsigned long labelno) 5207132718Skan{ 5208132718Skan char *const buf = alloca (40 + strlen (prefix)); 5209132718Skan ASM_GENERATE_INTERNAL_LABEL (buf, prefix, labelno); 5210132718Skan ASM_OUTPUT_LABEL (stream, buf); 5211132718Skan} 5212132718Skan 5213132718Skan/* This is the default behavior at the beginning of a file. It's 5214132718Skan controlled by two other target-hook toggles. */ 5215132718Skanvoid 5216132718Skandefault_file_start (void) 5217132718Skan{ 5218132718Skan if (targetm.file_start_app_off && !flag_verbose_asm) 5219132718Skan fputs (ASM_APP_OFF, asm_out_file); 5220132718Skan 5221132718Skan if (targetm.file_start_file_directive) 5222132718Skan output_file_directive (asm_out_file, main_input_filename); 5223132718Skan} 5224132718Skan 5225132718Skan/* This is a generic routine suitable for use as TARGET_ASM_FILE_END 5226132718Skan which emits a special section directive used to indicate whether or 5227132718Skan not this object file needs an executable stack. This is primarily 5228132718Skan a GNU extension to ELF but could be used on other targets. */ 5229132718Skanvoid 5230132718Skanfile_end_indicate_exec_stack (void) 5231132718Skan{ 5232132718Skan unsigned int flags = SECTION_DEBUG; 5233132718Skan if (trampolines_created) 5234132718Skan flags |= SECTION_CODE; 5235132718Skan 5236132718Skan named_section_flags (".note.GNU-stack", flags); 5237132718Skan} 5238132718Skan 5239117395Skan#include "gt-varasm.h" 5240