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
This commit is contained in:
Richard Sandiford 2002-10-01 10:14:35 +00:00 committed by Richard Sandiford
parent 73bff06445
commit d12b8c85a9
5 changed files with 84 additions and 60 deletions

View File

@ -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:

View File

@ -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));

View File

@ -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

View File

@ -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 }},

View File

@ -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;
}")