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, 2021, 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 
  37   static void loadStore(C2_MacroAssembler masm, bool is_store,
  38                         VectorRegister reg, BasicType bt, Register base) {
  39     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
  40     masm.vsetvli(t0, x0, sew);
  41     if (is_store) {
  42       masm.vsex_v(reg, base, sew);
  43     } else {
  44       masm.vlex_v(reg, base, sew);
  45     }
  46   }
  47 
  48   bool op_vec_supported(int opcode) {
  49     switch (opcode) {
  50       // No multiply reduction instructions
  51       case Op_MulReductionVD:
  52       case Op_MulReductionVF:
  53       case Op_MulReductionVI:
  54       case Op_MulReductionVL:
  55       // Others
  56       case Op_Extract:
  57       case Op_ExtractB:
  58       case Op_ExtractC:
  59       case Op_ExtractD:
  60       case Op_ExtractF:
  61       case Op_ExtractI:
  62       case Op_ExtractL:
  63       case Op_ExtractS:
  64       case Op_ExtractUB:
  65       // Vector API specific
  66       case Op_AndReductionV:
  67       case Op_OrReductionV:
  68       case Op_XorReductionV:
  69       case Op_LoadVectorGather:
  70       case Op_StoreVectorScatter:
  71       case Op_VectorBlend:
  72       case Op_VectorCast:
  73       case Op_VectorCastB2X:
  74       case Op_VectorCastD2X:
  75       case Op_VectorCastF2X:
  76       case Op_VectorCastI2X:
  77       case Op_VectorCastL2X:
  78       case Op_VectorCastS2X:
  79       case Op_VectorInsert:
  80       case Op_VectorLoadConst:
  81       case Op_VectorLoadMask:
  82       case Op_VectorLoadShuffle:
  83       case Op_VectorMaskCmp:
  84       case Op_VectorRearrange:
  85       case Op_VectorReinterpret:
  86       case Op_VectorStoreMask:
  87       case Op_VectorTest:
  88         return false;
  89       default:
  90         return UseRVV;
  91     }
  92   }
  93 
  94 %}
  95 
  96 definitions %{
  97   int_def VEC_COST             (200, 200);
  98 %}
  99 
 100 // All VEC instructions
 101 
 102 // vector load/store
 103 instruct loadV(vReg dst, vmemA mem) %{
 104   match(Set dst (LoadVector mem));
 105   ins_cost(VEC_COST);
 106   format %{ "vle $dst, $mem\t#@loadV" %}
 107   ins_encode %{
 108     VectorRegister dst_reg = as_VectorRegister($dst$$reg);
 109     loadStore(C2_MacroAssembler(&cbuf), false, dst_reg,
 110               Matcher::vector_element_basic_type(this), as_Register($mem$$base));
 111   %}
 112   ins_pipe(pipe_slow);
 113 %}
 114 
 115 instruct storeV(vReg src, vmemA mem) %{
 116   match(Set mem (StoreVector mem src));
 117   ins_cost(VEC_COST);
 118   format %{ "vse $src, $mem\t#@storeV" %}
 119   ins_encode %{
 120     VectorRegister src_reg = as_VectorRegister($src$$reg);
 121     loadStore(C2_MacroAssembler(&cbuf), true, src_reg,
 122               Matcher::vector_element_basic_type(this, $src), as_Register($mem$$base));
 123   %}
 124   ins_pipe(pipe_slow);
 125 %}
 126 
 127 // vector abs
 128 
 129 instruct vabsB(vReg dst, vReg src, vReg tmp) %{
 130   match(Set dst (AbsVB src));
 131   ins_cost(VEC_COST);
 132   effect(TEMP tmp);
 133   format %{ "vrsub.vi $tmp, 0, $src\t#@vabsB\n\t"
 134             "vmax.vv $dst, $tmp, $src" %}
 135   ins_encode %{
 136     __ vsetvli(t0, x0, Assembler::e8);
 137     __ vrsub_vi(as_VectorRegister($tmp$$reg), 0, as_VectorRegister($src$$reg));
 138     __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
 139   %}
 140   ins_pipe(pipe_slow);
 141 %}
 142 
 143 instruct vabsS(vReg dst, vReg src, vReg tmp) %{
 144   match(Set dst (AbsVS src));
 145   ins_cost(VEC_COST);
 146   effect(TEMP tmp);
 147   format %{ "vrsub.vi $tmp, 0, $src\t#@vabsS\n\t"
 148             "vmax.vv $dst, $tmp, $src" %}
 149   ins_encode %{
 150     __ vsetvli(t0, x0, Assembler::e16);
 151     __ vrsub_vi(as_VectorRegister($tmp$$reg), 0, as_VectorRegister($src$$reg));
 152     __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
 153   %}
 154   ins_pipe(pipe_slow);
 155 %}
 156 
 157 instruct vabsI(vReg dst, vReg src, vReg tmp) %{
 158   match(Set dst (AbsVI src));
 159   ins_cost(VEC_COST);
 160   effect(TEMP tmp);
 161   format %{ "vrsub.vi $tmp, 0, $src\t#@vabsI\n\t"
 162             "vmax.vv $dst, $tmp, $src" %}
 163   ins_encode %{
 164     __ vsetvli(t0, x0, Assembler::e32);
 165     __ vrsub_vi(as_VectorRegister($tmp$$reg), 0, as_VectorRegister($src$$reg));
 166     __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
 167   %}
 168   ins_pipe(pipe_slow);
 169 %}
 170 
 171 instruct vabsL(vReg dst, vReg src, vReg tmp) %{
 172   match(Set dst (AbsVL src));
 173   ins_cost(VEC_COST);
 174   effect(TEMP tmp);
 175   format %{ "vrsub.vi $tmp, 0, $src\t#@vabsL\n\t"
 176             "vmax.vv $dst, $tmp, $src" %}
 177   ins_encode %{
 178     __ vsetvli(t0, x0, Assembler::e64);
 179     __ vrsub_vi(as_VectorRegister($tmp$$reg), 0, as_VectorRegister($src$$reg));
 180     __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
 181   %}
 182   ins_pipe(pipe_slow);
 183 %}
 184 
 185 instruct vabsF(vReg dst, vReg src) %{
 186   match(Set dst (AbsVF src));
 187   ins_cost(VEC_COST);
 188   format %{ "vfsgnjx.vv $dst, $src, $src, vm\t#@vabsF" %}
 189   ins_encode %{
 190     __ vsetvli(t0, x0, Assembler::e32);
 191     __ vfsgnjx_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg));
 192   %}
 193   ins_pipe(pipe_slow);
 194 %}
 195 
 196 instruct vabsD(vReg dst, vReg src) %{
 197   match(Set dst (AbsVD src));
 198   ins_cost(VEC_COST);
 199   format %{ "vfsgnjx.vv $dst, $src, $src, vm\t#@vabsD" %}
 200   ins_encode %{
 201     __ vsetvli(t0, x0, Assembler::e64);
 202     __ vfsgnjx_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg));
 203   %}
 204   ins_pipe(pipe_slow);
 205 %}
 206 
 207 // vector add
 208 
 209 instruct vaddB(vReg dst, vReg src1, vReg src2) %{
 210   match(Set dst (AddVB src1 src2));
 211   ins_cost(VEC_COST);
 212   format %{ "vadd.vv $dst, $src1, $src2\t#@vaddB" %}
 213   ins_encode %{
 214     __ vsetvli(t0, x0, Assembler::e8);
 215     __ vadd_vv(as_VectorRegister($dst$$reg),
 216                as_VectorRegister($src1$$reg),
 217                as_VectorRegister($src2$$reg));
 218   %}
 219   ins_pipe(pipe_slow);
 220 %}
 221 
 222 instruct vaddS(vReg dst, vReg src1, vReg src2) %{
 223   match(Set dst (AddVS src1 src2));
 224   ins_cost(VEC_COST);
 225   format %{ "vadd.vv $dst, $src1, $src2\t#@vaddS" %}
 226   ins_encode %{
 227     __ vsetvli(t0, x0, Assembler::e16);
 228     __ vadd_vv(as_VectorRegister($dst$$reg),
 229                as_VectorRegister($src1$$reg),
 230                as_VectorRegister($src2$$reg));
 231   %}
 232   ins_pipe(pipe_slow);
 233 %}
 234 
 235 instruct vaddI(vReg dst, vReg src1, vReg src2) %{
 236   match(Set dst (AddVI src1 src2));
 237   ins_cost(VEC_COST);
 238   format %{ "vadd.vv $dst, $src1, $src2\t#@vaddI" %}
 239   ins_encode %{
 240     __ vsetvli(t0, x0, Assembler::e32);
 241     __ vadd_vv(as_VectorRegister($dst$$reg),
 242                as_VectorRegister($src1$$reg),
 243                as_VectorRegister($src2$$reg));
 244   %}
 245   ins_pipe(pipe_slow);
 246 %}
 247 
 248 instruct vaddL(vReg dst, vReg src1, vReg src2) %{
 249   match(Set dst (AddVL src1 src2));
 250   ins_cost(VEC_COST);
 251   format %{ "vadd.vv $dst, $src1, $src2\t#@vaddL" %}
 252   ins_encode %{
 253     __ vsetvli(t0, x0, Assembler::e64);
 254     __ vadd_vv(as_VectorRegister($dst$$reg),
 255                as_VectorRegister($src1$$reg),
 256                as_VectorRegister($src2$$reg));
 257   %}
 258   ins_pipe(pipe_slow);
 259 %}
 260 
 261 instruct vaddF(vReg dst, vReg src1, vReg src2) %{
 262   match(Set dst (AddVF src1 src2));
 263   ins_cost(VEC_COST);
 264   format %{ "vfadd.vv $dst, $src1, $src2\t#@vaddF" %}
 265   ins_encode %{
 266     __ vsetvli(t0, x0, Assembler::e32);
 267     __ vfadd_vv(as_VectorRegister($dst$$reg),
 268                 as_VectorRegister($src1$$reg),
 269                 as_VectorRegister($src2$$reg));
 270   %}
 271   ins_pipe(pipe_slow);
 272 %}
 273 
 274 instruct vaddD(vReg dst, vReg src1, vReg src2) %{
 275   match(Set dst (AddVD src1 src2));
 276   ins_cost(VEC_COST);
 277   format %{ "vfadd.vv $dst, $src1, $src2\t#@vaddD" %}
 278   ins_encode %{
 279     __ vsetvli(t0, x0, Assembler::e64);
 280     __ vfadd_vv(as_VectorRegister($dst$$reg),
 281                 as_VectorRegister($src1$$reg),
 282                 as_VectorRegister($src2$$reg));
 283   %}
 284   ins_pipe(pipe_slow);
 285 %}
 286 
 287 // vector and
 288 
 289 instruct vand(vReg dst, vReg src1, vReg src2) %{
 290   match(Set dst (AndV src1 src2));
 291   ins_cost(VEC_COST);
 292   format %{ "vand.vv  $dst, $src1, $src2\t#@vand" %}
 293   ins_encode %{
 294     __ vsetvli(t0, x0, Assembler::e64);
 295     __ vand_vv(as_VectorRegister($dst$$reg),
 296                as_VectorRegister($src1$$reg),
 297                as_VectorRegister($src2$$reg));
 298   %}
 299   ins_pipe(pipe_slow);
 300 %}
 301 
 302 // vector or
 303 
 304 instruct vor(vReg dst, vReg src1, vReg src2) %{
 305   match(Set dst (OrV src1 src2));
 306   ins_cost(VEC_COST);
 307   format %{ "vor.vv  $dst, $src1, $src2\t#@vor" %}
 308   ins_encode %{
 309     __ vsetvli(t0, x0, Assembler::e64);
 310     __ vor_vv(as_VectorRegister($dst$$reg),
 311               as_VectorRegister($src1$$reg),
 312               as_VectorRegister($src2$$reg));
 313   %}
 314   ins_pipe(pipe_slow);
 315 %}
 316 
 317 // vector xor
 318 
 319 instruct vxor(vReg dst, vReg src1, vReg src2) %{
 320   match(Set dst (XorV src1 src2));
 321   ins_cost(VEC_COST);
 322   format %{ "vxor.vv  $dst, $src1, $src2\t#@vxor" %}
 323   ins_encode %{
 324     __ vsetvli(t0, x0, Assembler::e64);
 325     __ vxor_vv(as_VectorRegister($dst$$reg),
 326                as_VectorRegister($src1$$reg),
 327                as_VectorRegister($src2$$reg));
 328   %}
 329   ins_pipe(pipe_slow);
 330 %}
 331 
 332 // vector float div
 333 
 334 instruct vdivF(vReg dst, vReg src1, vReg src2) %{
 335   match(Set dst (DivVF src1 src2));
 336   ins_cost(VEC_COST);
 337   format %{ "vfdiv.vv  $dst, $src1, $src2\t#@vdivF" %}
 338   ins_encode %{
 339     __ vsetvli(t0, x0, Assembler::e32);
 340     __ vfdiv_vv(as_VectorRegister($dst$$reg),
 341                 as_VectorRegister($src1$$reg),
 342                 as_VectorRegister($src2$$reg));
 343   %}
 344   ins_pipe(pipe_slow);
 345 %}
 346 
 347 instruct vdivD(vReg dst, vReg src1, vReg src2) %{
 348   match(Set dst (DivVD src1 src2));
 349   ins_cost(VEC_COST);
 350   format %{ "vfdiv.vv  $dst, $src1, $src2\t#@vdivD" %}
 351   ins_encode %{
 352     __ vsetvli(t0, x0, Assembler::e64);
 353     __ vfdiv_vv(as_VectorRegister($dst$$reg),
 354                 as_VectorRegister($src1$$reg),
 355                 as_VectorRegister($src2$$reg));
 356   %}
 357   ins_pipe(pipe_slow);
 358 %}
 359 
 360 // vector integer max/min
 361 
 362 instruct vmax(vReg dst, vReg src1, vReg src2) %{
 363   predicate(n->bottom_type()->is_vect()->element_basic_type() != T_FLOAT &&
 364             n->bottom_type()->is_vect()->element_basic_type() != T_DOUBLE);
 365   match(Set dst (MaxV src1 src2));
 366   ins_cost(VEC_COST);
 367   format %{ "vmax.vv $dst, $src1, $src2\t#@vmax" %}
 368   ins_encode %{
 369     BasicType bt = Matcher::vector_element_basic_type(this);
 370     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
 371     __ vsetvli(t0, x0, sew);
 372     __ vmax_vv(as_VectorRegister($dst$$reg),
 373                as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
 374   %}
 375   ins_pipe(pipe_slow);
 376 %}
 377 
 378 instruct vmin(vReg dst, vReg src1, vReg src2) %{
 379   predicate(n->bottom_type()->is_vect()->element_basic_type() != T_FLOAT &&
 380             n->bottom_type()->is_vect()->element_basic_type() != T_DOUBLE);
 381   match(Set dst (MinV src1 src2));
 382   ins_cost(VEC_COST);
 383   format %{ "vmin.vv $dst, $src1, $src2\t#@vmin" %}
 384   ins_encode %{
 385     BasicType bt = Matcher::vector_element_basic_type(this);
 386     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
 387     __ vsetvli(t0, x0, sew);
 388     __ vmin_vv(as_VectorRegister($dst$$reg),
 389                as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
 390   %}
 391   ins_pipe(pipe_slow);
 392 %}
 393 
 394 // vector float-point max/min
 395 
 396 instruct vmaxF(vReg dst, vReg src1, vReg src2) %{
 397   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
 398   match(Set dst (MaxV src1 src2));
 399   effect(TEMP_DEF dst);
 400   ins_cost(VEC_COST);
 401   format %{ "vmaxF $dst, $src1, $src2\t#@vmaxF" %}
 402   ins_encode %{
 403     __ minmax_FD_v(as_VectorRegister($dst$$reg),
 404                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 405                    false /* is_double */, false /* is_min */);
 406   %}
 407   ins_pipe(pipe_slow);
 408 %}
 409 
 410 instruct vmaxD(vReg dst, vReg src1, vReg src2) %{
 411   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
 412   match(Set dst (MaxV src1 src2));
 413   effect(TEMP_DEF dst);
 414   ins_cost(VEC_COST);
 415   format %{ "vmaxD $dst, $src1, $src2\t#@vmaxD" %}
 416   ins_encode %{
 417     __ minmax_FD_v(as_VectorRegister($dst$$reg),
 418                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 419                    true /* is_double */, false /* is_min */);
 420   %}
 421   ins_pipe(pipe_slow);
 422 %}
 423 
 424 instruct vminF(vReg dst, vReg src1, vReg src2) %{
 425   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
 426   match(Set dst (MinV src1 src2));
 427   effect(TEMP_DEF dst);
 428   ins_cost(VEC_COST);
 429   format %{ "vminF $dst, $src1, $src2\t#@vminF" %}
 430   ins_encode %{
 431     __ minmax_FD_v(as_VectorRegister($dst$$reg),
 432                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 433                    false /* is_double */, true /* is_min */);
 434   %}
 435   ins_pipe(pipe_slow);
 436 %}
 437 
 438 instruct vminD(vReg dst, vReg src1, vReg src2) %{
 439   predicate(n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
 440   match(Set dst (MinV src1 src2));
 441   effect(TEMP_DEF dst);
 442   ins_cost(VEC_COST);
 443   format %{ "vminD $dst, $src1, $src2\t#@vminD" %}
 444   ins_encode %{
 445     __ minmax_FD_v(as_VectorRegister($dst$$reg),
 446                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 447                    true /* is_double */, true /* is_min */);
 448   %}
 449   ins_pipe(pipe_slow);
 450 %}
 451 
 452 // vector fmla
 453 
 454 // dst_src1 = dst_src1 + src2 * src3
 455 instruct vfmlaF(vReg dst_src1, vReg src2, vReg src3) %{
 456   predicate(UseFMA);
 457   match(Set dst_src1 (FmaVF dst_src1 (Binary src2 src3)));
 458   ins_cost(VEC_COST);
 459   format %{ "vfmacc.vv $dst_src1, $src2, $src3\t#@vfmlaF" %}
 460   ins_encode %{
 461     __ vsetvli(t0, x0, Assembler::e32);
 462     __ vfmacc_vv(as_VectorRegister($dst_src1$$reg),
 463                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 464   %}
 465   ins_pipe(pipe_slow);
 466 %}
 467 
 468 // dst_src1 = dst_src1 + src2 * src3
 469 instruct vfmlaD(vReg dst_src1, vReg src2, vReg src3) %{
 470   predicate(UseFMA);
 471   match(Set dst_src1 (FmaVD dst_src1 (Binary src2 src3)));
 472   ins_cost(VEC_COST);
 473   format %{ "vfmacc.vv $dst_src1, $src2, $src3\t#@vfmlaD" %}
 474   ins_encode %{
 475     __ vsetvli(t0, x0, Assembler::e64);
 476     __ vfmacc_vv(as_VectorRegister($dst_src1$$reg),
 477                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 478   %}
 479   ins_pipe(pipe_slow);
 480 %}
 481 
 482 // vector fmls
 483 
 484 // dst_src1 = dst_src1 + -src2 * src3
 485 // dst_src1 = dst_src1 + src2 * -src3
 486 instruct vfmlsF(vReg dst_src1, vReg src2, vReg src3) %{
 487   predicate(UseFMA);
 488   match(Set dst_src1 (FmaVF dst_src1 (Binary (NegVF src2) src3)));
 489   match(Set dst_src1 (FmaVF dst_src1 (Binary src2 (NegVF src3))));
 490   ins_cost(VEC_COST);
 491   format %{ "vfnmsac.vv $dst_src1, $src2, $src3\t#@vfmlsF" %}
 492   ins_encode %{
 493     __ vsetvli(t0, x0, Assembler::e32);
 494     __ vfnmsac_vv(as_VectorRegister($dst_src1$$reg),
 495                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 496   %}
 497   ins_pipe(pipe_slow);
 498 %}
 499 
 500 // dst_src1 = dst_src1 + -src2 * src3
 501 // dst_src1 = dst_src1 + src2 * -src3
 502 instruct vfmlsD(vReg dst_src1, vReg src2, vReg src3) %{
 503   predicate(UseFMA);
 504   match(Set dst_src1 (FmaVD dst_src1 (Binary (NegVD src2) src3)));
 505   match(Set dst_src1 (FmaVD dst_src1 (Binary src2 (NegVD src3))));
 506   ins_cost(VEC_COST);
 507   format %{ "vfnmsac.vv $dst_src1, $src2, $src3\t#@vfmlsD" %}
 508   ins_encode %{
 509     __ vsetvli(t0, x0, Assembler::e64);
 510     __ vfnmsac_vv(as_VectorRegister($dst_src1$$reg),
 511                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 512   %}
 513   ins_pipe(pipe_slow);
 514 %}
 515 
 516 // vector fnmla
 517 
 518 // dst_src1 = -dst_src1 + -src2 * src3
 519 // dst_src1 = -dst_src1 + src2 * -src3
 520 instruct vfnmlaF(vReg dst_src1, vReg src2, vReg src3) %{
 521   predicate(UseFMA);
 522   match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary (NegVF src2) src3)));
 523   match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 (NegVF src3))));
 524   ins_cost(VEC_COST);
 525   format %{ "vfnmacc.vv $dst_src1, $src2, $src3\t#@vfnmlaF" %}
 526   ins_encode %{
 527     __ vsetvli(t0, x0, Assembler::e32);
 528     __ vfnmacc_vv(as_VectorRegister($dst_src1$$reg),
 529                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 530   %}
 531   ins_pipe(pipe_slow);
 532 %}
 533 
 534 // dst_src1 = -dst_src1 + -src2 * src3
 535 // dst_src1 = -dst_src1 + src2 * -src3
 536 instruct vfnmlaD(vReg dst_src1, vReg src2, vReg src3) %{
 537   predicate(UseFMA);
 538   match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary (NegVD src2) src3)));
 539   match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 (NegVD src3))));
 540   ins_cost(VEC_COST);
 541   format %{ "vfnmacc.vv $dst_src1, $src2, $src3\t#@vfnmlaD" %}
 542   ins_encode %{
 543     __ vsetvli(t0, x0, Assembler::e64);
 544     __ vfnmacc_vv(as_VectorRegister($dst_src1$$reg),
 545                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 546   %}
 547   ins_pipe(pipe_slow);
 548 %}
 549 
 550 // vector fnmls
 551 
 552 // dst_src1 = -dst_src1 + src2 * src3
 553 instruct vfnmlsF(vReg dst_src1, vReg src2, vReg src3) %{
 554   predicate(UseFMA);
 555   match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 src3)));
 556   ins_cost(VEC_COST);
 557   format %{ "vfmsac.vv $dst_src1, $src2, $src3\t#@vfnmlsF" %}
 558   ins_encode %{
 559     __ vsetvli(t0, x0, Assembler::e32);
 560     __ vfmsac_vv(as_VectorRegister($dst_src1$$reg),
 561                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 562   %}
 563   ins_pipe(pipe_slow);
 564 %}
 565 
 566 // dst_src1 = -dst_src1 + src2 * src3
 567 instruct vfnmlsD(vReg dst_src1, vReg src2, vReg src3) %{
 568   predicate(UseFMA);
 569   match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 src3)));
 570   ins_cost(VEC_COST);
 571   format %{ "vfmsac.vv $dst_src1, $src2, $src3\t#@vfnmlsD" %}
 572   ins_encode %{
 573     __ vsetvli(t0, x0, Assembler::e64);
 574     __ vfmsac_vv(as_VectorRegister($dst_src1$$reg),
 575                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 576   %}
 577   ins_pipe(pipe_slow);
 578 %}
 579 
 580 // vector mla
 581 
 582 // dst_src1 = dst_src1 + src2 * src3
 583 instruct vmlaB(vReg dst_src1, vReg src2, vReg src3) %{
 584   match(Set dst_src1 (AddVB dst_src1 (MulVB src2 src3)));
 585   ins_cost(VEC_COST);
 586   format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaB" %}
 587   ins_encode %{
 588     __ vsetvli(t0, x0, Assembler::e8);
 589     __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
 590                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 591   %}
 592   ins_pipe(pipe_slow);
 593 %}
 594 
 595 // dst_src1 = dst_src1 + src2 * src3
 596 instruct vmlaS(vReg dst_src1, vReg src2, vReg src3) %{
 597   match(Set dst_src1 (AddVS dst_src1 (MulVS src2 src3)));
 598   ins_cost(VEC_COST);
 599   format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaS" %}
 600   ins_encode %{
 601     __ vsetvli(t0, x0, Assembler::e16);
 602     __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
 603                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 604   %}
 605   ins_pipe(pipe_slow);
 606 %}
 607 
 608 // dst_src1 = dst_src1 + src2 * src3
 609 instruct vmlaI(vReg dst_src1, vReg src2, vReg src3) %{
 610   match(Set dst_src1 (AddVI dst_src1 (MulVI src2 src3)));
 611   ins_cost(VEC_COST);
 612   format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaI" %}
 613   ins_encode %{
 614     __ vsetvli(t0, x0, Assembler::e32);
 615     __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
 616                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 617   %}
 618   ins_pipe(pipe_slow);
 619 %}
 620 
 621 // dst_src1 = dst_src1 + src2 * src3
 622 instruct vmlaL(vReg dst_src1, vReg src2, vReg src3) %{
 623   match(Set dst_src1 (AddVL dst_src1 (MulVL src2 src3)));
 624   ins_cost(VEC_COST);
 625   format %{ "vmacc.vv $dst_src1, src2, src3\t#@vmlaL" %}
 626   ins_encode %{
 627     __ vsetvli(t0, x0, Assembler::e64);
 628     __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
 629                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 630   %}
 631   ins_pipe(pipe_slow);
 632 %}
 633 
 634 // vector mls
 635 
 636 // dst_src1 = dst_src1 - src2 * src3
 637 instruct vmlsB(vReg dst_src1, vReg src2, vReg src3) %{
 638   match(Set dst_src1 (SubVB dst_src1 (MulVB src2 src3)));
 639   ins_cost(VEC_COST);
 640   format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsB" %}
 641   ins_encode %{
 642     __ vsetvli(t0, x0, Assembler::e8);
 643     __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
 644                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 645   %}
 646   ins_pipe(pipe_slow);
 647 %}
 648 
 649 // dst_src1 = dst_src1 - src2 * src3
 650 instruct vmlsS(vReg dst_src1, vReg src2, vReg src3) %{
 651   match(Set dst_src1 (SubVS dst_src1 (MulVS src2 src3)));
 652   ins_cost(VEC_COST);
 653   format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsS" %}
 654   ins_encode %{
 655     __ vsetvli(t0, x0, Assembler::e16);
 656     __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
 657                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 658   %}
 659   ins_pipe(pipe_slow);
 660 %}
 661 
 662 // dst_src1 = dst_src1 - src2 * src3
 663 instruct vmlsI(vReg dst_src1, vReg src2, vReg src3) %{
 664   match(Set dst_src1 (SubVI dst_src1 (MulVI src2 src3)));
 665   ins_cost(VEC_COST);
 666   format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsI" %}
 667   ins_encode %{
 668     __ vsetvli(t0, x0, Assembler::e32);
 669     __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
 670                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 671   %}
 672   ins_pipe(pipe_slow);
 673 %}
 674 
 675 // dst_src1 = dst_src1 - src2 * src3
 676 instruct vmlsL(vReg dst_src1, vReg src2, vReg src3) %{
 677   match(Set dst_src1 (SubVL dst_src1 (MulVL src2 src3)));
 678   ins_cost(VEC_COST);
 679   format %{ "vnmsac.vv $dst_src1, src2, src3\t#@vmlsL" %}
 680   ins_encode %{
 681     __ vsetvli(t0, x0, Assembler::e64);
 682     __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
 683                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
 684   %}
 685   ins_pipe(pipe_slow);
 686 %}
 687 
 688 // vector mul
 689 
 690 instruct vmulB(vReg dst, vReg src1, vReg src2) %{
 691   match(Set dst (MulVB src1 src2));
 692   ins_cost(VEC_COST);
 693   format %{ "vmul.vv $dst, $src1, $src2\t#@vmulB" %}
 694   ins_encode %{
 695     __ vsetvli(t0, x0, Assembler::e8);
 696     __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 697                as_VectorRegister($src2$$reg));
 698   %}
 699   ins_pipe(pipe_slow);
 700 %}
 701 
 702 instruct vmulS(vReg dst, vReg src1, vReg src2) %{
 703   match(Set dst (MulVS src1 src2));
 704   ins_cost(VEC_COST);
 705   format %{ "vmul.vv $dst, $src1, $src2\t#@vmulS" %}
 706   ins_encode %{
 707     __ vsetvli(t0, x0, Assembler::e16);
 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 vmulI(vReg dst, vReg src1, vReg src2) %{
 715   match(Set dst (MulVI src1 src2));
 716   ins_cost(VEC_COST);
 717   format %{ "vmul.vv $dst, $src1, $src2\t#@vmulI" %}
 718   ins_encode %{
 719     __ vsetvli(t0, x0, Assembler::e32);
 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 vmulL(vReg dst, vReg src1, vReg src2) %{
 727   match(Set dst (MulVL src1 src2));
 728   ins_cost(VEC_COST);
 729   format %{ "vmul.vv $dst, $src1, $src2\t#@vmulL" %}
 730   ins_encode %{
 731     __ vsetvli(t0, x0, Assembler::e64);
 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 vmulF(vReg dst, vReg src1, vReg src2) %{
 739   match(Set dst (MulVF src1 src2));
 740   ins_cost(VEC_COST);
 741   format %{ "vfmul.vv $dst, $src1, $src2\t#@vmulF" %}
 742   ins_encode %{
 743     __ vsetvli(t0, x0, Assembler::e32);
 744     __ vfmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 745                 as_VectorRegister($src2$$reg));
 746   %}
 747   ins_pipe(pipe_slow);
 748 %}
 749 
 750 instruct vmulD(vReg dst, vReg src1, vReg src2) %{
 751   match(Set dst (MulVD src1 src2));
 752   ins_cost(VEC_COST);
 753   format %{ "vfmul.vv $dst, $src1, $src2\t#@vmulD" %}
 754   ins_encode %{
 755     __ vsetvli(t0, x0, Assembler::e64);
 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 // vector fneg
 763 
 764 instruct vnegF(vReg dst, vReg src) %{
 765   match(Set dst (NegVF src));
 766   ins_cost(VEC_COST);
 767   format %{ "vfsgnjn.vv $dst, $src, $src\t#@vnegF" %}
 768   ins_encode %{
 769     __ vsetvli(t0, x0, Assembler::e32);
 770     __ vfneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
 771   %}
 772   ins_pipe(pipe_slow);
 773 %}
 774 
 775 instruct vnegD(vReg dst, vReg src) %{
 776   match(Set dst (NegVD src));
 777   ins_cost(VEC_COST);
 778   format %{ "vfsgnjn.vv $dst, $src, $src\t#@vnegD" %}
 779   ins_encode %{
 780     __ vsetvli(t0, x0, Assembler::e64);
 781     __ vfneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
 782   %}
 783   ins_pipe(pipe_slow);
 784 %}
 785 
 786 // popcount vector
 787 
 788 instruct vpopcountI(iRegINoSp dst, vReg src) %{
 789   match(Set dst (PopCountVI src));
 790   format %{ "vpopc.m $dst, $src\t#@vpopcountI" %}
 791   ins_encode %{
 792     __ vsetvli(t0, x0, Assembler::e32);
 793     __ vpopc_m(as_Register($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, iRegL 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, iRegL 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, iRegL 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 ary1, iRegI_R12 len, iRegI_R10 result, iRegL tmp)
1997 %{
1998   predicate(UseRVV);
1999   match(Set result (HasNegatives ary1 len));
2000   effect(USE_KILL ary1, USE_KILL len, TEMP tmp);
2001   format %{ "has negatives byte[] $ary1,$len -> $result" %}
2002   ins_encode %{
2003     __ has_negatives_v($ary1$$Register, $len$$Register, $result$$Register, $tmp$$Register);
2004   %}
2005   ins_pipe( pipe_slow );
2006 %}
2007 
2008 instruct vstringU_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
2009                                iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
2010                                vReg_V1 v1, vReg_V2 v2, vReg_V3 v3)
2011 %{
2012   predicate(UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U));
2013   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
2014   effect(TEMP_DEF result, USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
2015          TEMP tmp1, TEMP tmp2, TEMP v1, TEMP v2, TEMP v3);
2016 
2017   format %{ "StringUTF16 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
2018 
2019   ins_encode %{
2020     __ string_indexof_char_v($str1$$Register, $cnt1$$Register, $ch$$Register,
2021                              $result$$Register, $tmp1$$Register, $tmp2$$Register,
2022                              false /* isL */);
2023   %}
2024 
2025   ins_pipe(pipe_class_memory);
2026 %}
2027 
2028 instruct vstringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
2029                                iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
2030                                vReg_V1 v1, vReg_V2 v2, vReg_V3 v3)
2031 %{
2032   predicate(UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
2033   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
2034   effect(TEMP_DEF result, USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
2035          TEMP tmp1, TEMP tmp2, TEMP v1, TEMP v2, TEMP v3);
2036 
2037   format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
2038 
2039   ins_encode %{
2040     __ string_indexof_char_v($str1$$Register, $cnt1$$Register, $ch$$Register,
2041                              $result$$Register, $tmp1$$Register, $tmp2$$Register,
2042                              true /* isL */);
2043   %}
2044 
2045   ins_pipe(pipe_class_memory);
2046 %}
2047 
2048 // clearing of an array
2049 instruct vclearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, Universe dummy,
2050                              vReg_V1 vReg1, vReg_V2 vReg2, vReg_V3 vReg3)
2051 %{
2052   predicate(UseRVV);
2053   match(Set dummy (ClearArray cnt base));
2054   effect(USE_KILL cnt, USE_KILL base, TEMP vReg1, TEMP vReg2, TEMP vReg3);
2055 
2056   format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg" %}
2057 
2058   ins_encode %{
2059     __ clear_array_v($base$$Register, $cnt$$Register);
2060   %}
2061 
2062   ins_pipe(pipe_class_memory);
2063 %}