varasm.c revision 146895
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 2353146895Skan handles the same types of nodes that compare_constant handles. 2354146895Skan Writable string constants are never copied. */ 235518334Speter 235618334Speterstatic tree 2357132718Skancopy_constant (tree exp) 235818334Speter{ 235918334Speter switch (TREE_CODE (exp)) 236018334Speter { 236118334Speter case ADDR_EXPR: 236218334Speter /* For ADDR_EXPR, we do not want to copy the decl whose address 236318334Speter is requested. We do want to copy constants though. */ 236418334Speter if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == 'c') 236518334Speter return build1 (TREE_CODE (exp), TREE_TYPE (exp), 236618334Speter copy_constant (TREE_OPERAND (exp, 0))); 236718334Speter else 236818334Speter return copy_node (exp); 236918334Speter 2370146895Skan case STRING_CST: 2371146895Skan if (flag_writable_strings) 2372146895Skan return exp; 2373146895Skan /* FALLTHROUGH */ 237418334Speter case INTEGER_CST: 237518334Speter case REAL_CST: 237618334Speter return copy_node (exp); 237718334Speter 237818334Speter case COMPLEX_CST: 237950397Sobrien return build_complex (TREE_TYPE (exp), 238050397Sobrien copy_constant (TREE_REALPART (exp)), 238118334Speter copy_constant (TREE_IMAGPART (exp))); 238218334Speter 238318334Speter case PLUS_EXPR: 238418334Speter case MINUS_EXPR: 238518334Speter return build (TREE_CODE (exp), TREE_TYPE (exp), 238618334Speter copy_constant (TREE_OPERAND (exp, 0)), 238718334Speter copy_constant (TREE_OPERAND (exp, 1))); 238818334Speter 238918334Speter case NOP_EXPR: 239018334Speter case CONVERT_EXPR: 239150397Sobrien case NON_LVALUE_EXPR: 2392132718Skan case VIEW_CONVERT_EXPR: 239318334Speter return build1 (TREE_CODE (exp), TREE_TYPE (exp), 239418334Speter copy_constant (TREE_OPERAND (exp, 0))); 239518334Speter 239618334Speter case CONSTRUCTOR: 239718334Speter { 239818334Speter tree copy = copy_node (exp); 239918334Speter tree list = copy_list (CONSTRUCTOR_ELTS (exp)); 240018334Speter tree tail; 240118334Speter 240218334Speter CONSTRUCTOR_ELTS (copy) = list; 240318334Speter for (tail = list; tail; tail = TREE_CHAIN (tail)) 240418334Speter TREE_VALUE (tail) = copy_constant (TREE_VALUE (tail)); 240518334Speter if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE) 240618334Speter for (tail = list; tail; tail = TREE_CHAIN (tail)) 240718334Speter TREE_PURPOSE (tail) = copy_constant (TREE_PURPOSE (tail)); 240818334Speter 240918334Speter return copy; 241018334Speter } 241118334Speter 241218334Speter default: 2413117395Skan { 2414117395Skan tree t; 2415117395Skan t = (*lang_hooks.expand_constant) (exp); 2416117395Skan if (t != exp) 2417117395Skan return copy_constant (t); 2418117395Skan else 2419117395Skan abort (); 2420117395Skan } 242118334Speter } 242218334Speter} 242318334Speter 2424132718Skan/* Subroutine of output_constant_def: 2425132718Skan No constant equal to EXP is known to have been output. 2426132718Skan Make a constant descriptor to enter EXP in the hash table. 2427132718Skan Assign the label number and construct RTL to refer to the 2428132718Skan constant's location in memory. 2429132718Skan Caller is responsible for updating the hash table. */ 243018334Speter 2431132718Skanstatic struct constant_descriptor_tree * 2432132718Skanbuild_constant_desc (tree exp) 243318334Speter{ 2434132718Skan rtx symbol; 2435132718Skan rtx rtl; 2436132718Skan char label[256]; 2437132718Skan int labelno; 2438117395Skan struct constant_descriptor_tree *desc; 243918334Speter 2440132718Skan desc = ggc_alloc (sizeof (*desc)); 2441146895Skan desc->value = copy_constant (exp); 2442122180Skan 2443132718Skan /* Create a string containing the label name, in LABEL. */ 2444132718Skan labelno = const_labelno++; 2445132718Skan ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno); 244618334Speter 2447132718Skan /* We have a symbol name; construct the SYMBOL_REF and the MEM. */ 2448132718Skan symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label)); 2449132718Skan SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL; 2450132718Skan SYMBOL_REF_DECL (symbol) = desc->value; 2451132718Skan TREE_CONSTANT_POOL_ADDRESS_P (symbol) = 1; 245218334Speter 2453132718Skan rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), symbol); 2454132718Skan set_mem_attributes (rtl, exp, 1); 2455132718Skan set_mem_alias_set (rtl, 0); 2456132718Skan set_mem_alias_set (rtl, const_alias_set); 245718334Speter 2458132718Skan /* Set flags or add text to the name to record information, such as 2459132718Skan that it is a local symbol. If the name is changed, the macro 2460132718Skan ASM_OUTPUT_LABELREF will have to know how to strip this 2461132718Skan information. This call might invalidate our local variable 2462132718Skan SYMBOL; we can't use it afterward. */ 246318334Speter 2464132718Skan (*targetm.encode_section_info) (exp, rtl, true); 246590075Sobrien 2466132718Skan desc->rtl = rtl; 246790075Sobrien 2468132718Skan return desc; 2469132718Skan} 247090075Sobrien 2471132718Skan/* Return an rtx representing a reference to constant data in memory 2472132718Skan for the constant expression EXP. 247318334Speter 2474132718Skan If assembler code for such a constant has already been output, 2475132718Skan return an rtx to refer to it. 2476132718Skan Otherwise, output such a constant in memory 2477132718Skan and generate an rtx for it. 247890075Sobrien 2479132718Skan If DEFER is nonzero, this constant can be deferred and output only 2480132718Skan if referenced in the function after all optimizations. 248190075Sobrien 2482132718Skan `const_desc_table' records which constants already have label strings. */ 248390075Sobrien 2484132718Skanrtx 2485132718Skanoutput_constant_def (tree exp, int defer) 2486132718Skan{ 2487132718Skan struct constant_descriptor_tree *desc; 2488132718Skan struct constant_descriptor_tree key; 2489132718Skan void **loc; 249018334Speter 2491132718Skan /* Look up EXP in the table of constant descriptors. If we didn't find 2492132718Skan it, create a new one. */ 2493132718Skan key.value = exp; 2494132718Skan loc = htab_find_slot (const_desc_htab, &key, INSERT); 249518334Speter 2496132718Skan desc = *loc; 2497132718Skan if (desc == 0) 249890075Sobrien { 2499132718Skan desc = build_constant_desc (exp); 2500132718Skan *loc = desc; 250190075Sobrien } 250218334Speter 2503132718Skan maybe_output_constant_def_contents (desc, defer); 2504132718Skan return desc->rtl; 2505132718Skan} 250690075Sobrien 2507132718Skan/* Subroutine of output_constant_def: Decide whether or not we need to 2508132718Skan output the constant DESC now, and if so, do it. */ 2509132718Skanstatic void 2510132718Skanmaybe_output_constant_def_contents (struct constant_descriptor_tree *desc, 2511132718Skan int defer) 2512132718Skan{ 2513132718Skan rtx symbol = XEXP (desc->rtl, 0); 2514132718Skan tree exp = desc->value; 251590075Sobrien 2516132718Skan if (flag_syntax_only) 2517132718Skan return; 251818334Speter 2519132718Skan if (TREE_ASM_WRITTEN (exp)) 2520132718Skan /* Already output; don't do it again. */ 2521132718Skan return; 252290075Sobrien 2523132718Skan /* The only constants that cannot safely be deferred, assuming the 2524132718Skan context allows it, are strings under flag_writable_strings. */ 2525132718Skan if (defer && (TREE_CODE (exp) != STRING_CST || !flag_writable_strings)) 2526132718Skan { 2527132718Skan /* Increment n_deferred_constants if it exists. It needs to be at 2528132718Skan least as large as the number of constants actually referred to 2529132718Skan by the function. If it's too small we'll stop looking too early 2530132718Skan and fail to emit constants; if it's too large we'll only look 2531132718Skan through the entire function when we could have stopped earlier. */ 2532132718Skan if (cfun) 2533132718Skan n_deferred_constants++; 2534132718Skan return; 253518334Speter } 253618334Speter 2537132718Skan output_constant_def_contents (symbol); 253818334Speter} 253918334Speter 2540132718Skan/* We must output the constant data referred to by SYMBOL; do so. */ 254118334Speter 254218334Speterstatic void 2543132718Skanoutput_constant_def_contents (rtx symbol) 254418334Speter{ 2545132718Skan tree exp = SYMBOL_REF_DECL (symbol); 2546132718Skan const char *label = XSTR (symbol, 0); 2547122180Skan HOST_WIDE_INT size; 254818334Speter 2549132718Skan /* Make sure any other constants whose addresses appear in EXP 2550132718Skan are assigned label numbers. */ 2551132718Skan int reloc = compute_reloc_for_constant (exp); 2552132718Skan 255390075Sobrien /* Align the location counter as required by EXP's data type. */ 2554132718Skan int align = TYPE_ALIGN (TREE_TYPE (exp)); 255590075Sobrien#ifdef CONSTANT_ALIGNMENT 255690075Sobrien align = CONSTANT_ALIGNMENT (exp, align); 255790075Sobrien#endif 255890075Sobrien 2559132718Skan output_addressed_constants (exp); 2560132718Skan 2561132718Skan /* We are no longer deferring this constant. */ 2562132718Skan TREE_ASM_WRITTEN (exp) = 1; 2563132718Skan 256418334Speter if (IN_NAMED_SECTION (exp)) 256550397Sobrien named_section (exp, NULL, reloc); 256618334Speter else 2567117395Skan (*targetm.asm_out.select_section) (exp, reloc, align); 256818334Speter 256918334Speter if (align > BITS_PER_UNIT) 257090075Sobrien { 257190075Sobrien ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT)); 257290075Sobrien } 257318334Speter 2574122180Skan size = int_size_in_bytes (TREE_TYPE (exp)); 2575122180Skan if (TREE_CODE (exp) == STRING_CST) 2576122180Skan size = MAX (TREE_STRING_LENGTH (exp), size); 2577122180Skan 2578122180Skan /* Do any machine/system dependent processing of the constant. */ 2579122180Skan#ifdef ASM_DECLARE_CONSTANT_NAME 2580132718Skan ASM_DECLARE_CONSTANT_NAME (asm_out_file, label, exp, size); 2581122180Skan#else 2582122180Skan /* Standard thing is just output label for the constant. */ 2583132718Skan ASM_OUTPUT_LABEL (asm_out_file, label); 2584122180Skan#endif /* ASM_DECLARE_CONSTANT_NAME */ 258518334Speter 258618334Speter /* Output the value of EXP. */ 2587122180Skan output_constant (exp, size, align); 258818334Speter} 2589132718Skan 2590132718Skan/* A constant which was deferred in its original location has been 2591132718Skan inserted by the RTL inliner into a different function. The 2592132718Skan current function's deferred constant count must be incremented. */ 2593132718Skanvoid 2594132718Skannotice_rtl_inlining_of_deferred_constant (void) 2595132718Skan{ 2596132718Skan n_deferred_constants++; 2597132718Skan} 2598132718Skan 2599132718Skan/* Look up EXP in the table of constant descriptors. Return the rtl 2600132718Skan if it has been emitted, else null. */ 2601132718Skan 2602132718Skanrtx 2603132718Skanlookup_constant_def (tree exp) 2604132718Skan{ 2605132718Skan struct constant_descriptor_tree *desc; 2606132718Skan struct constant_descriptor_tree key; 2607132718Skan 2608132718Skan key.value = exp; 2609132718Skan desc = htab_find (const_desc_htab, &key); 2610132718Skan 2611132718Skan return (desc ? desc->rtl : NULL_RTX); 2612132718Skan} 261318334Speter 2614117395Skan/* Used in the hash tables to avoid outputting the same constant 2615117395Skan twice. Unlike 'struct constant_descriptor_tree', RTX constants 2616117395Skan are output once per function, not once per file; there seems 2617117395Skan to be no reason for the difference. */ 2618117395Skan 2619117395Skanstruct constant_descriptor_rtx GTY(()) 2620117395Skan{ 2621117395Skan /* More constant_descriptors with the same hash code. */ 2622117395Skan struct constant_descriptor_rtx *next; 2623117395Skan 2624117395Skan /* A MEM for the constant. */ 2625117395Skan rtx rtl; 2626117395Skan 2627117395Skan /* The value of the constant. */ 2628117395Skan struct rtx_const value; 2629117395Skan}; 2630117395Skan 263118334Speter/* Structure to represent sufficient information about a constant so that 263218334Speter it can be output when the constant pool is output, so that function 263318334Speter integration can be done, and to simplify handling on machines that reference 263418334Speter constant pool as base+displacement. */ 263518334Speter 2636117395Skanstruct pool_constant GTY(()) 263718334Speter{ 2638117395Skan struct constant_descriptor_rtx *desc; 2639117395Skan struct pool_constant *next; 2640117395Skan struct pool_constant *next_sym; 264190075Sobrien rtx constant; 264218334Speter enum machine_mode mode; 264318334Speter int labelno; 264490075Sobrien unsigned int align; 264590075Sobrien HOST_WIDE_INT offset; 264650397Sobrien int mark; 264718334Speter}; 264818334Speter 264918334Speter/* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true. 265018334Speter The argument is XSTR (... , 0) */ 265118334Speter 2652117395Skan#define SYMHASH(LABEL) (((unsigned long) (LABEL)) % MAX_RTX_HASH_TABLE) 265318334Speter 265490075Sobrien/* Initialize constant pool hashing for a new function. */ 265518334Speter 265618334Spetervoid 2657132718Skaninit_varasm_status (struct function *f) 265818334Speter{ 265990075Sobrien struct varasm_status *p; 2660132718Skan p = ggc_alloc (sizeof (struct varasm_status)); 266190075Sobrien f->varasm = p; 266290075Sobrien p->x_const_rtx_hash_table 2663132718Skan = ggc_alloc_cleared (MAX_RTX_HASH_TABLE 2664132718Skan * sizeof (struct constant_descriptor_rtx *)); 266590075Sobrien p->x_const_rtx_sym_hash_table 2666132718Skan = ggc_alloc_cleared (MAX_RTX_HASH_TABLE 2667132718Skan * sizeof (struct pool_constant *)); 266818334Speter 266990075Sobrien p->x_first_pool = p->x_last_pool = 0; 267090075Sobrien p->x_pool_offset = 0; 2671132718Skan p->deferred_constants = 0; 267218334Speter} 267318334Speter 267418334Speter 267518334Speter/* Express an rtx for a constant integer (perhaps symbolic) 267618334Speter as the sum of a symbol or label plus an explicit integer. 267718334Speter They are stored into VALUE. */ 267818334Speter 267918334Speterstatic void 2680132718Skandecode_rtx_const (enum machine_mode mode, rtx x, struct rtx_const *value) 268118334Speter{ 268218334Speter /* Clear the whole structure, including any gaps. */ 268390075Sobrien memset (value, 0, sizeof (struct rtx_const)); 268418334Speter 268550397Sobrien value->kind = RTX_INT; /* Most usual kind. */ 268618334Speter value->mode = mode; 268718334Speter 268818334Speter switch (GET_CODE (x)) 268918334Speter { 269018334Speter case CONST_DOUBLE: 269118334Speter value->kind = RTX_DOUBLE; 269218334Speter if (GET_MODE (x) != VOIDmode) 269318334Speter { 2694117395Skan const REAL_VALUE_TYPE *r = CONST_DOUBLE_REAL_VALUE (x); 2695117395Skan 269618334Speter value->mode = GET_MODE (x); 2697117395Skan 2698117395Skan /* Copy the REAL_VALUE_TYPE by members so that we don't 2699117395Skan copy garbage from the original structure into our 2700117395Skan carefully cleaned hashing structure. */ 2701117395Skan value->un.du.class = r->class; 2702117395Skan value->un.du.sign = r->sign; 2703117395Skan switch (r->class) 2704117395Skan { 2705117395Skan case rvc_zero: 2706117395Skan case rvc_inf: 2707117395Skan break; 2708117395Skan case rvc_normal: 2709117395Skan value->un.du.exp = r->exp; 2710132718Skan /* Fall through. */ 2711117395Skan case rvc_nan: 2712117395Skan memcpy (value->un.du.sig, r->sig, sizeof (r->sig)); 2713117395Skan break; 2714117395Skan default: 2715117395Skan abort (); 2716117395Skan } 271718334Speter } 271818334Speter else 271918334Speter { 272018334Speter value->un.di.low = CONST_DOUBLE_LOW (x); 272118334Speter value->un.di.high = CONST_DOUBLE_HIGH (x); 272218334Speter } 272318334Speter break; 272418334Speter 272596263Sobrien case CONST_VECTOR: 272696263Sobrien { 272796263Sobrien int units, i; 272896263Sobrien 272996263Sobrien units = CONST_VECTOR_NUNITS (x); 273096263Sobrien value->kind = RTX_VECTOR; 273196263Sobrien value->mode = mode; 273296263Sobrien 2733117395Skan if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) 273496263Sobrien { 2735117395Skan for (i = 0; i < units; ++i) 273696263Sobrien { 2737117395Skan rtx elt = CONST_VECTOR_ELT (x, i); 2738117395Skan if (GET_CODE (elt) == CONST_INT) 2739117395Skan { 2740117395Skan value->un.int_vec[i].low = INTVAL (elt); 2741117395Skan value->un.int_vec[i].high = 0; 2742117395Skan } 2743117395Skan else 2744117395Skan { 2745117395Skan value->un.int_vec[i].low = CONST_DOUBLE_LOW (elt); 2746117395Skan value->un.int_vec[i].high = CONST_DOUBLE_HIGH (elt); 2747117395Skan } 274896263Sobrien } 2749117395Skan } 2750117395Skan else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) 2751117395Skan { 2752117395Skan for (i = 0; i < units; ++i) 275396263Sobrien { 2754117395Skan const REAL_VALUE_TYPE *r 2755117395Skan = CONST_DOUBLE_REAL_VALUE (CONST_VECTOR_ELT (x, i)); 2756117395Skan REAL_VALUE_TYPE *d = &value->un.fp_vec[i]; 2757117395Skan 2758117395Skan /* Copy the REAL_VALUE_TYPE by members so that we don't 2759117395Skan copy garbage from the original structure into our 2760117395Skan carefully cleaned hashing structure. */ 2761117395Skan d->class = r->class; 2762117395Skan d->sign = r->sign; 2763117395Skan switch (r->class) 2764117395Skan { 2765117395Skan case rvc_zero: 2766117395Skan case rvc_inf: 2767117395Skan break; 2768117395Skan case rvc_normal: 2769117395Skan d->exp = r->exp; 2770132718Skan /* Fall through. */ 2771117395Skan case rvc_nan: 2772117395Skan memcpy (d->sig, r->sig, sizeof (r->sig)); 2773117395Skan break; 2774117395Skan default: 2775117395Skan abort (); 2776117395Skan } 277796263Sobrien } 277896263Sobrien } 2779117395Skan else 2780117395Skan abort (); 278196263Sobrien } 278296263Sobrien break; 278396263Sobrien 278418334Speter case CONST_INT: 278518334Speter value->un.addr.offset = INTVAL (x); 278618334Speter break; 278718334Speter 278818334Speter case SYMBOL_REF: 278918334Speter case LABEL_REF: 279018334Speter case PC: 279118334Speter value->un.addr.base = x; 279218334Speter break; 279318334Speter 279418334Speter case CONST: 279518334Speter x = XEXP (x, 0); 279690075Sobrien if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT) 279718334Speter { 279818334Speter value->un.addr.base = XEXP (x, 0); 279918334Speter value->un.addr.offset = INTVAL (XEXP (x, 1)); 280018334Speter } 280190075Sobrien else if (GET_CODE (x) == MINUS && GET_CODE (XEXP (x, 1)) == CONST_INT) 280218334Speter { 280318334Speter value->un.addr.base = XEXP (x, 0); 280418334Speter value->un.addr.offset = - INTVAL (XEXP (x, 1)); 280518334Speter } 280618334Speter else 280790075Sobrien { 280890075Sobrien value->un.addr.base = x; 280990075Sobrien value->un.addr.offset = 0; 281090075Sobrien } 281118334Speter break; 281218334Speter 281318334Speter default: 281496263Sobrien value->kind = RTX_UNKNOWN; 281596263Sobrien break; 281618334Speter } 281718334Speter 281896263Sobrien if (value->kind == RTX_INT && value->un.addr.base != 0 281996263Sobrien && GET_CODE (value->un.addr.base) == UNSPEC) 2820117395Skan { 282196263Sobrien /* For a simple UNSPEC, the base is set to the 282296263Sobrien operand, the kind field is set to the index of 2823117395Skan the unspec expression. 282496263Sobrien Together with the code below, in case that 2825117395Skan the operand is a SYMBOL_REF or LABEL_REF, 2826117395Skan the address of the string or the code_label 282796263Sobrien is taken as base. */ 282896263Sobrien if (XVECLEN (value->un.addr.base, 0) == 1) 2829117395Skan { 283096263Sobrien value->kind = RTX_UNSPEC + XINT (value->un.addr.base, 1); 283196263Sobrien value->un.addr.base = XVECEXP (value->un.addr.base, 0, 0); 283296263Sobrien } 283396263Sobrien } 283496263Sobrien 2835117395Skan if (value->kind >= RTX_INT && value->un.addr.base != 0) 283618334Speter switch (GET_CODE (value->un.addr.base)) 283718334Speter { 283818334Speter case SYMBOL_REF: 283990075Sobrien /* Use the string's address, not the SYMBOL_REF's address, 284090075Sobrien for the sake of addresses of library routines. */ 2841117395Skan value->un.addr.symbol = XSTR (value->un.addr.base, 0); 2842117395Skan value->un.addr.base = NULL_RTX; 284390075Sobrien break; 284490075Sobrien 284518334Speter case LABEL_REF: 284690075Sobrien /* For a LABEL_REF, compare labels. */ 284718334Speter value->un.addr.base = XEXP (value->un.addr.base, 0); 284890075Sobrien 284950397Sobrien default: 285050397Sobrien break; 285118334Speter } 285218334Speter} 285318334Speter 285418334Speter/* Given a MINUS expression, simplify it if both sides 285518334Speter include the same symbol. */ 285618334Speter 285718334Speterrtx 2858132718Skansimplify_subtraction (rtx x) 285918334Speter{ 286018334Speter struct rtx_const val0, val1; 286118334Speter 286218334Speter decode_rtx_const (GET_MODE (x), XEXP (x, 0), &val0); 286318334Speter decode_rtx_const (GET_MODE (x), XEXP (x, 1), &val1); 286418334Speter 2865117395Skan if (val0.kind >= RTX_INT 286696263Sobrien && val0.kind == val1.kind 2867117395Skan && val0.un.addr.base == val1.un.addr.base 2868117395Skan && val0.un.addr.symbol == val1.un.addr.symbol) 286918334Speter return GEN_INT (val0.un.addr.offset - val1.un.addr.offset); 287096263Sobrien 287118334Speter return x; 287218334Speter} 287318334Speter 287418334Speter/* Compute a hash code for a constant RTL expression. */ 287518334Speter 2876117395Skanstatic unsigned int 2877132718Skanconst_hash_rtx (enum machine_mode mode, rtx x) 287818334Speter{ 2879117395Skan union { 2880117395Skan struct rtx_const value; 2881117395Skan unsigned int data[sizeof(struct rtx_const) / sizeof (unsigned int)]; 2882117395Skan } u; 2883117395Skan 2884117395Skan unsigned int hi; 288590075Sobrien size_t i; 288618334Speter 2887117395Skan decode_rtx_const (mode, x, &u.value); 288818334Speter 2889132718Skan /* Compute hashing function. */ 289018334Speter hi = 0; 2891117395Skan for (i = 0; i < ARRAY_SIZE (u.data); i++) 2892117395Skan hi = hi * 613 + u.data[i]; 289318334Speter 2894117395Skan return hi % MAX_RTX_HASH_TABLE; 289518334Speter} 289618334Speter 289718334Speter/* Compare a constant rtl object X with a constant-descriptor DESC. 289818334Speter Return 1 if DESC describes a constant with the same value as X. */ 289918334Speter 290018334Speterstatic int 2901132718Skancompare_constant_rtx (enum machine_mode mode, rtx x, 2902132718Skan struct constant_descriptor_rtx *desc) 290318334Speter{ 290418334Speter struct rtx_const value; 290518334Speter 290618334Speter decode_rtx_const (mode, x, &value); 290718334Speter 290818334Speter /* Compare constant contents. */ 2909117395Skan return memcmp (&value, &desc->value, sizeof (struct rtx_const)) == 0; 291018334Speter} 291118334Speter 291218334Speter/* Construct a constant descriptor for the rtl-expression X. 291318334Speter It is up to the caller to enter the descriptor in the hash table. */ 291418334Speter 2915117395Skanstatic struct constant_descriptor_rtx * 2916132718Skanrecord_constant_rtx (enum machine_mode mode, rtx x) 291718334Speter{ 2918117395Skan struct constant_descriptor_rtx *ptr; 291918334Speter 2920132718Skan ptr = ggc_alloc (sizeof (*ptr)); 2921117395Skan decode_rtx_const (mode, x, &ptr->value); 292218334Speter 292390075Sobrien return ptr; 292490075Sobrien} 292590075Sobrien 292618334Speter/* Given a constant rtx X, make (or find) a memory constant for its value 292718334Speter and return a MEM rtx to refer to it in memory. */ 292818334Speter 292918334Speterrtx 2930132718Skanforce_const_mem (enum machine_mode mode, rtx x) 293118334Speter{ 293290075Sobrien int hash; 2933117395Skan struct constant_descriptor_rtx *desc; 293418334Speter char label[256]; 2935132718Skan rtx def, symbol; 293690075Sobrien struct pool_constant *pool; 293790075Sobrien unsigned int align; 293818334Speter 2939117395Skan /* If we're not allowed to drop X into the constant pool, don't. */ 2940117395Skan if ((*targetm.cannot_force_const_mem) (x)) 2941117395Skan return NULL_RTX; 2942117395Skan 294318334Speter /* Compute hash code of X. Search the descriptors for that hash code 294490075Sobrien to see if any of them describes X. If yes, we have an rtx to use. */ 294518334Speter hash = const_hash_rtx (mode, x); 294618334Speter for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next) 294718334Speter if (compare_constant_rtx (mode, x, desc)) 2948132718Skan return copy_rtx (desc->rtl); 294918334Speter 295090075Sobrien /* No constant equal to X is known to have been output. 295190075Sobrien Make a constant descriptor to enter X in the hash table 295290075Sobrien and make a MEM for it. */ 295390075Sobrien desc = record_constant_rtx (mode, x); 295490075Sobrien desc->next = const_rtx_hash_table[hash]; 295590075Sobrien const_rtx_hash_table[hash] = desc; 2956117395Skan 295790075Sobrien /* Align the location counter as required by EXP's data type. */ 295890075Sobrien align = GET_MODE_ALIGNMENT (mode == VOIDmode ? word_mode : mode); 295950397Sobrien#ifdef CONSTANT_ALIGNMENT 2960132718Skan { 2961132718Skan tree type = (*lang_hooks.types.type_for_mode) (mode, 0); 2962132718Skan if (type != NULL_TREE) 2963132718Skan align = CONSTANT_ALIGNMENT (make_tree (type, x), align); 2964132718Skan } 296550397Sobrien#endif 296618334Speter 296790075Sobrien pool_offset += (align / BITS_PER_UNIT) - 1; 296890075Sobrien pool_offset &= ~ ((align / BITS_PER_UNIT) - 1); 296918334Speter 297090075Sobrien if (GET_CODE (x) == LABEL_REF) 297190075Sobrien LABEL_PRESERVE_P (XEXP (x, 0)) = 1; 297218334Speter 297390075Sobrien /* Allocate a pool constant descriptor, fill it in, and chain it in. */ 2974132718Skan pool = ggc_alloc (sizeof (struct pool_constant)); 297590075Sobrien pool->desc = desc; 297690075Sobrien pool->constant = x; 297790075Sobrien pool->mode = mode; 297890075Sobrien pool->labelno = const_labelno; 297990075Sobrien pool->align = align; 298090075Sobrien pool->offset = pool_offset; 298190075Sobrien pool->mark = 1; 298290075Sobrien pool->next = 0; 298350397Sobrien 298490075Sobrien if (last_pool == 0) 298590075Sobrien first_pool = pool; 298690075Sobrien else 298790075Sobrien last_pool->next = pool; 2988117395Skan 298990075Sobrien last_pool = pool; 299090075Sobrien pool_offset += GET_MODE_SIZE (mode); 299118334Speter 299290075Sobrien /* Create a string containing the label name, in LABEL. */ 299390075Sobrien ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno); 299474722Sobrien 299590075Sobrien ++const_labelno; 299674722Sobrien 299790075Sobrien /* Construct the SYMBOL_REF and the MEM. */ 299818334Speter 2999132718Skan symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label)); 3000132718Skan SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL; 3001132718Skan 3002132718Skan pool->desc->rtl = def = gen_rtx_MEM (mode, symbol); 3003117395Skan set_mem_attributes (def, (*lang_hooks.types.type_for_mode) (mode, 0), 1); 300490075Sobrien RTX_UNCHANGING_P (def) = 1; 300518334Speter 300690075Sobrien /* Add label to symbol hash table. */ 3007132718Skan hash = SYMHASH (XSTR (symbol, 0)); 300890075Sobrien pool->next_sym = const_rtx_sym_hash_table[hash]; 300990075Sobrien const_rtx_sym_hash_table[hash] = pool; 301018334Speter 301118334Speter /* Mark the symbol_ref as belonging to this constants pool. */ 3012132718Skan CONSTANT_POOL_ADDRESS_P (symbol) = 1; 3013132718Skan SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL; 301418334Speter current_function_uses_const_pool = 1; 301518334Speter 3016132718Skan return copy_rtx (def); 301718334Speter} 301818334Speter 301918334Speter/* Given a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true, return a pointer to 302018334Speter the corresponding pool_constant structure. */ 302118334Speter 302218334Speterstatic struct pool_constant * 3023132718Skanfind_pool_constant (struct function *f, rtx addr) 302418334Speter{ 302590075Sobrien struct pool_constant *pool; 302690075Sobrien const char *label = XSTR (addr, 0); 302718334Speter 302890075Sobrien for (pool = f->varasm->x_const_rtx_sym_hash_table[SYMHASH (label)]; pool; 302990075Sobrien pool = pool->next_sym) 303090075Sobrien if (XSTR (XEXP (pool->desc->rtl, 0), 0) == label) 303190075Sobrien return pool; 303218334Speter 303318334Speter abort (); 303418334Speter} 303518334Speter 303618334Speter/* Given a constant pool SYMBOL_REF, return the corresponding constant. */ 303718334Speter 303818334Speterrtx 3039132718Skanget_pool_constant (rtx addr) 304018334Speter{ 304190075Sobrien return (find_pool_constant (cfun, addr))->constant; 304218334Speter} 304318334Speter 304496263Sobrien/* Given a constant pool SYMBOL_REF, return the corresponding constant 304596263Sobrien and whether it has been output or not. */ 304696263Sobrien 304796263Sobrienrtx 3048132718Skanget_pool_constant_mark (rtx addr, bool *pmarked) 304996263Sobrien{ 305096263Sobrien struct pool_constant *pool = find_pool_constant (cfun, addr); 305196263Sobrien *pmarked = (pool->mark != 0); 305296263Sobrien return pool->constant; 305396263Sobrien} 305496263Sobrien 305590075Sobrien/* Likewise, but for the constant pool of a specific function. */ 305690075Sobrien 305790075Sobrienrtx 3058132718Skanget_pool_constant_for_function (struct function *f, rtx addr) 305990075Sobrien{ 306090075Sobrien return (find_pool_constant (f, addr))->constant; 306190075Sobrien} 306290075Sobrien 306318334Speter/* Similar, return the mode. */ 306418334Speter 306518334Speterenum machine_mode 3066132718Skanget_pool_mode (rtx addr) 306718334Speter{ 306890075Sobrien return (find_pool_constant (cfun, addr))->mode; 306918334Speter} 307018334Speter 307190075Sobrienenum machine_mode 3072132718Skanget_pool_mode_for_function (struct function *f, rtx addr) 307390075Sobrien{ 307490075Sobrien return (find_pool_constant (f, addr))->mode; 307590075Sobrien} 307690075Sobrien 307718334Speter/* Similar, return the offset in the constant pool. */ 307818334Speter 307918334Speterint 3080132718Skanget_pool_offset (rtx addr) 308118334Speter{ 308290075Sobrien return (find_pool_constant (cfun, addr))->offset; 308318334Speter} 308418334Speter 308518334Speter/* Return the size of the constant pool. */ 308618334Speter 308718334Speterint 3088132718Skanget_pool_size (void) 308918334Speter{ 309018334Speter return pool_offset; 309118334Speter} 309218334Speter 309318334Speter/* Write all the constants in the constant pool. */ 309418334Speter 309518334Spetervoid 3096132718Skanoutput_constant_pool (const char *fnname ATTRIBUTE_UNUSED, 3097132718Skan tree fndecl ATTRIBUTE_UNUSED) 309818334Speter{ 309918334Speter struct pool_constant *pool; 310018334Speter rtx x; 3101117395Skan REAL_VALUE_TYPE r; 310218334Speter 310350397Sobrien /* It is possible for gcc to call force_const_mem and then to later 310450397Sobrien discard the instructions which refer to the constant. In such a 310550397Sobrien case we do not need to output the constant. */ 310652284Sobrien mark_constant_pool (); 310750397Sobrien 310818334Speter#ifdef ASM_OUTPUT_POOL_PROLOGUE 310918334Speter ASM_OUTPUT_POOL_PROLOGUE (asm_out_file, fnname, fndecl, pool_offset); 311018334Speter#endif 311118334Speter 311218334Speter for (pool = first_pool; pool; pool = pool->next) 311318334Speter { 311490075Sobrien rtx tmp; 311590075Sobrien 311618334Speter x = pool->constant; 311718334Speter 311850397Sobrien if (! pool->mark) 311950397Sobrien continue; 312050397Sobrien 312118334Speter /* See if X is a LABEL_REF (or a CONST referring to a LABEL_REF) 312218334Speter whose CODE_LABEL has been deleted. This can occur if a jump table 312318334Speter is eliminated by optimization. If so, write a constant of zero 312418334Speter instead. Note that this can also happen by turning the 312518334Speter CODE_LABEL into a NOTE. */ 312690075Sobrien /* ??? This seems completely and utterly wrong. Certainly it's 312790075Sobrien not true for NOTE_INSN_DELETED_LABEL, but I disbelieve proper 312890075Sobrien functioning even with INSN_DELETED_P and friends. */ 312918334Speter 313090075Sobrien tmp = x; 313190075Sobrien switch (GET_CODE (x)) 313290075Sobrien { 313390075Sobrien case CONST: 313490075Sobrien if (GET_CODE (XEXP (x, 0)) != PLUS 313590075Sobrien || GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF) 313690075Sobrien break; 313790075Sobrien tmp = XEXP (XEXP (x, 0), 0); 3138132718Skan /* Fall through. */ 313990075Sobrien 314090075Sobrien case LABEL_REF: 314190075Sobrien tmp = XEXP (x, 0); 314290075Sobrien if (INSN_DELETED_P (tmp) 314390075Sobrien || (GET_CODE (tmp) == NOTE 314490075Sobrien && NOTE_LINE_NUMBER (tmp) == NOTE_INSN_DELETED)) 314590075Sobrien { 314690075Sobrien abort (); 314790075Sobrien x = const0_rtx; 314890075Sobrien } 314990075Sobrien break; 315090075Sobrien 315190075Sobrien default: 315290075Sobrien break; 315390075Sobrien } 315490075Sobrien 315518334Speter /* First switch to correct section. */ 3156117395Skan (*targetm.asm_out.select_rtx_section) (pool->mode, x, pool->align); 315718334Speter 315818334Speter#ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY 315918334Speter ASM_OUTPUT_SPECIAL_POOL_ENTRY (asm_out_file, x, pool->mode, 316018334Speter pool->align, pool->labelno, done); 316118334Speter#endif 316218334Speter 316390075Sobrien assemble_align (pool->align); 316418334Speter 316518334Speter /* Output the label. */ 3166132718Skan (*targetm.asm_out.internal_label) (asm_out_file, "LC", pool->labelno); 316718334Speter 316818334Speter /* Output the value of the constant itself. */ 316918334Speter switch (GET_MODE_CLASS (pool->mode)) 317018334Speter { 317118334Speter case MODE_FLOAT: 317218334Speter if (GET_CODE (x) != CONST_DOUBLE) 317318334Speter abort (); 317418334Speter 3175117395Skan REAL_VALUE_FROM_CONST_DOUBLE (r, x); 3176117395Skan assemble_real (r, pool->mode, pool->align); 317718334Speter break; 317818334Speter 317918334Speter case MODE_INT: 318018334Speter case MODE_PARTIAL_INT: 318190075Sobrien assemble_integer (x, GET_MODE_SIZE (pool->mode), pool->align, 1); 318218334Speter break; 318318334Speter 318496263Sobrien case MODE_VECTOR_FLOAT: 318596263Sobrien { 318696263Sobrien int i, units; 318796263Sobrien rtx elt; 318896263Sobrien 318996263Sobrien if (GET_CODE (x) != CONST_VECTOR) 319096263Sobrien abort (); 319196263Sobrien 319296263Sobrien units = CONST_VECTOR_NUNITS (x); 319396263Sobrien 319496263Sobrien for (i = 0; i < units; i++) 319596263Sobrien { 319696263Sobrien elt = CONST_VECTOR_ELT (x, i); 3197117395Skan REAL_VALUE_FROM_CONST_DOUBLE (r, elt); 3198117395Skan assemble_real (r, GET_MODE_INNER (pool->mode), pool->align); 319996263Sobrien } 320096263Sobrien } 320196263Sobrien break; 320296263Sobrien 3203117395Skan case MODE_VECTOR_INT: 320496263Sobrien { 320596263Sobrien int i, units; 320696263Sobrien rtx elt; 320796263Sobrien 320896263Sobrien if (GET_CODE (x) != CONST_VECTOR) 320996263Sobrien abort (); 321096263Sobrien 321196263Sobrien units = CONST_VECTOR_NUNITS (x); 321296263Sobrien 321396263Sobrien for (i = 0; i < units; i++) 321496263Sobrien { 321596263Sobrien elt = CONST_VECTOR_ELT (x, i); 321696263Sobrien assemble_integer (elt, GET_MODE_UNIT_SIZE (pool->mode), 321796263Sobrien pool->align, 1); 321896263Sobrien } 321996263Sobrien } 322096263Sobrien break; 322196263Sobrien 322218334Speter default: 322318334Speter abort (); 322418334Speter } 322518334Speter 3226117395Skan /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS 3227117395Skan sections have proper size. */ 3228117395Skan if (pool->align > GET_MODE_BITSIZE (pool->mode) 3229117395Skan && in_section == in_named 3230117395Skan && get_named_section_flags (in_named_name) & SECTION_MERGE) 3231117395Skan assemble_align (pool->align); 3232117395Skan 323350397Sobrien#ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY 323418334Speter done: ; 323550397Sobrien#endif 323618334Speter } 323718334Speter 323850397Sobrien#ifdef ASM_OUTPUT_POOL_EPILOGUE 323950397Sobrien ASM_OUTPUT_POOL_EPILOGUE (asm_out_file, fnname, fndecl, pool_offset); 324050397Sobrien#endif 324150397Sobrien 324218334Speter /* Done with this pool. */ 324318334Speter first_pool = last_pool = 0; 324418334Speter} 324550397Sobrien 324650397Sobrien/* Look through the instructions for this function, and mark all the 3247132718Skan entries in the constant pool which are actually being used. Emit 3248132718Skan deferred constants which have indeed been used. */ 324950397Sobrien 325050397Sobrienstatic void 3251132718Skanmark_constant_pool (void) 325250397Sobrien{ 325390075Sobrien rtx insn; 3254117395Skan rtx link; 325550397Sobrien struct pool_constant *pool; 325650397Sobrien 3257132718Skan if (first_pool == 0 && n_deferred_constants == 0) 325850397Sobrien return; 325950397Sobrien 326050397Sobrien for (pool = first_pool; pool; pool = pool->next) 326150397Sobrien pool->mark = 0; 326250397Sobrien 326350397Sobrien for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 326490075Sobrien if (INSN_P (insn)) 326550397Sobrien mark_constants (PATTERN (insn)); 326650397Sobrien 3267117395Skan for (link = current_function_epilogue_delay_list; 3268117395Skan link; 3269117395Skan link = XEXP (link, 1)) 3270117395Skan { 3271117395Skan insn = XEXP (link, 0); 3272117395Skan 3273117395Skan if (INSN_P (insn)) 3274117395Skan mark_constants (PATTERN (insn)); 3275117395Skan } 327690075Sobrien} 327752284Sobrien 327890075Sobrien/* Look through appropriate parts of X, marking all entries in the 327990075Sobrien constant pool which are actually being used. Entries that are only 328090075Sobrien referenced by other constants are also marked as used. Emit 328190075Sobrien deferred strings that are used. */ 328252284Sobrien 328350397Sobrienstatic void 3284132718Skanmark_constants (rtx x) 328550397Sobrien{ 328690075Sobrien int i; 328790075Sobrien const char *format_ptr; 328850397Sobrien 328950397Sobrien if (x == 0) 329050397Sobrien return; 329150397Sobrien 329250397Sobrien if (GET_CODE (x) == SYMBOL_REF) 329350397Sobrien { 329490075Sobrien mark_constant (&x, NULL); 329550397Sobrien return; 329650397Sobrien } 329750397Sobrien 329850397Sobrien /* Insns may appear inside a SEQUENCE. Only check the patterns of 329950397Sobrien insns, not any notes that may be attached. We don't want to mark 330050397Sobrien a constant just because it happens to appear in a REG_EQUIV note. */ 330190075Sobrien if (INSN_P (x)) 330250397Sobrien { 330350397Sobrien mark_constants (PATTERN (x)); 330450397Sobrien return; 330550397Sobrien } 330650397Sobrien 330750397Sobrien format_ptr = GET_RTX_FORMAT (GET_CODE (x)); 330850397Sobrien 330950397Sobrien for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++) 331050397Sobrien { 331150397Sobrien switch (*format_ptr++) 331250397Sobrien { 331350397Sobrien case 'e': 331450397Sobrien mark_constants (XEXP (x, i)); 331550397Sobrien break; 331650397Sobrien 331750397Sobrien case 'E': 331850397Sobrien if (XVEC (x, i) != 0) 331950397Sobrien { 332090075Sobrien int j; 332150397Sobrien 332250397Sobrien for (j = 0; j < XVECLEN (x, i); j++) 332350397Sobrien mark_constants (XVECEXP (x, i, j)); 332450397Sobrien } 332550397Sobrien break; 332650397Sobrien 332750397Sobrien case 'S': 332850397Sobrien case 's': 332950397Sobrien case '0': 333050397Sobrien case 'i': 333150397Sobrien case 'w': 333250397Sobrien case 'n': 333350397Sobrien case 'u': 3334117395Skan case 'B': 333550397Sobrien break; 333650397Sobrien 333750397Sobrien default: 333850397Sobrien abort (); 333950397Sobrien } 334050397Sobrien } 334150397Sobrien} 334290075Sobrien 334390075Sobrien/* Given a SYMBOL_REF CURRENT_RTX, mark it and all constants it refers 334490075Sobrien to as used. Emit referenced deferred strings. This function can 334590075Sobrien be used with for_each_rtx to mark all SYMBOL_REFs in an rtx. */ 334690075Sobrien 334790075Sobrienstatic int 3348132718Skanmark_constant (rtx *current_rtx, void *data ATTRIBUTE_UNUSED) 334990075Sobrien{ 335090075Sobrien rtx x = *current_rtx; 335190075Sobrien 335290075Sobrien if (x == NULL_RTX) 335390075Sobrien return 0; 335490075Sobrien 335590075Sobrien else if (GET_CODE (x) == SYMBOL_REF) 335690075Sobrien { 335790075Sobrien if (CONSTANT_POOL_ADDRESS_P (x)) 335890075Sobrien { 335990075Sobrien struct pool_constant *pool = find_pool_constant (cfun, x); 3360117395Skan if (pool->mark == 0) 3361117395Skan { 3362117395Skan pool->mark = 1; 3363117395Skan for_each_rtx (&(pool->constant), &mark_constant, NULL); 3364117395Skan } 336590075Sobrien else 336690075Sobrien return -1; 336790075Sobrien } 3368132718Skan else if (TREE_CONSTANT_POOL_ADDRESS_P (x)) 336990075Sobrien { 3370132718Skan tree exp = SYMBOL_REF_DECL (x); 3371132718Skan if (!TREE_ASM_WRITTEN (exp)) 337290075Sobrien { 3373132718Skan n_deferred_constants--; 3374132718Skan output_constant_def_contents (x); 337590075Sobrien } 337690075Sobrien } 337790075Sobrien } 337890075Sobrien return 0; 337990075Sobrien} 338018334Speter 3381132718Skan/* Determine what kind of relocations EXP may need. */ 338218334Speter 3383132718Skanint 3384132718Skancompute_reloc_for_constant (tree exp) 338518334Speter{ 3386117395Skan int reloc = 0, reloc2; 338790075Sobrien tree tem; 338818334Speter 338990075Sobrien /* Give the front-end a chance to convert VALUE to something that 339090075Sobrien looks more like a constant to the back-end. */ 339190075Sobrien exp = (*lang_hooks.expand_constant) (exp); 339290075Sobrien 339318334Speter switch (TREE_CODE (exp)) 339418334Speter { 339518334Speter case ADDR_EXPR: 3396102780Skan case FDESC_EXPR: 339790075Sobrien /* Go inside any operations that get_inner_reference can handle and see 339890075Sobrien if what's inside is a constant: no need to do anything here for 339990075Sobrien addresses of variables or functions. */ 340090075Sobrien for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem); 340190075Sobrien tem = TREE_OPERAND (tem, 0)) 340290075Sobrien ; 340318334Speter 340490075Sobrien if (TREE_PUBLIC (tem)) 340590075Sobrien reloc |= 2; 340690075Sobrien else 340790075Sobrien reloc |= 1; 340818334Speter break; 340918334Speter 341018334Speter case PLUS_EXPR: 3411132718Skan reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0)); 3412132718Skan reloc |= compute_reloc_for_constant (TREE_OPERAND (exp, 1)); 341318334Speter break; 341418334Speter 3415117395Skan case MINUS_EXPR: 3416132718Skan reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0)); 3417132718Skan reloc2 = compute_reloc_for_constant (TREE_OPERAND (exp, 1)); 3418117395Skan /* The difference of two local labels is computable at link time. */ 3419117395Skan if (reloc == 1 && reloc2 == 1) 3420117395Skan reloc = 0; 3421117395Skan else 3422117395Skan reloc |= reloc2; 3423117395Skan break; 3424117395Skan 342518334Speter case NOP_EXPR: 342618334Speter case CONVERT_EXPR: 342718334Speter case NON_LVALUE_EXPR: 3428132718Skan reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0)); 342918334Speter break; 343018334Speter 343118334Speter case CONSTRUCTOR: 343290075Sobrien for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem)) 343390075Sobrien if (TREE_VALUE (tem) != 0) 3434132718Skan reloc |= compute_reloc_for_constant (TREE_VALUE (tem)); 343590075Sobrien 343618334Speter break; 343718334Speter 343850397Sobrien default: 343918334Speter break; 344018334Speter } 344118334Speter return reloc; 344218334Speter} 3443132718Skan 3444132718Skan/* Find all the constants whose addresses are referenced inside of EXP, 3445132718Skan and make sure assembler code with a label has been output for each one. 3446132718Skan Indicate whether an ADDR_EXPR has been encountered. */ 3447132718Skan 3448132718Skanstatic void 3449132718Skanoutput_addressed_constants (tree exp) 3450132718Skan{ 3451132718Skan tree tem; 3452132718Skan 3453132718Skan /* Give the front-end a chance to convert VALUE to something that 3454132718Skan looks more like a constant to the back-end. */ 3455132718Skan exp = (*lang_hooks.expand_constant) (exp); 3456132718Skan 3457132718Skan switch (TREE_CODE (exp)) 3458132718Skan { 3459132718Skan case ADDR_EXPR: 3460132718Skan case FDESC_EXPR: 3461132718Skan /* Go inside any operations that get_inner_reference can handle and see 3462132718Skan if what's inside is a constant: no need to do anything here for 3463132718Skan addresses of variables or functions. */ 3464132718Skan for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem); 3465132718Skan tem = TREE_OPERAND (tem, 0)) 3466132718Skan ; 3467132718Skan 3468132718Skan if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c' 3469132718Skan || TREE_CODE (tem) == CONSTRUCTOR) 3470132718Skan output_constant_def (tem, 0); 3471132718Skan break; 3472132718Skan 3473132718Skan case PLUS_EXPR: 3474132718Skan case MINUS_EXPR: 3475132718Skan output_addressed_constants (TREE_OPERAND (exp, 1)); 3476132718Skan /* Fall through. */ 3477132718Skan 3478132718Skan case NOP_EXPR: 3479132718Skan case CONVERT_EXPR: 3480132718Skan case NON_LVALUE_EXPR: 3481132718Skan output_addressed_constants (TREE_OPERAND (exp, 0)); 3482132718Skan break; 3483132718Skan 3484132718Skan case CONSTRUCTOR: 3485132718Skan for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem)) 3486132718Skan if (TREE_VALUE (tem) != 0) 3487132718Skan output_addressed_constants (TREE_VALUE (tem)); 3488132718Skan 3489132718Skan break; 3490132718Skan 3491132718Skan default: 3492132718Skan break; 3493132718Skan } 3494132718Skan} 349518334Speter 349690075Sobrien/* Return nonzero if VALUE is a valid constant-valued expression 349790075Sobrien for use in initializing a static variable; one that can be an 349890075Sobrien element of a "constant" initializer. 349990075Sobrien 350090075Sobrien Return null_pointer_node if the value is absolute; 350190075Sobrien if it is relocatable, return the variable that determines the relocation. 350290075Sobrien We assume that VALUE has been folded as much as possible; 350390075Sobrien therefore, we do not need to check for such things as 350490075Sobrien arithmetic-combinations of integers. */ 350590075Sobrien 350690075Sobrientree 3507132718Skaninitializer_constant_valid_p (tree value, tree endtype) 350890075Sobrien{ 350990075Sobrien /* Give the front-end a chance to convert VALUE to something that 351090075Sobrien looks more like a constant to the back-end. */ 351190075Sobrien value = (*lang_hooks.expand_constant) (value); 351290075Sobrien 351390075Sobrien switch (TREE_CODE (value)) 351490075Sobrien { 351590075Sobrien case CONSTRUCTOR: 351690075Sobrien if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE 351790075Sobrien || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE) 351890075Sobrien && TREE_CONSTANT (value) 351990075Sobrien && CONSTRUCTOR_ELTS (value)) 3520122180Skan { 3521122180Skan tree elt; 3522122180Skan bool absolute = true; 352390075Sobrien 3524122180Skan for (elt = CONSTRUCTOR_ELTS (value); elt; elt = TREE_CHAIN (elt)) 3525122180Skan { 3526122180Skan tree reloc; 3527122180Skan value = TREE_VALUE (elt); 3528122180Skan reloc = initializer_constant_valid_p (value, TREE_TYPE (value)); 3529122180Skan if (!reloc) 3530122180Skan return NULL_TREE; 3531122180Skan if (reloc != null_pointer_node) 3532122180Skan absolute = false; 3533122180Skan } 3534122180Skan /* For a non-absolute relocation, there is no single 3535122180Skan variable that can be "the variable that determines the 3536122180Skan relocation." */ 3537122180Skan return absolute ? null_pointer_node : error_mark_node; 3538122180Skan } 353990075Sobrien 3540122180Skan return TREE_STATIC (value) ? null_pointer_node : NULL_TREE; 3541122180Skan 354290075Sobrien case INTEGER_CST: 354396263Sobrien case VECTOR_CST: 354490075Sobrien case REAL_CST: 354590075Sobrien case STRING_CST: 354690075Sobrien case COMPLEX_CST: 354790075Sobrien return null_pointer_node; 354890075Sobrien 354990075Sobrien case ADDR_EXPR: 355090075Sobrien case FDESC_EXPR: 355190075Sobrien return staticp (TREE_OPERAND (value, 0)) ? TREE_OPERAND (value, 0) : 0; 355290075Sobrien 355390075Sobrien case VIEW_CONVERT_EXPR: 355490075Sobrien case NON_LVALUE_EXPR: 355590075Sobrien return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); 355690075Sobrien 355790075Sobrien case CONVERT_EXPR: 355890075Sobrien case NOP_EXPR: 3559146895Skan { 3560146895Skan tree src; 3561146895Skan tree src_type; 3562146895Skan tree dest_type; 356390075Sobrien 3564146895Skan src = TREE_OPERAND (value, 0); 3565146895Skan src_type = TREE_TYPE (src); 3566146895Skan dest_type = TREE_TYPE (value); 356790075Sobrien 3568146895Skan /* Allow conversions between pointer types, floating-point 3569146895Skan types, and offset types. */ 3570146895Skan if ((POINTER_TYPE_P (dest_type) && POINTER_TYPE_P (src_type)) 3571146895Skan || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type)) 3572146895Skan || (TREE_CODE (dest_type) == OFFSET_TYPE 3573146895Skan && TREE_CODE (src_type) == OFFSET_TYPE)) 3574146895Skan return initializer_constant_valid_p (src, endtype); 357590075Sobrien 3576146895Skan /* Allow length-preserving conversions between integer types. */ 3577146895Skan if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type) 3578146895Skan && (TYPE_PRECISION (dest_type) == TYPE_PRECISION (src_type))) 3579146895Skan return initializer_constant_valid_p (src, endtype); 358090075Sobrien 3581146895Skan /* Allow conversions between other integer types only if 3582146895Skan explicit value. */ 3583146895Skan if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type)) 3584146895Skan { 3585146895Skan tree inner = initializer_constant_valid_p (src, endtype); 3586146895Skan if (inner == null_pointer_node) 3587146895Skan return null_pointer_node; 3588146895Skan break; 3589146895Skan } 359090075Sobrien 3591146895Skan /* Allow (int) &foo provided int is as wide as a pointer. */ 3592146895Skan if (INTEGRAL_TYPE_P (dest_type) && POINTER_TYPE_P (src_type) 3593146895Skan && (TYPE_PRECISION (dest_type) >= TYPE_PRECISION (src_type))) 3594146895Skan return initializer_constant_valid_p (src, endtype); 359590075Sobrien 3596146895Skan /* Likewise conversions from int to pointers, but also allow 3597146895Skan conversions from 0. */ 3598146895Skan if ((POINTER_TYPE_P (dest_type) 3599146895Skan || TREE_CODE (dest_type) == OFFSET_TYPE) 3600146895Skan && INTEGRAL_TYPE_P (src_type)) 3601146895Skan { 3602146895Skan if (integer_zerop (src)) 3603146895Skan return null_pointer_node; 3604146895Skan else if (TYPE_PRECISION (dest_type) <= TYPE_PRECISION (src_type)) 3605146895Skan return initializer_constant_valid_p (src, endtype); 3606146895Skan } 3607146895Skan 3608146895Skan /* Allow conversions to struct or union types if the value 3609146895Skan inside is okay. */ 3610146895Skan if (TREE_CODE (dest_type) == RECORD_TYPE 3611146895Skan || TREE_CODE (dest_type) == UNION_TYPE) 3612146895Skan return initializer_constant_valid_p (src, endtype); 3613146895Skan } 361490075Sobrien break; 361590075Sobrien 361690075Sobrien case PLUS_EXPR: 361790075Sobrien if (! INTEGRAL_TYPE_P (endtype) 361890075Sobrien || TYPE_PRECISION (endtype) >= POINTER_SIZE) 3619117395Skan { 362090075Sobrien tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), 362190075Sobrien endtype); 362290075Sobrien tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), 362390075Sobrien endtype); 362490075Sobrien /* If either term is absolute, use the other terms relocation. */ 362590075Sobrien if (valid0 == null_pointer_node) 362690075Sobrien return valid1; 362790075Sobrien if (valid1 == null_pointer_node) 362890075Sobrien return valid0; 3629117395Skan } 363090075Sobrien break; 363190075Sobrien 363290075Sobrien case MINUS_EXPR: 363390075Sobrien if (! INTEGRAL_TYPE_P (endtype) 363490075Sobrien || TYPE_PRECISION (endtype) >= POINTER_SIZE) 363590075Sobrien { 363690075Sobrien tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), 363790075Sobrien endtype); 363890075Sobrien tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), 363990075Sobrien endtype); 364090075Sobrien /* Win if second argument is absolute. */ 364190075Sobrien if (valid1 == null_pointer_node) 364290075Sobrien return valid0; 364390075Sobrien /* Win if both arguments have the same relocation. 364490075Sobrien Then the value is absolute. */ 364590075Sobrien if (valid0 == valid1 && valid0 != 0) 364690075Sobrien return null_pointer_node; 364790075Sobrien 364890075Sobrien /* Since GCC guarantees that string constants are unique in the 364990075Sobrien generated code, a subtraction between two copies of the same 365090075Sobrien constant string is absolute. */ 365190075Sobrien if (valid0 && TREE_CODE (valid0) == STRING_CST && 365290075Sobrien valid1 && TREE_CODE (valid1) == STRING_CST && 365390075Sobrien TREE_STRING_POINTER (valid0) == TREE_STRING_POINTER (valid1)) 365490075Sobrien return null_pointer_node; 365590075Sobrien } 365690075Sobrien 365790075Sobrien /* Support differences between labels. */ 365890075Sobrien if (INTEGRAL_TYPE_P (endtype)) 365990075Sobrien { 366090075Sobrien tree op0, op1; 366190075Sobrien op0 = TREE_OPERAND (value, 0); 366290075Sobrien op1 = TREE_OPERAND (value, 1); 366390075Sobrien 366496263Sobrien /* Like STRIP_NOPS except allow the operand mode to widen. 3665132718Skan This works around a feature of fold that simplifies 366696263Sobrien (int)(p1 - p2) to ((int)p1 - (int)p2) under the theory 366796263Sobrien that the narrower operation is cheaper. */ 366896263Sobrien 366996263Sobrien while (TREE_CODE (op0) == NOP_EXPR 367096263Sobrien || TREE_CODE (op0) == CONVERT_EXPR 367196263Sobrien || TREE_CODE (op0) == NON_LVALUE_EXPR) 367296263Sobrien { 367396263Sobrien tree inner = TREE_OPERAND (op0, 0); 367496263Sobrien if (inner == error_mark_node 367596263Sobrien || ! INTEGRAL_MODE_P (TYPE_MODE (TREE_TYPE (inner))) 367696263Sobrien || (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))) 367796263Sobrien > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (inner))))) 367896263Sobrien break; 367996263Sobrien op0 = inner; 368096263Sobrien } 368196263Sobrien 368296263Sobrien while (TREE_CODE (op1) == NOP_EXPR 368396263Sobrien || TREE_CODE (op1) == CONVERT_EXPR 368496263Sobrien || TREE_CODE (op1) == NON_LVALUE_EXPR) 368596263Sobrien { 368696263Sobrien tree inner = TREE_OPERAND (op1, 0); 368796263Sobrien if (inner == error_mark_node 368896263Sobrien || ! INTEGRAL_MODE_P (TYPE_MODE (TREE_TYPE (inner))) 368996263Sobrien || (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op1))) 369096263Sobrien > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (inner))))) 369196263Sobrien break; 369296263Sobrien op1 = inner; 369396263Sobrien } 369496263Sobrien 369590075Sobrien if (TREE_CODE (op0) == ADDR_EXPR 369690075Sobrien && TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL 369790075Sobrien && TREE_CODE (op1) == ADDR_EXPR 369890075Sobrien && TREE_CODE (TREE_OPERAND (op1, 0)) == LABEL_DECL) 369990075Sobrien return null_pointer_node; 370090075Sobrien } 370190075Sobrien break; 370290075Sobrien 370390075Sobrien default: 370490075Sobrien break; 370590075Sobrien } 370690075Sobrien 370790075Sobrien return 0; 370890075Sobrien} 370990075Sobrien 371018334Speter/* Output assembler code for constant EXP to FILE, with no label. 371118334Speter This includes the pseudo-op such as ".int" or ".byte", and a newline. 371218334Speter Assumes output_addressed_constants has been done on EXP already. 371318334Speter 371418334Speter Generate exactly SIZE bytes of assembler data, padding at the end 371518334Speter with zeros if necessary. SIZE must always be specified. 371618334Speter 371718334Speter SIZE is important for structure constructors, 371818334Speter since trailing members may have been omitted from the constructor. 371918334Speter It is also important for initialization of arrays from string constants 372018334Speter since the full length of the string constant might not be wanted. 372118334Speter It is also needed for initialization of unions, where the initializer's 372218334Speter type is just one member, and that may not be as long as the union. 372318334Speter 372418334Speter There a case in which we would fail to output exactly SIZE bytes: 372518334Speter for a structure constructor that wants to produce more than SIZE bytes. 372690075Sobrien But such constructors will never be generated for any possible input. 372718334Speter 372890075Sobrien ALIGN is the alignment of the data in bits. */ 372990075Sobrien 373018334Spetervoid 3731132718Skanoutput_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align) 373218334Speter{ 373390075Sobrien enum tree_code code; 3734132718Skan unsigned HOST_WIDE_INT thissize; 373518334Speter 3736132718Skan /* Some front-ends use constants other than the standard language-independent 373790075Sobrien varieties, but which may still be output directly. Give the front-end a 373890075Sobrien chance to convert EXP to a language-independent representation. */ 373990075Sobrien exp = (*lang_hooks.expand_constant) (exp); 374052284Sobrien 374152284Sobrien if (size == 0 || flag_syntax_only) 374218334Speter return; 374318334Speter 374490075Sobrien /* Eliminate any conversions since we'll be outputting the underlying 374590075Sobrien constant. */ 374690075Sobrien while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR 374790075Sobrien || TREE_CODE (exp) == NON_LVALUE_EXPR 374890075Sobrien || TREE_CODE (exp) == VIEW_CONVERT_EXPR) 374918334Speter exp = TREE_OPERAND (exp, 0); 375018334Speter 375190075Sobrien code = TREE_CODE (TREE_TYPE (exp)); 375290075Sobrien thissize = int_size_in_bytes (TREE_TYPE (exp)); 375390075Sobrien 375418334Speter /* Allow a constructor with no elements for any data type. 375518334Speter This means to fill the space with zeros. */ 375618334Speter if (TREE_CODE (exp) == CONSTRUCTOR && CONSTRUCTOR_ELTS (exp) == 0) 375718334Speter { 375850397Sobrien assemble_zeros (size); 375918334Speter return; 376018334Speter } 376118334Speter 376290075Sobrien if (TREE_CODE (exp) == FDESC_EXPR) 376390075Sobrien { 376490075Sobrien#ifdef ASM_OUTPUT_FDESC 376590075Sobrien HOST_WIDE_INT part = tree_low_cst (TREE_OPERAND (exp, 1), 0); 376690075Sobrien tree decl = TREE_OPERAND (exp, 0); 376790075Sobrien ASM_OUTPUT_FDESC (asm_out_file, decl, part); 376890075Sobrien#else 376990075Sobrien abort (); 377090075Sobrien#endif 377190075Sobrien return; 377290075Sobrien } 377390075Sobrien 377490075Sobrien /* Now output the underlying data. If we've handling the padding, return. 377590075Sobrien Otherwise, break and ensure THISSIZE is the size written. */ 377618334Speter switch (code) 377718334Speter { 377818334Speter case CHAR_TYPE: 377918334Speter case BOOLEAN_TYPE: 378018334Speter case INTEGER_TYPE: 378118334Speter case ENUMERAL_TYPE: 378218334Speter case POINTER_TYPE: 378318334Speter case REFERENCE_TYPE: 3784132718Skan case OFFSET_TYPE: 378518334Speter if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode, 378618334Speter EXPAND_INITIALIZER), 378790075Sobrien size, align, 0)) 378818334Speter error ("initializer for integer value is too complicated"); 378918334Speter break; 379018334Speter 379118334Speter case REAL_TYPE: 379218334Speter if (TREE_CODE (exp) != REAL_CST) 379318334Speter error ("initializer for floating value is not a floating constant"); 379418334Speter 3795132718Skan assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align); 379618334Speter break; 379718334Speter 379818334Speter case COMPLEX_TYPE: 379990075Sobrien output_constant (TREE_REALPART (exp), thissize / 2, align); 380090075Sobrien output_constant (TREE_IMAGPART (exp), thissize / 2, 380190075Sobrien min_align (align, BITS_PER_UNIT * (thissize / 2))); 380218334Speter break; 380318334Speter 380418334Speter case ARRAY_TYPE: 380596263Sobrien case VECTOR_TYPE: 380618334Speter if (TREE_CODE (exp) == CONSTRUCTOR) 380718334Speter { 380890075Sobrien output_constructor (exp, size, align); 380918334Speter return; 381018334Speter } 381118334Speter else if (TREE_CODE (exp) == STRING_CST) 381218334Speter { 3813132718Skan thissize = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp), 3814132718Skan size); 381590075Sobrien assemble_string (TREE_STRING_POINTER (exp), thissize); 381618334Speter } 3817119256Skan else if (TREE_CODE (exp) == VECTOR_CST) 3818119256Skan { 3819119256Skan int elt_size; 3820119256Skan tree link; 3821119256Skan unsigned int nalign; 3822119256Skan enum machine_mode inner; 3823119256Skan 3824119256Skan inner = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (exp))); 3825119256Skan nalign = MIN (align, GET_MODE_ALIGNMENT (inner)); 3826119256Skan 3827119256Skan elt_size = GET_MODE_UNIT_SIZE (TYPE_MODE (TREE_TYPE (exp))); 3828119256Skan 3829119256Skan link = TREE_VECTOR_CST_ELTS (exp); 3830119256Skan output_constant (TREE_VALUE (link), elt_size, align); 3831119256Skan while ((link = TREE_CHAIN (link)) != NULL) 3832119256Skan output_constant (TREE_VALUE (link), elt_size, nalign); 3833119256Skan } 383418334Speter else 383518334Speter abort (); 383618334Speter break; 383718334Speter 383818334Speter case RECORD_TYPE: 383918334Speter case UNION_TYPE: 384018334Speter if (TREE_CODE (exp) == CONSTRUCTOR) 384190075Sobrien output_constructor (exp, size, align); 384218334Speter else 384318334Speter abort (); 384418334Speter return; 384518334Speter 384618334Speter case SET_TYPE: 384718334Speter if (TREE_CODE (exp) == INTEGER_CST) 384818334Speter assemble_integer (expand_expr (exp, NULL_RTX, 384918334Speter VOIDmode, EXPAND_INITIALIZER), 3850117395Skan thissize, align, 1); 385118334Speter else if (TREE_CODE (exp) == CONSTRUCTOR) 385218334Speter { 3853132718Skan unsigned char *buffer = alloca (thissize); 385490075Sobrien if (get_set_constructor_bytes (exp, buffer, thissize)) 385518334Speter abort (); 385690075Sobrien assemble_string ((char *) buffer, thissize); 385718334Speter } 385818334Speter else 385918334Speter error ("unknown set constructor type"); 386018334Speter return; 386150397Sobrien 386290075Sobrien case ERROR_MARK: 386390075Sobrien return; 386490075Sobrien 386550397Sobrien default: 386690075Sobrien abort (); 386718334Speter } 386818334Speter 3869132718Skan if (size > thissize) 3870132718Skan assemble_zeros (size - thissize); 387118334Speter} 387218334Speter 387318334Speter 387490075Sobrien/* Subroutine of output_constructor, used for computing the size of 387590075Sobrien arrays of unspecified length. VAL must be a CONSTRUCTOR of an array 387690075Sobrien type with an unspecified upper bound. */ 387790075Sobrien 387890075Sobrienstatic unsigned HOST_WIDE_INT 3879132718Skanarray_size_for_constructor (tree val) 388090075Sobrien{ 388190075Sobrien tree max_index, i; 388290075Sobrien 388390075Sobrien /* This code used to attempt to handle string constants that are not 388490075Sobrien arrays of single-bytes, but nothing else does, so there's no point in 388590075Sobrien doing it here. */ 388690075Sobrien if (TREE_CODE (val) == STRING_CST) 388790075Sobrien return TREE_STRING_LENGTH (val); 388890075Sobrien 388990075Sobrien max_index = NULL_TREE; 3890117395Skan for (i = CONSTRUCTOR_ELTS (val); i; i = TREE_CHAIN (i)) 389190075Sobrien { 389290075Sobrien tree index = TREE_PURPOSE (i); 389390075Sobrien 389490075Sobrien if (TREE_CODE (index) == RANGE_EXPR) 389590075Sobrien index = TREE_OPERAND (index, 1); 389690075Sobrien if (max_index == NULL_TREE || tree_int_cst_lt (max_index, index)) 389790075Sobrien max_index = index; 389890075Sobrien } 389990075Sobrien 390090075Sobrien if (max_index == NULL_TREE) 390190075Sobrien return 0; 390290075Sobrien 390390075Sobrien /* Compute the total number of array elements. */ 390490075Sobrien i = size_binop (MINUS_EXPR, convert (sizetype, max_index), 390590075Sobrien convert (sizetype, 390690075Sobrien TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (val))))); 390790075Sobrien i = size_binop (PLUS_EXPR, i, convert (sizetype, integer_one_node)); 390890075Sobrien 390990075Sobrien /* Multiply by the array element unit size to find number of bytes. */ 391090075Sobrien i = size_binop (MULT_EXPR, i, TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (val)))); 391190075Sobrien 391290075Sobrien return tree_low_cst (i, 1); 391390075Sobrien} 391490075Sobrien 391590075Sobrien/* Subroutine of output_constant, used for CONSTRUCTORs (aggregate constants). 391618334Speter Generate at least SIZE bytes, padding if necessary. */ 391718334Speter 391818334Speterstatic void 3919132718Skanoutput_constructor (tree exp, unsigned HOST_WIDE_INT size, 3920132718Skan unsigned int align) 392118334Speter{ 392290075Sobrien tree type = TREE_TYPE (exp); 392390075Sobrien tree link, field = 0; 392490075Sobrien tree min_index = 0; 392518334Speter /* Number of bytes output or skipped so far. 392618334Speter In other words, current position within the constructor. */ 392790075Sobrien HOST_WIDE_INT total_bytes = 0; 3928132718Skan /* Nonzero means BYTE contains part of a byte, to be output. */ 392918334Speter int byte_buffer_in_use = 0; 393090075Sobrien int byte = 0; 393118334Speter 393218334Speter if (HOST_BITS_PER_WIDE_INT < BITS_PER_UNIT) 393318334Speter abort (); 393418334Speter 393590075Sobrien if (TREE_CODE (type) == RECORD_TYPE) 393690075Sobrien field = TYPE_FIELDS (type); 393718334Speter 393890075Sobrien if (TREE_CODE (type) == ARRAY_TYPE 393990075Sobrien && TYPE_DOMAIN (type) != 0) 394090075Sobrien min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); 394118334Speter 394218334Speter /* As LINK goes through the elements of the constant, 394318334Speter FIELD goes through the structure fields, if the constant is a structure. 394418334Speter if the constant is a union, then we override this, 394518334Speter by getting the field from the TREE_LIST element. 394652284Sobrien But the constant could also be an array. Then FIELD is zero. 394752284Sobrien 394852284Sobrien There is always a maximum of one element in the chain LINK for unions 394952284Sobrien (even if the initializer in a source program incorrectly contains 395090075Sobrien more one). */ 395118334Speter for (link = CONSTRUCTOR_ELTS (exp); 395218334Speter link; 395318334Speter link = TREE_CHAIN (link), 395418334Speter field = field ? TREE_CHAIN (field) : 0) 395518334Speter { 395618334Speter tree val = TREE_VALUE (link); 395718334Speter tree index = 0; 395818334Speter 395990075Sobrien /* The element in a union constructor specifies the proper field 396090075Sobrien or index. */ 396190075Sobrien if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE 396290075Sobrien || TREE_CODE (type) == QUAL_UNION_TYPE) 396390075Sobrien && TREE_PURPOSE (link) != 0) 396490075Sobrien field = TREE_PURPOSE (link); 396518334Speter 396690075Sobrien else if (TREE_CODE (type) == ARRAY_TYPE) 396718334Speter index = TREE_PURPOSE (link); 396818334Speter 3969132718Skan#ifdef ASM_COMMENT_START 3970132718Skan if (field && flag_verbose_asm) 3971132718Skan fprintf (asm_out_file, "%s %s:\n", 3972132718Skan ASM_COMMENT_START, 3973132718Skan DECL_NAME (field) 3974132718Skan ? IDENTIFIER_POINTER (DECL_NAME (field)) 3975132718Skan : "<anonymous>"); 3976132718Skan#endif 3977132718Skan 397818334Speter /* Eliminate the marker that makes a cast not be an lvalue. */ 397918334Speter if (val != 0) 398018334Speter STRIP_NOPS (val); 398118334Speter 398250397Sobrien if (index && TREE_CODE (index) == RANGE_EXPR) 398318334Speter { 398490075Sobrien unsigned HOST_WIDE_INT fieldsize 398590075Sobrien = int_size_in_bytes (TREE_TYPE (type)); 398690075Sobrien HOST_WIDE_INT lo_index = tree_low_cst (TREE_OPERAND (index, 0), 0); 398790075Sobrien HOST_WIDE_INT hi_index = tree_low_cst (TREE_OPERAND (index, 1), 0); 398850397Sobrien HOST_WIDE_INT index; 398990075Sobrien unsigned int align2 = min_align (align, fieldsize * BITS_PER_UNIT); 399090075Sobrien 399150397Sobrien for (index = lo_index; index <= hi_index; index++) 399250397Sobrien { 399350397Sobrien /* Output the element's initial value. */ 399450397Sobrien if (val == 0) 399550397Sobrien assemble_zeros (fieldsize); 399650397Sobrien else 399790075Sobrien output_constant (val, fieldsize, align2); 399850397Sobrien 399950397Sobrien /* Count its size. */ 400050397Sobrien total_bytes += fieldsize; 400150397Sobrien } 400250397Sobrien } 400350397Sobrien else if (field == 0 || !DECL_BIT_FIELD (field)) 400450397Sobrien { 400518334Speter /* An element that is not a bit-field. */ 400618334Speter 400790075Sobrien unsigned HOST_WIDE_INT fieldsize; 400818334Speter /* Since this structure is static, 400918334Speter we know the positions are constant. */ 401090075Sobrien HOST_WIDE_INT pos = field ? int_byte_position (field) : 0; 401190075Sobrien unsigned int align2; 401290075Sobrien 401318334Speter if (index != 0) 401490075Sobrien pos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (val)), 1) 401590075Sobrien * (tree_low_cst (index, 0) - tree_low_cst (min_index, 0))); 401618334Speter 401718334Speter /* Output any buffered-up bit-fields preceding this element. */ 401818334Speter if (byte_buffer_in_use) 401918334Speter { 402090075Sobrien assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1); 402118334Speter total_bytes++; 402218334Speter byte_buffer_in_use = 0; 402318334Speter } 402418334Speter 402518334Speter /* Advance to offset of this element. 402618334Speter Note no alignment needed in an array, since that is guaranteed 402718334Speter if each element has the proper size. */ 402890075Sobrien if ((field != 0 || index != 0) && pos != total_bytes) 402918334Speter { 403090075Sobrien assemble_zeros (pos - total_bytes); 403190075Sobrien total_bytes = pos; 403218334Speter } 403318334Speter 403490075Sobrien /* Find the alignment of this element. */ 403590075Sobrien align2 = min_align (align, BITS_PER_UNIT * pos); 403690075Sobrien 403718334Speter /* Determine size this element should occupy. */ 403818334Speter if (field) 403918334Speter { 404090075Sobrien fieldsize = 0; 404190075Sobrien 404290075Sobrien /* If this is an array with an unspecified upper bound, 404390075Sobrien the initializer determines the size. */ 404490075Sobrien /* ??? This ought to only checked if DECL_SIZE_UNIT is NULL, 404590075Sobrien but we cannot do this until the deprecated support for 404690075Sobrien initializing zero-length array members is removed. */ 404790075Sobrien if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE 404890075Sobrien && TYPE_DOMAIN (TREE_TYPE (field)) 404990075Sobrien && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field)))) 405018334Speter { 405190075Sobrien fieldsize = array_size_for_constructor (val); 405290075Sobrien /* Given a non-empty initialization, this field had 405390075Sobrien better be last. */ 405490075Sobrien if (fieldsize != 0 && TREE_CHAIN (field) != NULL_TREE) 405590075Sobrien abort (); 405618334Speter } 405790075Sobrien else if (DECL_SIZE_UNIT (field)) 405818334Speter { 405990075Sobrien /* ??? This can't be right. If the decl size overflows 406090075Sobrien a host integer we will silently emit no data. */ 406190075Sobrien if (host_integerp (DECL_SIZE_UNIT (field), 1)) 406290075Sobrien fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1); 406318334Speter } 406418334Speter } 406518334Speter else 406690075Sobrien fieldsize = int_size_in_bytes (TREE_TYPE (type)); 406718334Speter 406818334Speter /* Output the element's initial value. */ 406918334Speter if (val == 0) 407018334Speter assemble_zeros (fieldsize); 407118334Speter else 407290075Sobrien output_constant (val, fieldsize, align2); 407318334Speter 407418334Speter /* Count its size. */ 407518334Speter total_bytes += fieldsize; 407618334Speter } 407718334Speter else if (val != 0 && TREE_CODE (val) != INTEGER_CST) 407818334Speter error ("invalid initial value for member `%s'", 407918334Speter IDENTIFIER_POINTER (DECL_NAME (field))); 408018334Speter else 408118334Speter { 408218334Speter /* Element that is a bit-field. */ 408318334Speter 408490075Sobrien HOST_WIDE_INT next_offset = int_bit_position (field); 408590075Sobrien HOST_WIDE_INT end_offset 408690075Sobrien = (next_offset + tree_low_cst (DECL_SIZE (field), 1)); 408718334Speter 408818334Speter if (val == 0) 408918334Speter val = integer_zero_node; 409018334Speter 409118334Speter /* If this field does not start in this (or, next) byte, 409218334Speter skip some bytes. */ 409318334Speter if (next_offset / BITS_PER_UNIT != total_bytes) 409418334Speter { 409518334Speter /* Output remnant of any bit field in previous bytes. */ 409618334Speter if (byte_buffer_in_use) 409718334Speter { 409890075Sobrien assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1); 409918334Speter total_bytes++; 410018334Speter byte_buffer_in_use = 0; 410118334Speter } 410218334Speter 410318334Speter /* If still not at proper byte, advance to there. */ 410418334Speter if (next_offset / BITS_PER_UNIT != total_bytes) 410518334Speter { 410618334Speter assemble_zeros (next_offset / BITS_PER_UNIT - total_bytes); 410718334Speter total_bytes = next_offset / BITS_PER_UNIT; 410818334Speter } 410918334Speter } 411018334Speter 411118334Speter if (! byte_buffer_in_use) 411218334Speter byte = 0; 411318334Speter 411418334Speter /* We must split the element into pieces that fall within 411518334Speter separate bytes, and combine each byte with previous or 411618334Speter following bit-fields. */ 411718334Speter 411818334Speter /* next_offset is the offset n fbits from the beginning of 411918334Speter the structure to the next bit of this element to be processed. 412018334Speter end_offset is the offset of the first bit past the end of 412118334Speter this element. */ 412218334Speter while (next_offset < end_offset) 412318334Speter { 412418334Speter int this_time; 412518334Speter int shift; 412618334Speter HOST_WIDE_INT value; 412790075Sobrien HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT; 412890075Sobrien HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT; 412918334Speter 413018334Speter /* Advance from byte to byte 413118334Speter within this element when necessary. */ 413218334Speter while (next_byte != total_bytes) 413318334Speter { 413490075Sobrien assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1); 413518334Speter total_bytes++; 413618334Speter byte = 0; 413718334Speter } 413818334Speter 413918334Speter /* Number of bits we can process at once 414018334Speter (all part of the same byte). */ 414118334Speter this_time = MIN (end_offset - next_offset, 414218334Speter BITS_PER_UNIT - next_bit); 414318334Speter if (BYTES_BIG_ENDIAN) 414418334Speter { 414518334Speter /* On big-endian machine, take the most significant bits 414618334Speter first (of the bits that are significant) 414718334Speter and put them into bytes from the most significant end. */ 414818334Speter shift = end_offset - next_offset - this_time; 414990075Sobrien 415018334Speter /* Don't try to take a bunch of bits that cross 415190075Sobrien the word boundary in the INTEGER_CST. We can 415290075Sobrien only select bits from the LOW or HIGH part 415390075Sobrien not from both. */ 415418334Speter if (shift < HOST_BITS_PER_WIDE_INT 415518334Speter && shift + this_time > HOST_BITS_PER_WIDE_INT) 415618334Speter { 415790075Sobrien this_time = shift + this_time - HOST_BITS_PER_WIDE_INT; 415818334Speter shift = HOST_BITS_PER_WIDE_INT; 415918334Speter } 416018334Speter 416118334Speter /* Now get the bits from the appropriate constant word. */ 416218334Speter if (shift < HOST_BITS_PER_WIDE_INT) 416390075Sobrien value = TREE_INT_CST_LOW (val); 416418334Speter else if (shift < 2 * HOST_BITS_PER_WIDE_INT) 416518334Speter { 416618334Speter value = TREE_INT_CST_HIGH (val); 416718334Speter shift -= HOST_BITS_PER_WIDE_INT; 416818334Speter } 416918334Speter else 417018334Speter abort (); 417190075Sobrien 417290075Sobrien /* Get the result. This works only when: 417390075Sobrien 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */ 417418334Speter byte |= (((value >> shift) 417590075Sobrien & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1)) 417618334Speter << (BITS_PER_UNIT - this_time - next_bit)); 417718334Speter } 417818334Speter else 417918334Speter { 418018334Speter /* On little-endian machines, 418118334Speter take first the least significant bits of the value 418218334Speter and pack them starting at the least significant 418318334Speter bits of the bytes. */ 418490075Sobrien shift = next_offset - int_bit_position (field); 418590075Sobrien 418618334Speter /* Don't try to take a bunch of bits that cross 418790075Sobrien the word boundary in the INTEGER_CST. We can 418890075Sobrien only select bits from the LOW or HIGH part 418990075Sobrien not from both. */ 419018334Speter if (shift < HOST_BITS_PER_WIDE_INT 419118334Speter && shift + this_time > HOST_BITS_PER_WIDE_INT) 419290075Sobrien this_time = (HOST_BITS_PER_WIDE_INT - shift); 419318334Speter 419418334Speter /* Now get the bits from the appropriate constant word. */ 419550397Sobrien if (shift < HOST_BITS_PER_WIDE_INT) 419618334Speter value = TREE_INT_CST_LOW (val); 419718334Speter else if (shift < 2 * HOST_BITS_PER_WIDE_INT) 419818334Speter { 419918334Speter value = TREE_INT_CST_HIGH (val); 420018334Speter shift -= HOST_BITS_PER_WIDE_INT; 420118334Speter } 420218334Speter else 420318334Speter abort (); 420490075Sobrien 420590075Sobrien /* Get the result. This works only when: 420690075Sobrien 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */ 420718334Speter byte |= (((value >> shift) 420890075Sobrien & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1)) 420918334Speter << next_bit); 421018334Speter } 421190075Sobrien 421218334Speter next_offset += this_time; 421318334Speter byte_buffer_in_use = 1; 421418334Speter } 421518334Speter } 421618334Speter } 421790075Sobrien 421818334Speter if (byte_buffer_in_use) 421918334Speter { 422090075Sobrien assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1); 422118334Speter total_bytes++; 422218334Speter } 422390075Sobrien 4224132718Skan if ((unsigned HOST_WIDE_INT)total_bytes < size) 422518334Speter assemble_zeros (size - total_bytes); 422618334Speter} 422718334Speter 422896263Sobrien/* This TREE_LIST contains any weak symbol declarations waiting 422996263Sobrien to be emitted. */ 4230117395Skanstatic GTY(()) tree weak_decls; 423190075Sobrien 423296263Sobrien/* Mark DECL as weak. */ 423396263Sobrien 423496263Sobrienstatic void 4235132718Skanmark_weak (tree decl) 423690075Sobrien{ 423796263Sobrien DECL_WEAK (decl) = 1; 423890075Sobrien 423996263Sobrien if (DECL_RTL_SET_P (decl) 424096263Sobrien && GET_CODE (DECL_RTL (decl)) == MEM 424196263Sobrien && XEXP (DECL_RTL (decl), 0) 424296263Sobrien && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF) 424396263Sobrien SYMBOL_REF_WEAK (XEXP (DECL_RTL (decl), 0)) = 1; 424496263Sobrien} 4245117395Skan 424696263Sobrien/* Merge weak status between NEWDECL and OLDDECL. */ 424790075Sobrien 424896263Sobrienvoid 4249132718Skanmerge_weak (tree newdecl, tree olddecl) 425018334Speter{ 425196263Sobrien if (DECL_WEAK (newdecl) == DECL_WEAK (olddecl)) 425296263Sobrien return; 425318334Speter 425496263Sobrien if (DECL_WEAK (newdecl)) 425596263Sobrien { 425696263Sobrien tree wd; 4257117395Skan 425896263Sobrien /* NEWDECL is weak, but OLDDECL is not. */ 425918334Speter 426096263Sobrien /* If we already output the OLDDECL, we're in trouble; we can't 426196263Sobrien go back and make it weak. This error cannot caught in 426296263Sobrien declare_weak because the NEWDECL and OLDDECL was not yet 426396263Sobrien been merged; therefore, TREE_ASM_WRITTEN was not set. */ 4264102780Skan if (TREE_ASM_WRITTEN (olddecl)) 4265132718Skan error ("%Jweak declaration of '%D' must precede definition", 4266132718Skan newdecl, newdecl); 4267102780Skan 4268102780Skan /* If we've already generated rtl referencing OLDDECL, we may 4269102780Skan have done so in a way that will not function properly with 4270102780Skan a weak symbol. */ 4271102780Skan else if (TREE_USED (olddecl) 4272102780Skan && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl))) 4273132718Skan warning ("%Jweak declaration of '%D' after first use results " 4274132718Skan "in unspecified behavior", newdecl, newdecl); 4275102780Skan 427696263Sobrien if (SUPPORTS_WEAK) 427796263Sobrien { 427896263Sobrien /* We put the NEWDECL on the weak_decls list at some point. 427996263Sobrien Replace it with the OLDDECL. */ 428096263Sobrien for (wd = weak_decls; wd; wd = TREE_CHAIN (wd)) 428196263Sobrien if (TREE_VALUE (wd) == newdecl) 428296263Sobrien { 428396263Sobrien TREE_VALUE (wd) = olddecl; 428496263Sobrien break; 428596263Sobrien } 428696263Sobrien /* We may not find the entry on the list. If NEWDECL is a 428796263Sobrien weak alias, then we will have already called 428896263Sobrien globalize_decl to remove the entry; in that case, we do 428996263Sobrien not need to do anything. */ 429096263Sobrien } 429152284Sobrien 429296263Sobrien /* Make the OLDDECL weak; it's OLDDECL that we'll be keeping. */ 429396263Sobrien mark_weak (olddecl); 429496263Sobrien } 429596263Sobrien else 429696263Sobrien /* OLDDECL was weak, but NEWDECL was not explicitly marked as 429796263Sobrien weak. Just update NEWDECL to indicate that it's weak too. */ 429896263Sobrien mark_weak (newdecl); 429952284Sobrien} 430018334Speter 430118334Speter/* Declare DECL to be a weak symbol. */ 430218334Speter 430318334Spetervoid 4304132718Skandeclare_weak (tree decl) 430518334Speter{ 430618334Speter if (! TREE_PUBLIC (decl)) 4307132718Skan error ("%Jweak declaration of '%D' must be public", decl, decl); 430896263Sobrien else if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl)) 4309132718Skan error ("%Jweak declaration of '%D' must precede definition", decl, decl); 431018334Speter else if (SUPPORTS_WEAK) 431196263Sobrien { 431296263Sobrien if (! DECL_WEAK (decl)) 431396263Sobrien weak_decls = tree_cons (NULL, decl, weak_decls); 431496263Sobrien } 431590075Sobrien else 4316132718Skan warning ("%Jweak declaration of '%D' not supported", decl, decl); 431790075Sobrien 431896263Sobrien mark_weak (decl); 431918334Speter} 432018334Speter 432118334Speter/* Emit any pending weak declarations. */ 432218334Speter 432318334Spetervoid 4324132718Skanweak_finish (void) 432518334Speter{ 432696263Sobrien tree t; 432796263Sobrien 4328117395Skan for (t = weak_decls; t; t = TREE_CHAIN (t)) 432918334Speter { 433096263Sobrien tree decl = TREE_VALUE (t); 4331132718Skan#if defined (ASM_WEAKEN_DECL) || defined (ASM_WEAKEN_LABEL) 4332132718Skan const char *const name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 4333132718Skan#endif 433496263Sobrien 433596263Sobrien if (! TREE_USED (decl)) 433696263Sobrien continue; 433796263Sobrien 433896263Sobrien#ifdef ASM_WEAKEN_DECL 433996263Sobrien ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL); 434090075Sobrien#else 434190075Sobrien#ifdef ASM_WEAKEN_LABEL 434296263Sobrien ASM_WEAKEN_LABEL (asm_out_file, name); 434396263Sobrien#else 434496263Sobrien#ifdef ASM_OUTPUT_WEAK_ALIAS 434596263Sobrien warning ("only weak aliases are supported in this configuration"); 434696263Sobrien return; 434790075Sobrien#endif 434890075Sobrien#endif 434996263Sobrien#endif 435018334Speter } 435118334Speter} 435218334Speter 435396263Sobrien/* Emit the assembly bits to indicate that DECL is globally visible. */ 435496263Sobrien 435552284Sobrienstatic void 4356132718Skanglobalize_decl (tree decl) 435752284Sobrien{ 435896263Sobrien const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0); 435990075Sobrien 436096263Sobrien#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) 436196263Sobrien if (DECL_WEAK (decl)) 436252284Sobrien { 436396263Sobrien tree *p, t; 436496263Sobrien 436596263Sobrien#ifdef ASM_WEAKEN_DECL 436696263Sobrien ASM_WEAKEN_DECL (asm_out_file, decl, name, 0); 436796263Sobrien#else 436896263Sobrien ASM_WEAKEN_LABEL (asm_out_file, name); 436996263Sobrien#endif 437096263Sobrien 437196263Sobrien /* Remove this function from the pending weak list so that 437296263Sobrien we do not emit multiple .weak directives for it. */ 437396263Sobrien for (p = &weak_decls; (t = *p) ; ) 437496263Sobrien { 437596263Sobrien if (DECL_ASSEMBLER_NAME (decl) == DECL_ASSEMBLER_NAME (TREE_VALUE (t))) 437696263Sobrien *p = TREE_CHAIN (t); 437796263Sobrien else 437896263Sobrien p = &TREE_CHAIN (t); 437996263Sobrien } 438096263Sobrien return; 438152284Sobrien } 438296263Sobrien#endif 438396263Sobrien 4384117395Skan (*targetm.asm_out.globalize_label) (asm_out_file, name); 438552284Sobrien} 438652284Sobrien 4387146895Skan/* Some targets do not allow a forward or undefined reference in a 4388146895Skan ASM_OUTPUT_DEF. Thus, a mechanism is needed to defer the output 4389146895Skan of this assembler code. The output_def_pair struct holds the 4390146895Skan declaration and target for a deferred output define. */ 4391146895Skanstruct output_def_pair GTY(()) 4392146895Skan{ 4393146895Skan tree decl; 4394146895Skan tree target; 4395146895Skan}; 4396146895Skantypedef struct output_def_pair *output_def_pair; 4397146895Skan 4398146895Skan/* Variable array of deferred output defines. */ 4399146895Skanstatic GTY ((param_is (struct output_def_pair))) varray_type output_defs; 4400146895Skan 4401146895Skan#ifdef ASM_OUTPUT_DEF 4402146895Skan/* Output the assembler code for a define (equate) using ASM_OUTPUT_DEF 4403146895Skan or ASM_OUTPUT_DEF_FROM_DECLS. The function defines the symbol whose 4404146895Skan tree node is DECL to have the value of the tree node TARGET. */ 4405146895Skan 4406146895Skanstatic void 4407146895Skanassemble_output_def (tree decl ATTRIBUTE_UNUSED, tree target ATTRIBUTE_UNUSED) 4408146895Skan{ 4409146895Skan#ifdef ASM_OUTPUT_DEF_FROM_DECLS 4410146895Skan ASM_OUTPUT_DEF_FROM_DECLS (asm_out_file, decl, target); 4411146895Skan#else 4412146895Skan ASM_OUTPUT_DEF (asm_out_file, 4413146895Skan IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), 4414146895Skan IDENTIFIER_POINTER (target)); 4415146895Skan#endif 4416146895Skan} 4417146895Skan#endif 4418146895Skan 4419146895Skan/* Process the varray of pending assembler defines. */ 4420146895Skan 4421146895Skanvoid 4422146895Skanprocess_pending_assemble_output_defs (void) 4423146895Skan{ 4424146895Skan#ifdef ASM_OUTPUT_DEF 4425146895Skan size_t i; 4426146895Skan output_def_pair p; 4427146895Skan 4428146895Skan if (!output_defs) 4429146895Skan return; 4430146895Skan 4431146895Skan for (i = 0; i < VARRAY_ACTIVE_SIZE (output_defs); i++) 4432146895Skan { 4433146895Skan p = VARRAY_GENERIC_PTR (output_defs, i); 4434146895Skan assemble_output_def (p->decl, p->target); 4435146895Skan } 4436146895Skan 4437146895Skan output_defs = NULL; 4438146895Skan#endif 4439146895Skan} 4440146895Skan 444190075Sobrien/* Emit an assembler directive to make the symbol for DECL an alias to 444290075Sobrien the symbol for TARGET. */ 444390075Sobrien 444418334Spetervoid 4445132718Skanassemble_alias (tree decl, tree target ATTRIBUTE_UNUSED) 444618334Speter{ 444790075Sobrien /* We must force creation of DECL_RTL for debug info generation, even though 444890075Sobrien we don't use it here. */ 444990075Sobrien make_decl_rtl (decl, NULL); 445018334Speter 445150397Sobrien#ifdef ASM_OUTPUT_DEF 445218334Speter /* Make name accessible from other files, if appropriate. */ 4453117395Skan 445418334Speter if (TREE_PUBLIC (decl)) 4455117395Skan { 4456117395Skan globalize_decl (decl); 4457117395Skan maybe_assemble_visibility (decl); 4458117395Skan } 445918334Speter 4460146895Skan if (TARGET_DEFERRED_OUTPUT_DEFS (decl, target)) 4461146895Skan { 4462146895Skan output_def_pair p; 4463146895Skan 4464146895Skan if (!output_defs) 4465146895Skan VARRAY_GENERIC_PTR_INIT (output_defs, 10, "output defs"); 4466146895Skan 4467146895Skan p = ggc_alloc (sizeof (struct output_def_pair)); 4468146895Skan p->decl = decl; 4469146895Skan p->target = target; 4470146895Skan VARRAY_PUSH_GENERIC_PTR (output_defs, p); 4471146895Skan } 4472146895Skan else 4473146895Skan assemble_output_def (decl, target); 447496263Sobrien#else /* !ASM_OUTPUT_DEF */ 447596263Sobrien#if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL) 4476132718Skan if (DECL_WEAK (decl)) 4477132718Skan { 4478146895Skan const char *name; 4479132718Skan tree *p, t; 4480146895Skan 4481146895Skan name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 448296263Sobrien#ifdef ASM_WEAKEN_DECL 4483132718Skan ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target)); 448496263Sobrien#else 4485132718Skan ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target)); 448696263Sobrien#endif 4487132718Skan /* Remove this function from the pending weak list so that 4488132718Skan we do not emit multiple .weak directives for it. */ 4489132718Skan for (p = &weak_decls; (t = *p) ; ) 4490132718Skan if (DECL_ASSEMBLER_NAME (decl) 4491132718Skan == DECL_ASSEMBLER_NAME (TREE_VALUE (t))) 4492132718Skan *p = TREE_CHAIN (t); 4493132718Skan else 4494132718Skan p = &TREE_CHAIN (t); 4495132718Skan } 4496132718Skan else 4497132718Skan warning ("only weak aliases are supported in this configuration"); 4498132718Skan 449950397Sobrien#else 450050397Sobrien warning ("alias definitions not supported in this configuration; ignored"); 450118334Speter#endif 450250397Sobrien#endif 4503102780Skan 4504102780Skan TREE_USED (decl) = 1; 4505102780Skan TREE_ASM_WRITTEN (decl) = 1; 4506102780Skan TREE_ASM_WRITTEN (DECL_ASSEMBLER_NAME (decl)) = 1; 450718334Speter} 450850397Sobrien 4509117395Skan/* Emit an assembler directive to set symbol for DECL visibility to 4510117395Skan the visibility type VIS, which must not be VISIBILITY_DEFAULT. */ 4511117395Skan 4512117395Skanvoid 4513132718Skandefault_assemble_visibility (tree decl, int vis) 4514117395Skan{ 4515117395Skan static const char * const visibility_types[] = { 4516117395Skan NULL, "internal", "hidden", "protected" 4517117395Skan }; 4518117395Skan 4519117395Skan const char *name, *type; 4520117395Skan 4521117395Skan name = (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); 4522117395Skan type = visibility_types[vis]; 4523117395Skan 4524117395Skan#ifdef HAVE_GAS_HIDDEN 4525117395Skan fprintf (asm_out_file, "\t.%s\t", type); 4526117395Skan assemble_name (asm_out_file, name); 4527117395Skan fprintf (asm_out_file, "\n"); 4528117395Skan#else 4529117395Skan warning ("visibility attribute not supported in this configuration; ignored"); 4530117395Skan#endif 4531117395Skan} 4532117395Skan 4533117395Skan/* A helper function to call assemble_visibility when needed for a decl. */ 4534117395Skan 4535117395Skanstatic void 4536132718Skanmaybe_assemble_visibility (tree decl) 4537117395Skan{ 4538132718Skan enum symbol_visibility vis = DECL_VISIBILITY (decl); 4539117395Skan 4540117395Skan if (vis != VISIBILITY_DEFAULT) 4541117395Skan (* targetm.asm_out.visibility) (decl, vis); 4542117395Skan} 4543117395Skan 454450397Sobrien/* Returns 1 if the target configuration supports defining public symbols 454550397Sobrien so that one of them will be chosen at link time instead of generating a 454650397Sobrien multiply-defined symbol error, whether through the use of weak symbols or 454750397Sobrien a target-specific mechanism for having duplicates discarded. */ 454850397Sobrien 454950397Sobrienint 4550132718Skansupports_one_only (void) 455150397Sobrien{ 455250397Sobrien if (SUPPORTS_ONE_ONLY) 455350397Sobrien return 1; 455450397Sobrien return SUPPORTS_WEAK; 455550397Sobrien} 455650397Sobrien 455750397Sobrien/* Set up DECL as a public symbol that can be defined in multiple 455850397Sobrien translation units without generating a linker error. */ 455950397Sobrien 456050397Sobrienvoid 4561132718Skanmake_decl_one_only (tree decl) 456250397Sobrien{ 456350397Sobrien if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) 456450397Sobrien abort (); 456550397Sobrien 456650397Sobrien TREE_PUBLIC (decl) = 1; 456750397Sobrien 4568132718Skan if (SUPPORTS_ONE_ONLY) 456950397Sobrien { 457050397Sobrien#ifdef MAKE_DECL_ONE_ONLY 457150397Sobrien MAKE_DECL_ONE_ONLY (decl); 457250397Sobrien#endif 457350397Sobrien DECL_ONE_ONLY (decl) = 1; 457450397Sobrien } 4575132718Skan else if (TREE_CODE (decl) == VAR_DECL 4576132718Skan && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node)) 4577132718Skan DECL_COMMON (decl) = 1; 457850397Sobrien else if (SUPPORTS_WEAK) 457950397Sobrien DECL_WEAK (decl) = 1; 458050397Sobrien else 458150397Sobrien abort (); 458250397Sobrien} 458390075Sobrien 458490075Sobrienvoid 4585132718Skaninit_varasm_once (void) 458690075Sobrien{ 4587132718Skan in_named_htab = htab_create_ggc (31, in_named_entry_hash, 4588132718Skan in_named_entry_eq, NULL); 4589132718Skan const_desc_htab = htab_create_ggc (1009, const_desc_hash, 4590132718Skan const_desc_eq, NULL); 459190075Sobrien 459290075Sobrien const_alias_set = new_alias_set (); 459390075Sobrien} 459490075Sobrien 4595117395Skanenum tls_model 4596132718Skandecl_tls_model (tree decl) 4597117395Skan{ 4598117395Skan enum tls_model kind; 4599117395Skan tree attr = lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl)); 4600117395Skan bool is_local; 4601117395Skan 4602117395Skan if (attr) 4603117395Skan { 4604117395Skan attr = TREE_VALUE (TREE_VALUE (attr)); 4605117395Skan if (TREE_CODE (attr) != STRING_CST) 4606117395Skan abort (); 4607117395Skan if (!strcmp (TREE_STRING_POINTER (attr), "local-exec")) 4608117395Skan kind = TLS_MODEL_LOCAL_EXEC; 4609117395Skan else if (!strcmp (TREE_STRING_POINTER (attr), "initial-exec")) 4610117395Skan kind = TLS_MODEL_INITIAL_EXEC; 4611117395Skan else if (!strcmp (TREE_STRING_POINTER (attr), "local-dynamic")) 4612117395Skan kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC; 4613117395Skan else if (!strcmp (TREE_STRING_POINTER (attr), "global-dynamic")) 4614117395Skan kind = TLS_MODEL_GLOBAL_DYNAMIC; 4615117395Skan else 4616117395Skan abort (); 4617117395Skan return kind; 4618117395Skan } 4619117395Skan 4620117395Skan is_local = (*targetm.binds_local_p) (decl); 4621117395Skan if (!flag_pic) 4622117395Skan { 4623117395Skan if (is_local) 4624117395Skan kind = TLS_MODEL_LOCAL_EXEC; 4625117395Skan else 4626117395Skan kind = TLS_MODEL_INITIAL_EXEC; 4627117395Skan } 4628117395Skan /* Local dynamic is inefficient when we're not combining the 4629117395Skan parts of the address. */ 4630117395Skan else if (optimize && is_local) 4631117395Skan kind = TLS_MODEL_LOCAL_DYNAMIC; 4632117395Skan else 4633117395Skan kind = TLS_MODEL_GLOBAL_DYNAMIC; 4634117395Skan if (kind < flag_tls_default) 4635117395Skan kind = flag_tls_default; 4636117395Skan 4637117395Skan return kind; 4638117395Skan} 4639117395Skan 464090075Sobrien/* Select a set of attributes for section NAME based on the properties 464190075Sobrien of DECL and whether or not RELOC indicates that DECL's initializer 464290075Sobrien might contain runtime relocations. 464390075Sobrien 464490075Sobrien We make the section read-only and executable for a function decl, 464590075Sobrien read-only for a const data decl, and writable for a non-const data decl. */ 464690075Sobrien 464790075Sobrienunsigned int 4648132718Skandefault_section_type_flags (tree decl, const char *name, int reloc) 464990075Sobrien{ 4650117395Skan return default_section_type_flags_1 (decl, name, reloc, flag_pic); 4651117395Skan} 4652117395Skan 4653117395Skanunsigned int 4654132718Skandefault_section_type_flags_1 (tree decl, const char *name, int reloc, 4655132718Skan int shlib) 4656117395Skan{ 465790075Sobrien unsigned int flags; 465890075Sobrien 465990075Sobrien if (decl && TREE_CODE (decl) == FUNCTION_DECL) 466090075Sobrien flags = SECTION_CODE; 4661117395Skan else if (decl && decl_readonly_section_1 (decl, reloc, shlib)) 466290075Sobrien flags = 0; 466390075Sobrien else 466490075Sobrien flags = SECTION_WRITE; 466590075Sobrien 466690075Sobrien if (decl && DECL_ONE_ONLY (decl)) 466790075Sobrien flags |= SECTION_LINKONCE; 466890075Sobrien 4669117395Skan if (decl && TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) 4670117395Skan flags |= SECTION_TLS | SECTION_WRITE; 4671117395Skan 467290075Sobrien if (strcmp (name, ".bss") == 0 467390075Sobrien || strncmp (name, ".bss.", 5) == 0 467490075Sobrien || strncmp (name, ".gnu.linkonce.b.", 16) == 0 467590075Sobrien || strcmp (name, ".sbss") == 0 467690075Sobrien || strncmp (name, ".sbss.", 6) == 0 4677117395Skan || strncmp (name, ".gnu.linkonce.sb.", 17) == 0 4678117395Skan || strcmp (name, ".tbss") == 0 4679117395Skan || strncmp (name, ".gnu.linkonce.tb.", 17) == 0) 468090075Sobrien flags |= SECTION_BSS; 468190075Sobrien 4682117395Skan if (strcmp (name, ".tdata") == 0 4683117395Skan || strcmp (name, ".tbss") == 0 4684117395Skan || strncmp (name, ".gnu.linkonce.td.", 17) == 0 4685117395Skan || strncmp (name, ".gnu.linkonce.tb.", 17) == 0) 4686117395Skan flags |= SECTION_TLS; 4687117395Skan 4688117395Skan /* These three sections have special ELF types. They are neither 4689117395Skan SHT_PROGBITS nor SHT_NOBITS, so when changing sections we don't 4690117395Skan want to print a section type (@progbits or @nobits). If someone 4691117395Skan is silly enough to emit code or TLS variables to one of these 4692117395Skan sections, then don't handle them specially. */ 4693117395Skan if (!(flags & (SECTION_CODE | SECTION_BSS | SECTION_TLS)) 4694117395Skan && (strcmp (name, ".init_array") == 0 4695117395Skan || strcmp (name, ".fini_array") == 0 4696117395Skan || strcmp (name, ".preinit_array") == 0)) 4697117395Skan flags |= SECTION_NOTYPE; 4698117395Skan 469990075Sobrien return flags; 470090075Sobrien} 470190075Sobrien 470290075Sobrien/* Output assembly to switch to section NAME with attribute FLAGS. 470390075Sobrien Four variants for common object file formats. */ 470490075Sobrien 470590075Sobrienvoid 4706132718Skandefault_no_named_section (const char *name ATTRIBUTE_UNUSED, 4707132718Skan unsigned int flags ATTRIBUTE_UNUSED) 470890075Sobrien{ 470990075Sobrien /* Some object formats don't support named sections at all. The 471090075Sobrien front-end should already have flagged this as an error. */ 471190075Sobrien abort (); 471290075Sobrien} 471390075Sobrien 471490075Sobrienvoid 4715132718Skandefault_elf_asm_named_section (const char *name, unsigned int flags) 471690075Sobrien{ 471790075Sobrien char flagchars[10], *f = flagchars; 471890075Sobrien 471990075Sobrien if (! named_section_first_declaration (name)) 472090075Sobrien { 472190075Sobrien fprintf (asm_out_file, "\t.section\t%s\n", name); 472290075Sobrien return; 472390075Sobrien } 472490075Sobrien 472590075Sobrien if (!(flags & SECTION_DEBUG)) 472690075Sobrien *f++ = 'a'; 472790075Sobrien if (flags & SECTION_WRITE) 472890075Sobrien *f++ = 'w'; 472990075Sobrien if (flags & SECTION_CODE) 473090075Sobrien *f++ = 'x'; 473190075Sobrien if (flags & SECTION_SMALL) 473290075Sobrien *f++ = 's'; 473390075Sobrien if (flags & SECTION_MERGE) 473490075Sobrien *f++ = 'M'; 473590075Sobrien if (flags & SECTION_STRINGS) 473690075Sobrien *f++ = 'S'; 4737117395Skan if (flags & SECTION_TLS) 4738117395Skan *f++ = 'T'; 473990075Sobrien *f = '\0'; 474090075Sobrien 4741117395Skan fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars); 474290075Sobrien 4743117395Skan if (!(flags & SECTION_NOTYPE)) 4744117395Skan { 4745117395Skan const char *type; 4746117395Skan 4747117395Skan if (flags & SECTION_BSS) 4748117395Skan type = "nobits"; 4749117395Skan else 4750117395Skan type = "progbits"; 4751117395Skan 4752117395Skan fprintf (asm_out_file, ",@%s", type); 4753117395Skan 4754117395Skan if (flags & SECTION_ENTSIZE) 4755117395Skan fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE); 4756117395Skan } 4757117395Skan 4758117395Skan putc ('\n', asm_out_file); 475990075Sobrien} 476090075Sobrien 476190075Sobrienvoid 4762132718Skandefault_coff_asm_named_section (const char *name, unsigned int flags) 476390075Sobrien{ 476490075Sobrien char flagchars[8], *f = flagchars; 476590075Sobrien 476690075Sobrien if (flags & SECTION_WRITE) 476790075Sobrien *f++ = 'w'; 476890075Sobrien if (flags & SECTION_CODE) 476990075Sobrien *f++ = 'x'; 477090075Sobrien *f = '\0'; 477190075Sobrien 477290075Sobrien fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars); 477390075Sobrien} 477490075Sobrien 477590075Sobrienvoid 4776132718Skandefault_pe_asm_named_section (const char *name, unsigned int flags) 477790075Sobrien{ 477890075Sobrien default_coff_asm_named_section (name, flags); 477990075Sobrien 478090075Sobrien if (flags & SECTION_LINKONCE) 478190075Sobrien { 478290075Sobrien /* Functions may have been compiled at various levels of 478390075Sobrien optimization so we can't use `same_size' here. 478490075Sobrien Instead, have the linker pick one. */ 478590075Sobrien fprintf (asm_out_file, "\t.linkonce %s\n", 478690075Sobrien (flags & SECTION_CODE ? "discard" : "same_size")); 478790075Sobrien } 478890075Sobrien} 478990075Sobrien 4790117395Skan/* The lame default section selector. */ 4791117395Skan 4792117395Skanvoid 4793132718Skandefault_select_section (tree decl, int reloc, 4794132718Skan unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) 4795117395Skan{ 4796117395Skan bool readonly = false; 4797117395Skan 4798117395Skan if (DECL_P (decl)) 4799117395Skan { 4800117395Skan if (decl_readonly_section (decl, reloc)) 4801117395Skan readonly = true; 4802117395Skan } 4803117395Skan else if (TREE_CODE (decl) == CONSTRUCTOR) 4804117395Skan { 4805117395Skan if (! ((flag_pic && reloc) 4806117395Skan || !TREE_READONLY (decl) 4807117395Skan || TREE_SIDE_EFFECTS (decl) 4808117395Skan || !TREE_CONSTANT (decl))) 4809117395Skan readonly = true; 4810117395Skan } 4811117395Skan else if (TREE_CODE (decl) == STRING_CST) 4812117395Skan readonly = !flag_writable_strings; 4813117395Skan else if (! (flag_pic && reloc)) 4814117395Skan readonly = true; 4815117395Skan 4816117395Skan if (readonly) 4817117395Skan readonly_data_section (); 4818117395Skan else 4819117395Skan data_section (); 4820117395Skan} 4821117395Skan 4822117395Skan/* A helper function for default_elf_select_section and 4823117395Skan default_elf_unique_section. Categorizes the DECL. */ 4824117395Skan 4825117395Skanenum section_category 4826117395Skan{ 4827117395Skan SECCAT_TEXT, 4828117395Skan 4829117395Skan SECCAT_RODATA, 4830117395Skan SECCAT_RODATA_MERGE_STR, 4831117395Skan SECCAT_RODATA_MERGE_STR_INIT, 4832117395Skan SECCAT_RODATA_MERGE_CONST, 4833117395Skan SECCAT_SRODATA, 4834117395Skan 4835117395Skan SECCAT_DATA, 4836117395Skan 4837117395Skan /* To optimize loading of shared programs, define following subsections 4838117395Skan of data section: 4839117395Skan _REL Contains data that has relocations, so they get grouped 4840117395Skan together and dynamic linker will visit fewer pages in memory. 4841117395Skan _RO Contains data that is otherwise read-only. This is useful 4842117395Skan with prelinking as most relocations won't be dynamically 4843117395Skan linked and thus stay read only. 4844117395Skan _LOCAL Marks data containing relocations only to local objects. 4845117395Skan These relocations will get fully resolved by prelinking. */ 4846117395Skan SECCAT_DATA_REL, 4847117395Skan SECCAT_DATA_REL_LOCAL, 4848117395Skan SECCAT_DATA_REL_RO, 4849117395Skan SECCAT_DATA_REL_RO_LOCAL, 4850117395Skan 4851117395Skan SECCAT_SDATA, 4852117395Skan SECCAT_TDATA, 4853117395Skan 4854117395Skan SECCAT_BSS, 4855117395Skan SECCAT_SBSS, 4856117395Skan SECCAT_TBSS 4857117395Skan}; 4858117395Skan 4859117395Skanstatic enum section_category 4860132718Skancategorize_decl_for_section (tree, int, int); 4861117395Skan 4862117395Skanstatic enum section_category 4863132718Skancategorize_decl_for_section (tree decl, int reloc, int shlib) 4864117395Skan{ 4865117395Skan enum section_category ret; 4866117395Skan 4867117395Skan if (TREE_CODE (decl) == FUNCTION_DECL) 4868117395Skan return SECCAT_TEXT; 4869117395Skan else if (TREE_CODE (decl) == STRING_CST) 4870117395Skan { 4871117395Skan if (flag_writable_strings) 4872117395Skan return SECCAT_DATA; 4873117395Skan else 4874117395Skan return SECCAT_RODATA_MERGE_STR; 4875117395Skan } 4876117395Skan else if (TREE_CODE (decl) == VAR_DECL) 4877117395Skan { 4878117395Skan if (DECL_INITIAL (decl) == NULL 4879117395Skan || DECL_INITIAL (decl) == error_mark_node) 4880117395Skan ret = SECCAT_BSS; 4881117395Skan else if (! TREE_READONLY (decl) 4882117395Skan || TREE_SIDE_EFFECTS (decl) 4883117395Skan || ! TREE_CONSTANT (DECL_INITIAL (decl))) 4884117395Skan { 4885117395Skan if (shlib && (reloc & 2)) 4886117395Skan ret = SECCAT_DATA_REL; 4887117395Skan else if (shlib && reloc) 4888117395Skan ret = SECCAT_DATA_REL_LOCAL; 4889117395Skan else 4890117395Skan ret = SECCAT_DATA; 4891117395Skan } 4892117395Skan else if (shlib && (reloc & 2)) 4893117395Skan ret = SECCAT_DATA_REL_RO; 4894117395Skan else if (shlib && reloc) 4895117395Skan ret = SECCAT_DATA_REL_RO_LOCAL; 4896117395Skan else if (reloc || flag_merge_constants < 2) 4897117395Skan /* C and C++ don't allow different variables to share the same 4898117395Skan location. -fmerge-all-constants allows even that (at the 4899117395Skan expense of not conforming). */ 4900117395Skan ret = SECCAT_RODATA; 4901117395Skan else if (TREE_CODE (DECL_INITIAL (decl)) == STRING_CST) 4902117395Skan ret = SECCAT_RODATA_MERGE_STR_INIT; 4903117395Skan else 4904117395Skan ret = SECCAT_RODATA_MERGE_CONST; 4905117395Skan } 4906117395Skan else if (TREE_CODE (decl) == CONSTRUCTOR) 4907117395Skan { 4908117395Skan if ((shlib && reloc) 4909117395Skan || TREE_SIDE_EFFECTS (decl) 4910117395Skan || ! TREE_CONSTANT (decl)) 4911117395Skan ret = SECCAT_DATA; 4912117395Skan else 4913117395Skan ret = SECCAT_RODATA; 4914117395Skan } 4915117395Skan else 4916117395Skan ret = SECCAT_RODATA; 4917117395Skan 4918117395Skan /* There are no read-only thread-local sections. */ 4919117395Skan if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) 4920117395Skan { 4921117395Skan if (ret == SECCAT_BSS) 4922117395Skan ret = SECCAT_TBSS; 4923117395Skan else 4924117395Skan ret = SECCAT_TDATA; 4925117395Skan } 4926117395Skan 4927117395Skan /* If the target uses small data sections, select it. */ 4928117395Skan else if ((*targetm.in_small_data_p) (decl)) 4929117395Skan { 4930117395Skan if (ret == SECCAT_BSS) 4931117395Skan ret = SECCAT_SBSS; 4932117395Skan else if (targetm.have_srodata_section && ret == SECCAT_RODATA) 4933117395Skan ret = SECCAT_SRODATA; 4934117395Skan else 4935117395Skan ret = SECCAT_SDATA; 4936117395Skan } 4937117395Skan 4938117395Skan return ret; 4939117395Skan} 4940117395Skan 4941117395Skanbool 4942132718Skandecl_readonly_section (tree decl, int reloc) 4943117395Skan{ 4944117395Skan return decl_readonly_section_1 (decl, reloc, flag_pic); 4945117395Skan} 4946117395Skan 4947117395Skanbool 4948132718Skandecl_readonly_section_1 (tree decl, int reloc, int shlib) 4949117395Skan{ 4950117395Skan switch (categorize_decl_for_section (decl, reloc, shlib)) 4951117395Skan { 4952117395Skan case SECCAT_RODATA: 4953117395Skan case SECCAT_RODATA_MERGE_STR: 4954117395Skan case SECCAT_RODATA_MERGE_STR_INIT: 4955117395Skan case SECCAT_RODATA_MERGE_CONST: 4956117395Skan case SECCAT_SRODATA: 4957117395Skan return true; 4958117395Skan break; 4959117395Skan default: 4960117395Skan return false; 4961117395Skan break; 4962117395Skan } 4963117395Skan} 4964117395Skan 4965117395Skan/* Select a section based on the above categorization. */ 4966117395Skan 4967117395Skanvoid 4968132718Skandefault_elf_select_section (tree decl, int reloc, 4969132718Skan unsigned HOST_WIDE_INT align) 4970117395Skan{ 4971117395Skan default_elf_select_section_1 (decl, reloc, align, flag_pic); 4972117395Skan} 4973117395Skan 4974117395Skanvoid 4975132718Skandefault_elf_select_section_1 (tree decl, int reloc, 4976132718Skan unsigned HOST_WIDE_INT align, int shlib) 4977117395Skan{ 4978117395Skan switch (categorize_decl_for_section (decl, reloc, shlib)) 4979117395Skan { 4980117395Skan case SECCAT_TEXT: 4981117395Skan /* We're not supposed to be called on FUNCTION_DECLs. */ 4982117395Skan abort (); 4983117395Skan case SECCAT_RODATA: 4984117395Skan readonly_data_section (); 4985117395Skan break; 4986117395Skan case SECCAT_RODATA_MERGE_STR: 4987117395Skan mergeable_string_section (decl, align, 0); 4988117395Skan break; 4989117395Skan case SECCAT_RODATA_MERGE_STR_INIT: 4990117395Skan mergeable_string_section (DECL_INITIAL (decl), align, 0); 4991117395Skan break; 4992117395Skan case SECCAT_RODATA_MERGE_CONST: 4993117395Skan mergeable_constant_section (DECL_MODE (decl), align, 0); 4994117395Skan break; 4995117395Skan case SECCAT_SRODATA: 4996117395Skan named_section (NULL_TREE, ".sdata2", reloc); 4997117395Skan break; 4998117395Skan case SECCAT_DATA: 4999117395Skan data_section (); 5000117395Skan break; 5001117395Skan case SECCAT_DATA_REL: 5002117395Skan named_section (NULL_TREE, ".data.rel", reloc); 5003117395Skan break; 5004117395Skan case SECCAT_DATA_REL_LOCAL: 5005117395Skan named_section (NULL_TREE, ".data.rel.local", reloc); 5006117395Skan break; 5007117395Skan case SECCAT_DATA_REL_RO: 5008117395Skan named_section (NULL_TREE, ".data.rel.ro", reloc); 5009117395Skan break; 5010117395Skan case SECCAT_DATA_REL_RO_LOCAL: 5011117395Skan named_section (NULL_TREE, ".data.rel.ro.local", reloc); 5012117395Skan break; 5013117395Skan case SECCAT_SDATA: 5014117395Skan named_section (NULL_TREE, ".sdata", reloc); 5015117395Skan break; 5016117395Skan case SECCAT_TDATA: 5017117395Skan named_section (NULL_TREE, ".tdata", reloc); 5018117395Skan break; 5019117395Skan case SECCAT_BSS: 5020117395Skan#ifdef BSS_SECTION_ASM_OP 5021117395Skan bss_section (); 5022117395Skan#else 5023117395Skan named_section (NULL_TREE, ".bss", reloc); 5024117395Skan#endif 5025117395Skan break; 5026117395Skan case SECCAT_SBSS: 5027117395Skan named_section (NULL_TREE, ".sbss", reloc); 5028117395Skan break; 5029117395Skan case SECCAT_TBSS: 5030117395Skan named_section (NULL_TREE, ".tbss", reloc); 5031117395Skan break; 5032117395Skan default: 5033117395Skan abort (); 5034117395Skan } 5035117395Skan} 5036117395Skan 5037117395Skan/* Construct a unique section name based on the decl name and the 5038117395Skan categorization performed above. */ 5039117395Skan 5040117395Skanvoid 5041132718Skandefault_unique_section (tree decl, int reloc) 5042117395Skan{ 5043117395Skan default_unique_section_1 (decl, reloc, flag_pic); 5044117395Skan} 5045117395Skan 5046117395Skanvoid 5047132718Skandefault_unique_section_1 (tree decl, int reloc, int shlib) 5048117395Skan{ 5049117395Skan bool one_only = DECL_ONE_ONLY (decl); 5050117395Skan const char *prefix, *name; 5051117395Skan size_t nlen, plen; 5052117395Skan char *string; 5053117395Skan 5054117395Skan switch (categorize_decl_for_section (decl, reloc, shlib)) 5055117395Skan { 5056117395Skan case SECCAT_TEXT: 5057117395Skan prefix = one_only ? ".gnu.linkonce.t." : ".text."; 5058117395Skan break; 5059117395Skan case SECCAT_RODATA: 5060117395Skan case SECCAT_RODATA_MERGE_STR: 5061117395Skan case SECCAT_RODATA_MERGE_STR_INIT: 5062117395Skan case SECCAT_RODATA_MERGE_CONST: 5063117395Skan prefix = one_only ? ".gnu.linkonce.r." : ".rodata."; 5064117395Skan break; 5065117395Skan case SECCAT_SRODATA: 5066117395Skan prefix = one_only ? ".gnu.linkonce.s2." : ".sdata2."; 5067117395Skan break; 5068117395Skan case SECCAT_DATA: 5069117395Skan case SECCAT_DATA_REL: 5070117395Skan case SECCAT_DATA_REL_LOCAL: 5071117395Skan case SECCAT_DATA_REL_RO: 5072117395Skan case SECCAT_DATA_REL_RO_LOCAL: 5073117395Skan prefix = one_only ? ".gnu.linkonce.d." : ".data."; 5074117395Skan break; 5075117395Skan case SECCAT_SDATA: 5076117395Skan prefix = one_only ? ".gnu.linkonce.s." : ".sdata."; 5077117395Skan break; 5078117395Skan case SECCAT_BSS: 5079117395Skan prefix = one_only ? ".gnu.linkonce.b." : ".bss."; 5080117395Skan break; 5081117395Skan case SECCAT_SBSS: 5082117395Skan prefix = one_only ? ".gnu.linkonce.sb." : ".sbss."; 5083117395Skan break; 5084117395Skan case SECCAT_TDATA: 5085117395Skan prefix = one_only ? ".gnu.linkonce.td." : ".tdata."; 5086117395Skan break; 5087117395Skan case SECCAT_TBSS: 5088117395Skan prefix = one_only ? ".gnu.linkonce.tb." : ".tbss."; 5089117395Skan break; 5090117395Skan default: 5091117395Skan abort (); 5092117395Skan } 5093117395Skan plen = strlen (prefix); 5094117395Skan 5095117395Skan name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 5096117395Skan name = (* targetm.strip_name_encoding) (name); 5097117395Skan nlen = strlen (name); 5098117395Skan 5099117395Skan string = alloca (nlen + plen + 1); 5100117395Skan memcpy (string, prefix, plen); 5101117395Skan memcpy (string + plen, name, nlen + 1); 5102117395Skan 5103117395Skan DECL_SECTION_NAME (decl) = build_string (nlen + plen, string); 5104117395Skan} 5105117395Skan 5106117395Skanvoid 5107132718Skandefault_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED, 5108132718Skan rtx x, 5109132718Skan unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) 5110117395Skan{ 5111117395Skan if (flag_pic) 5112117395Skan switch (GET_CODE (x)) 5113117395Skan { 5114117395Skan case CONST: 5115117395Skan case SYMBOL_REF: 5116117395Skan case LABEL_REF: 5117117395Skan data_section (); 5118117395Skan return; 5119117395Skan 5120117395Skan default: 5121117395Skan break; 5122117395Skan } 5123117395Skan 5124117395Skan readonly_data_section (); 5125117395Skan} 5126117395Skan 5127117395Skanvoid 5128132718Skandefault_elf_select_rtx_section (enum machine_mode mode, rtx x, 5129132718Skan unsigned HOST_WIDE_INT align) 5130117395Skan{ 5131117395Skan /* ??? Handle small data here somehow. */ 5132117395Skan 5133117395Skan if (flag_pic) 5134117395Skan switch (GET_CODE (x)) 5135117395Skan { 5136117395Skan case CONST: 5137117395Skan case SYMBOL_REF: 5138117395Skan named_section (NULL_TREE, ".data.rel.ro", 3); 5139117395Skan return; 5140117395Skan 5141117395Skan case LABEL_REF: 5142117395Skan named_section (NULL_TREE, ".data.rel.ro.local", 1); 5143117395Skan return; 5144117395Skan 5145117395Skan default: 5146117395Skan break; 5147117395Skan } 5148117395Skan 5149117395Skan mergeable_constant_section (mode, align, 0); 5150117395Skan} 5151117395Skan 5152132718Skan/* Set the generally applicable flags on the SYMBOL_REF for EXP. */ 5153132718Skan 5154132718Skanvoid 5155132718Skandefault_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED) 5156132718Skan{ 5157132718Skan rtx symbol; 5158132718Skan int flags; 5159132718Skan 5160132718Skan /* Careful not to prod global register variables. */ 5161132718Skan if (GET_CODE (rtl) != MEM) 5162132718Skan return; 5163132718Skan symbol = XEXP (rtl, 0); 5164132718Skan if (GET_CODE (symbol) != SYMBOL_REF) 5165132718Skan return; 5166132718Skan 5167132718Skan flags = 0; 5168132718Skan if (TREE_CODE (decl) == FUNCTION_DECL) 5169132718Skan flags |= SYMBOL_FLAG_FUNCTION; 5170132718Skan if ((*targetm.binds_local_p) (decl)) 5171132718Skan flags |= SYMBOL_FLAG_LOCAL; 5172132718Skan if ((*targetm.in_small_data_p) (decl)) 5173132718Skan flags |= SYMBOL_FLAG_SMALL; 5174132718Skan if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) 5175132718Skan flags |= decl_tls_model (decl) << SYMBOL_FLAG_TLS_SHIFT; 5176132718Skan /* ??? Why is DECL_EXTERNAL ever set for non-PUBLIC names? Without 5177132718Skan being PUBLIC, the thing *must* be defined in this translation unit. 5178132718Skan Prevent this buglet from being propagated into rtl code as well. */ 5179132718Skan if (DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)) 5180132718Skan flags |= SYMBOL_FLAG_EXTERNAL; 5181132718Skan 5182132718Skan SYMBOL_REF_FLAGS (symbol) = flags; 5183132718Skan} 5184132718Skan 5185117395Skan/* By default, we do nothing for encode_section_info, so we need not 5186117395Skan do anything but discard the '*' marker. */ 5187117395Skan 5188117395Skanconst char * 5189132718Skandefault_strip_name_encoding (const char *str) 5190117395Skan{ 5191117395Skan return str + (*str == '*'); 5192117395Skan} 5193117395Skan 5194117395Skan/* Assume ELF-ish defaults, since that's pretty much the most liberal 5195117395Skan wrt cross-module name binding. */ 5196117395Skan 5197117395Skanbool 5198132718Skandefault_binds_local_p (tree exp) 5199117395Skan{ 5200132718Skan return default_binds_local_p_1 (exp, flag_shlib); 5201117395Skan} 5202117395Skan 5203117395Skanbool 5204132718Skandefault_binds_local_p_1 (tree exp, int shlib) 5205117395Skan{ 5206117395Skan bool local_p; 5207117395Skan 5208117395Skan /* A non-decl is an entry in the constant pool. */ 5209117395Skan if (!DECL_P (exp)) 5210117395Skan local_p = true; 5211117395Skan /* Static variables are always local. */ 5212117395Skan else if (! TREE_PUBLIC (exp)) 5213117395Skan local_p = true; 5214117395Skan /* A variable is local if the user tells us so. */ 5215132718Skan else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) 5216117395Skan local_p = true; 5217117395Skan /* Otherwise, variables defined outside this object may not be local. */ 5218117395Skan else if (DECL_EXTERNAL (exp)) 5219117395Skan local_p = false; 5220117395Skan /* Linkonce and weak data are never local. */ 5221117395Skan else if (DECL_ONE_ONLY (exp) || DECL_WEAK (exp)) 5222117395Skan local_p = false; 5223117395Skan /* If PIC, then assume that any global name can be overridden by 5224117395Skan symbols resolved from other modules. */ 5225117395Skan else if (shlib) 5226117395Skan local_p = false; 5227117395Skan /* Uninitialized COMMON variable may be unified with symbols 5228117395Skan resolved from other modules. */ 5229117395Skan else if (DECL_COMMON (exp) 5230117395Skan && (DECL_INITIAL (exp) == NULL 5231117395Skan || DECL_INITIAL (exp) == error_mark_node)) 5232117395Skan local_p = false; 5233117395Skan /* Otherwise we're left with initialized (or non-common) global data 5234117395Skan which is of necessity defined locally. */ 5235117395Skan else 5236117395Skan local_p = true; 5237117395Skan 5238117395Skan return local_p; 5239117395Skan} 5240117395Skan 5241132718Skan/* Determine whether or not a pointer mode is valid. Assume defaults 5242132718Skan of ptr_mode or Pmode - can be overridden. */ 5243132718Skanbool 5244132718Skandefault_valid_pointer_mode (enum machine_mode mode) 5245132718Skan{ 5246132718Skan return (mode == ptr_mode || mode == Pmode); 5247132718Skan} 5248132718Skan 5249117395Skan/* Default function to output code that will globalize a label. A 5250117395Skan target must define GLOBAL_ASM_OP or provide it's own function to 5251117395Skan globalize a label. */ 5252117395Skan#ifdef GLOBAL_ASM_OP 5253117395Skanvoid 5254132718Skandefault_globalize_label (FILE * stream, const char *name) 5255117395Skan{ 5256117395Skan fputs (GLOBAL_ASM_OP, stream); 5257117395Skan assemble_name (stream, name); 5258117395Skan putc ('\n', stream); 5259117395Skan} 5260117395Skan#endif /* GLOBAL_ASM_OP */ 5261132718Skan 5262132718Skan/* This is how to output an internal numbered label where PREFIX is 5263132718Skan the class of label and LABELNO is the number within the class. */ 5264132718Skan 5265132718Skanvoid 5266132718Skandefault_internal_label (FILE *stream, const char *prefix, 5267132718Skan unsigned long labelno) 5268132718Skan{ 5269132718Skan char *const buf = alloca (40 + strlen (prefix)); 5270132718Skan ASM_GENERATE_INTERNAL_LABEL (buf, prefix, labelno); 5271132718Skan ASM_OUTPUT_LABEL (stream, buf); 5272132718Skan} 5273132718Skan 5274132718Skan/* This is the default behavior at the beginning of a file. It's 5275132718Skan controlled by two other target-hook toggles. */ 5276132718Skanvoid 5277132718Skandefault_file_start (void) 5278132718Skan{ 5279132718Skan if (targetm.file_start_app_off && !flag_verbose_asm) 5280132718Skan fputs (ASM_APP_OFF, asm_out_file); 5281132718Skan 5282132718Skan if (targetm.file_start_file_directive) 5283132718Skan output_file_directive (asm_out_file, main_input_filename); 5284132718Skan} 5285132718Skan 5286132718Skan/* This is a generic routine suitable for use as TARGET_ASM_FILE_END 5287132718Skan which emits a special section directive used to indicate whether or 5288132718Skan not this object file needs an executable stack. This is primarily 5289132718Skan a GNU extension to ELF but could be used on other targets. */ 5290132718Skanvoid 5291132718Skanfile_end_indicate_exec_stack (void) 5292132718Skan{ 5293132718Skan unsigned int flags = SECTION_DEBUG; 5294132718Skan if (trampolines_created) 5295132718Skan flags |= SECTION_CODE; 5296132718Skan 5297132718Skan named_section_flags (".note.GNU-stack", flags); 5298132718Skan} 5299132718Skan 5300117395Skan#include "gt-varasm.h" 5301