This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Backport fix for PR6362 to 3.2.x?
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- To: rsandifo at redhat dot com
- Cc: David dot Billinghurst at riotinto dot com, echristo at redhat dot com, gcc-patches at gcc dot gnu dot org, gcc at gcc dot gnu dot org, gdr at integrable-solutions dot net
- Date: Tue, 11 Feb 2003 10:31:08 -0500 (EST)
- Subject: Re: Backport fix for PR6362 to 3.2.x?
- References: <wvn65rsqxk9.fsf@talisman.cambridge.redhat.com>
> From: Richard Sandiford <rsandifo@redhat.com>
>
> "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> writes:
> > Richard since it's your patch would you please comment on this piece?
> > Is it necessary and still relevant for 3.2.x?
> >
> > * mips.c (override_options): Allow TFmode values in float
> > registers if ISA_HAS_8CC.
>
> No, I think it fixes a problem I introduced on trunk after 3.1 branched.
> The rest of the patch wouldn't work if TFmode values weren't allowed
> in float regs, so if your backport fixes the regression, this bit
> shouldn't be needed.
> Richard
Here is the patch I tested. In addition to the previous patch I also
had to backport the definition of FP_INC into mips.h. Bootstrapped in
3.2.x on mips-sgi-irix6.5. No regressions and the compile/920501-4.c
failure with -mips4 is gone.
Is this ok for 3.2.x?
Thanks,
--Kaveh
2003-02-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* mips.h (FP_INC): Define.
Backport:
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:13:04 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 16:34:15 2003
*************** do { \
*** 1582,1587 ****
--- 1582,1591 ----
/* For MIPS, width of a floating point register. */
#define UNITS_PER_FPREG (TARGET_FLOAT64 ? 8 : 4)
+ /* If register $f0 holds a floating-point value, $f(0 + FP_INC) is
+ the next available register. */
+ #define FP_INC (TARGET_FLOAT64 || TARGET_SINGLE_FLOAT ? 1 : 2)
+
/* A C expression for the size in bits of the type `int' on the
target machine. If you don't define this, the default is one
word. */
*************** while (0)
*** 4001,4006 ****
--- 4005,4011 ----
{"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:13:04 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:13:04 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;
}")