aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames A. Morrison <phython@gcc.gnu.org>2004-11-09 17:06:03 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2004-11-09 17:06:03 +0000
commitc75d6010b052d367dbd4b53c7615e09cf4f1bf5a (patch)
tree674046a0364c024f7b74eb9076fb8b241aec8ad0
parent26a8930190b8a1e9f7afb866870e85ec48c7b9be (diff)
downloadgcc-c75d6010b052d367dbd4b53c7615e09cf4f1bf5a.zip
gcc-c75d6010b052d367dbd4b53c7615e09cf4f1bf5a.tar.gz
gcc-c75d6010b052d367dbd4b53c7615e09cf4f1bf5a.tar.bz2
re PR target/18230 (SPARC VIS instructions are not generated by GCC)
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
-rw-r--r--gcc/ChangeLog26
-rw-r--r--gcc/config/sparc/sparc-modes.def6
-rw-r--r--gcc/config/sparc/sparc.c33
-rw-r--r--gcc/config/sparc/sparc.h6
-rw-r--r--gcc/config/sparc/sparc.md221
-rw-r--r--gcc/doc/md.texi5
6 files changed, 202 insertions, 95 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1816d81..5ce802b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/sparc/sparc-modes.def b/gcc/config/sparc/sparc-modes.def
index ea2a99d..bf85aed 100644
--- a/gcc/config/sparc/sparc-modes.def
+++ b/gcc/config/sparc/sparc-modes.def
@@ -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 */
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 5c5b326..0f34884 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -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);
}
+/* 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;
+}
+
/* 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;
}
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index d1b93ec..37f1905 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -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
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 1000fbb..0118a3c 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -2207,6 +2207,10 @@
[(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"))]
@@ -2627,12 +2631,12 @@
[(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
@@ -2718,6 +2722,8 @@
}
[(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")
@@ -2756,27 +2762,29 @@
[(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]),
@@ -2786,14 +2794,14 @@
/* 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]);
}
}
@@ -2802,12 +2810,12 @@
{
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));
@@ -2818,27 +2826,28 @@
;
})
-(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;
@@ -2849,14 +2858,14 @@
/* 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]);
}
}
@@ -2865,12 +2874,12 @@
{
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));
@@ -2969,14 +2978,14 @@
;; 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
@@ -3018,14 +3027,14 @@
;; 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
@@ -3053,6 +3062,7 @@
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" ""))]
@@ -3112,8 +3122,8 @@
;; 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
@@ -3128,30 +3138,37 @@
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)
@@ -3159,29 +3176,34 @@
&& 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)
@@ -3189,19 +3211,26 @@
&& 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
@@ -3209,19 +3238,26 @@
&& 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
@@ -3231,13 +3267,20 @@
&& 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;
})
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 6f3d8f3..adf9fe5 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -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