From d12b8c85a9c84502436fdea354e99bcd9c03338a Mon Sep 17 00:00:00 2001
From: Richard Sandiford <rsandifo@redhat.com>
Date: Tue, 1 Oct 2002 10:14:35 +0000
Subject: [PATCH] mips-protos.h (mips_emit_fcc_reload): Declare.

	* 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.
	(override_options): Allow TFmode values in float registers
	if ISA_HAS_8CC.
	* 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.

From-SVN: r57683
---
 gcc/ChangeLog                 | 13 ++++++
 gcc/config/mips/mips-protos.h |  1 +
 gcc/config/mips/mips.c        | 49 ++++++++++++++++++++-
 gcc/config/mips/mips.h        |  1 +
 gcc/config/mips/mips.md       | 80 +++++++++--------------------------
 5 files changed, 84 insertions(+), 60 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d8073b4d418f..301d1d778b01 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+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.
+	(override_options): Allow TFmode values in float registers
+	if ISA_HAS_8CC.
+	* 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.
+
 2002-09-30  Ulrich Weigand  <uweigand@de.ibm.com>
 
 	* longlong.h: Partially synchronize with GMP-4.1 version:
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index d9b12ba02dc2..df943afb3f54 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -87,6 +87,7 @@ extern void		init_cumulative_args PARAMS ((CUMULATIVE_ARGS *,
 						      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		mips_set_return_address PARAMS ((rtx, rtx));
 extern void		machine_dependent_reorg PARAMS ((rtx));
 extern int		mips_address_cost PARAMS ((rtx));
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 610beb743e9a..ae578b0677e0 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -3522,6 +3522,51 @@ mips_gen_conditional_trap (operands)
 			      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));
+}
+
 /* Emit code to change the current function's return address to
    ADDRESS.  SCRATCH is available as a scratch register, if needed.
    ADDRESS and SCRATCH are both word-mode GPRs.  */
@@ -5362,7 +5407,9 @@ override_options ()
 			/* 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)));
+			|| (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
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index ed23e27de841..8d8b401f7a7a 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -3824,6 +3824,7 @@ typedef struct mips_args {
 				  REG, 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 --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 9d269f5ee68d..a351add1e305 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -6025,77 +6025,39 @@ move\\t%0,%z4\\n\\
    (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.
-
+;; 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 "register_operand" "=z")
-	(match_operand:CC 1 "general_operand" "z"))
+  [(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"
   "
 {
-  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)));
-
+  mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
   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"))]
+  [(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"
   "
 {
-  /* 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]));
-
+  mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
   DONE;
 }")
 
-- 
GitLab