re PR target/18230 (SPARC VIS instructions are not generated by GCC)
authorJames A. Morrison <phython@gcc.gnu.org>
Tue, 9 Nov 2004 17:06:03 +0000 (17:06 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 9 Nov 2004 17:06:03 +0000 (17:06 +0000)
PR target/18230
* doc/md.texi (SPARC constraints): Document 'Y' constraint.
* config/sparc/sparc-modes.def: Add vector modes of 4 and 8 bytes.
* config/sparc/sparc.c (sparc_vector_mode_supported_p): New function.
(TARGET_VECTOR_MODE_SUPPORTED_P): Set to sparc_vector_mode_supported_p.
(fp_zero_operand): Accept MODE_VECTOR_INT modes.
(input_operand): Accept CONST_VECTOR with MODE_VECTOR_INT modes.
(sparc_cannot_force_const_mem): Return false for CONST_VECTOR.
(sparc_init_modes): Set sparc_mode_class to SF_MODE or DF_MODE for
MODE_VECTOR_INT modes.
(sparc_extra_constraint_check): Add new constraint 'Y'.
* config/sparc/sparc.h: Define UNITS_PER_SIMD_WORD to 8 for TARGET_VIS.
* config/sparc/sparc.md (V32): New mode macro for 32-bit modes.
(V64): New mode macro for 64-bit modes.
(movsf): Use V32 for mode instead of SF.
(movsf_insn_vis): Use V32 for mode instead of SF.  Add 'Y' constraint
alongside 'G' constraint.
(movdf): Use V64 for mode instead of DF.
(movdf_insn_v9only_vis, modf_insn_sp64_vis): Use V64 for mode instead
of DF.  Add 'Y' constraint alongside 'G' constraint.
(multi-isn and misaligned mems DFmode splitters): Use V64 for mode
instead of DF.

Co-Authored-By: Eric Botcazou <ebotcazou@libertysurf.fr>
From-SVN: r90348

gcc/ChangeLog
gcc/config/sparc/sparc-modes.def
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/sparc/sparc.md
gcc/doc/md.texi

index 1816d81f1cb591185dc634a18c264a184bee5943..5ce802b6d144d40cb8a46f800bd6f73efe134316 100644 (file)
@@ -1,3 +1,29 @@
+2004-11-09  James A. Morrison  <phython@gcc.gnu.org>
+            Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR target/18230
+       * doc/md.texi (SPARC constraints): Document 'Y' constraint.
+       * config/sparc/sparc-modes.def: Add vector modes of 4 and 8 bytes.
+       * config/sparc/sparc.c (sparc_vector_mode_supported_p): New function.
+       (TARGET_VECTOR_MODE_SUPPORTED_P): Set to sparc_vector_mode_supported_p.
+       (fp_zero_operand): Accept MODE_VECTOR_INT modes.
+       (input_operand): Accept CONST_VECTOR with MODE_VECTOR_INT modes.
+       (sparc_cannot_force_const_mem): Return false for CONST_VECTOR.
+       (sparc_init_modes): Set sparc_mode_class to SF_MODE or DF_MODE for
+       MODE_VECTOR_INT modes.
+       (sparc_extra_constraint_check): Add new constraint 'Y'.
+       * config/sparc/sparc.h: Define UNITS_PER_SIMD_WORD to 8 for TARGET_VIS.
+       * config/sparc/sparc.md (V32): New mode macro for 32-bit modes.
+       (V64): New mode macro for 64-bit modes.
+       (movsf): Use V32 for mode instead of SF.
+       (movsf_insn_vis): Use V32 for mode instead of SF.  Add 'Y' constraint
+       alongside 'G' constraint.
+       (movdf): Use V64 for mode instead of DF.
+       (movdf_insn_v9only_vis, modf_insn_sp64_vis): Use V64 for mode instead
+       of DF.  Add 'Y' constraint alongside 'G' constraint.
+       (multi-isn and misaligned mems DFmode splitters): Use V64 for mode
+       instead of DF.
+
 2004-11-09  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * config/s390/s390.c (s390_select_ccmode): Return CCAPmode for
index ea2a99d5ae1397f63251e33f92934cd0f3112855..bf85aed5bec3c44ecb009d48605c13157fbb6e81 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GCC, for Sun SPARC.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com).
    64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
    at Cygnus Support.
@@ -42,3 +42,7 @@ CC_MODE (CC_NOOV);
 CC_MODE (CCX_NOOV);
 CC_MODE (CCFP);
 CC_MODE (CCFPE);
+
+/* Vector modes.  */
+VECTOR_MODES (INT, 8);        /*       V8QI V4HI V2SI */
+VECTOR_MODES (INT, 4);        /*       V4QI V2HI */
index 5c5b3267b4e261924a4a3e28ce3711836e82a006..0f3488492ed4161d0992c275d6fc666405c678d2 100644 (file)
@@ -348,6 +348,7 @@ static rtx sparc_struct_value_rtx (tree, int);
 static bool sparc_return_in_memory (tree, tree);
 static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *);
 static tree sparc_gimplify_va_arg (tree, tree, tree *, tree *);
+static bool sparc_vector_mode_supported_p (enum machine_mode);
 static bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
                                     enum machine_mode, tree, bool);
 #ifdef SUBTARGET_ATTRIBUTE_TABLE
@@ -466,6 +467,9 @@ enum processor_type sparc_cpu;
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR sparc_gimplify_va_arg
 
+#undef TARGET_VECTOR_MODE_SUPPORTED_P
+#define TARGET_VECTOR_MODE_SUPPORTED_P sparc_vector_mode_supported_p
+
 #ifdef SUBTARGET_INSERT_ATTRIBUTES
 #undef TARGET_INSERT_ATTRIBUTES
 #define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
@@ -769,7 +773,8 @@ const1_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
 int
 fp_zero_operand (rtx op, enum machine_mode mode)
 {
-  if (GET_MODE_CLASS (GET_MODE (op)) != MODE_FLOAT)
+  enum mode_class mclass = GET_MODE_CLASS (GET_MODE (op));
+  if (mclass != MODE_FLOAT && mclass != MODE_VECTOR_INT)
     return 0;
   return op == CONST0_RTX (mode);
 }
@@ -1498,6 +1503,8 @@ clobbered_register (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
 int
 input_operand (rtx op, enum machine_mode mode)
 {
+  enum mode_class mclass;
+
   /* If both modes are non-void they must be the same.  */
   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
     return 0;
@@ -1538,8 +1545,9 @@ input_operand (rtx op, enum machine_mode mode)
   if (register_operand (op, mode))
     return 1;
 
-  if (GET_MODE_CLASS (mode) == MODE_FLOAT
-      && GET_CODE (op) == CONST_DOUBLE)
+  mclass = GET_MODE_CLASS (mode);
+  if ((mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
+      || (mclass == MODE_VECTOR_INT && GET_CODE (op) == CONST_VECTOR))
     return 1;
 
   /* If this is a SUBREG, look inside so that we handle
@@ -3293,6 +3301,7 @@ sparc_cannot_force_const_mem (rtx x)
     {
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
       /* Accept all non-symbolic constants.  */
       return false;
 
@@ -4181,6 +4190,12 @@ sparc_init_modes (void)
          else 
            sparc_mode_class[i] = 0;
          break;
+       case MODE_VECTOR_INT:
+         if (GET_MODE_SIZE (i) <= 4)
+           sparc_mode_class[i] = 1 << (int)SF_MODE;
+         else if (GET_MODE_SIZE (i) == 8)
+           sparc_mode_class[i] = 1 << (int)DF_MODE;
+         break;
        case MODE_FLOAT:
        case MODE_COMPLEX_FLOAT:
          if (GET_MODE_SIZE (i) <= 4)
@@ -6263,6 +6278,15 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
   return build_va_arg_indirect_ref (addr);
 }
 \f
+/* Implement the TARGET_VECTOR_MODE_SUPPORTED_P target hook.
+   Specify whether the vector mode is supported by the hardware.  */
+
+static bool
+sparc_vector_mode_supported_p (enum machine_mode mode)
+{
+  return TARGET_VIS && VECTOR_MODE_P (mode) ? true : false;
+}
+\f
 /* Return the string to output an unconditional branch to LABEL, which is
    the operand number of the label.
 
@@ -8445,6 +8469,9 @@ sparc_extra_constraint_check (rtx op, int c, int strict)
     case 'T':
       break;
 
+    case 'Y':
+      return fp_zero_operand (op, GET_MODE (op));
+
     default:
       return 0;
     }
index d1b93ec1ab730f35ef074a1e1dd861594bc5ab61..37f1905bb58cbb902e5a2cb5319c1c546a53e06e 100644 (file)
@@ -769,6 +769,8 @@ extern struct sparc_cpu_select sparc_select[];
 #define MIN_UNITS_PER_WORD     4
 #endif
 
+#define UNITS_PER_SIMD_WORD    (TARGET_VIS ? 8 : 0)
+
 /* Now define the sizes of the C data types.  */
 
 #define SHORT_TYPE_SIZE                16
@@ -2042,7 +2044,9 @@ do {                                                                      \
        integer register, needed for ldd/std instructions.
 
    'W' handles the memory operand when moving operands in/out
-       of 'e' constraint floating point registers.  */
+       of 'e' constraint floating point registers.
+
+   'Y' handles the zero vector constant.  */
 
 #ifndef REG_OK_STRICT
 
index 1000fbb3063a6c9f9ea21ada4eb32fe05167facf..0118a3c30372850e235156cd1b85708758e521d6 100644 (file)
   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
    (set_attr "fptype" "*,*,*,*,*,double,*,*")])
 
+;; We don't define V1SI because SI should work just fine.
+(define_mode_macro V64 [DF V4HI V8QI V2SI])
+(define_mode_macro V32 [SF V2HI V4QI])
+
 (define_insn "*movdi_insn_sp64_vis"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e,J"))]
   [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
 
 (define_insn "*movsf_insn_vis"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
-       (match_operand:SF 1 "input_operand"         "f,G,G,Q,*rR,S,m,m,f,*rG"))]
+  [(set (match_operand:V32 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
+       (match_operand:V32 1 "input_operand"         "f,GY,GY,Q,*rR,S,m,m,f,*rGY"))]
   "(TARGET_FPU && TARGET_VIS)
-   && (register_operand (operands[0], SFmode)
-       || register_operand (operands[1], SFmode)
-       || fp_zero_operand (operands[1], SFmode))"
+   && (register_operand (operands[0], <V32:MODE>mode)
+       || register_operand (operands[1], <V32:MODE>mode)
+       || fp_zero_operand (operands[1], <V32:MODE>mode))"
 {
   if (GET_CODE (operands[1]) == CONST_DOUBLE
       && (which_alternative == 3
 }
   [(set_attr "type" "*,*,*,*,load,store")])
 
+;; The following 3 patterns build SFmode constants in integer registers.
+
 (define_insn "*movsf_lo_sum"
   [(set (match_operand:SF 0 "register_operand" "=r")
         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
   [(set (match_dup 0) (high:SF (match_dup 1)))
    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
 
-(define_expand "movsf"
-  [(set (match_operand:SF 0 "general_operand" "")
-       (match_operand:SF 1 "general_operand" ""))]
-  ""
+;; Yes, you guessed it right, the former movsf expander.
+(define_expand "mov<V32:mode>"
+  [(set (match_operand:V32 0 "general_operand" "")
+       (match_operand:V32 1 "general_operand" ""))]
+  "<V32:MODE>mode == SFmode || TARGET_VIS"
 {
-  /* Force SFmode constants into memory.  */
-  if (GET_CODE (operands[0]) == REG
-      && CONSTANT_P (operands[1]))
+  /* 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 (SFmode);
+        operands[1] = CONST0_RTX (<V32:MODE>mode);
 
-      if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
+      if ((TARGET_VIS || REGNO (operands[0]) < 32)
+         && fp_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)
+      if (REGNO (operands[0]) < 32
+         && <V32:MODE>mode == SFmode)
        goto movsf_is_ok;
 
       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
   /* Handle sets of MEM first.  */
   if (GET_CODE (operands[0]) == MEM)
     {
-      if (register_operand (operands[1], SFmode)
-         || fp_zero_operand (operands[1], SFmode))
+      if (register_operand (operands[1], <V32:MODE>mode)
+         || fp_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 (SFmode, operands[1]);
+         operands[1] = force_reg (<V32:MODE>mode, operands[1]);
        }
     }
 
     {
       if (CONSTANT_P (operands[1])
          && pic_address_needs_scratch (operands[1]))
-       operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
+       operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
 
-      if (symbolic_operand (operands[1], SFmode))
+      if (symbolic_operand (operands[1], <V32:MODE>mode))
        {
          operands[1] = legitimize_pic_address (operands[1],
-                                               SFmode,
+                                               <V32:MODE>mode,
                                                (reload_in_progress ?
                                                 operands[0] :
                                                 NULL_RTX));
   ;
 })
 
-(define_expand "movdf"
-  [(set (match_operand:DF 0 "general_operand" "")
-       (match_operand:DF 1 "general_operand" ""))]
-  ""
+;; Yes, you again guessed it right, the former movdf expander.
+(define_expand "mov<V64:mode>"
+  [(set (match_operand:V64 0 "general_operand" "")
+       (match_operand:V64 1 "general_operand" ""))]
+  "<V64:MODE>mode == DFmode || TARGET_VIS"
 {
-  /* Force DFmode constants into memory.  */
-  if (GET_CODE (operands[0]) == REG
-      && CONSTANT_P (operands[1]))
+  /* 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 (DFmode);
+        operands[1] = CONST0_RTX (<V64:MODE>mode);
 
       if ((TARGET_VIS || REGNO (operands[0]) < 32)
-         && fp_zero_operand (operands[1], DFmode))
+         && fp_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;
 
   /* Handle MEM cases first.  */
   if (GET_CODE (operands[0]) == MEM)
     {
-      if (register_operand (operands[1], DFmode)
-         || fp_zero_operand (operands[1], DFmode))
+      if (register_operand (operands[1], <V64:MODE>mode)
+         || fp_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 (DFmode, operands[1]);
+         operands[1] = force_reg (<V64:MODE>mode, operands[1]);
        }
     }
 
     {
       if (CONSTANT_P (operands[1])
          && pic_address_needs_scratch (operands[1]))
-       operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
+       operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
 
-      if (symbolic_operand (operands[1], DFmode))
+      if (symbolic_operand (operands[1], <V64:MODE>mode))
        {
          operands[1] = legitimize_pic_address (operands[1],
-                                               DFmode,
+                                               <V64:MODE>mode,
                                                (reload_in_progress ?
                                                 operands[0] :
                                                 NULL_RTX));
 ;; We have available v9 double floats but not 64-bit
 ;; integer registers but we have VIS.
 (define_insn "*movdf_insn_v9only_vis"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
-        (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
+  [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
+        (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
   "TARGET_FPU
    && TARGET_VIS
    && ! TARGET_ARCH64
-   && (register_operand (operands[0], DFmode)
-       || register_operand (operands[1], DFmode)
-       || fp_zero_operand (operands[1], DFmode))"
+   && (register_operand (operands[0], <V64:MODE>mode)
+       || register_operand (operands[1], <V64:MODE>mode)
+       || fp_zero_operand (operands[1], <V64:MODE>mode))"
   "@
   fzero\t%0
   fmovd\t%1, %0
 ;; We have available both v9 double floats and 64-bit
 ;; integer registers. And we have VIS.
 (define_insn "*movdf_insn_sp64_vis"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
-        (match_operand:DF 1 "input_operand"    "G,e,W#F,e,*rG,m,*rG,F"))]
+  [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
+        (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
   "TARGET_FPU
    && TARGET_VIS
    && TARGET_ARCH64
-   && (register_operand (operands[0], DFmode)
-       || register_operand (operands[1], DFmode)
-       || fp_zero_operand (operands[1], DFmode))"
+   && (register_operand (operands[0], <V64:MODE>mode)
+       || register_operand (operands[1], <V64:MODE>mode)
+       || fp_zero_operand (operands[1], <V64:MODE>mode))"
   "@
   fzero\t%0
   fmovd\t%1, %0
   stx\t%r1, %0"
   [(set_attr "type" "*,load,store")])
 
+;; This pattern build DFmode constants in integer registers.
 (define_split
   [(set (match_operand:DF 0 "register_operand" "")
         (match_operand:DF 1 "const_double_operand" ""))]
 ;; careful when V9 but not ARCH64 because the integer
 ;; register DFmode cases must be handled.
 (define_split
-  [(set (match_operand:DF 0 "register_operand" "")
-        (match_operand:DF 1 "register_operand" ""))]
+  [(set (match_operand:V64 0 "register_operand" "")
+        (match_operand:V64 1 "register_operand" ""))]
   "(! TARGET_V9
     || (! TARGET_ARCH64
         && ((GET_CODE (operands[0]) == REG
   rtx set_src = operands[1];
   rtx dest1, dest2;
   rtx src1, src2;
+  enum machine_mode half_mode;
 
-  dest1 = gen_highpart (SFmode, set_dest);
-  dest2 = gen_lowpart (SFmode, set_dest);
-  src1 = gen_highpart (SFmode, set_src);
-  src2 = gen_lowpart (SFmode, set_src);
+  /* We can be expanded for DFmode or integral vector modes.  */
+  if (<V64:MODE>mode == DFmode)
+    half_mode = SFmode;
+  else
+    half_mode = SImode;
+  
+  dest1 = gen_highpart (half_mode, set_dest);
+  dest2 = gen_lowpart (half_mode, set_dest);
+  src1 = gen_highpart (half_mode, set_src);
+  src2 = gen_lowpart (half_mode, set_src);
 
   /* Now emit using the real source and destination we found, swapping
      the order if we detect overlap.  */
   if (reg_overlap_mentioned_p (dest1, src2))
     {
-      emit_insn (gen_movsf (dest2, src2));
-      emit_insn (gen_movsf (dest1, src1));
+      emit_move_insn_1 (dest2, src2);
+      emit_move_insn_1 (dest1, src1);
     }
   else
     {
-      emit_insn (gen_movsf (dest1, src1));
-      emit_insn (gen_movsf (dest2, src2));
+      emit_move_insn_1 (dest1, src1);
+      emit_move_insn_1 (dest2, src2);
     }
   DONE;
 })
 
 (define_split
-  [(set (match_operand:DF 0 "register_operand" "")
-       (match_operand:DF 1 "memory_operand" ""))]
+  [(set (match_operand:V64 0 "register_operand" "")
+       (match_operand:V64 1 "memory_operand" ""))]
   "reload_completed
    && ! TARGET_ARCH64
    && (((REGNO (operands[0]) % 2) != 0)
    && offsettable_memref_p (operands[1])"
   [(clobber (const_int 0))]
 {
-  rtx word0 = adjust_address (operands[1], SFmode, 0);
-  rtx word1 = adjust_address (operands[1], SFmode, 4);
+  enum machine_mode half_mode;
+  rtx word0, word1;
+
+  /* We can be expanded for DFmode or integral vector modes.  */
+  if (<V64:MODE>mode == DFmode)
+    half_mode = SFmode;
+  else
+    half_mode = SImode;
+
+  word0 = adjust_address (operands[1], half_mode, 0);
+  word1 = adjust_address (operands[1], half_mode, 4);
 
-  if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
+  if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
     {
-      emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
-                           word1));
-      emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
-                           word0));
+      emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
+      emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
     }
   else
     {
-      emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
-                           word0));
-      emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
-                           word1));
+      emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
+      emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
     }
   DONE;
 })
 
 (define_split
-  [(set (match_operand:DF 0 "memory_operand" "")
-       (match_operand:DF 1 "register_operand" ""))]
+  [(set (match_operand:V64 0 "memory_operand" "")
+       (match_operand:V64 1 "register_operand" ""))]
   "reload_completed
    && ! TARGET_ARCH64
    && (((REGNO (operands[1]) % 2) != 0)
    && offsettable_memref_p (operands[0])"
   [(clobber (const_int 0))]
 {
-  rtx word0 = adjust_address (operands[0], SFmode, 0);
-  rtx word1 = adjust_address (operands[0], SFmode, 4);
+  enum machine_mode half_mode;
+  rtx word0, word1;
 
-  emit_insn (gen_movsf (word0,
-                       gen_highpart (SFmode, operands[1])));
-  emit_insn (gen_movsf (word1,
-                       gen_lowpart (SFmode, operands[1])));
+  /* We can be expanded for DFmode or integral vector modes.  */
+  if (<V64:MODE>mode == DFmode)
+    half_mode = SFmode;
+  else
+    half_mode = SImode;
+
+  word0 = adjust_address (operands[0], half_mode, 0);
+  word1 = adjust_address (operands[0], half_mode, 4);
+
+  emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
+  emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
   DONE;
 })
 
 (define_split
-  [(set (match_operand:DF 0 "memory_operand" "")
-        (match_operand:DF 1 "fp_zero_operand" ""))]
+  [(set (match_operand:V64 0 "memory_operand" "")
+        (match_operand:V64 1 "fp_zero_operand" ""))]
   "reload_completed
    && (! TARGET_V9
        || (! TARGET_ARCH64
    && offsettable_memref_p (operands[0])"
   [(clobber (const_int 0))]
 {
+  enum machine_mode half_mode;
   rtx dest1, dest2;
 
-  dest1 = adjust_address (operands[0], SFmode, 0);
-  dest2 = adjust_address (operands[0], SFmode, 4);
+  /* We can be expanded for DFmode or integral vector modes.  */
+  if (<V64:MODE>mode == DFmode)
+    half_mode = SFmode;
+  else
+    half_mode = SImode;
+
+  dest1 = adjust_address (operands[0], half_mode, 0);
+  dest2 = adjust_address (operands[0], half_mode, 4);
 
-  emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
-  emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
+  emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
+  emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
   DONE;
 })
 
 (define_split
-  [(set (match_operand:DF 0 "register_operand" "")
-        (match_operand:DF 1 "fp_zero_operand" ""))]
+  [(set (match_operand:V64 0 "register_operand" "")
+        (match_operand:V64 1 "fp_zero_operand" ""))]
   "reload_completed
    && ! TARGET_ARCH64
    && ((GET_CODE (operands[0]) == REG
           && REGNO (SUBREG_REG (operands[0])) < 32))"
   [(clobber (const_int 0))]
 {
+  enum machine_mode half_mode;
   rtx set_dest = operands[0];
   rtx dest1, dest2;
 
-  dest1 = gen_highpart (SFmode, set_dest);
-  dest2 = gen_lowpart (SFmode, set_dest);
-  emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
-  emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
+  /* We can be expanded for DFmode or integral vector modes.  */
+  if (<V64:MODE>mode == DFmode)
+    half_mode = SFmode;
+  else
+    half_mode = SImode;
+
+  dest1 = gen_highpart (half_mode, set_dest);
+  dest2 = gen_lowpart (half_mode, set_dest);
+  emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
+  emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
   DONE;
 })
 
index 6f3d8f3e41b02e4b6aa2528103fe7febedb7d92c..adf9fe5d1951d86cb9d235f356cd5c3ecd234770 100644 (file)
@@ -2367,7 +2367,10 @@ Memory address aligned to an 8-byte boundary
 Even register
 
 @item W
-Memory address for @samp{e} constraint registers.
+Memory address for @samp{e} constraint registers
+
+@item Y
+Vector zero
 
 @end table