]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm-builtins.c
Set FLT_EVAL_METHOD to 2 only if 387 FPU is used
[thirdparty/gcc.git] / gcc / config / arm / arm-builtins.c
CommitLineData
d6504d76 1/* Description of builtins used by the ARM backend.
f1717362 2 Copyright (C) 2014-2016 Free Software Foundation, Inc.
d6504d76 3
4 This file is part of GCC.
5
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.
10
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.
15
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/>. */
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
c1eb80de 23#include "target.h"
24#include "function.h"
d6504d76 25#include "rtl.h"
26#include "tree.h"
c1eb80de 27#include "gimple-expr.h"
28#include "tm_p.h"
29#include "optabs.h"
30#include "emit-rtl.h"
31#include "recog.h"
32#include "diagnostic-core.h"
b20a8bb4 33#include "fold-const.h"
d6504d76 34#include "stor-layout.h"
d53441c8 35#include "explow.h"
d6504d76 36#include "expr.h"
d6504d76 37#include "langhooks.h"
b6c464fe 38#include "case-cfn-macros.h"
d6504d76 39
c5f2b407 40#define SIMD_MAX_BUILTIN_ARGS 5
41
42enum arm_type_qualifiers
43{
44 /* T foo. */
45 qualifier_none = 0x0,
46 /* unsigned T foo. */
47 qualifier_unsigned = 0x1, /* 1 << 0 */
48 /* const T foo. */
49 qualifier_const = 0x2, /* 1 << 1 */
50 /* T *foo. */
51 qualifier_pointer = 0x4, /* 1 << 2 */
52 /* Used when expanding arguments if an operand could
53 be an immediate. */
54 qualifier_immediate = 0x8, /* 1 << 3 */
55 qualifier_maybe_immediate = 0x10, /* 1 << 4 */
56 /* void foo (...). */
57 qualifier_void = 0x20, /* 1 << 5 */
58 /* Some patterns may have internal operands, this qualifier is an
59 instruction to the initialisation code to skip this operand. */
60 qualifier_internal = 0x40, /* 1 << 6 */
61 /* Some builtins should use the T_*mode* encoded in a simd_builtin_datum
62 rather than using the type of the operand. */
63 qualifier_map_mode = 0x80, /* 1 << 7 */
64 /* qualifier_pointer | qualifier_map_mode */
65 qualifier_pointer_map_mode = 0x84,
66 /* qualifier_const_pointer | qualifier_map_mode */
67 qualifier_const_pointer_map_mode = 0x86,
68 /* Polynomial types. */
505e1f91 69 qualifier_poly = 0x100,
70 /* Lane indices - must be within range of previous argument = a vector. */
d4023b2c 71 qualifier_lane_index = 0x200,
72 /* Lane indices for single lane structure loads and stores. */
73 qualifier_struct_load_store_lane_index = 0x400
c5f2b407 74};
75
76/* The qualifier_internal allows generation of a unary builtin from
77 a pattern with a third pseudo-operand such as a match_scratch.
78 T (T). */
79static enum arm_type_qualifiers
80arm_unop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
81 = { qualifier_none, qualifier_none, qualifier_internal };
c5f2b407 82#define UNOP_QUALIFIERS (arm_unop_qualifiers)
83
84/* unsigned T (unsigned T). */
85static enum arm_type_qualifiers
86arm_bswap_qualifiers[SIMD_MAX_BUILTIN_ARGS]
87 = { qualifier_unsigned, qualifier_unsigned };
88#define BSWAP_QUALIFIERS (arm_bswap_qualifiers)
89
90/* T (T, T [maybe_immediate]). */
91static enum arm_type_qualifiers
92arm_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
93 = { qualifier_none, qualifier_none, qualifier_maybe_immediate };
94#define BINOP_QUALIFIERS (arm_binop_qualifiers)
c5f2b407 95
96/* T (T, T, T). */
97static enum arm_type_qualifiers
98arm_ternop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
99 = { qualifier_none, qualifier_none, qualifier_none, qualifier_none };
100#define TERNOP_QUALIFIERS (arm_ternop_qualifiers)
c5f2b407 101
102/* T (T, immediate). */
103static enum arm_type_qualifiers
505e1f91 104arm_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
c5f2b407 105 = { qualifier_none, qualifier_none, qualifier_immediate };
505e1f91 106#define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers)
107
108/* T (T, lane index). */
109static enum arm_type_qualifiers
110arm_getlane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
111 = { qualifier_none, qualifier_none, qualifier_lane_index };
c5f2b407 112#define GETLANE_QUALIFIERS (arm_getlane_qualifiers)
c5f2b407 113
114/* T (T, T, T, immediate). */
115static enum arm_type_qualifiers
505e1f91 116arm_mac_n_qualifiers[SIMD_MAX_BUILTIN_ARGS]
c5f2b407 117 = { qualifier_none, qualifier_none, qualifier_none,
118 qualifier_none, qualifier_immediate };
505e1f91 119#define MAC_N_QUALIFIERS (arm_mac_n_qualifiers)
120
121/* T (T, T, T, lane index). */
122static enum arm_type_qualifiers
123arm_mac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
124 = { qualifier_none, qualifier_none, qualifier_none,
125 qualifier_none, qualifier_lane_index };
126#define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers)
c5f2b407 127
128/* T (T, T, immediate). */
129static enum arm_type_qualifiers
505e1f91 130arm_ternop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
c5f2b407 131 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate };
505e1f91 132#define TERNOP_IMM_QUALIFIERS (arm_ternop_imm_qualifiers)
133
134/* T (T, T, lane index). */
135static enum arm_type_qualifiers
136arm_setlane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
137 = { qualifier_none, qualifier_none, qualifier_none, qualifier_lane_index };
c5f2b407 138#define SETLANE_QUALIFIERS (arm_setlane_qualifiers)
c5f2b407 139
140/* T (T, T). */
141static enum arm_type_qualifiers
142arm_combine_qualifiers[SIMD_MAX_BUILTIN_ARGS]
143 = { qualifier_none, qualifier_none, qualifier_none };
144#define COMBINE_QUALIFIERS (arm_combine_qualifiers)
c5f2b407 145
146/* T ([T element type] *). */
147static enum arm_type_qualifiers
148arm_load1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
149 = { qualifier_none, qualifier_const_pointer_map_mode };
150#define LOAD1_QUALIFIERS (arm_load1_qualifiers)
c5f2b407 151
152/* T ([T element type] *, T, immediate). */
153static enum arm_type_qualifiers
154arm_load1_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
155 = { qualifier_none, qualifier_const_pointer_map_mode,
fe8542d5 156 qualifier_none, qualifier_struct_load_store_lane_index };
c5f2b407 157#define LOAD1LANE_QUALIFIERS (arm_load1_lane_qualifiers)
c5f2b407 158
159/* The first argument (return type) of a store should be void type,
160 which we represent with qualifier_void. Their first operand will be
161 a DImode pointer to the location to store to, so we must use
162 qualifier_map_mode | qualifier_pointer to build a pointer to the
163 element type of the vector.
164
165 void ([T element type] *, T). */
166static enum arm_type_qualifiers
167arm_store1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
168 = { qualifier_void, qualifier_pointer_map_mode, qualifier_none };
169#define STORE1_QUALIFIERS (arm_store1_qualifiers)
c5f2b407 170
171 /* void ([T element type] *, T, immediate). */
172static enum arm_type_qualifiers
173arm_storestruct_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
174 = { qualifier_void, qualifier_pointer_map_mode,
fe8542d5 175 qualifier_none, qualifier_struct_load_store_lane_index };
c5f2b407 176#define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers)
c5f2b407 177
c7796b7e 178#define v8qi_UP V8QImode
179#define v4hi_UP V4HImode
180#define v4hf_UP V4HFmode
181#define v2si_UP V2SImode
182#define v2sf_UP V2SFmode
183#define di_UP DImode
184#define v16qi_UP V16QImode
185#define v8hi_UP V8HImode
60712275 186#define v8hf_UP V8HFmode
c7796b7e 187#define v4si_UP V4SImode
188#define v4sf_UP V4SFmode
189#define v2di_UP V2DImode
190#define ti_UP TImode
191#define ei_UP EImode
192#define oi_UP OImode
d6504d76 193
194#define UP(X) X##_UP
195
d6504d76 196typedef struct {
197 const char *name;
c7796b7e 198 machine_mode mode;
d6504d76 199 const enum insn_code code;
200 unsigned int fcode;
c5f2b407 201 enum arm_type_qualifiers *qualifiers;
d6504d76 202} neon_builtin_datum;
203
204#define CF(N,X) CODE_FOR_neon_##N##X
205
206#define VAR1(T, N, A) \
c7796b7e 207 {#N #A, UP (A), CF (N, A), 0, T##_QUALIFIERS},
d6504d76 208#define VAR2(T, N, A, B) \
e0b44776 209 VAR1 (T, N, A) \
210 VAR1 (T, N, B)
d6504d76 211#define VAR3(T, N, A, B, C) \
e0b44776 212 VAR2 (T, N, A, B) \
213 VAR1 (T, N, C)
d6504d76 214#define VAR4(T, N, A, B, C, D) \
e0b44776 215 VAR3 (T, N, A, B, C) \
216 VAR1 (T, N, D)
d6504d76 217#define VAR5(T, N, A, B, C, D, E) \
e0b44776 218 VAR4 (T, N, A, B, C, D) \
219 VAR1 (T, N, E)
d6504d76 220#define VAR6(T, N, A, B, C, D, E, F) \
e0b44776 221 VAR5 (T, N, A, B, C, D, E) \
222 VAR1 (T, N, F)
d6504d76 223#define VAR7(T, N, A, B, C, D, E, F, G) \
e0b44776 224 VAR6 (T, N, A, B, C, D, E, F) \
225 VAR1 (T, N, G)
d6504d76 226#define VAR8(T, N, A, B, C, D, E, F, G, H) \
e0b44776 227 VAR7 (T, N, A, B, C, D, E, F, G) \
228 VAR1 (T, N, H)
d6504d76 229#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
e0b44776 230 VAR8 (T, N, A, B, C, D, E, F, G, H) \
231 VAR1 (T, N, I)
d6504d76 232#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
e0b44776 233 VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
234 VAR1 (T, N, J)
fb5f110d 235#define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \
236 VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \
237 VAR1 (T, N, K)
238#define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
239 VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
240 VAR1 (T, N, L)
d6504d76 241
242/* The NEON builtin data can be found in arm_neon_builtins.def.
243 The mode entries in the following table correspond to the "key" type of the
244 instruction variant, i.e. equivalent to that which would be specified after
245 the assembler mnemonic, which usually refers to the last vector operand.
c7796b7e 246 The modes listed per instruction should be the same as those defined for
247 that instruction's pattern in neon.md. */
d6504d76 248
249static neon_builtin_datum neon_builtin_data[] =
250{
251#include "arm_neon_builtins.def"
252};
253
254#undef CF
255#undef VAR1
d6504d76 256
e0b44776 257#define VAR1(T, N, X) \
258 ARM_BUILTIN_NEON_##N##X,
259
d6504d76 260enum arm_builtins
261{
262 ARM_BUILTIN_GETWCGR0,
263 ARM_BUILTIN_GETWCGR1,
264 ARM_BUILTIN_GETWCGR2,
265 ARM_BUILTIN_GETWCGR3,
266
267 ARM_BUILTIN_SETWCGR0,
268 ARM_BUILTIN_SETWCGR1,
269 ARM_BUILTIN_SETWCGR2,
270 ARM_BUILTIN_SETWCGR3,
271
272 ARM_BUILTIN_WZERO,
273
274 ARM_BUILTIN_WAVG2BR,
275 ARM_BUILTIN_WAVG2HR,
276 ARM_BUILTIN_WAVG2B,
277 ARM_BUILTIN_WAVG2H,
278
279 ARM_BUILTIN_WACCB,
280 ARM_BUILTIN_WACCH,
281 ARM_BUILTIN_WACCW,
282
283 ARM_BUILTIN_WMACS,
284 ARM_BUILTIN_WMACSZ,
285 ARM_BUILTIN_WMACU,
286 ARM_BUILTIN_WMACUZ,
287
288 ARM_BUILTIN_WSADB,
289 ARM_BUILTIN_WSADBZ,
290 ARM_BUILTIN_WSADH,
291 ARM_BUILTIN_WSADHZ,
292
293 ARM_BUILTIN_WALIGNI,
294 ARM_BUILTIN_WALIGNR0,
295 ARM_BUILTIN_WALIGNR1,
296 ARM_BUILTIN_WALIGNR2,
297 ARM_BUILTIN_WALIGNR3,
298
299 ARM_BUILTIN_TMIA,
300 ARM_BUILTIN_TMIAPH,
301 ARM_BUILTIN_TMIABB,
302 ARM_BUILTIN_TMIABT,
303 ARM_BUILTIN_TMIATB,
304 ARM_BUILTIN_TMIATT,
305
306 ARM_BUILTIN_TMOVMSKB,
307 ARM_BUILTIN_TMOVMSKH,
308 ARM_BUILTIN_TMOVMSKW,
309
310 ARM_BUILTIN_TBCSTB,
311 ARM_BUILTIN_TBCSTH,
312 ARM_BUILTIN_TBCSTW,
313
314 ARM_BUILTIN_WMADDS,
315 ARM_BUILTIN_WMADDU,
316
317 ARM_BUILTIN_WPACKHSS,
318 ARM_BUILTIN_WPACKWSS,
319 ARM_BUILTIN_WPACKDSS,
320 ARM_BUILTIN_WPACKHUS,
321 ARM_BUILTIN_WPACKWUS,
322 ARM_BUILTIN_WPACKDUS,
323
324 ARM_BUILTIN_WADDB,
325 ARM_BUILTIN_WADDH,
326 ARM_BUILTIN_WADDW,
327 ARM_BUILTIN_WADDSSB,
328 ARM_BUILTIN_WADDSSH,
329 ARM_BUILTIN_WADDSSW,
330 ARM_BUILTIN_WADDUSB,
331 ARM_BUILTIN_WADDUSH,
332 ARM_BUILTIN_WADDUSW,
333 ARM_BUILTIN_WSUBB,
334 ARM_BUILTIN_WSUBH,
335 ARM_BUILTIN_WSUBW,
336 ARM_BUILTIN_WSUBSSB,
337 ARM_BUILTIN_WSUBSSH,
338 ARM_BUILTIN_WSUBSSW,
339 ARM_BUILTIN_WSUBUSB,
340 ARM_BUILTIN_WSUBUSH,
341 ARM_BUILTIN_WSUBUSW,
342
343 ARM_BUILTIN_WAND,
344 ARM_BUILTIN_WANDN,
345 ARM_BUILTIN_WOR,
346 ARM_BUILTIN_WXOR,
347
348 ARM_BUILTIN_WCMPEQB,
349 ARM_BUILTIN_WCMPEQH,
350 ARM_BUILTIN_WCMPEQW,
351 ARM_BUILTIN_WCMPGTUB,
352 ARM_BUILTIN_WCMPGTUH,
353 ARM_BUILTIN_WCMPGTUW,
354 ARM_BUILTIN_WCMPGTSB,
355 ARM_BUILTIN_WCMPGTSH,
356 ARM_BUILTIN_WCMPGTSW,
357
358 ARM_BUILTIN_TEXTRMSB,
359 ARM_BUILTIN_TEXTRMSH,
360 ARM_BUILTIN_TEXTRMSW,
361 ARM_BUILTIN_TEXTRMUB,
362 ARM_BUILTIN_TEXTRMUH,
363 ARM_BUILTIN_TEXTRMUW,
364 ARM_BUILTIN_TINSRB,
365 ARM_BUILTIN_TINSRH,
366 ARM_BUILTIN_TINSRW,
367
368 ARM_BUILTIN_WMAXSW,
369 ARM_BUILTIN_WMAXSH,
370 ARM_BUILTIN_WMAXSB,
371 ARM_BUILTIN_WMAXUW,
372 ARM_BUILTIN_WMAXUH,
373 ARM_BUILTIN_WMAXUB,
374 ARM_BUILTIN_WMINSW,
375 ARM_BUILTIN_WMINSH,
376 ARM_BUILTIN_WMINSB,
377 ARM_BUILTIN_WMINUW,
378 ARM_BUILTIN_WMINUH,
379 ARM_BUILTIN_WMINUB,
380
381 ARM_BUILTIN_WMULUM,
382 ARM_BUILTIN_WMULSM,
383 ARM_BUILTIN_WMULUL,
384
385 ARM_BUILTIN_PSADBH,
386 ARM_BUILTIN_WSHUFH,
387
388 ARM_BUILTIN_WSLLH,
389 ARM_BUILTIN_WSLLW,
390 ARM_BUILTIN_WSLLD,
391 ARM_BUILTIN_WSRAH,
392 ARM_BUILTIN_WSRAW,
393 ARM_BUILTIN_WSRAD,
394 ARM_BUILTIN_WSRLH,
395 ARM_BUILTIN_WSRLW,
396 ARM_BUILTIN_WSRLD,
397 ARM_BUILTIN_WRORH,
398 ARM_BUILTIN_WRORW,
399 ARM_BUILTIN_WRORD,
400 ARM_BUILTIN_WSLLHI,
401 ARM_BUILTIN_WSLLWI,
402 ARM_BUILTIN_WSLLDI,
403 ARM_BUILTIN_WSRAHI,
404 ARM_BUILTIN_WSRAWI,
405 ARM_BUILTIN_WSRADI,
406 ARM_BUILTIN_WSRLHI,
407 ARM_BUILTIN_WSRLWI,
408 ARM_BUILTIN_WSRLDI,
409 ARM_BUILTIN_WRORHI,
410 ARM_BUILTIN_WRORWI,
411 ARM_BUILTIN_WRORDI,
412
413 ARM_BUILTIN_WUNPCKIHB,
414 ARM_BUILTIN_WUNPCKIHH,
415 ARM_BUILTIN_WUNPCKIHW,
416 ARM_BUILTIN_WUNPCKILB,
417 ARM_BUILTIN_WUNPCKILH,
418 ARM_BUILTIN_WUNPCKILW,
419
420 ARM_BUILTIN_WUNPCKEHSB,
421 ARM_BUILTIN_WUNPCKEHSH,
422 ARM_BUILTIN_WUNPCKEHSW,
423 ARM_BUILTIN_WUNPCKEHUB,
424 ARM_BUILTIN_WUNPCKEHUH,
425 ARM_BUILTIN_WUNPCKEHUW,
426 ARM_BUILTIN_WUNPCKELSB,
427 ARM_BUILTIN_WUNPCKELSH,
428 ARM_BUILTIN_WUNPCKELSW,
429 ARM_BUILTIN_WUNPCKELUB,
430 ARM_BUILTIN_WUNPCKELUH,
431 ARM_BUILTIN_WUNPCKELUW,
432
433 ARM_BUILTIN_WABSB,
434 ARM_BUILTIN_WABSH,
435 ARM_BUILTIN_WABSW,
436
437 ARM_BUILTIN_WADDSUBHX,
438 ARM_BUILTIN_WSUBADDHX,
439
440 ARM_BUILTIN_WABSDIFFB,
441 ARM_BUILTIN_WABSDIFFH,
442 ARM_BUILTIN_WABSDIFFW,
443
444 ARM_BUILTIN_WADDCH,
445 ARM_BUILTIN_WADDCW,
446
447 ARM_BUILTIN_WAVG4,
448 ARM_BUILTIN_WAVG4R,
449
450 ARM_BUILTIN_WMADDSX,
451 ARM_BUILTIN_WMADDUX,
452
453 ARM_BUILTIN_WMADDSN,
454 ARM_BUILTIN_WMADDUN,
455
456 ARM_BUILTIN_WMULWSM,
457 ARM_BUILTIN_WMULWUM,
458
459 ARM_BUILTIN_WMULWSMR,
460 ARM_BUILTIN_WMULWUMR,
461
462 ARM_BUILTIN_WMULWL,
463
464 ARM_BUILTIN_WMULSMR,
465 ARM_BUILTIN_WMULUMR,
466
467 ARM_BUILTIN_WQMULM,
468 ARM_BUILTIN_WQMULMR,
469
470 ARM_BUILTIN_WQMULWM,
471 ARM_BUILTIN_WQMULWMR,
472
473 ARM_BUILTIN_WADDBHUSM,
474 ARM_BUILTIN_WADDBHUSL,
475
476 ARM_BUILTIN_WQMIABB,
477 ARM_BUILTIN_WQMIABT,
478 ARM_BUILTIN_WQMIATB,
479 ARM_BUILTIN_WQMIATT,
480
481 ARM_BUILTIN_WQMIABBN,
482 ARM_BUILTIN_WQMIABTN,
483 ARM_BUILTIN_WQMIATBN,
484 ARM_BUILTIN_WQMIATTN,
485
486 ARM_BUILTIN_WMIABB,
487 ARM_BUILTIN_WMIABT,
488 ARM_BUILTIN_WMIATB,
489 ARM_BUILTIN_WMIATT,
490
491 ARM_BUILTIN_WMIABBN,
492 ARM_BUILTIN_WMIABTN,
493 ARM_BUILTIN_WMIATBN,
494 ARM_BUILTIN_WMIATTN,
495
496 ARM_BUILTIN_WMIAWBB,
497 ARM_BUILTIN_WMIAWBT,
498 ARM_BUILTIN_WMIAWTB,
499 ARM_BUILTIN_WMIAWTT,
500
501 ARM_BUILTIN_WMIAWBBN,
502 ARM_BUILTIN_WMIAWBTN,
503 ARM_BUILTIN_WMIAWTBN,
504 ARM_BUILTIN_WMIAWTTN,
505
506 ARM_BUILTIN_WMERGE,
507
508 ARM_BUILTIN_CRC32B,
509 ARM_BUILTIN_CRC32H,
510 ARM_BUILTIN_CRC32W,
511 ARM_BUILTIN_CRC32CB,
512 ARM_BUILTIN_CRC32CH,
513 ARM_BUILTIN_CRC32CW,
514
515 ARM_BUILTIN_GET_FPSCR,
516 ARM_BUILTIN_SET_FPSCR,
517
518#undef CRYPTO1
519#undef CRYPTO2
520#undef CRYPTO3
521
522#define CRYPTO1(L, U, M1, M2) \
523 ARM_BUILTIN_CRYPTO_##U,
524#define CRYPTO2(L, U, M1, M2, M3) \
525 ARM_BUILTIN_CRYPTO_##U,
526#define CRYPTO3(L, U, M1, M2, M3, M4) \
527 ARM_BUILTIN_CRYPTO_##U,
528
529#include "crypto.def"
530
531#undef CRYPTO1
532#undef CRYPTO2
533#undef CRYPTO3
534
732205bc 535 ARM_BUILTIN_NEON_BASE,
536 ARM_BUILTIN_NEON_LANE_CHECK = ARM_BUILTIN_NEON_BASE,
537
d6504d76 538#include "arm_neon_builtins.def"
539
e0b44776 540 ARM_BUILTIN_MAX
d6504d76 541};
542
732205bc 543#define ARM_BUILTIN_NEON_PATTERN_START \
544 (ARM_BUILTIN_MAX - ARRAY_SIZE (neon_builtin_data))
d6504d76 545
546#undef CF
547#undef VAR1
548#undef VAR2
549#undef VAR3
550#undef VAR4
551#undef VAR5
552#undef VAR6
553#undef VAR7
554#undef VAR8
555#undef VAR9
556#undef VAR10
557
558static GTY(()) tree arm_builtin_decls[ARM_BUILTIN_MAX];
559
560#define NUM_DREG_TYPES 5
561#define NUM_QREG_TYPES 6
562
6612f298 563/* Internal scalar builtin types. These types are used to support
564 neon intrinsic builtins. They are _not_ user-visible types. Therefore
565 the mangling for these types are implementation defined. */
566const char *arm_scalar_builtin_types[] = {
567 "__builtin_neon_qi",
568 "__builtin_neon_hi",
569 "__builtin_neon_si",
570 "__builtin_neon_sf",
571 "__builtin_neon_di",
572 "__builtin_neon_df",
573 "__builtin_neon_ti",
574 "__builtin_neon_uqi",
575 "__builtin_neon_uhi",
576 "__builtin_neon_usi",
577 "__builtin_neon_udi",
578 "__builtin_neon_ei",
579 "__builtin_neon_oi",
580 "__builtin_neon_ci",
581 "__builtin_neon_xi",
582 NULL
583};
584
585#define ENTRY(E, M, Q, S, T, G) E,
586enum arm_simd_type
587{
588#include "arm-simd-builtin-types.def"
589 __TYPE_FINAL
590};
591#undef ENTRY
592
593struct arm_simd_type_info
594{
595 enum arm_simd_type type;
596
597 /* Internal type name. */
598 const char *name;
599
600 /* Internal type name(mangled). The mangled names conform to the
601 AAPCS (see "Procedure Call Standard for the ARM Architecture",
602 Appendix A). To qualify for emission with the mangled names defined in
603 that document, a vector type must not only be of the correct mode but also
604 be of the correct internal Neon vector type (e.g. __simd64_int8_t);
605 these types are registered by arm_init_simd_builtin_types (). In other
606 words, vector types defined in other ways e.g. via vector_size attribute
607 will get default mangled names. */
608 const char *mangle;
609
610 /* Internal type. */
611 tree itype;
612
613 /* Element type. */
614 tree eltype;
615
616 /* Machine mode the internal type maps to. */
617 machine_mode mode;
618
619 /* Qualifiers. */
620 enum arm_type_qualifiers q;
621};
622
623#define ENTRY(E, M, Q, S, T, G) \
624 {E, \
625 "__simd" #S "_" #T "_t", \
626 #G "__simd" #S "_" #T "_t", \
627 NULL_TREE, NULL_TREE, M##mode, qualifier_##Q},
628static struct arm_simd_type_info arm_simd_types [] = {
629#include "arm-simd-builtin-types.def"
630};
631#undef ENTRY
632
633static tree arm_simd_floatHF_type_node = NULL_TREE;
634static tree arm_simd_intOI_type_node = NULL_TREE;
635static tree arm_simd_intEI_type_node = NULL_TREE;
636static tree arm_simd_intCI_type_node = NULL_TREE;
637static tree arm_simd_intXI_type_node = NULL_TREE;
638static tree arm_simd_polyQI_type_node = NULL_TREE;
639static tree arm_simd_polyHI_type_node = NULL_TREE;
640static tree arm_simd_polyDI_type_node = NULL_TREE;
641static tree arm_simd_polyTI_type_node = NULL_TREE;
642
643static const char *
644arm_mangle_builtin_scalar_type (const_tree type)
645{
646 int i = 0;
647
648 while (arm_scalar_builtin_types[i] != NULL)
649 {
650 const char *name = arm_scalar_builtin_types[i];
651
652 if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
653 && DECL_NAME (TYPE_NAME (type))
654 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), name))
655 return arm_scalar_builtin_types[i];
656 i++;
657 }
658 return NULL;
659}
660
661static const char *
662arm_mangle_builtin_vector_type (const_tree type)
663{
664 int i;
665 int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
666
667 for (i = 0; i < nelts; i++)
668 if (arm_simd_types[i].mode == TYPE_MODE (type)
669 && TYPE_NAME (type)
670 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
671 && DECL_NAME (TYPE_NAME (type))
672 && !strcmp
673 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
674 arm_simd_types[i].name))
675 return arm_simd_types[i].mangle;
676
677 return NULL;
678}
679
680const char *
681arm_mangle_builtin_type (const_tree type)
682{
683 const char *mangle;
684 /* Walk through all the AArch64 builtins types tables to filter out the
685 incoming type. */
686 if ((mangle = arm_mangle_builtin_vector_type (type))
687 || (mangle = arm_mangle_builtin_scalar_type (type)))
688 return mangle;
689
690 return NULL;
691}
692
693static tree
694arm_simd_builtin_std_type (enum machine_mode mode,
695 enum arm_type_qualifiers q)
696{
697#define QUAL_TYPE(M) \
698 ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node);
699 switch (mode)
700 {
701 case QImode:
702 return QUAL_TYPE (QI);
703 case HImode:
704 return QUAL_TYPE (HI);
705 case SImode:
706 return QUAL_TYPE (SI);
707 case DImode:
708 return QUAL_TYPE (DI);
709 case TImode:
710 return QUAL_TYPE (TI);
711 case OImode:
712 return arm_simd_intOI_type_node;
713 case EImode:
714 return arm_simd_intEI_type_node;
715 case CImode:
716 return arm_simd_intCI_type_node;
717 case XImode:
718 return arm_simd_intXI_type_node;
719 case HFmode:
720 return arm_simd_floatHF_type_node;
721 case SFmode:
722 return float_type_node;
723 case DFmode:
724 return double_type_node;
725 default:
726 gcc_unreachable ();
727 }
728#undef QUAL_TYPE
729}
730
731static tree
732arm_lookup_simd_builtin_type (enum machine_mode mode,
733 enum arm_type_qualifiers q)
734{
735 int i;
736 int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
737
738 /* Non-poly scalar modes map to standard types not in the table. */
739 if (q != qualifier_poly && !VECTOR_MODE_P (mode))
740 return arm_simd_builtin_std_type (mode, q);
741
742 for (i = 0; i < nelts; i++)
743 if (arm_simd_types[i].mode == mode
744 && arm_simd_types[i].q == q)
745 return arm_simd_types[i].itype;
746
747 /* Note that we won't have caught the underlying type for poly64x2_t
748 in the above table. This gets default mangling. */
749
750 return NULL_TREE;
751}
752
753static tree
754arm_simd_builtin_type (enum machine_mode mode,
755 bool unsigned_p, bool poly_p)
756{
757 if (poly_p)
758 return arm_lookup_simd_builtin_type (mode, qualifier_poly);
759 else if (unsigned_p)
760 return arm_lookup_simd_builtin_type (mode, qualifier_unsigned);
761 else
762 return arm_lookup_simd_builtin_type (mode, qualifier_none);
763}
764
d6504d76 765static void
6612f298 766arm_init_simd_builtin_types (void)
767{
768 int i;
769 int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
770 tree tdecl;
771
6612f298 772 /* Poly types are a world of their own. In order to maintain legacy
773 ABI, they get initialized using the old interface, and don't get
774 an entry in our mangling table, consequently, they get default
775 mangling. As a further gotcha, poly8_t and poly16_t are signed
776 types, poly64_t and poly128_t are unsigned types. */
777 arm_simd_polyQI_type_node
778 = build_distinct_type_copy (intQI_type_node);
779 (*lang_hooks.types.register_builtin_type) (arm_simd_polyQI_type_node,
780 "__builtin_neon_poly8");
781 arm_simd_polyHI_type_node
782 = build_distinct_type_copy (intHI_type_node);
783 (*lang_hooks.types.register_builtin_type) (arm_simd_polyHI_type_node,
784 "__builtin_neon_poly16");
785 arm_simd_polyDI_type_node
786 = build_distinct_type_copy (unsigned_intDI_type_node);
787 (*lang_hooks.types.register_builtin_type) (arm_simd_polyDI_type_node,
788 "__builtin_neon_poly64");
789 arm_simd_polyTI_type_node
790 = build_distinct_type_copy (unsigned_intTI_type_node);
791 (*lang_hooks.types.register_builtin_type) (arm_simd_polyTI_type_node,
792 "__builtin_neon_poly128");
793
794 /* Init all the element types built by the front-end. */
795 arm_simd_types[Int8x8_t].eltype = intQI_type_node;
796 arm_simd_types[Int8x16_t].eltype = intQI_type_node;
797 arm_simd_types[Int16x4_t].eltype = intHI_type_node;
798 arm_simd_types[Int16x8_t].eltype = intHI_type_node;
799 arm_simd_types[Int32x2_t].eltype = intSI_type_node;
800 arm_simd_types[Int32x4_t].eltype = intSI_type_node;
801 arm_simd_types[Int64x2_t].eltype = intDI_type_node;
802 arm_simd_types[Uint8x8_t].eltype = unsigned_intQI_type_node;
803 arm_simd_types[Uint8x16_t].eltype = unsigned_intQI_type_node;
804 arm_simd_types[Uint16x4_t].eltype = unsigned_intHI_type_node;
805 arm_simd_types[Uint16x8_t].eltype = unsigned_intHI_type_node;
806 arm_simd_types[Uint32x2_t].eltype = unsigned_intSI_type_node;
807 arm_simd_types[Uint32x4_t].eltype = unsigned_intSI_type_node;
808 arm_simd_types[Uint64x2_t].eltype = unsigned_intDI_type_node;
809
810 /* Init poly vector element types with scalar poly types. */
811 arm_simd_types[Poly8x8_t].eltype = arm_simd_polyQI_type_node;
812 arm_simd_types[Poly8x16_t].eltype = arm_simd_polyQI_type_node;
813 arm_simd_types[Poly16x4_t].eltype = arm_simd_polyHI_type_node;
814 arm_simd_types[Poly16x8_t].eltype = arm_simd_polyHI_type_node;
815 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
816 mangling. */
817
818 /* Continue with standard types. */
481aa322 819 /* The __builtin_simd{64,128}_float16 types are kept private unless
820 we have a scalar __fp16 type. */
6612f298 821 arm_simd_types[Float16x4_t].eltype = arm_simd_floatHF_type_node;
60712275 822 arm_simd_types[Float16x8_t].eltype = arm_simd_floatHF_type_node;
6612f298 823 arm_simd_types[Float32x2_t].eltype = float_type_node;
824 arm_simd_types[Float32x4_t].eltype = float_type_node;
825
826 for (i = 0; i < nelts; i++)
827 {
828 tree eltype = arm_simd_types[i].eltype;
829 enum machine_mode mode = arm_simd_types[i].mode;
830
831 if (arm_simd_types[i].itype == NULL)
832 arm_simd_types[i].itype =
833 build_distinct_type_copy
834 (build_vector_type (eltype, GET_MODE_NUNITS (mode)));
835
836 tdecl = add_builtin_type (arm_simd_types[i].name,
837 arm_simd_types[i].itype);
838 TYPE_NAME (arm_simd_types[i].itype) = tdecl;
839 SET_TYPE_STRUCTURAL_EQUALITY (arm_simd_types[i].itype);
840 }
841
842#define AARCH_BUILD_SIGNED_TYPE(mode) \
843 make_signed_type (GET_MODE_PRECISION (mode));
844 arm_simd_intOI_type_node = AARCH_BUILD_SIGNED_TYPE (OImode);
845 arm_simd_intEI_type_node = AARCH_BUILD_SIGNED_TYPE (EImode);
846 arm_simd_intCI_type_node = AARCH_BUILD_SIGNED_TYPE (CImode);
847 arm_simd_intXI_type_node = AARCH_BUILD_SIGNED_TYPE (XImode);
848#undef AARCH_BUILD_SIGNED_TYPE
849
850 tdecl = add_builtin_type
851 ("__builtin_neon_ei" , arm_simd_intEI_type_node);
852 TYPE_NAME (arm_simd_intEI_type_node) = tdecl;
853 tdecl = add_builtin_type
854 ("__builtin_neon_oi" , arm_simd_intOI_type_node);
855 TYPE_NAME (arm_simd_intOI_type_node) = tdecl;
856 tdecl = add_builtin_type
857 ("__builtin_neon_ci" , arm_simd_intCI_type_node);
858 TYPE_NAME (arm_simd_intCI_type_node) = tdecl;
859 tdecl = add_builtin_type
860 ("__builtin_neon_xi" , arm_simd_intXI_type_node);
861 TYPE_NAME (arm_simd_intXI_type_node) = tdecl;
862}
863
864static void
865arm_init_simd_builtin_scalar_types (void)
d6504d76 866{
6612f298 867 /* Define typedefs for all the standard scalar types. */
868 (*lang_hooks.types.register_builtin_type) (intQI_type_node,
d6504d76 869 "__builtin_neon_qi");
6612f298 870 (*lang_hooks.types.register_builtin_type) (intHI_type_node,
d6504d76 871 "__builtin_neon_hi");
6612f298 872 (*lang_hooks.types.register_builtin_type) (intSI_type_node,
d6504d76 873 "__builtin_neon_si");
6612f298 874 (*lang_hooks.types.register_builtin_type) (float_type_node,
d6504d76 875 "__builtin_neon_sf");
6612f298 876 (*lang_hooks.types.register_builtin_type) (intDI_type_node,
d6504d76 877 "__builtin_neon_di");
6612f298 878 (*lang_hooks.types.register_builtin_type) (double_type_node,
879 "__builtin_neon_df");
880 (*lang_hooks.types.register_builtin_type) (intTI_type_node,
881 "__builtin_neon_ti");
d6504d76 882
883 /* Unsigned integer types for various mode sizes. */
6612f298 884 (*lang_hooks.types.register_builtin_type) (unsigned_intQI_type_node,
d6504d76 885 "__builtin_neon_uqi");
6612f298 886 (*lang_hooks.types.register_builtin_type) (unsigned_intHI_type_node,
d6504d76 887 "__builtin_neon_uhi");
6612f298 888 (*lang_hooks.types.register_builtin_type) (unsigned_intSI_type_node,
d6504d76 889 "__builtin_neon_usi");
6612f298 890 (*lang_hooks.types.register_builtin_type) (unsigned_intDI_type_node,
d6504d76 891 "__builtin_neon_udi");
6612f298 892 (*lang_hooks.types.register_builtin_type) (unsigned_intTI_type_node,
893 "__builtin_neon_uti");
894}
d6504d76 895
6612f298 896static void
4bbe6dbe 897arm_init_neon_builtins_internal (void)
6612f298 898{
732205bc 899 unsigned int i, fcode = ARM_BUILTIN_NEON_PATTERN_START;
d6504d76 900
6612f298 901 arm_init_simd_builtin_types ();
d6504d76 902
6612f298 903 /* Strong-typing hasn't been implemented for all AdvSIMD builtin intrinsics.
904 Therefore we need to preserve the old __builtin scalar types. It can be
905 removed once all the intrinsics become strongly typed using the qualifier
906 system. */
907 arm_init_simd_builtin_scalar_types ();
d6504d76 908
732205bc 909 tree lane_check_fpr = build_function_type_list (void_type_node,
910 intSI_type_node,
911 intSI_type_node,
912 NULL);
913 arm_builtin_decls[ARM_BUILTIN_NEON_LANE_CHECK] =
914 add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr,
915 ARM_BUILTIN_NEON_LANE_CHECK, BUILT_IN_MD,
916 NULL, NULL_TREE);
917
6612f298 918 for (i = 0; i < ARRAY_SIZE (neon_builtin_data); i++, fcode++)
d6504d76 919 {
6612f298 920 bool print_type_signature_p = false;
921 char type_signature[SIMD_MAX_BUILTIN_ARGS] = { 0 };
d6504d76 922 neon_builtin_datum *d = &neon_builtin_data[i];
d6504d76 923 char namebuf[60];
924 tree ftype = NULL;
6612f298 925 tree fndecl = NULL;
d6504d76 926
d6504d76 927 d->fcode = fcode;
928
6612f298 929 /* We must track two variables here. op_num is
930 the operand number as in the RTL pattern. This is
931 required to access the mode (e.g. V4SF mode) of the
932 argument, from which the base type can be derived.
933 arg_num is an index in to the qualifiers data, which
934 gives qualifiers to the type (e.g. const unsigned).
935 The reason these two variables may differ by one is the
936 void return type. While all return types take the 0th entry
937 in the qualifiers array, there is no operand for them in the
938 RTL pattern. */
939 int op_num = insn_data[d->code].n_operands - 1;
940 int arg_num = d->qualifiers[0] & qualifier_void
941 ? op_num + 1
942 : op_num;
943 tree return_type = void_type_node, args = void_list_node;
944 tree eltype;
945
946 /* Build a function type directly from the insn_data for this
947 builtin. The build_function_type () function takes care of
948 removing duplicates for us. */
949 for (; op_num >= 0; arg_num--, op_num--)
d6504d76 950 {
6612f298 951 machine_mode op_mode = insn_data[d->code].operand[op_num].mode;
952 enum arm_type_qualifiers qualifiers = d->qualifiers[arg_num];
953
954 if (qualifiers & qualifier_unsigned)
d6504d76 955 {
6612f298 956 type_signature[arg_num] = 'u';
957 print_type_signature_p = true;
d6504d76 958 }
6612f298 959 else if (qualifiers & qualifier_poly)
d6504d76 960 {
6612f298 961 type_signature[arg_num] = 'p';
962 print_type_signature_p = true;
d6504d76 963 }
6612f298 964 else
965 type_signature[arg_num] = 's';
966
967 /* Skip an internal operand for vget_{low, high}. */
968 if (qualifiers & qualifier_internal)
969 continue;
970
971 /* Some builtins have different user-facing types
972 for certain arguments, encoded in d->mode. */
973 if (qualifiers & qualifier_map_mode)
c7796b7e 974 op_mode = d->mode;
6612f298 975
976 /* For pointers, we want a pointer to the basic type
977 of the vector. */
978 if (qualifiers & qualifier_pointer && VECTOR_MODE_P (op_mode))
979 op_mode = GET_MODE_INNER (op_mode);
980
981 eltype = arm_simd_builtin_type
982 (op_mode,
983 (qualifiers & qualifier_unsigned) != 0,
984 (qualifiers & qualifier_poly) != 0);
985 gcc_assert (eltype != NULL);
986
987 /* Add qualifiers. */
988 if (qualifiers & qualifier_const)
989 eltype = build_qualified_type (eltype, TYPE_QUAL_CONST);
990
991 if (qualifiers & qualifier_pointer)
992 eltype = build_pointer_type (eltype);
993
994 /* If we have reached arg_num == 0, we are at a non-void
995 return type. Otherwise, we are still processing
996 arguments. */
997 if (arg_num == 0)
998 return_type = eltype;
999 else
1000 args = tree_cons (NULL_TREE, eltype, args);
d6504d76 1001 }
1002
6612f298 1003 ftype = build_function_type (return_type, args);
1004
d6504d76 1005 gcc_assert (ftype != NULL);
1006
6612f298 1007 if (print_type_signature_p)
c7796b7e 1008 snprintf (namebuf, sizeof (namebuf), "__builtin_neon_%s_%s",
1009 d->name, type_signature);
6612f298 1010 else
c7796b7e 1011 snprintf (namebuf, sizeof (namebuf), "__builtin_neon_%s",
1012 d->name);
6612f298 1013
1014 fndecl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD,
1015 NULL, NULL_TREE);
1016 arm_builtin_decls[fcode] = fndecl;
1017 }
4bbe6dbe 1018}
d6504d76 1019
4bbe6dbe 1020static void
1021arm_init_crypto_builtins_internal (void)
1022{
1023 tree V16UQI_type_node
1024 = arm_simd_builtin_type (V16QImode, true, false);
6612f298 1025
4bbe6dbe 1026 tree V4USI_type_node
1027 = arm_simd_builtin_type (V4SImode, true, false);
6612f298 1028
4bbe6dbe 1029 tree v16uqi_ftype_v16uqi
1030 = build_function_type_list (V16UQI_type_node, V16UQI_type_node,
1031 NULL_TREE);
6612f298 1032
4bbe6dbe 1033 tree v16uqi_ftype_v16uqi_v16uqi
6612f298 1034 = build_function_type_list (V16UQI_type_node, V16UQI_type_node,
1035 V16UQI_type_node, NULL_TREE);
1036
4bbe6dbe 1037 tree v4usi_ftype_v4usi
1038 = build_function_type_list (V4USI_type_node, V4USI_type_node,
1039 NULL_TREE);
1040
1041 tree v4usi_ftype_v4usi_v4usi
1042 = build_function_type_list (V4USI_type_node, V4USI_type_node,
1043 V4USI_type_node, NULL_TREE);
1044
1045 tree v4usi_ftype_v4usi_v4usi_v4usi
1046 = build_function_type_list (V4USI_type_node, V4USI_type_node,
1047 V4USI_type_node, V4USI_type_node,
1048 NULL_TREE);
1049
1050 tree uti_ftype_udi_udi
1051 = build_function_type_list (unsigned_intTI_type_node,
1052 unsigned_intDI_type_node,
1053 unsigned_intDI_type_node,
1054 NULL_TREE);
1055
1056 #undef CRYPTO1
1057 #undef CRYPTO2
1058 #undef CRYPTO3
1059 #undef C
1060 #undef N
1061 #undef CF
1062 #undef FT1
1063 #undef FT2
1064 #undef FT3
1065
1066 #define C(U) \
1067 ARM_BUILTIN_CRYPTO_##U
1068 #define N(L) \
1069 "__builtin_arm_crypto_"#L
1070 #define FT1(R, A) \
1071 R##_ftype_##A
1072 #define FT2(R, A1, A2) \
1073 R##_ftype_##A1##_##A2
1074 #define FT3(R, A1, A2, A3) \
1075 R##_ftype_##A1##_##A2##_##A3
1076 #define CRYPTO1(L, U, R, A) \
1077 arm_builtin_decls[C (U)] \
1078 = add_builtin_function (N (L), FT1 (R, A), \
1079 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1080 #define CRYPTO2(L, U, R, A1, A2) \
1081 arm_builtin_decls[C (U)] \
1082 = add_builtin_function (N (L), FT2 (R, A1, A2), \
1083 C (U), BUILT_IN_MD, NULL, NULL_TREE);
1084
1085 #define CRYPTO3(L, U, R, A1, A2, A3) \
1086 arm_builtin_decls[C (U)] \
1087 = add_builtin_function (N (L), FT3 (R, A1, A2, A3), \
6612f298 1088 C (U), BUILT_IN_MD, NULL, NULL_TREE);
4bbe6dbe 1089 #include "crypto.def"
1090
1091 #undef CRYPTO1
1092 #undef CRYPTO2
1093 #undef CRYPTO3
1094 #undef C
1095 #undef N
1096 #undef FT1
1097 #undef FT2
1098 #undef FT3
1099}
6612f298 1100
4bbe6dbe 1101static bool neon_set_p = false;
1102static bool neon_crypto_set_p = false;
1103
1104void
1105arm_init_neon_builtins (void)
1106{
1107 if (! neon_set_p)
1108 {
1109 neon_set_p = true;
1110 arm_init_neon_builtins_internal ();
1111 }
1112
3f0c3c4e 1113 if (! neon_crypto_set_p && TARGET_CRYPTO && TARGET_HARD_FLOAT)
4bbe6dbe 1114 {
1115 neon_crypto_set_p = true;
1116 arm_init_crypto_builtins_internal ();
d6504d76 1117 }
1118}
1119
1120#undef NUM_DREG_TYPES
1121#undef NUM_QREG_TYPES
1122
0cbfbd7d 1123#define def_mbuiltin(FLAGS, NAME, TYPE, CODE) \
d6504d76 1124 do \
1125 { \
0cbfbd7d 1126 const arm_feature_set flags = FLAGS; \
1127 if (ARM_FSET_CPU_SUBSET (flags, insn_flags)) \
d6504d76 1128 { \
1129 tree bdecl; \
1130 bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
1131 BUILT_IN_MD, NULL, NULL_TREE); \
1132 arm_builtin_decls[CODE] = bdecl; \
1133 } \
1134 } \
1135 while (0)
1136
1137struct builtin_description
1138{
0cbfbd7d 1139 const arm_feature_set features;
d6504d76 1140 const enum insn_code icode;
1141 const char * const name;
1142 const enum arm_builtins code;
1143 const enum rtx_code comparison;
1144 const unsigned int flag;
1145};
1146
1147static const struct builtin_description bdesc_2arg[] =
1148{
1149#define IWMMXT_BUILTIN(code, string, builtin) \
0cbfbd7d 1150 { ARM_FSET_MAKE_CPU1 (FL_IWMMXT), CODE_FOR_##code, \
1151 "__builtin_arm_" string, \
d6504d76 1152 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1153
1154#define IWMMXT2_BUILTIN(code, string, builtin) \
0cbfbd7d 1155 { ARM_FSET_MAKE_CPU1 (FL_IWMMXT2), CODE_FOR_##code, \
1156 "__builtin_arm_" string, \
d6504d76 1157 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1158
1159 IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
1160 IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
1161 IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
1162 IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
1163 IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
1164 IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
1165 IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
1166 IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
1167 IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
1168 IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
1169 IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
1170 IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
1171 IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
1172 IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
1173 IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
1174 IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
1175 IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
1176 IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
1177 IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
1178 IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsm", WMULSM)
1179 IWMMXT_BUILTIN (umulv4hi3_highpart, "wmulum", WMULUM)
1180 IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
1181 IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
1182 IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
1183 IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
1184 IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
1185 IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
1186 IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
1187 IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
1188 IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
1189 IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
1190 IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
1191 IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
1192 IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
1193 IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
1194 IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
1195 IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
1196 IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
1197 IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
1198 IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
1199 IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
1200 IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
1201 IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
1202 IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
1203 IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
1204 IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
1205 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
1206 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
1207 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
1208 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
1209 IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
1210 IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
1211 IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
1212 IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
1213 IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
1214 IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
1215 IWMMXT2_BUILTIN (iwmmxt_waddsubhx, "waddsubhx", WADDSUBHX)
1216 IWMMXT2_BUILTIN (iwmmxt_wsubaddhx, "wsubaddhx", WSUBADDHX)
1217 IWMMXT2_BUILTIN (iwmmxt_wabsdiffb, "wabsdiffb", WABSDIFFB)
1218 IWMMXT2_BUILTIN (iwmmxt_wabsdiffh, "wabsdiffh", WABSDIFFH)
1219 IWMMXT2_BUILTIN (iwmmxt_wabsdiffw, "wabsdiffw", WABSDIFFW)
1220 IWMMXT2_BUILTIN (iwmmxt_avg4, "wavg4", WAVG4)
1221 IWMMXT2_BUILTIN (iwmmxt_avg4r, "wavg4r", WAVG4R)
1222 IWMMXT2_BUILTIN (iwmmxt_wmulwsm, "wmulwsm", WMULWSM)
1223 IWMMXT2_BUILTIN (iwmmxt_wmulwum, "wmulwum", WMULWUM)
1224 IWMMXT2_BUILTIN (iwmmxt_wmulwsmr, "wmulwsmr", WMULWSMR)
1225 IWMMXT2_BUILTIN (iwmmxt_wmulwumr, "wmulwumr", WMULWUMR)
1226 IWMMXT2_BUILTIN (iwmmxt_wmulwl, "wmulwl", WMULWL)
1227 IWMMXT2_BUILTIN (iwmmxt_wmulsmr, "wmulsmr", WMULSMR)
1228 IWMMXT2_BUILTIN (iwmmxt_wmulumr, "wmulumr", WMULUMR)
1229 IWMMXT2_BUILTIN (iwmmxt_wqmulm, "wqmulm", WQMULM)
1230 IWMMXT2_BUILTIN (iwmmxt_wqmulmr, "wqmulmr", WQMULMR)
1231 IWMMXT2_BUILTIN (iwmmxt_wqmulwm, "wqmulwm", WQMULWM)
1232 IWMMXT2_BUILTIN (iwmmxt_wqmulwmr, "wqmulwmr", WQMULWMR)
1233 IWMMXT_BUILTIN (iwmmxt_walignr0, "walignr0", WALIGNR0)
1234 IWMMXT_BUILTIN (iwmmxt_walignr1, "walignr1", WALIGNR1)
1235 IWMMXT_BUILTIN (iwmmxt_walignr2, "walignr2", WALIGNR2)
1236 IWMMXT_BUILTIN (iwmmxt_walignr3, "walignr3", WALIGNR3)
1237
1238#define IWMMXT_BUILTIN2(code, builtin) \
0cbfbd7d 1239 { ARM_FSET_MAKE_CPU1 (FL_IWMMXT), CODE_FOR_##code, NULL, \
1240 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
d6504d76 1241
1242#define IWMMXT2_BUILTIN2(code, builtin) \
0cbfbd7d 1243 { ARM_FSET_MAKE_CPU2 (FL_IWMMXT2), CODE_FOR_##code, NULL, \
1244 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
d6504d76 1245
1246 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm, WADDBHUSM)
1247 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl, WADDBHUSL)
1248 IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
1249 IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
1250 IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
1251 IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
1252 IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
1253 IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
1254 IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
1255 IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
1256
1257
1258#define FP_BUILTIN(L, U) \
0cbfbd7d 1259 {ARM_FSET_EMPTY, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
d6504d76 1260 UNKNOWN, 0},
1261
1262 FP_BUILTIN (get_fpscr, GET_FPSCR)
1263 FP_BUILTIN (set_fpscr, SET_FPSCR)
1264#undef FP_BUILTIN
1265
1266#define CRC32_BUILTIN(L, U) \
0cbfbd7d 1267 {ARM_FSET_EMPTY, CODE_FOR_##L, "__builtin_arm_"#L, \
1268 ARM_BUILTIN_##U, UNKNOWN, 0},
d6504d76 1269 CRC32_BUILTIN (crc32b, CRC32B)
1270 CRC32_BUILTIN (crc32h, CRC32H)
1271 CRC32_BUILTIN (crc32w, CRC32W)
1272 CRC32_BUILTIN (crc32cb, CRC32CB)
1273 CRC32_BUILTIN (crc32ch, CRC32CH)
1274 CRC32_BUILTIN (crc32cw, CRC32CW)
1275#undef CRC32_BUILTIN
1276
1277
0cbfbd7d 1278#define CRYPTO_BUILTIN(L, U) \
1279 {ARM_FSET_EMPTY, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, \
1280 ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0},
d6504d76 1281#undef CRYPTO1
1282#undef CRYPTO2
1283#undef CRYPTO3
1284#define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U)
1285#define CRYPTO1(L, U, R, A)
1286#define CRYPTO3(L, U, R, A1, A2, A3)
1287#include "crypto.def"
1288#undef CRYPTO1
1289#undef CRYPTO2
1290#undef CRYPTO3
1291
1292};
1293
1294static const struct builtin_description bdesc_1arg[] =
1295{
1296 IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
1297 IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
1298 IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
1299 IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
1300 IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
1301 IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
1302 IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
1303 IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
1304 IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
1305 IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
1306 IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
1307 IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
1308 IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
1309 IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
1310 IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
1311 IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
1312 IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
1313 IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
1314 IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3, "wabsb", WABSB)
1315 IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3, "wabsh", WABSH)
1316 IWMMXT2_BUILTIN (iwmmxt_wabsv2si3, "wabsw", WABSW)
1317 IWMMXT_BUILTIN (tbcstv8qi, "tbcstb", TBCSTB)
1318 IWMMXT_BUILTIN (tbcstv4hi, "tbcsth", TBCSTH)
1319 IWMMXT_BUILTIN (tbcstv2si, "tbcstw", TBCSTW)
1320
1321#define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U)
1322#define CRYPTO2(L, U, R, A1, A2)
1323#define CRYPTO3(L, U, R, A1, A2, A3)
1324#include "crypto.def"
1325#undef CRYPTO1
1326#undef CRYPTO2
1327#undef CRYPTO3
1328};
1329
1330static const struct builtin_description bdesc_3arg[] =
1331{
1332#define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U)
1333#define CRYPTO1(L, U, R, A)
1334#define CRYPTO2(L, U, R, A1, A2)
1335#include "crypto.def"
1336#undef CRYPTO1
1337#undef CRYPTO2
1338#undef CRYPTO3
1339 };
1340#undef CRYPTO_BUILTIN
1341
1342/* Set up all the iWMMXt builtins. This is not called if
1343 TARGET_IWMMXT is zero. */
1344
1345static void
1346arm_init_iwmmxt_builtins (void)
1347{
1348 const struct builtin_description * d;
1349 size_t i;
1350
1351 tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
1352 tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
1353 tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode);
1354
1355 tree v8qi_ftype_v8qi_v8qi_int
1356 = build_function_type_list (V8QI_type_node,
1357 V8QI_type_node, V8QI_type_node,
1358 integer_type_node, NULL_TREE);
1359 tree v4hi_ftype_v4hi_int
1360 = build_function_type_list (V4HI_type_node,
1361 V4HI_type_node, integer_type_node, NULL_TREE);
1362 tree v2si_ftype_v2si_int
1363 = build_function_type_list (V2SI_type_node,
1364 V2SI_type_node, integer_type_node, NULL_TREE);
1365 tree v2si_ftype_di_di
1366 = build_function_type_list (V2SI_type_node,
1367 long_long_integer_type_node,
1368 long_long_integer_type_node,
1369 NULL_TREE);
1370 tree di_ftype_di_int
1371 = build_function_type_list (long_long_integer_type_node,
1372 long_long_integer_type_node,
1373 integer_type_node, NULL_TREE);
1374 tree di_ftype_di_int_int
1375 = build_function_type_list (long_long_integer_type_node,
1376 long_long_integer_type_node,
1377 integer_type_node,
1378 integer_type_node, NULL_TREE);
1379 tree int_ftype_v8qi
1380 = build_function_type_list (integer_type_node,
1381 V8QI_type_node, NULL_TREE);
1382 tree int_ftype_v4hi
1383 = build_function_type_list (integer_type_node,
1384 V4HI_type_node, NULL_TREE);
1385 tree int_ftype_v2si
1386 = build_function_type_list (integer_type_node,
1387 V2SI_type_node, NULL_TREE);
1388 tree int_ftype_v8qi_int
1389 = build_function_type_list (integer_type_node,
1390 V8QI_type_node, integer_type_node, NULL_TREE);
1391 tree int_ftype_v4hi_int
1392 = build_function_type_list (integer_type_node,
1393 V4HI_type_node, integer_type_node, NULL_TREE);
1394 tree int_ftype_v2si_int
1395 = build_function_type_list (integer_type_node,
1396 V2SI_type_node, integer_type_node, NULL_TREE);
1397 tree v8qi_ftype_v8qi_int_int
1398 = build_function_type_list (V8QI_type_node,
1399 V8QI_type_node, integer_type_node,
1400 integer_type_node, NULL_TREE);
1401 tree v4hi_ftype_v4hi_int_int
1402 = build_function_type_list (V4HI_type_node,
1403 V4HI_type_node, integer_type_node,
1404 integer_type_node, NULL_TREE);
1405 tree v2si_ftype_v2si_int_int
1406 = build_function_type_list (V2SI_type_node,
1407 V2SI_type_node, integer_type_node,
1408 integer_type_node, NULL_TREE);
1409 /* Miscellaneous. */
1410 tree v8qi_ftype_v4hi_v4hi
1411 = build_function_type_list (V8QI_type_node,
1412 V4HI_type_node, V4HI_type_node, NULL_TREE);
1413 tree v4hi_ftype_v2si_v2si
1414 = build_function_type_list (V4HI_type_node,
1415 V2SI_type_node, V2SI_type_node, NULL_TREE);
1416 tree v8qi_ftype_v4hi_v8qi
1417 = build_function_type_list (V8QI_type_node,
1418 V4HI_type_node, V8QI_type_node, NULL_TREE);
1419 tree v2si_ftype_v4hi_v4hi
1420 = build_function_type_list (V2SI_type_node,
1421 V4HI_type_node, V4HI_type_node, NULL_TREE);
1422 tree v2si_ftype_v8qi_v8qi
1423 = build_function_type_list (V2SI_type_node,
1424 V8QI_type_node, V8QI_type_node, NULL_TREE);
1425 tree v4hi_ftype_v4hi_di
1426 = build_function_type_list (V4HI_type_node,
1427 V4HI_type_node, long_long_integer_type_node,
1428 NULL_TREE);
1429 tree v2si_ftype_v2si_di
1430 = build_function_type_list (V2SI_type_node,
1431 V2SI_type_node, long_long_integer_type_node,
1432 NULL_TREE);
1433 tree di_ftype_void
1434 = build_function_type_list (long_long_unsigned_type_node, NULL_TREE);
1435 tree int_ftype_void
1436 = build_function_type_list (integer_type_node, NULL_TREE);
1437 tree di_ftype_v8qi
1438 = build_function_type_list (long_long_integer_type_node,
1439 V8QI_type_node, NULL_TREE);
1440 tree di_ftype_v4hi
1441 = build_function_type_list (long_long_integer_type_node,
1442 V4HI_type_node, NULL_TREE);
1443 tree di_ftype_v2si
1444 = build_function_type_list (long_long_integer_type_node,
1445 V2SI_type_node, NULL_TREE);
1446 tree v2si_ftype_v4hi
1447 = build_function_type_list (V2SI_type_node,
1448 V4HI_type_node, NULL_TREE);
1449 tree v4hi_ftype_v8qi
1450 = build_function_type_list (V4HI_type_node,
1451 V8QI_type_node, NULL_TREE);
1452 tree v8qi_ftype_v8qi
1453 = build_function_type_list (V8QI_type_node,
1454 V8QI_type_node, NULL_TREE);
1455 tree v4hi_ftype_v4hi
1456 = build_function_type_list (V4HI_type_node,
1457 V4HI_type_node, NULL_TREE);
1458 tree v2si_ftype_v2si
1459 = build_function_type_list (V2SI_type_node,
1460 V2SI_type_node, NULL_TREE);
1461
1462 tree di_ftype_di_v4hi_v4hi
1463 = build_function_type_list (long_long_unsigned_type_node,
1464 long_long_unsigned_type_node,
1465 V4HI_type_node, V4HI_type_node,
1466 NULL_TREE);
1467
1468 tree di_ftype_v4hi_v4hi
1469 = build_function_type_list (long_long_unsigned_type_node,
1470 V4HI_type_node,V4HI_type_node,
1471 NULL_TREE);
1472
1473 tree v2si_ftype_v2si_v4hi_v4hi
1474 = build_function_type_list (V2SI_type_node,
1475 V2SI_type_node, V4HI_type_node,
1476 V4HI_type_node, NULL_TREE);
1477
1478 tree v2si_ftype_v2si_v8qi_v8qi
1479 = build_function_type_list (V2SI_type_node,
1480 V2SI_type_node, V8QI_type_node,
1481 V8QI_type_node, NULL_TREE);
1482
1483 tree di_ftype_di_v2si_v2si
1484 = build_function_type_list (long_long_unsigned_type_node,
1485 long_long_unsigned_type_node,
1486 V2SI_type_node, V2SI_type_node,
1487 NULL_TREE);
1488
1489 tree di_ftype_di_di_int
1490 = build_function_type_list (long_long_unsigned_type_node,
1491 long_long_unsigned_type_node,
1492 long_long_unsigned_type_node,
1493 integer_type_node, NULL_TREE);
1494
1495 tree void_ftype_int
1496 = build_function_type_list (void_type_node,
1497 integer_type_node, NULL_TREE);
1498
1499 tree v8qi_ftype_char
1500 = build_function_type_list (V8QI_type_node,
1501 signed_char_type_node, NULL_TREE);
1502
1503 tree v4hi_ftype_short
1504 = build_function_type_list (V4HI_type_node,
1505 short_integer_type_node, NULL_TREE);
1506
1507 tree v2si_ftype_int
1508 = build_function_type_list (V2SI_type_node,
1509 integer_type_node, NULL_TREE);
1510
1511 /* Normal vector binops. */
1512 tree v8qi_ftype_v8qi_v8qi
1513 = build_function_type_list (V8QI_type_node,
1514 V8QI_type_node, V8QI_type_node, NULL_TREE);
1515 tree v4hi_ftype_v4hi_v4hi
1516 = build_function_type_list (V4HI_type_node,
1517 V4HI_type_node,V4HI_type_node, NULL_TREE);
1518 tree v2si_ftype_v2si_v2si
1519 = build_function_type_list (V2SI_type_node,
1520 V2SI_type_node, V2SI_type_node, NULL_TREE);
1521 tree di_ftype_di_di
1522 = build_function_type_list (long_long_unsigned_type_node,
1523 long_long_unsigned_type_node,
1524 long_long_unsigned_type_node,
1525 NULL_TREE);
1526
1527 /* Add all builtins that are more or less simple operations on two
1528 operands. */
1529 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
1530 {
1531 /* Use one of the operands; the target can have a different mode for
1532 mask-generating compares. */
1533 machine_mode mode;
1534 tree type;
1535
0cbfbd7d 1536 if (d->name == 0 ||
1537 !(ARM_FSET_HAS_CPU1 (d->features, FL_IWMMXT) ||
1538 ARM_FSET_HAS_CPU1 (d->features, FL_IWMMXT2)))
d6504d76 1539 continue;
1540
1541 mode = insn_data[d->icode].operand[1].mode;
1542
1543 switch (mode)
1544 {
1545 case V8QImode:
1546 type = v8qi_ftype_v8qi_v8qi;
1547 break;
1548 case V4HImode:
1549 type = v4hi_ftype_v4hi_v4hi;
1550 break;
1551 case V2SImode:
1552 type = v2si_ftype_v2si_v2si;
1553 break;
1554 case DImode:
1555 type = di_ftype_di_di;
1556 break;
1557
1558 default:
1559 gcc_unreachable ();
1560 }
1561
0cbfbd7d 1562 def_mbuiltin (d->features, d->name, type, d->code);
d6504d76 1563 }
1564
1565 /* Add the remaining MMX insns with somewhat more complicated types. */
1566#define iwmmx_mbuiltin(NAME, TYPE, CODE) \
0cbfbd7d 1567 def_mbuiltin (ARM_FSET_MAKE_CPU1 (FL_IWMMXT), "__builtin_arm_" NAME, \
1568 (TYPE), ARM_BUILTIN_ ## CODE)
d6504d76 1569
1570#define iwmmx2_mbuiltin(NAME, TYPE, CODE) \
0cbfbd7d 1571 def_mbuiltin (ARM_FSET_MAKE_CPU1 (FL_IWMMXT2), "__builtin_arm_" NAME, \
1572 (TYPE), ARM_BUILTIN_ ## CODE)
d6504d76 1573
1574 iwmmx_mbuiltin ("wzero", di_ftype_void, WZERO);
1575 iwmmx_mbuiltin ("setwcgr0", void_ftype_int, SETWCGR0);
1576 iwmmx_mbuiltin ("setwcgr1", void_ftype_int, SETWCGR1);
1577 iwmmx_mbuiltin ("setwcgr2", void_ftype_int, SETWCGR2);
1578 iwmmx_mbuiltin ("setwcgr3", void_ftype_int, SETWCGR3);
1579 iwmmx_mbuiltin ("getwcgr0", int_ftype_void, GETWCGR0);
1580 iwmmx_mbuiltin ("getwcgr1", int_ftype_void, GETWCGR1);
1581 iwmmx_mbuiltin ("getwcgr2", int_ftype_void, GETWCGR2);
1582 iwmmx_mbuiltin ("getwcgr3", int_ftype_void, GETWCGR3);
1583
1584 iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di, WSLLH);
1585 iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di, WSLLW);
1586 iwmmx_mbuiltin ("wslld", di_ftype_di_di, WSLLD);
1587 iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int, WSLLHI);
1588 iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int, WSLLWI);
1589 iwmmx_mbuiltin ("wslldi", di_ftype_di_int, WSLLDI);
1590
1591 iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di, WSRLH);
1592 iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di, WSRLW);
1593 iwmmx_mbuiltin ("wsrld", di_ftype_di_di, WSRLD);
1594 iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int, WSRLHI);
1595 iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int, WSRLWI);
1596 iwmmx_mbuiltin ("wsrldi", di_ftype_di_int, WSRLDI);
1597
1598 iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di, WSRAH);
1599 iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di, WSRAW);
1600 iwmmx_mbuiltin ("wsrad", di_ftype_di_di, WSRAD);
1601 iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int, WSRAHI);
1602 iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int, WSRAWI);
1603 iwmmx_mbuiltin ("wsradi", di_ftype_di_int, WSRADI);
1604
1605 iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di, WRORH);
1606 iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di, WRORW);
1607 iwmmx_mbuiltin ("wrord", di_ftype_di_di, WRORD);
1608 iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int, WRORHI);
1609 iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int, WRORWI);
1610 iwmmx_mbuiltin ("wrordi", di_ftype_di_int, WRORDI);
1611
1612 iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int, WSHUFH);
1613
1614 iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi, WSADB);
1615 iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi, WSADH);
1616 iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi, WMADDS);
1617 iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi, WMADDSX);
1618 iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi, WMADDSN);
1619 iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi, WMADDU);
1620 iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi, WMADDUX);
1621 iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi, WMADDUN);
1622 iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi, WSADBZ);
1623 iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi, WSADHZ);
1624
1625 iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int, TEXTRMSB);
1626 iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int, TEXTRMSH);
1627 iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int, TEXTRMSW);
1628 iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int, TEXTRMUB);
1629 iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int, TEXTRMUH);
1630 iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int, TEXTRMUW);
1631 iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int, TINSRB);
1632 iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int, TINSRH);
1633 iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int, TINSRW);
1634
1635 iwmmx_mbuiltin ("waccb", di_ftype_v8qi, WACCB);
1636 iwmmx_mbuiltin ("wacch", di_ftype_v4hi, WACCH);
1637 iwmmx_mbuiltin ("waccw", di_ftype_v2si, WACCW);
1638
1639 iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi, TMOVMSKB);
1640 iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi, TMOVMSKH);
1641 iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si, TMOVMSKW);
1642
1643 iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi, WADDBHUSM);
1644 iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi, WADDBHUSL);
1645
1646 iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi, WPACKHSS);
1647 iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi, WPACKHUS);
1648 iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si, WPACKWUS);
1649 iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si, WPACKWSS);
1650 iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di, WPACKDUS);
1651 iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di, WPACKDSS);
1652
1653 iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi, WUNPCKEHUB);
1654 iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi, WUNPCKEHUH);
1655 iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si, WUNPCKEHUW);
1656 iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi, WUNPCKEHSB);
1657 iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi, WUNPCKEHSH);
1658 iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si, WUNPCKEHSW);
1659 iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi, WUNPCKELUB);
1660 iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi, WUNPCKELUH);
1661 iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si, WUNPCKELUW);
1662 iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi, WUNPCKELSB);
1663 iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi, WUNPCKELSH);
1664 iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si, WUNPCKELSW);
1665
1666 iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi, WMACS);
1667 iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi, WMACSZ);
1668 iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi, WMACU);
1669 iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi, WMACUZ);
1670
1671 iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int, WALIGNI);
1672 iwmmx_mbuiltin ("tmia", di_ftype_di_int_int, TMIA);
1673 iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int, TMIAPH);
1674 iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int, TMIABB);
1675 iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int, TMIABT);
1676 iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int, TMIATB);
1677 iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int, TMIATT);
1678
1679 iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi, WABSB);
1680 iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi, WABSH);
1681 iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si, WABSW);
1682
1683 iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi, WQMIABB);
1684 iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi, WQMIABT);
1685 iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi, WQMIATB);
1686 iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi, WQMIATT);
1687
1688 iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi, WQMIABBN);
1689 iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi, WQMIABTN);
1690 iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi, WQMIATBN);
1691 iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi, WQMIATTN);
1692
1693 iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi, WMIABB);
1694 iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi, WMIABT);
1695 iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi, WMIATB);
1696 iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi, WMIATT);
1697
1698 iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi, WMIABBN);
1699 iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi, WMIABTN);
1700 iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi, WMIATBN);
1701 iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi, WMIATTN);
1702
1703 iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si, WMIAWBB);
1704 iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si, WMIAWBT);
1705 iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si, WMIAWTB);
1706 iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si, WMIAWTT);
1707
1708 iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si, WMIAWBBN);
1709 iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si, WMIAWBTN);
1710 iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si, WMIAWTBN);
1711 iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si, WMIAWTTN);
1712
1713 iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int, WMERGE);
1714
1715 iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char, TBCSTB);
1716 iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short, TBCSTH);
1717 iwmmx_mbuiltin ("tbcstw", v2si_ftype_int, TBCSTW);
1718
1719#undef iwmmx_mbuiltin
1720#undef iwmmx2_mbuiltin
1721}
1722
1723static void
1724arm_init_fp16_builtins (void)
1725{
481aa322 1726 arm_simd_floatHF_type_node = make_node (REAL_TYPE);
1727 TYPE_PRECISION (arm_simd_floatHF_type_node) = GET_MODE_PRECISION (HFmode);
1728 layout_type (arm_simd_floatHF_type_node);
1729 if (arm_fp16_format)
1730 (*lang_hooks.types.register_builtin_type) (arm_simd_floatHF_type_node,
1731 "__fp16");
d6504d76 1732}
1733
1734static void
1735arm_init_crc32_builtins ()
1736{
1737 tree si_ftype_si_qi
1738 = build_function_type_list (unsigned_intSI_type_node,
1739 unsigned_intSI_type_node,
1740 unsigned_intQI_type_node, NULL_TREE);
1741 tree si_ftype_si_hi
1742 = build_function_type_list (unsigned_intSI_type_node,
1743 unsigned_intSI_type_node,
1744 unsigned_intHI_type_node, NULL_TREE);
1745 tree si_ftype_si_si
1746 = build_function_type_list (unsigned_intSI_type_node,
1747 unsigned_intSI_type_node,
1748 unsigned_intSI_type_node, NULL_TREE);
1749
1750 arm_builtin_decls[ARM_BUILTIN_CRC32B]
1751 = add_builtin_function ("__builtin_arm_crc32b", si_ftype_si_qi,
1752 ARM_BUILTIN_CRC32B, BUILT_IN_MD, NULL, NULL_TREE);
1753 arm_builtin_decls[ARM_BUILTIN_CRC32H]
1754 = add_builtin_function ("__builtin_arm_crc32h", si_ftype_si_hi,
1755 ARM_BUILTIN_CRC32H, BUILT_IN_MD, NULL, NULL_TREE);
1756 arm_builtin_decls[ARM_BUILTIN_CRC32W]
1757 = add_builtin_function ("__builtin_arm_crc32w", si_ftype_si_si,
1758 ARM_BUILTIN_CRC32W, BUILT_IN_MD, NULL, NULL_TREE);
1759 arm_builtin_decls[ARM_BUILTIN_CRC32CB]
1760 = add_builtin_function ("__builtin_arm_crc32cb", si_ftype_si_qi,
1761 ARM_BUILTIN_CRC32CB, BUILT_IN_MD, NULL, NULL_TREE);
1762 arm_builtin_decls[ARM_BUILTIN_CRC32CH]
1763 = add_builtin_function ("__builtin_arm_crc32ch", si_ftype_si_hi,
1764 ARM_BUILTIN_CRC32CH, BUILT_IN_MD, NULL, NULL_TREE);
1765 arm_builtin_decls[ARM_BUILTIN_CRC32CW]
1766 = add_builtin_function ("__builtin_arm_crc32cw", si_ftype_si_si,
1767 ARM_BUILTIN_CRC32CW, BUILT_IN_MD, NULL, NULL_TREE);
1768}
1769
1770void
1771arm_init_builtins (void)
1772{
1773 if (TARGET_REALLY_IWMMXT)
1774 arm_init_iwmmxt_builtins ();
1775
481aa322 1776 /* This creates the arm_simd_floatHF_type_node so must come before
1777 arm_init_neon_builtins which uses it. */
1778 arm_init_fp16_builtins ();
1779
d6504d76 1780 if (TARGET_NEON)
1781 arm_init_neon_builtins ();
1782
d6504d76 1783 if (TARGET_CRC32)
1784 arm_init_crc32_builtins ();
1785
1786 if (TARGET_VFP && TARGET_HARD_FLOAT)
1787 {
1788 tree ftype_set_fpscr
1789 = build_function_type_list (void_type_node, unsigned_type_node, NULL);
1790 tree ftype_get_fpscr
1791 = build_function_type_list (unsigned_type_node, NULL);
1792
1793 arm_builtin_decls[ARM_BUILTIN_GET_FPSCR]
1794 = add_builtin_function ("__builtin_arm_ldfscr", ftype_get_fpscr,
1795 ARM_BUILTIN_GET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
1796 arm_builtin_decls[ARM_BUILTIN_SET_FPSCR]
1797 = add_builtin_function ("__builtin_arm_stfscr", ftype_set_fpscr,
1798 ARM_BUILTIN_SET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
1799 }
1800}
1801
1802/* Return the ARM builtin for CODE. */
1803
1804tree
1805arm_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
1806{
1807 if (code >= ARM_BUILTIN_MAX)
1808 return error_mark_node;
1809
1810 return arm_builtin_decls[code];
1811}
1812
1813/* Errors in the source file can cause expand_expr to return const0_rtx
1814 where we expect a vector. To avoid crashing, use one of the vector
1815 clear instructions. */
1816
1817static rtx
1818safe_vector_operand (rtx x, machine_mode mode)
1819{
1820 if (x != const0_rtx)
1821 return x;
1822 x = gen_reg_rtx (mode);
1823
1824 emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x
1825 : gen_rtx_SUBREG (DImode, x, 0)));
1826 return x;
1827}
1828
1829/* Function to expand ternary builtins. */
1830static rtx
1831arm_expand_ternop_builtin (enum insn_code icode,
1832 tree exp, rtx target)
1833{
1834 rtx pat;
1835 tree arg0 = CALL_EXPR_ARG (exp, 0);
1836 tree arg1 = CALL_EXPR_ARG (exp, 1);
1837 tree arg2 = CALL_EXPR_ARG (exp, 2);
1838
1839 rtx op0 = expand_normal (arg0);
1840 rtx op1 = expand_normal (arg1);
1841 rtx op2 = expand_normal (arg2);
1842 rtx op3 = NULL_RTX;
1843
1844 /* The sha1c, sha1p, sha1m crypto builtins require a different vec_select
1845 lane operand depending on endianness. */
1846 bool builtin_sha1cpm_p = false;
1847
1848 if (insn_data[icode].n_operands == 5)
1849 {
1850 gcc_assert (icode == CODE_FOR_crypto_sha1c
1851 || icode == CODE_FOR_crypto_sha1p
1852 || icode == CODE_FOR_crypto_sha1m);
1853 builtin_sha1cpm_p = true;
1854 }
1855 machine_mode tmode = insn_data[icode].operand[0].mode;
1856 machine_mode mode0 = insn_data[icode].operand[1].mode;
1857 machine_mode mode1 = insn_data[icode].operand[2].mode;
1858 machine_mode mode2 = insn_data[icode].operand[3].mode;
1859
1860
1861 if (VECTOR_MODE_P (mode0))
1862 op0 = safe_vector_operand (op0, mode0);
1863 if (VECTOR_MODE_P (mode1))
1864 op1 = safe_vector_operand (op1, mode1);
1865 if (VECTOR_MODE_P (mode2))
1866 op2 = safe_vector_operand (op2, mode2);
1867
1868 if (! target
1869 || GET_MODE (target) != tmode
1870 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
1871 target = gen_reg_rtx (tmode);
1872
1873 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
1874 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode)
1875 && (GET_MODE (op2) == mode2 || GET_MODE (op2) == VOIDmode));
1876
1877 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
1878 op0 = copy_to_mode_reg (mode0, op0);
1879 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
1880 op1 = copy_to_mode_reg (mode1, op1);
1881 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
1882 op2 = copy_to_mode_reg (mode2, op2);
1883 if (builtin_sha1cpm_p)
1884 op3 = GEN_INT (TARGET_BIG_END ? 1 : 0);
1885
1886 if (builtin_sha1cpm_p)
1887 pat = GEN_FCN (icode) (target, op0, op1, op2, op3);
1888 else
1889 pat = GEN_FCN (icode) (target, op0, op1, op2);
1890 if (! pat)
1891 return 0;
1892 emit_insn (pat);
1893 return target;
1894}
1895
1896/* Subroutine of arm_expand_builtin to take care of binop insns. */
1897
1898static rtx
1899arm_expand_binop_builtin (enum insn_code icode,
1900 tree exp, rtx target)
1901{
1902 rtx pat;
1903 tree arg0 = CALL_EXPR_ARG (exp, 0);
1904 tree arg1 = CALL_EXPR_ARG (exp, 1);
1905 rtx op0 = expand_normal (arg0);
1906 rtx op1 = expand_normal (arg1);
1907 machine_mode tmode = insn_data[icode].operand[0].mode;
1908 machine_mode mode0 = insn_data[icode].operand[1].mode;
1909 machine_mode mode1 = insn_data[icode].operand[2].mode;
1910
1911 if (VECTOR_MODE_P (mode0))
1912 op0 = safe_vector_operand (op0, mode0);
1913 if (VECTOR_MODE_P (mode1))
1914 op1 = safe_vector_operand (op1, mode1);
1915
1916 if (! target
1917 || GET_MODE (target) != tmode
1918 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
1919 target = gen_reg_rtx (tmode);
1920
1921 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
1922 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode));
1923
1924 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
1925 op0 = copy_to_mode_reg (mode0, op0);
1926 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
1927 op1 = copy_to_mode_reg (mode1, op1);
1928
1929 pat = GEN_FCN (icode) (target, op0, op1);
1930 if (! pat)
1931 return 0;
1932 emit_insn (pat);
1933 return target;
1934}
1935
1936/* Subroutine of arm_expand_builtin to take care of unop insns. */
1937
1938static rtx
1939arm_expand_unop_builtin (enum insn_code icode,
1940 tree exp, rtx target, int do_load)
1941{
1942 rtx pat;
1943 tree arg0 = CALL_EXPR_ARG (exp, 0);
1944 rtx op0 = expand_normal (arg0);
1945 rtx op1 = NULL_RTX;
1946 machine_mode tmode = insn_data[icode].operand[0].mode;
1947 machine_mode mode0 = insn_data[icode].operand[1].mode;
1948 bool builtin_sha1h_p = false;
1949
1950 if (insn_data[icode].n_operands == 3)
1951 {
1952 gcc_assert (icode == CODE_FOR_crypto_sha1h);
1953 builtin_sha1h_p = true;
1954 }
1955
1956 if (! target
1957 || GET_MODE (target) != tmode
1958 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
1959 target = gen_reg_rtx (tmode);
1960 if (do_load)
1961 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
1962 else
1963 {
1964 if (VECTOR_MODE_P (mode0))
1965 op0 = safe_vector_operand (op0, mode0);
1966
1967 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
1968 op0 = copy_to_mode_reg (mode0, op0);
1969 }
1970 if (builtin_sha1h_p)
1971 op1 = GEN_INT (TARGET_BIG_END ? 1 : 0);
1972
1973 if (builtin_sha1h_p)
1974 pat = GEN_FCN (icode) (target, op0, op1);
1975 else
1976 pat = GEN_FCN (icode) (target, op0);
1977 if (! pat)
1978 return 0;
1979 emit_insn (pat);
1980 return target;
1981}
1982
1983typedef enum {
1984 NEON_ARG_COPY_TO_REG,
1985 NEON_ARG_CONSTANT,
505e1f91 1986 NEON_ARG_LANE_INDEX,
d4023b2c 1987 NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX,
d6504d76 1988 NEON_ARG_MEMORY,
1989 NEON_ARG_STOP
1990} builtin_arg;
1991
1992#define NEON_MAX_BUILTIN_ARGS 5
1993
1994/* EXP is a pointer argument to a Neon load or store intrinsic. Derive
1995 and return an expression for the accessed memory.
1996
1997 The intrinsic function operates on a block of registers that has
1998 mode REG_MODE. This block contains vectors of type TYPE_MODE. The
1999 function references the memory at EXP of type TYPE and in mode
2000 MEM_MODE; this mode may be BLKmode if no more suitable mode is
2001 available. */
2002
2003static tree
2004neon_dereference_pointer (tree exp, tree type, machine_mode mem_mode,
2005 machine_mode reg_mode,
c7796b7e 2006 machine_mode vector_mode)
d6504d76 2007{
2008 HOST_WIDE_INT reg_size, vector_size, nvectors, nelems;
2009 tree elem_type, upper_bound, array_type;
2010
2011 /* Work out the size of the register block in bytes. */
2012 reg_size = GET_MODE_SIZE (reg_mode);
2013
2014 /* Work out the size of each vector in bytes. */
c7796b7e 2015 vector_size = GET_MODE_SIZE (vector_mode);
d6504d76 2016
2017 /* Work out how many vectors there are. */
2018 gcc_assert (reg_size % vector_size == 0);
2019 nvectors = reg_size / vector_size;
2020
2021 /* Work out the type of each element. */
2022 gcc_assert (POINTER_TYPE_P (type));
2023 elem_type = TREE_TYPE (type);
2024
2025 /* Work out how many elements are being loaded or stored.
2026 MEM_MODE == REG_MODE implies a one-to-one mapping between register
2027 and memory elements; anything else implies a lane load or store. */
2028 if (mem_mode == reg_mode)
2029 nelems = vector_size * nvectors / int_size_in_bytes (elem_type);
2030 else
2031 nelems = nvectors;
2032
2033 /* Create a type that describes the full access. */
2034 upper_bound = build_int_cst (size_type_node, nelems - 1);
2035 array_type = build_array_type (elem_type, build_index_type (upper_bound));
2036
2037 /* Dereference EXP using that type. */
2038 return fold_build2 (MEM_REF, array_type, exp,
2039 build_int_cst (build_pointer_type (array_type), 0));
2040}
2041
2042/* Expand a Neon builtin. */
2043static rtx
c7796b7e 2044arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
d4023b2c 2045 int icode, int have_retval, tree exp,
2046 builtin_arg *args)
d6504d76 2047{
d6504d76 2048 rtx pat;
c7796b7e 2049 tree arg[SIMD_MAX_BUILTIN_ARGS];
2050 rtx op[SIMD_MAX_BUILTIN_ARGS];
d6504d76 2051 machine_mode tmode = insn_data[icode].operand[0].mode;
c7796b7e 2052 machine_mode mode[SIMD_MAX_BUILTIN_ARGS];
2053 tree formals;
d6504d76 2054 int argc = 0;
d6504d76 2055
2056 if (have_retval
2057 && (!target
2058 || GET_MODE (target) != tmode
2059 || !(*insn_data[icode].operand[0].predicate) (target, tmode)))
2060 target = gen_reg_rtx (tmode);
2061
d6504d76 2062 formals = TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls[fcode]));
2063
2064 for (;;)
2065 {
d4023b2c 2066 builtin_arg thisarg = args[argc];
d6504d76 2067
2068 if (thisarg == NEON_ARG_STOP)
c7796b7e 2069 break;
d6504d76 2070 else
c7796b7e 2071 {
2072 int opno = argc + have_retval;
2073 arg[argc] = CALL_EXPR_ARG (exp, argc);
2074 mode[argc] = insn_data[icode].operand[opno].mode;
d6504d76 2075 if (thisarg == NEON_ARG_MEMORY)
2076 {
c7796b7e 2077 machine_mode other_mode
2078 = insn_data[icode].operand[1 - opno].mode;
2079 arg[argc] = neon_dereference_pointer (arg[argc],
2080 TREE_VALUE (formals),
d6504d76 2081 mode[argc], other_mode,
c7796b7e 2082 map_mode);
d6504d76 2083 }
2084
2085 /* Use EXPAND_MEMORY for NEON_ARG_MEMORY to ensure a MEM_P
2086 be returned. */
2087 op[argc] = expand_expr (arg[argc], NULL_RTX, VOIDmode,
2088 (thisarg == NEON_ARG_MEMORY
2089 ? EXPAND_MEMORY : EXPAND_NORMAL));
2090
c7796b7e 2091 switch (thisarg)
2092 {
2093 case NEON_ARG_COPY_TO_REG:
2094 if (POINTER_TYPE_P (TREE_TYPE (arg[argc])))
2095 op[argc] = convert_memory_address (Pmode, op[argc]);
2096 /*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */
2097 if (!(*insn_data[icode].operand[opno].predicate)
2098 (op[argc], mode[argc]))
2099 op[argc] = copy_to_mode_reg (mode[argc], op[argc]);
2100 break;
d6504d76 2101
d4023b2c 2102 case NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX:
2103 gcc_assert (argc > 1);
2104 if (CONST_INT_P (op[argc]))
2105 {
2106 neon_lane_bounds (op[argc], 0,
2107 GET_MODE_NUNITS (map_mode), exp);
2108 /* Keep to GCC-vector-extension lane indices in the RTL. */
2109 op[argc] =
2110 GEN_INT (NEON_ENDIAN_LANE_N (map_mode, INTVAL (op[argc])));
2111 }
2112 goto constant_arg;
2113
505e1f91 2114 case NEON_ARG_LANE_INDEX:
2115 /* Previous argument must be a vector, which this indexes. */
2116 gcc_assert (argc > 0);
2117 if (CONST_INT_P (op[argc]))
2118 {
2119 enum machine_mode vmode = mode[argc - 1];
2120 neon_lane_bounds (op[argc], 0, GET_MODE_NUNITS (vmode), exp);
2121 }
2122 /* Fall through - if the lane index isn't a constant then
2123 the next case will error. */
d4023b2c 2124
c7796b7e 2125 case NEON_ARG_CONSTANT:
d4023b2c 2126constant_arg:
c7796b7e 2127 if (!(*insn_data[icode].operand[opno].predicate)
2128 (op[argc], mode[argc]))
d4023b2c 2129 {
2130 error ("%Kargument %d must be a constant immediate",
2131 exp, argc + 1);
2132 return const0_rtx;
2133 }
c7796b7e 2134 break;
d4023b2c 2135
d6504d76 2136 case NEON_ARG_MEMORY:
2137 /* Check if expand failed. */
2138 if (op[argc] == const0_rtx)
2139 return 0;
2140 gcc_assert (MEM_P (op[argc]));
2141 PUT_MODE (op[argc], mode[argc]);
2142 /* ??? arm_neon.h uses the same built-in functions for signed
2143 and unsigned accesses, casting where necessary. This isn't
2144 alias safe. */
2145 set_mem_alias_set (op[argc], 0);
2146 if (!(*insn_data[icode].operand[opno].predicate)
c7796b7e 2147 (op[argc], mode[argc]))
d6504d76 2148 op[argc] = (replace_equiv_address
2149 (op[argc], force_reg (Pmode, XEXP (op[argc], 0))));
2150 break;
2151
c7796b7e 2152 case NEON_ARG_STOP:
2153 gcc_unreachable ();
2154 }
d6504d76 2155
c7796b7e 2156 argc++;
2157 }
d6504d76 2158 }
2159
d6504d76 2160 if (have_retval)
2161 switch (argc)
2162 {
2163 case 1:
2164 pat = GEN_FCN (icode) (target, op[0]);
2165 break;
2166
2167 case 2:
2168 pat = GEN_FCN (icode) (target, op[0], op[1]);
2169 break;
2170
2171 case 3:
2172 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2173 break;
2174
2175 case 4:
2176 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2177 break;
2178
2179 case 5:
2180 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]);
2181 break;
2182
2183 default:
2184 gcc_unreachable ();
2185 }
2186 else
2187 switch (argc)
2188 {
2189 case 1:
2190 pat = GEN_FCN (icode) (op[0]);
2191 break;
2192
2193 case 2:
2194 pat = GEN_FCN (icode) (op[0], op[1]);
2195 break;
2196
2197 case 3:
2198 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2199 break;
2200
2201 case 4:
2202 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2203 break;
2204
2205 case 5:
2206 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
c7796b7e 2207 break;
d6504d76 2208
2209 default:
2210 gcc_unreachable ();
2211 }
2212
2213 if (!pat)
2214 return 0;
2215
2216 emit_insn (pat);
2217
2218 return target;
2219}
2220
732205bc 2221/* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds.
2222 Most of these are "special" because they don't have symbolic
d6504d76 2223 constants defined per-instruction or per instruction-variant. Instead, the
2224 required info is looked up in the table neon_builtin_data. */
2225static rtx
2226arm_expand_neon_builtin (int fcode, tree exp, rtx target)
2227{
732205bc 2228 if (fcode == ARM_BUILTIN_NEON_LANE_CHECK)
2229 {
2230 /* Builtin is only to check bounds of the lane passed to some intrinsics
2231 that are implemented with gcc vector extensions in arm_neon.h. */
2232
2233 tree nlanes = CALL_EXPR_ARG (exp, 0);
2234 gcc_assert (TREE_CODE (nlanes) == INTEGER_CST);
2235 rtx lane_idx = expand_normal (CALL_EXPR_ARG (exp, 1));
2236 if (CONST_INT_P (lane_idx))
2237 neon_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp);
2238 else
2239 error ("%Klane index must be a constant immediate", exp);
2240 /* Don't generate any RTL. */
2241 return const0_rtx;
2242 }
2243
c7796b7e 2244 neon_builtin_datum *d =
732205bc 2245 &neon_builtin_data[fcode - ARM_BUILTIN_NEON_PATTERN_START];
d6504d76 2246 enum insn_code icode = d->code;
c7796b7e 2247 builtin_arg args[SIMD_MAX_BUILTIN_ARGS];
2248 int num_args = insn_data[d->code].n_operands;
2249 int is_void = 0;
2250 int k;
2251
2252 is_void = !!(d->qualifiers[0] & qualifier_void);
d6504d76 2253
c7796b7e 2254 num_args += is_void;
2255
2256 for (k = 1; k < num_args; k++)
d6504d76 2257 {
c7796b7e 2258 /* We have four arrays of data, each indexed in a different fashion.
2259 qualifiers - element 0 always describes the function return type.
2260 operands - element 0 is either the operand for return value (if
2261 the function has a non-void return type) or the operand for the
2262 first argument.
2263 expr_args - element 0 always holds the first argument.
2264 args - element 0 is always used for the return type. */
2265 int qualifiers_k = k;
2266 int operands_k = k - is_void;
2267 int expr_args_k = k - 1;
2268
505e1f91 2269 if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
2270 args[k] = NEON_ARG_LANE_INDEX;
d4023b2c 2271 else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
2272 args[k] = NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX;
505e1f91 2273 else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
c7796b7e 2274 args[k] = NEON_ARG_CONSTANT;
2275 else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
2276 {
2277 rtx arg
2278 = expand_normal (CALL_EXPR_ARG (exp,
2279 (expr_args_k)));
2280 /* Handle constants only if the predicate allows it. */
2281 bool op_const_int_p =
2282 (CONST_INT_P (arg)
2283 && (*insn_data[icode].operand[operands_k].predicate)
2284 (arg, insn_data[icode].operand[operands_k].mode));
2285 args[k] = op_const_int_p ? NEON_ARG_CONSTANT : NEON_ARG_COPY_TO_REG;
2286 }
2287 else if (d->qualifiers[qualifiers_k] & qualifier_pointer)
2288 args[k] = NEON_ARG_MEMORY;
2289 else
2290 args[k] = NEON_ARG_COPY_TO_REG;
d6504d76 2291 }
c7796b7e 2292 args[k] = NEON_ARG_STOP;
2293
2294 /* The interface to arm_expand_neon_args expects a 0 if
2295 the function is void, and a 1 if it is not. */
2296 return arm_expand_neon_args
2297 (target, d->mode, fcode, icode, !is_void, exp,
d4023b2c 2298 &args[1]);
d6504d76 2299}
2300
2301/* Expand an expression EXP that calls a built-in function,
2302 with result going to TARGET if that's convenient
2303 (and in mode MODE if that's convenient).
2304 SUBTARGET may be used as the target for computing one of EXP's operands.
2305 IGNORE is nonzero if the value is to be ignored. */
2306
2307rtx
2308arm_expand_builtin (tree exp,
2309 rtx target,
2310 rtx subtarget ATTRIBUTE_UNUSED,
2311 machine_mode mode ATTRIBUTE_UNUSED,
2312 int ignore ATTRIBUTE_UNUSED)
2313{
2314 const struct builtin_description * d;
2315 enum insn_code icode;
2316 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2317 tree arg0;
2318 tree arg1;
2319 tree arg2;
2320 rtx op0;
2321 rtx op1;
2322 rtx op2;
2323 rtx pat;
2324 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2325 size_t i;
2326 machine_mode tmode;
2327 machine_mode mode0;
2328 machine_mode mode1;
2329 machine_mode mode2;
2330 int opint;
2331 int selector;
2332 int mask;
2333 int imm;
2334
2335 if (fcode >= ARM_BUILTIN_NEON_BASE)
2336 return arm_expand_neon_builtin (fcode, exp, target);
2337
2338 switch (fcode)
2339 {
2340 case ARM_BUILTIN_GET_FPSCR:
2341 case ARM_BUILTIN_SET_FPSCR:
2342 if (fcode == ARM_BUILTIN_GET_FPSCR)
2343 {
2344 icode = CODE_FOR_get_fpscr;
2345 target = gen_reg_rtx (SImode);
2346 pat = GEN_FCN (icode) (target);
2347 }
2348 else
2349 {
2350 target = NULL_RTX;
2351 icode = CODE_FOR_set_fpscr;
2352 arg0 = CALL_EXPR_ARG (exp, 0);
2353 op0 = expand_normal (arg0);
2354 pat = GEN_FCN (icode) (op0);
2355 }
2356 emit_insn (pat);
2357 return target;
2358
2359 case ARM_BUILTIN_TEXTRMSB:
2360 case ARM_BUILTIN_TEXTRMUB:
2361 case ARM_BUILTIN_TEXTRMSH:
2362 case ARM_BUILTIN_TEXTRMUH:
2363 case ARM_BUILTIN_TEXTRMSW:
2364 case ARM_BUILTIN_TEXTRMUW:
2365 icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
2366 : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
2367 : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
2368 : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
2369 : CODE_FOR_iwmmxt_textrmw);
2370
2371 arg0 = CALL_EXPR_ARG (exp, 0);
2372 arg1 = CALL_EXPR_ARG (exp, 1);
2373 op0 = expand_normal (arg0);
2374 op1 = expand_normal (arg1);
2375 tmode = insn_data[icode].operand[0].mode;
2376 mode0 = insn_data[icode].operand[1].mode;
2377 mode1 = insn_data[icode].operand[2].mode;
2378
2379 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2380 op0 = copy_to_mode_reg (mode0, op0);
2381 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2382 {
2383 /* @@@ better error message */
2384 error ("selector must be an immediate");
2385 return gen_reg_rtx (tmode);
2386 }
2387
2388 opint = INTVAL (op1);
2389 if (fcode == ARM_BUILTIN_TEXTRMSB || fcode == ARM_BUILTIN_TEXTRMUB)
2390 {
2391 if (opint > 7 || opint < 0)
2392 error ("the range of selector should be in 0 to 7");
2393 }
2394 else if (fcode == ARM_BUILTIN_TEXTRMSH || fcode == ARM_BUILTIN_TEXTRMUH)
2395 {
2396 if (opint > 3 || opint < 0)
2397 error ("the range of selector should be in 0 to 3");
2398 }
2399 else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */
2400 {
2401 if (opint > 1 || opint < 0)
2402 error ("the range of selector should be in 0 to 1");
2403 }
2404
2405 if (target == 0
2406 || GET_MODE (target) != tmode
2407 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2408 target = gen_reg_rtx (tmode);
2409 pat = GEN_FCN (icode) (target, op0, op1);
2410 if (! pat)
2411 return 0;
2412 emit_insn (pat);
2413 return target;
2414
2415 case ARM_BUILTIN_WALIGNI:
2416 /* If op2 is immediate, call walighi, else call walighr. */
2417 arg0 = CALL_EXPR_ARG (exp, 0);
2418 arg1 = CALL_EXPR_ARG (exp, 1);
2419 arg2 = CALL_EXPR_ARG (exp, 2);
2420 op0 = expand_normal (arg0);
2421 op1 = expand_normal (arg1);
2422 op2 = expand_normal (arg2);
2423 if (CONST_INT_P (op2))
2424 {
2425 icode = CODE_FOR_iwmmxt_waligni;
2426 tmode = insn_data[icode].operand[0].mode;
2427 mode0 = insn_data[icode].operand[1].mode;
2428 mode1 = insn_data[icode].operand[2].mode;
2429 mode2 = insn_data[icode].operand[3].mode;
2430 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
2431 op0 = copy_to_mode_reg (mode0, op0);
2432 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
2433 op1 = copy_to_mode_reg (mode1, op1);
2434 gcc_assert ((*insn_data[icode].operand[3].predicate) (op2, mode2));
2435 selector = INTVAL (op2);
2436 if (selector > 7 || selector < 0)
2437 error ("the range of selector should be in 0 to 7");
2438 }
2439 else
2440 {
2441 icode = CODE_FOR_iwmmxt_walignr;
2442 tmode = insn_data[icode].operand[0].mode;
2443 mode0 = insn_data[icode].operand[1].mode;
2444 mode1 = insn_data[icode].operand[2].mode;
2445 mode2 = insn_data[icode].operand[3].mode;
2446 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
2447 op0 = copy_to_mode_reg (mode0, op0);
2448 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
2449 op1 = copy_to_mode_reg (mode1, op1);
2450 if (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
2451 op2 = copy_to_mode_reg (mode2, op2);
2452 }
2453 if (target == 0
2454 || GET_MODE (target) != tmode
2455 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
2456 target = gen_reg_rtx (tmode);
2457 pat = GEN_FCN (icode) (target, op0, op1, op2);
2458 if (!pat)
2459 return 0;
2460 emit_insn (pat);
2461 return target;
2462
2463 case ARM_BUILTIN_TINSRB:
2464 case ARM_BUILTIN_TINSRH:
2465 case ARM_BUILTIN_TINSRW:
2466 case ARM_BUILTIN_WMERGE:
2467 icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
2468 : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
2469 : fcode == ARM_BUILTIN_WMERGE ? CODE_FOR_iwmmxt_wmerge
2470 : CODE_FOR_iwmmxt_tinsrw);
2471 arg0 = CALL_EXPR_ARG (exp, 0);
2472 arg1 = CALL_EXPR_ARG (exp, 1);
2473 arg2 = CALL_EXPR_ARG (exp, 2);
2474 op0 = expand_normal (arg0);
2475 op1 = expand_normal (arg1);
2476 op2 = expand_normal (arg2);
2477 tmode = insn_data[icode].operand[0].mode;
2478 mode0 = insn_data[icode].operand[1].mode;
2479 mode1 = insn_data[icode].operand[2].mode;
2480 mode2 = insn_data[icode].operand[3].mode;
2481
2482 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2483 op0 = copy_to_mode_reg (mode0, op0);
2484 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2485 op1 = copy_to_mode_reg (mode1, op1);
2486 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
2487 {
2488 error ("selector must be an immediate");
2489 return const0_rtx;
2490 }
2491 if (icode == CODE_FOR_iwmmxt_wmerge)
2492 {
2493 selector = INTVAL (op2);
2494 if (selector > 7 || selector < 0)
2495 error ("the range of selector should be in 0 to 7");
2496 }
2497 if ((icode == CODE_FOR_iwmmxt_tinsrb)
2498 || (icode == CODE_FOR_iwmmxt_tinsrh)
2499 || (icode == CODE_FOR_iwmmxt_tinsrw))
2500 {
2501 mask = 0x01;
2502 selector= INTVAL (op2);
2503 if (icode == CODE_FOR_iwmmxt_tinsrb && (selector < 0 || selector > 7))
2504 error ("the range of selector should be in 0 to 7");
2505 else if (icode == CODE_FOR_iwmmxt_tinsrh && (selector < 0 ||selector > 3))
2506 error ("the range of selector should be in 0 to 3");
2507 else if (icode == CODE_FOR_iwmmxt_tinsrw && (selector < 0 ||selector > 1))
2508 error ("the range of selector should be in 0 to 1");
2509 mask <<= selector;
2510 op2 = GEN_INT (mask);
2511 }
2512 if (target == 0
2513 || GET_MODE (target) != tmode
2514 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2515 target = gen_reg_rtx (tmode);
2516 pat = GEN_FCN (icode) (target, op0, op1, op2);
2517 if (! pat)
2518 return 0;
2519 emit_insn (pat);
2520 return target;
2521
2522 case ARM_BUILTIN_SETWCGR0:
2523 case ARM_BUILTIN_SETWCGR1:
2524 case ARM_BUILTIN_SETWCGR2:
2525 case ARM_BUILTIN_SETWCGR3:
2526 icode = (fcode == ARM_BUILTIN_SETWCGR0 ? CODE_FOR_iwmmxt_setwcgr0
2527 : fcode == ARM_BUILTIN_SETWCGR1 ? CODE_FOR_iwmmxt_setwcgr1
2528 : fcode == ARM_BUILTIN_SETWCGR2 ? CODE_FOR_iwmmxt_setwcgr2
2529 : CODE_FOR_iwmmxt_setwcgr3);
2530 arg0 = CALL_EXPR_ARG (exp, 0);
2531 op0 = expand_normal (arg0);
2532 mode0 = insn_data[icode].operand[0].mode;
2533 if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
2534 op0 = copy_to_mode_reg (mode0, op0);
2535 pat = GEN_FCN (icode) (op0);
2536 if (!pat)
2537 return 0;
2538 emit_insn (pat);
2539 return 0;
2540
2541 case ARM_BUILTIN_GETWCGR0:
2542 case ARM_BUILTIN_GETWCGR1:
2543 case ARM_BUILTIN_GETWCGR2:
2544 case ARM_BUILTIN_GETWCGR3:
2545 icode = (fcode == ARM_BUILTIN_GETWCGR0 ? CODE_FOR_iwmmxt_getwcgr0
2546 : fcode == ARM_BUILTIN_GETWCGR1 ? CODE_FOR_iwmmxt_getwcgr1
2547 : fcode == ARM_BUILTIN_GETWCGR2 ? CODE_FOR_iwmmxt_getwcgr2
2548 : CODE_FOR_iwmmxt_getwcgr3);
2549 tmode = insn_data[icode].operand[0].mode;
2550 if (target == 0
2551 || GET_MODE (target) != tmode
2552 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
2553 target = gen_reg_rtx (tmode);
2554 pat = GEN_FCN (icode) (target);
2555 if (!pat)
2556 return 0;
2557 emit_insn (pat);
2558 return target;
2559
2560 case ARM_BUILTIN_WSHUFH:
2561 icode = CODE_FOR_iwmmxt_wshufh;
2562 arg0 = CALL_EXPR_ARG (exp, 0);
2563 arg1 = CALL_EXPR_ARG (exp, 1);
2564 op0 = expand_normal (arg0);
2565 op1 = expand_normal (arg1);
2566 tmode = insn_data[icode].operand[0].mode;
2567 mode1 = insn_data[icode].operand[1].mode;
2568 mode2 = insn_data[icode].operand[2].mode;
2569
2570 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
2571 op0 = copy_to_mode_reg (mode1, op0);
2572 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
2573 {
2574 error ("mask must be an immediate");
2575 return const0_rtx;
2576 }
2577 selector = INTVAL (op1);
2578 if (selector < 0 || selector > 255)
2579 error ("the range of mask should be in 0 to 255");
2580 if (target == 0
2581 || GET_MODE (target) != tmode
2582 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2583 target = gen_reg_rtx (tmode);
2584 pat = GEN_FCN (icode) (target, op0, op1);
2585 if (! pat)
2586 return 0;
2587 emit_insn (pat);
2588 return target;
2589
2590 case ARM_BUILTIN_WMADDS:
2591 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds, exp, target);
2592 case ARM_BUILTIN_WMADDSX:
2593 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx, exp, target);
2594 case ARM_BUILTIN_WMADDSN:
2595 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn, exp, target);
2596 case ARM_BUILTIN_WMADDU:
2597 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu, exp, target);
2598 case ARM_BUILTIN_WMADDUX:
2599 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux, exp, target);
2600 case ARM_BUILTIN_WMADDUN:
2601 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun, exp, target);
2602 case ARM_BUILTIN_WSADBZ:
2603 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target);
2604 case ARM_BUILTIN_WSADHZ:
2605 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, exp, target);
2606
2607 /* Several three-argument builtins. */
2608 case ARM_BUILTIN_WMACS:
2609 case ARM_BUILTIN_WMACU:
2610 case ARM_BUILTIN_TMIA:
2611 case ARM_BUILTIN_TMIAPH:
2612 case ARM_BUILTIN_TMIATT:
2613 case ARM_BUILTIN_TMIATB:
2614 case ARM_BUILTIN_TMIABT:
2615 case ARM_BUILTIN_TMIABB:
2616 case ARM_BUILTIN_WQMIABB:
2617 case ARM_BUILTIN_WQMIABT:
2618 case ARM_BUILTIN_WQMIATB:
2619 case ARM_BUILTIN_WQMIATT:
2620 case ARM_BUILTIN_WQMIABBN:
2621 case ARM_BUILTIN_WQMIABTN:
2622 case ARM_BUILTIN_WQMIATBN:
2623 case ARM_BUILTIN_WQMIATTN:
2624 case ARM_BUILTIN_WMIABB:
2625 case ARM_BUILTIN_WMIABT:
2626 case ARM_BUILTIN_WMIATB:
2627 case ARM_BUILTIN_WMIATT:
2628 case ARM_BUILTIN_WMIABBN:
2629 case ARM_BUILTIN_WMIABTN:
2630 case ARM_BUILTIN_WMIATBN:
2631 case ARM_BUILTIN_WMIATTN:
2632 case ARM_BUILTIN_WMIAWBB:
2633 case ARM_BUILTIN_WMIAWBT:
2634 case ARM_BUILTIN_WMIAWTB:
2635 case ARM_BUILTIN_WMIAWTT:
2636 case ARM_BUILTIN_WMIAWBBN:
2637 case ARM_BUILTIN_WMIAWBTN:
2638 case ARM_BUILTIN_WMIAWTBN:
2639 case ARM_BUILTIN_WMIAWTTN:
2640 case ARM_BUILTIN_WSADB:
2641 case ARM_BUILTIN_WSADH:
2642 icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
2643 : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
2644 : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
2645 : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
2646 : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
2647 : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
2648 : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
2649 : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
2650 : fcode == ARM_BUILTIN_WQMIABB ? CODE_FOR_iwmmxt_wqmiabb
2651 : fcode == ARM_BUILTIN_WQMIABT ? CODE_FOR_iwmmxt_wqmiabt
2652 : fcode == ARM_BUILTIN_WQMIATB ? CODE_FOR_iwmmxt_wqmiatb
2653 : fcode == ARM_BUILTIN_WQMIATT ? CODE_FOR_iwmmxt_wqmiatt
2654 : fcode == ARM_BUILTIN_WQMIABBN ? CODE_FOR_iwmmxt_wqmiabbn
2655 : fcode == ARM_BUILTIN_WQMIABTN ? CODE_FOR_iwmmxt_wqmiabtn
2656 : fcode == ARM_BUILTIN_WQMIATBN ? CODE_FOR_iwmmxt_wqmiatbn
2657 : fcode == ARM_BUILTIN_WQMIATTN ? CODE_FOR_iwmmxt_wqmiattn
2658 : fcode == ARM_BUILTIN_WMIABB ? CODE_FOR_iwmmxt_wmiabb
2659 : fcode == ARM_BUILTIN_WMIABT ? CODE_FOR_iwmmxt_wmiabt
2660 : fcode == ARM_BUILTIN_WMIATB ? CODE_FOR_iwmmxt_wmiatb
2661 : fcode == ARM_BUILTIN_WMIATT ? CODE_FOR_iwmmxt_wmiatt
2662 : fcode == ARM_BUILTIN_WMIABBN ? CODE_FOR_iwmmxt_wmiabbn
2663 : fcode == ARM_BUILTIN_WMIABTN ? CODE_FOR_iwmmxt_wmiabtn
2664 : fcode == ARM_BUILTIN_WMIATBN ? CODE_FOR_iwmmxt_wmiatbn
2665 : fcode == ARM_BUILTIN_WMIATTN ? CODE_FOR_iwmmxt_wmiattn
2666 : fcode == ARM_BUILTIN_WMIAWBB ? CODE_FOR_iwmmxt_wmiawbb
2667 : fcode == ARM_BUILTIN_WMIAWBT ? CODE_FOR_iwmmxt_wmiawbt
2668 : fcode == ARM_BUILTIN_WMIAWTB ? CODE_FOR_iwmmxt_wmiawtb
2669 : fcode == ARM_BUILTIN_WMIAWTT ? CODE_FOR_iwmmxt_wmiawtt
2670 : fcode == ARM_BUILTIN_WMIAWBBN ? CODE_FOR_iwmmxt_wmiawbbn
2671 : fcode == ARM_BUILTIN_WMIAWBTN ? CODE_FOR_iwmmxt_wmiawbtn
2672 : fcode == ARM_BUILTIN_WMIAWTBN ? CODE_FOR_iwmmxt_wmiawtbn
2673 : fcode == ARM_BUILTIN_WMIAWTTN ? CODE_FOR_iwmmxt_wmiawttn
2674 : fcode == ARM_BUILTIN_WSADB ? CODE_FOR_iwmmxt_wsadb
2675 : CODE_FOR_iwmmxt_wsadh);
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 tmode = insn_data[icode].operand[0].mode;
2683 mode0 = insn_data[icode].operand[1].mode;
2684 mode1 = insn_data[icode].operand[2].mode;
2685 mode2 = insn_data[icode].operand[3].mode;
2686
2687 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2688 op0 = copy_to_mode_reg (mode0, op0);
2689 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2690 op1 = copy_to_mode_reg (mode1, op1);
2691 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
2692 op2 = copy_to_mode_reg (mode2, op2);
2693 if (target == 0
2694 || GET_MODE (target) != tmode
2695 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2696 target = gen_reg_rtx (tmode);
2697 pat = GEN_FCN (icode) (target, op0, op1, op2);
2698 if (! pat)
2699 return 0;
2700 emit_insn (pat);
2701 return target;
2702
2703 case ARM_BUILTIN_WZERO:
2704 target = gen_reg_rtx (DImode);
2705 emit_insn (gen_iwmmxt_clrdi (target));
2706 return target;
2707
2708 case ARM_BUILTIN_WSRLHI:
2709 case ARM_BUILTIN_WSRLWI:
2710 case ARM_BUILTIN_WSRLDI:
2711 case ARM_BUILTIN_WSLLHI:
2712 case ARM_BUILTIN_WSLLWI:
2713 case ARM_BUILTIN_WSLLDI:
2714 case ARM_BUILTIN_WSRAHI:
2715 case ARM_BUILTIN_WSRAWI:
2716 case ARM_BUILTIN_WSRADI:
2717 case ARM_BUILTIN_WRORHI:
2718 case ARM_BUILTIN_WRORWI:
2719 case ARM_BUILTIN_WRORDI:
2720 case ARM_BUILTIN_WSRLH:
2721 case ARM_BUILTIN_WSRLW:
2722 case ARM_BUILTIN_WSRLD:
2723 case ARM_BUILTIN_WSLLH:
2724 case ARM_BUILTIN_WSLLW:
2725 case ARM_BUILTIN_WSLLD:
2726 case ARM_BUILTIN_WSRAH:
2727 case ARM_BUILTIN_WSRAW:
2728 case ARM_BUILTIN_WSRAD:
2729 case ARM_BUILTIN_WRORH:
2730 case ARM_BUILTIN_WRORW:
2731 case ARM_BUILTIN_WRORD:
2732 icode = (fcode == ARM_BUILTIN_WSRLHI ? CODE_FOR_lshrv4hi3_iwmmxt
2733 : fcode == ARM_BUILTIN_WSRLWI ? CODE_FOR_lshrv2si3_iwmmxt
2734 : fcode == ARM_BUILTIN_WSRLDI ? CODE_FOR_lshrdi3_iwmmxt
2735 : fcode == ARM_BUILTIN_WSLLHI ? CODE_FOR_ashlv4hi3_iwmmxt
2736 : fcode == ARM_BUILTIN_WSLLWI ? CODE_FOR_ashlv2si3_iwmmxt
2737 : fcode == ARM_BUILTIN_WSLLDI ? CODE_FOR_ashldi3_iwmmxt
2738 : fcode == ARM_BUILTIN_WSRAHI ? CODE_FOR_ashrv4hi3_iwmmxt
2739 : fcode == ARM_BUILTIN_WSRAWI ? CODE_FOR_ashrv2si3_iwmmxt
2740 : fcode == ARM_BUILTIN_WSRADI ? CODE_FOR_ashrdi3_iwmmxt
2741 : fcode == ARM_BUILTIN_WRORHI ? CODE_FOR_rorv4hi3
2742 : fcode == ARM_BUILTIN_WRORWI ? CODE_FOR_rorv2si3
2743 : fcode == ARM_BUILTIN_WRORDI ? CODE_FOR_rordi3
2744 : fcode == ARM_BUILTIN_WSRLH ? CODE_FOR_lshrv4hi3_di
2745 : fcode == ARM_BUILTIN_WSRLW ? CODE_FOR_lshrv2si3_di
2746 : fcode == ARM_BUILTIN_WSRLD ? CODE_FOR_lshrdi3_di
2747 : fcode == ARM_BUILTIN_WSLLH ? CODE_FOR_ashlv4hi3_di
2748 : fcode == ARM_BUILTIN_WSLLW ? CODE_FOR_ashlv2si3_di
2749 : fcode == ARM_BUILTIN_WSLLD ? CODE_FOR_ashldi3_di
2750 : fcode == ARM_BUILTIN_WSRAH ? CODE_FOR_ashrv4hi3_di
2751 : fcode == ARM_BUILTIN_WSRAW ? CODE_FOR_ashrv2si3_di
2752 : fcode == ARM_BUILTIN_WSRAD ? CODE_FOR_ashrdi3_di
2753 : fcode == ARM_BUILTIN_WRORH ? CODE_FOR_rorv4hi3_di
2754 : fcode == ARM_BUILTIN_WRORW ? CODE_FOR_rorv2si3_di
2755 : fcode == ARM_BUILTIN_WRORD ? CODE_FOR_rordi3_di
2756 : CODE_FOR_nothing);
2757 arg1 = CALL_EXPR_ARG (exp, 1);
2758 op1 = expand_normal (arg1);
2759 if (GET_MODE (op1) == VOIDmode)
2760 {
2761 imm = INTVAL (op1);
2762 if ((fcode == ARM_BUILTIN_WRORHI || fcode == ARM_BUILTIN_WRORWI
2763 || fcode == ARM_BUILTIN_WRORH || fcode == ARM_BUILTIN_WRORW)
2764 && (imm < 0 || imm > 32))
2765 {
2766 if (fcode == ARM_BUILTIN_WRORHI)
2767 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi16 in code.");
2768 else if (fcode == ARM_BUILTIN_WRORWI)
2769 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi32 in code.");
2770 else if (fcode == ARM_BUILTIN_WRORH)
2771 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi16 in code.");
2772 else
2773 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi32 in code.");
2774 }
2775 else if ((fcode == ARM_BUILTIN_WRORDI || fcode == ARM_BUILTIN_WRORD)
2776 && (imm < 0 || imm > 64))
2777 {
2778 if (fcode == ARM_BUILTIN_WRORDI)
2779 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_rori_si64 in code.");
2780 else
2781 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_ror_si64 in code.");
2782 }
2783 else if (imm < 0)
2784 {
2785 if (fcode == ARM_BUILTIN_WSRLHI)
2786 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi16 in code.");
2787 else if (fcode == ARM_BUILTIN_WSRLWI)
2788 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi32 in code.");
2789 else if (fcode == ARM_BUILTIN_WSRLDI)
2790 error ("the count should be no less than 0. please check the intrinsic _mm_srli_si64 in code.");
2791 else if (fcode == ARM_BUILTIN_WSLLHI)
2792 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi16 in code.");
2793 else if (fcode == ARM_BUILTIN_WSLLWI)
2794 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi32 in code.");
2795 else if (fcode == ARM_BUILTIN_WSLLDI)
2796 error ("the count should be no less than 0. please check the intrinsic _mm_slli_si64 in code.");
2797 else if (fcode == ARM_BUILTIN_WSRAHI)
2798 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi16 in code.");
2799 else if (fcode == ARM_BUILTIN_WSRAWI)
2800 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi32 in code.");
2801 else if (fcode == ARM_BUILTIN_WSRADI)
2802 error ("the count should be no less than 0. please check the intrinsic _mm_srai_si64 in code.");
2803 else if (fcode == ARM_BUILTIN_WSRLH)
2804 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi16 in code.");
2805 else if (fcode == ARM_BUILTIN_WSRLW)
2806 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi32 in code.");
2807 else if (fcode == ARM_BUILTIN_WSRLD)
2808 error ("the count should be no less than 0. please check the intrinsic _mm_srl_si64 in code.");
2809 else if (fcode == ARM_BUILTIN_WSLLH)
2810 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi16 in code.");
2811 else if (fcode == ARM_BUILTIN_WSLLW)
2812 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi32 in code.");
2813 else if (fcode == ARM_BUILTIN_WSLLD)
2814 error ("the count should be no less than 0. please check the intrinsic _mm_sll_si64 in code.");
2815 else if (fcode == ARM_BUILTIN_WSRAH)
2816 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi16 in code.");
2817 else if (fcode == ARM_BUILTIN_WSRAW)
2818 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi32 in code.");
2819 else
2820 error ("the count should be no less than 0. please check the intrinsic _mm_sra_si64 in code.");
2821 }
2822 }
2823 return arm_expand_binop_builtin (icode, exp, target);
2824
2825 default:
2826 break;
2827 }
2828
2829 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
2830 if (d->code == (const enum arm_builtins) fcode)
2831 return arm_expand_binop_builtin (d->icode, exp, target);
2832
2833 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2834 if (d->code == (const enum arm_builtins) fcode)
2835 return arm_expand_unop_builtin (d->icode, exp, target, 0);
2836
2837 for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2838 if (d->code == (const enum arm_builtins) fcode)
2839 return arm_expand_ternop_builtin (d->icode, exp, target);
2840
2841 /* @@@ Should really do something sensible here. */
2842 return NULL_RTX;
2843}
2844
2845tree
b6c464fe 2846arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in)
d6504d76 2847{
2848 machine_mode in_mode, out_mode;
2849 int in_n, out_n;
2850 bool out_unsigned_p = TYPE_UNSIGNED (type_out);
2851
2852 if (TREE_CODE (type_out) != VECTOR_TYPE
2853 || TREE_CODE (type_in) != VECTOR_TYPE)
2854 return NULL_TREE;
2855
2856 out_mode = TYPE_MODE (TREE_TYPE (type_out));
2857 out_n = TYPE_VECTOR_SUBPARTS (type_out);
2858 in_mode = TYPE_MODE (TREE_TYPE (type_in));
2859 in_n = TYPE_VECTOR_SUBPARTS (type_in);
2860
2861/* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the
2862 decl of the vectorized builtin for the appropriate vector mode.
2863 NULL_TREE is returned if no such builtin is available. */
2864#undef ARM_CHECK_BUILTIN_MODE
2865#define ARM_CHECK_BUILTIN_MODE(C) \
2866 (TARGET_NEON && TARGET_FPU_ARMV8 \
2867 && flag_unsafe_math_optimizations \
2868 && ARM_CHECK_BUILTIN_MODE_1 (C))
2869
2870#undef ARM_CHECK_BUILTIN_MODE_1
2871#define ARM_CHECK_BUILTIN_MODE_1(C) \
2872 (out_mode == SFmode && out_n == C \
2873 && in_mode == SFmode && in_n == C)
2874
2875#undef ARM_FIND_VRINT_VARIANT
2876#define ARM_FIND_VRINT_VARIANT(N) \
2877 (ARM_CHECK_BUILTIN_MODE (2) \
2878 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \
2879 : (ARM_CHECK_BUILTIN_MODE (4) \
2880 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \
2881 : NULL_TREE))
2882
b6c464fe 2883 switch (fn)
d6504d76 2884 {
b6c464fe 2885 CASE_CFN_FLOOR:
2886 return ARM_FIND_VRINT_VARIANT (vrintm);
2887 CASE_CFN_CEIL:
2888 return ARM_FIND_VRINT_VARIANT (vrintp);
2889 CASE_CFN_TRUNC:
2890 return ARM_FIND_VRINT_VARIANT (vrintz);
2891 CASE_CFN_ROUND:
2892 return ARM_FIND_VRINT_VARIANT (vrinta);
d6504d76 2893#undef ARM_CHECK_BUILTIN_MODE_1
2894#define ARM_CHECK_BUILTIN_MODE_1(C) \
2895 (out_mode == SImode && out_n == C \
2896 && in_mode == SFmode && in_n == C)
2897
2898#define ARM_FIND_VCVT_VARIANT(N) \
2899 (ARM_CHECK_BUILTIN_MODE (2) \
2900 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sfv2si, false) \
2901 : (ARM_CHECK_BUILTIN_MODE (4) \
2902 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sfv4si, false) \
2903 : NULL_TREE))
2904
2905#define ARM_FIND_VCVTU_VARIANT(N) \
2906 (ARM_CHECK_BUILTIN_MODE (2) \
2907 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv2sfv2si, false) \
2908 : (ARM_CHECK_BUILTIN_MODE (4) \
2909 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \
2910 : NULL_TREE))
b6c464fe 2911 CASE_CFN_LROUND:
2912 return (out_unsigned_p
2913 ? ARM_FIND_VCVTU_VARIANT (vcvta)
2914 : ARM_FIND_VCVT_VARIANT (vcvta));
2915 CASE_CFN_LCEIL:
2916 return (out_unsigned_p
2917 ? ARM_FIND_VCVTU_VARIANT (vcvtp)
2918 : ARM_FIND_VCVT_VARIANT (vcvtp));
2919 CASE_CFN_LFLOOR:
2920 return (out_unsigned_p
2921 ? ARM_FIND_VCVTU_VARIANT (vcvtm)
2922 : ARM_FIND_VCVT_VARIANT (vcvtm));
d6504d76 2923#undef ARM_CHECK_BUILTIN_MODE
2924#define ARM_CHECK_BUILTIN_MODE(C, N) \
2925 (out_mode == N##mode && out_n == C \
2926 && in_mode == N##mode && in_n == C)
b6c464fe 2927 case CFN_BUILT_IN_BSWAP16:
2928 if (ARM_CHECK_BUILTIN_MODE (4, HI))
2929 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi, false);
2930 else if (ARM_CHECK_BUILTIN_MODE (8, HI))
2931 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi, false);
2932 else
2933 return NULL_TREE;
2934 case CFN_BUILT_IN_BSWAP32:
2935 if (ARM_CHECK_BUILTIN_MODE (2, SI))
2936 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si, false);
2937 else if (ARM_CHECK_BUILTIN_MODE (4, SI))
2938 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si, false);
2939 else
2940 return NULL_TREE;
2941 case CFN_BUILT_IN_BSWAP64:
2942 if (ARM_CHECK_BUILTIN_MODE (2, DI))
2943 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di, false);
2944 else
2945 return NULL_TREE;
2946 CASE_CFN_COPYSIGN:
2947 if (ARM_CHECK_BUILTIN_MODE (2, SF))
2948 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf, false);
2949 else if (ARM_CHECK_BUILTIN_MODE (4, SF))
2950 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf, false);
2951 else
2952 return NULL_TREE;
2953
2954 default:
2955 return NULL_TREE;
d6504d76 2956 }
2957 return NULL_TREE;
2958}
2959#undef ARM_FIND_VCVT_VARIANT
2960#undef ARM_FIND_VCVTU_VARIANT
2961#undef ARM_CHECK_BUILTIN_MODE
2962#undef ARM_FIND_VRINT_VARIANT
2963
2964void
2965arm_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
2966{
2967 const unsigned ARM_FE_INVALID = 1;
2968 const unsigned ARM_FE_DIVBYZERO = 2;
2969 const unsigned ARM_FE_OVERFLOW = 4;
2970 const unsigned ARM_FE_UNDERFLOW = 8;
2971 const unsigned ARM_FE_INEXACT = 16;
2972 const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT = (ARM_FE_INVALID
2973 | ARM_FE_DIVBYZERO
2974 | ARM_FE_OVERFLOW
2975 | ARM_FE_UNDERFLOW
2976 | ARM_FE_INEXACT);
2977 const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT = 8;
2978 tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv;
2979 tree new_fenv_var, reload_fenv, restore_fnenv;
2980 tree update_call, atomic_feraiseexcept, hold_fnclex;
2981
2982 if (!TARGET_VFP || !TARGET_HARD_FLOAT)
2983 return;
2984
2985 /* Generate the equivalent of :
2986 unsigned int fenv_var;
2987 fenv_var = __builtin_arm_get_fpscr ();
2988
2989 unsigned int masked_fenv;
2990 masked_fenv = fenv_var & mask;
2991
2992 __builtin_arm_set_fpscr (masked_fenv); */
2993
7aa5890a 2994 fenv_var = create_tmp_var_raw (unsigned_type_node);
d6504d76 2995 get_fpscr = arm_builtin_decls[ARM_BUILTIN_GET_FPSCR];
2996 set_fpscr = arm_builtin_decls[ARM_BUILTIN_SET_FPSCR];
2997 mask = build_int_cst (unsigned_type_node,
2998 ~((ARM_FE_ALL_EXCEPT << ARM_FE_EXCEPT_SHIFT)
2999 | ARM_FE_ALL_EXCEPT));
3000 ld_fenv = build2 (MODIFY_EXPR, unsigned_type_node,
3001 fenv_var, build_call_expr (get_fpscr, 0));
3002 masked_fenv = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var, mask);
3003 hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv);
3004 *hold = build2 (COMPOUND_EXPR, void_type_node,
3005 build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv),
3006 hold_fnclex);
3007
3008 /* Store the value of masked_fenv to clear the exceptions:
3009 __builtin_arm_set_fpscr (masked_fenv); */
3010
3011 *clear = build_call_expr (set_fpscr, 1, masked_fenv);
3012
3013 /* Generate the equivalent of :
3014 unsigned int new_fenv_var;
3015 new_fenv_var = __builtin_arm_get_fpscr ();
3016
3017 __builtin_arm_set_fpscr (fenv_var);
3018
3019 __atomic_feraiseexcept (new_fenv_var); */
3020
7aa5890a 3021 new_fenv_var = create_tmp_var_raw (unsigned_type_node);
d6504d76 3022 reload_fenv = build2 (MODIFY_EXPR, unsigned_type_node, new_fenv_var,
3023 build_call_expr (get_fpscr, 0));
3024 restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var);
3025 atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
3026 update_call = build_call_expr (atomic_feraiseexcept, 1,
3027 fold_convert (integer_type_node, new_fenv_var));
3028 *update = build2 (COMPOUND_EXPR, void_type_node,
3029 build2 (COMPOUND_EXPR, void_type_node,
3030 reload_fenv, restore_fnenv), update_call);
3031}
3032
3033#include "gt-arm-builtins.h"