builtins.c revision 236962
1/* Expand builtin functions. 2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 2, or (at your option) any later 10version. 11 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING. If not, write to the Free 19Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 2002110-1301, USA. */ 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 "tree-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 51#ifndef PAD_VARARGS_DOWN 52#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN 53#endif 54 55/* Define the names of the builtin function types and codes. */ 56const char *const built_in_class_names[4] 57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"}; 58 59#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X, 60const char * built_in_names[(int) END_BUILTINS] = 61{ 62#include "builtins.def" 63}; 64#undef DEF_BUILTIN 65 66/* Setup an array of _DECL trees, make sure each element is 67 initialized to NULL_TREE. */ 68tree built_in_decls[(int) END_BUILTINS]; 69/* Declarations used when constructing the builtin implicitly in the compiler. 70 It may be NULL_TREE when this is invalid (for instance runtime is not 71 required to implement the function call in all cases). */ 72tree implicit_built_in_decls[(int) END_BUILTINS]; 73 74static int get_pointer_alignment (tree, unsigned int); 75static const char *c_getstr (tree); 76static rtx c_readstr (const char *, enum machine_mode); 77static int target_char_cast (tree, char *); 78static rtx get_memory_rtx (tree, tree); 79static int apply_args_size (void); 80static int apply_result_size (void); 81#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return) 82static rtx result_vector (int, rtx); 83#endif 84static void expand_builtin_update_setjmp_buf (rtx); 85static void expand_builtin_prefetch (tree); 86static rtx expand_builtin_apply_args (void); 87static rtx expand_builtin_apply_args_1 (void); 88static rtx expand_builtin_apply (rtx, rtx, rtx); 89static void expand_builtin_return (rtx); 90static enum type_class type_to_class (tree); 91static rtx expand_builtin_classify_type (tree); 92static void expand_errno_check (tree, rtx); 93static rtx expand_builtin_mathfn (tree, rtx, rtx); 94static rtx expand_builtin_mathfn_2 (tree, rtx, rtx); 95static rtx expand_builtin_mathfn_3 (tree, rtx, rtx); 96static rtx expand_builtin_sincos (tree); 97static rtx expand_builtin_int_roundingfn (tree, rtx, rtx); 98static rtx expand_builtin_args_info (tree); 99static rtx expand_builtin_next_arg (void); 100static rtx expand_builtin_va_start (tree); 101static rtx expand_builtin_va_end (tree); 102static rtx expand_builtin_va_copy (tree); 103static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode); 104static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode); 105static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode); 106static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode); 107static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode); 108static rtx expand_builtin_strncat (tree, rtx, enum machine_mode); 109static rtx expand_builtin_strspn (tree, rtx, enum machine_mode); 110static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode); 111static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode); 112static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int); 113static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree); 114static rtx expand_builtin_bcopy (tree); 115static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode); 116static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode); 117static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode); 118static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode); 119static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode); 120static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode); 121static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree); 122static rtx expand_builtin_bzero (tree); 123static rtx expand_builtin_strlen (tree, rtx, enum machine_mode); 124static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode); 125static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode); 126static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode); 127static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode); 128static rtx expand_builtin_alloca (tree, rtx); 129static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab); 130static rtx expand_builtin_frame_address (tree, tree); 131static rtx expand_builtin_fputs (tree, rtx, bool); 132static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool); 133static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool); 134static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode); 135static tree stabilize_va_list (tree, int); 136static rtx expand_builtin_expect (tree, rtx); 137static tree fold_builtin_constant_p (tree); 138static tree fold_builtin_classify_type (tree); 139static tree fold_builtin_strlen (tree); 140static tree fold_builtin_inf (tree, int); 141static tree fold_builtin_nan (tree, tree, int); 142static int validate_arglist (tree, ...); 143static bool integer_valued_real_p (tree); 144static tree fold_trunc_transparent_mathfn (tree, tree); 145static bool readonly_data_expr (tree); 146static rtx expand_builtin_fabs (tree, rtx, rtx); 147static rtx expand_builtin_signbit (tree, rtx); 148static tree fold_builtin_sqrt (tree, tree); 149static tree fold_builtin_cbrt (tree, tree); 150static tree fold_builtin_pow (tree, tree, tree); 151static tree fold_builtin_powi (tree, tree, tree); 152static tree fold_builtin_sin (tree); 153static tree fold_builtin_cos (tree, tree, tree); 154static tree fold_builtin_tan (tree); 155static tree fold_builtin_atan (tree, tree); 156static tree fold_builtin_trunc (tree, tree); 157static tree fold_builtin_floor (tree, tree); 158static tree fold_builtin_ceil (tree, tree); 159static tree fold_builtin_round (tree, tree); 160static tree fold_builtin_int_roundingfn (tree, tree); 161static tree fold_builtin_bitop (tree, tree); 162static tree fold_builtin_memory_op (tree, tree, bool, int); 163static tree fold_builtin_strchr (tree, tree); 164static tree fold_builtin_memcmp (tree); 165static tree fold_builtin_strcmp (tree); 166static tree fold_builtin_strncmp (tree); 167static tree fold_builtin_signbit (tree, tree); 168static tree fold_builtin_copysign (tree, tree, tree); 169static tree fold_builtin_isascii (tree); 170static tree fold_builtin_toascii (tree); 171static tree fold_builtin_isdigit (tree); 172static tree fold_builtin_fabs (tree, tree); 173static tree fold_builtin_abs (tree, tree); 174static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code, 175 enum tree_code); 176static tree fold_builtin_1 (tree, tree, bool); 177 178static tree fold_builtin_strpbrk (tree, tree); 179static tree fold_builtin_strstr (tree, tree); 180static tree fold_builtin_strrchr (tree, tree); 181static tree fold_builtin_strcat (tree); 182static tree fold_builtin_strncat (tree); 183static tree fold_builtin_strspn (tree); 184static tree fold_builtin_strcspn (tree); 185static tree fold_builtin_sprintf (tree, int); 186 187static rtx expand_builtin_object_size (tree); 188static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode, 189 enum built_in_function); 190static void maybe_emit_chk_warning (tree, enum built_in_function); 191static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function); 192static tree fold_builtin_object_size (tree); 193static tree fold_builtin_strcat_chk (tree, tree); 194static tree fold_builtin_strncat_chk (tree, tree); 195static tree fold_builtin_sprintf_chk (tree, enum built_in_function); 196static tree fold_builtin_printf (tree, tree, bool, enum built_in_function); 197static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function); 198static bool init_target_chars (void); 199 200static unsigned HOST_WIDE_INT target_newline; 201static unsigned HOST_WIDE_INT target_percent; 202static unsigned HOST_WIDE_INT target_c; 203static unsigned HOST_WIDE_INT target_s; 204static char target_percent_c[3]; 205static char target_percent_s[3]; 206static char target_percent_s_newline[4]; 207 208/* Return true if NODE should be considered for inline expansion regardless 209 of the optimization level. This means whenever a function is invoked with 210 its "internal" name, which normally contains the prefix "__builtin". */ 211 212static bool called_as_built_in (tree node) 213{ 214 const char *name = IDENTIFIER_POINTER (DECL_NAME (node)); 215 if (strncmp (name, "__builtin_", 10) == 0) 216 return true; 217 if (strncmp (name, "__sync_", 7) == 0) 218 return true; 219 return false; 220} 221 222/* Return the alignment in bits of EXP, a pointer valued expression. 223 But don't return more than MAX_ALIGN no matter what. 224 The alignment returned is, by default, the alignment of the thing that 225 EXP points to. If it is not a POINTER_TYPE, 0 is returned. 226 227 Otherwise, look at the expression to see if we can do better, i.e., if the 228 expression is actually pointing at an object whose alignment is tighter. */ 229 230static int 231get_pointer_alignment (tree exp, unsigned int max_align) 232{ 233 unsigned int align, inner; 234 235 /* We rely on TER to compute accurate alignment information. */ 236 if (!(optimize && flag_tree_ter)) 237 return 0; 238 239 if (!POINTER_TYPE_P (TREE_TYPE (exp))) 240 return 0; 241 242 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))); 243 align = MIN (align, max_align); 244 245 while (1) 246 { 247 switch (TREE_CODE (exp)) 248 { 249 case NOP_EXPR: 250 case CONVERT_EXPR: 251 case NON_LVALUE_EXPR: 252 exp = TREE_OPERAND (exp, 0); 253 if (! POINTER_TYPE_P (TREE_TYPE (exp))) 254 return align; 255 256 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))); 257 align = MIN (inner, max_align); 258 break; 259 260 case PLUS_EXPR: 261 /* If sum of pointer + int, restrict our maximum alignment to that 262 imposed by the integer. If not, we can't do any better than 263 ALIGN. */ 264 if (! host_integerp (TREE_OPERAND (exp, 1), 1)) 265 return align; 266 267 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1)) 268 & (max_align / BITS_PER_UNIT - 1)) 269 != 0) 270 max_align >>= 1; 271 272 exp = TREE_OPERAND (exp, 0); 273 break; 274 275 case ADDR_EXPR: 276 /* See what we are pointing at and look at its alignment. */ 277 exp = TREE_OPERAND (exp, 0); 278 inner = max_align; 279 if (handled_component_p (exp)) 280 { 281 HOST_WIDE_INT bitsize, bitpos; 282 tree offset; 283 enum machine_mode mode; 284 int unsignedp, volatilep; 285 286 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset, 287 &mode, &unsignedp, &volatilep, true); 288 if (bitpos) 289 inner = MIN (inner, (unsigned) (bitpos & -bitpos)); 290 if (offset && TREE_CODE (offset) == PLUS_EXPR 291 && host_integerp (TREE_OPERAND (offset, 1), 1)) 292 { 293 /* Any overflow in calculating offset_bits won't change 294 the alignment. */ 295 unsigned offset_bits 296 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1) 297 * BITS_PER_UNIT); 298 299 if (offset_bits) 300 inner = MIN (inner, (offset_bits & -offset_bits)); 301 offset = TREE_OPERAND (offset, 0); 302 } 303 if (offset && TREE_CODE (offset) == MULT_EXPR 304 && host_integerp (TREE_OPERAND (offset, 1), 1)) 305 { 306 /* Any overflow in calculating offset_factor won't change 307 the alignment. */ 308 unsigned offset_factor 309 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1) 310 * BITS_PER_UNIT); 311 312 if (offset_factor) 313 inner = MIN (inner, (offset_factor & -offset_factor)); 314 } 315 else if (offset) 316 inner = MIN (inner, BITS_PER_UNIT); 317 } 318 if (TREE_CODE (exp) == FUNCTION_DECL) 319 align = FUNCTION_BOUNDARY; 320 else if (DECL_P (exp)) 321 align = MIN (inner, DECL_ALIGN (exp)); 322#ifdef CONSTANT_ALIGNMENT 323 else if (CONSTANT_CLASS_P (exp)) 324 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align)); 325#endif 326 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR 327 || TREE_CODE (exp) == INDIRECT_REF) 328 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner); 329 else 330 align = MIN (align, inner); 331 return MIN (align, max_align); 332 333 default: 334 return align; 335 } 336 } 337} 338 339/* Compute the length of a C string. TREE_STRING_LENGTH is not the right 340 way, because it could contain a zero byte in the middle. 341 TREE_STRING_LENGTH is the size of the character array, not the string. 342 343 ONLY_VALUE should be nonzero if the result is not going to be emitted 344 into the instruction stream and zero if it is going to be expanded. 345 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3 346 is returned, otherwise NULL, since 347 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not 348 evaluate the side-effects. 349 350 The value returned is of type `ssizetype'. 351 352 Unfortunately, string_constant can't access the values of const char 353 arrays with initializers, so neither can we do so here. */ 354 355tree 356c_strlen (tree src, int only_value) 357{ 358 tree offset_node; 359 HOST_WIDE_INT offset; 360 int max; 361 const char *ptr; 362 363 STRIP_NOPS (src); 364 if (TREE_CODE (src) == COND_EXPR 365 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) 366 { 367 tree len1, len2; 368 369 len1 = c_strlen (TREE_OPERAND (src, 1), only_value); 370 len2 = c_strlen (TREE_OPERAND (src, 2), only_value); 371 if (tree_int_cst_equal (len1, len2)) 372 return len1; 373 } 374 375 if (TREE_CODE (src) == COMPOUND_EXPR 376 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) 377 return c_strlen (TREE_OPERAND (src, 1), only_value); 378 379 src = string_constant (src, &offset_node); 380 if (src == 0) 381 return 0; 382 383 max = TREE_STRING_LENGTH (src) - 1; 384 ptr = TREE_STRING_POINTER (src); 385 386 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST) 387 { 388 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't 389 compute the offset to the following null if we don't know where to 390 start searching for it. */ 391 int i; 392 393 for (i = 0; i < max; i++) 394 if (ptr[i] == 0) 395 return 0; 396 397 /* We don't know the starting offset, but we do know that the string 398 has no internal zero bytes. We can assume that the offset falls 399 within the bounds of the string; otherwise, the programmer deserves 400 what he gets. Subtract the offset from the length of the string, 401 and return that. This would perhaps not be valid if we were dealing 402 with named arrays in addition to literal string constants. */ 403 404 return size_diffop (size_int (max), offset_node); 405 } 406 407 /* We have a known offset into the string. Start searching there for 408 a null character if we can represent it as a single HOST_WIDE_INT. */ 409 if (offset_node == 0) 410 offset = 0; 411 else if (! host_integerp (offset_node, 0)) 412 offset = -1; 413 else 414 offset = tree_low_cst (offset_node, 0); 415 416 /* If the offset is known to be out of bounds, warn, and call strlen at 417 runtime. */ 418 if (offset < 0 || offset > max) 419 { 420 warning (0, "offset outside bounds of constant string"); 421 return 0; 422 } 423 424 /* Use strlen to search for the first zero byte. Since any strings 425 constructed with build_string will have nulls appended, we win even 426 if we get handed something like (char[4])"abcd". 427 428 Since OFFSET is our starting index into the string, no further 429 calculation is needed. */ 430 return ssize_int (strlen (ptr + offset)); 431} 432 433/* Return a char pointer for a C string if it is a string constant 434 or sum of string constant and integer constant. */ 435 436static const char * 437c_getstr (tree src) 438{ 439 tree offset_node; 440 441 src = string_constant (src, &offset_node); 442 if (src == 0) 443 return 0; 444 445 if (offset_node == 0) 446 return TREE_STRING_POINTER (src); 447 else if (!host_integerp (offset_node, 1) 448 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0) 449 return 0; 450 451 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1); 452} 453 454/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading 455 GET_MODE_BITSIZE (MODE) bits from string constant STR. */ 456 457static rtx 458c_readstr (const char *str, enum machine_mode mode) 459{ 460 HOST_WIDE_INT c[2]; 461 HOST_WIDE_INT ch; 462 unsigned int i, j; 463 464 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT); 465 466 c[0] = 0; 467 c[1] = 0; 468 ch = 1; 469 for (i = 0; i < GET_MODE_SIZE (mode); i++) 470 { 471 j = i; 472 if (WORDS_BIG_ENDIAN) 473 j = GET_MODE_SIZE (mode) - i - 1; 474 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN 475 && GET_MODE_SIZE (mode) > UNITS_PER_WORD) 476 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1; 477 j *= BITS_PER_UNIT; 478 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT); 479 480 if (ch) 481 ch = (unsigned char) str[i]; 482 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT); 483 } 484 return immed_double_const (c[0], c[1], mode); 485} 486 487/* Cast a target constant CST to target CHAR and if that value fits into 488 host char type, return zero and put that value into variable pointed to by 489 P. */ 490 491static int 492target_char_cast (tree cst, char *p) 493{ 494 unsigned HOST_WIDE_INT val, hostval; 495 496 if (!host_integerp (cst, 1) 497 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT) 498 return 1; 499 500 val = tree_low_cst (cst, 1); 501 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT) 502 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1; 503 504 hostval = val; 505 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT) 506 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1; 507 508 if (val != hostval) 509 return 1; 510 511 *p = hostval; 512 return 0; 513} 514 515/* Similar to save_expr, but assumes that arbitrary code is not executed 516 in between the multiple evaluations. In particular, we assume that a 517 non-addressable local variable will not be modified. */ 518 519static tree 520builtin_save_expr (tree exp) 521{ 522 if (TREE_ADDRESSABLE (exp) == 0 523 && (TREE_CODE (exp) == PARM_DECL 524 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp)))) 525 return exp; 526 527 return save_expr (exp); 528} 529 530/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT 531 times to get the address of either a higher stack frame, or a return 532 address located within it (depending on FNDECL_CODE). */ 533 534static rtx 535expand_builtin_return_addr (enum built_in_function fndecl_code, int count) 536{ 537 int i; 538 539#ifdef INITIAL_FRAME_ADDRESS_RTX 540 rtx tem = INITIAL_FRAME_ADDRESS_RTX; 541#else 542 rtx tem; 543 544 /* For a zero count with __builtin_return_address, we don't care what 545 frame address we return, because target-specific definitions will 546 override us. Therefore frame pointer elimination is OK, and using 547 the soft frame pointer is OK. 548 549 For a non-zero count, or a zero count with __builtin_frame_address, 550 we require a stable offset from the current frame pointer to the 551 previous one, so we must use the hard frame pointer, and 552 we must disable frame pointer elimination. */ 553 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS) 554 tem = frame_pointer_rtx; 555 else 556 { 557 tem = hard_frame_pointer_rtx; 558 559 /* Tell reload not to eliminate the frame pointer. */ 560 current_function_accesses_prior_frames = 1; 561 } 562#endif 563 564 /* Some machines need special handling before we can access 565 arbitrary frames. For example, on the SPARC, we must first flush 566 all register windows to the stack. */ 567#ifdef SETUP_FRAME_ADDRESSES 568 if (count > 0) 569 SETUP_FRAME_ADDRESSES (); 570#endif 571 572 /* On the SPARC, the return address is not in the frame, it is in a 573 register. There is no way to access it off of the current frame 574 pointer, but it can be accessed off the previous frame pointer by 575 reading the value from the register window save area. */ 576#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME 577 if (fndecl_code == BUILT_IN_RETURN_ADDRESS) 578 count--; 579#endif 580 581 /* Scan back COUNT frames to the specified frame. */ 582 for (i = 0; i < count; i++) 583 { 584 /* Assume the dynamic chain pointer is in the word that the 585 frame address points to, unless otherwise specified. */ 586#ifdef DYNAMIC_CHAIN_ADDRESS 587 tem = DYNAMIC_CHAIN_ADDRESS (tem); 588#endif 589 tem = memory_address (Pmode, tem); 590 tem = gen_frame_mem (Pmode, tem); 591 tem = copy_to_reg (tem); 592 } 593 594 /* For __builtin_frame_address, return what we've got. But, on 595 the SPARC for example, we may have to add a bias. */ 596 if (fndecl_code == BUILT_IN_FRAME_ADDRESS) 597#ifdef FRAME_ADDR_RTX 598 return FRAME_ADDR_RTX (tem); 599#else 600 return tem; 601#endif 602 603 /* For __builtin_return_address, get the return address from that frame. */ 604#ifdef RETURN_ADDR_RTX 605 tem = RETURN_ADDR_RTX (count, tem); 606#else 607 tem = memory_address (Pmode, 608 plus_constant (tem, GET_MODE_SIZE (Pmode))); 609 tem = gen_frame_mem (Pmode, tem); 610#endif 611 return tem; 612} 613 614/* Alias set used for setjmp buffer. */ 615static HOST_WIDE_INT setjmp_alias_set = -1; 616 617/* Construct the leading half of a __builtin_setjmp call. Control will 618 return to RECEIVER_LABEL. This is also called directly by the SJLJ 619 exception handling code. */ 620 621void 622expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label) 623{ 624 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 625 rtx stack_save; 626 rtx mem; 627 628 if (setjmp_alias_set == -1) 629 setjmp_alias_set = new_alias_set (); 630 631 buf_addr = convert_memory_address (Pmode, buf_addr); 632 633 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX)); 634 635 /* We store the frame pointer and the address of receiver_label in 636 the buffer and use the rest of it for the stack save area, which 637 is machine-dependent. */ 638 639 mem = gen_rtx_MEM (Pmode, buf_addr); 640 set_mem_alias_set (mem, setjmp_alias_set); 641 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ()); 642 643 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))), 644 set_mem_alias_set (mem, setjmp_alias_set); 645 646 emit_move_insn (validize_mem (mem), 647 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label))); 648 649 stack_save = gen_rtx_MEM (sa_mode, 650 plus_constant (buf_addr, 651 2 * GET_MODE_SIZE (Pmode))); 652 set_mem_alias_set (stack_save, setjmp_alias_set); 653 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX); 654 655 /* If there is further processing to do, do it. */ 656#ifdef HAVE_builtin_setjmp_setup 657 if (HAVE_builtin_setjmp_setup) 658 emit_insn (gen_builtin_setjmp_setup (buf_addr)); 659#endif 660 661 /* Tell optimize_save_area_alloca that extra work is going to 662 need to go on during alloca. */ 663 current_function_calls_setjmp = 1; 664 665 /* Set this so all the registers get saved in our frame; we need to be 666 able to copy the saved values for any registers from frames we unwind. */ 667 current_function_has_nonlocal_label = 1; 668} 669 670/* Construct the trailing part of a __builtin_setjmp call. This is 671 also called directly by the SJLJ exception handling code. */ 672 673void 674expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED) 675{ 676 /* Clobber the FP when we get here, so we have to make sure it's 677 marked as used by this function. */ 678 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); 679 680 /* Mark the static chain as clobbered here so life information 681 doesn't get messed up for it. */ 682 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx)); 683 684 /* Now put in the code to restore the frame pointer, and argument 685 pointer, if needed. */ 686#ifdef HAVE_nonlocal_goto 687 if (! HAVE_nonlocal_goto) 688#endif 689 { 690 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); 691 /* This might change the hard frame pointer in ways that aren't 692 apparent to early optimization passes, so force a clobber. */ 693 emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx)); 694 } 695 696#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM 697 if (fixed_regs[ARG_POINTER_REGNUM]) 698 { 699#ifdef ELIMINABLE_REGS 700 size_t i; 701 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS; 702 703 for (i = 0; i < ARRAY_SIZE (elim_regs); i++) 704 if (elim_regs[i].from == ARG_POINTER_REGNUM 705 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM) 706 break; 707 708 if (i == ARRAY_SIZE (elim_regs)) 709#endif 710 { 711 /* Now restore our arg pointer from the address at which it 712 was saved in our stack frame. */ 713 emit_move_insn (virtual_incoming_args_rtx, 714 copy_to_reg (get_arg_pointer_save_area (cfun))); 715 } 716 } 717#endif 718 719#ifdef HAVE_builtin_setjmp_receiver 720 if (HAVE_builtin_setjmp_receiver) 721 emit_insn (gen_builtin_setjmp_receiver (receiver_label)); 722 else 723#endif 724#ifdef HAVE_nonlocal_goto_receiver 725 if (HAVE_nonlocal_goto_receiver) 726 emit_insn (gen_nonlocal_goto_receiver ()); 727 else 728#endif 729 { /* Nothing */ } 730 731 /* @@@ This is a kludge. Not all machine descriptions define a blockage 732 insn, but we must not allow the code we just generated to be reordered 733 by scheduling. Specifically, the update of the frame pointer must 734 happen immediately, not later. So emit an ASM_INPUT to act as blockage 735 insn. */ 736 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, "")); 737} 738 739/* __builtin_longjmp is passed a pointer to an array of five words (not 740 all will be used on all machines). It operates similarly to the C 741 library function of the same name, but is more efficient. Much of 742 the code below is copied from the handling of non-local gotos. */ 743 744static void 745expand_builtin_longjmp (rtx buf_addr, rtx value) 746{ 747 rtx fp, lab, stack, insn, last; 748 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 749 750 if (setjmp_alias_set == -1) 751 setjmp_alias_set = new_alias_set (); 752 753 buf_addr = convert_memory_address (Pmode, buf_addr); 754 755 buf_addr = force_reg (Pmode, buf_addr); 756 757 /* We used to store value in static_chain_rtx, but that fails if pointers 758 are smaller than integers. We instead require that the user must pass 759 a second argument of 1, because that is what builtin_setjmp will 760 return. This also makes EH slightly more efficient, since we are no 761 longer copying around a value that we don't care about. */ 762 gcc_assert (value == const1_rtx); 763 764 last = get_last_insn (); 765#ifdef HAVE_builtin_longjmp 766 if (HAVE_builtin_longjmp) 767 emit_insn (gen_builtin_longjmp (buf_addr)); 768 else 769#endif 770 { 771 fp = gen_rtx_MEM (Pmode, buf_addr); 772 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr, 773 GET_MODE_SIZE (Pmode))); 774 775 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr, 776 2 * GET_MODE_SIZE (Pmode))); 777 set_mem_alias_set (fp, setjmp_alias_set); 778 set_mem_alias_set (lab, setjmp_alias_set); 779 set_mem_alias_set (stack, setjmp_alias_set); 780 781 /* Pick up FP, label, and SP from the block and jump. This code is 782 from expand_goto in stmt.c; see there for detailed comments. */ 783#ifdef HAVE_nonlocal_goto 784 if (HAVE_nonlocal_goto) 785 /* We have to pass a value to the nonlocal_goto pattern that will 786 get copied into the static_chain pointer, but it does not matter 787 what that value is, because builtin_setjmp does not use it. */ 788 emit_insn (gen_nonlocal_goto (value, lab, stack, fp)); 789 else 790#endif 791 { 792 lab = copy_to_reg (lab); 793 794 emit_insn (gen_rtx_CLOBBER (VOIDmode, 795 gen_rtx_MEM (BLKmode, 796 gen_rtx_SCRATCH (VOIDmode)))); 797 emit_insn (gen_rtx_CLOBBER (VOIDmode, 798 gen_rtx_MEM (BLKmode, 799 hard_frame_pointer_rtx))); 800 801 emit_move_insn (hard_frame_pointer_rtx, fp); 802 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX); 803 804 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); 805 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); 806 emit_indirect_jump (lab); 807 } 808 } 809 810 /* Search backwards and mark the jump insn as a non-local goto. 811 Note that this precludes the use of __builtin_longjmp to a 812 __builtin_setjmp target in the same function. However, we've 813 already cautioned the user that these functions are for 814 internal exception handling use only. */ 815 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) 816 { 817 gcc_assert (insn != last); 818 819 if (JUMP_P (insn)) 820 { 821 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx, 822 REG_NOTES (insn)); 823 break; 824 } 825 else if (CALL_P (insn)) 826 break; 827 } 828} 829 830/* Expand a call to __builtin_nonlocal_goto. We're passed the target label 831 and the address of the save area. */ 832 833static rtx 834expand_builtin_nonlocal_goto (tree arglist) 835{ 836 tree t_label, t_save_area; 837 rtx r_label, r_save_area, r_fp, r_sp, insn; 838 839 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 840 return NULL_RTX; 841 842 t_label = TREE_VALUE (arglist); 843 arglist = TREE_CHAIN (arglist); 844 t_save_area = TREE_VALUE (arglist); 845 846 r_label = expand_normal (t_label); 847 r_label = convert_memory_address (Pmode, r_label); 848 r_save_area = expand_normal (t_save_area); 849 r_save_area = convert_memory_address (Pmode, r_save_area); 850 r_fp = gen_rtx_MEM (Pmode, r_save_area); 851 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL), 852 plus_constant (r_save_area, GET_MODE_SIZE (Pmode))); 853 854 current_function_has_nonlocal_goto = 1; 855 856#ifdef HAVE_nonlocal_goto 857 /* ??? We no longer need to pass the static chain value, afaik. */ 858 if (HAVE_nonlocal_goto) 859 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp)); 860 else 861#endif 862 { 863 r_label = copy_to_reg (r_label); 864 865 emit_insn (gen_rtx_CLOBBER (VOIDmode, 866 gen_rtx_MEM (BLKmode, 867 gen_rtx_SCRATCH (VOIDmode)))); 868 869 emit_insn (gen_rtx_CLOBBER (VOIDmode, 870 gen_rtx_MEM (BLKmode, 871 hard_frame_pointer_rtx))); 872 873 /* Restore frame pointer for containing function. 874 This sets the actual hard register used for the frame pointer 875 to the location of the function's incoming static chain info. 876 The non-local goto handler will then adjust it to contain the 877 proper value and reload the argument pointer, if needed. */ 878 emit_move_insn (hard_frame_pointer_rtx, r_fp); 879 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX); 880 881 /* USE of hard_frame_pointer_rtx added for consistency; 882 not clear if really needed. */ 883 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); 884 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); 885 emit_indirect_jump (r_label); 886 } 887 888 /* Search backwards to the jump insn and mark it as a 889 non-local goto. */ 890 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) 891 { 892 if (JUMP_P (insn)) 893 { 894 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, 895 const0_rtx, REG_NOTES (insn)); 896 break; 897 } 898 else if (CALL_P (insn)) 899 break; 900 } 901 902 return const0_rtx; 903} 904 905/* __builtin_update_setjmp_buf is passed a pointer to an array of five words 906 (not all will be used on all machines) that was passed to __builtin_setjmp. 907 It updates the stack pointer in that block to correspond to the current 908 stack pointer. */ 909 910static void 911expand_builtin_update_setjmp_buf (rtx buf_addr) 912{ 913 enum machine_mode sa_mode = Pmode; 914 rtx stack_save; 915 916 917#ifdef HAVE_save_stack_nonlocal 918 if (HAVE_save_stack_nonlocal) 919 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode; 920#endif 921#ifdef STACK_SAVEAREA_MODE 922 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 923#endif 924 925 stack_save 926 = gen_rtx_MEM (sa_mode, 927 memory_address 928 (sa_mode, 929 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode)))); 930 931#ifdef HAVE_setjmp 932 if (HAVE_setjmp) 933 emit_insn (gen_setjmp ()); 934#endif 935 936 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX); 937} 938 939/* Expand a call to __builtin_prefetch. For a target that does not support 940 data prefetch, evaluate the memory address argument in case it has side 941 effects. */ 942 943static void 944expand_builtin_prefetch (tree arglist) 945{ 946 tree arg0, arg1, arg2; 947 rtx op0, op1, op2; 948 949 if (!validate_arglist (arglist, POINTER_TYPE, 0)) 950 return; 951 952 arg0 = TREE_VALUE (arglist); 953 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to 954 zero (read) and argument 2 (locality) defaults to 3 (high degree of 955 locality). */ 956 if (TREE_CHAIN (arglist)) 957 { 958 arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 959 if (TREE_CHAIN (TREE_CHAIN (arglist))) 960 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 961 else 962 arg2 = build_int_cst (NULL_TREE, 3); 963 } 964 else 965 { 966 arg1 = integer_zero_node; 967 arg2 = build_int_cst (NULL_TREE, 3); 968 } 969 970 /* Argument 0 is an address. */ 971 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL); 972 973 /* Argument 1 (read/write flag) must be a compile-time constant int. */ 974 if (TREE_CODE (arg1) != INTEGER_CST) 975 { 976 error ("second argument to %<__builtin_prefetch%> must be a constant"); 977 arg1 = integer_zero_node; 978 } 979 op1 = expand_normal (arg1); 980 /* Argument 1 must be either zero or one. */ 981 if (INTVAL (op1) != 0 && INTVAL (op1) != 1) 982 { 983 warning (0, "invalid second argument to %<__builtin_prefetch%>;" 984 " using zero"); 985 op1 = const0_rtx; 986 } 987 988 /* Argument 2 (locality) must be a compile-time constant int. */ 989 if (TREE_CODE (arg2) != INTEGER_CST) 990 { 991 error ("third argument to %<__builtin_prefetch%> must be a constant"); 992 arg2 = integer_zero_node; 993 } 994 op2 = expand_normal (arg2); 995 /* Argument 2 must be 0, 1, 2, or 3. */ 996 if (INTVAL (op2) < 0 || INTVAL (op2) > 3) 997 { 998 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero"); 999 op2 = const0_rtx; 1000 } 1001 1002#ifdef HAVE_prefetch 1003 if (HAVE_prefetch) 1004 { 1005 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate) 1006 (op0, 1007 insn_data[(int) CODE_FOR_prefetch].operand[0].mode)) 1008 || (GET_MODE (op0) != Pmode)) 1009 { 1010 op0 = convert_memory_address (Pmode, op0); 1011 op0 = force_reg (Pmode, op0); 1012 } 1013 emit_insn (gen_prefetch (op0, op1, op2)); 1014 } 1015#endif 1016 1017 /* Don't do anything with direct references to volatile memory, but 1018 generate code to handle other side effects. */ 1019 if (!MEM_P (op0) && side_effects_p (op0)) 1020 emit_insn (op0); 1021} 1022 1023/* Get a MEM rtx for expression EXP which is the address of an operand 1024 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is 1025 the maximum length of the block of memory that might be accessed or 1026 NULL if unknown. */ 1027 1028static rtx 1029get_memory_rtx (tree exp, tree len) 1030{ 1031 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL); 1032 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr)); 1033 1034 /* Get an expression we can use to find the attributes to assign to MEM. 1035 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if 1036 we can. First remove any nops. */ 1037 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR 1038 || TREE_CODE (exp) == NON_LVALUE_EXPR) 1039 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0)))) 1040 exp = TREE_OPERAND (exp, 0); 1041 1042 if (TREE_CODE (exp) == ADDR_EXPR) 1043 exp = TREE_OPERAND (exp, 0); 1044 else if (POINTER_TYPE_P (TREE_TYPE (exp))) 1045 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp); 1046 else 1047 exp = NULL; 1048 1049 /* Honor attributes derived from exp, except for the alias set 1050 (as builtin stringops may alias with anything) and the size 1051 (as stringops may access multiple array elements). */ 1052 if (exp) 1053 { 1054 set_mem_attributes (mem, exp, 0); 1055 1056 /* Allow the string and memory builtins to overflow from one 1057 field into another, see http://gcc.gnu.org/PR23561. 1058 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole 1059 memory accessed by the string or memory builtin will fit 1060 within the field. */ 1061 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF) 1062 { 1063 tree mem_expr = MEM_EXPR (mem); 1064 HOST_WIDE_INT offset = -1, length = -1; 1065 tree inner = exp; 1066 1067 while (TREE_CODE (inner) == ARRAY_REF 1068 || TREE_CODE (inner) == NOP_EXPR 1069 || TREE_CODE (inner) == CONVERT_EXPR 1070 || TREE_CODE (inner) == NON_LVALUE_EXPR 1071 || TREE_CODE (inner) == VIEW_CONVERT_EXPR 1072 || TREE_CODE (inner) == SAVE_EXPR) 1073 inner = TREE_OPERAND (inner, 0); 1074 1075 gcc_assert (TREE_CODE (inner) == COMPONENT_REF); 1076 1077 if (MEM_OFFSET (mem) 1078 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT) 1079 offset = INTVAL (MEM_OFFSET (mem)); 1080 1081 if (offset >= 0 && len && host_integerp (len, 0)) 1082 length = tree_low_cst (len, 0); 1083 1084 while (TREE_CODE (inner) == COMPONENT_REF) 1085 { 1086 tree field = TREE_OPERAND (inner, 1); 1087 gcc_assert (! DECL_BIT_FIELD (field)); 1088 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF); 1089 gcc_assert (field == TREE_OPERAND (mem_expr, 1)); 1090 1091 if (length >= 0 1092 && TYPE_SIZE_UNIT (TREE_TYPE (inner)) 1093 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0)) 1094 { 1095 HOST_WIDE_INT size 1096 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0); 1097 /* If we can prove the memory starting at XEXP (mem, 0) 1098 and ending at XEXP (mem, 0) + LENGTH will fit into 1099 this field, we can keep that COMPONENT_REF in MEM_EXPR. */ 1100 if (offset <= size 1101 && length <= size 1102 && offset + length <= size) 1103 break; 1104 } 1105 1106 if (offset >= 0 1107 && host_integerp (DECL_FIELD_OFFSET (field), 0)) 1108 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0) 1109 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1) 1110 / BITS_PER_UNIT; 1111 else 1112 { 1113 offset = -1; 1114 length = -1; 1115 } 1116 1117 mem_expr = TREE_OPERAND (mem_expr, 0); 1118 inner = TREE_OPERAND (inner, 0); 1119 } 1120 1121 if (mem_expr == NULL) 1122 offset = -1; 1123 if (mem_expr != MEM_EXPR (mem)) 1124 { 1125 set_mem_expr (mem, mem_expr); 1126 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX); 1127 } 1128 } 1129 set_mem_alias_set (mem, 0); 1130 set_mem_size (mem, NULL_RTX); 1131 } 1132 1133 return mem; 1134} 1135 1136/* Built-in functions to perform an untyped call and return. */ 1137 1138/* For each register that may be used for calling a function, this 1139 gives a mode used to copy the register's value. VOIDmode indicates 1140 the register is not used for calling a function. If the machine 1141 has register windows, this gives only the outbound registers. 1142 INCOMING_REGNO gives the corresponding inbound register. */ 1143static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER]; 1144 1145/* For each register that may be used for returning values, this gives 1146 a mode used to copy the register's value. VOIDmode indicates the 1147 register is not used for returning values. If the machine has 1148 register windows, this gives only the outbound registers. 1149 INCOMING_REGNO gives the corresponding inbound register. */ 1150static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER]; 1151 1152/* For each register that may be used for calling a function, this 1153 gives the offset of that register into the block returned by 1154 __builtin_apply_args. 0 indicates that the register is not 1155 used for calling a function. */ 1156static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER]; 1157 1158/* Return the size required for the block returned by __builtin_apply_args, 1159 and initialize apply_args_mode. */ 1160 1161static int 1162apply_args_size (void) 1163{ 1164 static int size = -1; 1165 int align; 1166 unsigned int regno; 1167 enum machine_mode mode; 1168 1169 /* The values computed by this function never change. */ 1170 if (size < 0) 1171 { 1172 /* The first value is the incoming arg-pointer. */ 1173 size = GET_MODE_SIZE (Pmode); 1174 1175 /* The second value is the structure value address unless this is 1176 passed as an "invisible" first argument. */ 1177 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0)) 1178 size += GET_MODE_SIZE (Pmode); 1179 1180 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1181 if (FUNCTION_ARG_REGNO_P (regno)) 1182 { 1183 mode = reg_raw_mode[regno]; 1184 1185 gcc_assert (mode != VOIDmode); 1186 1187 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1188 if (size % align != 0) 1189 size = CEIL (size, align) * align; 1190 apply_args_reg_offset[regno] = size; 1191 size += GET_MODE_SIZE (mode); 1192 apply_args_mode[regno] = mode; 1193 } 1194 else 1195 { 1196 apply_args_mode[regno] = VOIDmode; 1197 apply_args_reg_offset[regno] = 0; 1198 } 1199 } 1200 return size; 1201} 1202 1203/* Return the size required for the block returned by __builtin_apply, 1204 and initialize apply_result_mode. */ 1205 1206static int 1207apply_result_size (void) 1208{ 1209 static int size = -1; 1210 int align, regno; 1211 enum machine_mode mode; 1212 1213 /* The values computed by this function never change. */ 1214 if (size < 0) 1215 { 1216 size = 0; 1217 1218 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1219 if (FUNCTION_VALUE_REGNO_P (regno)) 1220 { 1221 mode = reg_raw_mode[regno]; 1222 1223 gcc_assert (mode != VOIDmode); 1224 1225 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1226 if (size % align != 0) 1227 size = CEIL (size, align) * align; 1228 size += GET_MODE_SIZE (mode); 1229 apply_result_mode[regno] = mode; 1230 } 1231 else 1232 apply_result_mode[regno] = VOIDmode; 1233 1234 /* Allow targets that use untyped_call and untyped_return to override 1235 the size so that machine-specific information can be stored here. */ 1236#ifdef APPLY_RESULT_SIZE 1237 size = APPLY_RESULT_SIZE; 1238#endif 1239 } 1240 return size; 1241} 1242 1243#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return) 1244/* Create a vector describing the result block RESULT. If SAVEP is true, 1245 the result block is used to save the values; otherwise it is used to 1246 restore the values. */ 1247 1248static rtx 1249result_vector (int savep, rtx result) 1250{ 1251 int regno, size, align, nelts; 1252 enum machine_mode mode; 1253 rtx reg, mem; 1254 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx)); 1255 1256 size = nelts = 0; 1257 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1258 if ((mode = apply_result_mode[regno]) != VOIDmode) 1259 { 1260 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1261 if (size % align != 0) 1262 size = CEIL (size, align) * align; 1263 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno)); 1264 mem = adjust_address (result, mode, size); 1265 savevec[nelts++] = (savep 1266 ? gen_rtx_SET (VOIDmode, mem, reg) 1267 : gen_rtx_SET (VOIDmode, reg, mem)); 1268 size += GET_MODE_SIZE (mode); 1269 } 1270 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec)); 1271} 1272#endif /* HAVE_untyped_call or HAVE_untyped_return */ 1273 1274/* Save the state required to perform an untyped call with the same 1275 arguments as were passed to the current function. */ 1276 1277static rtx 1278expand_builtin_apply_args_1 (void) 1279{ 1280 rtx registers, tem; 1281 int size, align, regno; 1282 enum machine_mode mode; 1283 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1); 1284 1285 /* Create a block where the arg-pointer, structure value address, 1286 and argument registers can be saved. */ 1287 registers = assign_stack_local (BLKmode, apply_args_size (), -1); 1288 1289 /* Walk past the arg-pointer and structure value address. */ 1290 size = GET_MODE_SIZE (Pmode); 1291 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0)) 1292 size += GET_MODE_SIZE (Pmode); 1293 1294 /* Save each register used in calling a function to the block. */ 1295 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1296 if ((mode = apply_args_mode[regno]) != VOIDmode) 1297 { 1298 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1299 if (size % align != 0) 1300 size = CEIL (size, align) * align; 1301 1302 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno)); 1303 1304 emit_move_insn (adjust_address (registers, mode, size), tem); 1305 size += GET_MODE_SIZE (mode); 1306 } 1307 1308 /* Save the arg pointer to the block. */ 1309 tem = copy_to_reg (virtual_incoming_args_rtx); 1310#ifdef STACK_GROWS_DOWNWARD 1311 /* We need the pointer as the caller actually passed them to us, not 1312 as we might have pretended they were passed. Make sure it's a valid 1313 operand, as emit_move_insn isn't expected to handle a PLUS. */ 1314 tem 1315 = force_operand (plus_constant (tem, current_function_pretend_args_size), 1316 NULL_RTX); 1317#endif 1318 emit_move_insn (adjust_address (registers, Pmode, 0), tem); 1319 1320 size = GET_MODE_SIZE (Pmode); 1321 1322 /* Save the structure value address unless this is passed as an 1323 "invisible" first argument. */ 1324 if (struct_incoming_value) 1325 { 1326 emit_move_insn (adjust_address (registers, Pmode, size), 1327 copy_to_reg (struct_incoming_value)); 1328 size += GET_MODE_SIZE (Pmode); 1329 } 1330 1331 /* Return the address of the block. */ 1332 return copy_addr_to_reg (XEXP (registers, 0)); 1333} 1334 1335/* __builtin_apply_args returns block of memory allocated on 1336 the stack into which is stored the arg pointer, structure 1337 value address, static chain, and all the registers that might 1338 possibly be used in performing a function call. The code is 1339 moved to the start of the function so the incoming values are 1340 saved. */ 1341 1342static rtx 1343expand_builtin_apply_args (void) 1344{ 1345 /* Don't do __builtin_apply_args more than once in a function. 1346 Save the result of the first call and reuse it. */ 1347 if (apply_args_value != 0) 1348 return apply_args_value; 1349 { 1350 /* When this function is called, it means that registers must be 1351 saved on entry to this function. So we migrate the 1352 call to the first insn of this function. */ 1353 rtx temp; 1354 rtx seq; 1355 1356 start_sequence (); 1357 temp = expand_builtin_apply_args_1 (); 1358 seq = get_insns (); 1359 end_sequence (); 1360 1361 apply_args_value = temp; 1362 1363 /* Put the insns after the NOTE that starts the function. 1364 If this is inside a start_sequence, make the outer-level insn 1365 chain current, so the code is placed at the start of the 1366 function. */ 1367 push_topmost_sequence (); 1368 emit_insn_before (seq, NEXT_INSN (entry_of_function ())); 1369 pop_topmost_sequence (); 1370 return temp; 1371 } 1372} 1373 1374/* Perform an untyped call and save the state required to perform an 1375 untyped return of whatever value was returned by the given function. */ 1376 1377static rtx 1378expand_builtin_apply (rtx function, rtx arguments, rtx argsize) 1379{ 1380 int size, align, regno; 1381 enum machine_mode mode; 1382 rtx incoming_args, result, reg, dest, src, call_insn; 1383 rtx old_stack_level = 0; 1384 rtx call_fusage = 0; 1385 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0); 1386 1387 arguments = convert_memory_address (Pmode, arguments); 1388 1389 /* Create a block where the return registers can be saved. */ 1390 result = assign_stack_local (BLKmode, apply_result_size (), -1); 1391 1392 /* Fetch the arg pointer from the ARGUMENTS block. */ 1393 incoming_args = gen_reg_rtx (Pmode); 1394 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments)); 1395#ifndef STACK_GROWS_DOWNWARD 1396 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize, 1397 incoming_args, 0, OPTAB_LIB_WIDEN); 1398#endif 1399 1400 /* Push a new argument block and copy the arguments. Do not allow 1401 the (potential) memcpy call below to interfere with our stack 1402 manipulations. */ 1403 do_pending_stack_adjust (); 1404 NO_DEFER_POP; 1405 1406 /* Save the stack with nonlocal if available. */ 1407#ifdef HAVE_save_stack_nonlocal 1408 if (HAVE_save_stack_nonlocal) 1409 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX); 1410 else 1411#endif 1412 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); 1413 1414 /* Allocate a block of memory onto the stack and copy the memory 1415 arguments to the outgoing arguments address. */ 1416 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT); 1417 dest = virtual_outgoing_args_rtx; 1418#ifndef STACK_GROWS_DOWNWARD 1419 if (GET_CODE (argsize) == CONST_INT) 1420 dest = plus_constant (dest, -INTVAL (argsize)); 1421 else 1422 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize)); 1423#endif 1424 dest = gen_rtx_MEM (BLKmode, dest); 1425 set_mem_align (dest, PARM_BOUNDARY); 1426 src = gen_rtx_MEM (BLKmode, incoming_args); 1427 set_mem_align (src, PARM_BOUNDARY); 1428 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL); 1429 1430 /* Refer to the argument block. */ 1431 apply_args_size (); 1432 arguments = gen_rtx_MEM (BLKmode, arguments); 1433 set_mem_align (arguments, PARM_BOUNDARY); 1434 1435 /* Walk past the arg-pointer and structure value address. */ 1436 size = GET_MODE_SIZE (Pmode); 1437 if (struct_value) 1438 size += GET_MODE_SIZE (Pmode); 1439 1440 /* Restore each of the registers previously saved. Make USE insns 1441 for each of these registers for use in making the call. */ 1442 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1443 if ((mode = apply_args_mode[regno]) != VOIDmode) 1444 { 1445 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1446 if (size % align != 0) 1447 size = CEIL (size, align) * align; 1448 reg = gen_rtx_REG (mode, regno); 1449 emit_move_insn (reg, adjust_address (arguments, mode, size)); 1450 use_reg (&call_fusage, reg); 1451 size += GET_MODE_SIZE (mode); 1452 } 1453 1454 /* Restore the structure value address unless this is passed as an 1455 "invisible" first argument. */ 1456 size = GET_MODE_SIZE (Pmode); 1457 if (struct_value) 1458 { 1459 rtx value = gen_reg_rtx (Pmode); 1460 emit_move_insn (value, adjust_address (arguments, Pmode, size)); 1461 emit_move_insn (struct_value, value); 1462 if (REG_P (struct_value)) 1463 use_reg (&call_fusage, struct_value); 1464 size += GET_MODE_SIZE (Pmode); 1465 } 1466 1467 /* All arguments and registers used for the call are set up by now! */ 1468 function = prepare_call_address (function, NULL, &call_fusage, 0, 0); 1469 1470 /* Ensure address is valid. SYMBOL_REF is already valid, so no need, 1471 and we don't want to load it into a register as an optimization, 1472 because prepare_call_address already did it if it should be done. */ 1473 if (GET_CODE (function) != SYMBOL_REF) 1474 function = memory_address (FUNCTION_MODE, function); 1475 1476 /* Generate the actual call instruction and save the return value. */ 1477#ifdef HAVE_untyped_call 1478 if (HAVE_untyped_call) 1479 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function), 1480 result, result_vector (1, result))); 1481 else 1482#endif 1483#ifdef HAVE_call_value 1484 if (HAVE_call_value) 1485 { 1486 rtx valreg = 0; 1487 1488 /* Locate the unique return register. It is not possible to 1489 express a call that sets more than one return register using 1490 call_value; use untyped_call for that. In fact, untyped_call 1491 only needs to save the return registers in the given block. */ 1492 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1493 if ((mode = apply_result_mode[regno]) != VOIDmode) 1494 { 1495 gcc_assert (!valreg); /* HAVE_untyped_call required. */ 1496 1497 valreg = gen_rtx_REG (mode, regno); 1498 } 1499 1500 emit_call_insn (GEN_CALL_VALUE (valreg, 1501 gen_rtx_MEM (FUNCTION_MODE, function), 1502 const0_rtx, NULL_RTX, const0_rtx)); 1503 1504 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg); 1505 } 1506 else 1507#endif 1508 gcc_unreachable (); 1509 1510 /* Find the CALL insn we just emitted, and attach the register usage 1511 information. */ 1512 call_insn = last_call_insn (); 1513 add_function_usage_to (call_insn, call_fusage); 1514 1515 /* Restore the stack. */ 1516#ifdef HAVE_save_stack_nonlocal 1517 if (HAVE_save_stack_nonlocal) 1518 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX); 1519 else 1520#endif 1521 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX); 1522 1523 OK_DEFER_POP; 1524 1525 /* Return the address of the result block. */ 1526 result = copy_addr_to_reg (XEXP (result, 0)); 1527 return convert_memory_address (ptr_mode, result); 1528} 1529 1530/* Perform an untyped return. */ 1531 1532static void 1533expand_builtin_return (rtx result) 1534{ 1535 int size, align, regno; 1536 enum machine_mode mode; 1537 rtx reg; 1538 rtx call_fusage = 0; 1539 1540 result = convert_memory_address (Pmode, result); 1541 1542 apply_result_size (); 1543 result = gen_rtx_MEM (BLKmode, result); 1544 1545#ifdef HAVE_untyped_return 1546 if (HAVE_untyped_return) 1547 { 1548 emit_jump_insn (gen_untyped_return (result, result_vector (0, result))); 1549 emit_barrier (); 1550 return; 1551 } 1552#endif 1553 1554 /* Restore the return value and note that each value is used. */ 1555 size = 0; 1556 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1557 if ((mode = apply_result_mode[regno]) != VOIDmode) 1558 { 1559 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1560 if (size % align != 0) 1561 size = CEIL (size, align) * align; 1562 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno)); 1563 emit_move_insn (reg, adjust_address (result, mode, size)); 1564 1565 push_to_sequence (call_fusage); 1566 emit_insn (gen_rtx_USE (VOIDmode, reg)); 1567 call_fusage = get_insns (); 1568 end_sequence (); 1569 size += GET_MODE_SIZE (mode); 1570 } 1571 1572 /* Put the USE insns before the return. */ 1573 emit_insn (call_fusage); 1574 1575 /* Return whatever values was restored by jumping directly to the end 1576 of the function. */ 1577 expand_naked_return (); 1578} 1579 1580/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */ 1581 1582static enum type_class 1583type_to_class (tree type) 1584{ 1585 switch (TREE_CODE (type)) 1586 { 1587 case VOID_TYPE: return void_type_class; 1588 case INTEGER_TYPE: return integer_type_class; 1589 case ENUMERAL_TYPE: return enumeral_type_class; 1590 case BOOLEAN_TYPE: return boolean_type_class; 1591 case POINTER_TYPE: return pointer_type_class; 1592 case REFERENCE_TYPE: return reference_type_class; 1593 case OFFSET_TYPE: return offset_type_class; 1594 case REAL_TYPE: return real_type_class; 1595 case COMPLEX_TYPE: return complex_type_class; 1596 case FUNCTION_TYPE: return function_type_class; 1597 case METHOD_TYPE: return method_type_class; 1598 case RECORD_TYPE: return record_type_class; 1599 case UNION_TYPE: 1600 case QUAL_UNION_TYPE: return union_type_class; 1601 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type) 1602 ? string_type_class : array_type_class); 1603 case LANG_TYPE: return lang_type_class; 1604 default: return no_type_class; 1605 } 1606} 1607 1608/* Expand a call to __builtin_classify_type with arguments found in 1609 ARGLIST. */ 1610 1611static rtx 1612expand_builtin_classify_type (tree arglist) 1613{ 1614 if (arglist != 0) 1615 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist)))); 1616 return GEN_INT (no_type_class); 1617} 1618 1619/* This helper macro, meant to be used in mathfn_built_in below, 1620 determines which among a set of three builtin math functions is 1621 appropriate for a given type mode. The `F' and `L' cases are 1622 automatically generated from the `double' case. */ 1623#define CASE_MATHFN(BUILT_IN_MATHFN) \ 1624 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \ 1625 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \ 1626 fcodel = BUILT_IN_MATHFN##L ; break; 1627 1628/* Return mathematic function equivalent to FN but operating directly 1629 on TYPE, if available. If we can't do the conversion, return zero. */ 1630tree 1631mathfn_built_in (tree type, enum built_in_function fn) 1632{ 1633 enum built_in_function fcode, fcodef, fcodel; 1634 1635 switch (fn) 1636 { 1637 CASE_MATHFN (BUILT_IN_ACOS) 1638 CASE_MATHFN (BUILT_IN_ACOSH) 1639 CASE_MATHFN (BUILT_IN_ASIN) 1640 CASE_MATHFN (BUILT_IN_ASINH) 1641 CASE_MATHFN (BUILT_IN_ATAN) 1642 CASE_MATHFN (BUILT_IN_ATAN2) 1643 CASE_MATHFN (BUILT_IN_ATANH) 1644 CASE_MATHFN (BUILT_IN_CBRT) 1645 CASE_MATHFN (BUILT_IN_CEIL) 1646 CASE_MATHFN (BUILT_IN_COPYSIGN) 1647 CASE_MATHFN (BUILT_IN_COS) 1648 CASE_MATHFN (BUILT_IN_COSH) 1649 CASE_MATHFN (BUILT_IN_DREM) 1650 CASE_MATHFN (BUILT_IN_ERF) 1651 CASE_MATHFN (BUILT_IN_ERFC) 1652 CASE_MATHFN (BUILT_IN_EXP) 1653 CASE_MATHFN (BUILT_IN_EXP10) 1654 CASE_MATHFN (BUILT_IN_EXP2) 1655 CASE_MATHFN (BUILT_IN_EXPM1) 1656 CASE_MATHFN (BUILT_IN_FABS) 1657 CASE_MATHFN (BUILT_IN_FDIM) 1658 CASE_MATHFN (BUILT_IN_FLOOR) 1659 CASE_MATHFN (BUILT_IN_FMA) 1660 CASE_MATHFN (BUILT_IN_FMAX) 1661 CASE_MATHFN (BUILT_IN_FMIN) 1662 CASE_MATHFN (BUILT_IN_FMOD) 1663 CASE_MATHFN (BUILT_IN_FREXP) 1664 CASE_MATHFN (BUILT_IN_GAMMA) 1665 CASE_MATHFN (BUILT_IN_HUGE_VAL) 1666 CASE_MATHFN (BUILT_IN_HYPOT) 1667 CASE_MATHFN (BUILT_IN_ILOGB) 1668 CASE_MATHFN (BUILT_IN_INF) 1669 CASE_MATHFN (BUILT_IN_J0) 1670 CASE_MATHFN (BUILT_IN_J1) 1671 CASE_MATHFN (BUILT_IN_JN) 1672 CASE_MATHFN (BUILT_IN_LCEIL) 1673 CASE_MATHFN (BUILT_IN_LDEXP) 1674 CASE_MATHFN (BUILT_IN_LFLOOR) 1675 CASE_MATHFN (BUILT_IN_LGAMMA) 1676 CASE_MATHFN (BUILT_IN_LLCEIL) 1677 CASE_MATHFN (BUILT_IN_LLFLOOR) 1678 CASE_MATHFN (BUILT_IN_LLRINT) 1679 CASE_MATHFN (BUILT_IN_LLROUND) 1680 CASE_MATHFN (BUILT_IN_LOG) 1681 CASE_MATHFN (BUILT_IN_LOG10) 1682 CASE_MATHFN (BUILT_IN_LOG1P) 1683 CASE_MATHFN (BUILT_IN_LOG2) 1684 CASE_MATHFN (BUILT_IN_LOGB) 1685 CASE_MATHFN (BUILT_IN_LRINT) 1686 CASE_MATHFN (BUILT_IN_LROUND) 1687 CASE_MATHFN (BUILT_IN_MODF) 1688 CASE_MATHFN (BUILT_IN_NAN) 1689 CASE_MATHFN (BUILT_IN_NANS) 1690 CASE_MATHFN (BUILT_IN_NEARBYINT) 1691 CASE_MATHFN (BUILT_IN_NEXTAFTER) 1692 CASE_MATHFN (BUILT_IN_NEXTTOWARD) 1693 CASE_MATHFN (BUILT_IN_POW) 1694 CASE_MATHFN (BUILT_IN_POWI) 1695 CASE_MATHFN (BUILT_IN_POW10) 1696 CASE_MATHFN (BUILT_IN_REMAINDER) 1697 CASE_MATHFN (BUILT_IN_REMQUO) 1698 CASE_MATHFN (BUILT_IN_RINT) 1699 CASE_MATHFN (BUILT_IN_ROUND) 1700 CASE_MATHFN (BUILT_IN_SCALB) 1701 CASE_MATHFN (BUILT_IN_SCALBLN) 1702 CASE_MATHFN (BUILT_IN_SCALBN) 1703 CASE_MATHFN (BUILT_IN_SIGNIFICAND) 1704 CASE_MATHFN (BUILT_IN_SIN) 1705 CASE_MATHFN (BUILT_IN_SINCOS) 1706 CASE_MATHFN (BUILT_IN_SINH) 1707 CASE_MATHFN (BUILT_IN_SQRT) 1708 CASE_MATHFN (BUILT_IN_TAN) 1709 CASE_MATHFN (BUILT_IN_TANH) 1710 CASE_MATHFN (BUILT_IN_TGAMMA) 1711 CASE_MATHFN (BUILT_IN_TRUNC) 1712 CASE_MATHFN (BUILT_IN_Y0) 1713 CASE_MATHFN (BUILT_IN_Y1) 1714 CASE_MATHFN (BUILT_IN_YN) 1715 1716 default: 1717 return 0; 1718 } 1719 1720 if (TYPE_MAIN_VARIANT (type) == double_type_node) 1721 return implicit_built_in_decls[fcode]; 1722 else if (TYPE_MAIN_VARIANT (type) == float_type_node) 1723 return implicit_built_in_decls[fcodef]; 1724 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node) 1725 return implicit_built_in_decls[fcodel]; 1726 else 1727 return 0; 1728} 1729 1730/* If errno must be maintained, expand the RTL to check if the result, 1731 TARGET, of a built-in function call, EXP, is NaN, and if so set 1732 errno to EDOM. */ 1733 1734static void 1735expand_errno_check (tree exp, rtx target) 1736{ 1737 rtx lab = gen_label_rtx (); 1738 1739 /* Test the result; if it is NaN, set errno=EDOM because 1740 the argument was not in the domain. */ 1741 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target), 1742 0, lab); 1743 1744#ifdef TARGET_EDOM 1745 /* If this built-in doesn't throw an exception, set errno directly. */ 1746 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) 1747 { 1748#ifdef GEN_ERRNO_RTX 1749 rtx errno_rtx = GEN_ERRNO_RTX; 1750#else 1751 rtx errno_rtx 1752 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno")); 1753#endif 1754 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM)); 1755 emit_label (lab); 1756 return; 1757 } 1758#endif 1759 1760 /* We can't set errno=EDOM directly; let the library call do it. 1761 Pop the arguments right away in case the call gets deleted. */ 1762 NO_DEFER_POP; 1763 expand_call (exp, target, 0); 1764 OK_DEFER_POP; 1765 emit_label (lab); 1766} 1767 1768 1769/* Expand a call to one of the builtin math functions (sqrt, exp, or log). 1770 Return 0 if a normal call should be emitted rather than expanding the 1771 function in-line. EXP is the expression that is a call to the builtin 1772 function; if convenient, the result should be placed in TARGET. 1773 SUBTARGET may be used as the target for computing one of EXP's operands. */ 1774 1775static rtx 1776expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) 1777{ 1778 optab builtin_optab; 1779 rtx op0, insns, before_call; 1780 tree fndecl = get_callee_fndecl (exp); 1781 tree arglist = TREE_OPERAND (exp, 1); 1782 enum machine_mode mode; 1783 bool errno_set = false; 1784 tree arg, narg; 1785 1786 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 1787 return 0; 1788 1789 arg = TREE_VALUE (arglist); 1790 1791 switch (DECL_FUNCTION_CODE (fndecl)) 1792 { 1793 CASE_FLT_FN (BUILT_IN_SQRT): 1794 errno_set = ! tree_expr_nonnegative_p (arg); 1795 builtin_optab = sqrt_optab; 1796 break; 1797 CASE_FLT_FN (BUILT_IN_EXP): 1798 errno_set = true; builtin_optab = exp_optab; break; 1799 CASE_FLT_FN (BUILT_IN_EXP10): 1800 CASE_FLT_FN (BUILT_IN_POW10): 1801 errno_set = true; builtin_optab = exp10_optab; break; 1802 CASE_FLT_FN (BUILT_IN_EXP2): 1803 errno_set = true; builtin_optab = exp2_optab; break; 1804 CASE_FLT_FN (BUILT_IN_EXPM1): 1805 errno_set = true; builtin_optab = expm1_optab; break; 1806 CASE_FLT_FN (BUILT_IN_LOGB): 1807 errno_set = true; builtin_optab = logb_optab; break; 1808 CASE_FLT_FN (BUILT_IN_ILOGB): 1809 errno_set = true; builtin_optab = ilogb_optab; break; 1810 CASE_FLT_FN (BUILT_IN_LOG): 1811 errno_set = true; builtin_optab = log_optab; break; 1812 CASE_FLT_FN (BUILT_IN_LOG10): 1813 errno_set = true; builtin_optab = log10_optab; break; 1814 CASE_FLT_FN (BUILT_IN_LOG2): 1815 errno_set = true; builtin_optab = log2_optab; break; 1816 CASE_FLT_FN (BUILT_IN_LOG1P): 1817 errno_set = true; builtin_optab = log1p_optab; break; 1818 CASE_FLT_FN (BUILT_IN_ASIN): 1819 builtin_optab = asin_optab; break; 1820 CASE_FLT_FN (BUILT_IN_ACOS): 1821 builtin_optab = acos_optab; break; 1822 CASE_FLT_FN (BUILT_IN_TAN): 1823 builtin_optab = tan_optab; break; 1824 CASE_FLT_FN (BUILT_IN_ATAN): 1825 builtin_optab = atan_optab; break; 1826 CASE_FLT_FN (BUILT_IN_FLOOR): 1827 builtin_optab = floor_optab; break; 1828 CASE_FLT_FN (BUILT_IN_CEIL): 1829 builtin_optab = ceil_optab; break; 1830 CASE_FLT_FN (BUILT_IN_TRUNC): 1831 builtin_optab = btrunc_optab; break; 1832 CASE_FLT_FN (BUILT_IN_ROUND): 1833 builtin_optab = round_optab; break; 1834 CASE_FLT_FN (BUILT_IN_NEARBYINT): 1835 builtin_optab = nearbyint_optab; break; 1836 CASE_FLT_FN (BUILT_IN_RINT): 1837 builtin_optab = rint_optab; break; 1838 CASE_FLT_FN (BUILT_IN_LRINT): 1839 CASE_FLT_FN (BUILT_IN_LLRINT): 1840 builtin_optab = lrint_optab; break; 1841 default: 1842 gcc_unreachable (); 1843 } 1844 1845 /* Make a suitable register to place result in. */ 1846 mode = TYPE_MODE (TREE_TYPE (exp)); 1847 1848 if (! flag_errno_math || ! HONOR_NANS (mode)) 1849 errno_set = false; 1850 1851 /* Before working hard, check whether the instruction is available. */ 1852 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 1853 { 1854 target = gen_reg_rtx (mode); 1855 1856 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 1857 need to expand the argument again. This way, we will not perform 1858 side-effects more the once. */ 1859 narg = builtin_save_expr (arg); 1860 if (narg != arg) 1861 { 1862 arg = narg; 1863 arglist = build_tree_list (NULL_TREE, arg); 1864 exp = build_function_call_expr (fndecl, arglist); 1865 } 1866 1867 op0 = expand_expr (arg, subtarget, VOIDmode, 0); 1868 1869 start_sequence (); 1870 1871 /* Compute into TARGET. 1872 Set TARGET to wherever the result comes back. */ 1873 target = expand_unop (mode, builtin_optab, op0, target, 0); 1874 1875 if (target != 0) 1876 { 1877 if (errno_set) 1878 expand_errno_check (exp, target); 1879 1880 /* Output the entire sequence. */ 1881 insns = get_insns (); 1882 end_sequence (); 1883 emit_insn (insns); 1884 return target; 1885 } 1886 1887 /* If we were unable to expand via the builtin, stop the sequence 1888 (without outputting the insns) and call to the library function 1889 with the stabilized argument list. */ 1890 end_sequence (); 1891 } 1892 1893 before_call = get_last_insn (); 1894 1895 target = expand_call (exp, target, target == const0_rtx); 1896 1897 /* If this is a sqrt operation and we don't care about errno, try to 1898 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall. 1899 This allows the semantics of the libcall to be visible to the RTL 1900 optimizers. */ 1901 if (builtin_optab == sqrt_optab && !errno_set) 1902 { 1903 /* Search backwards through the insns emitted by expand_call looking 1904 for the instruction with the REG_RETVAL note. */ 1905 rtx last = get_last_insn (); 1906 while (last != before_call) 1907 { 1908 if (find_reg_note (last, REG_RETVAL, NULL)) 1909 { 1910 rtx note = find_reg_note (last, REG_EQUAL, NULL); 1911 /* Check that the REQ_EQUAL note is an EXPR_LIST with 1912 two elements, i.e. symbol_ref(sqrt) and the operand. */ 1913 if (note 1914 && GET_CODE (note) == EXPR_LIST 1915 && GET_CODE (XEXP (note, 0)) == EXPR_LIST 1916 && XEXP (XEXP (note, 0), 1) != NULL_RTX 1917 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX) 1918 { 1919 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0); 1920 /* Check operand is a register with expected mode. */ 1921 if (operand 1922 && REG_P (operand) 1923 && GET_MODE (operand) == mode) 1924 { 1925 /* Replace the REG_EQUAL note with a SQRT rtx. */ 1926 rtx equiv = gen_rtx_SQRT (mode, operand); 1927 set_unique_reg_note (last, REG_EQUAL, equiv); 1928 } 1929 } 1930 break; 1931 } 1932 last = PREV_INSN (last); 1933 } 1934 } 1935 1936 return target; 1937} 1938 1939/* Expand a call to the builtin binary math functions (pow and atan2). 1940 Return 0 if a normal call should be emitted rather than expanding the 1941 function in-line. EXP is the expression that is a call to the builtin 1942 function; if convenient, the result should be placed in TARGET. 1943 SUBTARGET may be used as the target for computing one of EXP's 1944 operands. */ 1945 1946static rtx 1947expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget) 1948{ 1949 optab builtin_optab; 1950 rtx op0, op1, insns; 1951 int op1_type = REAL_TYPE; 1952 tree fndecl = get_callee_fndecl (exp); 1953 tree arglist = TREE_OPERAND (exp, 1); 1954 tree arg0, arg1, temp, narg; 1955 enum machine_mode mode; 1956 bool errno_set = true; 1957 bool stable = true; 1958 1959 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP) 1960 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF) 1961 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL)) 1962 op1_type = INTEGER_TYPE; 1963 1964 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE)) 1965 return 0; 1966 1967 arg0 = TREE_VALUE (arglist); 1968 arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 1969 1970 switch (DECL_FUNCTION_CODE (fndecl)) 1971 { 1972 CASE_FLT_FN (BUILT_IN_POW): 1973 builtin_optab = pow_optab; break; 1974 CASE_FLT_FN (BUILT_IN_ATAN2): 1975 builtin_optab = atan2_optab; break; 1976 CASE_FLT_FN (BUILT_IN_LDEXP): 1977 builtin_optab = ldexp_optab; break; 1978 CASE_FLT_FN (BUILT_IN_FMOD): 1979 builtin_optab = fmod_optab; break; 1980 CASE_FLT_FN (BUILT_IN_DREM): 1981 builtin_optab = drem_optab; break; 1982 default: 1983 gcc_unreachable (); 1984 } 1985 1986 /* Make a suitable register to place result in. */ 1987 mode = TYPE_MODE (TREE_TYPE (exp)); 1988 1989 /* Before working hard, check whether the instruction is available. */ 1990 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) 1991 return 0; 1992 1993 target = gen_reg_rtx (mode); 1994 1995 if (! flag_errno_math || ! HONOR_NANS (mode)) 1996 errno_set = false; 1997 1998 /* Always stabilize the argument list. */ 1999 narg = builtin_save_expr (arg1); 2000 if (narg != arg1) 2001 { 2002 arg1 = narg; 2003 temp = build_tree_list (NULL_TREE, narg); 2004 stable = false; 2005 } 2006 else 2007 temp = TREE_CHAIN (arglist); 2008 2009 narg = builtin_save_expr (arg0); 2010 if (narg != arg0) 2011 { 2012 arg0 = narg; 2013 arglist = tree_cons (NULL_TREE, narg, temp); 2014 stable = false; 2015 } 2016 else if (! stable) 2017 arglist = tree_cons (NULL_TREE, arg0, temp); 2018 2019 if (! stable) 2020 exp = build_function_call_expr (fndecl, arglist); 2021 2022 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL); 2023 op1 = expand_normal (arg1); 2024 2025 start_sequence (); 2026 2027 /* Compute into TARGET. 2028 Set TARGET to wherever the result comes back. */ 2029 target = expand_binop (mode, builtin_optab, op0, op1, 2030 target, 0, OPTAB_DIRECT); 2031 2032 /* If we were unable to expand via the builtin, stop the sequence 2033 (without outputting the insns) and call to the library function 2034 with the stabilized argument list. */ 2035 if (target == 0) 2036 { 2037 end_sequence (); 2038 return expand_call (exp, target, target == const0_rtx); 2039 } 2040 2041 if (errno_set) 2042 expand_errno_check (exp, target); 2043 2044 /* Output the entire sequence. */ 2045 insns = get_insns (); 2046 end_sequence (); 2047 emit_insn (insns); 2048 2049 return target; 2050} 2051 2052/* Expand a call to the builtin sin and cos math functions. 2053 Return 0 if a normal call should be emitted rather than expanding the 2054 function in-line. EXP is the expression that is a call to the builtin 2055 function; if convenient, the result should be placed in TARGET. 2056 SUBTARGET may be used as the target for computing one of EXP's 2057 operands. */ 2058 2059static rtx 2060expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget) 2061{ 2062 optab builtin_optab; 2063 rtx op0, insns; 2064 tree fndecl = get_callee_fndecl (exp); 2065 tree arglist = TREE_OPERAND (exp, 1); 2066 enum machine_mode mode; 2067 tree arg, narg; 2068 2069 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 2070 return 0; 2071 2072 arg = TREE_VALUE (arglist); 2073 2074 switch (DECL_FUNCTION_CODE (fndecl)) 2075 { 2076 CASE_FLT_FN (BUILT_IN_SIN): 2077 CASE_FLT_FN (BUILT_IN_COS): 2078 builtin_optab = sincos_optab; break; 2079 default: 2080 gcc_unreachable (); 2081 } 2082 2083 /* Make a suitable register to place result in. */ 2084 mode = TYPE_MODE (TREE_TYPE (exp)); 2085 2086 /* Check if sincos insn is available, otherwise fallback 2087 to sin or cos insn. */ 2088 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) { 2089 switch (DECL_FUNCTION_CODE (fndecl)) 2090 { 2091 CASE_FLT_FN (BUILT_IN_SIN): 2092 builtin_optab = sin_optab; break; 2093 CASE_FLT_FN (BUILT_IN_COS): 2094 builtin_optab = cos_optab; break; 2095 default: 2096 gcc_unreachable (); 2097 } 2098 } 2099 2100 /* Before working hard, check whether the instruction is available. */ 2101 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 2102 { 2103 target = gen_reg_rtx (mode); 2104 2105 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2106 need to expand the argument again. This way, we will not perform 2107 side-effects more the once. */ 2108 narg = save_expr (arg); 2109 if (narg != arg) 2110 { 2111 arg = narg; 2112 arglist = build_tree_list (NULL_TREE, arg); 2113 exp = build_function_call_expr (fndecl, arglist); 2114 } 2115 2116 op0 = expand_expr (arg, subtarget, VOIDmode, 0); 2117 2118 start_sequence (); 2119 2120 /* Compute into TARGET. 2121 Set TARGET to wherever the result comes back. */ 2122 if (builtin_optab == sincos_optab) 2123 { 2124 int result; 2125 2126 switch (DECL_FUNCTION_CODE (fndecl)) 2127 { 2128 CASE_FLT_FN (BUILT_IN_SIN): 2129 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0); 2130 break; 2131 CASE_FLT_FN (BUILT_IN_COS): 2132 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0); 2133 break; 2134 default: 2135 gcc_unreachable (); 2136 } 2137 gcc_assert (result); 2138 } 2139 else 2140 { 2141 target = expand_unop (mode, builtin_optab, op0, target, 0); 2142 } 2143 2144 if (target != 0) 2145 { 2146 /* Output the entire sequence. */ 2147 insns = get_insns (); 2148 end_sequence (); 2149 emit_insn (insns); 2150 return target; 2151 } 2152 2153 /* If we were unable to expand via the builtin, stop the sequence 2154 (without outputting the insns) and call to the library function 2155 with the stabilized argument list. */ 2156 end_sequence (); 2157 } 2158 2159 target = expand_call (exp, target, target == const0_rtx); 2160 2161 return target; 2162} 2163 2164/* Expand a call to the builtin sincos math function. 2165 Return 0 if a normal call should be emitted rather than expanding the 2166 function in-line. EXP is the expression that is a call to the builtin 2167 function. */ 2168 2169static rtx 2170expand_builtin_sincos (tree exp) 2171{ 2172 rtx op0, op1, op2, target1, target2; 2173 tree arglist = TREE_OPERAND (exp, 1); 2174 enum machine_mode mode; 2175 tree arg, sinp, cosp; 2176 int result; 2177 2178 if (!validate_arglist (arglist, REAL_TYPE, 2179 POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 2180 return 0; 2181 2182 arg = TREE_VALUE (arglist); 2183 sinp = TREE_VALUE (TREE_CHAIN (arglist)); 2184 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 2185 2186 /* Make a suitable register to place result in. */ 2187 mode = TYPE_MODE (TREE_TYPE (arg)); 2188 2189 /* Check if sincos insn is available, otherwise emit the call. */ 2190 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) 2191 return NULL_RTX; 2192 2193 target1 = gen_reg_rtx (mode); 2194 target2 = gen_reg_rtx (mode); 2195 2196 op0 = expand_normal (arg); 2197 op1 = expand_normal (build_fold_indirect_ref (sinp)); 2198 op2 = expand_normal (build_fold_indirect_ref (cosp)); 2199 2200 /* Compute into target1 and target2. 2201 Set TARGET to wherever the result comes back. */ 2202 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0); 2203 gcc_assert (result); 2204 2205 /* Move target1 and target2 to the memory locations indicated 2206 by op1 and op2. */ 2207 emit_move_insn (op1, target1); 2208 emit_move_insn (op2, target2); 2209 2210 return const0_rtx; 2211} 2212 2213/* Expand a call to one of the builtin rounding functions (lfloor). 2214 If expanding via optab fails, lower expression to (int)(floor(x)). 2215 EXP is the expression that is a call to the builtin function; 2216 if convenient, the result should be placed in TARGET. SUBTARGET may 2217 be used as the target for computing one of EXP's operands. */ 2218 2219static rtx 2220expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget) 2221{ 2222 optab builtin_optab; 2223 rtx op0, insns, tmp; 2224 tree fndecl = get_callee_fndecl (exp); 2225 tree arglist = TREE_OPERAND (exp, 1); 2226 enum built_in_function fallback_fn; 2227 tree fallback_fndecl; 2228 enum machine_mode mode; 2229 tree arg, narg; 2230 2231 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 2232 gcc_unreachable (); 2233 2234 arg = TREE_VALUE (arglist); 2235 2236 switch (DECL_FUNCTION_CODE (fndecl)) 2237 { 2238 CASE_FLT_FN (BUILT_IN_LCEIL): 2239 CASE_FLT_FN (BUILT_IN_LLCEIL): 2240 builtin_optab = lceil_optab; 2241 fallback_fn = BUILT_IN_CEIL; 2242 break; 2243 2244 CASE_FLT_FN (BUILT_IN_LFLOOR): 2245 CASE_FLT_FN (BUILT_IN_LLFLOOR): 2246 builtin_optab = lfloor_optab; 2247 fallback_fn = BUILT_IN_FLOOR; 2248 break; 2249 2250 default: 2251 gcc_unreachable (); 2252 } 2253 2254 /* Make a suitable register to place result in. */ 2255 mode = TYPE_MODE (TREE_TYPE (exp)); 2256 2257 /* Before working hard, check whether the instruction is available. */ 2258 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 2259 { 2260 target = gen_reg_rtx (mode); 2261 2262 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 2263 need to expand the argument again. This way, we will not perform 2264 side-effects more the once. */ 2265 narg = builtin_save_expr (arg); 2266 if (narg != arg) 2267 { 2268 arg = narg; 2269 arglist = build_tree_list (NULL_TREE, arg); 2270 exp = build_function_call_expr (fndecl, arglist); 2271 } 2272 2273 op0 = expand_expr (arg, subtarget, VOIDmode, 0); 2274 2275 start_sequence (); 2276 2277 /* Compute into TARGET. 2278 Set TARGET to wherever the result comes back. */ 2279 target = expand_unop (mode, builtin_optab, op0, target, 0); 2280 2281 if (target != 0) 2282 { 2283 /* Output the entire sequence. */ 2284 insns = get_insns (); 2285 end_sequence (); 2286 emit_insn (insns); 2287 return target; 2288 } 2289 2290 /* If we were unable to expand via the builtin, stop the sequence 2291 (without outputting the insns). */ 2292 end_sequence (); 2293 } 2294 2295 /* Fall back to floating point rounding optab. */ 2296 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn); 2297 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS. 2298 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */ 2299 gcc_assert (fallback_fndecl != NULL_TREE); 2300 exp = build_function_call_expr (fallback_fndecl, arglist); 2301 2302 tmp = expand_normal (exp); 2303 2304 /* Truncate the result of floating point optab to integer 2305 via expand_fix (). */ 2306 target = gen_reg_rtx (mode); 2307 expand_fix (target, tmp, 0); 2308 2309 return target; 2310} 2311 2312/* To evaluate powi(x,n), the floating point value x raised to the 2313 constant integer exponent n, we use a hybrid algorithm that 2314 combines the "window method" with look-up tables. For an 2315 introduction to exponentiation algorithms and "addition chains", 2316 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth, 2317 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming", 2318 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation 2319 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */ 2320 2321/* Provide a default value for POWI_MAX_MULTS, the maximum number of 2322 multiplications to inline before calling the system library's pow 2323 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications, 2324 so this default never requires calling pow, powf or powl. */ 2325 2326#ifndef POWI_MAX_MULTS 2327#define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2) 2328#endif 2329 2330/* The size of the "optimal power tree" lookup table. All 2331 exponents less than this value are simply looked up in the 2332 powi_table below. This threshold is also used to size the 2333 cache of pseudo registers that hold intermediate results. */ 2334#define POWI_TABLE_SIZE 256 2335 2336/* The size, in bits of the window, used in the "window method" 2337 exponentiation algorithm. This is equivalent to a radix of 2338 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */ 2339#define POWI_WINDOW_SIZE 3 2340 2341/* The following table is an efficient representation of an 2342 "optimal power tree". For each value, i, the corresponding 2343 value, j, in the table states than an optimal evaluation 2344 sequence for calculating pow(x,i) can be found by evaluating 2345 pow(x,j)*pow(x,i-j). An optimal power tree for the first 2346 100 integers is given in Knuth's "Seminumerical algorithms". */ 2347 2348static const unsigned char powi_table[POWI_TABLE_SIZE] = 2349 { 2350 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */ 2351 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */ 2352 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */ 2353 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */ 2354 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */ 2355 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */ 2356 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */ 2357 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */ 2358 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */ 2359 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */ 2360 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */ 2361 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */ 2362 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */ 2363 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */ 2364 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */ 2365 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */ 2366 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */ 2367 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */ 2368 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */ 2369 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */ 2370 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */ 2371 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */ 2372 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */ 2373 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */ 2374 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */ 2375 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */ 2376 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */ 2377 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */ 2378 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */ 2379 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */ 2380 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */ 2381 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */ 2382 }; 2383 2384 2385/* Return the number of multiplications required to calculate 2386 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a 2387 subroutine of powi_cost. CACHE is an array indicating 2388 which exponents have already been calculated. */ 2389 2390static int 2391powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache) 2392{ 2393 /* If we've already calculated this exponent, then this evaluation 2394 doesn't require any additional multiplications. */ 2395 if (cache[n]) 2396 return 0; 2397 2398 cache[n] = true; 2399 return powi_lookup_cost (n - powi_table[n], cache) 2400 + powi_lookup_cost (powi_table[n], cache) + 1; 2401} 2402 2403/* Return the number of multiplications required to calculate 2404 powi(x,n) for an arbitrary x, given the exponent N. This 2405 function needs to be kept in sync with expand_powi below. */ 2406 2407static int 2408powi_cost (HOST_WIDE_INT n) 2409{ 2410 bool cache[POWI_TABLE_SIZE]; 2411 unsigned HOST_WIDE_INT digit; 2412 unsigned HOST_WIDE_INT val; 2413 int result; 2414 2415 if (n == 0) 2416 return 0; 2417 2418 /* Ignore the reciprocal when calculating the cost. */ 2419 val = (n < 0) ? -n : n; 2420 2421 /* Initialize the exponent cache. */ 2422 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool)); 2423 cache[1] = true; 2424 2425 result = 0; 2426 2427 while (val >= POWI_TABLE_SIZE) 2428 { 2429 if (val & 1) 2430 { 2431 digit = val & ((1 << POWI_WINDOW_SIZE) - 1); 2432 result += powi_lookup_cost (digit, cache) 2433 + POWI_WINDOW_SIZE + 1; 2434 val >>= POWI_WINDOW_SIZE; 2435 } 2436 else 2437 { 2438 val >>= 1; 2439 result++; 2440 } 2441 } 2442 2443 return result + powi_lookup_cost (val, cache); 2444} 2445 2446/* Recursive subroutine of expand_powi. This function takes the array, 2447 CACHE, of already calculated exponents and an exponent N and returns 2448 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */ 2449 2450static rtx 2451expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache) 2452{ 2453 unsigned HOST_WIDE_INT digit; 2454 rtx target, result; 2455 rtx op0, op1; 2456 2457 if (n < POWI_TABLE_SIZE) 2458 { 2459 if (cache[n]) 2460 return cache[n]; 2461 2462 target = gen_reg_rtx (mode); 2463 cache[n] = target; 2464 2465 op0 = expand_powi_1 (mode, n - powi_table[n], cache); 2466 op1 = expand_powi_1 (mode, powi_table[n], cache); 2467 } 2468 else if (n & 1) 2469 { 2470 target = gen_reg_rtx (mode); 2471 digit = n & ((1 << POWI_WINDOW_SIZE) - 1); 2472 op0 = expand_powi_1 (mode, n - digit, cache); 2473 op1 = expand_powi_1 (mode, digit, cache); 2474 } 2475 else 2476 { 2477 target = gen_reg_rtx (mode); 2478 op0 = expand_powi_1 (mode, n >> 1, cache); 2479 op1 = op0; 2480 } 2481 2482 result = expand_mult (mode, op0, op1, target, 0); 2483 if (result != target) 2484 emit_move_insn (target, result); 2485 return target; 2486} 2487 2488/* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the 2489 floating point operand in mode MODE, and N is the exponent. This 2490 function needs to be kept in sync with powi_cost above. */ 2491 2492static rtx 2493expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n) 2494{ 2495 unsigned HOST_WIDE_INT val; 2496 rtx cache[POWI_TABLE_SIZE]; 2497 rtx result; 2498 2499 if (n == 0) 2500 return CONST1_RTX (mode); 2501 2502 val = (n < 0) ? -n : n; 2503 2504 memset (cache, 0, sizeof (cache)); 2505 cache[1] = x; 2506 2507 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache); 2508 2509 /* If the original exponent was negative, reciprocate the result. */ 2510 if (n < 0) 2511 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode), 2512 result, NULL_RTX, 0, OPTAB_LIB_WIDEN); 2513 2514 return result; 2515} 2516 2517/* Expand a call to the pow built-in mathematical function. Return 0 if 2518 a normal call should be emitted rather than expanding the function 2519 in-line. EXP is the expression that is a call to the builtin 2520 function; if convenient, the result should be placed in TARGET. */ 2521 2522static rtx 2523expand_builtin_pow (tree exp, rtx target, rtx subtarget) 2524{ 2525 tree arglist = TREE_OPERAND (exp, 1); 2526 tree arg0, arg1; 2527 2528 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 2529 return 0; 2530 2531 arg0 = TREE_VALUE (arglist); 2532 arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 2533 2534 if (TREE_CODE (arg1) == REAL_CST 2535 && ! TREE_CONSTANT_OVERFLOW (arg1)) 2536 { 2537 REAL_VALUE_TYPE cint; 2538 REAL_VALUE_TYPE c; 2539 HOST_WIDE_INT n; 2540 2541 c = TREE_REAL_CST (arg1); 2542 n = real_to_integer (&c); 2543 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); 2544 if (real_identical (&c, &cint)) 2545 { 2546 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact. 2547 Otherwise, check the number of multiplications required. 2548 Note that pow never sets errno for an integer exponent. */ 2549 if ((n >= -1 && n <= 2) 2550 || (flag_unsafe_math_optimizations 2551 && ! optimize_size 2552 && powi_cost (n) <= POWI_MAX_MULTS)) 2553 { 2554 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); 2555 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0); 2556 op = force_reg (mode, op); 2557 return expand_powi (op, mode, n); 2558 } 2559 } 2560 } 2561 2562 if (! flag_unsafe_math_optimizations) 2563 return NULL_RTX; 2564 return expand_builtin_mathfn_2 (exp, target, subtarget); 2565} 2566 2567/* Expand a call to the powi built-in mathematical function. Return 0 if 2568 a normal call should be emitted rather than expanding the function 2569 in-line. EXP is the expression that is a call to the builtin 2570 function; if convenient, the result should be placed in TARGET. */ 2571 2572static rtx 2573expand_builtin_powi (tree exp, rtx target, rtx subtarget) 2574{ 2575 tree arglist = TREE_OPERAND (exp, 1); 2576 tree arg0, arg1; 2577 rtx op0, op1; 2578 enum machine_mode mode; 2579 enum machine_mode mode2; 2580 2581 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE)) 2582 return 0; 2583 2584 arg0 = TREE_VALUE (arglist); 2585 arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 2586 mode = TYPE_MODE (TREE_TYPE (exp)); 2587 2588 /* Handle constant power. */ 2589 2590 if (TREE_CODE (arg1) == INTEGER_CST 2591 && ! TREE_CONSTANT_OVERFLOW (arg1)) 2592 { 2593 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1); 2594 2595 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact. 2596 Otherwise, check the number of multiplications required. */ 2597 if ((TREE_INT_CST_HIGH (arg1) == 0 2598 || TREE_INT_CST_HIGH (arg1) == -1) 2599 && ((n >= -1 && n <= 2) 2600 || (! optimize_size 2601 && powi_cost (n) <= POWI_MAX_MULTS))) 2602 { 2603 op0 = expand_expr (arg0, subtarget, VOIDmode, 0); 2604 op0 = force_reg (mode, op0); 2605 return expand_powi (op0, mode, n); 2606 } 2607 } 2608 2609 /* Emit a libcall to libgcc. */ 2610 2611 /* Mode of the 2nd argument must match that of an int. */ 2612 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0); 2613 2614 if (target == NULL_RTX) 2615 target = gen_reg_rtx (mode); 2616 2617 op0 = expand_expr (arg0, subtarget, mode, 0); 2618 if (GET_MODE (op0) != mode) 2619 op0 = convert_to_mode (mode, op0, 0); 2620 op1 = expand_expr (arg1, 0, mode2, 0); 2621 if (GET_MODE (op1) != mode2) 2622 op1 = convert_to_mode (mode2, op1, 0); 2623 2624 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc, 2625 target, LCT_CONST_MAKE_BLOCK, mode, 2, 2626 op0, mode, op1, mode2); 2627 2628 return target; 2629} 2630 2631/* Expand expression EXP which is a call to the strlen builtin. Return 0 2632 if we failed the caller should emit a normal call, otherwise 2633 try to get the result in TARGET, if convenient. */ 2634 2635static rtx 2636expand_builtin_strlen (tree arglist, rtx target, 2637 enum machine_mode target_mode) 2638{ 2639 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 2640 return 0; 2641 else 2642 { 2643 rtx pat; 2644 tree len, src = TREE_VALUE (arglist); 2645 rtx result, src_reg, char_rtx, before_strlen; 2646 enum machine_mode insn_mode = target_mode, char_mode; 2647 enum insn_code icode = CODE_FOR_nothing; 2648 int align; 2649 2650 /* If the length can be computed at compile-time, return it. */ 2651 len = c_strlen (src, 0); 2652 if (len) 2653 return expand_expr (len, target, target_mode, EXPAND_NORMAL); 2654 2655 /* If the length can be computed at compile-time and is constant 2656 integer, but there are side-effects in src, evaluate 2657 src for side-effects, then return len. 2658 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar"); 2659 can be optimized into: i++; x = 3; */ 2660 len = c_strlen (src, 1); 2661 if (len && TREE_CODE (len) == INTEGER_CST) 2662 { 2663 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL); 2664 return expand_expr (len, target, target_mode, EXPAND_NORMAL); 2665 } 2666 2667 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 2668 2669 /* If SRC is not a pointer type, don't do this operation inline. */ 2670 if (align == 0) 2671 return 0; 2672 2673 /* Bail out if we can't compute strlen in the right mode. */ 2674 while (insn_mode != VOIDmode) 2675 { 2676 icode = strlen_optab->handlers[(int) insn_mode].insn_code; 2677 if (icode != CODE_FOR_nothing) 2678 break; 2679 2680 insn_mode = GET_MODE_WIDER_MODE (insn_mode); 2681 } 2682 if (insn_mode == VOIDmode) 2683 return 0; 2684 2685 /* Make a place to write the result of the instruction. */ 2686 result = target; 2687 if (! (result != 0 2688 && REG_P (result) 2689 && GET_MODE (result) == insn_mode 2690 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 2691 result = gen_reg_rtx (insn_mode); 2692 2693 /* Make a place to hold the source address. We will not expand 2694 the actual source until we are sure that the expansion will 2695 not fail -- there are trees that cannot be expanded twice. */ 2696 src_reg = gen_reg_rtx (Pmode); 2697 2698 /* Mark the beginning of the strlen sequence so we can emit the 2699 source operand later. */ 2700 before_strlen = get_last_insn (); 2701 2702 char_rtx = const0_rtx; 2703 char_mode = insn_data[(int) icode].operand[2].mode; 2704 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx, 2705 char_mode)) 2706 char_rtx = copy_to_mode_reg (char_mode, char_rtx); 2707 2708 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg), 2709 char_rtx, GEN_INT (align)); 2710 if (! pat) 2711 return 0; 2712 emit_insn (pat); 2713 2714 /* Now that we are assured of success, expand the source. */ 2715 start_sequence (); 2716 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL); 2717 if (pat != src_reg) 2718 emit_move_insn (src_reg, pat); 2719 pat = get_insns (); 2720 end_sequence (); 2721 2722 if (before_strlen) 2723 emit_insn_after (pat, before_strlen); 2724 else 2725 emit_insn_before (pat, get_insns ()); 2726 2727 /* Return the value in the proper mode for this function. */ 2728 if (GET_MODE (result) == target_mode) 2729 target = result; 2730 else if (target != 0) 2731 convert_move (target, result, 0); 2732 else 2733 target = convert_to_mode (target_mode, result, 0); 2734 2735 return target; 2736 } 2737} 2738 2739/* Expand a call to the strstr builtin. Return 0 if we failed the 2740 caller should emit a normal call, otherwise try to get the result 2741 in TARGET, if convenient (and in mode MODE if that's convenient). */ 2742 2743static rtx 2744expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode) 2745{ 2746 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 2747 { 2748 tree result = fold_builtin_strstr (arglist, type); 2749 if (result) 2750 return expand_expr (result, target, mode, EXPAND_NORMAL); 2751 } 2752 return 0; 2753} 2754 2755/* Expand a call to the strchr builtin. Return 0 if we failed the 2756 caller should emit a normal call, otherwise try to get the result 2757 in TARGET, if convenient (and in mode MODE if that's convenient). */ 2758 2759static rtx 2760expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode) 2761{ 2762 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2763 { 2764 tree result = fold_builtin_strchr (arglist, type); 2765 if (result) 2766 return expand_expr (result, target, mode, EXPAND_NORMAL); 2767 2768 /* FIXME: Should use strchrM optab so that ports can optimize this. */ 2769 } 2770 return 0; 2771} 2772 2773/* Expand a call to the strrchr builtin. Return 0 if we failed the 2774 caller should emit a normal call, otherwise try to get the result 2775 in TARGET, if convenient (and in mode MODE if that's convenient). */ 2776 2777static rtx 2778expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode) 2779{ 2780 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2781 { 2782 tree result = fold_builtin_strrchr (arglist, type); 2783 if (result) 2784 return expand_expr (result, target, mode, EXPAND_NORMAL); 2785 } 2786 return 0; 2787} 2788 2789/* Expand a call to the strpbrk builtin. Return 0 if we failed the 2790 caller should emit a normal call, otherwise try to get the result 2791 in TARGET, if convenient (and in mode MODE if that's convenient). */ 2792 2793static rtx 2794expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode) 2795{ 2796 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 2797 { 2798 tree result = fold_builtin_strpbrk (arglist, type); 2799 if (result) 2800 return expand_expr (result, target, mode, EXPAND_NORMAL); 2801 } 2802 return 0; 2803} 2804 2805/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 2806 bytes from constant string DATA + OFFSET and return it as target 2807 constant. */ 2808 2809static rtx 2810builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset, 2811 enum machine_mode mode) 2812{ 2813 const char *str = (const char *) data; 2814 2815 gcc_assert (offset >= 0 2816 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode) 2817 <= strlen (str) + 1)); 2818 2819 return c_readstr (str + offset, mode); 2820} 2821 2822/* Expand a call to the memcpy builtin, with arguments in ARGLIST. 2823 Return 0 if we failed, the caller should emit a normal call, 2824 otherwise try to get the result in TARGET, if convenient (and in 2825 mode MODE if that's convenient). */ 2826static rtx 2827expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode) 2828{ 2829 tree fndecl = get_callee_fndecl (exp); 2830 tree arglist = TREE_OPERAND (exp, 1); 2831 if (!validate_arglist (arglist, 2832 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2833 return 0; 2834 else 2835 { 2836 tree dest = TREE_VALUE (arglist); 2837 tree src = TREE_VALUE (TREE_CHAIN (arglist)); 2838 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 2839 const char *src_str; 2840 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 2841 unsigned int dest_align 2842 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 2843 rtx dest_mem, src_mem, dest_addr, len_rtx; 2844 tree result = fold_builtin_memory_op (arglist, TREE_TYPE (TREE_TYPE (fndecl)), 2845 false, /*endp=*/0); 2846 2847 if (result) 2848 { 2849 while (TREE_CODE (result) == COMPOUND_EXPR) 2850 { 2851 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode, 2852 EXPAND_NORMAL); 2853 result = TREE_OPERAND (result, 1); 2854 } 2855 return expand_expr (result, target, mode, EXPAND_NORMAL); 2856 } 2857 2858 /* If DEST is not a pointer type, call the normal function. */ 2859 if (dest_align == 0) 2860 return 0; 2861 2862 /* If either SRC is not a pointer type, don't do this 2863 operation in-line. */ 2864 if (src_align == 0) 2865 return 0; 2866 2867 dest_mem = get_memory_rtx (dest, len); 2868 set_mem_align (dest_mem, dest_align); 2869 len_rtx = expand_normal (len); 2870 src_str = c_getstr (src); 2871 2872 /* If SRC is a string constant and block move would be done 2873 by pieces, we can avoid loading the string from memory 2874 and only stored the computed constants. */ 2875 if (src_str 2876 && GET_CODE (len_rtx) == CONST_INT 2877 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1 2878 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str, 2879 (void *) src_str, dest_align)) 2880 { 2881 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx), 2882 builtin_memcpy_read_str, 2883 (void *) src_str, dest_align, 0); 2884 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 2885 dest_mem = convert_memory_address (ptr_mode, dest_mem); 2886 return dest_mem; 2887 } 2888 2889 src_mem = get_memory_rtx (src, len); 2890 set_mem_align (src_mem, src_align); 2891 2892 /* Copy word part most expediently. */ 2893 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx, 2894 CALL_EXPR_TAILCALL (exp) 2895 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL); 2896 2897 if (dest_addr == 0) 2898 { 2899 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); 2900 dest_addr = convert_memory_address (ptr_mode, dest_addr); 2901 } 2902 return dest_addr; 2903 } 2904} 2905 2906/* Expand a call to the mempcpy builtin, with arguments in ARGLIST. 2907 Return 0 if we failed; the caller should emit a normal call, 2908 otherwise try to get the result in TARGET, if convenient (and in 2909 mode MODE if that's convenient). If ENDP is 0 return the 2910 destination pointer, if ENDP is 1 return the end pointer ala 2911 mempcpy, and if ENDP is 2 return the end pointer minus one ala 2912 stpcpy. */ 2913 2914static rtx 2915expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode, 2916 int endp) 2917{ 2918 if (!validate_arglist (arglist, 2919 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2920 return 0; 2921 /* If return value is ignored, transform mempcpy into memcpy. */ 2922 else if (target == const0_rtx) 2923 { 2924 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 2925 2926 if (!fn) 2927 return 0; 2928 2929 return expand_expr (build_function_call_expr (fn, arglist), 2930 target, mode, EXPAND_NORMAL); 2931 } 2932 else 2933 { 2934 tree dest = TREE_VALUE (arglist); 2935 tree src = TREE_VALUE (TREE_CHAIN (arglist)); 2936 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 2937 const char *src_str; 2938 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 2939 unsigned int dest_align 2940 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 2941 rtx dest_mem, src_mem, len_rtx; 2942 tree result = fold_builtin_memory_op (arglist, type, false, endp); 2943 2944 if (result) 2945 { 2946 while (TREE_CODE (result) == COMPOUND_EXPR) 2947 { 2948 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode, 2949 EXPAND_NORMAL); 2950 result = TREE_OPERAND (result, 1); 2951 } 2952 return expand_expr (result, target, mode, EXPAND_NORMAL); 2953 } 2954 2955 /* If either SRC or DEST is not a pointer type, don't do this 2956 operation in-line. */ 2957 if (dest_align == 0 || src_align == 0) 2958 return 0; 2959 2960 /* If LEN is not constant, call the normal function. */ 2961 if (! host_integerp (len, 1)) 2962 return 0; 2963 2964 len_rtx = expand_normal (len); 2965 src_str = c_getstr (src); 2966 2967 /* If SRC is a string constant and block move would be done 2968 by pieces, we can avoid loading the string from memory 2969 and only stored the computed constants. */ 2970 if (src_str 2971 && GET_CODE (len_rtx) == CONST_INT 2972 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1 2973 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str, 2974 (void *) src_str, dest_align)) 2975 { 2976 dest_mem = get_memory_rtx (dest, len); 2977 set_mem_align (dest_mem, dest_align); 2978 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx), 2979 builtin_memcpy_read_str, 2980 (void *) src_str, dest_align, endp); 2981 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 2982 dest_mem = convert_memory_address (ptr_mode, dest_mem); 2983 return dest_mem; 2984 } 2985 2986 if (GET_CODE (len_rtx) == CONST_INT 2987 && can_move_by_pieces (INTVAL (len_rtx), 2988 MIN (dest_align, src_align))) 2989 { 2990 dest_mem = get_memory_rtx (dest, len); 2991 set_mem_align (dest_mem, dest_align); 2992 src_mem = get_memory_rtx (src, len); 2993 set_mem_align (src_mem, src_align); 2994 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx), 2995 MIN (dest_align, src_align), endp); 2996 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 2997 dest_mem = convert_memory_address (ptr_mode, dest_mem); 2998 return dest_mem; 2999 } 3000 3001 return 0; 3002 } 3003} 3004 3005/* Expand expression EXP, which is a call to the memmove builtin. Return 0 3006 if we failed; the caller should emit a normal call. */ 3007 3008static rtx 3009expand_builtin_memmove (tree arglist, tree type, rtx target, 3010 enum machine_mode mode, tree orig_exp) 3011{ 3012 if (!validate_arglist (arglist, 3013 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3014 return 0; 3015 else 3016 { 3017 tree dest = TREE_VALUE (arglist); 3018 tree src = TREE_VALUE (TREE_CHAIN (arglist)); 3019 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 3020 3021 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 3022 unsigned int dest_align 3023 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 3024 tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3); 3025 3026 if (result) 3027 { 3028 while (TREE_CODE (result) == COMPOUND_EXPR) 3029 { 3030 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode, 3031 EXPAND_NORMAL); 3032 result = TREE_OPERAND (result, 1); 3033 } 3034 return expand_expr (result, target, mode, EXPAND_NORMAL); 3035 } 3036 3037 /* If DEST is not a pointer type, call the normal function. */ 3038 if (dest_align == 0) 3039 return 0; 3040 3041 /* If either SRC is not a pointer type, don't do this 3042 operation in-line. */ 3043 if (src_align == 0) 3044 return 0; 3045 3046 /* If src is categorized for a readonly section we can use 3047 normal memcpy. */ 3048 if (readonly_data_expr (src)) 3049 { 3050 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 3051 if (!fn) 3052 return 0; 3053 fn = build_function_call_expr (fn, arglist); 3054 if (TREE_CODE (fn) == CALL_EXPR) 3055 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp); 3056 return expand_expr (fn, target, mode, EXPAND_NORMAL); 3057 } 3058 3059 /* If length is 1 and we can expand memcpy call inline, 3060 it is ok to use memcpy as well. */ 3061 if (integer_onep (len)) 3062 { 3063 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode, 3064 /*endp=*/0); 3065 if (ret) 3066 return ret; 3067 } 3068 3069 /* Otherwise, call the normal function. */ 3070 return 0; 3071 } 3072} 3073 3074/* Expand expression EXP, which is a call to the bcopy builtin. Return 0 3075 if we failed the caller should emit a normal call. */ 3076 3077static rtx 3078expand_builtin_bcopy (tree exp) 3079{ 3080 tree arglist = TREE_OPERAND (exp, 1); 3081 tree type = TREE_TYPE (exp); 3082 tree src, dest, size, newarglist; 3083 3084 if (!validate_arglist (arglist, 3085 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3086 return NULL_RTX; 3087 3088 src = TREE_VALUE (arglist); 3089 dest = TREE_VALUE (TREE_CHAIN (arglist)); 3090 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 3091 3092 /* New argument list transforming bcopy(ptr x, ptr y, int z) to 3093 memmove(ptr y, ptr x, size_t z). This is done this way 3094 so that if it isn't expanded inline, we fallback to 3095 calling bcopy instead of memmove. */ 3096 3097 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size)); 3098 newarglist = tree_cons (NULL_TREE, src, newarglist); 3099 newarglist = tree_cons (NULL_TREE, dest, newarglist); 3100 3101 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp); 3102} 3103 3104#ifndef HAVE_movstr 3105# define HAVE_movstr 0 3106# define CODE_FOR_movstr CODE_FOR_nothing 3107#endif 3108 3109/* Expand into a movstr instruction, if one is available. Return 0 if 3110 we failed, the caller should emit a normal call, otherwise try to 3111 get the result in TARGET, if convenient. If ENDP is 0 return the 3112 destination pointer, if ENDP is 1 return the end pointer ala 3113 mempcpy, and if ENDP is 2 return the end pointer minus one ala 3114 stpcpy. */ 3115 3116static rtx 3117expand_movstr (tree dest, tree src, rtx target, int endp) 3118{ 3119 rtx end; 3120 rtx dest_mem; 3121 rtx src_mem; 3122 rtx insn; 3123 const struct insn_data * data; 3124 3125 if (!HAVE_movstr) 3126 return 0; 3127 3128 dest_mem = get_memory_rtx (dest, NULL); 3129 src_mem = get_memory_rtx (src, NULL); 3130 if (!endp) 3131 { 3132 target = force_reg (Pmode, XEXP (dest_mem, 0)); 3133 dest_mem = replace_equiv_address (dest_mem, target); 3134 end = gen_reg_rtx (Pmode); 3135 } 3136 else 3137 { 3138 if (target == 0 || target == const0_rtx) 3139 { 3140 end = gen_reg_rtx (Pmode); 3141 if (target == 0) 3142 target = end; 3143 } 3144 else 3145 end = target; 3146 } 3147 3148 data = insn_data + CODE_FOR_movstr; 3149 3150 if (data->operand[0].mode != VOIDmode) 3151 end = gen_lowpart (data->operand[0].mode, end); 3152 3153 insn = data->genfun (end, dest_mem, src_mem); 3154 3155 gcc_assert (insn); 3156 3157 emit_insn (insn); 3158 3159 /* movstr is supposed to set end to the address of the NUL 3160 terminator. If the caller requested a mempcpy-like return value, 3161 adjust it. */ 3162 if (endp == 1 && target != const0_rtx) 3163 { 3164 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1); 3165 emit_move_insn (target, force_operand (tem, NULL_RTX)); 3166 } 3167 3168 return target; 3169} 3170 3171/* Expand expression EXP, which is a call to the strcpy builtin. Return 0 3172 if we failed the caller should emit a normal call, otherwise try to get 3173 the result in TARGET, if convenient (and in mode MODE if that's 3174 convenient). */ 3175 3176static rtx 3177expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode) 3178{ 3179 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3180 { 3181 tree result = fold_builtin_strcpy (fndecl, arglist, 0); 3182 if (result) 3183 { 3184 while (TREE_CODE (result) == COMPOUND_EXPR) 3185 { 3186 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode, 3187 EXPAND_NORMAL); 3188 result = TREE_OPERAND (result, 1); 3189 } 3190 return expand_expr (result, target, mode, EXPAND_NORMAL); 3191 } 3192 3193 return expand_movstr (TREE_VALUE (arglist), 3194 TREE_VALUE (TREE_CHAIN (arglist)), 3195 target, /*endp=*/0); 3196 } 3197 return 0; 3198} 3199 3200/* Expand a call to the stpcpy builtin, with arguments in ARGLIST. 3201 Return 0 if we failed the caller should emit a normal call, 3202 otherwise try to get the result in TARGET, if convenient (and in 3203 mode MODE if that's convenient). */ 3204 3205static rtx 3206expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode) 3207{ 3208 tree arglist = TREE_OPERAND (exp, 1); 3209 /* If return value is ignored, transform stpcpy into strcpy. */ 3210 if (target == const0_rtx) 3211 { 3212 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 3213 if (!fn) 3214 return 0; 3215 3216 return expand_expr (build_function_call_expr (fn, arglist), 3217 target, mode, EXPAND_NORMAL); 3218 } 3219 3220 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3221 return 0; 3222 else 3223 { 3224 tree dst, src, len, lenp1; 3225 tree narglist; 3226 rtx ret; 3227 3228 /* Ensure we get an actual string whose length can be evaluated at 3229 compile-time, not an expression containing a string. This is 3230 because the latter will potentially produce pessimized code 3231 when used to produce the return value. */ 3232 src = TREE_VALUE (TREE_CHAIN (arglist)); 3233 if (! c_getstr (src) || ! (len = c_strlen (src, 0))) 3234 return expand_movstr (TREE_VALUE (arglist), 3235 TREE_VALUE (TREE_CHAIN (arglist)), 3236 target, /*endp=*/2); 3237 3238 dst = TREE_VALUE (arglist); 3239 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1)); 3240 narglist = build_tree_list (NULL_TREE, lenp1); 3241 narglist = tree_cons (NULL_TREE, src, narglist); 3242 narglist = tree_cons (NULL_TREE, dst, narglist); 3243 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp), 3244 target, mode, /*endp=*/2); 3245 3246 if (ret) 3247 return ret; 3248 3249 if (TREE_CODE (len) == INTEGER_CST) 3250 { 3251 rtx len_rtx = expand_normal (len); 3252 3253 if (GET_CODE (len_rtx) == CONST_INT) 3254 { 3255 ret = expand_builtin_strcpy (get_callee_fndecl (exp), 3256 arglist, target, mode); 3257 3258 if (ret) 3259 { 3260 if (! target) 3261 { 3262 if (mode != VOIDmode) 3263 target = gen_reg_rtx (mode); 3264 else 3265 target = gen_reg_rtx (GET_MODE (ret)); 3266 } 3267 if (GET_MODE (target) != GET_MODE (ret)) 3268 ret = gen_lowpart (GET_MODE (target), ret); 3269 3270 ret = plus_constant (ret, INTVAL (len_rtx)); 3271 ret = emit_move_insn (target, force_operand (ret, NULL_RTX)); 3272 gcc_assert (ret); 3273 3274 return target; 3275 } 3276 } 3277 } 3278 3279 return expand_movstr (TREE_VALUE (arglist), 3280 TREE_VALUE (TREE_CHAIN (arglist)), 3281 target, /*endp=*/2); 3282 } 3283} 3284 3285/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 3286 bytes from constant string DATA + OFFSET and return it as target 3287 constant. */ 3288 3289static rtx 3290builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset, 3291 enum machine_mode mode) 3292{ 3293 const char *str = (const char *) data; 3294 3295 if ((unsigned HOST_WIDE_INT) offset > strlen (str)) 3296 return const0_rtx; 3297 3298 return c_readstr (str + offset, mode); 3299} 3300 3301/* Expand expression EXP, which is a call to the strncpy builtin. Return 0 3302 if we failed the caller should emit a normal call. */ 3303 3304static rtx 3305expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode) 3306{ 3307 tree fndecl = get_callee_fndecl (exp); 3308 tree arglist = TREE_OPERAND (exp, 1); 3309 if (validate_arglist (arglist, 3310 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3311 { 3312 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1); 3313 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 3314 tree result = fold_builtin_strncpy (fndecl, arglist, slen); 3315 3316 if (result) 3317 { 3318 while (TREE_CODE (result) == COMPOUND_EXPR) 3319 { 3320 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode, 3321 EXPAND_NORMAL); 3322 result = TREE_OPERAND (result, 1); 3323 } 3324 return expand_expr (result, target, mode, EXPAND_NORMAL); 3325 } 3326 3327 /* We must be passed a constant len and src parameter. */ 3328 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1)) 3329 return 0; 3330 3331 slen = size_binop (PLUS_EXPR, slen, ssize_int (1)); 3332 3333 /* We're required to pad with trailing zeros if the requested 3334 len is greater than strlen(s2)+1. In that case try to 3335 use store_by_pieces, if it fails, punt. */ 3336 if (tree_int_cst_lt (slen, len)) 3337 { 3338 tree dest = TREE_VALUE (arglist); 3339 unsigned int dest_align 3340 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 3341 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist))); 3342 rtx dest_mem; 3343 3344 if (!p || dest_align == 0 || !host_integerp (len, 1) 3345 || !can_store_by_pieces (tree_low_cst (len, 1), 3346 builtin_strncpy_read_str, 3347 (void *) p, dest_align)) 3348 return 0; 3349 3350 dest_mem = get_memory_rtx (dest, len); 3351 store_by_pieces (dest_mem, tree_low_cst (len, 1), 3352 builtin_strncpy_read_str, 3353 (void *) p, dest_align, 0); 3354 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3355 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3356 return dest_mem; 3357 } 3358 } 3359 return 0; 3360} 3361 3362/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 3363 bytes from constant string DATA + OFFSET and return it as target 3364 constant. */ 3365 3366static rtx 3367builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED, 3368 enum machine_mode mode) 3369{ 3370 const char *c = (const char *) data; 3371 char *p = alloca (GET_MODE_SIZE (mode)); 3372 3373 memset (p, *c, GET_MODE_SIZE (mode)); 3374 3375 return c_readstr (p, mode); 3376} 3377 3378/* Callback routine for store_by_pieces. Return the RTL of a register 3379 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned 3380 char value given in the RTL register data. For example, if mode is 3381 4 bytes wide, return the RTL for 0x01010101*data. */ 3382 3383static rtx 3384builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED, 3385 enum machine_mode mode) 3386{ 3387 rtx target, coeff; 3388 size_t size; 3389 char *p; 3390 3391 size = GET_MODE_SIZE (mode); 3392 if (size == 1) 3393 return (rtx) data; 3394 3395 p = alloca (size); 3396 memset (p, 1, size); 3397 coeff = c_readstr (p, mode); 3398 3399 target = convert_to_mode (mode, (rtx) data, 1); 3400 target = expand_mult (mode, target, coeff, NULL_RTX, 1); 3401 return force_reg (mode, target); 3402} 3403 3404/* Expand expression EXP, which is a call to the memset builtin. Return 0 3405 if we failed the caller should emit a normal call, otherwise try to get 3406 the result in TARGET, if convenient (and in mode MODE if that's 3407 convenient). */ 3408 3409static rtx 3410expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode, 3411 tree orig_exp) 3412{ 3413 if (!validate_arglist (arglist, 3414 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3415 return 0; 3416 else 3417 { 3418 tree dest = TREE_VALUE (arglist); 3419 tree val = TREE_VALUE (TREE_CHAIN (arglist)); 3420 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 3421 tree fndecl, fn; 3422 enum built_in_function fcode; 3423 char c; 3424 unsigned int dest_align; 3425 rtx dest_mem, dest_addr, len_rtx; 3426 3427 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 3428 3429 /* If DEST is not a pointer type, don't do this 3430 operation in-line. */ 3431 if (dest_align == 0) 3432 return 0; 3433 3434 /* If the LEN parameter is zero, return DEST. */ 3435 if (integer_zerop (len)) 3436 { 3437 /* Evaluate and ignore VAL in case it has side-effects. */ 3438 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL); 3439 return expand_expr (dest, target, mode, EXPAND_NORMAL); 3440 } 3441 3442 /* Stabilize the arguments in case we fail. */ 3443 dest = builtin_save_expr (dest); 3444 val = builtin_save_expr (val); 3445 len = builtin_save_expr (len); 3446 3447 len_rtx = expand_normal (len); 3448 dest_mem = get_memory_rtx (dest, len); 3449 3450 if (TREE_CODE (val) != INTEGER_CST) 3451 { 3452 rtx val_rtx; 3453 3454 val_rtx = expand_normal (val); 3455 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node), 3456 val_rtx, 0); 3457 3458 /* Assume that we can memset by pieces if we can store the 3459 * the coefficients by pieces (in the required modes). 3460 * We can't pass builtin_memset_gen_str as that emits RTL. */ 3461 c = 1; 3462 if (host_integerp (len, 1) 3463 && !(optimize_size && tree_low_cst (len, 1) > 1) 3464 && can_store_by_pieces (tree_low_cst (len, 1), 3465 builtin_memset_read_str, &c, dest_align)) 3466 { 3467 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node), 3468 val_rtx); 3469 store_by_pieces (dest_mem, tree_low_cst (len, 1), 3470 builtin_memset_gen_str, val_rtx, dest_align, 0); 3471 } 3472 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx, 3473 dest_align)) 3474 goto do_libcall; 3475 3476 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3477 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3478 return dest_mem; 3479 } 3480 3481 if (target_char_cast (val, &c)) 3482 goto do_libcall; 3483 3484 if (c) 3485 { 3486 if (host_integerp (len, 1) 3487 && !(optimize_size && tree_low_cst (len, 1) > 1) 3488 && can_store_by_pieces (tree_low_cst (len, 1), 3489 builtin_memset_read_str, &c, dest_align)) 3490 store_by_pieces (dest_mem, tree_low_cst (len, 1), 3491 builtin_memset_read_str, &c, dest_align, 0); 3492 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c), 3493 dest_align)) 3494 goto do_libcall; 3495 3496 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3497 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3498 return dest_mem; 3499 } 3500 3501 set_mem_align (dest_mem, dest_align); 3502 dest_addr = clear_storage (dest_mem, len_rtx, 3503 CALL_EXPR_TAILCALL (orig_exp) 3504 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL); 3505 3506 if (dest_addr == 0) 3507 { 3508 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3509 dest_addr = convert_memory_address (ptr_mode, dest_addr); 3510 } 3511 3512 return dest_addr; 3513 3514 do_libcall: 3515 fndecl = get_callee_fndecl (orig_exp); 3516 fcode = DECL_FUNCTION_CODE (fndecl); 3517 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO); 3518 arglist = build_tree_list (NULL_TREE, len); 3519 if (fcode == BUILT_IN_MEMSET) 3520 arglist = tree_cons (NULL_TREE, val, arglist); 3521 arglist = tree_cons (NULL_TREE, dest, arglist); 3522 fn = build_function_call_expr (fndecl, arglist); 3523 if (TREE_CODE (fn) == CALL_EXPR) 3524 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp); 3525 return expand_call (fn, target, target == const0_rtx); 3526 } 3527} 3528 3529/* Expand expression EXP, which is a call to the bzero builtin. Return 0 3530 if we failed the caller should emit a normal call. */ 3531 3532static rtx 3533expand_builtin_bzero (tree exp) 3534{ 3535 tree arglist = TREE_OPERAND (exp, 1); 3536 tree dest, size, newarglist; 3537 3538 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3539 return NULL_RTX; 3540 3541 dest = TREE_VALUE (arglist); 3542 size = TREE_VALUE (TREE_CHAIN (arglist)); 3543 3544 /* New argument list transforming bzero(ptr x, int y) to 3545 memset(ptr x, int 0, size_t y). This is done this way 3546 so that if it isn't expanded inline, we fallback to 3547 calling bzero instead of memset. */ 3548 3549 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size)); 3550 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist); 3551 newarglist = tree_cons (NULL_TREE, dest, newarglist); 3552 3553 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp); 3554} 3555 3556/* Expand expression EXP, which is a call to the memcmp built-in function. 3557 ARGLIST is the argument list for this call. Return 0 if we failed and the 3558 caller should emit a normal call, otherwise try to get the result in 3559 TARGET, if convenient (and in mode MODE, if that's convenient). */ 3560 3561static rtx 3562expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target, 3563 enum machine_mode mode) 3564{ 3565 if (!validate_arglist (arglist, 3566 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3567 return 0; 3568 else 3569 { 3570 tree result = fold_builtin_memcmp (arglist); 3571 if (result) 3572 return expand_expr (result, target, mode, EXPAND_NORMAL); 3573 } 3574 3575#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi 3576 { 3577 tree arg1 = TREE_VALUE (arglist); 3578 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 3579 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 3580 rtx arg1_rtx, arg2_rtx, arg3_rtx; 3581 rtx result; 3582 rtx insn; 3583 3584 int arg1_align 3585 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3586 int arg2_align 3587 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3588 enum machine_mode insn_mode; 3589 3590#ifdef HAVE_cmpmemsi 3591 if (HAVE_cmpmemsi) 3592 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode; 3593 else 3594#endif 3595#ifdef HAVE_cmpstrnsi 3596 if (HAVE_cmpstrnsi) 3597 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode; 3598 else 3599#endif 3600 return 0; 3601 3602 /* If we don't have POINTER_TYPE, call the function. */ 3603 if (arg1_align == 0 || arg2_align == 0) 3604 return 0; 3605 3606 /* Make a place to write the result of the instruction. */ 3607 result = target; 3608 if (! (result != 0 3609 && REG_P (result) && GET_MODE (result) == insn_mode 3610 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 3611 result = gen_reg_rtx (insn_mode); 3612 3613 arg1_rtx = get_memory_rtx (arg1, len); 3614 arg2_rtx = get_memory_rtx (arg2, len); 3615 arg3_rtx = expand_normal (len); 3616 3617 /* Set MEM_SIZE as appropriate. */ 3618 if (GET_CODE (arg3_rtx) == CONST_INT) 3619 { 3620 set_mem_size (arg1_rtx, arg3_rtx); 3621 set_mem_size (arg2_rtx, arg3_rtx); 3622 } 3623 3624#ifdef HAVE_cmpmemsi 3625 if (HAVE_cmpmemsi) 3626 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 3627 GEN_INT (MIN (arg1_align, arg2_align))); 3628 else 3629#endif 3630#ifdef HAVE_cmpstrnsi 3631 if (HAVE_cmpstrnsi) 3632 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 3633 GEN_INT (MIN (arg1_align, arg2_align))); 3634 else 3635#endif 3636 gcc_unreachable (); 3637 3638 if (insn) 3639 emit_insn (insn); 3640 else 3641 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK, 3642 TYPE_MODE (integer_type_node), 3, 3643 XEXP (arg1_rtx, 0), Pmode, 3644 XEXP (arg2_rtx, 0), Pmode, 3645 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx, 3646 TYPE_UNSIGNED (sizetype)), 3647 TYPE_MODE (sizetype)); 3648 3649 /* Return the value in the proper mode for this function. */ 3650 mode = TYPE_MODE (TREE_TYPE (exp)); 3651 if (GET_MODE (result) == mode) 3652 return result; 3653 else if (target != 0) 3654 { 3655 convert_move (target, result, 0); 3656 return target; 3657 } 3658 else 3659 return convert_to_mode (mode, result, 0); 3660 } 3661#endif 3662 3663 return 0; 3664} 3665 3666/* Expand expression EXP, which is a call to the strcmp builtin. Return 0 3667 if we failed the caller should emit a normal call, otherwise try to get 3668 the result in TARGET, if convenient. */ 3669 3670static rtx 3671expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode) 3672{ 3673 tree arglist = TREE_OPERAND (exp, 1); 3674 3675 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3676 return 0; 3677 else 3678 { 3679 tree result = fold_builtin_strcmp (arglist); 3680 if (result) 3681 return expand_expr (result, target, mode, EXPAND_NORMAL); 3682 } 3683 3684#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi 3685 if (cmpstr_optab[SImode] != CODE_FOR_nothing 3686 || cmpstrn_optab[SImode] != CODE_FOR_nothing) 3687 { 3688 rtx arg1_rtx, arg2_rtx; 3689 rtx result, insn = NULL_RTX; 3690 tree fndecl, fn; 3691 3692 tree arg1 = TREE_VALUE (arglist); 3693 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 3694 int arg1_align 3695 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3696 int arg2_align 3697 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3698 3699 /* If we don't have POINTER_TYPE, call the function. */ 3700 if (arg1_align == 0 || arg2_align == 0) 3701 return 0; 3702 3703 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */ 3704 arg1 = builtin_save_expr (arg1); 3705 arg2 = builtin_save_expr (arg2); 3706 3707 arg1_rtx = get_memory_rtx (arg1, NULL); 3708 arg2_rtx = get_memory_rtx (arg2, NULL); 3709 3710#ifdef HAVE_cmpstrsi 3711 /* Try to call cmpstrsi. */ 3712 if (HAVE_cmpstrsi) 3713 { 3714 enum machine_mode insn_mode 3715 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode; 3716 3717 /* Make a place to write the result of the instruction. */ 3718 result = target; 3719 if (! (result != 0 3720 && REG_P (result) && GET_MODE (result) == insn_mode 3721 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 3722 result = gen_reg_rtx (insn_mode); 3723 3724 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, 3725 GEN_INT (MIN (arg1_align, arg2_align))); 3726 } 3727#endif 3728#ifdef HAVE_cmpstrnsi 3729 /* Try to determine at least one length and call cmpstrnsi. */ 3730 if (!insn && HAVE_cmpstrnsi) 3731 { 3732 tree len; 3733 rtx arg3_rtx; 3734 3735 enum machine_mode insn_mode 3736 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode; 3737 tree len1 = c_strlen (arg1, 1); 3738 tree len2 = c_strlen (arg2, 1); 3739 3740 if (len1) 3741 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1); 3742 if (len2) 3743 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2); 3744 3745 /* If we don't have a constant length for the first, use the length 3746 of the second, if we know it. We don't require a constant for 3747 this case; some cost analysis could be done if both are available 3748 but neither is constant. For now, assume they're equally cheap, 3749 unless one has side effects. If both strings have constant lengths, 3750 use the smaller. */ 3751 3752 if (!len1) 3753 len = len2; 3754 else if (!len2) 3755 len = len1; 3756 else if (TREE_SIDE_EFFECTS (len1)) 3757 len = len2; 3758 else if (TREE_SIDE_EFFECTS (len2)) 3759 len = len1; 3760 else if (TREE_CODE (len1) != INTEGER_CST) 3761 len = len2; 3762 else if (TREE_CODE (len2) != INTEGER_CST) 3763 len = len1; 3764 else if (tree_int_cst_lt (len1, len2)) 3765 len = len1; 3766 else 3767 len = len2; 3768 3769 /* If both arguments have side effects, we cannot optimize. */ 3770 if (!len || TREE_SIDE_EFFECTS (len)) 3771 goto do_libcall; 3772 3773 arg3_rtx = expand_normal (len); 3774 3775 /* Make a place to write the result of the instruction. */ 3776 result = target; 3777 if (! (result != 0 3778 && REG_P (result) && GET_MODE (result) == insn_mode 3779 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 3780 result = gen_reg_rtx (insn_mode); 3781 3782 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 3783 GEN_INT (MIN (arg1_align, arg2_align))); 3784 } 3785#endif 3786 3787 if (insn) 3788 { 3789 emit_insn (insn); 3790 3791 /* Return the value in the proper mode for this function. */ 3792 mode = TYPE_MODE (TREE_TYPE (exp)); 3793 if (GET_MODE (result) == mode) 3794 return result; 3795 if (target == 0) 3796 return convert_to_mode (mode, result, 0); 3797 convert_move (target, result, 0); 3798 return target; 3799 } 3800 3801 /* Expand the library call ourselves using a stabilized argument 3802 list to avoid re-evaluating the function's arguments twice. */ 3803#ifdef HAVE_cmpstrnsi 3804 do_libcall: 3805#endif 3806 arglist = build_tree_list (NULL_TREE, arg2); 3807 arglist = tree_cons (NULL_TREE, arg1, arglist); 3808 fndecl = get_callee_fndecl (exp); 3809 fn = build_function_call_expr (fndecl, arglist); 3810 if (TREE_CODE (fn) == CALL_EXPR) 3811 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 3812 return expand_call (fn, target, target == const0_rtx); 3813 } 3814#endif 3815 return 0; 3816} 3817 3818/* Expand expression EXP, which is a call to the strncmp builtin. Return 0 3819 if we failed the caller should emit a normal call, otherwise try to get 3820 the result in TARGET, if convenient. */ 3821 3822static rtx 3823expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode) 3824{ 3825 tree arglist = TREE_OPERAND (exp, 1); 3826 3827 if (!validate_arglist (arglist, 3828 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3829 return 0; 3830 else 3831 { 3832 tree result = fold_builtin_strncmp (arglist); 3833 if (result) 3834 return expand_expr (result, target, mode, EXPAND_NORMAL); 3835 } 3836 3837 /* If c_strlen can determine an expression for one of the string 3838 lengths, and it doesn't have side effects, then emit cmpstrnsi 3839 using length MIN(strlen(string)+1, arg3). */ 3840#ifdef HAVE_cmpstrnsi 3841 if (HAVE_cmpstrnsi) 3842 { 3843 tree arg1 = TREE_VALUE (arglist); 3844 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 3845 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 3846 tree len, len1, len2; 3847 rtx arg1_rtx, arg2_rtx, arg3_rtx; 3848 rtx result, insn; 3849 tree fndecl, fn; 3850 3851 int arg1_align 3852 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3853 int arg2_align 3854 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3855 enum machine_mode insn_mode 3856 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode; 3857 3858 len1 = c_strlen (arg1, 1); 3859 len2 = c_strlen (arg2, 1); 3860 3861 if (len1) 3862 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1); 3863 if (len2) 3864 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2); 3865 3866 /* If we don't have a constant length for the first, use the length 3867 of the second, if we know it. We don't require a constant for 3868 this case; some cost analysis could be done if both are available 3869 but neither is constant. For now, assume they're equally cheap, 3870 unless one has side effects. If both strings have constant lengths, 3871 use the smaller. */ 3872 3873 if (!len1) 3874 len = len2; 3875 else if (!len2) 3876 len = len1; 3877 else if (TREE_SIDE_EFFECTS (len1)) 3878 len = len2; 3879 else if (TREE_SIDE_EFFECTS (len2)) 3880 len = len1; 3881 else if (TREE_CODE (len1) != INTEGER_CST) 3882 len = len2; 3883 else if (TREE_CODE (len2) != INTEGER_CST) 3884 len = len1; 3885 else if (tree_int_cst_lt (len1, len2)) 3886 len = len1; 3887 else 3888 len = len2; 3889 3890 /* If both arguments have side effects, we cannot optimize. */ 3891 if (!len || TREE_SIDE_EFFECTS (len)) 3892 return 0; 3893 3894 /* The actual new length parameter is MIN(len,arg3). */ 3895 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len, 3896 fold_convert (TREE_TYPE (len), arg3)); 3897 3898 /* If we don't have POINTER_TYPE, call the function. */ 3899 if (arg1_align == 0 || arg2_align == 0) 3900 return 0; 3901 3902 /* Make a place to write the result of the instruction. */ 3903 result = target; 3904 if (! (result != 0 3905 && REG_P (result) && GET_MODE (result) == insn_mode 3906 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 3907 result = gen_reg_rtx (insn_mode); 3908 3909 /* Stabilize the arguments in case gen_cmpstrnsi fails. */ 3910 arg1 = builtin_save_expr (arg1); 3911 arg2 = builtin_save_expr (arg2); 3912 len = builtin_save_expr (len); 3913 3914 arg1_rtx = get_memory_rtx (arg1, len); 3915 arg2_rtx = get_memory_rtx (arg2, len); 3916 arg3_rtx = expand_normal (len); 3917 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 3918 GEN_INT (MIN (arg1_align, arg2_align))); 3919 if (insn) 3920 { 3921 emit_insn (insn); 3922 3923 /* Return the value in the proper mode for this function. */ 3924 mode = TYPE_MODE (TREE_TYPE (exp)); 3925 if (GET_MODE (result) == mode) 3926 return result; 3927 if (target == 0) 3928 return convert_to_mode (mode, result, 0); 3929 convert_move (target, result, 0); 3930 return target; 3931 } 3932 3933 /* Expand the library call ourselves using a stabilized argument 3934 list to avoid re-evaluating the function's arguments twice. */ 3935 arglist = build_tree_list (NULL_TREE, len); 3936 arglist = tree_cons (NULL_TREE, arg2, arglist); 3937 arglist = tree_cons (NULL_TREE, arg1, arglist); 3938 fndecl = get_callee_fndecl (exp); 3939 fn = build_function_call_expr (fndecl, arglist); 3940 if (TREE_CODE (fn) == CALL_EXPR) 3941 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 3942 return expand_call (fn, target, target == const0_rtx); 3943 } 3944#endif 3945 return 0; 3946} 3947 3948/* Expand expression EXP, which is a call to the strcat builtin. 3949 Return 0 if we failed the caller should emit a normal call, 3950 otherwise try to get the result in TARGET, if convenient. */ 3951 3952static rtx 3953expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode) 3954{ 3955 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3956 return 0; 3957 else 3958 { 3959 tree dst = TREE_VALUE (arglist), 3960 src = TREE_VALUE (TREE_CHAIN (arglist)); 3961 const char *p = c_getstr (src); 3962 3963 /* If the string length is zero, return the dst parameter. */ 3964 if (p && *p == '\0') 3965 return expand_expr (dst, target, mode, EXPAND_NORMAL); 3966 3967 if (!optimize_size) 3968 { 3969 /* See if we can store by pieces into (dst + strlen(dst)). */ 3970 tree newsrc, newdst, 3971 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN]; 3972 rtx insns; 3973 3974 /* Stabilize the argument list. */ 3975 newsrc = builtin_save_expr (src); 3976 if (newsrc != src) 3977 arglist = build_tree_list (NULL_TREE, newsrc); 3978 else 3979 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */ 3980 3981 dst = builtin_save_expr (dst); 3982 3983 start_sequence (); 3984 3985 /* Create strlen (dst). */ 3986 newdst = 3987 build_function_call_expr (strlen_fn, 3988 build_tree_list (NULL_TREE, dst)); 3989 /* Create (dst + (cast) strlen (dst)). */ 3990 newdst = fold_convert (TREE_TYPE (dst), newdst); 3991 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst); 3992 3993 newdst = builtin_save_expr (newdst); 3994 arglist = tree_cons (NULL_TREE, newdst, arglist); 3995 3996 if (!expand_builtin_strcpy (fndecl, arglist, target, mode)) 3997 { 3998 end_sequence (); /* Stop sequence. */ 3999 return 0; 4000 } 4001 4002 /* Output the entire sequence. */ 4003 insns = get_insns (); 4004 end_sequence (); 4005 emit_insn (insns); 4006 4007 return expand_expr (dst, target, mode, EXPAND_NORMAL); 4008 } 4009 4010 return 0; 4011 } 4012} 4013 4014/* Expand expression EXP, which is a call to the strncat builtin. 4015 Return 0 if we failed the caller should emit a normal call, 4016 otherwise try to get the result in TARGET, if convenient. */ 4017 4018static rtx 4019expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode) 4020{ 4021 if (validate_arglist (arglist, 4022 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 4023 { 4024 tree result = fold_builtin_strncat (arglist); 4025 if (result) 4026 return expand_expr (result, target, mode, EXPAND_NORMAL); 4027 } 4028 return 0; 4029} 4030 4031/* Expand expression EXP, which is a call to the strspn builtin. 4032 Return 0 if we failed the caller should emit a normal call, 4033 otherwise try to get the result in TARGET, if convenient. */ 4034 4035static rtx 4036expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode) 4037{ 4038 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 4039 { 4040 tree result = fold_builtin_strspn (arglist); 4041 if (result) 4042 return expand_expr (result, target, mode, EXPAND_NORMAL); 4043 } 4044 return 0; 4045} 4046 4047/* Expand expression EXP, which is a call to the strcspn builtin. 4048 Return 0 if we failed the caller should emit a normal call, 4049 otherwise try to get the result in TARGET, if convenient. */ 4050 4051static rtx 4052expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode) 4053{ 4054 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 4055 { 4056 tree result = fold_builtin_strcspn (arglist); 4057 if (result) 4058 return expand_expr (result, target, mode, EXPAND_NORMAL); 4059 } 4060 return 0; 4061} 4062 4063/* Expand a call to __builtin_saveregs, generating the result in TARGET, 4064 if that's convenient. */ 4065 4066rtx 4067expand_builtin_saveregs (void) 4068{ 4069 rtx val, seq; 4070 4071 /* Don't do __builtin_saveregs more than once in a function. 4072 Save the result of the first call and reuse it. */ 4073 if (saveregs_value != 0) 4074 return saveregs_value; 4075 4076 /* When this function is called, it means that registers must be 4077 saved on entry to this function. So we migrate the call to the 4078 first insn of this function. */ 4079 4080 start_sequence (); 4081 4082 /* Do whatever the machine needs done in this case. */ 4083 val = targetm.calls.expand_builtin_saveregs (); 4084 4085 seq = get_insns (); 4086 end_sequence (); 4087 4088 saveregs_value = val; 4089 4090 /* Put the insns after the NOTE that starts the function. If this 4091 is inside a start_sequence, make the outer-level insn chain current, so 4092 the code is placed at the start of the function. */ 4093 push_topmost_sequence (); 4094 emit_insn_after (seq, entry_of_function ()); 4095 pop_topmost_sequence (); 4096 4097 return val; 4098} 4099 4100/* __builtin_args_info (N) returns word N of the arg space info 4101 for the current function. The number and meanings of words 4102 is controlled by the definition of CUMULATIVE_ARGS. */ 4103 4104static rtx 4105expand_builtin_args_info (tree arglist) 4106{ 4107 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int); 4108 int *word_ptr = (int *) ¤t_function_args_info; 4109 4110 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0); 4111 4112 if (arglist != 0) 4113 { 4114 if (!host_integerp (TREE_VALUE (arglist), 0)) 4115 error ("argument of %<__builtin_args_info%> must be constant"); 4116 else 4117 { 4118 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0); 4119 4120 if (wordnum < 0 || wordnum >= nwords) 4121 error ("argument of %<__builtin_args_info%> out of range"); 4122 else 4123 return GEN_INT (word_ptr[wordnum]); 4124 } 4125 } 4126 else 4127 error ("missing argument in %<__builtin_args_info%>"); 4128 4129 return const0_rtx; 4130} 4131 4132/* Expand a call to __builtin_next_arg. */ 4133 4134static rtx 4135expand_builtin_next_arg (void) 4136{ 4137 /* Checking arguments is already done in fold_builtin_next_arg 4138 that must be called before this function. */ 4139 return expand_binop (Pmode, add_optab, 4140 current_function_internal_arg_pointer, 4141 current_function_arg_offset_rtx, 4142 NULL_RTX, 0, OPTAB_LIB_WIDEN); 4143} 4144 4145/* Make it easier for the backends by protecting the valist argument 4146 from multiple evaluations. */ 4147 4148static tree 4149stabilize_va_list (tree valist, int needs_lvalue) 4150{ 4151 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE) 4152 { 4153 if (TREE_SIDE_EFFECTS (valist)) 4154 valist = save_expr (valist); 4155 4156 /* For this case, the backends will be expecting a pointer to 4157 TREE_TYPE (va_list_type_node), but it's possible we've 4158 actually been given an array (an actual va_list_type_node). 4159 So fix it. */ 4160 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE) 4161 { 4162 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node)); 4163 valist = build_fold_addr_expr_with_type (valist, p1); 4164 } 4165 } 4166 else 4167 { 4168 tree pt; 4169 4170 if (! needs_lvalue) 4171 { 4172 if (! TREE_SIDE_EFFECTS (valist)) 4173 return valist; 4174 4175 pt = build_pointer_type (va_list_type_node); 4176 valist = fold_build1 (ADDR_EXPR, pt, valist); 4177 TREE_SIDE_EFFECTS (valist) = 1; 4178 } 4179 4180 if (TREE_SIDE_EFFECTS (valist)) 4181 valist = save_expr (valist); 4182 valist = build_fold_indirect_ref (valist); 4183 } 4184 4185 return valist; 4186} 4187 4188/* The "standard" definition of va_list is void*. */ 4189 4190tree 4191std_build_builtin_va_list (void) 4192{ 4193 return ptr_type_node; 4194} 4195 4196/* The "standard" implementation of va_start: just assign `nextarg' to 4197 the variable. */ 4198 4199void 4200std_expand_builtin_va_start (tree valist, rtx nextarg) 4201{ 4202 tree t; 4203 4204 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, 4205 make_tree (ptr_type_node, nextarg)); 4206 TREE_SIDE_EFFECTS (t) = 1; 4207 4208 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 4209} 4210 4211/* Expand ARGLIST, from a call to __builtin_va_start. */ 4212 4213static rtx 4214expand_builtin_va_start (tree arglist) 4215{ 4216 rtx nextarg; 4217 tree chain, valist; 4218 4219 chain = TREE_CHAIN (arglist); 4220 4221 if (!chain) 4222 { 4223 error ("too few arguments to function %<va_start%>"); 4224 return const0_rtx; 4225 } 4226 4227 if (fold_builtin_next_arg (chain)) 4228 return const0_rtx; 4229 4230 nextarg = expand_builtin_next_arg (); 4231 valist = stabilize_va_list (TREE_VALUE (arglist), 1); 4232 4233#ifdef EXPAND_BUILTIN_VA_START 4234 EXPAND_BUILTIN_VA_START (valist, nextarg); 4235#else 4236 std_expand_builtin_va_start (valist, nextarg); 4237#endif 4238 4239 return const0_rtx; 4240} 4241 4242/* The "standard" implementation of va_arg: read the value from the 4243 current (padded) address and increment by the (padded) size. */ 4244 4245tree 4246std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p) 4247{ 4248 tree addr, t, type_size, rounded_size, valist_tmp; 4249 unsigned HOST_WIDE_INT align, boundary; 4250 bool indirect; 4251 4252#ifdef ARGS_GROW_DOWNWARD 4253 /* All of the alignment and movement below is for args-grow-up machines. 4254 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all 4255 implement their own specialized gimplify_va_arg_expr routines. */ 4256 gcc_unreachable (); 4257#endif 4258 4259 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false); 4260 if (indirect) 4261 type = build_pointer_type (type); 4262 4263 align = PARM_BOUNDARY / BITS_PER_UNIT; 4264 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT; 4265 4266 /* Hoist the valist value into a temporary for the moment. */ 4267 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL); 4268 4269 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually 4270 requires greater alignment, we must perform dynamic alignment. */ 4271 if (boundary > align 4272 && !integer_zerop (TYPE_SIZE (type))) 4273 { 4274 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1)); 4275 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, 4276 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t)); 4277 gimplify_and_add (t, pre_p); 4278 4279 t = fold_convert (TREE_TYPE (valist), size_int (-boundary)); 4280 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, 4281 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t)); 4282 gimplify_and_add (t, pre_p); 4283 } 4284 else 4285 boundary = align; 4286 4287 /* If the actual alignment is less than the alignment of the type, 4288 adjust the type accordingly so that we don't assume strict alignment 4289 when deferencing the pointer. */ 4290 boundary *= BITS_PER_UNIT; 4291 if (boundary < TYPE_ALIGN (type)) 4292 { 4293 type = build_variant_type_copy (type); 4294 TYPE_ALIGN (type) = boundary; 4295 } 4296 4297 /* Compute the rounded size of the type. */ 4298 type_size = size_in_bytes (type); 4299 rounded_size = round_up (type_size, align); 4300 4301 /* Reduce rounded_size so it's sharable with the postqueue. */ 4302 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue); 4303 4304 /* Get AP. */ 4305 addr = valist_tmp; 4306 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size)) 4307 { 4308 /* Small args are padded downward. */ 4309 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align)); 4310 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node, 4311 size_binop (MINUS_EXPR, rounded_size, type_size)); 4312 t = fold_convert (TREE_TYPE (addr), t); 4313 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t); 4314 } 4315 4316 /* Compute new value for AP. */ 4317 t = fold_convert (TREE_TYPE (valist), rounded_size); 4318 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t); 4319 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t); 4320 gimplify_and_add (t, pre_p); 4321 4322 addr = fold_convert (build_pointer_type (type), addr); 4323 4324 if (indirect) 4325 addr = build_va_arg_indirect_ref (addr); 4326 4327 return build_va_arg_indirect_ref (addr); 4328} 4329 4330/* Build an indirect-ref expression over the given TREE, which represents a 4331 piece of a va_arg() expansion. */ 4332tree 4333build_va_arg_indirect_ref (tree addr) 4334{ 4335 addr = build_fold_indirect_ref (addr); 4336 4337 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */ 4338 mf_mark (addr); 4339 4340 return addr; 4341} 4342 4343/* Return a dummy expression of type TYPE in order to keep going after an 4344 error. */ 4345 4346static tree 4347dummy_object (tree type) 4348{ 4349 tree t = build_int_cst (build_pointer_type (type), 0); 4350 return build1 (INDIRECT_REF, type, t); 4351} 4352 4353/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a 4354 builtin function, but a very special sort of operator. */ 4355 4356enum gimplify_status 4357gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p) 4358{ 4359 tree promoted_type, want_va_type, have_va_type; 4360 tree valist = TREE_OPERAND (*expr_p, 0); 4361 tree type = TREE_TYPE (*expr_p); 4362 tree t; 4363 4364 /* Verify that valist is of the proper type. */ 4365 want_va_type = va_list_type_node; 4366 have_va_type = TREE_TYPE (valist); 4367 4368 if (have_va_type == error_mark_node) 4369 return GS_ERROR; 4370 4371 if (TREE_CODE (want_va_type) == ARRAY_TYPE) 4372 { 4373 /* If va_list is an array type, the argument may have decayed 4374 to a pointer type, e.g. by being passed to another function. 4375 In that case, unwrap both types so that we can compare the 4376 underlying records. */ 4377 if (TREE_CODE (have_va_type) == ARRAY_TYPE 4378 || POINTER_TYPE_P (have_va_type)) 4379 { 4380 want_va_type = TREE_TYPE (want_va_type); 4381 have_va_type = TREE_TYPE (have_va_type); 4382 } 4383 } 4384 4385 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type)) 4386 { 4387 error ("first argument to %<va_arg%> not of type %<va_list%>"); 4388 return GS_ERROR; 4389 } 4390 4391 /* Generate a diagnostic for requesting data of a type that cannot 4392 be passed through `...' due to type promotion at the call site. */ 4393 else if ((promoted_type = lang_hooks.types.type_promotes_to (type)) 4394 != type) 4395 { 4396 static bool gave_help; 4397 4398 /* Unfortunately, this is merely undefined, rather than a constraint 4399 violation, so we cannot make this an error. If this call is never 4400 executed, the program is still strictly conforming. */ 4401 warning (0, "%qT is promoted to %qT when passed through %<...%>", 4402 type, promoted_type); 4403 if (! gave_help) 4404 { 4405 gave_help = true; 4406 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)", 4407 promoted_type, type); 4408 } 4409 4410 /* We can, however, treat "undefined" any way we please. 4411 Call abort to encourage the user to fix the program. */ 4412 inform ("if this code is reached, the program will abort"); 4413 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 4414 NULL); 4415 append_to_statement_list (t, pre_p); 4416 4417 /* This is dead code, but go ahead and finish so that the 4418 mode of the result comes out right. */ 4419 *expr_p = dummy_object (type); 4420 return GS_ALL_DONE; 4421 } 4422 else 4423 { 4424 /* Make it easier for the backends by protecting the valist argument 4425 from multiple evaluations. */ 4426 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE) 4427 { 4428 /* For this case, the backends will be expecting a pointer to 4429 TREE_TYPE (va_list_type_node), but it's possible we've 4430 actually been given an array (an actual va_list_type_node). 4431 So fix it. */ 4432 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE) 4433 { 4434 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node)); 4435 valist = build_fold_addr_expr_with_type (valist, p1); 4436 } 4437 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue); 4438 } 4439 else 4440 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue); 4441 4442 if (!targetm.gimplify_va_arg_expr) 4443 /* FIXME:Once most targets are converted we should merely 4444 assert this is non-null. */ 4445 return GS_ALL_DONE; 4446 4447 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p); 4448 return GS_OK; 4449 } 4450} 4451 4452/* Expand ARGLIST, from a call to __builtin_va_end. */ 4453 4454static rtx 4455expand_builtin_va_end (tree arglist) 4456{ 4457 tree valist = TREE_VALUE (arglist); 4458 4459 /* Evaluate for side effects, if needed. I hate macros that don't 4460 do that. */ 4461 if (TREE_SIDE_EFFECTS (valist)) 4462 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL); 4463 4464 return const0_rtx; 4465} 4466 4467/* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a 4468 builtin rather than just as an assignment in stdarg.h because of the 4469 nastiness of array-type va_list types. */ 4470 4471static rtx 4472expand_builtin_va_copy (tree arglist) 4473{ 4474 tree dst, src, t; 4475 4476 dst = TREE_VALUE (arglist); 4477 src = TREE_VALUE (TREE_CHAIN (arglist)); 4478 4479 dst = stabilize_va_list (dst, 1); 4480 src = stabilize_va_list (src, 0); 4481 4482 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE) 4483 { 4484 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src); 4485 TREE_SIDE_EFFECTS (t) = 1; 4486 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 4487 } 4488 else 4489 { 4490 rtx dstb, srcb, size; 4491 4492 /* Evaluate to pointers. */ 4493 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL); 4494 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL); 4495 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX, 4496 VOIDmode, EXPAND_NORMAL); 4497 4498 dstb = convert_memory_address (Pmode, dstb); 4499 srcb = convert_memory_address (Pmode, srcb); 4500 4501 /* "Dereference" to BLKmode memories. */ 4502 dstb = gen_rtx_MEM (BLKmode, dstb); 4503 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst)))); 4504 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node)); 4505 srcb = gen_rtx_MEM (BLKmode, srcb); 4506 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src)))); 4507 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node)); 4508 4509 /* Copy. */ 4510 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL); 4511 } 4512 4513 return const0_rtx; 4514} 4515 4516/* Expand a call to one of the builtin functions __builtin_frame_address or 4517 __builtin_return_address. */ 4518 4519static rtx 4520expand_builtin_frame_address (tree fndecl, tree arglist) 4521{ 4522 /* The argument must be a nonnegative integer constant. 4523 It counts the number of frames to scan up the stack. 4524 The value is the return address saved in that frame. */ 4525 if (arglist == 0) 4526 /* Warning about missing arg was already issued. */ 4527 return const0_rtx; 4528 else if (! host_integerp (TREE_VALUE (arglist), 1)) 4529 { 4530 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4531 error ("invalid argument to %<__builtin_frame_address%>"); 4532 else 4533 error ("invalid argument to %<__builtin_return_address%>"); 4534 return const0_rtx; 4535 } 4536 else 4537 { 4538 rtx tem 4539 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl), 4540 tree_low_cst (TREE_VALUE (arglist), 1)); 4541 4542 /* Some ports cannot access arbitrary stack frames. */ 4543 if (tem == NULL) 4544 { 4545 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4546 warning (0, "unsupported argument to %<__builtin_frame_address%>"); 4547 else 4548 warning (0, "unsupported argument to %<__builtin_return_address%>"); 4549 return const0_rtx; 4550 } 4551 4552 /* For __builtin_frame_address, return what we've got. */ 4553 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4554 return tem; 4555 4556 if (!REG_P (tem) 4557 && ! CONSTANT_P (tem)) 4558 tem = copy_to_mode_reg (Pmode, tem); 4559 return tem; 4560 } 4561} 4562 4563/* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if 4564 we failed and the caller should emit a normal call, otherwise try to get 4565 the result in TARGET, if convenient. */ 4566 4567static rtx 4568expand_builtin_alloca (tree arglist, rtx target) 4569{ 4570 rtx op0; 4571 rtx result; 4572 4573 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca() 4574 should always expand to function calls. These can be intercepted 4575 in libmudflap. */ 4576 if (flag_mudflap) 4577 return 0; 4578 4579 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 4580 return 0; 4581 4582 /* Compute the argument. */ 4583 op0 = expand_normal (TREE_VALUE (arglist)); 4584 4585 /* Allocate the desired space. */ 4586 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT); 4587 result = convert_memory_address (ptr_mode, result); 4588 4589 return result; 4590} 4591 4592/* Expand a call to a unary builtin. The arguments are in ARGLIST. 4593 Return 0 if a normal call should be emitted rather than expanding the 4594 function in-line. If convenient, the result should be placed in TARGET. 4595 SUBTARGET may be used as the target for computing one of EXP's operands. */ 4596 4597static rtx 4598expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target, 4599 rtx subtarget, optab op_optab) 4600{ 4601 rtx op0; 4602 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 4603 return 0; 4604 4605 /* Compute the argument. */ 4606 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0); 4607 /* Compute op, into TARGET if possible. 4608 Set TARGET to wherever the result comes back. */ 4609 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))), 4610 op_optab, op0, target, 1); 4611 gcc_assert (target); 4612 4613 return convert_to_mode (target_mode, target, 0); 4614} 4615 4616/* If the string passed to fputs is a constant and is one character 4617 long, we attempt to transform this call into __builtin_fputc(). */ 4618 4619static rtx 4620expand_builtin_fputs (tree arglist, rtx target, bool unlocked) 4621{ 4622 /* Verify the arguments in the original call. */ 4623 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 4624 { 4625 tree result = fold_builtin_fputs (arglist, (target == const0_rtx), 4626 unlocked, NULL_TREE); 4627 if (result) 4628 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL); 4629 } 4630 return 0; 4631} 4632 4633/* Expand a call to __builtin_expect. We return our argument and emit a 4634 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in 4635 a non-jump context. */ 4636 4637static rtx 4638expand_builtin_expect (tree arglist, rtx target) 4639{ 4640 tree exp, c; 4641 rtx note, rtx_c; 4642 4643 if (arglist == NULL_TREE 4644 || TREE_CHAIN (arglist) == NULL_TREE) 4645 return const0_rtx; 4646 exp = TREE_VALUE (arglist); 4647 c = TREE_VALUE (TREE_CHAIN (arglist)); 4648 4649 if (TREE_CODE (c) != INTEGER_CST) 4650 { 4651 error ("second argument to %<__builtin_expect%> must be a constant"); 4652 c = integer_zero_node; 4653 } 4654 4655 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL); 4656 4657 /* Don't bother with expected value notes for integral constants. */ 4658 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT) 4659 { 4660 /* We do need to force this into a register so that we can be 4661 moderately sure to be able to correctly interpret the branch 4662 condition later. */ 4663 target = force_reg (GET_MODE (target), target); 4664 4665 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL); 4666 4667 note = emit_note (NOTE_INSN_EXPECTED_VALUE); 4668 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c); 4669 } 4670 4671 return target; 4672} 4673 4674/* Like expand_builtin_expect, except do this in a jump context. This is 4675 called from do_jump if the conditional is a __builtin_expect. Return either 4676 a list of insns to emit the jump or NULL if we cannot optimize 4677 __builtin_expect. We need to optimize this at jump time so that machines 4678 like the PowerPC don't turn the test into a SCC operation, and then jump 4679 based on the test being 0/1. */ 4680 4681rtx 4682expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label) 4683{ 4684 tree arglist = TREE_OPERAND (exp, 1); 4685 tree arg0 = TREE_VALUE (arglist); 4686 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 4687 rtx ret = NULL_RTX; 4688 4689 /* Only handle __builtin_expect (test, 0) and 4690 __builtin_expect (test, 1). */ 4691 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE 4692 && (integer_zerop (arg1) || integer_onep (arg1))) 4693 { 4694 rtx insn, drop_through_label, temp; 4695 4696 /* Expand the jump insns. */ 4697 start_sequence (); 4698 do_jump (arg0, if_false_label, if_true_label); 4699 ret = get_insns (); 4700 4701 drop_through_label = get_last_insn (); 4702 if (drop_through_label && NOTE_P (drop_through_label)) 4703 drop_through_label = prev_nonnote_insn (drop_through_label); 4704 if (drop_through_label && !LABEL_P (drop_through_label)) 4705 drop_through_label = NULL_RTX; 4706 end_sequence (); 4707 4708 if (! if_true_label) 4709 if_true_label = drop_through_label; 4710 if (! if_false_label) 4711 if_false_label = drop_through_label; 4712 4713 /* Go through and add the expect's to each of the conditional jumps. */ 4714 insn = ret; 4715 while (insn != NULL_RTX) 4716 { 4717 rtx next = NEXT_INSN (insn); 4718 4719 if (JUMP_P (insn) && any_condjump_p (insn)) 4720 { 4721 rtx ifelse = SET_SRC (pc_set (insn)); 4722 rtx then_dest = XEXP (ifelse, 1); 4723 rtx else_dest = XEXP (ifelse, 2); 4724 int taken = -1; 4725 4726 /* First check if we recognize any of the labels. */ 4727 if (GET_CODE (then_dest) == LABEL_REF 4728 && XEXP (then_dest, 0) == if_true_label) 4729 taken = 1; 4730 else if (GET_CODE (then_dest) == LABEL_REF 4731 && XEXP (then_dest, 0) == if_false_label) 4732 taken = 0; 4733 else if (GET_CODE (else_dest) == LABEL_REF 4734 && XEXP (else_dest, 0) == if_false_label) 4735 taken = 1; 4736 else if (GET_CODE (else_dest) == LABEL_REF 4737 && XEXP (else_dest, 0) == if_true_label) 4738 taken = 0; 4739 /* Otherwise check where we drop through. */ 4740 else if (else_dest == pc_rtx) 4741 { 4742 if (next && NOTE_P (next)) 4743 next = next_nonnote_insn (next); 4744 4745 if (next && JUMP_P (next) 4746 && any_uncondjump_p (next)) 4747 temp = XEXP (SET_SRC (pc_set (next)), 0); 4748 else 4749 temp = next; 4750 4751 /* TEMP is either a CODE_LABEL, NULL_RTX or something 4752 else that can't possibly match either target label. */ 4753 if (temp == if_false_label) 4754 taken = 1; 4755 else if (temp == if_true_label) 4756 taken = 0; 4757 } 4758 else if (then_dest == pc_rtx) 4759 { 4760 if (next && NOTE_P (next)) 4761 next = next_nonnote_insn (next); 4762 4763 if (next && JUMP_P (next) 4764 && any_uncondjump_p (next)) 4765 temp = XEXP (SET_SRC (pc_set (next)), 0); 4766 else 4767 temp = next; 4768 4769 if (temp == if_false_label) 4770 taken = 0; 4771 else if (temp == if_true_label) 4772 taken = 1; 4773 } 4774 4775 if (taken != -1) 4776 { 4777 /* If the test is expected to fail, reverse the 4778 probabilities. */ 4779 if (integer_zerop (arg1)) 4780 taken = 1 - taken; 4781 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken); 4782 } 4783 } 4784 4785 insn = next; 4786 } 4787 } 4788 4789 return ret; 4790} 4791 4792void 4793expand_builtin_trap (void) 4794{ 4795#ifdef HAVE_trap 4796 if (HAVE_trap) 4797 emit_insn (gen_trap ()); 4798 else 4799#endif 4800 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0); 4801 emit_barrier (); 4802} 4803 4804/* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST. 4805 Return 0 if a normal call should be emitted rather than expanding 4806 the function inline. If convenient, the result should be placed 4807 in TARGET. SUBTARGET may be used as the target for computing 4808 the operand. */ 4809 4810static rtx 4811expand_builtin_fabs (tree arglist, rtx target, rtx subtarget) 4812{ 4813 enum machine_mode mode; 4814 tree arg; 4815 rtx op0; 4816 4817 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 4818 return 0; 4819 4820 arg = TREE_VALUE (arglist); 4821 mode = TYPE_MODE (TREE_TYPE (arg)); 4822 op0 = expand_expr (arg, subtarget, VOIDmode, 0); 4823 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1)); 4824} 4825 4826/* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST. 4827 Return NULL is a normal call should be emitted rather than expanding the 4828 function inline. If convenient, the result should be placed in TARGET. 4829 SUBTARGET may be used as the target for computing the operand. */ 4830 4831static rtx 4832expand_builtin_copysign (tree arglist, rtx target, rtx subtarget) 4833{ 4834 rtx op0, op1; 4835 tree arg; 4836 4837 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 4838 return 0; 4839 4840 arg = TREE_VALUE (arglist); 4841 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 4842 4843 arg = TREE_VALUE (TREE_CHAIN (arglist)); 4844 op1 = expand_normal (arg); 4845 4846 return expand_copysign (op0, op1, target); 4847} 4848 4849/* Create a new constant string literal and return a char* pointer to it. 4850 The STRING_CST value is the LEN characters at STR. */ 4851tree 4852build_string_literal (int len, const char *str) 4853{ 4854 tree t, elem, index, type; 4855 4856 t = build_string (len, str); 4857 elem = build_type_variant (char_type_node, 1, 0); 4858 index = build_index_type (build_int_cst (NULL_TREE, len - 1)); 4859 type = build_array_type (elem, index); 4860 TREE_TYPE (t) = type; 4861 TREE_CONSTANT (t) = 1; 4862 TREE_INVARIANT (t) = 1; 4863 TREE_READONLY (t) = 1; 4864 TREE_STATIC (t) = 1; 4865 4866 type = build_pointer_type (type); 4867 t = build1 (ADDR_EXPR, type, t); 4868 4869 type = build_pointer_type (elem); 4870 t = build1 (NOP_EXPR, type, t); 4871 return t; 4872} 4873 4874/* Expand EXP, a call to printf or printf_unlocked. 4875 Return 0 if a normal call should be emitted rather than transforming 4876 the function inline. If convenient, the result should be placed in 4877 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked 4878 call. */ 4879static rtx 4880expand_builtin_printf (tree exp, rtx target, enum machine_mode mode, 4881 bool unlocked) 4882{ 4883 tree arglist = TREE_OPERAND (exp, 1); 4884 /* If we're using an unlocked function, assume the other unlocked 4885 functions exist explicitly. */ 4886 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] 4887 : implicit_built_in_decls[BUILT_IN_PUTCHAR]; 4888 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED] 4889 : implicit_built_in_decls[BUILT_IN_PUTS]; 4890 const char *fmt_str; 4891 tree fn, fmt, arg; 4892 4893 /* If the return value is used, don't do the transformation. */ 4894 if (target != const0_rtx) 4895 return 0; 4896 4897 /* Verify the required arguments in the original call. */ 4898 if (! arglist) 4899 return 0; 4900 fmt = TREE_VALUE (arglist); 4901 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 4902 return 0; 4903 arglist = TREE_CHAIN (arglist); 4904 4905 /* Check whether the format is a literal string constant. */ 4906 fmt_str = c_getstr (fmt); 4907 if (fmt_str == NULL) 4908 return 0; 4909 4910 if (!init_target_chars()) 4911 return 0; 4912 4913 /* If the format specifier was "%s\n", call __builtin_puts(arg). */ 4914 if (strcmp (fmt_str, target_percent_s_newline) == 0) 4915 { 4916 if (! arglist 4917 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))) 4918 || TREE_CHAIN (arglist)) 4919 return 0; 4920 fn = fn_puts; 4921 } 4922 /* If the format specifier was "%c", call __builtin_putchar(arg). */ 4923 else if (strcmp (fmt_str, target_percent_c) == 0) 4924 { 4925 if (! arglist 4926 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE 4927 || TREE_CHAIN (arglist)) 4928 return 0; 4929 fn = fn_putchar; 4930 } 4931 else 4932 { 4933 /* We can't handle anything else with % args or %% ... yet. */ 4934 if (strchr (fmt_str, target_percent)) 4935 return 0; 4936 4937 if (arglist) 4938 return 0; 4939 4940 /* If the format specifier was "", printf does nothing. */ 4941 if (fmt_str[0] == '\0') 4942 return const0_rtx; 4943 /* If the format specifier has length of 1, call putchar. */ 4944 if (fmt_str[1] == '\0') 4945 { 4946 /* Given printf("c"), (where c is any one character,) 4947 convert "c"[0] to an int and pass that to the replacement 4948 function. */ 4949 arg = build_int_cst (NULL_TREE, fmt_str[0]); 4950 arglist = build_tree_list (NULL_TREE, arg); 4951 fn = fn_putchar; 4952 } 4953 else 4954 { 4955 /* If the format specifier was "string\n", call puts("string"). */ 4956 size_t len = strlen (fmt_str); 4957 if ((unsigned char)fmt_str[len - 1] == target_newline) 4958 { 4959 /* Create a NUL-terminated string that's one char shorter 4960 than the original, stripping off the trailing '\n'. */ 4961 char *newstr = alloca (len); 4962 memcpy (newstr, fmt_str, len - 1); 4963 newstr[len - 1] = 0; 4964 4965 arg = build_string_literal (len, newstr); 4966 arglist = build_tree_list (NULL_TREE, arg); 4967 fn = fn_puts; 4968 } 4969 else 4970 /* We'd like to arrange to call fputs(string,stdout) here, 4971 but we need stdout and don't have a way to get it yet. */ 4972 return 0; 4973 } 4974 } 4975 4976 if (!fn) 4977 return 0; 4978 fn = build_function_call_expr (fn, arglist); 4979 if (TREE_CODE (fn) == CALL_EXPR) 4980 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 4981 return expand_expr (fn, target, mode, EXPAND_NORMAL); 4982} 4983 4984/* Expand EXP, a call to fprintf or fprintf_unlocked. 4985 Return 0 if a normal call should be emitted rather than transforming 4986 the function inline. If convenient, the result should be placed in 4987 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked 4988 call. */ 4989static rtx 4990expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode, 4991 bool unlocked) 4992{ 4993 tree arglist = TREE_OPERAND (exp, 1); 4994 /* If we're using an unlocked function, assume the other unlocked 4995 functions exist explicitly. */ 4996 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED] 4997 : implicit_built_in_decls[BUILT_IN_FPUTC]; 4998 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED] 4999 : implicit_built_in_decls[BUILT_IN_FPUTS]; 5000 const char *fmt_str; 5001 tree fn, fmt, fp, arg; 5002 5003 /* If the return value is used, don't do the transformation. */ 5004 if (target != const0_rtx) 5005 return 0; 5006 5007 /* Verify the required arguments in the original call. */ 5008 if (! arglist) 5009 return 0; 5010 fp = TREE_VALUE (arglist); 5011 if (! POINTER_TYPE_P (TREE_TYPE (fp))) 5012 return 0; 5013 arglist = TREE_CHAIN (arglist); 5014 if (! arglist) 5015 return 0; 5016 fmt = TREE_VALUE (arglist); 5017 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 5018 return 0; 5019 arglist = TREE_CHAIN (arglist); 5020 5021 /* Check whether the format is a literal string constant. */ 5022 fmt_str = c_getstr (fmt); 5023 if (fmt_str == NULL) 5024 return 0; 5025 5026 if (!init_target_chars()) 5027 return 0; 5028 5029 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */ 5030 if (strcmp (fmt_str, target_percent_s) == 0) 5031 { 5032 if (! arglist 5033 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))) 5034 || TREE_CHAIN (arglist)) 5035 return 0; 5036 arg = TREE_VALUE (arglist); 5037 arglist = build_tree_list (NULL_TREE, fp); 5038 arglist = tree_cons (NULL_TREE, arg, arglist); 5039 fn = fn_fputs; 5040 } 5041 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */ 5042 else if (strcmp (fmt_str, target_percent_c) == 0) 5043 { 5044 if (! arglist 5045 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE 5046 || TREE_CHAIN (arglist)) 5047 return 0; 5048 arg = TREE_VALUE (arglist); 5049 arglist = build_tree_list (NULL_TREE, fp); 5050 arglist = tree_cons (NULL_TREE, arg, arglist); 5051 fn = fn_fputc; 5052 } 5053 else 5054 { 5055 /* We can't handle anything else with % args or %% ... yet. */ 5056 if (strchr (fmt_str, target_percent)) 5057 return 0; 5058 5059 if (arglist) 5060 return 0; 5061 5062 /* If the format specifier was "", fprintf does nothing. */ 5063 if (fmt_str[0] == '\0') 5064 { 5065 /* Evaluate and ignore FILE* argument for side-effects. */ 5066 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL); 5067 return const0_rtx; 5068 } 5069 5070 /* When "string" doesn't contain %, replace all cases of 5071 fprintf(stream,string) with fputs(string,stream). The fputs 5072 builtin will take care of special cases like length == 1. */ 5073 arglist = build_tree_list (NULL_TREE, fp); 5074 arglist = tree_cons (NULL_TREE, fmt, arglist); 5075 fn = fn_fputs; 5076 } 5077 5078 if (!fn) 5079 return 0; 5080 fn = build_function_call_expr (fn, arglist); 5081 if (TREE_CODE (fn) == CALL_EXPR) 5082 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 5083 return expand_expr (fn, target, mode, EXPAND_NORMAL); 5084} 5085 5086/* Expand a call to sprintf with argument list ARGLIST. Return 0 if 5087 a normal call should be emitted rather than expanding the function 5088 inline. If convenient, the result should be placed in TARGET with 5089 mode MODE. */ 5090 5091static rtx 5092expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode) 5093{ 5094 tree orig_arglist, dest, fmt; 5095 const char *fmt_str; 5096 5097 orig_arglist = arglist; 5098 5099 /* Verify the required arguments in the original call. */ 5100 if (! arglist) 5101 return 0; 5102 dest = TREE_VALUE (arglist); 5103 if (! POINTER_TYPE_P (TREE_TYPE (dest))) 5104 return 0; 5105 arglist = TREE_CHAIN (arglist); 5106 if (! arglist) 5107 return 0; 5108 fmt = TREE_VALUE (arglist); 5109 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 5110 return 0; 5111 arglist = TREE_CHAIN (arglist); 5112 5113 /* Check whether the format is a literal string constant. */ 5114 fmt_str = c_getstr (fmt); 5115 if (fmt_str == NULL) 5116 return 0; 5117 5118 if (!init_target_chars()) 5119 return 0; 5120 5121 /* If the format doesn't contain % args or %%, use strcpy. */ 5122 if (strchr (fmt_str, target_percent) == 0) 5123 { 5124 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 5125 tree exp; 5126 5127 if (arglist || ! fn) 5128 return 0; 5129 expand_expr (build_function_call_expr (fn, orig_arglist), 5130 const0_rtx, VOIDmode, EXPAND_NORMAL); 5131 if (target == const0_rtx) 5132 return const0_rtx; 5133 exp = build_int_cst (NULL_TREE, strlen (fmt_str)); 5134 return expand_expr (exp, target, mode, EXPAND_NORMAL); 5135 } 5136 /* If the format is "%s", use strcpy if the result isn't used. */ 5137 else if (strcmp (fmt_str, target_percent_s) == 0) 5138 { 5139 tree fn, arg, len; 5140 fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 5141 5142 if (! fn) 5143 return 0; 5144 5145 if (! arglist || TREE_CHAIN (arglist)) 5146 return 0; 5147 arg = TREE_VALUE (arglist); 5148 if (! POINTER_TYPE_P (TREE_TYPE (arg))) 5149 return 0; 5150 5151 if (target != const0_rtx) 5152 { 5153 len = c_strlen (arg, 1); 5154 if (! len || TREE_CODE (len) != INTEGER_CST) 5155 return 0; 5156 } 5157 else 5158 len = NULL_TREE; 5159 5160 arglist = build_tree_list (NULL_TREE, arg); 5161 arglist = tree_cons (NULL_TREE, dest, arglist); 5162 expand_expr (build_function_call_expr (fn, arglist), 5163 const0_rtx, VOIDmode, EXPAND_NORMAL); 5164 5165 if (target == const0_rtx) 5166 return const0_rtx; 5167 return expand_expr (len, target, mode, EXPAND_NORMAL); 5168 } 5169 5170 return 0; 5171} 5172 5173/* Expand a call to either the entry or exit function profiler. */ 5174 5175static rtx 5176expand_builtin_profile_func (bool exitp) 5177{ 5178 rtx this, which; 5179 5180 this = DECL_RTL (current_function_decl); 5181 gcc_assert (MEM_P (this)); 5182 this = XEXP (this, 0); 5183 5184 if (exitp) 5185 which = profile_function_exit_libfunc; 5186 else 5187 which = profile_function_entry_libfunc; 5188 5189 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode, 5190 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS, 5191 0), 5192 Pmode); 5193 5194 return const0_rtx; 5195} 5196 5197/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */ 5198 5199static rtx 5200round_trampoline_addr (rtx tramp) 5201{ 5202 rtx temp, addend, mask; 5203 5204 /* If we don't need too much alignment, we'll have been guaranteed 5205 proper alignment by get_trampoline_type. */ 5206 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY) 5207 return tramp; 5208 5209 /* Round address up to desired boundary. */ 5210 temp = gen_reg_rtx (Pmode); 5211 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1); 5212 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT); 5213 5214 temp = expand_simple_binop (Pmode, PLUS, tramp, addend, 5215 temp, 0, OPTAB_LIB_WIDEN); 5216 tramp = expand_simple_binop (Pmode, AND, temp, mask, 5217 temp, 0, OPTAB_LIB_WIDEN); 5218 5219 return tramp; 5220} 5221 5222static rtx 5223expand_builtin_init_trampoline (tree arglist) 5224{ 5225 tree t_tramp, t_func, t_chain; 5226 rtx r_tramp, r_func, r_chain; 5227#ifdef TRAMPOLINE_TEMPLATE 5228 rtx blktramp; 5229#endif 5230 5231 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, 5232 POINTER_TYPE, VOID_TYPE)) 5233 return NULL_RTX; 5234 5235 t_tramp = TREE_VALUE (arglist); 5236 arglist = TREE_CHAIN (arglist); 5237 t_func = TREE_VALUE (arglist); 5238 arglist = TREE_CHAIN (arglist); 5239 t_chain = TREE_VALUE (arglist); 5240 5241 r_tramp = expand_normal (t_tramp); 5242 r_func = expand_normal (t_func); 5243 r_chain = expand_normal (t_chain); 5244 5245 /* Generate insns to initialize the trampoline. */ 5246 r_tramp = round_trampoline_addr (r_tramp); 5247#ifdef TRAMPOLINE_TEMPLATE 5248 blktramp = gen_rtx_MEM (BLKmode, r_tramp); 5249 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT); 5250 emit_block_move (blktramp, assemble_trampoline_template (), 5251 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); 5252#endif 5253 trampolines_created = 1; 5254 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain); 5255 5256 return const0_rtx; 5257} 5258 5259static rtx 5260expand_builtin_adjust_trampoline (tree arglist) 5261{ 5262 rtx tramp; 5263 5264 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 5265 return NULL_RTX; 5266 5267 tramp = expand_normal (TREE_VALUE (arglist)); 5268 tramp = round_trampoline_addr (tramp); 5269#ifdef TRAMPOLINE_ADJUST_ADDRESS 5270 TRAMPOLINE_ADJUST_ADDRESS (tramp); 5271#endif 5272 5273 return tramp; 5274} 5275 5276/* Expand a call to the built-in signbit, signbitf or signbitl function. 5277 Return NULL_RTX if a normal call should be emitted rather than expanding 5278 the function in-line. EXP is the expression that is a call to the builtin 5279 function; if convenient, the result should be placed in TARGET. */ 5280 5281static rtx 5282expand_builtin_signbit (tree exp, rtx target) 5283{ 5284 const struct real_format *fmt; 5285 enum machine_mode fmode, imode, rmode; 5286 HOST_WIDE_INT hi, lo; 5287 tree arg, arglist; 5288 int word, bitpos; 5289 rtx temp; 5290 5291 arglist = TREE_OPERAND (exp, 1); 5292 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 5293 return 0; 5294 5295 arg = TREE_VALUE (arglist); 5296 fmode = TYPE_MODE (TREE_TYPE (arg)); 5297 rmode = TYPE_MODE (TREE_TYPE (exp)); 5298 fmt = REAL_MODE_FORMAT (fmode); 5299 5300 /* For floating point formats without a sign bit, implement signbit 5301 as "ARG < 0.0". */ 5302 bitpos = fmt->signbit_ro; 5303 if (bitpos < 0) 5304 { 5305 /* But we can't do this if the format supports signed zero. */ 5306 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode)) 5307 return 0; 5308 5309 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg, 5310 build_real (TREE_TYPE (arg), dconst0)); 5311 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL); 5312 } 5313 5314 temp = expand_normal (arg); 5315 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD) 5316 { 5317 imode = int_mode_for_mode (fmode); 5318 if (imode == BLKmode) 5319 return 0; 5320 temp = gen_lowpart (imode, temp); 5321 } 5322 else 5323 { 5324 imode = word_mode; 5325 /* Handle targets with different FP word orders. */ 5326 if (FLOAT_WORDS_BIG_ENDIAN) 5327 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD; 5328 else 5329 word = bitpos / BITS_PER_WORD; 5330 temp = operand_subword_force (temp, word, fmode); 5331 bitpos = bitpos % BITS_PER_WORD; 5332 } 5333 5334 /* Force the intermediate word_mode (or narrower) result into a 5335 register. This avoids attempting to create paradoxical SUBREGs 5336 of floating point modes below. */ 5337 temp = force_reg (imode, temp); 5338 5339 /* If the bitpos is within the "result mode" lowpart, the operation 5340 can be implement with a single bitwise AND. Otherwise, we need 5341 a right shift and an AND. */ 5342 5343 if (bitpos < GET_MODE_BITSIZE (rmode)) 5344 { 5345 if (bitpos < HOST_BITS_PER_WIDE_INT) 5346 { 5347 hi = 0; 5348 lo = (HOST_WIDE_INT) 1 << bitpos; 5349 } 5350 else 5351 { 5352 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT); 5353 lo = 0; 5354 } 5355 5356 if (imode != rmode) 5357 temp = gen_lowpart (rmode, temp); 5358 temp = expand_binop (rmode, and_optab, temp, 5359 immed_double_const (lo, hi, rmode), 5360 NULL_RTX, 1, OPTAB_LIB_WIDEN); 5361 } 5362 else 5363 { 5364 /* Perform a logical right shift to place the signbit in the least 5365 significant bit, then truncate the result to the desired mode 5366 and mask just this bit. */ 5367 temp = expand_shift (RSHIFT_EXPR, imode, temp, 5368 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1); 5369 temp = gen_lowpart (rmode, temp); 5370 temp = expand_binop (rmode, and_optab, temp, const1_rtx, 5371 NULL_RTX, 1, OPTAB_LIB_WIDEN); 5372 } 5373 5374 return temp; 5375} 5376 5377/* Expand fork or exec calls. TARGET is the desired target of the 5378 call. ARGLIST is the list of arguments of the call. FN is the 5379 identificator of the actual function. IGNORE is nonzero if the 5380 value is to be ignored. */ 5381 5382static rtx 5383expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore) 5384{ 5385 tree id, decl; 5386 tree call; 5387 5388 /* If we are not profiling, just call the function. */ 5389 if (!profile_arc_flag) 5390 return NULL_RTX; 5391 5392 /* Otherwise call the wrapper. This should be equivalent for the rest of 5393 compiler, so the code does not diverge, and the wrapper may run the 5394 code necessary for keeping the profiling sane. */ 5395 5396 switch (DECL_FUNCTION_CODE (fn)) 5397 { 5398 case BUILT_IN_FORK: 5399 id = get_identifier ("__gcov_fork"); 5400 break; 5401 5402 case BUILT_IN_EXECL: 5403 id = get_identifier ("__gcov_execl"); 5404 break; 5405 5406 case BUILT_IN_EXECV: 5407 id = get_identifier ("__gcov_execv"); 5408 break; 5409 5410 case BUILT_IN_EXECLP: 5411 id = get_identifier ("__gcov_execlp"); 5412 break; 5413 5414 case BUILT_IN_EXECLE: 5415 id = get_identifier ("__gcov_execle"); 5416 break; 5417 5418 case BUILT_IN_EXECVP: 5419 id = get_identifier ("__gcov_execvp"); 5420 break; 5421 5422 case BUILT_IN_EXECVE: 5423 id = get_identifier ("__gcov_execve"); 5424 break; 5425 5426 default: 5427 gcc_unreachable (); 5428 } 5429 5430 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn)); 5431 DECL_EXTERNAL (decl) = 1; 5432 TREE_PUBLIC (decl) = 1; 5433 DECL_ARTIFICIAL (decl) = 1; 5434 TREE_NOTHROW (decl) = 1; 5435 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; 5436 DECL_VISIBILITY_SPECIFIED (decl) = 1; 5437 call = build_function_call_expr (decl, arglist); 5438 5439 return expand_call (call, target, ignore); 5440} 5441 5442 5443/* Reconstitute a mode for a __sync intrinsic operation. Since the type of 5444 the pointer in these functions is void*, the tree optimizers may remove 5445 casts. The mode computed in expand_builtin isn't reliable either, due 5446 to __sync_bool_compare_and_swap. 5447 5448 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the 5449 group of builtins. This gives us log2 of the mode size. */ 5450 5451static inline enum machine_mode 5452get_builtin_sync_mode (int fcode_diff) 5453{ 5454 /* The size is not negotiable, so ask not to get BLKmode in return 5455 if the target indicates that a smaller size would be better. */ 5456 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0); 5457} 5458 5459/* Expand the memory expression LOC and return the appropriate memory operand 5460 for the builtin_sync operations. */ 5461 5462static rtx 5463get_builtin_sync_mem (tree loc, enum machine_mode mode) 5464{ 5465 rtx addr, mem; 5466 5467 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM); 5468 5469 /* Note that we explicitly do not want any alias information for this 5470 memory, so that we kill all other live memories. Otherwise we don't 5471 satisfy the full barrier semantics of the intrinsic. */ 5472 mem = validize_mem (gen_rtx_MEM (mode, addr)); 5473 5474 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT)); 5475 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); 5476 MEM_VOLATILE_P (mem) = 1; 5477 5478 return mem; 5479} 5480 5481/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics. 5482 ARGLIST is the operands list to the function. CODE is the rtx code 5483 that corresponds to the arithmetic or logical operation from the name; 5484 an exception here is that NOT actually means NAND. TARGET is an optional 5485 place for us to store the results; AFTER is true if this is the 5486 fetch_and_xxx form. IGNORE is true if we don't actually care about 5487 the result of the operation at all. */ 5488 5489static rtx 5490expand_builtin_sync_operation (enum machine_mode mode, tree arglist, 5491 enum rtx_code code, bool after, 5492 rtx target, bool ignore) 5493{ 5494 rtx val, mem; 5495 enum machine_mode old_mode; 5496 5497 /* Expand the operands. */ 5498 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode); 5499 5500 arglist = TREE_CHAIN (arglist); 5501 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL); 5502 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5503 of CONST_INTs, where we know the old_mode only from the call argument. */ 5504 old_mode = GET_MODE (val); 5505 if (old_mode == VOIDmode) 5506 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))); 5507 val = convert_modes (mode, old_mode, val, 1); 5508 5509 if (ignore) 5510 return expand_sync_operation (mem, val, code); 5511 else 5512 return expand_sync_fetch_operation (mem, val, code, after, target); 5513} 5514 5515/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap 5516 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is 5517 true if this is the boolean form. TARGET is a place for us to store the 5518 results; this is NOT optional if IS_BOOL is true. */ 5519 5520static rtx 5521expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist, 5522 bool is_bool, rtx target) 5523{ 5524 rtx old_val, new_val, mem; 5525 enum machine_mode old_mode; 5526 5527 /* Expand the operands. */ 5528 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode); 5529 5530 arglist = TREE_CHAIN (arglist); 5531 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL); 5532 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5533 of CONST_INTs, where we know the old_mode only from the call argument. */ 5534 old_mode = GET_MODE (old_val); 5535 if (old_mode == VOIDmode) 5536 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))); 5537 old_val = convert_modes (mode, old_mode, old_val, 1); 5538 5539 arglist = TREE_CHAIN (arglist); 5540 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL); 5541 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5542 of CONST_INTs, where we know the old_mode only from the call argument. */ 5543 old_mode = GET_MODE (new_val); 5544 if (old_mode == VOIDmode) 5545 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))); 5546 new_val = convert_modes (mode, old_mode, new_val, 1); 5547 5548 if (is_bool) 5549 return expand_bool_compare_and_swap (mem, old_val, new_val, target); 5550 else 5551 return expand_val_compare_and_swap (mem, old_val, new_val, target); 5552} 5553 5554/* Expand the __sync_lock_test_and_set intrinsic. Note that the most 5555 general form is actually an atomic exchange, and some targets only 5556 support a reduced form with the second argument being a constant 1. 5557 ARGLIST is the operands list to the function; TARGET is an optional 5558 place for us to store the results. */ 5559 5560static rtx 5561expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist, 5562 rtx target) 5563{ 5564 rtx val, mem; 5565 enum machine_mode old_mode; 5566 5567 /* Expand the operands. */ 5568 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode); 5569 5570 arglist = TREE_CHAIN (arglist); 5571 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL); 5572 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5573 of CONST_INTs, where we know the old_mode only from the call argument. */ 5574 old_mode = GET_MODE (val); 5575 if (old_mode == VOIDmode) 5576 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))); 5577 val = convert_modes (mode, old_mode, val, 1); 5578 5579 return expand_sync_lock_test_and_set (mem, val, target); 5580} 5581 5582/* Expand the __sync_synchronize intrinsic. */ 5583 5584static void 5585expand_builtin_synchronize (void) 5586{ 5587 tree x; 5588 5589#ifdef HAVE_memory_barrier 5590 if (HAVE_memory_barrier) 5591 { 5592 emit_insn (gen_memory_barrier ()); 5593 return; 5594 } 5595#endif 5596 5597 /* If no explicit memory barrier instruction is available, create an 5598 empty asm stmt with a memory clobber. */ 5599 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL, 5600 tree_cons (NULL, build_string (6, "memory"), NULL)); 5601 ASM_VOLATILE_P (x) = 1; 5602 expand_asm_expr (x); 5603} 5604 5605/* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list 5606 to the function. */ 5607 5608static void 5609expand_builtin_lock_release (enum machine_mode mode, tree arglist) 5610{ 5611 enum insn_code icode; 5612 rtx mem, insn; 5613 rtx val = const0_rtx; 5614 5615 /* Expand the operands. */ 5616 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode); 5617 5618 /* If there is an explicit operation in the md file, use it. */ 5619 icode = sync_lock_release[mode]; 5620 if (icode != CODE_FOR_nothing) 5621 { 5622 if (!insn_data[icode].operand[1].predicate (val, mode)) 5623 val = force_reg (mode, val); 5624 5625 insn = GEN_FCN (icode) (mem, val); 5626 if (insn) 5627 { 5628 emit_insn (insn); 5629 return; 5630 } 5631 } 5632 5633 /* Otherwise we can implement this operation by emitting a barrier 5634 followed by a store of zero. */ 5635 expand_builtin_synchronize (); 5636 emit_move_insn (mem, val); 5637} 5638 5639/* Expand an expression EXP that calls a built-in function, 5640 with result going to TARGET if that's convenient 5641 (and in mode MODE if that's convenient). 5642 SUBTARGET may be used as the target for computing one of EXP's operands. 5643 IGNORE is nonzero if the value is to be ignored. */ 5644 5645rtx 5646expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, 5647 int ignore) 5648{ 5649 tree fndecl = get_callee_fndecl (exp); 5650 tree arglist = TREE_OPERAND (exp, 1); 5651 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 5652 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp)); 5653 5654 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 5655 return targetm.expand_builtin (exp, target, subtarget, mode, ignore); 5656 5657 /* When not optimizing, generate calls to library functions for a certain 5658 set of builtins. */ 5659 if (!optimize 5660 && !called_as_built_in (fndecl) 5661 && DECL_ASSEMBLER_NAME_SET_P (fndecl) 5662 && fcode != BUILT_IN_ALLOCA) 5663 return expand_call (exp, target, ignore); 5664 5665 /* The built-in function expanders test for target == const0_rtx 5666 to determine whether the function's result will be ignored. */ 5667 if (ignore) 5668 target = const0_rtx; 5669 5670 /* If the result of a pure or const built-in function is ignored, and 5671 none of its arguments are volatile, we can avoid expanding the 5672 built-in call and just evaluate the arguments for side-effects. */ 5673 if (target == const0_rtx 5674 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl))) 5675 { 5676 bool volatilep = false; 5677 tree arg; 5678 5679 for (arg = arglist; arg; arg = TREE_CHAIN (arg)) 5680 if (TREE_THIS_VOLATILE (TREE_VALUE (arg))) 5681 { 5682 volatilep = true; 5683 break; 5684 } 5685 5686 if (! volatilep) 5687 { 5688 for (arg = arglist; arg; arg = TREE_CHAIN (arg)) 5689 expand_expr (TREE_VALUE (arg), const0_rtx, 5690 VOIDmode, EXPAND_NORMAL); 5691 return const0_rtx; 5692 } 5693 } 5694 5695 switch (fcode) 5696 { 5697 CASE_FLT_FN (BUILT_IN_FABS): 5698 target = expand_builtin_fabs (arglist, target, subtarget); 5699 if (target) 5700 return target; 5701 break; 5702 5703 CASE_FLT_FN (BUILT_IN_COPYSIGN): 5704 target = expand_builtin_copysign (arglist, target, subtarget); 5705 if (target) 5706 return target; 5707 break; 5708 5709 /* Just do a normal library call if we were unable to fold 5710 the values. */ 5711 CASE_FLT_FN (BUILT_IN_CABS): 5712 break; 5713 5714 CASE_FLT_FN (BUILT_IN_EXP): 5715 CASE_FLT_FN (BUILT_IN_EXP10): 5716 CASE_FLT_FN (BUILT_IN_POW10): 5717 CASE_FLT_FN (BUILT_IN_EXP2): 5718 CASE_FLT_FN (BUILT_IN_EXPM1): 5719 CASE_FLT_FN (BUILT_IN_LOGB): 5720 CASE_FLT_FN (BUILT_IN_ILOGB): 5721 CASE_FLT_FN (BUILT_IN_LOG): 5722 CASE_FLT_FN (BUILT_IN_LOG10): 5723 CASE_FLT_FN (BUILT_IN_LOG2): 5724 CASE_FLT_FN (BUILT_IN_LOG1P): 5725 CASE_FLT_FN (BUILT_IN_TAN): 5726 CASE_FLT_FN (BUILT_IN_ASIN): 5727 CASE_FLT_FN (BUILT_IN_ACOS): 5728 CASE_FLT_FN (BUILT_IN_ATAN): 5729 /* Treat these like sqrt only if unsafe math optimizations are allowed, 5730 because of possible accuracy problems. */ 5731 if (! flag_unsafe_math_optimizations) 5732 break; 5733 CASE_FLT_FN (BUILT_IN_SQRT): 5734 CASE_FLT_FN (BUILT_IN_FLOOR): 5735 CASE_FLT_FN (BUILT_IN_CEIL): 5736 CASE_FLT_FN (BUILT_IN_TRUNC): 5737 CASE_FLT_FN (BUILT_IN_ROUND): 5738 CASE_FLT_FN (BUILT_IN_NEARBYINT): 5739 CASE_FLT_FN (BUILT_IN_RINT): 5740 CASE_FLT_FN (BUILT_IN_LRINT): 5741 CASE_FLT_FN (BUILT_IN_LLRINT): 5742 target = expand_builtin_mathfn (exp, target, subtarget); 5743 if (target) 5744 return target; 5745 break; 5746 5747 CASE_FLT_FN (BUILT_IN_LCEIL): 5748 CASE_FLT_FN (BUILT_IN_LLCEIL): 5749 CASE_FLT_FN (BUILT_IN_LFLOOR): 5750 CASE_FLT_FN (BUILT_IN_LLFLOOR): 5751 target = expand_builtin_int_roundingfn (exp, target, subtarget); 5752 if (target) 5753 return target; 5754 break; 5755 5756 CASE_FLT_FN (BUILT_IN_POW): 5757 target = expand_builtin_pow (exp, target, subtarget); 5758 if (target) 5759 return target; 5760 break; 5761 5762 CASE_FLT_FN (BUILT_IN_POWI): 5763 target = expand_builtin_powi (exp, target, subtarget); 5764 if (target) 5765 return target; 5766 break; 5767 5768 CASE_FLT_FN (BUILT_IN_ATAN2): 5769 CASE_FLT_FN (BUILT_IN_LDEXP): 5770 CASE_FLT_FN (BUILT_IN_FMOD): 5771 CASE_FLT_FN (BUILT_IN_DREM): 5772 if (! flag_unsafe_math_optimizations) 5773 break; 5774 target = expand_builtin_mathfn_2 (exp, target, subtarget); 5775 if (target) 5776 return target; 5777 break; 5778 5779 CASE_FLT_FN (BUILT_IN_SIN): 5780 CASE_FLT_FN (BUILT_IN_COS): 5781 if (! flag_unsafe_math_optimizations) 5782 break; 5783 target = expand_builtin_mathfn_3 (exp, target, subtarget); 5784 if (target) 5785 return target; 5786 break; 5787 5788 CASE_FLT_FN (BUILT_IN_SINCOS): 5789 if (! flag_unsafe_math_optimizations) 5790 break; 5791 target = expand_builtin_sincos (exp); 5792 if (target) 5793 return target; 5794 break; 5795 5796 case BUILT_IN_APPLY_ARGS: 5797 return expand_builtin_apply_args (); 5798 5799 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes 5800 FUNCTION with a copy of the parameters described by 5801 ARGUMENTS, and ARGSIZE. It returns a block of memory 5802 allocated on the stack into which is stored all the registers 5803 that might possibly be used for returning the result of a 5804 function. ARGUMENTS is the value returned by 5805 __builtin_apply_args. ARGSIZE is the number of bytes of 5806 arguments that must be copied. ??? How should this value be 5807 computed? We'll also need a safe worst case value for varargs 5808 functions. */ 5809 case BUILT_IN_APPLY: 5810 if (!validate_arglist (arglist, POINTER_TYPE, 5811 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE) 5812 && !validate_arglist (arglist, REFERENCE_TYPE, 5813 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 5814 return const0_rtx; 5815 else 5816 { 5817 int i; 5818 tree t; 5819 rtx ops[3]; 5820 5821 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++) 5822 ops[i] = expand_normal (TREE_VALUE (t)); 5823 5824 return expand_builtin_apply (ops[0], ops[1], ops[2]); 5825 } 5826 5827 /* __builtin_return (RESULT) causes the function to return the 5828 value described by RESULT. RESULT is address of the block of 5829 memory returned by __builtin_apply. */ 5830 case BUILT_IN_RETURN: 5831 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 5832 expand_builtin_return (expand_normal (TREE_VALUE (arglist))); 5833 return const0_rtx; 5834 5835 case BUILT_IN_SAVEREGS: 5836 return expand_builtin_saveregs (); 5837 5838 case BUILT_IN_ARGS_INFO: 5839 return expand_builtin_args_info (arglist); 5840 5841 /* Return the address of the first anonymous stack arg. */ 5842 case BUILT_IN_NEXT_ARG: 5843 if (fold_builtin_next_arg (arglist)) 5844 return const0_rtx; 5845 return expand_builtin_next_arg (); 5846 5847 case BUILT_IN_CLASSIFY_TYPE: 5848 return expand_builtin_classify_type (arglist); 5849 5850 case BUILT_IN_CONSTANT_P: 5851 return const0_rtx; 5852 5853 case BUILT_IN_FRAME_ADDRESS: 5854 case BUILT_IN_RETURN_ADDRESS: 5855 return expand_builtin_frame_address (fndecl, arglist); 5856 5857 /* Returns the address of the area where the structure is returned. 5858 0 otherwise. */ 5859 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: 5860 if (arglist != 0 5861 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))) 5862 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl)))) 5863 return const0_rtx; 5864 else 5865 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0); 5866 5867 case BUILT_IN_ALLOCA: 5868 target = expand_builtin_alloca (arglist, target); 5869 if (target) 5870 return target; 5871 break; 5872 5873 case BUILT_IN_STACK_SAVE: 5874 return expand_stack_save (); 5875 5876 case BUILT_IN_STACK_RESTORE: 5877 expand_stack_restore (TREE_VALUE (arglist)); 5878 return const0_rtx; 5879 5880 CASE_INT_FN (BUILT_IN_FFS): 5881 case BUILT_IN_FFSIMAX: 5882 target = expand_builtin_unop (target_mode, arglist, target, 5883 subtarget, ffs_optab); 5884 if (target) 5885 return target; 5886 break; 5887 5888 CASE_INT_FN (BUILT_IN_CLZ): 5889 case BUILT_IN_CLZIMAX: 5890 target = expand_builtin_unop (target_mode, arglist, target, 5891 subtarget, clz_optab); 5892 if (target) 5893 return target; 5894 break; 5895 5896 CASE_INT_FN (BUILT_IN_CTZ): 5897 case BUILT_IN_CTZIMAX: 5898 target = expand_builtin_unop (target_mode, arglist, target, 5899 subtarget, ctz_optab); 5900 if (target) 5901 return target; 5902 break; 5903 5904 CASE_INT_FN (BUILT_IN_POPCOUNT): 5905 case BUILT_IN_POPCOUNTIMAX: 5906 target = expand_builtin_unop (target_mode, arglist, target, 5907 subtarget, popcount_optab); 5908 if (target) 5909 return target; 5910 break; 5911 5912 CASE_INT_FN (BUILT_IN_PARITY): 5913 case BUILT_IN_PARITYIMAX: 5914 target = expand_builtin_unop (target_mode, arglist, target, 5915 subtarget, parity_optab); 5916 if (target) 5917 return target; 5918 break; 5919 5920 case BUILT_IN_STRLEN: 5921 target = expand_builtin_strlen (arglist, target, target_mode); 5922 if (target) 5923 return target; 5924 break; 5925 5926 case BUILT_IN_STRCPY: 5927 target = expand_builtin_strcpy (fndecl, arglist, target, mode); 5928 if (target) 5929 return target; 5930 break; 5931 5932 case BUILT_IN_STRNCPY: 5933 target = expand_builtin_strncpy (exp, target, mode); 5934 if (target) 5935 return target; 5936 break; 5937 5938 case BUILT_IN_STPCPY: 5939 target = expand_builtin_stpcpy (exp, target, mode); 5940 if (target) 5941 return target; 5942 break; 5943 5944 case BUILT_IN_STRCAT: 5945 target = expand_builtin_strcat (fndecl, arglist, target, mode); 5946 if (target) 5947 return target; 5948 break; 5949 5950 case BUILT_IN_STRNCAT: 5951 target = expand_builtin_strncat (arglist, target, mode); 5952 if (target) 5953 return target; 5954 break; 5955 5956 case BUILT_IN_STRSPN: 5957 target = expand_builtin_strspn (arglist, target, mode); 5958 if (target) 5959 return target; 5960 break; 5961 5962 case BUILT_IN_STRCSPN: 5963 target = expand_builtin_strcspn (arglist, target, mode); 5964 if (target) 5965 return target; 5966 break; 5967 5968 case BUILT_IN_STRSTR: 5969 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode); 5970 if (target) 5971 return target; 5972 break; 5973 5974 case BUILT_IN_STRPBRK: 5975 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode); 5976 if (target) 5977 return target; 5978 break; 5979 5980 case BUILT_IN_INDEX: 5981 case BUILT_IN_STRCHR: 5982 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode); 5983 if (target) 5984 return target; 5985 break; 5986 5987 case BUILT_IN_RINDEX: 5988 case BUILT_IN_STRRCHR: 5989 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode); 5990 if (target) 5991 return target; 5992 break; 5993 5994 case BUILT_IN_MEMCPY: 5995 target = expand_builtin_memcpy (exp, target, mode); 5996 if (target) 5997 return target; 5998 break; 5999 6000 case BUILT_IN_MEMPCPY: 6001 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1); 6002 if (target) 6003 return target; 6004 break; 6005 6006 case BUILT_IN_MEMMOVE: 6007 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target, 6008 mode, exp); 6009 if (target) 6010 return target; 6011 break; 6012 6013 case BUILT_IN_BCOPY: 6014 target = expand_builtin_bcopy (exp); 6015 if (target) 6016 return target; 6017 break; 6018 6019 case BUILT_IN_MEMSET: 6020 target = expand_builtin_memset (arglist, target, mode, exp); 6021 if (target) 6022 return target; 6023 break; 6024 6025 case BUILT_IN_BZERO: 6026 target = expand_builtin_bzero (exp); 6027 if (target) 6028 return target; 6029 break; 6030 6031 case BUILT_IN_STRCMP: 6032 target = expand_builtin_strcmp (exp, target, mode); 6033 if (target) 6034 return target; 6035 break; 6036 6037 case BUILT_IN_STRNCMP: 6038 target = expand_builtin_strncmp (exp, target, mode); 6039 if (target) 6040 return target; 6041 break; 6042 6043 case BUILT_IN_BCMP: 6044 case BUILT_IN_MEMCMP: 6045 target = expand_builtin_memcmp (exp, arglist, target, mode); 6046 if (target) 6047 return target; 6048 break; 6049 6050 case BUILT_IN_SETJMP: 6051 /* This should have been lowered to the builtins below. */ 6052 gcc_unreachable (); 6053 6054 case BUILT_IN_SETJMP_SETUP: 6055 /* __builtin_setjmp_setup is passed a pointer to an array of five words 6056 and the receiver label. */ 6057 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 6058 { 6059 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget, 6060 VOIDmode, EXPAND_NORMAL); 6061 tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0); 6062 rtx label_r = label_rtx (label); 6063 6064 /* This is copied from the handling of non-local gotos. */ 6065 expand_builtin_setjmp_setup (buf_addr, label_r); 6066 nonlocal_goto_handler_labels 6067 = gen_rtx_EXPR_LIST (VOIDmode, label_r, 6068 nonlocal_goto_handler_labels); 6069 /* ??? Do not let expand_label treat us as such since we would 6070 not want to be both on the list of non-local labels and on 6071 the list of forced labels. */ 6072 FORCED_LABEL (label) = 0; 6073 return const0_rtx; 6074 } 6075 break; 6076 6077 case BUILT_IN_SETJMP_DISPATCHER: 6078 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */ 6079 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6080 { 6081 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0); 6082 rtx label_r = label_rtx (label); 6083 6084 /* Remove the dispatcher label from the list of non-local labels 6085 since the receiver labels have been added to it above. */ 6086 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels); 6087 return const0_rtx; 6088 } 6089 break; 6090 6091 case BUILT_IN_SETJMP_RECEIVER: 6092 /* __builtin_setjmp_receiver is passed the receiver label. */ 6093 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6094 { 6095 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0); 6096 rtx label_r = label_rtx (label); 6097 6098 expand_builtin_setjmp_receiver (label_r); 6099 return const0_rtx; 6100 } 6101 break; 6102 6103 /* __builtin_longjmp is passed a pointer to an array of five words. 6104 It's similar to the C library longjmp function but works with 6105 __builtin_setjmp above. */ 6106 case BUILT_IN_LONGJMP: 6107 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6108 { 6109 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget, 6110 VOIDmode, EXPAND_NORMAL); 6111 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist))); 6112 6113 if (value != const1_rtx) 6114 { 6115 error ("%<__builtin_longjmp%> second argument must be 1"); 6116 return const0_rtx; 6117 } 6118 6119 expand_builtin_longjmp (buf_addr, value); 6120 return const0_rtx; 6121 } 6122 break; 6123 6124 case BUILT_IN_NONLOCAL_GOTO: 6125 target = expand_builtin_nonlocal_goto (arglist); 6126 if (target) 6127 return target; 6128 break; 6129 6130 /* This updates the setjmp buffer that is its argument with the value 6131 of the current stack pointer. */ 6132 case BUILT_IN_UPDATE_SETJMP_BUF: 6133 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6134 { 6135 rtx buf_addr 6136 = expand_normal (TREE_VALUE (arglist)); 6137 6138 expand_builtin_update_setjmp_buf (buf_addr); 6139 return const0_rtx; 6140 } 6141 break; 6142 6143 case BUILT_IN_TRAP: 6144 expand_builtin_trap (); 6145 return const0_rtx; 6146 6147 case BUILT_IN_PRINTF: 6148 target = expand_builtin_printf (exp, target, mode, false); 6149 if (target) 6150 return target; 6151 break; 6152 6153 case BUILT_IN_PRINTF_UNLOCKED: 6154 target = expand_builtin_printf (exp, target, mode, true); 6155 if (target) 6156 return target; 6157 break; 6158 6159 case BUILT_IN_FPUTS: 6160 target = expand_builtin_fputs (arglist, target, false); 6161 if (target) 6162 return target; 6163 break; 6164 case BUILT_IN_FPUTS_UNLOCKED: 6165 target = expand_builtin_fputs (arglist, target, true); 6166 if (target) 6167 return target; 6168 break; 6169 6170 case BUILT_IN_FPRINTF: 6171 target = expand_builtin_fprintf (exp, target, mode, false); 6172 if (target) 6173 return target; 6174 break; 6175 6176 case BUILT_IN_FPRINTF_UNLOCKED: 6177 target = expand_builtin_fprintf (exp, target, mode, true); 6178 if (target) 6179 return target; 6180 break; 6181 6182 case BUILT_IN_SPRINTF: 6183 target = expand_builtin_sprintf (arglist, target, mode); 6184 if (target) 6185 return target; 6186 break; 6187 6188 CASE_FLT_FN (BUILT_IN_SIGNBIT): 6189 target = expand_builtin_signbit (exp, target); 6190 if (target) 6191 return target; 6192 break; 6193 6194 /* Various hooks for the DWARF 2 __throw routine. */ 6195 case BUILT_IN_UNWIND_INIT: 6196 expand_builtin_unwind_init (); 6197 return const0_rtx; 6198 case BUILT_IN_DWARF_CFA: 6199 return virtual_cfa_rtx; 6200#ifdef DWARF2_UNWIND_INFO 6201 case BUILT_IN_DWARF_SP_COLUMN: 6202 return expand_builtin_dwarf_sp_column (); 6203 case BUILT_IN_INIT_DWARF_REG_SIZES: 6204 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist)); 6205 return const0_rtx; 6206#endif 6207 case BUILT_IN_FROB_RETURN_ADDR: 6208 return expand_builtin_frob_return_addr (TREE_VALUE (arglist)); 6209 case BUILT_IN_EXTRACT_RETURN_ADDR: 6210 return expand_builtin_extract_return_addr (TREE_VALUE (arglist)); 6211 case BUILT_IN_EH_RETURN: 6212 expand_builtin_eh_return (TREE_VALUE (arglist), 6213 TREE_VALUE (TREE_CHAIN (arglist))); 6214 return const0_rtx; 6215#ifdef EH_RETURN_DATA_REGNO 6216 case BUILT_IN_EH_RETURN_DATA_REGNO: 6217 return expand_builtin_eh_return_data_regno (arglist); 6218#endif 6219 case BUILT_IN_EXTEND_POINTER: 6220 return expand_builtin_extend_pointer (TREE_VALUE (arglist)); 6221 6222 case BUILT_IN_VA_START: 6223 case BUILT_IN_STDARG_START: 6224 return expand_builtin_va_start (arglist); 6225 case BUILT_IN_VA_END: 6226 return expand_builtin_va_end (arglist); 6227 case BUILT_IN_VA_COPY: 6228 return expand_builtin_va_copy (arglist); 6229 case BUILT_IN_EXPECT: 6230 return expand_builtin_expect (arglist, target); 6231 case BUILT_IN_PREFETCH: 6232 expand_builtin_prefetch (arglist); 6233 return const0_rtx; 6234 6235 case BUILT_IN_PROFILE_FUNC_ENTER: 6236 return expand_builtin_profile_func (false); 6237 case BUILT_IN_PROFILE_FUNC_EXIT: 6238 return expand_builtin_profile_func (true); 6239 6240 case BUILT_IN_INIT_TRAMPOLINE: 6241 return expand_builtin_init_trampoline (arglist); 6242 case BUILT_IN_ADJUST_TRAMPOLINE: 6243 return expand_builtin_adjust_trampoline (arglist); 6244 6245 case BUILT_IN_FORK: 6246 case BUILT_IN_EXECL: 6247 case BUILT_IN_EXECV: 6248 case BUILT_IN_EXECLP: 6249 case BUILT_IN_EXECLE: 6250 case BUILT_IN_EXECVP: 6251 case BUILT_IN_EXECVE: 6252 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore); 6253 if (target) 6254 return target; 6255 break; 6256 6257 case BUILT_IN_FETCH_AND_ADD_1: 6258 case BUILT_IN_FETCH_AND_ADD_2: 6259 case BUILT_IN_FETCH_AND_ADD_4: 6260 case BUILT_IN_FETCH_AND_ADD_8: 6261 case BUILT_IN_FETCH_AND_ADD_16: 6262 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1); 6263 target = expand_builtin_sync_operation (mode, arglist, PLUS, 6264 false, target, ignore); 6265 if (target) 6266 return target; 6267 break; 6268 6269 case BUILT_IN_FETCH_AND_SUB_1: 6270 case BUILT_IN_FETCH_AND_SUB_2: 6271 case BUILT_IN_FETCH_AND_SUB_4: 6272 case BUILT_IN_FETCH_AND_SUB_8: 6273 case BUILT_IN_FETCH_AND_SUB_16: 6274 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1); 6275 target = expand_builtin_sync_operation (mode, arglist, MINUS, 6276 false, target, ignore); 6277 if (target) 6278 return target; 6279 break; 6280 6281 case BUILT_IN_FETCH_AND_OR_1: 6282 case BUILT_IN_FETCH_AND_OR_2: 6283 case BUILT_IN_FETCH_AND_OR_4: 6284 case BUILT_IN_FETCH_AND_OR_8: 6285 case BUILT_IN_FETCH_AND_OR_16: 6286 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1); 6287 target = expand_builtin_sync_operation (mode, arglist, IOR, 6288 false, target, ignore); 6289 if (target) 6290 return target; 6291 break; 6292 6293 case BUILT_IN_FETCH_AND_AND_1: 6294 case BUILT_IN_FETCH_AND_AND_2: 6295 case BUILT_IN_FETCH_AND_AND_4: 6296 case BUILT_IN_FETCH_AND_AND_8: 6297 case BUILT_IN_FETCH_AND_AND_16: 6298 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1); 6299 target = expand_builtin_sync_operation (mode, arglist, AND, 6300 false, target, ignore); 6301 if (target) 6302 return target; 6303 break; 6304 6305 case BUILT_IN_FETCH_AND_XOR_1: 6306 case BUILT_IN_FETCH_AND_XOR_2: 6307 case BUILT_IN_FETCH_AND_XOR_4: 6308 case BUILT_IN_FETCH_AND_XOR_8: 6309 case BUILT_IN_FETCH_AND_XOR_16: 6310 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1); 6311 target = expand_builtin_sync_operation (mode, arglist, XOR, 6312 false, target, ignore); 6313 if (target) 6314 return target; 6315 break; 6316 6317 case BUILT_IN_FETCH_AND_NAND_1: 6318 case BUILT_IN_FETCH_AND_NAND_2: 6319 case BUILT_IN_FETCH_AND_NAND_4: 6320 case BUILT_IN_FETCH_AND_NAND_8: 6321 case BUILT_IN_FETCH_AND_NAND_16: 6322 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1); 6323 target = expand_builtin_sync_operation (mode, arglist, NOT, 6324 false, target, ignore); 6325 if (target) 6326 return target; 6327 break; 6328 6329 case BUILT_IN_ADD_AND_FETCH_1: 6330 case BUILT_IN_ADD_AND_FETCH_2: 6331 case BUILT_IN_ADD_AND_FETCH_4: 6332 case BUILT_IN_ADD_AND_FETCH_8: 6333 case BUILT_IN_ADD_AND_FETCH_16: 6334 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1); 6335 target = expand_builtin_sync_operation (mode, arglist, PLUS, 6336 true, target, ignore); 6337 if (target) 6338 return target; 6339 break; 6340 6341 case BUILT_IN_SUB_AND_FETCH_1: 6342 case BUILT_IN_SUB_AND_FETCH_2: 6343 case BUILT_IN_SUB_AND_FETCH_4: 6344 case BUILT_IN_SUB_AND_FETCH_8: 6345 case BUILT_IN_SUB_AND_FETCH_16: 6346 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1); 6347 target = expand_builtin_sync_operation (mode, arglist, MINUS, 6348 true, target, ignore); 6349 if (target) 6350 return target; 6351 break; 6352 6353 case BUILT_IN_OR_AND_FETCH_1: 6354 case BUILT_IN_OR_AND_FETCH_2: 6355 case BUILT_IN_OR_AND_FETCH_4: 6356 case BUILT_IN_OR_AND_FETCH_8: 6357 case BUILT_IN_OR_AND_FETCH_16: 6358 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1); 6359 target = expand_builtin_sync_operation (mode, arglist, IOR, 6360 true, target, ignore); 6361 if (target) 6362 return target; 6363 break; 6364 6365 case BUILT_IN_AND_AND_FETCH_1: 6366 case BUILT_IN_AND_AND_FETCH_2: 6367 case BUILT_IN_AND_AND_FETCH_4: 6368 case BUILT_IN_AND_AND_FETCH_8: 6369 case BUILT_IN_AND_AND_FETCH_16: 6370 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1); 6371 target = expand_builtin_sync_operation (mode, arglist, AND, 6372 true, target, ignore); 6373 if (target) 6374 return target; 6375 break; 6376 6377 case BUILT_IN_XOR_AND_FETCH_1: 6378 case BUILT_IN_XOR_AND_FETCH_2: 6379 case BUILT_IN_XOR_AND_FETCH_4: 6380 case BUILT_IN_XOR_AND_FETCH_8: 6381 case BUILT_IN_XOR_AND_FETCH_16: 6382 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1); 6383 target = expand_builtin_sync_operation (mode, arglist, XOR, 6384 true, target, ignore); 6385 if (target) 6386 return target; 6387 break; 6388 6389 case BUILT_IN_NAND_AND_FETCH_1: 6390 case BUILT_IN_NAND_AND_FETCH_2: 6391 case BUILT_IN_NAND_AND_FETCH_4: 6392 case BUILT_IN_NAND_AND_FETCH_8: 6393 case BUILT_IN_NAND_AND_FETCH_16: 6394 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1); 6395 target = expand_builtin_sync_operation (mode, arglist, NOT, 6396 true, target, ignore); 6397 if (target) 6398 return target; 6399 break; 6400 6401 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1: 6402 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2: 6403 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4: 6404 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8: 6405 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16: 6406 if (mode == VOIDmode) 6407 mode = TYPE_MODE (boolean_type_node); 6408 if (!target || !register_operand (target, mode)) 6409 target = gen_reg_rtx (mode); 6410 6411 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1); 6412 target = expand_builtin_compare_and_swap (mode, arglist, true, target); 6413 if (target) 6414 return target; 6415 break; 6416 6417 case BUILT_IN_VAL_COMPARE_AND_SWAP_1: 6418 case BUILT_IN_VAL_COMPARE_AND_SWAP_2: 6419 case BUILT_IN_VAL_COMPARE_AND_SWAP_4: 6420 case BUILT_IN_VAL_COMPARE_AND_SWAP_8: 6421 case BUILT_IN_VAL_COMPARE_AND_SWAP_16: 6422 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1); 6423 target = expand_builtin_compare_and_swap (mode, arglist, false, target); 6424 if (target) 6425 return target; 6426 break; 6427 6428 case BUILT_IN_LOCK_TEST_AND_SET_1: 6429 case BUILT_IN_LOCK_TEST_AND_SET_2: 6430 case BUILT_IN_LOCK_TEST_AND_SET_4: 6431 case BUILT_IN_LOCK_TEST_AND_SET_8: 6432 case BUILT_IN_LOCK_TEST_AND_SET_16: 6433 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1); 6434 target = expand_builtin_lock_test_and_set (mode, arglist, target); 6435 if (target) 6436 return target; 6437 break; 6438 6439 case BUILT_IN_LOCK_RELEASE_1: 6440 case BUILT_IN_LOCK_RELEASE_2: 6441 case BUILT_IN_LOCK_RELEASE_4: 6442 case BUILT_IN_LOCK_RELEASE_8: 6443 case BUILT_IN_LOCK_RELEASE_16: 6444 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1); 6445 expand_builtin_lock_release (mode, arglist); 6446 return const0_rtx; 6447 6448 case BUILT_IN_SYNCHRONIZE: 6449 expand_builtin_synchronize (); 6450 return const0_rtx; 6451 6452 case BUILT_IN_OBJECT_SIZE: 6453 return expand_builtin_object_size (exp); 6454 6455 case BUILT_IN_MEMCPY_CHK: 6456 case BUILT_IN_MEMPCPY_CHK: 6457 case BUILT_IN_MEMMOVE_CHK: 6458 case BUILT_IN_MEMSET_CHK: 6459 target = expand_builtin_memory_chk (exp, target, mode, fcode); 6460 if (target) 6461 return target; 6462 break; 6463 6464 case BUILT_IN_STRCPY_CHK: 6465 case BUILT_IN_STPCPY_CHK: 6466 case BUILT_IN_STRNCPY_CHK: 6467 case BUILT_IN_STRCAT_CHK: 6468 case BUILT_IN_SNPRINTF_CHK: 6469 case BUILT_IN_VSNPRINTF_CHK: 6470 maybe_emit_chk_warning (exp, fcode); 6471 break; 6472 6473 case BUILT_IN_SPRINTF_CHK: 6474 case BUILT_IN_VSPRINTF_CHK: 6475 maybe_emit_sprintf_chk_warning (exp, fcode); 6476 break; 6477 6478 default: /* just do library call, if unknown builtin */ 6479 break; 6480 } 6481 6482 /* The switch statement above can drop through to cause the function 6483 to be called normally. */ 6484 return expand_call (exp, target, ignore); 6485} 6486 6487/* Determine whether a tree node represents a call to a built-in 6488 function. If the tree T is a call to a built-in function with 6489 the right number of arguments of the appropriate types, return 6490 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. 6491 Otherwise the return value is END_BUILTINS. */ 6492 6493enum built_in_function 6494builtin_mathfn_code (tree t) 6495{ 6496 tree fndecl, arglist, parmlist; 6497 tree argtype, parmtype; 6498 6499 if (TREE_CODE (t) != CALL_EXPR 6500 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR) 6501 return END_BUILTINS; 6502 6503 fndecl = get_callee_fndecl (t); 6504 if (fndecl == NULL_TREE 6505 || TREE_CODE (fndecl) != FUNCTION_DECL 6506 || ! DECL_BUILT_IN (fndecl) 6507 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 6508 return END_BUILTINS; 6509 6510 arglist = TREE_OPERAND (t, 1); 6511 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); 6512 for (; parmlist; parmlist = TREE_CHAIN (parmlist)) 6513 { 6514 /* If a function doesn't take a variable number of arguments, 6515 the last element in the list will have type `void'. */ 6516 parmtype = TREE_VALUE (parmlist); 6517 if (VOID_TYPE_P (parmtype)) 6518 { 6519 if (arglist) 6520 return END_BUILTINS; 6521 return DECL_FUNCTION_CODE (fndecl); 6522 } 6523 6524 if (! arglist) 6525 return END_BUILTINS; 6526 6527 argtype = TREE_TYPE (TREE_VALUE (arglist)); 6528 6529 if (SCALAR_FLOAT_TYPE_P (parmtype)) 6530 { 6531 if (! SCALAR_FLOAT_TYPE_P (argtype)) 6532 return END_BUILTINS; 6533 } 6534 else if (COMPLEX_FLOAT_TYPE_P (parmtype)) 6535 { 6536 if (! COMPLEX_FLOAT_TYPE_P (argtype)) 6537 return END_BUILTINS; 6538 } 6539 else if (POINTER_TYPE_P (parmtype)) 6540 { 6541 if (! POINTER_TYPE_P (argtype)) 6542 return END_BUILTINS; 6543 } 6544 else if (INTEGRAL_TYPE_P (parmtype)) 6545 { 6546 if (! INTEGRAL_TYPE_P (argtype)) 6547 return END_BUILTINS; 6548 } 6549 else 6550 return END_BUILTINS; 6551 6552 arglist = TREE_CHAIN (arglist); 6553 } 6554 6555 /* Variable-length argument list. */ 6556 return DECL_FUNCTION_CODE (fndecl); 6557} 6558 6559/* Fold a call to __builtin_constant_p, if we know it will evaluate to a 6560 constant. ARGLIST is the argument list of the call. */ 6561 6562static tree 6563fold_builtin_constant_p (tree arglist) 6564{ 6565 if (arglist == 0) 6566 return 0; 6567 6568 arglist = TREE_VALUE (arglist); 6569 6570 /* We return 1 for a numeric type that's known to be a constant 6571 value at compile-time or for an aggregate type that's a 6572 literal constant. */ 6573 STRIP_NOPS (arglist); 6574 6575 /* If we know this is a constant, emit the constant of one. */ 6576 if (CONSTANT_CLASS_P (arglist) 6577 || (TREE_CODE (arglist) == CONSTRUCTOR 6578 && TREE_CONSTANT (arglist))) 6579 return integer_one_node; 6580 if (TREE_CODE (arglist) == ADDR_EXPR) 6581 { 6582 tree op = TREE_OPERAND (arglist, 0); 6583 if (TREE_CODE (op) == STRING_CST 6584 || (TREE_CODE (op) == ARRAY_REF 6585 && integer_zerop (TREE_OPERAND (op, 1)) 6586 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST)) 6587 return integer_one_node; 6588 } 6589 6590 /* If this expression has side effects, show we don't know it to be a 6591 constant. Likewise if it's a pointer or aggregate type since in 6592 those case we only want literals, since those are only optimized 6593 when generating RTL, not later. 6594 And finally, if we are compiling an initializer, not code, we 6595 need to return a definite result now; there's not going to be any 6596 more optimization done. */ 6597 if (TREE_SIDE_EFFECTS (arglist) 6598 || AGGREGATE_TYPE_P (TREE_TYPE (arglist)) 6599 || POINTER_TYPE_P (TREE_TYPE (arglist)) 6600 || cfun == 0 6601 || folding_initializer) 6602 return integer_zero_node; 6603 6604 return 0; 6605} 6606 6607/* Fold a call to __builtin_expect, if we expect that a comparison against 6608 the argument will fold to a constant. In practice, this means a true 6609 constant or the address of a non-weak symbol. ARGLIST is the argument 6610 list of the call. */ 6611 6612static tree 6613fold_builtin_expect (tree arglist) 6614{ 6615 tree arg, inner; 6616 6617 if (arglist == 0) 6618 return 0; 6619 6620 arg = TREE_VALUE (arglist); 6621 6622 /* If the argument isn't invariant, then there's nothing we can do. */ 6623 if (!TREE_INVARIANT (arg)) 6624 return 0; 6625 6626 /* If we're looking at an address of a weak decl, then do not fold. */ 6627 inner = arg; 6628 STRIP_NOPS (inner); 6629 if (TREE_CODE (inner) == ADDR_EXPR) 6630 { 6631 do 6632 { 6633 inner = TREE_OPERAND (inner, 0); 6634 } 6635 while (TREE_CODE (inner) == COMPONENT_REF 6636 || TREE_CODE (inner) == ARRAY_REF); 6637 if (DECL_P (inner) && DECL_WEAK (inner)) 6638 return 0; 6639 } 6640 6641 /* Otherwise, ARG already has the proper type for the return value. */ 6642 return arg; 6643} 6644 6645/* Fold a call to __builtin_classify_type. */ 6646 6647static tree 6648fold_builtin_classify_type (tree arglist) 6649{ 6650 if (arglist == 0) 6651 return build_int_cst (NULL_TREE, no_type_class); 6652 6653 return build_int_cst (NULL_TREE, 6654 type_to_class (TREE_TYPE (TREE_VALUE (arglist)))); 6655} 6656 6657/* Fold a call to __builtin_strlen. */ 6658 6659static tree 6660fold_builtin_strlen (tree arglist) 6661{ 6662 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6663 return NULL_TREE; 6664 else 6665 { 6666 tree len = c_strlen (TREE_VALUE (arglist), 0); 6667 6668 if (len) 6669 { 6670 /* Convert from the internal "sizetype" type to "size_t". */ 6671 if (size_type_node) 6672 len = fold_convert (size_type_node, len); 6673 return len; 6674 } 6675 6676 return NULL_TREE; 6677 } 6678} 6679 6680/* Fold a call to __builtin_inf or __builtin_huge_val. */ 6681 6682static tree 6683fold_builtin_inf (tree type, int warn) 6684{ 6685 REAL_VALUE_TYPE real; 6686 6687 /* __builtin_inff is intended to be usable to define INFINITY on all 6688 targets. If an infinity is not available, INFINITY expands "to a 6689 positive constant of type float that overflows at translation 6690 time", footnote "In this case, using INFINITY will violate the 6691 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4). 6692 Thus we pedwarn to ensure this constraint violation is 6693 diagnosed. */ 6694 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn) 6695 pedwarn ("target format does not support infinity"); 6696 6697 real_inf (&real); 6698 return build_real (type, real); 6699} 6700 6701/* Fold a call to __builtin_nan or __builtin_nans. */ 6702 6703static tree 6704fold_builtin_nan (tree arglist, tree type, int quiet) 6705{ 6706 REAL_VALUE_TYPE real; 6707 const char *str; 6708 6709 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6710 return 0; 6711 str = c_getstr (TREE_VALUE (arglist)); 6712 if (!str) 6713 return 0; 6714 6715 if (!real_nan (&real, str, quiet, TYPE_MODE (type))) 6716 return 0; 6717 6718 return build_real (type, real); 6719} 6720 6721/* Return true if the floating point expression T has an integer value. 6722 We also allow +Inf, -Inf and NaN to be considered integer values. */ 6723 6724static bool 6725integer_valued_real_p (tree t) 6726{ 6727 switch (TREE_CODE (t)) 6728 { 6729 case FLOAT_EXPR: 6730 return true; 6731 6732 case ABS_EXPR: 6733 case SAVE_EXPR: 6734 case NON_LVALUE_EXPR: 6735 return integer_valued_real_p (TREE_OPERAND (t, 0)); 6736 6737 case COMPOUND_EXPR: 6738 case MODIFY_EXPR: 6739 case BIND_EXPR: 6740 return integer_valued_real_p (TREE_OPERAND (t, 1)); 6741 6742 case PLUS_EXPR: 6743 case MINUS_EXPR: 6744 case MULT_EXPR: 6745 case MIN_EXPR: 6746 case MAX_EXPR: 6747 return integer_valued_real_p (TREE_OPERAND (t, 0)) 6748 && integer_valued_real_p (TREE_OPERAND (t, 1)); 6749 6750 case COND_EXPR: 6751 return integer_valued_real_p (TREE_OPERAND (t, 1)) 6752 && integer_valued_real_p (TREE_OPERAND (t, 2)); 6753 6754 case REAL_CST: 6755 if (! TREE_CONSTANT_OVERFLOW (t)) 6756 { 6757 REAL_VALUE_TYPE c, cint; 6758 6759 c = TREE_REAL_CST (t); 6760 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c); 6761 return real_identical (&c, &cint); 6762 } 6763 break; 6764 6765 case NOP_EXPR: 6766 { 6767 tree type = TREE_TYPE (TREE_OPERAND (t, 0)); 6768 if (TREE_CODE (type) == INTEGER_TYPE) 6769 return true; 6770 if (TREE_CODE (type) == REAL_TYPE) 6771 return integer_valued_real_p (TREE_OPERAND (t, 0)); 6772 break; 6773 } 6774 6775 case CALL_EXPR: 6776 switch (builtin_mathfn_code (t)) 6777 { 6778 CASE_FLT_FN (BUILT_IN_CEIL): 6779 CASE_FLT_FN (BUILT_IN_FLOOR): 6780 CASE_FLT_FN (BUILT_IN_NEARBYINT): 6781 CASE_FLT_FN (BUILT_IN_RINT): 6782 CASE_FLT_FN (BUILT_IN_ROUND): 6783 CASE_FLT_FN (BUILT_IN_TRUNC): 6784 return true; 6785 6786 default: 6787 break; 6788 } 6789 break; 6790 6791 default: 6792 break; 6793 } 6794 return false; 6795} 6796 6797/* EXP is assumed to be builtin call where truncation can be propagated 6798 across (for instance floor((double)f) == (double)floorf (f). 6799 Do the transformation. */ 6800 6801static tree 6802fold_trunc_transparent_mathfn (tree fndecl, tree arglist) 6803{ 6804 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 6805 tree arg; 6806 6807 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6808 return 0; 6809 6810 arg = TREE_VALUE (arglist); 6811 /* Integer rounding functions are idempotent. */ 6812 if (fcode == builtin_mathfn_code (arg)) 6813 return arg; 6814 6815 /* If argument is already integer valued, and we don't need to worry 6816 about setting errno, there's no need to perform rounding. */ 6817 if (! flag_errno_math && integer_valued_real_p (arg)) 6818 return arg; 6819 6820 if (optimize) 6821 { 6822 tree arg0 = strip_float_extensions (arg); 6823 tree ftype = TREE_TYPE (TREE_TYPE (fndecl)); 6824 tree newtype = TREE_TYPE (arg0); 6825 tree decl; 6826 6827 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype) 6828 && (decl = mathfn_built_in (newtype, fcode))) 6829 { 6830 arglist = 6831 build_tree_list (NULL_TREE, fold_convert (newtype, arg0)); 6832 return fold_convert (ftype, 6833 build_function_call_expr (decl, arglist)); 6834 } 6835 } 6836 return 0; 6837} 6838 6839/* EXP is assumed to be builtin call which can narrow the FP type of 6840 the argument, for instance lround((double)f) -> lroundf (f). */ 6841 6842static tree 6843fold_fixed_mathfn (tree fndecl, tree arglist) 6844{ 6845 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 6846 tree arg; 6847 6848 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6849 return 0; 6850 6851 arg = TREE_VALUE (arglist); 6852 6853 /* If argument is already integer valued, and we don't need to worry 6854 about setting errno, there's no need to perform rounding. */ 6855 if (! flag_errno_math && integer_valued_real_p (arg)) 6856 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg); 6857 6858 if (optimize) 6859 { 6860 tree ftype = TREE_TYPE (arg); 6861 tree arg0 = strip_float_extensions (arg); 6862 tree newtype = TREE_TYPE (arg0); 6863 tree decl; 6864 6865 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype) 6866 && (decl = mathfn_built_in (newtype, fcode))) 6867 { 6868 arglist = 6869 build_tree_list (NULL_TREE, fold_convert (newtype, arg0)); 6870 return build_function_call_expr (decl, arglist); 6871 } 6872 } 6873 6874 /* Canonicalize llround (x) to lround (x) on LP64 targets where 6875 sizeof (long long) == sizeof (long). */ 6876 if (TYPE_PRECISION (long_long_integer_type_node) 6877 == TYPE_PRECISION (long_integer_type_node)) 6878 { 6879 tree newfn = NULL_TREE; 6880 switch (fcode) 6881 { 6882 CASE_FLT_FN (BUILT_IN_LLCEIL): 6883 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL); 6884 break; 6885 6886 CASE_FLT_FN (BUILT_IN_LLFLOOR): 6887 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR); 6888 break; 6889 6890 CASE_FLT_FN (BUILT_IN_LLROUND): 6891 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND); 6892 break; 6893 6894 CASE_FLT_FN (BUILT_IN_LLRINT): 6895 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT); 6896 break; 6897 6898 default: 6899 break; 6900 } 6901 6902 if (newfn) 6903 { 6904 tree newcall = build_function_call_expr (newfn, arglist); 6905 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall); 6906 } 6907 } 6908 6909 return 0; 6910} 6911 6912/* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST 6913 is the argument list, TYPE is the return type and FNDECL is the 6914 original function DECL. Return NULL_TREE if no if no simplification 6915 can be made. */ 6916 6917static tree 6918fold_builtin_cabs (tree arglist, tree type, tree fndecl) 6919{ 6920 tree arg; 6921 6922 if (!arglist || TREE_CHAIN (arglist)) 6923 return NULL_TREE; 6924 6925 arg = TREE_VALUE (arglist); 6926 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE 6927 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE) 6928 return NULL_TREE; 6929 6930 /* Evaluate cabs of a constant at compile-time. */ 6931 if (flag_unsafe_math_optimizations 6932 && TREE_CODE (arg) == COMPLEX_CST 6933 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST 6934 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST 6935 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg)) 6936 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg))) 6937 { 6938 REAL_VALUE_TYPE r, i; 6939 6940 r = TREE_REAL_CST (TREE_REALPART (arg)); 6941 i = TREE_REAL_CST (TREE_IMAGPART (arg)); 6942 6943 real_arithmetic (&r, MULT_EXPR, &r, &r); 6944 real_arithmetic (&i, MULT_EXPR, &i, &i); 6945 real_arithmetic (&r, PLUS_EXPR, &r, &i); 6946 if (real_sqrt (&r, TYPE_MODE (type), &r) 6947 || ! flag_trapping_math) 6948 return build_real (type, r); 6949 } 6950 6951 /* If either part is zero, cabs is fabs of the other. */ 6952 if (TREE_CODE (arg) == COMPLEX_EXPR 6953 && real_zerop (TREE_OPERAND (arg, 0))) 6954 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)); 6955 if (TREE_CODE (arg) == COMPLEX_EXPR 6956 && real_zerop (TREE_OPERAND (arg, 1))) 6957 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)); 6958 6959 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */ 6960 if (TREE_CODE (arg) == NEGATE_EXPR 6961 || TREE_CODE (arg) == CONJ_EXPR) 6962 { 6963 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0)); 6964 return build_function_call_expr (fndecl, arglist); 6965 } 6966 6967 /* Don't do this when optimizing for size. */ 6968 if (flag_unsafe_math_optimizations 6969 && optimize && !optimize_size) 6970 { 6971 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); 6972 6973 if (sqrtfn != NULL_TREE) 6974 { 6975 tree rpart, ipart, result, arglist; 6976 6977 arg = builtin_save_expr (arg); 6978 6979 rpart = fold_build1 (REALPART_EXPR, type, arg); 6980 ipart = fold_build1 (IMAGPART_EXPR, type, arg); 6981 6982 rpart = builtin_save_expr (rpart); 6983 ipart = builtin_save_expr (ipart); 6984 6985 result = fold_build2 (PLUS_EXPR, type, 6986 fold_build2 (MULT_EXPR, type, 6987 rpart, rpart), 6988 fold_build2 (MULT_EXPR, type, 6989 ipart, ipart)); 6990 6991 arglist = build_tree_list (NULL_TREE, result); 6992 return build_function_call_expr (sqrtfn, arglist); 6993 } 6994 } 6995 6996 return NULL_TREE; 6997} 6998 6999/* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return 7000 NULL_TREE if no simplification can be made. */ 7001 7002static tree 7003fold_builtin_sqrt (tree arglist, tree type) 7004{ 7005 7006 enum built_in_function fcode; 7007 tree arg = TREE_VALUE (arglist); 7008 7009 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7010 return NULL_TREE; 7011 7012 /* Optimize sqrt of constant value. */ 7013 if (TREE_CODE (arg) == REAL_CST 7014 && ! TREE_CONSTANT_OVERFLOW (arg)) 7015 { 7016 REAL_VALUE_TYPE r, x; 7017 7018 x = TREE_REAL_CST (arg); 7019 if (real_sqrt (&r, TYPE_MODE (type), &x) 7020 || (!flag_trapping_math && !flag_errno_math)) 7021 return build_real (type, r); 7022 } 7023 7024 /* Optimize sqrt(expN(x)) = expN(x*0.5). */ 7025 fcode = builtin_mathfn_code (arg); 7026 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode)) 7027 { 7028 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 7029 arg = fold_build2 (MULT_EXPR, type, 7030 TREE_VALUE (TREE_OPERAND (arg, 1)), 7031 build_real (type, dconsthalf)); 7032 arglist = build_tree_list (NULL_TREE, arg); 7033 return build_function_call_expr (expfn, arglist); 7034 } 7035 7036 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */ 7037 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode)) 7038 { 7039 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7040 7041 if (powfn) 7042 { 7043 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1)); 7044 tree tree_root; 7045 /* The inner root was either sqrt or cbrt. */ 7046 REAL_VALUE_TYPE dconstroot = 7047 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird; 7048 7049 /* Adjust for the outer root. */ 7050 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); 7051 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7052 tree_root = build_real (type, dconstroot); 7053 arglist = tree_cons (NULL_TREE, arg0, 7054 build_tree_list (NULL_TREE, tree_root)); 7055 return build_function_call_expr (powfn, arglist); 7056 } 7057 } 7058 7059 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */ 7060 if (flag_unsafe_math_optimizations 7061 && (fcode == BUILT_IN_POW 7062 || fcode == BUILT_IN_POWF 7063 || fcode == BUILT_IN_POWL)) 7064 { 7065 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 7066 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1)); 7067 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1))); 7068 tree narg1; 7069 if (!tree_expr_nonnegative_p (arg0)) 7070 arg0 = build1 (ABS_EXPR, type, arg0); 7071 narg1 = fold_build2 (MULT_EXPR, type, arg1, 7072 build_real (type, dconsthalf)); 7073 arglist = tree_cons (NULL_TREE, arg0, 7074 build_tree_list (NULL_TREE, narg1)); 7075 return build_function_call_expr (powfn, arglist); 7076 } 7077 7078 return NULL_TREE; 7079} 7080 7081/* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return 7082 NULL_TREE if no simplification can be made. */ 7083static tree 7084fold_builtin_cbrt (tree arglist, tree type) 7085{ 7086 tree arg = TREE_VALUE (arglist); 7087 const enum built_in_function fcode = builtin_mathfn_code (arg); 7088 7089 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7090 return NULL_TREE; 7091 7092 /* Optimize cbrt of constant value. */ 7093 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg)) 7094 return arg; 7095 7096 if (flag_unsafe_math_optimizations) 7097 { 7098 /* Optimize cbrt(expN(x)) -> expN(x/3). */ 7099 if (BUILTIN_EXPONENT_P (fcode)) 7100 { 7101 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 7102 const REAL_VALUE_TYPE third_trunc = 7103 real_value_truncate (TYPE_MODE (type), dconstthird); 7104 arg = fold_build2 (MULT_EXPR, type, 7105 TREE_VALUE (TREE_OPERAND (arg, 1)), 7106 build_real (type, third_trunc)); 7107 arglist = build_tree_list (NULL_TREE, arg); 7108 return build_function_call_expr (expfn, arglist); 7109 } 7110 7111 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */ 7112 if (BUILTIN_SQRT_P (fcode)) 7113 { 7114 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7115 7116 if (powfn) 7117 { 7118 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1)); 7119 tree tree_root; 7120 REAL_VALUE_TYPE dconstroot = dconstthird; 7121 7122 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); 7123 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7124 tree_root = build_real (type, dconstroot); 7125 arglist = tree_cons (NULL_TREE, arg0, 7126 build_tree_list (NULL_TREE, tree_root)); 7127 return build_function_call_expr (powfn, arglist); 7128 } 7129 } 7130 7131 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */ 7132 if (BUILTIN_CBRT_P (fcode)) 7133 { 7134 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1)); 7135 if (tree_expr_nonnegative_p (arg0)) 7136 { 7137 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7138 7139 if (powfn) 7140 { 7141 tree tree_root; 7142 REAL_VALUE_TYPE dconstroot; 7143 7144 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird); 7145 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7146 tree_root = build_real (type, dconstroot); 7147 arglist = tree_cons (NULL_TREE, arg0, 7148 build_tree_list (NULL_TREE, tree_root)); 7149 return build_function_call_expr (powfn, arglist); 7150 } 7151 } 7152 } 7153 7154 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */ 7155 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF 7156 || fcode == BUILT_IN_POWL) 7157 { 7158 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1)); 7159 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1))); 7160 if (tree_expr_nonnegative_p (arg00)) 7161 { 7162 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 7163 const REAL_VALUE_TYPE dconstroot 7164 = real_value_truncate (TYPE_MODE (type), dconstthird); 7165 tree narg01 = fold_build2 (MULT_EXPR, type, arg01, 7166 build_real (type, dconstroot)); 7167 arglist = tree_cons (NULL_TREE, arg00, 7168 build_tree_list (NULL_TREE, narg01)); 7169 return build_function_call_expr (powfn, arglist); 7170 } 7171 } 7172 } 7173 return NULL_TREE; 7174} 7175 7176/* Fold function call to builtin sin, sinf, or sinl. Return 7177 NULL_TREE if no simplification can be made. */ 7178static tree 7179fold_builtin_sin (tree arglist) 7180{ 7181 tree arg = TREE_VALUE (arglist); 7182 7183 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7184 return NULL_TREE; 7185 7186 /* Optimize sin (0.0) = 0.0. */ 7187 if (real_zerop (arg)) 7188 return arg; 7189 7190 return NULL_TREE; 7191} 7192 7193/* Fold function call to builtin cos, cosf, or cosl. Return 7194 NULL_TREE if no simplification can be made. */ 7195static tree 7196fold_builtin_cos (tree arglist, tree type, tree fndecl) 7197{ 7198 tree arg = TREE_VALUE (arglist); 7199 7200 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7201 return NULL_TREE; 7202 7203 /* Optimize cos (0.0) = 1.0. */ 7204 if (real_zerop (arg)) 7205 return build_real (type, dconst1); 7206 7207 /* Optimize cos(-x) into cos (x). */ 7208 if (TREE_CODE (arg) == NEGATE_EXPR) 7209 { 7210 tree args = build_tree_list (NULL_TREE, 7211 TREE_OPERAND (arg, 0)); 7212 return build_function_call_expr (fndecl, args); 7213 } 7214 7215 return NULL_TREE; 7216} 7217 7218/* Fold function call to builtin tan, tanf, or tanl. Return 7219 NULL_TREE if no simplification can be made. */ 7220static tree 7221fold_builtin_tan (tree arglist) 7222{ 7223 enum built_in_function fcode; 7224 tree arg = TREE_VALUE (arglist); 7225 7226 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7227 return NULL_TREE; 7228 7229 /* Optimize tan(0.0) = 0.0. */ 7230 if (real_zerop (arg)) 7231 return arg; 7232 7233 /* Optimize tan(atan(x)) = x. */ 7234 fcode = builtin_mathfn_code (arg); 7235 if (flag_unsafe_math_optimizations 7236 && (fcode == BUILT_IN_ATAN 7237 || fcode == BUILT_IN_ATANF 7238 || fcode == BUILT_IN_ATANL)) 7239 return TREE_VALUE (TREE_OPERAND (arg, 1)); 7240 7241 return NULL_TREE; 7242} 7243 7244/* Fold function call to builtin atan, atanf, or atanl. Return 7245 NULL_TREE if no simplification can be made. */ 7246 7247static tree 7248fold_builtin_atan (tree arglist, tree type) 7249{ 7250 7251 tree arg = TREE_VALUE (arglist); 7252 7253 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7254 return NULL_TREE; 7255 7256 /* Optimize atan(0.0) = 0.0. */ 7257 if (real_zerop (arg)) 7258 return arg; 7259 7260 /* Optimize atan(1.0) = pi/4. */ 7261 if (real_onep (arg)) 7262 { 7263 REAL_VALUE_TYPE cst; 7264 7265 real_convert (&cst, TYPE_MODE (type), &dconstpi); 7266 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2); 7267 return build_real (type, cst); 7268 } 7269 7270 return NULL_TREE; 7271} 7272 7273/* Fold function call to builtin trunc, truncf or truncl. Return 7274 NULL_TREE if no simplification can be made. */ 7275 7276static tree 7277fold_builtin_trunc (tree fndecl, tree arglist) 7278{ 7279 tree arg; 7280 7281 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7282 return 0; 7283 7284 /* Optimize trunc of constant value. */ 7285 arg = TREE_VALUE (arglist); 7286 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7287 { 7288 REAL_VALUE_TYPE r, x; 7289 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7290 7291 x = TREE_REAL_CST (arg); 7292 real_trunc (&r, TYPE_MODE (type), &x); 7293 return build_real (type, r); 7294 } 7295 7296 return fold_trunc_transparent_mathfn (fndecl, arglist); 7297} 7298 7299/* Fold function call to builtin floor, floorf or floorl. Return 7300 NULL_TREE if no simplification can be made. */ 7301 7302static tree 7303fold_builtin_floor (tree fndecl, tree arglist) 7304{ 7305 tree arg; 7306 7307 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7308 return 0; 7309 7310 /* Optimize floor of constant value. */ 7311 arg = TREE_VALUE (arglist); 7312 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7313 { 7314 REAL_VALUE_TYPE x; 7315 7316 x = TREE_REAL_CST (arg); 7317 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 7318 { 7319 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7320 REAL_VALUE_TYPE r; 7321 7322 real_floor (&r, TYPE_MODE (type), &x); 7323 return build_real (type, r); 7324 } 7325 } 7326 7327 return fold_trunc_transparent_mathfn (fndecl, arglist); 7328} 7329 7330/* Fold function call to builtin ceil, ceilf or ceill. Return 7331 NULL_TREE if no simplification can be made. */ 7332 7333static tree 7334fold_builtin_ceil (tree fndecl, tree arglist) 7335{ 7336 tree arg; 7337 7338 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7339 return 0; 7340 7341 /* Optimize ceil of constant value. */ 7342 arg = TREE_VALUE (arglist); 7343 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7344 { 7345 REAL_VALUE_TYPE x; 7346 7347 x = TREE_REAL_CST (arg); 7348 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 7349 { 7350 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7351 REAL_VALUE_TYPE r; 7352 7353 real_ceil (&r, TYPE_MODE (type), &x); 7354 return build_real (type, r); 7355 } 7356 } 7357 7358 /* Fold floor (x) where x is nonnegative to trunc (x). */ 7359 if (tree_expr_nonnegative_p (arg)) 7360 return build_function_call_expr (mathfn_built_in (TREE_TYPE (arg), 7361 BUILT_IN_TRUNC), 7362 arglist); 7363 7364 return fold_trunc_transparent_mathfn (fndecl, arglist); 7365} 7366 7367/* Fold function call to builtin round, roundf or roundl. Return 7368 NULL_TREE if no simplification can be made. */ 7369 7370static tree 7371fold_builtin_round (tree fndecl, tree arglist) 7372{ 7373 tree arg; 7374 7375 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7376 return 0; 7377 7378 /* Optimize round of constant value. */ 7379 arg = TREE_VALUE (arglist); 7380 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7381 { 7382 REAL_VALUE_TYPE x; 7383 7384 x = TREE_REAL_CST (arg); 7385 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 7386 { 7387 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7388 REAL_VALUE_TYPE r; 7389 7390 real_round (&r, TYPE_MODE (type), &x); 7391 return build_real (type, r); 7392 } 7393 } 7394 7395 return fold_trunc_transparent_mathfn (fndecl, arglist); 7396} 7397 7398/* Fold function call to builtin lround, lroundf or lroundl (or the 7399 corresponding long long versions) and other rounding functions. 7400 Return NULL_TREE if no simplification can be made. */ 7401 7402static tree 7403fold_builtin_int_roundingfn (tree fndecl, tree arglist) 7404{ 7405 tree arg; 7406 7407 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7408 return 0; 7409 7410 /* Optimize lround of constant value. */ 7411 arg = TREE_VALUE (arglist); 7412 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7413 { 7414 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg); 7415 7416 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x)) 7417 { 7418 tree itype = TREE_TYPE (TREE_TYPE (fndecl)); 7419 tree ftype = TREE_TYPE (arg), result; 7420 HOST_WIDE_INT hi, lo; 7421 REAL_VALUE_TYPE r; 7422 7423 switch (DECL_FUNCTION_CODE (fndecl)) 7424 { 7425 CASE_FLT_FN (BUILT_IN_LFLOOR): 7426 CASE_FLT_FN (BUILT_IN_LLFLOOR): 7427 real_floor (&r, TYPE_MODE (ftype), &x); 7428 break; 7429 7430 CASE_FLT_FN (BUILT_IN_LCEIL): 7431 CASE_FLT_FN (BUILT_IN_LLCEIL): 7432 real_ceil (&r, TYPE_MODE (ftype), &x); 7433 break; 7434 7435 CASE_FLT_FN (BUILT_IN_LROUND): 7436 CASE_FLT_FN (BUILT_IN_LLROUND): 7437 real_round (&r, TYPE_MODE (ftype), &x); 7438 break; 7439 7440 default: 7441 gcc_unreachable (); 7442 } 7443 7444 REAL_VALUE_TO_INT (&lo, &hi, r); 7445 result = build_int_cst_wide (NULL_TREE, lo, hi); 7446 if (int_fits_type_p (result, itype)) 7447 return fold_convert (itype, result); 7448 } 7449 } 7450 7451 switch (DECL_FUNCTION_CODE (fndecl)) 7452 { 7453 CASE_FLT_FN (BUILT_IN_LFLOOR): 7454 CASE_FLT_FN (BUILT_IN_LLFLOOR): 7455 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */ 7456 if (tree_expr_nonnegative_p (arg)) 7457 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), 7458 arg); 7459 break; 7460 default:; 7461 } 7462 7463 return fold_fixed_mathfn (fndecl, arglist); 7464} 7465 7466/* Fold function call to builtin ffs, clz, ctz, popcount and parity 7467 and their long and long long variants (i.e. ffsl and ffsll). 7468 Return NULL_TREE if no simplification can be made. */ 7469 7470static tree 7471fold_builtin_bitop (tree fndecl, tree arglist) 7472{ 7473 tree arg; 7474 7475 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 7476 return NULL_TREE; 7477 7478 /* Optimize for constant argument. */ 7479 arg = TREE_VALUE (arglist); 7480 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7481 { 7482 HOST_WIDE_INT hi, width, result; 7483 unsigned HOST_WIDE_INT lo; 7484 tree type; 7485 7486 type = TREE_TYPE (arg); 7487 width = TYPE_PRECISION (type); 7488 lo = TREE_INT_CST_LOW (arg); 7489 7490 /* Clear all the bits that are beyond the type's precision. */ 7491 if (width > HOST_BITS_PER_WIDE_INT) 7492 { 7493 hi = TREE_INT_CST_HIGH (arg); 7494 if (width < 2 * HOST_BITS_PER_WIDE_INT) 7495 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT)); 7496 } 7497 else 7498 { 7499 hi = 0; 7500 if (width < HOST_BITS_PER_WIDE_INT) 7501 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width); 7502 } 7503 7504 switch (DECL_FUNCTION_CODE (fndecl)) 7505 { 7506 CASE_INT_FN (BUILT_IN_FFS): 7507 if (lo != 0) 7508 result = exact_log2 (lo & -lo) + 1; 7509 else if (hi != 0) 7510 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1; 7511 else 7512 result = 0; 7513 break; 7514 7515 CASE_INT_FN (BUILT_IN_CLZ): 7516 if (hi != 0) 7517 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT; 7518 else if (lo != 0) 7519 result = width - floor_log2 (lo) - 1; 7520 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result)) 7521 result = width; 7522 break; 7523 7524 CASE_INT_FN (BUILT_IN_CTZ): 7525 if (lo != 0) 7526 result = exact_log2 (lo & -lo); 7527 else if (hi != 0) 7528 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi); 7529 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result)) 7530 result = width; 7531 break; 7532 7533 CASE_INT_FN (BUILT_IN_POPCOUNT): 7534 result = 0; 7535 while (lo) 7536 result++, lo &= lo - 1; 7537 while (hi) 7538 result++, hi &= hi - 1; 7539 break; 7540 7541 CASE_INT_FN (BUILT_IN_PARITY): 7542 result = 0; 7543 while (lo) 7544 result++, lo &= lo - 1; 7545 while (hi) 7546 result++, hi &= hi - 1; 7547 result &= 1; 7548 break; 7549 7550 default: 7551 gcc_unreachable (); 7552 } 7553 7554 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result); 7555 } 7556 7557 return NULL_TREE; 7558} 7559 7560/* Return true if EXPR is the real constant contained in VALUE. */ 7561 7562static bool 7563real_dconstp (tree expr, const REAL_VALUE_TYPE *value) 7564{ 7565 STRIP_NOPS (expr); 7566 7567 return ((TREE_CODE (expr) == REAL_CST 7568 && ! TREE_CONSTANT_OVERFLOW (expr) 7569 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value)) 7570 || (TREE_CODE (expr) == COMPLEX_CST 7571 && real_dconstp (TREE_REALPART (expr), value) 7572 && real_zerop (TREE_IMAGPART (expr)))); 7573} 7574 7575/* A subroutine of fold_builtin to fold the various logarithmic 7576 functions. EXP is the CALL_EXPR of a call to a builtin logN 7577 function. VALUE is the base of the logN function. */ 7578 7579static tree 7580fold_builtin_logarithm (tree fndecl, tree arglist, 7581 const REAL_VALUE_TYPE *value) 7582{ 7583 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7584 { 7585 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7586 tree arg = TREE_VALUE (arglist); 7587 const enum built_in_function fcode = builtin_mathfn_code (arg); 7588 7589 /* Optimize logN(1.0) = 0.0. */ 7590 if (real_onep (arg)) 7591 return build_real (type, dconst0); 7592 7593 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE 7594 exactly, then only do this if flag_unsafe_math_optimizations. */ 7595 if (exact_real_truncate (TYPE_MODE (type), value) 7596 || flag_unsafe_math_optimizations) 7597 { 7598 const REAL_VALUE_TYPE value_truncate = 7599 real_value_truncate (TYPE_MODE (type), *value); 7600 if (real_dconstp (arg, &value_truncate)) 7601 return build_real (type, dconst1); 7602 } 7603 7604 /* Special case, optimize logN(expN(x)) = x. */ 7605 if (flag_unsafe_math_optimizations 7606 && ((value == &dconste 7607 && (fcode == BUILT_IN_EXP 7608 || fcode == BUILT_IN_EXPF 7609 || fcode == BUILT_IN_EXPL)) 7610 || (value == &dconst2 7611 && (fcode == BUILT_IN_EXP2 7612 || fcode == BUILT_IN_EXP2F 7613 || fcode == BUILT_IN_EXP2L)) 7614 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode))))) 7615 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1))); 7616 7617 /* Optimize logN(func()) for various exponential functions. We 7618 want to determine the value "x" and the power "exponent" in 7619 order to transform logN(x**exponent) into exponent*logN(x). */ 7620 if (flag_unsafe_math_optimizations) 7621 { 7622 tree exponent = 0, x = 0; 7623 7624 switch (fcode) 7625 { 7626 CASE_FLT_FN (BUILT_IN_EXP): 7627 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */ 7628 x = build_real (type, 7629 real_value_truncate (TYPE_MODE (type), dconste)); 7630 exponent = TREE_VALUE (TREE_OPERAND (arg, 1)); 7631 break; 7632 CASE_FLT_FN (BUILT_IN_EXP2): 7633 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */ 7634 x = build_real (type, dconst2); 7635 exponent = TREE_VALUE (TREE_OPERAND (arg, 1)); 7636 break; 7637 CASE_FLT_FN (BUILT_IN_EXP10): 7638 CASE_FLT_FN (BUILT_IN_POW10): 7639 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */ 7640 x = build_real (type, dconst10); 7641 exponent = TREE_VALUE (TREE_OPERAND (arg, 1)); 7642 break; 7643 CASE_FLT_FN (BUILT_IN_SQRT): 7644 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */ 7645 x = TREE_VALUE (TREE_OPERAND (arg, 1)); 7646 exponent = build_real (type, dconsthalf); 7647 break; 7648 CASE_FLT_FN (BUILT_IN_CBRT): 7649 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */ 7650 x = TREE_VALUE (TREE_OPERAND (arg, 1)); 7651 exponent = build_real (type, real_value_truncate (TYPE_MODE (type), 7652 dconstthird)); 7653 break; 7654 CASE_FLT_FN (BUILT_IN_POW): 7655 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */ 7656 x = TREE_VALUE (TREE_OPERAND (arg, 1)); 7657 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1))); 7658 break; 7659 default: 7660 break; 7661 } 7662 7663 /* Now perform the optimization. */ 7664 if (x && exponent) 7665 { 7666 tree logfn; 7667 arglist = build_tree_list (NULL_TREE, x); 7668 logfn = build_function_call_expr (fndecl, arglist); 7669 return fold_build2 (MULT_EXPR, type, exponent, logfn); 7670 } 7671 } 7672 } 7673 7674 return 0; 7675} 7676 7677/* Fold a builtin function call to pow, powf, or powl. Return 7678 NULL_TREE if no simplification can be made. */ 7679static tree 7680fold_builtin_pow (tree fndecl, tree arglist, tree type) 7681{ 7682 tree arg0 = TREE_VALUE (arglist); 7683 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 7684 7685 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 7686 return NULL_TREE; 7687 7688 /* Optimize pow(1.0,y) = 1.0. */ 7689 if (real_onep (arg0)) 7690 return omit_one_operand (type, build_real (type, dconst1), arg1); 7691 7692 if (TREE_CODE (arg1) == REAL_CST 7693 && ! TREE_CONSTANT_OVERFLOW (arg1)) 7694 { 7695 REAL_VALUE_TYPE cint; 7696 REAL_VALUE_TYPE c; 7697 HOST_WIDE_INT n; 7698 7699 c = TREE_REAL_CST (arg1); 7700 7701 /* Optimize pow(x,0.0) = 1.0. */ 7702 if (REAL_VALUES_EQUAL (c, dconst0)) 7703 return omit_one_operand (type, build_real (type, dconst1), 7704 arg0); 7705 7706 /* Optimize pow(x,1.0) = x. */ 7707 if (REAL_VALUES_EQUAL (c, dconst1)) 7708 return arg0; 7709 7710 /* Optimize pow(x,-1.0) = 1.0/x. */ 7711 if (REAL_VALUES_EQUAL (c, dconstm1)) 7712 return fold_build2 (RDIV_EXPR, type, 7713 build_real (type, dconst1), arg0); 7714 7715 /* Optimize pow(x,0.5) = sqrt(x). */ 7716 if (flag_unsafe_math_optimizations 7717 && REAL_VALUES_EQUAL (c, dconsthalf)) 7718 { 7719 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); 7720 7721 if (sqrtfn != NULL_TREE) 7722 { 7723 tree arglist = build_tree_list (NULL_TREE, arg0); 7724 return build_function_call_expr (sqrtfn, arglist); 7725 } 7726 } 7727 7728 /* Check for an integer exponent. */ 7729 n = real_to_integer (&c); 7730 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); 7731 if (real_identical (&c, &cint)) 7732 { 7733 /* Attempt to evaluate pow at compile-time. */ 7734 if (TREE_CODE (arg0) == REAL_CST 7735 && ! TREE_CONSTANT_OVERFLOW (arg0)) 7736 { 7737 REAL_VALUE_TYPE x; 7738 bool inexact; 7739 7740 x = TREE_REAL_CST (arg0); 7741 inexact = real_powi (&x, TYPE_MODE (type), &x, n); 7742 if (flag_unsafe_math_optimizations || !inexact) 7743 return build_real (type, x); 7744 } 7745 7746 /* Strip sign ops from even integer powers. */ 7747 if ((n & 1) == 0 && flag_unsafe_math_optimizations) 7748 { 7749 tree narg0 = fold_strip_sign_ops (arg0); 7750 if (narg0) 7751 { 7752 arglist = build_tree_list (NULL_TREE, arg1); 7753 arglist = tree_cons (NULL_TREE, narg0, arglist); 7754 return build_function_call_expr (fndecl, arglist); 7755 } 7756 } 7757 } 7758 } 7759 7760 if (flag_unsafe_math_optimizations) 7761 { 7762 const enum built_in_function fcode = builtin_mathfn_code (arg0); 7763 7764 /* Optimize pow(expN(x),y) = expN(x*y). */ 7765 if (BUILTIN_EXPONENT_P (fcode)) 7766 { 7767 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0); 7768 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1)); 7769 arg = fold_build2 (MULT_EXPR, type, arg, arg1); 7770 arglist = build_tree_list (NULL_TREE, arg); 7771 return build_function_call_expr (expfn, arglist); 7772 } 7773 7774 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */ 7775 if (BUILTIN_SQRT_P (fcode)) 7776 { 7777 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1)); 7778 tree narg1 = fold_build2 (MULT_EXPR, type, arg1, 7779 build_real (type, dconsthalf)); 7780 7781 arglist = tree_cons (NULL_TREE, narg0, 7782 build_tree_list (NULL_TREE, narg1)); 7783 return build_function_call_expr (fndecl, arglist); 7784 } 7785 7786 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */ 7787 if (BUILTIN_CBRT_P (fcode)) 7788 { 7789 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1)); 7790 if (tree_expr_nonnegative_p (arg)) 7791 { 7792 const REAL_VALUE_TYPE dconstroot 7793 = real_value_truncate (TYPE_MODE (type), dconstthird); 7794 tree narg1 = fold_build2 (MULT_EXPR, type, arg1, 7795 build_real (type, dconstroot)); 7796 arglist = tree_cons (NULL_TREE, arg, 7797 build_tree_list (NULL_TREE, narg1)); 7798 return build_function_call_expr (fndecl, arglist); 7799 } 7800 } 7801 7802 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */ 7803 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF 7804 || fcode == BUILT_IN_POWL) 7805 { 7806 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1)); 7807 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1))); 7808 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1); 7809 arglist = tree_cons (NULL_TREE, arg00, 7810 build_tree_list (NULL_TREE, narg1)); 7811 return build_function_call_expr (fndecl, arglist); 7812 } 7813 } 7814 7815 return NULL_TREE; 7816} 7817 7818/* Fold a builtin function call to powi, powif, or powil. Return 7819 NULL_TREE if no simplification can be made. */ 7820static tree 7821fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type) 7822{ 7823 tree arg0 = TREE_VALUE (arglist); 7824 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 7825 7826 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE)) 7827 return NULL_TREE; 7828 7829 /* Optimize pow(1.0,y) = 1.0. */ 7830 if (real_onep (arg0)) 7831 return omit_one_operand (type, build_real (type, dconst1), arg1); 7832 7833 if (host_integerp (arg1, 0)) 7834 { 7835 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1); 7836 7837 /* Evaluate powi at compile-time. */ 7838 if (TREE_CODE (arg0) == REAL_CST 7839 && ! TREE_CONSTANT_OVERFLOW (arg0)) 7840 { 7841 REAL_VALUE_TYPE x; 7842 x = TREE_REAL_CST (arg0); 7843 real_powi (&x, TYPE_MODE (type), &x, c); 7844 return build_real (type, x); 7845 } 7846 7847 /* Optimize pow(x,0) = 1.0. */ 7848 if (c == 0) 7849 return omit_one_operand (type, build_real (type, dconst1), 7850 arg0); 7851 7852 /* Optimize pow(x,1) = x. */ 7853 if (c == 1) 7854 return arg0; 7855 7856 /* Optimize pow(x,-1) = 1.0/x. */ 7857 if (c == -1) 7858 return fold_build2 (RDIV_EXPR, type, 7859 build_real (type, dconst1), arg0); 7860 } 7861 7862 return NULL_TREE; 7863} 7864 7865/* A subroutine of fold_builtin to fold the various exponent 7866 functions. EXP is the CALL_EXPR of a call to a builtin function. 7867 VALUE is the value which will be raised to a power. */ 7868 7869static tree 7870fold_builtin_exponent (tree fndecl, tree arglist, 7871 const REAL_VALUE_TYPE *value) 7872{ 7873 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7874 { 7875 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7876 tree arg = TREE_VALUE (arglist); 7877 7878 /* Optimize exp*(0.0) = 1.0. */ 7879 if (real_zerop (arg)) 7880 return build_real (type, dconst1); 7881 7882 /* Optimize expN(1.0) = N. */ 7883 if (real_onep (arg)) 7884 { 7885 REAL_VALUE_TYPE cst; 7886 7887 real_convert (&cst, TYPE_MODE (type), value); 7888 return build_real (type, cst); 7889 } 7890 7891 /* Attempt to evaluate expN(integer) at compile-time. */ 7892 if (flag_unsafe_math_optimizations 7893 && TREE_CODE (arg) == REAL_CST 7894 && ! TREE_CONSTANT_OVERFLOW (arg)) 7895 { 7896 REAL_VALUE_TYPE cint; 7897 REAL_VALUE_TYPE c; 7898 HOST_WIDE_INT n; 7899 7900 c = TREE_REAL_CST (arg); 7901 n = real_to_integer (&c); 7902 real_from_integer (&cint, VOIDmode, n, 7903 n < 0 ? -1 : 0, 0); 7904 if (real_identical (&c, &cint)) 7905 { 7906 REAL_VALUE_TYPE x; 7907 7908 real_powi (&x, TYPE_MODE (type), value, n); 7909 return build_real (type, x); 7910 } 7911 } 7912 7913 /* Optimize expN(logN(x)) = x. */ 7914 if (flag_unsafe_math_optimizations) 7915 { 7916 const enum built_in_function fcode = builtin_mathfn_code (arg); 7917 7918 if ((value == &dconste 7919 && (fcode == BUILT_IN_LOG 7920 || fcode == BUILT_IN_LOGF 7921 || fcode == BUILT_IN_LOGL)) 7922 || (value == &dconst2 7923 && (fcode == BUILT_IN_LOG2 7924 || fcode == BUILT_IN_LOG2F 7925 || fcode == BUILT_IN_LOG2L)) 7926 || (value == &dconst10 7927 && (fcode == BUILT_IN_LOG10 7928 || fcode == BUILT_IN_LOG10F 7929 || fcode == BUILT_IN_LOG10L))) 7930 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1))); 7931 } 7932 } 7933 7934 return 0; 7935} 7936 7937/* Return true if VAR is a VAR_DECL or a component thereof. */ 7938 7939static bool 7940var_decl_component_p (tree var) 7941{ 7942 tree inner = var; 7943 while (handled_component_p (inner)) 7944 inner = TREE_OPERAND (inner, 0); 7945 return SSA_VAR_P (inner); 7946} 7947 7948/* Fold function call to builtin memset. Return 7949 NULL_TREE if no simplification can be made. */ 7950 7951static tree 7952fold_builtin_memset (tree arglist, tree type, bool ignore) 7953{ 7954 tree dest, c, len, var, ret; 7955 unsigned HOST_WIDE_INT length, cval; 7956 7957 if (!validate_arglist (arglist, 7958 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 7959 return 0; 7960 7961 dest = TREE_VALUE (arglist); 7962 c = TREE_VALUE (TREE_CHAIN (arglist)); 7963 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 7964 7965 if (! host_integerp (len, 1)) 7966 return 0; 7967 7968 /* If the LEN parameter is zero, return DEST. */ 7969 if (integer_zerop (len)) 7970 return omit_one_operand (type, dest, c); 7971 7972 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest)) 7973 return 0; 7974 7975 var = dest; 7976 STRIP_NOPS (var); 7977 if (TREE_CODE (var) != ADDR_EXPR) 7978 return 0; 7979 7980 var = TREE_OPERAND (var, 0); 7981 if (TREE_THIS_VOLATILE (var)) 7982 return 0; 7983 7984 if (!INTEGRAL_TYPE_P (TREE_TYPE (var)) 7985 && !POINTER_TYPE_P (TREE_TYPE (var))) 7986 return 0; 7987 7988 if (! var_decl_component_p (var)) 7989 return 0; 7990 7991 length = tree_low_cst (len, 1); 7992 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length 7993 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT 7994 < (int) length) 7995 return 0; 7996 7997 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT) 7998 return 0; 7999 8000 if (integer_zerop (c)) 8001 cval = 0; 8002 else 8003 { 8004 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64) 8005 return 0; 8006 8007 cval = tree_low_cst (c, 1); 8008 cval &= 0xff; 8009 cval |= cval << 8; 8010 cval |= cval << 16; 8011 cval |= (cval << 31) << 1; 8012 } 8013 8014 ret = build_int_cst_type (TREE_TYPE (var), cval); 8015 ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret); 8016 if (ignore) 8017 return ret; 8018 8019 return omit_one_operand (type, dest, ret); 8020} 8021 8022/* Fold function call to builtin memset. Return 8023 NULL_TREE if no simplification can be made. */ 8024 8025static tree 8026fold_builtin_bzero (tree arglist, bool ignore) 8027{ 8028 tree dest, size, newarglist; 8029 8030 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8031 return 0; 8032 8033 if (!ignore) 8034 return 0; 8035 8036 dest = TREE_VALUE (arglist); 8037 size = TREE_VALUE (TREE_CHAIN (arglist)); 8038 8039 /* New argument list transforming bzero(ptr x, int y) to 8040 memset(ptr x, int 0, size_t y). This is done this way 8041 so that if it isn't expanded inline, we fallback to 8042 calling bzero instead of memset. */ 8043 8044 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size)); 8045 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist); 8046 newarglist = tree_cons (NULL_TREE, dest, newarglist); 8047 return fold_builtin_memset (newarglist, void_type_node, ignore); 8048} 8049 8050/* Fold function call to builtin mem{{,p}cpy,move}. Return 8051 NULL_TREE if no simplification can be made. 8052 If ENDP is 0, return DEST (like memcpy). 8053 If ENDP is 1, return DEST+LEN (like mempcpy). 8054 If ENDP is 2, return DEST+LEN-1 (like stpcpy). 8055 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap 8056 (memmove). */ 8057 8058static tree 8059fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp) 8060{ 8061 tree dest, src, len, destvar, srcvar, expr; 8062 unsigned HOST_WIDE_INT length; 8063 8064 if (! validate_arglist (arglist, 8065 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8066 return 0; 8067 8068 dest = TREE_VALUE (arglist); 8069 src = TREE_VALUE (TREE_CHAIN (arglist)); 8070 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8071 8072 /* If the LEN parameter is zero, return DEST. */ 8073 if (integer_zerop (len)) 8074 return omit_one_operand (type, dest, src); 8075 8076 /* If SRC and DEST are the same (and not volatile), return 8077 DEST{,+LEN,+LEN-1}. */ 8078 if (operand_equal_p (src, dest, 0)) 8079 expr = len; 8080 else 8081 { 8082 if (! host_integerp (len, 1)) 8083 return 0; 8084 8085 if (TREE_SIDE_EFFECTS (dest) || TREE_SIDE_EFFECTS (src)) 8086 return 0; 8087 8088 destvar = dest; 8089 STRIP_NOPS (destvar); 8090 if (TREE_CODE (destvar) != ADDR_EXPR) 8091 return 0; 8092 8093 destvar = TREE_OPERAND (destvar, 0); 8094 if (TREE_THIS_VOLATILE (destvar)) 8095 return 0; 8096 8097 if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar)) 8098 && !POINTER_TYPE_P (TREE_TYPE (destvar)) 8099 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar))) 8100 return 0; 8101 8102 if (! var_decl_component_p (destvar)) 8103 return 0; 8104 8105 srcvar = src; 8106 STRIP_NOPS (srcvar); 8107 if (TREE_CODE (srcvar) != ADDR_EXPR) 8108 return 0; 8109 8110 srcvar = TREE_OPERAND (srcvar, 0); 8111 if (TREE_THIS_VOLATILE (srcvar)) 8112 return 0; 8113 8114 if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar)) 8115 && !POINTER_TYPE_P (TREE_TYPE (srcvar)) 8116 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar))) 8117 return 0; 8118 8119 if (! var_decl_component_p (srcvar)) 8120 return 0; 8121 8122 length = tree_low_cst (len, 1); 8123 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length 8124 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT 8125 < (int) length 8126 || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar))) != length 8127 || get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT 8128 < (int) length) 8129 return 0; 8130 8131 if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar)) 8132 || POINTER_TYPE_P (TREE_TYPE (srcvar))) 8133 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar)) 8134 || POINTER_TYPE_P (TREE_TYPE (destvar)))) 8135 expr = fold_convert (TREE_TYPE (destvar), srcvar); 8136 else 8137 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar); 8138 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr); 8139 } 8140 8141 if (ignore) 8142 return expr; 8143 8144 if (endp == 0 || endp == 3) 8145 return omit_one_operand (type, dest, expr); 8146 8147 if (expr == len) 8148 expr = 0; 8149 8150 if (endp == 2) 8151 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len, 8152 ssize_int (1)); 8153 8154 len = fold_convert (TREE_TYPE (dest), len); 8155 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len); 8156 dest = fold_convert (type, dest); 8157 if (expr) 8158 dest = omit_one_operand (type, dest, expr); 8159 return dest; 8160} 8161 8162/* Fold function call to builtin bcopy. Return NULL_TREE if no 8163 simplification can be made. */ 8164 8165static tree 8166fold_builtin_bcopy (tree arglist, bool ignore) 8167{ 8168 tree src, dest, size, newarglist; 8169 8170 if (!validate_arglist (arglist, 8171 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8172 return 0; 8173 8174 if (! ignore) 8175 return 0; 8176 8177 src = TREE_VALUE (arglist); 8178 dest = TREE_VALUE (TREE_CHAIN (arglist)); 8179 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8180 8181 /* New argument list transforming bcopy(ptr x, ptr y, int z) to 8182 memmove(ptr y, ptr x, size_t z). This is done this way 8183 so that if it isn't expanded inline, we fallback to 8184 calling bcopy instead of memmove. */ 8185 8186 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size)); 8187 newarglist = tree_cons (NULL_TREE, src, newarglist); 8188 newarglist = tree_cons (NULL_TREE, dest, newarglist); 8189 8190 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3); 8191} 8192 8193/* Fold function call to builtin strcpy. If LEN is not NULL, it represents 8194 the length of the string to be copied. Return NULL_TREE if no 8195 simplification can be made. */ 8196 8197tree 8198fold_builtin_strcpy (tree fndecl, tree arglist, tree len) 8199{ 8200 tree dest, src, fn; 8201 8202 if (!validate_arglist (arglist, 8203 POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 8204 return 0; 8205 8206 dest = TREE_VALUE (arglist); 8207 src = TREE_VALUE (TREE_CHAIN (arglist)); 8208 8209 /* If SRC and DEST are the same (and not volatile), return DEST. */ 8210 if (operand_equal_p (src, dest, 0)) 8211 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest); 8212 8213 if (optimize_size) 8214 return 0; 8215 8216 fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 8217 if (!fn) 8218 return 0; 8219 8220 if (!len) 8221 { 8222 len = c_strlen (src, 1); 8223 if (! len || TREE_SIDE_EFFECTS (len)) 8224 return 0; 8225 } 8226 8227 len = size_binop (PLUS_EXPR, len, ssize_int (1)); 8228 arglist = build_tree_list (NULL_TREE, len); 8229 arglist = tree_cons (NULL_TREE, src, arglist); 8230 arglist = tree_cons (NULL_TREE, dest, arglist); 8231 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), 8232 build_function_call_expr (fn, arglist)); 8233} 8234 8235/* Fold function call to builtin strncpy. If SLEN is not NULL, it represents 8236 the length of the source string. Return NULL_TREE if no simplification 8237 can be made. */ 8238 8239tree 8240fold_builtin_strncpy (tree fndecl, tree arglist, tree slen) 8241{ 8242 tree dest, src, len, fn; 8243 8244 if (!validate_arglist (arglist, 8245 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8246 return 0; 8247 8248 dest = TREE_VALUE (arglist); 8249 src = TREE_VALUE (TREE_CHAIN (arglist)); 8250 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8251 8252 /* If the LEN parameter is zero, return DEST. */ 8253 if (integer_zerop (len)) 8254 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src); 8255 8256 /* We can't compare slen with len as constants below if len is not a 8257 constant. */ 8258 if (len == 0 || TREE_CODE (len) != INTEGER_CST) 8259 return 0; 8260 8261 if (!slen) 8262 slen = c_strlen (src, 1); 8263 8264 /* Now, we must be passed a constant src ptr parameter. */ 8265 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST) 8266 return 0; 8267 8268 slen = size_binop (PLUS_EXPR, slen, ssize_int (1)); 8269 8270 /* We do not support simplification of this case, though we do 8271 support it when expanding trees into RTL. */ 8272 /* FIXME: generate a call to __builtin_memset. */ 8273 if (tree_int_cst_lt (slen, len)) 8274 return 0; 8275 8276 /* OK transform into builtin memcpy. */ 8277 fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 8278 if (!fn) 8279 return 0; 8280 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), 8281 build_function_call_expr (fn, arglist)); 8282} 8283 8284/* Fold function call to builtin memcmp. Return 8285 NULL_TREE if no simplification can be made. */ 8286 8287static tree 8288fold_builtin_memcmp (tree arglist) 8289{ 8290 tree arg1, arg2, len; 8291 const char *p1, *p2; 8292 8293 if (!validate_arglist (arglist, 8294 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8295 return 0; 8296 8297 arg1 = TREE_VALUE (arglist); 8298 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 8299 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8300 8301 /* If the LEN parameter is zero, return zero. */ 8302 if (integer_zerop (len)) 8303 return omit_two_operands (integer_type_node, integer_zero_node, 8304 arg1, arg2); 8305 8306 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8307 if (operand_equal_p (arg1, arg2, 0)) 8308 return omit_one_operand (integer_type_node, integer_zero_node, len); 8309 8310 p1 = c_getstr (arg1); 8311 p2 = c_getstr (arg2); 8312 8313 /* If all arguments are constant, and the value of len is not greater 8314 than the lengths of arg1 and arg2, evaluate at compile-time. */ 8315 if (host_integerp (len, 1) && p1 && p2 8316 && compare_tree_int (len, strlen (p1) + 1) <= 0 8317 && compare_tree_int (len, strlen (p2) + 1) <= 0) 8318 { 8319 const int r = memcmp (p1, p2, tree_low_cst (len, 1)); 8320 8321 if (r > 0) 8322 return integer_one_node; 8323 else if (r < 0) 8324 return integer_minus_one_node; 8325 else 8326 return integer_zero_node; 8327 } 8328 8329 /* If len parameter is one, return an expression corresponding to 8330 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ 8331 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1) 8332 { 8333 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8334 tree cst_uchar_ptr_node 8335 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8336 8337 tree ind1 = fold_convert (integer_type_node, 8338 build1 (INDIRECT_REF, cst_uchar_node, 8339 fold_convert (cst_uchar_ptr_node, 8340 arg1))); 8341 tree ind2 = fold_convert (integer_type_node, 8342 build1 (INDIRECT_REF, cst_uchar_node, 8343 fold_convert (cst_uchar_ptr_node, 8344 arg2))); 8345 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2); 8346 } 8347 8348 return 0; 8349} 8350 8351/* Fold function call to builtin strcmp. Return 8352 NULL_TREE if no simplification can be made. */ 8353 8354static tree 8355fold_builtin_strcmp (tree arglist) 8356{ 8357 tree arg1, arg2; 8358 const char *p1, *p2; 8359 8360 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 8361 return 0; 8362 8363 arg1 = TREE_VALUE (arglist); 8364 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 8365 8366 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8367 if (operand_equal_p (arg1, arg2, 0)) 8368 return integer_zero_node; 8369 8370 p1 = c_getstr (arg1); 8371 p2 = c_getstr (arg2); 8372 8373 if (p1 && p2) 8374 { 8375 const int i = strcmp (p1, p2); 8376 if (i < 0) 8377 return integer_minus_one_node; 8378 else if (i > 0) 8379 return integer_one_node; 8380 else 8381 return integer_zero_node; 8382 } 8383 8384 /* If the second arg is "", return *(const unsigned char*)arg1. */ 8385 if (p2 && *p2 == '\0') 8386 { 8387 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8388 tree cst_uchar_ptr_node 8389 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8390 8391 return fold_convert (integer_type_node, 8392 build1 (INDIRECT_REF, cst_uchar_node, 8393 fold_convert (cst_uchar_ptr_node, 8394 arg1))); 8395 } 8396 8397 /* If the first arg is "", return -*(const unsigned char*)arg2. */ 8398 if (p1 && *p1 == '\0') 8399 { 8400 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8401 tree cst_uchar_ptr_node 8402 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8403 8404 tree temp = fold_convert (integer_type_node, 8405 build1 (INDIRECT_REF, cst_uchar_node, 8406 fold_convert (cst_uchar_ptr_node, 8407 arg2))); 8408 return fold_build1 (NEGATE_EXPR, integer_type_node, temp); 8409 } 8410 8411 return 0; 8412} 8413 8414/* Fold function call to builtin strncmp. Return 8415 NULL_TREE if no simplification can be made. */ 8416 8417static tree 8418fold_builtin_strncmp (tree arglist) 8419{ 8420 tree arg1, arg2, len; 8421 const char *p1, *p2; 8422 8423 if (!validate_arglist (arglist, 8424 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8425 return 0; 8426 8427 arg1 = TREE_VALUE (arglist); 8428 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 8429 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8430 8431 /* If the LEN parameter is zero, return zero. */ 8432 if (integer_zerop (len)) 8433 return omit_two_operands (integer_type_node, integer_zero_node, 8434 arg1, arg2); 8435 8436 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8437 if (operand_equal_p (arg1, arg2, 0)) 8438 return omit_one_operand (integer_type_node, integer_zero_node, len); 8439 8440 p1 = c_getstr (arg1); 8441 p2 = c_getstr (arg2); 8442 8443 if (host_integerp (len, 1) && p1 && p2) 8444 { 8445 const int i = strncmp (p1, p2, tree_low_cst (len, 1)); 8446 if (i > 0) 8447 return integer_one_node; 8448 else if (i < 0) 8449 return integer_minus_one_node; 8450 else 8451 return integer_zero_node; 8452 } 8453 8454 /* If the second arg is "", and the length is greater than zero, 8455 return *(const unsigned char*)arg1. */ 8456 if (p2 && *p2 == '\0' 8457 && TREE_CODE (len) == INTEGER_CST 8458 && tree_int_cst_sgn (len) == 1) 8459 { 8460 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8461 tree cst_uchar_ptr_node 8462 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8463 8464 return fold_convert (integer_type_node, 8465 build1 (INDIRECT_REF, cst_uchar_node, 8466 fold_convert (cst_uchar_ptr_node, 8467 arg1))); 8468 } 8469 8470 /* If the first arg is "", and the length is greater than zero, 8471 return -*(const unsigned char*)arg2. */ 8472 if (p1 && *p1 == '\0' 8473 && TREE_CODE (len) == INTEGER_CST 8474 && tree_int_cst_sgn (len) == 1) 8475 { 8476 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8477 tree cst_uchar_ptr_node 8478 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8479 8480 tree temp = fold_convert (integer_type_node, 8481 build1 (INDIRECT_REF, cst_uchar_node, 8482 fold_convert (cst_uchar_ptr_node, 8483 arg2))); 8484 return fold_build1 (NEGATE_EXPR, integer_type_node, temp); 8485 } 8486 8487 /* If len parameter is one, return an expression corresponding to 8488 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ 8489 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1) 8490 { 8491 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8492 tree cst_uchar_ptr_node 8493 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8494 8495 tree ind1 = fold_convert (integer_type_node, 8496 build1 (INDIRECT_REF, cst_uchar_node, 8497 fold_convert (cst_uchar_ptr_node, 8498 arg1))); 8499 tree ind2 = fold_convert (integer_type_node, 8500 build1 (INDIRECT_REF, cst_uchar_node, 8501 fold_convert (cst_uchar_ptr_node, 8502 arg2))); 8503 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2); 8504 } 8505 8506 return 0; 8507} 8508 8509/* Fold function call to builtin signbit, signbitf or signbitl. Return 8510 NULL_TREE if no simplification can be made. */ 8511 8512static tree 8513fold_builtin_signbit (tree fndecl, tree arglist) 8514{ 8515 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8516 tree arg, temp; 8517 8518 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 8519 return NULL_TREE; 8520 8521 arg = TREE_VALUE (arglist); 8522 8523 /* If ARG is a compile-time constant, determine the result. */ 8524 if (TREE_CODE (arg) == REAL_CST 8525 && !TREE_CONSTANT_OVERFLOW (arg)) 8526 { 8527 REAL_VALUE_TYPE c; 8528 8529 c = TREE_REAL_CST (arg); 8530 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node; 8531 return fold_convert (type, temp); 8532 } 8533 8534 /* If ARG is non-negative, the result is always zero. */ 8535 if (tree_expr_nonnegative_p (arg)) 8536 return omit_one_operand (type, integer_zero_node, arg); 8537 8538 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */ 8539 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg)))) 8540 return fold_build2 (LT_EXPR, type, arg, 8541 build_real (TREE_TYPE (arg), dconst0)); 8542 8543 return NULL_TREE; 8544} 8545 8546/* Fold function call to builtin copysign, copysignf or copysignl. 8547 Return NULL_TREE if no simplification can be made. */ 8548 8549static tree 8550fold_builtin_copysign (tree fndecl, tree arglist, tree type) 8551{ 8552 tree arg1, arg2, tem; 8553 8554 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 8555 return NULL_TREE; 8556 8557 arg1 = TREE_VALUE (arglist); 8558 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 8559 8560 /* copysign(X,X) is X. */ 8561 if (operand_equal_p (arg1, arg2, 0)) 8562 return fold_convert (type, arg1); 8563 8564 /* If ARG1 and ARG2 are compile-time constants, determine the result. */ 8565 if (TREE_CODE (arg1) == REAL_CST 8566 && TREE_CODE (arg2) == REAL_CST 8567 && !TREE_CONSTANT_OVERFLOW (arg1) 8568 && !TREE_CONSTANT_OVERFLOW (arg2)) 8569 { 8570 REAL_VALUE_TYPE c1, c2; 8571 8572 c1 = TREE_REAL_CST (arg1); 8573 c2 = TREE_REAL_CST (arg2); 8574 /* c1.sign := c2.sign. */ 8575 real_copysign (&c1, &c2); 8576 return build_real (type, c1); 8577 } 8578 8579 /* copysign(X, Y) is fabs(X) when Y is always non-negative. 8580 Remember to evaluate Y for side-effects. */ 8581 if (tree_expr_nonnegative_p (arg2)) 8582 return omit_one_operand (type, 8583 fold_build1 (ABS_EXPR, type, arg1), 8584 arg2); 8585 8586 /* Strip sign changing operations for the first argument. */ 8587 tem = fold_strip_sign_ops (arg1); 8588 if (tem) 8589 { 8590 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist)); 8591 return build_function_call_expr (fndecl, arglist); 8592 } 8593 8594 return NULL_TREE; 8595} 8596 8597/* Fold a call to builtin isascii. */ 8598 8599static tree 8600fold_builtin_isascii (tree arglist) 8601{ 8602 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 8603 return 0; 8604 else 8605 { 8606 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */ 8607 tree arg = TREE_VALUE (arglist); 8608 8609 arg = build2 (BIT_AND_EXPR, integer_type_node, arg, 8610 build_int_cst (NULL_TREE, 8611 ~ (unsigned HOST_WIDE_INT) 0x7f)); 8612 arg = fold_build2 (EQ_EXPR, integer_type_node, 8613 arg, integer_zero_node); 8614 8615 if (in_gimple_form && !TREE_CONSTANT (arg)) 8616 return NULL_TREE; 8617 else 8618 return arg; 8619 } 8620} 8621 8622/* Fold a call to builtin toascii. */ 8623 8624static tree 8625fold_builtin_toascii (tree arglist) 8626{ 8627 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 8628 return 0; 8629 else 8630 { 8631 /* Transform toascii(c) -> (c & 0x7f). */ 8632 tree arg = TREE_VALUE (arglist); 8633 8634 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg, 8635 build_int_cst (NULL_TREE, 0x7f)); 8636 } 8637} 8638 8639/* Fold a call to builtin isdigit. */ 8640 8641static tree 8642fold_builtin_isdigit (tree arglist) 8643{ 8644 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 8645 return 0; 8646 else 8647 { 8648 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */ 8649 /* According to the C standard, isdigit is unaffected by locale. 8650 However, it definitely is affected by the target character set. */ 8651 tree arg; 8652 unsigned HOST_WIDE_INT target_digit0 8653 = lang_hooks.to_target_charset ('0'); 8654 8655 if (target_digit0 == 0) 8656 return NULL_TREE; 8657 8658 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist)); 8659 arg = build2 (MINUS_EXPR, unsigned_type_node, arg, 8660 build_int_cst (unsigned_type_node, target_digit0)); 8661 arg = fold_build2 (LE_EXPR, integer_type_node, arg, 8662 build_int_cst (unsigned_type_node, 9)); 8663 if (in_gimple_form && !TREE_CONSTANT (arg)) 8664 return NULL_TREE; 8665 else 8666 return arg; 8667 } 8668} 8669 8670/* Fold a call to fabs, fabsf or fabsl. */ 8671 8672static tree 8673fold_builtin_fabs (tree arglist, tree type) 8674{ 8675 tree arg; 8676 8677 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 8678 return 0; 8679 8680 arg = TREE_VALUE (arglist); 8681 arg = fold_convert (type, arg); 8682 if (TREE_CODE (arg) == REAL_CST) 8683 return fold_abs_const (arg, type); 8684 return fold_build1 (ABS_EXPR, type, arg); 8685} 8686 8687/* Fold a call to abs, labs, llabs or imaxabs. */ 8688 8689static tree 8690fold_builtin_abs (tree arglist, tree type) 8691{ 8692 tree arg; 8693 8694 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 8695 return 0; 8696 8697 arg = TREE_VALUE (arglist); 8698 arg = fold_convert (type, arg); 8699 if (TREE_CODE (arg) == INTEGER_CST) 8700 return fold_abs_const (arg, type); 8701 return fold_build1 (ABS_EXPR, type, arg); 8702} 8703 8704/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite. 8705 EXP is the CALL_EXPR for the call. */ 8706 8707static tree 8708fold_builtin_classify (tree fndecl, tree arglist, int builtin_index) 8709{ 8710 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8711 tree arg; 8712 REAL_VALUE_TYPE r; 8713 8714 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 8715 { 8716 /* Check that we have exactly one argument. */ 8717 if (arglist == 0) 8718 { 8719 error ("too few arguments to function %qs", 8720 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8721 return error_mark_node; 8722 } 8723 else if (TREE_CHAIN (arglist) != 0) 8724 { 8725 error ("too many arguments to function %qs", 8726 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8727 return error_mark_node; 8728 } 8729 else 8730 { 8731 error ("non-floating-point argument to function %qs", 8732 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8733 return error_mark_node; 8734 } 8735 } 8736 8737 arg = TREE_VALUE (arglist); 8738 switch (builtin_index) 8739 { 8740 case BUILT_IN_ISINF: 8741 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg)))) 8742 return omit_one_operand (type, integer_zero_node, arg); 8743 8744 if (TREE_CODE (arg) == REAL_CST) 8745 { 8746 r = TREE_REAL_CST (arg); 8747 if (real_isinf (&r)) 8748 return real_compare (GT_EXPR, &r, &dconst0) 8749 ? integer_one_node : integer_minus_one_node; 8750 else 8751 return integer_zero_node; 8752 } 8753 8754 return NULL_TREE; 8755 8756 case BUILT_IN_FINITE: 8757 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))) 8758 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg)))) 8759 return omit_one_operand (type, integer_one_node, arg); 8760 8761 if (TREE_CODE (arg) == REAL_CST) 8762 { 8763 r = TREE_REAL_CST (arg); 8764 return real_isinf (&r) || real_isnan (&r) 8765 ? integer_zero_node : integer_one_node; 8766 } 8767 8768 return NULL_TREE; 8769 8770 case BUILT_IN_ISNAN: 8771 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))) 8772 return omit_one_operand (type, integer_zero_node, arg); 8773 8774 if (TREE_CODE (arg) == REAL_CST) 8775 { 8776 r = TREE_REAL_CST (arg); 8777 return real_isnan (&r) ? integer_one_node : integer_zero_node; 8778 } 8779 8780 arg = builtin_save_expr (arg); 8781 return fold_build2 (UNORDERED_EXPR, type, arg, arg); 8782 8783 default: 8784 gcc_unreachable (); 8785 } 8786} 8787 8788/* Fold a call to an unordered comparison function such as 8789 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function 8790 being called and ARGLIST is the argument list for the call. 8791 UNORDERED_CODE and ORDERED_CODE are comparison codes that give 8792 the opposite of the desired result. UNORDERED_CODE is used 8793 for modes that can hold NaNs and ORDERED_CODE is used for 8794 the rest. */ 8795 8796static tree 8797fold_builtin_unordered_cmp (tree fndecl, tree arglist, 8798 enum tree_code unordered_code, 8799 enum tree_code ordered_code) 8800{ 8801 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8802 enum tree_code code; 8803 tree arg0, arg1; 8804 tree type0, type1; 8805 enum tree_code code0, code1; 8806 tree cmp_type = NULL_TREE; 8807 8808 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 8809 { 8810 /* Check that we have exactly two arguments. */ 8811 if (arglist == 0 || TREE_CHAIN (arglist) == 0) 8812 { 8813 error ("too few arguments to function %qs", 8814 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8815 return error_mark_node; 8816 } 8817 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0) 8818 { 8819 error ("too many arguments to function %qs", 8820 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8821 return error_mark_node; 8822 } 8823 } 8824 8825 arg0 = TREE_VALUE (arglist); 8826 arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 8827 8828 type0 = TREE_TYPE (arg0); 8829 type1 = TREE_TYPE (arg1); 8830 8831 code0 = TREE_CODE (type0); 8832 code1 = TREE_CODE (type1); 8833 8834 if (code0 == REAL_TYPE && code1 == REAL_TYPE) 8835 /* Choose the wider of two real types. */ 8836 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1) 8837 ? type0 : type1; 8838 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE) 8839 cmp_type = type0; 8840 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE) 8841 cmp_type = type1; 8842 else 8843 { 8844 error ("non-floating-point argument to function %qs", 8845 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8846 return error_mark_node; 8847 } 8848 8849 arg0 = fold_convert (cmp_type, arg0); 8850 arg1 = fold_convert (cmp_type, arg1); 8851 8852 if (unordered_code == UNORDERED_EXPR) 8853 { 8854 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))) 8855 return omit_two_operands (type, integer_zero_node, arg0, arg1); 8856 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1); 8857 } 8858 8859 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code 8860 : ordered_code; 8861 return fold_build1 (TRUTH_NOT_EXPR, type, 8862 fold_build2 (code, type, arg0, arg1)); 8863} 8864 8865/* Used by constant folding to simplify calls to builtin functions. EXP is 8866 the CALL_EXPR of a call to a builtin function. IGNORE is true if the 8867 result of the function call is ignored. This function returns NULL_TREE 8868 if no simplification was possible. */ 8869 8870static tree 8871fold_builtin_1 (tree fndecl, tree arglist, bool ignore) 8872{ 8873 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8874 enum built_in_function fcode; 8875 8876 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 8877 return targetm.fold_builtin (fndecl, arglist, ignore); 8878 8879 fcode = DECL_FUNCTION_CODE (fndecl); 8880 switch (fcode) 8881 { 8882 case BUILT_IN_FPUTS: 8883 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE); 8884 8885 case BUILT_IN_FPUTS_UNLOCKED: 8886 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE); 8887 8888 case BUILT_IN_STRSTR: 8889 return fold_builtin_strstr (arglist, type); 8890 8891 case BUILT_IN_STRCAT: 8892 return fold_builtin_strcat (arglist); 8893 8894 case BUILT_IN_STRNCAT: 8895 return fold_builtin_strncat (arglist); 8896 8897 case BUILT_IN_STRSPN: 8898 return fold_builtin_strspn (arglist); 8899 8900 case BUILT_IN_STRCSPN: 8901 return fold_builtin_strcspn (arglist); 8902 8903 case BUILT_IN_STRCHR: 8904 case BUILT_IN_INDEX: 8905 return fold_builtin_strchr (arglist, type); 8906 8907 case BUILT_IN_STRRCHR: 8908 case BUILT_IN_RINDEX: 8909 return fold_builtin_strrchr (arglist, type); 8910 8911 case BUILT_IN_STRCPY: 8912 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE); 8913 8914 case BUILT_IN_STRNCPY: 8915 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE); 8916 8917 case BUILT_IN_STRCMP: 8918 return fold_builtin_strcmp (arglist); 8919 8920 case BUILT_IN_STRNCMP: 8921 return fold_builtin_strncmp (arglist); 8922 8923 case BUILT_IN_STRPBRK: 8924 return fold_builtin_strpbrk (arglist, type); 8925 8926 case BUILT_IN_BCMP: 8927 case BUILT_IN_MEMCMP: 8928 return fold_builtin_memcmp (arglist); 8929 8930 case BUILT_IN_SPRINTF: 8931 return fold_builtin_sprintf (arglist, ignore); 8932 8933 case BUILT_IN_CONSTANT_P: 8934 { 8935 tree val; 8936 8937 val = fold_builtin_constant_p (arglist); 8938 /* Gimplification will pull the CALL_EXPR for the builtin out of 8939 an if condition. When not optimizing, we'll not CSE it back. 8940 To avoid link error types of regressions, return false now. */ 8941 if (!val && !optimize) 8942 val = integer_zero_node; 8943 8944 return val; 8945 } 8946 8947 case BUILT_IN_EXPECT: 8948 return fold_builtin_expect (arglist); 8949 8950 case BUILT_IN_CLASSIFY_TYPE: 8951 return fold_builtin_classify_type (arglist); 8952 8953 case BUILT_IN_STRLEN: 8954 return fold_builtin_strlen (arglist); 8955 8956 CASE_FLT_FN (BUILT_IN_FABS): 8957 return fold_builtin_fabs (arglist, type); 8958 8959 case BUILT_IN_ABS: 8960 case BUILT_IN_LABS: 8961 case BUILT_IN_LLABS: 8962 case BUILT_IN_IMAXABS: 8963 return fold_builtin_abs (arglist, type); 8964 8965 CASE_FLT_FN (BUILT_IN_CONJ): 8966 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE)) 8967 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist)); 8968 break; 8969 8970 CASE_FLT_FN (BUILT_IN_CREAL): 8971 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE)) 8972 return non_lvalue (fold_build1 (REALPART_EXPR, type, 8973 TREE_VALUE (arglist))); 8974 break; 8975 8976 CASE_FLT_FN (BUILT_IN_CIMAG): 8977 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE)) 8978 return non_lvalue (fold_build1 (IMAGPART_EXPR, type, 8979 TREE_VALUE (arglist))); 8980 break; 8981 8982 CASE_FLT_FN (BUILT_IN_CABS): 8983 return fold_builtin_cabs (arglist, type, fndecl); 8984 8985 CASE_FLT_FN (BUILT_IN_SQRT): 8986 return fold_builtin_sqrt (arglist, type); 8987 8988 CASE_FLT_FN (BUILT_IN_CBRT): 8989 return fold_builtin_cbrt (arglist, type); 8990 8991 CASE_FLT_FN (BUILT_IN_SIN): 8992 return fold_builtin_sin (arglist); 8993 8994 CASE_FLT_FN (BUILT_IN_COS): 8995 return fold_builtin_cos (arglist, type, fndecl); 8996 8997 CASE_FLT_FN (BUILT_IN_EXP): 8998 return fold_builtin_exponent (fndecl, arglist, &dconste); 8999 9000 CASE_FLT_FN (BUILT_IN_EXP2): 9001 return fold_builtin_exponent (fndecl, arglist, &dconst2); 9002 9003 CASE_FLT_FN (BUILT_IN_EXP10): 9004 CASE_FLT_FN (BUILT_IN_POW10): 9005 return fold_builtin_exponent (fndecl, arglist, &dconst10); 9006 9007 CASE_FLT_FN (BUILT_IN_LOG): 9008 return fold_builtin_logarithm (fndecl, arglist, &dconste); 9009 9010 CASE_FLT_FN (BUILT_IN_LOG2): 9011 return fold_builtin_logarithm (fndecl, arglist, &dconst2); 9012 9013 CASE_FLT_FN (BUILT_IN_LOG10): 9014 return fold_builtin_logarithm (fndecl, arglist, &dconst10); 9015 9016 CASE_FLT_FN (BUILT_IN_TAN): 9017 return fold_builtin_tan (arglist); 9018 9019 CASE_FLT_FN (BUILT_IN_ATAN): 9020 return fold_builtin_atan (arglist, type); 9021 9022 CASE_FLT_FN (BUILT_IN_POW): 9023 return fold_builtin_pow (fndecl, arglist, type); 9024 9025 CASE_FLT_FN (BUILT_IN_POWI): 9026 return fold_builtin_powi (fndecl, arglist, type); 9027 9028 CASE_FLT_FN (BUILT_IN_INF): 9029 case BUILT_IN_INFD32: 9030 case BUILT_IN_INFD64: 9031 case BUILT_IN_INFD128: 9032 return fold_builtin_inf (type, true); 9033 9034 CASE_FLT_FN (BUILT_IN_HUGE_VAL): 9035 return fold_builtin_inf (type, false); 9036 9037 CASE_FLT_FN (BUILT_IN_NAN): 9038 case BUILT_IN_NAND32: 9039 case BUILT_IN_NAND64: 9040 case BUILT_IN_NAND128: 9041 return fold_builtin_nan (arglist, type, true); 9042 9043 CASE_FLT_FN (BUILT_IN_NANS): 9044 return fold_builtin_nan (arglist, type, false); 9045 9046 CASE_FLT_FN (BUILT_IN_FLOOR): 9047 return fold_builtin_floor (fndecl, arglist); 9048 9049 CASE_FLT_FN (BUILT_IN_CEIL): 9050 return fold_builtin_ceil (fndecl, arglist); 9051 9052 CASE_FLT_FN (BUILT_IN_TRUNC): 9053 return fold_builtin_trunc (fndecl, arglist); 9054 9055 CASE_FLT_FN (BUILT_IN_ROUND): 9056 return fold_builtin_round (fndecl, arglist); 9057 9058 CASE_FLT_FN (BUILT_IN_NEARBYINT): 9059 CASE_FLT_FN (BUILT_IN_RINT): 9060 return fold_trunc_transparent_mathfn (fndecl, arglist); 9061 9062 CASE_FLT_FN (BUILT_IN_LCEIL): 9063 CASE_FLT_FN (BUILT_IN_LLCEIL): 9064 CASE_FLT_FN (BUILT_IN_LFLOOR): 9065 CASE_FLT_FN (BUILT_IN_LLFLOOR): 9066 CASE_FLT_FN (BUILT_IN_LROUND): 9067 CASE_FLT_FN (BUILT_IN_LLROUND): 9068 return fold_builtin_int_roundingfn (fndecl, arglist); 9069 9070 CASE_FLT_FN (BUILT_IN_LRINT): 9071 CASE_FLT_FN (BUILT_IN_LLRINT): 9072 return fold_fixed_mathfn (fndecl, arglist); 9073 9074 CASE_INT_FN (BUILT_IN_FFS): 9075 CASE_INT_FN (BUILT_IN_CLZ): 9076 CASE_INT_FN (BUILT_IN_CTZ): 9077 CASE_INT_FN (BUILT_IN_POPCOUNT): 9078 CASE_INT_FN (BUILT_IN_PARITY): 9079 return fold_builtin_bitop (fndecl, arglist); 9080 9081 case BUILT_IN_MEMSET: 9082 return fold_builtin_memset (arglist, type, ignore); 9083 9084 case BUILT_IN_MEMCPY: 9085 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0); 9086 9087 case BUILT_IN_MEMPCPY: 9088 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1); 9089 9090 case BUILT_IN_MEMMOVE: 9091 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3); 9092 9093 case BUILT_IN_BZERO: 9094 return fold_builtin_bzero (arglist, ignore); 9095 9096 case BUILT_IN_BCOPY: 9097 return fold_builtin_bcopy (arglist, ignore); 9098 9099 CASE_FLT_FN (BUILT_IN_SIGNBIT): 9100 return fold_builtin_signbit (fndecl, arglist); 9101 9102 case BUILT_IN_ISASCII: 9103 return fold_builtin_isascii (arglist); 9104 9105 case BUILT_IN_TOASCII: 9106 return fold_builtin_toascii (arglist); 9107 9108 case BUILT_IN_ISDIGIT: 9109 return fold_builtin_isdigit (arglist); 9110 9111 CASE_FLT_FN (BUILT_IN_COPYSIGN): 9112 return fold_builtin_copysign (fndecl, arglist, type); 9113 9114 CASE_FLT_FN (BUILT_IN_FINITE): 9115 case BUILT_IN_FINITED32: 9116 case BUILT_IN_FINITED64: 9117 case BUILT_IN_FINITED128: 9118 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE); 9119 9120 CASE_FLT_FN (BUILT_IN_ISINF): 9121 case BUILT_IN_ISINFD32: 9122 case BUILT_IN_ISINFD64: 9123 case BUILT_IN_ISINFD128: 9124 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF); 9125 9126 CASE_FLT_FN (BUILT_IN_ISNAN): 9127 case BUILT_IN_ISNAND32: 9128 case BUILT_IN_ISNAND64: 9129 case BUILT_IN_ISNAND128: 9130 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN); 9131 9132 case BUILT_IN_ISGREATER: 9133 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR); 9134 case BUILT_IN_ISGREATEREQUAL: 9135 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR); 9136 case BUILT_IN_ISLESS: 9137 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR); 9138 case BUILT_IN_ISLESSEQUAL: 9139 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR); 9140 case BUILT_IN_ISLESSGREATER: 9141 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR); 9142 case BUILT_IN_ISUNORDERED: 9143 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR, 9144 NOP_EXPR); 9145 9146 /* We do the folding for va_start in the expander. */ 9147 case BUILT_IN_VA_START: 9148 break; 9149 9150 case BUILT_IN_OBJECT_SIZE: 9151 return fold_builtin_object_size (arglist); 9152 case BUILT_IN_MEMCPY_CHK: 9153 case BUILT_IN_MEMPCPY_CHK: 9154 case BUILT_IN_MEMMOVE_CHK: 9155 case BUILT_IN_MEMSET_CHK: 9156 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore, 9157 DECL_FUNCTION_CODE (fndecl)); 9158 case BUILT_IN_STRCPY_CHK: 9159 case BUILT_IN_STPCPY_CHK: 9160 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore, 9161 DECL_FUNCTION_CODE (fndecl)); 9162 case BUILT_IN_STRNCPY_CHK: 9163 return fold_builtin_strncpy_chk (arglist, NULL_TREE); 9164 case BUILT_IN_STRCAT_CHK: 9165 return fold_builtin_strcat_chk (fndecl, arglist); 9166 case BUILT_IN_STRNCAT_CHK: 9167 return fold_builtin_strncat_chk (fndecl, arglist); 9168 case BUILT_IN_SPRINTF_CHK: 9169 case BUILT_IN_VSPRINTF_CHK: 9170 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl)); 9171 case BUILT_IN_SNPRINTF_CHK: 9172 case BUILT_IN_VSNPRINTF_CHK: 9173 return fold_builtin_snprintf_chk (arglist, NULL_TREE, 9174 DECL_FUNCTION_CODE (fndecl)); 9175 9176 case BUILT_IN_PRINTF: 9177 case BUILT_IN_PRINTF_UNLOCKED: 9178 case BUILT_IN_VPRINTF: 9179 case BUILT_IN_PRINTF_CHK: 9180 case BUILT_IN_VPRINTF_CHK: 9181 return fold_builtin_printf (fndecl, arglist, ignore, 9182 DECL_FUNCTION_CODE (fndecl)); 9183 9184 case BUILT_IN_FPRINTF: 9185 case BUILT_IN_FPRINTF_UNLOCKED: 9186 case BUILT_IN_VFPRINTF: 9187 case BUILT_IN_FPRINTF_CHK: 9188 case BUILT_IN_VFPRINTF_CHK: 9189 return fold_builtin_fprintf (fndecl, arglist, ignore, 9190 DECL_FUNCTION_CODE (fndecl)); 9191 9192 default: 9193 break; 9194 } 9195 9196 return 0; 9197} 9198 9199/* A wrapper function for builtin folding that prevents warnings for 9200 "statement without effect" and the like, caused by removing the 9201 call node earlier than the warning is generated. */ 9202 9203tree 9204fold_builtin (tree fndecl, tree arglist, bool ignore) 9205{ 9206 tree exp = fold_builtin_1 (fndecl, arglist, ignore); 9207 if (exp) 9208 { 9209 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp); 9210 TREE_NO_WARNING (exp) = 1; 9211 } 9212 9213 return exp; 9214} 9215 9216/* Conveniently construct a function call expression. */ 9217 9218tree 9219build_function_call_expr (tree fn, tree arglist) 9220{ 9221 tree call_expr; 9222 9223 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); 9224 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)), 9225 call_expr, arglist, NULL_TREE); 9226} 9227 9228/* This function validates the types of a function call argument list 9229 represented as a tree chain of parameters against a specified list 9230 of tree_codes. If the last specifier is a 0, that represents an 9231 ellipses, otherwise the last specifier must be a VOID_TYPE. */ 9232 9233static int 9234validate_arglist (tree arglist, ...) 9235{ 9236 enum tree_code code; 9237 int res = 0; 9238 va_list ap; 9239 9240 va_start (ap, arglist); 9241 9242 do 9243 { 9244 code = va_arg (ap, enum tree_code); 9245 switch (code) 9246 { 9247 case 0: 9248 /* This signifies an ellipses, any further arguments are all ok. */ 9249 res = 1; 9250 goto end; 9251 case VOID_TYPE: 9252 /* This signifies an endlink, if no arguments remain, return 9253 true, otherwise return false. */ 9254 res = arglist == 0; 9255 goto end; 9256 default: 9257 /* If no parameters remain or the parameter's code does not 9258 match the specified code, return false. Otherwise continue 9259 checking any remaining arguments. */ 9260 if (arglist == 0) 9261 goto end; 9262 if (code == POINTER_TYPE) 9263 { 9264 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))) 9265 goto end; 9266 } 9267 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist)))) 9268 goto end; 9269 break; 9270 } 9271 arglist = TREE_CHAIN (arglist); 9272 } 9273 while (1); 9274 9275 /* We need gotos here since we can only have one VA_CLOSE in a 9276 function. */ 9277 end: ; 9278 va_end (ap); 9279 9280 return res; 9281} 9282 9283/* Default target-specific builtin expander that does nothing. */ 9284 9285rtx 9286default_expand_builtin (tree exp ATTRIBUTE_UNUSED, 9287 rtx target ATTRIBUTE_UNUSED, 9288 rtx subtarget ATTRIBUTE_UNUSED, 9289 enum machine_mode mode ATTRIBUTE_UNUSED, 9290 int ignore ATTRIBUTE_UNUSED) 9291{ 9292 return NULL_RTX; 9293} 9294 9295/* Returns true is EXP represents data that would potentially reside 9296 in a readonly section. */ 9297 9298static bool 9299readonly_data_expr (tree exp) 9300{ 9301 STRIP_NOPS (exp); 9302 9303 if (TREE_CODE (exp) != ADDR_EXPR) 9304 return false; 9305 9306 exp = get_base_address (TREE_OPERAND (exp, 0)); 9307 if (!exp) 9308 return false; 9309 9310 /* Make sure we call decl_readonly_section only for trees it 9311 can handle (since it returns true for everything it doesn't 9312 understand). */ 9313 if (TREE_CODE (exp) == STRING_CST 9314 || TREE_CODE (exp) == CONSTRUCTOR 9315 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp))) 9316 return decl_readonly_section (exp, 0); 9317 else 9318 return false; 9319} 9320 9321/* Simplify a call to the strstr builtin. 9322 9323 Return 0 if no simplification was possible, otherwise return the 9324 simplified form of the call as a tree. 9325 9326 The simplified form may be a constant or other expression which 9327 computes the same value, but in a more efficient manner (including 9328 calls to other builtin functions). 9329 9330 The call may contain arguments which need to be evaluated, but 9331 which are not useful to determine the result of the call. In 9332 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9333 COMPOUND_EXPR will be an argument which must be evaluated. 9334 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9335 COMPOUND_EXPR in the chain will contain the tree for the simplified 9336 form of the builtin function call. */ 9337 9338static tree 9339fold_builtin_strstr (tree arglist, tree type) 9340{ 9341 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9342 return 0; 9343 else 9344 { 9345 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9346 tree fn; 9347 const char *p1, *p2; 9348 9349 p2 = c_getstr (s2); 9350 if (p2 == NULL) 9351 return 0; 9352 9353 p1 = c_getstr (s1); 9354 if (p1 != NULL) 9355 { 9356 const char *r = strstr (p1, p2); 9357 tree tem; 9358 9359 if (r == NULL) 9360 return build_int_cst (TREE_TYPE (s1), 0); 9361 9362 /* Return an offset into the constant string argument. */ 9363 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1), 9364 s1, build_int_cst (TREE_TYPE (s1), r - p1)); 9365 return fold_convert (type, tem); 9366 } 9367 9368 /* The argument is const char *, and the result is char *, so we need 9369 a type conversion here to avoid a warning. */ 9370 if (p2[0] == '\0') 9371 return fold_convert (type, s1); 9372 9373 if (p2[1] != '\0') 9374 return 0; 9375 9376 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 9377 if (!fn) 9378 return 0; 9379 9380 /* New argument list transforming strstr(s1, s2) to 9381 strchr(s1, s2[0]). */ 9382 arglist = build_tree_list (NULL_TREE, 9383 build_int_cst (NULL_TREE, p2[0])); 9384 arglist = tree_cons (NULL_TREE, s1, arglist); 9385 return build_function_call_expr (fn, arglist); 9386 } 9387} 9388 9389/* Simplify a call to the strchr builtin. 9390 9391 Return 0 if no simplification was possible, otherwise return the 9392 simplified form of the call as a tree. 9393 9394 The simplified form may be a constant or other expression which 9395 computes the same value, but in a more efficient manner (including 9396 calls to other builtin functions). 9397 9398 The call may contain arguments which need to be evaluated, but 9399 which are not useful to determine the result of the call. In 9400 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9401 COMPOUND_EXPR will be an argument which must be evaluated. 9402 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9403 COMPOUND_EXPR in the chain will contain the tree for the simplified 9404 form of the builtin function call. */ 9405 9406static tree 9407fold_builtin_strchr (tree arglist, tree type) 9408{ 9409 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 9410 return 0; 9411 else 9412 { 9413 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9414 const char *p1; 9415 9416 if (TREE_CODE (s2) != INTEGER_CST) 9417 return 0; 9418 9419 p1 = c_getstr (s1); 9420 if (p1 != NULL) 9421 { 9422 char c; 9423 const char *r; 9424 tree tem; 9425 9426 if (target_char_cast (s2, &c)) 9427 return 0; 9428 9429 r = strchr (p1, c); 9430 9431 if (r == NULL) 9432 return build_int_cst (TREE_TYPE (s1), 0); 9433 9434 /* Return an offset into the constant string argument. */ 9435 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1), 9436 s1, build_int_cst (TREE_TYPE (s1), r - p1)); 9437 return fold_convert (type, tem); 9438 } 9439 return 0; 9440 } 9441} 9442 9443/* Simplify a call to the strrchr builtin. 9444 9445 Return 0 if no simplification was possible, otherwise return the 9446 simplified form of the call as a tree. 9447 9448 The simplified form may be a constant or other expression which 9449 computes the same value, but in a more efficient manner (including 9450 calls to other builtin functions). 9451 9452 The call may contain arguments which need to be evaluated, but 9453 which are not useful to determine the result of the call. In 9454 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9455 COMPOUND_EXPR will be an argument which must be evaluated. 9456 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9457 COMPOUND_EXPR in the chain will contain the tree for the simplified 9458 form of the builtin function call. */ 9459 9460static tree 9461fold_builtin_strrchr (tree arglist, tree type) 9462{ 9463 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 9464 return 0; 9465 else 9466 { 9467 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9468 tree fn; 9469 const char *p1; 9470 9471 if (TREE_CODE (s2) != INTEGER_CST) 9472 return 0; 9473 9474 p1 = c_getstr (s1); 9475 if (p1 != NULL) 9476 { 9477 char c; 9478 const char *r; 9479 tree tem; 9480 9481 if (target_char_cast (s2, &c)) 9482 return 0; 9483 9484 r = strrchr (p1, c); 9485 9486 if (r == NULL) 9487 return build_int_cst (TREE_TYPE (s1), 0); 9488 9489 /* Return an offset into the constant string argument. */ 9490 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1), 9491 s1, build_int_cst (TREE_TYPE (s1), r - p1)); 9492 return fold_convert (type, tem); 9493 } 9494 9495 if (! integer_zerop (s2)) 9496 return 0; 9497 9498 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 9499 if (!fn) 9500 return 0; 9501 9502 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */ 9503 return build_function_call_expr (fn, arglist); 9504 } 9505} 9506 9507/* Simplify a call to the strpbrk builtin. 9508 9509 Return 0 if no simplification was possible, otherwise return the 9510 simplified form of the call as a tree. 9511 9512 The simplified form may be a constant or other expression which 9513 computes the same value, but in a more efficient manner (including 9514 calls to other builtin functions). 9515 9516 The call may contain arguments which need to be evaluated, but 9517 which are not useful to determine the result of the call. In 9518 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9519 COMPOUND_EXPR will be an argument which must be evaluated. 9520 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9521 COMPOUND_EXPR in the chain will contain the tree for the simplified 9522 form of the builtin function call. */ 9523 9524static tree 9525fold_builtin_strpbrk (tree arglist, tree type) 9526{ 9527 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9528 return 0; 9529 else 9530 { 9531 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9532 tree fn; 9533 const char *p1, *p2; 9534 9535 p2 = c_getstr (s2); 9536 if (p2 == NULL) 9537 return 0; 9538 9539 p1 = c_getstr (s1); 9540 if (p1 != NULL) 9541 { 9542 const char *r = strpbrk (p1, p2); 9543 tree tem; 9544 9545 if (r == NULL) 9546 return build_int_cst (TREE_TYPE (s1), 0); 9547 9548 /* Return an offset into the constant string argument. */ 9549 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1), 9550 s1, build_int_cst (TREE_TYPE (s1), r - p1)); 9551 return fold_convert (type, tem); 9552 } 9553 9554 if (p2[0] == '\0') 9555 /* strpbrk(x, "") == NULL. 9556 Evaluate and ignore s1 in case it had side-effects. */ 9557 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1); 9558 9559 if (p2[1] != '\0') 9560 return 0; /* Really call strpbrk. */ 9561 9562 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 9563 if (!fn) 9564 return 0; 9565 9566 /* New argument list transforming strpbrk(s1, s2) to 9567 strchr(s1, s2[0]). */ 9568 arglist = build_tree_list (NULL_TREE, 9569 build_int_cst (NULL_TREE, p2[0])); 9570 arglist = tree_cons (NULL_TREE, s1, arglist); 9571 return build_function_call_expr (fn, arglist); 9572 } 9573} 9574 9575/* Simplify a call to the strcat builtin. 9576 9577 Return 0 if no simplification was possible, otherwise return the 9578 simplified form of the call as a tree. 9579 9580 The simplified form may be a constant or other expression which 9581 computes the same value, but in a more efficient manner (including 9582 calls to other builtin functions). 9583 9584 The call may contain arguments which need to be evaluated, but 9585 which are not useful to determine the result of the call. In 9586 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9587 COMPOUND_EXPR will be an argument which must be evaluated. 9588 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9589 COMPOUND_EXPR in the chain will contain the tree for the simplified 9590 form of the builtin function call. */ 9591 9592static tree 9593fold_builtin_strcat (tree arglist) 9594{ 9595 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9596 return 0; 9597 else 9598 { 9599 tree dst = TREE_VALUE (arglist), 9600 src = TREE_VALUE (TREE_CHAIN (arglist)); 9601 const char *p = c_getstr (src); 9602 9603 /* If the string length is zero, return the dst parameter. */ 9604 if (p && *p == '\0') 9605 return dst; 9606 9607 return 0; 9608 } 9609} 9610 9611/* Simplify a call to the strncat builtin. 9612 9613 Return 0 if no simplification was possible, otherwise return the 9614 simplified form of the call as a tree. 9615 9616 The simplified form may be a constant or other expression which 9617 computes the same value, but in a more efficient manner (including 9618 calls to other builtin functions). 9619 9620 The call may contain arguments which need to be evaluated, but 9621 which are not useful to determine the result of the call. In 9622 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9623 COMPOUND_EXPR will be an argument which must be evaluated. 9624 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9625 COMPOUND_EXPR in the chain will contain the tree for the simplified 9626 form of the builtin function call. */ 9627 9628static tree 9629fold_builtin_strncat (tree arglist) 9630{ 9631 if (!validate_arglist (arglist, 9632 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 9633 return 0; 9634 else 9635 { 9636 tree dst = TREE_VALUE (arglist); 9637 tree src = TREE_VALUE (TREE_CHAIN (arglist)); 9638 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 9639 const char *p = c_getstr (src); 9640 9641 /* If the requested length is zero, or the src parameter string 9642 length is zero, return the dst parameter. */ 9643 if (integer_zerop (len) || (p && *p == '\0')) 9644 return omit_two_operands (TREE_TYPE (dst), dst, src, len); 9645 9646 /* If the requested len is greater than or equal to the string 9647 length, call strcat. */ 9648 if (TREE_CODE (len) == INTEGER_CST && p 9649 && compare_tree_int (len, strlen (p)) >= 0) 9650 { 9651 tree newarglist 9652 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src)); 9653 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT]; 9654 9655 /* If the replacement _DECL isn't initialized, don't do the 9656 transformation. */ 9657 if (!fn) 9658 return 0; 9659 9660 return build_function_call_expr (fn, newarglist); 9661 } 9662 return 0; 9663 } 9664} 9665 9666/* Simplify a call to the strspn builtin. 9667 9668 Return 0 if no simplification was possible, otherwise return the 9669 simplified form of the call as a tree. 9670 9671 The simplified form may be a constant or other expression which 9672 computes the same value, but in a more efficient manner (including 9673 calls to other builtin functions). 9674 9675 The call may contain arguments which need to be evaluated, but 9676 which are not useful to determine the result of the call. In 9677 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9678 COMPOUND_EXPR will be an argument which must be evaluated. 9679 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9680 COMPOUND_EXPR in the chain will contain the tree for the simplified 9681 form of the builtin function call. */ 9682 9683static tree 9684fold_builtin_strspn (tree arglist) 9685{ 9686 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9687 return 0; 9688 else 9689 { 9690 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9691 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); 9692 9693 /* If both arguments are constants, evaluate at compile-time. */ 9694 if (p1 && p2) 9695 { 9696 const size_t r = strspn (p1, p2); 9697 return size_int (r); 9698 } 9699 9700 /* If either argument is "", return 0. */ 9701 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')) 9702 /* Evaluate and ignore both arguments in case either one has 9703 side-effects. */ 9704 return omit_two_operands (integer_type_node, integer_zero_node, 9705 s1, s2); 9706 return 0; 9707 } 9708} 9709 9710/* Simplify a call to the strcspn builtin. 9711 9712 Return 0 if no simplification was possible, otherwise return the 9713 simplified form of the call as a tree. 9714 9715 The simplified form may be a constant or other expression which 9716 computes the same value, but in a more efficient manner (including 9717 calls to other builtin functions). 9718 9719 The call may contain arguments which need to be evaluated, but 9720 which are not useful to determine the result of the call. In 9721 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9722 COMPOUND_EXPR will be an argument which must be evaluated. 9723 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9724 COMPOUND_EXPR in the chain will contain the tree for the simplified 9725 form of the builtin function call. */ 9726 9727static tree 9728fold_builtin_strcspn (tree arglist) 9729{ 9730 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9731 return 0; 9732 else 9733 { 9734 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9735 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); 9736 9737 /* If both arguments are constants, evaluate at compile-time. */ 9738 if (p1 && p2) 9739 { 9740 const size_t r = strcspn (p1, p2); 9741 return size_int (r); 9742 } 9743 9744 /* If the first argument is "", return 0. */ 9745 if (p1 && *p1 == '\0') 9746 { 9747 /* Evaluate and ignore argument s2 in case it has 9748 side-effects. */ 9749 return omit_one_operand (integer_type_node, 9750 integer_zero_node, s2); 9751 } 9752 9753 /* If the second argument is "", return __builtin_strlen(s1). */ 9754 if (p2 && *p2 == '\0') 9755 { 9756 tree newarglist = build_tree_list (NULL_TREE, s1), 9757 fn = implicit_built_in_decls[BUILT_IN_STRLEN]; 9758 9759 /* If the replacement _DECL isn't initialized, don't do the 9760 transformation. */ 9761 if (!fn) 9762 return 0; 9763 9764 return build_function_call_expr (fn, newarglist); 9765 } 9766 return 0; 9767 } 9768} 9769 9770/* Fold a call to the fputs builtin. IGNORE is true if the value returned 9771 by the builtin will be ignored. UNLOCKED is true is true if this 9772 actually a call to fputs_unlocked. If LEN in non-NULL, it represents 9773 the known length of the string. Return NULL_TREE if no simplification 9774 was possible. */ 9775 9776tree 9777fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len) 9778{ 9779 tree fn; 9780 /* If we're using an unlocked function, assume the other unlocked 9781 functions exist explicitly. */ 9782 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED] 9783 : implicit_built_in_decls[BUILT_IN_FPUTC]; 9784 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED] 9785 : implicit_built_in_decls[BUILT_IN_FWRITE]; 9786 9787 /* If the return value is used, don't do the transformation. */ 9788 if (!ignore) 9789 return 0; 9790 9791 /* Verify the arguments in the original call. */ 9792 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9793 return 0; 9794 9795 if (! len) 9796 len = c_strlen (TREE_VALUE (arglist), 0); 9797 9798 /* Get the length of the string passed to fputs. If the length 9799 can't be determined, punt. */ 9800 if (!len 9801 || TREE_CODE (len) != INTEGER_CST) 9802 return 0; 9803 9804 switch (compare_tree_int (len, 1)) 9805 { 9806 case -1: /* length is 0, delete the call entirely . */ 9807 return omit_one_operand (integer_type_node, integer_zero_node, 9808 TREE_VALUE (TREE_CHAIN (arglist))); 9809 9810 case 0: /* length is 1, call fputc. */ 9811 { 9812 const char *p = c_getstr (TREE_VALUE (arglist)); 9813 9814 if (p != NULL) 9815 { 9816 /* New argument list transforming fputs(string, stream) to 9817 fputc(string[0], stream). */ 9818 arglist = build_tree_list (NULL_TREE, 9819 TREE_VALUE (TREE_CHAIN (arglist))); 9820 arglist = tree_cons (NULL_TREE, 9821 build_int_cst (NULL_TREE, p[0]), 9822 arglist); 9823 fn = fn_fputc; 9824 break; 9825 } 9826 } 9827 /* FALLTHROUGH */ 9828 case 1: /* length is greater than 1, call fwrite. */ 9829 { 9830 tree string_arg; 9831 9832 /* If optimizing for size keep fputs. */ 9833 if (optimize_size) 9834 return 0; 9835 string_arg = TREE_VALUE (arglist); 9836 /* New argument list transforming fputs(string, stream) to 9837 fwrite(string, 1, len, stream). */ 9838 arglist = build_tree_list (NULL_TREE, 9839 TREE_VALUE (TREE_CHAIN (arglist))); 9840 arglist = tree_cons (NULL_TREE, len, arglist); 9841 arglist = tree_cons (NULL_TREE, size_one_node, arglist); 9842 arglist = tree_cons (NULL_TREE, string_arg, arglist); 9843 fn = fn_fwrite; 9844 break; 9845 } 9846 default: 9847 gcc_unreachable (); 9848 } 9849 9850 /* If the replacement _DECL isn't initialized, don't do the 9851 transformation. */ 9852 if (!fn) 9853 return 0; 9854 9855 /* These optimizations are only performed when the result is ignored, 9856 hence there's no need to cast the result to integer_type_node. */ 9857 return build_function_call_expr (fn, arglist); 9858} 9859 9860/* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error 9861 produced. False otherwise. This is done so that we don't output the error 9862 or warning twice or three times. */ 9863bool 9864fold_builtin_next_arg (tree arglist) 9865{ 9866 tree fntype = TREE_TYPE (current_function_decl); 9867 9868 if (TYPE_ARG_TYPES (fntype) == 0 9869 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) 9870 == void_type_node)) 9871 { 9872 error ("%<va_start%> used in function with fixed args"); 9873 return true; 9874 } 9875 else if (!arglist) 9876 { 9877 /* Evidently an out of date version of <stdarg.h>; can't validate 9878 va_start's second argument, but can still work as intended. */ 9879 warning (0, "%<__builtin_next_arg%> called without an argument"); 9880 return true; 9881 } 9882 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0) 9883 when we checked the arguments and if needed issued a warning. */ 9884 else if (!TREE_CHAIN (arglist) 9885 || !integer_zerop (TREE_VALUE (arglist)) 9886 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist))) 9887 || TREE_CHAIN (TREE_CHAIN (arglist))) 9888 { 9889 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl)); 9890 tree arg = TREE_VALUE (arglist); 9891 9892 if (TREE_CHAIN (arglist)) 9893 { 9894 error ("%<va_start%> used with too many arguments"); 9895 return true; 9896 } 9897 9898 /* Strip off all nops for the sake of the comparison. This 9899 is not quite the same as STRIP_NOPS. It does more. 9900 We must also strip off INDIRECT_EXPR for C++ reference 9901 parameters. */ 9902 while (TREE_CODE (arg) == NOP_EXPR 9903 || TREE_CODE (arg) == CONVERT_EXPR 9904 || TREE_CODE (arg) == NON_LVALUE_EXPR 9905 || TREE_CODE (arg) == INDIRECT_REF) 9906 arg = TREE_OPERAND (arg, 0); 9907 if (arg != last_parm) 9908 { 9909 /* FIXME: Sometimes with the tree optimizers we can get the 9910 not the last argument even though the user used the last 9911 argument. We just warn and set the arg to be the last 9912 argument so that we will get wrong-code because of 9913 it. */ 9914 warning (0, "second parameter of %<va_start%> not last named argument"); 9915 } 9916 /* We want to verify the second parameter just once before the tree 9917 optimizers are run and then avoid keeping it in the tree, 9918 as otherwise we could warn even for correct code like: 9919 void foo (int i, ...) 9920 { va_list ap; i++; va_start (ap, i); va_end (ap); } */ 9921 TREE_VALUE (arglist) = integer_zero_node; 9922 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node); 9923 } 9924 return false; 9925} 9926 9927 9928/* Simplify a call to the sprintf builtin. 9929 9930 Return 0 if no simplification was possible, otherwise return the 9931 simplified form of the call as a tree. If IGNORED is true, it means that 9932 the caller does not use the returned value of the function. */ 9933 9934static tree 9935fold_builtin_sprintf (tree arglist, int ignored) 9936{ 9937 tree call, retval, dest, fmt; 9938 const char *fmt_str = NULL; 9939 9940 /* Verify the required arguments in the original call. We deal with two 9941 types of sprintf() calls: 'sprintf (str, fmt)' and 9942 'sprintf (dest, "%s", orig)'. */ 9943 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE) 9944 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE, 9945 VOID_TYPE)) 9946 return NULL_TREE; 9947 9948 /* Get the destination string and the format specifier. */ 9949 dest = TREE_VALUE (arglist); 9950 fmt = TREE_VALUE (TREE_CHAIN (arglist)); 9951 arglist = TREE_CHAIN (TREE_CHAIN (arglist)); 9952 9953 /* Check whether the format is a literal string constant. */ 9954 fmt_str = c_getstr (fmt); 9955 if (fmt_str == NULL) 9956 return NULL_TREE; 9957 9958 call = NULL_TREE; 9959 retval = NULL_TREE; 9960 9961 if (!init_target_chars()) 9962 return 0; 9963 9964 /* If the format doesn't contain % args or %%, use strcpy. */ 9965 if (strchr (fmt_str, target_percent) == NULL) 9966 { 9967 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 9968 9969 if (!fn) 9970 return NULL_TREE; 9971 9972 /* Don't optimize sprintf (buf, "abc", ptr++). */ 9973 if (arglist) 9974 return NULL_TREE; 9975 9976 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when 9977 'format' is known to contain no % formats. */ 9978 arglist = build_tree_list (NULL_TREE, fmt); 9979 arglist = tree_cons (NULL_TREE, dest, arglist); 9980 call = build_function_call_expr (fn, arglist); 9981 if (!ignored) 9982 retval = build_int_cst (NULL_TREE, strlen (fmt_str)); 9983 } 9984 9985 /* If the format is "%s", use strcpy if the result isn't used. */ 9986 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0) 9987 { 9988 tree fn, orig; 9989 fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 9990 9991 if (!fn) 9992 return NULL_TREE; 9993 9994 /* Don't crash on sprintf (str1, "%s"). */ 9995 if (!arglist) 9996 return NULL_TREE; 9997 9998 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */ 9999 orig = TREE_VALUE (arglist); 10000 arglist = build_tree_list (NULL_TREE, orig); 10001 arglist = tree_cons (NULL_TREE, dest, arglist); 10002 if (!ignored) 10003 { 10004 retval = c_strlen (orig, 1); 10005 if (!retval || TREE_CODE (retval) != INTEGER_CST) 10006 return NULL_TREE; 10007 } 10008 call = build_function_call_expr (fn, arglist); 10009 } 10010 10011 if (call && retval) 10012 { 10013 retval = fold_convert 10014 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])), 10015 retval); 10016 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval); 10017 } 10018 else 10019 return call; 10020} 10021 10022/* Expand a call to __builtin_object_size. */ 10023 10024rtx 10025expand_builtin_object_size (tree exp) 10026{ 10027 tree ost; 10028 int object_size_type; 10029 tree fndecl = get_callee_fndecl (exp); 10030 tree arglist = TREE_OPERAND (exp, 1); 10031 location_t locus = EXPR_LOCATION (exp); 10032 10033 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 10034 { 10035 error ("%Hfirst argument of %D must be a pointer, second integer constant", 10036 &locus, fndecl); 10037 expand_builtin_trap (); 10038 return const0_rtx; 10039 } 10040 10041 ost = TREE_VALUE (TREE_CHAIN (arglist)); 10042 STRIP_NOPS (ost); 10043 10044 if (TREE_CODE (ost) != INTEGER_CST 10045 || tree_int_cst_sgn (ost) < 0 10046 || compare_tree_int (ost, 3) > 0) 10047 { 10048 error ("%Hlast argument of %D is not integer constant between 0 and 3", 10049 &locus, fndecl); 10050 expand_builtin_trap (); 10051 return const0_rtx; 10052 } 10053 10054 object_size_type = tree_low_cst (ost, 0); 10055 10056 return object_size_type < 2 ? constm1_rtx : const0_rtx; 10057} 10058 10059/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin. 10060 FCODE is the BUILT_IN_* to use. 10061 Return 0 if we failed; the caller should emit a normal call, 10062 otherwise try to get the result in TARGET, if convenient (and in 10063 mode MODE if that's convenient). */ 10064 10065static rtx 10066expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode, 10067 enum built_in_function fcode) 10068{ 10069 tree arglist = TREE_OPERAND (exp, 1); 10070 tree dest, src, len, size; 10071 10072 if (!validate_arglist (arglist, 10073 POINTER_TYPE, 10074 fcode == BUILT_IN_MEMSET_CHK 10075 ? INTEGER_TYPE : POINTER_TYPE, 10076 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 10077 return 0; 10078 10079 dest = TREE_VALUE (arglist); 10080 src = TREE_VALUE (TREE_CHAIN (arglist)); 10081 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10082 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))); 10083 10084 if (! host_integerp (size, 1)) 10085 return 0; 10086 10087 if (host_integerp (len, 1) || integer_all_onesp (size)) 10088 { 10089 tree fn; 10090 10091 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len)) 10092 { 10093 location_t locus = EXPR_LOCATION (exp); 10094 warning (0, "%Hcall to %D will always overflow destination buffer", 10095 &locus, get_callee_fndecl (exp)); 10096 return 0; 10097 } 10098 10099 arglist = build_tree_list (NULL_TREE, len); 10100 arglist = tree_cons (NULL_TREE, src, arglist); 10101 arglist = tree_cons (NULL_TREE, dest, arglist); 10102 10103 fn = NULL_TREE; 10104 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume 10105 mem{cpy,pcpy,move,set} is available. */ 10106 switch (fcode) 10107 { 10108 case BUILT_IN_MEMCPY_CHK: 10109 fn = built_in_decls[BUILT_IN_MEMCPY]; 10110 break; 10111 case BUILT_IN_MEMPCPY_CHK: 10112 fn = built_in_decls[BUILT_IN_MEMPCPY]; 10113 break; 10114 case BUILT_IN_MEMMOVE_CHK: 10115 fn = built_in_decls[BUILT_IN_MEMMOVE]; 10116 break; 10117 case BUILT_IN_MEMSET_CHK: 10118 fn = built_in_decls[BUILT_IN_MEMSET]; 10119 break; 10120 default: 10121 break; 10122 } 10123 10124 if (! fn) 10125 return 0; 10126 10127 fn = build_function_call_expr (fn, arglist); 10128 if (TREE_CODE (fn) == CALL_EXPR) 10129 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 10130 return expand_expr (fn, target, mode, EXPAND_NORMAL); 10131 } 10132 else if (fcode == BUILT_IN_MEMSET_CHK) 10133 return 0; 10134 else 10135 { 10136 unsigned int dest_align 10137 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 10138 10139 /* If DEST is not a pointer type, call the normal function. */ 10140 if (dest_align == 0) 10141 return 0; 10142 10143 /* If SRC and DEST are the same (and not volatile), do nothing. */ 10144 if (operand_equal_p (src, dest, 0)) 10145 { 10146 tree expr; 10147 10148 if (fcode != BUILT_IN_MEMPCPY_CHK) 10149 { 10150 /* Evaluate and ignore LEN in case it has side-effects. */ 10151 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL); 10152 return expand_expr (dest, target, mode, EXPAND_NORMAL); 10153 } 10154 10155 len = fold_convert (TREE_TYPE (dest), len); 10156 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len); 10157 return expand_expr (expr, target, mode, EXPAND_NORMAL); 10158 } 10159 10160 /* __memmove_chk special case. */ 10161 if (fcode == BUILT_IN_MEMMOVE_CHK) 10162 { 10163 unsigned int src_align 10164 = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 10165 10166 if (src_align == 0) 10167 return 0; 10168 10169 /* If src is categorized for a readonly section we can use 10170 normal __memcpy_chk. */ 10171 if (readonly_data_expr (src)) 10172 { 10173 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK]; 10174 if (!fn) 10175 return 0; 10176 fn = build_function_call_expr (fn, arglist); 10177 if (TREE_CODE (fn) == CALL_EXPR) 10178 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 10179 return expand_expr (fn, target, mode, EXPAND_NORMAL); 10180 } 10181 } 10182 return 0; 10183 } 10184} 10185 10186/* Emit warning if a buffer overflow is detected at compile time. */ 10187 10188static void 10189maybe_emit_chk_warning (tree exp, enum built_in_function fcode) 10190{ 10191 int arg_mask, is_strlen = 0; 10192 tree arglist = TREE_OPERAND (exp, 1), a; 10193 tree len, size; 10194 location_t locus; 10195 10196 switch (fcode) 10197 { 10198 case BUILT_IN_STRCPY_CHK: 10199 case BUILT_IN_STPCPY_CHK: 10200 /* For __strcat_chk the warning will be emitted only if overflowing 10201 by at least strlen (dest) + 1 bytes. */ 10202 case BUILT_IN_STRCAT_CHK: 10203 arg_mask = 6; 10204 is_strlen = 1; 10205 break; 10206 case BUILT_IN_STRNCPY_CHK: 10207 arg_mask = 12; 10208 break; 10209 case BUILT_IN_SNPRINTF_CHK: 10210 case BUILT_IN_VSNPRINTF_CHK: 10211 arg_mask = 10; 10212 break; 10213 default: 10214 gcc_unreachable (); 10215 } 10216 10217 len = NULL_TREE; 10218 size = NULL_TREE; 10219 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1) 10220 if (arg_mask & 1) 10221 { 10222 if (len) 10223 size = a; 10224 else 10225 len = a; 10226 } 10227 10228 if (!len || !size) 10229 return; 10230 10231 len = TREE_VALUE (len); 10232 size = TREE_VALUE (size); 10233 10234 if (! host_integerp (size, 1) || integer_all_onesp (size)) 10235 return; 10236 10237 if (is_strlen) 10238 { 10239 len = c_strlen (len, 1); 10240 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size)) 10241 return; 10242 } 10243 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len)) 10244 return; 10245 10246 locus = EXPR_LOCATION (exp); 10247 warning (0, "%Hcall to %D will always overflow destination buffer", 10248 &locus, get_callee_fndecl (exp)); 10249} 10250 10251/* Emit warning if a buffer overflow is detected at compile time 10252 in __sprintf_chk/__vsprintf_chk calls. */ 10253 10254static void 10255maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode) 10256{ 10257 tree arglist = TREE_OPERAND (exp, 1); 10258 tree dest, size, len, fmt, flag; 10259 const char *fmt_str; 10260 10261 /* Verify the required arguments in the original call. */ 10262 if (! arglist) 10263 return; 10264 dest = TREE_VALUE (arglist); 10265 arglist = TREE_CHAIN (arglist); 10266 if (! arglist) 10267 return; 10268 flag = TREE_VALUE (arglist); 10269 arglist = TREE_CHAIN (arglist); 10270 if (! arglist) 10271 return; 10272 size = TREE_VALUE (arglist); 10273 arglist = TREE_CHAIN (arglist); 10274 if (! arglist) 10275 return; 10276 fmt = TREE_VALUE (arglist); 10277 arglist = TREE_CHAIN (arglist); 10278 10279 if (! host_integerp (size, 1) || integer_all_onesp (size)) 10280 return; 10281 10282 /* Check whether the format is a literal string constant. */ 10283 fmt_str = c_getstr (fmt); 10284 if (fmt_str == NULL) 10285 return; 10286 10287 if (!init_target_chars()) 10288 return; 10289 10290 /* If the format doesn't contain % args or %%, we know its size. */ 10291 if (strchr (fmt_str, target_percent) == 0) 10292 len = build_int_cstu (size_type_node, strlen (fmt_str)); 10293 /* If the format is "%s" and first ... argument is a string literal, 10294 we know it too. */ 10295 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0) 10296 { 10297 tree arg; 10298 10299 if (! arglist) 10300 return; 10301 arg = TREE_VALUE (arglist); 10302 if (! POINTER_TYPE_P (TREE_TYPE (arg))) 10303 return; 10304 10305 len = c_strlen (arg, 1); 10306 if (!len || ! host_integerp (len, 1)) 10307 return; 10308 } 10309 else 10310 return; 10311 10312 if (! tree_int_cst_lt (len, size)) 10313 { 10314 location_t locus = EXPR_LOCATION (exp); 10315 warning (0, "%Hcall to %D will always overflow destination buffer", 10316 &locus, get_callee_fndecl (exp)); 10317 } 10318} 10319 10320/* Fold a call to __builtin_object_size, if possible. */ 10321 10322tree 10323fold_builtin_object_size (tree arglist) 10324{ 10325 tree ptr, ost, ret = 0; 10326 int object_size_type; 10327 10328 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 10329 return 0; 10330 10331 ptr = TREE_VALUE (arglist); 10332 ost = TREE_VALUE (TREE_CHAIN (arglist)); 10333 STRIP_NOPS (ost); 10334 10335 if (TREE_CODE (ost) != INTEGER_CST 10336 || tree_int_cst_sgn (ost) < 0 10337 || compare_tree_int (ost, 3) > 0) 10338 return 0; 10339 10340 object_size_type = tree_low_cst (ost, 0); 10341 10342 /* __builtin_object_size doesn't evaluate side-effects in its arguments; 10343 if there are any side-effects, it returns (size_t) -1 for types 0 and 1 10344 and (size_t) 0 for types 2 and 3. */ 10345 if (TREE_SIDE_EFFECTS (ptr)) 10346 return fold_convert (size_type_node, 10347 object_size_type < 2 10348 ? integer_minus_one_node : integer_zero_node); 10349 10350 if (TREE_CODE (ptr) == ADDR_EXPR) 10351 ret = build_int_cstu (size_type_node, 10352 compute_builtin_object_size (ptr, object_size_type)); 10353 10354 else if (TREE_CODE (ptr) == SSA_NAME) 10355 { 10356 unsigned HOST_WIDE_INT bytes; 10357 10358 /* If object size is not known yet, delay folding until 10359 later. Maybe subsequent passes will help determining 10360 it. */ 10361 bytes = compute_builtin_object_size (ptr, object_size_type); 10362 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 10363 ? -1 : 0)) 10364 ret = build_int_cstu (size_type_node, bytes); 10365 } 10366 10367 if (ret) 10368 { 10369 ret = force_fit_type (ret, -1, false, false); 10370 if (TREE_CONSTANT_OVERFLOW (ret)) 10371 ret = 0; 10372 } 10373 10374 return ret; 10375} 10376 10377/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin. 10378 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_* 10379 code of the builtin. If MAXLEN is not NULL, it is maximum length 10380 passed as third argument. */ 10381 10382tree 10383fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore, 10384 enum built_in_function fcode) 10385{ 10386 tree dest, src, len, size, fn; 10387 10388 if (!validate_arglist (arglist, 10389 POINTER_TYPE, 10390 fcode == BUILT_IN_MEMSET_CHK 10391 ? INTEGER_TYPE : POINTER_TYPE, 10392 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 10393 return 0; 10394 10395 dest = TREE_VALUE (arglist); 10396 /* Actually val for __memset_chk, but it doesn't matter. */ 10397 src = TREE_VALUE (TREE_CHAIN (arglist)); 10398 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10399 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))); 10400 10401 /* If SRC and DEST are the same (and not volatile), return DEST 10402 (resp. DEST+LEN for __mempcpy_chk). */ 10403 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0)) 10404 { 10405 if (fcode != BUILT_IN_MEMPCPY_CHK) 10406 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len); 10407 else 10408 { 10409 tree temp = fold_convert (TREE_TYPE (dest), len); 10410 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp); 10411 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp); 10412 } 10413 } 10414 10415 if (! host_integerp (size, 1)) 10416 return 0; 10417 10418 if (! integer_all_onesp (size)) 10419 { 10420 if (! host_integerp (len, 1)) 10421 { 10422 /* If LEN is not constant, try MAXLEN too. 10423 For MAXLEN only allow optimizing into non-_ocs function 10424 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 10425 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 10426 { 10427 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore) 10428 { 10429 /* (void) __mempcpy_chk () can be optimized into 10430 (void) __memcpy_chk (). */ 10431 fn = built_in_decls[BUILT_IN_MEMCPY_CHK]; 10432 if (!fn) 10433 return 0; 10434 10435 return build_function_call_expr (fn, arglist); 10436 } 10437 return 0; 10438 } 10439 } 10440 else 10441 maxlen = len; 10442 10443 if (tree_int_cst_lt (size, maxlen)) 10444 return 0; 10445 } 10446 10447 arglist = build_tree_list (NULL_TREE, len); 10448 arglist = tree_cons (NULL_TREE, src, arglist); 10449 arglist = tree_cons (NULL_TREE, dest, arglist); 10450 10451 fn = NULL_TREE; 10452 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume 10453 mem{cpy,pcpy,move,set} is available. */ 10454 switch (fcode) 10455 { 10456 case BUILT_IN_MEMCPY_CHK: 10457 fn = built_in_decls[BUILT_IN_MEMCPY]; 10458 break; 10459 case BUILT_IN_MEMPCPY_CHK: 10460 fn = built_in_decls[BUILT_IN_MEMPCPY]; 10461 break; 10462 case BUILT_IN_MEMMOVE_CHK: 10463 fn = built_in_decls[BUILT_IN_MEMMOVE]; 10464 break; 10465 case BUILT_IN_MEMSET_CHK: 10466 fn = built_in_decls[BUILT_IN_MEMSET]; 10467 break; 10468 default: 10469 break; 10470 } 10471 10472 if (!fn) 10473 return 0; 10474 10475 return build_function_call_expr (fn, arglist); 10476} 10477 10478/* Fold a call to the __st[rp]cpy_chk builtin. 10479 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_* 10480 code of the builtin. If MAXLEN is not NULL, it is maximum length of 10481 strings passed as second argument. */ 10482 10483tree 10484fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore, 10485 enum built_in_function fcode) 10486{ 10487 tree dest, src, size, len, fn; 10488 10489 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, 10490 VOID_TYPE)) 10491 return 0; 10492 10493 dest = TREE_VALUE (arglist); 10494 src = TREE_VALUE (TREE_CHAIN (arglist)); 10495 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10496 10497 /* If SRC and DEST are the same (and not volatile), return DEST. */ 10498 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0)) 10499 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest); 10500 10501 if (! host_integerp (size, 1)) 10502 return 0; 10503 10504 if (! integer_all_onesp (size)) 10505 { 10506 len = c_strlen (src, 1); 10507 if (! len || ! host_integerp (len, 1)) 10508 { 10509 /* If LEN is not constant, try MAXLEN too. 10510 For MAXLEN only allow optimizing into non-_ocs function 10511 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 10512 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 10513 { 10514 if (fcode == BUILT_IN_STPCPY_CHK) 10515 { 10516 if (! ignore) 10517 return 0; 10518 10519 /* If return value of __stpcpy_chk is ignored, 10520 optimize into __strcpy_chk. */ 10521 fn = built_in_decls[BUILT_IN_STRCPY_CHK]; 10522 if (!fn) 10523 return 0; 10524 10525 return build_function_call_expr (fn, arglist); 10526 } 10527 10528 if (! len || TREE_SIDE_EFFECTS (len)) 10529 return 0; 10530 10531 /* If c_strlen returned something, but not a constant, 10532 transform __strcpy_chk into __memcpy_chk. */ 10533 fn = built_in_decls[BUILT_IN_MEMCPY_CHK]; 10534 if (!fn) 10535 return 0; 10536 10537 len = size_binop (PLUS_EXPR, len, ssize_int (1)); 10538 arglist = build_tree_list (NULL_TREE, size); 10539 arglist = tree_cons (NULL_TREE, len, arglist); 10540 arglist = tree_cons (NULL_TREE, src, arglist); 10541 arglist = tree_cons (NULL_TREE, dest, arglist); 10542 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), 10543 build_function_call_expr (fn, arglist)); 10544 } 10545 } 10546 else 10547 maxlen = len; 10548 10549 if (! tree_int_cst_lt (maxlen, size)) 10550 return 0; 10551 } 10552 10553 arglist = build_tree_list (NULL_TREE, src); 10554 arglist = tree_cons (NULL_TREE, dest, arglist); 10555 10556 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */ 10557 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK 10558 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY]; 10559 if (!fn) 10560 return 0; 10561 10562 return build_function_call_expr (fn, arglist); 10563} 10564 10565/* Fold a call to the __strncpy_chk builtin. 10566 If MAXLEN is not NULL, it is maximum length passed as third argument. */ 10567 10568tree 10569fold_builtin_strncpy_chk (tree arglist, tree maxlen) 10570{ 10571 tree dest, src, size, len, fn; 10572 10573 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, 10574 INTEGER_TYPE, VOID_TYPE)) 10575 return 0; 10576 10577 dest = TREE_VALUE (arglist); 10578 src = TREE_VALUE (TREE_CHAIN (arglist)); 10579 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10580 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))); 10581 10582 if (! host_integerp (size, 1)) 10583 return 0; 10584 10585 if (! integer_all_onesp (size)) 10586 { 10587 if (! host_integerp (len, 1)) 10588 { 10589 /* If LEN is not constant, try MAXLEN too. 10590 For MAXLEN only allow optimizing into non-_ocs function 10591 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 10592 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 10593 return 0; 10594 } 10595 else 10596 maxlen = len; 10597 10598 if (tree_int_cst_lt (size, maxlen)) 10599 return 0; 10600 } 10601 10602 arglist = build_tree_list (NULL_TREE, len); 10603 arglist = tree_cons (NULL_TREE, src, arglist); 10604 arglist = tree_cons (NULL_TREE, dest, arglist); 10605 10606 /* If __builtin_strncpy_chk is used, assume strncpy is available. */ 10607 fn = built_in_decls[BUILT_IN_STRNCPY]; 10608 if (!fn) 10609 return 0; 10610 10611 return build_function_call_expr (fn, arglist); 10612} 10613 10614/* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */ 10615 10616static tree 10617fold_builtin_strcat_chk (tree fndecl, tree arglist) 10618{ 10619 tree dest, src, size, fn; 10620 const char *p; 10621 10622 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, 10623 VOID_TYPE)) 10624 return 0; 10625 10626 dest = TREE_VALUE (arglist); 10627 src = TREE_VALUE (TREE_CHAIN (arglist)); 10628 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10629 10630 p = c_getstr (src); 10631 /* If the SRC parameter is "", return DEST. */ 10632 if (p && *p == '\0') 10633 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src); 10634 10635 if (! host_integerp (size, 1) || ! integer_all_onesp (size)) 10636 return 0; 10637 10638 arglist = build_tree_list (NULL_TREE, src); 10639 arglist = tree_cons (NULL_TREE, dest, arglist); 10640 10641 /* If __builtin_strcat_chk is used, assume strcat is available. */ 10642 fn = built_in_decls[BUILT_IN_STRCAT]; 10643 if (!fn) 10644 return 0; 10645 10646 return build_function_call_expr (fn, arglist); 10647} 10648 10649/* Fold a call to the __strncat_chk builtin EXP. */ 10650 10651static tree 10652fold_builtin_strncat_chk (tree fndecl, tree arglist) 10653{ 10654 tree dest, src, size, len, fn; 10655 const char *p; 10656 10657 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, 10658 INTEGER_TYPE, VOID_TYPE)) 10659 return 0; 10660 10661 dest = TREE_VALUE (arglist); 10662 src = TREE_VALUE (TREE_CHAIN (arglist)); 10663 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10664 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))); 10665 10666 p = c_getstr (src); 10667 /* If the SRC parameter is "" or if LEN is 0, return DEST. */ 10668 if (p && *p == '\0') 10669 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len); 10670 else if (integer_zerop (len)) 10671 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src); 10672 10673 if (! host_integerp (size, 1)) 10674 return 0; 10675 10676 if (! integer_all_onesp (size)) 10677 { 10678 tree src_len = c_strlen (src, 1); 10679 if (src_len 10680 && host_integerp (src_len, 1) 10681 && host_integerp (len, 1) 10682 && ! tree_int_cst_lt (len, src_len)) 10683 { 10684 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */ 10685 fn = built_in_decls[BUILT_IN_STRCAT_CHK]; 10686 if (!fn) 10687 return 0; 10688 10689 arglist = build_tree_list (NULL_TREE, size); 10690 arglist = tree_cons (NULL_TREE, src, arglist); 10691 arglist = tree_cons (NULL_TREE, dest, arglist); 10692 return build_function_call_expr (fn, arglist); 10693 } 10694 return 0; 10695 } 10696 10697 arglist = build_tree_list (NULL_TREE, len); 10698 arglist = tree_cons (NULL_TREE, src, arglist); 10699 arglist = tree_cons (NULL_TREE, dest, arglist); 10700 10701 /* If __builtin_strncat_chk is used, assume strncat is available. */ 10702 fn = built_in_decls[BUILT_IN_STRNCAT]; 10703 if (!fn) 10704 return 0; 10705 10706 return build_function_call_expr (fn, arglist); 10707} 10708 10709/* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if 10710 a normal call should be emitted rather than expanding the function 10711 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */ 10712 10713static tree 10714fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode) 10715{ 10716 tree dest, size, len, fn, fmt, flag; 10717 const char *fmt_str; 10718 10719 /* Verify the required arguments in the original call. */ 10720 if (! arglist) 10721 return 0; 10722 dest = TREE_VALUE (arglist); 10723 if (! POINTER_TYPE_P (TREE_TYPE (dest))) 10724 return 0; 10725 arglist = TREE_CHAIN (arglist); 10726 if (! arglist) 10727 return 0; 10728 flag = TREE_VALUE (arglist); 10729 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE) 10730 return 0; 10731 arglist = TREE_CHAIN (arglist); 10732 if (! arglist) 10733 return 0; 10734 size = TREE_VALUE (arglist); 10735 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE) 10736 return 0; 10737 arglist = TREE_CHAIN (arglist); 10738 if (! arglist) 10739 return 0; 10740 fmt = TREE_VALUE (arglist); 10741 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 10742 return 0; 10743 arglist = TREE_CHAIN (arglist); 10744 10745 if (! host_integerp (size, 1)) 10746 return 0; 10747 10748 len = NULL_TREE; 10749 10750 if (!init_target_chars()) 10751 return 0; 10752 10753 /* Check whether the format is a literal string constant. */ 10754 fmt_str = c_getstr (fmt); 10755 if (fmt_str != NULL) 10756 { 10757 /* If the format doesn't contain % args or %%, we know the size. */ 10758 if (strchr (fmt_str, target_percent) == 0) 10759 { 10760 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE) 10761 len = build_int_cstu (size_type_node, strlen (fmt_str)); 10762 } 10763 /* If the format is "%s" and first ... argument is a string literal, 10764 we know the size too. */ 10765 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0) 10766 { 10767 tree arg; 10768 10769 if (arglist && !TREE_CHAIN (arglist)) 10770 { 10771 arg = TREE_VALUE (arglist); 10772 if (POINTER_TYPE_P (TREE_TYPE (arg))) 10773 { 10774 len = c_strlen (arg, 1); 10775 if (! len || ! host_integerp (len, 1)) 10776 len = NULL_TREE; 10777 } 10778 } 10779 } 10780 } 10781 10782 if (! integer_all_onesp (size)) 10783 { 10784 if (! len || ! tree_int_cst_lt (len, size)) 10785 return 0; 10786 } 10787 10788 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0 10789 or if format doesn't contain % chars or is "%s". */ 10790 if (! integer_zerop (flag)) 10791 { 10792 if (fmt_str == NULL) 10793 return 0; 10794 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s)) 10795 return 0; 10796 } 10797 10798 arglist = tree_cons (NULL_TREE, fmt, arglist); 10799 arglist = tree_cons (NULL_TREE, dest, arglist); 10800 10801 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */ 10802 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK 10803 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF]; 10804 if (!fn) 10805 return 0; 10806 10807 return build_function_call_expr (fn, arglist); 10808} 10809 10810/* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if 10811 a normal call should be emitted rather than expanding the function 10812 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or 10813 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length 10814 passed as second argument. */ 10815 10816tree 10817fold_builtin_snprintf_chk (tree arglist, tree maxlen, 10818 enum built_in_function fcode) 10819{ 10820 tree dest, size, len, fn, fmt, flag; 10821 const char *fmt_str; 10822 10823 /* Verify the required arguments in the original call. */ 10824 if (! arglist) 10825 return 0; 10826 dest = TREE_VALUE (arglist); 10827 if (! POINTER_TYPE_P (TREE_TYPE (dest))) 10828 return 0; 10829 arglist = TREE_CHAIN (arglist); 10830 if (! arglist) 10831 return 0; 10832 len = TREE_VALUE (arglist); 10833 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE) 10834 return 0; 10835 arglist = TREE_CHAIN (arglist); 10836 if (! arglist) 10837 return 0; 10838 flag = TREE_VALUE (arglist); 10839 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE) 10840 return 0; 10841 arglist = TREE_CHAIN (arglist); 10842 if (! arglist) 10843 return 0; 10844 size = TREE_VALUE (arglist); 10845 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE) 10846 return 0; 10847 arglist = TREE_CHAIN (arglist); 10848 if (! arglist) 10849 return 0; 10850 fmt = TREE_VALUE (arglist); 10851 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 10852 return 0; 10853 arglist = TREE_CHAIN (arglist); 10854 10855 if (! host_integerp (size, 1)) 10856 return 0; 10857 10858 if (! integer_all_onesp (size)) 10859 { 10860 if (! host_integerp (len, 1)) 10861 { 10862 /* If LEN is not constant, try MAXLEN too. 10863 For MAXLEN only allow optimizing into non-_ocs function 10864 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 10865 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 10866 return 0; 10867 } 10868 else 10869 maxlen = len; 10870 10871 if (tree_int_cst_lt (size, maxlen)) 10872 return 0; 10873 } 10874 10875 if (!init_target_chars()) 10876 return 0; 10877 10878 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0 10879 or if format doesn't contain % chars or is "%s". */ 10880 if (! integer_zerop (flag)) 10881 { 10882 fmt_str = c_getstr (fmt); 10883 if (fmt_str == NULL) 10884 return 0; 10885 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s)) 10886 return 0; 10887 } 10888 10889 arglist = tree_cons (NULL_TREE, fmt, arglist); 10890 arglist = tree_cons (NULL_TREE, len, arglist); 10891 arglist = tree_cons (NULL_TREE, dest, arglist); 10892 10893 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is 10894 available. */ 10895 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK 10896 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF]; 10897 if (!fn) 10898 return 0; 10899 10900 return build_function_call_expr (fn, arglist); 10901} 10902 10903/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins. 10904 10905 Return 0 if no simplification was possible, otherwise return the 10906 simplified form of the call as a tree. FCODE is the BUILT_IN_* 10907 code of the function to be simplified. */ 10908 10909static tree 10910fold_builtin_printf (tree fndecl, tree arglist, bool ignore, 10911 enum built_in_function fcode) 10912{ 10913 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call; 10914 const char *fmt_str = NULL; 10915 10916 /* If the return value is used, don't do the transformation. */ 10917 if (! ignore) 10918 return 0; 10919 10920 /* Verify the required arguments in the original call. */ 10921 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK) 10922 { 10923 tree flag; 10924 10925 if (! arglist) 10926 return 0; 10927 flag = TREE_VALUE (arglist); 10928 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE 10929 || TREE_SIDE_EFFECTS (flag)) 10930 return 0; 10931 arglist = TREE_CHAIN (arglist); 10932 } 10933 10934 if (! arglist) 10935 return 0; 10936 fmt = TREE_VALUE (arglist); 10937 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 10938 return 0; 10939 arglist = TREE_CHAIN (arglist); 10940 10941 /* Check whether the format is a literal string constant. */ 10942 fmt_str = c_getstr (fmt); 10943 if (fmt_str == NULL) 10944 return NULL_TREE; 10945 10946 if (fcode == BUILT_IN_PRINTF_UNLOCKED) 10947 { 10948 /* If we're using an unlocked function, assume the other 10949 unlocked functions exist explicitly. */ 10950 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]; 10951 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED]; 10952 } 10953 else 10954 { 10955 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR]; 10956 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS]; 10957 } 10958 10959 if (!init_target_chars()) 10960 return 0; 10961 10962 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL) 10963 { 10964 const char *str; 10965 10966 if (strcmp (fmt_str, target_percent_s) == 0) 10967 { 10968 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK) 10969 return 0; 10970 10971 if (! arglist 10972 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))) 10973 || TREE_CHAIN (arglist)) 10974 return 0; 10975 10976 str = c_getstr (TREE_VALUE (arglist)); 10977 if (str == NULL) 10978 return 0; 10979 } 10980 else 10981 { 10982 /* The format specifier doesn't contain any '%' characters. */ 10983 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK 10984 && arglist) 10985 return 0; 10986 str = fmt_str; 10987 } 10988 10989 /* If the string was "", printf does nothing. */ 10990 if (str[0] == '\0') 10991 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0); 10992 10993 /* If the string has length of 1, call putchar. */ 10994 if (str[1] == '\0') 10995 { 10996 /* Given printf("c"), (where c is any one character,) 10997 convert "c"[0] to an int and pass that to the replacement 10998 function. */ 10999 arg = build_int_cst (NULL_TREE, str[0]); 11000 arglist = build_tree_list (NULL_TREE, arg); 11001 fn = fn_putchar; 11002 } 11003 else 11004 { 11005 /* If the string was "string\n", call puts("string"). */ 11006 size_t len = strlen (str); 11007 if ((unsigned char)str[len - 1] == target_newline) 11008 { 11009 /* Create a NUL-terminated string that's one char shorter 11010 than the original, stripping off the trailing '\n'. */ 11011 char *newstr = alloca (len); 11012 memcpy (newstr, str, len - 1); 11013 newstr[len - 1] = 0; 11014 11015 arg = build_string_literal (len, newstr); 11016 arglist = build_tree_list (NULL_TREE, arg); 11017 fn = fn_puts; 11018 } 11019 else 11020 /* We'd like to arrange to call fputs(string,stdout) here, 11021 but we need stdout and don't have a way to get it yet. */ 11022 return 0; 11023 } 11024 } 11025 11026 /* The other optimizations can be done only on the non-va_list variants. */ 11027 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK) 11028 return 0; 11029 11030 /* If the format specifier was "%s\n", call __builtin_puts(arg). */ 11031 else if (strcmp (fmt_str, target_percent_s_newline) == 0) 11032 { 11033 if (! arglist 11034 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))) 11035 || TREE_CHAIN (arglist)) 11036 return 0; 11037 fn = fn_puts; 11038 } 11039 11040 /* If the format specifier was "%c", call __builtin_putchar(arg). */ 11041 else if (strcmp (fmt_str, target_percent_c) == 0) 11042 { 11043 if (! arglist 11044 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE 11045 || TREE_CHAIN (arglist)) 11046 return 0; 11047 fn = fn_putchar; 11048 } 11049 11050 if (!fn) 11051 return 0; 11052 11053 call = build_function_call_expr (fn, arglist); 11054 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call); 11055} 11056 11057/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins. 11058 11059 Return 0 if no simplification was possible, otherwise return the 11060 simplified form of the call as a tree. FCODE is the BUILT_IN_* 11061 code of the function to be simplified. */ 11062 11063static tree 11064fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore, 11065 enum built_in_function fcode) 11066{ 11067 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call; 11068 const char *fmt_str = NULL; 11069 11070 /* If the return value is used, don't do the transformation. */ 11071 if (! ignore) 11072 return 0; 11073 11074 /* Verify the required arguments in the original call. */ 11075 if (! arglist) 11076 return 0; 11077 fp = TREE_VALUE (arglist); 11078 if (! POINTER_TYPE_P (TREE_TYPE (fp))) 11079 return 0; 11080 arglist = TREE_CHAIN (arglist); 11081 11082 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK) 11083 { 11084 tree flag; 11085 11086 if (! arglist) 11087 return 0; 11088 flag = TREE_VALUE (arglist); 11089 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE 11090 || TREE_SIDE_EFFECTS (flag)) 11091 return 0; 11092 arglist = TREE_CHAIN (arglist); 11093 } 11094 11095 if (! arglist) 11096 return 0; 11097 fmt = TREE_VALUE (arglist); 11098 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 11099 return 0; 11100 arglist = TREE_CHAIN (arglist); 11101 11102 /* Check whether the format is a literal string constant. */ 11103 fmt_str = c_getstr (fmt); 11104 if (fmt_str == NULL) 11105 return NULL_TREE; 11106 11107 if (fcode == BUILT_IN_FPRINTF_UNLOCKED) 11108 { 11109 /* If we're using an unlocked function, assume the other 11110 unlocked functions exist explicitly. */ 11111 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED]; 11112 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED]; 11113 } 11114 else 11115 { 11116 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC]; 11117 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS]; 11118 } 11119 11120 if (!init_target_chars()) 11121 return 0; 11122 11123 /* If the format doesn't contain % args or %%, use strcpy. */ 11124 if (strchr (fmt_str, target_percent) == NULL) 11125 { 11126 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK 11127 && arglist) 11128 return 0; 11129 11130 /* If the format specifier was "", fprintf does nothing. */ 11131 if (fmt_str[0] == '\0') 11132 { 11133 /* If FP has side-effects, just wait until gimplification is 11134 done. */ 11135 if (TREE_SIDE_EFFECTS (fp)) 11136 return 0; 11137 11138 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0); 11139 } 11140 11141 /* When "string" doesn't contain %, replace all cases of 11142 fprintf (fp, string) with fputs (string, fp). The fputs 11143 builtin will take care of special cases like length == 1. */ 11144 arglist = build_tree_list (NULL_TREE, fp); 11145 arglist = tree_cons (NULL_TREE, fmt, arglist); 11146 fn = fn_fputs; 11147 } 11148 11149 /* The other optimizations can be done only on the non-va_list variants. */ 11150 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK) 11151 return 0; 11152 11153 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */ 11154 else if (strcmp (fmt_str, target_percent_s) == 0) 11155 { 11156 if (! arglist 11157 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))) 11158 || TREE_CHAIN (arglist)) 11159 return 0; 11160 arg = TREE_VALUE (arglist); 11161 arglist = build_tree_list (NULL_TREE, fp); 11162 arglist = tree_cons (NULL_TREE, arg, arglist); 11163 fn = fn_fputs; 11164 } 11165 11166 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */ 11167 else if (strcmp (fmt_str, target_percent_c) == 0) 11168 { 11169 if (! arglist 11170 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE 11171 || TREE_CHAIN (arglist)) 11172 return 0; 11173 arg = TREE_VALUE (arglist); 11174 arglist = build_tree_list (NULL_TREE, fp); 11175 arglist = tree_cons (NULL_TREE, arg, arglist); 11176 fn = fn_fputc; 11177 } 11178 11179 if (!fn) 11180 return 0; 11181 11182 call = build_function_call_expr (fn, arglist); 11183 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call); 11184} 11185 11186/* Initialize format string characters in the target charset. */ 11187 11188static bool 11189init_target_chars (void) 11190{ 11191 static bool init; 11192 if (!init) 11193 { 11194 target_newline = lang_hooks.to_target_charset ('\n'); 11195 target_percent = lang_hooks.to_target_charset ('%'); 11196 target_c = lang_hooks.to_target_charset ('c'); 11197 target_s = lang_hooks.to_target_charset ('s'); 11198 if (target_newline == 0 || target_percent == 0 || target_c == 0 11199 || target_s == 0) 11200 return false; 11201 11202 target_percent_c[0] = target_percent; 11203 target_percent_c[1] = target_c; 11204 target_percent_c[2] = '\0'; 11205 11206 target_percent_s[0] = target_percent; 11207 target_percent_s[1] = target_s; 11208 target_percent_s[2] = '\0'; 11209 11210 target_percent_s_newline[0] = target_percent; 11211 target_percent_s_newline[1] = target_s; 11212 target_percent_s_newline[2] = target_newline; 11213 target_percent_s_newline[3] = '\0'; 11214 11215 init = true; 11216 } 11217 return true; 11218} 11219