aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2002-10-01 10:14:35 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2002-10-01 10:14:35 +0000
commitd12b8c85a9c84502436fdea354e99bcd9c03338a (patch)
treef69c789a027f4f0baede901d54b871c4a8488d62 /gcc
parent73bff0644500d63d67e70d753784bbc83525b938 (diff)
downloadgcc-d12b8c85a9c84502436fdea354e99bcd9c03338a.zip
gcc-d12b8c85a9c84502436fdea354e99bcd9c03338a.tar.gz
gcc-d12b8c85a9c84502436fdea354e99bcd9c03338a.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.c49
-rw-r--r--gcc/config/mips/mips.h1
-rw-r--r--gcc/config/mips/mips.md80
5 files changed, 84 insertions, 60 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d8073b4..301d1d7 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 d9b12ba..df943af 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 610beb7..ae578b0 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 ed23e27..8d8b401 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 9d269f5..a351add 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;
}")