diff options
author | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-10-01 22:57:57 +0000 |
---|---|---|
committer | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-10-01 22:57:57 +0000 |
commit | ee4722fe75c9ac8daf218a254f0211bb5f554567 (patch) | |
tree | bbd97c70ecaadc17cbc3a74ea03bb24419c8944b | |
parent | 22ed000fbf7011f4786181f7782aa2e851d6ba3e (diff) | |
download | gcc-ee4722fe75c9ac8daf218a254f0211bb5f554567.tar.gz |
* output.h (compute_reloc_for_constant): Declare.
* varasm.c (compute_reloc_for_constant): Extract from...
(output_addressed_constants): ... here. Adjust all callers.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72000 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/output.h | 4 | ||||
-rw-r--r-- | gcc/varasm.c | 87 |
3 files changed, 80 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d20632b3f92..297a01244ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2003-10-01 Alexandre Oliva <aoliva@redhat.com> + + * output.h (compute_reloc_for_constant): Declare. + * varasm.c (compute_reloc_for_constant): Extract from... + (output_addressed_constants): ... here. Adjust all callers. + 2003-10-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> * aclocal.m4: Add hpux10* and hpux11.00 to /dev/zero blacklist. @@ -10,7 +16,7 @@ 2003-09-30 Alexandre Oliva <aoliva@redhat.com> - config/frv/frv.h (PREDICATE_CODES): Added + * config/frv/frv.h (PREDICATE_CODES): Added condexec_si_media_operator, condexec_sf_add_operator and condexec_sf_conv_operator. Removed condexec_sf_binary_operator and condexec_sf_unary_operator. diff --git a/gcc/output.h b/gcc/output.h index c4fdc536746..9fbc726a665 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -437,6 +437,10 @@ extern rtx this_is_asm_operands; extern bool decl_readonly_section (tree, int); extern bool decl_readonly_section_1 (tree, int, int); +/* This can be used to compute RELOC for the function above, when + given a constant expression. */ +extern int compute_reloc_for_constant (tree); + /* User label prefix in effect for this compilation. */ extern const char *user_label_prefix; diff --git a/gcc/varasm.c b/gcc/varasm.c index 47db821d92d..ea43a7d3e1b 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -154,7 +154,7 @@ static struct pool_constant *find_pool_constant (struct function *, rtx); static void mark_constant_pool (void); static void mark_constants (rtx); static int mark_constant (rtx *current_rtx, void *data); -static int output_addressed_constants (tree); +static void output_addressed_constants (tree); static unsigned HOST_WIDE_INT array_size_for_constructor (tree); static unsigned min_align (unsigned, unsigned); static void output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int); @@ -1459,7 +1459,10 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, if (DECL_INITIAL (decl) == error_mark_node) reloc = contains_pointers_p (TREE_TYPE (decl)) ? 3 : 0; else if (DECL_INITIAL (decl)) - reloc = output_addressed_constants (DECL_INITIAL (decl)); + { + reloc = compute_reloc_for_constant (DECL_INITIAL (decl)); + output_addressed_constants (DECL_INITIAL (decl)); + } resolve_unique_section (decl, reloc, flag_data_sections); /* Handle uninitialized definitions. */ @@ -2501,7 +2504,7 @@ output_constant_def_contents (rtx symbol) /* Make sure any other constants whose addresses appear in EXP are assigned label numbers. */ - int reloc = output_addressed_constants (exp); + int reloc = compute_reloc_for_constant (exp); /* Align the location counter as required by EXP's data type. */ int align = TYPE_ALIGN (TREE_TYPE (exp)); @@ -2509,6 +2512,8 @@ output_constant_def_contents (rtx symbol) align = CONSTANT_ALIGNMENT (exp, align); #endif + output_addressed_constants (exp); + /* We are no longer deferring this constant. */ TREE_ASM_WRITTEN (exp) = 1; @@ -3329,12 +3334,10 @@ mark_constant (rtx *current_rtx, void *data ATTRIBUTE_UNUSED) return 0; } -/* Find all the constants whose addresses are referenced inside of EXP, - and make sure assembler code with a label has been output for each one. - Indicate whether an ADDR_EXPR has been encountered. */ +/* Determine what kind of relocations EXP may need. */ -static int -output_addressed_constants (tree exp) +int +compute_reloc_for_constant (tree exp) { int reloc = 0, reloc2; tree tem; @@ -3354,10 +3357,6 @@ output_addressed_constants (tree exp) tem = TREE_OPERAND (tem, 0)) ; - if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c' - || TREE_CODE (tem) == CONSTRUCTOR) - output_constant_def (tem, 0); - if (TREE_PUBLIC (tem)) reloc |= 2; else @@ -3365,13 +3364,13 @@ output_addressed_constants (tree exp) break; case PLUS_EXPR: - reloc = output_addressed_constants (TREE_OPERAND (exp, 0)); - reloc |= output_addressed_constants (TREE_OPERAND (exp, 1)); + reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0)); + reloc |= compute_reloc_for_constant (TREE_OPERAND (exp, 1)); break; case MINUS_EXPR: - reloc = output_addressed_constants (TREE_OPERAND (exp, 0)); - reloc2 = output_addressed_constants (TREE_OPERAND (exp, 1)); + reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0)); + reloc2 = compute_reloc_for_constant (TREE_OPERAND (exp, 1)); /* The difference of two local labels is computable at link time. */ if (reloc == 1 && reloc2 == 1) reloc = 0; @@ -3382,13 +3381,13 @@ output_addressed_constants (tree exp) case NOP_EXPR: case CONVERT_EXPR: case NON_LVALUE_EXPR: - reloc = output_addressed_constants (TREE_OPERAND (exp, 0)); + reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0)); break; case CONSTRUCTOR: for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem)) if (TREE_VALUE (tem) != 0) - reloc |= output_addressed_constants (TREE_VALUE (tem)); + reloc |= compute_reloc_for_constant (TREE_VALUE (tem)); break; @@ -3397,6 +3396,58 @@ output_addressed_constants (tree exp) } return reloc; } + +/* Find all the constants whose addresses are referenced inside of EXP, + and make sure assembler code with a label has been output for each one. + Indicate whether an ADDR_EXPR has been encountered. */ + +static void +output_addressed_constants (tree exp) +{ + tree tem; + + /* Give the front-end a chance to convert VALUE to something that + looks more like a constant to the back-end. */ + exp = (*lang_hooks.expand_constant) (exp); + + switch (TREE_CODE (exp)) + { + case ADDR_EXPR: + case FDESC_EXPR: + /* Go inside any operations that get_inner_reference can handle and see + if what's inside is a constant: no need to do anything here for + addresses of variables or functions. */ + for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem); + tem = TREE_OPERAND (tem, 0)) + ; + + if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c' + || TREE_CODE (tem) == CONSTRUCTOR) + output_constant_def (tem, 0); + break; + + case PLUS_EXPR: + case MINUS_EXPR: + output_addressed_constants (TREE_OPERAND (exp, 1)); + /* Fall through. */ + + case NOP_EXPR: + case CONVERT_EXPR: + case NON_LVALUE_EXPR: + output_addressed_constants (TREE_OPERAND (exp, 0)); + break; + + case CONSTRUCTOR: + for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem)) + if (TREE_VALUE (tem) != 0) + output_addressed_constants (TREE_VALUE (tem)); + + break; + + default: + break; + } +} /* Return nonzero if VALUE is a valid constant-valued expression for use in initializing a static variable; one that can be an |