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