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