1// 2// Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. 3// Copyright (c) 2020, 2021, Arm Limited. All rights reserved. 4// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5// 6// This code is free software; you can redistribute it and/or modify it 7// under the terms of the GNU General Public License version 2 only, as 8// published by the Free Software Foundation. 9// 10// This code is distributed in the hope that it will be useful, but WITHOUT 11// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13// version 2 for more details (a copy is included in the LICENSE file that 14// accompanied this code). 15// 16// You should have received a copy of the GNU General Public License version 17// 2 along with this work; if not, write to the Free Software Foundation, 18// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19// 20// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21// or visit www.oracle.com if you need additional information or have any 22// questions. 23// 24// 25 26// This file is automatically generated by running "m4 aarch64_sve_ad.m4". Do not edit ---- 27 28// AArch64 SVE Architecture Description File 29 30 31// 4 bit signed offset -- for predicated load/store 32 33operand vmemA_immIOffset4() 34%{ 35 predicate(Address::offset_ok_for_sve_immed(n->get_int(), 4, 36 Matcher::scalable_vector_reg_size(T_BYTE))); 37 match(ConI); 38 39 op_cost(0); 40 format %{ %} 41 interface(CONST_INTER); 42%} 43 44operand vmemA_immLOffset4() 45%{ 46 predicate(Address::offset_ok_for_sve_immed(n->get_long(), 4, 47 Matcher::scalable_vector_reg_size(T_BYTE))); 48 match(ConL); 49 50 op_cost(0); 51 format %{ %} 52 interface(CONST_INTER); 53%} 54 55operand vmemA_indOffI4(iRegP reg, vmemA_immIOffset4 off) 56%{ 57 constraint(ALLOC_IN_RC(ptr_reg)); 58 match(AddP reg off); 59 op_cost(0); 60 format %{ "[$reg, $off, MUL VL]" %} 61 interface(MEMORY_INTER) %{ 62 base($reg); 63 index(0xffffffff); 64 scale(0x0); 65 disp($off); 66 %} 67%} 68 69operand vmemA_indOffL4(iRegP reg, vmemA_immLOffset4 off) 70%{ 71 constraint(ALLOC_IN_RC(ptr_reg)); 72 match(AddP reg off); 73 op_cost(0); 74 format %{ "[$reg, $off, MUL VL]" %} 75 interface(MEMORY_INTER) %{ 76 base($reg); 77 index(0xffffffff); 78 scale(0x0); 79 disp($off); 80 %} 81%} 82 83opclass vmemA(indirect, vmemA_indOffI4, vmemA_indOffL4); 84 85source_hpp %{ 86 bool op_sve_supported(int opcode); 87%} 88 89source %{ 90 static inline BasicType vector_element_basic_type(const MachNode* n) { 91 const TypeVect* vt = n->bottom_type()->is_vect(); 92 return vt->element_basic_type(); 93 } 94 95 static inline BasicType vector_element_basic_type(const MachNode* use, const MachOper* opnd) { 96 int def_idx = use->operand_index(opnd); 97 Node* def = use->in(def_idx); 98 const TypeVect* vt = def->bottom_type()->is_vect(); 99 return vt->element_basic_type(); 100 } 101 102 static Assembler::SIMD_RegVariant elemBytes_to_regVariant(int esize) { 103 switch(esize) { 104 case 1: 105 return Assembler::B; 106 case 2: 107 return Assembler::H; 108 case 4: 109 return Assembler::S; 110 case 8: 111 return Assembler::D; 112 default: 113 assert(false, "unsupported"); 114 ShouldNotReachHere(); 115 } 116 return Assembler::INVALID; 117 } 118 119 static Assembler::SIMD_RegVariant elemType_to_regVariant(BasicType bt) { 120 return elemBytes_to_regVariant(type2aelembytes(bt)); 121 } 122 123 typedef void (C2_MacroAssembler::* sve_mem_insn_predicate)(FloatRegister Rt, Assembler::SIMD_RegVariant T, 124 PRegister Pg, const Address &adr); 125 126 // Predicated load/store, with optional ptrue to all elements of given predicate register. 127 static void loadStoreA_predicate(C2_MacroAssembler masm, bool is_store, 128 FloatRegister reg, PRegister pg, BasicType bt, 129 int opcode, Register base, int index, int size, int disp) { 130 sve_mem_insn_predicate insn; 131 Assembler::SIMD_RegVariant type; 132 int esize = type2aelembytes(bt); 133 if (index == -1) { 134 assert(size == 0, "unsupported address mode: scale size = %d", size); 135 switch(esize) { 136 case 1: 137 insn = is_store ? &C2_MacroAssembler::sve_st1b : &C2_MacroAssembler::sve_ld1b; 138 type = Assembler::B; 139 break; 140 case 2: 141 insn = is_store ? &C2_MacroAssembler::sve_st1h : &C2_MacroAssembler::sve_ld1h; 142 type = Assembler::H; 143 break; 144 case 4: 145 insn = is_store ? &C2_MacroAssembler::sve_st1w : &C2_MacroAssembler::sve_ld1w; 146 type = Assembler::S; 147 break; 148 case 8: 149 insn = is_store ? &C2_MacroAssembler::sve_st1d : &C2_MacroAssembler::sve_ld1d; 150 type = Assembler::D; 151 break; 152 default: 153 assert(false, "unsupported"); 154 ShouldNotReachHere(); 155 } 156 (masm.*insn)(reg, type, pg, Address(base, disp / Matcher::scalable_vector_reg_size(T_BYTE))); 157 } else { 158 assert(false, "unimplemented"); 159 ShouldNotReachHere(); 160 } 161 } 162 163 bool op_sve_supported(int opcode) { 164 switch (opcode) { 165 case Op_MulAddVS2VI: 166 // No multiply reduction instructions 167 case Op_MulReductionVD: 168 case Op_MulReductionVF: 169 case Op_MulReductionVI: 170 case Op_MulReductionVL: 171 // Others 172 case Op_Extract: 173 case Op_ExtractB: 174 case Op_ExtractC: 175 case Op_ExtractD: 176 case Op_ExtractF: 177 case Op_ExtractI: 178 case Op_ExtractL: 179 case Op_ExtractS: 180 case Op_ExtractUB: 181 // Vector API specific 182 case Op_AndReductionV: 183 case Op_OrReductionV: 184 case Op_XorReductionV: 185 case Op_MaxReductionV: 186 case Op_MinReductionV: 187 case Op_LoadVectorGather: 188 case Op_StoreVectorScatter: 189 case Op_VectorBlend: 190 case Op_VectorCast: 191 case Op_VectorCastB2X: 192 case Op_VectorCastD2X: 193 case Op_VectorCastF2X: 194 case Op_VectorCastI2X: 195 case Op_VectorCastL2X: 196 case Op_VectorCastS2X: 197 case Op_VectorInsert: 198 case Op_VectorLoadConst: 199 case Op_VectorLoadMask: 200 case Op_VectorLoadShuffle: 201 case Op_VectorMaskCmp: 202 case Op_VectorRearrange: 203 case Op_VectorReinterpret: 204 case Op_VectorStoreMask: 205 case Op_VectorTest: 206 return false; 207 default: 208 return true; 209 } 210 } 211%} 212 213definitions %{ 214 int_def SVE_COST (200, 200); 215%} 216 217 218// All SVE instructions 219 220// vector load/store 221 222// Use predicated vector load/store 223instruct loadV(vReg dst, vmemA mem) %{ 224 predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() >= 16); 225 match(Set dst (LoadVector mem)); 226 ins_cost(SVE_COST); 227 format %{ "sve_ldr $dst, $mem\t # vector (sve)" %} 228 ins_encode %{ 229 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 230 loadStoreA_predicate(C2_MacroAssembler(&cbuf), false, dst_reg, ptrue, 231 vector_element_basic_type(this), $mem->opcode(), 232 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 233 %} 234 ins_pipe(pipe_slow); 235%} 236 237instruct storeV(vReg src, vmemA mem) %{ 238 predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() >= 16); 239 match(Set mem (StoreVector mem src)); 240 ins_cost(SVE_COST); 241 format %{ "sve_str $mem, $src\t # vector (sve)" %} 242 ins_encode %{ 243 FloatRegister src_reg = as_FloatRegister($src$$reg); 244 loadStoreA_predicate(C2_MacroAssembler(&cbuf), true, src_reg, ptrue, 245 vector_element_basic_type(this, $src), $mem->opcode(), 246 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 247 %} 248 ins_pipe(pipe_slow); 249%} 250 251// vector abs 252 253instruct vabsB(vReg dst, vReg src) %{ 254 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16 && 255 n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); 256 match(Set dst (AbsVB src)); 257 ins_cost(SVE_COST); 258 format %{ "sve_abs $dst, $src\t# vector (sve) (B)" %} 259 ins_encode %{ 260 __ sve_abs(as_FloatRegister($dst$$reg), __ B, 261 ptrue, as_FloatRegister($src$$reg)); 262 %} 263 ins_pipe(pipe_slow); 264%} 265 266instruct vabsS(vReg dst, vReg src) %{ 267 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8 && 268 n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); 269 match(Set dst (AbsVS src)); 270 ins_cost(SVE_COST); 271 format %{ "sve_abs $dst, $src\t# vector (sve) (H)" %} 272 ins_encode %{ 273 __ sve_abs(as_FloatRegister($dst$$reg), __ H, 274 ptrue, as_FloatRegister($src$$reg)); 275 %} 276 ins_pipe(pipe_slow); 277%} 278 279instruct vabsI(vReg dst, vReg src) %{ 280 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4 && 281 n->bottom_type()->is_vect()->element_basic_type() == T_INT); 282 match(Set dst (AbsVI src)); 283 ins_cost(SVE_COST); 284 format %{ "sve_abs $dst, $src\t# vector (sve) (S)" %} 285 ins_encode %{ 286 __ sve_abs(as_FloatRegister($dst$$reg), __ S, 287 ptrue, as_FloatRegister($src$$reg)); 288 %} 289 ins_pipe(pipe_slow); 290%} 291 292instruct vabsL(vReg dst, vReg src) %{ 293 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2 && 294 n->bottom_type()->is_vect()->element_basic_type() == T_LONG); 295 match(Set dst (AbsVL src)); 296 ins_cost(SVE_COST); 297 format %{ "sve_abs $dst, $src\t# vector (sve) (D)" %} 298 ins_encode %{ 299 __ sve_abs(as_FloatRegister($dst$$reg), __ D, 300 ptrue, as_FloatRegister($src$$reg)); 301 %} 302 ins_pipe(pipe_slow); 303%} 304 305instruct vabsF(vReg dst, vReg src) %{ 306 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4 && 307 n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 308 match(Set dst (AbsVF src)); 309 ins_cost(SVE_COST); 310 format %{ "sve_fabs $dst, $src\t# vector (sve) (S)" %} 311 ins_encode %{ 312 __ sve_fabs(as_FloatRegister($dst$$reg), __ S, 313 ptrue, as_FloatRegister($src$$reg)); 314 %} 315 ins_pipe(pipe_slow); 316%} 317 318instruct vabsD(vReg dst, vReg src) %{ 319 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2 && 320 n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 321 match(Set dst (AbsVD src)); 322 ins_cost(SVE_COST); 323 format %{ "sve_fabs $dst, $src\t# vector (sve) (D)" %} 324 ins_encode %{ 325 __ sve_fabs(as_FloatRegister($dst$$reg), __ D, 326 ptrue, as_FloatRegister($src$$reg)); 327 %} 328 ins_pipe(pipe_slow); 329%} 330 331// vector add 332 333instruct vaddB(vReg dst, vReg src1, vReg src2) %{ 334 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 335 match(Set dst (AddVB src1 src2)); 336 ins_cost(SVE_COST); 337 format %{ "sve_add $dst, $src1, $src2\t # vector (sve) (B)" %} 338 ins_encode %{ 339 __ sve_add(as_FloatRegister($dst$$reg), __ B, 340 as_FloatRegister($src1$$reg), 341 as_FloatRegister($src2$$reg)); 342 %} 343 ins_pipe(pipe_slow); 344%} 345 346instruct vaddS(vReg dst, vReg src1, vReg src2) %{ 347 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 348 match(Set dst (AddVS src1 src2)); 349 ins_cost(SVE_COST); 350 format %{ "sve_add $dst, $src1, $src2\t # vector (sve) (H)" %} 351 ins_encode %{ 352 __ sve_add(as_FloatRegister($dst$$reg), __ H, 353 as_FloatRegister($src1$$reg), 354 as_FloatRegister($src2$$reg)); 355 %} 356 ins_pipe(pipe_slow); 357%} 358 359instruct vaddI(vReg dst, vReg src1, vReg src2) %{ 360 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 361 match(Set dst (AddVI src1 src2)); 362 ins_cost(SVE_COST); 363 format %{ "sve_add $dst, $src1, $src2\t # vector (sve) (S)" %} 364 ins_encode %{ 365 __ sve_add(as_FloatRegister($dst$$reg), __ S, 366 as_FloatRegister($src1$$reg), 367 as_FloatRegister($src2$$reg)); 368 %} 369 ins_pipe(pipe_slow); 370%} 371 372instruct vaddL(vReg dst, vReg src1, vReg src2) %{ 373 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 374 match(Set dst (AddVL src1 src2)); 375 ins_cost(SVE_COST); 376 format %{ "sve_add $dst, $src1, $src2\t # vector (sve) (D)" %} 377 ins_encode %{ 378 __ sve_add(as_FloatRegister($dst$$reg), __ D, 379 as_FloatRegister($src1$$reg), 380 as_FloatRegister($src2$$reg)); 381 %} 382 ins_pipe(pipe_slow); 383%} 384 385instruct vaddF(vReg dst, vReg src1, vReg src2) %{ 386 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 387 match(Set dst (AddVF src1 src2)); 388 ins_cost(SVE_COST); 389 format %{ "sve_fadd $dst, $src1, $src2\t # vector (sve) (S)" %} 390 ins_encode %{ 391 __ sve_fadd(as_FloatRegister($dst$$reg), __ S, 392 as_FloatRegister($src1$$reg), 393 as_FloatRegister($src2$$reg)); 394 %} 395 ins_pipe(pipe_slow); 396%} 397 398instruct vaddD(vReg dst, vReg src1, vReg src2) %{ 399 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 400 match(Set dst (AddVD src1 src2)); 401 ins_cost(SVE_COST); 402 format %{ "sve_fadd $dst, $src1, $src2\t # vector (sve) (D)" %} 403 ins_encode %{ 404 __ sve_fadd(as_FloatRegister($dst$$reg), __ D, 405 as_FloatRegister($src1$$reg), 406 as_FloatRegister($src2$$reg)); 407 %} 408 ins_pipe(pipe_slow); 409%} 410 411// vector and 412 413instruct vand(vReg dst, vReg src1, vReg src2) %{ 414 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 415 match(Set dst (AndV src1 src2)); 416 ins_cost(SVE_COST); 417 format %{ "sve_and $dst, $src1, $src2\t# vector (sve)" %} 418 ins_encode %{ 419 __ sve_and(as_FloatRegister($dst$$reg), 420 as_FloatRegister($src1$$reg), 421 as_FloatRegister($src2$$reg)); 422 %} 423 ins_pipe(pipe_slow); 424%} 425 426// vector or 427 428instruct vor(vReg dst, vReg src1, vReg src2) %{ 429 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 430 match(Set dst (OrV src1 src2)); 431 ins_cost(SVE_COST); 432 format %{ "sve_orr $dst, $src1, $src2\t# vector (sve)" %} 433 ins_encode %{ 434 __ sve_orr(as_FloatRegister($dst$$reg), 435 as_FloatRegister($src1$$reg), 436 as_FloatRegister($src2$$reg)); 437 %} 438 ins_pipe(pipe_slow); 439%} 440 441// vector xor 442 443instruct vxor(vReg dst, vReg src1, vReg src2) %{ 444 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 445 match(Set dst (XorV src1 src2)); 446 ins_cost(SVE_COST); 447 format %{ "sve_eor $dst, $src1, $src2\t# vector (sve)" %} 448 ins_encode %{ 449 __ sve_eor(as_FloatRegister($dst$$reg), 450 as_FloatRegister($src1$$reg), 451 as_FloatRegister($src2$$reg)); 452 %} 453 ins_pipe(pipe_slow); 454%} 455 456// vector not 457 458instruct vnotI(vReg dst, vReg src, immI_M1 m1) %{ 459 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 460 match(Set dst (XorV src (ReplicateB m1))); 461 match(Set dst (XorV src (ReplicateS m1))); 462 match(Set dst (XorV src (ReplicateI m1))); 463 ins_cost(SVE_COST); 464 format %{ "sve_not $dst, $src\t# vector (sve) B/H/S" %} 465 ins_encode %{ 466 __ sve_not(as_FloatRegister($dst$$reg), __ D, 467 ptrue, as_FloatRegister($src$$reg)); 468 %} 469 ins_pipe(pipe_slow); 470%} 471 472instruct vnotL(vReg dst, vReg src, immL_M1 m1) %{ 473 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 474 match(Set dst (XorV src (ReplicateL m1))); 475 ins_cost(SVE_COST); 476 format %{ "sve_not $dst, $src\t# vector (sve) D" %} 477 ins_encode %{ 478 __ sve_not(as_FloatRegister($dst$$reg), __ D, 479 ptrue, as_FloatRegister($src$$reg)); 480 %} 481 ins_pipe(pipe_slow); 482%} 483 484 485// vector and_not 486 487instruct vand_notI(vReg dst, vReg src1, vReg src2, immI_M1 m1) %{ 488 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 489 match(Set dst (AndV src1 (XorV src2 (ReplicateB m1)))); 490 match(Set dst (AndV src1 (XorV src2 (ReplicateS m1)))); 491 match(Set dst (AndV src1 (XorV src2 (ReplicateI m1)))); 492 ins_cost(SVE_COST); 493 format %{ "sve_bic $dst, $src1, $src2\t# vector (sve) B/H/S" %} 494 ins_encode %{ 495 __ sve_bic(as_FloatRegister($dst$$reg), 496 as_FloatRegister($src1$$reg), 497 as_FloatRegister($src2$$reg)); 498 %} 499 ins_pipe(pipe_slow); 500%} 501 502instruct vand_notL(vReg dst, vReg src1, vReg src2, immL_M1 m1) %{ 503 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 504 match(Set dst (AndV src1 (XorV src2 (ReplicateL m1)))); 505 ins_cost(SVE_COST); 506 format %{ "sve_bic $dst, $src1, $src2\t# vector (sve) D" %} 507 ins_encode %{ 508 __ sve_bic(as_FloatRegister($dst$$reg), 509 as_FloatRegister($src1$$reg), 510 as_FloatRegister($src2$$reg)); 511 %} 512 ins_pipe(pipe_slow); 513%} 514 515 516// vector float div 517 518instruct vdivF(vReg dst_src1, vReg src2) %{ 519 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 520 match(Set dst_src1 (DivVF dst_src1 src2)); 521 ins_cost(SVE_COST); 522 format %{ "sve_fdiv $dst_src1, $dst_src1, $src2\t# vector (sve) (S)" %} 523 ins_encode %{ 524 __ sve_fdiv(as_FloatRegister($dst_src1$$reg), __ S, 525 ptrue, as_FloatRegister($src2$$reg)); 526 %} 527 ins_pipe(pipe_slow); 528%} 529 530instruct vdivD(vReg dst_src1, vReg src2) %{ 531 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 532 match(Set dst_src1 (DivVD dst_src1 src2)); 533 ins_cost(SVE_COST); 534 format %{ "sve_fdiv $dst_src1, $dst_src1, $src2\t# vector (sve) (D)" %} 535 ins_encode %{ 536 __ sve_fdiv(as_FloatRegister($dst_src1$$reg), __ D, 537 ptrue, as_FloatRegister($src2$$reg)); 538 %} 539 ins_pipe(pipe_slow); 540%} 541 542// vector min/max 543 544instruct vmin(vReg dst_src1, vReg src2) %{ 545 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 546 match(Set dst_src1 (MinV dst_src1 src2)); 547 ins_cost(SVE_COST); 548 format %{ "sve_min $dst_src1, $dst_src1, $src2\t # vector (sve)" %} 549 ins_encode %{ 550 BasicType bt = vector_element_basic_type(this); 551 Assembler::SIMD_RegVariant size = elemType_to_regVariant(bt); 552 if (is_floating_point_type(bt)) { 553 __ sve_fmin(as_FloatRegister($dst_src1$$reg), size, 554 ptrue, as_FloatRegister($src2$$reg)); 555 } else { 556 assert(is_integral_type(bt), "Unsupported type"); 557 __ sve_smin(as_FloatRegister($dst_src1$$reg), size, 558 ptrue, as_FloatRegister($src2$$reg)); 559 } 560 %} 561 ins_pipe(pipe_slow); 562%} 563 564instruct vmax(vReg dst_src1, vReg src2) %{ 565 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 566 match(Set dst_src1 (MaxV dst_src1 src2)); 567 ins_cost(SVE_COST); 568 format %{ "sve_max $dst_src1, $dst_src1, $src2\t # vector (sve)" %} 569 ins_encode %{ 570 BasicType bt = vector_element_basic_type(this); 571 Assembler::SIMD_RegVariant size = elemType_to_regVariant(bt); 572 if (is_floating_point_type(bt)) { 573 __ sve_fmax(as_FloatRegister($dst_src1$$reg), size, 574 ptrue, as_FloatRegister($src2$$reg)); 575 } else { 576 assert(is_integral_type(bt), "Unsupported type"); 577 __ sve_smax(as_FloatRegister($dst_src1$$reg), size, 578 ptrue, as_FloatRegister($src2$$reg)); 579 } 580 %} 581 ins_pipe(pipe_slow); 582%} 583 584// vector fmla 585 586// dst_src1 = dst_src1 + src2 * src3 587instruct vfmlaF(vReg dst_src1, vReg src2, vReg src3) %{ 588 predicate(UseFMA && UseSVE > 0 && n->as_Vector()->length() >= 4); 589 match(Set dst_src1 (FmaVF dst_src1 (Binary src2 src3))); 590 ins_cost(SVE_COST); 591 format %{ "sve_fmla $dst_src1, $src2, $src3\t # vector (sve) (S)" %} 592 ins_encode %{ 593 __ sve_fmla(as_FloatRegister($dst_src1$$reg), __ S, 594 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 595 %} 596 ins_pipe(pipe_slow); 597%} 598 599// dst_src1 = dst_src1 + src2 * src3 600instruct vfmlaD(vReg dst_src1, vReg src2, vReg src3) %{ 601 predicate(UseFMA && UseSVE > 0 && n->as_Vector()->length() >= 2); 602 match(Set dst_src1 (FmaVD dst_src1 (Binary src2 src3))); 603 ins_cost(SVE_COST); 604 format %{ "sve_fmla $dst_src1, $src2, $src3\t # vector (sve) (D)" %} 605 ins_encode %{ 606 __ sve_fmla(as_FloatRegister($dst_src1$$reg), __ D, 607 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 608 %} 609 ins_pipe(pipe_slow); 610%} 611 612// vector fmls 613 614// dst_src1 = dst_src1 + -src2 * src3 615// dst_src1 = dst_src1 + src2 * -src3 616instruct vfmlsF(vReg dst_src1, vReg src2, vReg src3) %{ 617 predicate(UseFMA && UseSVE > 0 && n->as_Vector()->length() >= 4); 618 match(Set dst_src1 (FmaVF dst_src1 (Binary (NegVF src2) src3))); 619 match(Set dst_src1 (FmaVF dst_src1 (Binary src2 (NegVF src3)))); 620 ins_cost(SVE_COST); 621 format %{ "sve_fmls $dst_src1, $src2, $src3\t # vector (sve) (S)" %} 622 ins_encode %{ 623 __ sve_fmls(as_FloatRegister($dst_src1$$reg), __ S, 624 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 625 %} 626 ins_pipe(pipe_slow); 627%} 628 629// dst_src1 = dst_src1 + -src2 * src3 630// dst_src1 = dst_src1 + src2 * -src3 631instruct vfmlsD(vReg dst_src1, vReg src2, vReg src3) %{ 632 predicate(UseFMA && UseSVE > 0 && n->as_Vector()->length() >= 2); 633 match(Set dst_src1 (FmaVD dst_src1 (Binary (NegVD src2) src3))); 634 match(Set dst_src1 (FmaVD dst_src1 (Binary src2 (NegVD src3)))); 635 ins_cost(SVE_COST); 636 format %{ "sve_fmls $dst_src1, $src2, $src3\t # vector (sve) (D)" %} 637 ins_encode %{ 638 __ sve_fmls(as_FloatRegister($dst_src1$$reg), __ D, 639 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 640 %} 641 ins_pipe(pipe_slow); 642%} 643 644// vector fnmla 645 646// dst_src1 = -dst_src1 + -src2 * src3 647// dst_src1 = -dst_src1 + src2 * -src3 648instruct vfnmlaF(vReg dst_src1, vReg src2, vReg src3) %{ 649 predicate(UseFMA && UseSVE > 0 && n->as_Vector()->length() >= 4); 650 match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary (NegVF src2) src3))); 651 match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 (NegVF src3)))); 652 ins_cost(SVE_COST); 653 format %{ "sve_fnmla $dst_src1, $src2, $src3\t # vector (sve) (S)" %} 654 ins_encode %{ 655 __ sve_fnmla(as_FloatRegister($dst_src1$$reg), __ S, 656 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 657 %} 658 ins_pipe(pipe_slow); 659%} 660 661// dst_src1 = -dst_src1 + -src2 * src3 662// dst_src1 = -dst_src1 + src2 * -src3 663instruct vfnmlaD(vReg dst_src1, vReg src2, vReg src3) %{ 664 predicate(UseFMA && UseSVE > 0 && n->as_Vector()->length() >= 2); 665 match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary (NegVD src2) src3))); 666 match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 (NegVD src3)))); 667 ins_cost(SVE_COST); 668 format %{ "sve_fnmla $dst_src1, $src2, $src3\t # vector (sve) (D)" %} 669 ins_encode %{ 670 __ sve_fnmla(as_FloatRegister($dst_src1$$reg), __ D, 671 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 672 %} 673 ins_pipe(pipe_slow); 674%} 675 676// vector fnmls 677 678// dst_src1 = -dst_src1 + src2 * src3 679instruct vfnmlsF(vReg dst_src1, vReg src2, vReg src3) %{ 680 predicate(UseFMA && UseSVE > 0 && n->as_Vector()->length() >= 4); 681 match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 src3))); 682 ins_cost(SVE_COST); 683 format %{ "sve_fnmls $dst_src1, $src2, $src3\t # vector (sve) (S)" %} 684 ins_encode %{ 685 __ sve_fnmls(as_FloatRegister($dst_src1$$reg), __ S, 686 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 687 %} 688 ins_pipe(pipe_slow); 689%} 690 691// dst_src1 = -dst_src1 + src2 * src3 692instruct vfnmlsD(vReg dst_src1, vReg src2, vReg src3) %{ 693 predicate(UseFMA && UseSVE > 0 && n->as_Vector()->length() >= 2); 694 match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 src3))); 695 ins_cost(SVE_COST); 696 format %{ "sve_fnmls $dst_src1, $src2, $src3\t # vector (sve) (D)" %} 697 ins_encode %{ 698 __ sve_fnmls(as_FloatRegister($dst_src1$$reg), __ D, 699 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 700 %} 701 ins_pipe(pipe_slow); 702%} 703 704// vector mla 705 706// dst_src1 = dst_src1 + src2 * src3 707instruct vmlaB(vReg dst_src1, vReg src2, vReg src3) 708%{ 709 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 710 match(Set dst_src1 (AddVB dst_src1 (MulVB src2 src3))); 711 ins_cost(SVE_COST); 712 format %{ "sve_mla $dst_src1, src2, src3\t # vector (sve) (B)" %} 713 ins_encode %{ 714 __ sve_mla(as_FloatRegister($dst_src1$$reg), __ B, 715 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 716 %} 717 ins_pipe(pipe_slow); 718%} 719 720// dst_src1 = dst_src1 + src2 * src3 721instruct vmlaS(vReg dst_src1, vReg src2, vReg src3) 722%{ 723 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 724 match(Set dst_src1 (AddVS dst_src1 (MulVS src2 src3))); 725 ins_cost(SVE_COST); 726 format %{ "sve_mla $dst_src1, src2, src3\t # vector (sve) (H)" %} 727 ins_encode %{ 728 __ sve_mla(as_FloatRegister($dst_src1$$reg), __ H, 729 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 730 %} 731 ins_pipe(pipe_slow); 732%} 733 734// dst_src1 = dst_src1 + src2 * src3 735instruct vmlaI(vReg dst_src1, vReg src2, vReg src3) 736%{ 737 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 738 match(Set dst_src1 (AddVI dst_src1 (MulVI src2 src3))); 739 ins_cost(SVE_COST); 740 format %{ "sve_mla $dst_src1, src2, src3\t # vector (sve) (S)" %} 741 ins_encode %{ 742 __ sve_mla(as_FloatRegister($dst_src1$$reg), __ S, 743 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 744 %} 745 ins_pipe(pipe_slow); 746%} 747 748// dst_src1 = dst_src1 + src2 * src3 749instruct vmlaL(vReg dst_src1, vReg src2, vReg src3) 750%{ 751 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 752 match(Set dst_src1 (AddVL dst_src1 (MulVL src2 src3))); 753 ins_cost(SVE_COST); 754 format %{ "sve_mla $dst_src1, src2, src3\t # vector (sve) (D)" %} 755 ins_encode %{ 756 __ sve_mla(as_FloatRegister($dst_src1$$reg), __ D, 757 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 758 %} 759 ins_pipe(pipe_slow); 760%} 761 762// vector mls 763 764// dst_src1 = dst_src1 - src2 * src3 765instruct vmlsB(vReg dst_src1, vReg src2, vReg src3) 766%{ 767 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 768 match(Set dst_src1 (SubVB dst_src1 (MulVB src2 src3))); 769 ins_cost(SVE_COST); 770 format %{ "sve_mls $dst_src1, src2, src3\t # vector (sve) (B)" %} 771 ins_encode %{ 772 __ sve_mls(as_FloatRegister($dst_src1$$reg), __ B, 773 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 774 %} 775 ins_pipe(pipe_slow); 776%} 777 778// dst_src1 = dst_src1 - src2 * src3 779instruct vmlsS(vReg dst_src1, vReg src2, vReg src3) 780%{ 781 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 782 match(Set dst_src1 (SubVS dst_src1 (MulVS src2 src3))); 783 ins_cost(SVE_COST); 784 format %{ "sve_mls $dst_src1, src2, src3\t # vector (sve) (H)" %} 785 ins_encode %{ 786 __ sve_mls(as_FloatRegister($dst_src1$$reg), __ H, 787 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 788 %} 789 ins_pipe(pipe_slow); 790%} 791 792// dst_src1 = dst_src1 - src2 * src3 793instruct vmlsI(vReg dst_src1, vReg src2, vReg src3) 794%{ 795 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 796 match(Set dst_src1 (SubVI dst_src1 (MulVI src2 src3))); 797 ins_cost(SVE_COST); 798 format %{ "sve_mls $dst_src1, src2, src3\t # vector (sve) (S)" %} 799 ins_encode %{ 800 __ sve_mls(as_FloatRegister($dst_src1$$reg), __ S, 801 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 802 %} 803 ins_pipe(pipe_slow); 804%} 805 806// dst_src1 = dst_src1 - src2 * src3 807instruct vmlsL(vReg dst_src1, vReg src2, vReg src3) 808%{ 809 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 810 match(Set dst_src1 (SubVL dst_src1 (MulVL src2 src3))); 811 ins_cost(SVE_COST); 812 format %{ "sve_mls $dst_src1, src2, src3\t # vector (sve) (D)" %} 813 ins_encode %{ 814 __ sve_mls(as_FloatRegister($dst_src1$$reg), __ D, 815 ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); 816 %} 817 ins_pipe(pipe_slow); 818%} 819 820 821// vector mul 822 823instruct vmulB(vReg dst_src1, vReg src2) %{ 824 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 825 match(Set dst_src1 (MulVB dst_src1 src2)); 826 ins_cost(SVE_COST); 827 format %{ "sve_mul $dst_src1, $dst_src1, $src2\t # vector (sve) (B)" %} 828 ins_encode %{ 829 __ sve_mul(as_FloatRegister($dst_src1$$reg), __ B, 830 ptrue, as_FloatRegister($src2$$reg)); 831 %} 832 ins_pipe(pipe_slow); 833%} 834 835instruct vmulS(vReg dst_src1, vReg src2) %{ 836 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 837 match(Set dst_src1 (MulVS dst_src1 src2)); 838 ins_cost(SVE_COST); 839 format %{ "sve_mul $dst_src1, $dst_src1, $src2\t # vector (sve) (H)" %} 840 ins_encode %{ 841 __ sve_mul(as_FloatRegister($dst_src1$$reg), __ H, 842 ptrue, as_FloatRegister($src2$$reg)); 843 %} 844 ins_pipe(pipe_slow); 845%} 846 847instruct vmulI(vReg dst_src1, vReg src2) %{ 848 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 849 match(Set dst_src1 (MulVI dst_src1 src2)); 850 ins_cost(SVE_COST); 851 format %{ "sve_mul $dst_src1, $dst_src1, $src2\t # vector (sve) (S)" %} 852 ins_encode %{ 853 __ sve_mul(as_FloatRegister($dst_src1$$reg), __ S, 854 ptrue, as_FloatRegister($src2$$reg)); 855 %} 856 ins_pipe(pipe_slow); 857%} 858 859instruct vmulL(vReg dst_src1, vReg src2) %{ 860 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 861 match(Set dst_src1 (MulVL dst_src1 src2)); 862 ins_cost(SVE_COST); 863 format %{ "sve_mul $dst_src1, $dst_src1, $src2\t # vector (sve) (D)" %} 864 ins_encode %{ 865 __ sve_mul(as_FloatRegister($dst_src1$$reg), __ D, 866 ptrue, as_FloatRegister($src2$$reg)); 867 %} 868 ins_pipe(pipe_slow); 869%} 870 871instruct vmulF(vReg dst, vReg src1, vReg src2) %{ 872 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 873 match(Set dst (MulVF src1 src2)); 874 ins_cost(SVE_COST); 875 format %{ "sve_fmul $dst, $src1, $src2\t # vector (sve) (S)" %} 876 ins_encode %{ 877 __ sve_fmul(as_FloatRegister($dst$$reg), __ S, 878 as_FloatRegister($src1$$reg), 879 as_FloatRegister($src2$$reg)); 880 %} 881 ins_pipe(pipe_slow); 882%} 883 884instruct vmulD(vReg dst, vReg src1, vReg src2) %{ 885 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 886 match(Set dst (MulVD src1 src2)); 887 ins_cost(SVE_COST); 888 format %{ "sve_fmul $dst, $src1, $src2\t # vector (sve) (D)" %} 889 ins_encode %{ 890 __ sve_fmul(as_FloatRegister($dst$$reg), __ D, 891 as_FloatRegister($src1$$reg), 892 as_FloatRegister($src2$$reg)); 893 %} 894 ins_pipe(pipe_slow); 895%} 896 897// vector fneg 898 899instruct vnegF(vReg dst, vReg src) %{ 900 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 901 match(Set dst (NegVF src)); 902 ins_cost(SVE_COST); 903 format %{ "sve_fneg $dst, $src\t# vector (sve) (S)" %} 904 ins_encode %{ 905 __ sve_fneg(as_FloatRegister($dst$$reg), __ S, 906 ptrue, as_FloatRegister($src$$reg)); 907 %} 908 ins_pipe(pipe_slow); 909%} 910 911instruct vnegD(vReg dst, vReg src) %{ 912 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 913 match(Set dst (NegVD src)); 914 ins_cost(SVE_COST); 915 format %{ "sve_fneg $dst, $src\t# vector (sve) (D)" %} 916 ins_encode %{ 917 __ sve_fneg(as_FloatRegister($dst$$reg), __ D, 918 ptrue, as_FloatRegister($src$$reg)); 919 %} 920 ins_pipe(pipe_slow); 921%} 922 923// popcount vector 924 925instruct vpopcountI(vReg dst, vReg src) %{ 926 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 927 match(Set dst (PopCountVI src)); 928 format %{ "sve_cnt $dst, $src\t# vector (sve) (S)\n\t" %} 929 ins_encode %{ 930 __ sve_cnt(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg)); 931 %} 932 ins_pipe(pipe_slow); 933%} 934 935// vector add reduction 936 937instruct reduce_addB(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{ 938 predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 && 939 n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); 940 match(Set dst (AddReductionVI src1 src2)); 941 effect(TEMP_DEF dst, TEMP tmp); 942 ins_cost(SVE_COST); 943 format %{ "sve_uaddv $tmp, $src2\t# vector (sve) (B)\n\t" 944 "smov $dst, $tmp, B, 0\n\t" 945 "addw $dst, $dst, $src1\n\t" 946 "sxtb $dst, $dst\t # add reduction B" %} 947 ins_encode %{ 948 __ sve_uaddv(as_FloatRegister($tmp$$reg), __ B, 949 ptrue, as_FloatRegister($src2$$reg)); 950 __ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ B, 0); 951 __ addw($dst$$Register, $dst$$Register, $src1$$Register); 952 __ sxtb($dst$$Register, $dst$$Register); 953 %} 954 ins_pipe(pipe_slow); 955%} 956 957instruct reduce_addS(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{ 958 predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 && 959 n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); 960 match(Set dst (AddReductionVI src1 src2)); 961 effect(TEMP_DEF dst, TEMP tmp); 962 ins_cost(SVE_COST); 963 format %{ "sve_uaddv $tmp, $src2\t# vector (sve) (H)\n\t" 964 "smov $dst, $tmp, H, 0\n\t" 965 "addw $dst, $dst, $src1\n\t" 966 "sxth $dst, $dst\t # add reduction H" %} 967 ins_encode %{ 968 __ sve_uaddv(as_FloatRegister($tmp$$reg), __ H, 969 ptrue, as_FloatRegister($src2$$reg)); 970 __ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ H, 0); 971 __ addw($dst$$Register, $dst$$Register, $src1$$Register); 972 __ sxth($dst$$Register, $dst$$Register); 973 %} 974 ins_pipe(pipe_slow); 975%} 976 977instruct reduce_addI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{ 978 predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 && 979 n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); 980 match(Set dst (AddReductionVI src1 src2)); 981 effect(TEMP_DEF dst, TEMP tmp); 982 ins_cost(SVE_COST); 983 format %{ "sve_uaddv $tmp, $src2\t# vector (sve) (S)\n\t" 984 "umov $dst, $tmp, S, 0\n\t" 985 "addw $dst, $dst, $src1\t # add reduction S" %} 986 ins_encode %{ 987 __ sve_uaddv(as_FloatRegister($tmp$$reg), __ S, 988 ptrue, as_FloatRegister($src2$$reg)); 989 __ umov($dst$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 990 __ addw($dst$$Register, $dst$$Register, $src1$$Register); 991 %} 992 ins_pipe(pipe_slow); 993%} 994 995instruct reduce_addL(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp) %{ 996 predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 && 997 n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); 998 match(Set dst (AddReductionVL src1 src2)); 999 effect(TEMP_DEF dst, TEMP tmp); 1000 ins_cost(SVE_COST); 1001 format %{ "sve_uaddv $tmp, $src2\t# vector (sve) (D)\n\t" 1002 "umov $dst, $tmp, D, 0\n\t" 1003 "add $dst, $dst, $src1\t # add reduction D" %} 1004 ins_encode %{ 1005 __ sve_uaddv(as_FloatRegister($tmp$$reg), __ D, 1006 ptrue, as_FloatRegister($src2$$reg)); 1007 __ umov($dst$$Register, as_FloatRegister($tmp$$reg), __ D, 0); 1008 __ add($dst$$Register, $dst$$Register, $src1$$Register); 1009 %} 1010 ins_pipe(pipe_slow); 1011%} 1012 1013instruct reduce_addF(vRegF src1_dst, vReg src2) %{ 1014 predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16); 1015 match(Set src1_dst (AddReductionVF src1_dst src2)); 1016 ins_cost(SVE_COST); 1017 format %{ "sve_fadda $src1_dst, $src1_dst, $src2\t# vector (sve) (S)" %} 1018 ins_encode %{ 1019 __ sve_fadda(as_FloatRegister($src1_dst$$reg), __ S, 1020 ptrue, as_FloatRegister($src2$$reg)); 1021 %} 1022 ins_pipe(pipe_slow); 1023%} 1024 1025instruct reduce_addD(vRegD src1_dst, vReg src2) %{ 1026 predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16); 1027 match(Set src1_dst (AddReductionVD src1_dst src2)); 1028 ins_cost(SVE_COST); 1029 format %{ "sve_fadda $src1_dst, $src1_dst, $src2\t# vector (sve) (D)" %} 1030 ins_encode %{ 1031 __ sve_fadda(as_FloatRegister($src1_dst$$reg), __ D, 1032 ptrue, as_FloatRegister($src2$$reg)); 1033 %} 1034 ins_pipe(pipe_slow); 1035%} 1036 1037// vector max reduction 1038 1039instruct reduce_maxF(vRegF dst, vRegF src1, vReg src2) %{ 1040 predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT && 1041 n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16); 1042 match(Set dst (MaxReductionV src1 src2)); 1043 ins_cost(INSN_COST); 1044 effect(TEMP_DEF dst); 1045 format %{ "sve_fmaxv $dst, $src2 # vector (sve) (S)\n\t" 1046 "fmaxs $dst, $dst, $src1\t # max reduction F" %} 1047 ins_encode %{ 1048 __ sve_fmaxv(as_FloatRegister($dst$$reg), __ S, 1049 ptrue, as_FloatRegister($src2$$reg)); 1050 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 1051 %} 1052 ins_pipe(pipe_slow); 1053%} 1054 1055instruct reduce_maxD(vRegD dst, vRegD src1, vReg src2) %{ 1056 predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE && 1057 n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16); 1058 match(Set dst (MaxReductionV src1 src2)); 1059 ins_cost(INSN_COST); 1060 effect(TEMP_DEF dst); 1061 format %{ "sve_fmaxv $dst, $src2 # vector (sve) (S)\n\t" 1062 "fmaxs $dst, $dst, $src1\t # max reduction D" %} 1063 ins_encode %{ 1064 __ sve_fmaxv(as_FloatRegister($dst$$reg), __ D, 1065 ptrue, as_FloatRegister($src2$$reg)); 1066 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 1067 %} 1068 ins_pipe(pipe_slow); 1069%} 1070 1071// vector min reduction 1072 1073instruct reduce_minF(vRegF dst, vRegF src1, vReg src2) %{ 1074 predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT && 1075 n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16); 1076 match(Set dst (MinReductionV src1 src2)); 1077 ins_cost(INSN_COST); 1078 effect(TEMP_DEF dst); 1079 format %{ "sve_fminv $dst, $src2 # vector (sve) (S)\n\t" 1080 "fmins $dst, $dst, $src1\t # min reduction F" %} 1081 ins_encode %{ 1082 __ sve_fminv(as_FloatRegister($dst$$reg), __ S, 1083 ptrue, as_FloatRegister($src2$$reg)); 1084 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 1085 %} 1086 ins_pipe(pipe_slow); 1087%} 1088 1089instruct reduce_minD(vRegD dst, vRegD src1, vReg src2) %{ 1090 predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE && 1091 n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16); 1092 match(Set dst (MinReductionV src1 src2)); 1093 ins_cost(INSN_COST); 1094 effect(TEMP_DEF dst); 1095 format %{ "sve_fminv $dst, $src2 # vector (sve) (S)\n\t" 1096 "fmins $dst, $dst, $src1\t # min reduction D" %} 1097 ins_encode %{ 1098 __ sve_fminv(as_FloatRegister($dst$$reg), __ D, 1099 ptrue, as_FloatRegister($src2$$reg)); 1100 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 1101 %} 1102 ins_pipe(pipe_slow); 1103%} 1104 1105// vector Math.rint, floor, ceil 1106 1107instruct vroundD(vReg dst, vReg src, immI rmode) %{ 1108 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2 && 1109 n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 1110 match(Set dst (RoundDoubleModeV src rmode)); 1111 format %{ "sve_frint $dst, $src, $rmode\t# vector (sve) (D)" %} 1112 ins_encode %{ 1113 switch ($rmode$$constant) { 1114 case RoundDoubleModeNode::rmode_rint: 1115 __ sve_frintn(as_FloatRegister($dst$$reg), __ D, 1116 ptrue, as_FloatRegister($src$$reg)); 1117 break; 1118 case RoundDoubleModeNode::rmode_floor: 1119 __ sve_frintm(as_FloatRegister($dst$$reg), __ D, 1120 ptrue, as_FloatRegister($src$$reg)); 1121 break; 1122 case RoundDoubleModeNode::rmode_ceil: 1123 __ sve_frintp(as_FloatRegister($dst$$reg), __ D, 1124 ptrue, as_FloatRegister($src$$reg)); 1125 break; 1126 } 1127 %} 1128 ins_pipe(pipe_slow); 1129%} 1130 1131// vector replicate 1132 1133instruct replicateB(vReg dst, iRegIorL2I src) %{ 1134 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 1135 match(Set dst (ReplicateB src)); 1136 ins_cost(SVE_COST); 1137 format %{ "sve_dup $dst, $src\t# vector (sve) (B)" %} 1138 ins_encode %{ 1139 __ sve_dup(as_FloatRegister($dst$$reg), __ B, as_Register($src$$reg)); 1140 %} 1141 ins_pipe(pipe_slow); 1142%} 1143 1144instruct replicateS(vReg dst, iRegIorL2I src) %{ 1145 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 1146 match(Set dst (ReplicateS src)); 1147 ins_cost(SVE_COST); 1148 format %{ "sve_dup $dst, $src\t# vector (sve) (H)" %} 1149 ins_encode %{ 1150 __ sve_dup(as_FloatRegister($dst$$reg), __ H, as_Register($src$$reg)); 1151 %} 1152 ins_pipe(pipe_slow); 1153%} 1154 1155instruct replicateI(vReg dst, iRegIorL2I src) %{ 1156 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1157 match(Set dst (ReplicateI src)); 1158 ins_cost(SVE_COST); 1159 format %{ "sve_dup $dst, $src\t# vector (sve) (S)" %} 1160 ins_encode %{ 1161 __ sve_dup(as_FloatRegister($dst$$reg), __ S, as_Register($src$$reg)); 1162 %} 1163 ins_pipe(pipe_slow); 1164%} 1165 1166instruct replicateL(vReg dst, iRegL src) %{ 1167 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1168 match(Set dst (ReplicateL src)); 1169 ins_cost(SVE_COST); 1170 format %{ "sve_dup $dst, $src\t# vector (sve) (D)" %} 1171 ins_encode %{ 1172 __ sve_dup(as_FloatRegister($dst$$reg), __ D, as_Register($src$$reg)); 1173 %} 1174 ins_pipe(pipe_slow); 1175%} 1176 1177instruct replicateB_imm8(vReg dst, immI8 con) %{ 1178 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 1179 match(Set dst (ReplicateB con)); 1180 ins_cost(SVE_COST); 1181 format %{ "sve_dup $dst, $con\t# vector (sve) (B)" %} 1182 ins_encode %{ 1183 __ sve_dup(as_FloatRegister($dst$$reg), __ B, $con$$constant); 1184 %} 1185 ins_pipe(pipe_slow); 1186%} 1187 1188instruct replicateS_imm8(vReg dst, immI8_shift8 con) %{ 1189 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 1190 match(Set dst (ReplicateS con)); 1191 ins_cost(SVE_COST); 1192 format %{ "sve_dup $dst, $con\t# vector (sve) (H)" %} 1193 ins_encode %{ 1194 __ sve_dup(as_FloatRegister($dst$$reg), __ H, $con$$constant); 1195 %} 1196 ins_pipe(pipe_slow); 1197%} 1198 1199instruct replicateI_imm8(vReg dst, immI8_shift8 con) %{ 1200 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1201 match(Set dst (ReplicateI con)); 1202 ins_cost(SVE_COST); 1203 format %{ "sve_dup $dst, $con\t# vector (sve) (S)" %} 1204 ins_encode %{ 1205 __ sve_dup(as_FloatRegister($dst$$reg), __ S, $con$$constant); 1206 %} 1207 ins_pipe(pipe_slow); 1208%} 1209 1210instruct replicateL_imm8(vReg dst, immL8_shift8 con) %{ 1211 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1212 match(Set dst (ReplicateL con)); 1213 ins_cost(SVE_COST); 1214 format %{ "sve_dup $dst, $con\t# vector (sve) (D)" %} 1215 ins_encode %{ 1216 __ sve_dup(as_FloatRegister($dst$$reg), __ D, $con$$constant); 1217 %} 1218 ins_pipe(pipe_slow); 1219%} 1220 1221instruct replicateF(vReg dst, vRegF src) %{ 1222 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1223 match(Set dst (ReplicateF src)); 1224 ins_cost(SVE_COST); 1225 format %{ "sve_cpy $dst, $src\t# vector (sve) (S)" %} 1226 ins_encode %{ 1227 __ sve_cpy(as_FloatRegister($dst$$reg), __ S, 1228 ptrue, as_FloatRegister($src$$reg)); 1229 %} 1230 ins_pipe(pipe_slow); 1231%} 1232 1233instruct replicateD(vReg dst, vRegD src) %{ 1234 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1235 match(Set dst (ReplicateD src)); 1236 ins_cost(SVE_COST); 1237 format %{ "sve_cpy $dst, $src\t# vector (sve) (D)" %} 1238 ins_encode %{ 1239 __ sve_cpy(as_FloatRegister($dst$$reg), __ D, 1240 ptrue, as_FloatRegister($src$$reg)); 1241 %} 1242 ins_pipe(pipe_slow); 1243%} 1244 1245// vector shift 1246 1247instruct vasrB(vReg dst, vReg shift) %{ 1248 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 1249 match(Set dst (RShiftVB dst shift)); 1250 ins_cost(SVE_COST); 1251 format %{ "sve_asr $dst, $dst, $shift\t# vector (sve) (B)" %} 1252 ins_encode %{ 1253 __ sve_asr(as_FloatRegister($dst$$reg), __ B, 1254 ptrue, as_FloatRegister($shift$$reg)); 1255 %} 1256 ins_pipe(pipe_slow); 1257%} 1258 1259instruct vasrS(vReg dst, vReg shift) %{ 1260 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 1261 match(Set dst (RShiftVS dst shift)); 1262 ins_cost(SVE_COST); 1263 format %{ "sve_asr $dst, $dst, $shift\t# vector (sve) (H)" %} 1264 ins_encode %{ 1265 __ sve_asr(as_FloatRegister($dst$$reg), __ H, 1266 ptrue, as_FloatRegister($shift$$reg)); 1267 %} 1268 ins_pipe(pipe_slow); 1269%} 1270 1271instruct vasrI(vReg dst, vReg shift) %{ 1272 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1273 match(Set dst (RShiftVI dst shift)); 1274 ins_cost(SVE_COST); 1275 format %{ "sve_asr $dst, $dst, $shift\t# vector (sve) (S)" %} 1276 ins_encode %{ 1277 __ sve_asr(as_FloatRegister($dst$$reg), __ S, 1278 ptrue, as_FloatRegister($shift$$reg)); 1279 %} 1280 ins_pipe(pipe_slow); 1281%} 1282 1283instruct vasrL(vReg dst, vReg shift) %{ 1284 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1285 match(Set dst (RShiftVL dst shift)); 1286 ins_cost(SVE_COST); 1287 format %{ "sve_asr $dst, $dst, $shift\t# vector (sve) (D)" %} 1288 ins_encode %{ 1289 __ sve_asr(as_FloatRegister($dst$$reg), __ D, 1290 ptrue, as_FloatRegister($shift$$reg)); 1291 %} 1292 ins_pipe(pipe_slow); 1293%} 1294 1295instruct vlslB(vReg dst, vReg shift) %{ 1296 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 1297 match(Set dst (LShiftVB dst shift)); 1298 ins_cost(SVE_COST); 1299 format %{ "sve_lsl $dst, $dst, $shift\t# vector (sve) (B)" %} 1300 ins_encode %{ 1301 __ sve_lsl(as_FloatRegister($dst$$reg), __ B, 1302 ptrue, as_FloatRegister($shift$$reg)); 1303 %} 1304 ins_pipe(pipe_slow); 1305%} 1306 1307instruct vlslS(vReg dst, vReg shift) %{ 1308 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 1309 match(Set dst (LShiftVS dst shift)); 1310 ins_cost(SVE_COST); 1311 format %{ "sve_lsl $dst, $dst, $shift\t# vector (sve) (H)" %} 1312 ins_encode %{ 1313 __ sve_lsl(as_FloatRegister($dst$$reg), __ H, 1314 ptrue, as_FloatRegister($shift$$reg)); 1315 %} 1316 ins_pipe(pipe_slow); 1317%} 1318 1319instruct vlslI(vReg dst, vReg shift) %{ 1320 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1321 match(Set dst (LShiftVI dst shift)); 1322 ins_cost(SVE_COST); 1323 format %{ "sve_lsl $dst, $dst, $shift\t# vector (sve) (S)" %} 1324 ins_encode %{ 1325 __ sve_lsl(as_FloatRegister($dst$$reg), __ S, 1326 ptrue, as_FloatRegister($shift$$reg)); 1327 %} 1328 ins_pipe(pipe_slow); 1329%} 1330 1331instruct vlslL(vReg dst, vReg shift) %{ 1332 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1333 match(Set dst (LShiftVL dst shift)); 1334 ins_cost(SVE_COST); 1335 format %{ "sve_lsl $dst, $dst, $shift\t# vector (sve) (D)" %} 1336 ins_encode %{ 1337 __ sve_lsl(as_FloatRegister($dst$$reg), __ D, 1338 ptrue, as_FloatRegister($shift$$reg)); 1339 %} 1340 ins_pipe(pipe_slow); 1341%} 1342 1343instruct vlsrB(vReg dst, vReg shift) %{ 1344 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 1345 match(Set dst (URShiftVB dst shift)); 1346 ins_cost(SVE_COST); 1347 format %{ "sve_lsr $dst, $dst, $shift\t# vector (sve) (B)" %} 1348 ins_encode %{ 1349 __ sve_lsr(as_FloatRegister($dst$$reg), __ B, 1350 ptrue, as_FloatRegister($shift$$reg)); 1351 %} 1352 ins_pipe(pipe_slow); 1353%} 1354 1355instruct vlsrS(vReg dst, vReg shift) %{ 1356 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 1357 match(Set dst (URShiftVS dst shift)); 1358 ins_cost(SVE_COST); 1359 format %{ "sve_lsr $dst, $dst, $shift\t# vector (sve) (H)" %} 1360 ins_encode %{ 1361 __ sve_lsr(as_FloatRegister($dst$$reg), __ H, 1362 ptrue, as_FloatRegister($shift$$reg)); 1363 %} 1364 ins_pipe(pipe_slow); 1365%} 1366 1367instruct vlsrI(vReg dst, vReg shift) %{ 1368 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1369 match(Set dst (URShiftVI dst shift)); 1370 ins_cost(SVE_COST); 1371 format %{ "sve_lsr $dst, $dst, $shift\t# vector (sve) (S)" %} 1372 ins_encode %{ 1373 __ sve_lsr(as_FloatRegister($dst$$reg), __ S, 1374 ptrue, as_FloatRegister($shift$$reg)); 1375 %} 1376 ins_pipe(pipe_slow); 1377%} 1378 1379instruct vlsrL(vReg dst, vReg shift) %{ 1380 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1381 match(Set dst (URShiftVL dst shift)); 1382 ins_cost(SVE_COST); 1383 format %{ "sve_lsr $dst, $dst, $shift\t# vector (sve) (D)" %} 1384 ins_encode %{ 1385 __ sve_lsr(as_FloatRegister($dst$$reg), __ D, 1386 ptrue, as_FloatRegister($shift$$reg)); 1387 %} 1388 ins_pipe(pipe_slow); 1389%} 1390 1391instruct vasrB_imm(vReg dst, vReg src, immI shift) %{ 1392 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 1393 match(Set dst (RShiftVB src (RShiftCntV shift))); 1394 ins_cost(SVE_COST); 1395 format %{ "sve_asr $dst, $src, $shift\t# vector (sve) (B)" %} 1396 ins_encode %{ 1397 int con = (int)$shift$$constant; 1398 if (con == 0) { 1399 __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1400 as_FloatRegister($src$$reg)); 1401 return; 1402 } 1403 if (con >= 8) con = 7; 1404 __ sve_asr(as_FloatRegister($dst$$reg), __ B, 1405 as_FloatRegister($src$$reg), con); 1406 %} 1407 ins_pipe(pipe_slow); 1408%} 1409 1410instruct vasrS_imm(vReg dst, vReg src, immI shift) %{ 1411 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 1412 match(Set dst (RShiftVS src (RShiftCntV shift))); 1413 ins_cost(SVE_COST); 1414 format %{ "sve_asr $dst, $src, $shift\t# vector (sve) (H)" %} 1415 ins_encode %{ 1416 int con = (int)$shift$$constant; 1417 if (con == 0) { 1418 __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1419 as_FloatRegister($src$$reg)); 1420 return; 1421 } 1422 if (con >= 16) con = 15; 1423 __ sve_asr(as_FloatRegister($dst$$reg), __ H, 1424 as_FloatRegister($src$$reg), con); 1425 %} 1426 ins_pipe(pipe_slow); 1427%} 1428 1429instruct vasrI_imm(vReg dst, vReg src, immI shift) %{ 1430 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1431 match(Set dst (RShiftVI src (RShiftCntV shift))); 1432 ins_cost(SVE_COST); 1433 format %{ "sve_asr $dst, $src, $shift\t# vector (sve) (S)" %} 1434 ins_encode %{ 1435 int con = (int)$shift$$constant; 1436 if (con == 0) { 1437 __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1438 as_FloatRegister($src$$reg)); 1439 return; 1440 } 1441 __ sve_asr(as_FloatRegister($dst$$reg), __ S, 1442 as_FloatRegister($src$$reg), con); 1443 %} 1444 ins_pipe(pipe_slow); 1445%} 1446 1447instruct vasrL_imm(vReg dst, vReg src, immI shift) %{ 1448 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1449 match(Set dst (RShiftVL src (RShiftCntV shift))); 1450 ins_cost(SVE_COST); 1451 format %{ "sve_asr $dst, $src, $shift\t# vector (sve) (D)" %} 1452 ins_encode %{ 1453 int con = (int)$shift$$constant; 1454 if (con == 0) { 1455 __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1456 as_FloatRegister($src$$reg)); 1457 return; 1458 } 1459 __ sve_asr(as_FloatRegister($dst$$reg), __ D, 1460 as_FloatRegister($src$$reg), con); 1461 %} 1462 ins_pipe(pipe_slow); 1463%} 1464 1465instruct vlsrB_imm(vReg dst, vReg src, immI shift) %{ 1466 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 1467 match(Set dst (URShiftVB src (RShiftCntV shift))); 1468 ins_cost(SVE_COST); 1469 format %{ "sve_lsr $dst, $src, $shift\t# vector (sve) (B)" %} 1470 ins_encode %{ 1471 int con = (int)$shift$$constant; 1472 if (con == 0) { 1473 __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1474 as_FloatRegister($src$$reg)); 1475 return; 1476 } 1477 if (con >= 8) { 1478 __ sve_eor(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1479 as_FloatRegister($src$$reg)); 1480 return; 1481 } 1482 __ sve_lsr(as_FloatRegister($dst$$reg), __ B, 1483 as_FloatRegister($src$$reg), con); 1484 %} 1485 ins_pipe(pipe_slow); 1486%} 1487 1488instruct vlsrS_imm(vReg dst, vReg src, immI shift) %{ 1489 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 1490 match(Set dst (URShiftVS src (RShiftCntV shift))); 1491 ins_cost(SVE_COST); 1492 format %{ "sve_lsr $dst, $src, $shift\t# vector (sve) (H)" %} 1493 ins_encode %{ 1494 int con = (int)$shift$$constant; 1495 if (con == 0) { 1496 __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1497 as_FloatRegister($src$$reg)); 1498 return; 1499 } 1500 if (con >= 16) { 1501 __ sve_eor(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1502 as_FloatRegister($src$$reg)); 1503 return; 1504 } 1505 __ sve_lsr(as_FloatRegister($dst$$reg), __ H, 1506 as_FloatRegister($src$$reg), con); 1507 %} 1508 ins_pipe(pipe_slow); 1509%} 1510 1511instruct vlsrI_imm(vReg dst, vReg src, immI shift) %{ 1512 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1513 match(Set dst (URShiftVI src (RShiftCntV shift))); 1514 ins_cost(SVE_COST); 1515 format %{ "sve_lsr $dst, $src, $shift\t# vector (sve) (S)" %} 1516 ins_encode %{ 1517 int con = (int)$shift$$constant; 1518 if (con == 0) { 1519 __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1520 as_FloatRegister($src$$reg)); 1521 return; 1522 } 1523 __ sve_lsr(as_FloatRegister($dst$$reg), __ S, 1524 as_FloatRegister($src$$reg), con); 1525 %} 1526 ins_pipe(pipe_slow); 1527%} 1528 1529instruct vlsrL_imm(vReg dst, vReg src, immI shift) %{ 1530 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1531 match(Set dst (URShiftVL src (RShiftCntV shift))); 1532 ins_cost(SVE_COST); 1533 format %{ "sve_lsr $dst, $src, $shift\t# vector (sve) (D)" %} 1534 ins_encode %{ 1535 int con = (int)$shift$$constant; 1536 if (con == 0) { 1537 __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1538 as_FloatRegister($src$$reg)); 1539 return; 1540 } 1541 __ sve_lsr(as_FloatRegister($dst$$reg), __ D, 1542 as_FloatRegister($src$$reg), con); 1543 %} 1544 ins_pipe(pipe_slow); 1545%} 1546 1547instruct vlslB_imm(vReg dst, vReg src, immI shift) %{ 1548 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 1549 match(Set dst (LShiftVB src (LShiftCntV shift))); 1550 ins_cost(SVE_COST); 1551 format %{ "sve_lsl $dst, $src, $shift\t# vector (sve) (B)" %} 1552 ins_encode %{ 1553 int con = (int)$shift$$constant; 1554 if (con >= 8) { 1555 __ sve_eor(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1556 as_FloatRegister($src$$reg)); 1557 return; 1558 } 1559 __ sve_lsl(as_FloatRegister($dst$$reg), __ B, 1560 as_FloatRegister($src$$reg), con); 1561 %} 1562 ins_pipe(pipe_slow); 1563%} 1564 1565instruct vlslS_imm(vReg dst, vReg src, immI shift) %{ 1566 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 1567 match(Set dst (LShiftVS src (LShiftCntV shift))); 1568 ins_cost(SVE_COST); 1569 format %{ "sve_lsl $dst, $src, $shift\t# vector (sve) (H)" %} 1570 ins_encode %{ 1571 int con = (int)$shift$$constant; 1572 if (con >= 16) { 1573 __ sve_eor(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), 1574 as_FloatRegister($src$$reg)); 1575 return; 1576 } 1577 __ sve_lsl(as_FloatRegister($dst$$reg), __ H, 1578 as_FloatRegister($src$$reg), con); 1579 %} 1580 ins_pipe(pipe_slow); 1581%} 1582 1583instruct vlslI_imm(vReg dst, vReg src, immI shift) %{ 1584 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1585 match(Set dst (LShiftVI src (LShiftCntV shift))); 1586 ins_cost(SVE_COST); 1587 format %{ "sve_lsl $dst, $src, $shift\t# vector (sve) (S)" %} 1588 ins_encode %{ 1589 int con = (int)$shift$$constant; 1590 __ sve_lsl(as_FloatRegister($dst$$reg), __ S, 1591 as_FloatRegister($src$$reg), con); 1592 %} 1593 ins_pipe(pipe_slow); 1594%} 1595 1596instruct vlslL_imm(vReg dst, vReg src, immI shift) %{ 1597 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1598 match(Set dst (LShiftVL src (LShiftCntV shift))); 1599 ins_cost(SVE_COST); 1600 format %{ "sve_lsl $dst, $src, $shift\t# vector (sve) (D)" %} 1601 ins_encode %{ 1602 int con = (int)$shift$$constant; 1603 __ sve_lsl(as_FloatRegister($dst$$reg), __ D, 1604 as_FloatRegister($src$$reg), con); 1605 %} 1606 ins_pipe(pipe_slow); 1607%} 1608 1609instruct vshiftcntB(vReg dst, iRegIorL2I cnt) %{ 1610 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16 && 1611 (n->bottom_type()->is_vect()->element_basic_type() == T_BYTE)); 1612 match(Set dst (LShiftCntV cnt)); 1613 match(Set dst (RShiftCntV cnt)); 1614 format %{ "sve_dup $dst, $cnt\t# vector shift count (sve) (B)" %} 1615 ins_encode %{ 1616 __ sve_dup(as_FloatRegister($dst$$reg), __ B, as_Register($cnt$$reg)); 1617 %} 1618 ins_pipe(pipe_slow); 1619%} 1620 1621instruct vshiftcntS(vReg dst, iRegIorL2I cnt) %{ 1622 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8 && 1623 (n->bottom_type()->is_vect()->element_basic_type() == T_SHORT || 1624 (n->bottom_type()->is_vect()->element_basic_type() == T_CHAR))); 1625 match(Set dst (LShiftCntV cnt)); 1626 match(Set dst (RShiftCntV cnt)); 1627 format %{ "sve_dup $dst, $cnt\t# vector shift count (sve) (H)" %} 1628 ins_encode %{ 1629 __ sve_dup(as_FloatRegister($dst$$reg), __ H, as_Register($cnt$$reg)); 1630 %} 1631 ins_pipe(pipe_slow); 1632%} 1633 1634instruct vshiftcntI(vReg dst, iRegIorL2I cnt) %{ 1635 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4 && 1636 (n->bottom_type()->is_vect()->element_basic_type() == T_INT)); 1637 match(Set dst (LShiftCntV cnt)); 1638 match(Set dst (RShiftCntV cnt)); 1639 format %{ "sve_dup $dst, $cnt\t# vector shift count (sve) (S)" %} 1640 ins_encode %{ 1641 __ sve_dup(as_FloatRegister($dst$$reg), __ S, as_Register($cnt$$reg)); 1642 %} 1643 ins_pipe(pipe_slow); 1644%} 1645 1646instruct vshiftcntL(vReg dst, iRegIorL2I cnt) %{ 1647 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2 && 1648 (n->bottom_type()->is_vect()->element_basic_type() == T_LONG)); 1649 match(Set dst (LShiftCntV cnt)); 1650 match(Set dst (RShiftCntV cnt)); 1651 format %{ "sve_dup $dst, $cnt\t# vector shift count (sve) (D)" %} 1652 ins_encode %{ 1653 __ sve_dup(as_FloatRegister($dst$$reg), __ D, as_Register($cnt$$reg)); 1654 %} 1655 ins_pipe(pipe_slow); 1656%} 1657 1658// vector sqrt 1659 1660instruct vsqrtF(vReg dst, vReg src) %{ 1661 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 1662 match(Set dst (SqrtVF src)); 1663 ins_cost(SVE_COST); 1664 format %{ "sve_fsqrt $dst, $src\t# vector (sve) (S)" %} 1665 ins_encode %{ 1666 __ sve_fsqrt(as_FloatRegister($dst$$reg), __ S, 1667 ptrue, as_FloatRegister($src$$reg)); 1668 %} 1669 ins_pipe(pipe_slow); 1670%} 1671 1672instruct vsqrtD(vReg dst, vReg src) %{ 1673 predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16); 1674 match(Set dst (SqrtVD src)); 1675 ins_cost(SVE_COST); 1676 format %{ "sve_fsqrt $dst, $src\t# vector (sve) (D)" %} 1677 ins_encode %{ 1678 __ sve_fsqrt(as_FloatRegister($dst$$reg), __ D, 1679 ptrue, as_FloatRegister($src$$reg)); 1680 %} 1681 ins_pipe(pipe_slow); 1682%} 1683 1684// vector sub 1685 1686instruct vsubB(vReg dst, vReg src1, vReg src2) %{ 1687 predicate(UseSVE > 0 && n->as_Vector()->length() >= 16); 1688 match(Set dst (SubVB src1 src2)); 1689 ins_cost(SVE_COST); 1690 format %{ "sve_sub $dst, $src1, $src2\t # vector (sve) (B)" %} 1691 ins_encode %{ 1692 __ sve_sub(as_FloatRegister($dst$$reg), __ B, 1693 as_FloatRegister($src1$$reg), 1694 as_FloatRegister($src2$$reg)); 1695 %} 1696 ins_pipe(pipe_slow); 1697%} 1698 1699instruct vsubS(vReg dst, vReg src1, vReg src2) %{ 1700 predicate(UseSVE > 0 && n->as_Vector()->length() >= 8); 1701 match(Set dst (SubVS src1 src2)); 1702 ins_cost(SVE_COST); 1703 format %{ "sve_sub $dst, $src1, $src2\t # vector (sve) (H)" %} 1704 ins_encode %{ 1705 __ sve_sub(as_FloatRegister($dst$$reg), __ H, 1706 as_FloatRegister($src1$$reg), 1707 as_FloatRegister($src2$$reg)); 1708 %} 1709 ins_pipe(pipe_slow); 1710%} 1711 1712instruct vsubI(vReg dst, vReg src1, vReg src2) %{ 1713 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1714 match(Set dst (SubVI src1 src2)); 1715 ins_cost(SVE_COST); 1716 format %{ "sve_sub $dst, $src1, $src2\t # vector (sve) (S)" %} 1717 ins_encode %{ 1718 __ sve_sub(as_FloatRegister($dst$$reg), __ S, 1719 as_FloatRegister($src1$$reg), 1720 as_FloatRegister($src2$$reg)); 1721 %} 1722 ins_pipe(pipe_slow); 1723%} 1724 1725instruct vsubL(vReg dst, vReg src1, vReg src2) %{ 1726 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1727 match(Set dst (SubVL src1 src2)); 1728 ins_cost(SVE_COST); 1729 format %{ "sve_sub $dst, $src1, $src2\t # vector (sve) (D)" %} 1730 ins_encode %{ 1731 __ sve_sub(as_FloatRegister($dst$$reg), __ D, 1732 as_FloatRegister($src1$$reg), 1733 as_FloatRegister($src2$$reg)); 1734 %} 1735 ins_pipe(pipe_slow); 1736%} 1737 1738instruct vsubF(vReg dst, vReg src1, vReg src2) %{ 1739 predicate(UseSVE > 0 && n->as_Vector()->length() >= 4); 1740 match(Set dst (SubVF src1 src2)); 1741 ins_cost(SVE_COST); 1742 format %{ "sve_fsub $dst, $src1, $src2\t # vector (sve) (S)" %} 1743 ins_encode %{ 1744 __ sve_fsub(as_FloatRegister($dst$$reg), __ S, 1745 as_FloatRegister($src1$$reg), 1746 as_FloatRegister($src2$$reg)); 1747 %} 1748 ins_pipe(pipe_slow); 1749%} 1750 1751instruct vsubD(vReg dst, vReg src1, vReg src2) %{ 1752 predicate(UseSVE > 0 && n->as_Vector()->length() >= 2); 1753 match(Set dst (SubVD src1 src2)); 1754 ins_cost(SVE_COST); 1755 format %{ "sve_fsub $dst, $src1, $src2\t # vector (sve) (D)" %} 1756 ins_encode %{ 1757 __ sve_fsub(as_FloatRegister($dst$$reg), __ D, 1758 as_FloatRegister($src1$$reg), 1759 as_FloatRegister($src2$$reg)); 1760 %} 1761 ins_pipe(pipe_slow); 1762%} 1763 1764// vector mask cast 1765 1766instruct vmaskcast(vReg dst) %{ 1767 predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length() == n->in(1)->bottom_type()->is_vect()->length() && 1768 n->bottom_type()->is_vect()->length_in_bytes() == n->in(1)->bottom_type()->is_vect()->length_in_bytes()); 1769 match(Set dst (VectorMaskCast dst)); 1770 ins_cost(0); 1771 format %{ "vmaskcast $dst\t# empty (sve)" %} 1772 ins_encode %{ 1773 // empty 1774 %} 1775 ins_pipe(pipe_class_empty); 1776%} 1777 1778