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]

Re: Darwin FP constant peephole



On Tuesday, December 4, 2001, at 04:13 PM, Richard Henderson wrote:
> On Tue, Dec 04, 2001 at 11:30:48AM -0800, Dale Johannesen wrote:
>> + (define_peephole2  <details snipped>
> You should be able to do this with LEGITIMIZE_RELOAD_ADDRESS,
> if I am not mistaking where this construct comes from.

Thanks, that was helpful.  This replaces the original peephole2 patch
(catches some more cases, too).  The problem is Darwin specific; I'd
prefer to put this in rs6000.h, but there is a reason not to, as shown
in the comment.  Bootstrapped and tested on Darwin.

2001-12-14  Dale Johannesen  <dalej@apple.com>

         * config/rs6000/darwin.h: LEGITIMIZE_RELOAD_ADDRESS:  Add
           Darwin-specific version containing code for load of FP
           constant.

Index: darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/darwin.h,v
retrieving revision 1.14
diff -u -d -b -w -c -3 -p -r1.14 darwin.h
cvs server: conflicting specifications of output style
*** darwin.h    2001/12/07 22:17:02     1.14
--- darwin.h    2001/12/14 18:48:02
*************** Boston, MA 02111-1307, USA.  */
*** 224,226 ****
--- 224,314 ----
      space/speed.  */
   #undef MAX_LONG_TYPE_SIZE
   #define MAX_LONG_TYPE_SIZE 32
+
+ /* This contains additional code to load a floating point constant
+    in 2 instructions instead of 3.  machopic_function_base_name()
+    is defined only #if TARGET_MACHO, so this can't go in rs6000.h.  */
+ #undef LEGITIMIZE_RELOAD_ADDRESS
+ #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 (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)      
    \
+     {                                                                   
    \
+       push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,           
    \
+               BASE_REG_CLASS, Pmode, 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;                                                         
          \
+     }                                                                   
    \
+   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, 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;                                                         
          \
+     }                                                                   
    \
+ } while (0)


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