OSDN Git Service

* output.h (compute_reloc_for_constant): Declare.
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Oct 2003 22:57:57 +0000 (22:57 +0000)
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Oct 2003 22:57:57 +0000 (22:57 +0000)
* 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

gcc/ChangeLog
gcc/output.h
gcc/varasm.c

index d20632b..297a012 100644 (file)
@@ -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.
index c4fdc53..9fbc726 100644 (file)
@@ -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;
 
index 47db821..ea43a7d 100644 (file)
@@ -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;
 }
 \f
-/* 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;
+    }
+}
 \f
 /* Return nonzero if VALUE is a valid constant-valued expression
    for use in initializing a static variable; one that can be an