This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
patch: unmacroize HARD_REGNO_* on PPC
- From: Aldy Hernandez <aldyh at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, dje at watson dot ibm dot com
- Date: Mon, 3 May 2004 21:04:41 -0400
- Subject: 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.