This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Darwin FP constant peephole (again)


All right, I've redone this as a function.  I agree this is cleaner
than putting a separate LEGITIMIZE_RELOAD_ADDRESS in darwin.h, but
there are some unaesthetic bits this way too:
- REG_MODE_OK_FOR_BASE_P needs to be defined in rs6000.h, as shown.
This is similar to the way it's done everywhere else, but ugly.
- The logically correct prototype uses enum reload_type (reload.h),
which isn't normally defined at the time rs6000-protos.h is included.
I tried a few things with rearrangements and nested includes, but
eventually gave up and fell back on declaring it "int", with casts.
Even uglier.
Bootstrapped and tested on darwin.

2001-12-18  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.


Index: rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.27
diff -u -d -b -w -r1.27 rs6000-protos.h
--- rs6000-protos.h     2001/12/09 16:31:51     1.27
+++ rs6000-protos.h     2001/12/18 22:04:09
@@ -114,6 +114,8 @@
  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: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.264
diff -u -d -b -w -r1.264 rs6000.c
--- rs6000.c    2001/12/17 19:05:43     1.264
+++ rs6000.c    2001/12/18 22:04:09
@@ -47,6 +47,7 @@
  #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 @@
    else
      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.
Index: rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.161
diff -u -d -b -w -r1.161 rs6000.h
--- rs6000.h    2001/12/17 19:11:13     1.161
+++ rs6000.h    2001/12/18 22:04:09
@@ -2059,59 +2059,16 @@
     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);                                    
    \
+  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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]