diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2005-02-01 06:33:35 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2005-02-01 06:33:35 +0000 |
commit | 7b150713cf3dcfeabd4cc01ecd24f4843cd46c31 (patch) | |
tree | 17fb9906b4b1c13fb22721a25ba78ef3468d22ce /gcc/config/frv | |
parent | e894ab29c7bb872bc9ff2bc79f1b7c05033563cb (diff) | |
download | gcc-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.c | 48 | ||||
-rw-r--r-- | gcc/config/frv/frv.h | 2 | ||||
-rw-r--r-- | gcc/config/frv/frv.md | 27 |
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))); |