Commit c5e74d9d by Michael Meissner Committed by Michael Meissner

predicates.md (const_0_to_7_operand): New predicate, recognize 0..7.

[gcc]
2016-06-29  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/predicates.md (const_0_to_7_operand): New
	predicate, recognize 0..7.
	* config/rs6000/rs6000.c (rs6000_expand_vector_extract): Add
	support for doing extracts from V16QImode, V8HImode, V4SImode
	under ISA 3.0.
	* config/rs6000/vsx.md (VSX_EXTRACT_I): Mode iterator for ISA 3.0
	vector extract support.
	(VSX_EXTRACT_PREDICATE): Mode attribute to validate element number
	for ISA 3.0 vector extract.
	(VSX_EX): Constraints to use for ISA 3.0 vector extract.
	(vsx_extract_<mode>, VSX_EXTRACT_I): Add support for doing
	extracts of a constant element number from small integer vectors
	on 64-bit ISA 3.0 systems.
	(vsx_extract_<mode>_di): Likewise.
	* config/rs6000/rs6000.h (TARGET_VEXTRACTUB): New target macro to
	say when we can do ISA 3.0 vector extracts.
	* config/rs6000/rs6000.md (stfiwx): Allow DImode in Altivec
	registers, using the stxsiwx instruction.

[gcc/testsuite]
2016-06-29  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/p9-extract-1.c: New file to test ISA 3.0
	vector extract instructions.
	* gcc.target/powerpc/p9-extract-2.c: Likewise.

From-SVN: r237864
parent e44ecbfd
2016-06-29 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/predicates.md (const_0_to_7_operand): New
predicate, recognize 0..7.
* config/rs6000/rs6000.c (rs6000_expand_vector_extract): Add
support for doing extracts from V16QImode, V8HImode, V4SImode
under ISA 3.0.
* config/rs6000/vsx.md (VSX_EXTRACT_I): Mode iterator for ISA 3.0
vector extract support.
(VSX_EXTRACT_PREDICATE): Mode attribute to validate element number
for ISA 3.0 vector extract.
(VSX_EX): Constraints to use for ISA 3.0 vector extract.
(vsx_extract_<mode>, VSX_EXTRACT_I): Add support for doing
extracts of a constant element number from small integer vectors
on 64-bit ISA 3.0 systems.
(vsx_extract_<mode>_di): Likewise.
* config/rs6000/rs6000.h (TARGET_VEXTRACTUB): New target macro to
say when we can do ISA 3.0 vector extracts.
* config/rs6000/rs6000.md (stfiwx): Allow DImode in Altivec
registers, using the stxsiwx instruction.
2016-06-29 Jim Wilson <jim.wilson@linaro.org> 2016-06-29 Jim Wilson <jim.wilson@linaro.org>
* config/aarch64/aarch64-cores.def (qdf24xx): Use qdf24xx tuning. * config/aarch64/aarch64-cores.def (qdf24xx): Use qdf24xx tuning.
......
...@@ -200,6 +200,11 @@ ...@@ -200,6 +200,11 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 2, 3)"))) (match_test "IN_RANGE (INTVAL (op), 2, 3)")))
;; Match op = 0..7.
(define_predicate "const_0_to_7_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 7)")))
;; Match op = 0..15 ;; Match op = 0..15
(define_predicate "const_0_to_15_operand" (define_predicate "const_0_to_15_operand"
(and (match_code "const_int") (and (match_code "const_int")
......
...@@ -6916,6 +6916,30 @@ rs6000_expand_vector_extract (rtx target, rtx vec, int elt) ...@@ -6916,6 +6916,30 @@ rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
case V4SFmode: case V4SFmode:
emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt))); emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt)));
return; return;
case V16QImode:
if (TARGET_VEXTRACTUB)
{
emit_insn (gen_vsx_extract_v16qi (target, vec, GEN_INT (elt)));
return;
}
else
break;
case V8HImode:
if (TARGET_VEXTRACTUB)
{
emit_insn (gen_vsx_extract_v8hi (target, vec, GEN_INT (elt)));
return;
}
else
break;
case V4SImode:
if (TARGET_VEXTRACTUB)
{
emit_insn (gen_vsx_extract_v4si (target, vec, GEN_INT (elt)));
return;
}
else
break;
} }
} }
...@@ -599,6 +599,9 @@ extern int rs6000_vector_align[]; ...@@ -599,6 +599,9 @@ extern int rs6000_vector_align[];
#define TARGET_VADDUQM (TARGET_P8_VECTOR && TARGET_POWERPC64) #define TARGET_VADDUQM (TARGET_P8_VECTOR && TARGET_POWERPC64)
#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 \
&& TARGET_UPPER_REGS_DF \
&& 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
in power7, so conditionalize them on p8 features. TImode syncs need quad in power7, so conditionalize them on p8 features. TImode syncs need quad
......
...@@ -5696,11 +5696,13 @@ ...@@ -5696,11 +5696,13 @@
; An UNSPEC is used so we don't have to support SImode in FP registers. ; An UNSPEC is used so we don't have to support SImode in FP registers.
(define_insn "stfiwx" (define_insn "stfiwx"
[(set (match_operand:SI 0 "memory_operand" "=Z") [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")] (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wv")]
UNSPEC_STFIWX))] UNSPEC_STFIWX))]
"TARGET_PPC_GFXOPT" "TARGET_PPC_GFXOPT"
"stfiwx %1,%y0" "@
stfiwx %1,%y0
stxsiwx %x1,%y0"
[(set_attr "type" "fpstore")]) [(set_attr "type" "fpstore")])
;; If we don't have a direct conversion to single precision, don't enable this ;; If we don't have a direct conversion to single precision, don't enable this
......
...@@ -263,6 +263,21 @@ ...@@ -263,6 +263,21 @@
(define_mode_iterator VSINT_84 [V4SI V2DI DI]) (define_mode_iterator VSINT_84 [V4SI V2DI DI])
(define_mode_iterator VSINT_842 [V8HI V4SI V2DI]) (define_mode_iterator VSINT_842 [V8HI V4SI V2DI])
;; Iterator for ISA 3.0 vector extract/insert of integer vectors
(define_mode_iterator VSX_EXTRACT_I [V16QI V8HI V4SI])
;; Mode attribute to give the correct predicate for ISA 3.0 vector extract and
;; insert to validate the operand number.
(define_mode_attr VSX_EXTRACT_PREDICATE [(V16QI "const_0_to_15_operand")
(V8HI "const_0_to_7_operand")
(V4SI "const_0_to_3_operand")])
;; Mode attribute to give the constraint for vector extract and insert
;; operations.
(define_mode_attr VSX_EX [(V16QI "v")
(V8HI "v")
(V4SI "wa")])
;; Constants for creating unspecs ;; Constants for creating unspecs
(define_c_enum "unspec" (define_c_enum "unspec"
[UNSPEC_VSX_CONCAT [UNSPEC_VSX_CONCAT
...@@ -2322,6 +2337,78 @@ ...@@ -2322,6 +2337,78 @@
FAIL; FAIL;
}) })
;; Extraction of a single element in a small integer vector. None of the small
;; types are currently allowed in a vector register, so we extract to a DImode
;; and either do a direct move or store.
(define_insn_and_split "vsx_extract_<mode>"
[(set (match_operand:<VS_scalar> 0 "nonimmediate_operand" "=r,Z")
(vec_select:<VS_scalar>
(match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand" "<VSX_EX>,<VSX_EX>")
(parallel [(match_operand:QI 2 "<VSX_EXTRACT_PREDICATE>" "n,n")])))
(clobber (match_scratch:DI 3 "=<VSX_EX>,<VSX_EX>"))]
"VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_VEXTRACTUB"
"#"
"&& (reload_completed || MEM_P (operands[0]))"
[(const_int 0)]
{
rtx dest = operands[0];
rtx src = operands[1];
rtx element = operands[2];
rtx di_tmp = operands[3];
if (GET_CODE (di_tmp) == SCRATCH)
di_tmp = gen_reg_rtx (DImode);
emit_insn (gen_vsx_extract_<mode>_di (di_tmp, src, element));
if (REG_P (dest))
emit_move_insn (gen_rtx_REG (DImode, REGNO (dest)), di_tmp);
else if (SUBREG_P (dest))
emit_move_insn (gen_rtx_REG (DImode, subreg_regno (dest)), di_tmp);
else if (MEM_P (operands[0]))
{
if (can_create_pseudo_p ())
dest = rs6000_address_for_fpconvert (dest);
if (<MODE>mode == V16QImode)
emit_insn (gen_p9_stxsibx (dest, di_tmp));
else if (<MODE>mode == V8HImode)
emit_insn (gen_p9_stxsihx (dest, di_tmp));
else if (<MODE>mode == V4SImode)
emit_insn (gen_stfiwx (dest, di_tmp));
else
gcc_unreachable ();
}
else
gcc_unreachable ();
DONE;
}
[(set_attr "type" "vecsimple,fpstore")])
(define_insn "vsx_extract_<mode>_di"
[(set (match_operand:DI 0 "gpc_reg_operand" "=<VSX_EX>")
(zero_extend:DI
(vec_select:<VS_scalar>
(match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand" "<VSX_EX>")
(parallel [(match_operand:QI 2 "<VSX_EXTRACT_PREDICATE>" "n")]))))]
"VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_VEXTRACTUB"
{
int element = INTVAL (operands[2]);
int unit_size = GET_MODE_UNIT_SIZE (<MODE>mode);
int offset = ((VECTOR_ELT_ORDER_BIG)
? unit_size * element
: unit_size * (GET_MODE_NUNITS (<MODE>mode) - 1 - element));
operands[2] = GEN_INT (offset);
if (unit_size == 4)
return "xxextractuw %x0,%x1,%2";
else
return "vextractu<wd> %0,%1,%2";
}
[(set_attr "type" "vecsimple")])
;; Expanders for builtins ;; Expanders for builtins
(define_expand "vsx_mergel_<mode>" (define_expand "vsx_mergel_<mode>"
[(use (match_operand:VSX_D 0 "vsx_register_operand" "")) [(use (match_operand:VSX_D 0 "vsx_register_operand" ""))
......
2016-06-29 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/p9-extract-1.c: New file to test ISA 3.0
vector extract instructions.
* gcc.target/powerpc/p9-extract-2.c: Likewise.
2016-06-29 Jerry DeLisle <jvdelisle@gcc.gnu.org> 2016-06-29 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/71686 PR fortran/71686
......
/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
/* { dg-require-effective-target powerpc_p9vector_ok } */
/* { dg-options "-mcpu=power9 -O2" } */
#include <altivec.h>
int extract_int_0 (vector int a) { return vec_extract (a, 0); }
int extract_int_3 (vector int a) { return vec_extract (a, 3); }
int extract_short_0 (vector short a) { return vec_extract (a, 0); }
int extract_short_3 (vector short a) { return vec_extract (a, 7); }
int extract_schar_0 (vector signed char a) { return vec_extract (a, 0); }
int extract_schar_3 (vector signed char a) { return vec_extract (a, 15); }
/* { dg-final { scan-assembler "vextractub" } } */
/* { dg-final { scan-assembler "vextractuh" } } */
/* { dg-final { scan-assembler "xxextractuw" } } */
/* { dg-final { scan-assembler "mfvsrd" } } */
/* { dg-final { scan-assembler-not "stxvd2x" } } */
/* { dg-final { scan-assembler-not "stxv" } } */
/* { dg-final { scan-assembler-not "lwa" } } */
/* { dg-final { scan-assembler-not "lwz" } } */
/* { dg-final { scan-assembler-not "lha" } } */
/* { dg-final { scan-assembler-not "lhz" } } */
/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
/* { dg-require-effective-target powerpc_p9vector_ok } */
/* { dg-options "-mcpu=power9 -O2" } */
#include <altivec.h>
void extract_int_0 (int *p, vector int a) { *p = vec_extract (a, 0); }
void extract_int_3 (int *p, vector int a) { *p = vec_extract (a, 3); }
void extract_short_0 (short *p, vector short a) { *p = vec_extract (a, 0); }
void extract_short_3 (short *p, vector short a) { *p = vec_extract (a, 7); }
void extract_schar_0 (signed char *p, vector signed char a) { *p = vec_extract (a, 0); }
void extract_schar_3 (signed char *p, vector signed char a) { *p = vec_extract (a, 15); }
/* { dg-final { scan-assembler "vextractub" } } */
/* { dg-final { scan-assembler "vextractuh" } } */
/* { dg-final { scan-assembler "xxextractuw" } } */
/* { dg-final { scan-assembler "stxsibx" } } */
/* { dg-final { scan-assembler "stxsihx" } } */
/* { dg-final { scan-assembler "stfiwx\|stxsiwx" } } */
/* { dg-final { scan-assembler-not "mfvsrd" } } */
/* { dg-final { scan-assembler-not "stxvd2x" } } */
/* { dg-final { scan-assembler-not "stxv" } } */
/* { dg-final { scan-assembler-not "lwa" } } */
/* { dg-final { scan-assembler-not "stw" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment