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,
83 qualifier_void_pointer
= 0x800,
84 /* A const void pointer. */
85 qualifier_const_void_pointer
= 0x802
88 /* The qualifier_internal allows generation of a unary builtin from
89 a pattern with a third pseudo-operand such as a match_scratch.
91 static enum arm_type_qualifiers
92 arm_unop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
93 = { qualifier_none
, qualifier_none
, qualifier_internal
};
94 #define UNOP_QUALIFIERS (arm_unop_qualifiers)
96 /* unsigned T (unsigned T). */
97 static enum arm_type_qualifiers
98 arm_bswap_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
99 = { qualifier_unsigned
, qualifier_unsigned
};
100 #define BSWAP_QUALIFIERS (arm_bswap_qualifiers)
102 /* T (T, T [maybe_immediate]). */
103 static enum arm_type_qualifiers
104 arm_binop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
105 = { qualifier_none
, qualifier_none
, qualifier_maybe_immediate
};
106 #define BINOP_QUALIFIERS (arm_binop_qualifiers)
109 static enum arm_type_qualifiers
110 arm_ternop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
111 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_none
};
112 #define TERNOP_QUALIFIERS (arm_ternop_qualifiers)
114 /* unsigned T (unsigned T, unsigned T, unsigned T). */
115 static enum arm_type_qualifiers
116 arm_unsigned_uternop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
117 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
118 qualifier_unsigned
};
119 #define UTERNOP_QUALIFIERS (arm_unsigned_uternop_qualifiers)
121 /* T (T, immediate). */
122 static enum arm_type_qualifiers
123 arm_binop_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
124 = { qualifier_none
, qualifier_none
, qualifier_immediate
};
125 #define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers)
127 /* T (T, lane index). */
128 static enum arm_type_qualifiers
129 arm_getlane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
130 = { qualifier_none
, qualifier_none
, qualifier_lane_index
};
131 #define GETLANE_QUALIFIERS (arm_getlane_qualifiers)
133 /* T (T, T, T, immediate). */
134 static enum arm_type_qualifiers
135 arm_mac_n_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
136 = { qualifier_none
, qualifier_none
, qualifier_none
,
137 qualifier_none
, qualifier_immediate
};
138 #define MAC_N_QUALIFIERS (arm_mac_n_qualifiers)
140 /* T (T, T, T, lane index). */
141 static enum arm_type_qualifiers
142 arm_mac_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
143 = { qualifier_none
, qualifier_none
, qualifier_none
,
144 qualifier_none
, qualifier_lane_index
};
145 #define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers)
147 /* unsigned T (unsigned T, unsigned T, unsigend T, lane index). */
148 static enum arm_type_qualifiers
149 arm_umac_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
150 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
151 qualifier_unsigned
, qualifier_lane_index
};
152 #define UMAC_LANE_QUALIFIERS (arm_umac_lane_qualifiers)
154 /* T (T, T, immediate). */
155 static enum arm_type_qualifiers
156 arm_ternop_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
157 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_immediate
};
158 #define TERNOP_IMM_QUALIFIERS (arm_ternop_imm_qualifiers)
160 /* T (T, T, lane index). */
161 static enum arm_type_qualifiers
162 arm_setlane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
163 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_lane_index
};
164 #define SETLANE_QUALIFIERS (arm_setlane_qualifiers)
167 static enum arm_type_qualifiers
168 arm_combine_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
169 = { qualifier_none
, qualifier_none
, qualifier_none
};
170 #define COMBINE_QUALIFIERS (arm_combine_qualifiers)
172 /* T ([T element type] *). */
173 static enum arm_type_qualifiers
174 arm_load1_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
175 = { qualifier_none
, qualifier_const_pointer_map_mode
};
176 #define LOAD1_QUALIFIERS (arm_load1_qualifiers)
178 /* T ([T element type] *, T, immediate). */
179 static enum arm_type_qualifiers
180 arm_load1_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
181 = { qualifier_none
, qualifier_const_pointer_map_mode
,
182 qualifier_none
, qualifier_struct_load_store_lane_index
};
183 #define LOAD1LANE_QUALIFIERS (arm_load1_lane_qualifiers)
185 /* unsigned T (unsigned T, unsigned T, unsigned T). */
186 static enum arm_type_qualifiers
187 arm_unsigned_binop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
188 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
189 qualifier_unsigned
};
190 #define UBINOP_QUALIFIERS (arm_unsigned_binop_qualifiers)
192 /* void (unsigned immediate, unsigned immediate, unsigned immediate,
193 unsigned immediate, unsigned immediate, unsigned immediate). */
194 static enum arm_type_qualifiers
195 arm_cdp_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
196 = { qualifier_void
, qualifier_unsigned_immediate
,
197 qualifier_unsigned_immediate
,
198 qualifier_unsigned_immediate
,
199 qualifier_unsigned_immediate
,
200 qualifier_unsigned_immediate
,
201 qualifier_unsigned_immediate
};
202 #define CDP_QUALIFIERS \
205 /* void (unsigned immediate, unsigned immediate, const void *). */
206 static enum arm_type_qualifiers
207 arm_ldc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
208 = { qualifier_void
, qualifier_unsigned_immediate
,
209 qualifier_unsigned_immediate
, qualifier_const_void_pointer
};
210 #define LDC_QUALIFIERS \
213 /* void (unsigned immediate, unsigned immediate, void *). */
214 static enum arm_type_qualifiers
215 arm_stc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
216 = { qualifier_void
, qualifier_unsigned_immediate
,
217 qualifier_unsigned_immediate
, qualifier_void_pointer
};
218 #define STC_QUALIFIERS \
221 /* void (unsigned immediate, unsigned immediate, T, unsigned immediate,
222 unsigned immediate, unsigned immediate). */
223 static enum arm_type_qualifiers
224 arm_mcr_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
225 = { qualifier_void
, qualifier_unsigned_immediate
,
226 qualifier_unsigned_immediate
, qualifier_none
,
227 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
,
228 qualifier_unsigned_immediate
};
229 #define MCR_QUALIFIERS \
232 /* T (unsigned immediate, unsigned immediate, unsigned immediate,
233 unsigned immediate, unsigned immediate). */
234 static enum arm_type_qualifiers
235 arm_mrc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
236 = { qualifier_none
, qualifier_unsigned_immediate
,
237 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
,
238 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
};
239 #define MRC_QUALIFIERS \
242 /* void (unsigned immediate, unsigned immediate, T, unsigned immediate). */
243 static enum arm_type_qualifiers
244 arm_mcrr_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
245 = { qualifier_void
, qualifier_unsigned_immediate
,
246 qualifier_unsigned_immediate
, qualifier_none
,
247 qualifier_unsigned_immediate
};
248 #define MCRR_QUALIFIERS \
249 (arm_mcrr_qualifiers)
251 /* T (unsigned immediate, unsigned immediate, unsigned immediate). */
252 static enum arm_type_qualifiers
253 arm_mrrc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
254 = { qualifier_none
, qualifier_unsigned_immediate
,
255 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
};
256 #define MRRC_QUALIFIERS \
257 (arm_mrrc_qualifiers)
259 /* The first argument (return type) of a store should be void type,
260 which we represent with qualifier_void. Their first operand will be
261 a DImode pointer to the location to store to, so we must use
262 qualifier_map_mode | qualifier_pointer to build a pointer to the
263 element type of the vector.
265 void ([T element type] *, T). */
266 static enum arm_type_qualifiers
267 arm_store1_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
268 = { qualifier_void
, qualifier_pointer_map_mode
, qualifier_none
};
269 #define STORE1_QUALIFIERS (arm_store1_qualifiers)
271 /* void ([T element type] *, T, immediate). */
272 static enum arm_type_qualifiers
273 arm_storestruct_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
274 = { qualifier_void
, qualifier_pointer_map_mode
,
275 qualifier_none
, qualifier_struct_load_store_lane_index
};
276 #define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers)
278 #define v8qi_UP E_V8QImode
279 #define v4hi_UP E_V4HImode
280 #define v4hf_UP E_V4HFmode
281 #define v2si_UP E_V2SImode
282 #define v2sf_UP E_V2SFmode
283 #define di_UP E_DImode
284 #define v16qi_UP E_V16QImode
285 #define v8hi_UP E_V8HImode
286 #define v8hf_UP E_V8HFmode
287 #define v4si_UP E_V4SImode
288 #define v4sf_UP E_V4SFmode
289 #define v2di_UP E_V2DImode
290 #define ti_UP E_TImode
291 #define ei_UP E_EImode
292 #define oi_UP E_OImode
293 #define hf_UP E_HFmode
294 #define si_UP E_SImode
295 #define void_UP E_VOIDmode
302 const enum insn_code code
;
304 enum arm_type_qualifiers
*qualifiers
;
307 #define CF(N,X) CODE_FOR_neon_##N##X
309 #define VAR1(T, N, A) \
310 {#N #A, UP (A), CF (N, A), 0, T##_QUALIFIERS},
311 #define VAR2(T, N, A, B) \
314 #define VAR3(T, N, A, B, C) \
317 #define VAR4(T, N, A, B, C, D) \
318 VAR3 (T, N, A, B, C) \
320 #define VAR5(T, N, A, B, C, D, E) \
321 VAR4 (T, N, A, B, C, D) \
323 #define VAR6(T, N, A, B, C, D, E, F) \
324 VAR5 (T, N, A, B, C, D, E) \
326 #define VAR7(T, N, A, B, C, D, E, F, G) \
327 VAR6 (T, N, A, B, C, D, E, F) \
329 #define VAR8(T, N, A, B, C, D, E, F, G, H) \
330 VAR7 (T, N, A, B, C, D, E, F, G) \
332 #define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
333 VAR8 (T, N, A, B, C, D, E, F, G, H) \
335 #define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
336 VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
338 #define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \
339 VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \
341 #define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
342 VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
345 /* The builtin data can be found in arm_neon_builtins.def, arm_vfp_builtins.def
346 and arm_acle_builtins.def. The entries in arm_neon_builtins.def require
347 TARGET_NEON to be true. The feature tests are checked when the builtins are
350 The mode entries in the following table correspond to the "key" type of the
351 instruction variant, i.e. equivalent to that which would be specified after
352 the assembler mnemonic for neon instructions, which usually refers to the
353 last vector operand. The modes listed per instruction should be the same as
354 those defined for that instruction's pattern, for instance in neon.md. */
356 static arm_builtin_datum vfp_builtin_data
[] =
358 #include "arm_vfp_builtins.def"
361 static arm_builtin_datum neon_builtin_data
[] =
363 #include "arm_neon_builtins.def"
368 #define VAR1(T, N, A) \
369 {#N, UP (A), CODE_FOR_##N, 0, T##_QUALIFIERS},
371 static arm_builtin_datum acle_builtin_data
[] =
373 #include "arm_acle_builtins.def"
378 #define VAR1(T, N, X) \
379 ARM_BUILTIN_NEON_##N##X,
383 ARM_BUILTIN_GETWCGR0
,
384 ARM_BUILTIN_GETWCGR1
,
385 ARM_BUILTIN_GETWCGR2
,
386 ARM_BUILTIN_GETWCGR3
,
388 ARM_BUILTIN_SETWCGR0
,
389 ARM_BUILTIN_SETWCGR1
,
390 ARM_BUILTIN_SETWCGR2
,
391 ARM_BUILTIN_SETWCGR3
,
415 ARM_BUILTIN_WALIGNR0
,
416 ARM_BUILTIN_WALIGNR1
,
417 ARM_BUILTIN_WALIGNR2
,
418 ARM_BUILTIN_WALIGNR3
,
427 ARM_BUILTIN_TMOVMSKB
,
428 ARM_BUILTIN_TMOVMSKH
,
429 ARM_BUILTIN_TMOVMSKW
,
438 ARM_BUILTIN_WPACKHSS
,
439 ARM_BUILTIN_WPACKWSS
,
440 ARM_BUILTIN_WPACKDSS
,
441 ARM_BUILTIN_WPACKHUS
,
442 ARM_BUILTIN_WPACKWUS
,
443 ARM_BUILTIN_WPACKDUS
,
472 ARM_BUILTIN_WCMPGTUB
,
473 ARM_BUILTIN_WCMPGTUH
,
474 ARM_BUILTIN_WCMPGTUW
,
475 ARM_BUILTIN_WCMPGTSB
,
476 ARM_BUILTIN_WCMPGTSH
,
477 ARM_BUILTIN_WCMPGTSW
,
479 ARM_BUILTIN_TEXTRMSB
,
480 ARM_BUILTIN_TEXTRMSH
,
481 ARM_BUILTIN_TEXTRMSW
,
482 ARM_BUILTIN_TEXTRMUB
,
483 ARM_BUILTIN_TEXTRMUH
,
484 ARM_BUILTIN_TEXTRMUW
,
534 ARM_BUILTIN_WUNPCKIHB
,
535 ARM_BUILTIN_WUNPCKIHH
,
536 ARM_BUILTIN_WUNPCKIHW
,
537 ARM_BUILTIN_WUNPCKILB
,
538 ARM_BUILTIN_WUNPCKILH
,
539 ARM_BUILTIN_WUNPCKILW
,
541 ARM_BUILTIN_WUNPCKEHSB
,
542 ARM_BUILTIN_WUNPCKEHSH
,
543 ARM_BUILTIN_WUNPCKEHSW
,
544 ARM_BUILTIN_WUNPCKEHUB
,
545 ARM_BUILTIN_WUNPCKEHUH
,
546 ARM_BUILTIN_WUNPCKEHUW
,
547 ARM_BUILTIN_WUNPCKELSB
,
548 ARM_BUILTIN_WUNPCKELSH
,
549 ARM_BUILTIN_WUNPCKELSW
,
550 ARM_BUILTIN_WUNPCKELUB
,
551 ARM_BUILTIN_WUNPCKELUH
,
552 ARM_BUILTIN_WUNPCKELUW
,
558 ARM_BUILTIN_WADDSUBHX
,
559 ARM_BUILTIN_WSUBADDHX
,
561 ARM_BUILTIN_WABSDIFFB
,
562 ARM_BUILTIN_WABSDIFFH
,
563 ARM_BUILTIN_WABSDIFFW
,
580 ARM_BUILTIN_WMULWSMR
,
581 ARM_BUILTIN_WMULWUMR
,
592 ARM_BUILTIN_WQMULWMR
,
594 ARM_BUILTIN_WADDBHUSM
,
595 ARM_BUILTIN_WADDBHUSL
,
602 ARM_BUILTIN_WQMIABBN
,
603 ARM_BUILTIN_WQMIABTN
,
604 ARM_BUILTIN_WQMIATBN
,
605 ARM_BUILTIN_WQMIATTN
,
622 ARM_BUILTIN_WMIAWBBN
,
623 ARM_BUILTIN_WMIAWBTN
,
624 ARM_BUILTIN_WMIAWTBN
,
625 ARM_BUILTIN_WMIAWTTN
,
629 ARM_BUILTIN_GET_FPSCR
,
630 ARM_BUILTIN_SET_FPSCR
,
632 ARM_BUILTIN_CMSE_NONSECURE_CALLER
,
638 #define CRYPTO1(L, U, M1, M2) \
639 ARM_BUILTIN_CRYPTO_##U,
640 #define CRYPTO2(L, U, M1, M2, M3) \
641 ARM_BUILTIN_CRYPTO_##U,
642 #define CRYPTO3(L, U, M1, M2, M3, M4) \
643 ARM_BUILTIN_CRYPTO_##U,
645 ARM_BUILTIN_CRYPTO_BASE
,
647 #include "crypto.def"
653 ARM_BUILTIN_VFP_BASE
,
655 #include "arm_vfp_builtins.def"
657 ARM_BUILTIN_NEON_BASE
,
658 ARM_BUILTIN_NEON_LANE_CHECK
= ARM_BUILTIN_NEON_BASE
,
660 #include "arm_neon_builtins.def"
663 #define VAR1(T, N, X) \
666 ARM_BUILTIN_ACLE_BASE
,
668 #include "arm_acle_builtins.def"
673 #define ARM_BUILTIN_VFP_PATTERN_START \
674 (ARM_BUILTIN_VFP_BASE + 1)
676 #define ARM_BUILTIN_NEON_PATTERN_START \
677 (ARM_BUILTIN_NEON_BASE + 1)
679 #define ARM_BUILTIN_ACLE_PATTERN_START \
680 (ARM_BUILTIN_ACLE_BASE + 1)
694 static GTY(()) tree arm_builtin_decls
[ARM_BUILTIN_MAX
];
696 #define NUM_DREG_TYPES 5
697 #define NUM_QREG_TYPES 6
699 /* Internal scalar builtin types. These types are used to support
700 neon intrinsic builtins. They are _not_ user-visible types. Therefore
701 the mangling for these types are implementation defined. */
702 const char *arm_scalar_builtin_types
[] = {
710 "__builtin_neon_uqi",
711 "__builtin_neon_uhi",
712 "__builtin_neon_usi",
713 "__builtin_neon_udi",
721 #define ENTRY(E, M, Q, S, T, G) E,
724 #include "arm-simd-builtin-types.def"
729 struct arm_simd_type_info
731 enum arm_simd_type type
;
733 /* Internal type name. */
736 /* Internal type name(mangled). The mangled names conform to the
737 AAPCS (see "Procedure Call Standard for the ARM Architecture",
738 Appendix A). To qualify for emission with the mangled names defined in
739 that document, a vector type must not only be of the correct mode but also
740 be of the correct internal Neon vector type (e.g. __simd64_int8_t);
741 these types are registered by arm_init_simd_builtin_types (). In other
742 words, vector types defined in other ways e.g. via vector_size attribute
743 will get default mangled names. */
752 /* Machine mode the internal type maps to. */
756 enum arm_type_qualifiers q
;
759 #define ENTRY(E, M, Q, S, T, G) \
761 "__simd" #S "_" #T "_t", \
762 #G "__simd" #S "_" #T "_t", \
763 NULL_TREE, NULL_TREE, M##mode, qualifier_##Q},
764 static struct arm_simd_type_info arm_simd_types
[] = {
765 #include "arm-simd-builtin-types.def"
769 /* The user-visible __fp16 type. */
770 tree arm_fp16_type_node
= NULL_TREE
;
771 static tree arm_simd_intOI_type_node
= NULL_TREE
;
772 static tree arm_simd_intEI_type_node
= NULL_TREE
;
773 static tree arm_simd_intCI_type_node
= NULL_TREE
;
774 static tree arm_simd_intXI_type_node
= NULL_TREE
;
775 static tree arm_simd_polyQI_type_node
= NULL_TREE
;
776 static tree arm_simd_polyHI_type_node
= NULL_TREE
;
777 static tree arm_simd_polyDI_type_node
= NULL_TREE
;
778 static tree arm_simd_polyTI_type_node
= NULL_TREE
;
781 arm_mangle_builtin_scalar_type (const_tree type
)
785 while (arm_scalar_builtin_types
[i
] != NULL
)
787 const char *name
= arm_scalar_builtin_types
[i
];
789 if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
790 && DECL_NAME (TYPE_NAME (type
))
791 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
))), name
))
792 return arm_scalar_builtin_types
[i
];
799 arm_mangle_builtin_vector_type (const_tree type
)
802 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
804 for (i
= 0; i
< nelts
; i
++)
805 if (arm_simd_types
[i
].mode
== TYPE_MODE (type
)
807 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
808 && DECL_NAME (TYPE_NAME (type
))
810 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
))),
811 arm_simd_types
[i
].name
))
812 return arm_simd_types
[i
].mangle
;
818 arm_mangle_builtin_type (const_tree type
)
821 /* Walk through all the AArch64 builtins types tables to filter out the
823 if ((mangle
= arm_mangle_builtin_vector_type (type
))
824 || (mangle
= arm_mangle_builtin_scalar_type (type
)))
831 arm_simd_builtin_std_type (machine_mode mode
,
832 enum arm_type_qualifiers q
)
834 #define QUAL_TYPE(M) \
835 ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node);
839 return QUAL_TYPE (QI
);
841 return QUAL_TYPE (HI
);
843 return QUAL_TYPE (SI
);
845 return QUAL_TYPE (DI
);
847 return QUAL_TYPE (TI
);
849 return arm_simd_intOI_type_node
;
851 return arm_simd_intEI_type_node
;
853 return arm_simd_intCI_type_node
;
855 return arm_simd_intXI_type_node
;
857 return arm_fp16_type_node
;
859 return float_type_node
;
861 return double_type_node
;
869 arm_lookup_simd_builtin_type (machine_mode mode
,
870 enum arm_type_qualifiers q
)
873 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
875 /* Non-poly scalar modes map to standard types not in the table. */
876 if (q
!= qualifier_poly
&& !VECTOR_MODE_P (mode
))
877 return arm_simd_builtin_std_type (mode
, q
);
879 for (i
= 0; i
< nelts
; i
++)
880 if (arm_simd_types
[i
].mode
== mode
881 && arm_simd_types
[i
].q
== q
)
882 return arm_simd_types
[i
].itype
;
884 /* Note that we won't have caught the underlying type for poly64x2_t
885 in the above table. This gets default mangling. */
891 arm_simd_builtin_type (machine_mode mode
, bool unsigned_p
, bool poly_p
)
894 return arm_lookup_simd_builtin_type (mode
, qualifier_poly
);
896 return arm_lookup_simd_builtin_type (mode
, qualifier_unsigned
);
898 return arm_lookup_simd_builtin_type (mode
, qualifier_none
);
902 arm_init_simd_builtin_types (void)
905 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
908 /* Poly types are a world of their own. In order to maintain legacy
909 ABI, they get initialized using the old interface, and don't get
910 an entry in our mangling table, consequently, they get default
911 mangling. As a further gotcha, poly8_t and poly16_t are signed
912 types, poly64_t and poly128_t are unsigned types. */
913 arm_simd_polyQI_type_node
914 = build_distinct_type_copy (intQI_type_node
);
915 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyQI_type_node
,
916 "__builtin_neon_poly8");
917 arm_simd_polyHI_type_node
918 = build_distinct_type_copy (intHI_type_node
);
919 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyHI_type_node
,
920 "__builtin_neon_poly16");
921 arm_simd_polyDI_type_node
922 = build_distinct_type_copy (unsigned_intDI_type_node
);
923 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyDI_type_node
,
924 "__builtin_neon_poly64");
925 arm_simd_polyTI_type_node
926 = build_distinct_type_copy (unsigned_intTI_type_node
);
927 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyTI_type_node
,
928 "__builtin_neon_poly128");
930 /* Init all the element types built by the front-end. */
931 arm_simd_types
[Int8x8_t
].eltype
= intQI_type_node
;
932 arm_simd_types
[Int8x16_t
].eltype
= intQI_type_node
;
933 arm_simd_types
[Int16x4_t
].eltype
= intHI_type_node
;
934 arm_simd_types
[Int16x8_t
].eltype
= intHI_type_node
;
935 arm_simd_types
[Int32x2_t
].eltype
= intSI_type_node
;
936 arm_simd_types
[Int32x4_t
].eltype
= intSI_type_node
;
937 arm_simd_types
[Int64x2_t
].eltype
= intDI_type_node
;
938 arm_simd_types
[Uint8x8_t
].eltype
= unsigned_intQI_type_node
;
939 arm_simd_types
[Uint8x16_t
].eltype
= unsigned_intQI_type_node
;
940 arm_simd_types
[Uint16x4_t
].eltype
= unsigned_intHI_type_node
;
941 arm_simd_types
[Uint16x8_t
].eltype
= unsigned_intHI_type_node
;
942 arm_simd_types
[Uint32x2_t
].eltype
= unsigned_intSI_type_node
;
943 arm_simd_types
[Uint32x4_t
].eltype
= unsigned_intSI_type_node
;
944 arm_simd_types
[Uint64x2_t
].eltype
= unsigned_intDI_type_node
;
946 /* Init poly vector element types with scalar poly types. */
947 arm_simd_types
[Poly8x8_t
].eltype
= arm_simd_polyQI_type_node
;
948 arm_simd_types
[Poly8x16_t
].eltype
= arm_simd_polyQI_type_node
;
949 arm_simd_types
[Poly16x4_t
].eltype
= arm_simd_polyHI_type_node
;
950 arm_simd_types
[Poly16x8_t
].eltype
= arm_simd_polyHI_type_node
;
951 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
954 /* Continue with standard types. */
955 /* The __builtin_simd{64,128}_float16 types are kept private unless
956 we have a scalar __fp16 type. */
957 arm_simd_types
[Float16x4_t
].eltype
= arm_fp16_type_node
;
958 arm_simd_types
[Float16x8_t
].eltype
= arm_fp16_type_node
;
959 arm_simd_types
[Float32x2_t
].eltype
= float_type_node
;
960 arm_simd_types
[Float32x4_t
].eltype
= float_type_node
;
962 for (i
= 0; i
< nelts
; i
++)
964 tree eltype
= arm_simd_types
[i
].eltype
;
965 machine_mode mode
= arm_simd_types
[i
].mode
;
967 if (arm_simd_types
[i
].itype
== NULL
)
968 arm_simd_types
[i
].itype
=
969 build_distinct_type_copy
970 (build_vector_type (eltype
, GET_MODE_NUNITS (mode
)));
972 tdecl
= add_builtin_type (arm_simd_types
[i
].name
,
973 arm_simd_types
[i
].itype
);
974 TYPE_NAME (arm_simd_types
[i
].itype
) = tdecl
;
975 SET_TYPE_STRUCTURAL_EQUALITY (arm_simd_types
[i
].itype
);
978 #define AARCH_BUILD_SIGNED_TYPE(mode) \
979 make_signed_type (GET_MODE_PRECISION (mode));
980 arm_simd_intOI_type_node
= AARCH_BUILD_SIGNED_TYPE (OImode
);
981 arm_simd_intEI_type_node
= AARCH_BUILD_SIGNED_TYPE (EImode
);
982 arm_simd_intCI_type_node
= AARCH_BUILD_SIGNED_TYPE (CImode
);
983 arm_simd_intXI_type_node
= AARCH_BUILD_SIGNED_TYPE (XImode
);
984 #undef AARCH_BUILD_SIGNED_TYPE
986 tdecl
= add_builtin_type
987 ("__builtin_neon_ei" , arm_simd_intEI_type_node
);
988 TYPE_NAME (arm_simd_intEI_type_node
) = tdecl
;
989 tdecl
= add_builtin_type
990 ("__builtin_neon_oi" , arm_simd_intOI_type_node
);
991 TYPE_NAME (arm_simd_intOI_type_node
) = tdecl
;
992 tdecl
= add_builtin_type
993 ("__builtin_neon_ci" , arm_simd_intCI_type_node
);
994 TYPE_NAME (arm_simd_intCI_type_node
) = tdecl
;
995 tdecl
= add_builtin_type
996 ("__builtin_neon_xi" , arm_simd_intXI_type_node
);
997 TYPE_NAME (arm_simd_intXI_type_node
) = tdecl
;
1001 arm_init_simd_builtin_scalar_types (void)
1003 /* Define typedefs for all the standard scalar types. */
1004 (*lang_hooks
.types
.register_builtin_type
) (intQI_type_node
,
1005 "__builtin_neon_qi");
1006 (*lang_hooks
.types
.register_builtin_type
) (intHI_type_node
,
1007 "__builtin_neon_hi");
1008 (*lang_hooks
.types
.register_builtin_type
) (intSI_type_node
,
1009 "__builtin_neon_si");
1010 (*lang_hooks
.types
.register_builtin_type
) (float_type_node
,
1011 "__builtin_neon_sf");
1012 (*lang_hooks
.types
.register_builtin_type
) (intDI_type_node
,
1013 "__builtin_neon_di");
1014 (*lang_hooks
.types
.register_builtin_type
) (double_type_node
,
1015 "__builtin_neon_df");
1016 (*lang_hooks
.types
.register_builtin_type
) (intTI_type_node
,
1017 "__builtin_neon_ti");
1019 /* Unsigned integer types for various mode sizes. */
1020 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intQI_type_node
,
1021 "__builtin_neon_uqi");
1022 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intHI_type_node
,
1023 "__builtin_neon_uhi");
1024 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intSI_type_node
,
1025 "__builtin_neon_usi");
1026 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intDI_type_node
,
1027 "__builtin_neon_udi");
1028 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intTI_type_node
,
1029 "__builtin_neon_uti");
1032 /* Set up a builtin. It will use information stored in the argument struct D to
1033 derive the builtin's type signature and name. It will append the name in D
1034 to the PREFIX passed and use these to create a builtin declaration that is
1035 then stored in 'arm_builtin_decls' under index FCODE. This FCODE is also
1036 written back to D for future use. */
1039 arm_init_builtin (unsigned int fcode
, arm_builtin_datum
*d
,
1040 const char * prefix
)
1042 bool print_type_signature_p
= false;
1043 char type_signature
[SIMD_MAX_BUILTIN_ARGS
] = { 0 };
1050 /* We must track two variables here. op_num is
1051 the operand number as in the RTL pattern. This is
1052 required to access the mode (e.g. V4SF mode) of the
1053 argument, from which the base type can be derived.
1054 arg_num is an index in to the qualifiers data, which
1055 gives qualifiers to the type (e.g. const unsigned).
1056 The reason these two variables may differ by one is the
1057 void return type. While all return types take the 0th entry
1058 in the qualifiers array, there is no operand for them in the
1060 int op_num
= insn_data
[d
->code
].n_operands
- 1;
1061 int arg_num
= d
->qualifiers
[0] & qualifier_void
1064 tree return_type
= void_type_node
, args
= void_list_node
;
1067 /* Build a function type directly from the insn_data for this
1068 builtin. The build_function_type () function takes care of
1069 removing duplicates for us. */
1070 for (; op_num
>= 0; arg_num
--, op_num
--)
1072 machine_mode op_mode
= insn_data
[d
->code
].operand
[op_num
].mode
;
1073 enum arm_type_qualifiers qualifiers
= d
->qualifiers
[arg_num
];
1075 if (qualifiers
& qualifier_unsigned
)
1077 type_signature
[arg_num
] = 'u';
1078 print_type_signature_p
= true;
1080 else if (qualifiers
& qualifier_poly
)
1082 type_signature
[arg_num
] = 'p';
1083 print_type_signature_p
= true;
1086 type_signature
[arg_num
] = 's';
1088 /* Skip an internal operand for vget_{low, high}. */
1089 if (qualifiers
& qualifier_internal
)
1092 /* Some builtins have different user-facing types
1093 for certain arguments, encoded in d->mode. */
1094 if (qualifiers
& qualifier_map_mode
)
1097 /* For pointers, we want a pointer to the basic type
1099 if (qualifiers
& qualifier_pointer
&& VECTOR_MODE_P (op_mode
))
1100 op_mode
= GET_MODE_INNER (op_mode
);
1102 /* For void pointers we already have nodes constructed by the midend. */
1103 if (qualifiers
& qualifier_void_pointer
)
1104 eltype
= qualifiers
& qualifier_const
1105 ? const_ptr_type_node
: ptr_type_node
;
1109 = arm_simd_builtin_type (op_mode
,
1110 (qualifiers
& qualifier_unsigned
) != 0,
1111 (qualifiers
& qualifier_poly
) != 0);
1112 gcc_assert (eltype
!= NULL
);
1114 /* Add qualifiers. */
1115 if (qualifiers
& qualifier_const
)
1116 eltype
= build_qualified_type (eltype
, TYPE_QUAL_CONST
);
1118 if (qualifiers
& qualifier_pointer
)
1119 eltype
= build_pointer_type (eltype
);
1121 /* If we have reached arg_num == 0, we are at a non-void
1122 return type. Otherwise, we are still processing
1125 return_type
= eltype
;
1127 args
= tree_cons (NULL_TREE
, eltype
, args
);
1130 ftype
= build_function_type (return_type
, args
);
1132 gcc_assert (ftype
!= NULL
);
1134 if (print_type_signature_p
1135 && IN_RANGE (fcode
, ARM_BUILTIN_VFP_BASE
, ARM_BUILTIN_ACLE_BASE
- 1))
1136 snprintf (namebuf
, sizeof (namebuf
), "%s_%s_%s",
1137 prefix
, d
->name
, type_signature
);
1139 snprintf (namebuf
, sizeof (namebuf
), "%s_%s",
1142 fndecl
= add_builtin_function (namebuf
, ftype
, fcode
, BUILT_IN_MD
,
1144 arm_builtin_decls
[fcode
] = fndecl
;
1147 /* Set up ACLE builtins, even builtins for instructions that are not
1148 in the current target ISA to allow the user to compile particular modules
1149 with different target specific options that differ from the command line
1150 options. Such builtins will be rejected in arm_expand_builtin. */
1153 arm_init_acle_builtins (void)
1155 unsigned int i
, fcode
= ARM_BUILTIN_ACLE_PATTERN_START
;
1157 for (i
= 0; i
< ARRAY_SIZE (acle_builtin_data
); i
++, fcode
++)
1159 arm_builtin_datum
*d
= &acle_builtin_data
[i
];
1160 arm_init_builtin (fcode
, d
, "__builtin_arm");
1164 /* Set up all the NEON builtins, even builtins for instructions that are not
1165 in the current target ISA to allow the user to compile particular modules
1166 with different target specific options that differ from the command line
1167 options. Such builtins will be rejected in arm_expand_builtin. */
1170 arm_init_neon_builtins (void)
1172 unsigned int i
, fcode
= ARM_BUILTIN_NEON_PATTERN_START
;
1174 arm_init_simd_builtin_types ();
1176 /* Strong-typing hasn't been implemented for all AdvSIMD builtin intrinsics.
1177 Therefore we need to preserve the old __builtin scalar types. It can be
1178 removed once all the intrinsics become strongly typed using the qualifier
1180 arm_init_simd_builtin_scalar_types ();
1182 tree lane_check_fpr
= build_function_type_list (void_type_node
,
1186 arm_builtin_decls
[ARM_BUILTIN_NEON_LANE_CHECK
] =
1187 add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr
,
1188 ARM_BUILTIN_NEON_LANE_CHECK
, BUILT_IN_MD
,
1191 for (i
= 0; i
< ARRAY_SIZE (neon_builtin_data
); i
++, fcode
++)
1193 arm_builtin_datum
*d
= &neon_builtin_data
[i
];
1194 arm_init_builtin (fcode
, d
, "__builtin_neon");
1198 /* Set up all the scalar floating point builtins. */
1201 arm_init_vfp_builtins (void)
1203 unsigned int i
, fcode
= ARM_BUILTIN_VFP_PATTERN_START
;
1205 for (i
= 0; i
< ARRAY_SIZE (vfp_builtin_data
); i
++, fcode
++)
1207 arm_builtin_datum
*d
= &vfp_builtin_data
[i
];
1208 arm_init_builtin (fcode
, d
, "__builtin_neon");
1213 arm_init_crypto_builtins (void)
1215 tree V16UQI_type_node
1216 = arm_simd_builtin_type (V16QImode
, true, false);
1218 tree V4USI_type_node
1219 = arm_simd_builtin_type (V4SImode
, true, false);
1221 tree v16uqi_ftype_v16uqi
1222 = build_function_type_list (V16UQI_type_node
, V16UQI_type_node
,
1225 tree v16uqi_ftype_v16uqi_v16uqi
1226 = build_function_type_list (V16UQI_type_node
, V16UQI_type_node
,
1227 V16UQI_type_node
, NULL_TREE
);
1229 tree v4usi_ftype_v4usi
1230 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1233 tree v4usi_ftype_v4usi_v4usi
1234 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1235 V4USI_type_node
, NULL_TREE
);
1237 tree v4usi_ftype_v4usi_v4usi_v4usi
1238 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1239 V4USI_type_node
, V4USI_type_node
,
1242 tree uti_ftype_udi_udi
1243 = build_function_type_list (unsigned_intTI_type_node
,
1244 unsigned_intDI_type_node
,
1245 unsigned_intDI_type_node
,
1259 ARM_BUILTIN_CRYPTO_##U
1261 "__builtin_arm_crypto_"#L
1264 #define FT2(R, A1, A2) \
1265 R##_ftype_##A1##_##A2
1266 #define FT3(R, A1, A2, A3) \
1267 R##_ftype_##A1##_##A2##_##A3
1268 #define CRYPTO1(L, U, R, A) \
1269 arm_builtin_decls[C (U)] \
1270 = add_builtin_function (N (L), FT1 (R, A), \
1271 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1272 #define CRYPTO2(L, U, R, A1, A2) \
1273 arm_builtin_decls[C (U)] \
1274 = add_builtin_function (N (L), FT2 (R, A1, A2), \
1275 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1277 #define CRYPTO3(L, U, R, A1, A2, A3) \
1278 arm_builtin_decls[C (U)] \
1279 = add_builtin_function (N (L), FT3 (R, A1, A2, A3), \
1280 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1281 #include "crypto.def"
1293 #undef NUM_DREG_TYPES
1294 #undef NUM_QREG_TYPES
1296 #define def_mbuiltin(FLAG, NAME, TYPE, CODE) \
1299 if (FLAG == isa_nobit \
1300 || bitmap_bit_p (arm_active_target.isa, FLAG)) \
1303 bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
1304 BUILT_IN_MD, NULL, NULL_TREE); \
1305 arm_builtin_decls[CODE] = bdecl; \
1310 struct builtin_description
1312 const enum isa_feature feature
;
1313 const enum insn_code icode
;
1314 const char * const name
;
1315 const enum arm_builtins code
;
1316 const enum rtx_code comparison
;
1317 const unsigned int flag
;
1320 static const struct builtin_description bdesc_2arg
[] =
1322 #define IWMMXT_BUILTIN(code, string, builtin) \
1323 { isa_bit_iwmmxt, CODE_FOR_##code, \
1324 "__builtin_arm_" string, \
1325 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1327 #define IWMMXT2_BUILTIN(code, string, builtin) \
1328 { isa_bit_iwmmxt2, CODE_FOR_##code, \
1329 "__builtin_arm_" string, \
1330 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1332 IWMMXT_BUILTIN (addv8qi3
, "waddb", WADDB
)
1333 IWMMXT_BUILTIN (addv4hi3
, "waddh", WADDH
)
1334 IWMMXT_BUILTIN (addv2si3
, "waddw", WADDW
)
1335 IWMMXT_BUILTIN (subv8qi3
, "wsubb", WSUBB
)
1336 IWMMXT_BUILTIN (subv4hi3
, "wsubh", WSUBH
)
1337 IWMMXT_BUILTIN (subv2si3
, "wsubw", WSUBW
)
1338 IWMMXT_BUILTIN (ssaddv8qi3
, "waddbss", WADDSSB
)
1339 IWMMXT_BUILTIN (ssaddv4hi3
, "waddhss", WADDSSH
)
1340 IWMMXT_BUILTIN (ssaddv2si3
, "waddwss", WADDSSW
)
1341 IWMMXT_BUILTIN (sssubv8qi3
, "wsubbss", WSUBSSB
)
1342 IWMMXT_BUILTIN (sssubv4hi3
, "wsubhss", WSUBSSH
)
1343 IWMMXT_BUILTIN (sssubv2si3
, "wsubwss", WSUBSSW
)
1344 IWMMXT_BUILTIN (usaddv8qi3
, "waddbus", WADDUSB
)
1345 IWMMXT_BUILTIN (usaddv4hi3
, "waddhus", WADDUSH
)
1346 IWMMXT_BUILTIN (usaddv2si3
, "waddwus", WADDUSW
)
1347 IWMMXT_BUILTIN (ussubv8qi3
, "wsubbus", WSUBUSB
)
1348 IWMMXT_BUILTIN (ussubv4hi3
, "wsubhus", WSUBUSH
)
1349 IWMMXT_BUILTIN (ussubv2si3
, "wsubwus", WSUBUSW
)
1350 IWMMXT_BUILTIN (mulv4hi3
, "wmulul", WMULUL
)
1351 IWMMXT_BUILTIN (smulv4hi3_highpart
, "wmulsm", WMULSM
)
1352 IWMMXT_BUILTIN (umulv4hi3_highpart
, "wmulum", WMULUM
)
1353 IWMMXT_BUILTIN (eqv8qi3
, "wcmpeqb", WCMPEQB
)
1354 IWMMXT_BUILTIN (eqv4hi3
, "wcmpeqh", WCMPEQH
)
1355 IWMMXT_BUILTIN (eqv2si3
, "wcmpeqw", WCMPEQW
)
1356 IWMMXT_BUILTIN (gtuv8qi3
, "wcmpgtub", WCMPGTUB
)
1357 IWMMXT_BUILTIN (gtuv4hi3
, "wcmpgtuh", WCMPGTUH
)
1358 IWMMXT_BUILTIN (gtuv2si3
, "wcmpgtuw", WCMPGTUW
)
1359 IWMMXT_BUILTIN (gtv8qi3
, "wcmpgtsb", WCMPGTSB
)
1360 IWMMXT_BUILTIN (gtv4hi3
, "wcmpgtsh", WCMPGTSH
)
1361 IWMMXT_BUILTIN (gtv2si3
, "wcmpgtsw", WCMPGTSW
)
1362 IWMMXT_BUILTIN (umaxv8qi3
, "wmaxub", WMAXUB
)
1363 IWMMXT_BUILTIN (smaxv8qi3
, "wmaxsb", WMAXSB
)
1364 IWMMXT_BUILTIN (umaxv4hi3
, "wmaxuh", WMAXUH
)
1365 IWMMXT_BUILTIN (smaxv4hi3
, "wmaxsh", WMAXSH
)
1366 IWMMXT_BUILTIN (umaxv2si3
, "wmaxuw", WMAXUW
)
1367 IWMMXT_BUILTIN (smaxv2si3
, "wmaxsw", WMAXSW
)
1368 IWMMXT_BUILTIN (uminv8qi3
, "wminub", WMINUB
)
1369 IWMMXT_BUILTIN (sminv8qi3
, "wminsb", WMINSB
)
1370 IWMMXT_BUILTIN (uminv4hi3
, "wminuh", WMINUH
)
1371 IWMMXT_BUILTIN (sminv4hi3
, "wminsh", WMINSH
)
1372 IWMMXT_BUILTIN (uminv2si3
, "wminuw", WMINUW
)
1373 IWMMXT_BUILTIN (sminv2si3
, "wminsw", WMINSW
)
1374 IWMMXT_BUILTIN (iwmmxt_anddi3
, "wand", WAND
)
1375 IWMMXT_BUILTIN (iwmmxt_nanddi3
, "wandn", WANDN
)
1376 IWMMXT_BUILTIN (iwmmxt_iordi3
, "wor", WOR
)
1377 IWMMXT_BUILTIN (iwmmxt_xordi3
, "wxor", WXOR
)
1378 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3
, "wavg2b", WAVG2B
)
1379 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3
, "wavg2h", WAVG2H
)
1380 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3
, "wavg2br", WAVG2BR
)
1381 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3
, "wavg2hr", WAVG2HR
)
1382 IWMMXT_BUILTIN (iwmmxt_wunpckilb
, "wunpckilb", WUNPCKILB
)
1383 IWMMXT_BUILTIN (iwmmxt_wunpckilh
, "wunpckilh", WUNPCKILH
)
1384 IWMMXT_BUILTIN (iwmmxt_wunpckilw
, "wunpckilw", WUNPCKILW
)
1385 IWMMXT_BUILTIN (iwmmxt_wunpckihb
, "wunpckihb", WUNPCKIHB
)
1386 IWMMXT_BUILTIN (iwmmxt_wunpckihh
, "wunpckihh", WUNPCKIHH
)
1387 IWMMXT_BUILTIN (iwmmxt_wunpckihw
, "wunpckihw", WUNPCKIHW
)
1388 IWMMXT2_BUILTIN (iwmmxt_waddsubhx
, "waddsubhx", WADDSUBHX
)
1389 IWMMXT2_BUILTIN (iwmmxt_wsubaddhx
, "wsubaddhx", WSUBADDHX
)
1390 IWMMXT2_BUILTIN (iwmmxt_wabsdiffb
, "wabsdiffb", WABSDIFFB
)
1391 IWMMXT2_BUILTIN (iwmmxt_wabsdiffh
, "wabsdiffh", WABSDIFFH
)
1392 IWMMXT2_BUILTIN (iwmmxt_wabsdiffw
, "wabsdiffw", WABSDIFFW
)
1393 IWMMXT2_BUILTIN (iwmmxt_avg4
, "wavg4", WAVG4
)
1394 IWMMXT2_BUILTIN (iwmmxt_avg4r
, "wavg4r", WAVG4R
)
1395 IWMMXT2_BUILTIN (iwmmxt_wmulwsm
, "wmulwsm", WMULWSM
)
1396 IWMMXT2_BUILTIN (iwmmxt_wmulwum
, "wmulwum", WMULWUM
)
1397 IWMMXT2_BUILTIN (iwmmxt_wmulwsmr
, "wmulwsmr", WMULWSMR
)
1398 IWMMXT2_BUILTIN (iwmmxt_wmulwumr
, "wmulwumr", WMULWUMR
)
1399 IWMMXT2_BUILTIN (iwmmxt_wmulwl
, "wmulwl", WMULWL
)
1400 IWMMXT2_BUILTIN (iwmmxt_wmulsmr
, "wmulsmr", WMULSMR
)
1401 IWMMXT2_BUILTIN (iwmmxt_wmulumr
, "wmulumr", WMULUMR
)
1402 IWMMXT2_BUILTIN (iwmmxt_wqmulm
, "wqmulm", WQMULM
)
1403 IWMMXT2_BUILTIN (iwmmxt_wqmulmr
, "wqmulmr", WQMULMR
)
1404 IWMMXT2_BUILTIN (iwmmxt_wqmulwm
, "wqmulwm", WQMULWM
)
1405 IWMMXT2_BUILTIN (iwmmxt_wqmulwmr
, "wqmulwmr", WQMULWMR
)
1406 IWMMXT_BUILTIN (iwmmxt_walignr0
, "walignr0", WALIGNR0
)
1407 IWMMXT_BUILTIN (iwmmxt_walignr1
, "walignr1", WALIGNR1
)
1408 IWMMXT_BUILTIN (iwmmxt_walignr2
, "walignr2", WALIGNR2
)
1409 IWMMXT_BUILTIN (iwmmxt_walignr3
, "walignr3", WALIGNR3
)
1411 #define IWMMXT_BUILTIN2(code, builtin) \
1412 { isa_bit_iwmmxt, CODE_FOR_##code, NULL, \
1413 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1415 #define IWMMXT2_BUILTIN2(code, builtin) \
1416 { isa_bit_iwmmxt2, CODE_FOR_##code, NULL, \
1417 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1419 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm
, WADDBHUSM
)
1420 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl
, WADDBHUSL
)
1421 IWMMXT_BUILTIN2 (iwmmxt_wpackhss
, WPACKHSS
)
1422 IWMMXT_BUILTIN2 (iwmmxt_wpackwss
, WPACKWSS
)
1423 IWMMXT_BUILTIN2 (iwmmxt_wpackdss
, WPACKDSS
)
1424 IWMMXT_BUILTIN2 (iwmmxt_wpackhus
, WPACKHUS
)
1425 IWMMXT_BUILTIN2 (iwmmxt_wpackwus
, WPACKWUS
)
1426 IWMMXT_BUILTIN2 (iwmmxt_wpackdus
, WPACKDUS
)
1427 IWMMXT_BUILTIN2 (iwmmxt_wmacuz
, WMACUZ
)
1428 IWMMXT_BUILTIN2 (iwmmxt_wmacsz
, WMACSZ
)
1431 #define FP_BUILTIN(L, U) \
1432 {isa_nobit, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
1435 FP_BUILTIN (get_fpscr
, GET_FPSCR
)
1436 FP_BUILTIN (set_fpscr
, SET_FPSCR
)
1439 #define CRYPTO_BUILTIN(L, U) \
1440 {isa_nobit, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, \
1441 ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0},
1445 #define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U)
1446 #define CRYPTO1(L, U, R, A)
1447 #define CRYPTO3(L, U, R, A1, A2, A3)
1448 #include "crypto.def"
1455 static const struct builtin_description bdesc_1arg
[] =
1457 IWMMXT_BUILTIN (iwmmxt_tmovmskb
, "tmovmskb", TMOVMSKB
)
1458 IWMMXT_BUILTIN (iwmmxt_tmovmskh
, "tmovmskh", TMOVMSKH
)
1459 IWMMXT_BUILTIN (iwmmxt_tmovmskw
, "tmovmskw", TMOVMSKW
)
1460 IWMMXT_BUILTIN (iwmmxt_waccb
, "waccb", WACCB
)
1461 IWMMXT_BUILTIN (iwmmxt_wacch
, "wacch", WACCH
)
1462 IWMMXT_BUILTIN (iwmmxt_waccw
, "waccw", WACCW
)
1463 IWMMXT_BUILTIN (iwmmxt_wunpckehub
, "wunpckehub", WUNPCKEHUB
)
1464 IWMMXT_BUILTIN (iwmmxt_wunpckehuh
, "wunpckehuh", WUNPCKEHUH
)
1465 IWMMXT_BUILTIN (iwmmxt_wunpckehuw
, "wunpckehuw", WUNPCKEHUW
)
1466 IWMMXT_BUILTIN (iwmmxt_wunpckehsb
, "wunpckehsb", WUNPCKEHSB
)
1467 IWMMXT_BUILTIN (iwmmxt_wunpckehsh
, "wunpckehsh", WUNPCKEHSH
)
1468 IWMMXT_BUILTIN (iwmmxt_wunpckehsw
, "wunpckehsw", WUNPCKEHSW
)
1469 IWMMXT_BUILTIN (iwmmxt_wunpckelub
, "wunpckelub", WUNPCKELUB
)
1470 IWMMXT_BUILTIN (iwmmxt_wunpckeluh
, "wunpckeluh", WUNPCKELUH
)
1471 IWMMXT_BUILTIN (iwmmxt_wunpckeluw
, "wunpckeluw", WUNPCKELUW
)
1472 IWMMXT_BUILTIN (iwmmxt_wunpckelsb
, "wunpckelsb", WUNPCKELSB
)
1473 IWMMXT_BUILTIN (iwmmxt_wunpckelsh
, "wunpckelsh", WUNPCKELSH
)
1474 IWMMXT_BUILTIN (iwmmxt_wunpckelsw
, "wunpckelsw", WUNPCKELSW
)
1475 IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3
, "wabsb", WABSB
)
1476 IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3
, "wabsh", WABSH
)
1477 IWMMXT2_BUILTIN (iwmmxt_wabsv2si3
, "wabsw", WABSW
)
1478 IWMMXT_BUILTIN (tbcstv8qi
, "tbcstb", TBCSTB
)
1479 IWMMXT_BUILTIN (tbcstv4hi
, "tbcsth", TBCSTH
)
1480 IWMMXT_BUILTIN (tbcstv2si
, "tbcstw", TBCSTW
)
1482 #define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U)
1483 #define CRYPTO2(L, U, R, A1, A2)
1484 #define CRYPTO3(L, U, R, A1, A2, A3)
1485 #include "crypto.def"
1491 static const struct builtin_description bdesc_3arg
[] =
1493 #define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U)
1494 #define CRYPTO1(L, U, R, A)
1495 #define CRYPTO2(L, U, R, A1, A2)
1496 #include "crypto.def"
1501 #undef CRYPTO_BUILTIN
1503 /* Set up all the iWMMXt builtins. This is not called if
1504 TARGET_IWMMXT is zero. */
1507 arm_init_iwmmxt_builtins (void)
1509 const struct builtin_description
* d
;
1512 tree V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
1513 tree V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
1514 tree V8QI_type_node
= build_vector_type_for_mode (intQI_type_node
, V8QImode
);
1516 tree v8qi_ftype_v8qi_v8qi_int
1517 = build_function_type_list (V8QI_type_node
,
1518 V8QI_type_node
, V8QI_type_node
,
1519 integer_type_node
, NULL_TREE
);
1520 tree v4hi_ftype_v4hi_int
1521 = build_function_type_list (V4HI_type_node
,
1522 V4HI_type_node
, integer_type_node
, NULL_TREE
);
1523 tree v2si_ftype_v2si_int
1524 = build_function_type_list (V2SI_type_node
,
1525 V2SI_type_node
, integer_type_node
, NULL_TREE
);
1526 tree v2si_ftype_di_di
1527 = build_function_type_list (V2SI_type_node
,
1528 long_long_integer_type_node
,
1529 long_long_integer_type_node
,
1531 tree di_ftype_di_int
1532 = build_function_type_list (long_long_integer_type_node
,
1533 long_long_integer_type_node
,
1534 integer_type_node
, NULL_TREE
);
1535 tree di_ftype_di_int_int
1536 = build_function_type_list (long_long_integer_type_node
,
1537 long_long_integer_type_node
,
1539 integer_type_node
, NULL_TREE
);
1541 = build_function_type_list (integer_type_node
,
1542 V8QI_type_node
, NULL_TREE
);
1544 = build_function_type_list (integer_type_node
,
1545 V4HI_type_node
, NULL_TREE
);
1547 = build_function_type_list (integer_type_node
,
1548 V2SI_type_node
, NULL_TREE
);
1549 tree int_ftype_v8qi_int
1550 = build_function_type_list (integer_type_node
,
1551 V8QI_type_node
, integer_type_node
, NULL_TREE
);
1552 tree int_ftype_v4hi_int
1553 = build_function_type_list (integer_type_node
,
1554 V4HI_type_node
, integer_type_node
, NULL_TREE
);
1555 tree int_ftype_v2si_int
1556 = build_function_type_list (integer_type_node
,
1557 V2SI_type_node
, integer_type_node
, NULL_TREE
);
1558 tree v8qi_ftype_v8qi_int_int
1559 = build_function_type_list (V8QI_type_node
,
1560 V8QI_type_node
, integer_type_node
,
1561 integer_type_node
, NULL_TREE
);
1562 tree v4hi_ftype_v4hi_int_int
1563 = build_function_type_list (V4HI_type_node
,
1564 V4HI_type_node
, integer_type_node
,
1565 integer_type_node
, NULL_TREE
);
1566 tree v2si_ftype_v2si_int_int
1567 = build_function_type_list (V2SI_type_node
,
1568 V2SI_type_node
, integer_type_node
,
1569 integer_type_node
, NULL_TREE
);
1570 /* Miscellaneous. */
1571 tree v8qi_ftype_v4hi_v4hi
1572 = build_function_type_list (V8QI_type_node
,
1573 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
1574 tree v4hi_ftype_v2si_v2si
1575 = build_function_type_list (V4HI_type_node
,
1576 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
1577 tree v8qi_ftype_v4hi_v8qi
1578 = build_function_type_list (V8QI_type_node
,
1579 V4HI_type_node
, V8QI_type_node
, NULL_TREE
);
1580 tree v2si_ftype_v4hi_v4hi
1581 = build_function_type_list (V2SI_type_node
,
1582 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
1583 tree v2si_ftype_v8qi_v8qi
1584 = build_function_type_list (V2SI_type_node
,
1585 V8QI_type_node
, V8QI_type_node
, NULL_TREE
);
1586 tree v4hi_ftype_v4hi_di
1587 = build_function_type_list (V4HI_type_node
,
1588 V4HI_type_node
, long_long_integer_type_node
,
1590 tree v2si_ftype_v2si_di
1591 = build_function_type_list (V2SI_type_node
,
1592 V2SI_type_node
, long_long_integer_type_node
,
1595 = build_function_type_list (long_long_unsigned_type_node
, NULL_TREE
);
1597 = build_function_type_list (integer_type_node
, NULL_TREE
);
1599 = build_function_type_list (long_long_integer_type_node
,
1600 V8QI_type_node
, NULL_TREE
);
1602 = build_function_type_list (long_long_integer_type_node
,
1603 V4HI_type_node
, NULL_TREE
);
1605 = build_function_type_list (long_long_integer_type_node
,
1606 V2SI_type_node
, NULL_TREE
);
1607 tree v2si_ftype_v4hi
1608 = build_function_type_list (V2SI_type_node
,
1609 V4HI_type_node
, NULL_TREE
);
1610 tree v4hi_ftype_v8qi
1611 = build_function_type_list (V4HI_type_node
,
1612 V8QI_type_node
, NULL_TREE
);
1613 tree v8qi_ftype_v8qi
1614 = build_function_type_list (V8QI_type_node
,
1615 V8QI_type_node
, NULL_TREE
);
1616 tree v4hi_ftype_v4hi
1617 = build_function_type_list (V4HI_type_node
,
1618 V4HI_type_node
, NULL_TREE
);
1619 tree v2si_ftype_v2si
1620 = build_function_type_list (V2SI_type_node
,
1621 V2SI_type_node
, NULL_TREE
);
1623 tree di_ftype_di_v4hi_v4hi
1624 = build_function_type_list (long_long_unsigned_type_node
,
1625 long_long_unsigned_type_node
,
1626 V4HI_type_node
, V4HI_type_node
,
1629 tree di_ftype_v4hi_v4hi
1630 = build_function_type_list (long_long_unsigned_type_node
,
1631 V4HI_type_node
,V4HI_type_node
,
1634 tree v2si_ftype_v2si_v4hi_v4hi
1635 = build_function_type_list (V2SI_type_node
,
1636 V2SI_type_node
, V4HI_type_node
,
1637 V4HI_type_node
, NULL_TREE
);
1639 tree v2si_ftype_v2si_v8qi_v8qi
1640 = build_function_type_list (V2SI_type_node
,
1641 V2SI_type_node
, V8QI_type_node
,
1642 V8QI_type_node
, NULL_TREE
);
1644 tree di_ftype_di_v2si_v2si
1645 = build_function_type_list (long_long_unsigned_type_node
,
1646 long_long_unsigned_type_node
,
1647 V2SI_type_node
, V2SI_type_node
,
1650 tree di_ftype_di_di_int
1651 = build_function_type_list (long_long_unsigned_type_node
,
1652 long_long_unsigned_type_node
,
1653 long_long_unsigned_type_node
,
1654 integer_type_node
, NULL_TREE
);
1657 = build_function_type_list (void_type_node
,
1658 integer_type_node
, NULL_TREE
);
1660 tree v8qi_ftype_char
1661 = build_function_type_list (V8QI_type_node
,
1662 signed_char_type_node
, NULL_TREE
);
1664 tree v4hi_ftype_short
1665 = build_function_type_list (V4HI_type_node
,
1666 short_integer_type_node
, NULL_TREE
);
1669 = build_function_type_list (V2SI_type_node
,
1670 integer_type_node
, NULL_TREE
);
1672 /* Normal vector binops. */
1673 tree v8qi_ftype_v8qi_v8qi
1674 = build_function_type_list (V8QI_type_node
,
1675 V8QI_type_node
, V8QI_type_node
, NULL_TREE
);
1676 tree v4hi_ftype_v4hi_v4hi
1677 = build_function_type_list (V4HI_type_node
,
1678 V4HI_type_node
,V4HI_type_node
, NULL_TREE
);
1679 tree v2si_ftype_v2si_v2si
1680 = build_function_type_list (V2SI_type_node
,
1681 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
1683 = build_function_type_list (long_long_unsigned_type_node
,
1684 long_long_unsigned_type_node
,
1685 long_long_unsigned_type_node
,
1688 /* Add all builtins that are more or less simple operations on two
1690 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
1692 /* Use one of the operands; the target can have a different mode for
1693 mask-generating compares. */
1698 || !(d
->feature
== isa_bit_iwmmxt
1699 || d
->feature
== isa_bit_iwmmxt2
))
1702 mode
= insn_data
[d
->icode
].operand
[1].mode
;
1707 type
= v8qi_ftype_v8qi_v8qi
;
1710 type
= v4hi_ftype_v4hi_v4hi
;
1713 type
= v2si_ftype_v2si_v2si
;
1716 type
= di_ftype_di_di
;
1723 def_mbuiltin (d
->feature
, d
->name
, type
, d
->code
);
1726 /* Add the remaining MMX insns with somewhat more complicated types. */
1727 #define iwmmx_mbuiltin(NAME, TYPE, CODE) \
1728 def_mbuiltin (isa_bit_iwmmxt, "__builtin_arm_" NAME, \
1729 (TYPE), ARM_BUILTIN_ ## CODE)
1731 #define iwmmx2_mbuiltin(NAME, TYPE, CODE) \
1732 def_mbuiltin (isa_bit_iwmmxt2, "__builtin_arm_" NAME, \
1733 (TYPE), ARM_BUILTIN_ ## CODE)
1735 iwmmx_mbuiltin ("wzero", di_ftype_void
, WZERO
);
1736 iwmmx_mbuiltin ("setwcgr0", void_ftype_int
, SETWCGR0
);
1737 iwmmx_mbuiltin ("setwcgr1", void_ftype_int
, SETWCGR1
);
1738 iwmmx_mbuiltin ("setwcgr2", void_ftype_int
, SETWCGR2
);
1739 iwmmx_mbuiltin ("setwcgr3", void_ftype_int
, SETWCGR3
);
1740 iwmmx_mbuiltin ("getwcgr0", int_ftype_void
, GETWCGR0
);
1741 iwmmx_mbuiltin ("getwcgr1", int_ftype_void
, GETWCGR1
);
1742 iwmmx_mbuiltin ("getwcgr2", int_ftype_void
, GETWCGR2
);
1743 iwmmx_mbuiltin ("getwcgr3", int_ftype_void
, GETWCGR3
);
1745 iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di
, WSLLH
);
1746 iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di
, WSLLW
);
1747 iwmmx_mbuiltin ("wslld", di_ftype_di_di
, WSLLD
);
1748 iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int
, WSLLHI
);
1749 iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int
, WSLLWI
);
1750 iwmmx_mbuiltin ("wslldi", di_ftype_di_int
, WSLLDI
);
1752 iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di
, WSRLH
);
1753 iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di
, WSRLW
);
1754 iwmmx_mbuiltin ("wsrld", di_ftype_di_di
, WSRLD
);
1755 iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int
, WSRLHI
);
1756 iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int
, WSRLWI
);
1757 iwmmx_mbuiltin ("wsrldi", di_ftype_di_int
, WSRLDI
);
1759 iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di
, WSRAH
);
1760 iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di
, WSRAW
);
1761 iwmmx_mbuiltin ("wsrad", di_ftype_di_di
, WSRAD
);
1762 iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int
, WSRAHI
);
1763 iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int
, WSRAWI
);
1764 iwmmx_mbuiltin ("wsradi", di_ftype_di_int
, WSRADI
);
1766 iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di
, WRORH
);
1767 iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di
, WRORW
);
1768 iwmmx_mbuiltin ("wrord", di_ftype_di_di
, WRORD
);
1769 iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int
, WRORHI
);
1770 iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int
, WRORWI
);
1771 iwmmx_mbuiltin ("wrordi", di_ftype_di_int
, WRORDI
);
1773 iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int
, WSHUFH
);
1775 iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi
, WSADB
);
1776 iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi
, WSADH
);
1777 iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi
, WMADDS
);
1778 iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi
, WMADDSX
);
1779 iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi
, WMADDSN
);
1780 iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi
, WMADDU
);
1781 iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi
, WMADDUX
);
1782 iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi
, WMADDUN
);
1783 iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi
, WSADBZ
);
1784 iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi
, WSADHZ
);
1786 iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int
, TEXTRMSB
);
1787 iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int
, TEXTRMSH
);
1788 iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int
, TEXTRMSW
);
1789 iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int
, TEXTRMUB
);
1790 iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int
, TEXTRMUH
);
1791 iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int
, TEXTRMUW
);
1792 iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int
, TINSRB
);
1793 iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int
, TINSRH
);
1794 iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int
, TINSRW
);
1796 iwmmx_mbuiltin ("waccb", di_ftype_v8qi
, WACCB
);
1797 iwmmx_mbuiltin ("wacch", di_ftype_v4hi
, WACCH
);
1798 iwmmx_mbuiltin ("waccw", di_ftype_v2si
, WACCW
);
1800 iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi
, TMOVMSKB
);
1801 iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi
, TMOVMSKH
);
1802 iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si
, TMOVMSKW
);
1804 iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi
, WADDBHUSM
);
1805 iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi
, WADDBHUSL
);
1807 iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi
, WPACKHSS
);
1808 iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi
, WPACKHUS
);
1809 iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si
, WPACKWUS
);
1810 iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si
, WPACKWSS
);
1811 iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di
, WPACKDUS
);
1812 iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di
, WPACKDSS
);
1814 iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi
, WUNPCKEHUB
);
1815 iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi
, WUNPCKEHUH
);
1816 iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si
, WUNPCKEHUW
);
1817 iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi
, WUNPCKEHSB
);
1818 iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi
, WUNPCKEHSH
);
1819 iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si
, WUNPCKEHSW
);
1820 iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi
, WUNPCKELUB
);
1821 iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi
, WUNPCKELUH
);
1822 iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si
, WUNPCKELUW
);
1823 iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi
, WUNPCKELSB
);
1824 iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi
, WUNPCKELSH
);
1825 iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si
, WUNPCKELSW
);
1827 iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi
, WMACS
);
1828 iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi
, WMACSZ
);
1829 iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi
, WMACU
);
1830 iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi
, WMACUZ
);
1832 iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int
, WALIGNI
);
1833 iwmmx_mbuiltin ("tmia", di_ftype_di_int_int
, TMIA
);
1834 iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int
, TMIAPH
);
1835 iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int
, TMIABB
);
1836 iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int
, TMIABT
);
1837 iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int
, TMIATB
);
1838 iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int
, TMIATT
);
1840 iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi
, WABSB
);
1841 iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi
, WABSH
);
1842 iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si
, WABSW
);
1844 iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi
, WQMIABB
);
1845 iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi
, WQMIABT
);
1846 iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi
, WQMIATB
);
1847 iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi
, WQMIATT
);
1849 iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi
, WQMIABBN
);
1850 iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi
, WQMIABTN
);
1851 iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi
, WQMIATBN
);
1852 iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi
, WQMIATTN
);
1854 iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi
, WMIABB
);
1855 iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi
, WMIABT
);
1856 iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi
, WMIATB
);
1857 iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi
, WMIATT
);
1859 iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi
, WMIABBN
);
1860 iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi
, WMIABTN
);
1861 iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi
, WMIATBN
);
1862 iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi
, WMIATTN
);
1864 iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si
, WMIAWBB
);
1865 iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si
, WMIAWBT
);
1866 iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si
, WMIAWTB
);
1867 iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si
, WMIAWTT
);
1869 iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si
, WMIAWBBN
);
1870 iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si
, WMIAWBTN
);
1871 iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si
, WMIAWTBN
);
1872 iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si
, WMIAWTTN
);
1874 iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int
, WMERGE
);
1876 iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char
, TBCSTB
);
1877 iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short
, TBCSTH
);
1878 iwmmx_mbuiltin ("tbcstw", v2si_ftype_int
, TBCSTW
);
1880 #undef iwmmx_mbuiltin
1881 #undef iwmmx2_mbuiltin
1885 arm_init_fp16_builtins (void)
1887 arm_fp16_type_node
= make_node (REAL_TYPE
);
1888 TYPE_PRECISION (arm_fp16_type_node
) = GET_MODE_PRECISION (HFmode
);
1889 layout_type (arm_fp16_type_node
);
1890 if (arm_fp16_format
)
1891 (*lang_hooks
.types
.register_builtin_type
) (arm_fp16_type_node
,
1896 arm_init_builtins (void)
1898 if (TARGET_REALLY_IWMMXT
)
1899 arm_init_iwmmxt_builtins ();
1901 /* This creates the arm_simd_floatHF_type_node so must come before
1902 arm_init_neon_builtins which uses it. */
1903 arm_init_fp16_builtins ();
1905 if (TARGET_MAYBE_HARD_FLOAT
)
1907 arm_init_neon_builtins ();
1908 arm_init_vfp_builtins ();
1909 arm_init_crypto_builtins ();
1912 arm_init_acle_builtins ();
1914 if (TARGET_MAYBE_HARD_FLOAT
)
1916 tree ftype_set_fpscr
1917 = build_function_type_list (void_type_node
, unsigned_type_node
, NULL
);
1918 tree ftype_get_fpscr
1919 = build_function_type_list (unsigned_type_node
, NULL
);
1921 arm_builtin_decls
[ARM_BUILTIN_GET_FPSCR
]
1922 = add_builtin_function ("__builtin_arm_get_fpscr", ftype_get_fpscr
,
1923 ARM_BUILTIN_GET_FPSCR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1924 arm_builtin_decls
[ARM_BUILTIN_SET_FPSCR
]
1925 = add_builtin_function ("__builtin_arm_set_fpscr", ftype_set_fpscr
,
1926 ARM_BUILTIN_SET_FPSCR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1931 tree ftype_cmse_nonsecure_caller
1932 = build_function_type_list (unsigned_type_node
, NULL
);
1933 arm_builtin_decls
[ARM_BUILTIN_CMSE_NONSECURE_CALLER
]
1934 = add_builtin_function ("__builtin_arm_cmse_nonsecure_caller",
1935 ftype_cmse_nonsecure_caller
,
1936 ARM_BUILTIN_CMSE_NONSECURE_CALLER
, BUILT_IN_MD
,
1941 /* Return the ARM builtin for CODE. */
1944 arm_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
1946 if (code
>= ARM_BUILTIN_MAX
)
1947 return error_mark_node
;
1949 return arm_builtin_decls
[code
];
1952 /* Errors in the source file can cause expand_expr to return const0_rtx
1953 where we expect a vector. To avoid crashing, use one of the vector
1954 clear instructions. */
1957 safe_vector_operand (rtx x
, machine_mode mode
)
1959 if (x
!= const0_rtx
)
1961 x
= gen_reg_rtx (mode
);
1963 emit_insn (gen_iwmmxt_clrdi (mode
== DImode
? x
1964 : gen_rtx_SUBREG (DImode
, x
, 0)));
1968 /* Function to expand ternary builtins. */
1970 arm_expand_ternop_builtin (enum insn_code icode
,
1971 tree exp
, rtx target
)
1974 tree arg0
= CALL_EXPR_ARG (exp
, 0);
1975 tree arg1
= CALL_EXPR_ARG (exp
, 1);
1976 tree arg2
= CALL_EXPR_ARG (exp
, 2);
1978 rtx op0
= expand_normal (arg0
);
1979 rtx op1
= expand_normal (arg1
);
1980 rtx op2
= expand_normal (arg2
);
1983 /* The sha1c, sha1p, sha1m crypto builtins require a different vec_select
1984 lane operand depending on endianness. */
1985 bool builtin_sha1cpm_p
= false;
1987 if (insn_data
[icode
].n_operands
== 5)
1989 gcc_assert (icode
== CODE_FOR_crypto_sha1c
1990 || icode
== CODE_FOR_crypto_sha1p
1991 || icode
== CODE_FOR_crypto_sha1m
);
1992 builtin_sha1cpm_p
= true;
1994 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
1995 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1996 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
1997 machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
2000 if (VECTOR_MODE_P (mode0
))
2001 op0
= safe_vector_operand (op0
, mode0
);
2002 if (VECTOR_MODE_P (mode1
))
2003 op1
= safe_vector_operand (op1
, mode1
);
2004 if (VECTOR_MODE_P (mode2
))
2005 op2
= safe_vector_operand (op2
, mode2
);
2008 || GET_MODE (target
) != tmode
2009 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2010 target
= gen_reg_rtx (tmode
);
2012 gcc_assert ((GET_MODE (op0
) == mode0
|| GET_MODE (op0
) == VOIDmode
)
2013 && (GET_MODE (op1
) == mode1
|| GET_MODE (op1
) == VOIDmode
)
2014 && (GET_MODE (op2
) == mode2
|| GET_MODE (op2
) == VOIDmode
));
2016 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2017 op0
= copy_to_mode_reg (mode0
, op0
);
2018 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2019 op1
= copy_to_mode_reg (mode1
, op1
);
2020 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2021 op2
= copy_to_mode_reg (mode2
, op2
);
2022 if (builtin_sha1cpm_p
)
2023 op3
= GEN_INT (TARGET_BIG_END
? 1 : 0);
2025 if (builtin_sha1cpm_p
)
2026 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, op3
);
2028 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2035 /* Subroutine of arm_expand_builtin to take care of binop insns. */
2038 arm_expand_binop_builtin (enum insn_code icode
,
2039 tree exp
, rtx target
)
2042 tree arg0
= CALL_EXPR_ARG (exp
, 0);
2043 tree arg1
= CALL_EXPR_ARG (exp
, 1);
2044 rtx op0
= expand_normal (arg0
);
2045 rtx op1
= expand_normal (arg1
);
2046 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2047 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2048 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2050 if (VECTOR_MODE_P (mode0
))
2051 op0
= safe_vector_operand (op0
, mode0
);
2052 if (VECTOR_MODE_P (mode1
))
2053 op1
= safe_vector_operand (op1
, mode1
);
2056 || GET_MODE (target
) != tmode
2057 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2058 target
= gen_reg_rtx (tmode
);
2060 gcc_assert ((GET_MODE (op0
) == mode0
|| GET_MODE (op0
) == VOIDmode
)
2061 && (GET_MODE (op1
) == mode1
|| GET_MODE (op1
) == VOIDmode
));
2063 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2064 op0
= copy_to_mode_reg (mode0
, op0
);
2065 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2066 op1
= copy_to_mode_reg (mode1
, op1
);
2068 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2075 /* Subroutine of arm_expand_builtin to take care of unop insns. */
2078 arm_expand_unop_builtin (enum insn_code icode
,
2079 tree exp
, rtx target
, int do_load
)
2082 tree arg0
= CALL_EXPR_ARG (exp
, 0);
2083 rtx op0
= expand_normal (arg0
);
2085 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2086 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2087 bool builtin_sha1h_p
= false;
2089 if (insn_data
[icode
].n_operands
== 3)
2091 gcc_assert (icode
== CODE_FOR_crypto_sha1h
);
2092 builtin_sha1h_p
= true;
2096 || GET_MODE (target
) != tmode
2097 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2098 target
= gen_reg_rtx (tmode
);
2100 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
2103 if (VECTOR_MODE_P (mode0
))
2104 op0
= safe_vector_operand (op0
, mode0
);
2106 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2107 op0
= copy_to_mode_reg (mode0
, op0
);
2109 if (builtin_sha1h_p
)
2110 op1
= GEN_INT (TARGET_BIG_END
? 1 : 0);
2112 if (builtin_sha1h_p
)
2113 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2115 pat
= GEN_FCN (icode
) (target
, op0
);
2123 ARG_BUILTIN_COPY_TO_REG
,
2124 ARG_BUILTIN_CONSTANT
,
2125 ARG_BUILTIN_LANE_INDEX
,
2126 ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX
,
2127 ARG_BUILTIN_NEON_MEMORY
,
2133 /* EXP is a pointer argument to a Neon load or store intrinsic. Derive
2134 and return an expression for the accessed memory.
2136 The intrinsic function operates on a block of registers that has
2137 mode REG_MODE. This block contains vectors of type TYPE_MODE. The
2138 function references the memory at EXP of type TYPE and in mode
2139 MEM_MODE; this mode may be BLKmode if no more suitable mode is
2143 neon_dereference_pointer (tree exp
, tree type
, machine_mode mem_mode
,
2144 machine_mode reg_mode
,
2145 machine_mode vector_mode
)
2147 HOST_WIDE_INT reg_size
, vector_size
, nvectors
, nelems
;
2148 tree elem_type
, upper_bound
, array_type
;
2150 /* Work out the size of the register block in bytes. */
2151 reg_size
= GET_MODE_SIZE (reg_mode
);
2153 /* Work out the size of each vector in bytes. */
2154 vector_size
= GET_MODE_SIZE (vector_mode
);
2156 /* Work out how many vectors there are. */
2157 gcc_assert (reg_size
% vector_size
== 0);
2158 nvectors
= reg_size
/ vector_size
;
2160 /* Work out the type of each element. */
2161 gcc_assert (POINTER_TYPE_P (type
));
2162 elem_type
= TREE_TYPE (type
);
2164 /* Work out how many elements are being loaded or stored.
2165 MEM_MODE == REG_MODE implies a one-to-one mapping between register
2166 and memory elements; anything else implies a lane load or store. */
2167 if (mem_mode
== reg_mode
)
2168 nelems
= vector_size
* nvectors
/ int_size_in_bytes (elem_type
);
2172 /* Create a type that describes the full access. */
2173 upper_bound
= build_int_cst (size_type_node
, nelems
- 1);
2174 array_type
= build_array_type (elem_type
, build_index_type (upper_bound
));
2176 /* Dereference EXP using that type. */
2177 return fold_build2 (MEM_REF
, array_type
, exp
,
2178 build_int_cst (build_pointer_type (array_type
), 0));
2181 /* Expand a builtin. */
2183 arm_expand_builtin_args (rtx target
, machine_mode map_mode
, int fcode
,
2184 int icode
, int have_retval
, tree exp
,
2188 tree arg
[SIMD_MAX_BUILTIN_ARGS
];
2189 rtx op
[SIMD_MAX_BUILTIN_ARGS
];
2190 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2191 machine_mode mode
[SIMD_MAX_BUILTIN_ARGS
];
2198 || GET_MODE (target
) != tmode
2199 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
)))
2200 target
= gen_reg_rtx (tmode
);
2202 formals
= TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls
[fcode
]));
2206 builtin_arg thisarg
= args
[argc
];
2208 if (thisarg
== ARG_BUILTIN_STOP
)
2212 int opno
= argc
+ have_retval
;
2213 arg
[argc
] = CALL_EXPR_ARG (exp
, argc
);
2214 mode
[argc
] = insn_data
[icode
].operand
[opno
].mode
;
2215 if (thisarg
== ARG_BUILTIN_NEON_MEMORY
)
2217 machine_mode other_mode
2218 = insn_data
[icode
].operand
[1 - opno
].mode
;
2219 arg
[argc
] = neon_dereference_pointer (arg
[argc
],
2220 TREE_VALUE (formals
),
2221 mode
[argc
], other_mode
,
2225 /* Use EXPAND_MEMORY for ARG_BUILTIN_MEMORY and
2226 ARG_BUILTIN_NEON_MEMORY to ensure a MEM_P be returned. */
2227 op
[argc
] = expand_expr (arg
[argc
], NULL_RTX
, VOIDmode
,
2228 ((thisarg
== ARG_BUILTIN_MEMORY
2229 || thisarg
== ARG_BUILTIN_NEON_MEMORY
)
2230 ? EXPAND_MEMORY
: EXPAND_NORMAL
));
2234 case ARG_BUILTIN_MEMORY
:
2235 case ARG_BUILTIN_COPY_TO_REG
:
2236 if (POINTER_TYPE_P (TREE_TYPE (arg
[argc
])))
2237 op
[argc
] = convert_memory_address (Pmode
, op
[argc
]);
2238 /*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */
2239 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
2240 (op
[argc
], mode
[argc
]))
2241 op
[argc
] = copy_to_mode_reg (mode
[argc
], op
[argc
]);
2244 case ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX
:
2245 gcc_assert (argc
> 1);
2246 if (CONST_INT_P (op
[argc
]))
2248 neon_lane_bounds (op
[argc
], 0,
2249 GET_MODE_NUNITS (map_mode
), exp
);
2250 /* Keep to GCC-vector-extension lane indices in the RTL. */
2252 GEN_INT (NEON_ENDIAN_LANE_N (map_mode
, INTVAL (op
[argc
])));
2256 case ARG_BUILTIN_LANE_INDEX
:
2257 /* Previous argument must be a vector, which this indexes. */
2258 gcc_assert (argc
> 0);
2259 if (CONST_INT_P (op
[argc
]))
2261 machine_mode vmode
= mode
[argc
- 1];
2262 neon_lane_bounds (op
[argc
], 0, GET_MODE_NUNITS (vmode
), exp
);
2264 /* If the lane index isn't a constant then the next
2267 case ARG_BUILTIN_CONSTANT
:
2269 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
2270 (op
[argc
], mode
[argc
]))
2272 error ("%Kargument %d must be a constant immediate",
2274 /* We have failed to expand the pattern, and are safely
2275 in to invalid code. But the mid-end will still try to
2276 build an assignment for this node while it expands,
2277 before stopping for the error, just pass it back
2278 TARGET to ensure a valid assignment. */
2283 case ARG_BUILTIN_NEON_MEMORY
:
2284 /* Check if expand failed. */
2285 if (op
[argc
] == const0_rtx
)
2287 gcc_assert (MEM_P (op
[argc
]));
2288 PUT_MODE (op
[argc
], mode
[argc
]);
2289 /* ??? arm_neon.h uses the same built-in functions for signed
2290 and unsigned accesses, casting where necessary. This isn't
2292 set_mem_alias_set (op
[argc
], 0);
2293 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
2294 (op
[argc
], mode
[argc
]))
2295 op
[argc
] = (replace_equiv_address
2297 copy_to_mode_reg (Pmode
, XEXP (op
[argc
], 0))));
2300 case ARG_BUILTIN_STOP
:
2312 pat
= GEN_FCN (icode
) (target
, op
[0]);
2316 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
2320 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
2324 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
2328 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3], op
[4]);
2332 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3], op
[4], op
[5]);
2342 pat
= GEN_FCN (icode
) (op
[0]);
2346 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
2350 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
2354 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
2358 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3], op
[4]);
2362 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3], op
[4], op
[5]);
2372 /* Check whether our current target implements the pattern chosen for this
2373 builtin and error out if not. */
2376 insn
= get_insns ();
2379 if (recog_memoized (insn
) < 0)
2380 error ("this builtin is not supported for this target");
2387 /* Expand a builtin. These builtins are "special" because they don't have
2388 symbolic constants defined per-instruction or per instruction-variant.
2389 Instead, the required info is looked up in the ARM_BUILTIN_DATA record that
2390 is passed into the function. */
2393 arm_expand_builtin_1 (int fcode
, tree exp
, rtx target
,
2394 arm_builtin_datum
*d
)
2396 enum insn_code icode
= d
->code
;
2397 builtin_arg args
[SIMD_MAX_BUILTIN_ARGS
+ 1];
2398 int num_args
= insn_data
[d
->code
].n_operands
;
2403 if (IN_RANGE (fcode
, ARM_BUILTIN_VFP_BASE
, ARM_BUILTIN_ACLE_BASE
- 1))
2406 is_void
= !!(d
->qualifiers
[0] & qualifier_void
);
2408 num_args
+= is_void
;
2410 for (k
= 1; k
< num_args
; k
++)
2412 /* We have four arrays of data, each indexed in a different fashion.
2413 qualifiers - element 0 always describes the function return type.
2414 operands - element 0 is either the operand for return value (if
2415 the function has a non-void return type) or the operand for the
2417 expr_args - element 0 always holds the first argument.
2418 args - element 0 is always used for the return type. */
2419 int qualifiers_k
= k
;
2420 int operands_k
= k
- is_void
;
2421 int expr_args_k
= k
- 1;
2423 if (d
->qualifiers
[qualifiers_k
] & qualifier_lane_index
)
2424 args
[k
] = ARG_BUILTIN_LANE_INDEX
;
2425 else if (d
->qualifiers
[qualifiers_k
] & qualifier_struct_load_store_lane_index
)
2426 args
[k
] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX
;
2427 else if (d
->qualifiers
[qualifiers_k
] & qualifier_immediate
)
2428 args
[k
] = ARG_BUILTIN_CONSTANT
;
2429 else if (d
->qualifiers
[qualifiers_k
] & qualifier_maybe_immediate
)
2432 = expand_normal (CALL_EXPR_ARG (exp
,
2434 /* Handle constants only if the predicate allows it. */
2435 bool op_const_int_p
=
2437 && (*insn_data
[icode
].operand
[operands_k
].predicate
)
2438 (arg
, insn_data
[icode
].operand
[operands_k
].mode
));
2439 args
[k
] = op_const_int_p
? ARG_BUILTIN_CONSTANT
: ARG_BUILTIN_COPY_TO_REG
;
2441 else if (d
->qualifiers
[qualifiers_k
] & qualifier_pointer
)
2444 args
[k
] = ARG_BUILTIN_NEON_MEMORY
;
2446 args
[k
] = ARG_BUILTIN_MEMORY
;
2449 args
[k
] = ARG_BUILTIN_COPY_TO_REG
;
2451 args
[k
] = ARG_BUILTIN_STOP
;
2453 /* The interface to arm_expand_builtin_args expects a 0 if
2454 the function is void, and a 1 if it is not. */
2455 return arm_expand_builtin_args
2456 (target
, d
->mode
, fcode
, icode
, !is_void
, exp
,
2460 /* Expand an ACLE builtin, i.e. those registered only if their respective
2461 target constraints are met. This check happens within
2462 arm_expand_builtin_args. */
2465 arm_expand_acle_builtin (int fcode
, tree exp
, rtx target
)
2468 arm_builtin_datum
*d
2469 = &acle_builtin_data
[fcode
- ARM_BUILTIN_ACLE_PATTERN_START
];
2471 return arm_expand_builtin_1 (fcode
, exp
, target
, d
);
2474 /* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds.
2475 Most of these are "special" because they don't have symbolic
2476 constants defined per-instruction or per instruction-variant. Instead, the
2477 required info is looked up in the table neon_builtin_data. */
2480 arm_expand_neon_builtin (int fcode
, tree exp
, rtx target
)
2482 if (fcode
>= ARM_BUILTIN_NEON_BASE
&& ! TARGET_NEON
)
2484 fatal_error (input_location
,
2485 "You must enable NEON instructions"
2486 " (e.g. -mfloat-abi=softfp -mfpu=neon)"
2487 " to use these intrinsics.");
2491 if (fcode
== ARM_BUILTIN_NEON_LANE_CHECK
)
2493 /* Builtin is only to check bounds of the lane passed to some intrinsics
2494 that are implemented with gcc vector extensions in arm_neon.h. */
2496 tree nlanes
= CALL_EXPR_ARG (exp
, 0);
2497 gcc_assert (TREE_CODE (nlanes
) == INTEGER_CST
);
2498 rtx lane_idx
= expand_normal (CALL_EXPR_ARG (exp
, 1));
2499 if (CONST_INT_P (lane_idx
))
2500 neon_lane_bounds (lane_idx
, 0, TREE_INT_CST_LOW (nlanes
), exp
);
2502 error ("%Klane index must be a constant immediate", exp
);
2503 /* Don't generate any RTL. */
2507 arm_builtin_datum
*d
2508 = &neon_builtin_data
[fcode
- ARM_BUILTIN_NEON_PATTERN_START
];
2510 return arm_expand_builtin_1 (fcode
, exp
, target
, d
);
2513 /* Expand a VFP builtin. These builtins are treated like
2514 neon builtins except that the data is looked up in table
2515 VFP_BUILTIN_DATA. */
2518 arm_expand_vfp_builtin (int fcode
, tree exp
, rtx target
)
2520 if (fcode
>= ARM_BUILTIN_VFP_BASE
&& ! TARGET_HARD_FLOAT
)
2522 fatal_error (input_location
,
2523 "You must enable VFP instructions"
2524 " to use these intrinsics.");
2528 arm_builtin_datum
*d
2529 = &vfp_builtin_data
[fcode
- ARM_BUILTIN_VFP_PATTERN_START
];
2531 return arm_expand_builtin_1 (fcode
, exp
, target
, d
);
2534 /* Expand an expression EXP that calls a built-in function,
2535 with result going to TARGET if that's convenient
2536 (and in mode MODE if that's convenient).
2537 SUBTARGET may be used as the target for computing one of EXP's operands.
2538 IGNORE is nonzero if the value is to be ignored. */
2541 arm_expand_builtin (tree exp
,
2543 rtx subtarget ATTRIBUTE_UNUSED
,
2544 machine_mode mode ATTRIBUTE_UNUSED
,
2545 int ignore ATTRIBUTE_UNUSED
)
2547 const struct builtin_description
* d
;
2548 enum insn_code icode
;
2549 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
2557 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
2568 if (fcode
>= ARM_BUILTIN_ACLE_BASE
)
2569 return arm_expand_acle_builtin (fcode
, exp
, target
);
2571 if (fcode
>= ARM_BUILTIN_NEON_BASE
)
2572 return arm_expand_neon_builtin (fcode
, exp
, target
);
2574 if (fcode
>= ARM_BUILTIN_VFP_BASE
)
2575 return arm_expand_vfp_builtin (fcode
, exp
, target
);
2577 /* Check in the context of the function making the call whether the
2578 builtin is supported. */
2579 if (fcode
>= ARM_BUILTIN_CRYPTO_BASE
2580 && (!TARGET_CRYPTO
|| !TARGET_HARD_FLOAT
))
2582 fatal_error (input_location
,
2583 "You must enable crypto instructions"
2584 " (e.g. include -mfloat-abi=softfp -mfpu=crypto-neon...)"
2585 " to use these intrinsics.");
2591 case ARM_BUILTIN_GET_FPSCR
:
2592 case ARM_BUILTIN_SET_FPSCR
:
2593 if (fcode
== ARM_BUILTIN_GET_FPSCR
)
2595 icode
= CODE_FOR_get_fpscr
;
2596 target
= gen_reg_rtx (SImode
);
2597 pat
= GEN_FCN (icode
) (target
);
2602 icode
= CODE_FOR_set_fpscr
;
2603 arg0
= CALL_EXPR_ARG (exp
, 0);
2604 op0
= expand_normal (arg0
);
2605 pat
= GEN_FCN (icode
) (force_reg (SImode
, op0
));
2610 case ARM_BUILTIN_CMSE_NONSECURE_CALLER
:
2611 target
= gen_reg_rtx (SImode
);
2612 op0
= arm_return_addr (0, NULL_RTX
);
2613 emit_insn (gen_andsi3 (target
, op0
, const1_rtx
));
2614 op1
= gen_rtx_EQ (SImode
, target
, const0_rtx
);
2615 emit_insn (gen_cstoresi4 (target
, op1
, target
, const0_rtx
));
2618 case ARM_BUILTIN_TEXTRMSB
:
2619 case ARM_BUILTIN_TEXTRMUB
:
2620 case ARM_BUILTIN_TEXTRMSH
:
2621 case ARM_BUILTIN_TEXTRMUH
:
2622 case ARM_BUILTIN_TEXTRMSW
:
2623 case ARM_BUILTIN_TEXTRMUW
:
2624 icode
= (fcode
== ARM_BUILTIN_TEXTRMSB
? CODE_FOR_iwmmxt_textrmsb
2625 : fcode
== ARM_BUILTIN_TEXTRMUB
? CODE_FOR_iwmmxt_textrmub
2626 : fcode
== ARM_BUILTIN_TEXTRMSH
? CODE_FOR_iwmmxt_textrmsh
2627 : fcode
== ARM_BUILTIN_TEXTRMUH
? CODE_FOR_iwmmxt_textrmuh
2628 : CODE_FOR_iwmmxt_textrmw
);
2630 arg0
= CALL_EXPR_ARG (exp
, 0);
2631 arg1
= CALL_EXPR_ARG (exp
, 1);
2632 op0
= expand_normal (arg0
);
2633 op1
= expand_normal (arg1
);
2634 tmode
= insn_data
[icode
].operand
[0].mode
;
2635 mode0
= insn_data
[icode
].operand
[1].mode
;
2636 mode1
= insn_data
[icode
].operand
[2].mode
;
2638 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2639 op0
= copy_to_mode_reg (mode0
, op0
);
2640 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2642 /* @@@ better error message */
2643 error ("selector must be an immediate");
2644 return gen_reg_rtx (tmode
);
2647 opint
= INTVAL (op1
);
2648 if (fcode
== ARM_BUILTIN_TEXTRMSB
|| fcode
== ARM_BUILTIN_TEXTRMUB
)
2650 if (opint
> 7 || opint
< 0)
2651 error ("the range of selector should be in 0 to 7");
2653 else if (fcode
== ARM_BUILTIN_TEXTRMSH
|| fcode
== ARM_BUILTIN_TEXTRMUH
)
2655 if (opint
> 3 || opint
< 0)
2656 error ("the range of selector should be in 0 to 3");
2658 else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */
2660 if (opint
> 1 || opint
< 0)
2661 error ("the range of selector should be in 0 to 1");
2665 || GET_MODE (target
) != tmode
2666 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2667 target
= gen_reg_rtx (tmode
);
2668 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2674 case ARM_BUILTIN_WALIGNI
:
2675 /* If op2 is immediate, call walighi, else call walighr. */
2676 arg0
= CALL_EXPR_ARG (exp
, 0);
2677 arg1
= CALL_EXPR_ARG (exp
, 1);
2678 arg2
= CALL_EXPR_ARG (exp
, 2);
2679 op0
= expand_normal (arg0
);
2680 op1
= expand_normal (arg1
);
2681 op2
= expand_normal (arg2
);
2682 if (CONST_INT_P (op2
))
2684 icode
= CODE_FOR_iwmmxt_waligni
;
2685 tmode
= insn_data
[icode
].operand
[0].mode
;
2686 mode0
= insn_data
[icode
].operand
[1].mode
;
2687 mode1
= insn_data
[icode
].operand
[2].mode
;
2688 mode2
= insn_data
[icode
].operand
[3].mode
;
2689 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2690 op0
= copy_to_mode_reg (mode0
, op0
);
2691 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2692 op1
= copy_to_mode_reg (mode1
, op1
);
2693 gcc_assert ((*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
));
2694 selector
= INTVAL (op2
);
2695 if (selector
> 7 || selector
< 0)
2696 error ("the range of selector should be in 0 to 7");
2700 icode
= CODE_FOR_iwmmxt_walignr
;
2701 tmode
= insn_data
[icode
].operand
[0].mode
;
2702 mode0
= insn_data
[icode
].operand
[1].mode
;
2703 mode1
= insn_data
[icode
].operand
[2].mode
;
2704 mode2
= insn_data
[icode
].operand
[3].mode
;
2705 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2706 op0
= copy_to_mode_reg (mode0
, op0
);
2707 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2708 op1
= copy_to_mode_reg (mode1
, op1
);
2709 if (!(*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2710 op2
= copy_to_mode_reg (mode2
, op2
);
2713 || GET_MODE (target
) != tmode
2714 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2715 target
= gen_reg_rtx (tmode
);
2716 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2722 case ARM_BUILTIN_TINSRB
:
2723 case ARM_BUILTIN_TINSRH
:
2724 case ARM_BUILTIN_TINSRW
:
2725 case ARM_BUILTIN_WMERGE
:
2726 icode
= (fcode
== ARM_BUILTIN_TINSRB
? CODE_FOR_iwmmxt_tinsrb
2727 : fcode
== ARM_BUILTIN_TINSRH
? CODE_FOR_iwmmxt_tinsrh
2728 : fcode
== ARM_BUILTIN_WMERGE
? CODE_FOR_iwmmxt_wmerge
2729 : CODE_FOR_iwmmxt_tinsrw
);
2730 arg0
= CALL_EXPR_ARG (exp
, 0);
2731 arg1
= CALL_EXPR_ARG (exp
, 1);
2732 arg2
= CALL_EXPR_ARG (exp
, 2);
2733 op0
= expand_normal (arg0
);
2734 op1
= expand_normal (arg1
);
2735 op2
= expand_normal (arg2
);
2736 tmode
= insn_data
[icode
].operand
[0].mode
;
2737 mode0
= insn_data
[icode
].operand
[1].mode
;
2738 mode1
= insn_data
[icode
].operand
[2].mode
;
2739 mode2
= insn_data
[icode
].operand
[3].mode
;
2741 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2742 op0
= copy_to_mode_reg (mode0
, op0
);
2743 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2744 op1
= copy_to_mode_reg (mode1
, op1
);
2745 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2747 error ("selector must be an immediate");
2750 if (icode
== CODE_FOR_iwmmxt_wmerge
)
2752 selector
= INTVAL (op2
);
2753 if (selector
> 7 || selector
< 0)
2754 error ("the range of selector should be in 0 to 7");
2756 if ((icode
== CODE_FOR_iwmmxt_tinsrb
)
2757 || (icode
== CODE_FOR_iwmmxt_tinsrh
)
2758 || (icode
== CODE_FOR_iwmmxt_tinsrw
))
2761 selector
= INTVAL (op2
);
2762 if (icode
== CODE_FOR_iwmmxt_tinsrb
&& (selector
< 0 || selector
> 7))
2763 error ("the range of selector should be in 0 to 7");
2764 else if (icode
== CODE_FOR_iwmmxt_tinsrh
&& (selector
< 0 ||selector
> 3))
2765 error ("the range of selector should be in 0 to 3");
2766 else if (icode
== CODE_FOR_iwmmxt_tinsrw
&& (selector
< 0 ||selector
> 1))
2767 error ("the range of selector should be in 0 to 1");
2769 op2
= GEN_INT (mask
);
2772 || GET_MODE (target
) != tmode
2773 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2774 target
= gen_reg_rtx (tmode
);
2775 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2781 case ARM_BUILTIN_SETWCGR0
:
2782 case ARM_BUILTIN_SETWCGR1
:
2783 case ARM_BUILTIN_SETWCGR2
:
2784 case ARM_BUILTIN_SETWCGR3
:
2785 icode
= (fcode
== ARM_BUILTIN_SETWCGR0
? CODE_FOR_iwmmxt_setwcgr0
2786 : fcode
== ARM_BUILTIN_SETWCGR1
? CODE_FOR_iwmmxt_setwcgr1
2787 : fcode
== ARM_BUILTIN_SETWCGR2
? CODE_FOR_iwmmxt_setwcgr2
2788 : CODE_FOR_iwmmxt_setwcgr3
);
2789 arg0
= CALL_EXPR_ARG (exp
, 0);
2790 op0
= expand_normal (arg0
);
2791 mode0
= insn_data
[icode
].operand
[0].mode
;
2792 if (!(*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
2793 op0
= copy_to_mode_reg (mode0
, op0
);
2794 pat
= GEN_FCN (icode
) (op0
);
2800 case ARM_BUILTIN_GETWCGR0
:
2801 case ARM_BUILTIN_GETWCGR1
:
2802 case ARM_BUILTIN_GETWCGR2
:
2803 case ARM_BUILTIN_GETWCGR3
:
2804 icode
= (fcode
== ARM_BUILTIN_GETWCGR0
? CODE_FOR_iwmmxt_getwcgr0
2805 : fcode
== ARM_BUILTIN_GETWCGR1
? CODE_FOR_iwmmxt_getwcgr1
2806 : fcode
== ARM_BUILTIN_GETWCGR2
? CODE_FOR_iwmmxt_getwcgr2
2807 : CODE_FOR_iwmmxt_getwcgr3
);
2808 tmode
= insn_data
[icode
].operand
[0].mode
;
2810 || GET_MODE (target
) != tmode
2811 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2812 target
= gen_reg_rtx (tmode
);
2813 pat
= GEN_FCN (icode
) (target
);
2819 case ARM_BUILTIN_WSHUFH
:
2820 icode
= CODE_FOR_iwmmxt_wshufh
;
2821 arg0
= CALL_EXPR_ARG (exp
, 0);
2822 arg1
= CALL_EXPR_ARG (exp
, 1);
2823 op0
= expand_normal (arg0
);
2824 op1
= expand_normal (arg1
);
2825 tmode
= insn_data
[icode
].operand
[0].mode
;
2826 mode1
= insn_data
[icode
].operand
[1].mode
;
2827 mode2
= insn_data
[icode
].operand
[2].mode
;
2829 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode1
))
2830 op0
= copy_to_mode_reg (mode1
, op0
);
2831 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode2
))
2833 error ("mask must be an immediate");
2836 selector
= INTVAL (op1
);
2837 if (selector
< 0 || selector
> 255)
2838 error ("the range of mask should be in 0 to 255");
2840 || GET_MODE (target
) != tmode
2841 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2842 target
= gen_reg_rtx (tmode
);
2843 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2849 case ARM_BUILTIN_WMADDS
:
2850 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds
, exp
, target
);
2851 case ARM_BUILTIN_WMADDSX
:
2852 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx
, exp
, target
);
2853 case ARM_BUILTIN_WMADDSN
:
2854 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn
, exp
, target
);
2855 case ARM_BUILTIN_WMADDU
:
2856 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu
, exp
, target
);
2857 case ARM_BUILTIN_WMADDUX
:
2858 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux
, exp
, target
);
2859 case ARM_BUILTIN_WMADDUN
:
2860 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun
, exp
, target
);
2861 case ARM_BUILTIN_WSADBZ
:
2862 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz
, exp
, target
);
2863 case ARM_BUILTIN_WSADHZ
:
2864 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz
, exp
, target
);
2866 /* Several three-argument builtins. */
2867 case ARM_BUILTIN_WMACS
:
2868 case ARM_BUILTIN_WMACU
:
2869 case ARM_BUILTIN_TMIA
:
2870 case ARM_BUILTIN_TMIAPH
:
2871 case ARM_BUILTIN_TMIATT
:
2872 case ARM_BUILTIN_TMIATB
:
2873 case ARM_BUILTIN_TMIABT
:
2874 case ARM_BUILTIN_TMIABB
:
2875 case ARM_BUILTIN_WQMIABB
:
2876 case ARM_BUILTIN_WQMIABT
:
2877 case ARM_BUILTIN_WQMIATB
:
2878 case ARM_BUILTIN_WQMIATT
:
2879 case ARM_BUILTIN_WQMIABBN
:
2880 case ARM_BUILTIN_WQMIABTN
:
2881 case ARM_BUILTIN_WQMIATBN
:
2882 case ARM_BUILTIN_WQMIATTN
:
2883 case ARM_BUILTIN_WMIABB
:
2884 case ARM_BUILTIN_WMIABT
:
2885 case ARM_BUILTIN_WMIATB
:
2886 case ARM_BUILTIN_WMIATT
:
2887 case ARM_BUILTIN_WMIABBN
:
2888 case ARM_BUILTIN_WMIABTN
:
2889 case ARM_BUILTIN_WMIATBN
:
2890 case ARM_BUILTIN_WMIATTN
:
2891 case ARM_BUILTIN_WMIAWBB
:
2892 case ARM_BUILTIN_WMIAWBT
:
2893 case ARM_BUILTIN_WMIAWTB
:
2894 case ARM_BUILTIN_WMIAWTT
:
2895 case ARM_BUILTIN_WMIAWBBN
:
2896 case ARM_BUILTIN_WMIAWBTN
:
2897 case ARM_BUILTIN_WMIAWTBN
:
2898 case ARM_BUILTIN_WMIAWTTN
:
2899 case ARM_BUILTIN_WSADB
:
2900 case ARM_BUILTIN_WSADH
:
2901 icode
= (fcode
== ARM_BUILTIN_WMACS
? CODE_FOR_iwmmxt_wmacs
2902 : fcode
== ARM_BUILTIN_WMACU
? CODE_FOR_iwmmxt_wmacu
2903 : fcode
== ARM_BUILTIN_TMIA
? CODE_FOR_iwmmxt_tmia
2904 : fcode
== ARM_BUILTIN_TMIAPH
? CODE_FOR_iwmmxt_tmiaph
2905 : fcode
== ARM_BUILTIN_TMIABB
? CODE_FOR_iwmmxt_tmiabb
2906 : fcode
== ARM_BUILTIN_TMIABT
? CODE_FOR_iwmmxt_tmiabt
2907 : fcode
== ARM_BUILTIN_TMIATB
? CODE_FOR_iwmmxt_tmiatb
2908 : fcode
== ARM_BUILTIN_TMIATT
? CODE_FOR_iwmmxt_tmiatt
2909 : fcode
== ARM_BUILTIN_WQMIABB
? CODE_FOR_iwmmxt_wqmiabb
2910 : fcode
== ARM_BUILTIN_WQMIABT
? CODE_FOR_iwmmxt_wqmiabt
2911 : fcode
== ARM_BUILTIN_WQMIATB
? CODE_FOR_iwmmxt_wqmiatb
2912 : fcode
== ARM_BUILTIN_WQMIATT
? CODE_FOR_iwmmxt_wqmiatt
2913 : fcode
== ARM_BUILTIN_WQMIABBN
? CODE_FOR_iwmmxt_wqmiabbn
2914 : fcode
== ARM_BUILTIN_WQMIABTN
? CODE_FOR_iwmmxt_wqmiabtn
2915 : fcode
== ARM_BUILTIN_WQMIATBN
? CODE_FOR_iwmmxt_wqmiatbn
2916 : fcode
== ARM_BUILTIN_WQMIATTN
? CODE_FOR_iwmmxt_wqmiattn
2917 : fcode
== ARM_BUILTIN_WMIABB
? CODE_FOR_iwmmxt_wmiabb
2918 : fcode
== ARM_BUILTIN_WMIABT
? CODE_FOR_iwmmxt_wmiabt
2919 : fcode
== ARM_BUILTIN_WMIATB
? CODE_FOR_iwmmxt_wmiatb
2920 : fcode
== ARM_BUILTIN_WMIATT
? CODE_FOR_iwmmxt_wmiatt
2921 : fcode
== ARM_BUILTIN_WMIABBN
? CODE_FOR_iwmmxt_wmiabbn
2922 : fcode
== ARM_BUILTIN_WMIABTN
? CODE_FOR_iwmmxt_wmiabtn
2923 : fcode
== ARM_BUILTIN_WMIATBN
? CODE_FOR_iwmmxt_wmiatbn
2924 : fcode
== ARM_BUILTIN_WMIATTN
? CODE_FOR_iwmmxt_wmiattn
2925 : fcode
== ARM_BUILTIN_WMIAWBB
? CODE_FOR_iwmmxt_wmiawbb
2926 : fcode
== ARM_BUILTIN_WMIAWBT
? CODE_FOR_iwmmxt_wmiawbt
2927 : fcode
== ARM_BUILTIN_WMIAWTB
? CODE_FOR_iwmmxt_wmiawtb
2928 : fcode
== ARM_BUILTIN_WMIAWTT
? CODE_FOR_iwmmxt_wmiawtt
2929 : fcode
== ARM_BUILTIN_WMIAWBBN
? CODE_FOR_iwmmxt_wmiawbbn
2930 : fcode
== ARM_BUILTIN_WMIAWBTN
? CODE_FOR_iwmmxt_wmiawbtn
2931 : fcode
== ARM_BUILTIN_WMIAWTBN
? CODE_FOR_iwmmxt_wmiawtbn
2932 : fcode
== ARM_BUILTIN_WMIAWTTN
? CODE_FOR_iwmmxt_wmiawttn
2933 : fcode
== ARM_BUILTIN_WSADB
? CODE_FOR_iwmmxt_wsadb
2934 : CODE_FOR_iwmmxt_wsadh
);
2935 arg0
= CALL_EXPR_ARG (exp
, 0);
2936 arg1
= CALL_EXPR_ARG (exp
, 1);
2937 arg2
= CALL_EXPR_ARG (exp
, 2);
2938 op0
= expand_normal (arg0
);
2939 op1
= expand_normal (arg1
);
2940 op2
= expand_normal (arg2
);
2941 tmode
= insn_data
[icode
].operand
[0].mode
;
2942 mode0
= insn_data
[icode
].operand
[1].mode
;
2943 mode1
= insn_data
[icode
].operand
[2].mode
;
2944 mode2
= insn_data
[icode
].operand
[3].mode
;
2946 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2947 op0
= copy_to_mode_reg (mode0
, op0
);
2948 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2949 op1
= copy_to_mode_reg (mode1
, op1
);
2950 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2951 op2
= copy_to_mode_reg (mode2
, op2
);
2953 || GET_MODE (target
) != tmode
2954 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2955 target
= gen_reg_rtx (tmode
);
2956 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2962 case ARM_BUILTIN_WZERO
:
2963 target
= gen_reg_rtx (DImode
);
2964 emit_insn (gen_iwmmxt_clrdi (target
));
2967 case ARM_BUILTIN_WSRLHI
:
2968 case ARM_BUILTIN_WSRLWI
:
2969 case ARM_BUILTIN_WSRLDI
:
2970 case ARM_BUILTIN_WSLLHI
:
2971 case ARM_BUILTIN_WSLLWI
:
2972 case ARM_BUILTIN_WSLLDI
:
2973 case ARM_BUILTIN_WSRAHI
:
2974 case ARM_BUILTIN_WSRAWI
:
2975 case ARM_BUILTIN_WSRADI
:
2976 case ARM_BUILTIN_WRORHI
:
2977 case ARM_BUILTIN_WRORWI
:
2978 case ARM_BUILTIN_WRORDI
:
2979 case ARM_BUILTIN_WSRLH
:
2980 case ARM_BUILTIN_WSRLW
:
2981 case ARM_BUILTIN_WSRLD
:
2982 case ARM_BUILTIN_WSLLH
:
2983 case ARM_BUILTIN_WSLLW
:
2984 case ARM_BUILTIN_WSLLD
:
2985 case ARM_BUILTIN_WSRAH
:
2986 case ARM_BUILTIN_WSRAW
:
2987 case ARM_BUILTIN_WSRAD
:
2988 case ARM_BUILTIN_WRORH
:
2989 case ARM_BUILTIN_WRORW
:
2990 case ARM_BUILTIN_WRORD
:
2991 icode
= (fcode
== ARM_BUILTIN_WSRLHI
? CODE_FOR_lshrv4hi3_iwmmxt
2992 : fcode
== ARM_BUILTIN_WSRLWI
? CODE_FOR_lshrv2si3_iwmmxt
2993 : fcode
== ARM_BUILTIN_WSRLDI
? CODE_FOR_lshrdi3_iwmmxt
2994 : fcode
== ARM_BUILTIN_WSLLHI
? CODE_FOR_ashlv4hi3_iwmmxt
2995 : fcode
== ARM_BUILTIN_WSLLWI
? CODE_FOR_ashlv2si3_iwmmxt
2996 : fcode
== ARM_BUILTIN_WSLLDI
? CODE_FOR_ashldi3_iwmmxt
2997 : fcode
== ARM_BUILTIN_WSRAHI
? CODE_FOR_ashrv4hi3_iwmmxt
2998 : fcode
== ARM_BUILTIN_WSRAWI
? CODE_FOR_ashrv2si3_iwmmxt
2999 : fcode
== ARM_BUILTIN_WSRADI
? CODE_FOR_ashrdi3_iwmmxt
3000 : fcode
== ARM_BUILTIN_WRORHI
? CODE_FOR_rorv4hi3
3001 : fcode
== ARM_BUILTIN_WRORWI
? CODE_FOR_rorv2si3
3002 : fcode
== ARM_BUILTIN_WRORDI
? CODE_FOR_rordi3
3003 : fcode
== ARM_BUILTIN_WSRLH
? CODE_FOR_lshrv4hi3_di
3004 : fcode
== ARM_BUILTIN_WSRLW
? CODE_FOR_lshrv2si3_di
3005 : fcode
== ARM_BUILTIN_WSRLD
? CODE_FOR_lshrdi3_di
3006 : fcode
== ARM_BUILTIN_WSLLH
? CODE_FOR_ashlv4hi3_di
3007 : fcode
== ARM_BUILTIN_WSLLW
? CODE_FOR_ashlv2si3_di
3008 : fcode
== ARM_BUILTIN_WSLLD
? CODE_FOR_ashldi3_di
3009 : fcode
== ARM_BUILTIN_WSRAH
? CODE_FOR_ashrv4hi3_di
3010 : fcode
== ARM_BUILTIN_WSRAW
? CODE_FOR_ashrv2si3_di
3011 : fcode
== ARM_BUILTIN_WSRAD
? CODE_FOR_ashrdi3_di
3012 : fcode
== ARM_BUILTIN_WRORH
? CODE_FOR_rorv4hi3_di
3013 : fcode
== ARM_BUILTIN_WRORW
? CODE_FOR_rorv2si3_di
3014 : fcode
== ARM_BUILTIN_WRORD
? CODE_FOR_rordi3_di
3015 : CODE_FOR_nothing
);
3016 arg1
= CALL_EXPR_ARG (exp
, 1);
3017 op1
= expand_normal (arg1
);
3018 if (GET_MODE (op1
) == VOIDmode
)
3021 if ((fcode
== ARM_BUILTIN_WRORHI
|| fcode
== ARM_BUILTIN_WRORWI
3022 || fcode
== ARM_BUILTIN_WRORH
|| fcode
== ARM_BUILTIN_WRORW
)
3023 && (imm
< 0 || imm
> 32))
3025 if (fcode
== ARM_BUILTIN_WRORHI
)
3026 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi16 in code.");
3027 else if (fcode
== ARM_BUILTIN_WRORWI
)
3028 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi32 in code.");
3029 else if (fcode
== ARM_BUILTIN_WRORH
)
3030 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi16 in code.");
3032 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi32 in code.");
3034 else if ((fcode
== ARM_BUILTIN_WRORDI
|| fcode
== ARM_BUILTIN_WRORD
)
3035 && (imm
< 0 || imm
> 64))
3037 if (fcode
== ARM_BUILTIN_WRORDI
)
3038 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_rori_si64 in code.");
3040 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_ror_si64 in code.");
3044 if (fcode
== ARM_BUILTIN_WSRLHI
)
3045 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi16 in code.");
3046 else if (fcode
== ARM_BUILTIN_WSRLWI
)
3047 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi32 in code.");
3048 else if (fcode
== ARM_BUILTIN_WSRLDI
)
3049 error ("the count should be no less than 0. please check the intrinsic _mm_srli_si64 in code.");
3050 else if (fcode
== ARM_BUILTIN_WSLLHI
)
3051 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi16 in code.");
3052 else if (fcode
== ARM_BUILTIN_WSLLWI
)
3053 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi32 in code.");
3054 else if (fcode
== ARM_BUILTIN_WSLLDI
)
3055 error ("the count should be no less than 0. please check the intrinsic _mm_slli_si64 in code.");
3056 else if (fcode
== ARM_BUILTIN_WSRAHI
)
3057 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi16 in code.");
3058 else if (fcode
== ARM_BUILTIN_WSRAWI
)
3059 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi32 in code.");
3060 else if (fcode
== ARM_BUILTIN_WSRADI
)
3061 error ("the count should be no less than 0. please check the intrinsic _mm_srai_si64 in code.");
3062 else if (fcode
== ARM_BUILTIN_WSRLH
)
3063 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi16 in code.");
3064 else if (fcode
== ARM_BUILTIN_WSRLW
)
3065 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi32 in code.");
3066 else if (fcode
== ARM_BUILTIN_WSRLD
)
3067 error ("the count should be no less than 0. please check the intrinsic _mm_srl_si64 in code.");
3068 else if (fcode
== ARM_BUILTIN_WSLLH
)
3069 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi16 in code.");
3070 else if (fcode
== ARM_BUILTIN_WSLLW
)
3071 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi32 in code.");
3072 else if (fcode
== ARM_BUILTIN_WSLLD
)
3073 error ("the count should be no less than 0. please check the intrinsic _mm_sll_si64 in code.");
3074 else if (fcode
== ARM_BUILTIN_WSRAH
)
3075 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi16 in code.");
3076 else if (fcode
== ARM_BUILTIN_WSRAW
)
3077 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi32 in code.");
3079 error ("the count should be no less than 0. please check the intrinsic _mm_sra_si64 in code.");
3082 return arm_expand_binop_builtin (icode
, exp
, target
);
3088 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
3089 if (d
->code
== (enum arm_builtins
) fcode
)
3090 return arm_expand_binop_builtin (d
->icode
, exp
, target
);
3092 for (i
= 0, d
= bdesc_1arg
; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
3093 if (d
->code
== (enum arm_builtins
) fcode
)
3094 return arm_expand_unop_builtin (d
->icode
, exp
, target
, 0);
3096 for (i
= 0, d
= bdesc_3arg
; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
3097 if (d
->code
== (enum arm_builtins
) fcode
)
3098 return arm_expand_ternop_builtin (d
->icode
, exp
, target
);
3100 /* @@@ Should really do something sensible here. */
3105 arm_builtin_vectorized_function (unsigned int fn
, tree type_out
, tree type_in
)
3107 machine_mode in_mode
, out_mode
;
3109 bool out_unsigned_p
= TYPE_UNSIGNED (type_out
);
3111 /* Can't provide any vectorized builtins when we can't use NEON. */
3115 if (TREE_CODE (type_out
) != VECTOR_TYPE
3116 || TREE_CODE (type_in
) != VECTOR_TYPE
)
3119 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3120 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
3121 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3122 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3124 /* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the
3125 decl of the vectorized builtin for the appropriate vector mode.
3126 NULL_TREE is returned if no such builtin is available. */
3127 #undef ARM_CHECK_BUILTIN_MODE
3128 #define ARM_CHECK_BUILTIN_MODE(C) \
3130 && flag_unsafe_math_optimizations \
3131 && ARM_CHECK_BUILTIN_MODE_1 (C))
3133 #undef ARM_CHECK_BUILTIN_MODE_1
3134 #define ARM_CHECK_BUILTIN_MODE_1(C) \
3135 (out_mode == SFmode && out_n == C \
3136 && in_mode == SFmode && in_n == C)
3138 #undef ARM_FIND_VRINT_VARIANT
3139 #define ARM_FIND_VRINT_VARIANT(N) \
3140 (ARM_CHECK_BUILTIN_MODE (2) \
3141 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \
3142 : (ARM_CHECK_BUILTIN_MODE (4) \
3143 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \
3149 return ARM_FIND_VRINT_VARIANT (vrintm
);
3151 return ARM_FIND_VRINT_VARIANT (vrintp
);
3153 return ARM_FIND_VRINT_VARIANT (vrintz
);
3155 return ARM_FIND_VRINT_VARIANT (vrinta
);
3156 #undef ARM_CHECK_BUILTIN_MODE_1
3157 #define ARM_CHECK_BUILTIN_MODE_1(C) \
3158 (out_mode == SImode && out_n == C \
3159 && in_mode == SFmode && in_n == C)
3161 #define ARM_FIND_VCVT_VARIANT(N) \
3162 (ARM_CHECK_BUILTIN_MODE (2) \
3163 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sfv2si, false) \
3164 : (ARM_CHECK_BUILTIN_MODE (4) \
3165 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sfv4si, false) \
3168 #define ARM_FIND_VCVTU_VARIANT(N) \
3169 (ARM_CHECK_BUILTIN_MODE (2) \
3170 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv2sfv2si, false) \
3171 : (ARM_CHECK_BUILTIN_MODE (4) \
3172 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \
3175 return (out_unsigned_p
3176 ? ARM_FIND_VCVTU_VARIANT (vcvta
)
3177 : ARM_FIND_VCVT_VARIANT (vcvta
));
3179 return (out_unsigned_p
3180 ? ARM_FIND_VCVTU_VARIANT (vcvtp
)
3181 : ARM_FIND_VCVT_VARIANT (vcvtp
));
3183 return (out_unsigned_p
3184 ? ARM_FIND_VCVTU_VARIANT (vcvtm
)
3185 : ARM_FIND_VCVT_VARIANT (vcvtm
));
3186 #undef ARM_CHECK_BUILTIN_MODE
3187 #define ARM_CHECK_BUILTIN_MODE(C, N) \
3188 (out_mode == N##mode && out_n == C \
3189 && in_mode == N##mode && in_n == C)
3190 case CFN_BUILT_IN_BSWAP16
:
3191 if (ARM_CHECK_BUILTIN_MODE (4, HI
))
3192 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi
, false);
3193 else if (ARM_CHECK_BUILTIN_MODE (8, HI
))
3194 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi
, false);
3197 case CFN_BUILT_IN_BSWAP32
:
3198 if (ARM_CHECK_BUILTIN_MODE (2, SI
))
3199 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si
, false);
3200 else if (ARM_CHECK_BUILTIN_MODE (4, SI
))
3201 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si
, false);
3204 case CFN_BUILT_IN_BSWAP64
:
3205 if (ARM_CHECK_BUILTIN_MODE (2, DI
))
3206 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di
, false);
3210 if (ARM_CHECK_BUILTIN_MODE (2, SF
))
3211 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf
, false);
3212 else if (ARM_CHECK_BUILTIN_MODE (4, SF
))
3213 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf
, false);
3222 #undef ARM_FIND_VCVT_VARIANT
3223 #undef ARM_FIND_VCVTU_VARIANT
3224 #undef ARM_CHECK_BUILTIN_MODE
3225 #undef ARM_FIND_VRINT_VARIANT
3228 arm_atomic_assign_expand_fenv (tree
*hold
, tree
*clear
, tree
*update
)
3230 const unsigned ARM_FE_INVALID
= 1;
3231 const unsigned ARM_FE_DIVBYZERO
= 2;
3232 const unsigned ARM_FE_OVERFLOW
= 4;
3233 const unsigned ARM_FE_UNDERFLOW
= 8;
3234 const unsigned ARM_FE_INEXACT
= 16;
3235 const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT
= (ARM_FE_INVALID
3240 const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT
= 8;
3241 tree fenv_var
, get_fpscr
, set_fpscr
, mask
, ld_fenv
, masked_fenv
;
3242 tree new_fenv_var
, reload_fenv
, restore_fnenv
;
3243 tree update_call
, atomic_feraiseexcept
, hold_fnclex
;
3245 if (!TARGET_HARD_FLOAT
)
3248 /* Generate the equivalent of :
3249 unsigned int fenv_var;
3250 fenv_var = __builtin_arm_get_fpscr ();
3252 unsigned int masked_fenv;
3253 masked_fenv = fenv_var & mask;
3255 __builtin_arm_set_fpscr (masked_fenv); */
3257 fenv_var
= create_tmp_var_raw (unsigned_type_node
);
3258 get_fpscr
= arm_builtin_decls
[ARM_BUILTIN_GET_FPSCR
];
3259 set_fpscr
= arm_builtin_decls
[ARM_BUILTIN_SET_FPSCR
];
3260 mask
= build_int_cst (unsigned_type_node
,
3261 ~((ARM_FE_ALL_EXCEPT
<< ARM_FE_EXCEPT_SHIFT
)
3262 | ARM_FE_ALL_EXCEPT
));
3263 ld_fenv
= build2 (MODIFY_EXPR
, unsigned_type_node
,
3264 fenv_var
, build_call_expr (get_fpscr
, 0));
3265 masked_fenv
= build2 (BIT_AND_EXPR
, unsigned_type_node
, fenv_var
, mask
);
3266 hold_fnclex
= build_call_expr (set_fpscr
, 1, masked_fenv
);
3267 *hold
= build2 (COMPOUND_EXPR
, void_type_node
,
3268 build2 (COMPOUND_EXPR
, void_type_node
, masked_fenv
, ld_fenv
),
3271 /* Store the value of masked_fenv to clear the exceptions:
3272 __builtin_arm_set_fpscr (masked_fenv); */
3274 *clear
= build_call_expr (set_fpscr
, 1, masked_fenv
);
3276 /* Generate the equivalent of :
3277 unsigned int new_fenv_var;
3278 new_fenv_var = __builtin_arm_get_fpscr ();
3280 __builtin_arm_set_fpscr (fenv_var);
3282 __atomic_feraiseexcept (new_fenv_var); */
3284 new_fenv_var
= create_tmp_var_raw (unsigned_type_node
);
3285 reload_fenv
= build2 (MODIFY_EXPR
, unsigned_type_node
, new_fenv_var
,
3286 build_call_expr (get_fpscr
, 0));
3287 restore_fnenv
= build_call_expr (set_fpscr
, 1, fenv_var
);
3288 atomic_feraiseexcept
= builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT
);
3289 update_call
= build_call_expr (atomic_feraiseexcept
, 1,
3290 fold_convert (integer_type_node
, new_fenv_var
));
3291 *update
= build2 (COMPOUND_EXPR
, void_type_node
,
3292 build2 (COMPOUND_EXPR
, void_type_node
,
3293 reload_fenv
, restore_fnenv
), update_call
);
3296 #include "gt-arm-builtins.h"