builtins.c revision 259563
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 bswap builtin. The arguments are in ARGLIST. MODE 4593 is the mode to expand with. */ 4594 4595static rtx 4596expand_builtin_bswap (tree arglist, rtx target, rtx subtarget) 4597{ 4598 enum machine_mode mode; 4599 tree arg; 4600 rtx op0; 4601 4602 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 4603 return 0; 4604 4605 arg = TREE_VALUE (arglist); 4606 mode = TYPE_MODE (TREE_TYPE (arg)); 4607 op0 = expand_expr (arg, subtarget, VOIDmode, 0); 4608 4609 target = expand_unop (mode, bswap_optab, op0, target, 1); 4610 4611 gcc_assert (target); 4612 4613 return convert_to_mode (mode, target, 0); 4614} 4615 4616/* Expand a call to a unary builtin. The arguments are in ARGLIST. 4617 Return 0 if a normal call should be emitted rather than expanding the 4618 function in-line. If convenient, the result should be placed in TARGET. 4619 SUBTARGET may be used as the target for computing one of EXP's operands. */ 4620 4621static rtx 4622expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target, 4623 rtx subtarget, optab op_optab) 4624{ 4625 rtx op0; 4626 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 4627 return 0; 4628 4629 /* Compute the argument. */ 4630 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0); 4631 /* Compute op, into TARGET if possible. 4632 Set TARGET to wherever the result comes back. */ 4633 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))), 4634 op_optab, op0, target, 1); 4635 gcc_assert (target); 4636 4637 return convert_to_mode (target_mode, target, 0); 4638} 4639 4640/* If the string passed to fputs is a constant and is one character 4641 long, we attempt to transform this call into __builtin_fputc(). */ 4642 4643static rtx 4644expand_builtin_fputs (tree arglist, rtx target, bool unlocked) 4645{ 4646 /* Verify the arguments in the original call. */ 4647 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 4648 { 4649 tree result = fold_builtin_fputs (arglist, (target == const0_rtx), 4650 unlocked, NULL_TREE); 4651 if (result) 4652 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL); 4653 } 4654 return 0; 4655} 4656 4657/* Expand a call to __builtin_expect. We return our argument and emit a 4658 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in 4659 a non-jump context. */ 4660 4661static rtx 4662expand_builtin_expect (tree arglist, rtx target) 4663{ 4664 tree exp, c; 4665 rtx note, rtx_c; 4666 4667 if (arglist == NULL_TREE 4668 || TREE_CHAIN (arglist) == NULL_TREE) 4669 return const0_rtx; 4670 exp = TREE_VALUE (arglist); 4671 c = TREE_VALUE (TREE_CHAIN (arglist)); 4672 4673 if (TREE_CODE (c) != INTEGER_CST) 4674 { 4675 error ("second argument to %<__builtin_expect%> must be a constant"); 4676 c = integer_zero_node; 4677 } 4678 4679 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL); 4680 4681 /* Don't bother with expected value notes for integral constants. */ 4682 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT) 4683 { 4684 /* We do need to force this into a register so that we can be 4685 moderately sure to be able to correctly interpret the branch 4686 condition later. */ 4687 target = force_reg (GET_MODE (target), target); 4688 4689 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL); 4690 4691 note = emit_note (NOTE_INSN_EXPECTED_VALUE); 4692 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c); 4693 } 4694 4695 return target; 4696} 4697 4698/* Like expand_builtin_expect, except do this in a jump context. This is 4699 called from do_jump if the conditional is a __builtin_expect. Return either 4700 a list of insns to emit the jump or NULL if we cannot optimize 4701 __builtin_expect. We need to optimize this at jump time so that machines 4702 like the PowerPC don't turn the test into a SCC operation, and then jump 4703 based on the test being 0/1. */ 4704 4705rtx 4706expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label) 4707{ 4708 tree arglist = TREE_OPERAND (exp, 1); 4709 tree arg0 = TREE_VALUE (arglist); 4710 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 4711 rtx ret = NULL_RTX; 4712 4713 /* Only handle __builtin_expect (test, 0) and 4714 __builtin_expect (test, 1). */ 4715 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE 4716 && (integer_zerop (arg1) || integer_onep (arg1))) 4717 { 4718 rtx insn, drop_through_label, temp; 4719 4720 /* Expand the jump insns. */ 4721 start_sequence (); 4722 do_jump (arg0, if_false_label, if_true_label); 4723 ret = get_insns (); 4724 4725 drop_through_label = get_last_insn (); 4726 if (drop_through_label && NOTE_P (drop_through_label)) 4727 drop_through_label = prev_nonnote_insn (drop_through_label); 4728 if (drop_through_label && !LABEL_P (drop_through_label)) 4729 drop_through_label = NULL_RTX; 4730 end_sequence (); 4731 4732 if (! if_true_label) 4733 if_true_label = drop_through_label; 4734 if (! if_false_label) 4735 if_false_label = drop_through_label; 4736 4737 /* Go through and add the expect's to each of the conditional jumps. */ 4738 insn = ret; 4739 while (insn != NULL_RTX) 4740 { 4741 rtx next = NEXT_INSN (insn); 4742 4743 if (JUMP_P (insn) && any_condjump_p (insn)) 4744 { 4745 rtx ifelse = SET_SRC (pc_set (insn)); 4746 rtx then_dest = XEXP (ifelse, 1); 4747 rtx else_dest = XEXP (ifelse, 2); 4748 int taken = -1; 4749 4750 /* First check if we recognize any of the labels. */ 4751 if (GET_CODE (then_dest) == LABEL_REF 4752 && XEXP (then_dest, 0) == if_true_label) 4753 taken = 1; 4754 else if (GET_CODE (then_dest) == LABEL_REF 4755 && XEXP (then_dest, 0) == if_false_label) 4756 taken = 0; 4757 else if (GET_CODE (else_dest) == LABEL_REF 4758 && XEXP (else_dest, 0) == if_false_label) 4759 taken = 1; 4760 else if (GET_CODE (else_dest) == LABEL_REF 4761 && XEXP (else_dest, 0) == if_true_label) 4762 taken = 0; 4763 /* Otherwise check where we drop through. */ 4764 else if (else_dest == pc_rtx) 4765 { 4766 if (next && NOTE_P (next)) 4767 next = next_nonnote_insn (next); 4768 4769 if (next && JUMP_P (next) 4770 && any_uncondjump_p (next)) 4771 temp = XEXP (SET_SRC (pc_set (next)), 0); 4772 else 4773 temp = next; 4774 4775 /* TEMP is either a CODE_LABEL, NULL_RTX or something 4776 else that can't possibly match either target label. */ 4777 if (temp == if_false_label) 4778 taken = 1; 4779 else if (temp == if_true_label) 4780 taken = 0; 4781 } 4782 else if (then_dest == pc_rtx) 4783 { 4784 if (next && NOTE_P (next)) 4785 next = next_nonnote_insn (next); 4786 4787 if (next && JUMP_P (next) 4788 && any_uncondjump_p (next)) 4789 temp = XEXP (SET_SRC (pc_set (next)), 0); 4790 else 4791 temp = next; 4792 4793 if (temp == if_false_label) 4794 taken = 0; 4795 else if (temp == if_true_label) 4796 taken = 1; 4797 } 4798 4799 if (taken != -1) 4800 { 4801 /* If the test is expected to fail, reverse the 4802 probabilities. */ 4803 if (integer_zerop (arg1)) 4804 taken = 1 - taken; 4805 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken); 4806 } 4807 } 4808 4809 insn = next; 4810 } 4811 } 4812 4813 return ret; 4814} 4815 4816void 4817expand_builtin_trap (void) 4818{ 4819#ifdef HAVE_trap 4820 if (HAVE_trap) 4821 emit_insn (gen_trap ()); 4822 else 4823#endif 4824 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0); 4825 emit_barrier (); 4826} 4827 4828/* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST. 4829 Return 0 if a normal call should be emitted rather than expanding 4830 the function inline. If convenient, the result should be placed 4831 in TARGET. SUBTARGET may be used as the target for computing 4832 the operand. */ 4833 4834static rtx 4835expand_builtin_fabs (tree arglist, rtx target, rtx subtarget) 4836{ 4837 enum machine_mode mode; 4838 tree arg; 4839 rtx op0; 4840 4841 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 4842 return 0; 4843 4844 arg = TREE_VALUE (arglist); 4845 mode = TYPE_MODE (TREE_TYPE (arg)); 4846 op0 = expand_expr (arg, subtarget, VOIDmode, 0); 4847 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1)); 4848} 4849 4850/* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST. 4851 Return NULL is a normal call should be emitted rather than expanding the 4852 function inline. If convenient, the result should be placed in TARGET. 4853 SUBTARGET may be used as the target for computing the operand. */ 4854 4855static rtx 4856expand_builtin_copysign (tree arglist, rtx target, rtx subtarget) 4857{ 4858 rtx op0, op1; 4859 tree arg; 4860 4861 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 4862 return 0; 4863 4864 arg = TREE_VALUE (arglist); 4865 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL); 4866 4867 arg = TREE_VALUE (TREE_CHAIN (arglist)); 4868 op1 = expand_normal (arg); 4869 4870 return expand_copysign (op0, op1, target); 4871} 4872 4873/* Create a new constant string literal and return a char* pointer to it. 4874 The STRING_CST value is the LEN characters at STR. */ 4875tree 4876build_string_literal (int len, const char *str) 4877{ 4878 tree t, elem, index, type; 4879 4880 t = build_string (len, str); 4881 elem = build_type_variant (char_type_node, 1, 0); 4882 index = build_index_type (build_int_cst (NULL_TREE, len - 1)); 4883 type = build_array_type (elem, index); 4884 TREE_TYPE (t) = type; 4885 TREE_CONSTANT (t) = 1; 4886 TREE_INVARIANT (t) = 1; 4887 TREE_READONLY (t) = 1; 4888 TREE_STATIC (t) = 1; 4889 4890 type = build_pointer_type (type); 4891 t = build1 (ADDR_EXPR, type, t); 4892 4893 type = build_pointer_type (elem); 4894 t = build1 (NOP_EXPR, type, t); 4895 return t; 4896} 4897 4898/* Expand EXP, a call to printf or printf_unlocked. 4899 Return 0 if a normal call should be emitted rather than transforming 4900 the function inline. If convenient, the result should be placed in 4901 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked 4902 call. */ 4903static rtx 4904expand_builtin_printf (tree exp, rtx target, enum machine_mode mode, 4905 bool unlocked) 4906{ 4907 tree arglist = TREE_OPERAND (exp, 1); 4908 /* If we're using an unlocked function, assume the other unlocked 4909 functions exist explicitly. */ 4910 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] 4911 : implicit_built_in_decls[BUILT_IN_PUTCHAR]; 4912 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED] 4913 : implicit_built_in_decls[BUILT_IN_PUTS]; 4914 const char *fmt_str; 4915 tree fn, fmt, arg; 4916 4917 /* If the return value is used, don't do the transformation. */ 4918 if (target != const0_rtx) 4919 return 0; 4920 4921 /* Verify the required arguments in the original call. */ 4922 if (! arglist) 4923 return 0; 4924 fmt = TREE_VALUE (arglist); 4925 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 4926 return 0; 4927 arglist = TREE_CHAIN (arglist); 4928 4929 /* Check whether the format is a literal string constant. */ 4930 fmt_str = c_getstr (fmt); 4931 if (fmt_str == NULL) 4932 return 0; 4933 4934 if (!init_target_chars()) 4935 return 0; 4936 4937 /* If the format specifier was "%s\n", call __builtin_puts(arg). */ 4938 if (strcmp (fmt_str, target_percent_s_newline) == 0) 4939 { 4940 if (! arglist 4941 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))) 4942 || TREE_CHAIN (arglist)) 4943 return 0; 4944 fn = fn_puts; 4945 } 4946 /* If the format specifier was "%c", call __builtin_putchar(arg). */ 4947 else if (strcmp (fmt_str, target_percent_c) == 0) 4948 { 4949 if (! arglist 4950 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE 4951 || TREE_CHAIN (arglist)) 4952 return 0; 4953 fn = fn_putchar; 4954 } 4955 else 4956 { 4957 /* We can't handle anything else with % args or %% ... yet. */ 4958 if (strchr (fmt_str, target_percent)) 4959 return 0; 4960 4961 if (arglist) 4962 return 0; 4963 4964 /* If the format specifier was "", printf does nothing. */ 4965 if (fmt_str[0] == '\0') 4966 return const0_rtx; 4967 /* If the format specifier has length of 1, call putchar. */ 4968 if (fmt_str[1] == '\0') 4969 { 4970 /* Given printf("c"), (where c is any one character,) 4971 convert "c"[0] to an int and pass that to the replacement 4972 function. */ 4973 arg = build_int_cst (NULL_TREE, fmt_str[0]); 4974 arglist = build_tree_list (NULL_TREE, arg); 4975 fn = fn_putchar; 4976 } 4977 else 4978 { 4979 /* If the format specifier was "string\n", call puts("string"). */ 4980 size_t len = strlen (fmt_str); 4981 if ((unsigned char)fmt_str[len - 1] == target_newline) 4982 { 4983 /* Create a NUL-terminated string that's one char shorter 4984 than the original, stripping off the trailing '\n'. */ 4985 char *newstr = alloca (len); 4986 memcpy (newstr, fmt_str, len - 1); 4987 newstr[len - 1] = 0; 4988 4989 arg = build_string_literal (len, newstr); 4990 arglist = build_tree_list (NULL_TREE, arg); 4991 fn = fn_puts; 4992 } 4993 else 4994 /* We'd like to arrange to call fputs(string,stdout) here, 4995 but we need stdout and don't have a way to get it yet. */ 4996 return 0; 4997 } 4998 } 4999 5000 if (!fn) 5001 return 0; 5002 fn = build_function_call_expr (fn, arglist); 5003 if (TREE_CODE (fn) == CALL_EXPR) 5004 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 5005 return expand_expr (fn, target, mode, EXPAND_NORMAL); 5006} 5007 5008/* Expand EXP, a call to fprintf or fprintf_unlocked. 5009 Return 0 if a normal call should be emitted rather than transforming 5010 the function inline. If convenient, the result should be placed in 5011 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked 5012 call. */ 5013static rtx 5014expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode, 5015 bool unlocked) 5016{ 5017 tree arglist = TREE_OPERAND (exp, 1); 5018 /* If we're using an unlocked function, assume the other unlocked 5019 functions exist explicitly. */ 5020 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED] 5021 : implicit_built_in_decls[BUILT_IN_FPUTC]; 5022 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED] 5023 : implicit_built_in_decls[BUILT_IN_FPUTS]; 5024 const char *fmt_str; 5025 tree fn, fmt, fp, arg; 5026 5027 /* If the return value is used, don't do the transformation. */ 5028 if (target != const0_rtx) 5029 return 0; 5030 5031 /* Verify the required arguments in the original call. */ 5032 if (! arglist) 5033 return 0; 5034 fp = TREE_VALUE (arglist); 5035 if (! POINTER_TYPE_P (TREE_TYPE (fp))) 5036 return 0; 5037 arglist = TREE_CHAIN (arglist); 5038 if (! arglist) 5039 return 0; 5040 fmt = TREE_VALUE (arglist); 5041 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 5042 return 0; 5043 arglist = TREE_CHAIN (arglist); 5044 5045 /* Check whether the format is a literal string constant. */ 5046 fmt_str = c_getstr (fmt); 5047 if (fmt_str == NULL) 5048 return 0; 5049 5050 if (!init_target_chars()) 5051 return 0; 5052 5053 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */ 5054 if (strcmp (fmt_str, target_percent_s) == 0) 5055 { 5056 if (! arglist 5057 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))) 5058 || TREE_CHAIN (arglist)) 5059 return 0; 5060 arg = TREE_VALUE (arglist); 5061 arglist = build_tree_list (NULL_TREE, fp); 5062 arglist = tree_cons (NULL_TREE, arg, arglist); 5063 fn = fn_fputs; 5064 } 5065 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */ 5066 else if (strcmp (fmt_str, target_percent_c) == 0) 5067 { 5068 if (! arglist 5069 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE 5070 || TREE_CHAIN (arglist)) 5071 return 0; 5072 arg = TREE_VALUE (arglist); 5073 arglist = build_tree_list (NULL_TREE, fp); 5074 arglist = tree_cons (NULL_TREE, arg, arglist); 5075 fn = fn_fputc; 5076 } 5077 else 5078 { 5079 /* We can't handle anything else with % args or %% ... yet. */ 5080 if (strchr (fmt_str, target_percent)) 5081 return 0; 5082 5083 if (arglist) 5084 return 0; 5085 5086 /* If the format specifier was "", fprintf does nothing. */ 5087 if (fmt_str[0] == '\0') 5088 { 5089 /* Evaluate and ignore FILE* argument for side-effects. */ 5090 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL); 5091 return const0_rtx; 5092 } 5093 5094 /* When "string" doesn't contain %, replace all cases of 5095 fprintf(stream,string) with fputs(string,stream). The fputs 5096 builtin will take care of special cases like length == 1. */ 5097 arglist = build_tree_list (NULL_TREE, fp); 5098 arglist = tree_cons (NULL_TREE, fmt, arglist); 5099 fn = fn_fputs; 5100 } 5101 5102 if (!fn) 5103 return 0; 5104 fn = build_function_call_expr (fn, arglist); 5105 if (TREE_CODE (fn) == CALL_EXPR) 5106 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 5107 return expand_expr (fn, target, mode, EXPAND_NORMAL); 5108} 5109 5110/* Expand a call to sprintf with argument list ARGLIST. Return 0 if 5111 a normal call should be emitted rather than expanding the function 5112 inline. If convenient, the result should be placed in TARGET with 5113 mode MODE. */ 5114 5115static rtx 5116expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode) 5117{ 5118 tree orig_arglist, dest, fmt; 5119 const char *fmt_str; 5120 5121 orig_arglist = arglist; 5122 5123 /* Verify the required arguments in the original call. */ 5124 if (! arglist) 5125 return 0; 5126 dest = TREE_VALUE (arglist); 5127 if (! POINTER_TYPE_P (TREE_TYPE (dest))) 5128 return 0; 5129 arglist = TREE_CHAIN (arglist); 5130 if (! arglist) 5131 return 0; 5132 fmt = TREE_VALUE (arglist); 5133 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 5134 return 0; 5135 arglist = TREE_CHAIN (arglist); 5136 5137 /* Check whether the format is a literal string constant. */ 5138 fmt_str = c_getstr (fmt); 5139 if (fmt_str == NULL) 5140 return 0; 5141 5142 if (!init_target_chars()) 5143 return 0; 5144 5145 /* If the format doesn't contain % args or %%, use strcpy. */ 5146 if (strchr (fmt_str, target_percent) == 0) 5147 { 5148 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 5149 tree exp; 5150 5151 if (arglist || ! fn) 5152 return 0; 5153 expand_expr (build_function_call_expr (fn, orig_arglist), 5154 const0_rtx, VOIDmode, EXPAND_NORMAL); 5155 if (target == const0_rtx) 5156 return const0_rtx; 5157 exp = build_int_cst (NULL_TREE, strlen (fmt_str)); 5158 return expand_expr (exp, target, mode, EXPAND_NORMAL); 5159 } 5160 /* If the format is "%s", use strcpy if the result isn't used. */ 5161 else if (strcmp (fmt_str, target_percent_s) == 0) 5162 { 5163 tree fn, arg, len; 5164 fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 5165 5166 if (! fn) 5167 return 0; 5168 5169 if (! arglist || TREE_CHAIN (arglist)) 5170 return 0; 5171 arg = TREE_VALUE (arglist); 5172 if (! POINTER_TYPE_P (TREE_TYPE (arg))) 5173 return 0; 5174 5175 if (target != const0_rtx) 5176 { 5177 len = c_strlen (arg, 1); 5178 if (! len || TREE_CODE (len) != INTEGER_CST) 5179 return 0; 5180 } 5181 else 5182 len = NULL_TREE; 5183 5184 arglist = build_tree_list (NULL_TREE, arg); 5185 arglist = tree_cons (NULL_TREE, dest, arglist); 5186 expand_expr (build_function_call_expr (fn, arglist), 5187 const0_rtx, VOIDmode, EXPAND_NORMAL); 5188 5189 if (target == const0_rtx) 5190 return const0_rtx; 5191 return expand_expr (len, target, mode, EXPAND_NORMAL); 5192 } 5193 5194 return 0; 5195} 5196 5197/* Expand a call to either the entry or exit function profiler. */ 5198 5199static rtx 5200expand_builtin_profile_func (bool exitp) 5201{ 5202 rtx this, which; 5203 5204 this = DECL_RTL (current_function_decl); 5205 gcc_assert (MEM_P (this)); 5206 this = XEXP (this, 0); 5207 5208 if (exitp) 5209 which = profile_function_exit_libfunc; 5210 else 5211 which = profile_function_entry_libfunc; 5212 5213 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode, 5214 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS, 5215 0), 5216 Pmode); 5217 5218 return const0_rtx; 5219} 5220 5221/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */ 5222 5223static rtx 5224round_trampoline_addr (rtx tramp) 5225{ 5226 rtx temp, addend, mask; 5227 5228 /* If we don't need too much alignment, we'll have been guaranteed 5229 proper alignment by get_trampoline_type. */ 5230 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY) 5231 return tramp; 5232 5233 /* Round address up to desired boundary. */ 5234 temp = gen_reg_rtx (Pmode); 5235 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1); 5236 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT); 5237 5238 temp = expand_simple_binop (Pmode, PLUS, tramp, addend, 5239 temp, 0, OPTAB_LIB_WIDEN); 5240 tramp = expand_simple_binop (Pmode, AND, temp, mask, 5241 temp, 0, OPTAB_LIB_WIDEN); 5242 5243 return tramp; 5244} 5245 5246static rtx 5247expand_builtin_init_trampoline (tree arglist) 5248{ 5249 tree t_tramp, t_func, t_chain; 5250 rtx r_tramp, r_func, r_chain; 5251#ifdef TRAMPOLINE_TEMPLATE 5252 rtx blktramp; 5253#endif 5254 5255 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, 5256 POINTER_TYPE, VOID_TYPE)) 5257 return NULL_RTX; 5258 5259 t_tramp = TREE_VALUE (arglist); 5260 arglist = TREE_CHAIN (arglist); 5261 t_func = TREE_VALUE (arglist); 5262 arglist = TREE_CHAIN (arglist); 5263 t_chain = TREE_VALUE (arglist); 5264 5265 r_tramp = expand_normal (t_tramp); 5266 r_func = expand_normal (t_func); 5267 r_chain = expand_normal (t_chain); 5268 5269 /* Generate insns to initialize the trampoline. */ 5270 r_tramp = round_trampoline_addr (r_tramp); 5271#ifdef TRAMPOLINE_TEMPLATE 5272 blktramp = gen_rtx_MEM (BLKmode, r_tramp); 5273 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT); 5274 emit_block_move (blktramp, assemble_trampoline_template (), 5275 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); 5276#endif 5277 trampolines_created = 1; 5278 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain); 5279 5280 return const0_rtx; 5281} 5282 5283static rtx 5284expand_builtin_adjust_trampoline (tree arglist) 5285{ 5286 rtx tramp; 5287 5288 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 5289 return NULL_RTX; 5290 5291 tramp = expand_normal (TREE_VALUE (arglist)); 5292 tramp = round_trampoline_addr (tramp); 5293#ifdef TRAMPOLINE_ADJUST_ADDRESS 5294 TRAMPOLINE_ADJUST_ADDRESS (tramp); 5295#endif 5296 5297 return tramp; 5298} 5299 5300/* Expand a call to the built-in signbit, signbitf or signbitl function. 5301 Return NULL_RTX if a normal call should be emitted rather than expanding 5302 the function in-line. EXP is the expression that is a call to the builtin 5303 function; if convenient, the result should be placed in TARGET. */ 5304 5305static rtx 5306expand_builtin_signbit (tree exp, rtx target) 5307{ 5308 const struct real_format *fmt; 5309 enum machine_mode fmode, imode, rmode; 5310 HOST_WIDE_INT hi, lo; 5311 tree arg, arglist; 5312 int word, bitpos; 5313 rtx temp; 5314 5315 arglist = TREE_OPERAND (exp, 1); 5316 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 5317 return 0; 5318 5319 arg = TREE_VALUE (arglist); 5320 fmode = TYPE_MODE (TREE_TYPE (arg)); 5321 rmode = TYPE_MODE (TREE_TYPE (exp)); 5322 fmt = REAL_MODE_FORMAT (fmode); 5323 5324 /* For floating point formats without a sign bit, implement signbit 5325 as "ARG < 0.0". */ 5326 bitpos = fmt->signbit_ro; 5327 if (bitpos < 0) 5328 { 5329 /* But we can't do this if the format supports signed zero. */ 5330 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode)) 5331 return 0; 5332 5333 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg, 5334 build_real (TREE_TYPE (arg), dconst0)); 5335 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL); 5336 } 5337 5338 temp = expand_normal (arg); 5339 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD) 5340 { 5341 imode = int_mode_for_mode (fmode); 5342 if (imode == BLKmode) 5343 return 0; 5344 temp = gen_lowpart (imode, temp); 5345 } 5346 else 5347 { 5348 imode = word_mode; 5349 /* Handle targets with different FP word orders. */ 5350 if (FLOAT_WORDS_BIG_ENDIAN) 5351 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD; 5352 else 5353 word = bitpos / BITS_PER_WORD; 5354 temp = operand_subword_force (temp, word, fmode); 5355 bitpos = bitpos % BITS_PER_WORD; 5356 } 5357 5358 /* Force the intermediate word_mode (or narrower) result into a 5359 register. This avoids attempting to create paradoxical SUBREGs 5360 of floating point modes below. */ 5361 temp = force_reg (imode, temp); 5362 5363 /* If the bitpos is within the "result mode" lowpart, the operation 5364 can be implement with a single bitwise AND. Otherwise, we need 5365 a right shift and an AND. */ 5366 5367 if (bitpos < GET_MODE_BITSIZE (rmode)) 5368 { 5369 if (bitpos < HOST_BITS_PER_WIDE_INT) 5370 { 5371 hi = 0; 5372 lo = (HOST_WIDE_INT) 1 << bitpos; 5373 } 5374 else 5375 { 5376 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT); 5377 lo = 0; 5378 } 5379 5380 if (imode != rmode) 5381 temp = gen_lowpart (rmode, temp); 5382 temp = expand_binop (rmode, and_optab, temp, 5383 immed_double_const (lo, hi, rmode), 5384 NULL_RTX, 1, OPTAB_LIB_WIDEN); 5385 } 5386 else 5387 { 5388 /* Perform a logical right shift to place the signbit in the least 5389 significant bit, then truncate the result to the desired mode 5390 and mask just this bit. */ 5391 temp = expand_shift (RSHIFT_EXPR, imode, temp, 5392 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1); 5393 temp = gen_lowpart (rmode, temp); 5394 temp = expand_binop (rmode, and_optab, temp, const1_rtx, 5395 NULL_RTX, 1, OPTAB_LIB_WIDEN); 5396 } 5397 5398 return temp; 5399} 5400 5401/* Expand fork or exec calls. TARGET is the desired target of the 5402 call. ARGLIST is the list of arguments of the call. FN is the 5403 identificator of the actual function. IGNORE is nonzero if the 5404 value is to be ignored. */ 5405 5406static rtx 5407expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore) 5408{ 5409 tree id, decl; 5410 tree call; 5411 5412 /* If we are not profiling, just call the function. */ 5413 if (!profile_arc_flag) 5414 return NULL_RTX; 5415 5416 /* Otherwise call the wrapper. This should be equivalent for the rest of 5417 compiler, so the code does not diverge, and the wrapper may run the 5418 code necessary for keeping the profiling sane. */ 5419 5420 switch (DECL_FUNCTION_CODE (fn)) 5421 { 5422 case BUILT_IN_FORK: 5423 id = get_identifier ("__gcov_fork"); 5424 break; 5425 5426 case BUILT_IN_EXECL: 5427 id = get_identifier ("__gcov_execl"); 5428 break; 5429 5430 case BUILT_IN_EXECV: 5431 id = get_identifier ("__gcov_execv"); 5432 break; 5433 5434 case BUILT_IN_EXECLP: 5435 id = get_identifier ("__gcov_execlp"); 5436 break; 5437 5438 case BUILT_IN_EXECLE: 5439 id = get_identifier ("__gcov_execle"); 5440 break; 5441 5442 case BUILT_IN_EXECVP: 5443 id = get_identifier ("__gcov_execvp"); 5444 break; 5445 5446 case BUILT_IN_EXECVE: 5447 id = get_identifier ("__gcov_execve"); 5448 break; 5449 5450 default: 5451 gcc_unreachable (); 5452 } 5453 5454 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn)); 5455 DECL_EXTERNAL (decl) = 1; 5456 TREE_PUBLIC (decl) = 1; 5457 DECL_ARTIFICIAL (decl) = 1; 5458 TREE_NOTHROW (decl) = 1; 5459 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; 5460 DECL_VISIBILITY_SPECIFIED (decl) = 1; 5461 call = build_function_call_expr (decl, arglist); 5462 5463 return expand_call (call, target, ignore); 5464} 5465 5466 5467/* Reconstitute a mode for a __sync intrinsic operation. Since the type of 5468 the pointer in these functions is void*, the tree optimizers may remove 5469 casts. The mode computed in expand_builtin isn't reliable either, due 5470 to __sync_bool_compare_and_swap. 5471 5472 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the 5473 group of builtins. This gives us log2 of the mode size. */ 5474 5475static inline enum machine_mode 5476get_builtin_sync_mode (int fcode_diff) 5477{ 5478 /* The size is not negotiable, so ask not to get BLKmode in return 5479 if the target indicates that a smaller size would be better. */ 5480 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0); 5481} 5482 5483/* Expand the memory expression LOC and return the appropriate memory operand 5484 for the builtin_sync operations. */ 5485 5486static rtx 5487get_builtin_sync_mem (tree loc, enum machine_mode mode) 5488{ 5489 rtx addr, mem; 5490 5491 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM); 5492 5493 /* Note that we explicitly do not want any alias information for this 5494 memory, so that we kill all other live memories. Otherwise we don't 5495 satisfy the full barrier semantics of the intrinsic. */ 5496 mem = validize_mem (gen_rtx_MEM (mode, addr)); 5497 5498 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT)); 5499 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); 5500 MEM_VOLATILE_P (mem) = 1; 5501 5502 return mem; 5503} 5504 5505/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics. 5506 ARGLIST is the operands list to the function. CODE is the rtx code 5507 that corresponds to the arithmetic or logical operation from the name; 5508 an exception here is that NOT actually means NAND. TARGET is an optional 5509 place for us to store the results; AFTER is true if this is the 5510 fetch_and_xxx form. IGNORE is true if we don't actually care about 5511 the result of the operation at all. */ 5512 5513static rtx 5514expand_builtin_sync_operation (enum machine_mode mode, tree arglist, 5515 enum rtx_code code, bool after, 5516 rtx target, bool ignore) 5517{ 5518 rtx val, mem; 5519 enum machine_mode old_mode; 5520 5521 /* Expand the operands. */ 5522 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode); 5523 5524 arglist = TREE_CHAIN (arglist); 5525 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL); 5526 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5527 of CONST_INTs, where we know the old_mode only from the call argument. */ 5528 old_mode = GET_MODE (val); 5529 if (old_mode == VOIDmode) 5530 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))); 5531 val = convert_modes (mode, old_mode, val, 1); 5532 5533 if (ignore) 5534 return expand_sync_operation (mem, val, code); 5535 else 5536 return expand_sync_fetch_operation (mem, val, code, after, target); 5537} 5538 5539/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap 5540 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is 5541 true if this is the boolean form. TARGET is a place for us to store the 5542 results; this is NOT optional if IS_BOOL is true. */ 5543 5544static rtx 5545expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist, 5546 bool is_bool, rtx target) 5547{ 5548 rtx old_val, new_val, mem; 5549 enum machine_mode old_mode; 5550 5551 /* Expand the operands. */ 5552 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode); 5553 5554 arglist = TREE_CHAIN (arglist); 5555 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL); 5556 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5557 of CONST_INTs, where we know the old_mode only from the call argument. */ 5558 old_mode = GET_MODE (old_val); 5559 if (old_mode == VOIDmode) 5560 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))); 5561 old_val = convert_modes (mode, old_mode, old_val, 1); 5562 5563 arglist = TREE_CHAIN (arglist); 5564 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL); 5565 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5566 of CONST_INTs, where we know the old_mode only from the call argument. */ 5567 old_mode = GET_MODE (new_val); 5568 if (old_mode == VOIDmode) 5569 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))); 5570 new_val = convert_modes (mode, old_mode, new_val, 1); 5571 5572 if (is_bool) 5573 return expand_bool_compare_and_swap (mem, old_val, new_val, target); 5574 else 5575 return expand_val_compare_and_swap (mem, old_val, new_val, target); 5576} 5577 5578/* Expand the __sync_lock_test_and_set intrinsic. Note that the most 5579 general form is actually an atomic exchange, and some targets only 5580 support a reduced form with the second argument being a constant 1. 5581 ARGLIST is the operands list to the function; TARGET is an optional 5582 place for us to store the results. */ 5583 5584static rtx 5585expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist, 5586 rtx target) 5587{ 5588 rtx val, mem; 5589 enum machine_mode old_mode; 5590 5591 /* Expand the operands. */ 5592 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode); 5593 5594 arglist = TREE_CHAIN (arglist); 5595 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL); 5596 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care 5597 of CONST_INTs, where we know the old_mode only from the call argument. */ 5598 old_mode = GET_MODE (val); 5599 if (old_mode == VOIDmode) 5600 old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))); 5601 val = convert_modes (mode, old_mode, val, 1); 5602 5603 return expand_sync_lock_test_and_set (mem, val, target); 5604} 5605 5606/* Expand the __sync_synchronize intrinsic. */ 5607 5608static void 5609expand_builtin_synchronize (void) 5610{ 5611 tree x; 5612 5613#ifdef HAVE_memory_barrier 5614 if (HAVE_memory_barrier) 5615 { 5616 emit_insn (gen_memory_barrier ()); 5617 return; 5618 } 5619#endif 5620 5621 /* If no explicit memory barrier instruction is available, create an 5622 empty asm stmt with a memory clobber. */ 5623 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL, 5624 tree_cons (NULL, build_string (6, "memory"), NULL)); 5625 ASM_VOLATILE_P (x) = 1; 5626 expand_asm_expr (x); 5627} 5628 5629/* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list 5630 to the function. */ 5631 5632static void 5633expand_builtin_lock_release (enum machine_mode mode, tree arglist) 5634{ 5635 enum insn_code icode; 5636 rtx mem, insn; 5637 rtx val = const0_rtx; 5638 5639 /* Expand the operands. */ 5640 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode); 5641 5642 /* If there is an explicit operation in the md file, use it. */ 5643 icode = sync_lock_release[mode]; 5644 if (icode != CODE_FOR_nothing) 5645 { 5646 if (!insn_data[icode].operand[1].predicate (val, mode)) 5647 val = force_reg (mode, val); 5648 5649 insn = GEN_FCN (icode) (mem, val); 5650 if (insn) 5651 { 5652 emit_insn (insn); 5653 return; 5654 } 5655 } 5656 5657 /* Otherwise we can implement this operation by emitting a barrier 5658 followed by a store of zero. */ 5659 expand_builtin_synchronize (); 5660 emit_move_insn (mem, val); 5661} 5662 5663/* Expand an expression EXP that calls a built-in function, 5664 with result going to TARGET if that's convenient 5665 (and in mode MODE if that's convenient). 5666 SUBTARGET may be used as the target for computing one of EXP's operands. 5667 IGNORE is nonzero if the value is to be ignored. */ 5668 5669rtx 5670expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, 5671 int ignore) 5672{ 5673 tree fndecl = get_callee_fndecl (exp); 5674 tree arglist = TREE_OPERAND (exp, 1); 5675 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 5676 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp)); 5677 5678 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 5679 return targetm.expand_builtin (exp, target, subtarget, mode, ignore); 5680 5681 /* When not optimizing, generate calls to library functions for a certain 5682 set of builtins. */ 5683 if (!optimize 5684 && !called_as_built_in (fndecl) 5685 && DECL_ASSEMBLER_NAME_SET_P (fndecl) 5686 && fcode != BUILT_IN_ALLOCA) 5687 return expand_call (exp, target, ignore); 5688 5689 /* The built-in function expanders test for target == const0_rtx 5690 to determine whether the function's result will be ignored. */ 5691 if (ignore) 5692 target = const0_rtx; 5693 5694 /* If the result of a pure or const built-in function is ignored, and 5695 none of its arguments are volatile, we can avoid expanding the 5696 built-in call and just evaluate the arguments for side-effects. */ 5697 if (target == const0_rtx 5698 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl))) 5699 { 5700 bool volatilep = false; 5701 tree arg; 5702 5703 for (arg = arglist; arg; arg = TREE_CHAIN (arg)) 5704 if (TREE_THIS_VOLATILE (TREE_VALUE (arg))) 5705 { 5706 volatilep = true; 5707 break; 5708 } 5709 5710 if (! volatilep) 5711 { 5712 for (arg = arglist; arg; arg = TREE_CHAIN (arg)) 5713 expand_expr (TREE_VALUE (arg), const0_rtx, 5714 VOIDmode, EXPAND_NORMAL); 5715 return const0_rtx; 5716 } 5717 } 5718 5719 switch (fcode) 5720 { 5721 CASE_FLT_FN (BUILT_IN_FABS): 5722 target = expand_builtin_fabs (arglist, target, subtarget); 5723 if (target) 5724 return target; 5725 break; 5726 5727 CASE_FLT_FN (BUILT_IN_COPYSIGN): 5728 target = expand_builtin_copysign (arglist, target, subtarget); 5729 if (target) 5730 return target; 5731 break; 5732 5733 /* Just do a normal library call if we were unable to fold 5734 the values. */ 5735 CASE_FLT_FN (BUILT_IN_CABS): 5736 break; 5737 5738 CASE_FLT_FN (BUILT_IN_EXP): 5739 CASE_FLT_FN (BUILT_IN_EXP10): 5740 CASE_FLT_FN (BUILT_IN_POW10): 5741 CASE_FLT_FN (BUILT_IN_EXP2): 5742 CASE_FLT_FN (BUILT_IN_EXPM1): 5743 CASE_FLT_FN (BUILT_IN_LOGB): 5744 CASE_FLT_FN (BUILT_IN_ILOGB): 5745 CASE_FLT_FN (BUILT_IN_LOG): 5746 CASE_FLT_FN (BUILT_IN_LOG10): 5747 CASE_FLT_FN (BUILT_IN_LOG2): 5748 CASE_FLT_FN (BUILT_IN_LOG1P): 5749 CASE_FLT_FN (BUILT_IN_TAN): 5750 CASE_FLT_FN (BUILT_IN_ASIN): 5751 CASE_FLT_FN (BUILT_IN_ACOS): 5752 CASE_FLT_FN (BUILT_IN_ATAN): 5753 /* Treat these like sqrt only if unsafe math optimizations are allowed, 5754 because of possible accuracy problems. */ 5755 if (! flag_unsafe_math_optimizations) 5756 break; 5757 CASE_FLT_FN (BUILT_IN_SQRT): 5758 CASE_FLT_FN (BUILT_IN_FLOOR): 5759 CASE_FLT_FN (BUILT_IN_CEIL): 5760 CASE_FLT_FN (BUILT_IN_TRUNC): 5761 CASE_FLT_FN (BUILT_IN_ROUND): 5762 CASE_FLT_FN (BUILT_IN_NEARBYINT): 5763 CASE_FLT_FN (BUILT_IN_RINT): 5764 CASE_FLT_FN (BUILT_IN_LRINT): 5765 CASE_FLT_FN (BUILT_IN_LLRINT): 5766 target = expand_builtin_mathfn (exp, target, subtarget); 5767 if (target) 5768 return target; 5769 break; 5770 5771 CASE_FLT_FN (BUILT_IN_LCEIL): 5772 CASE_FLT_FN (BUILT_IN_LLCEIL): 5773 CASE_FLT_FN (BUILT_IN_LFLOOR): 5774 CASE_FLT_FN (BUILT_IN_LLFLOOR): 5775 target = expand_builtin_int_roundingfn (exp, target, subtarget); 5776 if (target) 5777 return target; 5778 break; 5779 5780 CASE_FLT_FN (BUILT_IN_POW): 5781 target = expand_builtin_pow (exp, target, subtarget); 5782 if (target) 5783 return target; 5784 break; 5785 5786 CASE_FLT_FN (BUILT_IN_POWI): 5787 target = expand_builtin_powi (exp, target, subtarget); 5788 if (target) 5789 return target; 5790 break; 5791 5792 CASE_FLT_FN (BUILT_IN_ATAN2): 5793 CASE_FLT_FN (BUILT_IN_LDEXP): 5794 CASE_FLT_FN (BUILT_IN_FMOD): 5795 CASE_FLT_FN (BUILT_IN_DREM): 5796 if (! flag_unsafe_math_optimizations) 5797 break; 5798 target = expand_builtin_mathfn_2 (exp, target, subtarget); 5799 if (target) 5800 return target; 5801 break; 5802 5803 CASE_FLT_FN (BUILT_IN_SIN): 5804 CASE_FLT_FN (BUILT_IN_COS): 5805 if (! flag_unsafe_math_optimizations) 5806 break; 5807 target = expand_builtin_mathfn_3 (exp, target, subtarget); 5808 if (target) 5809 return target; 5810 break; 5811 5812 CASE_FLT_FN (BUILT_IN_SINCOS): 5813 if (! flag_unsafe_math_optimizations) 5814 break; 5815 target = expand_builtin_sincos (exp); 5816 if (target) 5817 return target; 5818 break; 5819 5820 case BUILT_IN_APPLY_ARGS: 5821 return expand_builtin_apply_args (); 5822 5823 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes 5824 FUNCTION with a copy of the parameters described by 5825 ARGUMENTS, and ARGSIZE. It returns a block of memory 5826 allocated on the stack into which is stored all the registers 5827 that might possibly be used for returning the result of a 5828 function. ARGUMENTS is the value returned by 5829 __builtin_apply_args. ARGSIZE is the number of bytes of 5830 arguments that must be copied. ??? How should this value be 5831 computed? We'll also need a safe worst case value for varargs 5832 functions. */ 5833 case BUILT_IN_APPLY: 5834 if (!validate_arglist (arglist, POINTER_TYPE, 5835 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE) 5836 && !validate_arglist (arglist, REFERENCE_TYPE, 5837 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 5838 return const0_rtx; 5839 else 5840 { 5841 int i; 5842 tree t; 5843 rtx ops[3]; 5844 5845 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++) 5846 ops[i] = expand_normal (TREE_VALUE (t)); 5847 5848 return expand_builtin_apply (ops[0], ops[1], ops[2]); 5849 } 5850 5851 /* __builtin_return (RESULT) causes the function to return the 5852 value described by RESULT. RESULT is address of the block of 5853 memory returned by __builtin_apply. */ 5854 case BUILT_IN_RETURN: 5855 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 5856 expand_builtin_return (expand_normal (TREE_VALUE (arglist))); 5857 return const0_rtx; 5858 5859 case BUILT_IN_SAVEREGS: 5860 return expand_builtin_saveregs (); 5861 5862 case BUILT_IN_ARGS_INFO: 5863 return expand_builtin_args_info (arglist); 5864 5865 /* Return the address of the first anonymous stack arg. */ 5866 case BUILT_IN_NEXT_ARG: 5867 if (fold_builtin_next_arg (arglist)) 5868 return const0_rtx; 5869 return expand_builtin_next_arg (); 5870 5871 case BUILT_IN_CLASSIFY_TYPE: 5872 return expand_builtin_classify_type (arglist); 5873 5874 case BUILT_IN_CONSTANT_P: 5875 return const0_rtx; 5876 5877 case BUILT_IN_FRAME_ADDRESS: 5878 case BUILT_IN_RETURN_ADDRESS: 5879 return expand_builtin_frame_address (fndecl, arglist); 5880 5881 /* Returns the address of the area where the structure is returned. 5882 0 otherwise. */ 5883 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: 5884 if (arglist != 0 5885 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))) 5886 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl)))) 5887 return const0_rtx; 5888 else 5889 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0); 5890 5891 case BUILT_IN_ALLOCA: 5892 target = expand_builtin_alloca (arglist, target); 5893 if (target) 5894 return target; 5895 break; 5896 5897 case BUILT_IN_STACK_SAVE: 5898 return expand_stack_save (); 5899 5900 case BUILT_IN_STACK_RESTORE: 5901 expand_stack_restore (TREE_VALUE (arglist)); 5902 return const0_rtx; 5903 5904 case BUILT_IN_BSWAP32: 5905 case BUILT_IN_BSWAP64: 5906 target = expand_builtin_bswap (arglist, target, subtarget); 5907 5908 if (target) 5909 return target; 5910 break; 5911 5912 CASE_INT_FN (BUILT_IN_FFS): 5913 case BUILT_IN_FFSIMAX: 5914 target = expand_builtin_unop (target_mode, arglist, target, 5915 subtarget, ffs_optab); 5916 if (target) 5917 return target; 5918 break; 5919 5920 CASE_INT_FN (BUILT_IN_CLZ): 5921 case BUILT_IN_CLZIMAX: 5922 target = expand_builtin_unop (target_mode, arglist, target, 5923 subtarget, clz_optab); 5924 if (target) 5925 return target; 5926 break; 5927 5928 CASE_INT_FN (BUILT_IN_CTZ): 5929 case BUILT_IN_CTZIMAX: 5930 target = expand_builtin_unop (target_mode, arglist, target, 5931 subtarget, ctz_optab); 5932 if (target) 5933 return target; 5934 break; 5935 5936 CASE_INT_FN (BUILT_IN_POPCOUNT): 5937 case BUILT_IN_POPCOUNTIMAX: 5938 target = expand_builtin_unop (target_mode, arglist, target, 5939 subtarget, popcount_optab); 5940 if (target) 5941 return target; 5942 break; 5943 5944 CASE_INT_FN (BUILT_IN_PARITY): 5945 case BUILT_IN_PARITYIMAX: 5946 target = expand_builtin_unop (target_mode, arglist, target, 5947 subtarget, parity_optab); 5948 if (target) 5949 return target; 5950 break; 5951 5952 case BUILT_IN_STRLEN: 5953 target = expand_builtin_strlen (arglist, target, target_mode); 5954 if (target) 5955 return target; 5956 break; 5957 5958 case BUILT_IN_STRCPY: 5959 target = expand_builtin_strcpy (fndecl, arglist, target, mode); 5960 if (target) 5961 return target; 5962 break; 5963 5964 case BUILT_IN_STRNCPY: 5965 target = expand_builtin_strncpy (exp, target, mode); 5966 if (target) 5967 return target; 5968 break; 5969 5970 case BUILT_IN_STPCPY: 5971 target = expand_builtin_stpcpy (exp, target, mode); 5972 if (target) 5973 return target; 5974 break; 5975 5976 case BUILT_IN_STRCAT: 5977 target = expand_builtin_strcat (fndecl, arglist, target, mode); 5978 if (target) 5979 return target; 5980 break; 5981 5982 case BUILT_IN_STRNCAT: 5983 target = expand_builtin_strncat (arglist, target, mode); 5984 if (target) 5985 return target; 5986 break; 5987 5988 case BUILT_IN_STRSPN: 5989 target = expand_builtin_strspn (arglist, target, mode); 5990 if (target) 5991 return target; 5992 break; 5993 5994 case BUILT_IN_STRCSPN: 5995 target = expand_builtin_strcspn (arglist, target, mode); 5996 if (target) 5997 return target; 5998 break; 5999 6000 case BUILT_IN_STRSTR: 6001 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode); 6002 if (target) 6003 return target; 6004 break; 6005 6006 case BUILT_IN_STRPBRK: 6007 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode); 6008 if (target) 6009 return target; 6010 break; 6011 6012 case BUILT_IN_INDEX: 6013 case BUILT_IN_STRCHR: 6014 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode); 6015 if (target) 6016 return target; 6017 break; 6018 6019 case BUILT_IN_RINDEX: 6020 case BUILT_IN_STRRCHR: 6021 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode); 6022 if (target) 6023 return target; 6024 break; 6025 6026 case BUILT_IN_MEMCPY: 6027 target = expand_builtin_memcpy (exp, target, mode); 6028 if (target) 6029 return target; 6030 break; 6031 6032 case BUILT_IN_MEMPCPY: 6033 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1); 6034 if (target) 6035 return target; 6036 break; 6037 6038 case BUILT_IN_MEMMOVE: 6039 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target, 6040 mode, exp); 6041 if (target) 6042 return target; 6043 break; 6044 6045 case BUILT_IN_BCOPY: 6046 target = expand_builtin_bcopy (exp); 6047 if (target) 6048 return target; 6049 break; 6050 6051 case BUILT_IN_MEMSET: 6052 target = expand_builtin_memset (arglist, target, mode, exp); 6053 if (target) 6054 return target; 6055 break; 6056 6057 case BUILT_IN_BZERO: 6058 target = expand_builtin_bzero (exp); 6059 if (target) 6060 return target; 6061 break; 6062 6063 case BUILT_IN_STRCMP: 6064 target = expand_builtin_strcmp (exp, target, mode); 6065 if (target) 6066 return target; 6067 break; 6068 6069 case BUILT_IN_STRNCMP: 6070 target = expand_builtin_strncmp (exp, target, mode); 6071 if (target) 6072 return target; 6073 break; 6074 6075 case BUILT_IN_BCMP: 6076 case BUILT_IN_MEMCMP: 6077 target = expand_builtin_memcmp (exp, arglist, target, mode); 6078 if (target) 6079 return target; 6080 break; 6081 6082 case BUILT_IN_SETJMP: 6083 /* This should have been lowered to the builtins below. */ 6084 gcc_unreachable (); 6085 6086 case BUILT_IN_SETJMP_SETUP: 6087 /* __builtin_setjmp_setup is passed a pointer to an array of five words 6088 and the receiver label. */ 6089 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 6090 { 6091 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget, 6092 VOIDmode, EXPAND_NORMAL); 6093 tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0); 6094 rtx label_r = label_rtx (label); 6095 6096 /* This is copied from the handling of non-local gotos. */ 6097 expand_builtin_setjmp_setup (buf_addr, label_r); 6098 nonlocal_goto_handler_labels 6099 = gen_rtx_EXPR_LIST (VOIDmode, label_r, 6100 nonlocal_goto_handler_labels); 6101 /* ??? Do not let expand_label treat us as such since we would 6102 not want to be both on the list of non-local labels and on 6103 the list of forced labels. */ 6104 FORCED_LABEL (label) = 0; 6105 return const0_rtx; 6106 } 6107 break; 6108 6109 case BUILT_IN_SETJMP_DISPATCHER: 6110 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */ 6111 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6112 { 6113 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0); 6114 rtx label_r = label_rtx (label); 6115 6116 /* Remove the dispatcher label from the list of non-local labels 6117 since the receiver labels have been added to it above. */ 6118 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels); 6119 return const0_rtx; 6120 } 6121 break; 6122 6123 case BUILT_IN_SETJMP_RECEIVER: 6124 /* __builtin_setjmp_receiver is passed the receiver label. */ 6125 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6126 { 6127 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0); 6128 rtx label_r = label_rtx (label); 6129 6130 expand_builtin_setjmp_receiver (label_r); 6131 return const0_rtx; 6132 } 6133 break; 6134 6135 /* __builtin_longjmp is passed a pointer to an array of five words. 6136 It's similar to the C library longjmp function but works with 6137 __builtin_setjmp above. */ 6138 case BUILT_IN_LONGJMP: 6139 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6140 { 6141 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget, 6142 VOIDmode, EXPAND_NORMAL); 6143 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist))); 6144 6145 if (value != const1_rtx) 6146 { 6147 error ("%<__builtin_longjmp%> second argument must be 1"); 6148 return const0_rtx; 6149 } 6150 6151 expand_builtin_longjmp (buf_addr, value); 6152 return const0_rtx; 6153 } 6154 break; 6155 6156 case BUILT_IN_NONLOCAL_GOTO: 6157 target = expand_builtin_nonlocal_goto (arglist); 6158 if (target) 6159 return target; 6160 break; 6161 6162 /* This updates the setjmp buffer that is its argument with the value 6163 of the current stack pointer. */ 6164 case BUILT_IN_UPDATE_SETJMP_BUF: 6165 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6166 { 6167 rtx buf_addr 6168 = expand_normal (TREE_VALUE (arglist)); 6169 6170 expand_builtin_update_setjmp_buf (buf_addr); 6171 return const0_rtx; 6172 } 6173 break; 6174 6175 case BUILT_IN_TRAP: 6176 expand_builtin_trap (); 6177 return const0_rtx; 6178 6179 case BUILT_IN_PRINTF: 6180 target = expand_builtin_printf (exp, target, mode, false); 6181 if (target) 6182 return target; 6183 break; 6184 6185 case BUILT_IN_PRINTF_UNLOCKED: 6186 target = expand_builtin_printf (exp, target, mode, true); 6187 if (target) 6188 return target; 6189 break; 6190 6191 case BUILT_IN_FPUTS: 6192 target = expand_builtin_fputs (arglist, target, false); 6193 if (target) 6194 return target; 6195 break; 6196 case BUILT_IN_FPUTS_UNLOCKED: 6197 target = expand_builtin_fputs (arglist, target, true); 6198 if (target) 6199 return target; 6200 break; 6201 6202 case BUILT_IN_FPRINTF: 6203 target = expand_builtin_fprintf (exp, target, mode, false); 6204 if (target) 6205 return target; 6206 break; 6207 6208 case BUILT_IN_FPRINTF_UNLOCKED: 6209 target = expand_builtin_fprintf (exp, target, mode, true); 6210 if (target) 6211 return target; 6212 break; 6213 6214 case BUILT_IN_SPRINTF: 6215 target = expand_builtin_sprintf (arglist, target, mode); 6216 if (target) 6217 return target; 6218 break; 6219 6220 CASE_FLT_FN (BUILT_IN_SIGNBIT): 6221 target = expand_builtin_signbit (exp, target); 6222 if (target) 6223 return target; 6224 break; 6225 6226 /* Various hooks for the DWARF 2 __throw routine. */ 6227 case BUILT_IN_UNWIND_INIT: 6228 expand_builtin_unwind_init (); 6229 return const0_rtx; 6230 case BUILT_IN_DWARF_CFA: 6231 return virtual_cfa_rtx; 6232#ifdef DWARF2_UNWIND_INFO 6233 case BUILT_IN_DWARF_SP_COLUMN: 6234 return expand_builtin_dwarf_sp_column (); 6235 case BUILT_IN_INIT_DWARF_REG_SIZES: 6236 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist)); 6237 return const0_rtx; 6238#endif 6239 case BUILT_IN_FROB_RETURN_ADDR: 6240 return expand_builtin_frob_return_addr (TREE_VALUE (arglist)); 6241 case BUILT_IN_EXTRACT_RETURN_ADDR: 6242 return expand_builtin_extract_return_addr (TREE_VALUE (arglist)); 6243 case BUILT_IN_EH_RETURN: 6244 expand_builtin_eh_return (TREE_VALUE (arglist), 6245 TREE_VALUE (TREE_CHAIN (arglist))); 6246 return const0_rtx; 6247#ifdef EH_RETURN_DATA_REGNO 6248 case BUILT_IN_EH_RETURN_DATA_REGNO: 6249 return expand_builtin_eh_return_data_regno (arglist); 6250#endif 6251 case BUILT_IN_EXTEND_POINTER: 6252 return expand_builtin_extend_pointer (TREE_VALUE (arglist)); 6253 6254 case BUILT_IN_VA_START: 6255 case BUILT_IN_STDARG_START: 6256 return expand_builtin_va_start (arglist); 6257 case BUILT_IN_VA_END: 6258 return expand_builtin_va_end (arglist); 6259 case BUILT_IN_VA_COPY: 6260 return expand_builtin_va_copy (arglist); 6261 case BUILT_IN_EXPECT: 6262 return expand_builtin_expect (arglist, target); 6263 case BUILT_IN_PREFETCH: 6264 expand_builtin_prefetch (arglist); 6265 return const0_rtx; 6266 6267 case BUILT_IN_PROFILE_FUNC_ENTER: 6268 return expand_builtin_profile_func (false); 6269 case BUILT_IN_PROFILE_FUNC_EXIT: 6270 return expand_builtin_profile_func (true); 6271 6272 case BUILT_IN_INIT_TRAMPOLINE: 6273 return expand_builtin_init_trampoline (arglist); 6274 case BUILT_IN_ADJUST_TRAMPOLINE: 6275 return expand_builtin_adjust_trampoline (arglist); 6276 6277 case BUILT_IN_FORK: 6278 case BUILT_IN_EXECL: 6279 case BUILT_IN_EXECV: 6280 case BUILT_IN_EXECLP: 6281 case BUILT_IN_EXECLE: 6282 case BUILT_IN_EXECVP: 6283 case BUILT_IN_EXECVE: 6284 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore); 6285 if (target) 6286 return target; 6287 break; 6288 6289 case BUILT_IN_FETCH_AND_ADD_1: 6290 case BUILT_IN_FETCH_AND_ADD_2: 6291 case BUILT_IN_FETCH_AND_ADD_4: 6292 case BUILT_IN_FETCH_AND_ADD_8: 6293 case BUILT_IN_FETCH_AND_ADD_16: 6294 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1); 6295 target = expand_builtin_sync_operation (mode, arglist, PLUS, 6296 false, target, ignore); 6297 if (target) 6298 return target; 6299 break; 6300 6301 case BUILT_IN_FETCH_AND_SUB_1: 6302 case BUILT_IN_FETCH_AND_SUB_2: 6303 case BUILT_IN_FETCH_AND_SUB_4: 6304 case BUILT_IN_FETCH_AND_SUB_8: 6305 case BUILT_IN_FETCH_AND_SUB_16: 6306 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1); 6307 target = expand_builtin_sync_operation (mode, arglist, MINUS, 6308 false, target, ignore); 6309 if (target) 6310 return target; 6311 break; 6312 6313 case BUILT_IN_FETCH_AND_OR_1: 6314 case BUILT_IN_FETCH_AND_OR_2: 6315 case BUILT_IN_FETCH_AND_OR_4: 6316 case BUILT_IN_FETCH_AND_OR_8: 6317 case BUILT_IN_FETCH_AND_OR_16: 6318 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1); 6319 target = expand_builtin_sync_operation (mode, arglist, IOR, 6320 false, target, ignore); 6321 if (target) 6322 return target; 6323 break; 6324 6325 case BUILT_IN_FETCH_AND_AND_1: 6326 case BUILT_IN_FETCH_AND_AND_2: 6327 case BUILT_IN_FETCH_AND_AND_4: 6328 case BUILT_IN_FETCH_AND_AND_8: 6329 case BUILT_IN_FETCH_AND_AND_16: 6330 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1); 6331 target = expand_builtin_sync_operation (mode, arglist, AND, 6332 false, target, ignore); 6333 if (target) 6334 return target; 6335 break; 6336 6337 case BUILT_IN_FETCH_AND_XOR_1: 6338 case BUILT_IN_FETCH_AND_XOR_2: 6339 case BUILT_IN_FETCH_AND_XOR_4: 6340 case BUILT_IN_FETCH_AND_XOR_8: 6341 case BUILT_IN_FETCH_AND_XOR_16: 6342 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1); 6343 target = expand_builtin_sync_operation (mode, arglist, XOR, 6344 false, target, ignore); 6345 if (target) 6346 return target; 6347 break; 6348 6349 case BUILT_IN_FETCH_AND_NAND_1: 6350 case BUILT_IN_FETCH_AND_NAND_2: 6351 case BUILT_IN_FETCH_AND_NAND_4: 6352 case BUILT_IN_FETCH_AND_NAND_8: 6353 case BUILT_IN_FETCH_AND_NAND_16: 6354 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1); 6355 target = expand_builtin_sync_operation (mode, arglist, NOT, 6356 false, target, ignore); 6357 if (target) 6358 return target; 6359 break; 6360 6361 case BUILT_IN_ADD_AND_FETCH_1: 6362 case BUILT_IN_ADD_AND_FETCH_2: 6363 case BUILT_IN_ADD_AND_FETCH_4: 6364 case BUILT_IN_ADD_AND_FETCH_8: 6365 case BUILT_IN_ADD_AND_FETCH_16: 6366 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1); 6367 target = expand_builtin_sync_operation (mode, arglist, PLUS, 6368 true, target, ignore); 6369 if (target) 6370 return target; 6371 break; 6372 6373 case BUILT_IN_SUB_AND_FETCH_1: 6374 case BUILT_IN_SUB_AND_FETCH_2: 6375 case BUILT_IN_SUB_AND_FETCH_4: 6376 case BUILT_IN_SUB_AND_FETCH_8: 6377 case BUILT_IN_SUB_AND_FETCH_16: 6378 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1); 6379 target = expand_builtin_sync_operation (mode, arglist, MINUS, 6380 true, target, ignore); 6381 if (target) 6382 return target; 6383 break; 6384 6385 case BUILT_IN_OR_AND_FETCH_1: 6386 case BUILT_IN_OR_AND_FETCH_2: 6387 case BUILT_IN_OR_AND_FETCH_4: 6388 case BUILT_IN_OR_AND_FETCH_8: 6389 case BUILT_IN_OR_AND_FETCH_16: 6390 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1); 6391 target = expand_builtin_sync_operation (mode, arglist, IOR, 6392 true, target, ignore); 6393 if (target) 6394 return target; 6395 break; 6396 6397 case BUILT_IN_AND_AND_FETCH_1: 6398 case BUILT_IN_AND_AND_FETCH_2: 6399 case BUILT_IN_AND_AND_FETCH_4: 6400 case BUILT_IN_AND_AND_FETCH_8: 6401 case BUILT_IN_AND_AND_FETCH_16: 6402 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1); 6403 target = expand_builtin_sync_operation (mode, arglist, AND, 6404 true, target, ignore); 6405 if (target) 6406 return target; 6407 break; 6408 6409 case BUILT_IN_XOR_AND_FETCH_1: 6410 case BUILT_IN_XOR_AND_FETCH_2: 6411 case BUILT_IN_XOR_AND_FETCH_4: 6412 case BUILT_IN_XOR_AND_FETCH_8: 6413 case BUILT_IN_XOR_AND_FETCH_16: 6414 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1); 6415 target = expand_builtin_sync_operation (mode, arglist, XOR, 6416 true, target, ignore); 6417 if (target) 6418 return target; 6419 break; 6420 6421 case BUILT_IN_NAND_AND_FETCH_1: 6422 case BUILT_IN_NAND_AND_FETCH_2: 6423 case BUILT_IN_NAND_AND_FETCH_4: 6424 case BUILT_IN_NAND_AND_FETCH_8: 6425 case BUILT_IN_NAND_AND_FETCH_16: 6426 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1); 6427 target = expand_builtin_sync_operation (mode, arglist, NOT, 6428 true, target, ignore); 6429 if (target) 6430 return target; 6431 break; 6432 6433 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1: 6434 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2: 6435 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4: 6436 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8: 6437 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16: 6438 if (mode == VOIDmode) 6439 mode = TYPE_MODE (boolean_type_node); 6440 if (!target || !register_operand (target, mode)) 6441 target = gen_reg_rtx (mode); 6442 6443 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1); 6444 target = expand_builtin_compare_and_swap (mode, arglist, true, target); 6445 if (target) 6446 return target; 6447 break; 6448 6449 case BUILT_IN_VAL_COMPARE_AND_SWAP_1: 6450 case BUILT_IN_VAL_COMPARE_AND_SWAP_2: 6451 case BUILT_IN_VAL_COMPARE_AND_SWAP_4: 6452 case BUILT_IN_VAL_COMPARE_AND_SWAP_8: 6453 case BUILT_IN_VAL_COMPARE_AND_SWAP_16: 6454 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1); 6455 target = expand_builtin_compare_and_swap (mode, arglist, false, target); 6456 if (target) 6457 return target; 6458 break; 6459 6460 case BUILT_IN_LOCK_TEST_AND_SET_1: 6461 case BUILT_IN_LOCK_TEST_AND_SET_2: 6462 case BUILT_IN_LOCK_TEST_AND_SET_4: 6463 case BUILT_IN_LOCK_TEST_AND_SET_8: 6464 case BUILT_IN_LOCK_TEST_AND_SET_16: 6465 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1); 6466 target = expand_builtin_lock_test_and_set (mode, arglist, target); 6467 if (target) 6468 return target; 6469 break; 6470 6471 case BUILT_IN_LOCK_RELEASE_1: 6472 case BUILT_IN_LOCK_RELEASE_2: 6473 case BUILT_IN_LOCK_RELEASE_4: 6474 case BUILT_IN_LOCK_RELEASE_8: 6475 case BUILT_IN_LOCK_RELEASE_16: 6476 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1); 6477 expand_builtin_lock_release (mode, arglist); 6478 return const0_rtx; 6479 6480 case BUILT_IN_SYNCHRONIZE: 6481 expand_builtin_synchronize (); 6482 return const0_rtx; 6483 6484 case BUILT_IN_OBJECT_SIZE: 6485 return expand_builtin_object_size (exp); 6486 6487 case BUILT_IN_MEMCPY_CHK: 6488 case BUILT_IN_MEMPCPY_CHK: 6489 case BUILT_IN_MEMMOVE_CHK: 6490 case BUILT_IN_MEMSET_CHK: 6491 target = expand_builtin_memory_chk (exp, target, mode, fcode); 6492 if (target) 6493 return target; 6494 break; 6495 6496 case BUILT_IN_STRCPY_CHK: 6497 case BUILT_IN_STPCPY_CHK: 6498 case BUILT_IN_STRNCPY_CHK: 6499 case BUILT_IN_STRCAT_CHK: 6500 case BUILT_IN_SNPRINTF_CHK: 6501 case BUILT_IN_VSNPRINTF_CHK: 6502 maybe_emit_chk_warning (exp, fcode); 6503 break; 6504 6505 case BUILT_IN_SPRINTF_CHK: 6506 case BUILT_IN_VSPRINTF_CHK: 6507 maybe_emit_sprintf_chk_warning (exp, fcode); 6508 break; 6509 6510 default: /* just do library call, if unknown builtin */ 6511 break; 6512 } 6513 6514 /* The switch statement above can drop through to cause the function 6515 to be called normally. */ 6516 return expand_call (exp, target, ignore); 6517} 6518 6519/* Determine whether a tree node represents a call to a built-in 6520 function. If the tree T is a call to a built-in function with 6521 the right number of arguments of the appropriate types, return 6522 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. 6523 Otherwise the return value is END_BUILTINS. */ 6524 6525enum built_in_function 6526builtin_mathfn_code (tree t) 6527{ 6528 tree fndecl, arglist, parmlist; 6529 tree argtype, parmtype; 6530 6531 if (TREE_CODE (t) != CALL_EXPR 6532 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR) 6533 return END_BUILTINS; 6534 6535 fndecl = get_callee_fndecl (t); 6536 if (fndecl == NULL_TREE 6537 || TREE_CODE (fndecl) != FUNCTION_DECL 6538 || ! DECL_BUILT_IN (fndecl) 6539 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 6540 return END_BUILTINS; 6541 6542 arglist = TREE_OPERAND (t, 1); 6543 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); 6544 for (; parmlist; parmlist = TREE_CHAIN (parmlist)) 6545 { 6546 /* If a function doesn't take a variable number of arguments, 6547 the last element in the list will have type `void'. */ 6548 parmtype = TREE_VALUE (parmlist); 6549 if (VOID_TYPE_P (parmtype)) 6550 { 6551 if (arglist) 6552 return END_BUILTINS; 6553 return DECL_FUNCTION_CODE (fndecl); 6554 } 6555 6556 if (! arglist) 6557 return END_BUILTINS; 6558 6559 argtype = TREE_TYPE (TREE_VALUE (arglist)); 6560 6561 if (SCALAR_FLOAT_TYPE_P (parmtype)) 6562 { 6563 if (! SCALAR_FLOAT_TYPE_P (argtype)) 6564 return END_BUILTINS; 6565 } 6566 else if (COMPLEX_FLOAT_TYPE_P (parmtype)) 6567 { 6568 if (! COMPLEX_FLOAT_TYPE_P (argtype)) 6569 return END_BUILTINS; 6570 } 6571 else if (POINTER_TYPE_P (parmtype)) 6572 { 6573 if (! POINTER_TYPE_P (argtype)) 6574 return END_BUILTINS; 6575 } 6576 else if (INTEGRAL_TYPE_P (parmtype)) 6577 { 6578 if (! INTEGRAL_TYPE_P (argtype)) 6579 return END_BUILTINS; 6580 } 6581 else 6582 return END_BUILTINS; 6583 6584 arglist = TREE_CHAIN (arglist); 6585 } 6586 6587 /* Variable-length argument list. */ 6588 return DECL_FUNCTION_CODE (fndecl); 6589} 6590 6591/* Fold a call to __builtin_constant_p, if we know it will evaluate to a 6592 constant. ARGLIST is the argument list of the call. */ 6593 6594static tree 6595fold_builtin_constant_p (tree arglist) 6596{ 6597 if (arglist == 0) 6598 return 0; 6599 6600 arglist = TREE_VALUE (arglist); 6601 6602 /* We return 1 for a numeric type that's known to be a constant 6603 value at compile-time or for an aggregate type that's a 6604 literal constant. */ 6605 STRIP_NOPS (arglist); 6606 6607 /* If we know this is a constant, emit the constant of one. */ 6608 if (CONSTANT_CLASS_P (arglist) 6609 || (TREE_CODE (arglist) == CONSTRUCTOR 6610 && TREE_CONSTANT (arglist))) 6611 return integer_one_node; 6612 if (TREE_CODE (arglist) == ADDR_EXPR) 6613 { 6614 tree op = TREE_OPERAND (arglist, 0); 6615 if (TREE_CODE (op) == STRING_CST 6616 || (TREE_CODE (op) == ARRAY_REF 6617 && integer_zerop (TREE_OPERAND (op, 1)) 6618 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST)) 6619 return integer_one_node; 6620 } 6621 6622 /* If this expression has side effects, show we don't know it to be a 6623 constant. Likewise if it's a pointer or aggregate type since in 6624 those case we only want literals, since those are only optimized 6625 when generating RTL, not later. 6626 And finally, if we are compiling an initializer, not code, we 6627 need to return a definite result now; there's not going to be any 6628 more optimization done. */ 6629 if (TREE_SIDE_EFFECTS (arglist) 6630 || AGGREGATE_TYPE_P (TREE_TYPE (arglist)) 6631 || POINTER_TYPE_P (TREE_TYPE (arglist)) 6632 || cfun == 0 6633 || folding_initializer) 6634 return integer_zero_node; 6635 6636 return 0; 6637} 6638 6639/* Fold a call to __builtin_expect, if we expect that a comparison against 6640 the argument will fold to a constant. In practice, this means a true 6641 constant or the address of a non-weak symbol. ARGLIST is the argument 6642 list of the call. */ 6643 6644static tree 6645fold_builtin_expect (tree arglist) 6646{ 6647 tree arg, inner; 6648 6649 if (arglist == 0) 6650 return 0; 6651 6652 arg = TREE_VALUE (arglist); 6653 6654 /* If the argument isn't invariant, then there's nothing we can do. */ 6655 if (!TREE_INVARIANT (arg)) 6656 return 0; 6657 6658 /* If we're looking at an address of a weak decl, then do not fold. */ 6659 inner = arg; 6660 STRIP_NOPS (inner); 6661 if (TREE_CODE (inner) == ADDR_EXPR) 6662 { 6663 do 6664 { 6665 inner = TREE_OPERAND (inner, 0); 6666 } 6667 while (TREE_CODE (inner) == COMPONENT_REF 6668 || TREE_CODE (inner) == ARRAY_REF); 6669 if (DECL_P (inner) && DECL_WEAK (inner)) 6670 return 0; 6671 } 6672 6673 /* Otherwise, ARG already has the proper type for the return value. */ 6674 return arg; 6675} 6676 6677/* Fold a call to __builtin_classify_type. */ 6678 6679static tree 6680fold_builtin_classify_type (tree arglist) 6681{ 6682 if (arglist == 0) 6683 return build_int_cst (NULL_TREE, no_type_class); 6684 6685 return build_int_cst (NULL_TREE, 6686 type_to_class (TREE_TYPE (TREE_VALUE (arglist)))); 6687} 6688 6689/* Fold a call to __builtin_strlen. */ 6690 6691static tree 6692fold_builtin_strlen (tree arglist) 6693{ 6694 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6695 return NULL_TREE; 6696 else 6697 { 6698 tree len = c_strlen (TREE_VALUE (arglist), 0); 6699 6700 if (len) 6701 { 6702 /* Convert from the internal "sizetype" type to "size_t". */ 6703 if (size_type_node) 6704 len = fold_convert (size_type_node, len); 6705 return len; 6706 } 6707 6708 return NULL_TREE; 6709 } 6710} 6711 6712/* Fold a call to __builtin_inf or __builtin_huge_val. */ 6713 6714static tree 6715fold_builtin_inf (tree type, int warn) 6716{ 6717 REAL_VALUE_TYPE real; 6718 6719 /* __builtin_inff is intended to be usable to define INFINITY on all 6720 targets. If an infinity is not available, INFINITY expands "to a 6721 positive constant of type float that overflows at translation 6722 time", footnote "In this case, using INFINITY will violate the 6723 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4). 6724 Thus we pedwarn to ensure this constraint violation is 6725 diagnosed. */ 6726 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn) 6727 pedwarn ("target format does not support infinity"); 6728 6729 real_inf (&real); 6730 return build_real (type, real); 6731} 6732 6733/* Fold a call to __builtin_nan or __builtin_nans. */ 6734 6735static tree 6736fold_builtin_nan (tree arglist, tree type, int quiet) 6737{ 6738 REAL_VALUE_TYPE real; 6739 const char *str; 6740 6741 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6742 return 0; 6743 str = c_getstr (TREE_VALUE (arglist)); 6744 if (!str) 6745 return 0; 6746 6747 if (!real_nan (&real, str, quiet, TYPE_MODE (type))) 6748 return 0; 6749 6750 return build_real (type, real); 6751} 6752 6753/* Return true if the floating point expression T has an integer value. 6754 We also allow +Inf, -Inf and NaN to be considered integer values. */ 6755 6756static bool 6757integer_valued_real_p (tree t) 6758{ 6759 switch (TREE_CODE (t)) 6760 { 6761 case FLOAT_EXPR: 6762 return true; 6763 6764 case ABS_EXPR: 6765 case SAVE_EXPR: 6766 case NON_LVALUE_EXPR: 6767 return integer_valued_real_p (TREE_OPERAND (t, 0)); 6768 6769 case COMPOUND_EXPR: 6770 case MODIFY_EXPR: 6771 case BIND_EXPR: 6772 return integer_valued_real_p (TREE_OPERAND (t, 1)); 6773 6774 case PLUS_EXPR: 6775 case MINUS_EXPR: 6776 case MULT_EXPR: 6777 case MIN_EXPR: 6778 case MAX_EXPR: 6779 return integer_valued_real_p (TREE_OPERAND (t, 0)) 6780 && integer_valued_real_p (TREE_OPERAND (t, 1)); 6781 6782 case COND_EXPR: 6783 return integer_valued_real_p (TREE_OPERAND (t, 1)) 6784 && integer_valued_real_p (TREE_OPERAND (t, 2)); 6785 6786 case REAL_CST: 6787 if (! TREE_CONSTANT_OVERFLOW (t)) 6788 { 6789 REAL_VALUE_TYPE c, cint; 6790 6791 c = TREE_REAL_CST (t); 6792 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c); 6793 return real_identical (&c, &cint); 6794 } 6795 break; 6796 6797 case NOP_EXPR: 6798 { 6799 tree type = TREE_TYPE (TREE_OPERAND (t, 0)); 6800 if (TREE_CODE (type) == INTEGER_TYPE) 6801 return true; 6802 if (TREE_CODE (type) == REAL_TYPE) 6803 return integer_valued_real_p (TREE_OPERAND (t, 0)); 6804 break; 6805 } 6806 6807 case CALL_EXPR: 6808 switch (builtin_mathfn_code (t)) 6809 { 6810 CASE_FLT_FN (BUILT_IN_CEIL): 6811 CASE_FLT_FN (BUILT_IN_FLOOR): 6812 CASE_FLT_FN (BUILT_IN_NEARBYINT): 6813 CASE_FLT_FN (BUILT_IN_RINT): 6814 CASE_FLT_FN (BUILT_IN_ROUND): 6815 CASE_FLT_FN (BUILT_IN_TRUNC): 6816 return true; 6817 6818 default: 6819 break; 6820 } 6821 break; 6822 6823 default: 6824 break; 6825 } 6826 return false; 6827} 6828 6829/* EXP is assumed to be builtin call where truncation can be propagated 6830 across (for instance floor((double)f) == (double)floorf (f). 6831 Do the transformation. */ 6832 6833static tree 6834fold_trunc_transparent_mathfn (tree fndecl, tree arglist) 6835{ 6836 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 6837 tree arg; 6838 6839 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6840 return 0; 6841 6842 arg = TREE_VALUE (arglist); 6843 /* Integer rounding functions are idempotent. */ 6844 if (fcode == builtin_mathfn_code (arg)) 6845 return arg; 6846 6847 /* If argument is already integer valued, and we don't need to worry 6848 about setting errno, there's no need to perform rounding. */ 6849 if (! flag_errno_math && integer_valued_real_p (arg)) 6850 return arg; 6851 6852 if (optimize) 6853 { 6854 tree arg0 = strip_float_extensions (arg); 6855 tree ftype = TREE_TYPE (TREE_TYPE (fndecl)); 6856 tree newtype = TREE_TYPE (arg0); 6857 tree decl; 6858 6859 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype) 6860 && (decl = mathfn_built_in (newtype, fcode))) 6861 { 6862 arglist = 6863 build_tree_list (NULL_TREE, fold_convert (newtype, arg0)); 6864 return fold_convert (ftype, 6865 build_function_call_expr (decl, arglist)); 6866 } 6867 } 6868 return 0; 6869} 6870 6871/* EXP is assumed to be builtin call which can narrow the FP type of 6872 the argument, for instance lround((double)f) -> lroundf (f). */ 6873 6874static tree 6875fold_fixed_mathfn (tree fndecl, tree arglist) 6876{ 6877 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 6878 tree arg; 6879 6880 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6881 return 0; 6882 6883 arg = TREE_VALUE (arglist); 6884 6885 /* If argument is already integer valued, and we don't need to worry 6886 about setting errno, there's no need to perform rounding. */ 6887 if (! flag_errno_math && integer_valued_real_p (arg)) 6888 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg); 6889 6890 if (optimize) 6891 { 6892 tree ftype = TREE_TYPE (arg); 6893 tree arg0 = strip_float_extensions (arg); 6894 tree newtype = TREE_TYPE (arg0); 6895 tree decl; 6896 6897 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype) 6898 && (decl = mathfn_built_in (newtype, fcode))) 6899 { 6900 arglist = 6901 build_tree_list (NULL_TREE, fold_convert (newtype, arg0)); 6902 return build_function_call_expr (decl, arglist); 6903 } 6904 } 6905 6906 /* Canonicalize llround (x) to lround (x) on LP64 targets where 6907 sizeof (long long) == sizeof (long). */ 6908 if (TYPE_PRECISION (long_long_integer_type_node) 6909 == TYPE_PRECISION (long_integer_type_node)) 6910 { 6911 tree newfn = NULL_TREE; 6912 switch (fcode) 6913 { 6914 CASE_FLT_FN (BUILT_IN_LLCEIL): 6915 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL); 6916 break; 6917 6918 CASE_FLT_FN (BUILT_IN_LLFLOOR): 6919 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR); 6920 break; 6921 6922 CASE_FLT_FN (BUILT_IN_LLROUND): 6923 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND); 6924 break; 6925 6926 CASE_FLT_FN (BUILT_IN_LLRINT): 6927 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT); 6928 break; 6929 6930 default: 6931 break; 6932 } 6933 6934 if (newfn) 6935 { 6936 tree newcall = build_function_call_expr (newfn, arglist); 6937 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall); 6938 } 6939 } 6940 6941 return 0; 6942} 6943 6944/* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST 6945 is the argument list, TYPE is the return type and FNDECL is the 6946 original function DECL. Return NULL_TREE if no if no simplification 6947 can be made. */ 6948 6949static tree 6950fold_builtin_cabs (tree arglist, tree type, tree fndecl) 6951{ 6952 tree arg; 6953 6954 if (!arglist || TREE_CHAIN (arglist)) 6955 return NULL_TREE; 6956 6957 arg = TREE_VALUE (arglist); 6958 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE 6959 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE) 6960 return NULL_TREE; 6961 6962 /* Evaluate cabs of a constant at compile-time. */ 6963 if (flag_unsafe_math_optimizations 6964 && TREE_CODE (arg) == COMPLEX_CST 6965 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST 6966 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST 6967 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg)) 6968 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg))) 6969 { 6970 REAL_VALUE_TYPE r, i; 6971 6972 r = TREE_REAL_CST (TREE_REALPART (arg)); 6973 i = TREE_REAL_CST (TREE_IMAGPART (arg)); 6974 6975 real_arithmetic (&r, MULT_EXPR, &r, &r); 6976 real_arithmetic (&i, MULT_EXPR, &i, &i); 6977 real_arithmetic (&r, PLUS_EXPR, &r, &i); 6978 if (real_sqrt (&r, TYPE_MODE (type), &r) 6979 || ! flag_trapping_math) 6980 return build_real (type, r); 6981 } 6982 6983 /* If either part is zero, cabs is fabs of the other. */ 6984 if (TREE_CODE (arg) == COMPLEX_EXPR 6985 && real_zerop (TREE_OPERAND (arg, 0))) 6986 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)); 6987 if (TREE_CODE (arg) == COMPLEX_EXPR 6988 && real_zerop (TREE_OPERAND (arg, 1))) 6989 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)); 6990 6991 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */ 6992 if (TREE_CODE (arg) == NEGATE_EXPR 6993 || TREE_CODE (arg) == CONJ_EXPR) 6994 { 6995 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0)); 6996 return build_function_call_expr (fndecl, arglist); 6997 } 6998 6999 /* Don't do this when optimizing for size. */ 7000 if (flag_unsafe_math_optimizations 7001 && optimize && !optimize_size) 7002 { 7003 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); 7004 7005 if (sqrtfn != NULL_TREE) 7006 { 7007 tree rpart, ipart, result, arglist; 7008 7009 arg = builtin_save_expr (arg); 7010 7011 rpart = fold_build1 (REALPART_EXPR, type, arg); 7012 ipart = fold_build1 (IMAGPART_EXPR, type, arg); 7013 7014 rpart = builtin_save_expr (rpart); 7015 ipart = builtin_save_expr (ipart); 7016 7017 result = fold_build2 (PLUS_EXPR, type, 7018 fold_build2 (MULT_EXPR, type, 7019 rpart, rpart), 7020 fold_build2 (MULT_EXPR, type, 7021 ipart, ipart)); 7022 7023 arglist = build_tree_list (NULL_TREE, result); 7024 return build_function_call_expr (sqrtfn, arglist); 7025 } 7026 } 7027 7028 return NULL_TREE; 7029} 7030 7031/* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return 7032 NULL_TREE if no simplification can be made. */ 7033 7034static tree 7035fold_builtin_sqrt (tree arglist, tree type) 7036{ 7037 7038 enum built_in_function fcode; 7039 tree arg = TREE_VALUE (arglist); 7040 7041 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7042 return NULL_TREE; 7043 7044 /* Optimize sqrt of constant value. */ 7045 if (TREE_CODE (arg) == REAL_CST 7046 && ! TREE_CONSTANT_OVERFLOW (arg)) 7047 { 7048 REAL_VALUE_TYPE r, x; 7049 7050 x = TREE_REAL_CST (arg); 7051 if (real_sqrt (&r, TYPE_MODE (type), &x) 7052 || (!flag_trapping_math && !flag_errno_math)) 7053 return build_real (type, r); 7054 } 7055 7056 /* Optimize sqrt(expN(x)) = expN(x*0.5). */ 7057 fcode = builtin_mathfn_code (arg); 7058 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode)) 7059 { 7060 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 7061 arg = fold_build2 (MULT_EXPR, type, 7062 TREE_VALUE (TREE_OPERAND (arg, 1)), 7063 build_real (type, dconsthalf)); 7064 arglist = build_tree_list (NULL_TREE, arg); 7065 return build_function_call_expr (expfn, arglist); 7066 } 7067 7068 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */ 7069 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode)) 7070 { 7071 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7072 7073 if (powfn) 7074 { 7075 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1)); 7076 tree tree_root; 7077 /* The inner root was either sqrt or cbrt. */ 7078 REAL_VALUE_TYPE dconstroot = 7079 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird; 7080 7081 /* Adjust for the outer root. */ 7082 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); 7083 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7084 tree_root = build_real (type, dconstroot); 7085 arglist = tree_cons (NULL_TREE, arg0, 7086 build_tree_list (NULL_TREE, tree_root)); 7087 return build_function_call_expr (powfn, arglist); 7088 } 7089 } 7090 7091 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */ 7092 if (flag_unsafe_math_optimizations 7093 && (fcode == BUILT_IN_POW 7094 || fcode == BUILT_IN_POWF 7095 || fcode == BUILT_IN_POWL)) 7096 { 7097 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 7098 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1)); 7099 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1))); 7100 tree narg1; 7101 if (!tree_expr_nonnegative_p (arg0)) 7102 arg0 = build1 (ABS_EXPR, type, arg0); 7103 narg1 = fold_build2 (MULT_EXPR, type, arg1, 7104 build_real (type, dconsthalf)); 7105 arglist = tree_cons (NULL_TREE, arg0, 7106 build_tree_list (NULL_TREE, narg1)); 7107 return build_function_call_expr (powfn, arglist); 7108 } 7109 7110 return NULL_TREE; 7111} 7112 7113/* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return 7114 NULL_TREE if no simplification can be made. */ 7115static tree 7116fold_builtin_cbrt (tree arglist, tree type) 7117{ 7118 tree arg = TREE_VALUE (arglist); 7119 const enum built_in_function fcode = builtin_mathfn_code (arg); 7120 7121 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7122 return NULL_TREE; 7123 7124 /* Optimize cbrt of constant value. */ 7125 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg)) 7126 return arg; 7127 7128 if (flag_unsafe_math_optimizations) 7129 { 7130 /* Optimize cbrt(expN(x)) -> expN(x/3). */ 7131 if (BUILTIN_EXPONENT_P (fcode)) 7132 { 7133 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 7134 const REAL_VALUE_TYPE third_trunc = 7135 real_value_truncate (TYPE_MODE (type), dconstthird); 7136 arg = fold_build2 (MULT_EXPR, type, 7137 TREE_VALUE (TREE_OPERAND (arg, 1)), 7138 build_real (type, third_trunc)); 7139 arglist = build_tree_list (NULL_TREE, arg); 7140 return build_function_call_expr (expfn, arglist); 7141 } 7142 7143 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */ 7144 if (BUILTIN_SQRT_P (fcode)) 7145 { 7146 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7147 7148 if (powfn) 7149 { 7150 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1)); 7151 tree tree_root; 7152 REAL_VALUE_TYPE dconstroot = dconstthird; 7153 7154 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); 7155 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7156 tree_root = build_real (type, dconstroot); 7157 arglist = tree_cons (NULL_TREE, arg0, 7158 build_tree_list (NULL_TREE, tree_root)); 7159 return build_function_call_expr (powfn, arglist); 7160 } 7161 } 7162 7163 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */ 7164 if (BUILTIN_CBRT_P (fcode)) 7165 { 7166 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1)); 7167 if (tree_expr_nonnegative_p (arg0)) 7168 { 7169 tree powfn = mathfn_built_in (type, BUILT_IN_POW); 7170 7171 if (powfn) 7172 { 7173 tree tree_root; 7174 REAL_VALUE_TYPE dconstroot; 7175 7176 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird); 7177 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); 7178 tree_root = build_real (type, dconstroot); 7179 arglist = tree_cons (NULL_TREE, arg0, 7180 build_tree_list (NULL_TREE, tree_root)); 7181 return build_function_call_expr (powfn, arglist); 7182 } 7183 } 7184 } 7185 7186 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */ 7187 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF 7188 || fcode == BUILT_IN_POWL) 7189 { 7190 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1)); 7191 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1))); 7192 if (tree_expr_nonnegative_p (arg00)) 7193 { 7194 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 7195 const REAL_VALUE_TYPE dconstroot 7196 = real_value_truncate (TYPE_MODE (type), dconstthird); 7197 tree narg01 = fold_build2 (MULT_EXPR, type, arg01, 7198 build_real (type, dconstroot)); 7199 arglist = tree_cons (NULL_TREE, arg00, 7200 build_tree_list (NULL_TREE, narg01)); 7201 return build_function_call_expr (powfn, arglist); 7202 } 7203 } 7204 } 7205 return NULL_TREE; 7206} 7207 7208/* Fold function call to builtin sin, sinf, or sinl. Return 7209 NULL_TREE if no simplification can be made. */ 7210static tree 7211fold_builtin_sin (tree arglist) 7212{ 7213 tree arg = TREE_VALUE (arglist); 7214 7215 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7216 return NULL_TREE; 7217 7218 /* Optimize sin (0.0) = 0.0. */ 7219 if (real_zerop (arg)) 7220 return arg; 7221 7222 return NULL_TREE; 7223} 7224 7225/* Fold function call to builtin cos, cosf, or cosl. Return 7226 NULL_TREE if no simplification can be made. */ 7227static tree 7228fold_builtin_cos (tree arglist, tree type, tree fndecl) 7229{ 7230 tree arg = TREE_VALUE (arglist); 7231 7232 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7233 return NULL_TREE; 7234 7235 /* Optimize cos (0.0) = 1.0. */ 7236 if (real_zerop (arg)) 7237 return build_real (type, dconst1); 7238 7239 /* Optimize cos(-x) into cos (x). */ 7240 if (TREE_CODE (arg) == NEGATE_EXPR) 7241 { 7242 tree args = build_tree_list (NULL_TREE, 7243 TREE_OPERAND (arg, 0)); 7244 return build_function_call_expr (fndecl, args); 7245 } 7246 7247 return NULL_TREE; 7248} 7249 7250/* Fold function call to builtin tan, tanf, or tanl. Return 7251 NULL_TREE if no simplification can be made. */ 7252static tree 7253fold_builtin_tan (tree arglist) 7254{ 7255 enum built_in_function fcode; 7256 tree arg = TREE_VALUE (arglist); 7257 7258 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7259 return NULL_TREE; 7260 7261 /* Optimize tan(0.0) = 0.0. */ 7262 if (real_zerop (arg)) 7263 return arg; 7264 7265 /* Optimize tan(atan(x)) = x. */ 7266 fcode = builtin_mathfn_code (arg); 7267 if (flag_unsafe_math_optimizations 7268 && (fcode == BUILT_IN_ATAN 7269 || fcode == BUILT_IN_ATANF 7270 || fcode == BUILT_IN_ATANL)) 7271 return TREE_VALUE (TREE_OPERAND (arg, 1)); 7272 7273 return NULL_TREE; 7274} 7275 7276/* Fold function call to builtin atan, atanf, or atanl. Return 7277 NULL_TREE if no simplification can be made. */ 7278 7279static tree 7280fold_builtin_atan (tree arglist, tree type) 7281{ 7282 7283 tree arg = TREE_VALUE (arglist); 7284 7285 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7286 return NULL_TREE; 7287 7288 /* Optimize atan(0.0) = 0.0. */ 7289 if (real_zerop (arg)) 7290 return arg; 7291 7292 /* Optimize atan(1.0) = pi/4. */ 7293 if (real_onep (arg)) 7294 { 7295 REAL_VALUE_TYPE cst; 7296 7297 real_convert (&cst, TYPE_MODE (type), &dconstpi); 7298 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2); 7299 return build_real (type, cst); 7300 } 7301 7302 return NULL_TREE; 7303} 7304 7305/* Fold function call to builtin trunc, truncf or truncl. Return 7306 NULL_TREE if no simplification can be made. */ 7307 7308static tree 7309fold_builtin_trunc (tree fndecl, tree arglist) 7310{ 7311 tree arg; 7312 7313 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7314 return 0; 7315 7316 /* Optimize trunc of constant value. */ 7317 arg = TREE_VALUE (arglist); 7318 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7319 { 7320 REAL_VALUE_TYPE r, x; 7321 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7322 7323 x = TREE_REAL_CST (arg); 7324 real_trunc (&r, TYPE_MODE (type), &x); 7325 return build_real (type, r); 7326 } 7327 7328 return fold_trunc_transparent_mathfn (fndecl, arglist); 7329} 7330 7331/* Fold function call to builtin floor, floorf or floorl. Return 7332 NULL_TREE if no simplification can be made. */ 7333 7334static tree 7335fold_builtin_floor (tree fndecl, tree arglist) 7336{ 7337 tree arg; 7338 7339 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7340 return 0; 7341 7342 /* Optimize floor of constant value. */ 7343 arg = TREE_VALUE (arglist); 7344 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7345 { 7346 REAL_VALUE_TYPE x; 7347 7348 x = TREE_REAL_CST (arg); 7349 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 7350 { 7351 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7352 REAL_VALUE_TYPE r; 7353 7354 real_floor (&r, TYPE_MODE (type), &x); 7355 return build_real (type, r); 7356 } 7357 } 7358 7359 return fold_trunc_transparent_mathfn (fndecl, arglist); 7360} 7361 7362/* Fold function call to builtin ceil, ceilf or ceill. Return 7363 NULL_TREE if no simplification can be made. */ 7364 7365static tree 7366fold_builtin_ceil (tree fndecl, tree arglist) 7367{ 7368 tree arg; 7369 7370 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7371 return 0; 7372 7373 /* Optimize ceil of constant value. */ 7374 arg = TREE_VALUE (arglist); 7375 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7376 { 7377 REAL_VALUE_TYPE x; 7378 7379 x = TREE_REAL_CST (arg); 7380 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 7381 { 7382 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7383 REAL_VALUE_TYPE r; 7384 7385 real_ceil (&r, TYPE_MODE (type), &x); 7386 return build_real (type, r); 7387 } 7388 } 7389 7390 return fold_trunc_transparent_mathfn (fndecl, arglist); 7391} 7392 7393/* Fold function call to builtin round, roundf or roundl. Return 7394 NULL_TREE if no simplification can be made. */ 7395 7396static tree 7397fold_builtin_round (tree fndecl, tree arglist) 7398{ 7399 tree arg; 7400 7401 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7402 return 0; 7403 7404 /* Optimize round of constant value. */ 7405 arg = TREE_VALUE (arglist); 7406 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7407 { 7408 REAL_VALUE_TYPE x; 7409 7410 x = TREE_REAL_CST (arg); 7411 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 7412 { 7413 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7414 REAL_VALUE_TYPE r; 7415 7416 real_round (&r, TYPE_MODE (type), &x); 7417 return build_real (type, r); 7418 } 7419 } 7420 7421 return fold_trunc_transparent_mathfn (fndecl, arglist); 7422} 7423 7424/* Fold function call to builtin lround, lroundf or lroundl (or the 7425 corresponding long long versions) and other rounding functions. 7426 Return NULL_TREE if no simplification can be made. */ 7427 7428static tree 7429fold_builtin_int_roundingfn (tree fndecl, tree arglist) 7430{ 7431 tree arg; 7432 7433 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7434 return 0; 7435 7436 /* Optimize lround of constant value. */ 7437 arg = TREE_VALUE (arglist); 7438 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7439 { 7440 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg); 7441 7442 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x)) 7443 { 7444 tree itype = TREE_TYPE (TREE_TYPE (fndecl)); 7445 tree ftype = TREE_TYPE (arg), result; 7446 HOST_WIDE_INT hi, lo; 7447 REAL_VALUE_TYPE r; 7448 7449 switch (DECL_FUNCTION_CODE (fndecl)) 7450 { 7451 CASE_FLT_FN (BUILT_IN_LFLOOR): 7452 CASE_FLT_FN (BUILT_IN_LLFLOOR): 7453 real_floor (&r, TYPE_MODE (ftype), &x); 7454 break; 7455 7456 CASE_FLT_FN (BUILT_IN_LCEIL): 7457 CASE_FLT_FN (BUILT_IN_LLCEIL): 7458 real_ceil (&r, TYPE_MODE (ftype), &x); 7459 break; 7460 7461 CASE_FLT_FN (BUILT_IN_LROUND): 7462 CASE_FLT_FN (BUILT_IN_LLROUND): 7463 real_round (&r, TYPE_MODE (ftype), &x); 7464 break; 7465 7466 default: 7467 gcc_unreachable (); 7468 } 7469 7470 REAL_VALUE_TO_INT (&lo, &hi, r); 7471 result = build_int_cst_wide (NULL_TREE, lo, hi); 7472 if (int_fits_type_p (result, itype)) 7473 return fold_convert (itype, result); 7474 } 7475 } 7476 7477 return fold_fixed_mathfn (fndecl, arglist); 7478} 7479 7480/* Fold function call to builtin ffs, clz, ctz, popcount and parity 7481 and their long and long long variants (i.e. ffsl and ffsll). 7482 Return NULL_TREE if no simplification can be made. */ 7483 7484static tree 7485fold_builtin_bitop (tree fndecl, tree arglist) 7486{ 7487 tree arg; 7488 7489 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 7490 return NULL_TREE; 7491 7492 /* Optimize for constant argument. */ 7493 arg = TREE_VALUE (arglist); 7494 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7495 { 7496 HOST_WIDE_INT hi, width, result; 7497 unsigned HOST_WIDE_INT lo; 7498 tree type; 7499 7500 type = TREE_TYPE (arg); 7501 width = TYPE_PRECISION (type); 7502 lo = TREE_INT_CST_LOW (arg); 7503 7504 /* Clear all the bits that are beyond the type's precision. */ 7505 if (width > HOST_BITS_PER_WIDE_INT) 7506 { 7507 hi = TREE_INT_CST_HIGH (arg); 7508 if (width < 2 * HOST_BITS_PER_WIDE_INT) 7509 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT)); 7510 } 7511 else 7512 { 7513 hi = 0; 7514 if (width < HOST_BITS_PER_WIDE_INT) 7515 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width); 7516 } 7517 7518 switch (DECL_FUNCTION_CODE (fndecl)) 7519 { 7520 CASE_INT_FN (BUILT_IN_FFS): 7521 if (lo != 0) 7522 result = exact_log2 (lo & -lo) + 1; 7523 else if (hi != 0) 7524 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1; 7525 else 7526 result = 0; 7527 break; 7528 7529 CASE_INT_FN (BUILT_IN_CLZ): 7530 if (hi != 0) 7531 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT; 7532 else if (lo != 0) 7533 result = width - floor_log2 (lo) - 1; 7534 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result)) 7535 result = width; 7536 break; 7537 7538 CASE_INT_FN (BUILT_IN_CTZ): 7539 if (lo != 0) 7540 result = exact_log2 (lo & -lo); 7541 else if (hi != 0) 7542 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi); 7543 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result)) 7544 result = width; 7545 break; 7546 7547 CASE_INT_FN (BUILT_IN_POPCOUNT): 7548 result = 0; 7549 while (lo) 7550 result++, lo &= lo - 1; 7551 while (hi) 7552 result++, hi &= hi - 1; 7553 break; 7554 7555 CASE_INT_FN (BUILT_IN_PARITY): 7556 result = 0; 7557 while (lo) 7558 result++, lo &= lo - 1; 7559 while (hi) 7560 result++, hi &= hi - 1; 7561 result &= 1; 7562 break; 7563 7564 default: 7565 gcc_unreachable (); 7566 } 7567 7568 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result); 7569 } 7570 7571 return NULL_TREE; 7572} 7573 7574/* Fold function call to builtin_bswap and the long and long long 7575 variants. Return NULL_TREE if no simplification can be made. */ 7576static tree 7577fold_builtin_bswap (tree fndecl, tree arglist) 7578{ 7579 tree arg; 7580 7581 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 7582 return 0; 7583 7584 /* Optimize constant value. */ 7585 arg = TREE_VALUE (arglist); 7586 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 7587 { 7588 HOST_WIDE_INT hi, width, r_hi = 0; 7589 unsigned HOST_WIDE_INT lo, r_lo = 0; 7590 tree type; 7591 7592 type = TREE_TYPE (arg); 7593 width = TYPE_PRECISION (type); 7594 lo = TREE_INT_CST_LOW (arg); 7595 hi = TREE_INT_CST_HIGH (arg); 7596 7597 switch (DECL_FUNCTION_CODE (fndecl)) 7598 { 7599 case BUILT_IN_BSWAP32: 7600 case BUILT_IN_BSWAP64: 7601 { 7602 int s; 7603 7604 for (s = 0; s < width; s += 8) 7605 { 7606 int d = width - s - 8; 7607 unsigned HOST_WIDE_INT byte; 7608 7609 if (s < HOST_BITS_PER_WIDE_INT) 7610 byte = (lo >> s) & 0xff; 7611 else 7612 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff; 7613 7614 if (d < HOST_BITS_PER_WIDE_INT) 7615 r_lo |= byte << d; 7616 else 7617 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT); 7618 } 7619 } 7620 7621 break; 7622 7623 default: 7624 gcc_unreachable (); 7625 } 7626 7627 if (width < HOST_BITS_PER_WIDE_INT) 7628 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo); 7629 else 7630 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi); 7631 } 7632 7633 return NULL_TREE; 7634} 7635/* Return true if EXPR is the real constant contained in VALUE. */ 7636 7637static bool 7638real_dconstp (tree expr, const REAL_VALUE_TYPE *value) 7639{ 7640 STRIP_NOPS (expr); 7641 7642 return ((TREE_CODE (expr) == REAL_CST 7643 && ! TREE_CONSTANT_OVERFLOW (expr) 7644 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value)) 7645 || (TREE_CODE (expr) == COMPLEX_CST 7646 && real_dconstp (TREE_REALPART (expr), value) 7647 && real_zerop (TREE_IMAGPART (expr)))); 7648} 7649 7650/* A subroutine of fold_builtin to fold the various logarithmic 7651 functions. EXP is the CALL_EXPR of a call to a builtin logN 7652 function. VALUE is the base of the logN function. */ 7653 7654static tree 7655fold_builtin_logarithm (tree fndecl, tree arglist, 7656 const REAL_VALUE_TYPE *value) 7657{ 7658 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7659 { 7660 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7661 tree arg = TREE_VALUE (arglist); 7662 const enum built_in_function fcode = builtin_mathfn_code (arg); 7663 7664 /* Optimize logN(1.0) = 0.0. */ 7665 if (real_onep (arg)) 7666 return build_real (type, dconst0); 7667 7668 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE 7669 exactly, then only do this if flag_unsafe_math_optimizations. */ 7670 if (exact_real_truncate (TYPE_MODE (type), value) 7671 || flag_unsafe_math_optimizations) 7672 { 7673 const REAL_VALUE_TYPE value_truncate = 7674 real_value_truncate (TYPE_MODE (type), *value); 7675 if (real_dconstp (arg, &value_truncate)) 7676 return build_real (type, dconst1); 7677 } 7678 7679 /* Special case, optimize logN(expN(x)) = x. */ 7680 if (flag_unsafe_math_optimizations 7681 && ((value == &dconste 7682 && (fcode == BUILT_IN_EXP 7683 || fcode == BUILT_IN_EXPF 7684 || fcode == BUILT_IN_EXPL)) 7685 || (value == &dconst2 7686 && (fcode == BUILT_IN_EXP2 7687 || fcode == BUILT_IN_EXP2F 7688 || fcode == BUILT_IN_EXP2L)) 7689 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode))))) 7690 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1))); 7691 7692 /* Optimize logN(func()) for various exponential functions. We 7693 want to determine the value "x" and the power "exponent" in 7694 order to transform logN(x**exponent) into exponent*logN(x). */ 7695 if (flag_unsafe_math_optimizations) 7696 { 7697 tree exponent = 0, x = 0; 7698 7699 switch (fcode) 7700 { 7701 CASE_FLT_FN (BUILT_IN_EXP): 7702 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */ 7703 x = build_real (type, 7704 real_value_truncate (TYPE_MODE (type), dconste)); 7705 exponent = TREE_VALUE (TREE_OPERAND (arg, 1)); 7706 break; 7707 CASE_FLT_FN (BUILT_IN_EXP2): 7708 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */ 7709 x = build_real (type, dconst2); 7710 exponent = TREE_VALUE (TREE_OPERAND (arg, 1)); 7711 break; 7712 CASE_FLT_FN (BUILT_IN_EXP10): 7713 CASE_FLT_FN (BUILT_IN_POW10): 7714 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */ 7715 x = build_real (type, dconst10); 7716 exponent = TREE_VALUE (TREE_OPERAND (arg, 1)); 7717 break; 7718 CASE_FLT_FN (BUILT_IN_SQRT): 7719 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */ 7720 x = TREE_VALUE (TREE_OPERAND (arg, 1)); 7721 exponent = build_real (type, dconsthalf); 7722 break; 7723 CASE_FLT_FN (BUILT_IN_CBRT): 7724 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */ 7725 x = TREE_VALUE (TREE_OPERAND (arg, 1)); 7726 exponent = build_real (type, real_value_truncate (TYPE_MODE (type), 7727 dconstthird)); 7728 break; 7729 CASE_FLT_FN (BUILT_IN_POW): 7730 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */ 7731 x = TREE_VALUE (TREE_OPERAND (arg, 1)); 7732 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1))); 7733 break; 7734 default: 7735 break; 7736 } 7737 7738 /* Now perform the optimization. */ 7739 if (x && exponent) 7740 { 7741 tree logfn; 7742 arglist = build_tree_list (NULL_TREE, x); 7743 logfn = build_function_call_expr (fndecl, arglist); 7744 return fold_build2 (MULT_EXPR, type, exponent, logfn); 7745 } 7746 } 7747 } 7748 7749 return 0; 7750} 7751 7752/* Fold a builtin function call to pow, powf, or powl. Return 7753 NULL_TREE if no simplification can be made. */ 7754static tree 7755fold_builtin_pow (tree fndecl, tree arglist, tree type) 7756{ 7757 tree arg0 = TREE_VALUE (arglist); 7758 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 7759 7760 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 7761 return NULL_TREE; 7762 7763 /* Optimize pow(1.0,y) = 1.0. */ 7764 if (real_onep (arg0)) 7765 return omit_one_operand (type, build_real (type, dconst1), arg1); 7766 7767 if (TREE_CODE (arg1) == REAL_CST 7768 && ! TREE_CONSTANT_OVERFLOW (arg1)) 7769 { 7770 REAL_VALUE_TYPE cint; 7771 REAL_VALUE_TYPE c; 7772 HOST_WIDE_INT n; 7773 7774 c = TREE_REAL_CST (arg1); 7775 7776 /* Optimize pow(x,0.0) = 1.0. */ 7777 if (REAL_VALUES_EQUAL (c, dconst0)) 7778 return omit_one_operand (type, build_real (type, dconst1), 7779 arg0); 7780 7781 /* Optimize pow(x,1.0) = x. */ 7782 if (REAL_VALUES_EQUAL (c, dconst1)) 7783 return arg0; 7784 7785 /* Optimize pow(x,-1.0) = 1.0/x. */ 7786 if (REAL_VALUES_EQUAL (c, dconstm1)) 7787 return fold_build2 (RDIV_EXPR, type, 7788 build_real (type, dconst1), arg0); 7789 7790 /* Optimize pow(x,0.5) = sqrt(x). */ 7791 if (flag_unsafe_math_optimizations 7792 && REAL_VALUES_EQUAL (c, dconsthalf)) 7793 { 7794 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); 7795 7796 if (sqrtfn != NULL_TREE) 7797 { 7798 tree arglist = build_tree_list (NULL_TREE, arg0); 7799 return build_function_call_expr (sqrtfn, arglist); 7800 } 7801 } 7802 7803 /* Check for an integer exponent. */ 7804 n = real_to_integer (&c); 7805 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); 7806 if (real_identical (&c, &cint)) 7807 { 7808 /* Attempt to evaluate pow at compile-time. */ 7809 if (TREE_CODE (arg0) == REAL_CST 7810 && ! TREE_CONSTANT_OVERFLOW (arg0)) 7811 { 7812 REAL_VALUE_TYPE x; 7813 bool inexact; 7814 7815 x = TREE_REAL_CST (arg0); 7816 inexact = real_powi (&x, TYPE_MODE (type), &x, n); 7817 if (flag_unsafe_math_optimizations || !inexact) 7818 return build_real (type, x); 7819 } 7820 7821 /* Strip sign ops from even integer powers. */ 7822 if ((n & 1) == 0 && flag_unsafe_math_optimizations) 7823 { 7824 tree narg0 = fold_strip_sign_ops (arg0); 7825 if (narg0) 7826 { 7827 arglist = build_tree_list (NULL_TREE, arg1); 7828 arglist = tree_cons (NULL_TREE, narg0, arglist); 7829 return build_function_call_expr (fndecl, arglist); 7830 } 7831 } 7832 } 7833 } 7834 7835 if (flag_unsafe_math_optimizations) 7836 { 7837 const enum built_in_function fcode = builtin_mathfn_code (arg0); 7838 7839 /* Optimize pow(expN(x),y) = expN(x*y). */ 7840 if (BUILTIN_EXPONENT_P (fcode)) 7841 { 7842 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0); 7843 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1)); 7844 arg = fold_build2 (MULT_EXPR, type, arg, arg1); 7845 arglist = build_tree_list (NULL_TREE, arg); 7846 return build_function_call_expr (expfn, arglist); 7847 } 7848 7849 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */ 7850 if (BUILTIN_SQRT_P (fcode)) 7851 { 7852 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1)); 7853 tree narg1 = fold_build2 (MULT_EXPR, type, arg1, 7854 build_real (type, dconsthalf)); 7855 7856 arglist = tree_cons (NULL_TREE, narg0, 7857 build_tree_list (NULL_TREE, narg1)); 7858 return build_function_call_expr (fndecl, arglist); 7859 } 7860 7861 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */ 7862 if (BUILTIN_CBRT_P (fcode)) 7863 { 7864 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1)); 7865 if (tree_expr_nonnegative_p (arg)) 7866 { 7867 const REAL_VALUE_TYPE dconstroot 7868 = real_value_truncate (TYPE_MODE (type), dconstthird); 7869 tree narg1 = fold_build2 (MULT_EXPR, type, arg1, 7870 build_real (type, dconstroot)); 7871 arglist = tree_cons (NULL_TREE, arg, 7872 build_tree_list (NULL_TREE, narg1)); 7873 return build_function_call_expr (fndecl, arglist); 7874 } 7875 } 7876 7877 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */ 7878 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF 7879 || fcode == BUILT_IN_POWL) 7880 { 7881 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1)); 7882 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1))); 7883 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1); 7884 arglist = tree_cons (NULL_TREE, arg00, 7885 build_tree_list (NULL_TREE, narg1)); 7886 return build_function_call_expr (fndecl, arglist); 7887 } 7888 } 7889 7890 return NULL_TREE; 7891} 7892 7893/* Fold a builtin function call to powi, powif, or powil. Return 7894 NULL_TREE if no simplification can be made. */ 7895static tree 7896fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type) 7897{ 7898 tree arg0 = TREE_VALUE (arglist); 7899 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 7900 7901 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE)) 7902 return NULL_TREE; 7903 7904 /* Optimize pow(1.0,y) = 1.0. */ 7905 if (real_onep (arg0)) 7906 return omit_one_operand (type, build_real (type, dconst1), arg1); 7907 7908 if (host_integerp (arg1, 0)) 7909 { 7910 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1); 7911 7912 /* Evaluate powi at compile-time. */ 7913 if (TREE_CODE (arg0) == REAL_CST 7914 && ! TREE_CONSTANT_OVERFLOW (arg0)) 7915 { 7916 REAL_VALUE_TYPE x; 7917 x = TREE_REAL_CST (arg0); 7918 real_powi (&x, TYPE_MODE (type), &x, c); 7919 return build_real (type, x); 7920 } 7921 7922 /* Optimize pow(x,0) = 1.0. */ 7923 if (c == 0) 7924 return omit_one_operand (type, build_real (type, dconst1), 7925 arg0); 7926 7927 /* Optimize pow(x,1) = x. */ 7928 if (c == 1) 7929 return arg0; 7930 7931 /* Optimize pow(x,-1) = 1.0/x. */ 7932 if (c == -1) 7933 return fold_build2 (RDIV_EXPR, type, 7934 build_real (type, dconst1), arg0); 7935 } 7936 7937 return NULL_TREE; 7938} 7939 7940/* A subroutine of fold_builtin to fold the various exponent 7941 functions. EXP is the CALL_EXPR of a call to a builtin function. 7942 VALUE is the value which will be raised to a power. */ 7943 7944static tree 7945fold_builtin_exponent (tree fndecl, tree arglist, 7946 const REAL_VALUE_TYPE *value) 7947{ 7948 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 7949 { 7950 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 7951 tree arg = TREE_VALUE (arglist); 7952 7953 /* Optimize exp*(0.0) = 1.0. */ 7954 if (real_zerop (arg)) 7955 return build_real (type, dconst1); 7956 7957 /* Optimize expN(1.0) = N. */ 7958 if (real_onep (arg)) 7959 { 7960 REAL_VALUE_TYPE cst; 7961 7962 real_convert (&cst, TYPE_MODE (type), value); 7963 return build_real (type, cst); 7964 } 7965 7966 /* Attempt to evaluate expN(integer) at compile-time. */ 7967 if (flag_unsafe_math_optimizations 7968 && TREE_CODE (arg) == REAL_CST 7969 && ! TREE_CONSTANT_OVERFLOW (arg)) 7970 { 7971 REAL_VALUE_TYPE cint; 7972 REAL_VALUE_TYPE c; 7973 HOST_WIDE_INT n; 7974 7975 c = TREE_REAL_CST (arg); 7976 n = real_to_integer (&c); 7977 real_from_integer (&cint, VOIDmode, n, 7978 n < 0 ? -1 : 0, 0); 7979 if (real_identical (&c, &cint)) 7980 { 7981 REAL_VALUE_TYPE x; 7982 7983 real_powi (&x, TYPE_MODE (type), value, n); 7984 return build_real (type, x); 7985 } 7986 } 7987 7988 /* Optimize expN(logN(x)) = x. */ 7989 if (flag_unsafe_math_optimizations) 7990 { 7991 const enum built_in_function fcode = builtin_mathfn_code (arg); 7992 7993 if ((value == &dconste 7994 && (fcode == BUILT_IN_LOG 7995 || fcode == BUILT_IN_LOGF 7996 || fcode == BUILT_IN_LOGL)) 7997 || (value == &dconst2 7998 && (fcode == BUILT_IN_LOG2 7999 || fcode == BUILT_IN_LOG2F 8000 || fcode == BUILT_IN_LOG2L)) 8001 || (value == &dconst10 8002 && (fcode == BUILT_IN_LOG10 8003 || fcode == BUILT_IN_LOG10F 8004 || fcode == BUILT_IN_LOG10L))) 8005 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1))); 8006 } 8007 } 8008 8009 return 0; 8010} 8011 8012/* Return true if VAR is a VAR_DECL or a component thereof. */ 8013 8014static bool 8015var_decl_component_p (tree var) 8016{ 8017 tree inner = var; 8018 while (handled_component_p (inner)) 8019 inner = TREE_OPERAND (inner, 0); 8020 return SSA_VAR_P (inner); 8021} 8022 8023/* Fold function call to builtin memset. Return 8024 NULL_TREE if no simplification can be made. */ 8025 8026static tree 8027fold_builtin_memset (tree arglist, tree type, bool ignore) 8028{ 8029 tree dest, c, len, var, ret; 8030 unsigned HOST_WIDE_INT length, cval; 8031 8032 if (!validate_arglist (arglist, 8033 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8034 return 0; 8035 8036 dest = TREE_VALUE (arglist); 8037 c = TREE_VALUE (TREE_CHAIN (arglist)); 8038 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8039 8040 if (! host_integerp (len, 1)) 8041 return 0; 8042 8043 /* If the LEN parameter is zero, return DEST. */ 8044 if (integer_zerop (len)) 8045 return omit_one_operand (type, dest, c); 8046 8047 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest)) 8048 return 0; 8049 8050 var = dest; 8051 STRIP_NOPS (var); 8052 if (TREE_CODE (var) != ADDR_EXPR) 8053 return 0; 8054 8055 var = TREE_OPERAND (var, 0); 8056 if (TREE_THIS_VOLATILE (var)) 8057 return 0; 8058 8059 if (!INTEGRAL_TYPE_P (TREE_TYPE (var)) 8060 && !POINTER_TYPE_P (TREE_TYPE (var))) 8061 return 0; 8062 8063 if (! var_decl_component_p (var)) 8064 return 0; 8065 8066 length = tree_low_cst (len, 1); 8067 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length 8068 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT 8069 < (int) length) 8070 return 0; 8071 8072 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT) 8073 return 0; 8074 8075 if (integer_zerop (c)) 8076 cval = 0; 8077 else 8078 { 8079 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64) 8080 return 0; 8081 8082 cval = tree_low_cst (c, 1); 8083 cval &= 0xff; 8084 cval |= cval << 8; 8085 cval |= cval << 16; 8086 cval |= (cval << 31) << 1; 8087 } 8088 8089 ret = build_int_cst_type (TREE_TYPE (var), cval); 8090 ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret); 8091 if (ignore) 8092 return ret; 8093 8094 return omit_one_operand (type, dest, ret); 8095} 8096 8097/* Fold function call to builtin memset. Return 8098 NULL_TREE if no simplification can be made. */ 8099 8100static tree 8101fold_builtin_bzero (tree arglist, bool ignore) 8102{ 8103 tree dest, size, newarglist; 8104 8105 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8106 return 0; 8107 8108 if (!ignore) 8109 return 0; 8110 8111 dest = TREE_VALUE (arglist); 8112 size = TREE_VALUE (TREE_CHAIN (arglist)); 8113 8114 /* New argument list transforming bzero(ptr x, int y) to 8115 memset(ptr x, int 0, size_t y). This is done this way 8116 so that if it isn't expanded inline, we fallback to 8117 calling bzero instead of memset. */ 8118 8119 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size)); 8120 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist); 8121 newarglist = tree_cons (NULL_TREE, dest, newarglist); 8122 return fold_builtin_memset (newarglist, void_type_node, ignore); 8123} 8124 8125/* Fold function call to builtin mem{{,p}cpy,move}. Return 8126 NULL_TREE if no simplification can be made. 8127 If ENDP is 0, return DEST (like memcpy). 8128 If ENDP is 1, return DEST+LEN (like mempcpy). 8129 If ENDP is 2, return DEST+LEN-1 (like stpcpy). 8130 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap 8131 (memmove). */ 8132 8133static tree 8134fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp) 8135{ 8136 tree dest, src, len, destvar, srcvar, expr; 8137 unsigned HOST_WIDE_INT length; 8138 8139 if (! validate_arglist (arglist, 8140 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8141 return 0; 8142 8143 dest = TREE_VALUE (arglist); 8144 src = TREE_VALUE (TREE_CHAIN (arglist)); 8145 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8146 8147 /* If the LEN parameter is zero, return DEST. */ 8148 if (integer_zerop (len)) 8149 return omit_one_operand (type, dest, src); 8150 8151 /* If SRC and DEST are the same (and not volatile), return 8152 DEST{,+LEN,+LEN-1}. */ 8153 if (operand_equal_p (src, dest, 0)) 8154 expr = len; 8155 else 8156 { 8157 if (! host_integerp (len, 1)) 8158 return 0; 8159 8160 if (TREE_SIDE_EFFECTS (dest) || TREE_SIDE_EFFECTS (src)) 8161 return 0; 8162 8163 destvar = dest; 8164 STRIP_NOPS (destvar); 8165 if (TREE_CODE (destvar) != ADDR_EXPR) 8166 return 0; 8167 8168 destvar = TREE_OPERAND (destvar, 0); 8169 if (TREE_THIS_VOLATILE (destvar)) 8170 return 0; 8171 8172 if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar)) 8173 && !POINTER_TYPE_P (TREE_TYPE (destvar)) 8174 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar))) 8175 return 0; 8176 8177 if (! var_decl_component_p (destvar)) 8178 return 0; 8179 8180 srcvar = src; 8181 STRIP_NOPS (srcvar); 8182 if (TREE_CODE (srcvar) != ADDR_EXPR) 8183 return 0; 8184 8185 srcvar = TREE_OPERAND (srcvar, 0); 8186 if (TREE_THIS_VOLATILE (srcvar)) 8187 return 0; 8188 8189 if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar)) 8190 && !POINTER_TYPE_P (TREE_TYPE (srcvar)) 8191 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar))) 8192 return 0; 8193 8194 if (! var_decl_component_p (srcvar)) 8195 return 0; 8196 8197 length = tree_low_cst (len, 1); 8198 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length 8199 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT 8200 < (int) length 8201 || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar))) != length 8202 || get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT 8203 < (int) length) 8204 return 0; 8205 8206 if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar)) 8207 || POINTER_TYPE_P (TREE_TYPE (srcvar))) 8208 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar)) 8209 || POINTER_TYPE_P (TREE_TYPE (destvar)))) 8210 expr = fold_convert (TREE_TYPE (destvar), srcvar); 8211 else 8212 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar); 8213 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr); 8214 } 8215 8216 if (ignore) 8217 return expr; 8218 8219 if (endp == 0 || endp == 3) 8220 return omit_one_operand (type, dest, expr); 8221 8222 if (expr == len) 8223 expr = 0; 8224 8225 if (endp == 2) 8226 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len, 8227 ssize_int (1)); 8228 8229 len = fold_convert (TREE_TYPE (dest), len); 8230 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len); 8231 dest = fold_convert (type, dest); 8232 if (expr) 8233 dest = omit_one_operand (type, dest, expr); 8234 return dest; 8235} 8236 8237/* Fold function call to builtin bcopy. Return NULL_TREE if no 8238 simplification can be made. */ 8239 8240static tree 8241fold_builtin_bcopy (tree arglist, bool ignore) 8242{ 8243 tree src, dest, size, newarglist; 8244 8245 if (!validate_arglist (arglist, 8246 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8247 return 0; 8248 8249 if (! ignore) 8250 return 0; 8251 8252 src = TREE_VALUE (arglist); 8253 dest = TREE_VALUE (TREE_CHAIN (arglist)); 8254 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8255 8256 /* New argument list transforming bcopy(ptr x, ptr y, int z) to 8257 memmove(ptr y, ptr x, size_t z). This is done this way 8258 so that if it isn't expanded inline, we fallback to 8259 calling bcopy instead of memmove. */ 8260 8261 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size)); 8262 newarglist = tree_cons (NULL_TREE, src, newarglist); 8263 newarglist = tree_cons (NULL_TREE, dest, newarglist); 8264 8265 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3); 8266} 8267 8268/* Fold function call to builtin strcpy. If LEN is not NULL, it represents 8269 the length of the string to be copied. Return NULL_TREE if no 8270 simplification can be made. */ 8271 8272tree 8273fold_builtin_strcpy (tree fndecl, tree arglist, tree len) 8274{ 8275 tree dest, src, fn; 8276 8277 if (!validate_arglist (arglist, 8278 POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 8279 return 0; 8280 8281 dest = TREE_VALUE (arglist); 8282 src = TREE_VALUE (TREE_CHAIN (arglist)); 8283 8284 /* If SRC and DEST are the same (and not volatile), return DEST. */ 8285 if (operand_equal_p (src, dest, 0)) 8286 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest); 8287 8288 if (optimize_size) 8289 return 0; 8290 8291 fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 8292 if (!fn) 8293 return 0; 8294 8295 if (!len) 8296 { 8297 len = c_strlen (src, 1); 8298 if (! len || TREE_SIDE_EFFECTS (len)) 8299 return 0; 8300 } 8301 8302 len = size_binop (PLUS_EXPR, len, ssize_int (1)); 8303 arglist = build_tree_list (NULL_TREE, len); 8304 arglist = tree_cons (NULL_TREE, src, arglist); 8305 arglist = tree_cons (NULL_TREE, dest, arglist); 8306 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), 8307 build_function_call_expr (fn, arglist)); 8308} 8309 8310/* Fold function call to builtin strncpy. If SLEN is not NULL, it represents 8311 the length of the source string. Return NULL_TREE if no simplification 8312 can be made. */ 8313 8314tree 8315fold_builtin_strncpy (tree fndecl, tree arglist, tree slen) 8316{ 8317 tree dest, src, len, fn; 8318 8319 if (!validate_arglist (arglist, 8320 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8321 return 0; 8322 8323 dest = TREE_VALUE (arglist); 8324 src = TREE_VALUE (TREE_CHAIN (arglist)); 8325 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8326 8327 /* If the LEN parameter is zero, return DEST. */ 8328 if (integer_zerop (len)) 8329 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src); 8330 8331 /* We can't compare slen with len as constants below if len is not a 8332 constant. */ 8333 if (len == 0 || TREE_CODE (len) != INTEGER_CST) 8334 return 0; 8335 8336 if (!slen) 8337 slen = c_strlen (src, 1); 8338 8339 /* Now, we must be passed a constant src ptr parameter. */ 8340 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST) 8341 return 0; 8342 8343 slen = size_binop (PLUS_EXPR, slen, ssize_int (1)); 8344 8345 /* We do not support simplification of this case, though we do 8346 support it when expanding trees into RTL. */ 8347 /* FIXME: generate a call to __builtin_memset. */ 8348 if (tree_int_cst_lt (slen, len)) 8349 return 0; 8350 8351 /* OK transform into builtin memcpy. */ 8352 fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 8353 if (!fn) 8354 return 0; 8355 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), 8356 build_function_call_expr (fn, arglist)); 8357} 8358 8359/* Fold function call to builtin memcmp. Return 8360 NULL_TREE if no simplification can be made. */ 8361 8362static tree 8363fold_builtin_memcmp (tree arglist) 8364{ 8365 tree arg1, arg2, len; 8366 const char *p1, *p2; 8367 8368 if (!validate_arglist (arglist, 8369 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8370 return 0; 8371 8372 arg1 = TREE_VALUE (arglist); 8373 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 8374 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8375 8376 /* If the LEN parameter is zero, return zero. */ 8377 if (integer_zerop (len)) 8378 return omit_two_operands (integer_type_node, integer_zero_node, 8379 arg1, arg2); 8380 8381 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8382 if (operand_equal_p (arg1, arg2, 0)) 8383 return omit_one_operand (integer_type_node, integer_zero_node, len); 8384 8385 p1 = c_getstr (arg1); 8386 p2 = c_getstr (arg2); 8387 8388 /* If all arguments are constant, and the value of len is not greater 8389 than the lengths of arg1 and arg2, evaluate at compile-time. */ 8390 if (host_integerp (len, 1) && p1 && p2 8391 && compare_tree_int (len, strlen (p1) + 1) <= 0 8392 && compare_tree_int (len, strlen (p2) + 1) <= 0) 8393 { 8394 const int r = memcmp (p1, p2, tree_low_cst (len, 1)); 8395 8396 if (r > 0) 8397 return integer_one_node; 8398 else if (r < 0) 8399 return integer_minus_one_node; 8400 else 8401 return integer_zero_node; 8402 } 8403 8404 /* If len parameter is one, return an expression corresponding to 8405 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ 8406 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1) 8407 { 8408 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8409 tree cst_uchar_ptr_node 8410 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8411 8412 tree ind1 = fold_convert (integer_type_node, 8413 build1 (INDIRECT_REF, cst_uchar_node, 8414 fold_convert (cst_uchar_ptr_node, 8415 arg1))); 8416 tree ind2 = fold_convert (integer_type_node, 8417 build1 (INDIRECT_REF, cst_uchar_node, 8418 fold_convert (cst_uchar_ptr_node, 8419 arg2))); 8420 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2); 8421 } 8422 8423 return 0; 8424} 8425 8426/* Fold function call to builtin strcmp. Return 8427 NULL_TREE if no simplification can be made. */ 8428 8429static tree 8430fold_builtin_strcmp (tree arglist) 8431{ 8432 tree arg1, arg2; 8433 const char *p1, *p2; 8434 8435 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 8436 return 0; 8437 8438 arg1 = TREE_VALUE (arglist); 8439 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 8440 8441 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8442 if (operand_equal_p (arg1, arg2, 0)) 8443 return integer_zero_node; 8444 8445 p1 = c_getstr (arg1); 8446 p2 = c_getstr (arg2); 8447 8448 if (p1 && p2) 8449 { 8450 const int i = strcmp (p1, p2); 8451 if (i < 0) 8452 return integer_minus_one_node; 8453 else if (i > 0) 8454 return integer_one_node; 8455 else 8456 return integer_zero_node; 8457 } 8458 8459 /* If the second arg is "", return *(const unsigned char*)arg1. */ 8460 if (p2 && *p2 == '\0') 8461 { 8462 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8463 tree cst_uchar_ptr_node 8464 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8465 8466 return fold_convert (integer_type_node, 8467 build1 (INDIRECT_REF, cst_uchar_node, 8468 fold_convert (cst_uchar_ptr_node, 8469 arg1))); 8470 } 8471 8472 /* If the first arg is "", return -*(const unsigned char*)arg2. */ 8473 if (p1 && *p1 == '\0') 8474 { 8475 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8476 tree cst_uchar_ptr_node 8477 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8478 8479 tree temp = fold_convert (integer_type_node, 8480 build1 (INDIRECT_REF, cst_uchar_node, 8481 fold_convert (cst_uchar_ptr_node, 8482 arg2))); 8483 return fold_build1 (NEGATE_EXPR, integer_type_node, temp); 8484 } 8485 8486 return 0; 8487} 8488 8489/* Fold function call to builtin strncmp. Return 8490 NULL_TREE if no simplification can be made. */ 8491 8492static tree 8493fold_builtin_strncmp (tree arglist) 8494{ 8495 tree arg1, arg2, len; 8496 const char *p1, *p2; 8497 8498 if (!validate_arglist (arglist, 8499 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 8500 return 0; 8501 8502 arg1 = TREE_VALUE (arglist); 8503 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 8504 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 8505 8506 /* If the LEN parameter is zero, return zero. */ 8507 if (integer_zerop (len)) 8508 return omit_two_operands (integer_type_node, integer_zero_node, 8509 arg1, arg2); 8510 8511 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 8512 if (operand_equal_p (arg1, arg2, 0)) 8513 return omit_one_operand (integer_type_node, integer_zero_node, len); 8514 8515 p1 = c_getstr (arg1); 8516 p2 = c_getstr (arg2); 8517 8518 if (host_integerp (len, 1) && p1 && p2) 8519 { 8520 const int i = strncmp (p1, p2, tree_low_cst (len, 1)); 8521 if (i > 0) 8522 return integer_one_node; 8523 else if (i < 0) 8524 return integer_minus_one_node; 8525 else 8526 return integer_zero_node; 8527 } 8528 8529 /* If the second arg is "", and the length is greater than zero, 8530 return *(const unsigned char*)arg1. */ 8531 if (p2 && *p2 == '\0' 8532 && TREE_CODE (len) == INTEGER_CST 8533 && tree_int_cst_sgn (len) == 1) 8534 { 8535 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8536 tree cst_uchar_ptr_node 8537 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8538 8539 return fold_convert (integer_type_node, 8540 build1 (INDIRECT_REF, cst_uchar_node, 8541 fold_convert (cst_uchar_ptr_node, 8542 arg1))); 8543 } 8544 8545 /* If the first arg is "", and the length is greater than zero, 8546 return -*(const unsigned char*)arg2. */ 8547 if (p1 && *p1 == '\0' 8548 && TREE_CODE (len) == INTEGER_CST 8549 && tree_int_cst_sgn (len) == 1) 8550 { 8551 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8552 tree cst_uchar_ptr_node 8553 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8554 8555 tree temp = fold_convert (integer_type_node, 8556 build1 (INDIRECT_REF, cst_uchar_node, 8557 fold_convert (cst_uchar_ptr_node, 8558 arg2))); 8559 return fold_build1 (NEGATE_EXPR, integer_type_node, temp); 8560 } 8561 8562 /* If len parameter is one, return an expression corresponding to 8563 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ 8564 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1) 8565 { 8566 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 8567 tree cst_uchar_ptr_node 8568 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true); 8569 8570 tree ind1 = fold_convert (integer_type_node, 8571 build1 (INDIRECT_REF, cst_uchar_node, 8572 fold_convert (cst_uchar_ptr_node, 8573 arg1))); 8574 tree ind2 = fold_convert (integer_type_node, 8575 build1 (INDIRECT_REF, cst_uchar_node, 8576 fold_convert (cst_uchar_ptr_node, 8577 arg2))); 8578 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2); 8579 } 8580 8581 return 0; 8582} 8583 8584/* Fold function call to builtin signbit, signbitf or signbitl. Return 8585 NULL_TREE if no simplification can be made. */ 8586 8587static tree 8588fold_builtin_signbit (tree fndecl, tree arglist) 8589{ 8590 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8591 tree arg, temp; 8592 8593 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 8594 return NULL_TREE; 8595 8596 arg = TREE_VALUE (arglist); 8597 8598 /* If ARG is a compile-time constant, determine the result. */ 8599 if (TREE_CODE (arg) == REAL_CST 8600 && !TREE_CONSTANT_OVERFLOW (arg)) 8601 { 8602 REAL_VALUE_TYPE c; 8603 8604 c = TREE_REAL_CST (arg); 8605 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node; 8606 return fold_convert (type, temp); 8607 } 8608 8609 /* If ARG is non-negative, the result is always zero. */ 8610 if (tree_expr_nonnegative_p (arg)) 8611 return omit_one_operand (type, integer_zero_node, arg); 8612 8613 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */ 8614 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg)))) 8615 return fold_build2 (LT_EXPR, type, arg, 8616 build_real (TREE_TYPE (arg), dconst0)); 8617 8618 return NULL_TREE; 8619} 8620 8621/* Fold function call to builtin copysign, copysignf or copysignl. 8622 Return NULL_TREE if no simplification can be made. */ 8623 8624static tree 8625fold_builtin_copysign (tree fndecl, tree arglist, tree type) 8626{ 8627 tree arg1, arg2, tem; 8628 8629 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 8630 return NULL_TREE; 8631 8632 arg1 = TREE_VALUE (arglist); 8633 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 8634 8635 /* copysign(X,X) is X. */ 8636 if (operand_equal_p (arg1, arg2, 0)) 8637 return fold_convert (type, arg1); 8638 8639 /* If ARG1 and ARG2 are compile-time constants, determine the result. */ 8640 if (TREE_CODE (arg1) == REAL_CST 8641 && TREE_CODE (arg2) == REAL_CST 8642 && !TREE_CONSTANT_OVERFLOW (arg1) 8643 && !TREE_CONSTANT_OVERFLOW (arg2)) 8644 { 8645 REAL_VALUE_TYPE c1, c2; 8646 8647 c1 = TREE_REAL_CST (arg1); 8648 c2 = TREE_REAL_CST (arg2); 8649 /* c1.sign := c2.sign. */ 8650 real_copysign (&c1, &c2); 8651 return build_real (type, c1); 8652 } 8653 8654 /* copysign(X, Y) is fabs(X) when Y is always non-negative. 8655 Remember to evaluate Y for side-effects. */ 8656 if (tree_expr_nonnegative_p (arg2)) 8657 return omit_one_operand (type, 8658 fold_build1 (ABS_EXPR, type, arg1), 8659 arg2); 8660 8661 /* Strip sign changing operations for the first argument. */ 8662 tem = fold_strip_sign_ops (arg1); 8663 if (tem) 8664 { 8665 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist)); 8666 return build_function_call_expr (fndecl, arglist); 8667 } 8668 8669 return NULL_TREE; 8670} 8671 8672/* Fold a call to builtin isascii. */ 8673 8674static tree 8675fold_builtin_isascii (tree arglist) 8676{ 8677 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 8678 return 0; 8679 else 8680 { 8681 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */ 8682 tree arg = TREE_VALUE (arglist); 8683 8684 arg = build2 (BIT_AND_EXPR, integer_type_node, arg, 8685 build_int_cst (NULL_TREE, 8686 ~ (unsigned HOST_WIDE_INT) 0x7f)); 8687 arg = fold_build2 (EQ_EXPR, integer_type_node, 8688 arg, integer_zero_node); 8689 8690 if (in_gimple_form && !TREE_CONSTANT (arg)) 8691 return NULL_TREE; 8692 else 8693 return arg; 8694 } 8695} 8696 8697/* Fold a call to builtin toascii. */ 8698 8699static tree 8700fold_builtin_toascii (tree arglist) 8701{ 8702 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 8703 return 0; 8704 else 8705 { 8706 /* Transform toascii(c) -> (c & 0x7f). */ 8707 tree arg = TREE_VALUE (arglist); 8708 8709 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg, 8710 build_int_cst (NULL_TREE, 0x7f)); 8711 } 8712} 8713 8714/* Fold a call to builtin isdigit. */ 8715 8716static tree 8717fold_builtin_isdigit (tree arglist) 8718{ 8719 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 8720 return 0; 8721 else 8722 { 8723 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */ 8724 /* According to the C standard, isdigit is unaffected by locale. 8725 However, it definitely is affected by the target character set. */ 8726 tree arg; 8727 unsigned HOST_WIDE_INT target_digit0 8728 = lang_hooks.to_target_charset ('0'); 8729 8730 if (target_digit0 == 0) 8731 return NULL_TREE; 8732 8733 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist)); 8734 arg = build2 (MINUS_EXPR, unsigned_type_node, arg, 8735 build_int_cst (unsigned_type_node, target_digit0)); 8736 arg = fold_build2 (LE_EXPR, integer_type_node, arg, 8737 build_int_cst (unsigned_type_node, 9)); 8738 if (in_gimple_form && !TREE_CONSTANT (arg)) 8739 return NULL_TREE; 8740 else 8741 return arg; 8742 } 8743} 8744 8745/* Fold a call to fabs, fabsf or fabsl. */ 8746 8747static tree 8748fold_builtin_fabs (tree arglist, tree type) 8749{ 8750 tree arg; 8751 8752 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 8753 return 0; 8754 8755 arg = TREE_VALUE (arglist); 8756 arg = fold_convert (type, arg); 8757 if (TREE_CODE (arg) == REAL_CST) 8758 return fold_abs_const (arg, type); 8759 return fold_build1 (ABS_EXPR, type, arg); 8760} 8761 8762/* Fold a call to abs, labs, llabs or imaxabs. */ 8763 8764static tree 8765fold_builtin_abs (tree arglist, tree type) 8766{ 8767 tree arg; 8768 8769 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 8770 return 0; 8771 8772 arg = TREE_VALUE (arglist); 8773 arg = fold_convert (type, arg); 8774 if (TREE_CODE (arg) == INTEGER_CST) 8775 return fold_abs_const (arg, type); 8776 return fold_build1 (ABS_EXPR, type, arg); 8777} 8778 8779/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite. 8780 EXP is the CALL_EXPR for the call. */ 8781 8782static tree 8783fold_builtin_classify (tree fndecl, tree arglist, int builtin_index) 8784{ 8785 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8786 tree arg; 8787 REAL_VALUE_TYPE r; 8788 8789 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 8790 { 8791 /* Check that we have exactly one argument. */ 8792 if (arglist == 0) 8793 { 8794 error ("too few arguments to function %qs", 8795 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8796 return error_mark_node; 8797 } 8798 else if (TREE_CHAIN (arglist) != 0) 8799 { 8800 error ("too many arguments to function %qs", 8801 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8802 return error_mark_node; 8803 } 8804 else 8805 { 8806 error ("non-floating-point argument to function %qs", 8807 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8808 return error_mark_node; 8809 } 8810 } 8811 8812 arg = TREE_VALUE (arglist); 8813 switch (builtin_index) 8814 { 8815 case BUILT_IN_ISINF: 8816 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg)))) 8817 return omit_one_operand (type, integer_zero_node, arg); 8818 8819 if (TREE_CODE (arg) == REAL_CST) 8820 { 8821 r = TREE_REAL_CST (arg); 8822 if (real_isinf (&r)) 8823 return real_compare (GT_EXPR, &r, &dconst0) 8824 ? integer_one_node : integer_minus_one_node; 8825 else 8826 return integer_zero_node; 8827 } 8828 8829 return NULL_TREE; 8830 8831 case BUILT_IN_FINITE: 8832 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))) 8833 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg)))) 8834 return omit_one_operand (type, integer_one_node, arg); 8835 8836 if (TREE_CODE (arg) == REAL_CST) 8837 { 8838 r = TREE_REAL_CST (arg); 8839 return real_isinf (&r) || real_isnan (&r) 8840 ? integer_zero_node : integer_one_node; 8841 } 8842 8843 return NULL_TREE; 8844 8845 case BUILT_IN_ISNAN: 8846 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))) 8847 return omit_one_operand (type, integer_zero_node, arg); 8848 8849 if (TREE_CODE (arg) == REAL_CST) 8850 { 8851 r = TREE_REAL_CST (arg); 8852 return real_isnan (&r) ? integer_one_node : integer_zero_node; 8853 } 8854 8855 arg = builtin_save_expr (arg); 8856 return fold_build2 (UNORDERED_EXPR, type, arg, arg); 8857 8858 default: 8859 gcc_unreachable (); 8860 } 8861} 8862 8863/* Fold a call to an unordered comparison function such as 8864 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function 8865 being called and ARGLIST is the argument list for the call. 8866 UNORDERED_CODE and ORDERED_CODE are comparison codes that give 8867 the opposite of the desired result. UNORDERED_CODE is used 8868 for modes that can hold NaNs and ORDERED_CODE is used for 8869 the rest. */ 8870 8871static tree 8872fold_builtin_unordered_cmp (tree fndecl, tree arglist, 8873 enum tree_code unordered_code, 8874 enum tree_code ordered_code) 8875{ 8876 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8877 enum tree_code code; 8878 tree arg0, arg1; 8879 tree type0, type1; 8880 enum tree_code code0, code1; 8881 tree cmp_type = NULL_TREE; 8882 8883 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 8884 { 8885 /* Check that we have exactly two arguments. */ 8886 if (arglist == 0 || TREE_CHAIN (arglist) == 0) 8887 { 8888 error ("too few arguments to function %qs", 8889 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8890 return error_mark_node; 8891 } 8892 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0) 8893 { 8894 error ("too many arguments to function %qs", 8895 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8896 return error_mark_node; 8897 } 8898 } 8899 8900 arg0 = TREE_VALUE (arglist); 8901 arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 8902 8903 type0 = TREE_TYPE (arg0); 8904 type1 = TREE_TYPE (arg1); 8905 8906 code0 = TREE_CODE (type0); 8907 code1 = TREE_CODE (type1); 8908 8909 if (code0 == REAL_TYPE && code1 == REAL_TYPE) 8910 /* Choose the wider of two real types. */ 8911 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1) 8912 ? type0 : type1; 8913 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE) 8914 cmp_type = type0; 8915 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE) 8916 cmp_type = type1; 8917 else 8918 { 8919 error ("non-floating-point argument to function %qs", 8920 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 8921 return error_mark_node; 8922 } 8923 8924 arg0 = fold_convert (cmp_type, arg0); 8925 arg1 = fold_convert (cmp_type, arg1); 8926 8927 if (unordered_code == UNORDERED_EXPR) 8928 { 8929 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))) 8930 return omit_two_operands (type, integer_zero_node, arg0, arg1); 8931 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1); 8932 } 8933 8934 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code 8935 : ordered_code; 8936 return fold_build1 (TRUTH_NOT_EXPR, type, 8937 fold_build2 (code, type, arg0, arg1)); 8938} 8939 8940/* Used by constant folding to simplify calls to builtin functions. EXP is 8941 the CALL_EXPR of a call to a builtin function. IGNORE is true if the 8942 result of the function call is ignored. This function returns NULL_TREE 8943 if no simplification was possible. */ 8944 8945static tree 8946fold_builtin_1 (tree fndecl, tree arglist, bool ignore) 8947{ 8948 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 8949 enum built_in_function fcode; 8950 8951 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 8952 return targetm.fold_builtin (fndecl, arglist, ignore); 8953 8954 fcode = DECL_FUNCTION_CODE (fndecl); 8955 switch (fcode) 8956 { 8957 case BUILT_IN_FPUTS: 8958 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE); 8959 8960 case BUILT_IN_FPUTS_UNLOCKED: 8961 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE); 8962 8963 case BUILT_IN_STRSTR: 8964 return fold_builtin_strstr (arglist, type); 8965 8966 case BUILT_IN_STRCAT: 8967 return fold_builtin_strcat (arglist); 8968 8969 case BUILT_IN_STRNCAT: 8970 return fold_builtin_strncat (arglist); 8971 8972 case BUILT_IN_STRSPN: 8973 return fold_builtin_strspn (arglist); 8974 8975 case BUILT_IN_STRCSPN: 8976 return fold_builtin_strcspn (arglist); 8977 8978 case BUILT_IN_STRCHR: 8979 case BUILT_IN_INDEX: 8980 return fold_builtin_strchr (arglist, type); 8981 8982 case BUILT_IN_STRRCHR: 8983 case BUILT_IN_RINDEX: 8984 return fold_builtin_strrchr (arglist, type); 8985 8986 case BUILT_IN_STRCPY: 8987 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE); 8988 8989 case BUILT_IN_STRNCPY: 8990 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE); 8991 8992 case BUILT_IN_STRCMP: 8993 return fold_builtin_strcmp (arglist); 8994 8995 case BUILT_IN_STRNCMP: 8996 return fold_builtin_strncmp (arglist); 8997 8998 case BUILT_IN_STRPBRK: 8999 return fold_builtin_strpbrk (arglist, type); 9000 9001 case BUILT_IN_BCMP: 9002 case BUILT_IN_MEMCMP: 9003 return fold_builtin_memcmp (arglist); 9004 9005 case BUILT_IN_SPRINTF: 9006 return fold_builtin_sprintf (arglist, ignore); 9007 9008 case BUILT_IN_CONSTANT_P: 9009 { 9010 tree val; 9011 9012 val = fold_builtin_constant_p (arglist); 9013 /* Gimplification will pull the CALL_EXPR for the builtin out of 9014 an if condition. When not optimizing, we'll not CSE it back. 9015 To avoid link error types of regressions, return false now. */ 9016 if (!val && !optimize) 9017 val = integer_zero_node; 9018 9019 return val; 9020 } 9021 9022 case BUILT_IN_EXPECT: 9023 return fold_builtin_expect (arglist); 9024 9025 case BUILT_IN_CLASSIFY_TYPE: 9026 return fold_builtin_classify_type (arglist); 9027 9028 case BUILT_IN_STRLEN: 9029 return fold_builtin_strlen (arglist); 9030 9031 CASE_FLT_FN (BUILT_IN_FABS): 9032 return fold_builtin_fabs (arglist, type); 9033 9034 case BUILT_IN_ABS: 9035 case BUILT_IN_LABS: 9036 case BUILT_IN_LLABS: 9037 case BUILT_IN_IMAXABS: 9038 return fold_builtin_abs (arglist, type); 9039 9040 CASE_FLT_FN (BUILT_IN_CONJ): 9041 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE)) 9042 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist)); 9043 break; 9044 9045 CASE_FLT_FN (BUILT_IN_CREAL): 9046 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE)) 9047 return non_lvalue (fold_build1 (REALPART_EXPR, type, 9048 TREE_VALUE (arglist))); 9049 break; 9050 9051 CASE_FLT_FN (BUILT_IN_CIMAG): 9052 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE)) 9053 return non_lvalue (fold_build1 (IMAGPART_EXPR, type, 9054 TREE_VALUE (arglist))); 9055 break; 9056 9057 CASE_FLT_FN (BUILT_IN_CABS): 9058 return fold_builtin_cabs (arglist, type, fndecl); 9059 9060 CASE_FLT_FN (BUILT_IN_SQRT): 9061 return fold_builtin_sqrt (arglist, type); 9062 9063 CASE_FLT_FN (BUILT_IN_CBRT): 9064 return fold_builtin_cbrt (arglist, type); 9065 9066 CASE_FLT_FN (BUILT_IN_SIN): 9067 return fold_builtin_sin (arglist); 9068 9069 CASE_FLT_FN (BUILT_IN_COS): 9070 return fold_builtin_cos (arglist, type, fndecl); 9071 9072 CASE_FLT_FN (BUILT_IN_EXP): 9073 return fold_builtin_exponent (fndecl, arglist, &dconste); 9074 9075 CASE_FLT_FN (BUILT_IN_EXP2): 9076 return fold_builtin_exponent (fndecl, arglist, &dconst2); 9077 9078 CASE_FLT_FN (BUILT_IN_EXP10): 9079 CASE_FLT_FN (BUILT_IN_POW10): 9080 return fold_builtin_exponent (fndecl, arglist, &dconst10); 9081 9082 CASE_FLT_FN (BUILT_IN_LOG): 9083 return fold_builtin_logarithm (fndecl, arglist, &dconste); 9084 9085 CASE_FLT_FN (BUILT_IN_LOG2): 9086 return fold_builtin_logarithm (fndecl, arglist, &dconst2); 9087 9088 CASE_FLT_FN (BUILT_IN_LOG10): 9089 return fold_builtin_logarithm (fndecl, arglist, &dconst10); 9090 9091 CASE_FLT_FN (BUILT_IN_TAN): 9092 return fold_builtin_tan (arglist); 9093 9094 CASE_FLT_FN (BUILT_IN_ATAN): 9095 return fold_builtin_atan (arglist, type); 9096 9097 CASE_FLT_FN (BUILT_IN_POW): 9098 return fold_builtin_pow (fndecl, arglist, type); 9099 9100 CASE_FLT_FN (BUILT_IN_POWI): 9101 return fold_builtin_powi (fndecl, arglist, type); 9102 9103 CASE_FLT_FN (BUILT_IN_INF): 9104 case BUILT_IN_INFD32: 9105 case BUILT_IN_INFD64: 9106 case BUILT_IN_INFD128: 9107 return fold_builtin_inf (type, true); 9108 9109 CASE_FLT_FN (BUILT_IN_HUGE_VAL): 9110 return fold_builtin_inf (type, false); 9111 9112 CASE_FLT_FN (BUILT_IN_NAN): 9113 case BUILT_IN_NAND32: 9114 case BUILT_IN_NAND64: 9115 case BUILT_IN_NAND128: 9116 return fold_builtin_nan (arglist, type, true); 9117 9118 CASE_FLT_FN (BUILT_IN_NANS): 9119 return fold_builtin_nan (arglist, type, false); 9120 9121 CASE_FLT_FN (BUILT_IN_FLOOR): 9122 return fold_builtin_floor (fndecl, arglist); 9123 9124 CASE_FLT_FN (BUILT_IN_CEIL): 9125 return fold_builtin_ceil (fndecl, arglist); 9126 9127 CASE_FLT_FN (BUILT_IN_TRUNC): 9128 return fold_builtin_trunc (fndecl, arglist); 9129 9130 CASE_FLT_FN (BUILT_IN_ROUND): 9131 return fold_builtin_round (fndecl, arglist); 9132 9133 CASE_FLT_FN (BUILT_IN_NEARBYINT): 9134 CASE_FLT_FN (BUILT_IN_RINT): 9135 return fold_trunc_transparent_mathfn (fndecl, arglist); 9136 9137 CASE_FLT_FN (BUILT_IN_LCEIL): 9138 CASE_FLT_FN (BUILT_IN_LLCEIL): 9139 CASE_FLT_FN (BUILT_IN_LFLOOR): 9140 CASE_FLT_FN (BUILT_IN_LLFLOOR): 9141 CASE_FLT_FN (BUILT_IN_LROUND): 9142 CASE_FLT_FN (BUILT_IN_LLROUND): 9143 return fold_builtin_int_roundingfn (fndecl, arglist); 9144 9145 CASE_FLT_FN (BUILT_IN_LRINT): 9146 CASE_FLT_FN (BUILT_IN_LLRINT): 9147 return fold_fixed_mathfn (fndecl, arglist); 9148 9149 case BUILT_IN_BSWAP32: 9150 case BUILT_IN_BSWAP64: 9151 return fold_builtin_bswap (fndecl, arglist); 9152 9153 CASE_INT_FN (BUILT_IN_FFS): 9154 CASE_INT_FN (BUILT_IN_CLZ): 9155 CASE_INT_FN (BUILT_IN_CTZ): 9156 CASE_INT_FN (BUILT_IN_POPCOUNT): 9157 CASE_INT_FN (BUILT_IN_PARITY): 9158 return fold_builtin_bitop (fndecl, arglist); 9159 9160 case BUILT_IN_MEMSET: 9161 return fold_builtin_memset (arglist, type, ignore); 9162 9163 case BUILT_IN_MEMCPY: 9164 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0); 9165 9166 case BUILT_IN_MEMPCPY: 9167 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1); 9168 9169 case BUILT_IN_MEMMOVE: 9170 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3); 9171 9172 case BUILT_IN_BZERO: 9173 return fold_builtin_bzero (arglist, ignore); 9174 9175 case BUILT_IN_BCOPY: 9176 return fold_builtin_bcopy (arglist, ignore); 9177 9178 CASE_FLT_FN (BUILT_IN_SIGNBIT): 9179 return fold_builtin_signbit (fndecl, arglist); 9180 9181 case BUILT_IN_ISASCII: 9182 return fold_builtin_isascii (arglist); 9183 9184 case BUILT_IN_TOASCII: 9185 return fold_builtin_toascii (arglist); 9186 9187 case BUILT_IN_ISDIGIT: 9188 return fold_builtin_isdigit (arglist); 9189 9190 CASE_FLT_FN (BUILT_IN_COPYSIGN): 9191 return fold_builtin_copysign (fndecl, arglist, type); 9192 9193 CASE_FLT_FN (BUILT_IN_FINITE): 9194 case BUILT_IN_FINITED32: 9195 case BUILT_IN_FINITED64: 9196 case BUILT_IN_FINITED128: 9197 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE); 9198 9199 CASE_FLT_FN (BUILT_IN_ISINF): 9200 case BUILT_IN_ISINFD32: 9201 case BUILT_IN_ISINFD64: 9202 case BUILT_IN_ISINFD128: 9203 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF); 9204 9205 CASE_FLT_FN (BUILT_IN_ISNAN): 9206 case BUILT_IN_ISNAND32: 9207 case BUILT_IN_ISNAND64: 9208 case BUILT_IN_ISNAND128: 9209 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN); 9210 9211 case BUILT_IN_ISGREATER: 9212 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR); 9213 case BUILT_IN_ISGREATEREQUAL: 9214 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR); 9215 case BUILT_IN_ISLESS: 9216 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR); 9217 case BUILT_IN_ISLESSEQUAL: 9218 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR); 9219 case BUILT_IN_ISLESSGREATER: 9220 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR); 9221 case BUILT_IN_ISUNORDERED: 9222 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR, 9223 NOP_EXPR); 9224 9225 /* We do the folding for va_start in the expander. */ 9226 case BUILT_IN_VA_START: 9227 break; 9228 9229 case BUILT_IN_OBJECT_SIZE: 9230 return fold_builtin_object_size (arglist); 9231 case BUILT_IN_MEMCPY_CHK: 9232 case BUILT_IN_MEMPCPY_CHK: 9233 case BUILT_IN_MEMMOVE_CHK: 9234 case BUILT_IN_MEMSET_CHK: 9235 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore, 9236 DECL_FUNCTION_CODE (fndecl)); 9237 case BUILT_IN_STRCPY_CHK: 9238 case BUILT_IN_STPCPY_CHK: 9239 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore, 9240 DECL_FUNCTION_CODE (fndecl)); 9241 case BUILT_IN_STRNCPY_CHK: 9242 return fold_builtin_strncpy_chk (arglist, NULL_TREE); 9243 case BUILT_IN_STRCAT_CHK: 9244 return fold_builtin_strcat_chk (fndecl, arglist); 9245 case BUILT_IN_STRNCAT_CHK: 9246 return fold_builtin_strncat_chk (fndecl, arglist); 9247 case BUILT_IN_SPRINTF_CHK: 9248 case BUILT_IN_VSPRINTF_CHK: 9249 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl)); 9250 case BUILT_IN_SNPRINTF_CHK: 9251 case BUILT_IN_VSNPRINTF_CHK: 9252 return fold_builtin_snprintf_chk (arglist, NULL_TREE, 9253 DECL_FUNCTION_CODE (fndecl)); 9254 9255 case BUILT_IN_PRINTF: 9256 case BUILT_IN_PRINTF_UNLOCKED: 9257 case BUILT_IN_VPRINTF: 9258 case BUILT_IN_PRINTF_CHK: 9259 case BUILT_IN_VPRINTF_CHK: 9260 return fold_builtin_printf (fndecl, arglist, ignore, 9261 DECL_FUNCTION_CODE (fndecl)); 9262 9263 case BUILT_IN_FPRINTF: 9264 case BUILT_IN_FPRINTF_UNLOCKED: 9265 case BUILT_IN_VFPRINTF: 9266 case BUILT_IN_FPRINTF_CHK: 9267 case BUILT_IN_VFPRINTF_CHK: 9268 return fold_builtin_fprintf (fndecl, arglist, ignore, 9269 DECL_FUNCTION_CODE (fndecl)); 9270 9271 default: 9272 break; 9273 } 9274 9275 return 0; 9276} 9277 9278/* A wrapper function for builtin folding that prevents warnings for 9279 "statement without effect" and the like, caused by removing the 9280 call node earlier than the warning is generated. */ 9281 9282tree 9283fold_builtin (tree fndecl, tree arglist, bool ignore) 9284{ 9285 tree exp = fold_builtin_1 (fndecl, arglist, ignore); 9286 if (exp) 9287 { 9288 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp); 9289 TREE_NO_WARNING (exp) = 1; 9290 } 9291 9292 return exp; 9293} 9294 9295/* Conveniently construct a function call expression. */ 9296 9297tree 9298build_function_call_expr (tree fn, tree arglist) 9299{ 9300 tree call_expr; 9301 9302 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); 9303 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)), 9304 call_expr, arglist, NULL_TREE); 9305} 9306 9307/* This function validates the types of a function call argument list 9308 represented as a tree chain of parameters against a specified list 9309 of tree_codes. If the last specifier is a 0, that represents an 9310 ellipses, otherwise the last specifier must be a VOID_TYPE. */ 9311 9312static int 9313validate_arglist (tree arglist, ...) 9314{ 9315 enum tree_code code; 9316 int res = 0; 9317 va_list ap; 9318 9319 va_start (ap, arglist); 9320 9321 do 9322 { 9323 code = va_arg (ap, enum tree_code); 9324 switch (code) 9325 { 9326 case 0: 9327 /* This signifies an ellipses, any further arguments are all ok. */ 9328 res = 1; 9329 goto end; 9330 case VOID_TYPE: 9331 /* This signifies an endlink, if no arguments remain, return 9332 true, otherwise return false. */ 9333 res = arglist == 0; 9334 goto end; 9335 default: 9336 /* If no parameters remain or the parameter's code does not 9337 match the specified code, return false. Otherwise continue 9338 checking any remaining arguments. */ 9339 if (arglist == 0) 9340 goto end; 9341 if (code == POINTER_TYPE) 9342 { 9343 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))) 9344 goto end; 9345 } 9346 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist)))) 9347 goto end; 9348 break; 9349 } 9350 arglist = TREE_CHAIN (arglist); 9351 } 9352 while (1); 9353 9354 /* We need gotos here since we can only have one VA_CLOSE in a 9355 function. */ 9356 end: ; 9357 va_end (ap); 9358 9359 return res; 9360} 9361 9362/* Default target-specific builtin expander that does nothing. */ 9363 9364rtx 9365default_expand_builtin (tree exp ATTRIBUTE_UNUSED, 9366 rtx target ATTRIBUTE_UNUSED, 9367 rtx subtarget ATTRIBUTE_UNUSED, 9368 enum machine_mode mode ATTRIBUTE_UNUSED, 9369 int ignore ATTRIBUTE_UNUSED) 9370{ 9371 return NULL_RTX; 9372} 9373 9374/* Returns true is EXP represents data that would potentially reside 9375 in a readonly section. */ 9376 9377static bool 9378readonly_data_expr (tree exp) 9379{ 9380 STRIP_NOPS (exp); 9381 9382 if (TREE_CODE (exp) != ADDR_EXPR) 9383 return false; 9384 9385 exp = get_base_address (TREE_OPERAND (exp, 0)); 9386 if (!exp) 9387 return false; 9388 9389 /* Make sure we call decl_readonly_section only for trees it 9390 can handle (since it returns true for everything it doesn't 9391 understand). */ 9392 if (TREE_CODE (exp) == STRING_CST 9393 || TREE_CODE (exp) == CONSTRUCTOR 9394 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp))) 9395 return decl_readonly_section (exp, 0); 9396 else 9397 return false; 9398} 9399 9400/* Simplify a call to the strstr builtin. 9401 9402 Return 0 if no simplification was possible, otherwise return the 9403 simplified form of the call as a tree. 9404 9405 The simplified form may be a constant or other expression which 9406 computes the same value, but in a more efficient manner (including 9407 calls to other builtin functions). 9408 9409 The call may contain arguments which need to be evaluated, but 9410 which are not useful to determine the result of the call. In 9411 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9412 COMPOUND_EXPR will be an argument which must be evaluated. 9413 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9414 COMPOUND_EXPR in the chain will contain the tree for the simplified 9415 form of the builtin function call. */ 9416 9417static tree 9418fold_builtin_strstr (tree arglist, tree type) 9419{ 9420 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9421 return 0; 9422 else 9423 { 9424 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9425 tree fn; 9426 const char *p1, *p2; 9427 9428 p2 = c_getstr (s2); 9429 if (p2 == NULL) 9430 return 0; 9431 9432 p1 = c_getstr (s1); 9433 if (p1 != NULL) 9434 { 9435 const char *r = strstr (p1, p2); 9436 tree tem; 9437 9438 if (r == NULL) 9439 return build_int_cst (TREE_TYPE (s1), 0); 9440 9441 /* Return an offset into the constant string argument. */ 9442 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1), 9443 s1, build_int_cst (TREE_TYPE (s1), r - p1)); 9444 return fold_convert (type, tem); 9445 } 9446 9447 /* The argument is const char *, and the result is char *, so we need 9448 a type conversion here to avoid a warning. */ 9449 if (p2[0] == '\0') 9450 return fold_convert (type, s1); 9451 9452 if (p2[1] != '\0') 9453 return 0; 9454 9455 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 9456 if (!fn) 9457 return 0; 9458 9459 /* New argument list transforming strstr(s1, s2) to 9460 strchr(s1, s2[0]). */ 9461 arglist = build_tree_list (NULL_TREE, 9462 build_int_cst (NULL_TREE, p2[0])); 9463 arglist = tree_cons (NULL_TREE, s1, arglist); 9464 return build_function_call_expr (fn, arglist); 9465 } 9466} 9467 9468/* Simplify a call to the strchr builtin. 9469 9470 Return 0 if no simplification was possible, otherwise return the 9471 simplified form of the call as a tree. 9472 9473 The simplified form may be a constant or other expression which 9474 computes the same value, but in a more efficient manner (including 9475 calls to other builtin functions). 9476 9477 The call may contain arguments which need to be evaluated, but 9478 which are not useful to determine the result of the call. In 9479 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9480 COMPOUND_EXPR will be an argument which must be evaluated. 9481 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9482 COMPOUND_EXPR in the chain will contain the tree for the simplified 9483 form of the builtin function call. */ 9484 9485static tree 9486fold_builtin_strchr (tree arglist, tree type) 9487{ 9488 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 9489 return 0; 9490 else 9491 { 9492 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9493 const char *p1; 9494 9495 if (TREE_CODE (s2) != INTEGER_CST) 9496 return 0; 9497 9498 p1 = c_getstr (s1); 9499 if (p1 != NULL) 9500 { 9501 char c; 9502 const char *r; 9503 tree tem; 9504 9505 if (target_char_cast (s2, &c)) 9506 return 0; 9507 9508 r = strchr (p1, c); 9509 9510 if (r == NULL) 9511 return build_int_cst (TREE_TYPE (s1), 0); 9512 9513 /* Return an offset into the constant string argument. */ 9514 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1), 9515 s1, build_int_cst (TREE_TYPE (s1), r - p1)); 9516 return fold_convert (type, tem); 9517 } 9518 return 0; 9519 } 9520} 9521 9522/* Simplify a call to the strrchr builtin. 9523 9524 Return 0 if no simplification was possible, otherwise return the 9525 simplified form of the call as a tree. 9526 9527 The simplified form may be a constant or other expression which 9528 computes the same value, but in a more efficient manner (including 9529 calls to other builtin functions). 9530 9531 The call may contain arguments which need to be evaluated, but 9532 which are not useful to determine the result of the call. In 9533 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9534 COMPOUND_EXPR will be an argument which must be evaluated. 9535 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9536 COMPOUND_EXPR in the chain will contain the tree for the simplified 9537 form of the builtin function call. */ 9538 9539static tree 9540fold_builtin_strrchr (tree arglist, tree type) 9541{ 9542 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 9543 return 0; 9544 else 9545 { 9546 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9547 tree fn; 9548 const char *p1; 9549 9550 if (TREE_CODE (s2) != INTEGER_CST) 9551 return 0; 9552 9553 p1 = c_getstr (s1); 9554 if (p1 != NULL) 9555 { 9556 char c; 9557 const char *r; 9558 tree tem; 9559 9560 if (target_char_cast (s2, &c)) 9561 return 0; 9562 9563 r = strrchr (p1, c); 9564 9565 if (r == NULL) 9566 return build_int_cst (TREE_TYPE (s1), 0); 9567 9568 /* Return an offset into the constant string argument. */ 9569 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1), 9570 s1, build_int_cst (TREE_TYPE (s1), r - p1)); 9571 return fold_convert (type, tem); 9572 } 9573 9574 if (! integer_zerop (s2)) 9575 return 0; 9576 9577 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 9578 if (!fn) 9579 return 0; 9580 9581 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */ 9582 return build_function_call_expr (fn, arglist); 9583 } 9584} 9585 9586/* Simplify a call to the strpbrk builtin. 9587 9588 Return 0 if no simplification was possible, otherwise return the 9589 simplified form of the call as a tree. 9590 9591 The simplified form may be a constant or other expression which 9592 computes the same value, but in a more efficient manner (including 9593 calls to other builtin functions). 9594 9595 The call may contain arguments which need to be evaluated, but 9596 which are not useful to determine the result of the call. In 9597 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9598 COMPOUND_EXPR will be an argument which must be evaluated. 9599 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9600 COMPOUND_EXPR in the chain will contain the tree for the simplified 9601 form of the builtin function call. */ 9602 9603static tree 9604fold_builtin_strpbrk (tree arglist, tree type) 9605{ 9606 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9607 return 0; 9608 else 9609 { 9610 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9611 tree fn; 9612 const char *p1, *p2; 9613 9614 p2 = c_getstr (s2); 9615 if (p2 == NULL) 9616 return 0; 9617 9618 p1 = c_getstr (s1); 9619 if (p1 != NULL) 9620 { 9621 const char *r = strpbrk (p1, p2); 9622 tree tem; 9623 9624 if (r == NULL) 9625 return build_int_cst (TREE_TYPE (s1), 0); 9626 9627 /* Return an offset into the constant string argument. */ 9628 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1), 9629 s1, build_int_cst (TREE_TYPE (s1), r - p1)); 9630 return fold_convert (type, tem); 9631 } 9632 9633 if (p2[0] == '\0') 9634 /* strpbrk(x, "") == NULL. 9635 Evaluate and ignore s1 in case it had side-effects. */ 9636 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1); 9637 9638 if (p2[1] != '\0') 9639 return 0; /* Really call strpbrk. */ 9640 9641 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 9642 if (!fn) 9643 return 0; 9644 9645 /* New argument list transforming strpbrk(s1, s2) to 9646 strchr(s1, s2[0]). */ 9647 arglist = build_tree_list (NULL_TREE, 9648 build_int_cst (NULL_TREE, p2[0])); 9649 arglist = tree_cons (NULL_TREE, s1, arglist); 9650 return build_function_call_expr (fn, arglist); 9651 } 9652} 9653 9654/* Simplify a call to the strcat builtin. 9655 9656 Return 0 if no simplification was possible, otherwise return the 9657 simplified form of the call as a tree. 9658 9659 The simplified form may be a constant or other expression which 9660 computes the same value, but in a more efficient manner (including 9661 calls to other builtin functions). 9662 9663 The call may contain arguments which need to be evaluated, but 9664 which are not useful to determine the result of the call. In 9665 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9666 COMPOUND_EXPR will be an argument which must be evaluated. 9667 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9668 COMPOUND_EXPR in the chain will contain the tree for the simplified 9669 form of the builtin function call. */ 9670 9671static tree 9672fold_builtin_strcat (tree arglist) 9673{ 9674 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9675 return 0; 9676 else 9677 { 9678 tree dst = TREE_VALUE (arglist), 9679 src = TREE_VALUE (TREE_CHAIN (arglist)); 9680 const char *p = c_getstr (src); 9681 9682 /* If the string length is zero, return the dst parameter. */ 9683 if (p && *p == '\0') 9684 return dst; 9685 9686 return 0; 9687 } 9688} 9689 9690/* Simplify a call to the strncat builtin. 9691 9692 Return 0 if no simplification was possible, otherwise return the 9693 simplified form of the call as a tree. 9694 9695 The simplified form may be a constant or other expression which 9696 computes the same value, but in a more efficient manner (including 9697 calls to other builtin functions). 9698 9699 The call may contain arguments which need to be evaluated, but 9700 which are not useful to determine the result of the call. In 9701 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9702 COMPOUND_EXPR will be an argument which must be evaluated. 9703 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9704 COMPOUND_EXPR in the chain will contain the tree for the simplified 9705 form of the builtin function call. */ 9706 9707static tree 9708fold_builtin_strncat (tree arglist) 9709{ 9710 if (!validate_arglist (arglist, 9711 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 9712 return 0; 9713 else 9714 { 9715 tree dst = TREE_VALUE (arglist); 9716 tree src = TREE_VALUE (TREE_CHAIN (arglist)); 9717 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 9718 const char *p = c_getstr (src); 9719 9720 /* If the requested length is zero, or the src parameter string 9721 length is zero, return the dst parameter. */ 9722 if (integer_zerop (len) || (p && *p == '\0')) 9723 return omit_two_operands (TREE_TYPE (dst), dst, src, len); 9724 9725 /* If the requested len is greater than or equal to the string 9726 length, call strcat. */ 9727 if (TREE_CODE (len) == INTEGER_CST && p 9728 && compare_tree_int (len, strlen (p)) >= 0) 9729 { 9730 tree newarglist 9731 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src)); 9732 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT]; 9733 9734 /* If the replacement _DECL isn't initialized, don't do the 9735 transformation. */ 9736 if (!fn) 9737 return 0; 9738 9739 return build_function_call_expr (fn, newarglist); 9740 } 9741 return 0; 9742 } 9743} 9744 9745/* Simplify a call to the strspn builtin. 9746 9747 Return 0 if no simplification was possible, otherwise return the 9748 simplified form of the call as a tree. 9749 9750 The simplified form may be a constant or other expression which 9751 computes the same value, but in a more efficient manner (including 9752 calls to other builtin functions). 9753 9754 The call may contain arguments which need to be evaluated, but 9755 which are not useful to determine the result of the call. In 9756 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9757 COMPOUND_EXPR will be an argument which must be evaluated. 9758 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9759 COMPOUND_EXPR in the chain will contain the tree for the simplified 9760 form of the builtin function call. */ 9761 9762static tree 9763fold_builtin_strspn (tree arglist) 9764{ 9765 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9766 return 0; 9767 else 9768 { 9769 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9770 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); 9771 9772 /* If both arguments are constants, evaluate at compile-time. */ 9773 if (p1 && p2) 9774 { 9775 const size_t r = strspn (p1, p2); 9776 return size_int (r); 9777 } 9778 9779 /* If either argument is "", return 0. */ 9780 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')) 9781 /* Evaluate and ignore both arguments in case either one has 9782 side-effects. */ 9783 return omit_two_operands (integer_type_node, integer_zero_node, 9784 s1, s2); 9785 return 0; 9786 } 9787} 9788 9789/* Simplify a call to the strcspn builtin. 9790 9791 Return 0 if no simplification was possible, otherwise return the 9792 simplified form of the call as a tree. 9793 9794 The simplified form may be a constant or other expression which 9795 computes the same value, but in a more efficient manner (including 9796 calls to other builtin functions). 9797 9798 The call may contain arguments which need to be evaluated, but 9799 which are not useful to determine the result of the call. In 9800 this case we return a chain of COMPOUND_EXPRs. The LHS of each 9801 COMPOUND_EXPR will be an argument which must be evaluated. 9802 COMPOUND_EXPRs are chained through their RHS. The RHS of the last 9803 COMPOUND_EXPR in the chain will contain the tree for the simplified 9804 form of the builtin function call. */ 9805 9806static tree 9807fold_builtin_strcspn (tree arglist) 9808{ 9809 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9810 return 0; 9811 else 9812 { 9813 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 9814 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); 9815 9816 /* If both arguments are constants, evaluate at compile-time. */ 9817 if (p1 && p2) 9818 { 9819 const size_t r = strcspn (p1, p2); 9820 return size_int (r); 9821 } 9822 9823 /* If the first argument is "", return 0. */ 9824 if (p1 && *p1 == '\0') 9825 { 9826 /* Evaluate and ignore argument s2 in case it has 9827 side-effects. */ 9828 return omit_one_operand (integer_type_node, 9829 integer_zero_node, s2); 9830 } 9831 9832 /* If the second argument is "", return __builtin_strlen(s1). */ 9833 if (p2 && *p2 == '\0') 9834 { 9835 tree newarglist = build_tree_list (NULL_TREE, s1), 9836 fn = implicit_built_in_decls[BUILT_IN_STRLEN]; 9837 9838 /* If the replacement _DECL isn't initialized, don't do the 9839 transformation. */ 9840 if (!fn) 9841 return 0; 9842 9843 return build_function_call_expr (fn, newarglist); 9844 } 9845 return 0; 9846 } 9847} 9848 9849/* Fold a call to the fputs builtin. IGNORE is true if the value returned 9850 by the builtin will be ignored. UNLOCKED is true is true if this 9851 actually a call to fputs_unlocked. If LEN in non-NULL, it represents 9852 the known length of the string. Return NULL_TREE if no simplification 9853 was possible. */ 9854 9855tree 9856fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len) 9857{ 9858 tree fn; 9859 /* If we're using an unlocked function, assume the other unlocked 9860 functions exist explicitly. */ 9861 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED] 9862 : implicit_built_in_decls[BUILT_IN_FPUTC]; 9863 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED] 9864 : implicit_built_in_decls[BUILT_IN_FWRITE]; 9865 9866 /* If the return value is used, don't do the transformation. */ 9867 if (!ignore) 9868 return 0; 9869 9870 /* Verify the arguments in the original call. */ 9871 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 9872 return 0; 9873 9874 if (! len) 9875 len = c_strlen (TREE_VALUE (arglist), 0); 9876 9877 /* Get the length of the string passed to fputs. If the length 9878 can't be determined, punt. */ 9879 if (!len 9880 || TREE_CODE (len) != INTEGER_CST) 9881 return 0; 9882 9883 switch (compare_tree_int (len, 1)) 9884 { 9885 case -1: /* length is 0, delete the call entirely . */ 9886 return omit_one_operand (integer_type_node, integer_zero_node, 9887 TREE_VALUE (TREE_CHAIN (arglist))); 9888 9889 case 0: /* length is 1, call fputc. */ 9890 { 9891 const char *p = c_getstr (TREE_VALUE (arglist)); 9892 9893 if (p != NULL) 9894 { 9895 /* New argument list transforming fputs(string, stream) to 9896 fputc(string[0], stream). */ 9897 arglist = build_tree_list (NULL_TREE, 9898 TREE_VALUE (TREE_CHAIN (arglist))); 9899 arglist = tree_cons (NULL_TREE, 9900 build_int_cst (NULL_TREE, p[0]), 9901 arglist); 9902 fn = fn_fputc; 9903 break; 9904 } 9905 } 9906 /* FALLTHROUGH */ 9907 case 1: /* length is greater than 1, call fwrite. */ 9908 { 9909 tree string_arg; 9910 9911 /* If optimizing for size keep fputs. */ 9912 if (optimize_size) 9913 return 0; 9914 string_arg = TREE_VALUE (arglist); 9915 /* New argument list transforming fputs(string, stream) to 9916 fwrite(string, 1, len, stream). */ 9917 arglist = build_tree_list (NULL_TREE, 9918 TREE_VALUE (TREE_CHAIN (arglist))); 9919 arglist = tree_cons (NULL_TREE, len, arglist); 9920 arglist = tree_cons (NULL_TREE, size_one_node, arglist); 9921 arglist = tree_cons (NULL_TREE, string_arg, arglist); 9922 fn = fn_fwrite; 9923 break; 9924 } 9925 default: 9926 gcc_unreachable (); 9927 } 9928 9929 /* If the replacement _DECL isn't initialized, don't do the 9930 transformation. */ 9931 if (!fn) 9932 return 0; 9933 9934 /* These optimizations are only performed when the result is ignored, 9935 hence there's no need to cast the result to integer_type_node. */ 9936 return build_function_call_expr (fn, arglist); 9937} 9938 9939/* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error 9940 produced. False otherwise. This is done so that we don't output the error 9941 or warning twice or three times. */ 9942bool 9943fold_builtin_next_arg (tree arglist) 9944{ 9945 tree fntype = TREE_TYPE (current_function_decl); 9946 9947 if (TYPE_ARG_TYPES (fntype) == 0 9948 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) 9949 == void_type_node)) 9950 { 9951 error ("%<va_start%> used in function with fixed args"); 9952 return true; 9953 } 9954 else if (!arglist) 9955 { 9956 /* Evidently an out of date version of <stdarg.h>; can't validate 9957 va_start's second argument, but can still work as intended. */ 9958 warning (0, "%<__builtin_next_arg%> called without an argument"); 9959 return true; 9960 } 9961 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0) 9962 when we checked the arguments and if needed issued a warning. */ 9963 else if (!TREE_CHAIN (arglist) 9964 || !integer_zerop (TREE_VALUE (arglist)) 9965 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist))) 9966 || TREE_CHAIN (TREE_CHAIN (arglist))) 9967 { 9968 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl)); 9969 tree arg = TREE_VALUE (arglist); 9970 9971 if (TREE_CHAIN (arglist)) 9972 { 9973 error ("%<va_start%> used with too many arguments"); 9974 return true; 9975 } 9976 9977 /* Strip off all nops for the sake of the comparison. This 9978 is not quite the same as STRIP_NOPS. It does more. 9979 We must also strip off INDIRECT_EXPR for C++ reference 9980 parameters. */ 9981 while (TREE_CODE (arg) == NOP_EXPR 9982 || TREE_CODE (arg) == CONVERT_EXPR 9983 || TREE_CODE (arg) == NON_LVALUE_EXPR 9984 || TREE_CODE (arg) == INDIRECT_REF) 9985 arg = TREE_OPERAND (arg, 0); 9986 if (arg != last_parm) 9987 { 9988 /* FIXME: Sometimes with the tree optimizers we can get the 9989 not the last argument even though the user used the last 9990 argument. We just warn and set the arg to be the last 9991 argument so that we will get wrong-code because of 9992 it. */ 9993 warning (0, "second parameter of %<va_start%> not last named argument"); 9994 } 9995 /* We want to verify the second parameter just once before the tree 9996 optimizers are run and then avoid keeping it in the tree, 9997 as otherwise we could warn even for correct code like: 9998 void foo (int i, ...) 9999 { va_list ap; i++; va_start (ap, i); va_end (ap); } */ 10000 TREE_VALUE (arglist) = integer_zero_node; 10001 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node); 10002 } 10003 return false; 10004} 10005 10006 10007/* Simplify a call to the sprintf builtin. 10008 10009 Return 0 if no simplification was possible, otherwise return the 10010 simplified form of the call as a tree. If IGNORED is true, it means that 10011 the caller does not use the returned value of the function. */ 10012 10013static tree 10014fold_builtin_sprintf (tree arglist, int ignored) 10015{ 10016 tree call, retval, dest, fmt; 10017 const char *fmt_str = NULL; 10018 10019 /* Verify the required arguments in the original call. We deal with two 10020 types of sprintf() calls: 'sprintf (str, fmt)' and 10021 'sprintf (dest, "%s", orig)'. */ 10022 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE) 10023 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE, 10024 VOID_TYPE)) 10025 return NULL_TREE; 10026 10027 /* Get the destination string and the format specifier. */ 10028 dest = TREE_VALUE (arglist); 10029 fmt = TREE_VALUE (TREE_CHAIN (arglist)); 10030 arglist = TREE_CHAIN (TREE_CHAIN (arglist)); 10031 10032 /* Check whether the format is a literal string constant. */ 10033 fmt_str = c_getstr (fmt); 10034 if (fmt_str == NULL) 10035 return NULL_TREE; 10036 10037 call = NULL_TREE; 10038 retval = NULL_TREE; 10039 10040 if (!init_target_chars()) 10041 return 0; 10042 10043 /* If the format doesn't contain % args or %%, use strcpy. */ 10044 if (strchr (fmt_str, target_percent) == NULL) 10045 { 10046 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 10047 10048 if (!fn) 10049 return NULL_TREE; 10050 10051 /* Don't optimize sprintf (buf, "abc", ptr++). */ 10052 if (arglist) 10053 return NULL_TREE; 10054 10055 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when 10056 'format' is known to contain no % formats. */ 10057 arglist = build_tree_list (NULL_TREE, fmt); 10058 arglist = tree_cons (NULL_TREE, dest, arglist); 10059 call = build_function_call_expr (fn, arglist); 10060 if (!ignored) 10061 retval = build_int_cst (NULL_TREE, strlen (fmt_str)); 10062 } 10063 10064 /* If the format is "%s", use strcpy if the result isn't used. */ 10065 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0) 10066 { 10067 tree fn, orig; 10068 fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 10069 10070 if (!fn) 10071 return NULL_TREE; 10072 10073 /* Don't crash on sprintf (str1, "%s"). */ 10074 if (!arglist) 10075 return NULL_TREE; 10076 10077 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */ 10078 orig = TREE_VALUE (arglist); 10079 arglist = build_tree_list (NULL_TREE, orig); 10080 arglist = tree_cons (NULL_TREE, dest, arglist); 10081 if (!ignored) 10082 { 10083 retval = c_strlen (orig, 1); 10084 if (!retval || TREE_CODE (retval) != INTEGER_CST) 10085 return NULL_TREE; 10086 } 10087 call = build_function_call_expr (fn, arglist); 10088 } 10089 10090 if (call && retval) 10091 { 10092 retval = fold_convert 10093 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])), 10094 retval); 10095 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval); 10096 } 10097 else 10098 return call; 10099} 10100 10101/* Expand a call to __builtin_object_size. */ 10102 10103rtx 10104expand_builtin_object_size (tree exp) 10105{ 10106 tree ost; 10107 int object_size_type; 10108 tree fndecl = get_callee_fndecl (exp); 10109 tree arglist = TREE_OPERAND (exp, 1); 10110 location_t locus = EXPR_LOCATION (exp); 10111 10112 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 10113 { 10114 error ("%Hfirst argument of %D must be a pointer, second integer constant", 10115 &locus, fndecl); 10116 expand_builtin_trap (); 10117 return const0_rtx; 10118 } 10119 10120 ost = TREE_VALUE (TREE_CHAIN (arglist)); 10121 STRIP_NOPS (ost); 10122 10123 if (TREE_CODE (ost) != INTEGER_CST 10124 || tree_int_cst_sgn (ost) < 0 10125 || compare_tree_int (ost, 3) > 0) 10126 { 10127 error ("%Hlast argument of %D is not integer constant between 0 and 3", 10128 &locus, fndecl); 10129 expand_builtin_trap (); 10130 return const0_rtx; 10131 } 10132 10133 object_size_type = tree_low_cst (ost, 0); 10134 10135 return object_size_type < 2 ? constm1_rtx : const0_rtx; 10136} 10137 10138/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin. 10139 FCODE is the BUILT_IN_* to use. 10140 Return 0 if we failed; the caller should emit a normal call, 10141 otherwise try to get the result in TARGET, if convenient (and in 10142 mode MODE if that's convenient). */ 10143 10144static rtx 10145expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode, 10146 enum built_in_function fcode) 10147{ 10148 tree arglist = TREE_OPERAND (exp, 1); 10149 tree dest, src, len, size; 10150 10151 if (!validate_arglist (arglist, 10152 POINTER_TYPE, 10153 fcode == BUILT_IN_MEMSET_CHK 10154 ? INTEGER_TYPE : POINTER_TYPE, 10155 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 10156 return 0; 10157 10158 dest = TREE_VALUE (arglist); 10159 src = TREE_VALUE (TREE_CHAIN (arglist)); 10160 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10161 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))); 10162 10163 if (! host_integerp (size, 1)) 10164 return 0; 10165 10166 if (host_integerp (len, 1) || integer_all_onesp (size)) 10167 { 10168 tree fn; 10169 10170 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len)) 10171 { 10172 location_t locus = EXPR_LOCATION (exp); 10173 warning (0, "%Hcall to %D will always overflow destination buffer", 10174 &locus, get_callee_fndecl (exp)); 10175 return 0; 10176 } 10177 10178 arglist = build_tree_list (NULL_TREE, len); 10179 arglist = tree_cons (NULL_TREE, src, arglist); 10180 arglist = tree_cons (NULL_TREE, dest, arglist); 10181 10182 fn = NULL_TREE; 10183 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume 10184 mem{cpy,pcpy,move,set} is available. */ 10185 switch (fcode) 10186 { 10187 case BUILT_IN_MEMCPY_CHK: 10188 fn = built_in_decls[BUILT_IN_MEMCPY]; 10189 break; 10190 case BUILT_IN_MEMPCPY_CHK: 10191 fn = built_in_decls[BUILT_IN_MEMPCPY]; 10192 break; 10193 case BUILT_IN_MEMMOVE_CHK: 10194 fn = built_in_decls[BUILT_IN_MEMMOVE]; 10195 break; 10196 case BUILT_IN_MEMSET_CHK: 10197 fn = built_in_decls[BUILT_IN_MEMSET]; 10198 break; 10199 default: 10200 break; 10201 } 10202 10203 if (! fn) 10204 return 0; 10205 10206 fn = build_function_call_expr (fn, arglist); 10207 if (TREE_CODE (fn) == CALL_EXPR) 10208 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 10209 return expand_expr (fn, target, mode, EXPAND_NORMAL); 10210 } 10211 else if (fcode == BUILT_IN_MEMSET_CHK) 10212 return 0; 10213 else 10214 { 10215 unsigned int dest_align 10216 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 10217 10218 /* If DEST is not a pointer type, call the normal function. */ 10219 if (dest_align == 0) 10220 return 0; 10221 10222 /* If SRC and DEST are the same (and not volatile), do nothing. */ 10223 if (operand_equal_p (src, dest, 0)) 10224 { 10225 tree expr; 10226 10227 if (fcode != BUILT_IN_MEMPCPY_CHK) 10228 { 10229 /* Evaluate and ignore LEN in case it has side-effects. */ 10230 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL); 10231 return expand_expr (dest, target, mode, EXPAND_NORMAL); 10232 } 10233 10234 len = fold_convert (TREE_TYPE (dest), len); 10235 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len); 10236 return expand_expr (expr, target, mode, EXPAND_NORMAL); 10237 } 10238 10239 /* __memmove_chk special case. */ 10240 if (fcode == BUILT_IN_MEMMOVE_CHK) 10241 { 10242 unsigned int src_align 10243 = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 10244 10245 if (src_align == 0) 10246 return 0; 10247 10248 /* If src is categorized for a readonly section we can use 10249 normal __memcpy_chk. */ 10250 if (readonly_data_expr (src)) 10251 { 10252 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK]; 10253 if (!fn) 10254 return 0; 10255 fn = build_function_call_expr (fn, arglist); 10256 if (TREE_CODE (fn) == CALL_EXPR) 10257 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); 10258 return expand_expr (fn, target, mode, EXPAND_NORMAL); 10259 } 10260 } 10261 return 0; 10262 } 10263} 10264 10265/* Emit warning if a buffer overflow is detected at compile time. */ 10266 10267static void 10268maybe_emit_chk_warning (tree exp, enum built_in_function fcode) 10269{ 10270 int arg_mask, is_strlen = 0; 10271 tree arglist = TREE_OPERAND (exp, 1), a; 10272 tree len, size; 10273 location_t locus; 10274 10275 switch (fcode) 10276 { 10277 case BUILT_IN_STRCPY_CHK: 10278 case BUILT_IN_STPCPY_CHK: 10279 /* For __strcat_chk the warning will be emitted only if overflowing 10280 by at least strlen (dest) + 1 bytes. */ 10281 case BUILT_IN_STRCAT_CHK: 10282 arg_mask = 6; 10283 is_strlen = 1; 10284 break; 10285 case BUILT_IN_STRNCPY_CHK: 10286 arg_mask = 12; 10287 break; 10288 case BUILT_IN_SNPRINTF_CHK: 10289 case BUILT_IN_VSNPRINTF_CHK: 10290 arg_mask = 10; 10291 break; 10292 default: 10293 gcc_unreachable (); 10294 } 10295 10296 len = NULL_TREE; 10297 size = NULL_TREE; 10298 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1) 10299 if (arg_mask & 1) 10300 { 10301 if (len) 10302 size = a; 10303 else 10304 len = a; 10305 } 10306 10307 if (!len || !size) 10308 return; 10309 10310 len = TREE_VALUE (len); 10311 size = TREE_VALUE (size); 10312 10313 if (! host_integerp (size, 1) || integer_all_onesp (size)) 10314 return; 10315 10316 if (is_strlen) 10317 { 10318 len = c_strlen (len, 1); 10319 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size)) 10320 return; 10321 } 10322 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len)) 10323 return; 10324 10325 locus = EXPR_LOCATION (exp); 10326 warning (0, "%Hcall to %D will always overflow destination buffer", 10327 &locus, get_callee_fndecl (exp)); 10328} 10329 10330/* Emit warning if a buffer overflow is detected at compile time 10331 in __sprintf_chk/__vsprintf_chk calls. */ 10332 10333static void 10334maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode) 10335{ 10336 tree arglist = TREE_OPERAND (exp, 1); 10337 tree dest, size, len, fmt, flag; 10338 const char *fmt_str; 10339 10340 /* Verify the required arguments in the original call. */ 10341 if (! arglist) 10342 return; 10343 dest = TREE_VALUE (arglist); 10344 arglist = TREE_CHAIN (arglist); 10345 if (! arglist) 10346 return; 10347 flag = TREE_VALUE (arglist); 10348 arglist = TREE_CHAIN (arglist); 10349 if (! arglist) 10350 return; 10351 size = TREE_VALUE (arglist); 10352 arglist = TREE_CHAIN (arglist); 10353 if (! arglist) 10354 return; 10355 fmt = TREE_VALUE (arglist); 10356 arglist = TREE_CHAIN (arglist); 10357 10358 if (! host_integerp (size, 1) || integer_all_onesp (size)) 10359 return; 10360 10361 /* Check whether the format is a literal string constant. */ 10362 fmt_str = c_getstr (fmt); 10363 if (fmt_str == NULL) 10364 return; 10365 10366 if (!init_target_chars()) 10367 return; 10368 10369 /* If the format doesn't contain % args or %%, we know its size. */ 10370 if (strchr (fmt_str, target_percent) == 0) 10371 len = build_int_cstu (size_type_node, strlen (fmt_str)); 10372 /* If the format is "%s" and first ... argument is a string literal, 10373 we know it too. */ 10374 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0) 10375 { 10376 tree arg; 10377 10378 if (! arglist) 10379 return; 10380 arg = TREE_VALUE (arglist); 10381 if (! POINTER_TYPE_P (TREE_TYPE (arg))) 10382 return; 10383 10384 len = c_strlen (arg, 1); 10385 if (!len || ! host_integerp (len, 1)) 10386 return; 10387 } 10388 else 10389 return; 10390 10391 if (! tree_int_cst_lt (len, size)) 10392 { 10393 location_t locus = EXPR_LOCATION (exp); 10394 warning (0, "%Hcall to %D will always overflow destination buffer", 10395 &locus, get_callee_fndecl (exp)); 10396 } 10397} 10398 10399/* Fold a call to __builtin_object_size, if possible. */ 10400 10401tree 10402fold_builtin_object_size (tree arglist) 10403{ 10404 tree ptr, ost, ret = 0; 10405 int object_size_type; 10406 10407 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 10408 return 0; 10409 10410 ptr = TREE_VALUE (arglist); 10411 ost = TREE_VALUE (TREE_CHAIN (arglist)); 10412 STRIP_NOPS (ost); 10413 10414 if (TREE_CODE (ost) != INTEGER_CST 10415 || tree_int_cst_sgn (ost) < 0 10416 || compare_tree_int (ost, 3) > 0) 10417 return 0; 10418 10419 object_size_type = tree_low_cst (ost, 0); 10420 10421 /* __builtin_object_size doesn't evaluate side-effects in its arguments; 10422 if there are any side-effects, it returns (size_t) -1 for types 0 and 1 10423 and (size_t) 0 for types 2 and 3. */ 10424 if (TREE_SIDE_EFFECTS (ptr)) 10425 return fold_convert (size_type_node, 10426 object_size_type < 2 10427 ? integer_minus_one_node : integer_zero_node); 10428 10429 if (TREE_CODE (ptr) == ADDR_EXPR) 10430 ret = build_int_cstu (size_type_node, 10431 compute_builtin_object_size (ptr, object_size_type)); 10432 10433 else if (TREE_CODE (ptr) == SSA_NAME) 10434 { 10435 unsigned HOST_WIDE_INT bytes; 10436 10437 /* If object size is not known yet, delay folding until 10438 later. Maybe subsequent passes will help determining 10439 it. */ 10440 bytes = compute_builtin_object_size (ptr, object_size_type); 10441 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 10442 ? -1 : 0)) 10443 ret = build_int_cstu (size_type_node, bytes); 10444 } 10445 10446 if (ret) 10447 { 10448 ret = force_fit_type (ret, -1, false, false); 10449 if (TREE_CONSTANT_OVERFLOW (ret)) 10450 ret = 0; 10451 } 10452 10453 return ret; 10454} 10455 10456/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin. 10457 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_* 10458 code of the builtin. If MAXLEN is not NULL, it is maximum length 10459 passed as third argument. */ 10460 10461tree 10462fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore, 10463 enum built_in_function fcode) 10464{ 10465 tree dest, src, len, size, fn; 10466 10467 if (!validate_arglist (arglist, 10468 POINTER_TYPE, 10469 fcode == BUILT_IN_MEMSET_CHK 10470 ? INTEGER_TYPE : POINTER_TYPE, 10471 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 10472 return 0; 10473 10474 dest = TREE_VALUE (arglist); 10475 /* Actually val for __memset_chk, but it doesn't matter. */ 10476 src = TREE_VALUE (TREE_CHAIN (arglist)); 10477 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10478 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))); 10479 10480 /* If SRC and DEST are the same (and not volatile), return DEST 10481 (resp. DEST+LEN for __mempcpy_chk). */ 10482 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0)) 10483 { 10484 if (fcode != BUILT_IN_MEMPCPY_CHK) 10485 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len); 10486 else 10487 { 10488 tree temp = fold_convert (TREE_TYPE (dest), len); 10489 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp); 10490 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp); 10491 } 10492 } 10493 10494 if (! host_integerp (size, 1)) 10495 return 0; 10496 10497 if (! integer_all_onesp (size)) 10498 { 10499 if (! host_integerp (len, 1)) 10500 { 10501 /* If LEN is not constant, try MAXLEN too. 10502 For MAXLEN only allow optimizing into non-_ocs function 10503 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 10504 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 10505 { 10506 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore) 10507 { 10508 /* (void) __mempcpy_chk () can be optimized into 10509 (void) __memcpy_chk (). */ 10510 fn = built_in_decls[BUILT_IN_MEMCPY_CHK]; 10511 if (!fn) 10512 return 0; 10513 10514 return build_function_call_expr (fn, arglist); 10515 } 10516 return 0; 10517 } 10518 } 10519 else 10520 maxlen = len; 10521 10522 if (tree_int_cst_lt (size, maxlen)) 10523 return 0; 10524 } 10525 10526 arglist = build_tree_list (NULL_TREE, len); 10527 arglist = tree_cons (NULL_TREE, src, arglist); 10528 arglist = tree_cons (NULL_TREE, dest, arglist); 10529 10530 fn = NULL_TREE; 10531 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume 10532 mem{cpy,pcpy,move,set} is available. */ 10533 switch (fcode) 10534 { 10535 case BUILT_IN_MEMCPY_CHK: 10536 fn = built_in_decls[BUILT_IN_MEMCPY]; 10537 break; 10538 case BUILT_IN_MEMPCPY_CHK: 10539 fn = built_in_decls[BUILT_IN_MEMPCPY]; 10540 break; 10541 case BUILT_IN_MEMMOVE_CHK: 10542 fn = built_in_decls[BUILT_IN_MEMMOVE]; 10543 break; 10544 case BUILT_IN_MEMSET_CHK: 10545 fn = built_in_decls[BUILT_IN_MEMSET]; 10546 break; 10547 default: 10548 break; 10549 } 10550 10551 if (!fn) 10552 return 0; 10553 10554 return build_function_call_expr (fn, arglist); 10555} 10556 10557/* Fold a call to the __st[rp]cpy_chk builtin. 10558 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_* 10559 code of the builtin. If MAXLEN is not NULL, it is maximum length of 10560 strings passed as second argument. */ 10561 10562tree 10563fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore, 10564 enum built_in_function fcode) 10565{ 10566 tree dest, src, size, len, fn; 10567 10568 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, 10569 VOID_TYPE)) 10570 return 0; 10571 10572 dest = TREE_VALUE (arglist); 10573 src = TREE_VALUE (TREE_CHAIN (arglist)); 10574 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10575 10576 /* If SRC and DEST are the same (and not volatile), return DEST. */ 10577 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0)) 10578 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest); 10579 10580 if (! host_integerp (size, 1)) 10581 return 0; 10582 10583 if (! integer_all_onesp (size)) 10584 { 10585 len = c_strlen (src, 1); 10586 if (! len || ! host_integerp (len, 1)) 10587 { 10588 /* If LEN is not constant, try MAXLEN too. 10589 For MAXLEN only allow optimizing into non-_ocs function 10590 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 10591 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 10592 { 10593 if (fcode == BUILT_IN_STPCPY_CHK) 10594 { 10595 if (! ignore) 10596 return 0; 10597 10598 /* If return value of __stpcpy_chk is ignored, 10599 optimize into __strcpy_chk. */ 10600 fn = built_in_decls[BUILT_IN_STRCPY_CHK]; 10601 if (!fn) 10602 return 0; 10603 10604 return build_function_call_expr (fn, arglist); 10605 } 10606 10607 if (! len || TREE_SIDE_EFFECTS (len)) 10608 return 0; 10609 10610 /* If c_strlen returned something, but not a constant, 10611 transform __strcpy_chk into __memcpy_chk. */ 10612 fn = built_in_decls[BUILT_IN_MEMCPY_CHK]; 10613 if (!fn) 10614 return 0; 10615 10616 len = size_binop (PLUS_EXPR, len, ssize_int (1)); 10617 arglist = build_tree_list (NULL_TREE, size); 10618 arglist = tree_cons (NULL_TREE, len, arglist); 10619 arglist = tree_cons (NULL_TREE, src, arglist); 10620 arglist = tree_cons (NULL_TREE, dest, arglist); 10621 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), 10622 build_function_call_expr (fn, arglist)); 10623 } 10624 } 10625 else 10626 maxlen = len; 10627 10628 if (! tree_int_cst_lt (maxlen, size)) 10629 return 0; 10630 } 10631 10632 arglist = build_tree_list (NULL_TREE, src); 10633 arglist = tree_cons (NULL_TREE, dest, arglist); 10634 10635 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */ 10636 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK 10637 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY]; 10638 if (!fn) 10639 return 0; 10640 10641 return build_function_call_expr (fn, arglist); 10642} 10643 10644/* Fold a call to the __strncpy_chk builtin. 10645 If MAXLEN is not NULL, it is maximum length passed as third argument. */ 10646 10647tree 10648fold_builtin_strncpy_chk (tree arglist, tree maxlen) 10649{ 10650 tree dest, src, size, len, fn; 10651 10652 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, 10653 INTEGER_TYPE, VOID_TYPE)) 10654 return 0; 10655 10656 dest = TREE_VALUE (arglist); 10657 src = TREE_VALUE (TREE_CHAIN (arglist)); 10658 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10659 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))); 10660 10661 if (! host_integerp (size, 1)) 10662 return 0; 10663 10664 if (! integer_all_onesp (size)) 10665 { 10666 if (! host_integerp (len, 1)) 10667 { 10668 /* If LEN is not constant, try MAXLEN too. 10669 For MAXLEN only allow optimizing into non-_ocs function 10670 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 10671 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 10672 return 0; 10673 } 10674 else 10675 maxlen = len; 10676 10677 if (tree_int_cst_lt (size, maxlen)) 10678 return 0; 10679 } 10680 10681 arglist = build_tree_list (NULL_TREE, len); 10682 arglist = tree_cons (NULL_TREE, src, arglist); 10683 arglist = tree_cons (NULL_TREE, dest, arglist); 10684 10685 /* If __builtin_strncpy_chk is used, assume strncpy is available. */ 10686 fn = built_in_decls[BUILT_IN_STRNCPY]; 10687 if (!fn) 10688 return 0; 10689 10690 return build_function_call_expr (fn, arglist); 10691} 10692 10693/* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */ 10694 10695static tree 10696fold_builtin_strcat_chk (tree fndecl, tree arglist) 10697{ 10698 tree dest, src, size, fn; 10699 const char *p; 10700 10701 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, 10702 VOID_TYPE)) 10703 return 0; 10704 10705 dest = TREE_VALUE (arglist); 10706 src = TREE_VALUE (TREE_CHAIN (arglist)); 10707 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10708 10709 p = c_getstr (src); 10710 /* If the SRC parameter is "", return DEST. */ 10711 if (p && *p == '\0') 10712 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src); 10713 10714 if (! host_integerp (size, 1) || ! integer_all_onesp (size)) 10715 return 0; 10716 10717 arglist = build_tree_list (NULL_TREE, src); 10718 arglist = tree_cons (NULL_TREE, dest, arglist); 10719 10720 /* If __builtin_strcat_chk is used, assume strcat is available. */ 10721 fn = built_in_decls[BUILT_IN_STRCAT]; 10722 if (!fn) 10723 return 0; 10724 10725 return build_function_call_expr (fn, arglist); 10726} 10727 10728/* Fold a call to the __strncat_chk builtin EXP. */ 10729 10730static tree 10731fold_builtin_strncat_chk (tree fndecl, tree arglist) 10732{ 10733 tree dest, src, size, len, fn; 10734 const char *p; 10735 10736 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, 10737 INTEGER_TYPE, VOID_TYPE)) 10738 return 0; 10739 10740 dest = TREE_VALUE (arglist); 10741 src = TREE_VALUE (TREE_CHAIN (arglist)); 10742 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 10743 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))); 10744 10745 p = c_getstr (src); 10746 /* If the SRC parameter is "" or if LEN is 0, return DEST. */ 10747 if (p && *p == '\0') 10748 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len); 10749 else if (integer_zerop (len)) 10750 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src); 10751 10752 if (! host_integerp (size, 1)) 10753 return 0; 10754 10755 if (! integer_all_onesp (size)) 10756 { 10757 tree src_len = c_strlen (src, 1); 10758 if (src_len 10759 && host_integerp (src_len, 1) 10760 && host_integerp (len, 1) 10761 && ! tree_int_cst_lt (len, src_len)) 10762 { 10763 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */ 10764 fn = built_in_decls[BUILT_IN_STRCAT_CHK]; 10765 if (!fn) 10766 return 0; 10767 10768 arglist = build_tree_list (NULL_TREE, size); 10769 arglist = tree_cons (NULL_TREE, src, arglist); 10770 arglist = tree_cons (NULL_TREE, dest, arglist); 10771 return build_function_call_expr (fn, arglist); 10772 } 10773 return 0; 10774 } 10775 10776 arglist = build_tree_list (NULL_TREE, len); 10777 arglist = tree_cons (NULL_TREE, src, arglist); 10778 arglist = tree_cons (NULL_TREE, dest, arglist); 10779 10780 /* If __builtin_strncat_chk is used, assume strncat is available. */ 10781 fn = built_in_decls[BUILT_IN_STRNCAT]; 10782 if (!fn) 10783 return 0; 10784 10785 return build_function_call_expr (fn, arglist); 10786} 10787 10788/* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if 10789 a normal call should be emitted rather than expanding the function 10790 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */ 10791 10792static tree 10793fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode) 10794{ 10795 tree dest, size, len, fn, fmt, flag; 10796 const char *fmt_str; 10797 10798 /* Verify the required arguments in the original call. */ 10799 if (! arglist) 10800 return 0; 10801 dest = TREE_VALUE (arglist); 10802 if (! POINTER_TYPE_P (TREE_TYPE (dest))) 10803 return 0; 10804 arglist = TREE_CHAIN (arglist); 10805 if (! arglist) 10806 return 0; 10807 flag = TREE_VALUE (arglist); 10808 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE) 10809 return 0; 10810 arglist = TREE_CHAIN (arglist); 10811 if (! arglist) 10812 return 0; 10813 size = TREE_VALUE (arglist); 10814 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE) 10815 return 0; 10816 arglist = TREE_CHAIN (arglist); 10817 if (! arglist) 10818 return 0; 10819 fmt = TREE_VALUE (arglist); 10820 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 10821 return 0; 10822 arglist = TREE_CHAIN (arglist); 10823 10824 if (! host_integerp (size, 1)) 10825 return 0; 10826 10827 len = NULL_TREE; 10828 10829 if (!init_target_chars()) 10830 return 0; 10831 10832 /* Check whether the format is a literal string constant. */ 10833 fmt_str = c_getstr (fmt); 10834 if (fmt_str != NULL) 10835 { 10836 /* If the format doesn't contain % args or %%, we know the size. */ 10837 if (strchr (fmt_str, target_percent) == 0) 10838 { 10839 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE) 10840 len = build_int_cstu (size_type_node, strlen (fmt_str)); 10841 } 10842 /* If the format is "%s" and first ... argument is a string literal, 10843 we know the size too. */ 10844 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0) 10845 { 10846 tree arg; 10847 10848 if (arglist && !TREE_CHAIN (arglist)) 10849 { 10850 arg = TREE_VALUE (arglist); 10851 if (POINTER_TYPE_P (TREE_TYPE (arg))) 10852 { 10853 len = c_strlen (arg, 1); 10854 if (! len || ! host_integerp (len, 1)) 10855 len = NULL_TREE; 10856 } 10857 } 10858 } 10859 } 10860 10861 if (! integer_all_onesp (size)) 10862 { 10863 if (! len || ! tree_int_cst_lt (len, size)) 10864 return 0; 10865 } 10866 10867 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0 10868 or if format doesn't contain % chars or is "%s". */ 10869 if (! integer_zerop (flag)) 10870 { 10871 if (fmt_str == NULL) 10872 return 0; 10873 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s)) 10874 return 0; 10875 } 10876 10877 arglist = tree_cons (NULL_TREE, fmt, arglist); 10878 arglist = tree_cons (NULL_TREE, dest, arglist); 10879 10880 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */ 10881 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK 10882 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF]; 10883 if (!fn) 10884 return 0; 10885 10886 return build_function_call_expr (fn, arglist); 10887} 10888 10889/* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if 10890 a normal call should be emitted rather than expanding the function 10891 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or 10892 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length 10893 passed as second argument. */ 10894 10895tree 10896fold_builtin_snprintf_chk (tree arglist, tree maxlen, 10897 enum built_in_function fcode) 10898{ 10899 tree dest, size, len, fn, fmt, flag; 10900 const char *fmt_str; 10901 10902 /* Verify the required arguments in the original call. */ 10903 if (! arglist) 10904 return 0; 10905 dest = TREE_VALUE (arglist); 10906 if (! POINTER_TYPE_P (TREE_TYPE (dest))) 10907 return 0; 10908 arglist = TREE_CHAIN (arglist); 10909 if (! arglist) 10910 return 0; 10911 len = TREE_VALUE (arglist); 10912 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE) 10913 return 0; 10914 arglist = TREE_CHAIN (arglist); 10915 if (! arglist) 10916 return 0; 10917 flag = TREE_VALUE (arglist); 10918 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE) 10919 return 0; 10920 arglist = TREE_CHAIN (arglist); 10921 if (! arglist) 10922 return 0; 10923 size = TREE_VALUE (arglist); 10924 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE) 10925 return 0; 10926 arglist = TREE_CHAIN (arglist); 10927 if (! arglist) 10928 return 0; 10929 fmt = TREE_VALUE (arglist); 10930 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 10931 return 0; 10932 arglist = TREE_CHAIN (arglist); 10933 10934 if (! host_integerp (size, 1)) 10935 return 0; 10936 10937 if (! integer_all_onesp (size)) 10938 { 10939 if (! host_integerp (len, 1)) 10940 { 10941 /* If LEN is not constant, try MAXLEN too. 10942 For MAXLEN only allow optimizing into non-_ocs function 10943 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ 10944 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) 10945 return 0; 10946 } 10947 else 10948 maxlen = len; 10949 10950 if (tree_int_cst_lt (size, maxlen)) 10951 return 0; 10952 } 10953 10954 if (!init_target_chars()) 10955 return 0; 10956 10957 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0 10958 or if format doesn't contain % chars or is "%s". */ 10959 if (! integer_zerop (flag)) 10960 { 10961 fmt_str = c_getstr (fmt); 10962 if (fmt_str == NULL) 10963 return 0; 10964 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s)) 10965 return 0; 10966 } 10967 10968 arglist = tree_cons (NULL_TREE, fmt, arglist); 10969 arglist = tree_cons (NULL_TREE, len, arglist); 10970 arglist = tree_cons (NULL_TREE, dest, arglist); 10971 10972 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is 10973 available. */ 10974 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK 10975 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF]; 10976 if (!fn) 10977 return 0; 10978 10979 return build_function_call_expr (fn, arglist); 10980} 10981 10982/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins. 10983 10984 Return 0 if no simplification was possible, otherwise return the 10985 simplified form of the call as a tree. FCODE is the BUILT_IN_* 10986 code of the function to be simplified. */ 10987 10988static tree 10989fold_builtin_printf (tree fndecl, tree arglist, bool ignore, 10990 enum built_in_function fcode) 10991{ 10992 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call; 10993 const char *fmt_str = NULL; 10994 10995 /* If the return value is used, don't do the transformation. */ 10996 if (! ignore) 10997 return 0; 10998 10999 /* Verify the required arguments in the original call. */ 11000 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK) 11001 { 11002 tree flag; 11003 11004 if (! arglist) 11005 return 0; 11006 flag = TREE_VALUE (arglist); 11007 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE 11008 || TREE_SIDE_EFFECTS (flag)) 11009 return 0; 11010 arglist = TREE_CHAIN (arglist); 11011 } 11012 11013 if (! arglist) 11014 return 0; 11015 fmt = TREE_VALUE (arglist); 11016 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 11017 return 0; 11018 arglist = TREE_CHAIN (arglist); 11019 11020 /* Check whether the format is a literal string constant. */ 11021 fmt_str = c_getstr (fmt); 11022 if (fmt_str == NULL) 11023 return NULL_TREE; 11024 11025 if (fcode == BUILT_IN_PRINTF_UNLOCKED) 11026 { 11027 /* If we're using an unlocked function, assume the other 11028 unlocked functions exist explicitly. */ 11029 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]; 11030 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED]; 11031 } 11032 else 11033 { 11034 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR]; 11035 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS]; 11036 } 11037 11038 if (!init_target_chars()) 11039 return 0; 11040 11041 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL) 11042 { 11043 const char *str; 11044 11045 if (strcmp (fmt_str, target_percent_s) == 0) 11046 { 11047 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK) 11048 return 0; 11049 11050 if (! arglist 11051 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))) 11052 || TREE_CHAIN (arglist)) 11053 return 0; 11054 11055 str = c_getstr (TREE_VALUE (arglist)); 11056 if (str == NULL) 11057 return 0; 11058 } 11059 else 11060 { 11061 /* The format specifier doesn't contain any '%' characters. */ 11062 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK 11063 && arglist) 11064 return 0; 11065 str = fmt_str; 11066 } 11067 11068 /* If the string was "", printf does nothing. */ 11069 if (str[0] == '\0') 11070 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0); 11071 11072 /* If the string has length of 1, call putchar. */ 11073 if (str[1] == '\0') 11074 { 11075 /* Given printf("c"), (where c is any one character,) 11076 convert "c"[0] to an int and pass that to the replacement 11077 function. */ 11078 arg = build_int_cst (NULL_TREE, str[0]); 11079 arglist = build_tree_list (NULL_TREE, arg); 11080 fn = fn_putchar; 11081 } 11082 else 11083 { 11084 /* If the string was "string\n", call puts("string"). */ 11085 size_t len = strlen (str); 11086 if ((unsigned char)str[len - 1] == target_newline) 11087 { 11088 /* Create a NUL-terminated string that's one char shorter 11089 than the original, stripping off the trailing '\n'. */ 11090 char *newstr = alloca (len); 11091 memcpy (newstr, str, len - 1); 11092 newstr[len - 1] = 0; 11093 11094 arg = build_string_literal (len, newstr); 11095 arglist = build_tree_list (NULL_TREE, arg); 11096 fn = fn_puts; 11097 } 11098 else 11099 /* We'd like to arrange to call fputs(string,stdout) here, 11100 but we need stdout and don't have a way to get it yet. */ 11101 return 0; 11102 } 11103 } 11104 11105 /* The other optimizations can be done only on the non-va_list variants. */ 11106 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK) 11107 return 0; 11108 11109 /* If the format specifier was "%s\n", call __builtin_puts(arg). */ 11110 else if (strcmp (fmt_str, target_percent_s_newline) == 0) 11111 { 11112 if (! arglist 11113 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))) 11114 || TREE_CHAIN (arglist)) 11115 return 0; 11116 fn = fn_puts; 11117 } 11118 11119 /* If the format specifier was "%c", call __builtin_putchar(arg). */ 11120 else if (strcmp (fmt_str, target_percent_c) == 0) 11121 { 11122 if (! arglist 11123 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE 11124 || TREE_CHAIN (arglist)) 11125 return 0; 11126 fn = fn_putchar; 11127 } 11128 11129 if (!fn) 11130 return 0; 11131 11132 call = build_function_call_expr (fn, arglist); 11133 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call); 11134} 11135 11136/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins. 11137 11138 Return 0 if no simplification was possible, otherwise return the 11139 simplified form of the call as a tree. FCODE is the BUILT_IN_* 11140 code of the function to be simplified. */ 11141 11142static tree 11143fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore, 11144 enum built_in_function fcode) 11145{ 11146 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call; 11147 const char *fmt_str = NULL; 11148 11149 /* If the return value is used, don't do the transformation. */ 11150 if (! ignore) 11151 return 0; 11152 11153 /* Verify the required arguments in the original call. */ 11154 if (! arglist) 11155 return 0; 11156 fp = TREE_VALUE (arglist); 11157 if (! POINTER_TYPE_P (TREE_TYPE (fp))) 11158 return 0; 11159 arglist = TREE_CHAIN (arglist); 11160 11161 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK) 11162 { 11163 tree flag; 11164 11165 if (! arglist) 11166 return 0; 11167 flag = TREE_VALUE (arglist); 11168 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE 11169 || TREE_SIDE_EFFECTS (flag)) 11170 return 0; 11171 arglist = TREE_CHAIN (arglist); 11172 } 11173 11174 if (! arglist) 11175 return 0; 11176 fmt = TREE_VALUE (arglist); 11177 if (! POINTER_TYPE_P (TREE_TYPE (fmt))) 11178 return 0; 11179 arglist = TREE_CHAIN (arglist); 11180 11181 /* Check whether the format is a literal string constant. */ 11182 fmt_str = c_getstr (fmt); 11183 if (fmt_str == NULL) 11184 return NULL_TREE; 11185 11186 if (fcode == BUILT_IN_FPRINTF_UNLOCKED) 11187 { 11188 /* If we're using an unlocked function, assume the other 11189 unlocked functions exist explicitly. */ 11190 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED]; 11191 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED]; 11192 } 11193 else 11194 { 11195 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC]; 11196 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS]; 11197 } 11198 11199 if (!init_target_chars()) 11200 return 0; 11201 11202 /* If the format doesn't contain % args or %%, use strcpy. */ 11203 if (strchr (fmt_str, target_percent) == NULL) 11204 { 11205 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK 11206 && arglist) 11207 return 0; 11208 11209 /* If the format specifier was "", fprintf does nothing. */ 11210 if (fmt_str[0] == '\0') 11211 { 11212 /* If FP has side-effects, just wait until gimplification is 11213 done. */ 11214 if (TREE_SIDE_EFFECTS (fp)) 11215 return 0; 11216 11217 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0); 11218 } 11219 11220 /* When "string" doesn't contain %, replace all cases of 11221 fprintf (fp, string) with fputs (string, fp). The fputs 11222 builtin will take care of special cases like length == 1. */ 11223 arglist = build_tree_list (NULL_TREE, fp); 11224 arglist = tree_cons (NULL_TREE, fmt, arglist); 11225 fn = fn_fputs; 11226 } 11227 11228 /* The other optimizations can be done only on the non-va_list variants. */ 11229 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK) 11230 return 0; 11231 11232 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */ 11233 else if (strcmp (fmt_str, target_percent_s) == 0) 11234 { 11235 if (! arglist 11236 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))) 11237 || TREE_CHAIN (arglist)) 11238 return 0; 11239 arg = TREE_VALUE (arglist); 11240 arglist = build_tree_list (NULL_TREE, fp); 11241 arglist = tree_cons (NULL_TREE, arg, arglist); 11242 fn = fn_fputs; 11243 } 11244 11245 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */ 11246 else if (strcmp (fmt_str, target_percent_c) == 0) 11247 { 11248 if (! arglist 11249 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE 11250 || TREE_CHAIN (arglist)) 11251 return 0; 11252 arg = TREE_VALUE (arglist); 11253 arglist = build_tree_list (NULL_TREE, fp); 11254 arglist = tree_cons (NULL_TREE, arg, arglist); 11255 fn = fn_fputc; 11256 } 11257 11258 if (!fn) 11259 return 0; 11260 11261 call = build_function_call_expr (fn, arglist); 11262 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call); 11263} 11264 11265/* Initialize format string characters in the target charset. */ 11266 11267static bool 11268init_target_chars (void) 11269{ 11270 static bool init; 11271 if (!init) 11272 { 11273 target_newline = lang_hooks.to_target_charset ('\n'); 11274 target_percent = lang_hooks.to_target_charset ('%'); 11275 target_c = lang_hooks.to_target_charset ('c'); 11276 target_s = lang_hooks.to_target_charset ('s'); 11277 if (target_newline == 0 || target_percent == 0 || target_c == 0 11278 || target_s == 0) 11279 return false; 11280 11281 target_percent_c[0] = target_percent; 11282 target_percent_c[1] = target_c; 11283 target_percent_c[2] = '\0'; 11284 11285 target_percent_s[0] = target_percent; 11286 target_percent_s[1] = target_s; 11287 target_percent_s[2] = '\0'; 11288 11289 target_percent_s_newline[0] = target_percent; 11290 target_percent_s_newline[1] = target_s; 11291 target_percent_s_newline[2] = target_newline; 11292 target_percent_s_newline[3] = '\0'; 11293 11294 init = true; 11295 } 11296 return true; 11297} 11298