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