1 //
   2 // Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
   3 // Copyright (c) 2020, Arm Limited. All rights reserved.
   4 // Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
   5 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6 //
   7 // This code is free software; you can redistribute it and/or modify it
   8 // under the terms of the GNU General Public License version 2 only, as
   9 // published by the Free Software Foundation.
  10 //
  11 // This code is distributed in the hope that it will be useful, but WITHOUT
  12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14 // version 2 for more details (a copy is included in the LICENSE file that
  15 // accompanied this code).
  16 //
  17 // You should have received a copy of the GNU General Public License version
  18 // 2 along with this work; if not, write to the Free Software Foundation,
  19 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20 //
  21 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22 // or visit www.oracle.com if you need additional information or have any
  23 // questions.
  24 //
  25 //
  26 
  27 // RISCV Vector Extension Architecture Description File
  28 
  29 opclass vmemA(indirect);
  30 
  31 source_hpp %{
  32   bool op_vec_supported(int opcode);
  33 %}
  34 
  35 source %{
  36   static inline BasicType vector_element_basic_type(const MachNode* n) {
  37     const TypeVect* vt = n->bottom_type()->is_vect();
  38     return vt->element_basic_type();
  39   }
  40 
  41   static inline BasicType vector_element_basic_type(const MachNode* use, const MachOper* opnd) {
  42     int def_idx = use->operand_index(opnd);
  43     Node* def = use->in(def_idx);
  44     const TypeVect* vt = def->bottom_type()->is_vect();
  45     return vt->element_basic_type();
  46   }
  47 
  48   static void loadStore(C2_MacroAssembler masm, bool is_store,
  49                         VectorRegister reg, BasicType bt, Register base) {
  50     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
  51     masm.vsetvli(t0, x0, sew);
  52     if (is_store) {
  53       masm.vsex_v(reg, base, sew);
  54     } else {
  55       masm.vlex_v(reg, base, sew);
  56     }
  57   }
  58 
  59   bool op_vec_supported(int opcode) {
  60     switch (opcode) {
  61       // No multiply reduction instructions
  62       case Op_MulReductionVD:
  63       case Op_MulReductionVF:
  64       case Op_MulReductionVI:
  65       case Op_MulReductionVL:
  66       // Others
  67       case Op_Extract:
  68       case Op_ExtractB:
  69       case Op_ExtractC:
  70       case Op_ExtractD:
  71       case Op_ExtractF:
  72       case Op_ExtractI:
  73       case Op_ExtractL:
  74       case Op_ExtractS:
  75       case Op_ExtractUB:
  76       // Vector API specific
  77       case Op_AndReductionV:
  78       case Op_OrReductionV:
  79       case Op_XorReductionV:
  80       case Op_LoadVectorGather:
  81       case Op_StoreVectorScatter:
  82       case Op_VectorBlend:
  83       case Op_VectorCast:
  84       case Op_VectorCastB2X:
  85       case Op_VectorCastD2X:
  86       case Op_VectorCastF2X:
  87       case Op_VectorCastI2X:
  88       case Op_VectorCastL2X:
  89       case Op_VectorCastS2X:
  90       case Op_VectorInsert:
  91       case Op_VectorLoadConst:
  92       case Op_VectorLoadMask:
  93       case Op_VectorLoadShuffle:
  94       case Op_VectorMaskCmp:
  95       case Op_VectorRearrange:
  96       case Op_VectorReinterpret:
  97       case Op_VectorStoreMask:
  98       case Op_VectorTest:
  99       case Op_PopCountVI:
 100         return false;
 101       default:
 102         return UseRVV;
 103     }
 104   }
 105 
 106 %}
 107 
 108 definitions %{
 109   int_def VEC_COST             (200, 200);
 110 %}
 111 
 112 // All VEC instructions
 113 
 114 // vector load/store
 115 instruct loadV(vReg dst, vmemA mem) %{
 116   match(Set dst (LoadVector mem));
 117   ins_cost(VEC_COST);
 118   format %{ "vle $dst, $mem\t#@loadV" %}
 119   ins_encode %{
 120     VectorRegister dst_reg = as_VectorRegister($dst$$reg);
 121     loadStore(C2_MacroAssembler(&cbuf), false, dst_reg,
 122               vector_element_basic_type(this), as_Register($mem$$base));
 123   %}
 124   ins_pipe(pipe_slow);
 125 %}
 126 
 127 instruct storeV(vReg src, vmemA mem) %{
 128   match(Set mem (StoreVector mem src));
 129   ins_cost(VEC_COST);
 130   format %{ "vse $src, $mem\t#@storeV" %}
 131   ins_encode %{
 132     VectorRegister src_reg = as_VectorRegister($src$$reg);
 133     loadStore(C2_MacroAssembler(&cbuf), true, src_reg,
 134               vector_element_basic_type(this, $src), as_Register($mem$$base));
 135   %}
 136   ins_pipe(pipe_slow);
 137 %}
 138 
 139 // vector abs
 140 
 141 instruct vabsB(vReg dst, vReg src, vReg tmp) %{
 142   match(Set dst (AbsVB src));
 143   ins_cost(VEC_COST);
 144   effect(TEMP tmp);
 145   format %{ "vrsub.vi $tmp, 0, $src\t#@vabsB\n\t"
 146             "vmax.vv $dst, $tmp, $src" %}
 147   ins_encode %{
 148     __ vsetvli(t0, x0, Assembler::e8);
 149     __ vrsub_vi(as_VectorRegister($tmp$$reg), 0, as_VectorRegister($src$$reg));
 150     __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
 151   %}
 152   ins_pipe(pipe_slow);
 153 %}
 154 
 155 instruct vabsS(vReg dst, vReg src, vReg tmp) %{
 156   match(Set dst (AbsVS src));
 157   ins_cost(VEC_COST);
 158   effect(TEMP tmp);
 159   format %{ "vrsub.vi $tmp, 0, $src\t#@vabsS\n\t"
 160             "vmax.vv $dst, $tmp, $src" %}
 161   ins_encode %{
 162     __ vsetvli(t0, x0, Assembler::e16);
 163     __ vrsub_vi(as_VectorRegister($tmp$$reg), 0, as_VectorRegister($src$$reg));
 164     __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
 165   %}
 166   ins_pipe(pipe_slow);
 167 %}
 168 
 169 instruct vabsI(vReg dst, vReg src, vReg tmp) %{
 170   match(Set dst (AbsVI src));
 171   ins_cost(VEC_COST);
 172   effect(TEMP tmp);
 173   format %{ "vrsub.vi $tmp, 0, $src\t#@vabsI\n\t"
 174             "vmax.vv $dst, $tmp, $src" %}
 175   ins_encode %{
 176     __ vsetvli(t0, x0, Assembler::e32);
 177     __ vrsub_vi(as_VectorRegister($tmp$$reg), 0, as_VectorRegister($src$$reg));
 178     __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
 179   %}
 180   ins_pipe(pipe_slow);
 181 %}
 182 
 183 instruct vabsL(vReg dst, vReg src, vReg tmp) %{
 184   match(Set dst (AbsVL src));
 185   ins_cost(VEC_COST);
 186   effect(TEMP tmp);
 187   format %{ "vrsub.vi $tmp, 0, $src\t#@vabsL\n\t"
 188             "vmax.vv $dst, $tmp, $src" %}
 189   ins_encode %{
 190     __ vsetvli(t0, x0, Assembler::e64);
 191     __ vrsub_vi(as_VectorRegister($tmp$$reg), 0, as_VectorRegister($src$$reg));
 192     __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
 193   %}
 194   ins_pipe(pipe_slow);
 195 %}
 196 
 197 instruct vabsF(vReg dst, vReg src) %{
 198   match(Set dst (AbsVF src));
 199   ins_cost(VEC_COST);
 200   format %{ "vfsgnjx.vv $dst, $src, $src, vm\t#@vabsF" %}
 201   ins_encode %{
 202     __ vsetvli(t0, x0, Assembler::e32);
 203     __ vfsgnjx_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg));
 204   %}
 205   ins_pipe(pipe_slow);
 206 %}
 207 
 208 instruct vabsD(vReg dst, vReg src) %{
 209   match(Set dst (AbsVD src));
 210   ins_cost(VEC_COST);
 211   format %{ "vfsgnjx.vv $dst, $src, $src, vm\t#@vabsD" %}
 212   ins_encode %{
 213     __ vsetvli(t0, x0, Assembler::e64);
 214     __ vfsgnjx_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg));
 215   %}
 216   ins_pipe(pipe_slow);
 217 %}
 218 
 219 // vector add
 220 
 221 instruct vaddB(vReg dst, vReg src1, vReg src2) %{
 222   match(Set dst (AddVB src1 src2));
 223   ins_cost(VEC_COST);
 224   format %{ "vadd.vv $dst, $src1, $src2\t#@vaddB" %}
 225   ins_encode %{
 226     __ vsetvli(t0, x0, Assembler::e8);
 227     __ vadd_vv(as_VectorRegister($dst$$reg),
 228                as_VectorRegister($src1$$reg),
 229                as_VectorRegister($src2$$reg));
 230   %}
 231   ins_pipe(pipe_slow);
 232 %}
 233 
 234 instruct vaddS(vReg dst, vReg src1, vReg src2) %{
 235   match(Set dst (AddVS src1 src2));
 236   ins_cost(VEC_COST);
 237   format %{ "vadd.vv $dst, $src1, $src2\t#@vaddS" %}
 238   ins_encode %{
 239     __ vsetvli(t0, x0, Assembler::e16);
 240     __ vadd_vv(as_VectorRegister($dst$$reg),
 241                as_VectorRegister($src1$$reg),
 242                as_VectorRegister($src2$$reg));
 243   %}
 244   ins_pipe(pipe_slow);
 245 %}
 246 
 247 instruct vaddI(vReg dst, vReg src1, vReg src2) %{
 248   match(Set dst (AddVI src1 src2));
 249   ins_cost(VEC_COST);
 250   format %{ "vadd.vv $dst, $src1, $src2\t#@vaddI" %}
 251   ins_encode %{
 252     __ vsetvli(t0, x0, Assembler::e32);
 253     __ vadd_vv(as_VectorRegister($dst$$reg),
 254                as_VectorRegister($src1$$reg),
 255                as_VectorRegister($src2$$reg));
 256   %}
 257   ins_pipe(pipe_slow);
 258 %}
 259 
 260 instruct vaddL(vReg dst, vReg src1, vReg src2) %{
 261   match(Set dst (AddVL src1 src2));
 262   ins_cost(VEC_COST);
 263   format %{ "vadd.vv $dst, $src1, $src2\t#@vaddL" %}
 264   ins_encode %{
 265     __ vsetvli(t0, x0, Assembler::e64);
 266     __ vadd_vv(as_VectorRegister($dst$$reg),
 267                as_VectorRegister($src1$$reg),
 268                as_VectorRegister($src2$$reg));
 269   %}
 270   ins_pipe(pipe_slow);
 271 %}
 272 
 273 instruct vaddF(vReg dst, vReg src1, vReg src2) %{
 274   match(Set dst (AddVF src1 src2));
 275   ins_cost(VEC_COST);
 276   format %{ "vfadd.vv $dst, $src1, $src2\t#@vaddF" %}
 277   ins_encode %{
 278     __ vsetvli(t0, x0, Assembler::e32);
 279     __ vfadd_vv(as_VectorRegister($dst$$reg),
 280                 as_VectorRegister($src1$$reg),
 281                 as_VectorRegister($src2$$reg));
 282   %}
 283   ins_pipe(pipe_slow);
 284 %}
 285 
 286 instruct vaddD(vReg dst, vReg src1, vReg src2) %{
 287   match(Set dst (AddVD src1 src2));
 288   ins_cost(VEC_COST);
 289   format %{ "vfadd.vv $dst, $src1, $src2\t#@vaddD" %}
 290   ins_encode %{
 291     __ vsetvli(t0, x0, Assembler::e64);
 292     __ vfadd_vv(as_VectorRegister($dst$$reg),
 293                 as_VectorRegister($src1$$reg),
 294                 as_VectorRegister($src2$$reg));
 295   %}
 296   ins_pipe(pipe_slow);
 297 %}
 298 
 299 // vector and
 300 
 301 instruct vand(vReg dst, vReg src1, vReg src2) %{
 302   match(Set dst (AndV src1 src2));
 303   ins_cost(VEC_COST);
 304   format %{ "vand.vv  $dst, $src1, $src2\t#@vand" %}
 305   ins_encode %{
 306     __ vsetvli(t0, x0, Assembler::e64);
 307     __ vand_vv(as_VectorRegister($dst$$reg),
 308                as_VectorRegister($src1$$reg),
 309                as_VectorRegister($src2$$reg));
 310   %}
 311   ins_pipe(pipe_slow);
 312 %}
 313 
 314 // vector or
 315 
 316 instruct vor(vReg dst, vReg src1, vReg src2) %{
 317   match(Set dst (OrV src1 src2));
 318   ins_cost(VEC_COST);
 319   format %{ "vor.vv  $dst, $src1, $src2\t#@vor" %}
 320   ins_encode %{
 321     __ vsetvli(t0, x0, Assembler::e64);
 322     __ vor_vv(as_VectorRegister($dst$$reg),
 323               as_VectorRegister($src1$$reg),
 324               as_VectorRegister($src2$$reg));
 325   %}
 326   ins_pipe(pipe_slow);
 327 %}
 328 
 329 // vector xor
 330 
 331 instruct vxor(vReg dst, vReg src1, vReg src2) %{
 332   match(Set dst (XorV src1 src2));
 333   ins_cost(VEC_COST);
 334   format %{ "vxor.vv  $dst, $src1, $src2\t#@vxor" %}
 335   ins_encode %{
 336     __ vsetvli(t0, x0, Assembler::e64);
 337     __ vxor_vv(as_VectorRegister($dst$$reg),
 338                as_VectorRegister($src1$$reg),
 339                as_VectorRegister($src2$$reg));
 340   %}
 341   ins_pipe(pipe_slow);
 342 %}
 343 
 344 // vector float div
 345 
 346 instruct vdivF(vReg dst, vReg src1, vReg src2) %{
 347   match(Set dst (DivVF src1 src2));
 348   ins_cost(VEC_COST);
 349   format %{ "vfdiv.vv  $dst, $src1, $src2\t#@vdivF" %}
 350   ins_encode %{
 351     __ vsetvli(t0, x0, Assembler::e32);
 352     __ vfdiv_vv(as_VectorRegister($dst$$reg),
 353                 as_VectorRegister($src1$$reg),
 354                 as_VectorRegister($src2$$reg));
 355   %}
 356   ins_pipe(pipe_slow);
 357 %}
 358 
 359 instruct vdivD(vReg dst, vReg src1, vReg src2) %{
 360   match(Set dst (DivVD src1 src2));
 361   ins_cost(VEC_COST);
 362   format %{ "vfdiv.vv  $dst, $src1, $src2\t#@vdivD" %}
 363   ins_encode %{
 364     __ vsetvli(t0, x0, Assembler::e64);
 365     __ vfdiv_vv(as_VectorRegister($dst$$reg),
 366                 as_VectorRegister($src1$$reg),
 367                 as_VectorRegister($src2$$reg));
 368   %}
 369   ins_pipe(pipe_slow);
 370 %}
 371 
 372 // vector integer max/min
 373 
 374 instruct vmax(vReg dst, vReg src1, vReg src2) %{
 375   predicate(n->bottom_type()->is_vect()->element_basic_type() != T_FLOAT &&
 376             n->bottom_type()->is_vect()->element_basic_type() != T_DOUBLE);
 377   match(Set dst (MaxV src1 src2));
 378   ins_cost(VEC_COST);
 379   format %{ "vmax.vv $dst, $src1, $src2\t#@vmax" %}
 380   ins_encode %{
 381     BasicType bt = vector_element_basic_type(this);
 382     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
 383     __ vsetvli(t0, x0, sew);
 384     __ vmax_vv(as_VectorRegister($dst$$reg),
 385                as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
 386   %}
 387   ins_pipe(pipe_slow);
 388 %}
 389 
 390 instruct vmin(vReg dst, vReg src1, vReg src2) %{
 391   predicate(n->bottom_type()->is_vect()->element_basic_type() != T_FLOAT &&
 392             n->bottom_type()->is_vect()->element_basic_type() != T_DOUBLE);
 393   match(Set dst (MinV src1 src2));
 394   ins_cost(VEC_COST);
 395   format %{ "vmin.vv $dst, $src1, $src2\t#@vmin" %}
 396   ins_encode %{
 397     BasicType bt = vector_element_basic_type(this);
 398     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
 399     __ vsetvli(t0, x0, sew);
 400     __ vmin_vv(as_VectorRegister($dst$$reg),
 401                as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
 402   %}
 403   ins_pipe(pipe_slow);
 404 %}
 405 
 406 // vector float-point max/min
 407 
 408 instruct vmaxF(vReg dst, vReg src1, vReg src2) %{
 409   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
 410   match(Set dst (MaxV src1 src2));
 411   effect(TEMP_DEF dst);
 412   ins_cost(VEC_COST);
 413   format %{ "vmaxF $dst, $src1, $src2\t#@vmaxF" %}
 414   ins_encode %{
 415     __ minmax_FD_v(as_VectorRegister($dst$$reg),
 416                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 417                    false /* is_double */, false /* is_min */);
 418   %}
 419   ins_pipe(pipe_slow);
 420 %}
 421 
 422 instruct vmaxD(vReg dst, vReg src1, vReg src2) %{
 423   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
 424   match(Set dst (MaxV src1 src2));
 425   effect(TEMP_DEF dst);
 426   ins_cost(VEC_COST);
 427   format %{ "vmaxD $dst, $src1, $src2\t#@vmaxD" %}
 428   ins_encode %{
 429     __ minmax_FD_v(as_VectorRegister($dst$$reg),
 430                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 431                    true /* is_double */, false /* is_min */);
 432   %}
 433   ins_pipe(pipe_slow);
 434 %}
 435 
 436 instruct vminF(vReg dst, vReg src1, vReg src2) %{
 437   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
 438   match(Set dst (MinV src1 src2));
 439   effect(TEMP_DEF dst);
 440   ins_cost(VEC_COST);
 441   format %{ "vminF $dst, $src1, $src2\t#@vminF" %}
 442   ins_encode %{
 443     __ minmax_FD_v(as_VectorRegister($dst$$reg),
 444                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 445                    false /* is_double */, true /* is_min */);
 446   %}
 447   ins_pipe(pipe_slow);
 448 %}
 449 
 450 instruct vminD(vReg dst, vReg src1, vReg src2) %{
 451   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
 452   match(Set dst (MinV src1 src2));
 453   effect(TEMP_DEF dst);
 454   ins_cost(VEC_COST);
 455   format %{ "vminD $dst, $src1, $src2\t#@vminD" %}
 456   ins_encode %{
 457     __ minmax_FD_v(as_VectorRegister($dst$$reg),
 458                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 459                    true /* is_double */, true /* is_min */);
 460   %}
 461   ins_pipe(pipe_slow);
 462 %}
 463 
 464 // vector fmla
 465 
 466 // dst_src1 = dst_src1 + src2 * src3
 467 instruct vfmlaF(vReg dst_src1, vReg src2, vReg src3) %{
 468   predicate(UseFMA);
 469   match(Set dst_src1 (FmaVF dst_src1 (Binary src2 src3)));
 470   ins_cost(VEC_COST);
 471   format %{ "vfmacc.vv $dst_src1, $src2, $src3\t#@vfmlaF" %}
 472   ins_encode %{
 473     __ vsetvli(t0, x0, Assembler::e32);
 474     __ vfmacc_vv(as_VectorRegister($dst_src1$$reg),
 475                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 476   %}
 477   ins_pipe(pipe_slow);
 478 %}
 479 
 480 // dst_src1 = dst_src1 + src2 * src3
 481 instruct vfmlaD(vReg dst_src1, vReg src2, vReg src3) %{
 482   predicate(UseFMA);
 483   match(Set dst_src1 (FmaVD dst_src1 (Binary src2 src3)));
 484   ins_cost(VEC_COST);
 485   format %{ "vfmacc.vv $dst_src1, $src2, $src3\t#@vfmlaD" %}
 486   ins_encode %{
 487     __ vsetvli(t0, x0, Assembler::e64);
 488     __ vfmacc_vv(as_VectorRegister($dst_src1$$reg),
 489                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 490   %}
 491   ins_pipe(pipe_slow);
 492 %}
 493 
 494 // vector fmls
 495 
 496 // dst_src1 = dst_src1 + -src2 * src3
 497 // dst_src1 = dst_src1 + src2 * -src3
 498 instruct vfmlsF(vReg dst_src1, vReg src2, vReg src3) %{
 499   predicate(UseFMA);
 500   match(Set dst_src1 (FmaVF dst_src1 (Binary (NegVF src2) src3)));
 501   match(Set dst_src1 (FmaVF dst_src1 (Binary src2 (NegVF src3))));
 502   ins_cost(VEC_COST);
 503   format %{ "vfnmsac.vv $dst_src1, $src2, $src3\t#@vfmlsF" %}
 504   ins_encode %{
 505     __ vsetvli(t0, x0, Assembler::e32);
 506     __ vfnmsac_vv(as_VectorRegister($dst_src1$$reg),
 507                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 508   %}
 509   ins_pipe(pipe_slow);
 510 %}
 511 
 512 // dst_src1 = dst_src1 + -src2 * src3
 513 // dst_src1 = dst_src1 + src2 * -src3
 514 instruct vfmlsD(vReg dst_src1, vReg src2, vReg src3) %{
 515   predicate(UseFMA);
 516   match(Set dst_src1 (FmaVD dst_src1 (Binary (NegVD src2) src3)));
 517   match(Set dst_src1 (FmaVD dst_src1 (Binary src2 (NegVD src3))));
 518   ins_cost(VEC_COST);
 519   format %{ "vfnmsac.vv $dst_src1, $src2, $src3\t#@vfmlsD" %}
 520   ins_encode %{
 521     __ vsetvli(t0, x0, Assembler::e64);
 522     __ vfnmsac_vv(as_VectorRegister($dst_src1$$reg),
 523                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 524   %}
 525   ins_pipe(pipe_slow);
 526 %}
 527 
 528 // vector fnmla
 529 
 530 // dst_src1 = -dst_src1 + -src2 * src3
 531 // dst_src1 = -dst_src1 + src2 * -src3
 532 instruct vfnmlaF(vReg dst_src1, vReg src2, vReg src3) %{
 533   predicate(UseFMA);
 534   match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary (NegVF src2) src3)));
 535   match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 (NegVF src3))));
 536   ins_cost(VEC_COST);
 537   format %{ "vfnmacc.vv $dst_src1, $src2, $src3\t#@vfnmlaF" %}
 538   ins_encode %{
 539     __ vsetvli(t0, x0, Assembler::e32);
 540     __ vfnmacc_vv(as_VectorRegister($dst_src1$$reg),
 541                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 542   %}
 543   ins_pipe(pipe_slow);
 544 %}
 545 
 546 // dst_src1 = -dst_src1 + -src2 * src3
 547 // dst_src1 = -dst_src1 + src2 * -src3
 548 instruct vfnmlaD(vReg dst_src1, vReg src2, vReg src3) %{
 549   predicate(UseFMA);
 550   match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary (NegVD src2) src3)));
 551   match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 (NegVD src3))));
 552   ins_cost(VEC_COST);
 553   format %{ "vfnmacc.vv $dst_src1, $src2, $src3\t#@vfnmlaD" %}
 554   ins_encode %{
 555     __ vsetvli(t0, x0, Assembler::e64);
 556     __ vfnmacc_vv(as_VectorRegister($dst_src1$$reg),
 557                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 558   %}
 559   ins_pipe(pipe_slow);
 560 %}
 561 
 562 // vector fnmls
 563 
 564 // dst_src1 = -dst_src1 + src2 * src3
 565 instruct vfnmlsF(vReg dst_src1, vReg src2, vReg src3) %{
 566   predicate(UseFMA);
 567   match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 src3)));
 568   ins_cost(VEC_COST);
 569   format %{ "vfmsac.vv $dst_src1, $src2, $src3\t#@vfnmlsF" %}
 570   ins_encode %{
 571     __ vsetvli(t0, x0, Assembler::e32);
 572     __ vfmsac_vv(as_VectorRegister($dst_src1$$reg),
 573                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 574   %}
 575   ins_pipe(pipe_slow);
 576 %}
 577 
 578 // dst_src1 = -dst_src1 + src2 * src3
 579 instruct vfnmlsD(vReg dst_src1, vReg src2, vReg src3) %{
 580   predicate(UseFMA);
 581   match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 src3)));
 582   ins_cost(VEC_COST);
 583   format %{ "vfmsac.vv $dst_src1, $src2, $src3\t#@vfnmlsD" %}
 584   ins_encode %{
 585     __ vsetvli(t0, x0, Assembler::e64);
 586     __ vfmsac_vv(as_VectorRegister($dst_src1$$reg),
 587                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 588   %}
 589   ins_pipe(pipe_slow);
 590 %}
 591 
 592 // vector mla
 593 
 594 // dst_src1 = dst_src1 + src2 * src3
 595 instruct vmlaB(vReg dst_src1, vReg src2, vReg src3) %{
 596   match(Set dst_src1 (AddVB dst_src1 (MulVB src2 src3)));
 597   ins_cost(VEC_COST);
 598   format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaB" %}
 599   ins_encode %{
 600     __ vsetvli(t0, x0, Assembler::e8);
 601     __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
 602                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 603   %}
 604   ins_pipe(pipe_slow);
 605 %}
 606 
 607 // dst_src1 = dst_src1 + src2 * src3
 608 instruct vmlaS(vReg dst_src1, vReg src2, vReg src3) %{
 609   match(Set dst_src1 (AddVS dst_src1 (MulVS src2 src3)));
 610   ins_cost(VEC_COST);
 611   format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaS" %}
 612   ins_encode %{
 613     __ vsetvli(t0, x0, Assembler::e16);
 614     __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
 615                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 616   %}
 617   ins_pipe(pipe_slow);
 618 %}
 619 
 620 // dst_src1 = dst_src1 + src2 * src3
 621 instruct vmlaI(vReg dst_src1, vReg src2, vReg src3) %{
 622   match(Set dst_src1 (AddVI dst_src1 (MulVI src2 src3)));
 623   ins_cost(VEC_COST);
 624   format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaI" %}
 625   ins_encode %{
 626     __ vsetvli(t0, x0, Assembler::e32);
 627     __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
 628                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 629   %}
 630   ins_pipe(pipe_slow);
 631 %}
 632 
 633 // dst_src1 = dst_src1 + src2 * src3
 634 instruct vmlaL(vReg dst_src1, vReg src2, vReg src3) %{
 635   match(Set dst_src1 (AddVL dst_src1 (MulVL src2 src3)));
 636   ins_cost(VEC_COST);
 637   format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaL" %}
 638   ins_encode %{
 639     __ vsetvli(t0, x0, Assembler::e64);
 640     __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
 641                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 642   %}
 643   ins_pipe(pipe_slow);
 644 %}
 645 
 646 // vector mls
 647 
 648 // dst_src1 = dst_src1 - src2 * src3
 649 instruct vmlsB(vReg dst_src1, vReg src2, vReg src3) %{
 650   match(Set dst_src1 (SubVB dst_src1 (MulVB src2 src3)));
 651   ins_cost(VEC_COST);
 652   format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsB" %}
 653   ins_encode %{
 654     __ vsetvli(t0, x0, Assembler::e8);
 655     __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
 656                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 657   %}
 658   ins_pipe(pipe_slow);
 659 %}
 660 
 661 // dst_src1 = dst_src1 - src2 * src3
 662 instruct vmlsS(vReg dst_src1, vReg src2, vReg src3) %{
 663   match(Set dst_src1 (SubVS dst_src1 (MulVS src2 src3)));
 664   ins_cost(VEC_COST);
 665   format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsS" %}
 666   ins_encode %{
 667     __ vsetvli(t0, x0, Assembler::e16);
 668     __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
 669                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 670   %}
 671   ins_pipe(pipe_slow);
 672 %}
 673 
 674 // dst_src1 = dst_src1 - src2 * src3
 675 instruct vmlsI(vReg dst_src1, vReg src2, vReg src3) %{
 676   match(Set dst_src1 (SubVI dst_src1 (MulVI src2 src3)));
 677   ins_cost(VEC_COST);
 678   format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsI" %}
 679   ins_encode %{
 680     __ vsetvli(t0, x0, Assembler::e32);
 681     __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
 682                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 683   %}
 684   ins_pipe(pipe_slow);
 685 %}
 686 
 687 // dst_src1 = dst_src1 - src2 * src3
 688 instruct vmlsL(vReg dst_src1, vReg src2, vReg src3) %{
 689   match(Set dst_src1 (SubVL dst_src1 (MulVL src2 src3)));
 690   ins_cost(VEC_COST);
 691   format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsL" %}
 692   ins_encode %{
 693     __ vsetvli(t0, x0, Assembler::e64);
 694     __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
 695                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 696   %}
 697   ins_pipe(pipe_slow);
 698 %}
 699 
 700 // vector mul
 701 
 702 instruct vmulB(vReg dst, vReg src1, vReg src2) %{
 703   match(Set dst (MulVB src1 src2));
 704   ins_cost(VEC_COST);
 705   format %{ "vmul.vv $dst, $src1, $src2\t#@vmulB" %}
 706   ins_encode %{
 707     __ vsetvli(t0, x0, Assembler::e8);
 708     __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 709                as_VectorRegister($src2$$reg));
 710   %}
 711   ins_pipe(pipe_slow);
 712 %}
 713 
 714 instruct vmulS(vReg dst, vReg src1, vReg src2) %{
 715   match(Set dst (MulVS src1 src2));
 716   ins_cost(VEC_COST);
 717   format %{ "vmul.vv $dst, $src1, $src2\t#@vmulS" %}
 718   ins_encode %{
 719     __ vsetvli(t0, x0, Assembler::e16);
 720     __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 721                as_VectorRegister($src2$$reg));
 722   %}
 723   ins_pipe(pipe_slow);
 724 %}
 725 
 726 instruct vmulI(vReg dst, vReg src1, vReg src2) %{
 727   match(Set dst (MulVI src1 src2));
 728   ins_cost(VEC_COST);
 729   format %{ "vmul.vv $dst, $src1, $src2\t#@vmulI" %}
 730   ins_encode %{
 731     __ vsetvli(t0, x0, Assembler::e32);
 732     __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 733                as_VectorRegister($src2$$reg));
 734   %}
 735   ins_pipe(pipe_slow);
 736 %}
 737 
 738 instruct vmulL(vReg dst, vReg src1, vReg src2) %{
 739   match(Set dst (MulVL src1 src2));
 740   ins_cost(VEC_COST);
 741   format %{ "vmul.vv $dst, $src1, $src2\t#@vmulL" %}
 742   ins_encode %{
 743     __ vsetvli(t0, x0, Assembler::e64);
 744     __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 745                as_VectorRegister($src2$$reg));
 746   %}
 747   ins_pipe(pipe_slow);
 748 %}
 749 
 750 instruct vmulF(vReg dst, vReg src1, vReg src2) %{
 751   match(Set dst (MulVF src1 src2));
 752   ins_cost(VEC_COST);
 753   format %{ "vfmul.vv $dst, $src1, $src2\t#@vmulF" %}
 754   ins_encode %{
 755     __ vsetvli(t0, x0, Assembler::e32);
 756     __ vfmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 757                 as_VectorRegister($src2$$reg));
 758   %}
 759   ins_pipe(pipe_slow);
 760 %}
 761 
 762 instruct vmulD(vReg dst, vReg src1, vReg src2) %{
 763   match(Set dst (MulVD src1 src2));
 764   ins_cost(VEC_COST);
 765   format %{ "vfmul.vv $dst, $src1, $src2\t#@vmulD" %}
 766   ins_encode %{
 767     __ vsetvli(t0, x0, Assembler::e64);
 768     __ vfmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 769                 as_VectorRegister($src2$$reg));
 770   %}
 771   ins_pipe(pipe_slow);
 772 %}
 773 
 774 // vector fneg
 775 
 776 instruct vnegF(vReg dst, vReg src) %{
 777   match(Set dst (NegVF src));
 778   ins_cost(VEC_COST);
 779   format %{ "vfsgnjn.vv $dst, $src, $src\t#@vnegF" %}
 780   ins_encode %{
 781     __ vsetvli(t0, x0, Assembler::e32);
 782     __ vfneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
 783   %}
 784   ins_pipe(pipe_slow);
 785 %}
 786 
 787 instruct vnegD(vReg dst, vReg src) %{
 788   match(Set dst (NegVD src));
 789   ins_cost(VEC_COST);
 790   format %{ "vfsgnjn.vv $dst, $src, $src\t#@vnegD" %}
 791   ins_encode %{
 792     __ vsetvli(t0, x0, Assembler::e64);
 793     __ vfneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
 794   %}
 795   ins_pipe(pipe_slow);
 796 %}
 797 
 798 // vector add reduction
 799 
 800 instruct reduce_addB(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
 801   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
 802   match(Set dst (AddReductionVI src1 src2));
 803   effect(TEMP tmp);
 804   ins_cost(VEC_COST);
 805   format %{ "vmv.s.x $tmp, $src1\t#@reduce_addB\n\t"
 806             "vredsum.vs $tmp, $src2, $tmp\n\t"
 807             "vmv.x.s  $dst, $tmp" %}
 808   ins_encode %{
 809     __ vsetvli(t0, x0, Assembler::e8);
 810     __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register);
 811     __ vredsum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
 812                   as_VectorRegister($tmp$$reg));
 813     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
 814   %}
 815   ins_pipe(pipe_slow);
 816 %}
 817 
 818 instruct reduce_addS(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
 819   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT);
 820   match(Set dst (AddReductionVI src1 src2));
 821   effect(TEMP tmp);
 822   ins_cost(VEC_COST);
 823   format %{ "vmv.s.x $tmp, $src1\t#@reduce_addS\n\t"
 824             "vredsum.vs $tmp, $src2, $tmp\n\t"
 825             "vmv.x.s  $dst, $tmp" %}
 826   ins_encode %{
 827     __ vsetvli(t0, x0, Assembler::e16);
 828     __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register);
 829     __ vredsum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
 830                   as_VectorRegister($tmp$$reg));
 831     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
 832   %}
 833   ins_pipe(pipe_slow);
 834 %}
 835 
 836 instruct reduce_addI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
 837   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT);
 838   match(Set dst (AddReductionVI src1 src2));
 839   effect(TEMP tmp);
 840   ins_cost(VEC_COST);
 841   format %{ "vmv.s.x $tmp, $src1\t#@reduce_addI\n\t"
 842             "vredsum.vs $tmp, $src2, $tmp\n\t"
 843             "vmv.x.s  $dst, $tmp" %}
 844   ins_encode %{
 845     __ vsetvli(t0, x0, Assembler::e32);
 846     __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register);
 847     __ vredsum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
 848                   as_VectorRegister($tmp$$reg));
 849     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
 850   %}
 851   ins_pipe(pipe_slow);
 852 %}
 853 
 854 instruct reduce_addL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
 855   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG);
 856   match(Set dst (AddReductionVL src1 src2));
 857   effect(TEMP tmp);
 858   ins_cost(VEC_COST);
 859   format %{ "vmv.s.x $tmp, $src1\t#@reduce_addL\n\t"
 860             "vredsum.vs $tmp, $src2, $tmp\n\t"
 861             "vmv.x.s  $dst, $tmp" %}
 862   ins_encode %{
 863     __ vsetvli(t0, x0, Assembler::e64);
 864     __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register);
 865     __ vredsum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
 866                   as_VectorRegister($tmp$$reg));
 867     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
 868   %}
 869   ins_pipe(pipe_slow);
 870 %}
 871 
 872 instruct reduce_addF(fRegF src1_dst, vReg src2, vReg tmp) %{
 873   match(Set src1_dst (AddReductionVF src1_dst src2));
 874   effect(TEMP tmp);
 875   ins_cost(VEC_COST);
 876   format %{ "vfmv.s.f $tmp, $src1_dst\t#@reduce_addF\n\t"
 877             "vfredosum.vs $tmp, $src2, $tmp\n\t"
 878             "vfmv.f.s $src1_dst, $tmp" %}
 879   ins_encode %{
 880     __ vsetvli(t0, x0, Assembler::e32);
 881     __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1_dst$$FloatRegister);
 882     __ vfredosum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
 883                     as_VectorRegister($tmp$$reg));
 884     __ vfmv_f_s($src1_dst$$FloatRegister, as_VectorRegister($tmp$$reg));
 885   %}
 886   ins_pipe(pipe_slow);
 887 %}
 888 
 889 instruct reduce_addD(fRegD src1_dst, vReg src2, vReg tmp) %{
 890   match(Set src1_dst (AddReductionVD src1_dst src2));
 891   effect(TEMP tmp);
 892   ins_cost(VEC_COST);
 893   format %{ "vfmv.s.f $tmp, $src1_dst\t#@reduce_addD\n\t"
 894             "vfredosum.vs $tmp, $src2, $tmp\n\t"
 895             "vfmv.f.s $src1_dst, $tmp" %}
 896   ins_encode %{
 897     __ vsetvli(t0, x0, Assembler::e64);
 898     __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1_dst$$FloatRegister);
 899     __ vfredosum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
 900                     as_VectorRegister($tmp$$reg));
 901     __ vfmv_f_s($src1_dst$$FloatRegister, as_VectorRegister($tmp$$reg));
 902   %}
 903   ins_pipe(pipe_slow);
 904 %}
 905 
 906 // vector integer max reduction
 907 instruct vreduce_maxB(iRegINoSp dst, iRegI src1, vReg src2, vReg tmp) %{
 908   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
 909   match(Set dst (MaxReductionV src1 src2));
 910   ins_cost(VEC_COST);
 911   effect(TEMP tmp);
 912   format %{ "vreduce_maxB $dst, $src1, $src2, $tmp" %}
 913   ins_encode %{
 914     __ vsetvli(t0, x0, Assembler::e8);
 915     __ vredmax_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($src2$$reg));
 916     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
 917     Label Ldone;
 918     __ ble(as_Register($src1$$reg), as_Register($dst$$reg), Ldone);
 919     __ mv(as_Register($dst$$reg), as_Register($src1$$reg));
 920     __ bind(Ldone);
 921   %}
 922   ins_pipe(pipe_slow);
 923 %}
 924 
 925 instruct vreduce_maxS(iRegINoSp dst, iRegI src1, vReg src2, vReg tmp) %{
 926   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT);
 927   match(Set dst (MaxReductionV src1 src2));
 928   ins_cost(VEC_COST);
 929   effect(TEMP tmp);
 930   format %{ "vreduce_maxS $dst, $src1, $src2, $tmp" %}
 931   ins_encode %{
 932     __ vsetvli(t0, x0, Assembler::e16);
 933     __ vredmax_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($src2$$reg));
 934     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
 935     Label Ldone;
 936     __ ble(as_Register($src1$$reg), as_Register($dst$$reg), Ldone);
 937     __ mv(as_Register($dst$$reg), as_Register($src1$$reg));
 938     __ bind(Ldone);
 939   %}
 940   ins_pipe(pipe_slow);
 941 %}
 942 
 943 instruct vreduce_maxI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
 944   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT);
 945   match(Set dst (MaxReductionV src1 src2));
 946   ins_cost(VEC_COST);
 947   effect(TEMP tmp);
 948   format %{ "vreduce_maxI $dst, $src1, $src2, $tmp" %}
 949   ins_encode %{
 950     __ vsetvli(t0, x0, Assembler::e32);
 951     __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register);
 952     __ vredmax_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg));
 953     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
 954   %}
 955   ins_pipe(pipe_slow);
 956 %}
 957 
 958 instruct vreduce_maxL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
 959   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG);
 960   match(Set dst (MaxReductionV src1 src2));
 961   ins_cost(VEC_COST);
 962   effect(TEMP tmp);
 963   format %{ "vreduce_maxL $dst, $src1, $src2, $tmp" %}
 964   ins_encode %{
 965     __ vsetvli(t0, x0, Assembler::e64);
 966     __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register);
 967     __ vredmax_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg));
 968     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
 969   %}
 970   ins_pipe(pipe_slow);
 971 %}
 972 
 973 // vector integer min reduction
 974 instruct vreduce_minB(iRegINoSp dst, iRegI src1, vReg src2, vReg tmp) %{
 975   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
 976   match(Set dst (MinReductionV src1 src2));
 977   ins_cost(VEC_COST);
 978   effect(TEMP tmp);
 979   format %{ "vreduce_minB $dst, $src1, $src2, $tmp" %}
 980   ins_encode %{
 981     __ vsetvli(t0, x0, Assembler::e8);
 982     __ vredmin_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($src2$$reg));
 983     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
 984     Label Ldone;
 985     __ bge(as_Register($src1$$reg), as_Register($dst$$reg), Ldone);
 986     __ mv(as_Register($dst$$reg), as_Register($src1$$reg));
 987     __ bind(Ldone);
 988   %}
 989   ins_pipe(pipe_slow);
 990 %}
 991 
 992 instruct vreduce_minS(iRegINoSp dst, iRegI src1, vReg src2, vReg tmp) %{
 993   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT);
 994   match(Set dst (MinReductionV src1 src2));
 995   ins_cost(VEC_COST);
 996   effect(TEMP tmp);
 997   format %{ "vreduce_minS $dst, $src1, $src2, $tmp" %}
 998   ins_encode %{
 999     __ vsetvli(t0, x0, Assembler::e16);
1000     __ vredmin_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($src2$$reg));
1001     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
1002     Label Ldone;
1003     __ bge(as_Register($src1$$reg), as_Register($dst$$reg), Ldone);
1004     __ mv(as_Register($dst$$reg), as_Register($src1$$reg));
1005     __ bind(Ldone);
1006   %}
1007   ins_pipe(pipe_slow);
1008 %}
1009 
1010 instruct vreduce_minI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
1011   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT);
1012   match(Set dst (MinReductionV src1 src2));
1013   ins_cost(VEC_COST);
1014   effect(TEMP tmp);
1015   format %{ "vreduce_minI $dst, $src1, $src2, $tmp" %}
1016   ins_encode %{
1017     __ vsetvli(t0, x0, Assembler::e32);
1018     __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register);
1019     __ vredmin_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg));
1020     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
1021   %}
1022   ins_pipe(pipe_slow);
1023 %}
1024 
1025 instruct vreduce_minL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
1026   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG);
1027   match(Set dst (MinReductionV src1 src2));
1028   ins_cost(VEC_COST);
1029   effect(TEMP tmp);
1030   format %{ "vreduce_minL $dst, $src1, $src2, $tmp" %}
1031   ins_encode %{
1032     __ vsetvli(t0, x0, Assembler::e64);
1033     __ vmv_s_x(as_VectorRegister($tmp$$reg), $src1$$Register);
1034     __ vredmin_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg));
1035     __ vmv_x_s($dst$$Register, as_VectorRegister($tmp$$reg));
1036   %}
1037   ins_pipe(pipe_slow);
1038 %}
1039 
1040 // vector float max reduction
1041 
1042 instruct vreduce_maxF(fRegF dst, fRegF src1, vReg src2, vReg tmp1, vReg tmp2) %{
1043   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
1044   match(Set dst (MaxReductionV src1 src2));
1045   ins_cost(VEC_COST);
1046   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
1047   format %{ "reduce_maxF $dst, $src1, $src2, $tmp1, $tmp2" %}
1048   ins_encode %{
1049     __ reduce_minmax_FD_v($dst$$FloatRegister,
1050                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
1051                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
1052                           false /* is_double */, false /* is_min */);
1053   %}
1054   ins_pipe(pipe_slow);
1055 %}
1056 
1057 instruct vreduce_maxD(fRegD dst, fRegD src1, vReg src2, vReg tmp1, vReg tmp2) %{
1058   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
1059   match(Set dst (MaxReductionV src1 src2));
1060   ins_cost(VEC_COST);
1061   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
1062   format %{ "reduce_maxD $dst, $src1, $src2, $tmp1, $tmp2" %}
1063   ins_encode %{
1064     __ reduce_minmax_FD_v($dst$$FloatRegister,
1065                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
1066                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
1067                           true /* is_double */, false /* is_min */);
1068   %}
1069   ins_pipe(pipe_slow);
1070 %}
1071 
1072 // vector float min reduction
1073 
1074 instruct vreduce_minF(fRegF dst, fRegF src1, vReg src2, vReg tmp1, vReg tmp2) %{
1075   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
1076   match(Set dst (MinReductionV src1 src2));
1077   ins_cost(VEC_COST);
1078   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
1079   format %{ "reduce_minF $dst, $src1, $src2, $tmp1, $tmp2" %}
1080   ins_encode %{
1081     __ reduce_minmax_FD_v($dst$$FloatRegister,
1082                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
1083                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
1084                           false /* is_double */, true /* is_min */);
1085   %}
1086   ins_pipe(pipe_slow);
1087 %}
1088 
1089 instruct vreduce_minD(fRegD dst, fRegD src1, vReg src2, vReg tmp1, vReg tmp2) %{
1090   predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
1091   match(Set dst (MinReductionV src1 src2));
1092   ins_cost(VEC_COST);
1093   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
1094   format %{ "reduce_minD $dst, $src1, $src2, $tmp1, $tmp2" %}
1095   ins_encode %{
1096     __ reduce_minmax_FD_v($dst$$FloatRegister,
1097                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
1098                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
1099                           true /* is_double */, true /* is_min */);
1100   %}
1101   ins_pipe(pipe_slow);
1102 %}
1103 
1104 // vector Math.rint, floor, ceil
1105 
1106 instruct vroundD(vReg dst, vReg src, immI rmode) %{
1107   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
1108   match(Set dst (RoundDoubleModeV src rmode));
1109   format %{ "vroundD $dst, $src, $rmode" %}
1110   ins_encode %{
1111     switch ($rmode$$constant) {
1112       case RoundDoubleModeNode::rmode_rint:
1113         __ csrwi(CSR_FRM, C2_MacroAssembler::rne);
1114         __ vfcvt_rtz_x_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
1115         break;
1116       case RoundDoubleModeNode::rmode_floor:
1117         __ csrwi(CSR_FRM, C2_MacroAssembler::rdn);
1118         __ vfcvt_rtz_x_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
1119         break;
1120       case RoundDoubleModeNode::rmode_ceil:
1121         __ csrwi(CSR_FRM, C2_MacroAssembler::rup);
1122         __ vfcvt_rtz_x_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
1123         break;
1124       default:
1125         ShouldNotReachHere();
1126         break;
1127     }
1128   %}
1129   ins_pipe(pipe_slow);
1130 %}
1131 
1132 // vector replicate
1133 
1134 instruct replicateB(vReg dst, iRegIorL2I src) %{
1135   match(Set dst (ReplicateB src));
1136   ins_cost(VEC_COST);
1137   format %{ "vmv.v.x  $dst, $src\t#@replicateB" %}
1138   ins_encode %{
1139     __ vsetvli(t0, x0, Assembler::e8);
1140     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
1141   %}
1142   ins_pipe(pipe_slow);
1143 %}
1144 
1145 instruct replicateS(vReg dst, iRegIorL2I src) %{
1146   match(Set dst (ReplicateS src));
1147   ins_cost(VEC_COST);
1148   format %{ "vmv.v.x  $dst, $src\t#@replicateS" %}
1149   ins_encode %{
1150     __ vsetvli(t0, x0, Assembler::e16);
1151     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
1152   %}
1153   ins_pipe(pipe_slow);
1154 %}
1155 
1156 instruct replicateI(vReg dst, iRegIorL2I src) %{
1157   match(Set dst (ReplicateI src));
1158   ins_cost(VEC_COST);
1159   format %{ "vmv.v.x  $dst, $src\t#@replicateI" %}
1160   ins_encode %{
1161     __ vsetvli(t0, x0, Assembler::e32);
1162     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
1163   %}
1164   ins_pipe(pipe_slow);
1165 %}
1166 
1167 instruct replicateL(vReg dst, iRegL src) %{
1168   match(Set dst (ReplicateL src));
1169   ins_cost(VEC_COST);
1170   format %{ "vmv.v.x  $dst, $src\t#@replicateL" %}
1171   ins_encode %{
1172     __ vsetvli(t0, x0, Assembler::e64);
1173     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
1174   %}
1175   ins_pipe(pipe_slow);
1176 %}
1177 
1178 instruct replicateB_imm5(vReg dst, immI5 con) %{
1179   match(Set dst (ReplicateB con));
1180   ins_cost(VEC_COST);
1181   format %{ "vmv.v.i  $dst, $con\t#@replicateB_imm5" %}
1182   ins_encode %{
1183     __ vsetvli(t0, x0, Assembler::e8);
1184     __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant);
1185   %}
1186   ins_pipe(pipe_slow);
1187 %}
1188 
1189 instruct replicateS_imm5(vReg dst, immI5 con) %{
1190   match(Set dst (ReplicateS con));
1191   ins_cost(VEC_COST);
1192   format %{ "vmv.v.i  $dst, $con\t#@replicateS_imm5" %}
1193   ins_encode %{
1194     __ vsetvli(t0, x0, Assembler::e16);
1195     __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant);
1196   %}
1197   ins_pipe(pipe_slow);
1198 %}
1199 
1200 instruct replicateI_imm5(vReg dst, immI5 con) %{
1201   match(Set dst (ReplicateI con));
1202   ins_cost(VEC_COST);
1203   format %{ "vmv.v.i  $dst, $con\t#@replicateI_imm5" %}
1204   ins_encode %{
1205     __ vsetvli(t0, x0, Assembler::e32);
1206     __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant);
1207   %}
1208   ins_pipe(pipe_slow);
1209 %}
1210 
1211 instruct replicateL_imm5(vReg dst, immL5 con) %{
1212   match(Set dst (ReplicateL con));
1213   ins_cost(VEC_COST);
1214   format %{ "vmv.v.i  $dst, $con\t#@replicateL_imm5" %}
1215   ins_encode %{
1216     __ vsetvli(t0, x0, Assembler::e64);
1217     __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant);
1218   %}
1219   ins_pipe(pipe_slow);
1220 %}
1221 
1222 instruct replicateF(vReg dst, fRegF src) %{
1223   match(Set dst (ReplicateF src));
1224   ins_cost(VEC_COST);
1225   format %{ "vfmv.v.f  $dst, $src\t#@replicateF" %}
1226   ins_encode %{
1227     __ vsetvli(t0, x0, Assembler::e32);
1228     __ vfmv_v_f(as_VectorRegister($dst$$reg), $src$$FloatRegister);
1229   %}
1230   ins_pipe(pipe_slow);
1231 %}
1232 
1233 instruct replicateD(vReg dst, fRegD src) %{
1234   match(Set dst (ReplicateD src));
1235   ins_cost(VEC_COST);
1236   format %{ "vfmv.v.f  $dst, $src\t#@replicateD" %}
1237   ins_encode %{
1238     __ vsetvli(t0, x0, Assembler::e64);
1239     __ vfmv_v_f(as_VectorRegister($dst$$reg), $src$$FloatRegister);
1240   %}
1241   ins_pipe(pipe_slow);
1242 %}
1243 
1244 // vector shift
1245 
1246 instruct vasrB(vReg dst, vReg src, vReg shift) %{
1247   match(Set dst (RShiftVB src shift));
1248   ins_cost(VEC_COST);
1249   effect(TEMP_DEF dst);
1250   format %{ "vmsgtu.vi v0, $shift 7\t#@vasrB\n\t"
1251             "vsra.vi $dst, $src, 7, Assembler::v0_t\n\t"
1252             "vmnot.m v0, v0\n\t"
1253             "vsra.vv $dst, $src, $shift, Assembler::v0_t" %}
1254   ins_encode %{
1255     __ vsetvli(t0, x0, Assembler::e8);
1256     // if shift > BitsPerByte - 1, clear the low BitsPerByte - 1 bits
1257     __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1);
1258     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1259                BitsPerByte - 1, Assembler::v0_t);
1260     // otherwise, shift
1261     __ vmnot_m(v0, v0);
1262     __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1263                as_VectorRegister($shift$$reg), Assembler::v0_t);
1264   %}
1265   ins_pipe(pipe_slow);
1266 %}
1267 
1268 instruct vasrS(vReg dst, vReg src, vReg shift) %{
1269   match(Set dst (RShiftVS src shift));
1270   ins_cost(VEC_COST);
1271   effect(TEMP_DEF dst);
1272   format %{ "vmsgtu.vi v0, $shift, 15\t#@vasrS\n\t"
1273             "vsra.vi $dst, $src, 15, Assembler::v0_t\n\t"
1274             "vmnot.m v0, v0\n\t"
1275             "vsra.vv $dst, $src, $shift, Assembler::v0_t" %}
1276   ins_encode %{
1277     __ vsetvli(t0, x0, Assembler::e16);
1278     // if shift > BitsPerShort - 1, clear the low BitsPerShort - 1 bits
1279     __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1);
1280     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1281                BitsPerShort - 1, Assembler::v0_t);
1282     // otherwise, shift
1283     __ vmnot_m(v0, v0);
1284     __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1285                as_VectorRegister($shift$$reg), Assembler::v0_t);
1286   %}
1287   ins_pipe(pipe_slow);
1288 %}
1289 
1290 instruct vasrI(vReg dst, vReg src, vReg shift) %{
1291   match(Set dst (RShiftVI src shift));
1292   ins_cost(VEC_COST);
1293   format %{ "vsra.vv $dst, $src, $shift\t#@vasrI" %}
1294   ins_encode %{
1295     __ vsetvli(t0, x0, Assembler::e32);
1296     __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1297                as_VectorRegister($shift$$reg));
1298   %}
1299   ins_pipe(pipe_slow);
1300 %}
1301 
1302 instruct vasrL(vReg dst, vReg src, vReg shift) %{
1303   match(Set dst (RShiftVL src shift));
1304   ins_cost(VEC_COST);
1305   format %{ "vsra.vv $dst, $src, $shift\t#@vasrL" %}
1306   ins_encode %{
1307     __ vsetvli(t0, x0, Assembler::e64);
1308     __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1309          as_VectorRegister($shift$$reg));
1310   %}
1311   ins_pipe(pipe_slow);
1312 %}
1313 
1314 instruct vlslB(vReg dst, vReg src, vReg shift) %{
1315   match(Set dst (LShiftVB src shift));
1316   ins_cost(VEC_COST);
1317   effect( TEMP_DEF dst);
1318   format %{ "vmsgtu.vi v0, $shift, 7\t#@vlslB\n\t"
1319             "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t"
1320             "vmnot.m v0, v0\n\t"
1321             "vsll.vv $dst, $src, $shift, Assembler::v0_t" %}
1322   ins_encode %{
1323     __ vsetvli(t0, x0, Assembler::e8);
1324     // if shift > BitsPerByte - 1, clear the element
1325     __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1);
1326     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1327                as_VectorRegister($src$$reg), Assembler::v0_t);
1328     // otherwise, shift
1329     __ vmnot_m(v0, v0);
1330     __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1331                as_VectorRegister($shift$$reg), Assembler::v0_t);
1332   %}
1333   ins_pipe(pipe_slow);
1334 %}
1335 
1336 instruct vlslS(vReg dst, vReg src, vReg shift) %{
1337   match(Set dst (LShiftVS src shift));
1338   ins_cost(VEC_COST);
1339   effect(TEMP_DEF dst);
1340   format %{ "vmsgtu.vi v0, $shift, 15\t#@vlslS\n\t"
1341             "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t"
1342             "vmnot.m v0, v0\n\t"
1343             "vsll.vv $dst, $src, $shift, Assembler::v0_t" %}
1344   ins_encode %{
1345     __ vsetvli(t0, x0, Assembler::e16);
1346     // if shift > BitsPerShort - 1, clear the element
1347     __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1);
1348     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1349                as_VectorRegister($src$$reg), Assembler::v0_t);
1350     // otherwise, shift
1351     __ vmnot_m(v0, v0);
1352     __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1353                as_VectorRegister($shift$$reg), Assembler::v0_t);
1354   %}
1355   ins_pipe(pipe_slow);
1356 %}
1357 
1358 instruct vlslI(vReg dst, vReg src, vReg shift) %{
1359   match(Set dst (LShiftVI src shift));
1360   ins_cost(VEC_COST);
1361   format %{ "vsll.vv $dst, $src, $shift\t#@vlslI" %}
1362   ins_encode %{
1363     __ vsetvli(t0, x0, Assembler::e32);
1364     __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1365                as_VectorRegister($shift$$reg));
1366   %}
1367   ins_pipe(pipe_slow);
1368 %}
1369 
1370 instruct vlslL(vReg dst, vReg src, vReg shift) %{
1371   match(Set dst (LShiftVL src shift));
1372   ins_cost(VEC_COST);
1373   format %{ "vsll.vv $dst, $src, $shift\t# vector (D)" %}
1374   ins_encode %{
1375     __ vsetvli(t0, x0, Assembler::e64);
1376     __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1377                as_VectorRegister($shift$$reg));
1378   %}
1379   ins_pipe(pipe_slow);
1380 %}
1381 
1382 instruct vlsrB(vReg dst, vReg src, vReg shift) %{
1383   match(Set dst (URShiftVB src shift));
1384   ins_cost(VEC_COST);
1385   effect(TEMP_DEF dst);
1386   format %{ "vmsgtu.vi v0, $shift, 7\t#@vlsrB\n\t"
1387             "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t"
1388             "vmnot.m v0, v0, v0\n\t"
1389             "vsll.vv $dst, $src, $shift, Assembler::v0_t" %}
1390   ins_encode %{
1391     __ vsetvli(t0, x0, Assembler::e8);
1392     // if shift > BitsPerByte - 1, clear the element
1393     __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1);
1394     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1395                as_VectorRegister($src$$reg), Assembler::v0_t);
1396     // otherwise, shift
1397     __ vmnot_m(v0, v0);
1398     __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1399                as_VectorRegister($shift$$reg), Assembler::v0_t);
1400   %}
1401   ins_pipe(pipe_slow);
1402 %}
1403 
1404 instruct vlsrS(vReg dst, vReg src, vReg shift) %{
1405   match(Set dst (URShiftVS src shift));
1406   ins_cost(VEC_COST);
1407   effect(TEMP_DEF dst);
1408   format %{ "vmsgtu.vi v0, $shift, 15\t#@vlsrS\n\t"
1409             "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t"
1410             "vmnot.m v0, v0\n\t"
1411             "vsll.vv $dst, $src, $shift, Assembler::v0_t" %}
1412   ins_encode %{
1413     __ vsetvli(t0, x0, Assembler::e16);
1414     // if shift > BitsPerShort - 1, clear the element
1415     __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1);
1416     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1417                as_VectorRegister($src$$reg), Assembler::v0_t);
1418     // otherwise, shift
1419     __ vmnot_m(v0, v0);
1420     __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1421                as_VectorRegister($shift$$reg), Assembler::v0_t);
1422   %}
1423   ins_pipe(pipe_slow);
1424 %}
1425 
1426 
1427 instruct vlsrI(vReg dst, vReg src, vReg shift) %{
1428   match(Set dst (URShiftVI src shift));
1429   ins_cost(VEC_COST);
1430   format %{ "vsrl.vv $dst, $src, $shift\t#@vlsrI" %}
1431   ins_encode %{
1432     __ vsetvli(t0, x0, Assembler::e32);
1433     __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1434                as_VectorRegister($shift$$reg));
1435   %}
1436   ins_pipe(pipe_slow);
1437 %}
1438 
1439 
1440 instruct vlsrL(vReg dst, vReg src, vReg shift) %{
1441   match(Set dst (URShiftVL src shift));
1442   ins_cost(VEC_COST);
1443   format %{ "vsrl.vv $dst, $src, $shift\t#@vlsrL" %}
1444   ins_encode %{
1445     __ vsetvli(t0, x0, Assembler::e64);
1446     __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1447                as_VectorRegister($shift$$reg));
1448   %}
1449   ins_pipe(pipe_slow);
1450 %}
1451 
1452 instruct vasrB_imm(vReg dst, vReg src, immI shift) %{
1453   match(Set dst (RShiftVB src (RShiftCntV shift)));
1454   ins_cost(VEC_COST);
1455   format %{ "vsra.vi $dst, $src, $shift\t#@vasrB_imm" %}
1456   ins_encode %{
1457     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1458     __ vsetvli(t0, x0, Assembler::e8);
1459     if (con == 0) {
1460       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1461                 as_VectorRegister($src$$reg));
1462       return;
1463     }
1464     if (con >= BitsPerByte) con = BitsPerByte - 1;
1465     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1466   %}
1467   ins_pipe(pipe_slow);
1468 %}
1469 
1470 instruct vasrS_imm(vReg dst, vReg src, immI shift) %{
1471   match(Set dst (RShiftVS src (RShiftCntV shift)));
1472   ins_cost(VEC_COST);
1473   format %{ "vsra.vi $dst, $src, $shift\t#@vasrS_imm" %}
1474   ins_encode %{
1475     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1476     __ vsetvli(t0, x0, Assembler::e16);
1477     if (con == 0) {
1478       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1479                 as_VectorRegister($src$$reg));
1480       return;
1481     }
1482     if (con >= BitsPerShort) con = BitsPerShort - 1;
1483     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1484   %}
1485   ins_pipe(pipe_slow);
1486 %}
1487 
1488 instruct vasrI_imm(vReg dst, vReg src, immI shift) %{
1489   match(Set dst (RShiftVI src (RShiftCntV shift)));
1490   ins_cost(VEC_COST);
1491   format %{ "vsrl.vi $dst, $src, $shift\t#@vasrI_imm" %}
1492   ins_encode %{
1493     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1494     __ vsetvli(t0, x0, Assembler::e32);
1495     if (con == 0) {
1496       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1497                 as_VectorRegister($src$$reg));
1498       return;
1499     }
1500     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1501   %}
1502   ins_pipe(pipe_slow);
1503 %}
1504 
1505 instruct vasrL_imm(vReg dst, vReg src, immI shift) %{
1506   predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32);
1507   match(Set dst (RShiftVL src (RShiftCntV shift)));
1508   ins_cost(VEC_COST);
1509   format %{ "vsrl.vi $dst, $src, $shift\t#@vasrL_imm" %}
1510   ins_encode %{
1511     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1512     __ vsetvli(t0, x0, Assembler::e64);
1513     if (con == 0) {
1514       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1515                 as_VectorRegister($src$$reg));
1516       return;
1517     }
1518     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1519   %}
1520   ins_pipe(pipe_slow);
1521 %}
1522 
1523 instruct vlsrB_imm(vReg dst, vReg src, immI shift) %{
1524   match(Set dst (URShiftVB src (RShiftCntV shift)));
1525   ins_cost(VEC_COST);
1526   format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrB_imm" %}
1527   ins_encode %{
1528     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1529     __ vsetvli(t0, x0, Assembler::e8);
1530     if (con == 0) {
1531       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1532                 as_VectorRegister($src$$reg));
1533       return;
1534     }
1535     if (con >= BitsPerByte) {
1536       __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1537                  as_VectorRegister($src$$reg));
1538       return;
1539     }
1540     __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1541   %}
1542   ins_pipe(pipe_slow);
1543 %}
1544 
1545 instruct vlsrS_imm(vReg dst, vReg src, immI shift) %{
1546   match(Set dst (URShiftVS src (RShiftCntV shift)));
1547   ins_cost(VEC_COST);
1548   format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrS_imm" %}
1549   ins_encode %{
1550     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1551     __ vsetvli(t0, x0, Assembler::e16);
1552     if (con == 0) {
1553       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1554                 as_VectorRegister($src$$reg));
1555       return;
1556     }
1557     if (con >= BitsPerShort) {
1558       __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1559                  as_VectorRegister($src$$reg));
1560       return;
1561     }
1562     __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1563   %}
1564   ins_pipe(pipe_slow);
1565 %}
1566 
1567 instruct vlsrI_imm(vReg dst, vReg src, immI shift) %{
1568   match(Set dst (URShiftVI src (RShiftCntV shift)));
1569   ins_cost(VEC_COST);
1570   format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrI_imm" %}
1571   ins_encode %{
1572     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1573     __ vsetvli(t0, x0, Assembler::e32);
1574     if (con == 0) {
1575       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1576                 as_VectorRegister($src$$reg));
1577       return;
1578     }
1579     __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1580   %}
1581   ins_pipe(pipe_slow);
1582 %}
1583 
1584 instruct vlsrL_imm(vReg dst, vReg src, immI shift) %{
1585   predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32);
1586   match(Set dst (URShiftVL src (RShiftCntV shift)));
1587   ins_cost(VEC_COST);
1588   format %{ "vsrl.vi $dst, $src, $shift\t#@vlsrL_imm" %}
1589   ins_encode %{
1590     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1591     __ vsetvli(t0, x0, Assembler::e64);
1592     if (con == 0) {
1593       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1594                 as_VectorRegister($src$$reg));
1595       return;
1596     }
1597     __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1598   %}
1599   ins_pipe(pipe_slow);
1600 %}
1601 
1602 instruct vlslB_imm(vReg dst, vReg src, immI shift) %{
1603   match(Set dst (LShiftVB src (LShiftCntV shift)));
1604   ins_cost(VEC_COST);
1605   format %{ "vsll.vi $dst, $src, $shift\t#@vlslB_imm" %}
1606   ins_encode %{
1607     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1608     __ vsetvli(t0, x0, Assembler::e8);
1609     if (con >= BitsPerByte) {
1610       __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1611                  as_VectorRegister($src$$reg));
1612       return;
1613     }
1614     __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1615   %}
1616   ins_pipe(pipe_slow);
1617 %}
1618 
1619 instruct vlslS_imm(vReg dst, vReg src, immI shift) %{
1620   match(Set dst (LShiftVS src (LShiftCntV shift)));
1621   ins_cost(VEC_COST);
1622   format %{ "vsll.vi $dst, $src, $shift\t#@vlslS_imm" %}
1623   ins_encode %{
1624     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1625     __ vsetvli(t0, x0, Assembler::e16);
1626     if (con >= BitsPerShort) {
1627       __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
1628                  as_VectorRegister($src$$reg));
1629       return;
1630     }
1631     __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1632   %}
1633   ins_pipe(pipe_slow);
1634 %}
1635 
1636 instruct vlslI_imm(vReg dst, vReg src, immI shift) %{
1637   match(Set dst (LShiftVI src (LShiftCntV shift)));
1638   ins_cost(VEC_COST);
1639   format %{ "vsll.vi $dst, $src, $shift\t#@vlslI_imm" %}
1640   ins_encode %{
1641     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1642     __ vsetvli(t0, x0, Assembler::e32);
1643     __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1644   %}
1645   ins_pipe(pipe_slow);
1646 %}
1647 
1648 instruct vlslL_imm(vReg dst, vReg src, immI shift) %{
1649   predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32);
1650   match(Set dst (LShiftVL src (LShiftCntV shift)));
1651   ins_cost(VEC_COST);
1652   format %{ "vsll.vi $dst, $src, $shift\t#@vlslL_imm" %}
1653   ins_encode %{
1654     uint32_t con = (unsigned)$shift$$constant & 0x1f;
1655     __ vsetvli(t0, x0, Assembler::e64);
1656     __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
1657   %}
1658   ins_pipe(pipe_slow);
1659 %}
1660 
1661 instruct vshiftcntB(vReg dst, iRegIorL2I cnt) %{
1662   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
1663   match(Set dst (LShiftCntV cnt));
1664   match(Set dst (RShiftCntV cnt));
1665   format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntB" %}
1666   ins_encode %{
1667     __ vsetvli(t0, x0, Assembler::e8);
1668     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg));
1669   %}
1670   ins_pipe(pipe_slow);
1671 %}
1672 
1673 instruct vshiftcntS(vReg dst, iRegIorL2I cnt) %{
1674   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_SHORT ||
1675             n->bottom_type()->is_vect()->element_basic_type() == T_CHAR);
1676   match(Set dst (LShiftCntV cnt));
1677   match(Set dst (RShiftCntV cnt));
1678   format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntS" %}
1679   ins_encode %{
1680     __ vsetvli(t0, x0, Assembler::e16);
1681     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg));
1682   %}
1683   ins_pipe(pipe_slow);
1684 %}
1685 
1686 instruct vshiftcntI(vReg dst, iRegIorL2I cnt) %{
1687   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_INT);
1688   match(Set dst (LShiftCntV cnt));
1689   match(Set dst (RShiftCntV cnt));
1690   format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntI" %}
1691   ins_encode %{
1692     __ vsetvli(t0, x0, Assembler::e32);
1693     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg));
1694   %}
1695   ins_pipe(pipe_slow);
1696 %}
1697 
1698 instruct vshiftcntL(vReg dst, iRegIorL2I cnt) %{
1699   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_LONG);
1700   match(Set dst (LShiftCntV cnt));
1701   match(Set dst (RShiftCntV cnt));
1702   format %{ "vmv.v.x $dst, $cnt\t#@vshiftcntL" %}
1703   ins_encode %{
1704     __ vsetvli(t0, x0, Assembler::e64);
1705     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg));
1706   %}
1707   ins_pipe(pipe_slow);
1708 %}
1709 
1710 // vector sqrt
1711 
1712 instruct vsqrtF(vReg dst, vReg src) %{
1713   match(Set dst (SqrtVF src));
1714   ins_cost(VEC_COST);
1715   format %{ "vfsqrt.v $dst, $src\t#@vsqrtF" %}
1716   ins_encode %{
1717     __ vsetvli(t0, x0, Assembler::e32);
1718     __ vfsqrt_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
1719   %}
1720   ins_pipe(pipe_slow);
1721 %}
1722 
1723 instruct vsqrtD(vReg dst, vReg src) %{
1724   match(Set dst (SqrtVD src));
1725   ins_cost(VEC_COST);
1726   format %{ "vfsqrt.v $dst, $src\t#@vsqrtD" %}
1727   ins_encode %{
1728     __ vsetvli(t0, x0, Assembler::e64);
1729     __ vfsqrt_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
1730   %}
1731   ins_pipe(pipe_slow);
1732 %}
1733 
1734 // vector sub
1735 
1736 instruct vsubB(vReg dst, vReg src1, vReg src2) %{
1737   match(Set dst (SubVB src1 src2));
1738   ins_cost(VEC_COST);
1739   format %{ "vsub.vv $dst, $src1, $src2\t#@vsubB" %}
1740   ins_encode %{
1741     __ vsetvli(t0, x0, Assembler::e8);
1742     __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
1743                as_VectorRegister($src2$$reg));
1744   %}
1745   ins_pipe(pipe_slow);
1746 %}
1747 
1748 instruct vsubS(vReg dst, vReg src1, vReg src2) %{
1749   match(Set dst (SubVS src1 src2));
1750   ins_cost(VEC_COST);
1751   format %{ "vsub.vv $dst, $src1, $src2\t#@vsubS" %}
1752   ins_encode %{
1753     __ vsetvli(t0, x0, Assembler::e16);
1754     __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
1755                as_VectorRegister($src2$$reg));
1756   %}
1757   ins_pipe(pipe_slow);
1758 %}
1759 
1760 instruct vsubI(vReg dst, vReg src1, vReg src2) %{
1761   match(Set dst (SubVI src1 src2));
1762   ins_cost(VEC_COST);
1763   format %{ "vsub.vv $dst, $src1, $src2\t#@vsubI" %}
1764   ins_encode %{
1765     __ vsetvli(t0, x0, Assembler::e32);
1766     __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
1767                as_VectorRegister($src2$$reg));
1768   %}
1769   ins_pipe(pipe_slow);
1770 %}
1771 
1772 instruct vsubL(vReg dst, vReg src1, vReg src2) %{
1773   match(Set dst (SubVL src1 src2));
1774   ins_cost(VEC_COST);
1775   format %{ "vsub.vv $dst, $src1, $src2\t#@vsubL" %}
1776   ins_encode %{
1777     __ vsetvli(t0, x0, Assembler::e64);
1778     __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
1779                as_VectorRegister($src2$$reg));
1780   %}
1781   ins_pipe(pipe_slow);
1782 %}
1783 
1784 instruct vsubF(vReg dst, vReg src1, vReg src2) %{
1785   match(Set dst (SubVF src1 src2));
1786   ins_cost(VEC_COST);
1787   format %{ "vfsub.vv $dst, $src1, $src2\t@vsubF" %}
1788   ins_encode %{
1789     __ vsetvli(t0, x0, Assembler::e32);
1790     __ vfsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
1791                 as_VectorRegister($src2$$reg));
1792   %}
1793   ins_pipe(pipe_slow);
1794 %}
1795 
1796 instruct vsubD(vReg dst, vReg src1, vReg src2) %{
1797   match(Set dst (SubVD src1 src2));
1798   ins_cost(VEC_COST);
1799   format %{ "vfsub.vv $dst, $src1, $src2\t#@vsubD" %}
1800   ins_encode %{
1801     __ vsetvli(t0, x0, Assembler::e64);
1802     __ vfsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
1803                 as_VectorRegister($src2$$reg));
1804   %}
1805   ins_pipe(pipe_slow);
1806 %}
1807 
1808 instruct vstring_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt,
1809                          iRegI_R10 result, vReg_V1 v1,
1810                          vReg_V2 v2, vReg_V3 v3, rFlagsReg cr)
1811 %{
1812   predicate(UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
1813   match(Set result (StrEquals (Binary str1 str2) cnt));
1814   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v1, TEMP v2, TEMP v3, KILL cr);
1815 
1816   format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %}
1817   ins_encode %{
1818     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
1819     __ string_equals_v($str1$$Register, $str2$$Register,
1820                        $result$$Register, $cnt$$Register, 1);
1821   %}
1822   ins_pipe(pipe_class_memory);
1823 %}
1824 
1825 instruct vstring_equalsU(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt,
1826                          iRegI_R10 result, vReg_V1 v1,
1827                          vReg_V2 v2, vReg_V3 v3, rFlagsReg cr)
1828 %{
1829   predicate(UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
1830   match(Set result (StrEquals (Binary str1 str2) cnt));
1831   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v1, TEMP v2, TEMP v3, KILL cr);
1832 
1833   format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsU" %}
1834   ins_encode %{
1835     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
1836     __ string_equals_v($str1$$Register, $str2$$Register,
1837                        $result$$Register, $cnt$$Register, 2);
1838   %}
1839   ins_pipe(pipe_class_memory);
1840 %}
1841 
1842 instruct varray_equalsB(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result,
1843                         vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegP_R28 tmp, rFlagsReg cr)
1844 %{
1845   predicate(UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
1846   match(Set result (AryEq ary1 ary2));
1847   effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v1, TEMP v2, TEMP v3, KILL cr);
1848 
1849   format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsB // KILL $tmp" %}
1850   ins_encode %{
1851     __ arrays_equals_v($ary1$$Register, $ary2$$Register,
1852                        $result$$Register, $tmp$$Register, 1);
1853     %}
1854   ins_pipe(pipe_class_memory);
1855 %}
1856 
1857 instruct varray_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result,
1858                         vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegP_R28 tmp, rFlagsReg cr)
1859 %{
1860   predicate(UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
1861   match(Set result (AryEq ary1 ary2));
1862   effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v1, TEMP v2, TEMP v3, KILL cr);
1863 
1864   format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsC // KILL $tmp" %}
1865   ins_encode %{
1866     __ arrays_equals_v($ary1$$Register, $ary2$$Register,
1867                        $result$$Register, $tmp$$Register, 2);
1868   %}
1869   ins_pipe(pipe_class_memory);
1870 %}
1871 
1872 instruct vstring_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
1873                           iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5,
1874                           iRegP_R28 tmp1, iRegL_R29 tmp2)
1875 %{
1876   predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU);
1877   match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2)));
1878   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
1879          TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5);
1880 
1881   format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareU" %}
1882   ins_encode %{
1883     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
1884     __ string_compare_v($str1$$Register, $str2$$Register,
1885                         $cnt1$$Register, $cnt2$$Register, $result$$Register,
1886                         $tmp1$$Register, $tmp2$$Register,
1887                         StrIntrinsicNode::UU);
1888   %}
1889   ins_pipe(pipe_class_memory);
1890 %}
1891 instruct vstring_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
1892                           iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5,
1893                           iRegP_R28 tmp1, iRegL_R29 tmp2)
1894 %{
1895   predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LL);
1896   match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2)));
1897   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
1898          TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5);
1899 
1900   format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareL" %}
1901   ins_encode %{
1902     __ string_compare_v($str1$$Register, $str2$$Register,
1903                         $cnt1$$Register, $cnt2$$Register, $result$$Register,
1904                         $tmp1$$Register, $tmp2$$Register,
1905                         StrIntrinsicNode::LL);
1906   %}
1907   ins_pipe(pipe_class_memory);
1908 %}
1909 
1910 instruct vstring_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
1911                            iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5,
1912                            iRegP_R28 tmp1, iRegL_R29 tmp2)
1913 %{
1914   predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UL);
1915   match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2)));
1916   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
1917          TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5);
1918 
1919   format %{"String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareUL" %}
1920   ins_encode %{
1921     __ string_compare_v($str1$$Register, $str2$$Register,
1922                         $cnt1$$Register, $cnt2$$Register, $result$$Register,
1923                         $tmp1$$Register, $tmp2$$Register,
1924                         StrIntrinsicNode::UL);
1925   %}
1926   ins_pipe(pipe_class_memory);
1927 %}
1928 instruct vstring_compareLU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
1929                            iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5,
1930                            iRegP_R28 tmp1, iRegL_R29 tmp2)
1931 %{
1932   predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LU);
1933   match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2)));
1934   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
1935          TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5);
1936 
1937   format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareLU" %}
1938   ins_encode %{
1939     __ string_compare_v($str1$$Register, $str2$$Register,
1940                         $cnt1$$Register, $cnt2$$Register, $result$$Register,
1941                         $tmp1$$Register, $tmp2$$Register,
1942                         StrIntrinsicNode::LU);
1943   %}
1944   ins_pipe(pipe_class_memory);
1945 %}
1946 
1947 // fast byte[] to char[] inflation
1948 instruct vstring_inflate(Universe dummy, iRegP_R10 src, iRegP_R11 dst, iRegI_R12 len,
1949                          vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp)
1950 %{
1951   predicate(UseRVV);
1952   match(Set dummy (StrInflatedCopy src (Binary dst len)));
1953   effect(TEMP v1, TEMP v2, TEMP v3, TEMP tmp, USE_KILL src, USE_KILL dst, USE_KILL len);
1954 
1955   format %{ "String Inflate $src,$dst" %}
1956   ins_encode %{
1957     __ byte_array_inflate_v($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register);
1958   %}
1959   ins_pipe(pipe_class_memory);
1960 %}
1961 
1962 // encode char[] to byte[] in ISO_8859_1
1963 instruct vencode_iso_array(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result,
1964                            vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp)
1965 %{
1966   predicate(UseRVV);
1967   match(Set result (EncodeISOArray src (Binary dst len)));
1968   effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len,
1969          TEMP v1, TEMP v2, TEMP v3, TEMP tmp);
1970 
1971   format %{ "Encode array $src,$dst,$len -> $result" %}
1972   ins_encode %{
1973     __ encode_iso_array_v($src$$Register, $dst$$Register, $len$$Register,
1974                           $result$$Register, $tmp$$Register);
1975   %}
1976   ins_pipe( pipe_class_memory );
1977 %}
1978 
1979 // fast char[] to byte[] compression
1980 instruct vstring_compress(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result,
1981                           vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp)
1982 %{
1983   predicate(UseRVV);
1984   match(Set result (StrCompressedCopy src (Binary dst len)));
1985   effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len,
1986          TEMP v1, TEMP v2, TEMP v3, TEMP tmp);
1987 
1988   format %{ "String Compress $src,$dst -> $result    // KILL R11, R12, R13" %}
1989   ins_encode %{
1990     __ char_array_compress_v($src$$Register, $dst$$Register, $len$$Register,
1991                              $result$$Register, $tmp$$Register);
1992   %}
1993   ins_pipe( pipe_slow );
1994 %}
1995 
1996 instruct vhas_negatives(iRegP_R11 ary, iRegI_R12 len, iRegI_R10 result,
1997                         vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp)
1998 %{
1999   predicate(UseRVV);
2000   match(Set result (HasNegatives ary len));
2001   effect(TEMP_DEF result, USE_KILL ary, USE_KILL len, TEMP v1, TEMP v2, TEMP v3, TEMP tmp);
2002 
2003   format %{ "has negatives byte[] $ary, $len -> $result" %}
2004   ins_encode %{
2005     __ has_negatives_v($ary$$Register, $len$$Register, $result$$Register, $tmp$$Register);
2006   %}
2007 
2008   ins_pipe(pipe_slow);
2009 %}
2010 
2011 instruct vstringU_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
2012                                iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
2013                                vReg_V1 v1, vReg_V2 v2, vReg_V3 v3)
2014 %{
2015   predicate(UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U));
2016   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
2017   effect(TEMP_DEF result, USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
2018          TEMP tmp1, TEMP tmp2, TEMP v1, TEMP v2, TEMP v3);
2019 
2020   format %{ "StringUTF16 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
2021 
2022   ins_encode %{
2023     __ string_indexof_char_v($str1$$Register, $cnt1$$Register, $ch$$Register,
2024                              $result$$Register, $tmp1$$Register, $tmp2$$Register,
2025                              false /* isL */);
2026   %}
2027 
2028   ins_pipe(pipe_class_memory);
2029 %}
2030 
2031 instruct vstringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
2032                                iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
2033                                vReg_V1 v1, vReg_V2 v2, vReg_V3 v3)
2034 %{
2035   predicate(UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
2036   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
2037   effect(TEMP_DEF result, USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
2038          TEMP tmp1, TEMP tmp2, TEMP v1, TEMP v2, TEMP v3);
2039 
2040   format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
2041 
2042   ins_encode %{
2043     __ string_indexof_char_v($str1$$Register, $cnt1$$Register, $ch$$Register,
2044                              $result$$Register, $tmp1$$Register, $tmp2$$Register,
2045                              true /* isL */);
2046   %}
2047 
2048   ins_pipe(pipe_class_memory);
2049 %}
2050 
2051 // clearing of an array
2052 instruct vclearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, Universe dummy,
2053                              vReg_V1 vReg1, vReg_V2 vReg2, vReg_V3 vReg3)
2054 %{
2055   predicate(UseRVV);
2056   match(Set dummy (ClearArray cnt base));
2057   effect(USE_KILL cnt, USE_KILL base, TEMP vReg1, TEMP vReg2, TEMP vReg3);
2058 
2059   format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg" %}
2060 
2061   ins_encode %{
2062     __ clear_array_v($base$$Register, $cnt$$Register);
2063   %}
2064 
2065   ins_pipe(pipe_class_memory);
2066 %}