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