re PR target/6362 (mips-irix6 gcc-3.1 C testsuite failure with -mips4 in compile/920501-4.c)

* mips.h (FP_INC): Define.

	Backport fix for PR6362:
	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.

From-SVN: r62770
This commit is contained in:
Kaveh R. Ghazi 2003-02-12 15:25:50 +00:00 committed by Kaveh Ghazi
parent a9802526ea
commit 243f24b4c7
5 changed files with 88 additions and 59 deletions

View File

@ -1,3 +1,19 @@
2003-02-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* mips.h (FP_INC): Define.
Backport fix for PR6362:
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.
2003-02-11 Bob Wilson <bob.wilson@acm.org>
Backport following patch:

View File

@ -80,6 +80,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 machine_dependent_reorg PARAMS ((rtx));
extern int mips_address_cost PARAMS ((rtx));
extern void mips_count_memory_refs PARAMS ((rtx, int));

View File

@ -3267,6 +3267,51 @@ mips_gen_conditional_trap (operands)
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:

View File

@ -1582,6 +1582,10 @@ do { \
/* 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. */
@ -4001,6 +4005,7 @@ while (0)
{"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 }},

View File

@ -5786,77 +5786,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;
}")