1/* Expand builtin functions. 2 Copyright (C) 1988-2015 Free Software Foundation, Inc. 3 4This file is part of GCC. 5 6GCC is free software; you can redistribute it and/or modify it under 7the terms of the GNU General Public License as published by the Free 8Software Foundation; either version 3, or (at your option) any later 9version. 10 11GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12WARRANTY; without even the implied warranty of MERCHANTABILITY or 13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14for more details. 15 16You should have received a copy of the GNU General Public License 17along with GCC; see the file COPYING3. If not see 18<http://www.gnu.org/licenses/>. */ 19 20#include "config.h" 21#include "system.h" 22#include "coretypes.h" 23#include "tm.h" 24#include "machmode.h" 25#include "rtl.h" 26#include "hash-set.h" 27#include "vec.h" 28#include "double-int.h" 29#include "input.h" 30#include "alias.h" 31#include "symtab.h" 32#include "wide-int.h" 33#include "inchash.h" 34#include "tree.h" 35#include "fold-const.h" 36#include "stringpool.h" 37#include "stor-layout.h" 38#include "calls.h" 39#include "varasm.h" 40#include "tree-object-size.h" 41#include "realmpfr.h" 42#include "predict.h" 43#include "hashtab.h" 44#include "hard-reg-set.h" 45#include "function.h" 46#include "cfgrtl.h" 47#include "basic-block.h" 48#include "tree-ssa-alias.h" 49#include "internal-fn.h" 50#include "gimple-expr.h" 51#include "is-a.h" 52#include "gimple.h" 53#include "flags.h" 54#include "regs.h" 55#include "except.h" 56#include "insn-config.h" 57#include "statistics.h" 58#include "real.h" 59#include "fixed-value.h" 60#include "expmed.h" 61#include "dojump.h" 62#include "explow.h" 63#include "emit-rtl.h" 64#include "stmt.h" 65#include "expr.h" 66#include "insn-codes.h" 67#include "optabs.h" 68#include "libfuncs.h" 69#include "recog.h" 70#include "output.h" 71#include "typeclass.h" 72#include "tm_p.h" 73#include "target.h" 74#include "langhooks.h" 75#include "tree-ssanames.h" 76#include "tree-dfa.h" 77#include "value-prof.h" 78#include "diagnostic-core.h" 79#include "builtins.h" 80#include "asan.h" 81#include "cilk.h" 82#include "ipa-ref.h" 83#include "lto-streamer.h" 84#include "cgraph.h" 85#include "tree-chkp.h" 86#include "rtl-chkp.h" 87#include "gomp-constants.h" 88 89 90static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t)); 91 92struct target_builtins default_target_builtins; 93#if SWITCHABLE_TARGET 94struct target_builtins *this_target_builtins = &default_target_builtins; 95#endif 96 97/* Define the names of the builtin function types and codes. */ 98const char *const built_in_class_names[BUILT_IN_LAST] 99 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"}; 100 101#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X, 102const char * built_in_names[(int) END_BUILTINS] = 103{ 104#include "builtins.def" 105}; 106#undef DEF_BUILTIN 107 108/* Setup an array of builtin_info_type, make sure each element decl is 109 initialized to NULL_TREE. */ 110builtin_info_type builtin_info[(int)END_BUILTINS]; 111 112/* Non-zero if __builtin_constant_p should be folded right away. */ 113bool force_folding_builtin_constant_p; 114 115static rtx c_readstr (const char *, machine_mode); 116static int target_char_cast (tree, char *); 117static rtx get_memory_rtx (tree, tree); 118static int apply_args_size (void); 119static int apply_result_size (void); 120#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return) 121static rtx result_vector (int, rtx); 122#endif 123static void expand_builtin_update_setjmp_buf (rtx); 124static void expand_builtin_prefetch (tree); 125static rtx expand_builtin_apply_args (void); 126static rtx expand_builtin_apply_args_1 (void); 127static rtx expand_builtin_apply (rtx, rtx, rtx); 128static void expand_builtin_return (rtx); 129static enum type_class type_to_class (tree); 130static rtx expand_builtin_classify_type (tree); 131static void expand_errno_check (tree, rtx); 132static rtx expand_builtin_mathfn (tree, rtx, rtx); 133static rtx expand_builtin_mathfn_2 (tree, rtx, rtx); 134static rtx expand_builtin_mathfn_3 (tree, rtx, rtx); 135static rtx expand_builtin_mathfn_ternary (tree, rtx, rtx); 136static rtx expand_builtin_interclass_mathfn (tree, rtx); 137static rtx expand_builtin_sincos (tree); 138static rtx expand_builtin_cexpi (tree, rtx); 139static rtx expand_builtin_int_roundingfn (tree, rtx); 140static rtx expand_builtin_int_roundingfn_2 (tree, rtx); 141static rtx expand_builtin_next_arg (void); 142static rtx expand_builtin_va_start (tree); 143static rtx expand_builtin_va_end (tree); 144static rtx expand_builtin_va_copy (tree); 145static rtx expand_builtin_memcmp (tree, rtx, machine_mode); 146static rtx expand_builtin_strcmp (tree, rtx); 147static rtx expand_builtin_strncmp (tree, rtx, machine_mode); 148static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, machine_mode); 149static rtx expand_builtin_memcpy (tree, rtx); 150static rtx expand_builtin_memcpy_with_bounds (tree, rtx); 151static rtx expand_builtin_memcpy_args (tree, tree, tree, rtx, tree); 152static rtx expand_builtin_mempcpy (tree, rtx, machine_mode); 153static rtx expand_builtin_mempcpy_with_bounds (tree, rtx, machine_mode); 154static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, 155 machine_mode, int, tree); 156static rtx expand_builtin_strcpy (tree, rtx); 157static rtx expand_builtin_strcpy_args (tree, tree, rtx); 158static rtx expand_builtin_stpcpy (tree, rtx, machine_mode); 159static rtx expand_builtin_strncpy (tree, rtx); 160static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, machine_mode); 161static rtx expand_builtin_memset (tree, rtx, machine_mode); 162static rtx expand_builtin_memset_with_bounds (tree, rtx, machine_mode); 163static rtx expand_builtin_memset_args (tree, tree, tree, rtx, machine_mode, tree); 164static rtx expand_builtin_bzero (tree); 165static rtx expand_builtin_strlen (tree, rtx, machine_mode); 166static rtx expand_builtin_alloca (tree, bool); 167static rtx expand_builtin_unop (machine_mode, tree, rtx, rtx, optab); 168static rtx expand_builtin_frame_address (tree, tree); 169static tree stabilize_va_list_loc (location_t, tree, int); 170static rtx expand_builtin_expect (tree, rtx); 171static tree fold_builtin_constant_p (tree); 172static tree fold_builtin_classify_type (tree); 173static tree fold_builtin_strlen (location_t, tree, tree); 174static tree fold_builtin_inf (location_t, tree, int); 175static tree fold_builtin_nan (tree, tree, int); 176static tree rewrite_call_expr (location_t, tree, int, tree, int, ...); 177static bool validate_arg (const_tree, enum tree_code code); 178static bool integer_valued_real_p (tree); 179static tree fold_trunc_transparent_mathfn (location_t, tree, tree); 180static rtx expand_builtin_fabs (tree, rtx, rtx); 181static rtx expand_builtin_signbit (tree, rtx); 182static tree fold_builtin_sqrt (location_t, tree, tree); 183static tree fold_builtin_cbrt (location_t, tree, tree); 184static tree fold_builtin_pow (location_t, tree, tree, tree, tree); 185static tree fold_builtin_powi (location_t, tree, tree, tree, tree); 186static tree fold_builtin_cos (location_t, tree, tree, tree); 187static tree fold_builtin_cosh (location_t, tree, tree, tree); 188static tree fold_builtin_tan (tree, tree); 189static tree fold_builtin_trunc (location_t, tree, tree); 190static tree fold_builtin_floor (location_t, tree, tree); 191static tree fold_builtin_ceil (location_t, tree, tree); 192static tree fold_builtin_round (location_t, tree, tree); 193static tree fold_builtin_int_roundingfn (location_t, tree, tree); 194static tree fold_builtin_bitop (tree, tree); 195static tree fold_builtin_strchr (location_t, tree, tree, tree); 196static tree fold_builtin_memchr (location_t, tree, tree, tree, tree); 197static tree fold_builtin_memcmp (location_t, tree, tree, tree); 198static tree fold_builtin_strcmp (location_t, tree, tree); 199static tree fold_builtin_strncmp (location_t, tree, tree, tree); 200static tree fold_builtin_signbit (location_t, tree, tree); 201static tree fold_builtin_copysign (location_t, tree, tree, tree, tree); 202static tree fold_builtin_isascii (location_t, tree); 203static tree fold_builtin_toascii (location_t, tree); 204static tree fold_builtin_isdigit (location_t, tree); 205static tree fold_builtin_fabs (location_t, tree, tree); 206static tree fold_builtin_abs (location_t, tree, tree); 207static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code, 208 enum tree_code); 209static tree fold_builtin_0 (location_t, tree); 210static tree fold_builtin_1 (location_t, tree, tree); 211static tree fold_builtin_2 (location_t, tree, tree, tree); 212static tree fold_builtin_3 (location_t, tree, tree, tree, tree); 213static tree fold_builtin_varargs (location_t, tree, tree*, int); 214 215static tree fold_builtin_strpbrk (location_t, tree, tree, tree); 216static tree fold_builtin_strstr (location_t, tree, tree, tree); 217static tree fold_builtin_strrchr (location_t, tree, tree, tree); 218static tree fold_builtin_strspn (location_t, tree, tree); 219static tree fold_builtin_strcspn (location_t, tree, tree); 220 221static rtx expand_builtin_object_size (tree); 222static rtx expand_builtin_memory_chk (tree, rtx, machine_mode, 223 enum built_in_function); 224static void maybe_emit_chk_warning (tree, enum built_in_function); 225static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function); 226static void maybe_emit_free_warning (tree); 227static tree fold_builtin_object_size (tree, tree); 228 229unsigned HOST_WIDE_INT target_newline; 230unsigned HOST_WIDE_INT target_percent; 231static unsigned HOST_WIDE_INT target_c; 232static unsigned HOST_WIDE_INT target_s; 233char target_percent_c[3]; 234char target_percent_s[3]; 235char target_percent_s_newline[4]; 236static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t), 237 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool); 238static tree do_mpfr_arg2 (tree, tree, tree, 239 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); 240static tree do_mpfr_arg3 (tree, tree, tree, tree, 241 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); 242static tree do_mpfr_sincos (tree, tree, tree); 243static tree do_mpfr_bessel_n (tree, tree, tree, 244 int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t), 245 const REAL_VALUE_TYPE *, bool); 246static tree do_mpfr_remquo (tree, tree, tree); 247static tree do_mpfr_lgamma_r (tree, tree, tree); 248static void expand_builtin_sync_synchronize (void); 249 250/* Return true if NAME starts with __builtin_ or __sync_. */ 251 252static bool 253is_builtin_name (const char *name) 254{ 255 if (strncmp (name, "__builtin_", 10) == 0) 256 return true; 257 if (strncmp (name, "__sync_", 7) == 0) 258 return true; 259 if (strncmp (name, "__atomic_", 9) == 0) 260 return true; 261 if (flag_cilkplus 262 && (!strcmp (name, "__cilkrts_detach") 263 || !strcmp (name, "__cilkrts_pop_frame"))) 264 return true; 265 return false; 266} 267 268 269/* Return true if DECL is a function symbol representing a built-in. */ 270 271bool 272is_builtin_fn (tree decl) 273{ 274 return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl); 275} 276 277/* Return true if NODE should be considered for inline expansion regardless 278 of the optimization level. This means whenever a function is invoked with 279 its "internal" name, which normally contains the prefix "__builtin". */ 280 281static bool 282called_as_built_in (tree node) 283{ 284 /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since 285 we want the name used to call the function, not the name it 286 will have. */ 287 const char *name = IDENTIFIER_POINTER (DECL_NAME (node)); 288 return is_builtin_name (name); 289} 290 291/* Compute values M and N such that M divides (address of EXP - N) and such 292 that N < M. If these numbers can be determined, store M in alignp and N in 293 *BITPOSP and return true. Otherwise return false and store BITS_PER_UNIT to 294 *alignp and any bit-offset to *bitposp. 295 296 Note that the address (and thus the alignment) computed here is based 297 on the address to which a symbol resolves, whereas DECL_ALIGN is based 298 on the address at which an object is actually located. These two 299 addresses are not always the same. For example, on ARM targets, 300 the address &foo of a Thumb function foo() has the lowest bit set, 301 whereas foo() itself starts on an even address. 302 303 If ADDR_P is true we are taking the address of the memory reference EXP 304 and thus cannot rely on the access taking place. */ 305 306static bool 307get_object_alignment_2 (tree exp, unsigned int *alignp, 308 unsigned HOST_WIDE_INT *bitposp, bool addr_p) 309{ 310 HOST_WIDE_INT bitsize, bitpos; 311 tree offset; 312 machine_mode mode; 313 int unsignedp, volatilep; 314 unsigned int align = BITS_PER_UNIT; 315 bool known_alignment = false; 316 317 /* Get the innermost object and the constant (bitpos) and possibly 318 variable (offset) offset of the access. */ 319 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset, 320 &mode, &unsignedp, &volatilep, true); 321 322 /* Extract alignment information from the innermost object and 323 possibly adjust bitpos and offset. */ 324 if (TREE_CODE (exp) == FUNCTION_DECL) 325 { 326 /* Function addresses can encode extra information besides their 327 alignment. However, if TARGET_PTRMEMFUNC_VBIT_LOCATION 328 allows the low bit to be used as a virtual bit, we know 329 that the address itself must be at least 2-byte aligned. */ 330 if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn) 331 align = 2 * BITS_PER_UNIT; 332 } 333 else if (TREE_CODE (exp) == LABEL_DECL) 334 ; 335 else if (TREE_CODE (exp) == CONST_DECL) 336 { 337 /* The alignment of a CONST_DECL is determined by its initializer. */ 338 exp = DECL_INITIAL (exp); 339 align = TYPE_ALIGN (TREE_TYPE (exp)); 340#ifdef CONSTANT_ALIGNMENT 341 if (CONSTANT_CLASS_P (exp)) 342 align = (unsigned) CONSTANT_ALIGNMENT (exp, align); 343#endif 344 known_alignment = true; 345 } 346 else if (DECL_P (exp)) 347 { 348 align = DECL_ALIGN (exp); 349 known_alignment = true; 350 } 351 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR) 352 { 353 align = TYPE_ALIGN (TREE_TYPE (exp)); 354 } 355 else if (TREE_CODE (exp) == INDIRECT_REF 356 || TREE_CODE (exp) == MEM_REF 357 || TREE_CODE (exp) == TARGET_MEM_REF) 358 { 359 tree addr = TREE_OPERAND (exp, 0); 360 unsigned ptr_align; 361 unsigned HOST_WIDE_INT ptr_bitpos; 362 unsigned HOST_WIDE_INT ptr_bitmask = ~0; 363 364 /* If the address is explicitely aligned, handle that. */ 365 if (TREE_CODE (addr) == BIT_AND_EXPR 366 && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST) 367 { 368 ptr_bitmask = TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)); 369 ptr_bitmask *= BITS_PER_UNIT; 370 align = ptr_bitmask & -ptr_bitmask; 371 addr = TREE_OPERAND (addr, 0); 372 } 373 374 known_alignment 375 = get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos); 376 align = MAX (ptr_align, align); 377 378 /* Re-apply explicit alignment to the bitpos. */ 379 ptr_bitpos &= ptr_bitmask; 380 381 /* The alignment of the pointer operand in a TARGET_MEM_REF 382 has to take the variable offset parts into account. */ 383 if (TREE_CODE (exp) == TARGET_MEM_REF) 384 { 385 if (TMR_INDEX (exp)) 386 { 387 unsigned HOST_WIDE_INT step = 1; 388 if (TMR_STEP (exp)) 389 step = TREE_INT_CST_LOW (TMR_STEP (exp)); 390 align = MIN (align, (step & -step) * BITS_PER_UNIT); 391 } 392 if (TMR_INDEX2 (exp)) 393 align = BITS_PER_UNIT; 394 known_alignment = false; 395 } 396 397 /* When EXP is an actual memory reference then we can use 398 TYPE_ALIGN of a pointer indirection to derive alignment. 399 Do so only if get_pointer_alignment_1 did not reveal absolute 400 alignment knowledge and if using that alignment would 401 improve the situation. */ 402 if (!addr_p && !known_alignment 403 && TYPE_ALIGN (TREE_TYPE (exp)) > align) 404 align = TYPE_ALIGN (TREE_TYPE (exp)); 405 else 406 { 407 /* Else adjust bitpos accordingly. */ 408 bitpos += ptr_bitpos; 409 if (TREE_CODE (exp) == MEM_REF 410 || TREE_CODE (exp) == TARGET_MEM_REF) 411 bitpos += mem_ref_offset (exp).to_short_addr () * BITS_PER_UNIT; 412 } 413 } 414 else if (TREE_CODE (exp) == STRING_CST) 415 { 416 /* STRING_CST are the only constant objects we allow to be not 417 wrapped inside a CONST_DECL. */ 418 align = TYPE_ALIGN (TREE_TYPE (exp)); 419#ifdef CONSTANT_ALIGNMENT 420 if (CONSTANT_CLASS_P (exp)) 421 align = (unsigned) CONSTANT_ALIGNMENT (exp, align); 422#endif 423 known_alignment = true; 424 } 425 426 /* If there is a non-constant offset part extract the maximum 427 alignment that can prevail. */ 428 if (offset) 429 { 430 unsigned int trailing_zeros = tree_ctz (offset); 431 if (trailing_zeros < HOST_BITS_PER_INT) 432 { 433 unsigned int inner = (1U << trailing_zeros) * BITS_PER_UNIT; 434 if (inner) 435 align = MIN (align, inner); 436 } 437 } 438 439 *alignp = align; 440 *bitposp = bitpos & (*alignp - 1); 441 return known_alignment; 442} 443 444/* For a memory reference expression EXP compute values M and N such that M 445 divides (&EXP - N) and such that N < M. If these numbers can be determined, 446 store M in alignp and N in *BITPOSP and return true. Otherwise return false 447 and store BITS_PER_UNIT to *alignp and any bit-offset to *bitposp. */ 448 449bool 450get_object_alignment_1 (tree exp, unsigned int *alignp, 451 unsigned HOST_WIDE_INT *bitposp) 452{ 453 return get_object_alignment_2 (exp, alignp, bitposp, false); 454} 455 456/* Return the alignment in bits of EXP, an object. */ 457 458unsigned int 459get_object_alignment (tree exp) 460{ 461 unsigned HOST_WIDE_INT bitpos = 0; 462 unsigned int align; 463 464 get_object_alignment_1 (exp, &align, &bitpos); 465 466 /* align and bitpos now specify known low bits of the pointer. 467 ptr & (align - 1) == bitpos. */ 468 469 if (bitpos != 0) 470 align = (bitpos & -bitpos); 471 return align; 472} 473 474/* For a pointer valued expression EXP compute values M and N such that M 475 divides (EXP - N) and such that N < M. If these numbers can be determined, 476 store M in alignp and N in *BITPOSP and return true. Return false if 477 the results are just a conservative approximation. 478 479 If EXP is not a pointer, false is returned too. */ 480 481bool 482get_pointer_alignment_1 (tree exp, unsigned int *alignp, 483 unsigned HOST_WIDE_INT *bitposp) 484{ 485 STRIP_NOPS (exp); 486 487 if (TREE_CODE (exp) == ADDR_EXPR) 488 return get_object_alignment_2 (TREE_OPERAND (exp, 0), 489 alignp, bitposp, true); 490 else if (TREE_CODE (exp) == SSA_NAME 491 && POINTER_TYPE_P (TREE_TYPE (exp))) 492 { 493 unsigned int ptr_align, ptr_misalign; 494 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp); 495 496 if (pi && get_ptr_info_alignment (pi, &ptr_align, &ptr_misalign)) 497 { 498 *bitposp = ptr_misalign * BITS_PER_UNIT; 499 *alignp = ptr_align * BITS_PER_UNIT; 500 /* Make sure to return a sensible alignment when the multiplication 501 by BITS_PER_UNIT overflowed. */ 502 if (*alignp == 0) 503 *alignp = 1u << (HOST_BITS_PER_INT - 1); 504 /* We cannot really tell whether this result is an approximation. */ 505 return false; 506 } 507 else 508 { 509 *bitposp = 0; 510 *alignp = BITS_PER_UNIT; 511 return false; 512 } 513 } 514 else if (TREE_CODE (exp) == INTEGER_CST) 515 { 516 *alignp = BIGGEST_ALIGNMENT; 517 *bitposp = ((TREE_INT_CST_LOW (exp) * BITS_PER_UNIT) 518 & (BIGGEST_ALIGNMENT - 1)); 519 return true; 520 } 521 522 *bitposp = 0; 523 *alignp = BITS_PER_UNIT; 524 return false; 525} 526 527/* Return the alignment in bits of EXP, a pointer valued expression. 528 The alignment returned is, by default, the alignment of the thing that 529 EXP points to. If it is not a POINTER_TYPE, 0 is returned. 530 531 Otherwise, look at the expression to see if we can do better, i.e., if the 532 expression is actually pointing at an object whose alignment is tighter. */ 533 534unsigned int 535get_pointer_alignment (tree exp) 536{ 537 unsigned HOST_WIDE_INT bitpos = 0; 538 unsigned int align; 539 540 get_pointer_alignment_1 (exp, &align, &bitpos); 541 542 /* align and bitpos now specify known low bits of the pointer. 543 ptr & (align - 1) == bitpos. */ 544 545 if (bitpos != 0) 546 align = (bitpos & -bitpos); 547 548 return align; 549} 550 551/* Compute the length of a C string. TREE_STRING_LENGTH is not the right 552 way, because it could contain a zero byte in the middle. 553 TREE_STRING_LENGTH is the size of the character array, not the string. 554 555 ONLY_VALUE should be nonzero if the result is not going to be emitted 556 into the instruction stream and zero if it is going to be expanded. 557 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3 558 is returned, otherwise NULL, since 559 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not 560 evaluate the side-effects. 561 562 If ONLY_VALUE is two then we do not emit warnings about out-of-bound 563 accesses. Note that this implies the result is not going to be emitted 564 into the instruction stream. 565 566 The value returned is of type `ssizetype'. 567 568 Unfortunately, string_constant can't access the values of const char 569 arrays with initializers, so neither can we do so here. */ 570 571tree 572c_strlen (tree src, int only_value) 573{ 574 tree offset_node; 575 HOST_WIDE_INT offset; 576 int max; 577 const char *ptr; 578 location_t loc; 579 580 STRIP_NOPS (src); 581 if (TREE_CODE (src) == COND_EXPR 582 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) 583 { 584 tree len1, len2; 585 586 len1 = c_strlen (TREE_OPERAND (src, 1), only_value); 587 len2 = c_strlen (TREE_OPERAND (src, 2), only_value); 588 if (tree_int_cst_equal (len1, len2)) 589 return len1; 590 } 591 592 if (TREE_CODE (src) == COMPOUND_EXPR 593 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) 594 return c_strlen (TREE_OPERAND (src, 1), only_value); 595 596 loc = EXPR_LOC_OR_LOC (src, input_location); 597 598 src = string_constant (src, &offset_node); 599 if (src == 0) 600 return NULL_TREE; 601 602 max = TREE_STRING_LENGTH (src) - 1; 603 ptr = TREE_STRING_POINTER (src); 604 605 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST) 606 { 607 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't 608 compute the offset to the following null if we don't know where to 609 start searching for it. */ 610 int i; 611 612 for (i = 0; i < max; i++) 613 if (ptr[i] == 0) 614 return NULL_TREE; 615 616 /* We don't know the starting offset, but we do know that the string 617 has no internal zero bytes. We can assume that the offset falls 618 within the bounds of the string; otherwise, the programmer deserves 619 what he gets. Subtract the offset from the length of the string, 620 and return that. This would perhaps not be valid if we were dealing 621 with named arrays in addition to literal string constants. */ 622 623 return size_diffop_loc (loc, size_int (max), offset_node); 624 } 625 626 /* We have a known offset into the string. Start searching there for 627 a null character if we can represent it as a single HOST_WIDE_INT. */ 628 if (offset_node == 0) 629 offset = 0; 630 else if (! tree_fits_shwi_p (offset_node)) 631 offset = -1; 632 else 633 offset = tree_to_shwi (offset_node); 634 635 /* If the offset is known to be out of bounds, warn, and call strlen at 636 runtime. */ 637 if (offset < 0 || offset > max) 638 { 639 /* Suppress multiple warnings for propagated constant strings. */ 640 if (only_value != 2 641 && !TREE_NO_WARNING (src)) 642 { 643 warning_at (loc, 0, "offset outside bounds of constant string"); 644 TREE_NO_WARNING (src) = 1; 645 } 646 return NULL_TREE; 647 } 648 649 /* Use strlen to search for the first zero byte. Since any strings 650 constructed with build_string will have nulls appended, we win even 651 if we get handed something like (char[4])"abcd". 652 653 Since OFFSET is our starting index into the string, no further 654 calculation is needed. */ 655 return ssize_int (strlen (ptr + offset)); 656} 657 658/* Return a char pointer for a C string if it is a string constant 659 or sum of string constant and integer constant. */ 660 661const char * 662c_getstr (tree src) 663{ 664 tree offset_node; 665 666 src = string_constant (src, &offset_node); 667 if (src == 0) 668 return 0; 669 670 if (offset_node == 0) 671 return TREE_STRING_POINTER (src); 672 else if (!tree_fits_uhwi_p (offset_node) 673 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0) 674 return 0; 675 676 return TREE_STRING_POINTER (src) + tree_to_uhwi (offset_node); 677} 678 679/* Return a constant integer corresponding to target reading 680 GET_MODE_BITSIZE (MODE) bits from string constant STR. */ 681 682static rtx 683c_readstr (const char *str, machine_mode mode) 684{ 685 HOST_WIDE_INT ch; 686 unsigned int i, j; 687 HOST_WIDE_INT tmp[MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT]; 688 689 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT); 690 unsigned int len = (GET_MODE_PRECISION (mode) + HOST_BITS_PER_WIDE_INT - 1) 691 / HOST_BITS_PER_WIDE_INT; 692 693 gcc_assert (len <= MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT); 694 for (i = 0; i < len; i++) 695 tmp[i] = 0; 696 697 ch = 1; 698 for (i = 0; i < GET_MODE_SIZE (mode); i++) 699 { 700 j = i; 701 if (WORDS_BIG_ENDIAN) 702 j = GET_MODE_SIZE (mode) - i - 1; 703 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN 704 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD) 705 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1; 706 j *= BITS_PER_UNIT; 707 708 if (ch) 709 ch = (unsigned char) str[i]; 710 tmp[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT); 711 } 712 713 wide_int c = wide_int::from_array (tmp, len, GET_MODE_PRECISION (mode)); 714 return immed_wide_int_const (c, mode); 715} 716 717/* Cast a target constant CST to target CHAR and if that value fits into 718 host char type, return zero and put that value into variable pointed to by 719 P. */ 720 721static int 722target_char_cast (tree cst, char *p) 723{ 724 unsigned HOST_WIDE_INT val, hostval; 725 726 if (TREE_CODE (cst) != INTEGER_CST 727 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT) 728 return 1; 729 730 /* Do not care if it fits or not right here. */ 731 val = TREE_INT_CST_LOW (cst); 732 733 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT) 734 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1; 735 736 hostval = val; 737 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT) 738 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1; 739 740 if (val != hostval) 741 return 1; 742 743 *p = hostval; 744 return 0; 745} 746 747/* Similar to save_expr, but assumes that arbitrary code is not executed 748 in between the multiple evaluations. In particular, we assume that a 749 non-addressable local variable will not be modified. */ 750 751static tree 752builtin_save_expr (tree exp) 753{ 754 if (TREE_CODE (exp) == SSA_NAME 755 || (TREE_ADDRESSABLE (exp) == 0 756 && (TREE_CODE (exp) == PARM_DECL 757 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))) 758 return exp; 759 760 return save_expr (exp); 761} 762 763/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT 764 times to get the address of either a higher stack frame, or a return 765 address located within it (depending on FNDECL_CODE). */ 766 767static rtx 768expand_builtin_return_addr (enum built_in_function fndecl_code, int count) 769{ 770 int i; 771 772#ifdef INITIAL_FRAME_ADDRESS_RTX 773 rtx tem = INITIAL_FRAME_ADDRESS_RTX; 774#else 775 rtx tem; 776 777 /* For a zero count with __builtin_return_address, we don't care what 778 frame address we return, because target-specific definitions will 779 override us. Therefore frame pointer elimination is OK, and using 780 the soft frame pointer is OK. 781 782 For a nonzero count, or a zero count with __builtin_frame_address, 783 we require a stable offset from the current frame pointer to the 784 previous one, so we must use the hard frame pointer, and 785 we must disable frame pointer elimination. */ 786 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS) 787 tem = frame_pointer_rtx; 788 else 789 { 790 tem = hard_frame_pointer_rtx; 791 792 /* Tell reload not to eliminate the frame pointer. */ 793 crtl->accesses_prior_frames = 1; 794 } 795#endif 796 797 /* Some machines need special handling before we can access 798 arbitrary frames. For example, on the SPARC, we must first flush 799 all register windows to the stack. */ 800#ifdef SETUP_FRAME_ADDRESSES 801 if (count > 0) 802 SETUP_FRAME_ADDRESSES (); 803#endif 804 805 /* On the SPARC, the return address is not in the frame, it is in a 806 register. There is no way to access it off of the current frame 807 pointer, but it can be accessed off the previous frame pointer by 808 reading the value from the register window save area. */ 809 if (RETURN_ADDR_IN_PREVIOUS_FRAME && fndecl_code == BUILT_IN_RETURN_ADDRESS) 810 count--; 811 812 /* Scan back COUNT frames to the specified frame. */ 813 for (i = 0; i < count; i++) 814 { 815 /* Assume the dynamic chain pointer is in the word that the 816 frame address points to, unless otherwise specified. */ 817#ifdef DYNAMIC_CHAIN_ADDRESS 818 tem = DYNAMIC_CHAIN_ADDRESS (tem); 819#endif 820 tem = memory_address (Pmode, tem); 821 tem = gen_frame_mem (Pmode, tem); 822 tem = copy_to_reg (tem); 823 } 824 825 /* For __builtin_frame_address, return what we've got. But, on 826 the SPARC for example, we may have to add a bias. */ 827 if (fndecl_code == BUILT_IN_FRAME_ADDRESS) 828#ifdef FRAME_ADDR_RTX 829 return FRAME_ADDR_RTX (tem); 830#else 831 return tem; 832#endif 833 834 /* For __builtin_return_address, get the return address from that frame. */ 835#ifdef RETURN_ADDR_RTX 836 tem = RETURN_ADDR_RTX (count, tem); 837#else 838 tem = memory_address (Pmode, 839 plus_constant (Pmode, tem, GET_MODE_SIZE (Pmode))); 840 tem = gen_frame_mem (Pmode, tem); 841#endif 842 return tem; 843} 844 845/* Alias set used for setjmp buffer. */ 846static alias_set_type setjmp_alias_set = -1; 847 848/* Construct the leading half of a __builtin_setjmp call. Control will 849 return to RECEIVER_LABEL. This is also called directly by the SJLJ 850 exception handling code. */ 851 852void 853expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label) 854{ 855 machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 856 rtx stack_save; 857 rtx mem; 858 859 if (setjmp_alias_set == -1) 860 setjmp_alias_set = new_alias_set (); 861 862 buf_addr = convert_memory_address (Pmode, buf_addr); 863 864 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX)); 865 866 /* We store the frame pointer and the address of receiver_label in 867 the buffer and use the rest of it for the stack save area, which 868 is machine-dependent. */ 869 870 mem = gen_rtx_MEM (Pmode, buf_addr); 871 set_mem_alias_set (mem, setjmp_alias_set); 872 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ()); 873 874 mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr, 875 GET_MODE_SIZE (Pmode))), 876 set_mem_alias_set (mem, setjmp_alias_set); 877 878 emit_move_insn (validize_mem (mem), 879 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label))); 880 881 stack_save = gen_rtx_MEM (sa_mode, 882 plus_constant (Pmode, buf_addr, 883 2 * GET_MODE_SIZE (Pmode))); 884 set_mem_alias_set (stack_save, setjmp_alias_set); 885 emit_stack_save (SAVE_NONLOCAL, &stack_save); 886 887 /* If there is further processing to do, do it. */ 888#ifdef HAVE_builtin_setjmp_setup 889 if (HAVE_builtin_setjmp_setup) 890 emit_insn (gen_builtin_setjmp_setup (buf_addr)); 891#endif 892 893 /* We have a nonlocal label. */ 894 cfun->has_nonlocal_label = 1; 895} 896 897/* Construct the trailing part of a __builtin_setjmp call. This is 898 also called directly by the SJLJ exception handling code. 899 If RECEIVER_LABEL is NULL, instead contruct a nonlocal goto handler. */ 900 901void 902expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED) 903{ 904 rtx chain; 905 906 /* Mark the FP as used when we get here, so we have to make sure it's 907 marked as used by this function. */ 908 emit_use (hard_frame_pointer_rtx); 909 910 /* Mark the static chain as clobbered here so life information 911 doesn't get messed up for it. */ 912 chain = targetm.calls.static_chain (current_function_decl, true); 913 if (chain && REG_P (chain)) 914 emit_clobber (chain); 915 916 /* Now put in the code to restore the frame pointer, and argument 917 pointer, if needed. */ 918#ifdef HAVE_nonlocal_goto 919 if (! HAVE_nonlocal_goto) 920#endif 921 { 922 /* First adjust our frame pointer to its actual value. It was 923 previously set to the start of the virtual area corresponding to 924 the stacked variables when we branched here and now needs to be 925 adjusted to the actual hardware fp value. 926 927 Assignments to virtual registers are converted by 928 instantiate_virtual_regs into the corresponding assignment 929 to the underlying register (fp in this case) that makes 930 the original assignment true. 931 So the following insn will actually be decrementing fp by 932 STARTING_FRAME_OFFSET. */ 933 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); 934 935 /* Restoring the frame pointer also modifies the hard frame pointer. 936 Mark it used (so that the previous assignment remains live once 937 the frame pointer is eliminated) and clobbered (to represent the 938 implicit update from the assignment). */ 939 emit_use (hard_frame_pointer_rtx); 940 emit_clobber (hard_frame_pointer_rtx); 941 } 942 943#if !HARD_FRAME_POINTER_IS_ARG_POINTER 944 if (fixed_regs[ARG_POINTER_REGNUM]) 945 { 946#ifdef ELIMINABLE_REGS 947 /* If the argument pointer can be eliminated in favor of the 948 frame pointer, we don't need to restore it. We assume here 949 that if such an elimination is present, it can always be used. 950 This is the case on all known machines; if we don't make this 951 assumption, we do unnecessary saving on many machines. */ 952 size_t i; 953 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS; 954 955 for (i = 0; i < ARRAY_SIZE (elim_regs); i++) 956 if (elim_regs[i].from == ARG_POINTER_REGNUM 957 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM) 958 break; 959 960 if (i == ARRAY_SIZE (elim_regs)) 961#endif 962 { 963 /* Now restore our arg pointer from the address at which it 964 was saved in our stack frame. */ 965 emit_move_insn (crtl->args.internal_arg_pointer, 966 copy_to_reg (get_arg_pointer_save_area ())); 967 } 968 } 969#endif 970 971#ifdef HAVE_builtin_setjmp_receiver 972 if (receiver_label != NULL && HAVE_builtin_setjmp_receiver) 973 emit_insn (gen_builtin_setjmp_receiver (receiver_label)); 974 else 975#endif 976#ifdef HAVE_nonlocal_goto_receiver 977 if (HAVE_nonlocal_goto_receiver) 978 emit_insn (gen_nonlocal_goto_receiver ()); 979 else 980#endif 981 { /* Nothing */ } 982 983 /* We must not allow the code we just generated to be reordered by 984 scheduling. Specifically, the update of the frame pointer must 985 happen immediately, not later. */ 986 emit_insn (gen_blockage ()); 987} 988 989/* __builtin_longjmp is passed a pointer to an array of five words (not 990 all will be used on all machines). It operates similarly to the C 991 library function of the same name, but is more efficient. Much of 992 the code below is copied from the handling of non-local gotos. */ 993 994static void 995expand_builtin_longjmp (rtx buf_addr, rtx value) 996{ 997 rtx fp, lab, stack; 998 rtx_insn *insn, *last; 999 machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 1000 1001 /* DRAP is needed for stack realign if longjmp is expanded to current 1002 function */ 1003 if (SUPPORTS_STACK_ALIGNMENT) 1004 crtl->need_drap = true; 1005 1006 if (setjmp_alias_set == -1) 1007 setjmp_alias_set = new_alias_set (); 1008 1009 buf_addr = convert_memory_address (Pmode, buf_addr); 1010 1011 buf_addr = force_reg (Pmode, buf_addr); 1012 1013 /* We require that the user must pass a second argument of 1, because 1014 that is what builtin_setjmp will return. */ 1015 gcc_assert (value == const1_rtx); 1016 1017 last = get_last_insn (); 1018#ifdef HAVE_builtin_longjmp 1019 if (HAVE_builtin_longjmp) 1020 emit_insn (gen_builtin_longjmp (buf_addr)); 1021 else 1022#endif 1023 { 1024 fp = gen_rtx_MEM (Pmode, buf_addr); 1025 lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr, 1026 GET_MODE_SIZE (Pmode))); 1027 1028 stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, buf_addr, 1029 2 * GET_MODE_SIZE (Pmode))); 1030 set_mem_alias_set (fp, setjmp_alias_set); 1031 set_mem_alias_set (lab, setjmp_alias_set); 1032 set_mem_alias_set (stack, setjmp_alias_set); 1033 1034 /* Pick up FP, label, and SP from the block and jump. This code is 1035 from expand_goto in stmt.c; see there for detailed comments. */ 1036#ifdef HAVE_nonlocal_goto 1037 if (HAVE_nonlocal_goto) 1038 /* We have to pass a value to the nonlocal_goto pattern that will 1039 get copied into the static_chain pointer, but it does not matter 1040 what that value is, because builtin_setjmp does not use it. */ 1041 emit_insn (gen_nonlocal_goto (value, lab, stack, fp)); 1042 else 1043#endif 1044 { 1045 lab = copy_to_reg (lab); 1046 1047 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); 1048 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); 1049 1050 emit_move_insn (hard_frame_pointer_rtx, fp); 1051 emit_stack_restore (SAVE_NONLOCAL, stack); 1052 1053 emit_use (hard_frame_pointer_rtx); 1054 emit_use (stack_pointer_rtx); 1055 emit_indirect_jump (lab); 1056 } 1057 } 1058 1059 /* Search backwards and mark the jump insn as a non-local goto. 1060 Note that this precludes the use of __builtin_longjmp to a 1061 __builtin_setjmp target in the same function. However, we've 1062 already cautioned the user that these functions are for 1063 internal exception handling use only. */ 1064 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) 1065 { 1066 gcc_assert (insn != last); 1067 1068 if (JUMP_P (insn)) 1069 { 1070 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx); 1071 break; 1072 } 1073 else if (CALL_P (insn)) 1074 break; 1075 } 1076} 1077 1078static inline bool 1079more_const_call_expr_args_p (const const_call_expr_arg_iterator *iter) 1080{ 1081 return (iter->i < iter->n); 1082} 1083 1084/* This function validates the types of a function call argument list 1085 against a specified list of tree_codes. If the last specifier is a 0, 1086 that represents an ellipses, otherwise the last specifier must be a 1087 VOID_TYPE. */ 1088 1089static bool 1090validate_arglist (const_tree callexpr, ...) 1091{ 1092 enum tree_code code; 1093 bool res = 0; 1094 va_list ap; 1095 const_call_expr_arg_iterator iter; 1096 const_tree arg; 1097 1098 va_start (ap, callexpr); 1099 init_const_call_expr_arg_iterator (callexpr, &iter); 1100 1101 do 1102 { 1103 code = (enum tree_code) va_arg (ap, int); 1104 switch (code) 1105 { 1106 case 0: 1107 /* This signifies an ellipses, any further arguments are all ok. */ 1108 res = true; 1109 goto end; 1110 case VOID_TYPE: 1111 /* This signifies an endlink, if no arguments remain, return 1112 true, otherwise return false. */ 1113 res = !more_const_call_expr_args_p (&iter); 1114 goto end; 1115 default: 1116 /* If no parameters remain or the parameter's code does not 1117 match the specified code, return false. Otherwise continue 1118 checking any remaining arguments. */ 1119 arg = next_const_call_expr_arg (&iter); 1120 if (!validate_arg (arg, code)) 1121 goto end; 1122 break; 1123 } 1124 } 1125 while (1); 1126 1127 /* We need gotos here since we can only have one VA_CLOSE in a 1128 function. */ 1129 end: ; 1130 va_end (ap); 1131 1132 return res; 1133} 1134 1135/* Expand a call to __builtin_nonlocal_goto. We're passed the target label 1136 and the address of the save area. */ 1137 1138static rtx 1139expand_builtin_nonlocal_goto (tree exp) 1140{ 1141 tree t_label, t_save_area; 1142 rtx r_label, r_save_area, r_fp, r_sp; 1143 rtx_insn *insn; 1144 1145 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 1146 return NULL_RTX; 1147 1148 t_label = CALL_EXPR_ARG (exp, 0); 1149 t_save_area = CALL_EXPR_ARG (exp, 1); 1150 1151 r_label = expand_normal (t_label); 1152 r_label = convert_memory_address (Pmode, r_label); 1153 r_save_area = expand_normal (t_save_area); 1154 r_save_area = convert_memory_address (Pmode, r_save_area); 1155 /* Copy the address of the save location to a register just in case it was 1156 based on the frame pointer. */ 1157 r_save_area = copy_to_reg (r_save_area); 1158 r_fp = gen_rtx_MEM (Pmode, r_save_area); 1159 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL), 1160 plus_constant (Pmode, r_save_area, 1161 GET_MODE_SIZE (Pmode))); 1162 1163 crtl->has_nonlocal_goto = 1; 1164 1165#ifdef HAVE_nonlocal_goto 1166 /* ??? We no longer need to pass the static chain value, afaik. */ 1167 if (HAVE_nonlocal_goto) 1168 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp)); 1169 else 1170#endif 1171 { 1172 r_label = copy_to_reg (r_label); 1173 1174 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); 1175 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); 1176 1177 /* Restore frame pointer for containing function. */ 1178 emit_move_insn (hard_frame_pointer_rtx, r_fp); 1179 emit_stack_restore (SAVE_NONLOCAL, r_sp); 1180 1181 /* USE of hard_frame_pointer_rtx added for consistency; 1182 not clear if really needed. */ 1183 emit_use (hard_frame_pointer_rtx); 1184 emit_use (stack_pointer_rtx); 1185 1186 /* If the architecture is using a GP register, we must 1187 conservatively assume that the target function makes use of it. 1188 The prologue of functions with nonlocal gotos must therefore 1189 initialize the GP register to the appropriate value, and we 1190 must then make sure that this value is live at the point 1191 of the jump. (Note that this doesn't necessarily apply 1192 to targets with a nonlocal_goto pattern; they are free 1193 to implement it in their own way. Note also that this is 1194 a no-op if the GP register is a global invariant.) */ 1195 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM 1196 && fixed_regs[PIC_OFFSET_TABLE_REGNUM]) 1197 emit_use (pic_offset_table_rtx); 1198 1199 emit_indirect_jump (r_label); 1200 } 1201 1202 /* Search backwards to the jump insn and mark it as a 1203 non-local goto. */ 1204 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) 1205 { 1206 if (JUMP_P (insn)) 1207 { 1208 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx); 1209 break; 1210 } 1211 else if (CALL_P (insn)) 1212 break; 1213 } 1214 1215 return const0_rtx; 1216} 1217 1218/* __builtin_update_setjmp_buf is passed a pointer to an array of five words 1219 (not all will be used on all machines) that was passed to __builtin_setjmp. 1220 It updates the stack pointer in that block to correspond to the current 1221 stack pointer. */ 1222 1223static void 1224expand_builtin_update_setjmp_buf (rtx buf_addr) 1225{ 1226 machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 1227 rtx stack_save 1228 = gen_rtx_MEM (sa_mode, 1229 memory_address 1230 (sa_mode, 1231 plus_constant (Pmode, buf_addr, 1232 2 * GET_MODE_SIZE (Pmode)))); 1233 1234 emit_stack_save (SAVE_NONLOCAL, &stack_save); 1235} 1236 1237/* Expand a call to __builtin_prefetch. For a target that does not support 1238 data prefetch, evaluate the memory address argument in case it has side 1239 effects. */ 1240 1241static void 1242expand_builtin_prefetch (tree exp) 1243{ 1244 tree arg0, arg1, arg2; 1245 int nargs; 1246 rtx op0, op1, op2; 1247 1248 if (!validate_arglist (exp, POINTER_TYPE, 0)) 1249 return; 1250 1251 arg0 = CALL_EXPR_ARG (exp, 0); 1252 1253 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to 1254 zero (read) and argument 2 (locality) defaults to 3 (high degree of 1255 locality). */ 1256 nargs = call_expr_nargs (exp); 1257 if (nargs > 1) 1258 arg1 = CALL_EXPR_ARG (exp, 1); 1259 else 1260 arg1 = integer_zero_node; 1261 if (nargs > 2) 1262 arg2 = CALL_EXPR_ARG (exp, 2); 1263 else 1264 arg2 = integer_three_node; 1265 1266 /* Argument 0 is an address. */ 1267 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL); 1268 1269 /* Argument 1 (read/write flag) must be a compile-time constant int. */ 1270 if (TREE_CODE (arg1) != INTEGER_CST) 1271 { 1272 error ("second argument to %<__builtin_prefetch%> must be a constant"); 1273 arg1 = integer_zero_node; 1274 } 1275 op1 = expand_normal (arg1); 1276 /* Argument 1 must be either zero or one. */ 1277 if (INTVAL (op1) != 0 && INTVAL (op1) != 1) 1278 { 1279 warning (0, "invalid second argument to %<__builtin_prefetch%>;" 1280 " using zero"); 1281 op1 = const0_rtx; 1282 } 1283 1284 /* Argument 2 (locality) must be a compile-time constant int. */ 1285 if (TREE_CODE (arg2) != INTEGER_CST) 1286 { 1287 error ("third argument to %<__builtin_prefetch%> must be a constant"); 1288 arg2 = integer_zero_node; 1289 } 1290 op2 = expand_normal (arg2); 1291 /* Argument 2 must be 0, 1, 2, or 3. */ 1292 if (INTVAL (op2) < 0 || INTVAL (op2) > 3) 1293 { 1294 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero"); 1295 op2 = const0_rtx; 1296 } 1297 1298#ifdef HAVE_prefetch 1299 if (HAVE_prefetch) 1300 { 1301 struct expand_operand ops[3]; 1302 1303 create_address_operand (&ops[0], op0); 1304 create_integer_operand (&ops[1], INTVAL (op1)); 1305 create_integer_operand (&ops[2], INTVAL (op2)); 1306 if (maybe_expand_insn (CODE_FOR_prefetch, 3, ops)) 1307 return; 1308 } 1309#endif 1310 1311 /* Don't do anything with direct references to volatile memory, but 1312 generate code to handle other side effects. */ 1313 if (!MEM_P (op0) && side_effects_p (op0)) 1314 emit_insn (op0); 1315} 1316 1317/* Get a MEM rtx for expression EXP which is the address of an operand 1318 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is 1319 the maximum length of the block of memory that might be accessed or 1320 NULL if unknown. */ 1321 1322static rtx 1323get_memory_rtx (tree exp, tree len) 1324{ 1325 tree orig_exp = exp; 1326 rtx addr, mem; 1327 1328 /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived 1329 from its expression, for expr->a.b only <variable>.a.b is recorded. */ 1330 if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp)) 1331 exp = TREE_OPERAND (exp, 0); 1332 1333 addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL); 1334 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr)); 1335 1336 /* Get an expression we can use to find the attributes to assign to MEM. 1337 First remove any nops. */ 1338 while (CONVERT_EXPR_P (exp) 1339 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0)))) 1340 exp = TREE_OPERAND (exp, 0); 1341 1342 /* Build a MEM_REF representing the whole accessed area as a byte blob, 1343 (as builtin stringops may alias with anything). */ 1344 exp = fold_build2 (MEM_REF, 1345 build_array_type (char_type_node, 1346 build_range_type (sizetype, 1347 size_one_node, len)), 1348 exp, build_int_cst (ptr_type_node, 0)); 1349 1350 /* If the MEM_REF has no acceptable address, try to get the base object 1351 from the original address we got, and build an all-aliasing 1352 unknown-sized access to that one. */ 1353 if (is_gimple_mem_ref_addr (TREE_OPERAND (exp, 0))) 1354 set_mem_attributes (mem, exp, 0); 1355 else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR 1356 && (exp = get_base_address (TREE_OPERAND (TREE_OPERAND (exp, 0), 1357 0)))) 1358 { 1359 exp = build_fold_addr_expr (exp); 1360 exp = fold_build2 (MEM_REF, 1361 build_array_type (char_type_node, 1362 build_range_type (sizetype, 1363 size_zero_node, 1364 NULL)), 1365 exp, build_int_cst (ptr_type_node, 0)); 1366 set_mem_attributes (mem, exp, 0); 1367 } 1368 set_mem_alias_set (mem, 0); 1369 return mem; 1370} 1371 1372/* Built-in functions to perform an untyped call and return. */ 1373 1374#define apply_args_mode \ 1375 (this_target_builtins->x_apply_args_mode) 1376#define apply_result_mode \ 1377 (this_target_builtins->x_apply_result_mode) 1378 1379/* Return the size required for the block returned by __builtin_apply_args, 1380 and initialize apply_args_mode. */ 1381 1382static int 1383apply_args_size (void) 1384{ 1385 static int size = -1; 1386 int align; 1387 unsigned int regno; 1388 machine_mode mode; 1389 1390 /* The values computed by this function never change. */ 1391 if (size < 0) 1392 { 1393 /* The first value is the incoming arg-pointer. */ 1394 size = GET_MODE_SIZE (Pmode); 1395 1396 /* The second value is the structure value address unless this is 1397 passed as an "invisible" first argument. */ 1398 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0)) 1399 size += GET_MODE_SIZE (Pmode); 1400 1401 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1402 if (FUNCTION_ARG_REGNO_P (regno)) 1403 { 1404 mode = targetm.calls.get_raw_arg_mode (regno); 1405 1406 gcc_assert (mode != VOIDmode); 1407 1408 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1409 if (size % align != 0) 1410 size = CEIL (size, align) * align; 1411 size += GET_MODE_SIZE (mode); 1412 apply_args_mode[regno] = mode; 1413 } 1414 else 1415 { 1416 apply_args_mode[regno] = VOIDmode; 1417 } 1418 } 1419 return size; 1420} 1421 1422/* Return the size required for the block returned by __builtin_apply, 1423 and initialize apply_result_mode. */ 1424 1425static int 1426apply_result_size (void) 1427{ 1428 static int size = -1; 1429 int align, regno; 1430 machine_mode mode; 1431 1432 /* The values computed by this function never change. */ 1433 if (size < 0) 1434 { 1435 size = 0; 1436 1437 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1438 if (targetm.calls.function_value_regno_p (regno)) 1439 { 1440 mode = targetm.calls.get_raw_result_mode (regno); 1441 1442 gcc_assert (mode != VOIDmode); 1443 1444 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1445 if (size % align != 0) 1446 size = CEIL (size, align) * align; 1447 size += GET_MODE_SIZE (mode); 1448 apply_result_mode[regno] = mode; 1449 } 1450 else 1451 apply_result_mode[regno] = VOIDmode; 1452 1453 /* Allow targets that use untyped_call and untyped_return to override 1454 the size so that machine-specific information can be stored here. */ 1455#ifdef APPLY_RESULT_SIZE 1456 size = APPLY_RESULT_SIZE; 1457#endif 1458 } 1459 return size; 1460} 1461 1462#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return) 1463/* Create a vector describing the result block RESULT. If SAVEP is true, 1464 the result block is used to save the values; otherwise it is used to 1465 restore the values. */ 1466 1467static rtx 1468result_vector (int savep, rtx result) 1469{ 1470 int regno, size, align, nelts; 1471 machine_mode mode; 1472 rtx reg, mem; 1473 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER); 1474 1475 size = nelts = 0; 1476 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1477 if ((mode = apply_result_mode[regno]) != VOIDmode) 1478 { 1479 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1480 if (size % align != 0) 1481 size = CEIL (size, align) * align; 1482 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno)); 1483 mem = adjust_address (result, mode, size); 1484 savevec[nelts++] = (savep 1485 ? gen_rtx_SET (VOIDmode, mem, reg) 1486 : gen_rtx_SET (VOIDmode, reg, mem)); 1487 size += GET_MODE_SIZE (mode); 1488 } 1489 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec)); 1490} 1491#endif /* HAVE_untyped_call or HAVE_untyped_return */ 1492 1493/* Save the state required to perform an untyped call with the same 1494 arguments as were passed to the current function. */ 1495 1496static rtx 1497expand_builtin_apply_args_1 (void) 1498{ 1499 rtx registers, tem; 1500 int size, align, regno; 1501 machine_mode mode; 1502 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1); 1503 1504 /* Create a block where the arg-pointer, structure value address, 1505 and argument registers can be saved. */ 1506 registers = assign_stack_local (BLKmode, apply_args_size (), -1); 1507 1508 /* Walk past the arg-pointer and structure value address. */ 1509 size = GET_MODE_SIZE (Pmode); 1510 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0)) 1511 size += GET_MODE_SIZE (Pmode); 1512 1513 /* Save each register used in calling a function to the block. */ 1514 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1515 if ((mode = apply_args_mode[regno]) != VOIDmode) 1516 { 1517 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1518 if (size % align != 0) 1519 size = CEIL (size, align) * align; 1520 1521 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno)); 1522 1523 emit_move_insn (adjust_address (registers, mode, size), tem); 1524 size += GET_MODE_SIZE (mode); 1525 } 1526 1527 /* Save the arg pointer to the block. */ 1528 tem = copy_to_reg (crtl->args.internal_arg_pointer); 1529#ifdef STACK_GROWS_DOWNWARD 1530 /* We need the pointer as the caller actually passed them to us, not 1531 as we might have pretended they were passed. Make sure it's a valid 1532 operand, as emit_move_insn isn't expected to handle a PLUS. */ 1533 tem 1534 = force_operand (plus_constant (Pmode, tem, crtl->args.pretend_args_size), 1535 NULL_RTX); 1536#endif 1537 emit_move_insn (adjust_address (registers, Pmode, 0), tem); 1538 1539 size = GET_MODE_SIZE (Pmode); 1540 1541 /* Save the structure value address unless this is passed as an 1542 "invisible" first argument. */ 1543 if (struct_incoming_value) 1544 { 1545 emit_move_insn (adjust_address (registers, Pmode, size), 1546 copy_to_reg (struct_incoming_value)); 1547 size += GET_MODE_SIZE (Pmode); 1548 } 1549 1550 /* Return the address of the block. */ 1551 return copy_addr_to_reg (XEXP (registers, 0)); 1552} 1553 1554/* __builtin_apply_args returns block of memory allocated on 1555 the stack into which is stored the arg pointer, structure 1556 value address, static chain, and all the registers that might 1557 possibly be used in performing a function call. The code is 1558 moved to the start of the function so the incoming values are 1559 saved. */ 1560 1561static rtx 1562expand_builtin_apply_args (void) 1563{ 1564 /* Don't do __builtin_apply_args more than once in a function. 1565 Save the result of the first call and reuse it. */ 1566 if (apply_args_value != 0) 1567 return apply_args_value; 1568 { 1569 /* When this function is called, it means that registers must be 1570 saved on entry to this function. So we migrate the 1571 call to the first insn of this function. */ 1572 rtx temp; 1573 rtx seq; 1574 1575 start_sequence (); 1576 temp = expand_builtin_apply_args_1 (); 1577 seq = get_insns (); 1578 end_sequence (); 1579 1580 apply_args_value = temp; 1581 1582 /* Put the insns after the NOTE that starts the function. 1583 If this is inside a start_sequence, make the outer-level insn 1584 chain current, so the code is placed at the start of the 1585 function. If internal_arg_pointer is a non-virtual pseudo, 1586 it needs to be placed after the function that initializes 1587 that pseudo. */ 1588 push_topmost_sequence (); 1589 if (REG_P (crtl->args.internal_arg_pointer) 1590 && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER) 1591 emit_insn_before (seq, parm_birth_insn); 1592 else 1593 emit_insn_before (seq, NEXT_INSN (entry_of_function ())); 1594 pop_topmost_sequence (); 1595 return temp; 1596 } 1597} 1598 1599/* Perform an untyped call and save the state required to perform an 1600 untyped return of whatever value was returned by the given function. */ 1601 1602static rtx 1603expand_builtin_apply (rtx function, rtx arguments, rtx argsize) 1604{ 1605 int size, align, regno; 1606 machine_mode mode; 1607 rtx incoming_args, result, reg, dest, src; 1608 rtx_call_insn *call_insn; 1609 rtx old_stack_level = 0; 1610 rtx call_fusage = 0; 1611 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0); 1612 1613 arguments = convert_memory_address (Pmode, arguments); 1614 1615 /* Create a block where the return registers can be saved. */ 1616 result = assign_stack_local (BLKmode, apply_result_size (), -1); 1617 1618 /* Fetch the arg pointer from the ARGUMENTS block. */ 1619 incoming_args = gen_reg_rtx (Pmode); 1620 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments)); 1621#ifndef STACK_GROWS_DOWNWARD 1622 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize, 1623 incoming_args, 0, OPTAB_LIB_WIDEN); 1624#endif 1625 1626 /* Push a new argument block and copy the arguments. Do not allow 1627 the (potential) memcpy call below to interfere with our stack 1628 manipulations. */ 1629 do_pending_stack_adjust (); 1630 NO_DEFER_POP; 1631 1632 /* Save the stack with nonlocal if available. */ 1633#ifdef HAVE_save_stack_nonlocal 1634 if (HAVE_save_stack_nonlocal) 1635 emit_stack_save (SAVE_NONLOCAL, &old_stack_level); 1636 else 1637#endif 1638 emit_stack_save (SAVE_BLOCK, &old_stack_level); 1639 1640 /* Allocate a block of memory onto the stack and copy the memory 1641 arguments to the outgoing arguments address. We can pass TRUE 1642 as the 4th argument because we just saved the stack pointer 1643 and will restore it right after the call. */ 1644 allocate_dynamic_stack_space (argsize, 0, BIGGEST_ALIGNMENT, true); 1645 1646 /* Set DRAP flag to true, even though allocate_dynamic_stack_space 1647 may have already set current_function_calls_alloca to true. 1648 current_function_calls_alloca won't be set if argsize is zero, 1649 so we have to guarantee need_drap is true here. */ 1650 if (SUPPORTS_STACK_ALIGNMENT) 1651 crtl->need_drap = true; 1652 1653 dest = virtual_outgoing_args_rtx; 1654#ifndef STACK_GROWS_DOWNWARD 1655 if (CONST_INT_P (argsize)) 1656 dest = plus_constant (Pmode, dest, -INTVAL (argsize)); 1657 else 1658 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize)); 1659#endif 1660 dest = gen_rtx_MEM (BLKmode, dest); 1661 set_mem_align (dest, PARM_BOUNDARY); 1662 src = gen_rtx_MEM (BLKmode, incoming_args); 1663 set_mem_align (src, PARM_BOUNDARY); 1664 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL); 1665 1666 /* Refer to the argument block. */ 1667 apply_args_size (); 1668 arguments = gen_rtx_MEM (BLKmode, arguments); 1669 set_mem_align (arguments, PARM_BOUNDARY); 1670 1671 /* Walk past the arg-pointer and structure value address. */ 1672 size = GET_MODE_SIZE (Pmode); 1673 if (struct_value) 1674 size += GET_MODE_SIZE (Pmode); 1675 1676 /* Restore each of the registers previously saved. Make USE insns 1677 for each of these registers for use in making the call. */ 1678 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1679 if ((mode = apply_args_mode[regno]) != VOIDmode) 1680 { 1681 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1682 if (size % align != 0) 1683 size = CEIL (size, align) * align; 1684 reg = gen_rtx_REG (mode, regno); 1685 emit_move_insn (reg, adjust_address (arguments, mode, size)); 1686 use_reg (&call_fusage, reg); 1687 size += GET_MODE_SIZE (mode); 1688 } 1689 1690 /* Restore the structure value address unless this is passed as an 1691 "invisible" first argument. */ 1692 size = GET_MODE_SIZE (Pmode); 1693 if (struct_value) 1694 { 1695 rtx value = gen_reg_rtx (Pmode); 1696 emit_move_insn (value, adjust_address (arguments, Pmode, size)); 1697 emit_move_insn (struct_value, value); 1698 if (REG_P (struct_value)) 1699 use_reg (&call_fusage, struct_value); 1700 size += GET_MODE_SIZE (Pmode); 1701 } 1702 1703 /* All arguments and registers used for the call are set up by now! */ 1704 function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0); 1705 1706 /* Ensure address is valid. SYMBOL_REF is already valid, so no need, 1707 and we don't want to load it into a register as an optimization, 1708 because prepare_call_address already did it if it should be done. */ 1709 if (GET_CODE (function) != SYMBOL_REF) 1710 function = memory_address (FUNCTION_MODE, function); 1711 1712 /* Generate the actual call instruction and save the return value. */ 1713#ifdef HAVE_untyped_call 1714 if (HAVE_untyped_call) 1715 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function), 1716 result, result_vector (1, result))); 1717 else 1718#endif 1719#ifdef HAVE_call_value 1720 if (HAVE_call_value) 1721 { 1722 rtx valreg = 0; 1723 1724 /* Locate the unique return register. It is not possible to 1725 express a call that sets more than one return register using 1726 call_value; use untyped_call for that. In fact, untyped_call 1727 only needs to save the return registers in the given block. */ 1728 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1729 if ((mode = apply_result_mode[regno]) != VOIDmode) 1730 { 1731 gcc_assert (!valreg); /* HAVE_untyped_call required. */ 1732 1733 valreg = gen_rtx_REG (mode, regno); 1734 } 1735 1736 emit_call_insn (GEN_CALL_VALUE (valreg, 1737 gen_rtx_MEM (FUNCTION_MODE, function), 1738 const0_rtx, NULL_RTX, const0_rtx)); 1739 1740 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg); 1741 } 1742 else 1743#endif 1744 gcc_unreachable (); 1745 1746 /* Find the CALL insn we just emitted, and attach the register usage 1747 information. */ 1748 call_insn = last_call_insn (); 1749 add_function_usage_to (call_insn, call_fusage); 1750 1751 /* Restore the stack. */ 1752#ifdef HAVE_save_stack_nonlocal 1753 if (HAVE_save_stack_nonlocal) 1754 emit_stack_restore (SAVE_NONLOCAL, old_stack_level); 1755 else 1756#endif 1757 emit_stack_restore (SAVE_BLOCK, old_stack_level); 1758 fixup_args_size_notes (call_insn, get_last_insn (), 0); 1759 1760 OK_DEFER_POP; 1761 1762 /* Return the address of the result block. */ 1763 result = copy_addr_to_reg (XEXP (result, 0)); 1764 return convert_memory_address (ptr_mode, result); 1765} 1766 1767/* Perform an untyped return. */ 1768 1769static void 1770expand_builtin_return (rtx result) 1771{ 1772 int size, align, regno; 1773 machine_mode mode; 1774 rtx reg; 1775 rtx_insn *call_fusage = 0; 1776 1777 result = convert_memory_address (Pmode, result); 1778 1779 apply_result_size (); 1780 result = gen_rtx_MEM (BLKmode, result); 1781 1782#ifdef HAVE_untyped_return 1783 if (HAVE_untyped_return) 1784 { 1785 emit_jump_insn (gen_untyped_return (result, result_vector (0, result))); 1786 emit_barrier (); 1787 return; 1788 } 1789#endif 1790 1791 /* Restore the return value and note that each value is used. */ 1792 size = 0; 1793 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1794 if ((mode = apply_result_mode[regno]) != VOIDmode) 1795 { 1796 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1797 if (size % align != 0) 1798 size = CEIL (size, align) * align; 1799 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno)); 1800 emit_move_insn (reg, adjust_address (result, mode, size)); 1801 1802 push_to_sequence (call_fusage); 1803 emit_use (reg); 1804 call_fusage = get_insns (); 1805 end_sequence (); 1806 size += GET_MODE_SIZE (mode); 1807 } 1808 1809 /* Put the USE insns before the return. */ 1810 emit_insn (call_fusage); 1811 1812 /* Return whatever values was restored by jumping directly to the end 1813 of the function. */ 1814 expand_naked_return (); 1815} 1816 1817/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */ 1818 1819static enum type_class 1820type_to_class (tree type) 1821{ 1822 switch (TREE_CODE (type)) 1823 { 1824 case VOID_TYPE: return void_type_class; 1825 case INTEGER_TYPE: return integer_type_class; 1826 case ENUMERAL_TYPE: return enumeral_type_class; 1827 case BOOLEAN_TYPE: return boolean_type_class; 1828 case POINTER_TYPE: return pointer_type_class; 1829 case REFERENCE_TYPE: return reference_type_class; 1830 case OFFSET_TYPE: return offset_type_class; 1831 case REAL_TYPE: return real_type_class; 1832 case COMPLEX_TYPE: return complex_type_class; 1833 case FUNCTION_TYPE: return function_type_class; 1834 case METHOD_TYPE: return method_type_class; 1835 case RECORD_TYPE: return record_type_class; 1836 case UNION_TYPE: 1837 case QUAL_UNION_TYPE: return union_type_class; 1838 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type) 1839 ? string_type_class : array_type_class); 1840 case LANG_TYPE: return lang_type_class; 1841 default: return no_type_class; 1842 } 1843} 1844 1845/* Expand a call EXP to __builtin_classify_type. */ 1846 1847static rtx 1848expand_builtin_classify_type (tree exp) 1849{ 1850 if (call_expr_nargs (exp)) 1851 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0)))); 1852 return GEN_INT (no_type_class); 1853} 1854 1855/* This helper macro, meant to be used in mathfn_built_in below, 1856 determines which among a set of three builtin math functions is 1857 appropriate for a given type mode. The `F' and `L' cases are 1858 automatically generated from the `double' case. */ 1859#define CASE_MATHFN(BUILT_IN_MATHFN) \ 1860 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \ 1861 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \ 1862 fcodel = BUILT_IN_MATHFN##L ; break; 1863/* Similar to above, but appends _R after any F/L suffix. */ 1864#define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \ 1865 case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \ 1866 fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \ 1867 fcodel = BUILT_IN_MATHFN##L_R ; break; 1868 1869/* Return mathematic function equivalent to FN but operating directly on TYPE, 1870 if available. If IMPLICIT is true use the implicit builtin declaration, 1871 otherwise use the explicit declaration. If we can't do the conversion, 1872 return zero. */ 1873 1874static tree 1875mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit_p) 1876{ 1877 enum built_in_function fcode, fcodef, fcodel, fcode2; 1878 1879 switch (fn) 1880 { 1881 CASE_MATHFN (BUILT_IN_ACOS) 1882 CASE_MATHFN (BUILT_IN_ACOSH) 1883 CASE_MATHFN (BUILT_IN_ASIN) 1884 CASE_MATHFN (BUILT_IN_ASINH) 1885 CASE_MATHFN (BUILT_IN_ATAN) 1886 CASE_MATHFN (BUILT_IN_ATAN2) 1887 CASE_MATHFN (BUILT_IN_ATANH) 1888 CASE_MATHFN (BUILT_IN_CBRT) 1889 CASE_MATHFN (BUILT_IN_CEIL) 1890 CASE_MATHFN (BUILT_IN_CEXPI) 1891 CASE_MATHFN (BUILT_IN_COPYSIGN) 1892 CASE_MATHFN (BUILT_IN_COS) 1893 CASE_MATHFN (BUILT_IN_COSH) 1894 CASE_MATHFN (BUILT_IN_DREM) 1895 CASE_MATHFN (BUILT_IN_ERF) 1896 CASE_MATHFN (BUILT_IN_ERFC) 1897 CASE_MATHFN (BUILT_IN_EXP) 1898 CASE_MATHFN (BUILT_IN_EXP10) 1899 CASE_MATHFN (BUILT_IN_EXP2) 1900 CASE_MATHFN (BUILT_IN_EXPM1) 1901 CASE_MATHFN (BUILT_IN_FABS) 1902 CASE_MATHFN (BUILT_IN_FDIM) 1903 CASE_MATHFN (BUILT_IN_FLOOR) 1904 CASE_MATHFN (BUILT_IN_FMA) 1905 CASE_MATHFN (BUILT_IN_FMAX) 1906 CASE_MATHFN (BUILT_IN_FMIN) 1907 CASE_MATHFN (BUILT_IN_FMOD) 1908 CASE_MATHFN (BUILT_IN_FREXP) 1909 CASE_MATHFN (BUILT_IN_GAMMA) 1910 CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */ 1911 CASE_MATHFN (BUILT_IN_HUGE_VAL) 1912 CASE_MATHFN (BUILT_IN_HYPOT) 1913 CASE_MATHFN (BUILT_IN_ILOGB) 1914 CASE_MATHFN (BUILT_IN_ICEIL) 1915 CASE_MATHFN (BUILT_IN_IFLOOR) 1916 CASE_MATHFN (BUILT_IN_INF) 1917 CASE_MATHFN (BUILT_IN_IRINT) 1918 CASE_MATHFN (BUILT_IN_IROUND) 1919 CASE_MATHFN (BUILT_IN_ISINF) 1920 CASE_MATHFN (BUILT_IN_J0) 1921 CASE_MATHFN (BUILT_IN_J1) 1922 CASE_MATHFN (BUILT_IN_JN) 1923 CASE_MATHFN (BUILT_IN_LCEIL) 1924 CASE_MATHFN (BUILT_IN_LDEXP) 1925 CASE_MATHFN (BUILT_IN_LFLOOR) 1926 CASE_MATHFN (BUILT_IN_LGAMMA) 1927 CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */ 1928 CASE_MATHFN (BUILT_IN_LLCEIL) 1929 CASE_MATHFN (BUILT_IN_LLFLOOR) 1930 CASE_MATHFN (BUILT_IN_LLRINT) 1931 CASE_MATHFN (BUILT_IN_LLROUND) 1932 CASE_MATHFN (BUILT_IN_LOG) 1933 CASE_MATHFN (BUILT_IN_LOG10) 1934 CASE_MATHFN (BUILT_IN_LOG1P) 1935 CASE_MATHFN (BUILT_IN_LOG2) 1936 CASE_MATHFN (BUILT_IN_LOGB) 1937 CASE_MATHFN (BUILT_IN_LRINT) 1938 CASE_MATHFN (BUILT_IN_LROUND) 1939 CASE_MATHFN (BUILT_IN_MODF) 1940 CASE_MATHFN (BUILT_IN_NAN) 1941 CASE_MATHFN (BUILT_IN_NANS) 1942 CASE_MATHFN (BUILT_IN_NEARBYINT) 1943 CASE_MATHFN (BUILT_IN_NEXTAFTER) 1944 CASE_MATHFN (BUILT_IN_NEXTTOWARD) 1945 CASE_MATHFN (BUILT_IN_POW) 1946 CASE_MATHFN (BUILT_IN_POWI) 1947 CASE_MATHFN (BUILT_IN_POW10) 1948 CASE_MATHFN (BUILT_IN_REMAINDER) 1949 CASE_MATHFN (BUILT_IN_REMQUO) 1950 CASE_MATHFN (BUILT_IN_RINT) 1951 CASE_MATHFN (BUILT_IN_ROUND) 1952 CASE_MATHFN (BUILT_IN_SCALB) 1953 CASE_MATHFN (BUILT_IN_SCALBLN) 1954 CASE_MATHFN (BUILT_IN_SCALBN) 1955 CASE_MATHFN (BUILT_IN_SIGNBIT) 1956 CASE_MATHFN (BUILT_IN_SIGNIFICAND) 1957 CASE_MATHFN (BUILT_IN_SIN) 1958 CASE_MATHFN (BUILT_IN_SINCOS) 1959 CASE_MATHFN (BUILT_IN_SINH) 1960 CASE_MATHFN (BUILT_IN_SQRT) 1961 CASE_MATHFN (BUILT_IN_TAN) 1962 CASE_MATHFN (BUILT_IN_TANH) 1963 CASE_MATHFN (BUILT_IN_TGAMMA) 1964 CASE_MATHFN (BUILT_IN_TRUNC) 1965 CASE_MATHFN (BUILT_IN_Y0) 1966 CASE_MATHFN (BUILT_IN_Y1) 1967 CASE_MATHFN (BUILT_IN_YN) 1968 1969 default: 1970 return NULL_TREE; 1971 } 1972 1973 if (TYPE_MAIN_VARIANT (type) == double_type_node) 1974 fcode2 = fcode; 1975 else if (TYPE_MAIN_VARIANT (type) == float_type_node) 1976 fcode2 = fcodef; 1977 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node) 1978 fcode2 = fcodel; 1979 else 1980 return NULL_TREE; 1981 1982 if (implicit_p && !builtin_decl_implicit_p (fcode2)) 1983 return NULL_TREE; 1984 1985 return builtin_decl_explicit (fcode2); 1986} 1987 1988/* Like mathfn_built_in_1(), but always use the implicit array. */ 1989 1990tree 1991mathfn_built_in (tree type, enum built_in_function fn) 1992{ 1993 return mathfn_built_in_1 (type, fn, /*implicit=*/ 1); 1994} 1995 1996/* If errno must be maintained, expand the RTL to check if the result, 1997 TARGET, of a built-in function call, EXP, is NaN, and if so set 1998 errno to EDOM. */ 1999 2000static void 2001expand_errno_check (tree exp, rtx target) 2002{ 2003 rtx_code_label *lab = gen_label_rtx (); 2004 2005 /* Test the result; if it is NaN, set errno=EDOM because 2006 the argument was not in the domain. */ 2007 do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target), 2008 NULL_RTX, NULL_RTX, lab, 2009 /* The jump is very likely. */ 2010 REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1)); 2011 2012#ifdef TARGET_EDOM 2013 /* If this built-in doesn't throw an exception, set errno directly. */ 2014 if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0))) 2015 { 2016#ifdef GEN_ERRNO_RTX 2017 rtx errno_rtx = GEN_ERRNO_RTX; 2018#else 2019 rtx errno_rtx 2020 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno")); 2021#endif 2022 emit_move_insn (errno_rtx, 2023 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx))); 2024 emit_label (lab); 2025 return; 2026 } 2027#endif 2028 2029 /* Make sure the library call isn't expanded as a tail call. */ 2030 CALL_EXPR_TAILCALL (exp) = 0; 2031 2032 /* We can't set errno=EDOM directly; let the library call do it. 2033 Pop the arguments right away in case the call gets deleted. */ 2034 NO_DEFER_POP; 2035 expand_call (exp, target, 0); 2036 OK_DEFER_POP; 2037 emit_label (lab); 2038} 2039 2040/* Expand a call to one of the builtin math functions (sqrt, exp, or log). 2041 Return NULL_RTX if a normal call should be emitted rather than expanding 2042 the function in-line. EXP is the expression that is a call to the builtin 2043 function; if convenient, the result should be placed in TARGET. 2044 SUBTARGET may be used as the target for computing one of EXP's operands. */ 2045 2046static rtx 2047expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) 2048{ 2049 optab builtin_optab; 2050 rtx op0; 2051 rtx_insn *insns; 2052 tree fndecl = get_callee_fndecl (exp); 2053 machine_mode mode; 2054 bool errno_set = false; 2055 bool try_widening = false; 2056 tree arg; 2057 2058 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2059 return NULL_RTX; 2060 2061 arg = CALL_EXPR_ARG (exp, 0); 2062 2063 switch (DECL_FUNCTION_CODE (fndecl)) 2064 { 2065 CASE_FLT_FN (BUILT_IN_SQRT): 2066 errno_set = ! tree_expr_nonnegative_p (arg); 2067 try_widening = true; 2068 builtin_optab = sqrt_optab; 2069 break; 2070 CASE_FLT_FN (BUILT_IN_EXP): 2071 errno_set = true; builtin_optab = exp_optab; break; 2072 CASE_FLT_FN (BUILT_IN_EXP10): 2073 CASE_FLT_FN (BUILT_IN_POW10): 2074 errno_set = true; builtin_optab = exp10_optab; break; 2075 CASE_FLT_FN (BUILT_IN_EXP2): 2076 errno_set = true; builtin_optab = exp2_optab; break; 2077 CASE_FLT_FN (BUILT_IN_EXPM1): 2078 errno_set = true; builtin_optab = expm1_optab; break; 2079 CASE_FLT_FN (BUILT_IN_LOGB): 2080 errno_set = true; builtin_optab = logb_optab; break; 2081 CASE_FLT_FN (BUILT_IN_LOG): 2082 errno_set = true; builtin_optab = log_optab; break; 2083 CASE_FLT_FN (BUILT_IN_LOG10): 2084 errno_set = true; builtin_optab = log10_optab; break; 2085 CASE_FLT_FN (BUILT_IN_LOG2): 2086 errno_set = true; builtin_optab = log2_optab; break; 2087 CASE_FLT_FN (BUILT_IN_LOG1P): 2088 errno_set = true; builtin_optab = log1p_optab; break; 2089 CASE_FLT_FN (BUILT_IN_ASIN): 2090 builtin_optab = asin_optab; break; 2091 CASE_FLT_FN (BUILT_IN_ACOS): 2092 builtin_optab = acos_optab; break; 2093 CASE_FLT_FN (BUILT_IN_TAN): 2094 builtin_optab = tan_optab; break; 2095 CASE_FLT_FN (BUILT_IN_ATAN): 2096 builtin_optab = atan_optab; break; 2097 CASE_FLT_FN (BUILT_IN_FLOOR): 2098 builtin_optab = floor_optab; break; 2099 CASE_FLT_FN (BUILT_IN_CEIL): 2100 builtin_optab = ceil_optab; break; 2101 CASE_FLT_FN (BUILT_IN_TRUNC): 2102 builtin_optab = btrunc_optab; break; 2103 CASE_FLT_FN (BUILT_IN_ROUND): 2104 builtin_optab = round_optab; break; 2105 CASE_FLT_FN (BUILT_IN_NEARBYINT): 2106 builtin_optab = nearbyint_optab; 2107 if (flag_trapping_math) 2108 break; 2109 /* Else fallthrough and expand as rint. */ 2110 CASE_FLT_FN (BUILT_IN_RINT): 2111 builtin_optab = rint_optab; break; 2112 CASE_FLT_FN (BUILT_IN_SIGNIFICAND): 2113 builtin_optab = significand_optab; break; 2114 default: 2115 gcc_unreachable (); 2116 } 2117 2118 /* Make a suitable register to place result in. */ 2119 mode = TYPE_MODE (TREE_TYPE (exp)); 2120 2121 if (! flag_errno_math || ! HONOR_NANS (mode)) 2122 errno_set = false; 2123 2124 /* Before working hard, check whether the instruction is available, but try 2125 to widen the mode for specific operations. */ 2126 if ((optab_handler (builtin_optab, mode) != CODE_FOR_nothing 2127 || (try_widening && !excess_precision_type (TREE_TYPE (exp)))) 2128 && (!errno_set || !optimize_insn_for_size_p ())) 2129 { 2130 rtx result = gen_reg_rtx (mode); 2131 2132 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2133 need to expand the argument again. This way, we will not perform 2134 side-effects more the once. */ 2135 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 2136 2137 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 2138 2139 start_sequence (); 2140 2141 /* Compute into RESULT. 2142 Set RESULT to wherever the result comes back. */ 2143 result = expand_unop (mode, builtin_optab, op0, result, 0); 2144 2145 if (result != 0) 2146 { 2147 if (errno_set) 2148 expand_errno_check (exp, result); 2149 2150 /* Output the entire sequence. */ 2151 insns = get_insns (); 2152 end_sequence (); 2153 emit_insn (insns); 2154 return result; 2155 } 2156 2157 /* If we were unable to expand via the builtin, stop the sequence 2158 (without outputting the insns) and call to the library function 2159 with the stabilized argument list. */ 2160 end_sequence (); 2161 } 2162 2163 return expand_call (exp, target, target == const0_rtx); 2164} 2165 2166/* Expand a call to the builtin binary math functions (pow and atan2). 2167 Return NULL_RTX if a normal call should be emitted rather than expanding the 2168 function in-line. EXP is the expression that is a call to the builtin 2169 function; if convenient, the result should be placed in TARGET. 2170 SUBTARGET may be used as the target for computing one of EXP's 2171 operands. */ 2172 2173static rtx 2174expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget) 2175{ 2176 optab builtin_optab; 2177 rtx op0, op1, result; 2178 rtx_insn *insns; 2179 int op1_type = REAL_TYPE; 2180 tree fndecl = get_callee_fndecl (exp); 2181 tree arg0, arg1; 2182 machine_mode mode; 2183 bool errno_set = true; 2184 2185 switch (DECL_FUNCTION_CODE (fndecl)) 2186 { 2187 CASE_FLT_FN (BUILT_IN_SCALBN): 2188 CASE_FLT_FN (BUILT_IN_SCALBLN): 2189 CASE_FLT_FN (BUILT_IN_LDEXP): 2190 op1_type = INTEGER_TYPE; 2191 default: 2192 break; 2193 } 2194 2195 if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE)) 2196 return NULL_RTX; 2197 2198 arg0 = CALL_EXPR_ARG (exp, 0); 2199 arg1 = CALL_EXPR_ARG (exp, 1); 2200 2201 switch (DECL_FUNCTION_CODE (fndecl)) 2202 { 2203 CASE_FLT_FN (BUILT_IN_POW): 2204 builtin_optab = pow_optab; break; 2205 CASE_FLT_FN (BUILT_IN_ATAN2): 2206 builtin_optab = atan2_optab; break; 2207 CASE_FLT_FN (BUILT_IN_SCALB): 2208 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2) 2209 return 0; 2210 builtin_optab = scalb_optab; break; 2211 CASE_FLT_FN (BUILT_IN_SCALBN): 2212 CASE_FLT_FN (BUILT_IN_SCALBLN): 2213 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2) 2214 return 0; 2215 /* Fall through... */ 2216 CASE_FLT_FN (BUILT_IN_LDEXP): 2217 builtin_optab = ldexp_optab; break; 2218 CASE_FLT_FN (BUILT_IN_FMOD): 2219 builtin_optab = fmod_optab; break; 2220 CASE_FLT_FN (BUILT_IN_REMAINDER): 2221 CASE_FLT_FN (BUILT_IN_DREM): 2222 builtin_optab = remainder_optab; break; 2223 default: 2224 gcc_unreachable (); 2225 } 2226 2227 /* Make a suitable register to place result in. */ 2228 mode = TYPE_MODE (TREE_TYPE (exp)); 2229 2230 /* Before working hard, check whether the instruction is available. */ 2231 if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing) 2232 return NULL_RTX; 2233 2234 result = gen_reg_rtx (mode); 2235 2236 if (! flag_errno_math || ! HONOR_NANS (mode)) 2237 errno_set = false; 2238 2239 if (errno_set && optimize_insn_for_size_p ()) 2240 return 0; 2241 2242 /* Always stabilize the argument list. */ 2243 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0); 2244 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1); 2245 2246 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL); 2247 op1 = expand_normal (arg1); 2248 2249 start_sequence (); 2250 2251 /* Compute into RESULT. 2252 Set RESULT to wherever the result comes back. */ 2253 result = expand_binop (mode, builtin_optab, op0, op1, 2254 result, 0, OPTAB_DIRECT); 2255 2256 /* If we were unable to expand via the builtin, stop the sequence 2257 (without outputting the insns) and call to the library function 2258 with the stabilized argument list. */ 2259 if (result == 0) 2260 { 2261 end_sequence (); 2262 return expand_call (exp, target, target == const0_rtx); 2263 } 2264 2265 if (errno_set) 2266 expand_errno_check (exp, result); 2267 2268 /* Output the entire sequence. */ 2269 insns = get_insns (); 2270 end_sequence (); 2271 emit_insn (insns); 2272 2273 return result; 2274} 2275 2276/* Expand a call to the builtin trinary math functions (fma). 2277 Return NULL_RTX if a normal call should be emitted rather than expanding the 2278 function in-line. EXP is the expression that is a call to the builtin 2279 function; if convenient, the result should be placed in TARGET. 2280 SUBTARGET may be used as the target for computing one of EXP's 2281 operands. */ 2282 2283static rtx 2284expand_builtin_mathfn_ternary (tree exp, rtx target, rtx subtarget) 2285{ 2286 optab builtin_optab; 2287 rtx op0, op1, op2, result; 2288 rtx_insn *insns; 2289 tree fndecl = get_callee_fndecl (exp); 2290 tree arg0, arg1, arg2; 2291 machine_mode mode; 2292 2293 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 2294 return NULL_RTX; 2295 2296 arg0 = CALL_EXPR_ARG (exp, 0); 2297 arg1 = CALL_EXPR_ARG (exp, 1); 2298 arg2 = CALL_EXPR_ARG (exp, 2); 2299 2300 switch (DECL_FUNCTION_CODE (fndecl)) 2301 { 2302 CASE_FLT_FN (BUILT_IN_FMA): 2303 builtin_optab = fma_optab; break; 2304 default: 2305 gcc_unreachable (); 2306 } 2307 2308 /* Make a suitable register to place result in. */ 2309 mode = TYPE_MODE (TREE_TYPE (exp)); 2310 2311 /* Before working hard, check whether the instruction is available. */ 2312 if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing) 2313 return NULL_RTX; 2314 2315 result = gen_reg_rtx (mode); 2316 2317 /* Always stabilize the argument list. */ 2318 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0); 2319 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1); 2320 CALL_EXPR_ARG (exp, 2) = arg2 = builtin_save_expr (arg2); 2321 2322 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL); 2323 op1 = expand_normal (arg1); 2324 op2 = expand_normal (arg2); 2325 2326 start_sequence (); 2327 2328 /* Compute into RESULT. 2329 Set RESULT to wherever the result comes back. */ 2330 result = expand_ternary_op (mode, builtin_optab, op0, op1, op2, 2331 result, 0); 2332 2333 /* If we were unable to expand via the builtin, stop the sequence 2334 (without outputting the insns) and call to the library function 2335 with the stabilized argument list. */ 2336 if (result == 0) 2337 { 2338 end_sequence (); 2339 return expand_call (exp, target, target == const0_rtx); 2340 } 2341 2342 /* Output the entire sequence. */ 2343 insns = get_insns (); 2344 end_sequence (); 2345 emit_insn (insns); 2346 2347 return result; 2348} 2349 2350/* Expand a call to the builtin sin and cos math functions. 2351 Return NULL_RTX if a normal call should be emitted rather than expanding the 2352 function in-line. EXP is the expression that is a call to the builtin 2353 function; if convenient, the result should be placed in TARGET. 2354 SUBTARGET may be used as the target for computing one of EXP's 2355 operands. */ 2356 2357static rtx 2358expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget) 2359{ 2360 optab builtin_optab; 2361 rtx op0; 2362 rtx_insn *insns; 2363 tree fndecl = get_callee_fndecl (exp); 2364 machine_mode mode; 2365 tree arg; 2366 2367 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2368 return NULL_RTX; 2369 2370 arg = CALL_EXPR_ARG (exp, 0); 2371 2372 switch (DECL_FUNCTION_CODE (fndecl)) 2373 { 2374 CASE_FLT_FN (BUILT_IN_SIN): 2375 CASE_FLT_FN (BUILT_IN_COS): 2376 builtin_optab = sincos_optab; break; 2377 default: 2378 gcc_unreachable (); 2379 } 2380 2381 /* Make a suitable register to place result in. */ 2382 mode = TYPE_MODE (TREE_TYPE (exp)); 2383 2384 /* Check if sincos insn is available, otherwise fallback 2385 to sin or cos insn. */ 2386 if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing) 2387 switch (DECL_FUNCTION_CODE (fndecl)) 2388 { 2389 CASE_FLT_FN (BUILT_IN_SIN): 2390 builtin_optab = sin_optab; break; 2391 CASE_FLT_FN (BUILT_IN_COS): 2392 builtin_optab = cos_optab; break; 2393 default: 2394 gcc_unreachable (); 2395 } 2396 2397 /* Before working hard, check whether the instruction is available. */ 2398 if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing) 2399 { 2400 rtx result = gen_reg_rtx (mode); 2401 2402 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2403 need to expand the argument again. This way, we will not perform 2404 side-effects more the once. */ 2405 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 2406 2407 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 2408 2409 start_sequence (); 2410 2411 /* Compute into RESULT. 2412 Set RESULT to wherever the result comes back. */ 2413 if (builtin_optab == sincos_optab) 2414 { 2415 int ok; 2416 2417 switch (DECL_FUNCTION_CODE (fndecl)) 2418 { 2419 CASE_FLT_FN (BUILT_IN_SIN): 2420 ok = expand_twoval_unop (builtin_optab, op0, 0, result, 0); 2421 break; 2422 CASE_FLT_FN (BUILT_IN_COS): 2423 ok = expand_twoval_unop (builtin_optab, op0, result, 0, 0); 2424 break; 2425 default: 2426 gcc_unreachable (); 2427 } 2428 gcc_assert (ok); 2429 } 2430 else 2431 result = expand_unop (mode, builtin_optab, op0, result, 0); 2432 2433 if (result != 0) 2434 { 2435 /* Output the entire sequence. */ 2436 insns = get_insns (); 2437 end_sequence (); 2438 emit_insn (insns); 2439 return result; 2440 } 2441 2442 /* If we were unable to expand via the builtin, stop the sequence 2443 (without outputting the insns) and call to the library function 2444 with the stabilized argument list. */ 2445 end_sequence (); 2446 } 2447 2448 return expand_call (exp, target, target == const0_rtx); 2449} 2450 2451/* Given an interclass math builtin decl FNDECL and it's argument ARG 2452 return an RTL instruction code that implements the functionality. 2453 If that isn't possible or available return CODE_FOR_nothing. */ 2454 2455static enum insn_code 2456interclass_mathfn_icode (tree arg, tree fndecl) 2457{ 2458 bool errno_set = false; 2459 optab builtin_optab = unknown_optab; 2460 machine_mode mode; 2461 2462 switch (DECL_FUNCTION_CODE (fndecl)) 2463 { 2464 CASE_FLT_FN (BUILT_IN_ILOGB): 2465 errno_set = true; builtin_optab = ilogb_optab; break; 2466 CASE_FLT_FN (BUILT_IN_ISINF): 2467 builtin_optab = isinf_optab; break; 2468 case BUILT_IN_ISNORMAL: 2469 case BUILT_IN_ISFINITE: 2470 CASE_FLT_FN (BUILT_IN_FINITE): 2471 case BUILT_IN_FINITED32: 2472 case BUILT_IN_FINITED64: 2473 case BUILT_IN_FINITED128: 2474 case BUILT_IN_ISINFD32: 2475 case BUILT_IN_ISINFD64: 2476 case BUILT_IN_ISINFD128: 2477 /* These builtins have no optabs (yet). */ 2478 break; 2479 default: 2480 gcc_unreachable (); 2481 } 2482 2483 /* There's no easy way to detect the case we need to set EDOM. */ 2484 if (flag_errno_math && errno_set) 2485 return CODE_FOR_nothing; 2486 2487 /* Optab mode depends on the mode of the input argument. */ 2488 mode = TYPE_MODE (TREE_TYPE (arg)); 2489 2490 if (builtin_optab) 2491 return optab_handler (builtin_optab, mode); 2492 return CODE_FOR_nothing; 2493} 2494 2495/* Expand a call to one of the builtin math functions that operate on 2496 floating point argument and output an integer result (ilogb, isinf, 2497 isnan, etc). 2498 Return 0 if a normal call should be emitted rather than expanding the 2499 function in-line. EXP is the expression that is a call to the builtin 2500 function; if convenient, the result should be placed in TARGET. */ 2501 2502static rtx 2503expand_builtin_interclass_mathfn (tree exp, rtx target) 2504{ 2505 enum insn_code icode = CODE_FOR_nothing; 2506 rtx op0; 2507 tree fndecl = get_callee_fndecl (exp); 2508 machine_mode mode; 2509 tree arg; 2510 2511 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2512 return NULL_RTX; 2513 2514 arg = CALL_EXPR_ARG (exp, 0); 2515 icode = interclass_mathfn_icode (arg, fndecl); 2516 mode = TYPE_MODE (TREE_TYPE (arg)); 2517 2518 if (icode != CODE_FOR_nothing) 2519 { 2520 struct expand_operand ops[1]; 2521 rtx_insn *last = get_last_insn (); 2522 tree orig_arg = arg; 2523 2524 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2525 need to expand the argument again. This way, we will not perform 2526 side-effects more the once. */ 2527 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 2528 2529 op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL); 2530 2531 if (mode != GET_MODE (op0)) 2532 op0 = convert_to_mode (mode, op0, 0); 2533 2534 create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp))); 2535 if (maybe_legitimize_operands (icode, 0, 1, ops) 2536 && maybe_emit_unop_insn (icode, ops[0].value, op0, UNKNOWN)) 2537 return ops[0].value; 2538 2539 delete_insns_since (last); 2540 CALL_EXPR_ARG (exp, 0) = orig_arg; 2541 } 2542 2543 return NULL_RTX; 2544} 2545 2546/* Expand a call to the builtin sincos math function. 2547 Return NULL_RTX if a normal call should be emitted rather than expanding the 2548 function in-line. EXP is the expression that is a call to the builtin 2549 function. */ 2550 2551static rtx 2552expand_builtin_sincos (tree exp) 2553{ 2554 rtx op0, op1, op2, target1, target2; 2555 machine_mode mode; 2556 tree arg, sinp, cosp; 2557 int result; 2558 location_t loc = EXPR_LOCATION (exp); 2559 tree alias_type, alias_off; 2560 2561 if (!validate_arglist (exp, REAL_TYPE, 2562 POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 2563 return NULL_RTX; 2564 2565 arg = CALL_EXPR_ARG (exp, 0); 2566 sinp = CALL_EXPR_ARG (exp, 1); 2567 cosp = CALL_EXPR_ARG (exp, 2); 2568 2569 /* Make a suitable register to place result in. */ 2570 mode = TYPE_MODE (TREE_TYPE (arg)); 2571 2572 /* Check if sincos insn is available, otherwise emit the call. */ 2573 if (optab_handler (sincos_optab, mode) == CODE_FOR_nothing) 2574 return NULL_RTX; 2575 2576 target1 = gen_reg_rtx (mode); 2577 target2 = gen_reg_rtx (mode); 2578 2579 op0 = expand_normal (arg); 2580 alias_type = build_pointer_type_for_mode (TREE_TYPE (arg), ptr_mode, true); 2581 alias_off = build_int_cst (alias_type, 0); 2582 op1 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg), 2583 sinp, alias_off)); 2584 op2 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg), 2585 cosp, alias_off)); 2586 2587 /* Compute into target1 and target2. 2588 Set TARGET to wherever the result comes back. */ 2589 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0); 2590 gcc_assert (result); 2591 2592 /* Move target1 and target2 to the memory locations indicated 2593 by op1 and op2. */ 2594 emit_move_insn (op1, target1); 2595 emit_move_insn (op2, target2); 2596 2597 return const0_rtx; 2598} 2599 2600/* Expand a call to the internal cexpi builtin to the sincos math function. 2601 EXP is the expression that is a call to the builtin function; if convenient, 2602 the result should be placed in TARGET. */ 2603 2604static rtx 2605expand_builtin_cexpi (tree exp, rtx target) 2606{ 2607 tree fndecl = get_callee_fndecl (exp); 2608 tree arg, type; 2609 machine_mode mode; 2610 rtx op0, op1, op2; 2611 location_t loc = EXPR_LOCATION (exp); 2612 2613 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2614 return NULL_RTX; 2615 2616 arg = CALL_EXPR_ARG (exp, 0); 2617 type = TREE_TYPE (arg); 2618 mode = TYPE_MODE (TREE_TYPE (arg)); 2619 2620 /* Try expanding via a sincos optab, fall back to emitting a libcall 2621 to sincos or cexp. We are sure we have sincos or cexp because cexpi 2622 is only generated from sincos, cexp or if we have either of them. */ 2623 if (optab_handler (sincos_optab, mode) != CODE_FOR_nothing) 2624 { 2625 op1 = gen_reg_rtx (mode); 2626 op2 = gen_reg_rtx (mode); 2627 2628 op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL); 2629 2630 /* Compute into op1 and op2. */ 2631 expand_twoval_unop (sincos_optab, op0, op2, op1, 0); 2632 } 2633 else if (targetm.libc_has_function (function_sincos)) 2634 { 2635 tree call, fn = NULL_TREE; 2636 tree top1, top2; 2637 rtx op1a, op2a; 2638 2639 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF) 2640 fn = builtin_decl_explicit (BUILT_IN_SINCOSF); 2641 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI) 2642 fn = builtin_decl_explicit (BUILT_IN_SINCOS); 2643 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL) 2644 fn = builtin_decl_explicit (BUILT_IN_SINCOSL); 2645 else 2646 gcc_unreachable (); 2647 2648 op1 = assign_temp (TREE_TYPE (arg), 1, 1); 2649 op2 = assign_temp (TREE_TYPE (arg), 1, 1); 2650 op1a = copy_addr_to_reg (XEXP (op1, 0)); 2651 op2a = copy_addr_to_reg (XEXP (op2, 0)); 2652 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a); 2653 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a); 2654 2655 /* Make sure not to fold the sincos call again. */ 2656 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); 2657 expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)), 2658 call, 3, arg, top1, top2)); 2659 } 2660 else 2661 { 2662 tree call, fn = NULL_TREE, narg; 2663 tree ctype = build_complex_type (type); 2664 2665 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF) 2666 fn = builtin_decl_explicit (BUILT_IN_CEXPF); 2667 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI) 2668 fn = builtin_decl_explicit (BUILT_IN_CEXP); 2669 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL) 2670 fn = builtin_decl_explicit (BUILT_IN_CEXPL); 2671 else 2672 gcc_unreachable (); 2673 2674 /* If we don't have a decl for cexp create one. This is the 2675 friendliest fallback if the user calls __builtin_cexpi 2676 without full target C99 function support. */ 2677 if (fn == NULL_TREE) 2678 { 2679 tree fntype; 2680 const char *name = NULL; 2681 2682 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF) 2683 name = "cexpf"; 2684 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI) 2685 name = "cexp"; 2686 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL) 2687 name = "cexpl"; 2688 2689 fntype = build_function_type_list (ctype, ctype, NULL_TREE); 2690 fn = build_fn_decl (name, fntype); 2691 } 2692 2693 narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype, 2694 build_real (type, dconst0), arg); 2695 2696 /* Make sure not to fold the cexp call again. */ 2697 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); 2698 return expand_expr (build_call_nary (ctype, call, 1, narg), 2699 target, VOIDmode, EXPAND_NORMAL); 2700 } 2701 2702 /* Now build the proper return type. */ 2703 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type), 2704 make_tree (TREE_TYPE (arg), op2), 2705 make_tree (TREE_TYPE (arg), op1)), 2706 target, VOIDmode, EXPAND_NORMAL); 2707} 2708 2709/* Conveniently construct a function call expression. FNDECL names the 2710 function to be called, N is the number of arguments, and the "..." 2711 parameters are the argument expressions. Unlike build_call_exr 2712 this doesn't fold the call, hence it will always return a CALL_EXPR. */ 2713 2714static tree 2715build_call_nofold_loc (location_t loc, tree fndecl, int n, ...) 2716{ 2717 va_list ap; 2718 tree fntype = TREE_TYPE (fndecl); 2719 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl); 2720 2721 va_start (ap, n); 2722 fn = build_call_valist (TREE_TYPE (fntype), fn, n, ap); 2723 va_end (ap); 2724 SET_EXPR_LOCATION (fn, loc); 2725 return fn; 2726} 2727 2728/* Expand a call to one of the builtin rounding functions gcc defines 2729 as an extension (lfloor and lceil). As these are gcc extensions we 2730 do not need to worry about setting errno to EDOM. 2731 If expanding via optab fails, lower expression to (int)(floor(x)). 2732 EXP is the expression that is a call to the builtin function; 2733 if convenient, the result should be placed in TARGET. */ 2734 2735static rtx 2736expand_builtin_int_roundingfn (tree exp, rtx target) 2737{ 2738 convert_optab builtin_optab; 2739 rtx op0, tmp; 2740 rtx_insn *insns; 2741 tree fndecl = get_callee_fndecl (exp); 2742 enum built_in_function fallback_fn; 2743 tree fallback_fndecl; 2744 machine_mode mode; 2745 tree arg; 2746 2747 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2748 gcc_unreachable (); 2749 2750 arg = CALL_EXPR_ARG (exp, 0); 2751 2752 switch (DECL_FUNCTION_CODE (fndecl)) 2753 { 2754 CASE_FLT_FN (BUILT_IN_ICEIL): 2755 CASE_FLT_FN (BUILT_IN_LCEIL): 2756 CASE_FLT_FN (BUILT_IN_LLCEIL): 2757 builtin_optab = lceil_optab; 2758 fallback_fn = BUILT_IN_CEIL; 2759 break; 2760 2761 CASE_FLT_FN (BUILT_IN_IFLOOR): 2762 CASE_FLT_FN (BUILT_IN_LFLOOR): 2763 CASE_FLT_FN (BUILT_IN_LLFLOOR): 2764 builtin_optab = lfloor_optab; 2765 fallback_fn = BUILT_IN_FLOOR; 2766 break; 2767 2768 default: 2769 gcc_unreachable (); 2770 } 2771 2772 /* Make a suitable register to place result in. */ 2773 mode = TYPE_MODE (TREE_TYPE (exp)); 2774 2775 target = gen_reg_rtx (mode); 2776 2777 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2778 need to expand the argument again. This way, we will not perform 2779 side-effects more the once. */ 2780 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 2781 2782 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL); 2783 2784 start_sequence (); 2785 2786 /* Compute into TARGET. */ 2787 if (expand_sfix_optab (target, op0, builtin_optab)) 2788 { 2789 /* Output the entire sequence. */ 2790 insns = get_insns (); 2791 end_sequence (); 2792 emit_insn (insns); 2793 return target; 2794 } 2795 2796 /* If we were unable to expand via the builtin, stop the sequence 2797 (without outputting the insns). */ 2798 end_sequence (); 2799 2800 /* Fall back to floating point rounding optab. */ 2801 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn); 2802 2803 /* For non-C99 targets we may end up without a fallback fndecl here 2804 if the user called __builtin_lfloor directly. In this case emit 2805 a call to the floor/ceil variants nevertheless. This should result 2806 in the best user experience for not full C99 targets. */ 2807 if (fallback_fndecl == NULL_TREE) 2808 { 2809 tree fntype; 2810 const char *name = NULL; 2811 2812 switch (DECL_FUNCTION_CODE (fndecl)) 2813 { 2814 case BUILT_IN_ICEIL: 2815 case BUILT_IN_LCEIL: 2816 case BUILT_IN_LLCEIL: 2817 name = "ceil"; 2818 break; 2819 case BUILT_IN_ICEILF: 2820 case BUILT_IN_LCEILF: 2821 case BUILT_IN_LLCEILF: 2822 name = "ceilf"; 2823 break; 2824 case BUILT_IN_ICEILL: 2825 case BUILT_IN_LCEILL: 2826 case BUILT_IN_LLCEILL: 2827 name = "ceill"; 2828 break; 2829 case BUILT_IN_IFLOOR: 2830 case BUILT_IN_LFLOOR: 2831 case BUILT_IN_LLFLOOR: 2832 name = "floor"; 2833 break; 2834 case BUILT_IN_IFLOORF: 2835 case BUILT_IN_LFLOORF: 2836 case BUILT_IN_LLFLOORF: 2837 name = "floorf"; 2838 break; 2839 case BUILT_IN_IFLOORL: 2840 case BUILT_IN_LFLOORL: 2841 case BUILT_IN_LLFLOORL: 2842 name = "floorl"; 2843 break; 2844 default: 2845 gcc_unreachable (); 2846 } 2847 2848 fntype = build_function_type_list (TREE_TYPE (arg), 2849 TREE_TYPE (arg), NULL_TREE); 2850 fallback_fndecl = build_fn_decl (name, fntype); 2851 } 2852 2853 exp = build_call_nofold_loc (EXPR_LOCATION (exp), fallback_fndecl, 1, arg); 2854 2855 tmp = expand_normal (exp); 2856 tmp = maybe_emit_group_store (tmp, TREE_TYPE (exp)); 2857 2858 /* Truncate the result of floating point optab to integer 2859 via expand_fix (). */ 2860 target = gen_reg_rtx (mode); 2861 expand_fix (target, tmp, 0); 2862 2863 return target; 2864} 2865 2866/* Expand a call to one of the builtin math functions doing integer 2867 conversion (lrint). 2868 Return 0 if a normal call should be emitted rather than expanding the 2869 function in-line. EXP is the expression that is a call to the builtin 2870 function; if convenient, the result should be placed in TARGET. */ 2871 2872static rtx 2873expand_builtin_int_roundingfn_2 (tree exp, rtx target) 2874{ 2875 convert_optab builtin_optab; 2876 rtx op0; 2877 rtx_insn *insns; 2878 tree fndecl = get_callee_fndecl (exp); 2879 tree arg; 2880 machine_mode mode; 2881 enum built_in_function fallback_fn = BUILT_IN_NONE; 2882 2883 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2884 gcc_unreachable (); 2885 2886 arg = CALL_EXPR_ARG (exp, 0); 2887 2888 switch (DECL_FUNCTION_CODE (fndecl)) 2889 { 2890 CASE_FLT_FN (BUILT_IN_IRINT): 2891 fallback_fn = BUILT_IN_LRINT; 2892 /* FALLTHRU */ 2893 CASE_FLT_FN (BUILT_IN_LRINT): 2894 CASE_FLT_FN (BUILT_IN_LLRINT): 2895 builtin_optab = lrint_optab; 2896 break; 2897 2898 CASE_FLT_FN (BUILT_IN_IROUND): 2899 fallback_fn = BUILT_IN_LROUND; 2900 /* FALLTHRU */ 2901 CASE_FLT_FN (BUILT_IN_LROUND): 2902 CASE_FLT_FN (BUILT_IN_LLROUND): 2903 builtin_optab = lround_optab; 2904 break; 2905 2906 default: 2907 gcc_unreachable (); 2908 } 2909 2910 /* There's no easy way to detect the case we need to set EDOM. */ 2911 if (flag_errno_math && fallback_fn == BUILT_IN_NONE) 2912 return NULL_RTX; 2913 2914 /* Make a suitable register to place result in. */ 2915 mode = TYPE_MODE (TREE_TYPE (exp)); 2916 2917 /* There's no easy way to detect the case we need to set EDOM. */ 2918 if (!flag_errno_math) 2919 { 2920 rtx result = gen_reg_rtx (mode); 2921 2922 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2923 need to expand the argument again. This way, we will not perform 2924 side-effects more the once. */ 2925 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 2926 2927 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL); 2928 2929 start_sequence (); 2930 2931 if (expand_sfix_optab (result, op0, builtin_optab)) 2932 { 2933 /* Output the entire sequence. */ 2934 insns = get_insns (); 2935 end_sequence (); 2936 emit_insn (insns); 2937 return result; 2938 } 2939 2940 /* If we were unable to expand via the builtin, stop the sequence 2941 (without outputting the insns) and call to the library function 2942 with the stabilized argument list. */ 2943 end_sequence (); 2944 } 2945 2946 if (fallback_fn != BUILT_IN_NONE) 2947 { 2948 /* Fall back to rounding to long int. Use implicit_p 0 - for non-C99 2949 targets, (int) round (x) should never be transformed into 2950 BUILT_IN_IROUND and if __builtin_iround is called directly, emit 2951 a call to lround in the hope that the target provides at least some 2952 C99 functions. This should result in the best user experience for 2953 not full C99 targets. */ 2954 tree fallback_fndecl = mathfn_built_in_1 (TREE_TYPE (arg), 2955 fallback_fn, 0); 2956 2957 exp = build_call_nofold_loc (EXPR_LOCATION (exp), 2958 fallback_fndecl, 1, arg); 2959 2960 target = expand_call (exp, NULL_RTX, target == const0_rtx); 2961 target = maybe_emit_group_store (target, TREE_TYPE (exp)); 2962 return convert_to_mode (mode, target, 0); 2963 } 2964 2965 return expand_call (exp, target, target == const0_rtx); 2966} 2967 2968/* Expand a call to the powi built-in mathematical function. Return NULL_RTX if 2969 a normal call should be emitted rather than expanding the function 2970 in-line. EXP is the expression that is a call to the builtin 2971 function; if convenient, the result should be placed in TARGET. */ 2972 2973static rtx 2974expand_builtin_powi (tree exp, rtx target) 2975{ 2976 tree arg0, arg1; 2977 rtx op0, op1; 2978 machine_mode mode; 2979 machine_mode mode2; 2980 2981 if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE)) 2982 return NULL_RTX; 2983 2984 arg0 = CALL_EXPR_ARG (exp, 0); 2985 arg1 = CALL_EXPR_ARG (exp, 1); 2986 mode = TYPE_MODE (TREE_TYPE (exp)); 2987 2988 /* Emit a libcall to libgcc. */ 2989 2990 /* Mode of the 2nd argument must match that of an int. */ 2991 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0); 2992 2993 if (target == NULL_RTX) 2994 target = gen_reg_rtx (mode); 2995 2996 op0 = expand_expr (arg0, NULL_RTX, mode, EXPAND_NORMAL); 2997 if (GET_MODE (op0) != mode) 2998 op0 = convert_to_mode (mode, op0, 0); 2999 op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL); 3000 if (GET_MODE (op1) != mode2) 3001 op1 = convert_to_mode (mode2, op1, 0); 3002 3003 target = emit_library_call_value (optab_libfunc (powi_optab, mode), 3004 target, LCT_CONST, mode, 2, 3005 op0, mode, op1, mode2); 3006 3007 return target; 3008} 3009 3010/* Expand expression EXP which is a call to the strlen builtin. Return 3011 NULL_RTX if we failed the caller should emit a normal call, otherwise 3012 try to get the result in TARGET, if convenient. */ 3013 3014static rtx 3015expand_builtin_strlen (tree exp, rtx target, 3016 machine_mode target_mode) 3017{ 3018 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 3019 return NULL_RTX; 3020 else 3021 { 3022 struct expand_operand ops[4]; 3023 rtx pat; 3024 tree len; 3025 tree src = CALL_EXPR_ARG (exp, 0); 3026 rtx src_reg; 3027 rtx_insn *before_strlen; 3028 machine_mode insn_mode = target_mode; 3029 enum insn_code icode = CODE_FOR_nothing; 3030 unsigned int align; 3031 3032 /* If the length can be computed at compile-time, return it. */ 3033 len = c_strlen (src, 0); 3034 if (len) 3035 return expand_expr (len, target, target_mode, EXPAND_NORMAL); 3036 3037 /* If the length can be computed at compile-time and is constant 3038 integer, but there are side-effects in src, evaluate 3039 src for side-effects, then return len. 3040 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar"); 3041 can be optimized into: i++; x = 3; */ 3042 len = c_strlen (src, 1); 3043 if (len && TREE_CODE (len) == INTEGER_CST) 3044 { 3045 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL); 3046 return expand_expr (len, target, target_mode, EXPAND_NORMAL); 3047 } 3048 3049 align = get_pointer_alignment (src) / BITS_PER_UNIT; 3050 3051 /* If SRC is not a pointer type, don't do this operation inline. */ 3052 if (align == 0) 3053 return NULL_RTX; 3054 3055 /* Bail out if we can't compute strlen in the right mode. */ 3056 while (insn_mode != VOIDmode) 3057 { 3058 icode = optab_handler (strlen_optab, insn_mode); 3059 if (icode != CODE_FOR_nothing) 3060 break; 3061 3062 insn_mode = GET_MODE_WIDER_MODE (insn_mode); 3063 } 3064 if (insn_mode == VOIDmode) 3065 return NULL_RTX; 3066 3067 /* Make a place to hold the source address. We will not expand 3068 the actual source until we are sure that the expansion will 3069 not fail -- there are trees that cannot be expanded twice. */ 3070 src_reg = gen_reg_rtx (Pmode); 3071 3072 /* Mark the beginning of the strlen sequence so we can emit the 3073 source operand later. */ 3074 before_strlen = get_last_insn (); 3075 3076 create_output_operand (&ops[0], target, insn_mode); 3077 create_fixed_operand (&ops[1], gen_rtx_MEM (BLKmode, src_reg)); 3078 create_integer_operand (&ops[2], 0); 3079 create_integer_operand (&ops[3], align); 3080 if (!maybe_expand_insn (icode, 4, ops)) 3081 return NULL_RTX; 3082 3083 /* Now that we are assured of success, expand the source. */ 3084 start_sequence (); 3085 pat = expand_expr (src, src_reg, Pmode, EXPAND_NORMAL); 3086 if (pat != src_reg) 3087 { 3088#ifdef POINTERS_EXTEND_UNSIGNED 3089 if (GET_MODE (pat) != Pmode) 3090 pat = convert_to_mode (Pmode, pat, 3091 POINTERS_EXTEND_UNSIGNED); 3092#endif 3093 emit_move_insn (src_reg, pat); 3094 } 3095 pat = get_insns (); 3096 end_sequence (); 3097 3098 if (before_strlen) 3099 emit_insn_after (pat, before_strlen); 3100 else 3101 emit_insn_before (pat, get_insns ()); 3102 3103 /* Return the value in the proper mode for this function. */ 3104 if (GET_MODE (ops[0].value) == target_mode) 3105 target = ops[0].value; 3106 else if (target != 0) 3107 convert_move (target, ops[0].value, 0); 3108 else 3109 target = convert_to_mode (target_mode, ops[0].value, 0); 3110 3111 return target; 3112 } 3113} 3114 3115/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 3116 bytes from constant string DATA + OFFSET and return it as target 3117 constant. */ 3118 3119static rtx 3120builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset, 3121 machine_mode mode) 3122{ 3123 const char *str = (const char *) data; 3124 3125 gcc_assert (offset >= 0 3126 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode) 3127 <= strlen (str) + 1)); 3128 3129 return c_readstr (str + offset, mode); 3130} 3131 3132/* LEN specify length of the block of memcpy/memset operation. 3133 Figure out its range and put it into MIN_SIZE/MAX_SIZE. 3134 In some cases we can make very likely guess on max size, then we 3135 set it into PROBABLE_MAX_SIZE. */ 3136 3137static void 3138determine_block_size (tree len, rtx len_rtx, 3139 unsigned HOST_WIDE_INT *min_size, 3140 unsigned HOST_WIDE_INT *max_size, 3141 unsigned HOST_WIDE_INT *probable_max_size) 3142{ 3143 if (CONST_INT_P (len_rtx)) 3144 { 3145 *min_size = *max_size = *probable_max_size = UINTVAL (len_rtx); 3146 return; 3147 } 3148 else 3149 { 3150 wide_int min, max; 3151 enum value_range_type range_type = VR_UNDEFINED; 3152 3153 /* Determine bounds from the type. */ 3154 if (tree_fits_uhwi_p (TYPE_MIN_VALUE (TREE_TYPE (len)))) 3155 *min_size = tree_to_uhwi (TYPE_MIN_VALUE (TREE_TYPE (len))); 3156 else 3157 *min_size = 0; 3158 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (TREE_TYPE (len)))) 3159 *probable_max_size = *max_size 3160 = tree_to_uhwi (TYPE_MAX_VALUE (TREE_TYPE (len))); 3161 else 3162 *probable_max_size = *max_size = GET_MODE_MASK (GET_MODE (len_rtx)); 3163 3164 if (TREE_CODE (len) == SSA_NAME) 3165 range_type = get_range_info (len, &min, &max); 3166 if (range_type == VR_RANGE) 3167 { 3168 if (wi::fits_uhwi_p (min) && *min_size < min.to_uhwi ()) 3169 *min_size = min.to_uhwi (); 3170 if (wi::fits_uhwi_p (max) && *max_size > max.to_uhwi ()) 3171 *probable_max_size = *max_size = max.to_uhwi (); 3172 } 3173 else if (range_type == VR_ANTI_RANGE) 3174 { 3175 /* Anti range 0...N lets us to determine minimal size to N+1. */ 3176 if (min == 0) 3177 { 3178 if (wi::fits_uhwi_p (max) && max.to_uhwi () + 1 != 0) 3179 *min_size = max.to_uhwi () + 1; 3180 } 3181 /* Code like 3182 3183 int n; 3184 if (n < 100) 3185 memcpy (a, b, n) 3186 3187 Produce anti range allowing negative values of N. We still 3188 can use the information and make a guess that N is not negative. 3189 */ 3190 else if (!wi::leu_p (max, 1 << 30) && wi::fits_uhwi_p (min)) 3191 *probable_max_size = min.to_uhwi () - 1; 3192 } 3193 } 3194 gcc_checking_assert (*max_size <= 3195 (unsigned HOST_WIDE_INT) 3196 GET_MODE_MASK (GET_MODE (len_rtx))); 3197} 3198 3199/* Helper function to do the actual work for expand_builtin_memcpy. */ 3200 3201static rtx 3202expand_builtin_memcpy_args (tree dest, tree src, tree len, rtx target, tree exp) 3203{ 3204 const char *src_str; 3205 unsigned int src_align = get_pointer_alignment (src); 3206 unsigned int dest_align = get_pointer_alignment (dest); 3207 rtx dest_mem, src_mem, dest_addr, len_rtx; 3208 HOST_WIDE_INT expected_size = -1; 3209 unsigned int expected_align = 0; 3210 unsigned HOST_WIDE_INT min_size; 3211 unsigned HOST_WIDE_INT max_size; 3212 unsigned HOST_WIDE_INT probable_max_size; 3213 3214 /* If DEST is not a pointer type, call the normal function. */ 3215 if (dest_align == 0) 3216 return NULL_RTX; 3217 3218 /* If either SRC is not a pointer type, don't do this 3219 operation in-line. */ 3220 if (src_align == 0) 3221 return NULL_RTX; 3222 3223 if (currently_expanding_gimple_stmt) 3224 stringop_block_profile (currently_expanding_gimple_stmt, 3225 &expected_align, &expected_size); 3226 3227 if (expected_align < dest_align) 3228 expected_align = dest_align; 3229 dest_mem = get_memory_rtx (dest, len); 3230 set_mem_align (dest_mem, dest_align); 3231 len_rtx = expand_normal (len); 3232 determine_block_size (len, len_rtx, &min_size, &max_size, 3233 &probable_max_size); 3234 src_str = c_getstr (src); 3235 3236 /* If SRC is a string constant and block move would be done 3237 by pieces, we can avoid loading the string from memory 3238 and only stored the computed constants. */ 3239 if (src_str 3240 && CONST_INT_P (len_rtx) 3241 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1 3242 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str, 3243 CONST_CAST (char *, src_str), 3244 dest_align, false)) 3245 { 3246 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx), 3247 builtin_memcpy_read_str, 3248 CONST_CAST (char *, src_str), 3249 dest_align, false, 0); 3250 dest_mem = force_operand (XEXP (dest_mem, 0), target); 3251 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3252 return dest_mem; 3253 } 3254 3255 src_mem = get_memory_rtx (src, len); 3256 set_mem_align (src_mem, src_align); 3257 3258 /* Copy word part most expediently. */ 3259 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, 3260 CALL_EXPR_TAILCALL (exp) 3261 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL, 3262 expected_align, expected_size, 3263 min_size, max_size, probable_max_size); 3264 3265 if (dest_addr == 0) 3266 { 3267 dest_addr = force_operand (XEXP (dest_mem, 0), target); 3268 dest_addr = convert_memory_address (ptr_mode, dest_addr); 3269 } 3270 3271 return dest_addr; 3272} 3273 3274/* Expand a call EXP to the memcpy builtin. 3275 Return NULL_RTX if we failed, the caller should emit a normal call, 3276 otherwise try to get the result in TARGET, if convenient (and in 3277 mode MODE if that's convenient). */ 3278 3279static rtx 3280expand_builtin_memcpy (tree exp, rtx target) 3281{ 3282 if (!validate_arglist (exp, 3283 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3284 return NULL_RTX; 3285 else 3286 { 3287 tree dest = CALL_EXPR_ARG (exp, 0); 3288 tree src = CALL_EXPR_ARG (exp, 1); 3289 tree len = CALL_EXPR_ARG (exp, 2); 3290 return expand_builtin_memcpy_args (dest, src, len, target, exp); 3291 } 3292} 3293 3294/* Expand an instrumented call EXP to the memcpy builtin. 3295 Return NULL_RTX if we failed, the caller should emit a normal call, 3296 otherwise try to get the result in TARGET, if convenient (and in 3297 mode MODE if that's convenient). */ 3298 3299static rtx 3300expand_builtin_memcpy_with_bounds (tree exp, rtx target) 3301{ 3302 if (!validate_arglist (exp, 3303 POINTER_TYPE, POINTER_BOUNDS_TYPE, 3304 POINTER_TYPE, POINTER_BOUNDS_TYPE, 3305 INTEGER_TYPE, VOID_TYPE)) 3306 return NULL_RTX; 3307 else 3308 { 3309 tree dest = CALL_EXPR_ARG (exp, 0); 3310 tree src = CALL_EXPR_ARG (exp, 2); 3311 tree len = CALL_EXPR_ARG (exp, 4); 3312 rtx res = expand_builtin_memcpy_args (dest, src, len, target, exp); 3313 3314 /* Return src bounds with the result. */ 3315 if (res) 3316 { 3317 rtx bnd = force_reg (targetm.chkp_bound_mode (), 3318 expand_normal (CALL_EXPR_ARG (exp, 1))); 3319 res = chkp_join_splitted_slot (res, bnd); 3320 } 3321 return res; 3322 } 3323} 3324 3325/* Expand a call EXP to the mempcpy builtin. 3326 Return NULL_RTX if we failed; the caller should emit a normal call, 3327 otherwise try to get the result in TARGET, if convenient (and in 3328 mode MODE if that's convenient). If ENDP is 0 return the 3329 destination pointer, if ENDP is 1 return the end pointer ala 3330 mempcpy, and if ENDP is 2 return the end pointer minus one ala 3331 stpcpy. */ 3332 3333static rtx 3334expand_builtin_mempcpy (tree exp, rtx target, machine_mode mode) 3335{ 3336 if (!validate_arglist (exp, 3337 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3338 return NULL_RTX; 3339 else 3340 { 3341 tree dest = CALL_EXPR_ARG (exp, 0); 3342 tree src = CALL_EXPR_ARG (exp, 1); 3343 tree len = CALL_EXPR_ARG (exp, 2); 3344 return expand_builtin_mempcpy_args (dest, src, len, 3345 target, mode, /*endp=*/ 1, 3346 exp); 3347 } 3348} 3349 3350/* Expand an instrumented call EXP to the mempcpy builtin. 3351 Return NULL_RTX if we failed, the caller should emit a normal call, 3352 otherwise try to get the result in TARGET, if convenient (and in 3353 mode MODE if that's convenient). */ 3354 3355static rtx 3356expand_builtin_mempcpy_with_bounds (tree exp, rtx target, machine_mode mode) 3357{ 3358 if (!validate_arglist (exp, 3359 POINTER_TYPE, POINTER_BOUNDS_TYPE, 3360 POINTER_TYPE, POINTER_BOUNDS_TYPE, 3361 INTEGER_TYPE, VOID_TYPE)) 3362 return NULL_RTX; 3363 else 3364 { 3365 tree dest = CALL_EXPR_ARG (exp, 0); 3366 tree src = CALL_EXPR_ARG (exp, 2); 3367 tree len = CALL_EXPR_ARG (exp, 4); 3368 rtx res = expand_builtin_mempcpy_args (dest, src, len, target, 3369 mode, 1, exp); 3370 3371 /* Return src bounds with the result. */ 3372 if (res) 3373 { 3374 rtx bnd = force_reg (targetm.chkp_bound_mode (), 3375 expand_normal (CALL_EXPR_ARG (exp, 1))); 3376 res = chkp_join_splitted_slot (res, bnd); 3377 } 3378 return res; 3379 } 3380} 3381 3382/* Helper function to do the actual work for expand_builtin_mempcpy. The 3383 arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out 3384 so that this can also be called without constructing an actual CALL_EXPR. 3385 The other arguments and return value are the same as for 3386 expand_builtin_mempcpy. */ 3387 3388static rtx 3389expand_builtin_mempcpy_args (tree dest, tree src, tree len, 3390 rtx target, machine_mode mode, int endp, 3391 tree orig_exp) 3392{ 3393 tree fndecl = get_callee_fndecl (orig_exp); 3394 3395 /* If return value is ignored, transform mempcpy into memcpy. */ 3396 if (target == const0_rtx 3397 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK_CHKP 3398 && builtin_decl_implicit_p (BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK_CHKP)) 3399 { 3400 tree fn = builtin_decl_implicit (BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK_CHKP); 3401 tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3, 3402 dest, src, len); 3403 return expand_expr (result, target, mode, EXPAND_NORMAL); 3404 } 3405 else if (target == const0_rtx 3406 && builtin_decl_implicit_p (BUILT_IN_MEMCPY)) 3407 { 3408 tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY); 3409 tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3, 3410 dest, src, len); 3411 return expand_expr (result, target, mode, EXPAND_NORMAL); 3412 } 3413 else 3414 { 3415 const char *src_str; 3416 unsigned int src_align = get_pointer_alignment (src); 3417 unsigned int dest_align = get_pointer_alignment (dest); 3418 rtx dest_mem, src_mem, len_rtx; 3419 3420 /* If either SRC or DEST is not a pointer type, don't do this 3421 operation in-line. */ 3422 if (dest_align == 0 || src_align == 0) 3423 return NULL_RTX; 3424 3425 /* If LEN is not constant, call the normal function. */ 3426 if (! tree_fits_uhwi_p (len)) 3427 return NULL_RTX; 3428 3429 len_rtx = expand_normal (len); 3430 src_str = c_getstr (src); 3431 3432 /* If SRC is a string constant and block move would be done 3433 by pieces, we can avoid loading the string from memory 3434 and only stored the computed constants. */ 3435 if (src_str 3436 && CONST_INT_P (len_rtx) 3437 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1 3438 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str, 3439 CONST_CAST (char *, src_str), 3440 dest_align, false)) 3441 { 3442 dest_mem = get_memory_rtx (dest, len); 3443 set_mem_align (dest_mem, dest_align); 3444 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx), 3445 builtin_memcpy_read_str, 3446 CONST_CAST (char *, src_str), 3447 dest_align, false, endp); 3448 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3449 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3450 return dest_mem; 3451 } 3452 3453 if (CONST_INT_P (len_rtx) 3454 && can_move_by_pieces (INTVAL (len_rtx), 3455 MIN (dest_align, src_align))) 3456 { 3457 dest_mem = get_memory_rtx (dest, len); 3458 set_mem_align (dest_mem, dest_align); 3459 src_mem = get_memory_rtx (src, len); 3460 set_mem_align (src_mem, src_align); 3461 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx), 3462 MIN (dest_align, src_align), endp); 3463 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3464 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3465 return dest_mem; 3466 } 3467 3468 return NULL_RTX; 3469 } 3470} 3471 3472#ifndef HAVE_movstr 3473# define HAVE_movstr 0 3474# define CODE_FOR_movstr CODE_FOR_nothing 3475#endif 3476 3477/* Expand into a movstr instruction, if one is available. Return NULL_RTX if 3478 we failed, the caller should emit a normal call, otherwise try to 3479 get the result in TARGET, if convenient. If ENDP is 0 return the 3480 destination pointer, if ENDP is 1 return the end pointer ala 3481 mempcpy, and if ENDP is 2 return the end pointer minus one ala 3482 stpcpy. */ 3483 3484static rtx 3485expand_movstr (tree dest, tree src, rtx target, int endp) 3486{ 3487 struct expand_operand ops[3]; 3488 rtx dest_mem; 3489 rtx src_mem; 3490 3491 if (!HAVE_movstr) 3492 return NULL_RTX; 3493 3494 dest_mem = get_memory_rtx (dest, NULL); 3495 src_mem = get_memory_rtx (src, NULL); 3496 if (!endp) 3497 { 3498 target = force_reg (Pmode, XEXP (dest_mem, 0)); 3499 dest_mem = replace_equiv_address (dest_mem, target); 3500 } 3501 3502 create_output_operand (&ops[0], endp ? target : NULL_RTX, Pmode); 3503 create_fixed_operand (&ops[1], dest_mem); 3504 create_fixed_operand (&ops[2], src_mem); 3505 if (!maybe_expand_insn (CODE_FOR_movstr, 3, ops)) 3506 return NULL_RTX; 3507 3508 if (endp && target != const0_rtx) 3509 { 3510 target = ops[0].value; 3511 /* movstr is supposed to set end to the address of the NUL 3512 terminator. If the caller requested a mempcpy-like return value, 3513 adjust it. */ 3514 if (endp == 1) 3515 { 3516 rtx tem = plus_constant (GET_MODE (target), 3517 gen_lowpart (GET_MODE (target), target), 1); 3518 emit_move_insn (target, force_operand (tem, NULL_RTX)); 3519 } 3520 } 3521 return target; 3522} 3523 3524/* Expand expression EXP, which is a call to the strcpy builtin. Return 3525 NULL_RTX if we failed the caller should emit a normal call, otherwise 3526 try to get the result in TARGET, if convenient (and in mode MODE if that's 3527 convenient). */ 3528 3529static rtx 3530expand_builtin_strcpy (tree exp, rtx target) 3531{ 3532 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3533 { 3534 tree dest = CALL_EXPR_ARG (exp, 0); 3535 tree src = CALL_EXPR_ARG (exp, 1); 3536 return expand_builtin_strcpy_args (dest, src, target); 3537 } 3538 return NULL_RTX; 3539} 3540 3541/* Helper function to do the actual work for expand_builtin_strcpy. The 3542 arguments to the builtin_strcpy call DEST and SRC are broken out 3543 so that this can also be called without constructing an actual CALL_EXPR. 3544 The other arguments and return value are the same as for 3545 expand_builtin_strcpy. */ 3546 3547static rtx 3548expand_builtin_strcpy_args (tree dest, tree src, rtx target) 3549{ 3550 return expand_movstr (dest, src, target, /*endp=*/0); 3551} 3552 3553/* Expand a call EXP to the stpcpy builtin. 3554 Return NULL_RTX if we failed the caller should emit a normal call, 3555 otherwise try to get the result in TARGET, if convenient (and in 3556 mode MODE if that's convenient). */ 3557 3558static rtx 3559expand_builtin_stpcpy (tree exp, rtx target, machine_mode mode) 3560{ 3561 tree dst, src; 3562 location_t loc = EXPR_LOCATION (exp); 3563 3564 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3565 return NULL_RTX; 3566 3567 dst = CALL_EXPR_ARG (exp, 0); 3568 src = CALL_EXPR_ARG (exp, 1); 3569 3570 /* If return value is ignored, transform stpcpy into strcpy. */ 3571 if (target == const0_rtx && builtin_decl_implicit (BUILT_IN_STRCPY)) 3572 { 3573 tree fn = builtin_decl_implicit (BUILT_IN_STRCPY); 3574 tree result = build_call_nofold_loc (loc, fn, 2, dst, src); 3575 return expand_expr (result, target, mode, EXPAND_NORMAL); 3576 } 3577 else 3578 { 3579 tree len, lenp1; 3580 rtx ret; 3581 3582 /* Ensure we get an actual string whose length can be evaluated at 3583 compile-time, not an expression containing a string. This is 3584 because the latter will potentially produce pessimized code 3585 when used to produce the return value. */ 3586 if (! c_getstr (src) || ! (len = c_strlen (src, 0))) 3587 return expand_movstr (dst, src, target, /*endp=*/2); 3588 3589 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1)); 3590 ret = expand_builtin_mempcpy_args (dst, src, lenp1, 3591 target, mode, /*endp=*/2, 3592 exp); 3593 3594 if (ret) 3595 return ret; 3596 3597 if (TREE_CODE (len) == INTEGER_CST) 3598 { 3599 rtx len_rtx = expand_normal (len); 3600 3601 if (CONST_INT_P (len_rtx)) 3602 { 3603 ret = expand_builtin_strcpy_args (dst, src, target); 3604 3605 if (ret) 3606 { 3607 if (! target) 3608 { 3609 if (mode != VOIDmode) 3610 target = gen_reg_rtx (mode); 3611 else 3612 target = gen_reg_rtx (GET_MODE (ret)); 3613 } 3614 if (GET_MODE (target) != GET_MODE (ret)) 3615 ret = gen_lowpart (GET_MODE (target), ret); 3616 3617 ret = plus_constant (GET_MODE (ret), ret, INTVAL (len_rtx)); 3618 ret = emit_move_insn (target, force_operand (ret, NULL_RTX)); 3619 gcc_assert (ret); 3620 3621 return target; 3622 } 3623 } 3624 } 3625 3626 return expand_movstr (dst, src, target, /*endp=*/2); 3627 } 3628} 3629 3630/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 3631 bytes from constant string DATA + OFFSET and return it as target 3632 constant. */ 3633 3634rtx 3635builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset, 3636 machine_mode mode) 3637{ 3638 const char *str = (const char *) data; 3639 3640 if ((unsigned HOST_WIDE_INT) offset > strlen (str)) 3641 return const0_rtx; 3642 3643 return c_readstr (str + offset, mode); 3644} 3645 3646/* Expand expression EXP, which is a call to the strncpy builtin. Return 3647 NULL_RTX if we failed the caller should emit a normal call. */ 3648 3649static rtx 3650expand_builtin_strncpy (tree exp, rtx target) 3651{ 3652 location_t loc = EXPR_LOCATION (exp); 3653 3654 if (validate_arglist (exp, 3655 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3656 { 3657 tree dest = CALL_EXPR_ARG (exp, 0); 3658 tree src = CALL_EXPR_ARG (exp, 1); 3659 tree len = CALL_EXPR_ARG (exp, 2); 3660 tree slen = c_strlen (src, 1); 3661 3662 /* We must be passed a constant len and src parameter. */ 3663 if (!tree_fits_uhwi_p (len) || !slen || !tree_fits_uhwi_p (slen)) 3664 return NULL_RTX; 3665 3666 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1)); 3667 3668 /* We're required to pad with trailing zeros if the requested 3669 len is greater than strlen(s2)+1. In that case try to 3670 use store_by_pieces, if it fails, punt. */ 3671 if (tree_int_cst_lt (slen, len)) 3672 { 3673 unsigned int dest_align = get_pointer_alignment (dest); 3674 const char *p = c_getstr (src); 3675 rtx dest_mem; 3676 3677 if (!p || dest_align == 0 || !tree_fits_uhwi_p (len) 3678 || !can_store_by_pieces (tree_to_uhwi (len), 3679 builtin_strncpy_read_str, 3680 CONST_CAST (char *, p), 3681 dest_align, false)) 3682 return NULL_RTX; 3683 3684 dest_mem = get_memory_rtx (dest, len); 3685 store_by_pieces (dest_mem, tree_to_uhwi (len), 3686 builtin_strncpy_read_str, 3687 CONST_CAST (char *, p), dest_align, false, 0); 3688 dest_mem = force_operand (XEXP (dest_mem, 0), target); 3689 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3690 return dest_mem; 3691 } 3692 } 3693 return NULL_RTX; 3694} 3695 3696/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 3697 bytes from constant string DATA + OFFSET and return it as target 3698 constant. */ 3699 3700rtx 3701builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED, 3702 machine_mode mode) 3703{ 3704 const char *c = (const char *) data; 3705 char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode)); 3706 3707 memset (p, *c, GET_MODE_SIZE (mode)); 3708 3709 return c_readstr (p, mode); 3710} 3711 3712/* Callback routine for store_by_pieces. Return the RTL of a register 3713 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned 3714 char value given in the RTL register data. For example, if mode is 3715 4 bytes wide, return the RTL for 0x01010101*data. */ 3716 3717static rtx 3718builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED, 3719 machine_mode mode) 3720{ 3721 rtx target, coeff; 3722 size_t size; 3723 char *p; 3724 3725 size = GET_MODE_SIZE (mode); 3726 if (size == 1) 3727 return (rtx) data; 3728 3729 p = XALLOCAVEC (char, size); 3730 memset (p, 1, size); 3731 coeff = c_readstr (p, mode); 3732 3733 target = convert_to_mode (mode, (rtx) data, 1); 3734 target = expand_mult (mode, target, coeff, NULL_RTX, 1); 3735 return force_reg (mode, target); 3736} 3737 3738/* Expand expression EXP, which is a call to the memset builtin. Return 3739 NULL_RTX if we failed the caller should emit a normal call, otherwise 3740 try to get the result in TARGET, if convenient (and in mode MODE if that's 3741 convenient). */ 3742 3743static rtx 3744expand_builtin_memset (tree exp, rtx target, machine_mode mode) 3745{ 3746 if (!validate_arglist (exp, 3747 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3748 return NULL_RTX; 3749 else 3750 { 3751 tree dest = CALL_EXPR_ARG (exp, 0); 3752 tree val = CALL_EXPR_ARG (exp, 1); 3753 tree len = CALL_EXPR_ARG (exp, 2); 3754 return expand_builtin_memset_args (dest, val, len, target, mode, exp); 3755 } 3756} 3757 3758/* Expand expression EXP, which is an instrumented call to the memset builtin. 3759 Return NULL_RTX if we failed the caller should emit a normal call, otherwise 3760 try to get the result in TARGET, if convenient (and in mode MODE if that's 3761 convenient). */ 3762 3763static rtx 3764expand_builtin_memset_with_bounds (tree exp, rtx target, machine_mode mode) 3765{ 3766 if (!validate_arglist (exp, 3767 POINTER_TYPE, POINTER_BOUNDS_TYPE, 3768 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3769 return NULL_RTX; 3770 else 3771 { 3772 tree dest = CALL_EXPR_ARG (exp, 0); 3773 tree val = CALL_EXPR_ARG (exp, 2); 3774 tree len = CALL_EXPR_ARG (exp, 3); 3775 rtx res = expand_builtin_memset_args (dest, val, len, target, mode, exp); 3776 3777 /* Return src bounds with the result. */ 3778 if (res) 3779 { 3780 rtx bnd = force_reg (targetm.chkp_bound_mode (), 3781 expand_normal (CALL_EXPR_ARG (exp, 1))); 3782 res = chkp_join_splitted_slot (res, bnd); 3783 } 3784 return res; 3785 } 3786} 3787 3788/* Helper function to do the actual work for expand_builtin_memset. The 3789 arguments to the builtin_memset call DEST, VAL, and LEN are broken out 3790 so that this can also be called without constructing an actual CALL_EXPR. 3791 The other arguments and return value are the same as for 3792 expand_builtin_memset. */ 3793 3794static rtx 3795expand_builtin_memset_args (tree dest, tree val, tree len, 3796 rtx target, machine_mode mode, tree orig_exp) 3797{ 3798 tree fndecl, fn; 3799 enum built_in_function fcode; 3800 machine_mode val_mode; 3801 char c; 3802 unsigned int dest_align; 3803 rtx dest_mem, dest_addr, len_rtx; 3804 HOST_WIDE_INT expected_size = -1; 3805 unsigned int expected_align = 0; 3806 unsigned HOST_WIDE_INT min_size; 3807 unsigned HOST_WIDE_INT max_size; 3808 unsigned HOST_WIDE_INT probable_max_size; 3809 3810 dest_align = get_pointer_alignment (dest); 3811 3812 /* If DEST is not a pointer type, don't do this operation in-line. */ 3813 if (dest_align == 0) 3814 return NULL_RTX; 3815 3816 if (currently_expanding_gimple_stmt) 3817 stringop_block_profile (currently_expanding_gimple_stmt, 3818 &expected_align, &expected_size); 3819 3820 if (expected_align < dest_align) 3821 expected_align = dest_align; 3822 3823 /* If the LEN parameter is zero, return DEST. */ 3824 if (integer_zerop (len)) 3825 { 3826 /* Evaluate and ignore VAL in case it has side-effects. */ 3827 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL); 3828 return expand_expr (dest, target, mode, EXPAND_NORMAL); 3829 } 3830 3831 /* Stabilize the arguments in case we fail. */ 3832 dest = builtin_save_expr (dest); 3833 val = builtin_save_expr (val); 3834 len = builtin_save_expr (len); 3835 3836 len_rtx = expand_normal (len); 3837 determine_block_size (len, len_rtx, &min_size, &max_size, 3838 &probable_max_size); 3839 dest_mem = get_memory_rtx (dest, len); 3840 val_mode = TYPE_MODE (unsigned_char_type_node); 3841 3842 if (TREE_CODE (val) != INTEGER_CST) 3843 { 3844 rtx val_rtx; 3845 3846 val_rtx = expand_normal (val); 3847 val_rtx = convert_to_mode (val_mode, val_rtx, 0); 3848 3849 /* Assume that we can memset by pieces if we can store 3850 * the coefficients by pieces (in the required modes). 3851 * We can't pass builtin_memset_gen_str as that emits RTL. */ 3852 c = 1; 3853 if (tree_fits_uhwi_p (len) 3854 && can_store_by_pieces (tree_to_uhwi (len), 3855 builtin_memset_read_str, &c, dest_align, 3856 true)) 3857 { 3858 val_rtx = force_reg (val_mode, val_rtx); 3859 store_by_pieces (dest_mem, tree_to_uhwi (len), 3860 builtin_memset_gen_str, val_rtx, dest_align, 3861 true, 0); 3862 } 3863 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx, 3864 dest_align, expected_align, 3865 expected_size, min_size, max_size, 3866 probable_max_size)) 3867 goto do_libcall; 3868 3869 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3870 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3871 return dest_mem; 3872 } 3873 3874 if (target_char_cast (val, &c)) 3875 goto do_libcall; 3876 3877 if (c) 3878 { 3879 if (tree_fits_uhwi_p (len) 3880 && can_store_by_pieces (tree_to_uhwi (len), 3881 builtin_memset_read_str, &c, dest_align, 3882 true)) 3883 store_by_pieces (dest_mem, tree_to_uhwi (len), 3884 builtin_memset_read_str, &c, dest_align, true, 0); 3885 else if (!set_storage_via_setmem (dest_mem, len_rtx, 3886 gen_int_mode (c, val_mode), 3887 dest_align, expected_align, 3888 expected_size, min_size, max_size, 3889 probable_max_size)) 3890 goto do_libcall; 3891 3892 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3893 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3894 return dest_mem; 3895 } 3896 3897 set_mem_align (dest_mem, dest_align); 3898 dest_addr = clear_storage_hints (dest_mem, len_rtx, 3899 CALL_EXPR_TAILCALL (orig_exp) 3900 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL, 3901 expected_align, expected_size, 3902 min_size, max_size, 3903 probable_max_size); 3904 3905 if (dest_addr == 0) 3906 { 3907 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3908 dest_addr = convert_memory_address (ptr_mode, dest_addr); 3909 } 3910 3911 return dest_addr; 3912 3913 do_libcall: 3914 fndecl = get_callee_fndecl (orig_exp); 3915 fcode = DECL_FUNCTION_CODE (fndecl); 3916 if (fcode == BUILT_IN_MEMSET 3917 || fcode == BUILT_IN_CHKP_MEMSET_NOBND_NOCHK_CHKP) 3918 fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3, 3919 dest, val, len); 3920 else if (fcode == BUILT_IN_BZERO) 3921 fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 2, 3922 dest, len); 3923 else 3924 gcc_unreachable (); 3925 gcc_assert (TREE_CODE (fn) == CALL_EXPR); 3926 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp); 3927 return expand_call (fn, target, target == const0_rtx); 3928} 3929 3930/* Expand expression EXP, which is a call to the bzero builtin. Return 3931 NULL_RTX if we failed the caller should emit a normal call. */ 3932 3933static rtx 3934expand_builtin_bzero (tree exp) 3935{ 3936 tree dest, size; 3937 location_t loc = EXPR_LOCATION (exp); 3938 3939 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3940 return NULL_RTX; 3941 3942 dest = CALL_EXPR_ARG (exp, 0); 3943 size = CALL_EXPR_ARG (exp, 1); 3944 3945 /* New argument list transforming bzero(ptr x, int y) to 3946 memset(ptr x, int 0, size_t y). This is done this way 3947 so that if it isn't expanded inline, we fallback to 3948 calling bzero instead of memset. */ 3949 3950 return expand_builtin_memset_args (dest, integer_zero_node, 3951 fold_convert_loc (loc, 3952 size_type_node, size), 3953 const0_rtx, VOIDmode, exp); 3954} 3955 3956/* Expand expression EXP, which is a call to the memcmp built-in function. 3957 Return NULL_RTX if we failed and the caller should emit a normal call, 3958 otherwise try to get the result in TARGET, if convenient (and in mode 3959 MODE, if that's convenient). */ 3960 3961static rtx 3962expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target, 3963 ATTRIBUTE_UNUSED machine_mode mode) 3964{ 3965 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp); 3966 3967 if (!validate_arglist (exp, 3968 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3969 return NULL_RTX; 3970 3971 /* Note: The cmpstrnsi pattern, if it exists, is not suitable for 3972 implementing memcmp because it will stop if it encounters two 3973 zero bytes. */ 3974#if defined HAVE_cmpmemsi 3975 { 3976 rtx arg1_rtx, arg2_rtx, arg3_rtx; 3977 rtx result; 3978 rtx insn; 3979 tree arg1 = CALL_EXPR_ARG (exp, 0); 3980 tree arg2 = CALL_EXPR_ARG (exp, 1); 3981 tree len = CALL_EXPR_ARG (exp, 2); 3982 3983 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; 3984 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; 3985 machine_mode insn_mode; 3986 3987 if (HAVE_cmpmemsi) 3988 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode; 3989 else 3990 return NULL_RTX; 3991 3992 /* If we don't have POINTER_TYPE, call the function. */ 3993 if (arg1_align == 0 || arg2_align == 0) 3994 return NULL_RTX; 3995 3996 /* Make a place to write the result of the instruction. */ 3997 result = target; 3998 if (! (result != 0 3999 && REG_P (result) && GET_MODE (result) == insn_mode 4000 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 4001 result = gen_reg_rtx (insn_mode); 4002 4003 arg1_rtx = get_memory_rtx (arg1, len); 4004 arg2_rtx = get_memory_rtx (arg2, len); 4005 arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len)); 4006 4007 /* Set MEM_SIZE as appropriate. */ 4008 if (CONST_INT_P (arg3_rtx)) 4009 { 4010 set_mem_size (arg1_rtx, INTVAL (arg3_rtx)); 4011 set_mem_size (arg2_rtx, INTVAL (arg3_rtx)); 4012 } 4013 4014 if (HAVE_cmpmemsi) 4015 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 4016 GEN_INT (MIN (arg1_align, arg2_align))); 4017 else 4018 gcc_unreachable (); 4019 4020 if (insn) 4021 emit_insn (insn); 4022 else 4023 emit_library_call_value (memcmp_libfunc, result, LCT_PURE, 4024 TYPE_MODE (integer_type_node), 3, 4025 XEXP (arg1_rtx, 0), Pmode, 4026 XEXP (arg2_rtx, 0), Pmode, 4027 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx, 4028 TYPE_UNSIGNED (sizetype)), 4029 TYPE_MODE (sizetype)); 4030 4031 /* Return the value in the proper mode for this function. */ 4032 mode = TYPE_MODE (TREE_TYPE (exp)); 4033 if (GET_MODE (result) == mode) 4034 return result; 4035 else if (target != 0) 4036 { 4037 convert_move (target, result, 0); 4038 return target; 4039 } 4040 else 4041 return convert_to_mode (mode, result, 0); 4042 } 4043#endif /* HAVE_cmpmemsi. */ 4044 4045 return NULL_RTX; 4046} 4047 4048/* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX 4049 if we failed the caller should emit a normal call, otherwise try to get 4050 the result in TARGET, if convenient. */ 4051 4052static rtx 4053expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) 4054{ 4055 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 4056 return NULL_RTX; 4057 4058#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi 4059 if (direct_optab_handler (cmpstr_optab, SImode) != CODE_FOR_nothing 4060 || direct_optab_handler (cmpstrn_optab, SImode) != CODE_FOR_nothing) 4061 { 4062 rtx arg1_rtx, arg2_rtx; 4063 rtx result, insn = NULL_RTX; 4064 tree fndecl, fn; 4065 tree arg1 = CALL_EXPR_ARG (exp, 0); 4066 tree arg2 = CALL_EXPR_ARG (exp, 1); 4067 4068 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; 4069 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; 4070 4071 /* If we don't have POINTER_TYPE, call the function. */ 4072 if (arg1_align == 0 || arg2_align == 0) 4073 return NULL_RTX; 4074 4075 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */ 4076 arg1 = builtin_save_expr (arg1); 4077 arg2 = builtin_save_expr (arg2); 4078 4079 arg1_rtx = get_memory_rtx (arg1, NULL); 4080 arg2_rtx = get_memory_rtx (arg2, NULL); 4081 4082#ifdef HAVE_cmpstrsi 4083 /* Try to call cmpstrsi. */ 4084 if (HAVE_cmpstrsi) 4085 { 4086 machine_mode insn_mode 4087 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode; 4088 4089 /* Make a place to write the result of the instruction. */ 4090 result = target; 4091 if (! (result != 0 4092 && REG_P (result) && GET_MODE (result) == insn_mode 4093 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 4094 result = gen_reg_rtx (insn_mode); 4095 4096 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, 4097 GEN_INT (MIN (arg1_align, arg2_align))); 4098 } 4099#endif 4100#ifdef HAVE_cmpstrnsi 4101 /* Try to determine at least one length and call cmpstrnsi. */ 4102 if (!insn && HAVE_cmpstrnsi) 4103 { 4104 tree len; 4105 rtx arg3_rtx; 4106 4107 machine_mode insn_mode 4108 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode; 4109 tree len1 = c_strlen (arg1, 1); 4110 tree len2 = c_strlen (arg2, 1); 4111 4112 if (len1) 4113 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1); 4114 if (len2) 4115 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2); 4116 4117 /* If we don't have a constant length for the first, use the length 4118 of the second, if we know it. We don't require a constant for 4119 this case; some cost analysis could be done if both are available 4120 but neither is constant. For now, assume they're equally cheap, 4121 unless one has side effects. If both strings have constant lengths, 4122 use the smaller. */ 4123 4124 if (!len1) 4125 len = len2; 4126 else if (!len2) 4127 len = len1; 4128 else if (TREE_SIDE_EFFECTS (len1)) 4129 len = len2; 4130 else if (TREE_SIDE_EFFECTS (len2)) 4131 len = len1; 4132 else if (TREE_CODE (len1) != INTEGER_CST) 4133 len = len2; 4134 else if (TREE_CODE (len2) != INTEGER_CST) 4135 len = len1; 4136 else if (tree_int_cst_lt (len1, len2)) 4137 len = len1; 4138 else 4139 len = len2; 4140 4141 /* If both arguments have side effects, we cannot optimize. */ 4142 if (!len || TREE_SIDE_EFFECTS (len)) 4143 goto do_libcall; 4144 4145 arg3_rtx = expand_normal (len); 4146 4147 /* Make a place to write the result of the instruction. */ 4148 result = target; 4149 if (! (result != 0 4150 && REG_P (result) && GET_MODE (result) == insn_mode 4151 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 4152 result = gen_reg_rtx (insn_mode); 4153 4154 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 4155 GEN_INT (MIN (arg1_align, arg2_align))); 4156 } 4157#endif 4158 4159 if (insn) 4160 { 4161 machine_mode mode; 4162 emit_insn (insn); 4163 4164 /* Return the value in the proper mode for this function. */ 4165 mode = TYPE_MODE (TREE_TYPE (exp)); 4166 if (GET_MODE (result) == mode) 4167 return result; 4168 if (target == 0) 4169 return convert_to_mode (mode, result, 0); 4170 convert_move (target, result, 0); 4171 return target; 4172 } 4173 4174 /* Expand the library call ourselves using a stabilized argument 4175 list to avoid re-evaluating the function's arguments twice. */ 4176#ifdef HAVE_cmpstrnsi 4177 do_libcall: 4178#endif 4179 fndecl = get_callee_fndecl (exp); 4180 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2); 4181 gcc_assert (TREE_CODE (fn) == CALL_EXPR); 4182 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 4183 return expand_call (fn, target, target == const0_rtx); 4184 } 4185#endif 4186 return NULL_RTX; 4187} 4188 4189/* Expand expression EXP, which is a call to the strncmp builtin. Return 4190 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get 4191 the result in TARGET, if convenient. */ 4192 4193static rtx 4194expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, 4195 ATTRIBUTE_UNUSED machine_mode mode) 4196{ 4197 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp); 4198 4199 if (!validate_arglist (exp, 4200 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 4201 return NULL_RTX; 4202 4203 /* If c_strlen can determine an expression for one of the string 4204 lengths, and it doesn't have side effects, then emit cmpstrnsi 4205 using length MIN(strlen(string)+1, arg3). */ 4206#ifdef HAVE_cmpstrnsi 4207 if (HAVE_cmpstrnsi) 4208 { 4209 tree len, len1, len2; 4210 rtx arg1_rtx, arg2_rtx, arg3_rtx; 4211 rtx result, insn; 4212 tree fndecl, fn; 4213 tree arg1 = CALL_EXPR_ARG (exp, 0); 4214 tree arg2 = CALL_EXPR_ARG (exp, 1); 4215 tree arg3 = CALL_EXPR_ARG (exp, 2); 4216 4217 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; 4218 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; 4219 machine_mode insn_mode 4220 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode; 4221 4222 len1 = c_strlen (arg1, 1); 4223 len2 = c_strlen (arg2, 1); 4224 4225 if (len1) 4226 len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1); 4227 if (len2) 4228 len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2); 4229 4230 /* If we don't have a constant length for the first, use the length 4231 of the second, if we know it. We don't require a constant for 4232 this case; some cost analysis could be done if both are available 4233 but neither is constant. For now, assume they're equally cheap, 4234 unless one has side effects. If both strings have constant lengths, 4235 use the smaller. */ 4236 4237 if (!len1) 4238 len = len2; 4239 else if (!len2) 4240 len = len1; 4241 else if (TREE_SIDE_EFFECTS (len1)) 4242 len = len2; 4243 else if (TREE_SIDE_EFFECTS (len2)) 4244 len = len1; 4245 else if (TREE_CODE (len1) != INTEGER_CST) 4246 len = len2; 4247 else if (TREE_CODE (len2) != INTEGER_CST) 4248 len = len1; 4249 else if (tree_int_cst_lt (len1, len2)) 4250 len = len1; 4251 else 4252 len = len2; 4253 4254 /* If both arguments have side effects, we cannot optimize. */ 4255 if (!len || TREE_SIDE_EFFECTS (len)) 4256 return NULL_RTX; 4257 4258 /* The actual new length parameter is MIN(len,arg3). */ 4259 len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len, 4260 fold_convert_loc (loc, TREE_TYPE (len), arg3)); 4261 4262 /* If we don't have POINTER_TYPE, call the function. */ 4263 if (arg1_align == 0 || arg2_align == 0) 4264 return NULL_RTX; 4265 4266 /* Make a place to write the result of the instruction. */ 4267 result = target; 4268 if (! (result != 0 4269 && REG_P (result) && GET_MODE (result) == insn_mode 4270 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 4271 result = gen_reg_rtx (insn_mode); 4272 4273 /* Stabilize the arguments in case gen_cmpstrnsi fails. */ 4274 arg1 = builtin_save_expr (arg1); 4275 arg2 = builtin_save_expr (arg2); 4276 len = builtin_save_expr (len); 4277 4278 arg1_rtx = get_memory_rtx (arg1, len); 4279 arg2_rtx = get_memory_rtx (arg2, len); 4280 arg3_rtx = expand_normal (len); 4281 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 4282 GEN_INT (MIN (arg1_align, arg2_align))); 4283 if (insn) 4284 { 4285 emit_insn (insn); 4286 4287 /* Return the value in the proper mode for this function. */ 4288 mode = TYPE_MODE (TREE_TYPE (exp)); 4289 if (GET_MODE (result) == mode) 4290 return result; 4291 if (target == 0) 4292 return convert_to_mode (mode, result, 0); 4293 convert_move (target, result, 0); 4294 return target; 4295 } 4296 4297 /* Expand the library call ourselves using a stabilized argument 4298 list to avoid re-evaluating the function's arguments twice. */ 4299 fndecl = get_callee_fndecl (exp); 4300 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 3, 4301 arg1, arg2, len); 4302 gcc_assert (TREE_CODE (fn) == CALL_EXPR); 4303 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 4304 return expand_call (fn, target, target == const0_rtx); 4305 } 4306#endif 4307 return NULL_RTX; 4308} 4309 4310/* Expand a call to __builtin_saveregs, generating the result in TARGET, 4311 if that's convenient. */ 4312 4313rtx 4314expand_builtin_saveregs (void) 4315{ 4316 rtx val; 4317 rtx_insn *seq; 4318 4319 /* Don't do __builtin_saveregs more than once in a function. 4320 Save the result of the first call and reuse it. */ 4321 if (saveregs_value != 0) 4322 return saveregs_value; 4323 4324 /* When this function is called, it means that registers must be 4325 saved on entry to this function. So we migrate the call to the 4326 first insn of this function. */ 4327 4328 start_sequence (); 4329 4330 /* Do whatever the machine needs done in this case. */ 4331 val = targetm.calls.expand_builtin_saveregs (); 4332 4333 seq = get_insns (); 4334 end_sequence (); 4335 4336 saveregs_value = val; 4337 4338 /* Put the insns after the NOTE that starts the function. If this 4339 is inside a start_sequence, make the outer-level insn chain current, so 4340 the code is placed at the start of the function. */ 4341 push_topmost_sequence (); 4342 emit_insn_after (seq, entry_of_function ()); 4343 pop_topmost_sequence (); 4344 4345 return val; 4346} 4347 4348/* Expand a call to __builtin_next_arg. */ 4349 4350static rtx 4351expand_builtin_next_arg (void) 4352{ 4353 /* Checking arguments is already done in fold_builtin_next_arg 4354 that must be called before this function. */ 4355 return expand_binop (ptr_mode, add_optab, 4356 crtl->args.internal_arg_pointer, 4357 crtl->args.arg_offset_rtx, 4358 NULL_RTX, 0, OPTAB_LIB_WIDEN); 4359} 4360 4361/* Make it easier for the backends by protecting the valist argument 4362 from multiple evaluations. */ 4363 4364static tree 4365stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue) 4366{ 4367 tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist)); 4368 4369 /* The current way of determining the type of valist is completely 4370 bogus. We should have the information on the va builtin instead. */ 4371 if (!vatype) 4372 vatype = targetm.fn_abi_va_list (cfun->decl); 4373 4374 if (TREE_CODE (vatype) == ARRAY_TYPE) 4375 { 4376 if (TREE_SIDE_EFFECTS (valist)) 4377 valist = save_expr (valist); 4378 4379 /* For this case, the backends will be expecting a pointer to 4380 vatype, but it's possible we've actually been given an array 4381 (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)). 4382 So fix it. */ 4383 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE) 4384 { 4385 tree p1 = build_pointer_type (TREE_TYPE (vatype)); 4386 valist = build_fold_addr_expr_with_type_loc (loc, valist, p1); 4387 } 4388 } 4389 else 4390 { 4391 tree pt = build_pointer_type (vatype); 4392 4393 if (! needs_lvalue) 4394 { 4395 if (! TREE_SIDE_EFFECTS (valist)) 4396 return valist; 4397 4398 valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist); 4399 TREE_SIDE_EFFECTS (valist) = 1; 4400 } 4401 4402 if (TREE_SIDE_EFFECTS (valist)) 4403 valist = save_expr (valist); 4404 valist = fold_build2_loc (loc, MEM_REF, 4405 vatype, valist, build_int_cst (pt, 0)); 4406 } 4407 4408 return valist; 4409} 4410 4411/* The "standard" definition of va_list is void*. */ 4412 4413tree 4414std_build_builtin_va_list (void) 4415{ 4416 return ptr_type_node; 4417} 4418 4419/* The "standard" abi va_list is va_list_type_node. */ 4420 4421tree 4422std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED) 4423{ 4424 return va_list_type_node; 4425} 4426 4427/* The "standard" type of va_list is va_list_type_node. */ 4428 4429tree 4430std_canonical_va_list_type (tree type) 4431{ 4432 tree wtype, htype; 4433 4434 if (INDIRECT_REF_P (type)) 4435 type = TREE_TYPE (type); 4436 else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE (type))) 4437 type = TREE_TYPE (type); 4438 wtype = va_list_type_node; 4439 htype = type; 4440 /* Treat structure va_list types. */ 4441 if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype)) 4442 htype = TREE_TYPE (htype); 4443 else if (TREE_CODE (wtype) == ARRAY_TYPE) 4444 { 4445 /* If va_list is an array type, the argument may have decayed 4446 to a pointer type, e.g. by being passed to another function. 4447 In that case, unwrap both types so that we can compare the 4448 underlying records. */ 4449 if (TREE_CODE (htype) == ARRAY_TYPE 4450 || POINTER_TYPE_P (htype)) 4451 { 4452 wtype = TREE_TYPE (wtype); 4453 htype = TREE_TYPE (htype); 4454 } 4455 } 4456 if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype)) 4457 return va_list_type_node; 4458 4459 return NULL_TREE; 4460} 4461 4462/* The "standard" implementation of va_start: just assign `nextarg' to 4463 the variable. */ 4464 4465void 4466std_expand_builtin_va_start (tree valist, rtx nextarg) 4467{ 4468 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE); 4469 convert_move (va_r, nextarg, 0); 4470 4471 /* We do not have any valid bounds for the pointer, so 4472 just store zero bounds for it. */ 4473 if (chkp_function_instrumented_p (current_function_decl)) 4474 chkp_expand_bounds_reset_for_mem (valist, 4475 make_tree (TREE_TYPE (valist), 4476 nextarg)); 4477} 4478 4479/* Expand EXP, a call to __builtin_va_start. */ 4480 4481static rtx 4482expand_builtin_va_start (tree exp) 4483{ 4484 rtx nextarg; 4485 tree valist; 4486 location_t loc = EXPR_LOCATION (exp); 4487 4488 if (call_expr_nargs (exp) < 2) 4489 { 4490 error_at (loc, "too few arguments to function %<va_start%>"); 4491 return const0_rtx; 4492 } 4493 4494 if (fold_builtin_next_arg (exp, true)) 4495 return const0_rtx; 4496 4497 nextarg = expand_builtin_next_arg (); 4498 valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1); 4499 4500 if (targetm.expand_builtin_va_start) 4501 targetm.expand_builtin_va_start (valist, nextarg); 4502 else 4503 std_expand_builtin_va_start (valist, nextarg); 4504 4505 return const0_rtx; 4506} 4507 4508/* Expand EXP, a call to __builtin_va_end. */ 4509 4510static rtx 4511expand_builtin_va_end (tree exp) 4512{ 4513 tree valist = CALL_EXPR_ARG (exp, 0); 4514 4515 /* Evaluate for side effects, if needed. I hate macros that don't 4516 do that. */ 4517 if (TREE_SIDE_EFFECTS (valist)) 4518 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL); 4519 4520 return const0_rtx; 4521} 4522 4523/* Expand EXP, a call to __builtin_va_copy. We do this as a 4524 builtin rather than just as an assignment in stdarg.h because of the 4525 nastiness of array-type va_list types. */ 4526 4527static rtx 4528expand_builtin_va_copy (tree exp) 4529{ 4530 tree dst, src, t; 4531 location_t loc = EXPR_LOCATION (exp); 4532 4533 dst = CALL_EXPR_ARG (exp, 0); 4534 src = CALL_EXPR_ARG (exp, 1); 4535 4536 dst = stabilize_va_list_loc (loc, dst, 1); 4537 src = stabilize_va_list_loc (loc, src, 0); 4538 4539 gcc_assert (cfun != NULL && cfun->decl != NULL_TREE); 4540 4541 if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE) 4542 { 4543 t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src); 4544 TREE_SIDE_EFFECTS (t) = 1; 4545 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 4546 } 4547 else 4548 { 4549 rtx dstb, srcb, size; 4550 4551 /* Evaluate to pointers. */ 4552 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL); 4553 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL); 4554 size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)), 4555 NULL_RTX, VOIDmode, EXPAND_NORMAL); 4556 4557 dstb = convert_memory_address (Pmode, dstb); 4558 srcb = convert_memory_address (Pmode, srcb); 4559 4560 /* "Dereference" to BLKmode memories. */ 4561 dstb = gen_rtx_MEM (BLKmode, dstb); 4562 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst)))); 4563 set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl))); 4564 srcb = gen_rtx_MEM (BLKmode, srcb); 4565 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src)))); 4566 set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl))); 4567 4568 /* Copy. */ 4569 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL); 4570 } 4571 4572 return const0_rtx; 4573} 4574 4575/* Expand a call to one of the builtin functions __builtin_frame_address or 4576 __builtin_return_address. */ 4577 4578static rtx 4579expand_builtin_frame_address (tree fndecl, tree exp) 4580{ 4581 /* The argument must be a nonnegative integer constant. 4582 It counts the number of frames to scan up the stack. 4583 The value is the return address saved in that frame. */ 4584 if (call_expr_nargs (exp) == 0) 4585 /* Warning about missing arg was already issued. */ 4586 return const0_rtx; 4587 else if (! tree_fits_uhwi_p (CALL_EXPR_ARG (exp, 0))) 4588 { 4589 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4590 error ("invalid argument to %<__builtin_frame_address%>"); 4591 else 4592 error ("invalid argument to %<__builtin_return_address%>"); 4593 return const0_rtx; 4594 } 4595 else 4596 { 4597 rtx tem 4598 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl), 4599 tree_to_uhwi (CALL_EXPR_ARG (exp, 0))); 4600 4601 /* Some ports cannot access arbitrary stack frames. */ 4602 if (tem == NULL) 4603 { 4604 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4605 warning (0, "unsupported argument to %<__builtin_frame_address%>"); 4606 else 4607 warning (0, "unsupported argument to %<__builtin_return_address%>"); 4608 return const0_rtx; 4609 } 4610 4611 /* For __builtin_frame_address, return what we've got. */ 4612 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4613 return tem; 4614 4615 if (!REG_P (tem) 4616 && ! CONSTANT_P (tem)) 4617 tem = copy_addr_to_reg (tem); 4618 return tem; 4619 } 4620} 4621 4622/* Expand EXP, a call to the alloca builtin. Return NULL_RTX if we 4623 failed and the caller should emit a normal call. CANNOT_ACCUMULATE 4624 is the same as for allocate_dynamic_stack_space. */ 4625 4626static rtx 4627expand_builtin_alloca (tree exp, bool cannot_accumulate) 4628{ 4629 rtx op0; 4630 rtx result; 4631 bool valid_arglist; 4632 unsigned int align; 4633 bool alloca_with_align = (DECL_FUNCTION_CODE (get_callee_fndecl (exp)) 4634 == BUILT_IN_ALLOCA_WITH_ALIGN); 4635 4636 valid_arglist 4637 = (alloca_with_align 4638 ? validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE) 4639 : validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)); 4640 4641 if (!valid_arglist) 4642 return NULL_RTX; 4643 4644 /* Compute the argument. */ 4645 op0 = expand_normal (CALL_EXPR_ARG (exp, 0)); 4646 4647 /* Compute the alignment. */ 4648 align = (alloca_with_align 4649 ? TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1)) 4650 : BIGGEST_ALIGNMENT); 4651 4652 /* Allocate the desired space. */ 4653 result = allocate_dynamic_stack_space (op0, 0, align, cannot_accumulate); 4654 result = convert_memory_address (ptr_mode, result); 4655 4656 return result; 4657} 4658 4659/* Expand a call to bswap builtin in EXP. 4660 Return NULL_RTX if a normal call should be emitted rather than expanding the 4661 function in-line. If convenient, the result should be placed in TARGET. 4662 SUBTARGET may be used as the target for computing one of EXP's operands. */ 4663 4664static rtx 4665expand_builtin_bswap (machine_mode target_mode, tree exp, rtx target, 4666 rtx subtarget) 4667{ 4668 tree arg; 4669 rtx op0; 4670 4671 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)) 4672 return NULL_RTX; 4673 4674 arg = CALL_EXPR_ARG (exp, 0); 4675 op0 = expand_expr (arg, 4676 subtarget && GET_MODE (subtarget) == target_mode 4677 ? subtarget : NULL_RTX, 4678 target_mode, EXPAND_NORMAL); 4679 if (GET_MODE (op0) != target_mode) 4680 op0 = convert_to_mode (target_mode, op0, 1); 4681 4682 target = expand_unop (target_mode, bswap_optab, op0, target, 1); 4683 4684 gcc_assert (target); 4685 4686 return convert_to_mode (target_mode, target, 1); 4687} 4688 4689/* Expand a call to a unary builtin in EXP. 4690 Return NULL_RTX if a normal call should be emitted rather than expanding the 4691 function in-line. If convenient, the result should be placed in TARGET. 4692 SUBTARGET may be used as the target for computing one of EXP's operands. */ 4693 4694static rtx 4695expand_builtin_unop (machine_mode target_mode, tree exp, rtx target, 4696 rtx subtarget, optab op_optab) 4697{ 4698 rtx op0; 4699 4700 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)) 4701 return NULL_RTX; 4702 4703 /* Compute the argument. */ 4704 op0 = expand_expr (CALL_EXPR_ARG (exp, 0), 4705 (subtarget 4706 && (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))) 4707 == GET_MODE (subtarget))) ? subtarget : NULL_RTX, 4708 VOIDmode, EXPAND_NORMAL); 4709 /* Compute op, into TARGET if possible. 4710 Set TARGET to wherever the result comes back. */ 4711 target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))), 4712 op_optab, op0, target, op_optab != clrsb_optab); 4713 gcc_assert (target); 4714 4715 return convert_to_mode (target_mode, target, 0); 4716} 4717 4718/* Expand a call to __builtin_expect. We just return our argument 4719 as the builtin_expect semantic should've been already executed by 4720 tree branch prediction pass. */ 4721 4722static rtx 4723expand_builtin_expect (tree exp, rtx target) 4724{ 4725 tree arg; 4726 4727 if (call_expr_nargs (exp) < 2) 4728 return const0_rtx; 4729 arg = CALL_EXPR_ARG (exp, 0); 4730 4731 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL); 4732 /* When guessing was done, the hints should be already stripped away. */ 4733 gcc_assert (!flag_guess_branch_prob 4734 || optimize == 0 || seen_error ()); 4735 return target; 4736} 4737 4738/* Expand a call to __builtin_assume_aligned. We just return our first 4739 argument as the builtin_assume_aligned semantic should've been already 4740 executed by CCP. */ 4741 4742static rtx 4743expand_builtin_assume_aligned (tree exp, rtx target) 4744{ 4745 if (call_expr_nargs (exp) < 2) 4746 return const0_rtx; 4747 target = expand_expr (CALL_EXPR_ARG (exp, 0), target, VOIDmode, 4748 EXPAND_NORMAL); 4749 gcc_assert (!TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 1)) 4750 && (call_expr_nargs (exp) < 3 4751 || !TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 2)))); 4752 return target; 4753} 4754 4755void 4756expand_builtin_trap (void) 4757{ 4758#ifdef HAVE_trap 4759 if (HAVE_trap) 4760 { 4761 rtx insn = emit_insn (gen_trap ()); 4762 /* For trap insns when not accumulating outgoing args force 4763 REG_ARGS_SIZE note to prevent crossjumping of calls with 4764 different args sizes. */ 4765 if (!ACCUMULATE_OUTGOING_ARGS) 4766 add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta)); 4767 } 4768 else 4769#endif 4770 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0); 4771 emit_barrier (); 4772} 4773 4774/* Expand a call to __builtin_unreachable. We do nothing except emit 4775 a barrier saying that control flow will not pass here. 4776 4777 It is the responsibility of the program being compiled to ensure 4778 that control flow does never reach __builtin_unreachable. */ 4779static void 4780expand_builtin_unreachable (void) 4781{ 4782 emit_barrier (); 4783} 4784 4785/* Expand EXP, a call to fabs, fabsf or fabsl. 4786 Return NULL_RTX if a normal call should be emitted rather than expanding 4787 the function inline. If convenient, the result should be placed 4788 in TARGET. SUBTARGET may be used as the target for computing 4789 the operand. */ 4790 4791static rtx 4792expand_builtin_fabs (tree exp, rtx target, rtx subtarget) 4793{ 4794 machine_mode mode; 4795 tree arg; 4796 rtx op0; 4797 4798 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 4799 return NULL_RTX; 4800 4801 arg = CALL_EXPR_ARG (exp, 0); 4802 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 4803 mode = TYPE_MODE (TREE_TYPE (arg)); 4804 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 4805 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1)); 4806} 4807 4808/* Expand EXP, a call to copysign, copysignf, or copysignl. 4809 Return NULL is a normal call should be emitted rather than expanding the 4810 function inline. If convenient, the result should be placed in TARGET. 4811 SUBTARGET may be used as the target for computing the operand. */ 4812 4813static rtx 4814expand_builtin_copysign (tree exp, rtx target, rtx subtarget) 4815{ 4816 rtx op0, op1; 4817 tree arg; 4818 4819 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 4820 return NULL_RTX; 4821 4822 arg = CALL_EXPR_ARG (exp, 0); 4823 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 4824 4825 arg = CALL_EXPR_ARG (exp, 1); 4826 op1 = expand_normal (arg); 4827 4828 return expand_copysign (op0, op1, target); 4829} 4830 4831/* Expand a call to __builtin___clear_cache. */ 4832 4833static rtx 4834expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED) 4835{ 4836#ifndef HAVE_clear_cache 4837#ifdef CLEAR_INSN_CACHE 4838 /* There is no "clear_cache" insn, and __clear_cache() in libgcc 4839 does something. Just do the default expansion to a call to 4840 __clear_cache(). */ 4841 return NULL_RTX; 4842#else 4843 /* There is no "clear_cache" insn, and __clear_cache() in libgcc 4844 does nothing. There is no need to call it. Do nothing. */ 4845 return const0_rtx; 4846#endif /* CLEAR_INSN_CACHE */ 4847#else 4848 /* We have a "clear_cache" insn, and it will handle everything. */ 4849 tree begin, end; 4850 rtx begin_rtx, end_rtx; 4851 4852 /* We must not expand to a library call. If we did, any 4853 fallback library function in libgcc that might contain a call to 4854 __builtin___clear_cache() would recurse infinitely. */ 4855 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 4856 { 4857 error ("both arguments to %<__builtin___clear_cache%> must be pointers"); 4858 return const0_rtx; 4859 } 4860 4861 if (HAVE_clear_cache) 4862 { 4863 struct expand_operand ops[2]; 4864 4865 begin = CALL_EXPR_ARG (exp, 0); 4866 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL); 4867 4868 end = CALL_EXPR_ARG (exp, 1); 4869 end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL); 4870 4871 create_address_operand (&ops[0], begin_rtx); 4872 create_address_operand (&ops[1], end_rtx); 4873 if (maybe_expand_insn (CODE_FOR_clear_cache, 2, ops)) 4874 return const0_rtx; 4875 } 4876 return const0_rtx; 4877#endif /* HAVE_clear_cache */ 4878} 4879 4880/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */ 4881 4882static rtx 4883round_trampoline_addr (rtx tramp) 4884{ 4885 rtx temp, addend, mask; 4886 4887 /* If we don't need too much alignment, we'll have been guaranteed 4888 proper alignment by get_trampoline_type. */ 4889 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY) 4890 return tramp; 4891 4892 /* Round address up to desired boundary. */ 4893 temp = gen_reg_rtx (Pmode); 4894 addend = gen_int_mode (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1, Pmode); 4895 mask = gen_int_mode (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT, Pmode); 4896 4897 temp = expand_simple_binop (Pmode, PLUS, tramp, addend, 4898 temp, 0, OPTAB_LIB_WIDEN); 4899 tramp = expand_simple_binop (Pmode, AND, temp, mask, 4900 temp, 0, OPTAB_LIB_WIDEN); 4901 4902 return tramp; 4903} 4904 4905static rtx 4906expand_builtin_init_trampoline (tree exp, bool onstack) 4907{ 4908 tree t_tramp, t_func, t_chain; 4909 rtx m_tramp, r_tramp, r_chain, tmp; 4910 4911 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, 4912 POINTER_TYPE, VOID_TYPE)) 4913 return NULL_RTX; 4914 4915 t_tramp = CALL_EXPR_ARG (exp, 0); 4916 t_func = CALL_EXPR_ARG (exp, 1); 4917 t_chain = CALL_EXPR_ARG (exp, 2); 4918 4919 r_tramp = expand_normal (t_tramp); 4920 m_tramp = gen_rtx_MEM (BLKmode, r_tramp); 4921 MEM_NOTRAP_P (m_tramp) = 1; 4922 4923 /* If ONSTACK, the TRAMP argument should be the address of a field 4924 within the local function's FRAME decl. Either way, let's see if 4925 we can fill in the MEM_ATTRs for this memory. */ 4926 if (TREE_CODE (t_tramp) == ADDR_EXPR) 4927 set_mem_attributes (m_tramp, TREE_OPERAND (t_tramp, 0), true); 4928 4929 /* Creator of a heap trampoline is responsible for making sure the 4930 address is aligned to at least STACK_BOUNDARY. Normally malloc 4931 will ensure this anyhow. */ 4932 tmp = round_trampoline_addr (r_tramp); 4933 if (tmp != r_tramp) 4934 { 4935 m_tramp = change_address (m_tramp, BLKmode, tmp); 4936 set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT); 4937 set_mem_size (m_tramp, TRAMPOLINE_SIZE); 4938 } 4939 4940 /* The FUNC argument should be the address of the nested function. 4941 Extract the actual function decl to pass to the hook. */ 4942 gcc_assert (TREE_CODE (t_func) == ADDR_EXPR); 4943 t_func = TREE_OPERAND (t_func, 0); 4944 gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL); 4945 4946 r_chain = expand_normal (t_chain); 4947 4948 /* Generate insns to initialize the trampoline. */ 4949 targetm.calls.trampoline_init (m_tramp, t_func, r_chain); 4950 4951 if (onstack) 4952 { 4953 trampolines_created = 1; 4954 4955 warning_at (DECL_SOURCE_LOCATION (t_func), OPT_Wtrampolines, 4956 "trampoline generated for nested function %qD", t_func); 4957 } 4958 4959 return const0_rtx; 4960} 4961 4962static rtx 4963expand_builtin_adjust_trampoline (tree exp) 4964{ 4965 rtx tramp; 4966 4967 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 4968 return NULL_RTX; 4969 4970 tramp = expand_normal (CALL_EXPR_ARG (exp, 0)); 4971 tramp = round_trampoline_addr (tramp); 4972 if (targetm.calls.trampoline_adjust_address) 4973 tramp = targetm.calls.trampoline_adjust_address (tramp); 4974 4975 return tramp; 4976} 4977 4978/* Expand the call EXP to the built-in signbit, signbitf or signbitl 4979 function. The function first checks whether the back end provides 4980 an insn to implement signbit for the respective mode. If not, it 4981 checks whether the floating point format of the value is such that 4982 the sign bit can be extracted. If that is not the case, the 4983 function returns NULL_RTX to indicate that a normal call should be 4984 emitted rather than expanding the function in-line. EXP is the 4985 expression that is a call to the builtin function; if convenient, 4986 the result should be placed in TARGET. */ 4987static rtx 4988expand_builtin_signbit (tree exp, rtx target) 4989{ 4990 const struct real_format *fmt; 4991 machine_mode fmode, imode, rmode; 4992 tree arg; 4993 int word, bitpos; 4994 enum insn_code icode; 4995 rtx temp; 4996 location_t loc = EXPR_LOCATION (exp); 4997 4998 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 4999 return NULL_RTX; 5000 5001 arg = CALL_EXPR_ARG (exp, 0); 5002 fmode = TYPE_MODE (TREE_TYPE (arg)); 5003 rmode = TYPE_MODE (TREE_TYPE (exp)); 5004 fmt = REAL_MODE_FORMAT (fmode); 5005 5006 arg = builtin_save_expr (arg); 5007 5008 /* Expand the argument yielding a RTX expression. */ 5009 temp = expand_normal (arg); 5010 5011 /* Check if the back end provides an insn that handles signbit for the 5012 argument's mode. */ 5013 icode = optab_handler (signbit_optab, fmode); 5014 if (icode != CODE_FOR_nothing) 5015 { 5016 rtx_insn *last = get_last_insn (); 5017 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp))); 5018 if (maybe_emit_unop_insn (icode, target, temp, UNKNOWN)) 5019 return target; 5020 delete_insns_since (last); 5021 } 5022 5023 /* For floating point formats without a sign bit, implement signbit 5024 as "ARG < 0.0". */ 5025 bitpos = fmt->signbit_ro; 5026 if (bitpos < 0) 5027 { 5028 /* But we can't do this if the format supports signed zero. */ 5029 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode)) 5030 return NULL_RTX; 5031 5032 arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg, 5033 build_real (TREE_TYPE (arg), dconst0)); 5034 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL); 5035 } 5036 5037 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD) 5038 { 5039 imode = int_mode_for_mode (fmode); 5040 if (imode == BLKmode) 5041 return NULL_RTX; 5042 temp = gen_lowpart (imode, temp); 5043 } 5044 else 5045 { 5046 imode = word_mode; 5047 /* Handle targets with different FP word orders. */ 5048 if (FLOAT_WORDS_BIG_ENDIAN) 5049 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD; 5050 else 5051 word = bitpos / BITS_PER_WORD; 5052 temp = operand_subword_force (temp, word, fmode); 5053 bitpos = bitpos % BITS_PER_WORD; 5054 } 5055 5056 /* Force the intermediate word_mode (or narrower) result into a 5057 register. This avoids attempting to create paradoxical SUBREGs 5058 of floating point modes below. */ 5059 temp = force_reg (imode, temp); 5060 5061 /* If the bitpos is within the "result mode" lowpart, the operation 5062 can be implement with a single bitwise AND. Otherwise, we need 5063 a right shift and an AND. */ 5064 5065 if (bitpos < GET_MODE_BITSIZE (rmode)) 5066 { 5067 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (rmode)); 5068 5069 if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode)) 5070 temp = gen_lowpart (rmode, temp); 5071 temp = expand_binop (rmode, and_optab, temp, 5072 immed_wide_int_const (mask, rmode), 5073 NULL_RTX, 1, OPTAB_LIB_WIDEN); 5074 } 5075 else 5076 { 5077 /* Perform a logical right shift to place the signbit in the least 5078 significant bit, then truncate the result to the desired mode 5079 and mask just this bit. */ 5080 temp = expand_shift (RSHIFT_EXPR, imode, temp, bitpos, NULL_RTX, 1); 5081 temp = gen_lowpart (rmode, temp); 5082 temp = expand_binop (rmode, and_optab, temp, const1_rtx, 5083 NULL_RTX, 1, OPTAB_LIB_WIDEN); 5084 } 5085 5086 return temp; 5087} 5088 5089/* Expand fork or exec calls. TARGET is the desired target of the 5090 call. EXP is the call. FN is the 5091 identificator of the actual function. IGNORE is nonzero if the 5092 value is to be ignored. */ 5093 5094static rtx 5095expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore) 5096{ 5097 tree id, decl; 5098 tree call; 5099 5100 /* If we are not profiling, just call the function. */ 5101 if (!profile_arc_flag) 5102 return NULL_RTX; 5103 5104 /* Otherwise call the wrapper. This should be equivalent for the rest of 5105 compiler, so the code does not diverge, and the wrapper may run the 5106 code necessary for keeping the profiling sane. */ 5107 5108 switch (DECL_FUNCTION_CODE (fn)) 5109 { 5110 case BUILT_IN_FORK: 5111 id = get_identifier ("__gcov_fork"); 5112 break; 5113 5114 case BUILT_IN_EXECL: 5115 id = get_identifier ("__gcov_execl"); 5116 break; 5117 5118 case BUILT_IN_EXECV: 5119 id = get_identifier ("__gcov_execv"); 5120 break; 5121 5122 case BUILT_IN_EXECLP: 5123 id = get_identifier ("__gcov_execlp"); 5124 break; 5125 5126 case BUILT_IN_EXECLE: 5127 id = get_identifier ("__gcov_execle"); 5128 break; 5129 5130 case BUILT_IN_EXECVP: 5131 id = get_identifier ("__gcov_execvp"); 5132 break; 5133 5134 case BUILT_IN_EXECVE: 5135 id = get_identifier ("__gcov_execve"); 5136 break; 5137 5138 default: 5139 gcc_unreachable (); 5140 } 5141 5142 decl = build_decl (DECL_SOURCE_LOCATION (fn), 5143 FUNCTION_DECL, id, TREE_TYPE (fn)); 5144 DECL_EXTERNAL (decl) = 1; 5145 TREE_PUBLIC (decl) = 1; 5146 DECL_ARTIFICIAL (decl) = 1; 5147 TREE_NOTHROW (decl) = 1; 5148 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; 5149 DECL_VISIBILITY_SPECIFIED (decl) = 1; 5150 call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0); 5151 return expand_call (call, target, ignore); 5152 } 5153 5154 5155 5156/* Reconstitute a mode for a __sync intrinsic operation. Since the type of 5157 the pointer in these functions is void*, the tree optimizers may remove 5158 casts. The mode computed in expand_builtin isn't reliable either, due 5159 to __sync_bool_compare_and_swap. 5160 5161 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the 5162 group of builtins. This gives us log2 of the mode size. */ 5163 5164static inline machine_mode 5165get_builtin_sync_mode (int fcode_diff) 5166{ 5167 /* The size is not negotiable, so ask not to get BLKmode in return 5168 if the target indicates that a smaller size would be better. */ 5169 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0); 5170} 5171 5172/* Expand the memory expression LOC and return the appropriate memory operand 5173 for the builtin_sync operations. */ 5174 5175static rtx 5176get_builtin_sync_mem (tree loc, machine_mode mode) 5177{ 5178 rtx addr, mem; 5179 5180 addr = expand_expr (loc, NULL_RTX, ptr_mode, EXPAND_SUM); 5181 addr = convert_memory_address (Pmode, addr); 5182 5183 /* Note that we explicitly do not want any alias information for this 5184 memory, so that we kill all other live memories. Otherwise we don't 5185 satisfy the full barrier semantics of the intrinsic. */ 5186 mem = validize_mem (gen_rtx_MEM (mode, addr)); 5187 5188 /* The alignment needs to be at least according to that of the mode. */ 5189 set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode), 5190 get_pointer_alignment (loc))); 5191 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); 5192 MEM_VOLATILE_P (mem) = 1; 5193 5194 return mem; 5195} 5196 5197/* Make sure an argument is in the right mode. 5198 EXP is the tree argument. 5199 MODE is the mode it should be in. */ 5200 5201static rtx 5202expand_expr_force_mode (tree exp, machine_mode mode) 5203{ 5204 rtx val; 5205 machine_mode old_mode; 5206 5207 val = expand_expr (exp, NULL_RTX, mode, EXPAND_NORMAL); 5208 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5209 of CONST_INTs, where we know the old_mode only from the call argument. */ 5210 5211 old_mode = GET_MODE (val); 5212 if (old_mode == VOIDmode) 5213 old_mode = TYPE_MODE (TREE_TYPE (exp)); 5214 val = convert_modes (mode, old_mode, val, 1); 5215 return val; 5216} 5217 5218 5219/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics. 5220 EXP is the CALL_EXPR. CODE is the rtx code 5221 that corresponds to the arithmetic or logical operation from the name; 5222 an exception here is that NOT actually means NAND. TARGET is an optional 5223 place for us to store the results; AFTER is true if this is the 5224 fetch_and_xxx form. */ 5225 5226static rtx 5227expand_builtin_sync_operation (machine_mode mode, tree exp, 5228 enum rtx_code code, bool after, 5229 rtx target) 5230{ 5231 rtx val, mem; 5232 location_t loc = EXPR_LOCATION (exp); 5233 5234 if (code == NOT && warn_sync_nand) 5235 { 5236 tree fndecl = get_callee_fndecl (exp); 5237 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 5238 5239 static bool warned_f_a_n, warned_n_a_f; 5240 5241 switch (fcode) 5242 { 5243 case BUILT_IN_SYNC_FETCH_AND_NAND_1: 5244 case BUILT_IN_SYNC_FETCH_AND_NAND_2: 5245 case BUILT_IN_SYNC_FETCH_AND_NAND_4: 5246 case BUILT_IN_SYNC_FETCH_AND_NAND_8: 5247 case BUILT_IN_SYNC_FETCH_AND_NAND_16: 5248 if (warned_f_a_n) 5249 break; 5250 5251 fndecl = builtin_decl_implicit (BUILT_IN_SYNC_FETCH_AND_NAND_N); 5252 inform (loc, "%qD changed semantics in GCC 4.4", fndecl); 5253 warned_f_a_n = true; 5254 break; 5255 5256 case BUILT_IN_SYNC_NAND_AND_FETCH_1: 5257 case BUILT_IN_SYNC_NAND_AND_FETCH_2: 5258 case BUILT_IN_SYNC_NAND_AND_FETCH_4: 5259 case BUILT_IN_SYNC_NAND_AND_FETCH_8: 5260 case BUILT_IN_SYNC_NAND_AND_FETCH_16: 5261 if (warned_n_a_f) 5262 break; 5263 5264 fndecl = builtin_decl_implicit (BUILT_IN_SYNC_NAND_AND_FETCH_N); 5265 inform (loc, "%qD changed semantics in GCC 4.4", fndecl); 5266 warned_n_a_f = true; 5267 break; 5268 5269 default: 5270 gcc_unreachable (); 5271 } 5272 } 5273 5274 /* Expand the operands. */ 5275 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5276 val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode); 5277 5278 return expand_atomic_fetch_op (target, mem, val, code, MEMMODEL_SYNC_SEQ_CST, 5279 after); 5280} 5281 5282/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap 5283 intrinsics. EXP is the CALL_EXPR. IS_BOOL is 5284 true if this is the boolean form. TARGET is a place for us to store the 5285 results; this is NOT optional if IS_BOOL is true. */ 5286 5287static rtx 5288expand_builtin_compare_and_swap (machine_mode mode, tree exp, 5289 bool is_bool, rtx target) 5290{ 5291 rtx old_val, new_val, mem; 5292 rtx *pbool, *poval; 5293 5294 /* Expand the operands. */ 5295 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5296 old_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode); 5297 new_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode); 5298 5299 pbool = poval = NULL; 5300 if (target != const0_rtx) 5301 { 5302 if (is_bool) 5303 pbool = ⌖ 5304 else 5305 poval = ⌖ 5306 } 5307 if (!expand_atomic_compare_and_swap (pbool, poval, mem, old_val, new_val, 5308 false, MEMMODEL_SYNC_SEQ_CST, 5309 MEMMODEL_SYNC_SEQ_CST)) 5310 return NULL_RTX; 5311 5312 return target; 5313} 5314 5315/* Expand the __sync_lock_test_and_set intrinsic. Note that the most 5316 general form is actually an atomic exchange, and some targets only 5317 support a reduced form with the second argument being a constant 1. 5318 EXP is the CALL_EXPR; TARGET is an optional place for us to store 5319 the results. */ 5320 5321static rtx 5322expand_builtin_sync_lock_test_and_set (machine_mode mode, tree exp, 5323 rtx target) 5324{ 5325 rtx val, mem; 5326 5327 /* Expand the operands. */ 5328 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5329 val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode); 5330 5331 return expand_sync_lock_test_and_set (target, mem, val); 5332} 5333 5334/* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */ 5335 5336static void 5337expand_builtin_sync_lock_release (machine_mode mode, tree exp) 5338{ 5339 rtx mem; 5340 5341 /* Expand the operands. */ 5342 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5343 5344 expand_atomic_store (mem, const0_rtx, MEMMODEL_SYNC_RELEASE, true); 5345} 5346 5347/* Given an integer representing an ``enum memmodel'', verify its 5348 correctness and return the memory model enum. */ 5349 5350static enum memmodel 5351get_memmodel (tree exp) 5352{ 5353 rtx op; 5354 unsigned HOST_WIDE_INT val; 5355 5356 /* If the parameter is not a constant, it's a run time value so we'll just 5357 convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking. */ 5358 if (TREE_CODE (exp) != INTEGER_CST) 5359 return MEMMODEL_SEQ_CST; 5360 5361 op = expand_normal (exp); 5362 5363 val = INTVAL (op); 5364 if (targetm.memmodel_check) 5365 val = targetm.memmodel_check (val); 5366 else if (val & ~MEMMODEL_MASK) 5367 { 5368 warning (OPT_Winvalid_memory_model, 5369 "Unknown architecture specifier in memory model to builtin."); 5370 return MEMMODEL_SEQ_CST; 5371 } 5372 5373 /* Should never see a user explicit SYNC memodel model, so >= LAST works. */ 5374 if (memmodel_base (val) >= MEMMODEL_LAST) 5375 { 5376 warning (OPT_Winvalid_memory_model, 5377 "invalid memory model argument to builtin"); 5378 return MEMMODEL_SEQ_CST; 5379 } 5380 5381 /* Workaround for Bugzilla 59448. GCC doesn't track consume properly, so 5382 be conservative and promote consume to acquire. */ 5383 if (val == MEMMODEL_CONSUME) 5384 val = MEMMODEL_ACQUIRE; 5385 5386 return (enum memmodel) val; 5387} 5388 5389/* Expand the __atomic_exchange intrinsic: 5390 TYPE __atomic_exchange (TYPE *object, TYPE desired, enum memmodel) 5391 EXP is the CALL_EXPR. 5392 TARGET is an optional place for us to store the results. */ 5393 5394static rtx 5395expand_builtin_atomic_exchange (machine_mode mode, tree exp, rtx target) 5396{ 5397 rtx val, mem; 5398 enum memmodel model; 5399 5400 model = get_memmodel (CALL_EXPR_ARG (exp, 2)); 5401 5402 if (!flag_inline_atomics) 5403 return NULL_RTX; 5404 5405 /* Expand the operands. */ 5406 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5407 val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode); 5408 5409 return expand_atomic_exchange (target, mem, val, model); 5410} 5411 5412/* Expand the __atomic_compare_exchange intrinsic: 5413 bool __atomic_compare_exchange (TYPE *object, TYPE *expect, 5414 TYPE desired, BOOL weak, 5415 enum memmodel success, 5416 enum memmodel failure) 5417 EXP is the CALL_EXPR. 5418 TARGET is an optional place for us to store the results. */ 5419 5420static rtx 5421expand_builtin_atomic_compare_exchange (machine_mode mode, tree exp, 5422 rtx target) 5423{ 5424 rtx expect, desired, mem, oldval; 5425 rtx_code_label *label; 5426 enum memmodel success, failure; 5427 tree weak; 5428 bool is_weak; 5429 5430 success = get_memmodel (CALL_EXPR_ARG (exp, 4)); 5431 failure = get_memmodel (CALL_EXPR_ARG (exp, 5)); 5432 5433 if (failure > success) 5434 { 5435 warning (OPT_Winvalid_memory_model, 5436 "failure memory model cannot be stronger than success memory " 5437 "model for %<__atomic_compare_exchange%>"); 5438 success = MEMMODEL_SEQ_CST; 5439 } 5440 5441 if (is_mm_release (failure) || is_mm_acq_rel (failure)) 5442 { 5443 warning (OPT_Winvalid_memory_model, 5444 "invalid failure memory model for " 5445 "%<__atomic_compare_exchange%>"); 5446 failure = MEMMODEL_SEQ_CST; 5447 success = MEMMODEL_SEQ_CST; 5448 } 5449 5450 5451 if (!flag_inline_atomics) 5452 return NULL_RTX; 5453 5454 /* Expand the operands. */ 5455 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5456 5457 expect = expand_normal (CALL_EXPR_ARG (exp, 1)); 5458 expect = convert_memory_address (Pmode, expect); 5459 expect = gen_rtx_MEM (mode, expect); 5460 desired = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode); 5461 5462 weak = CALL_EXPR_ARG (exp, 3); 5463 is_weak = false; 5464 if (tree_fits_shwi_p (weak) && tree_to_shwi (weak) != 0) 5465 is_weak = true; 5466 5467 if (target == const0_rtx) 5468 target = NULL; 5469 5470 /* Lest the rtl backend create a race condition with an imporoper store 5471 to memory, always create a new pseudo for OLDVAL. */ 5472 oldval = NULL; 5473 5474 if (!expand_atomic_compare_and_swap (&target, &oldval, mem, expect, desired, 5475 is_weak, success, failure)) 5476 return NULL_RTX; 5477 5478 /* Conditionally store back to EXPECT, lest we create a race condition 5479 with an improper store to memory. */ 5480 /* ??? With a rearrangement of atomics at the gimple level, we can handle 5481 the normal case where EXPECT is totally private, i.e. a register. At 5482 which point the store can be unconditional. */ 5483 label = gen_label_rtx (); 5484 emit_cmp_and_jump_insns (target, const0_rtx, NE, NULL, VOIDmode, 1, label); 5485 emit_move_insn (expect, oldval); 5486 emit_label (label); 5487 5488 return target; 5489} 5490 5491/* Expand the __atomic_load intrinsic: 5492 TYPE __atomic_load (TYPE *object, enum memmodel) 5493 EXP is the CALL_EXPR. 5494 TARGET is an optional place for us to store the results. */ 5495 5496static rtx 5497expand_builtin_atomic_load (machine_mode mode, tree exp, rtx target) 5498{ 5499 rtx mem; 5500 enum memmodel model; 5501 5502 model = get_memmodel (CALL_EXPR_ARG (exp, 1)); 5503 if (is_mm_release (model) || is_mm_acq_rel (model)) 5504 { 5505 warning (OPT_Winvalid_memory_model, 5506 "invalid memory model for %<__atomic_load%>"); 5507 model = MEMMODEL_SEQ_CST; 5508 } 5509 5510 if (!flag_inline_atomics) 5511 return NULL_RTX; 5512 5513 /* Expand the operand. */ 5514 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5515 5516 return expand_atomic_load (target, mem, model); 5517} 5518 5519 5520/* Expand the __atomic_store intrinsic: 5521 void __atomic_store (TYPE *object, TYPE desired, enum memmodel) 5522 EXP is the CALL_EXPR. 5523 TARGET is an optional place for us to store the results. */ 5524 5525static rtx 5526expand_builtin_atomic_store (machine_mode mode, tree exp) 5527{ 5528 rtx mem, val; 5529 enum memmodel model; 5530 5531 model = get_memmodel (CALL_EXPR_ARG (exp, 2)); 5532 if (!(is_mm_relaxed (model) || is_mm_seq_cst (model) 5533 || is_mm_release (model))) 5534 { 5535 warning (OPT_Winvalid_memory_model, 5536 "invalid memory model for %<__atomic_store%>"); 5537 model = MEMMODEL_SEQ_CST; 5538 } 5539 5540 if (!flag_inline_atomics) 5541 return NULL_RTX; 5542 5543 /* Expand the operands. */ 5544 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5545 val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode); 5546 5547 return expand_atomic_store (mem, val, model, false); 5548} 5549 5550/* Expand the __atomic_fetch_XXX intrinsic: 5551 TYPE __atomic_fetch_XXX (TYPE *object, TYPE val, enum memmodel) 5552 EXP is the CALL_EXPR. 5553 TARGET is an optional place for us to store the results. 5554 CODE is the operation, PLUS, MINUS, ADD, XOR, or IOR. 5555 FETCH_AFTER is true if returning the result of the operation. 5556 FETCH_AFTER is false if returning the value before the operation. 5557 IGNORE is true if the result is not used. 5558 EXT_CALL is the correct builtin for an external call if this cannot be 5559 resolved to an instruction sequence. */ 5560 5561static rtx 5562expand_builtin_atomic_fetch_op (machine_mode mode, tree exp, rtx target, 5563 enum rtx_code code, bool fetch_after, 5564 bool ignore, enum built_in_function ext_call) 5565{ 5566 rtx val, mem, ret; 5567 enum memmodel model; 5568 tree fndecl; 5569 tree addr; 5570 5571 model = get_memmodel (CALL_EXPR_ARG (exp, 2)); 5572 5573 /* Expand the operands. */ 5574 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5575 val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode); 5576 5577 /* Only try generating instructions if inlining is turned on. */ 5578 if (flag_inline_atomics) 5579 { 5580 ret = expand_atomic_fetch_op (target, mem, val, code, model, fetch_after); 5581 if (ret) 5582 return ret; 5583 } 5584 5585 /* Return if a different routine isn't needed for the library call. */ 5586 if (ext_call == BUILT_IN_NONE) 5587 return NULL_RTX; 5588 5589 /* Change the call to the specified function. */ 5590 fndecl = get_callee_fndecl (exp); 5591 addr = CALL_EXPR_FN (exp); 5592 STRIP_NOPS (addr); 5593 5594 gcc_assert (TREE_OPERAND (addr, 0) == fndecl); 5595 TREE_OPERAND (addr, 0) = builtin_decl_explicit (ext_call); 5596 5597 /* Expand the call here so we can emit trailing code. */ 5598 ret = expand_call (exp, target, ignore); 5599 5600 /* Replace the original function just in case it matters. */ 5601 TREE_OPERAND (addr, 0) = fndecl; 5602 5603 /* Then issue the arithmetic correction to return the right result. */ 5604 if (!ignore) 5605 { 5606 if (code == NOT) 5607 { 5608 ret = expand_simple_binop (mode, AND, ret, val, NULL_RTX, true, 5609 OPTAB_LIB_WIDEN); 5610 ret = expand_simple_unop (mode, NOT, ret, target, true); 5611 } 5612 else 5613 ret = expand_simple_binop (mode, code, ret, val, target, true, 5614 OPTAB_LIB_WIDEN); 5615 } 5616 return ret; 5617} 5618 5619 5620#ifndef HAVE_atomic_clear 5621# define HAVE_atomic_clear 0 5622# define gen_atomic_clear(x,y) (gcc_unreachable (), NULL_RTX) 5623#endif 5624 5625/* Expand an atomic clear operation. 5626 void _atomic_clear (BOOL *obj, enum memmodel) 5627 EXP is the call expression. */ 5628 5629static rtx 5630expand_builtin_atomic_clear (tree exp) 5631{ 5632 machine_mode mode; 5633 rtx mem, ret; 5634 enum memmodel model; 5635 5636 mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0); 5637 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5638 model = get_memmodel (CALL_EXPR_ARG (exp, 1)); 5639 5640 if (is_mm_consume (model) || is_mm_acquire (model) || is_mm_acq_rel (model)) 5641 { 5642 warning (OPT_Winvalid_memory_model, 5643 "invalid memory model for %<__atomic_store%>"); 5644 model = MEMMODEL_SEQ_CST; 5645 } 5646 5647 if (HAVE_atomic_clear) 5648 { 5649 emit_insn (gen_atomic_clear (mem, model)); 5650 return const0_rtx; 5651 } 5652 5653 /* Try issuing an __atomic_store, and allow fallback to __sync_lock_release. 5654 Failing that, a store is issued by __atomic_store. The only way this can 5655 fail is if the bool type is larger than a word size. Unlikely, but 5656 handle it anyway for completeness. Assume a single threaded model since 5657 there is no atomic support in this case, and no barriers are required. */ 5658 ret = expand_atomic_store (mem, const0_rtx, model, true); 5659 if (!ret) 5660 emit_move_insn (mem, const0_rtx); 5661 return const0_rtx; 5662} 5663 5664/* Expand an atomic test_and_set operation. 5665 bool _atomic_test_and_set (BOOL *obj, enum memmodel) 5666 EXP is the call expression. */ 5667 5668static rtx 5669expand_builtin_atomic_test_and_set (tree exp, rtx target) 5670{ 5671 rtx mem; 5672 enum memmodel model; 5673 machine_mode mode; 5674 5675 mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0); 5676 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5677 model = get_memmodel (CALL_EXPR_ARG (exp, 1)); 5678 5679 return expand_atomic_test_and_set (target, mem, model); 5680} 5681 5682 5683/* Return true if (optional) argument ARG1 of size ARG0 is always lock free on 5684 this architecture. If ARG1 is NULL, use typical alignment for size ARG0. */ 5685 5686static tree 5687fold_builtin_atomic_always_lock_free (tree arg0, tree arg1) 5688{ 5689 int size; 5690 machine_mode mode; 5691 unsigned int mode_align, type_align; 5692 5693 if (TREE_CODE (arg0) != INTEGER_CST) 5694 return NULL_TREE; 5695 5696 size = INTVAL (expand_normal (arg0)) * BITS_PER_UNIT; 5697 mode = mode_for_size (size, MODE_INT, 0); 5698 mode_align = GET_MODE_ALIGNMENT (mode); 5699 5700 if (TREE_CODE (arg1) == INTEGER_CST) 5701 { 5702 unsigned HOST_WIDE_INT val = UINTVAL (expand_normal (arg1)); 5703 5704 /* Either this argument is null, or it's a fake pointer encoding 5705 the alignment of the object. */ 5706 val = val & -val; 5707 val *= BITS_PER_UNIT; 5708 5709 if (val == 0 || mode_align < val) 5710 type_align = mode_align; 5711 else 5712 type_align = val; 5713 } 5714 else 5715 { 5716 tree ttype = TREE_TYPE (arg1); 5717 5718 /* This function is usually invoked and folded immediately by the front 5719 end before anything else has a chance to look at it. The pointer 5720 parameter at this point is usually cast to a void *, so check for that 5721 and look past the cast. */ 5722 if (CONVERT_EXPR_P (arg1) && POINTER_TYPE_P (ttype) 5723 && VOID_TYPE_P (TREE_TYPE (ttype))) 5724 arg1 = TREE_OPERAND (arg1, 0); 5725 5726 ttype = TREE_TYPE (arg1); 5727 gcc_assert (POINTER_TYPE_P (ttype)); 5728 5729 /* Get the underlying type of the object. */ 5730 ttype = TREE_TYPE (ttype); 5731 type_align = TYPE_ALIGN (ttype); 5732 } 5733 5734 /* If the object has smaller alignment, the the lock free routines cannot 5735 be used. */ 5736 if (type_align < mode_align) 5737 return boolean_false_node; 5738 5739 /* Check if a compare_and_swap pattern exists for the mode which represents 5740 the required size. The pattern is not allowed to fail, so the existence 5741 of the pattern indicates support is present. */ 5742 if (can_compare_and_swap_p (mode, true)) 5743 return boolean_true_node; 5744 else 5745 return boolean_false_node; 5746} 5747 5748/* Return true if the parameters to call EXP represent an object which will 5749 always generate lock free instructions. The first argument represents the 5750 size of the object, and the second parameter is a pointer to the object 5751 itself. If NULL is passed for the object, then the result is based on 5752 typical alignment for an object of the specified size. Otherwise return 5753 false. */ 5754 5755static rtx 5756expand_builtin_atomic_always_lock_free (tree exp) 5757{ 5758 tree size; 5759 tree arg0 = CALL_EXPR_ARG (exp, 0); 5760 tree arg1 = CALL_EXPR_ARG (exp, 1); 5761 5762 if (TREE_CODE (arg0) != INTEGER_CST) 5763 { 5764 error ("non-constant argument 1 to __atomic_always_lock_free"); 5765 return const0_rtx; 5766 } 5767 5768 size = fold_builtin_atomic_always_lock_free (arg0, arg1); 5769 if (size == boolean_true_node) 5770 return const1_rtx; 5771 return const0_rtx; 5772} 5773 5774/* Return a one or zero if it can be determined that object ARG1 of size ARG 5775 is lock free on this architecture. */ 5776 5777static tree 5778fold_builtin_atomic_is_lock_free (tree arg0, tree arg1) 5779{ 5780 if (!flag_inline_atomics) 5781 return NULL_TREE; 5782 5783 /* If it isn't always lock free, don't generate a result. */ 5784 if (fold_builtin_atomic_always_lock_free (arg0, arg1) == boolean_true_node) 5785 return boolean_true_node; 5786 5787 return NULL_TREE; 5788} 5789 5790/* Return true if the parameters to call EXP represent an object which will 5791 always generate lock free instructions. The first argument represents the 5792 size of the object, and the second parameter is a pointer to the object 5793 itself. If NULL is passed for the object, then the result is based on 5794 typical alignment for an object of the specified size. Otherwise return 5795 NULL*/ 5796 5797static rtx 5798expand_builtin_atomic_is_lock_free (tree exp) 5799{ 5800 tree size; 5801 tree arg0 = CALL_EXPR_ARG (exp, 0); 5802 tree arg1 = CALL_EXPR_ARG (exp, 1); 5803 5804 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0))) 5805 { 5806 error ("non-integer argument 1 to __atomic_is_lock_free"); 5807 return NULL_RTX; 5808 } 5809 5810 if (!flag_inline_atomics) 5811 return NULL_RTX; 5812 5813 /* If the value is known at compile time, return the RTX for it. */ 5814 size = fold_builtin_atomic_is_lock_free (arg0, arg1); 5815 if (size == boolean_true_node) 5816 return const1_rtx; 5817 5818 return NULL_RTX; 5819} 5820 5821/* Expand the __atomic_thread_fence intrinsic: 5822 void __atomic_thread_fence (enum memmodel) 5823 EXP is the CALL_EXPR. */ 5824 5825static void 5826expand_builtin_atomic_thread_fence (tree exp) 5827{ 5828 enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0)); 5829 expand_mem_thread_fence (model); 5830} 5831 5832/* Expand the __atomic_signal_fence intrinsic: 5833 void __atomic_signal_fence (enum memmodel) 5834 EXP is the CALL_EXPR. */ 5835 5836static void 5837expand_builtin_atomic_signal_fence (tree exp) 5838{ 5839 enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0)); 5840 expand_mem_signal_fence (model); 5841} 5842 5843/* Expand the __sync_synchronize intrinsic. */ 5844 5845static void 5846expand_builtin_sync_synchronize (void) 5847{ 5848 expand_mem_thread_fence (MEMMODEL_SYNC_SEQ_CST); 5849} 5850 5851static rtx 5852expand_builtin_thread_pointer (tree exp, rtx target) 5853{ 5854 enum insn_code icode; 5855 if (!validate_arglist (exp, VOID_TYPE)) 5856 return const0_rtx; 5857 icode = direct_optab_handler (get_thread_pointer_optab, Pmode); 5858 if (icode != CODE_FOR_nothing) 5859 { 5860 struct expand_operand op; 5861 /* If the target is not sutitable then create a new target. */ 5862 if (target == NULL_RTX 5863 || !REG_P (target) 5864 || GET_MODE (target) != Pmode) 5865 target = gen_reg_rtx (Pmode); 5866 create_output_operand (&op, target, Pmode); 5867 expand_insn (icode, 1, &op); 5868 return target; 5869 } 5870 error ("__builtin_thread_pointer is not supported on this target"); 5871 return const0_rtx; 5872} 5873 5874static void 5875expand_builtin_set_thread_pointer (tree exp) 5876{ 5877 enum insn_code icode; 5878 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 5879 return; 5880 icode = direct_optab_handler (set_thread_pointer_optab, Pmode); 5881 if (icode != CODE_FOR_nothing) 5882 { 5883 struct expand_operand op; 5884 rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, 5885 Pmode, EXPAND_NORMAL); 5886 create_input_operand (&op, val, Pmode); 5887 expand_insn (icode, 1, &op); 5888 return; 5889 } 5890 error ("__builtin_set_thread_pointer is not supported on this target"); 5891} 5892 5893 5894/* Emit code to restore the current value of stack. */ 5895 5896static void 5897expand_stack_restore (tree var) 5898{ 5899 rtx_insn *prev; 5900 rtx sa = expand_normal (var); 5901 5902 sa = convert_memory_address (Pmode, sa); 5903 5904 prev = get_last_insn (); 5905 emit_stack_restore (SAVE_BLOCK, sa); 5906 fixup_args_size_notes (prev, get_last_insn (), 0); 5907} 5908 5909 5910/* Emit code to save the current value of stack. */ 5911 5912static rtx 5913expand_stack_save (void) 5914{ 5915 rtx ret = NULL_RTX; 5916 5917 do_pending_stack_adjust (); 5918 emit_stack_save (SAVE_BLOCK, &ret); 5919 return ret; 5920} 5921 5922 5923/* Expand OpenACC acc_on_device. 5924 5925 This has to happen late (that is, not in early folding; expand_builtin_*, 5926 rather than fold_builtin_*), as we have to act differently for host and 5927 acceleration device (ACCEL_COMPILER conditional). */ 5928 5929static rtx 5930expand_builtin_acc_on_device (tree exp ATTRIBUTE_UNUSED, 5931 rtx target ATTRIBUTE_UNUSED) 5932{ 5933#ifdef ACCEL_COMPILER 5934 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)) 5935 return NULL_RTX; 5936 5937 tree arg = CALL_EXPR_ARG (exp, 0); 5938 5939 /* Return (arg == v1 || arg == v2) ? 1 : 0. */ 5940 machine_mode v_mode = TYPE_MODE (TREE_TYPE (arg)); 5941 rtx v = expand_normal (arg), v1, v2; 5942 v1 = GEN_INT (GOMP_DEVICE_NOT_HOST); 5943 v2 = GEN_INT (ACCEL_COMPILER_acc_device); 5944 machine_mode target_mode = TYPE_MODE (integer_type_node); 5945 if (!target || !register_operand (target, target_mode)) 5946 target = gen_reg_rtx (target_mode); 5947 emit_move_insn (target, const1_rtx); 5948 rtx_code_label *done_label = gen_label_rtx (); 5949 do_compare_rtx_and_jump (v, v1, EQ, false, v_mode, NULL_RTX, 5950 NULL_RTX, done_label, PROB_EVEN); 5951 do_compare_rtx_and_jump (v, v2, EQ, false, v_mode, NULL_RTX, 5952 NULL_RTX, done_label, PROB_EVEN); 5953 emit_move_insn (target, const0_rtx); 5954 emit_label (done_label); 5955 5956 return target; 5957#else 5958 return NULL; 5959#endif 5960} 5961 5962 5963/* Expand an expression EXP that calls a built-in function, 5964 with result going to TARGET if that's convenient 5965 (and in mode MODE if that's convenient). 5966 SUBTARGET may be used as the target for computing one of EXP's operands. 5967 IGNORE is nonzero if the value is to be ignored. */ 5968 5969rtx 5970expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, 5971 int ignore) 5972{ 5973 tree fndecl = get_callee_fndecl (exp); 5974 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 5975 machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp)); 5976 int flags; 5977 5978 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 5979 return targetm.expand_builtin (exp, target, subtarget, mode, ignore); 5980 5981 /* When ASan is enabled, we don't want to expand some memory/string 5982 builtins and rely on libsanitizer's hooks. This allows us to avoid 5983 redundant checks and be sure, that possible overflow will be detected 5984 by ASan. */ 5985 5986 if ((flag_sanitize & SANITIZE_ADDRESS) && asan_intercepted_p (fcode)) 5987 return expand_call (exp, target, ignore); 5988 5989 /* When not optimizing, generate calls to library functions for a certain 5990 set of builtins. */ 5991 if (!optimize 5992 && !called_as_built_in (fndecl) 5993 && fcode != BUILT_IN_FORK 5994 && fcode != BUILT_IN_EXECL 5995 && fcode != BUILT_IN_EXECV 5996 && fcode != BUILT_IN_EXECLP 5997 && fcode != BUILT_IN_EXECLE 5998 && fcode != BUILT_IN_EXECVP 5999 && fcode != BUILT_IN_EXECVE 6000 && fcode != BUILT_IN_ALLOCA 6001 && fcode != BUILT_IN_ALLOCA_WITH_ALIGN 6002 && fcode != BUILT_IN_FREE 6003 && fcode != BUILT_IN_CHKP_SET_PTR_BOUNDS 6004 && fcode != BUILT_IN_CHKP_INIT_PTR_BOUNDS 6005 && fcode != BUILT_IN_CHKP_NULL_PTR_BOUNDS 6006 && fcode != BUILT_IN_CHKP_COPY_PTR_BOUNDS 6007 && fcode != BUILT_IN_CHKP_NARROW_PTR_BOUNDS 6008 && fcode != BUILT_IN_CHKP_STORE_PTR_BOUNDS 6009 && fcode != BUILT_IN_CHKP_CHECK_PTR_LBOUNDS 6010 && fcode != BUILT_IN_CHKP_CHECK_PTR_UBOUNDS 6011 && fcode != BUILT_IN_CHKP_CHECK_PTR_BOUNDS 6012 && fcode != BUILT_IN_CHKP_GET_PTR_LBOUND 6013 && fcode != BUILT_IN_CHKP_GET_PTR_UBOUND 6014 && fcode != BUILT_IN_CHKP_BNDRET) 6015 return expand_call (exp, target, ignore); 6016 6017 /* The built-in function expanders test for target == const0_rtx 6018 to determine whether the function's result will be ignored. */ 6019 if (ignore) 6020 target = const0_rtx; 6021 6022 /* If the result of a pure or const built-in function is ignored, and 6023 none of its arguments are volatile, we can avoid expanding the 6024 built-in call and just evaluate the arguments for side-effects. */ 6025 if (target == const0_rtx 6026 && ((flags = flags_from_decl_or_type (fndecl)) & (ECF_CONST | ECF_PURE)) 6027 && !(flags & ECF_LOOPING_CONST_OR_PURE)) 6028 { 6029 bool volatilep = false; 6030 tree arg; 6031 call_expr_arg_iterator iter; 6032 6033 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) 6034 if (TREE_THIS_VOLATILE (arg)) 6035 { 6036 volatilep = true; 6037 break; 6038 } 6039 6040 if (! volatilep) 6041 { 6042 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) 6043 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL); 6044 return const0_rtx; 6045 } 6046 } 6047 6048 /* expand_builtin_with_bounds is supposed to be used for 6049 instrumented builtin calls. */ 6050 gcc_assert (!CALL_WITH_BOUNDS_P (exp)); 6051 6052 switch (fcode) 6053 { 6054 CASE_FLT_FN (BUILT_IN_FABS): 6055 case BUILT_IN_FABSD32: 6056 case BUILT_IN_FABSD64: 6057 case BUILT_IN_FABSD128: 6058 target = expand_builtin_fabs (exp, target, subtarget); 6059 if (target) 6060 return target; 6061 break; 6062 6063 CASE_FLT_FN (BUILT_IN_COPYSIGN): 6064 target = expand_builtin_copysign (exp, target, subtarget); 6065 if (target) 6066 return target; 6067 break; 6068 6069 /* Just do a normal library call if we were unable to fold 6070 the values. */ 6071 CASE_FLT_FN (BUILT_IN_CABS): 6072 break; 6073 6074 CASE_FLT_FN (BUILT_IN_EXP): 6075 CASE_FLT_FN (BUILT_IN_EXP10): 6076 CASE_FLT_FN (BUILT_IN_POW10): 6077 CASE_FLT_FN (BUILT_IN_EXP2): 6078 CASE_FLT_FN (BUILT_IN_EXPM1): 6079 CASE_FLT_FN (BUILT_IN_LOGB): 6080 CASE_FLT_FN (BUILT_IN_LOG): 6081 CASE_FLT_FN (BUILT_IN_LOG10): 6082 CASE_FLT_FN (BUILT_IN_LOG2): 6083 CASE_FLT_FN (BUILT_IN_LOG1P): 6084 CASE_FLT_FN (BUILT_IN_TAN): 6085 CASE_FLT_FN (BUILT_IN_ASIN): 6086 CASE_FLT_FN (BUILT_IN_ACOS): 6087 CASE_FLT_FN (BUILT_IN_ATAN): 6088 CASE_FLT_FN (BUILT_IN_SIGNIFICAND): 6089 /* Treat these like sqrt only if unsafe math optimizations are allowed, 6090 because of possible accuracy problems. */ 6091 if (! flag_unsafe_math_optimizations) 6092 break; 6093 CASE_FLT_FN (BUILT_IN_SQRT): 6094 CASE_FLT_FN (BUILT_IN_FLOOR): 6095 CASE_FLT_FN (BUILT_IN_CEIL): 6096 CASE_FLT_FN (BUILT_IN_TRUNC): 6097 CASE_FLT_FN (BUILT_IN_ROUND): 6098 CASE_FLT_FN (BUILT_IN_NEARBYINT): 6099 CASE_FLT_FN (BUILT_IN_RINT): 6100 target = expand_builtin_mathfn (exp, target, subtarget); 6101 if (target) 6102 return target; 6103 break; 6104 6105 CASE_FLT_FN (BUILT_IN_FMA): 6106 target = expand_builtin_mathfn_ternary (exp, target, subtarget); 6107 if (target) 6108 return target; 6109 break; 6110 6111 CASE_FLT_FN (BUILT_IN_ILOGB): 6112 if (! flag_unsafe_math_optimizations) 6113 break; 6114 CASE_FLT_FN (BUILT_IN_ISINF): 6115 CASE_FLT_FN (BUILT_IN_FINITE): 6116 case BUILT_IN_ISFINITE: 6117 case BUILT_IN_ISNORMAL: 6118 target = expand_builtin_interclass_mathfn (exp, target); 6119 if (target) 6120 return target; 6121 break; 6122 6123 CASE_FLT_FN (BUILT_IN_ICEIL): 6124 CASE_FLT_FN (BUILT_IN_LCEIL): 6125 CASE_FLT_FN (BUILT_IN_LLCEIL): 6126 CASE_FLT_FN (BUILT_IN_LFLOOR): 6127 CASE_FLT_FN (BUILT_IN_IFLOOR): 6128 CASE_FLT_FN (BUILT_IN_LLFLOOR): 6129 target = expand_builtin_int_roundingfn (exp, target); 6130 if (target) 6131 return target; 6132 break; 6133 6134 CASE_FLT_FN (BUILT_IN_IRINT): 6135 CASE_FLT_FN (BUILT_IN_LRINT): 6136 CASE_FLT_FN (BUILT_IN_LLRINT): 6137 CASE_FLT_FN (BUILT_IN_IROUND): 6138 CASE_FLT_FN (BUILT_IN_LROUND): 6139 CASE_FLT_FN (BUILT_IN_LLROUND): 6140 target = expand_builtin_int_roundingfn_2 (exp, target); 6141 if (target) 6142 return target; 6143 break; 6144 6145 CASE_FLT_FN (BUILT_IN_POWI): 6146 target = expand_builtin_powi (exp, target); 6147 if (target) 6148 return target; 6149 break; 6150 6151 CASE_FLT_FN (BUILT_IN_ATAN2): 6152 CASE_FLT_FN (BUILT_IN_LDEXP): 6153 CASE_FLT_FN (BUILT_IN_SCALB): 6154 CASE_FLT_FN (BUILT_IN_SCALBN): 6155 CASE_FLT_FN (BUILT_IN_SCALBLN): 6156 if (! flag_unsafe_math_optimizations) 6157 break; 6158 6159 CASE_FLT_FN (BUILT_IN_FMOD): 6160 CASE_FLT_FN (BUILT_IN_REMAINDER): 6161 CASE_FLT_FN (BUILT_IN_DREM): 6162 CASE_FLT_FN (BUILT_IN_POW): 6163 target = expand_builtin_mathfn_2 (exp, target, subtarget); 6164 if (target) 6165 return target; 6166 break; 6167 6168 CASE_FLT_FN (BUILT_IN_CEXPI): 6169 target = expand_builtin_cexpi (exp, target); 6170 gcc_assert (target); 6171 return target; 6172 6173 CASE_FLT_FN (BUILT_IN_SIN): 6174 CASE_FLT_FN (BUILT_IN_COS): 6175 if (! flag_unsafe_math_optimizations) 6176 break; 6177 target = expand_builtin_mathfn_3 (exp, target, subtarget); 6178 if (target) 6179 return target; 6180 break; 6181 6182 CASE_FLT_FN (BUILT_IN_SINCOS): 6183 if (! flag_unsafe_math_optimizations) 6184 break; 6185 target = expand_builtin_sincos (exp); 6186 if (target) 6187 return target; 6188 break; 6189 6190 case BUILT_IN_APPLY_ARGS: 6191 return expand_builtin_apply_args (); 6192 6193 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes 6194 FUNCTION with a copy of the parameters described by 6195 ARGUMENTS, and ARGSIZE. It returns a block of memory 6196 allocated on the stack into which is stored all the registers 6197 that might possibly be used for returning the result of a 6198 function. ARGUMENTS is the value returned by 6199 __builtin_apply_args. ARGSIZE is the number of bytes of 6200 arguments that must be copied. ??? How should this value be 6201 computed? We'll also need a safe worst case value for varargs 6202 functions. */ 6203 case BUILT_IN_APPLY: 6204 if (!validate_arglist (exp, POINTER_TYPE, 6205 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE) 6206 && !validate_arglist (exp, REFERENCE_TYPE, 6207 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6208 return const0_rtx; 6209 else 6210 { 6211 rtx ops[3]; 6212 6213 ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0)); 6214 ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1)); 6215 ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2)); 6216 6217 return expand_builtin_apply (ops[0], ops[1], ops[2]); 6218 } 6219 6220 /* __builtin_return (RESULT) causes the function to return the 6221 value described by RESULT. RESULT is address of the block of 6222 memory returned by __builtin_apply. */ 6223 case BUILT_IN_RETURN: 6224 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 6225 expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0))); 6226 return const0_rtx; 6227 6228 case BUILT_IN_SAVEREGS: 6229 return expand_builtin_saveregs (); 6230 6231 case BUILT_IN_VA_ARG_PACK: 6232 /* All valid uses of __builtin_va_arg_pack () are removed during 6233 inlining. */ 6234 error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp); 6235 return const0_rtx; 6236 6237 case BUILT_IN_VA_ARG_PACK_LEN: 6238 /* All valid uses of __builtin_va_arg_pack_len () are removed during 6239 inlining. */ 6240 error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp); 6241 return const0_rtx; 6242 6243 /* Return the address of the first anonymous stack arg. */ 6244 case BUILT_IN_NEXT_ARG: 6245 if (fold_builtin_next_arg (exp, false)) 6246 return const0_rtx; 6247 return expand_builtin_next_arg (); 6248 6249 case BUILT_IN_CLEAR_CACHE: 6250 target = expand_builtin___clear_cache (exp); 6251 if (target) 6252 return target; 6253 break; 6254 6255 case BUILT_IN_CLASSIFY_TYPE: 6256 return expand_builtin_classify_type (exp); 6257 6258 case BUILT_IN_CONSTANT_P: 6259 return const0_rtx; 6260 6261 case BUILT_IN_FRAME_ADDRESS: 6262 case BUILT_IN_RETURN_ADDRESS: 6263 return expand_builtin_frame_address (fndecl, exp); 6264 6265 /* Returns the address of the area where the structure is returned. 6266 0 otherwise. */ 6267 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: 6268 if (call_expr_nargs (exp) != 0 6269 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))) 6270 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl)))) 6271 return const0_rtx; 6272 else 6273 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0); 6274 6275 case BUILT_IN_ALLOCA: 6276 case BUILT_IN_ALLOCA_WITH_ALIGN: 6277 /* If the allocation stems from the declaration of a variable-sized 6278 object, it cannot accumulate. */ 6279 target = expand_builtin_alloca (exp, CALL_ALLOCA_FOR_VAR_P (exp)); 6280 if (target) 6281 return target; 6282 break; 6283 6284 case BUILT_IN_STACK_SAVE: 6285 return expand_stack_save (); 6286 6287 case BUILT_IN_STACK_RESTORE: 6288 expand_stack_restore (CALL_EXPR_ARG (exp, 0)); 6289 return const0_rtx; 6290 6291 case BUILT_IN_BSWAP16: 6292 case BUILT_IN_BSWAP32: 6293 case BUILT_IN_BSWAP64: 6294 target = expand_builtin_bswap (target_mode, exp, target, subtarget); 6295 if (target) 6296 return target; 6297 break; 6298 6299 CASE_INT_FN (BUILT_IN_FFS): 6300 target = expand_builtin_unop (target_mode, exp, target, 6301 subtarget, ffs_optab); 6302 if (target) 6303 return target; 6304 break; 6305 6306 CASE_INT_FN (BUILT_IN_CLZ): 6307 target = expand_builtin_unop (target_mode, exp, target, 6308 subtarget, clz_optab); 6309 if (target) 6310 return target; 6311 break; 6312 6313 CASE_INT_FN (BUILT_IN_CTZ): 6314 target = expand_builtin_unop (target_mode, exp, target, 6315 subtarget, ctz_optab); 6316 if (target) 6317 return target; 6318 break; 6319 6320 CASE_INT_FN (BUILT_IN_CLRSB): 6321 target = expand_builtin_unop (target_mode, exp, target, 6322 subtarget, clrsb_optab); 6323 if (target) 6324 return target; 6325 break; 6326 6327 CASE_INT_FN (BUILT_IN_POPCOUNT): 6328 target = expand_builtin_unop (target_mode, exp, target, 6329 subtarget, popcount_optab); 6330 if (target) 6331 return target; 6332 break; 6333 6334 CASE_INT_FN (BUILT_IN_PARITY): 6335 target = expand_builtin_unop (target_mode, exp, target, 6336 subtarget, parity_optab); 6337 if (target) 6338 return target; 6339 break; 6340 6341 case BUILT_IN_STRLEN: 6342 target = expand_builtin_strlen (exp, target, target_mode); 6343 if (target) 6344 return target; 6345 break; 6346 6347 case BUILT_IN_STRCPY: 6348 target = expand_builtin_strcpy (exp, target); 6349 if (target) 6350 return target; 6351 break; 6352 6353 case BUILT_IN_STRNCPY: 6354 target = expand_builtin_strncpy (exp, target); 6355 if (target) 6356 return target; 6357 break; 6358 6359 case BUILT_IN_STPCPY: 6360 target = expand_builtin_stpcpy (exp, target, mode); 6361 if (target) 6362 return target; 6363 break; 6364 6365 case BUILT_IN_MEMCPY: 6366 target = expand_builtin_memcpy (exp, target); 6367 if (target) 6368 return target; 6369 break; 6370 6371 case BUILT_IN_MEMPCPY: 6372 target = expand_builtin_mempcpy (exp, target, mode); 6373 if (target) 6374 return target; 6375 break; 6376 6377 case BUILT_IN_MEMSET: 6378 target = expand_builtin_memset (exp, target, mode); 6379 if (target) 6380 return target; 6381 break; 6382 6383 case BUILT_IN_BZERO: 6384 target = expand_builtin_bzero (exp); 6385 if (target) 6386 return target; 6387 break; 6388 6389 case BUILT_IN_STRCMP: 6390 target = expand_builtin_strcmp (exp, target); 6391 if (target) 6392 return target; 6393 break; 6394 6395 case BUILT_IN_STRNCMP: 6396 target = expand_builtin_strncmp (exp, target, mode); 6397 if (target) 6398 return target; 6399 break; 6400 6401 case BUILT_IN_BCMP: 6402 case BUILT_IN_MEMCMP: 6403 target = expand_builtin_memcmp (exp, target, mode); 6404 if (target) 6405 return target; 6406 break; 6407 6408 case BUILT_IN_SETJMP: 6409 /* This should have been lowered to the builtins below. */ 6410 gcc_unreachable (); 6411 6412 case BUILT_IN_SETJMP_SETUP: 6413 /* __builtin_setjmp_setup is passed a pointer to an array of five words 6414 and the receiver label. */ 6415 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 6416 { 6417 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget, 6418 VOIDmode, EXPAND_NORMAL); 6419 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0); 6420 rtx label_r = label_rtx (label); 6421 6422 /* This is copied from the handling of non-local gotos. */ 6423 expand_builtin_setjmp_setup (buf_addr, label_r); 6424 nonlocal_goto_handler_labels 6425 = gen_rtx_INSN_LIST (VOIDmode, label_r, 6426 nonlocal_goto_handler_labels); 6427 /* ??? Do not let expand_label treat us as such since we would 6428 not want to be both on the list of non-local labels and on 6429 the list of forced labels. */ 6430 FORCED_LABEL (label) = 0; 6431 return const0_rtx; 6432 } 6433 break; 6434 6435 case BUILT_IN_SETJMP_RECEIVER: 6436 /* __builtin_setjmp_receiver is passed the receiver label. */ 6437 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 6438 { 6439 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0); 6440 rtx label_r = label_rtx (label); 6441 6442 expand_builtin_setjmp_receiver (label_r); 6443 return const0_rtx; 6444 } 6445 break; 6446 6447 /* __builtin_longjmp is passed a pointer to an array of five words. 6448 It's similar to the C library longjmp function but works with 6449 __builtin_setjmp above. */ 6450 case BUILT_IN_LONGJMP: 6451 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6452 { 6453 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget, 6454 VOIDmode, EXPAND_NORMAL); 6455 rtx value = expand_normal (CALL_EXPR_ARG (exp, 1)); 6456 6457 if (value != const1_rtx) 6458 { 6459 error ("%<__builtin_longjmp%> second argument must be 1"); 6460 return const0_rtx; 6461 } 6462 6463 expand_builtin_longjmp (buf_addr, value); 6464 return const0_rtx; 6465 } 6466 break; 6467 6468 case BUILT_IN_NONLOCAL_GOTO: 6469 target = expand_builtin_nonlocal_goto (exp); 6470 if (target) 6471 return target; 6472 break; 6473 6474 /* This updates the setjmp buffer that is its argument with the value 6475 of the current stack pointer. */ 6476 case BUILT_IN_UPDATE_SETJMP_BUF: 6477 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 6478 { 6479 rtx buf_addr 6480 = expand_normal (CALL_EXPR_ARG (exp, 0)); 6481 6482 expand_builtin_update_setjmp_buf (buf_addr); 6483 return const0_rtx; 6484 } 6485 break; 6486 6487 case BUILT_IN_TRAP: 6488 expand_builtin_trap (); 6489 return const0_rtx; 6490 6491 case BUILT_IN_UNREACHABLE: 6492 expand_builtin_unreachable (); 6493 return const0_rtx; 6494 6495 CASE_FLT_FN (BUILT_IN_SIGNBIT): 6496 case BUILT_IN_SIGNBITD32: 6497 case BUILT_IN_SIGNBITD64: 6498 case BUILT_IN_SIGNBITD128: 6499 target = expand_builtin_signbit (exp, target); 6500 if (target) 6501 return target; 6502 break; 6503 6504 /* Various hooks for the DWARF 2 __throw routine. */ 6505 case BUILT_IN_UNWIND_INIT: 6506 expand_builtin_unwind_init (); 6507 return const0_rtx; 6508 case BUILT_IN_DWARF_CFA: 6509 return virtual_cfa_rtx; 6510#ifdef DWARF2_UNWIND_INFO 6511 case BUILT_IN_DWARF_SP_COLUMN: 6512 return expand_builtin_dwarf_sp_column (); 6513 case BUILT_IN_INIT_DWARF_REG_SIZES: 6514 expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0)); 6515 return const0_rtx; 6516#endif 6517 case BUILT_IN_FROB_RETURN_ADDR: 6518 return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0)); 6519 case BUILT_IN_EXTRACT_RETURN_ADDR: 6520 return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0)); 6521 case BUILT_IN_EH_RETURN: 6522 expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0), 6523 CALL_EXPR_ARG (exp, 1)); 6524 return const0_rtx; 6525#ifdef EH_RETURN_DATA_REGNO 6526 case BUILT_IN_EH_RETURN_DATA_REGNO: 6527 return expand_builtin_eh_return_data_regno (exp); 6528#endif 6529 case BUILT_IN_EXTEND_POINTER: 6530 return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0)); 6531 case BUILT_IN_EH_POINTER: 6532 return expand_builtin_eh_pointer (exp); 6533 case BUILT_IN_EH_FILTER: 6534 return expand_builtin_eh_filter (exp); 6535 case BUILT_IN_EH_COPY_VALUES: 6536 return expand_builtin_eh_copy_values (exp); 6537 6538 case BUILT_IN_VA_START: 6539 return expand_builtin_va_start (exp); 6540 case BUILT_IN_VA_END: 6541 return expand_builtin_va_end (exp); 6542 case BUILT_IN_VA_COPY: 6543 return expand_builtin_va_copy (exp); 6544 case BUILT_IN_EXPECT: 6545 return expand_builtin_expect (exp, target); 6546 case BUILT_IN_ASSUME_ALIGNED: 6547 return expand_builtin_assume_aligned (exp, target); 6548 case BUILT_IN_PREFETCH: 6549 expand_builtin_prefetch (exp); 6550 return const0_rtx; 6551 6552 case BUILT_IN_INIT_TRAMPOLINE: 6553 return expand_builtin_init_trampoline (exp, true); 6554 case BUILT_IN_INIT_HEAP_TRAMPOLINE: 6555 return expand_builtin_init_trampoline (exp, false); 6556 case BUILT_IN_ADJUST_TRAMPOLINE: 6557 return expand_builtin_adjust_trampoline (exp); 6558 6559 case BUILT_IN_FORK: 6560 case BUILT_IN_EXECL: 6561 case BUILT_IN_EXECV: 6562 case BUILT_IN_EXECLP: 6563 case BUILT_IN_EXECLE: 6564 case BUILT_IN_EXECVP: 6565 case BUILT_IN_EXECVE: 6566 target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore); 6567 if (target) 6568 return target; 6569 break; 6570 6571 case BUILT_IN_SYNC_FETCH_AND_ADD_1: 6572 case BUILT_IN_SYNC_FETCH_AND_ADD_2: 6573 case BUILT_IN_SYNC_FETCH_AND_ADD_4: 6574 case BUILT_IN_SYNC_FETCH_AND_ADD_8: 6575 case BUILT_IN_SYNC_FETCH_AND_ADD_16: 6576 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_ADD_1); 6577 target = expand_builtin_sync_operation (mode, exp, PLUS, false, target); 6578 if (target) 6579 return target; 6580 break; 6581 6582 case BUILT_IN_SYNC_FETCH_AND_SUB_1: 6583 case BUILT_IN_SYNC_FETCH_AND_SUB_2: 6584 case BUILT_IN_SYNC_FETCH_AND_SUB_4: 6585 case BUILT_IN_SYNC_FETCH_AND_SUB_8: 6586 case BUILT_IN_SYNC_FETCH_AND_SUB_16: 6587 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_SUB_1); 6588 target = expand_builtin_sync_operation (mode, exp, MINUS, false, target); 6589 if (target) 6590 return target; 6591 break; 6592 6593 case BUILT_IN_SYNC_FETCH_AND_OR_1: 6594 case BUILT_IN_SYNC_FETCH_AND_OR_2: 6595 case BUILT_IN_SYNC_FETCH_AND_OR_4: 6596 case BUILT_IN_SYNC_FETCH_AND_OR_8: 6597 case BUILT_IN_SYNC_FETCH_AND_OR_16: 6598 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_OR_1); 6599 target = expand_builtin_sync_operation (mode, exp, IOR, false, target); 6600 if (target) 6601 return target; 6602 break; 6603 6604 case BUILT_IN_SYNC_FETCH_AND_AND_1: 6605 case BUILT_IN_SYNC_FETCH_AND_AND_2: 6606 case BUILT_IN_SYNC_FETCH_AND_AND_4: 6607 case BUILT_IN_SYNC_FETCH_AND_AND_8: 6608 case BUILT_IN_SYNC_FETCH_AND_AND_16: 6609 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_AND_1); 6610 target = expand_builtin_sync_operation (mode, exp, AND, false, target); 6611 if (target) 6612 return target; 6613 break; 6614 6615 case BUILT_IN_SYNC_FETCH_AND_XOR_1: 6616 case BUILT_IN_SYNC_FETCH_AND_XOR_2: 6617 case BUILT_IN_SYNC_FETCH_AND_XOR_4: 6618 case BUILT_IN_SYNC_FETCH_AND_XOR_8: 6619 case BUILT_IN_SYNC_FETCH_AND_XOR_16: 6620 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_XOR_1); 6621 target = expand_builtin_sync_operation (mode, exp, XOR, false, target); 6622 if (target) 6623 return target; 6624 break; 6625 6626 case BUILT_IN_SYNC_FETCH_AND_NAND_1: 6627 case BUILT_IN_SYNC_FETCH_AND_NAND_2: 6628 case BUILT_IN_SYNC_FETCH_AND_NAND_4: 6629 case BUILT_IN_SYNC_FETCH_AND_NAND_8: 6630 case BUILT_IN_SYNC_FETCH_AND_NAND_16: 6631 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_NAND_1); 6632 target = expand_builtin_sync_operation (mode, exp, NOT, false, target); 6633 if (target) 6634 return target; 6635 break; 6636 6637 case BUILT_IN_SYNC_ADD_AND_FETCH_1: 6638 case BUILT_IN_SYNC_ADD_AND_FETCH_2: 6639 case BUILT_IN_SYNC_ADD_AND_FETCH_4: 6640 case BUILT_IN_SYNC_ADD_AND_FETCH_8: 6641 case BUILT_IN_SYNC_ADD_AND_FETCH_16: 6642 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_ADD_AND_FETCH_1); 6643 target = expand_builtin_sync_operation (mode, exp, PLUS, true, target); 6644 if (target) 6645 return target; 6646 break; 6647 6648 case BUILT_IN_SYNC_SUB_AND_FETCH_1: 6649 case BUILT_IN_SYNC_SUB_AND_FETCH_2: 6650 case BUILT_IN_SYNC_SUB_AND_FETCH_4: 6651 case BUILT_IN_SYNC_SUB_AND_FETCH_8: 6652 case BUILT_IN_SYNC_SUB_AND_FETCH_16: 6653 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_SUB_AND_FETCH_1); 6654 target = expand_builtin_sync_operation (mode, exp, MINUS, true, target); 6655 if (target) 6656 return target; 6657 break; 6658 6659 case BUILT_IN_SYNC_OR_AND_FETCH_1: 6660 case BUILT_IN_SYNC_OR_AND_FETCH_2: 6661 case BUILT_IN_SYNC_OR_AND_FETCH_4: 6662 case BUILT_IN_SYNC_OR_AND_FETCH_8: 6663 case BUILT_IN_SYNC_OR_AND_FETCH_16: 6664 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_OR_AND_FETCH_1); 6665 target = expand_builtin_sync_operation (mode, exp, IOR, true, target); 6666 if (target) 6667 return target; 6668 break; 6669 6670 case BUILT_IN_SYNC_AND_AND_FETCH_1: 6671 case BUILT_IN_SYNC_AND_AND_FETCH_2: 6672 case BUILT_IN_SYNC_AND_AND_FETCH_4: 6673 case BUILT_IN_SYNC_AND_AND_FETCH_8: 6674 case BUILT_IN_SYNC_AND_AND_FETCH_16: 6675 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_AND_AND_FETCH_1); 6676 target = expand_builtin_sync_operation (mode, exp, AND, true, target); 6677 if (target) 6678 return target; 6679 break; 6680 6681 case BUILT_IN_SYNC_XOR_AND_FETCH_1: 6682 case BUILT_IN_SYNC_XOR_AND_FETCH_2: 6683 case BUILT_IN_SYNC_XOR_AND_FETCH_4: 6684 case BUILT_IN_SYNC_XOR_AND_FETCH_8: 6685 case BUILT_IN_SYNC_XOR_AND_FETCH_16: 6686 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_XOR_AND_FETCH_1); 6687 target = expand_builtin_sync_operation (mode, exp, XOR, true, target); 6688 if (target) 6689 return target; 6690 break; 6691 6692 case BUILT_IN_SYNC_NAND_AND_FETCH_1: 6693 case BUILT_IN_SYNC_NAND_AND_FETCH_2: 6694 case BUILT_IN_SYNC_NAND_AND_FETCH_4: 6695 case BUILT_IN_SYNC_NAND_AND_FETCH_8: 6696 case BUILT_IN_SYNC_NAND_AND_FETCH_16: 6697 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_NAND_AND_FETCH_1); 6698 target = expand_builtin_sync_operation (mode, exp, NOT, true, target); 6699 if (target) 6700 return target; 6701 break; 6702 6703 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1: 6704 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2: 6705 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4: 6706 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8: 6707 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16: 6708 if (mode == VOIDmode) 6709 mode = TYPE_MODE (boolean_type_node); 6710 if (!target || !register_operand (target, mode)) 6711 target = gen_reg_rtx (mode); 6712 6713 mode = get_builtin_sync_mode 6714 (fcode - BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1); 6715 target = expand_builtin_compare_and_swap (mode, exp, true, target); 6716 if (target) 6717 return target; 6718 break; 6719 6720 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1: 6721 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2: 6722 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4: 6723 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8: 6724 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16: 6725 mode = get_builtin_sync_mode 6726 (fcode - BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1); 6727 target = expand_builtin_compare_and_swap (mode, exp, false, target); 6728 if (target) 6729 return target; 6730 break; 6731 6732 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1: 6733 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2: 6734 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4: 6735 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8: 6736 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16: 6737 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_TEST_AND_SET_1); 6738 target = expand_builtin_sync_lock_test_and_set (mode, exp, target); 6739 if (target) 6740 return target; 6741 break; 6742 6743 case BUILT_IN_SYNC_LOCK_RELEASE_1: 6744 case BUILT_IN_SYNC_LOCK_RELEASE_2: 6745 case BUILT_IN_SYNC_LOCK_RELEASE_4: 6746 case BUILT_IN_SYNC_LOCK_RELEASE_8: 6747 case BUILT_IN_SYNC_LOCK_RELEASE_16: 6748 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_RELEASE_1); 6749 expand_builtin_sync_lock_release (mode, exp); 6750 return const0_rtx; 6751 6752 case BUILT_IN_SYNC_SYNCHRONIZE: 6753 expand_builtin_sync_synchronize (); 6754 return const0_rtx; 6755 6756 case BUILT_IN_ATOMIC_EXCHANGE_1: 6757 case BUILT_IN_ATOMIC_EXCHANGE_2: 6758 case BUILT_IN_ATOMIC_EXCHANGE_4: 6759 case BUILT_IN_ATOMIC_EXCHANGE_8: 6760 case BUILT_IN_ATOMIC_EXCHANGE_16: 6761 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_EXCHANGE_1); 6762 target = expand_builtin_atomic_exchange (mode, exp, target); 6763 if (target) 6764 return target; 6765 break; 6766 6767 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1: 6768 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2: 6769 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4: 6770 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8: 6771 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16: 6772 { 6773 unsigned int nargs, z; 6774 vec<tree, va_gc> *vec; 6775 6776 mode = 6777 get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1); 6778 target = expand_builtin_atomic_compare_exchange (mode, exp, target); 6779 if (target) 6780 return target; 6781 6782 /* If this is turned into an external library call, the weak parameter 6783 must be dropped to match the expected parameter list. */ 6784 nargs = call_expr_nargs (exp); 6785 vec_alloc (vec, nargs - 1); 6786 for (z = 0; z < 3; z++) 6787 vec->quick_push (CALL_EXPR_ARG (exp, z)); 6788 /* Skip the boolean weak parameter. */ 6789 for (z = 4; z < 6; z++) 6790 vec->quick_push (CALL_EXPR_ARG (exp, z)); 6791 exp = build_call_vec (TREE_TYPE (exp), CALL_EXPR_FN (exp), vec); 6792 break; 6793 } 6794 6795 case BUILT_IN_ATOMIC_LOAD_1: 6796 case BUILT_IN_ATOMIC_LOAD_2: 6797 case BUILT_IN_ATOMIC_LOAD_4: 6798 case BUILT_IN_ATOMIC_LOAD_8: 6799 case BUILT_IN_ATOMIC_LOAD_16: 6800 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_LOAD_1); 6801 target = expand_builtin_atomic_load (mode, exp, target); 6802 if (target) 6803 return target; 6804 break; 6805 6806 case BUILT_IN_ATOMIC_STORE_1: 6807 case BUILT_IN_ATOMIC_STORE_2: 6808 case BUILT_IN_ATOMIC_STORE_4: 6809 case BUILT_IN_ATOMIC_STORE_8: 6810 case BUILT_IN_ATOMIC_STORE_16: 6811 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_STORE_1); 6812 target = expand_builtin_atomic_store (mode, exp); 6813 if (target) 6814 return const0_rtx; 6815 break; 6816 6817 case BUILT_IN_ATOMIC_ADD_FETCH_1: 6818 case BUILT_IN_ATOMIC_ADD_FETCH_2: 6819 case BUILT_IN_ATOMIC_ADD_FETCH_4: 6820 case BUILT_IN_ATOMIC_ADD_FETCH_8: 6821 case BUILT_IN_ATOMIC_ADD_FETCH_16: 6822 { 6823 enum built_in_function lib; 6824 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1); 6825 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_ADD_1 + 6826 (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1)); 6827 target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, true, 6828 ignore, lib); 6829 if (target) 6830 return target; 6831 break; 6832 } 6833 case BUILT_IN_ATOMIC_SUB_FETCH_1: 6834 case BUILT_IN_ATOMIC_SUB_FETCH_2: 6835 case BUILT_IN_ATOMIC_SUB_FETCH_4: 6836 case BUILT_IN_ATOMIC_SUB_FETCH_8: 6837 case BUILT_IN_ATOMIC_SUB_FETCH_16: 6838 { 6839 enum built_in_function lib; 6840 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1); 6841 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_SUB_1 + 6842 (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1)); 6843 target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, true, 6844 ignore, lib); 6845 if (target) 6846 return target; 6847 break; 6848 } 6849 case BUILT_IN_ATOMIC_AND_FETCH_1: 6850 case BUILT_IN_ATOMIC_AND_FETCH_2: 6851 case BUILT_IN_ATOMIC_AND_FETCH_4: 6852 case BUILT_IN_ATOMIC_AND_FETCH_8: 6853 case BUILT_IN_ATOMIC_AND_FETCH_16: 6854 { 6855 enum built_in_function lib; 6856 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_AND_FETCH_1); 6857 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_AND_1 + 6858 (fcode - BUILT_IN_ATOMIC_AND_FETCH_1)); 6859 target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, true, 6860 ignore, lib); 6861 if (target) 6862 return target; 6863 break; 6864 } 6865 case BUILT_IN_ATOMIC_NAND_FETCH_1: 6866 case BUILT_IN_ATOMIC_NAND_FETCH_2: 6867 case BUILT_IN_ATOMIC_NAND_FETCH_4: 6868 case BUILT_IN_ATOMIC_NAND_FETCH_8: 6869 case BUILT_IN_ATOMIC_NAND_FETCH_16: 6870 { 6871 enum built_in_function lib; 6872 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1); 6873 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_NAND_1 + 6874 (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1)); 6875 target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, true, 6876 ignore, lib); 6877 if (target) 6878 return target; 6879 break; 6880 } 6881 case BUILT_IN_ATOMIC_XOR_FETCH_1: 6882 case BUILT_IN_ATOMIC_XOR_FETCH_2: 6883 case BUILT_IN_ATOMIC_XOR_FETCH_4: 6884 case BUILT_IN_ATOMIC_XOR_FETCH_8: 6885 case BUILT_IN_ATOMIC_XOR_FETCH_16: 6886 { 6887 enum built_in_function lib; 6888 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1); 6889 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_XOR_1 + 6890 (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1)); 6891 target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, true, 6892 ignore, lib); 6893 if (target) 6894 return target; 6895 break; 6896 } 6897 case BUILT_IN_ATOMIC_OR_FETCH_1: 6898 case BUILT_IN_ATOMIC_OR_FETCH_2: 6899 case BUILT_IN_ATOMIC_OR_FETCH_4: 6900 case BUILT_IN_ATOMIC_OR_FETCH_8: 6901 case BUILT_IN_ATOMIC_OR_FETCH_16: 6902 { 6903 enum built_in_function lib; 6904 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_OR_FETCH_1); 6905 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_OR_1 + 6906 (fcode - BUILT_IN_ATOMIC_OR_FETCH_1)); 6907 target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, true, 6908 ignore, lib); 6909 if (target) 6910 return target; 6911 break; 6912 } 6913 case BUILT_IN_ATOMIC_FETCH_ADD_1: 6914 case BUILT_IN_ATOMIC_FETCH_ADD_2: 6915 case BUILT_IN_ATOMIC_FETCH_ADD_4: 6916 case BUILT_IN_ATOMIC_FETCH_ADD_8: 6917 case BUILT_IN_ATOMIC_FETCH_ADD_16: 6918 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_ADD_1); 6919 target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, false, 6920 ignore, BUILT_IN_NONE); 6921 if (target) 6922 return target; 6923 break; 6924 6925 case BUILT_IN_ATOMIC_FETCH_SUB_1: 6926 case BUILT_IN_ATOMIC_FETCH_SUB_2: 6927 case BUILT_IN_ATOMIC_FETCH_SUB_4: 6928 case BUILT_IN_ATOMIC_FETCH_SUB_8: 6929 case BUILT_IN_ATOMIC_FETCH_SUB_16: 6930 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_SUB_1); 6931 target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, false, 6932 ignore, BUILT_IN_NONE); 6933 if (target) 6934 return target; 6935 break; 6936 6937 case BUILT_IN_ATOMIC_FETCH_AND_1: 6938 case BUILT_IN_ATOMIC_FETCH_AND_2: 6939 case BUILT_IN_ATOMIC_FETCH_AND_4: 6940 case BUILT_IN_ATOMIC_FETCH_AND_8: 6941 case BUILT_IN_ATOMIC_FETCH_AND_16: 6942 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_AND_1); 6943 target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, false, 6944 ignore, BUILT_IN_NONE); 6945 if (target) 6946 return target; 6947 break; 6948 6949 case BUILT_IN_ATOMIC_FETCH_NAND_1: 6950 case BUILT_IN_ATOMIC_FETCH_NAND_2: 6951 case BUILT_IN_ATOMIC_FETCH_NAND_4: 6952 case BUILT_IN_ATOMIC_FETCH_NAND_8: 6953 case BUILT_IN_ATOMIC_FETCH_NAND_16: 6954 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_NAND_1); 6955 target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, false, 6956 ignore, BUILT_IN_NONE); 6957 if (target) 6958 return target; 6959 break; 6960 6961 case BUILT_IN_ATOMIC_FETCH_XOR_1: 6962 case BUILT_IN_ATOMIC_FETCH_XOR_2: 6963 case BUILT_IN_ATOMIC_FETCH_XOR_4: 6964 case BUILT_IN_ATOMIC_FETCH_XOR_8: 6965 case BUILT_IN_ATOMIC_FETCH_XOR_16: 6966 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_XOR_1); 6967 target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, false, 6968 ignore, BUILT_IN_NONE); 6969 if (target) 6970 return target; 6971 break; 6972 6973 case BUILT_IN_ATOMIC_FETCH_OR_1: 6974 case BUILT_IN_ATOMIC_FETCH_OR_2: 6975 case BUILT_IN_ATOMIC_FETCH_OR_4: 6976 case BUILT_IN_ATOMIC_FETCH_OR_8: 6977 case BUILT_IN_ATOMIC_FETCH_OR_16: 6978 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_OR_1); 6979 target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, false, 6980 ignore, BUILT_IN_NONE); 6981 if (target) 6982 return target; 6983 break; 6984 6985 case BUILT_IN_ATOMIC_TEST_AND_SET: 6986 return expand_builtin_atomic_test_and_set (exp, target); 6987 6988 case BUILT_IN_ATOMIC_CLEAR: 6989 return expand_builtin_atomic_clear (exp); 6990 6991 case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE: 6992 return expand_builtin_atomic_always_lock_free (exp); 6993 6994 case BUILT_IN_ATOMIC_IS_LOCK_FREE: 6995 target = expand_builtin_atomic_is_lock_free (exp); 6996 if (target) 6997 return target; 6998 break; 6999 7000 case BUILT_IN_ATOMIC_THREAD_FENCE: 7001 expand_builtin_atomic_thread_fence (exp); 7002 return const0_rtx; 7003 7004 case BUILT_IN_ATOMIC_SIGNAL_FENCE: 7005 expand_builtin_atomic_signal_fence (exp); 7006 return const0_rtx; 7007 7008 case BUILT_IN_OBJECT_SIZE: 7009 return expand_builtin_object_size (exp); 7010 7011 case BUILT_IN_MEMCPY_CHK: 7012 case BUILT_IN_MEMPCPY_CHK: 7013 case BUILT_IN_MEMMOVE_CHK: 7014 case BUILT_IN_MEMSET_CHK: 7015 target = expand_builtin_memory_chk (exp, target, mode, fcode); 7016 if (target) 7017 return target; 7018 break; 7019 7020 case BUILT_IN_STRCPY_CHK: 7021 case BUILT_IN_STPCPY_CHK: 7022 case BUILT_IN_STRNCPY_CHK: 7023 case BUILT_IN_STPNCPY_CHK: 7024 case BUILT_IN_STRCAT_CHK: 7025 case BUILT_IN_STRNCAT_CHK: 7026 case BUILT_IN_SNPRINTF_CHK: 7027 case BUILT_IN_VSNPRINTF_CHK: 7028 maybe_emit_chk_warning (exp, fcode); 7029 break; 7030 7031 case BUILT_IN_SPRINTF_CHK: 7032 case BUILT_IN_VSPRINTF_CHK: 7033 maybe_emit_sprintf_chk_warning (exp, fcode); 7034 break; 7035 7036 case BUILT_IN_FREE: 7037 if (warn_free_nonheap_object) 7038 maybe_emit_free_warning (exp); 7039 break; 7040 7041 case BUILT_IN_THREAD_POINTER: 7042 return expand_builtin_thread_pointer (exp, target); 7043 7044 case BUILT_IN_SET_THREAD_POINTER: 7045 expand_builtin_set_thread_pointer (exp); 7046 return const0_rtx; 7047 7048 case BUILT_IN_CILK_DETACH: 7049 expand_builtin_cilk_detach (exp); 7050 return const0_rtx; 7051 7052 case BUILT_IN_CILK_POP_FRAME: 7053 expand_builtin_cilk_pop_frame (exp); 7054 return const0_rtx; 7055 7056 case BUILT_IN_CHKP_INIT_PTR_BOUNDS: 7057 case BUILT_IN_CHKP_NULL_PTR_BOUNDS: 7058 case BUILT_IN_CHKP_COPY_PTR_BOUNDS: 7059 case BUILT_IN_CHKP_CHECK_PTR_LBOUNDS: 7060 case BUILT_IN_CHKP_CHECK_PTR_UBOUNDS: 7061 case BUILT_IN_CHKP_CHECK_PTR_BOUNDS: 7062 case BUILT_IN_CHKP_SET_PTR_BOUNDS: 7063 case BUILT_IN_CHKP_NARROW_PTR_BOUNDS: 7064 case BUILT_IN_CHKP_STORE_PTR_BOUNDS: 7065 case BUILT_IN_CHKP_GET_PTR_LBOUND: 7066 case BUILT_IN_CHKP_GET_PTR_UBOUND: 7067 /* We allow user CHKP builtins if Pointer Bounds 7068 Checker is off. */ 7069 if (!chkp_function_instrumented_p (current_function_decl)) 7070 { 7071 if (fcode == BUILT_IN_CHKP_SET_PTR_BOUNDS 7072 || fcode == BUILT_IN_CHKP_NARROW_PTR_BOUNDS 7073 || fcode == BUILT_IN_CHKP_INIT_PTR_BOUNDS 7074 || fcode == BUILT_IN_CHKP_NULL_PTR_BOUNDS 7075 || fcode == BUILT_IN_CHKP_COPY_PTR_BOUNDS) 7076 return expand_normal (CALL_EXPR_ARG (exp, 0)); 7077 else if (fcode == BUILT_IN_CHKP_GET_PTR_LBOUND) 7078 return expand_normal (size_zero_node); 7079 else if (fcode == BUILT_IN_CHKP_GET_PTR_UBOUND) 7080 return expand_normal (size_int (-1)); 7081 else 7082 return const0_rtx; 7083 } 7084 /* FALLTHROUGH */ 7085 7086 case BUILT_IN_CHKP_BNDMK: 7087 case BUILT_IN_CHKP_BNDSTX: 7088 case BUILT_IN_CHKP_BNDCL: 7089 case BUILT_IN_CHKP_BNDCU: 7090 case BUILT_IN_CHKP_BNDLDX: 7091 case BUILT_IN_CHKP_BNDRET: 7092 case BUILT_IN_CHKP_INTERSECT: 7093 case BUILT_IN_CHKP_NARROW: 7094 case BUILT_IN_CHKP_EXTRACT_LOWER: 7095 case BUILT_IN_CHKP_EXTRACT_UPPER: 7096 /* Software implementation of Pointer Bounds Checker is NYI. 7097 Target support is required. */ 7098 error ("Your target platform does not support -fcheck-pointer-bounds"); 7099 break; 7100 7101 case BUILT_IN_ACC_ON_DEVICE: 7102 target = expand_builtin_acc_on_device (exp, target); 7103 if (target) 7104 return target; 7105 break; 7106 7107 default: /* just do library call, if unknown builtin */ 7108 break; 7109 } 7110 7111 /* The switch statement above can drop through to cause the function 7112 to be called normally. */ 7113 return expand_call (exp, target, ignore); 7114} 7115 7116/* Similar to expand_builtin but is used for instrumented calls. */ 7117 7118rtx 7119expand_builtin_with_bounds (tree exp, rtx target, 7120 rtx subtarget ATTRIBUTE_UNUSED, 7121 machine_mode mode, int ignore) 7122{ 7123 tree fndecl = get_callee_fndecl (exp); 7124 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 7125 7126 gcc_assert (CALL_WITH_BOUNDS_P (exp)); 7127 7128 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 7129 return targetm.expand_builtin (exp, target, subtarget, mode, ignore); 7130 7131 gcc_assert (fcode > BEGIN_CHKP_BUILTINS 7132 && fcode < END_CHKP_BUILTINS); 7133 7134 switch (fcode) 7135 { 7136 case BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK_CHKP: 7137 target = expand_builtin_memcpy_with_bounds (exp, target); 7138 if (target) 7139 return target; 7140 break; 7141 7142 case BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK_CHKP: 7143 target = expand_builtin_mempcpy_with_bounds (exp, target, mode); 7144 if (target) 7145 return target; 7146 break; 7147 7148 case BUILT_IN_CHKP_MEMSET_NOBND_NOCHK_CHKP: 7149 target = expand_builtin_memset_with_bounds (exp, target, mode); 7150 if (target) 7151 return target; 7152 break; 7153 7154 default: 7155 break; 7156 } 7157 7158 /* The switch statement above can drop through to cause the function 7159 to be called normally. */ 7160 return expand_call (exp, target, ignore); 7161 } 7162 7163/* Determine whether a tree node represents a call to a built-in 7164 function. If the tree T is a call to a built-in function with 7165 the right number of arguments of the appropriate types, return 7166 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. 7167 Otherwise the return value is END_BUILTINS. */ 7168 7169enum built_in_function 7170builtin_mathfn_code (const_tree t) 7171{ 7172 const_tree fndecl, arg, parmlist; 7173 const_tree argtype, parmtype; 7174 const_call_expr_arg_iterator iter; 7175 7176 if (TREE_CODE (t) != CALL_EXPR 7177 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR) 7178 return END_BUILTINS; 7179 7180 fndecl = get_callee_fndecl (t); 7181 if (fndecl == NULL_TREE 7182 || TREE_CODE (fndecl) != FUNCTION_DECL 7183 || ! DECL_BUILT_IN (fndecl) 7184 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 7185 return END_BUILTINS; 7186 7187 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); 7188 init_const_call_expr_arg_iterator (t, &iter); 7189 for (; parmlist; parmlist = TREE_CHAIN (parmlist)) 7190 { 7191 /* If a function doesn't take a variable number of arguments, 7192 the last element in the list will have type `void'. */ 7193 parmtype = TREE_VALUE (parmlist); 7194 if (VOID_TYPE_P (parmtype)) 7195 { 7196 if (more_const_call_expr_args_p (&iter)) 7197 return END_BUILTINS; 7198 return DECL_FUNCTION_CODE (fndecl); 7199 } 7200 7201 if (! more_const_call_expr_args_p (&iter)) 7202 return END_BUILTINS; 7203 7204 arg = next_const_call_expr_arg (&iter); 7205 argtype = TREE_TYPE (arg); 7206 7207 if (SCALAR_FLOAT_TYPE_P (parmtype)) 7208 { 7209 if (! SCALAR_FLOAT_TYPE_P (argtype)) 7210 return END_BUILTINS; 7211 } 7212 else if (COMPLEX_FLOAT_TYPE_P (parmtype)) 7213 { 7214 if (! COMPLEX_FLOAT_TYPE_P (argtype)) 7215 return END_BUILTINS; 7216 } 7217 else if (POINTER_TYPE_P (parmtype)) 7218 { 7219 if (! POINTER_TYPE_P (argtype)) 7220 return END_BUILTINS; 7221 } 7222 else if (INTEGRAL_TYPE_P (parmtype)) 7223 { 7224 if (! INTEGRAL_TYPE_P (argtype)) 7225 return END_BUILTINS; 7226 } 7227 else 7228 return END_BUILTINS; 7229 } 7230 7231 /* Variable-length argument list. */ 7232 return DECL_FUNCTION_CODE (fndecl); 7233} 7234 7235/* Fold a call to __builtin_constant_p, if we know its argument ARG will 7236 evaluate to a constant. */ 7237 7238static tree 7239fold_builtin_constant_p (tree arg) 7240{ 7241 /* We return 1 for a numeric type that's known to be a constant 7242 value at compile-time or for an aggregate type that's a 7243 literal constant. */ 7244 STRIP_NOPS (arg); 7245 7246 /* If we know this is a constant, emit the constant of one. */ 7247 if (CONSTANT_CLASS_P (arg) 7248 || (TREE_CODE (arg) == CONSTRUCTOR 7249 && TREE_CONSTANT (arg))) 7250 return integer_one_node; 7251 if (TREE_CODE (arg) == ADDR_EXPR) 7252 { 7253 tree op = TREE_OPERAND (arg, 0); 7254 if (TREE_CODE (op) == STRING_CST 7255 || (TREE_CODE (op) == ARRAY_REF 7256 && integer_zerop (TREE_OPERAND (op, 1)) 7257 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST)) 7258 return integer_one_node; 7259 } 7260 7261 /* If this expression has side effects, show we don't know it to be a 7262 constant. Likewise if it's a pointer or aggregate type since in 7263 those case we only want literals, since those are only optimized 7264 when generating RTL, not later. 7265 And finally, if we are compiling an initializer, not code, we 7266 need to return a definite result now; there's not going to be any 7267 more optimization done. */ 7268 if (TREE_SIDE_EFFECTS (arg) 7269 || AGGREGATE_TYPE_P (TREE_TYPE (arg)) 7270 || POINTER_TYPE_P (TREE_TYPE (arg)) 7271 || cfun == 0 7272 || folding_initializer 7273 || force_folding_builtin_constant_p) 7274 return integer_zero_node; 7275 7276 return NULL_TREE; 7277} 7278 7279/* Create builtin_expect with PRED and EXPECTED as its arguments and 7280 return it as a truthvalue. */ 7281 7282static tree 7283build_builtin_expect_predicate (location_t loc, tree pred, tree expected, 7284 tree predictor) 7285{ 7286 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type; 7287 7288 fn = builtin_decl_explicit (BUILT_IN_EXPECT); 7289 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); 7290 ret_type = TREE_TYPE (TREE_TYPE (fn)); 7291 pred_type = TREE_VALUE (arg_types); 7292 expected_type = TREE_VALUE (TREE_CHAIN (arg_types)); 7293 7294 pred = fold_convert_loc (loc, pred_type, pred); 7295 expected = fold_convert_loc (loc, expected_type, expected); 7296 call_expr = build_call_expr_loc (loc, fn, predictor ? 3 : 2, pred, expected, 7297 predictor); 7298 7299 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr, 7300 build_int_cst (ret_type, 0)); 7301} 7302 7303/* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return 7304 NULL_TREE if no simplification is possible. */ 7305 7306tree 7307fold_builtin_expect (location_t loc, tree arg0, tree arg1, tree arg2) 7308{ 7309 tree inner, fndecl, inner_arg0; 7310 enum tree_code code; 7311 7312 /* Distribute the expected value over short-circuiting operators. 7313 See through the cast from truthvalue_type_node to long. */ 7314 inner_arg0 = arg0; 7315 while (CONVERT_EXPR_P (inner_arg0) 7316 && INTEGRAL_TYPE_P (TREE_TYPE (inner_arg0)) 7317 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner_arg0, 0)))) 7318 inner_arg0 = TREE_OPERAND (inner_arg0, 0); 7319 7320 /* If this is a builtin_expect within a builtin_expect keep the 7321 inner one. See through a comparison against a constant. It 7322 might have been added to create a thruthvalue. */ 7323 inner = inner_arg0; 7324 7325 if (COMPARISON_CLASS_P (inner) 7326 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST) 7327 inner = TREE_OPERAND (inner, 0); 7328 7329 if (TREE_CODE (inner) == CALL_EXPR 7330 && (fndecl = get_callee_fndecl (inner)) 7331 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL 7332 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT) 7333 return arg0; 7334 7335 inner = inner_arg0; 7336 code = TREE_CODE (inner); 7337 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) 7338 { 7339 tree op0 = TREE_OPERAND (inner, 0); 7340 tree op1 = TREE_OPERAND (inner, 1); 7341 7342 op0 = build_builtin_expect_predicate (loc, op0, arg1, arg2); 7343 op1 = build_builtin_expect_predicate (loc, op1, arg1, arg2); 7344 inner = build2 (code, TREE_TYPE (inner), op0, op1); 7345 7346 return fold_convert_loc (loc, TREE_TYPE (arg0), inner); 7347 } 7348 7349 /* If the argument isn't invariant then there's nothing else we can do. */ 7350 if (!TREE_CONSTANT (inner_arg0)) 7351 return NULL_TREE; 7352 7353 /* If we expect that a comparison against the argument will fold to 7354 a constant return the constant. In practice, this means a true 7355 constant or the address of a non-weak symbol. */ 7356 inner = inner_arg0; 7357 STRIP_NOPS (inner); 7358 if (TREE_CODE (inner) == ADDR_EXPR) 7359 { 7360 do 7361 { 7362 inner = TREE_OPERAND (inner, 0); 7363 } 7364 while (TREE_CODE (inner) == COMPONENT_REF 7365 || TREE_CODE (inner) == ARRAY_REF); 7366 if ((TREE_CODE (inner) == VAR_DECL 7367 || TREE_CODE (inner) == FUNCTION_DECL) 7368 && DECL_WEAK (inner)) 7369 return NULL_TREE; 7370 } 7371 7372 /* Otherwise, ARG0 already has the proper type for the return value. */ 7373 return arg0; 7374} 7375 7376/* Fold a call to __builtin_classify_type with argument ARG. */ 7377 7378static tree 7379fold_builtin_classify_type (tree arg) 7380{ 7381 if (arg == 0) 7382 return build_int_cst (integer_type_node, no_type_class); 7383 7384 return build_int_cst (integer_type_node, type_to_class (TREE_TYPE (arg))); 7385} 7386 7387/* Fold a call to __builtin_strlen with argument ARG. */ 7388 7389static tree 7390fold_builtin_strlen (location_t loc, tree type, tree arg) 7391{ 7392 if (!validate_arg (arg, POINTER_TYPE)) 7393 return NULL_TREE; 7394 else 7395 { 7396 tree len = c_strlen (arg, 0); 7397 7398 if (len) 7399 return fold_convert_loc (loc, type, len); 7400 7401 return NULL_TREE; 7402 } 7403} 7404 7405/* Fold a call to __builtin_inf or __builtin_huge_val. */ 7406 7407static tree 7408fold_builtin_inf (location_t loc, tree type, int warn) 7409{ 7410 REAL_VALUE_TYPE real; 7411 7412 /* __builtin_inff is intended to be usable to define INFINITY on all 7413 targets. If an infinity is not available, INFINITY expands "to a 7414 positive constant of type float that overflows at translation 7415 time", footnote "In this case, using INFINITY will violate the 7416 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4). 7417 Thus we pedwarn to ensure this constraint violation is 7418 diagnosed. */ 7419 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn) 7420 pedwarn (loc, 0, "target format does not support infinity"); 7421 7422 real_inf (&real); 7423 return build_real (type, real); 7424} 7425 7426/* Fold a call to __builtin_nan or __builtin_nans with argument ARG. */ 7427 7428static tree 7429fold_builtin_nan (tree arg, tree type, int quiet) 7430{ 7431 REAL_VALUE_TYPE real; 7432 const char *str; 7433 7434 if (!validate_arg (arg, POINTER_TYPE)) 7435 return NULL_TREE; 7436 str = c_getstr (arg); 7437 if (!str) 7438 return NULL_TREE; 7439 7440 if (!real_nan (&real, str, quiet, TYPE_MODE (type))) 7441 return NULL_TREE; 7442 7443 return build_real (type, real); 7444} 7445 7446/* Return true if the floating point expression T has an integer value. 7447 We also allow +Inf, -Inf and NaN to be considered integer values. */ 7448 7449static bool 7450integer_valued_real_p (tree t) 7451{ 7452 switch (TREE_CODE (t)) 7453 { 7454 case FLOAT_EXPR: 7455 return true; 7456 7457 case ABS_EXPR: 7458 case SAVE_EXPR: 7459 return integer_valued_real_p (TREE_OPERAND (t, 0)); 7460 7461 case COMPOUND_EXPR: 7462 case MODIFY_EXPR: 7463 case BIND_EXPR: 7464 return integer_valued_real_p (TREE_OPERAND (t, 1)); 7465 7466 case PLUS_EXPR: 7467 case MINUS_EXPR: 7468 case MULT_EXPR: 7469 case MIN_EXPR: 7470 case MAX_EXPR: 7471 return integer_valued_real_p (TREE_OPERAND (t, 0)) 7472 && integer_valued_real_p (TREE_OPERAND (t, 1)); 7473 7474 case COND_EXPR: 7475 return integer_valued_real_p (TREE_OPERAND (t, 1)) 7476 && integer_valued_real_p (TREE_OPERAND (t, 2)); 7477 7478 case REAL_CST: 7479 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t))); 7480 7481 CASE_CONVERT: 7482 { 7483 tree type = TREE_TYPE (TREE_OPERAND (t, 0)); 7484 if (TREE_CODE (type) == INTEGER_TYPE) 7485 return true; 7486 if (TREE_CODE (type) == REAL_TYPE) 7487 return integer_valued_real_p (TREE_OPERAND (t, 0)); 7488 break; 7489 } 7490 7491 case CALL_EXPR: 7492 switch (builtin_mathfn_code (t)) 7493 { 7494 CASE_FLT_FN (BUILT_IN_CEIL): 7495 CASE_FLT_FN (BUILT_IN_FLOOR): 7496 CASE_FLT_FN (BUILT_IN_NEARBYINT): 7497 CASE_FLT_FN (BUILT_IN_RINT): 7498 CASE_FLT_FN (BUILT_IN_ROUND): 7499 CASE_FLT_FN (BUILT_IN_TRUNC): 7500 return true; 7501 7502 CASE_FLT_FN (BUILT_IN_FMIN): 7503 CASE_FLT_FN (BUILT_IN_FMAX): 7504 return integer_valued_real_p (CALL_EXPR_ARG (t, 0)) 7505 && integer_valued_real_p (CALL_EXPR_ARG (t, 1)); 7506 7507 default: 7508 break; 7509 } 7510 break; 7511 7512 default: 7513 break; 7514 } 7515 return false; 7516} 7517 7518/* FNDECL is assumed to be a builtin where truncation can be propagated 7519 across (for instance floor((double)f) == (double)floorf (f). 7520 Do the transformation for a call with argument ARG. */ 7521 7522static tree 7523fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg) 7524{ 7525 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 7526 7527 if (!validate_arg (arg, REAL_TYPE)) 7528 return NULL_TREE; 7529 7530 /* Integer rounding functions are idempotent. */ 7531 if (fcode == builtin_mathfn_code (arg)) 7532 return arg; 7533 7534 /* If argument is already integer valued, and we don't need to worry 7535 about setting errno, there's no need to perform rounding. */ 7536 if (! flag_errno_math && integer_valued_real_p (arg)) 7537 return arg; 7538 7539 if (optimize) 7540 { 7541 tree arg0 = strip_float_extensions (arg); 7542 tree ftype = TREE_TYPE (TREE_TYPE (fndecl)); 7543 tree newtype = TREE_TYPE (arg0); 7544 tree decl; 7545 7546 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype) 7547 && (decl = mathfn_built_in (newtype, fcode))) 7548 return fold_convert_loc (loc, ftype, 7549 build_call_expr_loc (loc, decl, 1, 7550 fold_convert_loc (loc, 7551 newtype, 7552 arg0))); 7553 } 7554 return NULL_TREE; 7555} 7556 7557/* FNDECL is assumed to be builtin which can narrow the FP type of 7558 the argument, for instance lround((double)f) -> lroundf (f). 7559 Do the transformation for a call with argument ARG. */ 7560 7561static tree 7562fold_fixed_mathfn (location_t loc, tree fndecl, tree arg) 7563{ 7564 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 7565 7566 if (!validate_arg (arg, REAL_TYPE)) 7567 return NULL_TREE; 7568 7569 /* If argument is already integer valued, and we don't need to worry 7570 about setting errno, there's no need to perform rounding. */ 7571 if (! flag_errno_math && integer_valued_real_p (arg)) 7572 return fold_build1_loc (loc, FIX_TRUNC_EXPR, 7573 TREE_TYPE (TREE_TYPE (fndecl)), arg); 7574 7575 if (optimize) 7576 { 7577 tree ftype = TREE_TYPE (arg); 7578 tree arg0 = strip_float_extensions (arg); 7579 tree newtype = TREE_TYPE (arg0); 7580 tree decl; 7581 7582 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype) 7583 && (decl = mathfn_built_in (newtype, fcode))) 7584 return build_call_expr_loc (loc, decl, 1, 7585 fold_convert_loc (loc, newtype, arg0)); 7586 } 7587 7588 /* Canonicalize iround (x) to lround (x) on ILP32 targets where 7589 sizeof (int) == sizeof (long). */ 7590 if (TYPE_PRECISION (integer_type_node) 7591 == TYPE_PRECISION (long_integer_type_node)) 7592 { 7593 tree newfn = NULL_TREE; 7594 switch (fcode) 7595 { 7596 CASE_FLT_FN (BUILT_IN_ICEIL): 7597 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL); 7598 break; 7599 7600 CASE_FLT_FN (BUILT_IN_IFLOOR): 7601 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR); 7602 break; 7603 7604 CASE_FLT_FN (BUILT_IN_IROUND): 7605 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND); 7606 break; 7607 7608 CASE_FLT_FN (BUILT_IN_IRINT): 7609 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT); 7610 break; 7611 7612 default: 7613 break; 7614 } 7615 7616 if (newfn) 7617 { 7618 tree newcall = build_call_expr_loc (loc, newfn, 1, arg); 7619 return fold_convert_loc (loc, 7620 TREE_TYPE (TREE_TYPE (fndecl)), newcall); 7621 } 7622 } 7623 7624 /* Canonicalize llround (x) to lround (x) on LP64 targets where 7625 sizeof (long long) == sizeof (long). */ 7626 if (TYPE_PRECISION (long_long_integer_type_node) 7627 == TYPE_PRECISION (long_integer_type_node)) 7628 { 7629 tree newfn = NULL_TREE; 7630 switch (fcode) 7631 { 7632 CASE_FLT_FN (BUILT_IN_LLCEIL): 7633 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL); 7634 break; 7635 7636 CASE_FLT_FN (BUILT_IN_LLFLOOR): 7637 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR); 7638 break; 7639 7640 CASE_FLT_FN (BUILT_IN_LLROUND): 7641 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND); 7642 break; 7643 7644 CASE_FLT_FN (BUILT_IN_LLRINT): 7645 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT); 7646 break; 7647 7648 default: 7649 break; 7650 } 7651 7652 if (newfn) 7653 { 7654 tree newcall = build_call_expr_loc (loc, newfn, 1, arg); 7655 return fold_convert_loc (loc, 7656 TREE_TYPE (TREE_TYPE (fndecl)), newcall); 7657 } 7658 } 7659 7660 return NULL_TREE; 7661} 7662 7663/* Fold call to builtin cabs, cabsf or cabsl with argument ARG. TYPE is the 7664 return type. Return NULL_TREE if no simplification can be made. */ 7665 7666static tree 7667fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl) 7668{ 7669 tree res; 7670 7671 if (!validate_arg (arg, COMPLEX_TYPE) 7672 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE) 7673 return NULL_TREE; 7674 7675 /* Calculate the result when the argument is a constant. */ 7676 if (TREE_CODE (arg) == COMPLEX_CST 7677 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg), 7678 type, mpfr_hypot))) 7679 return res; 7680 7681 if (TREE_CODE (arg) == COMPLEX_EXPR) 7682 { 7683 tree real = TREE_OPERAND (arg, 0); 7684 tree imag = TREE_OPERAND (arg, 1); 7685 7686 /* If either part is zero, cabs is fabs of the other. */ 7687 if (real_zerop (real)) 7688 return fold_build1_loc (loc, ABS_EXPR, type, imag); 7689 if (real_zerop (imag)) 7690 return fold_build1_loc (loc, ABS_EXPR, type, real); 7691 7692 /* cabs(x+xi) -> fabs(x)*sqrt(2). */ 7693 if (flag_unsafe_math_optimizations 7694 && operand_equal_p (real, imag, OEP_PURE_SAME)) 7695 { 7696 const REAL_VALUE_TYPE sqrt2_trunc 7697 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ()); 7698 STRIP_NOPS (real); 7699 return fold_build2_loc (loc, MULT_EXPR, type, 7700 fold_build1_loc (loc, ABS_EXPR, type, real), 7701 build_real (type, sqrt2_trunc)); 7702 } 7703 } 7704 7705 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */ 7706 if (TREE_CODE (arg) == NEGATE_EXPR 7707 || TREE_CODE (arg) == CONJ_EXPR) 7708 return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0)); 7709 7710 /* Don't do this when optimizing for size. */ 7711 if (flag_unsafe_math_optimizations 7712 && optimize && optimize_function_for_speed_p (cfun)) 7713 { 7714 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); 7715 7716 if (sqrtfn != NULL_TREE) 7717 { 7718 tree rpart, ipart, result; 7719 7720 arg = builtin_save_expr (arg); 7721 7722 rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg); 7723 ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg); 7724 7725 rpart = builtin_save_expr (rpart); 7726 ipart = builtin_save_expr (ipart); 7727 7728 result = fold_build2_loc (loc, PLUS_EXPR, type, 7729 fold_build2_loc (loc, MULT_EXPR, type, 7730 rpart, rpart), 7731 fold_build2_loc (loc, MULT_EXPR, type, 7732 ipart, ipart)); 7733 7734 return build_call_expr_loc (loc, sqrtfn, 1, result); 7735 } 7736 } 7737 7738 return NULL_TREE; 7739} 7740 7741/* Build a complex (inf +- 0i) for the result of cproj. TYPE is the 7742 complex tree type of the result. If NEG is true, the imaginary 7743 zero is negative. */ 7744 7745static tree 7746build_complex_cproj (tree type, bool neg) 7747{ 7748 REAL_VALUE_TYPE rinf, rzero = dconst0; 7749 7750 real_inf (&rinf); 7751 rzero.sign = neg; 7752 return build_complex (type, build_real (TREE_TYPE (type), rinf), 7753 build_real (TREE_TYPE (type), rzero)); 7754} 7755 7756/* Fold call to builtin cproj, cprojf or cprojl with argument ARG. TYPE is the 7757 return type. Return NULL_TREE if no simplification can be made. */ 7758 7759static tree 7760fold_builtin_cproj (location_t loc, tree arg, tree type) 7761{ 7762 if (!validate_arg (arg, COMPLEX_TYPE) 7763 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE) 7764 return NULL_TREE; 7765 7766 /* If there are no infinities, return arg. */ 7767 if (! HONOR_INFINITIES (type)) 7768 return non_lvalue_loc (loc, arg); 7769 7770 /* Calculate the result when the argument is a constant. */ 7771 if (TREE_CODE (arg) == COMPLEX_CST) 7772 { 7773 const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg)); 7774 const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg)); 7775 7776 if (real_isinf (real) || real_isinf (imag)) 7777 return build_complex_cproj (type, imag->sign); 7778 else 7779 return arg; 7780 } 7781 else if (TREE_CODE (arg) == COMPLEX_EXPR) 7782 { 7783 tree real = TREE_OPERAND (arg, 0); 7784 tree imag = TREE_OPERAND (arg, 1); 7785 7786 STRIP_NOPS (real); 7787 STRIP_NOPS (imag); 7788 7789 /* If the real part is inf and the imag part is known to be 7790 nonnegative, return (inf + 0i). Remember side-effects are 7791 possible in the imag part. */ 7792 if (TREE_CODE (real) == REAL_CST 7793 && real_isinf (TREE_REAL_CST_PTR (real)) 7794 && tree_expr_nonnegative_p (imag)) 7795 return omit_one_operand_loc (loc, type, 7796 build_complex_cproj (type, false), 7797 arg); 7798 7799 /* If the imag part is inf, return (inf+I*copysign(0,imag)). 7800 Remember side-effects are possible in the real part. */ 7801 if (TREE_CODE (imag) == REAL_CST 7802 && real_isinf (TREE_REAL_CST_PTR (imag))) 7803 return 7804 omit_one_operand_loc (loc, type, 7805 build_complex_cproj (type, TREE_REAL_CST_PTR 7806 (imag)->sign), arg); 7807 } 7808 7809 return NULL_TREE; 7810} 7811 7812/* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG. 7813 Return NULL_TREE if no simplification can be made. */ 7814 7815static tree 7816fold_builtin_sqrt (location_t loc, tree arg, tree type) 7817{ 7818 7819 enum built_in_function fcode; 7820 tree res; 7821 7822 if (!validate_arg (arg, REAL_TYPE)) 7823 return NULL_TREE; 7824 7825 /* Calculate the result when the argument is a constant. */ 7826 if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true))) 7827 return res; 7828 7829 /* Optimize sqrt(expN(x)) = expN(x*0.5). */ 7830 fcode = builtin_mathfn_code (arg); 7831 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode)) 7832 { 7833 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); 7834 arg = fold_build2_loc (loc, MULT_EXPR, type, 7835 CALL_EXPR_ARG (arg, 0), 7836 build_real (type, dconsthalf)); 7837 return build_call_expr_loc (loc, expfn, 1, arg); 7838 } 7839 7840 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */ 7841 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode)) 7842 { 7843 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7844 7845 if (powfn) 7846 { 7847 tree arg0 = CALL_EXPR_ARG (arg, 0); 7848 tree tree_root; 7849 /* The inner root was either sqrt or cbrt. */ 7850 /* This was a conditional expression but it triggered a bug 7851 in Sun C 5.5. */ 7852 REAL_VALUE_TYPE dconstroot; 7853 if (BUILTIN_SQRT_P (fcode)) 7854 dconstroot = dconsthalf; 7855 else 7856 dconstroot = dconst_third (); 7857 7858 /* Adjust for the outer root. */ 7859 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); 7860 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7861 tree_root = build_real (type, dconstroot); 7862 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root); 7863 } 7864 } 7865 7866 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */ 7867 if (flag_unsafe_math_optimizations 7868 && (fcode == BUILT_IN_POW 7869 || fcode == BUILT_IN_POWF 7870 || fcode == BUILT_IN_POWL)) 7871 { 7872 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); 7873 tree arg0 = CALL_EXPR_ARG (arg, 0); 7874 tree arg1 = CALL_EXPR_ARG (arg, 1); 7875 tree narg1; 7876 if (!tree_expr_nonnegative_p (arg0)) 7877 arg0 = build1 (ABS_EXPR, type, arg0); 7878 narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, 7879 build_real (type, dconsthalf)); 7880 return build_call_expr_loc (loc, powfn, 2, arg0, narg1); 7881 } 7882 7883 return NULL_TREE; 7884} 7885 7886/* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG. 7887 Return NULL_TREE if no simplification can be made. */ 7888 7889static tree 7890fold_builtin_cbrt (location_t loc, tree arg, tree type) 7891{ 7892 const enum built_in_function fcode = builtin_mathfn_code (arg); 7893 tree res; 7894 7895 if (!validate_arg (arg, REAL_TYPE)) 7896 return NULL_TREE; 7897 7898 /* Calculate the result when the argument is a constant. */ 7899 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0))) 7900 return res; 7901 7902 if (flag_unsafe_math_optimizations) 7903 { 7904 /* Optimize cbrt(expN(x)) -> expN(x/3). */ 7905 if (BUILTIN_EXPONENT_P (fcode)) 7906 { 7907 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); 7908 const REAL_VALUE_TYPE third_trunc = 7909 real_value_truncate (TYPE_MODE (type), dconst_third ()); 7910 arg = fold_build2_loc (loc, MULT_EXPR, type, 7911 CALL_EXPR_ARG (arg, 0), 7912 build_real (type, third_trunc)); 7913 return build_call_expr_loc (loc, expfn, 1, arg); 7914 } 7915 7916 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */ 7917 if (BUILTIN_SQRT_P (fcode)) 7918 { 7919 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7920 7921 if (powfn) 7922 { 7923 tree arg0 = CALL_EXPR_ARG (arg, 0); 7924 tree tree_root; 7925 REAL_VALUE_TYPE dconstroot = dconst_third (); 7926 7927 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); 7928 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7929 tree_root = build_real (type, dconstroot); 7930 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root); 7931 } 7932 } 7933 7934 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */ 7935 if (BUILTIN_CBRT_P (fcode)) 7936 { 7937 tree arg0 = CALL_EXPR_ARG (arg, 0); 7938 if (tree_expr_nonnegative_p (arg0)) 7939 { 7940 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7941 7942 if (powfn) 7943 { 7944 tree tree_root; 7945 REAL_VALUE_TYPE dconstroot; 7946 7947 real_arithmetic (&dconstroot, MULT_EXPR, 7948 dconst_third_ptr (), dconst_third_ptr ()); 7949 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7950 tree_root = build_real (type, dconstroot); 7951 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root); 7952 } 7953 } 7954 } 7955 7956 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */ 7957 if (fcode == BUILT_IN_POW 7958 || fcode == BUILT_IN_POWF 7959 || fcode == BUILT_IN_POWL) 7960 { 7961 tree arg00 = CALL_EXPR_ARG (arg, 0); 7962 tree arg01 = CALL_EXPR_ARG (arg, 1); 7963 if (tree_expr_nonnegative_p (arg00)) 7964 { 7965 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); 7966 const REAL_VALUE_TYPE dconstroot 7967 = real_value_truncate (TYPE_MODE (type), dconst_third ()); 7968 tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01, 7969 build_real (type, dconstroot)); 7970 return build_call_expr_loc (loc, powfn, 2, arg00, narg01); 7971 } 7972 } 7973 } 7974 return NULL_TREE; 7975} 7976 7977/* Fold function call to builtin cos, cosf, or cosl with argument ARG. 7978 TYPE is the type of the return value. Return NULL_TREE if no 7979 simplification can be made. */ 7980 7981static tree 7982fold_builtin_cos (location_t loc, 7983 tree arg, tree type, tree fndecl) 7984{ 7985 tree res, narg; 7986 7987 if (!validate_arg (arg, REAL_TYPE)) 7988 return NULL_TREE; 7989 7990 /* Calculate the result when the argument is a constant. */ 7991 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0))) 7992 return res; 7993 7994 /* Optimize cos(-x) into cos (x). */ 7995 if ((narg = fold_strip_sign_ops (arg))) 7996 return build_call_expr_loc (loc, fndecl, 1, narg); 7997 7998 return NULL_TREE; 7999} 8000 8001/* Fold function call to builtin cosh, coshf, or coshl with argument ARG. 8002 Return NULL_TREE if no simplification can be made. */ 8003 8004static tree 8005fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl) 8006{ 8007 if (validate_arg (arg, REAL_TYPE)) 8008 { 8009 tree res, narg; 8010 8011 /* Calculate the result when the argument is a constant. */ 8012 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0))) 8013 return res; 8014 8015 /* Optimize cosh(-x) into cosh (x). */ 8016 if ((narg = fold_strip_sign_ops (arg))) 8017 return build_call_expr_loc (loc, fndecl, 1, narg); 8018 } 8019 8020 return NULL_TREE; 8021} 8022 8023/* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with 8024 argument ARG. TYPE is the type of the return value. Return 8025 NULL_TREE if no simplification can be made. */ 8026 8027static tree 8028fold_builtin_ccos (location_t loc, tree arg, tree type, tree fndecl, 8029 bool hyper) 8030{ 8031 if (validate_arg (arg, COMPLEX_TYPE) 8032 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE) 8033 { 8034 tree tmp; 8035 8036 /* Calculate the result when the argument is a constant. */ 8037 if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos)))) 8038 return tmp; 8039 8040 /* Optimize fn(-x) into fn(x). */ 8041 if ((tmp = fold_strip_sign_ops (arg))) 8042 return build_call_expr_loc (loc, fndecl, 1, tmp); 8043 } 8044 8045 return NULL_TREE; 8046} 8047 8048/* Fold function call to builtin tan, tanf, or tanl with argument ARG. 8049 Return NULL_TREE if no simplification can be made. */ 8050 8051static tree 8052fold_builtin_tan (tree arg, tree type) 8053{ 8054 enum built_in_function fcode; 8055 tree res; 8056 8057 if (!validate_arg (arg, REAL_TYPE)) 8058 return NULL_TREE; 8059 8060 /* Calculate the result when the argument is a constant. */ 8061 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0))) 8062 return res; 8063 8064 /* Optimize tan(atan(x)) = x. */ 8065 fcode = builtin_mathfn_code (arg); 8066 if (flag_unsafe_math_optimizations 8067 && (fcode == BUILT_IN_ATAN 8068 || fcode == BUILT_IN_ATANF 8069 || fcode == BUILT_IN_ATANL)) 8070 return CALL_EXPR_ARG (arg, 0); 8071 8072 return NULL_TREE; 8073} 8074 8075/* Fold function call to builtin sincos, sincosf, or sincosl. Return 8076 NULL_TREE if no simplification can be made. */ 8077 8078static tree 8079fold_builtin_sincos (location_t loc, 8080 tree arg0, tree arg1, tree arg2) 8081{ 8082 tree type; 8083 tree res, fn, call; 8084 8085 if (!validate_arg (arg0, REAL_TYPE) 8086 || !validate_arg (arg1, POINTER_TYPE) 8087 || !validate_arg (arg2, POINTER_TYPE)) 8088 return NULL_TREE; 8089 8090 type = TREE_TYPE (arg0); 8091 8092 /* Calculate the result when the argument is a constant. */ 8093 if ((res = do_mpfr_sincos (arg0, arg1, arg2))) 8094 return res; 8095 8096 /* Canonicalize sincos to cexpi. */ 8097 if (!targetm.libc_has_function (function_c99_math_complex)) 8098 return NULL_TREE; 8099 fn = mathfn_built_in (type, BUILT_IN_CEXPI); 8100 if (!fn) 8101 return NULL_TREE; 8102 8103 call = build_call_expr_loc (loc, fn, 1, arg0); 8104 call = builtin_save_expr (call); 8105 8106 return build2 (COMPOUND_EXPR, void_type_node, 8107 build2 (MODIFY_EXPR, void_type_node, 8108 build_fold_indirect_ref_loc (loc, arg1), 8109 build1 (IMAGPART_EXPR, type, call)), 8110 build2 (MODIFY_EXPR, void_type_node, 8111 build_fold_indirect_ref_loc (loc, arg2), 8112 build1 (REALPART_EXPR, type, call))); 8113} 8114 8115/* Fold function call to builtin cexp, cexpf, or cexpl. Return 8116 NULL_TREE if no simplification can be made. */ 8117 8118static tree 8119fold_builtin_cexp (location_t loc, tree arg0, tree type) 8120{ 8121 tree rtype; 8122 tree realp, imagp, ifn; 8123 tree res; 8124 8125 if (!validate_arg (arg0, COMPLEX_TYPE) 8126 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE) 8127 return NULL_TREE; 8128 8129 /* Calculate the result when the argument is a constant. */ 8130 if ((res = do_mpc_arg1 (arg0, type, mpc_exp))) 8131 return res; 8132 8133 rtype = TREE_TYPE (TREE_TYPE (arg0)); 8134 8135 /* In case we can figure out the real part of arg0 and it is constant zero 8136 fold to cexpi. */ 8137 if (!targetm.libc_has_function (function_c99_math_complex)) 8138 return NULL_TREE; 8139 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI); 8140 if (!ifn) 8141 return NULL_TREE; 8142 8143 if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0)) 8144 && real_zerop (realp)) 8145 { 8146 tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0); 8147 return build_call_expr_loc (loc, ifn, 1, narg); 8148 } 8149 8150 /* In case we can easily decompose real and imaginary parts split cexp 8151 to exp (r) * cexpi (i). */ 8152 if (flag_unsafe_math_optimizations 8153 && realp) 8154 { 8155 tree rfn, rcall, icall; 8156 8157 rfn = mathfn_built_in (rtype, BUILT_IN_EXP); 8158 if (!rfn) 8159 return NULL_TREE; 8160 8161 imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0); 8162 if (!imagp) 8163 return NULL_TREE; 8164 8165 icall = build_call_expr_loc (loc, ifn, 1, imagp); 8166 icall = builtin_save_expr (icall); 8167 rcall = build_call_expr_loc (loc, rfn, 1, realp); 8168 rcall = builtin_save_expr (rcall); 8169 return fold_build2_loc (loc, COMPLEX_EXPR, type, 8170 fold_build2_loc (loc, MULT_EXPR, rtype, 8171 rcall, 8172 fold_build1_loc (loc, REALPART_EXPR, 8173 rtype, icall)), 8174 fold_build2_loc (loc, MULT_EXPR, rtype, 8175 rcall, 8176 fold_build1_loc (loc, IMAGPART_EXPR, 8177 rtype, icall))); 8178 } 8179 8180 return NULL_TREE; 8181} 8182 8183/* Fold function call to builtin trunc, truncf or truncl with argument ARG. 8184 Return NULL_TREE if no simplification can be made. */ 8185 8186static tree 8187fold_builtin_trunc (location_t loc, tree fndecl, tree arg) 8188{ 8189 if (!validate_arg (arg, REAL_TYPE)) 8190 return NULL_TREE; 8191 8192 /* Optimize trunc of constant value. */ 8193 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 8194 { 8195 REAL_VALUE_TYPE r, x; 8196 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8197 8198 x = TREE_REAL_CST (arg); 8199 real_trunc (&r, TYPE_MODE (type), &x); 8200 return build_real (type, r); 8201 } 8202 8203 return fold_trunc_transparent_mathfn (loc, fndecl, arg); 8204} 8205 8206/* Fold function call to builtin floor, floorf or floorl with argument ARG. 8207 Return NULL_TREE if no simplification can be made. */ 8208 8209static tree 8210fold_builtin_floor (location_t loc, tree fndecl, tree arg) 8211{ 8212 if (!validate_arg (arg, REAL_TYPE)) 8213 return NULL_TREE; 8214 8215 /* Optimize floor of constant value. */ 8216 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 8217 { 8218 REAL_VALUE_TYPE x; 8219 8220 x = TREE_REAL_CST (arg); 8221 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 8222 { 8223 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8224 REAL_VALUE_TYPE r; 8225 8226 real_floor (&r, TYPE_MODE (type), &x); 8227 return build_real (type, r); 8228 } 8229 } 8230 8231 /* Fold floor (x) where x is nonnegative to trunc (x). */ 8232 if (tree_expr_nonnegative_p (arg)) 8233 { 8234 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC); 8235 if (truncfn) 8236 return build_call_expr_loc (loc, truncfn, 1, arg); 8237 } 8238 8239 return fold_trunc_transparent_mathfn (loc, fndecl, arg); 8240} 8241 8242/* Fold function call to builtin ceil, ceilf or ceill with argument ARG. 8243 Return NULL_TREE if no simplification can be made. */ 8244 8245static tree 8246fold_builtin_ceil (location_t loc, tree fndecl, tree arg) 8247{ 8248 if (!validate_arg (arg, REAL_TYPE)) 8249 return NULL_TREE; 8250 8251 /* Optimize ceil of constant value. */ 8252 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 8253 { 8254 REAL_VALUE_TYPE x; 8255 8256 x = TREE_REAL_CST (arg); 8257 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 8258 { 8259 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8260 REAL_VALUE_TYPE r; 8261 8262 real_ceil (&r, TYPE_MODE (type), &x); 8263 return build_real (type, r); 8264 } 8265 } 8266 8267 return fold_trunc_transparent_mathfn (loc, fndecl, arg); 8268} 8269 8270/* Fold function call to builtin round, roundf or roundl with argument ARG. 8271 Return NULL_TREE if no simplification can be made. */ 8272 8273static tree 8274fold_builtin_round (location_t loc, tree fndecl, tree arg) 8275{ 8276 if (!validate_arg (arg, REAL_TYPE)) 8277 return NULL_TREE; 8278 8279 /* Optimize round of constant value. */ 8280 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 8281 { 8282 REAL_VALUE_TYPE x; 8283 8284 x = TREE_REAL_CST (arg); 8285 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 8286 { 8287 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8288 REAL_VALUE_TYPE r; 8289 8290 real_round (&r, TYPE_MODE (type), &x); 8291 return build_real (type, r); 8292 } 8293 } 8294 8295 return fold_trunc_transparent_mathfn (loc, fndecl, arg); 8296} 8297 8298/* Fold function call to builtin lround, lroundf or lroundl (or the 8299 corresponding long long versions) and other rounding functions. ARG 8300 is the argument to the call. Return NULL_TREE if no simplification 8301 can be made. */ 8302 8303static tree 8304fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg) 8305{ 8306 if (!validate_arg (arg, REAL_TYPE)) 8307 return NULL_TREE; 8308 8309 /* Optimize lround of constant value. */ 8310 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 8311 { 8312 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg); 8313 8314 if (real_isfinite (&x)) 8315 { 8316 tree itype = TREE_TYPE (TREE_TYPE (fndecl)); 8317 tree ftype = TREE_TYPE (arg); 8318 REAL_VALUE_TYPE r; 8319 bool fail = false; 8320 8321 switch (DECL_FUNCTION_CODE (fndecl)) 8322 { 8323 CASE_FLT_FN (BUILT_IN_IFLOOR): 8324 CASE_FLT_FN (BUILT_IN_LFLOOR): 8325 CASE_FLT_FN (BUILT_IN_LLFLOOR): 8326 real_floor (&r, TYPE_MODE (ftype), &x); 8327 break; 8328 8329 CASE_FLT_FN (BUILT_IN_ICEIL): 8330 CASE_FLT_FN (BUILT_IN_LCEIL): 8331 CASE_FLT_FN (BUILT_IN_LLCEIL): 8332 real_ceil (&r, TYPE_MODE (ftype), &x); 8333 break; 8334 8335 CASE_FLT_FN (BUILT_IN_IROUND): 8336 CASE_FLT_FN (BUILT_IN_LROUND): 8337 CASE_FLT_FN (BUILT_IN_LLROUND): 8338 real_round (&r, TYPE_MODE (ftype), &x); 8339 break; 8340 8341 default: 8342 gcc_unreachable (); 8343 } 8344 8345 wide_int val = real_to_integer (&r, &fail, TYPE_PRECISION (itype)); 8346 if (!fail) 8347 return wide_int_to_tree (itype, val); 8348 } 8349 } 8350 8351 switch (DECL_FUNCTION_CODE (fndecl)) 8352 { 8353 CASE_FLT_FN (BUILT_IN_LFLOOR): 8354 CASE_FLT_FN (BUILT_IN_LLFLOOR): 8355 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */ 8356 if (tree_expr_nonnegative_p (arg)) 8357 return fold_build1_loc (loc, FIX_TRUNC_EXPR, 8358 TREE_TYPE (TREE_TYPE (fndecl)), arg); 8359 break; 8360 default:; 8361 } 8362 8363 return fold_fixed_mathfn (loc, fndecl, arg); 8364} 8365 8366/* Fold function call to builtin ffs, clz, ctz, popcount and parity 8367 and their long and long long variants (i.e. ffsl and ffsll). ARG is 8368 the argument to the call. Return NULL_TREE if no simplification can 8369 be made. */ 8370 8371static tree 8372fold_builtin_bitop (tree fndecl, tree arg) 8373{ 8374 if (!validate_arg (arg, INTEGER_TYPE)) 8375 return NULL_TREE; 8376 8377 /* Optimize for constant argument. */ 8378 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg)) 8379 { 8380 tree type = TREE_TYPE (arg); 8381 int result; 8382 8383 switch (DECL_FUNCTION_CODE (fndecl)) 8384 { 8385 CASE_INT_FN (BUILT_IN_FFS): 8386 result = wi::ffs (arg); 8387 break; 8388 8389 CASE_INT_FN (BUILT_IN_CLZ): 8390 if (wi::ne_p (arg, 0)) 8391 result = wi::clz (arg); 8392 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result)) 8393 result = TYPE_PRECISION (type); 8394 break; 8395 8396 CASE_INT_FN (BUILT_IN_CTZ): 8397 if (wi::ne_p (arg, 0)) 8398 result = wi::ctz (arg); 8399 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result)) 8400 result = TYPE_PRECISION (type); 8401 break; 8402 8403 CASE_INT_FN (BUILT_IN_CLRSB): 8404 result = wi::clrsb (arg); 8405 break; 8406 8407 CASE_INT_FN (BUILT_IN_POPCOUNT): 8408 result = wi::popcount (arg); 8409 break; 8410 8411 CASE_INT_FN (BUILT_IN_PARITY): 8412 result = wi::parity (arg); 8413 break; 8414 8415 default: 8416 gcc_unreachable (); 8417 } 8418 8419 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result); 8420 } 8421 8422 return NULL_TREE; 8423} 8424 8425/* Fold function call to builtin_bswap and the short, long and long long 8426 variants. Return NULL_TREE if no simplification can be made. */ 8427static tree 8428fold_builtin_bswap (tree fndecl, tree arg) 8429{ 8430 if (! validate_arg (arg, INTEGER_TYPE)) 8431 return NULL_TREE; 8432 8433 /* Optimize constant value. */ 8434 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg)) 8435 { 8436 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8437 8438 switch (DECL_FUNCTION_CODE (fndecl)) 8439 { 8440 case BUILT_IN_BSWAP16: 8441 case BUILT_IN_BSWAP32: 8442 case BUILT_IN_BSWAP64: 8443 { 8444 signop sgn = TYPE_SIGN (type); 8445 tree result = 8446 wide_int_to_tree (type, 8447 wide_int::from (arg, TYPE_PRECISION (type), 8448 sgn).bswap ()); 8449 return result; 8450 } 8451 default: 8452 gcc_unreachable (); 8453 } 8454 } 8455 8456 return NULL_TREE; 8457} 8458 8459/* Fold a builtin function call to hypot, hypotf, or hypotl. Return 8460 NULL_TREE if no simplification can be made. */ 8461 8462static tree 8463fold_builtin_hypot (location_t loc, tree fndecl, 8464 tree arg0, tree arg1, tree type) 8465{ 8466 tree res, narg0, narg1; 8467 8468 if (!validate_arg (arg0, REAL_TYPE) 8469 || !validate_arg (arg1, REAL_TYPE)) 8470 return NULL_TREE; 8471 8472 /* Calculate the result when the argument is a constant. */ 8473 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot))) 8474 return res; 8475 8476 /* If either argument to hypot has a negate or abs, strip that off. 8477 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */ 8478 narg0 = fold_strip_sign_ops (arg0); 8479 narg1 = fold_strip_sign_ops (arg1); 8480 if (narg0 || narg1) 8481 { 8482 return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0, 8483 narg1 ? narg1 : arg1); 8484 } 8485 8486 /* If either argument is zero, hypot is fabs of the other. */ 8487 if (real_zerop (arg0)) 8488 return fold_build1_loc (loc, ABS_EXPR, type, arg1); 8489 else if (real_zerop (arg1)) 8490 return fold_build1_loc (loc, ABS_EXPR, type, arg0); 8491 8492 /* hypot(x,x) -> fabs(x)*sqrt(2). */ 8493 if (flag_unsafe_math_optimizations 8494 && operand_equal_p (arg0, arg1, OEP_PURE_SAME)) 8495 { 8496 const REAL_VALUE_TYPE sqrt2_trunc 8497 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ()); 8498 return fold_build2_loc (loc, MULT_EXPR, type, 8499 fold_build1_loc (loc, ABS_EXPR, type, arg0), 8500 build_real (type, sqrt2_trunc)); 8501 } 8502 8503 return NULL_TREE; 8504} 8505 8506 8507/* Fold a builtin function call to pow, powf, or powl. Return 8508 NULL_TREE if no simplification can be made. */ 8509static tree 8510fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type) 8511{ 8512 tree res; 8513 8514 if (!validate_arg (arg0, REAL_TYPE) 8515 || !validate_arg (arg1, REAL_TYPE)) 8516 return NULL_TREE; 8517 8518 /* Calculate the result when the argument is a constant. */ 8519 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow))) 8520 return res; 8521 8522 /* Optimize pow(1.0,y) = 1.0. */ 8523 if (real_onep (arg0)) 8524 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1); 8525 8526 if (TREE_CODE (arg1) == REAL_CST 8527 && !TREE_OVERFLOW (arg1)) 8528 { 8529 REAL_VALUE_TYPE cint; 8530 REAL_VALUE_TYPE c; 8531 HOST_WIDE_INT n; 8532 8533 c = TREE_REAL_CST (arg1); 8534 8535 /* Optimize pow(x,0.0) = 1.0. */ 8536 if (REAL_VALUES_EQUAL (c, dconst0)) 8537 return omit_one_operand_loc (loc, type, build_real (type, dconst1), 8538 arg0); 8539 8540 /* Optimize pow(x,1.0) = x. */ 8541 if (REAL_VALUES_EQUAL (c, dconst1)) 8542 return arg0; 8543 8544 /* Optimize pow(x,-1.0) = 1.0/x. */ 8545 if (REAL_VALUES_EQUAL (c, dconstm1)) 8546 return fold_build2_loc (loc, RDIV_EXPR, type, 8547 build_real (type, dconst1), arg0); 8548 8549 /* Optimize pow(x,0.5) = sqrt(x). */ 8550 if (flag_unsafe_math_optimizations 8551 && REAL_VALUES_EQUAL (c, dconsthalf)) 8552 { 8553 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); 8554 8555 if (sqrtfn != NULL_TREE) 8556 return build_call_expr_loc (loc, sqrtfn, 1, arg0); 8557 } 8558 8559 /* Optimize pow(x,1.0/3.0) = cbrt(x). */ 8560 if (flag_unsafe_math_optimizations) 8561 { 8562 const REAL_VALUE_TYPE dconstroot 8563 = real_value_truncate (TYPE_MODE (type), dconst_third ()); 8564 8565 if (REAL_VALUES_EQUAL (c, dconstroot)) 8566 { 8567 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT); 8568 if (cbrtfn != NULL_TREE) 8569 return build_call_expr_loc (loc, cbrtfn, 1, arg0); 8570 } 8571 } 8572 8573 /* Check for an integer exponent. */ 8574 n = real_to_integer (&c); 8575 real_from_integer (&cint, VOIDmode, n, SIGNED); 8576 if (real_identical (&c, &cint)) 8577 { 8578 /* Attempt to evaluate pow at compile-time, unless this should 8579 raise an exception. */ 8580 if (TREE_CODE (arg0) == REAL_CST 8581 && !TREE_OVERFLOW (arg0) 8582 && (n > 0 8583 || (!flag_trapping_math && !flag_errno_math) 8584 || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0))) 8585 { 8586 REAL_VALUE_TYPE x; 8587 bool inexact; 8588 8589 x = TREE_REAL_CST (arg0); 8590 inexact = real_powi (&x, TYPE_MODE (type), &x, n); 8591 if (flag_unsafe_math_optimizations || !inexact) 8592 return build_real (type, x); 8593 } 8594 8595 /* Strip sign ops from even integer powers. */ 8596 if ((n & 1) == 0 && flag_unsafe_math_optimizations) 8597 { 8598 tree narg0 = fold_strip_sign_ops (arg0); 8599 if (narg0) 8600 return build_call_expr_loc (loc, fndecl, 2, narg0, arg1); 8601 } 8602 } 8603 } 8604 8605 if (flag_unsafe_math_optimizations) 8606 { 8607 const enum built_in_function fcode = builtin_mathfn_code (arg0); 8608 8609 /* Optimize pow(expN(x),y) = expN(x*y). */ 8610 if (BUILTIN_EXPONENT_P (fcode)) 8611 { 8612 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0); 8613 tree arg = CALL_EXPR_ARG (arg0, 0); 8614 arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1); 8615 return build_call_expr_loc (loc, expfn, 1, arg); 8616 } 8617 8618 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */ 8619 if (BUILTIN_SQRT_P (fcode)) 8620 { 8621 tree narg0 = CALL_EXPR_ARG (arg0, 0); 8622 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, 8623 build_real (type, dconsthalf)); 8624 return build_call_expr_loc (loc, fndecl, 2, narg0, narg1); 8625 } 8626 8627 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */ 8628 if (BUILTIN_CBRT_P (fcode)) 8629 { 8630 tree arg = CALL_EXPR_ARG (arg0, 0); 8631 if (tree_expr_nonnegative_p (arg)) 8632 { 8633 const REAL_VALUE_TYPE dconstroot 8634 = real_value_truncate (TYPE_MODE (type), dconst_third ()); 8635 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, 8636 build_real (type, dconstroot)); 8637 return build_call_expr_loc (loc, fndecl, 2, arg, narg1); 8638 } 8639 } 8640 8641 /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative. */ 8642 if (fcode == BUILT_IN_POW 8643 || fcode == BUILT_IN_POWF 8644 || fcode == BUILT_IN_POWL) 8645 { 8646 tree arg00 = CALL_EXPR_ARG (arg0, 0); 8647 if (tree_expr_nonnegative_p (arg00)) 8648 { 8649 tree arg01 = CALL_EXPR_ARG (arg0, 1); 8650 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1); 8651 return build_call_expr_loc (loc, fndecl, 2, arg00, narg1); 8652 } 8653 } 8654 } 8655 8656 return NULL_TREE; 8657} 8658 8659/* Fold a builtin function call to powi, powif, or powil with argument ARG. 8660 Return NULL_TREE if no simplification can be made. */ 8661static tree 8662fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED, 8663 tree arg0, tree arg1, tree type) 8664{ 8665 if (!validate_arg (arg0, REAL_TYPE) 8666 || !validate_arg (arg1, INTEGER_TYPE)) 8667 return NULL_TREE; 8668 8669 /* Optimize pow(1.0,y) = 1.0. */ 8670 if (real_onep (arg0)) 8671 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1); 8672 8673 if (tree_fits_shwi_p (arg1)) 8674 { 8675 HOST_WIDE_INT c = tree_to_shwi (arg1); 8676 8677 /* Evaluate powi at compile-time. */ 8678 if (TREE_CODE (arg0) == REAL_CST 8679 && !TREE_OVERFLOW (arg0)) 8680 { 8681 REAL_VALUE_TYPE x; 8682 x = TREE_REAL_CST (arg0); 8683 real_powi (&x, TYPE_MODE (type), &x, c); 8684 return build_real (type, x); 8685 } 8686 8687 /* Optimize pow(x,0) = 1.0. */ 8688 if (c == 0) 8689 return omit_one_operand_loc (loc, type, build_real (type, dconst1), 8690 arg0); 8691 8692 /* Optimize pow(x,1) = x. */ 8693 if (c == 1) 8694 return arg0; 8695 8696 /* Optimize pow(x,-1) = 1.0/x. */ 8697 if (c == -1) 8698 return fold_build2_loc (loc, RDIV_EXPR, type, 8699 build_real (type, dconst1), arg0); 8700 } 8701 8702 return NULL_TREE; 8703} 8704 8705/* A subroutine of fold_builtin to fold the various exponent 8706 functions. Return NULL_TREE if no simplification can be made. 8707 FUNC is the corresponding MPFR exponent function. */ 8708 8709static tree 8710fold_builtin_exponent (location_t loc, tree fndecl, tree arg, 8711 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t)) 8712{ 8713 if (validate_arg (arg, REAL_TYPE)) 8714 { 8715 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8716 tree res; 8717 8718 /* Calculate the result when the argument is a constant. */ 8719 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0))) 8720 return res; 8721 8722 /* Optimize expN(logN(x)) = x. */ 8723 if (flag_unsafe_math_optimizations) 8724 { 8725 const enum built_in_function fcode = builtin_mathfn_code (arg); 8726 8727 if ((func == mpfr_exp 8728 && (fcode == BUILT_IN_LOG 8729 || fcode == BUILT_IN_LOGF 8730 || fcode == BUILT_IN_LOGL)) 8731 || (func == mpfr_exp2 8732 && (fcode == BUILT_IN_LOG2 8733 || fcode == BUILT_IN_LOG2F 8734 || fcode == BUILT_IN_LOG2L)) 8735 || (func == mpfr_exp10 8736 && (fcode == BUILT_IN_LOG10 8737 || fcode == BUILT_IN_LOG10F 8738 || fcode == BUILT_IN_LOG10L))) 8739 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0)); 8740 } 8741 } 8742 8743 return NULL_TREE; 8744} 8745 8746/* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the 8747 arguments to the call, and TYPE is its return type. 8748 Return NULL_TREE if no simplification can be made. */ 8749 8750static tree 8751fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type) 8752{ 8753 if (!validate_arg (arg1, POINTER_TYPE) 8754 || !validate_arg (arg2, INTEGER_TYPE) 8755 || !validate_arg (len, INTEGER_TYPE)) 8756 return NULL_TREE; 8757 else 8758 { 8759 const char *p1; 8760 8761 if (TREE_CODE (arg2) != INTEGER_CST 8762 || !tree_fits_uhwi_p (len)) 8763 return NULL_TREE; 8764 8765 p1 = c_getstr (arg1); 8766 if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0) 8767 { 8768 char c; 8769 const char *r; 8770 tree tem; 8771 8772 if (target_char_cast (arg2, &c)) 8773 return NULL_TREE; 8774 8775 r = (const char *) memchr (p1, c, tree_to_uhwi (len)); 8776 8777 if (r == NULL) 8778 return build_int_cst (TREE_TYPE (arg1), 0); 8779 8780 tem = fold_build_pointer_plus_hwi_loc (loc, arg1, r - p1); 8781 return fold_convert_loc (loc, type, tem); 8782 } 8783 return NULL_TREE; 8784 } 8785} 8786 8787/* Fold function call to builtin memcmp with arguments ARG1 and ARG2. 8788 Return NULL_TREE if no simplification can be made. */ 8789 8790static tree 8791fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len) 8792{ 8793 const char *p1, *p2; 8794 8795 if (!validate_arg (arg1, POINTER_TYPE) 8796 || !validate_arg (arg2, POINTER_TYPE) 8797 || !validate_arg (len, INTEGER_TYPE)) 8798 return NULL_TREE; 8799 8800 /* If the LEN parameter is zero, return zero. */ 8801 if (integer_zerop (len)) 8802 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node, 8803 arg1, arg2); 8804 8805 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8806 if (operand_equal_p (arg1, arg2, 0)) 8807 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len); 8808 8809 p1 = c_getstr (arg1); 8810 p2 = c_getstr (arg2); 8811 8812 /* If all arguments are constant, and the value of len is not greater 8813 than the lengths of arg1 and arg2, evaluate at compile-time. */ 8814 if (tree_fits_uhwi_p (len) && p1 && p2 8815 && compare_tree_int (len, strlen (p1) + 1) <= 0 8816 && compare_tree_int (len, strlen (p2) + 1) <= 0) 8817 { 8818 const int r = memcmp (p1, p2, tree_to_uhwi (len)); 8819 8820 if (r > 0) 8821 return integer_one_node; 8822 else if (r < 0) 8823 return integer_minus_one_node; 8824 else 8825 return integer_zero_node; 8826 } 8827 8828 /* If len parameter is one, return an expression corresponding to 8829 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ 8830 if (tree_fits_uhwi_p (len) && tree_to_uhwi (len) == 1) 8831 { 8832 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8833 tree cst_uchar_ptr_node 8834 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8835 8836 tree ind1 8837 = fold_convert_loc (loc, integer_type_node, 8838 build1 (INDIRECT_REF, cst_uchar_node, 8839 fold_convert_loc (loc, 8840 cst_uchar_ptr_node, 8841 arg1))); 8842 tree ind2 8843 = fold_convert_loc (loc, integer_type_node, 8844 build1 (INDIRECT_REF, cst_uchar_node, 8845 fold_convert_loc (loc, 8846 cst_uchar_ptr_node, 8847 arg2))); 8848 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2); 8849 } 8850 8851 return NULL_TREE; 8852} 8853 8854/* Fold function call to builtin strcmp with arguments ARG1 and ARG2. 8855 Return NULL_TREE if no simplification can be made. */ 8856 8857static tree 8858fold_builtin_strcmp (location_t loc, tree arg1, tree arg2) 8859{ 8860 const char *p1, *p2; 8861 8862 if (!validate_arg (arg1, POINTER_TYPE) 8863 || !validate_arg (arg2, POINTER_TYPE)) 8864 return NULL_TREE; 8865 8866 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8867 if (operand_equal_p (arg1, arg2, 0)) 8868 return integer_zero_node; 8869 8870 p1 = c_getstr (arg1); 8871 p2 = c_getstr (arg2); 8872 8873 if (p1 && p2) 8874 { 8875 const int i = strcmp (p1, p2); 8876 if (i < 0) 8877 return integer_minus_one_node; 8878 else if (i > 0) 8879 return integer_one_node; 8880 else 8881 return integer_zero_node; 8882 } 8883 8884 /* If the second arg is "", return *(const unsigned char*)arg1. */ 8885 if (p2 && *p2 == '\0') 8886 { 8887 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8888 tree cst_uchar_ptr_node 8889 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8890 8891 return fold_convert_loc (loc, integer_type_node, 8892 build1 (INDIRECT_REF, cst_uchar_node, 8893 fold_convert_loc (loc, 8894 cst_uchar_ptr_node, 8895 arg1))); 8896 } 8897 8898 /* If the first arg is "", return -*(const unsigned char*)arg2. */ 8899 if (p1 && *p1 == '\0') 8900 { 8901 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8902 tree cst_uchar_ptr_node 8903 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8904 8905 tree temp 8906 = fold_convert_loc (loc, integer_type_node, 8907 build1 (INDIRECT_REF, cst_uchar_node, 8908 fold_convert_loc (loc, 8909 cst_uchar_ptr_node, 8910 arg2))); 8911 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp); 8912 } 8913 8914 return NULL_TREE; 8915} 8916 8917/* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN. 8918 Return NULL_TREE if no simplification can be made. */ 8919 8920static tree 8921fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len) 8922{ 8923 const char *p1, *p2; 8924 8925 if (!validate_arg (arg1, POINTER_TYPE) 8926 || !validate_arg (arg2, POINTER_TYPE) 8927 || !validate_arg (len, INTEGER_TYPE)) 8928 return NULL_TREE; 8929 8930 /* If the LEN parameter is zero, return zero. */ 8931 if (integer_zerop (len)) 8932 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node, 8933 arg1, arg2); 8934 8935 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8936 if (operand_equal_p (arg1, arg2, 0)) 8937 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len); 8938 8939 p1 = c_getstr (arg1); 8940 p2 = c_getstr (arg2); 8941 8942 if (tree_fits_uhwi_p (len) && p1 && p2) 8943 { 8944 const int i = strncmp (p1, p2, tree_to_uhwi (len)); 8945 if (i > 0) 8946 return integer_one_node; 8947 else if (i < 0) 8948 return integer_minus_one_node; 8949 else 8950 return integer_zero_node; 8951 } 8952 8953 /* If the second arg is "", and the length is greater than zero, 8954 return *(const unsigned char*)arg1. */ 8955 if (p2 && *p2 == '\0' 8956 && TREE_CODE (len) == INTEGER_CST 8957 && tree_int_cst_sgn (len) == 1) 8958 { 8959 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8960 tree cst_uchar_ptr_node 8961 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8962 8963 return fold_convert_loc (loc, integer_type_node, 8964 build1 (INDIRECT_REF, cst_uchar_node, 8965 fold_convert_loc (loc, 8966 cst_uchar_ptr_node, 8967 arg1))); 8968 } 8969 8970 /* If the first arg is "", and the length is greater than zero, 8971 return -*(const unsigned char*)arg2. */ 8972 if (p1 && *p1 == '\0' 8973 && TREE_CODE (len) == INTEGER_CST 8974 && tree_int_cst_sgn (len) == 1) 8975 { 8976 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8977 tree cst_uchar_ptr_node 8978 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8979 8980 tree temp = fold_convert_loc (loc, integer_type_node, 8981 build1 (INDIRECT_REF, cst_uchar_node, 8982 fold_convert_loc (loc, 8983 cst_uchar_ptr_node, 8984 arg2))); 8985 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp); 8986 } 8987 8988 /* If len parameter is one, return an expression corresponding to 8989 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ 8990 if (tree_fits_uhwi_p (len) && tree_to_uhwi (len) == 1) 8991 { 8992 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8993 tree cst_uchar_ptr_node 8994 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8995 8996 tree ind1 = fold_convert_loc (loc, integer_type_node, 8997 build1 (INDIRECT_REF, cst_uchar_node, 8998 fold_convert_loc (loc, 8999 cst_uchar_ptr_node, 9000 arg1))); 9001 tree ind2 = fold_convert_loc (loc, integer_type_node, 9002 build1 (INDIRECT_REF, cst_uchar_node, 9003 fold_convert_loc (loc, 9004 cst_uchar_ptr_node, 9005 arg2))); 9006 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2); 9007 } 9008 9009 return NULL_TREE; 9010} 9011 9012/* Fold function call to builtin signbit, signbitf or signbitl with argument 9013 ARG. Return NULL_TREE if no simplification can be made. */ 9014 9015static tree 9016fold_builtin_signbit (location_t loc, tree arg, tree type) 9017{ 9018 if (!validate_arg (arg, REAL_TYPE)) 9019 return NULL_TREE; 9020 9021 /* If ARG is a compile-time constant, determine the result. */ 9022 if (TREE_CODE (arg) == REAL_CST 9023 && !TREE_OVERFLOW (arg)) 9024 { 9025 REAL_VALUE_TYPE c; 9026 9027 c = TREE_REAL_CST (arg); 9028 return (REAL_VALUE_NEGATIVE (c) 9029 ? build_one_cst (type) 9030 : build_zero_cst (type)); 9031 } 9032 9033 /* If ARG is non-negative, the result is always zero. */ 9034 if (tree_expr_nonnegative_p (arg)) 9035 return omit_one_operand_loc (loc, type, integer_zero_node, arg); 9036 9037 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */ 9038 if (!HONOR_SIGNED_ZEROS (arg)) 9039 return fold_convert (type, 9040 fold_build2_loc (loc, LT_EXPR, boolean_type_node, arg, 9041 build_real (TREE_TYPE (arg), dconst0))); 9042 9043 return NULL_TREE; 9044} 9045 9046/* Fold function call to builtin copysign, copysignf or copysignl with 9047 arguments ARG1 and ARG2. Return NULL_TREE if no simplification can 9048 be made. */ 9049 9050static tree 9051fold_builtin_copysign (location_t loc, tree fndecl, 9052 tree arg1, tree arg2, tree type) 9053{ 9054 tree tem; 9055 9056 if (!validate_arg (arg1, REAL_TYPE) 9057 || !validate_arg (arg2, REAL_TYPE)) 9058 return NULL_TREE; 9059 9060 /* copysign(X,X) is X. */ 9061 if (operand_equal_p (arg1, arg2, 0)) 9062 return fold_convert_loc (loc, type, arg1); 9063 9064 /* If ARG1 and ARG2 are compile-time constants, determine the result. */ 9065 if (TREE_CODE (arg1) == REAL_CST 9066 && TREE_CODE (arg2) == REAL_CST 9067 && !TREE_OVERFLOW (arg1) 9068 && !TREE_OVERFLOW (arg2)) 9069 { 9070 REAL_VALUE_TYPE c1, c2; 9071 9072 c1 = TREE_REAL_CST (arg1); 9073 c2 = TREE_REAL_CST (arg2); 9074 /* c1.sign := c2.sign. */ 9075 real_copysign (&c1, &c2); 9076 return build_real (type, c1); 9077 } 9078 9079 /* copysign(X, Y) is fabs(X) when Y is always non-negative. 9080 Remember to evaluate Y for side-effects. */ 9081 if (tree_expr_nonnegative_p (arg2)) 9082 return omit_one_operand_loc (loc, type, 9083 fold_build1_loc (loc, ABS_EXPR, type, arg1), 9084 arg2); 9085 9086 /* Strip sign changing operations for the first argument. */ 9087 tem = fold_strip_sign_ops (arg1); 9088 if (tem) 9089 return build_call_expr_loc (loc, fndecl, 2, tem, arg2); 9090 9091 return NULL_TREE; 9092} 9093 9094/* Fold a call to builtin isascii with argument ARG. */ 9095 9096static tree 9097fold_builtin_isascii (location_t loc, tree arg) 9098{ 9099 if (!validate_arg (arg, INTEGER_TYPE)) 9100 return NULL_TREE; 9101 else 9102 { 9103 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */ 9104 arg = fold_build2 (BIT_AND_EXPR, integer_type_node, arg, 9105 build_int_cst (integer_type_node, 9106 ~ (unsigned HOST_WIDE_INT) 0x7f)); 9107 return fold_build2_loc (loc, EQ_EXPR, integer_type_node, 9108 arg, integer_zero_node); 9109 } 9110} 9111 9112/* Fold a call to builtin toascii with argument ARG. */ 9113 9114static tree 9115fold_builtin_toascii (location_t loc, tree arg) 9116{ 9117 if (!validate_arg (arg, INTEGER_TYPE)) 9118 return NULL_TREE; 9119 9120 /* Transform toascii(c) -> (c & 0x7f). */ 9121 return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg, 9122 build_int_cst (integer_type_node, 0x7f)); 9123} 9124 9125/* Fold a call to builtin isdigit with argument ARG. */ 9126 9127static tree 9128fold_builtin_isdigit (location_t loc, tree arg) 9129{ 9130 if (!validate_arg (arg, INTEGER_TYPE)) 9131 return NULL_TREE; 9132 else 9133 { 9134 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */ 9135 /* According to the C standard, isdigit is unaffected by locale. 9136 However, it definitely is affected by the target character set. */ 9137 unsigned HOST_WIDE_INT target_digit0 9138 = lang_hooks.to_target_charset ('0'); 9139 9140 if (target_digit0 == 0) 9141 return NULL_TREE; 9142 9143 arg = fold_convert_loc (loc, unsigned_type_node, arg); 9144 arg = fold_build2 (MINUS_EXPR, unsigned_type_node, arg, 9145 build_int_cst (unsigned_type_node, target_digit0)); 9146 return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg, 9147 build_int_cst (unsigned_type_node, 9)); 9148 } 9149} 9150 9151/* Fold a call to fabs, fabsf or fabsl with argument ARG. */ 9152 9153static tree 9154fold_builtin_fabs (location_t loc, tree arg, tree type) 9155{ 9156 if (!validate_arg (arg, REAL_TYPE)) 9157 return NULL_TREE; 9158 9159 arg = fold_convert_loc (loc, type, arg); 9160 if (TREE_CODE (arg) == REAL_CST) 9161 return fold_abs_const (arg, type); 9162 return fold_build1_loc (loc, ABS_EXPR, type, arg); 9163} 9164 9165/* Fold a call to abs, labs, llabs or imaxabs with argument ARG. */ 9166 9167static tree 9168fold_builtin_abs (location_t loc, tree arg, tree type) 9169{ 9170 if (!validate_arg (arg, INTEGER_TYPE)) 9171 return NULL_TREE; 9172 9173 arg = fold_convert_loc (loc, type, arg); 9174 if (TREE_CODE (arg) == INTEGER_CST) 9175 return fold_abs_const (arg, type); 9176 return fold_build1_loc (loc, ABS_EXPR, type, arg); 9177} 9178 9179/* Fold a fma operation with arguments ARG[012]. */ 9180 9181tree 9182fold_fma (location_t loc ATTRIBUTE_UNUSED, 9183 tree type, tree arg0, tree arg1, tree arg2) 9184{ 9185 if (TREE_CODE (arg0) == REAL_CST 9186 && TREE_CODE (arg1) == REAL_CST 9187 && TREE_CODE (arg2) == REAL_CST) 9188 return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma); 9189 9190 return NULL_TREE; 9191} 9192 9193/* Fold a call to fma, fmaf, or fmal with arguments ARG[012]. */ 9194 9195static tree 9196fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type) 9197{ 9198 if (validate_arg (arg0, REAL_TYPE) 9199 && validate_arg (arg1, REAL_TYPE) 9200 && validate_arg (arg2, REAL_TYPE)) 9201 { 9202 tree tem = fold_fma (loc, type, arg0, arg1, arg2); 9203 if (tem) 9204 return tem; 9205 9206 /* ??? Only expand to FMA_EXPR if it's directly supported. */ 9207 if (optab_handler (fma_optab, TYPE_MODE (type)) != CODE_FOR_nothing) 9208 return fold_build3_loc (loc, FMA_EXPR, type, arg0, arg1, arg2); 9209 } 9210 return NULL_TREE; 9211} 9212 9213/* Fold a call to builtin fmin or fmax. */ 9214 9215static tree 9216fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1, 9217 tree type, bool max) 9218{ 9219 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE)) 9220 { 9221 /* Calculate the result when the argument is a constant. */ 9222 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min)); 9223 9224 if (res) 9225 return res; 9226 9227 /* If either argument is NaN, return the other one. Avoid the 9228 transformation if we get (and honor) a signalling NaN. Using 9229 omit_one_operand() ensures we create a non-lvalue. */ 9230 if (TREE_CODE (arg0) == REAL_CST 9231 && real_isnan (&TREE_REAL_CST (arg0)) 9232 && (! HONOR_SNANS (arg0) 9233 || ! TREE_REAL_CST (arg0).signalling)) 9234 return omit_one_operand_loc (loc, type, arg1, arg0); 9235 if (TREE_CODE (arg1) == REAL_CST 9236 && real_isnan (&TREE_REAL_CST (arg1)) 9237 && (! HONOR_SNANS (arg1) 9238 || ! TREE_REAL_CST (arg1).signalling)) 9239 return omit_one_operand_loc (loc, type, arg0, arg1); 9240 9241 /* Transform fmin/fmax(x,x) -> x. */ 9242 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME)) 9243 return omit_one_operand_loc (loc, type, arg0, arg1); 9244 9245 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these 9246 functions to return the numeric arg if the other one is NaN. 9247 These tree codes don't honor that, so only transform if 9248 -ffinite-math-only is set. C99 doesn't require -0.0 to be 9249 handled, so we don't have to worry about it either. */ 9250 if (flag_finite_math_only) 9251 return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type, 9252 fold_convert_loc (loc, type, arg0), 9253 fold_convert_loc (loc, type, arg1)); 9254 } 9255 return NULL_TREE; 9256} 9257 9258/* Fold a call to builtin carg(a+bi) -> atan2(b,a). */ 9259 9260static tree 9261fold_builtin_carg (location_t loc, tree arg, tree type) 9262{ 9263 if (validate_arg (arg, COMPLEX_TYPE) 9264 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE) 9265 { 9266 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2); 9267 9268 if (atan2_fn) 9269 { 9270 tree new_arg = builtin_save_expr (arg); 9271 tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg); 9272 tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg); 9273 return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg); 9274 } 9275 } 9276 9277 return NULL_TREE; 9278} 9279 9280/* Fold a call to builtin logb/ilogb. */ 9281 9282static tree 9283fold_builtin_logb (location_t loc, tree arg, tree rettype) 9284{ 9285 if (! validate_arg (arg, REAL_TYPE)) 9286 return NULL_TREE; 9287 9288 STRIP_NOPS (arg); 9289 9290 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg)) 9291 { 9292 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg); 9293 9294 switch (value->cl) 9295 { 9296 case rvc_nan: 9297 case rvc_inf: 9298 /* If arg is Inf or NaN and we're logb, return it. */ 9299 if (TREE_CODE (rettype) == REAL_TYPE) 9300 { 9301 /* For logb(-Inf) we have to return +Inf. */ 9302 if (real_isinf (value) && real_isneg (value)) 9303 { 9304 REAL_VALUE_TYPE tem; 9305 real_inf (&tem); 9306 return build_real (rettype, tem); 9307 } 9308 return fold_convert_loc (loc, rettype, arg); 9309 } 9310 /* Fall through... */ 9311 case rvc_zero: 9312 /* Zero may set errno and/or raise an exception for logb, also 9313 for ilogb we don't know FP_ILOGB0. */ 9314 return NULL_TREE; 9315 case rvc_normal: 9316 /* For normal numbers, proceed iff radix == 2. In GCC, 9317 normalized significands are in the range [0.5, 1.0). We 9318 want the exponent as if they were [1.0, 2.0) so get the 9319 exponent and subtract 1. */ 9320 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2) 9321 return fold_convert_loc (loc, rettype, 9322 build_int_cst (integer_type_node, 9323 REAL_EXP (value)-1)); 9324 break; 9325 } 9326 } 9327 9328 return NULL_TREE; 9329} 9330 9331/* Fold a call to builtin significand, if radix == 2. */ 9332 9333static tree 9334fold_builtin_significand (location_t loc, tree arg, tree rettype) 9335{ 9336 if (! validate_arg (arg, REAL_TYPE)) 9337 return NULL_TREE; 9338 9339 STRIP_NOPS (arg); 9340 9341 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg)) 9342 { 9343 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg); 9344 9345 switch (value->cl) 9346 { 9347 case rvc_zero: 9348 case rvc_nan: 9349 case rvc_inf: 9350 /* If arg is +-0, +-Inf or +-NaN, then return it. */ 9351 return fold_convert_loc (loc, rettype, arg); 9352 case rvc_normal: 9353 /* For normal numbers, proceed iff radix == 2. */ 9354 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2) 9355 { 9356 REAL_VALUE_TYPE result = *value; 9357 /* In GCC, normalized significands are in the range [0.5, 9358 1.0). We want them to be [1.0, 2.0) so set the 9359 exponent to 1. */ 9360 SET_REAL_EXP (&result, 1); 9361 return build_real (rettype, result); 9362 } 9363 break; 9364 } 9365 } 9366 9367 return NULL_TREE; 9368} 9369 9370/* Fold a call to builtin frexp, we can assume the base is 2. */ 9371 9372static tree 9373fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype) 9374{ 9375 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE)) 9376 return NULL_TREE; 9377 9378 STRIP_NOPS (arg0); 9379 9380 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0))) 9381 return NULL_TREE; 9382 9383 arg1 = build_fold_indirect_ref_loc (loc, arg1); 9384 9385 /* Proceed if a valid pointer type was passed in. */ 9386 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node) 9387 { 9388 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0); 9389 tree frac, exp; 9390 9391 switch (value->cl) 9392 { 9393 case rvc_zero: 9394 /* For +-0, return (*exp = 0, +-0). */ 9395 exp = integer_zero_node; 9396 frac = arg0; 9397 break; 9398 case rvc_nan: 9399 case rvc_inf: 9400 /* For +-NaN or +-Inf, *exp is unspecified, return arg0. */ 9401 return omit_one_operand_loc (loc, rettype, arg0, arg1); 9402 case rvc_normal: 9403 { 9404 /* Since the frexp function always expects base 2, and in 9405 GCC normalized significands are already in the range 9406 [0.5, 1.0), we have exactly what frexp wants. */ 9407 REAL_VALUE_TYPE frac_rvt = *value; 9408 SET_REAL_EXP (&frac_rvt, 0); 9409 frac = build_real (rettype, frac_rvt); 9410 exp = build_int_cst (integer_type_node, REAL_EXP (value)); 9411 } 9412 break; 9413 default: 9414 gcc_unreachable (); 9415 } 9416 9417 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */ 9418 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp); 9419 TREE_SIDE_EFFECTS (arg1) = 1; 9420 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac); 9421 } 9422 9423 return NULL_TREE; 9424} 9425 9426/* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true 9427 then we can assume the base is two. If it's false, then we have to 9428 check the mode of the TYPE parameter in certain cases. */ 9429 9430static tree 9431fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1, 9432 tree type, bool ldexp) 9433{ 9434 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE)) 9435 { 9436 STRIP_NOPS (arg0); 9437 STRIP_NOPS (arg1); 9438 9439 /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */ 9440 if (real_zerop (arg0) || integer_zerop (arg1) 9441 || (TREE_CODE (arg0) == REAL_CST 9442 && !real_isfinite (&TREE_REAL_CST (arg0)))) 9443 return omit_one_operand_loc (loc, type, arg0, arg1); 9444 9445 /* If both arguments are constant, then try to evaluate it. */ 9446 if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2) 9447 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0) 9448 && tree_fits_shwi_p (arg1)) 9449 { 9450 /* Bound the maximum adjustment to twice the range of the 9451 mode's valid exponents. Use abs to ensure the range is 9452 positive as a sanity check. */ 9453 const long max_exp_adj = 2 * 9454 labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax 9455 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin); 9456 9457 /* Get the user-requested adjustment. */ 9458 const HOST_WIDE_INT req_exp_adj = tree_to_shwi (arg1); 9459 9460 /* The requested adjustment must be inside this range. This 9461 is a preliminary cap to avoid things like overflow, we 9462 may still fail to compute the result for other reasons. */ 9463 if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj) 9464 { 9465 REAL_VALUE_TYPE initial_result; 9466 9467 real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj); 9468 9469 /* Ensure we didn't overflow. */ 9470 if (! real_isinf (&initial_result)) 9471 { 9472 const REAL_VALUE_TYPE trunc_result 9473 = real_value_truncate (TYPE_MODE (type), initial_result); 9474 9475 /* Only proceed if the target mode can hold the 9476 resulting value. */ 9477 if (REAL_VALUES_EQUAL (initial_result, trunc_result)) 9478 return build_real (type, trunc_result); 9479 } 9480 } 9481 } 9482 } 9483 9484 return NULL_TREE; 9485} 9486 9487/* Fold a call to builtin modf. */ 9488 9489static tree 9490fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype) 9491{ 9492 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE)) 9493 return NULL_TREE; 9494 9495 STRIP_NOPS (arg0); 9496 9497 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0))) 9498 return NULL_TREE; 9499 9500 arg1 = build_fold_indirect_ref_loc (loc, arg1); 9501 9502 /* Proceed if a valid pointer type was passed in. */ 9503 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype)) 9504 { 9505 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0); 9506 REAL_VALUE_TYPE trunc, frac; 9507 9508 switch (value->cl) 9509 { 9510 case rvc_nan: 9511 case rvc_zero: 9512 /* For +-NaN or +-0, return (*arg1 = arg0, arg0). */ 9513 trunc = frac = *value; 9514 break; 9515 case rvc_inf: 9516 /* For +-Inf, return (*arg1 = arg0, +-0). */ 9517 frac = dconst0; 9518 frac.sign = value->sign; 9519 trunc = *value; 9520 break; 9521 case rvc_normal: 9522 /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */ 9523 real_trunc (&trunc, VOIDmode, value); 9524 real_arithmetic (&frac, MINUS_EXPR, value, &trunc); 9525 /* If the original number was negative and already 9526 integral, then the fractional part is -0.0. */ 9527 if (value->sign && frac.cl == rvc_zero) 9528 frac.sign = value->sign; 9529 break; 9530 } 9531 9532 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */ 9533 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, 9534 build_real (rettype, trunc)); 9535 TREE_SIDE_EFFECTS (arg1) = 1; 9536 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, 9537 build_real (rettype, frac)); 9538 } 9539 9540 return NULL_TREE; 9541} 9542 9543/* Given a location LOC, an interclass builtin function decl FNDECL 9544 and its single argument ARG, return an folded expression computing 9545 the same, or NULL_TREE if we either couldn't or didn't want to fold 9546 (the latter happen if there's an RTL instruction available). */ 9547 9548static tree 9549fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg) 9550{ 9551 machine_mode mode; 9552 9553 if (!validate_arg (arg, REAL_TYPE)) 9554 return NULL_TREE; 9555 9556 if (interclass_mathfn_icode (arg, fndecl) != CODE_FOR_nothing) 9557 return NULL_TREE; 9558 9559 mode = TYPE_MODE (TREE_TYPE (arg)); 9560 9561 bool is_ibm_extended = MODE_COMPOSITE_P (mode); 9562 9563 /* If there is no optab, try generic code. */ 9564 switch (DECL_FUNCTION_CODE (fndecl)) 9565 { 9566 tree result; 9567 9568 CASE_FLT_FN (BUILT_IN_ISINF): 9569 { 9570 /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */ 9571 tree const isgr_fn = builtin_decl_explicit (BUILT_IN_ISGREATER); 9572 tree type = TREE_TYPE (arg); 9573 REAL_VALUE_TYPE r; 9574 char buf[128]; 9575 9576 if (is_ibm_extended) 9577 { 9578 /* NaN and Inf are encoded in the high-order double value 9579 only. The low-order value is not significant. */ 9580 type = double_type_node; 9581 mode = DFmode; 9582 arg = fold_build1_loc (loc, NOP_EXPR, type, arg); 9583 } 9584 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); 9585 real_from_string (&r, buf); 9586 result = build_call_expr (isgr_fn, 2, 9587 fold_build1_loc (loc, ABS_EXPR, type, arg), 9588 build_real (type, r)); 9589 return result; 9590 } 9591 CASE_FLT_FN (BUILT_IN_FINITE): 9592 case BUILT_IN_ISFINITE: 9593 { 9594 /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */ 9595 tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL); 9596 tree type = TREE_TYPE (arg); 9597 REAL_VALUE_TYPE r; 9598 char buf[128]; 9599 9600 if (is_ibm_extended) 9601 { 9602 /* NaN and Inf are encoded in the high-order double value 9603 only. The low-order value is not significant. */ 9604 type = double_type_node; 9605 mode = DFmode; 9606 arg = fold_build1_loc (loc, NOP_EXPR, type, arg); 9607 } 9608 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); 9609 real_from_string (&r, buf); 9610 result = build_call_expr (isle_fn, 2, 9611 fold_build1_loc (loc, ABS_EXPR, type, arg), 9612 build_real (type, r)); 9613 /*result = fold_build2_loc (loc, UNGT_EXPR, 9614 TREE_TYPE (TREE_TYPE (fndecl)), 9615 fold_build1_loc (loc, ABS_EXPR, type, arg), 9616 build_real (type, r)); 9617 result = fold_build1_loc (loc, TRUTH_NOT_EXPR, 9618 TREE_TYPE (TREE_TYPE (fndecl)), 9619 result);*/ 9620 return result; 9621 } 9622 case BUILT_IN_ISNORMAL: 9623 { 9624 /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) & 9625 islessequal(fabs(x),DBL_MAX). */ 9626 tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL); 9627 tree type = TREE_TYPE (arg); 9628 tree orig_arg, max_exp, min_exp; 9629 machine_mode orig_mode = mode; 9630 REAL_VALUE_TYPE rmax, rmin; 9631 char buf[128]; 9632 9633 orig_arg = arg = builtin_save_expr (arg); 9634 if (is_ibm_extended) 9635 { 9636 /* Use double to test the normal range of IBM extended 9637 precision. Emin for IBM extended precision is 9638 different to emin for IEEE double, being 53 higher 9639 since the low double exponent is at least 53 lower 9640 than the high double exponent. */ 9641 type = double_type_node; 9642 mode = DFmode; 9643 arg = fold_build1_loc (loc, NOP_EXPR, type, arg); 9644 } 9645 arg = fold_build1_loc (loc, ABS_EXPR, type, arg); 9646 9647 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); 9648 real_from_string (&rmax, buf); 9649 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (orig_mode)->emin - 1); 9650 real_from_string (&rmin, buf); 9651 max_exp = build_real (type, rmax); 9652 min_exp = build_real (type, rmin); 9653 9654 max_exp = build_call_expr (isle_fn, 2, arg, max_exp); 9655 if (is_ibm_extended) 9656 { 9657 /* Testing the high end of the range is done just using 9658 the high double, using the same test as isfinite(). 9659 For the subnormal end of the range we first test the 9660 high double, then if its magnitude is equal to the 9661 limit of 0x1p-969, we test whether the low double is 9662 non-zero and opposite sign to the high double. */ 9663 tree const islt_fn = builtin_decl_explicit (BUILT_IN_ISLESS); 9664 tree const isgt_fn = builtin_decl_explicit (BUILT_IN_ISGREATER); 9665 tree gt_min = build_call_expr (isgt_fn, 2, arg, min_exp); 9666 tree eq_min = fold_build2 (EQ_EXPR, integer_type_node, 9667 arg, min_exp); 9668 tree as_complex = build1 (VIEW_CONVERT_EXPR, 9669 complex_double_type_node, orig_arg); 9670 tree hi_dbl = build1 (REALPART_EXPR, type, as_complex); 9671 tree lo_dbl = build1 (IMAGPART_EXPR, type, as_complex); 9672 tree zero = build_real (type, dconst0); 9673 tree hilt = build_call_expr (islt_fn, 2, hi_dbl, zero); 9674 tree lolt = build_call_expr (islt_fn, 2, lo_dbl, zero); 9675 tree logt = build_call_expr (isgt_fn, 2, lo_dbl, zero); 9676 tree ok_lo = fold_build1 (TRUTH_NOT_EXPR, integer_type_node, 9677 fold_build3 (COND_EXPR, 9678 integer_type_node, 9679 hilt, logt, lolt)); 9680 eq_min = fold_build2 (TRUTH_ANDIF_EXPR, integer_type_node, 9681 eq_min, ok_lo); 9682 min_exp = fold_build2 (TRUTH_ORIF_EXPR, integer_type_node, 9683 gt_min, eq_min); 9684 } 9685 else 9686 { 9687 tree const isge_fn 9688 = builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL); 9689 min_exp = build_call_expr (isge_fn, 2, arg, min_exp); 9690 } 9691 result = fold_build2 (BIT_AND_EXPR, integer_type_node, 9692 max_exp, min_exp); 9693 return result; 9694 } 9695 default: 9696 break; 9697 } 9698 9699 return NULL_TREE; 9700} 9701 9702/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite. 9703 ARG is the argument for the call. */ 9704 9705static tree 9706fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index) 9707{ 9708 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 9709 REAL_VALUE_TYPE r; 9710 9711 if (!validate_arg (arg, REAL_TYPE)) 9712 return NULL_TREE; 9713 9714 switch (builtin_index) 9715 { 9716 case BUILT_IN_ISINF: 9717 if (!HONOR_INFINITIES (arg)) 9718 return omit_one_operand_loc (loc, type, integer_zero_node, arg); 9719 9720 if (TREE_CODE (arg) == REAL_CST) 9721 { 9722 r = TREE_REAL_CST (arg); 9723 if (real_isinf (&r)) 9724 return real_compare (GT_EXPR, &r, &dconst0) 9725 ? integer_one_node : integer_minus_one_node; 9726 else 9727 return integer_zero_node; 9728 } 9729 9730 return NULL_TREE; 9731 9732 case BUILT_IN_ISINF_SIGN: 9733 { 9734 /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */ 9735 /* In a boolean context, GCC will fold the inner COND_EXPR to 9736 1. So e.g. "if (isinf_sign(x))" would be folded to just 9737 "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */ 9738 tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0); 9739 tree isinf_fn = builtin_decl_explicit (BUILT_IN_ISINF); 9740 tree tmp = NULL_TREE; 9741 9742 arg = builtin_save_expr (arg); 9743 9744 if (signbit_fn && isinf_fn) 9745 { 9746 tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg); 9747 tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg); 9748 9749 signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node, 9750 signbit_call, integer_zero_node); 9751 isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node, 9752 isinf_call, integer_zero_node); 9753 9754 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call, 9755 integer_minus_one_node, integer_one_node); 9756 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, 9757 isinf_call, tmp, 9758 integer_zero_node); 9759 } 9760 9761 return tmp; 9762 } 9763 9764 case BUILT_IN_ISFINITE: 9765 if (!HONOR_NANS (arg) 9766 && !HONOR_INFINITIES (arg)) 9767 return omit_one_operand_loc (loc, type, integer_one_node, arg); 9768 9769 if (TREE_CODE (arg) == REAL_CST) 9770 { 9771 r = TREE_REAL_CST (arg); 9772 return real_isfinite (&r) ? integer_one_node : integer_zero_node; 9773 } 9774 9775 return NULL_TREE; 9776 9777 case BUILT_IN_ISNAN: 9778 if (!HONOR_NANS (arg)) 9779 return omit_one_operand_loc (loc, type, integer_zero_node, arg); 9780 9781 if (TREE_CODE (arg) == REAL_CST) 9782 { 9783 r = TREE_REAL_CST (arg); 9784 return real_isnan (&r) ? integer_one_node : integer_zero_node; 9785 } 9786 9787 { 9788 bool is_ibm_extended = MODE_COMPOSITE_P (TYPE_MODE (TREE_TYPE (arg))); 9789 if (is_ibm_extended) 9790 { 9791 /* NaN and Inf are encoded in the high-order double value 9792 only. The low-order value is not significant. */ 9793 arg = fold_build1_loc (loc, NOP_EXPR, double_type_node, arg); 9794 } 9795 } 9796 arg = builtin_save_expr (arg); 9797 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg); 9798 9799 default: 9800 gcc_unreachable (); 9801 } 9802} 9803 9804/* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...). 9805 This builtin will generate code to return the appropriate floating 9806 point classification depending on the value of the floating point 9807 number passed in. The possible return values must be supplied as 9808 int arguments to the call in the following order: FP_NAN, FP_INFINITE, 9809 FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly 9810 one floating point argument which is "type generic". */ 9811 9812static tree 9813fold_builtin_fpclassify (location_t loc, tree *args, int nargs) 9814{ 9815 tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero, 9816 arg, type, res, tmp; 9817 machine_mode mode; 9818 REAL_VALUE_TYPE r; 9819 char buf[128]; 9820 9821 /* Verify the required arguments in the original call. */ 9822 if (nargs != 6 9823 || !validate_arg (args[0], INTEGER_TYPE) 9824 || !validate_arg (args[1], INTEGER_TYPE) 9825 || !validate_arg (args[2], INTEGER_TYPE) 9826 || !validate_arg (args[3], INTEGER_TYPE) 9827 || !validate_arg (args[4], INTEGER_TYPE) 9828 || !validate_arg (args[5], REAL_TYPE)) 9829 return NULL_TREE; 9830 9831 fp_nan = args[0]; 9832 fp_infinite = args[1]; 9833 fp_normal = args[2]; 9834 fp_subnormal = args[3]; 9835 fp_zero = args[4]; 9836 arg = args[5]; 9837 type = TREE_TYPE (arg); 9838 mode = TYPE_MODE (type); 9839 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg)); 9840 9841 /* fpclassify(x) -> 9842 isnan(x) ? FP_NAN : 9843 (fabs(x) == Inf ? FP_INFINITE : 9844 (fabs(x) >= DBL_MIN ? FP_NORMAL : 9845 (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */ 9846 9847 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg, 9848 build_real (type, dconst0)); 9849 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, 9850 tmp, fp_zero, fp_subnormal); 9851 9852 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1); 9853 real_from_string (&r, buf); 9854 tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node, 9855 arg, build_real (type, r)); 9856 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res); 9857 9858 if (HONOR_INFINITIES (mode)) 9859 { 9860 real_inf (&r); 9861 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg, 9862 build_real (type, r)); 9863 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, 9864 fp_infinite, res); 9865 } 9866 9867 if (HONOR_NANS (mode)) 9868 { 9869 tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg); 9870 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan); 9871 } 9872 9873 return res; 9874} 9875 9876/* Fold a call to an unordered comparison function such as 9877 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function 9878 being called and ARG0 and ARG1 are the arguments for the call. 9879 UNORDERED_CODE and ORDERED_CODE are comparison codes that give 9880 the opposite of the desired result. UNORDERED_CODE is used 9881 for modes that can hold NaNs and ORDERED_CODE is used for 9882 the rest. */ 9883 9884static tree 9885fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1, 9886 enum tree_code unordered_code, 9887 enum tree_code ordered_code) 9888{ 9889 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 9890 enum tree_code code; 9891 tree type0, type1; 9892 enum tree_code code0, code1; 9893 tree cmp_type = NULL_TREE; 9894 9895 type0 = TREE_TYPE (arg0); 9896 type1 = TREE_TYPE (arg1); 9897 9898 code0 = TREE_CODE (type0); 9899 code1 = TREE_CODE (type1); 9900 9901 if (code0 == REAL_TYPE && code1 == REAL_TYPE) 9902 /* Choose the wider of two real types. */ 9903 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1) 9904 ? type0 : type1; 9905 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE) 9906 cmp_type = type0; 9907 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE) 9908 cmp_type = type1; 9909 9910 arg0 = fold_convert_loc (loc, cmp_type, arg0); 9911 arg1 = fold_convert_loc (loc, cmp_type, arg1); 9912 9913 if (unordered_code == UNORDERED_EXPR) 9914 { 9915 if (!HONOR_NANS (arg0)) 9916 return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1); 9917 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1); 9918 } 9919 9920 code = HONOR_NANS (arg0) ? unordered_code : ordered_code; 9921 return fold_build1_loc (loc, TRUTH_NOT_EXPR, type, 9922 fold_build2_loc (loc, code, type, arg0, arg1)); 9923} 9924 9925/* Fold __builtin_{,s,u}{add,sub,mul}{,l,ll}_overflow, either into normal 9926 arithmetics if it can never overflow, or into internal functions that 9927 return both result of arithmetics and overflowed boolean flag in 9928 a complex integer result, or some other check for overflow. */ 9929 9930static tree 9931fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode, 9932 tree arg0, tree arg1, tree arg2) 9933{ 9934 enum internal_fn ifn = IFN_LAST; 9935 tree type = TREE_TYPE (TREE_TYPE (arg2)); 9936 tree mem_arg2 = build_fold_indirect_ref_loc (loc, arg2); 9937 switch (fcode) 9938 { 9939 case BUILT_IN_ADD_OVERFLOW: 9940 case BUILT_IN_SADD_OVERFLOW: 9941 case BUILT_IN_SADDL_OVERFLOW: 9942 case BUILT_IN_SADDLL_OVERFLOW: 9943 case BUILT_IN_UADD_OVERFLOW: 9944 case BUILT_IN_UADDL_OVERFLOW: 9945 case BUILT_IN_UADDLL_OVERFLOW: 9946 ifn = IFN_ADD_OVERFLOW; 9947 break; 9948 case BUILT_IN_SUB_OVERFLOW: 9949 case BUILT_IN_SSUB_OVERFLOW: 9950 case BUILT_IN_SSUBL_OVERFLOW: 9951 case BUILT_IN_SSUBLL_OVERFLOW: 9952 case BUILT_IN_USUB_OVERFLOW: 9953 case BUILT_IN_USUBL_OVERFLOW: 9954 case BUILT_IN_USUBLL_OVERFLOW: 9955 ifn = IFN_SUB_OVERFLOW; 9956 break; 9957 case BUILT_IN_MUL_OVERFLOW: 9958 case BUILT_IN_SMUL_OVERFLOW: 9959 case BUILT_IN_SMULL_OVERFLOW: 9960 case BUILT_IN_SMULLL_OVERFLOW: 9961 case BUILT_IN_UMUL_OVERFLOW: 9962 case BUILT_IN_UMULL_OVERFLOW: 9963 case BUILT_IN_UMULLL_OVERFLOW: 9964 ifn = IFN_MUL_OVERFLOW; 9965 break; 9966 default: 9967 gcc_unreachable (); 9968 } 9969 tree ctype = build_complex_type (type); 9970 tree call = build_call_expr_internal_loc (loc, ifn, ctype, 9971 2, arg0, arg1); 9972 tree tgt = save_expr (call); 9973 tree intres = build1_loc (loc, REALPART_EXPR, type, tgt); 9974 tree ovfres = build1_loc (loc, IMAGPART_EXPR, type, tgt); 9975 ovfres = fold_convert_loc (loc, boolean_type_node, ovfres); 9976 tree store 9977 = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, mem_arg2, intres); 9978 return build2_loc (loc, COMPOUND_EXPR, boolean_type_node, store, ovfres); 9979} 9980 9981/* Fold a call to built-in function FNDECL with 0 arguments. 9982 This function returns NULL_TREE if no simplification was possible. */ 9983 9984static tree 9985fold_builtin_0 (location_t loc, tree fndecl) 9986{ 9987 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 9988 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 9989 switch (fcode) 9990 { 9991 CASE_FLT_FN (BUILT_IN_INF): 9992 case BUILT_IN_INFD32: 9993 case BUILT_IN_INFD64: 9994 case BUILT_IN_INFD128: 9995 return fold_builtin_inf (loc, type, true); 9996 9997 CASE_FLT_FN (BUILT_IN_HUGE_VAL): 9998 return fold_builtin_inf (loc, type, false); 9999 10000 case BUILT_IN_CLASSIFY_TYPE: 10001 return fold_builtin_classify_type (NULL_TREE); 10002 10003 default: 10004 break; 10005 } 10006 return NULL_TREE; 10007} 10008 10009/* Fold a call to built-in function FNDECL with 1 argument, ARG0. 10010 This function returns NULL_TREE if no simplification was possible. */ 10011 10012static tree 10013fold_builtin_1 (location_t loc, tree fndecl, tree arg0) 10014{ 10015 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 10016 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 10017 switch (fcode) 10018 { 10019 case BUILT_IN_CONSTANT_P: 10020 { 10021 tree val = fold_builtin_constant_p (arg0); 10022 10023 /* Gimplification will pull the CALL_EXPR for the builtin out of 10024 an if condition. When not optimizing, we'll not CSE it back. 10025 To avoid link error types of regressions, return false now. */ 10026 if (!val && !optimize) 10027 val = integer_zero_node; 10028 10029 return val; 10030 } 10031 10032 case BUILT_IN_CLASSIFY_TYPE: 10033 return fold_builtin_classify_type (arg0); 10034 10035 case BUILT_IN_STRLEN: 10036 return fold_builtin_strlen (loc, type, arg0); 10037 10038 CASE_FLT_FN (BUILT_IN_FABS): 10039 case BUILT_IN_FABSD32: 10040 case BUILT_IN_FABSD64: 10041 case BUILT_IN_FABSD128: 10042 return fold_builtin_fabs (loc, arg0, type); 10043 10044 case BUILT_IN_ABS: 10045 case BUILT_IN_LABS: 10046 case BUILT_IN_LLABS: 10047 case BUILT_IN_IMAXABS: 10048 return fold_builtin_abs (loc, arg0, type); 10049 10050 CASE_FLT_FN (BUILT_IN_CONJ): 10051 if (validate_arg (arg0, COMPLEX_TYPE) 10052 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10053 return fold_build1_loc (loc, CONJ_EXPR, type, arg0); 10054 break; 10055 10056 CASE_FLT_FN (BUILT_IN_CREAL): 10057 if (validate_arg (arg0, COMPLEX_TYPE) 10058 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10059 return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));; 10060 break; 10061 10062 CASE_FLT_FN (BUILT_IN_CIMAG): 10063 if (validate_arg (arg0, COMPLEX_TYPE) 10064 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10065 return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0)); 10066 break; 10067 10068 CASE_FLT_FN (BUILT_IN_CCOS): 10069 return fold_builtin_ccos (loc, arg0, type, fndecl, /*hyper=*/ false); 10070 10071 CASE_FLT_FN (BUILT_IN_CCOSH): 10072 return fold_builtin_ccos (loc, arg0, type, fndecl, /*hyper=*/ true); 10073 10074 CASE_FLT_FN (BUILT_IN_CPROJ): 10075 return fold_builtin_cproj (loc, arg0, type); 10076 10077 CASE_FLT_FN (BUILT_IN_CSIN): 10078 if (validate_arg (arg0, COMPLEX_TYPE) 10079 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10080 return do_mpc_arg1 (arg0, type, mpc_sin); 10081 break; 10082 10083 CASE_FLT_FN (BUILT_IN_CSINH): 10084 if (validate_arg (arg0, COMPLEX_TYPE) 10085 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10086 return do_mpc_arg1 (arg0, type, mpc_sinh); 10087 break; 10088 10089 CASE_FLT_FN (BUILT_IN_CTAN): 10090 if (validate_arg (arg0, COMPLEX_TYPE) 10091 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10092 return do_mpc_arg1 (arg0, type, mpc_tan); 10093 break; 10094 10095 CASE_FLT_FN (BUILT_IN_CTANH): 10096 if (validate_arg (arg0, COMPLEX_TYPE) 10097 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10098 return do_mpc_arg1 (arg0, type, mpc_tanh); 10099 break; 10100 10101 CASE_FLT_FN (BUILT_IN_CLOG): 10102 if (validate_arg (arg0, COMPLEX_TYPE) 10103 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10104 return do_mpc_arg1 (arg0, type, mpc_log); 10105 break; 10106 10107 CASE_FLT_FN (BUILT_IN_CSQRT): 10108 if (validate_arg (arg0, COMPLEX_TYPE) 10109 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10110 return do_mpc_arg1 (arg0, type, mpc_sqrt); 10111 break; 10112 10113 CASE_FLT_FN (BUILT_IN_CASIN): 10114 if (validate_arg (arg0, COMPLEX_TYPE) 10115 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10116 return do_mpc_arg1 (arg0, type, mpc_asin); 10117 break; 10118 10119 CASE_FLT_FN (BUILT_IN_CACOS): 10120 if (validate_arg (arg0, COMPLEX_TYPE) 10121 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10122 return do_mpc_arg1 (arg0, type, mpc_acos); 10123 break; 10124 10125 CASE_FLT_FN (BUILT_IN_CATAN): 10126 if (validate_arg (arg0, COMPLEX_TYPE) 10127 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10128 return do_mpc_arg1 (arg0, type, mpc_atan); 10129 break; 10130 10131 CASE_FLT_FN (BUILT_IN_CASINH): 10132 if (validate_arg (arg0, COMPLEX_TYPE) 10133 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10134 return do_mpc_arg1 (arg0, type, mpc_asinh); 10135 break; 10136 10137 CASE_FLT_FN (BUILT_IN_CACOSH): 10138 if (validate_arg (arg0, COMPLEX_TYPE) 10139 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10140 return do_mpc_arg1 (arg0, type, mpc_acosh); 10141 break; 10142 10143 CASE_FLT_FN (BUILT_IN_CATANH): 10144 if (validate_arg (arg0, COMPLEX_TYPE) 10145 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 10146 return do_mpc_arg1 (arg0, type, mpc_atanh); 10147 break; 10148 10149 CASE_FLT_FN (BUILT_IN_CABS): 10150 return fold_builtin_cabs (loc, arg0, type, fndecl); 10151 10152 CASE_FLT_FN (BUILT_IN_CARG): 10153 return fold_builtin_carg (loc, arg0, type); 10154 10155 CASE_FLT_FN (BUILT_IN_SQRT): 10156 return fold_builtin_sqrt (loc, arg0, type); 10157 10158 CASE_FLT_FN (BUILT_IN_CBRT): 10159 return fold_builtin_cbrt (loc, arg0, type); 10160 10161 CASE_FLT_FN (BUILT_IN_ASIN): 10162 if (validate_arg (arg0, REAL_TYPE)) 10163 return do_mpfr_arg1 (arg0, type, mpfr_asin, 10164 &dconstm1, &dconst1, true); 10165 break; 10166 10167 CASE_FLT_FN (BUILT_IN_ACOS): 10168 if (validate_arg (arg0, REAL_TYPE)) 10169 return do_mpfr_arg1 (arg0, type, mpfr_acos, 10170 &dconstm1, &dconst1, true); 10171 break; 10172 10173 CASE_FLT_FN (BUILT_IN_ATAN): 10174 if (validate_arg (arg0, REAL_TYPE)) 10175 return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0); 10176 break; 10177 10178 CASE_FLT_FN (BUILT_IN_ASINH): 10179 if (validate_arg (arg0, REAL_TYPE)) 10180 return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0); 10181 break; 10182 10183 CASE_FLT_FN (BUILT_IN_ACOSH): 10184 if (validate_arg (arg0, REAL_TYPE)) 10185 return do_mpfr_arg1 (arg0, type, mpfr_acosh, 10186 &dconst1, NULL, true); 10187 break; 10188 10189 CASE_FLT_FN (BUILT_IN_ATANH): 10190 if (validate_arg (arg0, REAL_TYPE)) 10191 return do_mpfr_arg1 (arg0, type, mpfr_atanh, 10192 &dconstm1, &dconst1, false); 10193 break; 10194 10195 CASE_FLT_FN (BUILT_IN_SIN): 10196 if (validate_arg (arg0, REAL_TYPE)) 10197 return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0); 10198 break; 10199 10200 CASE_FLT_FN (BUILT_IN_COS): 10201 return fold_builtin_cos (loc, arg0, type, fndecl); 10202 10203 CASE_FLT_FN (BUILT_IN_TAN): 10204 return fold_builtin_tan (arg0, type); 10205 10206 CASE_FLT_FN (BUILT_IN_CEXP): 10207 return fold_builtin_cexp (loc, arg0, type); 10208 10209 CASE_FLT_FN (BUILT_IN_CEXPI): 10210 if (validate_arg (arg0, REAL_TYPE)) 10211 return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE); 10212 break; 10213 10214 CASE_FLT_FN (BUILT_IN_SINH): 10215 if (validate_arg (arg0, REAL_TYPE)) 10216 return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0); 10217 break; 10218 10219 CASE_FLT_FN (BUILT_IN_COSH): 10220 return fold_builtin_cosh (loc, arg0, type, fndecl); 10221 10222 CASE_FLT_FN (BUILT_IN_TANH): 10223 if (validate_arg (arg0, REAL_TYPE)) 10224 return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0); 10225 break; 10226 10227 CASE_FLT_FN (BUILT_IN_ERF): 10228 if (validate_arg (arg0, REAL_TYPE)) 10229 return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0); 10230 break; 10231 10232 CASE_FLT_FN (BUILT_IN_ERFC): 10233 if (validate_arg (arg0, REAL_TYPE)) 10234 return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0); 10235 break; 10236 10237 CASE_FLT_FN (BUILT_IN_TGAMMA): 10238 if (validate_arg (arg0, REAL_TYPE)) 10239 return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0); 10240 break; 10241 10242 CASE_FLT_FN (BUILT_IN_EXP): 10243 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp); 10244 10245 CASE_FLT_FN (BUILT_IN_EXP2): 10246 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2); 10247 10248 CASE_FLT_FN (BUILT_IN_EXP10): 10249 CASE_FLT_FN (BUILT_IN_POW10): 10250 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10); 10251 10252 CASE_FLT_FN (BUILT_IN_EXPM1): 10253 if (validate_arg (arg0, REAL_TYPE)) 10254 return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0); 10255 break; 10256 10257 CASE_FLT_FN (BUILT_IN_LOG): 10258 if (validate_arg (arg0, REAL_TYPE)) 10259 return do_mpfr_arg1 (arg0, type, mpfr_log, &dconst0, NULL, false); 10260 break; 10261 10262 CASE_FLT_FN (BUILT_IN_LOG2): 10263 if (validate_arg (arg0, REAL_TYPE)) 10264 return do_mpfr_arg1 (arg0, type, mpfr_log2, &dconst0, NULL, false); 10265 break; 10266 10267 CASE_FLT_FN (BUILT_IN_LOG10): 10268 if (validate_arg (arg0, REAL_TYPE)) 10269 return do_mpfr_arg1 (arg0, type, mpfr_log10, &dconst0, NULL, false); 10270 break; 10271 10272 CASE_FLT_FN (BUILT_IN_LOG1P): 10273 if (validate_arg (arg0, REAL_TYPE)) 10274 return do_mpfr_arg1 (arg0, type, mpfr_log1p, 10275 &dconstm1, NULL, false); 10276 break; 10277 10278 CASE_FLT_FN (BUILT_IN_J0): 10279 if (validate_arg (arg0, REAL_TYPE)) 10280 return do_mpfr_arg1 (arg0, type, mpfr_j0, 10281 NULL, NULL, 0); 10282 break; 10283 10284 CASE_FLT_FN (BUILT_IN_J1): 10285 if (validate_arg (arg0, REAL_TYPE)) 10286 return do_mpfr_arg1 (arg0, type, mpfr_j1, 10287 NULL, NULL, 0); 10288 break; 10289 10290 CASE_FLT_FN (BUILT_IN_Y0): 10291 if (validate_arg (arg0, REAL_TYPE)) 10292 return do_mpfr_arg1 (arg0, type, mpfr_y0, 10293 &dconst0, NULL, false); 10294 break; 10295 10296 CASE_FLT_FN (BUILT_IN_Y1): 10297 if (validate_arg (arg0, REAL_TYPE)) 10298 return do_mpfr_arg1 (arg0, type, mpfr_y1, 10299 &dconst0, NULL, false); 10300 break; 10301 10302 CASE_FLT_FN (BUILT_IN_NAN): 10303 case BUILT_IN_NAND32: 10304 case BUILT_IN_NAND64: 10305 case BUILT_IN_NAND128: 10306 return fold_builtin_nan (arg0, type, true); 10307 10308 CASE_FLT_FN (BUILT_IN_NANS): 10309 return fold_builtin_nan (arg0, type, false); 10310 10311 CASE_FLT_FN (BUILT_IN_FLOOR): 10312 return fold_builtin_floor (loc, fndecl, arg0); 10313 10314 CASE_FLT_FN (BUILT_IN_CEIL): 10315 return fold_builtin_ceil (loc, fndecl, arg0); 10316 10317 CASE_FLT_FN (BUILT_IN_TRUNC): 10318 return fold_builtin_trunc (loc, fndecl, arg0); 10319 10320 CASE_FLT_FN (BUILT_IN_ROUND): 10321 return fold_builtin_round (loc, fndecl, arg0); 10322 10323 CASE_FLT_FN (BUILT_IN_NEARBYINT): 10324 CASE_FLT_FN (BUILT_IN_RINT): 10325 return fold_trunc_transparent_mathfn (loc, fndecl, arg0); 10326 10327 CASE_FLT_FN (BUILT_IN_ICEIL): 10328 CASE_FLT_FN (BUILT_IN_LCEIL): 10329 CASE_FLT_FN (BUILT_IN_LLCEIL): 10330 CASE_FLT_FN (BUILT_IN_LFLOOR): 10331 CASE_FLT_FN (BUILT_IN_IFLOOR): 10332 CASE_FLT_FN (BUILT_IN_LLFLOOR): 10333 CASE_FLT_FN (BUILT_IN_IROUND): 10334 CASE_FLT_FN (BUILT_IN_LROUND): 10335 CASE_FLT_FN (BUILT_IN_LLROUND): 10336 return fold_builtin_int_roundingfn (loc, fndecl, arg0); 10337 10338 CASE_FLT_FN (BUILT_IN_IRINT): 10339 CASE_FLT_FN (BUILT_IN_LRINT): 10340 CASE_FLT_FN (BUILT_IN_LLRINT): 10341 return fold_fixed_mathfn (loc, fndecl, arg0); 10342 10343 case BUILT_IN_BSWAP16: 10344 case BUILT_IN_BSWAP32: 10345 case BUILT_IN_BSWAP64: 10346 return fold_builtin_bswap (fndecl, arg0); 10347 10348 CASE_INT_FN (BUILT_IN_FFS): 10349 CASE_INT_FN (BUILT_IN_CLZ): 10350 CASE_INT_FN (BUILT_IN_CTZ): 10351 CASE_INT_FN (BUILT_IN_CLRSB): 10352 CASE_INT_FN (BUILT_IN_POPCOUNT): 10353 CASE_INT_FN (BUILT_IN_PARITY): 10354 return fold_builtin_bitop (fndecl, arg0); 10355 10356 CASE_FLT_FN (BUILT_IN_SIGNBIT): 10357 return fold_builtin_signbit (loc, arg0, type); 10358 10359 CASE_FLT_FN (BUILT_IN_SIGNIFICAND): 10360 return fold_builtin_significand (loc, arg0, type); 10361 10362 CASE_FLT_FN (BUILT_IN_ILOGB): 10363 CASE_FLT_FN (BUILT_IN_LOGB): 10364 return fold_builtin_logb (loc, arg0, type); 10365 10366 case BUILT_IN_ISASCII: 10367 return fold_builtin_isascii (loc, arg0); 10368 10369 case BUILT_IN_TOASCII: 10370 return fold_builtin_toascii (loc, arg0); 10371 10372 case BUILT_IN_ISDIGIT: 10373 return fold_builtin_isdigit (loc, arg0); 10374 10375 CASE_FLT_FN (BUILT_IN_FINITE): 10376 case BUILT_IN_FINITED32: 10377 case BUILT_IN_FINITED64: 10378 case BUILT_IN_FINITED128: 10379 case BUILT_IN_ISFINITE: 10380 { 10381 tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE); 10382 if (ret) 10383 return ret; 10384 return fold_builtin_interclass_mathfn (loc, fndecl, arg0); 10385 } 10386 10387 CASE_FLT_FN (BUILT_IN_ISINF): 10388 case BUILT_IN_ISINFD32: 10389 case BUILT_IN_ISINFD64: 10390 case BUILT_IN_ISINFD128: 10391 { 10392 tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF); 10393 if (ret) 10394 return ret; 10395 return fold_builtin_interclass_mathfn (loc, fndecl, arg0); 10396 } 10397 10398 case BUILT_IN_ISNORMAL: 10399 return fold_builtin_interclass_mathfn (loc, fndecl, arg0); 10400 10401 case BUILT_IN_ISINF_SIGN: 10402 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN); 10403 10404 CASE_FLT_FN (BUILT_IN_ISNAN): 10405 case BUILT_IN_ISNAND32: 10406 case BUILT_IN_ISNAND64: 10407 case BUILT_IN_ISNAND128: 10408 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN); 10409 10410 case BUILT_IN_FREE: 10411 if (integer_zerop (arg0)) 10412 return build_empty_stmt (loc); 10413 break; 10414 10415 default: 10416 break; 10417 } 10418 10419 return NULL_TREE; 10420 10421} 10422 10423/* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1. 10424 This function returns NULL_TREE if no simplification was possible. */ 10425 10426static tree 10427fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1) 10428{ 10429 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 10430 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 10431 10432 switch (fcode) 10433 { 10434 CASE_FLT_FN (BUILT_IN_JN): 10435 if (validate_arg (arg0, INTEGER_TYPE) 10436 && validate_arg (arg1, REAL_TYPE)) 10437 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0); 10438 break; 10439 10440 CASE_FLT_FN (BUILT_IN_YN): 10441 if (validate_arg (arg0, INTEGER_TYPE) 10442 && validate_arg (arg1, REAL_TYPE)) 10443 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn, 10444 &dconst0, false); 10445 break; 10446 10447 CASE_FLT_FN (BUILT_IN_DREM): 10448 CASE_FLT_FN (BUILT_IN_REMAINDER): 10449 if (validate_arg (arg0, REAL_TYPE) 10450 && validate_arg (arg1, REAL_TYPE)) 10451 return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder); 10452 break; 10453 10454 CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */ 10455 CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */ 10456 if (validate_arg (arg0, REAL_TYPE) 10457 && validate_arg (arg1, POINTER_TYPE)) 10458 return do_mpfr_lgamma_r (arg0, arg1, type); 10459 break; 10460 10461 CASE_FLT_FN (BUILT_IN_ATAN2): 10462 if (validate_arg (arg0, REAL_TYPE) 10463 && validate_arg (arg1, REAL_TYPE)) 10464 return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2); 10465 break; 10466 10467 CASE_FLT_FN (BUILT_IN_FDIM): 10468 if (validate_arg (arg0, REAL_TYPE) 10469 && validate_arg (arg1, REAL_TYPE)) 10470 return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim); 10471 break; 10472 10473 CASE_FLT_FN (BUILT_IN_HYPOT): 10474 return fold_builtin_hypot (loc, fndecl, arg0, arg1, type); 10475 10476 CASE_FLT_FN (BUILT_IN_CPOW): 10477 if (validate_arg (arg0, COMPLEX_TYPE) 10478 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE 10479 && validate_arg (arg1, COMPLEX_TYPE) 10480 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE) 10481 return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow); 10482 break; 10483 10484 CASE_FLT_FN (BUILT_IN_LDEXP): 10485 return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true); 10486 CASE_FLT_FN (BUILT_IN_SCALBN): 10487 CASE_FLT_FN (BUILT_IN_SCALBLN): 10488 return fold_builtin_load_exponent (loc, arg0, arg1, 10489 type, /*ldexp=*/false); 10490 10491 CASE_FLT_FN (BUILT_IN_FREXP): 10492 return fold_builtin_frexp (loc, arg0, arg1, type); 10493 10494 CASE_FLT_FN (BUILT_IN_MODF): 10495 return fold_builtin_modf (loc, arg0, arg1, type); 10496 10497 case BUILT_IN_STRSTR: 10498 return fold_builtin_strstr (loc, arg0, arg1, type); 10499 10500 case BUILT_IN_STRSPN: 10501 return fold_builtin_strspn (loc, arg0, arg1); 10502 10503 case BUILT_IN_STRCSPN: 10504 return fold_builtin_strcspn (loc, arg0, arg1); 10505 10506 case BUILT_IN_STRCHR: 10507 case BUILT_IN_INDEX: 10508 return fold_builtin_strchr (loc, arg0, arg1, type); 10509 10510 case BUILT_IN_STRRCHR: 10511 case BUILT_IN_RINDEX: 10512 return fold_builtin_strrchr (loc, arg0, arg1, type); 10513 10514 case BUILT_IN_STRCMP: 10515 return fold_builtin_strcmp (loc, arg0, arg1); 10516 10517 case BUILT_IN_STRPBRK: 10518 return fold_builtin_strpbrk (loc, arg0, arg1, type); 10519 10520 case BUILT_IN_EXPECT: 10521 return fold_builtin_expect (loc, arg0, arg1, NULL_TREE); 10522 10523 CASE_FLT_FN (BUILT_IN_POW): 10524 return fold_builtin_pow (loc, fndecl, arg0, arg1, type); 10525 10526 CASE_FLT_FN (BUILT_IN_POWI): 10527 return fold_builtin_powi (loc, fndecl, arg0, arg1, type); 10528 10529 CASE_FLT_FN (BUILT_IN_COPYSIGN): 10530 return fold_builtin_copysign (loc, fndecl, arg0, arg1, type); 10531 10532 CASE_FLT_FN (BUILT_IN_FMIN): 10533 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false); 10534 10535 CASE_FLT_FN (BUILT_IN_FMAX): 10536 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true); 10537 10538 case BUILT_IN_ISGREATER: 10539 return fold_builtin_unordered_cmp (loc, fndecl, 10540 arg0, arg1, UNLE_EXPR, LE_EXPR); 10541 case BUILT_IN_ISGREATEREQUAL: 10542 return fold_builtin_unordered_cmp (loc, fndecl, 10543 arg0, arg1, UNLT_EXPR, LT_EXPR); 10544 case BUILT_IN_ISLESS: 10545 return fold_builtin_unordered_cmp (loc, fndecl, 10546 arg0, arg1, UNGE_EXPR, GE_EXPR); 10547 case BUILT_IN_ISLESSEQUAL: 10548 return fold_builtin_unordered_cmp (loc, fndecl, 10549 arg0, arg1, UNGT_EXPR, GT_EXPR); 10550 case BUILT_IN_ISLESSGREATER: 10551 return fold_builtin_unordered_cmp (loc, fndecl, 10552 arg0, arg1, UNEQ_EXPR, EQ_EXPR); 10553 case BUILT_IN_ISUNORDERED: 10554 return fold_builtin_unordered_cmp (loc, fndecl, 10555 arg0, arg1, UNORDERED_EXPR, 10556 NOP_EXPR); 10557 10558 /* We do the folding for va_start in the expander. */ 10559 case BUILT_IN_VA_START: 10560 break; 10561 10562 case BUILT_IN_OBJECT_SIZE: 10563 return fold_builtin_object_size (arg0, arg1); 10564 10565 case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE: 10566 return fold_builtin_atomic_always_lock_free (arg0, arg1); 10567 10568 case BUILT_IN_ATOMIC_IS_LOCK_FREE: 10569 return fold_builtin_atomic_is_lock_free (arg0, arg1); 10570 10571 default: 10572 break; 10573 } 10574 return NULL_TREE; 10575} 10576 10577/* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1, 10578 and ARG2. 10579 This function returns NULL_TREE if no simplification was possible. */ 10580 10581static tree 10582fold_builtin_3 (location_t loc, tree fndecl, 10583 tree arg0, tree arg1, tree arg2) 10584{ 10585 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 10586 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 10587 switch (fcode) 10588 { 10589 10590 CASE_FLT_FN (BUILT_IN_SINCOS): 10591 return fold_builtin_sincos (loc, arg0, arg1, arg2); 10592 10593 CASE_FLT_FN (BUILT_IN_FMA): 10594 return fold_builtin_fma (loc, arg0, arg1, arg2, type); 10595 break; 10596 10597 CASE_FLT_FN (BUILT_IN_REMQUO): 10598 if (validate_arg (arg0, REAL_TYPE) 10599 && validate_arg (arg1, REAL_TYPE) 10600 && validate_arg (arg2, POINTER_TYPE)) 10601 return do_mpfr_remquo (arg0, arg1, arg2); 10602 break; 10603 10604 case BUILT_IN_STRNCMP: 10605 return fold_builtin_strncmp (loc, arg0, arg1, arg2); 10606 10607 case BUILT_IN_MEMCHR: 10608 return fold_builtin_memchr (loc, arg0, arg1, arg2, type); 10609 10610 case BUILT_IN_BCMP: 10611 case BUILT_IN_MEMCMP: 10612 return fold_builtin_memcmp (loc, arg0, arg1, arg2);; 10613 10614 case BUILT_IN_EXPECT: 10615 return fold_builtin_expect (loc, arg0, arg1, arg2); 10616 10617 case BUILT_IN_ADD_OVERFLOW: 10618 case BUILT_IN_SUB_OVERFLOW: 10619 case BUILT_IN_MUL_OVERFLOW: 10620 case BUILT_IN_SADD_OVERFLOW: 10621 case BUILT_IN_SADDL_OVERFLOW: 10622 case BUILT_IN_SADDLL_OVERFLOW: 10623 case BUILT_IN_SSUB_OVERFLOW: 10624 case BUILT_IN_SSUBL_OVERFLOW: 10625 case BUILT_IN_SSUBLL_OVERFLOW: 10626 case BUILT_IN_SMUL_OVERFLOW: 10627 case BUILT_IN_SMULL_OVERFLOW: 10628 case BUILT_IN_SMULLL_OVERFLOW: 10629 case BUILT_IN_UADD_OVERFLOW: 10630 case BUILT_IN_UADDL_OVERFLOW: 10631 case BUILT_IN_UADDLL_OVERFLOW: 10632 case BUILT_IN_USUB_OVERFLOW: 10633 case BUILT_IN_USUBL_OVERFLOW: 10634 case BUILT_IN_USUBLL_OVERFLOW: 10635 case BUILT_IN_UMUL_OVERFLOW: 10636 case BUILT_IN_UMULL_OVERFLOW: 10637 case BUILT_IN_UMULLL_OVERFLOW: 10638 return fold_builtin_arith_overflow (loc, fcode, arg0, arg1, arg2); 10639 10640 default: 10641 break; 10642 } 10643 return NULL_TREE; 10644} 10645 10646/* Fold a call to built-in function FNDECL. ARGS is an array of NARGS 10647 arguments. IGNORE is true if the result of the 10648 function call is ignored. This function returns NULL_TREE if no 10649 simplification was possible. */ 10650 10651tree 10652fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool) 10653{ 10654 tree ret = NULL_TREE; 10655 10656 switch (nargs) 10657 { 10658 case 0: 10659 ret = fold_builtin_0 (loc, fndecl); 10660 break; 10661 case 1: 10662 ret = fold_builtin_1 (loc, fndecl, args[0]); 10663 break; 10664 case 2: 10665 ret = fold_builtin_2 (loc, fndecl, args[0], args[1]); 10666 break; 10667 case 3: 10668 ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2]); 10669 break; 10670 default: 10671 ret = fold_builtin_varargs (loc, fndecl, args, nargs); 10672 break; 10673 } 10674 if (ret) 10675 { 10676 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); 10677 SET_EXPR_LOCATION (ret, loc); 10678 TREE_NO_WARNING (ret) = 1; 10679 return ret; 10680 } 10681 return NULL_TREE; 10682} 10683 10684/* Construct a new CALL_EXPR to FNDECL using the tail of the argument 10685 list ARGS along with N new arguments in NEWARGS. SKIP is the number 10686 of arguments in ARGS to be omitted. OLDNARGS is the number of 10687 elements in ARGS. */ 10688 10689static tree 10690rewrite_call_expr_valist (location_t loc, int oldnargs, tree *args, 10691 int skip, tree fndecl, int n, va_list newargs) 10692{ 10693 int nargs = oldnargs - skip + n; 10694 tree *buffer; 10695 10696 if (n > 0) 10697 { 10698 int i, j; 10699 10700 buffer = XALLOCAVEC (tree, nargs); 10701 for (i = 0; i < n; i++) 10702 buffer[i] = va_arg (newargs, tree); 10703 for (j = skip; j < oldnargs; j++, i++) 10704 buffer[i] = args[j]; 10705 } 10706 else 10707 buffer = args + skip; 10708 10709 return build_call_expr_loc_array (loc, fndecl, nargs, buffer); 10710} 10711 10712/* Return true if FNDECL shouldn't be folded right now. 10713 If a built-in function has an inline attribute always_inline 10714 wrapper, defer folding it after always_inline functions have 10715 been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking 10716 might not be performed. */ 10717 10718bool 10719avoid_folding_inline_builtin (tree fndecl) 10720{ 10721 return (DECL_DECLARED_INLINE_P (fndecl) 10722 && DECL_DISREGARD_INLINE_LIMITS (fndecl) 10723 && cfun 10724 && !cfun->always_inline_functions_inlined 10725 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl))); 10726} 10727 10728/* A wrapper function for builtin folding that prevents warnings for 10729 "statement without effect" and the like, caused by removing the 10730 call node earlier than the warning is generated. */ 10731 10732tree 10733fold_call_expr (location_t loc, tree exp, bool ignore) 10734{ 10735 tree ret = NULL_TREE; 10736 tree fndecl = get_callee_fndecl (exp); 10737 if (fndecl 10738 && TREE_CODE (fndecl) == FUNCTION_DECL 10739 && DECL_BUILT_IN (fndecl) 10740 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized 10741 yet. Defer folding until we see all the arguments 10742 (after inlining). */ 10743 && !CALL_EXPR_VA_ARG_PACK (exp)) 10744 { 10745 int nargs = call_expr_nargs (exp); 10746 10747 /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but 10748 instead last argument is __builtin_va_arg_pack (). Defer folding 10749 even in that case, until arguments are finalized. */ 10750 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR) 10751 { 10752 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1)); 10753 if (fndecl2 10754 && TREE_CODE (fndecl2) == FUNCTION_DECL 10755 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL 10756 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK) 10757 return NULL_TREE; 10758 } 10759 10760 if (avoid_folding_inline_builtin (fndecl)) 10761 return NULL_TREE; 10762 10763 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 10764 return targetm.fold_builtin (fndecl, call_expr_nargs (exp), 10765 CALL_EXPR_ARGP (exp), ignore); 10766 else 10767 { 10768 tree *args = CALL_EXPR_ARGP (exp); 10769 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore); 10770 if (ret) 10771 return ret; 10772 } 10773 } 10774 return NULL_TREE; 10775} 10776 10777/* Fold a CALL_EXPR with type TYPE with FN as the function expression. 10778 N arguments are passed in the array ARGARRAY. Return a folded 10779 expression or NULL_TREE if no simplification was possible. */ 10780 10781tree 10782fold_builtin_call_array (location_t loc, tree, 10783 tree fn, 10784 int n, 10785 tree *argarray) 10786{ 10787 if (TREE_CODE (fn) != ADDR_EXPR) 10788 return NULL_TREE; 10789 10790 tree fndecl = TREE_OPERAND (fn, 0); 10791 if (TREE_CODE (fndecl) == FUNCTION_DECL 10792 && DECL_BUILT_IN (fndecl)) 10793 { 10794 /* If last argument is __builtin_va_arg_pack (), arguments to this 10795 function are not finalized yet. Defer folding until they are. */ 10796 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR) 10797 { 10798 tree fndecl2 = get_callee_fndecl (argarray[n - 1]); 10799 if (fndecl2 10800 && TREE_CODE (fndecl2) == FUNCTION_DECL 10801 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL 10802 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK) 10803 return NULL_TREE; 10804 } 10805 if (avoid_folding_inline_builtin (fndecl)) 10806 return NULL_TREE; 10807 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 10808 return targetm.fold_builtin (fndecl, n, argarray, false); 10809 else 10810 return fold_builtin_n (loc, fndecl, argarray, n, false); 10811 } 10812 10813 return NULL_TREE; 10814} 10815 10816/* Construct a new CALL_EXPR using the tail of the argument list of EXP 10817 along with N new arguments specified as the "..." parameters. SKIP 10818 is the number of arguments in EXP to be omitted. This function is used 10819 to do varargs-to-varargs transformations. */ 10820 10821static tree 10822rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...) 10823{ 10824 va_list ap; 10825 tree t; 10826 10827 va_start (ap, n); 10828 t = rewrite_call_expr_valist (loc, call_expr_nargs (exp), 10829 CALL_EXPR_ARGP (exp), skip, fndecl, n, ap); 10830 va_end (ap); 10831 10832 return t; 10833} 10834 10835/* Validate a single argument ARG against a tree code CODE representing 10836 a type. */ 10837 10838static bool 10839validate_arg (const_tree arg, enum tree_code code) 10840{ 10841 if (!arg) 10842 return false; 10843 else if (code == POINTER_TYPE) 10844 return POINTER_TYPE_P (TREE_TYPE (arg)); 10845 else if (code == INTEGER_TYPE) 10846 return INTEGRAL_TYPE_P (TREE_TYPE (arg)); 10847 return code == TREE_CODE (TREE_TYPE (arg)); 10848} 10849 10850/* This function validates the types of a function call argument list 10851 against a specified list of tree_codes. If the last specifier is a 0, 10852 that represents an ellipses, otherwise the last specifier must be a 10853 VOID_TYPE. 10854 10855 This is the GIMPLE version of validate_arglist. Eventually we want to 10856 completely convert builtins.c to work from GIMPLEs and the tree based 10857 validate_arglist will then be removed. */ 10858 10859bool 10860validate_gimple_arglist (const gcall *call, ...) 10861{ 10862 enum tree_code code; 10863 bool res = 0; 10864 va_list ap; 10865 const_tree arg; 10866 size_t i; 10867 10868 va_start (ap, call); 10869 i = 0; 10870 10871 do 10872 { 10873 code = (enum tree_code) va_arg (ap, int); 10874 switch (code) 10875 { 10876 case 0: 10877 /* This signifies an ellipses, any further arguments are all ok. */ 10878 res = true; 10879 goto end; 10880 case VOID_TYPE: 10881 /* This signifies an endlink, if no arguments remain, return 10882 true, otherwise return false. */ 10883 res = (i == gimple_call_num_args (call)); 10884 goto end; 10885 default: 10886 /* If no parameters remain or the parameter's code does not 10887 match the specified code, return false. Otherwise continue 10888 checking any remaining arguments. */ 10889 arg = gimple_call_arg (call, i++); 10890 if (!validate_arg (arg, code)) 10891 goto end; 10892 break; 10893 } 10894 } 10895 while (1); 10896 10897 /* We need gotos here since we can only have one VA_CLOSE in a 10898 function. */ 10899 end: ; 10900 va_end (ap); 10901 10902 return res; 10903} 10904 10905/* Default target-specific builtin expander that does nothing. */ 10906 10907rtx 10908default_expand_builtin (tree exp ATTRIBUTE_UNUSED, 10909 rtx target ATTRIBUTE_UNUSED, 10910 rtx subtarget ATTRIBUTE_UNUSED, 10911 machine_mode mode ATTRIBUTE_UNUSED, 10912 int ignore ATTRIBUTE_UNUSED) 10913{ 10914 return NULL_RTX; 10915} 10916 10917/* Returns true is EXP represents data that would potentially reside 10918 in a readonly section. */ 10919 10920bool 10921readonly_data_expr (tree exp) 10922{ 10923 STRIP_NOPS (exp); 10924 10925 if (TREE_CODE (exp) != ADDR_EXPR) 10926 return false; 10927 10928 exp = get_base_address (TREE_OPERAND (exp, 0)); 10929 if (!exp) 10930 return false; 10931 10932 /* Make sure we call decl_readonly_section only for trees it 10933 can handle (since it returns true for everything it doesn't 10934 understand). */ 10935 if (TREE_CODE (exp) == STRING_CST 10936 || TREE_CODE (exp) == CONSTRUCTOR 10937 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp))) 10938 return decl_readonly_section (exp, 0); 10939 else 10940 return false; 10941} 10942 10943/* Simplify a call to the strstr builtin. S1 and S2 are the arguments 10944 to the call, and TYPE is its return type. 10945 10946 Return NULL_TREE if no simplification was possible, otherwise return the 10947 simplified form of the call as a tree. 10948 10949 The simplified form may be a constant or other expression which 10950 computes the same value, but in a more efficient manner (including 10951 calls to other builtin functions). 10952 10953 The call may contain arguments which need to be evaluated, but 10954 which are not useful to determine the result of the call. In 10955 this case we return a chain of COMPOUND_EXPRs. The LHS of each 10956 COMPOUND_EXPR will be an argument which must be evaluated. 10957 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 10958 COMPOUND_EXPR in the chain will contain the tree for the simplified 10959 form of the builtin function call. */ 10960 10961static tree 10962fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type) 10963{ 10964 if (!validate_arg (s1, POINTER_TYPE) 10965 || !validate_arg (s2, POINTER_TYPE)) 10966 return NULL_TREE; 10967 else 10968 { 10969 tree fn; 10970 const char *p1, *p2; 10971 10972 p2 = c_getstr (s2); 10973 if (p2 == NULL) 10974 return NULL_TREE; 10975 10976 p1 = c_getstr (s1); 10977 if (p1 != NULL) 10978 { 10979 const char *r = strstr (p1, p2); 10980 tree tem; 10981 10982 if (r == NULL) 10983 return build_int_cst (TREE_TYPE (s1), 0); 10984 10985 /* Return an offset into the constant string argument. */ 10986 tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1); 10987 return fold_convert_loc (loc, type, tem); 10988 } 10989 10990 /* The argument is const char *, and the result is char *, so we need 10991 a type conversion here to avoid a warning. */ 10992 if (p2[0] == '\0') 10993 return fold_convert_loc (loc, type, s1); 10994 10995 if (p2[1] != '\0') 10996 return NULL_TREE; 10997 10998 fn = builtin_decl_implicit (BUILT_IN_STRCHR); 10999 if (!fn) 11000 return NULL_TREE; 11001 11002 /* New argument list transforming strstr(s1, s2) to 11003 strchr(s1, s2[0]). */ 11004 return build_call_expr_loc (loc, fn, 2, s1, 11005 build_int_cst (integer_type_node, p2[0])); 11006 } 11007} 11008 11009/* Simplify a call to the strchr builtin. S1 and S2 are the arguments to 11010 the call, and TYPE is its return type. 11011 11012 Return NULL_TREE if no simplification was possible, otherwise return the 11013 simplified form of the call as a tree. 11014 11015 The simplified form may be a constant or other expression which 11016 computes the same value, but in a more efficient manner (including 11017 calls to other builtin functions). 11018 11019 The call may contain arguments which need to be evaluated, but 11020 which are not useful to determine the result of the call. In 11021 this case we return a chain of COMPOUND_EXPRs. The LHS of each 11022 COMPOUND_EXPR will be an argument which must be evaluated. 11023 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 11024 COMPOUND_EXPR in the chain will contain the tree for the simplified 11025 form of the builtin function call. */ 11026 11027static tree 11028fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type) 11029{ 11030 if (!validate_arg (s1, POINTER_TYPE) 11031 || !validate_arg (s2, INTEGER_TYPE)) 11032 return NULL_TREE; 11033 else 11034 { 11035 const char *p1; 11036 11037 if (TREE_CODE (s2) != INTEGER_CST) 11038 return NULL_TREE; 11039 11040 p1 = c_getstr (s1); 11041 if (p1 != NULL) 11042 { 11043 char c; 11044 const char *r; 11045 tree tem; 11046 11047 if (target_char_cast (s2, &c)) 11048 return NULL_TREE; 11049 11050 r = strchr (p1, c); 11051 11052 if (r == NULL) 11053 return build_int_cst (TREE_TYPE (s1), 0); 11054 11055 /* Return an offset into the constant string argument. */ 11056 tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1); 11057 return fold_convert_loc (loc, type, tem); 11058 } 11059 return NULL_TREE; 11060 } 11061} 11062 11063/* Simplify a call to the strrchr builtin. S1 and S2 are the arguments to 11064 the call, and TYPE is its return type. 11065 11066 Return NULL_TREE if no simplification was possible, otherwise return the 11067 simplified form of the call as a tree. 11068 11069 The simplified form may be a constant or other expression which 11070 computes the same value, but in a more efficient manner (including 11071 calls to other builtin functions). 11072 11073 The call may contain arguments which need to be evaluated, but 11074 which are not useful to determine the result of the call. In 11075 this case we return a chain of COMPOUND_EXPRs. The LHS of each 11076 COMPOUND_EXPR will be an argument which must be evaluated. 11077 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 11078 COMPOUND_EXPR in the chain will contain the tree for the simplified 11079 form of the builtin function call. */ 11080 11081static tree 11082fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type) 11083{ 11084 if (!validate_arg (s1, POINTER_TYPE) 11085 || !validate_arg (s2, INTEGER_TYPE)) 11086 return NULL_TREE; 11087 else 11088 { 11089 tree fn; 11090 const char *p1; 11091 11092 if (TREE_CODE (s2) != INTEGER_CST) 11093 return NULL_TREE; 11094 11095 p1 = c_getstr (s1); 11096 if (p1 != NULL) 11097 { 11098 char c; 11099 const char *r; 11100 tree tem; 11101 11102 if (target_char_cast (s2, &c)) 11103 return NULL_TREE; 11104 11105 r = strrchr (p1, c); 11106 11107 if (r == NULL) 11108 return build_int_cst (TREE_TYPE (s1), 0); 11109 11110 /* Return an offset into the constant string argument. */ 11111 tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1); 11112 return fold_convert_loc (loc, type, tem); 11113 } 11114 11115 if (! integer_zerop (s2)) 11116 return NULL_TREE; 11117 11118 fn = builtin_decl_implicit (BUILT_IN_STRCHR); 11119 if (!fn) 11120 return NULL_TREE; 11121 11122 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */ 11123 return build_call_expr_loc (loc, fn, 2, s1, s2); 11124 } 11125} 11126 11127/* Simplify a call to the strpbrk builtin. S1 and S2 are the arguments 11128 to the call, and TYPE is its return type. 11129 11130 Return NULL_TREE if no simplification was possible, otherwise return the 11131 simplified form of the call as a tree. 11132 11133 The simplified form may be a constant or other expression which 11134 computes the same value, but in a more efficient manner (including 11135 calls to other builtin functions). 11136 11137 The call may contain arguments which need to be evaluated, but 11138 which are not useful to determine the result of the call. In 11139 this case we return a chain of COMPOUND_EXPRs. The LHS of each 11140 COMPOUND_EXPR will be an argument which must be evaluated. 11141 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 11142 COMPOUND_EXPR in the chain will contain the tree for the simplified 11143 form of the builtin function call. */ 11144 11145static tree 11146fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type) 11147{ 11148 if (!validate_arg (s1, POINTER_TYPE) 11149 || !validate_arg (s2, POINTER_TYPE)) 11150 return NULL_TREE; 11151 else 11152 { 11153 tree fn; 11154 const char *p1, *p2; 11155 11156 p2 = c_getstr (s2); 11157 if (p2 == NULL) 11158 return NULL_TREE; 11159 11160 p1 = c_getstr (s1); 11161 if (p1 != NULL) 11162 { 11163 const char *r = strpbrk (p1, p2); 11164 tree tem; 11165 11166 if (r == NULL) 11167 return build_int_cst (TREE_TYPE (s1), 0); 11168 11169 /* Return an offset into the constant string argument. */ 11170 tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1); 11171 return fold_convert_loc (loc, type, tem); 11172 } 11173 11174 if (p2[0] == '\0') 11175 /* strpbrk(x, "") == NULL. 11176 Evaluate and ignore s1 in case it had side-effects. */ 11177 return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1); 11178 11179 if (p2[1] != '\0') 11180 return NULL_TREE; /* Really call strpbrk. */ 11181 11182 fn = builtin_decl_implicit (BUILT_IN_STRCHR); 11183 if (!fn) 11184 return NULL_TREE; 11185 11186 /* New argument list transforming strpbrk(s1, s2) to 11187 strchr(s1, s2[0]). */ 11188 return build_call_expr_loc (loc, fn, 2, s1, 11189 build_int_cst (integer_type_node, p2[0])); 11190 } 11191} 11192 11193/* Simplify a call to the strspn builtin. S1 and S2 are the arguments 11194 to the call. 11195 11196 Return NULL_TREE if no simplification was possible, otherwise return the 11197 simplified form of the call as a tree. 11198 11199 The simplified form may be a constant or other expression which 11200 computes the same value, but in a more efficient manner (including 11201 calls to other builtin functions). 11202 11203 The call may contain arguments which need to be evaluated, but 11204 which are not useful to determine the result of the call. In 11205 this case we return a chain of COMPOUND_EXPRs. The LHS of each 11206 COMPOUND_EXPR will be an argument which must be evaluated. 11207 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 11208 COMPOUND_EXPR in the chain will contain the tree for the simplified 11209 form of the builtin function call. */ 11210 11211static tree 11212fold_builtin_strspn (location_t loc, tree s1, tree s2) 11213{ 11214 if (!validate_arg (s1, POINTER_TYPE) 11215 || !validate_arg (s2, POINTER_TYPE)) 11216 return NULL_TREE; 11217 else 11218 { 11219 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); 11220 11221 /* If both arguments are constants, evaluate at compile-time. */ 11222 if (p1 && p2) 11223 { 11224 const size_t r = strspn (p1, p2); 11225 return build_int_cst (size_type_node, r); 11226 } 11227 11228 /* If either argument is "", return NULL_TREE. */ 11229 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')) 11230 /* Evaluate and ignore both arguments in case either one has 11231 side-effects. */ 11232 return omit_two_operands_loc (loc, size_type_node, size_zero_node, 11233 s1, s2); 11234 return NULL_TREE; 11235 } 11236} 11237 11238/* Simplify a call to the strcspn builtin. S1 and S2 are the arguments 11239 to the call. 11240 11241 Return NULL_TREE if no simplification was possible, otherwise return the 11242 simplified form of the call as a tree. 11243 11244 The simplified form may be a constant or other expression which 11245 computes the same value, but in a more efficient manner (including 11246 calls to other builtin functions). 11247 11248 The call may contain arguments which need to be evaluated, but 11249 which are not useful to determine the result of the call. In 11250 this case we return a chain of COMPOUND_EXPRs. The LHS of each 11251 COMPOUND_EXPR will be an argument which must be evaluated. 11252 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 11253 COMPOUND_EXPR in the chain will contain the tree for the simplified 11254 form of the builtin function call. */ 11255 11256static tree 11257fold_builtin_strcspn (location_t loc, tree s1, tree s2) 11258{ 11259 if (!validate_arg (s1, POINTER_TYPE) 11260 || !validate_arg (s2, POINTER_TYPE)) 11261 return NULL_TREE; 11262 else 11263 { 11264 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); 11265 11266 /* If both arguments are constants, evaluate at compile-time. */ 11267 if (p1 && p2) 11268 { 11269 const size_t r = strcspn (p1, p2); 11270 return build_int_cst (size_type_node, r); 11271 } 11272 11273 /* If the first argument is "", return NULL_TREE. */ 11274 if (p1 && *p1 == '\0') 11275 { 11276 /* Evaluate and ignore argument s2 in case it has 11277 side-effects. */ 11278 return omit_one_operand_loc (loc, size_type_node, 11279 size_zero_node, s2); 11280 } 11281 11282 /* If the second argument is "", return __builtin_strlen(s1). */ 11283 if (p2 && *p2 == '\0') 11284 { 11285 tree fn = builtin_decl_implicit (BUILT_IN_STRLEN); 11286 11287 /* If the replacement _DECL isn't initialized, don't do the 11288 transformation. */ 11289 if (!fn) 11290 return NULL_TREE; 11291 11292 return build_call_expr_loc (loc, fn, 1, s1); 11293 } 11294 return NULL_TREE; 11295 } 11296} 11297 11298/* Fold the next_arg or va_start call EXP. Returns true if there was an error 11299 produced. False otherwise. This is done so that we don't output the error 11300 or warning twice or three times. */ 11301 11302bool 11303fold_builtin_next_arg (tree exp, bool va_start_p) 11304{ 11305 tree fntype = TREE_TYPE (current_function_decl); 11306 int nargs = call_expr_nargs (exp); 11307 tree arg; 11308 /* There is good chance the current input_location points inside the 11309 definition of the va_start macro (perhaps on the token for 11310 builtin) in a system header, so warnings will not be emitted. 11311 Use the location in real source code. */ 11312 source_location current_location = 11313 linemap_unwind_to_first_non_reserved_loc (line_table, input_location, 11314 NULL); 11315 11316 if (!stdarg_p (fntype)) 11317 { 11318 error ("%<va_start%> used in function with fixed args"); 11319 return true; 11320 } 11321 11322 if (va_start_p) 11323 { 11324 if (va_start_p && (nargs != 2)) 11325 { 11326 error ("wrong number of arguments to function %<va_start%>"); 11327 return true; 11328 } 11329 arg = CALL_EXPR_ARG (exp, 1); 11330 } 11331 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0) 11332 when we checked the arguments and if needed issued a warning. */ 11333 else 11334 { 11335 if (nargs == 0) 11336 { 11337 /* Evidently an out of date version of <stdarg.h>; can't validate 11338 va_start's second argument, but can still work as intended. */ 11339 warning_at (current_location, 11340 OPT_Wvarargs, 11341 "%<__builtin_next_arg%> called without an argument"); 11342 return true; 11343 } 11344 else if (nargs > 1) 11345 { 11346 error ("wrong number of arguments to function %<__builtin_next_arg%>"); 11347 return true; 11348 } 11349 arg = CALL_EXPR_ARG (exp, 0); 11350 } 11351 11352 if (TREE_CODE (arg) == SSA_NAME) 11353 arg = SSA_NAME_VAR (arg); 11354 11355 /* We destructively modify the call to be __builtin_va_start (ap, 0) 11356 or __builtin_next_arg (0) the first time we see it, after checking 11357 the arguments and if needed issuing a warning. */ 11358 if (!integer_zerop (arg)) 11359 { 11360 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl)); 11361 11362 /* Strip off all nops for the sake of the comparison. This 11363 is not quite the same as STRIP_NOPS. It does more. 11364 We must also strip off INDIRECT_EXPR for C++ reference 11365 parameters. */ 11366 while (CONVERT_EXPR_P (arg) 11367 || TREE_CODE (arg) == INDIRECT_REF) 11368 arg = TREE_OPERAND (arg, 0); 11369 if (arg != last_parm) 11370 { 11371 /* FIXME: Sometimes with the tree optimizers we can get the 11372 not the last argument even though the user used the last 11373 argument. We just warn and set the arg to be the last 11374 argument so that we will get wrong-code because of 11375 it. */ 11376 warning_at (current_location, 11377 OPT_Wvarargs, 11378 "second parameter of %<va_start%> not last named argument"); 11379 } 11380 11381 /* Undefined by C99 7.15.1.4p4 (va_start): 11382 "If the parameter parmN is declared with the register storage 11383 class, with a function or array type, or with a type that is 11384 not compatible with the type that results after application of 11385 the default argument promotions, the behavior is undefined." 11386 */ 11387 else if (DECL_REGISTER (arg)) 11388 { 11389 warning_at (current_location, 11390 OPT_Wvarargs, 11391 "undefined behaviour when second parameter of " 11392 "%<va_start%> is declared with %<register%> storage"); 11393 } 11394 11395 /* We want to verify the second parameter just once before the tree 11396 optimizers are run and then avoid keeping it in the tree, 11397 as otherwise we could warn even for correct code like: 11398 void foo (int i, ...) 11399 { va_list ap; i++; va_start (ap, i); va_end (ap); } */ 11400 if (va_start_p) 11401 CALL_EXPR_ARG (exp, 1) = integer_zero_node; 11402 else 11403 CALL_EXPR_ARG (exp, 0) = integer_zero_node; 11404 } 11405 return false; 11406} 11407 11408 11409/* Expand a call EXP to __builtin_object_size. */ 11410 11411static rtx 11412expand_builtin_object_size (tree exp) 11413{ 11414 tree ost; 11415 int object_size_type; 11416 tree fndecl = get_callee_fndecl (exp); 11417 11418 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 11419 { 11420 error ("%Kfirst argument of %D must be a pointer, second integer constant", 11421 exp, fndecl); 11422 expand_builtin_trap (); 11423 return const0_rtx; 11424 } 11425 11426 ost = CALL_EXPR_ARG (exp, 1); 11427 STRIP_NOPS (ost); 11428 11429 if (TREE_CODE (ost) != INTEGER_CST 11430 || tree_int_cst_sgn (ost) < 0 11431 || compare_tree_int (ost, 3) > 0) 11432 { 11433 error ("%Klast argument of %D is not integer constant between 0 and 3", 11434 exp, fndecl); 11435 expand_builtin_trap (); 11436 return const0_rtx; 11437 } 11438 11439 object_size_type = tree_to_shwi (ost); 11440 11441 return object_size_type < 2 ? constm1_rtx : const0_rtx; 11442} 11443 11444/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin. 11445 FCODE is the BUILT_IN_* to use. 11446 Return NULL_RTX if we failed; the caller should emit a normal call, 11447 otherwise try to get the result in TARGET, if convenient (and in 11448 mode MODE if that's convenient). */ 11449 11450static rtx 11451expand_builtin_memory_chk (tree exp, rtx target, machine_mode mode, 11452 enum built_in_function fcode) 11453{ 11454 tree dest, src, len, size; 11455 11456 if (!validate_arglist (exp, 11457 POINTER_TYPE, 11458 fcode == BUILT_IN_MEMSET_CHK 11459 ? INTEGER_TYPE : POINTER_TYPE, 11460 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 11461 return NULL_RTX; 11462 11463 dest = CALL_EXPR_ARG (exp, 0); 11464 src = CALL_EXPR_ARG (exp, 1); 11465 len = CALL_EXPR_ARG (exp, 2); 11466 size = CALL_EXPR_ARG (exp, 3); 11467 11468 if (! tree_fits_uhwi_p (size)) 11469 return NULL_RTX; 11470 11471 if (tree_fits_uhwi_p (len) || integer_all_onesp (size)) 11472 { 11473 tree fn; 11474 11475 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len)) 11476 { 11477 warning_at (tree_nonartificial_location (exp), 11478 0, "%Kcall to %D will always overflow destination buffer", 11479 exp, get_callee_fndecl (exp)); 11480 return NULL_RTX; 11481 } 11482 11483 fn = NULL_TREE; 11484 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume 11485 mem{cpy,pcpy,move,set} is available. */ 11486 switch (fcode) 11487 { 11488 case BUILT_IN_MEMCPY_CHK: 11489 fn = builtin_decl_explicit (BUILT_IN_MEMCPY); 11490 break; 11491 case BUILT_IN_MEMPCPY_CHK: 11492 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY); 11493 break; 11494 case BUILT_IN_MEMMOVE_CHK: 11495 fn = builtin_decl_explicit (BUILT_IN_MEMMOVE); 11496 break; 11497 case BUILT_IN_MEMSET_CHK: 11498 fn = builtin_decl_explicit (BUILT_IN_MEMSET); 11499 break; 11500 default: 11501 break; 11502 } 11503 11504 if (! fn) 11505 return NULL_RTX; 11506 11507 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 3, dest, src, len); 11508 gcc_assert (TREE_CODE (fn) == CALL_EXPR); 11509 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 11510 return expand_expr (fn, target, mode, EXPAND_NORMAL); 11511 } 11512 else if (fcode == BUILT_IN_MEMSET_CHK) 11513 return NULL_RTX; 11514 else 11515 { 11516 unsigned int dest_align = get_pointer_alignment (dest); 11517 11518 /* If DEST is not a pointer type, call the normal function. */ 11519 if (dest_align == 0) 11520 return NULL_RTX; 11521 11522 /* If SRC and DEST are the same (and not volatile), do nothing. */ 11523 if (operand_equal_p (src, dest, 0)) 11524 { 11525 tree expr; 11526 11527 if (fcode != BUILT_IN_MEMPCPY_CHK) 11528 { 11529 /* Evaluate and ignore LEN in case it has side-effects. */ 11530 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL); 11531 return expand_expr (dest, target, mode, EXPAND_NORMAL); 11532 } 11533 11534 expr = fold_build_pointer_plus (dest, len); 11535 return expand_expr (expr, target, mode, EXPAND_NORMAL); 11536 } 11537 11538 /* __memmove_chk special case. */ 11539 if (fcode == BUILT_IN_MEMMOVE_CHK) 11540 { 11541 unsigned int src_align = get_pointer_alignment (src); 11542 11543 if (src_align == 0) 11544 return NULL_RTX; 11545 11546 /* If src is categorized for a readonly section we can use 11547 normal __memcpy_chk. */ 11548 if (readonly_data_expr (src)) 11549 { 11550 tree fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK); 11551 if (!fn) 11552 return NULL_RTX; 11553 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 4, 11554 dest, src, len, size); 11555 gcc_assert (TREE_CODE (fn) == CALL_EXPR); 11556 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 11557 return expand_expr (fn, target, mode, EXPAND_NORMAL); 11558 } 11559 } 11560 return NULL_RTX; 11561 } 11562} 11563 11564/* Emit warning if a buffer overflow is detected at compile time. */ 11565 11566static void 11567maybe_emit_chk_warning (tree exp, enum built_in_function fcode) 11568{ 11569 int is_strlen = 0; 11570 tree len, size; 11571 location_t loc = tree_nonartificial_location (exp); 11572 11573 switch (fcode) 11574 { 11575 case BUILT_IN_STRCPY_CHK: 11576 case BUILT_IN_STPCPY_CHK: 11577 /* For __strcat_chk the warning will be emitted only if overflowing 11578 by at least strlen (dest) + 1 bytes. */ 11579 case BUILT_IN_STRCAT_CHK: 11580 len = CALL_EXPR_ARG (exp, 1); 11581 size = CALL_EXPR_ARG (exp, 2); 11582 is_strlen = 1; 11583 break; 11584 case BUILT_IN_STRNCAT_CHK: 11585 case BUILT_IN_STRNCPY_CHK: 11586 case BUILT_IN_STPNCPY_CHK: 11587 len = CALL_EXPR_ARG (exp, 2); 11588 size = CALL_EXPR_ARG (exp, 3); 11589 break; 11590 case BUILT_IN_SNPRINTF_CHK: 11591 case BUILT_IN_VSNPRINTF_CHK: 11592 len = CALL_EXPR_ARG (exp, 1); 11593 size = CALL_EXPR_ARG (exp, 3); 11594 break; 11595 default: 11596 gcc_unreachable (); 11597 } 11598 11599 if (!len || !size) 11600 return; 11601 11602 if (! tree_fits_uhwi_p (size) || integer_all_onesp (size)) 11603 return; 11604 11605 if (is_strlen) 11606 { 11607 len = c_strlen (len, 1); 11608 if (! len || ! tree_fits_uhwi_p (len) || tree_int_cst_lt (len, size)) 11609 return; 11610 } 11611 else if (fcode == BUILT_IN_STRNCAT_CHK) 11612 { 11613 tree src = CALL_EXPR_ARG (exp, 1); 11614 if (! src || ! tree_fits_uhwi_p (len) || tree_int_cst_lt (len, size)) 11615 return; 11616 src = c_strlen (src, 1); 11617 if (! src || ! tree_fits_uhwi_p (src)) 11618 { 11619 warning_at (loc, 0, "%Kcall to %D might overflow destination buffer", 11620 exp, get_callee_fndecl (exp)); 11621 return; 11622 } 11623 else if (tree_int_cst_lt (src, size)) 11624 return; 11625 } 11626 else if (! tree_fits_uhwi_p (len) || ! tree_int_cst_lt (size, len)) 11627 return; 11628 11629 warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer", 11630 exp, get_callee_fndecl (exp)); 11631} 11632 11633/* Emit warning if a buffer overflow is detected at compile time 11634 in __sprintf_chk/__vsprintf_chk calls. */ 11635 11636static void 11637maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode) 11638{ 11639 tree size, len, fmt; 11640 const char *fmt_str; 11641 int nargs = call_expr_nargs (exp); 11642 11643 /* Verify the required arguments in the original call. */ 11644 11645 if (nargs < 4) 11646 return; 11647 size = CALL_EXPR_ARG (exp, 2); 11648 fmt = CALL_EXPR_ARG (exp, 3); 11649 11650 if (! tree_fits_uhwi_p (size) || integer_all_onesp (size)) 11651 return; 11652 11653 /* Check whether the format is a literal string constant. */ 11654 fmt_str = c_getstr (fmt); 11655 if (fmt_str == NULL) 11656 return; 11657 11658 if (!init_target_chars ()) 11659 return; 11660 11661 /* If the format doesn't contain % args or %%, we know its size. */ 11662 if (strchr (fmt_str, target_percent) == 0) 11663 len = build_int_cstu (size_type_node, strlen (fmt_str)); 11664 /* If the format is "%s" and first ... argument is a string literal, 11665 we know it too. */ 11666 else if (fcode == BUILT_IN_SPRINTF_CHK 11667 && strcmp (fmt_str, target_percent_s) == 0) 11668 { 11669 tree arg; 11670 11671 if (nargs < 5) 11672 return; 11673 arg = CALL_EXPR_ARG (exp, 4); 11674 if (! POINTER_TYPE_P (TREE_TYPE (arg))) 11675 return; 11676 11677 len = c_strlen (arg, 1); 11678 if (!len || ! tree_fits_uhwi_p (len)) 11679 return; 11680 } 11681 else 11682 return; 11683 11684 if (! tree_int_cst_lt (len, size)) 11685 warning_at (tree_nonartificial_location (exp), 11686 0, "%Kcall to %D will always overflow destination buffer", 11687 exp, get_callee_fndecl (exp)); 11688} 11689 11690/* Emit warning if a free is called with address of a variable. */ 11691 11692static void 11693maybe_emit_free_warning (tree exp) 11694{ 11695 tree arg = CALL_EXPR_ARG (exp, 0); 11696 11697 STRIP_NOPS (arg); 11698 if (TREE_CODE (arg) != ADDR_EXPR) 11699 return; 11700 11701 arg = get_base_address (TREE_OPERAND (arg, 0)); 11702 if (arg == NULL || INDIRECT_REF_P (arg) || TREE_CODE (arg) == MEM_REF) 11703 return; 11704 11705 if (SSA_VAR_P (arg)) 11706 warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object, 11707 "%Kattempt to free a non-heap object %qD", exp, arg); 11708 else 11709 warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object, 11710 "%Kattempt to free a non-heap object", exp); 11711} 11712 11713/* Fold a call to __builtin_object_size with arguments PTR and OST, 11714 if possible. */ 11715 11716static tree 11717fold_builtin_object_size (tree ptr, tree ost) 11718{ 11719 unsigned HOST_WIDE_INT bytes; 11720 int object_size_type; 11721 11722 if (!validate_arg (ptr, POINTER_TYPE) 11723 || !validate_arg (ost, INTEGER_TYPE)) 11724 return NULL_TREE; 11725 11726 STRIP_NOPS (ost); 11727 11728 if (TREE_CODE (ost) != INTEGER_CST 11729 || tree_int_cst_sgn (ost) < 0 11730 || compare_tree_int (ost, 3) > 0) 11731 return NULL_TREE; 11732 11733 object_size_type = tree_to_shwi (ost); 11734 11735 /* __builtin_object_size doesn't evaluate side-effects in its arguments; 11736 if there are any side-effects, it returns (size_t) -1 for types 0 and 1 11737 and (size_t) 0 for types 2 and 3. */ 11738 if (TREE_SIDE_EFFECTS (ptr)) 11739 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0); 11740 11741 if (TREE_CODE (ptr) == ADDR_EXPR) 11742 { 11743 bytes = compute_builtin_object_size (ptr, object_size_type); 11744 if (wi::fits_to_tree_p (bytes, size_type_node)) 11745 return build_int_cstu (size_type_node, bytes); 11746 } 11747 else if (TREE_CODE (ptr) == SSA_NAME) 11748 { 11749 /* If object size is not known yet, delay folding until 11750 later. Maybe subsequent passes will help determining 11751 it. */ 11752 bytes = compute_builtin_object_size (ptr, object_size_type); 11753 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 ? -1 : 0) 11754 && wi::fits_to_tree_p (bytes, size_type_node)) 11755 return build_int_cstu (size_type_node, bytes); 11756 } 11757 11758 return NULL_TREE; 11759} 11760 11761/* Builtins with folding operations that operate on "..." arguments 11762 need special handling; we need to store the arguments in a convenient 11763 data structure before attempting any folding. Fortunately there are 11764 only a few builtins that fall into this category. FNDECL is the 11765 function, EXP is the CALL_EXPR for the call. */ 11766 11767static tree 11768fold_builtin_varargs (location_t loc, tree fndecl, tree *args, int nargs) 11769{ 11770 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 11771 tree ret = NULL_TREE; 11772 11773 switch (fcode) 11774 { 11775 case BUILT_IN_FPCLASSIFY: 11776 ret = fold_builtin_fpclassify (loc, args, nargs); 11777 break; 11778 11779 default: 11780 break; 11781 } 11782 if (ret) 11783 { 11784 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); 11785 SET_EXPR_LOCATION (ret, loc); 11786 TREE_NO_WARNING (ret) = 1; 11787 return ret; 11788 } 11789 return NULL_TREE; 11790} 11791 11792/* Initialize format string characters in the target charset. */ 11793 11794bool 11795init_target_chars (void) 11796{ 11797 static bool init; 11798 if (!init) 11799 { 11800 target_newline = lang_hooks.to_target_charset ('\n'); 11801 target_percent = lang_hooks.to_target_charset ('%'); 11802 target_c = lang_hooks.to_target_charset ('c'); 11803 target_s = lang_hooks.to_target_charset ('s'); 11804 if (target_newline == 0 || target_percent == 0 || target_c == 0 11805 || target_s == 0) 11806 return false; 11807 11808 target_percent_c[0] = target_percent; 11809 target_percent_c[1] = target_c; 11810 target_percent_c[2] = '\0'; 11811 11812 target_percent_s[0] = target_percent; 11813 target_percent_s[1] = target_s; 11814 target_percent_s[2] = '\0'; 11815 11816 target_percent_s_newline[0] = target_percent; 11817 target_percent_s_newline[1] = target_s; 11818 target_percent_s_newline[2] = target_newline; 11819 target_percent_s_newline[3] = '\0'; 11820 11821 init = true; 11822 } 11823 return true; 11824} 11825 11826/* Helper function for do_mpfr_arg*(). Ensure M is a normal number 11827 and no overflow/underflow occurred. INEXACT is true if M was not 11828 exactly calculated. TYPE is the tree type for the result. This 11829 function assumes that you cleared the MPFR flags and then 11830 calculated M to see if anything subsequently set a flag prior to 11831 entering this function. Return NULL_TREE if any checks fail. */ 11832 11833static tree 11834do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact) 11835{ 11836 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no 11837 overflow/underflow occurred. If -frounding-math, proceed iff the 11838 result of calling FUNC was exact. */ 11839 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p () 11840 && (!flag_rounding_math || !inexact)) 11841 { 11842 REAL_VALUE_TYPE rr; 11843 11844 real_from_mpfr (&rr, m, type, GMP_RNDN); 11845 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value, 11846 check for overflow/underflow. If the REAL_VALUE_TYPE is zero 11847 but the mpft_t is not, then we underflowed in the 11848 conversion. */ 11849 if (real_isfinite (&rr) 11850 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0)) 11851 { 11852 REAL_VALUE_TYPE rmode; 11853 11854 real_convert (&rmode, TYPE_MODE (type), &rr); 11855 /* Proceed iff the specified mode can hold the value. */ 11856 if (real_identical (&rmode, &rr)) 11857 return build_real (type, rmode); 11858 } 11859 } 11860 return NULL_TREE; 11861} 11862 11863/* Helper function for do_mpc_arg*(). Ensure M is a normal complex 11864 number and no overflow/underflow occurred. INEXACT is true if M 11865 was not exactly calculated. TYPE is the tree type for the result. 11866 This function assumes that you cleared the MPFR flags and then 11867 calculated M to see if anything subsequently set a flag prior to 11868 entering this function. Return NULL_TREE if any checks fail, if 11869 FORCE_CONVERT is true, then bypass the checks. */ 11870 11871static tree 11872do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert) 11873{ 11874 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no 11875 overflow/underflow occurred. If -frounding-math, proceed iff the 11876 result of calling FUNC was exact. */ 11877 if (force_convert 11878 || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m)) 11879 && !mpfr_overflow_p () && !mpfr_underflow_p () 11880 && (!flag_rounding_math || !inexact))) 11881 { 11882 REAL_VALUE_TYPE re, im; 11883 11884 real_from_mpfr (&re, mpc_realref (m), TREE_TYPE (type), GMP_RNDN); 11885 real_from_mpfr (&im, mpc_imagref (m), TREE_TYPE (type), GMP_RNDN); 11886 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values, 11887 check for overflow/underflow. If the REAL_VALUE_TYPE is zero 11888 but the mpft_t is not, then we underflowed in the 11889 conversion. */ 11890 if (force_convert 11891 || (real_isfinite (&re) && real_isfinite (&im) 11892 && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0) 11893 && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0))) 11894 { 11895 REAL_VALUE_TYPE re_mode, im_mode; 11896 11897 real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re); 11898 real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im); 11899 /* Proceed iff the specified mode can hold the value. */ 11900 if (force_convert 11901 || (real_identical (&re_mode, &re) 11902 && real_identical (&im_mode, &im))) 11903 return build_complex (type, build_real (TREE_TYPE (type), re_mode), 11904 build_real (TREE_TYPE (type), im_mode)); 11905 } 11906 } 11907 return NULL_TREE; 11908} 11909 11910/* If argument ARG is a REAL_CST, call the one-argument mpfr function 11911 FUNC on it and return the resulting value as a tree with type TYPE. 11912 If MIN and/or MAX are not NULL, then the supplied ARG must be 11913 within those bounds. If INCLUSIVE is true, then MIN/MAX are 11914 acceptable values, otherwise they are not. The mpfr precision is 11915 set to the precision of TYPE. We assume that function FUNC returns 11916 zero if the result could be calculated exactly within the requested 11917 precision. */ 11918 11919static tree 11920do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t), 11921 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max, 11922 bool inclusive) 11923{ 11924 tree result = NULL_TREE; 11925 11926 STRIP_NOPS (arg); 11927 11928 /* To proceed, MPFR must exactly represent the target floating point 11929 format, which only happens when the target base equals two. */ 11930 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 11931 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 11932 { 11933 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg); 11934 11935 if (real_isfinite (ra) 11936 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)) 11937 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max))) 11938 { 11939 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 11940 const int prec = fmt->p; 11941 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 11942 int inexact; 11943 mpfr_t m; 11944 11945 mpfr_init2 (m, prec); 11946 mpfr_from_real (m, ra, GMP_RNDN); 11947 mpfr_clear_flags (); 11948 inexact = func (m, m, rnd); 11949 result = do_mpfr_ckconv (m, type, inexact); 11950 mpfr_clear (m); 11951 } 11952 } 11953 11954 return result; 11955} 11956 11957/* If argument ARG is a REAL_CST, call the two-argument mpfr function 11958 FUNC on it and return the resulting value as a tree with type TYPE. 11959 The mpfr precision is set to the precision of TYPE. We assume that 11960 function FUNC returns zero if the result could be calculated 11961 exactly within the requested precision. */ 11962 11963static tree 11964do_mpfr_arg2 (tree arg1, tree arg2, tree type, 11965 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)) 11966{ 11967 tree result = NULL_TREE; 11968 11969 STRIP_NOPS (arg1); 11970 STRIP_NOPS (arg2); 11971 11972 /* To proceed, MPFR must exactly represent the target floating point 11973 format, which only happens when the target base equals two. */ 11974 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 11975 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1) 11976 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)) 11977 { 11978 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1); 11979 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2); 11980 11981 if (real_isfinite (ra1) && real_isfinite (ra2)) 11982 { 11983 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 11984 const int prec = fmt->p; 11985 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 11986 int inexact; 11987 mpfr_t m1, m2; 11988 11989 mpfr_inits2 (prec, m1, m2, NULL); 11990 mpfr_from_real (m1, ra1, GMP_RNDN); 11991 mpfr_from_real (m2, ra2, GMP_RNDN); 11992 mpfr_clear_flags (); 11993 inexact = func (m1, m1, m2, rnd); 11994 result = do_mpfr_ckconv (m1, type, inexact); 11995 mpfr_clears (m1, m2, NULL); 11996 } 11997 } 11998 11999 return result; 12000} 12001 12002/* If argument ARG is a REAL_CST, call the three-argument mpfr function 12003 FUNC on it and return the resulting value as a tree with type TYPE. 12004 The mpfr precision is set to the precision of TYPE. We assume that 12005 function FUNC returns zero if the result could be calculated 12006 exactly within the requested precision. */ 12007 12008static tree 12009do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type, 12010 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)) 12011{ 12012 tree result = NULL_TREE; 12013 12014 STRIP_NOPS (arg1); 12015 STRIP_NOPS (arg2); 12016 STRIP_NOPS (arg3); 12017 12018 /* To proceed, MPFR must exactly represent the target floating point 12019 format, which only happens when the target base equals two. */ 12020 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 12021 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1) 12022 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2) 12023 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3)) 12024 { 12025 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1); 12026 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2); 12027 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3); 12028 12029 if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3)) 12030 { 12031 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 12032 const int prec = fmt->p; 12033 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 12034 int inexact; 12035 mpfr_t m1, m2, m3; 12036 12037 mpfr_inits2 (prec, m1, m2, m3, NULL); 12038 mpfr_from_real (m1, ra1, GMP_RNDN); 12039 mpfr_from_real (m2, ra2, GMP_RNDN); 12040 mpfr_from_real (m3, ra3, GMP_RNDN); 12041 mpfr_clear_flags (); 12042 inexact = func (m1, m1, m2, m3, rnd); 12043 result = do_mpfr_ckconv (m1, type, inexact); 12044 mpfr_clears (m1, m2, m3, NULL); 12045 } 12046 } 12047 12048 return result; 12049} 12050 12051/* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set 12052 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values. 12053 If ARG_SINP and ARG_COSP are NULL then the result is returned 12054 as a complex value. 12055 The type is taken from the type of ARG and is used for setting the 12056 precision of the calculation and results. */ 12057 12058static tree 12059do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp) 12060{ 12061 tree const type = TREE_TYPE (arg); 12062 tree result = NULL_TREE; 12063 12064 STRIP_NOPS (arg); 12065 12066 /* To proceed, MPFR must exactly represent the target floating point 12067 format, which only happens when the target base equals two. */ 12068 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 12069 && TREE_CODE (arg) == REAL_CST 12070 && !TREE_OVERFLOW (arg)) 12071 { 12072 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg); 12073 12074 if (real_isfinite (ra)) 12075 { 12076 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 12077 const int prec = fmt->p; 12078 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 12079 tree result_s, result_c; 12080 int inexact; 12081 mpfr_t m, ms, mc; 12082 12083 mpfr_inits2 (prec, m, ms, mc, NULL); 12084 mpfr_from_real (m, ra, GMP_RNDN); 12085 mpfr_clear_flags (); 12086 inexact = mpfr_sin_cos (ms, mc, m, rnd); 12087 result_s = do_mpfr_ckconv (ms, type, inexact); 12088 result_c = do_mpfr_ckconv (mc, type, inexact); 12089 mpfr_clears (m, ms, mc, NULL); 12090 if (result_s && result_c) 12091 { 12092 /* If we are to return in a complex value do so. */ 12093 if (!arg_sinp && !arg_cosp) 12094 return build_complex (build_complex_type (type), 12095 result_c, result_s); 12096 12097 /* Dereference the sin/cos pointer arguments. */ 12098 arg_sinp = build_fold_indirect_ref (arg_sinp); 12099 arg_cosp = build_fold_indirect_ref (arg_cosp); 12100 /* Proceed if valid pointer type were passed in. */ 12101 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type) 12102 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type)) 12103 { 12104 /* Set the values. */ 12105 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp, 12106 result_s); 12107 TREE_SIDE_EFFECTS (result_s) = 1; 12108 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp, 12109 result_c); 12110 TREE_SIDE_EFFECTS (result_c) = 1; 12111 /* Combine the assignments into a compound expr. */ 12112 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type, 12113 result_s, result_c)); 12114 } 12115 } 12116 } 12117 } 12118 return result; 12119} 12120 12121/* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the 12122 two-argument mpfr order N Bessel function FUNC on them and return 12123 the resulting value as a tree with type TYPE. The mpfr precision 12124 is set to the precision of TYPE. We assume that function FUNC 12125 returns zero if the result could be calculated exactly within the 12126 requested precision. */ 12127static tree 12128do_mpfr_bessel_n (tree arg1, tree arg2, tree type, 12129 int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t), 12130 const REAL_VALUE_TYPE *min, bool inclusive) 12131{ 12132 tree result = NULL_TREE; 12133 12134 STRIP_NOPS (arg1); 12135 STRIP_NOPS (arg2); 12136 12137 /* To proceed, MPFR must exactly represent the target floating point 12138 format, which only happens when the target base equals two. */ 12139 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 12140 && tree_fits_shwi_p (arg1) 12141 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)) 12142 { 12143 const HOST_WIDE_INT n = tree_to_shwi (arg1); 12144 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2); 12145 12146 if (n == (long)n 12147 && real_isfinite (ra) 12148 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))) 12149 { 12150 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 12151 const int prec = fmt->p; 12152 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 12153 int inexact; 12154 mpfr_t m; 12155 12156 mpfr_init2 (m, prec); 12157 mpfr_from_real (m, ra, GMP_RNDN); 12158 mpfr_clear_flags (); 12159 inexact = func (m, n, m, rnd); 12160 result = do_mpfr_ckconv (m, type, inexact); 12161 mpfr_clear (m); 12162 } 12163 } 12164 12165 return result; 12166} 12167 12168/* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set 12169 the pointer *(ARG_QUO) and return the result. The type is taken 12170 from the type of ARG0 and is used for setting the precision of the 12171 calculation and results. */ 12172 12173static tree 12174do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo) 12175{ 12176 tree const type = TREE_TYPE (arg0); 12177 tree result = NULL_TREE; 12178 12179 STRIP_NOPS (arg0); 12180 STRIP_NOPS (arg1); 12181 12182 /* To proceed, MPFR must exactly represent the target floating point 12183 format, which only happens when the target base equals two. */ 12184 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 12185 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0) 12186 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)) 12187 { 12188 const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0); 12189 const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1); 12190 12191 if (real_isfinite (ra0) && real_isfinite (ra1)) 12192 { 12193 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 12194 const int prec = fmt->p; 12195 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 12196 tree result_rem; 12197 long integer_quo; 12198 mpfr_t m0, m1; 12199 12200 mpfr_inits2 (prec, m0, m1, NULL); 12201 mpfr_from_real (m0, ra0, GMP_RNDN); 12202 mpfr_from_real (m1, ra1, GMP_RNDN); 12203 mpfr_clear_flags (); 12204 mpfr_remquo (m0, &integer_quo, m0, m1, rnd); 12205 /* Remquo is independent of the rounding mode, so pass 12206 inexact=0 to do_mpfr_ckconv(). */ 12207 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0); 12208 mpfr_clears (m0, m1, NULL); 12209 if (result_rem) 12210 { 12211 /* MPFR calculates quo in the host's long so it may 12212 return more bits in quo than the target int can hold 12213 if sizeof(host long) > sizeof(target int). This can 12214 happen even for native compilers in LP64 mode. In 12215 these cases, modulo the quo value with the largest 12216 number that the target int can hold while leaving one 12217 bit for the sign. */ 12218 if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE) 12219 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1)); 12220 12221 /* Dereference the quo pointer argument. */ 12222 arg_quo = build_fold_indirect_ref (arg_quo); 12223 /* Proceed iff a valid pointer type was passed in. */ 12224 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node) 12225 { 12226 /* Set the value. */ 12227 tree result_quo 12228 = fold_build2 (MODIFY_EXPR, TREE_TYPE (arg_quo), arg_quo, 12229 build_int_cst (TREE_TYPE (arg_quo), 12230 integer_quo)); 12231 TREE_SIDE_EFFECTS (result_quo) = 1; 12232 /* Combine the quo assignment with the rem. */ 12233 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type, 12234 result_quo, result_rem)); 12235 } 12236 } 12237 } 12238 } 12239 return result; 12240} 12241 12242/* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the 12243 resulting value as a tree with type TYPE. The mpfr precision is 12244 set to the precision of TYPE. We assume that this mpfr function 12245 returns zero if the result could be calculated exactly within the 12246 requested precision. In addition, the integer pointer represented 12247 by ARG_SG will be dereferenced and set to the appropriate signgam 12248 (-1,1) value. */ 12249 12250static tree 12251do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type) 12252{ 12253 tree result = NULL_TREE; 12254 12255 STRIP_NOPS (arg); 12256 12257 /* To proceed, MPFR must exactly represent the target floating point 12258 format, which only happens when the target base equals two. Also 12259 verify ARG is a constant and that ARG_SG is an int pointer. */ 12260 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 12261 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg) 12262 && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE 12263 && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node) 12264 { 12265 const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg); 12266 12267 /* In addition to NaN and Inf, the argument cannot be zero or a 12268 negative integer. */ 12269 if (real_isfinite (ra) 12270 && ra->cl != rvc_zero 12271 && !(real_isneg (ra) && real_isinteger (ra, TYPE_MODE (type)))) 12272 { 12273 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 12274 const int prec = fmt->p; 12275 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 12276 int inexact, sg; 12277 mpfr_t m; 12278 tree result_lg; 12279 12280 mpfr_init2 (m, prec); 12281 mpfr_from_real (m, ra, GMP_RNDN); 12282 mpfr_clear_flags (); 12283 inexact = mpfr_lgamma (m, &sg, m, rnd); 12284 result_lg = do_mpfr_ckconv (m, type, inexact); 12285 mpfr_clear (m); 12286 if (result_lg) 12287 { 12288 tree result_sg; 12289 12290 /* Dereference the arg_sg pointer argument. */ 12291 arg_sg = build_fold_indirect_ref (arg_sg); 12292 /* Assign the signgam value into *arg_sg. */ 12293 result_sg = fold_build2 (MODIFY_EXPR, 12294 TREE_TYPE (arg_sg), arg_sg, 12295 build_int_cst (TREE_TYPE (arg_sg), sg)); 12296 TREE_SIDE_EFFECTS (result_sg) = 1; 12297 /* Combine the signgam assignment with the lgamma result. */ 12298 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type, 12299 result_sg, result_lg)); 12300 } 12301 } 12302 } 12303 12304 return result; 12305} 12306 12307/* If argument ARG is a COMPLEX_CST, call the one-argument mpc 12308 function FUNC on it and return the resulting value as a tree with 12309 type TYPE. The mpfr precision is set to the precision of TYPE. We 12310 assume that function FUNC returns zero if the result could be 12311 calculated exactly within the requested precision. */ 12312 12313static tree 12314do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t)) 12315{ 12316 tree result = NULL_TREE; 12317 12318 STRIP_NOPS (arg); 12319 12320 /* To proceed, MPFR must exactly represent the target floating point 12321 format, which only happens when the target base equals two. */ 12322 if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg) 12323 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE 12324 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2) 12325 { 12326 const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg)); 12327 const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg)); 12328 12329 if (real_isfinite (re) && real_isfinite (im)) 12330 { 12331 const struct real_format *const fmt = 12332 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type))); 12333 const int prec = fmt->p; 12334 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN; 12335 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN; 12336 int inexact; 12337 mpc_t m; 12338 12339 mpc_init2 (m, prec); 12340 mpfr_from_real (mpc_realref (m), re, rnd); 12341 mpfr_from_real (mpc_imagref (m), im, rnd); 12342 mpfr_clear_flags (); 12343 inexact = func (m, m, crnd); 12344 result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0); 12345 mpc_clear (m); 12346 } 12347 } 12348 12349 return result; 12350} 12351 12352/* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument 12353 mpc function FUNC on it and return the resulting value as a tree 12354 with type TYPE. The mpfr precision is set to the precision of 12355 TYPE. We assume that function FUNC returns zero if the result 12356 could be calculated exactly within the requested precision. If 12357 DO_NONFINITE is true, then fold expressions containing Inf or NaN 12358 in the arguments and/or results. */ 12359 12360tree 12361do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite, 12362 int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t)) 12363{ 12364 tree result = NULL_TREE; 12365 12366 STRIP_NOPS (arg0); 12367 STRIP_NOPS (arg1); 12368 12369 /* To proceed, MPFR must exactly represent the target floating point 12370 format, which only happens when the target base equals two. */ 12371 if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0) 12372 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE 12373 && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1) 12374 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE 12375 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2) 12376 { 12377 const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0)); 12378 const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0)); 12379 const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1)); 12380 const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1)); 12381 12382 if (do_nonfinite 12383 || (real_isfinite (re0) && real_isfinite (im0) 12384 && real_isfinite (re1) && real_isfinite (im1))) 12385 { 12386 const struct real_format *const fmt = 12387 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type))); 12388 const int prec = fmt->p; 12389 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN; 12390 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN; 12391 int inexact; 12392 mpc_t m0, m1; 12393 12394 mpc_init2 (m0, prec); 12395 mpc_init2 (m1, prec); 12396 mpfr_from_real (mpc_realref (m0), re0, rnd); 12397 mpfr_from_real (mpc_imagref (m0), im0, rnd); 12398 mpfr_from_real (mpc_realref (m1), re1, rnd); 12399 mpfr_from_real (mpc_imagref (m1), im1, rnd); 12400 mpfr_clear_flags (); 12401 inexact = func (m0, m0, m1, crnd); 12402 result = do_mpc_ckconv (m0, type, inexact, do_nonfinite); 12403 mpc_clear (m0); 12404 mpc_clear (m1); 12405 } 12406 } 12407 12408 return result; 12409} 12410 12411/* A wrapper function for builtin folding that prevents warnings for 12412 "statement without effect" and the like, caused by removing the 12413 call node earlier than the warning is generated. */ 12414 12415tree 12416fold_call_stmt (gcall *stmt, bool ignore) 12417{ 12418 tree ret = NULL_TREE; 12419 tree fndecl = gimple_call_fndecl (stmt); 12420 location_t loc = gimple_location (stmt); 12421 if (fndecl 12422 && TREE_CODE (fndecl) == FUNCTION_DECL 12423 && DECL_BUILT_IN (fndecl) 12424 && !gimple_call_va_arg_pack_p (stmt)) 12425 { 12426 int nargs = gimple_call_num_args (stmt); 12427 tree *args = (nargs > 0 12428 ? gimple_call_arg_ptr (stmt, 0) 12429 : &error_mark_node); 12430 12431 if (avoid_folding_inline_builtin (fndecl)) 12432 return NULL_TREE; 12433 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 12434 { 12435 return targetm.fold_builtin (fndecl, nargs, args, ignore); 12436 } 12437 else 12438 { 12439 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore); 12440 if (ret) 12441 { 12442 /* Propagate location information from original call to 12443 expansion of builtin. Otherwise things like 12444 maybe_emit_chk_warning, that operate on the expansion 12445 of a builtin, will use the wrong location information. */ 12446 if (gimple_has_location (stmt)) 12447 { 12448 tree realret = ret; 12449 if (TREE_CODE (ret) == NOP_EXPR) 12450 realret = TREE_OPERAND (ret, 0); 12451 if (CAN_HAVE_LOCATION_P (realret) 12452 && !EXPR_HAS_LOCATION (realret)) 12453 SET_EXPR_LOCATION (realret, loc); 12454 return realret; 12455 } 12456 return ret; 12457 } 12458 } 12459 } 12460 return NULL_TREE; 12461} 12462 12463/* Look up the function in builtin_decl that corresponds to DECL 12464 and set ASMSPEC as its user assembler name. DECL must be a 12465 function decl that declares a builtin. */ 12466 12467void 12468set_builtin_user_assembler_name (tree decl, const char *asmspec) 12469{ 12470 tree builtin; 12471 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL 12472 && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL 12473 && asmspec != 0); 12474 12475 builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl)); 12476 set_user_assembler_name (builtin, asmspec); 12477 switch (DECL_FUNCTION_CODE (decl)) 12478 { 12479 case BUILT_IN_MEMCPY: 12480 init_block_move_fn (asmspec); 12481 memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec); 12482 break; 12483 case BUILT_IN_MEMSET: 12484 init_block_clear_fn (asmspec); 12485 memset_libfunc = set_user_assembler_libfunc ("memset", asmspec); 12486 break; 12487 case BUILT_IN_MEMMOVE: 12488 memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec); 12489 break; 12490 case BUILT_IN_MEMCMP: 12491 memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec); 12492 break; 12493 case BUILT_IN_ABORT: 12494 abort_libfunc = set_user_assembler_libfunc ("abort", asmspec); 12495 break; 12496 case BUILT_IN_FFS: 12497 if (INT_TYPE_SIZE < BITS_PER_WORD) 12498 { 12499 set_user_assembler_libfunc ("ffs", asmspec); 12500 set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, 12501 MODE_INT, 0), "ffs"); 12502 } 12503 break; 12504 default: 12505 break; 12506 } 12507} 12508 12509/* Return true if DECL is a builtin that expands to a constant or similarly 12510 simple code. */ 12511bool 12512is_simple_builtin (tree decl) 12513{ 12514 if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) 12515 switch (DECL_FUNCTION_CODE (decl)) 12516 { 12517 /* Builtins that expand to constants. */ 12518 case BUILT_IN_CONSTANT_P: 12519 case BUILT_IN_EXPECT: 12520 case BUILT_IN_OBJECT_SIZE: 12521 case BUILT_IN_UNREACHABLE: 12522 /* Simple register moves or loads from stack. */ 12523 case BUILT_IN_ASSUME_ALIGNED: 12524 case BUILT_IN_RETURN_ADDRESS: 12525 case BUILT_IN_EXTRACT_RETURN_ADDR: 12526 case BUILT_IN_FROB_RETURN_ADDR: 12527 case BUILT_IN_RETURN: 12528 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: 12529 case BUILT_IN_FRAME_ADDRESS: 12530 case BUILT_IN_VA_END: 12531 case BUILT_IN_STACK_SAVE: 12532 case BUILT_IN_STACK_RESTORE: 12533 /* Exception state returns or moves registers around. */ 12534 case BUILT_IN_EH_FILTER: 12535 case BUILT_IN_EH_POINTER: 12536 case BUILT_IN_EH_COPY_VALUES: 12537 return true; 12538 12539 default: 12540 return false; 12541 } 12542 12543 return false; 12544} 12545 12546/* Return true if DECL is a builtin that is not expensive, i.e., they are 12547 most probably expanded inline into reasonably simple code. This is a 12548 superset of is_simple_builtin. */ 12549bool 12550is_inexpensive_builtin (tree decl) 12551{ 12552 if (!decl) 12553 return false; 12554 else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD) 12555 return true; 12556 else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) 12557 switch (DECL_FUNCTION_CODE (decl)) 12558 { 12559 case BUILT_IN_ABS: 12560 case BUILT_IN_ALLOCA: 12561 case BUILT_IN_ALLOCA_WITH_ALIGN: 12562 case BUILT_IN_BSWAP16: 12563 case BUILT_IN_BSWAP32: 12564 case BUILT_IN_BSWAP64: 12565 case BUILT_IN_CLZ: 12566 case BUILT_IN_CLZIMAX: 12567 case BUILT_IN_CLZL: 12568 case BUILT_IN_CLZLL: 12569 case BUILT_IN_CTZ: 12570 case BUILT_IN_CTZIMAX: 12571 case BUILT_IN_CTZL: 12572 case BUILT_IN_CTZLL: 12573 case BUILT_IN_FFS: 12574 case BUILT_IN_FFSIMAX: 12575 case BUILT_IN_FFSL: 12576 case BUILT_IN_FFSLL: 12577 case BUILT_IN_IMAXABS: 12578 case BUILT_IN_FINITE: 12579 case BUILT_IN_FINITEF: 12580 case BUILT_IN_FINITEL: 12581 case BUILT_IN_FINITED32: 12582 case BUILT_IN_FINITED64: 12583 case BUILT_IN_FINITED128: 12584 case BUILT_IN_FPCLASSIFY: 12585 case BUILT_IN_ISFINITE: 12586 case BUILT_IN_ISINF_SIGN: 12587 case BUILT_IN_ISINF: 12588 case BUILT_IN_ISINFF: 12589 case BUILT_IN_ISINFL: 12590 case BUILT_IN_ISINFD32: 12591 case BUILT_IN_ISINFD64: 12592 case BUILT_IN_ISINFD128: 12593 case BUILT_IN_ISNAN: 12594 case BUILT_IN_ISNANF: 12595 case BUILT_IN_ISNANL: 12596 case BUILT_IN_ISNAND32: 12597 case BUILT_IN_ISNAND64: 12598 case BUILT_IN_ISNAND128: 12599 case BUILT_IN_ISNORMAL: 12600 case BUILT_IN_ISGREATER: 12601 case BUILT_IN_ISGREATEREQUAL: 12602 case BUILT_IN_ISLESS: 12603 case BUILT_IN_ISLESSEQUAL: 12604 case BUILT_IN_ISLESSGREATER: 12605 case BUILT_IN_ISUNORDERED: 12606 case BUILT_IN_VA_ARG_PACK: 12607 case BUILT_IN_VA_ARG_PACK_LEN: 12608 case BUILT_IN_VA_COPY: 12609 case BUILT_IN_TRAP: 12610 case BUILT_IN_SAVEREGS: 12611 case BUILT_IN_POPCOUNTL: 12612 case BUILT_IN_POPCOUNTLL: 12613 case BUILT_IN_POPCOUNTIMAX: 12614 case BUILT_IN_POPCOUNT: 12615 case BUILT_IN_PARITYL: 12616 case BUILT_IN_PARITYLL: 12617 case BUILT_IN_PARITYIMAX: 12618 case BUILT_IN_PARITY: 12619 case BUILT_IN_LABS: 12620 case BUILT_IN_LLABS: 12621 case BUILT_IN_PREFETCH: 12622 case BUILT_IN_ACC_ON_DEVICE: 12623 return true; 12624 12625 default: 12626 return is_simple_builtin (decl); 12627 } 12628 12629 return false; 12630} 12631