]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
frv.c (movcc_fp_destination_operand): New.
authorAlexandre Oliva <aoliva@redhat.com>
Tue, 1 Feb 2005 06:33:35 +0000 (06:33 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Tue, 1 Feb 2005 06:33:35 +0000 (06:33 +0000)
* 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

gcc/ChangeLog
gcc/config/frv/frv.c
gcc/config/frv/frv.h
gcc/config/frv/frv.md

index a67eb7f91c4de824db7d051d41b5b20a8301b818..ce0422c9323b80993079f13987d9c10d0523f75e 100644 (file)
@@ -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
index da3266ad3d5437fb9f7cb5b2b6186623fd36c120..833ccee686a62d67aa4260fffa9cca87c3dcdadc 100644 (file)
@@ -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
index 0636fff3664c20440ba2cd7a391d68890f566a3d..148ecae42e60c16d3a361ed3fa76ae3295958cea 100644 (file)
@@ -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,      \
index 0fc13e2a9e923a0d19b28a9740d59ac58d99cea5..94520ef46a9432b9e5343eabb852e7333874a7e2 100644 (file)
 ;; 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"
   "
 }")
 
 (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)"
   "@
 
 (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"
   "
   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)));