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