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]

followup on ia64 HARD_REGNO_NREGS change


While looking at that test case, I noticed that we had similar
problems with TCmode.  Also, it looks like our formulation of
MODES_TIEABLE_P is completely confused.

The following has survived a bootstrap and test run, but I'm 
interested in your thoughts on my ia64_modes_tieable_p formation.



r~



Index: ia64-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64-protos.h,v
retrieving revision 1.67
diff -c -p -d -r1.67 ia64-protos.h
*** ia64-protos.h	6 Oct 2004 16:07:03 -0000	1.67
--- ia64-protos.h	12 Nov 2004 23:30:49 -0000
*************** extern enum direction ia64_hpux_function
*** 107,109 ****
--- 107,113 ----
  #endif /* ARGS_SIZE_RTX */
  
  extern void ia64_hpux_handle_builtin_pragma (struct cpp_reader *);
+ 
+ extern unsigned int ia64_hard_regno_nregs (unsigned int, enum machine_mode);
+ extern bool ia64_hard_regno_mode_ok (unsigned int, enum machine_mode);
+ extern bool ia64_modes_tieable_p (enum machine_mode, enum machine_mode);
Index: ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.332
diff -c -p -d -r1.332 ia64.c
*** ia64.c	9 Nov 2004 10:13:04 -0000	1.332
--- ia64.c	12 Nov 2004 23:30:51 -0000
*************** ia64_initialize_trampoline (rtx addr, rt
*** 2929,2934 ****
--- 2929,3043 ----
    emit_move_insn (gen_rtx_MEM (Pmode, addr_reg), static_chain);
  }
  
+ /* Implement HARD_REGNO_NREGS.  */
+ 
+ unsigned int
+ ia64_hard_regno_nregs (unsigned int regno, enum machine_mode mode)
+ {
+   if (PR_REGNO_P (regno))
+     {
+       if (mode == CCImode)
+ 	return 1;
+       if (mode == BImode)
+ 	return 2;
+       return GET_MODE_BITSIZE (mode);
+     }
+   else if (FR_REGNO_P (regno))
+     {
+       if (mode == XFmode)
+ 	return 1;
+       if (mode == XCmode)
+ 	return 2;
+     }
+ 
+   return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ }
+ 
+ /* Implement HARD_REGNO_MODE_OK.  */
+ 
+ bool
+ ia64_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
+ {
+   if (GR_REGNO_P (regno))
+     {
+       if (mode == CCImode)
+ 	return false;
+       if (mode == XFmode || mode == XCmode)
+ 	return false;
+       return true;
+     }
+   else if (FR_REGNO_P (regno))
+     {
+       if (GET_MODE_CLASS (mode) == MODE_CC)
+ 	return false;
+       if (mode == BImode || mode == TImode)
+ 	return false;
+       if (mode == TFmode || mode == TCmode)
+ 	return false;
+       return true;
+     }
+   else if (regno == PR_REG (0) && mode == DImode)
+     return true;
+   else if (PR_REGNO_P (regno))
+     return mode == BImode || GET_MODE_CLASS (mode) == MODE_CC;
+   else if (AR_REGNO_P (regno) || BR_REGNO_P (regno))
+     return mode == DImode;
+   else
+     return false;
+ }
+ 
+ /* Implement MODES_TIEABLE_P.  */
+ 
+ bool
+ ia64_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
+ {
+   enum mode_class class1, class2;
+ 
+   switch (mode1)
+     {
+     case BImode:
+       /* BImode can be held in PR and GR regs, but these register
+ 	 classes have no other modes in common.  */
+       return false;
+ 
+     case TImode:
+     case TFmode:
+     case TCmode:
+       /* These modes are only allowed in GR registers.  */
+       return ia64_hard_regno_mode_ok (GR_REG (0), mode2);
+ 
+     case XFmode:
+     case XCmode:
+       /* These modes are only allowed in FR registers.  */
+       return ia64_hard_regno_mode_ok (FR_REG (0), mode2);
+ 
+     case DImode:
+       /* AR and BR registers can hold DImode, but nothing else.  */
+       return false;
+ 
+     default:
+       break;
+     }
+ 
+   class1 = GET_MODE_CLASS (mode1);
+   class2 = GET_MODE_CLASS (mode2);
+ 
+   /* ??? We shouldn't ever see any of these, I think.  */
+   if (class1 == MODE_RANDOM || class2 == MODE_RANDOM)
+     return false;
+ 
+   /* CC modes are only handled by PR regs.  */
+   if (class1 == MODE_CC)
+     return class2 == MODE_CC;
+   if (class2 == MODE_CC)
+     return class1 == MODE_CC;
+ 
+   /* Everything else is handled by both FR and GR regs, and thus to be
+      tieable, the result mode must be acceptable to both.  */
+   return (ia64_hard_regno_mode_ok (GR_REG (0), mode2)
+ 	  && ia64_hard_regno_mode_ok (FR_REG (0), mode2));
+ }
+ 
  /* Do any needed setup for a variadic function.  CUM has not been updated
     for the last named argument which has type TYPE and mode MODE.
  
Index: ia64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.h,v
retrieving revision 1.188
diff -c -p -d -r1.188 ia64.h
*** ia64.h	11 Nov 2004 21:20:22 -0000	1.188
--- ia64.h	12 Nov 2004 23:30:52 -0000
*************** while (0)
*** 805,855 ****
  /* A C expression for the number of consecutive hard registers, starting at
     register number REGNO, required to hold a value of mode MODE.  */
  
! /* ??? We say that BImode PR values require two registers.  This allows us to
!    easily store the normal and inverted values.  We use CCImode to indicate
!    a single predicate register.  */
! 
! #define HARD_REGNO_NREGS(REGNO, MODE)					\
!   ((REGNO) == PR_REG (0) && (MODE) == DImode ? 64			\
!    : PR_REGNO_P (REGNO) && (MODE) == BImode ? 2				\
!    : PR_REGNO_P (REGNO) && (MODE) == CCImode ? 1			\
!    : FR_REGNO_P (REGNO) && (MODE) == XFmode ? 1				\
!    : FR_REGNO_P (REGNO) && (MODE) == XCmode ? 2				\
!    : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
  
  /* A C expression that is nonzero if it is permissible to store a value of mode
     MODE in hard register number REGNO (or in several registers starting with
     that one).  */
  
! #define HARD_REGNO_MODE_OK(REGNO, MODE)				\
!   (FR_REGNO_P (REGNO) ?						\
!      GET_MODE_CLASS (MODE) != MODE_CC &&			\
!      (MODE) != TImode &&					\
!      (MODE) != BImode &&					\
!      (MODE) != TFmode 						\
!    : PR_REGNO_P (REGNO) ?					\
!      (MODE) == BImode || GET_MODE_CLASS (MODE) == MODE_CC	\
!    : GR_REGNO_P (REGNO) ?					\
!      (MODE) != CCImode && (MODE) != XFmode && (MODE) != XCmode	\
!    : AR_REGNO_P (REGNO) ? (MODE) == DImode			\
!    : BR_REGNO_P (REGNO) ? (MODE) == DImode			\
!    : 0)
  
! /* A C expression that is nonzero if it is desirable to choose register
!    allocation so as to avoid move instructions between a value of mode MODE1
!    and a value of mode MODE2.
  
!    If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
!    ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
!    zero.  */
! /* Don't tie integer and FP modes, as that causes us to get integer registers
!    allocated for FP instructions.  XFmode only supported in FP registers so
!    we can't tie it with any other modes.  */
! #define MODES_TIEABLE_P(MODE1, MODE2)			\
!   (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)	\
!    && ((((MODE1) == XFmode) || ((MODE1) == XCmode))	\
!        == (((MODE2) == XFmode) || ((MODE2) == XCmode)))	\
!    && (((MODE1) == BImode) == ((MODE2) == BImode)))
  
  /* Specify the modes required to caller save a given hard regno.
     We need to ensure floating pt regs are not saved as DImode.  */
--- 805,823 ----
  /* A C expression for the number of consecutive hard registers, starting at
     register number REGNO, required to hold a value of mode MODE.  */
  
! #define HARD_REGNO_NREGS(REGNO, MODE) ia64_hard_regno_nregs (REGNO, MODE)
  
  /* A C expression that is nonzero if it is permissible to store a value of mode
     MODE in hard register number REGNO (or in several registers starting with
     that one).  */
  
! #define HARD_REGNO_MODE_OK(REGNO, MODE) ia64_hard_regno_mode_ok (REGNO, MODE)
  
! /* A C expression that is nonzero if a value of mode MODE1 is accessible in
!    mode MODE2 without copying.  This asymmetric test is true when MODE1 could
!    be put in a hard register but MODE2 could not.  */
  
! #define MODES_TIEABLE_P(MODE1, MODE2) ia64_modes_tieable_p (MODE1, MODE2)
  
  /* Specify the modes required to caller save a given hard regno.
     We need to ensure floating pt regs are not saved as DImode.  */


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