GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* This file handles generation of all the assembler code
/* We give all constants their own alias set. Perhaps redundant with
MEM_READONLY_P, but pre-dates it. */
-static HOST_WIDE_INT const_alias_set;
+static alias_set_type const_alias_set;
static const char *strip_reg_name (const char *);
static int contains_pointers_p (tree);
/* Return true if DECL's initializer is suitable for a BSS section. */
static bool
-bss_initializer_p (tree decl)
+bss_initializer_p (const_tree decl)
{
return (DECL_INITIAL (decl) == NULL
|| DECL_INITIAL (decl) == error_mark_node
if (flag_reorder_blocks_and_partition)
{
switch_to_section (unlikely_text_section ());
- assemble_align (FUNCTION_BOUNDARY);
+ assemble_align (DECL_ALIGN (decl));
ASM_OUTPUT_LABEL (asm_out_file, cfun->cold_section_label);
/* When the function starts with a cold section, we need to explicitly
&& BB_PARTITION (ENTRY_BLOCK_PTR->next_bb) == BB_COLD_PARTITION)
{
switch_to_section (text_section);
- assemble_align (FUNCTION_BOUNDARY);
+ assemble_align (DECL_ALIGN (decl));
ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_label);
hot_label_written = true;
first_function_block_is_cold = true;
ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_label);
/* Tell assembler to move to target machine's alignment for functions. */
- align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
- if (align < force_align_functions_log)
- align = force_align_functions_log;
+ align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
if (align > 0)
{
ASM_OUTPUT_ALIGN (asm_out_file, align);
}
/* Handle a user-specified function alignment.
- Note that we still need to align to FUNCTION_BOUNDARY, as above,
+ Note that we still need to align to DECL_ALIGN, as above,
because ASM_OUTPUT_MAX_SKIP_ALIGN might not do any alignment at all. */
- if (align_functions_log > align
+ if (! DECL_USER_ALIGN (decl)
+ && align_functions_log > align
&& cfun->function_frequency != FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
{
#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
enum machine_mode omode, imode;
unsigned int subalign;
unsigned int subsize, i;
+ unsigned char mclass;
subsize = size > UNITS_PER_WORD? UNITS_PER_WORD : 1;
subalign = MIN (align, subsize * BITS_PER_UNIT);
- omode = mode_for_size (subsize * BITS_PER_UNIT, MODE_INT, 0);
- imode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
+ if (GET_CODE (x) == CONST_FIXED)
+ mclass = GET_MODE_CLASS (GET_MODE (x));
+ else
+ mclass = MODE_INT;
+
+ omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0);
+ imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0);
for (i = 0; i < size; i += subsize)
{
break;
case REAL_CST:
+ case FIXED_CST:
case STRING_CST:
case COMPLEX_CST:
case CONSTRUCTOR:
static hashval_t
const_desc_hash (const void *ptr)
{
- return ((struct constant_descriptor_tree *)ptr)->hash;
+ return ((const struct constant_descriptor_tree *)ptr)->hash;
}
static hashval_t
case REAL_CST:
return real_hash (TREE_REAL_CST_PTR (exp));
+ case FIXED_CST:
+ return fixed_hash (TREE_FIXED_CST_PTR (exp));
+
case STRING_CST:
p = TREE_STRING_POINTER (exp);
len = TREE_STRING_LENGTH (exp);
return hi;
case PLUS_EXPR:
+ case POINTER_PLUS_EXPR:
case MINUS_EXPR:
return (const_hash_1 (TREE_OPERAND (exp, 0)) * 9
+ const_hash_1 (TREE_OPERAND (exp, 1)));
return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
+ case FIXED_CST:
+ /* Fixed constants are the same only if the same width of type. */
+ if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
+ return 0;
+
+ return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1), TREE_FIXED_CST (t2));
+
case STRING_CST:
if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
return 0;
}
case PLUS_EXPR:
+ case POINTER_PLUS_EXPR:
case MINUS_EXPR:
case RANGE_EXPR:
return (compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))
case INTEGER_CST:
case REAL_CST:
+ case FIXED_CST:
case STRING_CST:
return copy_node (exp);
copy_constant (TREE_IMAGPART (exp)));
case PLUS_EXPR:
+ case POINTER_PLUS_EXPR:
case MINUS_EXPR:
return build2 (TREE_CODE (exp), TREE_TYPE (exp),
copy_constant (TREE_OPERAND (exp, 0)),
h ^= real_hash (CONST_DOUBLE_REAL_VALUE (x));
break;
+ case CONST_FIXED:
+ h ^= fixed_hash (CONST_FIXED_VALUE (x));
+ break;
+
case CONST_VECTOR:
{
int i;
/* Similar, return the mode. */
enum machine_mode
-get_pool_mode (rtx addr)
+get_pool_mode (const_rtx addr)
{
return SYMBOL_REF_CONSTANT (addr)->mode;
}
case MODE_INT:
case MODE_PARTIAL_INT:
+ case MODE_FRACT:
+ case MODE_UFRACT:
+ case MODE_ACCUM:
+ case MODE_UACCUM:
assemble_integer (x, GET_MODE_SIZE (mode), align, 1);
break;
case MODE_VECTOR_FLOAT:
case MODE_VECTOR_INT:
+ case MODE_VECTOR_FRACT:
+ case MODE_VECTOR_UFRACT:
+ case MODE_VECTOR_ACCUM:
+ case MODE_VECTOR_UACCUM:
{
int i, units;
enum machine_mode submode = GET_MODE_INNER (mode);
break;
case PLUS_EXPR:
+ case POINTER_PLUS_EXPR:
reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
reloc |= compute_reloc_for_constant (TREE_OPERAND (exp, 1));
break;
break;
case PLUS_EXPR:
+ case POINTER_PLUS_EXPR:
case MINUS_EXPR:
output_addressed_constants (TREE_OPERAND (exp, 1));
/* Fall through. */
evaluate the property while walking a constructor for other purposes. */
bool
-constructor_static_from_elts_p (tree ctor)
+constructor_static_from_elts_p (const_tree ctor)
{
return (TREE_CONSTANT (ctor)
&& (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE
case INTEGER_CST:
case VECTOR_CST:
case REAL_CST:
+ case FIXED_CST:
case STRING_CST:
case COMPLEX_CST:
return null_pointer_node;
}
break;
+ case POINTER_PLUS_EXPR:
case PLUS_EXPR:
if (! INTEGRAL_TYPE_P (endtype)
|| TYPE_PRECISION (endtype) >= POINTER_SIZE)
endtype);
tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
endtype);
- /* If either term is absolute, use the other terms relocation. */
+ /* If either term is absolute, use the other term's relocation. */
if (valid0 == null_pointer_node)
return valid1;
if (valid1 == null_pointer_node)
case POINTER_TYPE:
case REFERENCE_TYPE:
case OFFSET_TYPE:
+ case FIXED_POINT_TYPE:
if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode,
EXPAND_INITIALIZER),
MIN (size, thissize), align, 0))
- error ("initializer for integer value is too complicated");
+ error ("initializer for integer/fixed-point value is too complicated");
break;
case REAL_TYPE:
}
enum tls_model
-decl_default_tls_model (tree decl)
+decl_default_tls_model (const_tree decl)
{
enum tls_model kind;
bool is_local;
}
enum section_category
-categorize_decl_for_section (tree decl, int reloc)
+categorize_decl_for_section (const_tree decl, int reloc)
{
enum section_category ret;
}
bool
-decl_readonly_section (tree decl, int reloc)
+decl_readonly_section (const_tree decl, int reloc)
{
switch (categorize_decl_for_section (decl, reloc))
{
/* The default implementation of TARGET_USE_ANCHORS_FOR_SYMBOL_P. */
bool
-default_use_anchors_for_symbol_p (rtx symbol)
+default_use_anchors_for_symbol_p (const_rtx symbol)
{
section *sect;
tree decl;
wrt cross-module name binding. */
bool
-default_binds_local_p (tree exp)
+default_binds_local_p (const_tree exp)
{
return default_binds_local_p_1 (exp, flag_shlib);
}
bool
-default_binds_local_p_1 (tree exp, int shlib)
+default_binds_local_p_1 (const_tree exp, int shlib)
{
bool local_p;
else if (DECL_WEAK (exp))
local_p = false;
/* If PIC, then assume that any global name can be overridden by
- symbols resolved from other modules. */
+ symbols resolved from other modules, unless we are compiling with
+ -fwhole-program, which assumes that names are local. */
else if (shlib)
- local_p = false;
+ local_p = flag_whole_program;
/* Uninitialized COMMON variable may be unified with symbols
resolved from other modules. */
else if (DECL_COMMON (exp)