sparc-protos.h (sparc_expand_move): New prototype.
authorEric Botcazou <ebotcazou@libertysurf.fr>
Mon, 23 May 2005 07:09:03 +0000 (09:09 +0200)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 23 May 2005 07:09:03 +0000 (07:09 +0000)
* config/sparc/sparc-protos.h (sparc_expand_move): New prototype.
* config/sparc/sparc.c (sparc_expand_move): New function.
(sparc_emit_set_const64): Rewrite assert condition on entry.
(legitimate_constant_p) <CONST_VECTOR>: New case.
(legitimize_pic_address): Use TARGET_ARCH64 to select the mode.
* config/sparc/sparc.md (movqi, movhi, movsi, movdi, movV32,
movV64, movtf): Use nonimmediate_operand for the first operand.
Rewrite.  Only invoke sparc_expand_move.
* config/sparc/predicates.md (input_operand): Reorder tests.

From-SVN: r100077

gcc/ChangeLog
gcc/config/sparc/predicates.md
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md

index 74c51bc0408f8054301d5056bbb3c3bde51e85bf..c65fdfdbfef709d03ced993f9291fd73b2c11bae 100644 (file)
@@ -1,3 +1,15 @@
+2005-05-23  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * config/sparc/sparc-protos.h (sparc_expand_move): New prototype.
+       * config/sparc/sparc.c (sparc_expand_move): New function.
+       (sparc_emit_set_const64): Rewrite assert condition on entry.
+       (legitimate_constant_p) <CONST_VECTOR>: New case.
+       (legitimize_pic_address): Use TARGET_ARCH64 to select the mode.
+       * config/sparc/sparc.md (movqi, movhi, movsi, movdi, movV32,
+       movV64, movtf): Use nonimmediate_operand for the first operand.
+       Rewrite.  Only invoke sparc_expand_move.
+       * config/sparc/predicates.md (input_operand): Reorder tests.
+
 2005-05-23  Jan Beulich  <jbeulich@novell.com>
 
        * gthr-posix.h (__gthread_recursive_mutex_init_function): Add
index b56ae65af3563061cb6a7afa88c945f7ae7ac478..752286cb184d45374945f97a2b3c22b9a960b1fe 100644 (file)
   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
     return false;
 
+  mclass = GET_MODE_CLASS (mode);
+
   /* Allow any 1-instruction integer constant.  */
-  if (GET_MODE_CLASS (mode) == MODE_INT
+  if (mclass == MODE_INT
       && (small_int_operand (op, mode) || const_high_operand (op, mode)))
     return true;
 
       && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
     return true;
 
-  if (register_operand (op, mode))
-    return true;
-
-  mclass = GET_MODE_CLASS (mode);
   if ((mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
       || (mclass == MODE_VECTOR_INT && GET_CODE (op) == CONST_VECTOR))
     return true;
 
-  /* If this is a SUBREG, look inside so that we handle
-     paradoxical ones.  */
+  if (register_operand (op, mode))
+    return true;
+
+  /* If this is a SUBREG, look inside so that we handle paradoxical ones.  */
   if (GET_CODE (op) == SUBREG)
     op = SUBREG_REG (op);
 
index 74fba0c3408645363f8ec1fcdb301c7bd2059e98..a29bd691509927166af2b3f94d0cde970b5351c0 100644 (file)
@@ -74,6 +74,7 @@ extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
 extern rtx legitimize_tls_address (rtx);
 extern rtx legitimize_address (rtx, rtx, enum machine_mode);
 extern void sparc_defer_case_vector (rtx, rtx, int);
+extern bool sparc_expand_move (enum machine_mode, rtx *);
 extern void sparc_emit_set_const32 (rtx, rtx);
 extern void sparc_emit_set_const64 (rtx, rtx);
 extern void sparc_emit_set_symbolic_const64 (rtx, rtx, rtx);
index da536872bfe58ae2feb1fd15c87c33558262f97c..af920b30734c1032c90caaf0aa660f254ec5ba2c 100644 (file)
@@ -801,9 +801,6 @@ v9_regcmp_p (enum rtx_code code)
          || code == LE || code == GT);
 }
 
-\f
-/* Operand constraints.  */
-
 /* Nonzero if OP is a floating point constant which can
    be loaded into an integer register using a single
    sethi instruction.  */
@@ -877,9 +874,127 @@ tls_symbolic_operand (rtx op)
     return 0;
   return SYMBOL_REF_TLS_MODEL (op);
 }
-\f
-/* We know it can't be done in one insn when we get here,
-   the movsi expander guarantees this.  */
+
+/* Expand a move instruction.  Return true if all work is done.  */
+
+bool
+sparc_expand_move (enum machine_mode mode, rtx *operands)
+{
+  /* Handle sets of MEM first.  */
+  if (GET_CODE (operands[0]) == MEM)
+    {
+      /* 0 is a register (or a pair of registers) on SPARC.  */
+      if (register_or_zero_operand (operands[1], mode))
+       return false;
+
+      if (!reload_in_progress)
+       {
+         operands[0] = validize_mem (operands[0]);
+         operands[1] = force_reg (mode, operands[1]);
+       }
+    }
+
+  /* Fixup TLS cases.  */
+  if (tls_symbolic_operand (operands [1]))
+    operands[1] = legitimize_tls_address (operands[1]);
+
+  /* Fixup PIC cases.  */
+  if (flag_pic && CONSTANT_P (operands[1]))
+    {
+      if (pic_address_needs_scratch (operands[1]))
+       operands[1] = legitimize_pic_address (operands[1], mode, 0);
+
+      if (GET_CODE (operands[1]) == LABEL_REF && mode == SImode)
+       {
+         emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
+         return true;
+       }
+
+      if (GET_CODE (operands[1]) == LABEL_REF && mode == DImode)
+       {
+         gcc_assert (TARGET_ARCH64);
+         emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
+         return true;
+       }
+
+      if (symbolic_operand (operands[1], mode))
+       {
+         operands[1] = legitimize_pic_address (operands[1],
+                                               mode,
+                                               (reload_in_progress ?
+                                                operands[0] :
+                                                NULL_RTX));
+         return false;
+       }
+    }
+
+  /* If we are trying to toss an integer constant into FP registers,
+     or loading a FP or vector constant, force it into memory.  */
+  if (CONSTANT_P (operands[1])
+      && REG_P (operands[0])
+      && (SPARC_FP_REG_P (REGNO (operands[0]))
+         || SCALAR_FLOAT_MODE_P (mode)
+         || VECTOR_MODE_P (mode)))
+    {
+      /* emit_group_store will send such bogosity to us when it is
+         not storing directly into memory.  So fix this up to avoid
+         crashes in output_constant_pool.  */
+      if (operands [1] == const0_rtx)
+       operands[1] = CONST0_RTX (mode);
+
+      /* We can clear FP registers if TARGET_VIS, and always other regs.  */
+      if ((TARGET_VIS || REGNO (operands[0]) < SPARC_FIRST_FP_REG)
+         && const_zero_operand (operands[1], mode))
+       return false;
+
+      if (REGNO (operands[0]) < SPARC_FIRST_FP_REG
+         /* We are able to build any SF constant in integer registers
+            with at most 2 instructions.  */
+         && (mode == SFmode
+             /* And any DF constant in integer registers.  */
+             || (mode == DFmode
+                 && (reload_completed || reload_in_progress))))
+       return false;
+
+      operands[1] = force_const_mem (mode, operands[1]);
+      if (!reload_in_progress)
+       operands[1] = validize_mem (operands[1]);
+      return false;
+    }
+
+  /* Accept non-constants and valid constants unmodified.  */
+  if (!CONSTANT_P (operands[1])
+      || GET_CODE (operands[1]) == HIGH
+      || input_operand (operands[1], mode))
+    return false;
+
+  switch (mode)
+    {
+    case QImode:
+      /* All QImode constants require only one insn, so proceed.  */
+      break;
+
+    case HImode:
+    case SImode:
+      sparc_emit_set_const32 (operands[0], operands[1]);
+      return true;
+
+    case DImode:
+      /* input_operand should have filtered out 32-bit mode.  */
+      sparc_emit_set_const64 (operands[0], operands[1]);
+      return true;
+    
+    default:
+      gcc_unreachable ();
+    }
+
+  return false;
+}
+
+/* Load OP1, a 32-bit constant, into OP0, a register.
+   We know it can't be done in one insn when we get
+   here, the move expander guarantees this.  */
+
 void
 sparc_emit_set_const32 (rtx op0, rtx op1)
 {
@@ -918,13 +1033,13 @@ sparc_emit_set_const32 (rtx op0, rtx op1)
     }
 }
 
-\f
 /* Load OP1, a symbolic 64-bit constant, into OP0, a DImode register.
    If TEMP is nonzero, we are forbidden to use any other scratch
    registers.  Otherwise, we are allowed to generate them as needed.
 
    Note that TEMP may have TImode if the code model is TARGET_CM_MEDANY
    or TARGET_CM_EMBMEDANY (see the reload_indi and reload_outdi patterns).  */
+
 void
 sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp)
 {
@@ -1488,14 +1603,9 @@ sparc_emit_set_const64 (rtx op0, rtx op1)
   rtx temp = 0;
 
   /* Sanity check that we know what we are working with.  */
-  gcc_assert (TARGET_ARCH64);
-
-  if (GET_CODE (op0) != SUBREG)
-    {
-      gcc_assert (GET_CODE (op0) == REG
-                 && (REGNO (op0) < SPARC_FIRST_FP_REG
-                     || REGNO (op0) > SPARC_LAST_V9_FP_REG));
-    }
+  gcc_assert (TARGET_ARCH64
+             && (GET_CODE (op0) == SUBREG
+                 || (REG_P (op0) && ! SPARC_FP_REG_P (REGNO (op0)))));
 
   if (reload_in_progress || reload_completed)
     temp = op0;
@@ -2626,9 +2736,16 @@ legitimate_constant_p (rtx x)
       /* Floating point constants are generally not ok.
         The only exception is 0.0 in VIS.  */
       if (TARGET_VIS
-         && (GET_MODE (x) == SFmode
-             || GET_MODE (x) == DFmode
-             || GET_MODE (x) == TFmode)
+         && SCALAR_FLOAT_MODE_P (GET_MODE (x))
+         && const_zero_operand (x, GET_MODE (x)))
+       return true;
+
+      return false;
+
+    case CONST_VECTOR:
+      /* Vector constants are generally not ok.
+        The only exception is 0 in VIS.  */
+      if (TARGET_VIS
          && const_zero_operand (x, GET_MODE (x)))
        return true;
 
@@ -3007,15 +3124,15 @@ legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
             won't get confused into thinking that these two instructions
             are loading in the true address of the symbol.  If in the
             future a PIC rtx exists, that should be used instead.  */
-         if (Pmode == SImode)
+         if (TARGET_ARCH64)
            {
-             emit_insn (gen_movsi_high_pic (temp_reg, orig));
-             emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig));
+             emit_insn (gen_movdi_high_pic (temp_reg, orig));
+             emit_insn (gen_movdi_lo_sum_pic (temp_reg, temp_reg, orig));
            }
          else
            {
-             emit_insn (gen_movdi_high_pic (temp_reg, orig));
-             emit_insn (gen_movdi_lo_sum_pic (temp_reg, temp_reg, orig));
+             emit_insn (gen_movsi_high_pic (temp_reg, orig));
+             emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig));
            }
          address = temp_reg;
        }
index f40d59cd58b40d827e5b91f39405f855b38714f8..589edb612a4e4a34e4c46b84f5098f85c105a073 100644 (file)
 ;; Integer move instructions
 
 (define_expand "movqi"
-  [(set (match_operand:QI 0 "general_operand" "")
+  [(set (match_operand:QI 0 "nonimmediate_operand" "")
        (match_operand:QI 1 "general_operand" ""))]
   ""
 {
-  /* Working with CONST_INTs is easier, so convert
-     a double if needed.  */
-  if (GET_CODE (operands[1]) == CONST_DOUBLE)
-    operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), QImode);
-
-  /* Handle sets of MEM first.  */
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      if (register_or_zero_operand (operands[1], QImode))
-       goto movqi_is_ok;
-
-      if (! reload_in_progress)
-       {
-         operands[0] = validize_mem (operands[0]);
-         operands[1] = force_reg (QImode, operands[1]);
-       }
-    }
-
-  /* Fixup TLS cases.  */
-  if (tls_symbolic_operand (operands [1]))
-    operands[1] = legitimize_tls_address (operands[1]);
-
-  /* Fixup PIC cases.  */
-  if (flag_pic)
-    {
-      if (CONSTANT_P (operands[1])
-         && pic_address_needs_scratch (operands[1]))
-       operands[1] = legitimize_pic_address (operands[1], QImode, 0);
-
-      if (symbolic_operand (operands[1], QImode))
-       {
-         operands[1] = legitimize_pic_address (operands[1],
-                                               QImode,
-                                               (reload_in_progress ?
-                                                operands[0] :
-                                                NULL_RTX));
-         goto movqi_is_ok;
-       }
-    }
-
-  /* All QI constants require only one insn, so proceed.  */
-
- movqi_is_ok:
-  ;
+  if (sparc_expand_move (QImode, operands))
+    DONE;
 })
 
 (define_insn "*movqi_insn"
    (set_attr "us3load_type" "*,3cycle,*")])
 
 (define_expand "movhi"
-  [(set (match_operand:HI 0 "general_operand" "")
+  [(set (match_operand:HI 0 "nonimmediate_operand" "")
        (match_operand:HI 1 "general_operand" ""))]
   ""
 {
-  /* Working with CONST_INTs is easier, so convert
-     a double if needed.  */
-  if (GET_CODE (operands[1]) == CONST_DOUBLE)
-    operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), HImode);
-
-  /* Handle sets of MEM first.  */
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      if (register_or_zero_operand (operands[1], HImode))
-       goto movhi_is_ok;
-
-      if (! reload_in_progress)
-       {
-         operands[0] = validize_mem (operands[0]);
-         operands[1] = force_reg (HImode, operands[1]);
-       }
-    }
-
-  /* Fixup TLS cases.  */
-  if (tls_symbolic_operand (operands [1]))
-    operands[1] = legitimize_tls_address (operands[1]);
-
-  /* Fixup PIC cases.  */
-  if (flag_pic)
-    {
-      if (CONSTANT_P (operands[1])
-         && pic_address_needs_scratch (operands[1]))
-       operands[1] = legitimize_pic_address (operands[1], HImode, 0);
-
-      if (symbolic_operand (operands[1], HImode))
-       {
-         operands[1] = legitimize_pic_address (operands[1],
-                                               HImode,
-                                               (reload_in_progress ?
-                                                operands[0] :
-                                                NULL_RTX));
-         goto movhi_is_ok;
-       }
-    }
-
-  /* This makes sure we will not get rematched due to splittage.  */
-  if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
-    ;
-  else if (GET_CODE (operands[1]) != HIGH
-          && GET_CODE (operands[1]) != LO_SUM)
-    {
-      sparc_emit_set_const32 (operands[0], operands[1]);
-      DONE;
-    }
-
- movhi_is_ok:
-  ;
+  if (sparc_expand_move (HImode, operands))
+    DONE;
 })
 
 (define_insn "*movhi_insn"
   "or\t%1, %2, %0")
 
 (define_expand "movsi"
-  [(set (match_operand:SI 0 "general_operand" "")
+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
        (match_operand:SI 1 "general_operand" ""))]
   ""
 {
-  /* Working with CONST_INTs is easier, so convert
-     a double if needed.  */
-  if (GET_CODE (operands[1]) == CONST_DOUBLE)
-    operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), SImode);
-
-  /* Handle sets of MEM first.  */
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      if (register_or_zero_operand (operands[1], SImode))
-       goto movsi_is_ok;
-
-      if (! reload_in_progress)
-       {
-         operands[0] = validize_mem (operands[0]);
-         operands[1] = force_reg (SImode, operands[1]);
-       }
-    }
-
-  /* Fixup TLS cases.  */
-  if (tls_symbolic_operand (operands [1]))
-    operands[1] = legitimize_tls_address (operands[1]);
-
-  /* Fixup PIC cases.  */
-  if (flag_pic)
-    {
-      if (CONSTANT_P (operands[1])
-         && pic_address_needs_scratch (operands[1]))
-       operands[1] = legitimize_pic_address (operands[1], SImode, 0);
-
-      if (GET_CODE (operands[1]) == LABEL_REF)
-       {
-         emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
-         DONE;
-       }
-
-      if (symbolic_operand (operands[1], SImode))
-       {
-         operands[1] = legitimize_pic_address (operands[1],
-                                               SImode,
-                                               (reload_in_progress ?
-                                                operands[0] :
-                                                NULL_RTX));
-         goto movsi_is_ok;
-       }
-    }
-
-  /* If we are trying to toss an integer constant into the
-     FPU registers, force it into memory.  */
-  if (GET_CODE (operands[0]) == REG
-      && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
-      && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
-      && CONSTANT_P (operands[1]))
-    operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
-                                                operands[1]));
-
-  /* This makes sure we will not get rematched due to splittage.  */
-  if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
-    ;
-  else if (GET_CODE (operands[1]) != HIGH
-          && GET_CODE (operands[1]) != LO_SUM)
-    {
-      sparc_emit_set_const32 (operands[0], operands[1]);
-      DONE;
-    }
-
- movsi_is_ok:
-  ;
+  if (sparc_expand_move (SImode, operands))
+    DONE;
 })
 
 (define_insn "*movsi_insn"
   "or\t%1, %%lo(%a3-(%a2-.)), %0")
 
 (define_expand "movdi"
-  [(set (match_operand:DI 0 "general_operand" "")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
        (match_operand:DI 1 "general_operand" ""))]
   ""
 {
-  /* Working with CONST_INTs is easier, so convert
-     a double if needed.  */
-  if (GET_CODE (operands[1]) == CONST_DOUBLE
-#if HOST_BITS_PER_WIDE_INT == 32
-      && ((CONST_DOUBLE_HIGH (operands[1]) == 0
-          && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
-         || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
-             && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
-#endif
-      )
-    operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), DImode);
-
-  /* Handle MEM cases first.  */
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      if (register_or_zero_operand (operands[1], DImode))
-        goto movdi_is_ok;
-
-      if (! reload_in_progress)
-       {
-         operands[0] = validize_mem (operands[0]);
-         operands[1] = force_reg (DImode, operands[1]);
-       }
-    }
-
-  /* Fixup TLS cases.  */
-  if (tls_symbolic_operand (operands [1]))
-    operands[1] = legitimize_tls_address (operands[1]);
-
-  if (flag_pic)
-    {
-      if (CONSTANT_P (operands[1])
-         && pic_address_needs_scratch (operands[1]))
-       operands[1] = legitimize_pic_address (operands[1], DImode, 0);
-
-      if (GET_CODE (operands[1]) == LABEL_REF)
-        {
-          gcc_assert (TARGET_ARCH64);
-          emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
-          DONE;
-        }
-
-      if (symbolic_operand (operands[1], DImode))
-       {
-         operands[1] = legitimize_pic_address (operands[1],
-                                               DImode,
-                                               (reload_in_progress ?
-                                                operands[0] :
-                                                NULL_RTX));
-         goto movdi_is_ok;
-       }
-    }
-
-  /* If we are trying to toss an integer constant into the
-     FPU registers, force it into memory.  */
-  if (GET_CODE (operands[0]) == REG
-      && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
-      && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
-      && CONSTANT_P (operands[1]))
-    operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
-                                                operands[1]));
-
-  /* This makes sure we will not get rematched due to splittage.  */
-  if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
-    ;
-  else if (TARGET_ARCH64
-           && GET_CODE (operands[1]) != HIGH
-           && GET_CODE (operands[1]) != LO_SUM)
-    {
-      sparc_emit_set_const64 (operands[0], operands[1]);
-      DONE;
-    }
-
- movdi_is_ok:
-  ;
+  if (sparc_expand_move (DImode, operands))
+    DONE;
 })
 
 ;; Be careful, fmovd does not exist when !v9.
 
 ;; Yes, you guessed it right, the former movsf expander.
 (define_expand "mov<V32:mode>"
-  [(set (match_operand:V32 0 "general_operand" "")
+  [(set (match_operand:V32 0 "nonimmediate_operand" "")
        (match_operand:V32 1 "general_operand" ""))]
   "<V32:MODE>mode == SFmode || TARGET_VIS"
 {
-  /* Force constants into memory.  */
-  if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
-    {
-      /* emit_group_store will send such bogosity to us when it is
-         not storing directly into memory.  So fix this up to avoid
-         crashes in output_constant_pool.  */
-      if (operands [1] == const0_rtx)
-        operands[1] = CONST0_RTX (<V32:MODE>mode);
-
-      if ((TARGET_VIS || REGNO (operands[0]) < 32)
-         && const_zero_operand (operands[1], <V32:MODE>mode))
-       goto movsf_is_ok;
-
-      /* We are able to build any SF constant in integer registers
-        with at most 2 instructions.  */
-      if (REGNO (operands[0]) < 32
-         && <V32:MODE>mode == SFmode)
-       goto movsf_is_ok;
-
-      operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
-                                                   operands[1]));
-    }
-
-  /* Handle sets of MEM first.  */
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      if (register_or_zero_operand (operands[1], <V32:MODE>mode))
-       goto movsf_is_ok;
-
-      if (! reload_in_progress)
-       {
-         operands[0] = validize_mem (operands[0]);
-         operands[1] = force_reg (<V32:MODE>mode, operands[1]);
-       }
-    }
-
-  /* Fixup PIC cases.  */
-  if (flag_pic)
-    {
-      if (CONSTANT_P (operands[1])
-         && pic_address_needs_scratch (operands[1]))
-       operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
-
-      if (symbolic_operand (operands[1], <V32:MODE>mode))
-       {
-         operands[1] = legitimize_pic_address (operands[1],
-                                               <V32:MODE>mode,
-                                               (reload_in_progress ?
-                                                operands[0] :
-                                                NULL_RTX));
-       }
-    }
-
- movsf_is_ok:
-  ;
+  if (sparc_expand_move (<V32:MODE>mode, operands))
+    DONE;
 })
 
 (define_insn "*movsf_insn"
 
 ;; Yes, you again guessed it right, the former movdf expander.
 (define_expand "mov<V64:mode>"
-  [(set (match_operand:V64 0 "general_operand" "")
+  [(set (match_operand:V64 0 "nonimmediate_operand" "")
        (match_operand:V64 1 "general_operand" ""))]
   "<V64:MODE>mode == DFmode || TARGET_VIS"
 {
-  /* Force constants into memory.  */
-  if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
-    {
-      /* emit_group_store will send such bogosity to us when it is
-         not storing directly into memory.  So fix this up to avoid
-         crashes in output_constant_pool.  */
-      if (operands [1] == const0_rtx)
-        operands[1] = CONST0_RTX (<V64:MODE>mode);
-
-      if ((TARGET_VIS || REGNO (operands[0]) < 32)
-         && const_zero_operand (operands[1], <V64:MODE>mode))
-       goto movdf_is_ok;
-
-      /* We are able to build any DF constant in integer registers.  */
-      if (REGNO (operands[0]) < 32
-         && <V64:MODE>mode == DFmode
-         && (reload_completed || reload_in_progress))
-       goto movdf_is_ok;
-
-      operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
-                                                   operands[1]));
-    }
-
-  /* Handle MEM cases first.  */
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      if (register_or_zero_operand (operands[1], <V64:MODE>mode))
-       goto movdf_is_ok;
-
-      if (! reload_in_progress)
-       {
-         operands[0] = validize_mem (operands[0]);
-         operands[1] = force_reg (<V64:MODE>mode, operands[1]);
-       }
-    }
-
-  /* Fixup PIC cases.  */
-  if (flag_pic)
-    {
-      if (CONSTANT_P (operands[1])
-         && pic_address_needs_scratch (operands[1]))
-       operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
-
-      if (symbolic_operand (operands[1], <V64:MODE>mode))
-       {
-         operands[1] = legitimize_pic_address (operands[1],
-                                               <V64:MODE>mode,
-                                               (reload_in_progress ?
-                                                operands[0] :
-                                                NULL_RTX));
-       }
-    }
-
- movdf_is_ok:
-  ;
+  if (sparc_expand_move (<V64:MODE>mode, operands))
+    DONE;
 })
 
 ;; Be careful, fmovd does not exist when !v9.
 })
 
 (define_expand "movtf"
-  [(set (match_operand:TF 0 "general_operand" "")
+  [(set (match_operand:TF 0 "nonimmediate_operand" "")
        (match_operand:TF 1 "general_operand" ""))]
   ""
 {
-  /* Force TFmode constants into memory.  */
-  if (GET_CODE (operands[0]) == REG
-      && CONSTANT_P (operands[1]))
-    {
-      /* emit_group_store will send such bogosity to us when it is
-         not storing directly into memory.  So fix this up to avoid
-         crashes in output_constant_pool.  */
-      if (operands [1] == const0_rtx)
-        operands[1] = CONST0_RTX (TFmode);
-
-      if (TARGET_VIS && const_zero_operand (operands[1], TFmode))
-       goto movtf_is_ok;
-
-      operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
-                                                   operands[1]));
-    }
-
-  /* Handle MEM cases first, note that only v9 guarantees
-     full 16-byte alignment for quads.  */
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      if (register_or_zero_operand (operands[1], TFmode))
-       goto movtf_is_ok;
-
-      if (! reload_in_progress)
-       {
-         operands[0] = validize_mem (operands[0]);
-         operands[1] = force_reg (TFmode, operands[1]);
-       }
-    }
-
-  /* Fixup PIC cases.  */
-  if (flag_pic)
-    {
-      if (CONSTANT_P (operands[1])
-         && pic_address_needs_scratch (operands[1]))
-       operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
-
-      if (symbolic_operand (operands[1], TFmode))
-       {
-         operands[1] = legitimize_pic_address (operands[1],
-                                               TFmode,
-                                               (reload_in_progress ?
-                                                operands[0] :
-                                                NULL_RTX));
-       }
-    }
-
- movtf_is_ok:
-  ;
+  if (sparc_expand_move (TFmode, operands))
+    DONE;
 })
 
 (define_insn "*movtf_insn_sp32"