aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/frv/frv.c48
-rw-r--r--gcc/config/frv/frv.h2
-rw-r--r--gcc/config/frv/frv.md27
4 files changed, 84 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a67eb7f..ce0422c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2005-02-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/frv/frv.c (movcc_fp_destination_operand): New.
+ (gpr_or_memory_operand): Fix typo in comment.
+ (gpr_or_memory_operand_with_scratch): New.
+ * config/frv/frv.h (PREDICATE_CODES): Add the two new predicates.
+ * config/frv/frv.md (movcc_fp, movcc_fp_internal): Use
+ movcc_fp_destination_operand.
+ (reload_incc_fp): Use gpr_or_memory_operand_with_scratch.
+ Legitimize memory addresses using a scratch register.
+
2005-01-31 Jeff Law <law@redhat.com>
* tree-into-ssa.c (mark_def_sites_global_data): Make KILLS
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index da3266a..833ccee 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -4569,6 +4569,19 @@ move_destination_operand (rtx op, enum machine_mode mode)
return FALSE;
}
+/* Return true if we the operand is a valid destination for a movcc_fp
+ instruction. This means rejecting fcc_operands, since we need
+ scratch registers to write to them. */
+
+int
+movcc_fp_destination_operand (rtx op, enum machine_mode mode)
+{
+ if (fcc_operand (op, mode))
+ return FALSE;
+
+ return move_destination_operand (op, mode);
+}
+
/* Look for a SYMBOL_REF of a function in an rtx. We always want to
process these separately from any offsets, such that we add any
offsets to the function descriptor (the actual pointer), not to the
@@ -4832,7 +4845,8 @@ const_unspec_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return frv_const_unspec_p (op, &unspec);
}
-/* Return true if operand is a gpr register or a valid memory operation. */
+
+/* Return true if operand is a gpr register or a valid memory operand. */
int
gpr_or_memory_operand (rtx op, enum machine_mode mode)
@@ -4841,6 +4855,38 @@ gpr_or_memory_operand (rtx op, enum machine_mode mode)
|| frv_legitimate_memory_operand (op, mode, FALSE));
}
+/* Return true if operand is a gpr register, a valid memory operand,
+ or a memory operand that can be made valid using an additional gpr
+ register. */
+
+int
+gpr_or_memory_operand_with_scratch (rtx op, enum machine_mode mode)
+{
+ rtx addr;
+
+ if (gpr_or_memory_operand (op, mode))
+ return TRUE;
+
+ if (GET_CODE (op) != MEM)
+ return FALSE;
+
+ if (GET_MODE (op) != mode)
+ return FALSE;
+
+ addr = XEXP (op, 0);
+
+ if (GET_CODE (addr) != PLUS)
+ return FALSE;
+
+ if (!integer_register_operand (XEXP (addr, 0), Pmode))
+ return FALSE;
+
+ if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
+ return FALSE;
+
+ return TRUE;
+}
+
/* Return true if operand is a fpr register or a valid memory operation. */
int
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index 0636fff..148ecae 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -3023,12 +3023,14 @@ do { \
CONST_DOUBLE, CONST, \
SYMBOL_REF, LABEL_REF }}, \
{ "move_destination_operand", { REG, SUBREG, MEM }}, \
+ { "movcc_fp_destination_operand", { REG, SUBREG, MEM }}, \
{ "condexec_source_operand", { REG, SUBREG, CONST_INT, MEM, \
CONST_DOUBLE }}, \
{ "condexec_dest_operand", { REG, SUBREG, MEM }}, \
{ "reg_or_0_operand", { REG, SUBREG, CONST_INT }}, \
{ "lr_operand", { REG }}, \
{ "gpr_or_memory_operand", { REG, SUBREG, MEM }}, \
+ { "gpr_or_memory_operand_with_scratch", { REG, SUBREG, MEM }}, \
{ "fpr_or_memory_operand", { REG, SUBREG, MEM }}, \
{ "int12_operand", { CONST_INT }}, \
{ "int_2word_operand", { CONST_INT, CONST_DOUBLE, \
diff --git a/gcc/config/frv/frv.md b/gcc/config/frv/frv.md
index 0fc13e2..94520ef 100644
--- a/gcc/config/frv/frv.md
+++ b/gcc/config/frv/frv.md
@@ -2426,7 +2426,7 @@
;; to make it conditional on reload.
(define_expand "movcc_fp"
- [(set (match_operand:CC_FP 0 "move_destination_operand" "")
+ [(set (match_operand:CC_FP 0 "movcc_fp_destination_operand" "")
(match_operand:CC_FP 1 "move_source_operand" ""))]
"TARGET_HAS_FPRS"
"
@@ -2436,7 +2436,7 @@
}")
(define_insn "*movcc_fp_internal"
- [(set (match_operand:CC_FP 0 "move_destination_operand" "=d,d,d,m")
+ [(set (match_operand:CC_FP 0 "movcc_fp_destination_operand" "=d,d,d,m")
(match_operand:CC_FP 1 "move_source_operand" "u,d,m,d"))]
"TARGET_HAS_FPRS && (reload_in_progress || reload_completed)"
"@
@@ -2450,7 +2450,7 @@
(define_expand "reload_incc_fp"
[(match_operand:CC_FP 0 "fcc_operand" "=u")
- (match_operand:CC_FP 1 "memory_operand" "m")
+ (match_operand:CC_FP 1 "gpr_or_memory_operand_with_scratch" "m")
(match_operand:TI 2 "integer_register_operand" "=&d")]
"TARGET_HAS_FPRS"
"
@@ -2462,6 +2462,27 @@
int shift = CC_SHIFT_RIGHT (REGNO (operands[0]));
HOST_WIDE_INT mask;
+ if (!gpr_or_memory_operand (operands[1], CC_FPmode))
+ {
+ rtx addr;
+ rtx temp3 = simplify_gen_subreg (SImode, operands[2], TImode, 12);
+
+ if (GET_CODE (operands[1]) != MEM)
+ abort ();
+
+ addr = XEXP (operands[1], 0);
+
+ if (GET_CODE (addr) != PLUS)
+ abort ();
+
+ emit_move_insn (temp3, XEXP (addr, 1));
+
+ operands[1] = replace_equiv_address (operands[1],
+ gen_rtx_PLUS (GET_MODE (addr),
+ XEXP (addr, 0),
+ temp3));
+ }
+
emit_insn (gen_movcc_fp (cc_op2, operands[1]));
if (shift)
emit_insn (gen_ashlsi3 (int_op2, int_op2, GEN_INT (shift)));