})
(define_insn_and_split "*movoo"
- [(set (match_operand:OO 0 "nonimmediate_operand" "=wa,ZwO,wa")
- (match_operand:OO 1 "input_operand" "ZwO,wa,wa"))]
+ [(set (match_operand:OO 0 "nonimmediate_operand" "=wa,wa,ZwO,QwO,wa")
+ (match_operand:OO 1 "input_operand" "ZwO,QwO,wa,wa,wa"))]
"TARGET_MMA
&& (gpc_reg_operand (operands[0], OOmode)
|| gpc_reg_operand (operands[1], OOmode))"
"@
lxvp%X1 %x0,%1
+ #
stxvp%X0 %x1,%0
+ #
#"
"&& reload_completed
- && (!MEM_P (operands[0]) && !MEM_P (operands[1]))"
+ && ((MEM_P (operands[0]) && !TARGET_STXVP)
+ || (MEM_P (operands[1]) && !TARGET_LXVP)
+ || (!MEM_P (operands[0]) && !MEM_P (operands[1])))"
[(const_int 0)]
{
rs6000_split_multireg_move (operands[0], operands[1]);
DONE;
}
- [(set_attr "type" "vecload,vecstore,veclogical")
+ [(set_attr "type" "vecload,vecload,vecstore,vecstore,veclogical")
(set_attr "size" "256")
- (set_attr "length" "*,*,8")])
+ (set_attr "length" "*,8,*,8,8")
+ (set_attr "isa" "lxvp,*,stxvp,*,*")])
\f
;; Vector quad support. XOmode can only live in FPRs.
if (TARGET_DIRECT_MOVE_128)
fprintf (stderr, DEBUG_FMT_D, "VSX easy 64-bit mfvsrld element",
(int)VECTOR_ELEMENT_MFVSRLD_64BIT);
+
+ if (TARGET_MMA)
+ fprintf (stderr, DEBUG_FMT_ID "%s, %s\n",
+ "vector_pair",
+ TARGET_LXVP ? "lxvp" : "no-lxvp",
+ TARGET_STXVP ? "stxvp" : "no-stxvp");
}
\f
/* Vector pairs can do both indexed and offset loads if the
instructions are enabled, otherwise they can only do offset loads
since it will be broken into two vector moves. Vector quads can
- only do offset loads. */
+ only do offset loads. If the user restricted generation of either
+ of the LXVP or STXVP instructions, do not allow indexed mode so
+ that we can split the load/store. */
else if ((addr_mask != 0) && TARGET_MMA
&& (m2 == OOmode || m2 == XOmode))
{
if (rc == RELOAD_REG_FPR || rc == RELOAD_REG_VMX)
{
addr_mask |= RELOAD_REG_QUAD_OFFSET;
- if (m2 == OOmode)
+ if (m2 == OOmode && TARGET_LXVP && TARGET_STXVP)
addr_mask |= RELOAD_REG_INDEXED;
}
}
rs6000_isa_flags &= ~OPTION_MASK_MMA;
}
+ /* Warn if -mlxvp or -mstxvp are used and MMA is not set. */
+ if (!TARGET_MMA)
+ {
+ if (TARGET_LXVP && OPTION_SET_P(TARGET_LXVP))
+ warning (0, "%qs should not be used unless you use %qs",
+ "-mlxvp", "-mmma");
+
+ if (TARGET_STXVP && OPTION_SET_P(TARGET_STXVP))
+ warning (0, "%qs should not be used unless you use %qs",
+ "-mstxvp", "-mmma");
+ }
+
/* Enable power10 fusion if we are tuning for power10, even if we aren't
generating power10 instructions. */
if (!(rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION))
{ "speculate-indirect-jumps",
offsetof (struct gcc_options, x_rs6000_speculate_indirect_jumps),
offsetof (struct cl_target_option, x_rs6000_speculate_indirect_jumps), },
+ { "lxvp",
+ offsetof (struct gcc_options, x_TARGET_LXVP),
+ offsetof (struct cl_target_option, x_TARGET_LXVP), },
+ { "stxvp",
+ offsetof (struct gcc_options, x_TARGET_STXVP),
+ offsetof (struct cl_target_option, x_TARGET_STXVP), },
};
/* Inner function to handle attribute((target("..."))) and #pragma GCC target
UNSPEC_TOCREL
UNSPEC_MACHOPIC_OFFSET
UNSPEC_BPERM
- UNSPEC_COPYSIGN
UNSPEC_PARITY
UNSPEC_CMPB
UNSPEC_FCTIW
(const (symbol_ref "(enum attr_cpu) rs6000_tune")))
;; The ISA we implement.
-(define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10"
+(define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10,lxvp,stxvp"
(const_string "any"))
;; Is this alternative enabled for the current CPU/ISA/etc.?
(and (eq_attr "isa" "p10")
(match_test "TARGET_POWER10"))
(const_int 1)
+
+ (and (eq_attr "isa" "lxvp")
+ (match_test "TARGET_LXVP"))
+ (const_int 1)
+
+ (and (eq_attr "isa" "stxvp")
+ (match_test "TARGET_STXVP"))
+ (const_int 1)
] (const_int 0)))
;; If this instruction is microcoded on the CELL processor
;; compiler from optimizing -0.0
(define_insn "copysign<mode>3_fcpsgn"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
- (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
- (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")]
- UNSPEC_COPYSIGN))]
+ (copysign:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
+ (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
"TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
"@
fcpsgn %0,%2,%1
(define_insn "copysign<mode>3_hard"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
- (unspec:IEEE128
- [(match_operand:IEEE128 1 "altivec_register_operand" "v")
- (match_operand:IEEE128 2 "altivec_register_operand" "v")]
- UNSPEC_COPYSIGN))]
+ (copysign:IEEE128
+ (match_operand:IEEE128 1 "altivec_register_operand" "v")
+ (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xscpsgnqp %0,%2,%1"
[(set_attr "type" "vecmove")
(define_insn "copysign<mode>3_soft"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
- (unspec:IEEE128
- [(match_operand:IEEE128 1 "altivec_register_operand" "v")
- (match_operand:IEEE128 2 "altivec_register_operand" "v")]
- UNSPEC_COPYSIGN))
+ (copysign:IEEE128
+ (match_operand:IEEE128 1 "altivec_register_operand" "v")
+ (match_operand:IEEE128 2 "altivec_register_operand" "v")))
(clobber (match_scratch:IEEE128 3 "=&v"))]
"!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
"xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
Target Mask(MMA) Var(rs6000_isa_flags)
Generate (do not generate) MMA instructions.
+mlxvp
+Target Undocumented Var(TARGET_LXVP) Init(1) Save
+Generate (do not generate) the LXVP instruction if -mmma is enabled.
+
+mstxvp
+Target Undocumented Var(TARGET_STXVP) Init(1) Save
+Generate (do not generate) the STXVP instruction if -mmma is enabled.
+
mrelative-jumptables
Target Undocumented Var(rs6000_relative_jumptables) Init(1) Save
(define_expand "vector_copysign<mode>3"
[(set (match_operand:VEC_F 0 "vfloat_operand")
- (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand")
- (match_operand:VEC_F 2 "vfloat_operand")] UNSPEC_COPYSIGN))]
+ (copysign:VEC_F (match_operand:VEC_F 1 "vfloat_operand")
+ (match_operand:VEC_F 2 "vfloat_operand")))]
"VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
{
if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
;; Copy sign
(define_insn "vsx_copysign<mode>3"
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=wa")
- (unspec:VSX_F
- [(match_operand:VSX_F 1 "vsx_register_operand" "wa")
- (match_operand:VSX_F 2 "vsx_register_operand" "wa")]
- UNSPEC_COPYSIGN))]
+ (copysign:VSX_F
+ (match_operand:VSX_F 1 "vsx_register_operand" "wa")
+ (match_operand:VSX_F 2 "vsx_register_operand" "wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"xvcpsgn<sd>p %x0,%x2,%x1"
[(set_attr "type" "<VStype_simple>")])
--- /dev/null
+/* { dg-do compile } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+#include <stddef.h>
+
+/* Test whether we can control lxvp and stxvp. */
+
+#pragma GCC target ("no-lxvp,no-stxvp")
+
+void
+no_vector_pair (__vector_pair *dest,
+ __vector_pair *src,
+ size_t n,
+ size_t m)
+{
+ dest[n] = src[m]; /* 2 lxv + 2 stxv. */
+}
+
+#pragma GCC target ("lxvp,no-stxvp")
+
+void
+vector_pair_load (__vector_pair *dest,
+ __vector_pair *src,
+ size_t n,
+ size_t m)
+{
+ dest[n] = src[m]; /* 1 lxvpx + 2 stxv. */
+}
+
+#pragma GCC target ("no-lxvp,stxvp")
+
+void
+vector_pair_store (__vector_pair *dest,
+ __vector_pair *src,
+ size_t n,
+ size_t m)
+{
+ dest[n] = src[m]; /* 2 lxv + 1 stxvpx. */
+}
+
+#pragma GCC target ("lxvp,stxvp")
+
+void
+vector_pair_both (__vector_pair *dest,
+ __vector_pair *src,
+ size_t n,
+ size_t m)
+{
+ dest[n] = src[m]; /* 1 lxvpx + 1 stxvpx. */
+}
+
+/* { dg-final { scan-assembler-times {\mlxv\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mlxvpx\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mstxv\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mstxvpx\M} 2 } } */