* emit-rtl.c (gen_complex_constant_part): New function for getting
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 May 2003 21:41:21 +0000 (21:41 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 May 2003 21:41:21 +0000 (21:41 +0000)
the constant real or imaginary part of a complex constant.
(gen_realpart): Use it.
(gen_imagpart): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@67252 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/emit-rtl.c

index d98af3a..07455ab 100644 (file)
@@ -1,3 +1,10 @@
+2003-05-30  Roger Sayle  <roger@eyesopen.com>
+
+       * emit-rtl.c (gen_complex_constant_part): New function for getting
+       the constant real or imaginary part of a complex constant.
+       (gen_realpart): Use it.
+       (gen_imagpart): Likewise.
+
 2003-05-30  Kazu Hirata  <kazu@cs.umass.edu>
 
        * doc/invoke.texi: Fix typos.
index f568991..1bb79dd 100644 (file)
@@ -202,6 +202,8 @@ static int reg_attrs_htab_eq            PARAMS ((const void *,
 static reg_attrs *get_reg_attrs                PARAMS ((tree, int));
 static tree component_ref_for_mem_expr PARAMS ((tree));
 static rtx gen_const_vector_0          PARAMS ((enum machine_mode));
+static rtx gen_complex_constant_part   PARAMS ((enum machine_mode,
+                                                rtx, int));
 
 /* Probability of the conditional branch currently proceeded by try_split.
    Set to -1 otherwise.  */
@@ -1294,6 +1296,35 @@ gen_lowpart_common (mode, x)
   return 0;
 }
 \f
+/* Return the constant real or imaginary part (which has mode MODE)
+   of a complex value X.  The IMAGPART_P argument determines whether
+   the real or complex component should be returned.  This function
+   returns NULL_RTX if the component isn't a constant.  */
+
+static rtx
+gen_complex_constant_part (mode, x, imagpart_p)
+     enum machine_mode mode;
+     rtx x;
+     int imagpart_p;
+{
+  tree decl, part;
+
+  if (GET_CODE (x) == MEM
+      && GET_CODE (XEXP (x, 0)) == SYMBOL_REF
+      && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
+    {
+      decl = SYMBOL_REF_DECL (XEXP (x, 0));
+      if (decl != NULL_TREE && TREE_CODE (decl) == COMPLEX_CST)
+       {
+         part = imagpart_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl);
+         if (TREE_CODE (part) == REAL_CST
+             || TREE_CODE (part) == INTEGER_CST)
+           return expand_expr (part, NULL_RTX, mode, 0);
+       }
+    }
+  return NULL_RTX;
+}
+
 /* Return the real part (which has mode MODE) of a complex value X.
    This always comes at the low address in memory.  */
 
@@ -1302,6 +1333,13 @@ gen_realpart (mode, x)
      enum machine_mode mode;
      rtx x;
 {
+  rtx part;
+
+  /* Handle complex constants.  */
+  part = gen_complex_constant_part (mode, x, 0);
+  if (part != NULL_RTX)
+    return part;
+
   if (WORDS_BIG_ENDIAN
       && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
       && REG_P (x)
@@ -1322,6 +1360,13 @@ gen_imagpart (mode, x)
      enum machine_mode mode;
      rtx x;
 {
+  rtx part;
+
+  /* Handle complex constants.  */
+  part = gen_complex_constant_part (mode, x, 1);
+  if (part != NULL_RTX)
+    return part;
+
   if (WORDS_BIG_ENDIAN)
     return gen_lowpart (mode, x);
   else if (! WORDS_BIG_ENDIAN