< prev index next >

src/hotspot/cpu/aarch64/aarch64.ad

Print this page
rev 61975 : [vector] Address review comments for AArch64 backend changes
1. Seperate newly added NEON instructions to a new ad file
   aarch64_neon.ad
2. Add assembler tests for NEON instructions. Trailing spaces
   in the python script are also removed.

@@ -2073,11 +2073,11 @@
 }
 
 // Identify extra cases that we might want to provide match rules for vector nodes and
 // other intrinsics guarded with vector length (vlen) and element type (bt).
 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
-  if (!match_rule_supported(opcode)) {
+  if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
     return false;
   }
 
   // Special cases which require vector length
   switch (opcode) {

@@ -2085,19 +2085,29 @@
       if (vlen != 4) {
         return false;
       }
       break;
     }
+    case Op_VectorLoadShuffle:
+    case Op_VectorRearrange:
+      if (vlen < 4) {
+        return false;
+      }
+      break;
   }
 
   return true; // Per default match rules are supported.
 }
 
 const bool Matcher::has_predicated_vectors(void) {
   return false;
 }
 
+bool Matcher::supports_vector_variable_shifts(void) {
+  return true;
+}
+
 const int Matcher::float_pressure(int default_pressure_threshold) {
   return default_pressure_threshold;
 }
 
 int Matcher::regnum_to_fpu_offset(int regnum)

@@ -2140,19 +2150,30 @@
 // Limits on vector size (number of elements) loaded into vector.
 const int Matcher::max_vector_size(const BasicType bt) {
   return vector_width_in_bytes(bt)/type2aelembytes(bt);
 }
 const int Matcher::min_vector_size(const BasicType bt) {
-//  For the moment limit the vector size to 8 bytes
+  int max_size = max_vector_size(bt);
+  // Limit the vector size to 8 bytes
     int size = 8 / type2aelembytes(bt);
+  if (bt == T_BYTE) {
+    // To support vector api shuffle/rearrange.
+    size = 4;
+  } else if (bt == T_BOOLEAN) {
+    // To support vector api load/store mask.
+    size = 2;
+  }
     if (size < 2) size = 2;
-    return size;
+  return MIN2(size,max_size);
 }
 
 // Vector ideal reg.
 const uint Matcher::vector_ideal_reg(int len) {
   switch(len) {
+    // For 16-bit/32-bit mask vector, reuse VecD.
+    case  2:
+    case  4:
     case  8: return Op_VecD;
     case 16: return Op_VecX;
   }
   ShouldNotReachHere();
   return 0;

@@ -2791,10 +2812,16 @@
   %}
 
   // END Non-volatile memory access
 
   // Vector loads and stores
+  enc_class aarch64_enc_ldrvH(vecD dst, memory mem) %{
+    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
+    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::H,
+       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
+  %}
+
   enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{
     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
     loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S,
        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
   %}

@@ -2809,10 +2836,16 @@
     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
     loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q,
        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
   %}
 
+  enc_class aarch64_enc_strvH(vecD src, memory mem) %{
+    FloatRegister src_reg = as_FloatRegister($src$$reg);
+    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::H,
+       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
+  %}
+
   enc_class aarch64_enc_strvS(vecD src, memory mem) %{
     FloatRegister src_reg = as_FloatRegister($src$$reg);
     loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S,
        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
   %}

@@ -3893,10 +3926,30 @@
   op_cost(0);
   format %{ %}
   interface(CONST_INTER);
 %}
 
+operand immI_2()
+%{
+  predicate(n->get_int() == 2);
+  match(ConI);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
+operand immI_4()
+%{
+  predicate(n->get_int() == 4);
+  match(ConI);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 operand immI_8()
 %{
   predicate(n->get_int() == 8);
   match(ConI);
 

@@ -10795,10 +10848,11 @@
 
   ins_pipe(ialu_reg_shift);
 %}
 
 // BEGIN This section of the file is automatically generated. Do not edit --------------
+// This section is generated from aarch64_ad.m4
 
 instruct regL_not_reg(iRegLNoSp dst,
                          iRegL src1, immL_M1 m1,
                          rFlagsReg cr) %{
   match(Set dst (XorL src1 m1));

@@ -15985,10 +16039,11 @@
 
 // ====================REDUCTION ARITHMETIC====================================
 
 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp, iRegINoSp tmp2)
 %{
+  predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT);
   match(Set dst (AddReductionVI isrc vsrc));
   ins_cost(INSN_COST);
   effect(TEMP tmp, TEMP tmp2);
   format %{ "umov  $tmp, $vsrc, S, 0\n\t"
             "umov  $tmp2, $vsrc, S, 1\n\t"

@@ -16004,10 +16059,11 @@
   ins_pipe(pipe_class_default);
 %}
 
 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp)
 %{
+  predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT);
   match(Set dst (AddReductionVI isrc vsrc));
   ins_cost(INSN_COST);
   effect(TEMP vtmp, TEMP itmp);
   format %{ "addv  $vtmp, T4S, $vsrc\n\t"
             "umov  $itmp, $vtmp, S, 0\n\t"

@@ -16022,10 +16078,11 @@
   ins_pipe(pipe_class_default);
 %}
 
 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp)
 %{
+  predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT);
   match(Set dst (MulReductionVI isrc vsrc));
   ins_cost(INSN_COST);
   effect(TEMP tmp, TEMP dst);
   format %{ "umov  $tmp, $vsrc, S, 0\n\t"
             "mul   $dst, $tmp, $isrc\n\t"

@@ -16041,10 +16098,11 @@
   ins_pipe(pipe_class_default);
 %}
 
 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp)
 %{
+  predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT);
   match(Set dst (MulReductionVI isrc vsrc));
   ins_cost(INSN_COST);
   effect(TEMP vtmp, TEMP itmp, TEMP dst);
   format %{ "ins   $vtmp, D, $vsrc, 0, 1\n\t"
             "mulv  $vtmp, T2S, $vtmp, $vsrc\n\t"

@@ -17122,12 +17180,11 @@
   predicate(n->as_Vector()->length() == 2);
   match(Set dst (AbsVF src));
   ins_cost(INSN_COST * 3);
   format %{ "fabs  $dst,$src\t# vector (2S)" %}
   ins_encode %{
-    __ fabs(as_FloatRegister($dst$$reg), __ T2S,
-            as_FloatRegister($src$$reg));
+    __ fabs(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg));
   %}
   ins_pipe(vunop_fp64);
 %}
 
 instruct vabs4F(vecX dst, vecX src)

@@ -17135,12 +17192,11 @@
   predicate(n->as_Vector()->length() == 4);
   match(Set dst (AbsVF src));
   ins_cost(INSN_COST * 3);
   format %{ "fabs  $dst,$src\t# vector (4S)" %}
   ins_encode %{
-    __ fabs(as_FloatRegister($dst$$reg), __ T4S,
-            as_FloatRegister($src$$reg));
+    __ fabs(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg));
   %}
   ins_pipe(vunop_fp128);
 %}
 
 instruct vabs2D(vecX dst, vecX src)

@@ -17148,12 +17204,11 @@
   predicate(n->as_Vector()->length() == 2);
   match(Set dst (AbsVD src));
   ins_cost(INSN_COST * 3);
   format %{ "fabs  $dst,$src\t# vector (2D)" %}
   ins_encode %{
-    __ fabs(as_FloatRegister($dst$$reg), __ T2D,
-            as_FloatRegister($src$$reg));
+    __ fabs(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg));
   %}
   ins_pipe(vunop_fp128);
 %}
 
 // --------------------------------- NEG --------------------------------------

@@ -17290,11 +17345,12 @@
   ins_pipe(vlogical128);
 %}
 
 // ------------------------------ Shift ---------------------------------------
 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{
-  predicate(n->as_Vector()->length_in_bytes() == 8);
+  predicate(n->as_Vector()->length_in_bytes() == 4 ||
+            n->as_Vector()->length_in_bytes() == 8);
   match(Set dst (LShiftCntV cnt));
   match(Set dst (RShiftCntV cnt));
   format %{ "dup  $dst, $cnt\t# shift count vector (8B)" %}
   ins_encode %{
     __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg));
< prev index next >