diff options
author | kan <kan@FreeBSD.org> | 2005-06-03 03:28:44 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2005-06-03 03:28:44 +0000 |
commit | 2156e40a831a8e0ab68e4bc091c2940bf46ca6df (patch) | |
tree | f0dc8ad34f9fcaf27052e24e893a4284b5fee6e9 /contrib/gcc/varasm.c | |
parent | 0a20abcc95340c9d2bb59421bac84eca4fb43b0c (diff) | |
download | FreeBSD-src-2156e40a831a8e0ab68e4bc091c2940bf46ca6df.zip FreeBSD-src-2156e40a831a8e0ab68e4bc091c2940bf46ca6df.tar.gz |
Gcc 3.4.4 release.
Diffstat (limited to 'contrib/gcc/varasm.c')
-rw-r--r-- | contrib/gcc/varasm.c | 201 |
1 files changed, 131 insertions, 70 deletions
diff --git a/contrib/gcc/varasm.c b/contrib/gcc/varasm.c index e61b5b4..33307e5 100644 --- a/contrib/gcc/varasm.c +++ b/contrib/gcc/varasm.c @@ -2350,7 +2350,8 @@ compare_constant (const tree t1, const tree t2) } /* Make a copy of the whole tree structure for a constant. This - handles the same types of nodes that compare_constant handles. */ + handles the same types of nodes that compare_constant handles. + Writable string constants are never copied. */ static tree copy_constant (tree exp) @@ -2366,9 +2367,12 @@ copy_constant (tree exp) else return copy_node (exp); + case STRING_CST: + if (flag_writable_strings) + return exp; + /* FALLTHROUGH */ case INTEGER_CST: case REAL_CST: - case STRING_CST: return copy_node (exp); case COMPLEX_CST: @@ -2434,10 +2438,7 @@ build_constant_desc (tree exp) struct constant_descriptor_tree *desc; desc = ggc_alloc (sizeof (*desc)); - if (flag_writable_strings && TREE_CODE (exp) == STRING_CST) - desc->value = exp; - else - desc->value = copy_constant (exp); + desc->value = copy_constant (exp); /* Create a string containing the label name, in LABEL. */ labelno = const_labelno++; @@ -3555,63 +3556,61 @@ initializer_constant_valid_p (tree value, tree endtype) case CONVERT_EXPR: case NOP_EXPR: - /* Allow conversions between pointer types. */ - if (POINTER_TYPE_P (TREE_TYPE (value)) - && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow conversions between real types. */ - if (FLOAT_TYPE_P (TREE_TYPE (value)) - && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow length-preserving conversions between integer types. */ - if (INTEGRAL_TYPE_P (TREE_TYPE (value)) - && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))) - && (TYPE_PRECISION (TREE_TYPE (value)) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow conversions between other integer types only if - explicit value. */ - if (INTEGRAL_TYPE_P (TREE_TYPE (value)) - && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) - { - tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - if (inner == null_pointer_node) - return null_pointer_node; - break; - } + { + tree src; + tree src_type; + tree dest_type; + + src = TREE_OPERAND (value, 0); + src_type = TREE_TYPE (src); + dest_type = TREE_TYPE (value); + + /* Allow conversions between pointer types, floating-point + types, and offset types. */ + if ((POINTER_TYPE_P (dest_type) && POINTER_TYPE_P (src_type)) + || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type)) + || (TREE_CODE (dest_type) == OFFSET_TYPE + && TREE_CODE (src_type) == OFFSET_TYPE)) + return initializer_constant_valid_p (src, endtype); + + /* Allow length-preserving conversions between integer types. */ + if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type) + && (TYPE_PRECISION (dest_type) == TYPE_PRECISION (src_type))) + return initializer_constant_valid_p (src, endtype); + + /* Allow conversions between other integer types only if + explicit value. */ + if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type)) + { + tree inner = initializer_constant_valid_p (src, endtype); + if (inner == null_pointer_node) + return null_pointer_node; + break; + } - /* Allow (int) &foo provided int is as wide as a pointer. */ - if (INTEGRAL_TYPE_P (TREE_TYPE (value)) - && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))) - && (TYPE_PRECISION (TREE_TYPE (value)) - >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - - /* Likewise conversions from int to pointers, but also allow - conversions from 0. */ - if ((POINTER_TYPE_P (TREE_TYPE (value)) - || TREE_CODE (TREE_TYPE (value)) == OFFSET_TYPE) - && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) - { - if (integer_zerop (TREE_OPERAND (value, 0))) - return null_pointer_node; - else if (TYPE_PRECISION (TREE_TYPE (value)) - <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - } + /* Allow (int) &foo provided int is as wide as a pointer. */ + if (INTEGRAL_TYPE_P (dest_type) && POINTER_TYPE_P (src_type) + && (TYPE_PRECISION (dest_type) >= TYPE_PRECISION (src_type))) + return initializer_constant_valid_p (src, endtype); - /* Allow conversions to struct or union types if the value - inside is okay. */ - if (TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE - || TREE_CODE (TREE_TYPE (value)) == UNION_TYPE) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); + /* Likewise conversions from int to pointers, but also allow + conversions from 0. */ + if ((POINTER_TYPE_P (dest_type) + || TREE_CODE (dest_type) == OFFSET_TYPE) + && INTEGRAL_TYPE_P (src_type)) + { + if (integer_zerop (src)) + return null_pointer_node; + else if (TYPE_PRECISION (dest_type) <= TYPE_PRECISION (src_type)) + return initializer_constant_valid_p (src, endtype); + } + + /* Allow conversions to struct or union types if the value + inside is okay. */ + if (TREE_CODE (dest_type) == RECORD_TYPE + || TREE_CODE (dest_type) == UNION_TYPE) + return initializer_constant_valid_p (src, endtype); + } break; case PLUS_EXPR: @@ -4385,20 +4384,70 @@ globalize_decl (tree decl) (*targetm.asm_out.globalize_label) (asm_out_file, name); } +/* Some targets do not allow a forward or undefined reference in a + ASM_OUTPUT_DEF. Thus, a mechanism is needed to defer the output + of this assembler code. The output_def_pair struct holds the + declaration and target for a deferred output define. */ +struct output_def_pair GTY(()) +{ + tree decl; + tree target; +}; +typedef struct output_def_pair *output_def_pair; + +/* Variable array of deferred output defines. */ +static GTY ((param_is (struct output_def_pair))) varray_type output_defs; + +#ifdef ASM_OUTPUT_DEF +/* Output the assembler code for a define (equate) using ASM_OUTPUT_DEF + or ASM_OUTPUT_DEF_FROM_DECLS. The function defines the symbol whose + tree node is DECL to have the value of the tree node TARGET. */ + +static void +assemble_output_def (tree decl ATTRIBUTE_UNUSED, tree target ATTRIBUTE_UNUSED) +{ +#ifdef ASM_OUTPUT_DEF_FROM_DECLS + ASM_OUTPUT_DEF_FROM_DECLS (asm_out_file, decl, target); +#else + ASM_OUTPUT_DEF (asm_out_file, + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), + IDENTIFIER_POINTER (target)); +#endif +} +#endif + +/* Process the varray of pending assembler defines. */ + +void +process_pending_assemble_output_defs (void) +{ +#ifdef ASM_OUTPUT_DEF + size_t i; + output_def_pair p; + + if (!output_defs) + return; + + for (i = 0; i < VARRAY_ACTIVE_SIZE (output_defs); i++) + { + p = VARRAY_GENERIC_PTR (output_defs, i); + assemble_output_def (p->decl, p->target); + } + + output_defs = NULL; +#endif +} + /* Emit an assembler directive to make the symbol for DECL an alias to the symbol for TARGET. */ void assemble_alias (tree decl, tree target ATTRIBUTE_UNUSED) { - const char *name; - /* We must force creation of DECL_RTL for debug info generation, even though we don't use it here. */ make_decl_rtl (decl, NULL); - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - #ifdef ASM_OUTPUT_DEF /* Make name accessible from other files, if appropriate. */ @@ -4408,16 +4457,28 @@ assemble_alias (tree decl, tree target ATTRIBUTE_UNUSED) maybe_assemble_visibility (decl); } -#ifdef ASM_OUTPUT_DEF_FROM_DECLS - ASM_OUTPUT_DEF_FROM_DECLS (asm_out_file, decl, target); -#else - ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target)); -#endif + if (TARGET_DEFERRED_OUTPUT_DEFS (decl, target)) + { + output_def_pair p; + + if (!output_defs) + VARRAY_GENERIC_PTR_INIT (output_defs, 10, "output defs"); + + p = ggc_alloc (sizeof (struct output_def_pair)); + p->decl = decl; + p->target = target; + VARRAY_PUSH_GENERIC_PTR (output_defs, p); + } + else + assemble_output_def (decl, target); #else /* !ASM_OUTPUT_DEF */ #if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL) if (DECL_WEAK (decl)) { + const char *name; tree *p, t; + + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); #ifdef ASM_WEAKEN_DECL ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target)); #else |