1 /* Description of builtins used by the ARM backend.
2 Copyright (C) 2014-2015 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
8 by the Free Software Foundation; either version 3, or (at your
9 option) any later version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 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/>. */
22 #include "coretypes.h"
27 #include "fold-const.h"
28 #include "stor-layout.h"
31 #include "insn-config.h"
42 #include "langhooks.h"
43 #include "diagnostic-core.h"
45 #include "gimple-expr.h"
47 #include "arm-protos.h"
49 #define SIMD_MAX_BUILTIN_ARGS 5
51 enum arm_type_qualifiers
56 qualifier_unsigned
= 0x1, /* 1 << 0 */
58 qualifier_const
= 0x2, /* 1 << 1 */
60 qualifier_pointer
= 0x4, /* 1 << 2 */
61 /* Used when expanding arguments if an operand could
63 qualifier_immediate
= 0x8, /* 1 << 3 */
64 qualifier_maybe_immediate
= 0x10, /* 1 << 4 */
66 qualifier_void
= 0x20, /* 1 << 5 */
67 /* Some patterns may have internal operands, this qualifier is an
68 instruction to the initialisation code to skip this operand. */
69 qualifier_internal
= 0x40, /* 1 << 6 */
70 /* Some builtins should use the T_*mode* encoded in a simd_builtin_datum
71 rather than using the type of the operand. */
72 qualifier_map_mode
= 0x80, /* 1 << 7 */
73 /* qualifier_pointer | qualifier_map_mode */
74 qualifier_pointer_map_mode
= 0x84,
75 /* qualifier_const_pointer | qualifier_map_mode */
76 qualifier_const_pointer_map_mode
= 0x86,
77 /* Polynomial types. */
78 qualifier_poly
= 0x100,
79 /* Lane indices - must be within range of previous argument = a vector. */
80 qualifier_lane_index
= 0x200
83 /* The qualifier_internal allows generation of a unary builtin from
84 a pattern with a third pseudo-operand such as a match_scratch.
86 static enum arm_type_qualifiers
87 arm_unop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
88 = { qualifier_none
, qualifier_none
, qualifier_internal
};
89 #define UNOP_QUALIFIERS (arm_unop_qualifiers)
91 /* unsigned T (unsigned T). */
92 static enum arm_type_qualifiers
93 arm_bswap_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
94 = { qualifier_unsigned
, qualifier_unsigned
};
95 #define BSWAP_QUALIFIERS (arm_bswap_qualifiers)
97 /* T (T, T [maybe_immediate]). */
98 static enum arm_type_qualifiers
99 arm_binop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
100 = { qualifier_none
, qualifier_none
, qualifier_maybe_immediate
};
101 #define BINOP_QUALIFIERS (arm_binop_qualifiers)
104 static enum arm_type_qualifiers
105 arm_ternop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
106 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_none
};
107 #define TERNOP_QUALIFIERS (arm_ternop_qualifiers)
109 /* T (T, immediate). */
110 static enum arm_type_qualifiers
111 arm_binop_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
112 = { qualifier_none
, qualifier_none
, qualifier_immediate
};
113 #define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers)
115 /* T (T, lane index). */
116 static enum arm_type_qualifiers
117 arm_getlane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
118 = { qualifier_none
, qualifier_none
, qualifier_lane_index
};
119 #define GETLANE_QUALIFIERS (arm_getlane_qualifiers)
121 /* T (T, T, T, immediate). */
122 static enum arm_type_qualifiers
123 arm_mac_n_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
124 = { qualifier_none
, qualifier_none
, qualifier_none
,
125 qualifier_none
, qualifier_immediate
};
126 #define MAC_N_QUALIFIERS (arm_mac_n_qualifiers)
128 /* T (T, T, T, lane index). */
129 static enum arm_type_qualifiers
130 arm_mac_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
131 = { qualifier_none
, qualifier_none
, qualifier_none
,
132 qualifier_none
, qualifier_lane_index
};
133 #define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers)
135 /* T (T, T, immediate). */
136 static enum arm_type_qualifiers
137 arm_ternop_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
138 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_immediate
};
139 #define TERNOP_IMM_QUALIFIERS (arm_ternop_imm_qualifiers)
141 /* T (T, T, lane index). */
142 static enum arm_type_qualifiers
143 arm_setlane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
144 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_lane_index
};
145 #define SETLANE_QUALIFIERS (arm_setlane_qualifiers)
148 static enum arm_type_qualifiers
149 arm_combine_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
150 = { qualifier_none
, qualifier_none
, qualifier_none
};
151 #define COMBINE_QUALIFIERS (arm_combine_qualifiers)
153 /* T ([T element type] *). */
154 static enum arm_type_qualifiers
155 arm_load1_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
156 = { qualifier_none
, qualifier_const_pointer_map_mode
};
157 #define LOAD1_QUALIFIERS (arm_load1_qualifiers)
159 /* T ([T element type] *, T, immediate). */
160 static enum arm_type_qualifiers
161 arm_load1_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
162 = { qualifier_none
, qualifier_const_pointer_map_mode
,
163 qualifier_none
, qualifier_immediate
};
164 #define LOAD1LANE_QUALIFIERS (arm_load1_lane_qualifiers)
166 /* The first argument (return type) of a store should be void type,
167 which we represent with qualifier_void. Their first operand will be
168 a DImode pointer to the location to store to, so we must use
169 qualifier_map_mode | qualifier_pointer to build a pointer to the
170 element type of the vector.
172 void ([T element type] *, T). */
173 static enum arm_type_qualifiers
174 arm_store1_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
175 = { qualifier_void
, qualifier_pointer_map_mode
, qualifier_none
};
176 #define STORE1_QUALIFIERS (arm_store1_qualifiers)
178 /* void ([T element type] *, T, immediate). */
179 static enum arm_type_qualifiers
180 arm_storestruct_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
181 = { qualifier_void
, qualifier_pointer_map_mode
,
182 qualifier_none
, qualifier_immediate
};
183 #define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers)
185 #define v8qi_UP V8QImode
186 #define v4hi_UP V4HImode
187 #define v4hf_UP V4HFmode
188 #define v2si_UP V2SImode
189 #define v2sf_UP V2SFmode
191 #define v16qi_UP V16QImode
192 #define v8hi_UP V8HImode
193 #define v8hf_UP V8HFmode
194 #define v4si_UP V4SImode
195 #define v4sf_UP V4SFmode
196 #define v2di_UP V2DImode
206 const enum insn_code code
;
208 enum arm_type_qualifiers
*qualifiers
;
209 } neon_builtin_datum
;
211 #define CF(N,X) CODE_FOR_neon_##N##X
213 #define VAR1(T, N, A) \
214 {#N #A, UP (A), CF (N, A), 0, T##_QUALIFIERS},
215 #define VAR2(T, N, A, B) \
218 #define VAR3(T, N, A, B, C) \
221 #define VAR4(T, N, A, B, C, D) \
222 VAR3 (T, N, A, B, C) \
224 #define VAR5(T, N, A, B, C, D, E) \
225 VAR4 (T, N, A, B, C, D) \
227 #define VAR6(T, N, A, B, C, D, E, F) \
228 VAR5 (T, N, A, B, C, D, E) \
230 #define VAR7(T, N, A, B, C, D, E, F, G) \
231 VAR6 (T, N, A, B, C, D, E, F) \
233 #define VAR8(T, N, A, B, C, D, E, F, G, H) \
234 VAR7 (T, N, A, B, C, D, E, F, G) \
236 #define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
237 VAR8 (T, N, A, B, C, D, E, F, G, H) \
239 #define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
240 VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
242 #define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \
243 VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \
245 #define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
246 VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
249 /* The NEON builtin data can be found in arm_neon_builtins.def.
250 The mode entries in the following table correspond to the "key" type of the
251 instruction variant, i.e. equivalent to that which would be specified after
252 the assembler mnemonic, which usually refers to the last vector operand.
253 The modes listed per instruction should be the same as those defined for
254 that instruction's pattern in neon.md. */
256 static neon_builtin_datum neon_builtin_data
[] =
258 #include "arm_neon_builtins.def"
264 #define VAR1(T, N, X) \
265 ARM_BUILTIN_NEON_##N##X,
269 ARM_BUILTIN_GETWCGR0
,
270 ARM_BUILTIN_GETWCGR1
,
271 ARM_BUILTIN_GETWCGR2
,
272 ARM_BUILTIN_GETWCGR3
,
274 ARM_BUILTIN_SETWCGR0
,
275 ARM_BUILTIN_SETWCGR1
,
276 ARM_BUILTIN_SETWCGR2
,
277 ARM_BUILTIN_SETWCGR3
,
301 ARM_BUILTIN_WALIGNR0
,
302 ARM_BUILTIN_WALIGNR1
,
303 ARM_BUILTIN_WALIGNR2
,
304 ARM_BUILTIN_WALIGNR3
,
313 ARM_BUILTIN_TMOVMSKB
,
314 ARM_BUILTIN_TMOVMSKH
,
315 ARM_BUILTIN_TMOVMSKW
,
324 ARM_BUILTIN_WPACKHSS
,
325 ARM_BUILTIN_WPACKWSS
,
326 ARM_BUILTIN_WPACKDSS
,
327 ARM_BUILTIN_WPACKHUS
,
328 ARM_BUILTIN_WPACKWUS
,
329 ARM_BUILTIN_WPACKDUS
,
358 ARM_BUILTIN_WCMPGTUB
,
359 ARM_BUILTIN_WCMPGTUH
,
360 ARM_BUILTIN_WCMPGTUW
,
361 ARM_BUILTIN_WCMPGTSB
,
362 ARM_BUILTIN_WCMPGTSH
,
363 ARM_BUILTIN_WCMPGTSW
,
365 ARM_BUILTIN_TEXTRMSB
,
366 ARM_BUILTIN_TEXTRMSH
,
367 ARM_BUILTIN_TEXTRMSW
,
368 ARM_BUILTIN_TEXTRMUB
,
369 ARM_BUILTIN_TEXTRMUH
,
370 ARM_BUILTIN_TEXTRMUW
,
420 ARM_BUILTIN_WUNPCKIHB
,
421 ARM_BUILTIN_WUNPCKIHH
,
422 ARM_BUILTIN_WUNPCKIHW
,
423 ARM_BUILTIN_WUNPCKILB
,
424 ARM_BUILTIN_WUNPCKILH
,
425 ARM_BUILTIN_WUNPCKILW
,
427 ARM_BUILTIN_WUNPCKEHSB
,
428 ARM_BUILTIN_WUNPCKEHSH
,
429 ARM_BUILTIN_WUNPCKEHSW
,
430 ARM_BUILTIN_WUNPCKEHUB
,
431 ARM_BUILTIN_WUNPCKEHUH
,
432 ARM_BUILTIN_WUNPCKEHUW
,
433 ARM_BUILTIN_WUNPCKELSB
,
434 ARM_BUILTIN_WUNPCKELSH
,
435 ARM_BUILTIN_WUNPCKELSW
,
436 ARM_BUILTIN_WUNPCKELUB
,
437 ARM_BUILTIN_WUNPCKELUH
,
438 ARM_BUILTIN_WUNPCKELUW
,
444 ARM_BUILTIN_WADDSUBHX
,
445 ARM_BUILTIN_WSUBADDHX
,
447 ARM_BUILTIN_WABSDIFFB
,
448 ARM_BUILTIN_WABSDIFFH
,
449 ARM_BUILTIN_WABSDIFFW
,
466 ARM_BUILTIN_WMULWSMR
,
467 ARM_BUILTIN_WMULWUMR
,
478 ARM_BUILTIN_WQMULWMR
,
480 ARM_BUILTIN_WADDBHUSM
,
481 ARM_BUILTIN_WADDBHUSL
,
488 ARM_BUILTIN_WQMIABBN
,
489 ARM_BUILTIN_WQMIABTN
,
490 ARM_BUILTIN_WQMIATBN
,
491 ARM_BUILTIN_WQMIATTN
,
508 ARM_BUILTIN_WMIAWBBN
,
509 ARM_BUILTIN_WMIAWBTN
,
510 ARM_BUILTIN_WMIAWTBN
,
511 ARM_BUILTIN_WMIAWTTN
,
522 ARM_BUILTIN_GET_FPSCR
,
523 ARM_BUILTIN_SET_FPSCR
,
529 #define CRYPTO1(L, U, M1, M2) \
530 ARM_BUILTIN_CRYPTO_##U,
531 #define CRYPTO2(L, U, M1, M2, M3) \
532 ARM_BUILTIN_CRYPTO_##U,
533 #define CRYPTO3(L, U, M1, M2, M3, M4) \
534 ARM_BUILTIN_CRYPTO_##U,
536 #include "crypto.def"
542 ARM_BUILTIN_NEON_BASE
,
543 ARM_BUILTIN_NEON_LANE_CHECK
= ARM_BUILTIN_NEON_BASE
,
545 #include "arm_neon_builtins.def"
550 #define ARM_BUILTIN_NEON_PATTERN_START \
551 (ARM_BUILTIN_MAX - ARRAY_SIZE (neon_builtin_data))
565 static GTY(()) tree arm_builtin_decls
[ARM_BUILTIN_MAX
];
567 #define NUM_DREG_TYPES 5
568 #define NUM_QREG_TYPES 6
570 /* Internal scalar builtin types. These types are used to support
571 neon intrinsic builtins. They are _not_ user-visible types. Therefore
572 the mangling for these types are implementation defined. */
573 const char *arm_scalar_builtin_types
[] = {
581 "__builtin_neon_uqi",
582 "__builtin_neon_uhi",
583 "__builtin_neon_usi",
584 "__builtin_neon_udi",
592 #define ENTRY(E, M, Q, S, T, G) E,
595 #include "arm-simd-builtin-types.def"
600 struct arm_simd_type_info
602 enum arm_simd_type type
;
604 /* Internal type name. */
607 /* Internal type name(mangled). The mangled names conform to the
608 AAPCS (see "Procedure Call Standard for the ARM Architecture",
609 Appendix A). To qualify for emission with the mangled names defined in
610 that document, a vector type must not only be of the correct mode but also
611 be of the correct internal Neon vector type (e.g. __simd64_int8_t);
612 these types are registered by arm_init_simd_builtin_types (). In other
613 words, vector types defined in other ways e.g. via vector_size attribute
614 will get default mangled names. */
623 /* Machine mode the internal type maps to. */
627 enum arm_type_qualifiers q
;
630 #define ENTRY(E, M, Q, S, T, G) \
632 "__simd" #S "_" #T "_t", \
633 #G "__simd" #S "_" #T "_t", \
634 NULL_TREE, NULL_TREE, M##mode, qualifier_##Q},
635 static struct arm_simd_type_info arm_simd_types
[] = {
636 #include "arm-simd-builtin-types.def"
640 static tree arm_simd_floatHF_type_node
= NULL_TREE
;
641 static tree arm_simd_intOI_type_node
= NULL_TREE
;
642 static tree arm_simd_intEI_type_node
= NULL_TREE
;
643 static tree arm_simd_intCI_type_node
= NULL_TREE
;
644 static tree arm_simd_intXI_type_node
= NULL_TREE
;
645 static tree arm_simd_polyQI_type_node
= NULL_TREE
;
646 static tree arm_simd_polyHI_type_node
= NULL_TREE
;
647 static tree arm_simd_polyDI_type_node
= NULL_TREE
;
648 static tree arm_simd_polyTI_type_node
= NULL_TREE
;
651 arm_mangle_builtin_scalar_type (const_tree type
)
655 while (arm_scalar_builtin_types
[i
] != NULL
)
657 const char *name
= arm_scalar_builtin_types
[i
];
659 if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
660 && DECL_NAME (TYPE_NAME (type
))
661 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
))), name
))
662 return arm_scalar_builtin_types
[i
];
669 arm_mangle_builtin_vector_type (const_tree type
)
672 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
674 for (i
= 0; i
< nelts
; i
++)
675 if (arm_simd_types
[i
].mode
== TYPE_MODE (type
)
677 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
678 && DECL_NAME (TYPE_NAME (type
))
680 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
))),
681 arm_simd_types
[i
].name
))
682 return arm_simd_types
[i
].mangle
;
688 arm_mangle_builtin_type (const_tree type
)
691 /* Walk through all the AArch64 builtins types tables to filter out the
693 if ((mangle
= arm_mangle_builtin_vector_type (type
))
694 || (mangle
= arm_mangle_builtin_scalar_type (type
)))
701 arm_simd_builtin_std_type (enum machine_mode mode
,
702 enum arm_type_qualifiers q
)
704 #define QUAL_TYPE(M) \
705 ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node);
709 return QUAL_TYPE (QI
);
711 return QUAL_TYPE (HI
);
713 return QUAL_TYPE (SI
);
715 return QUAL_TYPE (DI
);
717 return QUAL_TYPE (TI
);
719 return arm_simd_intOI_type_node
;
721 return arm_simd_intEI_type_node
;
723 return arm_simd_intCI_type_node
;
725 return arm_simd_intXI_type_node
;
727 return arm_simd_floatHF_type_node
;
729 return float_type_node
;
731 return double_type_node
;
739 arm_lookup_simd_builtin_type (enum machine_mode mode
,
740 enum arm_type_qualifiers q
)
743 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
745 /* Non-poly scalar modes map to standard types not in the table. */
746 if (q
!= qualifier_poly
&& !VECTOR_MODE_P (mode
))
747 return arm_simd_builtin_std_type (mode
, q
);
749 for (i
= 0; i
< nelts
; i
++)
750 if (arm_simd_types
[i
].mode
== mode
751 && arm_simd_types
[i
].q
== q
)
752 return arm_simd_types
[i
].itype
;
754 /* Note that we won't have caught the underlying type for poly64x2_t
755 in the above table. This gets default mangling. */
761 arm_simd_builtin_type (enum machine_mode mode
,
762 bool unsigned_p
, bool poly_p
)
765 return arm_lookup_simd_builtin_type (mode
, qualifier_poly
);
767 return arm_lookup_simd_builtin_type (mode
, qualifier_unsigned
);
769 return arm_lookup_simd_builtin_type (mode
, qualifier_none
);
773 arm_init_simd_builtin_types (void)
776 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
779 /* Poly types are a world of their own. In order to maintain legacy
780 ABI, they get initialized using the old interface, and don't get
781 an entry in our mangling table, consequently, they get default
782 mangling. As a further gotcha, poly8_t and poly16_t are signed
783 types, poly64_t and poly128_t are unsigned types. */
784 arm_simd_polyQI_type_node
785 = build_distinct_type_copy (intQI_type_node
);
786 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyQI_type_node
,
787 "__builtin_neon_poly8");
788 arm_simd_polyHI_type_node
789 = build_distinct_type_copy (intHI_type_node
);
790 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyHI_type_node
,
791 "__builtin_neon_poly16");
792 arm_simd_polyDI_type_node
793 = build_distinct_type_copy (unsigned_intDI_type_node
);
794 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyDI_type_node
,
795 "__builtin_neon_poly64");
796 arm_simd_polyTI_type_node
797 = build_distinct_type_copy (unsigned_intTI_type_node
);
798 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyTI_type_node
,
799 "__builtin_neon_poly128");
801 /* Init all the element types built by the front-end. */
802 arm_simd_types
[Int8x8_t
].eltype
= intQI_type_node
;
803 arm_simd_types
[Int8x16_t
].eltype
= intQI_type_node
;
804 arm_simd_types
[Int16x4_t
].eltype
= intHI_type_node
;
805 arm_simd_types
[Int16x8_t
].eltype
= intHI_type_node
;
806 arm_simd_types
[Int32x2_t
].eltype
= intSI_type_node
;
807 arm_simd_types
[Int32x4_t
].eltype
= intSI_type_node
;
808 arm_simd_types
[Int64x2_t
].eltype
= intDI_type_node
;
809 arm_simd_types
[Uint8x8_t
].eltype
= unsigned_intQI_type_node
;
810 arm_simd_types
[Uint8x16_t
].eltype
= unsigned_intQI_type_node
;
811 arm_simd_types
[Uint16x4_t
].eltype
= unsigned_intHI_type_node
;
812 arm_simd_types
[Uint16x8_t
].eltype
= unsigned_intHI_type_node
;
813 arm_simd_types
[Uint32x2_t
].eltype
= unsigned_intSI_type_node
;
814 arm_simd_types
[Uint32x4_t
].eltype
= unsigned_intSI_type_node
;
815 arm_simd_types
[Uint64x2_t
].eltype
= unsigned_intDI_type_node
;
817 /* Init poly vector element types with scalar poly types. */
818 arm_simd_types
[Poly8x8_t
].eltype
= arm_simd_polyQI_type_node
;
819 arm_simd_types
[Poly8x16_t
].eltype
= arm_simd_polyQI_type_node
;
820 arm_simd_types
[Poly16x4_t
].eltype
= arm_simd_polyHI_type_node
;
821 arm_simd_types
[Poly16x8_t
].eltype
= arm_simd_polyHI_type_node
;
822 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
825 /* Continue with standard types. */
826 /* The __builtin_simd{64,128}_float16 types are kept private unless
827 we have a scalar __fp16 type. */
828 arm_simd_types
[Float16x4_t
].eltype
= arm_simd_floatHF_type_node
;
829 arm_simd_types
[Float16x8_t
].eltype
= arm_simd_floatHF_type_node
;
830 arm_simd_types
[Float32x2_t
].eltype
= float_type_node
;
831 arm_simd_types
[Float32x4_t
].eltype
= float_type_node
;
833 for (i
= 0; i
< nelts
; i
++)
835 tree eltype
= arm_simd_types
[i
].eltype
;
836 enum machine_mode mode
= arm_simd_types
[i
].mode
;
838 if (arm_simd_types
[i
].itype
== NULL
)
839 arm_simd_types
[i
].itype
=
840 build_distinct_type_copy
841 (build_vector_type (eltype
, GET_MODE_NUNITS (mode
)));
843 tdecl
= add_builtin_type (arm_simd_types
[i
].name
,
844 arm_simd_types
[i
].itype
);
845 TYPE_NAME (arm_simd_types
[i
].itype
) = tdecl
;
846 SET_TYPE_STRUCTURAL_EQUALITY (arm_simd_types
[i
].itype
);
849 #define AARCH_BUILD_SIGNED_TYPE(mode) \
850 make_signed_type (GET_MODE_PRECISION (mode));
851 arm_simd_intOI_type_node
= AARCH_BUILD_SIGNED_TYPE (OImode
);
852 arm_simd_intEI_type_node
= AARCH_BUILD_SIGNED_TYPE (EImode
);
853 arm_simd_intCI_type_node
= AARCH_BUILD_SIGNED_TYPE (CImode
);
854 arm_simd_intXI_type_node
= AARCH_BUILD_SIGNED_TYPE (XImode
);
855 #undef AARCH_BUILD_SIGNED_TYPE
857 tdecl
= add_builtin_type
858 ("__builtin_neon_ei" , arm_simd_intEI_type_node
);
859 TYPE_NAME (arm_simd_intEI_type_node
) = tdecl
;
860 tdecl
= add_builtin_type
861 ("__builtin_neon_oi" , arm_simd_intOI_type_node
);
862 TYPE_NAME (arm_simd_intOI_type_node
) = tdecl
;
863 tdecl
= add_builtin_type
864 ("__builtin_neon_ci" , arm_simd_intCI_type_node
);
865 TYPE_NAME (arm_simd_intCI_type_node
) = tdecl
;
866 tdecl
= add_builtin_type
867 ("__builtin_neon_xi" , arm_simd_intXI_type_node
);
868 TYPE_NAME (arm_simd_intXI_type_node
) = tdecl
;
872 arm_init_simd_builtin_scalar_types (void)
874 /* Define typedefs for all the standard scalar types. */
875 (*lang_hooks
.types
.register_builtin_type
) (intQI_type_node
,
876 "__builtin_neon_qi");
877 (*lang_hooks
.types
.register_builtin_type
) (intHI_type_node
,
878 "__builtin_neon_hi");
879 (*lang_hooks
.types
.register_builtin_type
) (intSI_type_node
,
880 "__builtin_neon_si");
881 (*lang_hooks
.types
.register_builtin_type
) (float_type_node
,
882 "__builtin_neon_sf");
883 (*lang_hooks
.types
.register_builtin_type
) (intDI_type_node
,
884 "__builtin_neon_di");
885 (*lang_hooks
.types
.register_builtin_type
) (double_type_node
,
886 "__builtin_neon_df");
887 (*lang_hooks
.types
.register_builtin_type
) (intTI_type_node
,
888 "__builtin_neon_ti");
890 /* Unsigned integer types for various mode sizes. */
891 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intQI_type_node
,
892 "__builtin_neon_uqi");
893 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intHI_type_node
,
894 "__builtin_neon_uhi");
895 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intSI_type_node
,
896 "__builtin_neon_usi");
897 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intDI_type_node
,
898 "__builtin_neon_udi");
899 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intTI_type_node
,
900 "__builtin_neon_uti");
904 arm_init_neon_builtins (void)
906 unsigned int i
, fcode
= ARM_BUILTIN_NEON_PATTERN_START
;
908 arm_init_simd_builtin_types ();
910 /* Strong-typing hasn't been implemented for all AdvSIMD builtin intrinsics.
911 Therefore we need to preserve the old __builtin scalar types. It can be
912 removed once all the intrinsics become strongly typed using the qualifier
914 arm_init_simd_builtin_scalar_types ();
916 tree lane_check_fpr
= build_function_type_list (void_type_node
,
920 arm_builtin_decls
[ARM_BUILTIN_NEON_LANE_CHECK
] =
921 add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr
,
922 ARM_BUILTIN_NEON_LANE_CHECK
, BUILT_IN_MD
,
925 for (i
= 0; i
< ARRAY_SIZE (neon_builtin_data
); i
++, fcode
++)
927 bool print_type_signature_p
= false;
928 char type_signature
[SIMD_MAX_BUILTIN_ARGS
] = { 0 };
929 neon_builtin_datum
*d
= &neon_builtin_data
[i
];
936 /* We must track two variables here. op_num is
937 the operand number as in the RTL pattern. This is
938 required to access the mode (e.g. V4SF mode) of the
939 argument, from which the base type can be derived.
940 arg_num is an index in to the qualifiers data, which
941 gives qualifiers to the type (e.g. const unsigned).
942 The reason these two variables may differ by one is the
943 void return type. While all return types take the 0th entry
944 in the qualifiers array, there is no operand for them in the
946 int op_num
= insn_data
[d
->code
].n_operands
- 1;
947 int arg_num
= d
->qualifiers
[0] & qualifier_void
950 tree return_type
= void_type_node
, args
= void_list_node
;
953 /* Build a function type directly from the insn_data for this
954 builtin. The build_function_type () function takes care of
955 removing duplicates for us. */
956 for (; op_num
>= 0; arg_num
--, op_num
--)
958 machine_mode op_mode
= insn_data
[d
->code
].operand
[op_num
].mode
;
959 enum arm_type_qualifiers qualifiers
= d
->qualifiers
[arg_num
];
961 if (qualifiers
& qualifier_unsigned
)
963 type_signature
[arg_num
] = 'u';
964 print_type_signature_p
= true;
966 else if (qualifiers
& qualifier_poly
)
968 type_signature
[arg_num
] = 'p';
969 print_type_signature_p
= true;
972 type_signature
[arg_num
] = 's';
974 /* Skip an internal operand for vget_{low, high}. */
975 if (qualifiers
& qualifier_internal
)
978 /* Some builtins have different user-facing types
979 for certain arguments, encoded in d->mode. */
980 if (qualifiers
& qualifier_map_mode
)
983 /* For pointers, we want a pointer to the basic type
985 if (qualifiers
& qualifier_pointer
&& VECTOR_MODE_P (op_mode
))
986 op_mode
= GET_MODE_INNER (op_mode
);
988 eltype
= arm_simd_builtin_type
990 (qualifiers
& qualifier_unsigned
) != 0,
991 (qualifiers
& qualifier_poly
) != 0);
992 gcc_assert (eltype
!= NULL
);
994 /* Add qualifiers. */
995 if (qualifiers
& qualifier_const
)
996 eltype
= build_qualified_type (eltype
, TYPE_QUAL_CONST
);
998 if (qualifiers
& qualifier_pointer
)
999 eltype
= build_pointer_type (eltype
);
1001 /* If we have reached arg_num == 0, we are at a non-void
1002 return type. Otherwise, we are still processing
1005 return_type
= eltype
;
1007 args
= tree_cons (NULL_TREE
, eltype
, args
);
1010 ftype
= build_function_type (return_type
, args
);
1012 gcc_assert (ftype
!= NULL
);
1014 if (print_type_signature_p
)
1015 snprintf (namebuf
, sizeof (namebuf
), "__builtin_neon_%s_%s",
1016 d
->name
, type_signature
);
1018 snprintf (namebuf
, sizeof (namebuf
), "__builtin_neon_%s",
1021 fndecl
= add_builtin_function (namebuf
, ftype
, fcode
, BUILT_IN_MD
,
1023 arm_builtin_decls
[fcode
] = fndecl
;
1026 if (TARGET_CRYPTO
&& TARGET_HARD_FLOAT
)
1028 tree V16UQI_type_node
= arm_simd_builtin_type (V16QImode
,
1032 tree V4USI_type_node
= arm_simd_builtin_type (V4SImode
,
1036 tree v16uqi_ftype_v16uqi
1037 = build_function_type_list (V16UQI_type_node
, V16UQI_type_node
,
1040 tree v16uqi_ftype_v16uqi_v16uqi
1041 = build_function_type_list (V16UQI_type_node
, V16UQI_type_node
,
1042 V16UQI_type_node
, NULL_TREE
);
1044 tree v4usi_ftype_v4usi
1045 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1048 tree v4usi_ftype_v4usi_v4usi
1049 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1050 V4USI_type_node
, NULL_TREE
);
1052 tree v4usi_ftype_v4usi_v4usi_v4usi
1053 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1054 V4USI_type_node
, V4USI_type_node
,
1057 tree uti_ftype_udi_udi
1058 = build_function_type_list (unsigned_intTI_type_node
,
1059 unsigned_intDI_type_node
,
1060 unsigned_intDI_type_node
,
1074 ARM_BUILTIN_CRYPTO_##U
1076 "__builtin_arm_crypto_"#L
1079 #define FT2(R, A1, A2) \
1080 R##_ftype_##A1##_##A2
1081 #define FT3(R, A1, A2, A3) \
1082 R##_ftype_##A1##_##A2##_##A3
1083 #define CRYPTO1(L, U, R, A) \
1084 arm_builtin_decls[C (U)] \
1085 = add_builtin_function (N (L), FT1 (R, A), \
1086 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1087 #define CRYPTO2(L, U, R, A1, A2) \
1088 arm_builtin_decls[C (U)] \
1089 = add_builtin_function (N (L), FT2 (R, A1, A2), \
1090 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1092 #define CRYPTO3(L, U, R, A1, A2, A3) \
1093 arm_builtin_decls[C (U)] \
1094 = add_builtin_function (N (L), FT3 (R, A1, A2, A3), \
1095 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1096 #include "crypto.def"
1109 #undef NUM_DREG_TYPES
1110 #undef NUM_QREG_TYPES
1112 #define def_mbuiltin(FLAGS, NAME, TYPE, CODE) \
1115 const arm_feature_set flags = FLAGS; \
1116 if (ARM_FSET_CPU_SUBSET (flags, insn_flags)) \
1119 bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
1120 BUILT_IN_MD, NULL, NULL_TREE); \
1121 arm_builtin_decls[CODE] = bdecl; \
1126 struct builtin_description
1128 const arm_feature_set features
;
1129 const enum insn_code icode
;
1130 const char * const name
;
1131 const enum arm_builtins code
;
1132 const enum rtx_code comparison
;
1133 const unsigned int flag
;
1136 static const struct builtin_description bdesc_2arg
[] =
1138 #define IWMMXT_BUILTIN(code, string, builtin) \
1139 { ARM_FSET_MAKE_CPU1 (FL_IWMMXT), CODE_FOR_##code, \
1140 "__builtin_arm_" string, \
1141 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1143 #define IWMMXT2_BUILTIN(code, string, builtin) \
1144 { ARM_FSET_MAKE_CPU1 (FL_IWMMXT2), CODE_FOR_##code, \
1145 "__builtin_arm_" string, \
1146 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1148 IWMMXT_BUILTIN (addv8qi3
, "waddb", WADDB
)
1149 IWMMXT_BUILTIN (addv4hi3
, "waddh", WADDH
)
1150 IWMMXT_BUILTIN (addv2si3
, "waddw", WADDW
)
1151 IWMMXT_BUILTIN (subv8qi3
, "wsubb", WSUBB
)
1152 IWMMXT_BUILTIN (subv4hi3
, "wsubh", WSUBH
)
1153 IWMMXT_BUILTIN (subv2si3
, "wsubw", WSUBW
)
1154 IWMMXT_BUILTIN (ssaddv8qi3
, "waddbss", WADDSSB
)
1155 IWMMXT_BUILTIN (ssaddv4hi3
, "waddhss", WADDSSH
)
1156 IWMMXT_BUILTIN (ssaddv2si3
, "waddwss", WADDSSW
)
1157 IWMMXT_BUILTIN (sssubv8qi3
, "wsubbss", WSUBSSB
)
1158 IWMMXT_BUILTIN (sssubv4hi3
, "wsubhss", WSUBSSH
)
1159 IWMMXT_BUILTIN (sssubv2si3
, "wsubwss", WSUBSSW
)
1160 IWMMXT_BUILTIN (usaddv8qi3
, "waddbus", WADDUSB
)
1161 IWMMXT_BUILTIN (usaddv4hi3
, "waddhus", WADDUSH
)
1162 IWMMXT_BUILTIN (usaddv2si3
, "waddwus", WADDUSW
)
1163 IWMMXT_BUILTIN (ussubv8qi3
, "wsubbus", WSUBUSB
)
1164 IWMMXT_BUILTIN (ussubv4hi3
, "wsubhus", WSUBUSH
)
1165 IWMMXT_BUILTIN (ussubv2si3
, "wsubwus", WSUBUSW
)
1166 IWMMXT_BUILTIN (mulv4hi3
, "wmulul", WMULUL
)
1167 IWMMXT_BUILTIN (smulv4hi3_highpart
, "wmulsm", WMULSM
)
1168 IWMMXT_BUILTIN (umulv4hi3_highpart
, "wmulum", WMULUM
)
1169 IWMMXT_BUILTIN (eqv8qi3
, "wcmpeqb", WCMPEQB
)
1170 IWMMXT_BUILTIN (eqv4hi3
, "wcmpeqh", WCMPEQH
)
1171 IWMMXT_BUILTIN (eqv2si3
, "wcmpeqw", WCMPEQW
)
1172 IWMMXT_BUILTIN (gtuv8qi3
, "wcmpgtub", WCMPGTUB
)
1173 IWMMXT_BUILTIN (gtuv4hi3
, "wcmpgtuh", WCMPGTUH
)
1174 IWMMXT_BUILTIN (gtuv2si3
, "wcmpgtuw", WCMPGTUW
)
1175 IWMMXT_BUILTIN (gtv8qi3
, "wcmpgtsb", WCMPGTSB
)
1176 IWMMXT_BUILTIN (gtv4hi3
, "wcmpgtsh", WCMPGTSH
)
1177 IWMMXT_BUILTIN (gtv2si3
, "wcmpgtsw", WCMPGTSW
)
1178 IWMMXT_BUILTIN (umaxv8qi3
, "wmaxub", WMAXUB
)
1179 IWMMXT_BUILTIN (smaxv8qi3
, "wmaxsb", WMAXSB
)
1180 IWMMXT_BUILTIN (umaxv4hi3
, "wmaxuh", WMAXUH
)
1181 IWMMXT_BUILTIN (smaxv4hi3
, "wmaxsh", WMAXSH
)
1182 IWMMXT_BUILTIN (umaxv2si3
, "wmaxuw", WMAXUW
)
1183 IWMMXT_BUILTIN (smaxv2si3
, "wmaxsw", WMAXSW
)
1184 IWMMXT_BUILTIN (uminv8qi3
, "wminub", WMINUB
)
1185 IWMMXT_BUILTIN (sminv8qi3
, "wminsb", WMINSB
)
1186 IWMMXT_BUILTIN (uminv4hi3
, "wminuh", WMINUH
)
1187 IWMMXT_BUILTIN (sminv4hi3
, "wminsh", WMINSH
)
1188 IWMMXT_BUILTIN (uminv2si3
, "wminuw", WMINUW
)
1189 IWMMXT_BUILTIN (sminv2si3
, "wminsw", WMINSW
)
1190 IWMMXT_BUILTIN (iwmmxt_anddi3
, "wand", WAND
)
1191 IWMMXT_BUILTIN (iwmmxt_nanddi3
, "wandn", WANDN
)
1192 IWMMXT_BUILTIN (iwmmxt_iordi3
, "wor", WOR
)
1193 IWMMXT_BUILTIN (iwmmxt_xordi3
, "wxor", WXOR
)
1194 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3
, "wavg2b", WAVG2B
)
1195 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3
, "wavg2h", WAVG2H
)
1196 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3
, "wavg2br", WAVG2BR
)
1197 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3
, "wavg2hr", WAVG2HR
)
1198 IWMMXT_BUILTIN (iwmmxt_wunpckilb
, "wunpckilb", WUNPCKILB
)
1199 IWMMXT_BUILTIN (iwmmxt_wunpckilh
, "wunpckilh", WUNPCKILH
)
1200 IWMMXT_BUILTIN (iwmmxt_wunpckilw
, "wunpckilw", WUNPCKILW
)
1201 IWMMXT_BUILTIN (iwmmxt_wunpckihb
, "wunpckihb", WUNPCKIHB
)
1202 IWMMXT_BUILTIN (iwmmxt_wunpckihh
, "wunpckihh", WUNPCKIHH
)
1203 IWMMXT_BUILTIN (iwmmxt_wunpckihw
, "wunpckihw", WUNPCKIHW
)
1204 IWMMXT2_BUILTIN (iwmmxt_waddsubhx
, "waddsubhx", WADDSUBHX
)
1205 IWMMXT2_BUILTIN (iwmmxt_wsubaddhx
, "wsubaddhx", WSUBADDHX
)
1206 IWMMXT2_BUILTIN (iwmmxt_wabsdiffb
, "wabsdiffb", WABSDIFFB
)
1207 IWMMXT2_BUILTIN (iwmmxt_wabsdiffh
, "wabsdiffh", WABSDIFFH
)
1208 IWMMXT2_BUILTIN (iwmmxt_wabsdiffw
, "wabsdiffw", WABSDIFFW
)
1209 IWMMXT2_BUILTIN (iwmmxt_avg4
, "wavg4", WAVG4
)
1210 IWMMXT2_BUILTIN (iwmmxt_avg4r
, "wavg4r", WAVG4R
)
1211 IWMMXT2_BUILTIN (iwmmxt_wmulwsm
, "wmulwsm", WMULWSM
)
1212 IWMMXT2_BUILTIN (iwmmxt_wmulwum
, "wmulwum", WMULWUM
)
1213 IWMMXT2_BUILTIN (iwmmxt_wmulwsmr
, "wmulwsmr", WMULWSMR
)
1214 IWMMXT2_BUILTIN (iwmmxt_wmulwumr
, "wmulwumr", WMULWUMR
)
1215 IWMMXT2_BUILTIN (iwmmxt_wmulwl
, "wmulwl", WMULWL
)
1216 IWMMXT2_BUILTIN (iwmmxt_wmulsmr
, "wmulsmr", WMULSMR
)
1217 IWMMXT2_BUILTIN (iwmmxt_wmulumr
, "wmulumr", WMULUMR
)
1218 IWMMXT2_BUILTIN (iwmmxt_wqmulm
, "wqmulm", WQMULM
)
1219 IWMMXT2_BUILTIN (iwmmxt_wqmulmr
, "wqmulmr", WQMULMR
)
1220 IWMMXT2_BUILTIN (iwmmxt_wqmulwm
, "wqmulwm", WQMULWM
)
1221 IWMMXT2_BUILTIN (iwmmxt_wqmulwmr
, "wqmulwmr", WQMULWMR
)
1222 IWMMXT_BUILTIN (iwmmxt_walignr0
, "walignr0", WALIGNR0
)
1223 IWMMXT_BUILTIN (iwmmxt_walignr1
, "walignr1", WALIGNR1
)
1224 IWMMXT_BUILTIN (iwmmxt_walignr2
, "walignr2", WALIGNR2
)
1225 IWMMXT_BUILTIN (iwmmxt_walignr3
, "walignr3", WALIGNR3
)
1227 #define IWMMXT_BUILTIN2(code, builtin) \
1228 { ARM_FSET_MAKE_CPU1 (FL_IWMMXT), CODE_FOR_##code, NULL, \
1229 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1231 #define IWMMXT2_BUILTIN2(code, builtin) \
1232 { ARM_FSET_MAKE_CPU2 (FL_IWMMXT2), CODE_FOR_##code, NULL, \
1233 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1235 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm
, WADDBHUSM
)
1236 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl
, WADDBHUSL
)
1237 IWMMXT_BUILTIN2 (iwmmxt_wpackhss
, WPACKHSS
)
1238 IWMMXT_BUILTIN2 (iwmmxt_wpackwss
, WPACKWSS
)
1239 IWMMXT_BUILTIN2 (iwmmxt_wpackdss
, WPACKDSS
)
1240 IWMMXT_BUILTIN2 (iwmmxt_wpackhus
, WPACKHUS
)
1241 IWMMXT_BUILTIN2 (iwmmxt_wpackwus
, WPACKWUS
)
1242 IWMMXT_BUILTIN2 (iwmmxt_wpackdus
, WPACKDUS
)
1243 IWMMXT_BUILTIN2 (iwmmxt_wmacuz
, WMACUZ
)
1244 IWMMXT_BUILTIN2 (iwmmxt_wmacsz
, WMACSZ
)
1247 #define FP_BUILTIN(L, U) \
1248 {ARM_FSET_EMPTY, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
1251 FP_BUILTIN (get_fpscr
, GET_FPSCR
)
1252 FP_BUILTIN (set_fpscr
, SET_FPSCR
)
1255 #define CRC32_BUILTIN(L, U) \
1256 {ARM_FSET_EMPTY, CODE_FOR_##L, "__builtin_arm_"#L, \
1257 ARM_BUILTIN_##U, UNKNOWN, 0},
1258 CRC32_BUILTIN (crc32b
, CRC32B
)
1259 CRC32_BUILTIN (crc32h
, CRC32H
)
1260 CRC32_BUILTIN (crc32w
, CRC32W
)
1261 CRC32_BUILTIN (crc32cb
, CRC32CB
)
1262 CRC32_BUILTIN (crc32ch
, CRC32CH
)
1263 CRC32_BUILTIN (crc32cw
, CRC32CW
)
1264 #undef CRC32_BUILTIN
1267 #define CRYPTO_BUILTIN(L, U) \
1268 {ARM_FSET_EMPTY, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, \
1269 ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0},
1273 #define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U)
1274 #define CRYPTO1(L, U, R, A)
1275 #define CRYPTO3(L, U, R, A1, A2, A3)
1276 #include "crypto.def"
1283 static const struct builtin_description bdesc_1arg
[] =
1285 IWMMXT_BUILTIN (iwmmxt_tmovmskb
, "tmovmskb", TMOVMSKB
)
1286 IWMMXT_BUILTIN (iwmmxt_tmovmskh
, "tmovmskh", TMOVMSKH
)
1287 IWMMXT_BUILTIN (iwmmxt_tmovmskw
, "tmovmskw", TMOVMSKW
)
1288 IWMMXT_BUILTIN (iwmmxt_waccb
, "waccb", WACCB
)
1289 IWMMXT_BUILTIN (iwmmxt_wacch
, "wacch", WACCH
)
1290 IWMMXT_BUILTIN (iwmmxt_waccw
, "waccw", WACCW
)
1291 IWMMXT_BUILTIN (iwmmxt_wunpckehub
, "wunpckehub", WUNPCKEHUB
)
1292 IWMMXT_BUILTIN (iwmmxt_wunpckehuh
, "wunpckehuh", WUNPCKEHUH
)
1293 IWMMXT_BUILTIN (iwmmxt_wunpckehuw
, "wunpckehuw", WUNPCKEHUW
)
1294 IWMMXT_BUILTIN (iwmmxt_wunpckehsb
, "wunpckehsb", WUNPCKEHSB
)
1295 IWMMXT_BUILTIN (iwmmxt_wunpckehsh
, "wunpckehsh", WUNPCKEHSH
)
1296 IWMMXT_BUILTIN (iwmmxt_wunpckehsw
, "wunpckehsw", WUNPCKEHSW
)
1297 IWMMXT_BUILTIN (iwmmxt_wunpckelub
, "wunpckelub", WUNPCKELUB
)
1298 IWMMXT_BUILTIN (iwmmxt_wunpckeluh
, "wunpckeluh", WUNPCKELUH
)
1299 IWMMXT_BUILTIN (iwmmxt_wunpckeluw
, "wunpckeluw", WUNPCKELUW
)
1300 IWMMXT_BUILTIN (iwmmxt_wunpckelsb
, "wunpckelsb", WUNPCKELSB
)
1301 IWMMXT_BUILTIN (iwmmxt_wunpckelsh
, "wunpckelsh", WUNPCKELSH
)
1302 IWMMXT_BUILTIN (iwmmxt_wunpckelsw
, "wunpckelsw", WUNPCKELSW
)
1303 IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3
, "wabsb", WABSB
)
1304 IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3
, "wabsh", WABSH
)
1305 IWMMXT2_BUILTIN (iwmmxt_wabsv2si3
, "wabsw", WABSW
)
1306 IWMMXT_BUILTIN (tbcstv8qi
, "tbcstb", TBCSTB
)
1307 IWMMXT_BUILTIN (tbcstv4hi
, "tbcsth", TBCSTH
)
1308 IWMMXT_BUILTIN (tbcstv2si
, "tbcstw", TBCSTW
)
1310 #define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U)
1311 #define CRYPTO2(L, U, R, A1, A2)
1312 #define CRYPTO3(L, U, R, A1, A2, A3)
1313 #include "crypto.def"
1319 static const struct builtin_description bdesc_3arg
[] =
1321 #define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U)
1322 #define CRYPTO1(L, U, R, A)
1323 #define CRYPTO2(L, U, R, A1, A2)
1324 #include "crypto.def"
1329 #undef CRYPTO_BUILTIN
1331 /* Set up all the iWMMXt builtins. This is not called if
1332 TARGET_IWMMXT is zero. */
1335 arm_init_iwmmxt_builtins (void)
1337 const struct builtin_description
* d
;
1340 tree V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
1341 tree V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
1342 tree V8QI_type_node
= build_vector_type_for_mode (intQI_type_node
, V8QImode
);
1344 tree v8qi_ftype_v8qi_v8qi_int
1345 = build_function_type_list (V8QI_type_node
,
1346 V8QI_type_node
, V8QI_type_node
,
1347 integer_type_node
, NULL_TREE
);
1348 tree v4hi_ftype_v4hi_int
1349 = build_function_type_list (V4HI_type_node
,
1350 V4HI_type_node
, integer_type_node
, NULL_TREE
);
1351 tree v2si_ftype_v2si_int
1352 = build_function_type_list (V2SI_type_node
,
1353 V2SI_type_node
, integer_type_node
, NULL_TREE
);
1354 tree v2si_ftype_di_di
1355 = build_function_type_list (V2SI_type_node
,
1356 long_long_integer_type_node
,
1357 long_long_integer_type_node
,
1359 tree di_ftype_di_int
1360 = build_function_type_list (long_long_integer_type_node
,
1361 long_long_integer_type_node
,
1362 integer_type_node
, NULL_TREE
);
1363 tree di_ftype_di_int_int
1364 = build_function_type_list (long_long_integer_type_node
,
1365 long_long_integer_type_node
,
1367 integer_type_node
, NULL_TREE
);
1369 = build_function_type_list (integer_type_node
,
1370 V8QI_type_node
, NULL_TREE
);
1372 = build_function_type_list (integer_type_node
,
1373 V4HI_type_node
, NULL_TREE
);
1375 = build_function_type_list (integer_type_node
,
1376 V2SI_type_node
, NULL_TREE
);
1377 tree int_ftype_v8qi_int
1378 = build_function_type_list (integer_type_node
,
1379 V8QI_type_node
, integer_type_node
, NULL_TREE
);
1380 tree int_ftype_v4hi_int
1381 = build_function_type_list (integer_type_node
,
1382 V4HI_type_node
, integer_type_node
, NULL_TREE
);
1383 tree int_ftype_v2si_int
1384 = build_function_type_list (integer_type_node
,
1385 V2SI_type_node
, integer_type_node
, NULL_TREE
);
1386 tree v8qi_ftype_v8qi_int_int
1387 = build_function_type_list (V8QI_type_node
,
1388 V8QI_type_node
, integer_type_node
,
1389 integer_type_node
, NULL_TREE
);
1390 tree v4hi_ftype_v4hi_int_int
1391 = build_function_type_list (V4HI_type_node
,
1392 V4HI_type_node
, integer_type_node
,
1393 integer_type_node
, NULL_TREE
);
1394 tree v2si_ftype_v2si_int_int
1395 = build_function_type_list (V2SI_type_node
,
1396 V2SI_type_node
, integer_type_node
,
1397 integer_type_node
, NULL_TREE
);
1398 /* Miscellaneous. */
1399 tree v8qi_ftype_v4hi_v4hi
1400 = build_function_type_list (V8QI_type_node
,
1401 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
1402 tree v4hi_ftype_v2si_v2si
1403 = build_function_type_list (V4HI_type_node
,
1404 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
1405 tree v8qi_ftype_v4hi_v8qi
1406 = build_function_type_list (V8QI_type_node
,
1407 V4HI_type_node
, V8QI_type_node
, NULL_TREE
);
1408 tree v2si_ftype_v4hi_v4hi
1409 = build_function_type_list (V2SI_type_node
,
1410 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
1411 tree v2si_ftype_v8qi_v8qi
1412 = build_function_type_list (V2SI_type_node
,
1413 V8QI_type_node
, V8QI_type_node
, NULL_TREE
);
1414 tree v4hi_ftype_v4hi_di
1415 = build_function_type_list (V4HI_type_node
,
1416 V4HI_type_node
, long_long_integer_type_node
,
1418 tree v2si_ftype_v2si_di
1419 = build_function_type_list (V2SI_type_node
,
1420 V2SI_type_node
, long_long_integer_type_node
,
1423 = build_function_type_list (long_long_unsigned_type_node
, NULL_TREE
);
1425 = build_function_type_list (integer_type_node
, NULL_TREE
);
1427 = build_function_type_list (long_long_integer_type_node
,
1428 V8QI_type_node
, NULL_TREE
);
1430 = build_function_type_list (long_long_integer_type_node
,
1431 V4HI_type_node
, NULL_TREE
);
1433 = build_function_type_list (long_long_integer_type_node
,
1434 V2SI_type_node
, NULL_TREE
);
1435 tree v2si_ftype_v4hi
1436 = build_function_type_list (V2SI_type_node
,
1437 V4HI_type_node
, NULL_TREE
);
1438 tree v4hi_ftype_v8qi
1439 = build_function_type_list (V4HI_type_node
,
1440 V8QI_type_node
, NULL_TREE
);
1441 tree v8qi_ftype_v8qi
1442 = build_function_type_list (V8QI_type_node
,
1443 V8QI_type_node
, NULL_TREE
);
1444 tree v4hi_ftype_v4hi
1445 = build_function_type_list (V4HI_type_node
,
1446 V4HI_type_node
, NULL_TREE
);
1447 tree v2si_ftype_v2si
1448 = build_function_type_list (V2SI_type_node
,
1449 V2SI_type_node
, NULL_TREE
);
1451 tree di_ftype_di_v4hi_v4hi
1452 = build_function_type_list (long_long_unsigned_type_node
,
1453 long_long_unsigned_type_node
,
1454 V4HI_type_node
, V4HI_type_node
,
1457 tree di_ftype_v4hi_v4hi
1458 = build_function_type_list (long_long_unsigned_type_node
,
1459 V4HI_type_node
,V4HI_type_node
,
1462 tree v2si_ftype_v2si_v4hi_v4hi
1463 = build_function_type_list (V2SI_type_node
,
1464 V2SI_type_node
, V4HI_type_node
,
1465 V4HI_type_node
, NULL_TREE
);
1467 tree v2si_ftype_v2si_v8qi_v8qi
1468 = build_function_type_list (V2SI_type_node
,
1469 V2SI_type_node
, V8QI_type_node
,
1470 V8QI_type_node
, NULL_TREE
);
1472 tree di_ftype_di_v2si_v2si
1473 = build_function_type_list (long_long_unsigned_type_node
,
1474 long_long_unsigned_type_node
,
1475 V2SI_type_node
, V2SI_type_node
,
1478 tree di_ftype_di_di_int
1479 = build_function_type_list (long_long_unsigned_type_node
,
1480 long_long_unsigned_type_node
,
1481 long_long_unsigned_type_node
,
1482 integer_type_node
, NULL_TREE
);
1485 = build_function_type_list (void_type_node
,
1486 integer_type_node
, NULL_TREE
);
1488 tree v8qi_ftype_char
1489 = build_function_type_list (V8QI_type_node
,
1490 signed_char_type_node
, NULL_TREE
);
1492 tree v4hi_ftype_short
1493 = build_function_type_list (V4HI_type_node
,
1494 short_integer_type_node
, NULL_TREE
);
1497 = build_function_type_list (V2SI_type_node
,
1498 integer_type_node
, NULL_TREE
);
1500 /* Normal vector binops. */
1501 tree v8qi_ftype_v8qi_v8qi
1502 = build_function_type_list (V8QI_type_node
,
1503 V8QI_type_node
, V8QI_type_node
, NULL_TREE
);
1504 tree v4hi_ftype_v4hi_v4hi
1505 = build_function_type_list (V4HI_type_node
,
1506 V4HI_type_node
,V4HI_type_node
, NULL_TREE
);
1507 tree v2si_ftype_v2si_v2si
1508 = build_function_type_list (V2SI_type_node
,
1509 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
1511 = build_function_type_list (long_long_unsigned_type_node
,
1512 long_long_unsigned_type_node
,
1513 long_long_unsigned_type_node
,
1516 /* Add all builtins that are more or less simple operations on two
1518 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
1520 /* Use one of the operands; the target can have a different mode for
1521 mask-generating compares. */
1526 !(ARM_FSET_HAS_CPU1 (d
->features
, FL_IWMMXT
) ||
1527 ARM_FSET_HAS_CPU1 (d
->features
, FL_IWMMXT2
)))
1530 mode
= insn_data
[d
->icode
].operand
[1].mode
;
1535 type
= v8qi_ftype_v8qi_v8qi
;
1538 type
= v4hi_ftype_v4hi_v4hi
;
1541 type
= v2si_ftype_v2si_v2si
;
1544 type
= di_ftype_di_di
;
1551 def_mbuiltin (d
->features
, d
->name
, type
, d
->code
);
1554 /* Add the remaining MMX insns with somewhat more complicated types. */
1555 #define iwmmx_mbuiltin(NAME, TYPE, CODE) \
1556 def_mbuiltin (ARM_FSET_MAKE_CPU1 (FL_IWMMXT), "__builtin_arm_" NAME, \
1557 (TYPE), ARM_BUILTIN_ ## CODE)
1559 #define iwmmx2_mbuiltin(NAME, TYPE, CODE) \
1560 def_mbuiltin (ARM_FSET_MAKE_CPU1 (FL_IWMMXT2), "__builtin_arm_" NAME, \
1561 (TYPE), ARM_BUILTIN_ ## CODE)
1563 iwmmx_mbuiltin ("wzero", di_ftype_void
, WZERO
);
1564 iwmmx_mbuiltin ("setwcgr0", void_ftype_int
, SETWCGR0
);
1565 iwmmx_mbuiltin ("setwcgr1", void_ftype_int
, SETWCGR1
);
1566 iwmmx_mbuiltin ("setwcgr2", void_ftype_int
, SETWCGR2
);
1567 iwmmx_mbuiltin ("setwcgr3", void_ftype_int
, SETWCGR3
);
1568 iwmmx_mbuiltin ("getwcgr0", int_ftype_void
, GETWCGR0
);
1569 iwmmx_mbuiltin ("getwcgr1", int_ftype_void
, GETWCGR1
);
1570 iwmmx_mbuiltin ("getwcgr2", int_ftype_void
, GETWCGR2
);
1571 iwmmx_mbuiltin ("getwcgr3", int_ftype_void
, GETWCGR3
);
1573 iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di
, WSLLH
);
1574 iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di
, WSLLW
);
1575 iwmmx_mbuiltin ("wslld", di_ftype_di_di
, WSLLD
);
1576 iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int
, WSLLHI
);
1577 iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int
, WSLLWI
);
1578 iwmmx_mbuiltin ("wslldi", di_ftype_di_int
, WSLLDI
);
1580 iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di
, WSRLH
);
1581 iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di
, WSRLW
);
1582 iwmmx_mbuiltin ("wsrld", di_ftype_di_di
, WSRLD
);
1583 iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int
, WSRLHI
);
1584 iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int
, WSRLWI
);
1585 iwmmx_mbuiltin ("wsrldi", di_ftype_di_int
, WSRLDI
);
1587 iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di
, WSRAH
);
1588 iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di
, WSRAW
);
1589 iwmmx_mbuiltin ("wsrad", di_ftype_di_di
, WSRAD
);
1590 iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int
, WSRAHI
);
1591 iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int
, WSRAWI
);
1592 iwmmx_mbuiltin ("wsradi", di_ftype_di_int
, WSRADI
);
1594 iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di
, WRORH
);
1595 iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di
, WRORW
);
1596 iwmmx_mbuiltin ("wrord", di_ftype_di_di
, WRORD
);
1597 iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int
, WRORHI
);
1598 iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int
, WRORWI
);
1599 iwmmx_mbuiltin ("wrordi", di_ftype_di_int
, WRORDI
);
1601 iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int
, WSHUFH
);
1603 iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi
, WSADB
);
1604 iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi
, WSADH
);
1605 iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi
, WMADDS
);
1606 iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi
, WMADDSX
);
1607 iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi
, WMADDSN
);
1608 iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi
, WMADDU
);
1609 iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi
, WMADDUX
);
1610 iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi
, WMADDUN
);
1611 iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi
, WSADBZ
);
1612 iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi
, WSADHZ
);
1614 iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int
, TEXTRMSB
);
1615 iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int
, TEXTRMSH
);
1616 iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int
, TEXTRMSW
);
1617 iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int
, TEXTRMUB
);
1618 iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int
, TEXTRMUH
);
1619 iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int
, TEXTRMUW
);
1620 iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int
, TINSRB
);
1621 iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int
, TINSRH
);
1622 iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int
, TINSRW
);
1624 iwmmx_mbuiltin ("waccb", di_ftype_v8qi
, WACCB
);
1625 iwmmx_mbuiltin ("wacch", di_ftype_v4hi
, WACCH
);
1626 iwmmx_mbuiltin ("waccw", di_ftype_v2si
, WACCW
);
1628 iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi
, TMOVMSKB
);
1629 iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi
, TMOVMSKH
);
1630 iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si
, TMOVMSKW
);
1632 iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi
, WADDBHUSM
);
1633 iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi
, WADDBHUSL
);
1635 iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi
, WPACKHSS
);
1636 iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi
, WPACKHUS
);
1637 iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si
, WPACKWUS
);
1638 iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si
, WPACKWSS
);
1639 iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di
, WPACKDUS
);
1640 iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di
, WPACKDSS
);
1642 iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi
, WUNPCKEHUB
);
1643 iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi
, WUNPCKEHUH
);
1644 iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si
, WUNPCKEHUW
);
1645 iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi
, WUNPCKEHSB
);
1646 iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi
, WUNPCKEHSH
);
1647 iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si
, WUNPCKEHSW
);
1648 iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi
, WUNPCKELUB
);
1649 iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi
, WUNPCKELUH
);
1650 iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si
, WUNPCKELUW
);
1651 iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi
, WUNPCKELSB
);
1652 iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi
, WUNPCKELSH
);
1653 iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si
, WUNPCKELSW
);
1655 iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi
, WMACS
);
1656 iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi
, WMACSZ
);
1657 iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi
, WMACU
);
1658 iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi
, WMACUZ
);
1660 iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int
, WALIGNI
);
1661 iwmmx_mbuiltin ("tmia", di_ftype_di_int_int
, TMIA
);
1662 iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int
, TMIAPH
);
1663 iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int
, TMIABB
);
1664 iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int
, TMIABT
);
1665 iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int
, TMIATB
);
1666 iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int
, TMIATT
);
1668 iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi
, WABSB
);
1669 iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi
, WABSH
);
1670 iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si
, WABSW
);
1672 iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi
, WQMIABB
);
1673 iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi
, WQMIABT
);
1674 iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi
, WQMIATB
);
1675 iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi
, WQMIATT
);
1677 iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi
, WQMIABBN
);
1678 iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi
, WQMIABTN
);
1679 iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi
, WQMIATBN
);
1680 iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi
, WQMIATTN
);
1682 iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi
, WMIABB
);
1683 iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi
, WMIABT
);
1684 iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi
, WMIATB
);
1685 iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi
, WMIATT
);
1687 iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi
, WMIABBN
);
1688 iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi
, WMIABTN
);
1689 iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi
, WMIATBN
);
1690 iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi
, WMIATTN
);
1692 iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si
, WMIAWBB
);
1693 iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si
, WMIAWBT
);
1694 iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si
, WMIAWTB
);
1695 iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si
, WMIAWTT
);
1697 iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si
, WMIAWBBN
);
1698 iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si
, WMIAWBTN
);
1699 iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si
, WMIAWTBN
);
1700 iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si
, WMIAWTTN
);
1702 iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int
, WMERGE
);
1704 iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char
, TBCSTB
);
1705 iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short
, TBCSTH
);
1706 iwmmx_mbuiltin ("tbcstw", v2si_ftype_int
, TBCSTW
);
1708 #undef iwmmx_mbuiltin
1709 #undef iwmmx2_mbuiltin
1713 arm_init_fp16_builtins (void)
1715 arm_simd_floatHF_type_node
= make_node (REAL_TYPE
);
1716 TYPE_PRECISION (arm_simd_floatHF_type_node
) = GET_MODE_PRECISION (HFmode
);
1717 layout_type (arm_simd_floatHF_type_node
);
1718 if (arm_fp16_format
)
1719 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_floatHF_type_node
,
1724 arm_init_crc32_builtins ()
1727 = build_function_type_list (unsigned_intSI_type_node
,
1728 unsigned_intSI_type_node
,
1729 unsigned_intQI_type_node
, NULL_TREE
);
1731 = build_function_type_list (unsigned_intSI_type_node
,
1732 unsigned_intSI_type_node
,
1733 unsigned_intHI_type_node
, NULL_TREE
);
1735 = build_function_type_list (unsigned_intSI_type_node
,
1736 unsigned_intSI_type_node
,
1737 unsigned_intSI_type_node
, NULL_TREE
);
1739 arm_builtin_decls
[ARM_BUILTIN_CRC32B
]
1740 = add_builtin_function ("__builtin_arm_crc32b", si_ftype_si_qi
,
1741 ARM_BUILTIN_CRC32B
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1742 arm_builtin_decls
[ARM_BUILTIN_CRC32H
]
1743 = add_builtin_function ("__builtin_arm_crc32h", si_ftype_si_hi
,
1744 ARM_BUILTIN_CRC32H
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1745 arm_builtin_decls
[ARM_BUILTIN_CRC32W
]
1746 = add_builtin_function ("__builtin_arm_crc32w", si_ftype_si_si
,
1747 ARM_BUILTIN_CRC32W
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1748 arm_builtin_decls
[ARM_BUILTIN_CRC32CB
]
1749 = add_builtin_function ("__builtin_arm_crc32cb", si_ftype_si_qi
,
1750 ARM_BUILTIN_CRC32CB
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1751 arm_builtin_decls
[ARM_BUILTIN_CRC32CH
]
1752 = add_builtin_function ("__builtin_arm_crc32ch", si_ftype_si_hi
,
1753 ARM_BUILTIN_CRC32CH
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1754 arm_builtin_decls
[ARM_BUILTIN_CRC32CW
]
1755 = add_builtin_function ("__builtin_arm_crc32cw", si_ftype_si_si
,
1756 ARM_BUILTIN_CRC32CW
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1760 arm_init_builtins (void)
1762 if (TARGET_REALLY_IWMMXT
)
1763 arm_init_iwmmxt_builtins ();
1765 /* This creates the arm_simd_floatHF_type_node so must come before
1766 arm_init_neon_builtins which uses it. */
1767 arm_init_fp16_builtins ();
1770 arm_init_neon_builtins ();
1773 arm_init_crc32_builtins ();
1775 if (TARGET_VFP
&& TARGET_HARD_FLOAT
)
1777 tree ftype_set_fpscr
1778 = build_function_type_list (void_type_node
, unsigned_type_node
, NULL
);
1779 tree ftype_get_fpscr
1780 = build_function_type_list (unsigned_type_node
, NULL
);
1782 arm_builtin_decls
[ARM_BUILTIN_GET_FPSCR
]
1783 = add_builtin_function ("__builtin_arm_ldfscr", ftype_get_fpscr
,
1784 ARM_BUILTIN_GET_FPSCR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1785 arm_builtin_decls
[ARM_BUILTIN_SET_FPSCR
]
1786 = add_builtin_function ("__builtin_arm_stfscr", ftype_set_fpscr
,
1787 ARM_BUILTIN_SET_FPSCR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1791 /* Return the ARM builtin for CODE. */
1794 arm_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
1796 if (code
>= ARM_BUILTIN_MAX
)
1797 return error_mark_node
;
1799 return arm_builtin_decls
[code
];
1802 /* Errors in the source file can cause expand_expr to return const0_rtx
1803 where we expect a vector. To avoid crashing, use one of the vector
1804 clear instructions. */
1807 safe_vector_operand (rtx x
, machine_mode mode
)
1809 if (x
!= const0_rtx
)
1811 x
= gen_reg_rtx (mode
);
1813 emit_insn (gen_iwmmxt_clrdi (mode
== DImode
? x
1814 : gen_rtx_SUBREG (DImode
, x
, 0)));
1818 /* Function to expand ternary builtins. */
1820 arm_expand_ternop_builtin (enum insn_code icode
,
1821 tree exp
, rtx target
)
1824 tree arg0
= CALL_EXPR_ARG (exp
, 0);
1825 tree arg1
= CALL_EXPR_ARG (exp
, 1);
1826 tree arg2
= CALL_EXPR_ARG (exp
, 2);
1828 rtx op0
= expand_normal (arg0
);
1829 rtx op1
= expand_normal (arg1
);
1830 rtx op2
= expand_normal (arg2
);
1833 /* The sha1c, sha1p, sha1m crypto builtins require a different vec_select
1834 lane operand depending on endianness. */
1835 bool builtin_sha1cpm_p
= false;
1837 if (insn_data
[icode
].n_operands
== 5)
1839 gcc_assert (icode
== CODE_FOR_crypto_sha1c
1840 || icode
== CODE_FOR_crypto_sha1p
1841 || icode
== CODE_FOR_crypto_sha1m
);
1842 builtin_sha1cpm_p
= true;
1844 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
1845 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1846 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
1847 machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
1850 if (VECTOR_MODE_P (mode0
))
1851 op0
= safe_vector_operand (op0
, mode0
);
1852 if (VECTOR_MODE_P (mode1
))
1853 op1
= safe_vector_operand (op1
, mode1
);
1854 if (VECTOR_MODE_P (mode2
))
1855 op2
= safe_vector_operand (op2
, mode2
);
1858 || GET_MODE (target
) != tmode
1859 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
1860 target
= gen_reg_rtx (tmode
);
1862 gcc_assert ((GET_MODE (op0
) == mode0
|| GET_MODE (op0
) == VOIDmode
)
1863 && (GET_MODE (op1
) == mode1
|| GET_MODE (op1
) == VOIDmode
)
1864 && (GET_MODE (op2
) == mode2
|| GET_MODE (op2
) == VOIDmode
));
1866 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
1867 op0
= copy_to_mode_reg (mode0
, op0
);
1868 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
1869 op1
= copy_to_mode_reg (mode1
, op1
);
1870 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
1871 op2
= copy_to_mode_reg (mode2
, op2
);
1872 if (builtin_sha1cpm_p
)
1873 op3
= GEN_INT (TARGET_BIG_END
? 1 : 0);
1875 if (builtin_sha1cpm_p
)
1876 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, op3
);
1878 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
1885 /* Subroutine of arm_expand_builtin to take care of binop insns. */
1888 arm_expand_binop_builtin (enum insn_code icode
,
1889 tree exp
, rtx target
)
1892 tree arg0
= CALL_EXPR_ARG (exp
, 0);
1893 tree arg1
= CALL_EXPR_ARG (exp
, 1);
1894 rtx op0
= expand_normal (arg0
);
1895 rtx op1
= expand_normal (arg1
);
1896 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
1897 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1898 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
1900 if (VECTOR_MODE_P (mode0
))
1901 op0
= safe_vector_operand (op0
, mode0
);
1902 if (VECTOR_MODE_P (mode1
))
1903 op1
= safe_vector_operand (op1
, mode1
);
1906 || GET_MODE (target
) != tmode
1907 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
1908 target
= gen_reg_rtx (tmode
);
1910 gcc_assert ((GET_MODE (op0
) == mode0
|| GET_MODE (op0
) == VOIDmode
)
1911 && (GET_MODE (op1
) == mode1
|| GET_MODE (op1
) == VOIDmode
));
1913 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
1914 op0
= copy_to_mode_reg (mode0
, op0
);
1915 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
1916 op1
= copy_to_mode_reg (mode1
, op1
);
1918 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
1925 /* Subroutine of arm_expand_builtin to take care of unop insns. */
1928 arm_expand_unop_builtin (enum insn_code icode
,
1929 tree exp
, rtx target
, int do_load
)
1932 tree arg0
= CALL_EXPR_ARG (exp
, 0);
1933 rtx op0
= expand_normal (arg0
);
1935 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
1936 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1937 bool builtin_sha1h_p
= false;
1939 if (insn_data
[icode
].n_operands
== 3)
1941 gcc_assert (icode
== CODE_FOR_crypto_sha1h
);
1942 builtin_sha1h_p
= true;
1946 || GET_MODE (target
) != tmode
1947 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
1948 target
= gen_reg_rtx (tmode
);
1950 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
1953 if (VECTOR_MODE_P (mode0
))
1954 op0
= safe_vector_operand (op0
, mode0
);
1956 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
1957 op0
= copy_to_mode_reg (mode0
, op0
);
1959 if (builtin_sha1h_p
)
1960 op1
= GEN_INT (TARGET_BIG_END
? 1 : 0);
1962 if (builtin_sha1h_p
)
1963 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
1965 pat
= GEN_FCN (icode
) (target
, op0
);
1973 NEON_ARG_COPY_TO_REG
,
1975 NEON_ARG_LANE_INDEX
,
1980 #define NEON_MAX_BUILTIN_ARGS 5
1982 /* EXP is a pointer argument to a Neon load or store intrinsic. Derive
1983 and return an expression for the accessed memory.
1985 The intrinsic function operates on a block of registers that has
1986 mode REG_MODE. This block contains vectors of type TYPE_MODE. The
1987 function references the memory at EXP of type TYPE and in mode
1988 MEM_MODE; this mode may be BLKmode if no more suitable mode is
1992 neon_dereference_pointer (tree exp
, tree type
, machine_mode mem_mode
,
1993 machine_mode reg_mode
,
1994 machine_mode vector_mode
)
1996 HOST_WIDE_INT reg_size
, vector_size
, nvectors
, nelems
;
1997 tree elem_type
, upper_bound
, array_type
;
1999 /* Work out the size of the register block in bytes. */
2000 reg_size
= GET_MODE_SIZE (reg_mode
);
2002 /* Work out the size of each vector in bytes. */
2003 vector_size
= GET_MODE_SIZE (vector_mode
);
2005 /* Work out how many vectors there are. */
2006 gcc_assert (reg_size
% vector_size
== 0);
2007 nvectors
= reg_size
/ vector_size
;
2009 /* Work out the type of each element. */
2010 gcc_assert (POINTER_TYPE_P (type
));
2011 elem_type
= TREE_TYPE (type
);
2013 /* Work out how many elements are being loaded or stored.
2014 MEM_MODE == REG_MODE implies a one-to-one mapping between register
2015 and memory elements; anything else implies a lane load or store. */
2016 if (mem_mode
== reg_mode
)
2017 nelems
= vector_size
* nvectors
/ int_size_in_bytes (elem_type
);
2021 /* Create a type that describes the full access. */
2022 upper_bound
= build_int_cst (size_type_node
, nelems
- 1);
2023 array_type
= build_array_type (elem_type
, build_index_type (upper_bound
));
2025 /* Dereference EXP using that type. */
2026 return fold_build2 (MEM_REF
, array_type
, exp
,
2027 build_int_cst (build_pointer_type (array_type
), 0));
2030 /* Expand a Neon builtin. */
2032 arm_expand_neon_args (rtx target
, machine_mode map_mode
, int fcode
,
2033 int icode
, int have_retval
, tree exp
, ...)
2037 tree arg
[SIMD_MAX_BUILTIN_ARGS
];
2038 rtx op
[SIMD_MAX_BUILTIN_ARGS
];
2039 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2040 machine_mode mode
[SIMD_MAX_BUILTIN_ARGS
];
2046 || GET_MODE (target
) != tmode
2047 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
)))
2048 target
= gen_reg_rtx (tmode
);
2052 formals
= TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls
[fcode
]));
2056 builtin_arg thisarg
= (builtin_arg
) va_arg (ap
, int);
2058 if (thisarg
== NEON_ARG_STOP
)
2062 int opno
= argc
+ have_retval
;
2063 arg
[argc
] = CALL_EXPR_ARG (exp
, argc
);
2064 mode
[argc
] = insn_data
[icode
].operand
[opno
].mode
;
2065 if (thisarg
== NEON_ARG_MEMORY
)
2067 machine_mode other_mode
2068 = insn_data
[icode
].operand
[1 - opno
].mode
;
2069 arg
[argc
] = neon_dereference_pointer (arg
[argc
],
2070 TREE_VALUE (formals
),
2071 mode
[argc
], other_mode
,
2075 /* Use EXPAND_MEMORY for NEON_ARG_MEMORY to ensure a MEM_P
2077 op
[argc
] = expand_expr (arg
[argc
], NULL_RTX
, VOIDmode
,
2078 (thisarg
== NEON_ARG_MEMORY
2079 ? EXPAND_MEMORY
: EXPAND_NORMAL
));
2083 case NEON_ARG_COPY_TO_REG
:
2084 if (POINTER_TYPE_P (TREE_TYPE (arg
[argc
])))
2085 op
[argc
] = convert_memory_address (Pmode
, op
[argc
]);
2086 /*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */
2087 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
2088 (op
[argc
], mode
[argc
]))
2089 op
[argc
] = copy_to_mode_reg (mode
[argc
], op
[argc
]);
2092 case NEON_ARG_LANE_INDEX
:
2093 /* Previous argument must be a vector, which this indexes. */
2094 gcc_assert (argc
> 0);
2095 if (CONST_INT_P (op
[argc
]))
2097 enum machine_mode vmode
= mode
[argc
- 1];
2098 neon_lane_bounds (op
[argc
], 0, GET_MODE_NUNITS (vmode
), exp
);
2100 /* Fall through - if the lane index isn't a constant then
2101 the next case will error. */
2102 case NEON_ARG_CONSTANT
:
2103 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
2104 (op
[argc
], mode
[argc
]))
2105 error_at (EXPR_LOCATION (exp
), "incompatible type for argument %d, "
2106 "expected %<const int%>", argc
+ 1);
2108 case NEON_ARG_MEMORY
:
2109 /* Check if expand failed. */
2110 if (op
[argc
] == const0_rtx
)
2115 gcc_assert (MEM_P (op
[argc
]));
2116 PUT_MODE (op
[argc
], mode
[argc
]);
2117 /* ??? arm_neon.h uses the same built-in functions for signed
2118 and unsigned accesses, casting where necessary. This isn't
2120 set_mem_alias_set (op
[argc
], 0);
2121 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
2122 (op
[argc
], mode
[argc
]))
2123 op
[argc
] = (replace_equiv_address
2124 (op
[argc
], force_reg (Pmode
, XEXP (op
[argc
], 0))));
2141 pat
= GEN_FCN (icode
) (target
, op
[0]);
2145 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
2149 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
2153 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
2157 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3], op
[4]);
2167 pat
= GEN_FCN (icode
) (op
[0]);
2171 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
2175 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
2179 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
2183 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3], op
[4]);
2198 /* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds.
2199 Most of these are "special" because they don't have symbolic
2200 constants defined per-instruction or per instruction-variant. Instead, the
2201 required info is looked up in the table neon_builtin_data. */
2203 arm_expand_neon_builtin (int fcode
, tree exp
, rtx target
)
2205 if (fcode
== ARM_BUILTIN_NEON_LANE_CHECK
)
2207 /* Builtin is only to check bounds of the lane passed to some intrinsics
2208 that are implemented with gcc vector extensions in arm_neon.h. */
2210 tree nlanes
= CALL_EXPR_ARG (exp
, 0);
2211 gcc_assert (TREE_CODE (nlanes
) == INTEGER_CST
);
2212 rtx lane_idx
= expand_normal (CALL_EXPR_ARG (exp
, 1));
2213 if (CONST_INT_P (lane_idx
))
2214 neon_lane_bounds (lane_idx
, 0, TREE_INT_CST_LOW (nlanes
), exp
);
2216 error ("%Klane index must be a constant immediate", exp
);
2217 /* Don't generate any RTL. */
2221 neon_builtin_datum
*d
=
2222 &neon_builtin_data
[fcode
- ARM_BUILTIN_NEON_PATTERN_START
];
2223 enum insn_code icode
= d
->code
;
2224 builtin_arg args
[SIMD_MAX_BUILTIN_ARGS
];
2225 int num_args
= insn_data
[d
->code
].n_operands
;
2229 is_void
= !!(d
->qualifiers
[0] & qualifier_void
);
2231 num_args
+= is_void
;
2233 for (k
= 1; k
< num_args
; k
++)
2235 /* We have four arrays of data, each indexed in a different fashion.
2236 qualifiers - element 0 always describes the function return type.
2237 operands - element 0 is either the operand for return value (if
2238 the function has a non-void return type) or the operand for the
2240 expr_args - element 0 always holds the first argument.
2241 args - element 0 is always used for the return type. */
2242 int qualifiers_k
= k
;
2243 int operands_k
= k
- is_void
;
2244 int expr_args_k
= k
- 1;
2246 if (d
->qualifiers
[qualifiers_k
] & qualifier_lane_index
)
2247 args
[k
] = NEON_ARG_LANE_INDEX
;
2248 else if (d
->qualifiers
[qualifiers_k
] & qualifier_immediate
)
2249 args
[k
] = NEON_ARG_CONSTANT
;
2250 else if (d
->qualifiers
[qualifiers_k
] & qualifier_maybe_immediate
)
2253 = expand_normal (CALL_EXPR_ARG (exp
,
2255 /* Handle constants only if the predicate allows it. */
2256 bool op_const_int_p
=
2258 && (*insn_data
[icode
].operand
[operands_k
].predicate
)
2259 (arg
, insn_data
[icode
].operand
[operands_k
].mode
));
2260 args
[k
] = op_const_int_p
? NEON_ARG_CONSTANT
: NEON_ARG_COPY_TO_REG
;
2262 else if (d
->qualifiers
[qualifiers_k
] & qualifier_pointer
)
2263 args
[k
] = NEON_ARG_MEMORY
;
2265 args
[k
] = NEON_ARG_COPY_TO_REG
;
2267 args
[k
] = NEON_ARG_STOP
;
2269 /* The interface to arm_expand_neon_args expects a 0 if
2270 the function is void, and a 1 if it is not. */
2271 return arm_expand_neon_args
2272 (target
, d
->mode
, fcode
, icode
, !is_void
, exp
,
2280 /* Expand an expression EXP that calls a built-in function,
2281 with result going to TARGET if that's convenient
2282 (and in mode MODE if that's convenient).
2283 SUBTARGET may be used as the target for computing one of EXP's operands.
2284 IGNORE is nonzero if the value is to be ignored. */
2287 arm_expand_builtin (tree exp
,
2289 rtx subtarget ATTRIBUTE_UNUSED
,
2290 machine_mode mode ATTRIBUTE_UNUSED
,
2291 int ignore ATTRIBUTE_UNUSED
)
2293 const struct builtin_description
* d
;
2294 enum insn_code icode
;
2295 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
2303 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
2314 if (fcode
>= ARM_BUILTIN_NEON_BASE
)
2315 return arm_expand_neon_builtin (fcode
, exp
, target
);
2319 case ARM_BUILTIN_GET_FPSCR
:
2320 case ARM_BUILTIN_SET_FPSCR
:
2321 if (fcode
== ARM_BUILTIN_GET_FPSCR
)
2323 icode
= CODE_FOR_get_fpscr
;
2324 target
= gen_reg_rtx (SImode
);
2325 pat
= GEN_FCN (icode
) (target
);
2330 icode
= CODE_FOR_set_fpscr
;
2331 arg0
= CALL_EXPR_ARG (exp
, 0);
2332 op0
= expand_normal (arg0
);
2333 pat
= GEN_FCN (icode
) (op0
);
2338 case ARM_BUILTIN_TEXTRMSB
:
2339 case ARM_BUILTIN_TEXTRMUB
:
2340 case ARM_BUILTIN_TEXTRMSH
:
2341 case ARM_BUILTIN_TEXTRMUH
:
2342 case ARM_BUILTIN_TEXTRMSW
:
2343 case ARM_BUILTIN_TEXTRMUW
:
2344 icode
= (fcode
== ARM_BUILTIN_TEXTRMSB
? CODE_FOR_iwmmxt_textrmsb
2345 : fcode
== ARM_BUILTIN_TEXTRMUB
? CODE_FOR_iwmmxt_textrmub
2346 : fcode
== ARM_BUILTIN_TEXTRMSH
? CODE_FOR_iwmmxt_textrmsh
2347 : fcode
== ARM_BUILTIN_TEXTRMUH
? CODE_FOR_iwmmxt_textrmuh
2348 : CODE_FOR_iwmmxt_textrmw
);
2350 arg0
= CALL_EXPR_ARG (exp
, 0);
2351 arg1
= CALL_EXPR_ARG (exp
, 1);
2352 op0
= expand_normal (arg0
);
2353 op1
= expand_normal (arg1
);
2354 tmode
= insn_data
[icode
].operand
[0].mode
;
2355 mode0
= insn_data
[icode
].operand
[1].mode
;
2356 mode1
= insn_data
[icode
].operand
[2].mode
;
2358 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2359 op0
= copy_to_mode_reg (mode0
, op0
);
2360 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2362 /* @@@ better error message */
2363 error ("selector must be an immediate");
2364 return gen_reg_rtx (tmode
);
2367 opint
= INTVAL (op1
);
2368 if (fcode
== ARM_BUILTIN_TEXTRMSB
|| fcode
== ARM_BUILTIN_TEXTRMUB
)
2370 if (opint
> 7 || opint
< 0)
2371 error ("the range of selector should be in 0 to 7");
2373 else if (fcode
== ARM_BUILTIN_TEXTRMSH
|| fcode
== ARM_BUILTIN_TEXTRMUH
)
2375 if (opint
> 3 || opint
< 0)
2376 error ("the range of selector should be in 0 to 3");
2378 else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */
2380 if (opint
> 1 || opint
< 0)
2381 error ("the range of selector should be in 0 to 1");
2385 || GET_MODE (target
) != tmode
2386 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2387 target
= gen_reg_rtx (tmode
);
2388 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2394 case ARM_BUILTIN_WALIGNI
:
2395 /* If op2 is immediate, call walighi, else call walighr. */
2396 arg0
= CALL_EXPR_ARG (exp
, 0);
2397 arg1
= CALL_EXPR_ARG (exp
, 1);
2398 arg2
= CALL_EXPR_ARG (exp
, 2);
2399 op0
= expand_normal (arg0
);
2400 op1
= expand_normal (arg1
);
2401 op2
= expand_normal (arg2
);
2402 if (CONST_INT_P (op2
))
2404 icode
= CODE_FOR_iwmmxt_waligni
;
2405 tmode
= insn_data
[icode
].operand
[0].mode
;
2406 mode0
= insn_data
[icode
].operand
[1].mode
;
2407 mode1
= insn_data
[icode
].operand
[2].mode
;
2408 mode2
= insn_data
[icode
].operand
[3].mode
;
2409 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2410 op0
= copy_to_mode_reg (mode0
, op0
);
2411 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2412 op1
= copy_to_mode_reg (mode1
, op1
);
2413 gcc_assert ((*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
));
2414 selector
= INTVAL (op2
);
2415 if (selector
> 7 || selector
< 0)
2416 error ("the range of selector should be in 0 to 7");
2420 icode
= CODE_FOR_iwmmxt_walignr
;
2421 tmode
= insn_data
[icode
].operand
[0].mode
;
2422 mode0
= insn_data
[icode
].operand
[1].mode
;
2423 mode1
= insn_data
[icode
].operand
[2].mode
;
2424 mode2
= insn_data
[icode
].operand
[3].mode
;
2425 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2426 op0
= copy_to_mode_reg (mode0
, op0
);
2427 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2428 op1
= copy_to_mode_reg (mode1
, op1
);
2429 if (!(*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2430 op2
= copy_to_mode_reg (mode2
, op2
);
2433 || GET_MODE (target
) != tmode
2434 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2435 target
= gen_reg_rtx (tmode
);
2436 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2442 case ARM_BUILTIN_TINSRB
:
2443 case ARM_BUILTIN_TINSRH
:
2444 case ARM_BUILTIN_TINSRW
:
2445 case ARM_BUILTIN_WMERGE
:
2446 icode
= (fcode
== ARM_BUILTIN_TINSRB
? CODE_FOR_iwmmxt_tinsrb
2447 : fcode
== ARM_BUILTIN_TINSRH
? CODE_FOR_iwmmxt_tinsrh
2448 : fcode
== ARM_BUILTIN_WMERGE
? CODE_FOR_iwmmxt_wmerge
2449 : CODE_FOR_iwmmxt_tinsrw
);
2450 arg0
= CALL_EXPR_ARG (exp
, 0);
2451 arg1
= CALL_EXPR_ARG (exp
, 1);
2452 arg2
= CALL_EXPR_ARG (exp
, 2);
2453 op0
= expand_normal (arg0
);
2454 op1
= expand_normal (arg1
);
2455 op2
= expand_normal (arg2
);
2456 tmode
= insn_data
[icode
].operand
[0].mode
;
2457 mode0
= insn_data
[icode
].operand
[1].mode
;
2458 mode1
= insn_data
[icode
].operand
[2].mode
;
2459 mode2
= insn_data
[icode
].operand
[3].mode
;
2461 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2462 op0
= copy_to_mode_reg (mode0
, op0
);
2463 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2464 op1
= copy_to_mode_reg (mode1
, op1
);
2465 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2467 error ("selector must be an immediate");
2470 if (icode
== CODE_FOR_iwmmxt_wmerge
)
2472 selector
= INTVAL (op2
);
2473 if (selector
> 7 || selector
< 0)
2474 error ("the range of selector should be in 0 to 7");
2476 if ((icode
== CODE_FOR_iwmmxt_tinsrb
)
2477 || (icode
== CODE_FOR_iwmmxt_tinsrh
)
2478 || (icode
== CODE_FOR_iwmmxt_tinsrw
))
2481 selector
= INTVAL (op2
);
2482 if (icode
== CODE_FOR_iwmmxt_tinsrb
&& (selector
< 0 || selector
> 7))
2483 error ("the range of selector should be in 0 to 7");
2484 else if (icode
== CODE_FOR_iwmmxt_tinsrh
&& (selector
< 0 ||selector
> 3))
2485 error ("the range of selector should be in 0 to 3");
2486 else if (icode
== CODE_FOR_iwmmxt_tinsrw
&& (selector
< 0 ||selector
> 1))
2487 error ("the range of selector should be in 0 to 1");
2489 op2
= GEN_INT (mask
);
2492 || GET_MODE (target
) != tmode
2493 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2494 target
= gen_reg_rtx (tmode
);
2495 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2501 case ARM_BUILTIN_SETWCGR0
:
2502 case ARM_BUILTIN_SETWCGR1
:
2503 case ARM_BUILTIN_SETWCGR2
:
2504 case ARM_BUILTIN_SETWCGR3
:
2505 icode
= (fcode
== ARM_BUILTIN_SETWCGR0
? CODE_FOR_iwmmxt_setwcgr0
2506 : fcode
== ARM_BUILTIN_SETWCGR1
? CODE_FOR_iwmmxt_setwcgr1
2507 : fcode
== ARM_BUILTIN_SETWCGR2
? CODE_FOR_iwmmxt_setwcgr2
2508 : CODE_FOR_iwmmxt_setwcgr3
);
2509 arg0
= CALL_EXPR_ARG (exp
, 0);
2510 op0
= expand_normal (arg0
);
2511 mode0
= insn_data
[icode
].operand
[0].mode
;
2512 if (!(*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
2513 op0
= copy_to_mode_reg (mode0
, op0
);
2514 pat
= GEN_FCN (icode
) (op0
);
2520 case ARM_BUILTIN_GETWCGR0
:
2521 case ARM_BUILTIN_GETWCGR1
:
2522 case ARM_BUILTIN_GETWCGR2
:
2523 case ARM_BUILTIN_GETWCGR3
:
2524 icode
= (fcode
== ARM_BUILTIN_GETWCGR0
? CODE_FOR_iwmmxt_getwcgr0
2525 : fcode
== ARM_BUILTIN_GETWCGR1
? CODE_FOR_iwmmxt_getwcgr1
2526 : fcode
== ARM_BUILTIN_GETWCGR2
? CODE_FOR_iwmmxt_getwcgr2
2527 : CODE_FOR_iwmmxt_getwcgr3
);
2528 tmode
= insn_data
[icode
].operand
[0].mode
;
2530 || GET_MODE (target
) != tmode
2531 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2532 target
= gen_reg_rtx (tmode
);
2533 pat
= GEN_FCN (icode
) (target
);
2539 case ARM_BUILTIN_WSHUFH
:
2540 icode
= CODE_FOR_iwmmxt_wshufh
;
2541 arg0
= CALL_EXPR_ARG (exp
, 0);
2542 arg1
= CALL_EXPR_ARG (exp
, 1);
2543 op0
= expand_normal (arg0
);
2544 op1
= expand_normal (arg1
);
2545 tmode
= insn_data
[icode
].operand
[0].mode
;
2546 mode1
= insn_data
[icode
].operand
[1].mode
;
2547 mode2
= insn_data
[icode
].operand
[2].mode
;
2549 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode1
))
2550 op0
= copy_to_mode_reg (mode1
, op0
);
2551 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode2
))
2553 error ("mask must be an immediate");
2556 selector
= INTVAL (op1
);
2557 if (selector
< 0 || selector
> 255)
2558 error ("the range of mask should be in 0 to 255");
2560 || GET_MODE (target
) != tmode
2561 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2562 target
= gen_reg_rtx (tmode
);
2563 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2569 case ARM_BUILTIN_WMADDS
:
2570 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds
, exp
, target
);
2571 case ARM_BUILTIN_WMADDSX
:
2572 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx
, exp
, target
);
2573 case ARM_BUILTIN_WMADDSN
:
2574 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn
, exp
, target
);
2575 case ARM_BUILTIN_WMADDU
:
2576 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu
, exp
, target
);
2577 case ARM_BUILTIN_WMADDUX
:
2578 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux
, exp
, target
);
2579 case ARM_BUILTIN_WMADDUN
:
2580 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun
, exp
, target
);
2581 case ARM_BUILTIN_WSADBZ
:
2582 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz
, exp
, target
);
2583 case ARM_BUILTIN_WSADHZ
:
2584 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz
, exp
, target
);
2586 /* Several three-argument builtins. */
2587 case ARM_BUILTIN_WMACS
:
2588 case ARM_BUILTIN_WMACU
:
2589 case ARM_BUILTIN_TMIA
:
2590 case ARM_BUILTIN_TMIAPH
:
2591 case ARM_BUILTIN_TMIATT
:
2592 case ARM_BUILTIN_TMIATB
:
2593 case ARM_BUILTIN_TMIABT
:
2594 case ARM_BUILTIN_TMIABB
:
2595 case ARM_BUILTIN_WQMIABB
:
2596 case ARM_BUILTIN_WQMIABT
:
2597 case ARM_BUILTIN_WQMIATB
:
2598 case ARM_BUILTIN_WQMIATT
:
2599 case ARM_BUILTIN_WQMIABBN
:
2600 case ARM_BUILTIN_WQMIABTN
:
2601 case ARM_BUILTIN_WQMIATBN
:
2602 case ARM_BUILTIN_WQMIATTN
:
2603 case ARM_BUILTIN_WMIABB
:
2604 case ARM_BUILTIN_WMIABT
:
2605 case ARM_BUILTIN_WMIATB
:
2606 case ARM_BUILTIN_WMIATT
:
2607 case ARM_BUILTIN_WMIABBN
:
2608 case ARM_BUILTIN_WMIABTN
:
2609 case ARM_BUILTIN_WMIATBN
:
2610 case ARM_BUILTIN_WMIATTN
:
2611 case ARM_BUILTIN_WMIAWBB
:
2612 case ARM_BUILTIN_WMIAWBT
:
2613 case ARM_BUILTIN_WMIAWTB
:
2614 case ARM_BUILTIN_WMIAWTT
:
2615 case ARM_BUILTIN_WMIAWBBN
:
2616 case ARM_BUILTIN_WMIAWBTN
:
2617 case ARM_BUILTIN_WMIAWTBN
:
2618 case ARM_BUILTIN_WMIAWTTN
:
2619 case ARM_BUILTIN_WSADB
:
2620 case ARM_BUILTIN_WSADH
:
2621 icode
= (fcode
== ARM_BUILTIN_WMACS
? CODE_FOR_iwmmxt_wmacs
2622 : fcode
== ARM_BUILTIN_WMACU
? CODE_FOR_iwmmxt_wmacu
2623 : fcode
== ARM_BUILTIN_TMIA
? CODE_FOR_iwmmxt_tmia
2624 : fcode
== ARM_BUILTIN_TMIAPH
? CODE_FOR_iwmmxt_tmiaph
2625 : fcode
== ARM_BUILTIN_TMIABB
? CODE_FOR_iwmmxt_tmiabb
2626 : fcode
== ARM_BUILTIN_TMIABT
? CODE_FOR_iwmmxt_tmiabt
2627 : fcode
== ARM_BUILTIN_TMIATB
? CODE_FOR_iwmmxt_tmiatb
2628 : fcode
== ARM_BUILTIN_TMIATT
? CODE_FOR_iwmmxt_tmiatt
2629 : fcode
== ARM_BUILTIN_WQMIABB
? CODE_FOR_iwmmxt_wqmiabb
2630 : fcode
== ARM_BUILTIN_WQMIABT
? CODE_FOR_iwmmxt_wqmiabt
2631 : fcode
== ARM_BUILTIN_WQMIATB
? CODE_FOR_iwmmxt_wqmiatb
2632 : fcode
== ARM_BUILTIN_WQMIATT
? CODE_FOR_iwmmxt_wqmiatt
2633 : fcode
== ARM_BUILTIN_WQMIABBN
? CODE_FOR_iwmmxt_wqmiabbn
2634 : fcode
== ARM_BUILTIN_WQMIABTN
? CODE_FOR_iwmmxt_wqmiabtn
2635 : fcode
== ARM_BUILTIN_WQMIATBN
? CODE_FOR_iwmmxt_wqmiatbn
2636 : fcode
== ARM_BUILTIN_WQMIATTN
? CODE_FOR_iwmmxt_wqmiattn
2637 : fcode
== ARM_BUILTIN_WMIABB
? CODE_FOR_iwmmxt_wmiabb
2638 : fcode
== ARM_BUILTIN_WMIABT
? CODE_FOR_iwmmxt_wmiabt
2639 : fcode
== ARM_BUILTIN_WMIATB
? CODE_FOR_iwmmxt_wmiatb
2640 : fcode
== ARM_BUILTIN_WMIATT
? CODE_FOR_iwmmxt_wmiatt
2641 : fcode
== ARM_BUILTIN_WMIABBN
? CODE_FOR_iwmmxt_wmiabbn
2642 : fcode
== ARM_BUILTIN_WMIABTN
? CODE_FOR_iwmmxt_wmiabtn
2643 : fcode
== ARM_BUILTIN_WMIATBN
? CODE_FOR_iwmmxt_wmiatbn
2644 : fcode
== ARM_BUILTIN_WMIATTN
? CODE_FOR_iwmmxt_wmiattn
2645 : fcode
== ARM_BUILTIN_WMIAWBB
? CODE_FOR_iwmmxt_wmiawbb
2646 : fcode
== ARM_BUILTIN_WMIAWBT
? CODE_FOR_iwmmxt_wmiawbt
2647 : fcode
== ARM_BUILTIN_WMIAWTB
? CODE_FOR_iwmmxt_wmiawtb
2648 : fcode
== ARM_BUILTIN_WMIAWTT
? CODE_FOR_iwmmxt_wmiawtt
2649 : fcode
== ARM_BUILTIN_WMIAWBBN
? CODE_FOR_iwmmxt_wmiawbbn
2650 : fcode
== ARM_BUILTIN_WMIAWBTN
? CODE_FOR_iwmmxt_wmiawbtn
2651 : fcode
== ARM_BUILTIN_WMIAWTBN
? CODE_FOR_iwmmxt_wmiawtbn
2652 : fcode
== ARM_BUILTIN_WMIAWTTN
? CODE_FOR_iwmmxt_wmiawttn
2653 : fcode
== ARM_BUILTIN_WSADB
? CODE_FOR_iwmmxt_wsadb
2654 : CODE_FOR_iwmmxt_wsadh
);
2655 arg0
= CALL_EXPR_ARG (exp
, 0);
2656 arg1
= CALL_EXPR_ARG (exp
, 1);
2657 arg2
= CALL_EXPR_ARG (exp
, 2);
2658 op0
= expand_normal (arg0
);
2659 op1
= expand_normal (arg1
);
2660 op2
= expand_normal (arg2
);
2661 tmode
= insn_data
[icode
].operand
[0].mode
;
2662 mode0
= insn_data
[icode
].operand
[1].mode
;
2663 mode1
= insn_data
[icode
].operand
[2].mode
;
2664 mode2
= insn_data
[icode
].operand
[3].mode
;
2666 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2667 op0
= copy_to_mode_reg (mode0
, op0
);
2668 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2669 op1
= copy_to_mode_reg (mode1
, op1
);
2670 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2671 op2
= copy_to_mode_reg (mode2
, op2
);
2673 || GET_MODE (target
) != tmode
2674 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2675 target
= gen_reg_rtx (tmode
);
2676 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2682 case ARM_BUILTIN_WZERO
:
2683 target
= gen_reg_rtx (DImode
);
2684 emit_insn (gen_iwmmxt_clrdi (target
));
2687 case ARM_BUILTIN_WSRLHI
:
2688 case ARM_BUILTIN_WSRLWI
:
2689 case ARM_BUILTIN_WSRLDI
:
2690 case ARM_BUILTIN_WSLLHI
:
2691 case ARM_BUILTIN_WSLLWI
:
2692 case ARM_BUILTIN_WSLLDI
:
2693 case ARM_BUILTIN_WSRAHI
:
2694 case ARM_BUILTIN_WSRAWI
:
2695 case ARM_BUILTIN_WSRADI
:
2696 case ARM_BUILTIN_WRORHI
:
2697 case ARM_BUILTIN_WRORWI
:
2698 case ARM_BUILTIN_WRORDI
:
2699 case ARM_BUILTIN_WSRLH
:
2700 case ARM_BUILTIN_WSRLW
:
2701 case ARM_BUILTIN_WSRLD
:
2702 case ARM_BUILTIN_WSLLH
:
2703 case ARM_BUILTIN_WSLLW
:
2704 case ARM_BUILTIN_WSLLD
:
2705 case ARM_BUILTIN_WSRAH
:
2706 case ARM_BUILTIN_WSRAW
:
2707 case ARM_BUILTIN_WSRAD
:
2708 case ARM_BUILTIN_WRORH
:
2709 case ARM_BUILTIN_WRORW
:
2710 case ARM_BUILTIN_WRORD
:
2711 icode
= (fcode
== ARM_BUILTIN_WSRLHI
? CODE_FOR_lshrv4hi3_iwmmxt
2712 : fcode
== ARM_BUILTIN_WSRLWI
? CODE_FOR_lshrv2si3_iwmmxt
2713 : fcode
== ARM_BUILTIN_WSRLDI
? CODE_FOR_lshrdi3_iwmmxt
2714 : fcode
== ARM_BUILTIN_WSLLHI
? CODE_FOR_ashlv4hi3_iwmmxt
2715 : fcode
== ARM_BUILTIN_WSLLWI
? CODE_FOR_ashlv2si3_iwmmxt
2716 : fcode
== ARM_BUILTIN_WSLLDI
? CODE_FOR_ashldi3_iwmmxt
2717 : fcode
== ARM_BUILTIN_WSRAHI
? CODE_FOR_ashrv4hi3_iwmmxt
2718 : fcode
== ARM_BUILTIN_WSRAWI
? CODE_FOR_ashrv2si3_iwmmxt
2719 : fcode
== ARM_BUILTIN_WSRADI
? CODE_FOR_ashrdi3_iwmmxt
2720 : fcode
== ARM_BUILTIN_WRORHI
? CODE_FOR_rorv4hi3
2721 : fcode
== ARM_BUILTIN_WRORWI
? CODE_FOR_rorv2si3
2722 : fcode
== ARM_BUILTIN_WRORDI
? CODE_FOR_rordi3
2723 : fcode
== ARM_BUILTIN_WSRLH
? CODE_FOR_lshrv4hi3_di
2724 : fcode
== ARM_BUILTIN_WSRLW
? CODE_FOR_lshrv2si3_di
2725 : fcode
== ARM_BUILTIN_WSRLD
? CODE_FOR_lshrdi3_di
2726 : fcode
== ARM_BUILTIN_WSLLH
? CODE_FOR_ashlv4hi3_di
2727 : fcode
== ARM_BUILTIN_WSLLW
? CODE_FOR_ashlv2si3_di
2728 : fcode
== ARM_BUILTIN_WSLLD
? CODE_FOR_ashldi3_di
2729 : fcode
== ARM_BUILTIN_WSRAH
? CODE_FOR_ashrv4hi3_di
2730 : fcode
== ARM_BUILTIN_WSRAW
? CODE_FOR_ashrv2si3_di
2731 : fcode
== ARM_BUILTIN_WSRAD
? CODE_FOR_ashrdi3_di
2732 : fcode
== ARM_BUILTIN_WRORH
? CODE_FOR_rorv4hi3_di
2733 : fcode
== ARM_BUILTIN_WRORW
? CODE_FOR_rorv2si3_di
2734 : fcode
== ARM_BUILTIN_WRORD
? CODE_FOR_rordi3_di
2735 : CODE_FOR_nothing
);
2736 arg1
= CALL_EXPR_ARG (exp
, 1);
2737 op1
= expand_normal (arg1
);
2738 if (GET_MODE (op1
) == VOIDmode
)
2741 if ((fcode
== ARM_BUILTIN_WRORHI
|| fcode
== ARM_BUILTIN_WRORWI
2742 || fcode
== ARM_BUILTIN_WRORH
|| fcode
== ARM_BUILTIN_WRORW
)
2743 && (imm
< 0 || imm
> 32))
2745 if (fcode
== ARM_BUILTIN_WRORHI
)
2746 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi16 in code.");
2747 else if (fcode
== ARM_BUILTIN_WRORWI
)
2748 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi32 in code.");
2749 else if (fcode
== ARM_BUILTIN_WRORH
)
2750 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi16 in code.");
2752 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi32 in code.");
2754 else if ((fcode
== ARM_BUILTIN_WRORDI
|| fcode
== ARM_BUILTIN_WRORD
)
2755 && (imm
< 0 || imm
> 64))
2757 if (fcode
== ARM_BUILTIN_WRORDI
)
2758 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_rori_si64 in code.");
2760 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_ror_si64 in code.");
2764 if (fcode
== ARM_BUILTIN_WSRLHI
)
2765 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi16 in code.");
2766 else if (fcode
== ARM_BUILTIN_WSRLWI
)
2767 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi32 in code.");
2768 else if (fcode
== ARM_BUILTIN_WSRLDI
)
2769 error ("the count should be no less than 0. please check the intrinsic _mm_srli_si64 in code.");
2770 else if (fcode
== ARM_BUILTIN_WSLLHI
)
2771 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi16 in code.");
2772 else if (fcode
== ARM_BUILTIN_WSLLWI
)
2773 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi32 in code.");
2774 else if (fcode
== ARM_BUILTIN_WSLLDI
)
2775 error ("the count should be no less than 0. please check the intrinsic _mm_slli_si64 in code.");
2776 else if (fcode
== ARM_BUILTIN_WSRAHI
)
2777 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi16 in code.");
2778 else if (fcode
== ARM_BUILTIN_WSRAWI
)
2779 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi32 in code.");
2780 else if (fcode
== ARM_BUILTIN_WSRADI
)
2781 error ("the count should be no less than 0. please check the intrinsic _mm_srai_si64 in code.");
2782 else if (fcode
== ARM_BUILTIN_WSRLH
)
2783 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi16 in code.");
2784 else if (fcode
== ARM_BUILTIN_WSRLW
)
2785 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi32 in code.");
2786 else if (fcode
== ARM_BUILTIN_WSRLD
)
2787 error ("the count should be no less than 0. please check the intrinsic _mm_srl_si64 in code.");
2788 else if (fcode
== ARM_BUILTIN_WSLLH
)
2789 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi16 in code.");
2790 else if (fcode
== ARM_BUILTIN_WSLLW
)
2791 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi32 in code.");
2792 else if (fcode
== ARM_BUILTIN_WSLLD
)
2793 error ("the count should be no less than 0. please check the intrinsic _mm_sll_si64 in code.");
2794 else if (fcode
== ARM_BUILTIN_WSRAH
)
2795 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi16 in code.");
2796 else if (fcode
== ARM_BUILTIN_WSRAW
)
2797 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi32 in code.");
2799 error ("the count should be no less than 0. please check the intrinsic _mm_sra_si64 in code.");
2802 return arm_expand_binop_builtin (icode
, exp
, target
);
2808 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
2809 if (d
->code
== (const enum arm_builtins
) fcode
)
2810 return arm_expand_binop_builtin (d
->icode
, exp
, target
);
2812 for (i
= 0, d
= bdesc_1arg
; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
2813 if (d
->code
== (const enum arm_builtins
) fcode
)
2814 return arm_expand_unop_builtin (d
->icode
, exp
, target
, 0);
2816 for (i
= 0, d
= bdesc_3arg
; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
2817 if (d
->code
== (const enum arm_builtins
) fcode
)
2818 return arm_expand_ternop_builtin (d
->icode
, exp
, target
);
2820 /* @@@ Should really do something sensible here. */
2825 arm_builtin_vectorized_function (tree fndecl
, tree type_out
, tree type_in
)
2827 machine_mode in_mode
, out_mode
;
2829 bool out_unsigned_p
= TYPE_UNSIGNED (type_out
);
2831 if (TREE_CODE (type_out
) != VECTOR_TYPE
2832 || TREE_CODE (type_in
) != VECTOR_TYPE
)
2835 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
2836 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
2837 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
2838 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
2840 /* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the
2841 decl of the vectorized builtin for the appropriate vector mode.
2842 NULL_TREE is returned if no such builtin is available. */
2843 #undef ARM_CHECK_BUILTIN_MODE
2844 #define ARM_CHECK_BUILTIN_MODE(C) \
2845 (TARGET_NEON && TARGET_FPU_ARMV8 \
2846 && flag_unsafe_math_optimizations \
2847 && ARM_CHECK_BUILTIN_MODE_1 (C))
2849 #undef ARM_CHECK_BUILTIN_MODE_1
2850 #define ARM_CHECK_BUILTIN_MODE_1(C) \
2851 (out_mode == SFmode && out_n == C \
2852 && in_mode == SFmode && in_n == C)
2854 #undef ARM_FIND_VRINT_VARIANT
2855 #define ARM_FIND_VRINT_VARIANT(N) \
2856 (ARM_CHECK_BUILTIN_MODE (2) \
2857 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \
2858 : (ARM_CHECK_BUILTIN_MODE (4) \
2859 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \
2862 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
2864 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
2867 case BUILT_IN_FLOORF
:
2868 return ARM_FIND_VRINT_VARIANT (vrintm
);
2869 case BUILT_IN_CEILF
:
2870 return ARM_FIND_VRINT_VARIANT (vrintp
);
2871 case BUILT_IN_TRUNCF
:
2872 return ARM_FIND_VRINT_VARIANT (vrintz
);
2873 case BUILT_IN_ROUNDF
:
2874 return ARM_FIND_VRINT_VARIANT (vrinta
);
2875 #undef ARM_CHECK_BUILTIN_MODE_1
2876 #define ARM_CHECK_BUILTIN_MODE_1(C) \
2877 (out_mode == SImode && out_n == C \
2878 && in_mode == SFmode && in_n == C)
2880 #define ARM_FIND_VCVT_VARIANT(N) \
2881 (ARM_CHECK_BUILTIN_MODE (2) \
2882 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sfv2si, false) \
2883 : (ARM_CHECK_BUILTIN_MODE (4) \
2884 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sfv4si, false) \
2887 #define ARM_FIND_VCVTU_VARIANT(N) \
2888 (ARM_CHECK_BUILTIN_MODE (2) \
2889 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv2sfv2si, false) \
2890 : (ARM_CHECK_BUILTIN_MODE (4) \
2891 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \
2893 case BUILT_IN_LROUNDF
:
2894 return out_unsigned_p
2895 ? ARM_FIND_VCVTU_VARIANT (vcvta
)
2896 : ARM_FIND_VCVT_VARIANT (vcvta
);
2897 case BUILT_IN_LCEILF
:
2898 return out_unsigned_p
2899 ? ARM_FIND_VCVTU_VARIANT (vcvtp
)
2900 : ARM_FIND_VCVT_VARIANT (vcvtp
);
2901 case BUILT_IN_LFLOORF
:
2902 return out_unsigned_p
2903 ? ARM_FIND_VCVTU_VARIANT (vcvtm
)
2904 : ARM_FIND_VCVT_VARIANT (vcvtm
);
2905 #undef ARM_CHECK_BUILTIN_MODE
2906 #define ARM_CHECK_BUILTIN_MODE(C, N) \
2907 (out_mode == N##mode && out_n == C \
2908 && in_mode == N##mode && in_n == C)
2909 case BUILT_IN_BSWAP16
:
2910 if (ARM_CHECK_BUILTIN_MODE (4, HI
))
2911 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi
, false);
2912 else if (ARM_CHECK_BUILTIN_MODE (8, HI
))
2913 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi
, false);
2916 case BUILT_IN_BSWAP32
:
2917 if (ARM_CHECK_BUILTIN_MODE (2, SI
))
2918 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si
, false);
2919 else if (ARM_CHECK_BUILTIN_MODE (4, SI
))
2920 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si
, false);
2923 case BUILT_IN_BSWAP64
:
2924 if (ARM_CHECK_BUILTIN_MODE (2, DI
))
2925 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di
, false);
2928 case BUILT_IN_COPYSIGNF
:
2929 if (ARM_CHECK_BUILTIN_MODE (2, SF
))
2930 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf
, false);
2931 else if (ARM_CHECK_BUILTIN_MODE (4, SF
))
2932 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf
, false);
2942 #undef ARM_FIND_VCVT_VARIANT
2943 #undef ARM_FIND_VCVTU_VARIANT
2944 #undef ARM_CHECK_BUILTIN_MODE
2945 #undef ARM_FIND_VRINT_VARIANT
2948 arm_atomic_assign_expand_fenv (tree
*hold
, tree
*clear
, tree
*update
)
2950 const unsigned ARM_FE_INVALID
= 1;
2951 const unsigned ARM_FE_DIVBYZERO
= 2;
2952 const unsigned ARM_FE_OVERFLOW
= 4;
2953 const unsigned ARM_FE_UNDERFLOW
= 8;
2954 const unsigned ARM_FE_INEXACT
= 16;
2955 const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT
= (ARM_FE_INVALID
2960 const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT
= 8;
2961 tree fenv_var
, get_fpscr
, set_fpscr
, mask
, ld_fenv
, masked_fenv
;
2962 tree new_fenv_var
, reload_fenv
, restore_fnenv
;
2963 tree update_call
, atomic_feraiseexcept
, hold_fnclex
;
2965 if (!TARGET_VFP
|| !TARGET_HARD_FLOAT
)
2968 /* Generate the equivalent of :
2969 unsigned int fenv_var;
2970 fenv_var = __builtin_arm_get_fpscr ();
2972 unsigned int masked_fenv;
2973 masked_fenv = fenv_var & mask;
2975 __builtin_arm_set_fpscr (masked_fenv); */
2977 fenv_var
= create_tmp_var_raw (unsigned_type_node
);
2978 get_fpscr
= arm_builtin_decls
[ARM_BUILTIN_GET_FPSCR
];
2979 set_fpscr
= arm_builtin_decls
[ARM_BUILTIN_SET_FPSCR
];
2980 mask
= build_int_cst (unsigned_type_node
,
2981 ~((ARM_FE_ALL_EXCEPT
<< ARM_FE_EXCEPT_SHIFT
)
2982 | ARM_FE_ALL_EXCEPT
));
2983 ld_fenv
= build2 (MODIFY_EXPR
, unsigned_type_node
,
2984 fenv_var
, build_call_expr (get_fpscr
, 0));
2985 masked_fenv
= build2 (BIT_AND_EXPR
, unsigned_type_node
, fenv_var
, mask
);
2986 hold_fnclex
= build_call_expr (set_fpscr
, 1, masked_fenv
);
2987 *hold
= build2 (COMPOUND_EXPR
, void_type_node
,
2988 build2 (COMPOUND_EXPR
, void_type_node
, masked_fenv
, ld_fenv
),
2991 /* Store the value of masked_fenv to clear the exceptions:
2992 __builtin_arm_set_fpscr (masked_fenv); */
2994 *clear
= build_call_expr (set_fpscr
, 1, masked_fenv
);
2996 /* Generate the equivalent of :
2997 unsigned int new_fenv_var;
2998 new_fenv_var = __builtin_arm_get_fpscr ();
3000 __builtin_arm_set_fpscr (fenv_var);
3002 __atomic_feraiseexcept (new_fenv_var); */
3004 new_fenv_var
= create_tmp_var_raw (unsigned_type_node
);
3005 reload_fenv
= build2 (MODIFY_EXPR
, unsigned_type_node
, new_fenv_var
,
3006 build_call_expr (get_fpscr
, 0));
3007 restore_fnenv
= build_call_expr (set_fpscr
, 1, fenv_var
);
3008 atomic_feraiseexcept
= builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT
);
3009 update_call
= build_call_expr (atomic_feraiseexcept
, 1,
3010 fold_convert (integer_type_node
, new_fenv_var
));
3011 *update
= build2 (COMPOUND_EXPR
, void_type_node
,
3012 build2 (COMPOUND_EXPR
, void_type_node
,
3013 reload_fenv
, restore_fnenv
), update_call
);
3016 #include "gt-arm-builtins.h"