Backport fix for PR6362 to 3.2.x?

Kaveh R. Ghazi ghazi@caip.rutgers.edu
Mon Feb 10 05:36:00 GMT 2003


 > From: Gabriel Dos Reis <gdr@integrable-solutions.net>
 > 
 > "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> writes:
 > 
 > | I'd like comments on whether the fix for PR6362 is both worthwhile and
 > | safe to backport to 3.2.x.  The patch here:
 > | http://gcc.gnu.org/ml/gcc-patches/2002-09/msg01492.html
 > | has been in the trunk and 3.3 for months without problems and the bug
 > | itself is a regression from 2.8.1.
 > | 
 > | It doesn't apply cleanly so before I go fixing and testing it, I
 > | wanted some sense of whether I should.
 > 
 > Yes, I think that will be helpful.

Ok, I got most of it.  There's one hunk which I can't merge, it may be
a separate fix for something else anyway.  I'll test with the rest of
it.

Richard since it's your patch would you please comment on this piece?
Is it necessary and still relevant for 3.2.x?

		Thanks,
		--Kaveh

PS: first bit is unmergable, second is what I'm testing:

	* mips.c (override_options): Allow TFmode values in float
	registers if ISA_HAS_8CC.

*************** override_options ()
*** 5362,5368 ****
  			/* Allow integer modes that fit into a single
  			   register.  We need to put integers into FPRs
  			   when using instructions like cvt and trunc.  */
! 			|| (class == MODE_INT && size <= UNITS_PER_FPREG)));
  
  	  else if (MD_REG_P (regno))
  	    temp = (class == MODE_INT
--- 5438,5446 ----
  			/* Allow integer modes that fit into a single
  			   register.  We need to put integers into FPRs
  			   when using instructions like cvt and trunc.  */
! 			|| (class == MODE_INT && size <= UNITS_PER_FPREG)
! 			/* Allow TFmode for CCmode reloads.  */
! 			|| (ISA_HAS_8CC && mode == TFmode)));
  
  	  else if (MD_REG_P (regno))
  	    temp = (class == MODE_INT






2002-10-01  Richard Sandiford  <rsandifo@redhat.com>

	* config/mips/mips-protos.h (mips_emit_fcc_reload): Declare.
	* config/mips/mips.h (PREDICATE_CODES): Add fcc_register_operand.
	* config/mips/mips.c (fcc_register_operand): New function.
	(mips_emit_fcc_reload): New function, extracted from reload_incc.
	* cnfig/mips/mips.md (reload_incc): Change destination prediate
	to fcc_register_operand.  Remove misleading source constraint.
	Use mips_emit_fcc_reload.
	(reload_outcc): Duplicate reload_incc.

diff -rcp orig/egcc-3.2-CVS20030209/gcc/config/mips/mips-protos.h egcc-3.2-CVS20030209/gcc/config/mips/mips-protos.h
*** orig/egcc-3.2-CVS20030209/gcc/config/mips/mips-protos.h	Sun Mar 24 03:13:16 2002
--- egcc-3.2-CVS20030209/gcc/config/mips/mips-protos.h	Mon Feb 10 00:20:21 2003
*************** extern void		init_cumulative_args PARAMS
*** 80,85 ****
--- 80,86 ----
  						      tree, rtx));
  extern void		gen_conditional_move PARAMS ((rtx *));
  extern void		mips_gen_conditional_trap PARAMS ((rtx *));
+ extern void		mips_emit_fcc_reload PARAMS ((rtx, rtx, rtx));
  extern void		machine_dependent_reorg PARAMS ((rtx));
  extern int		mips_address_cost PARAMS ((rtx));
  extern void		mips_count_memory_refs PARAMS ((rtx, int));
diff -rcp orig/egcc-3.2-CVS20030209/gcc/config/mips/mips.h egcc-3.2-CVS20030209/gcc/config/mips/mips.h
*** orig/egcc-3.2-CVS20030209/gcc/config/mips/mips.h	Fri Apr 26 17:32:14 2002
--- egcc-3.2-CVS20030209/gcc/config/mips/mips.h	Mon Feb 10 00:20:21 2003
*************** while (0)
*** 4001,4006 ****
--- 4001,4007 ----
    {"se_nonimmediate_operand",   { SUBREG, REG, MEM, SIGN_EXTEND }},	\
    {"consttable_operand",	{ LABEL_REF, SYMBOL_REF, CONST_INT,	\
  				  CONST_DOUBLE, CONST }},		\
+   {"fcc_register_operand",	{ REG, SUBREG }},			\
    {"extend_operator",           { SIGN_EXTEND, ZERO_EXTEND }},          \
    {"highpart_shift_operator",   { ASHIFTRT, LSHIFTRT, ROTATERT, ROTATE }},
  
diff -rcp orig/egcc-3.2-CVS20030209/gcc/config/mips/mips.c egcc-3.2-CVS20030209/gcc/config/mips/mips.c
*** orig/egcc-3.2-CVS20030209/gcc/config/mips/mips.c	Fri Jul 26 19:23:02 2002
--- egcc-3.2-CVS20030209/gcc/config/mips/mips.c	Mon Feb 10 00:20:21 2003
*************** mips_gen_conditional_trap (operands)
*** 3267,3272 ****
--- 3267,3317 ----
  			      gen_rtx (cmp_code, GET_MODE (operands[0]), op0, op1),
  			      operands[1]));
  }
+ 
+ /* Return true if operand OP is a condition code register.
+    Only for use during or after reload.  */
+ 
+ int
+ fcc_register_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   return ((mode == VOIDmode || mode == GET_MODE (op))
+ 	  && (reload_in_progress || reload_completed)
+ 	  && (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+ 	  && ST_REG_P (true_regnum (op)));
+ }
+ 
+ /* Emit code to move general operand SRC into condition-code
+    register DEST.  SCRATCH is a scratch TFmode float register.
+    The sequence is:
+ 
+ 	FP1 = SRC
+ 	FP2 = 0.0f
+ 	DEST = FP2 < FP1
+ 
+    where FP1 and FP2 are single-precision float registers
+    taken from SCRATCH.  */
+ 
+ void
+ mips_emit_fcc_reload (dest, src, scratch)
+      rtx dest, src, scratch;
+ {
+   rtx fp1, fp2;
+ 
+   /* Change the source to SFmode.  */
+   if (GET_CODE (src) == MEM)
+     src = adjust_address (src, SFmode, 0);
+   else if (GET_CODE (src) == REG || GET_CODE (src) == SUBREG)
+     src = gen_rtx_REG (SFmode, true_regnum (src));
+ 
+   fp1 = gen_rtx_REG (SFmode, REGNO (scratch));
+   fp2 = gen_rtx_REG (SFmode, REGNO (scratch) + FP_INC);
+ 
+   emit_move_insn (copy_rtx (fp1), src);
+   emit_move_insn (copy_rtx (fp2), CONST0_RTX (SFmode));
+   emit_insn (gen_slt_sf (dest, fp2, fp1));
+ }
  
  /* Write a loop to move a constant number of bytes.
     Generate load/stores as follows:
diff -rcp orig/egcc-3.2-CVS20030209/gcc/config/mips/mips.md egcc-3.2-CVS20030209/gcc/config/mips/mips.md
*** orig/egcc-3.2-CVS20030209/gcc/config/mips/mips.md	Mon Nov 11 07:21:52 2002
--- egcc-3.2-CVS20030209/gcc/config/mips/mips.md	Mon Feb 10 00:20:22 2003
*************** move\\t%0,%z4\\n\\
*** 5786,5862 ****
     (set_attr "mode"	"SI")
     (set_attr "length"	"8,4,4,8,4,8,4,4,4,4,8,4,8")])
  
! ;; Reload condition code registers.  These need scratch registers.
! 
  (define_expand "reload_incc"
!   [(set (match_operand:CC 0 "register_operand" "=z")
! 	(match_operand:CC 1 "general_operand" "z"))
     (clobber (match_operand:TF 2 "register_operand" "=&f"))]
    "ISA_HAS_8CC && TARGET_HARD_FLOAT"
    "
  {
!   rtx source;
!   rtx fp1, fp2;
!   int regno;
! 
!   /* This is called when are copying some value into a condition code
!      register.  Operand 0 is the condition code register.  Operand 1
!      is the source.  Operand 2 is a scratch register; we use TFmode
!      because we actually need two floating point registers.  */
!   if (! ST_REG_P (true_regnum (operands[0]))
!       || ! FP_REG_P (true_regnum (operands[2])))
!     abort ();
! 
!   /* We need to get the source in SFmode so that the insn is
!      recognized.  */
!   if (GET_CODE (operands[1]) == MEM)
!     source = adjust_address (operands[1], SFmode, 0);
!   else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
!     source = gen_rtx_REG (SFmode, true_regnum (operands[1]));
!   else
!     source = operands[1];
! 
!   /* FP1 and FP2 are the two halves of the TFmode scratch operand.  They
!      will be single registers in 64-bit mode and register pairs in 32-bit
!      mode.  SOURCE is loaded into FP1 and zero is loaded into FP2.  */
!   regno = REGNO (operands[2]);
!   fp1 = gen_rtx_REG (SFmode, regno);
!   fp2 = gen_rtx_REG (SFmode, regno + HARD_REGNO_NREGS (regno, DFmode));
! 
!   emit_insn (gen_move_insn (fp1, source));
!   emit_insn (gen_move_insn (fp2, gen_rtx_REG (SFmode, 0)));
!   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
! 			  gen_rtx_LT (CCmode, fp2, fp1)));
! 
    DONE;
  }")
  
  (define_expand "reload_outcc"
!   [(set (match_operand:CC 0 "general_operand" "=z")
! 	(match_operand:CC 1 "register_operand" "z"))
!    (clobber (match_operand:CC 2 "register_operand" "=&d"))]
    "ISA_HAS_8CC && TARGET_HARD_FLOAT"
    "
  {
!   /* This is called when we are copying a condition code register out
!      to save it somewhere.  Operand 0 should be the location we are
!      going to save it to.  Operand 1 should be the condition code
!      register.  Operand 2 should be a scratch general purpose register
!      created for us by reload.  The mips_secondary_reload_class
!      function should have told reload that we don't need a scratch
!      register if the destination is a general purpose register anyhow.  */
!   if (ST_REG_P (true_regnum (operands[0]))
!       || GP_REG_P (true_regnum (operands[0]))
!       || ! ST_REG_P (true_regnum (operands[1]))
!       || ! GP_REG_P (true_regnum (operands[2])))
!     abort ();
! 
!   /* All we have to do is copy the value from the condition code to
!      the data register, which movcc can handle, and then store the
!      value into the real final destination.  */
!   emit_insn (gen_move_insn (operands[2], operands[1]));
!   emit_insn (gen_move_insn (operands[0], operands[2]));
! 
    DONE;
  }")
  
--- 5786,5824 ----
     (set_attr "mode"	"SI")
     (set_attr "length"	"8,4,4,8,4,8,4,4,4,4,8,4,8")])
  
! ;; Reload condition code registers.  reload_incc and reload_outcc
! ;; both handle moves from arbitrary operands into condition code
! ;; registers.  reload_incc handles the more common case in which
! ;; a source operand is constrained to be in a condition-code
! ;; register, but has not been allocated to one.
! ;;
! ;; Sometimes, such as in movcc, we have a CCmode destination whose
! ;; constraints do not include 'z'.  reload_outcc handles the case
! ;; when such an operand is allocated to a condition-code register.
! ;;
! ;; Note that reloads from a condition code register to some
! ;; other location can be done using ordinary moves.  Moving
! ;; into a GPR takes a single movcc, moving elsewhere takes
! ;; two.  We can leave these cases to the generic reload code.
  (define_expand "reload_incc"
!   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
! 	(match_operand:CC 1 "general_operand" ""))
     (clobber (match_operand:TF 2 "register_operand" "=&f"))]
    "ISA_HAS_8CC && TARGET_HARD_FLOAT"
    "
  {
!   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
    DONE;
  }")
  
  (define_expand "reload_outcc"
!   [(set (match_operand:CC 0 "fcc_register_operand" "=z")
! 	(match_operand:CC 1 "register_operand" ""))
!    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
    "ISA_HAS_8CC && TARGET_HARD_FLOAT"
    "
  {
!   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
    DONE;
  }")
  



More information about the Gcc mailing list