1 /* Description of builtins used by the ARM backend.
2 Copyright (C) 2014-2018 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/>. */
20 #define IN_TARGET_CODE 1
24 #include "coretypes.h"
29 #include "gimple-expr.h"
32 #include "profile-count.h"
36 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "stor-layout.h"
41 #include "langhooks.h"
42 #include "case-cfn-macros.h"
45 #define SIMD_MAX_BUILTIN_ARGS 7
47 enum arm_type_qualifiers
52 qualifier_unsigned
= 0x1, /* 1 << 0 */
54 qualifier_const
= 0x2, /* 1 << 1 */
56 qualifier_pointer
= 0x4, /* 1 << 2 */
58 qualifier_const_pointer
= 0x6,
59 /* Used when expanding arguments if an operand could
61 qualifier_immediate
= 0x8, /* 1 << 3 */
62 qualifier_unsigned_immediate
= 0x9,
63 qualifier_maybe_immediate
= 0x10, /* 1 << 4 */
65 qualifier_void
= 0x20, /* 1 << 5 */
66 /* Some patterns may have internal operands, this qualifier is an
67 instruction to the initialisation code to skip this operand. */
68 qualifier_internal
= 0x40, /* 1 << 6 */
69 /* Some builtins should use the T_*mode* encoded in a simd_builtin_datum
70 rather than using the type of the operand. */
71 qualifier_map_mode
= 0x80, /* 1 << 7 */
72 /* qualifier_pointer | qualifier_map_mode */
73 qualifier_pointer_map_mode
= 0x84,
74 /* qualifier_const_pointer | qualifier_map_mode */
75 qualifier_const_pointer_map_mode
= 0x86,
76 /* Polynomial types. */
77 qualifier_poly
= 0x100,
78 /* Lane indices - must be within range of previous argument = a vector. */
79 qualifier_lane_index
= 0x200,
80 /* Lane indices for single lane structure loads and stores. */
81 qualifier_struct_load_store_lane_index
= 0x400
84 /* The qualifier_internal allows generation of a unary builtin from
85 a pattern with a third pseudo-operand such as a match_scratch.
87 static enum arm_type_qualifiers
88 arm_unop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
89 = { qualifier_none
, qualifier_none
, qualifier_internal
};
90 #define UNOP_QUALIFIERS (arm_unop_qualifiers)
92 /* unsigned T (unsigned T). */
93 static enum arm_type_qualifiers
94 arm_bswap_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
95 = { qualifier_unsigned
, qualifier_unsigned
};
96 #define BSWAP_QUALIFIERS (arm_bswap_qualifiers)
98 /* T (T, T [maybe_immediate]). */
99 static enum arm_type_qualifiers
100 arm_binop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
101 = { qualifier_none
, qualifier_none
, qualifier_maybe_immediate
};
102 #define BINOP_QUALIFIERS (arm_binop_qualifiers)
105 static enum arm_type_qualifiers
106 arm_ternop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
107 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_none
};
108 #define TERNOP_QUALIFIERS (arm_ternop_qualifiers)
110 /* unsigned T (unsigned T, unsigned T, unsigned T). */
111 static enum arm_type_qualifiers
112 arm_unsigned_uternop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
113 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
114 qualifier_unsigned
};
115 #define UTERNOP_QUALIFIERS (arm_unsigned_uternop_qualifiers)
117 /* T (T, immediate). */
118 static enum arm_type_qualifiers
119 arm_binop_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
120 = { qualifier_none
, qualifier_none
, qualifier_immediate
};
121 #define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers)
123 /* T (T, lane index). */
124 static enum arm_type_qualifiers
125 arm_getlane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
126 = { qualifier_none
, qualifier_none
, qualifier_lane_index
};
127 #define GETLANE_QUALIFIERS (arm_getlane_qualifiers)
129 /* T (T, T, T, immediate). */
130 static enum arm_type_qualifiers
131 arm_mac_n_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
132 = { qualifier_none
, qualifier_none
, qualifier_none
,
133 qualifier_none
, qualifier_immediate
};
134 #define MAC_N_QUALIFIERS (arm_mac_n_qualifiers)
136 /* T (T, T, T, lane index). */
137 static enum arm_type_qualifiers
138 arm_mac_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
139 = { qualifier_none
, qualifier_none
, qualifier_none
,
140 qualifier_none
, qualifier_lane_index
};
141 #define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers)
143 /* unsigned T (unsigned T, unsigned T, unsigend T, lane index). */
144 static enum arm_type_qualifiers
145 arm_umac_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
146 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
147 qualifier_unsigned
, qualifier_lane_index
};
148 #define UMAC_LANE_QUALIFIERS (arm_umac_lane_qualifiers)
150 /* T (T, T, immediate). */
151 static enum arm_type_qualifiers
152 arm_ternop_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
153 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_immediate
};
154 #define TERNOP_IMM_QUALIFIERS (arm_ternop_imm_qualifiers)
156 /* T (T, T, lane index). */
157 static enum arm_type_qualifiers
158 arm_setlane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
159 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_lane_index
};
160 #define SETLANE_QUALIFIERS (arm_setlane_qualifiers)
163 static enum arm_type_qualifiers
164 arm_combine_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
165 = { qualifier_none
, qualifier_none
, qualifier_none
};
166 #define COMBINE_QUALIFIERS (arm_combine_qualifiers)
168 /* T ([T element type] *). */
169 static enum arm_type_qualifiers
170 arm_load1_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
171 = { qualifier_none
, qualifier_const_pointer_map_mode
};
172 #define LOAD1_QUALIFIERS (arm_load1_qualifiers)
174 /* T ([T element type] *, T, immediate). */
175 static enum arm_type_qualifiers
176 arm_load1_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
177 = { qualifier_none
, qualifier_const_pointer_map_mode
,
178 qualifier_none
, qualifier_struct_load_store_lane_index
};
179 #define LOAD1LANE_QUALIFIERS (arm_load1_lane_qualifiers)
181 /* unsigned T (unsigned T, unsigned T, unsigned T). */
182 static enum arm_type_qualifiers
183 arm_unsigned_binop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
184 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
185 qualifier_unsigned
};
186 #define UBINOP_QUALIFIERS (arm_unsigned_binop_qualifiers)
188 /* void (unsigned immediate, unsigned immediate, unsigned immediate,
189 unsigned immediate, unsigned immediate, unsigned immediate). */
190 static enum arm_type_qualifiers
191 arm_cdp_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
192 = { qualifier_void
, qualifier_unsigned_immediate
,
193 qualifier_unsigned_immediate
,
194 qualifier_unsigned_immediate
,
195 qualifier_unsigned_immediate
,
196 qualifier_unsigned_immediate
,
197 qualifier_unsigned_immediate
};
198 #define CDP_QUALIFIERS \
201 /* void (unsigned immediate, unsigned immediate, const void *). */
202 static enum arm_type_qualifiers
203 arm_ldc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
204 = { qualifier_void
, qualifier_unsigned_immediate
,
205 qualifier_unsigned_immediate
, qualifier_const_pointer
};
206 #define LDC_QUALIFIERS \
209 /* void (unsigned immediate, unsigned immediate, void *). */
210 static enum arm_type_qualifiers
211 arm_stc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
212 = { qualifier_void
, qualifier_unsigned_immediate
,
213 qualifier_unsigned_immediate
, qualifier_pointer
};
214 #define STC_QUALIFIERS \
217 /* void (unsigned immediate, unsigned immediate, T, unsigned immediate,
218 unsigned immediate, unsigned immediate). */
219 static enum arm_type_qualifiers
220 arm_mcr_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
221 = { qualifier_void
, qualifier_unsigned_immediate
,
222 qualifier_unsigned_immediate
, qualifier_none
,
223 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
,
224 qualifier_unsigned_immediate
};
225 #define MCR_QUALIFIERS \
228 /* T (unsigned immediate, unsigned immediate, unsigned immediate,
229 unsigned immediate, unsigned immediate). */
230 static enum arm_type_qualifiers
231 arm_mrc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
232 = { qualifier_none
, qualifier_unsigned_immediate
,
233 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
,
234 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
};
235 #define MRC_QUALIFIERS \
238 /* void (unsigned immediate, unsigned immediate, T, unsigned immediate). */
239 static enum arm_type_qualifiers
240 arm_mcrr_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
241 = { qualifier_void
, qualifier_unsigned_immediate
,
242 qualifier_unsigned_immediate
, qualifier_none
,
243 qualifier_unsigned_immediate
};
244 #define MCRR_QUALIFIERS \
245 (arm_mcrr_qualifiers)
247 /* T (unsigned immediate, unsigned immediate, unsigned immediate). */
248 static enum arm_type_qualifiers
249 arm_mrrc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
250 = { qualifier_none
, qualifier_unsigned_immediate
,
251 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
};
252 #define MRRC_QUALIFIERS \
253 (arm_mrrc_qualifiers)
255 /* The first argument (return type) of a store should be void type,
256 which we represent with qualifier_void. Their first operand will be
257 a DImode pointer to the location to store to, so we must use
258 qualifier_map_mode | qualifier_pointer to build a pointer to the
259 element type of the vector.
261 void ([T element type] *, T). */
262 static enum arm_type_qualifiers
263 arm_store1_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
264 = { qualifier_void
, qualifier_pointer_map_mode
, qualifier_none
};
265 #define STORE1_QUALIFIERS (arm_store1_qualifiers)
267 /* void ([T element type] *, T, immediate). */
268 static enum arm_type_qualifiers
269 arm_storestruct_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
270 = { qualifier_void
, qualifier_pointer_map_mode
,
271 qualifier_none
, qualifier_struct_load_store_lane_index
};
272 #define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers)
274 #define v8qi_UP E_V8QImode
275 #define v4hi_UP E_V4HImode
276 #define v4hf_UP E_V4HFmode
277 #define v2si_UP E_V2SImode
278 #define v2sf_UP E_V2SFmode
279 #define di_UP E_DImode
280 #define v16qi_UP E_V16QImode
281 #define v8hi_UP E_V8HImode
282 #define v8hf_UP E_V8HFmode
283 #define v4si_UP E_V4SImode
284 #define v4sf_UP E_V4SFmode
285 #define v2di_UP E_V2DImode
286 #define ti_UP E_TImode
287 #define ei_UP E_EImode
288 #define oi_UP E_OImode
289 #define hf_UP E_HFmode
290 #define si_UP E_SImode
291 #define void_UP E_VOIDmode
298 const enum insn_code code
;
300 enum arm_type_qualifiers
*qualifiers
;
303 #define CF(N,X) CODE_FOR_neon_##N##X
305 #define VAR1(T, N, A) \
306 {#N #A, UP (A), CF (N, A), 0, T##_QUALIFIERS},
307 #define VAR2(T, N, A, B) \
310 #define VAR3(T, N, A, B, C) \
313 #define VAR4(T, N, A, B, C, D) \
314 VAR3 (T, N, A, B, C) \
316 #define VAR5(T, N, A, B, C, D, E) \
317 VAR4 (T, N, A, B, C, D) \
319 #define VAR6(T, N, A, B, C, D, E, F) \
320 VAR5 (T, N, A, B, C, D, E) \
322 #define VAR7(T, N, A, B, C, D, E, F, G) \
323 VAR6 (T, N, A, B, C, D, E, F) \
325 #define VAR8(T, N, A, B, C, D, E, F, G, H) \
326 VAR7 (T, N, A, B, C, D, E, F, G) \
328 #define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
329 VAR8 (T, N, A, B, C, D, E, F, G, H) \
331 #define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
332 VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
334 #define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \
335 VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \
337 #define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
338 VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
341 /* The builtin data can be found in arm_neon_builtins.def, arm_vfp_builtins.def
342 and arm_acle_builtins.def. The entries in arm_neon_builtins.def require
343 TARGET_NEON to be true. The feature tests are checked when the builtins are
346 The mode entries in the following table correspond to the "key" type of the
347 instruction variant, i.e. equivalent to that which would be specified after
348 the assembler mnemonic for neon instructions, which usually refers to the
349 last vector operand. The modes listed per instruction should be the same as
350 those defined for that instruction's pattern, for instance in neon.md. */
352 static arm_builtin_datum vfp_builtin_data
[] =
354 #include "arm_vfp_builtins.def"
357 static arm_builtin_datum neon_builtin_data
[] =
359 #include "arm_neon_builtins.def"
364 #define VAR1(T, N, A) \
365 {#N, UP (A), CODE_FOR_##N, 0, T##_QUALIFIERS},
367 static arm_builtin_datum acle_builtin_data
[] =
369 #include "arm_acle_builtins.def"
374 #define VAR1(T, N, X) \
375 ARM_BUILTIN_NEON_##N##X,
379 ARM_BUILTIN_GETWCGR0
,
380 ARM_BUILTIN_GETWCGR1
,
381 ARM_BUILTIN_GETWCGR2
,
382 ARM_BUILTIN_GETWCGR3
,
384 ARM_BUILTIN_SETWCGR0
,
385 ARM_BUILTIN_SETWCGR1
,
386 ARM_BUILTIN_SETWCGR2
,
387 ARM_BUILTIN_SETWCGR3
,
411 ARM_BUILTIN_WALIGNR0
,
412 ARM_BUILTIN_WALIGNR1
,
413 ARM_BUILTIN_WALIGNR2
,
414 ARM_BUILTIN_WALIGNR3
,
423 ARM_BUILTIN_TMOVMSKB
,
424 ARM_BUILTIN_TMOVMSKH
,
425 ARM_BUILTIN_TMOVMSKW
,
434 ARM_BUILTIN_WPACKHSS
,
435 ARM_BUILTIN_WPACKWSS
,
436 ARM_BUILTIN_WPACKDSS
,
437 ARM_BUILTIN_WPACKHUS
,
438 ARM_BUILTIN_WPACKWUS
,
439 ARM_BUILTIN_WPACKDUS
,
468 ARM_BUILTIN_WCMPGTUB
,
469 ARM_BUILTIN_WCMPGTUH
,
470 ARM_BUILTIN_WCMPGTUW
,
471 ARM_BUILTIN_WCMPGTSB
,
472 ARM_BUILTIN_WCMPGTSH
,
473 ARM_BUILTIN_WCMPGTSW
,
475 ARM_BUILTIN_TEXTRMSB
,
476 ARM_BUILTIN_TEXTRMSH
,
477 ARM_BUILTIN_TEXTRMSW
,
478 ARM_BUILTIN_TEXTRMUB
,
479 ARM_BUILTIN_TEXTRMUH
,
480 ARM_BUILTIN_TEXTRMUW
,
530 ARM_BUILTIN_WUNPCKIHB
,
531 ARM_BUILTIN_WUNPCKIHH
,
532 ARM_BUILTIN_WUNPCKIHW
,
533 ARM_BUILTIN_WUNPCKILB
,
534 ARM_BUILTIN_WUNPCKILH
,
535 ARM_BUILTIN_WUNPCKILW
,
537 ARM_BUILTIN_WUNPCKEHSB
,
538 ARM_BUILTIN_WUNPCKEHSH
,
539 ARM_BUILTIN_WUNPCKEHSW
,
540 ARM_BUILTIN_WUNPCKEHUB
,
541 ARM_BUILTIN_WUNPCKEHUH
,
542 ARM_BUILTIN_WUNPCKEHUW
,
543 ARM_BUILTIN_WUNPCKELSB
,
544 ARM_BUILTIN_WUNPCKELSH
,
545 ARM_BUILTIN_WUNPCKELSW
,
546 ARM_BUILTIN_WUNPCKELUB
,
547 ARM_BUILTIN_WUNPCKELUH
,
548 ARM_BUILTIN_WUNPCKELUW
,
554 ARM_BUILTIN_WADDSUBHX
,
555 ARM_BUILTIN_WSUBADDHX
,
557 ARM_BUILTIN_WABSDIFFB
,
558 ARM_BUILTIN_WABSDIFFH
,
559 ARM_BUILTIN_WABSDIFFW
,
576 ARM_BUILTIN_WMULWSMR
,
577 ARM_BUILTIN_WMULWUMR
,
588 ARM_BUILTIN_WQMULWMR
,
590 ARM_BUILTIN_WADDBHUSM
,
591 ARM_BUILTIN_WADDBHUSL
,
598 ARM_BUILTIN_WQMIABBN
,
599 ARM_BUILTIN_WQMIABTN
,
600 ARM_BUILTIN_WQMIATBN
,
601 ARM_BUILTIN_WQMIATTN
,
618 ARM_BUILTIN_WMIAWBBN
,
619 ARM_BUILTIN_WMIAWBTN
,
620 ARM_BUILTIN_WMIAWTBN
,
621 ARM_BUILTIN_WMIAWTTN
,
625 ARM_BUILTIN_GET_FPSCR
,
626 ARM_BUILTIN_SET_FPSCR
,
628 ARM_BUILTIN_CMSE_NONSECURE_CALLER
,
634 #define CRYPTO1(L, U, M1, M2) \
635 ARM_BUILTIN_CRYPTO_##U,
636 #define CRYPTO2(L, U, M1, M2, M3) \
637 ARM_BUILTIN_CRYPTO_##U,
638 #define CRYPTO3(L, U, M1, M2, M3, M4) \
639 ARM_BUILTIN_CRYPTO_##U,
641 ARM_BUILTIN_CRYPTO_BASE
,
643 #include "crypto.def"
649 ARM_BUILTIN_VFP_BASE
,
651 #include "arm_vfp_builtins.def"
653 ARM_BUILTIN_NEON_BASE
,
654 ARM_BUILTIN_NEON_LANE_CHECK
= ARM_BUILTIN_NEON_BASE
,
656 #include "arm_neon_builtins.def"
659 #define VAR1(T, N, X) \
662 ARM_BUILTIN_ACLE_BASE
,
664 #include "arm_acle_builtins.def"
669 #define ARM_BUILTIN_VFP_PATTERN_START \
670 (ARM_BUILTIN_VFP_BASE + 1)
672 #define ARM_BUILTIN_NEON_PATTERN_START \
673 (ARM_BUILTIN_NEON_BASE + 1)
675 #define ARM_BUILTIN_ACLE_PATTERN_START \
676 (ARM_BUILTIN_ACLE_BASE + 1)
690 static GTY(()) tree arm_builtin_decls
[ARM_BUILTIN_MAX
];
692 #define NUM_DREG_TYPES 5
693 #define NUM_QREG_TYPES 6
695 /* Internal scalar builtin types. These types are used to support
696 neon intrinsic builtins. They are _not_ user-visible types. Therefore
697 the mangling for these types are implementation defined. */
698 const char *arm_scalar_builtin_types
[] = {
706 "__builtin_neon_uqi",
707 "__builtin_neon_uhi",
708 "__builtin_neon_usi",
709 "__builtin_neon_udi",
717 #define ENTRY(E, M, Q, S, T, G) E,
720 #include "arm-simd-builtin-types.def"
725 struct arm_simd_type_info
727 enum arm_simd_type type
;
729 /* Internal type name. */
732 /* Internal type name(mangled). The mangled names conform to the
733 AAPCS (see "Procedure Call Standard for the ARM Architecture",
734 Appendix A). To qualify for emission with the mangled names defined in
735 that document, a vector type must not only be of the correct mode but also
736 be of the correct internal Neon vector type (e.g. __simd64_int8_t);
737 these types are registered by arm_init_simd_builtin_types (). In other
738 words, vector types defined in other ways e.g. via vector_size attribute
739 will get default mangled names. */
748 /* Machine mode the internal type maps to. */
752 enum arm_type_qualifiers q
;
755 #define ENTRY(E, M, Q, S, T, G) \
757 "__simd" #S "_" #T "_t", \
758 #G "__simd" #S "_" #T "_t", \
759 NULL_TREE, NULL_TREE, M##mode, qualifier_##Q},
760 static struct arm_simd_type_info arm_simd_types
[] = {
761 #include "arm-simd-builtin-types.def"
765 /* The user-visible __fp16 type. */
766 tree arm_fp16_type_node
= NULL_TREE
;
767 static tree arm_simd_intOI_type_node
= NULL_TREE
;
768 static tree arm_simd_intEI_type_node
= NULL_TREE
;
769 static tree arm_simd_intCI_type_node
= NULL_TREE
;
770 static tree arm_simd_intXI_type_node
= NULL_TREE
;
771 static tree arm_simd_polyQI_type_node
= NULL_TREE
;
772 static tree arm_simd_polyHI_type_node
= NULL_TREE
;
773 static tree arm_simd_polyDI_type_node
= NULL_TREE
;
774 static tree arm_simd_polyTI_type_node
= NULL_TREE
;
777 arm_mangle_builtin_scalar_type (const_tree type
)
781 while (arm_scalar_builtin_types
[i
] != NULL
)
783 const char *name
= arm_scalar_builtin_types
[i
];
785 if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
786 && DECL_NAME (TYPE_NAME (type
))
787 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
))), name
))
788 return arm_scalar_builtin_types
[i
];
795 arm_mangle_builtin_vector_type (const_tree type
)
798 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
800 for (i
= 0; i
< nelts
; i
++)
801 if (arm_simd_types
[i
].mode
== TYPE_MODE (type
)
803 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
804 && DECL_NAME (TYPE_NAME (type
))
806 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
))),
807 arm_simd_types
[i
].name
))
808 return arm_simd_types
[i
].mangle
;
814 arm_mangle_builtin_type (const_tree type
)
817 /* Walk through all the AArch64 builtins types tables to filter out the
819 if ((mangle
= arm_mangle_builtin_vector_type (type
))
820 || (mangle
= arm_mangle_builtin_scalar_type (type
)))
827 arm_simd_builtin_std_type (machine_mode mode
,
828 enum arm_type_qualifiers q
)
830 #define QUAL_TYPE(M) \
831 ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node);
835 return QUAL_TYPE (QI
);
837 return QUAL_TYPE (HI
);
839 return QUAL_TYPE (SI
);
841 return QUAL_TYPE (DI
);
843 return QUAL_TYPE (TI
);
845 return arm_simd_intOI_type_node
;
847 return arm_simd_intEI_type_node
;
849 return arm_simd_intCI_type_node
;
851 return arm_simd_intXI_type_node
;
853 return arm_fp16_type_node
;
855 return float_type_node
;
857 return double_type_node
;
865 arm_lookup_simd_builtin_type (machine_mode mode
,
866 enum arm_type_qualifiers q
)
869 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
871 /* Non-poly scalar modes map to standard types not in the table. */
872 if (q
!= qualifier_poly
&& !VECTOR_MODE_P (mode
))
873 return arm_simd_builtin_std_type (mode
, q
);
875 for (i
= 0; i
< nelts
; i
++)
876 if (arm_simd_types
[i
].mode
== mode
877 && arm_simd_types
[i
].q
== q
)
878 return arm_simd_types
[i
].itype
;
880 /* Note that we won't have caught the underlying type for poly64x2_t
881 in the above table. This gets default mangling. */
887 arm_simd_builtin_type (machine_mode mode
, bool unsigned_p
, bool poly_p
)
890 return arm_lookup_simd_builtin_type (mode
, qualifier_poly
);
892 return arm_lookup_simd_builtin_type (mode
, qualifier_unsigned
);
894 return arm_lookup_simd_builtin_type (mode
, qualifier_none
);
898 arm_init_simd_builtin_types (void)
901 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
904 /* Poly types are a world of their own. In order to maintain legacy
905 ABI, they get initialized using the old interface, and don't get
906 an entry in our mangling table, consequently, they get default
907 mangling. As a further gotcha, poly8_t and poly16_t are signed
908 types, poly64_t and poly128_t are unsigned types. */
909 arm_simd_polyQI_type_node
910 = build_distinct_type_copy (intQI_type_node
);
911 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyQI_type_node
,
912 "__builtin_neon_poly8");
913 arm_simd_polyHI_type_node
914 = build_distinct_type_copy (intHI_type_node
);
915 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyHI_type_node
,
916 "__builtin_neon_poly16");
917 arm_simd_polyDI_type_node
918 = build_distinct_type_copy (unsigned_intDI_type_node
);
919 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyDI_type_node
,
920 "__builtin_neon_poly64");
921 arm_simd_polyTI_type_node
922 = build_distinct_type_copy (unsigned_intTI_type_node
);
923 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyTI_type_node
,
924 "__builtin_neon_poly128");
926 /* Init all the element types built by the front-end. */
927 arm_simd_types
[Int8x8_t
].eltype
= intQI_type_node
;
928 arm_simd_types
[Int8x16_t
].eltype
= intQI_type_node
;
929 arm_simd_types
[Int16x4_t
].eltype
= intHI_type_node
;
930 arm_simd_types
[Int16x8_t
].eltype
= intHI_type_node
;
931 arm_simd_types
[Int32x2_t
].eltype
= intSI_type_node
;
932 arm_simd_types
[Int32x4_t
].eltype
= intSI_type_node
;
933 arm_simd_types
[Int64x2_t
].eltype
= intDI_type_node
;
934 arm_simd_types
[Uint8x8_t
].eltype
= unsigned_intQI_type_node
;
935 arm_simd_types
[Uint8x16_t
].eltype
= unsigned_intQI_type_node
;
936 arm_simd_types
[Uint16x4_t
].eltype
= unsigned_intHI_type_node
;
937 arm_simd_types
[Uint16x8_t
].eltype
= unsigned_intHI_type_node
;
938 arm_simd_types
[Uint32x2_t
].eltype
= unsigned_intSI_type_node
;
939 arm_simd_types
[Uint32x4_t
].eltype
= unsigned_intSI_type_node
;
940 arm_simd_types
[Uint64x2_t
].eltype
= unsigned_intDI_type_node
;
942 /* Init poly vector element types with scalar poly types. */
943 arm_simd_types
[Poly8x8_t
].eltype
= arm_simd_polyQI_type_node
;
944 arm_simd_types
[Poly8x16_t
].eltype
= arm_simd_polyQI_type_node
;
945 arm_simd_types
[Poly16x4_t
].eltype
= arm_simd_polyHI_type_node
;
946 arm_simd_types
[Poly16x8_t
].eltype
= arm_simd_polyHI_type_node
;
947 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
950 /* Continue with standard types. */
951 /* The __builtin_simd{64,128}_float16 types are kept private unless
952 we have a scalar __fp16 type. */
953 arm_simd_types
[Float16x4_t
].eltype
= arm_fp16_type_node
;
954 arm_simd_types
[Float16x8_t
].eltype
= arm_fp16_type_node
;
955 arm_simd_types
[Float32x2_t
].eltype
= float_type_node
;
956 arm_simd_types
[Float32x4_t
].eltype
= float_type_node
;
958 for (i
= 0; i
< nelts
; i
++)
960 tree eltype
= arm_simd_types
[i
].eltype
;
961 machine_mode mode
= arm_simd_types
[i
].mode
;
963 if (arm_simd_types
[i
].itype
== NULL
)
964 arm_simd_types
[i
].itype
=
965 build_distinct_type_copy
966 (build_vector_type (eltype
, GET_MODE_NUNITS (mode
)));
968 tdecl
= add_builtin_type (arm_simd_types
[i
].name
,
969 arm_simd_types
[i
].itype
);
970 TYPE_NAME (arm_simd_types
[i
].itype
) = tdecl
;
971 SET_TYPE_STRUCTURAL_EQUALITY (arm_simd_types
[i
].itype
);
974 #define AARCH_BUILD_SIGNED_TYPE(mode) \
975 make_signed_type (GET_MODE_PRECISION (mode));
976 arm_simd_intOI_type_node
= AARCH_BUILD_SIGNED_TYPE (OImode
);
977 arm_simd_intEI_type_node
= AARCH_BUILD_SIGNED_TYPE (EImode
);
978 arm_simd_intCI_type_node
= AARCH_BUILD_SIGNED_TYPE (CImode
);
979 arm_simd_intXI_type_node
= AARCH_BUILD_SIGNED_TYPE (XImode
);
980 #undef AARCH_BUILD_SIGNED_TYPE
982 tdecl
= add_builtin_type
983 ("__builtin_neon_ei" , arm_simd_intEI_type_node
);
984 TYPE_NAME (arm_simd_intEI_type_node
) = tdecl
;
985 tdecl
= add_builtin_type
986 ("__builtin_neon_oi" , arm_simd_intOI_type_node
);
987 TYPE_NAME (arm_simd_intOI_type_node
) = tdecl
;
988 tdecl
= add_builtin_type
989 ("__builtin_neon_ci" , arm_simd_intCI_type_node
);
990 TYPE_NAME (arm_simd_intCI_type_node
) = tdecl
;
991 tdecl
= add_builtin_type
992 ("__builtin_neon_xi" , arm_simd_intXI_type_node
);
993 TYPE_NAME (arm_simd_intXI_type_node
) = tdecl
;
997 arm_init_simd_builtin_scalar_types (void)
999 /* Define typedefs for all the standard scalar types. */
1000 (*lang_hooks
.types
.register_builtin_type
) (intQI_type_node
,
1001 "__builtin_neon_qi");
1002 (*lang_hooks
.types
.register_builtin_type
) (intHI_type_node
,
1003 "__builtin_neon_hi");
1004 (*lang_hooks
.types
.register_builtin_type
) (intSI_type_node
,
1005 "__builtin_neon_si");
1006 (*lang_hooks
.types
.register_builtin_type
) (float_type_node
,
1007 "__builtin_neon_sf");
1008 (*lang_hooks
.types
.register_builtin_type
) (intDI_type_node
,
1009 "__builtin_neon_di");
1010 (*lang_hooks
.types
.register_builtin_type
) (double_type_node
,
1011 "__builtin_neon_df");
1012 (*lang_hooks
.types
.register_builtin_type
) (intTI_type_node
,
1013 "__builtin_neon_ti");
1015 /* Unsigned integer types for various mode sizes. */
1016 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intQI_type_node
,
1017 "__builtin_neon_uqi");
1018 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intHI_type_node
,
1019 "__builtin_neon_uhi");
1020 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intSI_type_node
,
1021 "__builtin_neon_usi");
1022 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intDI_type_node
,
1023 "__builtin_neon_udi");
1024 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intTI_type_node
,
1025 "__builtin_neon_uti");
1028 /* Set up a builtin. It will use information stored in the argument struct D to
1029 derive the builtin's type signature and name. It will append the name in D
1030 to the PREFIX passed and use these to create a builtin declaration that is
1031 then stored in 'arm_builtin_decls' under index FCODE. This FCODE is also
1032 written back to D for future use. */
1035 arm_init_builtin (unsigned int fcode
, arm_builtin_datum
*d
,
1036 const char * prefix
)
1038 bool print_type_signature_p
= false;
1039 char type_signature
[SIMD_MAX_BUILTIN_ARGS
] = { 0 };
1046 /* We must track two variables here. op_num is
1047 the operand number as in the RTL pattern. This is
1048 required to access the mode (e.g. V4SF mode) of the
1049 argument, from which the base type can be derived.
1050 arg_num is an index in to the qualifiers data, which
1051 gives qualifiers to the type (e.g. const unsigned).
1052 The reason these two variables may differ by one is the
1053 void return type. While all return types take the 0th entry
1054 in the qualifiers array, there is no operand for them in the
1056 int op_num
= insn_data
[d
->code
].n_operands
- 1;
1057 int arg_num
= d
->qualifiers
[0] & qualifier_void
1060 tree return_type
= void_type_node
, args
= void_list_node
;
1063 /* Build a function type directly from the insn_data for this
1064 builtin. The build_function_type () function takes care of
1065 removing duplicates for us. */
1066 for (; op_num
>= 0; arg_num
--, op_num
--)
1068 machine_mode op_mode
= insn_data
[d
->code
].operand
[op_num
].mode
;
1069 enum arm_type_qualifiers qualifiers
= d
->qualifiers
[arg_num
];
1071 if (qualifiers
& qualifier_unsigned
)
1073 type_signature
[arg_num
] = 'u';
1074 print_type_signature_p
= true;
1076 else if (qualifiers
& qualifier_poly
)
1078 type_signature
[arg_num
] = 'p';
1079 print_type_signature_p
= true;
1082 type_signature
[arg_num
] = 's';
1084 /* Skip an internal operand for vget_{low, high}. */
1085 if (qualifiers
& qualifier_internal
)
1088 /* Some builtins have different user-facing types
1089 for certain arguments, encoded in d->mode. */
1090 if (qualifiers
& qualifier_map_mode
)
1093 /* For pointers, we want a pointer to the basic type
1095 if (qualifiers
& qualifier_pointer
&& VECTOR_MODE_P (op_mode
))
1096 op_mode
= GET_MODE_INNER (op_mode
);
1098 eltype
= arm_simd_builtin_type
1100 (qualifiers
& qualifier_unsigned
) != 0,
1101 (qualifiers
& qualifier_poly
) != 0);
1102 gcc_assert (eltype
!= NULL
);
1104 /* Add qualifiers. */
1105 if (qualifiers
& qualifier_const
)
1106 eltype
= build_qualified_type (eltype
, TYPE_QUAL_CONST
);
1108 if (qualifiers
& qualifier_pointer
)
1109 eltype
= build_pointer_type (eltype
);
1111 /* If we have reached arg_num == 0, we are at a non-void
1112 return type. Otherwise, we are still processing
1115 return_type
= eltype
;
1117 args
= tree_cons (NULL_TREE
, eltype
, args
);
1120 ftype
= build_function_type (return_type
, args
);
1122 gcc_assert (ftype
!= NULL
);
1124 if (print_type_signature_p
1125 && IN_RANGE (fcode
, ARM_BUILTIN_VFP_BASE
, ARM_BUILTIN_ACLE_BASE
- 1))
1126 snprintf (namebuf
, sizeof (namebuf
), "%s_%s_%s",
1127 prefix
, d
->name
, type_signature
);
1129 snprintf (namebuf
, sizeof (namebuf
), "%s_%s",
1132 fndecl
= add_builtin_function (namebuf
, ftype
, fcode
, BUILT_IN_MD
,
1134 arm_builtin_decls
[fcode
] = fndecl
;
1137 /* Set up ACLE builtins, even builtins for instructions that are not
1138 in the current target ISA to allow the user to compile particular modules
1139 with different target specific options that differ from the command line
1140 options. Such builtins will be rejected in arm_expand_builtin. */
1143 arm_init_acle_builtins (void)
1145 unsigned int i
, fcode
= ARM_BUILTIN_ACLE_PATTERN_START
;
1147 for (i
= 0; i
< ARRAY_SIZE (acle_builtin_data
); i
++, fcode
++)
1149 arm_builtin_datum
*d
= &acle_builtin_data
[i
];
1150 arm_init_builtin (fcode
, d
, "__builtin_arm");
1154 /* Set up all the NEON builtins, even builtins for instructions that are not
1155 in the current target ISA to allow the user to compile particular modules
1156 with different target specific options that differ from the command line
1157 options. Such builtins will be rejected in arm_expand_builtin. */
1160 arm_init_neon_builtins (void)
1162 unsigned int i
, fcode
= ARM_BUILTIN_NEON_PATTERN_START
;
1164 arm_init_simd_builtin_types ();
1166 /* Strong-typing hasn't been implemented for all AdvSIMD builtin intrinsics.
1167 Therefore we need to preserve the old __builtin scalar types. It can be
1168 removed once all the intrinsics become strongly typed using the qualifier
1170 arm_init_simd_builtin_scalar_types ();
1172 tree lane_check_fpr
= build_function_type_list (void_type_node
,
1176 arm_builtin_decls
[ARM_BUILTIN_NEON_LANE_CHECK
] =
1177 add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr
,
1178 ARM_BUILTIN_NEON_LANE_CHECK
, BUILT_IN_MD
,
1181 for (i
= 0; i
< ARRAY_SIZE (neon_builtin_data
); i
++, fcode
++)
1183 arm_builtin_datum
*d
= &neon_builtin_data
[i
];
1184 arm_init_builtin (fcode
, d
, "__builtin_neon");
1188 /* Set up all the scalar floating point builtins. */
1191 arm_init_vfp_builtins (void)
1193 unsigned int i
, fcode
= ARM_BUILTIN_VFP_PATTERN_START
;
1195 for (i
= 0; i
< ARRAY_SIZE (vfp_builtin_data
); i
++, fcode
++)
1197 arm_builtin_datum
*d
= &vfp_builtin_data
[i
];
1198 arm_init_builtin (fcode
, d
, "__builtin_neon");
1203 arm_init_crypto_builtins (void)
1205 tree V16UQI_type_node
1206 = arm_simd_builtin_type (V16QImode
, true, false);
1208 tree V4USI_type_node
1209 = arm_simd_builtin_type (V4SImode
, true, false);
1211 tree v16uqi_ftype_v16uqi
1212 = build_function_type_list (V16UQI_type_node
, V16UQI_type_node
,
1215 tree v16uqi_ftype_v16uqi_v16uqi
1216 = build_function_type_list (V16UQI_type_node
, V16UQI_type_node
,
1217 V16UQI_type_node
, NULL_TREE
);
1219 tree v4usi_ftype_v4usi
1220 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1223 tree v4usi_ftype_v4usi_v4usi
1224 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1225 V4USI_type_node
, NULL_TREE
);
1227 tree v4usi_ftype_v4usi_v4usi_v4usi
1228 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1229 V4USI_type_node
, V4USI_type_node
,
1232 tree uti_ftype_udi_udi
1233 = build_function_type_list (unsigned_intTI_type_node
,
1234 unsigned_intDI_type_node
,
1235 unsigned_intDI_type_node
,
1249 ARM_BUILTIN_CRYPTO_##U
1251 "__builtin_arm_crypto_"#L
1254 #define FT2(R, A1, A2) \
1255 R##_ftype_##A1##_##A2
1256 #define FT3(R, A1, A2, A3) \
1257 R##_ftype_##A1##_##A2##_##A3
1258 #define CRYPTO1(L, U, R, A) \
1259 arm_builtin_decls[C (U)] \
1260 = add_builtin_function (N (L), FT1 (R, A), \
1261 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1262 #define CRYPTO2(L, U, R, A1, A2) \
1263 arm_builtin_decls[C (U)] \
1264 = add_builtin_function (N (L), FT2 (R, A1, A2), \
1265 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1267 #define CRYPTO3(L, U, R, A1, A2, A3) \
1268 arm_builtin_decls[C (U)] \
1269 = add_builtin_function (N (L), FT3 (R, A1, A2, A3), \
1270 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1271 #include "crypto.def"
1283 #undef NUM_DREG_TYPES
1284 #undef NUM_QREG_TYPES
1286 #define def_mbuiltin(FLAG, NAME, TYPE, CODE) \
1289 if (FLAG == isa_nobit \
1290 || bitmap_bit_p (arm_active_target.isa, FLAG)) \
1293 bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
1294 BUILT_IN_MD, NULL, NULL_TREE); \
1295 arm_builtin_decls[CODE] = bdecl; \
1300 struct builtin_description
1302 const enum isa_feature feature
;
1303 const enum insn_code icode
;
1304 const char * const name
;
1305 const enum arm_builtins code
;
1306 const enum rtx_code comparison
;
1307 const unsigned int flag
;
1310 static const struct builtin_description bdesc_2arg
[] =
1312 #define IWMMXT_BUILTIN(code, string, builtin) \
1313 { isa_bit_iwmmxt, CODE_FOR_##code, \
1314 "__builtin_arm_" string, \
1315 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1317 #define IWMMXT2_BUILTIN(code, string, builtin) \
1318 { isa_bit_iwmmxt2, CODE_FOR_##code, \
1319 "__builtin_arm_" string, \
1320 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1322 IWMMXT_BUILTIN (addv8qi3
, "waddb", WADDB
)
1323 IWMMXT_BUILTIN (addv4hi3
, "waddh", WADDH
)
1324 IWMMXT_BUILTIN (addv2si3
, "waddw", WADDW
)
1325 IWMMXT_BUILTIN (subv8qi3
, "wsubb", WSUBB
)
1326 IWMMXT_BUILTIN (subv4hi3
, "wsubh", WSUBH
)
1327 IWMMXT_BUILTIN (subv2si3
, "wsubw", WSUBW
)
1328 IWMMXT_BUILTIN (ssaddv8qi3
, "waddbss", WADDSSB
)
1329 IWMMXT_BUILTIN (ssaddv4hi3
, "waddhss", WADDSSH
)
1330 IWMMXT_BUILTIN (ssaddv2si3
, "waddwss", WADDSSW
)
1331 IWMMXT_BUILTIN (sssubv8qi3
, "wsubbss", WSUBSSB
)
1332 IWMMXT_BUILTIN (sssubv4hi3
, "wsubhss", WSUBSSH
)
1333 IWMMXT_BUILTIN (sssubv2si3
, "wsubwss", WSUBSSW
)
1334 IWMMXT_BUILTIN (usaddv8qi3
, "waddbus", WADDUSB
)
1335 IWMMXT_BUILTIN (usaddv4hi3
, "waddhus", WADDUSH
)
1336 IWMMXT_BUILTIN (usaddv2si3
, "waddwus", WADDUSW
)
1337 IWMMXT_BUILTIN (ussubv8qi3
, "wsubbus", WSUBUSB
)
1338 IWMMXT_BUILTIN (ussubv4hi3
, "wsubhus", WSUBUSH
)
1339 IWMMXT_BUILTIN (ussubv2si3
, "wsubwus", WSUBUSW
)
1340 IWMMXT_BUILTIN (mulv4hi3
, "wmulul", WMULUL
)
1341 IWMMXT_BUILTIN (smulv4hi3_highpart
, "wmulsm", WMULSM
)
1342 IWMMXT_BUILTIN (umulv4hi3_highpart
, "wmulum", WMULUM
)
1343 IWMMXT_BUILTIN (eqv8qi3
, "wcmpeqb", WCMPEQB
)
1344 IWMMXT_BUILTIN (eqv4hi3
, "wcmpeqh", WCMPEQH
)
1345 IWMMXT_BUILTIN (eqv2si3
, "wcmpeqw", WCMPEQW
)
1346 IWMMXT_BUILTIN (gtuv8qi3
, "wcmpgtub", WCMPGTUB
)
1347 IWMMXT_BUILTIN (gtuv4hi3
, "wcmpgtuh", WCMPGTUH
)
1348 IWMMXT_BUILTIN (gtuv2si3
, "wcmpgtuw", WCMPGTUW
)
1349 IWMMXT_BUILTIN (gtv8qi3
, "wcmpgtsb", WCMPGTSB
)
1350 IWMMXT_BUILTIN (gtv4hi3
, "wcmpgtsh", WCMPGTSH
)
1351 IWMMXT_BUILTIN (gtv2si3
, "wcmpgtsw", WCMPGTSW
)
1352 IWMMXT_BUILTIN (umaxv8qi3
, "wmaxub", WMAXUB
)
1353 IWMMXT_BUILTIN (smaxv8qi3
, "wmaxsb", WMAXSB
)
1354 IWMMXT_BUILTIN (umaxv4hi3
, "wmaxuh", WMAXUH
)
1355 IWMMXT_BUILTIN (smaxv4hi3
, "wmaxsh", WMAXSH
)
1356 IWMMXT_BUILTIN (umaxv2si3
, "wmaxuw", WMAXUW
)
1357 IWMMXT_BUILTIN (smaxv2si3
, "wmaxsw", WMAXSW
)
1358 IWMMXT_BUILTIN (uminv8qi3
, "wminub", WMINUB
)
1359 IWMMXT_BUILTIN (sminv8qi3
, "wminsb", WMINSB
)
1360 IWMMXT_BUILTIN (uminv4hi3
, "wminuh", WMINUH
)
1361 IWMMXT_BUILTIN (sminv4hi3
, "wminsh", WMINSH
)
1362 IWMMXT_BUILTIN (uminv2si3
, "wminuw", WMINUW
)
1363 IWMMXT_BUILTIN (sminv2si3
, "wminsw", WMINSW
)
1364 IWMMXT_BUILTIN (iwmmxt_anddi3
, "wand", WAND
)
1365 IWMMXT_BUILTIN (iwmmxt_nanddi3
, "wandn", WANDN
)
1366 IWMMXT_BUILTIN (iwmmxt_iordi3
, "wor", WOR
)
1367 IWMMXT_BUILTIN (iwmmxt_xordi3
, "wxor", WXOR
)
1368 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3
, "wavg2b", WAVG2B
)
1369 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3
, "wavg2h", WAVG2H
)
1370 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3
, "wavg2br", WAVG2BR
)
1371 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3
, "wavg2hr", WAVG2HR
)
1372 IWMMXT_BUILTIN (iwmmxt_wunpckilb
, "wunpckilb", WUNPCKILB
)
1373 IWMMXT_BUILTIN (iwmmxt_wunpckilh
, "wunpckilh", WUNPCKILH
)
1374 IWMMXT_BUILTIN (iwmmxt_wunpckilw
, "wunpckilw", WUNPCKILW
)
1375 IWMMXT_BUILTIN (iwmmxt_wunpckihb
, "wunpckihb", WUNPCKIHB
)
1376 IWMMXT_BUILTIN (iwmmxt_wunpckihh
, "wunpckihh", WUNPCKIHH
)
1377 IWMMXT_BUILTIN (iwmmxt_wunpckihw
, "wunpckihw", WUNPCKIHW
)
1378 IWMMXT2_BUILTIN (iwmmxt_waddsubhx
, "waddsubhx", WADDSUBHX
)
1379 IWMMXT2_BUILTIN (iwmmxt_wsubaddhx
, "wsubaddhx", WSUBADDHX
)
1380 IWMMXT2_BUILTIN (iwmmxt_wabsdiffb
, "wabsdiffb", WABSDIFFB
)
1381 IWMMXT2_BUILTIN (iwmmxt_wabsdiffh
, "wabsdiffh", WABSDIFFH
)
1382 IWMMXT2_BUILTIN (iwmmxt_wabsdiffw
, "wabsdiffw", WABSDIFFW
)
1383 IWMMXT2_BUILTIN (iwmmxt_avg4
, "wavg4", WAVG4
)
1384 IWMMXT2_BUILTIN (iwmmxt_avg4r
, "wavg4r", WAVG4R
)
1385 IWMMXT2_BUILTIN (iwmmxt_wmulwsm
, "wmulwsm", WMULWSM
)
1386 IWMMXT2_BUILTIN (iwmmxt_wmulwum
, "wmulwum", WMULWUM
)
1387 IWMMXT2_BUILTIN (iwmmxt_wmulwsmr
, "wmulwsmr", WMULWSMR
)
1388 IWMMXT2_BUILTIN (iwmmxt_wmulwumr
, "wmulwumr", WMULWUMR
)
1389 IWMMXT2_BUILTIN (iwmmxt_wmulwl
, "wmulwl", WMULWL
)
1390 IWMMXT2_BUILTIN (iwmmxt_wmulsmr
, "wmulsmr", WMULSMR
)
1391 IWMMXT2_BUILTIN (iwmmxt_wmulumr
, "wmulumr", WMULUMR
)
1392 IWMMXT2_BUILTIN (iwmmxt_wqmulm
, "wqmulm", WQMULM
)
1393 IWMMXT2_BUILTIN (iwmmxt_wqmulmr
, "wqmulmr", WQMULMR
)
1394 IWMMXT2_BUILTIN (iwmmxt_wqmulwm
, "wqmulwm", WQMULWM
)
1395 IWMMXT2_BUILTIN (iwmmxt_wqmulwmr
, "wqmulwmr", WQMULWMR
)
1396 IWMMXT_BUILTIN (iwmmxt_walignr0
, "walignr0", WALIGNR0
)
1397 IWMMXT_BUILTIN (iwmmxt_walignr1
, "walignr1", WALIGNR1
)
1398 IWMMXT_BUILTIN (iwmmxt_walignr2
, "walignr2", WALIGNR2
)
1399 IWMMXT_BUILTIN (iwmmxt_walignr3
, "walignr3", WALIGNR3
)
1401 #define IWMMXT_BUILTIN2(code, builtin) \
1402 { isa_bit_iwmmxt, CODE_FOR_##code, NULL, \
1403 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1405 #define IWMMXT2_BUILTIN2(code, builtin) \
1406 { isa_bit_iwmmxt2, CODE_FOR_##code, NULL, \
1407 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1409 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm
, WADDBHUSM
)
1410 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl
, WADDBHUSL
)
1411 IWMMXT_BUILTIN2 (iwmmxt_wpackhss
, WPACKHSS
)
1412 IWMMXT_BUILTIN2 (iwmmxt_wpackwss
, WPACKWSS
)
1413 IWMMXT_BUILTIN2 (iwmmxt_wpackdss
, WPACKDSS
)
1414 IWMMXT_BUILTIN2 (iwmmxt_wpackhus
, WPACKHUS
)
1415 IWMMXT_BUILTIN2 (iwmmxt_wpackwus
, WPACKWUS
)
1416 IWMMXT_BUILTIN2 (iwmmxt_wpackdus
, WPACKDUS
)
1417 IWMMXT_BUILTIN2 (iwmmxt_wmacuz
, WMACUZ
)
1418 IWMMXT_BUILTIN2 (iwmmxt_wmacsz
, WMACSZ
)
1421 #define FP_BUILTIN(L, U) \
1422 {isa_nobit, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
1425 FP_BUILTIN (get_fpscr
, GET_FPSCR
)
1426 FP_BUILTIN (set_fpscr
, SET_FPSCR
)
1429 #define CRYPTO_BUILTIN(L, U) \
1430 {isa_nobit, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, \
1431 ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0},
1435 #define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U)
1436 #define CRYPTO1(L, U, R, A)
1437 #define CRYPTO3(L, U, R, A1, A2, A3)
1438 #include "crypto.def"
1445 static const struct builtin_description bdesc_1arg
[] =
1447 IWMMXT_BUILTIN (iwmmxt_tmovmskb
, "tmovmskb", TMOVMSKB
)
1448 IWMMXT_BUILTIN (iwmmxt_tmovmskh
, "tmovmskh", TMOVMSKH
)
1449 IWMMXT_BUILTIN (iwmmxt_tmovmskw
, "tmovmskw", TMOVMSKW
)
1450 IWMMXT_BUILTIN (iwmmxt_waccb
, "waccb", WACCB
)
1451 IWMMXT_BUILTIN (iwmmxt_wacch
, "wacch", WACCH
)
1452 IWMMXT_BUILTIN (iwmmxt_waccw
, "waccw", WACCW
)
1453 IWMMXT_BUILTIN (iwmmxt_wunpckehub
, "wunpckehub", WUNPCKEHUB
)
1454 IWMMXT_BUILTIN (iwmmxt_wunpckehuh
, "wunpckehuh", WUNPCKEHUH
)
1455 IWMMXT_BUILTIN (iwmmxt_wunpckehuw
, "wunpckehuw", WUNPCKEHUW
)
1456 IWMMXT_BUILTIN (iwmmxt_wunpckehsb
, "wunpckehsb", WUNPCKEHSB
)
1457 IWMMXT_BUILTIN (iwmmxt_wunpckehsh
, "wunpckehsh", WUNPCKEHSH
)
1458 IWMMXT_BUILTIN (iwmmxt_wunpckehsw
, "wunpckehsw", WUNPCKEHSW
)
1459 IWMMXT_BUILTIN (iwmmxt_wunpckelub
, "wunpckelub", WUNPCKELUB
)
1460 IWMMXT_BUILTIN (iwmmxt_wunpckeluh
, "wunpckeluh", WUNPCKELUH
)
1461 IWMMXT_BUILTIN (iwmmxt_wunpckeluw
, "wunpckeluw", WUNPCKELUW
)
1462 IWMMXT_BUILTIN (iwmmxt_wunpckelsb
, "wunpckelsb", WUNPCKELSB
)
1463 IWMMXT_BUILTIN (iwmmxt_wunpckelsh
, "wunpckelsh", WUNPCKELSH
)
1464 IWMMXT_BUILTIN (iwmmxt_wunpckelsw
, "wunpckelsw", WUNPCKELSW
)
1465 IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3
, "wabsb", WABSB
)
1466 IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3
, "wabsh", WABSH
)
1467 IWMMXT2_BUILTIN (iwmmxt_wabsv2si3
, "wabsw", WABSW
)
1468 IWMMXT_BUILTIN (tbcstv8qi
, "tbcstb", TBCSTB
)
1469 IWMMXT_BUILTIN (tbcstv4hi
, "tbcsth", TBCSTH
)
1470 IWMMXT_BUILTIN (tbcstv2si
, "tbcstw", TBCSTW
)
1472 #define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U)
1473 #define CRYPTO2(L, U, R, A1, A2)
1474 #define CRYPTO3(L, U, R, A1, A2, A3)
1475 #include "crypto.def"
1481 static const struct builtin_description bdesc_3arg
[] =
1483 #define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U)
1484 #define CRYPTO1(L, U, R, A)
1485 #define CRYPTO2(L, U, R, A1, A2)
1486 #include "crypto.def"
1491 #undef CRYPTO_BUILTIN
1493 /* Set up all the iWMMXt builtins. This is not called if
1494 TARGET_IWMMXT is zero. */
1497 arm_init_iwmmxt_builtins (void)
1499 const struct builtin_description
* d
;
1502 tree V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
1503 tree V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
1504 tree V8QI_type_node
= build_vector_type_for_mode (intQI_type_node
, V8QImode
);
1506 tree v8qi_ftype_v8qi_v8qi_int
1507 = build_function_type_list (V8QI_type_node
,
1508 V8QI_type_node
, V8QI_type_node
,
1509 integer_type_node
, NULL_TREE
);
1510 tree v4hi_ftype_v4hi_int
1511 = build_function_type_list (V4HI_type_node
,
1512 V4HI_type_node
, integer_type_node
, NULL_TREE
);
1513 tree v2si_ftype_v2si_int
1514 = build_function_type_list (V2SI_type_node
,
1515 V2SI_type_node
, integer_type_node
, NULL_TREE
);
1516 tree v2si_ftype_di_di
1517 = build_function_type_list (V2SI_type_node
,
1518 long_long_integer_type_node
,
1519 long_long_integer_type_node
,
1521 tree di_ftype_di_int
1522 = build_function_type_list (long_long_integer_type_node
,
1523 long_long_integer_type_node
,
1524 integer_type_node
, NULL_TREE
);
1525 tree di_ftype_di_int_int
1526 = build_function_type_list (long_long_integer_type_node
,
1527 long_long_integer_type_node
,
1529 integer_type_node
, NULL_TREE
);
1531 = build_function_type_list (integer_type_node
,
1532 V8QI_type_node
, NULL_TREE
);
1534 = build_function_type_list (integer_type_node
,
1535 V4HI_type_node
, NULL_TREE
);
1537 = build_function_type_list (integer_type_node
,
1538 V2SI_type_node
, NULL_TREE
);
1539 tree int_ftype_v8qi_int
1540 = build_function_type_list (integer_type_node
,
1541 V8QI_type_node
, integer_type_node
, NULL_TREE
);
1542 tree int_ftype_v4hi_int
1543 = build_function_type_list (integer_type_node
,
1544 V4HI_type_node
, integer_type_node
, NULL_TREE
);
1545 tree int_ftype_v2si_int
1546 = build_function_type_list (integer_type_node
,
1547 V2SI_type_node
, integer_type_node
, NULL_TREE
);
1548 tree v8qi_ftype_v8qi_int_int
1549 = build_function_type_list (V8QI_type_node
,
1550 V8QI_type_node
, integer_type_node
,
1551 integer_type_node
, NULL_TREE
);
1552 tree v4hi_ftype_v4hi_int_int
1553 = build_function_type_list (V4HI_type_node
,
1554 V4HI_type_node
, integer_type_node
,
1555 integer_type_node
, NULL_TREE
);
1556 tree v2si_ftype_v2si_int_int
1557 = build_function_type_list (V2SI_type_node
,
1558 V2SI_type_node
, integer_type_node
,
1559 integer_type_node
, NULL_TREE
);
1560 /* Miscellaneous. */
1561 tree v8qi_ftype_v4hi_v4hi
1562 = build_function_type_list (V8QI_type_node
,
1563 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
1564 tree v4hi_ftype_v2si_v2si
1565 = build_function_type_list (V4HI_type_node
,
1566 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
1567 tree v8qi_ftype_v4hi_v8qi
1568 = build_function_type_list (V8QI_type_node
,
1569 V4HI_type_node
, V8QI_type_node
, NULL_TREE
);
1570 tree v2si_ftype_v4hi_v4hi
1571 = build_function_type_list (V2SI_type_node
,
1572 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
1573 tree v2si_ftype_v8qi_v8qi
1574 = build_function_type_list (V2SI_type_node
,
1575 V8QI_type_node
, V8QI_type_node
, NULL_TREE
);
1576 tree v4hi_ftype_v4hi_di
1577 = build_function_type_list (V4HI_type_node
,
1578 V4HI_type_node
, long_long_integer_type_node
,
1580 tree v2si_ftype_v2si_di
1581 = build_function_type_list (V2SI_type_node
,
1582 V2SI_type_node
, long_long_integer_type_node
,
1585 = build_function_type_list (long_long_unsigned_type_node
, NULL_TREE
);
1587 = build_function_type_list (integer_type_node
, NULL_TREE
);
1589 = build_function_type_list (long_long_integer_type_node
,
1590 V8QI_type_node
, NULL_TREE
);
1592 = build_function_type_list (long_long_integer_type_node
,
1593 V4HI_type_node
, NULL_TREE
);
1595 = build_function_type_list (long_long_integer_type_node
,
1596 V2SI_type_node
, NULL_TREE
);
1597 tree v2si_ftype_v4hi
1598 = build_function_type_list (V2SI_type_node
,
1599 V4HI_type_node
, NULL_TREE
);
1600 tree v4hi_ftype_v8qi
1601 = build_function_type_list (V4HI_type_node
,
1602 V8QI_type_node
, NULL_TREE
);
1603 tree v8qi_ftype_v8qi
1604 = build_function_type_list (V8QI_type_node
,
1605 V8QI_type_node
, NULL_TREE
);
1606 tree v4hi_ftype_v4hi
1607 = build_function_type_list (V4HI_type_node
,
1608 V4HI_type_node
, NULL_TREE
);
1609 tree v2si_ftype_v2si
1610 = build_function_type_list (V2SI_type_node
,
1611 V2SI_type_node
, NULL_TREE
);
1613 tree di_ftype_di_v4hi_v4hi
1614 = build_function_type_list (long_long_unsigned_type_node
,
1615 long_long_unsigned_type_node
,
1616 V4HI_type_node
, V4HI_type_node
,
1619 tree di_ftype_v4hi_v4hi
1620 = build_function_type_list (long_long_unsigned_type_node
,
1621 V4HI_type_node
,V4HI_type_node
,
1624 tree v2si_ftype_v2si_v4hi_v4hi
1625 = build_function_type_list (V2SI_type_node
,
1626 V2SI_type_node
, V4HI_type_node
,
1627 V4HI_type_node
, NULL_TREE
);
1629 tree v2si_ftype_v2si_v8qi_v8qi
1630 = build_function_type_list (V2SI_type_node
,
1631 V2SI_type_node
, V8QI_type_node
,
1632 V8QI_type_node
, NULL_TREE
);
1634 tree di_ftype_di_v2si_v2si
1635 = build_function_type_list (long_long_unsigned_type_node
,
1636 long_long_unsigned_type_node
,
1637 V2SI_type_node
, V2SI_type_node
,
1640 tree di_ftype_di_di_int
1641 = build_function_type_list (long_long_unsigned_type_node
,
1642 long_long_unsigned_type_node
,
1643 long_long_unsigned_type_node
,
1644 integer_type_node
, NULL_TREE
);
1647 = build_function_type_list (void_type_node
,
1648 integer_type_node
, NULL_TREE
);
1650 tree v8qi_ftype_char
1651 = build_function_type_list (V8QI_type_node
,
1652 signed_char_type_node
, NULL_TREE
);
1654 tree v4hi_ftype_short
1655 = build_function_type_list (V4HI_type_node
,
1656 short_integer_type_node
, NULL_TREE
);
1659 = build_function_type_list (V2SI_type_node
,
1660 integer_type_node
, NULL_TREE
);
1662 /* Normal vector binops. */
1663 tree v8qi_ftype_v8qi_v8qi
1664 = build_function_type_list (V8QI_type_node
,
1665 V8QI_type_node
, V8QI_type_node
, NULL_TREE
);
1666 tree v4hi_ftype_v4hi_v4hi
1667 = build_function_type_list (V4HI_type_node
,
1668 V4HI_type_node
,V4HI_type_node
, NULL_TREE
);
1669 tree v2si_ftype_v2si_v2si
1670 = build_function_type_list (V2SI_type_node
,
1671 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
1673 = build_function_type_list (long_long_unsigned_type_node
,
1674 long_long_unsigned_type_node
,
1675 long_long_unsigned_type_node
,
1678 /* Add all builtins that are more or less simple operations on two
1680 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
1682 /* Use one of the operands; the target can have a different mode for
1683 mask-generating compares. */
1688 || !(d
->feature
== isa_bit_iwmmxt
1689 || d
->feature
== isa_bit_iwmmxt2
))
1692 mode
= insn_data
[d
->icode
].operand
[1].mode
;
1697 type
= v8qi_ftype_v8qi_v8qi
;
1700 type
= v4hi_ftype_v4hi_v4hi
;
1703 type
= v2si_ftype_v2si_v2si
;
1706 type
= di_ftype_di_di
;
1713 def_mbuiltin (d
->feature
, d
->name
, type
, d
->code
);
1716 /* Add the remaining MMX insns with somewhat more complicated types. */
1717 #define iwmmx_mbuiltin(NAME, TYPE, CODE) \
1718 def_mbuiltin (isa_bit_iwmmxt, "__builtin_arm_" NAME, \
1719 (TYPE), ARM_BUILTIN_ ## CODE)
1721 #define iwmmx2_mbuiltin(NAME, TYPE, CODE) \
1722 def_mbuiltin (isa_bit_iwmmxt2, "__builtin_arm_" NAME, \
1723 (TYPE), ARM_BUILTIN_ ## CODE)
1725 iwmmx_mbuiltin ("wzero", di_ftype_void
, WZERO
);
1726 iwmmx_mbuiltin ("setwcgr0", void_ftype_int
, SETWCGR0
);
1727 iwmmx_mbuiltin ("setwcgr1", void_ftype_int
, SETWCGR1
);
1728 iwmmx_mbuiltin ("setwcgr2", void_ftype_int
, SETWCGR2
);
1729 iwmmx_mbuiltin ("setwcgr3", void_ftype_int
, SETWCGR3
);
1730 iwmmx_mbuiltin ("getwcgr0", int_ftype_void
, GETWCGR0
);
1731 iwmmx_mbuiltin ("getwcgr1", int_ftype_void
, GETWCGR1
);
1732 iwmmx_mbuiltin ("getwcgr2", int_ftype_void
, GETWCGR2
);
1733 iwmmx_mbuiltin ("getwcgr3", int_ftype_void
, GETWCGR3
);
1735 iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di
, WSLLH
);
1736 iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di
, WSLLW
);
1737 iwmmx_mbuiltin ("wslld", di_ftype_di_di
, WSLLD
);
1738 iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int
, WSLLHI
);
1739 iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int
, WSLLWI
);
1740 iwmmx_mbuiltin ("wslldi", di_ftype_di_int
, WSLLDI
);
1742 iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di
, WSRLH
);
1743 iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di
, WSRLW
);
1744 iwmmx_mbuiltin ("wsrld", di_ftype_di_di
, WSRLD
);
1745 iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int
, WSRLHI
);
1746 iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int
, WSRLWI
);
1747 iwmmx_mbuiltin ("wsrldi", di_ftype_di_int
, WSRLDI
);
1749 iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di
, WSRAH
);
1750 iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di
, WSRAW
);
1751 iwmmx_mbuiltin ("wsrad", di_ftype_di_di
, WSRAD
);
1752 iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int
, WSRAHI
);
1753 iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int
, WSRAWI
);
1754 iwmmx_mbuiltin ("wsradi", di_ftype_di_int
, WSRADI
);
1756 iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di
, WRORH
);
1757 iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di
, WRORW
);
1758 iwmmx_mbuiltin ("wrord", di_ftype_di_di
, WRORD
);
1759 iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int
, WRORHI
);
1760 iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int
, WRORWI
);
1761 iwmmx_mbuiltin ("wrordi", di_ftype_di_int
, WRORDI
);
1763 iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int
, WSHUFH
);
1765 iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi
, WSADB
);
1766 iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi
, WSADH
);
1767 iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi
, WMADDS
);
1768 iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi
, WMADDSX
);
1769 iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi
, WMADDSN
);
1770 iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi
, WMADDU
);
1771 iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi
, WMADDUX
);
1772 iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi
, WMADDUN
);
1773 iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi
, WSADBZ
);
1774 iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi
, WSADHZ
);
1776 iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int
, TEXTRMSB
);
1777 iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int
, TEXTRMSH
);
1778 iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int
, TEXTRMSW
);
1779 iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int
, TEXTRMUB
);
1780 iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int
, TEXTRMUH
);
1781 iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int
, TEXTRMUW
);
1782 iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int
, TINSRB
);
1783 iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int
, TINSRH
);
1784 iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int
, TINSRW
);
1786 iwmmx_mbuiltin ("waccb", di_ftype_v8qi
, WACCB
);
1787 iwmmx_mbuiltin ("wacch", di_ftype_v4hi
, WACCH
);
1788 iwmmx_mbuiltin ("waccw", di_ftype_v2si
, WACCW
);
1790 iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi
, TMOVMSKB
);
1791 iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi
, TMOVMSKH
);
1792 iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si
, TMOVMSKW
);
1794 iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi
, WADDBHUSM
);
1795 iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi
, WADDBHUSL
);
1797 iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi
, WPACKHSS
);
1798 iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi
, WPACKHUS
);
1799 iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si
, WPACKWUS
);
1800 iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si
, WPACKWSS
);
1801 iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di
, WPACKDUS
);
1802 iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di
, WPACKDSS
);
1804 iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi
, WUNPCKEHUB
);
1805 iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi
, WUNPCKEHUH
);
1806 iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si
, WUNPCKEHUW
);
1807 iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi
, WUNPCKEHSB
);
1808 iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi
, WUNPCKEHSH
);
1809 iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si
, WUNPCKEHSW
);
1810 iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi
, WUNPCKELUB
);
1811 iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi
, WUNPCKELUH
);
1812 iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si
, WUNPCKELUW
);
1813 iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi
, WUNPCKELSB
);
1814 iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi
, WUNPCKELSH
);
1815 iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si
, WUNPCKELSW
);
1817 iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi
, WMACS
);
1818 iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi
, WMACSZ
);
1819 iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi
, WMACU
);
1820 iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi
, WMACUZ
);
1822 iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int
, WALIGNI
);
1823 iwmmx_mbuiltin ("tmia", di_ftype_di_int_int
, TMIA
);
1824 iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int
, TMIAPH
);
1825 iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int
, TMIABB
);
1826 iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int
, TMIABT
);
1827 iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int
, TMIATB
);
1828 iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int
, TMIATT
);
1830 iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi
, WABSB
);
1831 iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi
, WABSH
);
1832 iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si
, WABSW
);
1834 iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi
, WQMIABB
);
1835 iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi
, WQMIABT
);
1836 iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi
, WQMIATB
);
1837 iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi
, WQMIATT
);
1839 iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi
, WQMIABBN
);
1840 iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi
, WQMIABTN
);
1841 iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi
, WQMIATBN
);
1842 iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi
, WQMIATTN
);
1844 iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi
, WMIABB
);
1845 iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi
, WMIABT
);
1846 iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi
, WMIATB
);
1847 iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi
, WMIATT
);
1849 iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi
, WMIABBN
);
1850 iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi
, WMIABTN
);
1851 iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi
, WMIATBN
);
1852 iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi
, WMIATTN
);
1854 iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si
, WMIAWBB
);
1855 iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si
, WMIAWBT
);
1856 iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si
, WMIAWTB
);
1857 iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si
, WMIAWTT
);
1859 iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si
, WMIAWBBN
);
1860 iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si
, WMIAWBTN
);
1861 iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si
, WMIAWTBN
);
1862 iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si
, WMIAWTTN
);
1864 iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int
, WMERGE
);
1866 iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char
, TBCSTB
);
1867 iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short
, TBCSTH
);
1868 iwmmx_mbuiltin ("tbcstw", v2si_ftype_int
, TBCSTW
);
1870 #undef iwmmx_mbuiltin
1871 #undef iwmmx2_mbuiltin
1875 arm_init_fp16_builtins (void)
1877 arm_fp16_type_node
= make_node (REAL_TYPE
);
1878 TYPE_PRECISION (arm_fp16_type_node
) = GET_MODE_PRECISION (HFmode
);
1879 layout_type (arm_fp16_type_node
);
1880 if (arm_fp16_format
)
1881 (*lang_hooks
.types
.register_builtin_type
) (arm_fp16_type_node
,
1886 arm_init_builtins (void)
1888 if (TARGET_REALLY_IWMMXT
)
1889 arm_init_iwmmxt_builtins ();
1891 /* This creates the arm_simd_floatHF_type_node so must come before
1892 arm_init_neon_builtins which uses it. */
1893 arm_init_fp16_builtins ();
1895 if (TARGET_MAYBE_HARD_FLOAT
)
1897 arm_init_neon_builtins ();
1898 arm_init_vfp_builtins ();
1899 arm_init_crypto_builtins ();
1902 arm_init_acle_builtins ();
1904 if (TARGET_MAYBE_HARD_FLOAT
)
1906 tree ftype_set_fpscr
1907 = build_function_type_list (void_type_node
, unsigned_type_node
, NULL
);
1908 tree ftype_get_fpscr
1909 = build_function_type_list (unsigned_type_node
, NULL
);
1911 arm_builtin_decls
[ARM_BUILTIN_GET_FPSCR
]
1912 = add_builtin_function ("__builtin_arm_get_fpscr", ftype_get_fpscr
,
1913 ARM_BUILTIN_GET_FPSCR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1914 arm_builtin_decls
[ARM_BUILTIN_SET_FPSCR
]
1915 = add_builtin_function ("__builtin_arm_set_fpscr", ftype_set_fpscr
,
1916 ARM_BUILTIN_SET_FPSCR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1921 tree ftype_cmse_nonsecure_caller
1922 = build_function_type_list (unsigned_type_node
, NULL
);
1923 arm_builtin_decls
[ARM_BUILTIN_CMSE_NONSECURE_CALLER
]
1924 = add_builtin_function ("__builtin_arm_cmse_nonsecure_caller",
1925 ftype_cmse_nonsecure_caller
,
1926 ARM_BUILTIN_CMSE_NONSECURE_CALLER
, BUILT_IN_MD
,
1931 /* Return the ARM builtin for CODE. */
1934 arm_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
1936 if (code
>= ARM_BUILTIN_MAX
)
1937 return error_mark_node
;
1939 return arm_builtin_decls
[code
];
1942 /* Errors in the source file can cause expand_expr to return const0_rtx
1943 where we expect a vector. To avoid crashing, use one of the vector
1944 clear instructions. */
1947 safe_vector_operand (rtx x
, machine_mode mode
)
1949 if (x
!= const0_rtx
)
1951 x
= gen_reg_rtx (mode
);
1953 emit_insn (gen_iwmmxt_clrdi (mode
== DImode
? x
1954 : gen_rtx_SUBREG (DImode
, x
, 0)));
1958 /* Function to expand ternary builtins. */
1960 arm_expand_ternop_builtin (enum insn_code icode
,
1961 tree exp
, rtx target
)
1964 tree arg0
= CALL_EXPR_ARG (exp
, 0);
1965 tree arg1
= CALL_EXPR_ARG (exp
, 1);
1966 tree arg2
= CALL_EXPR_ARG (exp
, 2);
1968 rtx op0
= expand_normal (arg0
);
1969 rtx op1
= expand_normal (arg1
);
1970 rtx op2
= expand_normal (arg2
);
1973 /* The sha1c, sha1p, sha1m crypto builtins require a different vec_select
1974 lane operand depending on endianness. */
1975 bool builtin_sha1cpm_p
= false;
1977 if (insn_data
[icode
].n_operands
== 5)
1979 gcc_assert (icode
== CODE_FOR_crypto_sha1c
1980 || icode
== CODE_FOR_crypto_sha1p
1981 || icode
== CODE_FOR_crypto_sha1m
);
1982 builtin_sha1cpm_p
= true;
1984 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
1985 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1986 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
1987 machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
1990 if (VECTOR_MODE_P (mode0
))
1991 op0
= safe_vector_operand (op0
, mode0
);
1992 if (VECTOR_MODE_P (mode1
))
1993 op1
= safe_vector_operand (op1
, mode1
);
1994 if (VECTOR_MODE_P (mode2
))
1995 op2
= safe_vector_operand (op2
, mode2
);
1998 || GET_MODE (target
) != tmode
1999 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2000 target
= gen_reg_rtx (tmode
);
2002 gcc_assert ((GET_MODE (op0
) == mode0
|| GET_MODE (op0
) == VOIDmode
)
2003 && (GET_MODE (op1
) == mode1
|| GET_MODE (op1
) == VOIDmode
)
2004 && (GET_MODE (op2
) == mode2
|| GET_MODE (op2
) == VOIDmode
));
2006 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2007 op0
= copy_to_mode_reg (mode0
, op0
);
2008 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2009 op1
= copy_to_mode_reg (mode1
, op1
);
2010 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2011 op2
= copy_to_mode_reg (mode2
, op2
);
2012 if (builtin_sha1cpm_p
)
2013 op3
= GEN_INT (TARGET_BIG_END
? 1 : 0);
2015 if (builtin_sha1cpm_p
)
2016 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, op3
);
2018 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2025 /* Subroutine of arm_expand_builtin to take care of binop insns. */
2028 arm_expand_binop_builtin (enum insn_code icode
,
2029 tree exp
, rtx target
)
2032 tree arg0
= CALL_EXPR_ARG (exp
, 0);
2033 tree arg1
= CALL_EXPR_ARG (exp
, 1);
2034 rtx op0
= expand_normal (arg0
);
2035 rtx op1
= expand_normal (arg1
);
2036 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2037 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2038 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2040 if (VECTOR_MODE_P (mode0
))
2041 op0
= safe_vector_operand (op0
, mode0
);
2042 if (VECTOR_MODE_P (mode1
))
2043 op1
= safe_vector_operand (op1
, mode1
);
2046 || GET_MODE (target
) != tmode
2047 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2048 target
= gen_reg_rtx (tmode
);
2050 gcc_assert ((GET_MODE (op0
) == mode0
|| GET_MODE (op0
) == VOIDmode
)
2051 && (GET_MODE (op1
) == mode1
|| GET_MODE (op1
) == VOIDmode
));
2053 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2054 op0
= copy_to_mode_reg (mode0
, op0
);
2055 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2056 op1
= copy_to_mode_reg (mode1
, op1
);
2058 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2065 /* Subroutine of arm_expand_builtin to take care of unop insns. */
2068 arm_expand_unop_builtin (enum insn_code icode
,
2069 tree exp
, rtx target
, int do_load
)
2072 tree arg0
= CALL_EXPR_ARG (exp
, 0);
2073 rtx op0
= expand_normal (arg0
);
2075 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2076 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2077 bool builtin_sha1h_p
= false;
2079 if (insn_data
[icode
].n_operands
== 3)
2081 gcc_assert (icode
== CODE_FOR_crypto_sha1h
);
2082 builtin_sha1h_p
= true;
2086 || GET_MODE (target
) != tmode
2087 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2088 target
= gen_reg_rtx (tmode
);
2090 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
2093 if (VECTOR_MODE_P (mode0
))
2094 op0
= safe_vector_operand (op0
, mode0
);
2096 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2097 op0
= copy_to_mode_reg (mode0
, op0
);
2099 if (builtin_sha1h_p
)
2100 op1
= GEN_INT (TARGET_BIG_END
? 1 : 0);
2102 if (builtin_sha1h_p
)
2103 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2105 pat
= GEN_FCN (icode
) (target
, op0
);
2113 ARG_BUILTIN_COPY_TO_REG
,
2114 ARG_BUILTIN_CONSTANT
,
2115 ARG_BUILTIN_LANE_INDEX
,
2116 ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX
,
2117 ARG_BUILTIN_NEON_MEMORY
,
2123 /* EXP is a pointer argument to a Neon load or store intrinsic. Derive
2124 and return an expression for the accessed memory.
2126 The intrinsic function operates on a block of registers that has
2127 mode REG_MODE. This block contains vectors of type TYPE_MODE. The
2128 function references the memory at EXP of type TYPE and in mode
2129 MEM_MODE; this mode may be BLKmode if no more suitable mode is
2133 neon_dereference_pointer (tree exp
, tree type
, machine_mode mem_mode
,
2134 machine_mode reg_mode
,
2135 machine_mode vector_mode
)
2137 HOST_WIDE_INT reg_size
, vector_size
, nvectors
, nelems
;
2138 tree elem_type
, upper_bound
, array_type
;
2140 /* Work out the size of the register block in bytes. */
2141 reg_size
= GET_MODE_SIZE (reg_mode
);
2143 /* Work out the size of each vector in bytes. */
2144 vector_size
= GET_MODE_SIZE (vector_mode
);
2146 /* Work out how many vectors there are. */
2147 gcc_assert (reg_size
% vector_size
== 0);
2148 nvectors
= reg_size
/ vector_size
;
2150 /* Work out the type of each element. */
2151 gcc_assert (POINTER_TYPE_P (type
));
2152 elem_type
= TREE_TYPE (type
);
2154 /* Work out how many elements are being loaded or stored.
2155 MEM_MODE == REG_MODE implies a one-to-one mapping between register
2156 and memory elements; anything else implies a lane load or store. */
2157 if (mem_mode
== reg_mode
)
2158 nelems
= vector_size
* nvectors
/ int_size_in_bytes (elem_type
);
2162 /* Create a type that describes the full access. */
2163 upper_bound
= build_int_cst (size_type_node
, nelems
- 1);
2164 array_type
= build_array_type (elem_type
, build_index_type (upper_bound
));
2166 /* Dereference EXP using that type. */
2167 return fold_build2 (MEM_REF
, array_type
, exp
,
2168 build_int_cst (build_pointer_type (array_type
), 0));
2171 /* Expand a builtin. */
2173 arm_expand_builtin_args (rtx target
, machine_mode map_mode
, int fcode
,
2174 int icode
, int have_retval
, tree exp
,
2178 tree arg
[SIMD_MAX_BUILTIN_ARGS
];
2179 rtx op
[SIMD_MAX_BUILTIN_ARGS
];
2180 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2181 machine_mode mode
[SIMD_MAX_BUILTIN_ARGS
];
2188 || GET_MODE (target
) != tmode
2189 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
)))
2190 target
= gen_reg_rtx (tmode
);
2192 formals
= TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls
[fcode
]));
2196 builtin_arg thisarg
= args
[argc
];
2198 if (thisarg
== ARG_BUILTIN_STOP
)
2202 int opno
= argc
+ have_retval
;
2203 arg
[argc
] = CALL_EXPR_ARG (exp
, argc
);
2204 mode
[argc
] = insn_data
[icode
].operand
[opno
].mode
;
2205 if (thisarg
== ARG_BUILTIN_NEON_MEMORY
)
2207 machine_mode other_mode
2208 = insn_data
[icode
].operand
[1 - opno
].mode
;
2209 arg
[argc
] = neon_dereference_pointer (arg
[argc
],
2210 TREE_VALUE (formals
),
2211 mode
[argc
], other_mode
,
2215 /* Use EXPAND_MEMORY for ARG_BUILTIN_MEMORY and
2216 ARG_BUILTIN_NEON_MEMORY to ensure a MEM_P be returned. */
2217 op
[argc
] = expand_expr (arg
[argc
], NULL_RTX
, VOIDmode
,
2218 ((thisarg
== ARG_BUILTIN_MEMORY
2219 || thisarg
== ARG_BUILTIN_NEON_MEMORY
)
2220 ? EXPAND_MEMORY
: EXPAND_NORMAL
));
2224 case ARG_BUILTIN_MEMORY
:
2225 case ARG_BUILTIN_COPY_TO_REG
:
2226 if (POINTER_TYPE_P (TREE_TYPE (arg
[argc
])))
2227 op
[argc
] = convert_memory_address (Pmode
, op
[argc
]);
2228 /*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */
2229 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
2230 (op
[argc
], mode
[argc
]))
2231 op
[argc
] = copy_to_mode_reg (mode
[argc
], op
[argc
]);
2234 case ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX
:
2235 gcc_assert (argc
> 1);
2236 if (CONST_INT_P (op
[argc
]))
2238 neon_lane_bounds (op
[argc
], 0,
2239 GET_MODE_NUNITS (map_mode
), exp
);
2240 /* Keep to GCC-vector-extension lane indices in the RTL. */
2242 GEN_INT (NEON_ENDIAN_LANE_N (map_mode
, INTVAL (op
[argc
])));
2246 case ARG_BUILTIN_LANE_INDEX
:
2247 /* Previous argument must be a vector, which this indexes. */
2248 gcc_assert (argc
> 0);
2249 if (CONST_INT_P (op
[argc
]))
2251 machine_mode vmode
= mode
[argc
- 1];
2252 neon_lane_bounds (op
[argc
], 0, GET_MODE_NUNITS (vmode
), exp
);
2254 /* If the lane index isn't a constant then the next
2257 case ARG_BUILTIN_CONSTANT
:
2259 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
2260 (op
[argc
], mode
[argc
]))
2262 error ("%Kargument %d must be a constant immediate",
2264 /* We have failed to expand the pattern, and are safely
2265 in to invalid code. But the mid-end will still try to
2266 build an assignment for this node while it expands,
2267 before stopping for the error, just pass it back
2268 TARGET to ensure a valid assignment. */
2273 case ARG_BUILTIN_NEON_MEMORY
:
2274 /* Check if expand failed. */
2275 if (op
[argc
] == const0_rtx
)
2277 gcc_assert (MEM_P (op
[argc
]));
2278 PUT_MODE (op
[argc
], mode
[argc
]);
2279 /* ??? arm_neon.h uses the same built-in functions for signed
2280 and unsigned accesses, casting where necessary. This isn't
2282 set_mem_alias_set (op
[argc
], 0);
2283 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
2284 (op
[argc
], mode
[argc
]))
2285 op
[argc
] = (replace_equiv_address
2287 copy_to_mode_reg (Pmode
, XEXP (op
[argc
], 0))));
2290 case ARG_BUILTIN_STOP
:
2302 pat
= GEN_FCN (icode
) (target
, op
[0]);
2306 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
2310 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
2314 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
2318 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3], op
[4]);
2322 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3], op
[4], op
[5]);
2332 pat
= GEN_FCN (icode
) (op
[0]);
2336 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
2340 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
2344 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
2348 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3], op
[4]);
2352 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3], op
[4], op
[5]);
2362 /* Check whether our current target implements the pattern chosen for this
2363 builtin and error out if not. */
2366 insn
= get_insns ();
2369 if (recog_memoized (insn
) < 0)
2370 error ("this builtin is not supported for this target");
2377 /* Expand a builtin. These builtins are "special" because they don't have
2378 symbolic constants defined per-instruction or per instruction-variant.
2379 Instead, the required info is looked up in the ARM_BUILTIN_DATA record that
2380 is passed into the function. */
2383 arm_expand_builtin_1 (int fcode
, tree exp
, rtx target
,
2384 arm_builtin_datum
*d
)
2386 enum insn_code icode
= d
->code
;
2387 builtin_arg args
[SIMD_MAX_BUILTIN_ARGS
+ 1];
2388 int num_args
= insn_data
[d
->code
].n_operands
;
2393 if (IN_RANGE (fcode
, ARM_BUILTIN_VFP_BASE
, ARM_BUILTIN_ACLE_BASE
- 1))
2396 is_void
= !!(d
->qualifiers
[0] & qualifier_void
);
2398 num_args
+= is_void
;
2400 for (k
= 1; k
< num_args
; k
++)
2402 /* We have four arrays of data, each indexed in a different fashion.
2403 qualifiers - element 0 always describes the function return type.
2404 operands - element 0 is either the operand for return value (if
2405 the function has a non-void return type) or the operand for the
2407 expr_args - element 0 always holds the first argument.
2408 args - element 0 is always used for the return type. */
2409 int qualifiers_k
= k
;
2410 int operands_k
= k
- is_void
;
2411 int expr_args_k
= k
- 1;
2413 if (d
->qualifiers
[qualifiers_k
] & qualifier_lane_index
)
2414 args
[k
] = ARG_BUILTIN_LANE_INDEX
;
2415 else if (d
->qualifiers
[qualifiers_k
] & qualifier_struct_load_store_lane_index
)
2416 args
[k
] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX
;
2417 else if (d
->qualifiers
[qualifiers_k
] & qualifier_immediate
)
2418 args
[k
] = ARG_BUILTIN_CONSTANT
;
2419 else if (d
->qualifiers
[qualifiers_k
] & qualifier_maybe_immediate
)
2422 = expand_normal (CALL_EXPR_ARG (exp
,
2424 /* Handle constants only if the predicate allows it. */
2425 bool op_const_int_p
=
2427 && (*insn_data
[icode
].operand
[operands_k
].predicate
)
2428 (arg
, insn_data
[icode
].operand
[operands_k
].mode
));
2429 args
[k
] = op_const_int_p
? ARG_BUILTIN_CONSTANT
: ARG_BUILTIN_COPY_TO_REG
;
2431 else if (d
->qualifiers
[qualifiers_k
] & qualifier_pointer
)
2434 args
[k
] = ARG_BUILTIN_NEON_MEMORY
;
2436 args
[k
] = ARG_BUILTIN_MEMORY
;
2439 args
[k
] = ARG_BUILTIN_COPY_TO_REG
;
2441 args
[k
] = ARG_BUILTIN_STOP
;
2443 /* The interface to arm_expand_builtin_args expects a 0 if
2444 the function is void, and a 1 if it is not. */
2445 return arm_expand_builtin_args
2446 (target
, d
->mode
, fcode
, icode
, !is_void
, exp
,
2450 /* Expand an ACLE builtin, i.e. those registered only if their respective
2451 target constraints are met. This check happens within
2452 arm_expand_builtin_args. */
2455 arm_expand_acle_builtin (int fcode
, tree exp
, rtx target
)
2458 arm_builtin_datum
*d
2459 = &acle_builtin_data
[fcode
- ARM_BUILTIN_ACLE_PATTERN_START
];
2461 return arm_expand_builtin_1 (fcode
, exp
, target
, d
);
2464 /* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds.
2465 Most of these are "special" because they don't have symbolic
2466 constants defined per-instruction or per instruction-variant. Instead, the
2467 required info is looked up in the table neon_builtin_data. */
2470 arm_expand_neon_builtin (int fcode
, tree exp
, rtx target
)
2472 if (fcode
>= ARM_BUILTIN_NEON_BASE
&& ! TARGET_NEON
)
2474 fatal_error (input_location
,
2475 "You must enable NEON instructions"
2476 " (e.g. -mfloat-abi=softfp -mfpu=neon)"
2477 " to use these intrinsics.");
2481 if (fcode
== ARM_BUILTIN_NEON_LANE_CHECK
)
2483 /* Builtin is only to check bounds of the lane passed to some intrinsics
2484 that are implemented with gcc vector extensions in arm_neon.h. */
2486 tree nlanes
= CALL_EXPR_ARG (exp
, 0);
2487 gcc_assert (TREE_CODE (nlanes
) == INTEGER_CST
);
2488 rtx lane_idx
= expand_normal (CALL_EXPR_ARG (exp
, 1));
2489 if (CONST_INT_P (lane_idx
))
2490 neon_lane_bounds (lane_idx
, 0, TREE_INT_CST_LOW (nlanes
), exp
);
2492 error ("%Klane index must be a constant immediate", exp
);
2493 /* Don't generate any RTL. */
2497 arm_builtin_datum
*d
2498 = &neon_builtin_data
[fcode
- ARM_BUILTIN_NEON_PATTERN_START
];
2500 return arm_expand_builtin_1 (fcode
, exp
, target
, d
);
2503 /* Expand a VFP builtin. These builtins are treated like
2504 neon builtins except that the data is looked up in table
2505 VFP_BUILTIN_DATA. */
2508 arm_expand_vfp_builtin (int fcode
, tree exp
, rtx target
)
2510 if (fcode
>= ARM_BUILTIN_VFP_BASE
&& ! TARGET_HARD_FLOAT
)
2512 fatal_error (input_location
,
2513 "You must enable VFP instructions"
2514 " to use these intrinsics.");
2518 arm_builtin_datum
*d
2519 = &vfp_builtin_data
[fcode
- ARM_BUILTIN_VFP_PATTERN_START
];
2521 return arm_expand_builtin_1 (fcode
, exp
, target
, d
);
2524 /* Expand an expression EXP that calls a built-in function,
2525 with result going to TARGET if that's convenient
2526 (and in mode MODE if that's convenient).
2527 SUBTARGET may be used as the target for computing one of EXP's operands.
2528 IGNORE is nonzero if the value is to be ignored. */
2531 arm_expand_builtin (tree exp
,
2533 rtx subtarget ATTRIBUTE_UNUSED
,
2534 machine_mode mode ATTRIBUTE_UNUSED
,
2535 int ignore ATTRIBUTE_UNUSED
)
2537 const struct builtin_description
* d
;
2538 enum insn_code icode
;
2539 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
2547 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
2558 if (fcode
>= ARM_BUILTIN_ACLE_BASE
)
2559 return arm_expand_acle_builtin (fcode
, exp
, target
);
2561 if (fcode
>= ARM_BUILTIN_NEON_BASE
)
2562 return arm_expand_neon_builtin (fcode
, exp
, target
);
2564 if (fcode
>= ARM_BUILTIN_VFP_BASE
)
2565 return arm_expand_vfp_builtin (fcode
, exp
, target
);
2567 /* Check in the context of the function making the call whether the
2568 builtin is supported. */
2569 if (fcode
>= ARM_BUILTIN_CRYPTO_BASE
2570 && (!TARGET_CRYPTO
|| !TARGET_HARD_FLOAT
))
2572 fatal_error (input_location
,
2573 "You must enable crypto instructions"
2574 " (e.g. include -mfloat-abi=softfp -mfpu=crypto-neon...)"
2575 " to use these intrinsics.");
2581 case ARM_BUILTIN_GET_FPSCR
:
2582 case ARM_BUILTIN_SET_FPSCR
:
2583 if (fcode
== ARM_BUILTIN_GET_FPSCR
)
2585 icode
= CODE_FOR_get_fpscr
;
2586 target
= gen_reg_rtx (SImode
);
2587 pat
= GEN_FCN (icode
) (target
);
2592 icode
= CODE_FOR_set_fpscr
;
2593 arg0
= CALL_EXPR_ARG (exp
, 0);
2594 op0
= expand_normal (arg0
);
2595 pat
= GEN_FCN (icode
) (force_reg (SImode
, op0
));
2600 case ARM_BUILTIN_CMSE_NONSECURE_CALLER
:
2601 target
= gen_reg_rtx (SImode
);
2602 op0
= arm_return_addr (0, NULL_RTX
);
2603 emit_insn (gen_andsi3 (target
, op0
, const1_rtx
));
2604 op1
= gen_rtx_EQ (SImode
, target
, const0_rtx
);
2605 emit_insn (gen_cstoresi4 (target
, op1
, target
, const0_rtx
));
2608 case ARM_BUILTIN_TEXTRMSB
:
2609 case ARM_BUILTIN_TEXTRMUB
:
2610 case ARM_BUILTIN_TEXTRMSH
:
2611 case ARM_BUILTIN_TEXTRMUH
:
2612 case ARM_BUILTIN_TEXTRMSW
:
2613 case ARM_BUILTIN_TEXTRMUW
:
2614 icode
= (fcode
== ARM_BUILTIN_TEXTRMSB
? CODE_FOR_iwmmxt_textrmsb
2615 : fcode
== ARM_BUILTIN_TEXTRMUB
? CODE_FOR_iwmmxt_textrmub
2616 : fcode
== ARM_BUILTIN_TEXTRMSH
? CODE_FOR_iwmmxt_textrmsh
2617 : fcode
== ARM_BUILTIN_TEXTRMUH
? CODE_FOR_iwmmxt_textrmuh
2618 : CODE_FOR_iwmmxt_textrmw
);
2620 arg0
= CALL_EXPR_ARG (exp
, 0);
2621 arg1
= CALL_EXPR_ARG (exp
, 1);
2622 op0
= expand_normal (arg0
);
2623 op1
= expand_normal (arg1
);
2624 tmode
= insn_data
[icode
].operand
[0].mode
;
2625 mode0
= insn_data
[icode
].operand
[1].mode
;
2626 mode1
= insn_data
[icode
].operand
[2].mode
;
2628 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2629 op0
= copy_to_mode_reg (mode0
, op0
);
2630 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2632 /* @@@ better error message */
2633 error ("selector must be an immediate");
2634 return gen_reg_rtx (tmode
);
2637 opint
= INTVAL (op1
);
2638 if (fcode
== ARM_BUILTIN_TEXTRMSB
|| fcode
== ARM_BUILTIN_TEXTRMUB
)
2640 if (opint
> 7 || opint
< 0)
2641 error ("the range of selector should be in 0 to 7");
2643 else if (fcode
== ARM_BUILTIN_TEXTRMSH
|| fcode
== ARM_BUILTIN_TEXTRMUH
)
2645 if (opint
> 3 || opint
< 0)
2646 error ("the range of selector should be in 0 to 3");
2648 else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */
2650 if (opint
> 1 || opint
< 0)
2651 error ("the range of selector should be in 0 to 1");
2655 || GET_MODE (target
) != tmode
2656 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2657 target
= gen_reg_rtx (tmode
);
2658 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2664 case ARM_BUILTIN_WALIGNI
:
2665 /* If op2 is immediate, call walighi, else call walighr. */
2666 arg0
= CALL_EXPR_ARG (exp
, 0);
2667 arg1
= CALL_EXPR_ARG (exp
, 1);
2668 arg2
= CALL_EXPR_ARG (exp
, 2);
2669 op0
= expand_normal (arg0
);
2670 op1
= expand_normal (arg1
);
2671 op2
= expand_normal (arg2
);
2672 if (CONST_INT_P (op2
))
2674 icode
= CODE_FOR_iwmmxt_waligni
;
2675 tmode
= insn_data
[icode
].operand
[0].mode
;
2676 mode0
= insn_data
[icode
].operand
[1].mode
;
2677 mode1
= insn_data
[icode
].operand
[2].mode
;
2678 mode2
= insn_data
[icode
].operand
[3].mode
;
2679 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2680 op0
= copy_to_mode_reg (mode0
, op0
);
2681 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2682 op1
= copy_to_mode_reg (mode1
, op1
);
2683 gcc_assert ((*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
));
2684 selector
= INTVAL (op2
);
2685 if (selector
> 7 || selector
< 0)
2686 error ("the range of selector should be in 0 to 7");
2690 icode
= CODE_FOR_iwmmxt_walignr
;
2691 tmode
= insn_data
[icode
].operand
[0].mode
;
2692 mode0
= insn_data
[icode
].operand
[1].mode
;
2693 mode1
= insn_data
[icode
].operand
[2].mode
;
2694 mode2
= insn_data
[icode
].operand
[3].mode
;
2695 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2696 op0
= copy_to_mode_reg (mode0
, op0
);
2697 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2698 op1
= copy_to_mode_reg (mode1
, op1
);
2699 if (!(*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2700 op2
= copy_to_mode_reg (mode2
, op2
);
2703 || GET_MODE (target
) != tmode
2704 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2705 target
= gen_reg_rtx (tmode
);
2706 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2712 case ARM_BUILTIN_TINSRB
:
2713 case ARM_BUILTIN_TINSRH
:
2714 case ARM_BUILTIN_TINSRW
:
2715 case ARM_BUILTIN_WMERGE
:
2716 icode
= (fcode
== ARM_BUILTIN_TINSRB
? CODE_FOR_iwmmxt_tinsrb
2717 : fcode
== ARM_BUILTIN_TINSRH
? CODE_FOR_iwmmxt_tinsrh
2718 : fcode
== ARM_BUILTIN_WMERGE
? CODE_FOR_iwmmxt_wmerge
2719 : CODE_FOR_iwmmxt_tinsrw
);
2720 arg0
= CALL_EXPR_ARG (exp
, 0);
2721 arg1
= CALL_EXPR_ARG (exp
, 1);
2722 arg2
= CALL_EXPR_ARG (exp
, 2);
2723 op0
= expand_normal (arg0
);
2724 op1
= expand_normal (arg1
);
2725 op2
= expand_normal (arg2
);
2726 tmode
= insn_data
[icode
].operand
[0].mode
;
2727 mode0
= insn_data
[icode
].operand
[1].mode
;
2728 mode1
= insn_data
[icode
].operand
[2].mode
;
2729 mode2
= insn_data
[icode
].operand
[3].mode
;
2731 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2732 op0
= copy_to_mode_reg (mode0
, op0
);
2733 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2734 op1
= copy_to_mode_reg (mode1
, op1
);
2735 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2737 error ("selector must be an immediate");
2740 if (icode
== CODE_FOR_iwmmxt_wmerge
)
2742 selector
= INTVAL (op2
);
2743 if (selector
> 7 || selector
< 0)
2744 error ("the range of selector should be in 0 to 7");
2746 if ((icode
== CODE_FOR_iwmmxt_tinsrb
)
2747 || (icode
== CODE_FOR_iwmmxt_tinsrh
)
2748 || (icode
== CODE_FOR_iwmmxt_tinsrw
))
2751 selector
= INTVAL (op2
);
2752 if (icode
== CODE_FOR_iwmmxt_tinsrb
&& (selector
< 0 || selector
> 7))
2753 error ("the range of selector should be in 0 to 7");
2754 else if (icode
== CODE_FOR_iwmmxt_tinsrh
&& (selector
< 0 ||selector
> 3))
2755 error ("the range of selector should be in 0 to 3");
2756 else if (icode
== CODE_FOR_iwmmxt_tinsrw
&& (selector
< 0 ||selector
> 1))
2757 error ("the range of selector should be in 0 to 1");
2759 op2
= GEN_INT (mask
);
2762 || GET_MODE (target
) != tmode
2763 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2764 target
= gen_reg_rtx (tmode
);
2765 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2771 case ARM_BUILTIN_SETWCGR0
:
2772 case ARM_BUILTIN_SETWCGR1
:
2773 case ARM_BUILTIN_SETWCGR2
:
2774 case ARM_BUILTIN_SETWCGR3
:
2775 icode
= (fcode
== ARM_BUILTIN_SETWCGR0
? CODE_FOR_iwmmxt_setwcgr0
2776 : fcode
== ARM_BUILTIN_SETWCGR1
? CODE_FOR_iwmmxt_setwcgr1
2777 : fcode
== ARM_BUILTIN_SETWCGR2
? CODE_FOR_iwmmxt_setwcgr2
2778 : CODE_FOR_iwmmxt_setwcgr3
);
2779 arg0
= CALL_EXPR_ARG (exp
, 0);
2780 op0
= expand_normal (arg0
);
2781 mode0
= insn_data
[icode
].operand
[0].mode
;
2782 if (!(*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
2783 op0
= copy_to_mode_reg (mode0
, op0
);
2784 pat
= GEN_FCN (icode
) (op0
);
2790 case ARM_BUILTIN_GETWCGR0
:
2791 case ARM_BUILTIN_GETWCGR1
:
2792 case ARM_BUILTIN_GETWCGR2
:
2793 case ARM_BUILTIN_GETWCGR3
:
2794 icode
= (fcode
== ARM_BUILTIN_GETWCGR0
? CODE_FOR_iwmmxt_getwcgr0
2795 : fcode
== ARM_BUILTIN_GETWCGR1
? CODE_FOR_iwmmxt_getwcgr1
2796 : fcode
== ARM_BUILTIN_GETWCGR2
? CODE_FOR_iwmmxt_getwcgr2
2797 : CODE_FOR_iwmmxt_getwcgr3
);
2798 tmode
= insn_data
[icode
].operand
[0].mode
;
2800 || GET_MODE (target
) != tmode
2801 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2802 target
= gen_reg_rtx (tmode
);
2803 pat
= GEN_FCN (icode
) (target
);
2809 case ARM_BUILTIN_WSHUFH
:
2810 icode
= CODE_FOR_iwmmxt_wshufh
;
2811 arg0
= CALL_EXPR_ARG (exp
, 0);
2812 arg1
= CALL_EXPR_ARG (exp
, 1);
2813 op0
= expand_normal (arg0
);
2814 op1
= expand_normal (arg1
);
2815 tmode
= insn_data
[icode
].operand
[0].mode
;
2816 mode1
= insn_data
[icode
].operand
[1].mode
;
2817 mode2
= insn_data
[icode
].operand
[2].mode
;
2819 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode1
))
2820 op0
= copy_to_mode_reg (mode1
, op0
);
2821 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode2
))
2823 error ("mask must be an immediate");
2826 selector
= INTVAL (op1
);
2827 if (selector
< 0 || selector
> 255)
2828 error ("the range of mask should be in 0 to 255");
2830 || GET_MODE (target
) != tmode
2831 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2832 target
= gen_reg_rtx (tmode
);
2833 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2839 case ARM_BUILTIN_WMADDS
:
2840 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds
, exp
, target
);
2841 case ARM_BUILTIN_WMADDSX
:
2842 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx
, exp
, target
);
2843 case ARM_BUILTIN_WMADDSN
:
2844 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn
, exp
, target
);
2845 case ARM_BUILTIN_WMADDU
:
2846 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu
, exp
, target
);
2847 case ARM_BUILTIN_WMADDUX
:
2848 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux
, exp
, target
);
2849 case ARM_BUILTIN_WMADDUN
:
2850 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun
, exp
, target
);
2851 case ARM_BUILTIN_WSADBZ
:
2852 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz
, exp
, target
);
2853 case ARM_BUILTIN_WSADHZ
:
2854 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz
, exp
, target
);
2856 /* Several three-argument builtins. */
2857 case ARM_BUILTIN_WMACS
:
2858 case ARM_BUILTIN_WMACU
:
2859 case ARM_BUILTIN_TMIA
:
2860 case ARM_BUILTIN_TMIAPH
:
2861 case ARM_BUILTIN_TMIATT
:
2862 case ARM_BUILTIN_TMIATB
:
2863 case ARM_BUILTIN_TMIABT
:
2864 case ARM_BUILTIN_TMIABB
:
2865 case ARM_BUILTIN_WQMIABB
:
2866 case ARM_BUILTIN_WQMIABT
:
2867 case ARM_BUILTIN_WQMIATB
:
2868 case ARM_BUILTIN_WQMIATT
:
2869 case ARM_BUILTIN_WQMIABBN
:
2870 case ARM_BUILTIN_WQMIABTN
:
2871 case ARM_BUILTIN_WQMIATBN
:
2872 case ARM_BUILTIN_WQMIATTN
:
2873 case ARM_BUILTIN_WMIABB
:
2874 case ARM_BUILTIN_WMIABT
:
2875 case ARM_BUILTIN_WMIATB
:
2876 case ARM_BUILTIN_WMIATT
:
2877 case ARM_BUILTIN_WMIABBN
:
2878 case ARM_BUILTIN_WMIABTN
:
2879 case ARM_BUILTIN_WMIATBN
:
2880 case ARM_BUILTIN_WMIATTN
:
2881 case ARM_BUILTIN_WMIAWBB
:
2882 case ARM_BUILTIN_WMIAWBT
:
2883 case ARM_BUILTIN_WMIAWTB
:
2884 case ARM_BUILTIN_WMIAWTT
:
2885 case ARM_BUILTIN_WMIAWBBN
:
2886 case ARM_BUILTIN_WMIAWBTN
:
2887 case ARM_BUILTIN_WMIAWTBN
:
2888 case ARM_BUILTIN_WMIAWTTN
:
2889 case ARM_BUILTIN_WSADB
:
2890 case ARM_BUILTIN_WSADH
:
2891 icode
= (fcode
== ARM_BUILTIN_WMACS
? CODE_FOR_iwmmxt_wmacs
2892 : fcode
== ARM_BUILTIN_WMACU
? CODE_FOR_iwmmxt_wmacu
2893 : fcode
== ARM_BUILTIN_TMIA
? CODE_FOR_iwmmxt_tmia
2894 : fcode
== ARM_BUILTIN_TMIAPH
? CODE_FOR_iwmmxt_tmiaph
2895 : fcode
== ARM_BUILTIN_TMIABB
? CODE_FOR_iwmmxt_tmiabb
2896 : fcode
== ARM_BUILTIN_TMIABT
? CODE_FOR_iwmmxt_tmiabt
2897 : fcode
== ARM_BUILTIN_TMIATB
? CODE_FOR_iwmmxt_tmiatb
2898 : fcode
== ARM_BUILTIN_TMIATT
? CODE_FOR_iwmmxt_tmiatt
2899 : fcode
== ARM_BUILTIN_WQMIABB
? CODE_FOR_iwmmxt_wqmiabb
2900 : fcode
== ARM_BUILTIN_WQMIABT
? CODE_FOR_iwmmxt_wqmiabt
2901 : fcode
== ARM_BUILTIN_WQMIATB
? CODE_FOR_iwmmxt_wqmiatb
2902 : fcode
== ARM_BUILTIN_WQMIATT
? CODE_FOR_iwmmxt_wqmiatt
2903 : fcode
== ARM_BUILTIN_WQMIABBN
? CODE_FOR_iwmmxt_wqmiabbn
2904 : fcode
== ARM_BUILTIN_WQMIABTN
? CODE_FOR_iwmmxt_wqmiabtn
2905 : fcode
== ARM_BUILTIN_WQMIATBN
? CODE_FOR_iwmmxt_wqmiatbn
2906 : fcode
== ARM_BUILTIN_WQMIATTN
? CODE_FOR_iwmmxt_wqmiattn
2907 : fcode
== ARM_BUILTIN_WMIABB
? CODE_FOR_iwmmxt_wmiabb
2908 : fcode
== ARM_BUILTIN_WMIABT
? CODE_FOR_iwmmxt_wmiabt
2909 : fcode
== ARM_BUILTIN_WMIATB
? CODE_FOR_iwmmxt_wmiatb
2910 : fcode
== ARM_BUILTIN_WMIATT
? CODE_FOR_iwmmxt_wmiatt
2911 : fcode
== ARM_BUILTIN_WMIABBN
? CODE_FOR_iwmmxt_wmiabbn
2912 : fcode
== ARM_BUILTIN_WMIABTN
? CODE_FOR_iwmmxt_wmiabtn
2913 : fcode
== ARM_BUILTIN_WMIATBN
? CODE_FOR_iwmmxt_wmiatbn
2914 : fcode
== ARM_BUILTIN_WMIATTN
? CODE_FOR_iwmmxt_wmiattn
2915 : fcode
== ARM_BUILTIN_WMIAWBB
? CODE_FOR_iwmmxt_wmiawbb
2916 : fcode
== ARM_BUILTIN_WMIAWBT
? CODE_FOR_iwmmxt_wmiawbt
2917 : fcode
== ARM_BUILTIN_WMIAWTB
? CODE_FOR_iwmmxt_wmiawtb
2918 : fcode
== ARM_BUILTIN_WMIAWTT
? CODE_FOR_iwmmxt_wmiawtt
2919 : fcode
== ARM_BUILTIN_WMIAWBBN
? CODE_FOR_iwmmxt_wmiawbbn
2920 : fcode
== ARM_BUILTIN_WMIAWBTN
? CODE_FOR_iwmmxt_wmiawbtn
2921 : fcode
== ARM_BUILTIN_WMIAWTBN
? CODE_FOR_iwmmxt_wmiawtbn
2922 : fcode
== ARM_BUILTIN_WMIAWTTN
? CODE_FOR_iwmmxt_wmiawttn
2923 : fcode
== ARM_BUILTIN_WSADB
? CODE_FOR_iwmmxt_wsadb
2924 : CODE_FOR_iwmmxt_wsadh
);
2925 arg0
= CALL_EXPR_ARG (exp
, 0);
2926 arg1
= CALL_EXPR_ARG (exp
, 1);
2927 arg2
= CALL_EXPR_ARG (exp
, 2);
2928 op0
= expand_normal (arg0
);
2929 op1
= expand_normal (arg1
);
2930 op2
= expand_normal (arg2
);
2931 tmode
= insn_data
[icode
].operand
[0].mode
;
2932 mode0
= insn_data
[icode
].operand
[1].mode
;
2933 mode1
= insn_data
[icode
].operand
[2].mode
;
2934 mode2
= insn_data
[icode
].operand
[3].mode
;
2936 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2937 op0
= copy_to_mode_reg (mode0
, op0
);
2938 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2939 op1
= copy_to_mode_reg (mode1
, op1
);
2940 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2941 op2
= copy_to_mode_reg (mode2
, op2
);
2943 || GET_MODE (target
) != tmode
2944 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2945 target
= gen_reg_rtx (tmode
);
2946 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2952 case ARM_BUILTIN_WZERO
:
2953 target
= gen_reg_rtx (DImode
);
2954 emit_insn (gen_iwmmxt_clrdi (target
));
2957 case ARM_BUILTIN_WSRLHI
:
2958 case ARM_BUILTIN_WSRLWI
:
2959 case ARM_BUILTIN_WSRLDI
:
2960 case ARM_BUILTIN_WSLLHI
:
2961 case ARM_BUILTIN_WSLLWI
:
2962 case ARM_BUILTIN_WSLLDI
:
2963 case ARM_BUILTIN_WSRAHI
:
2964 case ARM_BUILTIN_WSRAWI
:
2965 case ARM_BUILTIN_WSRADI
:
2966 case ARM_BUILTIN_WRORHI
:
2967 case ARM_BUILTIN_WRORWI
:
2968 case ARM_BUILTIN_WRORDI
:
2969 case ARM_BUILTIN_WSRLH
:
2970 case ARM_BUILTIN_WSRLW
:
2971 case ARM_BUILTIN_WSRLD
:
2972 case ARM_BUILTIN_WSLLH
:
2973 case ARM_BUILTIN_WSLLW
:
2974 case ARM_BUILTIN_WSLLD
:
2975 case ARM_BUILTIN_WSRAH
:
2976 case ARM_BUILTIN_WSRAW
:
2977 case ARM_BUILTIN_WSRAD
:
2978 case ARM_BUILTIN_WRORH
:
2979 case ARM_BUILTIN_WRORW
:
2980 case ARM_BUILTIN_WRORD
:
2981 icode
= (fcode
== ARM_BUILTIN_WSRLHI
? CODE_FOR_lshrv4hi3_iwmmxt
2982 : fcode
== ARM_BUILTIN_WSRLWI
? CODE_FOR_lshrv2si3_iwmmxt
2983 : fcode
== ARM_BUILTIN_WSRLDI
? CODE_FOR_lshrdi3_iwmmxt
2984 : fcode
== ARM_BUILTIN_WSLLHI
? CODE_FOR_ashlv4hi3_iwmmxt
2985 : fcode
== ARM_BUILTIN_WSLLWI
? CODE_FOR_ashlv2si3_iwmmxt
2986 : fcode
== ARM_BUILTIN_WSLLDI
? CODE_FOR_ashldi3_iwmmxt
2987 : fcode
== ARM_BUILTIN_WSRAHI
? CODE_FOR_ashrv4hi3_iwmmxt
2988 : fcode
== ARM_BUILTIN_WSRAWI
? CODE_FOR_ashrv2si3_iwmmxt
2989 : fcode
== ARM_BUILTIN_WSRADI
? CODE_FOR_ashrdi3_iwmmxt
2990 : fcode
== ARM_BUILTIN_WRORHI
? CODE_FOR_rorv4hi3
2991 : fcode
== ARM_BUILTIN_WRORWI
? CODE_FOR_rorv2si3
2992 : fcode
== ARM_BUILTIN_WRORDI
? CODE_FOR_rordi3
2993 : fcode
== ARM_BUILTIN_WSRLH
? CODE_FOR_lshrv4hi3_di
2994 : fcode
== ARM_BUILTIN_WSRLW
? CODE_FOR_lshrv2si3_di
2995 : fcode
== ARM_BUILTIN_WSRLD
? CODE_FOR_lshrdi3_di
2996 : fcode
== ARM_BUILTIN_WSLLH
? CODE_FOR_ashlv4hi3_di
2997 : fcode
== ARM_BUILTIN_WSLLW
? CODE_FOR_ashlv2si3_di
2998 : fcode
== ARM_BUILTIN_WSLLD
? CODE_FOR_ashldi3_di
2999 : fcode
== ARM_BUILTIN_WSRAH
? CODE_FOR_ashrv4hi3_di
3000 : fcode
== ARM_BUILTIN_WSRAW
? CODE_FOR_ashrv2si3_di
3001 : fcode
== ARM_BUILTIN_WSRAD
? CODE_FOR_ashrdi3_di
3002 : fcode
== ARM_BUILTIN_WRORH
? CODE_FOR_rorv4hi3_di
3003 : fcode
== ARM_BUILTIN_WRORW
? CODE_FOR_rorv2si3_di
3004 : fcode
== ARM_BUILTIN_WRORD
? CODE_FOR_rordi3_di
3005 : CODE_FOR_nothing
);
3006 arg1
= CALL_EXPR_ARG (exp
, 1);
3007 op1
= expand_normal (arg1
);
3008 if (GET_MODE (op1
) == VOIDmode
)
3011 if ((fcode
== ARM_BUILTIN_WRORHI
|| fcode
== ARM_BUILTIN_WRORWI
3012 || fcode
== ARM_BUILTIN_WRORH
|| fcode
== ARM_BUILTIN_WRORW
)
3013 && (imm
< 0 || imm
> 32))
3015 if (fcode
== ARM_BUILTIN_WRORHI
)
3016 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi16 in code.");
3017 else if (fcode
== ARM_BUILTIN_WRORWI
)
3018 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi32 in code.");
3019 else if (fcode
== ARM_BUILTIN_WRORH
)
3020 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi16 in code.");
3022 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi32 in code.");
3024 else if ((fcode
== ARM_BUILTIN_WRORDI
|| fcode
== ARM_BUILTIN_WRORD
)
3025 && (imm
< 0 || imm
> 64))
3027 if (fcode
== ARM_BUILTIN_WRORDI
)
3028 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_rori_si64 in code.");
3030 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_ror_si64 in code.");
3034 if (fcode
== ARM_BUILTIN_WSRLHI
)
3035 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi16 in code.");
3036 else if (fcode
== ARM_BUILTIN_WSRLWI
)
3037 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi32 in code.");
3038 else if (fcode
== ARM_BUILTIN_WSRLDI
)
3039 error ("the count should be no less than 0. please check the intrinsic _mm_srli_si64 in code.");
3040 else if (fcode
== ARM_BUILTIN_WSLLHI
)
3041 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi16 in code.");
3042 else if (fcode
== ARM_BUILTIN_WSLLWI
)
3043 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi32 in code.");
3044 else if (fcode
== ARM_BUILTIN_WSLLDI
)
3045 error ("the count should be no less than 0. please check the intrinsic _mm_slli_si64 in code.");
3046 else if (fcode
== ARM_BUILTIN_WSRAHI
)
3047 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi16 in code.");
3048 else if (fcode
== ARM_BUILTIN_WSRAWI
)
3049 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi32 in code.");
3050 else if (fcode
== ARM_BUILTIN_WSRADI
)
3051 error ("the count should be no less than 0. please check the intrinsic _mm_srai_si64 in code.");
3052 else if (fcode
== ARM_BUILTIN_WSRLH
)
3053 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi16 in code.");
3054 else if (fcode
== ARM_BUILTIN_WSRLW
)
3055 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi32 in code.");
3056 else if (fcode
== ARM_BUILTIN_WSRLD
)
3057 error ("the count should be no less than 0. please check the intrinsic _mm_srl_si64 in code.");
3058 else if (fcode
== ARM_BUILTIN_WSLLH
)
3059 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi16 in code.");
3060 else if (fcode
== ARM_BUILTIN_WSLLW
)
3061 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi32 in code.");
3062 else if (fcode
== ARM_BUILTIN_WSLLD
)
3063 error ("the count should be no less than 0. please check the intrinsic _mm_sll_si64 in code.");
3064 else if (fcode
== ARM_BUILTIN_WSRAH
)
3065 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi16 in code.");
3066 else if (fcode
== ARM_BUILTIN_WSRAW
)
3067 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi32 in code.");
3069 error ("the count should be no less than 0. please check the intrinsic _mm_sra_si64 in code.");
3072 return arm_expand_binop_builtin (icode
, exp
, target
);
3078 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
3079 if (d
->code
== (enum arm_builtins
) fcode
)
3080 return arm_expand_binop_builtin (d
->icode
, exp
, target
);
3082 for (i
= 0, d
= bdesc_1arg
; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
3083 if (d
->code
== (enum arm_builtins
) fcode
)
3084 return arm_expand_unop_builtin (d
->icode
, exp
, target
, 0);
3086 for (i
= 0, d
= bdesc_3arg
; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
3087 if (d
->code
== (enum arm_builtins
) fcode
)
3088 return arm_expand_ternop_builtin (d
->icode
, exp
, target
);
3090 /* @@@ Should really do something sensible here. */
3095 arm_builtin_vectorized_function (unsigned int fn
, tree type_out
, tree type_in
)
3097 machine_mode in_mode
, out_mode
;
3099 bool out_unsigned_p
= TYPE_UNSIGNED (type_out
);
3101 /* Can't provide any vectorized builtins when we can't use NEON. */
3105 if (TREE_CODE (type_out
) != VECTOR_TYPE
3106 || TREE_CODE (type_in
) != VECTOR_TYPE
)
3109 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3110 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
3111 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3112 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3114 /* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the
3115 decl of the vectorized builtin for the appropriate vector mode.
3116 NULL_TREE is returned if no such builtin is available. */
3117 #undef ARM_CHECK_BUILTIN_MODE
3118 #define ARM_CHECK_BUILTIN_MODE(C) \
3120 && flag_unsafe_math_optimizations \
3121 && ARM_CHECK_BUILTIN_MODE_1 (C))
3123 #undef ARM_CHECK_BUILTIN_MODE_1
3124 #define ARM_CHECK_BUILTIN_MODE_1(C) \
3125 (out_mode == SFmode && out_n == C \
3126 && in_mode == SFmode && in_n == C)
3128 #undef ARM_FIND_VRINT_VARIANT
3129 #define ARM_FIND_VRINT_VARIANT(N) \
3130 (ARM_CHECK_BUILTIN_MODE (2) \
3131 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \
3132 : (ARM_CHECK_BUILTIN_MODE (4) \
3133 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \
3139 return ARM_FIND_VRINT_VARIANT (vrintm
);
3141 return ARM_FIND_VRINT_VARIANT (vrintp
);
3143 return ARM_FIND_VRINT_VARIANT (vrintz
);
3145 return ARM_FIND_VRINT_VARIANT (vrinta
);
3146 #undef ARM_CHECK_BUILTIN_MODE_1
3147 #define ARM_CHECK_BUILTIN_MODE_1(C) \
3148 (out_mode == SImode && out_n == C \
3149 && in_mode == SFmode && in_n == C)
3151 #define ARM_FIND_VCVT_VARIANT(N) \
3152 (ARM_CHECK_BUILTIN_MODE (2) \
3153 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sfv2si, false) \
3154 : (ARM_CHECK_BUILTIN_MODE (4) \
3155 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sfv4si, false) \
3158 #define ARM_FIND_VCVTU_VARIANT(N) \
3159 (ARM_CHECK_BUILTIN_MODE (2) \
3160 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv2sfv2si, false) \
3161 : (ARM_CHECK_BUILTIN_MODE (4) \
3162 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \
3165 return (out_unsigned_p
3166 ? ARM_FIND_VCVTU_VARIANT (vcvta
)
3167 : ARM_FIND_VCVT_VARIANT (vcvta
));
3169 return (out_unsigned_p
3170 ? ARM_FIND_VCVTU_VARIANT (vcvtp
)
3171 : ARM_FIND_VCVT_VARIANT (vcvtp
));
3173 return (out_unsigned_p
3174 ? ARM_FIND_VCVTU_VARIANT (vcvtm
)
3175 : ARM_FIND_VCVT_VARIANT (vcvtm
));
3176 #undef ARM_CHECK_BUILTIN_MODE
3177 #define ARM_CHECK_BUILTIN_MODE(C, N) \
3178 (out_mode == N##mode && out_n == C \
3179 && in_mode == N##mode && in_n == C)
3180 case CFN_BUILT_IN_BSWAP16
:
3181 if (ARM_CHECK_BUILTIN_MODE (4, HI
))
3182 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi
, false);
3183 else if (ARM_CHECK_BUILTIN_MODE (8, HI
))
3184 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi
, false);
3187 case CFN_BUILT_IN_BSWAP32
:
3188 if (ARM_CHECK_BUILTIN_MODE (2, SI
))
3189 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si
, false);
3190 else if (ARM_CHECK_BUILTIN_MODE (4, SI
))
3191 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si
, false);
3194 case CFN_BUILT_IN_BSWAP64
:
3195 if (ARM_CHECK_BUILTIN_MODE (2, DI
))
3196 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di
, false);
3200 if (ARM_CHECK_BUILTIN_MODE (2, SF
))
3201 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf
, false);
3202 else if (ARM_CHECK_BUILTIN_MODE (4, SF
))
3203 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf
, false);
3212 #undef ARM_FIND_VCVT_VARIANT
3213 #undef ARM_FIND_VCVTU_VARIANT
3214 #undef ARM_CHECK_BUILTIN_MODE
3215 #undef ARM_FIND_VRINT_VARIANT
3218 arm_atomic_assign_expand_fenv (tree
*hold
, tree
*clear
, tree
*update
)
3220 const unsigned ARM_FE_INVALID
= 1;
3221 const unsigned ARM_FE_DIVBYZERO
= 2;
3222 const unsigned ARM_FE_OVERFLOW
= 4;
3223 const unsigned ARM_FE_UNDERFLOW
= 8;
3224 const unsigned ARM_FE_INEXACT
= 16;
3225 const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT
= (ARM_FE_INVALID
3230 const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT
= 8;
3231 tree fenv_var
, get_fpscr
, set_fpscr
, mask
, ld_fenv
, masked_fenv
;
3232 tree new_fenv_var
, reload_fenv
, restore_fnenv
;
3233 tree update_call
, atomic_feraiseexcept
, hold_fnclex
;
3235 if (!TARGET_HARD_FLOAT
)
3238 /* Generate the equivalent of :
3239 unsigned int fenv_var;
3240 fenv_var = __builtin_arm_get_fpscr ();
3242 unsigned int masked_fenv;
3243 masked_fenv = fenv_var & mask;
3245 __builtin_arm_set_fpscr (masked_fenv); */
3247 fenv_var
= create_tmp_var_raw (unsigned_type_node
);
3248 get_fpscr
= arm_builtin_decls
[ARM_BUILTIN_GET_FPSCR
];
3249 set_fpscr
= arm_builtin_decls
[ARM_BUILTIN_SET_FPSCR
];
3250 mask
= build_int_cst (unsigned_type_node
,
3251 ~((ARM_FE_ALL_EXCEPT
<< ARM_FE_EXCEPT_SHIFT
)
3252 | ARM_FE_ALL_EXCEPT
));
3253 ld_fenv
= build2 (MODIFY_EXPR
, unsigned_type_node
,
3254 fenv_var
, build_call_expr (get_fpscr
, 0));
3255 masked_fenv
= build2 (BIT_AND_EXPR
, unsigned_type_node
, fenv_var
, mask
);
3256 hold_fnclex
= build_call_expr (set_fpscr
, 1, masked_fenv
);
3257 *hold
= build2 (COMPOUND_EXPR
, void_type_node
,
3258 build2 (COMPOUND_EXPR
, void_type_node
, masked_fenv
, ld_fenv
),
3261 /* Store the value of masked_fenv to clear the exceptions:
3262 __builtin_arm_set_fpscr (masked_fenv); */
3264 *clear
= build_call_expr (set_fpscr
, 1, masked_fenv
);
3266 /* Generate the equivalent of :
3267 unsigned int new_fenv_var;
3268 new_fenv_var = __builtin_arm_get_fpscr ();
3270 __builtin_arm_set_fpscr (fenv_var);
3272 __atomic_feraiseexcept (new_fenv_var); */
3274 new_fenv_var
= create_tmp_var_raw (unsigned_type_node
);
3275 reload_fenv
= build2 (MODIFY_EXPR
, unsigned_type_node
, new_fenv_var
,
3276 build_call_expr (get_fpscr
, 0));
3277 restore_fnenv
= build_call_expr (set_fpscr
, 1, fenv_var
);
3278 atomic_feraiseexcept
= builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT
);
3279 update_call
= build_call_expr (atomic_feraiseexcept
, 1,
3280 fold_convert (integer_type_node
, new_fenv_var
));
3281 *update
= build2 (COMPOUND_EXPR
, void_type_node
,
3282 build2 (COMPOUND_EXPR
, void_type_node
,
3283 reload_fenv
, restore_fnenv
), update_call
);
3286 #include "gt-arm-builtins.h"