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: unmacroize HARD_REGNO_* on PPC


Tested on powerpc-linux-gnualtivec.  Bootstrap and regtested for C and
C++.

Ok for mainline?

	* config/rs6000/rs6000-protos.h: Protoize rs6000_hard_regno_nregs,
	rs6000_hard_regno_mode_ok.

	* config/rs6000/rs6000.c (rs6000_hard_regno_nregs): New.
	(rs6000_hard_regno_mode_ok): New.

	* config/rs6000/rs6000.h (HARD_REGNO_NREGS): Call
	rs6000_hard_regno_nregs.
	(HARD_REGNO_MODE_OK): Call rs6000_hard_regno_mode_ok.

Index: config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.78
diff -c -p -r1.78 rs6000-protos.h
*** config/rs6000/rs6000-protos.h	28 Apr 2004 23:03:26 -0000	1.78
--- config/rs6000/rs6000-protos.h	4 May 2004 01:00:05 -0000
*************** extern int rs6000_memory_move_cost (enum
*** 201,206 ****
--- 201,208 ----
  extern bool rs6000_tls_referenced_p (rtx);
  extern int rs6000_tls_symbol_ref (rtx, enum machine_mode);
  extern void rs6000_output_dwarf_dtprel (FILE*, int, rtx);
+ extern int rs6000_hard_regno_nregs (int, enum machine_mode);
+ extern int rs6000_hard_regno_mode_ok (int, enum machine_mode);
  
  /* Declare functions in rs6000-c.c */
  
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.632
diff -c -p -r1.632 rs6000.c
*** config/rs6000/rs6000.c	29 Apr 2004 18:37:27 -0000	1.632
--- config/rs6000/rs6000.c	4 May 2004 01:00:15 -0000
*************** rs6000_mode_dependent_address (rtx addr)
*** 3343,3348 ****
--- 3343,3411 ----
  
    return false;
  }
+ 
+ /* Return number of consecutive hard regs needed starting at reg REGNO
+    to hold something of mode MODE.
+    This is ordinarily the length in words of a value of mode MODE
+    but can be less for certain modes in special long registers.
+ 
+    For the SPE, GPRs are 64 bits but only 32 bits are visible in
+    scalar instructions.  The upper 32 bits are only available to the
+    SIMD instructions.
+ 
+    POWER and PowerPC GPRs hold 32 bits worth;
+    PowerPC64 GPRs and FPRs point register holds 64 bits worth.  */
+ 
+ int
+ rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
+ {
+   if (FP_REGNO_P (regno))
+     return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
+ 
+   if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
+     return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
+ 
+   if (ALTIVEC_REGNO_P (regno))
+     return
+       (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
+ 
+   return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ }
+ 
+ /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
+    For POWER and PowerPC, the GPRs can hold any mode, but values bigger
+    than one register cannot go past R31.  The float
+    registers only can hold floating modes and DImode, and CR register only
+    can hold CC modes.  We cannot put TImode anywhere except general
+    register and it must be able to fit within the register set.  */
+ int
+ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
+ {
+   if (INT_REGNO_P (regno))
+     return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
+ 
+   if (FP_REGNO_P (regno))
+      return
+        (GET_MODE_CLASS (mode) == MODE_FLOAT
+ 	&& FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
+        || (GET_MODE_CLASS (mode) == MODE_INT
+ 	   && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
+ 
+    if (ALTIVEC_REGNO_P (regno))
+      return ALTIVEC_VECTOR_MODE (mode);
+ 
+    if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
+      return 1;
+ 
+    if (CR_REGNO_P (regno))
+      return GET_MODE_CLASS (mode) == MODE_CC;
+ 
+    if (XER_REGNO_P (regno))
+      return mode == PSImode;
+ 
+    return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
+ }
+ 
  
  /* Try to output insns to set TARGET equal to the constant C if it can
     be done in less than N insns.  Do all computations in MODE.
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.320
diff -c -p -r1.320 rs6000.h
*** config/rs6000/rs6000.h	24 Apr 2004 06:37:19 -0000	1.320
--- config/rs6000/rs6000.h	4 May 2004 01:00:16 -0000
*************** extern const char *rs6000_warn_altivec_l
*** 997,1021 ****
  #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
  
  /* Return number of consecutive hard regs needed starting at reg REGNO
!    to hold something of mode MODE.
!    This is ordinarily the length in words of a value of mode MODE
!    but can be less for certain modes in special long registers.
! 
!    For the SPE, GPRs are 64 bits but only 32 bits are visible in
!    scalar instructions.  The upper 32 bits are only available to the
!    SIMD instructions.
! 
!    POWER and PowerPC GPRs hold 32 bits worth;
!    PowerPC64 GPRs and FPRs point register holds 64 bits worth.  */
! 
! #define HARD_REGNO_NREGS(REGNO, MODE)					\
!   (FP_REGNO_P (REGNO)							\
!    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
!    : (SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE))   \
!    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD) \
!    : ALTIVEC_REGNO_P (REGNO)						\
!    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
!    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
  #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)	\
    ((TARGET_32BIT && TARGET_POWERPC64			\
--- 997,1005 ----
  #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
  
  /* Return number of consecutive hard regs needed starting at reg REGNO
!    to hold something of mode MODE.  */
! 
! #define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs ((REGNO), (MODE))
  
  #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)	\
    ((TARGET_32BIT && TARGET_POWERPC64			\
*************** extern const char *rs6000_warn_altivec_l
*** 1042,1067 ****
          ((TARGET_SPE && SPE_VECTOR_MODE (MODE))		\
  	 || (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
  
! /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
!    For POWER and PowerPC, the GPRs can hold any mode, but values bigger
!    than one register cannot go past R31.  The float
!    registers only can hold floating modes and DImode, and CR register only
!    can hold CC modes.  We cannot put TImode anywhere except general
!    register and it must be able to fit within the register set.  */
! 
! #define HARD_REGNO_MODE_OK(REGNO, MODE)					\
!   (INT_REGNO_P (REGNO) ?						\
!      INT_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1)	        \
!    : FP_REGNO_P (REGNO) ?						\
!      ((GET_MODE_CLASS (MODE) == MODE_FLOAT				\
!        && FP_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1))	\
!       || (GET_MODE_CLASS (MODE) == MODE_INT				\
! 	  && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))		\
!    : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE)		\
!    : SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
!    : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC		\
!    : XER_REGNO_P (REGNO) ? (MODE) == PSImode				\
!    : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
  
  /* Value is 1 if it is a good idea to tie two pseudo registers
     when one has mode MODE1 and one has mode MODE2.
--- 1026,1034 ----
          ((TARGET_SPE && SPE_VECTOR_MODE (MODE))		\
  	 || (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
  
! /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.  */
! 
! #define HARD_REGNO_MODE_OK(REGNO, MODE) rs6000_hard_regno_mode_ok ((REGNO), (MODE))
  
  /* Value is 1 if it is a good idea to tie two pseudo registers
     when one has mode MODE1 and one has mode MODE2.


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