summaryrefslogtreecommitdiff
path: root/gcc/config/frv
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2005-02-01 06:33:35 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2005-02-01 06:33:35 +0000
commit7b150713cf3dcfeabd4cc01ecd24f4843cd46c31 (patch)
tree17fb9906b4b1c13fb22721a25ba78ef3468d22ce /gcc/config/frv
parente894ab29c7bb872bc9ff2bc79f1b7c05033563cb (diff)
downloadgcc-7b150713cf3dcfeabd4cc01ecd24f4843cd46c31.tar.gz
frv.c (movcc_fp_destination_operand): New.
* 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. From-SVN: r94523
Diffstat (limited to 'gcc/config/frv')
-rw-r--r--gcc/config/frv/frv.c48
-rw-r--r--gcc/config/frv/frv.h2
-rw-r--r--gcc/config/frv/frv.md27
3 files changed, 73 insertions, 4 deletions
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index da3266ad3d5..833ccee686a 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 0636fff3664..148ecae42e6 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 0fc13e2a9e9..94520ef46a9 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)));