]> gcc.gnu.org Git - gcc.git/commitdiff
rs6000.h: LEGITIMIZE_RELOAD_ADDRESS: redefine in terms of rs6000_legitimize_reload_ad...
authorDale Johannesen <dalej@apple.com>
Wed, 19 Dec 2001 18:06:38 +0000 (18:06 +0000)
committerDale Johannesen <dalej@gcc.gnu.org>
Wed, 19 Dec 2001 18:06:38 +0000 (18:06 +0000)
         * config/rs6000/rs6000.h: LEGITIMIZE_RELOAD_ADDRESS:
         redefine in terms of rs6000_legitimize_reload_address().
         * config/rs6000/rs6000-protos.h: Add this function.
         * config/rs6000/rs6000.c: Add this function.  Includes
         handling for Darwin FP constants.

From-SVN: r48181

gcc/ChangeLog
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h

index ea773b77642f55f937973775d7de3e6c02b01f82..e5aa14daed1f2a85d362060977e97b15829ad00f 100644 (file)
@@ -1,3 +1,11 @@
+2001-12-19  Dale Johannesen  <dalej@apple.com>
+
+        * config/rs6000/rs6000.h: LEGITIMIZE_RELOAD_ADDRESS:
+        redefine in terms of rs6000_legitimize_reload_address().
+        * config/rs6000/rs6000-protos.h: Add this function.
+        * config/rs6000/rs6000.c: Add this function.  Includes
+        handling for Darwin FP constants.
+
 Wed Dec 19 11:01:21 2001  Jeffrey A Law  (law@redhat.com)
 
        * config/pa/t-hpux-shlib: New file.
index 5a86ab07f6ea38be47b4d0382445e607cbac70e7..c40689e9069c65e6b444357c4eda8bd808658304 100644 (file)
@@ -114,6 +114,8 @@ extern struct rtx_def *create_TOC_reference PARAMS ((rtx));
 extern void rs6000_emit_eh_toc_restore PARAMS ((rtx));
 extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode));
 extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
+extern rtx rs6000_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
+                           int, int, int, int *));
 extern int rs6000_legitimate_address PARAMS ((enum machine_mode, rtx, int));
 extern void rs6000_select_rtx_section PARAMS ((enum machine_mode, rtx));
 
index 3dca0fa0b3bf3ce34a4357ec4c917c1f789a39b3..4a661fcbefaa918aecd9f32d77c588c728893f5c 100644 (file)
@@ -47,6 +47,7 @@ Boston, MA 02111-1307, USA.  */
 #include "target.h"
 #include "target-def.h"
 #include "langhooks.h"
+#include "reload.h"
 
 #ifndef TARGET_NO_PROTOTYPE
 #define TARGET_NO_PROTOTYPE 0
@@ -1757,6 +1758,133 @@ rs6000_legitimize_address (x, oldx, mode)
     return NULL_RTX;
 }
 
+/* The convention appears to be to define this wherever it is used.
+   With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
+   is now used here.  */
+#ifndef REG_MODE_OK_FOR_BASE_P
+#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
+#endif
+
+/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS.  Returns a value to
+   replace the input X, or the original X if no replacement is called for.
+   The output parameter *WIN is 1 if the calling macro should goto WIN,
+   0 if it should not.
+
+   For RS/6000, we wish to handle large displacements off a base
+   register by splitting the addend across an addiu/addis and the mem insn.
+   This cuts number of extra insns needed from 3 to 1.
+
+   On Darwin, we use this to generate code for floating point constants.
+   A movsf_low is generated so we wind up with 2 instructions rather than 3.
+   The Darwin code is inside #if TARGET_MACHO because only then is
+   machopic_function_base_name() defined.  */
+rtx
+rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
+    rtx x;
+    enum machine_mode mode;
+    int opnum;
+    int type;
+    int ind_levels ATTRIBUTE_UNUSED;
+    int *win;
+{
+  /* We must recognize output that we have already generated ourselves.  */ 
+  if (GET_CODE (x) == PLUS
+      && GET_CODE (XEXP (x, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+    {
+      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
+                   BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
+                   opnum, (enum reload_type)type);
+      *win = 1;
+      return x;
+    }
+#if TARGET_MACHO
+  if (DEFAULT_ABI == ABI_DARWIN && flag_pic
+      && GET_CODE (x) == LO_SUM
+      && GET_CODE (XEXP (x, 0)) == PLUS
+      && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
+      && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
+      && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
+      && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
+      && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
+      && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
+      && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
+    {
+      /* Result of previous invocation of this function on Darwin
+        floating point constant. */
+      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
+               BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
+               opnum, (enum reload_type)type);
+      *win = 1;
+      return x;
+    }
+#endif
+  if (GET_CODE (x) == PLUS
+      && GET_CODE (XEXP (x, 0)) == REG
+      && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
+      && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
+      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+    {
+      HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
+      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
+      HOST_WIDE_INT high
+        = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
+
+      /* Check for 32-bit overflow.  */
+      if (high + low != val)
+        {
+         *win = 0;
+         return x;
+       }
+
+      /* Reload the high part into a base reg; leave the low part
+         in the mem directly.  */
+
+      x = gen_rtx_PLUS (GET_MODE (x),
+                        gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
+                                      GEN_INT (high)),
+                        GEN_INT (low));
+
+      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
+                   BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
+                   opnum, (enum reload_type)type);
+      *win = 1;
+      return x;
+    }
+#if TARGET_MACHO
+  if (GET_CODE (x) == SYMBOL_REF
+      && DEFAULT_ABI == ABI_DARWIN
+      && flag_pic)
+    {
+      /* Darwin load of floating point constant.  */
+      rtx offset = gen_rtx (CONST, Pmode,
+                   gen_rtx (MINUS, Pmode, x,
+                   gen_rtx (SYMBOL_REF, Pmode,
+                       machopic_function_base_name ())));
+      x = gen_rtx (LO_SUM, GET_MODE (x),
+           gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
+               gen_rtx (HIGH, Pmode, offset)), offset);
+      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
+               BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
+               opnum, (enum reload_type)type);
+      *win = 1;
+      return x;
+    }
+#endif
+  if (TARGET_TOC
+          && CONSTANT_POOL_EXPR_P (x)
+          && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
+    {
+      (x) = create_TOC_reference (x);
+      *win = 1;
+      return x;
+    }
+  *win = 0;
+  return x;
+}    
+
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
    that is a valid memory address for an instruction.
    The MODE argument is the machine mode for the MEM expression
index 47cf4d322909e88d16ae3381b3616e1dbea08d8a..40769a0178b026dee0a42af46e527d917e43df42 100644 (file)
@@ -2058,59 +2058,16 @@ typedef struct rs6000_args
    operand.  If we find one, push the reload and jump to WIN.  This
    macro is used in only one place: `find_reloads_address' in reload.c.
 
-   For RS/6000, we wish to handle large displacements off a base
-   register by splitting the addend across an addiu/addis and the mem insn.
-   This cuts number of extra insns needed from 3 to 1.  */
+   Implemented on rs6000 by rs6000_legitimize_reload_address.  
+   Note that (X) is evaluated twice; this is safe in current usage.  */
    
 #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)         \
 do {                                                                        \
-  /* We must recognize output that we have already generated ourselves.  */  \
-  if (GET_CODE (X) == PLUS                                                  \
-      && GET_CODE (XEXP (X, 0)) == PLUS                                             \
-      && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG                            \
-      && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT                      \
-      && GET_CODE (XEXP (X, 1)) == CONST_INT)                               \
-    {                                                                       \
-      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,               \
-                   BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,            \
-                   OPNUM, TYPE);                                            \
-      goto WIN;                                                             \
-    }                                                                       \
-  if (GET_CODE (X) == PLUS                                                  \
-      && GET_CODE (XEXP (X, 0)) == REG                                      \
-      && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER                        \
-      && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE)                         \
-      && GET_CODE (XEXP (X, 1)) == CONST_INT)                               \
-    {                                                                       \
-      HOST_WIDE_INT val = INTVAL (XEXP (X, 1));                                     \
-      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;               \
-      HOST_WIDE_INT high                                                    \
-        = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;           \
-                                                                            \
-      /* Check for 32-bit overflow.  */                                             \
-      if (high + low != val)                                                \
-        break;                                                              \
-                                                                            \
-      /* Reload the high part into a base reg; leave the low part           \
-         in the mem directly.  */                                           \
-                                                                            \
-      X = gen_rtx_PLUS (GET_MODE (X),                                       \
-                        gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0),            \
-                                      GEN_INT (high)),                      \
-                        GEN_INT (low));                                             \
-                                                                            \
-      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,               \
-                   BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,            \
-                   OPNUM, TYPE);                                            \
-      goto WIN;                                                                     \
-    }                                                                       \
-  else if (TARGET_TOC                                                       \
-          && CONSTANT_POOL_EXPR_P (X)                                       \
-          && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X), MODE)) \
-    {                                                                       \
-      (X) = create_TOC_reference (X);                                       \
-      goto WIN;                                                                     \
-    }                                                                       \
+  int win;                                                                  \
+  (X) = rs6000_legitimize_reload_address ((X), (MODE), (OPNUM),                     \
+                       (int)(TYPE), (IND_LEVELS), &win);                    \
+  if ( win )                                                                \
+    goto WIN;                                                               \
 } while (0)
 
 /* Go to LABEL if ADDR (a legitimate address expression)
This page took 0.112644 seconds and 5 git commands to generate.