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