< prev index next >

src/hotspot/cpu/aarch64/aarch64_neon.ad

Print this page
*** 5681,43 ***
      }
    %}
    ins_pipe(vdop_fp128);
  %}
  
! instruct vpopcount4I(vecX dst, vecX src) %{
!   predicate(UsePopCountInstruction && n->as_Vector()->length() == 4);
    match(Set dst (PopCountVI src));
!   format %{
!     "cnt     $dst, $src\t# vector (16B)\n\t"
!     "uaddlp  $dst, $dst\t# vector (16B)\n\t"
!     "uaddlp  $dst, $dst\t# vector (8H)"
    %}
    ins_encode %{
      __ cnt(as_FloatRegister($dst$$reg), __ T16B,
             as_FloatRegister($src$$reg));
      __ uaddlp(as_FloatRegister($dst$$reg), __ T16B,
                as_FloatRegister($dst$$reg));
      __ uaddlp(as_FloatRegister($dst$$reg), __ T8H,
                as_FloatRegister($dst$$reg));
    %}
    ins_pipe(pipe_class_default);
  %}
  
! instruct vpopcount2I(vecD dst, vecD src) %{
!   predicate(UsePopCountInstruction && n->as_Vector()->length() == 2);
!   match(Set dst (PopCountVI src));
!   format %{
!     "cnt     $dst, $src\t# vector (8B)\n\t"
!     "uaddlp  $dst, $dst\t# vector (8B)\n\t"
-     "uaddlp  $dst, $dst\t# vector (4H)"
-   %}
    ins_encode %{
!     __ cnt(as_FloatRegister($dst$$reg), __ T8B,
             as_FloatRegister($src$$reg));
!     __ uaddlp(as_FloatRegister($dst$$reg), __ T8B,
                as_FloatRegister($dst$$reg));
!     __ uaddlp(as_FloatRegister($dst$$reg), __ T4H,
                as_FloatRegister($dst$$reg));
    %}
    ins_pipe(pipe_class_default);
  %}
  
--- 5681,95 ---
      }
    %}
    ins_pipe(vdop_fp128);
  %}
  
! instruct vpopcountID(vecD dst, vecD src) %{
!   predicate(n->as_Vector()->length_in_bytes() < 16);
    match(Set dst (PopCountVI src));
!   ins_cost(3 * INSN_COST);
!   format %{ "vpopcountI  $dst, $src\t# vector (8B/4H/2S)" %}
!   ins_encode %{
!     assert(UsePopCountInstruction, "unsupported");
+     BasicType bt = Matcher::vector_element_basic_type(this);
+     __ cnt(as_FloatRegister($dst$$reg), __ T8B,
+            as_FloatRegister($src$$reg));
+     if (bt == T_SHORT || bt == T_INT) {
+       __ uaddlp(as_FloatRegister($dst$$reg), __ T8B,
+                 as_FloatRegister($dst$$reg));
+     }
+     if (bt == T_INT) {
+       __ uaddlp(as_FloatRegister($dst$$reg), __ T4H,
+                 as_FloatRegister($dst$$reg));
+     }
    %}
+   ins_pipe(pipe_class_default);
+ %}
+ 
+ instruct vpopcountIX(vecX dst, vecX src) %{
+   predicate(n->as_Vector()->length_in_bytes() == 16);
+   match(Set dst (PopCountVI src));
+   ins_cost(3 * INSN_COST);
+   format %{ "vpopcountI  $dst, $src\t# vector (16B/8H/4S)" %}
    ins_encode %{
+     assert(UsePopCountInstruction, "unsupported");
+     BasicType bt = Matcher::vector_element_basic_type(this);
+     __ cnt(as_FloatRegister($dst$$reg), __ T16B,
+            as_FloatRegister($src$$reg));
+     if (bt == T_SHORT || bt == T_INT) {
+       __ uaddlp(as_FloatRegister($dst$$reg), __ T16B,
+                 as_FloatRegister($dst$$reg));
+     }
+     if (bt == T_INT) {
+       __ uaddlp(as_FloatRegister($dst$$reg), __ T8H,
+                 as_FloatRegister($dst$$reg));
+     }
+   %}
+   ins_pipe(pipe_class_default);
+ %}
+ 
+ // If the PopCountVL is generated by auto-vectorization, the dst basic
+ // type is T_INT. And once we have unified the type definition for
+ // Vector API and auto-vectorization, this rule can be merged with
+ // "vpopcountLX" rule.
+ instruct vpopcountLD(vecD dst, vecX src) %{
+   predicate(n->as_Vector()->length_in_bytes() < 16 &&
+             n->bottom_type()->is_vect()->element_basic_type() == T_INT);
+   match(Set dst (PopCountVL src));
+   ins_cost(5 * INSN_COST);
+   format %{ "vpopcountL  $dst, $src\t# vector (2S)" %}
+   ins_encode %{
+     assert(UsePopCountInstruction, "unsupported");
      __ cnt(as_FloatRegister($dst$$reg), __ T16B,
             as_FloatRegister($src$$reg));
      __ uaddlp(as_FloatRegister($dst$$reg), __ T16B,
                as_FloatRegister($dst$$reg));
      __ uaddlp(as_FloatRegister($dst$$reg), __ T8H,
                as_FloatRegister($dst$$reg));
+     __ uaddlp(as_FloatRegister($dst$$reg), __ T4S,
+               as_FloatRegister($dst$$reg));
+     __ xtn(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($dst$$reg), __ T2D);
    %}
    ins_pipe(pipe_class_default);
  %}
  
! instruct vpopcountLX(vecX dst, vecX src) %{
!   predicate(n->as_Vector()->length_in_bytes() == 16 &&
!             n->bottom_type()->is_vect()->element_basic_type() == T_LONG);
!   match(Set dst (PopCountVL src));
!   ins_cost(4 * INSN_COST);
!   format %{ "vpopcountL  $dst, $src\t# vector (2D)" %}
    ins_encode %{
!     assert(UsePopCountInstruction, "unsupported");
+     __ cnt(as_FloatRegister($dst$$reg), __ T16B,
             as_FloatRegister($src$$reg));
!     __ uaddlp(as_FloatRegister($dst$$reg), __ T16B,
                as_FloatRegister($dst$$reg));
!     __ uaddlp(as_FloatRegister($dst$$reg), __ T8H,
+               as_FloatRegister($dst$$reg));
+     __ uaddlp(as_FloatRegister($dst$$reg), __ T4S,
                as_FloatRegister($dst$$reg));
    %}
    ins_pipe(pipe_class_default);
  %}
  

*** 5919,5 ***
--- 5971,133 ---
      __ orr(as_Register($dst$$reg), as_Register($dst$$reg),
             rscratch1, Assembler::LSL, 8);
    %}
    ins_pipe(pipe_slow);
  %}
+ 
+ //------------------------- CountLeadingZerosV -----------------------------
+ 
+ instruct countLeadingZerosVD(vecD dst, vecD src) %{
+   predicate(n->as_Vector()->length_in_bytes() == 8);
+   match(Set dst (CountLeadingZerosV src));
+   ins_cost(INSN_COST);
+   format %{ "countLeadingZerosV $dst, $src\t# vector (8B/4H/2S)" %}
+   ins_encode %{
+     BasicType bt = Matcher::vector_element_basic_type(this);
+     Assembler::SIMD_Arrangement size = __ esize2arrangement((unsigned)type2aelembytes(bt), false);
+     __ clz(as_FloatRegister($dst$$reg), size, as_FloatRegister($src$$reg));
+   %}
+   ins_pipe(pipe_slow);
+ %}
+ 
+ instruct countLeadingZerosVX(vecX dst, vecX src) %{
+   predicate(n->as_Vector()->length_in_bytes() == 16);
+   match(Set dst (CountLeadingZerosV src));
+   ins_cost(INSN_COST);
+   format %{ "countLeadingZerosV $dst, $src\t# vector (16B/8H/4S/2D)" %}
+   ins_encode %{
+     BasicType bt = Matcher::vector_element_basic_type(this);
+     Assembler::SIMD_Arrangement size = __ esize2arrangement((unsigned)type2aelembytes(bt), true);
+     if (bt != T_LONG) {
+       __ clz(as_FloatRegister($dst$$reg), size, as_FloatRegister($src$$reg));
+     } else {
+       __ umov(rscratch1, as_FloatRegister($src$$reg), __ D, 0);
+       __ clz(rscratch1, rscratch1);
+       __ mov(as_FloatRegister($dst$$reg), __ D, 0, rscratch1);
+       __ umov(rscratch1, as_FloatRegister($src$$reg), __ D, 1);
+       __ clz(rscratch1, rscratch1);
+       __ mov(as_FloatRegister($dst$$reg), __ D, 1, rscratch1);
+     }
+   %}
+   ins_pipe(pipe_slow);
+ %}
+ 
+ //------------------------- CountTrailingZerosV ----------------------------
+ 
+ instruct countTrailingZerosVD(vecD dst, vecD src) %{
+   predicate(n->as_Vector()->length_in_bytes() == 8);
+   match(Set dst (CountTrailingZerosV src));
+   ins_cost(3 * INSN_COST);
+   format %{ "countTrailingZerosV $dst, $src\t# vector (8B/4H/2S)" %}
+   ins_encode %{
+     BasicType bt = Matcher::vector_element_basic_type(this);
+     Assembler::SIMD_Arrangement size = __ esize2arrangement((unsigned)type2aelembytes(bt), false);
+     __ neon_reverse_bits(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), bt, false);
+     __ clz(as_FloatRegister($dst$$reg), size, as_FloatRegister($dst$$reg));
+   %}
+   ins_pipe(pipe_slow);
+ %}
+ 
+ instruct countTrailingZerosVX(vecX dst, vecX src) %{
+   predicate(n->as_Vector()->length_in_bytes() == 16);
+   match(Set dst (CountTrailingZerosV src));
+   ins_cost(3 * INSN_COST);
+   format %{ "countTrailingZerosV $dst, $src\t# vector (16B/8H/4S/2D)" %}
+   ins_encode %{
+     BasicType bt = Matcher::vector_element_basic_type(this);
+     Assembler::SIMD_Arrangement size = __ esize2arrangement((unsigned)type2aelembytes(bt), true);
+     __ neon_reverse_bits(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), bt, true);
+     if (bt != T_LONG) {
+       __ clz(as_FloatRegister($dst$$reg), size, as_FloatRegister($dst$$reg));
+     } else {
+       __ umov(rscratch1, as_FloatRegister($dst$$reg), __ D, 0);
+       __ clz(rscratch1, rscratch1);
+       __ mov(as_FloatRegister($dst$$reg), __ D, 0, rscratch1);
+       __ umov(rscratch1, as_FloatRegister($dst$$reg), __ D, 1);
+       __ clz(rscratch1, rscratch1);
+       __ mov(as_FloatRegister($dst$$reg), __ D, 1, rscratch1);
+     }
+   %}
+   ins_pipe(pipe_slow);
+ %}
+ 
+ //------------------------------ ReverseV -----------------------------------
+ 
+ instruct vreverseD(vecD dst, vecD src) %{
+   predicate(n->as_Vector()->length_in_bytes() == 8);
+   match(Set dst (ReverseV src));
+   ins_cost(2 * INSN_COST);
+   format %{ "ReverseV $dst, $src\t# vector (D)" %}
+   ins_encode %{
+     BasicType bt = Matcher::vector_element_basic_type(this);
+     __ neon_reverse_bits(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), bt, false);
+   %}
+   ins_pipe(pipe_slow);
+ %}
+ 
+ instruct vreverseX(vecX dst, vecX src) %{
+   predicate(n->as_Vector()->length_in_bytes() == 16);
+   match(Set dst (ReverseV src));
+   ins_cost(2 * INSN_COST);
+   format %{ "ReverseV $dst, $src\t# vector (X)" %}
+   ins_encode %{
+     BasicType bt = Matcher::vector_element_basic_type(this);
+     __ neon_reverse_bits(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), bt, true);
+   %}
+   ins_pipe(pipe_slow);
+ %}
+ 
+ //---------------------------- ReverseBytesV --------------------------------
+ 
+ instruct vreverseBytesD(vecD dst, vecD src) %{
+   predicate(n->as_Vector()->length_in_bytes() == 8);
+   match(Set dst (ReverseBytesV src));
+   ins_cost(INSN_COST);
+   format %{ "ReverseBytesV $dst, $src\t# vector (D)" %}
+   ins_encode %{
+     BasicType bt = Matcher::vector_element_basic_type(this);
+     __ neon_reverse_bytes(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), bt, false);
+   %}
+   ins_pipe(pipe_slow);
+ %}
+ 
+ instruct vreverseBytesX(vecX dst, vecX src) %{
+   predicate(n->as_Vector()->length_in_bytes() == 16);
+   match(Set dst (ReverseBytesV src));
+   ins_cost(INSN_COST);
+   format %{ "ReverseBytesV $dst, $src\t# vector (X)" %}
+   ins_encode %{
+     BasicType bt = Matcher::vector_element_basic_type(this);
+     __ neon_reverse_bytes(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), bt, true);
+   %}
+   ins_pipe(pipe_slow);
+ %}
< prev index next >