mirror of git://gcc.gnu.org/git/gcc.git
rs6000-protos.h (rs6000_split_vec_extract_var): New declaration.
[gcc] 2016-07-28 Michael Meissner <meissner@linux.vnet.ibm.com> * config/rs6000/rs6000-protos.h (rs6000_split_vec_extract_var): New declaration. * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Add support for vec_extract of vector double or vector long having a variable element number on 64-bit ISA 2.07 systems or newer. * config/rs6000/rs6000.c (rs6000_expand_vector_extract): Likewise. (rs6000_split_vec_extract_var): New function to split a vec_extract built-in function with variable element number. (rtx_is_swappable_p): Variable vec_extracts and shifts are not swappable. * config/rs6000/vsx.md (UNSPEC_VSX_VSLO): New unspec. (UNSPEC_VSX_EXTRACT): Likewise. (vsx_extract_<mode>, VSX_D iterator): Fix constraints to allow direct move instructions to be generated on 64-bit ISA 2.07 systems and newer, and to take advantage of the ISA 3.0 MFVSRLD instruction. (vsx_vslo_<mode>): New insn to do VSLO on V2DFmode and V2DImode arguments for vec_extract variable element. (vsx_extract_<mode>_var, VSX_D iterator): New insn to support vec_extract with variable element on V2DFmode and V2DImode vectors. * config/rs6000/rs6000.h (TARGET_VEXTRACTUB): Remove -mupper-regs-df requirement, since it isn't needed. (TARGET_DIRECT_MOVE_64BIT): New macro to say whether we can do direct moves on 64-bit systems, which allows optimization of vec_extract on 64-bit ISA 2.07 systems and newer. [gcc/testsuite] 2016-07-28 Michael Meissner <meissner@linux.vnet.ibm.com> * gcc.target/powerpc/vec-extract-1.c: New test. From-SVN: r238838
This commit is contained in:
parent
1a2196e484
commit
e0d321856b
|
|
@ -1,3 +1,33 @@
|
||||||
|
2016-07-28 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
* config/rs6000/rs6000-protos.h (rs6000_split_vec_extract_var):
|
||||||
|
New declaration.
|
||||||
|
* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
|
||||||
|
Add support for vec_extract of vector double or vector long having
|
||||||
|
a variable element number on 64-bit ISA 2.07 systems or newer.
|
||||||
|
* config/rs6000/rs6000.c (rs6000_expand_vector_extract):
|
||||||
|
Likewise.
|
||||||
|
(rs6000_split_vec_extract_var): New function to split a
|
||||||
|
vec_extract built-in function with variable element number.
|
||||||
|
(rtx_is_swappable_p): Variable vec_extracts and shifts are not
|
||||||
|
swappable.
|
||||||
|
* config/rs6000/vsx.md (UNSPEC_VSX_VSLO): New unspec.
|
||||||
|
(UNSPEC_VSX_EXTRACT): Likewise.
|
||||||
|
(vsx_extract_<mode>, VSX_D iterator): Fix constraints to allow
|
||||||
|
direct move instructions to be generated on 64-bit ISA 2.07
|
||||||
|
systems and newer, and to take advantage of the ISA 3.0 MFVSRLD
|
||||||
|
instruction.
|
||||||
|
(vsx_vslo_<mode>): New insn to do VSLO on V2DFmode and V2DImode
|
||||||
|
arguments for vec_extract variable element.
|
||||||
|
(vsx_extract_<mode>_var, VSX_D iterator): New insn to support
|
||||||
|
vec_extract with variable element on V2DFmode and V2DImode
|
||||||
|
vectors.
|
||||||
|
* config/rs6000/rs6000.h (TARGET_VEXTRACTUB): Remove
|
||||||
|
-mupper-regs-df requirement, since it isn't needed.
|
||||||
|
(TARGET_DIRECT_MOVE_64BIT): New macro to say whether we can
|
||||||
|
do direct moves on 64-bit systems, which allows optimization of
|
||||||
|
vec_extract on 64-bit ISA 2.07 systems and newer.
|
||||||
|
|
||||||
2016-07-28 Kristina Martsenko <kristina.martsenko@arm.com>
|
2016-07-28 Kristina Martsenko <kristina.martsenko@arm.com>
|
||||||
2016-07-28 Wilco Dijkstra <wdijkstr@arm.com>
|
2016-07-28 Wilco Dijkstra <wdijkstr@arm.com>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5105,29 +5105,61 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
|
||||||
arg2);
|
arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we can use the VSX xxpermdi instruction, use that for extract. */
|
/* See if we can optimize vec_extracts with the current VSX instruction
|
||||||
|
set. */
|
||||||
mode = TYPE_MODE (arg1_type);
|
mode = TYPE_MODE (arg1_type);
|
||||||
if ((mode == V2DFmode || mode == V2DImode) && VECTOR_MEM_VSX_P (mode)
|
if (VECTOR_MEM_VSX_P (mode))
|
||||||
&& TREE_CODE (arg2) == INTEGER_CST
|
|
||||||
&& wi::ltu_p (arg2, 2))
|
|
||||||
{
|
{
|
||||||
tree call = NULL_TREE;
|
tree call = NULL_TREE;
|
||||||
|
int nunits = GET_MODE_NUNITS (mode);
|
||||||
|
|
||||||
if (mode == V2DFmode)
|
/* If the second argument is an integer constant, if the value is in
|
||||||
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF];
|
the expected range, generate the built-in code if we can. We need
|
||||||
else if (mode == V2DImode)
|
64-bit and direct move to extract the small integer vectors. */
|
||||||
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DI];
|
if (TREE_CODE (arg2) == INTEGER_CST && wi::ltu_p (arg2, nunits))
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case V1TImode:
|
||||||
|
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V1TI];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case V2DFmode:
|
||||||
|
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case V2DImode:
|
||||||
|
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DI];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the second argument is variable, we can optimize it if we are
|
||||||
|
generating 64-bit code on a machine with direct move. */
|
||||||
|
else if (TREE_CODE (arg2) != INTEGER_CST && TARGET_DIRECT_MOVE_64BIT)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case V2DFmode:
|
||||||
|
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case V2DImode:
|
||||||
|
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DI];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (call)
|
if (call)
|
||||||
return build_call_expr (call, 2, arg1, arg2);
|
return build_call_expr (call, 2, arg1, arg2);
|
||||||
}
|
}
|
||||||
else if (mode == V1TImode && VECTOR_MEM_VSX_P (mode)
|
|
||||||
&& TREE_CODE (arg2) == INTEGER_CST
|
|
||||||
&& wi::eq_p (arg2, 0))
|
|
||||||
{
|
|
||||||
tree call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V1TI];
|
|
||||||
return build_call_expr (call, 2, arg1, arg2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2). */
|
/* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2). */
|
||||||
arg1_inner_type = TREE_TYPE (arg1_type);
|
arg1_inner_type = TREE_TYPE (arg1_type);
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ extern void rs6000_expand_vector_init (rtx, rtx);
|
||||||
extern void paired_expand_vector_init (rtx, rtx);
|
extern void paired_expand_vector_init (rtx, rtx);
|
||||||
extern void rs6000_expand_vector_set (rtx, rtx, int);
|
extern void rs6000_expand_vector_set (rtx, rtx, int);
|
||||||
extern void rs6000_expand_vector_extract (rtx, rtx, rtx);
|
extern void rs6000_expand_vector_extract (rtx, rtx, rtx);
|
||||||
|
extern void rs6000_split_vec_extract_var (rtx, rtx, rtx, rtx, rtx);
|
||||||
extern bool altivec_expand_vec_perm_const (rtx op[4]);
|
extern bool altivec_expand_vec_perm_const (rtx op[4]);
|
||||||
extern void altivec_expand_vec_perm_le (rtx op[4]);
|
extern void altivec_expand_vec_perm_le (rtx op[4]);
|
||||||
extern bool rs6000_expand_vec_perm_const (rtx op[4]);
|
extern bool rs6000_expand_vec_perm_const (rtx op[4]);
|
||||||
|
|
|
||||||
|
|
@ -6959,8 +6959,31 @@ rs6000_expand_vector_extract (rtx target, rtx vec, rtx elt)
|
||||||
emit_insn (gen_vsx_extract_v4si (target, vec, elt));
|
emit_insn (gen_vsx_extract_v4si (target, vec, elt));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
|
else if (VECTOR_MEM_VSX_P (mode) && !CONST_INT_P (elt)
|
||||||
|
&& TARGET_DIRECT_MOVE_64BIT)
|
||||||
|
{
|
||||||
|
if (GET_MODE (elt) != DImode)
|
||||||
|
{
|
||||||
|
rtx tmp = gen_reg_rtx (DImode);
|
||||||
|
convert_move (tmp, elt, 0);
|
||||||
|
elt = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case V2DFmode:
|
||||||
|
emit_insn (gen_vsx_extract_v2df_var (target, vec, elt));
|
||||||
|
return;
|
||||||
|
|
||||||
|
case V2DImode:
|
||||||
|
emit_insn (gen_vsx_extract_v2di_var (target, vec, elt));
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6978,6 +7001,99 @@ rs6000_expand_vector_extract (rtx target, rtx vec, rtx elt)
|
||||||
emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
|
emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Split a variable vec_extract operation into the component instructions. */
|
||||||
|
|
||||||
|
void
|
||||||
|
rs6000_split_vec_extract_var (rtx dest, rtx src, rtx element, rtx tmp_gpr,
|
||||||
|
rtx tmp_altivec)
|
||||||
|
{
|
||||||
|
machine_mode mode = GET_MODE (src);
|
||||||
|
machine_mode scalar_mode = GET_MODE (dest);
|
||||||
|
unsigned scalar_size = GET_MODE_SIZE (scalar_mode);
|
||||||
|
int byte_shift = exact_log2 (scalar_size);
|
||||||
|
|
||||||
|
gcc_assert (byte_shift >= 0);
|
||||||
|
|
||||||
|
if (REG_P (src) || SUBREG_P (src))
|
||||||
|
{
|
||||||
|
int bit_shift = byte_shift + 3;
|
||||||
|
rtx element2;
|
||||||
|
|
||||||
|
gcc_assert (REG_P (tmp_gpr) && REG_P (tmp_altivec));
|
||||||
|
|
||||||
|
/* For little endian, adjust element ordering. For V2DI/V2DF, we can use
|
||||||
|
an XOR, otherwise we need to subtract. The shift amount is so VSLO
|
||||||
|
will shift the element into the upper position (adding 3 to convert a
|
||||||
|
byte shift into a bit shift). */
|
||||||
|
if (scalar_size == 8)
|
||||||
|
{
|
||||||
|
if (!VECTOR_ELT_ORDER_BIG)
|
||||||
|
{
|
||||||
|
emit_insn (gen_xordi3 (tmp_gpr, element, const1_rtx));
|
||||||
|
element2 = tmp_gpr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
element2 = element;
|
||||||
|
|
||||||
|
/* Generate RLDIC directly to shift left 6 bits and retrieve 1
|
||||||
|
bit. */
|
||||||
|
emit_insn (gen_rtx_SET (tmp_gpr,
|
||||||
|
gen_rtx_AND (DImode,
|
||||||
|
gen_rtx_ASHIFT (DImode,
|
||||||
|
element2,
|
||||||
|
GEN_INT (6)),
|
||||||
|
GEN_INT (64))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!VECTOR_ELT_ORDER_BIG)
|
||||||
|
{
|
||||||
|
rtx num_ele_m1 = GEN_INT (GET_MODE_NUNITS (mode) - 1);
|
||||||
|
|
||||||
|
emit_insn (gen_anddi3 (tmp_gpr, element, num_ele_m1));
|
||||||
|
emit_insn (gen_subdi3 (tmp_gpr, num_ele_m1, tmp_gpr));
|
||||||
|
element2 = tmp_gpr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
element2 = element;
|
||||||
|
|
||||||
|
emit_insn (gen_ashldi3 (tmp_gpr, element2, GEN_INT (bit_shift)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the value into the lower byte of the Altivec register where VSLO
|
||||||
|
expects it. */
|
||||||
|
if (TARGET_P9_VECTOR)
|
||||||
|
emit_insn (gen_vsx_splat_v2di (tmp_altivec, tmp_gpr));
|
||||||
|
else if (can_create_pseudo_p ())
|
||||||
|
emit_insn (gen_vsx_concat_v2di (tmp_altivec, tmp_gpr, tmp_gpr));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rtx tmp_di = gen_rtx_REG (DImode, REGNO (tmp_altivec));
|
||||||
|
emit_move_insn (tmp_di, tmp_gpr);
|
||||||
|
emit_insn (gen_vsx_concat_v2di (tmp_altivec, tmp_di, tmp_di));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the VSLO to get the value into the final location. */
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case V2DFmode:
|
||||||
|
emit_insn (gen_vsx_vslo_v2df (dest, src, tmp_altivec));
|
||||||
|
return;
|
||||||
|
|
||||||
|
case V2DImode:
|
||||||
|
emit_insn (gen_vsx_vslo_v2di (dest, src, tmp_altivec));
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
gcc_unreachable ();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gcc_unreachable ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Return TRUE if OP is an invalid SUBREG operation on the e500. */
|
/* Return TRUE if OP is an invalid SUBREG operation on the e500. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -38640,6 +38756,7 @@ rtx_is_swappable_p (rtx op, unsigned int *special)
|
||||||
case UNSPEC_VSX_CVDPSPN:
|
case UNSPEC_VSX_CVDPSPN:
|
||||||
case UNSPEC_VSX_CVSPDP:
|
case UNSPEC_VSX_CVSPDP:
|
||||||
case UNSPEC_VSX_CVSPDPN:
|
case UNSPEC_VSX_CVSPDPN:
|
||||||
|
case UNSPEC_VSX_EXTRACT:
|
||||||
return 0;
|
return 0;
|
||||||
case UNSPEC_VSPLT_DIRECT:
|
case UNSPEC_VSPLT_DIRECT:
|
||||||
*special = SH_SPLAT;
|
*special = SH_SPLAT;
|
||||||
|
|
|
||||||
|
|
@ -602,7 +602,6 @@ extern int rs6000_vector_align[];
|
||||||
#define TARGET_DIRECT_MOVE_128 (TARGET_P9_VECTOR && TARGET_DIRECT_MOVE \
|
#define TARGET_DIRECT_MOVE_128 (TARGET_P9_VECTOR && TARGET_DIRECT_MOVE \
|
||||||
&& TARGET_POWERPC64)
|
&& TARGET_POWERPC64)
|
||||||
#define TARGET_VEXTRACTUB (TARGET_P9_VECTOR && TARGET_DIRECT_MOVE \
|
#define TARGET_VEXTRACTUB (TARGET_P9_VECTOR && TARGET_DIRECT_MOVE \
|
||||||
&& TARGET_UPPER_REGS_DF \
|
|
||||||
&& TARGET_UPPER_REGS_DI && TARGET_POWERPC64)
|
&& TARGET_UPPER_REGS_DI && TARGET_POWERPC64)
|
||||||
|
|
||||||
/* Byte/char syncs were added as phased in for ISA 2.06B, but are not present
|
/* Byte/char syncs were added as phased in for ISA 2.06B, but are not present
|
||||||
|
|
@ -761,6 +760,14 @@ extern int rs6000_vector_align[];
|
||||||
&& TARGET_SINGLE_FLOAT \
|
&& TARGET_SINGLE_FLOAT \
|
||||||
&& TARGET_DOUBLE_FLOAT)
|
&& TARGET_DOUBLE_FLOAT)
|
||||||
|
|
||||||
|
/* Macro to say whether we can do optimization where we need to do parts of the
|
||||||
|
calculation in 64-bit GPRs and then is transfered to the vector
|
||||||
|
registers. */
|
||||||
|
#define TARGET_DIRECT_MOVE_64BIT (TARGET_DIRECT_MOVE \
|
||||||
|
&& TARGET_P8_VECTOR \
|
||||||
|
&& TARGET_POWERPC64 \
|
||||||
|
&& TARGET_UPPER_REGS_DI)
|
||||||
|
|
||||||
/* Whether the various reciprocal divide/square root estimate instructions
|
/* Whether the various reciprocal divide/square root estimate instructions
|
||||||
exist, and whether we should automatically generate code for the instruction
|
exist, and whether we should automatically generate code for the instruction
|
||||||
by default. */
|
by default. */
|
||||||
|
|
|
||||||
|
|
@ -309,6 +309,8 @@
|
||||||
UNSPEC_VSX_XVCVDPUXDS
|
UNSPEC_VSX_XVCVDPUXDS
|
||||||
UNSPEC_VSX_SIGN_EXTEND
|
UNSPEC_VSX_SIGN_EXTEND
|
||||||
UNSPEC_P9_MEMORY
|
UNSPEC_P9_MEMORY
|
||||||
|
UNSPEC_VSX_VSLO
|
||||||
|
UNSPEC_VSX_EXTRACT
|
||||||
])
|
])
|
||||||
|
|
||||||
;; VSX moves
|
;; VSX moves
|
||||||
|
|
@ -2118,16 +2120,13 @@
|
||||||
;; register was picked. Limit the scalar value to FPRs for now.
|
;; register was picked. Limit the scalar value to FPRs for now.
|
||||||
|
|
||||||
(define_insn "vsx_extract_<mode>"
|
(define_insn "vsx_extract_<mode>"
|
||||||
[(set (match_operand:<VS_scalar> 0 "gpc_reg_operand"
|
[(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=d, d, wr, wr")
|
||||||
"=d, wm, wo, d")
|
|
||||||
|
|
||||||
(vec_select:<VS_scalar>
|
(vec_select:<VS_scalar>
|
||||||
(match_operand:VSX_D 1 "gpc_reg_operand"
|
(match_operand:VSX_D 1 "gpc_reg_operand" "<VSa>, <VSa>, wm, wo")
|
||||||
"<VSa>, <VSa>, <VSa>, <VSa>")
|
|
||||||
|
|
||||||
(parallel
|
(parallel
|
||||||
[(match_operand:QI 2 "const_0_to_1_operand"
|
[(match_operand:QI 2 "const_0_to_1_operand" "wD, n, wD, n")])))]
|
||||||
"wD, wD, wL, n")])))]
|
|
||||||
"VECTOR_MEM_VSX_P (<MODE>mode)"
|
"VECTOR_MEM_VSX_P (<MODE>mode)"
|
||||||
{
|
{
|
||||||
int element = INTVAL (operands[2]);
|
int element = INTVAL (operands[2]);
|
||||||
|
|
@ -2205,6 +2204,34 @@
|
||||||
[(set_attr "type" "fpstore")
|
[(set_attr "type" "fpstore")
|
||||||
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
||||||
|
|
||||||
|
;; Variable V2DI/V2DF extract shift
|
||||||
|
(define_insn "vsx_vslo_<mode>"
|
||||||
|
[(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=v")
|
||||||
|
(unspec:<VS_scalar> [(match_operand:VSX_D 1 "gpc_reg_operand" "v")
|
||||||
|
(match_operand:V2DI 2 "gpc_reg_operand" "v")]
|
||||||
|
UNSPEC_VSX_VSLO))]
|
||||||
|
"VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
|
||||||
|
"vslo %0,%1,%2"
|
||||||
|
[(set_attr "type" "vecperm")])
|
||||||
|
|
||||||
|
;; Variable V2DI/V2DF extract
|
||||||
|
(define_insn_and_split "vsx_extract_<mode>_var"
|
||||||
|
[(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=v")
|
||||||
|
(unspec:<VS_scalar> [(match_operand:VSX_D 1 "input_operand" "v")
|
||||||
|
(match_operand:DI 2 "gpc_reg_operand" "r")]
|
||||||
|
UNSPEC_VSX_EXTRACT))
|
||||||
|
(clobber (match_scratch:DI 3 "=r"))
|
||||||
|
(clobber (match_scratch:V2DI 4 "=&v"))]
|
||||||
|
"VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(const_int 0)]
|
||||||
|
{
|
||||||
|
rs6000_split_vec_extract_var (operands[0], operands[1], operands[2],
|
||||||
|
operands[3], operands[4]);
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
;; Extract a SF element from V4SF
|
;; Extract a SF element from V4SF
|
||||||
(define_insn_and_split "vsx_extract_v4sf"
|
(define_insn_and_split "vsx_extract_v4sf"
|
||||||
[(set (match_operand:SF 0 "vsx_register_operand" "=f,f")
|
[(set (match_operand:SF 0 "vsx_register_operand" "=f,f")
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
2016-07-28 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
* gcc.target/powerpc/vec-extract-1.c: New test.
|
||||||
|
|
||||||
2016-07-28 Steven G. Kargl <kargl@gcc.gnu.org>
|
2016-07-28 Steven G. Kargl <kargl@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/71799
|
PR fortran/71799
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
|
||||||
|
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||||
|
/* { dg-require-effective-target powerpc_p8vector_ok } */
|
||||||
|
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
|
||||||
|
/* { dg-options "-mcpu=power8 -O2 -mupper-regs-df -mupper-regs-di" } */
|
||||||
|
|
||||||
|
#include <altivec.h>
|
||||||
|
|
||||||
|
double
|
||||||
|
add_double (vector double a, int n)
|
||||||
|
{
|
||||||
|
return vec_extract (a, n) + 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
add_long (vector long a, int n)
|
||||||
|
{
|
||||||
|
return vec_extract (a, n) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "vslo" } } */
|
||||||
|
/* { dg-final { scan-assembler "mtvsrd" } } */
|
||||||
|
/* { dg-final { scan-assembler "mfvsrd" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "stxvd2x" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "stxvx" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "stxv" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "ldx" } } */
|
||||||
Loading…
Reference in New Issue