changeset 8459:e563aed0fbf3

8086087: aarch64: add support for 64 bit vectors Summary: Support 64 bit vectors Reviewed-by: kvn, aph
author enevill
date Thu, 25 Jun 2015 08:52:12 +0000
parents f39e296fb4c5
children 7bc779e0d64e
files src/cpu/aarch64/vm/aarch64.ad
diffstat 1 files changed, 696 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/aarch64.ad	Wed Jun 24 09:13:12 2015 +0200
+++ b/src/cpu/aarch64/vm/aarch64.ad	Thu Jun 25 08:52:12 2015 +0000
@@ -796,6 +796,42 @@
     V31, V31_H
 );
 
+// Class for all 64bit vector registers
+reg_class vectord_reg(
+    V0, V0_H,
+    V1, V1_H,
+    V2, V2_H,
+    V3, V3_H,
+    V4, V4_H,
+    V5, V5_H,
+    V6, V6_H,
+    V7, V7_H,
+    V8, V8_H,
+    V9, V9_H,
+    V10, V10_H,
+    V11, V11_H,
+    V12, V12_H,
+    V13, V13_H,
+    V14, V14_H,
+    V15, V15_H,
+    V16, V16_H,
+    V17, V17_H,
+    V18, V18_H,
+    V19, V19_H,
+    V20, V20_H,
+    V21, V21_H,
+    V22, V22_H,
+    V23, V23_H,
+    V24, V24_H,
+    V25, V25_H,
+    V26, V26_H,
+    V27, V27_H,
+    V28, V28_H,
+    V29, V29_H,
+    V30, V30_H,
+    V31, V31_H
+);
+
 // Class for all 128bit vector registers
 reg_class vectorx_reg(
     V0, V0_H, V0_J, V0_K,
@@ -1272,40 +1308,48 @@
 
   if (bottom_type()->isa_vect() != NULL) {
     uint len = 4;
+    uint ireg = ideal_reg();
+    assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector");
     if (cbuf) {
       MacroAssembler _masm(cbuf);
-      uint ireg = ideal_reg();
       assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity");
-      assert(ireg == Op_VecX, "sanity");
       if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
         // stack->stack
         int src_offset = ra_->reg2offset(src_lo);
         int dst_offset = ra_->reg2offset(dst_lo);
         assert((src_offset & 7) && (dst_offset & 7), "unaligned stack offset");
         len = 8;
-        if (src_offset < 512) {
-          __ ldp(rscratch1, rscratch2, Address(sp, src_offset));
-        } else {
+        if (ireg == Op_VecD) {
           __ ldr(rscratch1, Address(sp, src_offset));
-          __ ldr(rscratch2, Address(sp, src_offset+4));
-          len += 4;
-        }
-        if (dst_offset < 512) {
-          __ stp(rscratch1, rscratch2, Address(sp, dst_offset));
+          __ str(rscratch1, Address(sp, dst_offset));
         } else {
-          __ str(rscratch1, Address(sp, dst_offset));
-          __ str(rscratch2, Address(sp, dst_offset+4));
-          len += 4;
+          if (src_offset < 512) {
+            __ ldp(rscratch1, rscratch2, Address(sp, src_offset));
+          } else {
+            __ ldr(rscratch1, Address(sp, src_offset));
+            __ ldr(rscratch2, Address(sp, src_offset+4));
+            len += 4;
+          }
+          if (dst_offset < 512) {
+            __ stp(rscratch1, rscratch2, Address(sp, dst_offset));
+          } else {
+            __ str(rscratch1, Address(sp, dst_offset));
+            __ str(rscratch2, Address(sp, dst_offset+4));
+            len += 4;
+          }
         }
       } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
-        __ orr(as_FloatRegister(Matcher::_regEncode[dst_lo]), __ T16B,
+        __ orr(as_FloatRegister(Matcher::_regEncode[dst_lo]),
+               ireg == Op_VecD ? __ T8B : __ T16B,
                as_FloatRegister(Matcher::_regEncode[src_lo]),
                as_FloatRegister(Matcher::_regEncode[src_lo]));
       } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
-        __ str(as_FloatRegister(Matcher::_regEncode[src_lo]), __ Q,
+        __ str(as_FloatRegister(Matcher::_regEncode[src_lo]),
+               ireg == Op_VecD ? __ D : __ Q,
                Address(sp, ra_->reg2offset(dst_lo)));
       } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) {
-        __ ldr(as_FloatRegister(Matcher::_regEncode[dst_lo]), __ Q,
+        __ ldr(as_FloatRegister(Matcher::_regEncode[dst_lo]),
+               ireg == Op_VecD ? __ D : __ Q,
                Address(sp, ra_->reg2offset(src_lo)));
       } else {
         ShouldNotReachHere();
@@ -1315,17 +1359,22 @@
         // stack->stack
         int src_offset = ra_->reg2offset(src_lo);
         int dst_offset = ra_->reg2offset(dst_lo);
-        if (src_offset < 512) {
-          st->print("ldp  rscratch1, rscratch2, [sp, #%d]", src_offset);
-        } else {
+        if (ireg == Op_VecD) {
           st->print("ldr  rscratch1, [sp, #%d]", src_offset);
-          st->print("\nldr  rscratch2, [sp, #%d]", src_offset+4);
-        }
-        if (dst_offset < 512) {
-          st->print("\nstp  rscratch1, rscratch2, [sp, #%d]", dst_offset);
+          st->print("str  rscratch1, [sp, #%d]", dst_offset);
         } else {
-          st->print("\nstr  rscratch1, [sp, #%d]", dst_offset);
-          st->print("\nstr  rscratch2, [sp, #%d]", dst_offset+4);
+          if (src_offset < 512) {
+            st->print("ldp  rscratch1, rscratch2, [sp, #%d]", src_offset);
+          } else {
+            st->print("ldr  rscratch1, [sp, #%d]", src_offset);
+            st->print("\nldr  rscratch2, [sp, #%d]", src_offset+4);
+          }
+          if (dst_offset < 512) {
+            st->print("\nstp  rscratch1, rscratch2, [sp, #%d]", dst_offset);
+          } else {
+            st->print("\nstr  rscratch1, [sp, #%d]", dst_offset);
+            st->print("\nstr  rscratch2, [sp, #%d]", dst_offset+4);
+          }
         }
         st->print("\t# vector spill, stack to stack");
       } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
@@ -1779,17 +1828,22 @@
   return vector_width_in_bytes(bt)/type2aelembytes(bt);
 }
 const int Matcher::min_vector_size(const BasicType bt) {
-  //return (type2aelembytes(bt) == 1) ? 4 : 2;
-  // For the moment, only support 1 vector size, 128 bits
-  return max_vector_size(bt);
+//  For the moment limit the vector size to 8 bytes
+    int size = 8 / type2aelembytes(bt);
+    if (size < 2) size = 2;
+    return size;
 }
 
 // Vector ideal reg.
 const int Matcher::vector_ideal_reg(int len) {
-  return Op_VecX;
+  switch(len) {
+    case  8: return Op_VecD;
+    case 16: return Op_VecX;
+  }
+  ShouldNotReachHere();
+  return 0;
 }
 
-// Only lowest bits of xmm reg are used for vector shift count.
 const int Matcher::vector_shift_count_ideal_reg(int size) {
   return Op_VecX;
 }
@@ -1801,9 +1855,7 @@
 
 // x86 supports misaligned vectors store/load.
 const bool Matcher::misaligned_vectors_ok() {
-  // TODO fixme
-  // return !AlignVector; // can be changed by flag
-  return false;
+  return !AlignVector; // can be changed by flag
 }
 
 // false => size gets scaled to BytesPerLong, ok.
@@ -2214,13 +2266,13 @@
                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
   %}
 
-  enc_class aarch64_enc_ldrvS(vecX dst, memory mem) %{
+  enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{
     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S,
        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
   %}
 
-  enc_class aarch64_enc_ldrvD(vecX dst, memory mem) %{
+  enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{
     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
     loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D,
        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
@@ -2300,13 +2352,13 @@
                as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
   %}
 
-  enc_class aarch64_enc_strvS(vecX src, memory mem) %{
+  enc_class aarch64_enc_strvS(vecD src, memory mem) %{
     FloatRegister src_reg = as_FloatRegister($src$$reg);
     loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S,
        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
   %}
 
-  enc_class aarch64_enc_strvD(vecX src, memory mem) %{
+  enc_class aarch64_enc_strvD(vecD src, memory mem) %{
     FloatRegister src_reg = as_FloatRegister($src$$reg);
     loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D,
        $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
@@ -4467,6 +4519,16 @@
   interface(REG_INTER);
 %}
 
+operand vecD()
+%{
+  constraint(ALLOC_IN_RC(vectord_reg));
+  match(VecD);
+
+  op_cost(0);
+  format %{ %}
+  interface(REG_INTER);
+%}
+
 operand vecX()
 %{
   constraint(ALLOC_IN_RC(vectorx_reg));
@@ -12513,7 +12575,7 @@
 // ====================VECTOR INSTRUCTIONS=====================================
 
 // Load vector (32 bits)
-instruct loadV4(vecX dst, vmem mem)
+instruct loadV4(vecD dst, vmem mem)
 %{
   predicate(n->as_LoadVector()->memory_size() == 4);
   match(Set dst (LoadVector mem));
@@ -12524,7 +12586,7 @@
 %}
 
 // Load vector (64 bits)
-instruct loadV8(vecX dst, vmem mem)
+instruct loadV8(vecD dst, vmem mem)
 %{
   predicate(n->as_LoadVector()->memory_size() == 8);
   match(Set dst (LoadVector mem));
@@ -12546,7 +12608,7 @@
 %}
 
 // Store Vector (32 bits)
-instruct storeV4(vecX src, vmem mem)
+instruct storeV4(vecD src, vmem mem)
 %{
   predicate(n->as_StoreVector()->memory_size() == 4);
   match(Set mem (StoreVector mem src));
@@ -12557,7 +12619,7 @@
 %}
 
 // Store Vector (64 bits)
-instruct storeV8(vecX src, vmem mem)
+instruct storeV8(vecD src, vmem mem)
 %{
   predicate(n->as_StoreVector()->memory_size() == 8);
   match(Set mem (StoreVector mem src));
@@ -12578,8 +12640,22 @@
   ins_pipe(pipe_class_memory);
 %}
 
+instruct replicate8B(vecD dst, iRegIorL2I src)
+%{
+  predicate(n->as_Vector()->length() == 4 ||
+            n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateB src));
+  ins_cost(INSN_COST);
+  format %{ "dup  $dst, $src\t# vector (8B)" %}
+  ins_encode %{
+    __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct replicate16B(vecX dst, iRegIorL2I src)
 %{
+  predicate(n->as_Vector()->length() == 16);
   match(Set dst (ReplicateB src));
   ins_cost(INSN_COST);
   format %{ "dup  $dst, $src\t# vector (16B)" %}
@@ -12589,8 +12665,22 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct replicate8B_imm(vecD dst, immI con)
+%{
+  predicate(n->as_Vector()->length() == 4 ||
+            n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateB con));
+  ins_cost(INSN_COST);
+  format %{ "movi  $dst, $con\t# vector(8B)" %}
+  ins_encode %{
+    __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct replicate16B_imm(vecX dst, immI con)
 %{
+  predicate(n->as_Vector()->length() == 16);
   match(Set dst (ReplicateB con));
   ins_cost(INSN_COST);
   format %{ "movi  $dst, $con\t# vector(16B)" %}
@@ -12600,8 +12690,22 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct replicate4S(vecD dst, iRegIorL2I src)
+%{
+  predicate(n->as_Vector()->length() == 2 ||
+            n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateS src));
+  ins_cost(INSN_COST);
+  format %{ "dup  $dst, $src\t# vector (4S)" %}
+  ins_encode %{
+    __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct replicate8S(vecX dst, iRegIorL2I src)
 %{
+  predicate(n->as_Vector()->length() == 8);
   match(Set dst (ReplicateS src));
   ins_cost(INSN_COST);
   format %{ "dup  $dst, $src\t# vector (8S)" %}
@@ -12611,8 +12715,22 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct replicate4S_imm(vecD dst, immI con)
+%{
+  predicate(n->as_Vector()->length() == 2 ||
+            n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateS con));
+  ins_cost(INSN_COST);
+  format %{ "movi  $dst, $con\t# vector(4H)" %}
+  ins_encode %{
+    __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct replicate8S_imm(vecX dst, immI con)
 %{
+  predicate(n->as_Vector()->length() == 8);
   match(Set dst (ReplicateS con));
   ins_cost(INSN_COST);
   format %{ "movi  $dst, $con\t# vector(8H)" %}
@@ -12622,8 +12740,21 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct replicate2I(vecD dst, iRegIorL2I src)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateI src));
+  ins_cost(INSN_COST);
+  format %{ "dup  $dst, $src\t# vector (2I)" %}
+  ins_encode %{
+    __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct replicate4I(vecX dst, iRegIorL2I src)
 %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (ReplicateI src));
   ins_cost(INSN_COST);
   format %{ "dup  $dst, $src\t# vector (4I)" %}
@@ -12633,8 +12764,21 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct replicate2I_imm(vecD dst, immI con)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateI con));
+  ins_cost(INSN_COST);
+  format %{ "movi  $dst, $con\t# vector(2I)" %}
+  ins_encode %{
+    __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct replicate4I_imm(vecX dst, immI con)
 %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (ReplicateI con));
   ins_cost(INSN_COST);
   format %{ "movi  $dst, $con\t# vector(4I)" %}
@@ -12646,6 +12790,7 @@
 
 instruct replicate2L(vecX dst, iRegL src)
 %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (ReplicateL src));
   ins_cost(INSN_COST);
   format %{ "dup  $dst, $src\t# vector (2L)" %}
@@ -12657,6 +12802,7 @@
 
 instruct replicate2L_zero(vecX dst, immI0 zero)
 %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (ReplicateI zero));
   ins_cost(INSN_COST);
   format %{ "movi  $dst, $zero\t# vector(4I)" %}
@@ -12668,8 +12814,22 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct replicate2F(vecD dst, vRegF src)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateF src));
+  ins_cost(INSN_COST);
+  format %{ "dup  $dst, $src\t# vector (2F)" %}
+  ins_encode %{
+    __ dup(as_FloatRegister($dst$$reg), __ T2S,
+           as_FloatRegister($src$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct replicate4F(vecX dst, vRegF src)
 %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (ReplicateF src));
   ins_cost(INSN_COST);
   format %{ "dup  $dst, $src\t# vector (4F)" %}
@@ -12682,6 +12842,7 @@
 
 instruct replicate2D(vecX dst, vRegD src)
 %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (ReplicateD src));
   ins_cost(INSN_COST);
   format %{ "dup  $dst, $src\t# vector (2D)" %}
@@ -12696,8 +12857,24 @@
 
 // --------------------------------- ADD --------------------------------------
 
+instruct vadd8B(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 4 ||
+            n->as_Vector()->length() == 8);
+  match(Set dst (AddVB src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "addv  $dst,$src1,$src2\t# vector (8B)" %}
+  ins_encode %{
+    __ addv(as_FloatRegister($dst$$reg), __ T8B,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vadd16B(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 16);
   match(Set dst (AddVB src1 src2));
   ins_cost(INSN_COST);
   format %{ "addv  $dst,$src1,$src2\t# vector (16B)" %}
@@ -12709,8 +12886,24 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vadd4S(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 2 ||
+            n->as_Vector()->length() == 4);
+  match(Set dst (AddVS src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "addv  $dst,$src1,$src2\t# vector (4H)" %}
+  ins_encode %{
+    __ addv(as_FloatRegister($dst$$reg), __ T4H,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vadd8S(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 8);
   match(Set dst (AddVS src1 src2));
   ins_cost(INSN_COST);
   format %{ "addv  $dst,$src1,$src2\t# vector (8H)" %}
@@ -12722,8 +12915,23 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vadd2I(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (AddVI src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "addv  $dst,$src1,$src2\t# vector (2S)" %}
+  ins_encode %{
+    __ addv(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vadd4I(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (AddVI src1 src2));
   ins_cost(INSN_COST);
   format %{ "addv  $dst,$src1,$src2\t# vector (4S)" %}
@@ -12737,6 +12945,7 @@
 
 instruct vadd2L(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (AddVL src1 src2));
   ins_cost(INSN_COST);
   format %{ "addv  $dst,$src1,$src2\t# vector (2L)" %}
@@ -12748,8 +12957,23 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vadd2F(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (AddVF src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "fadd  $dst,$src1,$src2\t# vector (2S)" %}
+  ins_encode %{
+    __ fadd(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vadd4F(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (AddVF src1 src2));
   ins_cost(INSN_COST);
   format %{ "fadd  $dst,$src1,$src2\t# vector (4S)" %}
@@ -12776,8 +13000,24 @@
 
 // --------------------------------- SUB --------------------------------------
 
+instruct vsub8B(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 4 ||
+            n->as_Vector()->length() == 8);
+  match(Set dst (SubVB src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "subv  $dst,$src1,$src2\t# vector (8B)" %}
+  ins_encode %{
+    __ subv(as_FloatRegister($dst$$reg), __ T8B,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsub16B(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 16);
   match(Set dst (SubVB src1 src2));
   ins_cost(INSN_COST);
   format %{ "subv  $dst,$src1,$src2\t# vector (16B)" %}
@@ -12789,8 +13029,24 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsub4S(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 2 ||
+            n->as_Vector()->length() == 4);
+  match(Set dst (SubVS src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "subv  $dst,$src1,$src2\t# vector (4H)" %}
+  ins_encode %{
+    __ subv(as_FloatRegister($dst$$reg), __ T4H,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsub8S(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 8);
   match(Set dst (SubVS src1 src2));
   ins_cost(INSN_COST);
   format %{ "subv  $dst,$src1,$src2\t# vector (8H)" %}
@@ -12802,8 +13058,23 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsub2I(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (SubVI src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "subv  $dst,$src1,$src2\t# vector (2S)" %}
+  ins_encode %{
+    __ subv(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsub4I(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (SubVI src1 src2));
   ins_cost(INSN_COST);
   format %{ "subv  $dst,$src1,$src2\t# vector (4S)" %}
@@ -12817,6 +13088,7 @@
 
 instruct vsub2L(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (SubVL src1 src2));
   ins_cost(INSN_COST);
   format %{ "subv  $dst,$src1,$src2\t# vector (2L)" %}
@@ -12828,8 +13100,23 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsub2F(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (AddVF src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "fsub  $dst,$src1,$src2\t# vector (2S)" %}
+  ins_encode %{
+    __ fsub(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsub4F(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (SubVF src1 src2));
   ins_cost(INSN_COST);
   format %{ "fsub  $dst,$src1,$src2\t# vector (4S)" %}
@@ -12843,6 +13130,7 @@
 
 instruct vsub2D(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (SubVD src1 src2));
   ins_cost(INSN_COST);
   format %{ "fsub  $dst,$src1,$src2\t# vector (2D)" %}
@@ -12856,8 +13144,24 @@
 
 // --------------------------------- MUL --------------------------------------
 
+instruct vmul4S(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 2 ||
+            n->as_Vector()->length() == 4);
+  match(Set dst (MulVS src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "mulv  $dst,$src1,$src2\t# vector (4H)" %}
+  ins_encode %{
+    __ mulv(as_FloatRegister($dst$$reg), __ T4H,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vmul8S(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 8);
   match(Set dst (MulVS src1 src2));
   ins_cost(INSN_COST);
   format %{ "mulv  $dst,$src1,$src2\t# vector (8H)" %}
@@ -12869,8 +13173,23 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vmul2I(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (MulVI src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "mulv  $dst,$src1,$src2\t# vector (2S)" %}
+  ins_encode %{
+    __ mulv(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vmul4I(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (MulVI src1 src2));
   ins_cost(INSN_COST);
   format %{ "mulv  $dst,$src1,$src2\t# vector (4S)" %}
@@ -12882,8 +13201,23 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vmul2F(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (MulVF src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "fmul  $dst,$src1,$src2\t# vector (2S)" %}
+  ins_encode %{
+    __ fmul(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vmul4F(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (MulVF src1 src2));
   ins_cost(INSN_COST);
   format %{ "fmul  $dst,$src1,$src2\t# vector (4S)" %}
@@ -12897,6 +13231,7 @@
 
 instruct vmul2D(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (MulVD src1 src2));
   ins_cost(INSN_COST);
   format %{ "fmul  $dst,$src1,$src2\t# vector (2D)" %}
@@ -12910,8 +13245,23 @@
 
 // --------------------------------- DIV --------------------------------------
 
+instruct vdiv2F(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (DivVF src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "fdiv  $dst,$src1,$src2\t# vector (2S)" %}
+  ins_encode %{
+    __ fdiv(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vdiv4F(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (DivVF src1 src2));
   ins_cost(INSN_COST);
   format %{ "fdiv  $dst,$src1,$src2\t# vector (4S)" %}
@@ -12925,6 +13275,7 @@
 
 instruct vdiv2D(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (DivVD src1 src2));
   ins_cost(INSN_COST);
   format %{ "fdiv  $dst,$src1,$src2\t# vector (2D)" %}
@@ -12938,8 +13289,24 @@
 
 // --------------------------------- AND --------------------------------------
 
+instruct vand8B(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length_in_bytes() == 4 ||
+            n->as_Vector()->length_in_bytes() == 8);
+  match(Set dst (AndV src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "and  $dst,$src1,$src2\t# vector (8B)" %}
+  ins_encode %{
+    __ andr(as_FloatRegister($dst$$reg), __ T8B,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vand16B(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length_in_bytes() == 16);
   match(Set dst (AndV src1 src2));
   ins_cost(INSN_COST);
   format %{ "and  $dst,$src1,$src2\t# vector (16B)" %}
@@ -12953,8 +13320,24 @@
 
 // --------------------------------- OR ---------------------------------------
 
+instruct vor8B(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length_in_bytes() == 4 ||
+            n->as_Vector()->length_in_bytes() == 8);
+  match(Set dst (OrV src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "and  $dst,$src1,$src2\t# vector (8B)" %}
+  ins_encode %{
+    __ orr(as_FloatRegister($dst$$reg), __ T8B,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vor16B(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length_in_bytes() == 16);
   match(Set dst (OrV src1 src2));
   ins_cost(INSN_COST);
   format %{ "orr  $dst,$src1,$src2\t# vector (16B)" %}
@@ -12968,8 +13351,24 @@
 
 // --------------------------------- XOR --------------------------------------
 
+instruct vxor8B(vecD dst, vecD src1, vecD src2)
+%{
+  predicate(n->as_Vector()->length_in_bytes() == 4 ||
+            n->as_Vector()->length_in_bytes() == 8);
+  match(Set dst (XorV src1 src2));
+  ins_cost(INSN_COST);
+  format %{ "xor  $dst,$src1,$src2\t# vector (8B)" %}
+  ins_encode %{
+    __ eor(as_FloatRegister($dst$$reg), __ T8B,
+            as_FloatRegister($src1$$reg),
+            as_FloatRegister($src2$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vxor16B(vecX dst, vecX src1, vecX src2)
 %{
+  predicate(n->as_Vector()->length_in_bytes() == 16);
   match(Set dst (XorV src1 src2));
   ins_cost(INSN_COST);
   format %{ "xor  $dst,$src1,$src2\t# vector (16B)" %}
@@ -13003,7 +13402,23 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsll8B(vecD dst, vecD src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 4 ||
+            n->as_Vector()->length() == 8);
+  match(Set dst (LShiftVB src shift));
+  match(Set dst (RShiftVB src shift));
+  ins_cost(INSN_COST);
+  format %{ "sshl  $dst,$src,$shift\t# vector (8B)" %}
+  ins_encode %{
+    __ sshl(as_FloatRegister($dst$$reg), __ T8B,
+            as_FloatRegister($src$$reg),
+            as_FloatRegister($shift$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsll16B(vecX dst, vecX src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 16);
   match(Set dst (LShiftVB src shift));
   match(Set dst (RShiftVB src shift));
   ins_cost(INSN_COST);
@@ -13016,7 +13431,22 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsrl8B(vecD dst, vecD src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 4 ||
+            n->as_Vector()->length() == 8);
+  match(Set dst (URShiftVB src shift));
+  ins_cost(INSN_COST);
+  format %{ "ushl  $dst,$src,$shift\t# vector (8B)" %}
+  ins_encode %{
+    __ ushl(as_FloatRegister($dst$$reg), __ T8B,
+            as_FloatRegister($src$$reg),
+            as_FloatRegister($shift$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsrl16B(vecX dst, vecX src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 16);
   match(Set dst (URShiftVB src shift));
   ins_cost(INSN_COST);
   format %{ "ushl  $dst,$src,$shift\t# vector (16B)" %}
@@ -13028,7 +13458,28 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{
+  predicate(n->as_Vector()->length() == 4 ||
+            n->as_Vector()->length() == 8);
+  match(Set dst (LShiftVB src shift));
+  ins_cost(INSN_COST);
+  format %{ "shl    $dst, $src, $shift\t# vector (8B)" %}
+  ins_encode %{
+    int sh = (int)$shift$$constant & 31;
+    if (sh >= 8) {
+      __ eor(as_FloatRegister($dst$$reg), __ T8B,
+             as_FloatRegister($src$$reg),
+             as_FloatRegister($src$$reg));
+    } else {
+      __ shl(as_FloatRegister($dst$$reg), __ T8B,
+             as_FloatRegister($src$$reg), sh);
+    }
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 16);
   match(Set dst (LShiftVB src shift));
   ins_cost(INSN_COST);
   format %{ "shl    $dst, $src, $shift\t# vector (16B)" %}
@@ -13046,7 +13497,24 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{
+  predicate(n->as_Vector()->length() == 4 ||
+            n->as_Vector()->length() == 8);
+  match(Set dst (RShiftVB src shift));
+  ins_cost(INSN_COST);
+  format %{ "sshr    $dst, $src, $shift\t# vector (8B)" %}
+  ins_encode %{
+    int sh = (int)$shift$$constant & 31;
+    if (sh >= 8) sh = 7;
+    sh = -sh & 7;
+    __ sshr(as_FloatRegister($dst$$reg), __ T8B,
+           as_FloatRegister($src$$reg), sh);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 16);
   match(Set dst (RShiftVB src shift));
   ins_cost(INSN_COST);
   format %{ "sshr    $dst, $src, $shift\t# vector (16B)" %}
@@ -13060,7 +13528,28 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{
+  predicate(n->as_Vector()->length() == 4 ||
+            n->as_Vector()->length() == 8);
+  match(Set dst (URShiftVB src shift));
+  ins_cost(INSN_COST);
+  format %{ "ushr    $dst, $src, $shift\t# vector (8B)" %}
+  ins_encode %{
+    int sh = (int)$shift$$constant & 31;
+    if (sh >= 8) {
+      __ eor(as_FloatRegister($dst$$reg), __ T8B,
+             as_FloatRegister($src$$reg),
+             as_FloatRegister($src$$reg));
+    } else {
+      __ ushr(as_FloatRegister($dst$$reg), __ T8B,
+             as_FloatRegister($src$$reg), -sh & 7);
+    }
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 16);
   match(Set dst (URShiftVB src shift));
   ins_cost(INSN_COST);
   format %{ "ushr    $dst, $src, $shift\t# vector (16B)" %}
@@ -13078,7 +13567,23 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsll4S(vecD dst, vecD src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 2 ||
+            n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVS src shift));
+  match(Set dst (RShiftVS src shift));
+  ins_cost(INSN_COST);
+  format %{ "sshl  $dst,$src,$shift\t# vector (4H)" %}
+  ins_encode %{
+    __ sshl(as_FloatRegister($dst$$reg), __ T4H,
+            as_FloatRegister($src$$reg),
+            as_FloatRegister($shift$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsll8S(vecX dst, vecX src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 8);
   match(Set dst (LShiftVS src shift));
   match(Set dst (RShiftVS src shift));
   ins_cost(INSN_COST);
@@ -13091,7 +13596,22 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsrl4S(vecD dst, vecD src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 2 ||
+            n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVS src shift));
+  ins_cost(INSN_COST);
+  format %{ "ushl  $dst,$src,$shift\t# vector (4H)" %}
+  ins_encode %{
+    __ ushl(as_FloatRegister($dst$$reg), __ T4H,
+            as_FloatRegister($src$$reg),
+            as_FloatRegister($shift$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsrl8S(vecX dst, vecX src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 8);
   match(Set dst (URShiftVS src shift));
   ins_cost(INSN_COST);
   format %{ "ushl  $dst,$src,$shift\t# vector (8H)" %}
@@ -13103,7 +13623,28 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{
+  predicate(n->as_Vector()->length() == 2 ||
+            n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVS src shift));
+  ins_cost(INSN_COST);
+  format %{ "shl    $dst, $src, $shift\t# vector (4H)" %}
+  ins_encode %{
+    int sh = (int)$shift$$constant & 31;
+    if (sh >= 16) {
+      __ eor(as_FloatRegister($dst$$reg), __ T8B,
+             as_FloatRegister($src$$reg),
+             as_FloatRegister($src$$reg));
+    } else {
+      __ shl(as_FloatRegister($dst$$reg), __ T4H,
+             as_FloatRegister($src$$reg), sh);
+    }
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 8);
   match(Set dst (LShiftVS src shift));
   ins_cost(INSN_COST);
   format %{ "shl    $dst, $src, $shift\t# vector (8H)" %}
@@ -13121,7 +13662,24 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{
+  predicate(n->as_Vector()->length() == 2 ||
+            n->as_Vector()->length() == 4);
+  match(Set dst (RShiftVS src shift));
+  ins_cost(INSN_COST);
+  format %{ "sshr    $dst, $src, $shift\t# vector (4H)" %}
+  ins_encode %{
+    int sh = (int)$shift$$constant & 31;
+    if (sh >= 16) sh = 15;
+    sh = -sh & 15;
+    __ sshr(as_FloatRegister($dst$$reg), __ T4H,
+           as_FloatRegister($src$$reg), sh);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 8);
   match(Set dst (RShiftVS src shift));
   ins_cost(INSN_COST);
   format %{ "sshr    $dst, $src, $shift\t# vector (8H)" %}
@@ -13135,7 +13693,28 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{
+  predicate(n->as_Vector()->length() == 2 ||
+            n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVS src shift));
+  ins_cost(INSN_COST);
+  format %{ "ushr    $dst, $src, $shift\t# vector (4H)" %}
+  ins_encode %{
+    int sh = (int)$shift$$constant & 31;
+    if (sh >= 16) {
+      __ eor(as_FloatRegister($dst$$reg), __ T8B,
+             as_FloatRegister($src$$reg),
+             as_FloatRegister($src$$reg));
+    } else {
+      __ ushr(as_FloatRegister($dst$$reg), __ T4H,
+             as_FloatRegister($src$$reg), -sh & 15);
+    }
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 8);
   match(Set dst (URShiftVS src shift));
   ins_cost(INSN_COST);
   format %{ "ushr    $dst, $src, $shift\t# vector (8H)" %}
@@ -13153,7 +13732,22 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsll2I(vecD dst, vecD src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVI src shift));
+  match(Set dst (RShiftVI src shift));
+  ins_cost(INSN_COST);
+  format %{ "sshl  $dst,$src,$shift\t# vector (2S)" %}
+  ins_encode %{
+    __ sshl(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src$$reg),
+            as_FloatRegister($shift$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsll4I(vecX dst, vecX src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (LShiftVI src shift));
   match(Set dst (RShiftVI src shift));
   ins_cost(INSN_COST);
@@ -13166,7 +13760,21 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsrl2I(vecD dst, vecD src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVI src shift));
+  ins_cost(INSN_COST);
+  format %{ "ushl  $dst,$src,$shift\t# vector (2S)" %}
+  ins_encode %{
+    __ ushl(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src$$reg),
+            as_FloatRegister($shift$$reg));
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsrl4I(vecX dst, vecX src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (URShiftVI src shift));
   ins_cost(INSN_COST);
   format %{ "ushl  $dst,$src,$shift\t# vector (4S)" %}
@@ -13178,7 +13786,21 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVI src shift));
+  ins_cost(INSN_COST);
+  format %{ "shl    $dst, $src, $shift\t# vector (2S)" %}
+  ins_encode %{
+    __ shl(as_FloatRegister($dst$$reg), __ T2S,
+           as_FloatRegister($src$$reg),
+           (int)$shift$$constant & 31);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (LShiftVI src shift));
   ins_cost(INSN_COST);
   format %{ "shl    $dst, $src, $shift\t# vector (4S)" %}
@@ -13190,7 +13812,21 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (RShiftVI src shift));
+  ins_cost(INSN_COST);
+  format %{ "sshr    $dst, $src, $shift\t# vector (2S)" %}
+  ins_encode %{
+    __ sshr(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src$$reg),
+            -(int)$shift$$constant & 31);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (RShiftVI src shift));
   ins_cost(INSN_COST);
   format %{ "sshr    $dst, $src, $shift\t# vector (4S)" %}
@@ -13202,7 +13838,21 @@
   ins_pipe(pipe_class_default);
 %}
 
+instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVI src shift));
+  ins_cost(INSN_COST);
+  format %{ "ushr    $dst, $src, $shift\t# vector (2S)" %}
+  ins_encode %{
+    __ ushr(as_FloatRegister($dst$$reg), __ T2S,
+            as_FloatRegister($src$$reg),
+            -(int)$shift$$constant & 31);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (URShiftVI src shift));
   ins_cost(INSN_COST);
   format %{ "ushr    $dst, $src, $shift\t# vector (4S)" %}
@@ -13215,6 +13865,7 @@
 %}
 
 instruct vsll2L(vecX dst, vecX src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (LShiftVL src shift));
   match(Set dst (RShiftVL src shift));
   ins_cost(INSN_COST);
@@ -13228,6 +13879,7 @@
 %}
 
 instruct vsrl2L(vecX dst, vecX src, vecX shift) %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (URShiftVL src shift));
   ins_cost(INSN_COST);
   format %{ "ushl  $dst,$src,$shift\t# vector (2D)" %}
@@ -13240,6 +13892,7 @@
 %}
 
 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (LShiftVL src shift));
   ins_cost(INSN_COST);
   format %{ "shl    $dst, $src, $shift\t# vector (2D)" %}
@@ -13252,6 +13905,7 @@
 %}
 
 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (RShiftVL src shift));
   ins_cost(INSN_COST);
   format %{ "sshr    $dst, $src, $shift\t# vector (2D)" %}
@@ -13264,6 +13918,7 @@
 %}
 
 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (URShiftVL src shift));
   ins_cost(INSN_COST);
   format %{ "ushr    $dst, $src, $shift\t# vector (2D)" %}