diff mbox series

RS6000 Add testlsbb (Test LSB by Byte) operations

Message ID 77e5059f82f39477a3b12f8b5784bb771dd367cf.camel@vnet.ibm.com
State New
Headers show
Series RS6000 Add testlsbb (Test LSB by Byte) operations | expand

Commit Message

will schmidt May 26, 2020, 4:12 p.m. UTC
Hi,

  Add support for new instructions to test LSB by Byte.

  Tested on powerpc64le-unknown-linux-gnu with no
  regressions.  (power7BE, power8LE, power8BE, power9LE).

[gcc]

2020-05-26  Will Schmidt  <will_schmidt@vnet.ibm.com>

    * config/rs6000/altivec.h (vec_test_lsbb_all_ones): New define.
    (vec_test_lsbb_all_zeros): New define.
    * config/rs6000/rs6000-builtin.def (BU_FUTURE_VSX_1): New built-in
    handling macro.  (XVTLSBB_ZEROS, XVTLSBB_ONES) New builtin defines.
    (xvtlsbb_zeros, xvtlsbb_ones) New builtin overloads.
    * config/rs6000/rs6000-call.c (FUTURE_BUILTIN_VEC_XVTLSBB_ZEROS,
    FUTURE_BUILTIN_VEC_XVTLSBB_ONES): New altivec_builtin_types entries.
    * config/rs6000/rs6000.md (UNSPEC_XVTLSBB):  New unspec.
    * config/rs6000/vsx.md (*xvtlsbb_internal): New instruction define.
    (xvtlsbbo, xvtlsbbz): New instruction expands.

[testsuite]

2020-05-26  Will Schmidt  <will_schmidt@vnet.ibm.com>

    * testsuite/gcc.target/powerpc/lsbb-runnable.c: New test.
    * testsuite/gcc.target/powerpc/lsbb.c: New test.

Comments

will schmidt June 17, 2020, 3:57 p.m. UTC | #1
On Tue, 2020-05-26 at 11:12 -0500, will schmidt wrote:
> Hi,
> 
>   Add support for new instructions to test LSB by Byte.
> 
>   Tested on powerpc64le-unknown-linux-gnu with no
>   regressions.  (power7BE, power8LE, power8BE, power9LE).
> 
> [gcc]
> 
> 2020-05-26  Will Schmidt  <will_schmidt@vnet.ibm.com>
> 
>     * config/rs6000/altivec.h (vec_test_lsbb_all_ones): New define.
>     (vec_test_lsbb_all_zeros): New define.
>     * config/rs6000/rs6000-builtin.def (BU_FUTURE_VSX_1): New built-in
>     handling macro.  (XVTLSBB_ZEROS, XVTLSBB_ONES) New builtin defines.
>     (xvtlsbb_zeros, xvtlsbb_ones) New builtin overloads.
>     * config/rs6000/rs6000-call.c (FUTURE_BUILTIN_VEC_XVTLSBB_ZEROS,
>     FUTURE_BUILTIN_VEC_XVTLSBB_ONES): New altivec_builtin_types entries.
>     * config/rs6000/rs6000.md (UNSPEC_XVTLSBB):  New unspec.
>     * config/rs6000/vsx.md (*xvtlsbb_internal): New instruction define.
>     (xvtlsbbo, xvtlsbbz): New instruction expands.
> 
> [testsuite]
> 
> 2020-05-26  Will Schmidt  <will_schmidt@vnet.ibm.com>
> 
>     * testsuite/gcc.target/powerpc/lsbb-runnable.c: New test.
>     * testsuite/gcc.target/powerpc/lsbb.c: New test.
> 
> 

ok


> 
> diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
> index 0a7e8ab..94afaf7 100644
> --- a/gcc/config/rs6000/altivec.h
> +++ b/gcc/config/rs6000/altivec.h
> @@ -490,10 +490,13 @@
>  #define vec_cmpnez __builtin_vec_vcmpnez
>  
>  #define vec_cntlz_lsbb __builtin_vec_vclzlsbb
>  #define vec_cnttz_lsbb __builtin_vec_vctzlsbb
>  
> +#define vec_test_lsbb_all_ones __builtin_vec_xvtlsbb_ones
> +#define vec_test_lsbb_all_zeros __builtin_vec_xvtlsbb_zeros
> +
>  #define vec_xlx __builtin_vec_vextulx
>  #define vec_xrx __builtin_vec_vexturx
>  #endif
>  
>  /* Predicates.
> diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
> index 8b1ddb0..e149c5a 100644
> --- a/gcc/config/rs6000/rs6000-builtin.def
> +++ b/gcc/config/rs6000/rs6000-builtin.def
> @@ -956,10 +956,18 @@
>  		    RS6000_BTM_FUTURE,			/* MASK */	\
>  		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
>  		     | RS6000_BTC_UNARY),				\
>  		    CODE_FOR_ ## ICODE)			/* ICODE */
>  
> +#define BU_FUTURE_VSX_1(ENUM, NAME, ATTR, ICODE)			\
> +  RS6000_BUILTIN_1 (FUTURE_BUILTIN_ ## ENUM,		/* ENUM */	\
> +		    "__builtin_vsx_" NAME,		/* NAME */	\
> +		    RS6000_BTM_FUTURE,			/* MASK */	\
> +		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
> +		     | RS6000_BTC_UNARY),				\
> +		    CODE_FOR_ ## ICODE)			/* ICODE */
> +
>  #define BU_FUTURE_V_2(ENUM, NAME, ATTR, ICODE)			\
>    RS6000_BUILTIN_2 (FUTURE_BUILTIN_ ## ENUM,		/* ENUM */	\
>  		    "__builtin_altivec_" NAME,		/* NAME */	\
>  		    RS6000_BTM_FUTURE,			/* MASK */	\
>  		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
> @@ -2635,10 +2643,13 @@ BU_FUTURE_V_1 (VSTRIHL, "vstrihl", CONST, vstril_v8hi)
>  BU_FUTURE_V_1 (VSTRIBR_P, "vstribr_p", CONST, vstrir_p_v16qi)
>  BU_FUTURE_V_1 (VSTRIHR_P, "vstrihr_p", CONST, vstrir_p_v8hi)
>  BU_FUTURE_V_1 (VSTRIBL_P, "vstribl_p", CONST, vstril_p_v16qi)
>  BU_FUTURE_V_1 (VSTRIHL_P, "vstrihl_p", CONST, vstril_p_v8hi)
>  
> +BU_FUTURE_VSX_1 (XVTLSBB_ZEROS,  "xvtlsbb_zeros", CONST, xvtlsbbz)
> +BU_FUTURE_VSX_1 (XVTLSBB_ONES,   "xvtlsbb_ones", CONST, xvtlsbbo)
> +
>  /* Future architecture overloaded vector built-ins.  */
>  BU_FUTURE_OVERLOAD_2 (CLRL, "clrl")
>  BU_FUTURE_OVERLOAD_2 (CLRR, "clrr")
>  BU_FUTURE_OVERLOAD_2 (GNB, "gnb")
>  BU_FUTURE_OVERLOAD_4 (XXEVAL, "xxeval")
> @@ -2650,10 +2661,13 @@ BU_FUTURE_OVERLOAD_3 (EXTRACTH, "extracth")
>  BU_FUTURE_OVERLOAD_1 (VSTRIR, "strir")
>  BU_FUTURE_OVERLOAD_1 (VSTRIL, "stril")
>  
>  BU_FUTURE_OVERLOAD_1 (VSTRIR_P, "strir_p")
>  BU_FUTURE_OVERLOAD_1 (VSTRIL_P, "stril_p")
> +
> +BU_FUTURE_OVERLOAD_1 (XVTLSBB_ZEROS, "xvtlsbb_zeros")
> +BU_FUTURE_OVERLOAD_1 (XVTLSBB_ONES,  "xvtlsbb_ones")
>  
>  /* 1 argument crypto functions.  */
>  BU_CRYPTO_1 (VSBOX,		"vsbox",	  CONST, crypto_vsbox_v2di)
>  BU_CRYPTO_1 (VSBOX_BE,		"vsbox_be",	  CONST, crypto_vsbox_v16qi)
>  
> diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
> index 0ac8054..f83167f 100644
> --- a/gcc/config/rs6000/rs6000-call.c
> +++ b/gcc/config/rs6000/rs6000-call.c
> @@ -5616,10 +5616,15 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
>    { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIHR_P,
>      RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, 0, 0 },
>    { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIHR_P,
>      RS6000_BTI_INTSI, RS6000_BTI_V8HI, 0, 0 },
>  
> + { FUTURE_BUILTIN_VEC_XVTLSBB_ZEROS, FUTURE_BUILTIN_XVTLSBB_ZEROS,
> +    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0},
> + { FUTURE_BUILTIN_VEC_XVTLSBB_ONES, FUTURE_BUILTIN_XVTLSBB_ONES,
> +    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0},
> +

Nearby entries have a space before the closing "}".


>    { RS6000_BUILTIN_NONE, RS6000_BUILTIN_NONE, 0, 0, 0, 0 }
>  };
>  
>  /* Nonzero if we can use a floating-point register to pass this arg.  */
>  #define USE_FP_FOR_ARG_P(CUM,MODE)		\
> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
> index 0aa5265..df0b8b7 100644
> --- a/gcc/config/rs6000/rs6000.md
> +++ b/gcc/config/rs6000/rs6000.md
> @@ -75,10 +75,11 @@
>     UNSPEC_TLSGD
>     UNSPEC_TLSLD
>     UNSPEC_TLS_GET_ADDR
>     UNSPEC_MOVESI_FROM_CR
>     UNSPEC_MOVESI_TO_CR
> +   UNSPEC_XVTLSBB
>     UNSPEC_TLSDTPREL
>     UNSPEC_TLSDTPRELHA
>     UNSPEC_TLSDTPRELLO
>     UNSPEC_TLSGOTDTPREL
>     UNSPEC_TLSTPREL
> diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
> index 2a28215..1211e0d 100644
> --- a/gcc/config/rs6000/vsx.md
> +++ b/gcc/config/rs6000/vsx.md
> @@ -1966,10 +1966,50 @@
>  		  (match_dup 2)))]
>    "VECTOR_UNIT_VSX_P (<MODE>mode)"
>    "xvcmpgt<sd>p. %x0,%x1,%x2"
>    [(set_attr "type" "<VStype_simple>")])
>  
> +;; xvtlsbb BF,XB
> +;; set CR field BF to indicate if bit 7 of every byte element in VSR[XB}
> +;; is equal to 1 (ALL_TRUE) or equal to 0 (ALL_FALSE).
> +;; CR.field_WRITE (BF, ALL_TRUE, 0, ALL_FALSE, 0);

s/set/Set the/


> +(define_insn "*xvtlsbb_internal"
> +  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
> +	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand" "wa")]
> +	 UNSPEC_XVTLSBB))]
> +"TARGET_FUTURE"
> +"xvtlsbb %0,%x1"
> +[(set_attr "type" "logical")])
> +
> +;; Vector Test Least Significant Bit by Byte
> +;; for the implementation of the builtin
> +;;     __builtin_vec_test_lsbb_all_ones
> +;;     int vec_test_lsbb_all_ones (vector unsigned char);
> +;; and
> +;;     __builtin_vec_test_lsbb_all_zeros
> +;;     int vec_test_lsbb_all_zeros (vector unsigned char);
> +(define_expand "xvtlsbbo"
> +  [(set (match_dup 2)
> +	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand" "v")]
> +	 UNSPEC_XVTLSBB))
> +	(set (match_operand:SI 0 "gpc_reg_operand" "=r")
> +		(lt:SI (match_dup 2) (const_int 0)))]
> +"TARGET_FUTURE"
> +{
> +operands[2] = gen_reg_rtx (CCmode);
> +})
> +(define_expand "xvtlsbbz"
> +  [(set (match_dup 2)
> +	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand" "v")]
> +	 UNSPEC_XVTLSBB))
> +	(set (match_operand:SI 0 "gpc_reg_operand" "=r")
> +		(eq:SI (match_dup 2) (const_int 0)))]
> +"TARGET_FUTURE"
> +{
> +operands[2] = gen_reg_rtx (CCmode);
> +})
> +
>  (define_insn "*vsx_ge_<mode>_p"
>    [(set (reg:CC CR6_REGNO)
>  	(unspec:CC
>  	 [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" "wa")
>  		 (match_operand:VSX_F 2 "vsx_register_operand" "wa"))]
> diff --git a/gcc/testsuite/gcc.target/powerpc/lsbb-runnable.c b/gcc/testsuite/gcc.target/powerpc/lsbb-runnable.c
> new file mode 100644
> index 0000000..9c770e0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/lsbb-runnable.c
> @@ -0,0 +1,65 @@
> +/*
> + Test the least significant bit by byte instruction
> +    xvtlsbb BF,XB
> + Using the builtins
> +    int vec_test_lsbb_all_zeros(vector unsigned char);
> +    int vec_test_lsbb_all_ones(vector unsigned char);
> + */

For consistency, space before "(".
Same for subsequent test.


> +
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O2 -fno-inline -mvsx -mdejagnu-cpu=future" } */
> +

-mvsx is probably not necessary.  (doesn't hurt?)

Nothing noted aside from those cosmetic nits.
lgtm

thanks
-Will


> +#include <altivec.h>
> +#include <stdio.h>
> +
> +void abort (void);
> +
> +#define ITERS 7
> +vector char input_vec[ITERS] = {
> +  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
> +  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
> +  {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
> +  {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
> +  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
> +  {0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe},
> +  {0xfe, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9}
> +};
> +
> +int expected_allzeros_results[ITERS] = {1, 0, 0, 0, 0, 1, 0};
> +int expected_allones_results[ITERS] =  {0, 1, 0, 0, 1, 0, 0};
> +
> +int test_for_zeros(vector char vc) {
> +  return vec_test_lsbb_all_zeros(vc);
> +}
> +
> +int test_for_ones(vector char vc) {
> +  return vec_test_lsbb_all_ones(vc);
> +}
> +
> +int main ()
> +{
> +int allzeros,allones;
> +int iter;
> +int failcount=0;
> +vector char srcvec;
> +
> +for (iter=0;iter<ITERS;iter++) {
> +  srcvec = input_vec[iter];
> +  allzeros = test_for_zeros(srcvec);
> +  allones = test_for_ones(srcvec);
> +  if (allzeros != expected_allzeros_results[iter]) {
> +    printf("fail on allzero check. iter %d, result was %d \n", iter, allzeros);
> +    failcount++;
> +  }
> +  if (allones != expected_allones_results[iter]) {
> +    printf("fail on allones check. iter %d, result was %d \n", iter, allones);
> +    failcount++;
> +  }
> +}
> +
> +if (failcount)
> +  abort();
> +return 0;
> +}
> +
> diff --git a/gcc/testsuite/gcc.target/powerpc/lsbb.c b/gcc/testsuite/gcc.target/powerpc/lsbb.c
> new file mode 100644
> index 0000000..a990518
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/lsbb.c
> @@ -0,0 +1,24 @@
> +/*
> + Test the least significant bit by byte instruction
> +    xvtlsbb BF,XB
> + Using the builtins
> +    int vec_test_lsbb_all_zeros(vector unsigned char);
> +    int vec_test_lsbb_all_ones(vector unsigned char);
> + */
> +
> +/* { dg-require-effective-target powerpc_future_ok } */
> +/* { dg-options "-O2 -fno-inline -mvsx -mdejagnu-cpu=future" } */
> +
> +/* { dg-final { scan-assembler-times {\mxvtlsbb\M} 2 } } */
> +/* { dg-final { scan-assembler-times {\msetbc\M} 2 } } */
> +
> +#include <altivec.h>
> +
> +int test_for_zeros(vector char vc) {
> +  return vec_test_lsbb_all_zeros(vc);
> +}
> +
> +int test_for_ones(vector char vc) {
> +  return vec_test_lsbb_all_ones(vc);
> +}
> +
will schmidt July 28, 2020, 3:31 p.m. UTC | #2
On Tue, 2020-05-26 at 11:12 -0500, will schmidt via Gcc-patches wrote:
> Hi,
> 
>   Add support for new instructions to test LSB by Byte.
> 
>   Tested on powerpc64le-unknown-linux-gnu with no
>   regressions.  (power7BE, power8LE, power8BE, power9LE).


Ping.
I note that I'll need to refresh to update the future references with
power10.  Beyond that, any other feedback?

Thanks,
-Will



> 
> [gcc]
> 
> 2020-05-26  Will Schmidt  <will_schmidt@vnet.ibm.com>
> 
>     * config/rs6000/altivec.h (vec_test_lsbb_all_ones): New define.
>     (vec_test_lsbb_all_zeros): New define.
>     * config/rs6000/rs6000-builtin.def (BU_FUTURE_VSX_1): New built-
> in
>     handling macro.  (XVTLSBB_ZEROS, XVTLSBB_ONES) New builtin
> defines.
>     (xvtlsbb_zeros, xvtlsbb_ones) New builtin overloads.
>     * config/rs6000/rs6000-call.c (FUTURE_BUILTIN_VEC_XVTLSBB_ZEROS,
>     FUTURE_BUILTIN_VEC_XVTLSBB_ONES): New altivec_builtin_types
> entries.
>     * config/rs6000/rs6000.md (UNSPEC_XVTLSBB):  New unspec.
>     * config/rs6000/vsx.md (*xvtlsbb_internal): New instruction
> define.
>     (xvtlsbbo, xvtlsbbz): New instruction expands.
> 
> [testsuite]
> 
> 2020-05-26  Will Schmidt  <will_schmidt@vnet.ibm.com>
> 
>     * testsuite/gcc.target/powerpc/lsbb-runnable.c: New test.
>     * testsuite/gcc.target/powerpc/lsbb.c: New test.
> 
> 
> 
> diff --git a/gcc/config/rs6000/altivec.h
> b/gcc/config/rs6000/altivec.h
> index 0a7e8ab..94afaf7 100644
> --- a/gcc/config/rs6000/altivec.h
> +++ b/gcc/config/rs6000/altivec.h
> @@ -490,10 +490,13 @@
>  #define vec_cmpnez __builtin_vec_vcmpnez
> 
>  #define vec_cntlz_lsbb __builtin_vec_vclzlsbb
>  #define vec_cnttz_lsbb __builtin_vec_vctzlsbb
> 
> +#define vec_test_lsbb_all_ones __builtin_vec_xvtlsbb_ones
> +#define vec_test_lsbb_all_zeros __builtin_vec_xvtlsbb_zeros
> +
>  #define vec_xlx __builtin_vec_vextulx
>  #define vec_xrx __builtin_vec_vexturx
>  #endif
> 
>  /* Predicates.
> diff --git a/gcc/config/rs6000/rs6000-builtin.def
> b/gcc/config/rs6000/rs6000-builtin.def
> index 8b1ddb0..e149c5a 100644
> --- a/gcc/config/rs6000/rs6000-builtin.def
> +++ b/gcc/config/rs6000/rs6000-builtin.def
> @@ -956,10 +956,18 @@
>  		    RS6000_BTM_FUTURE,			/* MASK */	
> \
>  		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
>  		     | RS6000_BTC_UNARY),				\
>  		    CODE_FOR_ ## ICODE)			/* ICODE */
> 
> +#define BU_FUTURE_VSX_1(ENUM, NAME, ATTR, ICODE)			
> \
> +  RS6000_BUILTIN_1 (FUTURE_BUILTIN_ ## ENUM,		/* ENUM */	
> \
> +		    "__builtin_vsx_" NAME,		/* NAME */	
> \
> +		    RS6000_BTM_FUTURE,			/* MASK */	
> \
> +		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
> +		     | RS6000_BTC_UNARY),				\
> +		    CODE_FOR_ ## ICODE)			/* ICODE */
> +
>  #define BU_FUTURE_V_2(ENUM, NAME, ATTR, ICODE)			
> \
>    RS6000_BUILTIN_2 (FUTURE_BUILTIN_ ## ENUM,		/* ENUM */	
> \
>  		    "__builtin_altivec_" NAME,		/* NAME */	
> \
>  		    RS6000_BTM_FUTURE,			/* MASK */	
> \
>  		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
> @@ -2635,10 +2643,13 @@ BU_FUTURE_V_1 (VSTRIHL, "vstrihl", CONST,
> vstril_v8hi)
>  BU_FUTURE_V_1 (VSTRIBR_P, "vstribr_p", CONST, vstrir_p_v16qi)
>  BU_FUTURE_V_1 (VSTRIHR_P, "vstrihr_p", CONST, vstrir_p_v8hi)
>  BU_FUTURE_V_1 (VSTRIBL_P, "vstribl_p", CONST, vstril_p_v16qi)
>  BU_FUTURE_V_1 (VSTRIHL_P, "vstrihl_p", CONST, vstril_p_v8hi)
> 
> +BU_FUTURE_VSX_1 (XVTLSBB_ZEROS,  "xvtlsbb_zeros", CONST, xvtlsbbz)
> +BU_FUTURE_VSX_1 (XVTLSBB_ONES,   "xvtlsbb_ones", CONST, xvtlsbbo)
> +
>  /* Future architecture overloaded vector built-ins.  */
>  BU_FUTURE_OVERLOAD_2 (CLRL, "clrl")
>  BU_FUTURE_OVERLOAD_2 (CLRR, "clrr")
>  BU_FUTURE_OVERLOAD_2 (GNB, "gnb")
>  BU_FUTURE_OVERLOAD_4 (XXEVAL, "xxeval")
> @@ -2650,10 +2661,13 @@ BU_FUTURE_OVERLOAD_3 (EXTRACTH, "extracth")
>  BU_FUTURE_OVERLOAD_1 (VSTRIR, "strir")
>  BU_FUTURE_OVERLOAD_1 (VSTRIL, "stril")
> 
>  BU_FUTURE_OVERLOAD_1 (VSTRIR_P, "strir_p")
>  BU_FUTURE_OVERLOAD_1 (VSTRIL_P, "stril_p")
> +
> +BU_FUTURE_OVERLOAD_1 (XVTLSBB_ZEROS, "xvtlsbb_zeros")
> +BU_FUTURE_OVERLOAD_1 (XVTLSBB_ONES,  "xvtlsbb_ones")
>  
>  /* 1 argument crypto functions.  */
>  BU_CRYPTO_1 (VSBOX,		"vsbox",	  CONST, crypto_vsbox_v2di)
>  BU_CRYPTO_1 (VSBOX_BE,		"vsbox_be",	  CONST,
> crypto_vsbox_v16qi)
> 
> diff --git a/gcc/config/rs6000/rs6000-call.c
> b/gcc/config/rs6000/rs6000-call.c
> index 0ac8054..f83167f 100644
> --- a/gcc/config/rs6000/rs6000-call.c
> +++ b/gcc/config/rs6000/rs6000-call.c
> @@ -5616,10 +5616,15 @@ const struct altivec_builtin_types
> altivec_overloaded_builtins[] = {
>    { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIHR_P,
>      RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, 0, 0 },
>    { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIHR_P,
>      RS6000_BTI_INTSI, RS6000_BTI_V8HI, 0, 0 },
> 
> + { FUTURE_BUILTIN_VEC_XVTLSBB_ZEROS, FUTURE_BUILTIN_XVTLSBB_ZEROS,
> +    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0},
> + { FUTURE_BUILTIN_VEC_XVTLSBB_ONES, FUTURE_BUILTIN_XVTLSBB_ONES,
> +    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0},
> +
>    { RS6000_BUILTIN_NONE, RS6000_BUILTIN_NONE, 0, 0, 0, 0 }
>  };
>  
>  /* Nonzero if we can use a floating-point register to pass this
> arg.  */
>  #define USE_FP_FOR_ARG_P(CUM,MODE)		\
> diff --git a/gcc/config/rs6000/rs6000.md
> b/gcc/config/rs6000/rs6000.md
> index 0aa5265..df0b8b7 100644
> --- a/gcc/config/rs6000/rs6000.md
> +++ b/gcc/config/rs6000/rs6000.md
> @@ -75,10 +75,11 @@
>     UNSPEC_TLSGD
>     UNSPEC_TLSLD
>     UNSPEC_TLS_GET_ADDR
>     UNSPEC_MOVESI_FROM_CR
>     UNSPEC_MOVESI_TO_CR
> +   UNSPEC_XVTLSBB
>     UNSPEC_TLSDTPREL
>     UNSPEC_TLSDTPRELHA
>     UNSPEC_TLSDTPRELLO
>     UNSPEC_TLSGOTDTPREL
>     UNSPEC_TLSTPREL
> diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
> index 2a28215..1211e0d 100644
> --- a/gcc/config/rs6000/vsx.md
> +++ b/gcc/config/rs6000/vsx.md
> @@ -1966,10 +1966,50 @@
>  		  (match_dup 2)))]
>    "VECTOR_UNIT_VSX_P (<MODE>mode)"
>    "xvcmpgt<sd>p. %x0,%x1,%x2"
>    [(set_attr "type" "<VStype_simple>")])
> 
> +;; xvtlsbb BF,XB
> +;; set CR field BF to indicate if bit 7 of every byte element in
> VSR[XB}
> +;; is equal to 1 (ALL_TRUE) or equal to 0 (ALL_FALSE).
> +;; CR.field_WRITE (BF, ALL_TRUE, 0, ALL_FALSE, 0);
> +(define_insn "*xvtlsbb_internal"
> +  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
> +	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand"
> "wa")]
> +	 UNSPEC_XVTLSBB))]
> +"TARGET_FUTURE"
> +"xvtlsbb %0,%x1"
> +[(set_attr "type" "logical")])
> +
> +;; Vector Test Least Significant Bit by Byte
> +;; for the implementation of the builtin
> +;;     __builtin_vec_test_lsbb_all_ones
> +;;     int vec_test_lsbb_all_ones (vector unsigned char);
> +;; and
> +;;     __builtin_vec_test_lsbb_all_zeros
> +;;     int vec_test_lsbb_all_zeros (vector unsigned char);
> +(define_expand "xvtlsbbo"
> +  [(set (match_dup 2)
> +	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand" "v")]
> +	 UNSPEC_XVTLSBB))
> +	(set (match_operand:SI 0 "gpc_reg_operand" "=r")
> +		(lt:SI (match_dup 2) (const_int 0)))]
> +"TARGET_FUTURE"
> +{
> +operands[2] = gen_reg_rtx (CCmode);
> +})
> +(define_expand "xvtlsbbz"
> +  [(set (match_dup 2)
> +	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand" "v")]
> +	 UNSPEC_XVTLSBB))
> +	(set (match_operand:SI 0 "gpc_reg_operand" "=r")
> +		(eq:SI (match_dup 2) (const_int 0)))]
> +"TARGET_FUTURE"
> +{
> +operands[2] = gen_reg_rtx (CCmode);
> +})
> +
>  (define_insn "*vsx_ge_<mode>_p"
>    [(set (reg:CC CR6_REGNO)
>  	(unspec:CC
>  	 [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" "wa")
>  		 (match_operand:VSX_F 2 "vsx_register_operand" "wa"))]
> diff --git a/gcc/testsuite/gcc.target/powerpc/lsbb-runnable.c
> b/gcc/testsuite/gcc.target/powerpc/lsbb-runnable.c
> new file mode 100644
> index 0000000..9c770e0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/lsbb-runnable.c
> @@ -0,0 +1,65 @@
> +/*
> + Test the least significant bit by byte instruction
> +    xvtlsbb BF,XB
> + Using the builtins
> +    int vec_test_lsbb_all_zeros(vector unsigned char);
> +    int vec_test_lsbb_all_ones(vector unsigned char);
> + */
> +
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O2 -fno-inline -mvsx -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +#include <stdio.h>
> +
> +void abort (void);
> +
> +#define ITERS 7
> +vector char input_vec[ITERS] = {
> +  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
> +  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
> +  {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
> +  {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
> +  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> 0xff, 0xff, 0xff, 0xff, 0xff},
> +  {0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
> 0xfe, 0xfe, 0xfe, 0xfe, 0xfe},
> +  {0xfe, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
> 0xf5, 0xf6, 0xf7, 0xf8, 0xf9}
> +};
> +
> +int expected_allzeros_results[ITERS] = {1, 0, 0, 0, 0, 1, 0};
> +int expected_allones_results[ITERS] =  {0, 1, 0, 0, 1, 0, 0};
> +
> +int test_for_zeros(vector char vc) {
> +  return vec_test_lsbb_all_zeros(vc);
> +}
> +
> +int test_for_ones(vector char vc) {
> +  return vec_test_lsbb_all_ones(vc);
> +}
> +
> +int main ()
> +{
> +int allzeros,allones;
> +int iter;
> +int failcount=0;
> +vector char srcvec;
> +
> +for (iter=0;iter<ITERS;iter++) {
> +  srcvec = input_vec[iter];
> +  allzeros = test_for_zeros(srcvec);
> +  allones = test_for_ones(srcvec);
> +  if (allzeros != expected_allzeros_results[iter]) {
> +    printf("fail on allzero check. iter %d, result was %d \n", iter,
> allzeros);
> +    failcount++;
> +  }
> +  if (allones != expected_allones_results[iter]) {
> +    printf("fail on allones check. iter %d, result was %d \n", iter,
> allones);
> +    failcount++;
> +  }
> +}
> +
> +if (failcount)
> +  abort();
> +return 0;
> +}
> +
> diff --git a/gcc/testsuite/gcc.target/powerpc/lsbb.c
> b/gcc/testsuite/gcc.target/powerpc/lsbb.c
> new file mode 100644
> index 0000000..a990518
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/lsbb.c
> @@ -0,0 +1,24 @@
> +/*
> + Test the least significant bit by byte instruction
> +    xvtlsbb BF,XB
> + Using the builtins
> +    int vec_test_lsbb_all_zeros(vector unsigned char);
> +    int vec_test_lsbb_all_ones(vector unsigned char);
> + */
> +
> +/* { dg-require-effective-target powerpc_future_ok } */
> +/* { dg-options "-O2 -fno-inline -mvsx -mdejagnu-cpu=future" } */
> +
> +/* { dg-final { scan-assembler-times {\mxvtlsbb\M} 2 } } */
> +/* { dg-final { scan-assembler-times {\msetbc\M} 2 } } */
> +
> +#include <altivec.h>
> +
> +int test_for_zeros(vector char vc) {
> +  return vec_test_lsbb_all_zeros(vc);
> +}
> +
> +int test_for_ones(vector char vc) {
> +  return vec_test_lsbb_all_ones(vc);
> +}
> +
>
Segher Boessenkool July 28, 2020, 9:44 p.m. UTC | #3
Hi!

On Tue, Jul 28, 2020 at 10:31:02AM -0500, will schmidt wrote:
> >     * config/rs6000/rs6000-builtin.def (BU_FUTURE_VSX_1): New built-
> > in
> >     handling macro.  (XVTLSBB_ZEROS, XVTLSBB_ONES) New builtin
> > defines.

New (...) should start a new line.  Missing colon here, btw.

> >     (xvtlsbb_zeros, xvtlsbb_ones) New builtin overloads.

And here.

> > --- a/gcc/config/rs6000/altivec.h
> > +++ b/gcc/config/rs6000/altivec.h
> > @@ -490,10 +490,13 @@
> >  #define vec_cmpnez __builtin_vec_vcmpnez
> > 
> >  #define vec_cntlz_lsbb __builtin_vec_vclzlsbb
> >  #define vec_cnttz_lsbb __builtin_vec_vctzlsbb
> > 
> > +#define vec_test_lsbb_all_ones __builtin_vec_xvtlsbb_ones
> > +#define vec_test_lsbb_all_zeros __builtin_vec_xvtlsbb_zeros

Maybe the builtins should have "_all" in the name as well?  It seems
clearer, and it's not much more to type (or read).

> > +BU_FUTURE_OVERLOAD_1 (XVTLSBB_ZEROS, "xvtlsbb_zeros")
> > +BU_FUTURE_OVERLOAD_1 (XVTLSBB_ONES,  "xvtlsbb_ones")

Here too, then.

> > +;; xvtlsbb BF,XB
> > +;; set CR field BF to indicate if bit 7 of every byte element in
> > VSR[XB}

Capital S in Set.  And you typoed the ].

"The low bit of every byte", perhaps?

> > +;; is equal to 1 (ALL_TRUE) or equal to 0 (ALL_FALSE).
> > +;; CR.field_WRITE (BF, ALL_TRUE, 0, ALL_FALSE, 0);

That last line is copied from the ISA, but is a bit cryptical without
context.

> > +(define_insn "*xvtlsbb_internal"
> > +  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
> > +	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand"
> > "wa")]

The line is wrapped strangely here.  Maybe it is how you mailed it?  But
please check.

> > +	 UNSPEC_XVTLSBB))]
> > +"TARGET_FUTURE"
> > +"xvtlsbb %0,%x1"
> > +[(set_attr "type" "logical")])

And here it is indented wrong.

> > +(define_expand "xvtlsbbo"
> > +  [(set (match_dup 2)
> > +	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand" "v")]
> > +	 UNSPEC_XVTLSBB))
> > +	(set (match_operand:SI 0 "gpc_reg_operand" "=r")
> > +		(lt:SI (match_dup 2) (const_int 0)))]
> > +"TARGET_FUTURE"
> > +{
> > +operands[2] = gen_reg_rtx (CCmode);
> > +})
> > +(define_expand "xvtlsbbz"
> > +  [(set (match_dup 2)
> > +	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand" "v")]
> > +	 UNSPEC_XVTLSBB))
> > +	(set (match_operand:SI 0 "gpc_reg_operand" "=r")
> > +		(eq:SI (match_dup 2) (const_int 0)))]
> > +"TARGET_FUTURE"
> > +{
> > +operands[2] = gen_reg_rtx (CCmode);
> > +})

All of this as well.

> > +/* { dg-do run } */
> > +/* { dg-require-effective-target powerpc_future_hw } */
> > +/* { dg-options "-O2 -fno-inline -mvsx -mdejagnu-cpu=future" } */

-mvsx is implied by -mcpu=power10.

> > +/* { dg-final { scan-assembler-times {\mxvtlsbb\M} 2 } } */
> > +/* { dg-final { scan-assembler-times {\msetbc\M} 2 } } */

So I wonder if it can always get the correct bit (we do not have CC modes
that allow multiple bits to be set, but for this particular insn, it
never *can* set multiple bits!)


Should be okay with those things fixed (and that _all thought about).
Okay for trunk, or you can send one more version if you prefer :-)

Thanks!


Segher
diff mbox series

Patch

diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index 0a7e8ab..94afaf7 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -490,10 +490,13 @@ 
 #define vec_cmpnez __builtin_vec_vcmpnez
 
 #define vec_cntlz_lsbb __builtin_vec_vclzlsbb
 #define vec_cnttz_lsbb __builtin_vec_vctzlsbb
 
+#define vec_test_lsbb_all_ones __builtin_vec_xvtlsbb_ones
+#define vec_test_lsbb_all_zeros __builtin_vec_xvtlsbb_zeros
+
 #define vec_xlx __builtin_vec_vextulx
 #define vec_xrx __builtin_vec_vexturx
 #endif
 
 /* Predicates.
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 8b1ddb0..e149c5a 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -956,10 +956,18 @@ 
 		    RS6000_BTM_FUTURE,			/* MASK */	\
 		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
 		     | RS6000_BTC_UNARY),				\
 		    CODE_FOR_ ## ICODE)			/* ICODE */
 
+#define BU_FUTURE_VSX_1(ENUM, NAME, ATTR, ICODE)			\
+  RS6000_BUILTIN_1 (FUTURE_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_vsx_" NAME,		/* NAME */	\
+		    RS6000_BTM_FUTURE,			/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_UNARY),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
 #define BU_FUTURE_V_2(ENUM, NAME, ATTR, ICODE)			\
   RS6000_BUILTIN_2 (FUTURE_BUILTIN_ ## ENUM,		/* ENUM */	\
 		    "__builtin_altivec_" NAME,		/* NAME */	\
 		    RS6000_BTM_FUTURE,			/* MASK */	\
 		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
@@ -2635,10 +2643,13 @@  BU_FUTURE_V_1 (VSTRIHL, "vstrihl", CONST, vstril_v8hi)
 BU_FUTURE_V_1 (VSTRIBR_P, "vstribr_p", CONST, vstrir_p_v16qi)
 BU_FUTURE_V_1 (VSTRIHR_P, "vstrihr_p", CONST, vstrir_p_v8hi)
 BU_FUTURE_V_1 (VSTRIBL_P, "vstribl_p", CONST, vstril_p_v16qi)
 BU_FUTURE_V_1 (VSTRIHL_P, "vstrihl_p", CONST, vstril_p_v8hi)
 
+BU_FUTURE_VSX_1 (XVTLSBB_ZEROS,  "xvtlsbb_zeros", CONST, xvtlsbbz)
+BU_FUTURE_VSX_1 (XVTLSBB_ONES,   "xvtlsbb_ones", CONST, xvtlsbbo)
+
 /* Future architecture overloaded vector built-ins.  */
 BU_FUTURE_OVERLOAD_2 (CLRL, "clrl")
 BU_FUTURE_OVERLOAD_2 (CLRR, "clrr")
 BU_FUTURE_OVERLOAD_2 (GNB, "gnb")
 BU_FUTURE_OVERLOAD_4 (XXEVAL, "xxeval")
@@ -2650,10 +2661,13 @@  BU_FUTURE_OVERLOAD_3 (EXTRACTH, "extracth")
 BU_FUTURE_OVERLOAD_1 (VSTRIR, "strir")
 BU_FUTURE_OVERLOAD_1 (VSTRIL, "stril")
 
 BU_FUTURE_OVERLOAD_1 (VSTRIR_P, "strir_p")
 BU_FUTURE_OVERLOAD_1 (VSTRIL_P, "stril_p")
+
+BU_FUTURE_OVERLOAD_1 (XVTLSBB_ZEROS, "xvtlsbb_zeros")
+BU_FUTURE_OVERLOAD_1 (XVTLSBB_ONES,  "xvtlsbb_ones")
 
 /* 1 argument crypto functions.  */
 BU_CRYPTO_1 (VSBOX,		"vsbox",	  CONST, crypto_vsbox_v2di)
 BU_CRYPTO_1 (VSBOX_BE,		"vsbox_be",	  CONST, crypto_vsbox_v16qi)
 
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 0ac8054..f83167f 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -5616,10 +5616,15 @@  const struct altivec_builtin_types altivec_overloaded_builtins[] = {
   { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIHR_P,
     RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, 0, 0 },
   { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIHR_P,
     RS6000_BTI_INTSI, RS6000_BTI_V8HI, 0, 0 },
 
+ { FUTURE_BUILTIN_VEC_XVTLSBB_ZEROS, FUTURE_BUILTIN_XVTLSBB_ZEROS,
+    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0},
+ { FUTURE_BUILTIN_VEC_XVTLSBB_ONES, FUTURE_BUILTIN_XVTLSBB_ONES,
+    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0},
+
   { RS6000_BUILTIN_NONE, RS6000_BUILTIN_NONE, 0, 0, 0, 0 }
 };
 
 /* Nonzero if we can use a floating-point register to pass this arg.  */
 #define USE_FP_FOR_ARG_P(CUM,MODE)		\
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 0aa5265..df0b8b7 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -75,10 +75,11 @@ 
    UNSPEC_TLSGD
    UNSPEC_TLSLD
    UNSPEC_TLS_GET_ADDR
    UNSPEC_MOVESI_FROM_CR
    UNSPEC_MOVESI_TO_CR
+   UNSPEC_XVTLSBB
    UNSPEC_TLSDTPREL
    UNSPEC_TLSDTPRELHA
    UNSPEC_TLSDTPRELLO
    UNSPEC_TLSGOTDTPREL
    UNSPEC_TLSTPREL
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 2a28215..1211e0d 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -1966,10 +1966,50 @@ 
 		  (match_dup 2)))]
   "VECTOR_UNIT_VSX_P (<MODE>mode)"
   "xvcmpgt<sd>p. %x0,%x1,%x2"
   [(set_attr "type" "<VStype_simple>")])
 
+;; xvtlsbb BF,XB
+;; set CR field BF to indicate if bit 7 of every byte element in VSR[XB}
+;; is equal to 1 (ALL_TRUE) or equal to 0 (ALL_FALSE).
+;; CR.field_WRITE (BF, ALL_TRUE, 0, ALL_FALSE, 0);
+(define_insn "*xvtlsbb_internal"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
+	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand" "wa")]
+	 UNSPEC_XVTLSBB))]
+"TARGET_FUTURE"
+"xvtlsbb %0,%x1"
+[(set_attr "type" "logical")])
+
+;; Vector Test Least Significant Bit by Byte
+;; for the implementation of the builtin
+;;     __builtin_vec_test_lsbb_all_ones
+;;     int vec_test_lsbb_all_ones (vector unsigned char);
+;; and
+;;     __builtin_vec_test_lsbb_all_zeros
+;;     int vec_test_lsbb_all_zeros (vector unsigned char);
+(define_expand "xvtlsbbo"
+  [(set (match_dup 2)
+	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand" "v")]
+	 UNSPEC_XVTLSBB))
+	(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+		(lt:SI (match_dup 2) (const_int 0)))]
+"TARGET_FUTURE"
+{
+operands[2] = gen_reg_rtx (CCmode);
+})
+(define_expand "xvtlsbbz"
+  [(set (match_dup 2)
+	(unspec:CC [(match_operand:V16QI 1 "vsx_register_operand" "v")]
+	 UNSPEC_XVTLSBB))
+	(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+		(eq:SI (match_dup 2) (const_int 0)))]
+"TARGET_FUTURE"
+{
+operands[2] = gen_reg_rtx (CCmode);
+})
+
 (define_insn "*vsx_ge_<mode>_p"
   [(set (reg:CC CR6_REGNO)
 	(unspec:CC
 	 [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" "wa")
 		 (match_operand:VSX_F 2 "vsx_register_operand" "wa"))]
diff --git a/gcc/testsuite/gcc.target/powerpc/lsbb-runnable.c b/gcc/testsuite/gcc.target/powerpc/lsbb-runnable.c
new file mode 100644
index 0000000..9c770e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/lsbb-runnable.c
@@ -0,0 +1,65 @@ 
+/*
+ Test the least significant bit by byte instruction
+    xvtlsbb BF,XB
+ Using the builtins
+    int vec_test_lsbb_all_zeros(vector unsigned char);
+    int vec_test_lsbb_all_ones(vector unsigned char);
+ */
+
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O2 -fno-inline -mvsx -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+#include <stdio.h>
+
+void abort (void);
+
+#define ITERS 7
+vector char input_vec[ITERS] = {
+  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+  {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
+  {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
+  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+  {0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe},
+  {0xfe, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9}
+};
+
+int expected_allzeros_results[ITERS] = {1, 0, 0, 0, 0, 1, 0};
+int expected_allones_results[ITERS] =  {0, 1, 0, 0, 1, 0, 0};
+
+int test_for_zeros(vector char vc) {
+  return vec_test_lsbb_all_zeros(vc);
+}
+
+int test_for_ones(vector char vc) {
+  return vec_test_lsbb_all_ones(vc);
+}
+
+int main ()
+{
+int allzeros,allones;
+int iter;
+int failcount=0;
+vector char srcvec;
+
+for (iter=0;iter<ITERS;iter++) {
+  srcvec = input_vec[iter];
+  allzeros = test_for_zeros(srcvec);
+  allones = test_for_ones(srcvec);
+  if (allzeros != expected_allzeros_results[iter]) {
+    printf("fail on allzero check. iter %d, result was %d \n", iter, allzeros);
+    failcount++;
+  }
+  if (allones != expected_allones_results[iter]) {
+    printf("fail on allones check. iter %d, result was %d \n", iter, allones);
+    failcount++;
+  }
+}
+
+if (failcount)
+  abort();
+return 0;
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/lsbb.c b/gcc/testsuite/gcc.target/powerpc/lsbb.c
new file mode 100644
index 0000000..a990518
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/lsbb.c
@@ -0,0 +1,24 @@ 
+/*
+ Test the least significant bit by byte instruction
+    xvtlsbb BF,XB
+ Using the builtins
+    int vec_test_lsbb_all_zeros(vector unsigned char);
+    int vec_test_lsbb_all_ones(vector unsigned char);
+ */
+
+/* { dg-require-effective-target powerpc_future_ok } */
+/* { dg-options "-O2 -fno-inline -mvsx -mdejagnu-cpu=future" } */
+
+/* { dg-final { scan-assembler-times {\mxvtlsbb\M} 2 } } */
+/* { dg-final { scan-assembler-times {\msetbc\M} 2 } } */
+
+#include <altivec.h>
+
+int test_for_zeros(vector char vc) {
+  return vec_test_lsbb_all_zeros(vc);
+}
+
+int test_for_ones(vector char vc) {
+  return vec_test_lsbb_all_ones(vc);
+}
+