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
This commit is contained in:
parent
e44ecbfd9f
commit
c5e74d9d4e
9 changed files with 204 additions and 3 deletions
|
@ -1,3 +1,24 @@
|
|||
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>
|
||||
|
||||
* config/aarch64/aarch64-cores.def (qdf24xx): Use qdf24xx tuning.
|
||||
|
|
|
@ -200,6 +200,11 @@
|
|||
(and (match_code "const_int")
|
||||
(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
|
||||
(define_predicate "const_0_to_15_operand"
|
||||
(and (match_code "const_int")
|
||||
|
|
|
@ -6916,6 +6916,30 @@ rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
|
|||
case V4SFmode:
|
||||
emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt)));
|
||||
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[];
|
|||
#define TARGET_VADDUQM (TARGET_P8_VECTOR && TARGET_POWERPC64)
|
||||
#define TARGET_DIRECT_MOVE_128 (TARGET_P9_VECTOR && TARGET_DIRECT_MOVE \
|
||||
&& 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
|
||||
in power7, so conditionalize them on p8 features. TImode syncs need quad
|
||||
|
|
|
@ -5696,11 +5696,13 @@
|
|||
|
||||
; An UNSPEC is used so we don't have to support SImode in FP registers.
|
||||
(define_insn "stfiwx"
|
||||
[(set (match_operand:SI 0 "memory_operand" "=Z")
|
||||
(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
|
||||
[(set (match_operand:SI 0 "memory_operand" "=Z,Z")
|
||||
(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wv")]
|
||||
UNSPEC_STFIWX))]
|
||||
"TARGET_PPC_GFXOPT"
|
||||
"stfiwx %1,%y0"
|
||||
"@
|
||||
stfiwx %1,%y0
|
||||
stxsiwx %x1,%y0"
|
||||
[(set_attr "type" "fpstore")])
|
||||
|
||||
;; If we don't have a direct conversion to single precision, don't enable this
|
||||
|
|
|
@ -263,6 +263,21 @@
|
|||
(define_mode_iterator VSINT_84 [V4SI V2DI DI])
|
||||
(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
|
||||
(define_c_enum "unspec"
|
||||
[UNSPEC_VSX_CONCAT
|
||||
|
@ -2322,6 +2337,78 @@
|
|||
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
|
||||
(define_expand "vsx_mergel_<mode>"
|
||||
[(use (match_operand:VSX_D 0 "vsx_register_operand" ""))
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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>
|
||||
|
||||
PR fortran/71686
|
||||
|
|
26
gcc/testsuite/gcc.target/powerpc/p9-extract-1.c
Normal file
26
gcc/testsuite/gcc.target/powerpc/p9-extract-1.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* { 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" } } */
|
27
gcc/testsuite/gcc.target/powerpc/p9-extract-2.c
Normal file
27
gcc/testsuite/gcc.target/powerpc/p9-extract-2.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* { 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" } } */
|
Loading…
Add table
Reference in a new issue