[PR testsuite/116860] Testsuite adjustment for recently added tests
[official-gcc.git] / gcc / config / arm / arm-mve-builtins-base.cc
blobfd0be2cbcd87f0e112fb388b2d61261d5036f08f
1 /* ACLE support for Arm MVE (__ARM_FEATURE_MVE intrinsics)
2 Copyright (C) 2023-2025 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "tree.h"
25 #include "rtl.h"
26 #include "memmodel.h"
27 #include "insn-codes.h"
28 #include "optabs.h"
29 #include "expr.h"
30 #include "basic-block.h"
31 #include "function.h"
32 #include "gimple.h"
33 #include "emit-rtl.h"
34 #include "arm-mve-builtins.h"
35 #include "arm-mve-builtins-shapes.h"
36 #include "arm-mve-builtins-base.h"
37 #include "arm-mve-builtins-functions.h"
39 using namespace arm_mve;
41 namespace {
43 /* Implements vdup_* intrinsics. */
44 class vdupq_impl : public quiet<function_base>
46 public:
47 CONSTEXPR vdupq_impl (int unspec_for_m_n_sint,
48 int unspec_for_m_n_uint,
49 int unspec_for_m_n_fp)
50 : m_unspec_for_m_n_sint (unspec_for_m_n_sint),
51 m_unspec_for_m_n_uint (unspec_for_m_n_uint),
52 m_unspec_for_m_n_fp (unspec_for_m_n_fp)
54 int m_unspec_for_m_n_sint;
55 int m_unspec_for_m_n_uint;
56 int m_unspec_for_m_n_fp;
58 rtx expand (function_expander &e) const override
60 gcc_assert (e.mode_suffix_id == MODE_n);
62 insn_code code;
63 machine_mode mode = e.vector_mode (0);
65 switch (e.pred)
67 case PRED_none:
68 /* No predicate, _n suffix. */
69 code = code_for_mve_vdupq_n (mode);
70 return e.use_exact_insn (code);
72 case PRED_m:
73 case PRED_x:
74 /* "m" or "x" predicate, _n suffix. */
75 if (e.type_suffix (0).integer_p)
76 if (e.type_suffix (0).unsigned_p)
77 code = code_for_mve_q_m_n (m_unspec_for_m_n_uint,
78 m_unspec_for_m_n_uint, mode);
79 else
80 code = code_for_mve_q_m_n (m_unspec_for_m_n_sint,
81 m_unspec_for_m_n_sint, mode);
82 else
83 code = code_for_mve_q_m_n_f (m_unspec_for_m_n_fp, mode);
85 if (e.pred == PRED_m)
86 return e.use_cond_insn (code, 0);
87 else
88 return e.use_pred_x_insn (code);
90 default:
91 gcc_unreachable ();
96 /* Implements vreinterpretq_* intrinsics. */
97 class vreinterpretq_impl : public quiet<function_base>
99 gimple *
100 fold (gimple_folder &f) const override
102 /* We should punt to rtl if the effect of the reinterpret on
103 registers does not conform to GCC's endianness model like we do
104 on aarch64, but MVE intrinsics are not currently supported on
105 big-endian. For this, we'd need to handle big-endian properly
106 in the .md file, like we do on aarch64 with
107 define_insn_and_split "*aarch64_sve_reinterpret<mode>". */
108 gcc_assert (targetm.can_change_mode_class (f.vector_mode (0),
109 f.vector_mode (1),
110 VFP_REGS));
112 /* Otherwise vreinterpret corresponds directly to a VIEW_CONVERT_EXPR
113 reinterpretation. */
114 tree rhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (f.lhs),
115 gimple_call_arg (f.call, 0));
116 return gimple_build_assign (f.lhs, VIEW_CONVERT_EXPR, rhs);
120 expand (function_expander &e) const override
122 machine_mode mode = e.vector_mode (0);
123 return e.use_exact_insn (code_for_arm_mve_reinterpret (mode));
127 /* Implements vuninitializedq_* intrinsics. */
128 class vuninitializedq_impl : public quiet<function_base>
132 expand (function_expander &e) const override
134 rtx target = e.get_reg_target ();
135 emit_clobber (copy_rtx (target));
136 return target;
140 class vld1_impl : public full_width_access
142 public:
143 unsigned int
144 call_properties (const function_instance &) const override
146 return CP_READ_MEMORY;
150 expand (function_expander &e) const override
152 insn_code icode;
153 switch (e.pred)
155 case PRED_none:
156 icode = code_for_mve_vldrq (e.vector_mode (0));
157 break;
159 case PRED_z:
160 icode = code_for_mve_vldrq_z (e.vector_mode (0));
161 break;
163 default:
164 gcc_unreachable ();
166 return e.use_contiguous_load_insn (icode);
170 class vst1_impl : public full_width_access
172 public:
173 unsigned int
174 call_properties (const function_instance &) const override
176 return CP_WRITE_MEMORY;
180 expand (function_expander &e) const override
182 insn_code icode;
183 switch (e.pred)
185 case PRED_none:
186 icode = code_for_mve_vstrq (e.vector_mode (0));
187 break;
189 case PRED_p:
190 icode = code_for_mve_vstrq_p (e.vector_mode (0));
191 break;
193 default:
194 gcc_unreachable ();
196 return e.use_contiguous_store_insn (icode);
200 /* Builds the vstrq* intrinsics. */
201 class vstrq_impl : public store_truncating
203 public:
204 using store_truncating::store_truncating;
206 rtx expand (function_expander &e) const override
208 insn_code icode;
209 switch (e.pred)
211 case PRED_none:
212 if (e.vector_mode (0) == e.memory_vector_mode ())
213 /* Non-truncating store case. */
214 icode = code_for_mve_vstrq (e.vector_mode (0));
215 else
216 /* Truncating store case.
217 (there is only one possible truncation for each memory mode so only
218 one mode argument is needed). */
219 icode = code_for_mve_vstrq_truncate (e.memory_vector_mode ());
220 break;
222 case PRED_p:
223 if (e.vector_mode (0) == e.memory_vector_mode ())
224 icode = code_for_mve_vstrq_p (e.vector_mode (0));
225 else
226 icode = code_for_mve_vstrq_p_truncate (e.memory_vector_mode ());
227 break;
229 default:
230 gcc_unreachable ();
233 return e.use_contiguous_store_insn (icode);
237 /* Builds the vstrq_scatter*offset intrinsics. */
238 class vstrq_scatter_impl : public store_truncating
240 public:
241 using store_truncating::store_truncating;
243 CONSTEXPR vstrq_scatter_impl (bool shifted,
244 scalar_mode to_int_mode,
245 opt_scalar_mode to_float_mode)
246 : store_truncating (to_int_mode, to_float_mode),
247 m_shifted (shifted)
250 /* Shifted offset (true) or plain offset (false). */
251 bool m_shifted;
253 rtx expand (function_expander &e) const override
255 insn_code icode;
256 machine_mode memory_mode = e.memory_vector_mode ();
258 switch (e.pred)
260 case PRED_none:
261 icode = (e.vector_mode (0) == memory_mode
262 /* Non-truncating store case. */
263 ? (m_shifted
264 ? code_for_mve_vstrq_scatter_shifted_offset (memory_mode)
265 : code_for_mve_vstrq_scatter_offset (memory_mode))
266 /* Truncating store case. */
267 : (m_shifted
268 ? CODE_FOR_mve_vstrq_truncate_scatter_shifted_offset_v4si
269 : code_for_mve_vstrq_truncate_scatter_offset (memory_mode)));
270 break;
272 case PRED_p:
273 icode = (e.vector_mode (0) == memory_mode
274 ? (m_shifted
275 ? code_for_mve_vstrq_scatter_shifted_offset_p (memory_mode)
276 : code_for_mve_vstrq_scatter_offset_p (memory_mode))
277 : (m_shifted
278 ? CODE_FOR_mve_vstrq_truncate_scatter_shifted_offset_p_v4si
279 : code_for_mve_vstrq_truncate_scatter_offset_p (memory_mode)));
280 break;
282 default:
283 gcc_unreachable ();
285 return e.use_exact_insn (icode);
289 /* Builds the vstrq_scatter_base intrinsics. */
290 class vstrq_scatter_base_impl : public function_base
292 public:
293 CONSTEXPR vstrq_scatter_base_impl (scalar_mode to_int_mode)
294 : m_to_int_mode (to_int_mode)
297 unsigned int call_properties (const function_instance &) const override
299 return CP_WRITE_MEMORY;
302 machine_mode memory_vector_mode (const function_instance &fi) const override
304 poly_uint64 nunits = GET_MODE_NUNITS (fi.vector_mode (0));
305 return arm_mve_data_mode (m_to_int_mode, nunits).require ();
308 rtx expand (function_expander &e) const override
310 insn_code icode;
311 rtx insns, base_ptr, new_base = NULL_RTX;
312 machine_mode base_mode;
314 if ((e.mode_suffix_id != MODE_none)
315 && (e.mode_suffix_id != MODE_wb))
316 gcc_unreachable ();
318 /* In _wb mode, the start offset is passed via a pointer,
319 dereference it. */
320 if (e.mode_suffix_id == MODE_wb)
322 base_mode = e.memory_vector_mode ();
323 rtx base = gen_reg_rtx (base_mode);
324 base_ptr = e.args[0];
325 emit_insn (gen_rtx_SET (base, gen_rtx_MEM (base_mode, base_ptr)));
326 e.args[0] = base;
327 new_base = gen_reg_rtx (base_mode);
328 e.args.quick_insert (0, new_base);
331 switch (e.pred)
333 case PRED_none:
334 icode = (e.mode_suffix_id == MODE_none)
335 ? code_for_mve_vstrq_scatter_base (e.vector_mode (0))
336 : code_for_mve_vstrq_scatter_base_wb (e.vector_mode (0));
337 break;
339 case PRED_p:
340 icode = (e.mode_suffix_id == MODE_none)
341 ? code_for_mve_vstrq_scatter_base_p (e.vector_mode (0))
342 : code_for_mve_vstrq_scatter_base_wb_p (e.vector_mode (0));
343 break;
345 default:
346 gcc_unreachable ();
348 insns = e.use_exact_insn (icode);
350 /* Update offset as appropriate. */
351 if (e.mode_suffix_id == MODE_wb)
352 emit_insn (gen_rtx_SET (gen_rtx_MEM (base_mode, base_ptr), new_base));
354 return insns;
357 /* The mode of a single memory element. */
358 scalar_mode m_to_int_mode;
361 /* Builds the vldrq* intrinsics. */
362 class vldrq_impl : public load_extending
364 public:
365 using load_extending::load_extending;
367 rtx expand (function_expander &e) const override
369 insn_code icode;
370 switch (e.pred)
372 case PRED_none:
373 if (e.vector_mode (0) == e.memory_vector_mode ())
374 /* Non-extending load case. */
375 icode = code_for_mve_vldrq (e.vector_mode (0));
376 else
377 /* Extending load case.
378 (there is only one extension for each memory mode so only one type
379 argument is needed). */
380 icode = code_for_mve_vldrq_extend (e.memory_vector_mode (),
381 e.type_suffix (0).unsigned_p
382 ? ZERO_EXTEND
383 : SIGN_EXTEND);
384 break;
386 case PRED_z:
387 if (e.vector_mode (0) == e.memory_vector_mode ())
388 icode = code_for_mve_vldrq_z (e.vector_mode (0));
389 else
390 icode = code_for_mve_vldrq_z_extend (e.memory_vector_mode (),
391 e.type_suffix (0).unsigned_p
392 ? ZERO_EXTEND
393 : SIGN_EXTEND);
394 break;
396 default:
397 gcc_unreachable ();
400 return e.use_contiguous_load_insn (icode);
404 /* Builds the vldrq_gather*offset intrinsics. */
405 class vldrq_gather_impl : public load_extending
407 public:
408 using load_extending::load_extending;
410 CONSTEXPR vldrq_gather_impl (bool shifted,
411 type_suffix_index signed_memory_type,
412 type_suffix_index unsigned_memory_type,
413 type_suffix_index float_memory_type)
414 : load_extending (signed_memory_type, unsigned_memory_type, float_memory_type),
415 m_shifted (shifted)
418 CONSTEXPR vldrq_gather_impl (bool shifted,
419 type_suffix_index signed_memory_type,
420 type_suffix_index unsigned_memory_type)
421 : load_extending (signed_memory_type, unsigned_memory_type, NUM_TYPE_SUFFIXES),
422 m_shifted (shifted)
425 /* Shifted offset (true) or plain offset (false). */
426 bool m_shifted;
428 rtx expand (function_expander &e) const override
430 insn_code icode;
431 machine_mode memory_mode = e.memory_vector_mode ();
432 rtx_code extend = (e.type_suffix (0).unsigned_p
433 ? ZERO_EXTEND
434 : SIGN_EXTEND);
436 switch (e.pred)
438 case PRED_none:
439 icode = (e.vector_mode (0) == memory_mode
440 /* Non-extending load case. */
441 ? (m_shifted
442 ? code_for_mve_vldrq_gather_shifted_offset (memory_mode)
443 : code_for_mve_vldrq_gather_offset (memory_mode))
444 /* Extending load case. */
445 : (m_shifted
446 ? code_for_mve_vldrq_gather_shifted_offset_extend_v4si (extend)
447 : code_for_mve_vldrq_gather_offset_extend (memory_mode,
448 extend)));
449 break;
451 case PRED_z:
452 icode = (e.vector_mode (0) == memory_mode
453 ? (m_shifted
454 ? code_for_mve_vldrq_gather_shifted_offset_z (memory_mode)
455 : code_for_mve_vldrq_gather_offset_z (memory_mode))
456 : (m_shifted
457 ? code_for_mve_vldrq_gather_shifted_offset_z_extend_v4si (extend)
458 : code_for_mve_vldrq_gather_offset_z_extend (memory_mode,
459 extend)));
460 break;
462 default:
463 gcc_unreachable ();
466 return e.use_exact_insn (icode);
470 /* Builds the vldrq_gather_base intrinsics. */
471 class vldrq_gather_base_impl : public load_extending
473 public:
474 using load_extending::load_extending;
476 machine_mode memory_vector_mode (const function_instance &fi) const override
478 unsigned int element_bits = fi.type_suffix (0).element_bits;
479 type_suffix_index suffix = find_type_suffix (TYPE_unsigned, element_bits);
480 return type_suffixes[suffix].vector_mode;
483 rtx expand (function_expander &e) const override
485 insn_code icode;
486 rtx insns, base_ptr, new_base = NULL_RTX;
487 machine_mode base_mode;
489 if ((e.mode_suffix_id != MODE_none)
490 && (e.mode_suffix_id != MODE_wb))
491 gcc_unreachable ();
493 /* In _wb mode, the start offset is passed via a pointer,
494 dereference it. */
495 if (e.mode_suffix_id == MODE_wb)
497 base_mode = e.memory_vector_mode ();
498 rtx base = gen_reg_rtx (base_mode);
499 base_ptr = e.args[0];
500 emit_insn (gen_rtx_SET (base, gen_rtx_MEM (base_mode, base_ptr)));
501 e.args[0] = base;
502 new_base = gen_reg_rtx (base_mode);
503 e.args.quick_insert (0, new_base);
506 switch (e.pred)
508 case PRED_none:
509 icode = (e.mode_suffix_id == MODE_none)
510 ? code_for_mve_vldrq_gather_base (e.vector_mode (0))
511 : code_for_mve_vldrq_gather_base_wb (e.vector_mode (0));
512 break;
514 case PRED_z:
515 icode = (e.mode_suffix_id == MODE_none)
516 ? code_for_mve_vldrq_gather_base_z (e.vector_mode (0))
517 : code_for_mve_vldrq_gather_base_wb_z (e.vector_mode (0));
518 break;
520 default:
521 gcc_unreachable ();
523 insns = e.use_exact_insn (icode);
525 /* Update offset as appropriate. */
526 if (e.mode_suffix_id == MODE_wb)
527 emit_insn (gen_rtx_SET (gen_rtx_MEM (base_mode, base_ptr), new_base));
529 return insns;
533 /* Implements vctp8q, vctp16q, vctp32q and vctp64q intrinsics. */
534 class vctpq_impl : public function_base
536 public:
537 CONSTEXPR vctpq_impl (machine_mode mode)
538 : m_mode (mode)
541 /* Mode this intrinsic operates on. */
542 machine_mode m_mode;
545 expand (function_expander &e) const override
547 insn_code code;
548 rtx target;
550 if (e.mode_suffix_id != MODE_none)
551 gcc_unreachable ();
553 switch (e.pred)
555 case PRED_none:
556 /* No predicate, no suffix. */
557 code = code_for_mve_vctpq (m_mode, m_mode);
558 target = e.use_exact_insn (code);
559 break;
561 case PRED_m:
562 /* No suffix, "m" predicate. */
563 code = code_for_mve_vctpq_m (m_mode, m_mode);
564 target = e.use_cond_insn (code, 0);
565 break;
567 default:
568 gcc_unreachable ();
571 rtx HItarget = gen_reg_rtx (HImode);
572 emit_move_insn (HItarget, gen_lowpart (HImode, target));
573 return HItarget;
577 /* Implements vcvtq intrinsics. */
578 class vcvtq_impl : public function_base
580 public:
582 expand (function_expander &e) const override
584 insn_code code;
585 machine_mode target_mode = e.vector_mode (0);
586 int unspec;
587 switch (e.pred)
589 case PRED_none:
590 switch (e.mode_suffix_id)
592 case MODE_none:
593 /* No predicate, no suffix. */
594 if (e.type_suffix (0).integer_p)
596 unspec = (e.type_suffix (0).unsigned_p
597 ? VCVTQ_FROM_F_U
598 : VCVTQ_FROM_F_S);
599 code = code_for_mve_q_from_f (unspec, unspec, target_mode);
601 else
603 unspec = (e.type_suffix (1).unsigned_p
604 ? VCVTQ_TO_F_U
605 : VCVTQ_TO_F_S);
606 code = code_for_mve_q_to_f (unspec, unspec, target_mode);
608 break;
610 case MODE_n:
611 /* No predicate, _n suffix. */
612 if (e.type_suffix (0).integer_p)
614 unspec = (e.type_suffix (0).unsigned_p
615 ? VCVTQ_N_FROM_F_U
616 : VCVTQ_N_FROM_F_S);
617 code = code_for_mve_q_n_from_f (unspec, unspec, target_mode);
619 else
621 unspec = (e.type_suffix (1).unsigned_p
622 ? VCVTQ_N_TO_F_U
623 : VCVTQ_N_TO_F_S);
624 code = code_for_mve_q_n_to_f (unspec, unspec, target_mode);
626 break;
628 default:
629 gcc_unreachable ();
631 return e.use_exact_insn (code);
633 case PRED_m:
634 case PRED_x:
635 switch (e.mode_suffix_id)
637 case MODE_none:
638 /* No suffix, "m" or "x" predicate. */
639 if (e.type_suffix (0).integer_p)
641 unspec = (e.type_suffix (0).unsigned_p
642 ? VCVTQ_M_FROM_F_U
643 : VCVTQ_M_FROM_F_S);
644 code = code_for_mve_q_m_from_f (unspec, unspec, target_mode);
646 else
648 unspec = (e.type_suffix (1).unsigned_p
649 ? VCVTQ_M_TO_F_U
650 : VCVTQ_M_TO_F_S);
651 code = code_for_mve_q_m_to_f (unspec, unspec, target_mode);
653 break;
655 case MODE_n:
656 /* _n suffix, "m" or "x" predicate. */
657 if (e.type_suffix (0).integer_p)
659 unspec = (e.type_suffix (0).unsigned_p
660 ? VCVTQ_M_N_FROM_F_U
661 : VCVTQ_M_N_FROM_F_S);
662 code = code_for_mve_q_m_n_from_f (unspec, unspec, target_mode);
664 else
666 unspec = (e.type_suffix (1).unsigned_p
667 ? VCVTQ_M_N_TO_F_U
668 : VCVTQ_M_N_TO_F_S);
669 code = code_for_mve_q_m_n_to_f (unspec, unspec, target_mode);
671 break;
673 default:
674 gcc_unreachable ();
676 if (e.pred == PRED_m)
677 return e.use_cond_insn (code, 0);
678 else
679 return e.use_pred_x_insn (code);
681 default:
682 gcc_unreachable ();
685 gcc_unreachable ();
689 /* Implements vcvt[bt]q_f32_f16 and vcvt[bt]q_f16_f32
690 intrinsics. */
691 class vcvtxq_impl : public function_base
693 public:
694 CONSTEXPR vcvtxq_impl (int unspec_f16_f32, int unspec_for_m_f16_f32,
695 int unspec_f32_f16, int unspec_for_m_f32_f16)
696 : m_unspec_f16_f32 (unspec_f16_f32),
697 m_unspec_for_m_f16_f32 (unspec_for_m_f16_f32),
698 m_unspec_f32_f16 (unspec_f32_f16),
699 m_unspec_for_m_f32_f16 (unspec_for_m_f32_f16)
702 /* The unspec code associated with vcvt[bt]q. */
703 int m_unspec_f16_f32;
704 int m_unspec_for_m_f16_f32;
705 int m_unspec_f32_f16;
706 int m_unspec_for_m_f32_f16;
709 expand (function_expander &e) const override
711 insn_code code;
712 switch (e.pred)
714 case PRED_none:
715 /* No predicate. */
716 if (e.type_suffix (0).element_bits == 16)
717 code = code_for_mve_q_f16_f32v8hf (m_unspec_f16_f32);
718 else
719 code = code_for_mve_q_f32_f16v4sf (m_unspec_f32_f16);
720 return e.use_exact_insn (code);
722 case PRED_m:
723 case PRED_x:
724 /* "m" or "x" predicate. */
725 if (e.type_suffix (0).element_bits == 16)
726 code = code_for_mve_q_m_f16_f32v8hf (m_unspec_for_m_f16_f32);
727 else
728 code = code_for_mve_q_m_f32_f16v4sf (m_unspec_for_m_f32_f16);
730 if (e.pred == PRED_m)
731 return e.use_cond_insn (code, 0);
732 else
733 return e.use_pred_x_insn (code);
735 default:
736 gcc_unreachable ();
739 gcc_unreachable ();
743 /* Map the vidup / vddup function directly to CODE (UNSPEC, M) where M is the
744 vector mode associated with type suffix 0. We need this special case
745 because in MODE_wb the builtins derefrence the first parameter and update
746 its contents. We also have to insert the two additional parameters needed
747 by the builtins compared to the intrinsics. In wrapping mode, we have to
748 match the 'hack' to make sure the 'wrap' parameters is in odd register. */
749 class viddup_impl : public function_base
751 public:
752 CONSTEXPR viddup_impl (bool inc_dec, bool wrap)
753 : m_inc_dec (inc_dec), m_wrap (wrap)
756 /* Increment (true) or decrement (false). */
757 bool m_inc_dec;
758 /* v[id]wdup (true) or v[id]dup (false). */
759 bool m_wrap;
761 unsigned int
762 call_properties (const function_instance &fi) const override
764 if (fi.mode_suffix_id == MODE_wb)
765 return CP_WRITE_MEMORY | CP_READ_MEMORY;
766 else
767 return 0;
770 tree
771 memory_scalar_type (const function_instance &) const override
773 return get_typenode_from_name (UINT32_TYPE);
777 expand (function_expander &e) const override
779 machine_mode mode = e.vector_mode (0);
780 insn_code code;
781 rtx insns, offset_ptr;
782 rtx new_offset;
783 int offset_arg_no;
785 if (! e.type_suffix (0).integer_p)
786 gcc_unreachable ();
788 if ((e.mode_suffix_id != MODE_n)
789 && (e.mode_suffix_id != MODE_wb))
790 gcc_unreachable ();
792 offset_arg_no = (e.pred == PRED_m) ? 1 : 0;
794 /* In _wb mode, the start offset is passed via a pointer,
795 dereference it. */
796 if (e.mode_suffix_id == MODE_wb)
798 rtx offset = gen_reg_rtx (SImode);
799 offset_ptr = e.args[offset_arg_no];
800 emit_insn (gen_rtx_SET (offset, gen_rtx_MEM (SImode, offset_ptr)));
801 e.args[offset_arg_no] = offset;
804 /* We have to shuffle parameters because the builtin needs additional
805 arguments:
806 - the updated "new_offset"
807 - total increment (incr * number of lanes) in the non-wrapping case
808 - hack to pass wrap in the top end of DImode operand so that it is
809 actually in a odd register */
810 new_offset = gen_reg_rtx (SImode);
811 e.args.quick_insert (offset_arg_no, new_offset);
813 if (m_wrap)
815 rtx wrap = gen_reg_rtx (DImode);
816 emit_insn (gen_rtx_SET (gen_rtx_SUBREG (SImode, wrap, 4),
817 e.args[offset_arg_no + 2]));
818 emit_insn (gen_rtx_SET (gen_rtx_SUBREG (SImode, wrap, 0),
819 GEN_INT (0)));
820 e.args[offset_arg_no + 2] = wrap;
822 else
824 rtx incr = e.args[offset_arg_no + 2];
825 rtx total_incr = gen_int_mode (INTVAL (incr)
826 * GET_MODE_NUNITS (e.vector_mode (0)),
827 SImode);
828 e.args.quick_push (total_incr);
831 /* _wb mode uses the _n builtins and adds code to update the
832 offset. */
833 switch (e.pred)
835 case PRED_none:
836 /* No predicate. */
837 code = m_wrap
838 ? (m_inc_dec
839 ? code_for_mve_q_wb_u_insn (VIWDUPQ, mode)
840 : code_for_mve_q_wb_u_insn (VDWDUPQ, mode))
841 : (m_inc_dec
842 ? code_for_mve_q_u_insn (VIDUPQ, mode)
843 : code_for_mve_q_u_insn (VDDUPQ, mode));
844 insns = e.use_exact_insn (code);
845 break;
847 case PRED_m:
848 case PRED_x:
849 /* "m" or "x" predicate. */
850 code = m_wrap
851 ? (m_inc_dec
852 ? code_for_mve_q_m_wb_u_insn (VIWDUPQ_M, mode)
853 : code_for_mve_q_m_wb_u_insn (VDWDUPQ_M, mode))
854 : (m_inc_dec
855 ? code_for_mve_q_m_wb_u_insn (VIDUPQ_M, mode)
856 : code_for_mve_q_m_wb_u_insn (VDDUPQ_M, mode));
858 if (e.pred == PRED_m)
859 insns = e.use_cond_insn (code, 0);
860 else
861 insns = e.use_pred_x_insn (code);
862 break;
864 default:
865 gcc_unreachable ();
868 /* Update offset as appropriate. */
869 if (e.mode_suffix_id == MODE_wb)
870 emit_insn (gen_rtx_SET (gen_rtx_MEM (Pmode, offset_ptr), new_offset));
872 return insns;
876 /* Map the vshlc function directly to CODE (UNSPEC, M) where M is the vector
877 mode associated with type suffix 0. We need this special case because the
878 intrinsics derefrence the second parameter and update its contents. */
879 class vshlc_impl : public function_base
881 public:
882 unsigned int
883 call_properties (const function_instance &) const override
885 return CP_WRITE_MEMORY | CP_READ_MEMORY;
888 tree
889 memory_scalar_type (const function_instance &) const override
891 return get_typenode_from_name (UINT32_TYPE);
895 expand (function_expander &e) const override
897 machine_mode mode = e.vector_mode (0);
898 insn_code code;
899 rtx insns, carry_ptr, carry, new_carry;
900 int carry_arg_no;
902 if (! e.type_suffix (0).integer_p)
903 gcc_unreachable ();
905 if (e.mode_suffix_id != MODE_none)
906 gcc_unreachable ();
908 carry_arg_no = 1;
910 carry = gen_reg_rtx (SImode);
911 carry_ptr = e.args[carry_arg_no];
912 emit_insn (gen_rtx_SET (carry, gen_rtx_MEM (SImode, carry_ptr)));
913 e.args[carry_arg_no] = carry;
915 new_carry = gen_reg_rtx (SImode);
916 e.args.quick_insert (0, new_carry);
918 switch (e.pred)
920 case PRED_none:
921 /* No predicate. */
922 code = e.type_suffix (0).unsigned_p
923 ? code_for_mve_vshlcq (VSHLCQ_U, mode)
924 : code_for_mve_vshlcq (VSHLCQ_S, mode);
925 insns = e.use_exact_insn (code);
926 break;
928 case PRED_m:
929 /* "m" predicate. */
930 code = e.type_suffix (0).unsigned_p
931 ? code_for_mve_vshlcq_m (VSHLCQ_M_U, mode)
932 : code_for_mve_vshlcq_m (VSHLCQ_M_S, mode);
933 insns = e.use_cond_insn (code, 0);
934 break;
936 default:
937 gcc_unreachable ();
940 /* Update carry. */
941 emit_insn (gen_rtx_SET (gen_rtx_MEM (Pmode, carry_ptr), new_carry));
943 return insns;
947 /* Map the vadc and similar functions directly to CODE (UNSPEC, UNSPEC). Take
948 care of the implicit carry argument. */
949 class vadc_vsbc_impl : public function_base
951 public:
952 CONSTEXPR vadc_vsbc_impl (bool init_carry, bool add)
953 : m_init_carry (init_carry), m_add (add)
956 /* Initialize carry with 0 (vadci). */
957 bool m_init_carry;
958 /* Add (true) or Sub (false). */
959 bool m_add;
961 unsigned int
962 call_properties (const function_instance &) const override
964 unsigned int flags = CP_WRITE_MEMORY | CP_READ_FPCR;
965 if (!m_init_carry)
966 flags |= CP_READ_MEMORY;
967 return flags;
970 tree
971 memory_scalar_type (const function_instance &) const override
973 /* carry is "unsigned int". */
974 return get_typenode_from_name ("unsigned int");
978 expand (function_expander &e) const override
980 insn_code code;
981 rtx insns, carry_ptr, carry_out;
982 int carry_out_arg_no;
983 int unspec;
985 if (! e.type_suffix (0).integer_p)
986 gcc_unreachable ();
988 if (e.mode_suffix_id != MODE_none)
989 gcc_unreachable ();
991 /* Remove carry from arguments, it is implicit for the builtin. */
992 switch (e.pred)
994 case PRED_none:
995 carry_out_arg_no = 2;
996 break;
998 case PRED_m:
999 carry_out_arg_no = 3;
1000 break;
1002 default:
1003 gcc_unreachable ();
1006 carry_ptr = e.args[carry_out_arg_no];
1007 e.args.ordered_remove (carry_out_arg_no);
1009 if (!m_init_carry)
1011 /* Prepare carry in:
1012 set_fpscr ( (fpscr & ~0x20000000u)
1013 | ((*carry & 1u) << 29) ) */
1014 rtx carry_in = gen_reg_rtx (SImode);
1015 rtx fpscr = gen_reg_rtx (SImode);
1016 emit_insn (gen_get_fpscr_nzcvqc (fpscr));
1017 emit_insn (gen_rtx_SET (carry_in, gen_rtx_MEM (SImode, carry_ptr)));
1019 emit_insn (gen_rtx_SET (carry_in,
1020 gen_rtx_ASHIFT (SImode,
1021 carry_in,
1022 GEN_INT (29))));
1023 emit_insn (gen_rtx_SET (carry_in,
1024 gen_rtx_AND (SImode,
1025 carry_in,
1026 GEN_INT (0x20000000))));
1027 emit_insn (gen_rtx_SET (fpscr,
1028 gen_rtx_AND (SImode,
1029 fpscr,
1030 GEN_INT (~0x20000000))));
1031 emit_insn (gen_rtx_SET (carry_in,
1032 gen_rtx_IOR (SImode,
1033 carry_in,
1034 fpscr)));
1035 emit_insn (gen_set_fpscr_nzcvqc (carry_in));
1038 switch (e.pred)
1040 case PRED_none:
1041 /* No predicate. */
1042 unspec = m_add
1043 ? (m_init_carry
1044 ? (e.type_suffix (0).unsigned_p
1045 ? VADCIQ_U
1046 : VADCIQ_S)
1047 : (e.type_suffix (0).unsigned_p
1048 ? VADCQ_U
1049 : VADCQ_S))
1050 : (m_init_carry
1051 ? (e.type_suffix (0).unsigned_p
1052 ? VSBCIQ_U
1053 : VSBCIQ_S)
1054 : (e.type_suffix (0).unsigned_p
1055 ? VSBCQ_U
1056 : VSBCQ_S));
1057 code = code_for_mve_q_v4si (unspec, unspec);
1058 insns = e.use_exact_insn (code);
1059 break;
1061 case PRED_m:
1062 /* "m" predicate. */
1063 unspec = m_add
1064 ? (m_init_carry
1065 ? (e.type_suffix (0).unsigned_p
1066 ? VADCIQ_M_U
1067 : VADCIQ_M_S)
1068 : (e.type_suffix (0).unsigned_p
1069 ? VADCQ_M_U
1070 : VADCQ_M_S))
1071 : (m_init_carry
1072 ? (e.type_suffix (0).unsigned_p
1073 ? VSBCIQ_M_U
1074 : VSBCIQ_M_S)
1075 : (e.type_suffix (0).unsigned_p
1076 ? VSBCQ_M_U
1077 : VSBCQ_M_S));
1078 code = code_for_mve_q_m_v4si (unspec, unspec);
1079 insns = e.use_cond_insn (code, 0);
1080 break;
1082 default:
1083 gcc_unreachable ();
1086 /* Update carry_out. */
1087 carry_out = gen_reg_rtx (SImode);
1088 emit_insn (gen_get_fpscr_nzcvqc (carry_out));
1089 emit_insn (gen_rtx_SET (carry_out,
1090 gen_rtx_LSHIFTRT (SImode,
1091 carry_out,
1092 GEN_INT (29))));
1093 emit_insn (gen_rtx_SET (carry_out,
1094 gen_rtx_AND (SImode,
1095 carry_out,
1096 GEN_INT (1))));
1097 emit_insn (gen_rtx_SET (gen_rtx_MEM (Pmode, carry_ptr), carry_out));
1099 return insns;
1104 /* Implements vst2 and vst4. */
1105 class vst24_impl : public full_width_access
1107 public:
1108 using full_width_access::full_width_access;
1110 unsigned int
1111 call_properties (const function_instance &) const override
1113 return CP_WRITE_MEMORY;
1117 expand (function_expander &e) const override
1119 insn_code icode;
1120 switch (vectors_per_tuple ())
1122 case 2:
1123 icode = code_for_mve_vst2q (e.vector_mode (0));
1124 break;
1126 case 4:
1127 icode = code_for_mve_vst4q (e.vector_mode (0));
1128 break;
1130 default:
1131 gcc_unreachable ();
1133 return e.use_contiguous_store_insn (icode);
1137 /* Implements vld2 and vld4. */
1138 class vld24_impl : public full_width_access
1140 public:
1141 using full_width_access::full_width_access;
1143 unsigned int
1144 call_properties (const function_instance &) const override
1146 return CP_READ_MEMORY;
1150 expand (function_expander &e) const override
1152 insn_code icode;
1153 switch (vectors_per_tuple ())
1155 case 2:
1156 icode = code_for_mve_vld2q (e.vector_mode (0));
1157 break;
1159 case 4:
1160 icode = code_for_mve_vld4q (e.vector_mode (0));
1161 break;
1163 default:
1164 gcc_unreachable ();
1166 return e.use_contiguous_load_insn (icode);
1170 } /* end anonymous namespace */
1172 namespace arm_mve {
1174 /* Helper for builtins with RTX codes, _m predicated and _n overrides. */
1175 #define FUNCTION_WITH_RTX_M_N(NAME, RTX, UNSPEC) FUNCTION \
1176 (NAME, unspec_based_mve_function_exact_insn, \
1177 (RTX, RTX, RTX, \
1178 UNSPEC##_N_S, UNSPEC##_N_U, UNSPEC##_N_F, \
1179 UNSPEC##_M_S, UNSPEC##_M_U, UNSPEC##_M_F, \
1180 UNSPEC##_M_N_S, UNSPEC##_M_N_U, UNSPEC##_M_N_F))
1182 /* Helper for builtins with RTX codes, and _m predicated overrides. */
1183 #define FUNCTION_WITH_RTX_M(NAME, RTX, UNSPEC) FUNCTION \
1184 (NAME, unspec_based_mve_function_exact_insn, \
1185 (RTX, RTX, RTX, \
1186 -1, -1, -1, \
1187 UNSPEC##_M_S, UNSPEC##_M_U, UNSPEC##_M_F, \
1188 -1, -1, -1))
1190 /* Helper for builtins with RTX codes, _m predicated and _n
1191 overrides, but no floating-point version. */
1192 #define FUNCTION_WITH_RTX_M_N_NO_F(NAME, RTX, UNSPEC) FUNCTION \
1193 (NAME, unspec_based_mve_function_exact_insn, \
1194 (RTX, RTX, UNKNOWN, \
1195 UNSPEC##_N_S, UNSPEC##_N_U, -1, \
1196 UNSPEC##_M_S, UNSPEC##_M_U, -1, \
1197 UNSPEC##_M_N_S, UNSPEC##_M_N_U, -1))
1199 /* Helper for builtins with RTX codes, _m predicated and _n overrides. */
1200 #define FUNCTION_WITH_RTX_M_N_NO_N_F(NAME, RTX, UNSPEC) FUNCTION \
1201 (NAME, unspec_based_mve_function_exact_insn, \
1202 (RTX, RTX, RTX, \
1203 UNSPEC##_N_S, UNSPEC##_N_U, -1, \
1204 UNSPEC##_M_S, UNSPEC##_M_U, UNSPEC##_M_F, \
1205 UNSPEC##_M_N_S, UNSPEC##_M_N_U, -1))
1207 /* Helper for builtins with RTX codes, _m predicated override, but
1208 no floating-point versions. */
1209 #define FUNCTION_WITH_RTX_M_NO_F(NAME, RTX_S, RTX_U, UNSPEC) FUNCTION \
1210 (NAME, unspec_based_mve_function_exact_insn, \
1211 (RTX_S, RTX_U, UNKNOWN, \
1212 -1, -1, -1, \
1213 UNSPEC##_M_S, UNSPEC##_M_U, -1, \
1214 -1, -1, -1))
1216 /* Helper for builtins without RTX codes, no _m predicated and no _n
1217 overrides. */
1218 #define FUNCTION_WITHOUT_M_N(NAME, UNSPEC) FUNCTION \
1219 (NAME, unspec_mve_function_exact_insn, \
1220 (UNSPEC##_S, UNSPEC##_U, UNSPEC##_F, \
1221 -1, -1, -1, \
1222 -1, -1, -1, \
1223 -1, -1, -1))
1225 /* Helper for builtins with only unspec codes, _m predicated and _n
1226 overrides, but no floating-point version. */
1227 #define FUNCTION_WITH_M_N_NO_F(NAME, UNSPEC) FUNCTION \
1228 (NAME, unspec_mve_function_exact_insn, \
1229 (UNSPEC##_S, UNSPEC##_U, -1, \
1230 UNSPEC##_N_S, UNSPEC##_N_U, -1, \
1231 UNSPEC##_M_S, UNSPEC##_M_U, -1, \
1232 UNSPEC##_M_N_S, UNSPEC##_M_N_U, -1))
1234 /* Helper for vshl builtins with only unspec codes, _m predicated
1235 and _n and _r overrides. */
1236 #define FUNCTION_WITH_M_N_R(NAME, UNSPEC) FUNCTION \
1237 (NAME, unspec_mve_function_exact_insn_vshl, \
1238 (UNSPEC##_S, UNSPEC##_U, \
1239 UNSPEC##_N_S, UNSPEC##_N_U, \
1240 UNSPEC##_M_S, UNSPEC##_M_U, \
1241 UNSPEC##_M_N_S, UNSPEC##_M_N_U, \
1242 UNSPEC##_M_R_S, UNSPEC##_M_R_U, \
1243 UNSPEC##_R_S, UNSPEC##_R_U))
1245 /* Helper for builtins with only unspec codes, _m predicated
1246 overrides, no _n and no floating-point version. */
1247 #define FUNCTION_WITHOUT_N_NO_F(NAME, UNSPEC) FUNCTION \
1248 (NAME, unspec_mve_function_exact_insn, \
1249 (UNSPEC##_S, UNSPEC##_U, -1, \
1250 -1, -1, -1, \
1251 UNSPEC##_M_S, UNSPEC##_M_U, -1, \
1252 -1, -1, -1))
1254 /* Helper for builtins with only unspec codes, _m predicated and _n
1255 overrides, but no unsigned and floating-point versions. */
1256 #define FUNCTION_WITH_M_N_NO_U_F(NAME, UNSPEC) FUNCTION \
1257 (NAME, unspec_mve_function_exact_insn, \
1258 (UNSPEC##_S, -1, -1, \
1259 UNSPEC##_N_S, -1, -1, \
1260 UNSPEC##_M_S, -1, -1, \
1261 UNSPEC##_M_N_S, -1, -1))
1263 /* Helper for builtins with only unspec codes, _m predicated
1264 overrides, but no _n version. */
1265 #define FUNCTION_WITHOUT_N(NAME, UNSPEC) FUNCTION \
1266 (NAME, unspec_mve_function_exact_insn, \
1267 (UNSPEC##_S, UNSPEC##_U, UNSPEC##_F, \
1268 -1, -1, -1, \
1269 UNSPEC##_M_S, UNSPEC##_M_U, UNSPEC##_M_F, \
1270 -1, -1, -1))
1272 /* Helper for builtins with only unspec codes, _m predicated
1273 overrides, only _n version. */
1274 #define FUNCTION_ONLY_N(NAME, UNSPEC) FUNCTION \
1275 (NAME, unspec_mve_function_exact_insn, \
1276 (-1, -1, -1, \
1277 UNSPEC##_N_S, UNSPEC##_N_U, UNSPEC##_N_F, \
1278 -1, -1, -1, \
1279 UNSPEC##_M_N_S, UNSPEC##_M_N_U, UNSPEC##_M_N_F))
1281 /* Helper for builtins with only unspec codes, _m predicated
1282 overrides, only _n version, no floating-point. */
1283 #define FUNCTION_ONLY_N_NO_F(NAME, UNSPEC) FUNCTION \
1284 (NAME, unspec_mve_function_exact_insn, \
1285 (-1, -1, -1, \
1286 UNSPEC##_N_S, UNSPEC##_N_U, -1, \
1287 -1, -1, -1, \
1288 UNSPEC##_M_N_S, UNSPEC##_M_N_U, -1))
1290 /* Helper for builtins with only unspec codes, _m predicated
1291 overrides, only _n version, no unsigned, no floating-point. */
1292 #define FUNCTION_ONLY_N_NO_U_F(NAME, UNSPEC) FUNCTION \
1293 (NAME, unspec_mve_function_exact_insn, \
1294 (-1, -1, -1, \
1295 UNSPEC##_N_S, -1, -1, \
1296 -1, -1, -1, \
1297 UNSPEC##_M_N_S, -1, -1))
1299 /* Helper for builtins with only unspec codes, _m predicated
1300 overrides, but no _n version, no unsigned and no
1301 floating-point. */
1302 #define FUNCTION_WITHOUT_N_NO_U_F(NAME, UNSPEC) FUNCTION \
1303 (NAME, unspec_mve_function_exact_insn, \
1304 (UNSPEC##_S, -1, -1, \
1305 -1, -1, -1, \
1306 UNSPEC##_M_S, -1, -1, \
1307 -1, -1, -1))
1309 /* Helper for builtins with only unspec codes, _m predicated
1310 overrides, only floating-point. */
1311 #define FUNCTION_ONLY_F(NAME, UNSPEC) FUNCTION \
1312 (NAME, unspec_mve_function_exact_insn, \
1313 (-1, -1, UNSPEC##_F, \
1314 -1, -1, -1, \
1315 -1, -1, UNSPEC##_M_F, \
1316 -1, -1, -1))
1318 /* Helper for builtins without RTX codes, _S mode, _p predicated. */
1319 #define FUNCTION_PRED_P_S(NAME, UNSPEC) FUNCTION \
1320 (NAME, unspec_mve_function_exact_insn_pred_p, \
1321 (UNSPEC##_S, -1, -1, \
1322 UNSPEC##_P_S, -1, -1))
1324 /* Helper for builtins without RTX codes, _S and _U modes, _p
1325 predicated. */
1326 #define FUNCTION_PRED_P_S_U(NAME, UNSPEC) FUNCTION \
1327 (NAME, unspec_mve_function_exact_insn_pred_p, \
1328 (UNSPEC##_S, UNSPEC##_U, -1, \
1329 UNSPEC##_P_S, UNSPEC##_P_U, -1))
1331 /* Helper for builtins without RTX codes, _F mode, _p predicated. */
1332 #define FUNCTION_PRED_P_F(NAME, UNSPEC) FUNCTION \
1333 (NAME, unspec_mve_function_exact_insn_pred_p, \
1334 (-1, -1, UNSPEC##_F, \
1335 -1, -1, UNSPEC##_P_F))
1337 FUNCTION_PRED_P_S_U (vabavq, VABAVQ)
1338 FUNCTION_WITHOUT_N (vabdq, VABDQ)
1339 FUNCTION (vabsq, unspec_based_mve_function_exact_insn, (ABS, ABS, ABS, -1, -1, -1, VABSQ_M_S, -1, VABSQ_M_F, -1, -1, -1))
1340 FUNCTION (vadciq, vadc_vsbc_impl, (true, true))
1341 FUNCTION (vadcq, vadc_vsbc_impl, (false, true))
1342 FUNCTION_WITH_RTX_M_N (vaddq, PLUS, VADDQ)
1343 FUNCTION_PRED_P_S_U (vaddlvaq, VADDLVAQ)
1344 FUNCTION_PRED_P_S_U (vaddlvq, VADDLVQ)
1345 FUNCTION_PRED_P_S_U (vaddvq, VADDVQ)
1346 FUNCTION_PRED_P_S_U (vaddvaq, VADDVAQ)
1347 FUNCTION_WITH_RTX_M (vandq, AND, VANDQ)
1348 FUNCTION (vbicq, unspec_based_mve_function_exact_insn_vbic, (VBICQ_N_S, VBICQ_N_U, VBICQ_M_S, VBICQ_M_U, VBICQ_M_F, VBICQ_M_N_S, VBICQ_M_N_U))
1349 FUNCTION_ONLY_N (vbrsrq, VBRSRQ)
1350 FUNCTION (vcaddq_rot90, unspec_mve_function_exact_insn_rot, (UNSPEC_VCADD90, UNSPEC_VCADD90, UNSPEC_VCADD90, VCADDQ_ROT90_M, VCADDQ_ROT90_M, VCADDQ_ROT90_M_F))
1351 FUNCTION (vcaddq_rot270, unspec_mve_function_exact_insn_rot, (UNSPEC_VCADD270, UNSPEC_VCADD270, UNSPEC_VCADD270, VCADDQ_ROT270_M, VCADDQ_ROT270_M, VCADDQ_ROT270_M_F))
1352 FUNCTION (vcmlaq, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMLA, -1, -1, VCMLAQ_M_F))
1353 FUNCTION (vcmlaq_rot90, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMLA90, -1, -1, VCMLAQ_ROT90_M_F))
1354 FUNCTION (vcmlaq_rot180, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMLA180, -1, -1, VCMLAQ_ROT180_M_F))
1355 FUNCTION (vcmlaq_rot270, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMLA270, -1, -1, VCMLAQ_ROT270_M_F))
1356 FUNCTION (vcmulq, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL, -1, -1, VCMULQ_M_F))
1357 FUNCTION (vcmulq_rot90, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL90, -1, -1, VCMULQ_ROT90_M_F))
1358 FUNCTION (vcmulq_rot180, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL180, -1, -1, VCMULQ_ROT180_M_F))
1359 FUNCTION (vcmulq_rot270, unspec_mve_function_exact_insn_rot, (-1, -1, UNSPEC_VCMUL270, -1, -1, VCMULQ_ROT270_M_F))
1360 FUNCTION (vhcaddq_rot90, unspec_mve_function_exact_insn_rot, (VHCADDQ_ROT90_S, -1, -1, VHCADDQ_ROT90_M_S, -1, -1))
1361 FUNCTION (vhcaddq_rot270, unspec_mve_function_exact_insn_rot, (VHCADDQ_ROT270_S, -1, -1, VHCADDQ_ROT270_M_S, -1, -1))
1362 FUNCTION_WITHOUT_N_NO_U_F (vclsq, VCLSQ)
1363 FUNCTION (vclzq, unspec_based_mve_function_exact_insn, (CLZ, CLZ, CLZ, -1, -1, -1, VCLZQ_M_S, VCLZQ_M_U, -1, -1, -1 ,-1))
1364 FUNCTION (vcmpeqq, unspec_based_mve_function_exact_insn_vcmp, (EQ, EQ, EQ, VCMPEQQ_M_S, VCMPEQQ_M_U, VCMPEQQ_M_F, VCMPEQQ_M_N_S, VCMPEQQ_M_N_U, VCMPEQQ_M_N_F))
1365 FUNCTION (vcmpneq, unspec_based_mve_function_exact_insn_vcmp, (NE, NE, NE, VCMPNEQ_M_S, VCMPNEQ_M_U, VCMPNEQ_M_F, VCMPNEQ_M_N_S, VCMPNEQ_M_N_U, VCMPNEQ_M_N_F))
1366 FUNCTION (vcmpgeq, unspec_based_mve_function_exact_insn_vcmp, (GE, UNKNOWN, GE, VCMPGEQ_M_S, UNKNOWN, VCMPGEQ_M_F, VCMPGEQ_M_N_S, UNKNOWN, VCMPGEQ_M_N_F))
1367 FUNCTION (vcmpgtq, unspec_based_mve_function_exact_insn_vcmp, (GT, UNKNOWN, GT, VCMPGTQ_M_S, UNKNOWN, VCMPGTQ_M_F, VCMPGTQ_M_N_S, UNKNOWN, VCMPGTQ_M_N_F))
1368 FUNCTION (vcmpleq, unspec_based_mve_function_exact_insn_vcmp, (LE, UNKNOWN, LE, VCMPLEQ_M_S, UNKNOWN, VCMPLEQ_M_F, VCMPLEQ_M_N_S, UNKNOWN, VCMPLEQ_M_N_F))
1369 FUNCTION (vcmpltq, unspec_based_mve_function_exact_insn_vcmp, (LT, UNKNOWN, LT, VCMPLTQ_M_S, UNKNOWN, VCMPLTQ_M_F, VCMPLTQ_M_N_S, UNKNOWN, VCMPLTQ_M_N_F))
1370 FUNCTION (vcmpcsq, unspec_based_mve_function_exact_insn_vcmp, (UNKNOWN, GEU, UNKNOWN, UNKNOWN, VCMPCSQ_M_U, UNKNOWN, UNKNOWN, VCMPCSQ_M_N_U, UNKNOWN))
1371 FUNCTION (vcmphiq, unspec_based_mve_function_exact_insn_vcmp, (UNKNOWN, GTU, UNKNOWN, UNKNOWN, VCMPHIQ_M_U, UNKNOWN, UNKNOWN, VCMPHIQ_M_N_U, UNKNOWN))
1372 FUNCTION_WITHOUT_M_N (vcreateq, VCREATEQ)
1373 FUNCTION (vctp8q, vctpq_impl, (V16BImode))
1374 FUNCTION (vctp16q, vctpq_impl, (V8BImode))
1375 FUNCTION (vctp32q, vctpq_impl, (V4BImode))
1376 FUNCTION (vctp64q, vctpq_impl, (V2QImode))
1377 FUNCTION_WITHOUT_N_NO_F (vcvtaq, VCVTAQ)
1378 FUNCTION (vcvtbq, vcvtxq_impl, (VCVTBQ_F16_F32, VCVTBQ_M_F16_F32, VCVTBQ_F32_F16, VCVTBQ_M_F32_F16))
1379 FUNCTION (vcvtq, vcvtq_impl,)
1380 FUNCTION_WITHOUT_N_NO_F (vcvtmq, VCVTMQ)
1381 FUNCTION_WITHOUT_N_NO_F (vcvtnq, VCVTNQ)
1382 FUNCTION_WITHOUT_N_NO_F (vcvtpq, VCVTPQ)
1383 FUNCTION (vcvttq, vcvtxq_impl, (VCVTTQ_F16_F32, VCVTTQ_M_F16_F32, VCVTTQ_F32_F16, VCVTTQ_M_F32_F16))
1384 FUNCTION (vddupq, viddup_impl, (false, false))
1385 FUNCTION (vdupq, vdupq_impl, (VDUPQ_M_N_S, VDUPQ_M_N_U, VDUPQ_M_N_F))
1386 FUNCTION (vdwdupq, viddup_impl, (false, true))
1387 FUNCTION (vidupq, viddup_impl, (true, false))
1388 FUNCTION (viwdupq, viddup_impl, (true, true))
1389 FUNCTION_WITH_RTX_M (veorq, XOR, VEORQ)
1390 FUNCTION (vfmaq, unspec_mve_function_exact_insn, (-1, -1, VFMAQ_F, -1, -1, VFMAQ_N_F, -1, -1, VFMAQ_M_F, -1, -1, VFMAQ_M_N_F))
1391 FUNCTION (vfmasq, unspec_mve_function_exact_insn, (-1, -1, -1, -1, -1, VFMASQ_N_F, -1, -1, -1, -1, -1, VFMASQ_M_N_F))
1392 FUNCTION (vfmsq, unspec_mve_function_exact_insn, (-1, -1, VFMSQ_F, -1, -1, -1, -1, -1, VFMSQ_M_F, -1, -1, -1))
1393 FUNCTION_WITH_M_N_NO_F (vhaddq, VHADDQ)
1394 FUNCTION_WITH_M_N_NO_F (vhsubq, VHSUBQ)
1395 FUNCTION (vld1q, vld1_impl,)
1396 FUNCTION (vld2q, vld24_impl, (2))
1397 FUNCTION (vld4q, vld24_impl, (4))
1398 FUNCTION (vldrbq, vldrq_impl, (TYPE_SUFFIX_s8, TYPE_SUFFIX_u8))
1399 FUNCTION (vldrbq_gather, vldrq_gather_impl, (false, TYPE_SUFFIX_s8, TYPE_SUFFIX_u8))
1400 FUNCTION (vldrdq_gather, vldrq_gather_impl, (false, TYPE_SUFFIX_s64, TYPE_SUFFIX_u64, NUM_TYPE_SUFFIXES))
1401 FUNCTION (vldrdq_gather_base, vldrq_gather_base_impl, (TYPE_SUFFIX_s64, TYPE_SUFFIX_u64))
1402 FUNCTION (vldrdq_gather_shifted, vldrq_gather_impl, (true, TYPE_SUFFIX_s64, TYPE_SUFFIX_u64, NUM_TYPE_SUFFIXES))
1403 FUNCTION (vldrhq, vldrq_impl, (TYPE_SUFFIX_s16, TYPE_SUFFIX_u16, TYPE_SUFFIX_f16))
1404 FUNCTION (vldrhq_gather, vldrq_gather_impl, (false, TYPE_SUFFIX_s16, TYPE_SUFFIX_u16, TYPE_SUFFIX_f16))
1405 FUNCTION (vldrhq_gather_shifted, vldrq_gather_impl, (true, TYPE_SUFFIX_s16, TYPE_SUFFIX_u16, TYPE_SUFFIX_f16))
1406 FUNCTION (vldrwq, vldrq_impl, (TYPE_SUFFIX_s32, TYPE_SUFFIX_u32, TYPE_SUFFIX_f32))
1407 FUNCTION (vldrwq_gather, vldrq_gather_impl, (false, TYPE_SUFFIX_s32, TYPE_SUFFIX_u32, TYPE_SUFFIX_f32))
1408 FUNCTION (vldrwq_gather_base, vldrq_gather_base_impl, (TYPE_SUFFIX_s32, TYPE_SUFFIX_u32, TYPE_SUFFIX_f32))
1409 FUNCTION (vldrwq_gather_shifted, vldrq_gather_impl, (true, TYPE_SUFFIX_s32, TYPE_SUFFIX_u32, TYPE_SUFFIX_f32))
1410 FUNCTION_PRED_P_S (vmaxavq, VMAXAVQ)
1411 FUNCTION_WITHOUT_N_NO_U_F (vmaxaq, VMAXAQ)
1412 FUNCTION_ONLY_F (vmaxnmaq, VMAXNMAQ)
1413 FUNCTION_PRED_P_F (vmaxnmavq, VMAXNMAVQ)
1414 FUNCTION (vmaxnmq, unspec_based_mve_function_exact_insn, (UNKNOWN, UNKNOWN, SMAX, -1, -1, -1, -1, -1, VMAXNMQ_M_F, -1, -1, -1))
1415 FUNCTION_PRED_P_F (vmaxnmvq, VMAXNMVQ)
1416 FUNCTION_WITH_RTX_M_NO_F (vmaxq, SMAX, UMAX, VMAXQ)
1417 FUNCTION_PRED_P_S_U (vmaxvq, VMAXVQ)
1418 FUNCTION_PRED_P_S (vminavq, VMINAVQ)
1419 FUNCTION_WITHOUT_N_NO_U_F (vminaq, VMINAQ)
1420 FUNCTION_ONLY_F (vminnmaq, VMINNMAQ)
1421 FUNCTION_PRED_P_F (vminnmavq, VMINNMAVQ)
1422 FUNCTION (vminnmq, unspec_based_mve_function_exact_insn, (UNKNOWN, UNKNOWN, SMIN, -1, -1, -1, -1, -1, VMINNMQ_M_F, -1, -1, -1))
1423 FUNCTION_PRED_P_F (vminnmvq, VMINNMVQ)
1424 FUNCTION_WITH_RTX_M_NO_F (vminq, SMIN, UMIN, VMINQ)
1425 FUNCTION_PRED_P_S_U (vminvq, VMINVQ)
1426 FUNCTION_PRED_P_S (vmladavaxq, VMLADAVAXQ)
1427 FUNCTION_PRED_P_S_U (vmladavaq, VMLADAVAQ)
1428 FUNCTION_PRED_P_S_U (vmladavq, VMLADAVQ)
1429 FUNCTION_PRED_P_S (vmladavxq, VMLADAVXQ)
1430 FUNCTION_PRED_P_S_U (vmlaldavaq, VMLALDAVAQ)
1431 FUNCTION_PRED_P_S (vmlaldavaxq, VMLALDAVAXQ)
1432 FUNCTION_PRED_P_S_U (vmlaldavq, VMLALDAVQ)
1433 FUNCTION_PRED_P_S (vmlaldavxq, VMLALDAVXQ)
1434 FUNCTION_ONLY_N_NO_F (vmlaq, VMLAQ)
1435 FUNCTION_ONLY_N_NO_F (vmlasq, VMLASQ)
1436 FUNCTION_PRED_P_S (vmlsdavaq, VMLSDAVAQ)
1437 FUNCTION_PRED_P_S (vmlsdavaxq, VMLSDAVAXQ)
1438 FUNCTION_PRED_P_S (vmlsdavq, VMLSDAVQ)
1439 FUNCTION_PRED_P_S (vmlsdavxq, VMLSDAVXQ)
1440 FUNCTION_PRED_P_S (vmlsldavaq, VMLSLDAVAQ)
1441 FUNCTION_PRED_P_S (vmlsldavaxq, VMLSLDAVAXQ)
1442 FUNCTION_PRED_P_S (vmlsldavq, VMLSLDAVQ)
1443 FUNCTION_PRED_P_S (vmlsldavxq, VMLSLDAVXQ)
1444 FUNCTION_WITHOUT_N_NO_F (vmovlbq, VMOVLBQ)
1445 FUNCTION_WITHOUT_N_NO_F (vmovltq, VMOVLTQ)
1446 FUNCTION_WITHOUT_N_NO_F (vmovnbq, VMOVNBQ)
1447 FUNCTION_WITHOUT_N_NO_F (vmovntq, VMOVNTQ)
1448 FUNCTION_WITHOUT_N_NO_F (vmulhq, VMULHQ)
1449 FUNCTION (vmullbq_int, unspec_mve_function_exact_insn_vmull, (VMULLBQ_INT_S, VMULLBQ_INT_U, VMULLBQ_INT_M_S, VMULLBQ_INT_M_U))
1450 FUNCTION (vmulltq_int, unspec_mve_function_exact_insn_vmull, (VMULLTQ_INT_S, VMULLTQ_INT_U, VMULLTQ_INT_M_S, VMULLTQ_INT_M_U))
1451 FUNCTION (vmullbq_poly, unspec_mve_function_exact_insn_vmull_poly, (VMULLBQ_POLY_P, VMULLBQ_POLY_M_P))
1452 FUNCTION (vmulltq_poly, unspec_mve_function_exact_insn_vmull_poly, (VMULLTQ_POLY_P, VMULLTQ_POLY_M_P))
1453 FUNCTION_WITH_RTX_M_N (vmulq, MULT, VMULQ)
1454 FUNCTION_WITH_RTX_M_N_NO_F (vmvnq, NOT, VMVNQ)
1455 FUNCTION (vnegq, unspec_based_mve_function_exact_insn, (NEG, NEG, NEG, -1, -1, -1, VNEGQ_M_S, -1, VNEGQ_M_F, -1, -1, -1))
1456 FUNCTION_WITHOUT_M_N (vpselq, VPSELQ)
1457 FUNCTION (vornq, unspec_based_mve_function_exact_insn_vorn, (-1, -1, VORNQ_M_S, VORNQ_M_U, VORNQ_M_F, -1, -1))
1458 FUNCTION_WITH_RTX_M_N_NO_N_F (vorrq, IOR, VORRQ)
1459 FUNCTION_WITHOUT_N_NO_U_F (vqabsq, VQABSQ)
1460 FUNCTION_WITH_M_N_NO_F (vqaddq, VQADDQ)
1461 FUNCTION_WITHOUT_N_NO_F (vqmovnbq, VQMOVNBQ)
1462 FUNCTION_WITHOUT_N_NO_F (vqmovntq, VQMOVNTQ)
1463 FUNCTION_WITHOUT_N_NO_U_F (vqmovunbq, VQMOVUNBQ)
1464 FUNCTION_WITHOUT_N_NO_U_F (vqmovuntq, VQMOVUNTQ)
1465 FUNCTION_WITHOUT_N_NO_U_F (vqdmladhq, VQDMLADHQ)
1466 FUNCTION_WITHOUT_N_NO_U_F (vqdmladhxq, VQDMLADHXQ)
1467 FUNCTION_ONLY_N_NO_U_F (vqdmlahq, VQDMLAHQ)
1468 FUNCTION_ONLY_N_NO_U_F (vqdmlashq, VQDMLASHQ)
1469 FUNCTION_WITHOUT_N_NO_U_F (vqdmlsdhq, VQDMLSDHQ)
1470 FUNCTION_WITHOUT_N_NO_U_F (vqdmlsdhxq, VQDMLSDHXQ)
1471 FUNCTION_WITH_M_N_NO_U_F (vqdmulhq, VQDMULHQ)
1472 FUNCTION_WITH_M_N_NO_U_F (vqdmullbq, VQDMULLBQ)
1473 FUNCTION_WITH_M_N_NO_U_F (vqdmulltq, VQDMULLTQ)
1474 FUNCTION_WITHOUT_N_NO_U_F (vqrdmladhq, VQRDMLADHQ)
1475 FUNCTION_WITHOUT_N_NO_U_F (vqrdmladhxq, VQRDMLADHXQ)
1476 FUNCTION_ONLY_N_NO_U_F (vqrdmlahq, VQRDMLAHQ)
1477 FUNCTION_ONLY_N_NO_U_F (vqrdmlashq, VQRDMLASHQ)
1478 FUNCTION_WITHOUT_N_NO_U_F (vqrdmlsdhq, VQRDMLSDHQ)
1479 FUNCTION_WITHOUT_N_NO_U_F (vqrdmlsdhxq, VQRDMLSDHXQ)
1480 FUNCTION_WITHOUT_N_NO_U_F (vqnegq, VQNEGQ)
1481 FUNCTION_WITH_M_N_NO_F (vqrshlq, VQRSHLQ)
1482 FUNCTION_WITH_M_N_NO_U_F (vqrdmulhq, VQRDMULHQ)
1483 FUNCTION_WITH_M_N_R (vqshlq, VQSHLQ)
1484 FUNCTION_ONLY_N_NO_U_F (vqshluq, VQSHLUQ)
1485 FUNCTION_ONLY_N_NO_F (vqrshrnbq, VQRSHRNBQ)
1486 FUNCTION_ONLY_N_NO_F (vqrshrntq, VQRSHRNTQ)
1487 FUNCTION_ONLY_N_NO_U_F (vqrshrunbq, VQRSHRUNBQ)
1488 FUNCTION_ONLY_N_NO_U_F (vqrshruntq, VQRSHRUNTQ)
1489 FUNCTION_ONLY_N_NO_F (vqshrnbq, VQSHRNBQ)
1490 FUNCTION_ONLY_N_NO_F (vqshrntq, VQSHRNTQ)
1491 FUNCTION_ONLY_N_NO_U_F (vqshrunbq, VQSHRUNBQ)
1492 FUNCTION_ONLY_N_NO_U_F (vqshruntq, VQSHRUNTQ)
1493 FUNCTION_WITH_M_N_NO_F (vqsubq, VQSUBQ)
1494 FUNCTION (vreinterpretq, vreinterpretq_impl,)
1495 FUNCTION_WITHOUT_N_NO_F (vrev16q, VREV16Q)
1496 FUNCTION_WITHOUT_N (vrev32q, VREV32Q)
1497 FUNCTION_WITHOUT_N (vrev64q, VREV64Q)
1498 FUNCTION_WITHOUT_N_NO_F (vrhaddq, VRHADDQ)
1499 FUNCTION_PRED_P_S_U (vrmlaldavhaq, VRMLALDAVHAQ)
1500 FUNCTION_PRED_P_S (vrmlaldavhaxq, VRMLALDAVHAXQ)
1501 FUNCTION_PRED_P_S_U (vrmlaldavhq, VRMLALDAVHQ)
1502 FUNCTION_PRED_P_S (vrmlaldavhxq, VRMLALDAVHXQ)
1503 FUNCTION_PRED_P_S (vrmlsldavhaq, VRMLSLDAVHAQ)
1504 FUNCTION_PRED_P_S (vrmlsldavhaxq, VRMLSLDAVHAXQ)
1505 FUNCTION_PRED_P_S (vrmlsldavhq, VRMLSLDAVHQ)
1506 FUNCTION_PRED_P_S (vrmlsldavhxq, VRMLSLDAVHXQ)
1507 FUNCTION_WITHOUT_N_NO_F (vrmulhq, VRMULHQ)
1508 FUNCTION_ONLY_F (vrndq, VRNDQ)
1509 FUNCTION_ONLY_F (vrndaq, VRNDAQ)
1510 FUNCTION_ONLY_F (vrndmq, VRNDMQ)
1511 FUNCTION_ONLY_F (vrndnq, VRNDNQ)
1512 FUNCTION_ONLY_F (vrndpq, VRNDPQ)
1513 FUNCTION_ONLY_F (vrndxq, VRNDXQ)
1514 FUNCTION_WITH_M_N_NO_F (vrshlq, VRSHLQ)
1515 FUNCTION_ONLY_N_NO_F (vrshrnbq, VRSHRNBQ)
1516 FUNCTION_ONLY_N_NO_F (vrshrntq, VRSHRNTQ)
1517 FUNCTION_ONLY_N_NO_F (vrshrq, VRSHRQ)
1518 FUNCTION (vsbciq, vadc_vsbc_impl, (true, false))
1519 FUNCTION (vsbcq, vadc_vsbc_impl, (false, false))
1520 FUNCTION (vshlcq, vshlc_impl,)
1521 FUNCTION_ONLY_N_NO_F (vshllbq, VSHLLBQ)
1522 FUNCTION_ONLY_N_NO_F (vshlltq, VSHLLTQ)
1523 FUNCTION_WITH_M_N_R (vshlq, VSHLQ)
1524 FUNCTION_ONLY_N_NO_F (vshrnbq, VSHRNBQ)
1525 FUNCTION_ONLY_N_NO_F (vshrntq, VSHRNTQ)
1526 FUNCTION_ONLY_N_NO_F (vshrq, VSHRQ)
1527 FUNCTION_ONLY_N_NO_F (vsliq, VSLIQ)
1528 FUNCTION_ONLY_N_NO_F (vsriq, VSRIQ)
1529 FUNCTION (vst1q, vst1_impl,)
1530 FUNCTION (vst2q, vst24_impl, (2))
1531 FUNCTION (vst4q, vst24_impl, (4))
1532 FUNCTION (vstrbq, vstrq_impl, (QImode, opt_scalar_mode ()))
1533 FUNCTION (vstrbq_scatter, vstrq_scatter_impl, (false, QImode, opt_scalar_mode ()))
1534 FUNCTION (vstrdq_scatter, vstrq_scatter_impl, (false, DImode, opt_scalar_mode ()))
1535 FUNCTION (vstrdq_scatter_base, vstrq_scatter_base_impl, (DImode))
1536 FUNCTION (vstrdq_scatter_shifted, vstrq_scatter_impl, (true, DImode, opt_scalar_mode ()))
1537 FUNCTION (vstrhq, vstrq_impl, (HImode, HFmode))
1538 FUNCTION (vstrhq_scatter, vstrq_scatter_impl, (false, HImode, HFmode))
1539 FUNCTION (vstrhq_scatter_shifted, vstrq_scatter_impl, (true, HImode, HFmode))
1540 FUNCTION (vstrwq, vstrq_impl, (SImode, SFmode))
1541 FUNCTION (vstrwq_scatter, vstrq_scatter_impl, (false, SImode, SFmode))
1542 FUNCTION (vstrwq_scatter_base, vstrq_scatter_base_impl, (SImode))
1543 FUNCTION (vstrwq_scatter_shifted, vstrq_scatter_impl, (true, SImode, SFmode))
1544 FUNCTION_WITH_RTX_M_N (vsubq, MINUS, VSUBQ)
1545 FUNCTION (vuninitializedq, vuninitializedq_impl,)
1547 } /* end namespace arm_mve */