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:
parent
a9802526ea
commit
243f24b4c7
|
@ -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:
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 }},
|
||||
|
||||
|
|
|
@ -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;
|
||||
}")
|
||||
|
||||
|
|
Loading…
Reference in New Issue