builtins.c revision 132727
1/* Expand builtin functions. 2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3 2000, 2001, 2002, 2003, 2004 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, 59 Temple Place - Suite 330, Boston, MA 2002111-1307, 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 "flags.h" 31#include "regs.h" 32#include "hard-reg-set.h" 33#include "except.h" 34#include "function.h" 35#include "insn-config.h" 36#include "expr.h" 37#include "optabs.h" 38#include "libfuncs.h" 39#include "recog.h" 40#include "output.h" 41#include "typeclass.h" 42#include "toplev.h" 43#include "predict.h" 44#include "tm_p.h" 45#include "target.h" 46#include "langhooks.h" 47 48#define CALLED_AS_BUILT_IN(NODE) \ 49 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10)) 50 51/* Register mappings for target machines without register windows. */ 52#ifndef INCOMING_REGNO 53#define INCOMING_REGNO(OUT) (OUT) 54#endif 55#ifndef OUTGOING_REGNO 56#define OUTGOING_REGNO(IN) (IN) 57#endif 58 59#ifndef PAD_VARARGS_DOWN 60#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN 61#endif 62 63/* Define the names of the builtin function types and codes. */ 64const char *const built_in_class_names[4] 65 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"}; 66 67#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X, 68const char *const built_in_names[(int) END_BUILTINS] = 69{ 70#include "builtins.def" 71}; 72#undef DEF_BUILTIN 73 74/* Setup an array of _DECL trees, make sure each element is 75 initialized to NULL_TREE. */ 76tree built_in_decls[(int) END_BUILTINS]; 77/* Declarations used when constructing the builtin implicitly in the compiler. 78 It may be NULL_TREE when this is invalid (for instance runtime is not 79 required to implement the function call in all cases. */ 80tree implicit_built_in_decls[(int) END_BUILTINS]; 81 82static int get_pointer_alignment (tree, unsigned int); 83static tree c_strlen (tree, int); 84static const char *c_getstr (tree); 85static rtx c_readstr (const char *, enum machine_mode); 86static int target_char_cast (tree, char *); 87static rtx get_memory_rtx (tree); 88static tree build_string_literal (int, const char *); 89static int apply_args_size (void); 90static int apply_result_size (void); 91#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return) 92static rtx result_vector (int, rtx); 93#endif 94static rtx expand_builtin_setjmp (tree, rtx); 95static void expand_builtin_prefetch (tree); 96static rtx expand_builtin_apply_args (void); 97static rtx expand_builtin_apply_args_1 (void); 98static rtx expand_builtin_apply (rtx, rtx, rtx); 99static void expand_builtin_return (rtx); 100static enum type_class type_to_class (tree); 101static rtx expand_builtin_classify_type (tree); 102static void expand_errno_check (tree, rtx); 103static rtx expand_builtin_mathfn (tree, rtx, rtx); 104static rtx expand_builtin_mathfn_2 (tree, rtx, rtx); 105static rtx expand_builtin_constant_p (tree, enum machine_mode); 106static rtx expand_builtin_args_info (tree); 107static rtx expand_builtin_next_arg (tree); 108static rtx expand_builtin_va_start (tree); 109static rtx expand_builtin_va_end (tree); 110static rtx expand_builtin_va_copy (tree); 111static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode); 112static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode); 113static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode); 114static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode); 115static rtx expand_builtin_strcat (tree, rtx, enum machine_mode); 116static rtx expand_builtin_strncat (tree, rtx, enum machine_mode); 117static rtx expand_builtin_strspn (tree, rtx, enum machine_mode); 118static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode); 119static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode); 120static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int); 121static rtx expand_builtin_memmove (tree, rtx, enum machine_mode); 122static rtx expand_builtin_bcopy (tree); 123static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode); 124static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode); 125static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode); 126static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode); 127static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode); 128static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode); 129static rtx expand_builtin_memset (tree, rtx, enum machine_mode); 130static rtx expand_builtin_bzero (tree); 131static rtx expand_builtin_strlen (tree, rtx, enum machine_mode); 132static rtx expand_builtin_strstr (tree, rtx, enum machine_mode); 133static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode); 134static rtx expand_builtin_strchr (tree, rtx, enum machine_mode); 135static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode); 136static rtx expand_builtin_alloca (tree, rtx); 137static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab); 138static rtx expand_builtin_frame_address (tree, tree); 139static rtx expand_builtin_fputs (tree, rtx, bool); 140static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool); 141static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool); 142static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode); 143static tree stabilize_va_list (tree, int); 144static rtx expand_builtin_expect (tree, rtx); 145static tree fold_builtin_constant_p (tree); 146static tree fold_builtin_classify_type (tree); 147static tree fold_builtin_inf (tree, int); 148static tree fold_builtin_nan (tree, tree, int); 149static int validate_arglist (tree, ...); 150static bool integer_valued_real_p (tree); 151static tree fold_trunc_transparent_mathfn (tree); 152static bool readonly_data_expr (tree); 153static rtx expand_builtin_fabs (tree, rtx, rtx); 154static rtx expand_builtin_cabs (tree, rtx); 155static tree fold_builtin_cabs (tree, tree, tree); 156static tree fold_builtin_trunc (tree); 157static tree fold_builtin_floor (tree); 158static tree fold_builtin_ceil (tree); 159static tree fold_builtin_bitop (tree); 160static tree fold_builtin_memcpy (tree); 161static tree fold_builtin_mempcpy (tree); 162static tree fold_builtin_memmove (tree); 163static tree fold_builtin_strcpy (tree); 164static tree fold_builtin_strncpy (tree); 165static tree fold_builtin_memcmp (tree); 166static tree fold_builtin_strcmp (tree); 167static tree fold_builtin_strncmp (tree); 168 169/* Return the alignment in bits of EXP, a pointer valued expression. 170 But don't return more than MAX_ALIGN no matter what. 171 The alignment returned is, by default, the alignment of the thing that 172 EXP points to. If it is not a POINTER_TYPE, 0 is returned. 173 174 Otherwise, look at the expression to see if we can do better, i.e., if the 175 expression is actually pointing at an object whose alignment is tighter. */ 176 177static int 178get_pointer_alignment (tree exp, unsigned int max_align) 179{ 180 unsigned int align, inner; 181 182 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE) 183 return 0; 184 185 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))); 186 align = MIN (align, max_align); 187 188 while (1) 189 { 190 switch (TREE_CODE (exp)) 191 { 192 case NOP_EXPR: 193 case CONVERT_EXPR: 194 case NON_LVALUE_EXPR: 195 exp = TREE_OPERAND (exp, 0); 196 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE) 197 return align; 198 199 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))); 200 align = MIN (inner, max_align); 201 break; 202 203 case PLUS_EXPR: 204 /* If sum of pointer + int, restrict our maximum alignment to that 205 imposed by the integer. If not, we can't do any better than 206 ALIGN. */ 207 if (! host_integerp (TREE_OPERAND (exp, 1), 1)) 208 return align; 209 210 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1)) 211 & (max_align / BITS_PER_UNIT - 1)) 212 != 0) 213 max_align >>= 1; 214 215 exp = TREE_OPERAND (exp, 0); 216 break; 217 218 case ADDR_EXPR: 219 /* See what we are pointing at and look at its alignment. */ 220 exp = TREE_OPERAND (exp, 0); 221 if (TREE_CODE (exp) == FUNCTION_DECL) 222 align = FUNCTION_BOUNDARY; 223 else if (DECL_P (exp)) 224 align = DECL_ALIGN (exp); 225#ifdef CONSTANT_ALIGNMENT 226 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c') 227 align = CONSTANT_ALIGNMENT (exp, align); 228#endif 229 return MIN (align, max_align); 230 231 default: 232 return align; 233 } 234 } 235} 236 237/* Compute the length of a C string. TREE_STRING_LENGTH is not the right 238 way, because it could contain a zero byte in the middle. 239 TREE_STRING_LENGTH is the size of the character array, not the string. 240 241 ONLY_VALUE should be nonzero if the result is not going to be emitted 242 into the instruction stream and zero if it is going to be expanded. 243 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3 244 is returned, otherwise NULL, since 245 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not 246 evaluate the side-effects. 247 248 The value returned is of type `ssizetype'. 249 250 Unfortunately, string_constant can't access the values of const char 251 arrays with initializers, so neither can we do so here. */ 252 253static tree 254c_strlen (tree src, int only_value) 255{ 256 tree offset_node; 257 HOST_WIDE_INT offset; 258 int max; 259 const char *ptr; 260 261 STRIP_NOPS (src); 262 if (TREE_CODE (src) == COND_EXPR 263 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) 264 { 265 tree len1, len2; 266 267 len1 = c_strlen (TREE_OPERAND (src, 1), only_value); 268 len2 = c_strlen (TREE_OPERAND (src, 2), only_value); 269 if (tree_int_cst_equal (len1, len2)) 270 return len1; 271 } 272 273 if (TREE_CODE (src) == COMPOUND_EXPR 274 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) 275 return c_strlen (TREE_OPERAND (src, 1), only_value); 276 277 src = string_constant (src, &offset_node); 278 if (src == 0) 279 return 0; 280 281 max = TREE_STRING_LENGTH (src) - 1; 282 ptr = TREE_STRING_POINTER (src); 283 284 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST) 285 { 286 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't 287 compute the offset to the following null if we don't know where to 288 start searching for it. */ 289 int i; 290 291 for (i = 0; i < max; i++) 292 if (ptr[i] == 0) 293 return 0; 294 295 /* We don't know the starting offset, but we do know that the string 296 has no internal zero bytes. We can assume that the offset falls 297 within the bounds of the string; otherwise, the programmer deserves 298 what he gets. Subtract the offset from the length of the string, 299 and return that. This would perhaps not be valid if we were dealing 300 with named arrays in addition to literal string constants. */ 301 302 return size_diffop (size_int (max), offset_node); 303 } 304 305 /* We have a known offset into the string. Start searching there for 306 a null character if we can represent it as a single HOST_WIDE_INT. */ 307 if (offset_node == 0) 308 offset = 0; 309 else if (! host_integerp (offset_node, 0)) 310 offset = -1; 311 else 312 offset = tree_low_cst (offset_node, 0); 313 314 /* If the offset is known to be out of bounds, warn, and call strlen at 315 runtime. */ 316 if (offset < 0 || offset > max) 317 { 318 warning ("offset outside bounds of constant string"); 319 return 0; 320 } 321 322 /* Use strlen to search for the first zero byte. Since any strings 323 constructed with build_string will have nulls appended, we win even 324 if we get handed something like (char[4])"abcd". 325 326 Since OFFSET is our starting index into the string, no further 327 calculation is needed. */ 328 return ssize_int (strlen (ptr + offset)); 329} 330 331/* Return a char pointer for a C string if it is a string constant 332 or sum of string constant and integer constant. */ 333 334static const char * 335c_getstr (tree src) 336{ 337 tree offset_node; 338 339 src = string_constant (src, &offset_node); 340 if (src == 0) 341 return 0; 342 343 if (offset_node == 0) 344 return TREE_STRING_POINTER (src); 345 else if (!host_integerp (offset_node, 1) 346 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0) 347 return 0; 348 349 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1); 350} 351 352/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading 353 GET_MODE_BITSIZE (MODE) bits from string constant STR. */ 354 355static rtx 356c_readstr (const char *str, enum machine_mode mode) 357{ 358 HOST_WIDE_INT c[2]; 359 HOST_WIDE_INT ch; 360 unsigned int i, j; 361 362 if (GET_MODE_CLASS (mode) != MODE_INT) 363 abort (); 364 c[0] = 0; 365 c[1] = 0; 366 ch = 1; 367 for (i = 0; i < GET_MODE_SIZE (mode); i++) 368 { 369 j = i; 370 if (WORDS_BIG_ENDIAN) 371 j = GET_MODE_SIZE (mode) - i - 1; 372 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN 373 && GET_MODE_SIZE (mode) > UNITS_PER_WORD) 374 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1; 375 j *= BITS_PER_UNIT; 376 if (j > 2 * HOST_BITS_PER_WIDE_INT) 377 abort (); 378 if (ch) 379 ch = (unsigned char) str[i]; 380 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT); 381 } 382 return immed_double_const (c[0], c[1], mode); 383} 384 385/* Cast a target constant CST to target CHAR and if that value fits into 386 host char type, return zero and put that value into variable pointed by 387 P. */ 388 389static int 390target_char_cast (tree cst, char *p) 391{ 392 unsigned HOST_WIDE_INT val, hostval; 393 394 if (!host_integerp (cst, 1) 395 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT) 396 return 1; 397 398 val = tree_low_cst (cst, 1); 399 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT) 400 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1; 401 402 hostval = val; 403 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT) 404 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1; 405 406 if (val != hostval) 407 return 1; 408 409 *p = hostval; 410 return 0; 411} 412 413/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT 414 times to get the address of either a higher stack frame, or a return 415 address located within it (depending on FNDECL_CODE). */ 416 417rtx 418expand_builtin_return_addr (enum built_in_function fndecl_code, int count, 419 rtx tem) 420{ 421 int i; 422 423 /* Some machines need special handling before we can access 424 arbitrary frames. For example, on the sparc, we must first flush 425 all register windows to the stack. */ 426#ifdef SETUP_FRAME_ADDRESSES 427 if (count > 0) 428 SETUP_FRAME_ADDRESSES (); 429#endif 430 431 /* On the sparc, the return address is not in the frame, it is in a 432 register. There is no way to access it off of the current frame 433 pointer, but it can be accessed off the previous frame pointer by 434 reading the value from the register window save area. */ 435#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME 436 if (fndecl_code == BUILT_IN_RETURN_ADDRESS) 437 count--; 438#endif 439 440 /* Scan back COUNT frames to the specified frame. */ 441 for (i = 0; i < count; i++) 442 { 443 /* Assume the dynamic chain pointer is in the word that the 444 frame address points to, unless otherwise specified. */ 445#ifdef DYNAMIC_CHAIN_ADDRESS 446 tem = DYNAMIC_CHAIN_ADDRESS (tem); 447#endif 448 tem = memory_address (Pmode, tem); 449 tem = gen_rtx_MEM (Pmode, tem); 450 set_mem_alias_set (tem, get_frame_alias_set ()); 451 tem = copy_to_reg (tem); 452 } 453 454 /* For __builtin_frame_address, return what we've got. */ 455 if (fndecl_code == BUILT_IN_FRAME_ADDRESS) 456 return tem; 457 458 /* For __builtin_return_address, Get the return address from that 459 frame. */ 460#ifdef RETURN_ADDR_RTX 461 tem = RETURN_ADDR_RTX (count, tem); 462#else 463 tem = memory_address (Pmode, 464 plus_constant (tem, GET_MODE_SIZE (Pmode))); 465 tem = gen_rtx_MEM (Pmode, tem); 466 set_mem_alias_set (tem, get_frame_alias_set ()); 467#endif 468 return tem; 469} 470 471/* Alias set used for setjmp buffer. */ 472static HOST_WIDE_INT setjmp_alias_set = -1; 473 474/* Construct the leading half of a __builtin_setjmp call. Control will 475 return to RECEIVER_LABEL. This is used directly by sjlj exception 476 handling code. */ 477 478void 479expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label) 480{ 481 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 482 rtx stack_save; 483 rtx mem; 484 485 if (setjmp_alias_set == -1) 486 setjmp_alias_set = new_alias_set (); 487 488 buf_addr = convert_memory_address (Pmode, buf_addr); 489 490 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX)); 491 492 emit_queue (); 493 494 /* We store the frame pointer and the address of receiver_label in 495 the buffer and use the rest of it for the stack save area, which 496 is machine-dependent. */ 497 498#ifndef BUILTIN_SETJMP_FRAME_VALUE 499#define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx 500#endif 501 502 mem = gen_rtx_MEM (Pmode, buf_addr); 503 set_mem_alias_set (mem, setjmp_alias_set); 504 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE); 505 506 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))), 507 set_mem_alias_set (mem, setjmp_alias_set); 508 509 emit_move_insn (validize_mem (mem), 510 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label))); 511 512 stack_save = gen_rtx_MEM (sa_mode, 513 plus_constant (buf_addr, 514 2 * GET_MODE_SIZE (Pmode))); 515 set_mem_alias_set (stack_save, setjmp_alias_set); 516 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX); 517 518 /* If there is further processing to do, do it. */ 519#ifdef HAVE_builtin_setjmp_setup 520 if (HAVE_builtin_setjmp_setup) 521 emit_insn (gen_builtin_setjmp_setup (buf_addr)); 522#endif 523 524 /* Tell optimize_save_area_alloca that extra work is going to 525 need to go on during alloca. */ 526 current_function_calls_setjmp = 1; 527 528 /* Set this so all the registers get saved in our frame; we need to be 529 able to copy the saved values for any registers from frames we unwind. */ 530 current_function_has_nonlocal_label = 1; 531} 532 533/* Construct the trailing part of a __builtin_setjmp call. 534 This is used directly by sjlj exception handling code. */ 535 536void 537expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED) 538{ 539 /* Clobber the FP when we get here, so we have to make sure it's 540 marked as used by this function. */ 541 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); 542 543 /* Mark the static chain as clobbered here so life information 544 doesn't get messed up for it. */ 545 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx)); 546 547 /* Now put in the code to restore the frame pointer, and argument 548 pointer, if needed. The code below is from expand_end_bindings 549 in stmt.c; see detailed documentation there. */ 550#ifdef HAVE_nonlocal_goto 551 if (! HAVE_nonlocal_goto) 552#endif 553 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); 554 555#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM 556 if (fixed_regs[ARG_POINTER_REGNUM]) 557 { 558#ifdef ELIMINABLE_REGS 559 size_t i; 560 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS; 561 562 for (i = 0; i < ARRAY_SIZE (elim_regs); i++) 563 if (elim_regs[i].from == ARG_POINTER_REGNUM 564 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM) 565 break; 566 567 if (i == ARRAY_SIZE (elim_regs)) 568#endif 569 { 570 /* Now restore our arg pointer from the address at which it 571 was saved in our stack frame. */ 572 emit_move_insn (virtual_incoming_args_rtx, 573 copy_to_reg (get_arg_pointer_save_area (cfun))); 574 } 575 } 576#endif 577 578#ifdef HAVE_builtin_setjmp_receiver 579 if (HAVE_builtin_setjmp_receiver) 580 emit_insn (gen_builtin_setjmp_receiver (receiver_label)); 581 else 582#endif 583#ifdef HAVE_nonlocal_goto_receiver 584 if (HAVE_nonlocal_goto_receiver) 585 emit_insn (gen_nonlocal_goto_receiver ()); 586 else 587#endif 588 { /* Nothing */ } 589 590 /* @@@ This is a kludge. Not all machine descriptions define a blockage 591 insn, but we must not allow the code we just generated to be reordered 592 by scheduling. Specifically, the update of the frame pointer must 593 happen immediately, not later. So emit an ASM_INPUT to act as blockage 594 insn. */ 595 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, "")); 596} 597 598/* __builtin_setjmp is passed a pointer to an array of five words (not 599 all will be used on all machines). It operates similarly to the C 600 library function of the same name, but is more efficient. Much of 601 the code below (and for longjmp) is copied from the handling of 602 non-local gotos. 603 604 NOTE: This is intended for use by GNAT and the exception handling 605 scheme in the compiler and will only work in the method used by 606 them. */ 607 608static rtx 609expand_builtin_setjmp (tree arglist, rtx target) 610{ 611 rtx buf_addr, next_lab, cont_lab; 612 613 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 614 return NULL_RTX; 615 616 if (target == 0 || GET_CODE (target) != REG 617 || REGNO (target) < FIRST_PSEUDO_REGISTER) 618 target = gen_reg_rtx (TYPE_MODE (integer_type_node)); 619 620 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0); 621 622 next_lab = gen_label_rtx (); 623 cont_lab = gen_label_rtx (); 624 625 expand_builtin_setjmp_setup (buf_addr, next_lab); 626 627 /* Set TARGET to zero and branch to the continue label. Use emit_jump to 628 ensure that pending stack adjustments are flushed. */ 629 emit_move_insn (target, const0_rtx); 630 emit_jump (cont_lab); 631 632 emit_label (next_lab); 633 634 expand_builtin_setjmp_receiver (next_lab); 635 636 /* Set TARGET to one. */ 637 emit_move_insn (target, const1_rtx); 638 emit_label (cont_lab); 639 640 /* Tell flow about the strange goings on. Putting `next_lab' on 641 `nonlocal_goto_handler_labels' to indicates that function 642 calls may traverse the arc back to this label. */ 643 644 current_function_has_nonlocal_label = 1; 645 nonlocal_goto_handler_labels 646 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels); 647 648 return target; 649} 650 651/* __builtin_longjmp is passed a pointer to an array of five words (not 652 all will be used on all machines). It operates similarly to the C 653 library function of the same name, but is more efficient. Much of 654 the code below is copied from the handling of non-local gotos. 655 656 NOTE: This is intended for use by GNAT and the exception handling 657 scheme in the compiler and will only work in the method used by 658 them. */ 659 660void 661expand_builtin_longjmp (rtx buf_addr, rtx value) 662{ 663 rtx fp, lab, stack, insn, last; 664 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); 665 666 if (setjmp_alias_set == -1) 667 setjmp_alias_set = new_alias_set (); 668 669 buf_addr = convert_memory_address (Pmode, buf_addr); 670 671 buf_addr = force_reg (Pmode, buf_addr); 672 673 /* We used to store value in static_chain_rtx, but that fails if pointers 674 are smaller than integers. We instead require that the user must pass 675 a second argument of 1, because that is what builtin_setjmp will 676 return. This also makes EH slightly more efficient, since we are no 677 longer copying around a value that we don't care about. */ 678 if (value != const1_rtx) 679 abort (); 680 681 current_function_calls_longjmp = 1; 682 683 last = get_last_insn (); 684#ifdef HAVE_builtin_longjmp 685 if (HAVE_builtin_longjmp) 686 emit_insn (gen_builtin_longjmp (buf_addr)); 687 else 688#endif 689 { 690 fp = gen_rtx_MEM (Pmode, buf_addr); 691 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr, 692 GET_MODE_SIZE (Pmode))); 693 694 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr, 695 2 * GET_MODE_SIZE (Pmode))); 696 set_mem_alias_set (fp, setjmp_alias_set); 697 set_mem_alias_set (lab, setjmp_alias_set); 698 set_mem_alias_set (stack, setjmp_alias_set); 699 700 /* Pick up FP, label, and SP from the block and jump. This code is 701 from expand_goto in stmt.c; see there for detailed comments. */ 702#if HAVE_nonlocal_goto 703 if (HAVE_nonlocal_goto) 704 /* We have to pass a value to the nonlocal_goto pattern that will 705 get copied into the static_chain pointer, but it does not matter 706 what that value is, because builtin_setjmp does not use it. */ 707 emit_insn (gen_nonlocal_goto (value, lab, stack, fp)); 708 else 709#endif 710 { 711 lab = copy_to_reg (lab); 712 713 emit_insn (gen_rtx_CLOBBER (VOIDmode, 714 gen_rtx_MEM (BLKmode, 715 gen_rtx_SCRATCH (VOIDmode)))); 716 emit_insn (gen_rtx_CLOBBER (VOIDmode, 717 gen_rtx_MEM (BLKmode, 718 hard_frame_pointer_rtx))); 719 720 emit_move_insn (hard_frame_pointer_rtx, fp); 721 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX); 722 723 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); 724 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); 725 emit_indirect_jump (lab); 726 } 727 } 728 729 /* Search backwards and mark the jump insn as a non-local goto. 730 Note that this precludes the use of __builtin_longjmp to a 731 __builtin_setjmp target in the same function. However, we've 732 already cautioned the user that these functions are for 733 internal exception handling use only. */ 734 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) 735 { 736 if (insn == last) 737 abort (); 738 if (GET_CODE (insn) == JUMP_INSN) 739 { 740 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx, 741 REG_NOTES (insn)); 742 break; 743 } 744 else if (GET_CODE (insn) == CALL_INSN) 745 break; 746 } 747} 748 749/* Expand a call to __builtin_prefetch. For a target that does not support 750 data prefetch, evaluate the memory address argument in case it has side 751 effects. */ 752 753static void 754expand_builtin_prefetch (tree arglist) 755{ 756 tree arg0, arg1, arg2; 757 rtx op0, op1, op2; 758 759 if (!validate_arglist (arglist, POINTER_TYPE, 0)) 760 return; 761 762 arg0 = TREE_VALUE (arglist); 763 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to 764 zero (read) and argument 2 (locality) defaults to 3 (high degree of 765 locality). */ 766 if (TREE_CHAIN (arglist)) 767 { 768 arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 769 if (TREE_CHAIN (TREE_CHAIN (arglist))) 770 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 771 else 772 arg2 = build_int_2 (3, 0); 773 } 774 else 775 { 776 arg1 = integer_zero_node; 777 arg2 = build_int_2 (3, 0); 778 } 779 780 /* Argument 0 is an address. */ 781 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL); 782 783 /* Argument 1 (read/write flag) must be a compile-time constant int. */ 784 if (TREE_CODE (arg1) != INTEGER_CST) 785 { 786 error ("second arg to `__builtin_prefetch' must be a constant"); 787 arg1 = integer_zero_node; 788 } 789 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); 790 /* Argument 1 must be either zero or one. */ 791 if (INTVAL (op1) != 0 && INTVAL (op1) != 1) 792 { 793 warning ("invalid second arg to __builtin_prefetch; using zero"); 794 op1 = const0_rtx; 795 } 796 797 /* Argument 2 (locality) must be a compile-time constant int. */ 798 if (TREE_CODE (arg2) != INTEGER_CST) 799 { 800 error ("third arg to `__builtin_prefetch' must be a constant"); 801 arg2 = integer_zero_node; 802 } 803 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); 804 /* Argument 2 must be 0, 1, 2, or 3. */ 805 if (INTVAL (op2) < 0 || INTVAL (op2) > 3) 806 { 807 warning ("invalid third arg to __builtin_prefetch; using zero"); 808 op2 = const0_rtx; 809 } 810 811#ifdef HAVE_prefetch 812 if (HAVE_prefetch) 813 { 814 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate) 815 (op0, 816 insn_data[(int) CODE_FOR_prefetch].operand[0].mode)) 817 || (GET_MODE (op0) != Pmode)) 818 { 819 op0 = convert_memory_address (Pmode, op0); 820 op0 = force_reg (Pmode, op0); 821 } 822 emit_insn (gen_prefetch (op0, op1, op2)); 823 } 824 else 825#endif 826 op0 = protect_from_queue (op0, 0); 827 /* Don't do anything with direct references to volatile memory, but 828 generate code to handle other side effects. */ 829 if (GET_CODE (op0) != MEM && side_effects_p (op0)) 830 emit_insn (op0); 831} 832 833/* Get a MEM rtx for expression EXP which is the address of an operand 834 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */ 835 836static rtx 837get_memory_rtx (tree exp) 838{ 839 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM); 840 rtx mem; 841 842 addr = convert_memory_address (Pmode, addr); 843 844 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr)); 845 846 /* Get an expression we can use to find the attributes to assign to MEM. 847 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if 848 we can. First remove any nops. */ 849 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR 850 || TREE_CODE (exp) == NON_LVALUE_EXPR) 851 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0)))) 852 exp = TREE_OPERAND (exp, 0); 853 854 if (TREE_CODE (exp) == ADDR_EXPR) 855 { 856 exp = TREE_OPERAND (exp, 0); 857 set_mem_attributes (mem, exp, 0); 858 } 859 else if (POINTER_TYPE_P (TREE_TYPE (exp))) 860 { 861 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp); 862 /* memcpy, memset and other builtin stringops can alias with anything. */ 863 set_mem_alias_set (mem, 0); 864 } 865 866 return mem; 867} 868 869/* Built-in functions to perform an untyped call and return. */ 870 871/* For each register that may be used for calling a function, this 872 gives a mode used to copy the register's value. VOIDmode indicates 873 the register is not used for calling a function. If the machine 874 has register windows, this gives only the outbound registers. 875 INCOMING_REGNO gives the corresponding inbound register. */ 876static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER]; 877 878/* For each register that may be used for returning values, this gives 879 a mode used to copy the register's value. VOIDmode indicates the 880 register is not used for returning values. If the machine has 881 register windows, this gives only the outbound registers. 882 INCOMING_REGNO gives the corresponding inbound register. */ 883static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER]; 884 885/* For each register that may be used for calling a function, this 886 gives the offset of that register into the block returned by 887 __builtin_apply_args. 0 indicates that the register is not 888 used for calling a function. */ 889static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER]; 890 891/* Return the offset of register REGNO into the block returned by 892 __builtin_apply_args. This is not declared static, since it is 893 needed in objc-act.c. */ 894 895int 896apply_args_register_offset (int regno) 897{ 898 apply_args_size (); 899 900 /* Arguments are always put in outgoing registers (in the argument 901 block) if such make sense. */ 902#ifdef OUTGOING_REGNO 903 regno = OUTGOING_REGNO (regno); 904#endif 905 return apply_args_reg_offset[regno]; 906} 907 908/* Return the size required for the block returned by __builtin_apply_args, 909 and initialize apply_args_mode. */ 910 911static int 912apply_args_size (void) 913{ 914 static int size = -1; 915 int align; 916 unsigned int regno; 917 enum machine_mode mode; 918 919 /* The values computed by this function never change. */ 920 if (size < 0) 921 { 922 /* The first value is the incoming arg-pointer. */ 923 size = GET_MODE_SIZE (Pmode); 924 925 /* The second value is the structure value address unless this is 926 passed as an "invisible" first argument. */ 927 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0)) 928 size += GET_MODE_SIZE (Pmode); 929 930 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 931 if (FUNCTION_ARG_REGNO_P (regno)) 932 { 933 /* Search for the proper mode for copying this register's 934 value. I'm not sure this is right, but it works so far. */ 935 enum machine_mode best_mode = VOIDmode; 936 937 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); 938 mode != VOIDmode; 939 mode = GET_MODE_WIDER_MODE (mode)) 940 if (HARD_REGNO_MODE_OK (regno, mode) 941 && HARD_REGNO_NREGS (regno, mode) == 1) 942 best_mode = mode; 943 944 if (best_mode == VOIDmode) 945 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); 946 mode != VOIDmode; 947 mode = GET_MODE_WIDER_MODE (mode)) 948 if (HARD_REGNO_MODE_OK (regno, mode) 949 && have_insn_for (SET, mode)) 950 best_mode = mode; 951 952 if (best_mode == VOIDmode) 953 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT); 954 mode != VOIDmode; 955 mode = GET_MODE_WIDER_MODE (mode)) 956 if (HARD_REGNO_MODE_OK (regno, mode) 957 && have_insn_for (SET, mode)) 958 best_mode = mode; 959 960 if (best_mode == VOIDmode) 961 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT); 962 mode != VOIDmode; 963 mode = GET_MODE_WIDER_MODE (mode)) 964 if (HARD_REGNO_MODE_OK (regno, mode) 965 && have_insn_for (SET, mode)) 966 best_mode = mode; 967 968 mode = best_mode; 969 if (mode == VOIDmode) 970 abort (); 971 972 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 973 if (size % align != 0) 974 size = CEIL (size, align) * align; 975 apply_args_reg_offset[regno] = size; 976 size += GET_MODE_SIZE (mode); 977 apply_args_mode[regno] = mode; 978 } 979 else 980 { 981 apply_args_mode[regno] = VOIDmode; 982 apply_args_reg_offset[regno] = 0; 983 } 984 } 985 return size; 986} 987 988/* Return the size required for the block returned by __builtin_apply, 989 and initialize apply_result_mode. */ 990 991static int 992apply_result_size (void) 993{ 994 static int size = -1; 995 int align, regno; 996 enum machine_mode mode; 997 998 /* The values computed by this function never change. */ 999 if (size < 0) 1000 { 1001 size = 0; 1002 1003 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1004 if (FUNCTION_VALUE_REGNO_P (regno)) 1005 { 1006 /* Search for the proper mode for copying this register's 1007 value. I'm not sure this is right, but it works so far. */ 1008 enum machine_mode best_mode = VOIDmode; 1009 1010 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); 1011 mode != TImode; 1012 mode = GET_MODE_WIDER_MODE (mode)) 1013 if (HARD_REGNO_MODE_OK (regno, mode)) 1014 best_mode = mode; 1015 1016 if (best_mode == VOIDmode) 1017 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); 1018 mode != VOIDmode; 1019 mode = GET_MODE_WIDER_MODE (mode)) 1020 if (HARD_REGNO_MODE_OK (regno, mode) 1021 && have_insn_for (SET, mode)) 1022 best_mode = mode; 1023 1024 if (best_mode == VOIDmode) 1025 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT); 1026 mode != VOIDmode; 1027 mode = GET_MODE_WIDER_MODE (mode)) 1028 if (HARD_REGNO_MODE_OK (regno, mode) 1029 && have_insn_for (SET, mode)) 1030 best_mode = mode; 1031 1032 if (best_mode == VOIDmode) 1033 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT); 1034 mode != VOIDmode; 1035 mode = GET_MODE_WIDER_MODE (mode)) 1036 if (HARD_REGNO_MODE_OK (regno, mode) 1037 && have_insn_for (SET, mode)) 1038 best_mode = mode; 1039 1040 mode = best_mode; 1041 if (mode == VOIDmode) 1042 abort (); 1043 1044 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1045 if (size % align != 0) 1046 size = CEIL (size, align) * align; 1047 size += GET_MODE_SIZE (mode); 1048 apply_result_mode[regno] = mode; 1049 } 1050 else 1051 apply_result_mode[regno] = VOIDmode; 1052 1053 /* Allow targets that use untyped_call and untyped_return to override 1054 the size so that machine-specific information can be stored here. */ 1055#ifdef APPLY_RESULT_SIZE 1056 size = APPLY_RESULT_SIZE; 1057#endif 1058 } 1059 return size; 1060} 1061 1062#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return) 1063/* Create a vector describing the result block RESULT. If SAVEP is true, 1064 the result block is used to save the values; otherwise it is used to 1065 restore the values. */ 1066 1067static rtx 1068result_vector (int savep, rtx result) 1069{ 1070 int regno, size, align, nelts; 1071 enum machine_mode mode; 1072 rtx reg, mem; 1073 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx)); 1074 1075 size = nelts = 0; 1076 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1077 if ((mode = apply_result_mode[regno]) != VOIDmode) 1078 { 1079 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1080 if (size % align != 0) 1081 size = CEIL (size, align) * align; 1082 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno)); 1083 mem = adjust_address (result, mode, size); 1084 savevec[nelts++] = (savep 1085 ? gen_rtx_SET (VOIDmode, mem, reg) 1086 : gen_rtx_SET (VOIDmode, reg, mem)); 1087 size += GET_MODE_SIZE (mode); 1088 } 1089 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec)); 1090} 1091#endif /* HAVE_untyped_call or HAVE_untyped_return */ 1092 1093/* Save the state required to perform an untyped call with the same 1094 arguments as were passed to the current function. */ 1095 1096static rtx 1097expand_builtin_apply_args_1 (void) 1098{ 1099 rtx registers, tem; 1100 int size, align, regno; 1101 enum machine_mode mode; 1102 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1); 1103 1104 /* Create a block where the arg-pointer, structure value address, 1105 and argument registers can be saved. */ 1106 registers = assign_stack_local (BLKmode, apply_args_size (), -1); 1107 1108 /* Walk past the arg-pointer and structure value address. */ 1109 size = GET_MODE_SIZE (Pmode); 1110 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0)) 1111 size += GET_MODE_SIZE (Pmode); 1112 1113 /* Save each register used in calling a function to the block. */ 1114 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1115 if ((mode = apply_args_mode[regno]) != VOIDmode) 1116 { 1117 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1118 if (size % align != 0) 1119 size = CEIL (size, align) * align; 1120 1121 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno)); 1122 1123 emit_move_insn (adjust_address (registers, mode, size), tem); 1124 size += GET_MODE_SIZE (mode); 1125 } 1126 1127 /* Save the arg pointer to the block. */ 1128 tem = copy_to_reg (virtual_incoming_args_rtx); 1129#ifdef STACK_GROWS_DOWNWARD 1130 /* We need the pointer as the caller actually passed them to us, not 1131 as we might have pretended they were passed. Make sure it's a valid 1132 operand, as emit_move_insn isn't expected to handle a PLUS. */ 1133 tem 1134 = force_operand (plus_constant (tem, current_function_pretend_args_size), 1135 NULL_RTX); 1136#endif 1137 emit_move_insn (adjust_address (registers, Pmode, 0), tem); 1138 1139 size = GET_MODE_SIZE (Pmode); 1140 1141 /* Save the structure value address unless this is passed as an 1142 "invisible" first argument. */ 1143 if (struct_incoming_value) 1144 { 1145 emit_move_insn (adjust_address (registers, Pmode, size), 1146 copy_to_reg (struct_incoming_value)); 1147 size += GET_MODE_SIZE (Pmode); 1148 } 1149 1150 /* Return the address of the block. */ 1151 return copy_addr_to_reg (XEXP (registers, 0)); 1152} 1153 1154/* __builtin_apply_args returns block of memory allocated on 1155 the stack into which is stored the arg pointer, structure 1156 value address, static chain, and all the registers that might 1157 possibly be used in performing a function call. The code is 1158 moved to the start of the function so the incoming values are 1159 saved. */ 1160 1161static rtx 1162expand_builtin_apply_args (void) 1163{ 1164 /* Don't do __builtin_apply_args more than once in a function. 1165 Save the result of the first call and reuse it. */ 1166 if (apply_args_value != 0) 1167 return apply_args_value; 1168 { 1169 /* When this function is called, it means that registers must be 1170 saved on entry to this function. So we migrate the 1171 call to the first insn of this function. */ 1172 rtx temp; 1173 rtx seq; 1174 1175 start_sequence (); 1176 temp = expand_builtin_apply_args_1 (); 1177 seq = get_insns (); 1178 end_sequence (); 1179 1180 apply_args_value = temp; 1181 1182 /* Put the insns after the NOTE that starts the function. 1183 If this is inside a start_sequence, make the outer-level insn 1184 chain current, so the code is placed at the start of the 1185 function. */ 1186 push_topmost_sequence (); 1187 emit_insn_before (seq, NEXT_INSN (get_insns ())); 1188 pop_topmost_sequence (); 1189 return temp; 1190 } 1191} 1192 1193/* Perform an untyped call and save the state required to perform an 1194 untyped return of whatever value was returned by the given function. */ 1195 1196static rtx 1197expand_builtin_apply (rtx function, rtx arguments, rtx argsize) 1198{ 1199 int size, align, regno; 1200 enum machine_mode mode; 1201 rtx incoming_args, result, reg, dest, src, call_insn; 1202 rtx old_stack_level = 0; 1203 rtx call_fusage = 0; 1204 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0); 1205 1206 arguments = convert_memory_address (Pmode, arguments); 1207 1208 /* Create a block where the return registers can be saved. */ 1209 result = assign_stack_local (BLKmode, apply_result_size (), -1); 1210 1211 /* Fetch the arg pointer from the ARGUMENTS block. */ 1212 incoming_args = gen_reg_rtx (Pmode); 1213 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments)); 1214#ifndef STACK_GROWS_DOWNWARD 1215 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize, 1216 incoming_args, 0, OPTAB_LIB_WIDEN); 1217#endif 1218 1219 /* Perform postincrements before actually calling the function. */ 1220 emit_queue (); 1221 1222 /* Push a new argument block and copy the arguments. Do not allow 1223 the (potential) memcpy call below to interfere with our stack 1224 manipulations. */ 1225 do_pending_stack_adjust (); 1226 NO_DEFER_POP; 1227 1228 /* Save the stack with nonlocal if available. */ 1229#ifdef HAVE_save_stack_nonlocal 1230 if (HAVE_save_stack_nonlocal) 1231 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX); 1232 else 1233#endif 1234 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); 1235 1236 /* Allocate a block of memory onto the stack and copy the memory 1237 arguments to the outgoing arguments address. */ 1238 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT); 1239 dest = virtual_outgoing_args_rtx; 1240#ifndef STACK_GROWS_DOWNWARD 1241 if (GET_CODE (argsize) == CONST_INT) 1242 dest = plus_constant (dest, -INTVAL (argsize)); 1243 else 1244 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize)); 1245#endif 1246 dest = gen_rtx_MEM (BLKmode, dest); 1247 set_mem_align (dest, PARM_BOUNDARY); 1248 src = gen_rtx_MEM (BLKmode, incoming_args); 1249 set_mem_align (src, PARM_BOUNDARY); 1250 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL); 1251 1252 /* Refer to the argument block. */ 1253 apply_args_size (); 1254 arguments = gen_rtx_MEM (BLKmode, arguments); 1255 set_mem_align (arguments, PARM_BOUNDARY); 1256 1257 /* Walk past the arg-pointer and structure value address. */ 1258 size = GET_MODE_SIZE (Pmode); 1259 if (struct_value) 1260 size += GET_MODE_SIZE (Pmode); 1261 1262 /* Restore each of the registers previously saved. Make USE insns 1263 for each of these registers for use in making the call. */ 1264 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1265 if ((mode = apply_args_mode[regno]) != VOIDmode) 1266 { 1267 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1268 if (size % align != 0) 1269 size = CEIL (size, align) * align; 1270 reg = gen_rtx_REG (mode, regno); 1271 emit_move_insn (reg, adjust_address (arguments, mode, size)); 1272 use_reg (&call_fusage, reg); 1273 size += GET_MODE_SIZE (mode); 1274 } 1275 1276 /* Restore the structure value address unless this is passed as an 1277 "invisible" first argument. */ 1278 size = GET_MODE_SIZE (Pmode); 1279 if (struct_value) 1280 { 1281 rtx value = gen_reg_rtx (Pmode); 1282 emit_move_insn (value, adjust_address (arguments, Pmode, size)); 1283 emit_move_insn (struct_value, value); 1284 if (GET_CODE (struct_value) == REG) 1285 use_reg (&call_fusage, struct_value); 1286 size += GET_MODE_SIZE (Pmode); 1287 } 1288 1289 /* All arguments and registers used for the call are set up by now! */ 1290 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0); 1291 1292 /* Ensure address is valid. SYMBOL_REF is already valid, so no need, 1293 and we don't want to load it into a register as an optimization, 1294 because prepare_call_address already did it if it should be done. */ 1295 if (GET_CODE (function) != SYMBOL_REF) 1296 function = memory_address (FUNCTION_MODE, function); 1297 1298 /* Generate the actual call instruction and save the return value. */ 1299#ifdef HAVE_untyped_call 1300 if (HAVE_untyped_call) 1301 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function), 1302 result, result_vector (1, result))); 1303 else 1304#endif 1305#ifdef HAVE_call_value 1306 if (HAVE_call_value) 1307 { 1308 rtx valreg = 0; 1309 1310 /* Locate the unique return register. It is not possible to 1311 express a call that sets more than one return register using 1312 call_value; use untyped_call for that. In fact, untyped_call 1313 only needs to save the return registers in the given block. */ 1314 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1315 if ((mode = apply_result_mode[regno]) != VOIDmode) 1316 { 1317 if (valreg) 1318 abort (); /* HAVE_untyped_call required. */ 1319 valreg = gen_rtx_REG (mode, regno); 1320 } 1321 1322 emit_call_insn (GEN_CALL_VALUE (valreg, 1323 gen_rtx_MEM (FUNCTION_MODE, function), 1324 const0_rtx, NULL_RTX, const0_rtx)); 1325 1326 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg); 1327 } 1328 else 1329#endif 1330 abort (); 1331 1332 /* Find the CALL insn we just emitted, and attach the register usage 1333 information. */ 1334 call_insn = last_call_insn (); 1335 add_function_usage_to (call_insn, call_fusage); 1336 1337 /* Restore the stack. */ 1338#ifdef HAVE_save_stack_nonlocal 1339 if (HAVE_save_stack_nonlocal) 1340 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX); 1341 else 1342#endif 1343 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX); 1344 1345 OK_DEFER_POP; 1346 1347 /* Return the address of the result block. */ 1348 result = copy_addr_to_reg (XEXP (result, 0)); 1349 return convert_memory_address (ptr_mode, result); 1350} 1351 1352/* Perform an untyped return. */ 1353 1354static void 1355expand_builtin_return (rtx result) 1356{ 1357 int size, align, regno; 1358 enum machine_mode mode; 1359 rtx reg; 1360 rtx call_fusage = 0; 1361 1362 result = convert_memory_address (Pmode, result); 1363 1364 apply_result_size (); 1365 result = gen_rtx_MEM (BLKmode, result); 1366 1367#ifdef HAVE_untyped_return 1368 if (HAVE_untyped_return) 1369 { 1370 emit_jump_insn (gen_untyped_return (result, result_vector (0, result))); 1371 emit_barrier (); 1372 return; 1373 } 1374#endif 1375 1376 /* Restore the return value and note that each value is used. */ 1377 size = 0; 1378 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1379 if ((mode = apply_result_mode[regno]) != VOIDmode) 1380 { 1381 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; 1382 if (size % align != 0) 1383 size = CEIL (size, align) * align; 1384 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno)); 1385 emit_move_insn (reg, adjust_address (result, mode, size)); 1386 1387 push_to_sequence (call_fusage); 1388 emit_insn (gen_rtx_USE (VOIDmode, reg)); 1389 call_fusage = get_insns (); 1390 end_sequence (); 1391 size += GET_MODE_SIZE (mode); 1392 } 1393 1394 /* Put the USE insns before the return. */ 1395 emit_insn (call_fusage); 1396 1397 /* Return whatever values was restored by jumping directly to the end 1398 of the function. */ 1399 expand_naked_return (); 1400} 1401 1402/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */ 1403 1404static enum type_class 1405type_to_class (tree type) 1406{ 1407 switch (TREE_CODE (type)) 1408 { 1409 case VOID_TYPE: return void_type_class; 1410 case INTEGER_TYPE: return integer_type_class; 1411 case CHAR_TYPE: return char_type_class; 1412 case ENUMERAL_TYPE: return enumeral_type_class; 1413 case BOOLEAN_TYPE: return boolean_type_class; 1414 case POINTER_TYPE: return pointer_type_class; 1415 case REFERENCE_TYPE: return reference_type_class; 1416 case OFFSET_TYPE: return offset_type_class; 1417 case REAL_TYPE: return real_type_class; 1418 case COMPLEX_TYPE: return complex_type_class; 1419 case FUNCTION_TYPE: return function_type_class; 1420 case METHOD_TYPE: return method_type_class; 1421 case RECORD_TYPE: return record_type_class; 1422 case UNION_TYPE: 1423 case QUAL_UNION_TYPE: return union_type_class; 1424 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type) 1425 ? string_type_class : array_type_class); 1426 case SET_TYPE: return set_type_class; 1427 case FILE_TYPE: return file_type_class; 1428 case LANG_TYPE: return lang_type_class; 1429 default: return no_type_class; 1430 } 1431} 1432 1433/* Expand a call to __builtin_classify_type with arguments found in 1434 ARGLIST. */ 1435 1436static rtx 1437expand_builtin_classify_type (tree arglist) 1438{ 1439 if (arglist != 0) 1440 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist)))); 1441 return GEN_INT (no_type_class); 1442} 1443 1444/* Expand expression EXP, which is a call to __builtin_constant_p. */ 1445 1446static rtx 1447expand_builtin_constant_p (tree arglist, enum machine_mode target_mode) 1448{ 1449 rtx tmp; 1450 1451 if (arglist == 0) 1452 return const0_rtx; 1453 arglist = TREE_VALUE (arglist); 1454 1455 /* We have taken care of the easy cases during constant folding. This 1456 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE 1457 get a chance to see if it can deduce whether ARGLIST is constant. 1458 If CSE isn't going to run, of course, don't bother waiting. */ 1459 1460 if (cse_not_expected) 1461 return const0_rtx; 1462 1463 current_function_calls_constant_p = 1; 1464 1465 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0); 1466 tmp = gen_rtx_CONSTANT_P_RTX (target_mode, tmp); 1467 return tmp; 1468} 1469 1470/* This helper macro, meant to be used in mathfn_built_in below, 1471 determines which among a set of three builtin math functions is 1472 appropriate for a given type mode. The `F' and `L' cases are 1473 automatically generated from the `double' case. */ 1474#define CASE_MATHFN(BUILT_IN_MATHFN) \ 1475 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \ 1476 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \ 1477 fcodel = BUILT_IN_MATHFN##L ; break; 1478 1479/* Return mathematic function equivalent to FN but operating directly 1480 on TYPE, if available. If we can't do the conversion, return zero. */ 1481tree 1482mathfn_built_in (tree type, enum built_in_function fn) 1483{ 1484 const enum machine_mode type_mode = TYPE_MODE (type); 1485 enum built_in_function fcode, fcodef, fcodel; 1486 1487 switch (fn) 1488 { 1489 CASE_MATHFN (BUILT_IN_ACOS) 1490 CASE_MATHFN (BUILT_IN_ACOSH) 1491 CASE_MATHFN (BUILT_IN_ASIN) 1492 CASE_MATHFN (BUILT_IN_ASINH) 1493 CASE_MATHFN (BUILT_IN_ATAN) 1494 CASE_MATHFN (BUILT_IN_ATAN2) 1495 CASE_MATHFN (BUILT_IN_ATANH) 1496 CASE_MATHFN (BUILT_IN_CBRT) 1497 CASE_MATHFN (BUILT_IN_CEIL) 1498 CASE_MATHFN (BUILT_IN_COPYSIGN) 1499 CASE_MATHFN (BUILT_IN_COS) 1500 CASE_MATHFN (BUILT_IN_COSH) 1501 CASE_MATHFN (BUILT_IN_DREM) 1502 CASE_MATHFN (BUILT_IN_ERF) 1503 CASE_MATHFN (BUILT_IN_ERFC) 1504 CASE_MATHFN (BUILT_IN_EXP) 1505 CASE_MATHFN (BUILT_IN_EXP10) 1506 CASE_MATHFN (BUILT_IN_EXP2) 1507 CASE_MATHFN (BUILT_IN_EXPM1) 1508 CASE_MATHFN (BUILT_IN_FABS) 1509 CASE_MATHFN (BUILT_IN_FDIM) 1510 CASE_MATHFN (BUILT_IN_FLOOR) 1511 CASE_MATHFN (BUILT_IN_FMA) 1512 CASE_MATHFN (BUILT_IN_FMAX) 1513 CASE_MATHFN (BUILT_IN_FMIN) 1514 CASE_MATHFN (BUILT_IN_FMOD) 1515 CASE_MATHFN (BUILT_IN_FREXP) 1516 CASE_MATHFN (BUILT_IN_GAMMA) 1517 CASE_MATHFN (BUILT_IN_HUGE_VAL) 1518 CASE_MATHFN (BUILT_IN_HYPOT) 1519 CASE_MATHFN (BUILT_IN_ILOGB) 1520 CASE_MATHFN (BUILT_IN_INF) 1521 CASE_MATHFN (BUILT_IN_J0) 1522 CASE_MATHFN (BUILT_IN_J1) 1523 CASE_MATHFN (BUILT_IN_JN) 1524 CASE_MATHFN (BUILT_IN_LDEXP) 1525 CASE_MATHFN (BUILT_IN_LGAMMA) 1526 CASE_MATHFN (BUILT_IN_LLRINT) 1527 CASE_MATHFN (BUILT_IN_LLROUND) 1528 CASE_MATHFN (BUILT_IN_LOG) 1529 CASE_MATHFN (BUILT_IN_LOG10) 1530 CASE_MATHFN (BUILT_IN_LOG1P) 1531 CASE_MATHFN (BUILT_IN_LOG2) 1532 CASE_MATHFN (BUILT_IN_LOGB) 1533 CASE_MATHFN (BUILT_IN_LRINT) 1534 CASE_MATHFN (BUILT_IN_LROUND) 1535 CASE_MATHFN (BUILT_IN_MODF) 1536 CASE_MATHFN (BUILT_IN_NAN) 1537 CASE_MATHFN (BUILT_IN_NANS) 1538 CASE_MATHFN (BUILT_IN_NEARBYINT) 1539 CASE_MATHFN (BUILT_IN_NEXTAFTER) 1540 CASE_MATHFN (BUILT_IN_NEXTTOWARD) 1541 CASE_MATHFN (BUILT_IN_POW) 1542 CASE_MATHFN (BUILT_IN_POW10) 1543 CASE_MATHFN (BUILT_IN_REMAINDER) 1544 CASE_MATHFN (BUILT_IN_REMQUO) 1545 CASE_MATHFN (BUILT_IN_RINT) 1546 CASE_MATHFN (BUILT_IN_ROUND) 1547 CASE_MATHFN (BUILT_IN_SCALB) 1548 CASE_MATHFN (BUILT_IN_SCALBLN) 1549 CASE_MATHFN (BUILT_IN_SCALBN) 1550 CASE_MATHFN (BUILT_IN_SIGNIFICAND) 1551 CASE_MATHFN (BUILT_IN_SIN) 1552 CASE_MATHFN (BUILT_IN_SINCOS) 1553 CASE_MATHFN (BUILT_IN_SINH) 1554 CASE_MATHFN (BUILT_IN_SQRT) 1555 CASE_MATHFN (BUILT_IN_TAN) 1556 CASE_MATHFN (BUILT_IN_TANH) 1557 CASE_MATHFN (BUILT_IN_TGAMMA) 1558 CASE_MATHFN (BUILT_IN_TRUNC) 1559 CASE_MATHFN (BUILT_IN_Y0) 1560 CASE_MATHFN (BUILT_IN_Y1) 1561 CASE_MATHFN (BUILT_IN_YN) 1562 1563 default: 1564 return 0; 1565 } 1566 1567 if (type_mode == TYPE_MODE (double_type_node)) 1568 return implicit_built_in_decls[fcode]; 1569 else if (type_mode == TYPE_MODE (float_type_node)) 1570 return implicit_built_in_decls[fcodef]; 1571 else if (type_mode == TYPE_MODE (long_double_type_node)) 1572 return implicit_built_in_decls[fcodel]; 1573 else 1574 return 0; 1575} 1576 1577/* If errno must be maintained, expand the RTL to check if the result, 1578 TARGET, of a built-in function call, EXP, is NaN, and if so set 1579 errno to EDOM. */ 1580 1581static void 1582expand_errno_check (tree exp, rtx target) 1583{ 1584 rtx lab = gen_label_rtx (); 1585 1586 /* Test the result; if it is NaN, set errno=EDOM because 1587 the argument was not in the domain. */ 1588 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target), 1589 0, lab); 1590 1591#ifdef TARGET_EDOM 1592 /* If this built-in doesn't throw an exception, set errno directly. */ 1593 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) 1594 { 1595#ifdef GEN_ERRNO_RTX 1596 rtx errno_rtx = GEN_ERRNO_RTX; 1597#else 1598 rtx errno_rtx 1599 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno")); 1600#endif 1601 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM)); 1602 emit_label (lab); 1603 return; 1604 } 1605#endif 1606 1607 /* We can't set errno=EDOM directly; let the library call do it. 1608 Pop the arguments right away in case the call gets deleted. */ 1609 NO_DEFER_POP; 1610 expand_call (exp, target, 0); 1611 OK_DEFER_POP; 1612 emit_label (lab); 1613} 1614 1615 1616/* Expand a call to one of the builtin math functions (sin, cos, or sqrt). 1617 Return 0 if a normal call should be emitted rather than expanding the 1618 function in-line. EXP is the expression that is a call to the builtin 1619 function; if convenient, the result should be placed in TARGET. 1620 SUBTARGET may be used as the target for computing one of EXP's operands. */ 1621 1622static rtx 1623expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) 1624{ 1625 optab builtin_optab; 1626 rtx op0, insns, before_call; 1627 tree fndecl = get_callee_fndecl (exp); 1628 tree arglist = TREE_OPERAND (exp, 1); 1629 enum machine_mode mode; 1630 bool errno_set = false; 1631 tree arg, narg; 1632 1633 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 1634 return 0; 1635 1636 arg = TREE_VALUE (arglist); 1637 1638 switch (DECL_FUNCTION_CODE (fndecl)) 1639 { 1640 case BUILT_IN_SIN: 1641 case BUILT_IN_SINF: 1642 case BUILT_IN_SINL: 1643 builtin_optab = sin_optab; break; 1644 case BUILT_IN_COS: 1645 case BUILT_IN_COSF: 1646 case BUILT_IN_COSL: 1647 builtin_optab = cos_optab; break; 1648 case BUILT_IN_SQRT: 1649 case BUILT_IN_SQRTF: 1650 case BUILT_IN_SQRTL: 1651 errno_set = ! tree_expr_nonnegative_p (arg); 1652 builtin_optab = sqrt_optab; 1653 break; 1654 case BUILT_IN_EXP: 1655 case BUILT_IN_EXPF: 1656 case BUILT_IN_EXPL: 1657 errno_set = true; builtin_optab = exp_optab; break; 1658 case BUILT_IN_LOG: 1659 case BUILT_IN_LOGF: 1660 case BUILT_IN_LOGL: 1661 errno_set = true; builtin_optab = log_optab; break; 1662 case BUILT_IN_TAN: 1663 case BUILT_IN_TANF: 1664 case BUILT_IN_TANL: 1665 builtin_optab = tan_optab; break; 1666 case BUILT_IN_ATAN: 1667 case BUILT_IN_ATANF: 1668 case BUILT_IN_ATANL: 1669 builtin_optab = atan_optab; break; 1670 case BUILT_IN_FLOOR: 1671 case BUILT_IN_FLOORF: 1672 case BUILT_IN_FLOORL: 1673 builtin_optab = floor_optab; break; 1674 case BUILT_IN_CEIL: 1675 case BUILT_IN_CEILF: 1676 case BUILT_IN_CEILL: 1677 builtin_optab = ceil_optab; break; 1678 case BUILT_IN_TRUNC: 1679 case BUILT_IN_TRUNCF: 1680 case BUILT_IN_TRUNCL: 1681 builtin_optab = btrunc_optab; break; 1682 case BUILT_IN_ROUND: 1683 case BUILT_IN_ROUNDF: 1684 case BUILT_IN_ROUNDL: 1685 builtin_optab = round_optab; break; 1686 case BUILT_IN_NEARBYINT: 1687 case BUILT_IN_NEARBYINTF: 1688 case BUILT_IN_NEARBYINTL: 1689 builtin_optab = nearbyint_optab; break; 1690 default: 1691 abort (); 1692 } 1693 1694 /* Make a suitable register to place result in. */ 1695 mode = TYPE_MODE (TREE_TYPE (exp)); 1696 1697 if (! flag_errno_math || ! HONOR_NANS (mode)) 1698 errno_set = false; 1699 1700 /* Before working hard, check whether the instruction is available. */ 1701 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) 1702 { 1703 target = gen_reg_rtx (mode); 1704 1705 /* Wrap the computation of the argument in a SAVE_EXPR, as we may 1706 need to expand the argument again. This way, we will not perform 1707 side-effects more the once. */ 1708 narg = save_expr (arg); 1709 if (narg != arg) 1710 { 1711 arglist = build_tree_list (NULL_TREE, arg); 1712 exp = build_function_call_expr (fndecl, arglist); 1713 } 1714 1715 op0 = expand_expr (arg, subtarget, VOIDmode, 0); 1716 1717 emit_queue (); 1718 start_sequence (); 1719 1720 /* Compute into TARGET. 1721 Set TARGET to wherever the result comes back. */ 1722 target = expand_unop (mode, builtin_optab, op0, target, 0); 1723 1724 if (target != 0) 1725 { 1726 if (errno_set) 1727 expand_errno_check (exp, target); 1728 1729 /* Output the entire sequence. */ 1730 insns = get_insns (); 1731 end_sequence (); 1732 emit_insn (insns); 1733 return target; 1734 } 1735 1736 /* If we were unable to expand via the builtin, stop the sequence 1737 (without outputting the insns) and call to the library function 1738 with the stabilized argument list. */ 1739 end_sequence (); 1740 } 1741 1742 before_call = get_last_insn (); 1743 1744 target = expand_call (exp, target, target == const0_rtx); 1745 1746 /* If this is a sqrt operation and we don't care about errno, try to 1747 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall. 1748 This allows the semantics of the libcall to be visible to the RTL 1749 optimizers. */ 1750 if (builtin_optab == sqrt_optab && !errno_set) 1751 { 1752 /* Search backwards through the insns emitted by expand_call looking 1753 for the instruction with the REG_RETVAL note. */ 1754 rtx last = get_last_insn (); 1755 while (last != before_call) 1756 { 1757 if (find_reg_note (last, REG_RETVAL, NULL)) 1758 { 1759 rtx note = find_reg_note (last, REG_EQUAL, NULL); 1760 /* Check that the REQ_EQUAL note is an EXPR_LIST with 1761 two elements, i.e. symbol_ref(sqrt) and the operand. */ 1762 if (note 1763 && GET_CODE (note) == EXPR_LIST 1764 && GET_CODE (XEXP (note, 0)) == EXPR_LIST 1765 && XEXP (XEXP (note, 0), 1) != NULL_RTX 1766 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX) 1767 { 1768 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0); 1769 /* Check operand is a register with expected mode. */ 1770 if (operand 1771 && GET_CODE (operand) == REG 1772 && GET_MODE (operand) == mode) 1773 { 1774 /* Replace the REG_EQUAL note with a SQRT rtx. */ 1775 rtx equiv = gen_rtx_SQRT (mode, operand); 1776 set_unique_reg_note (last, REG_EQUAL, equiv); 1777 } 1778 } 1779 break; 1780 } 1781 last = PREV_INSN (last); 1782 } 1783 } 1784 1785 return target; 1786} 1787 1788/* Expand a call to the builtin binary math functions (pow and atan2). 1789 Return 0 if a normal call should be emitted rather than expanding the 1790 function in-line. EXP is the expression that is a call to the builtin 1791 function; if convenient, the result should be placed in TARGET. 1792 SUBTARGET may be used as the target for computing one of EXP's 1793 operands. */ 1794 1795static rtx 1796expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget) 1797{ 1798 optab builtin_optab; 1799 rtx op0, op1, insns; 1800 tree fndecl = get_callee_fndecl (exp); 1801 tree arglist = TREE_OPERAND (exp, 1); 1802 tree arg0, arg1, temp, narg; 1803 enum machine_mode mode; 1804 bool errno_set = true; 1805 bool stable = true; 1806 1807 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 1808 return 0; 1809 1810 arg0 = TREE_VALUE (arglist); 1811 arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 1812 1813 switch (DECL_FUNCTION_CODE (fndecl)) 1814 { 1815 case BUILT_IN_POW: 1816 case BUILT_IN_POWF: 1817 case BUILT_IN_POWL: 1818 builtin_optab = pow_optab; break; 1819 case BUILT_IN_ATAN2: 1820 case BUILT_IN_ATAN2F: 1821 case BUILT_IN_ATAN2L: 1822 builtin_optab = atan2_optab; break; 1823 default: 1824 abort (); 1825 } 1826 1827 /* Make a suitable register to place result in. */ 1828 mode = TYPE_MODE (TREE_TYPE (exp)); 1829 1830 /* Before working hard, check whether the instruction is available. */ 1831 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) 1832 return 0; 1833 1834 target = gen_reg_rtx (mode); 1835 1836 if (! flag_errno_math || ! HONOR_NANS (mode)) 1837 errno_set = false; 1838 1839 /* Alway stabilize the argument list. */ 1840 narg = save_expr (arg1); 1841 if (narg != arg1) 1842 { 1843 temp = build_tree_list (NULL_TREE, narg); 1844 stable = false; 1845 } 1846 else 1847 temp = TREE_CHAIN (arglist); 1848 1849 narg = save_expr (arg0); 1850 if (narg != arg0) 1851 { 1852 arglist = tree_cons (NULL_TREE, narg, temp); 1853 stable = false; 1854 } 1855 else if (! stable) 1856 arglist = tree_cons (NULL_TREE, arg0, temp); 1857 1858 if (! stable) 1859 exp = build_function_call_expr (fndecl, arglist); 1860 1861 op0 = expand_expr (arg0, subtarget, VOIDmode, 0); 1862 op1 = expand_expr (arg1, 0, VOIDmode, 0); 1863 1864 emit_queue (); 1865 start_sequence (); 1866 1867 /* Compute into TARGET. 1868 Set TARGET to wherever the result comes back. */ 1869 target = expand_binop (mode, builtin_optab, op0, op1, 1870 target, 0, OPTAB_DIRECT); 1871 1872 /* If we were unable to expand via the builtin, stop the sequence 1873 (without outputting the insns) and call to the library function 1874 with the stabilized argument list. */ 1875 if (target == 0) 1876 { 1877 end_sequence (); 1878 return expand_call (exp, target, target == const0_rtx); 1879 } 1880 1881 if (errno_set) 1882 expand_errno_check (exp, target); 1883 1884 /* Output the entire sequence. */ 1885 insns = get_insns (); 1886 end_sequence (); 1887 emit_insn (insns); 1888 1889 return target; 1890} 1891 1892/* To evaluate powi(x,n), the floating point value x raised to the 1893 constant integer exponent n, we use a hybrid algorithm that 1894 combines the "window method" with look-up tables. For an 1895 introduction to exponentiation algorithms and "addition chains", 1896 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth, 1897 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming", 1898 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation 1899 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */ 1900 1901/* Provide a default value for POWI_MAX_MULTS, the maximum number of 1902 multiplications to inline before calling the system library's pow 1903 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications, 1904 so this default never requires calling pow, powf or powl. */ 1905 1906#ifndef POWI_MAX_MULTS 1907#define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2) 1908#endif 1909 1910/* The size of the "optimal power tree" lookup table. All 1911 exponents less than this value are simply looked up in the 1912 powi_table below. This threshold is also used to size the 1913 cache of pseudo registers that hold intermediate results. */ 1914#define POWI_TABLE_SIZE 256 1915 1916/* The size, in bits of the window, used in the "window method" 1917 exponentiation algorithm. This is equivalent to a radix of 1918 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */ 1919#define POWI_WINDOW_SIZE 3 1920 1921/* The following table is an efficient representation of an 1922 "optimal power tree". For each value, i, the corresponding 1923 value, j, in the table states than an optimal evaluation 1924 sequence for calculating pow(x,i) can be found by evaluating 1925 pow(x,j)*pow(x,i-j). An optimal power tree for the first 1926 100 integers is given in Knuth's "Seminumerical algorithms". */ 1927 1928static const unsigned char powi_table[POWI_TABLE_SIZE] = 1929 { 1930 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */ 1931 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */ 1932 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */ 1933 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */ 1934 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */ 1935 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */ 1936 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */ 1937 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */ 1938 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */ 1939 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */ 1940 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */ 1941 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */ 1942 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */ 1943 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */ 1944 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */ 1945 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */ 1946 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */ 1947 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */ 1948 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */ 1949 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */ 1950 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */ 1951 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */ 1952 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */ 1953 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */ 1954 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */ 1955 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */ 1956 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */ 1957 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */ 1958 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */ 1959 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */ 1960 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */ 1961 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */ 1962 }; 1963 1964 1965/* Return the number of multiplications required to calculate 1966 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a 1967 subroutine of powi_cost. CACHE is an array indicating 1968 which exponents have already been calculated. */ 1969 1970static int 1971powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache) 1972{ 1973 /* If we've already calculated this exponent, then this evaluation 1974 doesn't require any additional multiplications. */ 1975 if (cache[n]) 1976 return 0; 1977 1978 cache[n] = true; 1979 return powi_lookup_cost (n - powi_table[n], cache) 1980 + powi_lookup_cost (powi_table[n], cache) + 1; 1981} 1982 1983/* Return the number of multiplications required to calculate 1984 powi(x,n) for an arbitrary x, given the exponent N. This 1985 function needs to be kept in sync with expand_powi below. */ 1986 1987static int 1988powi_cost (HOST_WIDE_INT n) 1989{ 1990 bool cache[POWI_TABLE_SIZE]; 1991 unsigned HOST_WIDE_INT digit; 1992 unsigned HOST_WIDE_INT val; 1993 int result; 1994 1995 if (n == 0) 1996 return 0; 1997 1998 /* Ignore the reciprocal when calculating the cost. */ 1999 val = (n < 0) ? -n : n; 2000 2001 /* Initialize the exponent cache. */ 2002 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool)); 2003 cache[1] = true; 2004 2005 result = 0; 2006 2007 while (val >= POWI_TABLE_SIZE) 2008 { 2009 if (val & 1) 2010 { 2011 digit = val & ((1 << POWI_WINDOW_SIZE) - 1); 2012 result += powi_lookup_cost (digit, cache) 2013 + POWI_WINDOW_SIZE + 1; 2014 val >>= POWI_WINDOW_SIZE; 2015 } 2016 else 2017 { 2018 val >>= 1; 2019 result++; 2020 } 2021 } 2022 2023 return result + powi_lookup_cost (val, cache); 2024} 2025 2026/* Recursive subroutine of expand_powi. This function takes the array, 2027 CACHE, of already calculated exponents and an exponent N and returns 2028 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */ 2029 2030static rtx 2031expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache) 2032{ 2033 unsigned HOST_WIDE_INT digit; 2034 rtx target, result; 2035 rtx op0, op1; 2036 2037 if (n < POWI_TABLE_SIZE) 2038 { 2039 if (cache[n]) 2040 return cache[n]; 2041 2042 target = gen_reg_rtx (mode); 2043 cache[n] = target; 2044 2045 op0 = expand_powi_1 (mode, n - powi_table[n], cache); 2046 op1 = expand_powi_1 (mode, powi_table[n], cache); 2047 } 2048 else if (n & 1) 2049 { 2050 target = gen_reg_rtx (mode); 2051 digit = n & ((1 << POWI_WINDOW_SIZE) - 1); 2052 op0 = expand_powi_1 (mode, n - digit, cache); 2053 op1 = expand_powi_1 (mode, digit, cache); 2054 } 2055 else 2056 { 2057 target = gen_reg_rtx (mode); 2058 op0 = expand_powi_1 (mode, n >> 1, cache); 2059 op1 = op0; 2060 } 2061 2062 result = expand_mult (mode, op0, op1, target, 0); 2063 if (result != target) 2064 emit_move_insn (target, result); 2065 return target; 2066} 2067 2068/* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the 2069 floating point operand in mode MODE, and N is the exponent. This 2070 function needs to be kept in sync with powi_cost above. */ 2071 2072static rtx 2073expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n) 2074{ 2075 unsigned HOST_WIDE_INT val; 2076 rtx cache[POWI_TABLE_SIZE]; 2077 rtx result; 2078 2079 if (n == 0) 2080 return CONST1_RTX (mode); 2081 2082 val = (n < 0) ? -n : n; 2083 2084 memset (cache, 0, sizeof (cache)); 2085 cache[1] = x; 2086 2087 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache); 2088 2089 /* If the original exponent was negative, reciprocate the result. */ 2090 if (n < 0) 2091 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode), 2092 result, NULL_RTX, 0, OPTAB_LIB_WIDEN); 2093 2094 return result; 2095} 2096 2097/* Expand a call to the pow built-in mathematical function. Return 0 if 2098 a normal call should be emitted rather than expanding the function 2099 in-line. EXP is the expression that is a call to the builtin 2100 function; if convenient, the result should be placed in TARGET. */ 2101 2102static rtx 2103expand_builtin_pow (tree exp, rtx target, rtx subtarget) 2104{ 2105 tree arglist = TREE_OPERAND (exp, 1); 2106 tree arg0, arg1; 2107 2108 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 2109 return 0; 2110 2111 arg0 = TREE_VALUE (arglist); 2112 arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 2113 2114 if (TREE_CODE (arg1) == REAL_CST 2115 && ! TREE_CONSTANT_OVERFLOW (arg1)) 2116 { 2117 REAL_VALUE_TYPE cint; 2118 REAL_VALUE_TYPE c; 2119 HOST_WIDE_INT n; 2120 2121 c = TREE_REAL_CST (arg1); 2122 n = real_to_integer (&c); 2123 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); 2124 if (real_identical (&c, &cint)) 2125 { 2126 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact. 2127 Otherwise, check the number of multiplications required. 2128 Note that pow never sets errno for an integer exponent. */ 2129 if ((n >= -1 && n <= 2) 2130 || (flag_unsafe_math_optimizations 2131 && ! optimize_size 2132 && powi_cost (n) <= POWI_MAX_MULTS)) 2133 { 2134 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); 2135 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0); 2136 op = force_reg (mode, op); 2137 return expand_powi (op, mode, n); 2138 } 2139 } 2140 } 2141 return expand_builtin_mathfn_2 (exp, target, NULL_RTX); 2142} 2143 2144/* Expand expression EXP which is a call to the strlen builtin. Return 0 2145 if we failed the caller should emit a normal call, otherwise 2146 try to get the result in TARGET, if convenient. */ 2147 2148static rtx 2149expand_builtin_strlen (tree arglist, rtx target, 2150 enum machine_mode target_mode) 2151{ 2152 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 2153 return 0; 2154 else 2155 { 2156 rtx pat; 2157 tree len, src = TREE_VALUE (arglist); 2158 rtx result, src_reg, char_rtx, before_strlen; 2159 enum machine_mode insn_mode = target_mode, char_mode; 2160 enum insn_code icode = CODE_FOR_nothing; 2161 int align; 2162 2163 /* If the length can be computed at compile-time, return it. */ 2164 len = c_strlen (src, 0); 2165 if (len) 2166 return expand_expr (len, target, target_mode, EXPAND_NORMAL); 2167 2168 /* If the length can be computed at compile-time and is constant 2169 integer, but there are side-effects in src, evaluate 2170 src for side-effects, then return len. 2171 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar"); 2172 can be optimized into: i++; x = 3; */ 2173 len = c_strlen (src, 1); 2174 if (len && TREE_CODE (len) == INTEGER_CST) 2175 { 2176 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL); 2177 return expand_expr (len, target, target_mode, EXPAND_NORMAL); 2178 } 2179 2180 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 2181 2182 /* If SRC is not a pointer type, don't do this operation inline. */ 2183 if (align == 0) 2184 return 0; 2185 2186 /* Bail out if we can't compute strlen in the right mode. */ 2187 while (insn_mode != VOIDmode) 2188 { 2189 icode = strlen_optab->handlers[(int) insn_mode].insn_code; 2190 if (icode != CODE_FOR_nothing) 2191 break; 2192 2193 insn_mode = GET_MODE_WIDER_MODE (insn_mode); 2194 } 2195 if (insn_mode == VOIDmode) 2196 return 0; 2197 2198 /* Make a place to write the result of the instruction. */ 2199 result = target; 2200 if (! (result != 0 2201 && GET_CODE (result) == REG 2202 && GET_MODE (result) == insn_mode 2203 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 2204 result = gen_reg_rtx (insn_mode); 2205 2206 /* Make a place to hold the source address. We will not expand 2207 the actual source until we are sure that the expansion will 2208 not fail -- there are trees that cannot be expanded twice. */ 2209 src_reg = gen_reg_rtx (Pmode); 2210 2211 /* Mark the beginning of the strlen sequence so we can emit the 2212 source operand later. */ 2213 before_strlen = get_last_insn (); 2214 2215 char_rtx = const0_rtx; 2216 char_mode = insn_data[(int) icode].operand[2].mode; 2217 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx, 2218 char_mode)) 2219 char_rtx = copy_to_mode_reg (char_mode, char_rtx); 2220 2221 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg), 2222 char_rtx, GEN_INT (align)); 2223 if (! pat) 2224 return 0; 2225 emit_insn (pat); 2226 2227 /* Now that we are assured of success, expand the source. */ 2228 start_sequence (); 2229 pat = memory_address (BLKmode, 2230 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM)); 2231 if (pat != src_reg) 2232 emit_move_insn (src_reg, pat); 2233 pat = get_insns (); 2234 end_sequence (); 2235 2236 if (before_strlen) 2237 emit_insn_after (pat, before_strlen); 2238 else 2239 emit_insn_before (pat, get_insns ()); 2240 2241 /* Return the value in the proper mode for this function. */ 2242 if (GET_MODE (result) == target_mode) 2243 target = result; 2244 else if (target != 0) 2245 convert_move (target, result, 0); 2246 else 2247 target = convert_to_mode (target_mode, result, 0); 2248 2249 return target; 2250 } 2251} 2252 2253/* Expand a call to the strstr builtin. Return 0 if we failed the 2254 caller should emit a normal call, otherwise try to get the result 2255 in TARGET, if convenient (and in mode MODE if that's convenient). */ 2256 2257static rtx 2258expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode) 2259{ 2260 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 2261 return 0; 2262 else 2263 { 2264 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 2265 tree fn; 2266 const char *p1, *p2; 2267 2268 p2 = c_getstr (s2); 2269 if (p2 == NULL) 2270 return 0; 2271 2272 p1 = c_getstr (s1); 2273 if (p1 != NULL) 2274 { 2275 const char *r = strstr (p1, p2); 2276 2277 if (r == NULL) 2278 return const0_rtx; 2279 2280 /* Return an offset into the constant string argument. */ 2281 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), 2282 s1, convert (TREE_TYPE (s1), 2283 ssize_int (r - p1)))), 2284 target, mode, EXPAND_NORMAL); 2285 } 2286 2287 if (p2[0] == '\0') 2288 return expand_expr (s1, target, mode, EXPAND_NORMAL); 2289 2290 if (p2[1] != '\0') 2291 return 0; 2292 2293 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 2294 if (!fn) 2295 return 0; 2296 2297 /* New argument list transforming strstr(s1, s2) to 2298 strchr(s1, s2[0]). */ 2299 arglist = 2300 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0)); 2301 arglist = tree_cons (NULL_TREE, s1, arglist); 2302 return expand_expr (build_function_call_expr (fn, arglist), 2303 target, mode, EXPAND_NORMAL); 2304 } 2305} 2306 2307/* Expand a call to the strchr builtin. Return 0 if we failed the 2308 caller should emit a normal call, otherwise try to get the result 2309 in TARGET, if convenient (and in mode MODE if that's convenient). */ 2310 2311static rtx 2312expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode) 2313{ 2314 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2315 return 0; 2316 else 2317 { 2318 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 2319 const char *p1; 2320 2321 if (TREE_CODE (s2) != INTEGER_CST) 2322 return 0; 2323 2324 p1 = c_getstr (s1); 2325 if (p1 != NULL) 2326 { 2327 char c; 2328 const char *r; 2329 2330 if (target_char_cast (s2, &c)) 2331 return 0; 2332 2333 r = strchr (p1, c); 2334 2335 if (r == NULL) 2336 return const0_rtx; 2337 2338 /* Return an offset into the constant string argument. */ 2339 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), 2340 s1, convert (TREE_TYPE (s1), 2341 ssize_int (r - p1)))), 2342 target, mode, EXPAND_NORMAL); 2343 } 2344 2345 /* FIXME: Should use here strchrM optab so that ports can optimize 2346 this. */ 2347 return 0; 2348 } 2349} 2350 2351/* Expand a call to the strrchr builtin. Return 0 if we failed the 2352 caller should emit a normal call, otherwise try to get the result 2353 in TARGET, if convenient (and in mode MODE if that's convenient). */ 2354 2355static rtx 2356expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode) 2357{ 2358 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2359 return 0; 2360 else 2361 { 2362 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 2363 tree fn; 2364 const char *p1; 2365 2366 if (TREE_CODE (s2) != INTEGER_CST) 2367 return 0; 2368 2369 p1 = c_getstr (s1); 2370 if (p1 != NULL) 2371 { 2372 char c; 2373 const char *r; 2374 2375 if (target_char_cast (s2, &c)) 2376 return 0; 2377 2378 r = strrchr (p1, c); 2379 2380 if (r == NULL) 2381 return const0_rtx; 2382 2383 /* Return an offset into the constant string argument. */ 2384 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), 2385 s1, convert (TREE_TYPE (s1), 2386 ssize_int (r - p1)))), 2387 target, mode, EXPAND_NORMAL); 2388 } 2389 2390 if (! integer_zerop (s2)) 2391 return 0; 2392 2393 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 2394 if (!fn) 2395 return 0; 2396 2397 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */ 2398 return expand_expr (build_function_call_expr (fn, arglist), 2399 target, mode, EXPAND_NORMAL); 2400 } 2401} 2402 2403/* Expand a call to the strpbrk builtin. Return 0 if we failed the 2404 caller should emit a normal call, otherwise try to get the result 2405 in TARGET, if convenient (and in mode MODE if that's convenient). */ 2406 2407static rtx 2408expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode) 2409{ 2410 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 2411 return 0; 2412 else 2413 { 2414 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 2415 tree fn; 2416 const char *p1, *p2; 2417 2418 p2 = c_getstr (s2); 2419 if (p2 == NULL) 2420 return 0; 2421 2422 p1 = c_getstr (s1); 2423 if (p1 != NULL) 2424 { 2425 const char *r = strpbrk (p1, p2); 2426 2427 if (r == NULL) 2428 return const0_rtx; 2429 2430 /* Return an offset into the constant string argument. */ 2431 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), 2432 s1, convert (TREE_TYPE (s1), 2433 ssize_int (r - p1)))), 2434 target, mode, EXPAND_NORMAL); 2435 } 2436 2437 if (p2[0] == '\0') 2438 { 2439 /* strpbrk(x, "") == NULL. 2440 Evaluate and ignore the arguments in case they had 2441 side-effects. */ 2442 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL); 2443 return const0_rtx; 2444 } 2445 2446 if (p2[1] != '\0') 2447 return 0; /* Really call strpbrk. */ 2448 2449 fn = implicit_built_in_decls[BUILT_IN_STRCHR]; 2450 if (!fn) 2451 return 0; 2452 2453 /* New argument list transforming strpbrk(s1, s2) to 2454 strchr(s1, s2[0]). */ 2455 arglist = 2456 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0)); 2457 arglist = tree_cons (NULL_TREE, s1, arglist); 2458 return expand_expr (build_function_call_expr (fn, arglist), 2459 target, mode, EXPAND_NORMAL); 2460 } 2461} 2462 2463/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 2464 bytes from constant string DATA + OFFSET and return it as target 2465 constant. */ 2466 2467static rtx 2468builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset, 2469 enum machine_mode mode) 2470{ 2471 const char *str = (const char *) data; 2472 2473 if (offset < 0 2474 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode) 2475 > strlen (str) + 1)) 2476 abort (); /* Attempt to read past the end of constant string. */ 2477 2478 return c_readstr (str + offset, mode); 2479} 2480 2481/* Expand a call to the memcpy builtin, with arguments in ARGLIST. 2482 Return 0 if we failed, the caller should emit a normal call, 2483 otherwise try to get the result in TARGET, if convenient (and in 2484 mode MODE if that's convenient). */ 2485static rtx 2486expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode) 2487{ 2488 if (!validate_arglist (arglist, 2489 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2490 return 0; 2491 else 2492 { 2493 tree dest = TREE_VALUE (arglist); 2494 tree src = TREE_VALUE (TREE_CHAIN (arglist)); 2495 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 2496 const char *src_str; 2497 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 2498 unsigned int dest_align 2499 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 2500 rtx dest_mem, src_mem, dest_addr, len_rtx; 2501 2502 /* If DEST is not a pointer type, call the normal function. */ 2503 if (dest_align == 0) 2504 return 0; 2505 2506 /* If the LEN parameter is zero, return DEST. */ 2507 if (integer_zerop (len)) 2508 { 2509 /* Evaluate and ignore SRC in case it has side-effects. */ 2510 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL); 2511 return expand_expr (dest, target, mode, EXPAND_NORMAL); 2512 } 2513 2514 /* If SRC and DEST are the same (and not volatile), return DEST. */ 2515 if (operand_equal_p (src, dest, 0)) 2516 { 2517 /* Evaluate and ignore LEN in case it has side-effects. */ 2518 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL); 2519 return expand_expr (dest, target, mode, EXPAND_NORMAL); 2520 } 2521 2522 /* If either SRC is not a pointer type, don't do this 2523 operation in-line. */ 2524 if (src_align == 0) 2525 return 0; 2526 2527 dest_mem = get_memory_rtx (dest); 2528 set_mem_align (dest_mem, dest_align); 2529 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); 2530 src_str = c_getstr (src); 2531 2532 /* If SRC is a string constant and block move would be done 2533 by pieces, we can avoid loading the string from memory 2534 and only stored the computed constants. */ 2535 if (src_str 2536 && GET_CODE (len_rtx) == CONST_INT 2537 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1 2538 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str, 2539 (void *) src_str, dest_align)) 2540 { 2541 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx), 2542 builtin_memcpy_read_str, 2543 (void *) src_str, dest_align, 0); 2544 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 2545 dest_mem = convert_memory_address (ptr_mode, dest_mem); 2546 return dest_mem; 2547 } 2548 2549 src_mem = get_memory_rtx (src); 2550 set_mem_align (src_mem, src_align); 2551 2552 /* Copy word part most expediently. */ 2553 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx, 2554 BLOCK_OP_NORMAL); 2555 2556 if (dest_addr == 0) 2557 { 2558 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); 2559 dest_addr = convert_memory_address (ptr_mode, dest_addr); 2560 } 2561 return dest_addr; 2562 } 2563} 2564 2565/* Expand a call to the mempcpy builtin, with arguments in ARGLIST. 2566 Return 0 if we failed the caller should emit a normal call, 2567 otherwise try to get the result in TARGET, if convenient (and in 2568 mode MODE if that's convenient). If ENDP is 0 return the 2569 destination pointer, if ENDP is 1 return the end pointer ala 2570 mempcpy, and if ENDP is 2 return the end pointer minus one ala 2571 stpcpy. */ 2572 2573static rtx 2574expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode, 2575 int endp) 2576{ 2577 if (!validate_arglist (arglist, 2578 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2579 return 0; 2580 /* If return value is ignored, transform mempcpy into memcpy. */ 2581 else if (target == const0_rtx) 2582 { 2583 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 2584 2585 if (!fn) 2586 return 0; 2587 2588 return expand_expr (build_function_call_expr (fn, arglist), 2589 target, mode, EXPAND_NORMAL); 2590 } 2591 else 2592 { 2593 tree dest = TREE_VALUE (arglist); 2594 tree src = TREE_VALUE (TREE_CHAIN (arglist)); 2595 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 2596 const char *src_str; 2597 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 2598 unsigned int dest_align 2599 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 2600 rtx dest_mem, src_mem, len_rtx; 2601 2602 /* If DEST is not a pointer type, call the normal function. */ 2603 if (dest_align == 0) 2604 return 0; 2605 2606 /* If SRC and DEST are the same (and not volatile), do nothing. */ 2607 if (operand_equal_p (src, dest, 0)) 2608 { 2609 tree expr; 2610 2611 if (endp == 0) 2612 { 2613 /* Evaluate and ignore LEN in case it has side-effects. */ 2614 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL); 2615 return expand_expr (dest, target, mode, EXPAND_NORMAL); 2616 } 2617 2618 if (endp == 2) 2619 len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest, 2620 integer_one_node)); 2621 len = convert (TREE_TYPE (dest), len); 2622 expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len)); 2623 return expand_expr (expr, target, mode, EXPAND_NORMAL); 2624 } 2625 2626 /* If LEN is not constant, call the normal function. */ 2627 if (! host_integerp (len, 1)) 2628 return 0; 2629 2630 /* If the LEN parameter is zero, return DEST. */ 2631 if (tree_low_cst (len, 1) == 0) 2632 { 2633 /* Evaluate and ignore SRC in case it has side-effects. */ 2634 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL); 2635 return expand_expr (dest, target, mode, EXPAND_NORMAL); 2636 } 2637 2638 /* If either SRC is not a pointer type, don't do this 2639 operation in-line. */ 2640 if (src_align == 0) 2641 return 0; 2642 2643 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); 2644 src_str = c_getstr (src); 2645 2646 /* If SRC is a string constant and block move would be done 2647 by pieces, we can avoid loading the string from memory 2648 and only stored the computed constants. */ 2649 if (src_str 2650 && GET_CODE (len_rtx) == CONST_INT 2651 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1 2652 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str, 2653 (void *) src_str, dest_align)) 2654 { 2655 dest_mem = get_memory_rtx (dest); 2656 set_mem_align (dest_mem, dest_align); 2657 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx), 2658 builtin_memcpy_read_str, 2659 (void *) src_str, dest_align, endp); 2660 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 2661 dest_mem = convert_memory_address (ptr_mode, dest_mem); 2662 return dest_mem; 2663 } 2664 2665 if (GET_CODE (len_rtx) == CONST_INT 2666 && can_move_by_pieces (INTVAL (len_rtx), 2667 MIN (dest_align, src_align))) 2668 { 2669 dest_mem = get_memory_rtx (dest); 2670 set_mem_align (dest_mem, dest_align); 2671 src_mem = get_memory_rtx (src); 2672 set_mem_align (src_mem, src_align); 2673 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx), 2674 MIN (dest_align, src_align), endp); 2675 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 2676 dest_mem = convert_memory_address (ptr_mode, dest_mem); 2677 return dest_mem; 2678 } 2679 2680 return 0; 2681 } 2682} 2683 2684/* Expand expression EXP, which is a call to the memmove builtin. Return 0 2685 if we failed the caller should emit a normal call. */ 2686 2687static rtx 2688expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode) 2689{ 2690 if (!validate_arglist (arglist, 2691 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2692 return 0; 2693 else 2694 { 2695 tree dest = TREE_VALUE (arglist); 2696 tree src = TREE_VALUE (TREE_CHAIN (arglist)); 2697 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 2698 2699 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); 2700 unsigned int dest_align 2701 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 2702 2703 /* If DEST is not a pointer type, call the normal function. */ 2704 if (dest_align == 0) 2705 return 0; 2706 2707 /* If the LEN parameter is zero, return DEST. */ 2708 if (integer_zerop (len)) 2709 { 2710 /* Evaluate and ignore SRC in case it has side-effects. */ 2711 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL); 2712 return expand_expr (dest, target, mode, EXPAND_NORMAL); 2713 } 2714 2715 /* If SRC and DEST are the same (and not volatile), return DEST. */ 2716 if (operand_equal_p (src, dest, 0)) 2717 { 2718 /* Evaluate and ignore LEN in case it has side-effects. */ 2719 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL); 2720 return expand_expr (dest, target, mode, EXPAND_NORMAL); 2721 } 2722 2723 /* If either SRC is not a pointer type, don't do this 2724 operation in-line. */ 2725 if (src_align == 0) 2726 return 0; 2727 2728 /* If src is categorized for a readonly section we can use 2729 normal memcpy. */ 2730 if (readonly_data_expr (src)) 2731 { 2732 tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 2733 if (!fn) 2734 return 0; 2735 return expand_expr (build_function_call_expr (fn, arglist), 2736 target, mode, EXPAND_NORMAL); 2737 } 2738 2739 /* Otherwise, call the normal function. */ 2740 return 0; 2741 } 2742} 2743 2744/* Expand expression EXP, which is a call to the bcopy builtin. Return 0 2745 if we failed the caller should emit a normal call. */ 2746 2747static rtx 2748expand_builtin_bcopy (tree arglist) 2749{ 2750 tree src, dest, size, newarglist; 2751 2752 if (!validate_arglist (arglist, 2753 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2754 return NULL_RTX; 2755 2756 src = TREE_VALUE (arglist); 2757 dest = TREE_VALUE (TREE_CHAIN (arglist)); 2758 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 2759 2760 /* New argument list transforming bcopy(ptr x, ptr y, int z) to 2761 memmove(ptr y, ptr x, size_t z). This is done this way 2762 so that if it isn't expanded inline, we fallback to 2763 calling bcopy instead of memmove. */ 2764 2765 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size)); 2766 newarglist = tree_cons (NULL_TREE, src, newarglist); 2767 newarglist = tree_cons (NULL_TREE, dest, newarglist); 2768 2769 return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode); 2770} 2771 2772/* Expand expression EXP, which is a call to the strcpy builtin. Return 0 2773 if we failed the caller should emit a normal call, otherwise try to get 2774 the result in TARGET, if convenient (and in mode MODE if that's 2775 convenient). */ 2776 2777static rtx 2778expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode) 2779{ 2780 tree fn, len, src, dst; 2781 2782 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 2783 return 0; 2784 2785 src = TREE_VALUE (TREE_CHAIN (arglist)); 2786 dst = TREE_VALUE (arglist); 2787 2788 /* If SRC and DST are equal (and not volatile), return DST. */ 2789 if (operand_equal_p (src, dst, 0)) 2790 return expand_expr (dst, target, mode, EXPAND_NORMAL); 2791 2792 fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 2793 if (!fn) 2794 return 0; 2795 2796 len = c_strlen (src, 1); 2797 if (len == 0 || TREE_SIDE_EFFECTS (len)) 2798 return 0; 2799 2800 len = size_binop (PLUS_EXPR, len, ssize_int (1)); 2801 arglist = build_tree_list (NULL_TREE, len); 2802 arglist = tree_cons (NULL_TREE, src, arglist); 2803 arglist = tree_cons (NULL_TREE, dst, arglist); 2804 return expand_expr (build_function_call_expr (fn, arglist), 2805 target, mode, EXPAND_NORMAL); 2806} 2807 2808/* Expand a call to the stpcpy builtin, with arguments in ARGLIST. 2809 Return 0 if we failed the caller should emit a normal call, 2810 otherwise try to get the result in TARGET, if convenient (and in 2811 mode MODE if that's convenient). */ 2812 2813static rtx 2814expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode) 2815{ 2816 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 2817 return 0; 2818 else 2819 { 2820 tree dst, src, len; 2821 2822 /* If return value is ignored, transform stpcpy into strcpy. */ 2823 if (target == const0_rtx) 2824 { 2825 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 2826 if (!fn) 2827 return 0; 2828 2829 return expand_expr (build_function_call_expr (fn, arglist), 2830 target, mode, EXPAND_NORMAL); 2831 } 2832 2833 /* Ensure we get an actual string whose length can be evaluated at 2834 compile-time, not an expression containing a string. This is 2835 because the latter will potentially produce pessimized code 2836 when used to produce the return value. */ 2837 src = TREE_VALUE (TREE_CHAIN (arglist)); 2838 if (! c_getstr (src) || ! (len = c_strlen (src, 0))) 2839 return 0; 2840 2841 dst = TREE_VALUE (arglist); 2842 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1))); 2843 arglist = build_tree_list (NULL_TREE, len); 2844 arglist = tree_cons (NULL_TREE, src, arglist); 2845 arglist = tree_cons (NULL_TREE, dst, arglist); 2846 return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2); 2847 } 2848} 2849 2850/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 2851 bytes from constant string DATA + OFFSET and return it as target 2852 constant. */ 2853 2854static rtx 2855builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset, 2856 enum machine_mode mode) 2857{ 2858 const char *str = (const char *) data; 2859 2860 if ((unsigned HOST_WIDE_INT) offset > strlen (str)) 2861 return const0_rtx; 2862 2863 return c_readstr (str + offset, mode); 2864} 2865 2866/* Expand expression EXP, which is a call to the strncpy builtin. Return 0 2867 if we failed the caller should emit a normal call. */ 2868 2869static rtx 2870expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode) 2871{ 2872 if (!validate_arglist (arglist, 2873 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2874 return 0; 2875 else 2876 { 2877 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1); 2878 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 2879 tree fn; 2880 2881 /* We must be passed a constant len parameter. */ 2882 if (TREE_CODE (len) != INTEGER_CST) 2883 return 0; 2884 2885 /* If the len parameter is zero, return the dst parameter. */ 2886 if (integer_zerop (len)) 2887 { 2888 /* Evaluate and ignore the src argument in case it has 2889 side-effects. */ 2890 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx, 2891 VOIDmode, EXPAND_NORMAL); 2892 /* Return the dst parameter. */ 2893 return expand_expr (TREE_VALUE (arglist), target, mode, 2894 EXPAND_NORMAL); 2895 } 2896 2897 /* Now, we must be passed a constant src ptr parameter. */ 2898 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST) 2899 return 0; 2900 2901 slen = size_binop (PLUS_EXPR, slen, ssize_int (1)); 2902 2903 /* We're required to pad with trailing zeros if the requested 2904 len is greater than strlen(s2)+1. In that case try to 2905 use store_by_pieces, if it fails, punt. */ 2906 if (tree_int_cst_lt (slen, len)) 2907 { 2908 tree dest = TREE_VALUE (arglist); 2909 unsigned int dest_align 2910 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 2911 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist))); 2912 rtx dest_mem; 2913 2914 if (!p || dest_align == 0 || !host_integerp (len, 1) 2915 || !can_store_by_pieces (tree_low_cst (len, 1), 2916 builtin_strncpy_read_str, 2917 (void *) p, dest_align)) 2918 return 0; 2919 2920 dest_mem = get_memory_rtx (dest); 2921 store_by_pieces (dest_mem, tree_low_cst (len, 1), 2922 builtin_strncpy_read_str, 2923 (void *) p, dest_align, 0); 2924 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 2925 dest_mem = convert_memory_address (ptr_mode, dest_mem); 2926 return dest_mem; 2927 } 2928 2929 /* OK transform into builtin memcpy. */ 2930 fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; 2931 if (!fn) 2932 return 0; 2933 return expand_expr (build_function_call_expr (fn, arglist), 2934 target, mode, EXPAND_NORMAL); 2935 } 2936} 2937 2938/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) 2939 bytes from constant string DATA + OFFSET and return it as target 2940 constant. */ 2941 2942static rtx 2943builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED, 2944 enum machine_mode mode) 2945{ 2946 const char *c = (const char *) data; 2947 char *p = alloca (GET_MODE_SIZE (mode)); 2948 2949 memset (p, *c, GET_MODE_SIZE (mode)); 2950 2951 return c_readstr (p, mode); 2952} 2953 2954/* Callback routine for store_by_pieces. Return the RTL of a register 2955 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned 2956 char value given in the RTL register data. For example, if mode is 2957 4 bytes wide, return the RTL for 0x01010101*data. */ 2958 2959static rtx 2960builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED, 2961 enum machine_mode mode) 2962{ 2963 rtx target, coeff; 2964 size_t size; 2965 char *p; 2966 2967 size = GET_MODE_SIZE (mode); 2968 if (size == 1) 2969 return (rtx) data; 2970 2971 p = alloca (size); 2972 memset (p, 1, size); 2973 coeff = c_readstr (p, mode); 2974 2975 target = convert_to_mode (mode, (rtx) data, 1); 2976 target = expand_mult (mode, target, coeff, NULL_RTX, 1); 2977 return force_reg (mode, target); 2978} 2979 2980/* Expand expression EXP, which is a call to the memset builtin. Return 0 2981 if we failed the caller should emit a normal call, otherwise try to get 2982 the result in TARGET, if convenient (and in mode MODE if that's 2983 convenient). */ 2984 2985static rtx 2986expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode) 2987{ 2988 if (!validate_arglist (arglist, 2989 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) 2990 return 0; 2991 else 2992 { 2993 tree dest = TREE_VALUE (arglist); 2994 tree val = TREE_VALUE (TREE_CHAIN (arglist)); 2995 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 2996 char c; 2997 2998 unsigned int dest_align 2999 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); 3000 rtx dest_mem, dest_addr, len_rtx; 3001 3002 /* If DEST is not a pointer type, don't do this 3003 operation in-line. */ 3004 if (dest_align == 0) 3005 return 0; 3006 3007 /* If the LEN parameter is zero, return DEST. */ 3008 if (integer_zerop (len)) 3009 { 3010 /* Evaluate and ignore VAL in case it has side-effects. */ 3011 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL); 3012 return expand_expr (dest, target, mode, EXPAND_NORMAL); 3013 } 3014 3015 if (TREE_CODE (val) != INTEGER_CST) 3016 { 3017 rtx val_rtx; 3018 3019 if (!host_integerp (len, 1)) 3020 return 0; 3021 3022 if (optimize_size && tree_low_cst (len, 1) > 1) 3023 return 0; 3024 3025 /* Assume that we can memset by pieces if we can store the 3026 * the coefficients by pieces (in the required modes). 3027 * We can't pass builtin_memset_gen_str as that emits RTL. */ 3028 c = 1; 3029 if (!can_store_by_pieces (tree_low_cst (len, 1), 3030 builtin_memset_read_str, 3031 &c, dest_align)) 3032 return 0; 3033 3034 val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val)); 3035 val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0); 3036 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node), 3037 val_rtx); 3038 dest_mem = get_memory_rtx (dest); 3039 store_by_pieces (dest_mem, tree_low_cst (len, 1), 3040 builtin_memset_gen_str, 3041 val_rtx, dest_align, 0); 3042 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3043 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3044 return dest_mem; 3045 } 3046 3047 if (target_char_cast (val, &c)) 3048 return 0; 3049 3050 if (c) 3051 { 3052 if (!host_integerp (len, 1)) 3053 return 0; 3054 if (!can_store_by_pieces (tree_low_cst (len, 1), 3055 builtin_memset_read_str, &c, 3056 dest_align)) 3057 return 0; 3058 3059 dest_mem = get_memory_rtx (dest); 3060 store_by_pieces (dest_mem, tree_low_cst (len, 1), 3061 builtin_memset_read_str, 3062 &c, dest_align, 0); 3063 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3064 dest_mem = convert_memory_address (ptr_mode, dest_mem); 3065 return dest_mem; 3066 } 3067 3068 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); 3069 3070 dest_mem = get_memory_rtx (dest); 3071 set_mem_align (dest_mem, dest_align); 3072 dest_addr = clear_storage (dest_mem, len_rtx); 3073 3074 if (dest_addr == 0) 3075 { 3076 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); 3077 dest_addr = convert_memory_address (ptr_mode, dest_addr); 3078 } 3079 3080 return dest_addr; 3081 } 3082} 3083 3084/* Expand expression EXP, which is a call to the bzero builtin. Return 0 3085 if we failed the caller should emit a normal call. */ 3086 3087static rtx 3088expand_builtin_bzero (tree arglist) 3089{ 3090 tree dest, size, newarglist; 3091 3092 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3093 return NULL_RTX; 3094 3095 dest = TREE_VALUE (arglist); 3096 size = TREE_VALUE (TREE_CHAIN (arglist)); 3097 3098 /* New argument list transforming bzero(ptr x, int y) to 3099 memset(ptr x, int 0, size_t y). This is done this way 3100 so that if it isn't expanded inline, we fallback to 3101 calling bzero instead of memset. */ 3102 3103 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size)); 3104 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist); 3105 newarglist = tree_cons (NULL_TREE, dest, newarglist); 3106 3107 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode); 3108} 3109 3110/* Expand expression EXP, which is a call to the memcmp built-in function. 3111 ARGLIST is the argument list for this call. Return 0 if we failed and the 3112 caller should emit a normal call, otherwise try to get the result in 3113 TARGET, if convenient (and in mode MODE, if that's convenient). */ 3114 3115static rtx 3116expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target, 3117 enum machine_mode mode) 3118{ 3119 tree arg1, arg2, len; 3120 const char *p1, *p2; 3121 3122 if (!validate_arglist (arglist, 3123 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3124 return 0; 3125 3126 arg1 = TREE_VALUE (arglist); 3127 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 3128 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 3129 3130 /* If the len parameter is zero, return zero. */ 3131 if (integer_zerop (len)) 3132 { 3133 /* Evaluate and ignore arg1 and arg2 in case they have 3134 side-effects. */ 3135 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL); 3136 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL); 3137 return const0_rtx; 3138 } 3139 3140 /* If both arguments are equal (and not volatile), return zero. */ 3141 if (operand_equal_p (arg1, arg2, 0)) 3142 { 3143 /* Evaluate and ignore len in case it has side-effects. */ 3144 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL); 3145 return const0_rtx; 3146 } 3147 3148 p1 = c_getstr (arg1); 3149 p2 = c_getstr (arg2); 3150 3151 /* If all arguments are constant, and the value of len is not greater 3152 than the lengths of arg1 and arg2, evaluate at compile-time. */ 3153 if (host_integerp (len, 1) && p1 && p2 3154 && compare_tree_int (len, strlen (p1) + 1) <= 0 3155 && compare_tree_int (len, strlen (p2) + 1) <= 0) 3156 { 3157 const int r = memcmp (p1, p2, tree_low_cst (len, 1)); 3158 3159 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx)); 3160 } 3161 3162 /* If len parameter is one, return an expression corresponding to 3163 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ 3164 if (integer_onep (len)) 3165 { 3166 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 3167 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node); 3168 tree ind1 = 3169 fold (build1 (CONVERT_EXPR, integer_type_node, 3170 build1 (INDIRECT_REF, cst_uchar_node, 3171 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1)))); 3172 tree ind2 = 3173 fold (build1 (CONVERT_EXPR, integer_type_node, 3174 build1 (INDIRECT_REF, cst_uchar_node, 3175 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2)))); 3176 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2)); 3177 return expand_expr (result, target, mode, EXPAND_NORMAL); 3178 } 3179 3180#if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi 3181 { 3182 rtx arg1_rtx, arg2_rtx, arg3_rtx; 3183 rtx result; 3184 rtx insn; 3185 3186 int arg1_align 3187 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3188 int arg2_align 3189 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3190 enum machine_mode insn_mode; 3191 3192#ifdef HAVE_cmpmemsi 3193 if (HAVE_cmpmemsi) 3194 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode; 3195 else 3196#endif 3197#ifdef HAVE_cmpstrsi 3198 if (HAVE_cmpstrsi) 3199 insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode; 3200 else 3201#endif 3202 return 0; 3203 3204 /* If we don't have POINTER_TYPE, call the function. */ 3205 if (arg1_align == 0 || arg2_align == 0) 3206 return 0; 3207 3208 /* Make a place to write the result of the instruction. */ 3209 result = target; 3210 if (! (result != 0 3211 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode 3212 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 3213 result = gen_reg_rtx (insn_mode); 3214 3215 arg1_rtx = get_memory_rtx (arg1); 3216 arg2_rtx = get_memory_rtx (arg2); 3217 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); 3218#ifdef HAVE_cmpmemsi 3219 if (HAVE_cmpmemsi) 3220 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 3221 GEN_INT (MIN (arg1_align, arg2_align))); 3222 else 3223#endif 3224#ifdef HAVE_cmpstrsi 3225 if (HAVE_cmpstrsi) 3226 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 3227 GEN_INT (MIN (arg1_align, arg2_align))); 3228 else 3229#endif 3230 abort (); 3231 3232 if (insn) 3233 emit_insn (insn); 3234 else 3235 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK, 3236 TYPE_MODE (integer_type_node), 3, 3237 XEXP (arg1_rtx, 0), Pmode, 3238 XEXP (arg2_rtx, 0), Pmode, 3239 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx, 3240 TREE_UNSIGNED (sizetype)), 3241 TYPE_MODE (sizetype)); 3242 3243 /* Return the value in the proper mode for this function. */ 3244 mode = TYPE_MODE (TREE_TYPE (exp)); 3245 if (GET_MODE (result) == mode) 3246 return result; 3247 else if (target != 0) 3248 { 3249 convert_move (target, result, 0); 3250 return target; 3251 } 3252 else 3253 return convert_to_mode (mode, result, 0); 3254 } 3255#endif 3256 3257 return 0; 3258} 3259 3260/* Expand expression EXP, which is a call to the strcmp builtin. Return 0 3261 if we failed the caller should emit a normal call, otherwise try to get 3262 the result in TARGET, if convenient. */ 3263 3264static rtx 3265expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode) 3266{ 3267 tree arglist = TREE_OPERAND (exp, 1); 3268 tree arg1, arg2; 3269 const char *p1, *p2; 3270 3271 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3272 return 0; 3273 3274 arg1 = TREE_VALUE (arglist); 3275 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 3276 3277 /* If both arguments are equal (and not volatile), return zero. */ 3278 if (operand_equal_p (arg1, arg2, 0)) 3279 return const0_rtx; 3280 3281 p1 = c_getstr (arg1); 3282 p2 = c_getstr (arg2); 3283 3284 if (p1 && p2) 3285 { 3286 const int i = strcmp (p1, p2); 3287 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx)); 3288 } 3289 3290 /* If either arg is "", return an expression corresponding to 3291 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ 3292 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')) 3293 { 3294 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 3295 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node); 3296 tree ind1 = 3297 fold (build1 (CONVERT_EXPR, integer_type_node, 3298 build1 (INDIRECT_REF, cst_uchar_node, 3299 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1)))); 3300 tree ind2 = 3301 fold (build1 (CONVERT_EXPR, integer_type_node, 3302 build1 (INDIRECT_REF, cst_uchar_node, 3303 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2)))); 3304 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2)); 3305 return expand_expr (result, target, mode, EXPAND_NORMAL); 3306 } 3307 3308#ifdef HAVE_cmpstrsi 3309 if (HAVE_cmpstrsi) 3310 { 3311 tree len, len1, len2; 3312 rtx arg1_rtx, arg2_rtx, arg3_rtx; 3313 rtx result, insn; 3314 tree fndecl; 3315 3316 int arg1_align 3317 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3318 int arg2_align 3319 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3320 enum machine_mode insn_mode 3321 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode; 3322 3323 len1 = c_strlen (arg1, 1); 3324 len2 = c_strlen (arg2, 1); 3325 3326 if (len1) 3327 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1); 3328 if (len2) 3329 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2); 3330 3331 /* If we don't have a constant length for the first, use the length 3332 of the second, if we know it. We don't require a constant for 3333 this case; some cost analysis could be done if both are available 3334 but neither is constant. For now, assume they're equally cheap, 3335 unless one has side effects. If both strings have constant lengths, 3336 use the smaller. */ 3337 3338 if (!len1) 3339 len = len2; 3340 else if (!len2) 3341 len = len1; 3342 else if (TREE_SIDE_EFFECTS (len1)) 3343 len = len2; 3344 else if (TREE_SIDE_EFFECTS (len2)) 3345 len = len1; 3346 else if (TREE_CODE (len1) != INTEGER_CST) 3347 len = len2; 3348 else if (TREE_CODE (len2) != INTEGER_CST) 3349 len = len1; 3350 else if (tree_int_cst_lt (len1, len2)) 3351 len = len1; 3352 else 3353 len = len2; 3354 3355 /* If both arguments have side effects, we cannot optimize. */ 3356 if (!len || TREE_SIDE_EFFECTS (len)) 3357 return 0; 3358 3359 /* If we don't have POINTER_TYPE, call the function. */ 3360 if (arg1_align == 0 || arg2_align == 0) 3361 return 0; 3362 3363 /* Make a place to write the result of the instruction. */ 3364 result = target; 3365 if (! (result != 0 3366 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode 3367 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 3368 result = gen_reg_rtx (insn_mode); 3369 3370 /* Stabilize the arguments in case gen_cmpstrsi fails. */ 3371 arg1 = save_expr (arg1); 3372 arg2 = save_expr (arg2); 3373 3374 arg1_rtx = get_memory_rtx (arg1); 3375 arg2_rtx = get_memory_rtx (arg2); 3376 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); 3377 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 3378 GEN_INT (MIN (arg1_align, arg2_align))); 3379 if (insn) 3380 { 3381 emit_insn (insn); 3382 3383 /* Return the value in the proper mode for this function. */ 3384 mode = TYPE_MODE (TREE_TYPE (exp)); 3385 if (GET_MODE (result) == mode) 3386 return result; 3387 if (target == 0) 3388 return convert_to_mode (mode, result, 0); 3389 convert_move (target, result, 0); 3390 return target; 3391 } 3392 3393 /* Expand the library call ourselves using a stabilized argument 3394 list to avoid re-evaluating the function's arguments twice. */ 3395 arglist = build_tree_list (NULL_TREE, arg2); 3396 arglist = tree_cons (NULL_TREE, arg1, arglist); 3397 fndecl = get_callee_fndecl (exp); 3398 exp = build_function_call_expr (fndecl, arglist); 3399 return expand_call (exp, target, target == const0_rtx); 3400 } 3401#endif 3402 return 0; 3403} 3404 3405/* Expand expression EXP, which is a call to the strncmp builtin. Return 0 3406 if we failed the caller should emit a normal call, otherwise try to get 3407 the result in TARGET, if convenient. */ 3408 3409static rtx 3410expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode) 3411{ 3412 tree arglist = TREE_OPERAND (exp, 1); 3413 tree arg1, arg2, arg3; 3414 const char *p1, *p2; 3415 3416 if (!validate_arglist (arglist, 3417 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3418 return 0; 3419 3420 arg1 = TREE_VALUE (arglist); 3421 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 3422 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 3423 3424 /* If the len parameter is zero, return zero. */ 3425 if (integer_zerop (arg3)) 3426 { 3427 /* Evaluate and ignore arg1 and arg2 in case they have 3428 side-effects. */ 3429 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL); 3430 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL); 3431 return const0_rtx; 3432 } 3433 3434 /* If arg1 and arg2 are equal (and not volatile), return zero. */ 3435 if (operand_equal_p (arg1, arg2, 0)) 3436 { 3437 /* Evaluate and ignore arg3 in case it has side-effects. */ 3438 expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL); 3439 return const0_rtx; 3440 } 3441 3442 p1 = c_getstr (arg1); 3443 p2 = c_getstr (arg2); 3444 3445 /* If all arguments are constant, evaluate at compile-time. */ 3446 if (host_integerp (arg3, 1) && p1 && p2) 3447 { 3448 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1)); 3449 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx)); 3450 } 3451 3452 /* If len == 1 or (either string parameter is "" and (len >= 1)), 3453 return (*(const u_char*)arg1 - *(const u_char*)arg2). */ 3454 if (host_integerp (arg3, 1) 3455 && (tree_low_cst (arg3, 1) == 1 3456 || (tree_low_cst (arg3, 1) > 1 3457 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))))) 3458 { 3459 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0); 3460 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node); 3461 tree ind1 = 3462 fold (build1 (CONVERT_EXPR, integer_type_node, 3463 build1 (INDIRECT_REF, cst_uchar_node, 3464 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1)))); 3465 tree ind2 = 3466 fold (build1 (CONVERT_EXPR, integer_type_node, 3467 build1 (INDIRECT_REF, cst_uchar_node, 3468 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2)))); 3469 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2)); 3470 return expand_expr (result, target, mode, EXPAND_NORMAL); 3471 } 3472 3473 /* If c_strlen can determine an expression for one of the string 3474 lengths, and it doesn't have side effects, then emit cmpstrsi 3475 using length MIN(strlen(string)+1, arg3). */ 3476#ifdef HAVE_cmpstrsi 3477 if (HAVE_cmpstrsi) 3478 { 3479 tree len, len1, len2; 3480 rtx arg1_rtx, arg2_rtx, arg3_rtx; 3481 rtx result, insn; 3482 tree fndecl; 3483 3484 int arg1_align 3485 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3486 int arg2_align 3487 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT; 3488 enum machine_mode insn_mode 3489 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode; 3490 3491 len1 = c_strlen (arg1, 1); 3492 len2 = c_strlen (arg2, 1); 3493 3494 if (len1) 3495 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1); 3496 if (len2) 3497 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2); 3498 3499 /* If we don't have a constant length for the first, use the length 3500 of the second, if we know it. We don't require a constant for 3501 this case; some cost analysis could be done if both are available 3502 but neither is constant. For now, assume they're equally cheap, 3503 unless one has side effects. If both strings have constant lengths, 3504 use the smaller. */ 3505 3506 if (!len1) 3507 len = len2; 3508 else if (!len2) 3509 len = len1; 3510 else if (TREE_SIDE_EFFECTS (len1)) 3511 len = len2; 3512 else if (TREE_SIDE_EFFECTS (len2)) 3513 len = len1; 3514 else if (TREE_CODE (len1) != INTEGER_CST) 3515 len = len2; 3516 else if (TREE_CODE (len2) != INTEGER_CST) 3517 len = len1; 3518 else if (tree_int_cst_lt (len1, len2)) 3519 len = len1; 3520 else 3521 len = len2; 3522 3523 /* If both arguments have side effects, we cannot optimize. */ 3524 if (!len || TREE_SIDE_EFFECTS (len)) 3525 return 0; 3526 3527 /* The actual new length parameter is MIN(len,arg3). */ 3528 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3)); 3529 3530 /* If we don't have POINTER_TYPE, call the function. */ 3531 if (arg1_align == 0 || arg2_align == 0) 3532 return 0; 3533 3534 /* Make a place to write the result of the instruction. */ 3535 result = target; 3536 if (! (result != 0 3537 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode 3538 && REGNO (result) >= FIRST_PSEUDO_REGISTER)) 3539 result = gen_reg_rtx (insn_mode); 3540 3541 /* Stabilize the arguments in case gen_cmpstrsi fails. */ 3542 arg1 = save_expr (arg1); 3543 arg2 = save_expr (arg2); 3544 len = save_expr (len); 3545 3546 arg1_rtx = get_memory_rtx (arg1); 3547 arg2_rtx = get_memory_rtx (arg2); 3548 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); 3549 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx, 3550 GEN_INT (MIN (arg1_align, arg2_align))); 3551 if (insn) 3552 { 3553 emit_insn (insn); 3554 3555 /* Return the value in the proper mode for this function. */ 3556 mode = TYPE_MODE (TREE_TYPE (exp)); 3557 if (GET_MODE (result) == mode) 3558 return result; 3559 if (target == 0) 3560 return convert_to_mode (mode, result, 0); 3561 convert_move (target, result, 0); 3562 return target; 3563 } 3564 3565 /* Expand the library call ourselves using a stabilized argument 3566 list to avoid re-evaluating the function's arguments twice. */ 3567 arglist = build_tree_list (NULL_TREE, len); 3568 arglist = tree_cons (NULL_TREE, arg2, arglist); 3569 arglist = tree_cons (NULL_TREE, arg1, arglist); 3570 fndecl = get_callee_fndecl (exp); 3571 exp = build_function_call_expr (fndecl, arglist); 3572 return expand_call (exp, target, target == const0_rtx); 3573 } 3574#endif 3575 return 0; 3576} 3577 3578/* Expand expression EXP, which is a call to the strcat builtin. 3579 Return 0 if we failed the caller should emit a normal call, 3580 otherwise try to get the result in TARGET, if convenient. */ 3581 3582static rtx 3583expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode) 3584{ 3585 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3586 return 0; 3587 else 3588 { 3589 tree dst = TREE_VALUE (arglist), 3590 src = TREE_VALUE (TREE_CHAIN (arglist)); 3591 const char *p = c_getstr (src); 3592 3593 if (p) 3594 { 3595 /* If the string length is zero, return the dst parameter. */ 3596 if (*p == '\0') 3597 return expand_expr (dst, target, mode, EXPAND_NORMAL); 3598 else if (!optimize_size) 3599 { 3600 /* Otherwise if !optimize_size, see if we can store by 3601 pieces into (dst + strlen(dst)). */ 3602 tree newdst, arglist, 3603 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN]; 3604 3605 /* This is the length argument. */ 3606 arglist = build_tree_list (NULL_TREE, 3607 fold (size_binop (PLUS_EXPR, 3608 c_strlen (src, 0), 3609 ssize_int (1)))); 3610 /* Prepend src argument. */ 3611 arglist = tree_cons (NULL_TREE, src, arglist); 3612 3613 /* We're going to use dst more than once. */ 3614 dst = save_expr (dst); 3615 3616 /* Create strlen (dst). */ 3617 newdst = 3618 fold (build_function_call_expr (strlen_fn, 3619 build_tree_list (NULL_TREE, 3620 dst))); 3621 /* Create (dst + strlen (dst)). */ 3622 newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst)); 3623 3624 /* Prepend the new dst argument. */ 3625 arglist = tree_cons (NULL_TREE, newdst, arglist); 3626 3627 /* We don't want to get turned into a memcpy if the 3628 target is const0_rtx, i.e. when the return value 3629 isn't used. That would produce pessimized code so 3630 pass in a target of zero, it should never actually be 3631 used. If this was successful return the original 3632 dst, not the result of mempcpy. */ 3633 if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0)) 3634 return expand_expr (dst, target, mode, EXPAND_NORMAL); 3635 else 3636 return 0; 3637 } 3638 } 3639 3640 return 0; 3641 } 3642} 3643 3644/* Expand expression EXP, which is a call to the strncat builtin. 3645 Return 0 if we failed the caller should emit a normal call, 3646 otherwise try to get the result in TARGET, if convenient. */ 3647 3648static rtx 3649expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode) 3650{ 3651 if (!validate_arglist (arglist, 3652 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 3653 return 0; 3654 else 3655 { 3656 tree dst = TREE_VALUE (arglist), 3657 src = TREE_VALUE (TREE_CHAIN (arglist)), 3658 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 3659 const char *p = c_getstr (src); 3660 3661 /* If the requested length is zero, or the src parameter string 3662 length is zero, return the dst parameter. */ 3663 if (integer_zerop (len) || (p && *p == '\0')) 3664 { 3665 /* Evaluate and ignore the src and len parameters in case 3666 they have side-effects. */ 3667 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL); 3668 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL); 3669 return expand_expr (dst, target, mode, EXPAND_NORMAL); 3670 } 3671 3672 /* If the requested len is greater than or equal to the string 3673 length, call strcat. */ 3674 if (TREE_CODE (len) == INTEGER_CST && p 3675 && compare_tree_int (len, strlen (p)) >= 0) 3676 { 3677 tree newarglist 3678 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src)); 3679 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT]; 3680 3681 /* If the replacement _DECL isn't initialized, don't do the 3682 transformation. */ 3683 if (!fn) 3684 return 0; 3685 3686 return expand_expr (build_function_call_expr (fn, newarglist), 3687 target, mode, EXPAND_NORMAL); 3688 } 3689 return 0; 3690 } 3691} 3692 3693/* Expand expression EXP, which is a call to the strspn builtin. 3694 Return 0 if we failed the caller should emit a normal call, 3695 otherwise try to get the result in TARGET, if convenient. */ 3696 3697static rtx 3698expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode) 3699{ 3700 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3701 return 0; 3702 else 3703 { 3704 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 3705 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); 3706 3707 /* If both arguments are constants, evaluate at compile-time. */ 3708 if (p1 && p2) 3709 { 3710 const size_t r = strspn (p1, p2); 3711 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL); 3712 } 3713 3714 /* If either argument is "", return 0. */ 3715 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')) 3716 { 3717 /* Evaluate and ignore both arguments in case either one has 3718 side-effects. */ 3719 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL); 3720 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL); 3721 return const0_rtx; 3722 } 3723 return 0; 3724 } 3725} 3726 3727/* Expand expression EXP, which is a call to the strcspn builtin. 3728 Return 0 if we failed the caller should emit a normal call, 3729 otherwise try to get the result in TARGET, if convenient. */ 3730 3731static rtx 3732expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode) 3733{ 3734 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 3735 return 0; 3736 else 3737 { 3738 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist)); 3739 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); 3740 3741 /* If both arguments are constants, evaluate at compile-time. */ 3742 if (p1 && p2) 3743 { 3744 const size_t r = strcspn (p1, p2); 3745 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL); 3746 } 3747 3748 /* If the first argument is "", return 0. */ 3749 if (p1 && *p1 == '\0') 3750 { 3751 /* Evaluate and ignore argument s2 in case it has 3752 side-effects. */ 3753 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL); 3754 return const0_rtx; 3755 } 3756 3757 /* If the second argument is "", return __builtin_strlen(s1). */ 3758 if (p2 && *p2 == '\0') 3759 { 3760 tree newarglist = build_tree_list (NULL_TREE, s1), 3761 fn = implicit_built_in_decls[BUILT_IN_STRLEN]; 3762 3763 /* If the replacement _DECL isn't initialized, don't do the 3764 transformation. */ 3765 if (!fn) 3766 return 0; 3767 3768 return expand_expr (build_function_call_expr (fn, newarglist), 3769 target, mode, EXPAND_NORMAL); 3770 } 3771 return 0; 3772 } 3773} 3774 3775/* Expand a call to __builtin_saveregs, generating the result in TARGET, 3776 if that's convenient. */ 3777 3778rtx 3779expand_builtin_saveregs (void) 3780{ 3781 rtx val, seq; 3782 3783 /* Don't do __builtin_saveregs more than once in a function. 3784 Save the result of the first call and reuse it. */ 3785 if (saveregs_value != 0) 3786 return saveregs_value; 3787 3788 /* When this function is called, it means that registers must be 3789 saved on entry to this function. So we migrate the call to the 3790 first insn of this function. */ 3791 3792 start_sequence (); 3793 3794 /* Do whatever the machine needs done in this case. */ 3795 val = targetm.calls.expand_builtin_saveregs (); 3796 3797 seq = get_insns (); 3798 end_sequence (); 3799 3800 saveregs_value = val; 3801 3802 /* Put the insns after the NOTE that starts the function. If this 3803 is inside a start_sequence, make the outer-level insn chain current, so 3804 the code is placed at the start of the function. */ 3805 push_topmost_sequence (); 3806 emit_insn_after (seq, get_insns ()); 3807 pop_topmost_sequence (); 3808 3809 return val; 3810} 3811 3812/* __builtin_args_info (N) returns word N of the arg space info 3813 for the current function. The number and meanings of words 3814 is controlled by the definition of CUMULATIVE_ARGS. */ 3815 3816static rtx 3817expand_builtin_args_info (tree arglist) 3818{ 3819 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int); 3820 int *word_ptr = (int *) ¤t_function_args_info; 3821 3822 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0) 3823 abort (); 3824 3825 if (arglist != 0) 3826 { 3827 if (!host_integerp (TREE_VALUE (arglist), 0)) 3828 error ("argument of `__builtin_args_info' must be constant"); 3829 else 3830 { 3831 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0); 3832 3833 if (wordnum < 0 || wordnum >= nwords) 3834 error ("argument of `__builtin_args_info' out of range"); 3835 else 3836 return GEN_INT (word_ptr[wordnum]); 3837 } 3838 } 3839 else 3840 error ("missing argument in `__builtin_args_info'"); 3841 3842 return const0_rtx; 3843} 3844 3845/* Expand ARGLIST, from a call to __builtin_next_arg. */ 3846 3847static rtx 3848expand_builtin_next_arg (tree arglist) 3849{ 3850 tree fntype = TREE_TYPE (current_function_decl); 3851 3852 if (TYPE_ARG_TYPES (fntype) == 0 3853 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) 3854 == void_type_node)) 3855 { 3856 error ("`va_start' used in function with fixed args"); 3857 return const0_rtx; 3858 } 3859 3860 if (arglist) 3861 { 3862 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl)); 3863 tree arg = TREE_VALUE (arglist); 3864 3865 /* Strip off all nops for the sake of the comparison. This 3866 is not quite the same as STRIP_NOPS. It does more. 3867 We must also strip off INDIRECT_EXPR for C++ reference 3868 parameters. */ 3869 while (TREE_CODE (arg) == NOP_EXPR 3870 || TREE_CODE (arg) == CONVERT_EXPR 3871 || TREE_CODE (arg) == NON_LVALUE_EXPR 3872 || TREE_CODE (arg) == INDIRECT_REF) 3873 arg = TREE_OPERAND (arg, 0); 3874 if (arg != last_parm) 3875 warning ("second parameter of `va_start' not last named argument"); 3876 } 3877 else 3878 /* Evidently an out of date version of <stdarg.h>; can't validate 3879 va_start's second argument, but can still work as intended. */ 3880 warning ("`__builtin_next_arg' called without an argument"); 3881 3882 return expand_binop (Pmode, add_optab, 3883 current_function_internal_arg_pointer, 3884 current_function_arg_offset_rtx, 3885 NULL_RTX, 0, OPTAB_LIB_WIDEN); 3886} 3887 3888/* Make it easier for the backends by protecting the valist argument 3889 from multiple evaluations. */ 3890 3891static tree 3892stabilize_va_list (tree valist, int needs_lvalue) 3893{ 3894 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE) 3895 { 3896 if (TREE_SIDE_EFFECTS (valist)) 3897 valist = save_expr (valist); 3898 3899 /* For this case, the backends will be expecting a pointer to 3900 TREE_TYPE (va_list_type_node), but it's possible we've 3901 actually been given an array (an actual va_list_type_node). 3902 So fix it. */ 3903 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE) 3904 { 3905 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node)); 3906 tree p2 = build_pointer_type (va_list_type_node); 3907 3908 valist = build1 (ADDR_EXPR, p2, valist); 3909 valist = fold (build1 (NOP_EXPR, p1, valist)); 3910 } 3911 } 3912 else 3913 { 3914 tree pt; 3915 3916 if (! needs_lvalue) 3917 { 3918 if (! TREE_SIDE_EFFECTS (valist)) 3919 return valist; 3920 3921 pt = build_pointer_type (va_list_type_node); 3922 valist = fold (build1 (ADDR_EXPR, pt, valist)); 3923 TREE_SIDE_EFFECTS (valist) = 1; 3924 } 3925 3926 if (TREE_SIDE_EFFECTS (valist)) 3927 valist = save_expr (valist); 3928 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), 3929 valist)); 3930 } 3931 3932 return valist; 3933} 3934 3935/* The "standard" definition of va_list is void*. */ 3936 3937tree 3938std_build_builtin_va_list (void) 3939{ 3940 return ptr_type_node; 3941} 3942 3943/* The "standard" implementation of va_start: just assign `nextarg' to 3944 the variable. */ 3945 3946void 3947std_expand_builtin_va_start (tree valist, rtx nextarg) 3948{ 3949 tree t; 3950 3951 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, 3952 make_tree (ptr_type_node, nextarg)); 3953 TREE_SIDE_EFFECTS (t) = 1; 3954 3955 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 3956} 3957 3958/* Expand ARGLIST, from a call to __builtin_va_start. */ 3959 3960static rtx 3961expand_builtin_va_start (tree arglist) 3962{ 3963 rtx nextarg; 3964 tree chain, valist; 3965 3966 chain = TREE_CHAIN (arglist); 3967 3968 if (TREE_CHAIN (chain)) 3969 error ("too many arguments to function `va_start'"); 3970 3971 nextarg = expand_builtin_next_arg (chain); 3972 valist = stabilize_va_list (TREE_VALUE (arglist), 1); 3973 3974#ifdef EXPAND_BUILTIN_VA_START 3975 EXPAND_BUILTIN_VA_START (valist, nextarg); 3976#else 3977 std_expand_builtin_va_start (valist, nextarg); 3978#endif 3979 3980 return const0_rtx; 3981} 3982 3983/* The "standard" implementation of va_arg: read the value from the 3984 current (padded) address and increment by the (padded) size. */ 3985 3986rtx 3987std_expand_builtin_va_arg (tree valist, tree type) 3988{ 3989 tree addr_tree, t, type_size = NULL; 3990 tree align, alignm1; 3991 tree rounded_size; 3992 rtx addr; 3993 HOST_WIDE_INT boundary; 3994 3995 /* Compute the rounded size of the type. */ 3996 align = size_int (PARM_BOUNDARY / BITS_PER_UNIT); 3997 alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1); 3998 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type); 3999 4000 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually 4001 requires greater alignment, we must perform dynamic alignment. */ 4002 4003 if (boundary > PARM_BOUNDARY) 4004 { 4005 if (!PAD_VARARGS_DOWN) 4006 { 4007 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, 4008 build (PLUS_EXPR, TREE_TYPE (valist), valist, 4009 build_int_2 (boundary / BITS_PER_UNIT - 1, 0))); 4010 TREE_SIDE_EFFECTS (t) = 1; 4011 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 4012 } 4013 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, 4014 build (BIT_AND_EXPR, TREE_TYPE (valist), valist, 4015 build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1))); 4016 TREE_SIDE_EFFECTS (t) = 1; 4017 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 4018 } 4019 if (type == error_mark_node 4020 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL 4021 || TREE_OVERFLOW (type_size)) 4022 rounded_size = size_zero_node; 4023 else 4024 rounded_size = fold (build (MULT_EXPR, sizetype, 4025 fold (build (TRUNC_DIV_EXPR, sizetype, 4026 fold (build (PLUS_EXPR, sizetype, 4027 type_size, alignm1)), 4028 align)), 4029 align)); 4030 4031 /* Get AP. */ 4032 addr_tree = valist; 4033 if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size)) 4034 { 4035 /* Small args are padded downward. */ 4036 addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree, 4037 fold (build (COND_EXPR, sizetype, 4038 fold (build (GT_EXPR, sizetype, 4039 rounded_size, 4040 align)), 4041 size_zero_node, 4042 fold (build (MINUS_EXPR, sizetype, 4043 rounded_size, 4044 type_size)))))); 4045 } 4046 4047 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL); 4048 addr = copy_to_reg (addr); 4049 4050 /* Compute new value for AP. */ 4051 if (! integer_zerop (rounded_size)) 4052 { 4053 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, 4054 build (PLUS_EXPR, TREE_TYPE (valist), valist, 4055 rounded_size)); 4056 TREE_SIDE_EFFECTS (t) = 1; 4057 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 4058 } 4059 4060 return addr; 4061} 4062 4063/* Expand __builtin_va_arg, which is not really a builtin function, but 4064 a very special sort of operator. */ 4065 4066rtx 4067expand_builtin_va_arg (tree valist, tree type) 4068{ 4069 rtx addr, result; 4070 tree promoted_type, want_va_type, have_va_type; 4071 4072 /* Verify that valist is of the proper type. */ 4073 4074 want_va_type = va_list_type_node; 4075 have_va_type = TREE_TYPE (valist); 4076 if (TREE_CODE (want_va_type) == ARRAY_TYPE) 4077 { 4078 /* If va_list is an array type, the argument may have decayed 4079 to a pointer type, e.g. by being passed to another function. 4080 In that case, unwrap both types so that we can compare the 4081 underlying records. */ 4082 if (TREE_CODE (have_va_type) == ARRAY_TYPE 4083 || TREE_CODE (have_va_type) == POINTER_TYPE) 4084 { 4085 want_va_type = TREE_TYPE (want_va_type); 4086 have_va_type = TREE_TYPE (have_va_type); 4087 } 4088 } 4089 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type)) 4090 { 4091 error ("first argument to `va_arg' not of type `va_list'"); 4092 addr = const0_rtx; 4093 } 4094 4095 /* Generate a diagnostic for requesting data of a type that cannot 4096 be passed through `...' due to type promotion at the call site. */ 4097 else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type)) 4098 != type) 4099 { 4100 const char *name = "<anonymous type>", *pname = 0; 4101 static bool gave_help; 4102 4103 if (TYPE_NAME (type)) 4104 { 4105 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) 4106 name = IDENTIFIER_POINTER (TYPE_NAME (type)); 4107 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 4108 && DECL_NAME (TYPE_NAME (type))) 4109 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); 4110 } 4111 if (TYPE_NAME (promoted_type)) 4112 { 4113 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE) 4114 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type)); 4115 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL 4116 && DECL_NAME (TYPE_NAME (promoted_type))) 4117 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type))); 4118 } 4119 4120 /* Unfortunately, this is merely undefined, rather than a constraint 4121 violation, so we cannot make this an error. If this call is never 4122 executed, the program is still strictly conforming. */ 4123 warning ("`%s' is promoted to `%s' when passed through `...'", 4124 name, pname); 4125 if (! gave_help) 4126 { 4127 gave_help = true; 4128 warning ("(so you should pass `%s' not `%s' to `va_arg')", 4129 pname, name); 4130 } 4131 4132 /* We can, however, treat "undefined" any way we please. 4133 Call abort to encourage the user to fix the program. */ 4134 inform ("if this code is reached, the program will abort"); 4135 expand_builtin_trap (); 4136 4137 /* This is dead code, but go ahead and finish so that the 4138 mode of the result comes out right. */ 4139 addr = const0_rtx; 4140 } 4141 else 4142 { 4143 /* Make it easier for the backends by protecting the valist argument 4144 from multiple evaluations. */ 4145 valist = stabilize_va_list (valist, 0); 4146 4147#ifdef EXPAND_BUILTIN_VA_ARG 4148 addr = EXPAND_BUILTIN_VA_ARG (valist, type); 4149#else 4150 addr = std_expand_builtin_va_arg (valist, type); 4151#endif 4152 } 4153 4154 addr = convert_memory_address (Pmode, addr); 4155 4156 result = gen_rtx_MEM (TYPE_MODE (type), addr); 4157 set_mem_alias_set (result, get_varargs_alias_set ()); 4158 4159 return result; 4160} 4161 4162/* Expand ARGLIST, from a call to __builtin_va_end. */ 4163 4164static rtx 4165expand_builtin_va_end (tree arglist) 4166{ 4167 tree valist = TREE_VALUE (arglist); 4168 4169 /* Evaluate for side effects, if needed. I hate macros that don't 4170 do that. */ 4171 if (TREE_SIDE_EFFECTS (valist)) 4172 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL); 4173 4174 return const0_rtx; 4175} 4176 4177/* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a 4178 builtin rather than just as an assignment in stdarg.h because of the 4179 nastiness of array-type va_list types. */ 4180 4181static rtx 4182expand_builtin_va_copy (tree arglist) 4183{ 4184 tree dst, src, t; 4185 4186 dst = TREE_VALUE (arglist); 4187 src = TREE_VALUE (TREE_CHAIN (arglist)); 4188 4189 dst = stabilize_va_list (dst, 1); 4190 src = stabilize_va_list (src, 0); 4191 4192 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE) 4193 { 4194 t = build (MODIFY_EXPR, va_list_type_node, dst, src); 4195 TREE_SIDE_EFFECTS (t) = 1; 4196 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 4197 } 4198 else 4199 { 4200 rtx dstb, srcb, size; 4201 4202 /* Evaluate to pointers. */ 4203 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL); 4204 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL); 4205 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX, 4206 VOIDmode, EXPAND_NORMAL); 4207 4208 dstb = convert_memory_address (Pmode, dstb); 4209 srcb = convert_memory_address (Pmode, srcb); 4210 4211 /* "Dereference" to BLKmode memories. */ 4212 dstb = gen_rtx_MEM (BLKmode, dstb); 4213 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst)))); 4214 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node)); 4215 srcb = gen_rtx_MEM (BLKmode, srcb); 4216 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src)))); 4217 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node)); 4218 4219 /* Copy. */ 4220 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL); 4221 } 4222 4223 return const0_rtx; 4224} 4225 4226/* Expand a call to one of the builtin functions __builtin_frame_address or 4227 __builtin_return_address. */ 4228 4229static rtx 4230expand_builtin_frame_address (tree fndecl, tree arglist) 4231{ 4232 /* The argument must be a nonnegative integer constant. 4233 It counts the number of frames to scan up the stack. 4234 The value is the return address saved in that frame. */ 4235 if (arglist == 0) 4236 /* Warning about missing arg was already issued. */ 4237 return const0_rtx; 4238 else if (! host_integerp (TREE_VALUE (arglist), 1)) 4239 { 4240 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4241 error ("invalid arg to `__builtin_frame_address'"); 4242 else 4243 error ("invalid arg to `__builtin_return_address'"); 4244 return const0_rtx; 4245 } 4246 else 4247 { 4248 rtx tem 4249 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl), 4250 tree_low_cst (TREE_VALUE (arglist), 1), 4251 hard_frame_pointer_rtx); 4252 4253 /* Some ports cannot access arbitrary stack frames. */ 4254 if (tem == NULL) 4255 { 4256 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4257 warning ("unsupported arg to `__builtin_frame_address'"); 4258 else 4259 warning ("unsupported arg to `__builtin_return_address'"); 4260 return const0_rtx; 4261 } 4262 4263 /* For __builtin_frame_address, return what we've got. */ 4264 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) 4265 return tem; 4266 4267 if (GET_CODE (tem) != REG 4268 && ! CONSTANT_P (tem)) 4269 tem = copy_to_mode_reg (Pmode, tem); 4270 return tem; 4271 } 4272} 4273 4274/* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if 4275 we failed and the caller should emit a normal call, otherwise try to get 4276 the result in TARGET, if convenient. */ 4277 4278static rtx 4279expand_builtin_alloca (tree arglist, rtx target) 4280{ 4281 rtx op0; 4282 rtx result; 4283 4284 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 4285 return 0; 4286 4287 /* Compute the argument. */ 4288 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0); 4289 4290 /* Allocate the desired space. */ 4291 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT); 4292 result = convert_memory_address (ptr_mode, result); 4293 4294 return result; 4295} 4296 4297/* Expand a call to a unary builtin. The arguments are in ARGLIST. 4298 Return 0 if a normal call should be emitted rather than expanding the 4299 function in-line. If convenient, the result should be placed in TARGET. 4300 SUBTARGET may be used as the target for computing one of EXP's operands. */ 4301 4302static rtx 4303expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target, 4304 rtx subtarget, optab op_optab) 4305{ 4306 rtx op0; 4307 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 4308 return 0; 4309 4310 /* Compute the argument. */ 4311 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0); 4312 /* Compute op, into TARGET if possible. 4313 Set TARGET to wherever the result comes back. */ 4314 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))), 4315 op_optab, op0, target, 1); 4316 if (target == 0) 4317 abort (); 4318 4319 return convert_to_mode (target_mode, target, 0); 4320} 4321 4322/* If the string passed to fputs is a constant and is one character 4323 long, we attempt to transform this call into __builtin_fputc(). */ 4324 4325static rtx 4326expand_builtin_fputs (tree arglist, rtx target, bool unlocked) 4327{ 4328 tree len, fn; 4329 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED] 4330 : implicit_built_in_decls[BUILT_IN_FPUTC]; 4331 tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED] 4332 : implicit_built_in_decls[BUILT_IN_FWRITE]; 4333 4334 /* If the return value is used, or the replacement _DECL isn't 4335 initialized, don't do the transformation. */ 4336 if (target != const0_rtx || !fn_fputc || !fn_fwrite) 4337 return 0; 4338 4339 /* Verify the arguments in the original call. */ 4340 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 4341 return 0; 4342 4343 /* Get the length of the string passed to fputs. If the length 4344 can't be determined, punt. */ 4345 if (!(len = c_strlen (TREE_VALUE (arglist), 1)) 4346 || TREE_CODE (len) != INTEGER_CST) 4347 return 0; 4348 4349 switch (compare_tree_int (len, 1)) 4350 { 4351 case -1: /* length is 0, delete the call entirely . */ 4352 { 4353 /* Evaluate and ignore the argument in case it has 4354 side-effects. */ 4355 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx, 4356 VOIDmode, EXPAND_NORMAL); 4357 return const0_rtx; 4358 } 4359 case 0: /* length is 1, call fputc. */ 4360 { 4361 const char *p = c_getstr (TREE_VALUE (arglist)); 4362 4363 if (p != NULL) 4364 { 4365 /* New argument list transforming fputs(string, stream) to 4366 fputc(string[0], stream). */ 4367 arglist = 4368 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist))); 4369 arglist = 4370 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist); 4371 fn = fn_fputc; 4372 break; 4373 } 4374 } 4375 /* Fall through. */ 4376 case 1: /* length is greater than 1, call fwrite. */ 4377 { 4378 tree string_arg; 4379 4380 /* If optimizing for size keep fputs. */ 4381 if (optimize_size) 4382 return 0; 4383 string_arg = TREE_VALUE (arglist); 4384 /* New argument list transforming fputs(string, stream) to 4385 fwrite(string, 1, len, stream). */ 4386 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist))); 4387 arglist = tree_cons (NULL_TREE, len, arglist); 4388 arglist = tree_cons (NULL_TREE, size_one_node, arglist); 4389 arglist = tree_cons (NULL_TREE, string_arg, arglist); 4390 fn = fn_fwrite; 4391 break; 4392 } 4393 default: 4394 abort (); 4395 } 4396 4397 return expand_expr (build_function_call_expr (fn, arglist), 4398 const0_rtx, VOIDmode, EXPAND_NORMAL); 4399} 4400 4401/* Expand a call to __builtin_expect. We return our argument and emit a 4402 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in 4403 a non-jump context. */ 4404 4405static rtx 4406expand_builtin_expect (tree arglist, rtx target) 4407{ 4408 tree exp, c; 4409 rtx note, rtx_c; 4410 4411 if (arglist == NULL_TREE 4412 || TREE_CHAIN (arglist) == NULL_TREE) 4413 return const0_rtx; 4414 exp = TREE_VALUE (arglist); 4415 c = TREE_VALUE (TREE_CHAIN (arglist)); 4416 4417 if (TREE_CODE (c) != INTEGER_CST) 4418 { 4419 error ("second arg to `__builtin_expect' must be a constant"); 4420 c = integer_zero_node; 4421 } 4422 4423 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL); 4424 4425 /* Don't bother with expected value notes for integral constants. */ 4426 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT) 4427 { 4428 /* We do need to force this into a register so that we can be 4429 moderately sure to be able to correctly interpret the branch 4430 condition later. */ 4431 target = force_reg (GET_MODE (target), target); 4432 4433 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL); 4434 4435 note = emit_note (NOTE_INSN_EXPECTED_VALUE); 4436 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c); 4437 } 4438 4439 return target; 4440} 4441 4442/* Like expand_builtin_expect, except do this in a jump context. This is 4443 called from do_jump if the conditional is a __builtin_expect. Return either 4444 a list of insns to emit the jump or NULL if we cannot optimize 4445 __builtin_expect. We need to optimize this at jump time so that machines 4446 like the PowerPC don't turn the test into a SCC operation, and then jump 4447 based on the test being 0/1. */ 4448 4449rtx 4450expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label) 4451{ 4452 tree arglist = TREE_OPERAND (exp, 1); 4453 tree arg0 = TREE_VALUE (arglist); 4454 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 4455 rtx ret = NULL_RTX; 4456 4457 /* Only handle __builtin_expect (test, 0) and 4458 __builtin_expect (test, 1). */ 4459 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE 4460 && (integer_zerop (arg1) || integer_onep (arg1))) 4461 { 4462 rtx insn, drop_through_label, temp; 4463 4464 /* Expand the jump insns. */ 4465 start_sequence (); 4466 do_jump (arg0, if_false_label, if_true_label); 4467 ret = get_insns (); 4468 4469 drop_through_label = get_last_insn (); 4470 if (drop_through_label && GET_CODE (drop_through_label) == NOTE) 4471 drop_through_label = prev_nonnote_insn (drop_through_label); 4472 if (drop_through_label && GET_CODE (drop_through_label) != CODE_LABEL) 4473 drop_through_label = NULL_RTX; 4474 end_sequence (); 4475 4476 if (! if_true_label) 4477 if_true_label = drop_through_label; 4478 if (! if_false_label) 4479 if_false_label = drop_through_label; 4480 4481 /* Go through and add the expect's to each of the conditional jumps. */ 4482 insn = ret; 4483 while (insn != NULL_RTX) 4484 { 4485 rtx next = NEXT_INSN (insn); 4486 4487 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn)) 4488 { 4489 rtx ifelse = SET_SRC (pc_set (insn)); 4490 rtx then_dest = XEXP (ifelse, 1); 4491 rtx else_dest = XEXP (ifelse, 2); 4492 int taken = -1; 4493 4494 /* First check if we recognize any of the labels. */ 4495 if (GET_CODE (then_dest) == LABEL_REF 4496 && XEXP (then_dest, 0) == if_true_label) 4497 taken = 1; 4498 else if (GET_CODE (then_dest) == LABEL_REF 4499 && XEXP (then_dest, 0) == if_false_label) 4500 taken = 0; 4501 else if (GET_CODE (else_dest) == LABEL_REF 4502 && XEXP (else_dest, 0) == if_false_label) 4503 taken = 1; 4504 else if (GET_CODE (else_dest) == LABEL_REF 4505 && XEXP (else_dest, 0) == if_true_label) 4506 taken = 0; 4507 /* Otherwise check where we drop through. */ 4508 else if (else_dest == pc_rtx) 4509 { 4510 if (next && GET_CODE (next) == NOTE) 4511 next = next_nonnote_insn (next); 4512 4513 if (next && GET_CODE (next) == JUMP_INSN 4514 && any_uncondjump_p (next)) 4515 temp = XEXP (SET_SRC (pc_set (next)), 0); 4516 else 4517 temp = next; 4518 4519 /* TEMP is either a CODE_LABEL, NULL_RTX or something 4520 else that can't possibly match either target label. */ 4521 if (temp == if_false_label) 4522 taken = 1; 4523 else if (temp == if_true_label) 4524 taken = 0; 4525 } 4526 else if (then_dest == pc_rtx) 4527 { 4528 if (next && GET_CODE (next) == NOTE) 4529 next = next_nonnote_insn (next); 4530 4531 if (next && GET_CODE (next) == JUMP_INSN 4532 && any_uncondjump_p (next)) 4533 temp = XEXP (SET_SRC (pc_set (next)), 0); 4534 else 4535 temp = next; 4536 4537 if (temp == if_false_label) 4538 taken = 0; 4539 else if (temp == if_true_label) 4540 taken = 1; 4541 } 4542 4543 if (taken != -1) 4544 { 4545 /* If the test is expected to fail, reverse the 4546 probabilities. */ 4547 if (integer_zerop (arg1)) 4548 taken = 1 - taken; 4549 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken); 4550 } 4551 } 4552 4553 insn = next; 4554 } 4555 } 4556 4557 return ret; 4558} 4559 4560void 4561expand_builtin_trap (void) 4562{ 4563#ifdef HAVE_trap 4564 if (HAVE_trap) 4565 emit_insn (gen_trap ()); 4566 else 4567#endif 4568 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0); 4569 emit_barrier (); 4570} 4571 4572/* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST. 4573 Return 0 if a normal call should be emitted rather than expanding 4574 the function inline. If convenient, the result should be placed 4575 in TARGET. SUBTARGET may be used as the target for computing 4576 the operand. */ 4577 4578static rtx 4579expand_builtin_fabs (tree arglist, rtx target, rtx subtarget) 4580{ 4581 enum machine_mode mode; 4582 tree arg; 4583 rtx op0; 4584 4585 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 4586 return 0; 4587 4588 arg = TREE_VALUE (arglist); 4589 mode = TYPE_MODE (TREE_TYPE (arg)); 4590 op0 = expand_expr (arg, subtarget, VOIDmode, 0); 4591 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1)); 4592} 4593 4594/* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST. 4595 Return 0 if a normal call should be emitted rather than expanding 4596 the function inline. If convenient, the result should be placed 4597 in target. */ 4598 4599static rtx 4600expand_builtin_cabs (tree arglist, rtx target) 4601{ 4602 enum machine_mode mode; 4603 tree arg; 4604 rtx op0; 4605 4606 if (arglist == 0 || TREE_CHAIN (arglist)) 4607 return 0; 4608 arg = TREE_VALUE (arglist); 4609 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE 4610 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE) 4611 return 0; 4612 4613 mode = TYPE_MODE (TREE_TYPE (arg)); 4614 op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0); 4615 return expand_complex_abs (mode, op0, target, 0); 4616} 4617 4618/* Create a new constant string literal and return a char* pointer to it. 4619 The STRING_CST value is the LEN characters at STR. */ 4620static tree 4621build_string_literal (int len, const char *str) 4622{ 4623 tree t, elem, index, type; 4624 4625 t = build_string (len, str); 4626 elem = build_type_variant (char_type_node, 1, 0); 4627 index = build_index_type (build_int_2 (len - 1, 0)); 4628 type = build_array_type (elem, index); 4629 TREE_TYPE (t) = type; 4630 TREE_CONSTANT (t) = 1; 4631 TREE_READONLY (t) = 1; 4632 TREE_STATIC (t) = 1; 4633 4634 type = build_pointer_type (type); 4635 t = build1 (ADDR_EXPR, type, t); 4636 4637 type = build_pointer_type (elem); 4638 t = build1 (NOP_EXPR, type, t); 4639 return t; 4640} 4641 4642/* Expand a call to printf or printf_unlocked with argument list ARGLIST. 4643 Return 0 if a normal call should be emitted rather than transforming 4644 the function inline. If convenient, the result should be placed in 4645 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked 4646 call. */ 4647static rtx 4648expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode, 4649 bool unlocked) 4650{ 4651 tree fn_putchar = unlocked 4652 ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] 4653 : implicit_built_in_decls[BUILT_IN_PUTCHAR]; 4654 tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED] 4655 : implicit_built_in_decls[BUILT_IN_PUTS]; 4656 const char *fmt_str; 4657 tree fn, fmt, arg; 4658 4659 /* If the return value is used, don't do the transformation. */ 4660 if (target != const0_rtx) 4661 return 0; 4662 4663 /* Verify the required arguments in the original call. */ 4664 if (! arglist) 4665 return 0; 4666 fmt = TREE_VALUE (arglist); 4667 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE) 4668 return 0; 4669 arglist = TREE_CHAIN (arglist); 4670 4671 /* Check whether the format is a literal string constant. */ 4672 fmt_str = c_getstr (fmt); 4673 if (fmt_str == NULL) 4674 return 0; 4675 4676 /* If the format specifier was "%s\n", call __builtin_puts(arg). */ 4677 if (strcmp (fmt_str, "%s\n") == 0) 4678 { 4679 if (! arglist 4680 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE 4681 || TREE_CHAIN (arglist)) 4682 return 0; 4683 fn = fn_puts; 4684 } 4685 /* If the format specifier was "%c", call __builtin_putchar(arg). */ 4686 else if (strcmp (fmt_str, "%c") == 0) 4687 { 4688 if (! arglist 4689 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE 4690 || TREE_CHAIN (arglist)) 4691 return 0; 4692 fn = fn_putchar; 4693 } 4694 else 4695 { 4696 /* We can't handle anything else with % args or %% ... yet. */ 4697 if (strchr (fmt_str, '%')) 4698 return 0; 4699 4700 if (arglist) 4701 return 0; 4702 4703 /* If the format specifier was "", printf does nothing. */ 4704 if (fmt_str[0] == '\0') 4705 return const0_rtx; 4706 /* If the format specifier has length of 1, call putchar. */ 4707 if (fmt_str[1] == '\0') 4708 { 4709 /* Given printf("c"), (where c is any one character,) 4710 convert "c"[0] to an int and pass that to the replacement 4711 function. */ 4712 arg = build_int_2 (fmt_str[0], 0); 4713 arglist = build_tree_list (NULL_TREE, arg); 4714 fn = fn_putchar; 4715 } 4716 else 4717 { 4718 /* If the format specifier was "string\n", call puts("string"). */ 4719 size_t len = strlen (fmt_str); 4720 if (fmt_str[len - 1] == '\n') 4721 { 4722 /* Create a NUL-terminated string that's one char shorter 4723 than the original, stripping off the trailing '\n'. */ 4724 char *newstr = (char *) alloca (len); 4725 memcpy (newstr, fmt_str, len - 1); 4726 newstr[len - 1] = 0; 4727 4728 arg = build_string_literal (len, newstr); 4729 arglist = build_tree_list (NULL_TREE, arg); 4730 fn = fn_puts; 4731 } 4732 else 4733 /* We'd like to arrange to call fputs(string,stdout) here, 4734 but we need stdout and don't have a way to get it yet. */ 4735 return 0; 4736 } 4737 } 4738 4739 if (!fn) 4740 return 0; 4741 return expand_expr (build_function_call_expr (fn, arglist), 4742 target, mode, EXPAND_NORMAL); 4743} 4744 4745/* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST. 4746 Return 0 if a normal call should be emitted rather than transforming 4747 the function inline. If convenient, the result should be placed in 4748 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked 4749 call. */ 4750static rtx 4751expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode, 4752 bool unlocked) 4753{ 4754 tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED] 4755 : implicit_built_in_decls[BUILT_IN_FPUTC]; 4756 tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED] 4757 : implicit_built_in_decls[BUILT_IN_FPUTS]; 4758 const char *fmt_str; 4759 tree fn, fmt, fp, arg; 4760 4761 /* If the return value is used, don't do the transformation. */ 4762 if (target != const0_rtx) 4763 return 0; 4764 4765 /* Verify the required arguments in the original call. */ 4766 if (! arglist) 4767 return 0; 4768 fp = TREE_VALUE (arglist); 4769 if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE) 4770 return 0; 4771 arglist = TREE_CHAIN (arglist); 4772 if (! arglist) 4773 return 0; 4774 fmt = TREE_VALUE (arglist); 4775 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE) 4776 return 0; 4777 arglist = TREE_CHAIN (arglist); 4778 4779 /* Check whether the format is a literal string constant. */ 4780 fmt_str = c_getstr (fmt); 4781 if (fmt_str == NULL) 4782 return 0; 4783 4784 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */ 4785 if (strcmp (fmt_str, "%s") == 0) 4786 { 4787 if (! arglist 4788 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE 4789 || TREE_CHAIN (arglist)) 4790 return 0; 4791 arg = TREE_VALUE (arglist); 4792 arglist = build_tree_list (NULL_TREE, fp); 4793 arglist = tree_cons (NULL_TREE, arg, arglist); 4794 fn = fn_fputs; 4795 } 4796 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */ 4797 else if (strcmp (fmt_str, "%c") == 0) 4798 { 4799 if (! arglist 4800 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE 4801 || TREE_CHAIN (arglist)) 4802 return 0; 4803 arg = TREE_VALUE (arglist); 4804 arglist = build_tree_list (NULL_TREE, fp); 4805 arglist = tree_cons (NULL_TREE, arg, arglist); 4806 fn = fn_fputc; 4807 } 4808 else 4809 { 4810 /* We can't handle anything else with % args or %% ... yet. */ 4811 if (strchr (fmt_str, '%')) 4812 return 0; 4813 4814 if (arglist) 4815 return 0; 4816 4817 /* If the format specifier was "", fprintf does nothing. */ 4818 if (fmt_str[0] == '\0') 4819 { 4820 /* Evaluate and ignore FILE* argument for side-effects. */ 4821 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL); 4822 return const0_rtx; 4823 } 4824 4825 /* When "string" doesn't contain %, replace all cases of 4826 fprintf(stream,string) with fputs(string,stream). The fputs 4827 builtin will take care of special cases like length == 1. */ 4828 arglist = build_tree_list (NULL_TREE, fp); 4829 arglist = tree_cons (NULL_TREE, fmt, arglist); 4830 fn = fn_fputs; 4831 } 4832 4833 if (!fn) 4834 return 0; 4835 return expand_expr (build_function_call_expr (fn, arglist), 4836 target, mode, EXPAND_NORMAL); 4837} 4838 4839/* Expand a call to sprintf with argument list ARGLIST. Return 0 if 4840 a normal call should be emitted rather than expanding the function 4841 inline. If convenient, the result should be placed in TARGET with 4842 mode MODE. */ 4843 4844static rtx 4845expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode) 4846{ 4847 tree orig_arglist, dest, fmt; 4848 const char *fmt_str; 4849 4850 orig_arglist = arglist; 4851 4852 /* Verify the required arguments in the original call. */ 4853 if (! arglist) 4854 return 0; 4855 dest = TREE_VALUE (arglist); 4856 if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE) 4857 return 0; 4858 arglist = TREE_CHAIN (arglist); 4859 if (! arglist) 4860 return 0; 4861 fmt = TREE_VALUE (arglist); 4862 if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE) 4863 return 0; 4864 arglist = TREE_CHAIN (arglist); 4865 4866 /* Check whether the format is a literal string constant. */ 4867 fmt_str = c_getstr (fmt); 4868 if (fmt_str == NULL) 4869 return 0; 4870 4871 /* If the format doesn't contain % args or %%, use strcpy. */ 4872 if (strchr (fmt_str, '%') == 0) 4873 { 4874 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 4875 tree exp; 4876 4877 if (arglist || ! fn) 4878 return 0; 4879 expand_expr (build_function_call_expr (fn, orig_arglist), 4880 const0_rtx, VOIDmode, EXPAND_NORMAL); 4881 if (target == const0_rtx) 4882 return const0_rtx; 4883 exp = build_int_2 (strlen (fmt_str), 0); 4884 exp = fold (build1 (NOP_EXPR, integer_type_node, exp)); 4885 return expand_expr (exp, target, mode, EXPAND_NORMAL); 4886 } 4887 /* If the format is "%s", use strcpy if the result isn't used. */ 4888 else if (strcmp (fmt_str, "%s") == 0) 4889 { 4890 tree fn, arg, len; 4891 fn = implicit_built_in_decls[BUILT_IN_STRCPY]; 4892 4893 if (! fn) 4894 return 0; 4895 4896 if (! arglist || TREE_CHAIN (arglist)) 4897 return 0; 4898 arg = TREE_VALUE (arglist); 4899 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE) 4900 return 0; 4901 4902 if (target != const0_rtx) 4903 { 4904 len = c_strlen (arg, 1); 4905 if (! len || TREE_CODE (len) != INTEGER_CST) 4906 return 0; 4907 } 4908 else 4909 len = NULL_TREE; 4910 4911 arglist = build_tree_list (NULL_TREE, arg); 4912 arglist = tree_cons (NULL_TREE, dest, arglist); 4913 expand_expr (build_function_call_expr (fn, arglist), 4914 const0_rtx, VOIDmode, EXPAND_NORMAL); 4915 4916 if (target == const0_rtx) 4917 return const0_rtx; 4918 return expand_expr (len, target, mode, EXPAND_NORMAL); 4919 } 4920 4921 return 0; 4922} 4923 4924/* Expand an expression EXP that calls a built-in function, 4925 with result going to TARGET if that's convenient 4926 (and in mode MODE if that's convenient). 4927 SUBTARGET may be used as the target for computing one of EXP's operands. 4928 IGNORE is nonzero if the value is to be ignored. */ 4929 4930rtx 4931expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, 4932 int ignore) 4933{ 4934 tree fndecl = get_callee_fndecl (exp); 4935 tree arglist = TREE_OPERAND (exp, 1); 4936 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 4937 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp)); 4938 4939 /* Perform postincrements before expanding builtin functions. */ 4940 emit_queue (); 4941 4942 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 4943 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore); 4944 4945 /* When not optimizing, generate calls to library functions for a certain 4946 set of builtins. */ 4947 if (!optimize 4948 && !CALLED_AS_BUILT_IN (fndecl) 4949 && DECL_ASSEMBLER_NAME_SET_P (fndecl) 4950 && fcode != BUILT_IN_ALLOCA) 4951 return expand_call (exp, target, ignore); 4952 4953 /* The built-in function expanders test for target == const0_rtx 4954 to determine whether the function's result will be ignored. */ 4955 if (ignore) 4956 target = const0_rtx; 4957 4958 /* If the result of a pure or const built-in function is ignored, and 4959 none of its arguments are volatile, we can avoid expanding the 4960 built-in call and just evaluate the arguments for side-effects. */ 4961 if (target == const0_rtx 4962 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl))) 4963 { 4964 bool volatilep = false; 4965 tree arg; 4966 4967 for (arg = arglist; arg; arg = TREE_CHAIN (arg)) 4968 if (TREE_THIS_VOLATILE (TREE_VALUE (arg))) 4969 { 4970 volatilep = true; 4971 break; 4972 } 4973 4974 if (! volatilep) 4975 { 4976 for (arg = arglist; arg; arg = TREE_CHAIN (arg)) 4977 expand_expr (TREE_VALUE (arg), const0_rtx, 4978 VOIDmode, EXPAND_NORMAL); 4979 return const0_rtx; 4980 } 4981 } 4982 4983 switch (fcode) 4984 { 4985 case BUILT_IN_ABS: 4986 case BUILT_IN_LABS: 4987 case BUILT_IN_LLABS: 4988 case BUILT_IN_IMAXABS: 4989 /* build_function_call changes these into ABS_EXPR. */ 4990 abort (); 4991 4992 case BUILT_IN_FABS: 4993 case BUILT_IN_FABSF: 4994 case BUILT_IN_FABSL: 4995 target = expand_builtin_fabs (arglist, target, subtarget); 4996 if (target) 4997 return target; 4998 break; 4999 5000 case BUILT_IN_CABS: 5001 case BUILT_IN_CABSF: 5002 case BUILT_IN_CABSL: 5003 if (flag_unsafe_math_optimizations) 5004 { 5005 target = expand_builtin_cabs (arglist, target); 5006 if (target) 5007 return target; 5008 } 5009 break; 5010 5011 case BUILT_IN_CONJ: 5012 case BUILT_IN_CONJF: 5013 case BUILT_IN_CONJL: 5014 case BUILT_IN_CREAL: 5015 case BUILT_IN_CREALF: 5016 case BUILT_IN_CREALL: 5017 case BUILT_IN_CIMAG: 5018 case BUILT_IN_CIMAGF: 5019 case BUILT_IN_CIMAGL: 5020 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR 5021 and IMAGPART_EXPR. */ 5022 abort (); 5023 5024 case BUILT_IN_SIN: 5025 case BUILT_IN_SINF: 5026 case BUILT_IN_SINL: 5027 case BUILT_IN_COS: 5028 case BUILT_IN_COSF: 5029 case BUILT_IN_COSL: 5030 case BUILT_IN_EXP: 5031 case BUILT_IN_EXPF: 5032 case BUILT_IN_EXPL: 5033 case BUILT_IN_LOG: 5034 case BUILT_IN_LOGF: 5035 case BUILT_IN_LOGL: 5036 case BUILT_IN_TAN: 5037 case BUILT_IN_TANF: 5038 case BUILT_IN_TANL: 5039 case BUILT_IN_ATAN: 5040 case BUILT_IN_ATANF: 5041 case BUILT_IN_ATANL: 5042 /* Treat these like sqrt only if unsafe math optimizations are allowed, 5043 because of possible accuracy problems. */ 5044 if (! flag_unsafe_math_optimizations) 5045 break; 5046 case BUILT_IN_SQRT: 5047 case BUILT_IN_SQRTF: 5048 case BUILT_IN_SQRTL: 5049 case BUILT_IN_FLOOR: 5050 case BUILT_IN_FLOORF: 5051 case BUILT_IN_FLOORL: 5052 case BUILT_IN_CEIL: 5053 case BUILT_IN_CEILF: 5054 case BUILT_IN_CEILL: 5055 case BUILT_IN_TRUNC: 5056 case BUILT_IN_TRUNCF: 5057 case BUILT_IN_TRUNCL: 5058 case BUILT_IN_ROUND: 5059 case BUILT_IN_ROUNDF: 5060 case BUILT_IN_ROUNDL: 5061 case BUILT_IN_NEARBYINT: 5062 case BUILT_IN_NEARBYINTF: 5063 case BUILT_IN_NEARBYINTL: 5064 target = expand_builtin_mathfn (exp, target, subtarget); 5065 if (target) 5066 return target; 5067 break; 5068 5069 case BUILT_IN_POW: 5070 case BUILT_IN_POWF: 5071 case BUILT_IN_POWL: 5072 if (! flag_unsafe_math_optimizations) 5073 break; 5074 target = expand_builtin_pow (exp, target, subtarget); 5075 if (target) 5076 return target; 5077 break; 5078 5079 case BUILT_IN_ATAN2: 5080 case BUILT_IN_ATAN2F: 5081 case BUILT_IN_ATAN2L: 5082 if (! flag_unsafe_math_optimizations) 5083 break; 5084 target = expand_builtin_mathfn_2 (exp, target, subtarget); 5085 if (target) 5086 return target; 5087 break; 5088 5089 case BUILT_IN_APPLY_ARGS: 5090 return expand_builtin_apply_args (); 5091 5092 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes 5093 FUNCTION with a copy of the parameters described by 5094 ARGUMENTS, and ARGSIZE. It returns a block of memory 5095 allocated on the stack into which is stored all the registers 5096 that might possibly be used for returning the result of a 5097 function. ARGUMENTS is the value returned by 5098 __builtin_apply_args. ARGSIZE is the number of bytes of 5099 arguments that must be copied. ??? How should this value be 5100 computed? We'll also need a safe worst case value for varargs 5101 functions. */ 5102 case BUILT_IN_APPLY: 5103 if (!validate_arglist (arglist, POINTER_TYPE, 5104 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE) 5105 && !validate_arglist (arglist, REFERENCE_TYPE, 5106 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 5107 return const0_rtx; 5108 else 5109 { 5110 int i; 5111 tree t; 5112 rtx ops[3]; 5113 5114 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++) 5115 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0); 5116 5117 return expand_builtin_apply (ops[0], ops[1], ops[2]); 5118 } 5119 5120 /* __builtin_return (RESULT) causes the function to return the 5121 value described by RESULT. RESULT is address of the block of 5122 memory returned by __builtin_apply. */ 5123 case BUILT_IN_RETURN: 5124 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 5125 expand_builtin_return (expand_expr (TREE_VALUE (arglist), 5126 NULL_RTX, VOIDmode, 0)); 5127 return const0_rtx; 5128 5129 case BUILT_IN_SAVEREGS: 5130 return expand_builtin_saveregs (); 5131 5132 case BUILT_IN_ARGS_INFO: 5133 return expand_builtin_args_info (arglist); 5134 5135 /* Return the address of the first anonymous stack arg. */ 5136 case BUILT_IN_NEXT_ARG: 5137 return expand_builtin_next_arg (arglist); 5138 5139 case BUILT_IN_CLASSIFY_TYPE: 5140 return expand_builtin_classify_type (arglist); 5141 5142 case BUILT_IN_CONSTANT_P: 5143 return expand_builtin_constant_p (arglist, target_mode); 5144 5145 case BUILT_IN_FRAME_ADDRESS: 5146 case BUILT_IN_RETURN_ADDRESS: 5147 return expand_builtin_frame_address (fndecl, arglist); 5148 5149 /* Returns the address of the area where the structure is returned. 5150 0 otherwise. */ 5151 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: 5152 if (arglist != 0 5153 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))) 5154 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM) 5155 return const0_rtx; 5156 else 5157 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0); 5158 5159 case BUILT_IN_ALLOCA: 5160 target = expand_builtin_alloca (arglist, target); 5161 if (target) 5162 return target; 5163 break; 5164 5165 case BUILT_IN_FFS: 5166 case BUILT_IN_FFSL: 5167 case BUILT_IN_FFSLL: 5168 target = expand_builtin_unop (target_mode, arglist, target, 5169 subtarget, ffs_optab); 5170 if (target) 5171 return target; 5172 break; 5173 5174 case BUILT_IN_CLZ: 5175 case BUILT_IN_CLZL: 5176 case BUILT_IN_CLZLL: 5177 target = expand_builtin_unop (target_mode, arglist, target, 5178 subtarget, clz_optab); 5179 if (target) 5180 return target; 5181 break; 5182 5183 case BUILT_IN_CTZ: 5184 case BUILT_IN_CTZL: 5185 case BUILT_IN_CTZLL: 5186 target = expand_builtin_unop (target_mode, arglist, target, 5187 subtarget, ctz_optab); 5188 if (target) 5189 return target; 5190 break; 5191 5192 case BUILT_IN_POPCOUNT: 5193 case BUILT_IN_POPCOUNTL: 5194 case BUILT_IN_POPCOUNTLL: 5195 target = expand_builtin_unop (target_mode, arglist, target, 5196 subtarget, popcount_optab); 5197 if (target) 5198 return target; 5199 break; 5200 5201 case BUILT_IN_PARITY: 5202 case BUILT_IN_PARITYL: 5203 case BUILT_IN_PARITYLL: 5204 target = expand_builtin_unop (target_mode, arglist, target, 5205 subtarget, parity_optab); 5206 if (target) 5207 return target; 5208 break; 5209 5210 case BUILT_IN_STRLEN: 5211 target = expand_builtin_strlen (arglist, target, target_mode); 5212 if (target) 5213 return target; 5214 break; 5215 5216 case BUILT_IN_STRCPY: 5217 target = expand_builtin_strcpy (arglist, target, mode); 5218 if (target) 5219 return target; 5220 break; 5221 5222 case BUILT_IN_STRNCPY: 5223 target = expand_builtin_strncpy (arglist, target, mode); 5224 if (target) 5225 return target; 5226 break; 5227 5228 case BUILT_IN_STPCPY: 5229 target = expand_builtin_stpcpy (arglist, target, mode); 5230 if (target) 5231 return target; 5232 break; 5233 5234 case BUILT_IN_STRCAT: 5235 target = expand_builtin_strcat (arglist, target, mode); 5236 if (target) 5237 return target; 5238 break; 5239 5240 case BUILT_IN_STRNCAT: 5241 target = expand_builtin_strncat (arglist, target, mode); 5242 if (target) 5243 return target; 5244 break; 5245 5246 case BUILT_IN_STRSPN: 5247 target = expand_builtin_strspn (arglist, target, mode); 5248 if (target) 5249 return target; 5250 break; 5251 5252 case BUILT_IN_STRCSPN: 5253 target = expand_builtin_strcspn (arglist, target, mode); 5254 if (target) 5255 return target; 5256 break; 5257 5258 case BUILT_IN_STRSTR: 5259 target = expand_builtin_strstr (arglist, target, mode); 5260 if (target) 5261 return target; 5262 break; 5263 5264 case BUILT_IN_STRPBRK: 5265 target = expand_builtin_strpbrk (arglist, target, mode); 5266 if (target) 5267 return target; 5268 break; 5269 5270 case BUILT_IN_INDEX: 5271 case BUILT_IN_STRCHR: 5272 target = expand_builtin_strchr (arglist, target, mode); 5273 if (target) 5274 return target; 5275 break; 5276 5277 case BUILT_IN_RINDEX: 5278 case BUILT_IN_STRRCHR: 5279 target = expand_builtin_strrchr (arglist, target, mode); 5280 if (target) 5281 return target; 5282 break; 5283 5284 case BUILT_IN_MEMCPY: 5285 target = expand_builtin_memcpy (arglist, target, mode); 5286 if (target) 5287 return target; 5288 break; 5289 5290 case BUILT_IN_MEMPCPY: 5291 target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1); 5292 if (target) 5293 return target; 5294 break; 5295 5296 case BUILT_IN_MEMMOVE: 5297 target = expand_builtin_memmove (arglist, target, mode); 5298 if (target) 5299 return target; 5300 break; 5301 5302 case BUILT_IN_BCOPY: 5303 target = expand_builtin_bcopy (arglist); 5304 if (target) 5305 return target; 5306 break; 5307 5308 case BUILT_IN_MEMSET: 5309 target = expand_builtin_memset (arglist, target, mode); 5310 if (target) 5311 return target; 5312 break; 5313 5314 case BUILT_IN_BZERO: 5315 target = expand_builtin_bzero (arglist); 5316 if (target) 5317 return target; 5318 break; 5319 5320 case BUILT_IN_STRCMP: 5321 target = expand_builtin_strcmp (exp, target, mode); 5322 if (target) 5323 return target; 5324 break; 5325 5326 case BUILT_IN_STRNCMP: 5327 target = expand_builtin_strncmp (exp, target, mode); 5328 if (target) 5329 return target; 5330 break; 5331 5332 case BUILT_IN_BCMP: 5333 case BUILT_IN_MEMCMP: 5334 target = expand_builtin_memcmp (exp, arglist, target, mode); 5335 if (target) 5336 return target; 5337 break; 5338 5339 case BUILT_IN_SETJMP: 5340 target = expand_builtin_setjmp (arglist, target); 5341 if (target) 5342 return target; 5343 break; 5344 5345 /* __builtin_longjmp is passed a pointer to an array of five words. 5346 It's similar to the C library longjmp function but works with 5347 __builtin_setjmp above. */ 5348 case BUILT_IN_LONGJMP: 5349 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 5350 break; 5351 else 5352 { 5353 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget, 5354 VOIDmode, 0); 5355 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), 5356 NULL_RTX, VOIDmode, 0); 5357 5358 if (value != const1_rtx) 5359 { 5360 error ("__builtin_longjmp second argument must be 1"); 5361 return const0_rtx; 5362 } 5363 5364 expand_builtin_longjmp (buf_addr, value); 5365 return const0_rtx; 5366 } 5367 5368 case BUILT_IN_TRAP: 5369 expand_builtin_trap (); 5370 return const0_rtx; 5371 5372 case BUILT_IN_PRINTF: 5373 target = expand_builtin_printf (arglist, target, mode, false); 5374 if (target) 5375 return target; 5376 break; 5377 5378 case BUILT_IN_PRINTF_UNLOCKED: 5379 target = expand_builtin_printf (arglist, target, mode, true); 5380 if (target) 5381 return target; 5382 break; 5383 5384 case BUILT_IN_FPUTS: 5385 target = expand_builtin_fputs (arglist, target, false); 5386 if (target) 5387 return target; 5388 break; 5389 5390 case BUILT_IN_FPUTS_UNLOCKED: 5391 target = expand_builtin_fputs (arglist, target, true); 5392 if (target) 5393 return target; 5394 break; 5395 5396 case BUILT_IN_FPRINTF: 5397 target = expand_builtin_fprintf (arglist, target, mode, false); 5398 if (target) 5399 return target; 5400 break; 5401 5402 case BUILT_IN_FPRINTF_UNLOCKED: 5403 target = expand_builtin_fprintf (arglist, target, mode, true); 5404 if (target) 5405 return target; 5406 break; 5407 5408 case BUILT_IN_SPRINTF: 5409 target = expand_builtin_sprintf (arglist, target, mode); 5410 if (target) 5411 return target; 5412 break; 5413 5414 /* Various hooks for the DWARF 2 __throw routine. */ 5415 case BUILT_IN_UNWIND_INIT: 5416 expand_builtin_unwind_init (); 5417 return const0_rtx; 5418 case BUILT_IN_DWARF_CFA: 5419 return virtual_cfa_rtx; 5420#ifdef DWARF2_UNWIND_INFO 5421 case BUILT_IN_DWARF_SP_COLUMN: 5422 return expand_builtin_dwarf_sp_column (); 5423 case BUILT_IN_INIT_DWARF_REG_SIZES: 5424 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist)); 5425 return const0_rtx; 5426#endif 5427 case BUILT_IN_FROB_RETURN_ADDR: 5428 return expand_builtin_frob_return_addr (TREE_VALUE (arglist)); 5429 case BUILT_IN_EXTRACT_RETURN_ADDR: 5430 return expand_builtin_extract_return_addr (TREE_VALUE (arglist)); 5431 case BUILT_IN_EH_RETURN: 5432 expand_builtin_eh_return (TREE_VALUE (arglist), 5433 TREE_VALUE (TREE_CHAIN (arglist))); 5434 return const0_rtx; 5435#ifdef EH_RETURN_DATA_REGNO 5436 case BUILT_IN_EH_RETURN_DATA_REGNO: 5437 return expand_builtin_eh_return_data_regno (arglist); 5438#endif 5439 case BUILT_IN_EXTEND_POINTER: 5440 return expand_builtin_extend_pointer (TREE_VALUE (arglist)); 5441 5442 case BUILT_IN_VA_START: 5443 case BUILT_IN_STDARG_START: 5444 return expand_builtin_va_start (arglist); 5445 case BUILT_IN_VA_END: 5446 return expand_builtin_va_end (arglist); 5447 case BUILT_IN_VA_COPY: 5448 return expand_builtin_va_copy (arglist); 5449 case BUILT_IN_EXPECT: 5450 return expand_builtin_expect (arglist, target); 5451 case BUILT_IN_PREFETCH: 5452 expand_builtin_prefetch (arglist); 5453 return const0_rtx; 5454 5455 5456 default: /* just do library call, if unknown builtin */ 5457 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl)) 5458 error ("built-in function `%s' not currently supported", 5459 IDENTIFIER_POINTER (DECL_NAME (fndecl))); 5460 } 5461 5462 /* The switch statement above can drop through to cause the function 5463 to be called normally. */ 5464 return expand_call (exp, target, ignore); 5465} 5466 5467/* Determine whether a tree node represents a call to a built-in 5468 function. If the tree T is a call to a built-in function with 5469 the right number of arguments of the appropriate types, return 5470 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. 5471 Otherwise the return value is END_BUILTINS. */ 5472 5473enum built_in_function 5474builtin_mathfn_code (tree t) 5475{ 5476 tree fndecl, arglist, parmlist; 5477 tree argtype, parmtype; 5478 5479 if (TREE_CODE (t) != CALL_EXPR 5480 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR) 5481 return END_BUILTINS; 5482 5483 fndecl = get_callee_fndecl (t); 5484 if (fndecl == NULL_TREE 5485 || TREE_CODE (fndecl) != FUNCTION_DECL 5486 || ! DECL_BUILT_IN (fndecl) 5487 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 5488 return END_BUILTINS; 5489 5490 arglist = TREE_OPERAND (t, 1); 5491 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); 5492 for (; parmlist; parmlist = TREE_CHAIN (parmlist)) 5493 { 5494 /* If a function doesn't take a variable number of arguments, 5495 the last element in the list will have type `void'. */ 5496 parmtype = TREE_VALUE (parmlist); 5497 if (VOID_TYPE_P (parmtype)) 5498 { 5499 if (arglist) 5500 return END_BUILTINS; 5501 return DECL_FUNCTION_CODE (fndecl); 5502 } 5503 5504 if (! arglist) 5505 return END_BUILTINS; 5506 5507 argtype = TREE_TYPE (TREE_VALUE (arglist)); 5508 5509 if (SCALAR_FLOAT_TYPE_P (parmtype)) 5510 { 5511 if (! SCALAR_FLOAT_TYPE_P (argtype)) 5512 return END_BUILTINS; 5513 } 5514 else if (COMPLEX_FLOAT_TYPE_P (parmtype)) 5515 { 5516 if (! COMPLEX_FLOAT_TYPE_P (argtype)) 5517 return END_BUILTINS; 5518 } 5519 else if (POINTER_TYPE_P (parmtype)) 5520 { 5521 if (! POINTER_TYPE_P (argtype)) 5522 return END_BUILTINS; 5523 } 5524 else if (INTEGRAL_TYPE_P (parmtype)) 5525 { 5526 if (! INTEGRAL_TYPE_P (argtype)) 5527 return END_BUILTINS; 5528 } 5529 else 5530 return END_BUILTINS; 5531 5532 arglist = TREE_CHAIN (arglist); 5533 } 5534 5535 /* Variable-length argument list. */ 5536 return DECL_FUNCTION_CODE (fndecl); 5537} 5538 5539/* Fold a call to __builtin_constant_p, if we know it will evaluate to a 5540 constant. ARGLIST is the argument list of the call. */ 5541 5542static tree 5543fold_builtin_constant_p (tree arglist) 5544{ 5545 if (arglist == 0) 5546 return 0; 5547 5548 arglist = TREE_VALUE (arglist); 5549 5550 /* We return 1 for a numeric type that's known to be a constant 5551 value at compile-time or for an aggregate type that's a 5552 literal constant. */ 5553 STRIP_NOPS (arglist); 5554 5555 /* If we know this is a constant, emit the constant of one. */ 5556 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c' 5557 || (TREE_CODE (arglist) == CONSTRUCTOR 5558 && TREE_CONSTANT (arglist)) 5559 || (TREE_CODE (arglist) == ADDR_EXPR 5560 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST)) 5561 return integer_one_node; 5562 5563 /* If this expression has side effects, show we don't know it to be a 5564 constant. Likewise if it's a pointer or aggregate type since in 5565 those case we only want literals, since those are only optimized 5566 when generating RTL, not later. 5567 And finally, if we are compiling an initializer, not code, we 5568 need to return a definite result now; there's not going to be any 5569 more optimization done. */ 5570 if (TREE_SIDE_EFFECTS (arglist) 5571 || AGGREGATE_TYPE_P (TREE_TYPE (arglist)) 5572 || POINTER_TYPE_P (TREE_TYPE (arglist)) 5573 || cfun == 0) 5574 return integer_zero_node; 5575 5576 return 0; 5577} 5578 5579/* Fold a call to __builtin_classify_type. */ 5580 5581static tree 5582fold_builtin_classify_type (tree arglist) 5583{ 5584 if (arglist == 0) 5585 return build_int_2 (no_type_class, 0); 5586 5587 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0); 5588} 5589 5590/* Fold a call to __builtin_inf or __builtin_huge_val. */ 5591 5592static tree 5593fold_builtin_inf (tree type, int warn) 5594{ 5595 REAL_VALUE_TYPE real; 5596 5597 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn) 5598 warning ("target format does not support infinity"); 5599 5600 real_inf (&real); 5601 return build_real (type, real); 5602} 5603 5604/* Fold a call to __builtin_nan or __builtin_nans. */ 5605 5606static tree 5607fold_builtin_nan (tree arglist, tree type, int quiet) 5608{ 5609 REAL_VALUE_TYPE real; 5610 const char *str; 5611 5612 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 5613 return 0; 5614 str = c_getstr (TREE_VALUE (arglist)); 5615 if (!str) 5616 return 0; 5617 5618 if (!real_nan (&real, str, quiet, TYPE_MODE (type))) 5619 return 0; 5620 5621 return build_real (type, real); 5622} 5623 5624/* Return true if the floating point expression T has an integer value. 5625 We also allow +Inf, -Inf and NaN to be considered integer values. */ 5626 5627static bool 5628integer_valued_real_p (tree t) 5629{ 5630 switch (TREE_CODE (t)) 5631 { 5632 case FLOAT_EXPR: 5633 return true; 5634 5635 case ABS_EXPR: 5636 case SAVE_EXPR: 5637 case NON_LVALUE_EXPR: 5638 return integer_valued_real_p (TREE_OPERAND (t, 0)); 5639 5640 case COMPOUND_EXPR: 5641 case MODIFY_EXPR: 5642 case BIND_EXPR: 5643 return integer_valued_real_p (TREE_OPERAND (t, 1)); 5644 5645 case PLUS_EXPR: 5646 case MINUS_EXPR: 5647 case MULT_EXPR: 5648 case MIN_EXPR: 5649 case MAX_EXPR: 5650 return integer_valued_real_p (TREE_OPERAND (t, 0)) 5651 && integer_valued_real_p (TREE_OPERAND (t, 1)); 5652 5653 case COND_EXPR: 5654 return integer_valued_real_p (TREE_OPERAND (t, 1)) 5655 && integer_valued_real_p (TREE_OPERAND (t, 2)); 5656 5657 case REAL_CST: 5658 if (! TREE_CONSTANT_OVERFLOW (t)) 5659 { 5660 REAL_VALUE_TYPE c, cint; 5661 5662 c = TREE_REAL_CST (t); 5663 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c); 5664 return real_identical (&c, &cint); 5665 } 5666 5667 case NOP_EXPR: 5668 { 5669 tree type = TREE_TYPE (TREE_OPERAND (t, 0)); 5670 if (TREE_CODE (type) == INTEGER_TYPE) 5671 return true; 5672 if (TREE_CODE (type) == REAL_TYPE) 5673 return integer_valued_real_p (TREE_OPERAND (t, 0)); 5674 break; 5675 } 5676 5677 case CALL_EXPR: 5678 switch (builtin_mathfn_code (t)) 5679 { 5680 case BUILT_IN_CEIL: 5681 case BUILT_IN_CEILF: 5682 case BUILT_IN_CEILL: 5683 case BUILT_IN_FLOOR: 5684 case BUILT_IN_FLOORF: 5685 case BUILT_IN_FLOORL: 5686 case BUILT_IN_NEARBYINT: 5687 case BUILT_IN_NEARBYINTF: 5688 case BUILT_IN_NEARBYINTL: 5689 case BUILT_IN_ROUND: 5690 case BUILT_IN_ROUNDF: 5691 case BUILT_IN_ROUNDL: 5692 case BUILT_IN_TRUNC: 5693 case BUILT_IN_TRUNCF: 5694 case BUILT_IN_TRUNCL: 5695 return true; 5696 5697 default: 5698 break; 5699 } 5700 break; 5701 5702 default: 5703 break; 5704 } 5705 return false; 5706} 5707 5708/* EXP is assumed to be builtin call where truncation can be propagated 5709 across (for instance floor((double)f) == (double)floorf (f). 5710 Do the transformation. */ 5711 5712static tree 5713fold_trunc_transparent_mathfn (tree exp) 5714{ 5715 tree fndecl = get_callee_fndecl (exp); 5716 tree arglist = TREE_OPERAND (exp, 1); 5717 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 5718 tree arg; 5719 5720 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 5721 return 0; 5722 5723 arg = TREE_VALUE (arglist); 5724 /* Integer rounding functions are idempotent. */ 5725 if (fcode == builtin_mathfn_code (arg)) 5726 return arg; 5727 5728 /* If argument is already integer valued, and we don't need to worry 5729 about setting errno, there's no need to perform rounding. */ 5730 if (! flag_errno_math && integer_valued_real_p (arg)) 5731 return arg; 5732 5733 if (optimize) 5734 { 5735 tree arg0 = strip_float_extensions (arg); 5736 tree ftype = TREE_TYPE (exp); 5737 tree newtype = TREE_TYPE (arg0); 5738 tree decl; 5739 5740 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype) 5741 && (decl = mathfn_built_in (newtype, fcode))) 5742 { 5743 arglist = 5744 build_tree_list (NULL_TREE, fold (convert (newtype, arg0))); 5745 return convert (ftype, 5746 build_function_call_expr (decl, arglist)); 5747 } 5748 } 5749 return 0; 5750} 5751 5752/* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the 5753 function's DECL, ARGLIST is the argument list and TYPE is the return 5754 type. Return NULL_TREE if no simplification can be made. */ 5755 5756static tree 5757fold_builtin_cabs (tree fndecl, tree arglist, tree type) 5758{ 5759 tree arg; 5760 5761 if (!arglist || TREE_CHAIN (arglist)) 5762 return NULL_TREE; 5763 5764 arg = TREE_VALUE (arglist); 5765 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE 5766 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE) 5767 return NULL_TREE; 5768 5769 /* Evaluate cabs of a constant at compile-time. */ 5770 if (flag_unsafe_math_optimizations 5771 && TREE_CODE (arg) == COMPLEX_CST 5772 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST 5773 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST 5774 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg)) 5775 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg))) 5776 { 5777 REAL_VALUE_TYPE r, i; 5778 5779 r = TREE_REAL_CST (TREE_REALPART (arg)); 5780 i = TREE_REAL_CST (TREE_IMAGPART (arg)); 5781 5782 real_arithmetic (&r, MULT_EXPR, &r, &r); 5783 real_arithmetic (&i, MULT_EXPR, &i, &i); 5784 real_arithmetic (&r, PLUS_EXPR, &r, &i); 5785 if (real_sqrt (&r, TYPE_MODE (type), &r) 5786 || ! flag_trapping_math) 5787 return build_real (type, r); 5788 } 5789 5790 /* If either part is zero, cabs is fabs of the other. */ 5791 if (TREE_CODE (arg) == COMPLEX_EXPR 5792 && real_zerop (TREE_OPERAND (arg, 0))) 5793 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1))); 5794 if (TREE_CODE (arg) == COMPLEX_EXPR 5795 && real_zerop (TREE_OPERAND (arg, 1))) 5796 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0))); 5797 5798 if (flag_unsafe_math_optimizations) 5799 { 5800 enum built_in_function fcode; 5801 tree sqrtfn; 5802 5803 fcode = DECL_FUNCTION_CODE (fndecl); 5804 if (fcode == BUILT_IN_CABS) 5805 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT]; 5806 else if (fcode == BUILT_IN_CABSF) 5807 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF]; 5808 else if (fcode == BUILT_IN_CABSL) 5809 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL]; 5810 else 5811 sqrtfn = NULL_TREE; 5812 5813 if (sqrtfn != NULL_TREE) 5814 { 5815 tree rpart, ipart, result, arglist; 5816 5817 arg = save_expr (arg); 5818 5819 rpart = fold (build1 (REALPART_EXPR, type, arg)); 5820 ipart = fold (build1 (IMAGPART_EXPR, type, arg)); 5821 5822 rpart = save_expr (rpart); 5823 ipart = save_expr (ipart); 5824 5825 result = fold (build (PLUS_EXPR, type, 5826 fold (build (MULT_EXPR, type, 5827 rpart, rpart)), 5828 fold (build (MULT_EXPR, type, 5829 ipart, ipart)))); 5830 5831 arglist = build_tree_list (NULL_TREE, result); 5832 return build_function_call_expr (sqrtfn, arglist); 5833 } 5834 } 5835 5836 return NULL_TREE; 5837} 5838 5839/* Fold function call to builtin trunc, truncf or truncl. Return 5840 NULL_TREE if no simplification can be made. */ 5841 5842static tree 5843fold_builtin_trunc (tree exp) 5844{ 5845 tree arglist = TREE_OPERAND (exp, 1); 5846 tree arg; 5847 5848 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 5849 return 0; 5850 5851 /* Optimize trunc of constant value. */ 5852 arg = TREE_VALUE (arglist); 5853 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 5854 { 5855 REAL_VALUE_TYPE r, x; 5856 tree type = TREE_TYPE (exp); 5857 5858 x = TREE_REAL_CST (arg); 5859 real_trunc (&r, TYPE_MODE (type), &x); 5860 return build_real (type, r); 5861 } 5862 5863 return fold_trunc_transparent_mathfn (exp); 5864} 5865 5866/* Fold function call to builtin floor, floorf or floorl. Return 5867 NULL_TREE if no simplification can be made. */ 5868 5869static tree 5870fold_builtin_floor (tree exp) 5871{ 5872 tree arglist = TREE_OPERAND (exp, 1); 5873 tree arg; 5874 5875 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 5876 return 0; 5877 5878 /* Optimize floor of constant value. */ 5879 arg = TREE_VALUE (arglist); 5880 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 5881 { 5882 REAL_VALUE_TYPE x; 5883 5884 x = TREE_REAL_CST (arg); 5885 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 5886 { 5887 tree type = TREE_TYPE (exp); 5888 REAL_VALUE_TYPE r; 5889 5890 real_floor (&r, TYPE_MODE (type), &x); 5891 return build_real (type, r); 5892 } 5893 } 5894 5895 return fold_trunc_transparent_mathfn (exp); 5896} 5897 5898/* Fold function call to builtin ceil, ceilf or ceill. Return 5899 NULL_TREE if no simplification can be made. */ 5900 5901static tree 5902fold_builtin_ceil (tree exp) 5903{ 5904 tree arglist = TREE_OPERAND (exp, 1); 5905 tree arg; 5906 5907 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 5908 return 0; 5909 5910 /* Optimize ceil of constant value. */ 5911 arg = TREE_VALUE (arglist); 5912 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 5913 { 5914 REAL_VALUE_TYPE x; 5915 5916 x = TREE_REAL_CST (arg); 5917 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) 5918 { 5919 tree type = TREE_TYPE (exp); 5920 REAL_VALUE_TYPE r; 5921 5922 real_ceil (&r, TYPE_MODE (type), &x); 5923 return build_real (type, r); 5924 } 5925 } 5926 5927 return fold_trunc_transparent_mathfn (exp); 5928} 5929 5930/* Fold function call to builtin ffs, clz, ctz, popcount and parity 5931 and their long and long long variants (i.e. ffsl and ffsll). 5932 Return NULL_TREE if no simplification can be made. */ 5933 5934static tree 5935fold_builtin_bitop (tree exp) 5936{ 5937 tree fndecl = get_callee_fndecl (exp); 5938 tree arglist = TREE_OPERAND (exp, 1); 5939 tree arg; 5940 5941 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE)) 5942 return NULL_TREE; 5943 5944 /* Optimize for constant argument. */ 5945 arg = TREE_VALUE (arglist); 5946 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg)) 5947 { 5948 HOST_WIDE_INT hi, width, result; 5949 unsigned HOST_WIDE_INT lo; 5950 tree type, t; 5951 5952 type = TREE_TYPE (arg); 5953 width = TYPE_PRECISION (type); 5954 lo = TREE_INT_CST_LOW (arg); 5955 5956 /* Clear all the bits that are beyond the type's precision. */ 5957 if (width > HOST_BITS_PER_WIDE_INT) 5958 { 5959 hi = TREE_INT_CST_HIGH (arg); 5960 if (width < 2 * HOST_BITS_PER_WIDE_INT) 5961 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT)); 5962 } 5963 else 5964 { 5965 hi = 0; 5966 if (width < HOST_BITS_PER_WIDE_INT) 5967 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width); 5968 } 5969 5970 switch (DECL_FUNCTION_CODE (fndecl)) 5971 { 5972 case BUILT_IN_FFS: 5973 case BUILT_IN_FFSL: 5974 case BUILT_IN_FFSLL: 5975 if (lo != 0) 5976 result = exact_log2 (lo & -lo) + 1; 5977 else if (hi != 0) 5978 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1; 5979 else 5980 result = 0; 5981 break; 5982 5983 case BUILT_IN_CLZ: 5984 case BUILT_IN_CLZL: 5985 case BUILT_IN_CLZLL: 5986 if (hi != 0) 5987 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT; 5988 else if (lo != 0) 5989 result = width - floor_log2 (lo) - 1; 5990 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result)) 5991 result = width; 5992 break; 5993 5994 case BUILT_IN_CTZ: 5995 case BUILT_IN_CTZL: 5996 case BUILT_IN_CTZLL: 5997 if (lo != 0) 5998 result = exact_log2 (lo & -lo); 5999 else if (hi != 0) 6000 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi); 6001 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result)) 6002 result = width; 6003 break; 6004 6005 case BUILT_IN_POPCOUNT: 6006 case BUILT_IN_POPCOUNTL: 6007 case BUILT_IN_POPCOUNTLL: 6008 result = 0; 6009 while (lo) 6010 result++, lo &= lo - 1; 6011 while (hi) 6012 result++, hi &= hi - 1; 6013 break; 6014 6015 case BUILT_IN_PARITY: 6016 case BUILT_IN_PARITYL: 6017 case BUILT_IN_PARITYLL: 6018 result = 0; 6019 while (lo) 6020 result++, lo &= lo - 1; 6021 while (hi) 6022 result++, hi &= hi - 1; 6023 result &= 1; 6024 break; 6025 6026 default: 6027 abort(); 6028 } 6029 6030 t = build_int_2 (result, 0); 6031 TREE_TYPE (t) = TREE_TYPE (exp); 6032 return t; 6033 } 6034 6035 return NULL_TREE; 6036} 6037 6038/* Return true if EXPR is the real constant contained in VALUE. */ 6039 6040static bool 6041real_dconstp (tree expr, const REAL_VALUE_TYPE *value) 6042{ 6043 STRIP_NOPS (expr); 6044 6045 return ((TREE_CODE (expr) == REAL_CST 6046 && ! TREE_CONSTANT_OVERFLOW (expr) 6047 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value)) 6048 || (TREE_CODE (expr) == COMPLEX_CST 6049 && real_dconstp (TREE_REALPART (expr), value) 6050 && real_zerop (TREE_IMAGPART (expr)))); 6051} 6052 6053/* A subroutine of fold_builtin to fold the various logarithmic 6054 functions. EXP is the CALL_EXPR of a call to a builtin log* 6055 function. VALUE is the base of the log* function. */ 6056 6057static tree 6058fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value) 6059{ 6060 tree arglist = TREE_OPERAND (exp, 1); 6061 6062 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6063 { 6064 tree fndecl = get_callee_fndecl (exp); 6065 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 6066 tree arg = TREE_VALUE (arglist); 6067 const enum built_in_function fcode = builtin_mathfn_code (arg); 6068 6069 /* Optimize log*(1.0) = 0.0. */ 6070 if (real_onep (arg)) 6071 return build_real (type, dconst0); 6072 6073 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE 6074 exactly, then only do this if flag_unsafe_math_optimizations. */ 6075 if (exact_real_truncate (TYPE_MODE (type), value) 6076 || flag_unsafe_math_optimizations) 6077 { 6078 const REAL_VALUE_TYPE value_truncate = 6079 real_value_truncate (TYPE_MODE (type), *value); 6080 if (real_dconstp (arg, &value_truncate)) 6081 return build_real (type, dconst1); 6082 } 6083 6084 /* Special case, optimize logN(expN(x)) = x. */ 6085 if (flag_unsafe_math_optimizations 6086 && ((value == &dconste 6087 && (fcode == BUILT_IN_EXP 6088 || fcode == BUILT_IN_EXPF 6089 || fcode == BUILT_IN_EXPL)) 6090 || (value == &dconst2 6091 && (fcode == BUILT_IN_EXP2 6092 || fcode == BUILT_IN_EXP2F 6093 || fcode == BUILT_IN_EXP2L)) 6094 || (value == &dconst10 6095 && (fcode == BUILT_IN_EXP10 6096 || fcode == BUILT_IN_EXP10F 6097 || fcode == BUILT_IN_EXP10L)))) 6098 return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1))); 6099 6100 /* Optimize log*(func()) for various exponential functions. We 6101 want to determine the value "x" and the power "exponent" in 6102 order to transform logN(x**exponent) into exponent*logN(x). */ 6103 if (flag_unsafe_math_optimizations) 6104 { 6105 tree exponent = 0, x = 0; 6106 6107 switch (fcode) 6108 { 6109 case BUILT_IN_EXP: 6110 case BUILT_IN_EXPF: 6111 case BUILT_IN_EXPL: 6112 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */ 6113 x = build_real (type, 6114 real_value_truncate (TYPE_MODE (type), dconste)); 6115 exponent = TREE_VALUE (TREE_OPERAND (arg, 1)); 6116 break; 6117 case BUILT_IN_EXP2: 6118 case BUILT_IN_EXP2F: 6119 case BUILT_IN_EXP2L: 6120 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */ 6121 x = build_real (type, dconst2); 6122 exponent = TREE_VALUE (TREE_OPERAND (arg, 1)); 6123 break; 6124 case BUILT_IN_EXP10: 6125 case BUILT_IN_EXP10F: 6126 case BUILT_IN_EXP10L: 6127 case BUILT_IN_POW10: 6128 case BUILT_IN_POW10F: 6129 case BUILT_IN_POW10L: 6130 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */ 6131 x = build_real (type, dconst10); 6132 exponent = TREE_VALUE (TREE_OPERAND (arg, 1)); 6133 break; 6134 case BUILT_IN_SQRT: 6135 case BUILT_IN_SQRTF: 6136 case BUILT_IN_SQRTL: 6137 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */ 6138 x = TREE_VALUE (TREE_OPERAND (arg, 1)); 6139 exponent = build_real (type, dconsthalf); 6140 break; 6141 case BUILT_IN_CBRT: 6142 case BUILT_IN_CBRTF: 6143 case BUILT_IN_CBRTL: 6144 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */ 6145 x = TREE_VALUE (TREE_OPERAND (arg, 1)); 6146 exponent = build_real (type, real_value_truncate (TYPE_MODE (type), 6147 dconstthird)); 6148 break; 6149 case BUILT_IN_POW: 6150 case BUILT_IN_POWF: 6151 case BUILT_IN_POWL: 6152 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */ 6153 x = TREE_VALUE (TREE_OPERAND (arg, 1)); 6154 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1))); 6155 break; 6156 default: 6157 break; 6158 } 6159 6160 /* Now perform the optimization. */ 6161 if (x && exponent) 6162 { 6163 tree logfn; 6164 arglist = build_tree_list (NULL_TREE, x); 6165 logfn = build_function_call_expr (fndecl, arglist); 6166 return fold (build (MULT_EXPR, type, exponent, logfn)); 6167 } 6168 } 6169 } 6170 6171 return 0; 6172} 6173 6174/* A subroutine of fold_builtin to fold the various exponent 6175 functions. EXP is the CALL_EXPR of a call to a builtin function. 6176 VALUE is the value which will be raised to a power. */ 6177 6178static tree 6179fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value) 6180{ 6181 tree arglist = TREE_OPERAND (exp, 1); 6182 6183 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6184 { 6185 tree fndecl = get_callee_fndecl (exp); 6186 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 6187 tree arg = TREE_VALUE (arglist); 6188 6189 /* Optimize exp*(0.0) = 1.0. */ 6190 if (real_zerop (arg)) 6191 return build_real (type, dconst1); 6192 6193 /* Optimize expN(1.0) = N. */ 6194 if (real_onep (arg)) 6195 { 6196 REAL_VALUE_TYPE cst; 6197 6198 real_convert (&cst, TYPE_MODE (type), value); 6199 return build_real (type, cst); 6200 } 6201 6202 /* Attempt to evaluate expN(integer) at compile-time. */ 6203 if (flag_unsafe_math_optimizations 6204 && TREE_CODE (arg) == REAL_CST 6205 && ! TREE_CONSTANT_OVERFLOW (arg)) 6206 { 6207 REAL_VALUE_TYPE cint; 6208 REAL_VALUE_TYPE c; 6209 HOST_WIDE_INT n; 6210 6211 c = TREE_REAL_CST (arg); 6212 n = real_to_integer (&c); 6213 real_from_integer (&cint, VOIDmode, n, 6214 n < 0 ? -1 : 0, 0); 6215 if (real_identical (&c, &cint)) 6216 { 6217 REAL_VALUE_TYPE x; 6218 6219 real_powi (&x, TYPE_MODE (type), value, n); 6220 return build_real (type, x); 6221 } 6222 } 6223 6224 /* Optimize expN(logN(x)) = x. */ 6225 if (flag_unsafe_math_optimizations) 6226 { 6227 const enum built_in_function fcode = builtin_mathfn_code (arg); 6228 6229 if ((value == &dconste 6230 && (fcode == BUILT_IN_LOG 6231 || fcode == BUILT_IN_LOGF 6232 || fcode == BUILT_IN_LOGL)) 6233 || (value == &dconst2 6234 && (fcode == BUILT_IN_LOG2 6235 || fcode == BUILT_IN_LOG2F 6236 || fcode == BUILT_IN_LOG2L)) 6237 || (value == &dconst10 6238 && (fcode == BUILT_IN_LOG10 6239 || fcode == BUILT_IN_LOG10F 6240 || fcode == BUILT_IN_LOG10L))) 6241 return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1))); 6242 } 6243 } 6244 6245 return 0; 6246} 6247 6248/* Fold function call to builtin memcpy. Return 6249 NULL_TREE if no simplification can be made. */ 6250 6251static tree 6252fold_builtin_memcpy (tree exp) 6253{ 6254 tree arglist = TREE_OPERAND (exp, 1); 6255 tree dest, src, len; 6256 6257 if (!validate_arglist (arglist, 6258 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6259 return 0; 6260 6261 dest = TREE_VALUE (arglist); 6262 src = TREE_VALUE (TREE_CHAIN (arglist)); 6263 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 6264 6265 /* If the LEN parameter is zero, return DEST. */ 6266 if (integer_zerop (len)) 6267 return omit_one_operand (TREE_TYPE (exp), dest, src); 6268 6269 /* If SRC and DEST are the same (and not volatile), return DEST. */ 6270 if (operand_equal_p (src, dest, 0)) 6271 return omit_one_operand (TREE_TYPE (exp), dest, len); 6272 6273 return 0; 6274} 6275 6276/* Fold function call to builtin mempcpy. Return 6277 NULL_TREE if no simplification can be made. */ 6278 6279static tree 6280fold_builtin_mempcpy (tree exp) 6281{ 6282 tree arglist = TREE_OPERAND (exp, 1); 6283 tree dest, src, len; 6284 6285 if (!validate_arglist (arglist, 6286 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6287 return 0; 6288 6289 dest = TREE_VALUE (arglist); 6290 src = TREE_VALUE (TREE_CHAIN (arglist)); 6291 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 6292 6293 /* If the LEN parameter is zero, return DEST. */ 6294 if (integer_zerop (len)) 6295 return omit_one_operand (TREE_TYPE (exp), dest, src); 6296 6297 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */ 6298 if (operand_equal_p (src, dest, 0)) 6299 { 6300 tree temp = convert (TREE_TYPE (dest), len); 6301 temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len)); 6302 return convert (TREE_TYPE (exp), temp); 6303 } 6304 6305 return 0; 6306} 6307 6308/* Fold function call to builtin memmove. Return 6309 NULL_TREE if no simplification can be made. */ 6310 6311static tree 6312fold_builtin_memmove (tree exp) 6313{ 6314 tree arglist = TREE_OPERAND (exp, 1); 6315 tree dest, src, len; 6316 6317 if (!validate_arglist (arglist, 6318 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6319 return 0; 6320 6321 dest = TREE_VALUE (arglist); 6322 src = TREE_VALUE (TREE_CHAIN (arglist)); 6323 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 6324 6325 /* If the LEN parameter is zero, return DEST. */ 6326 if (integer_zerop (len)) 6327 return omit_one_operand (TREE_TYPE (exp), dest, src); 6328 6329 /* If SRC and DEST are the same (and not volatile), return DEST. */ 6330 if (operand_equal_p (src, dest, 0)) 6331 return omit_one_operand (TREE_TYPE (exp), dest, len); 6332 6333 return 0; 6334} 6335 6336/* Fold function call to builtin strcpy. Return 6337 NULL_TREE if no simplification can be made. */ 6338 6339static tree 6340fold_builtin_strcpy (tree exp) 6341{ 6342 tree arglist = TREE_OPERAND (exp, 1); 6343 tree dest, src; 6344 6345 if (!validate_arglist (arglist, 6346 POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 6347 return 0; 6348 6349 dest = TREE_VALUE (arglist); 6350 src = TREE_VALUE (TREE_CHAIN (arglist)); 6351 6352 /* If SRC and DEST are the same (and not volatile), return DEST. */ 6353 if (operand_equal_p (src, dest, 0)) 6354 return convert (TREE_TYPE (exp), dest); 6355 6356 return 0; 6357} 6358 6359/* Fold function call to builtin strncpy. Return 6360 NULL_TREE if no simplification can be made. */ 6361 6362static tree 6363fold_builtin_strncpy (tree exp) 6364{ 6365 tree arglist = TREE_OPERAND (exp, 1); 6366 tree dest, src, len; 6367 6368 if (!validate_arglist (arglist, 6369 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6370 return 0; 6371 6372 dest = TREE_VALUE (arglist); 6373 src = TREE_VALUE (TREE_CHAIN (arglist)); 6374 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 6375 6376 /* If the LEN parameter is zero, return DEST. */ 6377 if (integer_zerop (len)) 6378 return omit_one_operand (TREE_TYPE (exp), dest, src); 6379 6380 return 0; 6381} 6382 6383/* Fold function call to builtin memcmp. Return 6384 NULL_TREE if no simplification can be made. */ 6385 6386static tree 6387fold_builtin_memcmp (tree exp) 6388{ 6389 tree arglist = TREE_OPERAND (exp, 1); 6390 tree arg1, arg2, len; 6391 6392 if (!validate_arglist (arglist, 6393 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6394 return 0; 6395 6396 arg1 = TREE_VALUE (arglist); 6397 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 6398 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 6399 6400 /* If the LEN parameter is zero, return zero. */ 6401 if (integer_zerop (len)) 6402 { 6403 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2); 6404 return omit_one_operand (TREE_TYPE (exp), temp, arg1); 6405 } 6406 6407 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 6408 if (operand_equal_p (arg1, arg2, 0)) 6409 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len); 6410 6411 return 0; 6412} 6413 6414/* Fold function call to builtin strcmp. Return 6415 NULL_TREE if no simplification can be made. */ 6416 6417static tree 6418fold_builtin_strcmp (tree exp) 6419{ 6420 tree arglist = TREE_OPERAND (exp, 1); 6421 tree arg1, arg2; 6422 const char *p1, *p2; 6423 6424 if (!validate_arglist (arglist, 6425 POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) 6426 return 0; 6427 6428 arg1 = TREE_VALUE (arglist); 6429 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 6430 6431 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 6432 if (operand_equal_p (arg1, arg2, 0)) 6433 return convert (TREE_TYPE (exp), integer_zero_node); 6434 6435 p1 = c_getstr (arg1); 6436 p2 = c_getstr (arg2); 6437 6438 if (p1 && p2) 6439 { 6440 tree temp; 6441 const int i = strcmp (p1, p2); 6442 if (i < 0) 6443 temp = integer_minus_one_node; 6444 else if (i > 0) 6445 temp = integer_one_node; 6446 else 6447 temp = integer_zero_node; 6448 return convert (TREE_TYPE (exp), temp); 6449 } 6450 6451 return 0; 6452} 6453 6454/* Fold function call to builtin strncmp. Return 6455 NULL_TREE if no simplification can be made. */ 6456 6457static tree 6458fold_builtin_strncmp (tree exp) 6459{ 6460 tree arglist = TREE_OPERAND (exp, 1); 6461 tree arg1, arg2, len; 6462 const char *p1, *p2; 6463 6464 if (!validate_arglist (arglist, 6465 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) 6466 return 0; 6467 6468 arg1 = TREE_VALUE (arglist); 6469 arg2 = TREE_VALUE (TREE_CHAIN (arglist)); 6470 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); 6471 6472 /* If the LEN parameter is zero, return zero. */ 6473 if (integer_zerop (len)) 6474 { 6475 tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2); 6476 return omit_one_operand (TREE_TYPE (exp), temp, arg1); 6477 } 6478 6479 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */ 6480 if (operand_equal_p (arg1, arg2, 0)) 6481 return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len); 6482 6483 p1 = c_getstr (arg1); 6484 p2 = c_getstr (arg2); 6485 6486 if (host_integerp (len, 1) && p1 && p2) 6487 { 6488 tree temp; 6489 const int i = strncmp (p1, p2, tree_low_cst (len, 1)); 6490 if (i < 0) 6491 temp = integer_minus_one_node; 6492 else if (i > 0) 6493 temp = integer_one_node; 6494 else 6495 temp = integer_zero_node; 6496 return convert (TREE_TYPE (exp), temp); 6497 } 6498 6499 return 0; 6500} 6501 6502/* Used by constant folding to eliminate some builtin calls early. EXP is 6503 the CALL_EXPR of a call to a builtin function. */ 6504 6505tree 6506fold_builtin (tree exp) 6507{ 6508 tree fndecl = get_callee_fndecl (exp); 6509 tree arglist = TREE_OPERAND (exp, 1); 6510 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 6511 6512 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) 6513 return 0; 6514 6515 switch (DECL_FUNCTION_CODE (fndecl)) 6516 { 6517 case BUILT_IN_CONSTANT_P: 6518 return fold_builtin_constant_p (arglist); 6519 6520 case BUILT_IN_CLASSIFY_TYPE: 6521 return fold_builtin_classify_type (arglist); 6522 6523 case BUILT_IN_STRLEN: 6524 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) 6525 { 6526 tree len = c_strlen (TREE_VALUE (arglist), 0); 6527 if (len) 6528 { 6529 /* Convert from the internal "sizetype" type to "size_t". */ 6530 if (size_type_node) 6531 len = convert (size_type_node, len); 6532 return len; 6533 } 6534 } 6535 break; 6536 6537 case BUILT_IN_FABS: 6538 case BUILT_IN_FABSF: 6539 case BUILT_IN_FABSL: 6540 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6541 return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist))); 6542 break; 6543 6544 case BUILT_IN_CABS: 6545 case BUILT_IN_CABSF: 6546 case BUILT_IN_CABSL: 6547 return fold_builtin_cabs (fndecl, arglist, type); 6548 6549 case BUILT_IN_SQRT: 6550 case BUILT_IN_SQRTF: 6551 case BUILT_IN_SQRTL: 6552 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6553 { 6554 enum built_in_function fcode; 6555 tree arg = TREE_VALUE (arglist); 6556 6557 /* Optimize sqrt of constant value. */ 6558 if (TREE_CODE (arg) == REAL_CST 6559 && ! TREE_CONSTANT_OVERFLOW (arg)) 6560 { 6561 REAL_VALUE_TYPE r, x; 6562 6563 x = TREE_REAL_CST (arg); 6564 if (real_sqrt (&r, TYPE_MODE (type), &x) 6565 || (!flag_trapping_math && !flag_errno_math)) 6566 return build_real (type, r); 6567 } 6568 6569 /* Optimize sqrt(exp(x)) = exp(x*0.5). */ 6570 fcode = builtin_mathfn_code (arg); 6571 if (flag_unsafe_math_optimizations 6572 && (fcode == BUILT_IN_EXP 6573 || fcode == BUILT_IN_EXPF 6574 || fcode == BUILT_IN_EXPL)) 6575 { 6576 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 6577 arg = fold (build (MULT_EXPR, type, 6578 TREE_VALUE (TREE_OPERAND (arg, 1)), 6579 build_real (type, dconsthalf))); 6580 arglist = build_tree_list (NULL_TREE, arg); 6581 return build_function_call_expr (expfn, arglist); 6582 } 6583 6584 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */ 6585 if (flag_unsafe_math_optimizations 6586 && (fcode == BUILT_IN_POW 6587 || fcode == BUILT_IN_POWF 6588 || fcode == BUILT_IN_POWL)) 6589 { 6590 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); 6591 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1)); 6592 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1))); 6593 tree narg1 = fold (build (MULT_EXPR, type, arg1, 6594 build_real (type, dconsthalf))); 6595 arglist = tree_cons (NULL_TREE, arg0, 6596 build_tree_list (NULL_TREE, narg1)); 6597 return build_function_call_expr (powfn, arglist); 6598 } 6599 } 6600 break; 6601 6602 case BUILT_IN_SIN: 6603 case BUILT_IN_SINF: 6604 case BUILT_IN_SINL: 6605 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6606 { 6607 tree arg = TREE_VALUE (arglist); 6608 6609 /* Optimize sin(0.0) = 0.0. */ 6610 if (real_zerop (arg)) 6611 return arg; 6612 } 6613 break; 6614 6615 case BUILT_IN_COS: 6616 case BUILT_IN_COSF: 6617 case BUILT_IN_COSL: 6618 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6619 { 6620 tree arg = TREE_VALUE (arglist); 6621 6622 /* Optimize cos(0.0) = 1.0. */ 6623 if (real_zerop (arg)) 6624 return build_real (type, dconst1); 6625 6626 /* Optimize cos(-x) into cos(x). */ 6627 if (TREE_CODE (arg) == NEGATE_EXPR) 6628 { 6629 tree arglist = build_tree_list (NULL_TREE, 6630 TREE_OPERAND (arg, 0)); 6631 return build_function_call_expr (fndecl, arglist); 6632 } 6633 } 6634 break; 6635 6636 case BUILT_IN_EXP: 6637 case BUILT_IN_EXPF: 6638 case BUILT_IN_EXPL: 6639 return fold_builtin_exponent (exp, &dconste); 6640 case BUILT_IN_EXP2: 6641 case BUILT_IN_EXP2F: 6642 case BUILT_IN_EXP2L: 6643 return fold_builtin_exponent (exp, &dconst2); 6644 case BUILT_IN_EXP10: 6645 case BUILT_IN_EXP10F: 6646 case BUILT_IN_EXP10L: 6647 case BUILT_IN_POW10: 6648 case BUILT_IN_POW10F: 6649 case BUILT_IN_POW10L: 6650 return fold_builtin_exponent (exp, &dconst10); 6651 case BUILT_IN_LOG: 6652 case BUILT_IN_LOGF: 6653 case BUILT_IN_LOGL: 6654 return fold_builtin_logarithm (exp, &dconste); 6655 break; 6656 case BUILT_IN_LOG2: 6657 case BUILT_IN_LOG2F: 6658 case BUILT_IN_LOG2L: 6659 return fold_builtin_logarithm (exp, &dconst2); 6660 break; 6661 case BUILT_IN_LOG10: 6662 case BUILT_IN_LOG10F: 6663 case BUILT_IN_LOG10L: 6664 return fold_builtin_logarithm (exp, &dconst10); 6665 break; 6666 6667 case BUILT_IN_TAN: 6668 case BUILT_IN_TANF: 6669 case BUILT_IN_TANL: 6670 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6671 { 6672 enum built_in_function fcode; 6673 tree arg = TREE_VALUE (arglist); 6674 6675 /* Optimize tan(0.0) = 0.0. */ 6676 if (real_zerop (arg)) 6677 return arg; 6678 6679 /* Optimize tan(atan(x)) = x. */ 6680 fcode = builtin_mathfn_code (arg); 6681 if (flag_unsafe_math_optimizations 6682 && (fcode == BUILT_IN_ATAN 6683 || fcode == BUILT_IN_ATANF 6684 || fcode == BUILT_IN_ATANL)) 6685 return TREE_VALUE (TREE_OPERAND (arg, 1)); 6686 } 6687 break; 6688 6689 case BUILT_IN_ATAN: 6690 case BUILT_IN_ATANF: 6691 case BUILT_IN_ATANL: 6692 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) 6693 { 6694 tree arg = TREE_VALUE (arglist); 6695 6696 /* Optimize atan(0.0) = 0.0. */ 6697 if (real_zerop (arg)) 6698 return arg; 6699 6700 /* Optimize atan(1.0) = pi/4. */ 6701 if (real_onep (arg)) 6702 { 6703 REAL_VALUE_TYPE cst; 6704 6705 real_convert (&cst, TYPE_MODE (type), &dconstpi); 6706 cst.exp -= 2; 6707 return build_real (type, cst); 6708 } 6709 } 6710 break; 6711 6712 case BUILT_IN_POW: 6713 case BUILT_IN_POWF: 6714 case BUILT_IN_POWL: 6715 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) 6716 { 6717 enum built_in_function fcode; 6718 tree arg0 = TREE_VALUE (arglist); 6719 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); 6720 6721 /* Optimize pow(1.0,y) = 1.0. */ 6722 if (real_onep (arg0)) 6723 return omit_one_operand (type, build_real (type, dconst1), arg1); 6724 6725 if (TREE_CODE (arg1) == REAL_CST 6726 && ! TREE_CONSTANT_OVERFLOW (arg1)) 6727 { 6728 REAL_VALUE_TYPE c; 6729 c = TREE_REAL_CST (arg1); 6730 6731 /* Optimize pow(x,0.0) = 1.0. */ 6732 if (REAL_VALUES_EQUAL (c, dconst0)) 6733 return omit_one_operand (type, build_real (type, dconst1), 6734 arg0); 6735 6736 /* Optimize pow(x,1.0) = x. */ 6737 if (REAL_VALUES_EQUAL (c, dconst1)) 6738 return arg0; 6739 6740 /* Optimize pow(x,-1.0) = 1.0/x. */ 6741 if (REAL_VALUES_EQUAL (c, dconstm1)) 6742 return fold (build (RDIV_EXPR, type, 6743 build_real (type, dconst1), 6744 arg0)); 6745 6746 /* Optimize pow(x,0.5) = sqrt(x). */ 6747 if (flag_unsafe_math_optimizations 6748 && REAL_VALUES_EQUAL (c, dconsthalf)) 6749 { 6750 tree sqrtfn; 6751 6752 fcode = DECL_FUNCTION_CODE (fndecl); 6753 if (fcode == BUILT_IN_POW) 6754 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT]; 6755 else if (fcode == BUILT_IN_POWF) 6756 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF]; 6757 else if (fcode == BUILT_IN_POWL) 6758 sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL]; 6759 else 6760 sqrtfn = NULL_TREE; 6761 6762 if (sqrtfn != NULL_TREE) 6763 { 6764 tree arglist = build_tree_list (NULL_TREE, arg0); 6765 return build_function_call_expr (sqrtfn, arglist); 6766 } 6767 } 6768 6769 /* Attempt to evaluate pow at compile-time. */ 6770 if (TREE_CODE (arg0) == REAL_CST 6771 && ! TREE_CONSTANT_OVERFLOW (arg0)) 6772 { 6773 REAL_VALUE_TYPE cint; 6774 HOST_WIDE_INT n; 6775 6776 n = real_to_integer (&c); 6777 real_from_integer (&cint, VOIDmode, n, 6778 n < 0 ? -1 : 0, 0); 6779 if (real_identical (&c, &cint)) 6780 { 6781 REAL_VALUE_TYPE x; 6782 bool inexact; 6783 6784 x = TREE_REAL_CST (arg0); 6785 inexact = real_powi (&x, TYPE_MODE (type), &x, n); 6786 if (flag_unsafe_math_optimizations || !inexact) 6787 return build_real (type, x); 6788 } 6789 } 6790 } 6791 6792 /* Optimize pow(exp(x),y) = exp(x*y). */ 6793 fcode = builtin_mathfn_code (arg0); 6794 if (flag_unsafe_math_optimizations 6795 && (fcode == BUILT_IN_EXP 6796 || fcode == BUILT_IN_EXPF 6797 || fcode == BUILT_IN_EXPL)) 6798 { 6799 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0); 6800 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1)); 6801 arg = fold (build (MULT_EXPR, type, arg, arg1)); 6802 arglist = build_tree_list (NULL_TREE, arg); 6803 return build_function_call_expr (expfn, arglist); 6804 } 6805 6806 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */ 6807 if (flag_unsafe_math_optimizations 6808 && (fcode == BUILT_IN_SQRT 6809 || fcode == BUILT_IN_SQRTF 6810 || fcode == BUILT_IN_SQRTL)) 6811 { 6812 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1)); 6813 tree narg1 = fold (build (MULT_EXPR, type, arg1, 6814 build_real (type, dconsthalf))); 6815 6816 arglist = tree_cons (NULL_TREE, narg0, 6817 build_tree_list (NULL_TREE, narg1)); 6818 return build_function_call_expr (fndecl, arglist); 6819 } 6820 6821 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */ 6822 if (flag_unsafe_math_optimizations 6823 && (fcode == BUILT_IN_POW 6824 || fcode == BUILT_IN_POWF 6825 || fcode == BUILT_IN_POWL)) 6826 { 6827 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1)); 6828 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1))); 6829 tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1)); 6830 arglist = tree_cons (NULL_TREE, arg00, 6831 build_tree_list (NULL_TREE, narg1)); 6832 return build_function_call_expr (fndecl, arglist); 6833 } 6834 } 6835 break; 6836 6837 case BUILT_IN_INF: 6838 case BUILT_IN_INFF: 6839 case BUILT_IN_INFL: 6840 return fold_builtin_inf (type, true); 6841 6842 case BUILT_IN_HUGE_VAL: 6843 case BUILT_IN_HUGE_VALF: 6844 case BUILT_IN_HUGE_VALL: 6845 return fold_builtin_inf (type, false); 6846 6847 case BUILT_IN_NAN: 6848 case BUILT_IN_NANF: 6849 case BUILT_IN_NANL: 6850 return fold_builtin_nan (arglist, type, true); 6851 6852 case BUILT_IN_NANS: 6853 case BUILT_IN_NANSF: 6854 case BUILT_IN_NANSL: 6855 return fold_builtin_nan (arglist, type, false); 6856 6857 case BUILT_IN_FLOOR: 6858 case BUILT_IN_FLOORF: 6859 case BUILT_IN_FLOORL: 6860 return fold_builtin_floor (exp); 6861 6862 case BUILT_IN_CEIL: 6863 case BUILT_IN_CEILF: 6864 case BUILT_IN_CEILL: 6865 return fold_builtin_ceil (exp); 6866 6867 case BUILT_IN_TRUNC: 6868 case BUILT_IN_TRUNCF: 6869 case BUILT_IN_TRUNCL: 6870 return fold_builtin_trunc (exp); 6871 6872 case BUILT_IN_ROUND: 6873 case BUILT_IN_ROUNDF: 6874 case BUILT_IN_ROUNDL: 6875 case BUILT_IN_NEARBYINT: 6876 case BUILT_IN_NEARBYINTF: 6877 case BUILT_IN_NEARBYINTL: 6878 return fold_trunc_transparent_mathfn (exp); 6879 6880 case BUILT_IN_FFS: 6881 case BUILT_IN_FFSL: 6882 case BUILT_IN_FFSLL: 6883 case BUILT_IN_CLZ: 6884 case BUILT_IN_CLZL: 6885 case BUILT_IN_CLZLL: 6886 case BUILT_IN_CTZ: 6887 case BUILT_IN_CTZL: 6888 case BUILT_IN_CTZLL: 6889 case BUILT_IN_POPCOUNT: 6890 case BUILT_IN_POPCOUNTL: 6891 case BUILT_IN_POPCOUNTLL: 6892 case BUILT_IN_PARITY: 6893 case BUILT_IN_PARITYL: 6894 case BUILT_IN_PARITYLL: 6895 return fold_builtin_bitop (exp); 6896 6897 case BUILT_IN_MEMCPY: 6898 return fold_builtin_memcpy (exp); 6899 6900 case BUILT_IN_MEMPCPY: 6901 return fold_builtin_mempcpy (exp); 6902 6903 case BUILT_IN_MEMMOVE: 6904 return fold_builtin_memmove (exp); 6905 6906 case BUILT_IN_STRCPY: 6907 return fold_builtin_strcpy (exp); 6908 6909 case BUILT_IN_STRNCPY: 6910 return fold_builtin_strncpy (exp); 6911 6912 case BUILT_IN_MEMCMP: 6913 return fold_builtin_memcmp (exp); 6914 6915 case BUILT_IN_STRCMP: 6916 return fold_builtin_strcmp (exp); 6917 6918 case BUILT_IN_STRNCMP: 6919 return fold_builtin_strncmp (exp); 6920 6921 default: 6922 break; 6923 } 6924 6925 return 0; 6926} 6927 6928/* Conveniently construct a function call expression. */ 6929 6930tree 6931build_function_call_expr (tree fn, tree arglist) 6932{ 6933 tree call_expr; 6934 6935 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); 6936 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)), 6937 call_expr, arglist); 6938 return fold (call_expr); 6939} 6940 6941/* This function validates the types of a function call argument list 6942 represented as a tree chain of parameters against a specified list 6943 of tree_codes. If the last specifier is a 0, that represents an 6944 ellipses, otherwise the last specifier must be a VOID_TYPE. */ 6945 6946static int 6947validate_arglist (tree arglist, ...) 6948{ 6949 enum tree_code code; 6950 int res = 0; 6951 va_list ap; 6952 6953 va_start (ap, arglist); 6954 6955 do 6956 { 6957 code = va_arg (ap, enum tree_code); 6958 switch (code) 6959 { 6960 case 0: 6961 /* This signifies an ellipses, any further arguments are all ok. */ 6962 res = 1; 6963 goto end; 6964 case VOID_TYPE: 6965 /* This signifies an endlink, if no arguments remain, return 6966 true, otherwise return false. */ 6967 res = arglist == 0; 6968 goto end; 6969 default: 6970 /* If no parameters remain or the parameter's code does not 6971 match the specified code, return false. Otherwise continue 6972 checking any remaining arguments. */ 6973 if (arglist == 0 6974 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist)))) 6975 goto end; 6976 break; 6977 } 6978 arglist = TREE_CHAIN (arglist); 6979 } 6980 while (1); 6981 6982 /* We need gotos here since we can only have one VA_CLOSE in a 6983 function. */ 6984 end: ; 6985 va_end (ap); 6986 6987 return res; 6988} 6989 6990/* Default target-specific builtin expander that does nothing. */ 6991 6992rtx 6993default_expand_builtin (tree exp ATTRIBUTE_UNUSED, 6994 rtx target ATTRIBUTE_UNUSED, 6995 rtx subtarget ATTRIBUTE_UNUSED, 6996 enum machine_mode mode ATTRIBUTE_UNUSED, 6997 int ignore ATTRIBUTE_UNUSED) 6998{ 6999 return NULL_RTX; 7000} 7001 7002/* Instantiate all remaining CONSTANT_P_RTX nodes. */ 7003 7004void 7005purge_builtin_constant_p (void) 7006{ 7007 rtx insn, set, arg, new, note; 7008 7009 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 7010 if (INSN_P (insn) 7011 && (set = single_set (insn)) != NULL_RTX 7012 && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX 7013 || (GET_CODE (arg) == SUBREG 7014 && (GET_CODE (arg = SUBREG_REG (arg)) 7015 == CONSTANT_P_RTX)))) 7016 { 7017 arg = XEXP (arg, 0); 7018 new = CONSTANT_P (arg) ? const1_rtx : const0_rtx; 7019 validate_change (insn, &SET_SRC (set), new, 0); 7020 7021 /* Remove the REG_EQUAL note from the insn. */ 7022 if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0) 7023 remove_note (insn, note); 7024 } 7025} 7026 7027/* Returns true is EXP represents data that would potentially reside 7028 in a readonly section. */ 7029 7030static bool 7031readonly_data_expr (tree exp) 7032{ 7033 STRIP_NOPS (exp); 7034 7035 if (TREE_CODE (exp) == ADDR_EXPR) 7036 return decl_readonly_section (TREE_OPERAND (exp, 0), 0); 7037 else 7038 return false; 7039} 7040