Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: IBM424.nr   Sprache: C

Columbo aufrufen.ad zum Wurzelverzeichnis wechselnHaskell {Haskell[133] C[143] BAT[337]}Datei anzeigen

//
// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2020, Arm Limited. All rights reserved.
// Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License version 2 only, as
// published by the Free Software Foundation.
//
// This code is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// version 2 for more details (a copy is included in the LICENSE file that
// accompanied this code).
//
// You should have received a copy of the GNU General Public License version
// 2 along with this work; if not, write to the Free Software Foundation,
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
// or visit www.oracle.com if you need additional information or have any
// questions.
//
//

// RISCV Vector Extension Architecture Description File

opclass vmemA(indirect);

source_hpp %{
  bool op_vec_supported(int opcode);
%}

source %{

  static void loadStore(C2_MacroAssembler masm, bool is_store,
                        VectorRegister reg, BasicType bt, Register base) {
    Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
    masm.vsetvli(t0, x0, sew);
    if (is_store) {
      masm.vsex_v(reg, base, sew);
    } else {
      masm.vlex_v(reg, base, sew);
    }
  }

  bool op_vec_supported(int opcode) {
    switch (opcode) {
      // No multiply reduction instructions
      case Op_MulReductionVD:
      case Op_MulReductionVF:
      case Op_MulReductionVI:
      case Op_MulReductionVL:
      // Others
      case Op_Extract:
      case Op_ExtractB:
      case Op_ExtractC:
      case Op_ExtractD:
      case Op_ExtractF:
      case Op_ExtractI:
      case Op_ExtractL:
      case Op_ExtractS:
      case Op_ExtractUB:
      // Vector API specific
      case Op_LoadVectorGather:
      case Op_StoreVectorScatter:
      case Op_VectorBlend:
      case Op_VectorCast:
      case Op_VectorCastB2X:
      case Op_VectorCastD2X:
      case Op_VectorCastF2X:
      case Op_VectorCastI2X:
      case Op_VectorCastL2X:
      case Op_VectorCastS2X:
      case Op_VectorInsert:
      case Op_VectorLoadMask:
      case Op_VectorLoadShuffle:
      case Op_VectorMaskCmp:
      case Op_VectorRearrange:
      case Op_VectorReinterpret:
      case Op_VectorStoreMask:
      case Op_VectorTest:
      case Op_PopCountVI:
      case Op_PopCountVL:
        return false;
      default:
        return UseRVV;
    }
  }

%}

definitions %{
  int_def VEC_COST             (200, 200);
%}

// All VEC instructions

// vector load/store
instruct loadV(vReg dst, vmemA mem) %{
  match(Set dst (LoadVector mem));
  ins_cost(VEC_COST);
  format %{ "vle $dst, $mem\t#@loadV" %}
  ins_encode %{
    VectorRegister dst_reg = as_VectorRegister($dst$$reg);
    loadStore(C2_MacroAssembler(&cbuf), false, dst_reg,
              Matcher::vector_element_basic_type(this), as_Register($mem$$base));
  %}
  ins_pipe(pipe_slow);
%}

instruct storeV(vReg src, vmemA mem) %{
  match(Set mem (StoreVector mem src));
  ins_cost(VEC_COST);
  format %{ "vse $src, $mem\t#@storeV" %}
  ins_encode %{
    VectorRegister src_reg = as_VectorRegister($src$$reg);
    loadStore(C2_MacroAssembler(&cbuf), true, src_reg,
              Matcher::vector_element_basic_type(this, $src), as_Register($mem$$base));
  %}
  ins_pipe(pipe_slow);
%}

// vector abs

instruct vabsB(vReg dst, vReg src, vReg tmp) %{
  match(Set dst (AbsVB src));
  ins_cost(VEC_COST);
  effect(TEMP tmp);
  format %{ "vrsub.vi $tmp, 0, $src\t#@vabsB\n\t"
            "vmax.vv $dst, $tmp, $src" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    __ vrsub_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg), 0);
    __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vabsS(vReg dst, vReg src, vReg tmp) %{
  match(Set dst (AbsVS src));
  ins_cost(VEC_COST);
  effect(TEMP tmp);
  format %{ "vrsub.vi $tmp, 0, $src\t#@vabsS\n\t"
            "vmax.vv $dst, $tmp, $src" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    __ vrsub_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg), 0);
    __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vabsI(vReg dst, vReg src, vReg tmp) %{
  match(Set dst (AbsVI src));
  ins_cost(VEC_COST);
  effect(TEMP tmp);
  format %{ "vrsub.vi $tmp, 0, $src\t#@vabsI\n\t"
            "vmax.vv $dst, $tmp, $src" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vrsub_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg), 0);
    __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vabsL(vReg dst, vReg src, vReg tmp) %{
  match(Set dst (AbsVL src));
  ins_cost(VEC_COST);
  effect(TEMP tmp);
  format %{ "vrsub.vi $tmp, 0, $src\t#@vabsL\n\t"
            "vmax.vv $dst, $tmp, $src" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vrsub_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg), 0);
    __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vabsF(vReg dst, vReg src) %{
  match(Set dst (AbsVF src));
  ins_cost(VEC_COST);
  format %{ "vfsgnjx.vv $dst, $src, $src, vm\t#@vabsF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfsgnjx_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vabsD(vReg dst, vReg src) %{
  match(Set dst (AbsVD src));
  ins_cost(VEC_COST);
  format %{ "vfsgnjx.vv $dst, $src, $src, vm\t#@vabsD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfsgnjx_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector add

instruct vaddB(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (AddVB src1 src2));
  ins_cost(VEC_COST);
  format %{ "vadd.vv $dst, $src1, $src2\t#@vaddB" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    __ vadd_vv(as_VectorRegister($dst$$reg),
               as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vaddS(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (AddVS src1 src2));
  ins_cost(VEC_COST);
  format %{ "vadd.vv $dst, $src1, $src2\t#@vaddS" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    __ vadd_vv(as_VectorRegister($dst$$reg),
               as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vaddI(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (AddVI src1 src2));
  ins_cost(VEC_COST);
  format %{ "vadd.vv $dst, $src1, $src2\t#@vaddI" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vadd_vv(as_VectorRegister($dst$$reg),
               as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vaddL(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (AddVL src1 src2));
  ins_cost(VEC_COST);
  format %{ "vadd.vv $dst, $src1, $src2\t#@vaddL" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vadd_vv(as_VectorRegister($dst$$reg),
               as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vaddF(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (AddVF src1 src2));
  ins_cost(VEC_COST);
  format %{ "vfadd.vv $dst, $src1, $src2\t#@vaddF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfadd_vv(as_VectorRegister($dst$$reg),
                as_VectorRegister($src1$$reg),
                as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vaddD(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (AddVD src1 src2));
  ins_cost(VEC_COST);
  format %{ "vfadd.vv $dst, $src1, $src2\t#@vaddD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfadd_vv(as_VectorRegister($dst$$reg),
                as_VectorRegister($src1$$reg),
                as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector and

instruct vand(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (AndV src1 src2));
  ins_cost(VEC_COST);
  format %{ "vand.vv $dst, $src1, $src2\t#@vand" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vand_vv(as_VectorRegister($dst$$reg),
               as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector or

instruct vor(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (OrV src1 src2));
  ins_cost(VEC_COST);
  format %{ "vor.vv $dst, $src1, $src2\t#@vor" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vor_vv(as_VectorRegister($dst$$reg),
              as_VectorRegister($src1$$reg),
              as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector xor

instruct vxor(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (XorV src1 src2));
  ins_cost(VEC_COST);
  format %{ "vxor.vv $dst, $src1, $src2\t#@vxor" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vxor_vv(as_VectorRegister($dst$$reg),
               as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector float div

instruct vdivF(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (DivVF src1 src2));
  ins_cost(VEC_COST);
  format %{ "vfdiv.vv $dst, $src1, $src2\t#@vdivF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfdiv_vv(as_VectorRegister($dst$$reg),
                as_VectorRegister($src1$$reg),
                as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vdivD(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (DivVD src1 src2));
  ins_cost(VEC_COST);
  format %{ "vfdiv.vv $dst, $src1, $src2\t#@vdivD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfdiv_vv(as_VectorRegister($dst$$reg),
                as_VectorRegister($src1$$reg),
                as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector integer max/min

instruct vmax(vReg dst, vReg src1, vReg src2) %{
  predicate(Matcher::vector_element_basic_type(n) != T_FLOAT &&
            Matcher::vector_element_basic_type(n) != T_DOUBLE);
  match(Set dst (MaxV src1 src2));
  ins_cost(VEC_COST);
  format %{ "vmax.vv $dst, $src1, $src2\t#@vmax" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this);
    Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
    __ vsetvli(t0, x0, sew);
    __ vmax_vv(as_VectorRegister($dst$$reg),
               as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vmin(vReg dst, vReg src1, vReg src2) %{
  predicate(Matcher::vector_element_basic_type(n) != T_FLOAT &&
            Matcher::vector_element_basic_type(n) != T_DOUBLE);
  match(Set dst (MinV src1 src2));
  ins_cost(VEC_COST);
  format %{ "vmin.vv $dst, $src1, $src2\t#@vmin" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this);
    Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
    __ vsetvli(t0, x0, sew);
    __ vmin_vv(as_VectorRegister($dst$$reg),
               as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector float-point max/min

instruct vmaxF(vReg dst, vReg src1, vReg src2) %{
  predicate(Matcher::vector_element_basic_type(n) == T_FLOAT);
  match(Set dst (MaxV src1 src2));
  effect(TEMP_DEF dst);
  ins_cost(VEC_COST);
  format %{ "vmaxF $dst, $src1, $src2\t#@vmaxF" %}
  ins_encode %{
    __ minmax_FD_v(as_VectorRegister($dst$$reg),
                   as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
                   false /* is_double */, false /* is_min */);
  %}
  ins_pipe(pipe_slow);
%}

instruct vmaxD(vReg dst, vReg src1, vReg src2) %{
  predicate(Matcher::vector_element_basic_type(n) == T_DOUBLE);
  match(Set dst (MaxV src1 src2));
  effect(TEMP_DEF dst);
  ins_cost(VEC_COST);
  format %{ "vmaxD $dst, $src1, $src2\t#@vmaxD" %}
  ins_encode %{
    __ minmax_FD_v(as_VectorRegister($dst$$reg),
                   as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
                   true /* is_double */, false /* is_min */);
  %}
  ins_pipe(pipe_slow);
%}

instruct vminF(vReg dst, vReg src1, vReg src2) %{
  predicate(Matcher::vector_element_basic_type(n) == T_FLOAT);
  match(Set dst (MinV src1 src2));
  effect(TEMP_DEF dst);
  ins_cost(VEC_COST);
  format %{ "vminF $dst, $src1, $src2\t#@vminF" %}
  ins_encode %{
    __ minmax_FD_v(as_VectorRegister($dst$$reg),
                   as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
                   false /* is_double */, true /* is_min */);
  %}
  ins_pipe(pipe_slow);
%}

instruct vminD(vReg dst, vReg src1, vReg src2) %{
  predicate(Matcher::vector_element_basic_type(n) == T_DOUBLE);
  match(Set dst (MinV src1 src2));
  effect(TEMP_DEF dst);
  ins_cost(VEC_COST);
  format %{ "vminD $dst, $src1, $src2\t#@vminD" %}
  ins_encode %{
    __ minmax_FD_v(as_VectorRegister($dst$$reg),
                   as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
                   true /* is_double */, true /* is_min */);
  %}
  ins_pipe(pipe_slow);
%}

// vector fmla

// dst_src1 = dst_src1 + src2 * src3
instruct vfmlaF(vReg dst_src1, vReg src2, vReg src3) %{
  predicate(UseFMA);
  match(Set dst_src1 (FmaVF dst_src1 (Binary src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vfmacc.vv $dst_src1, $src2, $src3\t#@vfmlaF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfmacc_vv(as_VectorRegister($dst_src1$$reg),
                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// dst_src1 = dst_src1 + src2 * src3
instruct vfmlaD(vReg dst_src1, vReg src2, vReg src3) %{
  predicate(UseFMA);
  match(Set dst_src1 (FmaVD dst_src1 (Binary src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vfmacc.vv $dst_src1, $src2, $src3\t#@vfmlaD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfmacc_vv(as_VectorRegister($dst_src1$$reg),
                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector fmls

// dst_src1 = dst_src1 + -src2 * src3
// dst_src1 = dst_src1 + src2 * -src3
instruct vfmlsF(vReg dst_src1, vReg src2, vReg src3) %{
  predicate(UseFMA);
  match(Set dst_src1 (FmaVF dst_src1 (Binary (NegVF src2) src3)));
  match(Set dst_src1 (FmaVF dst_src1 (Binary src2 (NegVF src3))));
  ins_cost(VEC_COST);
  format %{ "vfnmsac.vv $dst_src1, $src2, $src3\t#@vfmlsF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfnmsac_vv(as_VectorRegister($dst_src1$$reg),
                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// dst_src1 = dst_src1 + -src2 * src3
// dst_src1 = dst_src1 + src2 * -src3
instruct vfmlsD(vReg dst_src1, vReg src2, vReg src3) %{
  predicate(UseFMA);
  match(Set dst_src1 (FmaVD dst_src1 (Binary (NegVD src2) src3)));
  match(Set dst_src1 (FmaVD dst_src1 (Binary src2 (NegVD src3))));
  ins_cost(VEC_COST);
  format %{ "vfnmsac.vv $dst_src1, $src2, $src3\t#@vfmlsD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfnmsac_vv(as_VectorRegister($dst_src1$$reg),
                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector fnmla

// dst_src1 = -dst_src1 + -src2 * src3
// dst_src1 = -dst_src1 + src2 * -src3
instruct vfnmlaF(vReg dst_src1, vReg src2, vReg src3) %{
  predicate(UseFMA);
  match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary (NegVF src2) src3)));
  match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 (NegVF src3))));
  ins_cost(VEC_COST);
  format %{ "vfnmacc.vv $dst_src1, $src2, $src3\t#@vfnmlaF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfnmacc_vv(as_VectorRegister($dst_src1$$reg),
                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// dst_src1 = -dst_src1 + -src2 * src3
// dst_src1 = -dst_src1 + src2 * -src3
instruct vfnmlaD(vReg dst_src1, vReg src2, vReg src3) %{
  predicate(UseFMA);
  match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary (NegVD src2) src3)));
  match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 (NegVD src3))));
  ins_cost(VEC_COST);
  format %{ "vfnmacc.vv $dst_src1, $src2, $src3\t#@vfnmlaD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfnmacc_vv(as_VectorRegister($dst_src1$$reg),
                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector fnmls

// dst_src1 = -dst_src1 + src2 * src3
instruct vfnmlsF(vReg dst_src1, vReg src2, vReg src3) %{
  predicate(UseFMA);
  match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vfmsac.vv $dst_src1, $src2, $src3\t#@vfnmlsF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfmsac_vv(as_VectorRegister($dst_src1$$reg),
                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// dst_src1 = -dst_src1 + src2 * src3
instruct vfnmlsD(vReg dst_src1, vReg src2, vReg src3) %{
  predicate(UseFMA);
  match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vfmsac.vv $dst_src1, $src2, $src3\t#@vfnmlsD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfmsac_vv(as_VectorRegister($dst_src1$$reg),
                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector mla

// dst_src1 = dst_src1 + src2 * src3
instruct vmlaB(vReg dst_src1, vReg src2, vReg src3) %{
  match(Set dst_src1 (AddVB dst_src1 (MulVB src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaB" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
                as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// dst_src1 = dst_src1 + src2 * src3
instruct vmlaS(vReg dst_src1, vReg src2, vReg src3) %{
  match(Set dst_src1 (AddVS dst_src1 (MulVS src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaS" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
                as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// dst_src1 = dst_src1 + src2 * src3
instruct vmlaI(vReg dst_src1, vReg src2, vReg src3) %{
  match(Set dst_src1 (AddVI dst_src1 (MulVI src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaI" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
                as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// dst_src1 = dst_src1 + src2 * src3
instruct vmlaL(vReg dst_src1, vReg src2, vReg src3) %{
  match(Set dst_src1 (AddVL dst_src1 (MulVL src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaL" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
                as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector mls

// dst_src1 = dst_src1 - src2 * src3
instruct vmlsB(vReg dst_src1, vReg src2, vReg src3) %{
  match(Set dst_src1 (SubVB dst_src1 (MulVB src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsB" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// dst_src1 = dst_src1 - src2 * src3
instruct vmlsS(vReg dst_src1, vReg src2, vReg src3) %{
  match(Set dst_src1 (SubVS dst_src1 (MulVS src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsS" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// dst_src1 = dst_src1 - src2 * src3
instruct vmlsI(vReg dst_src1, vReg src2, vReg src3) %{
  match(Set dst_src1 (SubVI dst_src1 (MulVI src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsI" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// dst_src1 = dst_src1 - src2 * src3
instruct vmlsL(vReg dst_src1, vReg src2, vReg src3) %{
  match(Set dst_src1 (SubVL dst_src1 (MulVL src2 src3)));
  ins_cost(VEC_COST);
  format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsL" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector mul

instruct vmulB(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (MulVB src1 src2));
  ins_cost(VEC_COST);
  format %{ "vmul.vv $dst, $src1, $src2\t#@vmulB" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vmulS(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (MulVS src1 src2));
  ins_cost(VEC_COST);
  format %{ "vmul.vv $dst, $src1, $src2\t#@vmulS" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vmulI(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (MulVI src1 src2));
  ins_cost(VEC_COST);
  format %{ "vmul.vv $dst, $src1, $src2\t#@vmulI" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vmulL(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (MulVL src1 src2));
  ins_cost(VEC_COST);
  format %{ "vmul.vv $dst, $src1, $src2\t#@vmulL" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vmulF(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (MulVF src1 src2));
  ins_cost(VEC_COST);
  format %{ "vfmul.vv $dst, $src1, $src2\t#@vmulF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
                as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vmulD(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (MulVD src1 src2));
  ins_cost(VEC_COST);
  format %{ "vfmul.vv $dst, $src1, $src2\t#@vmulD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
                as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector neg

instruct vnegI(vReg dst, vReg src) %{
  match(Set dst (NegVI src));
  ins_cost(VEC_COST);
  format %{ "vrsub.vx $dst, $src, $src\t#@vnegI" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this);
    Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
    __ vsetvli(t0, x0, sew);
    __ vneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vnegL(vReg dst, vReg src) %{
  match(Set dst (NegVL src));
  ins_cost(VEC_COST);
  format %{ "vrsub.vx $dst, $src, $src\t#@vnegL" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector fneg

instruct vnegF(vReg dst, vReg src) %{
  match(Set dst (NegVF src));
  ins_cost(VEC_COST);
  format %{ "vfsgnjn.vv $dst, $src, $src\t#@vnegF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vnegD(vReg dst, vReg src) %{
  match(Set dst (NegVD src));
  ins_cost(VEC_COST);
  format %{ "vfsgnjn.vv $dst, $src, $src\t#@vnegD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector and reduction

instruct reduce_andI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
            Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
            Matcher::vector_element_basic_type(n->in(2)) == T_INT);
  match(Set dst (AndReductionV src1 src2));
  effect(TEMP tmp);
  ins_cost(VEC_COST);
  format %{ "vmv.s.x $tmp, $src1\t#@reduce_andI\n\t"
            "vredand.vs $tmp, $src2, $tmp\n\t"
            "vmv.x.s $dst, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

instruct reduce_andL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
  match(Set dst (AndReductionV src1 src2));
  effect(TEMP tmp);
  ins_cost(VEC_COST);
  format %{ "vmv.s.x $tmp, $src1\t#@reduce_andL\n\t"
            "vredand.vs $tmp, $src2, $tmp\n\t"
            "vmv.x.s $dst, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

// vector or reduction

instruct reduce_orI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
            Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
            Matcher::vector_element_basic_type(n->in(2)) == T_INT);
  match(Set dst (OrReductionV src1 src2));
  effect(TEMP tmp);
  ins_cost(VEC_COST);
  format %{ "vmv.s.x $tmp, $src1\t#@reduce_orI\n\t"
            "vredor.vs $tmp, $src2, $tmp\n\t"
            "vmv.x.s $dst, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

instruct reduce_orL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
  match(Set dst (OrReductionV src1 src2));
  effect(TEMP tmp);
  ins_cost(VEC_COST);
  format %{ "vmv.s.x $tmp, $src1\t#@reduce_orL\n\t"
            "vredor.vs $tmp, $src2, $tmp\n\t"
            "vmv.x.s $dst, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

// vector xor reduction

instruct reduce_xorI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
            Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
            Matcher::vector_element_basic_type(n->in(2)) == T_INT);
  match(Set dst (XorReductionV src1 src2));
  effect(TEMP tmp);
  ins_cost(VEC_COST);
  format %{ "vmv.s.x $tmp, $src1\t#@reduce_xorI\n\t"
            "vredxor.vs $tmp, $src2, $tmp\n\t"
            "vmv.x.s $dst, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

instruct reduce_xorL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
  match(Set dst (XorReductionV src1 src2));
  effect(TEMP tmp);
  ins_cost(VEC_COST);
  format %{ "vmv.s.x $tmp, $src1\t#@reduce_xorL\n\t"
            "vredxor.vs $tmp, $src2, $tmp\n\t"
            "vmv.x.s $dst, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

// vector add reduction

instruct reduce_addI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
            Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
            Matcher::vector_element_basic_type(n->in(2)) == T_INT);
  match(Set dst (AddReductionVI src1 src2));
  effect(TEMP tmp);
  ins_cost(VEC_COST);
  format %{ "vmv.s.x $tmp, $src1\t#@reduce_addI\n\t"
            "vredsum.vs $tmp, $src2, $tmp\n\t"
            "vmv.x.s $dst, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

instruct reduce_addL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
  match(Set dst (AddReductionVL src1 src2));
  effect(TEMP tmp);
  ins_cost(VEC_COST);
  format %{ "vmv.s.x $tmp, $src1\t#@reduce_addL\n\t"
            "vredsum.vs $tmp, $src2, $tmp\n\t"
            "vmv.x.s $dst, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

instruct reduce_addF(fRegF src1_dst, vReg src2, vReg tmp) %{
  match(Set src1_dst (AddReductionVF src1_dst src2));
  effect(TEMP tmp);
  ins_cost(VEC_COST);
  format %{ "vfmv.s.f $tmp, $src1_dst\t#@reduce_addF\n\t"
            "vfredosum.vs $tmp, $src2, $tmp\n\t"
            "vfmv.f.s $src1_dst, $tmp" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1_dst$$FloatRegister);
    __ vfredosum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
                    as_VectorRegister($tmp$$reg));
    __ vfmv_f_s($src1_dst$$FloatRegister, as_VectorRegister($tmp$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct reduce_addD(fRegD src1_dst, vReg src2, vReg tmp) %{
  match(Set src1_dst (AddReductionVD src1_dst src2));
  effect(TEMP tmp);
  ins_cost(VEC_COST);
  format %{ "vfmv.s.f $tmp, $src1_dst\t#@reduce_addD\n\t"
            "vfredosum.vs $tmp, $src2, $tmp\n\t"
            "vfmv.f.s $src1_dst, $tmp" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1_dst$$FloatRegister);
    __ vfredosum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
                    as_VectorRegister($tmp$$reg));
    __ vfmv_f_s($src1_dst$$FloatRegister, as_VectorRegister($tmp$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector integer max reduction

instruct vreduce_maxI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
            Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
            Matcher::vector_element_basic_type(n->in(2)) == T_INT);
  match(Set dst (MaxReductionV src1 src2));
  ins_cost(VEC_COST);
  effect(TEMP tmp);
  format %{ "vreduce_maxI $dst, $src1, $src2, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

instruct vreduce_maxL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
  match(Set dst (MaxReductionV src1 src2));
  ins_cost(VEC_COST);
  effect(TEMP tmp);
  format %{ "vreduce_maxL $dst, $src1, $src2, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

// vector integer min reduction

instruct vreduce_minI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
            Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
            Matcher::vector_element_basic_type(n->in(2)) == T_INT);
  match(Set dst (MinReductionV src1 src2));
  ins_cost(VEC_COST);
  effect(TEMP tmp);
  format %{ "vreduce_minI $dst, $src1, $src2, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

instruct vreduce_minL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
  match(Set dst (MinReductionV src1 src2));
  ins_cost(VEC_COST);
  effect(TEMP tmp);
  format %{ "vreduce_minL $dst, $src1, $src2, $tmp" %}
  ins_encode %{
    BasicType bt = Matcher::vector_element_basic_type(this, $src2);
    __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg),
                           $src1$$Register, as_VectorRegister($src2$$reg), bt, this->ideal_Opcode());
  %}
  ins_pipe(pipe_slow);
%}

// vector float max reduction

instruct vreduce_maxF(fRegF dst, fRegF src1, vReg src2, vReg tmp1, vReg tmp2) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT);
  match(Set dst (MaxReductionV src1 src2));
  ins_cost(VEC_COST);
  effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
  format %{ "reduce_maxF $dst, $src1, $src2, $tmp1, $tmp2" %}
  ins_encode %{
    __ reduce_minmax_FD_v($dst$$FloatRegister,
                          $src1$$FloatRegister, as_VectorRegister($src2$$reg),
                          as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
                          false /* is_double */, false /* is_min */);
  %}
  ins_pipe(pipe_slow);
%}

instruct vreduce_maxD(fRegD dst, fRegD src1, vReg src2, vReg tmp1, vReg tmp2) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE);
  match(Set dst (MaxReductionV src1 src2));
  ins_cost(VEC_COST);
  effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
  format %{ "reduce_maxD $dst, $src1, $src2, $tmp1, $tmp2" %}
  ins_encode %{
    __ reduce_minmax_FD_v($dst$$FloatRegister,
                          $src1$$FloatRegister, as_VectorRegister($src2$$reg),
                          as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
                          true /* is_double */, false /* is_min */);
  %}
  ins_pipe(pipe_slow);
%}

// vector float min reduction

instruct vreduce_minF(fRegF dst, fRegF src1, vReg src2, vReg tmp1, vReg tmp2) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT);
  match(Set dst (MinReductionV src1 src2));
  ins_cost(VEC_COST);
  effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
  format %{ "reduce_minF $dst, $src1, $src2, $tmp1, $tmp2" %}
  ins_encode %{
    __ reduce_minmax_FD_v($dst$$FloatRegister,
                          $src1$$FloatRegister, as_VectorRegister($src2$$reg),
                          as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
                          false /* is_double */, true /* is_min */);
  %}
  ins_pipe(pipe_slow);
%}

instruct vreduce_minD(fRegD dst, fRegD src1, vReg src2, vReg tmp1, vReg tmp2) %{
  predicate(Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE);
  match(Set dst (MinReductionV src1 src2));
  ins_cost(VEC_COST);
  effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
  format %{ "reduce_minD $dst, $src1, $src2, $tmp1, $tmp2" %}
  ins_encode %{
    __ reduce_minmax_FD_v($dst$$FloatRegister,
                          $src1$$FloatRegister, as_VectorRegister($src2$$reg),
                          as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
                          true /* is_double */, true /* is_min */);
  %}
  ins_pipe(pipe_slow);
%}

// vector Math.rint, floor, ceil

instruct vroundD(vReg dst, vReg src, immI rmode) %{
  predicate(Matcher::vector_element_basic_type(n) == T_DOUBLE);
  match(Set dst (RoundDoubleModeV src rmode));
  format %{ "vroundD $dst, $src, $rmode" %}
  ins_encode %{
    switch ($rmode$$constant) {
      case RoundDoubleModeNode::rmode_rint:
        __ csrwi(CSR_FRM, C2_MacroAssembler::rne);
        __ vfcvt_rtz_x_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
        break;
      case RoundDoubleModeNode::rmode_floor:
        __ csrwi(CSR_FRM, C2_MacroAssembler::rdn);
        __ vfcvt_rtz_x_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
        break;
      case RoundDoubleModeNode::rmode_ceil:
        __ csrwi(CSR_FRM, C2_MacroAssembler::rup);
        __ vfcvt_rtz_x_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
        break;
      default:
        ShouldNotReachHere();
        break;
    }
  %}
  ins_pipe(pipe_slow);
%}

// vector replicate

instruct replicateB(vReg dst, iRegIorL2I src) %{
  match(Set dst (ReplicateB src));
  ins_cost(VEC_COST);
  format %{ "vmv.v.x $dst, $src\t#@replicateB" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct replicateS(vReg dst, iRegIorL2I src) %{
  match(Set dst (ReplicateS src));
  ins_cost(VEC_COST);
  format %{ "vmv.v.x $dst, $src\t#@replicateS" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct replicateI(vReg dst, iRegIorL2I src) %{
  match(Set dst (ReplicateI src));
  ins_cost(VEC_COST);
  format %{ "vmv.v.x $dst, $src\t#@replicateI" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct replicateL(vReg dst, iRegL src) %{
  match(Set dst (ReplicateL src));
  ins_cost(VEC_COST);
  format %{ "vmv.v.x $dst, $src\t#@replicateL" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct replicateB_imm5(vReg dst, immI5 con) %{
  match(Set dst (ReplicateB con));
  ins_cost(VEC_COST);
  format %{ "vmv.v.i $dst, $con\t#@replicateB_imm5" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant);
  %}
  ins_pipe(pipe_slow);
%}

instruct replicateS_imm5(vReg dst, immI5 con) %{
  match(Set dst (ReplicateS con));
  ins_cost(VEC_COST);
  format %{ "vmv.v.i $dst, $con\t#@replicateS_imm5" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant);
  %}
  ins_pipe(pipe_slow);
%}

instruct replicateI_imm5(vReg dst, immI5 con) %{
  match(Set dst (ReplicateI con));
  ins_cost(VEC_COST);
  format %{ "vmv.v.i $dst, $con\t#@replicateI_imm5" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant);
  %}
  ins_pipe(pipe_slow);
%}

instruct replicateL_imm5(vReg dst, immL5 con) %{
  match(Set dst (ReplicateL con));
  ins_cost(VEC_COST);
  format %{ "vmv.v.i $dst, $con\t#@replicateL_imm5" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant);
  %}
  ins_pipe(pipe_slow);
%}

instruct replicateF(vReg dst, fRegF src) %{
  match(Set dst (ReplicateF src));
  ins_cost(VEC_COST);
  format %{ "vfmv.v.f $dst, $src\t#@replicateF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfmv_v_f(as_VectorRegister($dst$$reg), $src$$FloatRegister);
  %}
  ins_pipe(pipe_slow);
%}

instruct replicateD(vReg dst, fRegD src) %{
  match(Set dst (ReplicateD src));
  ins_cost(VEC_COST);
  format %{ "vfmv.v.f $dst, $src\t#@replicateD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfmv_v_f(as_VectorRegister($dst$$reg), $src$$FloatRegister);
  %}
  ins_pipe(pipe_slow);
%}

// vector shift

instruct vasrB(vReg dst, vReg src, vReg shift) %{
  match(Set dst (RShiftVB src shift));
  ins_cost(VEC_COST);
  effect(TEMP_DEF dst);
  format %{ "vmsgtu.vi v0, $shift 7\t#@vasrB\n\t"
            "vsra.vi $dst, $src, 7, Assembler::v0_t\n\t"
            "vmnot.m v0, v0\n\t"
            "vsra.vv $dst, $src, $shift, Assembler::v0_t" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    // if shift > BitsPerByte - 1, clear the low BitsPerByte - 1 bits
    __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1);
    __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               BitsPerByte - 1, Assembler::v0_t);
    // otherwise, shift
    __ vmnot_m(v0, v0);
    __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg), Assembler::v0_t);
  %}
  ins_pipe(pipe_slow);
%}

instruct vasrS(vReg dst, vReg src, vReg shift) %{
  match(Set dst (RShiftVS src shift));
  ins_cost(VEC_COST);
  effect(TEMP_DEF dst);
  format %{ "vmsgtu.vi v0, $shift, 15\t#@vasrS\n\t"
            "vsra.vi $dst, $src, 15, Assembler::v0_t\n\t"
            "vmnot.m v0, v0\n\t"
            "vsra.vv $dst, $src, $shift, Assembler::v0_t" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    // if shift > BitsPerShort - 1, clear the low BitsPerShort - 1 bits
    __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1);
    __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               BitsPerShort - 1, Assembler::v0_t);
    // otherwise, shift
    __ vmnot_m(v0, v0);
    __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg), Assembler::v0_t);
  %}
  ins_pipe(pipe_slow);
%}

instruct vasrI(vReg dst, vReg src, vReg shift) %{
  match(Set dst (RShiftVI src shift));
  ins_cost(VEC_COST);
  format %{ "vsra.vv $dst, $src, $shift\t#@vasrI" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vasrL(vReg dst, vReg src, vReg shift) %{
  match(Set dst (RShiftVL src shift));
  ins_cost(VEC_COST);
  format %{ "vsra.vv $dst, $src, $shift\t#@vasrL" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
         as_VectorRegister($shift$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vlslB(vReg dst, vReg src, vReg shift) %{
  match(Set dst (LShiftVB src shift));
  ins_cost(VEC_COST);
  effect( TEMP_DEF dst);
  format %{ "vmsgtu.vi v0, $shift, 7\t#@vlslB\n\t"
            "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t"
            "vmnot.m v0, v0\n\t"
            "vsll.vv $dst, $src, $shift, Assembler::v0_t" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    // if shift > BitsPerByte - 1, clear the element
    __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1);
    __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($src$$reg), Assembler::v0_t);
    // otherwise, shift
    __ vmnot_m(v0, v0);
    __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg), Assembler::v0_t);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlslS(vReg dst, vReg src, vReg shift) %{
  match(Set dst (LShiftVS src shift));
  ins_cost(VEC_COST);
  effect(TEMP_DEF dst);
  format %{ "vmsgtu.vi v0, $shift, 15\t#@vlslS\n\t"
            "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t"
            "vmnot.m v0, v0\n\t"
            "vsll.vv $dst, $src, $shift, Assembler::v0_t" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    // if shift > BitsPerShort - 1, clear the element
    __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1);
    __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($src$$reg), Assembler::v0_t);
    // otherwise, shift
    __ vmnot_m(v0, v0);
    __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg), Assembler::v0_t);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlslI(vReg dst, vReg src, vReg shift) %{
  match(Set dst (LShiftVI src shift));
  ins_cost(VEC_COST);
  format %{ "vsll.vv $dst, $src, $shift\t#@vlslI" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vlslL(vReg dst, vReg src, vReg shift) %{
  match(Set dst (LShiftVL src shift));
  ins_cost(VEC_COST);
  format %{ "vsll.vv $dst, $src, $shift\t# vector (D)" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vlsrB(vReg dst, vReg src, vReg shift) %{
  match(Set dst (URShiftVB src shift));
  ins_cost(VEC_COST);
  effect(TEMP_DEF dst);
  format %{ "vmsgtu.vi v0, $shift, 7\t#@vlsrB\n\t"
            "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t"
            "vmnot.m v0, v0, v0\n\t"
            "vsll.vv $dst, $src, $shift, Assembler::v0_t" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    // if shift > BitsPerByte - 1, clear the element
    __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1);
    __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($src$$reg), Assembler::v0_t);
    // otherwise, shift
    __ vmnot_m(v0, v0);
    __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg), Assembler::v0_t);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlsrS(vReg dst, vReg src, vReg shift) %{
  match(Set dst (URShiftVS src shift));
  ins_cost(VEC_COST);
  effect(TEMP_DEF dst);
  format %{ "vmsgtu.vi v0, $shift, 15\t#@vlsrS\n\t"
            "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t"
            "vmnot.m v0, v0\n\t"
            "vsll.vv $dst, $src, $shift, Assembler::v0_t" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    // if shift > BitsPerShort - 1, clear the element
    __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1);
    __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($src$$reg), Assembler::v0_t);
    // otherwise, shift
    __ vmnot_m(v0, v0);
    __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg), Assembler::v0_t);
  %}
  ins_pipe(pipe_slow);
%}


instruct vlsrI(vReg dst, vReg src, vReg shift) %{
  match(Set dst (URShiftVI src shift));
  ins_cost(VEC_COST);
  format %{ "vsrl.vv $dst, $src, $shift\t#@vlsrI" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg));
  %}
  ins_pipe(pipe_slow);
%}


instruct vlsrL(vReg dst, vReg src, vReg shift) %{
  match(Set dst (URShiftVL src shift));
  ins_cost(VEC_COST);
  format %{ "vsrl.vv $dst, $src, $shift\t#@vlsrL" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
               as_VectorRegister($shift$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vasrB_imm(vReg dst, vReg src, immI shift) %{
  match(Set dst (RShiftVB src (RShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsra.vi $dst, $src, $shift\t#@vasrB_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e8);
    if (con == 0) {
      __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                as_VectorRegister($src$$reg));
      return;
    }
    if (con >= BitsPerByte) con = BitsPerByte - 1;
    __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vasrS_imm(vReg dst, vReg src, immI shift) %{
  match(Set dst (RShiftVS src (RShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsra.vi $dst, $src, $shift\t#@vasrS_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e16);
    if (con == 0) {
      __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                as_VectorRegister($src$$reg));
      return;
    }
    if (con >= BitsPerShort) con = BitsPerShort - 1;
    __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vasrI_imm(vReg dst, vReg src, immI shift) %{
  match(Set dst (RShiftVI src (RShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsrl.vi $dst, $src, $shift\t#@vasrI_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e32);
    if (con == 0) {
      __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                as_VectorRegister($src$$reg));
      return;
    }
    __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vasrL_imm(vReg dst, vReg src, immI shift) %{
  predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32);
  match(Set dst (RShiftVL src (RShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsrl.vi $dst, $src, $shift\t#@vasrL_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e64);
    if (con == 0) {
      __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                as_VectorRegister($src$$reg));
      return;
    }
    __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlsrB_imm(vReg dst, vReg src, immI shift) %{
  match(Set dst (URShiftVB src (RShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrB_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e8);
    if (con == 0) {
      __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                as_VectorRegister($src$$reg));
      return;
    }
    if (con >= BitsPerByte) {
      __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                 as_VectorRegister($src$$reg));
      return;
    }
    __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlsrS_imm(vReg dst, vReg src, immI shift) %{
  match(Set dst (URShiftVS src (RShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrS_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e16);
    if (con == 0) {
      __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                as_VectorRegister($src$$reg));
      return;
    }
    if (con >= BitsPerShort) {
      __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                 as_VectorRegister($src$$reg));
      return;
    }
    __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlsrI_imm(vReg dst, vReg src, immI shift) %{
  match(Set dst (URShiftVI src (RShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrI_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e32);
    if (con == 0) {
      __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                as_VectorRegister($src$$reg));
      return;
    }
    __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlsrL_imm(vReg dst, vReg src, immI shift) %{
  predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32);
  match(Set dst (URShiftVL src (RShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrL_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e64);
    if (con == 0) {
      __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                as_VectorRegister($src$$reg));
      return;
    }
    __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlslB_imm(vReg dst, vReg src, immI shift) %{
  match(Set dst (LShiftVB src (LShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsll.vi $dst, $src, $shift\t#@vlslB_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e8);
    if (con >= BitsPerByte) {
      __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                 as_VectorRegister($src$$reg));
      return;
    }
    __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlslS_imm(vReg dst, vReg src, immI shift) %{
  match(Set dst (LShiftVS src (LShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsll.vi $dst, $src, $shift\t#@vlslS_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e16);
    if (con >= BitsPerShort) {
      __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
                 as_VectorRegister($src$$reg));
      return;
    }
    __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlslI_imm(vReg dst, vReg src, immI shift) %{
  match(Set dst (LShiftVI src (LShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsll.vi $dst, $src, $shift\t#@vlslI_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e32);
    __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vlslL_imm(vReg dst, vReg src, immI shift) %{
  predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32);
  match(Set dst (LShiftVL src (LShiftCntV shift)));
  ins_cost(VEC_COST);
  format %{ "vsll.vi $dst, $src, $shift\t#@vlslL_imm" %}
  ins_encode %{
    uint32_t con = (unsigned)$shift$$constant & 0x1f;
    __ vsetvli(t0, x0, Assembler::e64);
    __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
  %}
  ins_pipe(pipe_slow);
%}

instruct vshiftcntB(vReg dst, iRegIorL2I cnt) %{
  predicate(Matcher::vector_element_basic_type(n) == T_BYTE);
  match(Set dst (LShiftCntV cnt));
  match(Set dst (RShiftCntV cnt));
  format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntB" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vshiftcntS(vReg dst, iRegIorL2I cnt) %{
  predicate(Matcher::vector_element_basic_type(n) == T_SHORT ||
            Matcher::vector_element_basic_type(n) == T_CHAR);
  match(Set dst (LShiftCntV cnt));
  match(Set dst (RShiftCntV cnt));
  format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntS" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vshiftcntI(vReg dst, iRegIorL2I cnt) %{
  predicate(Matcher::vector_element_basic_type(n) == T_INT);
  match(Set dst (LShiftCntV cnt));
  match(Set dst (RShiftCntV cnt));
  format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntI" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vshiftcntL(vReg dst, iRegIorL2I cnt) %{
  predicate(Matcher::vector_element_basic_type(n) == T_LONG);
  match(Set dst (LShiftCntV cnt));
  match(Set dst (RShiftCntV cnt));
  format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntL" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector sqrt

instruct vsqrtF(vReg dst, vReg src) %{
  match(Set dst (SqrtVF src));
  ins_cost(VEC_COST);
  format %{ "vfsqrt.v $dst, $src\t#@vsqrtF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfsqrt_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vsqrtD(vReg dst, vReg src) %{
  match(Set dst (SqrtVD src));
  ins_cost(VEC_COST);
  format %{ "vfsqrt.v $dst, $src\t#@vsqrtD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfsqrt_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
  %}
  ins_pipe(pipe_slow);
%}

// vector sub

instruct vsubB(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (SubVB src1 src2));
  ins_cost(VEC_COST);
  format %{ "vsub.vv $dst, $src1, $src2\t#@vsubB" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e8);
    __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vsubS(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (SubVS src1 src2));
  ins_cost(VEC_COST);
  format %{ "vsub.vv $dst, $src1, $src2\t#@vsubS" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e16);
    __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vsubI(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (SubVI src1 src2));
  ins_cost(VEC_COST);
  format %{ "vsub.vv $dst, $src1, $src2\t#@vsubI" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vsubL(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (SubVL src1 src2));
  ins_cost(VEC_COST);
  format %{ "vsub.vv $dst, $src1, $src2\t#@vsubL" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
               as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vsubF(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (SubVF src1 src2));
  ins_cost(VEC_COST);
  format %{ "vfsub.vv $dst, $src1, $src2\t@vsubF" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e32);
    __ vfsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
                as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vsubD(vReg dst, vReg src1, vReg src2) %{
  match(Set dst (SubVD src1 src2));
  ins_cost(VEC_COST);
  format %{ "vfsub.vv $dst, $src1, $src2\t#@vsubD" %}
  ins_encode %{
    __ vsetvli(t0, x0, Assembler::e64);
    __ vfsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
                as_VectorRegister($src2$$reg));
  %}
  ins_pipe(pipe_slow);
%}

instruct vstring_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt,
                         iRegI_R10 result, vReg_V1 v1,
                         vReg_V2 v2, vReg_V3 v3, rFlagsReg cr)
%{
  predicate(UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
  match(Set result (StrEquals (Binary str1 str2) cnt));
  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v1, TEMP v2, TEMP v3, KILL cr);

  format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %}
  ins_encode %{
    // Count is in 8-bit bytes; non-Compact chars are 16 bits.
    __ string_equals_v($str1$$Register, $str2$$Register,
                       $result$$Register, $cnt$$Register, 1);
  %}
  ins_pipe(pipe_class_memory);
%}

instruct vstring_equalsU(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt,
                         iRegI_R10 result, vReg_V1 v1,
                         vReg_V2 v2, vReg_V3 v3, rFlagsReg cr)
%{
  predicate(UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
  match(Set result (StrEquals (Binary str1 str2) cnt));
  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v1, TEMP v2, TEMP v3, KILL cr);

  format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsU" %}
  ins_encode %{
    // Count is in 8-bit bytes; non-Compact chars are 16 bits.
    __ string_equals_v($str1$$Register, $str2$$Register,
                       $result$$Register, $cnt$$Register, 2);
  %}
  ins_pipe(pipe_class_memory);
%}

instruct varray_equalsB(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result,
                        vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegP_R28 tmp, rFlagsReg cr)
%{
  predicate(UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
  match(Set result (AryEq ary1 ary2));
  effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v1, TEMP v2, TEMP v3, KILL cr);

  format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsB // KILL $tmp" %}
  ins_encode %{
    __ arrays_equals_v($ary1$$Register, $ary2$$Register,
                       $result$$Register, $tmp$$Register, 1);
    %}
  ins_pipe(pipe_class_memory);
%}

instruct varray_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result,
                        vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegP_R28 tmp, rFlagsReg cr)
%{
  predicate(UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
  match(Set result (AryEq ary1 ary2));
  effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v1, TEMP v2, TEMP v3, KILL cr);

  format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsC // KILL $tmp" %}
  ins_encode %{
    __ arrays_equals_v($ary1$$Register, $ary2$$Register,
                       $result$$Register, $tmp$$Register, 2);
  %}
  ins_pipe(pipe_class_memory);
%}

instruct vstring_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
                          iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5,
                          iRegP_R28 tmp1, iRegL_R29 tmp2)
%{
  predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU);
  match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2)));
  effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
         TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5);

  format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareU" %}
  ins_encode %{
    // Count is in 8-bit bytes; non-Compact chars are 16 bits.
    __ string_compare_v($str1$$Register, $str2$$Register,
                        $cnt1$$Register, $cnt2$$Register, $result$$Register,
                        $tmp1$$Register, $tmp2$$Register,
                        StrIntrinsicNode::UU);
  %}
  ins_pipe(pipe_class_memory);
%}
instruct vstring_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
                          iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5,
                          iRegP_R28 tmp1, iRegL_R29 tmp2)
%{
  predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LL);
--> --------------------

--> maximum size reached

--> --------------------

[ Verzeichnis aufwärts0.192unsichere Verbindung  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik