1 /* Expand builtin functions. 2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 4 Free Software Foundation, Inc. 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free 10 Software Foundation; either version 3, or (at your option) any later 11 version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GCC; see the file COPYING3. If not see 20 <http://www.gnu.org/licenses/>. */ 21 22 #include "config.h" 23 #include "system.h" 24 #include "coretypes.h" 25 #include "tm.h" 26 #include "machmode.h" 27 #include "real.h" 28 #include "rtl.h" 29 #include "tree.h" 30 #include "gimple.h" 31 #include "flags.h" 32 #include "regs.h" 33 #include "hard-reg-set.h" 34 #include "except.h" 35 #include "function.h" 36 #include "insn-config.h" 37 #include "expr.h" 38 #include "optabs.h" 39 #include "libfuncs.h" 40 #include "recog.h" 41 #include "output.h" 42 #include "typeclass.h" 43 #include "toplev.h" 44 #include "predict.h" 45 #include "tm_p.h" 46 #include "target.h" 47 #include "langhooks.h" 48 #include "basic-block.h" 49 #include "tree-mudflap.h" 50 #include "tree-flow.h" 51 #include "value-prof.h" 52 #include "diagnostic.h" 53 54 #ifndef SLOW_UNALIGNED_ACCESS 55 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT 56 #endif 57 58 #ifndef PAD_VARARGS_DOWN 59 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN 60 #endif 61 static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t)); 62 63 /* Define the names of the builtin function types and codes. */ 64 const char *const built_in_class_names[4] 65 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"}; 66 67 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X, 68 const char * built_in_names[(int) END_BUILTINS] = 69 { 70 #include "builtins.def" 71 }; 72 #undef DEF_BUILTIN 73 74 /* Setup an array of _DECL trees, make sure each element is 75 initialized to NULL_TREE. */ 76 tree built_in_decls[(int) END_BUILTINS]; 77 /* Declarations used when constructing the builtin implicitly in the compiler. 78 It may be NULL_TREE when this is invalid (for instance runtime is not 79 required to implement the function call in all cases). */ 80 tree implicit_built_in_decls[(int) END_BUILTINS]; 81 82 static const char *c_getstr (tree); 83 static rtx c_readstr (const char *, enum machine_mode); 84 static int target_char_cast (tree, char *); 85 static rtx get_memory_rtx (tree, tree); 86 static int apply_args_size (void); 87 static int apply_result_size (void); 88 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return) 89 static rtx result_vector (int, rtx); 90 #endif 91 static void expand_builtin_update_setjmp_buf (rtx); 92 static void expand_builtin_prefetch (tree); 93 static rtx expand_builtin_apply_args (void); 94 static rtx expand_builtin_apply_args_1 (void); 95 static rtx expand_builtin_apply (rtx, rtx, rtx); 96 static void expand_builtin_return (rtx); 97 static enum type_class type_to_class (tree); 98 static rtx expand_builtin_classify_type (tree); 99 static void expand_errno_check (tree, rtx); 100 static rtx expand_builtin_mathfn (tree, rtx, rtx); 101 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx); 102 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx); 103 static rtx expand_builtin_interclass_mathfn (tree, rtx); 104 static rtx expand_builtin_sincos (tree); 105 static rtx expand_builtin_cexpi (tree, rtx); 106 static rtx expand_builtin_int_roundingfn (tree, rtx); 107 static rtx expand_builtin_int_roundingfn_2 (tree, rtx); 108 static rtx expand_builtin_args_info (tree); 109 static rtx expand_builtin_next_arg (void); 110 static rtx expand_builtin_va_start (tree); 111 static rtx expand_builtin_va_end (tree); 112 static rtx expand_builtin_va_copy (tree); 113 static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode); 114 static rtx expand_builtin_strcmp (tree, rtx); 115 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode); 116 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode); 117 static rtx expand_builtin_memcpy (tree, rtx); 118 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode); 119 static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, 120 enum machine_mode, int); 121 static rtx expand_builtin_strcpy (tree, rtx); 122 static rtx expand_builtin_strcpy_args (tree, tree, rtx); 123 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode); 124 static rtx expand_builtin_strncpy (tree, rtx); 125 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode); 126 static rtx expand_builtin_memset (tree, rtx, enum machine_mode); 127 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree); 128 static rtx expand_builtin_bzero (tree); 129 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode); 130 static rtx expand_builtin_alloca (tree, rtx); 131 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab); 132 static rtx expand_builtin_frame_address (tree, tree); 133 static tree stabilize_va_list_loc (location_t, tree, int); 134 static rtx expand_builtin_expect (tree, rtx); 135 static tree fold_builtin_constant_p (tree); 136 static tree fold_builtin_expect (location_t, tree, tree); 137 static tree fold_builtin_classify_type (tree); 138 static tree fold_builtin_strlen (location_t, tree, tree); 139 static tree fold_builtin_inf (location_t, tree, int); 140 static tree fold_builtin_nan (tree, tree, int); 141 static tree rewrite_call_expr (location_t, tree, int, tree, int, ...); 142 static bool validate_arg (const_tree, enum tree_code code); 143 static bool integer_valued_real_p (tree); 144 static tree fold_trunc_transparent_mathfn (location_t, tree, tree); 145 static bool readonly_data_expr (tree); 146 static rtx expand_builtin_fabs (tree, rtx, rtx); 147 static rtx expand_builtin_signbit (tree, rtx); 148 static tree fold_builtin_sqrt (location_t, tree, tree); 149 static tree fold_builtin_cbrt (location_t, tree, tree); 150 static tree fold_builtin_pow (location_t, tree, tree, tree, tree); 151 static tree fold_builtin_powi (location_t, tree, tree, tree, tree); 152 static tree fold_builtin_cos (location_t, tree, tree, tree); 153 static tree fold_builtin_cosh (location_t, tree, tree, tree); 154 static tree fold_builtin_tan (tree, tree); 155 static tree fold_builtin_trunc (location_t, tree, tree); 156 static tree fold_builtin_floor (location_t, tree, tree); 157 static tree fold_builtin_ceil (location_t, tree, tree); 158 static tree fold_builtin_round (location_t, tree, tree); 159 static tree fold_builtin_int_roundingfn (location_t, tree, tree); 160 static tree fold_builtin_bitop (tree, tree); 161 static tree fold_builtin_memory_op (location_t, tree, tree, tree, tree, bool, int); 162 static tree fold_builtin_strchr (location_t, tree, tree, tree); 163 static tree fold_builtin_memchr (location_t, tree, tree, tree, tree); 164 static tree fold_builtin_memcmp (location_t, tree, tree, tree); 165 static tree fold_builtin_strcmp (location_t, tree, tree); 166 static tree fold_builtin_strncmp (location_t, tree, tree, tree); 167 static tree fold_builtin_signbit (location_t, tree, tree); 168 static tree fold_builtin_copysign (location_t, tree, tree, tree, tree); 169 static tree fold_builtin_isascii (location_t, tree); 170 static tree fold_builtin_toascii (location_t, tree); 171 static tree fold_builtin_isdigit (location_t, tree); 172 static tree fold_builtin_fabs (location_t, tree, tree); 173 static tree fold_builtin_abs (location_t, tree, tree); 174 static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code, 175 enum tree_code); 176 static tree fold_builtin_n (location_t, tree, tree *, int, bool); 177 static tree fold_builtin_0 (location_t, tree, bool); 178 static tree fold_builtin_1 (location_t, tree, tree, bool); 179 static tree fold_builtin_2 (location_t, tree, tree, tree, bool); 180 static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool); 181 static tree fold_builtin_4 (location_t, tree, tree, tree, tree, tree, bool); 182 static tree fold_builtin_varargs (location_t, tree, tree, bool); 183 184 static tree fold_builtin_strpbrk (location_t, tree, tree, tree); 185 static tree fold_builtin_strstr (location_t, tree, tree, tree); 186 static tree fold_builtin_strrchr (location_t, tree, tree, tree); 187 static tree fold_builtin_strcat (location_t, tree, tree); 188 static tree fold_builtin_strncat (location_t, tree, tree, tree); 189 static tree fold_builtin_strspn (location_t, tree, tree); 190 static tree fold_builtin_strcspn (location_t, tree, tree); 191 static tree fold_builtin_sprintf (location_t, tree, tree, tree, int); 192 193 static rtx expand_builtin_object_size (tree); 194 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode, 195 enum built_in_function); 196 static void maybe_emit_chk_warning (tree, enum built_in_function); 197 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function); 198 static void maybe_emit_free_warning (tree); 199 static tree fold_builtin_object_size (tree, tree); 200 static tree fold_builtin_strcat_chk (location_t, tree, tree, tree, tree); 201 static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree); 202 static tree fold_builtin_sprintf_chk (location_t, tree, enum built_in_function); 203 static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function); 204 static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool, 205 enum built_in_function); 206 static bool init_target_chars (void); 207 208 static unsigned HOST_WIDE_INT target_newline; 209 static unsigned HOST_WIDE_INT target_percent; 210 static unsigned HOST_WIDE_INT target_c; 211 static unsigned HOST_WIDE_INT target_s; 212 static char target_percent_c[3]; 213 static char target_percent_s[3]; 214 static char target_percent_s_newline[4]; 215 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t), 216 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool); 217 static tree do_mpfr_arg2 (tree, tree, tree, 218 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); 219 static tree do_mpfr_arg3 (tree, tree, tree, tree, 220 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); 221 static tree do_mpfr_sincos (tree, tree, tree); 222 static tree do_mpfr_bessel_n (tree, tree, tree, 223 int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t), 224 const REAL_VALUE_TYPE *, bool); 225 static tree do_mpfr_remquo (tree, tree, tree); 226 static tree do_mpfr_lgamma_r (tree, tree, tree); 227 228 /* Return true if NAME starts with __builtin_ or __sync_. */ 229 230 bool 231 is_builtin_name (const char *name) 232 { 233 if (strncmp (name, "__builtin_", 10) == 0) 234 return true; 235 if (strncmp (name, "__sync_", 7) == 0) 236 return true; 237 return false; 238 } 239 240 241 /* Return true if DECL is a function symbol representing a built-in. */ 242 243 bool 244 is_builtin_fn (tree decl) 245 { 246 return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl); 247 } 248 249 250 /* Return true if NODE should be considered for inline expansion regardless 251 of the optimization level. This means whenever a function is invoked with 252 its "internal" name, which normally contains the prefix "__builtin". */ 253 254 static bool 255 called_as_built_in (tree node) 256 { 257 /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since 258 we want the name used to call the function, not the name it 259 will have. */ 260 const char *name = IDENTIFIER_POINTER (DECL_NAME (node)); 261 return is_builtin_name (name); 262 } 263 264 /* Return the alignment in bits of EXP, an object. 265 Don't return more than MAX_ALIGN no matter what, ALIGN is the inital 266 guessed alignment e.g. from type alignment. */ 267 268 int 269 get_object_alignment (tree exp, unsigned int align, unsigned int max_align) 270 { 271 unsigned int inner; 272 273 inner = max_align; 274 if (handled_component_p (exp)) 275 { 276 HOST_WIDE_INT bitsize, bitpos; 277 tree offset; 278 enum machine_mode mode; 279 int unsignedp, volatilep; 280 281 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset, 282 &mode, &unsignedp, &volatilep, true); 283 if (bitpos) 284 inner = MIN (inner, (unsigned) (bitpos & -bitpos)); 285 while (offset) 286 { 287 tree next_offset; 288 289 if (TREE_CODE (offset) == PLUS_EXPR) 290 { 291 next_offset = TREE_OPERAND (offset, 0); 292 offset = TREE_OPERAND (offset, 1); 293 } 294 else 295 next_offset = NULL; 296 if (host_integerp (offset, 1)) 297 { 298 /* Any overflow in calculating offset_bits won't change 299 the alignment. */ 300 unsigned offset_bits 301 = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT); 302 303 if (offset_bits) 304 inner = MIN (inner, (offset_bits & -offset_bits)); 305 } 306 else if (TREE_CODE (offset) == MULT_EXPR 307 && host_integerp (TREE_OPERAND (offset, 1), 1)) 308 { 309 /* Any overflow in calculating offset_factor won't change 310 the alignment. */ 311 unsigned offset_factor 312 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1) 313 * BITS_PER_UNIT); 314 315 if (offset_factor) 316 inner = MIN (inner, (offset_factor & -offset_factor)); 317 } 318 else 319 { 320 inner = MIN (inner, BITS_PER_UNIT); 321 break; 322 } 323 offset = next_offset; 324 } 325 } 326 if (TREE_CODE (exp) == CONST_DECL) 327 exp = DECL_INITIAL (exp); 328 if (DECL_P (exp) 329 && TREE_CODE (exp) != LABEL_DECL) 330 align = MIN (inner, DECL_ALIGN (exp)); 331 #ifdef CONSTANT_ALIGNMENT 332 else if (CONSTANT_CLASS_P (exp)) 333 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align)); 334 #endif 335 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR 336 || TREE_CODE (exp) == INDIRECT_REF) 337 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner); 338 else 339 align = MIN (align, inner); 340 return MIN (align, max_align); 341 } 342 343 /* Returns true iff we can trust that alignment information has been 344 calculated properly. */ 345 346 bool 347 can_trust_pointer_alignment (void) 348 { 349 /* We rely on TER to compute accurate alignment information. */ 350 return (!STRICT_ALIGNMENT && optimize && flag_tree_ter); 351 } 352 353 /* Return the alignment in bits of EXP, a pointer valued expression. 354 But don't return more than MAX_ALIGN no matter what. 355 The alignment returned is, by default, the alignment of the thing that 356 EXP points to. If it is not a POINTER_TYPE, 0 is returned. 357 358 Otherwise, look at the expression to see if we can do better, i.e., if the 359 expression is actually pointing at an object whose alignment is tighter. */ 360 361 int 362 get_pointer_alignment (tree exp, unsigned int max_align) 363 { 364 unsigned int align, inner; 365 366 if (!can_trust_pointer_alignment ()) 367 return 0; 368 369 if (!POINTER_TYPE_P (TREE_TYPE (exp))) 370 return 0; 371 372 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))); 373 align = MIN (align, max_align); 374 375 while (1) 376 { 377 switch (TREE_CODE (exp)) 378 { 379 CASE_CONVERT: 380 exp = TREE_OPERAND (exp, 0); 381 if (! POINTER_TYPE_P (TREE_TYPE (exp))) 382 return align; 383 384 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))); 385 align = MIN (inner, max_align); 386 break; 387 388 case POINTER_PLUS_EXPR: 389 /* If sum of pointer + int, restrict our maximum alignment to that 390 imposed by the integer. If not, we can't do any better than 391 ALIGN. */ 392 if (! host_integerp (TREE_OPERAND (exp, 1), 1)) 393 return align; 394 395 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1)) 396 & (max_align / BITS_PER_UNIT - 1)) 397 != 0) 398 max_align >>= 1; 399 400 exp = TREE_OPERAND (exp, 0); 401 break; 402 403 case ADDR_EXPR: 404 /* See what we are pointing at and look at its alignment. */ 405 return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align); 406 407 default: 408 return align; 409 } 410 } 411 } 412 413 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right 414 way, because it could contain a zero byte in the middle. 415 TREE_STRING_LENGTH is the size of the character array, not the string. 416 417 ONLY_VALUE should be nonzero if the result is not going to be emitted 418 into the instruction stream and zero if it is going to be expanded. 419 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3 420 is returned, otherwise NULL, since 421 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not 422 evaluate the side-effects. 423 424 The value returned is of type `ssizetype'. 425 426 Unfortunately, string_constant can't access the values of const char 427 arrays with initializers, so neither can we do so here. */ 428 429 tree 430 c_strlen (tree src, int only_value) 431 { 432 tree offset_node; 433 HOST_WIDE_INT offset; 434 int max; 435 const char *ptr; 436 location_t loc; 437 438 STRIP_NOPS (src); 439 if (TREE_CODE (src) == COND_EXPR 440 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) 441 { 442 tree len1, len2; 443 444 len1 = c_strlen (TREE_OPERAND (src, 1), only_value); 445 len2 = c_strlen (TREE_OPERAND (src, 2), only_value); 446 if (tree_int_cst_equal (len1, len2)) 447 return len1; 448 } 449 450 if (TREE_CODE (src) == COMPOUND_EXPR 451 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) 452 return c_strlen (TREE_OPERAND (src, 1), only_value); 453 454 if (EXPR_HAS_LOCATION (src)) 455 loc = EXPR_LOCATION (src); 456 else 457 loc = input_location; 458 459 src = string_constant (src, &offset_node); 460 if (src == 0) 461 return NULL_TREE; 462 463 max = TREE_STRING_LENGTH (src) - 1; 464 ptr = TREE_STRING_POINTER (src); 465 466 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST) 467 { 468 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't 469 compute the offset to the following null if we don't know where to 470 start searching for it. */ 471 int i; 472 473 for (i = 0; i < max; i++) 474 if (ptr[i] == 0) 475 return NULL_TREE; 476 477 /* We don't know the starting offset, but we do know that the string 478 has no internal zero bytes. We can assume that the offset falls 479 within the bounds of the string; otherwise, the programmer deserves 480 what he gets. Subtract the offset from the length of the string, 481 and return that. This would perhaps not be valid if we were dealing 482 with named arrays in addition to literal string constants. */ 483 484 return size_diffop_loc (loc, size_int (max), offset_node); 485 } 486 487 /* We have a known offset into the string. Start searching there for 488 a null character if we can represent it as a single HOST_WIDE_INT. */ 489 if (offset_node == 0) 490 offset = 0; 491 else if (! host_integerp (offset_node, 0)) 492 offset = -1; 493 else 494 offset = tree_low_cst (offset_node, 0); 495 496 /* If the offset is known to be out of bounds, warn, and call strlen at 497 runtime. */ 498 if (offset < 0 || offset > max) 499 { 500 /* Suppress multiple warnings for propagated constant strings. */ 501 if (! TREE_NO_WARNING (src)) 502 { 503 warning_at (loc, 0, "offset outside bounds of constant string"); 504 TREE_NO_WARNING (src) = 1; 505 } 506 return NULL_TREE; 507 } 508 509 /* Use strlen to search for the first zero byte. Since any strings 510 constructed with build_string will have nulls appended, we win even 511 if we get handed something like (char[4])"abcd". 512 513 Since OFFSET is our starting index into the string, no further 514 calculation is needed. */ 515 return ssize_int (strlen (ptr + offset)); 516 } 517 518 /* Return a char pointer for a C string if it is a string constant 519 or sum of string constant and integer constant. */ 520 521 static const char * 522 c_getstr (tree src) 523 { 524 tree offset_node; 525 526 src = string_constant (src, &offset_node); 527 if (src == 0) 528 return 0; 529 530 if (offset_node == 0) 531 return TREE_STRING_POINTER (src); 532 else if (!host_integerp (offset_node, 1) 533 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0) 534 return 0; 535 536 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1); 537 } 538 539 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading 540 GET_MODE_BITSIZE (MODE) bits from string constant STR. */ 541 542 static rtx 543 c_readstr (const char *str, enum machine_mode mode) 544 { 545 HOST_WIDE_INT c[2]; 546 HOST_WIDE_INT ch; 547 unsigned int i, j; 548 549 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT); 550 551 c[0] = 0; 552 c[1] = 0; 553 ch = 1; 554 for (i = 0; i < GET_MODE_SIZE (mode); i++) 555 { 556 j = i; 557 if (WORDS_BIG_ENDIAN) 558 j = GET_MODE_SIZE (mode) - i - 1; 559 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN 560 && GET_MODE_SIZE (mode) > UNITS_PER_WORD) 561 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1; 562 j *= BITS_PER_UNIT; 563 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT); 564 565 if (ch) 566 ch = (unsigned char) str[i]; 567 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT); 568 } 569 return immed_double_const (c[0], c[1], mode); 570 } 571 572 /* Cast a target constant CST to target CHAR and if that value fits into 573 host char type, return zero and put that value into variable pointed to by 574 P. */ 575 576 static int 577 target_char_cast (tree cst, char *p) 578 { 579 unsigned HOST_WIDE_INT val, hostval; 580 581 if (!host_integerp (cst, 1) 582 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT) 583 return 1; 584 585 val = tree_low_cst (cst, 1); 586 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT) 587 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1; 588 589 hostval = val; 590 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT) 591 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1; 592 593 if (val != hostval) 594 return 1; 595 596 *p = hostval; 597 return 0; 598 } 599 600 /* Similar to save_expr, but assumes that arbitrary code is not executed 601 in between the multiple evaluations. In particular, we assume that a 602 non-addressable local variable will not be modified. */ 603 604 static tree 605 builtin_save_expr (tree exp) 606 { 607 if (TREE_ADDRESSABLE (exp) == 0 608 && (TREE_CODE (exp) == PARM_DECL 609 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp)))) 610 return exp; 611 612 return save_expr (exp); 613 } 614 615 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT 616 times to get the address of either a higher stack frame, or a return 617 address located within it (depending on FNDECL_CODE). */ 618 619 static rtx 620 expand_builtin_return_addr (enum built_in_function fndecl_code, int count) 621 { 622 int i; 623 624 #ifdef INITIAL_FRAME_ADDRESS_RTX 625 rtx tem = INITIAL_FRAME_ADDRESS_RTX; 626 #else 627 rtx tem; 628 629 /* For a zero count with __builtin_return_address, we don't care what 630 frame address we return, because target-specific definitions will 631 override us. Therefore frame pointer elimination is OK, and using 632 the soft frame pointer is OK. 633 634 For a nonzero count, or a zero count with __builtin_frame_address, 635 we require a stable offset from the current frame pointer to the 636 previous one, so we must use the hard frame pointer, and 637 we must disable frame pointer elimination. */ 638 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS) 639 tem = frame_pointer_rtx; 640 else 641 { 642 tem = hard_frame_pointer_rtx; 643 644 /* Tell reload not to eliminate the frame pointer. */ 645 crtl->accesses_prior_frames = 1; 646 } 647 #endif 648 649 /* Some machines need special handling before we can access 650 arbitrary frames. For example, on the SPARC, we must first flush 651 all register windows to the stack. */ 652 #ifdef SETUP_FRAME_ADDRESSES 653 if (count > 0) 654 SETUP_FRAME_ADDRESSES (); 655 #endif 656 657 /* On the SPARC, the return address is not in the frame, it is in a 658 register. There is no way to access it off of the current frame 659 pointer, but it can be accessed off the previous frame pointer by 660 reading the value from the register window save area. */ 661 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME 662 if (fndecl_code == BUILT_IN_RETURN_ADDRESS) 663 count--; 664 #endif 665 666 /* Scan back COUNT frames to the specified frame. */ 667 for (i = 0; i < count; i++) 668 { 669 /* Assume the dynamic chain pointer is in the word that the 670 frame address points to, unless otherwise specified. */ 671 #ifdef DYNAMIC_CHAIN_ADDRESS 672 tem = DYNAMIC_CHAIN_ADDRESS (tem); 673 #endif 674 tem = memory_address (Pmode, tem); 675 tem = gen_frame_mem (Pmode, tem); 676 tem = copy_to_reg (tem); 677 } 678 679 /* For __builtin_frame_address, return what we've got. But, on 680 the SPARC for example, we may have to add a bias. */ 681 if (fndecl_code == BUILT_IN_FRAME_ADDRESS) 682 #ifdef FRAME_ADDR_RTX 683 return FRAME_ADDR_RTX (tem); 684 #else 685 return tem; 686 #endif 687 688 /* For __builtin_return_address, get the return address from that frame. */ 689 #ifdef RETURN_ADDR_RTX 690 tem = RETURN_ADDR_RTX (count, tem); 691 #else 692 tem = memory_address (Pmode, 693 plus_constant (tem, GET_MODE_SIZE (Pmode))); 694 tem = gen_frame_mem (Pmode, tem); 695 #endif 696 return tem; 697 } 698 699 /* Alias set used for setjmp buffer. */ 700 static alias_set_type setjmp_alias_set = -1; 701 702 /* Construct the leading half of a __builtin_setjmp call. Control will 703 return to RECEIVER_LABEL. This is also called directly by the SJLJ 704 exception handling code. */ 705 706 void 707 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label) 708 { 709 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 710 rtx stack_save; 711 rtx mem; 712 713 if (setjmp_alias_set == -1) 714 setjmp_alias_set = new_alias_set (); 715 716 buf_addr = convert_memory_address (Pmode, buf_addr); 717 718 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX)); 719 720 /* We store the frame pointer and the address of receiver_label in 721 the buffer and use the rest of it for the stack save area, which 722 is machine-dependent. */ 723 724 mem = gen_rtx_MEM (Pmode, buf_addr); 725 set_mem_alias_set (mem, setjmp_alias_set); 726 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ()); 727 728 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))), 729 set_mem_alias_set (mem, setjmp_alias_set); 730 731 emit_move_insn (validize_mem (mem), 732 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label))); 733 734 stack_save = gen_rtx_MEM (sa_mode, 735 plus_constant (buf_addr, 736 2 * GET_MODE_SIZE (Pmode))); 737 set_mem_alias_set (stack_save, setjmp_alias_set); 738 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX); 739 740 /* If there is further processing to do, do it. */ 741 #ifdef HAVE_builtin_setjmp_setup 742 if (HAVE_builtin_setjmp_setup) 743 emit_insn (gen_builtin_setjmp_setup (buf_addr)); 744 #endif 745 746 /* Tell optimize_save_area_alloca that extra work is going to 747 need to go on during alloca. */ 748 cfun->calls_setjmp = 1; 749 750 /* We have a nonlocal label. */ 751 cfun->has_nonlocal_label = 1; 752 } 753 754 /* Construct the trailing part of a __builtin_setjmp call. This is 755 also called directly by the SJLJ exception handling code. */ 756 757 void 758 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED) 759 { 760 rtx chain; 761 762 /* Clobber the FP when we get here, so we have to make sure it's 763 marked as used by this function. */ 764 emit_use (hard_frame_pointer_rtx); 765 766 /* Mark the static chain as clobbered here so life information 767 doesn't get messed up for it. */ 768 chain = targetm.calls.static_chain (current_function_decl, true); 769 if (chain && REG_P (chain)) 770 emit_clobber (chain); 771 772 /* Now put in the code to restore the frame pointer, and argument 773 pointer, if needed. */ 774 #ifdef HAVE_nonlocal_goto 775 if (! HAVE_nonlocal_goto) 776 #endif 777 { 778 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); 779 /* This might change the hard frame pointer in ways that aren't 780 apparent to early optimization passes, so force a clobber. */ 781 emit_clobber (hard_frame_pointer_rtx); 782 } 783 784 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM 785 if (fixed_regs[ARG_POINTER_REGNUM]) 786 { 787 #ifdef ELIMINABLE_REGS 788 size_t i; 789 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS; 790 791 for (i = 0; i < ARRAY_SIZE (elim_regs); i++) 792 if (elim_regs[i].from == ARG_POINTER_REGNUM 793 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM) 794 break; 795 796 if (i == ARRAY_SIZE (elim_regs)) 797 #endif 798 { 799 /* Now restore our arg pointer from the address at which it 800 was saved in our stack frame. */ 801 emit_move_insn (crtl->args.internal_arg_pointer, 802 copy_to_reg (get_arg_pointer_save_area ())); 803 } 804 } 805 #endif 806 807 #ifdef HAVE_builtin_setjmp_receiver 808 if (HAVE_builtin_setjmp_receiver) 809 emit_insn (gen_builtin_setjmp_receiver (receiver_label)); 810 else 811 #endif 812 #ifdef HAVE_nonlocal_goto_receiver 813 if (HAVE_nonlocal_goto_receiver) 814 emit_insn (gen_nonlocal_goto_receiver ()); 815 else 816 #endif 817 { /* Nothing */ } 818 819 /* We must not allow the code we just generated to be reordered by 820 scheduling. Specifically, the update of the frame pointer must 821 happen immediately, not later. */ 822 emit_insn (gen_blockage ()); 823 } 824 825 /* __builtin_longjmp is passed a pointer to an array of five words (not 826 all will be used on all machines). It operates similarly to the C 827 library function of the same name, but is more efficient. Much of 828 the code below is copied from the handling of non-local gotos. */ 829 830 static void 831 expand_builtin_longjmp (rtx buf_addr, rtx value) 832 { 833 rtx fp, lab, stack, insn, last; 834 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 835 836 /* DRAP is needed for stack realign if longjmp is expanded to current 837 function */ 838 if (SUPPORTS_STACK_ALIGNMENT) 839 crtl->need_drap = true; 840 841 if (setjmp_alias_set == -1) 842 setjmp_alias_set = new_alias_set (); 843 844 buf_addr = convert_memory_address (Pmode, buf_addr); 845 846 buf_addr = force_reg (Pmode, buf_addr); 847 848 /* We require that the user must pass a second argument of 1, because 849 that is what builtin_setjmp will return. */ 850 gcc_assert (value == const1_rtx); 851 852 last = get_last_insn (); 853 #ifdef HAVE_builtin_longjmp 854 if (HAVE_builtin_longjmp) 855 emit_insn (gen_builtin_longjmp (buf_addr)); 856 else 857 #endif 858 { 859 fp = gen_rtx_MEM (Pmode, buf_addr); 860 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr, 861 GET_MODE_SIZE (Pmode))); 862 863 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr, 864 2 * GET_MODE_SIZE (Pmode))); 865 set_mem_alias_set (fp, setjmp_alias_set); 866 set_mem_alias_set (lab, setjmp_alias_set); 867 set_mem_alias_set (stack, setjmp_alias_set); 868 869 /* Pick up FP, label, and SP from the block and jump. This code is 870 from expand_goto in stmt.c; see there for detailed comments. */ 871 #ifdef HAVE_nonlocal_goto 872 if (HAVE_nonlocal_goto) 873 /* We have to pass a value to the nonlocal_goto pattern that will 874 get copied into the static_chain pointer, but it does not matter 875 what that value is, because builtin_setjmp does not use it. */ 876 emit_insn (gen_nonlocal_goto (value, lab, stack, fp)); 877 else 878 #endif 879 { 880 lab = copy_to_reg (lab); 881 882 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); 883 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); 884 885 emit_move_insn (hard_frame_pointer_rtx, fp); 886 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX); 887 888 emit_use (hard_frame_pointer_rtx); 889 emit_use (stack_pointer_rtx); 890 emit_indirect_jump (lab); 891 } 892 } 893 894 /* Search backwards and mark the jump insn as a non-local goto. 895 Note that this precludes the use of __builtin_longjmp to a 896 __builtin_setjmp target in the same function. However, we've 897 already cautioned the user that these functions are for 898 internal exception handling use only. */ 899 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) 900 { 901 gcc_assert (insn != last); 902 903 if (JUMP_P (insn)) 904 { 905 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx); 906 break; 907 } 908 else if (CALL_P (insn)) 909 break; 910 } 911 } 912 913 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label 914 and the address of the save area. */ 915 916 static rtx 917 expand_builtin_nonlocal_goto (tree exp) 918 { 919 tree t_label, t_save_area; 920 rtx r_label, r_save_area, r_fp, r_sp, insn; 921 922 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 923 return NULL_RTX; 924 925 t_label = CALL_EXPR_ARG (exp, 0); 926 t_save_area = CALL_EXPR_ARG (exp, 1); 927 928 r_label = expand_normal (t_label); 929 r_label = convert_memory_address (Pmode, r_label); 930 r_save_area = expand_normal (t_save_area); 931 r_save_area = convert_memory_address (Pmode, r_save_area); 932 /* Copy the address of the save location to a register just in case it was based 933 on the frame pointer. */ 934 r_save_area = copy_to_reg (r_save_area); 935 r_fp = gen_rtx_MEM (Pmode, r_save_area); 936 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL), 937 plus_constant (r_save_area, GET_MODE_SIZE (Pmode))); 938 939 crtl->has_nonlocal_goto = 1; 940 941 #ifdef HAVE_nonlocal_goto 942 /* ??? We no longer need to pass the static chain value, afaik. */ 943 if (HAVE_nonlocal_goto) 944 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp)); 945 else 946 #endif 947 { 948 r_label = copy_to_reg (r_label); 949 950 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); 951 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); 952 953 /* Restore frame pointer for containing function. 954 This sets the actual hard register used for the frame pointer 955 to the location of the function's incoming static chain info. 956 The non-local goto handler will then adjust it to contain the 957 proper value and reload the argument pointer, if needed. */ 958 emit_move_insn (hard_frame_pointer_rtx, r_fp); 959 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX); 960 961 /* USE of hard_frame_pointer_rtx added for consistency; 962 not clear if really needed. */ 963 emit_use (hard_frame_pointer_rtx); 964 emit_use (stack_pointer_rtx); 965 966 /* If the architecture is using a GP register, we must 967 conservatively assume that the target function makes use of it. 968 The prologue of functions with nonlocal gotos must therefore 969 initialize the GP register to the appropriate value, and we 970 must then make sure that this value is live at the point 971 of the jump. (Note that this doesn't necessarily apply 972 to targets with a nonlocal_goto pattern; they are free 973 to implement it in their own way. Note also that this is 974 a no-op if the GP register is a global invariant.) */ 975 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM 976 && fixed_regs[PIC_OFFSET_TABLE_REGNUM]) 977 emit_use (pic_offset_table_rtx); 978 979 emit_indirect_jump (r_label); 980 } 981 982 /* Search backwards to the jump insn and mark it as a 983 non-local goto. */ 984 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) 985 { 986 if (JUMP_P (insn)) 987 { 988 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx); 989 break; 990 } 991 else if (CALL_P (insn)) 992 break; 993 } 994 995 return const0_rtx; 996 } 997 998 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words 999 (not all will be used on all machines) that was passed to __builtin_setjmp. 1000 It updates the stack pointer in that block to correspond to the current 1001 stack pointer. */ 1002 1003 static void 1004 expand_builtin_update_setjmp_buf (rtx buf_addr) 1005 { 1006 enum machine_mode sa_mode = Pmode; 1007 rtx stack_save; 1008 1009 1010 #ifdef HAVE_save_stack_nonlocal 1011 if (HAVE_save_stack_nonlocal) 1012 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode; 1013 #endif 1014 #ifdef STACK_SAVEAREA_MODE 1015 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 1016 #endif 1017 1018 stack_save 1019 = gen_rtx_MEM (sa_mode, 1020 memory_address 1021 (sa_mode, 1022 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode)))); 1023 1024 #ifdef HAVE_setjmp 1025 if (HAVE_setjmp) 1026 emit_insn (gen_setjmp ()); 1027 #endif 1028 1029 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX); 1030 } 1031 1032 /* Expand a call to __builtin_prefetch. For a target that does not support 1033 data prefetch, evaluate the memory address argument in case it has side 1034 effects. */ 1035 1036 static void 1037 expand_builtin_prefetch (tree exp) 1038 { 1039 tree arg0, arg1, arg2; 1040 int nargs; 1041 rtx op0, op1, op2; 1042 1043 if (!validate_arglist (exp, POINTER_TYPE, 0)) 1044 return; 1045 1046 arg0 = CALL_EXPR_ARG (exp, 0); 1047 1048 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to 1049 zero (read) and argument 2 (locality) defaults to 3 (high degree of 1050 locality). */ 1051 nargs = call_expr_nargs (exp); 1052 if (nargs > 1) 1053 arg1 = CALL_EXPR_ARG (exp, 1); 1054 else 1055 arg1 = integer_zero_node; 1056 if (nargs > 2) 1057 arg2 = CALL_EXPR_ARG (exp, 2); 1058 else 1059 arg2 = build_int_cst (NULL_TREE, 3); 1060 1061 /* Argument 0 is an address. */ 1062 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL); 1063 1064 /* Argument 1 (read/write flag) must be a compile-time constant int. */ 1065 if (TREE_CODE (arg1) != INTEGER_CST) 1066 { 1067 error ("second argument to %<__builtin_prefetch%> must be a constant"); 1068 arg1 = integer_zero_node; 1069 } 1070 op1 = expand_normal (arg1); 1071 /* Argument 1 must be either zero or one. */ 1072 if (INTVAL (op1) != 0 && INTVAL (op1) != 1) 1073 { 1074 warning (0, "invalid second argument to %<__builtin_prefetch%>;" 1075 " using zero"); 1076 op1 = const0_rtx; 1077 } 1078 1079 /* Argument 2 (locality) must be a compile-time constant int. */ 1080 if (TREE_CODE (arg2) != INTEGER_CST) 1081 { 1082 error ("third argument to %<__builtin_prefetch%> must be a constant"); 1083 arg2 = integer_zero_node; 1084 } 1085 op2 = expand_normal (arg2); 1086 /* Argument 2 must be 0, 1, 2, or 3. */ 1087 if (INTVAL (op2) < 0 || INTVAL (op2) > 3) 1088 { 1089 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero"); 1090 op2 = const0_rtx; 1091 } 1092 1093 #ifdef HAVE_prefetch 1094 if (HAVE_prefetch) 1095 { 1096 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate) 1097 (op0, 1098 insn_data[(int) CODE_FOR_prefetch].operand[0].mode)) 1099 || (GET_MODE (op0) != Pmode)) 1100 { 1101 op0 = convert_memory_address (Pmode, op0); 1102 op0 = force_reg (Pmode, op0); 1103 } 1104 emit_insn (gen_prefetch (op0, op1, op2)); 1105 } 1106 #endif 1107 1108 /* Don't do anything with direct references to volatile memory, but 1109 generate code to handle other side effects. */ 1110 if (!MEM_P (op0) && side_effects_p (op0)) 1111 emit_insn (op0); 1112 } 1113 1114 /* Get a MEM rtx for expression EXP which is the address of an operand 1115 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is 1116 the maximum length of the block of memory that might be accessed or 1117 NULL if unknown. */ 1118 1119 static rtx 1120 get_memory_rtx (tree exp, tree len) 1121 { 1122 tree orig_exp = exp; 1123 rtx addr, mem; 1124 HOST_WIDE_INT off; 1125 1126 /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived 1127 from its expression, for expr->a.b only <variable>.a.b is recorded. */ 1128 if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp)) 1129 exp = TREE_OPERAND (exp, 0); 1130 1131 addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL); 1132 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr)); 1133 1134 /* Get an expression we can use to find the attributes to assign to MEM. 1135 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if 1136 we can. First remove any nops. */ 1137 while (CONVERT_EXPR_P (exp) 1138 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0)))) 1139 exp = TREE_OPERAND (exp, 0); 1140 1141 off = 0; 1142 if (TREE_CODE (exp) == POINTER_PLUS_EXPR 1143 && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR 1144 && host_integerp (TREE_OPERAND (exp, 1), 0) 1145 && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0) 1146 exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); 1147 else if (TREE_CODE (exp) == ADDR_EXPR) 1148 exp = TREE_OPERAND (exp, 0); 1149 else if (POINTER_TYPE_P (TREE_TYPE (exp))) 1150 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp); 1151 else 1152 exp = NULL; 1153 1154 /* Honor attributes derived from exp, except for the alias set 1155 (as builtin stringops may alias with anything) and the size 1156 (as stringops may access multiple array elements). */ 1157 if (exp) 1158 { 1159 set_mem_attributes (mem, exp, 0); 1160 1161 if (off) 1162 mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off); 1163 1164 /* Allow the string and memory builtins to overflow from one 1165 field into another, see http://gcc.gnu.org/PR23561. 1166 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole 1167 memory accessed by the string or memory builtin will fit 1168 within the field. */ 1169 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF) 1170 { 1171 tree mem_expr = MEM_EXPR (mem); 1172 HOST_WIDE_INT offset = -1, length = -1; 1173 tree inner = exp; 1174 1175 while (TREE_CODE (inner) == ARRAY_REF 1176 || CONVERT_EXPR_P (inner) 1177 || TREE_CODE (inner) == VIEW_CONVERT_EXPR 1178 || TREE_CODE (inner) == SAVE_EXPR) 1179 inner = TREE_OPERAND (inner, 0); 1180 1181 gcc_assert (TREE_CODE (inner) == COMPONENT_REF); 1182 1183 if (MEM_OFFSET (mem) 1184 && CONST_INT_P (MEM_OFFSET (mem))) 1185 offset = INTVAL (MEM_OFFSET (mem)); 1186 1187 if (offset >= 0 && len && host_integerp (len, 0)) 1188 length = tree_low_cst (len, 0); 1189 1190 while (TREE_CODE (inner) == COMPONENT_REF) 1191 { 1192 tree field = TREE_OPERAND (inner, 1); 1193 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF); 1194 gcc_assert (field == TREE_OPERAND (mem_expr, 1)); 1195 1196 /* Bitfields are generally not byte-addressable. */ 1197 gcc_assert (!DECL_BIT_FIELD (field) 1198 || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1) 1199 % BITS_PER_UNIT) == 0 1200 && host_integerp (DECL_SIZE (field), 0) 1201 && (TREE_INT_CST_LOW (DECL_SIZE (field)) 1202 % BITS_PER_UNIT) == 0)); 1203 1204 /* If we can prove that the memory starting at XEXP (mem, 0) and 1205 ending at XEXP (mem, 0) + LENGTH will fit into this field, we 1206 can keep the COMPONENT_REF in MEM_EXPR. But be careful with 1207 fields without DECL_SIZE_UNIT like flexible array members. */ 1208 if (length >= 0 1209 && DECL_SIZE_UNIT (field) 1210 && host_integerp (DECL_SIZE_UNIT (field), 0)) 1211 { 1212 HOST_WIDE_INT size 1213 = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field)); 1214 if (offset <= size 1215 && length <= size 1216 && offset + length <= size) 1217 break; 1218 } 1219 1220 if (offset >= 0 1221 && host_integerp (DECL_FIELD_OFFSET (field), 0)) 1222 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field)) 1223 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1) 1224 / BITS_PER_UNIT; 1225 else 1226 { 1227 offset = -1; 1228 length = -1; 1229 } 1230 1231 mem_expr = TREE_OPERAND (mem_expr, 0); 1232 inner = TREE_OPERAND (inner, 0); 1233 } 1234 1235 if (mem_expr == NULL) 1236 offset = -1; 1237 if (mem_expr != MEM_EXPR (mem)) 1238 { 1239 set_mem_expr (mem, mem_expr); 1240 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX); 1241 } 1242 } 1243 set_mem_alias_set (mem, 0); 1244 set_mem_size (mem, NULL_RTX); 1245 } 1246 1247 return mem; 1248 } 1249 1250 /* Built-in functions to perform an untyped call and return. */ 1251 1252 /* For each register that may be used for calling a function, this 1253 gives a mode used to copy the register's value. VOIDmode indicates 1254 the register is not used for calling a function. If the machine 1255 has register windows, this gives only the outbound registers. 1256 INCOMING_REGNO gives the corresponding inbound register. */ 1257 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER]; 1258 1259 /* For each register that may be used for returning values, this gives 1260 a mode used to copy the register's value. VOIDmode indicates the 1261 register is not used for returning values. If the machine has 1262 register windows, this gives only the outbound registers. 1263 INCOMING_REGNO gives the corresponding inbound register. */ 1264 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER]; 1265 1266 /* Return the size required for the block returned by __builtin_apply_args, 1267 and initialize apply_args_mode. */ 1268 1269 static int 1270 apply_args_size (void) 1271 { 1272 static int size = -1; 1273 int align; 1274 unsigned int regno; 1275 enum machine_mode mode; 1276 1277 /* The values computed by this function never change. */ 1278 if (size < 0) 1279 { 1280 /* The first value is the incoming arg-pointer. */ 1281 size = GET_MODE_SIZE (Pmode); 1282 1283 /* The second value is the structure value address unless this is 1284 passed as an "invisible" first argument. */ 1285 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0)) 1286 size += GET_MODE_SIZE (Pmode); 1287 1288 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1289 if (FUNCTION_ARG_REGNO_P (regno)) 1290 { 1291 mode = reg_raw_mode[regno]; 1292 1293 gcc_assert (mode != VOIDmode); 1294 1295 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1296 if (size % align != 0) 1297 size = CEIL (size, align) * align; 1298 size += GET_MODE_SIZE (mode); 1299 apply_args_mode[regno] = mode; 1300 } 1301 else 1302 { 1303 apply_args_mode[regno] = VOIDmode; 1304 } 1305 } 1306 return size; 1307 } 1308 1309 /* Return the size required for the block returned by __builtin_apply, 1310 and initialize apply_result_mode. */ 1311 1312 static int 1313 apply_result_size (void) 1314 { 1315 static int size = -1; 1316 int align, regno; 1317 enum machine_mode mode; 1318 1319 /* The values computed by this function never change. */ 1320 if (size < 0) 1321 { 1322 size = 0; 1323 1324 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1325 if (FUNCTION_VALUE_REGNO_P (regno)) 1326 { 1327 mode = reg_raw_mode[regno]; 1328 1329 gcc_assert (mode != VOIDmode); 1330 1331 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1332 if (size % align != 0) 1333 size = CEIL (size, align) * align; 1334 size += GET_MODE_SIZE (mode); 1335 apply_result_mode[regno] = mode; 1336 } 1337 else 1338 apply_result_mode[regno] = VOIDmode; 1339 1340 /* Allow targets that use untyped_call and untyped_return to override 1341 the size so that machine-specific information can be stored here. */ 1342 #ifdef APPLY_RESULT_SIZE 1343 size = APPLY_RESULT_SIZE; 1344 #endif 1345 } 1346 return size; 1347 } 1348 1349 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return) 1350 /* Create a vector describing the result block RESULT. If SAVEP is true, 1351 the result block is used to save the values; otherwise it is used to 1352 restore the values. */ 1353 1354 static rtx 1355 result_vector (int savep, rtx result) 1356 { 1357 int regno, size, align, nelts; 1358 enum machine_mode mode; 1359 rtx reg, mem; 1360 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER); 1361 1362 size = nelts = 0; 1363 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1364 if ((mode = apply_result_mode[regno]) != VOIDmode) 1365 { 1366 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1367 if (size % align != 0) 1368 size = CEIL (size, align) * align; 1369 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno)); 1370 mem = adjust_address (result, mode, size); 1371 savevec[nelts++] = (savep 1372 ? gen_rtx_SET (VOIDmode, mem, reg) 1373 : gen_rtx_SET (VOIDmode, reg, mem)); 1374 size += GET_MODE_SIZE (mode); 1375 } 1376 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec)); 1377 } 1378 #endif /* HAVE_untyped_call or HAVE_untyped_return */ 1379 1380 /* Save the state required to perform an untyped call with the same 1381 arguments as were passed to the current function. */ 1382 1383 static rtx 1384 expand_builtin_apply_args_1 (void) 1385 { 1386 rtx registers, tem; 1387 int size, align, regno; 1388 enum machine_mode mode; 1389 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1); 1390 1391 /* Create a block where the arg-pointer, structure value address, 1392 and argument registers can be saved. */ 1393 registers = assign_stack_local (BLKmode, apply_args_size (), -1); 1394 1395 /* Walk past the arg-pointer and structure value address. */ 1396 size = GET_MODE_SIZE (Pmode); 1397 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0)) 1398 size += GET_MODE_SIZE (Pmode); 1399 1400 /* Save each register used in calling a function to the block. */ 1401 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1402 if ((mode = apply_args_mode[regno]) != VOIDmode) 1403 { 1404 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1405 if (size % align != 0) 1406 size = CEIL (size, align) * align; 1407 1408 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno)); 1409 1410 emit_move_insn (adjust_address (registers, mode, size), tem); 1411 size += GET_MODE_SIZE (mode); 1412 } 1413 1414 /* Save the arg pointer to the block. */ 1415 tem = copy_to_reg (crtl->args.internal_arg_pointer); 1416 #ifdef STACK_GROWS_DOWNWARD 1417 /* We need the pointer as the caller actually passed them to us, not 1418 as we might have pretended they were passed. Make sure it's a valid 1419 operand, as emit_move_insn isn't expected to handle a PLUS. */ 1420 tem 1421 = force_operand (plus_constant (tem, crtl->args.pretend_args_size), 1422 NULL_RTX); 1423 #endif 1424 emit_move_insn (adjust_address (registers, Pmode, 0), tem); 1425 1426 size = GET_MODE_SIZE (Pmode); 1427 1428 /* Save the structure value address unless this is passed as an 1429 "invisible" first argument. */ 1430 if (struct_incoming_value) 1431 { 1432 emit_move_insn (adjust_address (registers, Pmode, size), 1433 copy_to_reg (struct_incoming_value)); 1434 size += GET_MODE_SIZE (Pmode); 1435 } 1436 1437 /* Return the address of the block. */ 1438 return copy_addr_to_reg (XEXP (registers, 0)); 1439 } 1440 1441 /* __builtin_apply_args returns block of memory allocated on 1442 the stack into which is stored the arg pointer, structure 1443 value address, static chain, and all the registers that might 1444 possibly be used in performing a function call. The code is 1445 moved to the start of the function so the incoming values are 1446 saved. */ 1447 1448 static rtx 1449 expand_builtin_apply_args (void) 1450 { 1451 /* Don't do __builtin_apply_args more than once in a function. 1452 Save the result of the first call and reuse it. */ 1453 if (apply_args_value != 0) 1454 return apply_args_value; 1455 { 1456 /* When this function is called, it means that registers must be 1457 saved on entry to this function. So we migrate the 1458 call to the first insn of this function. */ 1459 rtx temp; 1460 rtx seq; 1461 1462 start_sequence (); 1463 temp = expand_builtin_apply_args_1 (); 1464 seq = get_insns (); 1465 end_sequence (); 1466 1467 apply_args_value = temp; 1468 1469 /* Put the insns after the NOTE that starts the function. 1470 If this is inside a start_sequence, make the outer-level insn 1471 chain current, so the code is placed at the start of the 1472 function. If internal_arg_pointer is a non-virtual pseudo, 1473 it needs to be placed after the function that initializes 1474 that pseudo. */ 1475 push_topmost_sequence (); 1476 if (REG_P (crtl->args.internal_arg_pointer) 1477 && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER) 1478 emit_insn_before (seq, parm_birth_insn); 1479 else 1480 emit_insn_before (seq, NEXT_INSN (entry_of_function ())); 1481 pop_topmost_sequence (); 1482 return temp; 1483 } 1484 } 1485 1486 /* Perform an untyped call and save the state required to perform an 1487 untyped return of whatever value was returned by the given function. */ 1488 1489 static rtx 1490 expand_builtin_apply (rtx function, rtx arguments, rtx argsize) 1491 { 1492 int size, align, regno; 1493 enum machine_mode mode; 1494 rtx incoming_args, result, reg, dest, src, call_insn; 1495 rtx old_stack_level = 0; 1496 rtx call_fusage = 0; 1497 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0); 1498 1499 arguments = convert_memory_address (Pmode, arguments); 1500 1501 /* Create a block where the return registers can be saved. */ 1502 result = assign_stack_local (BLKmode, apply_result_size (), -1); 1503 1504 /* Fetch the arg pointer from the ARGUMENTS block. */ 1505 incoming_args = gen_reg_rtx (Pmode); 1506 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments)); 1507 #ifndef STACK_GROWS_DOWNWARD 1508 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize, 1509 incoming_args, 0, OPTAB_LIB_WIDEN); 1510 #endif 1511 1512 /* Push a new argument block and copy the arguments. Do not allow 1513 the (potential) memcpy call below to interfere with our stack 1514 manipulations. */ 1515 do_pending_stack_adjust (); 1516 NO_DEFER_POP; 1517 1518 /* Save the stack with nonlocal if available. */ 1519 #ifdef HAVE_save_stack_nonlocal 1520 if (HAVE_save_stack_nonlocal) 1521 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX); 1522 else 1523 #endif 1524 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); 1525 1526 /* Allocate a block of memory onto the stack and copy the memory 1527 arguments to the outgoing arguments address. */ 1528 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT); 1529 1530 /* Set DRAP flag to true, even though allocate_dynamic_stack_space 1531 may have already set current_function_calls_alloca to true. 1532 current_function_calls_alloca won't be set if argsize is zero, 1533 so we have to guarantee need_drap is true here. */ 1534 if (SUPPORTS_STACK_ALIGNMENT) 1535 crtl->need_drap = true; 1536 1537 dest = virtual_outgoing_args_rtx; 1538 #ifndef STACK_GROWS_DOWNWARD 1539 if (CONST_INT_P (argsize)) 1540 dest = plus_constant (dest, -INTVAL (argsize)); 1541 else 1542 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize)); 1543 #endif 1544 dest = gen_rtx_MEM (BLKmode, dest); 1545 set_mem_align (dest, PARM_BOUNDARY); 1546 src = gen_rtx_MEM (BLKmode, incoming_args); 1547 set_mem_align (src, PARM_BOUNDARY); 1548 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL); 1549 1550 /* Refer to the argument block. */ 1551 apply_args_size (); 1552 arguments = gen_rtx_MEM (BLKmode, arguments); 1553 set_mem_align (arguments, PARM_BOUNDARY); 1554 1555 /* Walk past the arg-pointer and structure value address. */ 1556 size = GET_MODE_SIZE (Pmode); 1557 if (struct_value) 1558 size += GET_MODE_SIZE (Pmode); 1559 1560 /* Restore each of the registers previously saved. Make USE insns 1561 for each of these registers for use in making the call. */ 1562 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1563 if ((mode = apply_args_mode[regno]) != VOIDmode) 1564 { 1565 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1566 if (size % align != 0) 1567 size = CEIL (size, align) * align; 1568 reg = gen_rtx_REG (mode, regno); 1569 emit_move_insn (reg, adjust_address (arguments, mode, size)); 1570 use_reg (&call_fusage, reg); 1571 size += GET_MODE_SIZE (mode); 1572 } 1573 1574 /* Restore the structure value address unless this is passed as an 1575 "invisible" first argument. */ 1576 size = GET_MODE_SIZE (Pmode); 1577 if (struct_value) 1578 { 1579 rtx value = gen_reg_rtx (Pmode); 1580 emit_move_insn (value, adjust_address (arguments, Pmode, size)); 1581 emit_move_insn (struct_value, value); 1582 if (REG_P (struct_value)) 1583 use_reg (&call_fusage, struct_value); 1584 size += GET_MODE_SIZE (Pmode); 1585 } 1586 1587 /* All arguments and registers used for the call are set up by now! */ 1588 function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0); 1589 1590 /* Ensure address is valid. SYMBOL_REF is already valid, so no need, 1591 and we don't want to load it into a register as an optimization, 1592 because prepare_call_address already did it if it should be done. */ 1593 if (GET_CODE (function) != SYMBOL_REF) 1594 function = memory_address (FUNCTION_MODE, function); 1595 1596 /* Generate the actual call instruction and save the return value. */ 1597 #ifdef HAVE_untyped_call 1598 if (HAVE_untyped_call) 1599 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function), 1600 result, result_vector (1, result))); 1601 else 1602 #endif 1603 #ifdef HAVE_call_value 1604 if (HAVE_call_value) 1605 { 1606 rtx valreg = 0; 1607 1608 /* Locate the unique return register. It is not possible to 1609 express a call that sets more than one return register using 1610 call_value; use untyped_call for that. In fact, untyped_call 1611 only needs to save the return registers in the given block. */ 1612 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1613 if ((mode = apply_result_mode[regno]) != VOIDmode) 1614 { 1615 gcc_assert (!valreg); /* HAVE_untyped_call required. */ 1616 1617 valreg = gen_rtx_REG (mode, regno); 1618 } 1619 1620 emit_call_insn (GEN_CALL_VALUE (valreg, 1621 gen_rtx_MEM (FUNCTION_MODE, function), 1622 const0_rtx, NULL_RTX, const0_rtx)); 1623 1624 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg); 1625 } 1626 else 1627 #endif 1628 gcc_unreachable (); 1629 1630 /* Find the CALL insn we just emitted, and attach the register usage 1631 information. */ 1632 call_insn = last_call_insn (); 1633 add_function_usage_to (call_insn, call_fusage); 1634 1635 /* Restore the stack. */ 1636 #ifdef HAVE_save_stack_nonlocal 1637 if (HAVE_save_stack_nonlocal) 1638 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX); 1639 else 1640 #endif 1641 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX); 1642 1643 OK_DEFER_POP; 1644 1645 /* Return the address of the result block. */ 1646 result = copy_addr_to_reg (XEXP (result, 0)); 1647 return convert_memory_address (ptr_mode, result); 1648 } 1649 1650 /* Perform an untyped return. */ 1651 1652 static void 1653 expand_builtin_return (rtx result) 1654 { 1655 int size, align, regno; 1656 enum machine_mode mode; 1657 rtx reg; 1658 rtx call_fusage = 0; 1659 1660 result = convert_memory_address (Pmode, result); 1661 1662 apply_result_size (); 1663 result = gen_rtx_MEM (BLKmode, result); 1664 1665 #ifdef HAVE_untyped_return 1666 if (HAVE_untyped_return) 1667 { 1668 emit_jump_insn (gen_untyped_return (result, result_vector (0, result))); 1669 emit_barrier (); 1670 return; 1671 } 1672 #endif 1673 1674 /* Restore the return value and note that each value is used. */ 1675 size = 0; 1676 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1677 if ((mode = apply_result_mode[regno]) != VOIDmode) 1678 { 1679 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1680 if (size % align != 0) 1681 size = CEIL (size, align) * align; 1682 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno)); 1683 emit_move_insn (reg, adjust_address (result, mode, size)); 1684 1685 push_to_sequence (call_fusage); 1686 emit_use (reg); 1687 call_fusage = get_insns (); 1688 end_sequence (); 1689 size += GET_MODE_SIZE (mode); 1690 } 1691 1692 /* Put the USE insns before the return. */ 1693 emit_insn (call_fusage); 1694 1695 /* Return whatever values was restored by jumping directly to the end 1696 of the function. */ 1697 expand_naked_return (); 1698 } 1699 1700 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */ 1701 1702 static enum type_class 1703 type_to_class (tree type) 1704 { 1705 switch (TREE_CODE (type)) 1706 { 1707 case VOID_TYPE: return void_type_class; 1708 case INTEGER_TYPE: return integer_type_class; 1709 case ENUMERAL_TYPE: return enumeral_type_class; 1710 case BOOLEAN_TYPE: return boolean_type_class; 1711 case POINTER_TYPE: return pointer_type_class; 1712 case REFERENCE_TYPE: return reference_type_class; 1713 case OFFSET_TYPE: return offset_type_class; 1714 case REAL_TYPE: return real_type_class; 1715 case COMPLEX_TYPE: return complex_type_class; 1716 case FUNCTION_TYPE: return function_type_class; 1717 case METHOD_TYPE: return method_type_class; 1718 case RECORD_TYPE: return record_type_class; 1719 case UNION_TYPE: 1720 case QUAL_UNION_TYPE: return union_type_class; 1721 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type) 1722 ? string_type_class : array_type_class); 1723 case LANG_TYPE: return lang_type_class; 1724 default: return no_type_class; 1725 } 1726 } 1727 1728 /* Expand a call EXP to __builtin_classify_type. */ 1729 1730 static rtx 1731 expand_builtin_classify_type (tree exp) 1732 { 1733 if (call_expr_nargs (exp)) 1734 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0)))); 1735 return GEN_INT (no_type_class); 1736 } 1737 1738 /* This helper macro, meant to be used in mathfn_built_in below, 1739 determines which among a set of three builtin math functions is 1740 appropriate for a given type mode. The `F' and `L' cases are 1741 automatically generated from the `double' case. */ 1742 #define CASE_MATHFN(BUILT_IN_MATHFN) \ 1743 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \ 1744 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \ 1745 fcodel = BUILT_IN_MATHFN##L ; break; 1746 /* Similar to above, but appends _R after any F/L suffix. */ 1747 #define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \ 1748 case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \ 1749 fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \ 1750 fcodel = BUILT_IN_MATHFN##L_R ; break; 1751 1752 /* Return mathematic function equivalent to FN but operating directly 1753 on TYPE, if available. If IMPLICIT is true find the function in 1754 implicit_built_in_decls[], otherwise use built_in_decls[]. If we 1755 can't do the conversion, return zero. */ 1756 1757 static tree 1758 mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit) 1759 { 1760 tree const *const fn_arr 1761 = implicit ? implicit_built_in_decls : built_in_decls; 1762 enum built_in_function fcode, fcodef, fcodel; 1763 1764 switch (fn) 1765 { 1766 CASE_MATHFN (BUILT_IN_ACOS) 1767 CASE_MATHFN (BUILT_IN_ACOSH) 1768 CASE_MATHFN (BUILT_IN_ASIN) 1769 CASE_MATHFN (BUILT_IN_ASINH) 1770 CASE_MATHFN (BUILT_IN_ATAN) 1771 CASE_MATHFN (BUILT_IN_ATAN2) 1772 CASE_MATHFN (BUILT_IN_ATANH) 1773 CASE_MATHFN (BUILT_IN_CBRT) 1774 CASE_MATHFN (BUILT_IN_CEIL) 1775 CASE_MATHFN (BUILT_IN_CEXPI) 1776 CASE_MATHFN (BUILT_IN_COPYSIGN) 1777 CASE_MATHFN (BUILT_IN_COS) 1778 CASE_MATHFN (BUILT_IN_COSH) 1779 CASE_MATHFN (BUILT_IN_DREM) 1780 CASE_MATHFN (BUILT_IN_ERF) 1781 CASE_MATHFN (BUILT_IN_ERFC) 1782 CASE_MATHFN (BUILT_IN_EXP) 1783 CASE_MATHFN (BUILT_IN_EXP10) 1784 CASE_MATHFN (BUILT_IN_EXP2) 1785 CASE_MATHFN (BUILT_IN_EXPM1) 1786 CASE_MATHFN (BUILT_IN_FABS) 1787 CASE_MATHFN (BUILT_IN_FDIM) 1788 CASE_MATHFN (BUILT_IN_FLOOR) 1789 CASE_MATHFN (BUILT_IN_FMA) 1790 CASE_MATHFN (BUILT_IN_FMAX) 1791 CASE_MATHFN (BUILT_IN_FMIN) 1792 CASE_MATHFN (BUILT_IN_FMOD) 1793 CASE_MATHFN (BUILT_IN_FREXP) 1794 CASE_MATHFN (BUILT_IN_GAMMA) 1795 CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */ 1796 CASE_MATHFN (BUILT_IN_HUGE_VAL) 1797 CASE_MATHFN (BUILT_IN_HYPOT) 1798 CASE_MATHFN (BUILT_IN_ILOGB) 1799 CASE_MATHFN (BUILT_IN_INF) 1800 CASE_MATHFN (BUILT_IN_ISINF) 1801 CASE_MATHFN (BUILT_IN_J0) 1802 CASE_MATHFN (BUILT_IN_J1) 1803 CASE_MATHFN (BUILT_IN_JN) 1804 CASE_MATHFN (BUILT_IN_LCEIL) 1805 CASE_MATHFN (BUILT_IN_LDEXP) 1806 CASE_MATHFN (BUILT_IN_LFLOOR) 1807 CASE_MATHFN (BUILT_IN_LGAMMA) 1808 CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */ 1809 CASE_MATHFN (BUILT_IN_LLCEIL) 1810 CASE_MATHFN (BUILT_IN_LLFLOOR) 1811 CASE_MATHFN (BUILT_IN_LLRINT) 1812 CASE_MATHFN (BUILT_IN_LLROUND) 1813 CASE_MATHFN (BUILT_IN_LOG) 1814 CASE_MATHFN (BUILT_IN_LOG10) 1815 CASE_MATHFN (BUILT_IN_LOG1P) 1816 CASE_MATHFN (BUILT_IN_LOG2) 1817 CASE_MATHFN (BUILT_IN_LOGB) 1818 CASE_MATHFN (BUILT_IN_LRINT) 1819 CASE_MATHFN (BUILT_IN_LROUND) 1820 CASE_MATHFN (BUILT_IN_MODF) 1821 CASE_MATHFN (BUILT_IN_NAN) 1822 CASE_MATHFN (BUILT_IN_NANS) 1823 CASE_MATHFN (BUILT_IN_NEARBYINT) 1824 CASE_MATHFN (BUILT_IN_NEXTAFTER) 1825 CASE_MATHFN (BUILT_IN_NEXTTOWARD) 1826 CASE_MATHFN (BUILT_IN_POW) 1827 CASE_MATHFN (BUILT_IN_POWI) 1828 CASE_MATHFN (BUILT_IN_POW10) 1829 CASE_MATHFN (BUILT_IN_REMAINDER) 1830 CASE_MATHFN (BUILT_IN_REMQUO) 1831 CASE_MATHFN (BUILT_IN_RINT) 1832 CASE_MATHFN (BUILT_IN_ROUND) 1833 CASE_MATHFN (BUILT_IN_SCALB) 1834 CASE_MATHFN (BUILT_IN_SCALBLN) 1835 CASE_MATHFN (BUILT_IN_SCALBN) 1836 CASE_MATHFN (BUILT_IN_SIGNBIT) 1837 CASE_MATHFN (BUILT_IN_SIGNIFICAND) 1838 CASE_MATHFN (BUILT_IN_SIN) 1839 CASE_MATHFN (BUILT_IN_SINCOS) 1840 CASE_MATHFN (BUILT_IN_SINH) 1841 CASE_MATHFN (BUILT_IN_SQRT) 1842 CASE_MATHFN (BUILT_IN_TAN) 1843 CASE_MATHFN (BUILT_IN_TANH) 1844 CASE_MATHFN (BUILT_IN_TGAMMA) 1845 CASE_MATHFN (BUILT_IN_TRUNC) 1846 CASE_MATHFN (BUILT_IN_Y0) 1847 CASE_MATHFN (BUILT_IN_Y1) 1848 CASE_MATHFN (BUILT_IN_YN) 1849 1850 default: 1851 return NULL_TREE; 1852 } 1853 1854 if (TYPE_MAIN_VARIANT (type) == double_type_node) 1855 return fn_arr[fcode]; 1856 else if (TYPE_MAIN_VARIANT (type) == float_type_node) 1857 return fn_arr[fcodef]; 1858 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node) 1859 return fn_arr[fcodel]; 1860 else 1861 return NULL_TREE; 1862 } 1863 1864 /* Like mathfn_built_in_1(), but always use the implicit array. */ 1865 1866 tree 1867 mathfn_built_in (tree type, enum built_in_function fn) 1868 { 1869 return mathfn_built_in_1 (type, fn, /*implicit=*/ 1); 1870 } 1871 1872 /* If errno must be maintained, expand the RTL to check if the result, 1873 TARGET, of a built-in function call, EXP, is NaN, and if so set 1874 errno to EDOM. */ 1875 1876 static void 1877 expand_errno_check (tree exp, rtx target) 1878 { 1879 rtx lab = gen_label_rtx (); 1880 1881 /* Test the result; if it is NaN, set errno=EDOM because 1882 the argument was not in the domain. */ 1883 do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target), 1884 NULL_RTX, NULL_RTX, lab, 1885 /* The jump is very likely. */ 1886 REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1)); 1887 1888 #ifdef TARGET_EDOM 1889 /* If this built-in doesn't throw an exception, set errno directly. */ 1890 if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0))) 1891 { 1892 #ifdef GEN_ERRNO_RTX 1893 rtx errno_rtx = GEN_ERRNO_RTX; 1894 #else 1895 rtx errno_rtx 1896 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno")); 1897 #endif 1898 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM)); 1899 emit_label (lab); 1900 return; 1901 } 1902 #endif 1903 1904 /* Make sure the library call isn't expanded as a tail call. */ 1905 CALL_EXPR_TAILCALL (exp) = 0; 1906 1907 /* We can't set errno=EDOM directly; let the library call do it. 1908 Pop the arguments right away in case the call gets deleted. */ 1909 NO_DEFER_POP; 1910 expand_call (exp, target, 0); 1911 OK_DEFER_POP; 1912 emit_label (lab); 1913 } 1914 1915 /* Expand a call to one of the builtin math functions (sqrt, exp, or log). 1916 Return NULL_RTX if a normal call should be emitted rather than expanding 1917 the function in-line. EXP is the expression that is a call to the builtin 1918 function; if convenient, the result should be placed in TARGET. 1919 SUBTARGET may be used as the target for computing one of EXP's operands. */ 1920 1921 static rtx 1922 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) 1923 { 1924 optab builtin_optab; 1925 rtx op0, insns; 1926 tree fndecl = get_callee_fndecl (exp); 1927 enum machine_mode mode; 1928 bool errno_set = false; 1929 tree arg; 1930 1931 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 1932 return NULL_RTX; 1933 1934 arg = CALL_EXPR_ARG (exp, 0); 1935 1936 switch (DECL_FUNCTION_CODE (fndecl)) 1937 { 1938 CASE_FLT_FN (BUILT_IN_SQRT): 1939 errno_set = ! tree_expr_nonnegative_p (arg); 1940 builtin_optab = sqrt_optab; 1941 break; 1942 CASE_FLT_FN (BUILT_IN_EXP): 1943 errno_set = true; builtin_optab = exp_optab; break; 1944 CASE_FLT_FN (BUILT_IN_EXP10): 1945 CASE_FLT_FN (BUILT_IN_POW10): 1946 errno_set = true; builtin_optab = exp10_optab; break; 1947 CASE_FLT_FN (BUILT_IN_EXP2): 1948 errno_set = true; builtin_optab = exp2_optab; break; 1949 CASE_FLT_FN (BUILT_IN_EXPM1): 1950 errno_set = true; builtin_optab = expm1_optab; break; 1951 CASE_FLT_FN (BUILT_IN_LOGB): 1952 errno_set = true; builtin_optab = logb_optab; break; 1953 CASE_FLT_FN (BUILT_IN_LOG): 1954 errno_set = true; builtin_optab = log_optab; break; 1955 CASE_FLT_FN (BUILT_IN_LOG10): 1956 errno_set = true; builtin_optab = log10_optab; break; 1957 CASE_FLT_FN (BUILT_IN_LOG2): 1958 errno_set = true; builtin_optab = log2_optab; break; 1959 CASE_FLT_FN (BUILT_IN_LOG1P): 1960 errno_set = true; builtin_optab = log1p_optab; break; 1961 CASE_FLT_FN (BUILT_IN_ASIN): 1962 builtin_optab = asin_optab; break; 1963 CASE_FLT_FN (BUILT_IN_ACOS): 1964 builtin_optab = acos_optab; break; 1965 CASE_FLT_FN (BUILT_IN_TAN): 1966 builtin_optab = tan_optab; break; 1967 CASE_FLT_FN (BUILT_IN_ATAN): 1968 builtin_optab = atan_optab; break; 1969 CASE_FLT_FN (BUILT_IN_FLOOR): 1970 builtin_optab = floor_optab; break; 1971 CASE_FLT_FN (BUILT_IN_CEIL): 1972 builtin_optab = ceil_optab; break; 1973 CASE_FLT_FN (BUILT_IN_TRUNC): 1974 builtin_optab = btrunc_optab; break; 1975 CASE_FLT_FN (BUILT_IN_ROUND): 1976 builtin_optab = round_optab; break; 1977 CASE_FLT_FN (BUILT_IN_NEARBYINT): 1978 builtin_optab = nearbyint_optab; 1979 if (flag_trapping_math) 1980 break; 1981 /* Else fallthrough and expand as rint. */ 1982 CASE_FLT_FN (BUILT_IN_RINT): 1983 builtin_optab = rint_optab; break; 1984 CASE_FLT_FN (BUILT_IN_SIGNIFICAND): 1985 builtin_optab = significand_optab; break; 1986 default: 1987 gcc_unreachable (); 1988 } 1989 1990 /* Make a suitable register to place result in. */ 1991 mode = TYPE_MODE (TREE_TYPE (exp)); 1992 1993 if (! flag_errno_math || ! HONOR_NANS (mode)) 1994 errno_set = false; 1995 1996 /* Before working hard, check whether the instruction is available. */ 1997 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing) 1998 { 1999 target = gen_reg_rtx (mode); 2000 2001 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2002 need to expand the argument again. This way, we will not perform 2003 side-effects more the once. */ 2004 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 2005 2006 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 2007 2008 start_sequence (); 2009 2010 /* Compute into TARGET. 2011 Set TARGET to wherever the result comes back. */ 2012 target = expand_unop (mode, builtin_optab, op0, target, 0); 2013 2014 if (target != 0) 2015 { 2016 if (errno_set) 2017 expand_errno_check (exp, target); 2018 2019 /* Output the entire sequence. */ 2020 insns = get_insns (); 2021 end_sequence (); 2022 emit_insn (insns); 2023 return target; 2024 } 2025 2026 /* If we were unable to expand via the builtin, stop the sequence 2027 (without outputting the insns) and call to the library function 2028 with the stabilized argument list. */ 2029 end_sequence (); 2030 } 2031 2032 return expand_call (exp, target, target == const0_rtx); 2033 } 2034 2035 /* Expand a call to the builtin binary math functions (pow and atan2). 2036 Return NULL_RTX if a normal call should be emitted rather than expanding the 2037 function in-line. EXP is the expression that is a call to the builtin 2038 function; if convenient, the result should be placed in TARGET. 2039 SUBTARGET may be used as the target for computing one of EXP's 2040 operands. */ 2041 2042 static rtx 2043 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget) 2044 { 2045 optab builtin_optab; 2046 rtx op0, op1, insns; 2047 int op1_type = REAL_TYPE; 2048 tree fndecl = get_callee_fndecl (exp); 2049 tree arg0, arg1; 2050 enum machine_mode mode; 2051 bool errno_set = true; 2052 2053 switch (DECL_FUNCTION_CODE (fndecl)) 2054 { 2055 CASE_FLT_FN (BUILT_IN_SCALBN): 2056 CASE_FLT_FN (BUILT_IN_SCALBLN): 2057 CASE_FLT_FN (BUILT_IN_LDEXP): 2058 op1_type = INTEGER_TYPE; 2059 default: 2060 break; 2061 } 2062 2063 if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE)) 2064 return NULL_RTX; 2065 2066 arg0 = CALL_EXPR_ARG (exp, 0); 2067 arg1 = CALL_EXPR_ARG (exp, 1); 2068 2069 switch (DECL_FUNCTION_CODE (fndecl)) 2070 { 2071 CASE_FLT_FN (BUILT_IN_POW): 2072 builtin_optab = pow_optab; break; 2073 CASE_FLT_FN (BUILT_IN_ATAN2): 2074 builtin_optab = atan2_optab; break; 2075 CASE_FLT_FN (BUILT_IN_SCALB): 2076 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2) 2077 return 0; 2078 builtin_optab = scalb_optab; break; 2079 CASE_FLT_FN (BUILT_IN_SCALBN): 2080 CASE_FLT_FN (BUILT_IN_SCALBLN): 2081 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2) 2082 return 0; 2083 /* Fall through... */ 2084 CASE_FLT_FN (BUILT_IN_LDEXP): 2085 builtin_optab = ldexp_optab; break; 2086 CASE_FLT_FN (BUILT_IN_FMOD): 2087 builtin_optab = fmod_optab; break; 2088 CASE_FLT_FN (BUILT_IN_REMAINDER): 2089 CASE_FLT_FN (BUILT_IN_DREM): 2090 builtin_optab = remainder_optab; break; 2091 default: 2092 gcc_unreachable (); 2093 } 2094 2095 /* Make a suitable register to place result in. */ 2096 mode = TYPE_MODE (TREE_TYPE (exp)); 2097 2098 /* Before working hard, check whether the instruction is available. */ 2099 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing) 2100 return NULL_RTX; 2101 2102 target = gen_reg_rtx (mode); 2103 2104 if (! flag_errno_math || ! HONOR_NANS (mode)) 2105 errno_set = false; 2106 2107 /* Always stabilize the argument list. */ 2108 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0); 2109 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1); 2110 2111 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL); 2112 op1 = expand_normal (arg1); 2113 2114 start_sequence (); 2115 2116 /* Compute into TARGET. 2117 Set TARGET to wherever the result comes back. */ 2118 target = expand_binop (mode, builtin_optab, op0, op1, 2119 target, 0, OPTAB_DIRECT); 2120 2121 /* If we were unable to expand via the builtin, stop the sequence 2122 (without outputting the insns) and call to the library function 2123 with the stabilized argument list. */ 2124 if (target == 0) 2125 { 2126 end_sequence (); 2127 return expand_call (exp, target, target == const0_rtx); 2128 } 2129 2130 if (errno_set) 2131 expand_errno_check (exp, target); 2132 2133 /* Output the entire sequence. */ 2134 insns = get_insns (); 2135 end_sequence (); 2136 emit_insn (insns); 2137 2138 return target; 2139 } 2140 2141 /* Expand a call to the builtin sin and cos math functions. 2142 Return NULL_RTX if a normal call should be emitted rather than expanding the 2143 function in-line. EXP is the expression that is a call to the builtin 2144 function; if convenient, the result should be placed in TARGET. 2145 SUBTARGET may be used as the target for computing one of EXP's 2146 operands. */ 2147 2148 static rtx 2149 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget) 2150 { 2151 optab builtin_optab; 2152 rtx op0, insns; 2153 tree fndecl = get_callee_fndecl (exp); 2154 enum machine_mode mode; 2155 tree arg; 2156 2157 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2158 return NULL_RTX; 2159 2160 arg = CALL_EXPR_ARG (exp, 0); 2161 2162 switch (DECL_FUNCTION_CODE (fndecl)) 2163 { 2164 CASE_FLT_FN (BUILT_IN_SIN): 2165 CASE_FLT_FN (BUILT_IN_COS): 2166 builtin_optab = sincos_optab; break; 2167 default: 2168 gcc_unreachable (); 2169 } 2170 2171 /* Make a suitable register to place result in. */ 2172 mode = TYPE_MODE (TREE_TYPE (exp)); 2173 2174 /* Check if sincos insn is available, otherwise fallback 2175 to sin or cos insn. */ 2176 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing) 2177 switch (DECL_FUNCTION_CODE (fndecl)) 2178 { 2179 CASE_FLT_FN (BUILT_IN_SIN): 2180 builtin_optab = sin_optab; break; 2181 CASE_FLT_FN (BUILT_IN_COS): 2182 builtin_optab = cos_optab; break; 2183 default: 2184 gcc_unreachable (); 2185 } 2186 2187 /* Before working hard, check whether the instruction is available. */ 2188 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing) 2189 { 2190 target = gen_reg_rtx (mode); 2191 2192 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2193 need to expand the argument again. This way, we will not perform 2194 side-effects more the once. */ 2195 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 2196 2197 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 2198 2199 start_sequence (); 2200 2201 /* Compute into TARGET. 2202 Set TARGET to wherever the result comes back. */ 2203 if (builtin_optab == sincos_optab) 2204 { 2205 int result; 2206 2207 switch (DECL_FUNCTION_CODE (fndecl)) 2208 { 2209 CASE_FLT_FN (BUILT_IN_SIN): 2210 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0); 2211 break; 2212 CASE_FLT_FN (BUILT_IN_COS): 2213 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0); 2214 break; 2215 default: 2216 gcc_unreachable (); 2217 } 2218 gcc_assert (result); 2219 } 2220 else 2221 { 2222 target = expand_unop (mode, builtin_optab, op0, target, 0); 2223 } 2224 2225 if (target != 0) 2226 { 2227 /* Output the entire sequence. */ 2228 insns = get_insns (); 2229 end_sequence (); 2230 emit_insn (insns); 2231 return target; 2232 } 2233 2234 /* If we were unable to expand via the builtin, stop the sequence 2235 (without outputting the insns) and call to the library function 2236 with the stabilized argument list. */ 2237 end_sequence (); 2238 } 2239 2240 target = expand_call (exp, target, target == const0_rtx); 2241 2242 return target; 2243 } 2244 2245 /* Given an interclass math builtin decl FNDECL and it's argument ARG 2246 return an RTL instruction code that implements the functionality. 2247 If that isn't possible or available return CODE_FOR_nothing. */ 2248 2249 static enum insn_code 2250 interclass_mathfn_icode (tree arg, tree fndecl) 2251 { 2252 bool errno_set = false; 2253 optab builtin_optab = 0; 2254 enum machine_mode mode; 2255 2256 switch (DECL_FUNCTION_CODE (fndecl)) 2257 { 2258 CASE_FLT_FN (BUILT_IN_ILOGB): 2259 errno_set = true; builtin_optab = ilogb_optab; break; 2260 CASE_FLT_FN (BUILT_IN_ISINF): 2261 builtin_optab = isinf_optab; break; 2262 case BUILT_IN_ISNORMAL: 2263 case BUILT_IN_ISFINITE: 2264 CASE_FLT_FN (BUILT_IN_FINITE): 2265 case BUILT_IN_FINITED32: 2266 case BUILT_IN_FINITED64: 2267 case BUILT_IN_FINITED128: 2268 case BUILT_IN_ISINFD32: 2269 case BUILT_IN_ISINFD64: 2270 case BUILT_IN_ISINFD128: 2271 /* These builtins have no optabs (yet). */ 2272 break; 2273 default: 2274 gcc_unreachable (); 2275 } 2276 2277 /* There's no easy way to detect the case we need to set EDOM. */ 2278 if (flag_errno_math && errno_set) 2279 return CODE_FOR_nothing; 2280 2281 /* Optab mode depends on the mode of the input argument. */ 2282 mode = TYPE_MODE (TREE_TYPE (arg)); 2283 2284 if (builtin_optab) 2285 return optab_handler (builtin_optab, mode)->insn_code; 2286 return CODE_FOR_nothing; 2287 } 2288 2289 /* Expand a call to one of the builtin math functions that operate on 2290 floating point argument and output an integer result (ilogb, isinf, 2291 isnan, etc). 2292 Return 0 if a normal call should be emitted rather than expanding the 2293 function in-line. EXP is the expression that is a call to the builtin 2294 function; if convenient, the result should be placed in TARGET. */ 2295 2296 static rtx 2297 expand_builtin_interclass_mathfn (tree exp, rtx target) 2298 { 2299 enum insn_code icode = CODE_FOR_nothing; 2300 rtx op0; 2301 tree fndecl = get_callee_fndecl (exp); 2302 enum machine_mode mode; 2303 tree arg; 2304 2305 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2306 return NULL_RTX; 2307 2308 arg = CALL_EXPR_ARG (exp, 0); 2309 icode = interclass_mathfn_icode (arg, fndecl); 2310 mode = TYPE_MODE (TREE_TYPE (arg)); 2311 2312 if (icode != CODE_FOR_nothing) 2313 { 2314 rtx last = get_last_insn (); 2315 tree orig_arg = arg; 2316 /* Make a suitable register to place result in. */ 2317 if (!target 2318 || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)) 2319 || !insn_data[icode].operand[0].predicate (target, GET_MODE (target))) 2320 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp))); 2321 2322 gcc_assert (insn_data[icode].operand[0].predicate 2323 (target, GET_MODE (target))); 2324 2325 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2326 need to expand the argument again. This way, we will not perform 2327 side-effects more the once. */ 2328 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 2329 2330 op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL); 2331 2332 if (mode != GET_MODE (op0)) 2333 op0 = convert_to_mode (mode, op0, 0); 2334 2335 /* Compute into TARGET. 2336 Set TARGET to wherever the result comes back. */ 2337 if (maybe_emit_unop_insn (icode, target, op0, UNKNOWN)) 2338 return target; 2339 delete_insns_since (last); 2340 CALL_EXPR_ARG (exp, 0) = orig_arg; 2341 } 2342 2343 return NULL_RTX; 2344 } 2345 2346 /* Expand a call to the builtin sincos math function. 2347 Return NULL_RTX if a normal call should be emitted rather than expanding the 2348 function in-line. EXP is the expression that is a call to the builtin 2349 function. */ 2350 2351 static rtx 2352 expand_builtin_sincos (tree exp) 2353 { 2354 rtx op0, op1, op2, target1, target2; 2355 enum machine_mode mode; 2356 tree arg, sinp, cosp; 2357 int result; 2358 location_t loc = EXPR_LOCATION (exp); 2359 2360 if (!validate_arglist (exp, REAL_TYPE, 2361 POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 2362 return NULL_RTX; 2363 2364 arg = CALL_EXPR_ARG (exp, 0); 2365 sinp = CALL_EXPR_ARG (exp, 1); 2366 cosp = CALL_EXPR_ARG (exp, 2); 2367 2368 /* Make a suitable register to place result in. */ 2369 mode = TYPE_MODE (TREE_TYPE (arg)); 2370 2371 /* Check if sincos insn is available, otherwise emit the call. */ 2372 if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing) 2373 return NULL_RTX; 2374 2375 target1 = gen_reg_rtx (mode); 2376 target2 = gen_reg_rtx (mode); 2377 2378 op0 = expand_normal (arg); 2379 op1 = expand_normal (build_fold_indirect_ref_loc (loc, sinp)); 2380 op2 = expand_normal (build_fold_indirect_ref_loc (loc, cosp)); 2381 2382 /* Compute into target1 and target2. 2383 Set TARGET to wherever the result comes back. */ 2384 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0); 2385 gcc_assert (result); 2386 2387 /* Move target1 and target2 to the memory locations indicated 2388 by op1 and op2. */ 2389 emit_move_insn (op1, target1); 2390 emit_move_insn (op2, target2); 2391 2392 return const0_rtx; 2393 } 2394 2395 /* Expand a call to the internal cexpi builtin to the sincos math function. 2396 EXP is the expression that is a call to the builtin function; if convenient, 2397 the result should be placed in TARGET. */ 2398 2399 static rtx 2400 expand_builtin_cexpi (tree exp, rtx target) 2401 { 2402 tree fndecl = get_callee_fndecl (exp); 2403 tree arg, type; 2404 enum machine_mode mode; 2405 rtx op0, op1, op2; 2406 location_t loc = EXPR_LOCATION (exp); 2407 2408 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2409 return NULL_RTX; 2410 2411 arg = CALL_EXPR_ARG (exp, 0); 2412 type = TREE_TYPE (arg); 2413 mode = TYPE_MODE (TREE_TYPE (arg)); 2414 2415 /* Try expanding via a sincos optab, fall back to emitting a libcall 2416 to sincos or cexp. We are sure we have sincos or cexp because cexpi 2417 is only generated from sincos, cexp or if we have either of them. */ 2418 if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing) 2419 { 2420 op1 = gen_reg_rtx (mode); 2421 op2 = gen_reg_rtx (mode); 2422 2423 op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL); 2424 2425 /* Compute into op1 and op2. */ 2426 expand_twoval_unop (sincos_optab, op0, op2, op1, 0); 2427 } 2428 else if (TARGET_HAS_SINCOS) 2429 { 2430 tree call, fn = NULL_TREE; 2431 tree top1, top2; 2432 rtx op1a, op2a; 2433 2434 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF) 2435 fn = built_in_decls[BUILT_IN_SINCOSF]; 2436 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI) 2437 fn = built_in_decls[BUILT_IN_SINCOS]; 2438 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL) 2439 fn = built_in_decls[BUILT_IN_SINCOSL]; 2440 else 2441 gcc_unreachable (); 2442 2443 op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1); 2444 op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1); 2445 op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0)); 2446 op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0)); 2447 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a); 2448 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a); 2449 2450 /* Make sure not to fold the sincos call again. */ 2451 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); 2452 expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)), 2453 call, 3, arg, top1, top2)); 2454 } 2455 else 2456 { 2457 tree call, fn = NULL_TREE, narg; 2458 tree ctype = build_complex_type (type); 2459 2460 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF) 2461 fn = built_in_decls[BUILT_IN_CEXPF]; 2462 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI) 2463 fn = built_in_decls[BUILT_IN_CEXP]; 2464 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL) 2465 fn = built_in_decls[BUILT_IN_CEXPL]; 2466 else 2467 gcc_unreachable (); 2468 2469 /* If we don't have a decl for cexp create one. This is the 2470 friendliest fallback if the user calls __builtin_cexpi 2471 without full target C99 function support. */ 2472 if (fn == NULL_TREE) 2473 { 2474 tree fntype; 2475 const char *name = NULL; 2476 2477 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF) 2478 name = "cexpf"; 2479 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI) 2480 name = "cexp"; 2481 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL) 2482 name = "cexpl"; 2483 2484 fntype = build_function_type_list (ctype, ctype, NULL_TREE); 2485 fn = build_fn_decl (name, fntype); 2486 } 2487 2488 narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype, 2489 build_real (type, dconst0), arg); 2490 2491 /* Make sure not to fold the cexp call again. */ 2492 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); 2493 return expand_expr (build_call_nary (ctype, call, 1, narg), 2494 target, VOIDmode, EXPAND_NORMAL); 2495 } 2496 2497 /* Now build the proper return type. */ 2498 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type), 2499 make_tree (TREE_TYPE (arg), op2), 2500 make_tree (TREE_TYPE (arg), op1)), 2501 target, VOIDmode, EXPAND_NORMAL); 2502 } 2503 2504 /* Conveniently construct a function call expression. FNDECL names the 2505 function to be called, N is the number of arguments, and the "..." 2506 parameters are the argument expressions. Unlike build_call_exr 2507 this doesn't fold the call, hence it will always return a CALL_EXPR. */ 2508 2509 static tree 2510 build_call_nofold_loc (location_t loc, tree fndecl, int n, ...) 2511 { 2512 va_list ap; 2513 tree fntype = TREE_TYPE (fndecl); 2514 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl); 2515 2516 va_start (ap, n); 2517 fn = build_call_valist (TREE_TYPE (fntype), fn, n, ap); 2518 va_end (ap); 2519 SET_EXPR_LOCATION (fn, loc); 2520 return fn; 2521 } 2522 2523 /* Expand a call to one of the builtin rounding functions gcc defines 2524 as an extension (lfloor and lceil). As these are gcc extensions we 2525 do not need to worry about setting errno to EDOM. 2526 If expanding via optab fails, lower expression to (int)(floor(x)). 2527 EXP is the expression that is a call to the builtin function; 2528 if convenient, the result should be placed in TARGET. */ 2529 2530 static rtx 2531 expand_builtin_int_roundingfn (tree exp, rtx target) 2532 { 2533 convert_optab builtin_optab; 2534 rtx op0, insns, tmp; 2535 tree fndecl = get_callee_fndecl (exp); 2536 enum built_in_function fallback_fn; 2537 tree fallback_fndecl; 2538 enum machine_mode mode; 2539 tree arg; 2540 2541 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2542 gcc_unreachable (); 2543 2544 arg = CALL_EXPR_ARG (exp, 0); 2545 2546 switch (DECL_FUNCTION_CODE (fndecl)) 2547 { 2548 CASE_FLT_FN (BUILT_IN_LCEIL): 2549 CASE_FLT_FN (BUILT_IN_LLCEIL): 2550 builtin_optab = lceil_optab; 2551 fallback_fn = BUILT_IN_CEIL; 2552 break; 2553 2554 CASE_FLT_FN (BUILT_IN_LFLOOR): 2555 CASE_FLT_FN (BUILT_IN_LLFLOOR): 2556 builtin_optab = lfloor_optab; 2557 fallback_fn = BUILT_IN_FLOOR; 2558 break; 2559 2560 default: 2561 gcc_unreachable (); 2562 } 2563 2564 /* Make a suitable register to place result in. */ 2565 mode = TYPE_MODE (TREE_TYPE (exp)); 2566 2567 target = gen_reg_rtx (mode); 2568 2569 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2570 need to expand the argument again. This way, we will not perform 2571 side-effects more the once. */ 2572 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 2573 2574 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL); 2575 2576 start_sequence (); 2577 2578 /* Compute into TARGET. */ 2579 if (expand_sfix_optab (target, op0, builtin_optab)) 2580 { 2581 /* Output the entire sequence. */ 2582 insns = get_insns (); 2583 end_sequence (); 2584 emit_insn (insns); 2585 return target; 2586 } 2587 2588 /* If we were unable to expand via the builtin, stop the sequence 2589 (without outputting the insns). */ 2590 end_sequence (); 2591 2592 /* Fall back to floating point rounding optab. */ 2593 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn); 2594 2595 /* For non-C99 targets we may end up without a fallback fndecl here 2596 if the user called __builtin_lfloor directly. In this case emit 2597 a call to the floor/ceil variants nevertheless. This should result 2598 in the best user experience for not full C99 targets. */ 2599 if (fallback_fndecl == NULL_TREE) 2600 { 2601 tree fntype; 2602 const char *name = NULL; 2603 2604 switch (DECL_FUNCTION_CODE (fndecl)) 2605 { 2606 case BUILT_IN_LCEIL: 2607 case BUILT_IN_LLCEIL: 2608 name = "ceil"; 2609 break; 2610 case BUILT_IN_LCEILF: 2611 case BUILT_IN_LLCEILF: 2612 name = "ceilf"; 2613 break; 2614 case BUILT_IN_LCEILL: 2615 case BUILT_IN_LLCEILL: 2616 name = "ceill"; 2617 break; 2618 case BUILT_IN_LFLOOR: 2619 case BUILT_IN_LLFLOOR: 2620 name = "floor"; 2621 break; 2622 case BUILT_IN_LFLOORF: 2623 case BUILT_IN_LLFLOORF: 2624 name = "floorf"; 2625 break; 2626 case BUILT_IN_LFLOORL: 2627 case BUILT_IN_LLFLOORL: 2628 name = "floorl"; 2629 break; 2630 default: 2631 gcc_unreachable (); 2632 } 2633 2634 fntype = build_function_type_list (TREE_TYPE (arg), 2635 TREE_TYPE (arg), NULL_TREE); 2636 fallback_fndecl = build_fn_decl (name, fntype); 2637 } 2638 2639 exp = build_call_nofold_loc (EXPR_LOCATION (exp), fallback_fndecl, 1, arg); 2640 2641 tmp = expand_normal (exp); 2642 2643 /* Truncate the result of floating point optab to integer 2644 via expand_fix (). */ 2645 target = gen_reg_rtx (mode); 2646 expand_fix (target, tmp, 0); 2647 2648 return target; 2649 } 2650 2651 /* Expand a call to one of the builtin math functions doing integer 2652 conversion (lrint). 2653 Return 0 if a normal call should be emitted rather than expanding the 2654 function in-line. EXP is the expression that is a call to the builtin 2655 function; if convenient, the result should be placed in TARGET. */ 2656 2657 static rtx 2658 expand_builtin_int_roundingfn_2 (tree exp, rtx target) 2659 { 2660 convert_optab builtin_optab; 2661 rtx op0, insns; 2662 tree fndecl = get_callee_fndecl (exp); 2663 tree arg; 2664 enum machine_mode mode; 2665 2666 /* There's no easy way to detect the case we need to set EDOM. */ 2667 if (flag_errno_math) 2668 return NULL_RTX; 2669 2670 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 2671 gcc_unreachable (); 2672 2673 arg = CALL_EXPR_ARG (exp, 0); 2674 2675 switch (DECL_FUNCTION_CODE (fndecl)) 2676 { 2677 CASE_FLT_FN (BUILT_IN_LRINT): 2678 CASE_FLT_FN (BUILT_IN_LLRINT): 2679 builtin_optab = lrint_optab; break; 2680 CASE_FLT_FN (BUILT_IN_LROUND): 2681 CASE_FLT_FN (BUILT_IN_LLROUND): 2682 builtin_optab = lround_optab; break; 2683 default: 2684 gcc_unreachable (); 2685 } 2686 2687 /* Make a suitable register to place result in. */ 2688 mode = TYPE_MODE (TREE_TYPE (exp)); 2689 2690 target = gen_reg_rtx (mode); 2691 2692 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2693 need to expand the argument again. This way, we will not perform 2694 side-effects more the once. */ 2695 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 2696 2697 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL); 2698 2699 start_sequence (); 2700 2701 if (expand_sfix_optab (target, op0, builtin_optab)) 2702 { 2703 /* Output the entire sequence. */ 2704 insns = get_insns (); 2705 end_sequence (); 2706 emit_insn (insns); 2707 return target; 2708 } 2709 2710 /* If we were unable to expand via the builtin, stop the sequence 2711 (without outputting the insns) and call to the library function 2712 with the stabilized argument list. */ 2713 end_sequence (); 2714 2715 target = expand_call (exp, target, target == const0_rtx); 2716 2717 return target; 2718 } 2719 2720 /* To evaluate powi(x,n), the floating point value x raised to the 2721 constant integer exponent n, we use a hybrid algorithm that 2722 combines the "window method" with look-up tables. For an 2723 introduction to exponentiation algorithms and "addition chains", 2724 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth, 2725 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming", 2726 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation 2727 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */ 2728 2729 /* Provide a default value for POWI_MAX_MULTS, the maximum number of 2730 multiplications to inline before calling the system library's pow 2731 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications, 2732 so this default never requires calling pow, powf or powl. */ 2733 2734 #ifndef POWI_MAX_MULTS 2735 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2) 2736 #endif 2737 2738 /* The size of the "optimal power tree" lookup table. All 2739 exponents less than this value are simply looked up in the 2740 powi_table below. This threshold is also used to size the 2741 cache of pseudo registers that hold intermediate results. */ 2742 #define POWI_TABLE_SIZE 256 2743 2744 /* The size, in bits of the window, used in the "window method" 2745 exponentiation algorithm. This is equivalent to a radix of 2746 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */ 2747 #define POWI_WINDOW_SIZE 3 2748 2749 /* The following table is an efficient representation of an 2750 "optimal power tree". For each value, i, the corresponding 2751 value, j, in the table states than an optimal evaluation 2752 sequence for calculating pow(x,i) can be found by evaluating 2753 pow(x,j)*pow(x,i-j). An optimal power tree for the first 2754 100 integers is given in Knuth's "Seminumerical algorithms". */ 2755 2756 static const unsigned char powi_table[POWI_TABLE_SIZE] = 2757 { 2758 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */ 2759 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */ 2760 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */ 2761 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */ 2762 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */ 2763 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */ 2764 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */ 2765 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */ 2766 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */ 2767 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */ 2768 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */ 2769 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */ 2770 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */ 2771 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */ 2772 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */ 2773 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */ 2774 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */ 2775 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */ 2776 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */ 2777 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */ 2778 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */ 2779 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */ 2780 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */ 2781 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */ 2782 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */ 2783 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */ 2784 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */ 2785 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */ 2786 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */ 2787 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */ 2788 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */ 2789 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */ 2790 }; 2791 2792 2793 /* Return the number of multiplications required to calculate 2794 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a 2795 subroutine of powi_cost. CACHE is an array indicating 2796 which exponents have already been calculated. */ 2797 2798 static int 2799 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache) 2800 { 2801 /* If we've already calculated this exponent, then this evaluation 2802 doesn't require any additional multiplications. */ 2803 if (cache[n]) 2804 return 0; 2805 2806 cache[n] = true; 2807 return powi_lookup_cost (n - powi_table[n], cache) 2808 + powi_lookup_cost (powi_table[n], cache) + 1; 2809 } 2810 2811 /* Return the number of multiplications required to calculate 2812 powi(x,n) for an arbitrary x, given the exponent N. This 2813 function needs to be kept in sync with expand_powi below. */ 2814 2815 static int 2816 powi_cost (HOST_WIDE_INT n) 2817 { 2818 bool cache[POWI_TABLE_SIZE]; 2819 unsigned HOST_WIDE_INT digit; 2820 unsigned HOST_WIDE_INT val; 2821 int result; 2822 2823 if (n == 0) 2824 return 0; 2825 2826 /* Ignore the reciprocal when calculating the cost. */ 2827 val = (n < 0) ? -n : n; 2828 2829 /* Initialize the exponent cache. */ 2830 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool)); 2831 cache[1] = true; 2832 2833 result = 0; 2834 2835 while (val >= POWI_TABLE_SIZE) 2836 { 2837 if (val & 1) 2838 { 2839 digit = val & ((1 << POWI_WINDOW_SIZE) - 1); 2840 result += powi_lookup_cost (digit, cache) 2841 + POWI_WINDOW_SIZE + 1; 2842 val >>= POWI_WINDOW_SIZE; 2843 } 2844 else 2845 { 2846 val >>= 1; 2847 result++; 2848 } 2849 } 2850 2851 return result + powi_lookup_cost (val, cache); 2852 } 2853 2854 /* Recursive subroutine of expand_powi. This function takes the array, 2855 CACHE, of already calculated exponents and an exponent N and returns 2856 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */ 2857 2858 static rtx 2859 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache) 2860 { 2861 unsigned HOST_WIDE_INT digit; 2862 rtx target, result; 2863 rtx op0, op1; 2864 2865 if (n < POWI_TABLE_SIZE) 2866 { 2867 if (cache[n]) 2868 return cache[n]; 2869 2870 target = gen_reg_rtx (mode); 2871 cache[n] = target; 2872 2873 op0 = expand_powi_1 (mode, n - powi_table[n], cache); 2874 op1 = expand_powi_1 (mode, powi_table[n], cache); 2875 } 2876 else if (n & 1) 2877 { 2878 target = gen_reg_rtx (mode); 2879 digit = n & ((1 << POWI_WINDOW_SIZE) - 1); 2880 op0 = expand_powi_1 (mode, n - digit, cache); 2881 op1 = expand_powi_1 (mode, digit, cache); 2882 } 2883 else 2884 { 2885 target = gen_reg_rtx (mode); 2886 op0 = expand_powi_1 (mode, n >> 1, cache); 2887 op1 = op0; 2888 } 2889 2890 result = expand_mult (mode, op0, op1, target, 0); 2891 if (result != target) 2892 emit_move_insn (target, result); 2893 return target; 2894 } 2895 2896 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the 2897 floating point operand in mode MODE, and N is the exponent. This 2898 function needs to be kept in sync with powi_cost above. */ 2899 2900 static rtx 2901 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n) 2902 { 2903 rtx cache[POWI_TABLE_SIZE]; 2904 rtx result; 2905 2906 if (n == 0) 2907 return CONST1_RTX (mode); 2908 2909 memset (cache, 0, sizeof (cache)); 2910 cache[1] = x; 2911 2912 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache); 2913 2914 /* If the original exponent was negative, reciprocate the result. */ 2915 if (n < 0) 2916 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode), 2917 result, NULL_RTX, 0, OPTAB_LIB_WIDEN); 2918 2919 return result; 2920 } 2921 2922 /* Expand a call to the pow built-in mathematical function. Return NULL_RTX if 2923 a normal call should be emitted rather than expanding the function 2924 in-line. EXP is the expression that is a call to the builtin 2925 function; if convenient, the result should be placed in TARGET. */ 2926 2927 static rtx 2928 expand_builtin_pow (tree exp, rtx target, rtx subtarget) 2929 { 2930 tree arg0, arg1; 2931 tree fn, narg0; 2932 tree type = TREE_TYPE (exp); 2933 REAL_VALUE_TYPE cint, c, c2; 2934 HOST_WIDE_INT n; 2935 rtx op, op2; 2936 enum machine_mode mode = TYPE_MODE (type); 2937 2938 if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 2939 return NULL_RTX; 2940 2941 arg0 = CALL_EXPR_ARG (exp, 0); 2942 arg1 = CALL_EXPR_ARG (exp, 1); 2943 2944 if (TREE_CODE (arg1) != REAL_CST 2945 || TREE_OVERFLOW (arg1)) 2946 return expand_builtin_mathfn_2 (exp, target, subtarget); 2947 2948 /* Handle constant exponents. */ 2949 2950 /* For integer valued exponents we can expand to an optimal multiplication 2951 sequence using expand_powi. */ 2952 c = TREE_REAL_CST (arg1); 2953 n = real_to_integer (&c); 2954 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); 2955 if (real_identical (&c, &cint) 2956 && ((n >= -1 && n <= 2) 2957 || (flag_unsafe_math_optimizations 2958 && optimize_insn_for_speed_p () 2959 && powi_cost (n) <= POWI_MAX_MULTS))) 2960 { 2961 op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL); 2962 if (n != 1) 2963 { 2964 op = force_reg (mode, op); 2965 op = expand_powi (op, mode, n); 2966 } 2967 return op; 2968 } 2969 2970 narg0 = builtin_save_expr (arg0); 2971 2972 /* If the exponent is not integer valued, check if it is half of an integer. 2973 In this case we can expand to sqrt (x) * x**(n/2). */ 2974 fn = mathfn_built_in (type, BUILT_IN_SQRT); 2975 if (fn != NULL_TREE) 2976 { 2977 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2); 2978 n = real_to_integer (&c2); 2979 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); 2980 if (real_identical (&c2, &cint) 2981 && ((flag_unsafe_math_optimizations 2982 && optimize_insn_for_speed_p () 2983 && powi_cost (n/2) <= POWI_MAX_MULTS) 2984 /* Even the c == 0.5 case cannot be done unconditionally 2985 when we need to preserve signed zeros, as 2986 pow (-0, 0.5) is +0, while sqrt(-0) is -0. */ 2987 || (!HONOR_SIGNED_ZEROS (mode) && n == 1) 2988 /* For c == 1.5 we can assume that x * sqrt (x) is always 2989 smaller than pow (x, 1.5) if sqrt will not be expanded 2990 as a call. */ 2991 || (n == 3 2992 && (optab_handler (sqrt_optab, mode)->insn_code 2993 != CODE_FOR_nothing)))) 2994 { 2995 tree call_expr = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 1, 2996 narg0); 2997 /* Use expand_expr in case the newly built call expression 2998 was folded to a non-call. */ 2999 op = expand_expr (call_expr, subtarget, mode, EXPAND_NORMAL); 3000 if (n != 1) 3001 { 3002 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL); 3003 op2 = force_reg (mode, op2); 3004 op2 = expand_powi (op2, mode, abs (n / 2)); 3005 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX, 3006 0, OPTAB_LIB_WIDEN); 3007 /* If the original exponent was negative, reciprocate the 3008 result. */ 3009 if (n < 0) 3010 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode), 3011 op, NULL_RTX, 0, OPTAB_LIB_WIDEN); 3012 } 3013 return op; 3014 } 3015 } 3016 3017 /* Try if the exponent is a third of an integer. In this case 3018 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is 3019 different from pow (x, 1./3.) due to rounding and behavior 3020 with negative x we need to constrain this transformation to 3021 unsafe math and positive x or finite math. */ 3022 fn = mathfn_built_in (type, BUILT_IN_CBRT); 3023 if (fn != NULL_TREE 3024 && flag_unsafe_math_optimizations 3025 && (tree_expr_nonnegative_p (arg0) 3026 || !HONOR_NANS (mode))) 3027 { 3028 REAL_VALUE_TYPE dconst3; 3029 real_from_integer (&dconst3, VOIDmode, 3, 0, 0); 3030 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3); 3031 real_round (&c2, mode, &c2); 3032 n = real_to_integer (&c2); 3033 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); 3034 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3); 3035 real_convert (&c2, mode, &c2); 3036 if (real_identical (&c2, &c) 3037 && ((optimize_insn_for_speed_p () 3038 && powi_cost (n/3) <= POWI_MAX_MULTS) 3039 || n == 1)) 3040 { 3041 tree call_expr = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 1, 3042 narg0); 3043 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0); 3044 if (abs (n) % 3 == 2) 3045 op = expand_simple_binop (mode, MULT, op, op, op, 3046 0, OPTAB_LIB_WIDEN); 3047 if (n != 1) 3048 { 3049 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL); 3050 op2 = force_reg (mode, op2); 3051 op2 = expand_powi (op2, mode, abs (n / 3)); 3052 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX, 3053 0, OPTAB_LIB_WIDEN); 3054 /* If the original exponent was negative, reciprocate the 3055 result. */ 3056 if (n < 0) 3057 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode), 3058 op, NULL_RTX, 0, OPTAB_LIB_WIDEN); 3059 } 3060 return op; 3061 } 3062 } 3063 3064 /* Fall back to optab expansion. */ 3065 return expand_builtin_mathfn_2 (exp, target, subtarget); 3066 } 3067 3068 /* Expand a call to the powi built-in mathematical function. Return NULL_RTX if 3069 a normal call should be emitted rather than expanding the function 3070 in-line. EXP is the expression that is a call to the builtin 3071 function; if convenient, the result should be placed in TARGET. */ 3072 3073 static rtx 3074 expand_builtin_powi (tree exp, rtx target) 3075 { 3076 tree arg0, arg1; 3077 rtx op0, op1; 3078 enum machine_mode mode; 3079 enum machine_mode mode2; 3080 3081 if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE)) 3082 return NULL_RTX; 3083 3084 arg0 = CALL_EXPR_ARG (exp, 0); 3085 arg1 = CALL_EXPR_ARG (exp, 1); 3086 mode = TYPE_MODE (TREE_TYPE (exp)); 3087 3088 /* Handle constant power. */ 3089 3090 if (TREE_CODE (arg1) == INTEGER_CST 3091 && !TREE_OVERFLOW (arg1)) 3092 { 3093 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1); 3094 3095 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact. 3096 Otherwise, check the number of multiplications required. */ 3097 if ((TREE_INT_CST_HIGH (arg1) == 0 3098 || TREE_INT_CST_HIGH (arg1) == -1) 3099 && ((n >= -1 && n <= 2) 3100 || (optimize_insn_for_speed_p () 3101 && powi_cost (n) <= POWI_MAX_MULTS))) 3102 { 3103 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); 3104 op0 = force_reg (mode, op0); 3105 return expand_powi (op0, mode, n); 3106 } 3107 } 3108 3109 /* Emit a libcall to libgcc. */ 3110 3111 /* Mode of the 2nd argument must match that of an int. */ 3112 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0); 3113 3114 if (target == NULL_RTX) 3115 target = gen_reg_rtx (mode); 3116 3117 op0 = expand_expr (arg0, NULL_RTX, mode, EXPAND_NORMAL); 3118 if (GET_MODE (op0) != mode) 3119 op0 = convert_to_mode (mode, op0, 0); 3120 op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL); 3121 if (GET_MODE (op1) != mode2) 3122 op1 = convert_to_mode (mode2, op1, 0); 3123 3124 target = emit_library_call_value (optab_libfunc (powi_optab, mode), 3125 target, LCT_CONST, mode, 2, 3126 op0, mode, op1, mode2); 3127 3128 return target; 3129 } 3130 3131 /* Expand expression EXP which is a call to the strlen builtin. Return 3132 NULL_RTX if we failed the caller should emit a normal call, otherwise 3133 try to get the result in TARGET, if convenient. */ 3134 3135 static rtx 3136 expand_builtin_strlen (tree exp, rtx target, 3137 enum machine_mode target_mode) 3138 { 3139 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 3140 return NULL_RTX; 3141 else 3142 { 3143 rtx pat; 3144 tree len; 3145 tree src = CALL_EXPR_ARG (exp, 0); 3146 rtx result, src_reg, char_rtx, before_strlen; 3147 enum machine_mode insn_mode = target_mode, char_mode; 3148 enum insn_code icode = CODE_FOR_nothing; 3149 int align; 3150 3151 /* If the length can be computed at compile-time, return it. */ 3152 len = c_strlen (src, 0); 3153 if (len) 3154 return expand_expr (len, target, target_mode, EXPAND_NORMAL); 3155 3156 /* If the length can be computed at compile-time and is constant 3157 integer, but there are side-effects in src, evaluate 3158 src for side-effects, then return len. 3159 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar"); 3160 can be optimized into: i++; x = 3; */ 3161 len = c_strlen (src, 1); 3162 if (len && TREE_CODE (len) == INTEGER_CST) 3163 { 3164 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL); 3165 return expand_expr (len, target, target_mode, EXPAND_NORMAL); 3166 } 3167 3168 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3169 3170 /* If SRC is not a pointer type, don't do this operation inline. */ 3171 if (align == 0) 3172 return NULL_RTX; 3173 3174 /* Bail out if we can't compute strlen in the right mode. */ 3175 while (insn_mode != VOIDmode) 3176 { 3177 icode = optab_handler (strlen_optab, insn_mode)->insn_code; 3178 if (icode != CODE_FOR_nothing) 3179 break; 3180 3181 insn_mode = GET_MODE_WIDER_MODE (insn_mode); 3182 } 3183 if (insn_mode == VOIDmode) 3184 return NULL_RTX; 3185 3186 /* Make a place to write the result of the instruction. */ 3187 result = target; 3188 if (! (result != 0 3189 && REG_P (result) 3190 && GET_MODE (result) == insn_mode 3191 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 3192 result = gen_reg_rtx (insn_mode); 3193 3194 /* Make a place to hold the source address. We will not expand 3195 the actual source until we are sure that the expansion will 3196 not fail -- there are trees that cannot be expanded twice. */ 3197 src_reg = gen_reg_rtx (Pmode); 3198 3199 /* Mark the beginning of the strlen sequence so we can emit the 3200 source operand later. */ 3201 before_strlen = get_last_insn (); 3202 3203 char_rtx = const0_rtx; 3204 char_mode = insn_data[(int) icode].operand[2].mode; 3205 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx, 3206 char_mode)) 3207 char_rtx = copy_to_mode_reg (char_mode, char_rtx); 3208 3209 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg), 3210 char_rtx, GEN_INT (align)); 3211 if (! pat) 3212 return NULL_RTX; 3213 emit_insn (pat); 3214 3215 /* Now that we are assured of success, expand the source. */ 3216 start_sequence (); 3217 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL); 3218 if (pat != src_reg) 3219 emit_move_insn (src_reg, pat); 3220 pat = get_insns (); 3221 end_sequence (); 3222 3223 if (before_strlen) 3224 emit_insn_after (pat, before_strlen); 3225 else 3226 emit_insn_before (pat, get_insns ()); 3227 3228 /* Return the value in the proper mode for this function. */ 3229 if (GET_MODE (result) == target_mode) 3230 target = result; 3231 else if (target != 0) 3232 convert_move (target, result, 0); 3233 else 3234 target = convert_to_mode (target_mode, result, 0); 3235 3236 return target; 3237 } 3238 } 3239 3240 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 3241 bytes from constant string DATA + OFFSET and return it as target 3242 constant. */ 3243 3244 static rtx 3245 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset, 3246 enum machine_mode mode) 3247 { 3248 const char *str = (const char *) data; 3249 3250 gcc_assert (offset >= 0 3251 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode) 3252 <= strlen (str) + 1)); 3253 3254 return c_readstr (str + offset, mode); 3255 } 3256 3257 /* Expand a call EXP to the memcpy builtin. 3258 Return NULL_RTX if we failed, the caller should emit a normal call, 3259 otherwise try to get the result in TARGET, if convenient (and in 3260 mode MODE if that's convenient). */ 3261 3262 static rtx 3263 expand_builtin_memcpy (tree exp, rtx target) 3264 { 3265 if (!validate_arglist (exp, 3266 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3267 return NULL_RTX; 3268 else 3269 { 3270 tree dest = CALL_EXPR_ARG (exp, 0); 3271 tree src = CALL_EXPR_ARG (exp, 1); 3272 tree len = CALL_EXPR_ARG (exp, 2); 3273 const char *src_str; 3274 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 3275 unsigned int dest_align 3276 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 3277 rtx dest_mem, src_mem, dest_addr, len_rtx; 3278 HOST_WIDE_INT expected_size = -1; 3279 unsigned int expected_align = 0; 3280 3281 /* If DEST is not a pointer type, call the normal function. */ 3282 if (dest_align == 0) 3283 return NULL_RTX; 3284 3285 /* If either SRC is not a pointer type, don't do this 3286 operation in-line. */ 3287 if (src_align == 0) 3288 return NULL_RTX; 3289 3290 if (currently_expanding_gimple_stmt) 3291 stringop_block_profile (currently_expanding_gimple_stmt, 3292 &expected_align, &expected_size); 3293 3294 if (expected_align < dest_align) 3295 expected_align = dest_align; 3296 dest_mem = get_memory_rtx (dest, len); 3297 set_mem_align (dest_mem, dest_align); 3298 len_rtx = expand_normal (len); 3299 src_str = c_getstr (src); 3300 3301 /* If SRC is a string constant and block move would be done 3302 by pieces, we can avoid loading the string from memory 3303 and only stored the computed constants. */ 3304 if (src_str 3305 && CONST_INT_P (len_rtx) 3306 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1 3307 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str, 3308 CONST_CAST (char *, src_str), 3309 dest_align, false)) 3310 { 3311 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx), 3312 builtin_memcpy_read_str, 3313 CONST_CAST (char *, src_str), 3314 dest_align, false, 0); 3315 dest_mem = force_operand (XEXP (dest_mem, 0), target); 3316 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3317 return dest_mem; 3318 } 3319 3320 src_mem = get_memory_rtx (src, len); 3321 set_mem_align (src_mem, src_align); 3322 3323 /* Copy word part most expediently. */ 3324 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, 3325 CALL_EXPR_TAILCALL (exp) 3326 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL, 3327 expected_align, expected_size); 3328 3329 if (dest_addr == 0) 3330 { 3331 dest_addr = force_operand (XEXP (dest_mem, 0), target); 3332 dest_addr = convert_memory_address (ptr_mode, dest_addr); 3333 } 3334 return dest_addr; 3335 } 3336 } 3337 3338 /* Expand a call EXP to the mempcpy builtin. 3339 Return NULL_RTX if we failed; the caller should emit a normal call, 3340 otherwise try to get the result in TARGET, if convenient (and in 3341 mode MODE if that's convenient). If ENDP is 0 return the 3342 destination pointer, if ENDP is 1 return the end pointer ala 3343 mempcpy, and if ENDP is 2 return the end pointer minus one ala 3344 stpcpy. */ 3345 3346 static rtx 3347 expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode) 3348 { 3349 if (!validate_arglist (exp, 3350 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3351 return NULL_RTX; 3352 else 3353 { 3354 tree dest = CALL_EXPR_ARG (exp, 0); 3355 tree src = CALL_EXPR_ARG (exp, 1); 3356 tree len = CALL_EXPR_ARG (exp, 2); 3357 return expand_builtin_mempcpy_args (dest, src, len, 3358 target, mode, /*endp=*/ 1); 3359 } 3360 } 3361 3362 /* Helper function to do the actual work for expand_builtin_mempcpy. The 3363 arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out 3364 so that this can also be called without constructing an actual CALL_EXPR. 3365 The other arguments and return value are the same as for 3366 expand_builtin_mempcpy. */ 3367 3368 static rtx 3369 expand_builtin_mempcpy_args (tree dest, tree src, tree len, 3370 rtx target, enum machine_mode mode, int endp) 3371 { 3372 /* If return value is ignored, transform mempcpy into memcpy. */ 3373 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_MEMCPY]) 3374 { 3375 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 3376 tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3, 3377 dest, src, len); 3378 return expand_expr (result, target, mode, EXPAND_NORMAL); 3379 } 3380 else 3381 { 3382 const char *src_str; 3383 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 3384 unsigned int dest_align 3385 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 3386 rtx dest_mem, src_mem, len_rtx; 3387 3388 /* If either SRC or DEST is not a pointer type, don't do this 3389 operation in-line. */ 3390 if (dest_align == 0 || src_align == 0) 3391 return NULL_RTX; 3392 3393 /* If LEN is not constant, call the normal function. */ 3394 if (! host_integerp (len, 1)) 3395 return NULL_RTX; 3396 3397 len_rtx = expand_normal (len); 3398 src_str = c_getstr (src); 3399 3400 /* If SRC is a string constant and block move would be done 3401 by pieces, we can avoid loading the string from memory 3402 and only stored the computed constants. */ 3403 if (src_str 3404 && CONST_INT_P (len_rtx) 3405 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1 3406 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str, 3407 CONST_CAST (char *, src_str), 3408 dest_align, false)) 3409 { 3410 dest_mem = get_memory_rtx (dest, len); 3411 set_mem_align (dest_mem, dest_align); 3412 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx), 3413 builtin_memcpy_read_str, 3414 CONST_CAST (char *, src_str), 3415 dest_align, false, endp); 3416 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3417 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3418 return dest_mem; 3419 } 3420 3421 if (CONST_INT_P (len_rtx) 3422 && can_move_by_pieces (INTVAL (len_rtx), 3423 MIN (dest_align, src_align))) 3424 { 3425 dest_mem = get_memory_rtx (dest, len); 3426 set_mem_align (dest_mem, dest_align); 3427 src_mem = get_memory_rtx (src, len); 3428 set_mem_align (src_mem, src_align); 3429 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx), 3430 MIN (dest_align, src_align), endp); 3431 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3432 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3433 return dest_mem; 3434 } 3435 3436 return NULL_RTX; 3437 } 3438 } 3439 3440 #ifndef HAVE_movstr 3441 # define HAVE_movstr 0 3442 # define CODE_FOR_movstr CODE_FOR_nothing 3443 #endif 3444 3445 /* Expand into a movstr instruction, if one is available. Return NULL_RTX if 3446 we failed, the caller should emit a normal call, otherwise try to 3447 get the result in TARGET, if convenient. If ENDP is 0 return the 3448 destination pointer, if ENDP is 1 return the end pointer ala 3449 mempcpy, and if ENDP is 2 return the end pointer minus one ala 3450 stpcpy. */ 3451 3452 static rtx 3453 expand_movstr (tree dest, tree src, rtx target, int endp) 3454 { 3455 rtx end; 3456 rtx dest_mem; 3457 rtx src_mem; 3458 rtx insn; 3459 const struct insn_data * data; 3460 3461 if (!HAVE_movstr) 3462 return NULL_RTX; 3463 3464 dest_mem = get_memory_rtx (dest, NULL); 3465 src_mem = get_memory_rtx (src, NULL); 3466 data = insn_data + CODE_FOR_movstr; 3467 if (!endp) 3468 { 3469 target = force_reg (Pmode, XEXP (dest_mem, 0)); 3470 dest_mem = replace_equiv_address (dest_mem, target); 3471 end = gen_reg_rtx (Pmode); 3472 } 3473 else 3474 { 3475 if (target == 0 3476 || target == const0_rtx 3477 || ! (*data->operand[0].predicate) (target, Pmode)) 3478 { 3479 end = gen_reg_rtx (Pmode); 3480 if (target != const0_rtx) 3481 target = end; 3482 } 3483 else 3484 end = target; 3485 } 3486 3487 if (data->operand[0].mode != VOIDmode) 3488 end = gen_lowpart (data->operand[0].mode, end); 3489 3490 insn = data->genfun (end, dest_mem, src_mem); 3491 3492 gcc_assert (insn); 3493 3494 emit_insn (insn); 3495 3496 /* movstr is supposed to set end to the address of the NUL 3497 terminator. If the caller requested a mempcpy-like return value, 3498 adjust it. */ 3499 if (endp == 1 && target != const0_rtx) 3500 { 3501 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1); 3502 emit_move_insn (target, force_operand (tem, NULL_RTX)); 3503 } 3504 3505 return target; 3506 } 3507 3508 /* Expand expression EXP, which is a call to the strcpy builtin. Return 3509 NULL_RTX if we failed the caller should emit a normal call, otherwise 3510 try to get the result in TARGET, if convenient (and in mode MODE if that's 3511 convenient). */ 3512 3513 static rtx 3514 expand_builtin_strcpy (tree exp, rtx target) 3515 { 3516 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3517 { 3518 tree dest = CALL_EXPR_ARG (exp, 0); 3519 tree src = CALL_EXPR_ARG (exp, 1); 3520 return expand_builtin_strcpy_args (dest, src, target); 3521 } 3522 return NULL_RTX; 3523 } 3524 3525 /* Helper function to do the actual work for expand_builtin_strcpy. The 3526 arguments to the builtin_strcpy call DEST and SRC are broken out 3527 so that this can also be called without constructing an actual CALL_EXPR. 3528 The other arguments and return value are the same as for 3529 expand_builtin_strcpy. */ 3530 3531 static rtx 3532 expand_builtin_strcpy_args (tree dest, tree src, rtx target) 3533 { 3534 return expand_movstr (dest, src, target, /*endp=*/0); 3535 } 3536 3537 /* Expand a call EXP to the stpcpy builtin. 3538 Return NULL_RTX if we failed the caller should emit a normal call, 3539 otherwise try to get the result in TARGET, if convenient (and in 3540 mode MODE if that's convenient). */ 3541 3542 static rtx 3543 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode) 3544 { 3545 tree dst, src; 3546 location_t loc = EXPR_LOCATION (exp); 3547 3548 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3549 return NULL_RTX; 3550 3551 dst = CALL_EXPR_ARG (exp, 0); 3552 src = CALL_EXPR_ARG (exp, 1); 3553 3554 /* If return value is ignored, transform stpcpy into strcpy. */ 3555 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_STRCPY]) 3556 { 3557 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 3558 tree result = build_call_nofold_loc (loc, fn, 2, dst, src); 3559 return expand_expr (result, target, mode, EXPAND_NORMAL); 3560 } 3561 else 3562 { 3563 tree len, lenp1; 3564 rtx ret; 3565 3566 /* Ensure we get an actual string whose length can be evaluated at 3567 compile-time, not an expression containing a string. This is 3568 because the latter will potentially produce pessimized code 3569 when used to produce the return value. */ 3570 if (! c_getstr (src) || ! (len = c_strlen (src, 0))) 3571 return expand_movstr (dst, src, target, /*endp=*/2); 3572 3573 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1)); 3574 ret = expand_builtin_mempcpy_args (dst, src, lenp1, 3575 target, mode, /*endp=*/2); 3576 3577 if (ret) 3578 return ret; 3579 3580 if (TREE_CODE (len) == INTEGER_CST) 3581 { 3582 rtx len_rtx = expand_normal (len); 3583 3584 if (CONST_INT_P (len_rtx)) 3585 { 3586 ret = expand_builtin_strcpy_args (dst, src, target); 3587 3588 if (ret) 3589 { 3590 if (! target) 3591 { 3592 if (mode != VOIDmode) 3593 target = gen_reg_rtx (mode); 3594 else 3595 target = gen_reg_rtx (GET_MODE (ret)); 3596 } 3597 if (GET_MODE (target) != GET_MODE (ret)) 3598 ret = gen_lowpart (GET_MODE (target), ret); 3599 3600 ret = plus_constant (ret, INTVAL (len_rtx)); 3601 ret = emit_move_insn (target, force_operand (ret, NULL_RTX)); 3602 gcc_assert (ret); 3603 3604 return target; 3605 } 3606 } 3607 } 3608 3609 return expand_movstr (dst, src, target, /*endp=*/2); 3610 } 3611 } 3612 3613 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 3614 bytes from constant string DATA + OFFSET and return it as target 3615 constant. */ 3616 3617 rtx 3618 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset, 3619 enum machine_mode mode) 3620 { 3621 const char *str = (const char *) data; 3622 3623 if ((unsigned HOST_WIDE_INT) offset > strlen (str)) 3624 return const0_rtx; 3625 3626 return c_readstr (str + offset, mode); 3627 } 3628 3629 /* Expand expression EXP, which is a call to the strncpy builtin. Return 3630 NULL_RTX if we failed the caller should emit a normal call. */ 3631 3632 static rtx 3633 expand_builtin_strncpy (tree exp, rtx target) 3634 { 3635 location_t loc = EXPR_LOCATION (exp); 3636 3637 if (validate_arglist (exp, 3638 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3639 { 3640 tree dest = CALL_EXPR_ARG (exp, 0); 3641 tree src = CALL_EXPR_ARG (exp, 1); 3642 tree len = CALL_EXPR_ARG (exp, 2); 3643 tree slen = c_strlen (src, 1); 3644 3645 /* We must be passed a constant len and src parameter. */ 3646 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1)) 3647 return NULL_RTX; 3648 3649 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1)); 3650 3651 /* We're required to pad with trailing zeros if the requested 3652 len is greater than strlen(s2)+1. In that case try to 3653 use store_by_pieces, if it fails, punt. */ 3654 if (tree_int_cst_lt (slen, len)) 3655 { 3656 unsigned int dest_align 3657 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 3658 const char *p = c_getstr (src); 3659 rtx dest_mem; 3660 3661 if (!p || dest_align == 0 || !host_integerp (len, 1) 3662 || !can_store_by_pieces (tree_low_cst (len, 1), 3663 builtin_strncpy_read_str, 3664 CONST_CAST (char *, p), 3665 dest_align, false)) 3666 return NULL_RTX; 3667 3668 dest_mem = get_memory_rtx (dest, len); 3669 store_by_pieces (dest_mem, tree_low_cst (len, 1), 3670 builtin_strncpy_read_str, 3671 CONST_CAST (char *, p), dest_align, false, 0); 3672 dest_mem = force_operand (XEXP (dest_mem, 0), target); 3673 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3674 return dest_mem; 3675 } 3676 } 3677 return NULL_RTX; 3678 } 3679 3680 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 3681 bytes from constant string DATA + OFFSET and return it as target 3682 constant. */ 3683 3684 rtx 3685 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED, 3686 enum machine_mode mode) 3687 { 3688 const char *c = (const char *) data; 3689 char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode)); 3690 3691 memset (p, *c, GET_MODE_SIZE (mode)); 3692 3693 return c_readstr (p, mode); 3694 } 3695 3696 /* Callback routine for store_by_pieces. Return the RTL of a register 3697 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned 3698 char value given in the RTL register data. For example, if mode is 3699 4 bytes wide, return the RTL for 0x01010101*data. */ 3700 3701 static rtx 3702 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED, 3703 enum machine_mode mode) 3704 { 3705 rtx target, coeff; 3706 size_t size; 3707 char *p; 3708 3709 size = GET_MODE_SIZE (mode); 3710 if (size == 1) 3711 return (rtx) data; 3712 3713 p = XALLOCAVEC (char, size); 3714 memset (p, 1, size); 3715 coeff = c_readstr (p, mode); 3716 3717 target = convert_to_mode (mode, (rtx) data, 1); 3718 target = expand_mult (mode, target, coeff, NULL_RTX, 1); 3719 return force_reg (mode, target); 3720 } 3721 3722 /* Expand expression EXP, which is a call to the memset builtin. Return 3723 NULL_RTX if we failed the caller should emit a normal call, otherwise 3724 try to get the result in TARGET, if convenient (and in mode MODE if that's 3725 convenient). */ 3726 3727 static rtx 3728 expand_builtin_memset (tree exp, rtx target, enum machine_mode mode) 3729 { 3730 if (!validate_arglist (exp, 3731 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3732 return NULL_RTX; 3733 else 3734 { 3735 tree dest = CALL_EXPR_ARG (exp, 0); 3736 tree val = CALL_EXPR_ARG (exp, 1); 3737 tree len = CALL_EXPR_ARG (exp, 2); 3738 return expand_builtin_memset_args (dest, val, len, target, mode, exp); 3739 } 3740 } 3741 3742 /* Helper function to do the actual work for expand_builtin_memset. The 3743 arguments to the builtin_memset call DEST, VAL, and LEN are broken out 3744 so that this can also be called without constructing an actual CALL_EXPR. 3745 The other arguments and return value are the same as for 3746 expand_builtin_memset. */ 3747 3748 static rtx 3749 expand_builtin_memset_args (tree dest, tree val, tree len, 3750 rtx target, enum machine_mode mode, tree orig_exp) 3751 { 3752 tree fndecl, fn; 3753 enum built_in_function fcode; 3754 char c; 3755 unsigned int dest_align; 3756 rtx dest_mem, dest_addr, len_rtx; 3757 HOST_WIDE_INT expected_size = -1; 3758 unsigned int expected_align = 0; 3759 3760 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 3761 3762 /* If DEST is not a pointer type, don't do this operation in-line. */ 3763 if (dest_align == 0) 3764 return NULL_RTX; 3765 3766 if (currently_expanding_gimple_stmt) 3767 stringop_block_profile (currently_expanding_gimple_stmt, 3768 &expected_align, &expected_size); 3769 3770 if (expected_align < dest_align) 3771 expected_align = dest_align; 3772 3773 /* If the LEN parameter is zero, return DEST. */ 3774 if (integer_zerop (len)) 3775 { 3776 /* Evaluate and ignore VAL in case it has side-effects. */ 3777 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL); 3778 return expand_expr (dest, target, mode, EXPAND_NORMAL); 3779 } 3780 3781 /* Stabilize the arguments in case we fail. */ 3782 dest = builtin_save_expr (dest); 3783 val = builtin_save_expr (val); 3784 len = builtin_save_expr (len); 3785 3786 len_rtx = expand_normal (len); 3787 dest_mem = get_memory_rtx (dest, len); 3788 3789 if (TREE_CODE (val) != INTEGER_CST) 3790 { 3791 rtx val_rtx; 3792 3793 val_rtx = expand_normal (val); 3794 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node), 3795 val_rtx, 0); 3796 3797 /* Assume that we can memset by pieces if we can store 3798 * the coefficients by pieces (in the required modes). 3799 * We can't pass builtin_memset_gen_str as that emits RTL. */ 3800 c = 1; 3801 if (host_integerp (len, 1) 3802 && can_store_by_pieces (tree_low_cst (len, 1), 3803 builtin_memset_read_str, &c, dest_align, 3804 true)) 3805 { 3806 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node), 3807 val_rtx); 3808 store_by_pieces (dest_mem, tree_low_cst (len, 1), 3809 builtin_memset_gen_str, val_rtx, dest_align, 3810 true, 0); 3811 } 3812 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx, 3813 dest_align, expected_align, 3814 expected_size)) 3815 goto do_libcall; 3816 3817 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3818 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3819 return dest_mem; 3820 } 3821 3822 if (target_char_cast (val, &c)) 3823 goto do_libcall; 3824 3825 if (c) 3826 { 3827 if (host_integerp (len, 1) 3828 && can_store_by_pieces (tree_low_cst (len, 1), 3829 builtin_memset_read_str, &c, dest_align, 3830 true)) 3831 store_by_pieces (dest_mem, tree_low_cst (len, 1), 3832 builtin_memset_read_str, &c, dest_align, true, 0); 3833 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c), 3834 dest_align, expected_align, 3835 expected_size)) 3836 goto do_libcall; 3837 3838 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3839 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3840 return dest_mem; 3841 } 3842 3843 set_mem_align (dest_mem, dest_align); 3844 dest_addr = clear_storage_hints (dest_mem, len_rtx, 3845 CALL_EXPR_TAILCALL (orig_exp) 3846 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL, 3847 expected_align, expected_size); 3848 3849 if (dest_addr == 0) 3850 { 3851 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3852 dest_addr = convert_memory_address (ptr_mode, dest_addr); 3853 } 3854 3855 return dest_addr; 3856 3857 do_libcall: 3858 fndecl = get_callee_fndecl (orig_exp); 3859 fcode = DECL_FUNCTION_CODE (fndecl); 3860 if (fcode == BUILT_IN_MEMSET) 3861 fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3, 3862 dest, val, len); 3863 else if (fcode == BUILT_IN_BZERO) 3864 fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 2, 3865 dest, len); 3866 else 3867 gcc_unreachable (); 3868 gcc_assert (TREE_CODE (fn) == CALL_EXPR); 3869 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp); 3870 return expand_call (fn, target, target == const0_rtx); 3871 } 3872 3873 /* Expand expression EXP, which is a call to the bzero builtin. Return 3874 NULL_RTX if we failed the caller should emit a normal call. */ 3875 3876 static rtx 3877 expand_builtin_bzero (tree exp) 3878 { 3879 tree dest, size; 3880 location_t loc = EXPR_LOCATION (exp); 3881 3882 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3883 return NULL_RTX; 3884 3885 dest = CALL_EXPR_ARG (exp, 0); 3886 size = CALL_EXPR_ARG (exp, 1); 3887 3888 /* New argument list transforming bzero(ptr x, int y) to 3889 memset(ptr x, int 0, size_t y). This is done this way 3890 so that if it isn't expanded inline, we fallback to 3891 calling bzero instead of memset. */ 3892 3893 return expand_builtin_memset_args (dest, integer_zero_node, 3894 fold_convert_loc (loc, sizetype, size), 3895 const0_rtx, VOIDmode, exp); 3896 } 3897 3898 /* Expand expression EXP, which is a call to the memcmp built-in function. 3899 Return NULL_RTX if we failed and the caller should emit a normal call, 3900 otherwise try to get the result in TARGET, if convenient (and in mode 3901 MODE, if that's convenient). */ 3902 3903 static rtx 3904 expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target, 3905 ATTRIBUTE_UNUSED enum machine_mode mode) 3906 { 3907 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp); 3908 3909 if (!validate_arglist (exp, 3910 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3911 return NULL_RTX; 3912 3913 /* Note: The cmpstrnsi pattern, if it exists, is not suitable for 3914 implementing memcmp because it will stop if it encounters two 3915 zero bytes. */ 3916 #if defined HAVE_cmpmemsi 3917 { 3918 rtx arg1_rtx, arg2_rtx, arg3_rtx; 3919 rtx result; 3920 rtx insn; 3921 tree arg1 = CALL_EXPR_ARG (exp, 0); 3922 tree arg2 = CALL_EXPR_ARG (exp, 1); 3923 tree len = CALL_EXPR_ARG (exp, 2); 3924 3925 int arg1_align 3926 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3927 int arg2_align 3928 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3929 enum machine_mode insn_mode; 3930 3931 if (HAVE_cmpmemsi) 3932 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode; 3933 else 3934 return NULL_RTX; 3935 3936 /* If we don't have POINTER_TYPE, call the function. */ 3937 if (arg1_align == 0 || arg2_align == 0) 3938 return NULL_RTX; 3939 3940 /* Make a place to write the result of the instruction. */ 3941 result = target; 3942 if (! (result != 0 3943 && REG_P (result) && GET_MODE (result) == insn_mode 3944 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 3945 result = gen_reg_rtx (insn_mode); 3946 3947 arg1_rtx = get_memory_rtx (arg1, len); 3948 arg2_rtx = get_memory_rtx (arg2, len); 3949 arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len)); 3950 3951 /* Set MEM_SIZE as appropriate. */ 3952 if (CONST_INT_P (arg3_rtx)) 3953 { 3954 set_mem_size (arg1_rtx, arg3_rtx); 3955 set_mem_size (arg2_rtx, arg3_rtx); 3956 } 3957 3958 if (HAVE_cmpmemsi) 3959 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 3960 GEN_INT (MIN (arg1_align, arg2_align))); 3961 else 3962 gcc_unreachable (); 3963 3964 if (insn) 3965 emit_insn (insn); 3966 else 3967 emit_library_call_value (memcmp_libfunc, result, LCT_PURE, 3968 TYPE_MODE (integer_type_node), 3, 3969 XEXP (arg1_rtx, 0), Pmode, 3970 XEXP (arg2_rtx, 0), Pmode, 3971 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx, 3972 TYPE_UNSIGNED (sizetype)), 3973 TYPE_MODE (sizetype)); 3974 3975 /* Return the value in the proper mode for this function. */ 3976 mode = TYPE_MODE (TREE_TYPE (exp)); 3977 if (GET_MODE (result) == mode) 3978 return result; 3979 else if (target != 0) 3980 { 3981 convert_move (target, result, 0); 3982 return target; 3983 } 3984 else 3985 return convert_to_mode (mode, result, 0); 3986 } 3987 #endif /* HAVE_cmpmemsi. */ 3988 3989 return NULL_RTX; 3990 } 3991 3992 /* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX 3993 if we failed the caller should emit a normal call, otherwise try to get 3994 the result in TARGET, if convenient. */ 3995 3996 static rtx 3997 expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) 3998 { 3999 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 4000 return NULL_RTX; 4001 4002 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi 4003 if (cmpstr_optab[SImode] != CODE_FOR_nothing 4004 || cmpstrn_optab[SImode] != CODE_FOR_nothing) 4005 { 4006 rtx arg1_rtx, arg2_rtx; 4007 rtx result, insn = NULL_RTX; 4008 tree fndecl, fn; 4009 tree arg1 = CALL_EXPR_ARG (exp, 0); 4010 tree arg2 = CALL_EXPR_ARG (exp, 1); 4011 4012 int arg1_align 4013 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 4014 int arg2_align 4015 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 4016 4017 /* If we don't have POINTER_TYPE, call the function. */ 4018 if (arg1_align == 0 || arg2_align == 0) 4019 return NULL_RTX; 4020 4021 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */ 4022 arg1 = builtin_save_expr (arg1); 4023 arg2 = builtin_save_expr (arg2); 4024 4025 arg1_rtx = get_memory_rtx (arg1, NULL); 4026 arg2_rtx = get_memory_rtx (arg2, NULL); 4027 4028 #ifdef HAVE_cmpstrsi 4029 /* Try to call cmpstrsi. */ 4030 if (HAVE_cmpstrsi) 4031 { 4032 enum machine_mode insn_mode 4033 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode; 4034 4035 /* Make a place to write the result of the instruction. */ 4036 result = target; 4037 if (! (result != 0 4038 && REG_P (result) && GET_MODE (result) == insn_mode 4039 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 4040 result = gen_reg_rtx (insn_mode); 4041 4042 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, 4043 GEN_INT (MIN (arg1_align, arg2_align))); 4044 } 4045 #endif 4046 #ifdef HAVE_cmpstrnsi 4047 /* Try to determine at least one length and call cmpstrnsi. */ 4048 if (!insn && HAVE_cmpstrnsi) 4049 { 4050 tree len; 4051 rtx arg3_rtx; 4052 4053 enum machine_mode insn_mode 4054 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode; 4055 tree len1 = c_strlen (arg1, 1); 4056 tree len2 = c_strlen (arg2, 1); 4057 4058 if (len1) 4059 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1); 4060 if (len2) 4061 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2); 4062 4063 /* If we don't have a constant length for the first, use the length 4064 of the second, if we know it. We don't require a constant for 4065 this case; some cost analysis could be done if both are available 4066 but neither is constant. For now, assume they're equally cheap, 4067 unless one has side effects. If both strings have constant lengths, 4068 use the smaller. */ 4069 4070 if (!len1) 4071 len = len2; 4072 else if (!len2) 4073 len = len1; 4074 else if (TREE_SIDE_EFFECTS (len1)) 4075 len = len2; 4076 else if (TREE_SIDE_EFFECTS (len2)) 4077 len = len1; 4078 else if (TREE_CODE (len1) != INTEGER_CST) 4079 len = len2; 4080 else if (TREE_CODE (len2) != INTEGER_CST) 4081 len = len1; 4082 else if (tree_int_cst_lt (len1, len2)) 4083 len = len1; 4084 else 4085 len = len2; 4086 4087 /* If both arguments have side effects, we cannot optimize. */ 4088 if (!len || TREE_SIDE_EFFECTS (len)) 4089 goto do_libcall; 4090 4091 arg3_rtx = expand_normal (len); 4092 4093 /* Make a place to write the result of the instruction. */ 4094 result = target; 4095 if (! (result != 0 4096 && REG_P (result) && GET_MODE (result) == insn_mode 4097 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 4098 result = gen_reg_rtx (insn_mode); 4099 4100 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 4101 GEN_INT (MIN (arg1_align, arg2_align))); 4102 } 4103 #endif 4104 4105 if (insn) 4106 { 4107 enum machine_mode mode; 4108 emit_insn (insn); 4109 4110 /* Return the value in the proper mode for this function. */ 4111 mode = TYPE_MODE (TREE_TYPE (exp)); 4112 if (GET_MODE (result) == mode) 4113 return result; 4114 if (target == 0) 4115 return convert_to_mode (mode, result, 0); 4116 convert_move (target, result, 0); 4117 return target; 4118 } 4119 4120 /* Expand the library call ourselves using a stabilized argument 4121 list to avoid re-evaluating the function's arguments twice. */ 4122 #ifdef HAVE_cmpstrnsi 4123 do_libcall: 4124 #endif 4125 fndecl = get_callee_fndecl (exp); 4126 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2); 4127 gcc_assert (TREE_CODE (fn) == CALL_EXPR); 4128 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 4129 return expand_call (fn, target, target == const0_rtx); 4130 } 4131 #endif 4132 return NULL_RTX; 4133 } 4134 4135 /* Expand expression EXP, which is a call to the strncmp builtin. Return 4136 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get 4137 the result in TARGET, if convenient. */ 4138 4139 static rtx 4140 expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, 4141 ATTRIBUTE_UNUSED enum machine_mode mode) 4142 { 4143 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp); 4144 4145 if (!validate_arglist (exp, 4146 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 4147 return NULL_RTX; 4148 4149 /* If c_strlen can determine an expression for one of the string 4150 lengths, and it doesn't have side effects, then emit cmpstrnsi 4151 using length MIN(strlen(string)+1, arg3). */ 4152 #ifdef HAVE_cmpstrnsi 4153 if (HAVE_cmpstrnsi) 4154 { 4155 tree len, len1, len2; 4156 rtx arg1_rtx, arg2_rtx, arg3_rtx; 4157 rtx result, insn; 4158 tree fndecl, fn; 4159 tree arg1 = CALL_EXPR_ARG (exp, 0); 4160 tree arg2 = CALL_EXPR_ARG (exp, 1); 4161 tree arg3 = CALL_EXPR_ARG (exp, 2); 4162 4163 int arg1_align 4164 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 4165 int arg2_align 4166 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 4167 enum machine_mode insn_mode 4168 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode; 4169 4170 len1 = c_strlen (arg1, 1); 4171 len2 = c_strlen (arg2, 1); 4172 4173 if (len1) 4174 len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1); 4175 if (len2) 4176 len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2); 4177 4178 /* If we don't have a constant length for the first, use the length 4179 of the second, if we know it. We don't require a constant for 4180 this case; some cost analysis could be done if both are available 4181 but neither is constant. For now, assume they're equally cheap, 4182 unless one has side effects. If both strings have constant lengths, 4183 use the smaller. */ 4184 4185 if (!len1) 4186 len = len2; 4187 else if (!len2) 4188 len = len1; 4189 else if (TREE_SIDE_EFFECTS (len1)) 4190 len = len2; 4191 else if (TREE_SIDE_EFFECTS (len2)) 4192 len = len1; 4193 else if (TREE_CODE (len1) != INTEGER_CST) 4194 len = len2; 4195 else if (TREE_CODE (len2) != INTEGER_CST) 4196 len = len1; 4197 else if (tree_int_cst_lt (len1, len2)) 4198 len = len1; 4199 else 4200 len = len2; 4201 4202 /* If both arguments have side effects, we cannot optimize. */ 4203 if (!len || TREE_SIDE_EFFECTS (len)) 4204 return NULL_RTX; 4205 4206 /* The actual new length parameter is MIN(len,arg3). */ 4207 len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len, 4208 fold_convert_loc (loc, TREE_TYPE (len), arg3)); 4209 4210 /* If we don't have POINTER_TYPE, call the function. */ 4211 if (arg1_align == 0 || arg2_align == 0) 4212 return NULL_RTX; 4213 4214 /* Make a place to write the result of the instruction. */ 4215 result = target; 4216 if (! (result != 0 4217 && REG_P (result) && GET_MODE (result) == insn_mode 4218 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 4219 result = gen_reg_rtx (insn_mode); 4220 4221 /* Stabilize the arguments in case gen_cmpstrnsi fails. */ 4222 arg1 = builtin_save_expr (arg1); 4223 arg2 = builtin_save_expr (arg2); 4224 len = builtin_save_expr (len); 4225 4226 arg1_rtx = get_memory_rtx (arg1, len); 4227 arg2_rtx = get_memory_rtx (arg2, len); 4228 arg3_rtx = expand_normal (len); 4229 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 4230 GEN_INT (MIN (arg1_align, arg2_align))); 4231 if (insn) 4232 { 4233 emit_insn (insn); 4234 4235 /* Return the value in the proper mode for this function. */ 4236 mode = TYPE_MODE (TREE_TYPE (exp)); 4237 if (GET_MODE (result) == mode) 4238 return result; 4239 if (target == 0) 4240 return convert_to_mode (mode, result, 0); 4241 convert_move (target, result, 0); 4242 return target; 4243 } 4244 4245 /* Expand the library call ourselves using a stabilized argument 4246 list to avoid re-evaluating the function's arguments twice. */ 4247 fndecl = get_callee_fndecl (exp); 4248 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 3, 4249 arg1, arg2, len); 4250 gcc_assert (TREE_CODE (fn) == CALL_EXPR); 4251 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 4252 return expand_call (fn, target, target == const0_rtx); 4253 } 4254 #endif 4255 return NULL_RTX; 4256 } 4257 4258 /* Expand a call to __builtin_saveregs, generating the result in TARGET, 4259 if that's convenient. */ 4260 4261 rtx 4262 expand_builtin_saveregs (void) 4263 { 4264 rtx val, seq; 4265 4266 /* Don't do __builtin_saveregs more than once in a function. 4267 Save the result of the first call and reuse it. */ 4268 if (saveregs_value != 0) 4269 return saveregs_value; 4270 4271 /* When this function is called, it means that registers must be 4272 saved on entry to this function. So we migrate the call to the 4273 first insn of this function. */ 4274 4275 start_sequence (); 4276 4277 /* Do whatever the machine needs done in this case. */ 4278 val = targetm.calls.expand_builtin_saveregs (); 4279 4280 seq = get_insns (); 4281 end_sequence (); 4282 4283 saveregs_value = val; 4284 4285 /* Put the insns after the NOTE that starts the function. If this 4286 is inside a start_sequence, make the outer-level insn chain current, so 4287 the code is placed at the start of the function. */ 4288 push_topmost_sequence (); 4289 emit_insn_after (seq, entry_of_function ()); 4290 pop_topmost_sequence (); 4291 4292 return val; 4293 } 4294 4295 /* __builtin_args_info (N) returns word N of the arg space info 4296 for the current function. The number and meanings of words 4297 is controlled by the definition of CUMULATIVE_ARGS. */ 4298 4299 static rtx 4300 expand_builtin_args_info (tree exp) 4301 { 4302 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int); 4303 int *word_ptr = (int *) &crtl->args.info; 4304 4305 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0); 4306 4307 if (call_expr_nargs (exp) != 0) 4308 { 4309 if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0)) 4310 error ("argument of %<__builtin_args_info%> must be constant"); 4311 else 4312 { 4313 HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0); 4314 4315 if (wordnum < 0 || wordnum >= nwords) 4316 error ("argument of %<__builtin_args_info%> out of range"); 4317 else 4318 return GEN_INT (word_ptr[wordnum]); 4319 } 4320 } 4321 else 4322 error ("missing argument in %<__builtin_args_info%>"); 4323 4324 return const0_rtx; 4325 } 4326 4327 /* Expand a call to __builtin_next_arg. */ 4328 4329 static rtx 4330 expand_builtin_next_arg (void) 4331 { 4332 /* Checking arguments is already done in fold_builtin_next_arg 4333 that must be called before this function. */ 4334 return expand_binop (ptr_mode, add_optab, 4335 crtl->args.internal_arg_pointer, 4336 crtl->args.arg_offset_rtx, 4337 NULL_RTX, 0, OPTAB_LIB_WIDEN); 4338 } 4339 4340 /* Make it easier for the backends by protecting the valist argument 4341 from multiple evaluations. */ 4342 4343 static tree 4344 stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue) 4345 { 4346 tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist)); 4347 4348 gcc_assert (vatype != NULL_TREE); 4349 4350 if (TREE_CODE (vatype) == ARRAY_TYPE) 4351 { 4352 if (TREE_SIDE_EFFECTS (valist)) 4353 valist = save_expr (valist); 4354 4355 /* For this case, the backends will be expecting a pointer to 4356 vatype, but it's possible we've actually been given an array 4357 (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)). 4358 So fix it. */ 4359 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE) 4360 { 4361 tree p1 = build_pointer_type (TREE_TYPE (vatype)); 4362 valist = build_fold_addr_expr_with_type_loc (loc, valist, p1); 4363 } 4364 } 4365 else 4366 { 4367 tree pt; 4368 4369 if (! needs_lvalue) 4370 { 4371 if (! TREE_SIDE_EFFECTS (valist)) 4372 return valist; 4373 4374 pt = build_pointer_type (vatype); 4375 valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist); 4376 TREE_SIDE_EFFECTS (valist) = 1; 4377 } 4378 4379 if (TREE_SIDE_EFFECTS (valist)) 4380 valist = save_expr (valist); 4381 valist = build_fold_indirect_ref_loc (loc, valist); 4382 } 4383 4384 return valist; 4385 } 4386 4387 /* The "standard" definition of va_list is void*. */ 4388 4389 tree 4390 std_build_builtin_va_list (void) 4391 { 4392 return ptr_type_node; 4393 } 4394 4395 /* The "standard" abi va_list is va_list_type_node. */ 4396 4397 tree 4398 std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED) 4399 { 4400 return va_list_type_node; 4401 } 4402 4403 /* The "standard" type of va_list is va_list_type_node. */ 4404 4405 tree 4406 std_canonical_va_list_type (tree type) 4407 { 4408 tree wtype, htype; 4409 4410 if (INDIRECT_REF_P (type)) 4411 type = TREE_TYPE (type); 4412 else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type))) 4413 type = TREE_TYPE (type); 4414 wtype = va_list_type_node; 4415 htype = type; 4416 /* Treat structure va_list types. */ 4417 if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype)) 4418 htype = TREE_TYPE (htype); 4419 else if (TREE_CODE (wtype) == ARRAY_TYPE) 4420 { 4421 /* If va_list is an array type, the argument may have decayed 4422 to a pointer type, e.g. by being passed to another function. 4423 In that case, unwrap both types so that we can compare the 4424 underlying records. */ 4425 if (TREE_CODE (htype) == ARRAY_TYPE 4426 || POINTER_TYPE_P (htype)) 4427 { 4428 wtype = TREE_TYPE (wtype); 4429 htype = TREE_TYPE (htype); 4430 } 4431 } 4432 if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype)) 4433 return va_list_type_node; 4434 4435 return NULL_TREE; 4436 } 4437 4438 /* The "standard" implementation of va_start: just assign `nextarg' to 4439 the variable. */ 4440 4441 void 4442 std_expand_builtin_va_start (tree valist, rtx nextarg) 4443 { 4444 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE); 4445 convert_move (va_r, nextarg, 0); 4446 } 4447 4448 /* Expand EXP, a call to __builtin_va_start. */ 4449 4450 static rtx 4451 expand_builtin_va_start (tree exp) 4452 { 4453 rtx nextarg; 4454 tree valist; 4455 location_t loc = EXPR_LOCATION (exp); 4456 4457 if (call_expr_nargs (exp) < 2) 4458 { 4459 error_at (loc, "too few arguments to function %<va_start%>"); 4460 return const0_rtx; 4461 } 4462 4463 if (fold_builtin_next_arg (exp, true)) 4464 return const0_rtx; 4465 4466 nextarg = expand_builtin_next_arg (); 4467 valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1); 4468 4469 if (targetm.expand_builtin_va_start) 4470 targetm.expand_builtin_va_start (valist, nextarg); 4471 else 4472 std_expand_builtin_va_start (valist, nextarg); 4473 4474 return const0_rtx; 4475 } 4476 4477 /* The "standard" implementation of va_arg: read the value from the 4478 current (padded) address and increment by the (padded) size. */ 4479 4480 tree 4481 std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, 4482 gimple_seq *post_p) 4483 { 4484 tree addr, t, type_size, rounded_size, valist_tmp; 4485 unsigned HOST_WIDE_INT align, boundary; 4486 bool indirect; 4487 4488 #ifdef ARGS_GROW_DOWNWARD 4489 /* All of the alignment and movement below is for args-grow-up machines. 4490 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all 4491 implement their own specialized gimplify_va_arg_expr routines. */ 4492 gcc_unreachable (); 4493 #endif 4494 4495 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false); 4496 if (indirect) 4497 type = build_pointer_type (type); 4498 4499 align = PARM_BOUNDARY / BITS_PER_UNIT; 4500 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type); 4501 4502 /* When we align parameter on stack for caller, if the parameter 4503 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be 4504 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee 4505 here with caller. */ 4506 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT) 4507 boundary = MAX_SUPPORTED_STACK_ALIGNMENT; 4508 4509 boundary /= BITS_PER_UNIT; 4510 4511 /* Hoist the valist value into a temporary for the moment. */ 4512 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL); 4513 4514 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually 4515 requires greater alignment, we must perform dynamic alignment. */ 4516 if (boundary > align 4517 && !integer_zerop (TYPE_SIZE (type))) 4518 { 4519 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, 4520 fold_build2 (POINTER_PLUS_EXPR, 4521 TREE_TYPE (valist), 4522 valist_tmp, size_int (boundary - 1))); 4523 gimplify_and_add (t, pre_p); 4524 4525 t = fold_convert (sizetype, valist_tmp); 4526 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, 4527 fold_convert (TREE_TYPE (valist), 4528 fold_build2 (BIT_AND_EXPR, sizetype, t, 4529 size_int (-boundary)))); 4530 gimplify_and_add (t, pre_p); 4531 } 4532 else 4533 boundary = align; 4534 4535 /* If the actual alignment is less than the alignment of the type, 4536 adjust the type accordingly so that we don't assume strict alignment 4537 when dereferencing the pointer. */ 4538 boundary *= BITS_PER_UNIT; 4539 if (boundary < TYPE_ALIGN (type)) 4540 { 4541 type = build_variant_type_copy (type); 4542 TYPE_ALIGN (type) = boundary; 4543 } 4544 4545 /* Compute the rounded size of the type. */ 4546 type_size = size_in_bytes (type); 4547 rounded_size = round_up (type_size, align); 4548 4549 /* Reduce rounded_size so it's sharable with the postqueue. */ 4550 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue); 4551 4552 /* Get AP. */ 4553 addr = valist_tmp; 4554 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size)) 4555 { 4556 /* Small args are padded downward. */ 4557 t = fold_build2_loc (input_location, GT_EXPR, sizetype, 4558 rounded_size, size_int (align)); 4559 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node, 4560 size_binop (MINUS_EXPR, rounded_size, type_size)); 4561 addr = fold_build2 (POINTER_PLUS_EXPR, 4562 TREE_TYPE (addr), addr, t); 4563 } 4564 4565 /* Compute new value for AP. */ 4566 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size); 4567 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t); 4568 gimplify_and_add (t, pre_p); 4569 4570 addr = fold_convert (build_pointer_type (type), addr); 4571 4572 if (indirect) 4573 addr = build_va_arg_indirect_ref (addr); 4574 4575 return build_va_arg_indirect_ref (addr); 4576 } 4577 4578 /* Build an indirect-ref expression over the given TREE, which represents a 4579 piece of a va_arg() expansion. */ 4580 tree 4581 build_va_arg_indirect_ref (tree addr) 4582 { 4583 addr = build_fold_indirect_ref_loc (EXPR_LOCATION (addr), addr); 4584 4585 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */ 4586 mf_mark (addr); 4587 4588 return addr; 4589 } 4590 4591 /* Return a dummy expression of type TYPE in order to keep going after an 4592 error. */ 4593 4594 static tree 4595 dummy_object (tree type) 4596 { 4597 tree t = build_int_cst (build_pointer_type (type), 0); 4598 return build1 (INDIRECT_REF, type, t); 4599 } 4600 4601 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a 4602 builtin function, but a very special sort of operator. */ 4603 4604 enum gimplify_status 4605 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 4606 { 4607 tree promoted_type, have_va_type; 4608 tree valist = TREE_OPERAND (*expr_p, 0); 4609 tree type = TREE_TYPE (*expr_p); 4610 tree t; 4611 location_t loc = EXPR_LOCATION (*expr_p); 4612 4613 /* Verify that valist is of the proper type. */ 4614 have_va_type = TREE_TYPE (valist); 4615 if (have_va_type == error_mark_node) 4616 return GS_ERROR; 4617 have_va_type = targetm.canonical_va_list_type (have_va_type); 4618 4619 if (have_va_type == NULL_TREE) 4620 { 4621 error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>"); 4622 return GS_ERROR; 4623 } 4624 4625 /* Generate a diagnostic for requesting data of a type that cannot 4626 be passed through `...' due to type promotion at the call site. */ 4627 if ((promoted_type = lang_hooks.types.type_promotes_to (type)) 4628 != type) 4629 { 4630 static bool gave_help; 4631 bool warned; 4632 4633 /* Unfortunately, this is merely undefined, rather than a constraint 4634 violation, so we cannot make this an error. If this call is never 4635 executed, the program is still strictly conforming. */ 4636 warned = warning_at (loc, 0, 4637 "%qT is promoted to %qT when passed through %<...%>", 4638 type, promoted_type); 4639 if (!gave_help && warned) 4640 { 4641 gave_help = true; 4642 inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)", 4643 promoted_type, type); 4644 } 4645 4646 /* We can, however, treat "undefined" any way we please. 4647 Call abort to encourage the user to fix the program. */ 4648 if (warned) 4649 inform (loc, "if this code is reached, the program will abort"); 4650 /* Before the abort, allow the evaluation of the va_list 4651 expression to exit or longjmp. */ 4652 gimplify_and_add (valist, pre_p); 4653 t = build_call_expr_loc (loc, 4654 implicit_built_in_decls[BUILT_IN_TRAP], 0); 4655 gimplify_and_add (t, pre_p); 4656 4657 /* This is dead code, but go ahead and finish so that the 4658 mode of the result comes out right. */ 4659 *expr_p = dummy_object (type); 4660 return GS_ALL_DONE; 4661 } 4662 else 4663 { 4664 /* Make it easier for the backends by protecting the valist argument 4665 from multiple evaluations. */ 4666 if (TREE_CODE (have_va_type) == ARRAY_TYPE) 4667 { 4668 /* For this case, the backends will be expecting a pointer to 4669 TREE_TYPE (abi), but it's possible we've 4670 actually been given an array (an actual TARGET_FN_ABI_VA_LIST). 4671 So fix it. */ 4672 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE) 4673 { 4674 tree p1 = build_pointer_type (TREE_TYPE (have_va_type)); 4675 valist = fold_convert_loc (loc, p1, 4676 build_fold_addr_expr_loc (loc, valist)); 4677 } 4678 4679 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue); 4680 } 4681 else 4682 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue); 4683 4684 if (!targetm.gimplify_va_arg_expr) 4685 /* FIXME: Once most targets are converted we should merely 4686 assert this is non-null. */ 4687 return GS_ALL_DONE; 4688 4689 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p); 4690 return GS_OK; 4691 } 4692 } 4693 4694 /* Expand EXP, a call to __builtin_va_end. */ 4695 4696 static rtx 4697 expand_builtin_va_end (tree exp) 4698 { 4699 tree valist = CALL_EXPR_ARG (exp, 0); 4700 4701 /* Evaluate for side effects, if needed. I hate macros that don't 4702 do that. */ 4703 if (TREE_SIDE_EFFECTS (valist)) 4704 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL); 4705 4706 return const0_rtx; 4707 } 4708 4709 /* Expand EXP, a call to __builtin_va_copy. We do this as a 4710 builtin rather than just as an assignment in stdarg.h because of the 4711 nastiness of array-type va_list types. */ 4712 4713 static rtx 4714 expand_builtin_va_copy (tree exp) 4715 { 4716 tree dst, src, t; 4717 location_t loc = EXPR_LOCATION (exp); 4718 4719 dst = CALL_EXPR_ARG (exp, 0); 4720 src = CALL_EXPR_ARG (exp, 1); 4721 4722 dst = stabilize_va_list_loc (loc, dst, 1); 4723 src = stabilize_va_list_loc (loc, src, 0); 4724 4725 gcc_assert (cfun != NULL && cfun->decl != NULL_TREE); 4726 4727 if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE) 4728 { 4729 t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src); 4730 TREE_SIDE_EFFECTS (t) = 1; 4731 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 4732 } 4733 else 4734 { 4735 rtx dstb, srcb, size; 4736 4737 /* Evaluate to pointers. */ 4738 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL); 4739 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL); 4740 size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)), 4741 NULL_RTX, VOIDmode, EXPAND_NORMAL); 4742 4743 dstb = convert_memory_address (Pmode, dstb); 4744 srcb = convert_memory_address (Pmode, srcb); 4745 4746 /* "Dereference" to BLKmode memories. */ 4747 dstb = gen_rtx_MEM (BLKmode, dstb); 4748 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst)))); 4749 set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl))); 4750 srcb = gen_rtx_MEM (BLKmode, srcb); 4751 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src)))); 4752 set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl))); 4753 4754 /* Copy. */ 4755 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL); 4756 } 4757 4758 return const0_rtx; 4759 } 4760 4761 /* Expand a call to one of the builtin functions __builtin_frame_address or 4762 __builtin_return_address. */ 4763 4764 static rtx 4765 expand_builtin_frame_address (tree fndecl, tree exp) 4766 { 4767 /* The argument must be a nonnegative integer constant. 4768 It counts the number of frames to scan up the stack. 4769 The value is the return address saved in that frame. */ 4770 if (call_expr_nargs (exp) == 0) 4771 /* Warning about missing arg was already issued. */ 4772 return const0_rtx; 4773 else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1)) 4774 { 4775 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4776 error ("invalid argument to %<__builtin_frame_address%>"); 4777 else 4778 error ("invalid argument to %<__builtin_return_address%>"); 4779 return const0_rtx; 4780 } 4781 else 4782 { 4783 rtx tem 4784 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl), 4785 tree_low_cst (CALL_EXPR_ARG (exp, 0), 1)); 4786 4787 /* Some ports cannot access arbitrary stack frames. */ 4788 if (tem == NULL) 4789 { 4790 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4791 warning (0, "unsupported argument to %<__builtin_frame_address%>"); 4792 else 4793 warning (0, "unsupported argument to %<__builtin_return_address%>"); 4794 return const0_rtx; 4795 } 4796 4797 /* For __builtin_frame_address, return what we've got. */ 4798 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4799 return tem; 4800 4801 if (!REG_P (tem) 4802 && ! CONSTANT_P (tem)) 4803 tem = copy_to_mode_reg (Pmode, tem); 4804 return tem; 4805 } 4806 } 4807 4808 /* Expand EXP, a call to the alloca builtin. Return NULL_RTX if 4809 we failed and the caller should emit a normal call, otherwise try to get 4810 the result in TARGET, if convenient. */ 4811 4812 static rtx 4813 expand_builtin_alloca (tree exp, rtx target) 4814 { 4815 rtx op0; 4816 rtx result; 4817 4818 /* Emit normal call if marked not-inlineable. */ 4819 if (CALL_CANNOT_INLINE_P (exp)) 4820 return NULL_RTX; 4821 4822 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)) 4823 return NULL_RTX; 4824 4825 /* Compute the argument. */ 4826 op0 = expand_normal (CALL_EXPR_ARG (exp, 0)); 4827 4828 /* Allocate the desired space. */ 4829 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT); 4830 result = convert_memory_address (ptr_mode, result); 4831 4832 return result; 4833 } 4834 4835 /* Expand a call to a bswap builtin with argument ARG0. MODE 4836 is the mode to expand with. */ 4837 4838 static rtx 4839 expand_builtin_bswap (tree exp, rtx target, rtx subtarget) 4840 { 4841 enum machine_mode mode; 4842 tree arg; 4843 rtx op0; 4844 4845 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)) 4846 return NULL_RTX; 4847 4848 arg = CALL_EXPR_ARG (exp, 0); 4849 mode = TYPE_MODE (TREE_TYPE (arg)); 4850 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 4851 4852 target = expand_unop (mode, bswap_optab, op0, target, 1); 4853 4854 gcc_assert (target); 4855 4856 return convert_to_mode (mode, target, 0); 4857 } 4858 4859 /* Expand a call to a unary builtin in EXP. 4860 Return NULL_RTX if a normal call should be emitted rather than expanding the 4861 function in-line. If convenient, the result should be placed in TARGET. 4862 SUBTARGET may be used as the target for computing one of EXP's operands. */ 4863 4864 static rtx 4865 expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target, 4866 rtx subtarget, optab op_optab) 4867 { 4868 rtx op0; 4869 4870 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)) 4871 return NULL_RTX; 4872 4873 /* Compute the argument. */ 4874 op0 = expand_expr (CALL_EXPR_ARG (exp, 0), 4875 (subtarget 4876 && (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))) 4877 == GET_MODE (subtarget))) ? subtarget : NULL_RTX, 4878 VOIDmode, EXPAND_NORMAL); 4879 /* Compute op, into TARGET if possible. 4880 Set TARGET to wherever the result comes back. */ 4881 target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))), 4882 op_optab, op0, target, 1); 4883 gcc_assert (target); 4884 4885 return convert_to_mode (target_mode, target, 0); 4886 } 4887 4888 /* Expand a call to __builtin_expect. We just return our argument 4889 as the builtin_expect semantic should've been already executed by 4890 tree branch prediction pass. */ 4891 4892 static rtx 4893 expand_builtin_expect (tree exp, rtx target) 4894 { 4895 tree arg; 4896 4897 if (call_expr_nargs (exp) < 2) 4898 return const0_rtx; 4899 arg = CALL_EXPR_ARG (exp, 0); 4900 4901 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL); 4902 /* When guessing was done, the hints should be already stripped away. */ 4903 gcc_assert (!flag_guess_branch_prob 4904 || optimize == 0 || errorcount || sorrycount); 4905 return target; 4906 } 4907 4908 void 4909 expand_builtin_trap (void) 4910 { 4911 #ifdef HAVE_trap 4912 if (HAVE_trap) 4913 emit_insn (gen_trap ()); 4914 else 4915 #endif 4916 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0); 4917 emit_barrier (); 4918 } 4919 4920 /* Expand a call to __builtin_unreachable. We do nothing except emit 4921 a barrier saying that control flow will not pass here. 4922 4923 It is the responsibility of the program being compiled to ensure 4924 that control flow does never reach __builtin_unreachable. */ 4925 static void 4926 expand_builtin_unreachable (void) 4927 { 4928 emit_barrier (); 4929 } 4930 4931 /* Expand EXP, a call to fabs, fabsf or fabsl. 4932 Return NULL_RTX if a normal call should be emitted rather than expanding 4933 the function inline. If convenient, the result should be placed 4934 in TARGET. SUBTARGET may be used as the target for computing 4935 the operand. */ 4936 4937 static rtx 4938 expand_builtin_fabs (tree exp, rtx target, rtx subtarget) 4939 { 4940 enum machine_mode mode; 4941 tree arg; 4942 rtx op0; 4943 4944 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 4945 return NULL_RTX; 4946 4947 arg = CALL_EXPR_ARG (exp, 0); 4948 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg); 4949 mode = TYPE_MODE (TREE_TYPE (arg)); 4950 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 4951 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1)); 4952 } 4953 4954 /* Expand EXP, a call to copysign, copysignf, or copysignl. 4955 Return NULL is a normal call should be emitted rather than expanding the 4956 function inline. If convenient, the result should be placed in TARGET. 4957 SUBTARGET may be used as the target for computing the operand. */ 4958 4959 static rtx 4960 expand_builtin_copysign (tree exp, rtx target, rtx subtarget) 4961 { 4962 rtx op0, op1; 4963 tree arg; 4964 4965 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 4966 return NULL_RTX; 4967 4968 arg = CALL_EXPR_ARG (exp, 0); 4969 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 4970 4971 arg = CALL_EXPR_ARG (exp, 1); 4972 op1 = expand_normal (arg); 4973 4974 return expand_copysign (op0, op1, target); 4975 } 4976 4977 /* Create a new constant string literal and return a char* pointer to it. 4978 The STRING_CST value is the LEN characters at STR. */ 4979 tree 4980 build_string_literal (int len, const char *str) 4981 { 4982 tree t, elem, index, type; 4983 4984 t = build_string (len, str); 4985 elem = build_type_variant (char_type_node, 1, 0); 4986 index = build_index_type (size_int (len - 1)); 4987 type = build_array_type (elem, index); 4988 TREE_TYPE (t) = type; 4989 TREE_CONSTANT (t) = 1; 4990 TREE_READONLY (t) = 1; 4991 TREE_STATIC (t) = 1; 4992 4993 type = build_pointer_type (elem); 4994 t = build1 (ADDR_EXPR, type, 4995 build4 (ARRAY_REF, elem, 4996 t, integer_zero_node, NULL_TREE, NULL_TREE)); 4997 return t; 4998 } 4999 5000 /* Expand a call to either the entry or exit function profiler. */ 5001 5002 static rtx 5003 expand_builtin_profile_func (bool exitp) 5004 { 5005 rtx this_rtx, which; 5006 5007 this_rtx = DECL_RTL (current_function_decl); 5008 gcc_assert (MEM_P (this_rtx)); 5009 this_rtx = XEXP (this_rtx, 0); 5010 5011 if (exitp) 5012 which = profile_function_exit_libfunc; 5013 else 5014 which = profile_function_entry_libfunc; 5015 5016 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this_rtx, Pmode, 5017 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS, 5018 0), 5019 Pmode); 5020 5021 return const0_rtx; 5022 } 5023 5024 /* Expand a call to __builtin___clear_cache. */ 5025 5026 static rtx 5027 expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED) 5028 { 5029 #ifndef HAVE_clear_cache 5030 #ifdef CLEAR_INSN_CACHE 5031 /* There is no "clear_cache" insn, and __clear_cache() in libgcc 5032 does something. Just do the default expansion to a call to 5033 __clear_cache(). */ 5034 return NULL_RTX; 5035 #else 5036 /* There is no "clear_cache" insn, and __clear_cache() in libgcc 5037 does nothing. There is no need to call it. Do nothing. */ 5038 return const0_rtx; 5039 #endif /* CLEAR_INSN_CACHE */ 5040 #else 5041 /* We have a "clear_cache" insn, and it will handle everything. */ 5042 tree begin, end; 5043 rtx begin_rtx, end_rtx; 5044 enum insn_code icode; 5045 5046 /* We must not expand to a library call. If we did, any 5047 fallback library function in libgcc that might contain a call to 5048 __builtin___clear_cache() would recurse infinitely. */ 5049 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 5050 { 5051 error ("both arguments to %<__builtin___clear_cache%> must be pointers"); 5052 return const0_rtx; 5053 } 5054 5055 if (HAVE_clear_cache) 5056 { 5057 icode = CODE_FOR_clear_cache; 5058 5059 begin = CALL_EXPR_ARG (exp, 0); 5060 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL); 5061 begin_rtx = convert_memory_address (Pmode, begin_rtx); 5062 if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode)) 5063 begin_rtx = copy_to_mode_reg (Pmode, begin_rtx); 5064 5065 end = CALL_EXPR_ARG (exp, 1); 5066 end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL); 5067 end_rtx = convert_memory_address (Pmode, end_rtx); 5068 if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode)) 5069 end_rtx = copy_to_mode_reg (Pmode, end_rtx); 5070 5071 emit_insn (gen_clear_cache (begin_rtx, end_rtx)); 5072 } 5073 return const0_rtx; 5074 #endif /* HAVE_clear_cache */ 5075 } 5076 5077 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */ 5078 5079 static rtx 5080 round_trampoline_addr (rtx tramp) 5081 { 5082 rtx temp, addend, mask; 5083 5084 /* If we don't need too much alignment, we'll have been guaranteed 5085 proper alignment by get_trampoline_type. */ 5086 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY) 5087 return tramp; 5088 5089 /* Round address up to desired boundary. */ 5090 temp = gen_reg_rtx (Pmode); 5091 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1); 5092 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT); 5093 5094 temp = expand_simple_binop (Pmode, PLUS, tramp, addend, 5095 temp, 0, OPTAB_LIB_WIDEN); 5096 tramp = expand_simple_binop (Pmode, AND, temp, mask, 5097 temp, 0, OPTAB_LIB_WIDEN); 5098 5099 return tramp; 5100 } 5101 5102 static rtx 5103 expand_builtin_init_trampoline (tree exp) 5104 { 5105 tree t_tramp, t_func, t_chain; 5106 rtx m_tramp, r_tramp, r_chain, tmp; 5107 5108 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, 5109 POINTER_TYPE, VOID_TYPE)) 5110 return NULL_RTX; 5111 5112 t_tramp = CALL_EXPR_ARG (exp, 0); 5113 t_func = CALL_EXPR_ARG (exp, 1); 5114 t_chain = CALL_EXPR_ARG (exp, 2); 5115 5116 r_tramp = expand_normal (t_tramp); 5117 m_tramp = gen_rtx_MEM (BLKmode, r_tramp); 5118 MEM_NOTRAP_P (m_tramp) = 1; 5119 5120 /* The TRAMP argument should be the address of a field within the 5121 local function's FRAME decl. Let's see if we can fill in the 5122 to fill in the MEM_ATTRs for this memory. */ 5123 if (TREE_CODE (t_tramp) == ADDR_EXPR) 5124 set_mem_attributes_minus_bitpos (m_tramp, TREE_OPERAND (t_tramp, 0), 5125 true, 0); 5126 5127 tmp = round_trampoline_addr (r_tramp); 5128 if (tmp != r_tramp) 5129 { 5130 m_tramp = change_address (m_tramp, BLKmode, tmp); 5131 set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT); 5132 set_mem_size (m_tramp, GEN_INT (TRAMPOLINE_SIZE)); 5133 } 5134 5135 /* The FUNC argument should be the address of the nested function. 5136 Extract the actual function decl to pass to the hook. */ 5137 gcc_assert (TREE_CODE (t_func) == ADDR_EXPR); 5138 t_func = TREE_OPERAND (t_func, 0); 5139 gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL); 5140 5141 r_chain = expand_normal (t_chain); 5142 5143 /* Generate insns to initialize the trampoline. */ 5144 targetm.calls.trampoline_init (m_tramp, t_func, r_chain); 5145 5146 trampolines_created = 1; 5147 return const0_rtx; 5148 } 5149 5150 static rtx 5151 expand_builtin_adjust_trampoline (tree exp) 5152 { 5153 rtx tramp; 5154 5155 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 5156 return NULL_RTX; 5157 5158 tramp = expand_normal (CALL_EXPR_ARG (exp, 0)); 5159 tramp = round_trampoline_addr (tramp); 5160 if (targetm.calls.trampoline_adjust_address) 5161 tramp = targetm.calls.trampoline_adjust_address (tramp); 5162 5163 return tramp; 5164 } 5165 5166 /* Expand the call EXP to the built-in signbit, signbitf or signbitl 5167 function. The function first checks whether the back end provides 5168 an insn to implement signbit for the respective mode. If not, it 5169 checks whether the floating point format of the value is such that 5170 the sign bit can be extracted. If that is not the case, the 5171 function returns NULL_RTX to indicate that a normal call should be 5172 emitted rather than expanding the function in-line. EXP is the 5173 expression that is a call to the builtin function; if convenient, 5174 the result should be placed in TARGET. */ 5175 static rtx 5176 expand_builtin_signbit (tree exp, rtx target) 5177 { 5178 const struct real_format *fmt; 5179 enum machine_mode fmode, imode, rmode; 5180 HOST_WIDE_INT hi, lo; 5181 tree arg; 5182 int word, bitpos; 5183 enum insn_code icode; 5184 rtx temp; 5185 location_t loc = EXPR_LOCATION (exp); 5186 5187 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) 5188 return NULL_RTX; 5189 5190 arg = CALL_EXPR_ARG (exp, 0); 5191 fmode = TYPE_MODE (TREE_TYPE (arg)); 5192 rmode = TYPE_MODE (TREE_TYPE (exp)); 5193 fmt = REAL_MODE_FORMAT (fmode); 5194 5195 arg = builtin_save_expr (arg); 5196 5197 /* Expand the argument yielding a RTX expression. */ 5198 temp = expand_normal (arg); 5199 5200 /* Check if the back end provides an insn that handles signbit for the 5201 argument's mode. */ 5202 icode = signbit_optab->handlers [(int) fmode].insn_code; 5203 if (icode != CODE_FOR_nothing) 5204 { 5205 rtx last = get_last_insn (); 5206 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp))); 5207 if (maybe_emit_unop_insn (icode, target, temp, UNKNOWN)) 5208 return target; 5209 delete_insns_since (last); 5210 } 5211 5212 /* For floating point formats without a sign bit, implement signbit 5213 as "ARG < 0.0". */ 5214 bitpos = fmt->signbit_ro; 5215 if (bitpos < 0) 5216 { 5217 /* But we can't do this if the format supports signed zero. */ 5218 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode)) 5219 return NULL_RTX; 5220 5221 arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg, 5222 build_real (TREE_TYPE (arg), dconst0)); 5223 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL); 5224 } 5225 5226 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD) 5227 { 5228 imode = int_mode_for_mode (fmode); 5229 if (imode == BLKmode) 5230 return NULL_RTX; 5231 temp = gen_lowpart (imode, temp); 5232 } 5233 else 5234 { 5235 imode = word_mode; 5236 /* Handle targets with different FP word orders. */ 5237 if (FLOAT_WORDS_BIG_ENDIAN) 5238 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD; 5239 else 5240 word = bitpos / BITS_PER_WORD; 5241 temp = operand_subword_force (temp, word, fmode); 5242 bitpos = bitpos % BITS_PER_WORD; 5243 } 5244 5245 /* Force the intermediate word_mode (or narrower) result into a 5246 register. This avoids attempting to create paradoxical SUBREGs 5247 of floating point modes below. */ 5248 temp = force_reg (imode, temp); 5249 5250 /* If the bitpos is within the "result mode" lowpart, the operation 5251 can be implement with a single bitwise AND. Otherwise, we need 5252 a right shift and an AND. */ 5253 5254 if (bitpos < GET_MODE_BITSIZE (rmode)) 5255 { 5256 if (bitpos < HOST_BITS_PER_WIDE_INT) 5257 { 5258 hi = 0; 5259 lo = (HOST_WIDE_INT) 1 << bitpos; 5260 } 5261 else 5262 { 5263 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT); 5264 lo = 0; 5265 } 5266 5267 if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode)) 5268 temp = gen_lowpart (rmode, temp); 5269 temp = expand_binop (rmode, and_optab, temp, 5270 immed_double_const (lo, hi, rmode), 5271 NULL_RTX, 1, OPTAB_LIB_WIDEN); 5272 } 5273 else 5274 { 5275 /* Perform a logical right shift to place the signbit in the least 5276 significant bit, then truncate the result to the desired mode 5277 and mask just this bit. */ 5278 temp = expand_shift (RSHIFT_EXPR, imode, temp, 5279 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1); 5280 temp = gen_lowpart (rmode, temp); 5281 temp = expand_binop (rmode, and_optab, temp, const1_rtx, 5282 NULL_RTX, 1, OPTAB_LIB_WIDEN); 5283 } 5284 5285 return temp; 5286 } 5287 5288 /* Expand fork or exec calls. TARGET is the desired target of the 5289 call. EXP is the call. FN is the 5290 identificator of the actual function. IGNORE is nonzero if the 5291 value is to be ignored. */ 5292 5293 static rtx 5294 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore) 5295 { 5296 tree id, decl; 5297 tree call; 5298 5299 /* If we are not profiling, just call the function. */ 5300 if (!profile_arc_flag) 5301 return NULL_RTX; 5302 5303 /* Otherwise call the wrapper. This should be equivalent for the rest of 5304 compiler, so the code does not diverge, and the wrapper may run the 5305 code necessary for keeping the profiling sane. */ 5306 5307 switch (DECL_FUNCTION_CODE (fn)) 5308 { 5309 case BUILT_IN_FORK: 5310 id = get_identifier ("__gcov_fork"); 5311 break; 5312 5313 case BUILT_IN_EXECL: 5314 id = get_identifier ("__gcov_execl"); 5315 break; 5316 5317 case BUILT_IN_EXECV: 5318 id = get_identifier ("__gcov_execv"); 5319 break; 5320 5321 case BUILT_IN_EXECLP: 5322 id = get_identifier ("__gcov_execlp"); 5323 break; 5324 5325 case BUILT_IN_EXECLE: 5326 id = get_identifier ("__gcov_execle"); 5327 break; 5328 5329 case BUILT_IN_EXECVP: 5330 id = get_identifier ("__gcov_execvp"); 5331 break; 5332 5333 case BUILT_IN_EXECVE: 5334 id = get_identifier ("__gcov_execve"); 5335 break; 5336 5337 default: 5338 gcc_unreachable (); 5339 } 5340 5341 decl = build_decl (DECL_SOURCE_LOCATION (fn), 5342 FUNCTION_DECL, id, TREE_TYPE (fn)); 5343 DECL_EXTERNAL (decl) = 1; 5344 TREE_PUBLIC (decl) = 1; 5345 DECL_ARTIFICIAL (decl) = 1; 5346 TREE_NOTHROW (decl) = 1; 5347 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; 5348 DECL_VISIBILITY_SPECIFIED (decl) = 1; 5349 call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0); 5350 return expand_call (call, target, ignore); 5351 } 5352 5353 5354 5355 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of 5356 the pointer in these functions is void*, the tree optimizers may remove 5357 casts. The mode computed in expand_builtin isn't reliable either, due 5358 to __sync_bool_compare_and_swap. 5359 5360 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the 5361 group of builtins. This gives us log2 of the mode size. */ 5362 5363 static inline enum machine_mode 5364 get_builtin_sync_mode (int fcode_diff) 5365 { 5366 /* The size is not negotiable, so ask not to get BLKmode in return 5367 if the target indicates that a smaller size would be better. */ 5368 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0); 5369 } 5370 5371 /* Expand the memory expression LOC and return the appropriate memory operand 5372 for the builtin_sync operations. */ 5373 5374 static rtx 5375 get_builtin_sync_mem (tree loc, enum machine_mode mode) 5376 { 5377 rtx addr, mem; 5378 5379 addr = expand_expr (loc, NULL_RTX, ptr_mode, EXPAND_SUM); 5380 addr = convert_memory_address (Pmode, addr); 5381 5382 /* Note that we explicitly do not want any alias information for this 5383 memory, so that we kill all other live memories. Otherwise we don't 5384 satisfy the full barrier semantics of the intrinsic. */ 5385 mem = validize_mem (gen_rtx_MEM (mode, addr)); 5386 5387 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT)); 5388 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); 5389 MEM_VOLATILE_P (mem) = 1; 5390 5391 return mem; 5392 } 5393 5394 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics. 5395 EXP is the CALL_EXPR. CODE is the rtx code 5396 that corresponds to the arithmetic or logical operation from the name; 5397 an exception here is that NOT actually means NAND. TARGET is an optional 5398 place for us to store the results; AFTER is true if this is the 5399 fetch_and_xxx form. IGNORE is true if we don't actually care about 5400 the result of the operation at all. */ 5401 5402 static rtx 5403 expand_builtin_sync_operation (enum machine_mode mode, tree exp, 5404 enum rtx_code code, bool after, 5405 rtx target, bool ignore) 5406 { 5407 rtx val, mem; 5408 enum machine_mode old_mode; 5409 location_t loc = EXPR_LOCATION (exp); 5410 5411 if (code == NOT && warn_sync_nand) 5412 { 5413 tree fndecl = get_callee_fndecl (exp); 5414 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 5415 5416 static bool warned_f_a_n, warned_n_a_f; 5417 5418 switch (fcode) 5419 { 5420 case BUILT_IN_FETCH_AND_NAND_1: 5421 case BUILT_IN_FETCH_AND_NAND_2: 5422 case BUILT_IN_FETCH_AND_NAND_4: 5423 case BUILT_IN_FETCH_AND_NAND_8: 5424 case BUILT_IN_FETCH_AND_NAND_16: 5425 5426 if (warned_f_a_n) 5427 break; 5428 5429 fndecl = implicit_built_in_decls[BUILT_IN_FETCH_AND_NAND_N]; 5430 inform (loc, "%qD changed semantics in GCC 4.4", fndecl); 5431 warned_f_a_n = true; 5432 break; 5433 5434 case BUILT_IN_NAND_AND_FETCH_1: 5435 case BUILT_IN_NAND_AND_FETCH_2: 5436 case BUILT_IN_NAND_AND_FETCH_4: 5437 case BUILT_IN_NAND_AND_FETCH_8: 5438 case BUILT_IN_NAND_AND_FETCH_16: 5439 5440 if (warned_n_a_f) 5441 break; 5442 5443 fndecl = implicit_built_in_decls[BUILT_IN_NAND_AND_FETCH_N]; 5444 inform (loc, "%qD changed semantics in GCC 4.4", fndecl); 5445 warned_n_a_f = true; 5446 break; 5447 5448 default: 5449 gcc_unreachable (); 5450 } 5451 } 5452 5453 /* Expand the operands. */ 5454 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5455 5456 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL); 5457 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5458 of CONST_INTs, where we know the old_mode only from the call argument. */ 5459 old_mode = GET_MODE (val); 5460 if (old_mode == VOIDmode) 5461 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))); 5462 val = convert_modes (mode, old_mode, val, 1); 5463 5464 if (ignore) 5465 return expand_sync_operation (mem, val, code); 5466 else 5467 return expand_sync_fetch_operation (mem, val, code, after, target); 5468 } 5469 5470 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap 5471 intrinsics. EXP is the CALL_EXPR. IS_BOOL is 5472 true if this is the boolean form. TARGET is a place for us to store the 5473 results; this is NOT optional if IS_BOOL is true. */ 5474 5475 static rtx 5476 expand_builtin_compare_and_swap (enum machine_mode mode, tree exp, 5477 bool is_bool, rtx target) 5478 { 5479 rtx old_val, new_val, mem; 5480 enum machine_mode old_mode; 5481 5482 /* Expand the operands. */ 5483 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5484 5485 5486 old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, 5487 mode, EXPAND_NORMAL); 5488 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5489 of CONST_INTs, where we know the old_mode only from the call argument. */ 5490 old_mode = GET_MODE (old_val); 5491 if (old_mode == VOIDmode) 5492 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))); 5493 old_val = convert_modes (mode, old_mode, old_val, 1); 5494 5495 new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX, 5496 mode, EXPAND_NORMAL); 5497 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5498 of CONST_INTs, where we know the old_mode only from the call argument. */ 5499 old_mode = GET_MODE (new_val); 5500 if (old_mode == VOIDmode) 5501 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))); 5502 new_val = convert_modes (mode, old_mode, new_val, 1); 5503 5504 if (is_bool) 5505 return expand_bool_compare_and_swap (mem, old_val, new_val, target); 5506 else 5507 return expand_val_compare_and_swap (mem, old_val, new_val, target); 5508 } 5509 5510 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most 5511 general form is actually an atomic exchange, and some targets only 5512 support a reduced form with the second argument being a constant 1. 5513 EXP is the CALL_EXPR; TARGET is an optional place for us to store 5514 the results. */ 5515 5516 static rtx 5517 expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp, 5518 rtx target) 5519 { 5520 rtx val, mem; 5521 enum machine_mode old_mode; 5522 5523 /* Expand the operands. */ 5524 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5525 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL); 5526 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5527 of CONST_INTs, where we know the old_mode only from the call argument. */ 5528 old_mode = GET_MODE (val); 5529 if (old_mode == VOIDmode) 5530 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))); 5531 val = convert_modes (mode, old_mode, val, 1); 5532 5533 return expand_sync_lock_test_and_set (mem, val, target); 5534 } 5535 5536 /* Expand the __sync_synchronize intrinsic. */ 5537 5538 static void 5539 expand_builtin_synchronize (void) 5540 { 5541 gimple x; 5542 VEC (tree, gc) *v_clobbers; 5543 5544 #ifdef HAVE_memory_barrier 5545 if (HAVE_memory_barrier) 5546 { 5547 emit_insn (gen_memory_barrier ()); 5548 return; 5549 } 5550 #endif 5551 5552 if (synchronize_libfunc != NULL_RTX) 5553 { 5554 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0); 5555 return; 5556 } 5557 5558 /* If no explicit memory barrier instruction is available, create an 5559 empty asm stmt with a memory clobber. */ 5560 v_clobbers = VEC_alloc (tree, gc, 1); 5561 VEC_quick_push (tree, v_clobbers, 5562 tree_cons (NULL, build_string (6, "memory"), NULL)); 5563 x = gimple_build_asm_vec ("", NULL, NULL, v_clobbers, NULL); 5564 gimple_asm_set_volatile (x, true); 5565 expand_asm_stmt (x); 5566 } 5567 5568 /* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */ 5569 5570 static void 5571 expand_builtin_lock_release (enum machine_mode mode, tree exp) 5572 { 5573 enum insn_code icode; 5574 rtx mem, insn; 5575 rtx val = const0_rtx; 5576 5577 /* Expand the operands. */ 5578 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); 5579 5580 /* If there is an explicit operation in the md file, use it. */ 5581 icode = sync_lock_release[mode]; 5582 if (icode != CODE_FOR_nothing) 5583 { 5584 if (!insn_data[icode].operand[1].predicate (val, mode)) 5585 val = force_reg (mode, val); 5586 5587 insn = GEN_FCN (icode) (mem, val); 5588 if (insn) 5589 { 5590 emit_insn (insn); 5591 return; 5592 } 5593 } 5594 5595 /* Otherwise we can implement this operation by emitting a barrier 5596 followed by a store of zero. */ 5597 expand_builtin_synchronize (); 5598 emit_move_insn (mem, val); 5599 } 5600 5601 /* Expand an expression EXP that calls a built-in function, 5602 with result going to TARGET if that's convenient 5603 (and in mode MODE if that's convenient). 5604 SUBTARGET may be used as the target for computing one of EXP's operands. 5605 IGNORE is nonzero if the value is to be ignored. */ 5606 5607 rtx 5608 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, 5609 int ignore) 5610 { 5611 tree fndecl = get_callee_fndecl (exp); 5612 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 5613 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp)); 5614 5615 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 5616 return targetm.expand_builtin (exp, target, subtarget, mode, ignore); 5617 5618 /* When not optimizing, generate calls to library functions for a certain 5619 set of builtins. */ 5620 if (!optimize 5621 && !called_as_built_in (fndecl) 5622 && DECL_ASSEMBLER_NAME_SET_P (fndecl) 5623 && fcode != BUILT_IN_ALLOCA 5624 && fcode != BUILT_IN_FREE) 5625 return expand_call (exp, target, ignore); 5626 5627 /* The built-in function expanders test for target == const0_rtx 5628 to determine whether the function's result will be ignored. */ 5629 if (ignore) 5630 target = const0_rtx; 5631 5632 /* If the result of a pure or const built-in function is ignored, and 5633 none of its arguments are volatile, we can avoid expanding the 5634 built-in call and just evaluate the arguments for side-effects. */ 5635 if (target == const0_rtx 5636 && (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl))) 5637 { 5638 bool volatilep = false; 5639 tree arg; 5640 call_expr_arg_iterator iter; 5641 5642 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) 5643 if (TREE_THIS_VOLATILE (arg)) 5644 { 5645 volatilep = true; 5646 break; 5647 } 5648 5649 if (! volatilep) 5650 { 5651 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) 5652 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL); 5653 return const0_rtx; 5654 } 5655 } 5656 5657 switch (fcode) 5658 { 5659 CASE_FLT_FN (BUILT_IN_FABS): 5660 target = expand_builtin_fabs (exp, target, subtarget); 5661 if (target) 5662 return target; 5663 break; 5664 5665 CASE_FLT_FN (BUILT_IN_COPYSIGN): 5666 target = expand_builtin_copysign (exp, target, subtarget); 5667 if (target) 5668 return target; 5669 break; 5670 5671 /* Just do a normal library call if we were unable to fold 5672 the values. */ 5673 CASE_FLT_FN (BUILT_IN_CABS): 5674 break; 5675 5676 CASE_FLT_FN (BUILT_IN_EXP): 5677 CASE_FLT_FN (BUILT_IN_EXP10): 5678 CASE_FLT_FN (BUILT_IN_POW10): 5679 CASE_FLT_FN (BUILT_IN_EXP2): 5680 CASE_FLT_FN (BUILT_IN_EXPM1): 5681 CASE_FLT_FN (BUILT_IN_LOGB): 5682 CASE_FLT_FN (BUILT_IN_LOG): 5683 CASE_FLT_FN (BUILT_IN_LOG10): 5684 CASE_FLT_FN (BUILT_IN_LOG2): 5685 CASE_FLT_FN (BUILT_IN_LOG1P): 5686 CASE_FLT_FN (BUILT_IN_TAN): 5687 CASE_FLT_FN (BUILT_IN_ASIN): 5688 CASE_FLT_FN (BUILT_IN_ACOS): 5689 CASE_FLT_FN (BUILT_IN_ATAN): 5690 CASE_FLT_FN (BUILT_IN_SIGNIFICAND): 5691 /* Treat these like sqrt only if unsafe math optimizations are allowed, 5692 because of possible accuracy problems. */ 5693 if (! flag_unsafe_math_optimizations) 5694 break; 5695 CASE_FLT_FN (BUILT_IN_SQRT): 5696 CASE_FLT_FN (BUILT_IN_FLOOR): 5697 CASE_FLT_FN (BUILT_IN_CEIL): 5698 CASE_FLT_FN (BUILT_IN_TRUNC): 5699 CASE_FLT_FN (BUILT_IN_ROUND): 5700 CASE_FLT_FN (BUILT_IN_NEARBYINT): 5701 CASE_FLT_FN (BUILT_IN_RINT): 5702 target = expand_builtin_mathfn (exp, target, subtarget); 5703 if (target) 5704 return target; 5705 break; 5706 5707 CASE_FLT_FN (BUILT_IN_ILOGB): 5708 if (! flag_unsafe_math_optimizations) 5709 break; 5710 CASE_FLT_FN (BUILT_IN_ISINF): 5711 CASE_FLT_FN (BUILT_IN_FINITE): 5712 case BUILT_IN_ISFINITE: 5713 case BUILT_IN_ISNORMAL: 5714 target = expand_builtin_interclass_mathfn (exp, target); 5715 if (target) 5716 return target; 5717 break; 5718 5719 CASE_FLT_FN (BUILT_IN_LCEIL): 5720 CASE_FLT_FN (BUILT_IN_LLCEIL): 5721 CASE_FLT_FN (BUILT_IN_LFLOOR): 5722 CASE_FLT_FN (BUILT_IN_LLFLOOR): 5723 target = expand_builtin_int_roundingfn (exp, target); 5724 if (target) 5725 return target; 5726 break; 5727 5728 CASE_FLT_FN (BUILT_IN_LRINT): 5729 CASE_FLT_FN (BUILT_IN_LLRINT): 5730 CASE_FLT_FN (BUILT_IN_LROUND): 5731 CASE_FLT_FN (BUILT_IN_LLROUND): 5732 target = expand_builtin_int_roundingfn_2 (exp, target); 5733 if (target) 5734 return target; 5735 break; 5736 5737 CASE_FLT_FN (BUILT_IN_POW): 5738 target = expand_builtin_pow (exp, target, subtarget); 5739 if (target) 5740 return target; 5741 break; 5742 5743 CASE_FLT_FN (BUILT_IN_POWI): 5744 target = expand_builtin_powi (exp, target); 5745 if (target) 5746 return target; 5747 break; 5748 5749 CASE_FLT_FN (BUILT_IN_ATAN2): 5750 CASE_FLT_FN (BUILT_IN_LDEXP): 5751 CASE_FLT_FN (BUILT_IN_SCALB): 5752 CASE_FLT_FN (BUILT_IN_SCALBN): 5753 CASE_FLT_FN (BUILT_IN_SCALBLN): 5754 if (! flag_unsafe_math_optimizations) 5755 break; 5756 5757 CASE_FLT_FN (BUILT_IN_FMOD): 5758 CASE_FLT_FN (BUILT_IN_REMAINDER): 5759 CASE_FLT_FN (BUILT_IN_DREM): 5760 target = expand_builtin_mathfn_2 (exp, target, subtarget); 5761 if (target) 5762 return target; 5763 break; 5764 5765 CASE_FLT_FN (BUILT_IN_CEXPI): 5766 target = expand_builtin_cexpi (exp, target); 5767 gcc_assert (target); 5768 return target; 5769 5770 CASE_FLT_FN (BUILT_IN_SIN): 5771 CASE_FLT_FN (BUILT_IN_COS): 5772 if (! flag_unsafe_math_optimizations) 5773 break; 5774 target = expand_builtin_mathfn_3 (exp, target, subtarget); 5775 if (target) 5776 return target; 5777 break; 5778 5779 CASE_FLT_FN (BUILT_IN_SINCOS): 5780 if (! flag_unsafe_math_optimizations) 5781 break; 5782 target = expand_builtin_sincos (exp); 5783 if (target) 5784 return target; 5785 break; 5786 5787 case BUILT_IN_APPLY_ARGS: 5788 return expand_builtin_apply_args (); 5789 5790 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes 5791 FUNCTION with a copy of the parameters described by 5792 ARGUMENTS, and ARGSIZE. It returns a block of memory 5793 allocated on the stack into which is stored all the registers 5794 that might possibly be used for returning the result of a 5795 function. ARGUMENTS is the value returned by 5796 __builtin_apply_args. ARGSIZE is the number of bytes of 5797 arguments that must be copied. ??? How should this value be 5798 computed? We'll also need a safe worst case value for varargs 5799 functions. */ 5800 case BUILT_IN_APPLY: 5801 if (!validate_arglist (exp, POINTER_TYPE, 5802 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE) 5803 && !validate_arglist (exp, REFERENCE_TYPE, 5804 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 5805 return const0_rtx; 5806 else 5807 { 5808 rtx ops[3]; 5809 5810 ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0)); 5811 ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1)); 5812 ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2)); 5813 5814 return expand_builtin_apply (ops[0], ops[1], ops[2]); 5815 } 5816 5817 /* __builtin_return (RESULT) causes the function to return the 5818 value described by RESULT. RESULT is address of the block of 5819 memory returned by __builtin_apply. */ 5820 case BUILT_IN_RETURN: 5821 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 5822 expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0))); 5823 return const0_rtx; 5824 5825 case BUILT_IN_SAVEREGS: 5826 return expand_builtin_saveregs (); 5827 5828 case BUILT_IN_ARGS_INFO: 5829 return expand_builtin_args_info (exp); 5830 5831 case BUILT_IN_VA_ARG_PACK: 5832 /* All valid uses of __builtin_va_arg_pack () are removed during 5833 inlining. */ 5834 error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp); 5835 return const0_rtx; 5836 5837 case BUILT_IN_VA_ARG_PACK_LEN: 5838 /* All valid uses of __builtin_va_arg_pack_len () are removed during 5839 inlining. */ 5840 error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp); 5841 return const0_rtx; 5842 5843 /* Return the address of the first anonymous stack arg. */ 5844 case BUILT_IN_NEXT_ARG: 5845 if (fold_builtin_next_arg (exp, false)) 5846 return const0_rtx; 5847 return expand_builtin_next_arg (); 5848 5849 case BUILT_IN_CLEAR_CACHE: 5850 target = expand_builtin___clear_cache (exp); 5851 if (target) 5852 return target; 5853 break; 5854 5855 case BUILT_IN_CLASSIFY_TYPE: 5856 return expand_builtin_classify_type (exp); 5857 5858 case BUILT_IN_CONSTANT_P: 5859 return const0_rtx; 5860 5861 case BUILT_IN_FRAME_ADDRESS: 5862 case BUILT_IN_RETURN_ADDRESS: 5863 return expand_builtin_frame_address (fndecl, exp); 5864 5865 /* Returns the address of the area where the structure is returned. 5866 0 otherwise. */ 5867 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: 5868 if (call_expr_nargs (exp) != 0 5869 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))) 5870 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl)))) 5871 return const0_rtx; 5872 else 5873 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0); 5874 5875 case BUILT_IN_ALLOCA: 5876 target = expand_builtin_alloca (exp, target); 5877 if (target) 5878 return target; 5879 break; 5880 5881 case BUILT_IN_STACK_SAVE: 5882 return expand_stack_save (); 5883 5884 case BUILT_IN_STACK_RESTORE: 5885 expand_stack_restore (CALL_EXPR_ARG (exp, 0)); 5886 return const0_rtx; 5887 5888 case BUILT_IN_BSWAP32: 5889 case BUILT_IN_BSWAP64: 5890 target = expand_builtin_bswap (exp, target, subtarget); 5891 5892 if (target) 5893 return target; 5894 break; 5895 5896 CASE_INT_FN (BUILT_IN_FFS): 5897 case BUILT_IN_FFSIMAX: 5898 target = expand_builtin_unop (target_mode, exp, target, 5899 subtarget, ffs_optab); 5900 if (target) 5901 return target; 5902 break; 5903 5904 CASE_INT_FN (BUILT_IN_CLZ): 5905 case BUILT_IN_CLZIMAX: 5906 target = expand_builtin_unop (target_mode, exp, target, 5907 subtarget, clz_optab); 5908 if (target) 5909 return target; 5910 break; 5911 5912 CASE_INT_FN (BUILT_IN_CTZ): 5913 case BUILT_IN_CTZIMAX: 5914 target = expand_builtin_unop (target_mode, exp, target, 5915 subtarget, ctz_optab); 5916 if (target) 5917 return target; 5918 break; 5919 5920 CASE_INT_FN (BUILT_IN_POPCOUNT): 5921 case BUILT_IN_POPCOUNTIMAX: 5922 target = expand_builtin_unop (target_mode, exp, target, 5923 subtarget, popcount_optab); 5924 if (target) 5925 return target; 5926 break; 5927 5928 CASE_INT_FN (BUILT_IN_PARITY): 5929 case BUILT_IN_PARITYIMAX: 5930 target = expand_builtin_unop (target_mode, exp, target, 5931 subtarget, parity_optab); 5932 if (target) 5933 return target; 5934 break; 5935 5936 case BUILT_IN_STRLEN: 5937 target = expand_builtin_strlen (exp, target, target_mode); 5938 if (target) 5939 return target; 5940 break; 5941 5942 case BUILT_IN_STRCPY: 5943 target = expand_builtin_strcpy (exp, target); 5944 if (target) 5945 return target; 5946 break; 5947 5948 case BUILT_IN_STRNCPY: 5949 target = expand_builtin_strncpy (exp, target); 5950 if (target) 5951 return target; 5952 break; 5953 5954 case BUILT_IN_STPCPY: 5955 target = expand_builtin_stpcpy (exp, target, mode); 5956 if (target) 5957 return target; 5958 break; 5959 5960 case BUILT_IN_MEMCPY: 5961 target = expand_builtin_memcpy (exp, target); 5962 if (target) 5963 return target; 5964 break; 5965 5966 case BUILT_IN_MEMPCPY: 5967 target = expand_builtin_mempcpy (exp, target, mode); 5968 if (target) 5969 return target; 5970 break; 5971 5972 case BUILT_IN_MEMSET: 5973 target = expand_builtin_memset (exp, target, mode); 5974 if (target) 5975 return target; 5976 break; 5977 5978 case BUILT_IN_BZERO: 5979 target = expand_builtin_bzero (exp); 5980 if (target) 5981 return target; 5982 break; 5983 5984 case BUILT_IN_STRCMP: 5985 target = expand_builtin_strcmp (exp, target); 5986 if (target) 5987 return target; 5988 break; 5989 5990 case BUILT_IN_STRNCMP: 5991 target = expand_builtin_strncmp (exp, target, mode); 5992 if (target) 5993 return target; 5994 break; 5995 5996 case BUILT_IN_BCMP: 5997 case BUILT_IN_MEMCMP: 5998 target = expand_builtin_memcmp (exp, target, mode); 5999 if (target) 6000 return target; 6001 break; 6002 6003 case BUILT_IN_SETJMP: 6004 /* This should have been lowered to the builtins below. */ 6005 gcc_unreachable (); 6006 6007 case BUILT_IN_SETJMP_SETUP: 6008 /* __builtin_setjmp_setup is passed a pointer to an array of five words 6009 and the receiver label. */ 6010 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 6011 { 6012 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget, 6013 VOIDmode, EXPAND_NORMAL); 6014 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0); 6015 rtx label_r = label_rtx (label); 6016 6017 /* This is copied from the handling of non-local gotos. */ 6018 expand_builtin_setjmp_setup (buf_addr, label_r); 6019 nonlocal_goto_handler_labels 6020 = gen_rtx_EXPR_LIST (VOIDmode, label_r, 6021 nonlocal_goto_handler_labels); 6022 /* ??? Do not let expand_label treat us as such since we would 6023 not want to be both on the list of non-local labels and on 6024 the list of forced labels. */ 6025 FORCED_LABEL (label) = 0; 6026 return const0_rtx; 6027 } 6028 break; 6029 6030 case BUILT_IN_SETJMP_DISPATCHER: 6031 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */ 6032 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 6033 { 6034 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0); 6035 rtx label_r = label_rtx (label); 6036 6037 /* Remove the dispatcher label from the list of non-local labels 6038 since the receiver labels have been added to it above. */ 6039 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels); 6040 return const0_rtx; 6041 } 6042 break; 6043 6044 case BUILT_IN_SETJMP_RECEIVER: 6045 /* __builtin_setjmp_receiver is passed the receiver label. */ 6046 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 6047 { 6048 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0); 6049 rtx label_r = label_rtx (label); 6050 6051 expand_builtin_setjmp_receiver (label_r); 6052 return const0_rtx; 6053 } 6054 break; 6055 6056 /* __builtin_longjmp is passed a pointer to an array of five words. 6057 It's similar to the C library longjmp function but works with 6058 __builtin_setjmp above. */ 6059 case BUILT_IN_LONGJMP: 6060 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6061 { 6062 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget, 6063 VOIDmode, EXPAND_NORMAL); 6064 rtx value = expand_normal (CALL_EXPR_ARG (exp, 1)); 6065 6066 if (value != const1_rtx) 6067 { 6068 error ("%<__builtin_longjmp%> second argument must be 1"); 6069 return const0_rtx; 6070 } 6071 6072 expand_builtin_longjmp (buf_addr, value); 6073 return const0_rtx; 6074 } 6075 break; 6076 6077 case BUILT_IN_NONLOCAL_GOTO: 6078 target = expand_builtin_nonlocal_goto (exp); 6079 if (target) 6080 return target; 6081 break; 6082 6083 /* This updates the setjmp buffer that is its argument with the value 6084 of the current stack pointer. */ 6085 case BUILT_IN_UPDATE_SETJMP_BUF: 6086 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) 6087 { 6088 rtx buf_addr 6089 = expand_normal (CALL_EXPR_ARG (exp, 0)); 6090 6091 expand_builtin_update_setjmp_buf (buf_addr); 6092 return const0_rtx; 6093 } 6094 break; 6095 6096 case BUILT_IN_TRAP: 6097 expand_builtin_trap (); 6098 return const0_rtx; 6099 6100 case BUILT_IN_UNREACHABLE: 6101 expand_builtin_unreachable (); 6102 return const0_rtx; 6103 6104 CASE_FLT_FN (BUILT_IN_SIGNBIT): 6105 case BUILT_IN_SIGNBITD32: 6106 case BUILT_IN_SIGNBITD64: 6107 case BUILT_IN_SIGNBITD128: 6108 target = expand_builtin_signbit (exp, target); 6109 if (target) 6110 return target; 6111 break; 6112 6113 /* Various hooks for the DWARF 2 __throw routine. */ 6114 case BUILT_IN_UNWIND_INIT: 6115 expand_builtin_unwind_init (); 6116 return const0_rtx; 6117 case BUILT_IN_DWARF_CFA: 6118 return virtual_cfa_rtx; 6119 #ifdef DWARF2_UNWIND_INFO 6120 case BUILT_IN_DWARF_SP_COLUMN: 6121 return expand_builtin_dwarf_sp_column (); 6122 case BUILT_IN_INIT_DWARF_REG_SIZES: 6123 expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0)); 6124 return const0_rtx; 6125 #endif 6126 case BUILT_IN_FROB_RETURN_ADDR: 6127 return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0)); 6128 case BUILT_IN_EXTRACT_RETURN_ADDR: 6129 return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0)); 6130 case BUILT_IN_EH_RETURN: 6131 expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0), 6132 CALL_EXPR_ARG (exp, 1)); 6133 return const0_rtx; 6134 #ifdef EH_RETURN_DATA_REGNO 6135 case BUILT_IN_EH_RETURN_DATA_REGNO: 6136 return expand_builtin_eh_return_data_regno (exp); 6137 #endif 6138 case BUILT_IN_EXTEND_POINTER: 6139 return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0)); 6140 case BUILT_IN_EH_POINTER: 6141 return expand_builtin_eh_pointer (exp); 6142 case BUILT_IN_EH_FILTER: 6143 return expand_builtin_eh_filter (exp); 6144 case BUILT_IN_EH_COPY_VALUES: 6145 return expand_builtin_eh_copy_values (exp); 6146 6147 case BUILT_IN_VA_START: 6148 return expand_builtin_va_start (exp); 6149 case BUILT_IN_VA_END: 6150 return expand_builtin_va_end (exp); 6151 case BUILT_IN_VA_COPY: 6152 return expand_builtin_va_copy (exp); 6153 case BUILT_IN_EXPECT: 6154 return expand_builtin_expect (exp, target); 6155 case BUILT_IN_PREFETCH: 6156 expand_builtin_prefetch (exp); 6157 return const0_rtx; 6158 6159 case BUILT_IN_PROFILE_FUNC_ENTER: 6160 return expand_builtin_profile_func (false); 6161 case BUILT_IN_PROFILE_FUNC_EXIT: 6162 return expand_builtin_profile_func (true); 6163 6164 case BUILT_IN_INIT_TRAMPOLINE: 6165 return expand_builtin_init_trampoline (exp); 6166 case BUILT_IN_ADJUST_TRAMPOLINE: 6167 return expand_builtin_adjust_trampoline (exp); 6168 6169 case BUILT_IN_FORK: 6170 case BUILT_IN_EXECL: 6171 case BUILT_IN_EXECV: 6172 case BUILT_IN_EXECLP: 6173 case BUILT_IN_EXECLE: 6174 case BUILT_IN_EXECVP: 6175 case BUILT_IN_EXECVE: 6176 target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore); 6177 if (target) 6178 return target; 6179 break; 6180 6181 case BUILT_IN_FETCH_AND_ADD_1: 6182 case BUILT_IN_FETCH_AND_ADD_2: 6183 case BUILT_IN_FETCH_AND_ADD_4: 6184 case BUILT_IN_FETCH_AND_ADD_8: 6185 case BUILT_IN_FETCH_AND_ADD_16: 6186 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1); 6187 target = expand_builtin_sync_operation (mode, exp, PLUS, 6188 false, target, ignore); 6189 if (target) 6190 return target; 6191 break; 6192 6193 case BUILT_IN_FETCH_AND_SUB_1: 6194 case BUILT_IN_FETCH_AND_SUB_2: 6195 case BUILT_IN_FETCH_AND_SUB_4: 6196 case BUILT_IN_FETCH_AND_SUB_8: 6197 case BUILT_IN_FETCH_AND_SUB_16: 6198 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1); 6199 target = expand_builtin_sync_operation (mode, exp, MINUS, 6200 false, target, ignore); 6201 if (target) 6202 return target; 6203 break; 6204 6205 case BUILT_IN_FETCH_AND_OR_1: 6206 case BUILT_IN_FETCH_AND_OR_2: 6207 case BUILT_IN_FETCH_AND_OR_4: 6208 case BUILT_IN_FETCH_AND_OR_8: 6209 case BUILT_IN_FETCH_AND_OR_16: 6210 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1); 6211 target = expand_builtin_sync_operation (mode, exp, IOR, 6212 false, target, ignore); 6213 if (target) 6214 return target; 6215 break; 6216 6217 case BUILT_IN_FETCH_AND_AND_1: 6218 case BUILT_IN_FETCH_AND_AND_2: 6219 case BUILT_IN_FETCH_AND_AND_4: 6220 case BUILT_IN_FETCH_AND_AND_8: 6221 case BUILT_IN_FETCH_AND_AND_16: 6222 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1); 6223 target = expand_builtin_sync_operation (mode, exp, AND, 6224 false, target, ignore); 6225 if (target) 6226 return target; 6227 break; 6228 6229 case BUILT_IN_FETCH_AND_XOR_1: 6230 case BUILT_IN_FETCH_AND_XOR_2: 6231 case BUILT_IN_FETCH_AND_XOR_4: 6232 case BUILT_IN_FETCH_AND_XOR_8: 6233 case BUILT_IN_FETCH_AND_XOR_16: 6234 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1); 6235 target = expand_builtin_sync_operation (mode, exp, XOR, 6236 false, target, ignore); 6237 if (target) 6238 return target; 6239 break; 6240 6241 case BUILT_IN_FETCH_AND_NAND_1: 6242 case BUILT_IN_FETCH_AND_NAND_2: 6243 case BUILT_IN_FETCH_AND_NAND_4: 6244 case BUILT_IN_FETCH_AND_NAND_8: 6245 case BUILT_IN_FETCH_AND_NAND_16: 6246 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1); 6247 target = expand_builtin_sync_operation (mode, exp, NOT, 6248 false, target, ignore); 6249 if (target) 6250 return target; 6251 break; 6252 6253 case BUILT_IN_ADD_AND_FETCH_1: 6254 case BUILT_IN_ADD_AND_FETCH_2: 6255 case BUILT_IN_ADD_AND_FETCH_4: 6256 case BUILT_IN_ADD_AND_FETCH_8: 6257 case BUILT_IN_ADD_AND_FETCH_16: 6258 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1); 6259 target = expand_builtin_sync_operation (mode, exp, PLUS, 6260 true, target, ignore); 6261 if (target) 6262 return target; 6263 break; 6264 6265 case BUILT_IN_SUB_AND_FETCH_1: 6266 case BUILT_IN_SUB_AND_FETCH_2: 6267 case BUILT_IN_SUB_AND_FETCH_4: 6268 case BUILT_IN_SUB_AND_FETCH_8: 6269 case BUILT_IN_SUB_AND_FETCH_16: 6270 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1); 6271 target = expand_builtin_sync_operation (mode, exp, MINUS, 6272 true, target, ignore); 6273 if (target) 6274 return target; 6275 break; 6276 6277 case BUILT_IN_OR_AND_FETCH_1: 6278 case BUILT_IN_OR_AND_FETCH_2: 6279 case BUILT_IN_OR_AND_FETCH_4: 6280 case BUILT_IN_OR_AND_FETCH_8: 6281 case BUILT_IN_OR_AND_FETCH_16: 6282 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1); 6283 target = expand_builtin_sync_operation (mode, exp, IOR, 6284 true, target, ignore); 6285 if (target) 6286 return target; 6287 break; 6288 6289 case BUILT_IN_AND_AND_FETCH_1: 6290 case BUILT_IN_AND_AND_FETCH_2: 6291 case BUILT_IN_AND_AND_FETCH_4: 6292 case BUILT_IN_AND_AND_FETCH_8: 6293 case BUILT_IN_AND_AND_FETCH_16: 6294 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1); 6295 target = expand_builtin_sync_operation (mode, exp, AND, 6296 true, target, ignore); 6297 if (target) 6298 return target; 6299 break; 6300 6301 case BUILT_IN_XOR_AND_FETCH_1: 6302 case BUILT_IN_XOR_AND_FETCH_2: 6303 case BUILT_IN_XOR_AND_FETCH_4: 6304 case BUILT_IN_XOR_AND_FETCH_8: 6305 case BUILT_IN_XOR_AND_FETCH_16: 6306 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1); 6307 target = expand_builtin_sync_operation (mode, exp, XOR, 6308 true, target, ignore); 6309 if (target) 6310 return target; 6311 break; 6312 6313 case BUILT_IN_NAND_AND_FETCH_1: 6314 case BUILT_IN_NAND_AND_FETCH_2: 6315 case BUILT_IN_NAND_AND_FETCH_4: 6316 case BUILT_IN_NAND_AND_FETCH_8: 6317 case BUILT_IN_NAND_AND_FETCH_16: 6318 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1); 6319 target = expand_builtin_sync_operation (mode, exp, NOT, 6320 true, target, ignore); 6321 if (target) 6322 return target; 6323 break; 6324 6325 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1: 6326 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2: 6327 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4: 6328 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8: 6329 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16: 6330 if (mode == VOIDmode) 6331 mode = TYPE_MODE (boolean_type_node); 6332 if (!target || !register_operand (target, mode)) 6333 target = gen_reg_rtx (mode); 6334 6335 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1); 6336 target = expand_builtin_compare_and_swap (mode, exp, true, target); 6337 if (target) 6338 return target; 6339 break; 6340 6341 case BUILT_IN_VAL_COMPARE_AND_SWAP_1: 6342 case BUILT_IN_VAL_COMPARE_AND_SWAP_2: 6343 case BUILT_IN_VAL_COMPARE_AND_SWAP_4: 6344 case BUILT_IN_VAL_COMPARE_AND_SWAP_8: 6345 case BUILT_IN_VAL_COMPARE_AND_SWAP_16: 6346 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1); 6347 target = expand_builtin_compare_and_swap (mode, exp, false, target); 6348 if (target) 6349 return target; 6350 break; 6351 6352 case BUILT_IN_LOCK_TEST_AND_SET_1: 6353 case BUILT_IN_LOCK_TEST_AND_SET_2: 6354 case BUILT_IN_LOCK_TEST_AND_SET_4: 6355 case BUILT_IN_LOCK_TEST_AND_SET_8: 6356 case BUILT_IN_LOCK_TEST_AND_SET_16: 6357 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1); 6358 target = expand_builtin_lock_test_and_set (mode, exp, target); 6359 if (target) 6360 return target; 6361 break; 6362 6363 case BUILT_IN_LOCK_RELEASE_1: 6364 case BUILT_IN_LOCK_RELEASE_2: 6365 case BUILT_IN_LOCK_RELEASE_4: 6366 case BUILT_IN_LOCK_RELEASE_8: 6367 case BUILT_IN_LOCK_RELEASE_16: 6368 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1); 6369 expand_builtin_lock_release (mode, exp); 6370 return const0_rtx; 6371 6372 case BUILT_IN_SYNCHRONIZE: 6373 expand_builtin_synchronize (); 6374 return const0_rtx; 6375 6376 case BUILT_IN_OBJECT_SIZE: 6377 return expand_builtin_object_size (exp); 6378 6379 case BUILT_IN_MEMCPY_CHK: 6380 case BUILT_IN_MEMPCPY_CHK: 6381 case BUILT_IN_MEMMOVE_CHK: 6382 case BUILT_IN_MEMSET_CHK: 6383 target = expand_builtin_memory_chk (exp, target, mode, fcode); 6384 if (target) 6385 return target; 6386 break; 6387 6388 case BUILT_IN_STRCPY_CHK: 6389 case BUILT_IN_STPCPY_CHK: 6390 case BUILT_IN_STRNCPY_CHK: 6391 case BUILT_IN_STRCAT_CHK: 6392 case BUILT_IN_STRNCAT_CHK: 6393 case BUILT_IN_SNPRINTF_CHK: 6394 case BUILT_IN_VSNPRINTF_CHK: 6395 maybe_emit_chk_warning (exp, fcode); 6396 break; 6397 6398 case BUILT_IN_SPRINTF_CHK: 6399 case BUILT_IN_VSPRINTF_CHK: 6400 maybe_emit_sprintf_chk_warning (exp, fcode); 6401 break; 6402 6403 case BUILT_IN_FREE: 6404 maybe_emit_free_warning (exp); 6405 break; 6406 6407 default: /* just do library call, if unknown builtin */ 6408 break; 6409 } 6410 6411 /* The switch statement above can drop through to cause the function 6412 to be called normally. */ 6413 return expand_call (exp, target, ignore); 6414 } 6415 6416 /* Determine whether a tree node represents a call to a built-in 6417 function. If the tree T is a call to a built-in function with 6418 the right number of arguments of the appropriate types, return 6419 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. 6420 Otherwise the return value is END_BUILTINS. */ 6421 6422 enum built_in_function 6423 builtin_mathfn_code (const_tree t) 6424 { 6425 const_tree fndecl, arg, parmlist; 6426 const_tree argtype, parmtype; 6427 const_call_expr_arg_iterator iter; 6428 6429 if (TREE_CODE (t) != CALL_EXPR 6430 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR) 6431 return END_BUILTINS; 6432 6433 fndecl = get_callee_fndecl (t); 6434 if (fndecl == NULL_TREE 6435 || TREE_CODE (fndecl) != FUNCTION_DECL 6436 || ! DECL_BUILT_IN (fndecl) 6437 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 6438 return END_BUILTINS; 6439 6440 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); 6441 init_const_call_expr_arg_iterator (t, &iter); 6442 for (; parmlist; parmlist = TREE_CHAIN (parmlist)) 6443 { 6444 /* If a function doesn't take a variable number of arguments, 6445 the last element in the list will have type `void'. */ 6446 parmtype = TREE_VALUE (parmlist); 6447 if (VOID_TYPE_P (parmtype)) 6448 { 6449 if (more_const_call_expr_args_p (&iter)) 6450 return END_BUILTINS; 6451 return DECL_FUNCTION_CODE (fndecl); 6452 } 6453 6454 if (! more_const_call_expr_args_p (&iter)) 6455 return END_BUILTINS; 6456 6457 arg = next_const_call_expr_arg (&iter); 6458 argtype = TREE_TYPE (arg); 6459 6460 if (SCALAR_FLOAT_TYPE_P (parmtype)) 6461 { 6462 if (! SCALAR_FLOAT_TYPE_P (argtype)) 6463 return END_BUILTINS; 6464 } 6465 else if (COMPLEX_FLOAT_TYPE_P (parmtype)) 6466 { 6467 if (! COMPLEX_FLOAT_TYPE_P (argtype)) 6468 return END_BUILTINS; 6469 } 6470 else if (POINTER_TYPE_P (parmtype)) 6471 { 6472 if (! POINTER_TYPE_P (argtype)) 6473 return END_BUILTINS; 6474 } 6475 else if (INTEGRAL_TYPE_P (parmtype)) 6476 { 6477 if (! INTEGRAL_TYPE_P (argtype)) 6478 return END_BUILTINS; 6479 } 6480 else 6481 return END_BUILTINS; 6482 } 6483 6484 /* Variable-length argument list. */ 6485 return DECL_FUNCTION_CODE (fndecl); 6486 } 6487 6488 /* Fold a call to __builtin_constant_p, if we know its argument ARG will 6489 evaluate to a constant. */ 6490 6491 static tree 6492 fold_builtin_constant_p (tree arg) 6493 { 6494 /* We return 1 for a numeric type that's known to be a constant 6495 value at compile-time or for an aggregate type that's a 6496 literal constant. */ 6497 STRIP_NOPS (arg); 6498 6499 /* If we know this is a constant, emit the constant of one. */ 6500 if (CONSTANT_CLASS_P (arg) 6501 || (TREE_CODE (arg) == CONSTRUCTOR 6502 && TREE_CONSTANT (arg))) 6503 return integer_one_node; 6504 if (TREE_CODE (arg) == ADDR_EXPR) 6505 { 6506 tree op = TREE_OPERAND (arg, 0); 6507 if (TREE_CODE (op) == STRING_CST 6508 || (TREE_CODE (op) == ARRAY_REF 6509 && integer_zerop (TREE_OPERAND (op, 1)) 6510 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST)) 6511 return integer_one_node; 6512 } 6513 6514 /* If this expression has side effects, show we don't know it to be a 6515 constant. Likewise if it's a pointer or aggregate type since in 6516 those case we only want literals, since those are only optimized 6517 when generating RTL, not later. 6518 And finally, if we are compiling an initializer, not code, we 6519 need to return a definite result now; there's not going to be any 6520 more optimization done. */ 6521 if (TREE_SIDE_EFFECTS (arg) 6522 || AGGREGATE_TYPE_P (TREE_TYPE (arg)) 6523 || POINTER_TYPE_P (TREE_TYPE (arg)) 6524 || cfun == 0 6525 || folding_initializer) 6526 return integer_zero_node; 6527 6528 return NULL_TREE; 6529 } 6530 6531 /* Create builtin_expect with PRED and EXPECTED as its arguments and 6532 return it as a truthvalue. */ 6533 6534 static tree 6535 build_builtin_expect_predicate (location_t loc, tree pred, tree expected) 6536 { 6537 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type; 6538 6539 fn = built_in_decls[BUILT_IN_EXPECT]; 6540 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); 6541 ret_type = TREE_TYPE (TREE_TYPE (fn)); 6542 pred_type = TREE_VALUE (arg_types); 6543 expected_type = TREE_VALUE (TREE_CHAIN (arg_types)); 6544 6545 pred = fold_convert_loc (loc, pred_type, pred); 6546 expected = fold_convert_loc (loc, expected_type, expected); 6547 call_expr = build_call_expr_loc (loc, fn, 2, pred, expected); 6548 6549 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr, 6550 build_int_cst (ret_type, 0)); 6551 } 6552 6553 /* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return 6554 NULL_TREE if no simplification is possible. */ 6555 6556 static tree 6557 fold_builtin_expect (location_t loc, tree arg0, tree arg1) 6558 { 6559 tree inner, fndecl; 6560 enum tree_code code; 6561 6562 /* If this is a builtin_expect within a builtin_expect keep the 6563 inner one. See through a comparison against a constant. It 6564 might have been added to create a thruthvalue. */ 6565 inner = arg0; 6566 if (COMPARISON_CLASS_P (inner) 6567 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST) 6568 inner = TREE_OPERAND (inner, 0); 6569 6570 if (TREE_CODE (inner) == CALL_EXPR 6571 && (fndecl = get_callee_fndecl (inner)) 6572 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL 6573 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT) 6574 return arg0; 6575 6576 /* Distribute the expected value over short-circuiting operators. 6577 See through the cast from truthvalue_type_node to long. */ 6578 inner = arg0; 6579 while (TREE_CODE (inner) == NOP_EXPR 6580 && INTEGRAL_TYPE_P (TREE_TYPE (inner)) 6581 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0)))) 6582 inner = TREE_OPERAND (inner, 0); 6583 6584 code = TREE_CODE (inner); 6585 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) 6586 { 6587 tree op0 = TREE_OPERAND (inner, 0); 6588 tree op1 = TREE_OPERAND (inner, 1); 6589 6590 op0 = build_builtin_expect_predicate (loc, op0, arg1); 6591 op1 = build_builtin_expect_predicate (loc, op1, arg1); 6592 inner = build2 (code, TREE_TYPE (inner), op0, op1); 6593 6594 return fold_convert_loc (loc, TREE_TYPE (arg0), inner); 6595 } 6596 6597 /* If the argument isn't invariant then there's nothing else we can do. */ 6598 if (!TREE_CONSTANT (arg0)) 6599 return NULL_TREE; 6600 6601 /* If we expect that a comparison against the argument will fold to 6602 a constant return the constant. In practice, this means a true 6603 constant or the address of a non-weak symbol. */ 6604 inner = arg0; 6605 STRIP_NOPS (inner); 6606 if (TREE_CODE (inner) == ADDR_EXPR) 6607 { 6608 do 6609 { 6610 inner = TREE_OPERAND (inner, 0); 6611 } 6612 while (TREE_CODE (inner) == COMPONENT_REF 6613 || TREE_CODE (inner) == ARRAY_REF); 6614 if ((TREE_CODE (inner) == VAR_DECL 6615 || TREE_CODE (inner) == FUNCTION_DECL) 6616 && DECL_WEAK (inner)) 6617 return NULL_TREE; 6618 } 6619 6620 /* Otherwise, ARG0 already has the proper type for the return value. */ 6621 return arg0; 6622 } 6623 6624 /* Fold a call to __builtin_classify_type with argument ARG. */ 6625 6626 static tree 6627 fold_builtin_classify_type (tree arg) 6628 { 6629 if (arg == 0) 6630 return build_int_cst (NULL_TREE, no_type_class); 6631 6632 return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg))); 6633 } 6634 6635 /* Fold a call to __builtin_strlen with argument ARG. */ 6636 6637 static tree 6638 fold_builtin_strlen (location_t loc, tree type, tree arg) 6639 { 6640 if (!validate_arg (arg, POINTER_TYPE)) 6641 return NULL_TREE; 6642 else 6643 { 6644 tree len = c_strlen (arg, 0); 6645 6646 if (len) 6647 return fold_convert_loc (loc, type, len); 6648 6649 return NULL_TREE; 6650 } 6651 } 6652 6653 /* Fold a call to __builtin_inf or __builtin_huge_val. */ 6654 6655 static tree 6656 fold_builtin_inf (location_t loc, tree type, int warn) 6657 { 6658 REAL_VALUE_TYPE real; 6659 6660 /* __builtin_inff is intended to be usable to define INFINITY on all 6661 targets. If an infinity is not available, INFINITY expands "to a 6662 positive constant of type float that overflows at translation 6663 time", footnote "In this case, using INFINITY will violate the 6664 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4). 6665 Thus we pedwarn to ensure this constraint violation is 6666 diagnosed. */ 6667 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn) 6668 pedwarn (loc, 0, "target format does not support infinity"); 6669 6670 real_inf (&real); 6671 return build_real (type, real); 6672 } 6673 6674 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG. */ 6675 6676 static tree 6677 fold_builtin_nan (tree arg, tree type, int quiet) 6678 { 6679 REAL_VALUE_TYPE real; 6680 const char *str; 6681 6682 if (!validate_arg (arg, POINTER_TYPE)) 6683 return NULL_TREE; 6684 str = c_getstr (arg); 6685 if (!str) 6686 return NULL_TREE; 6687 6688 if (!real_nan (&real, str, quiet, TYPE_MODE (type))) 6689 return NULL_TREE; 6690 6691 return build_real (type, real); 6692 } 6693 6694 /* Return true if the floating point expression T has an integer value. 6695 We also allow +Inf, -Inf and NaN to be considered integer values. */ 6696 6697 static bool 6698 integer_valued_real_p (tree t) 6699 { 6700 switch (TREE_CODE (t)) 6701 { 6702 case FLOAT_EXPR: 6703 return true; 6704 6705 case ABS_EXPR: 6706 case SAVE_EXPR: 6707 return integer_valued_real_p (TREE_OPERAND (t, 0)); 6708 6709 case COMPOUND_EXPR: 6710 case MODIFY_EXPR: 6711 case BIND_EXPR: 6712 return integer_valued_real_p (TREE_OPERAND (t, 1)); 6713 6714 case PLUS_EXPR: 6715 case MINUS_EXPR: 6716 case MULT_EXPR: 6717 case MIN_EXPR: 6718 case MAX_EXPR: 6719 return integer_valued_real_p (TREE_OPERAND (t, 0)) 6720 && integer_valued_real_p (TREE_OPERAND (t, 1)); 6721 6722 case COND_EXPR: 6723 return integer_valued_real_p (TREE_OPERAND (t, 1)) 6724 && integer_valued_real_p (TREE_OPERAND (t, 2)); 6725 6726 case REAL_CST: 6727 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t))); 6728 6729 case NOP_EXPR: 6730 { 6731 tree type = TREE_TYPE (TREE_OPERAND (t, 0)); 6732 if (TREE_CODE (type) == INTEGER_TYPE) 6733 return true; 6734 if (TREE_CODE (type) == REAL_TYPE) 6735 return integer_valued_real_p (TREE_OPERAND (t, 0)); 6736 break; 6737 } 6738 6739 case CALL_EXPR: 6740 switch (builtin_mathfn_code (t)) 6741 { 6742 CASE_FLT_FN (BUILT_IN_CEIL): 6743 CASE_FLT_FN (BUILT_IN_FLOOR): 6744 CASE_FLT_FN (BUILT_IN_NEARBYINT): 6745 CASE_FLT_FN (BUILT_IN_RINT): 6746 CASE_FLT_FN (BUILT_IN_ROUND): 6747 CASE_FLT_FN (BUILT_IN_TRUNC): 6748 return true; 6749 6750 CASE_FLT_FN (BUILT_IN_FMIN): 6751 CASE_FLT_FN (BUILT_IN_FMAX): 6752 return integer_valued_real_p (CALL_EXPR_ARG (t, 0)) 6753 && integer_valued_real_p (CALL_EXPR_ARG (t, 1)); 6754 6755 default: 6756 break; 6757 } 6758 break; 6759 6760 default: 6761 break; 6762 } 6763 return false; 6764 } 6765 6766 /* FNDECL is assumed to be a builtin where truncation can be propagated 6767 across (for instance floor((double)f) == (double)floorf (f). 6768 Do the transformation for a call with argument ARG. */ 6769 6770 static tree 6771 fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg) 6772 { 6773 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 6774 6775 if (!validate_arg (arg, REAL_TYPE)) 6776 return NULL_TREE; 6777 6778 /* Integer rounding functions are idempotent. */ 6779 if (fcode == builtin_mathfn_code (arg)) 6780 return arg; 6781 6782 /* If argument is already integer valued, and we don't need to worry 6783 about setting errno, there's no need to perform rounding. */ 6784 if (! flag_errno_math && integer_valued_real_p (arg)) 6785 return arg; 6786 6787 if (optimize) 6788 { 6789 tree arg0 = strip_float_extensions (arg); 6790 tree ftype = TREE_TYPE (TREE_TYPE (fndecl)); 6791 tree newtype = TREE_TYPE (arg0); 6792 tree decl; 6793 6794 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype) 6795 && (decl = mathfn_built_in (newtype, fcode))) 6796 return fold_convert_loc (loc, ftype, 6797 build_call_expr_loc (loc, decl, 1, 6798 fold_convert_loc (loc, 6799 newtype, 6800 arg0))); 6801 } 6802 return NULL_TREE; 6803 } 6804 6805 /* FNDECL is assumed to be builtin which can narrow the FP type of 6806 the argument, for instance lround((double)f) -> lroundf (f). 6807 Do the transformation for a call with argument ARG. */ 6808 6809 static tree 6810 fold_fixed_mathfn (location_t loc, tree fndecl, tree arg) 6811 { 6812 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 6813 6814 if (!validate_arg (arg, REAL_TYPE)) 6815 return NULL_TREE; 6816 6817 /* If argument is already integer valued, and we don't need to worry 6818 about setting errno, there's no need to perform rounding. */ 6819 if (! flag_errno_math && integer_valued_real_p (arg)) 6820 return fold_build1_loc (loc, FIX_TRUNC_EXPR, 6821 TREE_TYPE (TREE_TYPE (fndecl)), arg); 6822 6823 if (optimize) 6824 { 6825 tree ftype = TREE_TYPE (arg); 6826 tree arg0 = strip_float_extensions (arg); 6827 tree newtype = TREE_TYPE (arg0); 6828 tree decl; 6829 6830 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype) 6831 && (decl = mathfn_built_in (newtype, fcode))) 6832 return build_call_expr_loc (loc, decl, 1, 6833 fold_convert_loc (loc, newtype, arg0)); 6834 } 6835 6836 /* Canonicalize llround (x) to lround (x) on LP64 targets where 6837 sizeof (long long) == sizeof (long). */ 6838 if (TYPE_PRECISION (long_long_integer_type_node) 6839 == TYPE_PRECISION (long_integer_type_node)) 6840 { 6841 tree newfn = NULL_TREE; 6842 switch (fcode) 6843 { 6844 CASE_FLT_FN (BUILT_IN_LLCEIL): 6845 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL); 6846 break; 6847 6848 CASE_FLT_FN (BUILT_IN_LLFLOOR): 6849 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR); 6850 break; 6851 6852 CASE_FLT_FN (BUILT_IN_LLROUND): 6853 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND); 6854 break; 6855 6856 CASE_FLT_FN (BUILT_IN_LLRINT): 6857 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT); 6858 break; 6859 6860 default: 6861 break; 6862 } 6863 6864 if (newfn) 6865 { 6866 tree newcall = build_call_expr_loc (loc, newfn, 1, arg); 6867 return fold_convert_loc (loc, 6868 TREE_TYPE (TREE_TYPE (fndecl)), newcall); 6869 } 6870 } 6871 6872 return NULL_TREE; 6873 } 6874 6875 /* Fold call to builtin cabs, cabsf or cabsl with argument ARG. TYPE is the 6876 return type. Return NULL_TREE if no simplification can be made. */ 6877 6878 static tree 6879 fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl) 6880 { 6881 tree res; 6882 6883 if (!validate_arg (arg, COMPLEX_TYPE) 6884 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE) 6885 return NULL_TREE; 6886 6887 /* Calculate the result when the argument is a constant. */ 6888 if (TREE_CODE (arg) == COMPLEX_CST 6889 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg), 6890 type, mpfr_hypot))) 6891 return res; 6892 6893 if (TREE_CODE (arg) == COMPLEX_EXPR) 6894 { 6895 tree real = TREE_OPERAND (arg, 0); 6896 tree imag = TREE_OPERAND (arg, 1); 6897 6898 /* If either part is zero, cabs is fabs of the other. */ 6899 if (real_zerop (real)) 6900 return fold_build1_loc (loc, ABS_EXPR, type, imag); 6901 if (real_zerop (imag)) 6902 return fold_build1_loc (loc, ABS_EXPR, type, real); 6903 6904 /* cabs(x+xi) -> fabs(x)*sqrt(2). */ 6905 if (flag_unsafe_math_optimizations 6906 && operand_equal_p (real, imag, OEP_PURE_SAME)) 6907 { 6908 const REAL_VALUE_TYPE sqrt2_trunc 6909 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ()); 6910 STRIP_NOPS (real); 6911 return fold_build2_loc (loc, MULT_EXPR, type, 6912 fold_build1_loc (loc, ABS_EXPR, type, real), 6913 build_real (type, sqrt2_trunc)); 6914 } 6915 } 6916 6917 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */ 6918 if (TREE_CODE (arg) == NEGATE_EXPR 6919 || TREE_CODE (arg) == CONJ_EXPR) 6920 return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0)); 6921 6922 /* Don't do this when optimizing for size. */ 6923 if (flag_unsafe_math_optimizations 6924 && optimize && optimize_function_for_speed_p (cfun)) 6925 { 6926 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); 6927 6928 if (sqrtfn != NULL_TREE) 6929 { 6930 tree rpart, ipart, result; 6931 6932 arg = builtin_save_expr (arg); 6933 6934 rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg); 6935 ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg); 6936 6937 rpart = builtin_save_expr (rpart); 6938 ipart = builtin_save_expr (ipart); 6939 6940 result = fold_build2_loc (loc, PLUS_EXPR, type, 6941 fold_build2_loc (loc, MULT_EXPR, type, 6942 rpart, rpart), 6943 fold_build2_loc (loc, MULT_EXPR, type, 6944 ipart, ipart)); 6945 6946 return build_call_expr_loc (loc, sqrtfn, 1, result); 6947 } 6948 } 6949 6950 return NULL_TREE; 6951 } 6952 6953 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG. 6954 Return NULL_TREE if no simplification can be made. */ 6955 6956 static tree 6957 fold_builtin_sqrt (location_t loc, tree arg, tree type) 6958 { 6959 6960 enum built_in_function fcode; 6961 tree res; 6962 6963 if (!validate_arg (arg, REAL_TYPE)) 6964 return NULL_TREE; 6965 6966 /* Calculate the result when the argument is a constant. */ 6967 if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true))) 6968 return res; 6969 6970 /* Optimize sqrt(expN(x)) = expN(x*0.5). */ 6971 fcode = builtin_mathfn_code (arg); 6972 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode)) 6973 { 6974 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); 6975 arg = fold_build2_loc (loc, MULT_EXPR, type, 6976 CALL_EXPR_ARG (arg, 0), 6977 build_real (type, dconsthalf)); 6978 return build_call_expr_loc (loc, expfn, 1, arg); 6979 } 6980 6981 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */ 6982 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode)) 6983 { 6984 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 6985 6986 if (powfn) 6987 { 6988 tree arg0 = CALL_EXPR_ARG (arg, 0); 6989 tree tree_root; 6990 /* The inner root was either sqrt or cbrt. */ 6991 /* This was a conditional expression but it triggered a bug 6992 in Sun C 5.5. */ 6993 REAL_VALUE_TYPE dconstroot; 6994 if (BUILTIN_SQRT_P (fcode)) 6995 dconstroot = dconsthalf; 6996 else 6997 dconstroot = dconst_third (); 6998 6999 /* Adjust for the outer root. */ 7000 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); 7001 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7002 tree_root = build_real (type, dconstroot); 7003 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root); 7004 } 7005 } 7006 7007 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */ 7008 if (flag_unsafe_math_optimizations 7009 && (fcode == BUILT_IN_POW 7010 || fcode == BUILT_IN_POWF 7011 || fcode == BUILT_IN_POWL)) 7012 { 7013 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); 7014 tree arg0 = CALL_EXPR_ARG (arg, 0); 7015 tree arg1 = CALL_EXPR_ARG (arg, 1); 7016 tree narg1; 7017 if (!tree_expr_nonnegative_p (arg0)) 7018 arg0 = build1 (ABS_EXPR, type, arg0); 7019 narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, 7020 build_real (type, dconsthalf)); 7021 return build_call_expr_loc (loc, powfn, 2, arg0, narg1); 7022 } 7023 7024 return NULL_TREE; 7025 } 7026 7027 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG. 7028 Return NULL_TREE if no simplification can be made. */ 7029 7030 static tree 7031 fold_builtin_cbrt (location_t loc, tree arg, tree type) 7032 { 7033 const enum built_in_function fcode = builtin_mathfn_code (arg); 7034 tree res; 7035 7036 if (!validate_arg (arg, REAL_TYPE)) 7037 return NULL_TREE; 7038 7039 /* Calculate the result when the argument is a constant. */ 7040 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0))) 7041 return res; 7042 7043 if (flag_unsafe_math_optimizations) 7044 { 7045 /* Optimize cbrt(expN(x)) -> expN(x/3). */ 7046 if (BUILTIN_EXPONENT_P (fcode)) 7047 { 7048 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); 7049 const REAL_VALUE_TYPE third_trunc = 7050 real_value_truncate (TYPE_MODE (type), dconst_third ()); 7051 arg = fold_build2_loc (loc, MULT_EXPR, type, 7052 CALL_EXPR_ARG (arg, 0), 7053 build_real (type, third_trunc)); 7054 return build_call_expr_loc (loc, expfn, 1, arg); 7055 } 7056 7057 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */ 7058 if (BUILTIN_SQRT_P (fcode)) 7059 { 7060 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7061 7062 if (powfn) 7063 { 7064 tree arg0 = CALL_EXPR_ARG (arg, 0); 7065 tree tree_root; 7066 REAL_VALUE_TYPE dconstroot = dconst_third (); 7067 7068 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); 7069 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7070 tree_root = build_real (type, dconstroot); 7071 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root); 7072 } 7073 } 7074 7075 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */ 7076 if (BUILTIN_CBRT_P (fcode)) 7077 { 7078 tree arg0 = CALL_EXPR_ARG (arg, 0); 7079 if (tree_expr_nonnegative_p (arg0)) 7080 { 7081 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7082 7083 if (powfn) 7084 { 7085 tree tree_root; 7086 REAL_VALUE_TYPE dconstroot; 7087 7088 real_arithmetic (&dconstroot, MULT_EXPR, 7089 dconst_third_ptr (), dconst_third_ptr ()); 7090 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7091 tree_root = build_real (type, dconstroot); 7092 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root); 7093 } 7094 } 7095 } 7096 7097 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */ 7098 if (fcode == BUILT_IN_POW 7099 || fcode == BUILT_IN_POWF 7100 || fcode == BUILT_IN_POWL) 7101 { 7102 tree arg00 = CALL_EXPR_ARG (arg, 0); 7103 tree arg01 = CALL_EXPR_ARG (arg, 1); 7104 if (tree_expr_nonnegative_p (arg00)) 7105 { 7106 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); 7107 const REAL_VALUE_TYPE dconstroot 7108 = real_value_truncate (TYPE_MODE (type), dconst_third ()); 7109 tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01, 7110 build_real (type, dconstroot)); 7111 return build_call_expr_loc (loc, powfn, 2, arg00, narg01); 7112 } 7113 } 7114 } 7115 return NULL_TREE; 7116 } 7117 7118 /* Fold function call to builtin cos, cosf, or cosl with argument ARG. 7119 TYPE is the type of the return value. Return NULL_TREE if no 7120 simplification can be made. */ 7121 7122 static tree 7123 fold_builtin_cos (location_t loc, 7124 tree arg, tree type, tree fndecl) 7125 { 7126 tree res, narg; 7127 7128 if (!validate_arg (arg, REAL_TYPE)) 7129 return NULL_TREE; 7130 7131 /* Calculate the result when the argument is a constant. */ 7132 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0))) 7133 return res; 7134 7135 /* Optimize cos(-x) into cos (x). */ 7136 if ((narg = fold_strip_sign_ops (arg))) 7137 return build_call_expr_loc (loc, fndecl, 1, narg); 7138 7139 return NULL_TREE; 7140 } 7141 7142 /* Fold function call to builtin cosh, coshf, or coshl with argument ARG. 7143 Return NULL_TREE if no simplification can be made. */ 7144 7145 static tree 7146 fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl) 7147 { 7148 if (validate_arg (arg, REAL_TYPE)) 7149 { 7150 tree res, narg; 7151 7152 /* Calculate the result when the argument is a constant. */ 7153 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0))) 7154 return res; 7155 7156 /* Optimize cosh(-x) into cosh (x). */ 7157 if ((narg = fold_strip_sign_ops (arg))) 7158 return build_call_expr_loc (loc, fndecl, 1, narg); 7159 } 7160 7161 return NULL_TREE; 7162 } 7163 7164 /* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with 7165 argument ARG. TYPE is the type of the return value. Return 7166 NULL_TREE if no simplification can be made. */ 7167 7168 static tree 7169 fold_builtin_ccos (location_t loc, tree arg, tree type, tree fndecl, 7170 bool hyper) 7171 { 7172 if (validate_arg (arg, COMPLEX_TYPE) 7173 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE) 7174 { 7175 tree tmp; 7176 7177 /* Calculate the result when the argument is a constant. */ 7178 if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos)))) 7179 return tmp; 7180 7181 /* Optimize fn(-x) into fn(x). */ 7182 if ((tmp = fold_strip_sign_ops (arg))) 7183 return build_call_expr_loc (loc, fndecl, 1, tmp); 7184 } 7185 7186 return NULL_TREE; 7187 } 7188 7189 /* Fold function call to builtin tan, tanf, or tanl with argument ARG. 7190 Return NULL_TREE if no simplification can be made. */ 7191 7192 static tree 7193 fold_builtin_tan (tree arg, tree type) 7194 { 7195 enum built_in_function fcode; 7196 tree res; 7197 7198 if (!validate_arg (arg, REAL_TYPE)) 7199 return NULL_TREE; 7200 7201 /* Calculate the result when the argument is a constant. */ 7202 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0))) 7203 return res; 7204 7205 /* Optimize tan(atan(x)) = x. */ 7206 fcode = builtin_mathfn_code (arg); 7207 if (flag_unsafe_math_optimizations 7208 && (fcode == BUILT_IN_ATAN 7209 || fcode == BUILT_IN_ATANF 7210 || fcode == BUILT_IN_ATANL)) 7211 return CALL_EXPR_ARG (arg, 0); 7212 7213 return NULL_TREE; 7214 } 7215 7216 /* Fold function call to builtin sincos, sincosf, or sincosl. Return 7217 NULL_TREE if no simplification can be made. */ 7218 7219 static tree 7220 fold_builtin_sincos (location_t loc, 7221 tree arg0, tree arg1, tree arg2) 7222 { 7223 tree type; 7224 tree res, fn, call; 7225 7226 if (!validate_arg (arg0, REAL_TYPE) 7227 || !validate_arg (arg1, POINTER_TYPE) 7228 || !validate_arg (arg2, POINTER_TYPE)) 7229 return NULL_TREE; 7230 7231 type = TREE_TYPE (arg0); 7232 7233 /* Calculate the result when the argument is a constant. */ 7234 if ((res = do_mpfr_sincos (arg0, arg1, arg2))) 7235 return res; 7236 7237 /* Canonicalize sincos to cexpi. */ 7238 if (!TARGET_C99_FUNCTIONS) 7239 return NULL_TREE; 7240 fn = mathfn_built_in (type, BUILT_IN_CEXPI); 7241 if (!fn) 7242 return NULL_TREE; 7243 7244 call = build_call_expr_loc (loc, fn, 1, arg0); 7245 call = builtin_save_expr (call); 7246 7247 return build2 (COMPOUND_EXPR, void_type_node, 7248 build2 (MODIFY_EXPR, void_type_node, 7249 build_fold_indirect_ref_loc (loc, arg1), 7250 build1 (IMAGPART_EXPR, type, call)), 7251 build2 (MODIFY_EXPR, void_type_node, 7252 build_fold_indirect_ref_loc (loc, arg2), 7253 build1 (REALPART_EXPR, type, call))); 7254 } 7255 7256 /* Fold function call to builtin cexp, cexpf, or cexpl. Return 7257 NULL_TREE if no simplification can be made. */ 7258 7259 static tree 7260 fold_builtin_cexp (location_t loc, tree arg0, tree type) 7261 { 7262 tree rtype; 7263 tree realp, imagp, ifn; 7264 tree res; 7265 7266 if (!validate_arg (arg0, COMPLEX_TYPE) 7267 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE) 7268 return NULL_TREE; 7269 7270 /* Calculate the result when the argument is a constant. */ 7271 if ((res = do_mpc_arg1 (arg0, type, mpc_exp))) 7272 return res; 7273 7274 rtype = TREE_TYPE (TREE_TYPE (arg0)); 7275 7276 /* In case we can figure out the real part of arg0 and it is constant zero 7277 fold to cexpi. */ 7278 if (!TARGET_C99_FUNCTIONS) 7279 return NULL_TREE; 7280 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI); 7281 if (!ifn) 7282 return NULL_TREE; 7283 7284 if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0)) 7285 && real_zerop (realp)) 7286 { 7287 tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0); 7288 return build_call_expr_loc (loc, ifn, 1, narg); 7289 } 7290 7291 /* In case we can easily decompose real and imaginary parts split cexp 7292 to exp (r) * cexpi (i). */ 7293 if (flag_unsafe_math_optimizations 7294 && realp) 7295 { 7296 tree rfn, rcall, icall; 7297 7298 rfn = mathfn_built_in (rtype, BUILT_IN_EXP); 7299 if (!rfn) 7300 return NULL_TREE; 7301 7302 imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0); 7303 if (!imagp) 7304 return NULL_TREE; 7305 7306 icall = build_call_expr_loc (loc, ifn, 1, imagp); 7307 icall = builtin_save_expr (icall); 7308 rcall = build_call_expr_loc (loc, rfn, 1, realp); 7309 rcall = builtin_save_expr (rcall); 7310 return fold_build2_loc (loc, COMPLEX_EXPR, type, 7311 fold_build2_loc (loc, MULT_EXPR, rtype, 7312 rcall, 7313 fold_build1_loc (loc, REALPART_EXPR, 7314 rtype, icall)), 7315 fold_build2_loc (loc, MULT_EXPR, rtype, 7316 rcall, 7317 fold_build1_loc (loc, IMAGPART_EXPR, 7318 rtype, icall))); 7319 } 7320 7321 return NULL_TREE; 7322 } 7323 7324 /* Fold function call to builtin trunc, truncf or truncl with argument ARG. 7325 Return NULL_TREE if no simplification can be made. */ 7326 7327 static tree 7328 fold_builtin_trunc (location_t loc, tree fndecl, tree arg) 7329 { 7330 if (!validate_arg (arg, REAL_TYPE)) 7331 return NULL_TREE; 7332 7333 /* Optimize trunc of constant value. */ 7334 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 7335 { 7336 REAL_VALUE_TYPE r, x; 7337 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7338 7339 x = TREE_REAL_CST (arg); 7340 real_trunc (&r, TYPE_MODE (type), &x); 7341 return build_real (type, r); 7342 } 7343 7344 return fold_trunc_transparent_mathfn (loc, fndecl, arg); 7345 } 7346 7347 /* Fold function call to builtin floor, floorf or floorl with argument ARG. 7348 Return NULL_TREE if no simplification can be made. */ 7349 7350 static tree 7351 fold_builtin_floor (location_t loc, tree fndecl, tree arg) 7352 { 7353 if (!validate_arg (arg, REAL_TYPE)) 7354 return NULL_TREE; 7355 7356 /* Optimize floor of constant value. */ 7357 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 7358 { 7359 REAL_VALUE_TYPE x; 7360 7361 x = TREE_REAL_CST (arg); 7362 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 7363 { 7364 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7365 REAL_VALUE_TYPE r; 7366 7367 real_floor (&r, TYPE_MODE (type), &x); 7368 return build_real (type, r); 7369 } 7370 } 7371 7372 /* Fold floor (x) where x is nonnegative to trunc (x). */ 7373 if (tree_expr_nonnegative_p (arg)) 7374 { 7375 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC); 7376 if (truncfn) 7377 return build_call_expr_loc (loc, truncfn, 1, arg); 7378 } 7379 7380 return fold_trunc_transparent_mathfn (loc, fndecl, arg); 7381 } 7382 7383 /* Fold function call to builtin ceil, ceilf or ceill with argument ARG. 7384 Return NULL_TREE if no simplification can be made. */ 7385 7386 static tree 7387 fold_builtin_ceil (location_t loc, tree fndecl, tree arg) 7388 { 7389 if (!validate_arg (arg, REAL_TYPE)) 7390 return NULL_TREE; 7391 7392 /* Optimize ceil of constant value. */ 7393 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 7394 { 7395 REAL_VALUE_TYPE x; 7396 7397 x = TREE_REAL_CST (arg); 7398 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 7399 { 7400 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7401 REAL_VALUE_TYPE r; 7402 7403 real_ceil (&r, TYPE_MODE (type), &x); 7404 return build_real (type, r); 7405 } 7406 } 7407 7408 return fold_trunc_transparent_mathfn (loc, fndecl, arg); 7409 } 7410 7411 /* Fold function call to builtin round, roundf or roundl with argument ARG. 7412 Return NULL_TREE if no simplification can be made. */ 7413 7414 static tree 7415 fold_builtin_round (location_t loc, tree fndecl, tree arg) 7416 { 7417 if (!validate_arg (arg, REAL_TYPE)) 7418 return NULL_TREE; 7419 7420 /* Optimize round of constant value. */ 7421 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 7422 { 7423 REAL_VALUE_TYPE x; 7424 7425 x = TREE_REAL_CST (arg); 7426 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 7427 { 7428 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7429 REAL_VALUE_TYPE r; 7430 7431 real_round (&r, TYPE_MODE (type), &x); 7432 return build_real (type, r); 7433 } 7434 } 7435 7436 return fold_trunc_transparent_mathfn (loc, fndecl, arg); 7437 } 7438 7439 /* Fold function call to builtin lround, lroundf or lroundl (or the 7440 corresponding long long versions) and other rounding functions. ARG 7441 is the argument to the call. Return NULL_TREE if no simplification 7442 can be made. */ 7443 7444 static tree 7445 fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg) 7446 { 7447 if (!validate_arg (arg, REAL_TYPE)) 7448 return NULL_TREE; 7449 7450 /* Optimize lround of constant value. */ 7451 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 7452 { 7453 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg); 7454 7455 if (real_isfinite (&x)) 7456 { 7457 tree itype = TREE_TYPE (TREE_TYPE (fndecl)); 7458 tree ftype = TREE_TYPE (arg); 7459 unsigned HOST_WIDE_INT lo2; 7460 HOST_WIDE_INT hi, lo; 7461 REAL_VALUE_TYPE r; 7462 7463 switch (DECL_FUNCTION_CODE (fndecl)) 7464 { 7465 CASE_FLT_FN (BUILT_IN_LFLOOR): 7466 CASE_FLT_FN (BUILT_IN_LLFLOOR): 7467 real_floor (&r, TYPE_MODE (ftype), &x); 7468 break; 7469 7470 CASE_FLT_FN (BUILT_IN_LCEIL): 7471 CASE_FLT_FN (BUILT_IN_LLCEIL): 7472 real_ceil (&r, TYPE_MODE (ftype), &x); 7473 break; 7474 7475 CASE_FLT_FN (BUILT_IN_LROUND): 7476 CASE_FLT_FN (BUILT_IN_LLROUND): 7477 real_round (&r, TYPE_MODE (ftype), &x); 7478 break; 7479 7480 default: 7481 gcc_unreachable (); 7482 } 7483 7484 REAL_VALUE_TO_INT (&lo, &hi, r); 7485 if (!fit_double_type (lo, hi, &lo2, &hi, itype)) 7486 return build_int_cst_wide (itype, lo2, hi); 7487 } 7488 } 7489 7490 switch (DECL_FUNCTION_CODE (fndecl)) 7491 { 7492 CASE_FLT_FN (BUILT_IN_LFLOOR): 7493 CASE_FLT_FN (BUILT_IN_LLFLOOR): 7494 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */ 7495 if (tree_expr_nonnegative_p (arg)) 7496 return fold_build1_loc (loc, FIX_TRUNC_EXPR, 7497 TREE_TYPE (TREE_TYPE (fndecl)), arg); 7498 break; 7499 default:; 7500 } 7501 7502 return fold_fixed_mathfn (loc, fndecl, arg); 7503 } 7504 7505 /* Fold function call to builtin ffs, clz, ctz, popcount and parity 7506 and their long and long long variants (i.e. ffsl and ffsll). ARG is 7507 the argument to the call. Return NULL_TREE if no simplification can 7508 be made. */ 7509 7510 static tree 7511 fold_builtin_bitop (tree fndecl, tree arg) 7512 { 7513 if (!validate_arg (arg, INTEGER_TYPE)) 7514 return NULL_TREE; 7515 7516 /* Optimize for constant argument. */ 7517 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg)) 7518 { 7519 HOST_WIDE_INT hi, width, result; 7520 unsigned HOST_WIDE_INT lo; 7521 tree type; 7522 7523 type = TREE_TYPE (arg); 7524 width = TYPE_PRECISION (type); 7525 lo = TREE_INT_CST_LOW (arg); 7526 7527 /* Clear all the bits that are beyond the type's precision. */ 7528 if (width > HOST_BITS_PER_WIDE_INT) 7529 { 7530 hi = TREE_INT_CST_HIGH (arg); 7531 if (width < 2 * HOST_BITS_PER_WIDE_INT) 7532 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT)); 7533 } 7534 else 7535 { 7536 hi = 0; 7537 if (width < HOST_BITS_PER_WIDE_INT) 7538 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width); 7539 } 7540 7541 switch (DECL_FUNCTION_CODE (fndecl)) 7542 { 7543 CASE_INT_FN (BUILT_IN_FFS): 7544 if (lo != 0) 7545 result = exact_log2 (lo & -lo) + 1; 7546 else if (hi != 0) 7547 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1; 7548 else 7549 result = 0; 7550 break; 7551 7552 CASE_INT_FN (BUILT_IN_CLZ): 7553 if (hi != 0) 7554 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT; 7555 else if (lo != 0) 7556 result = width - floor_log2 (lo) - 1; 7557 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result)) 7558 result = width; 7559 break; 7560 7561 CASE_INT_FN (BUILT_IN_CTZ): 7562 if (lo != 0) 7563 result = exact_log2 (lo & -lo); 7564 else if (hi != 0) 7565 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi); 7566 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result)) 7567 result = width; 7568 break; 7569 7570 CASE_INT_FN (BUILT_IN_POPCOUNT): 7571 result = 0; 7572 while (lo) 7573 result++, lo &= lo - 1; 7574 while (hi) 7575 result++, hi &= hi - 1; 7576 break; 7577 7578 CASE_INT_FN (BUILT_IN_PARITY): 7579 result = 0; 7580 while (lo) 7581 result++, lo &= lo - 1; 7582 while (hi) 7583 result++, hi &= hi - 1; 7584 result &= 1; 7585 break; 7586 7587 default: 7588 gcc_unreachable (); 7589 } 7590 7591 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result); 7592 } 7593 7594 return NULL_TREE; 7595 } 7596 7597 /* Fold function call to builtin_bswap and the long and long long 7598 variants. Return NULL_TREE if no simplification can be made. */ 7599 static tree 7600 fold_builtin_bswap (tree fndecl, tree arg) 7601 { 7602 if (! validate_arg (arg, INTEGER_TYPE)) 7603 return NULL_TREE; 7604 7605 /* Optimize constant value. */ 7606 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg)) 7607 { 7608 HOST_WIDE_INT hi, width, r_hi = 0; 7609 unsigned HOST_WIDE_INT lo, r_lo = 0; 7610 tree type; 7611 7612 type = TREE_TYPE (arg); 7613 width = TYPE_PRECISION (type); 7614 lo = TREE_INT_CST_LOW (arg); 7615 hi = TREE_INT_CST_HIGH (arg); 7616 7617 switch (DECL_FUNCTION_CODE (fndecl)) 7618 { 7619 case BUILT_IN_BSWAP32: 7620 case BUILT_IN_BSWAP64: 7621 { 7622 int s; 7623 7624 for (s = 0; s < width; s += 8) 7625 { 7626 int d = width - s - 8; 7627 unsigned HOST_WIDE_INT byte; 7628 7629 if (s < HOST_BITS_PER_WIDE_INT) 7630 byte = (lo >> s) & 0xff; 7631 else 7632 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff; 7633 7634 if (d < HOST_BITS_PER_WIDE_INT) 7635 r_lo |= byte << d; 7636 else 7637 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT); 7638 } 7639 } 7640 7641 break; 7642 7643 default: 7644 gcc_unreachable (); 7645 } 7646 7647 if (width < HOST_BITS_PER_WIDE_INT) 7648 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo); 7649 else 7650 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi); 7651 } 7652 7653 return NULL_TREE; 7654 } 7655 7656 /* A subroutine of fold_builtin to fold the various logarithmic 7657 functions. Return NULL_TREE if no simplification can me made. 7658 FUNC is the corresponding MPFR logarithm function. */ 7659 7660 static tree 7661 fold_builtin_logarithm (location_t loc, tree fndecl, tree arg, 7662 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t)) 7663 { 7664 if (validate_arg (arg, REAL_TYPE)) 7665 { 7666 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7667 tree res; 7668 const enum built_in_function fcode = builtin_mathfn_code (arg); 7669 7670 /* Calculate the result when the argument is a constant. */ 7671 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false))) 7672 return res; 7673 7674 /* Special case, optimize logN(expN(x)) = x. */ 7675 if (flag_unsafe_math_optimizations 7676 && ((func == mpfr_log 7677 && (fcode == BUILT_IN_EXP 7678 || fcode == BUILT_IN_EXPF 7679 || fcode == BUILT_IN_EXPL)) 7680 || (func == mpfr_log2 7681 && (fcode == BUILT_IN_EXP2 7682 || fcode == BUILT_IN_EXP2F 7683 || fcode == BUILT_IN_EXP2L)) 7684 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode))))) 7685 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0)); 7686 7687 /* Optimize logN(func()) for various exponential functions. We 7688 want to determine the value "x" and the power "exponent" in 7689 order to transform logN(x**exponent) into exponent*logN(x). */ 7690 if (flag_unsafe_math_optimizations) 7691 { 7692 tree exponent = 0, x = 0; 7693 7694 switch (fcode) 7695 { 7696 CASE_FLT_FN (BUILT_IN_EXP): 7697 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */ 7698 x = build_real (type, real_value_truncate (TYPE_MODE (type), 7699 dconst_e ())); 7700 exponent = CALL_EXPR_ARG (arg, 0); 7701 break; 7702 CASE_FLT_FN (BUILT_IN_EXP2): 7703 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */ 7704 x = build_real (type, dconst2); 7705 exponent = CALL_EXPR_ARG (arg, 0); 7706 break; 7707 CASE_FLT_FN (BUILT_IN_EXP10): 7708 CASE_FLT_FN (BUILT_IN_POW10): 7709 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */ 7710 { 7711 REAL_VALUE_TYPE dconst10; 7712 real_from_integer (&dconst10, VOIDmode, 10, 0, 0); 7713 x = build_real (type, dconst10); 7714 } 7715 exponent = CALL_EXPR_ARG (arg, 0); 7716 break; 7717 CASE_FLT_FN (BUILT_IN_SQRT): 7718 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */ 7719 x = CALL_EXPR_ARG (arg, 0); 7720 exponent = build_real (type, dconsthalf); 7721 break; 7722 CASE_FLT_FN (BUILT_IN_CBRT): 7723 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */ 7724 x = CALL_EXPR_ARG (arg, 0); 7725 exponent = build_real (type, real_value_truncate (TYPE_MODE (type), 7726 dconst_third ())); 7727 break; 7728 CASE_FLT_FN (BUILT_IN_POW): 7729 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */ 7730 x = CALL_EXPR_ARG (arg, 0); 7731 exponent = CALL_EXPR_ARG (arg, 1); 7732 break; 7733 default: 7734 break; 7735 } 7736 7737 /* Now perform the optimization. */ 7738 if (x && exponent) 7739 { 7740 tree logfn = build_call_expr_loc (loc, fndecl, 1, x); 7741 return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn); 7742 } 7743 } 7744 } 7745 7746 return NULL_TREE; 7747 } 7748 7749 /* Fold a builtin function call to hypot, hypotf, or hypotl. Return 7750 NULL_TREE if no simplification can be made. */ 7751 7752 static tree 7753 fold_builtin_hypot (location_t loc, tree fndecl, 7754 tree arg0, tree arg1, tree type) 7755 { 7756 tree res, narg0, narg1; 7757 7758 if (!validate_arg (arg0, REAL_TYPE) 7759 || !validate_arg (arg1, REAL_TYPE)) 7760 return NULL_TREE; 7761 7762 /* Calculate the result when the argument is a constant. */ 7763 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot))) 7764 return res; 7765 7766 /* If either argument to hypot has a negate or abs, strip that off. 7767 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */ 7768 narg0 = fold_strip_sign_ops (arg0); 7769 narg1 = fold_strip_sign_ops (arg1); 7770 if (narg0 || narg1) 7771 { 7772 return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0, 7773 narg1 ? narg1 : arg1); 7774 } 7775 7776 /* If either argument is zero, hypot is fabs of the other. */ 7777 if (real_zerop (arg0)) 7778 return fold_build1_loc (loc, ABS_EXPR, type, arg1); 7779 else if (real_zerop (arg1)) 7780 return fold_build1_loc (loc, ABS_EXPR, type, arg0); 7781 7782 /* hypot(x,x) -> fabs(x)*sqrt(2). */ 7783 if (flag_unsafe_math_optimizations 7784 && operand_equal_p (arg0, arg1, OEP_PURE_SAME)) 7785 { 7786 const REAL_VALUE_TYPE sqrt2_trunc 7787 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ()); 7788 return fold_build2_loc (loc, MULT_EXPR, type, 7789 fold_build1_loc (loc, ABS_EXPR, type, arg0), 7790 build_real (type, sqrt2_trunc)); 7791 } 7792 7793 return NULL_TREE; 7794 } 7795 7796 7797 /* Fold a builtin function call to pow, powf, or powl. Return 7798 NULL_TREE if no simplification can be made. */ 7799 static tree 7800 fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type) 7801 { 7802 tree res; 7803 7804 if (!validate_arg (arg0, REAL_TYPE) 7805 || !validate_arg (arg1, REAL_TYPE)) 7806 return NULL_TREE; 7807 7808 /* Calculate the result when the argument is a constant. */ 7809 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow))) 7810 return res; 7811 7812 /* Optimize pow(1.0,y) = 1.0. */ 7813 if (real_onep (arg0)) 7814 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1); 7815 7816 if (TREE_CODE (arg1) == REAL_CST 7817 && !TREE_OVERFLOW (arg1)) 7818 { 7819 REAL_VALUE_TYPE cint; 7820 REAL_VALUE_TYPE c; 7821 HOST_WIDE_INT n; 7822 7823 c = TREE_REAL_CST (arg1); 7824 7825 /* Optimize pow(x,0.0) = 1.0. */ 7826 if (REAL_VALUES_EQUAL (c, dconst0)) 7827 return omit_one_operand_loc (loc, type, build_real (type, dconst1), 7828 arg0); 7829 7830 /* Optimize pow(x,1.0) = x. */ 7831 if (REAL_VALUES_EQUAL (c, dconst1)) 7832 return arg0; 7833 7834 /* Optimize pow(x,-1.0) = 1.0/x. */ 7835 if (REAL_VALUES_EQUAL (c, dconstm1)) 7836 return fold_build2_loc (loc, RDIV_EXPR, type, 7837 build_real (type, dconst1), arg0); 7838 7839 /* Optimize pow(x,0.5) = sqrt(x). */ 7840 if (flag_unsafe_math_optimizations 7841 && REAL_VALUES_EQUAL (c, dconsthalf)) 7842 { 7843 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); 7844 7845 if (sqrtfn != NULL_TREE) 7846 return build_call_expr_loc (loc, sqrtfn, 1, arg0); 7847 } 7848 7849 /* Optimize pow(x,1.0/3.0) = cbrt(x). */ 7850 if (flag_unsafe_math_optimizations) 7851 { 7852 const REAL_VALUE_TYPE dconstroot 7853 = real_value_truncate (TYPE_MODE (type), dconst_third ()); 7854 7855 if (REAL_VALUES_EQUAL (c, dconstroot)) 7856 { 7857 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT); 7858 if (cbrtfn != NULL_TREE) 7859 return build_call_expr_loc (loc, cbrtfn, 1, arg0); 7860 } 7861 } 7862 7863 /* Check for an integer exponent. */ 7864 n = real_to_integer (&c); 7865 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); 7866 if (real_identical (&c, &cint)) 7867 { 7868 /* Attempt to evaluate pow at compile-time, unless this should 7869 raise an exception. */ 7870 if (TREE_CODE (arg0) == REAL_CST 7871 && !TREE_OVERFLOW (arg0) 7872 && (n > 0 7873 || (!flag_trapping_math && !flag_errno_math) 7874 || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0))) 7875 { 7876 REAL_VALUE_TYPE x; 7877 bool inexact; 7878 7879 x = TREE_REAL_CST (arg0); 7880 inexact = real_powi (&x, TYPE_MODE (type), &x, n); 7881 if (flag_unsafe_math_optimizations || !inexact) 7882 return build_real (type, x); 7883 } 7884 7885 /* Strip sign ops from even integer powers. */ 7886 if ((n & 1) == 0 && flag_unsafe_math_optimizations) 7887 { 7888 tree narg0 = fold_strip_sign_ops (arg0); 7889 if (narg0) 7890 return build_call_expr_loc (loc, fndecl, 2, narg0, arg1); 7891 } 7892 } 7893 } 7894 7895 if (flag_unsafe_math_optimizations) 7896 { 7897 const enum built_in_function fcode = builtin_mathfn_code (arg0); 7898 7899 /* Optimize pow(expN(x),y) = expN(x*y). */ 7900 if (BUILTIN_EXPONENT_P (fcode)) 7901 { 7902 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0); 7903 tree arg = CALL_EXPR_ARG (arg0, 0); 7904 arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1); 7905 return build_call_expr_loc (loc, expfn, 1, arg); 7906 } 7907 7908 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */ 7909 if (BUILTIN_SQRT_P (fcode)) 7910 { 7911 tree narg0 = CALL_EXPR_ARG (arg0, 0); 7912 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, 7913 build_real (type, dconsthalf)); 7914 return build_call_expr_loc (loc, fndecl, 2, narg0, narg1); 7915 } 7916 7917 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */ 7918 if (BUILTIN_CBRT_P (fcode)) 7919 { 7920 tree arg = CALL_EXPR_ARG (arg0, 0); 7921 if (tree_expr_nonnegative_p (arg)) 7922 { 7923 const REAL_VALUE_TYPE dconstroot 7924 = real_value_truncate (TYPE_MODE (type), dconst_third ()); 7925 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, 7926 build_real (type, dconstroot)); 7927 return build_call_expr_loc (loc, fndecl, 2, arg, narg1); 7928 } 7929 } 7930 7931 /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative. */ 7932 if (fcode == BUILT_IN_POW 7933 || fcode == BUILT_IN_POWF 7934 || fcode == BUILT_IN_POWL) 7935 { 7936 tree arg00 = CALL_EXPR_ARG (arg0, 0); 7937 if (tree_expr_nonnegative_p (arg00)) 7938 { 7939 tree arg01 = CALL_EXPR_ARG (arg0, 1); 7940 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1); 7941 return build_call_expr_loc (loc, fndecl, 2, arg00, narg1); 7942 } 7943 } 7944 } 7945 7946 return NULL_TREE; 7947 } 7948 7949 /* Fold a builtin function call to powi, powif, or powil with argument ARG. 7950 Return NULL_TREE if no simplification can be made. */ 7951 static tree 7952 fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED, 7953 tree arg0, tree arg1, tree type) 7954 { 7955 if (!validate_arg (arg0, REAL_TYPE) 7956 || !validate_arg (arg1, INTEGER_TYPE)) 7957 return NULL_TREE; 7958 7959 /* Optimize pow(1.0,y) = 1.0. */ 7960 if (real_onep (arg0)) 7961 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1); 7962 7963 if (host_integerp (arg1, 0)) 7964 { 7965 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1); 7966 7967 /* Evaluate powi at compile-time. */ 7968 if (TREE_CODE (arg0) == REAL_CST 7969 && !TREE_OVERFLOW (arg0)) 7970 { 7971 REAL_VALUE_TYPE x; 7972 x = TREE_REAL_CST (arg0); 7973 real_powi (&x, TYPE_MODE (type), &x, c); 7974 return build_real (type, x); 7975 } 7976 7977 /* Optimize pow(x,0) = 1.0. */ 7978 if (c == 0) 7979 return omit_one_operand_loc (loc, type, build_real (type, dconst1), 7980 arg0); 7981 7982 /* Optimize pow(x,1) = x. */ 7983 if (c == 1) 7984 return arg0; 7985 7986 /* Optimize pow(x,-1) = 1.0/x. */ 7987 if (c == -1) 7988 return fold_build2_loc (loc, RDIV_EXPR, type, 7989 build_real (type, dconst1), arg0); 7990 } 7991 7992 return NULL_TREE; 7993 } 7994 7995 /* A subroutine of fold_builtin to fold the various exponent 7996 functions. Return NULL_TREE if no simplification can be made. 7997 FUNC is the corresponding MPFR exponent function. */ 7998 7999 static tree 8000 fold_builtin_exponent (location_t loc, tree fndecl, tree arg, 8001 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t)) 8002 { 8003 if (validate_arg (arg, REAL_TYPE)) 8004 { 8005 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8006 tree res; 8007 8008 /* Calculate the result when the argument is a constant. */ 8009 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0))) 8010 return res; 8011 8012 /* Optimize expN(logN(x)) = x. */ 8013 if (flag_unsafe_math_optimizations) 8014 { 8015 const enum built_in_function fcode = builtin_mathfn_code (arg); 8016 8017 if ((func == mpfr_exp 8018 && (fcode == BUILT_IN_LOG 8019 || fcode == BUILT_IN_LOGF 8020 || fcode == BUILT_IN_LOGL)) 8021 || (func == mpfr_exp2 8022 && (fcode == BUILT_IN_LOG2 8023 || fcode == BUILT_IN_LOG2F 8024 || fcode == BUILT_IN_LOG2L)) 8025 || (func == mpfr_exp10 8026 && (fcode == BUILT_IN_LOG10 8027 || fcode == BUILT_IN_LOG10F 8028 || fcode == BUILT_IN_LOG10L))) 8029 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0)); 8030 } 8031 } 8032 8033 return NULL_TREE; 8034 } 8035 8036 /* Return true if VAR is a VAR_DECL or a component thereof. */ 8037 8038 static bool 8039 var_decl_component_p (tree var) 8040 { 8041 tree inner = var; 8042 while (handled_component_p (inner)) 8043 inner = TREE_OPERAND (inner, 0); 8044 return SSA_VAR_P (inner); 8045 } 8046 8047 /* Fold function call to builtin memset. Return 8048 NULL_TREE if no simplification can be made. */ 8049 8050 static tree 8051 fold_builtin_memset (location_t loc, tree dest, tree c, tree len, 8052 tree type, bool ignore) 8053 { 8054 tree var, ret, etype; 8055 unsigned HOST_WIDE_INT length, cval; 8056 8057 if (! validate_arg (dest, POINTER_TYPE) 8058 || ! validate_arg (c, INTEGER_TYPE) 8059 || ! validate_arg (len, INTEGER_TYPE)) 8060 return NULL_TREE; 8061 8062 if (! host_integerp (len, 1)) 8063 return NULL_TREE; 8064 8065 /* If the LEN parameter is zero, return DEST. */ 8066 if (integer_zerop (len)) 8067 return omit_one_operand_loc (loc, type, dest, c); 8068 8069 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest)) 8070 return NULL_TREE; 8071 8072 var = dest; 8073 STRIP_NOPS (var); 8074 if (TREE_CODE (var) != ADDR_EXPR) 8075 return NULL_TREE; 8076 8077 var = TREE_OPERAND (var, 0); 8078 if (TREE_THIS_VOLATILE (var)) 8079 return NULL_TREE; 8080 8081 etype = TREE_TYPE (var); 8082 if (TREE_CODE (etype) == ARRAY_TYPE) 8083 etype = TREE_TYPE (etype); 8084 8085 if (!INTEGRAL_TYPE_P (etype) 8086 && !POINTER_TYPE_P (etype)) 8087 return NULL_TREE; 8088 8089 if (! var_decl_component_p (var)) 8090 return NULL_TREE; 8091 8092 length = tree_low_cst (len, 1); 8093 if (GET_MODE_SIZE (TYPE_MODE (etype)) != length 8094 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT 8095 < (int) length) 8096 return NULL_TREE; 8097 8098 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT) 8099 return NULL_TREE; 8100 8101 if (integer_zerop (c)) 8102 cval = 0; 8103 else 8104 { 8105 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64) 8106 return NULL_TREE; 8107 8108 cval = tree_low_cst (c, 1); 8109 cval &= 0xff; 8110 cval |= cval << 8; 8111 cval |= cval << 16; 8112 cval |= (cval << 31) << 1; 8113 } 8114 8115 ret = build_int_cst_type (etype, cval); 8116 var = build_fold_indirect_ref_loc (loc, 8117 fold_convert_loc (loc, 8118 build_pointer_type (etype), 8119 dest)); 8120 ret = build2 (MODIFY_EXPR, etype, var, ret); 8121 if (ignore) 8122 return ret; 8123 8124 return omit_one_operand_loc (loc, type, dest, ret); 8125 } 8126 8127 /* Fold function call to builtin memset. Return 8128 NULL_TREE if no simplification can be made. */ 8129 8130 static tree 8131 fold_builtin_bzero (location_t loc, tree dest, tree size, bool ignore) 8132 { 8133 if (! validate_arg (dest, POINTER_TYPE) 8134 || ! validate_arg (size, INTEGER_TYPE)) 8135 return NULL_TREE; 8136 8137 if (!ignore) 8138 return NULL_TREE; 8139 8140 /* New argument list transforming bzero(ptr x, int y) to 8141 memset(ptr x, int 0, size_t y). This is done this way 8142 so that if it isn't expanded inline, we fallback to 8143 calling bzero instead of memset. */ 8144 8145 return fold_builtin_memset (loc, dest, integer_zero_node, 8146 fold_convert_loc (loc, sizetype, size), 8147 void_type_node, ignore); 8148 } 8149 8150 /* Fold function call to builtin mem{{,p}cpy,move}. Return 8151 NULL_TREE if no simplification can be made. 8152 If ENDP is 0, return DEST (like memcpy). 8153 If ENDP is 1, return DEST+LEN (like mempcpy). 8154 If ENDP is 2, return DEST+LEN-1 (like stpcpy). 8155 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap 8156 (memmove). */ 8157 8158 static tree 8159 fold_builtin_memory_op (location_t loc, tree dest, tree src, 8160 tree len, tree type, bool ignore, int endp) 8161 { 8162 tree destvar, srcvar, expr; 8163 8164 if (! validate_arg (dest, POINTER_TYPE) 8165 || ! validate_arg (src, POINTER_TYPE) 8166 || ! validate_arg (len, INTEGER_TYPE)) 8167 return NULL_TREE; 8168 8169 /* If the LEN parameter is zero, return DEST. */ 8170 if (integer_zerop (len)) 8171 return omit_one_operand_loc (loc, type, dest, src); 8172 8173 /* If SRC and DEST are the same (and not volatile), return 8174 DEST{,+LEN,+LEN-1}. */ 8175 if (operand_equal_p (src, dest, 0)) 8176 expr = len; 8177 else 8178 { 8179 tree srctype, desttype; 8180 int src_align, dest_align; 8181 8182 if (endp == 3) 8183 { 8184 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 8185 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 8186 8187 /* Both DEST and SRC must be pointer types. 8188 ??? This is what old code did. Is the testing for pointer types 8189 really mandatory? 8190 8191 If either SRC is readonly or length is 1, we can use memcpy. */ 8192 if (!dest_align || !src_align) 8193 return NULL_TREE; 8194 if (readonly_data_expr (src) 8195 || (host_integerp (len, 1) 8196 && (MIN (src_align, dest_align) / BITS_PER_UNIT 8197 >= tree_low_cst (len, 1)))) 8198 { 8199 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 8200 if (!fn) 8201 return NULL_TREE; 8202 return build_call_expr_loc (loc, fn, 3, dest, src, len); 8203 } 8204 8205 /* If *src and *dest can't overlap, optimize into memcpy as well. */ 8206 srcvar = build_fold_indirect_ref_loc (loc, src); 8207 destvar = build_fold_indirect_ref_loc (loc, dest); 8208 if (srcvar 8209 && !TREE_THIS_VOLATILE (srcvar) 8210 && destvar 8211 && !TREE_THIS_VOLATILE (destvar)) 8212 { 8213 tree src_base, dest_base, fn; 8214 HOST_WIDE_INT src_offset = 0, dest_offset = 0; 8215 HOST_WIDE_INT size = -1; 8216 HOST_WIDE_INT maxsize = -1; 8217 8218 src_base = srcvar; 8219 if (handled_component_p (src_base)) 8220 src_base = get_ref_base_and_extent (src_base, &src_offset, 8221 &size, &maxsize); 8222 dest_base = destvar; 8223 if (handled_component_p (dest_base)) 8224 dest_base = get_ref_base_and_extent (dest_base, &dest_offset, 8225 &size, &maxsize); 8226 if (host_integerp (len, 1)) 8227 { 8228 maxsize = tree_low_cst (len, 1); 8229 if (maxsize 8230 > INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT) 8231 maxsize = -1; 8232 else 8233 maxsize *= BITS_PER_UNIT; 8234 } 8235 else 8236 maxsize = -1; 8237 if (SSA_VAR_P (src_base) 8238 && SSA_VAR_P (dest_base)) 8239 { 8240 if (operand_equal_p (src_base, dest_base, 0) 8241 && ranges_overlap_p (src_offset, maxsize, 8242 dest_offset, maxsize)) 8243 return NULL_TREE; 8244 } 8245 else if (TREE_CODE (src_base) == INDIRECT_REF 8246 && TREE_CODE (dest_base) == INDIRECT_REF) 8247 { 8248 if (! operand_equal_p (TREE_OPERAND (src_base, 0), 8249 TREE_OPERAND (dest_base, 0), 0) 8250 || ranges_overlap_p (src_offset, maxsize, 8251 dest_offset, maxsize)) 8252 return NULL_TREE; 8253 } 8254 else 8255 return NULL_TREE; 8256 8257 fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 8258 if (!fn) 8259 return NULL_TREE; 8260 return build_call_expr_loc (loc, fn, 3, dest, src, len); 8261 } 8262 return NULL_TREE; 8263 } 8264 8265 if (!host_integerp (len, 0)) 8266 return NULL_TREE; 8267 /* FIXME: 8268 This logic lose for arguments like (type *)malloc (sizeof (type)), 8269 since we strip the casts of up to VOID return value from malloc. 8270 Perhaps we ought to inherit type from non-VOID argument here? */ 8271 STRIP_NOPS (src); 8272 STRIP_NOPS (dest); 8273 /* As we fold (void *)(p + CST) to (void *)p + CST undo this here. */ 8274 if (TREE_CODE (src) == POINTER_PLUS_EXPR) 8275 { 8276 tree tem = TREE_OPERAND (src, 0); 8277 STRIP_NOPS (tem); 8278 if (tem != TREE_OPERAND (src, 0)) 8279 src = build1 (NOP_EXPR, TREE_TYPE (tem), src); 8280 } 8281 if (TREE_CODE (dest) == POINTER_PLUS_EXPR) 8282 { 8283 tree tem = TREE_OPERAND (dest, 0); 8284 STRIP_NOPS (tem); 8285 if (tem != TREE_OPERAND (dest, 0)) 8286 dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest); 8287 } 8288 srctype = TREE_TYPE (TREE_TYPE (src)); 8289 if (srctype 8290 && TREE_CODE (srctype) == ARRAY_TYPE 8291 && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)) 8292 { 8293 srctype = TREE_TYPE (srctype); 8294 STRIP_NOPS (src); 8295 src = build1 (NOP_EXPR, build_pointer_type (srctype), src); 8296 } 8297 desttype = TREE_TYPE (TREE_TYPE (dest)); 8298 if (desttype 8299 && TREE_CODE (desttype) == ARRAY_TYPE 8300 && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len)) 8301 { 8302 desttype = TREE_TYPE (desttype); 8303 STRIP_NOPS (dest); 8304 dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest); 8305 } 8306 if (!srctype || !desttype 8307 || !TYPE_SIZE_UNIT (srctype) 8308 || !TYPE_SIZE_UNIT (desttype) 8309 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST 8310 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST 8311 || TYPE_VOLATILE (srctype) 8312 || TYPE_VOLATILE (desttype)) 8313 return NULL_TREE; 8314 8315 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 8316 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 8317 if (dest_align < (int) TYPE_ALIGN (desttype) 8318 || src_align < (int) TYPE_ALIGN (srctype)) 8319 return NULL_TREE; 8320 8321 if (!ignore) 8322 dest = builtin_save_expr (dest); 8323 8324 srcvar = NULL_TREE; 8325 if (tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)) 8326 { 8327 srcvar = build_fold_indirect_ref_loc (loc, src); 8328 if (TREE_THIS_VOLATILE (srcvar)) 8329 return NULL_TREE; 8330 else if (!tree_int_cst_equal (tree_expr_size (srcvar), len)) 8331 srcvar = NULL_TREE; 8332 /* With memcpy, it is possible to bypass aliasing rules, so without 8333 this check i.e. execute/20060930-2.c would be misoptimized, 8334 because it use conflicting alias set to hold argument for the 8335 memcpy call. This check is probably unnecessary with 8336 -fno-strict-aliasing. Similarly for destvar. See also 8337 PR29286. */ 8338 else if (!var_decl_component_p (srcvar)) 8339 srcvar = NULL_TREE; 8340 } 8341 8342 destvar = NULL_TREE; 8343 if (tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len)) 8344 { 8345 destvar = build_fold_indirect_ref_loc (loc, dest); 8346 if (TREE_THIS_VOLATILE (destvar)) 8347 return NULL_TREE; 8348 else if (!tree_int_cst_equal (tree_expr_size (destvar), len)) 8349 destvar = NULL_TREE; 8350 else if (!var_decl_component_p (destvar)) 8351 destvar = NULL_TREE; 8352 } 8353 8354 if (srcvar == NULL_TREE && destvar == NULL_TREE) 8355 return NULL_TREE; 8356 8357 if (srcvar == NULL_TREE) 8358 { 8359 tree srcptype; 8360 if (TREE_ADDRESSABLE (TREE_TYPE (destvar))) 8361 return NULL_TREE; 8362 8363 srctype = build_qualified_type (desttype, 0); 8364 if (src_align < (int) TYPE_ALIGN (srctype)) 8365 { 8366 if (AGGREGATE_TYPE_P (srctype) 8367 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (srctype), src_align)) 8368 return NULL_TREE; 8369 8370 srctype = build_variant_type_copy (srctype); 8371 TYPE_ALIGN (srctype) = src_align; 8372 TYPE_USER_ALIGN (srctype) = 1; 8373 TYPE_PACKED (srctype) = 1; 8374 } 8375 srcptype = build_pointer_type_for_mode (srctype, ptr_mode, true); 8376 src = fold_convert_loc (loc, srcptype, src); 8377 srcvar = build_fold_indirect_ref_loc (loc, src); 8378 } 8379 else if (destvar == NULL_TREE) 8380 { 8381 tree destptype; 8382 if (TREE_ADDRESSABLE (TREE_TYPE (srcvar))) 8383 return NULL_TREE; 8384 8385 desttype = build_qualified_type (srctype, 0); 8386 if (dest_align < (int) TYPE_ALIGN (desttype)) 8387 { 8388 if (AGGREGATE_TYPE_P (desttype) 8389 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (desttype), dest_align)) 8390 return NULL_TREE; 8391 8392 desttype = build_variant_type_copy (desttype); 8393 TYPE_ALIGN (desttype) = dest_align; 8394 TYPE_USER_ALIGN (desttype) = 1; 8395 TYPE_PACKED (desttype) = 1; 8396 } 8397 destptype = build_pointer_type_for_mode (desttype, ptr_mode, true); 8398 dest = fold_convert_loc (loc, destptype, dest); 8399 destvar = build_fold_indirect_ref_loc (loc, dest); 8400 } 8401 8402 if (srctype == desttype 8403 || (gimple_in_ssa_p (cfun) 8404 && useless_type_conversion_p (desttype, srctype))) 8405 expr = srcvar; 8406 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar)) 8407 || POINTER_TYPE_P (TREE_TYPE (srcvar))) 8408 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar)) 8409 || POINTER_TYPE_P (TREE_TYPE (destvar)))) 8410 expr = fold_convert_loc (loc, TREE_TYPE (destvar), srcvar); 8411 else 8412 expr = fold_build1_loc (loc, VIEW_CONVERT_EXPR, 8413 TREE_TYPE (destvar), srcvar); 8414 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr); 8415 } 8416 8417 if (ignore) 8418 return expr; 8419 8420 if (endp == 0 || endp == 3) 8421 return omit_one_operand_loc (loc, type, dest, expr); 8422 8423 if (expr == len) 8424 expr = NULL_TREE; 8425 8426 if (endp == 2) 8427 len = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (len), len, 8428 ssize_int (1)); 8429 8430 len = fold_convert_loc (loc, sizetype, len); 8431 dest = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len); 8432 dest = fold_convert_loc (loc, type, dest); 8433 if (expr) 8434 dest = omit_one_operand_loc (loc, type, dest, expr); 8435 return dest; 8436 } 8437 8438 /* Fold function call to builtin strcpy with arguments DEST and SRC. 8439 If LEN is not NULL, it represents the length of the string to be 8440 copied. Return NULL_TREE if no simplification can be made. */ 8441 8442 tree 8443 fold_builtin_strcpy (location_t loc, tree fndecl, tree dest, tree src, tree len) 8444 { 8445 tree fn; 8446 8447 if (!validate_arg (dest, POINTER_TYPE) 8448 || !validate_arg (src, POINTER_TYPE)) 8449 return NULL_TREE; 8450 8451 /* If SRC and DEST are the same (and not volatile), return DEST. */ 8452 if (operand_equal_p (src, dest, 0)) 8453 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest); 8454 8455 if (optimize_function_for_size_p (cfun)) 8456 return NULL_TREE; 8457 8458 fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 8459 if (!fn) 8460 return NULL_TREE; 8461 8462 if (!len) 8463 { 8464 len = c_strlen (src, 1); 8465 if (! len || TREE_SIDE_EFFECTS (len)) 8466 return NULL_TREE; 8467 } 8468 8469 len = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1)); 8470 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), 8471 build_call_expr_loc (loc, fn, 3, dest, src, len)); 8472 } 8473 8474 /* Fold function call to builtin stpcpy with arguments DEST and SRC. 8475 Return NULL_TREE if no simplification can be made. */ 8476 8477 static tree 8478 fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src) 8479 { 8480 tree fn, len, lenp1, call, type; 8481 8482 if (!validate_arg (dest, POINTER_TYPE) 8483 || !validate_arg (src, POINTER_TYPE)) 8484 return NULL_TREE; 8485 8486 len = c_strlen (src, 1); 8487 if (!len 8488 || TREE_CODE (len) != INTEGER_CST) 8489 return NULL_TREE; 8490 8491 if (optimize_function_for_size_p (cfun) 8492 /* If length is zero it's small enough. */ 8493 && !integer_zerop (len)) 8494 return NULL_TREE; 8495 8496 fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 8497 if (!fn) 8498 return NULL_TREE; 8499 8500 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1)); 8501 /* We use dest twice in building our expression. Save it from 8502 multiple expansions. */ 8503 dest = builtin_save_expr (dest); 8504 call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1); 8505 8506 type = TREE_TYPE (TREE_TYPE (fndecl)); 8507 len = fold_convert_loc (loc, sizetype, len); 8508 dest = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len); 8509 dest = fold_convert_loc (loc, type, dest); 8510 dest = omit_one_operand_loc (loc, type, dest, call); 8511 return dest; 8512 } 8513 8514 /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN. 8515 If SLEN is not NULL, it represents the length of the source string. 8516 Return NULL_TREE if no simplification can be made. */ 8517 8518 tree 8519 fold_builtin_strncpy (location_t loc, tree fndecl, tree dest, 8520 tree src, tree len, tree slen) 8521 { 8522 tree fn; 8523 8524 if (!validate_arg (dest, POINTER_TYPE) 8525 || !validate_arg (src, POINTER_TYPE) 8526 || !validate_arg (len, INTEGER_TYPE)) 8527 return NULL_TREE; 8528 8529 /* If the LEN parameter is zero, return DEST. */ 8530 if (integer_zerop (len)) 8531 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src); 8532 8533 /* We can't compare slen with len as constants below if len is not a 8534 constant. */ 8535 if (len == 0 || TREE_CODE (len) != INTEGER_CST) 8536 return NULL_TREE; 8537 8538 if (!slen) 8539 slen = c_strlen (src, 1); 8540 8541 /* Now, we must be passed a constant src ptr parameter. */ 8542 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST) 8543 return NULL_TREE; 8544 8545 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1)); 8546 8547 /* We do not support simplification of this case, though we do 8548 support it when expanding trees into RTL. */ 8549 /* FIXME: generate a call to __builtin_memset. */ 8550 if (tree_int_cst_lt (slen, len)) 8551 return NULL_TREE; 8552 8553 /* OK transform into builtin memcpy. */ 8554 fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 8555 if (!fn) 8556 return NULL_TREE; 8557 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), 8558 build_call_expr_loc (loc, fn, 3, dest, src, len)); 8559 } 8560 8561 /* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the 8562 arguments to the call, and TYPE is its return type. 8563 Return NULL_TREE if no simplification can be made. */ 8564 8565 static tree 8566 fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type) 8567 { 8568 if (!validate_arg (arg1, POINTER_TYPE) 8569 || !validate_arg (arg2, INTEGER_TYPE) 8570 || !validate_arg (len, INTEGER_TYPE)) 8571 return NULL_TREE; 8572 else 8573 { 8574 const char *p1; 8575 8576 if (TREE_CODE (arg2) != INTEGER_CST 8577 || !host_integerp (len, 1)) 8578 return NULL_TREE; 8579 8580 p1 = c_getstr (arg1); 8581 if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0) 8582 { 8583 char c; 8584 const char *r; 8585 tree tem; 8586 8587 if (target_char_cast (arg2, &c)) 8588 return NULL_TREE; 8589 8590 r = (char *) memchr (p1, c, tree_low_cst (len, 1)); 8591 8592 if (r == NULL) 8593 return build_int_cst (TREE_TYPE (arg1), 0); 8594 8595 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1, 8596 size_int (r - p1)); 8597 return fold_convert_loc (loc, type, tem); 8598 } 8599 return NULL_TREE; 8600 } 8601 } 8602 8603 /* Fold function call to builtin memcmp with arguments ARG1 and ARG2. 8604 Return NULL_TREE if no simplification can be made. */ 8605 8606 static tree 8607 fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len) 8608 { 8609 const char *p1, *p2; 8610 8611 if (!validate_arg (arg1, POINTER_TYPE) 8612 || !validate_arg (arg2, POINTER_TYPE) 8613 || !validate_arg (len, INTEGER_TYPE)) 8614 return NULL_TREE; 8615 8616 /* If the LEN parameter is zero, return zero. */ 8617 if (integer_zerop (len)) 8618 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node, 8619 arg1, arg2); 8620 8621 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8622 if (operand_equal_p (arg1, arg2, 0)) 8623 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len); 8624 8625 p1 = c_getstr (arg1); 8626 p2 = c_getstr (arg2); 8627 8628 /* If all arguments are constant, and the value of len is not greater 8629 than the lengths of arg1 and arg2, evaluate at compile-time. */ 8630 if (host_integerp (len, 1) && p1 && p2 8631 && compare_tree_int (len, strlen (p1) + 1) <= 0 8632 && compare_tree_int (len, strlen (p2) + 1) <= 0) 8633 { 8634 const int r = memcmp (p1, p2, tree_low_cst (len, 1)); 8635 8636 if (r > 0) 8637 return integer_one_node; 8638 else if (r < 0) 8639 return integer_minus_one_node; 8640 else 8641 return integer_zero_node; 8642 } 8643 8644 /* If len parameter is one, return an expression corresponding to 8645 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ 8646 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1) 8647 { 8648 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8649 tree cst_uchar_ptr_node 8650 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8651 8652 tree ind1 8653 = fold_convert_loc (loc, integer_type_node, 8654 build1 (INDIRECT_REF, cst_uchar_node, 8655 fold_convert_loc (loc, 8656 cst_uchar_ptr_node, 8657 arg1))); 8658 tree ind2 8659 = fold_convert_loc (loc, integer_type_node, 8660 build1 (INDIRECT_REF, cst_uchar_node, 8661 fold_convert_loc (loc, 8662 cst_uchar_ptr_node, 8663 arg2))); 8664 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2); 8665 } 8666 8667 return NULL_TREE; 8668 } 8669 8670 /* Fold function call to builtin strcmp with arguments ARG1 and ARG2. 8671 Return NULL_TREE if no simplification can be made. */ 8672 8673 static tree 8674 fold_builtin_strcmp (location_t loc, tree arg1, tree arg2) 8675 { 8676 const char *p1, *p2; 8677 8678 if (!validate_arg (arg1, POINTER_TYPE) 8679 || !validate_arg (arg2, POINTER_TYPE)) 8680 return NULL_TREE; 8681 8682 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8683 if (operand_equal_p (arg1, arg2, 0)) 8684 return integer_zero_node; 8685 8686 p1 = c_getstr (arg1); 8687 p2 = c_getstr (arg2); 8688 8689 if (p1 && p2) 8690 { 8691 const int i = strcmp (p1, p2); 8692 if (i < 0) 8693 return integer_minus_one_node; 8694 else if (i > 0) 8695 return integer_one_node; 8696 else 8697 return integer_zero_node; 8698 } 8699 8700 /* If the second arg is "", return *(const unsigned char*)arg1. */ 8701 if (p2 && *p2 == '\0') 8702 { 8703 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8704 tree cst_uchar_ptr_node 8705 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8706 8707 return fold_convert_loc (loc, integer_type_node, 8708 build1 (INDIRECT_REF, cst_uchar_node, 8709 fold_convert_loc (loc, 8710 cst_uchar_ptr_node, 8711 arg1))); 8712 } 8713 8714 /* If the first arg is "", return -*(const unsigned char*)arg2. */ 8715 if (p1 && *p1 == '\0') 8716 { 8717 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8718 tree cst_uchar_ptr_node 8719 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8720 8721 tree temp 8722 = fold_convert_loc (loc, integer_type_node, 8723 build1 (INDIRECT_REF, cst_uchar_node, 8724 fold_convert_loc (loc, 8725 cst_uchar_ptr_node, 8726 arg2))); 8727 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp); 8728 } 8729 8730 return NULL_TREE; 8731 } 8732 8733 /* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN. 8734 Return NULL_TREE if no simplification can be made. */ 8735 8736 static tree 8737 fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len) 8738 { 8739 const char *p1, *p2; 8740 8741 if (!validate_arg (arg1, POINTER_TYPE) 8742 || !validate_arg (arg2, POINTER_TYPE) 8743 || !validate_arg (len, INTEGER_TYPE)) 8744 return NULL_TREE; 8745 8746 /* If the LEN parameter is zero, return zero. */ 8747 if (integer_zerop (len)) 8748 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node, 8749 arg1, arg2); 8750 8751 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8752 if (operand_equal_p (arg1, arg2, 0)) 8753 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len); 8754 8755 p1 = c_getstr (arg1); 8756 p2 = c_getstr (arg2); 8757 8758 if (host_integerp (len, 1) && p1 && p2) 8759 { 8760 const int i = strncmp (p1, p2, tree_low_cst (len, 1)); 8761 if (i > 0) 8762 return integer_one_node; 8763 else if (i < 0) 8764 return integer_minus_one_node; 8765 else 8766 return integer_zero_node; 8767 } 8768 8769 /* If the second arg is "", and the length is greater than zero, 8770 return *(const unsigned char*)arg1. */ 8771 if (p2 && *p2 == '\0' 8772 && TREE_CODE (len) == INTEGER_CST 8773 && tree_int_cst_sgn (len) == 1) 8774 { 8775 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8776 tree cst_uchar_ptr_node 8777 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8778 8779 return fold_convert_loc (loc, integer_type_node, 8780 build1 (INDIRECT_REF, cst_uchar_node, 8781 fold_convert_loc (loc, 8782 cst_uchar_ptr_node, 8783 arg1))); 8784 } 8785 8786 /* If the first arg is "", and the length is greater than zero, 8787 return -*(const unsigned char*)arg2. */ 8788 if (p1 && *p1 == '\0' 8789 && TREE_CODE (len) == INTEGER_CST 8790 && tree_int_cst_sgn (len) == 1) 8791 { 8792 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8793 tree cst_uchar_ptr_node 8794 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8795 8796 tree temp = fold_convert_loc (loc, integer_type_node, 8797 build1 (INDIRECT_REF, cst_uchar_node, 8798 fold_convert_loc (loc, 8799 cst_uchar_ptr_node, 8800 arg2))); 8801 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp); 8802 } 8803 8804 /* If len parameter is one, return an expression corresponding to 8805 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ 8806 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1) 8807 { 8808 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8809 tree cst_uchar_ptr_node 8810 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8811 8812 tree ind1 = fold_convert_loc (loc, integer_type_node, 8813 build1 (INDIRECT_REF, cst_uchar_node, 8814 fold_convert_loc (loc, 8815 cst_uchar_ptr_node, 8816 arg1))); 8817 tree ind2 = fold_convert_loc (loc, integer_type_node, 8818 build1 (INDIRECT_REF, cst_uchar_node, 8819 fold_convert_loc (loc, 8820 cst_uchar_ptr_node, 8821 arg2))); 8822 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2); 8823 } 8824 8825 return NULL_TREE; 8826 } 8827 8828 /* Fold function call to builtin signbit, signbitf or signbitl with argument 8829 ARG. Return NULL_TREE if no simplification can be made. */ 8830 8831 static tree 8832 fold_builtin_signbit (location_t loc, tree arg, tree type) 8833 { 8834 tree temp; 8835 8836 if (!validate_arg (arg, REAL_TYPE)) 8837 return NULL_TREE; 8838 8839 /* If ARG is a compile-time constant, determine the result. */ 8840 if (TREE_CODE (arg) == REAL_CST 8841 && !TREE_OVERFLOW (arg)) 8842 { 8843 REAL_VALUE_TYPE c; 8844 8845 c = TREE_REAL_CST (arg); 8846 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node; 8847 return fold_convert_loc (loc, type, temp); 8848 } 8849 8850 /* If ARG is non-negative, the result is always zero. */ 8851 if (tree_expr_nonnegative_p (arg)) 8852 return omit_one_operand_loc (loc, type, integer_zero_node, arg); 8853 8854 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */ 8855 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg)))) 8856 return fold_build2_loc (loc, LT_EXPR, type, arg, 8857 build_real (TREE_TYPE (arg), dconst0)); 8858 8859 return NULL_TREE; 8860 } 8861 8862 /* Fold function call to builtin copysign, copysignf or copysignl with 8863 arguments ARG1 and ARG2. Return NULL_TREE if no simplification can 8864 be made. */ 8865 8866 static tree 8867 fold_builtin_copysign (location_t loc, tree fndecl, 8868 tree arg1, tree arg2, tree type) 8869 { 8870 tree tem; 8871 8872 if (!validate_arg (arg1, REAL_TYPE) 8873 || !validate_arg (arg2, REAL_TYPE)) 8874 return NULL_TREE; 8875 8876 /* copysign(X,X) is X. */ 8877 if (operand_equal_p (arg1, arg2, 0)) 8878 return fold_convert_loc (loc, type, arg1); 8879 8880 /* If ARG1 and ARG2 are compile-time constants, determine the result. */ 8881 if (TREE_CODE (arg1) == REAL_CST 8882 && TREE_CODE (arg2) == REAL_CST 8883 && !TREE_OVERFLOW (arg1) 8884 && !TREE_OVERFLOW (arg2)) 8885 { 8886 REAL_VALUE_TYPE c1, c2; 8887 8888 c1 = TREE_REAL_CST (arg1); 8889 c2 = TREE_REAL_CST (arg2); 8890 /* c1.sign := c2.sign. */ 8891 real_copysign (&c1, &c2); 8892 return build_real (type, c1); 8893 } 8894 8895 /* copysign(X, Y) is fabs(X) when Y is always non-negative. 8896 Remember to evaluate Y for side-effects. */ 8897 if (tree_expr_nonnegative_p (arg2)) 8898 return omit_one_operand_loc (loc, type, 8899 fold_build1_loc (loc, ABS_EXPR, type, arg1), 8900 arg2); 8901 8902 /* Strip sign changing operations for the first argument. */ 8903 tem = fold_strip_sign_ops (arg1); 8904 if (tem) 8905 return build_call_expr_loc (loc, fndecl, 2, tem, arg2); 8906 8907 return NULL_TREE; 8908 } 8909 8910 /* Fold a call to builtin isascii with argument ARG. */ 8911 8912 static tree 8913 fold_builtin_isascii (location_t loc, tree arg) 8914 { 8915 if (!validate_arg (arg, INTEGER_TYPE)) 8916 return NULL_TREE; 8917 else 8918 { 8919 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */ 8920 arg = fold_build2 (BIT_AND_EXPR, integer_type_node, arg, 8921 build_int_cst (NULL_TREE, 8922 ~ (unsigned HOST_WIDE_INT) 0x7f)); 8923 return fold_build2_loc (loc, EQ_EXPR, integer_type_node, 8924 arg, integer_zero_node); 8925 } 8926 } 8927 8928 /* Fold a call to builtin toascii with argument ARG. */ 8929 8930 static tree 8931 fold_builtin_toascii (location_t loc, tree arg) 8932 { 8933 if (!validate_arg (arg, INTEGER_TYPE)) 8934 return NULL_TREE; 8935 8936 /* Transform toascii(c) -> (c & 0x7f). */ 8937 return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg, 8938 build_int_cst (NULL_TREE, 0x7f)); 8939 } 8940 8941 /* Fold a call to builtin isdigit with argument ARG. */ 8942 8943 static tree 8944 fold_builtin_isdigit (location_t loc, tree arg) 8945 { 8946 if (!validate_arg (arg, INTEGER_TYPE)) 8947 return NULL_TREE; 8948 else 8949 { 8950 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */ 8951 /* According to the C standard, isdigit is unaffected by locale. 8952 However, it definitely is affected by the target character set. */ 8953 unsigned HOST_WIDE_INT target_digit0 8954 = lang_hooks.to_target_charset ('0'); 8955 8956 if (target_digit0 == 0) 8957 return NULL_TREE; 8958 8959 arg = fold_convert_loc (loc, unsigned_type_node, arg); 8960 arg = fold_build2 (MINUS_EXPR, unsigned_type_node, arg, 8961 build_int_cst (unsigned_type_node, target_digit0)); 8962 return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg, 8963 build_int_cst (unsigned_type_node, 9)); 8964 } 8965 } 8966 8967 /* Fold a call to fabs, fabsf or fabsl with argument ARG. */ 8968 8969 static tree 8970 fold_builtin_fabs (location_t loc, tree arg, tree type) 8971 { 8972 if (!validate_arg (arg, REAL_TYPE)) 8973 return NULL_TREE; 8974 8975 arg = fold_convert_loc (loc, type, arg); 8976 if (TREE_CODE (arg) == REAL_CST) 8977 return fold_abs_const (arg, type); 8978 return fold_build1_loc (loc, ABS_EXPR, type, arg); 8979 } 8980 8981 /* Fold a call to abs, labs, llabs or imaxabs with argument ARG. */ 8982 8983 static tree 8984 fold_builtin_abs (location_t loc, tree arg, tree type) 8985 { 8986 if (!validate_arg (arg, INTEGER_TYPE)) 8987 return NULL_TREE; 8988 8989 arg = fold_convert_loc (loc, type, arg); 8990 if (TREE_CODE (arg) == INTEGER_CST) 8991 return fold_abs_const (arg, type); 8992 return fold_build1_loc (loc, ABS_EXPR, type, arg); 8993 } 8994 8995 /* Fold a call to builtin fmin or fmax. */ 8996 8997 static tree 8998 fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1, 8999 tree type, bool max) 9000 { 9001 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE)) 9002 { 9003 /* Calculate the result when the argument is a constant. */ 9004 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min)); 9005 9006 if (res) 9007 return res; 9008 9009 /* If either argument is NaN, return the other one. Avoid the 9010 transformation if we get (and honor) a signalling NaN. Using 9011 omit_one_operand() ensures we create a non-lvalue. */ 9012 if (TREE_CODE (arg0) == REAL_CST 9013 && real_isnan (&TREE_REAL_CST (arg0)) 9014 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))) 9015 || ! TREE_REAL_CST (arg0).signalling)) 9016 return omit_one_operand_loc (loc, type, arg1, arg0); 9017 if (TREE_CODE (arg1) == REAL_CST 9018 && real_isnan (&TREE_REAL_CST (arg1)) 9019 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1))) 9020 || ! TREE_REAL_CST (arg1).signalling)) 9021 return omit_one_operand_loc (loc, type, arg0, arg1); 9022 9023 /* Transform fmin/fmax(x,x) -> x. */ 9024 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME)) 9025 return omit_one_operand_loc (loc, type, arg0, arg1); 9026 9027 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these 9028 functions to return the numeric arg if the other one is NaN. 9029 These tree codes don't honor that, so only transform if 9030 -ffinite-math-only is set. C99 doesn't require -0.0 to be 9031 handled, so we don't have to worry about it either. */ 9032 if (flag_finite_math_only) 9033 return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type, 9034 fold_convert_loc (loc, type, arg0), 9035 fold_convert_loc (loc, type, arg1)); 9036 } 9037 return NULL_TREE; 9038 } 9039 9040 /* Fold a call to builtin carg(a+bi) -> atan2(b,a). */ 9041 9042 static tree 9043 fold_builtin_carg (location_t loc, tree arg, tree type) 9044 { 9045 if (validate_arg (arg, COMPLEX_TYPE) 9046 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE) 9047 { 9048 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2); 9049 9050 if (atan2_fn) 9051 { 9052 tree new_arg = builtin_save_expr (arg); 9053 tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg); 9054 tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg); 9055 return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg); 9056 } 9057 } 9058 9059 return NULL_TREE; 9060 } 9061 9062 /* Fold a call to builtin logb/ilogb. */ 9063 9064 static tree 9065 fold_builtin_logb (location_t loc, tree arg, tree rettype) 9066 { 9067 if (! validate_arg (arg, REAL_TYPE)) 9068 return NULL_TREE; 9069 9070 STRIP_NOPS (arg); 9071 9072 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg)) 9073 { 9074 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg); 9075 9076 switch (value->cl) 9077 { 9078 case rvc_nan: 9079 case rvc_inf: 9080 /* If arg is Inf or NaN and we're logb, return it. */ 9081 if (TREE_CODE (rettype) == REAL_TYPE) 9082 return fold_convert_loc (loc, rettype, arg); 9083 /* Fall through... */ 9084 case rvc_zero: 9085 /* Zero may set errno and/or raise an exception for logb, also 9086 for ilogb we don't know FP_ILOGB0. */ 9087 return NULL_TREE; 9088 case rvc_normal: 9089 /* For normal numbers, proceed iff radix == 2. In GCC, 9090 normalized significands are in the range [0.5, 1.0). We 9091 want the exponent as if they were [1.0, 2.0) so get the 9092 exponent and subtract 1. */ 9093 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2) 9094 return fold_convert_loc (loc, rettype, 9095 build_int_cst (NULL_TREE, 9096 REAL_EXP (value)-1)); 9097 break; 9098 } 9099 } 9100 9101 return NULL_TREE; 9102 } 9103 9104 /* Fold a call to builtin significand, if radix == 2. */ 9105 9106 static tree 9107 fold_builtin_significand (location_t loc, tree arg, tree rettype) 9108 { 9109 if (! validate_arg (arg, REAL_TYPE)) 9110 return NULL_TREE; 9111 9112 STRIP_NOPS (arg); 9113 9114 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg)) 9115 { 9116 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg); 9117 9118 switch (value->cl) 9119 { 9120 case rvc_zero: 9121 case rvc_nan: 9122 case rvc_inf: 9123 /* If arg is +-0, +-Inf or +-NaN, then return it. */ 9124 return fold_convert_loc (loc, rettype, arg); 9125 case rvc_normal: 9126 /* For normal numbers, proceed iff radix == 2. */ 9127 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2) 9128 { 9129 REAL_VALUE_TYPE result = *value; 9130 /* In GCC, normalized significands are in the range [0.5, 9131 1.0). We want them to be [1.0, 2.0) so set the 9132 exponent to 1. */ 9133 SET_REAL_EXP (&result, 1); 9134 return build_real (rettype, result); 9135 } 9136 break; 9137 } 9138 } 9139 9140 return NULL_TREE; 9141 } 9142 9143 /* Fold a call to builtin frexp, we can assume the base is 2. */ 9144 9145 static tree 9146 fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype) 9147 { 9148 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE)) 9149 return NULL_TREE; 9150 9151 STRIP_NOPS (arg0); 9152 9153 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0))) 9154 return NULL_TREE; 9155 9156 arg1 = build_fold_indirect_ref_loc (loc, arg1); 9157 9158 /* Proceed if a valid pointer type was passed in. */ 9159 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node) 9160 { 9161 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0); 9162 tree frac, exp; 9163 9164 switch (value->cl) 9165 { 9166 case rvc_zero: 9167 /* For +-0, return (*exp = 0, +-0). */ 9168 exp = integer_zero_node; 9169 frac = arg0; 9170 break; 9171 case rvc_nan: 9172 case rvc_inf: 9173 /* For +-NaN or +-Inf, *exp is unspecified, return arg0. */ 9174 return omit_one_operand_loc (loc, rettype, arg0, arg1); 9175 case rvc_normal: 9176 { 9177 /* Since the frexp function always expects base 2, and in 9178 GCC normalized significands are already in the range 9179 [0.5, 1.0), we have exactly what frexp wants. */ 9180 REAL_VALUE_TYPE frac_rvt = *value; 9181 SET_REAL_EXP (&frac_rvt, 0); 9182 frac = build_real (rettype, frac_rvt); 9183 exp = build_int_cst (NULL_TREE, REAL_EXP (value)); 9184 } 9185 break; 9186 default: 9187 gcc_unreachable (); 9188 } 9189 9190 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */ 9191 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp); 9192 TREE_SIDE_EFFECTS (arg1) = 1; 9193 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac); 9194 } 9195 9196 return NULL_TREE; 9197 } 9198 9199 /* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true 9200 then we can assume the base is two. If it's false, then we have to 9201 check the mode of the TYPE parameter in certain cases. */ 9202 9203 static tree 9204 fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1, 9205 tree type, bool ldexp) 9206 { 9207 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE)) 9208 { 9209 STRIP_NOPS (arg0); 9210 STRIP_NOPS (arg1); 9211 9212 /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */ 9213 if (real_zerop (arg0) || integer_zerop (arg1) 9214 || (TREE_CODE (arg0) == REAL_CST 9215 && !real_isfinite (&TREE_REAL_CST (arg0)))) 9216 return omit_one_operand_loc (loc, type, arg0, arg1); 9217 9218 /* If both arguments are constant, then try to evaluate it. */ 9219 if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2) 9220 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0) 9221 && host_integerp (arg1, 0)) 9222 { 9223 /* Bound the maximum adjustment to twice the range of the 9224 mode's valid exponents. Use abs to ensure the range is 9225 positive as a sanity check. */ 9226 const long max_exp_adj = 2 * 9227 labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax 9228 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin); 9229 9230 /* Get the user-requested adjustment. */ 9231 const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0); 9232 9233 /* The requested adjustment must be inside this range. This 9234 is a preliminary cap to avoid things like overflow, we 9235 may still fail to compute the result for other reasons. */ 9236 if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj) 9237 { 9238 REAL_VALUE_TYPE initial_result; 9239 9240 real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj); 9241 9242 /* Ensure we didn't overflow. */ 9243 if (! real_isinf (&initial_result)) 9244 { 9245 const REAL_VALUE_TYPE trunc_result 9246 = real_value_truncate (TYPE_MODE (type), initial_result); 9247 9248 /* Only proceed if the target mode can hold the 9249 resulting value. */ 9250 if (REAL_VALUES_EQUAL (initial_result, trunc_result)) 9251 return build_real (type, trunc_result); 9252 } 9253 } 9254 } 9255 } 9256 9257 return NULL_TREE; 9258 } 9259 9260 /* Fold a call to builtin modf. */ 9261 9262 static tree 9263 fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype) 9264 { 9265 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE)) 9266 return NULL_TREE; 9267 9268 STRIP_NOPS (arg0); 9269 9270 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0))) 9271 return NULL_TREE; 9272 9273 arg1 = build_fold_indirect_ref_loc (loc, arg1); 9274 9275 /* Proceed if a valid pointer type was passed in. */ 9276 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype)) 9277 { 9278 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0); 9279 REAL_VALUE_TYPE trunc, frac; 9280 9281 switch (value->cl) 9282 { 9283 case rvc_nan: 9284 case rvc_zero: 9285 /* For +-NaN or +-0, return (*arg1 = arg0, arg0). */ 9286 trunc = frac = *value; 9287 break; 9288 case rvc_inf: 9289 /* For +-Inf, return (*arg1 = arg0, +-0). */ 9290 frac = dconst0; 9291 frac.sign = value->sign; 9292 trunc = *value; 9293 break; 9294 case rvc_normal: 9295 /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */ 9296 real_trunc (&trunc, VOIDmode, value); 9297 real_arithmetic (&frac, MINUS_EXPR, value, &trunc); 9298 /* If the original number was negative and already 9299 integral, then the fractional part is -0.0. */ 9300 if (value->sign && frac.cl == rvc_zero) 9301 frac.sign = value->sign; 9302 break; 9303 } 9304 9305 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */ 9306 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, 9307 build_real (rettype, trunc)); 9308 TREE_SIDE_EFFECTS (arg1) = 1; 9309 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, 9310 build_real (rettype, frac)); 9311 } 9312 9313 return NULL_TREE; 9314 } 9315 9316 /* Given a location LOC, an interclass builtin function decl FNDECL 9317 and its single argument ARG, return an folded expression computing 9318 the same, or NULL_TREE if we either couldn't or didn't want to fold 9319 (the latter happen if there's an RTL instruction available). */ 9320 9321 static tree 9322 fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg) 9323 { 9324 enum machine_mode mode; 9325 9326 if (!validate_arg (arg, REAL_TYPE)) 9327 return NULL_TREE; 9328 9329 if (interclass_mathfn_icode (arg, fndecl) != CODE_FOR_nothing) 9330 return NULL_TREE; 9331 9332 mode = TYPE_MODE (TREE_TYPE (arg)); 9333 9334 /* If there is no optab, try generic code. */ 9335 switch (DECL_FUNCTION_CODE (fndecl)) 9336 { 9337 tree result; 9338 9339 CASE_FLT_FN (BUILT_IN_ISINF): 9340 { 9341 /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */ 9342 tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER]; 9343 tree const type = TREE_TYPE (arg); 9344 REAL_VALUE_TYPE r; 9345 char buf[128]; 9346 9347 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); 9348 real_from_string (&r, buf); 9349 result = build_call_expr (isgr_fn, 2, 9350 fold_build1_loc (loc, ABS_EXPR, type, arg), 9351 build_real (type, r)); 9352 return result; 9353 } 9354 CASE_FLT_FN (BUILT_IN_FINITE): 9355 case BUILT_IN_ISFINITE: 9356 { 9357 /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */ 9358 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL]; 9359 tree const type = TREE_TYPE (arg); 9360 REAL_VALUE_TYPE r; 9361 char buf[128]; 9362 9363 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); 9364 real_from_string (&r, buf); 9365 result = build_call_expr (isle_fn, 2, 9366 fold_build1_loc (loc, ABS_EXPR, type, arg), 9367 build_real (type, r)); 9368 /*result = fold_build2_loc (loc, UNGT_EXPR, 9369 TREE_TYPE (TREE_TYPE (fndecl)), 9370 fold_build1_loc (loc, ABS_EXPR, type, arg), 9371 build_real (type, r)); 9372 result = fold_build1_loc (loc, TRUTH_NOT_EXPR, 9373 TREE_TYPE (TREE_TYPE (fndecl)), 9374 result);*/ 9375 return result; 9376 } 9377 case BUILT_IN_ISNORMAL: 9378 { 9379 /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) & 9380 islessequal(fabs(x),DBL_MAX). */ 9381 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL]; 9382 tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL]; 9383 tree const type = TREE_TYPE (arg); 9384 REAL_VALUE_TYPE rmax, rmin; 9385 char buf[128]; 9386 9387 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); 9388 real_from_string (&rmax, buf); 9389 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1); 9390 real_from_string (&rmin, buf); 9391 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg)); 9392 result = build_call_expr (isle_fn, 2, arg, 9393 build_real (type, rmax)); 9394 result = fold_build2 (BIT_AND_EXPR, integer_type_node, result, 9395 build_call_expr (isge_fn, 2, arg, 9396 build_real (type, rmin))); 9397 return result; 9398 } 9399 default: 9400 break; 9401 } 9402 9403 return NULL_TREE; 9404 } 9405 9406 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite. 9407 ARG is the argument for the call. */ 9408 9409 static tree 9410 fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index) 9411 { 9412 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 9413 REAL_VALUE_TYPE r; 9414 9415 if (!validate_arg (arg, REAL_TYPE)) 9416 return NULL_TREE; 9417 9418 switch (builtin_index) 9419 { 9420 case BUILT_IN_ISINF: 9421 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg)))) 9422 return omit_one_operand_loc (loc, type, integer_zero_node, arg); 9423 9424 if (TREE_CODE (arg) == REAL_CST) 9425 { 9426 r = TREE_REAL_CST (arg); 9427 if (real_isinf (&r)) 9428 return real_compare (GT_EXPR, &r, &dconst0) 9429 ? integer_one_node : integer_minus_one_node; 9430 else 9431 return integer_zero_node; 9432 } 9433 9434 return NULL_TREE; 9435 9436 case BUILT_IN_ISINF_SIGN: 9437 { 9438 /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */ 9439 /* In a boolean context, GCC will fold the inner COND_EXPR to 9440 1. So e.g. "if (isinf_sign(x))" would be folded to just 9441 "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */ 9442 tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0); 9443 tree isinf_fn = built_in_decls[BUILT_IN_ISINF]; 9444 tree tmp = NULL_TREE; 9445 9446 arg = builtin_save_expr (arg); 9447 9448 if (signbit_fn && isinf_fn) 9449 { 9450 tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg); 9451 tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg); 9452 9453 signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node, 9454 signbit_call, integer_zero_node); 9455 isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node, 9456 isinf_call, integer_zero_node); 9457 9458 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call, 9459 integer_minus_one_node, integer_one_node); 9460 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, 9461 isinf_call, tmp, 9462 integer_zero_node); 9463 } 9464 9465 return tmp; 9466 } 9467 9468 case BUILT_IN_ISFINITE: 9469 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))) 9470 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg)))) 9471 return omit_one_operand_loc (loc, type, integer_one_node, arg); 9472 9473 if (TREE_CODE (arg) == REAL_CST) 9474 { 9475 r = TREE_REAL_CST (arg); 9476 return real_isfinite (&r) ? integer_one_node : integer_zero_node; 9477 } 9478 9479 return NULL_TREE; 9480 9481 case BUILT_IN_ISNAN: 9482 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))) 9483 return omit_one_operand_loc (loc, type, integer_zero_node, arg); 9484 9485 if (TREE_CODE (arg) == REAL_CST) 9486 { 9487 r = TREE_REAL_CST (arg); 9488 return real_isnan (&r) ? integer_one_node : integer_zero_node; 9489 } 9490 9491 arg = builtin_save_expr (arg); 9492 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg); 9493 9494 default: 9495 gcc_unreachable (); 9496 } 9497 } 9498 9499 /* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...). 9500 This builtin will generate code to return the appropriate floating 9501 point classification depending on the value of the floating point 9502 number passed in. The possible return values must be supplied as 9503 int arguments to the call in the following order: FP_NAN, FP_INFINITE, 9504 FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly 9505 one floating point argument which is "type generic". */ 9506 9507 static tree 9508 fold_builtin_fpclassify (location_t loc, tree exp) 9509 { 9510 tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero, 9511 arg, type, res, tmp; 9512 enum machine_mode mode; 9513 REAL_VALUE_TYPE r; 9514 char buf[128]; 9515 9516 /* Verify the required arguments in the original call. */ 9517 if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE, 9518 INTEGER_TYPE, INTEGER_TYPE, 9519 INTEGER_TYPE, REAL_TYPE, VOID_TYPE)) 9520 return NULL_TREE; 9521 9522 fp_nan = CALL_EXPR_ARG (exp, 0); 9523 fp_infinite = CALL_EXPR_ARG (exp, 1); 9524 fp_normal = CALL_EXPR_ARG (exp, 2); 9525 fp_subnormal = CALL_EXPR_ARG (exp, 3); 9526 fp_zero = CALL_EXPR_ARG (exp, 4); 9527 arg = CALL_EXPR_ARG (exp, 5); 9528 type = TREE_TYPE (arg); 9529 mode = TYPE_MODE (type); 9530 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg)); 9531 9532 /* fpclassify(x) -> 9533 isnan(x) ? FP_NAN : 9534 (fabs(x) == Inf ? FP_INFINITE : 9535 (fabs(x) >= DBL_MIN ? FP_NORMAL : 9536 (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */ 9537 9538 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg, 9539 build_real (type, dconst0)); 9540 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, 9541 tmp, fp_zero, fp_subnormal); 9542 9543 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1); 9544 real_from_string (&r, buf); 9545 tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node, 9546 arg, build_real (type, r)); 9547 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res); 9548 9549 if (HONOR_INFINITIES (mode)) 9550 { 9551 real_inf (&r); 9552 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg, 9553 build_real (type, r)); 9554 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, 9555 fp_infinite, res); 9556 } 9557 9558 if (HONOR_NANS (mode)) 9559 { 9560 tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg); 9561 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan); 9562 } 9563 9564 return res; 9565 } 9566 9567 /* Fold a call to an unordered comparison function such as 9568 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function 9569 being called and ARG0 and ARG1 are the arguments for the call. 9570 UNORDERED_CODE and ORDERED_CODE are comparison codes that give 9571 the opposite of the desired result. UNORDERED_CODE is used 9572 for modes that can hold NaNs and ORDERED_CODE is used for 9573 the rest. */ 9574 9575 static tree 9576 fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1, 9577 enum tree_code unordered_code, 9578 enum tree_code ordered_code) 9579 { 9580 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 9581 enum tree_code code; 9582 tree type0, type1; 9583 enum tree_code code0, code1; 9584 tree cmp_type = NULL_TREE; 9585 9586 type0 = TREE_TYPE (arg0); 9587 type1 = TREE_TYPE (arg1); 9588 9589 code0 = TREE_CODE (type0); 9590 code1 = TREE_CODE (type1); 9591 9592 if (code0 == REAL_TYPE && code1 == REAL_TYPE) 9593 /* Choose the wider of two real types. */ 9594 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1) 9595 ? type0 : type1; 9596 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE) 9597 cmp_type = type0; 9598 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE) 9599 cmp_type = type1; 9600 9601 arg0 = fold_convert_loc (loc, cmp_type, arg0); 9602 arg1 = fold_convert_loc (loc, cmp_type, arg1); 9603 9604 if (unordered_code == UNORDERED_EXPR) 9605 { 9606 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))) 9607 return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1); 9608 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1); 9609 } 9610 9611 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code 9612 : ordered_code; 9613 return fold_build1_loc (loc, TRUTH_NOT_EXPR, type, 9614 fold_build2_loc (loc, code, type, arg0, arg1)); 9615 } 9616 9617 /* Fold a call to built-in function FNDECL with 0 arguments. 9618 IGNORE is true if the result of the function call is ignored. This 9619 function returns NULL_TREE if no simplification was possible. */ 9620 9621 static tree 9622 fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED) 9623 { 9624 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 9625 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 9626 switch (fcode) 9627 { 9628 CASE_FLT_FN (BUILT_IN_INF): 9629 case BUILT_IN_INFD32: 9630 case BUILT_IN_INFD64: 9631 case BUILT_IN_INFD128: 9632 return fold_builtin_inf (loc, type, true); 9633 9634 CASE_FLT_FN (BUILT_IN_HUGE_VAL): 9635 return fold_builtin_inf (loc, type, false); 9636 9637 case BUILT_IN_CLASSIFY_TYPE: 9638 return fold_builtin_classify_type (NULL_TREE); 9639 9640 default: 9641 break; 9642 } 9643 return NULL_TREE; 9644 } 9645 9646 /* Fold a call to built-in function FNDECL with 1 argument, ARG0. 9647 IGNORE is true if the result of the function call is ignored. This 9648 function returns NULL_TREE if no simplification was possible. */ 9649 9650 static tree 9651 fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore) 9652 { 9653 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 9654 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 9655 switch (fcode) 9656 { 9657 9658 case BUILT_IN_CONSTANT_P: 9659 { 9660 tree val = fold_builtin_constant_p (arg0); 9661 9662 /* Gimplification will pull the CALL_EXPR for the builtin out of 9663 an if condition. When not optimizing, we'll not CSE it back. 9664 To avoid link error types of regressions, return false now. */ 9665 if (!val && !optimize) 9666 val = integer_zero_node; 9667 9668 return val; 9669 } 9670 9671 case BUILT_IN_CLASSIFY_TYPE: 9672 return fold_builtin_classify_type (arg0); 9673 9674 case BUILT_IN_STRLEN: 9675 return fold_builtin_strlen (loc, type, arg0); 9676 9677 CASE_FLT_FN (BUILT_IN_FABS): 9678 return fold_builtin_fabs (loc, arg0, type); 9679 9680 case BUILT_IN_ABS: 9681 case BUILT_IN_LABS: 9682 case BUILT_IN_LLABS: 9683 case BUILT_IN_IMAXABS: 9684 return fold_builtin_abs (loc, arg0, type); 9685 9686 CASE_FLT_FN (BUILT_IN_CONJ): 9687 if (validate_arg (arg0, COMPLEX_TYPE) 9688 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9689 return fold_build1_loc (loc, CONJ_EXPR, type, arg0); 9690 break; 9691 9692 CASE_FLT_FN (BUILT_IN_CREAL): 9693 if (validate_arg (arg0, COMPLEX_TYPE) 9694 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9695 return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));; 9696 break; 9697 9698 CASE_FLT_FN (BUILT_IN_CIMAG): 9699 if (validate_arg (arg0, COMPLEX_TYPE) 9700 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9701 return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0)); 9702 break; 9703 9704 CASE_FLT_FN (BUILT_IN_CCOS): 9705 return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false); 9706 9707 CASE_FLT_FN (BUILT_IN_CCOSH): 9708 return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true); 9709 9710 CASE_FLT_FN (BUILT_IN_CSIN): 9711 if (validate_arg (arg0, COMPLEX_TYPE) 9712 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9713 return do_mpc_arg1 (arg0, type, mpc_sin); 9714 break; 9715 9716 CASE_FLT_FN (BUILT_IN_CSINH): 9717 if (validate_arg (arg0, COMPLEX_TYPE) 9718 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9719 return do_mpc_arg1 (arg0, type, mpc_sinh); 9720 break; 9721 9722 CASE_FLT_FN (BUILT_IN_CTAN): 9723 if (validate_arg (arg0, COMPLEX_TYPE) 9724 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9725 return do_mpc_arg1 (arg0, type, mpc_tan); 9726 break; 9727 9728 CASE_FLT_FN (BUILT_IN_CTANH): 9729 if (validate_arg (arg0, COMPLEX_TYPE) 9730 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9731 return do_mpc_arg1 (arg0, type, mpc_tanh); 9732 break; 9733 9734 CASE_FLT_FN (BUILT_IN_CLOG): 9735 if (validate_arg (arg0, COMPLEX_TYPE) 9736 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9737 return do_mpc_arg1 (arg0, type, mpc_log); 9738 break; 9739 9740 CASE_FLT_FN (BUILT_IN_CSQRT): 9741 if (validate_arg (arg0, COMPLEX_TYPE) 9742 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9743 return do_mpc_arg1 (arg0, type, mpc_sqrt); 9744 break; 9745 9746 CASE_FLT_FN (BUILT_IN_CASIN): 9747 if (validate_arg (arg0, COMPLEX_TYPE) 9748 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9749 return do_mpc_arg1 (arg0, type, mpc_asin); 9750 break; 9751 9752 CASE_FLT_FN (BUILT_IN_CACOS): 9753 if (validate_arg (arg0, COMPLEX_TYPE) 9754 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9755 return do_mpc_arg1 (arg0, type, mpc_acos); 9756 break; 9757 9758 CASE_FLT_FN (BUILT_IN_CATAN): 9759 if (validate_arg (arg0, COMPLEX_TYPE) 9760 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9761 return do_mpc_arg1 (arg0, type, mpc_atan); 9762 break; 9763 9764 CASE_FLT_FN (BUILT_IN_CASINH): 9765 if (validate_arg (arg0, COMPLEX_TYPE) 9766 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9767 return do_mpc_arg1 (arg0, type, mpc_asinh); 9768 break; 9769 9770 CASE_FLT_FN (BUILT_IN_CACOSH): 9771 if (validate_arg (arg0, COMPLEX_TYPE) 9772 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9773 return do_mpc_arg1 (arg0, type, mpc_acosh); 9774 break; 9775 9776 CASE_FLT_FN (BUILT_IN_CATANH): 9777 if (validate_arg (arg0, COMPLEX_TYPE) 9778 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 9779 return do_mpc_arg1 (arg0, type, mpc_atanh); 9780 break; 9781 9782 CASE_FLT_FN (BUILT_IN_CABS): 9783 return fold_builtin_cabs (loc, arg0, type, fndecl); 9784 9785 CASE_FLT_FN (BUILT_IN_CARG): 9786 return fold_builtin_carg (loc, arg0, type); 9787 9788 CASE_FLT_FN (BUILT_IN_SQRT): 9789 return fold_builtin_sqrt (loc, arg0, type); 9790 9791 CASE_FLT_FN (BUILT_IN_CBRT): 9792 return fold_builtin_cbrt (loc, arg0, type); 9793 9794 CASE_FLT_FN (BUILT_IN_ASIN): 9795 if (validate_arg (arg0, REAL_TYPE)) 9796 return do_mpfr_arg1 (arg0, type, mpfr_asin, 9797 &dconstm1, &dconst1, true); 9798 break; 9799 9800 CASE_FLT_FN (BUILT_IN_ACOS): 9801 if (validate_arg (arg0, REAL_TYPE)) 9802 return do_mpfr_arg1 (arg0, type, mpfr_acos, 9803 &dconstm1, &dconst1, true); 9804 break; 9805 9806 CASE_FLT_FN (BUILT_IN_ATAN): 9807 if (validate_arg (arg0, REAL_TYPE)) 9808 return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0); 9809 break; 9810 9811 CASE_FLT_FN (BUILT_IN_ASINH): 9812 if (validate_arg (arg0, REAL_TYPE)) 9813 return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0); 9814 break; 9815 9816 CASE_FLT_FN (BUILT_IN_ACOSH): 9817 if (validate_arg (arg0, REAL_TYPE)) 9818 return do_mpfr_arg1 (arg0, type, mpfr_acosh, 9819 &dconst1, NULL, true); 9820 break; 9821 9822 CASE_FLT_FN (BUILT_IN_ATANH): 9823 if (validate_arg (arg0, REAL_TYPE)) 9824 return do_mpfr_arg1 (arg0, type, mpfr_atanh, 9825 &dconstm1, &dconst1, false); 9826 break; 9827 9828 CASE_FLT_FN (BUILT_IN_SIN): 9829 if (validate_arg (arg0, REAL_TYPE)) 9830 return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0); 9831 break; 9832 9833 CASE_FLT_FN (BUILT_IN_COS): 9834 return fold_builtin_cos (loc, arg0, type, fndecl); 9835 9836 CASE_FLT_FN (BUILT_IN_TAN): 9837 return fold_builtin_tan (arg0, type); 9838 9839 CASE_FLT_FN (BUILT_IN_CEXP): 9840 return fold_builtin_cexp (loc, arg0, type); 9841 9842 CASE_FLT_FN (BUILT_IN_CEXPI): 9843 if (validate_arg (arg0, REAL_TYPE)) 9844 return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE); 9845 break; 9846 9847 CASE_FLT_FN (BUILT_IN_SINH): 9848 if (validate_arg (arg0, REAL_TYPE)) 9849 return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0); 9850 break; 9851 9852 CASE_FLT_FN (BUILT_IN_COSH): 9853 return fold_builtin_cosh (loc, arg0, type, fndecl); 9854 9855 CASE_FLT_FN (BUILT_IN_TANH): 9856 if (validate_arg (arg0, REAL_TYPE)) 9857 return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0); 9858 break; 9859 9860 CASE_FLT_FN (BUILT_IN_ERF): 9861 if (validate_arg (arg0, REAL_TYPE)) 9862 return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0); 9863 break; 9864 9865 CASE_FLT_FN (BUILT_IN_ERFC): 9866 if (validate_arg (arg0, REAL_TYPE)) 9867 return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0); 9868 break; 9869 9870 CASE_FLT_FN (BUILT_IN_TGAMMA): 9871 if (validate_arg (arg0, REAL_TYPE)) 9872 return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0); 9873 break; 9874 9875 CASE_FLT_FN (BUILT_IN_EXP): 9876 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp); 9877 9878 CASE_FLT_FN (BUILT_IN_EXP2): 9879 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2); 9880 9881 CASE_FLT_FN (BUILT_IN_EXP10): 9882 CASE_FLT_FN (BUILT_IN_POW10): 9883 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10); 9884 9885 CASE_FLT_FN (BUILT_IN_EXPM1): 9886 if (validate_arg (arg0, REAL_TYPE)) 9887 return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0); 9888 break; 9889 9890 CASE_FLT_FN (BUILT_IN_LOG): 9891 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log); 9892 9893 CASE_FLT_FN (BUILT_IN_LOG2): 9894 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2); 9895 9896 CASE_FLT_FN (BUILT_IN_LOG10): 9897 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10); 9898 9899 CASE_FLT_FN (BUILT_IN_LOG1P): 9900 if (validate_arg (arg0, REAL_TYPE)) 9901 return do_mpfr_arg1 (arg0, type, mpfr_log1p, 9902 &dconstm1, NULL, false); 9903 break; 9904 9905 CASE_FLT_FN (BUILT_IN_J0): 9906 if (validate_arg (arg0, REAL_TYPE)) 9907 return do_mpfr_arg1 (arg0, type, mpfr_j0, 9908 NULL, NULL, 0); 9909 break; 9910 9911 CASE_FLT_FN (BUILT_IN_J1): 9912 if (validate_arg (arg0, REAL_TYPE)) 9913 return do_mpfr_arg1 (arg0, type, mpfr_j1, 9914 NULL, NULL, 0); 9915 break; 9916 9917 CASE_FLT_FN (BUILT_IN_Y0): 9918 if (validate_arg (arg0, REAL_TYPE)) 9919 return do_mpfr_arg1 (arg0, type, mpfr_y0, 9920 &dconst0, NULL, false); 9921 break; 9922 9923 CASE_FLT_FN (BUILT_IN_Y1): 9924 if (validate_arg (arg0, REAL_TYPE)) 9925 return do_mpfr_arg1 (arg0, type, mpfr_y1, 9926 &dconst0, NULL, false); 9927 break; 9928 9929 CASE_FLT_FN (BUILT_IN_NAN): 9930 case BUILT_IN_NAND32: 9931 case BUILT_IN_NAND64: 9932 case BUILT_IN_NAND128: 9933 return fold_builtin_nan (arg0, type, true); 9934 9935 CASE_FLT_FN (BUILT_IN_NANS): 9936 return fold_builtin_nan (arg0, type, false); 9937 9938 CASE_FLT_FN (BUILT_IN_FLOOR): 9939 return fold_builtin_floor (loc, fndecl, arg0); 9940 9941 CASE_FLT_FN (BUILT_IN_CEIL): 9942 return fold_builtin_ceil (loc, fndecl, arg0); 9943 9944 CASE_FLT_FN (BUILT_IN_TRUNC): 9945 return fold_builtin_trunc (loc, fndecl, arg0); 9946 9947 CASE_FLT_FN (BUILT_IN_ROUND): 9948 return fold_builtin_round (loc, fndecl, arg0); 9949 9950 CASE_FLT_FN (BUILT_IN_NEARBYINT): 9951 CASE_FLT_FN (BUILT_IN_RINT): 9952 return fold_trunc_transparent_mathfn (loc, fndecl, arg0); 9953 9954 CASE_FLT_FN (BUILT_IN_LCEIL): 9955 CASE_FLT_FN (BUILT_IN_LLCEIL): 9956 CASE_FLT_FN (BUILT_IN_LFLOOR): 9957 CASE_FLT_FN (BUILT_IN_LLFLOOR): 9958 CASE_FLT_FN (BUILT_IN_LROUND): 9959 CASE_FLT_FN (BUILT_IN_LLROUND): 9960 return fold_builtin_int_roundingfn (loc, fndecl, arg0); 9961 9962 CASE_FLT_FN (BUILT_IN_LRINT): 9963 CASE_FLT_FN (BUILT_IN_LLRINT): 9964 return fold_fixed_mathfn (loc, fndecl, arg0); 9965 9966 case BUILT_IN_BSWAP32: 9967 case BUILT_IN_BSWAP64: 9968 return fold_builtin_bswap (fndecl, arg0); 9969 9970 CASE_INT_FN (BUILT_IN_FFS): 9971 CASE_INT_FN (BUILT_IN_CLZ): 9972 CASE_INT_FN (BUILT_IN_CTZ): 9973 CASE_INT_FN (BUILT_IN_POPCOUNT): 9974 CASE_INT_FN (BUILT_IN_PARITY): 9975 return fold_builtin_bitop (fndecl, arg0); 9976 9977 CASE_FLT_FN (BUILT_IN_SIGNBIT): 9978 return fold_builtin_signbit (loc, arg0, type); 9979 9980 CASE_FLT_FN (BUILT_IN_SIGNIFICAND): 9981 return fold_builtin_significand (loc, arg0, type); 9982 9983 CASE_FLT_FN (BUILT_IN_ILOGB): 9984 CASE_FLT_FN (BUILT_IN_LOGB): 9985 return fold_builtin_logb (loc, arg0, type); 9986 9987 case BUILT_IN_ISASCII: 9988 return fold_builtin_isascii (loc, arg0); 9989 9990 case BUILT_IN_TOASCII: 9991 return fold_builtin_toascii (loc, arg0); 9992 9993 case BUILT_IN_ISDIGIT: 9994 return fold_builtin_isdigit (loc, arg0); 9995 9996 CASE_FLT_FN (BUILT_IN_FINITE): 9997 case BUILT_IN_FINITED32: 9998 case BUILT_IN_FINITED64: 9999 case BUILT_IN_FINITED128: 10000 case BUILT_IN_ISFINITE: 10001 { 10002 tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE); 10003 if (ret) 10004 return ret; 10005 return fold_builtin_interclass_mathfn (loc, fndecl, arg0); 10006 } 10007 10008 CASE_FLT_FN (BUILT_IN_ISINF): 10009 case BUILT_IN_ISINFD32: 10010 case BUILT_IN_ISINFD64: 10011 case BUILT_IN_ISINFD128: 10012 { 10013 tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF); 10014 if (ret) 10015 return ret; 10016 return fold_builtin_interclass_mathfn (loc, fndecl, arg0); 10017 } 10018 10019 case BUILT_IN_ISNORMAL: 10020 return fold_builtin_interclass_mathfn (loc, fndecl, arg0); 10021 10022 case BUILT_IN_ISINF_SIGN: 10023 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN); 10024 10025 CASE_FLT_FN (BUILT_IN_ISNAN): 10026 case BUILT_IN_ISNAND32: 10027 case BUILT_IN_ISNAND64: 10028 case BUILT_IN_ISNAND128: 10029 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN); 10030 10031 case BUILT_IN_PRINTF: 10032 case BUILT_IN_PRINTF_UNLOCKED: 10033 case BUILT_IN_VPRINTF: 10034 return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode); 10035 10036 default: 10037 break; 10038 } 10039 10040 return NULL_TREE; 10041 10042 } 10043 10044 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1. 10045 IGNORE is true if the result of the function call is ignored. This 10046 function returns NULL_TREE if no simplification was possible. */ 10047 10048 static tree 10049 fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore) 10050 { 10051 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 10052 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 10053 10054 switch (fcode) 10055 { 10056 CASE_FLT_FN (BUILT_IN_JN): 10057 if (validate_arg (arg0, INTEGER_TYPE) 10058 && validate_arg (arg1, REAL_TYPE)) 10059 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0); 10060 break; 10061 10062 CASE_FLT_FN (BUILT_IN_YN): 10063 if (validate_arg (arg0, INTEGER_TYPE) 10064 && validate_arg (arg1, REAL_TYPE)) 10065 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn, 10066 &dconst0, false); 10067 break; 10068 10069 CASE_FLT_FN (BUILT_IN_DREM): 10070 CASE_FLT_FN (BUILT_IN_REMAINDER): 10071 if (validate_arg (arg0, REAL_TYPE) 10072 && validate_arg(arg1, REAL_TYPE)) 10073 return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder); 10074 break; 10075 10076 CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */ 10077 CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */ 10078 if (validate_arg (arg0, REAL_TYPE) 10079 && validate_arg(arg1, POINTER_TYPE)) 10080 return do_mpfr_lgamma_r (arg0, arg1, type); 10081 break; 10082 10083 CASE_FLT_FN (BUILT_IN_ATAN2): 10084 if (validate_arg (arg0, REAL_TYPE) 10085 && validate_arg(arg1, REAL_TYPE)) 10086 return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2); 10087 break; 10088 10089 CASE_FLT_FN (BUILT_IN_FDIM): 10090 if (validate_arg (arg0, REAL_TYPE) 10091 && validate_arg(arg1, REAL_TYPE)) 10092 return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim); 10093 break; 10094 10095 CASE_FLT_FN (BUILT_IN_HYPOT): 10096 return fold_builtin_hypot (loc, fndecl, arg0, arg1, type); 10097 10098 CASE_FLT_FN (BUILT_IN_CPOW): 10099 if (validate_arg (arg0, COMPLEX_TYPE) 10100 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE 10101 && validate_arg (arg1, COMPLEX_TYPE) 10102 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE) 10103 return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow); 10104 break; 10105 10106 CASE_FLT_FN (BUILT_IN_LDEXP): 10107 return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true); 10108 CASE_FLT_FN (BUILT_IN_SCALBN): 10109 CASE_FLT_FN (BUILT_IN_SCALBLN): 10110 return fold_builtin_load_exponent (loc, arg0, arg1, 10111 type, /*ldexp=*/false); 10112 10113 CASE_FLT_FN (BUILT_IN_FREXP): 10114 return fold_builtin_frexp (loc, arg0, arg1, type); 10115 10116 CASE_FLT_FN (BUILT_IN_MODF): 10117 return fold_builtin_modf (loc, arg0, arg1, type); 10118 10119 case BUILT_IN_BZERO: 10120 return fold_builtin_bzero (loc, arg0, arg1, ignore); 10121 10122 case BUILT_IN_FPUTS: 10123 return fold_builtin_fputs (loc, arg0, arg1, ignore, false, NULL_TREE); 10124 10125 case BUILT_IN_FPUTS_UNLOCKED: 10126 return fold_builtin_fputs (loc, arg0, arg1, ignore, true, NULL_TREE); 10127 10128 case BUILT_IN_STRSTR: 10129 return fold_builtin_strstr (loc, arg0, arg1, type); 10130 10131 case BUILT_IN_STRCAT: 10132 return fold_builtin_strcat (loc, arg0, arg1); 10133 10134 case BUILT_IN_STRSPN: 10135 return fold_builtin_strspn (loc, arg0, arg1); 10136 10137 case BUILT_IN_STRCSPN: 10138 return fold_builtin_strcspn (loc, arg0, arg1); 10139 10140 case BUILT_IN_STRCHR: 10141 case BUILT_IN_INDEX: 10142 return fold_builtin_strchr (loc, arg0, arg1, type); 10143 10144 case BUILT_IN_STRRCHR: 10145 case BUILT_IN_RINDEX: 10146 return fold_builtin_strrchr (loc, arg0, arg1, type); 10147 10148 case BUILT_IN_STRCPY: 10149 return fold_builtin_strcpy (loc, fndecl, arg0, arg1, NULL_TREE); 10150 10151 case BUILT_IN_STPCPY: 10152 if (ignore) 10153 { 10154 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 10155 if (!fn) 10156 break; 10157 10158 return build_call_expr_loc (loc, fn, 2, arg0, arg1); 10159 } 10160 else 10161 return fold_builtin_stpcpy (loc, fndecl, arg0, arg1); 10162 break; 10163 10164 case BUILT_IN_STRCMP: 10165 return fold_builtin_strcmp (loc, arg0, arg1); 10166 10167 case BUILT_IN_STRPBRK: 10168 return fold_builtin_strpbrk (loc, arg0, arg1, type); 10169 10170 case BUILT_IN_EXPECT: 10171 return fold_builtin_expect (loc, arg0, arg1); 10172 10173 CASE_FLT_FN (BUILT_IN_POW): 10174 return fold_builtin_pow (loc, fndecl, arg0, arg1, type); 10175 10176 CASE_FLT_FN (BUILT_IN_POWI): 10177 return fold_builtin_powi (loc, fndecl, arg0, arg1, type); 10178 10179 CASE_FLT_FN (BUILT_IN_COPYSIGN): 10180 return fold_builtin_copysign (loc, fndecl, arg0, arg1, type); 10181 10182 CASE_FLT_FN (BUILT_IN_FMIN): 10183 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false); 10184 10185 CASE_FLT_FN (BUILT_IN_FMAX): 10186 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true); 10187 10188 case BUILT_IN_ISGREATER: 10189 return fold_builtin_unordered_cmp (loc, fndecl, 10190 arg0, arg1, UNLE_EXPR, LE_EXPR); 10191 case BUILT_IN_ISGREATEREQUAL: 10192 return fold_builtin_unordered_cmp (loc, fndecl, 10193 arg0, arg1, UNLT_EXPR, LT_EXPR); 10194 case BUILT_IN_ISLESS: 10195 return fold_builtin_unordered_cmp (loc, fndecl, 10196 arg0, arg1, UNGE_EXPR, GE_EXPR); 10197 case BUILT_IN_ISLESSEQUAL: 10198 return fold_builtin_unordered_cmp (loc, fndecl, 10199 arg0, arg1, UNGT_EXPR, GT_EXPR); 10200 case BUILT_IN_ISLESSGREATER: 10201 return fold_builtin_unordered_cmp (loc, fndecl, 10202 arg0, arg1, UNEQ_EXPR, EQ_EXPR); 10203 case BUILT_IN_ISUNORDERED: 10204 return fold_builtin_unordered_cmp (loc, fndecl, 10205 arg0, arg1, UNORDERED_EXPR, 10206 NOP_EXPR); 10207 10208 /* We do the folding for va_start in the expander. */ 10209 case BUILT_IN_VA_START: 10210 break; 10211 10212 case BUILT_IN_SPRINTF: 10213 return fold_builtin_sprintf (loc, arg0, arg1, NULL_TREE, ignore); 10214 10215 case BUILT_IN_OBJECT_SIZE: 10216 return fold_builtin_object_size (arg0, arg1); 10217 10218 case BUILT_IN_PRINTF: 10219 case BUILT_IN_PRINTF_UNLOCKED: 10220 case BUILT_IN_VPRINTF: 10221 return fold_builtin_printf (loc, fndecl, arg0, arg1, ignore, fcode); 10222 10223 case BUILT_IN_PRINTF_CHK: 10224 case BUILT_IN_VPRINTF_CHK: 10225 if (!validate_arg (arg0, INTEGER_TYPE) 10226 || TREE_SIDE_EFFECTS (arg0)) 10227 return NULL_TREE; 10228 else 10229 return fold_builtin_printf (loc, fndecl, 10230 arg1, NULL_TREE, ignore, fcode); 10231 break; 10232 10233 case BUILT_IN_FPRINTF: 10234 case BUILT_IN_FPRINTF_UNLOCKED: 10235 case BUILT_IN_VFPRINTF: 10236 return fold_builtin_fprintf (loc, fndecl, arg0, arg1, NULL_TREE, 10237 ignore, fcode); 10238 10239 default: 10240 break; 10241 } 10242 return NULL_TREE; 10243 } 10244 10245 /* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1, 10246 and ARG2. IGNORE is true if the result of the function call is ignored. 10247 This function returns NULL_TREE if no simplification was possible. */ 10248 10249 static tree 10250 fold_builtin_3 (location_t loc, tree fndecl, 10251 tree arg0, tree arg1, tree arg2, bool ignore) 10252 { 10253 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 10254 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 10255 switch (fcode) 10256 { 10257 10258 CASE_FLT_FN (BUILT_IN_SINCOS): 10259 return fold_builtin_sincos (loc, arg0, arg1, arg2); 10260 10261 CASE_FLT_FN (BUILT_IN_FMA): 10262 if (validate_arg (arg0, REAL_TYPE) 10263 && validate_arg(arg1, REAL_TYPE) 10264 && validate_arg(arg2, REAL_TYPE)) 10265 return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma); 10266 break; 10267 10268 CASE_FLT_FN (BUILT_IN_REMQUO): 10269 if (validate_arg (arg0, REAL_TYPE) 10270 && validate_arg(arg1, REAL_TYPE) 10271 && validate_arg(arg2, POINTER_TYPE)) 10272 return do_mpfr_remquo (arg0, arg1, arg2); 10273 break; 10274 10275 case BUILT_IN_MEMSET: 10276 return fold_builtin_memset (loc, arg0, arg1, arg2, type, ignore); 10277 10278 case BUILT_IN_BCOPY: 10279 return fold_builtin_memory_op (loc, arg1, arg0, arg2, 10280 void_type_node, true, /*endp=*/3); 10281 10282 case BUILT_IN_MEMCPY: 10283 return fold_builtin_memory_op (loc, arg0, arg1, arg2, 10284 type, ignore, /*endp=*/0); 10285 10286 case BUILT_IN_MEMPCPY: 10287 return fold_builtin_memory_op (loc, arg0, arg1, arg2, 10288 type, ignore, /*endp=*/1); 10289 10290 case BUILT_IN_MEMMOVE: 10291 return fold_builtin_memory_op (loc, arg0, arg1, arg2, 10292 type, ignore, /*endp=*/3); 10293 10294 case BUILT_IN_STRNCAT: 10295 return fold_builtin_strncat (loc, arg0, arg1, arg2); 10296 10297 case BUILT_IN_STRNCPY: 10298 return fold_builtin_strncpy (loc, fndecl, arg0, arg1, arg2, NULL_TREE); 10299 10300 case BUILT_IN_STRNCMP: 10301 return fold_builtin_strncmp (loc, arg0, arg1, arg2); 10302 10303 case BUILT_IN_MEMCHR: 10304 return fold_builtin_memchr (loc, arg0, arg1, arg2, type); 10305 10306 case BUILT_IN_BCMP: 10307 case BUILT_IN_MEMCMP: 10308 return fold_builtin_memcmp (loc, arg0, arg1, arg2);; 10309 10310 case BUILT_IN_SPRINTF: 10311 return fold_builtin_sprintf (loc, arg0, arg1, arg2, ignore); 10312 10313 case BUILT_IN_STRCPY_CHK: 10314 case BUILT_IN_STPCPY_CHK: 10315 return fold_builtin_stxcpy_chk (loc, fndecl, arg0, arg1, arg2, NULL_TREE, 10316 ignore, fcode); 10317 10318 case BUILT_IN_STRCAT_CHK: 10319 return fold_builtin_strcat_chk (loc, fndecl, arg0, arg1, arg2); 10320 10321 case BUILT_IN_PRINTF_CHK: 10322 case BUILT_IN_VPRINTF_CHK: 10323 if (!validate_arg (arg0, INTEGER_TYPE) 10324 || TREE_SIDE_EFFECTS (arg0)) 10325 return NULL_TREE; 10326 else 10327 return fold_builtin_printf (loc, fndecl, arg1, arg2, ignore, fcode); 10328 break; 10329 10330 case BUILT_IN_FPRINTF: 10331 case BUILT_IN_FPRINTF_UNLOCKED: 10332 case BUILT_IN_VFPRINTF: 10333 return fold_builtin_fprintf (loc, fndecl, arg0, arg1, arg2, 10334 ignore, fcode); 10335 10336 case BUILT_IN_FPRINTF_CHK: 10337 case BUILT_IN_VFPRINTF_CHK: 10338 if (!validate_arg (arg1, INTEGER_TYPE) 10339 || TREE_SIDE_EFFECTS (arg1)) 10340 return NULL_TREE; 10341 else 10342 return fold_builtin_fprintf (loc, fndecl, arg0, arg2, NULL_TREE, 10343 ignore, fcode); 10344 10345 default: 10346 break; 10347 } 10348 return NULL_TREE; 10349 } 10350 10351 /* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1, 10352 ARG2, and ARG3. IGNORE is true if the result of the function call is 10353 ignored. This function returns NULL_TREE if no simplification was 10354 possible. */ 10355 10356 static tree 10357 fold_builtin_4 (location_t loc, tree fndecl, 10358 tree arg0, tree arg1, tree arg2, tree arg3, bool ignore) 10359 { 10360 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 10361 10362 switch (fcode) 10363 { 10364 case BUILT_IN_MEMCPY_CHK: 10365 case BUILT_IN_MEMPCPY_CHK: 10366 case BUILT_IN_MEMMOVE_CHK: 10367 case BUILT_IN_MEMSET_CHK: 10368 return fold_builtin_memory_chk (loc, fndecl, arg0, arg1, arg2, arg3, 10369 NULL_TREE, ignore, 10370 DECL_FUNCTION_CODE (fndecl)); 10371 10372 case BUILT_IN_STRNCPY_CHK: 10373 return fold_builtin_strncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE); 10374 10375 case BUILT_IN_STRNCAT_CHK: 10376 return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3); 10377 10378 case BUILT_IN_FPRINTF_CHK: 10379 case BUILT_IN_VFPRINTF_CHK: 10380 if (!validate_arg (arg1, INTEGER_TYPE) 10381 || TREE_SIDE_EFFECTS (arg1)) 10382 return NULL_TREE; 10383 else 10384 return fold_builtin_fprintf (loc, fndecl, arg0, arg2, arg3, 10385 ignore, fcode); 10386 break; 10387 10388 default: 10389 break; 10390 } 10391 return NULL_TREE; 10392 } 10393 10394 /* Fold a call to built-in function FNDECL. ARGS is an array of NARGS 10395 arguments, where NARGS <= 4. IGNORE is true if the result of the 10396 function call is ignored. This function returns NULL_TREE if no 10397 simplification was possible. Note that this only folds builtins with 10398 fixed argument patterns. Foldings that do varargs-to-varargs 10399 transformations, or that match calls with more than 4 arguments, 10400 need to be handled with fold_builtin_varargs instead. */ 10401 10402 #define MAX_ARGS_TO_FOLD_BUILTIN 4 10403 10404 static tree 10405 fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore) 10406 { 10407 tree ret = NULL_TREE; 10408 10409 switch (nargs) 10410 { 10411 case 0: 10412 ret = fold_builtin_0 (loc, fndecl, ignore); 10413 break; 10414 case 1: 10415 ret = fold_builtin_1 (loc, fndecl, args[0], ignore); 10416 break; 10417 case 2: 10418 ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore); 10419 break; 10420 case 3: 10421 ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore); 10422 break; 10423 case 4: 10424 ret = fold_builtin_4 (loc, fndecl, args[0], args[1], args[2], args[3], 10425 ignore); 10426 break; 10427 default: 10428 break; 10429 } 10430 if (ret) 10431 { 10432 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); 10433 SET_EXPR_LOCATION (ret, loc); 10434 TREE_NO_WARNING (ret) = 1; 10435 return ret; 10436 } 10437 return NULL_TREE; 10438 } 10439 10440 /* Builtins with folding operations that operate on "..." arguments 10441 need special handling; we need to store the arguments in a convenient 10442 data structure before attempting any folding. Fortunately there are 10443 only a few builtins that fall into this category. FNDECL is the 10444 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the 10445 result of the function call is ignored. */ 10446 10447 static tree 10448 fold_builtin_varargs (location_t loc, tree fndecl, tree exp, 10449 bool ignore ATTRIBUTE_UNUSED) 10450 { 10451 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 10452 tree ret = NULL_TREE; 10453 10454 switch (fcode) 10455 { 10456 case BUILT_IN_SPRINTF_CHK: 10457 case BUILT_IN_VSPRINTF_CHK: 10458 ret = fold_builtin_sprintf_chk (loc, exp, fcode); 10459 break; 10460 10461 case BUILT_IN_SNPRINTF_CHK: 10462 case BUILT_IN_VSNPRINTF_CHK: 10463 ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode); 10464 break; 10465 10466 case BUILT_IN_FPCLASSIFY: 10467 ret = fold_builtin_fpclassify (loc, exp); 10468 break; 10469 10470 default: 10471 break; 10472 } 10473 if (ret) 10474 { 10475 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); 10476 SET_EXPR_LOCATION (ret, loc); 10477 TREE_NO_WARNING (ret) = 1; 10478 return ret; 10479 } 10480 return NULL_TREE; 10481 } 10482 10483 /* Return true if FNDECL shouldn't be folded right now. 10484 If a built-in function has an inline attribute always_inline 10485 wrapper, defer folding it after always_inline functions have 10486 been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking 10487 might not be performed. */ 10488 10489 static bool 10490 avoid_folding_inline_builtin (tree fndecl) 10491 { 10492 return (DECL_DECLARED_INLINE_P (fndecl) 10493 && DECL_DISREGARD_INLINE_LIMITS (fndecl) 10494 && cfun 10495 && !cfun->always_inline_functions_inlined 10496 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl))); 10497 } 10498 10499 /* A wrapper function for builtin folding that prevents warnings for 10500 "statement without effect" and the like, caused by removing the 10501 call node earlier than the warning is generated. */ 10502 10503 tree 10504 fold_call_expr (location_t loc, tree exp, bool ignore) 10505 { 10506 tree ret = NULL_TREE; 10507 tree fndecl = get_callee_fndecl (exp); 10508 if (fndecl 10509 && TREE_CODE (fndecl) == FUNCTION_DECL 10510 && DECL_BUILT_IN (fndecl) 10511 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized 10512 yet. Defer folding until we see all the arguments 10513 (after inlining). */ 10514 && !CALL_EXPR_VA_ARG_PACK (exp)) 10515 { 10516 int nargs = call_expr_nargs (exp); 10517 10518 /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but 10519 instead last argument is __builtin_va_arg_pack (). Defer folding 10520 even in that case, until arguments are finalized. */ 10521 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR) 10522 { 10523 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1)); 10524 if (fndecl2 10525 && TREE_CODE (fndecl2) == FUNCTION_DECL 10526 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL 10527 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK) 10528 return NULL_TREE; 10529 } 10530 10531 if (avoid_folding_inline_builtin (fndecl)) 10532 return NULL_TREE; 10533 10534 /* FIXME: Don't use a list in this interface. */ 10535 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 10536 return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore); 10537 else 10538 { 10539 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN) 10540 { 10541 tree *args = CALL_EXPR_ARGP (exp); 10542 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore); 10543 } 10544 if (!ret) 10545 ret = fold_builtin_varargs (loc, fndecl, exp, ignore); 10546 if (ret) 10547 return ret; 10548 } 10549 } 10550 return NULL_TREE; 10551 } 10552 10553 /* Conveniently construct a function call expression. FNDECL names the 10554 function to be called and ARGLIST is a TREE_LIST of arguments. */ 10555 10556 tree 10557 build_function_call_expr (location_t loc, tree fndecl, tree arglist) 10558 { 10559 tree fntype = TREE_TYPE (fndecl); 10560 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl); 10561 int n = list_length (arglist); 10562 tree *argarray = (tree *) alloca (n * sizeof (tree)); 10563 int i; 10564 10565 for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist)) 10566 argarray[i] = TREE_VALUE (arglist); 10567 return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray); 10568 } 10569 10570 /* Conveniently construct a function call expression. FNDECL names the 10571 function to be called, N is the number of arguments, and the "..." 10572 parameters are the argument expressions. */ 10573 10574 tree 10575 build_call_expr_loc (location_t loc, tree fndecl, int n, ...) 10576 { 10577 va_list ap; 10578 tree fntype = TREE_TYPE (fndecl); 10579 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl); 10580 tree *argarray = (tree *) alloca (n * sizeof (tree)); 10581 int i; 10582 10583 va_start (ap, n); 10584 for (i = 0; i < n; i++) 10585 argarray[i] = va_arg (ap, tree); 10586 va_end (ap); 10587 return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray); 10588 } 10589 10590 /* Like build_call_expr_loc (UNKNOWN_LOCATION, ...). Duplicated because 10591 varargs macros aren't supported by all bootstrap compilers. */ 10592 10593 tree 10594 build_call_expr (tree fndecl, int n, ...) 10595 { 10596 va_list ap; 10597 tree fntype = TREE_TYPE (fndecl); 10598 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl); 10599 tree *argarray = (tree *) alloca (n * sizeof (tree)); 10600 int i; 10601 10602 va_start (ap, n); 10603 for (i = 0; i < n; i++) 10604 argarray[i] = va_arg (ap, tree); 10605 va_end (ap); 10606 return fold_builtin_call_array (UNKNOWN_LOCATION, TREE_TYPE (fntype), 10607 fn, n, argarray); 10608 } 10609 10610 /* Construct a CALL_EXPR with type TYPE with FN as the function expression. 10611 N arguments are passed in the array ARGARRAY. */ 10612 10613 tree 10614 fold_builtin_call_array (location_t loc, tree type, 10615 tree fn, 10616 int n, 10617 tree *argarray) 10618 { 10619 tree ret = NULL_TREE; 10620 int i; 10621 tree exp; 10622 10623 if (TREE_CODE (fn) == ADDR_EXPR) 10624 { 10625 tree fndecl = TREE_OPERAND (fn, 0); 10626 if (TREE_CODE (fndecl) == FUNCTION_DECL 10627 && DECL_BUILT_IN (fndecl)) 10628 { 10629 /* If last argument is __builtin_va_arg_pack (), arguments to this 10630 function are not finalized yet. Defer folding until they are. */ 10631 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR) 10632 { 10633 tree fndecl2 = get_callee_fndecl (argarray[n - 1]); 10634 if (fndecl2 10635 && TREE_CODE (fndecl2) == FUNCTION_DECL 10636 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL 10637 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK) 10638 return build_call_array_loc (loc, type, fn, n, argarray); 10639 } 10640 if (avoid_folding_inline_builtin (fndecl)) 10641 return build_call_array_loc (loc, type, fn, n, argarray); 10642 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 10643 { 10644 tree arglist = NULL_TREE; 10645 for (i = n - 1; i >= 0; i--) 10646 arglist = tree_cons (NULL_TREE, argarray[i], arglist); 10647 ret = targetm.fold_builtin (fndecl, arglist, false); 10648 if (ret) 10649 return ret; 10650 return build_call_array_loc (loc, type, fn, n, argarray); 10651 } 10652 else if (n <= MAX_ARGS_TO_FOLD_BUILTIN) 10653 { 10654 /* First try the transformations that don't require consing up 10655 an exp. */ 10656 ret = fold_builtin_n (loc, fndecl, argarray, n, false); 10657 if (ret) 10658 return ret; 10659 } 10660 10661 /* If we got this far, we need to build an exp. */ 10662 exp = build_call_array_loc (loc, type, fn, n, argarray); 10663 ret = fold_builtin_varargs (loc, fndecl, exp, false); 10664 return ret ? ret : exp; 10665 } 10666 } 10667 10668 return build_call_array_loc (loc, type, fn, n, argarray); 10669 } 10670 10671 /* Construct a new CALL_EXPR using the tail of the argument list of EXP 10672 along with N new arguments specified as the "..." parameters. SKIP 10673 is the number of arguments in EXP to be omitted. This function is used 10674 to do varargs-to-varargs transformations. */ 10675 10676 static tree 10677 rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...) 10678 { 10679 int oldnargs = call_expr_nargs (exp); 10680 int nargs = oldnargs - skip + n; 10681 tree fntype = TREE_TYPE (fndecl); 10682 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl); 10683 tree *buffer; 10684 10685 if (n > 0) 10686 { 10687 int i, j; 10688 va_list ap; 10689 10690 buffer = XALLOCAVEC (tree, nargs); 10691 va_start (ap, n); 10692 for (i = 0; i < n; i++) 10693 buffer[i] = va_arg (ap, tree); 10694 va_end (ap); 10695 for (j = skip; j < oldnargs; j++, i++) 10696 buffer[i] = CALL_EXPR_ARG (exp, j); 10697 } 10698 else 10699 buffer = CALL_EXPR_ARGP (exp) + skip; 10700 10701 return fold (build_call_array_loc (loc, TREE_TYPE (exp), fn, nargs, buffer)); 10702 } 10703 10704 /* Validate a single argument ARG against a tree code CODE representing 10705 a type. */ 10706 10707 static bool 10708 validate_arg (const_tree arg, enum tree_code code) 10709 { 10710 if (!arg) 10711 return false; 10712 else if (code == POINTER_TYPE) 10713 return POINTER_TYPE_P (TREE_TYPE (arg)); 10714 else if (code == INTEGER_TYPE) 10715 return INTEGRAL_TYPE_P (TREE_TYPE (arg)); 10716 return code == TREE_CODE (TREE_TYPE (arg)); 10717 } 10718 10719 /* This function validates the types of a function call argument list 10720 against a specified list of tree_codes. If the last specifier is a 0, 10721 that represents an ellipses, otherwise the last specifier must be a 10722 VOID_TYPE. 10723 10724 This is the GIMPLE version of validate_arglist. Eventually we want to 10725 completely convert builtins.c to work from GIMPLEs and the tree based 10726 validate_arglist will then be removed. */ 10727 10728 bool 10729 validate_gimple_arglist (const_gimple call, ...) 10730 { 10731 enum tree_code code; 10732 bool res = 0; 10733 va_list ap; 10734 const_tree arg; 10735 size_t i; 10736 10737 va_start (ap, call); 10738 i = 0; 10739 10740 do 10741 { 10742 code = (enum tree_code) va_arg (ap, int); 10743 switch (code) 10744 { 10745 case 0: 10746 /* This signifies an ellipses, any further arguments are all ok. */ 10747 res = true; 10748 goto end; 10749 case VOID_TYPE: 10750 /* This signifies an endlink, if no arguments remain, return 10751 true, otherwise return false. */ 10752 res = (i == gimple_call_num_args (call)); 10753 goto end; 10754 default: 10755 /* If no parameters remain or the parameter's code does not 10756 match the specified code, return false. Otherwise continue 10757 checking any remaining arguments. */ 10758 arg = gimple_call_arg (call, i++); 10759 if (!validate_arg (arg, code)) 10760 goto end; 10761 break; 10762 } 10763 } 10764 while (1); 10765 10766 /* We need gotos here since we can only have one VA_CLOSE in a 10767 function. */ 10768 end: ; 10769 va_end (ap); 10770 10771 return res; 10772 } 10773 10774 /* This function validates the types of a function call argument list 10775 against a specified list of tree_codes. If the last specifier is a 0, 10776 that represents an ellipses, otherwise the last specifier must be a 10777 VOID_TYPE. */ 10778 10779 bool 10780 validate_arglist (const_tree callexpr, ...) 10781 { 10782 enum tree_code code; 10783 bool res = 0; 10784 va_list ap; 10785 const_call_expr_arg_iterator iter; 10786 const_tree arg; 10787 10788 va_start (ap, callexpr); 10789 init_const_call_expr_arg_iterator (callexpr, &iter); 10790 10791 do 10792 { 10793 code = (enum tree_code) va_arg (ap, int); 10794 switch (code) 10795 { 10796 case 0: 10797 /* This signifies an ellipses, any further arguments are all ok. */ 10798 res = true; 10799 goto end; 10800 case VOID_TYPE: 10801 /* This signifies an endlink, if no arguments remain, return 10802 true, otherwise return false. */ 10803 res = !more_const_call_expr_args_p (&iter); 10804 goto end; 10805 default: 10806 /* If no parameters remain or the parameter's code does not 10807 match the specified code, return false. Otherwise continue 10808 checking any remaining arguments. */ 10809 arg = next_const_call_expr_arg (&iter); 10810 if (!validate_arg (arg, code)) 10811 goto end; 10812 break; 10813 } 10814 } 10815 while (1); 10816 10817 /* We need gotos here since we can only have one VA_CLOSE in a 10818 function. */ 10819 end: ; 10820 va_end (ap); 10821 10822 return res; 10823 } 10824 10825 /* Default target-specific builtin expander that does nothing. */ 10826 10827 rtx 10828 default_expand_builtin (tree exp ATTRIBUTE_UNUSED, 10829 rtx target ATTRIBUTE_UNUSED, 10830 rtx subtarget ATTRIBUTE_UNUSED, 10831 enum machine_mode mode ATTRIBUTE_UNUSED, 10832 int ignore ATTRIBUTE_UNUSED) 10833 { 10834 return NULL_RTX; 10835 } 10836 10837 /* Returns true is EXP represents data that would potentially reside 10838 in a readonly section. */ 10839 10840 static bool 10841 readonly_data_expr (tree exp) 10842 { 10843 STRIP_NOPS (exp); 10844 10845 if (TREE_CODE (exp) != ADDR_EXPR) 10846 return false; 10847 10848 exp = get_base_address (TREE_OPERAND (exp, 0)); 10849 if (!exp) 10850 return false; 10851 10852 /* Make sure we call decl_readonly_section only for trees it 10853 can handle (since it returns true for everything it doesn't 10854 understand). */ 10855 if (TREE_CODE (exp) == STRING_CST 10856 || TREE_CODE (exp) == CONSTRUCTOR 10857 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp))) 10858 return decl_readonly_section (exp, 0); 10859 else 10860 return false; 10861 } 10862 10863 /* Simplify a call to the strstr builtin. S1 and S2 are the arguments 10864 to the call, and TYPE is its return type. 10865 10866 Return NULL_TREE if no simplification was possible, otherwise return the 10867 simplified form of the call as a tree. 10868 10869 The simplified form may be a constant or other expression which 10870 computes the same value, but in a more efficient manner (including 10871 calls to other builtin functions). 10872 10873 The call may contain arguments which need to be evaluated, but 10874 which are not useful to determine the result of the call. In 10875 this case we return a chain of COMPOUND_EXPRs. The LHS of each 10876 COMPOUND_EXPR will be an argument which must be evaluated. 10877 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 10878 COMPOUND_EXPR in the chain will contain the tree for the simplified 10879 form of the builtin function call. */ 10880 10881 static tree 10882 fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type) 10883 { 10884 if (!validate_arg (s1, POINTER_TYPE) 10885 || !validate_arg (s2, POINTER_TYPE)) 10886 return NULL_TREE; 10887 else 10888 { 10889 tree fn; 10890 const char *p1, *p2; 10891 10892 p2 = c_getstr (s2); 10893 if (p2 == NULL) 10894 return NULL_TREE; 10895 10896 p1 = c_getstr (s1); 10897 if (p1 != NULL) 10898 { 10899 const char *r = strstr (p1, p2); 10900 tree tem; 10901 10902 if (r == NULL) 10903 return build_int_cst (TREE_TYPE (s1), 0); 10904 10905 /* Return an offset into the constant string argument. */ 10906 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1), 10907 s1, size_int (r - p1)); 10908 return fold_convert_loc (loc, type, tem); 10909 } 10910 10911 /* The argument is const char *, and the result is char *, so we need 10912 a type conversion here to avoid a warning. */ 10913 if (p2[0] == '\0') 10914 return fold_convert_loc (loc, type, s1); 10915 10916 if (p2[1] != '\0') 10917 return NULL_TREE; 10918 10919 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 10920 if (!fn) 10921 return NULL_TREE; 10922 10923 /* New argument list transforming strstr(s1, s2) to 10924 strchr(s1, s2[0]). */ 10925 return build_call_expr_loc (loc, fn, 2, s1, build_int_cst (NULL_TREE, p2[0])); 10926 } 10927 } 10928 10929 /* Simplify a call to the strchr builtin. S1 and S2 are the arguments to 10930 the call, and TYPE is its return type. 10931 10932 Return NULL_TREE if no simplification was possible, otherwise return the 10933 simplified form of the call as a tree. 10934 10935 The simplified form may be a constant or other expression which 10936 computes the same value, but in a more efficient manner (including 10937 calls to other builtin functions). 10938 10939 The call may contain arguments which need to be evaluated, but 10940 which are not useful to determine the result of the call. In 10941 this case we return a chain of COMPOUND_EXPRs. The LHS of each 10942 COMPOUND_EXPR will be an argument which must be evaluated. 10943 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 10944 COMPOUND_EXPR in the chain will contain the tree for the simplified 10945 form of the builtin function call. */ 10946 10947 static tree 10948 fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type) 10949 { 10950 if (!validate_arg (s1, POINTER_TYPE) 10951 || !validate_arg (s2, INTEGER_TYPE)) 10952 return NULL_TREE; 10953 else 10954 { 10955 const char *p1; 10956 10957 if (TREE_CODE (s2) != INTEGER_CST) 10958 return NULL_TREE; 10959 10960 p1 = c_getstr (s1); 10961 if (p1 != NULL) 10962 { 10963 char c; 10964 const char *r; 10965 tree tem; 10966 10967 if (target_char_cast (s2, &c)) 10968 return NULL_TREE; 10969 10970 r = strchr (p1, c); 10971 10972 if (r == NULL) 10973 return build_int_cst (TREE_TYPE (s1), 0); 10974 10975 /* Return an offset into the constant string argument. */ 10976 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1), 10977 s1, size_int (r - p1)); 10978 return fold_convert_loc (loc, type, tem); 10979 } 10980 return NULL_TREE; 10981 } 10982 } 10983 10984 /* Simplify a call to the strrchr builtin. S1 and S2 are the arguments to 10985 the call, and TYPE is its return type. 10986 10987 Return NULL_TREE if no simplification was possible, otherwise return the 10988 simplified form of the call as a tree. 10989 10990 The simplified form may be a constant or other expression which 10991 computes the same value, but in a more efficient manner (including 10992 calls to other builtin functions). 10993 10994 The call may contain arguments which need to be evaluated, but 10995 which are not useful to determine the result of the call. In 10996 this case we return a chain of COMPOUND_EXPRs. The LHS of each 10997 COMPOUND_EXPR will be an argument which must be evaluated. 10998 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 10999 COMPOUND_EXPR in the chain will contain the tree for the simplified 11000 form of the builtin function call. */ 11001 11002 static tree 11003 fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type) 11004 { 11005 if (!validate_arg (s1, POINTER_TYPE) 11006 || !validate_arg (s2, INTEGER_TYPE)) 11007 return NULL_TREE; 11008 else 11009 { 11010 tree fn; 11011 const char *p1; 11012 11013 if (TREE_CODE (s2) != INTEGER_CST) 11014 return NULL_TREE; 11015 11016 p1 = c_getstr (s1); 11017 if (p1 != NULL) 11018 { 11019 char c; 11020 const char *r; 11021 tree tem; 11022 11023 if (target_char_cast (s2, &c)) 11024 return NULL_TREE; 11025 11026 r = strrchr (p1, c); 11027 11028 if (r == NULL) 11029 return build_int_cst (TREE_TYPE (s1), 0); 11030 11031 /* Return an offset into the constant string argument. */ 11032 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1), 11033 s1, size_int (r - p1)); 11034 return fold_convert_loc (loc, type, tem); 11035 } 11036 11037 if (! integer_zerop (s2)) 11038 return NULL_TREE; 11039 11040 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 11041 if (!fn) 11042 return NULL_TREE; 11043 11044 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */ 11045 return build_call_expr_loc (loc, fn, 2, s1, s2); 11046 } 11047 } 11048 11049 /* Simplify a call to the strpbrk builtin. S1 and S2 are the arguments 11050 to the call, and TYPE is its return type. 11051 11052 Return NULL_TREE if no simplification was possible, otherwise return the 11053 simplified form of the call as a tree. 11054 11055 The simplified form may be a constant or other expression which 11056 computes the same value, but in a more efficient manner (including 11057 calls to other builtin functions). 11058 11059 The call may contain arguments which need to be evaluated, but 11060 which are not useful to determine the result of the call. In 11061 this case we return a chain of COMPOUND_EXPRs. The LHS of each 11062 COMPOUND_EXPR will be an argument which must be evaluated. 11063 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 11064 COMPOUND_EXPR in the chain will contain the tree for the simplified 11065 form of the builtin function call. */ 11066 11067 static tree 11068 fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type) 11069 { 11070 if (!validate_arg (s1, POINTER_TYPE) 11071 || !validate_arg (s2, POINTER_TYPE)) 11072 return NULL_TREE; 11073 else 11074 { 11075 tree fn; 11076 const char *p1, *p2; 11077 11078 p2 = c_getstr (s2); 11079 if (p2 == NULL) 11080 return NULL_TREE; 11081 11082 p1 = c_getstr (s1); 11083 if (p1 != NULL) 11084 { 11085 const char *r = strpbrk (p1, p2); 11086 tree tem; 11087 11088 if (r == NULL) 11089 return build_int_cst (TREE_TYPE (s1), 0); 11090 11091 /* Return an offset into the constant string argument. */ 11092 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1), 11093 s1, size_int (r - p1)); 11094 return fold_convert_loc (loc, type, tem); 11095 } 11096 11097 if (p2[0] == '\0') 11098 /* strpbrk(x, "") == NULL. 11099 Evaluate and ignore s1 in case it had side-effects. */ 11100 return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1); 11101 11102 if (p2[1] != '\0') 11103 return NULL_TREE; /* Really call strpbrk. */ 11104 11105 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 11106 if (!fn) 11107 return NULL_TREE; 11108 11109 /* New argument list transforming strpbrk(s1, s2) to 11110 strchr(s1, s2[0]). */ 11111 return build_call_expr_loc (loc, fn, 2, s1, build_int_cst (NULL_TREE, p2[0])); 11112 } 11113 } 11114 11115 /* Simplify a call to the strcat builtin. DST and SRC are the arguments 11116 to the call. 11117 11118 Return NULL_TREE if no simplification was possible, otherwise return the 11119 simplified form of the call as a tree. 11120 11121 The simplified form may be a constant or other expression which 11122 computes the same value, but in a more efficient manner (including 11123 calls to other builtin functions). 11124 11125 The call may contain arguments which need to be evaluated, but 11126 which are not useful to determine the result of the call. In 11127 this case we return a chain of COMPOUND_EXPRs. The LHS of each 11128 COMPOUND_EXPR will be an argument which must be evaluated. 11129 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 11130 COMPOUND_EXPR in the chain will contain the tree for the simplified 11131 form of the builtin function call. */ 11132 11133 static tree 11134 fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src) 11135 { 11136 if (!validate_arg (dst, POINTER_TYPE) 11137 || !validate_arg (src, POINTER_TYPE)) 11138 return NULL_TREE; 11139 else 11140 { 11141 const char *p = c_getstr (src); 11142 11143 /* If the string length is zero, return the dst parameter. */ 11144 if (p && *p == '\0') 11145 return dst; 11146 11147 if (optimize_insn_for_speed_p ()) 11148 { 11149 /* See if we can store by pieces into (dst + strlen(dst)). */ 11150 tree newdst, call; 11151 tree strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN]; 11152 tree strcpy_fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 11153 11154 if (!strlen_fn || !strcpy_fn) 11155 return NULL_TREE; 11156 11157 /* If we don't have a movstr we don't want to emit an strcpy 11158 call. We have to do that if the length of the source string 11159 isn't computable (in that case we can use memcpy probably 11160 later expanding to a sequence of mov instructions). If we 11161 have movstr instructions we can emit strcpy calls. */ 11162 if (!HAVE_movstr) 11163 { 11164 tree len = c_strlen (src, 1); 11165 if (! len || TREE_SIDE_EFFECTS (len)) 11166 return NULL_TREE; 11167 } 11168 11169 /* Stabilize the argument list. */ 11170 dst = builtin_save_expr (dst); 11171 11172 /* Create strlen (dst). */ 11173 newdst = build_call_expr_loc (loc, strlen_fn, 1, dst); 11174 /* Create (dst p+ strlen (dst)). */ 11175 11176 newdst = fold_build2_loc (loc, POINTER_PLUS_EXPR, 11177 TREE_TYPE (dst), dst, newdst); 11178 newdst = builtin_save_expr (newdst); 11179 11180 call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src); 11181 return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst); 11182 } 11183 return NULL_TREE; 11184 } 11185 } 11186 11187 /* Simplify a call to the strncat builtin. DST, SRC, and LEN are the 11188 arguments to the call. 11189 11190 Return NULL_TREE if no simplification was possible, otherwise return the 11191 simplified form of the call as a tree. 11192 11193 The simplified form may be a constant or other expression which 11194 computes the same value, but in a more efficient manner (including 11195 calls to other builtin functions). 11196 11197 The call may contain arguments which need to be evaluated, but 11198 which are not useful to determine the result of the call. In 11199 this case we return a chain of COMPOUND_EXPRs. The LHS of each 11200 COMPOUND_EXPR will be an argument which must be evaluated. 11201 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 11202 COMPOUND_EXPR in the chain will contain the tree for the simplified 11203 form of the builtin function call. */ 11204 11205 static tree 11206 fold_builtin_strncat (location_t loc, tree dst, tree src, tree len) 11207 { 11208 if (!validate_arg (dst, POINTER_TYPE) 11209 || !validate_arg (src, POINTER_TYPE) 11210 || !validate_arg (len, INTEGER_TYPE)) 11211 return NULL_TREE; 11212 else 11213 { 11214 const char *p = c_getstr (src); 11215 11216 /* If the requested length is zero, or the src parameter string 11217 length is zero, return the dst parameter. */ 11218 if (integer_zerop (len) || (p && *p == '\0')) 11219 return omit_two_operands_loc (loc, TREE_TYPE (dst), dst, src, len); 11220 11221 /* If the requested len is greater than or equal to the string 11222 length, call strcat. */ 11223 if (TREE_CODE (len) == INTEGER_CST && p 11224 && compare_tree_int (len, strlen (p)) >= 0) 11225 { 11226 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT]; 11227 11228 /* If the replacement _DECL isn't initialized, don't do the 11229 transformation. */ 11230 if (!fn) 11231 return NULL_TREE; 11232 11233 return build_call_expr_loc (loc, fn, 2, dst, src); 11234 } 11235 return NULL_TREE; 11236 } 11237 } 11238 11239 /* Simplify a call to the strspn builtin. S1 and S2 are the arguments 11240 to the call. 11241 11242 Return NULL_TREE if no simplification was possible, otherwise return the 11243 simplified form of the call as a tree. 11244 11245 The simplified form may be a constant or other expression which 11246 computes the same value, but in a more efficient manner (including 11247 calls to other builtin functions). 11248 11249 The call may contain arguments which need to be evaluated, but 11250 which are not useful to determine the result of the call. In 11251 this case we return a chain of COMPOUND_EXPRs. The LHS of each 11252 COMPOUND_EXPR will be an argument which must be evaluated. 11253 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 11254 COMPOUND_EXPR in the chain will contain the tree for the simplified 11255 form of the builtin function call. */ 11256 11257 static tree 11258 fold_builtin_strspn (location_t loc, tree s1, tree s2) 11259 { 11260 if (!validate_arg (s1, POINTER_TYPE) 11261 || !validate_arg (s2, POINTER_TYPE)) 11262 return NULL_TREE; 11263 else 11264 { 11265 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); 11266 11267 /* If both arguments are constants, evaluate at compile-time. */ 11268 if (p1 && p2) 11269 { 11270 const size_t r = strspn (p1, p2); 11271 return size_int (r); 11272 } 11273 11274 /* If either argument is "", return NULL_TREE. */ 11275 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')) 11276 /* Evaluate and ignore both arguments in case either one has 11277 side-effects. */ 11278 return omit_two_operands_loc (loc, size_type_node, size_zero_node, 11279 s1, s2); 11280 return NULL_TREE; 11281 } 11282 } 11283 11284 /* Simplify a call to the strcspn builtin. S1 and S2 are the arguments 11285 to the call. 11286 11287 Return NULL_TREE if no simplification was possible, otherwise return the 11288 simplified form of the call as a tree. 11289 11290 The simplified form may be a constant or other expression which 11291 computes the same value, but in a more efficient manner (including 11292 calls to other builtin functions). 11293 11294 The call may contain arguments which need to be evaluated, but 11295 which are not useful to determine the result of the call. In 11296 this case we return a chain of COMPOUND_EXPRs. The LHS of each 11297 COMPOUND_EXPR will be an argument which must be evaluated. 11298 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 11299 COMPOUND_EXPR in the chain will contain the tree for the simplified 11300 form of the builtin function call. */ 11301 11302 static tree 11303 fold_builtin_strcspn (location_t loc, tree s1, tree s2) 11304 { 11305 if (!validate_arg (s1, POINTER_TYPE) 11306 || !validate_arg (s2, POINTER_TYPE)) 11307 return NULL_TREE; 11308 else 11309 { 11310 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); 11311 11312 /* If both arguments are constants, evaluate at compile-time. */ 11313 if (p1 && p2) 11314 { 11315 const size_t r = strcspn (p1, p2); 11316 return size_int (r); 11317 } 11318 11319 /* If the first argument is "", return NULL_TREE. */ 11320 if (p1 && *p1 == '\0') 11321 { 11322 /* Evaluate and ignore argument s2 in case it has 11323 side-effects. */ 11324 return omit_one_operand_loc (loc, size_type_node, 11325 size_zero_node, s2); 11326 } 11327 11328 /* If the second argument is "", return __builtin_strlen(s1). */ 11329 if (p2 && *p2 == '\0') 11330 { 11331 tree fn = implicit_built_in_decls[BUILT_IN_STRLEN]; 11332 11333 /* If the replacement _DECL isn't initialized, don't do the 11334 transformation. */ 11335 if (!fn) 11336 return NULL_TREE; 11337 11338 return build_call_expr_loc (loc, fn, 1, s1); 11339 } 11340 return NULL_TREE; 11341 } 11342 } 11343 11344 /* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments 11345 to the call. IGNORE is true if the value returned 11346 by the builtin will be ignored. UNLOCKED is true is true if this 11347 actually a call to fputs_unlocked. If LEN in non-NULL, it represents 11348 the known length of the string. Return NULL_TREE if no simplification 11349 was possible. */ 11350 11351 tree 11352 fold_builtin_fputs (location_t loc, tree arg0, tree arg1, 11353 bool ignore, bool unlocked, tree len) 11354 { 11355 /* If we're using an unlocked function, assume the other unlocked 11356 functions exist explicitly. */ 11357 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED] 11358 : implicit_built_in_decls[BUILT_IN_FPUTC]; 11359 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED] 11360 : implicit_built_in_decls[BUILT_IN_FWRITE]; 11361 11362 /* If the return value is used, don't do the transformation. */ 11363 if (!ignore) 11364 return NULL_TREE; 11365 11366 /* Verify the arguments in the original call. */ 11367 if (!validate_arg (arg0, POINTER_TYPE) 11368 || !validate_arg (arg1, POINTER_TYPE)) 11369 return NULL_TREE; 11370 11371 if (! len) 11372 len = c_strlen (arg0, 0); 11373 11374 /* Get the length of the string passed to fputs. If the length 11375 can't be determined, punt. */ 11376 if (!len 11377 || TREE_CODE (len) != INTEGER_CST) 11378 return NULL_TREE; 11379 11380 switch (compare_tree_int (len, 1)) 11381 { 11382 case -1: /* length is 0, delete the call entirely . */ 11383 return omit_one_operand_loc (loc, integer_type_node, 11384 integer_zero_node, arg1);; 11385 11386 case 0: /* length is 1, call fputc. */ 11387 { 11388 const char *p = c_getstr (arg0); 11389 11390 if (p != NULL) 11391 { 11392 if (fn_fputc) 11393 return build_call_expr_loc (loc, fn_fputc, 2, 11394 build_int_cst (NULL_TREE, p[0]), arg1); 11395 else 11396 return NULL_TREE; 11397 } 11398 } 11399 /* FALLTHROUGH */ 11400 case 1: /* length is greater than 1, call fwrite. */ 11401 { 11402 /* If optimizing for size keep fputs. */ 11403 if (optimize_function_for_size_p (cfun)) 11404 return NULL_TREE; 11405 /* New argument list transforming fputs(string, stream) to 11406 fwrite(string, 1, len, stream). */ 11407 if (fn_fwrite) 11408 return build_call_expr_loc (loc, fn_fwrite, 4, arg0, 11409 size_one_node, len, arg1); 11410 else 11411 return NULL_TREE; 11412 } 11413 default: 11414 gcc_unreachable (); 11415 } 11416 return NULL_TREE; 11417 } 11418 11419 /* Fold the next_arg or va_start call EXP. Returns true if there was an error 11420 produced. False otherwise. This is done so that we don't output the error 11421 or warning twice or three times. */ 11422 11423 bool 11424 fold_builtin_next_arg (tree exp, bool va_start_p) 11425 { 11426 tree fntype = TREE_TYPE (current_function_decl); 11427 int nargs = call_expr_nargs (exp); 11428 tree arg; 11429 11430 if (TYPE_ARG_TYPES (fntype) == 0 11431 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) 11432 == void_type_node)) 11433 { 11434 error ("%<va_start%> used in function with fixed args"); 11435 return true; 11436 } 11437 11438 if (va_start_p) 11439 { 11440 if (va_start_p && (nargs != 2)) 11441 { 11442 error ("wrong number of arguments to function %<va_start%>"); 11443 return true; 11444 } 11445 arg = CALL_EXPR_ARG (exp, 1); 11446 } 11447 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0) 11448 when we checked the arguments and if needed issued a warning. */ 11449 else 11450 { 11451 if (nargs == 0) 11452 { 11453 /* Evidently an out of date version of <stdarg.h>; can't validate 11454 va_start's second argument, but can still work as intended. */ 11455 warning (0, "%<__builtin_next_arg%> called without an argument"); 11456 return true; 11457 } 11458 else if (nargs > 1) 11459 { 11460 error ("wrong number of arguments to function %<__builtin_next_arg%>"); 11461 return true; 11462 } 11463 arg = CALL_EXPR_ARG (exp, 0); 11464 } 11465 11466 if (TREE_CODE (arg) == SSA_NAME) 11467 arg = SSA_NAME_VAR (arg); 11468 11469 /* We destructively modify the call to be __builtin_va_start (ap, 0) 11470 or __builtin_next_arg (0) the first time we see it, after checking 11471 the arguments and if needed issuing a warning. */ 11472 if (!integer_zerop (arg)) 11473 { 11474 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl)); 11475 11476 /* Strip off all nops for the sake of the comparison. This 11477 is not quite the same as STRIP_NOPS. It does more. 11478 We must also strip off INDIRECT_EXPR for C++ reference 11479 parameters. */ 11480 while (CONVERT_EXPR_P (arg) 11481 || TREE_CODE (arg) == INDIRECT_REF) 11482 arg = TREE_OPERAND (arg, 0); 11483 if (arg != last_parm) 11484 { 11485 /* FIXME: Sometimes with the tree optimizers we can get the 11486 not the last argument even though the user used the last 11487 argument. We just warn and set the arg to be the last 11488 argument so that we will get wrong-code because of 11489 it. */ 11490 warning (0, "second parameter of %<va_start%> not last named argument"); 11491 } 11492 11493 /* Undefined by C99 7.15.1.4p4 (va_start): 11494 "If the parameter parmN is declared with the register storage 11495 class, with a function or array type, or with a type that is 11496 not compatible with the type that results after application of 11497 the default argument promotions, the behavior is undefined." 11498 */ 11499 else if (DECL_REGISTER (arg)) 11500 warning (0, "undefined behaviour when second parameter of " 11501 "%<va_start%> is declared with %<register%> storage"); 11502 11503 /* We want to verify the second parameter just once before the tree 11504 optimizers are run and then avoid keeping it in the tree, 11505 as otherwise we could warn even for correct code like: 11506 void foo (int i, ...) 11507 { va_list ap; i++; va_start (ap, i); va_end (ap); } */ 11508 if (va_start_p) 11509 CALL_EXPR_ARG (exp, 1) = integer_zero_node; 11510 else 11511 CALL_EXPR_ARG (exp, 0) = integer_zero_node; 11512 } 11513 return false; 11514 } 11515 11516 11517 /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG. 11518 ORIG may be null if this is a 2-argument call. We don't attempt to 11519 simplify calls with more than 3 arguments. 11520 11521 Return NULL_TREE if no simplification was possible, otherwise return the 11522 simplified form of the call as a tree. If IGNORED is true, it means that 11523 the caller does not use the returned value of the function. */ 11524 11525 static tree 11526 fold_builtin_sprintf (location_t loc, tree dest, tree fmt, 11527 tree orig, int ignored) 11528 { 11529 tree call, retval; 11530 const char *fmt_str = NULL; 11531 11532 /* Verify the required arguments in the original call. We deal with two 11533 types of sprintf() calls: 'sprintf (str, fmt)' and 11534 'sprintf (dest, "%s", orig)'. */ 11535 if (!validate_arg (dest, POINTER_TYPE) 11536 || !validate_arg (fmt, POINTER_TYPE)) 11537 return NULL_TREE; 11538 if (orig && !validate_arg (orig, POINTER_TYPE)) 11539 return NULL_TREE; 11540 11541 /* Check whether the format is a literal string constant. */ 11542 fmt_str = c_getstr (fmt); 11543 if (fmt_str == NULL) 11544 return NULL_TREE; 11545 11546 call = NULL_TREE; 11547 retval = NULL_TREE; 11548 11549 if (!init_target_chars ()) 11550 return NULL_TREE; 11551 11552 /* If the format doesn't contain % args or %%, use strcpy. */ 11553 if (strchr (fmt_str, target_percent) == NULL) 11554 { 11555 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 11556 11557 if (!fn) 11558 return NULL_TREE; 11559 11560 /* Don't optimize sprintf (buf, "abc", ptr++). */ 11561 if (orig) 11562 return NULL_TREE; 11563 11564 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when 11565 'format' is known to contain no % formats. */ 11566 call = build_call_expr_loc (loc, fn, 2, dest, fmt); 11567 if (!ignored) 11568 retval = build_int_cst (NULL_TREE, strlen (fmt_str)); 11569 } 11570 11571 /* If the format is "%s", use strcpy if the result isn't used. */ 11572 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0) 11573 { 11574 tree fn; 11575 fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 11576 11577 if (!fn) 11578 return NULL_TREE; 11579 11580 /* Don't crash on sprintf (str1, "%s"). */ 11581 if (!orig) 11582 return NULL_TREE; 11583 11584 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */ 11585 if (!ignored) 11586 { 11587 retval = c_strlen (orig, 1); 11588 if (!retval || TREE_CODE (retval) != INTEGER_CST) 11589 return NULL_TREE; 11590 } 11591 call = build_call_expr_loc (loc, fn, 2, dest, orig); 11592 } 11593 11594 if (call && retval) 11595 { 11596 retval = fold_convert_loc 11597 (loc, TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])), 11598 retval); 11599 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval); 11600 } 11601 else 11602 return call; 11603 } 11604 11605 /* Expand a call EXP to __builtin_object_size. */ 11606 11607 rtx 11608 expand_builtin_object_size (tree exp) 11609 { 11610 tree ost; 11611 int object_size_type; 11612 tree fndecl = get_callee_fndecl (exp); 11613 11614 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 11615 { 11616 error ("%Kfirst argument of %D must be a pointer, second integer constant", 11617 exp, fndecl); 11618 expand_builtin_trap (); 11619 return const0_rtx; 11620 } 11621 11622 ost = CALL_EXPR_ARG (exp, 1); 11623 STRIP_NOPS (ost); 11624 11625 if (TREE_CODE (ost) != INTEGER_CST 11626 || tree_int_cst_sgn (ost) < 0 11627 || compare_tree_int (ost, 3) > 0) 11628 { 11629 error ("%Klast argument of %D is not integer constant between 0 and 3", 11630 exp, fndecl); 11631 expand_builtin_trap (); 11632 return const0_rtx; 11633 } 11634 11635 object_size_type = tree_low_cst (ost, 0); 11636 11637 return object_size_type < 2 ? constm1_rtx : const0_rtx; 11638 } 11639 11640 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin. 11641 FCODE is the BUILT_IN_* to use. 11642 Return NULL_RTX if we failed; the caller should emit a normal call, 11643 otherwise try to get the result in TARGET, if convenient (and in 11644 mode MODE if that's convenient). */ 11645 11646 static rtx 11647 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode, 11648 enum built_in_function fcode) 11649 { 11650 tree dest, src, len, size; 11651 11652 if (!validate_arglist (exp, 11653 POINTER_TYPE, 11654 fcode == BUILT_IN_MEMSET_CHK 11655 ? INTEGER_TYPE : POINTER_TYPE, 11656 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 11657 return NULL_RTX; 11658 11659 dest = CALL_EXPR_ARG (exp, 0); 11660 src = CALL_EXPR_ARG (exp, 1); 11661 len = CALL_EXPR_ARG (exp, 2); 11662 size = CALL_EXPR_ARG (exp, 3); 11663 11664 if (! host_integerp (size, 1)) 11665 return NULL_RTX; 11666 11667 if (host_integerp (len, 1) || integer_all_onesp (size)) 11668 { 11669 tree fn; 11670 11671 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len)) 11672 { 11673 warning_at (tree_nonartificial_location (exp), 11674 0, "%Kcall to %D will always overflow destination buffer", 11675 exp, get_callee_fndecl (exp)); 11676 return NULL_RTX; 11677 } 11678 11679 fn = NULL_TREE; 11680 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume 11681 mem{cpy,pcpy,move,set} is available. */ 11682 switch (fcode) 11683 { 11684 case BUILT_IN_MEMCPY_CHK: 11685 fn = built_in_decls[BUILT_IN_MEMCPY]; 11686 break; 11687 case BUILT_IN_MEMPCPY_CHK: 11688 fn = built_in_decls[BUILT_IN_MEMPCPY]; 11689 break; 11690 case BUILT_IN_MEMMOVE_CHK: 11691 fn = built_in_decls[BUILT_IN_MEMMOVE]; 11692 break; 11693 case BUILT_IN_MEMSET_CHK: 11694 fn = built_in_decls[BUILT_IN_MEMSET]; 11695 break; 11696 default: 11697 break; 11698 } 11699 11700 if (! fn) 11701 return NULL_RTX; 11702 11703 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 3, dest, src, len); 11704 gcc_assert (TREE_CODE (fn) == CALL_EXPR); 11705 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 11706 return expand_expr (fn, target, mode, EXPAND_NORMAL); 11707 } 11708 else if (fcode == BUILT_IN_MEMSET_CHK) 11709 return NULL_RTX; 11710 else 11711 { 11712 unsigned int dest_align 11713 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 11714 11715 /* If DEST is not a pointer type, call the normal function. */ 11716 if (dest_align == 0) 11717 return NULL_RTX; 11718 11719 /* If SRC and DEST are the same (and not volatile), do nothing. */ 11720 if (operand_equal_p (src, dest, 0)) 11721 { 11722 tree expr; 11723 11724 if (fcode != BUILT_IN_MEMPCPY_CHK) 11725 { 11726 /* Evaluate and ignore LEN in case it has side-effects. */ 11727 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL); 11728 return expand_expr (dest, target, mode, EXPAND_NORMAL); 11729 } 11730 11731 expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len); 11732 return expand_expr (expr, target, mode, EXPAND_NORMAL); 11733 } 11734 11735 /* __memmove_chk special case. */ 11736 if (fcode == BUILT_IN_MEMMOVE_CHK) 11737 { 11738 unsigned int src_align 11739 = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 11740 11741 if (src_align == 0) 11742 return NULL_RTX; 11743 11744 /* If src is categorized for a readonly section we can use 11745 normal __memcpy_chk. */ 11746 if (readonly_data_expr (src)) 11747 { 11748 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK]; 11749 if (!fn) 11750 return NULL_RTX; 11751 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 4, 11752 dest, src, len, size); 11753 gcc_assert (TREE_CODE (fn) == CALL_EXPR); 11754 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 11755 return expand_expr (fn, target, mode, EXPAND_NORMAL); 11756 } 11757 } 11758 return NULL_RTX; 11759 } 11760 } 11761 11762 /* Emit warning if a buffer overflow is detected at compile time. */ 11763 11764 static void 11765 maybe_emit_chk_warning (tree exp, enum built_in_function fcode) 11766 { 11767 int is_strlen = 0; 11768 tree len, size; 11769 location_t loc = tree_nonartificial_location (exp); 11770 11771 switch (fcode) 11772 { 11773 case BUILT_IN_STRCPY_CHK: 11774 case BUILT_IN_STPCPY_CHK: 11775 /* For __strcat_chk the warning will be emitted only if overflowing 11776 by at least strlen (dest) + 1 bytes. */ 11777 case BUILT_IN_STRCAT_CHK: 11778 len = CALL_EXPR_ARG (exp, 1); 11779 size = CALL_EXPR_ARG (exp, 2); 11780 is_strlen = 1; 11781 break; 11782 case BUILT_IN_STRNCAT_CHK: 11783 case BUILT_IN_STRNCPY_CHK: 11784 len = CALL_EXPR_ARG (exp, 2); 11785 size = CALL_EXPR_ARG (exp, 3); 11786 break; 11787 case BUILT_IN_SNPRINTF_CHK: 11788 case BUILT_IN_VSNPRINTF_CHK: 11789 len = CALL_EXPR_ARG (exp, 1); 11790 size = CALL_EXPR_ARG (exp, 3); 11791 break; 11792 default: 11793 gcc_unreachable (); 11794 } 11795 11796 if (!len || !size) 11797 return; 11798 11799 if (! host_integerp (size, 1) || integer_all_onesp (size)) 11800 return; 11801 11802 if (is_strlen) 11803 { 11804 len = c_strlen (len, 1); 11805 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size)) 11806 return; 11807 } 11808 else if (fcode == BUILT_IN_STRNCAT_CHK) 11809 { 11810 tree src = CALL_EXPR_ARG (exp, 1); 11811 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size)) 11812 return; 11813 src = c_strlen (src, 1); 11814 if (! src || ! host_integerp (src, 1)) 11815 { 11816 warning_at (loc, 0, "%Kcall to %D might overflow destination buffer", 11817 exp, get_callee_fndecl (exp)); 11818 return; 11819 } 11820 else if (tree_int_cst_lt (src, size)) 11821 return; 11822 } 11823 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len)) 11824 return; 11825 11826 warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer", 11827 exp, get_callee_fndecl (exp)); 11828 } 11829 11830 /* Emit warning if a buffer overflow is detected at compile time 11831 in __sprintf_chk/__vsprintf_chk calls. */ 11832 11833 static void 11834 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode) 11835 { 11836 tree size, len, fmt; 11837 const char *fmt_str; 11838 int nargs = call_expr_nargs (exp); 11839 11840 /* Verify the required arguments in the original call. */ 11841 11842 if (nargs < 4) 11843 return; 11844 size = CALL_EXPR_ARG (exp, 2); 11845 fmt = CALL_EXPR_ARG (exp, 3); 11846 11847 if (! host_integerp (size, 1) || integer_all_onesp (size)) 11848 return; 11849 11850 /* Check whether the format is a literal string constant. */ 11851 fmt_str = c_getstr (fmt); 11852 if (fmt_str == NULL) 11853 return; 11854 11855 if (!init_target_chars ()) 11856 return; 11857 11858 /* If the format doesn't contain % args or %%, we know its size. */ 11859 if (strchr (fmt_str, target_percent) == 0) 11860 len = build_int_cstu (size_type_node, strlen (fmt_str)); 11861 /* If the format is "%s" and first ... argument is a string literal, 11862 we know it too. */ 11863 else if (fcode == BUILT_IN_SPRINTF_CHK 11864 && strcmp (fmt_str, target_percent_s) == 0) 11865 { 11866 tree arg; 11867 11868 if (nargs < 5) 11869 return; 11870 arg = CALL_EXPR_ARG (exp, 4); 11871 if (! POINTER_TYPE_P (TREE_TYPE (arg))) 11872 return; 11873 11874 len = c_strlen (arg, 1); 11875 if (!len || ! host_integerp (len, 1)) 11876 return; 11877 } 11878 else 11879 return; 11880 11881 if (! tree_int_cst_lt (len, size)) 11882 warning_at (tree_nonartificial_location (exp), 11883 0, "%Kcall to %D will always overflow destination buffer", 11884 exp, get_callee_fndecl (exp)); 11885 } 11886 11887 /* Emit warning if a free is called with address of a variable. */ 11888 11889 static void 11890 maybe_emit_free_warning (tree exp) 11891 { 11892 tree arg = CALL_EXPR_ARG (exp, 0); 11893 11894 STRIP_NOPS (arg); 11895 if (TREE_CODE (arg) != ADDR_EXPR) 11896 return; 11897 11898 arg = get_base_address (TREE_OPERAND (arg, 0)); 11899 if (arg == NULL || INDIRECT_REF_P (arg)) 11900 return; 11901 11902 if (SSA_VAR_P (arg)) 11903 warning_at (tree_nonartificial_location (exp), 11904 0, "%Kattempt to free a non-heap object %qD", exp, arg); 11905 else 11906 warning_at (tree_nonartificial_location (exp), 11907 0, "%Kattempt to free a non-heap object", exp); 11908 } 11909 11910 /* Fold a call to __builtin_object_size with arguments PTR and OST, 11911 if possible. */ 11912 11913 tree 11914 fold_builtin_object_size (tree ptr, tree ost) 11915 { 11916 tree ret = NULL_TREE; 11917 int object_size_type; 11918 11919 if (!validate_arg (ptr, POINTER_TYPE) 11920 || !validate_arg (ost, INTEGER_TYPE)) 11921 return NULL_TREE; 11922 11923 STRIP_NOPS (ost); 11924 11925 if (TREE_CODE (ost) != INTEGER_CST 11926 || tree_int_cst_sgn (ost) < 0 11927 || compare_tree_int (ost, 3) > 0) 11928 return NULL_TREE; 11929 11930 object_size_type = tree_low_cst (ost, 0); 11931 11932 /* __builtin_object_size doesn't evaluate side-effects in its arguments; 11933 if there are any side-effects, it returns (size_t) -1 for types 0 and 1 11934 and (size_t) 0 for types 2 and 3. */ 11935 if (TREE_SIDE_EFFECTS (ptr)) 11936 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0); 11937 11938 if (TREE_CODE (ptr) == ADDR_EXPR) 11939 ret = build_int_cstu (size_type_node, 11940 compute_builtin_object_size (ptr, object_size_type)); 11941 11942 else if (TREE_CODE (ptr) == SSA_NAME) 11943 { 11944 unsigned HOST_WIDE_INT bytes; 11945 11946 /* If object size is not known yet, delay folding until 11947 later. Maybe subsequent passes will help determining 11948 it. */ 11949 bytes = compute_builtin_object_size (ptr, object_size_type); 11950 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 11951 ? -1 : 0)) 11952 ret = build_int_cstu (size_type_node, bytes); 11953 } 11954 11955 if (ret) 11956 { 11957 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret); 11958 HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret); 11959 if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret))) 11960 ret = NULL_TREE; 11961 } 11962 11963 return ret; 11964 } 11965 11966 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin. 11967 DEST, SRC, LEN, and SIZE are the arguments to the call. 11968 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_* 11969 code of the builtin. If MAXLEN is not NULL, it is maximum length 11970 passed as third argument. */ 11971 11972 tree 11973 fold_builtin_memory_chk (location_t loc, tree fndecl, 11974 tree dest, tree src, tree len, tree size, 11975 tree maxlen, bool ignore, 11976 enum built_in_function fcode) 11977 { 11978 tree fn; 11979 11980 if (!validate_arg (dest, POINTER_TYPE) 11981 || !validate_arg (src, 11982 (fcode == BUILT_IN_MEMSET_CHK 11983 ? INTEGER_TYPE : POINTER_TYPE)) 11984 || !validate_arg (len, INTEGER_TYPE) 11985 || !validate_arg (size, INTEGER_TYPE)) 11986 return NULL_TREE; 11987 11988 /* If SRC and DEST are the same (and not volatile), return DEST 11989 (resp. DEST+LEN for __mempcpy_chk). */ 11990 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0)) 11991 { 11992 if (fcode != BUILT_IN_MEMPCPY_CHK) 11993 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), 11994 dest, len); 11995 else 11996 { 11997 tree temp = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest), 11998 dest, len); 11999 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp); 12000 } 12001 } 12002 12003 if (! host_integerp (size, 1)) 12004 return NULL_TREE; 12005 12006 if (! integer_all_onesp (size)) 12007 { 12008 if (! host_integerp (len, 1)) 12009 { 12010 /* If LEN is not constant, try MAXLEN too. 12011 For MAXLEN only allow optimizing into non-_ocs function 12012 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 12013 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 12014 { 12015 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore) 12016 { 12017 /* (void) __mempcpy_chk () can be optimized into 12018 (void) __memcpy_chk (). */ 12019 fn = built_in_decls[BUILT_IN_MEMCPY_CHK]; 12020 if (!fn) 12021 return NULL_TREE; 12022 12023 return build_call_expr_loc (loc, fn, 4, dest, src, len, size); 12024 } 12025 return NULL_TREE; 12026 } 12027 } 12028 else 12029 maxlen = len; 12030 12031 if (tree_int_cst_lt (size, maxlen)) 12032 return NULL_TREE; 12033 } 12034 12035 fn = NULL_TREE; 12036 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume 12037 mem{cpy,pcpy,move,set} is available. */ 12038 switch (fcode) 12039 { 12040 case BUILT_IN_MEMCPY_CHK: 12041 fn = built_in_decls[BUILT_IN_MEMCPY]; 12042 break; 12043 case BUILT_IN_MEMPCPY_CHK: 12044 fn = built_in_decls[BUILT_IN_MEMPCPY]; 12045 break; 12046 case BUILT_IN_MEMMOVE_CHK: 12047 fn = built_in_decls[BUILT_IN_MEMMOVE]; 12048 break; 12049 case BUILT_IN_MEMSET_CHK: 12050 fn = built_in_decls[BUILT_IN_MEMSET]; 12051 break; 12052 default: 12053 break; 12054 } 12055 12056 if (!fn) 12057 return NULL_TREE; 12058 12059 return build_call_expr_loc (loc, fn, 3, dest, src, len); 12060 } 12061 12062 /* Fold a call to the __st[rp]cpy_chk builtin. 12063 DEST, SRC, and SIZE are the arguments to the call. 12064 IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_* 12065 code of the builtin. If MAXLEN is not NULL, it is maximum length of 12066 strings passed as second argument. */ 12067 12068 tree 12069 fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest, 12070 tree src, tree size, 12071 tree maxlen, bool ignore, 12072 enum built_in_function fcode) 12073 { 12074 tree len, fn; 12075 12076 if (!validate_arg (dest, POINTER_TYPE) 12077 || !validate_arg (src, POINTER_TYPE) 12078 || !validate_arg (size, INTEGER_TYPE)) 12079 return NULL_TREE; 12080 12081 /* If SRC and DEST are the same (and not volatile), return DEST. */ 12082 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0)) 12083 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest); 12084 12085 if (! host_integerp (size, 1)) 12086 return NULL_TREE; 12087 12088 if (! integer_all_onesp (size)) 12089 { 12090 len = c_strlen (src, 1); 12091 if (! len || ! host_integerp (len, 1)) 12092 { 12093 /* If LEN is not constant, try MAXLEN too. 12094 For MAXLEN only allow optimizing into non-_ocs function 12095 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 12096 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 12097 { 12098 if (fcode == BUILT_IN_STPCPY_CHK) 12099 { 12100 if (! ignore) 12101 return NULL_TREE; 12102 12103 /* If return value of __stpcpy_chk is ignored, 12104 optimize into __strcpy_chk. */ 12105 fn = built_in_decls[BUILT_IN_STRCPY_CHK]; 12106 if (!fn) 12107 return NULL_TREE; 12108 12109 return build_call_expr_loc (loc, fn, 3, dest, src, size); 12110 } 12111 12112 if (! len || TREE_SIDE_EFFECTS (len)) 12113 return NULL_TREE; 12114 12115 /* If c_strlen returned something, but not a constant, 12116 transform __strcpy_chk into __memcpy_chk. */ 12117 fn = built_in_decls[BUILT_IN_MEMCPY_CHK]; 12118 if (!fn) 12119 return NULL_TREE; 12120 12121 len = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1)); 12122 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), 12123 build_call_expr_loc (loc, fn, 4, 12124 dest, src, len, size)); 12125 } 12126 } 12127 else 12128 maxlen = len; 12129 12130 if (! tree_int_cst_lt (maxlen, size)) 12131 return NULL_TREE; 12132 } 12133 12134 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */ 12135 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK 12136 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY]; 12137 if (!fn) 12138 return NULL_TREE; 12139 12140 return build_call_expr_loc (loc, fn, 2, dest, src); 12141 } 12142 12143 /* Fold a call to the __strncpy_chk builtin. DEST, SRC, LEN, and SIZE 12144 are the arguments to the call. If MAXLEN is not NULL, it is maximum 12145 length passed as third argument. */ 12146 12147 tree 12148 fold_builtin_strncpy_chk (location_t loc, tree dest, tree src, 12149 tree len, tree size, tree maxlen) 12150 { 12151 tree fn; 12152 12153 if (!validate_arg (dest, POINTER_TYPE) 12154 || !validate_arg (src, POINTER_TYPE) 12155 || !validate_arg (len, INTEGER_TYPE) 12156 || !validate_arg (size, INTEGER_TYPE)) 12157 return NULL_TREE; 12158 12159 if (! host_integerp (size, 1)) 12160 return NULL_TREE; 12161 12162 if (! integer_all_onesp (size)) 12163 { 12164 if (! host_integerp (len, 1)) 12165 { 12166 /* If LEN is not constant, try MAXLEN too. 12167 For MAXLEN only allow optimizing into non-_ocs function 12168 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 12169 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 12170 return NULL_TREE; 12171 } 12172 else 12173 maxlen = len; 12174 12175 if (tree_int_cst_lt (size, maxlen)) 12176 return NULL_TREE; 12177 } 12178 12179 /* If __builtin_strncpy_chk is used, assume strncpy is available. */ 12180 fn = built_in_decls[BUILT_IN_STRNCPY]; 12181 if (!fn) 12182 return NULL_TREE; 12183 12184 return build_call_expr_loc (loc, fn, 3, dest, src, len); 12185 } 12186 12187 /* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE 12188 are the arguments to the call. */ 12189 12190 static tree 12191 fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest, 12192 tree src, tree size) 12193 { 12194 tree fn; 12195 const char *p; 12196 12197 if (!validate_arg (dest, POINTER_TYPE) 12198 || !validate_arg (src, POINTER_TYPE) 12199 || !validate_arg (size, INTEGER_TYPE)) 12200 return NULL_TREE; 12201 12202 p = c_getstr (src); 12203 /* If the SRC parameter is "", return DEST. */ 12204 if (p && *p == '\0') 12205 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src); 12206 12207 if (! host_integerp (size, 1) || ! integer_all_onesp (size)) 12208 return NULL_TREE; 12209 12210 /* If __builtin_strcat_chk is used, assume strcat is available. */ 12211 fn = built_in_decls[BUILT_IN_STRCAT]; 12212 if (!fn) 12213 return NULL_TREE; 12214 12215 return build_call_expr_loc (loc, fn, 2, dest, src); 12216 } 12217 12218 /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC, 12219 LEN, and SIZE. */ 12220 12221 static tree 12222 fold_builtin_strncat_chk (location_t loc, tree fndecl, 12223 tree dest, tree src, tree len, tree size) 12224 { 12225 tree fn; 12226 const char *p; 12227 12228 if (!validate_arg (dest, POINTER_TYPE) 12229 || !validate_arg (src, POINTER_TYPE) 12230 || !validate_arg (size, INTEGER_TYPE) 12231 || !validate_arg (size, INTEGER_TYPE)) 12232 return NULL_TREE; 12233 12234 p = c_getstr (src); 12235 /* If the SRC parameter is "" or if LEN is 0, return DEST. */ 12236 if (p && *p == '\0') 12237 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len); 12238 else if (integer_zerop (len)) 12239 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src); 12240 12241 if (! host_integerp (size, 1)) 12242 return NULL_TREE; 12243 12244 if (! integer_all_onesp (size)) 12245 { 12246 tree src_len = c_strlen (src, 1); 12247 if (src_len 12248 && host_integerp (src_len, 1) 12249 && host_integerp (len, 1) 12250 && ! tree_int_cst_lt (len, src_len)) 12251 { 12252 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */ 12253 fn = built_in_decls[BUILT_IN_STRCAT_CHK]; 12254 if (!fn) 12255 return NULL_TREE; 12256 12257 return build_call_expr_loc (loc, fn, 3, dest, src, size); 12258 } 12259 return NULL_TREE; 12260 } 12261 12262 /* If __builtin_strncat_chk is used, assume strncat is available. */ 12263 fn = built_in_decls[BUILT_IN_STRNCAT]; 12264 if (!fn) 12265 return NULL_TREE; 12266 12267 return build_call_expr_loc (loc, fn, 3, dest, src, len); 12268 } 12269 12270 /* Fold a call EXP to __{,v}sprintf_chk. Return NULL_TREE if 12271 a normal call should be emitted rather than expanding the function 12272 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */ 12273 12274 static tree 12275 fold_builtin_sprintf_chk (location_t loc, tree exp, 12276 enum built_in_function fcode) 12277 { 12278 tree dest, size, len, fn, fmt, flag; 12279 const char *fmt_str; 12280 int nargs = call_expr_nargs (exp); 12281 12282 /* Verify the required arguments in the original call. */ 12283 if (nargs < 4) 12284 return NULL_TREE; 12285 dest = CALL_EXPR_ARG (exp, 0); 12286 if (!validate_arg (dest, POINTER_TYPE)) 12287 return NULL_TREE; 12288 flag = CALL_EXPR_ARG (exp, 1); 12289 if (!validate_arg (flag, INTEGER_TYPE)) 12290 return NULL_TREE; 12291 size = CALL_EXPR_ARG (exp, 2); 12292 if (!validate_arg (size, INTEGER_TYPE)) 12293 return NULL_TREE; 12294 fmt = CALL_EXPR_ARG (exp, 3); 12295 if (!validate_arg (fmt, POINTER_TYPE)) 12296 return NULL_TREE; 12297 12298 if (! host_integerp (size, 1)) 12299 return NULL_TREE; 12300 12301 len = NULL_TREE; 12302 12303 if (!init_target_chars ()) 12304 return NULL_TREE; 12305 12306 /* Check whether the format is a literal string constant. */ 12307 fmt_str = c_getstr (fmt); 12308 if (fmt_str != NULL) 12309 { 12310 /* If the format doesn't contain % args or %%, we know the size. */ 12311 if (strchr (fmt_str, target_percent) == 0) 12312 { 12313 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4) 12314 len = build_int_cstu (size_type_node, strlen (fmt_str)); 12315 } 12316 /* If the format is "%s" and first ... argument is a string literal, 12317 we know the size too. */ 12318 else if (fcode == BUILT_IN_SPRINTF_CHK 12319 && strcmp (fmt_str, target_percent_s) == 0) 12320 { 12321 tree arg; 12322 12323 if (nargs == 5) 12324 { 12325 arg = CALL_EXPR_ARG (exp, 4); 12326 if (validate_arg (arg, POINTER_TYPE)) 12327 { 12328 len = c_strlen (arg, 1); 12329 if (! len || ! host_integerp (len, 1)) 12330 len = NULL_TREE; 12331 } 12332 } 12333 } 12334 } 12335 12336 if (! integer_all_onesp (size)) 12337 { 12338 if (! len || ! tree_int_cst_lt (len, size)) 12339 return NULL_TREE; 12340 } 12341 12342 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0 12343 or if format doesn't contain % chars or is "%s". */ 12344 if (! integer_zerop (flag)) 12345 { 12346 if (fmt_str == NULL) 12347 return NULL_TREE; 12348 if (strchr (fmt_str, target_percent) != NULL 12349 && strcmp (fmt_str, target_percent_s)) 12350 return NULL_TREE; 12351 } 12352 12353 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */ 12354 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK 12355 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF]; 12356 if (!fn) 12357 return NULL_TREE; 12358 12359 return rewrite_call_expr (loc, exp, 4, fn, 2, dest, fmt); 12360 } 12361 12362 /* Fold a call EXP to {,v}snprintf. Return NULL_TREE if 12363 a normal call should be emitted rather than expanding the function 12364 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or 12365 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length 12366 passed as second argument. */ 12367 12368 tree 12369 fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen, 12370 enum built_in_function fcode) 12371 { 12372 tree dest, size, len, fn, fmt, flag; 12373 const char *fmt_str; 12374 12375 /* Verify the required arguments in the original call. */ 12376 if (call_expr_nargs (exp) < 5) 12377 return NULL_TREE; 12378 dest = CALL_EXPR_ARG (exp, 0); 12379 if (!validate_arg (dest, POINTER_TYPE)) 12380 return NULL_TREE; 12381 len = CALL_EXPR_ARG (exp, 1); 12382 if (!validate_arg (len, INTEGER_TYPE)) 12383 return NULL_TREE; 12384 flag = CALL_EXPR_ARG (exp, 2); 12385 if (!validate_arg (flag, INTEGER_TYPE)) 12386 return NULL_TREE; 12387 size = CALL_EXPR_ARG (exp, 3); 12388 if (!validate_arg (size, INTEGER_TYPE)) 12389 return NULL_TREE; 12390 fmt = CALL_EXPR_ARG (exp, 4); 12391 if (!validate_arg (fmt, POINTER_TYPE)) 12392 return NULL_TREE; 12393 12394 if (! host_integerp (size, 1)) 12395 return NULL_TREE; 12396 12397 if (! integer_all_onesp (size)) 12398 { 12399 if (! host_integerp (len, 1)) 12400 { 12401 /* If LEN is not constant, try MAXLEN too. 12402 For MAXLEN only allow optimizing into non-_ocs function 12403 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 12404 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 12405 return NULL_TREE; 12406 } 12407 else 12408 maxlen = len; 12409 12410 if (tree_int_cst_lt (size, maxlen)) 12411 return NULL_TREE; 12412 } 12413 12414 if (!init_target_chars ()) 12415 return NULL_TREE; 12416 12417 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0 12418 or if format doesn't contain % chars or is "%s". */ 12419 if (! integer_zerop (flag)) 12420 { 12421 fmt_str = c_getstr (fmt); 12422 if (fmt_str == NULL) 12423 return NULL_TREE; 12424 if (strchr (fmt_str, target_percent) != NULL 12425 && strcmp (fmt_str, target_percent_s)) 12426 return NULL_TREE; 12427 } 12428 12429 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is 12430 available. */ 12431 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK 12432 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF]; 12433 if (!fn) 12434 return NULL_TREE; 12435 12436 return rewrite_call_expr (loc, exp, 5, fn, 3, dest, len, fmt); 12437 } 12438 12439 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins. 12440 FMT and ARG are the arguments to the call; we don't fold cases with 12441 more than 2 arguments, and ARG may be null if this is a 1-argument case. 12442 12443 Return NULL_TREE if no simplification was possible, otherwise return the 12444 simplified form of the call as a tree. FCODE is the BUILT_IN_* 12445 code of the function to be simplified. */ 12446 12447 static tree 12448 fold_builtin_printf (location_t loc, tree fndecl, tree fmt, 12449 tree arg, bool ignore, 12450 enum built_in_function fcode) 12451 { 12452 tree fn_putchar, fn_puts, newarg, call = NULL_TREE; 12453 const char *fmt_str = NULL; 12454 12455 /* If the return value is used, don't do the transformation. */ 12456 if (! ignore) 12457 return NULL_TREE; 12458 12459 /* Verify the required arguments in the original call. */ 12460 if (!validate_arg (fmt, POINTER_TYPE)) 12461 return NULL_TREE; 12462 12463 /* Check whether the format is a literal string constant. */ 12464 fmt_str = c_getstr (fmt); 12465 if (fmt_str == NULL) 12466 return NULL_TREE; 12467 12468 if (fcode == BUILT_IN_PRINTF_UNLOCKED) 12469 { 12470 /* If we're using an unlocked function, assume the other 12471 unlocked functions exist explicitly. */ 12472 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]; 12473 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED]; 12474 } 12475 else 12476 { 12477 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR]; 12478 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS]; 12479 } 12480 12481 if (!init_target_chars ()) 12482 return NULL_TREE; 12483 12484 if (strcmp (fmt_str, target_percent_s) == 0 12485 || strchr (fmt_str, target_percent) == NULL) 12486 { 12487 const char *str; 12488 12489 if (strcmp (fmt_str, target_percent_s) == 0) 12490 { 12491 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK) 12492 return NULL_TREE; 12493 12494 if (!arg || !validate_arg (arg, POINTER_TYPE)) 12495 return NULL_TREE; 12496 12497 str = c_getstr (arg); 12498 if (str == NULL) 12499 return NULL_TREE; 12500 } 12501 else 12502 { 12503 /* The format specifier doesn't contain any '%' characters. */ 12504 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK 12505 && arg) 12506 return NULL_TREE; 12507 str = fmt_str; 12508 } 12509 12510 /* If the string was "", printf does nothing. */ 12511 if (str[0] == '\0') 12512 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0); 12513 12514 /* If the string has length of 1, call putchar. */ 12515 if (str[1] == '\0') 12516 { 12517 /* Given printf("c"), (where c is any one character,) 12518 convert "c"[0] to an int and pass that to the replacement 12519 function. */ 12520 newarg = build_int_cst (NULL_TREE, str[0]); 12521 if (fn_putchar) 12522 call = build_call_expr_loc (loc, fn_putchar, 1, newarg); 12523 } 12524 else 12525 { 12526 /* If the string was "string\n", call puts("string"). */ 12527 size_t len = strlen (str); 12528 if ((unsigned char)str[len - 1] == target_newline 12529 && (size_t) (int) len == len 12530 && (int) len > 0) 12531 { 12532 char *newstr; 12533 tree offset_node, string_cst; 12534 12535 /* Create a NUL-terminated string that's one char shorter 12536 than the original, stripping off the trailing '\n'. */ 12537 newarg = build_string_literal (len, str); 12538 string_cst = string_constant (newarg, &offset_node); 12539 #ifdef ENABLE_CHECKING 12540 gcc_assert (string_cst 12541 && (TREE_STRING_LENGTH (string_cst) 12542 == (int) len) 12543 && integer_zerop (offset_node) 12544 && (unsigned char) 12545 TREE_STRING_POINTER (string_cst)[len - 1] 12546 == target_newline); 12547 #endif 12548 /* build_string_literal creates a new STRING_CST, 12549 modify it in place to avoid double copying. */ 12550 newstr = CONST_CAST (char *, TREE_STRING_POINTER (string_cst)); 12551 newstr[len - 1] = '\0'; 12552 if (fn_puts) 12553 call = build_call_expr_loc (loc, fn_puts, 1, newarg); 12554 } 12555 else 12556 /* We'd like to arrange to call fputs(string,stdout) here, 12557 but we need stdout and don't have a way to get it yet. */ 12558 return NULL_TREE; 12559 } 12560 } 12561 12562 /* The other optimizations can be done only on the non-va_list variants. */ 12563 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK) 12564 return NULL_TREE; 12565 12566 /* If the format specifier was "%s\n", call __builtin_puts(arg). */ 12567 else if (strcmp (fmt_str, target_percent_s_newline) == 0) 12568 { 12569 if (!arg || !validate_arg (arg, POINTER_TYPE)) 12570 return NULL_TREE; 12571 if (fn_puts) 12572 call = build_call_expr_loc (loc, fn_puts, 1, arg); 12573 } 12574 12575 /* If the format specifier was "%c", call __builtin_putchar(arg). */ 12576 else if (strcmp (fmt_str, target_percent_c) == 0) 12577 { 12578 if (!arg || !validate_arg (arg, INTEGER_TYPE)) 12579 return NULL_TREE; 12580 if (fn_putchar) 12581 call = build_call_expr_loc (loc, fn_putchar, 1, arg); 12582 } 12583 12584 if (!call) 12585 return NULL_TREE; 12586 12587 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call); 12588 } 12589 12590 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins. 12591 FP, FMT, and ARG are the arguments to the call. We don't fold calls with 12592 more than 3 arguments, and ARG may be null in the 2-argument case. 12593 12594 Return NULL_TREE if no simplification was possible, otherwise return the 12595 simplified form of the call as a tree. FCODE is the BUILT_IN_* 12596 code of the function to be simplified. */ 12597 12598 static tree 12599 fold_builtin_fprintf (location_t loc, tree fndecl, tree fp, 12600 tree fmt, tree arg, bool ignore, 12601 enum built_in_function fcode) 12602 { 12603 tree fn_fputc, fn_fputs, call = NULL_TREE; 12604 const char *fmt_str = NULL; 12605 12606 /* If the return value is used, don't do the transformation. */ 12607 if (! ignore) 12608 return NULL_TREE; 12609 12610 /* Verify the required arguments in the original call. */ 12611 if (!validate_arg (fp, POINTER_TYPE)) 12612 return NULL_TREE; 12613 if (!validate_arg (fmt, POINTER_TYPE)) 12614 return NULL_TREE; 12615 12616 /* Check whether the format is a literal string constant. */ 12617 fmt_str = c_getstr (fmt); 12618 if (fmt_str == NULL) 12619 return NULL_TREE; 12620 12621 if (fcode == BUILT_IN_FPRINTF_UNLOCKED) 12622 { 12623 /* If we're using an unlocked function, assume the other 12624 unlocked functions exist explicitly. */ 12625 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED]; 12626 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED]; 12627 } 12628 else 12629 { 12630 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC]; 12631 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS]; 12632 } 12633 12634 if (!init_target_chars ()) 12635 return NULL_TREE; 12636 12637 /* If the format doesn't contain % args or %%, use strcpy. */ 12638 if (strchr (fmt_str, target_percent) == NULL) 12639 { 12640 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK 12641 && arg) 12642 return NULL_TREE; 12643 12644 /* If the format specifier was "", fprintf does nothing. */ 12645 if (fmt_str[0] == '\0') 12646 { 12647 /* If FP has side-effects, just wait until gimplification is 12648 done. */ 12649 if (TREE_SIDE_EFFECTS (fp)) 12650 return NULL_TREE; 12651 12652 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0); 12653 } 12654 12655 /* When "string" doesn't contain %, replace all cases of 12656 fprintf (fp, string) with fputs (string, fp). The fputs 12657 builtin will take care of special cases like length == 1. */ 12658 if (fn_fputs) 12659 call = build_call_expr_loc (loc, fn_fputs, 2, fmt, fp); 12660 } 12661 12662 /* The other optimizations can be done only on the non-va_list variants. */ 12663 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK) 12664 return NULL_TREE; 12665 12666 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */ 12667 else if (strcmp (fmt_str, target_percent_s) == 0) 12668 { 12669 if (!arg || !validate_arg (arg, POINTER_TYPE)) 12670 return NULL_TREE; 12671 if (fn_fputs) 12672 call = build_call_expr_loc (loc, fn_fputs, 2, arg, fp); 12673 } 12674 12675 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */ 12676 else if (strcmp (fmt_str, target_percent_c) == 0) 12677 { 12678 if (!arg || !validate_arg (arg, INTEGER_TYPE)) 12679 return NULL_TREE; 12680 if (fn_fputc) 12681 call = build_call_expr_loc (loc, fn_fputc, 2, arg, fp); 12682 } 12683 12684 if (!call) 12685 return NULL_TREE; 12686 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call); 12687 } 12688 12689 /* Initialize format string characters in the target charset. */ 12690 12691 static bool 12692 init_target_chars (void) 12693 { 12694 static bool init; 12695 if (!init) 12696 { 12697 target_newline = lang_hooks.to_target_charset ('\n'); 12698 target_percent = lang_hooks.to_target_charset ('%'); 12699 target_c = lang_hooks.to_target_charset ('c'); 12700 target_s = lang_hooks.to_target_charset ('s'); 12701 if (target_newline == 0 || target_percent == 0 || target_c == 0 12702 || target_s == 0) 12703 return false; 12704 12705 target_percent_c[0] = target_percent; 12706 target_percent_c[1] = target_c; 12707 target_percent_c[2] = '\0'; 12708 12709 target_percent_s[0] = target_percent; 12710 target_percent_s[1] = target_s; 12711 target_percent_s[2] = '\0'; 12712 12713 target_percent_s_newline[0] = target_percent; 12714 target_percent_s_newline[1] = target_s; 12715 target_percent_s_newline[2] = target_newline; 12716 target_percent_s_newline[3] = '\0'; 12717 12718 init = true; 12719 } 12720 return true; 12721 } 12722 12723 /* Helper function for do_mpfr_arg*(). Ensure M is a normal number 12724 and no overflow/underflow occurred. INEXACT is true if M was not 12725 exactly calculated. TYPE is the tree type for the result. This 12726 function assumes that you cleared the MPFR flags and then 12727 calculated M to see if anything subsequently set a flag prior to 12728 entering this function. Return NULL_TREE if any checks fail. */ 12729 12730 static tree 12731 do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact) 12732 { 12733 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no 12734 overflow/underflow occurred. If -frounding-math, proceed iff the 12735 result of calling FUNC was exact. */ 12736 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p () 12737 && (!flag_rounding_math || !inexact)) 12738 { 12739 REAL_VALUE_TYPE rr; 12740 12741 real_from_mpfr (&rr, m, type, GMP_RNDN); 12742 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value, 12743 check for overflow/underflow. If the REAL_VALUE_TYPE is zero 12744 but the mpft_t is not, then we underflowed in the 12745 conversion. */ 12746 if (real_isfinite (&rr) 12747 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0)) 12748 { 12749 REAL_VALUE_TYPE rmode; 12750 12751 real_convert (&rmode, TYPE_MODE (type), &rr); 12752 /* Proceed iff the specified mode can hold the value. */ 12753 if (real_identical (&rmode, &rr)) 12754 return build_real (type, rmode); 12755 } 12756 } 12757 return NULL_TREE; 12758 } 12759 12760 /* Helper function for do_mpc_arg*(). Ensure M is a normal complex 12761 number and no overflow/underflow occurred. INEXACT is true if M 12762 was not exactly calculated. TYPE is the tree type for the result. 12763 This function assumes that you cleared the MPFR flags and then 12764 calculated M to see if anything subsequently set a flag prior to 12765 entering this function. Return NULL_TREE if any checks fail, if 12766 FORCE_CONVERT is true, then bypass the checks. */ 12767 12768 static tree 12769 do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert) 12770 { 12771 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no 12772 overflow/underflow occurred. If -frounding-math, proceed iff the 12773 result of calling FUNC was exact. */ 12774 if (force_convert 12775 || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m)) 12776 && !mpfr_overflow_p () && !mpfr_underflow_p () 12777 && (!flag_rounding_math || !inexact))) 12778 { 12779 REAL_VALUE_TYPE re, im; 12780 12781 real_from_mpfr (&re, mpc_realref (m), TREE_TYPE (type), GMP_RNDN); 12782 real_from_mpfr (&im, mpc_imagref (m), TREE_TYPE (type), GMP_RNDN); 12783 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values, 12784 check for overflow/underflow. If the REAL_VALUE_TYPE is zero 12785 but the mpft_t is not, then we underflowed in the 12786 conversion. */ 12787 if (force_convert 12788 || (real_isfinite (&re) && real_isfinite (&im) 12789 && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0) 12790 && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0))) 12791 { 12792 REAL_VALUE_TYPE re_mode, im_mode; 12793 12794 real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re); 12795 real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im); 12796 /* Proceed iff the specified mode can hold the value. */ 12797 if (force_convert 12798 || (real_identical (&re_mode, &re) 12799 && real_identical (&im_mode, &im))) 12800 return build_complex (type, build_real (TREE_TYPE (type), re_mode), 12801 build_real (TREE_TYPE (type), im_mode)); 12802 } 12803 } 12804 return NULL_TREE; 12805 } 12806 12807 /* If argument ARG is a REAL_CST, call the one-argument mpfr function 12808 FUNC on it and return the resulting value as a tree with type TYPE. 12809 If MIN and/or MAX are not NULL, then the supplied ARG must be 12810 within those bounds. If INCLUSIVE is true, then MIN/MAX are 12811 acceptable values, otherwise they are not. The mpfr precision is 12812 set to the precision of TYPE. We assume that function FUNC returns 12813 zero if the result could be calculated exactly within the requested 12814 precision. */ 12815 12816 static tree 12817 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t), 12818 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max, 12819 bool inclusive) 12820 { 12821 tree result = NULL_TREE; 12822 12823 STRIP_NOPS (arg); 12824 12825 /* To proceed, MPFR must exactly represent the target floating point 12826 format, which only happens when the target base equals two. */ 12827 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 12828 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) 12829 { 12830 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg); 12831 12832 if (real_isfinite (ra) 12833 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)) 12834 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max))) 12835 { 12836 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 12837 const int prec = fmt->p; 12838 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 12839 int inexact; 12840 mpfr_t m; 12841 12842 mpfr_init2 (m, prec); 12843 mpfr_from_real (m, ra, GMP_RNDN); 12844 mpfr_clear_flags (); 12845 inexact = func (m, m, rnd); 12846 result = do_mpfr_ckconv (m, type, inexact); 12847 mpfr_clear (m); 12848 } 12849 } 12850 12851 return result; 12852 } 12853 12854 /* If argument ARG is a REAL_CST, call the two-argument mpfr function 12855 FUNC on it and return the resulting value as a tree with type TYPE. 12856 The mpfr precision is set to the precision of TYPE. We assume that 12857 function FUNC returns zero if the result could be calculated 12858 exactly within the requested precision. */ 12859 12860 static tree 12861 do_mpfr_arg2 (tree arg1, tree arg2, tree type, 12862 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)) 12863 { 12864 tree result = NULL_TREE; 12865 12866 STRIP_NOPS (arg1); 12867 STRIP_NOPS (arg2); 12868 12869 /* To proceed, MPFR must exactly represent the target floating point 12870 format, which only happens when the target base equals two. */ 12871 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 12872 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1) 12873 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)) 12874 { 12875 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1); 12876 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2); 12877 12878 if (real_isfinite (ra1) && real_isfinite (ra2)) 12879 { 12880 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 12881 const int prec = fmt->p; 12882 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 12883 int inexact; 12884 mpfr_t m1, m2; 12885 12886 mpfr_inits2 (prec, m1, m2, NULL); 12887 mpfr_from_real (m1, ra1, GMP_RNDN); 12888 mpfr_from_real (m2, ra2, GMP_RNDN); 12889 mpfr_clear_flags (); 12890 inexact = func (m1, m1, m2, rnd); 12891 result = do_mpfr_ckconv (m1, type, inexact); 12892 mpfr_clears (m1, m2, NULL); 12893 } 12894 } 12895 12896 return result; 12897 } 12898 12899 /* If argument ARG is a REAL_CST, call the three-argument mpfr function 12900 FUNC on it and return the resulting value as a tree with type TYPE. 12901 The mpfr precision is set to the precision of TYPE. We assume that 12902 function FUNC returns zero if the result could be calculated 12903 exactly within the requested precision. */ 12904 12905 static tree 12906 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type, 12907 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)) 12908 { 12909 tree result = NULL_TREE; 12910 12911 STRIP_NOPS (arg1); 12912 STRIP_NOPS (arg2); 12913 STRIP_NOPS (arg3); 12914 12915 /* To proceed, MPFR must exactly represent the target floating point 12916 format, which only happens when the target base equals two. */ 12917 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 12918 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1) 12919 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2) 12920 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3)) 12921 { 12922 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1); 12923 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2); 12924 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3); 12925 12926 if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3)) 12927 { 12928 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 12929 const int prec = fmt->p; 12930 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 12931 int inexact; 12932 mpfr_t m1, m2, m3; 12933 12934 mpfr_inits2 (prec, m1, m2, m3, NULL); 12935 mpfr_from_real (m1, ra1, GMP_RNDN); 12936 mpfr_from_real (m2, ra2, GMP_RNDN); 12937 mpfr_from_real (m3, ra3, GMP_RNDN); 12938 mpfr_clear_flags (); 12939 inexact = func (m1, m1, m2, m3, rnd); 12940 result = do_mpfr_ckconv (m1, type, inexact); 12941 mpfr_clears (m1, m2, m3, NULL); 12942 } 12943 } 12944 12945 return result; 12946 } 12947 12948 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set 12949 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values. 12950 If ARG_SINP and ARG_COSP are NULL then the result is returned 12951 as a complex value. 12952 The type is taken from the type of ARG and is used for setting the 12953 precision of the calculation and results. */ 12954 12955 static tree 12956 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp) 12957 { 12958 tree const type = TREE_TYPE (arg); 12959 tree result = NULL_TREE; 12960 12961 STRIP_NOPS (arg); 12962 12963 /* To proceed, MPFR must exactly represent the target floating point 12964 format, which only happens when the target base equals two. */ 12965 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 12966 && TREE_CODE (arg) == REAL_CST 12967 && !TREE_OVERFLOW (arg)) 12968 { 12969 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg); 12970 12971 if (real_isfinite (ra)) 12972 { 12973 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 12974 const int prec = fmt->p; 12975 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 12976 tree result_s, result_c; 12977 int inexact; 12978 mpfr_t m, ms, mc; 12979 12980 mpfr_inits2 (prec, m, ms, mc, NULL); 12981 mpfr_from_real (m, ra, GMP_RNDN); 12982 mpfr_clear_flags (); 12983 inexact = mpfr_sin_cos (ms, mc, m, rnd); 12984 result_s = do_mpfr_ckconv (ms, type, inexact); 12985 result_c = do_mpfr_ckconv (mc, type, inexact); 12986 mpfr_clears (m, ms, mc, NULL); 12987 if (result_s && result_c) 12988 { 12989 /* If we are to return in a complex value do so. */ 12990 if (!arg_sinp && !arg_cosp) 12991 return build_complex (build_complex_type (type), 12992 result_c, result_s); 12993 12994 /* Dereference the sin/cos pointer arguments. */ 12995 arg_sinp = build_fold_indirect_ref (arg_sinp); 12996 arg_cosp = build_fold_indirect_ref (arg_cosp); 12997 /* Proceed if valid pointer type were passed in. */ 12998 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type) 12999 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type)) 13000 { 13001 /* Set the values. */ 13002 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp, 13003 result_s); 13004 TREE_SIDE_EFFECTS (result_s) = 1; 13005 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp, 13006 result_c); 13007 TREE_SIDE_EFFECTS (result_c) = 1; 13008 /* Combine the assignments into a compound expr. */ 13009 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type, 13010 result_s, result_c)); 13011 } 13012 } 13013 } 13014 } 13015 return result; 13016 } 13017 13018 /* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the 13019 two-argument mpfr order N Bessel function FUNC on them and return 13020 the resulting value as a tree with type TYPE. The mpfr precision 13021 is set to the precision of TYPE. We assume that function FUNC 13022 returns zero if the result could be calculated exactly within the 13023 requested precision. */ 13024 static tree 13025 do_mpfr_bessel_n (tree arg1, tree arg2, tree type, 13026 int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t), 13027 const REAL_VALUE_TYPE *min, bool inclusive) 13028 { 13029 tree result = NULL_TREE; 13030 13031 STRIP_NOPS (arg1); 13032 STRIP_NOPS (arg2); 13033 13034 /* To proceed, MPFR must exactly represent the target floating point 13035 format, which only happens when the target base equals two. */ 13036 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 13037 && host_integerp (arg1, 0) 13038 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)) 13039 { 13040 const HOST_WIDE_INT n = tree_low_cst(arg1, 0); 13041 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2); 13042 13043 if (n == (long)n 13044 && real_isfinite (ra) 13045 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))) 13046 { 13047 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 13048 const int prec = fmt->p; 13049 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 13050 int inexact; 13051 mpfr_t m; 13052 13053 mpfr_init2 (m, prec); 13054 mpfr_from_real (m, ra, GMP_RNDN); 13055 mpfr_clear_flags (); 13056 inexact = func (m, n, m, rnd); 13057 result = do_mpfr_ckconv (m, type, inexact); 13058 mpfr_clear (m); 13059 } 13060 } 13061 13062 return result; 13063 } 13064 13065 /* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set 13066 the pointer *(ARG_QUO) and return the result. The type is taken 13067 from the type of ARG0 and is used for setting the precision of the 13068 calculation and results. */ 13069 13070 static tree 13071 do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo) 13072 { 13073 tree const type = TREE_TYPE (arg0); 13074 tree result = NULL_TREE; 13075 13076 STRIP_NOPS (arg0); 13077 STRIP_NOPS (arg1); 13078 13079 /* To proceed, MPFR must exactly represent the target floating point 13080 format, which only happens when the target base equals two. */ 13081 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 13082 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0) 13083 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)) 13084 { 13085 const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0); 13086 const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1); 13087 13088 if (real_isfinite (ra0) && real_isfinite (ra1)) 13089 { 13090 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 13091 const int prec = fmt->p; 13092 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 13093 tree result_rem; 13094 long integer_quo; 13095 mpfr_t m0, m1; 13096 13097 mpfr_inits2 (prec, m0, m1, NULL); 13098 mpfr_from_real (m0, ra0, GMP_RNDN); 13099 mpfr_from_real (m1, ra1, GMP_RNDN); 13100 mpfr_clear_flags (); 13101 mpfr_remquo (m0, &integer_quo, m0, m1, rnd); 13102 /* Remquo is independent of the rounding mode, so pass 13103 inexact=0 to do_mpfr_ckconv(). */ 13104 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0); 13105 mpfr_clears (m0, m1, NULL); 13106 if (result_rem) 13107 { 13108 /* MPFR calculates quo in the host's long so it may 13109 return more bits in quo than the target int can hold 13110 if sizeof(host long) > sizeof(target int). This can 13111 happen even for native compilers in LP64 mode. In 13112 these cases, modulo the quo value with the largest 13113 number that the target int can hold while leaving one 13114 bit for the sign. */ 13115 if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE) 13116 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1)); 13117 13118 /* Dereference the quo pointer argument. */ 13119 arg_quo = build_fold_indirect_ref (arg_quo); 13120 /* Proceed iff a valid pointer type was passed in. */ 13121 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node) 13122 { 13123 /* Set the value. */ 13124 tree result_quo = fold_build2 (MODIFY_EXPR, 13125 TREE_TYPE (arg_quo), arg_quo, 13126 build_int_cst (NULL, integer_quo)); 13127 TREE_SIDE_EFFECTS (result_quo) = 1; 13128 /* Combine the quo assignment with the rem. */ 13129 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type, 13130 result_quo, result_rem)); 13131 } 13132 } 13133 } 13134 } 13135 return result; 13136 } 13137 13138 /* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the 13139 resulting value as a tree with type TYPE. The mpfr precision is 13140 set to the precision of TYPE. We assume that this mpfr function 13141 returns zero if the result could be calculated exactly within the 13142 requested precision. In addition, the integer pointer represented 13143 by ARG_SG will be dereferenced and set to the appropriate signgam 13144 (-1,1) value. */ 13145 13146 static tree 13147 do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type) 13148 { 13149 tree result = NULL_TREE; 13150 13151 STRIP_NOPS (arg); 13152 13153 /* To proceed, MPFR must exactly represent the target floating point 13154 format, which only happens when the target base equals two. Also 13155 verify ARG is a constant and that ARG_SG is an int pointer. */ 13156 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 13157 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg) 13158 && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE 13159 && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node) 13160 { 13161 const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg); 13162 13163 /* In addition to NaN and Inf, the argument cannot be zero or a 13164 negative integer. */ 13165 if (real_isfinite (ra) 13166 && ra->cl != rvc_zero 13167 && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type)))) 13168 { 13169 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); 13170 const int prec = fmt->p; 13171 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; 13172 int inexact, sg; 13173 mpfr_t m; 13174 tree result_lg; 13175 13176 mpfr_init2 (m, prec); 13177 mpfr_from_real (m, ra, GMP_RNDN); 13178 mpfr_clear_flags (); 13179 inexact = mpfr_lgamma (m, &sg, m, rnd); 13180 result_lg = do_mpfr_ckconv (m, type, inexact); 13181 mpfr_clear (m); 13182 if (result_lg) 13183 { 13184 tree result_sg; 13185 13186 /* Dereference the arg_sg pointer argument. */ 13187 arg_sg = build_fold_indirect_ref (arg_sg); 13188 /* Assign the signgam value into *arg_sg. */ 13189 result_sg = fold_build2 (MODIFY_EXPR, 13190 TREE_TYPE (arg_sg), arg_sg, 13191 build_int_cst (NULL, sg)); 13192 TREE_SIDE_EFFECTS (result_sg) = 1; 13193 /* Combine the signgam assignment with the lgamma result. */ 13194 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type, 13195 result_sg, result_lg)); 13196 } 13197 } 13198 } 13199 13200 return result; 13201 } 13202 13203 /* If argument ARG is a COMPLEX_CST, call the one-argument mpc 13204 function FUNC on it and return the resulting value as a tree with 13205 type TYPE. The mpfr precision is set to the precision of TYPE. We 13206 assume that function FUNC returns zero if the result could be 13207 calculated exactly within the requested precision. */ 13208 13209 static tree 13210 do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t)) 13211 { 13212 tree result = NULL_TREE; 13213 13214 STRIP_NOPS (arg); 13215 13216 /* To proceed, MPFR must exactly represent the target floating point 13217 format, which only happens when the target base equals two. */ 13218 if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg) 13219 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE 13220 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2) 13221 { 13222 const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg)); 13223 const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg)); 13224 13225 if (real_isfinite (re) && real_isfinite (im)) 13226 { 13227 const struct real_format *const fmt = 13228 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type))); 13229 const int prec = fmt->p; 13230 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN; 13231 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN; 13232 int inexact; 13233 mpc_t m; 13234 13235 mpc_init2 (m, prec); 13236 mpfr_from_real (mpc_realref(m), re, rnd); 13237 mpfr_from_real (mpc_imagref(m), im, rnd); 13238 mpfr_clear_flags (); 13239 inexact = func (m, m, crnd); 13240 result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0); 13241 mpc_clear (m); 13242 } 13243 } 13244 13245 return result; 13246 } 13247 13248 /* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument 13249 mpc function FUNC on it and return the resulting value as a tree 13250 with type TYPE. The mpfr precision is set to the precision of 13251 TYPE. We assume that function FUNC returns zero if the result 13252 could be calculated exactly within the requested precision. If 13253 DO_NONFINITE is true, then fold expressions containing Inf or NaN 13254 in the arguments and/or results. */ 13255 13256 tree 13257 do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite, 13258 int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t)) 13259 { 13260 tree result = NULL_TREE; 13261 13262 STRIP_NOPS (arg0); 13263 STRIP_NOPS (arg1); 13264 13265 /* To proceed, MPFR must exactly represent the target floating point 13266 format, which only happens when the target base equals two. */ 13267 if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0) 13268 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE 13269 && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1) 13270 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE 13271 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2) 13272 { 13273 const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0)); 13274 const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0)); 13275 const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1)); 13276 const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1)); 13277 13278 if (do_nonfinite 13279 || (real_isfinite (re0) && real_isfinite (im0) 13280 && real_isfinite (re1) && real_isfinite (im1))) 13281 { 13282 const struct real_format *const fmt = 13283 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type))); 13284 const int prec = fmt->p; 13285 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN; 13286 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN; 13287 int inexact; 13288 mpc_t m0, m1; 13289 13290 mpc_init2 (m0, prec); 13291 mpc_init2 (m1, prec); 13292 mpfr_from_real (mpc_realref(m0), re0, rnd); 13293 mpfr_from_real (mpc_imagref(m0), im0, rnd); 13294 mpfr_from_real (mpc_realref(m1), re1, rnd); 13295 mpfr_from_real (mpc_imagref(m1), im1, rnd); 13296 mpfr_clear_flags (); 13297 inexact = func (m0, m0, m1, crnd); 13298 result = do_mpc_ckconv (m0, type, inexact, do_nonfinite); 13299 mpc_clear (m0); 13300 mpc_clear (m1); 13301 } 13302 } 13303 13304 return result; 13305 } 13306 13307 /* FIXME tuples. 13308 The functions below provide an alternate interface for folding 13309 builtin function calls presented as GIMPLE_CALL statements rather 13310 than as CALL_EXPRs. The folded result is still expressed as a 13311 tree. There is too much code duplication in the handling of 13312 varargs functions, and a more intrusive re-factoring would permit 13313 better sharing of code between the tree and statement-based 13314 versions of these functions. */ 13315 13316 /* Construct a new CALL_EXPR using the tail of the argument list of STMT 13317 along with N new arguments specified as the "..." parameters. SKIP 13318 is the number of arguments in STMT to be omitted. This function is used 13319 to do varargs-to-varargs transformations. */ 13320 13321 static tree 13322 gimple_rewrite_call_expr (gimple stmt, int skip, tree fndecl, int n, ...) 13323 { 13324 int oldnargs = gimple_call_num_args (stmt); 13325 int nargs = oldnargs - skip + n; 13326 tree fntype = TREE_TYPE (fndecl); 13327 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl); 13328 tree *buffer; 13329 int i, j; 13330 va_list ap; 13331 location_t loc = gimple_location (stmt); 13332 13333 buffer = XALLOCAVEC (tree, nargs); 13334 va_start (ap, n); 13335 for (i = 0; i < n; i++) 13336 buffer[i] = va_arg (ap, tree); 13337 va_end (ap); 13338 for (j = skip; j < oldnargs; j++, i++) 13339 buffer[i] = gimple_call_arg (stmt, j); 13340 13341 return fold (build_call_array_loc (loc, TREE_TYPE (fntype), fn, nargs, buffer)); 13342 } 13343 13344 /* Fold a call STMT to __{,v}sprintf_chk. Return NULL_TREE if 13345 a normal call should be emitted rather than expanding the function 13346 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */ 13347 13348 static tree 13349 gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode) 13350 { 13351 tree dest, size, len, fn, fmt, flag; 13352 const char *fmt_str; 13353 int nargs = gimple_call_num_args (stmt); 13354 13355 /* Verify the required arguments in the original call. */ 13356 if (nargs < 4) 13357 return NULL_TREE; 13358 dest = gimple_call_arg (stmt, 0); 13359 if (!validate_arg (dest, POINTER_TYPE)) 13360 return NULL_TREE; 13361 flag = gimple_call_arg (stmt, 1); 13362 if (!validate_arg (flag, INTEGER_TYPE)) 13363 return NULL_TREE; 13364 size = gimple_call_arg (stmt, 2); 13365 if (!validate_arg (size, INTEGER_TYPE)) 13366 return NULL_TREE; 13367 fmt = gimple_call_arg (stmt, 3); 13368 if (!validate_arg (fmt, POINTER_TYPE)) 13369 return NULL_TREE; 13370 13371 if (! host_integerp (size, 1)) 13372 return NULL_TREE; 13373 13374 len = NULL_TREE; 13375 13376 if (!init_target_chars ()) 13377 return NULL_TREE; 13378 13379 /* Check whether the format is a literal string constant. */ 13380 fmt_str = c_getstr (fmt); 13381 if (fmt_str != NULL) 13382 { 13383 /* If the format doesn't contain % args or %%, we know the size. */ 13384 if (strchr (fmt_str, target_percent) == 0) 13385 { 13386 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4) 13387 len = build_int_cstu (size_type_node, strlen (fmt_str)); 13388 } 13389 /* If the format is "%s" and first ... argument is a string literal, 13390 we know the size too. */ 13391 else if (fcode == BUILT_IN_SPRINTF_CHK 13392 && strcmp (fmt_str, target_percent_s) == 0) 13393 { 13394 tree arg; 13395 13396 if (nargs == 5) 13397 { 13398 arg = gimple_call_arg (stmt, 4); 13399 if (validate_arg (arg, POINTER_TYPE)) 13400 { 13401 len = c_strlen (arg, 1); 13402 if (! len || ! host_integerp (len, 1)) 13403 len = NULL_TREE; 13404 } 13405 } 13406 } 13407 } 13408 13409 if (! integer_all_onesp (size)) 13410 { 13411 if (! len || ! tree_int_cst_lt (len, size)) 13412 return NULL_TREE; 13413 } 13414 13415 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0 13416 or if format doesn't contain % chars or is "%s". */ 13417 if (! integer_zerop (flag)) 13418 { 13419 if (fmt_str == NULL) 13420 return NULL_TREE; 13421 if (strchr (fmt_str, target_percent) != NULL 13422 && strcmp (fmt_str, target_percent_s)) 13423 return NULL_TREE; 13424 } 13425 13426 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */ 13427 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK 13428 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF]; 13429 if (!fn) 13430 return NULL_TREE; 13431 13432 return gimple_rewrite_call_expr (stmt, 4, fn, 2, dest, fmt); 13433 } 13434 13435 /* Fold a call STMT to {,v}snprintf. Return NULL_TREE if 13436 a normal call should be emitted rather than expanding the function 13437 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or 13438 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length 13439 passed as second argument. */ 13440 13441 tree 13442 gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen, 13443 enum built_in_function fcode) 13444 { 13445 tree dest, size, len, fn, fmt, flag; 13446 const char *fmt_str; 13447 13448 /* Verify the required arguments in the original call. */ 13449 if (gimple_call_num_args (stmt) < 5) 13450 return NULL_TREE; 13451 dest = gimple_call_arg (stmt, 0); 13452 if (!validate_arg (dest, POINTER_TYPE)) 13453 return NULL_TREE; 13454 len = gimple_call_arg (stmt, 1); 13455 if (!validate_arg (len, INTEGER_TYPE)) 13456 return NULL_TREE; 13457 flag = gimple_call_arg (stmt, 2); 13458 if (!validate_arg (flag, INTEGER_TYPE)) 13459 return NULL_TREE; 13460 size = gimple_call_arg (stmt, 3); 13461 if (!validate_arg (size, INTEGER_TYPE)) 13462 return NULL_TREE; 13463 fmt = gimple_call_arg (stmt, 4); 13464 if (!validate_arg (fmt, POINTER_TYPE)) 13465 return NULL_TREE; 13466 13467 if (! host_integerp (size, 1)) 13468 return NULL_TREE; 13469 13470 if (! integer_all_onesp (size)) 13471 { 13472 if (! host_integerp (len, 1)) 13473 { 13474 /* If LEN is not constant, try MAXLEN too. 13475 For MAXLEN only allow optimizing into non-_ocs function 13476 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 13477 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 13478 return NULL_TREE; 13479 } 13480 else 13481 maxlen = len; 13482 13483 if (tree_int_cst_lt (size, maxlen)) 13484 return NULL_TREE; 13485 } 13486 13487 if (!init_target_chars ()) 13488 return NULL_TREE; 13489 13490 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0 13491 or if format doesn't contain % chars or is "%s". */ 13492 if (! integer_zerop (flag)) 13493 { 13494 fmt_str = c_getstr (fmt); 13495 if (fmt_str == NULL) 13496 return NULL_TREE; 13497 if (strchr (fmt_str, target_percent) != NULL 13498 && strcmp (fmt_str, target_percent_s)) 13499 return NULL_TREE; 13500 } 13501 13502 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is 13503 available. */ 13504 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK 13505 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF]; 13506 if (!fn) 13507 return NULL_TREE; 13508 13509 return gimple_rewrite_call_expr (stmt, 5, fn, 3, dest, len, fmt); 13510 } 13511 13512 /* Builtins with folding operations that operate on "..." arguments 13513 need special handling; we need to store the arguments in a convenient 13514 data structure before attempting any folding. Fortunately there are 13515 only a few builtins that fall into this category. FNDECL is the 13516 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the 13517 result of the function call is ignored. */ 13518 13519 static tree 13520 gimple_fold_builtin_varargs (tree fndecl, gimple stmt, 13521 bool ignore ATTRIBUTE_UNUSED) 13522 { 13523 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 13524 tree ret = NULL_TREE; 13525 13526 switch (fcode) 13527 { 13528 case BUILT_IN_SPRINTF_CHK: 13529 case BUILT_IN_VSPRINTF_CHK: 13530 ret = gimple_fold_builtin_sprintf_chk (stmt, fcode); 13531 break; 13532 13533 case BUILT_IN_SNPRINTF_CHK: 13534 case BUILT_IN_VSNPRINTF_CHK: 13535 ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode); 13536 13537 default: 13538 break; 13539 } 13540 if (ret) 13541 { 13542 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); 13543 TREE_NO_WARNING (ret) = 1; 13544 return ret; 13545 } 13546 return NULL_TREE; 13547 } 13548 13549 /* A wrapper function for builtin folding that prevents warnings for 13550 "statement without effect" and the like, caused by removing the 13551 call node earlier than the warning is generated. */ 13552 13553 tree 13554 fold_call_stmt (gimple stmt, bool ignore) 13555 { 13556 tree ret = NULL_TREE; 13557 tree fndecl = gimple_call_fndecl (stmt); 13558 location_t loc = gimple_location (stmt); 13559 if (fndecl 13560 && TREE_CODE (fndecl) == FUNCTION_DECL 13561 && DECL_BUILT_IN (fndecl) 13562 && !gimple_call_va_arg_pack_p (stmt)) 13563 { 13564 int nargs = gimple_call_num_args (stmt); 13565 13566 if (avoid_folding_inline_builtin (fndecl)) 13567 return NULL_TREE; 13568 /* FIXME: Don't use a list in this interface. */ 13569 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 13570 { 13571 tree arglist = NULL_TREE; 13572 int i; 13573 for (i = nargs - 1; i >= 0; i--) 13574 arglist = tree_cons (NULL_TREE, gimple_call_arg (stmt, i), arglist); 13575 return targetm.fold_builtin (fndecl, arglist, ignore); 13576 } 13577 else 13578 { 13579 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN) 13580 { 13581 tree args[MAX_ARGS_TO_FOLD_BUILTIN]; 13582 int i; 13583 for (i = 0; i < nargs; i++) 13584 args[i] = gimple_call_arg (stmt, i); 13585 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore); 13586 } 13587 if (!ret) 13588 ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore); 13589 if (ret) 13590 { 13591 /* Propagate location information from original call to 13592 expansion of builtin. Otherwise things like 13593 maybe_emit_chk_warning, that operate on the expansion 13594 of a builtin, will use the wrong location information. */ 13595 if (gimple_has_location (stmt)) 13596 { 13597 tree realret = ret; 13598 if (TREE_CODE (ret) == NOP_EXPR) 13599 realret = TREE_OPERAND (ret, 0); 13600 if (CAN_HAVE_LOCATION_P (realret) 13601 && !EXPR_HAS_LOCATION (realret)) 13602 SET_EXPR_LOCATION (realret, loc); 13603 return realret; 13604 } 13605 return ret; 13606 } 13607 } 13608 } 13609 return NULL_TREE; 13610 } 13611 13612 /* Look up the function in built_in_decls that corresponds to DECL 13613 and set ASMSPEC as its user assembler name. DECL must be a 13614 function decl that declares a builtin. */ 13615 13616 void 13617 set_builtin_user_assembler_name (tree decl, const char *asmspec) 13618 { 13619 tree builtin; 13620 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL 13621 && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL 13622 && asmspec != 0); 13623 13624 builtin = built_in_decls [DECL_FUNCTION_CODE (decl)]; 13625 set_user_assembler_name (builtin, asmspec); 13626 switch (DECL_FUNCTION_CODE (decl)) 13627 { 13628 case BUILT_IN_MEMCPY: 13629 init_block_move_fn (asmspec); 13630 memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec); 13631 break; 13632 case BUILT_IN_MEMSET: 13633 init_block_clear_fn (asmspec); 13634 memset_libfunc = set_user_assembler_libfunc ("memset", asmspec); 13635 break; 13636 case BUILT_IN_MEMMOVE: 13637 memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec); 13638 break; 13639 case BUILT_IN_MEMCMP: 13640 memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec); 13641 break; 13642 case BUILT_IN_ABORT: 13643 abort_libfunc = set_user_assembler_libfunc ("abort", asmspec); 13644 break; 13645 case BUILT_IN_FFS: 13646 if (INT_TYPE_SIZE < BITS_PER_WORD) 13647 { 13648 set_user_assembler_libfunc ("ffs", asmspec); 13649 set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, 13650 MODE_INT, 0), "ffs"); 13651 } 13652 break; 13653 default: 13654 break; 13655 } 13656 } 13657