1 //
   2 // Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
   3 // Copyright (c) 2020, 2023, Arm Limited. All rights reserved.
   4 // Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
   5 // Copyright (c) 2023, 2025, Rivos Inc. All rights reserved.
   6 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7 //
   8 // This code is free software; you can redistribute it and/or modify it
   9 // under the terms of the GNU General Public License version 2 only, as
  10 // published by the Free Software Foundation.
  11 //
  12 // This code is distributed in the hope that it will be useful, but WITHOUT
  13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15 // version 2 for more details (a copy is included in the LICENSE file that
  16 // accompanied this code).
  17 //
  18 // You should have received a copy of the GNU General Public License version
  19 // 2 along with this work; if not, write to the Free Software Foundation,
  20 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21 //
  22 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  23 // or visit www.oracle.com if you need additional information or have any
  24 // questions.
  25 //
  26 //
  27 
  28 // RISCV Vector Extension Architecture Description File
  29 
  30 opclass vmemA(indirect);
  31 
  32 source %{
  33 
  34   static void loadStore(C2_MacroAssembler* masm, bool is_store,
  35                         VectorRegister reg, BasicType bt, Register base,
  36                         uint vector_length, Assembler::VectorMask vm = Assembler::unmasked) {
  37     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
  38     __ vsetvli_helper(bt, vector_length);
  39 
  40     if (is_store) {
  41       __ vsex_v(reg, base, sew, vm);
  42     } else {
  43       if (vm == Assembler::v0_t) {
  44         __ vxor_vv(reg, reg, reg);
  45       }
  46       __ vlex_v(reg, base, sew, vm);
  47     }
  48   }
  49 
  50   bool Matcher::match_rule_supported_auto_vectorization(int opcode, int vlen, BasicType bt) {
  51     return match_rule_supported_vector(opcode, vlen, bt);
  52   }
  53 
  54   // Identify extra cases that we might want to provide match rules for vector nodes
  55   // and other intrinsics guarded with vector length (vlen) and element type (bt).
  56   bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
  57     if (!UseRVV) {
  58       return false;
  59     }
  60 
  61     if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
  62       return false;
  63     }
  64 
  65     switch (opcode) {
  66       case Op_VectorMaskLastTrue:
  67         if (!UseZbb || vlen > XLEN) {
  68           return false;
  69         }
  70         break;
  71       case Op_VectorMaskToLong:
  72       case Op_VectorLongToMask:
  73         if (vlen > XLEN) {
  74           return false;
  75         }
  76         break;
  77       case Op_CountTrailingZerosV:
  78       case Op_CountLeadingZerosV:
  79       case Op_PopCountVL:
  80       case Op_PopCountVI:
  81       case Op_ReverseBytesV:
  82       case Op_ReverseV:
  83         return UseZvbb;
  84       case Op_RotateLeftV:
  85       case Op_RotateRightV:
  86         if (bt != T_INT && bt != T_LONG) {
  87           return false;
  88         }
  89         return UseZvbb;
  90       case Op_LoadVectorGather:
  91       case Op_LoadVectorGatherMasked:
  92       case Op_StoreVectorScatter:
  93       case Op_StoreVectorScatterMasked:
  94         if (is_subword_type(bt)) {
  95           return false;
  96         }
  97         break;
  98       case Op_VectorLoadShuffle:
  99       case Op_VectorRearrange:
 100         // vlen >= 4 is required, because min vector size for byte is 4 on riscv,
 101         // VectorLoadShuffle is from byte to X, so it requires vlen >= 4.
 102         // VectorRearrange depends on VectorLoadShuffle, so it also requires vlen >= 4.
 103         if (vlen < 4) {
 104           return false;
 105         }
 106         break;
 107       case Op_MulReductionVI:
 108       case Op_MulReductionVL:
 109         // When vlen < 4, our log2(vlen) implementation does not help to gain performance improvement.
 110         if (vlen < 4) {
 111           return false;
 112         }
 113         break;
 114       case Op_VectorCastHF2F:
 115       case Op_VectorCastF2HF:
 116       case Op_AddVHF:
 117       case Op_SubVHF:
 118       case Op_MulVHF:
 119       case Op_DivVHF:
 120       case Op_MaxVHF:
 121       case Op_MinVHF:
 122       case Op_SqrtVHF:
 123         return UseZvfh;
 124       case Op_FmaVHF:
 125         return UseZvfh && UseFMA;
 126       case Op_FmaVF:
 127       case Op_FmaVD:
 128         return UseFMA;
 129 
 130       // For float, current test shows that, it brings performance gain when vlen >= 8, but brings
 131       // regression when vlen == 4. So only enable this intrinsic when vlen >= 8.
 132       // For double, current test shows that even with vlen == 4, there is still some regression.
 133       // Although there is no hardware to verify it, from the trend of performance data on hardwares
 134       // (with vlen == 2 and 4 respectively), it's promising to bring better performance rather than
 135       // regression for double when vlen == 8. So only enable this intrinsic when vlen >= 8.
 136       case Op_RoundVF:
 137       case Op_RoundVD:
 138         return vlen >= 8;
 139 
 140       default:
 141         break;
 142     }
 143     return true;
 144   }
 145 
 146   bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) {
 147     if (!UseRVV) {
 148       return false;
 149     }
 150 
 151     switch (opcode) {
 152       case Op_SelectFromTwoVector:
 153         // There is no masked version of selectFrom two vector, i.e. selectFrom(av, bv, mask) in vector API.
 154         return false;
 155       // Currently, the masked versions of the following 8 Float16 operations are disabled.
 156       // When the support for Float16 vector classes is added in VectorAPI and the masked
 157       // Float16 IR can be generated, these masked operations will be enabled and relevant
 158       // backend support added.
 159       case Op_AddVHF:
 160       case Op_SubVHF:
 161       case Op_MulVHF:
 162       case Op_DivVHF:
 163       case Op_MaxVHF:
 164       case Op_MinVHF:
 165       case Op_SqrtVHF:
 166       case Op_FmaVHF:
 167         return false;
 168       default:
 169         break;
 170     }
 171 
 172     return match_rule_supported_vector(opcode, vlen, bt);
 173   }
 174 
 175   bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
 176     return false;
 177   }
 178 
 179   bool Matcher::vector_rearrange_requires_load_shuffle(BasicType elem_bt, int vlen) {
 180     return false;
 181   }
 182 
 183   bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
 184     // Prefer predicate if the mask type is "TypePVectMask".
 185     return vt->isa_pvectmask() != nullptr;
 186   }
 187 %}
 188 
 189 // All VEC instructions
 190 
 191 // vector load/store
 192 instruct loadV(vReg dst, vmemA mem) %{
 193   match(Set dst (LoadVector mem));
 194   format %{ "loadV $dst, $mem\t# vector (rvv)" %}
 195   ins_encode %{
 196     VectorRegister dst_reg = as_VectorRegister($dst$$reg);
 197     loadStore(masm, false, dst_reg,
 198               Matcher::vector_element_basic_type(this), as_Register($mem$$base), Matcher::vector_length(this));
 199   %}
 200   ins_pipe(pipe_slow);
 201 %}
 202 
 203 instruct storeV(vReg src, vmemA mem) %{
 204   match(Set mem (StoreVector mem src));
 205   format %{ "storeV $mem, $src\t# vector (rvv)" %}
 206   ins_encode %{
 207     VectorRegister src_reg = as_VectorRegister($src$$reg);
 208     loadStore(masm, true, src_reg,
 209               Matcher::vector_element_basic_type(this, $src), as_Register($mem$$base), Matcher::vector_length(this, $src));
 210   %}
 211   ins_pipe(pipe_slow);
 212 %}
 213 
 214 // vector load mask
 215 
 216 instruct vloadmask(vRegMask dst, vReg src) %{
 217   match(Set dst (VectorLoadMask src));
 218   format %{ "vloadmask $dst, $src" %}
 219   ins_encode %{
 220     __ vsetvli_helper(T_BOOLEAN, Matcher::vector_length(this));
 221     __ vmsne_vx(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), zr);
 222   %}
 223   ins_pipe(pipe_slow);
 224 %}
 225 
 226 instruct vloadmask_masked(vRegMask dst, vReg src, vRegMask_V0 v0) %{
 227   match(Set dst (VectorLoadMask src v0));
 228   format %{ "vloadmask_masked $dst, $src, $v0" %}
 229   ins_encode %{
 230     __ vsetvli_helper(T_BOOLEAN, Matcher::vector_length(this));
 231     __ vmsne_vx(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), zr, Assembler::v0_t);
 232   %}
 233   ins_pipe(pipe_slow);
 234 %}
 235 
 236 // vector store mask
 237 
 238 instruct vstoremask(vReg dst, vRegMask_V0 v0, immI size) %{
 239   match(Set dst (VectorStoreMask v0 size));
 240   format %{ "vstoremask $dst, V0 # elem size is $size byte[s]" %}
 241   ins_encode %{
 242     __ vsetvli_helper(T_BOOLEAN, Matcher::vector_length(this));
 243     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg));
 244     __ vmerge_vim(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), 1);
 245   %}
 246   ins_pipe(pipe_slow);
 247 %}
 248 
 249 // vector mask compare
 250 
 251 instruct vmaskcmp(vRegMask dst, vReg src1, vReg src2, immI cond) %{
 252   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
 253             Matcher::vector_element_basic_type(n) == T_SHORT ||
 254             Matcher::vector_element_basic_type(n) == T_INT ||
 255             Matcher::vector_element_basic_type(n) == T_LONG);
 256   match(Set dst (VectorMaskCmp (Binary src1 src2) cond));
 257   format %{ "vmaskcmp $dst, $src1, $src2, $cond" %}
 258   ins_encode %{
 259     BasicType bt = Matcher::vector_element_basic_type(this);
 260     uint vector_length = Matcher::vector_length(this);
 261     __ compare_integral_v(as_VectorRegister($dst$$reg),
 262                           as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 263                           (int)($cond$$constant), bt, vector_length);
 264   %}
 265   ins_pipe(pipe_slow);
 266 %}
 267 
 268 instruct vmaskcmp_masked(vRegMask dst, vReg src1, vReg src2, immI cond, vRegMask_V0 v0) %{
 269   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
 270             Matcher::vector_element_basic_type(n) == T_SHORT ||
 271             Matcher::vector_element_basic_type(n) == T_INT ||
 272             Matcher::vector_element_basic_type(n) == T_LONG);
 273   match(Set dst (VectorMaskCmp (Binary src1 src2) (Binary cond v0)));
 274   effect(TEMP_DEF dst);
 275   format %{ "vmaskcmp_masked $dst, $src1, $src2, $cond, $v0" %}
 276   ins_encode %{
 277     BasicType bt = Matcher::vector_element_basic_type(this);
 278     uint vector_length = Matcher::vector_length(this);
 279     __ compare_integral_v(as_VectorRegister($dst$$reg),
 280                           as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 281                           (int)($cond$$constant), bt, vector_length, Assembler::v0_t);
 282   %}
 283   ins_pipe(pipe_slow);
 284 %}
 285 
 286 // vector mask float compare
 287 
 288 instruct vmaskcmp_fp(vRegMask dst, vReg src1, vReg src2, immI cond) %{
 289   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT ||
 290             Matcher::vector_element_basic_type(n) == T_DOUBLE);
 291   match(Set dst (VectorMaskCmp (Binary src1 src2) cond));
 292   format %{ "vmaskcmp_fp $dst, $src1, $src2, $cond" %}
 293   ins_encode %{
 294     BasicType bt = Matcher::vector_element_basic_type(this);
 295     uint vector_length = Matcher::vector_length(this);
 296     __ compare_fp_v(as_VectorRegister($dst$$reg),
 297                     as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 298                     (int)($cond$$constant), bt, vector_length);
 299   %}
 300   ins_pipe(pipe_slow);
 301 %}
 302 
 303 instruct vmaskcmp_fp_masked(vRegMask dst, vReg src1, vReg src2, immI cond, vRegMask_V0 v0) %{
 304   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT ||
 305             Matcher::vector_element_basic_type(n) == T_DOUBLE);
 306   match(Set dst (VectorMaskCmp (Binary src1 src2) (Binary cond v0)));
 307   effect(TEMP_DEF dst);
 308   format %{ "vmaskcmp_fp_masked $dst, $src1, $src2, $cond, $v0" %}
 309   ins_encode %{
 310     BasicType bt = Matcher::vector_element_basic_type(this);
 311     uint vector_length = Matcher::vector_length(this);
 312     __ compare_fp_v(as_VectorRegister($dst$$reg),
 313                     as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
 314                     (int)($cond$$constant), bt, vector_length, Assembler::v0_t);
 315   %}
 316   ins_pipe(pipe_slow);
 317 %}
 318 
 319 // vector abs
 320 
 321 instruct vabs(vReg dst, vReg src, vReg tmp) %{
 322   match(Set dst (AbsVB src));
 323   match(Set dst (AbsVS src));
 324   match(Set dst (AbsVI src));
 325   match(Set dst (AbsVL src));
 326   effect(TEMP tmp);
 327   format %{ "vabs $dst, $src\t# KILL $tmp" %}
 328   ins_encode %{
 329     BasicType bt = Matcher::vector_element_basic_type(this);
 330     __ vsetvli_helper(bt, Matcher::vector_length(this));
 331     __ vrsub_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg), 0);
 332     __ vmax_vv(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
 333   %}
 334   ins_pipe(pipe_slow);
 335 %}
 336 
 337 instruct vabs_fp(vReg dst, vReg src) %{
 338   match(Set dst (AbsVF src));
 339   match(Set dst (AbsVD src));
 340   format %{ "vabs_fp $dst, $src" %}
 341   ins_encode %{
 342     BasicType bt = Matcher::vector_element_basic_type(this);
 343     __ vsetvli_helper(bt, Matcher::vector_length(this));
 344     __ vfabs_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
 345   %}
 346   ins_pipe(pipe_slow);
 347 %}
 348 
 349 // vector abs - predicated
 350 
 351 instruct vabs_masked(vReg dst_src, vRegMask_V0 v0, vReg tmp) %{
 352   match(Set dst_src (AbsVB dst_src v0));
 353   match(Set dst_src (AbsVS dst_src v0));
 354   match(Set dst_src (AbsVI dst_src v0));
 355   match(Set dst_src (AbsVL dst_src v0));
 356   effect(TEMP tmp);
 357   format %{ "vabs_masked $dst_src, $dst_src, $v0\t# KILL $tmp" %}
 358   ins_encode %{
 359     BasicType bt = Matcher::vector_element_basic_type(this);
 360     __ vsetvli_helper(bt, Matcher::vector_length(this));
 361     __ vrsub_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($dst_src$$reg), 0,
 362                 Assembler::v0_t);
 363     __ vmax_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($tmp$$reg),
 364                as_VectorRegister($dst_src$$reg), Assembler::v0_t);
 365   %}
 366   ins_pipe(pipe_slow);
 367 %}
 368 
 369 instruct vabs_fp_masked(vReg dst_src, vRegMask_V0 v0) %{
 370   match(Set dst_src (AbsVF dst_src v0));
 371   match(Set dst_src (AbsVD dst_src v0));
 372   format %{ "vabs_fp_masked $dst_src, $dst_src, $v0" %}
 373   ins_encode %{
 374     BasicType bt = Matcher::vector_element_basic_type(this);
 375     __ vsetvli_helper(bt, Matcher::vector_length(this));
 376     __ vfabs_v(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), Assembler::v0_t);
 377   %}
 378   ins_pipe(pipe_slow);
 379 %}
 380 
 381 // vector add
 382 
 383 instruct vadd(vReg dst, vReg src1, vReg src2) %{
 384   match(Set dst (AddVB src1 src2));
 385   match(Set dst (AddVS src1 src2));
 386   match(Set dst (AddVI src1 src2));
 387   match(Set dst (AddVL src1 src2));
 388   format %{ "vadd $dst, $src1, $src2" %}
 389   ins_encode %{
 390     BasicType bt = Matcher::vector_element_basic_type(this);
 391     __ vsetvli_helper(bt, Matcher::vector_length(this));
 392     __ vadd_vv(as_VectorRegister($dst$$reg),
 393                as_VectorRegister($src1$$reg),
 394                as_VectorRegister($src2$$reg));
 395   %}
 396   ins_pipe(pipe_slow);
 397 %}
 398 
 399 instruct vadd_hfp(vReg dst, vReg src1, vReg src2) %{
 400   match(Set dst (AddVHF src1 src2));
 401   format %{ "vadd_hfp $dst, $src1, $src2" %}
 402   ins_encode %{
 403     assert(UseZvfh, "must");
 404     assert(Matcher::vector_element_basic_type(this) == T_SHORT, "must");
 405     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
 406     __ vfadd_vv(as_VectorRegister($dst$$reg),
 407                 as_VectorRegister($src1$$reg),
 408                 as_VectorRegister($src2$$reg));
 409   %}
 410   ins_pipe(pipe_slow);
 411 %}
 412 
 413 instruct vadd_fp(vReg dst, vReg src1, vReg src2) %{
 414   match(Set dst (AddVF src1 src2));
 415   match(Set dst (AddVD src1 src2));
 416   format %{ "vadd_fp $dst, $src1, $src2" %}
 417   ins_encode %{
 418     BasicType bt = Matcher::vector_element_basic_type(this);
 419     __ vsetvli_helper(bt, Matcher::vector_length(this));
 420     __ vfadd_vv(as_VectorRegister($dst$$reg),
 421                 as_VectorRegister($src1$$reg),
 422                 as_VectorRegister($src2$$reg));
 423   %}
 424   ins_pipe(pipe_slow);
 425 %}
 426 
 427 // vector add - predicated
 428 
 429 instruct vadd_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
 430   match(Set dst_src1 (AddVB (Binary dst_src1 src2) v0));
 431   match(Set dst_src1 (AddVS (Binary dst_src1 src2) v0));
 432   match(Set dst_src1 (AddVI (Binary dst_src1 src2) v0));
 433   match(Set dst_src1 (AddVL (Binary dst_src1 src2) v0));
 434   format %{ "vadd_masked $dst_src1, $dst_src1, $src2, $v0" %}
 435   ins_encode %{
 436     BasicType bt = Matcher::vector_element_basic_type(this);
 437     __ vsetvli_helper(bt, Matcher::vector_length(this));
 438     __ vadd_vv(as_VectorRegister($dst_src1$$reg),
 439                as_VectorRegister($dst_src1$$reg),
 440                as_VectorRegister($src2$$reg), Assembler::v0_t);
 441   %}
 442   ins_pipe(pipe_slow);
 443 %}
 444 
 445 instruct vadd_fp_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
 446   match(Set dst_src1 (AddVF (Binary dst_src1 src2) v0));
 447   match(Set dst_src1 (AddVD (Binary dst_src1 src2) v0));
 448   format %{ "vadd_fp_masked $dst_src1, $dst_src1, $src2, $v0" %}
 449   ins_encode %{
 450     BasicType bt = Matcher::vector_element_basic_type(this);
 451     __ vsetvli_helper(bt, Matcher::vector_length(this));
 452     __ vfadd_vv(as_VectorRegister($dst_src1$$reg),
 453                 as_VectorRegister($dst_src1$$reg),
 454                 as_VectorRegister($src2$$reg), Assembler::v0_t);
 455   %}
 456   ins_pipe(pipe_slow);
 457 %}
 458 
 459 // vector-immediate add (unpredicated)
 460 
 461 instruct vadd_vi(vReg dst, vReg src1, immI5 con) %{
 462   match(Set dst (AddVB src1 (Replicate con)));
 463   match(Set dst (AddVS src1 (Replicate con)));
 464   match(Set dst (AddVI src1 (Replicate con)));
 465   format %{ "vadd_vi $dst, $src1, $con" %}
 466   ins_encode %{
 467     BasicType bt = Matcher::vector_element_basic_type(this);
 468     __ vsetvli_helper(bt, Matcher::vector_length(this));
 469     __ vadd_vi(as_VectorRegister($dst$$reg),
 470                as_VectorRegister($src1$$reg),
 471                $con$$constant);
 472   %}
 473   ins_pipe(pipe_slow);
 474 %}
 475 
 476 instruct vaddL_vi(vReg dst, vReg src1, immL5 con) %{
 477   match(Set dst (AddVL src1 (Replicate con)));
 478   format %{ "vaddL_vi $dst, $src1, $con" %}
 479   ins_encode %{
 480     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
 481     __ vadd_vi(as_VectorRegister($dst$$reg),
 482                as_VectorRegister($src1$$reg),
 483                $con$$constant);
 484   %}
 485   ins_pipe(pipe_slow);
 486 %}
 487 
 488 // vector-scalar add (unpredicated)
 489 
 490 instruct vadd_vx(vReg dst, vReg src1, iRegIorL2I src2) %{
 491   match(Set dst (AddVB src1 (Replicate src2)));
 492   match(Set dst (AddVS src1 (Replicate src2)));
 493   match(Set dst (AddVI src1 (Replicate src2)));
 494   format %{ "vadd_vx $dst, $src1, $src2" %}
 495   ins_encode %{
 496     BasicType bt = Matcher::vector_element_basic_type(this);
 497     __ vsetvli_helper(bt, Matcher::vector_length(this));
 498     __ vadd_vx(as_VectorRegister($dst$$reg),
 499                as_VectorRegister($src1$$reg),
 500                as_Register($src2$$reg));
 501   %}
 502   ins_pipe(pipe_slow);
 503 %}
 504 
 505 instruct vaddL_vx(vReg dst, vReg src1, iRegL src2) %{
 506   match(Set dst (AddVL src1 (Replicate src2)));
 507   format %{ "vaddL_vx $dst, $src1, $src2" %}
 508   ins_encode %{
 509     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
 510     __ vadd_vx(as_VectorRegister($dst$$reg),
 511                as_VectorRegister($src1$$reg),
 512                as_Register($src2$$reg));
 513   %}
 514   ins_pipe(pipe_slow);
 515 %}
 516 
 517 // vector-immediate add (predicated)
 518 
 519 instruct vadd_vi_masked(vReg dst_src, immI5 con, vRegMask_V0 v0) %{
 520   match(Set dst_src (AddVB (Binary dst_src (Replicate con)) v0));
 521   match(Set dst_src (AddVS (Binary dst_src (Replicate con)) v0));
 522   match(Set dst_src (AddVI (Binary dst_src (Replicate con)) v0));
 523   format %{ "vadd_vi_masked $dst_src, $dst_src, $con, $v0" %}
 524   ins_encode %{
 525     BasicType bt = Matcher::vector_element_basic_type(this);
 526     __ vsetvli_helper(bt, Matcher::vector_length(this));
 527     __ vadd_vi(as_VectorRegister($dst_src$$reg),
 528                as_VectorRegister($dst_src$$reg),
 529                $con$$constant, Assembler::v0_t);
 530   %}
 531   ins_pipe(pipe_slow);
 532 %}
 533 
 534 instruct vaddL_vi_masked(vReg dst_src, immL5 con, vRegMask_V0 v0) %{
 535   match(Set dst_src (AddVL (Binary dst_src (Replicate con)) v0));
 536   format %{ "vaddL_vi_masked $dst_src, $dst_src, $con, $v0" %}
 537   ins_encode %{
 538     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
 539     __ vadd_vi(as_VectorRegister($dst_src$$reg),
 540                as_VectorRegister($dst_src$$reg),
 541                $con$$constant, Assembler::v0_t);
 542   %}
 543   ins_pipe(pipe_slow);
 544 %}
 545 
 546 // vector-scalar add (predicated)
 547 
 548 instruct vadd_vx_masked(vReg dst_src, iRegIorL2I src2, vRegMask_V0 v0) %{
 549   match(Set dst_src (AddVB (Binary dst_src (Replicate src2)) v0));
 550   match(Set dst_src (AddVS (Binary dst_src (Replicate src2)) v0));
 551   match(Set dst_src (AddVI (Binary dst_src (Replicate src2)) v0));
 552   format %{ "vadd_vx_masked $dst_src, $dst_src, $src2, $v0" %}
 553   ins_encode %{
 554     BasicType bt = Matcher::vector_element_basic_type(this);
 555     __ vsetvli_helper(bt, Matcher::vector_length(this));
 556     __ vadd_vx(as_VectorRegister($dst_src$$reg),
 557                as_VectorRegister($dst_src$$reg),
 558                as_Register($src2$$reg), Assembler::v0_t);
 559   %}
 560   ins_pipe(pipe_slow);
 561 %}
 562 
 563 instruct vaddL_vx_masked(vReg dst_src, iRegL src2, vRegMask_V0 v0) %{
 564   match(Set dst_src (AddVL (Binary dst_src (Replicate src2)) v0));
 565   format %{ "vaddL_vx_masked $dst_src, $dst_src, $src2, $v0" %}
 566   ins_encode %{
 567     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
 568     __ vadd_vx(as_VectorRegister($dst_src$$reg),
 569                as_VectorRegister($dst_src$$reg),
 570                as_Register($src2$$reg), Assembler::v0_t);
 571   %}
 572   ins_pipe(pipe_slow);
 573 %}
 574 
 575 // vector sub
 576 
 577 instruct vsub(vReg dst, vReg src1, vReg src2) %{
 578   match(Set dst (SubVB src1 src2));
 579   match(Set dst (SubVS src1 src2));
 580   match(Set dst (SubVI src1 src2));
 581   match(Set dst (SubVL src1 src2));
 582   format %{ "vsub $dst, $src1, $src2" %}
 583   ins_encode %{
 584     BasicType bt = Matcher::vector_element_basic_type(this);
 585     __ vsetvli_helper(bt, Matcher::vector_length(this));
 586     __ vsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 587                as_VectorRegister($src2$$reg));
 588   %}
 589   ins_pipe(pipe_slow);
 590 %}
 591 
 592 instruct vsub_hfp(vReg dst, vReg src1, vReg src2) %{
 593   match(Set dst (SubVHF src1 src2));
 594   format %{ "vsub_hfp $dst, $src1, $src2" %}
 595   ins_encode %{
 596     assert(UseZvfh, "must");
 597     assert(Matcher::vector_element_basic_type(this) == T_SHORT, "must");
 598     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
 599     __ vfsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 600                 as_VectorRegister($src2$$reg));
 601   %}
 602   ins_pipe(pipe_slow);
 603 %}
 604 
 605 instruct vsub_fp(vReg dst, vReg src1, vReg src2) %{
 606   match(Set dst (SubVF src1 src2));
 607   match(Set dst (SubVD src1 src2));
 608   format %{ "vsub_fp $dst, $src1, $src2" %}
 609   ins_encode %{
 610     BasicType bt = Matcher::vector_element_basic_type(this);
 611     __ vsetvli_helper(bt, Matcher::vector_length(this));
 612     __ vfsub_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
 613                 as_VectorRegister($src2$$reg));
 614   %}
 615   ins_pipe(pipe_slow);
 616 %}
 617 
 618 // vector sub - predicated
 619 
 620 instruct vsub_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
 621   match(Set dst_src1 (SubVB (Binary dst_src1 src2) v0));
 622   match(Set dst_src1 (SubVS (Binary dst_src1 src2) v0));
 623   match(Set dst_src1 (SubVI (Binary dst_src1 src2) v0));
 624   match(Set dst_src1 (SubVL (Binary dst_src1 src2) v0));
 625   format %{ "vsub_masked $dst_src1, $dst_src1, $src2, $v0" %}
 626   ins_encode %{
 627     BasicType bt = Matcher::vector_element_basic_type(this);
 628     __ vsetvli_helper(bt, Matcher::vector_length(this));
 629     __ vsub_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg),
 630                as_VectorRegister($src2$$reg), Assembler::v0_t);
 631   %}
 632   ins_pipe(pipe_slow);
 633 %}
 634 
 635 instruct vsub_fp_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
 636   match(Set dst_src1 (SubVF (Binary dst_src1 src2) v0));
 637   match(Set dst_src1 (SubVD (Binary dst_src1 src2) v0));
 638   format %{ "vsub_fp_masked $dst_src1, $dst_src1, $src2, $v0" %}
 639   ins_encode %{
 640     BasicType bt = Matcher::vector_element_basic_type(this);
 641     __ vsetvli_helper(bt, Matcher::vector_length(this));
 642     __ vfsub_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg),
 643                 as_VectorRegister($src2$$reg), Assembler::v0_t);
 644   %}
 645   ins_pipe(pipe_slow);
 646 %}
 647 
 648 // vector-scalar sub (unpredicated)
 649 
 650 instruct vsub_vx(vReg dst, vReg src1, iRegIorL2I src2) %{
 651   match(Set dst (SubVB src1 (Replicate src2)));
 652   match(Set dst (SubVS src1 (Replicate src2)));
 653   match(Set dst (SubVI src1 (Replicate src2)));
 654   format %{ "vsub_vx $dst, $src1, $src2" %}
 655   ins_encode %{
 656     BasicType bt = Matcher::vector_element_basic_type(this);
 657     __ vsetvli_helper(bt, Matcher::vector_length(this));
 658     __ vsub_vx(as_VectorRegister($dst$$reg),
 659                as_VectorRegister($src1$$reg),
 660                as_Register($src2$$reg));
 661   %}
 662   ins_pipe(pipe_slow);
 663 %}
 664 
 665 instruct vsubL_vx(vReg dst, vReg src1, iRegL src2) %{
 666   match(Set dst (SubVL src1 (Replicate src2)));
 667   format %{ "vsubL_vx $dst, $src1, $src2" %}
 668   ins_encode %{
 669     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
 670     __ vsub_vx(as_VectorRegister($dst$$reg),
 671                as_VectorRegister($src1$$reg),
 672                as_Register($src2$$reg));
 673   %}
 674   ins_pipe(pipe_slow);
 675 %}
 676 
 677 // vector-scalar sub (predicated)
 678 
 679 instruct vsub_vx_masked(vReg dst_src, iRegIorL2I src2, vRegMask_V0 v0) %{
 680   match(Set dst_src (SubVB (Binary dst_src (Replicate src2)) v0));
 681   match(Set dst_src (SubVS (Binary dst_src (Replicate src2)) v0));
 682   match(Set dst_src (SubVI (Binary dst_src (Replicate src2)) v0));
 683   format %{ "vsub_vx_masked $dst_src, $dst_src, $src2, $v0" %}
 684   ins_encode %{
 685     BasicType bt = Matcher::vector_element_basic_type(this);
 686     __ vsetvli_helper(bt, Matcher::vector_length(this));
 687     __ vsub_vx(as_VectorRegister($dst_src$$reg),
 688                as_VectorRegister($dst_src$$reg),
 689                as_Register($src2$$reg), Assembler::v0_t);
 690   %}
 691   ins_pipe(pipe_slow);
 692 %}
 693 
 694 instruct vsubL_vx_masked(vReg dst_src, iRegL src2, vRegMask_V0 v0) %{
 695   match(Set dst_src (SubVL (Binary dst_src (Replicate src2)) v0));
 696   format %{ "vsubL_vx_masked $dst_src, $dst_src, $src2, $v0" %}
 697   ins_encode %{
 698     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
 699     __ vsub_vx(as_VectorRegister($dst_src$$reg),
 700                as_VectorRegister($dst_src$$reg),
 701                as_Register($src2$$reg), Assembler::v0_t);
 702   %}
 703   ins_pipe(pipe_slow);
 704 %}
 705 
 706 // -------- vector saturating integer operations
 707 
 708 // vector saturating signed integer addition
 709 
 710 instruct vsadd(vReg dst, vReg src1, vReg src2) %{
 711   predicate(n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
 712   match(Set dst (SaturatingAddV src1 src2));
 713   format %{ "vsadd $dst, $src1, $src2" %}
 714   ins_encode %{
 715     BasicType bt = Matcher::vector_element_basic_type(this);
 716     assert(is_integral_type(bt), "unsupported type");
 717     __ vsetvli_helper(bt, Matcher::vector_length(this));
 718     __ vsadd_vv(as_VectorRegister($dst$$reg),
 719                 as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
 720   %}
 721   ins_pipe(pipe_slow);
 722 %}
 723 
 724 // vector saturating unsigned integer addition
 725 
 726 instruct vsaddu(vReg dst, vReg src1, vReg src2) %{
 727   predicate(n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
 728   match(Set dst (SaturatingAddV src1 src2));
 729   format %{ "vsaddu $dst, $src1, $src2" %}
 730   ins_encode %{
 731     BasicType bt = Matcher::vector_element_basic_type(this);
 732     assert(is_integral_type(bt), "unsupported type");
 733     __ vsetvli_helper(bt, Matcher::vector_length(this));
 734     __ vsaddu_vv(as_VectorRegister($dst$$reg),
 735                  as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
 736   %}
 737   ins_pipe(pipe_slow);
 738 %}
 739 
 740 // vector saturating signed integer addition (predicated)
 741 
 742 instruct vsadd_masked(vReg dst_src, vReg src1, vRegMask_V0 v0) %{
 743   predicate(n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
 744   match(Set dst_src (SaturatingAddV (Binary dst_src src1) v0));
 745   format %{ "vsadd_masked $dst_src, $dst_src, $src1, $v0" %}
 746   ins_encode %{
 747     BasicType bt = Matcher::vector_element_basic_type(this);
 748     assert(is_integral_type(bt), "unsupported type");
 749     __ vsetvli_helper(bt, Matcher::vector_length(this));
 750     __ vsadd_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
 751                 as_VectorRegister($src1$$reg), Assembler::v0_t);
 752   %}
 753   ins_pipe(pipe_slow);
 754 %}
 755 
 756 // vector saturating unsigned integer addition (predicated)
 757 
 758 instruct vsaddu_masked(vReg dst_src, vReg src1, vRegMask_V0 v0) %{
 759   predicate(n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
 760   match(Set dst_src (SaturatingAddV (Binary dst_src src1) v0));
 761   format %{ "vsaddu_masked $dst_src, $dst_src, $src1, $v0" %}
 762   ins_encode %{
 763     BasicType bt = Matcher::vector_element_basic_type(this);
 764     assert(is_integral_type(bt), "unsupported type");
 765     __ vsetvli_helper(bt, Matcher::vector_length(this));
 766     __ vsaddu_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
 767                  as_VectorRegister($src1$$reg), Assembler::v0_t);
 768   %}
 769   ins_pipe(pipe_slow);
 770 %}
 771 
 772 // vector saturating signed integer subtraction
 773 
 774 instruct vssub(vReg dst, vReg src1, vReg src2) %{
 775   predicate(n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
 776   match(Set dst (SaturatingSubV src1 src2));
 777   format %{ "vssub $dst, $src1, $src2" %}
 778   ins_encode %{
 779     BasicType bt = Matcher::vector_element_basic_type(this);
 780     assert(is_integral_type(bt), "unsupported type");
 781     __ vsetvli_helper(bt, Matcher::vector_length(this));
 782     __ vssub_vv(as_VectorRegister($dst$$reg),
 783                 as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
 784   %}
 785   ins_pipe(pipe_slow);
 786 %}
 787 
 788 // vector saturating unsigned integer subtraction
 789 
 790 instruct vssubu(vReg dst, vReg src1, vReg src2) %{
 791   predicate(n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
 792   match(Set dst (SaturatingSubV src1 src2));
 793   format %{ "vssubu $dst, $src1, $src2" %}
 794   ins_encode %{
 795     BasicType bt = Matcher::vector_element_basic_type(this);
 796     assert(is_integral_type(bt), "unsupported type");
 797     __ vsetvli_helper(bt, Matcher::vector_length(this));
 798     __ vssubu_vv(as_VectorRegister($dst$$reg),
 799                  as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
 800   %}
 801   ins_pipe(pipe_slow);
 802 %}
 803 
 804 // vector saturating signed integer subtraction (predicated)
 805 
 806 instruct vssub_masked(vReg dst_src, vReg src1, vRegMask_V0 v0) %{
 807   predicate(n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
 808   match(Set dst_src (SaturatingSubV (Binary dst_src src1) v0));
 809   format %{ "vssub_masked $dst_src, $dst_src, $src1, $v0" %}
 810   ins_encode %{
 811     BasicType bt = Matcher::vector_element_basic_type(this);
 812     assert(is_integral_type(bt), "unsupported type");
 813     __ vsetvli_helper(bt, Matcher::vector_length(this));
 814     __ vssub_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
 815                 as_VectorRegister($src1$$reg), Assembler::v0_t);
 816   %}
 817   ins_pipe(pipe_slow);
 818 %}
 819 
 820 // vector saturating unsigned integer subtraction (predicated)
 821 
 822 instruct vssubu_masked(vReg dst_src, vReg src1, vRegMask_V0 v0) %{
 823   predicate(n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
 824   match(Set dst_src (SaturatingSubV (Binary dst_src src1) v0));
 825   format %{ "vssubu_masked $dst_src, $dst_src, $src1, $v0" %}
 826   ins_encode %{
 827     BasicType bt = Matcher::vector_element_basic_type(this);
 828     assert(is_integral_type(bt), "unsupported type");
 829     __ vsetvli_helper(bt, Matcher::vector_length(this));
 830     __ vssubu_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
 831                  as_VectorRegister($src1$$reg), Assembler::v0_t);
 832   %}
 833   ins_pipe(pipe_slow);
 834 %}
 835 
 836 // vector and
 837 
 838 instruct vand(vReg dst, vReg src1, vReg src2) %{
 839   match(Set dst (AndV src1 src2));
 840   format %{ "vand $dst, $src1, $src2" %}
 841   ins_encode %{
 842     BasicType bt = Matcher::vector_element_basic_type(this);
 843     __ vsetvli_helper(bt, Matcher::vector_length(this));
 844     __ vand_vv(as_VectorRegister($dst$$reg),
 845                as_VectorRegister($src1$$reg),
 846                as_VectorRegister($src2$$reg));
 847   %}
 848   ins_pipe(pipe_slow);
 849 %}
 850 
 851 // vector and - predicated
 852 
 853 instruct vand_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
 854   match(Set dst_src1 (AndV (Binary dst_src1 src2) v0));
 855   format %{ "vand_masked $dst_src1, $dst_src1, $src2, $v0" %}
 856   ins_encode %{
 857     BasicType bt = Matcher::vector_element_basic_type(this);
 858     __ vsetvli_helper(bt, Matcher::vector_length(this));
 859     __ vand_vv(as_VectorRegister($dst_src1$$reg),
 860                as_VectorRegister($dst_src1$$reg),
 861                as_VectorRegister($src2$$reg), Assembler::v0_t);
 862   %}
 863   ins_pipe(pipe_slow);
 864 %}
 865 
 866 // vector-immediate and (unpredicated)
 867 
 868 instruct vand_vi(vReg dst, vReg src1, immI5 con) %{
 869   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
 870             Matcher::vector_element_basic_type(n) == T_SHORT ||
 871             Matcher::vector_element_basic_type(n) == T_INT);
 872   match(Set dst (AndV src1 (Replicate con)));
 873   format %{ "vand_vi $dst, $src1, $con" %}
 874   ins_encode %{
 875     BasicType bt = Matcher::vector_element_basic_type(this);
 876     __ vsetvli_helper(bt, Matcher::vector_length(this));
 877     __ vand_vi(as_VectorRegister($dst$$reg),
 878                as_VectorRegister($src1$$reg),
 879                $con$$constant);
 880   %}
 881   ins_pipe(pipe_slow);
 882 %}
 883 
 884 instruct vandL_vi(vReg dst, vReg src1, immL5 con) %{
 885   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
 886   match(Set dst (AndV src1 (Replicate con)));
 887   format %{ "vandL_vi $dst, $src1, $con" %}
 888   ins_encode %{
 889     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
 890     __ vand_vi(as_VectorRegister($dst$$reg),
 891                as_VectorRegister($src1$$reg),
 892                $con$$constant);
 893   %}
 894   ins_pipe(pipe_slow);
 895 %}
 896 
 897 // vector-scalar and (unpredicated)
 898 
 899 instruct vand_vx(vReg dst, vReg src1, iRegIorL2I src2) %{
 900   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
 901             Matcher::vector_element_basic_type(n) == T_SHORT ||
 902             Matcher::vector_element_basic_type(n) == T_INT);
 903   match(Set dst (AndV src1 (Replicate src2)));
 904   format %{ "vand_vx $dst, $src1, $src2" %}
 905   ins_encode %{
 906     BasicType bt = Matcher::vector_element_basic_type(this);
 907     __ vsetvli_helper(bt, Matcher::vector_length(this));
 908     __ vand_vx(as_VectorRegister($dst$$reg),
 909                as_VectorRegister($src1$$reg),
 910                as_Register($src2$$reg));
 911   %}
 912   ins_pipe(pipe_slow);
 913 %}
 914 
 915 instruct vandL_vx(vReg dst, vReg src1, iRegL src2) %{
 916   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
 917   match(Set dst (AndV src1 (Replicate src2)));
 918   format %{ "vandL_vx $dst, $src1, $src2" %}
 919   ins_encode %{
 920     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
 921     __ vand_vx(as_VectorRegister($dst$$reg),
 922                as_VectorRegister($src1$$reg),
 923                as_Register($src2$$reg));
 924   %}
 925   ins_pipe(pipe_slow);
 926 %}
 927 
 928 // vector-immediate and (predicated)
 929 
 930 instruct vand_vi_masked(vReg dst_src, immI5 con, vRegMask_V0 v0) %{
 931   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
 932             Matcher::vector_element_basic_type(n) == T_SHORT ||
 933             Matcher::vector_element_basic_type(n) == T_INT);
 934   match(Set dst_src (AndV (Binary dst_src (Replicate con)) v0));
 935   format %{ "vand_vi_masked $dst_src, $dst_src, $con, $v0" %}
 936   ins_encode %{
 937     BasicType bt = Matcher::vector_element_basic_type(this);
 938     __ vsetvli_helper(bt, Matcher::vector_length(this));
 939     __ vand_vi(as_VectorRegister($dst_src$$reg),
 940                as_VectorRegister($dst_src$$reg),
 941                $con$$constant, Assembler::v0_t);
 942   %}
 943   ins_pipe(pipe_slow);
 944 %}
 945 
 946 instruct vandL_vi_masked(vReg dst_src, immL5 con, vRegMask_V0 v0) %{
 947   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
 948   match(Set dst_src (AndV (Binary dst_src (Replicate con)) v0));
 949   format %{ "vandL_vi_masked $dst_src, $dst_src, $con, $v0" %}
 950   ins_encode %{
 951     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
 952     __ vand_vi(as_VectorRegister($dst_src$$reg),
 953                as_VectorRegister($dst_src$$reg),
 954                $con$$constant, Assembler::v0_t);
 955   %}
 956   ins_pipe(pipe_slow);
 957 %}
 958 
 959 // vector-scalar and (predicated)
 960 
 961 instruct vand_vx_masked(vReg dst_src, iRegIorL2I src, vRegMask_V0 v0) %{
 962   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
 963             Matcher::vector_element_basic_type(n) == T_SHORT ||
 964             Matcher::vector_element_basic_type(n) == T_INT);
 965   match(Set dst_src (AndV (Binary dst_src (Replicate src)) v0));
 966   format %{ "vand_vx_masked $dst_src, $dst_src, $src, $v0" %}
 967   ins_encode %{
 968     BasicType bt = Matcher::vector_element_basic_type(this);
 969     __ vsetvli_helper(bt, Matcher::vector_length(this));
 970     __ vand_vx(as_VectorRegister($dst_src$$reg),
 971                as_VectorRegister($dst_src$$reg),
 972                as_Register($src$$reg), Assembler::v0_t);
 973   %}
 974   ins_pipe(pipe_slow);
 975 %}
 976 
 977 instruct vandL_vx_masked(vReg dst_src, iRegL src, vRegMask_V0 v0) %{
 978   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
 979   match(Set dst_src (AndV (Binary dst_src (Replicate src)) v0));
 980   format %{ "vandL_vx_masked $dst_src, $dst_src, $src, $v0" %}
 981   ins_encode %{
 982     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
 983     __ vand_vx(as_VectorRegister($dst_src$$reg),
 984                as_VectorRegister($dst_src$$reg),
 985                as_Register($src$$reg), Assembler::v0_t);
 986   %}
 987   ins_pipe(pipe_slow);
 988 %}
 989 
 990 // vector or
 991 
 992 instruct vor(vReg dst, vReg src1, vReg src2) %{
 993   match(Set dst (OrV src1 src2));
 994   format %{ "vor $dst, $src1, $src2" %}
 995   ins_encode %{
 996     BasicType bt = Matcher::vector_element_basic_type(this);
 997     __ vsetvli_helper(bt, Matcher::vector_length(this));
 998     __ vor_vv(as_VectorRegister($dst$$reg),
 999               as_VectorRegister($src1$$reg),
1000               as_VectorRegister($src2$$reg));
1001   %}
1002   ins_pipe(pipe_slow);
1003 %}
1004 
1005 // vector or - predicated
1006 
1007 instruct vor_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
1008   match(Set dst_src1 (OrV (Binary dst_src1 src2) v0));
1009   format %{ "vor_masked $dst_src1, $dst_src1, $src2, $v0" %}
1010   ins_encode %{
1011     BasicType bt = Matcher::vector_element_basic_type(this);
1012     __ vsetvli_helper(bt, Matcher::vector_length(this));
1013     __ vor_vv(as_VectorRegister($dst_src1$$reg),
1014               as_VectorRegister($dst_src1$$reg),
1015               as_VectorRegister($src2$$reg), Assembler::v0_t);
1016   %}
1017   ins_pipe(pipe_slow);
1018 %}
1019 
1020 // vector-immediate or (unpredicated)
1021 
1022 instruct vor_vi(vReg dst, vReg src1, immI5 con) %{
1023   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
1024             Matcher::vector_element_basic_type(n) == T_SHORT ||
1025             Matcher::vector_element_basic_type(n) == T_INT);
1026   match(Set dst (OrV src1 (Replicate con)));
1027   format %{ "vor_vi $dst, $src1, $con" %}
1028   ins_encode %{
1029     BasicType bt = Matcher::vector_element_basic_type(this);
1030     __ vsetvli_helper(bt, Matcher::vector_length(this));
1031     __ vor_vi(as_VectorRegister($dst$$reg),
1032               as_VectorRegister($src1$$reg),
1033               $con$$constant);
1034   %}
1035   ins_pipe(pipe_slow);
1036 %}
1037 
1038 instruct vorL_vi(vReg dst, vReg src1, immL5 con) %{
1039   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
1040   match(Set dst (OrV src1 (Replicate con)));
1041   format %{ "vorL_vi $dst, $src1, $con" %}
1042   ins_encode %{
1043     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1044     __ vor_vi(as_VectorRegister($dst$$reg),
1045               as_VectorRegister($src1$$reg),
1046               $con$$constant);
1047   %}
1048   ins_pipe(pipe_slow);
1049 %}
1050 
1051 // vector-scalar or (unpredicated)
1052 
1053 instruct vor_vx(vReg dst, vReg src1, iRegIorL2I src2) %{
1054   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
1055             Matcher::vector_element_basic_type(n) == T_SHORT ||
1056             Matcher::vector_element_basic_type(n) == T_INT);
1057   match(Set dst (OrV src1 (Replicate src2)));
1058   format %{ "vor_vx $dst, $src1, $src2" %}
1059   ins_encode %{
1060     BasicType bt = Matcher::vector_element_basic_type(this);
1061     __ vsetvli_helper(bt, Matcher::vector_length(this));
1062     __ vor_vx(as_VectorRegister($dst$$reg),
1063               as_VectorRegister($src1$$reg),
1064               as_Register($src2$$reg));
1065   %}
1066   ins_pipe(pipe_slow);
1067 %}
1068 
1069 instruct vorL_vx(vReg dst, vReg src1, iRegL src2) %{
1070   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
1071   match(Set dst (OrV src1 (Replicate src2)));
1072   format %{ "vorL_vx $dst, $src1, $src2" %}
1073   ins_encode %{
1074     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1075     __ vor_vx(as_VectorRegister($dst$$reg),
1076               as_VectorRegister($src1$$reg),
1077               as_Register($src2$$reg));
1078   %}
1079   ins_pipe(pipe_slow);
1080 %}
1081 
1082 // vector-immediate or (predicated)
1083 
1084 instruct vor_vi_masked(vReg dst_src, immI5 con, vRegMask_V0 v0) %{
1085   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
1086             Matcher::vector_element_basic_type(n) == T_SHORT ||
1087             Matcher::vector_element_basic_type(n) == T_INT);
1088   match(Set dst_src (OrV (Binary dst_src (Replicate con)) v0));
1089   format %{ "vor_vi_masked $dst_src, $dst_src, $con, $v0" %}
1090   ins_encode %{
1091     BasicType bt = Matcher::vector_element_basic_type(this);
1092     __ vsetvli_helper(bt, Matcher::vector_length(this));
1093     __ vor_vi(as_VectorRegister($dst_src$$reg),
1094               as_VectorRegister($dst_src$$reg),
1095               $con$$constant, Assembler::v0_t);
1096   %}
1097   ins_pipe(pipe_slow);
1098 %}
1099 
1100 instruct vorL_vi_masked(vReg dst_src, immL5 con, vRegMask_V0 v0) %{
1101   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
1102   match(Set dst_src (OrV (Binary dst_src (Replicate con)) v0));
1103   format %{ "vorL_vi_masked $dst_src, $dst_src, $con, $v0" %}
1104   ins_encode %{
1105     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1106     __ vor_vi(as_VectorRegister($dst_src$$reg),
1107               as_VectorRegister($dst_src$$reg),
1108               $con$$constant, Assembler::v0_t);
1109   %}
1110   ins_pipe(pipe_slow);
1111 %}
1112 
1113 // vector-scalar or (predicated)
1114 
1115 instruct vor_vx_masked(vReg dst_src, iRegIorL2I src, vRegMask_V0 v0) %{
1116   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
1117             Matcher::vector_element_basic_type(n) == T_SHORT ||
1118             Matcher::vector_element_basic_type(n) == T_INT);
1119   match(Set dst_src (OrV (Binary dst_src (Replicate src)) v0));
1120   format %{ "vor_vx_masked $dst_src, $dst_src, $src, $v0" %}
1121   ins_encode %{
1122     BasicType bt = Matcher::vector_element_basic_type(this);
1123     __ vsetvli_helper(bt, Matcher::vector_length(this));
1124     __ vor_vx(as_VectorRegister($dst_src$$reg),
1125               as_VectorRegister($dst_src$$reg),
1126               as_Register($src$$reg), Assembler::v0_t);
1127   %}
1128   ins_pipe(pipe_slow);
1129 %}
1130 
1131 instruct vorL_vx_masked(vReg dst_src, iRegL src, vRegMask_V0 v0) %{
1132   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
1133   match(Set dst_src (OrV (Binary dst_src (Replicate src)) v0));
1134   format %{ "vorL_vx_masked $dst_src, $dst_src, $src, $v0" %}
1135   ins_encode %{
1136     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1137     __ vor_vx(as_VectorRegister($dst_src$$reg),
1138               as_VectorRegister($dst_src$$reg),
1139               as_Register($src$$reg), Assembler::v0_t);
1140   %}
1141   ins_pipe(pipe_slow);
1142 %}
1143 
1144 // vector xor
1145 
1146 instruct vxor(vReg dst, vReg src1, vReg src2) %{
1147   match(Set dst (XorV src1 src2));
1148   format %{ "vxor $dst, $src1, $src2" %}
1149   ins_encode %{
1150     BasicType bt = Matcher::vector_element_basic_type(this);
1151     __ vsetvli_helper(bt, Matcher::vector_length(this));
1152     __ vxor_vv(as_VectorRegister($dst$$reg),
1153                as_VectorRegister($src1$$reg),
1154                as_VectorRegister($src2$$reg));
1155   %}
1156   ins_pipe(pipe_slow);
1157 %}
1158 
1159 // vector xor - predicated
1160 
1161 instruct vxor_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
1162   match(Set dst_src1 (XorV (Binary dst_src1 src2) v0));
1163   format %{ "vxor_masked $dst_src1, $dst_src1, $src2, $v0" %}
1164   ins_encode %{
1165     BasicType bt = Matcher::vector_element_basic_type(this);
1166     __ vsetvli_helper(bt, Matcher::vector_length(this));
1167     __ vxor_vv(as_VectorRegister($dst_src1$$reg),
1168                as_VectorRegister($dst_src1$$reg),
1169                as_VectorRegister($src2$$reg), Assembler::v0_t);
1170   %}
1171   ins_pipe(pipe_slow);
1172 %}
1173 
1174 // vector-immediate xor (unpredicated)
1175 
1176 instruct vxor_vi(vReg dst, vReg src1, immI5 con) %{
1177   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
1178             Matcher::vector_element_basic_type(n) == T_SHORT ||
1179             Matcher::vector_element_basic_type(n) == T_INT);
1180   match(Set dst (XorV src1 (Replicate con)));
1181   format %{ "vxor_vi $dst, $src1, $con" %}
1182   ins_encode %{
1183     BasicType bt = Matcher::vector_element_basic_type(this);
1184     __ vsetvli_helper(bt, Matcher::vector_length(this));
1185     __ vxor_vi(as_VectorRegister($dst$$reg),
1186                as_VectorRegister($src1$$reg),
1187                $con$$constant);
1188   %}
1189   ins_pipe(pipe_slow);
1190 %}
1191 
1192 instruct vxorL_vi(vReg dst, vReg src1, immL5 con) %{
1193   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
1194   match(Set dst (XorV src1 (Replicate con)));
1195   format %{ "vxorL_vi $dst, $src1, $con" %}
1196   ins_encode %{
1197     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1198     __ vxor_vi(as_VectorRegister($dst$$reg),
1199                as_VectorRegister($src1$$reg),
1200                $con$$constant);
1201   %}
1202   ins_pipe(pipe_slow);
1203 %}
1204 
1205 // vector-scalar xor (unpredicated)
1206 
1207 instruct vxor_vx(vReg dst, vReg src1, iRegIorL2I src2) %{
1208   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
1209             Matcher::vector_element_basic_type(n) == T_SHORT ||
1210             Matcher::vector_element_basic_type(n) == T_INT);
1211   match(Set dst (XorV src1 (Replicate src2)));
1212   format %{ "vxor_vx $dst, $src1, $src2" %}
1213   ins_encode %{
1214     BasicType bt = Matcher::vector_element_basic_type(this);
1215     __ vsetvli_helper(bt, Matcher::vector_length(this));
1216     __ vxor_vx(as_VectorRegister($dst$$reg),
1217                as_VectorRegister($src1$$reg),
1218                as_Register($src2$$reg));
1219   %}
1220   ins_pipe(pipe_slow);
1221 %}
1222 
1223 instruct vxorL_vx(vReg dst, vReg src1, iRegL src2) %{
1224   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
1225   match(Set dst (XorV src1 (Replicate src2)));
1226   format %{ "vxorL_vx $dst, $src1, $src2" %}
1227   ins_encode %{
1228     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1229     __ vxor_vx(as_VectorRegister($dst$$reg),
1230                as_VectorRegister($src1$$reg),
1231                as_Register($src2$$reg));
1232   %}
1233   ins_pipe(pipe_slow);
1234 %}
1235 
1236 // vector-immediate xor (predicated)
1237 
1238 instruct vxor_vi_masked(vReg dst_src, immI5 con, vRegMask_V0 v0) %{
1239   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
1240             Matcher::vector_element_basic_type(n) == T_SHORT ||
1241             Matcher::vector_element_basic_type(n) == T_INT);
1242   match(Set dst_src (XorV (Binary dst_src (Replicate con)) v0));
1243   format %{ "vxor_vi_masked $dst_src, $dst_src, $con, $v0" %}
1244   ins_encode %{
1245     BasicType bt = Matcher::vector_element_basic_type(this);
1246     __ vsetvli_helper(bt, Matcher::vector_length(this));
1247     __ vxor_vi(as_VectorRegister($dst_src$$reg),
1248                as_VectorRegister($dst_src$$reg),
1249                $con$$constant, Assembler::v0_t);
1250   %}
1251   ins_pipe(pipe_slow);
1252 %}
1253 
1254 instruct vxorL_vi_masked(vReg dst_src, immL5 con, vRegMask_V0 v0) %{
1255   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
1256   match(Set dst_src (XorV (Binary dst_src (Replicate con)) v0));
1257   format %{ "vxorL_vi_masked $dst_src, $dst_src, $con, $v0" %}
1258   ins_encode %{
1259     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1260     __ vxor_vi(as_VectorRegister($dst_src$$reg),
1261                as_VectorRegister($dst_src$$reg),
1262                $con$$constant, Assembler::v0_t);
1263   %}
1264   ins_pipe(pipe_slow);
1265 %}
1266 
1267 // vector-scalar xor (predicated)
1268 
1269 instruct vxor_vx_masked(vReg dst_src, iRegIorL2I src, vRegMask_V0 v0) %{
1270   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
1271             Matcher::vector_element_basic_type(n) == T_SHORT ||
1272             Matcher::vector_element_basic_type(n) == T_INT);
1273   match(Set dst_src (XorV (Binary dst_src (Replicate src)) v0));
1274   format %{ "vxor_vx_masked $dst_src, $dst_src, $src, $v0" %}
1275   ins_encode %{
1276     BasicType bt = Matcher::vector_element_basic_type(this);
1277     __ vsetvli_helper(bt, Matcher::vector_length(this));
1278     __ vxor_vx(as_VectorRegister($dst_src$$reg),
1279                as_VectorRegister($dst_src$$reg),
1280                as_Register($src$$reg), Assembler::v0_t);
1281   %}
1282   ins_pipe(pipe_slow);
1283 %}
1284 
1285 instruct vxorL_vx_masked(vReg dst_src, iRegL src, vRegMask_V0 v0) %{
1286   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
1287   match(Set dst_src (XorV (Binary dst_src (Replicate src)) v0));
1288   format %{ "vxorL_vx_masked $dst_src, $dst_src, $src, $v0" %}
1289   ins_encode %{
1290     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1291     __ vxor_vx(as_VectorRegister($dst_src$$reg),
1292                as_VectorRegister($dst_src$$reg),
1293                as_Register($src$$reg), Assembler::v0_t);
1294   %}
1295   ins_pipe(pipe_slow);
1296 %}
1297 
1298 // ------------------------------ Vector and not -----------------------------------
1299 
1300 // vector and not
1301 
1302 instruct vand_notB(vReg dst, vReg src1, vReg src2, immI_M1 m1) %{
1303   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_BYTE);
1304   match(Set dst (AndV src1 (XorV src2 (Replicate m1))));
1305   format %{ "vand_notB $dst, $src1, $src2" %}
1306   ins_encode %{
1307     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
1308     __ vandn_vv(as_VectorRegister($dst$$reg),
1309                 as_VectorRegister($src1$$reg),
1310                 as_VectorRegister($src2$$reg));
1311   %}
1312   ins_pipe(pipe_slow);
1313 %}
1314 
1315 instruct vand_notS(vReg dst, vReg src1, vReg src2, immI_M1 m1) %{
1316   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_SHORT);
1317   match(Set dst (AndV src1 (XorV src2 (Replicate m1))));
1318   format %{ "vand_notS $dst, $src1, $src2" %}
1319   ins_encode %{
1320     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
1321     __ vandn_vv(as_VectorRegister($dst$$reg),
1322                 as_VectorRegister($src1$$reg),
1323                 as_VectorRegister($src2$$reg));
1324   %}
1325   ins_pipe(pipe_slow);
1326 %}
1327 
1328 instruct vand_notI(vReg dst, vReg src1, vReg src2, immI_M1 m1) %{
1329   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_INT);
1330   match(Set dst (AndV src1 (XorV src2 (Replicate m1))));
1331   format %{ "vand_notI $dst, $src1, $src2" %}
1332   ins_encode %{
1333     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
1334     __ vandn_vv(as_VectorRegister($dst$$reg),
1335                 as_VectorRegister($src1$$reg),
1336                 as_VectorRegister($src2$$reg));
1337   %}
1338   ins_pipe(pipe_slow);
1339 %}
1340 
1341 instruct vand_notL(vReg dst, vReg src1, vReg src2, immL_M1 m1) %{
1342   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_LONG);
1343   match(Set dst (AndV src1 (XorV src2 (Replicate m1))));
1344   format %{ "vand_notL $dst, $src1, $src2" %}
1345   ins_encode %{
1346     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1347     __ vandn_vv(as_VectorRegister($dst$$reg),
1348                 as_VectorRegister($src1$$reg),
1349                 as_VectorRegister($src2$$reg));
1350   %}
1351   ins_pipe(pipe_slow);
1352 %}
1353 
1354 instruct vand_notB_masked(vReg dst_src1, vReg src2, immI_M1 m1, vRegMask_V0 v0) %{
1355   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_BYTE);
1356   match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (Replicate m1))) v0));
1357   format %{ "vand_notB_masked $dst_src1, $dst_src1, $src2, $v0" %}
1358   ins_encode %{
1359     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
1360     __ vandn_vv(as_VectorRegister($dst_src1$$reg),
1361                 as_VectorRegister($dst_src1$$reg),
1362                 as_VectorRegister($src2$$reg),
1363                 Assembler::v0_t);
1364   %}
1365   ins_pipe(pipe_slow);
1366 %}
1367 
1368 instruct vand_notS_masked(vReg dst_src1, vReg src2, immI_M1 m1, vRegMask_V0 v0) %{
1369   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_SHORT);
1370   match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (Replicate m1))) v0));
1371   format %{ "vand_notS_masked $dst_src1, $dst_src1, $src2, $v0" %}
1372   ins_encode %{
1373     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
1374     __ vandn_vv(as_VectorRegister($dst_src1$$reg),
1375                 as_VectorRegister($dst_src1$$reg),
1376                 as_VectorRegister($src2$$reg),
1377                 Assembler::v0_t);
1378   %}
1379   ins_pipe(pipe_slow);
1380 %}
1381 
1382 instruct vand_notI_masked(vReg dst_src1, vReg src2, immI_M1 m1, vRegMask_V0 v0) %{
1383   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_INT);
1384   match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (Replicate m1))) v0));
1385   format %{ "vand_notI_masked $dst_src1, $dst_src1, $src2, $v0" %}
1386   ins_encode %{
1387     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
1388     __ vandn_vv(as_VectorRegister($dst_src1$$reg),
1389                 as_VectorRegister($dst_src1$$reg),
1390                 as_VectorRegister($src2$$reg),
1391                 Assembler::v0_t);
1392   %}
1393   ins_pipe(pipe_slow);
1394 %}
1395 
1396 instruct vand_notL_masked(vReg dst_src1, vReg src2, immL_M1 m1, vRegMask_V0 v0) %{
1397   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_LONG);
1398   match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (Replicate m1))) v0));
1399   format %{ "vand_notL_masked $dst_src1, $dst_src1, $src2, $v0" %}
1400   ins_encode %{
1401     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1402     __ vandn_vv(as_VectorRegister($dst_src1$$reg),
1403                 as_VectorRegister($dst_src1$$reg),
1404                 as_VectorRegister($src2$$reg),
1405                 Assembler::v0_t);
1406   %}
1407   ins_pipe(pipe_slow);
1408 %}
1409 
1410 instruct vand_notB_vx(vReg dst, vReg src1, iRegIorL2I src2, immI_M1 m1) %{
1411   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_BYTE);
1412   match(Set dst (AndV src1 (Replicate (XorI src2 m1))));
1413   format %{ "vand_notB_vx $dst, $src1, $src2" %}
1414   ins_encode %{
1415     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
1416     __ vandn_vx(as_VectorRegister($dst$$reg),
1417                 as_VectorRegister($src1$$reg),
1418                 as_Register($src2$$reg));
1419   %}
1420   ins_pipe(pipe_slow);
1421 %}
1422 
1423 instruct vand_notS_vx(vReg dst, vReg src1, iRegIorL2I src2, immI_M1 m1) %{
1424   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_SHORT);
1425   match(Set dst (AndV src1 (Replicate (XorI src2 m1))));
1426   format %{ "vand_notS_vx $dst, $src1, $src2" %}
1427   ins_encode %{
1428     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
1429     __ vandn_vx(as_VectorRegister($dst$$reg),
1430                 as_VectorRegister($src1$$reg),
1431                 as_Register($src2$$reg));
1432   %}
1433   ins_pipe(pipe_slow);
1434 %}
1435 
1436 instruct vand_notI_vx(vReg dst, vReg src1, iRegIorL2I src2, immI_M1 m1) %{
1437   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_INT);
1438   match(Set dst (AndV src1 (Replicate (XorI src2 m1))));
1439   format %{ "vand_notI_vx $dst, $src1, $src2" %}
1440   ins_encode %{
1441     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
1442     __ vandn_vx(as_VectorRegister($dst$$reg),
1443                 as_VectorRegister($src1$$reg),
1444                 as_Register($src2$$reg));
1445   %}
1446   ins_pipe(pipe_slow);
1447 %}
1448 
1449 instruct vand_notL_vx(vReg dst, vReg src1, iRegL src2, immL_M1 m1) %{
1450   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_LONG);
1451   match(Set dst (AndV src1 (Replicate (XorL src2 m1))));
1452   format %{ "vand_notL_vx $dst, $src1, $src2" %}
1453   ins_encode %{
1454     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1455     __ vandn_vx(as_VectorRegister($dst$$reg),
1456                 as_VectorRegister($src1$$reg),
1457                 as_Register($src2$$reg));
1458   %}
1459   ins_pipe(pipe_slow);
1460 %}
1461 
1462 instruct vand_notB_vx_masked(vReg dst_src1, iRegIorL2I src2, immI_M1 m1, vRegMask_V0 v0) %{
1463   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_BYTE);
1464   match(Set dst_src1 (AndV (Binary dst_src1 (Replicate (XorI src2 m1))) v0));
1465   format %{ "vand_notB_vx_masked $dst_src1, $dst_src1, $src2, $v0" %}
1466   ins_encode %{
1467     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
1468     __ vandn_vx(as_VectorRegister($dst_src1$$reg),
1469                 as_VectorRegister($dst_src1$$reg),
1470                 as_Register($src2$$reg),
1471                 Assembler::v0_t);
1472   %}
1473   ins_pipe(pipe_slow);
1474 %}
1475 
1476 instruct vand_notS_vx_masked(vReg dst_src1, iRegIorL2I src2, immI_M1 m1, vRegMask_V0 v0) %{
1477   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_SHORT);
1478   match(Set dst_src1 (AndV (Binary dst_src1 (Replicate (XorI src2 m1))) v0));
1479   format %{ "vand_notS_vx_masked $dst_src1, $dst_src1, $src2, $v0" %}
1480   ins_encode %{
1481     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
1482     __ vandn_vx(as_VectorRegister($dst_src1$$reg),
1483                 as_VectorRegister($dst_src1$$reg),
1484                 as_Register($src2$$reg),
1485                 Assembler::v0_t);
1486   %}
1487   ins_pipe(pipe_slow);
1488 %}
1489 
1490 instruct vand_notI_vx_masked(vReg dst_src1, iRegIorL2I src2, immI_M1 m1, vRegMask_V0 v0) %{
1491   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_INT);
1492   match(Set dst_src1 (AndV (Binary dst_src1 (Replicate (XorI src2 m1))) v0));
1493   format %{ "vand_notI_vx_masked $dst_src1, $dst_src1, $src2, $v0" %}
1494   ins_encode %{
1495     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
1496     __ vandn_vx(as_VectorRegister($dst_src1$$reg),
1497                 as_VectorRegister($dst_src1$$reg),
1498                 as_Register($src2$$reg),
1499                 Assembler::v0_t);
1500   %}
1501   ins_pipe(pipe_slow);
1502 %}
1503 
1504 instruct vand_notL_vx_masked(vReg dst_src1, iRegL src2, immL_M1 m1, vRegMask_V0 v0) %{
1505   predicate(UseZvbb && Matcher::vector_element_basic_type(n) == T_LONG);
1506   match(Set dst_src1 (AndV (Binary dst_src1 (Replicate (XorL src2 m1))) v0));
1507   format %{ "vand_notL_vx_masked $dst_src1, $dst_src1, $src2, $v0" %}
1508   ins_encode %{
1509     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1510     __ vandn_vx(as_VectorRegister($dst_src1$$reg),
1511                 as_VectorRegister($dst_src1$$reg),
1512                 as_Register($src2$$reg),
1513                 Assembler::v0_t);
1514   %}
1515   ins_pipe(pipe_slow);
1516 %}
1517 
1518 // ------------------------------ Vector not -----------------------------------
1519 
1520 // vector not
1521 
1522 instruct vnot(vReg dst, vReg src, immI_M1 m1) %{
1523   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
1524             Matcher::vector_element_basic_type(n) == T_SHORT ||
1525             Matcher::vector_element_basic_type(n) == T_INT);
1526   match(Set dst (XorV src (Replicate m1)));
1527   format %{ "vnot $dst, $src" %}
1528   ins_encode %{
1529     BasicType bt = Matcher::vector_element_basic_type(this);
1530     __ vsetvli_helper(bt, Matcher::vector_length(this));
1531     __ vxor_vi(as_VectorRegister($dst$$reg),
1532                as_VectorRegister($src$$reg),
1533                -1);
1534   %}
1535   ins_pipe(pipe_slow);
1536 %}
1537 
1538 instruct vnotL(vReg dst, vReg src, immL_M1 m1) %{
1539   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
1540   match(Set dst (XorV src (Replicate m1)));
1541   format %{ "vnotL $dst, $src" %}
1542   ins_encode %{
1543     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1544     __ vxor_vi(as_VectorRegister($dst$$reg),
1545                as_VectorRegister($src$$reg),
1546                -1);
1547   %}
1548   ins_pipe(pipe_slow);
1549 %}
1550 
1551 // vector not - predicated
1552 
1553 instruct vnot_masked(vReg dst_src, immI_M1 m1, vRegMask_V0 v0) %{
1554   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
1555             Matcher::vector_element_basic_type(n) == T_SHORT ||
1556             Matcher::vector_element_basic_type(n) == T_INT);
1557   match(Set dst_src (XorV (Binary dst_src (Replicate m1)) v0));
1558   format %{ "vnot_masked $dst_src, $dst_src, $v0" %}
1559   ins_encode %{
1560     BasicType bt = Matcher::vector_element_basic_type(this);
1561     __ vsetvli_helper(bt, Matcher::vector_length(this));
1562     __ vxor_vi(as_VectorRegister($dst_src$$reg),
1563                as_VectorRegister($dst_src$$reg),
1564                -1, Assembler::v0_t);
1565   %}
1566   ins_pipe(pipe_slow);
1567 %}
1568 
1569 instruct vnotL_masked(vReg dst_src, immI_M1 m1, vRegMask_V0 v0) %{
1570   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
1571   match(Set dst_src (XorV (Binary dst_src (Replicate m1)) v0));
1572   format %{ "vnotL_masked $dst_src, $dst_src, $v0" %}
1573   ins_encode %{
1574     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
1575     __ vxor_vi(as_VectorRegister($dst_src$$reg),
1576                as_VectorRegister($dst_src$$reg),
1577                -1, Assembler::v0_t);
1578   %}
1579   ins_pipe(pipe_slow);
1580 %}
1581 
1582 // vector float div
1583 
1584 instruct vdiv_hfp(vReg dst, vReg src1, vReg src2) %{
1585   match(Set dst (DivVHF src1 src2));
1586   format %{ "vdiv_hfp $dst, $src1, $src2" %}
1587   ins_encode %{
1588     assert(UseZvfh, "must");
1589     assert(Matcher::vector_element_basic_type(this) == T_SHORT, "must");
1590     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
1591     __ vfdiv_vv(as_VectorRegister($dst$$reg),
1592                 as_VectorRegister($src1$$reg),
1593                 as_VectorRegister($src2$$reg));
1594   %}
1595   ins_pipe(pipe_slow);
1596 %}
1597 
1598 instruct vdiv_fp(vReg dst, vReg src1, vReg src2) %{
1599   match(Set dst (DivVF src1 src2));
1600   match(Set dst (DivVD src1 src2));
1601   format %{ "vdiv_fp $dst, $src1, $src2" %}
1602   ins_encode %{
1603     BasicType bt = Matcher::vector_element_basic_type(this);
1604     __ vsetvli_helper(bt, Matcher::vector_length(this));
1605     __ vfdiv_vv(as_VectorRegister($dst$$reg),
1606                 as_VectorRegister($src1$$reg),
1607                 as_VectorRegister($src2$$reg));
1608   %}
1609   ins_pipe(pipe_slow);
1610 %}
1611 
1612 // vector float div - predicated
1613 
1614 instruct vdiv_fp_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
1615   match(Set dst_src1 (DivVF (Binary dst_src1 src2) v0));
1616   match(Set dst_src1 (DivVD (Binary dst_src1 src2) v0));
1617   format %{ "vdiv_fp_masked $dst_src1, $dst_src1, $src2, $v0" %}
1618   ins_encode %{
1619     BasicType bt = Matcher::vector_element_basic_type(this);
1620     __ vsetvli_helper(bt, Matcher::vector_length(this));
1621     __ vfdiv_vv(as_VectorRegister($dst_src1$$reg),
1622                 as_VectorRegister($dst_src1$$reg),
1623                 as_VectorRegister($src2$$reg), Assembler::v0_t);
1624   %}
1625   ins_pipe(pipe_slow);
1626 %}
1627 
1628 // vector integer max/min
1629 
1630 instruct vmax(vReg dst, vReg src1, vReg src2) %{
1631   predicate(Matcher::vector_element_basic_type(n) != T_FLOAT &&
1632             Matcher::vector_element_basic_type(n) != T_DOUBLE);
1633   match(Set dst (MaxV src1 src2));
1634   format %{ "vmax $dst, $src1, $src2" %}
1635   ins_encode %{
1636     BasicType bt = Matcher::vector_element_basic_type(this);
1637     __ vsetvli_helper(bt, Matcher::vector_length(this));
1638     __ vmax_vv(as_VectorRegister($dst$$reg),
1639                as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
1640   %}
1641   ins_pipe(pipe_slow);
1642 %}
1643 
1644 instruct vmin(vReg dst, vReg src1, vReg src2) %{
1645   predicate(Matcher::vector_element_basic_type(n) != T_FLOAT &&
1646             Matcher::vector_element_basic_type(n) != T_DOUBLE);
1647   match(Set dst (MinV src1 src2));
1648   format %{ "vmin $dst, $src1, $src2" %}
1649   ins_encode %{
1650     BasicType bt = Matcher::vector_element_basic_type(this);
1651     __ vsetvli_helper(bt, Matcher::vector_length(this));
1652     __ vmin_vv(as_VectorRegister($dst$$reg),
1653                as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
1654   %}
1655   ins_pipe(pipe_slow);
1656 %}
1657 
1658 // vector integer max/min - predicated
1659 
1660 instruct vmax_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
1661   predicate(Matcher::vector_element_basic_type(n) != T_FLOAT &&
1662             Matcher::vector_element_basic_type(n) != T_DOUBLE);
1663   match(Set dst_src1 (MaxV (Binary dst_src1 src2) v0));
1664   format %{ "vmax_masked $dst_src1, $dst_src1, $src2, $v0" %}
1665   ins_encode %{
1666     BasicType bt = Matcher::vector_element_basic_type(this);
1667     __ vsetvli_helper(bt, Matcher::vector_length(this));
1668     __ vmax_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg),
1669                as_VectorRegister($src2$$reg), Assembler::v0_t);
1670   %}
1671   ins_pipe(pipe_slow);
1672 %}
1673 
1674 instruct vmin_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
1675   predicate(Matcher::vector_element_basic_type(n) != T_FLOAT &&
1676             Matcher::vector_element_basic_type(n) != T_DOUBLE);
1677   match(Set dst_src1 (MinV (Binary dst_src1 src2) v0));
1678   format %{ "vmin_masked $dst_src1, $dst_src1, $src2, $v0" %}
1679   ins_encode %{
1680     BasicType bt = Matcher::vector_element_basic_type(this);
1681     __ vsetvli_helper(bt, Matcher::vector_length(this));
1682     __ vmin_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg),
1683                as_VectorRegister($src2$$reg), Assembler::v0_t);
1684   %}
1685   ins_pipe(pipe_slow);
1686 %}
1687 
1688 // vector unsigned integer max/min
1689 
1690 instruct vmaxu(vReg dst, vReg src1, vReg src2) %{
1691   match(Set dst (UMaxV src1 src2));
1692   format %{ "vmaxu $dst, $src1, $src2" %}
1693   ins_encode %{
1694     BasicType bt = Matcher::vector_element_basic_type(this);
1695     assert(is_integral_type(bt), "unsupported type");
1696     __ vsetvli_helper(bt, Matcher::vector_length(this));
1697     __ vmaxu_vv(as_VectorRegister($dst$$reg),
1698                 as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
1699   %}
1700   ins_pipe(pipe_slow);
1701 %}
1702 
1703 instruct vminu(vReg dst, vReg src1, vReg src2) %{
1704   match(Set dst (UMinV src1 src2));
1705   format %{ "vminu $dst, $src1, $src2" %}
1706   ins_encode %{
1707     BasicType bt = Matcher::vector_element_basic_type(this);
1708     assert(is_integral_type(bt), "unsupported type");
1709     __ vsetvli_helper(bt, Matcher::vector_length(this));
1710     __ vminu_vv(as_VectorRegister($dst$$reg),
1711                 as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg));
1712   %}
1713   ins_pipe(pipe_slow);
1714 %}
1715 
1716 // vector unsigned integer max/min - predicated
1717 
1718 instruct vmaxu_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
1719   match(Set dst_src1 (UMaxV (Binary dst_src1 src2) v0));
1720   format %{ "vmaxu_masked $dst_src1, $dst_src1, $src2, $v0" %}
1721   ins_encode %{
1722     BasicType bt = Matcher::vector_element_basic_type(this);
1723     assert(is_integral_type(bt), "unsupported type");
1724     __ vsetvli_helper(bt, Matcher::vector_length(this));
1725     __ vmaxu_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg),
1726                 as_VectorRegister($src2$$reg), Assembler::v0_t);
1727   %}
1728   ins_pipe(pipe_slow);
1729 %}
1730 
1731 instruct vminu_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
1732   match(Set dst_src1 (UMinV (Binary dst_src1 src2) v0));
1733   format %{ "vminu_masked $dst_src1, $dst_src1, $src2, $v0" %}
1734   ins_encode %{
1735     BasicType bt = Matcher::vector_element_basic_type(this);
1736     assert(is_integral_type(bt), "unsupported type");
1737     __ vsetvli_helper(bt, Matcher::vector_length(this));
1738     __ vminu_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg),
1739                 as_VectorRegister($src2$$reg), Assembler::v0_t);
1740   %}
1741   ins_pipe(pipe_slow);
1742 %}
1743 
1744 // vector float-point max/min (half precision)
1745 
1746 instruct vmax_hfp(vReg dst, vReg src1, vReg src2, vRegMask_V0 v0) %{
1747   match(Set dst (MaxVHF src1 src2));
1748   effect(TEMP_DEF dst, TEMP v0);
1749   format %{ "vmax_hfp $dst, $src1, $src2" %}
1750   ins_encode %{
1751     assert(UseZvfh, "must");
1752     assert(Matcher::vector_element_basic_type(this) == T_SHORT, "must");
1753     __ minmax_fp_v(as_VectorRegister($dst$$reg),
1754                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
1755                    T_SHORT, false /* is_min */, Matcher::vector_length(this));
1756   %}
1757   ins_pipe(pipe_slow);
1758 %}
1759 
1760 instruct vmin_hfp(vReg dst, vReg src1, vReg src2, vRegMask_V0 v0) %{
1761   match(Set dst (MinVHF src1 src2));
1762   effect(TEMP_DEF dst, TEMP v0);
1763   format %{ "vmin_hfp $dst, $src1, $src2" %}
1764   ins_encode %{
1765     assert(UseZvfh, "must");
1766     assert(Matcher::vector_element_basic_type(this) == T_SHORT, "must");
1767     __ minmax_fp_v(as_VectorRegister($dst$$reg),
1768                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
1769                    T_SHORT, true /* is_min */, Matcher::vector_length(this));
1770   %}
1771   ins_pipe(pipe_slow);
1772 %}
1773 
1774 // vector float-point max/min
1775 
1776 instruct vmax_fp(vReg dst, vReg src1, vReg src2, vRegMask_V0 v0) %{
1777   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT ||
1778             Matcher::vector_element_basic_type(n) == T_DOUBLE);
1779   match(Set dst (MaxV src1 src2));
1780   effect(TEMP_DEF dst, TEMP v0);
1781   format %{ "vmax_fp $dst, $src1, $src2" %}
1782   ins_encode %{
1783     BasicType bt = Matcher::vector_element_basic_type(this);
1784     __ minmax_fp_v(as_VectorRegister($dst$$reg),
1785                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
1786                    bt, false /* is_min */, Matcher::vector_length(this));
1787   %}
1788   ins_pipe(pipe_slow);
1789 %}
1790 
1791 instruct vmin_fp(vReg dst, vReg src1, vReg src2, vRegMask_V0 v0) %{
1792   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT ||
1793             Matcher::vector_element_basic_type(n) == T_DOUBLE);
1794   match(Set dst (MinV src1 src2));
1795   effect(TEMP_DEF dst, TEMP v0);
1796   format %{ "vmin_fp $dst, $src1, $src2" %}
1797   ins_encode %{
1798     BasicType bt = Matcher::vector_element_basic_type(this);
1799     __ minmax_fp_v(as_VectorRegister($dst$$reg),
1800                    as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg),
1801                    bt, true /* is_min */, Matcher::vector_length(this));
1802   %}
1803   ins_pipe(pipe_slow);
1804 %}
1805 
1806 // vector float-point max/min - predicated
1807 
1808 instruct vmax_fp_masked(vReg dst_src1, vReg src2, vRegMask vmask, vReg tmp1, vReg tmp2, vRegMask_V0 v0) %{
1809   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT ||
1810             Matcher::vector_element_basic_type(n) == T_DOUBLE);
1811   match(Set dst_src1 (MaxV (Binary dst_src1 src2) vmask));
1812   effect(TEMP_DEF dst_src1, TEMP tmp1, TEMP tmp2, TEMP v0);
1813   format %{ "vmax_fp_masked $dst_src1, $dst_src1, $src2, $vmask\t# KILL $tmp1, $tmp2, $v0" %}
1814   ins_encode %{
1815     BasicType bt = Matcher::vector_element_basic_type(this);
1816     __ minmax_fp_masked_v(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg),
1817                           as_VectorRegister($src2$$reg), as_VectorRegister($vmask$$reg),
1818                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
1819                           bt, false /* is_min */, Matcher::vector_length(this));
1820   %}
1821   ins_pipe(pipe_slow);
1822 %}
1823 
1824 instruct vmin_fp_masked(vReg dst_src1, vReg src2, vRegMask vmask, vReg tmp1, vReg tmp2, vRegMask_V0 v0) %{
1825   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT ||
1826             Matcher::vector_element_basic_type(n) == T_DOUBLE);
1827   match(Set dst_src1 (MinV (Binary dst_src1 src2) vmask));
1828   effect(TEMP_DEF dst_src1, TEMP tmp1, TEMP tmp2, TEMP v0);
1829   format %{ "vmin_fp_masked $dst_src1, $dst_src1, $src2, $vmask\t# KILL $tmp1, $tmp2, $v0" %}
1830   ins_encode %{
1831     BasicType bt = Matcher::vector_element_basic_type(this);
1832     __ minmax_fp_masked_v(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg),
1833                           as_VectorRegister($src2$$reg), as_VectorRegister($vmask$$reg),
1834                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
1835                           bt, true /* is_min */, Matcher::vector_length(this));
1836   %}
1837   ins_pipe(pipe_slow);
1838 %}
1839 
1840 // vector fmla
1841 
1842 // dst_src1 = src2 * src3 + dst_src1 (half precision)
1843 instruct vhfmla(vReg dst_src1, vReg src2, vReg src3) %{
1844   match(Set dst_src1 (FmaVHF dst_src1 (Binary src2 src3)));
1845   format %{ "vhfmla $dst_src1, $dst_src1, $src2, $src3" %}
1846   ins_encode %{
1847     assert(UseFMA, "Needs FMA instructions support.");
1848     assert(UseZvfh, "must");
1849     assert(Matcher::vector_element_basic_type(this) == T_SHORT, "must");
1850     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
1851     __ vfmacc_vv(as_VectorRegister($dst_src1$$reg),
1852                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
1853   %}
1854   ins_pipe(pipe_slow);
1855 %}
1856 
1857 // dst_src1 = src2 * src3 + dst_src1
1858 instruct vfmla(vReg dst_src1, vReg src2, vReg src3) %{
1859   match(Set dst_src1 (FmaVF dst_src1 (Binary src2 src3)));
1860   match(Set dst_src1 (FmaVD dst_src1 (Binary src2 src3)));
1861   format %{ "vfmla $dst_src1, $dst_src1, $src2, $src3" %}
1862   ins_encode %{
1863     assert(UseFMA, "Needs FMA instructions support.");
1864     BasicType bt = Matcher::vector_element_basic_type(this);
1865     __ vsetvli_helper(bt, Matcher::vector_length(this));
1866     __ vfmacc_vv(as_VectorRegister($dst_src1$$reg),
1867                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
1868   %}
1869   ins_pipe(pipe_slow);
1870 %}
1871 
1872 // vector fmadd - predicated
1873 // dst_src1 = dst_src1 * src2 + src3
1874 
1875 instruct vfmadd_masked(vReg dst_src1, vReg src2, vReg src3, vRegMask_V0 v0) %{
1876   match(Set dst_src1 (FmaVF (Binary dst_src1 src2) (Binary src3 v0)));
1877   match(Set dst_src1 (FmaVD (Binary dst_src1 src2) (Binary src3 v0)));
1878   format %{ "vfmadd_masked $dst_src1, $dst_src1, $src2, $src3, $v0" %}
1879   ins_encode %{
1880     assert(UseFMA, "Needs FMA instructions support.");
1881     BasicType bt = Matcher::vector_element_basic_type(this);
1882     __ vsetvli_helper(bt, Matcher::vector_length(this));
1883     __ vfmadd_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($src2$$reg),
1884                  as_VectorRegister($src3$$reg), Assembler::v0_t);
1885   %}
1886   ins_pipe(pipe_slow);
1887 %}
1888 
1889 // vector fmls
1890 
1891 // dst_src1 = src2 * (-src3) + dst_src1
1892 // "(-src2) * src3 + dst_src1" has been idealized to "src3 * (-src2) + dst_src1"
1893 instruct vfmlsF(vReg dst_src1, vReg src2, vReg src3) %{
1894   match(Set dst_src1 (FmaVF dst_src1 (Binary src2 (NegVF src3))));
1895   format %{ "vfmlsF $dst_src1, $dst_src1, $src2, $src3" %}
1896   ins_encode %{
1897     assert(UseFMA, "Needs FMA instructions support.");
1898     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this));
1899     __ vfnmsac_vv(as_VectorRegister($dst_src1$$reg),
1900                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
1901   %}
1902   ins_pipe(pipe_slow);
1903 %}
1904 
1905 // dst_src1 = src2 * (-src3) + dst_src1
1906 // "(-src2) * src3 + dst_src1" has been idealized to "src3 * (-src2) + dst_src1"
1907 instruct vfmlsD(vReg dst_src1, vReg src2, vReg src3) %{
1908   match(Set dst_src1 (FmaVD dst_src1 (Binary src2 (NegVD src3))));
1909   format %{ "vfmlsD $dst_src1, $dst_src1, $src2, $src3" %}
1910   ins_encode %{
1911     assert(UseFMA, "Needs FMA instructions support.");
1912     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this));
1913     __ vfnmsac_vv(as_VectorRegister($dst_src1$$reg),
1914                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
1915   %}
1916   ins_pipe(pipe_slow);
1917 %}
1918 
1919 // vector fnmsub - predicated
1920 
1921 // dst_src1 = dst_src1 * (-src2) + src3
1922 instruct vfnmsub_masked(vReg dst_src1, vReg src2, vReg src3, vRegMask_V0 v0) %{
1923   match(Set dst_src1 (FmaVF (Binary dst_src1 (NegVF src2)) (Binary src3 v0)));
1924   match(Set dst_src1 (FmaVD (Binary dst_src1 (NegVD src2)) (Binary src3 v0)));
1925   format %{ "vfnmsub_masked $dst_src1, $dst_src1, $src2, $src3, $v0" %}
1926   ins_encode %{
1927     assert(UseFMA, "Needs FMA instructions support.");
1928     BasicType bt = Matcher::vector_element_basic_type(this);
1929     __ vsetvli_helper(bt, Matcher::vector_length(this));
1930     __ vfnmsub_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($src2$$reg),
1931                   as_VectorRegister($src3$$reg), Assembler::v0_t);
1932   %}
1933   ins_pipe(pipe_slow);
1934 %}
1935 
1936 // vector fnmla
1937 
1938 // dst_src1 = src2 * (-src3) - dst_src1
1939 // "(-src2) * src3 - dst_src1" has been idealized to "src3 * (-src2) - dst_src1"
1940 instruct vfnmlaF(vReg dst_src1, vReg src2, vReg src3) %{
1941   match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 (NegVF src3))));
1942   format %{ "vfnmlaF $dst_src1, $dst_src1, $src2, $src3" %}
1943   ins_encode %{
1944     assert(UseFMA, "Needs FMA instructions support.");
1945     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this));
1946     __ vfnmacc_vv(as_VectorRegister($dst_src1$$reg),
1947                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
1948   %}
1949   ins_pipe(pipe_slow);
1950 %}
1951 
1952 // dst_src1 = src2 * (-src3) - dst_src1
1953 // "(-src2) * src3 - dst_src1" has been idealized to "src3 * (-src2) - dst_src1"
1954 instruct vfnmlaD(vReg dst_src1, vReg src2, vReg src3) %{
1955   match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 (NegVD src3))));
1956   format %{ "vfnmlaD $dst_src1, $dst_src1, $src2, $src3" %}
1957   ins_encode %{
1958     assert(UseFMA, "Needs FMA instructions support.");
1959     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this));
1960     __ vfnmacc_vv(as_VectorRegister($dst_src1$$reg),
1961                   as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
1962   %}
1963   ins_pipe(pipe_slow);
1964 %}
1965 
1966 // vector fnmadd - predicated
1967 
1968 // dst_src1 = dst_src1 * (-src2) - src3
1969 instruct vfnmadd_masked(vReg dst_src1, vReg src2, vReg src3, vRegMask_V0 v0) %{
1970   match(Set dst_src1 (FmaVF (Binary dst_src1 (NegVF src2)) (Binary (NegVF src3) v0)));
1971   match(Set dst_src1 (FmaVD (Binary dst_src1 (NegVD src2)) (Binary (NegVD src3) v0)));
1972   format %{ "vfnmadd_masked $dst_src1, $dst_src1, $src2, $src3, $v0" %}
1973   ins_encode %{
1974     assert(UseFMA, "Needs FMA instructions support.");
1975     BasicType bt = Matcher::vector_element_basic_type(this);
1976     __ vsetvli_helper(bt, Matcher::vector_length(this));
1977     __ vfnmadd_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($src2$$reg),
1978                   as_VectorRegister($src3$$reg), Assembler::v0_t);
1979   %}
1980   ins_pipe(pipe_slow);
1981 %}
1982 
1983 // vector fnmls
1984 
1985 // dst_src1 = src2 * src3 - dst_src1
1986 instruct vfnmlsF(vReg dst_src1, vReg src2, vReg src3) %{
1987   match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 src3)));
1988   format %{ "vfnmlsF $dst_src1, $dst_src1, $src2, $src3" %}
1989   ins_encode %{
1990     assert(UseFMA, "Needs FMA instructions support.");
1991     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this));
1992     __ vfmsac_vv(as_VectorRegister($dst_src1$$reg),
1993                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
1994   %}
1995   ins_pipe(pipe_slow);
1996 %}
1997 
1998 // dst_src1 = -dst_src1 + src2 * src3
1999 instruct vfnmlsD(vReg dst_src1, vReg src2, vReg src3) %{
2000   match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 src3)));
2001   format %{ "vfnmlsD $dst_src1, $dst_src1, $src2, $src3" %}
2002   ins_encode %{
2003     assert(UseFMA, "Needs FMA instructions support.");
2004     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this));
2005     __ vfmsac_vv(as_VectorRegister($dst_src1$$reg),
2006                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
2007   %}
2008   ins_pipe(pipe_slow);
2009 %}
2010 
2011 // vector vfmsub - predicated
2012 
2013 // dst_src1 = dst_src1 * src2 - src3
2014 instruct vfmsub_masked(vReg dst_src1, vReg src2, vReg src3, vRegMask_V0 v0) %{
2015   match(Set dst_src1 (FmaVF (Binary dst_src1 src2) (Binary (NegVF src3) v0)));
2016   match(Set dst_src1 (FmaVD (Binary dst_src1 src2) (Binary (NegVD src3) v0)));
2017   format %{ "vfmsub_masked $dst_src1, $dst_src1, $src2, $src3, $v0" %}
2018   ins_encode %{
2019     assert(UseFMA, "Needs FMA instructions support.");
2020     BasicType bt = Matcher::vector_element_basic_type(this);
2021     __ vsetvli_helper(bt, Matcher::vector_length(this));
2022     __ vfmsub_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($src2$$reg),
2023                  as_VectorRegister($src3$$reg), Assembler::v0_t);
2024   %}
2025   ins_pipe(pipe_slow);
2026 %}
2027 
2028 // vector mla
2029 
2030 // dst_src1 = dst_src1 + src2 * src3
2031 instruct vmla(vReg dst_src1, vReg src2, vReg src3) %{
2032   match(Set dst_src1 (AddVB dst_src1 (MulVB src2 src3)));
2033   match(Set dst_src1 (AddVS dst_src1 (MulVS src2 src3)));
2034   match(Set dst_src1 (AddVI dst_src1 (MulVI src2 src3)));
2035   match(Set dst_src1 (AddVL dst_src1 (MulVL src2 src3)));
2036   format %{ "vmla $dst_src1, $dst_src1, $src2, $src3" %}
2037   ins_encode %{
2038     BasicType bt = Matcher::vector_element_basic_type(this);
2039     __ vsetvli_helper(bt, Matcher::vector_length(this));
2040     __ vmacc_vv(as_VectorRegister($dst_src1$$reg),
2041                 as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
2042   %}
2043   ins_pipe(pipe_slow);
2044 %}
2045 
2046 // vector mla - predicated
2047 
2048 instruct vmla_masked(vReg dst_src1, vReg src2, vReg src3, vRegMask_V0 v0) %{
2049   match(Set dst_src1 (AddVB (Binary dst_src1 (MulVB src2 src3)) v0));
2050   match(Set dst_src1 (AddVS (Binary dst_src1 (MulVS src2 src3)) v0));
2051   match(Set dst_src1 (AddVI (Binary dst_src1 (MulVI src2 src3)) v0));
2052   match(Set dst_src1 (AddVL (Binary dst_src1 (MulVL src2 src3)) v0));
2053   format %{ "vmla_masked $dst_src1, $dst_src1, $src2, $src3, $v0" %}
2054   ins_encode %{
2055     BasicType bt = Matcher::vector_element_basic_type(this);
2056     __ vsetvli_helper(bt, Matcher::vector_length(this));
2057     __ vmacc_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($src2$$reg),
2058                 as_VectorRegister($src3$$reg), Assembler::v0_t);
2059   %}
2060   ins_pipe(pipe_slow);
2061 %}
2062 
2063 // vector mls
2064 
2065 // dst_src1 = dst_src1 - src2 * src3
2066 instruct vmls(vReg dst_src1, vReg src2, vReg src3) %{
2067   match(Set dst_src1 (SubVB dst_src1 (MulVB src2 src3)));
2068   match(Set dst_src1 (SubVS dst_src1 (MulVS src2 src3)));
2069   match(Set dst_src1 (SubVI dst_src1 (MulVI src2 src3)));
2070   match(Set dst_src1 (SubVL dst_src1 (MulVL src2 src3)));
2071   format %{ "vmls $dst_src1, $dst_src1, $src2, $src3" %}
2072   ins_encode %{
2073     BasicType bt = Matcher::vector_element_basic_type(this);
2074     __ vsetvli_helper(bt, Matcher::vector_length(this));
2075     __ vnmsac_vv(as_VectorRegister($dst_src1$$reg),
2076                  as_VectorRegister($src2$$reg), as_VectorRegister($src3$$reg));
2077   %}
2078   ins_pipe(pipe_slow);
2079 %}
2080 
2081 // vector mls - predicated
2082 
2083 instruct vmls_masked(vReg dst_src1, vReg src2, vReg src3, vRegMask_V0 v0) %{
2084   match(Set dst_src1 (SubVB (Binary dst_src1 (MulVB src2 src3)) v0));
2085   match(Set dst_src1 (SubVS (Binary dst_src1 (MulVS src2 src3)) v0));
2086   match(Set dst_src1 (SubVI (Binary dst_src1 (MulVI src2 src3)) v0));
2087   match(Set dst_src1 (SubVL (Binary dst_src1 (MulVL src2 src3)) v0));
2088   format %{ "vmls_masked $dst_src1, $dst_src1, $src2, $src3, $v0" %}
2089   ins_encode %{
2090     BasicType bt = Matcher::vector_element_basic_type(this);
2091     __ vsetvli_helper(bt, Matcher::vector_length(this));
2092     __ vnmsac_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($src2$$reg),
2093                  as_VectorRegister($src3$$reg), Assembler::v0_t);
2094   %}
2095   ins_pipe(pipe_slow);
2096 %}
2097 
2098 // vector mul
2099 
2100 instruct vmul(vReg dst, vReg src1, vReg src2) %{
2101   match(Set dst (MulVB src1 src2));
2102   match(Set dst (MulVS src1 src2));
2103   match(Set dst (MulVI src1 src2));
2104   match(Set dst (MulVL src1 src2));
2105   format %{ "vmul $dst, $src1, $src2" %}
2106   ins_encode %{
2107     BasicType bt = Matcher::vector_element_basic_type(this);
2108     __ vsetvli_helper(bt, Matcher::vector_length(this));
2109     __ vmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
2110                as_VectorRegister($src2$$reg));
2111   %}
2112   ins_pipe(pipe_slow);
2113 %}
2114 
2115 instruct vmul_hfp(vReg dst, vReg src1, vReg src2) %{
2116   match(Set dst (MulVHF src1 src2));
2117   format %{ "vmul_hfp $dst, $src1, $src2" %}
2118   ins_encode %{
2119     assert(UseZvfh, "must");
2120     assert(Matcher::vector_element_basic_type(this) == T_SHORT, "must");
2121     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
2122     __ vfmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
2123                 as_VectorRegister($src2$$reg));
2124   %}
2125   ins_pipe(pipe_slow);
2126 %}
2127 
2128 instruct vmul_fp(vReg dst, vReg src1, vReg src2) %{
2129   match(Set dst (MulVF src1 src2));
2130   match(Set dst (MulVD src1 src2));
2131   format %{ "vmul_fp $dst, $src1, $src2" %}
2132   ins_encode %{
2133     BasicType bt = Matcher::vector_element_basic_type(this);
2134     __ vsetvli_helper(bt, Matcher::vector_length(this));
2135     __ vfmul_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
2136                 as_VectorRegister($src2$$reg));
2137   %}
2138   ins_pipe(pipe_slow);
2139 %}
2140 
2141 // vector mul - predicated
2142 
2143 instruct vmul_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
2144   match(Set dst_src1 (MulVB (Binary dst_src1 src2) v0));
2145   match(Set dst_src1 (MulVS (Binary dst_src1 src2) v0));
2146   match(Set dst_src1 (MulVI (Binary dst_src1 src2) v0));
2147   match(Set dst_src1 (MulVL (Binary dst_src1 src2) v0));
2148   format %{ "vmul_masked $dst_src1, $dst_src1, $src2, $v0" %}
2149   ins_encode %{
2150     BasicType bt = Matcher::vector_element_basic_type(this);
2151     __ vsetvli_helper(bt, Matcher::vector_length(this));
2152     __ vmul_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg),
2153                as_VectorRegister($src2$$reg), Assembler::v0_t);
2154   %}
2155   ins_pipe(pipe_slow);
2156 %}
2157 
2158 instruct vmul_fp_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{
2159   match(Set dst_src1 (MulVF (Binary dst_src1 src2) v0));
2160   match(Set dst_src1 (MulVD (Binary dst_src1 src2) v0));
2161   format %{ "vmul_fp_masked $dst_src1, $dst_src1, $src2, $v0" %}
2162   ins_encode %{
2163     BasicType bt = Matcher::vector_element_basic_type(this);
2164     __ vsetvli_helper(bt, Matcher::vector_length(this));
2165     __ vfmul_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg),
2166                 as_VectorRegister($src2$$reg), Assembler::v0_t);
2167   %}
2168   ins_pipe(pipe_slow);
2169 %}
2170 
2171 // vector-scalar mul (unpredicated)
2172 
2173 instruct vmul_vx(vReg dst, vReg src1, iRegIorL2I src2) %{
2174   match(Set dst (MulVB src1 (Replicate src2)));
2175   match(Set dst (MulVS src1 (Replicate src2)));
2176   match(Set dst (MulVI src1 (Replicate src2)));
2177   format %{ "vmul_vx $dst, $src1, $src2" %}
2178   ins_encode %{
2179     BasicType bt = Matcher::vector_element_basic_type(this);
2180     __ vsetvli_helper(bt, Matcher::vector_length(this));
2181     __ vmul_vx(as_VectorRegister($dst$$reg),
2182                as_VectorRegister($src1$$reg),
2183                as_Register($src2$$reg));
2184   %}
2185   ins_pipe(pipe_slow);
2186 %}
2187 
2188 instruct vmulL_vx(vReg dst, vReg src1, iRegL src2) %{
2189   match(Set dst (MulVL src1 (Replicate src2)));
2190   format %{ "vmulL_vx $dst, $src1, $src2" %}
2191   ins_encode %{
2192     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
2193     __ vmul_vx(as_VectorRegister($dst$$reg),
2194                as_VectorRegister($src1$$reg),
2195                as_Register($src2$$reg));
2196   %}
2197   ins_pipe(pipe_slow);
2198 %}
2199 
2200 // vector-scalar mul (predicated)
2201 
2202 instruct vmul_vx_masked(vReg dst_src, iRegIorL2I src2, vRegMask_V0 v0) %{
2203   match(Set dst_src (MulVB (Binary dst_src (Replicate src2)) v0));
2204   match(Set dst_src (MulVS (Binary dst_src (Replicate src2)) v0));
2205   match(Set dst_src (MulVI (Binary dst_src (Replicate src2)) v0));
2206   format %{ "vmul_vx_masked $dst_src, $dst_src, $src2, $v0" %}
2207   ins_encode %{
2208     BasicType bt = Matcher::vector_element_basic_type(this);
2209     __ vsetvli_helper(bt, Matcher::vector_length(this));
2210     __ vmul_vx(as_VectorRegister($dst_src$$reg),
2211                as_VectorRegister($dst_src$$reg),
2212                as_Register($src2$$reg), Assembler::v0_t);
2213   %}
2214   ins_pipe(pipe_slow);
2215 %}
2216 
2217 instruct vmulL_vx_masked(vReg dst_src, iRegL src2, vRegMask_V0 v0) %{
2218   match(Set dst_src (MulVL (Binary dst_src (Replicate src2)) v0));
2219   format %{ "vmulL_vx_masked $dst_src, $dst_src, $src2, $v0" %}
2220   ins_encode %{
2221     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
2222     __ vmul_vx(as_VectorRegister($dst_src$$reg),
2223                as_VectorRegister($dst_src$$reg),
2224                as_Register($src2$$reg), Assembler::v0_t);
2225   %}
2226   ins_pipe(pipe_slow);
2227 %}
2228 
2229 // vector neg
2230 
2231 instruct vneg(vReg dst, vReg src) %{
2232   match(Set dst (NegVI src));
2233   match(Set dst (NegVL src));
2234   format %{ "vneg $dst, $src" %}
2235   ins_encode %{
2236     BasicType bt = Matcher::vector_element_basic_type(this);
2237     __ vsetvli_helper(bt, Matcher::vector_length(this));
2238     __ vneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
2239   %}
2240   ins_pipe(pipe_slow);
2241 %}
2242 
2243 // vector neg - predicated
2244 
2245 instruct vneg_masked(vReg dst_src, vRegMask_V0 v0) %{
2246   match(Set dst_src (NegVI dst_src v0));
2247   match(Set dst_src (NegVL dst_src v0));
2248   format %{ "vneg_masked $dst_src, $dst_src, $v0" %}
2249   ins_encode %{
2250     BasicType bt = Matcher::vector_element_basic_type(this);
2251     __ vsetvli_helper(bt, Matcher::vector_length(this));
2252     __ vneg_v(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
2253               Assembler::v0_t);
2254   %}
2255   ins_pipe(pipe_slow);
2256 %}
2257 
2258 // vector fneg
2259 
2260 instruct vfneg(vReg dst, vReg src) %{
2261   match(Set dst (NegVF src));
2262   match(Set dst (NegVD src));
2263   format %{ "vfneg $dst, $src" %}
2264   ins_encode %{
2265     BasicType bt = Matcher::vector_element_basic_type(this);
2266     __ vsetvli_helper(bt, Matcher::vector_length(this));
2267     __ vfneg_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
2268   %}
2269   ins_pipe(pipe_slow);
2270 %}
2271 
2272 // vector fneg  - predicated
2273 
2274 instruct vfneg_masked(vReg dst_src, vRegMask_V0 v0) %{
2275   match(Set dst_src (NegVF dst_src v0));
2276   match(Set dst_src (NegVD dst_src v0));
2277   format %{ "vfneg_masked $dst_src, $dst_src, $v0" %}
2278   ins_encode %{
2279     BasicType bt = Matcher::vector_element_basic_type(this);
2280     __ vsetvli_helper(bt, Matcher::vector_length(this));
2281     __ vfneg_v(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
2282                Assembler::v0_t);
2283   %}
2284   ins_pipe(pipe_slow);
2285 %}
2286 
2287 // vector and reduction
2288 
2289 instruct reduce_and(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
2290   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2291             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2292             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2293   match(Set dst (AndReductionV src1 src2));
2294   effect(TEMP tmp);
2295   format %{ "reduce_and $dst, $src1, $src2\t# KILL $tmp" %}
2296   ins_encode %{
2297     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2298     __ reduce_integral_v($dst$$Register, $src1$$Register,
2299                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2300                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2301   %}
2302   ins_pipe(pipe_slow);
2303 %}
2304 
2305 instruct reduce_andL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
2306   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2307   match(Set dst (AndReductionV src1 src2));
2308   effect(TEMP tmp);
2309   format %{ "reduce_andL $dst, $src1, $src2\t# KILL $tmp" %}
2310   ins_encode %{
2311     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2312     __ reduce_integral_v($dst$$Register, $src1$$Register,
2313                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2314                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2315   %}
2316   ins_pipe(pipe_slow);
2317 %}
2318 
2319 // vector and reduction - predicated
2320 
2321 instruct reduce_and_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2322   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2323             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2324             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2325   match(Set dst (AndReductionV (Binary src1 src2) v0));
2326   effect(TEMP tmp);
2327   format %{ "reduce_and_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2328   ins_encode %{
2329     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2330     __ reduce_integral_v($dst$$Register, $src1$$Register,
2331                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2332                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2333                          Assembler::v0_t);
2334   %}
2335   ins_pipe(pipe_slow);
2336 %}
2337 
2338 instruct reduce_andL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2339   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2340   match(Set dst (AndReductionV (Binary src1 src2) v0));
2341   effect(TEMP tmp);
2342   format %{ "reduce_andL_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2343   ins_encode %{
2344     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2345     __ reduce_integral_v($dst$$Register, $src1$$Register,
2346                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2347                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2348                          Assembler::v0_t);
2349   %}
2350   ins_pipe(pipe_slow);
2351 %}
2352 
2353 // vector or reduction
2354 
2355 instruct reduce_or(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
2356   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2357             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2358             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2359   match(Set dst (OrReductionV src1 src2));
2360   effect(TEMP tmp);
2361   format %{ "reduce_or $dst, $src1, $src2\t# KILL $tmp" %}
2362   ins_encode %{
2363     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2364     __ reduce_integral_v($dst$$Register, $src1$$Register,
2365                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2366                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2367   %}
2368   ins_pipe(pipe_slow);
2369 %}
2370 
2371 instruct reduce_orL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
2372   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2373   match(Set dst (OrReductionV src1 src2));
2374   effect(TEMP tmp);
2375   format %{ "reduce_orL $dst, $src1, $src2\t# KILL $tmp" %}
2376   ins_encode %{
2377     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2378     __ reduce_integral_v($dst$$Register, $src1$$Register,
2379                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2380                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2381   %}
2382   ins_pipe(pipe_slow);
2383 %}
2384 
2385 // vector or reduction - predicated
2386 
2387 instruct reduce_or_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2388   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2389             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2390             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2391   match(Set dst (OrReductionV (Binary src1 src2) v0));
2392   effect(TEMP tmp);
2393   format %{ "reduce_or_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2394   ins_encode %{
2395     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2396     __ reduce_integral_v($dst$$Register, $src1$$Register,
2397                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2398                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2399                          Assembler::v0_t);
2400   %}
2401   ins_pipe(pipe_slow);
2402 %}
2403 
2404 instruct reduce_orL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2405   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2406   match(Set dst (OrReductionV (Binary src1 src2) v0));
2407   effect(TEMP tmp);
2408   format %{ "reduce_orL_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2409   ins_encode %{
2410     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2411     __ reduce_integral_v($dst$$Register, $src1$$Register,
2412                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2413                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2414                          Assembler::v0_t);
2415   %}
2416   ins_pipe(pipe_slow);
2417 %}
2418 
2419 // vector xor reduction
2420 
2421 instruct reduce_xor(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
2422   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2423             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2424             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2425   match(Set dst (XorReductionV src1 src2));
2426   effect(TEMP tmp);
2427   format %{ "reduce_xor $dst, $src1, $src2\t# KILL $tmp" %}
2428   ins_encode %{
2429     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2430     __ reduce_integral_v($dst$$Register, $src1$$Register,
2431                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2432                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2433   %}
2434   ins_pipe(pipe_slow);
2435 %}
2436 
2437 instruct reduce_xorL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
2438   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2439   match(Set dst (XorReductionV src1 src2));
2440   effect(TEMP tmp);
2441   format %{ "reduce_xorL $dst, $src1, $src2\t# KILL $tmp" %}
2442   ins_encode %{
2443     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2444     __ reduce_integral_v($dst$$Register, $src1$$Register,
2445                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2446                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2447   %}
2448   ins_pipe(pipe_slow);
2449 %}
2450 
2451 // vector xor reduction - predicated
2452 
2453 instruct reduce_xor_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2454   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2455             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2456             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2457   match(Set dst (XorReductionV (Binary src1 src2) v0));
2458   effect(TEMP tmp);
2459   format %{ "reduce_xor_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2460   ins_encode %{
2461     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2462     __ reduce_integral_v($dst$$Register, $src1$$Register,
2463                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2464                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2465                          Assembler::v0_t);
2466   %}
2467   ins_pipe(pipe_slow);
2468 %}
2469 
2470 instruct reduce_xorL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2471   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2472   match(Set dst (XorReductionV (Binary src1 src2) v0));
2473   effect(TEMP tmp);
2474   format %{ "reduce_xorL_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2475   ins_encode %{
2476     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2477     __ reduce_integral_v($dst$$Register, $src1$$Register,
2478                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2479                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2480                          Assembler::v0_t);
2481   %}
2482   ins_pipe(pipe_slow);
2483 %}
2484 
2485 // vector add reduction
2486 
2487 instruct reduce_add(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
2488   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2489             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2490             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2491   match(Set dst (AddReductionVI src1 src2));
2492   effect(TEMP tmp);
2493   format %{ "reduce_add $dst, $src1, $src2\t# KILL $tmp" %}
2494   ins_encode %{
2495     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2496     __ reduce_integral_v($dst$$Register, $src1$$Register,
2497                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2498                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2499   %}
2500   ins_pipe(pipe_slow);
2501 %}
2502 
2503 instruct reduce_addL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
2504   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2505   match(Set dst (AddReductionVL src1 src2));
2506   effect(TEMP tmp);
2507   format %{ "reduce_addL $dst, $src1, $src2\t# KILL $tmp" %}
2508   ins_encode %{
2509     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2510     __ reduce_integral_v($dst$$Register, $src1$$Register,
2511                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2512                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2513   %}
2514   ins_pipe(pipe_slow);
2515 %}
2516 
2517 // Distinguish two cases based on requires_strict_order
2518 // 1. Non strictly-ordered AddReductionVF/D. For example, AddReductionVF/D
2519 //    generated by Vector API. It is more beneficial performance-wise to do
2520 //    an unordered FP reduction sum (vfredusum.vs).
2521 // 2. Strictly-ordered AddReductionVF/D. For example, AddReductionVF/D
2522 //    generated by auto-vectorization. Must do an ordered FP reduction sum
2523 //    (vfredosum.vs).
2524 
2525 instruct reduce_addF_ordered(fRegF dst, fRegF src1, vReg src2, vReg tmp) %{
2526   predicate(n->as_Reduction()->requires_strict_order());
2527   match(Set dst (AddReductionVF src1 src2));
2528   effect(TEMP tmp);
2529   format %{ "reduce_addF_ordered $dst, $src1, $src2\t# KILL $tmp" %}
2530   ins_encode %{
2531     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this, $src2));
2532     __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1$$FloatRegister);
2533     __ vfredosum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
2534                     as_VectorRegister($tmp$$reg));
2535     __ vfmv_f_s($dst$$FloatRegister, as_VectorRegister($tmp$$reg));
2536   %}
2537   ins_pipe(pipe_slow);
2538 %}
2539 
2540 instruct reduce_addF_unordered(fRegF dst, fRegF src1, vReg src2, vReg tmp) %{
2541   predicate(!n->as_Reduction()->requires_strict_order());
2542   match(Set dst (AddReductionVF src1 src2));
2543   effect(TEMP tmp);
2544   format %{ "reduce_addF_unordered $dst, $src1, $src2\t# KILL $tmp" %}
2545   ins_encode %{
2546     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this, $src2));
2547     __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1$$FloatRegister);
2548     __ vfredusum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
2549                     as_VectorRegister($tmp$$reg));
2550     __ vfmv_f_s($dst$$FloatRegister, as_VectorRegister($tmp$$reg));
2551   %}
2552   ins_pipe(pipe_slow);
2553 %}
2554 
2555 instruct reduce_addD_ordered(fRegD dst, fRegD src1, vReg src2, vReg tmp) %{
2556   predicate(n->as_Reduction()->requires_strict_order());
2557   match(Set dst (AddReductionVD src1 src2));
2558   effect(TEMP tmp);
2559   format %{ "reduce_addD_ordered $dst, $src1, $src2\t# KILL $tmp" %}
2560   ins_encode %{
2561     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this, $src2));
2562     __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1$$FloatRegister);
2563     __ vfredosum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
2564                     as_VectorRegister($tmp$$reg));
2565     __ vfmv_f_s($dst$$FloatRegister, as_VectorRegister($tmp$$reg));
2566   %}
2567   ins_pipe(pipe_slow);
2568 %}
2569 
2570 instruct reduce_addD_unordered(fRegD dst, fRegD src1, vReg src2, vReg tmp) %{
2571   predicate(!n->as_Reduction()->requires_strict_order());
2572   match(Set dst (AddReductionVD src1 src2));
2573   effect(TEMP tmp);
2574   format %{ "reduce_addD_unordered $dst, $src1, $src2\t# KILL $tmp" %}
2575   ins_encode %{
2576     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this, $src2));
2577     __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1$$FloatRegister);
2578     __ vfredusum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
2579                     as_VectorRegister($tmp$$reg));
2580     __ vfmv_f_s($dst$$FloatRegister, as_VectorRegister($tmp$$reg));
2581   %}
2582   ins_pipe(pipe_slow);
2583 %}
2584 
2585 // vector add reduction - predicated
2586 
2587 instruct reduce_add_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2588   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2589             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2590             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2591   match(Set dst (AddReductionVI (Binary src1 src2) v0));
2592   effect(TEMP tmp);
2593   format %{ "reduce_add_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2594   ins_encode %{
2595     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2596     __ reduce_integral_v($dst$$Register, $src1$$Register,
2597                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2598                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2599                          Assembler::v0_t);
2600   %}
2601   ins_pipe(pipe_slow);
2602 %}
2603 
2604 instruct reduce_addL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2605   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2606   match(Set dst (AddReductionVL (Binary src1 src2) v0));
2607   effect(TEMP tmp);
2608   format %{ "reduce_addL_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2609   ins_encode %{
2610     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2611     __ reduce_integral_v($dst$$Register, $src1$$Register,
2612                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2613                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2614                          Assembler::v0_t);
2615   %}
2616   ins_pipe(pipe_slow);
2617 %}
2618 
2619 instruct reduce_addF_masked(fRegF dst, fRegF src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2620   match(Set dst (AddReductionVF (Binary src1 src2) v0));
2621   effect(TEMP tmp);
2622   format %{ "reduce_addF_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2623   ins_encode %{
2624     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this, $src2));
2625     __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1$$FloatRegister);
2626     __ vfredosum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
2627                     as_VectorRegister($tmp$$reg), Assembler::v0_t);
2628     __ vfmv_f_s($dst$$FloatRegister, as_VectorRegister($tmp$$reg));
2629   %}
2630   ins_pipe(pipe_slow);
2631 %}
2632 
2633 instruct reduce_addD_masked(fRegD dst, fRegD src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2634   match(Set dst (AddReductionVD (Binary src1 src2) v0));
2635   effect(TEMP tmp);
2636   format %{ "reduce_addD_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2637   ins_encode %{
2638     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this, $src2));
2639     __ vfmv_s_f(as_VectorRegister($tmp$$reg), $src1$$FloatRegister);
2640     __ vfredosum_vs(as_VectorRegister($tmp$$reg), as_VectorRegister($src2$$reg),
2641                     as_VectorRegister($tmp$$reg), Assembler::v0_t);
2642     __ vfmv_f_s($dst$$FloatRegister, as_VectorRegister($tmp$$reg));
2643   %}
2644   ins_pipe(pipe_slow);
2645 %}
2646 
2647 // vector integer max reduction
2648 
2649 instruct vreduce_max(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
2650   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2651             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2652             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2653   match(Set dst (MaxReductionV src1 src2));
2654   effect(TEMP tmp);
2655   format %{ "vreduce_max $dst, $src1, $src2\t# KILL $tmp" %}
2656   ins_encode %{
2657     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2658     __ reduce_integral_v($dst$$Register, $src1$$Register,
2659                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2660                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2661   %}
2662   ins_pipe(pipe_slow);
2663 %}
2664 
2665 instruct vreduce_maxL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
2666   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2667   match(Set dst (MaxReductionV src1 src2));
2668   effect(TEMP tmp);
2669   format %{ "vreduce_maxL $dst, $src1, $src2\t# KILL $tmp" %}
2670   ins_encode %{
2671     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2672     __ reduce_integral_v($dst$$Register, $src1$$Register,
2673                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2674                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2675   %}
2676   ins_pipe(pipe_slow);
2677 %}
2678 
2679 // vector integer max reduction - predicated
2680 
2681 instruct vreduce_max_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2682   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2683             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2684             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2685   match(Set dst (MaxReductionV (Binary src1 src2) v0));
2686   effect(TEMP tmp);
2687   format %{ "vreduce_max_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2688   ins_encode %{
2689     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2690     __ reduce_integral_v($dst$$Register, $src1$$Register,
2691                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2692                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2693                          Assembler::v0_t);
2694   %}
2695   ins_pipe(pipe_slow);
2696 %}
2697 
2698 instruct vreduce_maxL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2699   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2700   match(Set dst (MaxReductionV (Binary src1 src2) v0));
2701   effect(TEMP tmp);
2702   format %{ "vreduce_maxL_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2703   ins_encode %{
2704     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2705     __ reduce_integral_v($dst$$Register, $src1$$Register,
2706                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2707                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2708                          Assembler::v0_t);
2709   %}
2710   ins_pipe(pipe_slow);
2711 %}
2712 
2713 // vector integer min reduction
2714 
2715 instruct vreduce_min(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
2716   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2717             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2718             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2719   match(Set dst (MinReductionV src1 src2));
2720   effect(TEMP tmp);
2721   format %{ "vreduce_min $dst, $src1, $src2\t# KILL $tmp" %}
2722   ins_encode %{
2723     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2724     __ reduce_integral_v($dst$$Register, $src1$$Register,
2725                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2726                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2727   %}
2728   ins_pipe(pipe_slow);
2729 %}
2730 
2731 instruct vreduce_minL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
2732   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2733   match(Set dst (MinReductionV src1 src2));
2734   effect(TEMP tmp);
2735   format %{ "vreduce_minL $dst, $src1, $src2\t# KILL $tmp" %}
2736   ins_encode %{
2737     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2738     __ reduce_integral_v($dst$$Register, $src1$$Register,
2739                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2740                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2));
2741   %}
2742   ins_pipe(pipe_slow);
2743 %}
2744 
2745 // vector integer min reduction - predicated
2746 
2747 instruct vreduce_min_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2748   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_BYTE ||
2749             Matcher::vector_element_basic_type(n->in(2)) == T_SHORT ||
2750             Matcher::vector_element_basic_type(n->in(2)) == T_INT);
2751   match(Set dst (MinReductionV (Binary src1 src2) v0));
2752   effect(TEMP tmp);
2753   format %{ "vreduce_min_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2754   ins_encode %{
2755     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2756     __ reduce_integral_v($dst$$Register, $src1$$Register,
2757                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2758                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2759                          Assembler::v0_t);
2760   %}
2761   ins_pipe(pipe_slow);
2762 %}
2763 
2764 instruct vreduce_minL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegMask_V0 v0, vReg tmp) %{
2765   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
2766   match(Set dst (MinReductionV (Binary src1 src2) v0));
2767   effect(TEMP tmp);
2768   format %{ "vreduce_minL_masked $dst, $src1, $src2, $v0\t# KILL $tmp" %}
2769   ins_encode %{
2770     BasicType bt = Matcher::vector_element_basic_type(this, $src2);
2771     __ reduce_integral_v($dst$$Register, $src1$$Register,
2772                          as_VectorRegister($src2$$reg), as_VectorRegister($tmp$$reg),
2773                          this->ideal_Opcode(), bt, Matcher::vector_length(this, $src2),
2774                          Assembler::v0_t);
2775   %}
2776   ins_pipe(pipe_slow);
2777 %}
2778 
2779 // vector float max reduction
2780 
2781 instruct vreduce_maxF(fRegF dst, fRegF src1, vReg src2, vReg tmp1, vReg tmp2) %{
2782   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT);
2783   match(Set dst (MaxReductionV src1 src2));
2784   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2785   format %{ "vreduce_maxF $dst, $src1, $src2, $tmp1, $tmp2" %}
2786   ins_encode %{
2787     __ reduce_minmax_fp_v($dst$$FloatRegister,
2788                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
2789                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2790                           false /* is_double */, false /* is_min */, Matcher::vector_length(this, $src2));
2791   %}
2792   ins_pipe(pipe_slow);
2793 %}
2794 
2795 instruct vreduce_maxD(fRegD dst, fRegD src1, vReg src2, vReg tmp1, vReg tmp2) %{
2796   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE);
2797   match(Set dst (MaxReductionV src1 src2));
2798   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2799   format %{ "vreduce_maxD $dst, $src1, $src2, $tmp1, $tmp2" %}
2800   ins_encode %{
2801     __ reduce_minmax_fp_v($dst$$FloatRegister,
2802                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
2803                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2804                           true /* is_double */, false /* is_min */, Matcher::vector_length(this, $src2));
2805   %}
2806   ins_pipe(pipe_slow);
2807 %}
2808 
2809 // vector float max reduction - predicated
2810 
2811 instruct vreduce_maxF_masked(fRegF dst, fRegF src1, vReg src2, vRegMask_V0 v0, vReg tmp1, vReg tmp2) %{
2812   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT);
2813   match(Set dst (MaxReductionV (Binary src1 src2) v0));
2814   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2815   format %{ "vreduce_maxF_masked $dst, $src1, $src2, $v0\t# KILL $tmp1, $tmp2" %}
2816   ins_encode %{
2817     __ reduce_minmax_fp_v($dst$$FloatRegister,
2818                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
2819                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2820                           false /* is_double */, false /* is_min */,
2821                           Matcher::vector_length(this, $src2), Assembler::v0_t);
2822   %}
2823   ins_pipe(pipe_slow);
2824 %}
2825 
2826 instruct vreduce_maxD_masked(fRegD dst, fRegD src1, vReg src2, vRegMask_V0 v0, vReg tmp1, vReg tmp2) %{
2827   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE);
2828   match(Set dst (MaxReductionV (Binary src1 src2) v0));
2829   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2830   format %{ "vreduce_maxD_masked $dst, $src1, $src2, $v0\t# KILL $tmp1, $tmp2" %}
2831   ins_encode %{
2832     __ reduce_minmax_fp_v($dst$$FloatRegister,
2833                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
2834                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2835                           true /* is_double */, false /* is_min */,
2836                           Matcher::vector_length(this, $src2), Assembler::v0_t);
2837   %}
2838   ins_pipe(pipe_slow);
2839 %}
2840 
2841 // vector float min reduction
2842 
2843 instruct vreduce_minF(fRegF dst, fRegF src1, vReg src2, vReg tmp1, vReg tmp2) %{
2844   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT);
2845   match(Set dst (MinReductionV src1 src2));
2846   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2847   format %{ "vreduce_minF $dst, $src1, $src2, $tmp1, $tmp2" %}
2848   ins_encode %{
2849     __ reduce_minmax_fp_v($dst$$FloatRegister,
2850                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
2851                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2852                           false /* is_double */, true /* is_min */, Matcher::vector_length(this, $src2));
2853   %}
2854   ins_pipe(pipe_slow);
2855 %}
2856 
2857 instruct vreduce_minD(fRegD dst, fRegD src1, vReg src2, vReg tmp1, vReg tmp2) %{
2858   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE);
2859   match(Set dst (MinReductionV src1 src2));
2860   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2861   format %{ "vreduce_minD $dst, $src1, $src2, $tmp1, $tmp2" %}
2862   ins_encode %{
2863     __ reduce_minmax_fp_v($dst$$FloatRegister,
2864                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
2865                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2866                           true /* is_double */, true /* is_min */, Matcher::vector_length(this, $src2));
2867   %}
2868   ins_pipe(pipe_slow);
2869 %}
2870 
2871 // vector float min reduction - predicated
2872 
2873 instruct vreduce_minF_masked(fRegF dst, fRegF src1, vReg src2, vRegMask_V0 v0, vReg tmp1, vReg tmp2) %{
2874   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT);
2875   match(Set dst (MinReductionV (Binary src1 src2) v0));
2876   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2877   format %{ "vreduce_minF_masked $dst, $src1, $src2, $v0\t# KILL $tmp1, $tmp2" %}
2878   ins_encode %{
2879     __ reduce_minmax_fp_v($dst$$FloatRegister,
2880                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
2881                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2882                           false /* is_double */, true /* is_min */,
2883                           Matcher::vector_length(this, $src2), Assembler::v0_t);
2884   %}
2885   ins_pipe(pipe_slow);
2886 %}
2887 
2888 instruct vreduce_minD_masked(fRegD dst, fRegD src1, vReg src2, vRegMask_V0 v0, vReg tmp1, vReg tmp2) %{
2889   predicate(Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE);
2890   match(Set dst (MinReductionV (Binary src1 src2) v0));
2891   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2892   format %{ "vreduce_minD_masked $dst, $src1, $src2, $v0\t# KILL $tmp1, $tmp2" %}
2893   ins_encode %{
2894     __ reduce_minmax_fp_v($dst$$FloatRegister,
2895                           $src1$$FloatRegister, as_VectorRegister($src2$$reg),
2896                           as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2897                           true /* is_double */, true /* is_min */,
2898                           Matcher::vector_length(this, $src2), Assembler::v0_t);
2899   %}
2900   ins_pipe(pipe_slow);
2901 %}
2902 
2903 
2904 // ------------------------------ Vector reduction mul -------------------------
2905 
2906 instruct reduce_mulI(iRegINoSp dst, iRegIorL2I isrc, vReg vsrc,
2907                      vReg tmp1, vReg tmp2) %{
2908   match(Set dst (MulReductionVI isrc vsrc));
2909   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2910   format %{ "reduce_mulI $dst, $isrc, $vsrc\t" %}
2911 
2912   ins_encode %{
2913     __ reduce_mul_integral_v($dst$$Register, $isrc$$Register, as_VectorRegister($vsrc$$reg),
2914                              as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2915                              Matcher::vector_element_basic_type(this, $vsrc), Matcher::vector_length(this, $vsrc));
2916   %}
2917   ins_pipe(pipe_slow);
2918 %}
2919 
2920 instruct reduce_mulI_masked(iRegINoSp dst, iRegIorL2I isrc, vReg vsrc,
2921                             vRegMask_V0 v0, vReg tmp1, vReg tmp2) %{
2922   match(Set dst (MulReductionVI (Binary isrc vsrc) v0));
2923   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2924   format %{ "reduce_mulI_masked $dst, $isrc, $vsrc, $v0\t" %}
2925 
2926   ins_encode %{
2927     __ reduce_mul_integral_v($dst$$Register, $isrc$$Register, as_VectorRegister($vsrc$$reg),
2928                              as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2929                              Matcher::vector_element_basic_type(this, $vsrc), Matcher::vector_length(this, $vsrc),
2930                              Assembler::v0_t);
2931   %}
2932   ins_pipe(pipe_slow);
2933 %}
2934 
2935 instruct reduce_mulL(iRegLNoSp dst, iRegL isrc, vReg vsrc,
2936                      vReg tmp1, vReg tmp2) %{
2937   match(Set dst (MulReductionVL isrc vsrc));
2938   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2939   format %{ "reduce_mulL $dst, $isrc, $vsrc\t" %}
2940 
2941   ins_encode %{
2942     __ reduce_mul_integral_v($dst$$Register, $isrc$$Register, as_VectorRegister($vsrc$$reg),
2943                              as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2944                              Matcher::vector_element_basic_type(this, $vsrc), Matcher::vector_length(this, $vsrc));
2945   %}
2946   ins_pipe(pipe_slow);
2947 %}
2948 
2949 instruct reduce_mulL_masked(iRegLNoSp dst, iRegL isrc, vReg vsrc,
2950                             vRegMask_V0 v0, vReg tmp1, vReg tmp2) %{
2951   match(Set dst (MulReductionVL (Binary isrc vsrc) v0));
2952   effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
2953   format %{ "reduce_mulL_masked $dst, $isrc, $vsrc, $v0\t" %}
2954 
2955   ins_encode %{
2956     __ reduce_mul_integral_v($dst$$Register, $isrc$$Register, as_VectorRegister($vsrc$$reg),
2957                              as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg),
2958                              Matcher::vector_element_basic_type(this, $vsrc), Matcher::vector_length(this, $vsrc),
2959                              Assembler::v0_t);
2960   %}
2961   ins_pipe(pipe_slow);
2962 %}
2963 
2964 // vector replicate
2965 
2966 instruct replicate(vReg dst, iRegIorL2I src) %{
2967   predicate(Matcher::is_non_long_integral_vector(n));
2968   match(Set dst (Replicate src));
2969   format %{ "replicate $dst, $src" %}
2970   ins_encode %{
2971     BasicType bt = Matcher::vector_element_basic_type(this);
2972     __ vsetvli_helper(bt, Matcher::vector_length(this));
2973     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
2974   %}
2975   ins_pipe(pipe_slow);
2976 %}
2977 
2978 instruct replicateL(vReg dst, iRegL src) %{
2979   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
2980   match(Set dst (Replicate src));
2981   format %{ "replicateL $dst, $src" %}
2982   ins_encode %{
2983     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
2984     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
2985   %}
2986   ins_pipe(pipe_slow);
2987 %}
2988 
2989 instruct replicate_imm5(vReg dst, immI5 con) %{
2990   predicate(Matcher::is_non_long_integral_vector(n));
2991   match(Set dst (Replicate con));
2992   format %{ "replicate_imm5 $dst, $con" %}
2993   ins_encode %{
2994     BasicType bt = Matcher::vector_element_basic_type(this);
2995     __ vsetvli_helper(bt, Matcher::vector_length_in_bytes(this));
2996     __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant);
2997   %}
2998   ins_pipe(pipe_slow);
2999 %}
3000 
3001 instruct replicateL_imm5(vReg dst, immL5 con) %{
3002   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
3003   match(Set dst (Replicate con));
3004   format %{ "replicateL_imm5 $dst, $con" %}
3005   ins_encode %{
3006     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3007     __ vmv_v_i(as_VectorRegister($dst$$reg), $con$$constant);
3008   %}
3009   ins_pipe(pipe_slow);
3010 %}
3011 
3012 instruct replicateHF(vReg dst, fRegF src) %{
3013   predicate(Matcher::vector_element_basic_type(n) == T_SHORT);
3014   match(Set dst (Replicate src));
3015   format %{ "replicateHF $dst, $src" %}
3016   ins_encode %{
3017     assert(UseZvfh, "must");
3018     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3019     __ vfmv_v_f(as_VectorRegister($dst$$reg), $src$$FloatRegister);
3020   %}
3021   ins_pipe(pipe_slow);
3022 %}
3023 
3024 instruct replicateF(vReg dst, fRegF src) %{
3025   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT);
3026   match(Set dst (Replicate src));
3027   format %{ "replicateF $dst, $src" %}
3028   ins_encode %{
3029     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this));
3030     __ vfmv_v_f(as_VectorRegister($dst$$reg), $src$$FloatRegister);
3031   %}
3032   ins_pipe(pipe_slow);
3033 %}
3034 
3035 instruct replicateD(vReg dst, fRegD src) %{
3036   predicate(Matcher::vector_element_basic_type(n) == T_DOUBLE);
3037   match(Set dst (Replicate src));
3038   format %{ "replicateD $dst, $src" %}
3039   ins_encode %{
3040     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this));
3041     __ vfmv_v_f(as_VectorRegister($dst$$reg), $src$$FloatRegister);
3042   %}
3043   ins_pipe(pipe_slow);
3044 %}
3045 
3046 // vector shift
3047 //
3048 // Following shift instruct's are shared by vectorization (in SLP, superword.cpp) and Vector API.
3049 //
3050 // Shift behaviour in vectorization is defined by java language spec, which includes:
3051 //  1. "If the promoted type of the left-hand operand is int, then only the five lowest-order bits of
3052 //      the right-hand operand are used as the shift distance. It is as if the right-hand operand were
3053 //      subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111).
3054 //      The shift distance actually used is therefore always in the range 0 to 31, inclusive."
3055 //  2. similarly, for long "with the mask value 0x3f (0b111111)"
3056 // check https://docs.oracle.com/javase/specs/jls/se21/html/jls-15.html#jls-15.19 for details.
3057 //
3058 // Shift behaviour in Vector API is defined as:
3059 //   e.g. for ASHR, "a>>(n&(ESIZE*8-1))"
3060 //   this behaviour is the same as shift instrunction's in riscv vector extension.
3061 // check https://docs.oracle.com/en/java/javase/21/docs/api/jdk.incubator.vector/jdk/incubator/vector/VectorOperators.html#ASHR
3062 // and https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#116-vector-single-width-shift-instructions for details.
3063 //
3064 // Despite the difference between these 2 behaviours, the same shift instruct's of byte and short are
3065 // still shared between vectorization and Vector API. The way it works is hidden inside the implementation
3066 // of vectorization and Vector API:
3067 //  1. when doing optimization vectorization masks the shift value with "(BitsPerInt - 1)" or "(BitsPerLong - 1)"
3068 //  2. in Vector API, shift value is masked with SHIFT_MASK (e.g. for ByteVector it's "Byte.SIZE - 1")
3069 //
3070 // If not because of this pre-processing of shift value respectively in vectorization and Vector API, then
3071 // e.g. for a byte shift value 16, the intrinsic behaviour will be different, and they can not share the same
3072 // instruct here, as vectorization requires x >> 16, but Vector API requires x >> (16 & 7).
3073 
3074 instruct vasrB(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{
3075   match(Set dst (RShiftVB src shift));
3076   effect(TEMP_DEF dst, TEMP v0);
3077   format %{ "vasrB $dst, $src, $shift" %}
3078   ins_encode %{
3079     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3080     // if shift > BitsPerByte - 1, clear the low BitsPerByte - 1 bits
3081     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1);
3082     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3083                BitsPerByte - 1, Assembler::v0_t);
3084     // otherwise, shift
3085     __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg));
3086     __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3087                as_VectorRegister($shift$$reg), Assembler::v0_t);
3088   %}
3089   ins_pipe(pipe_slow);
3090 %}
3091 
3092 instruct vasrS(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{
3093   match(Set dst (RShiftVS src shift));
3094   effect(TEMP_DEF dst, TEMP v0);
3095   format %{ "vasrS $dst, $src, $shift" %}
3096   ins_encode %{
3097     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3098     // if shift > BitsPerShort - 1, clear the low BitsPerShort - 1 bits
3099     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1);
3100     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3101                BitsPerShort - 1, Assembler::v0_t);
3102     // otherwise, shift
3103     __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg));
3104     __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3105                as_VectorRegister($shift$$reg), Assembler::v0_t);
3106   %}
3107   ins_pipe(pipe_slow);
3108 %}
3109 
3110 instruct vasrI(vReg dst, vReg src, vReg shift) %{
3111   match(Set dst (RShiftVI src shift));
3112   format %{ "vasrI $dst, $src, $shift" %}
3113   ins_encode %{
3114     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3115     __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3116                as_VectorRegister($shift$$reg));
3117   %}
3118   ins_pipe(pipe_slow);
3119 %}
3120 
3121 instruct vasrL(vReg dst, vReg src, vReg shift) %{
3122   match(Set dst (RShiftVL src shift));
3123   format %{ "vasrL $dst, $src, $shift" %}
3124   ins_encode %{
3125     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3126     __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3127                as_VectorRegister($shift$$reg));
3128   %}
3129   ins_pipe(pipe_slow);
3130 %}
3131 
3132 instruct vasrB_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{
3133   match(Set dst_src (RShiftVB (Binary dst_src shift) vmask));
3134   effect(TEMP_DEF dst_src, TEMP v0);
3135   format %{ "vasrB_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %}
3136   ins_encode %{
3137     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3138     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1);
3139     // if shift > BitsPerByte - 1, clear the low BitsPerByte - 1 bits
3140     __ vmerge_vim(as_VectorRegister($shift$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1);
3141     // otherwise, shift
3142     __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg));
3143     __ vsra_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3144                as_VectorRegister($shift$$reg), Assembler::v0_t);
3145   %}
3146   ins_pipe(pipe_slow);
3147 %}
3148 
3149 instruct vasrS_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{
3150   match(Set dst_src (RShiftVS (Binary dst_src shift) vmask));
3151   effect(TEMP_DEF dst_src, TEMP v0);
3152   format %{ "vasrS_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %}
3153   ins_encode %{
3154     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3155     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1);
3156     // if shift > BitsPerShort - 1, clear the low BitsPerShort - 1 bits
3157     __ vmerge_vim(as_VectorRegister($shift$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1);
3158     // otherwise, shift
3159     __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg));
3160     __ vsra_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3161                as_VectorRegister($shift$$reg), Assembler::v0_t);
3162   %}
3163   ins_pipe(pipe_slow);
3164 %}
3165 
3166 instruct vasrI_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{
3167   match(Set dst_src (RShiftVI (Binary dst_src shift) v0));
3168   effect(TEMP_DEF dst_src);
3169   format %{ "vasrI_masked $dst_src, $dst_src, $shift, $v0" %}
3170   ins_encode %{
3171     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3172     __ vsra_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3173                as_VectorRegister($shift$$reg), Assembler::v0_t);
3174   %}
3175   ins_pipe(pipe_slow);
3176 %}
3177 
3178 instruct vasrL_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{
3179   match(Set dst_src (RShiftVL (Binary dst_src shift) v0));
3180   effect(TEMP_DEF dst_src);
3181   format %{ "vasrL_masked $dst_src, $dst_src, $shift, $v0" %}
3182   ins_encode %{
3183     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3184     __ vsra_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3185                as_VectorRegister($shift$$reg), Assembler::v0_t);
3186   %}
3187   ins_pipe(pipe_slow);
3188 %}
3189 
3190 instruct vlslB(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{
3191   match(Set dst (LShiftVB src shift));
3192   effect(TEMP_DEF dst, TEMP v0);
3193   format %{ "vlslB $dst, $src, $shift" %}
3194   ins_encode %{
3195     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3196     // if shift > BitsPerByte - 1, clear the element
3197     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1);
3198     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3199                as_VectorRegister($src$$reg), Assembler::v0_t);
3200     // otherwise, shift
3201     __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg));
3202     __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3203                as_VectorRegister($shift$$reg), Assembler::v0_t);
3204   %}
3205   ins_pipe(pipe_slow);
3206 %}
3207 
3208 instruct vlslS(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{
3209   match(Set dst (LShiftVS src shift));
3210   effect(TEMP_DEF dst, TEMP v0);
3211   format %{ "vlslS $dst, $src, $shift" %}
3212   ins_encode %{
3213     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3214     // if shift > BitsPerShort - 1, clear the element
3215     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1);
3216     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3217                as_VectorRegister($src$$reg), Assembler::v0_t);
3218     // otherwise, shift
3219     __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg));
3220     __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3221                as_VectorRegister($shift$$reg), Assembler::v0_t);
3222   %}
3223   ins_pipe(pipe_slow);
3224 %}
3225 
3226 instruct vlslI(vReg dst, vReg src, vReg shift) %{
3227   match(Set dst (LShiftVI src shift));
3228   format %{ "vlslI $dst, $src, $shift" %}
3229   ins_encode %{
3230     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3231     __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3232                as_VectorRegister($shift$$reg));
3233   %}
3234   ins_pipe(pipe_slow);
3235 %}
3236 
3237 instruct vlslL(vReg dst, vReg src, vReg shift) %{
3238   match(Set dst (LShiftVL src shift));
3239   format %{ "vlslL $dst, $src, $shift" %}
3240   ins_encode %{
3241     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3242     __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3243                as_VectorRegister($shift$$reg));
3244   %}
3245   ins_pipe(pipe_slow);
3246 %}
3247 
3248 instruct vlslB_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{
3249   match(Set dst_src (LShiftVB (Binary dst_src shift) vmask));
3250   effect(TEMP_DEF dst_src, TEMP v0);
3251   format %{ "vlslB_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %}
3252   ins_encode %{
3253     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3254     // if shift > BitsPerByte - 1, clear the element
3255     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1);
3256     __ vmand_mm(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg),
3257                 as_VectorRegister($vmask$$reg));
3258     __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3259                as_VectorRegister($dst_src$$reg), Assembler::v0_t);
3260     // otherwise, shift
3261     __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg));
3262     __ vsll_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3263                as_VectorRegister($shift$$reg), Assembler::v0_t);
3264   %}
3265   ins_pipe(pipe_slow);
3266 %}
3267 
3268 instruct vlslS_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{
3269   match(Set dst_src (LShiftVS (Binary dst_src shift) vmask));
3270   effect(TEMP_DEF dst_src, TEMP v0);
3271   format %{ "vlslS_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %}
3272   ins_encode %{
3273     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3274     // if shift > BitsPerShort - 1, clear the element
3275     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1);
3276     __ vmand_mm(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg),
3277                 as_VectorRegister($vmask$$reg));
3278     __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3279                as_VectorRegister($dst_src$$reg), Assembler::v0_t);
3280     // otherwise, shift
3281     __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg));
3282     __ vsll_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3283                as_VectorRegister($shift$$reg), Assembler::v0_t);
3284   %}
3285   ins_pipe(pipe_slow);
3286 %}
3287 
3288 instruct vlslI_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{
3289   match(Set dst_src (LShiftVI (Binary dst_src shift) v0));
3290   effect(TEMP_DEF dst_src);
3291   format %{ "vlslI_masked $dst_src, $dst_src, $shift, $v0" %}
3292   ins_encode %{
3293     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3294     __ vsll_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3295                as_VectorRegister($shift$$reg), Assembler::v0_t);
3296   %}
3297   ins_pipe(pipe_slow);
3298 %}
3299 
3300 instruct vlslL_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{
3301   match(Set dst_src (LShiftVL (Binary dst_src shift) v0));
3302   effect(TEMP_DEF dst_src);
3303   format %{ "vlslL_masked $dst_src, $dst_src, $shift, $v0" %}
3304   ins_encode %{
3305     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3306     __ vsll_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3307                as_VectorRegister($shift$$reg), Assembler::v0_t);
3308   %}
3309   ins_pipe(pipe_slow);
3310 %}
3311 
3312 instruct vlsrB(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{
3313   match(Set dst (URShiftVB src shift));
3314   effect(TEMP_DEF dst, TEMP v0);
3315   format %{ "vlsrB $dst, $src, $shift" %}
3316   ins_encode %{
3317     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3318     // if shift > BitsPerByte - 1, clear the element
3319     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1);
3320     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3321                as_VectorRegister($src$$reg), Assembler::v0_t);
3322     // otherwise, shift
3323     __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg));
3324     __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3325                as_VectorRegister($shift$$reg), Assembler::v0_t);
3326   %}
3327   ins_pipe(pipe_slow);
3328 %}
3329 
3330 instruct vlsrS(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{
3331   match(Set dst (URShiftVS src shift));
3332   effect(TEMP_DEF dst, TEMP v0);
3333   format %{ "vlsrS $dst, $src, $shift" %}
3334   ins_encode %{
3335     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3336     // if shift > BitsPerShort - 1, clear the element
3337     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1);
3338     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3339                as_VectorRegister($src$$reg), Assembler::v0_t);
3340     // otherwise, shift
3341     __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg));
3342     __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3343                as_VectorRegister($shift$$reg), Assembler::v0_t);
3344   %}
3345   ins_pipe(pipe_slow);
3346 %}
3347 
3348 instruct vlsrI(vReg dst, vReg src, vReg shift) %{
3349   match(Set dst (URShiftVI src shift));
3350   format %{ "vlsrI $dst, $src, $shift" %}
3351   ins_encode %{
3352     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3353     __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3354                as_VectorRegister($shift$$reg));
3355   %}
3356   ins_pipe(pipe_slow);
3357 %}
3358 
3359 instruct vlsrL(vReg dst, vReg src, vReg shift) %{
3360   match(Set dst (URShiftVL src shift));
3361   format %{ "vlsrL $dst, $src, $shift" %}
3362   ins_encode %{
3363     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3364     __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3365                as_VectorRegister($shift$$reg));
3366   %}
3367   ins_pipe(pipe_slow);
3368 %}
3369 
3370 instruct vlsrB_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{
3371   match(Set dst_src (URShiftVB (Binary dst_src shift) vmask));
3372   effect(TEMP_DEF dst_src, TEMP v0);
3373   format %{ "vlsrB_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %}
3374   ins_encode %{
3375     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3376     // if shift > BitsPerByte - 1, clear the element
3377     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1);
3378     __ vmand_mm(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg),
3379                 as_VectorRegister($vmask$$reg));
3380     __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3381                as_VectorRegister($dst_src$$reg), Assembler::v0_t);
3382     // otherwise, shift
3383     __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg));
3384     __ vsrl_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3385                as_VectorRegister($shift$$reg), Assembler::v0_t);
3386   %}
3387   ins_pipe(pipe_slow);
3388 %}
3389 
3390 instruct vlsrS_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{
3391   match(Set dst_src (URShiftVS (Binary dst_src shift) vmask));
3392   effect(TEMP_DEF dst_src, TEMP v0);
3393   format %{ "vlsrS_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %}
3394   ins_encode %{
3395     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3396     // if shift > BitsPerShort - 1, clear the element
3397     __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1);
3398     __ vmand_mm(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg),
3399                 as_VectorRegister($vmask$$reg));
3400     __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3401                as_VectorRegister($dst_src$$reg), Assembler::v0_t);
3402     // otherwise, shift
3403     __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg));
3404     __ vsrl_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3405                as_VectorRegister($shift$$reg), Assembler::v0_t);
3406   %}
3407   ins_pipe(pipe_slow);
3408 %}
3409 
3410 instruct vlsrI_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{
3411   match(Set dst_src (URShiftVI (Binary dst_src shift) v0));
3412   effect(TEMP_DEF dst_src);
3413   format %{ "vlsrI_masked $dst_src, $dst_src, $shift, $v0" %}
3414   ins_encode %{
3415     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3416     __ vsrl_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3417                as_VectorRegister($shift$$reg), Assembler::v0_t);
3418   %}
3419   ins_pipe(pipe_slow);
3420 %}
3421 
3422 instruct vlsrL_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{
3423   match(Set dst_src (URShiftVL (Binary dst_src shift) v0));
3424   effect(TEMP_DEF dst_src);
3425   format %{ "vlsrL_masked $dst_src, $dst_src, $shift, $v0" %}
3426   ins_encode %{
3427     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3428     __ vsrl_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3429                as_VectorRegister($shift$$reg), Assembler::v0_t);
3430   %}
3431   ins_pipe(pipe_slow);
3432 %}
3433 
3434 instruct vasrB_vi(vReg dst, vReg src, immI shift) %{
3435   match(Set dst (RShiftVB src (RShiftCntV shift)));
3436   format %{ "vasrB_vi $dst, $src, $shift" %}
3437   ins_encode %{
3438     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3439     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3440     if (con == 0) {
3441       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3442                 as_VectorRegister($src$$reg));
3443       return;
3444     }
3445     if (con >= BitsPerByte) con = BitsPerByte - 1;
3446     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3447   %}
3448   ins_pipe(pipe_slow);
3449 %}
3450 
3451 instruct vasrS_vi(vReg dst, vReg src, immI shift) %{
3452   match(Set dst (RShiftVS src (RShiftCntV shift)));
3453   format %{ "vasrS_vi $dst, $src, $shift" %}
3454   ins_encode %{
3455     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3456     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3457     if (con == 0) {
3458       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3459                 as_VectorRegister($src$$reg));
3460       return;
3461     }
3462     if (con >= BitsPerShort) con = BitsPerShort - 1;
3463     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3464   %}
3465   ins_pipe(pipe_slow);
3466 %}
3467 
3468 instruct vasrI_vi(vReg dst, vReg src, immI shift) %{
3469   match(Set dst (RShiftVI src (RShiftCntV shift)));
3470   format %{ "vasrI_vi $dst, $src, $shift" %}
3471   ins_encode %{
3472     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3473     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3474     if (con == 0) {
3475       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3476                 as_VectorRegister($src$$reg));
3477       return;
3478     }
3479     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3480   %}
3481   ins_pipe(pipe_slow);
3482 %}
3483 
3484 instruct vasrL_vi(vReg dst, vReg src, immI shift) %{
3485   predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32);
3486   match(Set dst (RShiftVL src (RShiftCntV shift)));
3487   format %{ "vasrL_vi $dst, $src, $shift" %}
3488   ins_encode %{
3489     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3490     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3491     if (con == 0) {
3492       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3493                 as_VectorRegister($src$$reg));
3494       return;
3495     }
3496     __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3497   %}
3498   ins_pipe(pipe_slow);
3499 %}
3500 
3501 instruct vasrB_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3502   match(Set dst_src (RShiftVB (Binary dst_src (RShiftCntV shift)) v0));
3503   format %{ "vasrB_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3504   ins_encode %{
3505     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3506     if (con == 0) {
3507       return;
3508     }
3509     if (con >= BitsPerByte) con = BitsPerByte - 1;
3510     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3511     __ vsra_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3512                Assembler::v0_t);
3513   %}
3514   ins_pipe(pipe_slow);
3515 %}
3516 
3517 instruct vasrS_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3518   match(Set dst_src (RShiftVS (Binary dst_src (RShiftCntV shift)) v0));
3519   format %{ "vasrS_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3520   ins_encode %{
3521     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3522     if (con == 0) {
3523       return;
3524     }
3525     if (con >= BitsPerShort) con = BitsPerShort - 1;
3526     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3527     __ vsra_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3528                Assembler::v0_t);
3529   %}
3530   ins_pipe(pipe_slow);
3531 %}
3532 
3533 instruct vasrI_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3534   match(Set dst_src (RShiftVI (Binary dst_src (RShiftCntV shift)) v0));
3535   format %{ "vasrI_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3536   ins_encode %{
3537     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3538     if (con == 0) {
3539       return;
3540     }
3541     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3542     __ vsra_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3543                Assembler::v0_t);
3544   %}
3545   ins_pipe(pipe_slow);
3546 %}
3547 
3548 instruct vasrL_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3549   predicate((n->in(1)->in(2)->in(1)->get_int() & 0x3f) < 32);
3550   match(Set dst_src (RShiftVL (Binary dst_src (RShiftCntV shift)) v0));
3551   format %{ "vasrL_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3552   ins_encode %{
3553     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3554     if (con == 0) {
3555       return;
3556     }
3557     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3558     __ vsra_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3559                Assembler::v0_t);
3560   %}
3561   ins_pipe(pipe_slow);
3562 %}
3563 
3564 instruct vlsrB_vi(vReg dst, vReg src, immI shift) %{
3565   match(Set dst (URShiftVB src (RShiftCntV shift)));
3566   format %{ "vlsrB_vi $dst, $src, $shift" %}
3567   ins_encode %{
3568     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3569     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3570     if (con == 0) {
3571       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3572                 as_VectorRegister($src$$reg));
3573       return;
3574     }
3575     if (con >= BitsPerByte) {
3576       __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3577                  as_VectorRegister($src$$reg));
3578       return;
3579     }
3580     __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3581   %}
3582   ins_pipe(pipe_slow);
3583 %}
3584 
3585 instruct vlsrS_vi(vReg dst, vReg src, immI shift) %{
3586   match(Set dst (URShiftVS src (RShiftCntV shift)));
3587   format %{ "vlsrS_vi $dst, $src, $shift" %}
3588   ins_encode %{
3589     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3590     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3591     if (con == 0) {
3592       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3593                 as_VectorRegister($src$$reg));
3594       return;
3595     }
3596     if (con >= BitsPerShort) {
3597       __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3598                  as_VectorRegister($src$$reg));
3599       return;
3600     }
3601     __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3602   %}
3603   ins_pipe(pipe_slow);
3604 %}
3605 
3606 instruct vlsrI_vi(vReg dst, vReg src, immI shift) %{
3607   match(Set dst (URShiftVI src (RShiftCntV shift)));
3608   format %{ "vlsrI_vi $dst, $src, $shift" %}
3609   ins_encode %{
3610     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3611     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3612     if (con == 0) {
3613       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3614                 as_VectorRegister($src$$reg));
3615       return;
3616     }
3617     __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3618   %}
3619   ins_pipe(pipe_slow);
3620 %}
3621 
3622 instruct vlsrL_vi(vReg dst, vReg src, immI shift) %{
3623   predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32);
3624   match(Set dst (URShiftVL src (RShiftCntV shift)));
3625   format %{ "vlsrL_vi $dst, $src, $shift" %}
3626   ins_encode %{
3627     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3628     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3629     if (con == 0) {
3630       __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3631                 as_VectorRegister($src$$reg));
3632       return;
3633     }
3634     __ vsrl_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3635   %}
3636   ins_pipe(pipe_slow);
3637 %}
3638 
3639 instruct vlsrB_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3640   match(Set dst_src (URShiftVB (Binary dst_src (RShiftCntV shift)) v0));
3641   format %{ "vlsrB_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3642   ins_encode %{
3643     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3644     if (con == 0) {
3645       return;
3646     }
3647     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3648     if (con >= BitsPerByte) {
3649       __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3650                  as_VectorRegister($dst_src$$reg), Assembler::v0_t);
3651       return;
3652     }
3653     __ vsrl_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3654                Assembler::v0_t);
3655   %}
3656   ins_pipe(pipe_slow);
3657 %}
3658 
3659 instruct vlsrS_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3660   match(Set dst_src (URShiftVS (Binary dst_src (RShiftCntV shift)) v0));
3661   format %{ "vlsrS_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3662   ins_encode %{
3663     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3664     if (con == 0) {
3665       return;
3666     }
3667     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3668     if (con >= BitsPerShort) {
3669       __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3670                  as_VectorRegister($dst_src$$reg), Assembler::v0_t);
3671       return;
3672     }
3673     __ vsrl_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3674                Assembler::v0_t);
3675   %}
3676   ins_pipe(pipe_slow);
3677 %}
3678 
3679 instruct vlsrI_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3680   match(Set dst_src (URShiftVI (Binary dst_src (RShiftCntV shift)) v0));
3681   format %{ "vlsrI_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3682   ins_encode %{
3683     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3684     if (con == 0) {
3685       return;
3686     }
3687     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3688     __ vsrl_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3689                Assembler::v0_t);
3690   %}
3691   ins_pipe(pipe_slow);
3692 %}
3693 
3694 instruct vlsrL_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3695   predicate((n->in(1)->in(2)->in(1)->get_int() & 0x3f) < 32);
3696   match(Set dst_src (URShiftVL (Binary dst_src (RShiftCntV shift)) v0));
3697   format %{ "vlsrL_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3698   ins_encode %{
3699     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3700     if (con == 0) {
3701       return;
3702     }
3703     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3704     __ vsrl_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3705                Assembler::v0_t);
3706   %}
3707   ins_pipe(pipe_slow);
3708 %}
3709 
3710 instruct vlslB_vi(vReg dst, vReg src, immI shift) %{
3711   match(Set dst (LShiftVB src (LShiftCntV shift)));
3712   format %{ "vlslB_vi $dst, $src, $shift" %}
3713   ins_encode %{
3714     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3715     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3716     if (con >= BitsPerByte) {
3717       __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3718                  as_VectorRegister($src$$reg));
3719       return;
3720     }
3721     __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3722   %}
3723   ins_pipe(pipe_slow);
3724 %}
3725 
3726 instruct vlslS_vi(vReg dst, vReg src, immI shift) %{
3727   match(Set dst (LShiftVS src (LShiftCntV shift)));
3728   format %{ "vlslS_vi $dst, $src, $shift" %}
3729   ins_encode %{
3730     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3731     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3732     if (con >= BitsPerShort) {
3733       __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3734                  as_VectorRegister($src$$reg));
3735       return;
3736     }
3737     __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3738   %}
3739   ins_pipe(pipe_slow);
3740 %}
3741 
3742 instruct vlslI_vi(vReg dst, vReg src, immI shift) %{
3743   match(Set dst (LShiftVI src (LShiftCntV shift)));
3744   format %{ "vlslI_vi $dst, $src, $shift" %}
3745   ins_encode %{
3746     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3747     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3748     __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3749   %}
3750   ins_pipe(pipe_slow);
3751 %}
3752 
3753 instruct vlslL_vi(vReg dst, vReg src, immI shift) %{
3754   predicate((n->in(2)->in(1)->get_int() & 0x3f) < 32);
3755   match(Set dst (LShiftVL src (LShiftCntV shift)));
3756   format %{ "vlslL_vi $dst, $src, $shift" %}
3757   ins_encode %{
3758     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3759     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3760     __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3761   %}
3762   ins_pipe(pipe_slow);
3763 %}
3764 
3765 instruct vlslB_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3766   match(Set dst_src (LShiftVB (Binary dst_src (LShiftCntV shift)) v0));
3767   format %{ "vlslB_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3768   ins_encode %{
3769     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3770     __ vsetvli_helper(T_BYTE, Matcher::vector_length(this));
3771     if (con >= BitsPerByte) {
3772       __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3773                  as_VectorRegister($dst_src$$reg), Assembler::v0_t);
3774       return;
3775     }
3776     __ vsll_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3777                Assembler::v0_t);
3778   %}
3779   ins_pipe(pipe_slow);
3780 %}
3781 
3782 instruct vlslS_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3783   match(Set dst_src (LShiftVS (Binary dst_src (LShiftCntV shift)) v0));
3784   format %{ "vlslS_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3785   ins_encode %{
3786     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3787     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
3788     if (con >= BitsPerShort) {
3789       __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3790                  as_VectorRegister($dst_src$$reg), Assembler::v0_t);
3791       return;
3792     }
3793     __ vsll_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3794                Assembler::v0_t);
3795   %}
3796   ins_pipe(pipe_slow);
3797 %}
3798 
3799 instruct vlslI_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3800   match(Set dst_src (LShiftVI (Binary dst_src (LShiftCntV shift)) v0));
3801   format %{ "vlslI_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3802   ins_encode %{
3803     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3804     __ vsetvli_helper(T_INT, Matcher::vector_length(this));
3805     __ vsll_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3806                Assembler::v0_t);
3807   %}
3808   ins_pipe(pipe_slow);
3809 %}
3810 
3811 instruct vlslL_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3812   predicate((n->in(1)->in(2)->in(1)->get_int() & 0x3f) < 32);
3813   match(Set dst_src (LShiftVL (Binary dst_src (LShiftCntV shift)) v0));
3814   format %{ "vlslL_vi_masked $dst_src, $dst_src, $shift, $v0" %}
3815   ins_encode %{
3816     uint32_t con = (unsigned)$shift$$constant & 0x1f;
3817     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
3818     __ vsll_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), con,
3819                Assembler::v0_t);
3820   %}
3821   ins_pipe(pipe_slow);
3822 %}
3823 
3824 // vector shift count
3825 
3826 instruct vshiftcnt(vReg dst, iRegIorL2I cnt) %{
3827   match(Set dst (LShiftCntV cnt));
3828   match(Set dst (RShiftCntV cnt));
3829   format %{ "vshiftcnt $dst, $cnt" %}
3830   ins_encode %{
3831     BasicType bt = Matcher::vector_element_basic_type(this);
3832     __ vsetvli_helper(bt, Matcher::vector_length(this));
3833     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($cnt$$reg));
3834   %}
3835   ins_pipe(pipe_slow);
3836 %}
3837 
3838 // --------------------------------- Vector Rotation ----------------------------------
3839 // Rotate right
3840 
3841 instruct vrotate_right(vReg dst, vReg src, vReg shift) %{
3842   match(Set dst (RotateRightV src shift));
3843   format %{ "vrotate_right $dst, $src, $shift\t" %}
3844   ins_encode %{
3845     BasicType bt = Matcher::vector_element_basic_type(this);
3846     __ vsetvli_helper(bt, Matcher::vector_length(this));
3847     __ vror_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3848                as_VectorRegister($shift$$reg));
3849   %}
3850   ins_pipe(pipe_slow);
3851 %}
3852 
3853 // Only the low log2(SEW) bits of shift value are used, all other bits are ignored.
3854 instruct vrotate_right_vx(vReg dst, vReg src, iRegIorL2I shift) %{
3855   match(Set dst (RotateRightV src (Replicate shift)));
3856   format %{ "vrotate_right_vx $dst, $src, $shift\t" %}
3857   ins_encode %{
3858     BasicType bt = Matcher::vector_element_basic_type(this);
3859     __ vsetvli_helper(bt, Matcher::vector_length(this));
3860     __ vror_vx(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3861                as_Register($shift$$reg));
3862   %}
3863   ins_pipe(pipe_slow);
3864 %}
3865 
3866 instruct vrotate_right_vi(vReg dst, vReg src, immI shift) %{
3867   match(Set dst (RotateRightV src shift));
3868   format %{ "vrotate_right_vi $dst, $src, $shift\t" %}
3869   ins_encode %{
3870     BasicType bt = Matcher::vector_element_basic_type(this);
3871     uint32_t bits = type2aelembytes(bt) * 8;
3872     uint32_t con = (unsigned)$shift$$constant & (bits - 1);
3873     if (con == 0) {
3874       return;
3875     }
3876     __ vsetvli_helper(bt, Matcher::vector_length(this));
3877     __ vror_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3878   %}
3879   ins_pipe(pipe_slow);
3880 %}
3881 
3882 // Rotate right - masked
3883 
3884 instruct vrotate_right_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{
3885   match(Set dst_src (RotateRightV (Binary dst_src shift) v0));
3886   format %{ "vrotate_right_masked $dst_src, $dst_src, $shift, $v0\t" %}
3887   ins_encode %{
3888     BasicType bt = Matcher::vector_element_basic_type(this);
3889     __ vsetvli_helper(bt, Matcher::vector_length(this));
3890     __ vror_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3891                as_VectorRegister($shift$$reg), Assembler::v0_t);
3892   %}
3893   ins_pipe(pipe_slow);
3894 %}
3895 
3896 // Only the low log2(SEW) bits of shift value are used, all other bits are ignored.
3897 instruct vrotate_right_vx_masked(vReg dst_src, iRegIorL2I shift, vRegMask_V0 v0) %{
3898   match(Set dst_src (RotateRightV (Binary dst_src (Replicate shift)) v0));
3899   format %{ "vrotate_right_vx_masked $dst_src, $dst_src, $shift, $v0\t" %}
3900   ins_encode %{
3901     BasicType bt = Matcher::vector_element_basic_type(this);
3902     __ vsetvli_helper(bt, Matcher::vector_length(this));
3903     __ vror_vx(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3904                as_Register($shift$$reg), Assembler::v0_t);
3905   %}
3906   ins_pipe(pipe_slow);
3907 %}
3908 
3909 instruct vrotate_right_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3910   match(Set dst_src (RotateRightV (Binary dst_src shift) v0));
3911   format %{ "vrotate_right_vi_masked $dst_src, $dst_src, $shift, $v0\t" %}
3912   ins_encode %{
3913     BasicType bt = Matcher::vector_element_basic_type(this);
3914     uint32_t bits = type2aelembytes(bt) * 8;
3915     uint32_t con = (unsigned)$shift$$constant & (bits - 1);
3916     if (con == 0) {
3917       return;
3918     }
3919     __ vsetvli_helper(bt, Matcher::vector_length(this));
3920     __ vror_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3921                con, Assembler::v0_t);
3922   %}
3923   ins_pipe(pipe_slow);
3924 %}
3925 
3926 // Rotate left
3927 
3928 instruct vrotate_left(vReg dst, vReg src, vReg shift) %{
3929   match(Set dst (RotateLeftV src shift));
3930   format %{ "vrotate_left $dst, $src, $shift\t" %}
3931   ins_encode %{
3932     BasicType bt = Matcher::vector_element_basic_type(this);
3933     __ vsetvli_helper(bt, Matcher::vector_length(this));
3934     __ vrol_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3935                as_VectorRegister($shift$$reg));
3936   %}
3937   ins_pipe(pipe_slow);
3938 %}
3939 
3940 // Only the low log2(SEW) bits of shift value are used, all other bits are ignored.
3941 instruct vrotate_left_vx(vReg dst, vReg src, iRegIorL2I shift) %{
3942   match(Set dst (RotateLeftV src (Replicate shift)));
3943   format %{ "vrotate_left_vx $dst, $src, $shift\t" %}
3944   ins_encode %{
3945     BasicType bt = Matcher::vector_element_basic_type(this);
3946     __ vsetvli_helper(bt, Matcher::vector_length(this));
3947     __ vrol_vx(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
3948                as_Register($shift$$reg));
3949   %}
3950   ins_pipe(pipe_slow);
3951 %}
3952 
3953 instruct vrotate_left_vi(vReg dst, vReg src, immI shift) %{
3954   match(Set dst (RotateLeftV src shift));
3955   format %{ "vrotate_left_vi $dst, $src, $shift\t" %}
3956   ins_encode %{
3957     BasicType bt = Matcher::vector_element_basic_type(this);
3958     uint32_t bits = type2aelembytes(bt) * 8;
3959     uint32_t con = (unsigned)$shift$$constant & (bits - 1);
3960     if (con == 0) {
3961       return;
3962     }
3963     __ vsetvli_helper(bt, Matcher::vector_length(this));
3964     con = bits - con;
3965     __ vror_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), con);
3966   %}
3967   ins_pipe(pipe_slow);
3968 %}
3969 
3970 // Rotate left - masked
3971 
3972 instruct vrotate_left_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{
3973   match(Set dst_src (RotateLeftV (Binary dst_src shift) v0));
3974   format %{ "vrotate_left_masked $dst_src, $dst_src, $shift, $v0\t" %}
3975   ins_encode %{
3976     BasicType bt = Matcher::vector_element_basic_type(this);
3977     __ vsetvli_helper(bt, Matcher::vector_length(this));
3978     __ vrol_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3979                as_VectorRegister($shift$$reg), Assembler::v0_t);
3980   %}
3981   ins_pipe(pipe_slow);
3982 %}
3983 
3984 // Only the low log2(SEW) bits of shift value are used, all other bits are ignored.
3985 instruct vrotate_left_vx_masked(vReg dst_src, iRegIorL2I shift, vRegMask_V0 v0) %{
3986   match(Set dst_src (RotateLeftV (Binary dst_src (Replicate shift)) v0));
3987   format %{ "vrotate_left_vx_masked $dst_src, $dst_src, $shift, $v0\t" %}
3988   ins_encode %{
3989     BasicType bt = Matcher::vector_element_basic_type(this);
3990     __ vsetvli_helper(bt, Matcher::vector_length(this));
3991     __ vrol_vx(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
3992                as_Register($shift$$reg), Assembler::v0_t);
3993   %}
3994   ins_pipe(pipe_slow);
3995 %}
3996 
3997 instruct vrotate_left_vi_masked(vReg dst_src, immI shift, vRegMask_V0 v0) %{
3998   match(Set dst_src (RotateLeftV (Binary dst_src shift) v0));
3999   format %{ "vrotate_left_vi_masked $dst_src, $dst_src, $shift, $v0\t" %}
4000   ins_encode %{
4001     BasicType bt = Matcher::vector_element_basic_type(this);
4002     uint32_t bits = type2aelembytes(bt) * 8;
4003     uint32_t con = (unsigned)$shift$$constant & (bits - 1);
4004     if (con == 0) {
4005       return;
4006     }
4007     __ vsetvli_helper(bt, Matcher::vector_length(this));
4008     con = bits - con;
4009     __ vror_vi(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
4010                con, Assembler::v0_t);
4011   %}
4012   ins_pipe(pipe_slow);
4013 %}
4014 
4015 // vector sqrt
4016 
4017 instruct vsqrt_hfp(vReg dst, vReg src) %{
4018   match(Set dst (SqrtVHF src));
4019   format %{ "vsqrt_hfp $dst, $src" %}
4020   ins_encode %{
4021     assert(UseZvfh, "must");
4022     assert(Matcher::vector_element_basic_type(this) == T_SHORT, "must");
4023     __ vsetvli_helper(T_SHORT, Matcher::vector_length(this));
4024     __ vfsqrt_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4025   %}
4026   ins_pipe(pipe_slow);
4027 %}
4028 
4029 instruct vsqrt_fp(vReg dst, vReg src) %{
4030   match(Set dst (SqrtVF src));
4031   match(Set dst (SqrtVD src));
4032   format %{ "vsqrt_fp $dst, $src" %}
4033   ins_encode %{
4034     BasicType bt = Matcher::vector_element_basic_type(this);
4035     __ vsetvli_helper(bt, Matcher::vector_length(this));
4036     __ vfsqrt_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4037   %}
4038   ins_pipe(pipe_slow);
4039 %}
4040 
4041 // vector sqrt - predicated
4042 
4043 instruct vsqrt_fp_masked(vReg dst_src, vRegMask_V0 v0) %{
4044   match(Set dst_src (SqrtVF dst_src v0));
4045   match(Set dst_src (SqrtVD dst_src v0));
4046   format %{ "vsqrt_fp_masked $dst_src, $dst_src, $v0" %}
4047   ins_encode %{
4048     BasicType bt = Matcher::vector_element_basic_type(this);
4049     __ vsetvli_helper(bt, Matcher::vector_length(this));
4050     __ vfsqrt_v(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg),
4051                 Assembler::v0_t);
4052   %}
4053   ins_pipe(pipe_slow);
4054 %}
4055 
4056 instruct vstring_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt,
4057                          iRegI_R10 result, vReg_V2 v2,
4058                          vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, rFlagsReg cr)
4059 %{
4060   predicate(UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
4061   match(Set result (StrEquals (Binary str1 str2) cnt));
4062   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v2, TEMP v3, TEMP v4, TEMP v5, KILL cr);
4063 
4064   format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %}
4065   ins_encode %{
4066     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
4067     __ string_equals_v($str1$$Register, $str2$$Register,
4068                        $result$$Register, $cnt$$Register);
4069   %}
4070   ins_pipe(pipe_class_memory);
4071 %}
4072 
4073 instruct varray_equalsB(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result,
4074                         vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, iRegP_R28 tmp, rFlagsReg cr)
4075 %{
4076   predicate(UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
4077   match(Set result (AryEq ary1 ary2));
4078   effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v2, TEMP v3, TEMP v4, TEMP v5, KILL cr);
4079 
4080   format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsB // KILL $tmp" %}
4081   ins_encode %{
4082     __ arrays_equals_v($ary1$$Register, $ary2$$Register,
4083                        $result$$Register, $tmp$$Register, 1);
4084     %}
4085   ins_pipe(pipe_class_memory);
4086 %}
4087 
4088 instruct varray_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result,
4089                         vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, iRegP_R28 tmp, rFlagsReg cr)
4090 %{
4091   predicate(UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
4092   match(Set result (AryEq ary1 ary2));
4093   effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v2, TEMP v3, TEMP v4, TEMP v5, KILL cr);
4094 
4095   format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsC // KILL $tmp" %}
4096   ins_encode %{
4097     __ arrays_equals_v($ary1$$Register, $ary2$$Register,
4098                        $result$$Register, $tmp$$Register, 2);
4099   %}
4100   ins_pipe(pipe_class_memory);
4101 %}
4102 
4103 // fast ArraysSupport.vectorizedHashCode
4104 instruct varrays_hashcode(iRegP_R11 ary, iRegI_R12 cnt, iRegI_R10 result, immI basic_type,
4105                           vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5,
4106                           vReg_V6 v6, vReg_V7 v7, vReg_V8 v8, vReg_V9 v9,
4107                           iRegLNoSp tmp1, iRegLNoSp tmp2, iRegLNoSp tmp3,
4108                           rFlagsReg cr)
4109 %{
4110   predicate(UseRVV);
4111   match(Set result (VectorizedHashCode (Binary ary cnt) (Binary result basic_type)));
4112   effect(USE_KILL ary, USE_KILL cnt, USE basic_type,
4113          TEMP v2, TEMP v3, TEMP v4, TEMP v5, TEMP v6, TEMP v7, TEMP v8, TEMP v9,
4114          TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
4115 
4116   format %{ "Array HashCode array[] $ary,$cnt,$result,$basic_type -> $result   // KILL all" %}
4117   ins_encode %{
4118     __ arrays_hashcode_v($ary$$Register, $cnt$$Register, $result$$Register,
4119                          $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
4120                          (BasicType)$basic_type$$constant);
4121   %}
4122   ins_pipe(pipe_class_memory);
4123 %}
4124 
4125 instruct vstring_compareU_128b(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
4126                           iRegI_R10 result, vReg_V4 v4, vReg_V5 v5, vReg_V6 v6, vReg_V7 v7,
4127                           vReg_V8 v8, vReg_V9 v9, vReg_V10 v10, vReg_V11 v11,
4128                           iRegP_R28 tmp1, iRegL_R29 tmp2)
4129 %{
4130   predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU &&
4131             MaxVectorSize == 16);
4132   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
4133   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
4134         TEMP v4, TEMP v5, TEMP v6, TEMP v7, TEMP v8, TEMP v9, TEMP v10, TEMP v11);
4135 
4136   format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareU" %}
4137   ins_encode %{
4138     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
4139     __ string_compare_v($str1$$Register, $str2$$Register,
4140                         $cnt1$$Register, $cnt2$$Register, $result$$Register,
4141                         $tmp1$$Register, $tmp2$$Register,
4142                         StrIntrinsicNode::UU);
4143   %}
4144   ins_pipe(pipe_class_memory);
4145 %}
4146 
4147 instruct vstring_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
4148                           iRegI_R10 result, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5,
4149                           iRegP_R28 tmp1, iRegL_R29 tmp2)
4150 %{
4151   predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU &&
4152             MaxVectorSize > 16);
4153   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
4154   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
4155         TEMP v2, TEMP v3, TEMP v4, TEMP v5);
4156 
4157   format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareU" %}
4158   ins_encode %{
4159     // Count is in 8-bit bytes; non-Compact chars are 16 bits.
4160     __ string_compare_v($str1$$Register, $str2$$Register,
4161                         $cnt1$$Register, $cnt2$$Register, $result$$Register,
4162                         $tmp1$$Register, $tmp2$$Register,
4163                         StrIntrinsicNode::UU);
4164   %}
4165   ins_pipe(pipe_class_memory);
4166 %}
4167 
4168 instruct vstring_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
4169                           iRegI_R10 result, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5,
4170                           iRegP_R28 tmp1, iRegL_R29 tmp2)
4171 %{
4172   predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LL);
4173   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
4174   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
4175         TEMP v2, TEMP v3, TEMP v4, TEMP v5);
4176 
4177   format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareL" %}
4178   ins_encode %{
4179     __ string_compare_v($str1$$Register, $str2$$Register,
4180                         $cnt1$$Register, $cnt2$$Register, $result$$Register,
4181                         $tmp1$$Register, $tmp2$$Register,
4182                         StrIntrinsicNode::LL);
4183   %}
4184   ins_pipe(pipe_class_memory);
4185 %}
4186 
4187 instruct vstring_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
4188                            iRegI_R10 result, vReg_V4 v4, vReg_V5 v5, vReg_V6 v6, vReg_V7 v7,
4189                            vReg_V8 v8, vReg_V9 v9, vReg_V10 v10, vReg_V11 v11,
4190                            iRegP_R28 tmp1, iRegL_R29 tmp2)
4191 %{
4192   predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UL);
4193   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
4194   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
4195          TEMP v4, TEMP v5, TEMP v6, TEMP v7, TEMP v8, TEMP v9, TEMP v10, TEMP v11);
4196 
4197   format %{"String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareUL" %}
4198   ins_encode %{
4199     __ string_compare_v($str1$$Register, $str2$$Register,
4200                         $cnt1$$Register, $cnt2$$Register, $result$$Register,
4201                         $tmp1$$Register, $tmp2$$Register,
4202                         StrIntrinsicNode::UL);
4203   %}
4204   ins_pipe(pipe_class_memory);
4205 %}
4206 instruct vstring_compareLU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
4207                            iRegI_R10 result, vReg_V4 v4, vReg_V5 v5, vReg_V6 v6, vReg_V7 v7,
4208                            vReg_V8 v8, vReg_V9 v9, vReg_V10 v10, vReg_V11 v11,
4209                            iRegP_R28 tmp1, iRegL_R29 tmp2)
4210 %{
4211   predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LU);
4212   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
4213   effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
4214          TEMP v4, TEMP v5, TEMP v6, TEMP v7, TEMP v8, TEMP v9, TEMP v10, TEMP v11);
4215 
4216   format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareLU" %}
4217   ins_encode %{
4218     __ string_compare_v($str1$$Register, $str2$$Register,
4219                         $cnt1$$Register, $cnt2$$Register, $result$$Register,
4220                         $tmp1$$Register, $tmp2$$Register,
4221                         StrIntrinsicNode::LU);
4222   %}
4223   ins_pipe(pipe_class_memory);
4224 %}
4225 
4226 // fast byte[] to char[] inflation
4227 instruct vstring_inflate(Universe dummy, iRegP_R10 src, iRegP_R11 dst, iRegI_R12 len,
4228                          vReg_V4 v4, vReg_V5 v5, vReg_V6 v6, vReg_V7 v7, iRegLNoSp tmp)
4229 %{
4230   predicate(UseRVV);
4231   match(Set dummy (StrInflatedCopy src (Binary dst len)));
4232   effect(TEMP v4, TEMP v5, TEMP v6, TEMP v7, TEMP tmp, USE_KILL src, USE_KILL dst, USE_KILL len);
4233 
4234   format %{ "String Inflate $src,$dst" %}
4235   ins_encode %{
4236     __ byte_array_inflate_v($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register);
4237   %}
4238   ins_pipe(pipe_class_memory);
4239 %}
4240 
4241 // encode char[] to byte[] in ISO_8859_1
4242 instruct vencode_iso_array(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result,
4243                            vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegLNoSp tmp)
4244 %{
4245   predicate(UseRVV && !((EncodeISOArrayNode*)n)->is_ascii());
4246   match(Set result (EncodeISOArray src (Binary dst len)));
4247   effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len,
4248          TEMP v0, TEMP v1, TEMP v2, TEMP v3, TEMP tmp);
4249 
4250   format %{ "Encode ISO array $src, $dst, $len -> $result # KILL $src, $dst, $len, $tmp, V0-V3" %}
4251   ins_encode %{
4252     __ encode_iso_array_v($src$$Register, $dst$$Register, $len$$Register,
4253                           $result$$Register, $tmp$$Register, false /* ascii */);
4254   %}
4255   ins_pipe(pipe_class_memory);
4256 %}
4257 
4258 instruct vencode_ascii_array(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result,
4259                              vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegLNoSp tmp)
4260 %{
4261   predicate(UseRVV && ((EncodeISOArrayNode*)n)->is_ascii());
4262   match(Set result (EncodeISOArray src (Binary dst len)));
4263   effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len,
4264          TEMP v0, TEMP v1, TEMP v2, TEMP v3, TEMP tmp);
4265 
4266   format %{ "Encode ASCII array $src, $dst, $len -> $result # KILL $src, $dst, $len, $tmp, V0-V3" %}
4267   ins_encode %{
4268     __ encode_iso_array_v($src$$Register, $dst$$Register, $len$$Register,
4269                           $result$$Register, $tmp$$Register, true /* ascii */);
4270   %}
4271   ins_pipe(pipe_class_memory);
4272 %}
4273 
4274 // fast char[] to byte[] compression
4275 instruct vstring_compress(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result,
4276                           vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegLNoSp tmp)
4277 %{
4278   predicate(UseRVV);
4279   match(Set result (StrCompressedCopy src (Binary dst len)));
4280   effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len,
4281          TEMP v0, TEMP v1, TEMP v2, TEMP v3, TEMP tmp);
4282 
4283   format %{ "String Compress $src,$dst -> $result    // KILL R11, R12, R13" %}
4284   ins_encode %{
4285     __ char_array_compress_v($src$$Register, $dst$$Register, $len$$Register,
4286                              $result$$Register, $tmp$$Register);
4287   %}
4288   ins_pipe(pipe_class_memory);
4289 %}
4290 
4291 instruct vcount_positives(iRegP_R11 ary, iRegI_R12 len, iRegI_R10 result,
4292                           vReg_V4 v4, vReg_V5 v5, vReg_V6 v6, vReg_V7 v7, iRegLNoSp tmp)
4293 %{
4294   predicate(UseRVV);
4295   match(Set result (CountPositives ary len));
4296   effect(TEMP_DEF result, USE_KILL ary, USE_KILL len, TEMP v4, TEMP v5, TEMP v6, TEMP v7, TEMP tmp);
4297 
4298   format %{ "count positives byte[] $ary, $len -> $result" %}
4299   ins_encode %{
4300     __ count_positives_v($ary$$Register, $len$$Register, $result$$Register, $tmp$$Register);
4301   %}
4302 
4303   ins_pipe(pipe_class_memory);
4304 %}
4305 
4306 instruct vstringU_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
4307                                iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
4308                                vReg_V4 v4, vReg_V5 v5, vReg_V6 v6, vReg_V7 v7)
4309 %{
4310   predicate(UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U));
4311   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
4312   effect(TEMP_DEF result, USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
4313          TEMP tmp1, TEMP tmp2, TEMP v4, TEMP v5, TEMP v6, TEMP v7);
4314 
4315   format %{ "StringUTF16 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
4316 
4317   ins_encode %{
4318     __ string_indexof_char_v($str1$$Register, $cnt1$$Register, $ch$$Register,
4319                              $result$$Register, $tmp1$$Register, $tmp2$$Register,
4320                              false /* isL */);
4321   %}
4322 
4323   ins_pipe(pipe_class_memory);
4324 %}
4325 
4326 instruct vstringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
4327                                iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
4328                                vReg_V4 v4, vReg_V5 v5, vReg_V6 v6, vReg_V7 v7)
4329 %{
4330   predicate(UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
4331   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
4332   effect(TEMP_DEF result, USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
4333          TEMP tmp1, TEMP tmp2, TEMP v4, TEMP v5, TEMP v6, TEMP v7);
4334 
4335   format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
4336 
4337   ins_encode %{
4338     __ string_indexof_char_v($str1$$Register, $cnt1$$Register, $ch$$Register,
4339                              $result$$Register, $tmp1$$Register, $tmp2$$Register,
4340                              true /* isL */);
4341   %}
4342 
4343   ins_pipe(pipe_class_memory);
4344 %}
4345 
4346 // clearing of an array
4347 instruct vclearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, immL0 zero,
4348                              vReg_V4 v4, vReg_V5 v5, vReg_V6 v6, vReg_V7 v7,
4349                              Universe dummy)
4350 %{
4351   predicate(!UseBlockZeroing && UseRVV);
4352   match(Set dummy (ClearArray (Binary cnt base) zero));
4353   effect(USE_KILL cnt, USE_KILL base, TEMP v4, TEMP v5, TEMP v6, TEMP v7);
4354 
4355   format %{ "ClearArray $cnt, $base\t#@vclearArray_reg_reg" %}
4356 
4357   ins_encode %{
4358     __ clear_array_v($base$$Register, $cnt$$Register);
4359   %}
4360 
4361   ins_pipe(pipe_class_memory);
4362 %}
4363 
4364 // Vector Load Const
4365 instruct vloadcon(vReg dst, immI0 src) %{
4366   match(Set dst (VectorLoadConst src));
4367   format %{ "vloadcon $dst\t# generate iota indices" %}
4368   ins_encode %{
4369     BasicType bt = Matcher::vector_element_basic_type(this);
4370     __ vsetvli_helper(bt, Matcher::vector_length(this));
4371     __ vid_v(as_VectorRegister($dst$$reg));
4372     if (is_floating_point_type(bt)) {
4373       __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg));
4374     }
4375   %}
4376   ins_pipe(pipe_slow);
4377 %}
4378 
4379 instruct vmask_gen_I(vRegMask dst, iRegI src) %{
4380   match(Set dst (VectorMaskGen (ConvI2L src)));
4381   format %{ "vmask_gen_I $dst, $src" %}
4382   ins_encode %{
4383     BasicType bt = Matcher::vector_element_basic_type(this);
4384     __ vsetvli_helper(bt, Matcher::vector_length(this));
4385     __ vid_v(as_VectorRegister($dst$$reg));
4386     __ vmsltu_vx(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), $src$$Register);
4387   %}
4388   ins_pipe(pipe_slow);
4389 %}
4390 
4391 instruct vmask_gen_L(vRegMask dst, iRegL src) %{
4392   match(Set dst (VectorMaskGen src));
4393   format %{ "vmask_gen_L $dst, $src" %}
4394   ins_encode %{
4395     BasicType bt = Matcher::vector_element_basic_type(this);
4396     __ vsetvli_helper(bt, Matcher::vector_length(this));
4397     __ vid_v(as_VectorRegister($dst$$reg));
4398     __ vmsltu_vx(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), $src$$Register);
4399   %}
4400   ins_pipe(pipe_slow);
4401 %}
4402 
4403 instruct vmask_gen_imm(vRegMask dst, immL con) %{
4404   predicate(n->in(1)->get_long() <= 16 ||
4405             n->in(1)->get_long() == Matcher::vector_length(n));
4406   match(Set dst (VectorMaskGen con));
4407   format %{ "vmask_gen_imm $dst, $con" %}
4408   ins_encode %{
4409     BasicType bt = Matcher::vector_element_basic_type(this);
4410     __ vsetvli_helper(bt, Matcher::vector_length(this));
4411     if ((uint)($con$$constant) == 0) {
4412       __ vmclr_m(as_VectorRegister($dst$$reg));
4413     } else if ((uint)($con$$constant) == Matcher::vector_length(this)) {
4414       __ vmset_m(as_VectorRegister($dst$$reg));
4415     } else {
4416       assert((uint)($con$$constant) < Matcher::vector_length(this), "unsupported input lane_cnt");
4417       __ vid_v(as_VectorRegister($dst$$reg));
4418       __ vmsleu_vi(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), (uint)($con$$constant) - 1);
4419     }
4420   %}
4421   ins_pipe(pipe_slow);
4422 %}
4423 
4424 instruct vmaskAll_immI(vRegMask dst, immI src) %{
4425   match(Set dst (MaskAll src));
4426   format %{ "vmaskAll_immI $dst, $src" %}
4427   ins_encode %{
4428     BasicType bt = Matcher::vector_element_basic_type(this);
4429     __ vsetvli_helper(bt, Matcher::vector_length(this));
4430     int con = (int)$src$$constant;
4431     if (con == 0) {
4432       __ vmclr_m(as_VectorRegister($dst$$reg));
4433     } else {
4434       assert(con == -1, "invalid constant value for mask");
4435       __ vmset_m(as_VectorRegister($dst$$reg));
4436     }
4437   %}
4438   ins_pipe(pipe_slow);
4439 %}
4440 
4441 instruct vmaskAllI(vRegMask dst, iRegIorL2I src) %{
4442   match(Set dst (MaskAll src));
4443   format %{ "vmaskAllI $dst, $src" %}
4444   ins_encode %{
4445     BasicType bt = Matcher::vector_element_basic_type(this);
4446     __ vsetvli_helper(bt, Matcher::vector_length(this));
4447     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
4448     __ vmsne_vx(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), zr);
4449   %}
4450   ins_pipe(pipe_slow);
4451 %}
4452 
4453 instruct vmaskAll_immL(vRegMask dst, immL src) %{
4454   match(Set dst (MaskAll src));
4455   format %{ "vmaskAll_immL $dst, $src" %}
4456   ins_encode %{
4457     BasicType bt = Matcher::vector_element_basic_type(this);
4458     __ vsetvli_helper(bt, Matcher::vector_length(this));
4459     long con = (long)$src$$constant;
4460     if (con == 0) {
4461       __ vmclr_m(as_VectorRegister($dst$$reg));
4462     } else {
4463       assert(con == -1, "invalid constant value for mask");
4464       __ vmset_m(as_VectorRegister($dst$$reg));
4465     }
4466   %}
4467   ins_pipe(pipe_slow);
4468 %}
4469 
4470 instruct vmaskAllL(vRegMask dst, iRegL src) %{
4471   match(Set dst (MaskAll src));
4472   format %{ "vmaskAllL $dst, $src" %}
4473   ins_encode %{
4474     BasicType bt = Matcher::vector_element_basic_type(this);
4475     __ vsetvli_helper(bt, Matcher::vector_length(this));
4476     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg));
4477     __ vmsne_vx(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), zr);
4478   %}
4479   ins_pipe(pipe_slow);
4480 %}
4481 
4482 // ------------------------------ Vector mask basic OPs ------------------------
4483 
4484 // vector mask logical ops: and/or/xor
4485 
4486 instruct vmask_and(vRegMask dst, vRegMask src1, vRegMask src2) %{
4487   match(Set dst (AndVMask src1 src2));
4488   format %{ "vmask_and $dst, $src1, $src2" %}
4489   ins_encode %{
4490     BasicType bt = Matcher::vector_element_basic_type(this);
4491     __ vsetvli_helper(bt, Matcher::vector_length(this));
4492     __ vmand_mm(as_VectorRegister($dst$$reg),
4493                 as_VectorRegister($src1$$reg),
4494                 as_VectorRegister($src2$$reg));
4495   %}
4496   ins_pipe(pipe_slow);
4497 %}
4498 
4499 instruct vmask_or(vRegMask dst, vRegMask src1, vRegMask src2) %{
4500   match(Set dst (OrVMask src1 src2));
4501   format %{ "vmask_or $dst, $src1, $src2" %}
4502   ins_encode %{
4503     BasicType bt = Matcher::vector_element_basic_type(this);
4504     __ vsetvli_helper(bt, Matcher::vector_length(this));
4505     __ vmor_mm(as_VectorRegister($dst$$reg),
4506                as_VectorRegister($src1$$reg),
4507                as_VectorRegister($src2$$reg));
4508   %}
4509   ins_pipe(pipe_slow);
4510 %}
4511 
4512 instruct vmask_xor(vRegMask dst, vRegMask src1, vRegMask src2) %{
4513   match(Set dst (XorVMask src1 src2));
4514   format %{ "vmask_xor $dst, $src1, $src2" %}
4515   ins_encode %{
4516     BasicType bt = Matcher::vector_element_basic_type(this);
4517     __ vsetvli_helper(bt, Matcher::vector_length(this));
4518     __ vmxor_mm(as_VectorRegister($dst$$reg),
4519                 as_VectorRegister($src1$$reg),
4520                 as_VectorRegister($src2$$reg));
4521   %}
4522   ins_pipe(pipe_slow);
4523 %}
4524 
4525 instruct vmaskcast(vRegMask dst_src) %{
4526   match(Set dst_src (VectorMaskCast dst_src));
4527   ins_cost(0);
4528   format %{ "vmaskcast $dst_src, $dst_src\t# do nothing" %}
4529   ins_encode(/* empty encoding */);
4530   ins_pipe(pipe_class_empty);
4531 %}
4532 
4533 // vector load/store - predicated
4534 
4535 instruct loadV_masked(vReg dst, vmemA mem, vRegMask_V0 v0) %{
4536   match(Set dst (LoadVectorMasked mem v0));
4537   format %{ "loadV_masked $dst, $mem, $v0" %}
4538   ins_encode %{
4539     VectorRegister dst_reg = as_VectorRegister($dst$$reg);
4540     loadStore(masm, false, dst_reg,
4541               Matcher::vector_element_basic_type(this), as_Register($mem$$base),
4542               Matcher::vector_length(this), Assembler::v0_t);
4543   %}
4544   ins_pipe(pipe_slow);
4545 %}
4546 
4547 instruct storeV_masked(vReg src, vmemA mem, vRegMask_V0 v0) %{
4548   match(Set mem (StoreVectorMasked mem (Binary src v0)));
4549   format %{ "storeV_masked $mem, $src, $v0" %}
4550   ins_encode %{
4551     VectorRegister src_reg = as_VectorRegister($src$$reg);
4552     loadStore(masm, true, src_reg,
4553               Matcher::vector_element_basic_type(this, $src), as_Register($mem$$base),
4554               Matcher::vector_length(this, $src), Assembler::v0_t);
4555   %}
4556   ins_pipe(pipe_slow);
4557 %}
4558 
4559 // ------------------------------ Vector blend ---------------------------------
4560 
4561 instruct vblend(vReg dst, vReg src1, vReg src2, vRegMask_V0 v0) %{
4562   match(Set dst (VectorBlend (Binary src1 src2) v0));
4563   format %{ "vblend $dst, $src1, $src2, v0" %}
4564   ins_encode %{
4565     BasicType bt = Matcher::vector_element_basic_type(this);
4566     __ vsetvli_helper(bt, Matcher::vector_length(this));
4567     __ vmerge_vvm(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
4568                   as_VectorRegister($src2$$reg));
4569   %}
4570   ins_pipe(pipe_slow);
4571 %}
4572 
4573 // ------------------------------ Vector cast ----------------------------------
4574 
4575 // VectorCastB2X, VectorUCastB2X
4576 
4577 instruct vcvtBtoX(vReg dst, vReg src) %{
4578   match(Set dst (VectorCastB2X src));
4579   effect(TEMP_DEF dst);
4580   format %{ "vcvtBtoX $dst, $src" %}
4581   ins_encode %{
4582     BasicType bt = Matcher::vector_element_basic_type(this);
4583     if (is_floating_point_type(bt)) {
4584       __ integer_extend_v(as_VectorRegister($dst$$reg), bt == T_FLOAT ? T_INT : T_LONG,
4585                           Matcher::vector_length(this), as_VectorRegister($src$$reg), T_BYTE,
4586                           true /* is_signed */);
4587       __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg));
4588     } else {
4589       __ integer_extend_v(as_VectorRegister($dst$$reg), bt,
4590                           Matcher::vector_length(this), as_VectorRegister($src$$reg), T_BYTE,
4591                           true /* is_signed */);
4592     }
4593   %}
4594   ins_pipe(pipe_slow);
4595 %}
4596 
4597 instruct vcvtUBtoX(vReg dst, vReg src) %{
4598   predicate(Matcher::vector_element_basic_type(n) == T_SHORT ||
4599             Matcher::vector_element_basic_type(n) == T_INT ||
4600             Matcher::vector_element_basic_type(n) == T_LONG);
4601   match(Set dst (VectorUCastB2X src));
4602   effect(TEMP_DEF dst);
4603   format %{ "vcvtUBtoX $dst, $src" %}
4604   ins_encode %{
4605     BasicType bt = Matcher::vector_element_basic_type(this);
4606     __ integer_extend_v(as_VectorRegister($dst$$reg), bt,
4607                         Matcher::vector_length(this), as_VectorRegister($src$$reg), T_BYTE,
4608                         false /* is_signed */);
4609   %}
4610   ins_pipe(pipe_slow);
4611 %}
4612 
4613 // VectorCastS2X, VectorUCastS2X
4614 
4615 instruct vcvtStoB(vReg dst, vReg src) %{
4616   predicate(Matcher::vector_element_basic_type(n) == T_BYTE);
4617   match(Set dst (VectorCastS2X src));
4618   format %{ "vcvtStoB $dst, $src" %}
4619   ins_encode %{
4620     __ integer_narrow_v(as_VectorRegister($dst$$reg), T_BYTE, Matcher::vector_length(this),
4621                         as_VectorRegister($src$$reg), T_SHORT);
4622   %}
4623   ins_pipe(pipe_slow);
4624 %}
4625 
4626 instruct vcvtStoX(vReg dst, vReg src) %{
4627   predicate(Matcher::vector_element_basic_type(n) == T_INT ||
4628             Matcher::vector_element_basic_type(n) == T_LONG);
4629   match(Set dst (VectorCastS2X src));
4630   effect(TEMP_DEF dst);
4631   format %{ "vcvtStoX $dst, $src" %}
4632   ins_encode %{
4633     __ integer_extend_v(as_VectorRegister($dst$$reg), Matcher::vector_element_basic_type(this),
4634                         Matcher::vector_length(this), as_VectorRegister($src$$reg), T_SHORT,
4635                         true /* is_signed */);
4636   %}
4637   ins_pipe(pipe_slow);
4638 %}
4639 
4640 instruct vcvtStoX_fp(vReg dst, vReg src) %{
4641   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT ||
4642             Matcher::vector_element_basic_type(n) == T_DOUBLE);
4643   match(Set dst (VectorCastS2X src));
4644   effect(TEMP_DEF dst);
4645   format %{ "vcvtStoX_fp $dst, $src" %}
4646   ins_encode %{
4647     BasicType bt = Matcher::vector_element_basic_type(this);
4648     __ integer_extend_v(as_VectorRegister($dst$$reg), (bt == T_FLOAT ? T_INT : T_LONG),
4649                         Matcher::vector_length(this), as_VectorRegister($src$$reg), T_SHORT,
4650                         true /* is_signed */);
4651     __ vsetvli_helper(bt, Matcher::vector_length(this));
4652     __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg));
4653   %}
4654   ins_pipe(pipe_slow);
4655 %}
4656 
4657 
4658 instruct vcvtUStoX(vReg dst, vReg src) %{
4659   predicate(Matcher::vector_element_basic_type(n) == T_INT ||
4660             Matcher::vector_element_basic_type(n) == T_LONG);
4661   match(Set dst (VectorUCastS2X src));
4662   effect(TEMP_DEF dst);
4663   format %{ "vcvtUStoX $dst, $src" %}
4664   ins_encode %{
4665     __ integer_extend_v(as_VectorRegister($dst$$reg), Matcher::vector_element_basic_type(this),
4666                         Matcher::vector_length(this), as_VectorRegister($src$$reg), T_SHORT,
4667                         false /* is_signed */);
4668   %}
4669   ins_pipe(pipe_slow);
4670 %}
4671 
4672 // VectorCastI2X, VectorUCastI2X
4673 
4674 instruct vcvtItoX_narrow(vReg dst, vReg src) %{
4675   predicate((Matcher::vector_element_basic_type(n) == T_BYTE ||
4676              Matcher::vector_element_basic_type(n) == T_SHORT));
4677   match(Set dst (VectorCastI2X src));
4678   format %{ "vcvtItoX_narrow $dst, $src" %}
4679   ins_encode %{
4680     BasicType bt = Matcher::vector_element_basic_type(this);
4681     __ integer_narrow_v(as_VectorRegister($dst$$reg), bt, Matcher::vector_length(this),
4682                         as_VectorRegister($src$$reg), T_INT);
4683   %}
4684   ins_pipe(pipe_slow);
4685 %}
4686 
4687 instruct vcvtItoL(vReg dst, vReg src) %{
4688   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
4689   match(Set dst (VectorCastI2X src));
4690   effect(TEMP_DEF dst);
4691   format %{ "vcvtItoL $dst, $src" %}
4692   ins_encode %{
4693     __ integer_extend_v(as_VectorRegister($dst$$reg), T_LONG,
4694                         Matcher::vector_length(this), as_VectorRegister($src$$reg), T_INT,
4695                         true /* is_signed */);
4696   %}
4697   ins_pipe(pipe_slow);
4698 %}
4699 
4700 instruct vcvtUItoL(vReg dst, vReg src) %{
4701   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
4702   match(Set dst (VectorUCastI2X src));
4703   effect(TEMP_DEF dst);
4704   format %{ "vcvtUItoL $dst, $src" %}
4705   ins_encode %{
4706     __ integer_extend_v(as_VectorRegister($dst$$reg), T_LONG,
4707                         Matcher::vector_length(this), as_VectorRegister($src$$reg), T_INT,
4708                         false /* is_signed */);
4709   %}
4710   ins_pipe(pipe_slow);
4711 %}
4712 
4713 instruct vcvtItoF(vReg dst, vReg src) %{
4714   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT);
4715   match(Set dst (VectorCastI2X src));
4716   format %{ "vcvtItoF $dst, $src" %}
4717   ins_encode %{
4718     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this));
4719     __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4720   %}
4721   ins_pipe(pipe_slow);
4722 %}
4723 
4724 instruct vcvtItoD(vReg dst, vReg src) %{
4725   predicate(Matcher::vector_element_basic_type(n) == T_DOUBLE);
4726   match(Set dst (VectorCastI2X src));
4727   effect(TEMP_DEF dst);
4728   format %{ "vcvtItoD $dst, $src" %}
4729   ins_encode %{
4730     __ vsetvli_helper(T_INT, Matcher::vector_length(this), Assembler::mf2);
4731     __ vfwcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4732   %}
4733   ins_pipe(pipe_slow);
4734 %}
4735 
4736 // VectorCastL2X
4737 
4738 instruct vcvtLtoI(vReg dst, vReg src) %{
4739   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
4740             Matcher::vector_element_basic_type(n) == T_SHORT ||
4741             Matcher::vector_element_basic_type(n) == T_INT);
4742   match(Set dst (VectorCastL2X src));
4743   format %{ "vcvtLtoI $dst, $src" %}
4744   ins_encode %{
4745     BasicType bt = Matcher::vector_element_basic_type(this);
4746     __ integer_narrow_v(as_VectorRegister($dst$$reg), bt, Matcher::vector_length(this),
4747                         as_VectorRegister($src$$reg), T_LONG);
4748   %}
4749   ins_pipe(pipe_slow);
4750 %}
4751 
4752 instruct vcvtLtoF(vReg dst, vReg src) %{
4753   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT);
4754   match(Set dst (VectorCastL2X src));
4755   format %{ "vcvtLtoF $dst, $src" %}
4756   ins_encode %{
4757     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this), Assembler::mf2);
4758     __ vfncvt_f_x_w(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4759   %}
4760   ins_pipe(pipe_slow);
4761 %}
4762 
4763 instruct vcvtLtoD(vReg dst, vReg src) %{
4764   predicate(Matcher::vector_element_basic_type(n) == T_DOUBLE);
4765   match(Set dst (VectorCastL2X src));
4766   format %{ "vcvtLtoD $dst, $src" %}
4767   ins_encode %{
4768     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this));
4769     __ vfcvt_f_x_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4770   %}
4771   ins_pipe(pipe_slow);
4772 %}
4773 
4774 // VectorCastF2X
4775 
4776 instruct vcvtFtoX_narrow(vReg dst, vReg src, vRegMask_V0 v0) %{
4777   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
4778             Matcher::vector_element_basic_type(n) == T_SHORT);
4779   match(Set dst (VectorCastF2X src));
4780   effect(TEMP_DEF dst, TEMP v0);
4781   format %{ "vcvtFtoX_narrow $dst, $src" %}
4782   ins_encode %{
4783     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this));
4784     __ vfcvt_rtz_x_f_v_safe(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4785     BasicType bt = Matcher::vector_element_basic_type(this);
4786     __ integer_narrow_v(as_VectorRegister($dst$$reg), bt, Matcher::vector_length(this),
4787                         as_VectorRegister($dst$$reg), T_INT);
4788   %}
4789   ins_pipe(pipe_slow);
4790 %}
4791 
4792 instruct vcvtFtoI(vReg dst, vReg src, vRegMask_V0 v0) %{
4793   predicate(Matcher::vector_element_basic_type(n) == T_INT);
4794   match(Set dst (VectorCastF2X src));
4795   effect(TEMP_DEF dst, TEMP v0);
4796   format %{ "vcvtFtoI $dst, $src" %}
4797   ins_encode %{
4798     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this));
4799     __ vfcvt_rtz_x_f_v_safe(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4800   %}
4801   ins_pipe(pipe_slow);
4802 %}
4803 
4804 instruct vcvtFtoL(vReg dst, vReg src, vRegMask_V0 v0) %{
4805   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
4806   match(Set dst (VectorCastF2X src));
4807   effect(TEMP_DEF dst, TEMP v0);
4808   format %{ "vcvtFtoL $dst, $src" %}
4809   ins_encode %{
4810     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
4811     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg));
4812     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this), Assembler::mf2);
4813     __ vmfeq_vv(as_VectorRegister($v0$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg));
4814     __ vfwcvt_rtz_x_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), Assembler::v0_t);
4815   %}
4816   ins_pipe(pipe_slow);
4817 %}
4818 
4819 instruct vcvtFtoD(vReg dst, vReg src) %{
4820   predicate(Matcher::vector_element_basic_type(n) == T_DOUBLE);
4821   match(Set dst (VectorCastF2X src));
4822   effect(TEMP_DEF dst);
4823   format %{ "vcvtFtoD $dst, $src" %}
4824   ins_encode %{
4825     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this), Assembler::mf2);
4826     __ vfwcvt_f_f_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4827   %}
4828   ins_pipe(pipe_slow);
4829 %}
4830 
4831 // VectorCastD2X
4832 
4833 instruct vcvtDtoX_narrow(vReg dst, vReg src, vRegMask_V0 v0) %{
4834   predicate(Matcher::vector_element_basic_type(n) == T_BYTE ||
4835             Matcher::vector_element_basic_type(n) == T_SHORT ||
4836             Matcher::vector_element_basic_type(n) == T_INT);
4837   match(Set dst (VectorCastD2X src));
4838   effect(TEMP_DEF dst, TEMP v0);
4839   format %{ "vcvtDtoX_narrow $dst, $src" %}
4840   ins_encode %{
4841     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this));
4842     __ vmfeq_vv(as_VectorRegister($v0$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg));
4843     __ vsetvli_helper(T_INT, Matcher::vector_length(this), Assembler::mf2);
4844     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg));
4845     __ vfncvt_rtz_x_f_w(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), Assembler::v0_t);
4846     BasicType bt = Matcher::vector_element_basic_type(this);
4847     if (bt == T_BYTE || bt == T_SHORT) {
4848       __ integer_narrow_v(as_VectorRegister($dst$$reg), bt, Matcher::vector_length(this),
4849                           as_VectorRegister($dst$$reg), T_INT);
4850     }
4851   %}
4852   ins_pipe(pipe_slow);
4853 %}
4854 
4855 instruct vcvtDtoL(vReg dst, vReg src, vRegMask_V0 v0) %{
4856   predicate(Matcher::vector_element_basic_type(n) == T_LONG);
4857   match(Set dst (VectorCastD2X src));
4858   effect(TEMP_DEF dst, TEMP v0);
4859   format %{ "vcvtDtoL $dst, $src" %}
4860   ins_encode %{
4861     __ vsetvli_helper(T_LONG, Matcher::vector_length(this));
4862     __ vfcvt_rtz_x_f_v_safe(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4863   %}
4864   ins_pipe(pipe_slow);
4865 %}
4866 
4867 instruct vcvtDtoF(vReg dst, vReg src) %{
4868   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT);
4869   match(Set dst (VectorCastD2X src));
4870   format %{ "vcvtDtoF $dst, $src" %}
4871   ins_encode %{
4872     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this), Assembler::mf2);
4873     __ vfncvt_f_f_w(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4874   %}
4875   ins_pipe(pipe_slow);
4876 %}
4877 
4878 // ------------------------------ Vector reinterpret ---------------------------
4879 
4880 instruct reinterpret(vReg dst_src) %{
4881   predicate(Matcher::vector_length_in_bytes(n) == Matcher::vector_length_in_bytes(n->in(1)));
4882   match(Set dst_src (VectorReinterpret dst_src));
4883   ins_cost(0);
4884   format %{ "# reinterpret $dst_src, $dst_src\t# do nothing" %}
4885   ins_encode %{
4886     // empty
4887   %}
4888   ins_pipe(pipe_class_empty);
4889 %}
4890 
4891 instruct reinterpretResize(vReg dst, vReg src) %{
4892   predicate(Matcher::vector_length_in_bytes(n) != Matcher::vector_length_in_bytes(n->in(1)));
4893   match(Set dst (VectorReinterpret src));
4894   effect(TEMP_DEF dst);
4895   format %{ "reinterpretResize $dst, $src" %}
4896   ins_encode %{
4897     uint length_in_bytes_src = Matcher::vector_length_in_bytes(this, $src);
4898     uint length_in_bytes_dst = Matcher::vector_length_in_bytes(this);
4899     uint length_in_bytes_resize = length_in_bytes_src < length_in_bytes_dst ?
4900                                   length_in_bytes_src : length_in_bytes_dst;
4901     assert(length_in_bytes_src <= MaxVectorSize && length_in_bytes_dst <= MaxVectorSize,
4902            "invalid vector length");
4903     BasicType bt = Matcher::vector_element_basic_type(this);
4904     __ vsetvli_helper(bt, Matcher::vector_length(this));
4905     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg));
4906     __ vsetvli_helper(T_BYTE, length_in_bytes_resize);
4907     __ vmv_v_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
4908   %}
4909   ins_pipe(pipe_slow);
4910 %}
4911 
4912 // vector mask reinterpret
4913 
4914 instruct vmask_reinterpret_same_esize(vRegMask dst_src) %{
4915   predicate(Matcher::vector_length(n) == Matcher::vector_length(n->in(1)) &&
4916             Matcher::vector_length_in_bytes(n) == Matcher::vector_length_in_bytes(n->in(1)));
4917   match(Set dst_src (VectorReinterpret dst_src));
4918   ins_cost(0);
4919   format %{ "vmask_reinterpret_same_esize $dst_src, $dst_src\t# do nothing" %}
4920   ins_encode(/* empty encoding */);
4921   ins_pipe(pipe_class_empty);
4922 %}
4923 
4924 instruct vmask_reinterpret_diff_esize(vRegMask dst, vRegMask_V0 src, vReg tmp) %{
4925   predicate(Matcher::vector_length(n) != Matcher::vector_length(n->in(1)) &&
4926             Matcher::vector_length_in_bytes(n) == Matcher::vector_length_in_bytes(n->in(1)));
4927   match(Set dst (VectorReinterpret src));
4928   effect(TEMP tmp);
4929   format %{ "vmask_reinterpret_diff_esize $dst, $src\t# KILL $tmp" %}
4930   ins_encode %{
4931     BasicType from_bt = Matcher::vector_element_basic_type(this, $src);
4932     __ vsetvli_helper(from_bt, Matcher::vector_length(this, $src));
4933     __ vxor_vv(as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg));
4934     __ vmerge_vim(as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg), -1);
4935     BasicType to_bt = Matcher::vector_element_basic_type(this);
4936     __ vsetvli_helper(to_bt, Matcher::vector_length(this));
4937     __ vmseq_vi(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), -1);
4938   %}
4939   ins_pipe(pipe_slow);
4940 %}
4941 
4942 // ------------------------------ Vector selectFrom -----------------------------
4943 
4944 instruct select_from_two_vectors(vReg dst, vReg src1, vReg src2, vReg index, vRegMask_V0 v0, vReg tmp) %{
4945   match(Set dst (SelectFromTwoVector (Binary index src1) src2));
4946   effect(TEMP_DEF dst, TEMP v0, TEMP tmp);
4947   format %{ "select_from_two_vectors $dst, $src1, $src2, $index" %}
4948   ins_encode %{
4949     BasicType bt = Matcher::vector_element_basic_type(this);
4950     __ vsetvli_helper(bt, Matcher::vector_length(this));
4951     __ vrgather_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg),
4952                    as_VectorRegister($index$$reg));
4953     bool use_imm = __ is_simm5(Matcher::vector_length(this) - 1);
4954     if (use_imm) {
4955       __ vmsgtu_vi(v0, as_VectorRegister($index$$reg), Matcher::vector_length(this) - 1);
4956       __ vadd_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($index$$reg),
4957                  -Matcher::vector_length(this), Assembler::v0_t);
4958     } else {
4959       __ mv(t0, Matcher::vector_length(this) - 1);
4960       __ vmsgtu_vx(v0, as_VectorRegister($index$$reg), t0);
4961       __ mv(t0, -Matcher::vector_length(this));
4962       __ vadd_vx(as_VectorRegister($tmp$$reg), as_VectorRegister($index$$reg), t0, Assembler::v0_t);
4963     }
4964     __ vrgather_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src2$$reg),
4965                    as_VectorRegister($tmp$$reg), Assembler::v0_t);
4966   %}
4967   ins_pipe(pipe_slow);
4968 %}
4969 
4970 // ------------------------------ Vector rearrange -----------------------------
4971 
4972 instruct rearrange(vReg dst, vReg src, vReg shuffle) %{
4973   match(Set dst (VectorRearrange src shuffle));
4974   effect(TEMP_DEF dst);
4975   format %{ "rearrange $dst, $src, $shuffle" %}
4976   ins_encode %{
4977     BasicType bt = Matcher::vector_element_basic_type(this);
4978     __ vsetvli_helper(bt, Matcher::vector_length(this));
4979     __ vrgather_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
4980                    as_VectorRegister($shuffle$$reg));
4981   %}
4982   ins_pipe(pipe_slow);
4983 %}
4984 
4985 instruct rearrange_masked(vReg dst, vReg src, vReg shuffle, vRegMask_V0 v0) %{
4986   match(Set dst (VectorRearrange (Binary src shuffle) v0));
4987   effect(TEMP_DEF dst);
4988   format %{ "rearrange_masked $dst, $src, $shuffle, $v0" %}
4989   ins_encode %{
4990     BasicType bt = Matcher::vector_element_basic_type(this);
4991     __ vsetvli_helper(bt, Matcher::vector_length(this));
4992     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg),
4993                as_VectorRegister($dst$$reg));
4994     __ vrgather_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
4995                    as_VectorRegister($shuffle$$reg), Assembler::v0_t);
4996   %}
4997   ins_pipe(pipe_slow);
4998 %}
4999 
5000 // ------------------------------ Vector extract ---------------------------------
5001 
5002 instruct extract(iRegINoSp dst, vReg src, immI idx, vReg tmp)
5003 %{
5004   match(Set dst (ExtractB src idx));
5005   match(Set dst (ExtractS src idx));
5006   match(Set dst (ExtractI src idx));
5007   effect(TEMP tmp);
5008   format %{ "extract $dst, $src, $idx\t# KILL $tmp" %}
5009   ins_encode %{
5010     __ extract_v($dst$$Register, as_VectorRegister($src$$reg),
5011                  Matcher::vector_element_basic_type(this, $src), (int)($idx$$constant),
5012                  as_VectorRegister($tmp$$reg));
5013   %}
5014   ins_pipe(pipe_slow);
5015 %}
5016 
5017 instruct extractL(iRegLNoSp dst, vReg src, immI idx, vReg tmp)
5018 %{
5019   match(Set dst (ExtractL src idx));
5020   effect(TEMP tmp);
5021   format %{ "extractL $dst, $src, $idx\t# KILL $tmp" %}
5022   ins_encode %{
5023     __ extract_v($dst$$Register, as_VectorRegister($src$$reg), T_LONG,
5024                  (int)($idx$$constant), as_VectorRegister($tmp$$reg));
5025   %}
5026   ins_pipe(pipe_slow);
5027 %}
5028 
5029 
5030 instruct extractF(fRegF dst, vReg src, immI idx, vReg tmp)
5031 %{
5032   match(Set dst (ExtractF src idx));
5033   effect(TEMP tmp);
5034   format %{ "extractF $dst, $src, $idx\t# KILL $tmp" %}
5035   ins_encode %{
5036     __ extract_fp_v($dst$$FloatRegister, as_VectorRegister($src$$reg), T_FLOAT,
5037                     (int)($idx$$constant), as_VectorRegister($tmp$$reg));
5038   %}
5039   ins_pipe(pipe_slow);
5040 %}
5041 
5042 instruct extractD(fRegD dst, vReg src, immI idx, vReg tmp)
5043 %{
5044   match(Set dst (ExtractD src idx));
5045   effect(TEMP tmp);
5046   format %{ "extractD $dst, $src, $idx\t# KILL $tmp" %}
5047   ins_encode %{
5048     __ extract_fp_v($dst$$FloatRegister, as_VectorRegister($src$$reg), T_DOUBLE,
5049                     (int)($idx$$constant), as_VectorRegister($tmp$$reg));
5050   %}
5051   ins_pipe(pipe_slow);
5052 %}
5053 
5054 // ------------------------------ Compress/Expand Operations -------------------
5055 
5056 instruct mcompress(vRegMask dst, vRegMask src, vReg tmp) %{
5057   match(Set dst (CompressM src));
5058   effect(TEMP tmp);
5059   format %{ "mcompress $dst, $src\t# KILL $tmp" %}
5060   ins_encode %{
5061     BasicType bt = Matcher::vector_element_basic_type(this);
5062     __ vsetvli_helper(bt, Matcher::vector_length(this));
5063     __ vid_v(as_VectorRegister($tmp$$reg));
5064     __ vcpop_m(t0, as_VectorRegister($src$$reg));
5065     __ vmsltu_vx(as_VectorRegister($dst$$reg), as_VectorRegister($tmp$$reg), t0);
5066   %}
5067   ins_pipe(pipe_slow);
5068 %}
5069 
5070 instruct vcompress(vReg dst, vReg src, vRegMask_V0 v0) %{
5071   match(Set dst (CompressV src v0));
5072   effect(TEMP_DEF dst);
5073   format %{ "vcompress $dst, $src, $v0" %}
5074   ins_encode %{
5075     BasicType bt = Matcher::vector_element_basic_type(this);
5076     __ vsetvli_helper(bt, Matcher::vector_length(this));
5077     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg),
5078                as_VectorRegister($dst$$reg));
5079     __ vcompress_vm(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
5080                     as_VectorRegister($v0$$reg));
5081   %}
5082   ins_pipe(pipe_slow);
5083 %}
5084 
5085 instruct vexpand(vReg dst, vReg src, vRegMask_V0 v0, vReg tmp) %{
5086   match(Set dst (ExpandV src v0));
5087   effect(TEMP_DEF dst, TEMP tmp);
5088   format %{ "vexpand $dst, $src, $v0\t# KILL $tmp" %}
5089   ins_encode %{
5090     BasicType bt = Matcher::vector_element_basic_type(this);
5091     __ vsetvli_helper(bt, Matcher::vector_length(this));
5092     __ viota_m(as_VectorRegister($tmp$$reg), as_VectorRegister($v0$$reg));
5093     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg),
5094                as_VectorRegister($dst$$reg));
5095     __ vrgather_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
5096                    as_VectorRegister($tmp$$reg), Assembler::v0_t);
5097   %}
5098   ins_pipe(pipe_slow);
5099 %}
5100 
5101 // ------------------------------ Vector signum --------------------------------
5102 
5103 // Vector Math.signum
5104 
5105 instruct vsignum_reg(vReg dst, vReg zero, vReg one, vRegMask_V0 v0) %{
5106   match(Set dst (SignumVF dst (Binary zero one)));
5107   match(Set dst (SignumVD dst (Binary zero one)));
5108   effect(TEMP_DEF dst, TEMP v0);
5109   format %{ "vsignum $dst, $dst\t" %}
5110   ins_encode %{
5111     BasicType bt = Matcher::vector_element_basic_type(this);
5112     __ signum_fp_v(as_VectorRegister($dst$$reg), as_VectorRegister($one$$reg),
5113                    bt, Matcher::vector_length(this));
5114   %}
5115   ins_pipe(pipe_slow);
5116 %}
5117 
5118 // ---------------- Round float/double Vector Operations ----------------
5119 
5120 instruct vround_f(vReg dst, vReg src, fRegF tmp, vRegMask_V0 v0) %{
5121   match(Set dst (RoundVF src));
5122   effect(TEMP_DEF dst, TEMP tmp, TEMP v0);
5123   format %{ "java_round_float_v $dst, $src\t" %}
5124   ins_encode %{
5125     BasicType bt = Matcher::vector_element_basic_type(this);
5126     uint vector_length = Matcher::vector_length(this);
5127     __ java_round_float_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
5128                           as_FloatRegister($tmp$$reg), bt, vector_length);
5129   %}
5130   ins_pipe(pipe_slow);
5131 %}
5132 
5133 instruct vround_d(vReg dst, vReg src, fRegD tmp, vRegMask_V0 v0) %{
5134   match(Set dst (RoundVD src));
5135   effect(TEMP_DEF dst, TEMP tmp, TEMP v0);
5136   format %{ "java_round_double_v $dst, $src\t" %}
5137   ins_encode %{
5138     BasicType bt = Matcher::vector_element_basic_type(this);
5139     uint vector_length = Matcher::vector_length(this);
5140     __ java_round_double_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
5141                            as_FloatRegister($tmp$$reg), bt, vector_length);
5142   %}
5143   ins_pipe(pipe_slow);
5144 %}
5145 
5146 // -------------------------------- Reverse Bits Vector Operations ------------------------
5147 
5148 instruct vreverse_masked(vReg dst_src, vRegMask_V0 v0) %{
5149   match(Set dst_src (ReverseV dst_src v0));
5150   format %{ "vreverse_masked $dst_src, $dst_src, v0" %}
5151   ins_encode %{
5152     BasicType bt = Matcher::vector_element_basic_type(this);
5153     uint vlen = Matcher::vector_length(this);
5154     __ vsetvli_helper(bt, vlen);
5155     __ vbrev_v(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), Assembler::v0_t);
5156   %}
5157   ins_pipe(pipe_slow);
5158 %}
5159 
5160 instruct vreverse(vReg dst, vReg src) %{
5161   match(Set dst (ReverseV src));
5162   format %{ "vreverse $dst, $src" %}
5163   ins_encode %{
5164     BasicType bt = Matcher::vector_element_basic_type(this);
5165     uint vlen = Matcher::vector_length(this);
5166     __ vsetvli_helper(bt, vlen);
5167     __ vbrev_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
5168   %}
5169   ins_pipe(pipe_slow);
5170 %}
5171 
5172 // -------------------------------- Reverse Bytes Vector Operations ------------------------
5173 
5174 instruct vreverse_bytes_masked(vReg dst_src, vRegMask_V0 v0) %{
5175   match(Set dst_src (ReverseBytesV dst_src v0));
5176   format %{ "vreverse_bytes_masked $dst_src, $dst_src, v0" %}
5177   ins_encode %{
5178     BasicType bt = Matcher::vector_element_basic_type(this);
5179     uint vlen = Matcher::vector_length(this);
5180     __ vsetvli_helper(bt, vlen);
5181     __ vrev8_v(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), Assembler::v0_t);
5182   %}
5183   ins_pipe(pipe_slow);
5184 %}
5185 
5186 instruct vreverse_bytes(vReg dst, vReg src) %{
5187   match(Set dst (ReverseBytesV src));
5188   format %{ "vreverse_bytes $dst, $src" %}
5189   ins_encode %{
5190     BasicType bt = Matcher::vector_element_basic_type(this);
5191     uint vlen = Matcher::vector_length(this);
5192     __ vsetvli_helper(bt, vlen);
5193     __ vrev8_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
5194   %}
5195   ins_pipe(pipe_slow);
5196 %}
5197 
5198 // ---------------- Convert Half Floating to Floating Vector Operations ----------------
5199 
5200 // half precision -> single
5201 
5202 instruct vconvHF2F(vReg dst, vReg src, vRegMask_V0 v0) %{
5203   predicate(Matcher::vector_element_basic_type(n) == T_FLOAT);
5204   match(Set dst (VectorCastHF2F src));
5205   effect(TEMP_DEF dst, TEMP v0);
5206   format %{ "vfwcvt.f.f.v $dst, $src\t# convert half to single precision" %}
5207   ins_encode %{
5208     __ float16_to_float_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
5209                           Matcher::vector_length(this));
5210   %}
5211   ins_pipe(pipe_slow);
5212 %}
5213 
5214 // single precision -> half
5215 
5216 instruct vconvF2HF(vReg dst, vReg src, vReg vtmp, vRegMask_V0 v0, iRegINoSp tmp) %{
5217   predicate(Matcher::vector_element_basic_type(n) == T_SHORT);
5218   match(Set dst (VectorCastF2HF src));
5219   effect(TEMP_DEF dst, TEMP v0, TEMP vtmp, TEMP tmp);
5220   format %{ "vfncvt.f.f.w $dst, $src\t# convert single to half precision" %}
5221   ins_encode %{
5222     __ float_to_float16_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg),
5223                           as_VectorRegister($vtmp$$reg), $tmp$$Register,
5224                           Matcher::vector_length(this));
5225   %}
5226   ins_pipe(pipe_slow);
5227 %}
5228 
5229 
5230 // ------------------------------ Popcount vector ------------------------------
5231 
5232 instruct vpopcount_masked(vReg dst_src, vRegMask_V0 v0) %{
5233   match(Set dst_src (PopCountVI dst_src v0));
5234   match(Set dst_src (PopCountVL dst_src v0));
5235   format %{ "vcpop_v $dst_src, $dst_src, $v0\t# vcpop_v with mask" %}
5236   ins_encode %{
5237     BasicType bt = Matcher::vector_element_basic_type(this);
5238     uint vlen = Matcher::vector_length(this);
5239     __ vsetvli_helper(bt, vlen);
5240     __ vcpop_v(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), Assembler::v0_t);
5241   %}
5242   ins_pipe(pipe_slow);
5243 %}
5244 
5245 instruct vpopcount(vReg dst, vReg src) %{
5246   match(Set dst (PopCountVI src));
5247   match(Set dst (PopCountVL src));
5248   format %{ "vcpop_v $dst, $src\t# vcpop_v without mask" %}
5249   ins_encode %{
5250     BasicType bt = Matcher::vector_element_basic_type(this);
5251     uint vlen = Matcher::vector_length(this);
5252     __ vsetvli_helper(bt, vlen);
5253     __ vcpop_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
5254   %}
5255   ins_pipe(pipe_slow);
5256 %}
5257 
5258 // ------------------------------ CountLeadingZerosV --------------------------
5259 
5260 instruct vcountLeadingZeros_masked(vReg dst_src, vRegMask_V0 v0) %{
5261   match(Set dst_src (CountLeadingZerosV dst_src v0));
5262   format %{ "vcount_leading_zeros_masked $dst_src, $dst_src, v0" %}
5263   ins_encode %{
5264     BasicType bt = Matcher::vector_element_basic_type(this);
5265     uint vlen = Matcher::vector_length(this);
5266     __ vsetvli_helper(bt, vlen);
5267     __ vclz_v(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), Assembler::v0_t);
5268   %}
5269   ins_pipe(pipe_slow);
5270 %}
5271 
5272 instruct vcountLeadingZeros(vReg dst, vReg src) %{
5273   match(Set dst (CountLeadingZerosV src));
5274   format %{ "vcount_leading_zeros $dst, $src" %}
5275   ins_encode %{
5276     BasicType bt = Matcher::vector_element_basic_type(this);
5277     uint vlen = Matcher::vector_length(this);
5278     __ vsetvli_helper(bt, vlen);
5279     __ vclz_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
5280   %}
5281   ins_pipe(pipe_slow);
5282 %}
5283 
5284 // ------------------------------ CountTrailingZerosV --------------------------
5285 
5286 instruct vcountTrailingZeros_masked(vReg dst_src, vRegMask_V0 v0) %{
5287   match(Set dst_src (CountTrailingZerosV dst_src v0));
5288   format %{ "vcount_trailing_zeros_masked $dst_src, $dst_src, v0" %}
5289   ins_encode %{
5290     BasicType bt = Matcher::vector_element_basic_type(this);
5291     uint vlen = Matcher::vector_length(this);
5292     __ vsetvli_helper(bt, vlen);
5293     __ vctz_v(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), Assembler::v0_t);
5294   %}
5295   ins_pipe(pipe_slow);
5296 %}
5297 
5298 instruct vcountTrailingZeros(vReg dst, vReg src) %{
5299   match(Set dst (CountTrailingZerosV src));
5300   format %{ "vcount_trailing_zeros $dst, $src" %}
5301   ins_encode %{
5302     BasicType bt = Matcher::vector_element_basic_type(this);
5303     uint vlen = Matcher::vector_length(this);
5304     __ vsetvli_helper(bt, vlen);
5305     __ vctz_v(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg));
5306   %}
5307   ins_pipe(pipe_slow);
5308 %}
5309 
5310 // ------------------------------ Vector Load Gather ---------------------------
5311 
5312 instruct gather_loadS(vReg dst, indirect mem, vReg idx) %{
5313   predicate(type2aelembytes(Matcher::vector_element_basic_type(n)) == 4);
5314   match(Set dst (LoadVectorGather mem idx));
5315   effect(TEMP_DEF dst);
5316   format %{ "gather_loadS $dst, $mem, $idx" %}
5317   ins_encode %{
5318     BasicType bt = Matcher::vector_element_basic_type(this);
5319     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
5320     __ vsetvli_helper(bt, Matcher::vector_length(this));
5321     __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($idx$$reg), (int)sew);
5322     __ vluxei32_v(as_VectorRegister($dst$$reg), as_Register($mem$$base),
5323                   as_VectorRegister($dst$$reg));
5324  %}
5325   ins_pipe(pipe_slow);
5326 %}
5327 
5328 instruct gather_loadD(vReg dst, indirect mem, vReg idx) %{
5329   predicate(type2aelembytes(Matcher::vector_element_basic_type(n)) == 8);
5330   match(Set dst (LoadVectorGather mem idx));
5331   effect(TEMP_DEF dst);
5332   format %{ "gather_loadD $dst, $mem, $idx" %}
5333   ins_encode %{
5334     BasicType bt = Matcher::vector_element_basic_type(this);
5335     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
5336     __ vsetvli_helper(bt, Matcher::vector_length(this));
5337     __ vzext_vf2(as_VectorRegister($dst$$reg), as_VectorRegister($idx$$reg));
5338     __ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), (int)sew);
5339     __ vluxei64_v(as_VectorRegister($dst$$reg), as_Register($mem$$base),
5340                   as_VectorRegister($dst$$reg));
5341  %}
5342   ins_pipe(pipe_slow);
5343 %}
5344 
5345 instruct gather_loadS_masked(vReg dst, indirect mem, vReg idx, vRegMask_V0 v0, vReg tmp) %{
5346   predicate(type2aelembytes(Matcher::vector_element_basic_type(n)) == 4);
5347   match(Set dst (LoadVectorGatherMasked mem (Binary idx v0)));
5348   effect(TEMP_DEF dst, TEMP tmp);
5349   format %{ "gather_loadS_masked $dst, $mem, $idx, $v0\t# KILL $tmp" %}
5350   ins_encode %{
5351     BasicType bt = Matcher::vector_element_basic_type(this);
5352     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
5353     __ vsetvli_helper(bt, Matcher::vector_length(this));
5354     __ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg), (int)sew);
5355     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg),
5356                as_VectorRegister($dst$$reg));
5357     __ vluxei32_v(as_VectorRegister($dst$$reg), as_Register($mem$$base),
5358                   as_VectorRegister($tmp$$reg), Assembler::v0_t);
5359  %}
5360   ins_pipe(pipe_slow);
5361 %}
5362 
5363 instruct gather_loadD_masked(vReg dst, indirect mem, vReg idx, vRegMask_V0 v0, vReg tmp) %{
5364   predicate(type2aelembytes(Matcher::vector_element_basic_type(n)) == 8);
5365   match(Set dst (LoadVectorGatherMasked mem (Binary idx v0)));
5366   effect(TEMP_DEF dst, TEMP tmp);
5367   format %{ "gather_loadD_masked $dst, $mem, $idx, $v0\t# KILL $tmp" %}
5368   ins_encode %{
5369     BasicType bt = Matcher::vector_element_basic_type(this);
5370     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
5371     __ vsetvli_helper(bt, Matcher::vector_length(this));
5372     __ vzext_vf2(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg));
5373     __ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg), (int)sew);
5374     __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg),
5375                as_VectorRegister($dst$$reg));
5376     __ vluxei64_v(as_VectorRegister($dst$$reg), as_Register($mem$$base),
5377                   as_VectorRegister($tmp$$reg), Assembler::v0_t);
5378  %}
5379   ins_pipe(pipe_slow);
5380 %}
5381 
5382 // ------------------------------ Vector Store Scatter -------------------------
5383 
5384 instruct scatter_storeS(indirect mem, vReg src, vReg idx, vReg tmp) %{
5385   predicate(type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 4);
5386   match(Set mem (StoreVectorScatter mem (Binary src idx)));
5387   effect(TEMP tmp);
5388   format %{ "scatter_storeS $mem, $idx, $src\t# KILL $tmp" %}
5389   ins_encode %{
5390     BasicType bt = Matcher::vector_element_basic_type(this, $src);
5391     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
5392     __ vsetvli_helper(bt, Matcher::vector_length(this, $src));
5393     __ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg), (int)sew);
5394     __ vsuxei32_v(as_VectorRegister($src$$reg), as_Register($mem$$base),
5395                   as_VectorRegister($tmp$$reg));
5396   %}
5397   ins_pipe(pipe_slow);
5398 %}
5399 
5400 instruct scatter_storeD(indirect mem, vReg src, vReg idx, vReg tmp) %{
5401   predicate(type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 8);
5402   match(Set mem (StoreVectorScatter mem (Binary src idx)));
5403   effect(TEMP tmp);
5404   format %{ "scatter_storeD $mem, $idx, $src\t# KILL $tmp" %}
5405   ins_encode %{
5406     BasicType bt = Matcher::vector_element_basic_type(this, $src);
5407     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
5408     __ vsetvli_helper(bt, Matcher::vector_length(this, $src));
5409     __ vzext_vf2(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg));
5410     __ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg), (int)sew);
5411     __ vsuxei64_v(as_VectorRegister($src$$reg), as_Register($mem$$base),
5412                   as_VectorRegister($tmp$$reg));
5413   %}
5414   ins_pipe(pipe_slow);
5415 %}
5416 
5417 instruct scatter_storeS_masked(indirect mem, vReg src, vReg idx, vRegMask_V0 v0, vReg tmp) %{
5418   predicate(type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 4);
5419   match(Set mem (StoreVectorScatterMasked mem (Binary src (Binary idx v0))));
5420   effect(TEMP tmp);
5421   format %{ "scatter_storeS_masked $mem, $idx, $src, $v0\t# KILL $tmp" %}
5422   ins_encode %{
5423     BasicType bt = Matcher::vector_element_basic_type(this, $src);
5424     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
5425     __ vsetvli_helper(bt, Matcher::vector_length(this, $src));
5426     __ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg), (int)sew);
5427     __ vsuxei32_v(as_VectorRegister($src$$reg), as_Register($mem$$base),
5428                   as_VectorRegister($tmp$$reg), Assembler::v0_t);
5429   %}
5430   ins_pipe(pipe_slow);
5431 %}
5432 
5433 instruct scatter_storeD_masked(indirect mem, vReg src, vReg idx, vRegMask_V0 v0, vReg tmp) %{
5434   predicate(type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 8);
5435   match(Set mem (StoreVectorScatterMasked mem (Binary src (Binary idx v0))));
5436   effect(TEMP tmp);
5437   format %{ "scatter_storeD_masked $mem, $idx, $src, $v0\t# KILL $tmp" %}
5438   ins_encode %{
5439     BasicType bt = Matcher::vector_element_basic_type(this, $src);
5440     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
5441     __ vsetvli_helper(bt, Matcher::vector_length(this, $src));
5442     __ vzext_vf2(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg));
5443     __ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg), (int)sew);
5444     __ vsuxei64_v(as_VectorRegister($src$$reg), as_Register($mem$$base),
5445                   as_VectorRegister($tmp$$reg), Assembler::v0_t);
5446   %}
5447   ins_pipe(pipe_slow);
5448 %}
5449 
5450 // ------------------------------ Populate Index to a Vector -------------------
5451 
5452 instruct populateindex(vReg dst, iRegIorL2I src1, iRegIorL2I src2, vReg tmp) %{
5453   match(Set dst (PopulateIndex src1 src2));
5454   effect(TEMP_DEF dst, TEMP tmp);
5455   format %{ "populateindex $dst, $src1, $src2\t# KILL $tmp" %}
5456   ins_encode %{
5457     BasicType bt = Matcher::vector_element_basic_type(this);
5458     Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
5459     __ vsetvli_helper(bt, Matcher::vector_length(this));
5460     __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src1$$reg));
5461     __ vid_v(as_VectorRegister($tmp$$reg));
5462     __ vmacc_vx(as_VectorRegister($dst$$reg), as_Register($src2$$reg), as_VectorRegister($tmp$$reg));
5463   %}
5464   ins_pipe(pipe_slow);
5465 %}
5466 
5467 // ------------------------------ Vector insert --------------------------------
5468 
5469 // BYTE, SHORT, INT
5470 
5471 instruct insert_index_lt32(vReg dst, vReg src, iRegIorL2I val, immI idx, vRegMask_V0 v0) %{
5472   predicate(n->in(2)->get_int() < 32 &&
5473             (Matcher::vector_element_basic_type(n) == T_BYTE ||
5474              Matcher::vector_element_basic_type(n) == T_SHORT ||
5475              Matcher::vector_element_basic_type(n) == T_INT));
5476   match(Set dst (VectorInsert (Binary src val) idx));
5477   effect(TEMP v0);
5478   format %{ "insert_index_lt32 $dst, $src, $val, $idx" %}
5479   ins_encode %{
5480     BasicType bt = Matcher::vector_element_basic_type(this);
5481     __ vsetvli_helper(bt, Matcher::vector_length(this));
5482     __ vid_v(as_VectorRegister($v0$$reg));
5483     __ vadd_vi(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), -16);
5484     __ vmseq_vi(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), (int)($idx$$constant) - 16);
5485     __ vmerge_vxm(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), $val$$Register);
5486   %}
5487   ins_pipe(pipe_slow);
5488 %}
5489 
5490 instruct insert_index(vReg dst, vReg src, iRegIorL2I val, iRegIorL2I idx, vReg tmp, vRegMask_V0 v0) %{
5491   predicate(n->in(2)->get_int() >= 32 &&
5492             (Matcher::vector_element_basic_type(n) == T_BYTE ||
5493              Matcher::vector_element_basic_type(n) == T_SHORT ||
5494              Matcher::vector_element_basic_type(n) == T_INT));
5495   match(Set dst (VectorInsert (Binary src val) idx));
5496   effect(TEMP tmp, TEMP v0);
5497   format %{ "insert_index $dst, $src, $val, $idx\t# KILL $tmp" %}
5498   ins_encode %{
5499     BasicType bt = Matcher::vector_element_basic_type(this);
5500     __ vsetvli_helper(bt, Matcher::vector_length(this));
5501     __ vid_v(as_VectorRegister($v0$$reg));
5502     __ vmv_v_x(as_VectorRegister($tmp$$reg), $idx$$Register);
5503     __ vmseq_vv(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), as_VectorRegister($tmp$$reg));
5504     __ vmerge_vxm(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), $val$$Register);
5505   %}
5506   ins_pipe(pipe_slow);
5507 %}
5508 
5509 // LONG
5510 
5511 instruct insertL_index_lt32(vReg dst, vReg src, iRegL val, immI idx, vRegMask_V0 v0) %{
5512   predicate(n->in(2)->get_int() < 32 &&
5513             (Matcher::vector_element_basic_type(n) == T_LONG));
5514   match(Set dst (VectorInsert (Binary src val) idx));
5515   effect(TEMP v0);
5516   format %{ "insertL_index_lt32 $dst, $src, $val, $idx" %}
5517   ins_encode %{
5518     BasicType bt = Matcher::vector_element_basic_type(this);
5519     __ vsetvli_helper(bt, Matcher::vector_length(this));
5520     __ vid_v(as_VectorRegister($v0$$reg));
5521     __ vadd_vi(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), -16);
5522     __ vmseq_vi(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), (int)($idx$$constant) - 16);
5523     __ vmerge_vxm(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), $val$$Register);
5524   %}
5525   ins_pipe(pipe_slow);
5526 %}
5527 
5528 instruct insertL_index(vReg dst, vReg src, iRegL val, iRegIorL2I idx, vReg tmp, vRegMask_V0 v0) %{
5529   predicate(n->in(2)->get_int() >= 32 &&
5530             (Matcher::vector_element_basic_type(n) == T_LONG));
5531   match(Set dst (VectorInsert (Binary src val) idx));
5532   effect(TEMP tmp, TEMP v0);
5533   format %{ "insertL_index $dst, $src, $val, $idx\t# KILL $tmp" %}
5534   ins_encode %{
5535     BasicType bt = Matcher::vector_element_basic_type(this);
5536     __ vsetvli_helper(bt, Matcher::vector_length(this));
5537     __ vid_v(as_VectorRegister($v0$$reg));
5538     __ vmv_v_x(as_VectorRegister($tmp$$reg), $idx$$Register);
5539     __ vmseq_vv(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), as_VectorRegister($tmp$$reg));
5540     __ vmerge_vxm(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), $val$$Register);
5541   %}
5542   ins_pipe(pipe_slow);
5543 %}
5544 
5545 // FLOAT
5546 
5547 instruct insertF_index_lt32(vReg dst, vReg src, fRegF val, immI idx, vRegMask_V0 v0) %{
5548   predicate(n->in(2)->get_int() < 32 &&
5549             (Matcher::vector_element_basic_type(n) == T_FLOAT));
5550   match(Set dst (VectorInsert (Binary src val) idx));
5551   effect(TEMP v0);
5552   format %{ "insertF_index_lt32 $dst, $src, $val, $idx" %}
5553   ins_encode %{
5554     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this));
5555     __ vid_v(as_VectorRegister($v0$$reg));
5556     __ vadd_vi(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), -16);
5557     __ vmseq_vi(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), (int)($idx$$constant) - 16);
5558     __ vfmerge_vfm(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), $val$$FloatRegister);
5559   %}
5560   ins_pipe(pipe_slow);
5561 %}
5562 
5563 instruct insertF_index(vReg dst, vReg src, fRegF val, iRegIorL2I idx, vReg tmp, vRegMask_V0 v0) %{
5564   predicate(n->in(2)->get_int() >= 32 &&
5565             (Matcher::vector_element_basic_type(n) == T_FLOAT));
5566   match(Set dst (VectorInsert (Binary src val) idx));
5567   effect(TEMP tmp, TEMP v0);
5568   format %{ "insertF_index $dst, $src, $val, $idx\t# KILL $tmp" %}
5569   ins_encode %{
5570     __ vsetvli_helper(T_FLOAT, Matcher::vector_length(this));
5571     __ vid_v(as_VectorRegister($v0$$reg));
5572     __ vmv_v_x(as_VectorRegister($tmp$$reg), $idx$$Register);
5573     __ vmseq_vv(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), as_VectorRegister($tmp$$reg));
5574     __ vfmerge_vfm(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), $val$$FloatRegister);
5575   %}
5576   ins_pipe(pipe_slow);
5577 %}
5578 
5579 // DOUBLE
5580 
5581 instruct insertD_index_lt32(vReg dst, vReg src, fRegD val, immI idx, vRegMask_V0 v0) %{
5582   predicate(n->in(2)->get_int() < 32 &&
5583             (Matcher::vector_element_basic_type(n) == T_DOUBLE));
5584   match(Set dst (VectorInsert (Binary src val) idx));
5585   effect(TEMP v0);
5586   format %{ "insertD_index_lt32 $dst, $src, $val, $idx" %}
5587   ins_encode %{
5588     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this));
5589     __ vid_v(as_VectorRegister($v0$$reg));
5590     __ vadd_vi(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), -16);
5591     __ vmseq_vi(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), (int)($idx$$constant) - 16);
5592     __ vfmerge_vfm(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), $val$$FloatRegister);
5593   %}
5594   ins_pipe(pipe_slow);
5595 %}
5596 
5597 instruct insertD_index(vReg dst, vReg src, fRegD val, iRegIorL2I idx, vReg tmp, vRegMask_V0 v0) %{
5598   predicate(n->in(2)->get_int() >= 32 &&
5599             (Matcher::vector_element_basic_type(n) == T_DOUBLE));
5600   match(Set dst (VectorInsert (Binary src val) idx));
5601   effect(TEMP tmp, TEMP v0);
5602   format %{ "insertD_index $dst, $src, $val, $idx\t# KILL $tmp" %}
5603   ins_encode %{
5604     __ vsetvli_helper(T_DOUBLE, Matcher::vector_length(this));
5605     __ vid_v(as_VectorRegister($v0$$reg));
5606     __ vmv_v_x(as_VectorRegister($tmp$$reg), $idx$$Register);
5607     __ vmseq_vv(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), as_VectorRegister($tmp$$reg));
5608     __ vfmerge_vfm(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), $val$$FloatRegister);
5609   %}
5610   ins_pipe(pipe_slow);
5611 %}
5612 
5613 // ------------------------------ Vector mask reductions -----------------------
5614 
5615 // true count
5616 
5617 instruct vmask_truecount(iRegINoSp dst, vRegMask src) %{
5618   match(Set dst (VectorMaskTrueCount src));
5619   format %{ "vmask_truecount $dst, $src" %}
5620   ins_encode %{
5621     BasicType bt = Matcher::vector_element_basic_type(this, $src);
5622     __ vsetvli_helper(bt, Matcher::vector_length(this, $src));
5623     __ vcpop_m($dst$$Register, as_VectorRegister($src$$reg));
5624   %}
5625   ins_pipe(pipe_slow);
5626 %}
5627 
5628 // first true
5629 
5630 // Return the index of the first mask lane that is set, or vector length if none of
5631 // them are set.
5632 
5633 instruct vmask_firsttrue(iRegINoSp dst, vRegMask src, vRegMask tmp) %{
5634   match(Set dst (VectorMaskFirstTrue src));
5635   effect(TEMP tmp);
5636   format %{ "vmask_firsttrue $dst, $src\t# KILL $tmp" %}
5637   ins_encode %{
5638     BasicType bt = Matcher::vector_element_basic_type(this, $src);
5639     __ vsetvli_helper(bt, Matcher::vector_length(this, $src));
5640     __ vmsbf_m(as_VectorRegister($tmp$$reg), as_VectorRegister($src$$reg));
5641     __ vcpop_m($dst$$Register, as_VectorRegister($tmp$$reg));
5642   %}
5643   ins_pipe(pipe_slow);
5644 %}
5645 
5646 // last true
5647 
5648 // Return the index of the first last lane that is set, or -1 if none of
5649 // them are set.
5650 
5651 instruct vmask_lasttrue(iRegINoSp dst, vRegMask src) %{
5652   match(Set dst (VectorMaskLastTrue src));
5653   format %{ "vmask_lasttrue $dst, $src" %}
5654   ins_encode %{
5655     uint vector_length = Matcher::vector_length(this, $src);
5656     assert(UseZbb && vector_length <= XLEN, "precondition");
5657     __ vsetvli_helper(T_LONG, 1);
5658     __ vmv_x_s($dst$$Register, as_VectorRegister($src$$reg));
5659     if (XLEN != vector_length) {
5660       __ slli($dst$$Register, $dst$$Register, XLEN - vector_length);
5661       __ srli($dst$$Register, $dst$$Register, XLEN - vector_length);
5662     }
5663     __ clz($dst$$Register, $dst$$Register);
5664     __ mv(t0, XLEN - 1);
5665     __ sub($dst$$Register, t0, $dst$$Register);
5666   %}
5667   ins_pipe(pipe_slow);
5668 %}
5669 
5670 // tolong
5671 
5672 instruct vmask_tolong(iRegLNoSp dst, vRegMask src) %{
5673   match(Set dst (VectorMaskToLong src));
5674   format %{ "vmask_tolong $dst, $src" %}
5675   ins_encode %{
5676     uint vector_length = Matcher::vector_length(this, $src);
5677     assert(vector_length <= XLEN, "precondition");
5678     __ vsetvli_helper(T_LONG, 1);
5679     __ vmv_x_s($dst$$Register, as_VectorRegister($src$$reg));
5680     if (XLEN != vector_length) {
5681       __ slli($dst$$Register, $dst$$Register, XLEN - vector_length);
5682       __ srli($dst$$Register, $dst$$Register, XLEN - vector_length);
5683     }
5684   %}
5685   ins_pipe(pipe_slow);
5686 %}
5687 
5688 // fromlong
5689 
5690 instruct vmask_fromlong(vRegMask dst, iRegL src) %{
5691   match(Set dst (VectorLongToMask src));
5692   format %{ "vmask_fromlong $dst, $src" %}
5693   ins_encode %{
5694     assert(Matcher::vector_length(this) <= XLEN, "precondition");
5695     __ vsetvli_helper(T_LONG, 1);
5696     __ vmv_s_x(as_VectorRegister($dst$$reg), $src$$Register);
5697   %}
5698   ins_pipe(pipe_slow);
5699 %}
5700 
5701 // ------------------------------ VectorTest -----------------------------------
5702 
5703 // anytrue
5704 
5705 // Not matched. Condition is negated and value zero is moved to the right side in CMoveINode::Ideal.
5706 
5707 // instruct cmovI_vtest_anytrue(iRegINoSp dst, cmpOp cop, vRegMask op1, vRegMask op2, immI0 zero, immI_1 one) %{
5708 //   predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne &&
5709 //             static_cast<const VectorTestNode*>(n->in(1)->in(2))->get_predicate() == BoolTest::ne);
5710 //   match(Set dst (CMoveI (Binary cop (VectorTest op1 op2)) (Binary zero one)));
5711 //   format %{ "CMove $dst, (vectortest $cop $op1 $op2), zero, one\t#@cmovI_vtest_anytrue"  %}
5712 //   ins_encode %{
5713 //     BasicType bt = Matcher::vector_element_basic_type(this, $op1);
5714 //     uint vector_length = Matcher::vector_length(this, $op1);
5715 //     __ vsetvli_helper(bt, vector_length);
5716 //     __ vcpop_m($dst$$Register, as_VectorRegister($op1$$reg));
5717 //     __ snez($dst$$Register, $dst$$Register);
5718 //   %}
5719 //   ins_pipe(pipe_slow);
5720 // %}
5721 
5722 instruct cmovI_vtest_anytrue_negate(iRegINoSp dst, cmpOp cop, vRegMask op1, vRegMask op2, immI0 zero, immI_1 one) %{
5723   predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq &&
5724             static_cast<const VectorTestNode*>(n->in(1)->in(2))->get_predicate() == BoolTest::ne);
5725   match(Set dst (CMoveI (Binary cop (VectorTest op1 op2)) (Binary one zero)));
5726   format %{ "CMove $dst, (vectortest $cop $op1 $op2), zero, one\t#@cmovI_vtest_anytrue_negate"  %}
5727   ins_encode %{
5728     BasicType bt = Matcher::vector_element_basic_type(this, $op1);
5729     uint vector_length = Matcher::vector_length(this, $op1);
5730     __ vsetvli_helper(bt, vector_length);
5731     __ vcpop_m($dst$$Register, as_VectorRegister($op1$$reg));
5732     __ snez($dst$$Register, $dst$$Register);
5733   %}
5734   ins_pipe(pipe_slow);
5735 %}
5736 
5737 // alltrue
5738 
5739 // Not matched. Condition is negated and value zero is moved to the right side in CMoveINode::Ideal.
5740 
5741 // instruct cmovI_vtest_alltrue(iRegINoSp dst, cmpOp cop, vRegMask op1, vRegMask op2, immI0 zero, immI_1 one) %{
5742 //   predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq &&
5743 //             static_cast<const VectorTestNode*>(n->in(1)->in(2))->get_predicate() == BoolTest::overflow);
5744 //   match(Set dst (CMoveI (Binary cop (VectorTest op1 op2)) (Binary zero one)));
5745 //   format %{ "CMove $dst, (vectortest $cop $op1 $op2), zero, one\t#@cmovI_vtest_alltrue"  %}
5746 //   ins_encode %{
5747 //     BasicType bt = Matcher::vector_element_basic_type(this, $op1);
5748 //     uint vector_length = Matcher::vector_length(this, $op1);
5749 //     __ vsetvli_helper(bt, vector_length);
5750 //     __ vcpop_m($dst$$Register, as_VectorRegister($op1$$reg));
5751 //     __ sub($dst$$Register, $dst$$Register, vector_length);
5752 //     __ seqz($dst$$Register, $dst$$Register);
5753 //   %}
5754 //   ins_pipe(pipe_slow);
5755 // %}
5756 
5757 instruct cmovI_vtest_alltrue_negate(iRegINoSp dst, cmpOp cop, vRegMask op1, vRegMask op2, immI0 zero, immI_1 one) %{
5758   predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne &&
5759             static_cast<const VectorTestNode*>(n->in(1)->in(2))->get_predicate() == BoolTest::overflow);
5760   match(Set dst (CMoveI (Binary cop (VectorTest op1 op2)) (Binary one zero)));
5761   format %{ "CMove $dst, (vectortest $cop $op1 $op2), zero, one\t#@cmovI_vtest_alltrue_negate"  %}
5762   ins_encode %{
5763     BasicType bt = Matcher::vector_element_basic_type(this, $op1);
5764     uint vector_length = Matcher::vector_length(this, $op1);
5765     __ vsetvli_helper(bt, vector_length);
5766     __ vcpop_m($dst$$Register, as_VectorRegister($op1$$reg));
5767     __ sub($dst$$Register, $dst$$Register, vector_length);
5768     __ seqz($dst$$Register, $dst$$Register);
5769   %}
5770   ins_pipe(pipe_slow);
5771 %}
5772 
5773 // anytrue
5774 
5775 instruct vtest_anytrue_branch(cmpOpEqNe cop, vRegMask op1, vRegMask op2, label lbl) %{
5776   predicate(static_cast<const VectorTestNode*>(n->in(2))->get_predicate() == BoolTest::ne);
5777   match(If cop (VectorTest op1 op2));
5778   effect(USE lbl);
5779   format %{ "b$cop (vectortest ne $op1, $op2) $lbl\t#@vtest_anytrue_branch" %}
5780   ins_encode %{
5781     uint vector_length = Matcher::vector_length(this, $op1);
5782     BasicType bt = Matcher::vector_element_basic_type(this, $op1);
5783     __ vsetvli_helper(bt, vector_length);
5784     __ vcpop_m(t0, as_VectorRegister($op1$$reg));
5785     __ enc_cmpEqNe_imm0_branch($cop$$cmpcode, t0, *($lbl$$label), /* is_far */ true);
5786   %}
5787   ins_pipe(pipe_slow);
5788 %}
5789 
5790 // alltrue
5791 
5792 instruct vtest_alltrue_branch(cmpOpEqNe cop, vRegMask op1, vRegMask op2, label lbl) %{
5793   predicate(static_cast<const VectorTestNode*>(n->in(2))->get_predicate() == BoolTest::overflow);
5794   match(If cop (VectorTest op1 op2));
5795   effect(USE lbl);
5796   format %{ "b$cop (vectortest overflow $op1, $op2) $lbl\t#@vtest_alltrue_branch" %}
5797   ins_encode %{
5798     uint vector_length = Matcher::vector_length(this, $op1);
5799     BasicType bt = Matcher::vector_element_basic_type(this, $op1);
5800     __ vsetvli_helper(bt, vector_length);
5801     __ vcpop_m(t0, as_VectorRegister($op1$$reg));
5802     __ sub(t0, t0, vector_length);
5803     __ enc_cmpEqNe_imm0_branch($cop$$cmpcode, t0, *($lbl$$label), /* is_far */ true);
5804   %}
5805   ins_pipe(pipe_slow);
5806 %}