1/* Description of builtins used by the ARM backend. 2 Copyright (C) 2014-2022 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#define IN_TARGET_CODE 1 21 22#include "config.h" 23#include "system.h" 24#include "coretypes.h" 25#include "target.h" 26#include "function.h" 27#include "rtl.h" 28#include "tree.h" 29#include "gimple-expr.h" 30#include "memmodel.h" 31#include "tm_p.h" 32#include "profile-count.h" 33#include "optabs.h" 34#include "emit-rtl.h" 35#include "recog.h" 36#include "diagnostic-core.h" 37#include "fold-const.h" 38#include "stor-layout.h" 39#include "explow.h" 40#include "expr.h" 41#include "langhooks.h" 42#include "case-cfn-macros.h" 43#include "sbitmap.h" 44#include "stringpool.h" 45#include "arm-builtins.h" 46#include "stringpool.h" 47#include "attribs.h" 48 49#define SIMD_MAX_BUILTIN_ARGS 7 50 51/* The qualifier_internal allows generation of a unary builtin from 52 a pattern with a third pseudo-operand such as a match_scratch. 53 T (T). */ 54static enum arm_type_qualifiers 55arm_unop_qualifiers[SIMD_MAX_BUILTIN_ARGS] 56 = { qualifier_none, qualifier_none, qualifier_internal }; 57#define UNOP_QUALIFIERS (arm_unop_qualifiers) 58 59/* unsigned T (unsigned T). */ 60static enum arm_type_qualifiers 61arm_bswap_qualifiers[SIMD_MAX_BUILTIN_ARGS] 62 = { qualifier_unsigned, qualifier_unsigned }; 63#define BSWAP_QUALIFIERS (arm_bswap_qualifiers) 64 65/* T (T, T [maybe_immediate]). */ 66static enum arm_type_qualifiers 67arm_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS] 68 = { qualifier_none, qualifier_none, qualifier_maybe_immediate }; 69#define BINOP_QUALIFIERS (arm_binop_qualifiers) 70 71/* T (T, T, T). */ 72static enum arm_type_qualifiers 73arm_ternop_qualifiers[SIMD_MAX_BUILTIN_ARGS] 74 = { qualifier_none, qualifier_none, qualifier_none, qualifier_none }; 75#define TERNOP_QUALIFIERS (arm_ternop_qualifiers) 76 77/* unsigned T (unsigned T, unsigned T, unsigned T). */ 78static enum arm_type_qualifiers 79arm_unsigned_uternop_qualifiers[SIMD_MAX_BUILTIN_ARGS] 80 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, 81 qualifier_unsigned }; 82#define UTERNOP_QUALIFIERS (arm_unsigned_uternop_qualifiers) 83 84/* T (T, unsigned T, T). */ 85static enum arm_type_qualifiers 86arm_usternop_qualifiers[SIMD_MAX_BUILTIN_ARGS] 87 = { qualifier_none, qualifier_none, qualifier_unsigned, 88 qualifier_none }; 89#define USTERNOP_QUALIFIERS (arm_usternop_qualifiers) 90 91/* T (T, immediate). */ 92static enum arm_type_qualifiers 93arm_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 94 = { qualifier_none, qualifier_none, qualifier_immediate }; 95#define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers) 96 97/* T (T, unsigned immediate). */ 98static enum arm_type_qualifiers 99arm_sat_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 100 = { qualifier_unsigned, qualifier_none, qualifier_unsigned_immediate }; 101#define SAT_BINOP_UNSIGNED_IMM_QUALIFIERS \ 102 (arm_sat_binop_imm_qualifiers) 103 104/* unsigned T (T, unsigned immediate). */ 105static enum arm_type_qualifiers 106arm_unsigned_sat_binop_unsigned_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 107 = { qualifier_unsigned, qualifier_none, qualifier_unsigned_immediate }; 108#define UNSIGNED_SAT_BINOP_UNSIGNED_IMM_QUALIFIERS \ 109 (arm_unsigned_sat_binop_unsigned_imm_qualifiers) 110 111/* T (T, lane index). */ 112static enum arm_type_qualifiers 113arm_getlane_qualifiers[SIMD_MAX_BUILTIN_ARGS] 114 = { qualifier_none, qualifier_none, qualifier_lane_index }; 115#define GETLANE_QUALIFIERS (arm_getlane_qualifiers) 116 117/* T (T, T, T, immediate). */ 118static enum arm_type_qualifiers 119arm_mac_n_qualifiers[SIMD_MAX_BUILTIN_ARGS] 120 = { qualifier_none, qualifier_none, qualifier_none, 121 qualifier_none, qualifier_immediate }; 122#define MAC_N_QUALIFIERS (arm_mac_n_qualifiers) 123 124/* T (T, T, T, lane index). */ 125static enum arm_type_qualifiers 126arm_mac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS] 127 = { qualifier_none, qualifier_none, qualifier_none, 128 qualifier_none, qualifier_lane_index }; 129#define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers) 130 131/* T (T, T, T, lane pair index). */ 132static enum arm_type_qualifiers 133arm_mac_lane_pair_qualifiers[SIMD_MAX_BUILTIN_ARGS] 134 = { qualifier_none, qualifier_none, qualifier_none, 135 qualifier_none, qualifier_lane_pair_index }; 136#define MAC_LANE_PAIR_QUALIFIERS (arm_mac_lane_pair_qualifiers) 137 138/* unsigned T (unsigned T, unsigned T, unsigend T, lane index). */ 139static enum arm_type_qualifiers 140arm_umac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS] 141 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, 142 qualifier_unsigned, qualifier_lane_index }; 143#define UMAC_LANE_QUALIFIERS (arm_umac_lane_qualifiers) 144 145/* T (T, unsigned T, T, lane index). */ 146static enum arm_type_qualifiers 147arm_usmac_lane_quadtup_qualifiers[SIMD_MAX_BUILTIN_ARGS] 148 = { qualifier_none, qualifier_none, qualifier_unsigned, 149 qualifier_none, qualifier_lane_quadtup_index }; 150#define USMAC_LANE_QUADTUP_QUALIFIERS (arm_usmac_lane_quadtup_qualifiers) 151 152/* T (T, T, unsigend T, lane index). */ 153static enum arm_type_qualifiers 154arm_sumac_lane_quadtup_qualifiers[SIMD_MAX_BUILTIN_ARGS] 155 = { qualifier_none, qualifier_none, qualifier_none, 156 qualifier_unsigned, qualifier_lane_quadtup_index }; 157#define SUMAC_LANE_QUADTUP_QUALIFIERS (arm_sumac_lane_quadtup_qualifiers) 158 159/* T (T, T, immediate). */ 160static enum arm_type_qualifiers 161arm_ternop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 162 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate }; 163#define TERNOP_IMM_QUALIFIERS (arm_ternop_imm_qualifiers) 164 165/* T (T, T, lane index). */ 166static enum arm_type_qualifiers 167arm_setlane_qualifiers[SIMD_MAX_BUILTIN_ARGS] 168 = { qualifier_none, qualifier_none, qualifier_none, qualifier_lane_index }; 169#define SETLANE_QUALIFIERS (arm_setlane_qualifiers) 170 171/* T (T, T). */ 172static enum arm_type_qualifiers 173arm_combine_qualifiers[SIMD_MAX_BUILTIN_ARGS] 174 = { qualifier_none, qualifier_none, qualifier_none }; 175#define COMBINE_QUALIFIERS (arm_combine_qualifiers) 176 177/* T ([T element type] *). */ 178static enum arm_type_qualifiers 179arm_load1_qualifiers[SIMD_MAX_BUILTIN_ARGS] 180 = { qualifier_none, qualifier_const_pointer_map_mode }; 181#define LOAD1_QUALIFIERS (arm_load1_qualifiers) 182 183/* T ([T element type] *, T, immediate). */ 184static enum arm_type_qualifiers 185arm_load1_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS] 186 = { qualifier_none, qualifier_const_pointer_map_mode, 187 qualifier_none, qualifier_struct_load_store_lane_index }; 188#define LOAD1LANE_QUALIFIERS (arm_load1_lane_qualifiers) 189 190/* unsigned T (unsigned T, unsigned T, unsigned T). */ 191static enum arm_type_qualifiers 192arm_unsigned_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS] 193 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, 194 qualifier_unsigned }; 195#define UBINOP_QUALIFIERS (arm_unsigned_binop_qualifiers) 196 197/* void (unsigned immediate, unsigned immediate, unsigned immediate, 198 unsigned immediate, unsigned immediate, unsigned immediate). */ 199static enum arm_type_qualifiers 200arm_cdp_qualifiers[SIMD_MAX_BUILTIN_ARGS] 201 = { qualifier_void, qualifier_unsigned_immediate, 202 qualifier_unsigned_immediate, 203 qualifier_unsigned_immediate, 204 qualifier_unsigned_immediate, 205 qualifier_unsigned_immediate, 206 qualifier_unsigned_immediate }; 207#define CDP_QUALIFIERS \ 208 (arm_cdp_qualifiers) 209 210/* void (unsigned immediate, unsigned immediate, const void *). */ 211static enum arm_type_qualifiers 212arm_ldc_qualifiers[SIMD_MAX_BUILTIN_ARGS] 213 = { qualifier_void, qualifier_unsigned_immediate, 214 qualifier_unsigned_immediate, qualifier_const_void_pointer }; 215#define LDC_QUALIFIERS \ 216 (arm_ldc_qualifiers) 217 218/* void (unsigned immediate, unsigned immediate, void *). */ 219static enum arm_type_qualifiers 220arm_stc_qualifiers[SIMD_MAX_BUILTIN_ARGS] 221 = { qualifier_void, qualifier_unsigned_immediate, 222 qualifier_unsigned_immediate, qualifier_void_pointer }; 223#define STC_QUALIFIERS \ 224 (arm_stc_qualifiers) 225 226/* void (unsigned immediate, unsigned immediate, T, unsigned immediate, 227 unsigned immediate, unsigned immediate). */ 228static enum arm_type_qualifiers 229arm_mcr_qualifiers[SIMD_MAX_BUILTIN_ARGS] 230 = { qualifier_void, qualifier_unsigned_immediate, 231 qualifier_unsigned_immediate, qualifier_none, 232 qualifier_unsigned_immediate, qualifier_unsigned_immediate, 233 qualifier_unsigned_immediate }; 234#define MCR_QUALIFIERS \ 235 (arm_mcr_qualifiers) 236 237/* T (unsigned immediate, unsigned immediate, unsigned immediate, 238 unsigned immediate, unsigned immediate). */ 239static enum arm_type_qualifiers 240arm_mrc_qualifiers[SIMD_MAX_BUILTIN_ARGS] 241 = { qualifier_none, qualifier_unsigned_immediate, 242 qualifier_unsigned_immediate, qualifier_unsigned_immediate, 243 qualifier_unsigned_immediate, qualifier_unsigned_immediate }; 244#define MRC_QUALIFIERS \ 245 (arm_mrc_qualifiers) 246 247/* void (unsigned immediate, unsigned immediate, T, unsigned immediate). */ 248static enum arm_type_qualifiers 249arm_mcrr_qualifiers[SIMD_MAX_BUILTIN_ARGS] 250 = { qualifier_void, qualifier_unsigned_immediate, 251 qualifier_unsigned_immediate, qualifier_none, 252 qualifier_unsigned_immediate }; 253#define MCRR_QUALIFIERS \ 254 (arm_mcrr_qualifiers) 255 256/* T (unsigned immediate, unsigned immediate, unsigned immediate). */ 257static enum arm_type_qualifiers 258arm_mrrc_qualifiers[SIMD_MAX_BUILTIN_ARGS] 259 = { qualifier_none, qualifier_unsigned_immediate, 260 qualifier_unsigned_immediate, qualifier_unsigned_immediate }; 261#define MRRC_QUALIFIERS \ 262 (arm_mrrc_qualifiers) 263 264/* T (immediate, unsigned immediate). */ 265static enum arm_type_qualifiers 266arm_cx_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 267 = { qualifier_none, qualifier_immediate, qualifier_unsigned_immediate }; 268#define CX_IMM_QUALIFIERS (arm_cx_imm_qualifiers) 269 270/* T (immediate, T, unsigned immediate). */ 271static enum arm_type_qualifiers 272arm_cx_unary_qualifiers[SIMD_MAX_BUILTIN_ARGS] 273 = { qualifier_none, qualifier_immediate, qualifier_none, 274 qualifier_unsigned_immediate }; 275#define CX_UNARY_QUALIFIERS (arm_cx_unary_qualifiers) 276 277/* T (immediate, T, T, unsigned immediate). */ 278static enum arm_type_qualifiers 279arm_cx_binary_qualifiers[SIMD_MAX_BUILTIN_ARGS] 280 = { qualifier_none, qualifier_immediate, 281 qualifier_none, qualifier_none, 282 qualifier_unsigned_immediate }; 283#define CX_BINARY_QUALIFIERS (arm_cx_binary_qualifiers) 284 285/* T (immediate, T, T, T, unsigned immediate). */ 286static enum arm_type_qualifiers 287arm_cx_ternary_qualifiers[SIMD_MAX_BUILTIN_ARGS] 288 = { qualifier_none, qualifier_immediate, 289 qualifier_none, qualifier_none, qualifier_none, 290 qualifier_unsigned_immediate }; 291#define CX_TERNARY_QUALIFIERS (arm_cx_ternary_qualifiers) 292 293/* T (immediate, T, unsigned immediate). */ 294static enum arm_type_qualifiers 295arm_cx_unary_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 296 = { qualifier_none, qualifier_immediate, qualifier_none, 297 qualifier_unsigned_immediate, 298 qualifier_predicate }; 299#define CX_UNARY_UNONE_QUALIFIERS (arm_cx_unary_unone_qualifiers) 300 301/* T (immediate, T, T, unsigned immediate). */ 302static enum arm_type_qualifiers 303arm_cx_binary_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 304 = { qualifier_none, qualifier_immediate, 305 qualifier_none, qualifier_none, 306 qualifier_unsigned_immediate, 307 qualifier_predicate }; 308#define CX_BINARY_UNONE_QUALIFIERS (arm_cx_binary_unone_qualifiers) 309 310/* T (immediate, T, T, T, unsigned immediate). */ 311static enum arm_type_qualifiers 312arm_cx_ternary_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 313 = { qualifier_none, qualifier_immediate, 314 qualifier_none, qualifier_none, qualifier_none, 315 qualifier_unsigned_immediate, 316 qualifier_predicate }; 317#define CX_TERNARY_UNONE_QUALIFIERS (arm_cx_ternary_unone_qualifiers) 318 319/* The first argument (return type) of a store should be void type, 320 which we represent with qualifier_void. Their first operand will be 321 a DImode pointer to the location to store to, so we must use 322 qualifier_map_mode | qualifier_pointer to build a pointer to the 323 element type of the vector. 324 325 void ([T element type] *, T). */ 326static enum arm_type_qualifiers 327arm_store1_qualifiers[SIMD_MAX_BUILTIN_ARGS] 328 = { qualifier_void, qualifier_pointer_map_mode, qualifier_none }; 329#define STORE1_QUALIFIERS (arm_store1_qualifiers) 330 331/* Qualifiers for MVE builtins. */ 332 333static enum arm_type_qualifiers 334arm_unop_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS] 335 = { qualifier_none, qualifier_none }; 336#define UNOP_NONE_NONE_QUALIFIERS \ 337 (arm_unop_none_none_qualifiers) 338 339static enum arm_type_qualifiers 340arm_unop_none_snone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 341 = { qualifier_none, qualifier_none }; 342#define UNOP_NONE_SNONE_QUALIFIERS \ 343 (arm_unop_none_snone_qualifiers) 344 345static enum arm_type_qualifiers 346arm_unop_none_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 347 = { qualifier_none, qualifier_unsigned }; 348#define UNOP_NONE_UNONE_QUALIFIERS \ 349 (arm_unop_none_unone_qualifiers) 350 351static enum arm_type_qualifiers 352arm_unop_snone_snone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 353 = { qualifier_none, qualifier_none }; 354#define UNOP_SNONE_SNONE_QUALIFIERS \ 355 (arm_unop_snone_snone_qualifiers) 356 357static enum arm_type_qualifiers 358arm_unop_snone_none_qualifiers[SIMD_MAX_BUILTIN_ARGS] 359 = { qualifier_none, qualifier_none }; 360#define UNOP_SNONE_NONE_QUALIFIERS \ 361 (arm_unop_snone_none_qualifiers) 362 363static enum arm_type_qualifiers 364arm_unop_snone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 365 = { qualifier_none, qualifier_immediate }; 366#define UNOP_SNONE_IMM_QUALIFIERS \ 367 (arm_unop_snone_imm_qualifiers) 368 369static enum arm_type_qualifiers 370arm_unop_unone_none_qualifiers[SIMD_MAX_BUILTIN_ARGS] 371 = { qualifier_unsigned, qualifier_none }; 372#define UNOP_UNONE_NONE_QUALIFIERS \ 373 (arm_unop_unone_none_qualifiers) 374 375static enum arm_type_qualifiers 376arm_unop_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 377 = { qualifier_unsigned, qualifier_unsigned }; 378#define UNOP_UNONE_UNONE_QUALIFIERS \ 379 (arm_unop_unone_unone_qualifiers) 380 381static enum arm_type_qualifiers 382arm_unop_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 383 = { qualifier_unsigned, qualifier_immediate }; 384#define UNOP_UNONE_IMM_QUALIFIERS \ 385 (arm_unop_unone_imm_qualifiers) 386 387static enum arm_type_qualifiers 388arm_binop_none_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS] 389 = { qualifier_none, qualifier_none, qualifier_none }; 390#define BINOP_NONE_NONE_NONE_QUALIFIERS \ 391 (arm_binop_none_none_none_qualifiers) 392 393static enum arm_type_qualifiers 394arm_binop_none_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 395 = { qualifier_none, qualifier_none, qualifier_immediate }; 396#define BINOP_NONE_NONE_IMM_QUALIFIERS \ 397 (arm_binop_none_none_imm_qualifiers) 398 399static enum arm_type_qualifiers 400arm_binop_none_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 401 = { qualifier_none, qualifier_unsigned, qualifier_immediate }; 402#define BINOP_NONE_UNONE_IMM_QUALIFIERS \ 403 (arm_binop_none_unone_imm_qualifiers) 404 405static enum arm_type_qualifiers 406arm_binop_none_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 407 = { qualifier_none, qualifier_unsigned, qualifier_unsigned }; 408#define BINOP_NONE_UNONE_UNONE_QUALIFIERS \ 409 (arm_binop_none_unone_unone_qualifiers) 410 411static enum arm_type_qualifiers 412arm_binop_unone_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 413 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate }; 414#define BINOP_UNONE_UNONE_IMM_QUALIFIERS \ 415 (arm_binop_unone_unone_imm_qualifiers) 416 417static enum arm_type_qualifiers 418arm_binop_unone_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 419 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned }; 420#define BINOP_UNONE_UNONE_UNONE_QUALIFIERS \ 421 (arm_binop_unone_unone_unone_qualifiers) 422 423static enum arm_type_qualifiers 424arm_binop_pred_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 425 = { qualifier_predicate, qualifier_unsigned, qualifier_unsigned }; 426#define BINOP_PRED_UNONE_UNONE_QUALIFIERS \ 427 (arm_binop_pred_unone_unone_qualifiers) 428 429static enum arm_type_qualifiers 430arm_binop_unone_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 431 = { qualifier_unsigned, qualifier_none, qualifier_immediate }; 432#define BINOP_UNONE_NONE_IMM_QUALIFIERS \ 433 (arm_binop_unone_none_imm_qualifiers) 434 435static enum arm_type_qualifiers 436arm_binop_pred_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS] 437 = { qualifier_predicate, qualifier_none, qualifier_none }; 438#define BINOP_PRED_NONE_NONE_QUALIFIERS \ 439 (arm_binop_pred_none_none_qualifiers) 440 441static enum arm_type_qualifiers 442arm_binop_unone_unone_none_qualifiers[SIMD_MAX_BUILTIN_ARGS] 443 = { qualifier_unsigned, qualifier_unsigned, qualifier_none }; 444#define BINOP_UNONE_UNONE_NONE_QUALIFIERS \ 445 (arm_binop_unone_unone_none_qualifiers) 446 447static enum arm_type_qualifiers 448arm_ternop_unone_unone_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 449 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, 450 qualifier_immediate }; 451#define TERNOP_UNONE_UNONE_UNONE_IMM_QUALIFIERS \ 452 (arm_ternop_unone_unone_unone_imm_qualifiers) 453 454static enum arm_type_qualifiers 455arm_ternop_unone_unone_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS] 456 = { qualifier_unsigned, qualifier_unsigned, qualifier_none, qualifier_none }; 457#define TERNOP_UNONE_UNONE_NONE_NONE_QUALIFIERS \ 458 (arm_ternop_unone_unone_none_none_qualifiers) 459 460static enum arm_type_qualifiers 461arm_ternop_unone_none_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 462 = { qualifier_unsigned, qualifier_none, qualifier_unsigned, 463 qualifier_immediate }; 464#define TERNOP_UNONE_NONE_UNONE_IMM_QUALIFIERS \ 465 (arm_ternop_unone_none_unone_imm_qualifiers) 466 467static enum arm_type_qualifiers 468arm_ternop_none_none_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 469 = { qualifier_none, qualifier_none, qualifier_unsigned, qualifier_immediate }; 470#define TERNOP_NONE_NONE_UNONE_IMM_QUALIFIERS \ 471 (arm_ternop_none_none_unone_imm_qualifiers) 472 473static enum arm_type_qualifiers 474arm_ternop_unone_unone_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 475 = { qualifier_unsigned, qualifier_unsigned, qualifier_none, 476 qualifier_immediate }; 477#define TERNOP_UNONE_UNONE_NONE_IMM_QUALIFIERS \ 478 (arm_ternop_unone_unone_none_imm_qualifiers) 479 480static enum arm_type_qualifiers 481arm_ternop_unone_unone_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 482 = { qualifier_unsigned, qualifier_unsigned, qualifier_none, 483 qualifier_predicate }; 484#define TERNOP_UNONE_UNONE_NONE_PRED_QUALIFIERS \ 485 (arm_ternop_unone_unone_none_pred_qualifiers) 486 487static enum arm_type_qualifiers 488arm_ternop_unone_unone_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 489 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate, 490 qualifier_predicate }; 491#define TERNOP_UNONE_UNONE_IMM_PRED_QUALIFIERS \ 492 (arm_ternop_unone_unone_imm_pred_qualifiers) 493 494static enum arm_type_qualifiers 495arm_ternop_pred_none_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 496 = { qualifier_predicate, qualifier_none, qualifier_none, qualifier_predicate }; 497#define TERNOP_PRED_NONE_NONE_PRED_QUALIFIERS \ 498 (arm_ternop_pred_none_none_pred_qualifiers) 499 500static enum arm_type_qualifiers 501arm_ternop_none_none_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] 502 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate }; 503#define TERNOP_NONE_NONE_NONE_IMM_QUALIFIERS \ 504 (arm_ternop_none_none_none_imm_qualifiers) 505 506static enum arm_type_qualifiers 507arm_ternop_none_none_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 508 = { qualifier_none, qualifier_none, qualifier_none, qualifier_predicate }; 509#define TERNOP_NONE_NONE_NONE_PRED_QUALIFIERS \ 510 (arm_ternop_none_none_none_pred_qualifiers) 511 512static enum arm_type_qualifiers 513arm_ternop_none_none_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 514 = { qualifier_none, qualifier_none, qualifier_immediate, qualifier_predicate }; 515#define TERNOP_NONE_NONE_IMM_PRED_QUALIFIERS \ 516 (arm_ternop_none_none_imm_pred_qualifiers) 517 518static enum arm_type_qualifiers 519arm_ternop_none_none_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 520 = { qualifier_none, qualifier_none, qualifier_unsigned, qualifier_predicate }; 521#define TERNOP_NONE_NONE_UNONE_PRED_QUALIFIERS \ 522 (arm_ternop_none_none_unone_pred_qualifiers) 523 524static enum arm_type_qualifiers 525arm_ternop_unone_unone_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS] 526 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, 527 qualifier_unsigned }; 528#define TERNOP_UNONE_UNONE_UNONE_UNONE_QUALIFIERS \ 529 (arm_ternop_unone_unone_unone_unone_qualifiers) 530 531static enum arm_type_qualifiers 532arm_ternop_unone_unone_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 533 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, 534 qualifier_predicate }; 535#define TERNOP_UNONE_UNONE_UNONE_PRED_QUALIFIERS \ 536 (arm_ternop_unone_unone_unone_pred_qualifiers) 537 538static enum arm_type_qualifiers 539arm_ternop_pred_unone_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 540 = { qualifier_predicate, qualifier_unsigned, qualifier_unsigned, 541 qualifier_predicate }; 542#define TERNOP_PRED_UNONE_UNONE_PRED_QUALIFIERS \ 543 (arm_ternop_pred_unone_unone_pred_qualifiers) 544 545static enum arm_type_qualifiers 546arm_ternop_none_none_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS] 547 = { qualifier_none, qualifier_none, qualifier_none, qualifier_none }; 548#define TERNOP_NONE_NONE_NONE_NONE_QUALIFIERS \ 549 (arm_ternop_none_none_none_none_qualifiers) 550 551static enum arm_type_qualifiers 552arm_quadop_unone_unone_none_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 553 = { qualifier_unsigned, qualifier_unsigned, qualifier_none, qualifier_none, 554 qualifier_predicate }; 555#define QUADOP_UNONE_UNONE_NONE_NONE_PRED_QUALIFIERS \ 556 (arm_quadop_unone_unone_none_none_pred_qualifiers) 557 558static enum arm_type_qualifiers 559arm_quadop_none_none_none_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 560 = { qualifier_none, qualifier_none, qualifier_none, qualifier_none, 561 qualifier_predicate }; 562#define QUADOP_NONE_NONE_NONE_NONE_PRED_QUALIFIERS \ 563 (arm_quadop_none_none_none_none_pred_qualifiers) 564 565static enum arm_type_qualifiers 566arm_quadop_none_none_none_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 567 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate, 568 qualifier_predicate }; 569#define QUADOP_NONE_NONE_NONE_IMM_PRED_QUALIFIERS \ 570 (arm_quadop_none_none_none_imm_pred_qualifiers) 571 572static enum arm_type_qualifiers 573arm_quadop_unone_unone_unone_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 574 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, 575 qualifier_unsigned, qualifier_predicate }; 576#define QUADOP_UNONE_UNONE_UNONE_UNONE_PRED_QUALIFIERS \ 577 (arm_quadop_unone_unone_unone_unone_pred_qualifiers) 578 579static enum arm_type_qualifiers 580arm_quadop_unone_unone_none_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 581 = { qualifier_unsigned, qualifier_unsigned, qualifier_none, 582 qualifier_immediate, qualifier_predicate }; 583#define QUADOP_UNONE_UNONE_NONE_IMM_PRED_QUALIFIERS \ 584 (arm_quadop_unone_unone_none_imm_pred_qualifiers) 585 586static enum arm_type_qualifiers 587arm_quadop_none_none_unone_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 588 = { qualifier_none, qualifier_none, qualifier_unsigned, qualifier_immediate, 589 qualifier_predicate }; 590#define QUADOP_NONE_NONE_UNONE_IMM_PRED_QUALIFIERS \ 591 (arm_quadop_none_none_unone_imm_pred_qualifiers) 592 593static enum arm_type_qualifiers 594arm_quadop_unone_unone_unone_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 595 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, 596 qualifier_immediate, qualifier_predicate }; 597#define QUADOP_UNONE_UNONE_UNONE_IMM_PRED_QUALIFIERS \ 598 (arm_quadop_unone_unone_unone_imm_pred_qualifiers) 599 600static enum arm_type_qualifiers 601arm_quadop_unone_unone_unone_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 602 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, 603 qualifier_none, qualifier_predicate }; 604#define QUADOP_UNONE_UNONE_UNONE_NONE_PRED_QUALIFIERS \ 605 (arm_quadop_unone_unone_unone_none_pred_qualifiers) 606 607static enum arm_type_qualifiers 608arm_strs_qualifiers[SIMD_MAX_BUILTIN_ARGS] 609 = { qualifier_void, qualifier_pointer, qualifier_none }; 610#define STRS_QUALIFIERS (arm_strs_qualifiers) 611 612static enum arm_type_qualifiers 613arm_stru_qualifiers[SIMD_MAX_BUILTIN_ARGS] 614 = { qualifier_void, qualifier_pointer, qualifier_unsigned }; 615#define STRU_QUALIFIERS (arm_stru_qualifiers) 616 617static enum arm_type_qualifiers 618arm_strss_qualifiers[SIMD_MAX_BUILTIN_ARGS] 619 = { qualifier_void, qualifier_pointer, qualifier_unsigned, 620 qualifier_none}; 621#define STRSS_QUALIFIERS (arm_strss_qualifiers) 622 623static enum arm_type_qualifiers 624arm_strsu_qualifiers[SIMD_MAX_BUILTIN_ARGS] 625 = { qualifier_void, qualifier_pointer, qualifier_unsigned, 626 qualifier_unsigned}; 627#define STRSU_QUALIFIERS (arm_strsu_qualifiers) 628 629static enum arm_type_qualifiers 630arm_strsbs_qualifiers[SIMD_MAX_BUILTIN_ARGS] 631 = { qualifier_void, qualifier_unsigned, qualifier_immediate, qualifier_none}; 632#define STRSBS_QUALIFIERS (arm_strsbs_qualifiers) 633 634static enum arm_type_qualifiers 635arm_strsbu_qualifiers[SIMD_MAX_BUILTIN_ARGS] 636 = { qualifier_void, qualifier_unsigned, qualifier_immediate, 637 qualifier_unsigned}; 638#define STRSBU_QUALIFIERS (arm_strsbu_qualifiers) 639 640static enum arm_type_qualifiers 641arm_strs_p_qualifiers[SIMD_MAX_BUILTIN_ARGS] 642 = { qualifier_void, qualifier_pointer, qualifier_none, qualifier_predicate}; 643#define STRS_P_QUALIFIERS (arm_strs_p_qualifiers) 644 645static enum arm_type_qualifiers 646arm_stru_p_qualifiers[SIMD_MAX_BUILTIN_ARGS] 647 = { qualifier_void, qualifier_pointer, qualifier_unsigned, 648 qualifier_predicate}; 649#define STRU_P_QUALIFIERS (arm_stru_p_qualifiers) 650 651static enum arm_type_qualifiers 652arm_strsu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS] 653 = { qualifier_void, qualifier_pointer, qualifier_unsigned, 654 qualifier_unsigned, qualifier_predicate}; 655#define STRSU_P_QUALIFIERS (arm_strsu_p_qualifiers) 656 657static enum arm_type_qualifiers 658arm_strss_p_qualifiers[SIMD_MAX_BUILTIN_ARGS] 659 = { qualifier_void, qualifier_pointer, qualifier_unsigned, 660 qualifier_none, qualifier_predicate}; 661#define STRSS_P_QUALIFIERS (arm_strss_p_qualifiers) 662 663static enum arm_type_qualifiers 664arm_strsbs_p_qualifiers[SIMD_MAX_BUILTIN_ARGS] 665 = { qualifier_void, qualifier_unsigned, qualifier_immediate, 666 qualifier_none, qualifier_predicate}; 667#define STRSBS_P_QUALIFIERS (arm_strsbs_p_qualifiers) 668 669static enum arm_type_qualifiers 670arm_strsbu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS] 671 = { qualifier_void, qualifier_unsigned, qualifier_immediate, 672 qualifier_unsigned, qualifier_predicate}; 673#define STRSBU_P_QUALIFIERS (arm_strsbu_p_qualifiers) 674 675static enum arm_type_qualifiers 676arm_ldrgu_qualifiers[SIMD_MAX_BUILTIN_ARGS] 677 = { qualifier_unsigned, qualifier_pointer, qualifier_unsigned}; 678#define LDRGU_QUALIFIERS (arm_ldrgu_qualifiers) 679 680static enum arm_type_qualifiers 681arm_ldrgs_qualifiers[SIMD_MAX_BUILTIN_ARGS] 682 = { qualifier_none, qualifier_pointer, qualifier_unsigned}; 683#define LDRGS_QUALIFIERS (arm_ldrgs_qualifiers) 684 685static enum arm_type_qualifiers 686arm_ldrs_qualifiers[SIMD_MAX_BUILTIN_ARGS] 687 = { qualifier_none, qualifier_pointer}; 688#define LDRS_QUALIFIERS (arm_ldrs_qualifiers) 689 690static enum arm_type_qualifiers 691arm_ldru_qualifiers[SIMD_MAX_BUILTIN_ARGS] 692 = { qualifier_unsigned, qualifier_pointer}; 693#define LDRU_QUALIFIERS (arm_ldru_qualifiers) 694 695static enum arm_type_qualifiers 696arm_ldrgbs_qualifiers[SIMD_MAX_BUILTIN_ARGS] 697 = { qualifier_none, qualifier_unsigned, qualifier_immediate}; 698#define LDRGBS_QUALIFIERS (arm_ldrgbs_qualifiers) 699 700static enum arm_type_qualifiers 701arm_ldrgbu_qualifiers[SIMD_MAX_BUILTIN_ARGS] 702 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate}; 703#define LDRGBU_QUALIFIERS (arm_ldrgbu_qualifiers) 704 705static enum arm_type_qualifiers 706arm_ldrgbs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS] 707 = { qualifier_none, qualifier_unsigned, qualifier_immediate, 708 qualifier_predicate}; 709#define LDRGBS_Z_QUALIFIERS (arm_ldrgbs_z_qualifiers) 710 711static enum arm_type_qualifiers 712arm_ldrgbu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS] 713 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate, 714 qualifier_predicate}; 715#define LDRGBU_Z_QUALIFIERS (arm_ldrgbu_z_qualifiers) 716 717static enum arm_type_qualifiers 718arm_ldrgs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS] 719 = { qualifier_none, qualifier_pointer, qualifier_unsigned, 720 qualifier_predicate}; 721#define LDRGS_Z_QUALIFIERS (arm_ldrgs_z_qualifiers) 722 723static enum arm_type_qualifiers 724arm_ldrgu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS] 725 = { qualifier_unsigned, qualifier_pointer, qualifier_unsigned, 726 qualifier_predicate}; 727#define LDRGU_Z_QUALIFIERS (arm_ldrgu_z_qualifiers) 728 729static enum arm_type_qualifiers 730arm_ldrs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS] 731 = { qualifier_none, qualifier_pointer, qualifier_predicate}; 732#define LDRS_Z_QUALIFIERS (arm_ldrs_z_qualifiers) 733 734static enum arm_type_qualifiers 735arm_ldru_z_qualifiers[SIMD_MAX_BUILTIN_ARGS] 736 = { qualifier_unsigned, qualifier_pointer, qualifier_predicate}; 737#define LDRU_Z_QUALIFIERS (arm_ldru_z_qualifiers) 738 739static enum arm_type_qualifiers 740arm_quinop_unone_unone_unone_unone_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 741 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, 742 qualifier_unsigned, qualifier_immediate, qualifier_predicate }; 743#define QUINOP_UNONE_UNONE_UNONE_UNONE_IMM_PRED_QUALIFIERS \ 744 (arm_quinop_unone_unone_unone_unone_imm_pred_qualifiers) 745 746static enum arm_type_qualifiers 747arm_ldrgbwbxu_qualifiers[SIMD_MAX_BUILTIN_ARGS] 748 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate}; 749#define LDRGBWBXU_QUALIFIERS (arm_ldrgbwbxu_qualifiers) 750 751static enum arm_type_qualifiers 752arm_ldrgbwbxu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS] 753 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate, 754 qualifier_predicate}; 755#define LDRGBWBXU_Z_QUALIFIERS (arm_ldrgbwbxu_z_qualifiers) 756 757static enum arm_type_qualifiers 758arm_ldrgbwbs_qualifiers[SIMD_MAX_BUILTIN_ARGS] 759 = { qualifier_none, qualifier_unsigned, qualifier_immediate}; 760#define LDRGBWBS_QUALIFIERS (arm_ldrgbwbs_qualifiers) 761 762static enum arm_type_qualifiers 763arm_ldrgbwbu_qualifiers[SIMD_MAX_BUILTIN_ARGS] 764 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate}; 765#define LDRGBWBU_QUALIFIERS (arm_ldrgbwbu_qualifiers) 766 767static enum arm_type_qualifiers 768arm_ldrgbwbs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS] 769 = { qualifier_none, qualifier_unsigned, qualifier_immediate, 770 qualifier_predicate}; 771#define LDRGBWBS_Z_QUALIFIERS (arm_ldrgbwbs_z_qualifiers) 772 773static enum arm_type_qualifiers 774arm_ldrgbwbu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS] 775 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate, 776 qualifier_predicate}; 777#define LDRGBWBU_Z_QUALIFIERS (arm_ldrgbwbu_z_qualifiers) 778 779static enum arm_type_qualifiers 780arm_strsbwbs_qualifiers[SIMD_MAX_BUILTIN_ARGS] 781 = { qualifier_unsigned, qualifier_unsigned, qualifier_const, qualifier_none}; 782#define STRSBWBS_QUALIFIERS (arm_strsbwbs_qualifiers) 783 784static enum arm_type_qualifiers 785arm_strsbwbu_qualifiers[SIMD_MAX_BUILTIN_ARGS] 786 = { qualifier_unsigned, qualifier_unsigned, qualifier_const, qualifier_unsigned}; 787#define STRSBWBU_QUALIFIERS (arm_strsbwbu_qualifiers) 788 789static enum arm_type_qualifiers 790arm_strsbwbs_p_qualifiers[SIMD_MAX_BUILTIN_ARGS] 791 = { qualifier_unsigned, qualifier_unsigned, qualifier_const, 792 qualifier_none, qualifier_predicate}; 793#define STRSBWBS_P_QUALIFIERS (arm_strsbwbs_p_qualifiers) 794 795static enum arm_type_qualifiers 796arm_strsbwbu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS] 797 = { qualifier_unsigned, qualifier_unsigned, qualifier_const, 798 qualifier_unsigned, qualifier_predicate}; 799#define STRSBWBU_P_QUALIFIERS (arm_strsbwbu_p_qualifiers) 800 801static enum arm_type_qualifiers 802arm_lsll_qualifiers[SIMD_MAX_BUILTIN_ARGS] 803 = { qualifier_unsigned, qualifier_unsigned, qualifier_none}; 804#define LSLL_QUALIFIERS (arm_lsll_qualifiers) 805 806static enum arm_type_qualifiers 807arm_uqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS] 808 = { qualifier_unsigned, qualifier_unsigned, qualifier_const}; 809#define UQSHL_QUALIFIERS (arm_uqshl_qualifiers) 810 811static enum arm_type_qualifiers 812arm_asrl_qualifiers[SIMD_MAX_BUILTIN_ARGS] 813 = { qualifier_none, qualifier_none, qualifier_none}; 814#define ASRL_QUALIFIERS (arm_asrl_qualifiers) 815 816static enum arm_type_qualifiers 817arm_sqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS] 818 = { qualifier_unsigned, qualifier_unsigned, qualifier_const}; 819#define SQSHL_QUALIFIERS (arm_sqshl_qualifiers) 820 821static enum arm_type_qualifiers 822arm_binop_none_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 823 = { qualifier_none, qualifier_none, qualifier_predicate }; 824#define BINOP_NONE_NONE_PRED_QUALIFIERS \ 825 (arm_binop_none_none_pred_qualifiers) 826 827static enum arm_type_qualifiers 828arm_binop_unone_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 829 = { qualifier_unsigned, qualifier_unsigned, qualifier_predicate }; 830#define BINOP_UNONE_UNONE_PRED_QUALIFIERS \ 831 (arm_binop_unone_unone_pred_qualifiers) 832 833/* End of Qualifier for MVE builtins. */ 834 835 /* void ([T element type] *, T, immediate). */ 836static enum arm_type_qualifiers 837arm_storestruct_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS] 838 = { qualifier_void, qualifier_pointer_map_mode, 839 qualifier_none, qualifier_struct_load_store_lane_index }; 840#define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers) 841 842 /* int (void). */ 843static enum arm_type_qualifiers 844arm_sat_occurred_qualifiers[SIMD_MAX_BUILTIN_ARGS] 845 = { qualifier_none, qualifier_void }; 846#define SAT_OCCURRED_QUALIFIERS (arm_sat_occurred_qualifiers) 847 848 /* void (int). */ 849static enum arm_type_qualifiers 850arm_set_sat_qualifiers[SIMD_MAX_BUILTIN_ARGS] 851 = { qualifier_void, qualifier_none }; 852#define SET_SAT_QUALIFIERS (arm_set_sat_qualifiers) 853 854#define v8qi_UP E_V8QImode 855#define v4hi_UP E_V4HImode 856#define v4hf_UP E_V4HFmode 857#define v4bf_UP E_V4BFmode 858#define v2si_UP E_V2SImode 859#define v2sf_UP E_V2SFmode 860#define v2bf_UP E_V2BFmode 861#define di_UP E_DImode 862#define v16qi_UP E_V16QImode 863#define v8hi_UP E_V8HImode 864#define v8hf_UP E_V8HFmode 865#define v8bf_UP E_V8BFmode 866#define v4si_UP E_V4SImode 867#define v4sf_UP E_V4SFmode 868#define v2di_UP E_V2DImode 869#define ti_UP E_TImode 870#define ei_UP E_EImode 871#define oi_UP E_OImode 872#define hf_UP E_HFmode 873#define bf_UP E_BFmode 874#define si_UP E_SImode 875#define hi_UP E_HImode 876#define void_UP E_VOIDmode 877#define sf_UP E_SFmode 878#define UP(X) X##_UP 879 880typedef struct { 881 const char *name; 882 machine_mode mode; 883 const enum insn_code code; 884 unsigned int fcode; 885 enum arm_type_qualifiers *qualifiers; 886} arm_builtin_datum; 887 888#define CF(N,X) CODE_FOR_neon_##N##X 889 890#define VAR1(T, N, A) \ 891 {#N #A, UP (A), CF (N, A), 0, T##_QUALIFIERS}, 892#define VAR2(T, N, A, B) \ 893 VAR1 (T, N, A) \ 894 VAR1 (T, N, B) 895#define VAR3(T, N, A, B, C) \ 896 VAR2 (T, N, A, B) \ 897 VAR1 (T, N, C) 898#define VAR4(T, N, A, B, C, D) \ 899 VAR3 (T, N, A, B, C) \ 900 VAR1 (T, N, D) 901#define VAR5(T, N, A, B, C, D, E) \ 902 VAR4 (T, N, A, B, C, D) \ 903 VAR1 (T, N, E) 904#define VAR6(T, N, A, B, C, D, E, F) \ 905 VAR5 (T, N, A, B, C, D, E) \ 906 VAR1 (T, N, F) 907#define VAR7(T, N, A, B, C, D, E, F, G) \ 908 VAR6 (T, N, A, B, C, D, E, F) \ 909 VAR1 (T, N, G) 910#define VAR8(T, N, A, B, C, D, E, F, G, H) \ 911 VAR7 (T, N, A, B, C, D, E, F, G) \ 912 VAR1 (T, N, H) 913#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \ 914 VAR8 (T, N, A, B, C, D, E, F, G, H) \ 915 VAR1 (T, N, I) 916#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \ 917 VAR9 (T, N, A, B, C, D, E, F, G, H, I) \ 918 VAR1 (T, N, J) 919#define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \ 920 VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \ 921 VAR1 (T, N, K) 922#define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \ 923 VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \ 924 VAR1 (T, N, L) 925#define VAR13(T, N, A, B, C, D, E, F, G, H, I, J, K, L, M) \ 926 VAR12 (T, N, A, B, C, D, E, F, G, H, I, J, K, L) \ 927 VAR1 (T, N, M) 928#define VAR14(T, N, A, B, C, D, E, F, G, H, I, J, K, L, M, O) \ 929 VAR13 (T, N, A, B, C, D, E, F, G, H, I, J, K, L, M) \ 930 VAR1 (T, N, O) 931 932/* The builtin data can be found in arm_neon_builtins.def, arm_vfp_builtins.def 933 and arm_acle_builtins.def. The entries in arm_neon_builtins.def require 934 TARGET_NEON to be true. The feature tests are checked when the builtins are 935 expanded. 936 937 The mode entries in the following table correspond to the "key" type of the 938 instruction variant, i.e. equivalent to that which would be specified after 939 the assembler mnemonic for neon instructions, which usually refers to the 940 last vector operand. The modes listed per instruction should be the same as 941 those defined for that instruction's pattern, for instance in neon.md. */ 942 943static arm_builtin_datum vfp_builtin_data[] = 944{ 945#include "arm_vfp_builtins.def" 946}; 947 948static arm_builtin_datum neon_builtin_data[] = 949{ 950#include "arm_neon_builtins.def" 951}; 952 953#undef CF 954#define CF(N,X) CODE_FOR_mve_##N##X 955static arm_builtin_datum mve_builtin_data[] = 956{ 957#include "arm_mve_builtins.def" 958}; 959 960#undef CF 961#undef VAR1 962#define VAR1(T, N, A) \ 963 {#N, UP (A), CODE_FOR_arm_##N, 0, T##_QUALIFIERS}, 964 965static arm_builtin_datum acle_builtin_data[] = 966{ 967#include "arm_acle_builtins.def" 968}; 969 970#undef VAR1 971/* IMM_MAX sets the maximum valid value of the CDE immediate operand. 972 ECF_FLAG sets the flag used for set_call_expr_flags. */ 973#define VAR1(T, N, A, IMM_MAX, ECF_FLAG) \ 974 {{#N #A, UP (A), CODE_FOR_arm_##N##A, 0, T##_QUALIFIERS}, IMM_MAX, ECF_FLAG}, 975 976typedef struct { 977 arm_builtin_datum base; 978 unsigned int imm_max; 979 int ecf_flag; 980} arm_builtin_cde_datum; 981 982static arm_builtin_cde_datum cde_builtin_data[] = 983{ 984#include "arm_cde_builtins.def" 985}; 986 987#undef VAR1 988#define VAR1(T, N, X) \ 989 ARM_BUILTIN_NEON_##N##X, 990 991enum arm_builtins 992{ 993 ARM_BUILTIN_GETWCGR0, 994 ARM_BUILTIN_GETWCGR1, 995 ARM_BUILTIN_GETWCGR2, 996 ARM_BUILTIN_GETWCGR3, 997 998 ARM_BUILTIN_SETWCGR0, 999 ARM_BUILTIN_SETWCGR1, 1000 ARM_BUILTIN_SETWCGR2, 1001 ARM_BUILTIN_SETWCGR3, 1002 1003 ARM_BUILTIN_WZERO, 1004 1005 ARM_BUILTIN_WAVG2BR, 1006 ARM_BUILTIN_WAVG2HR, 1007 ARM_BUILTIN_WAVG2B, 1008 ARM_BUILTIN_WAVG2H, 1009 1010 ARM_BUILTIN_WACCB, 1011 ARM_BUILTIN_WACCH, 1012 ARM_BUILTIN_WACCW, 1013 1014 ARM_BUILTIN_WMACS, 1015 ARM_BUILTIN_WMACSZ, 1016 ARM_BUILTIN_WMACU, 1017 ARM_BUILTIN_WMACUZ, 1018 1019 ARM_BUILTIN_WSADB, 1020 ARM_BUILTIN_WSADBZ, 1021 ARM_BUILTIN_WSADH, 1022 ARM_BUILTIN_WSADHZ, 1023 1024 ARM_BUILTIN_WALIGNI, 1025 ARM_BUILTIN_WALIGNR0, 1026 ARM_BUILTIN_WALIGNR1, 1027 ARM_BUILTIN_WALIGNR2, 1028 ARM_BUILTIN_WALIGNR3, 1029 1030 ARM_BUILTIN_TMIA, 1031 ARM_BUILTIN_TMIAPH, 1032 ARM_BUILTIN_TMIABB, 1033 ARM_BUILTIN_TMIABT, 1034 ARM_BUILTIN_TMIATB, 1035 ARM_BUILTIN_TMIATT, 1036 1037 ARM_BUILTIN_TMOVMSKB, 1038 ARM_BUILTIN_TMOVMSKH, 1039 ARM_BUILTIN_TMOVMSKW, 1040 1041 ARM_BUILTIN_TBCSTB, 1042 ARM_BUILTIN_TBCSTH, 1043 ARM_BUILTIN_TBCSTW, 1044 1045 ARM_BUILTIN_WMADDS, 1046 ARM_BUILTIN_WMADDU, 1047 1048 ARM_BUILTIN_WPACKHSS, 1049 ARM_BUILTIN_WPACKWSS, 1050 ARM_BUILTIN_WPACKDSS, 1051 ARM_BUILTIN_WPACKHUS, 1052 ARM_BUILTIN_WPACKWUS, 1053 ARM_BUILTIN_WPACKDUS, 1054 1055 ARM_BUILTIN_WADDB, 1056 ARM_BUILTIN_WADDH, 1057 ARM_BUILTIN_WADDW, 1058 ARM_BUILTIN_WADDSSB, 1059 ARM_BUILTIN_WADDSSH, 1060 ARM_BUILTIN_WADDSSW, 1061 ARM_BUILTIN_WADDUSB, 1062 ARM_BUILTIN_WADDUSH, 1063 ARM_BUILTIN_WADDUSW, 1064 ARM_BUILTIN_WSUBB, 1065 ARM_BUILTIN_WSUBH, 1066 ARM_BUILTIN_WSUBW, 1067 ARM_BUILTIN_WSUBSSB, 1068 ARM_BUILTIN_WSUBSSH, 1069 ARM_BUILTIN_WSUBSSW, 1070 ARM_BUILTIN_WSUBUSB, 1071 ARM_BUILTIN_WSUBUSH, 1072 ARM_BUILTIN_WSUBUSW, 1073 1074 ARM_BUILTIN_WAND, 1075 ARM_BUILTIN_WANDN, 1076 ARM_BUILTIN_WOR, 1077 ARM_BUILTIN_WXOR, 1078 1079 ARM_BUILTIN_WCMPEQB, 1080 ARM_BUILTIN_WCMPEQH, 1081 ARM_BUILTIN_WCMPEQW, 1082 ARM_BUILTIN_WCMPGTUB, 1083 ARM_BUILTIN_WCMPGTUH, 1084 ARM_BUILTIN_WCMPGTUW, 1085 ARM_BUILTIN_WCMPGTSB, 1086 ARM_BUILTIN_WCMPGTSH, 1087 ARM_BUILTIN_WCMPGTSW, 1088 1089 ARM_BUILTIN_TEXTRMSB, 1090 ARM_BUILTIN_TEXTRMSH, 1091 ARM_BUILTIN_TEXTRMSW, 1092 ARM_BUILTIN_TEXTRMUB, 1093 ARM_BUILTIN_TEXTRMUH, 1094 ARM_BUILTIN_TEXTRMUW, 1095 ARM_BUILTIN_TINSRB, 1096 ARM_BUILTIN_TINSRH, 1097 ARM_BUILTIN_TINSRW, 1098 1099 ARM_BUILTIN_WMAXSW, 1100 ARM_BUILTIN_WMAXSH, 1101 ARM_BUILTIN_WMAXSB, 1102 ARM_BUILTIN_WMAXUW, 1103 ARM_BUILTIN_WMAXUH, 1104 ARM_BUILTIN_WMAXUB, 1105 ARM_BUILTIN_WMINSW, 1106 ARM_BUILTIN_WMINSH, 1107 ARM_BUILTIN_WMINSB, 1108 ARM_BUILTIN_WMINUW, 1109 ARM_BUILTIN_WMINUH, 1110 ARM_BUILTIN_WMINUB, 1111 1112 ARM_BUILTIN_WMULUM, 1113 ARM_BUILTIN_WMULSM, 1114 ARM_BUILTIN_WMULUL, 1115 1116 ARM_BUILTIN_PSADBH, 1117 ARM_BUILTIN_WSHUFH, 1118 1119 ARM_BUILTIN_WSLLH, 1120 ARM_BUILTIN_WSLLW, 1121 ARM_BUILTIN_WSLLD, 1122 ARM_BUILTIN_WSRAH, 1123 ARM_BUILTIN_WSRAW, 1124 ARM_BUILTIN_WSRAD, 1125 ARM_BUILTIN_WSRLH, 1126 ARM_BUILTIN_WSRLW, 1127 ARM_BUILTIN_WSRLD, 1128 ARM_BUILTIN_WRORH, 1129 ARM_BUILTIN_WRORW, 1130 ARM_BUILTIN_WRORD, 1131 ARM_BUILTIN_WSLLHI, 1132 ARM_BUILTIN_WSLLWI, 1133 ARM_BUILTIN_WSLLDI, 1134 ARM_BUILTIN_WSRAHI, 1135 ARM_BUILTIN_WSRAWI, 1136 ARM_BUILTIN_WSRADI, 1137 ARM_BUILTIN_WSRLHI, 1138 ARM_BUILTIN_WSRLWI, 1139 ARM_BUILTIN_WSRLDI, 1140 ARM_BUILTIN_WRORHI, 1141 ARM_BUILTIN_WRORWI, 1142 ARM_BUILTIN_WRORDI, 1143 1144 ARM_BUILTIN_WUNPCKIHB, 1145 ARM_BUILTIN_WUNPCKIHH, 1146 ARM_BUILTIN_WUNPCKIHW, 1147 ARM_BUILTIN_WUNPCKILB, 1148 ARM_BUILTIN_WUNPCKILH, 1149 ARM_BUILTIN_WUNPCKILW, 1150 1151 ARM_BUILTIN_WUNPCKEHSB, 1152 ARM_BUILTIN_WUNPCKEHSH, 1153 ARM_BUILTIN_WUNPCKEHSW, 1154 ARM_BUILTIN_WUNPCKEHUB, 1155 ARM_BUILTIN_WUNPCKEHUH, 1156 ARM_BUILTIN_WUNPCKEHUW, 1157 ARM_BUILTIN_WUNPCKELSB, 1158 ARM_BUILTIN_WUNPCKELSH, 1159 ARM_BUILTIN_WUNPCKELSW, 1160 ARM_BUILTIN_WUNPCKELUB, 1161 ARM_BUILTIN_WUNPCKELUH, 1162 ARM_BUILTIN_WUNPCKELUW, 1163 1164 ARM_BUILTIN_WABSB, 1165 ARM_BUILTIN_WABSH, 1166 ARM_BUILTIN_WABSW, 1167 1168 ARM_BUILTIN_WADDSUBHX, 1169 ARM_BUILTIN_WSUBADDHX, 1170 1171 ARM_BUILTIN_WABSDIFFB, 1172 ARM_BUILTIN_WABSDIFFH, 1173 ARM_BUILTIN_WABSDIFFW, 1174 1175 ARM_BUILTIN_WADDCH, 1176 ARM_BUILTIN_WADDCW, 1177 1178 ARM_BUILTIN_WAVG4, 1179 ARM_BUILTIN_WAVG4R, 1180 1181 ARM_BUILTIN_WMADDSX, 1182 ARM_BUILTIN_WMADDUX, 1183 1184 ARM_BUILTIN_WMADDSN, 1185 ARM_BUILTIN_WMADDUN, 1186 1187 ARM_BUILTIN_WMULWSM, 1188 ARM_BUILTIN_WMULWUM, 1189 1190 ARM_BUILTIN_WMULWSMR, 1191 ARM_BUILTIN_WMULWUMR, 1192 1193 ARM_BUILTIN_WMULWL, 1194 1195 ARM_BUILTIN_WMULSMR, 1196 ARM_BUILTIN_WMULUMR, 1197 1198 ARM_BUILTIN_WQMULM, 1199 ARM_BUILTIN_WQMULMR, 1200 1201 ARM_BUILTIN_WQMULWM, 1202 ARM_BUILTIN_WQMULWMR, 1203 1204 ARM_BUILTIN_WADDBHUSM, 1205 ARM_BUILTIN_WADDBHUSL, 1206 1207 ARM_BUILTIN_WQMIABB, 1208 ARM_BUILTIN_WQMIABT, 1209 ARM_BUILTIN_WQMIATB, 1210 ARM_BUILTIN_WQMIATT, 1211 1212 ARM_BUILTIN_WQMIABBN, 1213 ARM_BUILTIN_WQMIABTN, 1214 ARM_BUILTIN_WQMIATBN, 1215 ARM_BUILTIN_WQMIATTN, 1216 1217 ARM_BUILTIN_WMIABB, 1218 ARM_BUILTIN_WMIABT, 1219 ARM_BUILTIN_WMIATB, 1220 ARM_BUILTIN_WMIATT, 1221 1222 ARM_BUILTIN_WMIABBN, 1223 ARM_BUILTIN_WMIABTN, 1224 ARM_BUILTIN_WMIATBN, 1225 ARM_BUILTIN_WMIATTN, 1226 1227 ARM_BUILTIN_WMIAWBB, 1228 ARM_BUILTIN_WMIAWBT, 1229 ARM_BUILTIN_WMIAWTB, 1230 ARM_BUILTIN_WMIAWTT, 1231 1232 ARM_BUILTIN_WMIAWBBN, 1233 ARM_BUILTIN_WMIAWBTN, 1234 ARM_BUILTIN_WMIAWTBN, 1235 ARM_BUILTIN_WMIAWTTN, 1236 1237 ARM_BUILTIN_WMERGE, 1238 1239 ARM_BUILTIN_GET_FPSCR, 1240 ARM_BUILTIN_SET_FPSCR, 1241 ARM_BUILTIN_GET_FPSCR_NZCVQC, 1242 ARM_BUILTIN_SET_FPSCR_NZCVQC, 1243 1244 ARM_BUILTIN_CMSE_NONSECURE_CALLER, 1245 ARM_BUILTIN_SIMD_LANE_CHECK, 1246 1247#undef CRYPTO1 1248#undef CRYPTO2 1249#undef CRYPTO3 1250 1251#define CRYPTO1(L, U, M1, M2) \ 1252 ARM_BUILTIN_CRYPTO_##U, 1253#define CRYPTO2(L, U, M1, M2, M3) \ 1254 ARM_BUILTIN_CRYPTO_##U, 1255#define CRYPTO3(L, U, M1, M2, M3, M4) \ 1256 ARM_BUILTIN_CRYPTO_##U, 1257 1258 ARM_BUILTIN_CRYPTO_BASE, 1259 1260#include "crypto.def" 1261 1262#undef CRYPTO1 1263#undef CRYPTO2 1264#undef CRYPTO3 1265 1266 ARM_BUILTIN_VFP_BASE, 1267 1268#include "arm_vfp_builtins.def" 1269 1270 ARM_BUILTIN_NEON_BASE, 1271 1272#include "arm_neon_builtins.def" 1273 1274#undef VAR1 1275#define VAR1(T, N, X) \ 1276 ARM_BUILTIN_##N, 1277 1278 ARM_BUILTIN_ACLE_BASE, 1279 ARM_BUILTIN_SAT_IMM_CHECK = ARM_BUILTIN_ACLE_BASE, 1280 1281#include "arm_acle_builtins.def" 1282 1283#undef VAR1 1284#define VAR1(T, N, X, ... ) \ 1285 ARM_BUILTIN_##N##X, 1286 1287 ARM_BUILTIN_CDE_BASE, 1288 1289#include "arm_cde_builtins.def" 1290 1291 ARM_BUILTIN_MVE_BASE, 1292 1293#undef VAR1 1294#define VAR1(T, N, X) \ 1295 ARM_BUILTIN_MVE_##N##X, 1296#include "arm_mve_builtins.def" 1297 1298 ARM_BUILTIN_MAX 1299}; 1300 1301#define ARM_BUILTIN_VFP_PATTERN_START \ 1302 (ARM_BUILTIN_VFP_BASE + 1) 1303 1304#define ARM_BUILTIN_NEON_PATTERN_START \ 1305 (ARM_BUILTIN_NEON_BASE + 1) 1306 1307#define ARM_BUILTIN_MVE_PATTERN_START \ 1308 (ARM_BUILTIN_MVE_BASE + 1) 1309 1310#define ARM_BUILTIN_ACLE_PATTERN_START \ 1311 (ARM_BUILTIN_ACLE_BASE + 1) 1312 1313#define ARM_BUILTIN_CDE_PATTERN_START \ 1314 (ARM_BUILTIN_CDE_BASE + 1) 1315 1316#define ARM_BUILTIN_CDE_PATTERN_END \ 1317 (ARM_BUILTIN_CDE_BASE + ARRAY_SIZE (cde_builtin_data)) 1318 1319#undef CF 1320#undef VAR1 1321#undef VAR2 1322#undef VAR3 1323#undef VAR4 1324#undef VAR5 1325#undef VAR6 1326#undef VAR7 1327#undef VAR8 1328#undef VAR9 1329#undef VAR10 1330 1331static GTY(()) tree arm_builtin_decls[ARM_BUILTIN_MAX]; 1332 1333#define NUM_DREG_TYPES 5 1334#define NUM_QREG_TYPES 6 1335 1336/* Internal scalar builtin types. These types are used to support 1337 neon intrinsic builtins. They are _not_ user-visible types. Therefore 1338 the mangling for these types are implementation defined. */ 1339const char *arm_scalar_builtin_types[] = { 1340 "__builtin_neon_qi", 1341 "__builtin_neon_hi", 1342 "__builtin_neon_si", 1343 "__builtin_neon_sf", 1344 "__builtin_neon_di", 1345 "__builtin_neon_df", 1346 "__builtin_neon_ti", 1347 "__builtin_neon_uqi", 1348 "__builtin_neon_uhi", 1349 "__builtin_neon_usi", 1350 "__builtin_neon_udi", 1351 "__builtin_neon_ei", 1352 "__builtin_neon_oi", 1353 "__builtin_neon_ci", 1354 "__builtin_neon_xi", 1355 "__builtin_neon_bf", 1356 NULL 1357}; 1358 1359#define ENTRY(E, M, Q, S, T, G) \ 1360 {E, \ 1361 "__simd" #S "_" #T "_t", \ 1362 #G "__simd" #S "_" #T "_t", \ 1363 NULL_TREE, NULL_TREE, M##mode, qualifier_##Q}, 1364struct arm_simd_type_info arm_simd_types [] = { 1365#include "arm-simd-builtin-types.def" 1366}; 1367#undef ENTRY 1368 1369/* The user-visible __fp16 type. */ 1370tree arm_fp16_type_node = NULL_TREE; 1371 1372/* Back-end node type for brain float (bfloat) types. */ 1373tree arm_bf16_type_node = NULL_TREE; 1374tree arm_bf16_ptr_type_node = NULL_TREE; 1375 1376static tree arm_simd_intOI_type_node = NULL_TREE; 1377static tree arm_simd_intEI_type_node = NULL_TREE; 1378static tree arm_simd_intCI_type_node = NULL_TREE; 1379static tree arm_simd_intXI_type_node = NULL_TREE; 1380static tree arm_simd_polyQI_type_node = NULL_TREE; 1381static tree arm_simd_polyHI_type_node = NULL_TREE; 1382static tree arm_simd_polyDI_type_node = NULL_TREE; 1383static tree arm_simd_polyTI_type_node = NULL_TREE; 1384 1385static const char * 1386arm_mangle_builtin_scalar_type (const_tree type) 1387{ 1388 int i = 0; 1389 1390 while (arm_scalar_builtin_types[i] != NULL) 1391 { 1392 const char *name = arm_scalar_builtin_types[i]; 1393 1394 if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 1395 && DECL_NAME (TYPE_NAME (type)) 1396 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), name)) 1397 return arm_scalar_builtin_types[i]; 1398 i++; 1399 } 1400 return NULL; 1401} 1402 1403static const char * 1404arm_mangle_builtin_vector_type (const_tree type) 1405{ 1406 tree attrs = TYPE_ATTRIBUTES (type); 1407 if (tree attr = lookup_attribute ("Advanced SIMD type", attrs)) 1408 { 1409 tree mangled_name = TREE_VALUE (TREE_VALUE (attr)); 1410 return IDENTIFIER_POINTER (mangled_name); 1411 } 1412 1413 return NULL; 1414} 1415 1416const char * 1417arm_mangle_builtin_type (const_tree type) 1418{ 1419 const char *mangle; 1420 /* Walk through all the Arm builtins types tables to filter out the 1421 incoming type. */ 1422 if ((mangle = arm_mangle_builtin_vector_type (type)) 1423 || (mangle = arm_mangle_builtin_scalar_type (type))) 1424 return mangle; 1425 1426 return NULL; 1427} 1428 1429static tree 1430arm_simd_builtin_std_type (machine_mode mode, 1431 enum arm_type_qualifiers q) 1432{ 1433#define QUAL_TYPE(M) \ 1434 ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node); 1435 switch (mode) 1436 { 1437 case E_QImode: 1438 return QUAL_TYPE (QI); 1439 case E_HImode: 1440 return QUAL_TYPE (HI); 1441 case E_SImode: 1442 return QUAL_TYPE (SI); 1443 case E_DImode: 1444 return QUAL_TYPE (DI); 1445 case E_TImode: 1446 return QUAL_TYPE (TI); 1447 case E_OImode: 1448 return arm_simd_intOI_type_node; 1449 case E_EImode: 1450 return arm_simd_intEI_type_node; 1451 case E_CImode: 1452 return arm_simd_intCI_type_node; 1453 case E_XImode: 1454 return arm_simd_intXI_type_node; 1455 case E_HFmode: 1456 return arm_fp16_type_node; 1457 case E_SFmode: 1458 return float_type_node; 1459 case E_DFmode: 1460 return double_type_node; 1461 case E_BFmode: 1462 return arm_bf16_type_node; 1463 default: 1464 gcc_unreachable (); 1465 } 1466#undef QUAL_TYPE 1467} 1468 1469static tree 1470arm_lookup_simd_builtin_type (machine_mode mode, 1471 enum arm_type_qualifiers q) 1472{ 1473 int i; 1474 int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]); 1475 1476 /* Non-poly scalar modes map to standard types not in the table. */ 1477 if (q != qualifier_poly && !VECTOR_MODE_P (mode)) 1478 return arm_simd_builtin_std_type (mode, q); 1479 1480 for (i = 0; i < nelts; i++) 1481 if (arm_simd_types[i].mode == mode 1482 && arm_simd_types[i].q == q) 1483 return arm_simd_types[i].itype; 1484 1485 /* Note that we won't have caught the underlying type for poly64x2_t 1486 in the above table. This gets default mangling. */ 1487 1488 return NULL_TREE; 1489} 1490 1491static tree 1492arm_simd_builtin_type (machine_mode mode, bool unsigned_p, bool poly_p) 1493{ 1494 if (poly_p) 1495 return arm_lookup_simd_builtin_type (mode, qualifier_poly); 1496 else if (unsigned_p) 1497 return arm_lookup_simd_builtin_type (mode, qualifier_unsigned); 1498 else 1499 return arm_lookup_simd_builtin_type (mode, qualifier_none); 1500} 1501 1502static void 1503arm_init_simd_builtin_types (void) 1504{ 1505 int i; 1506 int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]); 1507 tree tdecl; 1508 1509 /* Poly types are a world of their own. In order to maintain legacy 1510 ABI, they get initialized using the old interface, and don't get 1511 an entry in our mangling table, consequently, they get default 1512 mangling. As a further gotcha, poly8_t and poly16_t are signed 1513 types, poly64_t and poly128_t are unsigned types. */ 1514 if (!TARGET_HAVE_MVE) 1515 { 1516 arm_simd_polyQI_type_node 1517 = build_distinct_type_copy (intQI_type_node); 1518 (*lang_hooks.types.register_builtin_type) (arm_simd_polyQI_type_node, 1519 "__builtin_neon_poly8"); 1520 arm_simd_polyHI_type_node 1521 = build_distinct_type_copy (intHI_type_node); 1522 (*lang_hooks.types.register_builtin_type) (arm_simd_polyHI_type_node, 1523 "__builtin_neon_poly16"); 1524 arm_simd_polyDI_type_node 1525 = build_distinct_type_copy (unsigned_intDI_type_node); 1526 (*lang_hooks.types.register_builtin_type) (arm_simd_polyDI_type_node, 1527 "__builtin_neon_poly64"); 1528 arm_simd_polyTI_type_node 1529 = build_distinct_type_copy (unsigned_intTI_type_node); 1530 (*lang_hooks.types.register_builtin_type) (arm_simd_polyTI_type_node, 1531 "__builtin_neon_poly128"); 1532 /* Init poly vector element types with scalar poly types. */ 1533 arm_simd_types[Poly8x8_t].eltype = arm_simd_polyQI_type_node; 1534 arm_simd_types[Poly8x16_t].eltype = arm_simd_polyQI_type_node; 1535 arm_simd_types[Poly16x4_t].eltype = arm_simd_polyHI_type_node; 1536 arm_simd_types[Poly16x8_t].eltype = arm_simd_polyHI_type_node; 1537 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default 1538 mangling. */ 1539 1540 /* Prevent front-ends from transforming poly vectors into string 1541 literals. */ 1542 TYPE_STRING_FLAG (arm_simd_polyQI_type_node) = false; 1543 TYPE_STRING_FLAG (arm_simd_polyHI_type_node) = false; 1544 } 1545 /* Init all the element types built by the front-end. */ 1546 arm_simd_types[Int8x8_t].eltype = intQI_type_node; 1547 arm_simd_types[Int8x16_t].eltype = intQI_type_node; 1548 arm_simd_types[Int16x4_t].eltype = intHI_type_node; 1549 arm_simd_types[Int16x8_t].eltype = intHI_type_node; 1550 arm_simd_types[Int32x2_t].eltype = intSI_type_node; 1551 arm_simd_types[Int32x4_t].eltype = intSI_type_node; 1552 arm_simd_types[Int64x2_t].eltype = intDI_type_node; 1553 arm_simd_types[Uint8x8_t].eltype = unsigned_intQI_type_node; 1554 arm_simd_types[Uint8x16_t].eltype = unsigned_intQI_type_node; 1555 arm_simd_types[Uint16x4_t].eltype = unsigned_intHI_type_node; 1556 arm_simd_types[Uint16x8_t].eltype = unsigned_intHI_type_node; 1557 arm_simd_types[Uint32x2_t].eltype = unsigned_intSI_type_node; 1558 arm_simd_types[Uint32x4_t].eltype = unsigned_intSI_type_node; 1559 arm_simd_types[Uint64x2_t].eltype = unsigned_intDI_type_node; 1560 1561 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default 1562 mangling. */ 1563 1564 /* Continue with standard types. */ 1565 /* The __builtin_simd{64,128}_float16 types are kept private unless 1566 we have a scalar __fp16 type. */ 1567 arm_simd_types[Float16x4_t].eltype = arm_fp16_type_node; 1568 arm_simd_types[Float16x8_t].eltype = arm_fp16_type_node; 1569 arm_simd_types[Float32x2_t].eltype = float_type_node; 1570 arm_simd_types[Float32x4_t].eltype = float_type_node; 1571 1572 /* Init Bfloat vector types with underlying __bf16 scalar type. */ 1573 arm_simd_types[Bfloat16x2_t].eltype = arm_bf16_type_node; 1574 arm_simd_types[Bfloat16x4_t].eltype = arm_bf16_type_node; 1575 arm_simd_types[Bfloat16x8_t].eltype = arm_bf16_type_node; 1576 1577 for (i = 0; i < nelts; i++) 1578 { 1579 tree eltype = arm_simd_types[i].eltype; 1580 machine_mode mode = arm_simd_types[i].mode; 1581 1582 if (eltype == NULL 1583 /* VECTOR_BOOL is not supported unless MVE is activated, 1584 this would make build_truth_vector_type_for_mode 1585 crash. */ 1586 && ((GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL) 1587 || !TARGET_HAVE_MVE)) 1588 continue; 1589 if (arm_simd_types[i].itype == NULL) 1590 { 1591 tree type; 1592 if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL) 1593 { 1594 /* Handle MVE predicates: they are internally stored as 1595 16 bits, but are used as vectors of 1, 2 or 4-bit 1596 elements. */ 1597 type = build_truth_vector_type_for_mode (GET_MODE_NUNITS (mode), 1598 mode); 1599 eltype = TREE_TYPE (type); 1600 } 1601 else 1602 type = build_vector_type (eltype, GET_MODE_NUNITS (mode)); 1603 1604 type = build_distinct_type_copy (type); 1605 SET_TYPE_STRUCTURAL_EQUALITY (type); 1606 1607 tree mangled_name = get_identifier (arm_simd_types[i].mangle); 1608 tree value = tree_cons (NULL_TREE, mangled_name, NULL_TREE); 1609 TYPE_ATTRIBUTES (type) 1610 = tree_cons (get_identifier ("Advanced SIMD type"), value, 1611 TYPE_ATTRIBUTES (type)); 1612 arm_simd_types[i].itype = type; 1613 } 1614 1615 tdecl = add_builtin_type (arm_simd_types[i].name, 1616 arm_simd_types[i].itype); 1617 TYPE_NAME (arm_simd_types[i].itype) = tdecl; 1618 SET_TYPE_STRUCTURAL_EQUALITY (arm_simd_types[i].itype); 1619 } 1620 1621#define AARCH_BUILD_SIGNED_TYPE(mode) \ 1622 make_signed_type (GET_MODE_PRECISION (mode)); 1623 arm_simd_intOI_type_node = AARCH_BUILD_SIGNED_TYPE (OImode); 1624 arm_simd_intEI_type_node = AARCH_BUILD_SIGNED_TYPE (EImode); 1625 arm_simd_intCI_type_node = AARCH_BUILD_SIGNED_TYPE (CImode); 1626 arm_simd_intXI_type_node = AARCH_BUILD_SIGNED_TYPE (XImode); 1627#undef AARCH_BUILD_SIGNED_TYPE 1628 1629 tdecl = add_builtin_type 1630 ("__builtin_neon_ei" , arm_simd_intEI_type_node); 1631 TYPE_NAME (arm_simd_intEI_type_node) = tdecl; 1632 tdecl = add_builtin_type 1633 ("__builtin_neon_oi" , arm_simd_intOI_type_node); 1634 TYPE_NAME (arm_simd_intOI_type_node) = tdecl; 1635 tdecl = add_builtin_type 1636 ("__builtin_neon_ci" , arm_simd_intCI_type_node); 1637 TYPE_NAME (arm_simd_intCI_type_node) = tdecl; 1638 tdecl = add_builtin_type 1639 ("__builtin_neon_xi" , arm_simd_intXI_type_node); 1640 TYPE_NAME (arm_simd_intXI_type_node) = tdecl; 1641} 1642 1643static void 1644arm_init_simd_builtin_scalar_types (void) 1645{ 1646 /* Define typedefs for all the standard scalar types. */ 1647 (*lang_hooks.types.register_builtin_type) (intQI_type_node, 1648 "__builtin_neon_qi"); 1649 (*lang_hooks.types.register_builtin_type) (intHI_type_node, 1650 "__builtin_neon_hi"); 1651 (*lang_hooks.types.register_builtin_type) (intSI_type_node, 1652 "__builtin_neon_si"); 1653 (*lang_hooks.types.register_builtin_type) (float_type_node, 1654 "__builtin_neon_sf"); 1655 (*lang_hooks.types.register_builtin_type) (intDI_type_node, 1656 "__builtin_neon_di"); 1657 (*lang_hooks.types.register_builtin_type) (double_type_node, 1658 "__builtin_neon_df"); 1659 (*lang_hooks.types.register_builtin_type) (intTI_type_node, 1660 "__builtin_neon_ti"); 1661 (*lang_hooks.types.register_builtin_type) (arm_bf16_type_node, 1662 "__builtin_neon_bf"); 1663 /* Unsigned integer types for various mode sizes. */ 1664 (*lang_hooks.types.register_builtin_type) (unsigned_intQI_type_node, 1665 "__builtin_neon_uqi"); 1666 (*lang_hooks.types.register_builtin_type) (unsigned_intHI_type_node, 1667 "__builtin_neon_uhi"); 1668 (*lang_hooks.types.register_builtin_type) (unsigned_intSI_type_node, 1669 "__builtin_neon_usi"); 1670 (*lang_hooks.types.register_builtin_type) (unsigned_intDI_type_node, 1671 "__builtin_neon_udi"); 1672 (*lang_hooks.types.register_builtin_type) (unsigned_intTI_type_node, 1673 "__builtin_neon_uti"); 1674} 1675 1676/* Set up a builtin. It will use information stored in the argument struct D to 1677 derive the builtin's type signature and name. It will append the name in D 1678 to the PREFIX passed and use these to create a builtin declaration that is 1679 then stored in 'arm_builtin_decls' under index FCODE. This FCODE is also 1680 written back to D for future use. */ 1681 1682static void 1683arm_init_builtin (unsigned int fcode, arm_builtin_datum *d, 1684 const char * prefix) 1685{ 1686 bool print_type_signature_p = false; 1687 char type_signature[SIMD_MAX_BUILTIN_ARGS] = { 0 }; 1688 char namebuf[60]; 1689 tree ftype = NULL; 1690 tree fndecl = NULL; 1691 1692 d->fcode = fcode; 1693 1694 /* We must track two variables here. op_num is 1695 the operand number as in the RTL pattern. This is 1696 required to access the mode (e.g. V4SF mode) of the 1697 argument, from which the base type can be derived. 1698 arg_num is an index in to the qualifiers data, which 1699 gives qualifiers to the type (e.g. const unsigned). 1700 The reason these two variables may differ by one is the 1701 void return type. While all return types take the 0th entry 1702 in the qualifiers array, there is no operand for them in the 1703 RTL pattern. */ 1704 int op_num = insn_data[d->code].n_operands - 1; 1705 int arg_num = d->qualifiers[0] & qualifier_void 1706 ? op_num + 1 1707 : op_num; 1708 tree return_type = void_type_node, args = void_list_node; 1709 tree eltype; 1710 1711 /* Build a function type directly from the insn_data for this 1712 builtin. The build_function_type () function takes care of 1713 removing duplicates for us. */ 1714 for (; op_num >= 0; arg_num--, op_num--) 1715 { 1716 machine_mode op_mode = insn_data[d->code].operand[op_num].mode; 1717 enum arm_type_qualifiers qualifiers = d->qualifiers[arg_num]; 1718 1719 if (qualifiers & qualifier_unsigned) 1720 { 1721 type_signature[arg_num] = 'u'; 1722 print_type_signature_p = true; 1723 } 1724 else if (qualifiers & qualifier_poly) 1725 { 1726 type_signature[arg_num] = 'p'; 1727 print_type_signature_p = true; 1728 } 1729 else 1730 type_signature[arg_num] = 's'; 1731 1732 /* Skip an internal operand for vget_{low, high}. */ 1733 if (qualifiers & qualifier_internal) 1734 continue; 1735 1736 /* Some builtins have different user-facing types 1737 for certain arguments, encoded in d->mode. */ 1738 if (qualifiers & qualifier_map_mode) 1739 op_mode = d->mode; 1740 1741 /* MVE Predicates use HImode as mandated by the ABI: pred16_t is 1742 unsigned short. */ 1743 if (qualifiers & qualifier_predicate) 1744 op_mode = HImode; 1745 1746 /* For pointers, we want a pointer to the basic type 1747 of the vector. */ 1748 if (qualifiers & qualifier_pointer && VECTOR_MODE_P (op_mode)) 1749 op_mode = GET_MODE_INNER (op_mode); 1750 1751 /* For void pointers we already have nodes constructed by the midend. */ 1752 if (qualifiers & qualifier_void_pointer) 1753 eltype = qualifiers & qualifier_const 1754 ? const_ptr_type_node : ptr_type_node; 1755 else 1756 { 1757 eltype 1758 = arm_simd_builtin_type (op_mode, 1759 (qualifiers & qualifier_unsigned) != 0, 1760 (qualifiers & qualifier_poly) != 0); 1761 gcc_assert (eltype != NULL); 1762 1763 /* Add qualifiers. */ 1764 if (qualifiers & qualifier_const) 1765 eltype = build_qualified_type (eltype, TYPE_QUAL_CONST); 1766 1767 if (qualifiers & qualifier_pointer) 1768 eltype = build_pointer_type (eltype); 1769 } 1770 /* If we have reached arg_num == 0, we are at a non-void 1771 return type. Otherwise, we are still processing 1772 arguments. */ 1773 if (arg_num == 0) 1774 return_type = eltype; 1775 else 1776 args = tree_cons (NULL_TREE, eltype, args); 1777 } 1778 1779 ftype = build_function_type (return_type, args); 1780 1781 gcc_assert (ftype != NULL); 1782 1783 if (print_type_signature_p 1784 && IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_ACLE_BASE - 1)) 1785 snprintf (namebuf, sizeof (namebuf), "%s_%s_%s", 1786 prefix, d->name, type_signature); 1787 else 1788 snprintf (namebuf, sizeof (namebuf), "%s_%s", 1789 prefix, d->name); 1790 1791 fndecl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD, 1792 NULL, NULL_TREE); 1793 arm_builtin_decls[fcode] = fndecl; 1794} 1795 1796/* Initialize the backend REAL_TYPE type supporting bfloat types. */ 1797static void 1798arm_init_bf16_types (void) 1799{ 1800 arm_bf16_type_node = make_node (REAL_TYPE); 1801 TYPE_PRECISION (arm_bf16_type_node) = 16; 1802 SET_TYPE_MODE (arm_bf16_type_node, BFmode); 1803 layout_type (arm_bf16_type_node); 1804 1805 lang_hooks.types.register_builtin_type (arm_bf16_type_node, "__bf16"); 1806 arm_bf16_ptr_type_node = build_pointer_type (arm_bf16_type_node); 1807} 1808 1809/* Set up ACLE builtins, even builtins for instructions that are not 1810 in the current target ISA to allow the user to compile particular modules 1811 with different target specific options that differ from the command line 1812 options. Such builtins will be rejected in arm_expand_builtin. */ 1813 1814static void 1815arm_init_acle_builtins (void) 1816{ 1817 unsigned int i, fcode = ARM_BUILTIN_ACLE_PATTERN_START; 1818 1819 tree sat_check_fpr = build_function_type_list (void_type_node, 1820 intSI_type_node, 1821 intSI_type_node, 1822 intSI_type_node, 1823 NULL); 1824 arm_builtin_decls[ARM_BUILTIN_SAT_IMM_CHECK] 1825 = add_builtin_function ("__builtin_sat_imm_check", sat_check_fpr, 1826 ARM_BUILTIN_SAT_IMM_CHECK, BUILT_IN_MD, 1827 NULL, NULL_TREE); 1828 1829 for (i = 0; i < ARRAY_SIZE (acle_builtin_data); i++, fcode++) 1830 { 1831 arm_builtin_datum *d = &acle_builtin_data[i]; 1832 arm_init_builtin (fcode, d, "__builtin_arm"); 1833 } 1834} 1835 1836static void 1837arm_init_cde_builtins (void) 1838{ 1839 unsigned int i, fcode = ARM_BUILTIN_CDE_PATTERN_START; 1840 for (i = 0; i < ARRAY_SIZE (cde_builtin_data); i++, fcode++) 1841 { 1842 /* Only define CDE floating point builtins if the target has floating 1843 point registers. NOTE: without HARD_FLOAT we don't have MVE, so we 1844 can break out of this loop directly here. */ 1845 if (!TARGET_MAYBE_HARD_FLOAT && fcode >= ARM_BUILTIN_vcx1si) 1846 break; 1847 /* Only define CDE/MVE builtins if MVE is available. */ 1848 if (!TARGET_HAVE_MVE && fcode >= ARM_BUILTIN_vcx1qv16qi) 1849 break; 1850 arm_builtin_cde_datum *cde = &cde_builtin_data[i]; 1851 arm_builtin_datum *d = &cde->base; 1852 arm_init_builtin (fcode, d, "__builtin_arm"); 1853 set_call_expr_flags (arm_builtin_decls[fcode], cde->ecf_flag); 1854 } 1855} 1856 1857/* Set up all the MVE builtins mentioned in arm_mve_builtins.def file. */ 1858static void 1859arm_init_mve_builtins (void) 1860{ 1861 volatile unsigned int i, fcode = ARM_BUILTIN_MVE_PATTERN_START; 1862 1863 arm_init_simd_builtin_scalar_types (); 1864 arm_init_simd_builtin_types (); 1865 1866 /* Add support for __builtin_{get,set}_fpscr_nzcvqc, used by MVE intrinsics 1867 that read and/or write the carry bit. */ 1868 tree get_fpscr_nzcvqc = build_function_type_list (intSI_type_node, 1869 NULL); 1870 tree set_fpscr_nzcvqc = build_function_type_list (void_type_node, 1871 intSI_type_node, 1872 NULL); 1873 arm_builtin_decls[ARM_BUILTIN_GET_FPSCR_NZCVQC] 1874 = add_builtin_function ("__builtin_arm_get_fpscr_nzcvqc", get_fpscr_nzcvqc, 1875 ARM_BUILTIN_GET_FPSCR_NZCVQC, BUILT_IN_MD, NULL, 1876 NULL_TREE); 1877 arm_builtin_decls[ARM_BUILTIN_SET_FPSCR_NZCVQC] 1878 = add_builtin_function ("__builtin_arm_set_fpscr_nzcvqc", set_fpscr_nzcvqc, 1879 ARM_BUILTIN_SET_FPSCR_NZCVQC, BUILT_IN_MD, NULL, 1880 NULL_TREE); 1881 1882 for (i = 0; i < ARRAY_SIZE (mve_builtin_data); i++, fcode++) 1883 { 1884 arm_builtin_datum *d = &mve_builtin_data[i]; 1885 arm_init_builtin (fcode, d, "__builtin_mve"); 1886 } 1887} 1888 1889/* Set up all the NEON builtins, even builtins for instructions that are not 1890 in the current target ISA to allow the user to compile particular modules 1891 with different target specific options that differ from the command line 1892 options. Such builtins will be rejected in arm_expand_builtin. */ 1893 1894static void 1895arm_init_neon_builtins (void) 1896{ 1897 unsigned int i, fcode = ARM_BUILTIN_NEON_PATTERN_START; 1898 1899 arm_init_simd_builtin_types (); 1900 1901 /* Strong-typing hasn't been implemented for all AdvSIMD builtin intrinsics. 1902 Therefore we need to preserve the old __builtin scalar types. It can be 1903 removed once all the intrinsics become strongly typed using the qualifier 1904 system. */ 1905 arm_init_simd_builtin_scalar_types (); 1906 1907 for (i = 0; i < ARRAY_SIZE (neon_builtin_data); i++, fcode++) 1908 { 1909 arm_builtin_datum *d = &neon_builtin_data[i]; 1910 arm_init_builtin (fcode, d, "__builtin_neon"); 1911 } 1912} 1913 1914/* Set up all the scalar floating point builtins. */ 1915 1916static void 1917arm_init_vfp_builtins (void) 1918{ 1919 unsigned int i, fcode = ARM_BUILTIN_VFP_PATTERN_START; 1920 1921 for (i = 0; i < ARRAY_SIZE (vfp_builtin_data); i++, fcode++) 1922 { 1923 arm_builtin_datum *d = &vfp_builtin_data[i]; 1924 arm_init_builtin (fcode, d, "__builtin_neon"); 1925 } 1926} 1927 1928static void 1929arm_init_crypto_builtins (void) 1930{ 1931 tree V16UQI_type_node 1932 = arm_simd_builtin_type (V16QImode, true, false); 1933 1934 tree V4USI_type_node 1935 = arm_simd_builtin_type (V4SImode, true, false); 1936 1937 tree v16uqi_ftype_v16uqi 1938 = build_function_type_list (V16UQI_type_node, V16UQI_type_node, 1939 NULL_TREE); 1940 1941 tree v16uqi_ftype_v16uqi_v16uqi 1942 = build_function_type_list (V16UQI_type_node, V16UQI_type_node, 1943 V16UQI_type_node, NULL_TREE); 1944 1945 tree v4usi_ftype_v4usi 1946 = build_function_type_list (V4USI_type_node, V4USI_type_node, 1947 NULL_TREE); 1948 1949 tree v4usi_ftype_v4usi_v4usi 1950 = build_function_type_list (V4USI_type_node, V4USI_type_node, 1951 V4USI_type_node, NULL_TREE); 1952 1953 tree v4usi_ftype_v4usi_v4usi_v4usi 1954 = build_function_type_list (V4USI_type_node, V4USI_type_node, 1955 V4USI_type_node, V4USI_type_node, 1956 NULL_TREE); 1957 1958 tree uti_ftype_udi_udi 1959 = build_function_type_list (unsigned_intTI_type_node, 1960 unsigned_intDI_type_node, 1961 unsigned_intDI_type_node, 1962 NULL_TREE); 1963 1964 #undef CRYPTO1 1965 #undef CRYPTO2 1966 #undef CRYPTO3 1967 #undef C 1968 #undef N 1969 #undef CF 1970 #undef FT1 1971 #undef FT2 1972 #undef FT3 1973 1974 #define C(U) \ 1975 ARM_BUILTIN_CRYPTO_##U 1976 #define N(L) \ 1977 "__builtin_arm_crypto_"#L 1978 #define FT1(R, A) \ 1979 R##_ftype_##A 1980 #define FT2(R, A1, A2) \ 1981 R##_ftype_##A1##_##A2 1982 #define FT3(R, A1, A2, A3) \ 1983 R##_ftype_##A1##_##A2##_##A3 1984 #define CRYPTO1(L, U, R, A) \ 1985 arm_builtin_decls[C (U)] \ 1986 = add_builtin_function (N (L), FT1 (R, A), \ 1987 C (U), BUILT_IN_MD, NULL, NULL_TREE); 1988 #define CRYPTO2(L, U, R, A1, A2) \ 1989 arm_builtin_decls[C (U)] \ 1990 = add_builtin_function (N (L), FT2 (R, A1, A2), \ 1991 C (U), BUILT_IN_MD, NULL, NULL_TREE); 1992 1993 #define CRYPTO3(L, U, R, A1, A2, A3) \ 1994 arm_builtin_decls[C (U)] \ 1995 = add_builtin_function (N (L), FT3 (R, A1, A2, A3), \ 1996 C (U), BUILT_IN_MD, NULL, NULL_TREE); 1997 #include "crypto.def" 1998 1999 #undef CRYPTO1 2000 #undef CRYPTO2 2001 #undef CRYPTO3 2002 #undef C 2003 #undef N 2004 #undef FT1 2005 #undef FT2 2006 #undef FT3 2007} 2008 2009#undef NUM_DREG_TYPES 2010#undef NUM_QREG_TYPES 2011 2012#define def_mbuiltin(FLAG, NAME, TYPE, CODE) \ 2013 do \ 2014 { \ 2015 if (FLAG == isa_nobit \ 2016 || bitmap_bit_p (arm_active_target.isa, FLAG)) \ 2017 { \ 2018 tree bdecl; \ 2019 bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \ 2020 BUILT_IN_MD, NULL, NULL_TREE); \ 2021 arm_builtin_decls[CODE] = bdecl; \ 2022 } \ 2023 } \ 2024 while (0) 2025 2026struct builtin_description 2027{ 2028 const enum isa_feature feature; 2029 const enum insn_code icode; 2030 const char * const name; 2031 const enum arm_builtins code; 2032 const enum rtx_code comparison; 2033 const unsigned int flag; 2034}; 2035 2036static const struct builtin_description bdesc_2arg[] = 2037{ 2038#define IWMMXT_BUILTIN(code, string, builtin) \ 2039 { isa_bit_iwmmxt, CODE_FOR_##code, \ 2040 "__builtin_arm_" string, \ 2041 ARM_BUILTIN_##builtin, UNKNOWN, 0 }, 2042 2043#define IWMMXT2_BUILTIN(code, string, builtin) \ 2044 { isa_bit_iwmmxt2, CODE_FOR_##code, \ 2045 "__builtin_arm_" string, \ 2046 ARM_BUILTIN_##builtin, UNKNOWN, 0 }, 2047 2048 IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB) 2049 IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH) 2050 IWMMXT_BUILTIN (addv2si3, "waddw", WADDW) 2051 IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB) 2052 IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH) 2053 IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW) 2054 IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB) 2055 IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH) 2056 IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW) 2057 IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB) 2058 IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH) 2059 IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW) 2060 IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB) 2061 IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH) 2062 IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW) 2063 IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB) 2064 IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH) 2065 IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW) 2066 IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL) 2067 IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsm", WMULSM) 2068 IWMMXT_BUILTIN (umulv4hi3_highpart, "wmulum", WMULUM) 2069 IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB) 2070 IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH) 2071 IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW) 2072 IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB) 2073 IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH) 2074 IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW) 2075 IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB) 2076 IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH) 2077 IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW) 2078 IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB) 2079 IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB) 2080 IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH) 2081 IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH) 2082 IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW) 2083 IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW) 2084 IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB) 2085 IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB) 2086 IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH) 2087 IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH) 2088 IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW) 2089 IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW) 2090 IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND) 2091 IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN) 2092 IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR) 2093 IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR) 2094 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B) 2095 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H) 2096 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR) 2097 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR) 2098 IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB) 2099 IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH) 2100 IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW) 2101 IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB) 2102 IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH) 2103 IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW) 2104 IWMMXT2_BUILTIN (iwmmxt_waddsubhx, "waddsubhx", WADDSUBHX) 2105 IWMMXT2_BUILTIN (iwmmxt_wsubaddhx, "wsubaddhx", WSUBADDHX) 2106 IWMMXT2_BUILTIN (iwmmxt_wabsdiffb, "wabsdiffb", WABSDIFFB) 2107 IWMMXT2_BUILTIN (iwmmxt_wabsdiffh, "wabsdiffh", WABSDIFFH) 2108 IWMMXT2_BUILTIN (iwmmxt_wabsdiffw, "wabsdiffw", WABSDIFFW) 2109 IWMMXT2_BUILTIN (iwmmxt_avg4, "wavg4", WAVG4) 2110 IWMMXT2_BUILTIN (iwmmxt_avg4r, "wavg4r", WAVG4R) 2111 IWMMXT2_BUILTIN (iwmmxt_wmulwsm, "wmulwsm", WMULWSM) 2112 IWMMXT2_BUILTIN (iwmmxt_wmulwum, "wmulwum", WMULWUM) 2113 IWMMXT2_BUILTIN (iwmmxt_wmulwsmr, "wmulwsmr", WMULWSMR) 2114 IWMMXT2_BUILTIN (iwmmxt_wmulwumr, "wmulwumr", WMULWUMR) 2115 IWMMXT2_BUILTIN (iwmmxt_wmulwl, "wmulwl", WMULWL) 2116 IWMMXT2_BUILTIN (iwmmxt_wmulsmr, "wmulsmr", WMULSMR) 2117 IWMMXT2_BUILTIN (iwmmxt_wmulumr, "wmulumr", WMULUMR) 2118 IWMMXT2_BUILTIN (iwmmxt_wqmulm, "wqmulm", WQMULM) 2119 IWMMXT2_BUILTIN (iwmmxt_wqmulmr, "wqmulmr", WQMULMR) 2120 IWMMXT2_BUILTIN (iwmmxt_wqmulwm, "wqmulwm", WQMULWM) 2121 IWMMXT2_BUILTIN (iwmmxt_wqmulwmr, "wqmulwmr", WQMULWMR) 2122 IWMMXT_BUILTIN (iwmmxt_walignr0, "walignr0", WALIGNR0) 2123 IWMMXT_BUILTIN (iwmmxt_walignr1, "walignr1", WALIGNR1) 2124 IWMMXT_BUILTIN (iwmmxt_walignr2, "walignr2", WALIGNR2) 2125 IWMMXT_BUILTIN (iwmmxt_walignr3, "walignr3", WALIGNR3) 2126 2127#define IWMMXT_BUILTIN2(code, builtin) \ 2128 { isa_bit_iwmmxt, CODE_FOR_##code, NULL, \ 2129 ARM_BUILTIN_##builtin, UNKNOWN, 0 }, 2130 2131#define IWMMXT2_BUILTIN2(code, builtin) \ 2132 { isa_bit_iwmmxt2, CODE_FOR_##code, NULL, \ 2133 ARM_BUILTIN_##builtin, UNKNOWN, 0 }, 2134 2135 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm, WADDBHUSM) 2136 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl, WADDBHUSL) 2137 IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS) 2138 IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS) 2139 IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS) 2140 IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS) 2141 IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS) 2142 IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS) 2143 IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ) 2144 IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ) 2145 2146 2147#define FP_BUILTIN(L, U) \ 2148 {isa_nobit, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \ 2149 UNKNOWN, 0}, 2150 2151 FP_BUILTIN (get_fpscr, GET_FPSCR) 2152 FP_BUILTIN (set_fpscr, SET_FPSCR) 2153#undef FP_BUILTIN 2154 2155#define CRYPTO_BUILTIN(L, U) \ 2156 {isa_nobit, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, \ 2157 ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0}, 2158#undef CRYPTO1 2159#undef CRYPTO2 2160#undef CRYPTO3 2161#define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U) 2162#define CRYPTO1(L, U, R, A) 2163#define CRYPTO3(L, U, R, A1, A2, A3) 2164#include "crypto.def" 2165#undef CRYPTO1 2166#undef CRYPTO2 2167#undef CRYPTO3 2168 2169}; 2170 2171static const struct builtin_description bdesc_1arg[] = 2172{ 2173 IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB) 2174 IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH) 2175 IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW) 2176 IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB) 2177 IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH) 2178 IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW) 2179 IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB) 2180 IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH) 2181 IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW) 2182 IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB) 2183 IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH) 2184 IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW) 2185 IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB) 2186 IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH) 2187 IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW) 2188 IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB) 2189 IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH) 2190 IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW) 2191 IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3, "wabsb", WABSB) 2192 IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3, "wabsh", WABSH) 2193 IWMMXT2_BUILTIN (iwmmxt_wabsv2si3, "wabsw", WABSW) 2194 IWMMXT_BUILTIN (tbcstv8qi, "tbcstb", TBCSTB) 2195 IWMMXT_BUILTIN (tbcstv4hi, "tbcsth", TBCSTH) 2196 IWMMXT_BUILTIN (tbcstv2si, "tbcstw", TBCSTW) 2197 2198#define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U) 2199#define CRYPTO2(L, U, R, A1, A2) 2200#define CRYPTO3(L, U, R, A1, A2, A3) 2201#include "crypto.def" 2202#undef CRYPTO1 2203#undef CRYPTO2 2204#undef CRYPTO3 2205}; 2206 2207static const struct builtin_description bdesc_3arg[] = 2208{ 2209#define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U) 2210#define CRYPTO1(L, U, R, A) 2211#define CRYPTO2(L, U, R, A1, A2) 2212#include "crypto.def" 2213#undef CRYPTO1 2214#undef CRYPTO2 2215#undef CRYPTO3 2216 }; 2217#undef CRYPTO_BUILTIN 2218 2219/* Set up all the iWMMXt builtins. This is not called if 2220 TARGET_IWMMXT is zero. */ 2221 2222static void 2223arm_init_iwmmxt_builtins (void) 2224{ 2225 const struct builtin_description * d; 2226 size_t i; 2227 2228 tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode); 2229 tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode); 2230 tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode); 2231 2232 tree v8qi_ftype_v8qi_v8qi_int 2233 = build_function_type_list (V8QI_type_node, 2234 V8QI_type_node, V8QI_type_node, 2235 integer_type_node, NULL_TREE); 2236 tree v4hi_ftype_v4hi_int 2237 = build_function_type_list (V4HI_type_node, 2238 V4HI_type_node, integer_type_node, NULL_TREE); 2239 tree v2si_ftype_v2si_int 2240 = build_function_type_list (V2SI_type_node, 2241 V2SI_type_node, integer_type_node, NULL_TREE); 2242 tree v2si_ftype_di_di 2243 = build_function_type_list (V2SI_type_node, 2244 long_long_integer_type_node, 2245 long_long_integer_type_node, 2246 NULL_TREE); 2247 tree di_ftype_di_int 2248 = build_function_type_list (long_long_integer_type_node, 2249 long_long_integer_type_node, 2250 integer_type_node, NULL_TREE); 2251 tree di_ftype_di_int_int 2252 = build_function_type_list (long_long_integer_type_node, 2253 long_long_integer_type_node, 2254 integer_type_node, 2255 integer_type_node, NULL_TREE); 2256 tree int_ftype_v8qi 2257 = build_function_type_list (integer_type_node, 2258 V8QI_type_node, NULL_TREE); 2259 tree int_ftype_v4hi 2260 = build_function_type_list (integer_type_node, 2261 V4HI_type_node, NULL_TREE); 2262 tree int_ftype_v2si 2263 = build_function_type_list (integer_type_node, 2264 V2SI_type_node, NULL_TREE); 2265 tree int_ftype_v8qi_int 2266 = build_function_type_list (integer_type_node, 2267 V8QI_type_node, integer_type_node, NULL_TREE); 2268 tree int_ftype_v4hi_int 2269 = build_function_type_list (integer_type_node, 2270 V4HI_type_node, integer_type_node, NULL_TREE); 2271 tree int_ftype_v2si_int 2272 = build_function_type_list (integer_type_node, 2273 V2SI_type_node, integer_type_node, NULL_TREE); 2274 tree v8qi_ftype_v8qi_int_int 2275 = build_function_type_list (V8QI_type_node, 2276 V8QI_type_node, integer_type_node, 2277 integer_type_node, NULL_TREE); 2278 tree v4hi_ftype_v4hi_int_int 2279 = build_function_type_list (V4HI_type_node, 2280 V4HI_type_node, integer_type_node, 2281 integer_type_node, NULL_TREE); 2282 tree v2si_ftype_v2si_int_int 2283 = build_function_type_list (V2SI_type_node, 2284 V2SI_type_node, integer_type_node, 2285 integer_type_node, NULL_TREE); 2286 /* Miscellaneous. */ 2287 tree v8qi_ftype_v4hi_v4hi 2288 = build_function_type_list (V8QI_type_node, 2289 V4HI_type_node, V4HI_type_node, NULL_TREE); 2290 tree v4hi_ftype_v2si_v2si 2291 = build_function_type_list (V4HI_type_node, 2292 V2SI_type_node, V2SI_type_node, NULL_TREE); 2293 tree v8qi_ftype_v4hi_v8qi 2294 = build_function_type_list (V8QI_type_node, 2295 V4HI_type_node, V8QI_type_node, NULL_TREE); 2296 tree v2si_ftype_v4hi_v4hi 2297 = build_function_type_list (V2SI_type_node, 2298 V4HI_type_node, V4HI_type_node, NULL_TREE); 2299 tree v2si_ftype_v8qi_v8qi 2300 = build_function_type_list (V2SI_type_node, 2301 V8QI_type_node, V8QI_type_node, NULL_TREE); 2302 tree v4hi_ftype_v4hi_di 2303 = build_function_type_list (V4HI_type_node, 2304 V4HI_type_node, long_long_integer_type_node, 2305 NULL_TREE); 2306 tree v2si_ftype_v2si_di 2307 = build_function_type_list (V2SI_type_node, 2308 V2SI_type_node, long_long_integer_type_node, 2309 NULL_TREE); 2310 tree di_ftype_void 2311 = build_function_type_list (long_long_unsigned_type_node, NULL_TREE); 2312 tree int_ftype_void 2313 = build_function_type_list (integer_type_node, NULL_TREE); 2314 tree di_ftype_v8qi 2315 = build_function_type_list (long_long_integer_type_node, 2316 V8QI_type_node, NULL_TREE); 2317 tree di_ftype_v4hi 2318 = build_function_type_list (long_long_integer_type_node, 2319 V4HI_type_node, NULL_TREE); 2320 tree di_ftype_v2si 2321 = build_function_type_list (long_long_integer_type_node, 2322 V2SI_type_node, NULL_TREE); 2323 tree v2si_ftype_v4hi 2324 = build_function_type_list (V2SI_type_node, 2325 V4HI_type_node, NULL_TREE); 2326 tree v4hi_ftype_v8qi 2327 = build_function_type_list (V4HI_type_node, 2328 V8QI_type_node, NULL_TREE); 2329 tree v8qi_ftype_v8qi 2330 = build_function_type_list (V8QI_type_node, 2331 V8QI_type_node, NULL_TREE); 2332 tree v4hi_ftype_v4hi 2333 = build_function_type_list (V4HI_type_node, 2334 V4HI_type_node, NULL_TREE); 2335 tree v2si_ftype_v2si 2336 = build_function_type_list (V2SI_type_node, 2337 V2SI_type_node, NULL_TREE); 2338 2339 tree di_ftype_di_v4hi_v4hi 2340 = build_function_type_list (long_long_unsigned_type_node, 2341 long_long_unsigned_type_node, 2342 V4HI_type_node, V4HI_type_node, 2343 NULL_TREE); 2344 2345 tree di_ftype_v4hi_v4hi 2346 = build_function_type_list (long_long_unsigned_type_node, 2347 V4HI_type_node,V4HI_type_node, 2348 NULL_TREE); 2349 2350 tree v2si_ftype_v2si_v4hi_v4hi 2351 = build_function_type_list (V2SI_type_node, 2352 V2SI_type_node, V4HI_type_node, 2353 V4HI_type_node, NULL_TREE); 2354 2355 tree v2si_ftype_v2si_v8qi_v8qi 2356 = build_function_type_list (V2SI_type_node, 2357 V2SI_type_node, V8QI_type_node, 2358 V8QI_type_node, NULL_TREE); 2359 2360 tree di_ftype_di_v2si_v2si 2361 = build_function_type_list (long_long_unsigned_type_node, 2362 long_long_unsigned_type_node, 2363 V2SI_type_node, V2SI_type_node, 2364 NULL_TREE); 2365 2366 tree di_ftype_di_di_int 2367 = build_function_type_list (long_long_unsigned_type_node, 2368 long_long_unsigned_type_node, 2369 long_long_unsigned_type_node, 2370 integer_type_node, NULL_TREE); 2371 2372 tree void_ftype_int 2373 = build_function_type_list (void_type_node, 2374 integer_type_node, NULL_TREE); 2375 2376 tree v8qi_ftype_char 2377 = build_function_type_list (V8QI_type_node, 2378 signed_char_type_node, NULL_TREE); 2379 2380 tree v4hi_ftype_short 2381 = build_function_type_list (V4HI_type_node, 2382 short_integer_type_node, NULL_TREE); 2383 2384 tree v2si_ftype_int 2385 = build_function_type_list (V2SI_type_node, 2386 integer_type_node, NULL_TREE); 2387 2388 /* Normal vector binops. */ 2389 tree v8qi_ftype_v8qi_v8qi 2390 = build_function_type_list (V8QI_type_node, 2391 V8QI_type_node, V8QI_type_node, NULL_TREE); 2392 tree v4hi_ftype_v4hi_v4hi 2393 = build_function_type_list (V4HI_type_node, 2394 V4HI_type_node,V4HI_type_node, NULL_TREE); 2395 tree v2si_ftype_v2si_v2si 2396 = build_function_type_list (V2SI_type_node, 2397 V2SI_type_node, V2SI_type_node, NULL_TREE); 2398 tree di_ftype_di_di 2399 = build_function_type_list (long_long_unsigned_type_node, 2400 long_long_unsigned_type_node, 2401 long_long_unsigned_type_node, 2402 NULL_TREE); 2403 2404 /* Add all builtins that are more or less simple operations on two 2405 operands. */ 2406 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) 2407 { 2408 /* Use one of the operands; the target can have a different mode for 2409 mask-generating compares. */ 2410 machine_mode mode; 2411 tree type; 2412 2413 if (d->name == 0 2414 || !(d->feature == isa_bit_iwmmxt 2415 || d->feature == isa_bit_iwmmxt2)) 2416 continue; 2417 2418 mode = insn_data[d->icode].operand[1].mode; 2419 2420 switch (mode) 2421 { 2422 case E_V8QImode: 2423 type = v8qi_ftype_v8qi_v8qi; 2424 break; 2425 case E_V4HImode: 2426 type = v4hi_ftype_v4hi_v4hi; 2427 break; 2428 case E_V2SImode: 2429 type = v2si_ftype_v2si_v2si; 2430 break; 2431 case E_DImode: 2432 type = di_ftype_di_di; 2433 break; 2434 2435 default: 2436 gcc_unreachable (); 2437 } 2438 2439 def_mbuiltin (d->feature, d->name, type, d->code); 2440 } 2441 2442 /* Add the remaining MMX insns with somewhat more complicated types. */ 2443#define iwmmx_mbuiltin(NAME, TYPE, CODE) \ 2444 def_mbuiltin (isa_bit_iwmmxt, "__builtin_arm_" NAME, \ 2445 (TYPE), ARM_BUILTIN_ ## CODE) 2446 2447#define iwmmx2_mbuiltin(NAME, TYPE, CODE) \ 2448 def_mbuiltin (isa_bit_iwmmxt2, "__builtin_arm_" NAME, \ 2449 (TYPE), ARM_BUILTIN_ ## CODE) 2450 2451 iwmmx_mbuiltin ("wzero", di_ftype_void, WZERO); 2452 iwmmx_mbuiltin ("setwcgr0", void_ftype_int, SETWCGR0); 2453 iwmmx_mbuiltin ("setwcgr1", void_ftype_int, SETWCGR1); 2454 iwmmx_mbuiltin ("setwcgr2", void_ftype_int, SETWCGR2); 2455 iwmmx_mbuiltin ("setwcgr3", void_ftype_int, SETWCGR3); 2456 iwmmx_mbuiltin ("getwcgr0", int_ftype_void, GETWCGR0); 2457 iwmmx_mbuiltin ("getwcgr1", int_ftype_void, GETWCGR1); 2458 iwmmx_mbuiltin ("getwcgr2", int_ftype_void, GETWCGR2); 2459 iwmmx_mbuiltin ("getwcgr3", int_ftype_void, GETWCGR3); 2460 2461 iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di, WSLLH); 2462 iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di, WSLLW); 2463 iwmmx_mbuiltin ("wslld", di_ftype_di_di, WSLLD); 2464 iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int, WSLLHI); 2465 iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int, WSLLWI); 2466 iwmmx_mbuiltin ("wslldi", di_ftype_di_int, WSLLDI); 2467 2468 iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di, WSRLH); 2469 iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di, WSRLW); 2470 iwmmx_mbuiltin ("wsrld", di_ftype_di_di, WSRLD); 2471 iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int, WSRLHI); 2472 iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int, WSRLWI); 2473 iwmmx_mbuiltin ("wsrldi", di_ftype_di_int, WSRLDI); 2474 2475 iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di, WSRAH); 2476 iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di, WSRAW); 2477 iwmmx_mbuiltin ("wsrad", di_ftype_di_di, WSRAD); 2478 iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int, WSRAHI); 2479 iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int, WSRAWI); 2480 iwmmx_mbuiltin ("wsradi", di_ftype_di_int, WSRADI); 2481 2482 iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di, WRORH); 2483 iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di, WRORW); 2484 iwmmx_mbuiltin ("wrord", di_ftype_di_di, WRORD); 2485 iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int, WRORHI); 2486 iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int, WRORWI); 2487 iwmmx_mbuiltin ("wrordi", di_ftype_di_int, WRORDI); 2488 2489 iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int, WSHUFH); 2490 2491 iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi, WSADB); 2492 iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi, WSADH); 2493 iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi, WMADDS); 2494 iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi, WMADDSX); 2495 iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi, WMADDSN); 2496 iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi, WMADDU); 2497 iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi, WMADDUX); 2498 iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi, WMADDUN); 2499 iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi, WSADBZ); 2500 iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi, WSADHZ); 2501 2502 iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int, TEXTRMSB); 2503 iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int, TEXTRMSH); 2504 iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int, TEXTRMSW); 2505 iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int, TEXTRMUB); 2506 iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int, TEXTRMUH); 2507 iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int, TEXTRMUW); 2508 iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int, TINSRB); 2509 iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int, TINSRH); 2510 iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int, TINSRW); 2511 2512 iwmmx_mbuiltin ("waccb", di_ftype_v8qi, WACCB); 2513 iwmmx_mbuiltin ("wacch", di_ftype_v4hi, WACCH); 2514 iwmmx_mbuiltin ("waccw", di_ftype_v2si, WACCW); 2515 2516 iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi, TMOVMSKB); 2517 iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi, TMOVMSKH); 2518 iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si, TMOVMSKW); 2519 2520 iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi, WADDBHUSM); 2521 iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi, WADDBHUSL); 2522 2523 iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi, WPACKHSS); 2524 iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi, WPACKHUS); 2525 iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si, WPACKWUS); 2526 iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si, WPACKWSS); 2527 iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di, WPACKDUS); 2528 iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di, WPACKDSS); 2529 2530 iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi, WUNPCKEHUB); 2531 iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi, WUNPCKEHUH); 2532 iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si, WUNPCKEHUW); 2533 iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi, WUNPCKEHSB); 2534 iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi, WUNPCKEHSH); 2535 iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si, WUNPCKEHSW); 2536 iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi, WUNPCKELUB); 2537 iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi, WUNPCKELUH); 2538 iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si, WUNPCKELUW); 2539 iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi, WUNPCKELSB); 2540 iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi, WUNPCKELSH); 2541 iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si, WUNPCKELSW); 2542 2543 iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi, WMACS); 2544 iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi, WMACSZ); 2545 iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi, WMACU); 2546 iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi, WMACUZ); 2547 2548 iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int, WALIGNI); 2549 iwmmx_mbuiltin ("tmia", di_ftype_di_int_int, TMIA); 2550 iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int, TMIAPH); 2551 iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int, TMIABB); 2552 iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int, TMIABT); 2553 iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int, TMIATB); 2554 iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int, TMIATT); 2555 2556 iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi, WABSB); 2557 iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi, WABSH); 2558 iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si, WABSW); 2559 2560 iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi, WQMIABB); 2561 iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi, WQMIABT); 2562 iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi, WQMIATB); 2563 iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi, WQMIATT); 2564 2565 iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi, WQMIABBN); 2566 iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi, WQMIABTN); 2567 iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi, WQMIATBN); 2568 iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi, WQMIATTN); 2569 2570 iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi, WMIABB); 2571 iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi, WMIABT); 2572 iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi, WMIATB); 2573 iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi, WMIATT); 2574 2575 iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi, WMIABBN); 2576 iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi, WMIABTN); 2577 iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi, WMIATBN); 2578 iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi, WMIATTN); 2579 2580 iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si, WMIAWBB); 2581 iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si, WMIAWBT); 2582 iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si, WMIAWTB); 2583 iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si, WMIAWTT); 2584 2585 iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si, WMIAWBBN); 2586 iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si, WMIAWBTN); 2587 iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si, WMIAWTBN); 2588 iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si, WMIAWTTN); 2589 2590 iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int, WMERGE); 2591 2592 iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char, TBCSTB); 2593 iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short, TBCSTH); 2594 iwmmx_mbuiltin ("tbcstw", v2si_ftype_int, TBCSTW); 2595 2596#undef iwmmx_mbuiltin 2597#undef iwmmx2_mbuiltin 2598} 2599 2600static void 2601arm_init_fp16_builtins (void) 2602{ 2603 arm_fp16_type_node = make_node (REAL_TYPE); 2604 TYPE_PRECISION (arm_fp16_type_node) = GET_MODE_PRECISION (HFmode); 2605 layout_type (arm_fp16_type_node); 2606 if (arm_fp16_format) 2607 (*lang_hooks.types.register_builtin_type) (arm_fp16_type_node, 2608 "__fp16"); 2609} 2610 2611void 2612arm_init_builtins (void) 2613{ 2614 if (TARGET_REALLY_IWMMXT) 2615 arm_init_iwmmxt_builtins (); 2616 2617 /* This creates the arm_simd_floatHF_type_node so must come before 2618 arm_init_neon_builtins which uses it. */ 2619 arm_init_fp16_builtins (); 2620 2621 arm_init_bf16_types (); 2622 2623 if (TARGET_MAYBE_HARD_FLOAT) 2624 { 2625 tree lane_check_fpr = build_function_type_list (void_type_node, 2626 intSI_type_node, 2627 intSI_type_node, 2628 NULL); 2629 arm_builtin_decls[ARM_BUILTIN_SIMD_LANE_CHECK] 2630 = add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr, 2631 ARM_BUILTIN_SIMD_LANE_CHECK, BUILT_IN_MD, 2632 NULL, NULL_TREE); 2633 if (TARGET_HAVE_MVE) 2634 arm_init_mve_builtins (); 2635 else 2636 arm_init_neon_builtins (); 2637 arm_init_vfp_builtins (); 2638 arm_init_crypto_builtins (); 2639 } 2640 2641 if (TARGET_CDE) 2642 arm_init_cde_builtins (); 2643 2644 arm_init_acle_builtins (); 2645 2646 if (TARGET_MAYBE_HARD_FLOAT) 2647 { 2648 tree ftype_set_fpscr 2649 = build_function_type_list (void_type_node, unsigned_type_node, NULL); 2650 tree ftype_get_fpscr 2651 = build_function_type_list (unsigned_type_node, NULL); 2652 2653 arm_builtin_decls[ARM_BUILTIN_GET_FPSCR] 2654 = add_builtin_function ("__builtin_arm_get_fpscr", ftype_get_fpscr, 2655 ARM_BUILTIN_GET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE); 2656 arm_builtin_decls[ARM_BUILTIN_SET_FPSCR] 2657 = add_builtin_function ("__builtin_arm_set_fpscr", ftype_set_fpscr, 2658 ARM_BUILTIN_SET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE); 2659 } 2660 2661 if (use_cmse) 2662 { 2663 tree ftype_cmse_nonsecure_caller 2664 = build_function_type_list (unsigned_type_node, NULL); 2665 arm_builtin_decls[ARM_BUILTIN_CMSE_NONSECURE_CALLER] 2666 = add_builtin_function ("__builtin_arm_cmse_nonsecure_caller", 2667 ftype_cmse_nonsecure_caller, 2668 ARM_BUILTIN_CMSE_NONSECURE_CALLER, BUILT_IN_MD, 2669 NULL, NULL_TREE); 2670 } 2671} 2672 2673/* Return the ARM builtin for CODE. */ 2674 2675tree 2676arm_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) 2677{ 2678 if (code >= ARM_BUILTIN_MAX) 2679 return error_mark_node; 2680 2681 return arm_builtin_decls[code]; 2682} 2683 2684/* Errors in the source file can cause expand_expr to return const0_rtx 2685 where we expect a vector. To avoid crashing, use one of the vector 2686 clear instructions. */ 2687 2688static rtx 2689safe_vector_operand (rtx x, machine_mode mode) 2690{ 2691 if (x != const0_rtx) 2692 return x; 2693 x = gen_reg_rtx (mode); 2694 2695 emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x 2696 : gen_rtx_SUBREG (DImode, x, 0))); 2697 return x; 2698} 2699 2700/* Function to expand ternary builtins. */ 2701static rtx 2702arm_expand_ternop_builtin (enum insn_code icode, 2703 tree exp, rtx target) 2704{ 2705 rtx pat; 2706 tree arg0 = CALL_EXPR_ARG (exp, 0); 2707 tree arg1 = CALL_EXPR_ARG (exp, 1); 2708 tree arg2 = CALL_EXPR_ARG (exp, 2); 2709 2710 rtx op0 = expand_normal (arg0); 2711 rtx op1 = expand_normal (arg1); 2712 rtx op2 = expand_normal (arg2); 2713 2714 machine_mode tmode = insn_data[icode].operand[0].mode; 2715 machine_mode mode0 = insn_data[icode].operand[1].mode; 2716 machine_mode mode1 = insn_data[icode].operand[2].mode; 2717 machine_mode mode2 = insn_data[icode].operand[3].mode; 2718 2719 if (VECTOR_MODE_P (mode0)) 2720 op0 = safe_vector_operand (op0, mode0); 2721 if (VECTOR_MODE_P (mode1)) 2722 op1 = safe_vector_operand (op1, mode1); 2723 if (VECTOR_MODE_P (mode2)) 2724 op2 = safe_vector_operand (op2, mode2); 2725 2726 if (! target 2727 || GET_MODE (target) != tmode 2728 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 2729 target = gen_reg_rtx (tmode); 2730 2731 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode) 2732 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode) 2733 && (GET_MODE (op2) == mode2 || GET_MODE (op2) == VOIDmode)); 2734 2735 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 2736 op0 = copy_to_mode_reg (mode0, op0); 2737 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) 2738 op1 = copy_to_mode_reg (mode1, op1); 2739 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2)) 2740 op2 = copy_to_mode_reg (mode2, op2); 2741 2742 pat = GEN_FCN (icode) (target, op0, op1, op2); 2743 if (! pat) 2744 return 0; 2745 emit_insn (pat); 2746 return target; 2747} 2748 2749/* Subroutine of arm_expand_builtin to take care of binop insns. */ 2750 2751static rtx 2752arm_expand_binop_builtin (enum insn_code icode, 2753 tree exp, rtx target) 2754{ 2755 rtx pat; 2756 tree arg0 = CALL_EXPR_ARG (exp, 0); 2757 tree arg1 = CALL_EXPR_ARG (exp, 1); 2758 rtx op0 = expand_normal (arg0); 2759 rtx op1 = expand_normal (arg1); 2760 machine_mode tmode = insn_data[icode].operand[0].mode; 2761 machine_mode mode0 = insn_data[icode].operand[1].mode; 2762 machine_mode mode1 = insn_data[icode].operand[2].mode; 2763 2764 if (VECTOR_MODE_P (mode0)) 2765 op0 = safe_vector_operand (op0, mode0); 2766 if (VECTOR_MODE_P (mode1)) 2767 op1 = safe_vector_operand (op1, mode1); 2768 2769 if (! target 2770 || GET_MODE (target) != tmode 2771 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 2772 target = gen_reg_rtx (tmode); 2773 2774 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode) 2775 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode)); 2776 2777 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 2778 op0 = copy_to_mode_reg (mode0, op0); 2779 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) 2780 op1 = copy_to_mode_reg (mode1, op1); 2781 2782 pat = GEN_FCN (icode) (target, op0, op1); 2783 if (! pat) 2784 return 0; 2785 emit_insn (pat); 2786 return target; 2787} 2788 2789/* Subroutine of arm_expand_builtin to take care of unop insns. */ 2790 2791static rtx 2792arm_expand_unop_builtin (enum insn_code icode, 2793 tree exp, rtx target, int do_load) 2794{ 2795 rtx pat; 2796 tree arg0 = CALL_EXPR_ARG (exp, 0); 2797 rtx op0 = expand_normal (arg0); 2798 machine_mode tmode = insn_data[icode].operand[0].mode; 2799 machine_mode mode0 = insn_data[icode].operand[1].mode; 2800 2801 if (! target 2802 || GET_MODE (target) != tmode 2803 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 2804 target = gen_reg_rtx (tmode); 2805 if (do_load) 2806 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); 2807 else 2808 { 2809 if (VECTOR_MODE_P (mode0)) 2810 op0 = safe_vector_operand (op0, mode0); 2811 2812 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 2813 op0 = copy_to_mode_reg (mode0, op0); 2814 } 2815 2816 pat = GEN_FCN (icode) (target, op0); 2817 2818 if (! pat) 2819 return 0; 2820 emit_insn (pat); 2821 return target; 2822} 2823 2824typedef enum { 2825 ARG_BUILTIN_COPY_TO_REG, 2826 ARG_BUILTIN_CONSTANT, 2827 ARG_BUILTIN_LANE_INDEX, 2828 ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX, 2829 ARG_BUILTIN_LANE_PAIR_INDEX, 2830 ARG_BUILTIN_LANE_QUADTUP_INDEX, 2831 ARG_BUILTIN_NEON_MEMORY, 2832 ARG_BUILTIN_MEMORY, 2833 ARG_BUILTIN_STOP 2834} builtin_arg; 2835 2836 2837/* EXP is a pointer argument to a Neon load or store intrinsic. Derive 2838 and return an expression for the accessed memory. 2839 2840 The intrinsic function operates on a block of registers that has 2841 mode REG_MODE. This block contains vectors of type TYPE_MODE. The 2842 function references the memory at EXP of type TYPE and in mode 2843 MEM_MODE; this mode may be BLKmode if no more suitable mode is 2844 available. */ 2845 2846static tree 2847neon_dereference_pointer (tree exp, tree type, machine_mode mem_mode, 2848 machine_mode reg_mode, 2849 machine_mode vector_mode) 2850{ 2851 HOST_WIDE_INT reg_size, vector_size, nvectors, nelems; 2852 tree elem_type, upper_bound, array_type; 2853 2854 /* Work out the size of the register block in bytes. */ 2855 reg_size = GET_MODE_SIZE (reg_mode); 2856 2857 /* Work out the size of each vector in bytes. */ 2858 vector_size = GET_MODE_SIZE (vector_mode); 2859 2860 /* Work out how many vectors there are. */ 2861 gcc_assert (reg_size % vector_size == 0); 2862 nvectors = reg_size / vector_size; 2863 2864 /* Work out the type of each element. */ 2865 gcc_assert (POINTER_TYPE_P (type)); 2866 elem_type = TREE_TYPE (type); 2867 2868 /* Work out how many elements are being loaded or stored. 2869 MEM_MODE == REG_MODE implies a one-to-one mapping between register 2870 and memory elements; anything else implies a lane load or store. */ 2871 if (mem_mode == reg_mode) 2872 nelems = vector_size * nvectors / int_size_in_bytes (elem_type); 2873 else 2874 nelems = nvectors; 2875 2876 /* Create a type that describes the full access. */ 2877 upper_bound = build_int_cst (size_type_node, nelems - 1); 2878 array_type = build_array_type (elem_type, build_index_type (upper_bound)); 2879 2880 /* Dereference EXP using that type. */ 2881 return fold_build2 (MEM_REF, array_type, exp, 2882 build_int_cst (build_pointer_type (array_type), 0)); 2883} 2884 2885/* EXP is a pointer argument to a vector scatter store intrinsics. 2886 2887 Consider the following example: 2888 VSTRW<v>.<dt> Qd, [Qm{, #+/-<imm>}]! 2889 When <Qm> used as the base register for the target address, 2890 this function is used to derive and return an expression for the 2891 accessed memory. 2892 2893 The intrinsic function operates on a block of registers that has mode 2894 REG_MODE. This block contains vectors of type TYPE_MODE. The function 2895 references the memory at EXP of type TYPE and in mode MEM_MODE. This 2896 mode may be BLKmode if no more suitable mode is available. */ 2897 2898static tree 2899mve_dereference_pointer (tree exp, tree type, machine_mode reg_mode, 2900 machine_mode vector_mode) 2901{ 2902 HOST_WIDE_INT reg_size, vector_size, nelems; 2903 tree elem_type, upper_bound, array_type; 2904 2905 /* Work out the size of each vector in bytes. */ 2906 vector_size = GET_MODE_SIZE (vector_mode); 2907 2908 /* Work out the size of the register block in bytes. */ 2909 reg_size = GET_MODE_SIZE (reg_mode); 2910 2911 /* Work out the type of each element. */ 2912 gcc_assert (POINTER_TYPE_P (type)); 2913 elem_type = TREE_TYPE (type); 2914 2915 nelems = reg_size / vector_size; 2916 2917 /* Create a type that describes the full access. */ 2918 upper_bound = build_int_cst (size_type_node, nelems - 1); 2919 array_type = build_array_type (elem_type, build_index_type (upper_bound)); 2920 2921 /* Dereference EXP using that type. */ 2922 return fold_build2 (MEM_REF, array_type, exp, 2923 build_int_cst (build_pointer_type (array_type), 0)); 2924} 2925 2926/* Expand a builtin. */ 2927static rtx 2928arm_expand_builtin_args (rtx target, machine_mode map_mode, int fcode, 2929 int icode, int have_retval, tree exp, 2930 builtin_arg *args) 2931{ 2932 rtx pat; 2933 tree arg[SIMD_MAX_BUILTIN_ARGS]; 2934 rtx op[SIMD_MAX_BUILTIN_ARGS]; 2935 machine_mode tmode = insn_data[icode].operand[0].mode; 2936 machine_mode mode[SIMD_MAX_BUILTIN_ARGS]; 2937 tree formals; 2938 int argc = 0; 2939 rtx_insn * insn; 2940 2941 if (have_retval 2942 && (!target 2943 || GET_MODE (target) != tmode 2944 || !(*insn_data[icode].operand[0].predicate) (target, tmode))) 2945 target = gen_reg_rtx (tmode); 2946 2947 formals = TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls[fcode])); 2948 2949 for (;;) 2950 { 2951 builtin_arg thisarg = args[argc]; 2952 2953 if (thisarg == ARG_BUILTIN_STOP) 2954 break; 2955 else 2956 { 2957 int opno = argc + have_retval; 2958 arg[argc] = CALL_EXPR_ARG (exp, argc); 2959 mode[argc] = insn_data[icode].operand[opno].mode; 2960 if (thisarg == ARG_BUILTIN_NEON_MEMORY) 2961 { 2962 machine_mode other_mode 2963 = insn_data[icode].operand[1 - opno].mode; 2964 if (TARGET_HAVE_MVE && mode[argc] != other_mode) 2965 { 2966 arg[argc] = mve_dereference_pointer (arg[argc], 2967 TREE_VALUE (formals), 2968 other_mode, map_mode); 2969 } 2970 else 2971 arg[argc] = neon_dereference_pointer (arg[argc], 2972 TREE_VALUE (formals), 2973 mode[argc], other_mode, 2974 map_mode); 2975 } 2976 2977 /* Use EXPAND_MEMORY for ARG_BUILTIN_MEMORY and 2978 ARG_BUILTIN_NEON_MEMORY to ensure a MEM_P be returned. */ 2979 op[argc] = expand_expr (arg[argc], NULL_RTX, VOIDmode, 2980 ((thisarg == ARG_BUILTIN_MEMORY 2981 || thisarg == ARG_BUILTIN_NEON_MEMORY) 2982 ? EXPAND_MEMORY : EXPAND_NORMAL)); 2983 2984 switch (thisarg) 2985 { 2986 case ARG_BUILTIN_MEMORY: 2987 case ARG_BUILTIN_COPY_TO_REG: 2988 if (POINTER_TYPE_P (TREE_TYPE (arg[argc]))) 2989 op[argc] = convert_memory_address (Pmode, op[argc]); 2990 2991 /* MVE uses mve_pred16_t (aka HImode) for vectors of 2992 predicates. */ 2993 if (GET_MODE_CLASS (mode[argc]) == MODE_VECTOR_BOOL) 2994 op[argc] = gen_lowpart (mode[argc], op[argc]); 2995 2996 /*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */ 2997 if (!(*insn_data[icode].operand[opno].predicate) 2998 (op[argc], mode[argc])) 2999 op[argc] = copy_to_mode_reg (mode[argc], op[argc]); 3000 break; 3001 3002 case ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX: 3003 gcc_assert (argc > 1); 3004 if (CONST_INT_P (op[argc])) 3005 { 3006 neon_lane_bounds (op[argc], 0, 3007 GET_MODE_NUNITS (map_mode), exp); 3008 /* Keep to GCC-vector-extension lane indices in the RTL. */ 3009 op[argc] = 3010 GEN_INT (NEON_ENDIAN_LANE_N (map_mode, INTVAL (op[argc]))); 3011 } 3012 goto constant_arg; 3013 3014 case ARG_BUILTIN_LANE_INDEX: 3015 /* Previous argument must be a vector, which this indexes. */ 3016 gcc_assert (argc > 0); 3017 if (CONST_INT_P (op[argc])) 3018 { 3019 machine_mode vmode = mode[argc - 1]; 3020 neon_lane_bounds (op[argc], 0, GET_MODE_NUNITS (vmode), exp); 3021 } 3022 /* If the lane index isn't a constant then error out. */ 3023 goto constant_arg; 3024 3025 case ARG_BUILTIN_LANE_PAIR_INDEX: 3026 /* Previous argument must be a vector, which this indexes. The 3027 indexing will always select i and i+1 out of the vector, which 3028 puts a limit on i. */ 3029 gcc_assert (argc > 0); 3030 if (CONST_INT_P (op[argc])) 3031 { 3032 machine_mode vmode = mode[argc - 1]; 3033 neon_lane_bounds (op[argc], 0, 3034 GET_MODE_NUNITS (vmode) / 2, exp); 3035 } 3036 /* If the lane index isn't a constant then error out. */ 3037 goto constant_arg; 3038 3039 case ARG_BUILTIN_LANE_QUADTUP_INDEX: 3040 /* Previous argument must be a vector, which this indexes. */ 3041 gcc_assert (argc > 0); 3042 if (CONST_INT_P (op[argc])) 3043 { 3044 machine_mode vmode = mode[argc - 1]; 3045 neon_lane_bounds (op[argc], 0, 3046 GET_MODE_NUNITS (vmode) / 4, exp); 3047 } 3048 /* If the lane index isn't a constant then error out. */ 3049 goto constant_arg; 3050 3051 case ARG_BUILTIN_CONSTANT: 3052constant_arg: 3053 if (!(*insn_data[icode].operand[opno].predicate) 3054 (op[argc], mode[argc])) 3055 { 3056 if (IN_RANGE (fcode, ARM_BUILTIN_CDE_PATTERN_START, 3057 ARM_BUILTIN_CDE_PATTERN_END)) 3058 { 3059 if (argc == 0) 3060 { 3061 unsigned int cp_bit = (CONST_INT_P (op[argc]) 3062 ? UINTVAL (op[argc]) : -1); 3063 if (IN_RANGE (cp_bit, 0, ARM_CDE_CONST_COPROC)) 3064 error_at (EXPR_LOCATION (exp), 3065 "coprocessor %d is not enabled " 3066 "with +cdecp%d", cp_bit, cp_bit); 3067 else 3068 error_at (EXPR_LOCATION (exp), 3069 "coproc must be a constant immediate in " 3070 "range [0-%d] enabled with %<+cdecp<N>%>", 3071 ARM_CDE_CONST_COPROC); 3072 } 3073 else 3074 /* Here we mention the builtin name to follow the same 3075 format that the C/C++ frontends use for referencing 3076 a given argument index. */ 3077 error_at (EXPR_LOCATION (exp), 3078 "argument %d to %qE must be a constant " 3079 "immediate in range [0-%d]", argc + 1, 3080 arm_builtin_decls[fcode], 3081 cde_builtin_data[fcode - 3082 ARM_BUILTIN_CDE_PATTERN_START].imm_max); 3083 } 3084 else 3085 error_at (EXPR_LOCATION (exp), 3086 "argument %d must be a constant immediate", 3087 argc + 1); 3088 /* We have failed to expand the pattern, and are safely 3089 in to invalid code. But the mid-end will still try to 3090 build an assignment for this node while it expands, 3091 before stopping for the error, just pass it back 3092 TARGET to ensure a valid assignment. */ 3093 return target; 3094 } 3095 break; 3096 3097 case ARG_BUILTIN_NEON_MEMORY: 3098 /* Check if expand failed. */ 3099 if (op[argc] == const0_rtx) 3100 return 0; 3101 gcc_assert (MEM_P (op[argc])); 3102 PUT_MODE (op[argc], mode[argc]); 3103 /* ??? arm_neon.h uses the same built-in functions for signed 3104 and unsigned accesses, casting where necessary. This isn't 3105 alias safe. */ 3106 set_mem_alias_set (op[argc], 0); 3107 if (!(*insn_data[icode].operand[opno].predicate) 3108 (op[argc], mode[argc])) 3109 op[argc] = (replace_equiv_address 3110 (op[argc], 3111 copy_to_mode_reg (Pmode, XEXP (op[argc], 0)))); 3112 break; 3113 3114 case ARG_BUILTIN_STOP: 3115 gcc_unreachable (); 3116 } 3117 3118 argc++; 3119 } 3120 } 3121 3122 if (have_retval) 3123 switch (argc) 3124 { 3125 case 0: 3126 pat = GEN_FCN (icode) (target); 3127 break; 3128 case 1: 3129 pat = GEN_FCN (icode) (target, op[0]); 3130 break; 3131 3132 case 2: 3133 pat = GEN_FCN (icode) (target, op[0], op[1]); 3134 break; 3135 3136 case 3: 3137 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]); 3138 break; 3139 3140 case 4: 3141 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]); 3142 break; 3143 3144 case 5: 3145 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]); 3146 break; 3147 3148 case 6: 3149 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4], op[5]); 3150 break; 3151 3152 default: 3153 gcc_unreachable (); 3154 } 3155 else 3156 switch (argc) 3157 { 3158 case 1: 3159 pat = GEN_FCN (icode) (op[0]); 3160 break; 3161 3162 case 2: 3163 pat = GEN_FCN (icode) (op[0], op[1]); 3164 break; 3165 3166 case 3: 3167 pat = GEN_FCN (icode) (op[0], op[1], op[2]); 3168 break; 3169 3170 case 4: 3171 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]); 3172 break; 3173 3174 case 5: 3175 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]); 3176 break; 3177 3178 case 6: 3179 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]); 3180 break; 3181 3182 default: 3183 gcc_unreachable (); 3184 } 3185 3186 if (!pat) 3187 return 0; 3188 3189 /* Check whether our current target implements the pattern chosen for this 3190 builtin and error out if not. */ 3191 start_sequence (); 3192 emit_insn (pat); 3193 insn = get_insns (); 3194 end_sequence (); 3195 3196 if (recog_memoized (insn) < 0) 3197 error ("this builtin is not supported for this target"); 3198 else 3199 emit_insn (insn); 3200 3201 if (GET_MODE_CLASS (tmode) == MODE_VECTOR_BOOL) 3202 { 3203 rtx HItarget = gen_reg_rtx (HImode); 3204 emit_move_insn (HItarget, gen_lowpart (HImode, target)); 3205 return HItarget; 3206 } 3207 3208 return target; 3209} 3210 3211/* Expand a builtin. These builtins are "special" because they don't have 3212 symbolic constants defined per-instruction or per instruction-variant. 3213 Instead, the required info is looked up in the ARM_BUILTIN_DATA record that 3214 is passed into the function. */ 3215 3216static rtx 3217arm_expand_builtin_1 (int fcode, tree exp, rtx target, 3218 arm_builtin_datum *d) 3219{ 3220 enum insn_code icode = d->code; 3221 builtin_arg args[SIMD_MAX_BUILTIN_ARGS + 1]; 3222 int num_args = insn_data[d->code].n_operands; 3223 int is_void = 0; 3224 int k; 3225 bool neon = false; 3226 bool mve = false; 3227 3228 if (IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_ACLE_BASE - 1)) 3229 neon = true; 3230 3231 if (IN_RANGE (fcode, ARM_BUILTIN_MVE_BASE, ARM_BUILTIN_MAX - 1)) 3232 mve = true; 3233 3234 is_void = !!(d->qualifiers[0] & qualifier_void); 3235 3236 num_args += is_void; 3237 3238 for (k = 1; k < num_args; k++) 3239 { 3240 /* We have four arrays of data, each indexed in a different fashion. 3241 qualifiers - element 0 always describes the function return type. 3242 operands - element 0 is either the operand for return value (if 3243 the function has a non-void return type) or the operand for the 3244 first argument. 3245 expr_args - element 0 always holds the first argument. 3246 args - element 0 is always used for the return type. */ 3247 int qualifiers_k = k; 3248 int operands_k = k - is_void; 3249 int expr_args_k = k - 1; 3250 3251 if (d->qualifiers[qualifiers_k] & qualifier_lane_index) 3252 args[k] = ARG_BUILTIN_LANE_INDEX; 3253 else if (d->qualifiers[qualifiers_k] & qualifier_lane_pair_index) 3254 args[k] = ARG_BUILTIN_LANE_PAIR_INDEX; 3255 else if (d->qualifiers[qualifiers_k] & qualifier_lane_quadtup_index) 3256 args[k] = ARG_BUILTIN_LANE_QUADTUP_INDEX; 3257 else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index) 3258 args[k] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX; 3259 else if (d->qualifiers[qualifiers_k] & qualifier_immediate) 3260 args[k] = ARG_BUILTIN_CONSTANT; 3261 else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate) 3262 { 3263 rtx arg 3264 = expand_normal (CALL_EXPR_ARG (exp, 3265 (expr_args_k))); 3266 /* Handle constants only if the predicate allows it. */ 3267 bool op_const_int_p = 3268 (CONST_INT_P (arg) 3269 && (*insn_data[icode].operand[operands_k].predicate) 3270 (arg, insn_data[icode].operand[operands_k].mode)); 3271 args[k] = op_const_int_p ? ARG_BUILTIN_CONSTANT : ARG_BUILTIN_COPY_TO_REG; 3272 } 3273 else if (d->qualifiers[qualifiers_k] & qualifier_pointer) 3274 { 3275 if (neon || mve) 3276 args[k] = ARG_BUILTIN_NEON_MEMORY; 3277 else 3278 args[k] = ARG_BUILTIN_MEMORY; 3279 } 3280 else 3281 args[k] = ARG_BUILTIN_COPY_TO_REG; 3282 } 3283 args[k] = ARG_BUILTIN_STOP; 3284 3285 /* The interface to arm_expand_builtin_args expects a 0 if 3286 the function is void, and a 1 if it is not. */ 3287 return arm_expand_builtin_args 3288 (target, d->mode, fcode, icode, !is_void, exp, 3289 &args[1]); 3290} 3291 3292/* Expand an ACLE builtin, i.e. those registered only if their respective 3293 target constraints are met. This check happens within 3294 arm_expand_builtin_args. */ 3295 3296static rtx 3297arm_expand_acle_builtin (int fcode, tree exp, rtx target) 3298{ 3299 if (fcode == ARM_BUILTIN_SAT_IMM_CHECK) 3300 { 3301 /* Check the saturation immediate bounds. */ 3302 3303 rtx min_sat = expand_normal (CALL_EXPR_ARG (exp, 1)); 3304 rtx max_sat = expand_normal (CALL_EXPR_ARG (exp, 2)); 3305 gcc_assert (CONST_INT_P (min_sat)); 3306 gcc_assert (CONST_INT_P (max_sat)); 3307 rtx sat_imm = expand_normal (CALL_EXPR_ARG (exp, 0)); 3308 if (CONST_INT_P (sat_imm)) 3309 { 3310 if (!IN_RANGE (sat_imm, min_sat, max_sat)) 3311 error_at (EXPR_LOCATION (exp), 3312 "saturation bit range must be in the range [%wd, %wd]", 3313 UINTVAL (min_sat), UINTVAL (max_sat)); 3314 } 3315 else 3316 error_at (EXPR_LOCATION (exp), 3317 "saturation bit range must be a constant immediate"); 3318 /* Don't generate any RTL. */ 3319 return const0_rtx; 3320 } 3321 3322 gcc_assert (fcode != ARM_BUILTIN_CDE_BASE); 3323 arm_builtin_datum *d 3324 = (fcode < ARM_BUILTIN_CDE_BASE) 3325 ? &acle_builtin_data[fcode - ARM_BUILTIN_ACLE_PATTERN_START] 3326 : &cde_builtin_data[fcode - ARM_BUILTIN_CDE_PATTERN_START].base; 3327 3328 return arm_expand_builtin_1 (fcode, exp, target, d); 3329} 3330 3331/* Expand an MVE builtin, i.e. those registered only if their respective target 3332 constraints are met. This check happens within arm_expand_builtin. */ 3333 3334static rtx 3335arm_expand_mve_builtin (int fcode, tree exp, rtx target) 3336{ 3337 if (fcode >= ARM_BUILTIN_MVE_BASE && !TARGET_HAVE_MVE) 3338 { 3339 fatal_error (input_location, 3340 "You must enable MVE instructions" 3341 " to use these intrinsics"); 3342 return const0_rtx; 3343 } 3344 3345 arm_builtin_datum *d 3346 = &mve_builtin_data[fcode - ARM_BUILTIN_MVE_PATTERN_START]; 3347 3348 return arm_expand_builtin_1 (fcode, exp, target, d); 3349} 3350 3351/* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds. 3352 Most of these are "special" because they don't have symbolic 3353 constants defined per-instruction or per instruction-variant. Instead, the 3354 required info is looked up in the table neon_builtin_data. */ 3355 3356static rtx 3357arm_expand_neon_builtin (int fcode, tree exp, rtx target) 3358{ 3359 if (fcode >= ARM_BUILTIN_NEON_BASE && ! TARGET_NEON) 3360 { 3361 fatal_error (input_location, 3362 "You must enable NEON instructions" 3363 " (e.g. %<-mfloat-abi=softfp%> %<-mfpu=neon%>)" 3364 " to use these intrinsics."); 3365 return const0_rtx; 3366 } 3367 3368 arm_builtin_datum *d 3369 = &neon_builtin_data[fcode - ARM_BUILTIN_NEON_PATTERN_START]; 3370 3371 return arm_expand_builtin_1 (fcode, exp, target, d); 3372} 3373 3374/* Expand a VFP builtin. These builtins are treated like 3375 neon builtins except that the data is looked up in table 3376 VFP_BUILTIN_DATA. */ 3377 3378static rtx 3379arm_expand_vfp_builtin (int fcode, tree exp, rtx target) 3380{ 3381 if (fcode >= ARM_BUILTIN_VFP_BASE && ! TARGET_HARD_FLOAT) 3382 { 3383 fatal_error (input_location, 3384 "You must enable VFP instructions" 3385 " to use these intrinsics."); 3386 return const0_rtx; 3387 } 3388 3389 arm_builtin_datum *d 3390 = &vfp_builtin_data[fcode - ARM_BUILTIN_VFP_PATTERN_START]; 3391 3392 return arm_expand_builtin_1 (fcode, exp, target, d); 3393} 3394 3395/* Expand an expression EXP that calls a built-in function, 3396 with result going to TARGET if that's convenient 3397 (and in mode MODE if that's convenient). 3398 SUBTARGET may be used as the target for computing one of EXP's operands. 3399 IGNORE is nonzero if the value is to be ignored. */ 3400 3401rtx 3402arm_expand_builtin (tree exp, 3403 rtx target, 3404 rtx subtarget ATTRIBUTE_UNUSED, 3405 machine_mode mode ATTRIBUTE_UNUSED, 3406 int ignore ATTRIBUTE_UNUSED) 3407{ 3408 const struct builtin_description * d; 3409 enum insn_code icode; 3410 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 3411 tree arg0; 3412 tree arg1; 3413 tree arg2; 3414 rtx op0; 3415 rtx op1; 3416 rtx op2; 3417 rtx pat; 3418 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); 3419 size_t i; 3420 machine_mode tmode; 3421 machine_mode mode0; 3422 machine_mode mode1; 3423 machine_mode mode2; 3424 int opint; 3425 int selector; 3426 int mask; 3427 int imm; 3428 3429 if (fcode == ARM_BUILTIN_SIMD_LANE_CHECK) 3430 { 3431 /* Builtin is only to check bounds of the lane passed to some intrinsics 3432 that are implemented with gcc vector extensions in arm_neon.h. */ 3433 3434 tree nlanes = CALL_EXPR_ARG (exp, 0); 3435 gcc_assert (TREE_CODE (nlanes) == INTEGER_CST); 3436 rtx lane_idx = expand_normal (CALL_EXPR_ARG (exp, 1)); 3437 if (CONST_INT_P (lane_idx)) 3438 neon_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp); 3439 else 3440 error_at (EXPR_LOCATION (exp), 3441 "lane index must be a constant immediate"); 3442 /* Don't generate any RTL. */ 3443 return const0_rtx; 3444 } 3445 if (fcode >= ARM_BUILTIN_MVE_BASE) 3446 return arm_expand_mve_builtin (fcode, exp, target); 3447 3448 if (fcode >= ARM_BUILTIN_ACLE_BASE) 3449 return arm_expand_acle_builtin (fcode, exp, target); 3450 3451 if (fcode >= ARM_BUILTIN_NEON_BASE) 3452 return arm_expand_neon_builtin (fcode, exp, target); 3453 3454 if (fcode >= ARM_BUILTIN_VFP_BASE) 3455 return arm_expand_vfp_builtin (fcode, exp, target); 3456 3457 /* Check in the context of the function making the call whether the 3458 builtin is supported. */ 3459 if (fcode >= ARM_BUILTIN_CRYPTO_BASE 3460 && (!TARGET_CRYPTO || !TARGET_HARD_FLOAT)) 3461 { 3462 fatal_error (input_location, 3463 "You must enable crypto instructions" 3464 " (e.g. include %<-mfloat-abi=softfp%> " 3465 "%<-mfpu=crypto-neon%>)" 3466 " to use these intrinsics."); 3467 return const0_rtx; 3468 } 3469 3470 switch (fcode) 3471 { 3472 case ARM_BUILTIN_GET_FPSCR_NZCVQC: 3473 case ARM_BUILTIN_SET_FPSCR_NZCVQC: 3474 if (fcode == ARM_BUILTIN_GET_FPSCR_NZCVQC) 3475 { 3476 icode = CODE_FOR_get_fpscr_nzcvqc; 3477 target = gen_reg_rtx (SImode); 3478 emit_insn (GEN_FCN (icode) (target)); 3479 return target; 3480 } 3481 else 3482 { 3483 icode = CODE_FOR_set_fpscr_nzcvqc; 3484 op0 = expand_normal (CALL_EXPR_ARG (exp, 0)); 3485 emit_insn (GEN_FCN (icode) (force_reg (SImode, op0))); 3486 return NULL_RTX; 3487 } 3488 3489 case ARM_BUILTIN_GET_FPSCR: 3490 case ARM_BUILTIN_SET_FPSCR: 3491 if (fcode == ARM_BUILTIN_GET_FPSCR) 3492 { 3493 icode = CODE_FOR_get_fpscr; 3494 target = gen_reg_rtx (SImode); 3495 pat = GEN_FCN (icode) (target); 3496 } 3497 else 3498 { 3499 target = NULL_RTX; 3500 icode = CODE_FOR_set_fpscr; 3501 arg0 = CALL_EXPR_ARG (exp, 0); 3502 op0 = expand_normal (arg0); 3503 pat = GEN_FCN (icode) (force_reg (SImode, op0)); 3504 } 3505 emit_insn (pat); 3506 return target; 3507 3508 case ARM_BUILTIN_CMSE_NONSECURE_CALLER: 3509 target = gen_reg_rtx (SImode); 3510 op0 = arm_return_addr (0, NULL_RTX); 3511 emit_insn (gen_andsi3 (target, op0, const1_rtx)); 3512 op1 = gen_rtx_EQ (SImode, target, const0_rtx); 3513 emit_insn (gen_cstoresi4 (target, op1, target, const0_rtx)); 3514 return target; 3515 3516 case ARM_BUILTIN_TEXTRMSB: 3517 case ARM_BUILTIN_TEXTRMUB: 3518 case ARM_BUILTIN_TEXTRMSH: 3519 case ARM_BUILTIN_TEXTRMUH: 3520 case ARM_BUILTIN_TEXTRMSW: 3521 case ARM_BUILTIN_TEXTRMUW: 3522 icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb 3523 : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub 3524 : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh 3525 : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh 3526 : CODE_FOR_iwmmxt_textrmw); 3527 3528 arg0 = CALL_EXPR_ARG (exp, 0); 3529 arg1 = CALL_EXPR_ARG (exp, 1); 3530 op0 = expand_normal (arg0); 3531 op1 = expand_normal (arg1); 3532 tmode = insn_data[icode].operand[0].mode; 3533 mode0 = insn_data[icode].operand[1].mode; 3534 mode1 = insn_data[icode].operand[2].mode; 3535 3536 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 3537 op0 = copy_to_mode_reg (mode0, op0); 3538 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) 3539 { 3540 /* @@@ better error message */ 3541 error ("selector must be an immediate"); 3542 return gen_reg_rtx (tmode); 3543 } 3544 3545 opint = INTVAL (op1); 3546 if (fcode == ARM_BUILTIN_TEXTRMSB || fcode == ARM_BUILTIN_TEXTRMUB) 3547 { 3548 if (opint > 7 || opint < 0) 3549 error ("the range of selector should be in 0 to 7"); 3550 } 3551 else if (fcode == ARM_BUILTIN_TEXTRMSH || fcode == ARM_BUILTIN_TEXTRMUH) 3552 { 3553 if (opint > 3 || opint < 0) 3554 error ("the range of selector should be in 0 to 3"); 3555 } 3556 else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */ 3557 { 3558 if (opint > 1 || opint < 0) 3559 error ("the range of selector should be in 0 to 1"); 3560 } 3561 3562 if (target == 0 3563 || GET_MODE (target) != tmode 3564 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 3565 target = gen_reg_rtx (tmode); 3566 pat = GEN_FCN (icode) (target, op0, op1); 3567 if (! pat) 3568 return 0; 3569 emit_insn (pat); 3570 return target; 3571 3572 case ARM_BUILTIN_WALIGNI: 3573 /* If op2 is immediate, call walighi, else call walighr. */ 3574 arg0 = CALL_EXPR_ARG (exp, 0); 3575 arg1 = CALL_EXPR_ARG (exp, 1); 3576 arg2 = CALL_EXPR_ARG (exp, 2); 3577 op0 = expand_normal (arg0); 3578 op1 = expand_normal (arg1); 3579 op2 = expand_normal (arg2); 3580 if (CONST_INT_P (op2)) 3581 { 3582 icode = CODE_FOR_iwmmxt_waligni; 3583 tmode = insn_data[icode].operand[0].mode; 3584 mode0 = insn_data[icode].operand[1].mode; 3585 mode1 = insn_data[icode].operand[2].mode; 3586 mode2 = insn_data[icode].operand[3].mode; 3587 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) 3588 op0 = copy_to_mode_reg (mode0, op0); 3589 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) 3590 op1 = copy_to_mode_reg (mode1, op1); 3591 gcc_assert ((*insn_data[icode].operand[3].predicate) (op2, mode2)); 3592 selector = INTVAL (op2); 3593 if (selector > 7 || selector < 0) 3594 error ("the range of selector should be in 0 to 7"); 3595 } 3596 else 3597 { 3598 icode = CODE_FOR_iwmmxt_walignr; 3599 tmode = insn_data[icode].operand[0].mode; 3600 mode0 = insn_data[icode].operand[1].mode; 3601 mode1 = insn_data[icode].operand[2].mode; 3602 mode2 = insn_data[icode].operand[3].mode; 3603 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) 3604 op0 = copy_to_mode_reg (mode0, op0); 3605 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) 3606 op1 = copy_to_mode_reg (mode1, op1); 3607 if (!(*insn_data[icode].operand[3].predicate) (op2, mode2)) 3608 op2 = copy_to_mode_reg (mode2, op2); 3609 } 3610 if (target == 0 3611 || GET_MODE (target) != tmode 3612 || !(*insn_data[icode].operand[0].predicate) (target, tmode)) 3613 target = gen_reg_rtx (tmode); 3614 pat = GEN_FCN (icode) (target, op0, op1, op2); 3615 if (!pat) 3616 return 0; 3617 emit_insn (pat); 3618 return target; 3619 3620 case ARM_BUILTIN_TINSRB: 3621 case ARM_BUILTIN_TINSRH: 3622 case ARM_BUILTIN_TINSRW: 3623 case ARM_BUILTIN_WMERGE: 3624 icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb 3625 : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh 3626 : fcode == ARM_BUILTIN_WMERGE ? CODE_FOR_iwmmxt_wmerge 3627 : CODE_FOR_iwmmxt_tinsrw); 3628 arg0 = CALL_EXPR_ARG (exp, 0); 3629 arg1 = CALL_EXPR_ARG (exp, 1); 3630 arg2 = CALL_EXPR_ARG (exp, 2); 3631 op0 = expand_normal (arg0); 3632 op1 = expand_normal (arg1); 3633 op2 = expand_normal (arg2); 3634 tmode = insn_data[icode].operand[0].mode; 3635 mode0 = insn_data[icode].operand[1].mode; 3636 mode1 = insn_data[icode].operand[2].mode; 3637 mode2 = insn_data[icode].operand[3].mode; 3638 3639 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 3640 op0 = copy_to_mode_reg (mode0, op0); 3641 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) 3642 op1 = copy_to_mode_reg (mode1, op1); 3643 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2)) 3644 { 3645 error ("selector must be an immediate"); 3646 return const0_rtx; 3647 } 3648 if (icode == CODE_FOR_iwmmxt_wmerge) 3649 { 3650 selector = INTVAL (op2); 3651 if (selector > 7 || selector < 0) 3652 error ("the range of selector should be in 0 to 7"); 3653 } 3654 if ((icode == CODE_FOR_iwmmxt_tinsrb) 3655 || (icode == CODE_FOR_iwmmxt_tinsrh) 3656 || (icode == CODE_FOR_iwmmxt_tinsrw)) 3657 { 3658 mask = 0x01; 3659 selector= INTVAL (op2); 3660 if (icode == CODE_FOR_iwmmxt_tinsrb && (selector < 0 || selector > 7)) 3661 error ("the range of selector should be in 0 to 7"); 3662 else if (icode == CODE_FOR_iwmmxt_tinsrh && (selector < 0 ||selector > 3)) 3663 error ("the range of selector should be in 0 to 3"); 3664 else if (icode == CODE_FOR_iwmmxt_tinsrw && (selector < 0 ||selector > 1)) 3665 error ("the range of selector should be in 0 to 1"); 3666 mask <<= selector; 3667 op2 = GEN_INT (mask); 3668 } 3669 if (target == 0 3670 || GET_MODE (target) != tmode 3671 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 3672 target = gen_reg_rtx (tmode); 3673 pat = GEN_FCN (icode) (target, op0, op1, op2); 3674 if (! pat) 3675 return 0; 3676 emit_insn (pat); 3677 return target; 3678 3679 case ARM_BUILTIN_SETWCGR0: 3680 case ARM_BUILTIN_SETWCGR1: 3681 case ARM_BUILTIN_SETWCGR2: 3682 case ARM_BUILTIN_SETWCGR3: 3683 icode = (fcode == ARM_BUILTIN_SETWCGR0 ? CODE_FOR_iwmmxt_setwcgr0 3684 : fcode == ARM_BUILTIN_SETWCGR1 ? CODE_FOR_iwmmxt_setwcgr1 3685 : fcode == ARM_BUILTIN_SETWCGR2 ? CODE_FOR_iwmmxt_setwcgr2 3686 : CODE_FOR_iwmmxt_setwcgr3); 3687 arg0 = CALL_EXPR_ARG (exp, 0); 3688 op0 = expand_normal (arg0); 3689 mode0 = insn_data[icode].operand[0].mode; 3690 if (!(*insn_data[icode].operand[0].predicate) (op0, mode0)) 3691 op0 = copy_to_mode_reg (mode0, op0); 3692 pat = GEN_FCN (icode) (op0); 3693 if (!pat) 3694 return 0; 3695 emit_insn (pat); 3696 return 0; 3697 3698 case ARM_BUILTIN_GETWCGR0: 3699 case ARM_BUILTIN_GETWCGR1: 3700 case ARM_BUILTIN_GETWCGR2: 3701 case ARM_BUILTIN_GETWCGR3: 3702 icode = (fcode == ARM_BUILTIN_GETWCGR0 ? CODE_FOR_iwmmxt_getwcgr0 3703 : fcode == ARM_BUILTIN_GETWCGR1 ? CODE_FOR_iwmmxt_getwcgr1 3704 : fcode == ARM_BUILTIN_GETWCGR2 ? CODE_FOR_iwmmxt_getwcgr2 3705 : CODE_FOR_iwmmxt_getwcgr3); 3706 tmode = insn_data[icode].operand[0].mode; 3707 if (target == 0 3708 || GET_MODE (target) != tmode 3709 || !(*insn_data[icode].operand[0].predicate) (target, tmode)) 3710 target = gen_reg_rtx (tmode); 3711 pat = GEN_FCN (icode) (target); 3712 if (!pat) 3713 return 0; 3714 emit_insn (pat); 3715 return target; 3716 3717 case ARM_BUILTIN_WSHUFH: 3718 icode = CODE_FOR_iwmmxt_wshufh; 3719 arg0 = CALL_EXPR_ARG (exp, 0); 3720 arg1 = CALL_EXPR_ARG (exp, 1); 3721 op0 = expand_normal (arg0); 3722 op1 = expand_normal (arg1); 3723 tmode = insn_data[icode].operand[0].mode; 3724 mode1 = insn_data[icode].operand[1].mode; 3725 mode2 = insn_data[icode].operand[2].mode; 3726 3727 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1)) 3728 op0 = copy_to_mode_reg (mode1, op0); 3729 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2)) 3730 { 3731 error ("mask must be an immediate"); 3732 return const0_rtx; 3733 } 3734 selector = INTVAL (op1); 3735 if (selector < 0 || selector > 255) 3736 error ("the range of mask should be in 0 to 255"); 3737 if (target == 0 3738 || GET_MODE (target) != tmode 3739 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 3740 target = gen_reg_rtx (tmode); 3741 pat = GEN_FCN (icode) (target, op0, op1); 3742 if (! pat) 3743 return 0; 3744 emit_insn (pat); 3745 return target; 3746 3747 case ARM_BUILTIN_WMADDS: 3748 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds, exp, target); 3749 case ARM_BUILTIN_WMADDSX: 3750 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx, exp, target); 3751 case ARM_BUILTIN_WMADDSN: 3752 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn, exp, target); 3753 case ARM_BUILTIN_WMADDU: 3754 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu, exp, target); 3755 case ARM_BUILTIN_WMADDUX: 3756 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux, exp, target); 3757 case ARM_BUILTIN_WMADDUN: 3758 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun, exp, target); 3759 case ARM_BUILTIN_WSADBZ: 3760 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target); 3761 case ARM_BUILTIN_WSADHZ: 3762 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, exp, target); 3763 3764 /* Several three-argument builtins. */ 3765 case ARM_BUILTIN_WMACS: 3766 case ARM_BUILTIN_WMACU: 3767 case ARM_BUILTIN_TMIA: 3768 case ARM_BUILTIN_TMIAPH: 3769 case ARM_BUILTIN_TMIATT: 3770 case ARM_BUILTIN_TMIATB: 3771 case ARM_BUILTIN_TMIABT: 3772 case ARM_BUILTIN_TMIABB: 3773 case ARM_BUILTIN_WQMIABB: 3774 case ARM_BUILTIN_WQMIABT: 3775 case ARM_BUILTIN_WQMIATB: 3776 case ARM_BUILTIN_WQMIATT: 3777 case ARM_BUILTIN_WQMIABBN: 3778 case ARM_BUILTIN_WQMIABTN: 3779 case ARM_BUILTIN_WQMIATBN: 3780 case ARM_BUILTIN_WQMIATTN: 3781 case ARM_BUILTIN_WMIABB: 3782 case ARM_BUILTIN_WMIABT: 3783 case ARM_BUILTIN_WMIATB: 3784 case ARM_BUILTIN_WMIATT: 3785 case ARM_BUILTIN_WMIABBN: 3786 case ARM_BUILTIN_WMIABTN: 3787 case ARM_BUILTIN_WMIATBN: 3788 case ARM_BUILTIN_WMIATTN: 3789 case ARM_BUILTIN_WMIAWBB: 3790 case ARM_BUILTIN_WMIAWBT: 3791 case ARM_BUILTIN_WMIAWTB: 3792 case ARM_BUILTIN_WMIAWTT: 3793 case ARM_BUILTIN_WMIAWBBN: 3794 case ARM_BUILTIN_WMIAWBTN: 3795 case ARM_BUILTIN_WMIAWTBN: 3796 case ARM_BUILTIN_WMIAWTTN: 3797 case ARM_BUILTIN_WSADB: 3798 case ARM_BUILTIN_WSADH: 3799 icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs 3800 : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu 3801 : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia 3802 : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph 3803 : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb 3804 : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt 3805 : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb 3806 : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt 3807 : fcode == ARM_BUILTIN_WQMIABB ? CODE_FOR_iwmmxt_wqmiabb 3808 : fcode == ARM_BUILTIN_WQMIABT ? CODE_FOR_iwmmxt_wqmiabt 3809 : fcode == ARM_BUILTIN_WQMIATB ? CODE_FOR_iwmmxt_wqmiatb 3810 : fcode == ARM_BUILTIN_WQMIATT ? CODE_FOR_iwmmxt_wqmiatt 3811 : fcode == ARM_BUILTIN_WQMIABBN ? CODE_FOR_iwmmxt_wqmiabbn 3812 : fcode == ARM_BUILTIN_WQMIABTN ? CODE_FOR_iwmmxt_wqmiabtn 3813 : fcode == ARM_BUILTIN_WQMIATBN ? CODE_FOR_iwmmxt_wqmiatbn 3814 : fcode == ARM_BUILTIN_WQMIATTN ? CODE_FOR_iwmmxt_wqmiattn 3815 : fcode == ARM_BUILTIN_WMIABB ? CODE_FOR_iwmmxt_wmiabb 3816 : fcode == ARM_BUILTIN_WMIABT ? CODE_FOR_iwmmxt_wmiabt 3817 : fcode == ARM_BUILTIN_WMIATB ? CODE_FOR_iwmmxt_wmiatb 3818 : fcode == ARM_BUILTIN_WMIATT ? CODE_FOR_iwmmxt_wmiatt 3819 : fcode == ARM_BUILTIN_WMIABBN ? CODE_FOR_iwmmxt_wmiabbn 3820 : fcode == ARM_BUILTIN_WMIABTN ? CODE_FOR_iwmmxt_wmiabtn 3821 : fcode == ARM_BUILTIN_WMIATBN ? CODE_FOR_iwmmxt_wmiatbn 3822 : fcode == ARM_BUILTIN_WMIATTN ? CODE_FOR_iwmmxt_wmiattn 3823 : fcode == ARM_BUILTIN_WMIAWBB ? CODE_FOR_iwmmxt_wmiawbb 3824 : fcode == ARM_BUILTIN_WMIAWBT ? CODE_FOR_iwmmxt_wmiawbt 3825 : fcode == ARM_BUILTIN_WMIAWTB ? CODE_FOR_iwmmxt_wmiawtb 3826 : fcode == ARM_BUILTIN_WMIAWTT ? CODE_FOR_iwmmxt_wmiawtt 3827 : fcode == ARM_BUILTIN_WMIAWBBN ? CODE_FOR_iwmmxt_wmiawbbn 3828 : fcode == ARM_BUILTIN_WMIAWBTN ? CODE_FOR_iwmmxt_wmiawbtn 3829 : fcode == ARM_BUILTIN_WMIAWTBN ? CODE_FOR_iwmmxt_wmiawtbn 3830 : fcode == ARM_BUILTIN_WMIAWTTN ? CODE_FOR_iwmmxt_wmiawttn 3831 : fcode == ARM_BUILTIN_WSADB ? CODE_FOR_iwmmxt_wsadb 3832 : CODE_FOR_iwmmxt_wsadh); 3833 arg0 = CALL_EXPR_ARG (exp, 0); 3834 arg1 = CALL_EXPR_ARG (exp, 1); 3835 arg2 = CALL_EXPR_ARG (exp, 2); 3836 op0 = expand_normal (arg0); 3837 op1 = expand_normal (arg1); 3838 op2 = expand_normal (arg2); 3839 tmode = insn_data[icode].operand[0].mode; 3840 mode0 = insn_data[icode].operand[1].mode; 3841 mode1 = insn_data[icode].operand[2].mode; 3842 mode2 = insn_data[icode].operand[3].mode; 3843 3844 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 3845 op0 = copy_to_mode_reg (mode0, op0); 3846 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) 3847 op1 = copy_to_mode_reg (mode1, op1); 3848 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2)) 3849 op2 = copy_to_mode_reg (mode2, op2); 3850 if (target == 0 3851 || GET_MODE (target) != tmode 3852 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 3853 target = gen_reg_rtx (tmode); 3854 pat = GEN_FCN (icode) (target, op0, op1, op2); 3855 if (! pat) 3856 return 0; 3857 emit_insn (pat); 3858 return target; 3859 3860 case ARM_BUILTIN_WZERO: 3861 target = gen_reg_rtx (DImode); 3862 emit_insn (gen_iwmmxt_clrdi (target)); 3863 return target; 3864 3865 case ARM_BUILTIN_WSRLHI: 3866 case ARM_BUILTIN_WSRLWI: 3867 case ARM_BUILTIN_WSRLDI: 3868 case ARM_BUILTIN_WSLLHI: 3869 case ARM_BUILTIN_WSLLWI: 3870 case ARM_BUILTIN_WSLLDI: 3871 case ARM_BUILTIN_WSRAHI: 3872 case ARM_BUILTIN_WSRAWI: 3873 case ARM_BUILTIN_WSRADI: 3874 case ARM_BUILTIN_WRORHI: 3875 case ARM_BUILTIN_WRORWI: 3876 case ARM_BUILTIN_WRORDI: 3877 case ARM_BUILTIN_WSRLH: 3878 case ARM_BUILTIN_WSRLW: 3879 case ARM_BUILTIN_WSRLD: 3880 case ARM_BUILTIN_WSLLH: 3881 case ARM_BUILTIN_WSLLW: 3882 case ARM_BUILTIN_WSLLD: 3883 case ARM_BUILTIN_WSRAH: 3884 case ARM_BUILTIN_WSRAW: 3885 case ARM_BUILTIN_WSRAD: 3886 case ARM_BUILTIN_WRORH: 3887 case ARM_BUILTIN_WRORW: 3888 case ARM_BUILTIN_WRORD: 3889 icode = (fcode == ARM_BUILTIN_WSRLHI ? CODE_FOR_lshrv4hi3_iwmmxt 3890 : fcode == ARM_BUILTIN_WSRLWI ? CODE_FOR_lshrv2si3_iwmmxt 3891 : fcode == ARM_BUILTIN_WSRLDI ? CODE_FOR_lshrdi3_iwmmxt 3892 : fcode == ARM_BUILTIN_WSLLHI ? CODE_FOR_ashlv4hi3_iwmmxt 3893 : fcode == ARM_BUILTIN_WSLLWI ? CODE_FOR_ashlv2si3_iwmmxt 3894 : fcode == ARM_BUILTIN_WSLLDI ? CODE_FOR_ashldi3_iwmmxt 3895 : fcode == ARM_BUILTIN_WSRAHI ? CODE_FOR_ashrv4hi3_iwmmxt 3896 : fcode == ARM_BUILTIN_WSRAWI ? CODE_FOR_ashrv2si3_iwmmxt 3897 : fcode == ARM_BUILTIN_WSRADI ? CODE_FOR_ashrdi3_iwmmxt 3898 : fcode == ARM_BUILTIN_WRORHI ? CODE_FOR_rorv4hi3 3899 : fcode == ARM_BUILTIN_WRORWI ? CODE_FOR_rorv2si3 3900 : fcode == ARM_BUILTIN_WRORDI ? CODE_FOR_rordi3 3901 : fcode == ARM_BUILTIN_WSRLH ? CODE_FOR_lshrv4hi3_di 3902 : fcode == ARM_BUILTIN_WSRLW ? CODE_FOR_lshrv2si3_di 3903 : fcode == ARM_BUILTIN_WSRLD ? CODE_FOR_lshrdi3_di 3904 : fcode == ARM_BUILTIN_WSLLH ? CODE_FOR_ashlv4hi3_di 3905 : fcode == ARM_BUILTIN_WSLLW ? CODE_FOR_ashlv2si3_di 3906 : fcode == ARM_BUILTIN_WSLLD ? CODE_FOR_ashldi3_di 3907 : fcode == ARM_BUILTIN_WSRAH ? CODE_FOR_ashrv4hi3_di 3908 : fcode == ARM_BUILTIN_WSRAW ? CODE_FOR_ashrv2si3_di 3909 : fcode == ARM_BUILTIN_WSRAD ? CODE_FOR_ashrdi3_di 3910 : fcode == ARM_BUILTIN_WRORH ? CODE_FOR_rorv4hi3_di 3911 : fcode == ARM_BUILTIN_WRORW ? CODE_FOR_rorv2si3_di 3912 : fcode == ARM_BUILTIN_WRORD ? CODE_FOR_rordi3_di 3913 : CODE_FOR_nothing); 3914 arg1 = CALL_EXPR_ARG (exp, 1); 3915 op1 = expand_normal (arg1); 3916 if (GET_MODE (op1) == VOIDmode) 3917 { 3918 imm = INTVAL (op1); 3919 if ((fcode == ARM_BUILTIN_WRORWI || fcode == ARM_BUILTIN_WRORW) 3920 && (imm < 0 || imm > 32)) 3921 { 3922 const char *builtin = (fcode == ARM_BUILTIN_WRORWI 3923 ? "_mm_rori_pi32" : "_mm_ror_pi32"); 3924 error ("the range of count should be in 0 to 32; " 3925 "please check the intrinsic %qs in code", builtin); 3926 } 3927 else if ((fcode == ARM_BUILTIN_WRORHI || fcode == ARM_BUILTIN_WRORH) 3928 && (imm < 0 || imm > 16)) 3929 { 3930 const char *builtin = (fcode == ARM_BUILTIN_WRORHI 3931 ? "_mm_rori_pi16" : "_mm_ror_pi16"); 3932 error ("the range of count should be in 0 to 16; " 3933 "please check the intrinsic %qs in code", builtin); 3934 } 3935 else if ((fcode == ARM_BUILTIN_WRORDI || fcode == ARM_BUILTIN_WRORD) 3936 && (imm < 0 || imm > 64)) 3937 { 3938 const char *builtin = (fcode == ARM_BUILTIN_WRORDI 3939 ? "_mm_rori_si64" : "_mm_ror_si64"); 3940 error ("the range of count should be in 0 to 64; " 3941 "please check the intrinsic %qs in code", builtin); 3942 } 3943 else if (imm < 0) 3944 { 3945 const char *builtin; 3946 switch (fcode) 3947 { 3948 case ARM_BUILTIN_WSRLHI: 3949 builtin = "_mm_srli_pi16"; 3950 break; 3951 case ARM_BUILTIN_WSRLWI: 3952 builtin = "_mm_srli_pi32"; 3953 break; 3954 case ARM_BUILTIN_WSRLDI: 3955 builtin = "_mm_srli_si64"; 3956 break; 3957 case ARM_BUILTIN_WSLLHI: 3958 builtin = "_mm_slli_pi16"; 3959 break; 3960 case ARM_BUILTIN_WSLLWI: 3961 builtin = "_mm_slli_pi32"; 3962 break; 3963 case ARM_BUILTIN_WSLLDI: 3964 builtin = "_mm_slli_si64"; 3965 break; 3966 case ARM_BUILTIN_WSRAHI: 3967 builtin = "_mm_srai_pi16"; 3968 break; 3969 case ARM_BUILTIN_WSRAWI: 3970 builtin = "_mm_srai_pi32"; 3971 break; 3972 case ARM_BUILTIN_WSRADI: 3973 builtin = "_mm_srai_si64"; 3974 break; 3975 case ARM_BUILTIN_WSRLH: 3976 builtin = "_mm_srl_pi16"; 3977 break; 3978 case ARM_BUILTIN_WSRLW: 3979 builtin = "_mm_srl_pi32"; 3980 break; 3981 case ARM_BUILTIN_WSRLD: 3982 builtin = "_mm_srl_si64"; 3983 break; 3984 case ARM_BUILTIN_WSLLH: 3985 builtin = "_mm_sll_pi16"; 3986 break; 3987 case ARM_BUILTIN_WSLLW: 3988 builtin = "_mm_sll_pi32"; 3989 break; 3990 case ARM_BUILTIN_WSLLD: 3991 builtin = "_mm_sll_si64"; 3992 break; 3993 case ARM_BUILTIN_WSRAH: 3994 builtin = "_mm_sra_pi16"; 3995 break; 3996 case ARM_BUILTIN_WSRAW: 3997 builtin = "_mm_sra_si64"; 3998 break; 3999 default: 4000 builtin = "_mm_sra_si64"; 4001 break; 4002 } 4003 error ("the count should be no less than 0; " 4004 "please check the intrinsic %qs in code", builtin); 4005 } 4006 } 4007 return arm_expand_binop_builtin (icode, exp, target); 4008 4009 default: 4010 break; 4011 } 4012 4013 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) 4014 if (d->code == (enum arm_builtins) fcode) 4015 return arm_expand_binop_builtin (d->icode, exp, target); 4016 4017 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++) 4018 if (d->code == (enum arm_builtins) fcode) 4019 return arm_expand_unop_builtin (d->icode, exp, target, 0); 4020 4021 for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++) 4022 if (d->code == (enum arm_builtins) fcode) 4023 return arm_expand_ternop_builtin (d->icode, exp, target); 4024 4025 /* @@@ Should really do something sensible here. */ 4026 return NULL_RTX; 4027} 4028 4029tree 4030arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in) 4031{ 4032 machine_mode in_mode, out_mode; 4033 int in_n, out_n; 4034 bool out_unsigned_p = TYPE_UNSIGNED (type_out); 4035 4036 /* Can't provide any vectorized builtins when we can't use NEON. */ 4037 if (!TARGET_NEON) 4038 return NULL_TREE; 4039 4040 if (TREE_CODE (type_out) != VECTOR_TYPE 4041 || TREE_CODE (type_in) != VECTOR_TYPE) 4042 return NULL_TREE; 4043 4044 out_mode = TYPE_MODE (TREE_TYPE (type_out)); 4045 out_n = TYPE_VECTOR_SUBPARTS (type_out); 4046 in_mode = TYPE_MODE (TREE_TYPE (type_in)); 4047 in_n = TYPE_VECTOR_SUBPARTS (type_in); 4048 4049/* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the 4050 decl of the vectorized builtin for the appropriate vector mode. 4051 NULL_TREE is returned if no such builtin is available. */ 4052#undef ARM_CHECK_BUILTIN_MODE 4053#define ARM_CHECK_BUILTIN_MODE(C) \ 4054 (TARGET_VFP5 \ 4055 && flag_unsafe_math_optimizations \ 4056 && ARM_CHECK_BUILTIN_MODE_1 (C)) 4057 4058#undef ARM_CHECK_BUILTIN_MODE_1 4059#define ARM_CHECK_BUILTIN_MODE_1(C) \ 4060 (out_mode == SFmode && out_n == C \ 4061 && in_mode == SFmode && in_n == C) 4062 4063#undef ARM_FIND_VRINT_VARIANT 4064#define ARM_FIND_VRINT_VARIANT(N) \ 4065 (ARM_CHECK_BUILTIN_MODE (2) \ 4066 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \ 4067 : (ARM_CHECK_BUILTIN_MODE (4) \ 4068 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \ 4069 : NULL_TREE)) 4070 4071 switch (fn) 4072 { 4073 CASE_CFN_FLOOR: 4074 return ARM_FIND_VRINT_VARIANT (vrintm); 4075 CASE_CFN_CEIL: 4076 return ARM_FIND_VRINT_VARIANT (vrintp); 4077 CASE_CFN_TRUNC: 4078 return ARM_FIND_VRINT_VARIANT (vrintz); 4079 CASE_CFN_ROUND: 4080 return ARM_FIND_VRINT_VARIANT (vrinta); 4081#undef ARM_CHECK_BUILTIN_MODE_1 4082#define ARM_CHECK_BUILTIN_MODE_1(C) \ 4083 (out_mode == SImode && out_n == C \ 4084 && in_mode == SFmode && in_n == C) 4085 4086#define ARM_FIND_VCVT_VARIANT(N) \ 4087 (ARM_CHECK_BUILTIN_MODE (2) \ 4088 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sfv2si, false) \ 4089 : (ARM_CHECK_BUILTIN_MODE (4) \ 4090 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sfv4si, false) \ 4091 : NULL_TREE)) 4092 4093#define ARM_FIND_VCVTU_VARIANT(N) \ 4094 (ARM_CHECK_BUILTIN_MODE (2) \ 4095 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv2sfv2si, false) \ 4096 : (ARM_CHECK_BUILTIN_MODE (4) \ 4097 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \ 4098 : NULL_TREE)) 4099 CASE_CFN_LROUND: 4100 return (out_unsigned_p 4101 ? ARM_FIND_VCVTU_VARIANT (vcvta) 4102 : ARM_FIND_VCVT_VARIANT (vcvta)); 4103 CASE_CFN_LCEIL: 4104 return (out_unsigned_p 4105 ? ARM_FIND_VCVTU_VARIANT (vcvtp) 4106 : ARM_FIND_VCVT_VARIANT (vcvtp)); 4107 CASE_CFN_LFLOOR: 4108 return (out_unsigned_p 4109 ? ARM_FIND_VCVTU_VARIANT (vcvtm) 4110 : ARM_FIND_VCVT_VARIANT (vcvtm)); 4111#undef ARM_CHECK_BUILTIN_MODE 4112#define ARM_CHECK_BUILTIN_MODE(C, N) \ 4113 (out_mode == N##mode && out_n == C \ 4114 && in_mode == N##mode && in_n == C) 4115 case CFN_BUILT_IN_BSWAP16: 4116 if (ARM_CHECK_BUILTIN_MODE (4, HI)) 4117 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi, false); 4118 else if (ARM_CHECK_BUILTIN_MODE (8, HI)) 4119 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi, false); 4120 else 4121 return NULL_TREE; 4122 case CFN_BUILT_IN_BSWAP32: 4123 if (ARM_CHECK_BUILTIN_MODE (2, SI)) 4124 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si, false); 4125 else if (ARM_CHECK_BUILTIN_MODE (4, SI)) 4126 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si, false); 4127 else 4128 return NULL_TREE; 4129 case CFN_BUILT_IN_BSWAP64: 4130 if (ARM_CHECK_BUILTIN_MODE (2, DI)) 4131 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di, false); 4132 else 4133 return NULL_TREE; 4134 CASE_CFN_COPYSIGN: 4135 if (ARM_CHECK_BUILTIN_MODE (2, SF)) 4136 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf, false); 4137 else if (ARM_CHECK_BUILTIN_MODE (4, SF)) 4138 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf, false); 4139 else 4140 return NULL_TREE; 4141 4142 default: 4143 return NULL_TREE; 4144 } 4145 return NULL_TREE; 4146} 4147#undef ARM_FIND_VCVT_VARIANT 4148#undef ARM_FIND_VCVTU_VARIANT 4149#undef ARM_CHECK_BUILTIN_MODE 4150#undef ARM_FIND_VRINT_VARIANT 4151 4152void 4153arm_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) 4154{ 4155 const unsigned ARM_FE_INVALID = 1; 4156 const unsigned ARM_FE_DIVBYZERO = 2; 4157 const unsigned ARM_FE_OVERFLOW = 4; 4158 const unsigned ARM_FE_UNDERFLOW = 8; 4159 const unsigned ARM_FE_INEXACT = 16; 4160 const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT = (ARM_FE_INVALID 4161 | ARM_FE_DIVBYZERO 4162 | ARM_FE_OVERFLOW 4163 | ARM_FE_UNDERFLOW 4164 | ARM_FE_INEXACT); 4165 const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT = 8; 4166 tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv; 4167 tree new_fenv_var, reload_fenv, restore_fnenv; 4168 tree update_call, atomic_feraiseexcept, hold_fnclex; 4169 4170 if (!TARGET_HARD_FLOAT) 4171 return; 4172 4173 /* Generate the equivalent of : 4174 unsigned int fenv_var; 4175 fenv_var = __builtin_arm_get_fpscr (); 4176 4177 unsigned int masked_fenv; 4178 masked_fenv = fenv_var & mask; 4179 4180 __builtin_arm_set_fpscr (masked_fenv); */ 4181 4182 fenv_var = create_tmp_var_raw (unsigned_type_node); 4183 get_fpscr = arm_builtin_decls[ARM_BUILTIN_GET_FPSCR]; 4184 set_fpscr = arm_builtin_decls[ARM_BUILTIN_SET_FPSCR]; 4185 mask = build_int_cst (unsigned_type_node, 4186 ~((ARM_FE_ALL_EXCEPT << ARM_FE_EXCEPT_SHIFT) 4187 | ARM_FE_ALL_EXCEPT)); 4188 ld_fenv = build4 (TARGET_EXPR, unsigned_type_node, 4189 fenv_var, build_call_expr (get_fpscr, 0), 4190 NULL_TREE, NULL_TREE); 4191 masked_fenv = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var, mask); 4192 hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv); 4193 *hold = build2 (COMPOUND_EXPR, void_type_node, 4194 build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv), 4195 hold_fnclex); 4196 4197 /* Store the value of masked_fenv to clear the exceptions: 4198 __builtin_arm_set_fpscr (masked_fenv); */ 4199 4200 *clear = build_call_expr (set_fpscr, 1, masked_fenv); 4201 4202 /* Generate the equivalent of : 4203 unsigned int new_fenv_var; 4204 new_fenv_var = __builtin_arm_get_fpscr (); 4205 4206 __builtin_arm_set_fpscr (fenv_var); 4207 4208 __atomic_feraiseexcept (new_fenv_var); */ 4209 4210 new_fenv_var = create_tmp_var_raw (unsigned_type_node); 4211 reload_fenv = build4 (TARGET_EXPR, unsigned_type_node, new_fenv_var, 4212 build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE); 4213 restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var); 4214 atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT); 4215 update_call = build_call_expr (atomic_feraiseexcept, 1, 4216 fold_convert (integer_type_node, new_fenv_var)); 4217 *update = build2 (COMPOUND_EXPR, void_type_node, 4218 build2 (COMPOUND_EXPR, void_type_node, 4219 reload_fenv, restore_fnenv), update_call); 4220} 4221 4222/* Implement TARGET_CHECK_BUILTIN_CALL. Record a read of the Q bit through 4223 intrinsics in the machine function. */ 4224bool 4225arm_check_builtin_call (location_t , vec<location_t> , tree fndecl, 4226 tree, unsigned int, tree *) 4227{ 4228 int fcode = DECL_MD_FUNCTION_CODE (fndecl); 4229 if (fcode == ARM_BUILTIN_saturation_occurred 4230 || fcode == ARM_BUILTIN_set_saturation) 4231 { 4232 if (cfun && cfun->decl) 4233 DECL_ATTRIBUTES (cfun->decl) 4234 = tree_cons (get_identifier ("acle qbit"), NULL_TREE, 4235 DECL_ATTRIBUTES (cfun->decl)); 4236 } 4237 if (fcode == ARM_BUILTIN_sel) 4238 { 4239 if (cfun && cfun->decl) 4240 DECL_ATTRIBUTES (cfun->decl) 4241 = tree_cons (get_identifier ("acle gebits"), NULL_TREE, 4242 DECL_ATTRIBUTES (cfun->decl)); 4243 } 4244 return true; 4245} 4246 4247enum resolver_ident 4248arm_describe_resolver (tree fndecl) 4249{ 4250 if (DECL_MD_FUNCTION_CODE (fndecl) >= ARM_BUILTIN_vcx1qv16qi 4251 && DECL_MD_FUNCTION_CODE (fndecl) < ARM_BUILTIN_MVE_BASE) 4252 return arm_cde_resolver; 4253 return arm_no_resolver; 4254} 4255 4256unsigned 4257arm_cde_end_args (tree fndecl) 4258{ 4259 return DECL_MD_FUNCTION_CODE (fndecl) >= ARM_BUILTIN_vcx1q_p_v16qi ? 2 : 1; 4260} 4261 4262#include "gt-arm-builtins.h" 4263