007-01-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
[official-gcc.git] / gcc / builtins.c
bloba2f540a416f636c25d395f81f2238e83eadf9e5c
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "machmode.h"
28 #include "real.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "tree-gimple.h"
32 #include "flags.h"
33 #include "regs.h"
34 #include "hard-reg-set.h"
35 #include "except.h"
36 #include "function.h"
37 #include "insn-config.h"
38 #include "expr.h"
39 #include "optabs.h"
40 #include "libfuncs.h"
41 #include "recog.h"
42 #include "output.h"
43 #include "typeclass.h"
44 #include "toplev.h"
45 #include "predict.h"
46 #include "tm_p.h"
47 #include "target.h"
48 #include "langhooks.h"
49 #include "basic-block.h"
50 #include "tree-mudflap.h"
51 #include "tree-flow.h"
52 #include "value-prof.h"
54 #ifndef PAD_VARARGS_DOWN
55 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
56 #endif
58 /* Define the names of the builtin function types and codes. */
59 const char *const built_in_class_names[4]
60 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
62 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
63 const char * built_in_names[(int) END_BUILTINS] =
65 #include "builtins.def"
67 #undef DEF_BUILTIN
69 /* Setup an array of _DECL trees, make sure each element is
70 initialized to NULL_TREE. */
71 tree built_in_decls[(int) END_BUILTINS];
72 /* Declarations used when constructing the builtin implicitly in the compiler.
73 It may be NULL_TREE when this is invalid (for instance runtime is not
74 required to implement the function call in all cases). */
75 tree implicit_built_in_decls[(int) END_BUILTINS];
77 static const char *c_getstr (tree);
78 static rtx c_readstr (const char *, enum machine_mode);
79 static int target_char_cast (tree, char *);
80 static rtx get_memory_rtx (tree, tree);
81 static int apply_args_size (void);
82 static int apply_result_size (void);
83 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
84 static rtx result_vector (int, rtx);
85 #endif
86 static void expand_builtin_update_setjmp_buf (rtx);
87 static void expand_builtin_prefetch (tree);
88 static rtx expand_builtin_apply_args (void);
89 static rtx expand_builtin_apply_args_1 (void);
90 static rtx expand_builtin_apply (rtx, rtx, rtx);
91 static void expand_builtin_return (rtx);
92 static enum type_class type_to_class (tree);
93 static rtx expand_builtin_classify_type (tree);
94 static void expand_errno_check (tree, rtx);
95 static rtx expand_builtin_mathfn (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
97 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
98 static rtx expand_builtin_sincos (tree);
99 static rtx expand_builtin_cexpi (tree, rtx, rtx);
100 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
101 static rtx expand_builtin_int_roundingfn_2 (tree, rtx, rtx);
102 static rtx expand_builtin_args_info (tree);
103 static rtx expand_builtin_next_arg (void);
104 static rtx expand_builtin_va_start (tree);
105 static rtx expand_builtin_va_end (tree);
106 static rtx expand_builtin_va_copy (tree);
107 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
108 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
110 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
111 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
115 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
117 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode);
118 static rtx expand_builtin_bcopy (tree);
119 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
120 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
121 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
123 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
124 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
125 static rtx expand_builtin_bzero (tree);
126 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
130 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
131 static rtx expand_builtin_alloca (tree, rtx);
132 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
133 static rtx expand_builtin_frame_address (tree, tree);
134 static rtx expand_builtin_fputs (tree, rtx, bool);
135 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
136 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
137 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
138 static tree stabilize_va_list (tree, int);
139 static rtx expand_builtin_expect (tree, rtx);
140 static tree fold_builtin_constant_p (tree);
141 static tree fold_builtin_classify_type (tree);
142 static tree fold_builtin_strlen (tree);
143 static tree fold_builtin_inf (tree, int);
144 static tree fold_builtin_nan (tree, tree, int);
145 static bool integer_valued_real_p (tree);
146 static tree fold_trunc_transparent_mathfn (tree, tree);
147 static bool readonly_data_expr (tree);
148 static rtx expand_builtin_fabs (tree, rtx, rtx);
149 static rtx expand_builtin_signbit (tree, rtx);
150 static tree fold_builtin_sqrt (tree, tree);
151 static tree fold_builtin_cbrt (tree, tree);
152 static tree fold_builtin_pow (tree, tree, tree);
153 static tree fold_builtin_powi (tree, tree, tree);
154 static tree fold_builtin_cos (tree, tree, tree);
155 static tree fold_builtin_cosh (tree, tree, tree);
156 static tree fold_builtin_tan (tree, tree);
157 static tree fold_builtin_trunc (tree, tree);
158 static tree fold_builtin_floor (tree, tree);
159 static tree fold_builtin_ceil (tree, tree);
160 static tree fold_builtin_round (tree, tree);
161 static tree fold_builtin_int_roundingfn (tree, tree);
162 static tree fold_builtin_bitop (tree, tree);
163 static tree fold_builtin_memory_op (tree, tree, bool, int);
164 static tree fold_builtin_strchr (tree, tree);
165 static tree fold_builtin_memcmp (tree);
166 static tree fold_builtin_strcmp (tree);
167 static tree fold_builtin_strncmp (tree);
168 static tree fold_builtin_signbit (tree, tree);
169 static tree fold_builtin_copysign (tree, tree, tree);
170 static tree fold_builtin_isascii (tree);
171 static tree fold_builtin_toascii (tree);
172 static tree fold_builtin_isdigit (tree);
173 static tree fold_builtin_fabs (tree, tree);
174 static tree fold_builtin_abs (tree, tree);
175 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
176 enum tree_code);
177 static tree fold_builtin_1 (tree, tree, bool);
179 static tree fold_builtin_strpbrk (tree, tree);
180 static tree fold_builtin_strstr (tree, tree);
181 static tree fold_builtin_strrchr (tree, tree);
182 static tree fold_builtin_strcat (tree);
183 static tree fold_builtin_strncat (tree);
184 static tree fold_builtin_strspn (tree);
185 static tree fold_builtin_strcspn (tree);
186 static tree fold_builtin_sprintf (tree, int);
188 static rtx expand_builtin_object_size (tree);
189 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
190 enum built_in_function);
191 static void maybe_emit_chk_warning (tree, enum built_in_function);
192 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
193 static tree fold_builtin_object_size (tree);
194 static tree fold_builtin_strcat_chk (tree, tree);
195 static tree fold_builtin_strncat_chk (tree, tree);
196 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
197 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
198 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
199 static bool init_target_chars (void);
201 static unsigned HOST_WIDE_INT target_newline;
202 static unsigned HOST_WIDE_INT target_percent;
203 static unsigned HOST_WIDE_INT target_c;
204 static unsigned HOST_WIDE_INT target_s;
205 static char target_percent_c[3];
206 static char target_percent_s[3];
207 static char target_percent_s_newline[4];
208 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
209 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
210 static tree do_mpfr_arg2 (tree, tree, tree,
211 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
212 static tree do_mpfr_arg3 (tree, tree, tree, tree,
213 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
214 static tree do_mpfr_sincos (tree, tree, tree);
216 /* Return true if NODE should be considered for inline expansion regardless
217 of the optimization level. This means whenever a function is invoked with
218 its "internal" name, which normally contains the prefix "__builtin". */
220 static bool called_as_built_in (tree node)
222 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
223 if (strncmp (name, "__builtin_", 10) == 0)
224 return true;
225 if (strncmp (name, "__sync_", 7) == 0)
226 return true;
227 return false;
230 /* Return the alignment in bits of EXP, a pointer valued expression.
231 But don't return more than MAX_ALIGN no matter what.
232 The alignment returned is, by default, the alignment of the thing that
233 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
235 Otherwise, look at the expression to see if we can do better, i.e., if the
236 expression is actually pointing at an object whose alignment is tighter. */
239 get_pointer_alignment (tree exp, unsigned int max_align)
241 unsigned int align, inner;
243 /* We rely on TER to compute accurate alignment information. */
244 if (!(optimize && flag_tree_ter))
245 return 0;
247 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
248 return 0;
250 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
251 align = MIN (align, max_align);
253 while (1)
255 switch (TREE_CODE (exp))
257 case NOP_EXPR:
258 case CONVERT_EXPR:
259 case NON_LVALUE_EXPR:
260 exp = TREE_OPERAND (exp, 0);
261 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
262 return align;
264 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
265 align = MIN (inner, max_align);
266 break;
268 case PLUS_EXPR:
269 /* If sum of pointer + int, restrict our maximum alignment to that
270 imposed by the integer. If not, we can't do any better than
271 ALIGN. */
272 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
273 return align;
275 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
276 & (max_align / BITS_PER_UNIT - 1))
277 != 0)
278 max_align >>= 1;
280 exp = TREE_OPERAND (exp, 0);
281 break;
283 case ADDR_EXPR:
284 /* See what we are pointing at and look at its alignment. */
285 exp = TREE_OPERAND (exp, 0);
286 inner = max_align;
287 if (handled_component_p (exp))
289 HOST_WIDE_INT bitsize, bitpos;
290 tree offset;
291 enum machine_mode mode;
292 int unsignedp, volatilep;
294 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
295 &mode, &unsignedp, &volatilep, true);
296 if (bitpos)
297 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
298 if (offset && TREE_CODE (offset) == PLUS_EXPR
299 && host_integerp (TREE_OPERAND (offset, 1), 1))
301 /* Any overflow in calculating offset_bits won't change
302 the alignment. */
303 unsigned offset_bits
304 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
305 * BITS_PER_UNIT);
307 if (offset_bits)
308 inner = MIN (inner, (offset_bits & -offset_bits));
309 offset = TREE_OPERAND (offset, 0);
311 if (offset && TREE_CODE (offset) == MULT_EXPR
312 && host_integerp (TREE_OPERAND (offset, 1), 1))
314 /* Any overflow in calculating offset_factor won't change
315 the alignment. */
316 unsigned offset_factor
317 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
318 * BITS_PER_UNIT);
320 if (offset_factor)
321 inner = MIN (inner, (offset_factor & -offset_factor));
323 else if (offset)
324 inner = MIN (inner, BITS_PER_UNIT);
326 if (TREE_CODE (exp) == FUNCTION_DECL)
327 align = FUNCTION_BOUNDARY;
328 else if (DECL_P (exp))
329 align = MIN (inner, DECL_ALIGN (exp));
330 #ifdef CONSTANT_ALIGNMENT
331 else if (CONSTANT_CLASS_P (exp))
332 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
333 #endif
334 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
335 || TREE_CODE (exp) == INDIRECT_REF)
336 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
337 else
338 align = MIN (align, inner);
339 return MIN (align, max_align);
341 default:
342 return align;
347 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
348 way, because it could contain a zero byte in the middle.
349 TREE_STRING_LENGTH is the size of the character array, not the string.
351 ONLY_VALUE should be nonzero if the result is not going to be emitted
352 into the instruction stream and zero if it is going to be expanded.
353 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
354 is returned, otherwise NULL, since
355 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
356 evaluate the side-effects.
358 The value returned is of type `ssizetype'.
360 Unfortunately, string_constant can't access the values of const char
361 arrays with initializers, so neither can we do so here. */
363 tree
364 c_strlen (tree src, int only_value)
366 tree offset_node;
367 HOST_WIDE_INT offset;
368 int max;
369 const char *ptr;
371 STRIP_NOPS (src);
372 if (TREE_CODE (src) == COND_EXPR
373 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
375 tree len1, len2;
377 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
378 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
379 if (tree_int_cst_equal (len1, len2))
380 return len1;
383 if (TREE_CODE (src) == COMPOUND_EXPR
384 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
385 return c_strlen (TREE_OPERAND (src, 1), only_value);
387 src = string_constant (src, &offset_node);
388 if (src == 0)
389 return 0;
391 max = TREE_STRING_LENGTH (src) - 1;
392 ptr = TREE_STRING_POINTER (src);
394 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
396 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
397 compute the offset to the following null if we don't know where to
398 start searching for it. */
399 int i;
401 for (i = 0; i < max; i++)
402 if (ptr[i] == 0)
403 return 0;
405 /* We don't know the starting offset, but we do know that the string
406 has no internal zero bytes. We can assume that the offset falls
407 within the bounds of the string; otherwise, the programmer deserves
408 what he gets. Subtract the offset from the length of the string,
409 and return that. This would perhaps not be valid if we were dealing
410 with named arrays in addition to literal string constants. */
412 return size_diffop (size_int (max), offset_node);
415 /* We have a known offset into the string. Start searching there for
416 a null character if we can represent it as a single HOST_WIDE_INT. */
417 if (offset_node == 0)
418 offset = 0;
419 else if (! host_integerp (offset_node, 0))
420 offset = -1;
421 else
422 offset = tree_low_cst (offset_node, 0);
424 /* If the offset is known to be out of bounds, warn, and call strlen at
425 runtime. */
426 if (offset < 0 || offset > max)
428 warning (0, "offset outside bounds of constant string");
429 return 0;
432 /* Use strlen to search for the first zero byte. Since any strings
433 constructed with build_string will have nulls appended, we win even
434 if we get handed something like (char[4])"abcd".
436 Since OFFSET is our starting index into the string, no further
437 calculation is needed. */
438 return ssize_int (strlen (ptr + offset));
441 /* Return a char pointer for a C string if it is a string constant
442 or sum of string constant and integer constant. */
444 static const char *
445 c_getstr (tree src)
447 tree offset_node;
449 src = string_constant (src, &offset_node);
450 if (src == 0)
451 return 0;
453 if (offset_node == 0)
454 return TREE_STRING_POINTER (src);
455 else if (!host_integerp (offset_node, 1)
456 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
457 return 0;
459 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
462 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
463 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
465 static rtx
466 c_readstr (const char *str, enum machine_mode mode)
468 HOST_WIDE_INT c[2];
469 HOST_WIDE_INT ch;
470 unsigned int i, j;
472 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
474 c[0] = 0;
475 c[1] = 0;
476 ch = 1;
477 for (i = 0; i < GET_MODE_SIZE (mode); i++)
479 j = i;
480 if (WORDS_BIG_ENDIAN)
481 j = GET_MODE_SIZE (mode) - i - 1;
482 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
483 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
484 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
485 j *= BITS_PER_UNIT;
486 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
488 if (ch)
489 ch = (unsigned char) str[i];
490 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
492 return immed_double_const (c[0], c[1], mode);
495 /* Cast a target constant CST to target CHAR and if that value fits into
496 host char type, return zero and put that value into variable pointed to by
497 P. */
499 static int
500 target_char_cast (tree cst, char *p)
502 unsigned HOST_WIDE_INT val, hostval;
504 if (!host_integerp (cst, 1)
505 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
506 return 1;
508 val = tree_low_cst (cst, 1);
509 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
510 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
512 hostval = val;
513 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
514 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
516 if (val != hostval)
517 return 1;
519 *p = hostval;
520 return 0;
523 /* Similar to save_expr, but assumes that arbitrary code is not executed
524 in between the multiple evaluations. In particular, we assume that a
525 non-addressable local variable will not be modified. */
527 static tree
528 builtin_save_expr (tree exp)
530 if (TREE_ADDRESSABLE (exp) == 0
531 && (TREE_CODE (exp) == PARM_DECL
532 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
533 return exp;
535 return save_expr (exp);
538 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
539 times to get the address of either a higher stack frame, or a return
540 address located within it (depending on FNDECL_CODE). */
542 static rtx
543 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
545 int i;
547 #ifdef INITIAL_FRAME_ADDRESS_RTX
548 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
549 #else
550 rtx tem;
552 /* For a zero count with __builtin_return_address, we don't care what
553 frame address we return, because target-specific definitions will
554 override us. Therefore frame pointer elimination is OK, and using
555 the soft frame pointer is OK.
557 For a nonzero count, or a zero count with __builtin_frame_address,
558 we require a stable offset from the current frame pointer to the
559 previous one, so we must use the hard frame pointer, and
560 we must disable frame pointer elimination. */
561 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
562 tem = frame_pointer_rtx;
563 else
565 tem = hard_frame_pointer_rtx;
567 /* Tell reload not to eliminate the frame pointer. */
568 current_function_accesses_prior_frames = 1;
570 #endif
572 /* Some machines need special handling before we can access
573 arbitrary frames. For example, on the SPARC, we must first flush
574 all register windows to the stack. */
575 #ifdef SETUP_FRAME_ADDRESSES
576 if (count > 0)
577 SETUP_FRAME_ADDRESSES ();
578 #endif
580 /* On the SPARC, the return address is not in the frame, it is in a
581 register. There is no way to access it off of the current frame
582 pointer, but it can be accessed off the previous frame pointer by
583 reading the value from the register window save area. */
584 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
585 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
586 count--;
587 #endif
589 /* Scan back COUNT frames to the specified frame. */
590 for (i = 0; i < count; i++)
592 /* Assume the dynamic chain pointer is in the word that the
593 frame address points to, unless otherwise specified. */
594 #ifdef DYNAMIC_CHAIN_ADDRESS
595 tem = DYNAMIC_CHAIN_ADDRESS (tem);
596 #endif
597 tem = memory_address (Pmode, tem);
598 tem = gen_frame_mem (Pmode, tem);
599 tem = copy_to_reg (tem);
602 /* For __builtin_frame_address, return what we've got. But, on
603 the SPARC for example, we may have to add a bias. */
604 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
605 #ifdef FRAME_ADDR_RTX
606 return FRAME_ADDR_RTX (tem);
607 #else
608 return tem;
609 #endif
611 /* For __builtin_return_address, get the return address from that frame. */
612 #ifdef RETURN_ADDR_RTX
613 tem = RETURN_ADDR_RTX (count, tem);
614 #else
615 tem = memory_address (Pmode,
616 plus_constant (tem, GET_MODE_SIZE (Pmode)));
617 tem = gen_frame_mem (Pmode, tem);
618 #endif
619 return tem;
622 /* Alias set used for setjmp buffer. */
623 static HOST_WIDE_INT setjmp_alias_set = -1;
625 /* Construct the leading half of a __builtin_setjmp call. Control will
626 return to RECEIVER_LABEL. This is also called directly by the SJLJ
627 exception handling code. */
629 void
630 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
632 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
633 rtx stack_save;
634 rtx mem;
636 if (setjmp_alias_set == -1)
637 setjmp_alias_set = new_alias_set ();
639 buf_addr = convert_memory_address (Pmode, buf_addr);
641 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
643 /* We store the frame pointer and the address of receiver_label in
644 the buffer and use the rest of it for the stack save area, which
645 is machine-dependent. */
647 mem = gen_rtx_MEM (Pmode, buf_addr);
648 set_mem_alias_set (mem, setjmp_alias_set);
649 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
651 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
652 set_mem_alias_set (mem, setjmp_alias_set);
654 emit_move_insn (validize_mem (mem),
655 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
657 stack_save = gen_rtx_MEM (sa_mode,
658 plus_constant (buf_addr,
659 2 * GET_MODE_SIZE (Pmode)));
660 set_mem_alias_set (stack_save, setjmp_alias_set);
661 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
663 /* If there is further processing to do, do it. */
664 #ifdef HAVE_builtin_setjmp_setup
665 if (HAVE_builtin_setjmp_setup)
666 emit_insn (gen_builtin_setjmp_setup (buf_addr));
667 #endif
669 /* Tell optimize_save_area_alloca that extra work is going to
670 need to go on during alloca. */
671 current_function_calls_setjmp = 1;
673 /* Set this so all the registers get saved in our frame; we need to be
674 able to copy the saved values for any registers from frames we unwind. */
675 current_function_has_nonlocal_label = 1;
678 /* Construct the trailing part of a __builtin_setjmp call. This is
679 also called directly by the SJLJ exception handling code. */
681 void
682 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
684 /* Clobber the FP when we get here, so we have to make sure it's
685 marked as used by this function. */
686 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
688 /* Mark the static chain as clobbered here so life information
689 doesn't get messed up for it. */
690 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
692 /* Now put in the code to restore the frame pointer, and argument
693 pointer, if needed. */
694 #ifdef HAVE_nonlocal_goto
695 if (! HAVE_nonlocal_goto)
696 #endif
698 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
699 /* This might change the hard frame pointer in ways that aren't
700 apparent to early optimization passes, so force a clobber. */
701 emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx));
704 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
705 if (fixed_regs[ARG_POINTER_REGNUM])
707 #ifdef ELIMINABLE_REGS
708 size_t i;
709 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
711 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
712 if (elim_regs[i].from == ARG_POINTER_REGNUM
713 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
714 break;
716 if (i == ARRAY_SIZE (elim_regs))
717 #endif
719 /* Now restore our arg pointer from the address at which it
720 was saved in our stack frame. */
721 emit_move_insn (virtual_incoming_args_rtx,
722 copy_to_reg (get_arg_pointer_save_area (cfun)));
725 #endif
727 #ifdef HAVE_builtin_setjmp_receiver
728 if (HAVE_builtin_setjmp_receiver)
729 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
730 else
731 #endif
732 #ifdef HAVE_nonlocal_goto_receiver
733 if (HAVE_nonlocal_goto_receiver)
734 emit_insn (gen_nonlocal_goto_receiver ());
735 else
736 #endif
737 { /* Nothing */ }
739 /* @@@ This is a kludge. Not all machine descriptions define a blockage
740 insn, but we must not allow the code we just generated to be reordered
741 by scheduling. Specifically, the update of the frame pointer must
742 happen immediately, not later. So emit an ASM_INPUT to act as blockage
743 insn. */
744 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
747 /* __builtin_longjmp is passed a pointer to an array of five words (not
748 all will be used on all machines). It operates similarly to the C
749 library function of the same name, but is more efficient. Much of
750 the code below is copied from the handling of non-local gotos. */
752 static void
753 expand_builtin_longjmp (rtx buf_addr, rtx value)
755 rtx fp, lab, stack, insn, last;
756 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
758 if (setjmp_alias_set == -1)
759 setjmp_alias_set = new_alias_set ();
761 buf_addr = convert_memory_address (Pmode, buf_addr);
763 buf_addr = force_reg (Pmode, buf_addr);
765 /* We used to store value in static_chain_rtx, but that fails if pointers
766 are smaller than integers. We instead require that the user must pass
767 a second argument of 1, because that is what builtin_setjmp will
768 return. This also makes EH slightly more efficient, since we are no
769 longer copying around a value that we don't care about. */
770 gcc_assert (value == const1_rtx);
772 last = get_last_insn ();
773 #ifdef HAVE_builtin_longjmp
774 if (HAVE_builtin_longjmp)
775 emit_insn (gen_builtin_longjmp (buf_addr));
776 else
777 #endif
779 fp = gen_rtx_MEM (Pmode, buf_addr);
780 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
781 GET_MODE_SIZE (Pmode)));
783 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
784 2 * GET_MODE_SIZE (Pmode)));
785 set_mem_alias_set (fp, setjmp_alias_set);
786 set_mem_alias_set (lab, setjmp_alias_set);
787 set_mem_alias_set (stack, setjmp_alias_set);
789 /* Pick up FP, label, and SP from the block and jump. This code is
790 from expand_goto in stmt.c; see there for detailed comments. */
791 #ifdef HAVE_nonlocal_goto
792 if (HAVE_nonlocal_goto)
793 /* We have to pass a value to the nonlocal_goto pattern that will
794 get copied into the static_chain pointer, but it does not matter
795 what that value is, because builtin_setjmp does not use it. */
796 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
797 else
798 #endif
800 lab = copy_to_reg (lab);
802 emit_insn (gen_rtx_CLOBBER (VOIDmode,
803 gen_rtx_MEM (BLKmode,
804 gen_rtx_SCRATCH (VOIDmode))));
805 emit_insn (gen_rtx_CLOBBER (VOIDmode,
806 gen_rtx_MEM (BLKmode,
807 hard_frame_pointer_rtx)));
809 emit_move_insn (hard_frame_pointer_rtx, fp);
810 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
812 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
813 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
814 emit_indirect_jump (lab);
818 /* Search backwards and mark the jump insn as a non-local goto.
819 Note that this precludes the use of __builtin_longjmp to a
820 __builtin_setjmp target in the same function. However, we've
821 already cautioned the user that these functions are for
822 internal exception handling use only. */
823 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
825 gcc_assert (insn != last);
827 if (JUMP_P (insn))
829 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
830 REG_NOTES (insn));
831 break;
833 else if (CALL_P (insn))
834 break;
838 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
839 and the address of the save area. */
841 static rtx
842 expand_builtin_nonlocal_goto (tree arglist)
844 tree t_label, t_save_area;
845 rtx r_label, r_save_area, r_fp, r_sp, insn;
847 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
848 return NULL_RTX;
850 t_label = TREE_VALUE (arglist);
851 arglist = TREE_CHAIN (arglist);
852 t_save_area = TREE_VALUE (arglist);
854 r_label = expand_normal (t_label);
855 r_label = convert_memory_address (Pmode, r_label);
856 r_save_area = expand_normal (t_save_area);
857 r_save_area = convert_memory_address (Pmode, r_save_area);
858 r_fp = gen_rtx_MEM (Pmode, r_save_area);
859 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
860 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
862 current_function_has_nonlocal_goto = 1;
864 #ifdef HAVE_nonlocal_goto
865 /* ??? We no longer need to pass the static chain value, afaik. */
866 if (HAVE_nonlocal_goto)
867 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
868 else
869 #endif
871 r_label = copy_to_reg (r_label);
873 emit_insn (gen_rtx_CLOBBER (VOIDmode,
874 gen_rtx_MEM (BLKmode,
875 gen_rtx_SCRATCH (VOIDmode))));
877 emit_insn (gen_rtx_CLOBBER (VOIDmode,
878 gen_rtx_MEM (BLKmode,
879 hard_frame_pointer_rtx)));
881 /* Restore frame pointer for containing function.
882 This sets the actual hard register used for the frame pointer
883 to the location of the function's incoming static chain info.
884 The non-local goto handler will then adjust it to contain the
885 proper value and reload the argument pointer, if needed. */
886 emit_move_insn (hard_frame_pointer_rtx, r_fp);
887 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
889 /* USE of hard_frame_pointer_rtx added for consistency;
890 not clear if really needed. */
891 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
892 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
893 emit_indirect_jump (r_label);
896 /* Search backwards to the jump insn and mark it as a
897 non-local goto. */
898 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
900 if (JUMP_P (insn))
902 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
903 const0_rtx, REG_NOTES (insn));
904 break;
906 else if (CALL_P (insn))
907 break;
910 return const0_rtx;
913 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
914 (not all will be used on all machines) that was passed to __builtin_setjmp.
915 It updates the stack pointer in that block to correspond to the current
916 stack pointer. */
918 static void
919 expand_builtin_update_setjmp_buf (rtx buf_addr)
921 enum machine_mode sa_mode = Pmode;
922 rtx stack_save;
925 #ifdef HAVE_save_stack_nonlocal
926 if (HAVE_save_stack_nonlocal)
927 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
928 #endif
929 #ifdef STACK_SAVEAREA_MODE
930 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
931 #endif
933 stack_save
934 = gen_rtx_MEM (sa_mode,
935 memory_address
936 (sa_mode,
937 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
939 #ifdef HAVE_setjmp
940 if (HAVE_setjmp)
941 emit_insn (gen_setjmp ());
942 #endif
944 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
947 /* Expand a call to __builtin_prefetch. For a target that does not support
948 data prefetch, evaluate the memory address argument in case it has side
949 effects. */
951 static void
952 expand_builtin_prefetch (tree arglist)
954 tree arg0, arg1, arg2;
955 rtx op0, op1, op2;
957 if (!validate_arglist (arglist, POINTER_TYPE, 0))
958 return;
960 arg0 = TREE_VALUE (arglist);
961 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
962 zero (read) and argument 2 (locality) defaults to 3 (high degree of
963 locality). */
964 if (TREE_CHAIN (arglist))
966 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
967 if (TREE_CHAIN (TREE_CHAIN (arglist)))
968 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
969 else
970 arg2 = build_int_cst (NULL_TREE, 3);
972 else
974 arg1 = integer_zero_node;
975 arg2 = build_int_cst (NULL_TREE, 3);
978 /* Argument 0 is an address. */
979 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
981 /* Argument 1 (read/write flag) must be a compile-time constant int. */
982 if (TREE_CODE (arg1) != INTEGER_CST)
984 error ("second argument to %<__builtin_prefetch%> must be a constant");
985 arg1 = integer_zero_node;
987 op1 = expand_normal (arg1);
988 /* Argument 1 must be either zero or one. */
989 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
991 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
992 " using zero");
993 op1 = const0_rtx;
996 /* Argument 2 (locality) must be a compile-time constant int. */
997 if (TREE_CODE (arg2) != INTEGER_CST)
999 error ("third argument to %<__builtin_prefetch%> must be a constant");
1000 arg2 = integer_zero_node;
1002 op2 = expand_normal (arg2);
1003 /* Argument 2 must be 0, 1, 2, or 3. */
1004 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1006 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1007 op2 = const0_rtx;
1010 #ifdef HAVE_prefetch
1011 if (HAVE_prefetch)
1013 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1014 (op0,
1015 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1016 || (GET_MODE (op0) != Pmode))
1018 op0 = convert_memory_address (Pmode, op0);
1019 op0 = force_reg (Pmode, op0);
1021 emit_insn (gen_prefetch (op0, op1, op2));
1023 #endif
1025 /* Don't do anything with direct references to volatile memory, but
1026 generate code to handle other side effects. */
1027 if (!MEM_P (op0) && side_effects_p (op0))
1028 emit_insn (op0);
1031 /* Get a MEM rtx for expression EXP which is the address of an operand
1032 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1033 the maximum length of the block of memory that might be accessed or
1034 NULL if unknown. */
1036 static rtx
1037 get_memory_rtx (tree exp, tree len)
1039 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1040 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1042 /* Get an expression we can use to find the attributes to assign to MEM.
1043 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1044 we can. First remove any nops. */
1045 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1046 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1047 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1048 exp = TREE_OPERAND (exp, 0);
1050 if (TREE_CODE (exp) == ADDR_EXPR)
1051 exp = TREE_OPERAND (exp, 0);
1052 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1053 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1054 else
1055 exp = NULL;
1057 /* Honor attributes derived from exp, except for the alias set
1058 (as builtin stringops may alias with anything) and the size
1059 (as stringops may access multiple array elements). */
1060 if (exp)
1062 set_mem_attributes (mem, exp, 0);
1064 /* Allow the string and memory builtins to overflow from one
1065 field into another, see http://gcc.gnu.org/PR23561.
1066 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1067 memory accessed by the string or memory builtin will fit
1068 within the field. */
1069 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1071 tree mem_expr = MEM_EXPR (mem);
1072 HOST_WIDE_INT offset = -1, length = -1;
1073 tree inner = exp;
1075 while (TREE_CODE (inner) == ARRAY_REF
1076 || TREE_CODE (inner) == NOP_EXPR
1077 || TREE_CODE (inner) == CONVERT_EXPR
1078 || TREE_CODE (inner) == NON_LVALUE_EXPR
1079 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1080 || TREE_CODE (inner) == SAVE_EXPR)
1081 inner = TREE_OPERAND (inner, 0);
1083 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1085 if (MEM_OFFSET (mem)
1086 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1087 offset = INTVAL (MEM_OFFSET (mem));
1089 if (offset >= 0 && len && host_integerp (len, 0))
1090 length = tree_low_cst (len, 0);
1092 while (TREE_CODE (inner) == COMPONENT_REF)
1094 tree field = TREE_OPERAND (inner, 1);
1095 gcc_assert (! DECL_BIT_FIELD (field));
1096 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1097 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1099 if (length >= 0
1100 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1101 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1103 HOST_WIDE_INT size
1104 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1105 /* If we can prove the memory starting at XEXP (mem, 0)
1106 and ending at XEXP (mem, 0) + LENGTH will fit into
1107 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1108 if (offset <= size
1109 && length <= size
1110 && offset + length <= size)
1111 break;
1114 if (offset >= 0
1115 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1116 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1117 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1118 / BITS_PER_UNIT;
1119 else
1121 offset = -1;
1122 length = -1;
1125 mem_expr = TREE_OPERAND (mem_expr, 0);
1126 inner = TREE_OPERAND (inner, 0);
1129 if (mem_expr == NULL)
1130 offset = -1;
1131 if (mem_expr != MEM_EXPR (mem))
1133 set_mem_expr (mem, mem_expr);
1134 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1137 set_mem_alias_set (mem, 0);
1138 set_mem_size (mem, NULL_RTX);
1141 return mem;
1144 /* Built-in functions to perform an untyped call and return. */
1146 /* For each register that may be used for calling a function, this
1147 gives a mode used to copy the register's value. VOIDmode indicates
1148 the register is not used for calling a function. If the machine
1149 has register windows, this gives only the outbound registers.
1150 INCOMING_REGNO gives the corresponding inbound register. */
1151 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1153 /* For each register that may be used for returning values, this gives
1154 a mode used to copy the register's value. VOIDmode indicates the
1155 register is not used for returning values. If the machine has
1156 register windows, this gives only the outbound registers.
1157 INCOMING_REGNO gives the corresponding inbound register. */
1158 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1160 /* For each register that may be used for calling a function, this
1161 gives the offset of that register into the block returned by
1162 __builtin_apply_args. 0 indicates that the register is not
1163 used for calling a function. */
1164 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1166 /* Return the size required for the block returned by __builtin_apply_args,
1167 and initialize apply_args_mode. */
1169 static int
1170 apply_args_size (void)
1172 static int size = -1;
1173 int align;
1174 unsigned int regno;
1175 enum machine_mode mode;
1177 /* The values computed by this function never change. */
1178 if (size < 0)
1180 /* The first value is the incoming arg-pointer. */
1181 size = GET_MODE_SIZE (Pmode);
1183 /* The second value is the structure value address unless this is
1184 passed as an "invisible" first argument. */
1185 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1186 size += GET_MODE_SIZE (Pmode);
1188 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1189 if (FUNCTION_ARG_REGNO_P (regno))
1191 mode = reg_raw_mode[regno];
1193 gcc_assert (mode != VOIDmode);
1195 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1196 if (size % align != 0)
1197 size = CEIL (size, align) * align;
1198 apply_args_reg_offset[regno] = size;
1199 size += GET_MODE_SIZE (mode);
1200 apply_args_mode[regno] = mode;
1202 else
1204 apply_args_mode[regno] = VOIDmode;
1205 apply_args_reg_offset[regno] = 0;
1208 return size;
1211 /* Return the size required for the block returned by __builtin_apply,
1212 and initialize apply_result_mode. */
1214 static int
1215 apply_result_size (void)
1217 static int size = -1;
1218 int align, regno;
1219 enum machine_mode mode;
1221 /* The values computed by this function never change. */
1222 if (size < 0)
1224 size = 0;
1226 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1227 if (FUNCTION_VALUE_REGNO_P (regno))
1229 mode = reg_raw_mode[regno];
1231 gcc_assert (mode != VOIDmode);
1233 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1234 if (size % align != 0)
1235 size = CEIL (size, align) * align;
1236 size += GET_MODE_SIZE (mode);
1237 apply_result_mode[regno] = mode;
1239 else
1240 apply_result_mode[regno] = VOIDmode;
1242 /* Allow targets that use untyped_call and untyped_return to override
1243 the size so that machine-specific information can be stored here. */
1244 #ifdef APPLY_RESULT_SIZE
1245 size = APPLY_RESULT_SIZE;
1246 #endif
1248 return size;
1251 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1252 /* Create a vector describing the result block RESULT. If SAVEP is true,
1253 the result block is used to save the values; otherwise it is used to
1254 restore the values. */
1256 static rtx
1257 result_vector (int savep, rtx result)
1259 int regno, size, align, nelts;
1260 enum machine_mode mode;
1261 rtx reg, mem;
1262 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1264 size = nelts = 0;
1265 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1266 if ((mode = apply_result_mode[regno]) != VOIDmode)
1268 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1269 if (size % align != 0)
1270 size = CEIL (size, align) * align;
1271 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1272 mem = adjust_address (result, mode, size);
1273 savevec[nelts++] = (savep
1274 ? gen_rtx_SET (VOIDmode, mem, reg)
1275 : gen_rtx_SET (VOIDmode, reg, mem));
1276 size += GET_MODE_SIZE (mode);
1278 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1280 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1282 /* Save the state required to perform an untyped call with the same
1283 arguments as were passed to the current function. */
1285 static rtx
1286 expand_builtin_apply_args_1 (void)
1288 rtx registers, tem;
1289 int size, align, regno;
1290 enum machine_mode mode;
1291 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1293 /* Create a block where the arg-pointer, structure value address,
1294 and argument registers can be saved. */
1295 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1297 /* Walk past the arg-pointer and structure value address. */
1298 size = GET_MODE_SIZE (Pmode);
1299 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1300 size += GET_MODE_SIZE (Pmode);
1302 /* Save each register used in calling a function to the block. */
1303 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1304 if ((mode = apply_args_mode[regno]) != VOIDmode)
1306 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1307 if (size % align != 0)
1308 size = CEIL (size, align) * align;
1310 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1312 emit_move_insn (adjust_address (registers, mode, size), tem);
1313 size += GET_MODE_SIZE (mode);
1316 /* Save the arg pointer to the block. */
1317 tem = copy_to_reg (virtual_incoming_args_rtx);
1318 #ifdef STACK_GROWS_DOWNWARD
1319 /* We need the pointer as the caller actually passed them to us, not
1320 as we might have pretended they were passed. Make sure it's a valid
1321 operand, as emit_move_insn isn't expected to handle a PLUS. */
1323 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1324 NULL_RTX);
1325 #endif
1326 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1328 size = GET_MODE_SIZE (Pmode);
1330 /* Save the structure value address unless this is passed as an
1331 "invisible" first argument. */
1332 if (struct_incoming_value)
1334 emit_move_insn (adjust_address (registers, Pmode, size),
1335 copy_to_reg (struct_incoming_value));
1336 size += GET_MODE_SIZE (Pmode);
1339 /* Return the address of the block. */
1340 return copy_addr_to_reg (XEXP (registers, 0));
1343 /* __builtin_apply_args returns block of memory allocated on
1344 the stack into which is stored the arg pointer, structure
1345 value address, static chain, and all the registers that might
1346 possibly be used in performing a function call. The code is
1347 moved to the start of the function so the incoming values are
1348 saved. */
1350 static rtx
1351 expand_builtin_apply_args (void)
1353 /* Don't do __builtin_apply_args more than once in a function.
1354 Save the result of the first call and reuse it. */
1355 if (apply_args_value != 0)
1356 return apply_args_value;
1358 /* When this function is called, it means that registers must be
1359 saved on entry to this function. So we migrate the
1360 call to the first insn of this function. */
1361 rtx temp;
1362 rtx seq;
1364 start_sequence ();
1365 temp = expand_builtin_apply_args_1 ();
1366 seq = get_insns ();
1367 end_sequence ();
1369 apply_args_value = temp;
1371 /* Put the insns after the NOTE that starts the function.
1372 If this is inside a start_sequence, make the outer-level insn
1373 chain current, so the code is placed at the start of the
1374 function. */
1375 push_topmost_sequence ();
1376 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1377 pop_topmost_sequence ();
1378 return temp;
1382 /* Perform an untyped call and save the state required to perform an
1383 untyped return of whatever value was returned by the given function. */
1385 static rtx
1386 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1388 int size, align, regno;
1389 enum machine_mode mode;
1390 rtx incoming_args, result, reg, dest, src, call_insn;
1391 rtx old_stack_level = 0;
1392 rtx call_fusage = 0;
1393 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1395 arguments = convert_memory_address (Pmode, arguments);
1397 /* Create a block where the return registers can be saved. */
1398 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1400 /* Fetch the arg pointer from the ARGUMENTS block. */
1401 incoming_args = gen_reg_rtx (Pmode);
1402 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1403 #ifndef STACK_GROWS_DOWNWARD
1404 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1405 incoming_args, 0, OPTAB_LIB_WIDEN);
1406 #endif
1408 /* Push a new argument block and copy the arguments. Do not allow
1409 the (potential) memcpy call below to interfere with our stack
1410 manipulations. */
1411 do_pending_stack_adjust ();
1412 NO_DEFER_POP;
1414 /* Save the stack with nonlocal if available. */
1415 #ifdef HAVE_save_stack_nonlocal
1416 if (HAVE_save_stack_nonlocal)
1417 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1418 else
1419 #endif
1420 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1422 /* Allocate a block of memory onto the stack and copy the memory
1423 arguments to the outgoing arguments address. */
1424 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1425 dest = virtual_outgoing_args_rtx;
1426 #ifndef STACK_GROWS_DOWNWARD
1427 if (GET_CODE (argsize) == CONST_INT)
1428 dest = plus_constant (dest, -INTVAL (argsize));
1429 else
1430 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1431 #endif
1432 dest = gen_rtx_MEM (BLKmode, dest);
1433 set_mem_align (dest, PARM_BOUNDARY);
1434 src = gen_rtx_MEM (BLKmode, incoming_args);
1435 set_mem_align (src, PARM_BOUNDARY);
1436 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1438 /* Refer to the argument block. */
1439 apply_args_size ();
1440 arguments = gen_rtx_MEM (BLKmode, arguments);
1441 set_mem_align (arguments, PARM_BOUNDARY);
1443 /* Walk past the arg-pointer and structure value address. */
1444 size = GET_MODE_SIZE (Pmode);
1445 if (struct_value)
1446 size += GET_MODE_SIZE (Pmode);
1448 /* Restore each of the registers previously saved. Make USE insns
1449 for each of these registers for use in making the call. */
1450 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1451 if ((mode = apply_args_mode[regno]) != VOIDmode)
1453 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1454 if (size % align != 0)
1455 size = CEIL (size, align) * align;
1456 reg = gen_rtx_REG (mode, regno);
1457 emit_move_insn (reg, adjust_address (arguments, mode, size));
1458 use_reg (&call_fusage, reg);
1459 size += GET_MODE_SIZE (mode);
1462 /* Restore the structure value address unless this is passed as an
1463 "invisible" first argument. */
1464 size = GET_MODE_SIZE (Pmode);
1465 if (struct_value)
1467 rtx value = gen_reg_rtx (Pmode);
1468 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1469 emit_move_insn (struct_value, value);
1470 if (REG_P (struct_value))
1471 use_reg (&call_fusage, struct_value);
1472 size += GET_MODE_SIZE (Pmode);
1475 /* All arguments and registers used for the call are set up by now! */
1476 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1478 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1479 and we don't want to load it into a register as an optimization,
1480 because prepare_call_address already did it if it should be done. */
1481 if (GET_CODE (function) != SYMBOL_REF)
1482 function = memory_address (FUNCTION_MODE, function);
1484 /* Generate the actual call instruction and save the return value. */
1485 #ifdef HAVE_untyped_call
1486 if (HAVE_untyped_call)
1487 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1488 result, result_vector (1, result)));
1489 else
1490 #endif
1491 #ifdef HAVE_call_value
1492 if (HAVE_call_value)
1494 rtx valreg = 0;
1496 /* Locate the unique return register. It is not possible to
1497 express a call that sets more than one return register using
1498 call_value; use untyped_call for that. In fact, untyped_call
1499 only needs to save the return registers in the given block. */
1500 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1501 if ((mode = apply_result_mode[regno]) != VOIDmode)
1503 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1505 valreg = gen_rtx_REG (mode, regno);
1508 emit_call_insn (GEN_CALL_VALUE (valreg,
1509 gen_rtx_MEM (FUNCTION_MODE, function),
1510 const0_rtx, NULL_RTX, const0_rtx));
1512 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1514 else
1515 #endif
1516 gcc_unreachable ();
1518 /* Find the CALL insn we just emitted, and attach the register usage
1519 information. */
1520 call_insn = last_call_insn ();
1521 add_function_usage_to (call_insn, call_fusage);
1523 /* Restore the stack. */
1524 #ifdef HAVE_save_stack_nonlocal
1525 if (HAVE_save_stack_nonlocal)
1526 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1527 else
1528 #endif
1529 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1531 OK_DEFER_POP;
1533 /* Return the address of the result block. */
1534 result = copy_addr_to_reg (XEXP (result, 0));
1535 return convert_memory_address (ptr_mode, result);
1538 /* Perform an untyped return. */
1540 static void
1541 expand_builtin_return (rtx result)
1543 int size, align, regno;
1544 enum machine_mode mode;
1545 rtx reg;
1546 rtx call_fusage = 0;
1548 result = convert_memory_address (Pmode, result);
1550 apply_result_size ();
1551 result = gen_rtx_MEM (BLKmode, result);
1553 #ifdef HAVE_untyped_return
1554 if (HAVE_untyped_return)
1556 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1557 emit_barrier ();
1558 return;
1560 #endif
1562 /* Restore the return value and note that each value is used. */
1563 size = 0;
1564 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1565 if ((mode = apply_result_mode[regno]) != VOIDmode)
1567 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1568 if (size % align != 0)
1569 size = CEIL (size, align) * align;
1570 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1571 emit_move_insn (reg, adjust_address (result, mode, size));
1573 push_to_sequence (call_fusage);
1574 emit_insn (gen_rtx_USE (VOIDmode, reg));
1575 call_fusage = get_insns ();
1576 end_sequence ();
1577 size += GET_MODE_SIZE (mode);
1580 /* Put the USE insns before the return. */
1581 emit_insn (call_fusage);
1583 /* Return whatever values was restored by jumping directly to the end
1584 of the function. */
1585 expand_naked_return ();
1588 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1590 static enum type_class
1591 type_to_class (tree type)
1593 switch (TREE_CODE (type))
1595 case VOID_TYPE: return void_type_class;
1596 case INTEGER_TYPE: return integer_type_class;
1597 case ENUMERAL_TYPE: return enumeral_type_class;
1598 case BOOLEAN_TYPE: return boolean_type_class;
1599 case POINTER_TYPE: return pointer_type_class;
1600 case REFERENCE_TYPE: return reference_type_class;
1601 case OFFSET_TYPE: return offset_type_class;
1602 case REAL_TYPE: return real_type_class;
1603 case COMPLEX_TYPE: return complex_type_class;
1604 case FUNCTION_TYPE: return function_type_class;
1605 case METHOD_TYPE: return method_type_class;
1606 case RECORD_TYPE: return record_type_class;
1607 case UNION_TYPE:
1608 case QUAL_UNION_TYPE: return union_type_class;
1609 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1610 ? string_type_class : array_type_class);
1611 case LANG_TYPE: return lang_type_class;
1612 default: return no_type_class;
1616 /* Expand a call to __builtin_classify_type with arguments found in
1617 ARGLIST. */
1619 static rtx
1620 expand_builtin_classify_type (tree arglist)
1622 if (arglist != 0)
1623 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1624 return GEN_INT (no_type_class);
1627 /* This helper macro, meant to be used in mathfn_built_in below,
1628 determines which among a set of three builtin math functions is
1629 appropriate for a given type mode. The `F' and `L' cases are
1630 automatically generated from the `double' case. */
1631 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1632 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1633 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1634 fcodel = BUILT_IN_MATHFN##L ; break;
1636 /* Return mathematic function equivalent to FN but operating directly
1637 on TYPE, if available. If we can't do the conversion, return zero. */
1638 tree
1639 mathfn_built_in (tree type, enum built_in_function fn)
1641 enum built_in_function fcode, fcodef, fcodel;
1643 switch (fn)
1645 CASE_MATHFN (BUILT_IN_ACOS)
1646 CASE_MATHFN (BUILT_IN_ACOSH)
1647 CASE_MATHFN (BUILT_IN_ASIN)
1648 CASE_MATHFN (BUILT_IN_ASINH)
1649 CASE_MATHFN (BUILT_IN_ATAN)
1650 CASE_MATHFN (BUILT_IN_ATAN2)
1651 CASE_MATHFN (BUILT_IN_ATANH)
1652 CASE_MATHFN (BUILT_IN_CBRT)
1653 CASE_MATHFN (BUILT_IN_CEIL)
1654 CASE_MATHFN (BUILT_IN_CEXPI)
1655 CASE_MATHFN (BUILT_IN_COPYSIGN)
1656 CASE_MATHFN (BUILT_IN_COS)
1657 CASE_MATHFN (BUILT_IN_COSH)
1658 CASE_MATHFN (BUILT_IN_DREM)
1659 CASE_MATHFN (BUILT_IN_ERF)
1660 CASE_MATHFN (BUILT_IN_ERFC)
1661 CASE_MATHFN (BUILT_IN_EXP)
1662 CASE_MATHFN (BUILT_IN_EXP10)
1663 CASE_MATHFN (BUILT_IN_EXP2)
1664 CASE_MATHFN (BUILT_IN_EXPM1)
1665 CASE_MATHFN (BUILT_IN_FABS)
1666 CASE_MATHFN (BUILT_IN_FDIM)
1667 CASE_MATHFN (BUILT_IN_FLOOR)
1668 CASE_MATHFN (BUILT_IN_FMA)
1669 CASE_MATHFN (BUILT_IN_FMAX)
1670 CASE_MATHFN (BUILT_IN_FMIN)
1671 CASE_MATHFN (BUILT_IN_FMOD)
1672 CASE_MATHFN (BUILT_IN_FREXP)
1673 CASE_MATHFN (BUILT_IN_GAMMA)
1674 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1675 CASE_MATHFN (BUILT_IN_HYPOT)
1676 CASE_MATHFN (BUILT_IN_ILOGB)
1677 CASE_MATHFN (BUILT_IN_INF)
1678 CASE_MATHFN (BUILT_IN_J0)
1679 CASE_MATHFN (BUILT_IN_J1)
1680 CASE_MATHFN (BUILT_IN_JN)
1681 CASE_MATHFN (BUILT_IN_LCEIL)
1682 CASE_MATHFN (BUILT_IN_LDEXP)
1683 CASE_MATHFN (BUILT_IN_LFLOOR)
1684 CASE_MATHFN (BUILT_IN_LGAMMA)
1685 CASE_MATHFN (BUILT_IN_LLCEIL)
1686 CASE_MATHFN (BUILT_IN_LLFLOOR)
1687 CASE_MATHFN (BUILT_IN_LLRINT)
1688 CASE_MATHFN (BUILT_IN_LLROUND)
1689 CASE_MATHFN (BUILT_IN_LOG)
1690 CASE_MATHFN (BUILT_IN_LOG10)
1691 CASE_MATHFN (BUILT_IN_LOG1P)
1692 CASE_MATHFN (BUILT_IN_LOG2)
1693 CASE_MATHFN (BUILT_IN_LOGB)
1694 CASE_MATHFN (BUILT_IN_LRINT)
1695 CASE_MATHFN (BUILT_IN_LROUND)
1696 CASE_MATHFN (BUILT_IN_MODF)
1697 CASE_MATHFN (BUILT_IN_NAN)
1698 CASE_MATHFN (BUILT_IN_NANS)
1699 CASE_MATHFN (BUILT_IN_NEARBYINT)
1700 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1701 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1702 CASE_MATHFN (BUILT_IN_POW)
1703 CASE_MATHFN (BUILT_IN_POWI)
1704 CASE_MATHFN (BUILT_IN_POW10)
1705 CASE_MATHFN (BUILT_IN_REMAINDER)
1706 CASE_MATHFN (BUILT_IN_REMQUO)
1707 CASE_MATHFN (BUILT_IN_RINT)
1708 CASE_MATHFN (BUILT_IN_ROUND)
1709 CASE_MATHFN (BUILT_IN_SCALB)
1710 CASE_MATHFN (BUILT_IN_SCALBLN)
1711 CASE_MATHFN (BUILT_IN_SCALBN)
1712 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1713 CASE_MATHFN (BUILT_IN_SIN)
1714 CASE_MATHFN (BUILT_IN_SINCOS)
1715 CASE_MATHFN (BUILT_IN_SINH)
1716 CASE_MATHFN (BUILT_IN_SQRT)
1717 CASE_MATHFN (BUILT_IN_TAN)
1718 CASE_MATHFN (BUILT_IN_TANH)
1719 CASE_MATHFN (BUILT_IN_TGAMMA)
1720 CASE_MATHFN (BUILT_IN_TRUNC)
1721 CASE_MATHFN (BUILT_IN_Y0)
1722 CASE_MATHFN (BUILT_IN_Y1)
1723 CASE_MATHFN (BUILT_IN_YN)
1725 default:
1726 return 0;
1729 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1730 return implicit_built_in_decls[fcode];
1731 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1732 return implicit_built_in_decls[fcodef];
1733 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1734 return implicit_built_in_decls[fcodel];
1735 else
1736 return 0;
1739 /* If errno must be maintained, expand the RTL to check if the result,
1740 TARGET, of a built-in function call, EXP, is NaN, and if so set
1741 errno to EDOM. */
1743 static void
1744 expand_errno_check (tree exp, rtx target)
1746 rtx lab = gen_label_rtx ();
1748 /* Test the result; if it is NaN, set errno=EDOM because
1749 the argument was not in the domain. */
1750 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1751 0, lab);
1753 #ifdef TARGET_EDOM
1754 /* If this built-in doesn't throw an exception, set errno directly. */
1755 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1757 #ifdef GEN_ERRNO_RTX
1758 rtx errno_rtx = GEN_ERRNO_RTX;
1759 #else
1760 rtx errno_rtx
1761 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1762 #endif
1763 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1764 emit_label (lab);
1765 return;
1767 #endif
1769 /* We can't set errno=EDOM directly; let the library call do it.
1770 Pop the arguments right away in case the call gets deleted. */
1771 NO_DEFER_POP;
1772 expand_call (exp, target, 0);
1773 OK_DEFER_POP;
1774 emit_label (lab);
1778 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1779 Return 0 if a normal call should be emitted rather than expanding the
1780 function in-line. EXP is the expression that is a call to the builtin
1781 function; if convenient, the result should be placed in TARGET.
1782 SUBTARGET may be used as the target for computing one of EXP's operands. */
1784 static rtx
1785 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1787 optab builtin_optab;
1788 rtx op0, insns, before_call;
1789 tree fndecl = get_callee_fndecl (exp);
1790 tree arglist = TREE_OPERAND (exp, 1);
1791 enum machine_mode mode;
1792 bool errno_set = false;
1793 tree arg, narg;
1795 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1796 return 0;
1798 arg = TREE_VALUE (arglist);
1800 switch (DECL_FUNCTION_CODE (fndecl))
1802 CASE_FLT_FN (BUILT_IN_SQRT):
1803 errno_set = ! tree_expr_nonnegative_p (arg);
1804 builtin_optab = sqrt_optab;
1805 break;
1806 CASE_FLT_FN (BUILT_IN_EXP):
1807 errno_set = true; builtin_optab = exp_optab; break;
1808 CASE_FLT_FN (BUILT_IN_EXP10):
1809 CASE_FLT_FN (BUILT_IN_POW10):
1810 errno_set = true; builtin_optab = exp10_optab; break;
1811 CASE_FLT_FN (BUILT_IN_EXP2):
1812 errno_set = true; builtin_optab = exp2_optab; break;
1813 CASE_FLT_FN (BUILT_IN_EXPM1):
1814 errno_set = true; builtin_optab = expm1_optab; break;
1815 CASE_FLT_FN (BUILT_IN_LOGB):
1816 errno_set = true; builtin_optab = logb_optab; break;
1817 CASE_FLT_FN (BUILT_IN_ILOGB):
1818 errno_set = true; builtin_optab = ilogb_optab; break;
1819 CASE_FLT_FN (BUILT_IN_LOG):
1820 errno_set = true; builtin_optab = log_optab; break;
1821 CASE_FLT_FN (BUILT_IN_LOG10):
1822 errno_set = true; builtin_optab = log10_optab; break;
1823 CASE_FLT_FN (BUILT_IN_LOG2):
1824 errno_set = true; builtin_optab = log2_optab; break;
1825 CASE_FLT_FN (BUILT_IN_LOG1P):
1826 errno_set = true; builtin_optab = log1p_optab; break;
1827 CASE_FLT_FN (BUILT_IN_ASIN):
1828 builtin_optab = asin_optab; break;
1829 CASE_FLT_FN (BUILT_IN_ACOS):
1830 builtin_optab = acos_optab; break;
1831 CASE_FLT_FN (BUILT_IN_TAN):
1832 builtin_optab = tan_optab; break;
1833 CASE_FLT_FN (BUILT_IN_ATAN):
1834 builtin_optab = atan_optab; break;
1835 CASE_FLT_FN (BUILT_IN_FLOOR):
1836 builtin_optab = floor_optab; break;
1837 CASE_FLT_FN (BUILT_IN_CEIL):
1838 builtin_optab = ceil_optab; break;
1839 CASE_FLT_FN (BUILT_IN_TRUNC):
1840 builtin_optab = btrunc_optab; break;
1841 CASE_FLT_FN (BUILT_IN_ROUND):
1842 builtin_optab = round_optab; break;
1843 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1844 builtin_optab = nearbyint_optab;
1845 if (flag_trapping_math)
1846 break;
1847 /* Else fallthrough and expand as rint. */
1848 CASE_FLT_FN (BUILT_IN_RINT):
1849 builtin_optab = rint_optab; break;
1850 default:
1851 gcc_unreachable ();
1854 /* Make a suitable register to place result in. */
1855 mode = TYPE_MODE (TREE_TYPE (exp));
1857 if (! flag_errno_math || ! HONOR_NANS (mode))
1858 errno_set = false;
1860 /* Before working hard, check whether the instruction is available. */
1861 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1863 target = gen_reg_rtx (mode);
1865 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1866 need to expand the argument again. This way, we will not perform
1867 side-effects more the once. */
1868 narg = builtin_save_expr (arg);
1869 if (narg != arg)
1871 arg = narg;
1872 arglist = build_tree_list (NULL_TREE, arg);
1873 exp = build_function_call_expr (fndecl, arglist);
1876 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1878 start_sequence ();
1880 /* Compute into TARGET.
1881 Set TARGET to wherever the result comes back. */
1882 target = expand_unop (mode, builtin_optab, op0, target, 0);
1884 if (target != 0)
1886 if (errno_set)
1887 expand_errno_check (exp, target);
1889 /* Output the entire sequence. */
1890 insns = get_insns ();
1891 end_sequence ();
1892 emit_insn (insns);
1893 return target;
1896 /* If we were unable to expand via the builtin, stop the sequence
1897 (without outputting the insns) and call to the library function
1898 with the stabilized argument list. */
1899 end_sequence ();
1902 before_call = get_last_insn ();
1904 target = expand_call (exp, target, target == const0_rtx);
1906 /* If this is a sqrt operation and we don't care about errno, try to
1907 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1908 This allows the semantics of the libcall to be visible to the RTL
1909 optimizers. */
1910 if (builtin_optab == sqrt_optab && !errno_set)
1912 /* Search backwards through the insns emitted by expand_call looking
1913 for the instruction with the REG_RETVAL note. */
1914 rtx last = get_last_insn ();
1915 while (last != before_call)
1917 if (find_reg_note (last, REG_RETVAL, NULL))
1919 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1920 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1921 two elements, i.e. symbol_ref(sqrt) and the operand. */
1922 if (note
1923 && GET_CODE (note) == EXPR_LIST
1924 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1925 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1926 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1928 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1929 /* Check operand is a register with expected mode. */
1930 if (operand
1931 && REG_P (operand)
1932 && GET_MODE (operand) == mode)
1934 /* Replace the REG_EQUAL note with a SQRT rtx. */
1935 rtx equiv = gen_rtx_SQRT (mode, operand);
1936 set_unique_reg_note (last, REG_EQUAL, equiv);
1939 break;
1941 last = PREV_INSN (last);
1945 return target;
1948 /* Expand a call to the builtin binary math functions (pow and atan2).
1949 Return 0 if a normal call should be emitted rather than expanding the
1950 function in-line. EXP is the expression that is a call to the builtin
1951 function; if convenient, the result should be placed in TARGET.
1952 SUBTARGET may be used as the target for computing one of EXP's
1953 operands. */
1955 static rtx
1956 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1958 optab builtin_optab;
1959 rtx op0, op1, insns;
1960 int op1_type = REAL_TYPE;
1961 tree fndecl = get_callee_fndecl (exp);
1962 tree arglist = TREE_OPERAND (exp, 1);
1963 tree arg0, arg1, temp, narg;
1964 enum machine_mode mode;
1965 bool errno_set = true;
1966 bool stable = true;
1968 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1969 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1970 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1971 op1_type = INTEGER_TYPE;
1973 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1974 return 0;
1976 arg0 = TREE_VALUE (arglist);
1977 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1979 switch (DECL_FUNCTION_CODE (fndecl))
1981 CASE_FLT_FN (BUILT_IN_POW):
1982 builtin_optab = pow_optab; break;
1983 CASE_FLT_FN (BUILT_IN_ATAN2):
1984 builtin_optab = atan2_optab; break;
1985 CASE_FLT_FN (BUILT_IN_LDEXP):
1986 builtin_optab = ldexp_optab; break;
1987 CASE_FLT_FN (BUILT_IN_FMOD):
1988 builtin_optab = fmod_optab; break;
1989 CASE_FLT_FN (BUILT_IN_REMAINDER):
1990 CASE_FLT_FN (BUILT_IN_DREM):
1991 builtin_optab = remainder_optab; break;
1992 default:
1993 gcc_unreachable ();
1996 /* Make a suitable register to place result in. */
1997 mode = TYPE_MODE (TREE_TYPE (exp));
1999 /* Before working hard, check whether the instruction is available. */
2000 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2001 return 0;
2003 target = gen_reg_rtx (mode);
2005 if (! flag_errno_math || ! HONOR_NANS (mode))
2006 errno_set = false;
2008 /* Always stabilize the argument list. */
2009 narg = builtin_save_expr (arg1);
2010 if (narg != arg1)
2012 arg1 = narg;
2013 temp = build_tree_list (NULL_TREE, narg);
2014 stable = false;
2016 else
2017 temp = TREE_CHAIN (arglist);
2019 narg = builtin_save_expr (arg0);
2020 if (narg != arg0)
2022 arg0 = narg;
2023 arglist = tree_cons (NULL_TREE, narg, temp);
2024 stable = false;
2026 else if (! stable)
2027 arglist = tree_cons (NULL_TREE, arg0, temp);
2029 if (! stable)
2030 exp = build_function_call_expr (fndecl, arglist);
2032 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2033 op1 = expand_normal (arg1);
2035 start_sequence ();
2037 /* Compute into TARGET.
2038 Set TARGET to wherever the result comes back. */
2039 target = expand_binop (mode, builtin_optab, op0, op1,
2040 target, 0, OPTAB_DIRECT);
2042 /* If we were unable to expand via the builtin, stop the sequence
2043 (without outputting the insns) and call to the library function
2044 with the stabilized argument list. */
2045 if (target == 0)
2047 end_sequence ();
2048 return expand_call (exp, target, target == const0_rtx);
2051 if (errno_set)
2052 expand_errno_check (exp, target);
2054 /* Output the entire sequence. */
2055 insns = get_insns ();
2056 end_sequence ();
2057 emit_insn (insns);
2059 return target;
2062 /* Expand a call to the builtin sin and cos math functions.
2063 Return 0 if a normal call should be emitted rather than expanding the
2064 function in-line. EXP is the expression that is a call to the builtin
2065 function; if convenient, the result should be placed in TARGET.
2066 SUBTARGET may be used as the target for computing one of EXP's
2067 operands. */
2069 static rtx
2070 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2072 optab builtin_optab;
2073 rtx op0, insns;
2074 tree fndecl = get_callee_fndecl (exp);
2075 tree arglist = TREE_OPERAND (exp, 1);
2076 enum machine_mode mode;
2077 tree arg, narg;
2079 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2080 return 0;
2082 arg = TREE_VALUE (arglist);
2084 switch (DECL_FUNCTION_CODE (fndecl))
2086 CASE_FLT_FN (BUILT_IN_SIN):
2087 CASE_FLT_FN (BUILT_IN_COS):
2088 builtin_optab = sincos_optab; break;
2089 default:
2090 gcc_unreachable ();
2093 /* Make a suitable register to place result in. */
2094 mode = TYPE_MODE (TREE_TYPE (exp));
2096 /* Check if sincos insn is available, otherwise fallback
2097 to sin or cos insn. */
2098 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2099 switch (DECL_FUNCTION_CODE (fndecl))
2101 CASE_FLT_FN (BUILT_IN_SIN):
2102 builtin_optab = sin_optab; break;
2103 CASE_FLT_FN (BUILT_IN_COS):
2104 builtin_optab = cos_optab; break;
2105 default:
2106 gcc_unreachable ();
2109 /* Before working hard, check whether the instruction is available. */
2110 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2112 target = gen_reg_rtx (mode);
2114 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2115 need to expand the argument again. This way, we will not perform
2116 side-effects more the once. */
2117 narg = save_expr (arg);
2118 if (narg != arg)
2120 arg = narg;
2121 arglist = build_tree_list (NULL_TREE, arg);
2122 exp = build_function_call_expr (fndecl, arglist);
2125 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2127 start_sequence ();
2129 /* Compute into TARGET.
2130 Set TARGET to wherever the result comes back. */
2131 if (builtin_optab == sincos_optab)
2133 int result;
2135 switch (DECL_FUNCTION_CODE (fndecl))
2137 CASE_FLT_FN (BUILT_IN_SIN):
2138 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2139 break;
2140 CASE_FLT_FN (BUILT_IN_COS):
2141 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2142 break;
2143 default:
2144 gcc_unreachable ();
2146 gcc_assert (result);
2148 else
2150 target = expand_unop (mode, builtin_optab, op0, target, 0);
2153 if (target != 0)
2155 /* Output the entire sequence. */
2156 insns = get_insns ();
2157 end_sequence ();
2158 emit_insn (insns);
2159 return target;
2162 /* If we were unable to expand via the builtin, stop the sequence
2163 (without outputting the insns) and call to the library function
2164 with the stabilized argument list. */
2165 end_sequence ();
2168 target = expand_call (exp, target, target == const0_rtx);
2170 return target;
2173 /* Expand a call to the builtin sincos math function.
2174 Return 0 if a normal call should be emitted rather than expanding the
2175 function in-line. EXP is the expression that is a call to the builtin
2176 function. */
2178 static rtx
2179 expand_builtin_sincos (tree exp)
2181 rtx op0, op1, op2, target1, target2;
2182 tree arglist = TREE_OPERAND (exp, 1);
2183 enum machine_mode mode;
2184 tree arg, sinp, cosp;
2185 int result;
2187 if (!validate_arglist (arglist, REAL_TYPE,
2188 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2189 return 0;
2191 arg = TREE_VALUE (arglist);
2192 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2193 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2195 /* Make a suitable register to place result in. */
2196 mode = TYPE_MODE (TREE_TYPE (arg));
2198 /* Check if sincos insn is available, otherwise emit the call. */
2199 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2200 return NULL_RTX;
2202 target1 = gen_reg_rtx (mode);
2203 target2 = gen_reg_rtx (mode);
2205 op0 = expand_normal (arg);
2206 op1 = expand_normal (build_fold_indirect_ref (sinp));
2207 op2 = expand_normal (build_fold_indirect_ref (cosp));
2209 /* Compute into target1 and target2.
2210 Set TARGET to wherever the result comes back. */
2211 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2212 gcc_assert (result);
2214 /* Move target1 and target2 to the memory locations indicated
2215 by op1 and op2. */
2216 emit_move_insn (op1, target1);
2217 emit_move_insn (op2, target2);
2219 return const0_rtx;
2222 /* Expand a call to the internal cexpi builtin to the sincos math function.
2223 EXP is the expression that is a call to the builtin function; if convenient,
2224 the result should be placed in TARGET. SUBTARGET may be used as the target
2225 for computing one of EXP's operands. */
2227 static rtx
2228 expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2230 tree fndecl = get_callee_fndecl (exp);
2231 tree arglist = TREE_OPERAND (exp, 1);
2232 enum machine_mode mode;
2233 tree arg, type;
2234 rtx op0, op1, op2;
2236 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2237 return 0;
2239 arg = TREE_VALUE (arglist);
2240 type = TREE_TYPE (arg);
2241 mode = TYPE_MODE (TREE_TYPE (arg));
2243 /* Try expanding via a sincos optab, fall back to emitting a libcall
2244 to sincos or cexp. We are sure we have sincos or cexp because cexpi
2245 is only generated from sincos, cexp or if we have either of them. */
2246 if (sincos_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2248 op1 = gen_reg_rtx (mode);
2249 op2 = gen_reg_rtx (mode);
2251 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2253 /* Compute into op1 and op2. */
2254 expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2256 else if (TARGET_HAS_SINCOS)
2258 tree call, narglist, fn = NULL_TREE;
2259 tree top1, top2;
2260 rtx op1a, op2a;
2262 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2263 fn = built_in_decls[BUILT_IN_SINCOSF];
2264 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2265 fn = built_in_decls[BUILT_IN_SINCOS];
2266 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2267 fn = built_in_decls[BUILT_IN_SINCOSL];
2269 op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2270 op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2271 op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2272 op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2273 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2274 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2276 narglist = build_tree_list (NULL_TREE, top2);
2277 narglist = tree_cons (NULL_TREE, top1, narglist);
2278 narglist = tree_cons (NULL_TREE, arg, narglist);
2280 /* Make sure not to fold the sincos call again. */
2281 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2282 expand_normal (build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
2283 call, narglist, NULL_TREE));
2285 else
2287 tree call, fn = NULL_TREE, narg;
2288 tree ctype = build_complex_type (type);
2290 /* We can expand via the C99 cexp function. */
2291 gcc_assert (TARGET_C99_FUNCTIONS);
2293 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2294 fn = built_in_decls[BUILT_IN_CEXPF];
2295 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2296 fn = built_in_decls[BUILT_IN_CEXP];
2297 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2298 fn = built_in_decls[BUILT_IN_CEXPL];
2299 narg = fold_build2 (COMPLEX_EXPR, ctype,
2300 build_real (type, dconst0), arg);
2302 /* Make sure not to fold the cexp call again. */
2303 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2304 return expand_expr (build3 (CALL_EXPR, ctype, call,
2305 build_tree_list (NULL_TREE, narg),
2306 NULL_TREE), target, VOIDmode, 0);
2309 /* Now build the proper return type. */
2310 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2311 make_tree (TREE_TYPE (arg), op2),
2312 make_tree (TREE_TYPE (arg), op1)),
2313 target, VOIDmode, 0);
2316 /* Expand a call to one of the builtin rounding functions gcc defines
2317 as an extension (lfloor and lceil). As these are gcc extensions we
2318 do not need to worry about setting errno to EDOM.
2319 If expanding via optab fails, lower expression to (int)(floor(x)).
2320 EXP is the expression that is a call to the builtin function;
2321 if convenient, the result should be placed in TARGET. SUBTARGET may
2322 be used as the target for computing one of EXP's operands. */
2324 static rtx
2325 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2327 convert_optab builtin_optab;
2328 rtx op0, insns, tmp;
2329 tree fndecl = get_callee_fndecl (exp);
2330 tree arglist = TREE_OPERAND (exp, 1);
2331 enum built_in_function fallback_fn;
2332 tree fallback_fndecl;
2333 enum machine_mode mode;
2334 tree arg, narg;
2336 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2337 gcc_unreachable ();
2339 arg = TREE_VALUE (arglist);
2341 switch (DECL_FUNCTION_CODE (fndecl))
2343 CASE_FLT_FN (BUILT_IN_LCEIL):
2344 CASE_FLT_FN (BUILT_IN_LLCEIL):
2345 builtin_optab = lceil_optab;
2346 fallback_fn = BUILT_IN_CEIL;
2347 break;
2349 CASE_FLT_FN (BUILT_IN_LFLOOR):
2350 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2351 builtin_optab = lfloor_optab;
2352 fallback_fn = BUILT_IN_FLOOR;
2353 break;
2355 default:
2356 gcc_unreachable ();
2359 /* Make a suitable register to place result in. */
2360 mode = TYPE_MODE (TREE_TYPE (exp));
2362 target = gen_reg_rtx (mode);
2364 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2365 need to expand the argument again. This way, we will not perform
2366 side-effects more the once. */
2367 narg = builtin_save_expr (arg);
2368 if (narg != arg)
2370 arg = narg;
2371 arglist = build_tree_list (NULL_TREE, arg);
2372 exp = build_function_call_expr (fndecl, arglist);
2375 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2377 start_sequence ();
2379 /* Compute into TARGET. */
2380 if (expand_sfix_optab (target, op0, builtin_optab))
2382 /* Output the entire sequence. */
2383 insns = get_insns ();
2384 end_sequence ();
2385 emit_insn (insns);
2386 return target;
2389 /* If we were unable to expand via the builtin, stop the sequence
2390 (without outputting the insns). */
2391 end_sequence ();
2393 /* Fall back to floating point rounding optab. */
2394 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2395 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2396 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2397 gcc_assert (fallback_fndecl != NULL_TREE);
2398 exp = build_function_call_expr (fallback_fndecl, arglist);
2400 tmp = expand_normal (exp);
2402 /* Truncate the result of floating point optab to integer
2403 via expand_fix (). */
2404 target = gen_reg_rtx (mode);
2405 expand_fix (target, tmp, 0);
2407 return target;
2410 /* Expand a call to one of the builtin math functions doing integer
2411 conversion (lrint).
2412 Return 0 if a normal call should be emitted rather than expanding the
2413 function in-line. EXP is the expression that is a call to the builtin
2414 function; if convenient, the result should be placed in TARGET.
2415 SUBTARGET may be used as the target for computing one of EXP's operands. */
2417 static rtx
2418 expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
2420 convert_optab builtin_optab;
2421 rtx op0, insns;
2422 tree fndecl = get_callee_fndecl (exp);
2423 tree arglist = TREE_OPERAND (exp, 1);
2424 enum machine_mode mode;
2425 tree arg, narg;
2427 /* There's no easy way to detect the case we need to set EDOM. */
2428 if (flag_errno_math)
2429 return NULL_RTX;
2431 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2432 return NULL_RTX;
2434 arg = TREE_VALUE (arglist);
2436 switch (DECL_FUNCTION_CODE (fndecl))
2438 CASE_FLT_FN (BUILT_IN_LRINT):
2439 CASE_FLT_FN (BUILT_IN_LLRINT):
2440 builtin_optab = lrint_optab; break;
2441 CASE_FLT_FN (BUILT_IN_LROUND):
2442 CASE_FLT_FN (BUILT_IN_LLROUND):
2443 builtin_optab = lround_optab; break;
2444 default:
2445 gcc_unreachable ();
2448 /* Make a suitable register to place result in. */
2449 mode = TYPE_MODE (TREE_TYPE (exp));
2451 target = gen_reg_rtx (mode);
2453 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2454 need to expand the argument again. This way, we will not perform
2455 side-effects more the once. */
2456 narg = builtin_save_expr (arg);
2457 if (narg != arg)
2459 arg = narg;
2460 arglist = build_tree_list (NULL_TREE, arg);
2461 exp = build_function_call_expr (fndecl, arglist);
2464 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2466 start_sequence ();
2468 if (expand_sfix_optab (target, op0, builtin_optab))
2470 /* Output the entire sequence. */
2471 insns = get_insns ();
2472 end_sequence ();
2473 emit_insn (insns);
2474 return target;
2477 /* If we were unable to expand via the builtin, stop the sequence
2478 (without outputting the insns) and call to the library function
2479 with the stabilized argument list. */
2480 end_sequence ();
2482 target = expand_call (exp, target, target == const0_rtx);
2484 return target;
2487 /* To evaluate powi(x,n), the floating point value x raised to the
2488 constant integer exponent n, we use a hybrid algorithm that
2489 combines the "window method" with look-up tables. For an
2490 introduction to exponentiation algorithms and "addition chains",
2491 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2492 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2493 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2494 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2496 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2497 multiplications to inline before calling the system library's pow
2498 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2499 so this default never requires calling pow, powf or powl. */
2501 #ifndef POWI_MAX_MULTS
2502 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2503 #endif
2505 /* The size of the "optimal power tree" lookup table. All
2506 exponents less than this value are simply looked up in the
2507 powi_table below. This threshold is also used to size the
2508 cache of pseudo registers that hold intermediate results. */
2509 #define POWI_TABLE_SIZE 256
2511 /* The size, in bits of the window, used in the "window method"
2512 exponentiation algorithm. This is equivalent to a radix of
2513 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2514 #define POWI_WINDOW_SIZE 3
2516 /* The following table is an efficient representation of an
2517 "optimal power tree". For each value, i, the corresponding
2518 value, j, in the table states than an optimal evaluation
2519 sequence for calculating pow(x,i) can be found by evaluating
2520 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2521 100 integers is given in Knuth's "Seminumerical algorithms". */
2523 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2525 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2526 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2527 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2528 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2529 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2530 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2531 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2532 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2533 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2534 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2535 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2536 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2537 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2538 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2539 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2540 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2541 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2542 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2543 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2544 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2545 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2546 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2547 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2548 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2549 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2550 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2551 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2552 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2553 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2554 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2555 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2556 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2560 /* Return the number of multiplications required to calculate
2561 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2562 subroutine of powi_cost. CACHE is an array indicating
2563 which exponents have already been calculated. */
2565 static int
2566 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2568 /* If we've already calculated this exponent, then this evaluation
2569 doesn't require any additional multiplications. */
2570 if (cache[n])
2571 return 0;
2573 cache[n] = true;
2574 return powi_lookup_cost (n - powi_table[n], cache)
2575 + powi_lookup_cost (powi_table[n], cache) + 1;
2578 /* Return the number of multiplications required to calculate
2579 powi(x,n) for an arbitrary x, given the exponent N. This
2580 function needs to be kept in sync with expand_powi below. */
2582 static int
2583 powi_cost (HOST_WIDE_INT n)
2585 bool cache[POWI_TABLE_SIZE];
2586 unsigned HOST_WIDE_INT digit;
2587 unsigned HOST_WIDE_INT val;
2588 int result;
2590 if (n == 0)
2591 return 0;
2593 /* Ignore the reciprocal when calculating the cost. */
2594 val = (n < 0) ? -n : n;
2596 /* Initialize the exponent cache. */
2597 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2598 cache[1] = true;
2600 result = 0;
2602 while (val >= POWI_TABLE_SIZE)
2604 if (val & 1)
2606 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2607 result += powi_lookup_cost (digit, cache)
2608 + POWI_WINDOW_SIZE + 1;
2609 val >>= POWI_WINDOW_SIZE;
2611 else
2613 val >>= 1;
2614 result++;
2618 return result + powi_lookup_cost (val, cache);
2621 /* Recursive subroutine of expand_powi. This function takes the array,
2622 CACHE, of already calculated exponents and an exponent N and returns
2623 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2625 static rtx
2626 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2628 unsigned HOST_WIDE_INT digit;
2629 rtx target, result;
2630 rtx op0, op1;
2632 if (n < POWI_TABLE_SIZE)
2634 if (cache[n])
2635 return cache[n];
2637 target = gen_reg_rtx (mode);
2638 cache[n] = target;
2640 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2641 op1 = expand_powi_1 (mode, powi_table[n], cache);
2643 else if (n & 1)
2645 target = gen_reg_rtx (mode);
2646 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2647 op0 = expand_powi_1 (mode, n - digit, cache);
2648 op1 = expand_powi_1 (mode, digit, cache);
2650 else
2652 target = gen_reg_rtx (mode);
2653 op0 = expand_powi_1 (mode, n >> 1, cache);
2654 op1 = op0;
2657 result = expand_mult (mode, op0, op1, target, 0);
2658 if (result != target)
2659 emit_move_insn (target, result);
2660 return target;
2663 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2664 floating point operand in mode MODE, and N is the exponent. This
2665 function needs to be kept in sync with powi_cost above. */
2667 static rtx
2668 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2670 unsigned HOST_WIDE_INT val;
2671 rtx cache[POWI_TABLE_SIZE];
2672 rtx result;
2674 if (n == 0)
2675 return CONST1_RTX (mode);
2677 val = (n < 0) ? -n : n;
2679 memset (cache, 0, sizeof (cache));
2680 cache[1] = x;
2682 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2684 /* If the original exponent was negative, reciprocate the result. */
2685 if (n < 0)
2686 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2687 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2689 return result;
2692 /* Expand a call to the pow built-in mathematical function. Return 0 if
2693 a normal call should be emitted rather than expanding the function
2694 in-line. EXP is the expression that is a call to the builtin
2695 function; if convenient, the result should be placed in TARGET. */
2697 static rtx
2698 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2700 tree arg0, arg1, fn, narg0, narglist;
2701 tree arglist = TREE_OPERAND (exp, 1);
2702 tree type = TREE_TYPE (exp);
2703 REAL_VALUE_TYPE cint, c, c2;
2704 HOST_WIDE_INT n;
2705 rtx op, op2;
2706 enum machine_mode mode = TYPE_MODE (type);
2708 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2709 return 0;
2711 arg0 = TREE_VALUE (arglist);
2712 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2714 if (TREE_CODE (arg1) != REAL_CST
2715 || TREE_OVERFLOW (arg1))
2716 return expand_builtin_mathfn_2 (exp, target, subtarget);
2718 /* Handle constant exponents. */
2720 /* For integer valued exponents we can expand to an optimal multiplication
2721 sequence using expand_powi. */
2722 c = TREE_REAL_CST (arg1);
2723 n = real_to_integer (&c);
2724 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2725 if (real_identical (&c, &cint)
2726 && ((n >= -1 && n <= 2)
2727 || (flag_unsafe_math_optimizations
2728 && !optimize_size
2729 && powi_cost (n) <= POWI_MAX_MULTS)))
2731 op = expand_expr (arg0, subtarget, VOIDmode, 0);
2732 if (n != 1)
2734 op = force_reg (mode, op);
2735 op = expand_powi (op, mode, n);
2737 return op;
2740 narg0 = builtin_save_expr (arg0);
2741 narglist = build_tree_list (NULL_TREE, narg0);
2743 /* If the exponent is not integer valued, check if it is half of an integer.
2744 In this case we can expand to sqrt (x) * x**(n/2). */
2745 fn = mathfn_built_in (type, BUILT_IN_SQRT);
2746 if (fn != NULL_TREE)
2748 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2749 n = real_to_integer (&c2);
2750 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2751 if (real_identical (&c2, &cint)
2752 && ((flag_unsafe_math_optimizations
2753 && !optimize_size
2754 && powi_cost (n/2) <= POWI_MAX_MULTS)
2755 || n == 1))
2757 tree call_expr = build_function_call_expr (fn, narglist);
2758 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
2759 if (n != 1)
2761 op2 = expand_expr (narg0, subtarget, VOIDmode, 0);
2762 op2 = force_reg (mode, op2);
2763 op2 = expand_powi (op2, mode, abs (n / 2));
2764 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2765 0, OPTAB_LIB_WIDEN);
2766 /* If the original exponent was negative, reciprocate the
2767 result. */
2768 if (n < 0)
2769 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2770 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2772 return op;
2776 /* Try if the exponent is a third of an integer. In this case
2777 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
2778 different from pow (x, 1./3.) due to rounding and behavior
2779 with negative x we need to constrain this transformation to
2780 unsafe math and positive x or finite math. */
2781 fn = mathfn_built_in (type, BUILT_IN_CBRT);
2782 if (fn != NULL_TREE
2783 && flag_unsafe_math_optimizations
2784 && (tree_expr_nonnegative_p (arg0)
2785 || !HONOR_NANS (mode)))
2787 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
2788 real_round (&c2, mode, &c2);
2789 n = real_to_integer (&c2);
2790 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2791 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
2792 real_convert (&c2, mode, &c2);
2793 if (real_identical (&c2, &c)
2794 && ((!optimize_size
2795 && powi_cost (n/3) <= POWI_MAX_MULTS)
2796 || n == 1))
2798 tree call_expr = build_function_call_expr (fn, narglist);
2799 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
2800 if (abs (n) % 3 == 2)
2801 op = expand_simple_binop (mode, MULT, op, op, op,
2802 0, OPTAB_LIB_WIDEN);
2803 if (n != 1)
2805 op2 = expand_expr (narg0, subtarget, VOIDmode, 0);
2806 op2 = force_reg (mode, op2);
2807 op2 = expand_powi (op2, mode, abs (n / 3));
2808 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2809 0, OPTAB_LIB_WIDEN);
2810 /* If the original exponent was negative, reciprocate the
2811 result. */
2812 if (n < 0)
2813 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2814 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2816 return op;
2820 /* Fall back to optab expansion. */
2821 return expand_builtin_mathfn_2 (exp, target, subtarget);
2824 /* Expand a call to the powi built-in mathematical function. Return 0 if
2825 a normal call should be emitted rather than expanding the function
2826 in-line. EXP is the expression that is a call to the builtin
2827 function; if convenient, the result should be placed in TARGET. */
2829 static rtx
2830 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2832 tree arglist = TREE_OPERAND (exp, 1);
2833 tree arg0, arg1;
2834 rtx op0, op1;
2835 enum machine_mode mode;
2836 enum machine_mode mode2;
2838 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2839 return 0;
2841 arg0 = TREE_VALUE (arglist);
2842 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2843 mode = TYPE_MODE (TREE_TYPE (exp));
2845 /* Handle constant power. */
2847 if (TREE_CODE (arg1) == INTEGER_CST
2848 && !TREE_OVERFLOW (arg1))
2850 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2852 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2853 Otherwise, check the number of multiplications required. */
2854 if ((TREE_INT_CST_HIGH (arg1) == 0
2855 || TREE_INT_CST_HIGH (arg1) == -1)
2856 && ((n >= -1 && n <= 2)
2857 || (! optimize_size
2858 && powi_cost (n) <= POWI_MAX_MULTS)))
2860 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2861 op0 = force_reg (mode, op0);
2862 return expand_powi (op0, mode, n);
2866 /* Emit a libcall to libgcc. */
2868 /* Mode of the 2nd argument must match that of an int. */
2869 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2871 if (target == NULL_RTX)
2872 target = gen_reg_rtx (mode);
2874 op0 = expand_expr (arg0, subtarget, mode, 0);
2875 if (GET_MODE (op0) != mode)
2876 op0 = convert_to_mode (mode, op0, 0);
2877 op1 = expand_expr (arg1, 0, mode2, 0);
2878 if (GET_MODE (op1) != mode2)
2879 op1 = convert_to_mode (mode2, op1, 0);
2881 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2882 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2883 op0, mode, op1, mode2);
2885 return target;
2888 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2889 if we failed the caller should emit a normal call, otherwise
2890 try to get the result in TARGET, if convenient. */
2892 static rtx
2893 expand_builtin_strlen (tree arglist, rtx target,
2894 enum machine_mode target_mode)
2896 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2897 return 0;
2898 else
2900 rtx pat;
2901 tree len, src = TREE_VALUE (arglist);
2902 rtx result, src_reg, char_rtx, before_strlen;
2903 enum machine_mode insn_mode = target_mode, char_mode;
2904 enum insn_code icode = CODE_FOR_nothing;
2905 int align;
2907 /* If the length can be computed at compile-time, return it. */
2908 len = c_strlen (src, 0);
2909 if (len)
2910 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2912 /* If the length can be computed at compile-time and is constant
2913 integer, but there are side-effects in src, evaluate
2914 src for side-effects, then return len.
2915 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2916 can be optimized into: i++; x = 3; */
2917 len = c_strlen (src, 1);
2918 if (len && TREE_CODE (len) == INTEGER_CST)
2920 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2921 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2924 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2926 /* If SRC is not a pointer type, don't do this operation inline. */
2927 if (align == 0)
2928 return 0;
2930 /* Bail out if we can't compute strlen in the right mode. */
2931 while (insn_mode != VOIDmode)
2933 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2934 if (icode != CODE_FOR_nothing)
2935 break;
2937 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2939 if (insn_mode == VOIDmode)
2940 return 0;
2942 /* Make a place to write the result of the instruction. */
2943 result = target;
2944 if (! (result != 0
2945 && REG_P (result)
2946 && GET_MODE (result) == insn_mode
2947 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2948 result = gen_reg_rtx (insn_mode);
2950 /* Make a place to hold the source address. We will not expand
2951 the actual source until we are sure that the expansion will
2952 not fail -- there are trees that cannot be expanded twice. */
2953 src_reg = gen_reg_rtx (Pmode);
2955 /* Mark the beginning of the strlen sequence so we can emit the
2956 source operand later. */
2957 before_strlen = get_last_insn ();
2959 char_rtx = const0_rtx;
2960 char_mode = insn_data[(int) icode].operand[2].mode;
2961 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2962 char_mode))
2963 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2965 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2966 char_rtx, GEN_INT (align));
2967 if (! pat)
2968 return 0;
2969 emit_insn (pat);
2971 /* Now that we are assured of success, expand the source. */
2972 start_sequence ();
2973 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2974 if (pat != src_reg)
2975 emit_move_insn (src_reg, pat);
2976 pat = get_insns ();
2977 end_sequence ();
2979 if (before_strlen)
2980 emit_insn_after (pat, before_strlen);
2981 else
2982 emit_insn_before (pat, get_insns ());
2984 /* Return the value in the proper mode for this function. */
2985 if (GET_MODE (result) == target_mode)
2986 target = result;
2987 else if (target != 0)
2988 convert_move (target, result, 0);
2989 else
2990 target = convert_to_mode (target_mode, result, 0);
2992 return target;
2996 /* Expand a call to the strstr builtin. Return 0 if we failed the
2997 caller should emit a normal call, otherwise try to get the result
2998 in TARGET, if convenient (and in mode MODE if that's convenient). */
3000 static rtx
3001 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
3003 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3005 tree result = fold_builtin_strstr (arglist, type);
3006 if (result)
3007 return expand_expr (result, target, mode, EXPAND_NORMAL);
3009 return 0;
3012 /* Expand a call to the strchr builtin. Return 0 if we failed the
3013 caller should emit a normal call, otherwise try to get the result
3014 in TARGET, if convenient (and in mode MODE if that's convenient). */
3016 static rtx
3017 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
3019 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3021 tree result = fold_builtin_strchr (arglist, type);
3022 if (result)
3023 return expand_expr (result, target, mode, EXPAND_NORMAL);
3025 /* FIXME: Should use strchrM optab so that ports can optimize this. */
3027 return 0;
3030 /* Expand a call to the strrchr builtin. Return 0 if we failed the
3031 caller should emit a normal call, otherwise try to get the result
3032 in TARGET, if convenient (and in mode MODE if that's convenient). */
3034 static rtx
3035 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
3037 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3039 tree result = fold_builtin_strrchr (arglist, type);
3040 if (result)
3041 return expand_expr (result, target, mode, EXPAND_NORMAL);
3043 return 0;
3046 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
3047 caller should emit a normal call, otherwise try to get the result
3048 in TARGET, if convenient (and in mode MODE if that's convenient). */
3050 static rtx
3051 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
3053 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3055 tree result = fold_builtin_strpbrk (arglist, type);
3056 if (result)
3057 return expand_expr (result, target, mode, EXPAND_NORMAL);
3059 return 0;
3062 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3063 bytes from constant string DATA + OFFSET and return it as target
3064 constant. */
3066 static rtx
3067 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3068 enum machine_mode mode)
3070 const char *str = (const char *) data;
3072 gcc_assert (offset >= 0
3073 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3074 <= strlen (str) + 1));
3076 return c_readstr (str + offset, mode);
3079 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
3080 Return 0 if we failed, the caller should emit a normal call,
3081 otherwise try to get the result in TARGET, if convenient (and in
3082 mode MODE if that's convenient). */
3083 static rtx
3084 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
3086 tree fndecl = get_callee_fndecl (exp);
3087 tree arglist = TREE_OPERAND (exp, 1);
3088 if (!validate_arglist (arglist,
3089 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3090 return 0;
3091 else
3093 tree dest = TREE_VALUE (arglist);
3094 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3095 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3096 const char *src_str;
3097 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3098 unsigned int dest_align
3099 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3100 rtx dest_mem, src_mem, dest_addr, len_rtx;
3101 tree result = fold_builtin_memory_op (arglist, TREE_TYPE (TREE_TYPE (fndecl)),
3102 false, /*endp=*/0);
3103 HOST_WIDE_INT expected_size = -1;
3104 unsigned int expected_align = 0;
3106 if (result)
3108 while (TREE_CODE (result) == COMPOUND_EXPR)
3110 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3111 EXPAND_NORMAL);
3112 result = TREE_OPERAND (result, 1);
3114 return expand_expr (result, target, mode, EXPAND_NORMAL);
3117 /* If DEST is not a pointer type, call the normal function. */
3118 if (dest_align == 0)
3119 return 0;
3121 /* If either SRC is not a pointer type, don't do this
3122 operation in-line. */
3123 if (src_align == 0)
3124 return 0;
3126 stringop_block_profile (exp, &expected_align, &expected_size);
3127 if (expected_align < dest_align)
3128 expected_align = dest_align;
3129 dest_mem = get_memory_rtx (dest, len);
3130 set_mem_align (dest_mem, dest_align);
3131 len_rtx = expand_normal (len);
3132 src_str = c_getstr (src);
3134 /* If SRC is a string constant and block move would be done
3135 by pieces, we can avoid loading the string from memory
3136 and only stored the computed constants. */
3137 if (src_str
3138 && GET_CODE (len_rtx) == CONST_INT
3139 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3140 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3141 (void *) src_str, dest_align))
3143 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3144 builtin_memcpy_read_str,
3145 (void *) src_str, dest_align, 0);
3146 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3147 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3148 return dest_mem;
3151 src_mem = get_memory_rtx (src, len);
3152 set_mem_align (src_mem, src_align);
3154 /* Copy word part most expediently. */
3155 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3156 CALL_EXPR_TAILCALL (exp)
3157 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3158 expected_align, expected_size);
3160 if (dest_addr == 0)
3162 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3163 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3165 return dest_addr;
3169 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
3170 Return 0 if we failed; the caller should emit a normal call,
3171 otherwise try to get the result in TARGET, if convenient (and in
3172 mode MODE if that's convenient). If ENDP is 0 return the
3173 destination pointer, if ENDP is 1 return the end pointer ala
3174 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3175 stpcpy. */
3177 static rtx
3178 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
3179 int endp)
3181 if (!validate_arglist (arglist,
3182 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3183 return 0;
3184 /* If return value is ignored, transform mempcpy into memcpy. */
3185 else if (target == const0_rtx)
3187 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3189 if (!fn)
3190 return 0;
3192 return expand_expr (build_function_call_expr (fn, arglist),
3193 target, mode, EXPAND_NORMAL);
3195 else
3197 tree dest = TREE_VALUE (arglist);
3198 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3199 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3200 const char *src_str;
3201 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3202 unsigned int dest_align
3203 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3204 rtx dest_mem, src_mem, len_rtx;
3205 tree result = fold_builtin_memory_op (arglist, type, false, endp);
3207 if (result)
3209 while (TREE_CODE (result) == COMPOUND_EXPR)
3211 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3212 EXPAND_NORMAL);
3213 result = TREE_OPERAND (result, 1);
3215 return expand_expr (result, target, mode, EXPAND_NORMAL);
3218 /* If either SRC or DEST is not a pointer type, don't do this
3219 operation in-line. */
3220 if (dest_align == 0 || src_align == 0)
3221 return 0;
3223 /* If LEN is not constant, call the normal function. */
3224 if (! host_integerp (len, 1))
3225 return 0;
3227 len_rtx = expand_normal (len);
3228 src_str = c_getstr (src);
3230 /* If SRC is a string constant and block move would be done
3231 by pieces, we can avoid loading the string from memory
3232 and only stored the computed constants. */
3233 if (src_str
3234 && GET_CODE (len_rtx) == CONST_INT
3235 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3236 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3237 (void *) src_str, dest_align))
3239 dest_mem = get_memory_rtx (dest, len);
3240 set_mem_align (dest_mem, dest_align);
3241 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3242 builtin_memcpy_read_str,
3243 (void *) src_str, dest_align, endp);
3244 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3245 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3246 return dest_mem;
3249 if (GET_CODE (len_rtx) == CONST_INT
3250 && can_move_by_pieces (INTVAL (len_rtx),
3251 MIN (dest_align, src_align)))
3253 dest_mem = get_memory_rtx (dest, len);
3254 set_mem_align (dest_mem, dest_align);
3255 src_mem = get_memory_rtx (src, len);
3256 set_mem_align (src_mem, src_align);
3257 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3258 MIN (dest_align, src_align), endp);
3259 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3260 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3261 return dest_mem;
3264 return 0;
3268 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3269 if we failed; the caller should emit a normal call. */
3271 static rtx
3272 expand_builtin_memmove (tree arglist, tree type, rtx target,
3273 enum machine_mode mode)
3275 if (!validate_arglist (arglist,
3276 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3277 return 0;
3278 else
3280 tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3);
3282 if (result)
3284 while (TREE_CODE (result) == COMPOUND_EXPR)
3286 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3287 EXPAND_NORMAL);
3288 result = TREE_OPERAND (result, 1);
3290 return expand_expr (result, target, mode, EXPAND_NORMAL);
3293 /* Otherwise, call the normal function. */
3294 return 0;
3298 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3299 if we failed the caller should emit a normal call. */
3301 static rtx
3302 expand_builtin_bcopy (tree exp)
3304 tree arglist = TREE_OPERAND (exp, 1);
3305 tree type = TREE_TYPE (exp);
3306 tree src, dest, size, newarglist;
3308 if (!validate_arglist (arglist,
3309 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3310 return NULL_RTX;
3312 src = TREE_VALUE (arglist);
3313 dest = TREE_VALUE (TREE_CHAIN (arglist));
3314 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3316 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3317 memmove(ptr y, ptr x, size_t z). This is done this way
3318 so that if it isn't expanded inline, we fallback to
3319 calling bcopy instead of memmove. */
3321 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3322 newarglist = tree_cons (NULL_TREE, src, newarglist);
3323 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3325 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode);
3328 #ifndef HAVE_movstr
3329 # define HAVE_movstr 0
3330 # define CODE_FOR_movstr CODE_FOR_nothing
3331 #endif
3333 /* Expand into a movstr instruction, if one is available. Return 0 if
3334 we failed, the caller should emit a normal call, otherwise try to
3335 get the result in TARGET, if convenient. If ENDP is 0 return the
3336 destination pointer, if ENDP is 1 return the end pointer ala
3337 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3338 stpcpy. */
3340 static rtx
3341 expand_movstr (tree dest, tree src, rtx target, int endp)
3343 rtx end;
3344 rtx dest_mem;
3345 rtx src_mem;
3346 rtx insn;
3347 const struct insn_data * data;
3349 if (!HAVE_movstr)
3350 return 0;
3352 dest_mem = get_memory_rtx (dest, NULL);
3353 src_mem = get_memory_rtx (src, NULL);
3354 if (!endp)
3356 target = force_reg (Pmode, XEXP (dest_mem, 0));
3357 dest_mem = replace_equiv_address (dest_mem, target);
3358 end = gen_reg_rtx (Pmode);
3360 else
3362 if (target == 0 || target == const0_rtx)
3364 end = gen_reg_rtx (Pmode);
3365 if (target == 0)
3366 target = end;
3368 else
3369 end = target;
3372 data = insn_data + CODE_FOR_movstr;
3374 if (data->operand[0].mode != VOIDmode)
3375 end = gen_lowpart (data->operand[0].mode, end);
3377 insn = data->genfun (end, dest_mem, src_mem);
3379 gcc_assert (insn);
3381 emit_insn (insn);
3383 /* movstr is supposed to set end to the address of the NUL
3384 terminator. If the caller requested a mempcpy-like return value,
3385 adjust it. */
3386 if (endp == 1 && target != const0_rtx)
3388 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3389 emit_move_insn (target, force_operand (tem, NULL_RTX));
3392 return target;
3395 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3396 if we failed the caller should emit a normal call, otherwise try to get
3397 the result in TARGET, if convenient (and in mode MODE if that's
3398 convenient). */
3400 static rtx
3401 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3403 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3405 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3406 if (result)
3408 while (TREE_CODE (result) == COMPOUND_EXPR)
3410 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3411 EXPAND_NORMAL);
3412 result = TREE_OPERAND (result, 1);
3414 return expand_expr (result, target, mode, EXPAND_NORMAL);
3417 return expand_movstr (TREE_VALUE (arglist),
3418 TREE_VALUE (TREE_CHAIN (arglist)),
3419 target, /*endp=*/0);
3421 return 0;
3424 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3425 Return 0 if we failed the caller should emit a normal call,
3426 otherwise try to get the result in TARGET, if convenient (and in
3427 mode MODE if that's convenient). */
3429 static rtx
3430 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3432 tree arglist = TREE_OPERAND (exp, 1);
3433 /* If return value is ignored, transform stpcpy into strcpy. */
3434 if (target == const0_rtx)
3436 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3437 if (!fn)
3438 return 0;
3440 return expand_expr (build_function_call_expr (fn, arglist),
3441 target, mode, EXPAND_NORMAL);
3444 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3445 return 0;
3446 else
3448 tree dst, src, len, lenp1;
3449 tree narglist;
3450 rtx ret;
3452 /* Ensure we get an actual string whose length can be evaluated at
3453 compile-time, not an expression containing a string. This is
3454 because the latter will potentially produce pessimized code
3455 when used to produce the return value. */
3456 src = TREE_VALUE (TREE_CHAIN (arglist));
3457 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3458 return expand_movstr (TREE_VALUE (arglist),
3459 TREE_VALUE (TREE_CHAIN (arglist)),
3460 target, /*endp=*/2);
3462 dst = TREE_VALUE (arglist);
3463 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3464 narglist = build_tree_list (NULL_TREE, lenp1);
3465 narglist = tree_cons (NULL_TREE, src, narglist);
3466 narglist = tree_cons (NULL_TREE, dst, narglist);
3467 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3468 target, mode, /*endp=*/2);
3470 if (ret)
3471 return ret;
3473 if (TREE_CODE (len) == INTEGER_CST)
3475 rtx len_rtx = expand_normal (len);
3477 if (GET_CODE (len_rtx) == CONST_INT)
3479 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3480 arglist, target, mode);
3482 if (ret)
3484 if (! target)
3486 if (mode != VOIDmode)
3487 target = gen_reg_rtx (mode);
3488 else
3489 target = gen_reg_rtx (GET_MODE (ret));
3491 if (GET_MODE (target) != GET_MODE (ret))
3492 ret = gen_lowpart (GET_MODE (target), ret);
3494 ret = plus_constant (ret, INTVAL (len_rtx));
3495 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3496 gcc_assert (ret);
3498 return target;
3503 return expand_movstr (TREE_VALUE (arglist),
3504 TREE_VALUE (TREE_CHAIN (arglist)),
3505 target, /*endp=*/2);
3509 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3510 bytes from constant string DATA + OFFSET and return it as target
3511 constant. */
3513 static rtx
3514 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3515 enum machine_mode mode)
3517 const char *str = (const char *) data;
3519 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3520 return const0_rtx;
3522 return c_readstr (str + offset, mode);
3525 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3526 if we failed the caller should emit a normal call. */
3528 static rtx
3529 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3531 tree fndecl = get_callee_fndecl (exp);
3532 tree arglist = TREE_OPERAND (exp, 1);
3533 if (validate_arglist (arglist,
3534 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3536 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3537 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3538 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3540 if (result)
3542 while (TREE_CODE (result) == COMPOUND_EXPR)
3544 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3545 EXPAND_NORMAL);
3546 result = TREE_OPERAND (result, 1);
3548 return expand_expr (result, target, mode, EXPAND_NORMAL);
3551 /* We must be passed a constant len and src parameter. */
3552 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3553 return 0;
3555 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3557 /* We're required to pad with trailing zeros if the requested
3558 len is greater than strlen(s2)+1. In that case try to
3559 use store_by_pieces, if it fails, punt. */
3560 if (tree_int_cst_lt (slen, len))
3562 tree dest = TREE_VALUE (arglist);
3563 unsigned int dest_align
3564 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3565 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3566 rtx dest_mem;
3568 if (!p || dest_align == 0 || !host_integerp (len, 1)
3569 || !can_store_by_pieces (tree_low_cst (len, 1),
3570 builtin_strncpy_read_str,
3571 (void *) p, dest_align))
3572 return 0;
3574 dest_mem = get_memory_rtx (dest, len);
3575 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3576 builtin_strncpy_read_str,
3577 (void *) p, dest_align, 0);
3578 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3579 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3580 return dest_mem;
3583 return 0;
3586 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3587 bytes from constant string DATA + OFFSET and return it as target
3588 constant. */
3591 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3592 enum machine_mode mode)
3594 const char *c = (const char *) data;
3595 char *p = alloca (GET_MODE_SIZE (mode));
3597 memset (p, *c, GET_MODE_SIZE (mode));
3599 return c_readstr (p, mode);
3602 /* Callback routine for store_by_pieces. Return the RTL of a register
3603 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3604 char value given in the RTL register data. For example, if mode is
3605 4 bytes wide, return the RTL for 0x01010101*data. */
3607 static rtx
3608 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3609 enum machine_mode mode)
3611 rtx target, coeff;
3612 size_t size;
3613 char *p;
3615 size = GET_MODE_SIZE (mode);
3616 if (size == 1)
3617 return (rtx) data;
3619 p = alloca (size);
3620 memset (p, 1, size);
3621 coeff = c_readstr (p, mode);
3623 target = convert_to_mode (mode, (rtx) data, 1);
3624 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3625 return force_reg (mode, target);
3628 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3629 if we failed the caller should emit a normal call, otherwise try to get
3630 the result in TARGET, if convenient (and in mode MODE if that's
3631 convenient). */
3633 static rtx
3634 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3635 tree orig_exp)
3637 if (!validate_arglist (arglist,
3638 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3639 return 0;
3640 else
3642 tree dest = TREE_VALUE (arglist);
3643 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3644 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3645 tree fndecl, fn;
3646 enum built_in_function fcode;
3647 char c;
3648 unsigned int dest_align;
3649 rtx dest_mem, dest_addr, len_rtx;
3650 HOST_WIDE_INT expected_size = -1;
3651 unsigned int expected_align = 0;
3653 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3655 /* If DEST is not a pointer type, don't do this
3656 operation in-line. */
3657 if (dest_align == 0)
3658 return 0;
3660 stringop_block_profile (orig_exp, &expected_align, &expected_size);
3661 if (expected_align < dest_align)
3662 expected_align = dest_align;
3664 /* If the LEN parameter is zero, return DEST. */
3665 if (integer_zerop (len))
3667 /* Evaluate and ignore VAL in case it has side-effects. */
3668 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3669 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3672 /* Stabilize the arguments in case we fail. */
3673 dest = builtin_save_expr (dest);
3674 val = builtin_save_expr (val);
3675 len = builtin_save_expr (len);
3677 len_rtx = expand_normal (len);
3678 dest_mem = get_memory_rtx (dest, len);
3680 if (TREE_CODE (val) != INTEGER_CST)
3682 rtx val_rtx;
3684 val_rtx = expand_normal (val);
3685 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3686 val_rtx, 0);
3688 /* Assume that we can memset by pieces if we can store the
3689 * the coefficients by pieces (in the required modes).
3690 * We can't pass builtin_memset_gen_str as that emits RTL. */
3691 c = 1;
3692 if (host_integerp (len, 1)
3693 && !(optimize_size && tree_low_cst (len, 1) > 1)
3694 && can_store_by_pieces (tree_low_cst (len, 1),
3695 builtin_memset_read_str, &c, dest_align))
3697 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3698 val_rtx);
3699 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3700 builtin_memset_gen_str, val_rtx, dest_align, 0);
3702 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3703 dest_align, expected_align,
3704 expected_size))
3705 goto do_libcall;
3707 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3708 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3709 return dest_mem;
3712 if (target_char_cast (val, &c))
3713 goto do_libcall;
3715 if (c)
3717 if (host_integerp (len, 1)
3718 && !(optimize_size && tree_low_cst (len, 1) > 1)
3719 && can_store_by_pieces (tree_low_cst (len, 1),
3720 builtin_memset_read_str, &c, dest_align))
3721 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3722 builtin_memset_read_str, &c, dest_align, 0);
3723 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3724 dest_align, expected_align,
3725 expected_size))
3726 goto do_libcall;
3728 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3729 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3730 return dest_mem;
3733 set_mem_align (dest_mem, dest_align);
3734 dest_addr = clear_storage_hints (dest_mem, len_rtx,
3735 CALL_EXPR_TAILCALL (orig_exp)
3736 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3737 expected_align, expected_size);
3739 if (dest_addr == 0)
3741 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3742 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3745 return dest_addr;
3747 do_libcall:
3748 fndecl = get_callee_fndecl (orig_exp);
3749 fcode = DECL_FUNCTION_CODE (fndecl);
3750 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3751 arglist = build_tree_list (NULL_TREE, len);
3752 if (fcode == BUILT_IN_MEMSET)
3753 arglist = tree_cons (NULL_TREE, val, arglist);
3754 arglist = tree_cons (NULL_TREE, dest, arglist);
3755 fn = build_function_call_expr (fndecl, arglist);
3756 if (TREE_CODE (fn) == CALL_EXPR)
3757 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3758 return expand_call (fn, target, target == const0_rtx);
3762 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3763 if we failed the caller should emit a normal call. */
3765 static rtx
3766 expand_builtin_bzero (tree exp)
3768 tree arglist = TREE_OPERAND (exp, 1);
3769 tree dest, size, newarglist;
3771 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3772 return NULL_RTX;
3774 dest = TREE_VALUE (arglist);
3775 size = TREE_VALUE (TREE_CHAIN (arglist));
3777 /* New argument list transforming bzero(ptr x, int y) to
3778 memset(ptr x, int 0, size_t y). This is done this way
3779 so that if it isn't expanded inline, we fallback to
3780 calling bzero instead of memset. */
3782 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3783 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3784 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3786 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3789 /* Expand expression EXP, which is a call to the memcmp built-in function.
3790 ARGLIST is the argument list for this call. Return 0 if we failed and the
3791 caller should emit a normal call, otherwise try to get the result in
3792 TARGET, if convenient (and in mode MODE, if that's convenient). */
3794 static rtx
3795 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3796 enum machine_mode mode)
3798 if (!validate_arglist (arglist,
3799 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3800 return 0;
3801 else
3803 tree result = fold_builtin_memcmp (arglist);
3804 if (result)
3805 return expand_expr (result, target, mode, EXPAND_NORMAL);
3808 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3810 tree arg1 = TREE_VALUE (arglist);
3811 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3812 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3813 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3814 rtx result;
3815 rtx insn;
3817 int arg1_align
3818 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3819 int arg2_align
3820 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3821 enum machine_mode insn_mode;
3823 #ifdef HAVE_cmpmemsi
3824 if (HAVE_cmpmemsi)
3825 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3826 else
3827 #endif
3828 #ifdef HAVE_cmpstrnsi
3829 if (HAVE_cmpstrnsi)
3830 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3831 else
3832 #endif
3833 return 0;
3835 /* If we don't have POINTER_TYPE, call the function. */
3836 if (arg1_align == 0 || arg2_align == 0)
3837 return 0;
3839 /* Make a place to write the result of the instruction. */
3840 result = target;
3841 if (! (result != 0
3842 && REG_P (result) && GET_MODE (result) == insn_mode
3843 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3844 result = gen_reg_rtx (insn_mode);
3846 arg1_rtx = get_memory_rtx (arg1, len);
3847 arg2_rtx = get_memory_rtx (arg2, len);
3848 arg3_rtx = expand_normal (len);
3850 /* Set MEM_SIZE as appropriate. */
3851 if (GET_CODE (arg3_rtx) == CONST_INT)
3853 set_mem_size (arg1_rtx, arg3_rtx);
3854 set_mem_size (arg2_rtx, arg3_rtx);
3857 #ifdef HAVE_cmpmemsi
3858 if (HAVE_cmpmemsi)
3859 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3860 GEN_INT (MIN (arg1_align, arg2_align)));
3861 else
3862 #endif
3863 #ifdef HAVE_cmpstrnsi
3864 if (HAVE_cmpstrnsi)
3865 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3866 GEN_INT (MIN (arg1_align, arg2_align)));
3867 else
3868 #endif
3869 gcc_unreachable ();
3871 if (insn)
3872 emit_insn (insn);
3873 else
3874 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3875 TYPE_MODE (integer_type_node), 3,
3876 XEXP (arg1_rtx, 0), Pmode,
3877 XEXP (arg2_rtx, 0), Pmode,
3878 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3879 TYPE_UNSIGNED (sizetype)),
3880 TYPE_MODE (sizetype));
3882 /* Return the value in the proper mode for this function. */
3883 mode = TYPE_MODE (TREE_TYPE (exp));
3884 if (GET_MODE (result) == mode)
3885 return result;
3886 else if (target != 0)
3888 convert_move (target, result, 0);
3889 return target;
3891 else
3892 return convert_to_mode (mode, result, 0);
3894 #endif
3896 return 0;
3899 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3900 if we failed the caller should emit a normal call, otherwise try to get
3901 the result in TARGET, if convenient. */
3903 static rtx
3904 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3906 tree arglist = TREE_OPERAND (exp, 1);
3908 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3909 return 0;
3910 else
3912 tree result = fold_builtin_strcmp (arglist);
3913 if (result)
3914 return expand_expr (result, target, mode, EXPAND_NORMAL);
3917 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3918 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3919 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3921 rtx arg1_rtx, arg2_rtx;
3922 rtx result, insn = NULL_RTX;
3923 tree fndecl, fn;
3925 tree arg1 = TREE_VALUE (arglist);
3926 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3927 int arg1_align
3928 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3929 int arg2_align
3930 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3932 /* If we don't have POINTER_TYPE, call the function. */
3933 if (arg1_align == 0 || arg2_align == 0)
3934 return 0;
3936 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3937 arg1 = builtin_save_expr (arg1);
3938 arg2 = builtin_save_expr (arg2);
3940 arg1_rtx = get_memory_rtx (arg1, NULL);
3941 arg2_rtx = get_memory_rtx (arg2, NULL);
3943 #ifdef HAVE_cmpstrsi
3944 /* Try to call cmpstrsi. */
3945 if (HAVE_cmpstrsi)
3947 enum machine_mode insn_mode
3948 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3950 /* Make a place to write the result of the instruction. */
3951 result = target;
3952 if (! (result != 0
3953 && REG_P (result) && GET_MODE (result) == insn_mode
3954 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3955 result = gen_reg_rtx (insn_mode);
3957 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3958 GEN_INT (MIN (arg1_align, arg2_align)));
3960 #endif
3961 #ifdef HAVE_cmpstrnsi
3962 /* Try to determine at least one length and call cmpstrnsi. */
3963 if (!insn && HAVE_cmpstrnsi)
3965 tree len;
3966 rtx arg3_rtx;
3968 enum machine_mode insn_mode
3969 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3970 tree len1 = c_strlen (arg1, 1);
3971 tree len2 = c_strlen (arg2, 1);
3973 if (len1)
3974 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3975 if (len2)
3976 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3978 /* If we don't have a constant length for the first, use the length
3979 of the second, if we know it. We don't require a constant for
3980 this case; some cost analysis could be done if both are available
3981 but neither is constant. For now, assume they're equally cheap,
3982 unless one has side effects. If both strings have constant lengths,
3983 use the smaller. */
3985 if (!len1)
3986 len = len2;
3987 else if (!len2)
3988 len = len1;
3989 else if (TREE_SIDE_EFFECTS (len1))
3990 len = len2;
3991 else if (TREE_SIDE_EFFECTS (len2))
3992 len = len1;
3993 else if (TREE_CODE (len1) != INTEGER_CST)
3994 len = len2;
3995 else if (TREE_CODE (len2) != INTEGER_CST)
3996 len = len1;
3997 else if (tree_int_cst_lt (len1, len2))
3998 len = len1;
3999 else
4000 len = len2;
4002 /* If both arguments have side effects, we cannot optimize. */
4003 if (!len || TREE_SIDE_EFFECTS (len))
4004 goto do_libcall;
4006 arg3_rtx = expand_normal (len);
4008 /* Make a place to write the result of the instruction. */
4009 result = target;
4010 if (! (result != 0
4011 && REG_P (result) && GET_MODE (result) == insn_mode
4012 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4013 result = gen_reg_rtx (insn_mode);
4015 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4016 GEN_INT (MIN (arg1_align, arg2_align)));
4018 #endif
4020 if (insn)
4022 emit_insn (insn);
4024 /* Return the value in the proper mode for this function. */
4025 mode = TYPE_MODE (TREE_TYPE (exp));
4026 if (GET_MODE (result) == mode)
4027 return result;
4028 if (target == 0)
4029 return convert_to_mode (mode, result, 0);
4030 convert_move (target, result, 0);
4031 return target;
4034 /* Expand the library call ourselves using a stabilized argument
4035 list to avoid re-evaluating the function's arguments twice. */
4036 #ifdef HAVE_cmpstrnsi
4037 do_libcall:
4038 #endif
4039 arglist = build_tree_list (NULL_TREE, arg2);
4040 arglist = tree_cons (NULL_TREE, arg1, arglist);
4041 fndecl = get_callee_fndecl (exp);
4042 fn = build_function_call_expr (fndecl, arglist);
4043 if (TREE_CODE (fn) == CALL_EXPR)
4044 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4045 return expand_call (fn, target, target == const0_rtx);
4047 #endif
4048 return 0;
4051 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
4052 if we failed the caller should emit a normal call, otherwise try to get
4053 the result in TARGET, if convenient. */
4055 static rtx
4056 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
4058 tree arglist = TREE_OPERAND (exp, 1);
4060 if (!validate_arglist (arglist,
4061 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4062 return 0;
4063 else
4065 tree result = fold_builtin_strncmp (arglist);
4066 if (result)
4067 return expand_expr (result, target, mode, EXPAND_NORMAL);
4070 /* If c_strlen can determine an expression for one of the string
4071 lengths, and it doesn't have side effects, then emit cmpstrnsi
4072 using length MIN(strlen(string)+1, arg3). */
4073 #ifdef HAVE_cmpstrnsi
4074 if (HAVE_cmpstrnsi)
4076 tree arg1 = TREE_VALUE (arglist);
4077 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
4078 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4079 tree len, len1, len2;
4080 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4081 rtx result, insn;
4082 tree fndecl, fn;
4084 int arg1_align
4085 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4086 int arg2_align
4087 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4088 enum machine_mode insn_mode
4089 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4091 len1 = c_strlen (arg1, 1);
4092 len2 = c_strlen (arg2, 1);
4094 if (len1)
4095 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4096 if (len2)
4097 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4099 /* If we don't have a constant length for the first, use the length
4100 of the second, if we know it. We don't require a constant for
4101 this case; some cost analysis could be done if both are available
4102 but neither is constant. For now, assume they're equally cheap,
4103 unless one has side effects. If both strings have constant lengths,
4104 use the smaller. */
4106 if (!len1)
4107 len = len2;
4108 else if (!len2)
4109 len = len1;
4110 else if (TREE_SIDE_EFFECTS (len1))
4111 len = len2;
4112 else if (TREE_SIDE_EFFECTS (len2))
4113 len = len1;
4114 else if (TREE_CODE (len1) != INTEGER_CST)
4115 len = len2;
4116 else if (TREE_CODE (len2) != INTEGER_CST)
4117 len = len1;
4118 else if (tree_int_cst_lt (len1, len2))
4119 len = len1;
4120 else
4121 len = len2;
4123 /* If both arguments have side effects, we cannot optimize. */
4124 if (!len || TREE_SIDE_EFFECTS (len))
4125 return 0;
4127 /* The actual new length parameter is MIN(len,arg3). */
4128 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
4129 fold_convert (TREE_TYPE (len), arg3));
4131 /* If we don't have POINTER_TYPE, call the function. */
4132 if (arg1_align == 0 || arg2_align == 0)
4133 return 0;
4135 /* Make a place to write the result of the instruction. */
4136 result = target;
4137 if (! (result != 0
4138 && REG_P (result) && GET_MODE (result) == insn_mode
4139 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4140 result = gen_reg_rtx (insn_mode);
4142 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4143 arg1 = builtin_save_expr (arg1);
4144 arg2 = builtin_save_expr (arg2);
4145 len = builtin_save_expr (len);
4147 arg1_rtx = get_memory_rtx (arg1, len);
4148 arg2_rtx = get_memory_rtx (arg2, len);
4149 arg3_rtx = expand_normal (len);
4150 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4151 GEN_INT (MIN (arg1_align, arg2_align)));
4152 if (insn)
4154 emit_insn (insn);
4156 /* Return the value in the proper mode for this function. */
4157 mode = TYPE_MODE (TREE_TYPE (exp));
4158 if (GET_MODE (result) == mode)
4159 return result;
4160 if (target == 0)
4161 return convert_to_mode (mode, result, 0);
4162 convert_move (target, result, 0);
4163 return target;
4166 /* Expand the library call ourselves using a stabilized argument
4167 list to avoid re-evaluating the function's arguments twice. */
4168 arglist = build_tree_list (NULL_TREE, len);
4169 arglist = tree_cons (NULL_TREE, arg2, arglist);
4170 arglist = tree_cons (NULL_TREE, arg1, arglist);
4171 fndecl = get_callee_fndecl (exp);
4172 fn = build_function_call_expr (fndecl, arglist);
4173 if (TREE_CODE (fn) == CALL_EXPR)
4174 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4175 return expand_call (fn, target, target == const0_rtx);
4177 #endif
4178 return 0;
4181 /* Expand expression EXP, which is a call to the strcat builtin.
4182 Return 0 if we failed the caller should emit a normal call,
4183 otherwise try to get the result in TARGET, if convenient. */
4185 static rtx
4186 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
4188 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4189 return 0;
4190 else
4192 tree dst = TREE_VALUE (arglist),
4193 src = TREE_VALUE (TREE_CHAIN (arglist));
4194 const char *p = c_getstr (src);
4196 /* If the string length is zero, return the dst parameter. */
4197 if (p && *p == '\0')
4198 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4200 if (!optimize_size)
4202 /* See if we can store by pieces into (dst + strlen(dst)). */
4203 tree newsrc, newdst,
4204 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4205 rtx insns;
4207 /* Stabilize the argument list. */
4208 newsrc = builtin_save_expr (src);
4209 if (newsrc != src)
4210 arglist = build_tree_list (NULL_TREE, newsrc);
4211 else
4212 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
4214 dst = builtin_save_expr (dst);
4216 start_sequence ();
4218 /* Create strlen (dst). */
4219 newdst =
4220 build_function_call_expr (strlen_fn,
4221 build_tree_list (NULL_TREE, dst));
4222 /* Create (dst + (cast) strlen (dst)). */
4223 newdst = fold_convert (TREE_TYPE (dst), newdst);
4224 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4226 newdst = builtin_save_expr (newdst);
4227 arglist = tree_cons (NULL_TREE, newdst, arglist);
4229 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
4231 end_sequence (); /* Stop sequence. */
4232 return 0;
4235 /* Output the entire sequence. */
4236 insns = get_insns ();
4237 end_sequence ();
4238 emit_insn (insns);
4240 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4243 return 0;
4247 /* Expand expression EXP, which is a call to the strncat builtin.
4248 Return 0 if we failed the caller should emit a normal call,
4249 otherwise try to get the result in TARGET, if convenient. */
4251 static rtx
4252 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4254 if (validate_arglist (arglist,
4255 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4257 tree result = fold_builtin_strncat (arglist);
4258 if (result)
4259 return expand_expr (result, target, mode, EXPAND_NORMAL);
4261 return 0;
4264 /* Expand expression EXP, which is a call to the strspn builtin.
4265 Return 0 if we failed the caller should emit a normal call,
4266 otherwise try to get the result in TARGET, if convenient. */
4268 static rtx
4269 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4271 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4273 tree result = fold_builtin_strspn (arglist);
4274 if (result)
4275 return expand_expr (result, target, mode, EXPAND_NORMAL);
4277 return 0;
4280 /* Expand expression EXP, which is a call to the strcspn builtin.
4281 Return 0 if we failed the caller should emit a normal call,
4282 otherwise try to get the result in TARGET, if convenient. */
4284 static rtx
4285 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4287 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4289 tree result = fold_builtin_strcspn (arglist);
4290 if (result)
4291 return expand_expr (result, target, mode, EXPAND_NORMAL);
4293 return 0;
4296 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4297 if that's convenient. */
4300 expand_builtin_saveregs (void)
4302 rtx val, seq;
4304 /* Don't do __builtin_saveregs more than once in a function.
4305 Save the result of the first call and reuse it. */
4306 if (saveregs_value != 0)
4307 return saveregs_value;
4309 /* When this function is called, it means that registers must be
4310 saved on entry to this function. So we migrate the call to the
4311 first insn of this function. */
4313 start_sequence ();
4315 /* Do whatever the machine needs done in this case. */
4316 val = targetm.calls.expand_builtin_saveregs ();
4318 seq = get_insns ();
4319 end_sequence ();
4321 saveregs_value = val;
4323 /* Put the insns after the NOTE that starts the function. If this
4324 is inside a start_sequence, make the outer-level insn chain current, so
4325 the code is placed at the start of the function. */
4326 push_topmost_sequence ();
4327 emit_insn_after (seq, entry_of_function ());
4328 pop_topmost_sequence ();
4330 return val;
4333 /* __builtin_args_info (N) returns word N of the arg space info
4334 for the current function. The number and meanings of words
4335 is controlled by the definition of CUMULATIVE_ARGS. */
4337 static rtx
4338 expand_builtin_args_info (tree arglist)
4340 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4341 int *word_ptr = (int *) &current_function_args_info;
4343 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4345 if (arglist != 0)
4347 if (!host_integerp (TREE_VALUE (arglist), 0))
4348 error ("argument of %<__builtin_args_info%> must be constant");
4349 else
4351 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4353 if (wordnum < 0 || wordnum >= nwords)
4354 error ("argument of %<__builtin_args_info%> out of range");
4355 else
4356 return GEN_INT (word_ptr[wordnum]);
4359 else
4360 error ("missing argument in %<__builtin_args_info%>");
4362 return const0_rtx;
4365 /* Expand a call to __builtin_next_arg. */
4367 static rtx
4368 expand_builtin_next_arg (void)
4370 /* Checking arguments is already done in fold_builtin_next_arg
4371 that must be called before this function. */
4372 return expand_binop (Pmode, add_optab,
4373 current_function_internal_arg_pointer,
4374 current_function_arg_offset_rtx,
4375 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4378 /* Make it easier for the backends by protecting the valist argument
4379 from multiple evaluations. */
4381 static tree
4382 stabilize_va_list (tree valist, int needs_lvalue)
4384 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4386 if (TREE_SIDE_EFFECTS (valist))
4387 valist = save_expr (valist);
4389 /* For this case, the backends will be expecting a pointer to
4390 TREE_TYPE (va_list_type_node), but it's possible we've
4391 actually been given an array (an actual va_list_type_node).
4392 So fix it. */
4393 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4395 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4396 valist = build_fold_addr_expr_with_type (valist, p1);
4399 else
4401 tree pt;
4403 if (! needs_lvalue)
4405 if (! TREE_SIDE_EFFECTS (valist))
4406 return valist;
4408 pt = build_pointer_type (va_list_type_node);
4409 valist = fold_build1 (ADDR_EXPR, pt, valist);
4410 TREE_SIDE_EFFECTS (valist) = 1;
4413 if (TREE_SIDE_EFFECTS (valist))
4414 valist = save_expr (valist);
4415 valist = build_fold_indirect_ref (valist);
4418 return valist;
4421 /* The "standard" definition of va_list is void*. */
4423 tree
4424 std_build_builtin_va_list (void)
4426 return ptr_type_node;
4429 /* The "standard" implementation of va_start: just assign `nextarg' to
4430 the variable. */
4432 void
4433 std_expand_builtin_va_start (tree valist, rtx nextarg)
4435 tree t;
4437 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist,
4438 make_tree (ptr_type_node, nextarg));
4439 TREE_SIDE_EFFECTS (t) = 1;
4441 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4444 /* Expand ARGLIST, from a call to __builtin_va_start. */
4446 static rtx
4447 expand_builtin_va_start (tree arglist)
4449 rtx nextarg;
4450 tree chain, valist;
4452 chain = TREE_CHAIN (arglist);
4454 if (!chain)
4456 error ("too few arguments to function %<va_start%>");
4457 return const0_rtx;
4460 if (fold_builtin_next_arg (chain))
4461 return const0_rtx;
4463 nextarg = expand_builtin_next_arg ();
4464 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4466 #ifdef EXPAND_BUILTIN_VA_START
4467 EXPAND_BUILTIN_VA_START (valist, nextarg);
4468 #else
4469 std_expand_builtin_va_start (valist, nextarg);
4470 #endif
4472 return const0_rtx;
4475 /* The "standard" implementation of va_arg: read the value from the
4476 current (padded) address and increment by the (padded) size. */
4478 tree
4479 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4481 tree addr, t, type_size, rounded_size, valist_tmp;
4482 unsigned HOST_WIDE_INT align, boundary;
4483 bool indirect;
4485 #ifdef ARGS_GROW_DOWNWARD
4486 /* All of the alignment and movement below is for args-grow-up machines.
4487 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4488 implement their own specialized gimplify_va_arg_expr routines. */
4489 gcc_unreachable ();
4490 #endif
4492 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4493 if (indirect)
4494 type = build_pointer_type (type);
4496 align = PARM_BOUNDARY / BITS_PER_UNIT;
4497 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4499 /* Hoist the valist value into a temporary for the moment. */
4500 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4502 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4503 requires greater alignment, we must perform dynamic alignment. */
4504 if (boundary > align
4505 && !integer_zerop (TYPE_SIZE (type)))
4507 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4508 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist_tmp,
4509 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4510 gimplify_and_add (t, pre_p);
4512 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4513 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist_tmp,
4514 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4515 gimplify_and_add (t, pre_p);
4517 else
4518 boundary = align;
4520 /* If the actual alignment is less than the alignment of the type,
4521 adjust the type accordingly so that we don't assume strict alignment
4522 when deferencing the pointer. */
4523 boundary *= BITS_PER_UNIT;
4524 if (boundary < TYPE_ALIGN (type))
4526 type = build_variant_type_copy (type);
4527 TYPE_ALIGN (type) = boundary;
4530 /* Compute the rounded size of the type. */
4531 type_size = size_in_bytes (type);
4532 rounded_size = round_up (type_size, align);
4534 /* Reduce rounded_size so it's sharable with the postqueue. */
4535 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4537 /* Get AP. */
4538 addr = valist_tmp;
4539 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4541 /* Small args are padded downward. */
4542 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4543 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4544 size_binop (MINUS_EXPR, rounded_size, type_size));
4545 t = fold_convert (TREE_TYPE (addr), t);
4546 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4549 /* Compute new value for AP. */
4550 t = fold_convert (TREE_TYPE (valist), rounded_size);
4551 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4552 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist, t);
4553 gimplify_and_add (t, pre_p);
4555 addr = fold_convert (build_pointer_type (type), addr);
4557 if (indirect)
4558 addr = build_va_arg_indirect_ref (addr);
4560 return build_va_arg_indirect_ref (addr);
4563 /* Build an indirect-ref expression over the given TREE, which represents a
4564 piece of a va_arg() expansion. */
4565 tree
4566 build_va_arg_indirect_ref (tree addr)
4568 addr = build_fold_indirect_ref (addr);
4570 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4571 mf_mark (addr);
4573 return addr;
4576 /* Return a dummy expression of type TYPE in order to keep going after an
4577 error. */
4579 static tree
4580 dummy_object (tree type)
4582 tree t = build_int_cst (build_pointer_type (type), 0);
4583 return build1 (INDIRECT_REF, type, t);
4586 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4587 builtin function, but a very special sort of operator. */
4589 enum gimplify_status
4590 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4592 tree promoted_type, want_va_type, have_va_type;
4593 tree valist = TREE_OPERAND (*expr_p, 0);
4594 tree type = TREE_TYPE (*expr_p);
4595 tree t;
4597 /* Verify that valist is of the proper type. */
4598 want_va_type = va_list_type_node;
4599 have_va_type = TREE_TYPE (valist);
4601 if (have_va_type == error_mark_node)
4602 return GS_ERROR;
4604 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4606 /* If va_list is an array type, the argument may have decayed
4607 to a pointer type, e.g. by being passed to another function.
4608 In that case, unwrap both types so that we can compare the
4609 underlying records. */
4610 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4611 || POINTER_TYPE_P (have_va_type))
4613 want_va_type = TREE_TYPE (want_va_type);
4614 have_va_type = TREE_TYPE (have_va_type);
4618 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4620 error ("first argument to %<va_arg%> not of type %<va_list%>");
4621 return GS_ERROR;
4624 /* Generate a diagnostic for requesting data of a type that cannot
4625 be passed through `...' due to type promotion at the call site. */
4626 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4627 != type)
4629 static bool gave_help;
4631 /* Unfortunately, this is merely undefined, rather than a constraint
4632 violation, so we cannot make this an error. If this call is never
4633 executed, the program is still strictly conforming. */
4634 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4635 type, promoted_type);
4636 if (! gave_help)
4638 gave_help = true;
4639 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4640 promoted_type, type);
4643 /* We can, however, treat "undefined" any way we please.
4644 Call abort to encourage the user to fix the program. */
4645 inform ("if this code is reached, the program will abort");
4646 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4647 NULL);
4648 append_to_statement_list (t, pre_p);
4650 /* This is dead code, but go ahead and finish so that the
4651 mode of the result comes out right. */
4652 *expr_p = dummy_object (type);
4653 return GS_ALL_DONE;
4655 else
4657 /* Make it easier for the backends by protecting the valist argument
4658 from multiple evaluations. */
4659 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4661 /* For this case, the backends will be expecting a pointer to
4662 TREE_TYPE (va_list_type_node), but it's possible we've
4663 actually been given an array (an actual va_list_type_node).
4664 So fix it. */
4665 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4667 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4668 valist = build_fold_addr_expr_with_type (valist, p1);
4670 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4672 else
4673 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4675 if (!targetm.gimplify_va_arg_expr)
4676 /* FIXME:Once most targets are converted we should merely
4677 assert this is non-null. */
4678 return GS_ALL_DONE;
4680 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4681 return GS_OK;
4685 /* Expand ARGLIST, from a call to __builtin_va_end. */
4687 static rtx
4688 expand_builtin_va_end (tree arglist)
4690 tree valist = TREE_VALUE (arglist);
4692 /* Evaluate for side effects, if needed. I hate macros that don't
4693 do that. */
4694 if (TREE_SIDE_EFFECTS (valist))
4695 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4697 return const0_rtx;
4700 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4701 builtin rather than just as an assignment in stdarg.h because of the
4702 nastiness of array-type va_list types. */
4704 static rtx
4705 expand_builtin_va_copy (tree arglist)
4707 tree dst, src, t;
4709 dst = TREE_VALUE (arglist);
4710 src = TREE_VALUE (TREE_CHAIN (arglist));
4712 dst = stabilize_va_list (dst, 1);
4713 src = stabilize_va_list (src, 0);
4715 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4717 t = build2 (GIMPLE_MODIFY_STMT, va_list_type_node, dst, src);
4718 TREE_SIDE_EFFECTS (t) = 1;
4719 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4721 else
4723 rtx dstb, srcb, size;
4725 /* Evaluate to pointers. */
4726 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4727 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4728 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4729 VOIDmode, EXPAND_NORMAL);
4731 dstb = convert_memory_address (Pmode, dstb);
4732 srcb = convert_memory_address (Pmode, srcb);
4734 /* "Dereference" to BLKmode memories. */
4735 dstb = gen_rtx_MEM (BLKmode, dstb);
4736 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4737 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4738 srcb = gen_rtx_MEM (BLKmode, srcb);
4739 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4740 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4742 /* Copy. */
4743 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4746 return const0_rtx;
4749 /* Expand a call to one of the builtin functions __builtin_frame_address or
4750 __builtin_return_address. */
4752 static rtx
4753 expand_builtin_frame_address (tree fndecl, tree arglist)
4755 /* The argument must be a nonnegative integer constant.
4756 It counts the number of frames to scan up the stack.
4757 The value is the return address saved in that frame. */
4758 if (arglist == 0)
4759 /* Warning about missing arg was already issued. */
4760 return const0_rtx;
4761 else if (! host_integerp (TREE_VALUE (arglist), 1))
4763 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4764 error ("invalid argument to %<__builtin_frame_address%>");
4765 else
4766 error ("invalid argument to %<__builtin_return_address%>");
4767 return const0_rtx;
4769 else
4771 rtx tem
4772 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4773 tree_low_cst (TREE_VALUE (arglist), 1));
4775 /* Some ports cannot access arbitrary stack frames. */
4776 if (tem == NULL)
4778 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4779 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4780 else
4781 warning (0, "unsupported argument to %<__builtin_return_address%>");
4782 return const0_rtx;
4785 /* For __builtin_frame_address, return what we've got. */
4786 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4787 return tem;
4789 if (!REG_P (tem)
4790 && ! CONSTANT_P (tem))
4791 tem = copy_to_mode_reg (Pmode, tem);
4792 return tem;
4796 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4797 we failed and the caller should emit a normal call, otherwise try to get
4798 the result in TARGET, if convenient. */
4800 static rtx
4801 expand_builtin_alloca (tree arglist, rtx target)
4803 rtx op0;
4804 rtx result;
4806 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4807 should always expand to function calls. These can be intercepted
4808 in libmudflap. */
4809 if (flag_mudflap)
4810 return 0;
4812 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4813 return 0;
4815 /* Compute the argument. */
4816 op0 = expand_normal (TREE_VALUE (arglist));
4818 /* Allocate the desired space. */
4819 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4820 result = convert_memory_address (ptr_mode, result);
4822 return result;
4825 /* Expand a call to a bswap builtin. The arguments are in ARGLIST. MODE
4826 is the mode to expand with. */
4828 static rtx
4829 expand_builtin_bswap (tree arglist, rtx target, rtx subtarget)
4831 enum machine_mode mode;
4832 tree arg;
4833 rtx op0;
4835 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4836 return 0;
4838 arg = TREE_VALUE (arglist);
4839 mode = TYPE_MODE (TREE_TYPE (arg));
4840 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4842 target = expand_unop (mode, bswap_optab, op0, target, 1);
4844 gcc_assert (target);
4846 return convert_to_mode (mode, target, 0);
4849 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4850 Return 0 if a normal call should be emitted rather than expanding the
4851 function in-line. If convenient, the result should be placed in TARGET.
4852 SUBTARGET may be used as the target for computing one of EXP's operands. */
4854 static rtx
4855 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4856 rtx subtarget, optab op_optab)
4858 rtx op0;
4859 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4860 return 0;
4862 /* Compute the argument. */
4863 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4864 /* Compute op, into TARGET if possible.
4865 Set TARGET to wherever the result comes back. */
4866 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4867 op_optab, op0, target, 1);
4868 gcc_assert (target);
4870 return convert_to_mode (target_mode, target, 0);
4873 /* If the string passed to fputs is a constant and is one character
4874 long, we attempt to transform this call into __builtin_fputc(). */
4876 static rtx
4877 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4879 /* Verify the arguments in the original call. */
4880 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4882 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4883 unlocked, NULL_TREE);
4884 if (result)
4885 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4887 return 0;
4890 /* Expand a call to __builtin_expect. We just return our argument
4891 as the builtin_expect semantic should've been already executed by
4892 tree branch prediction pass. */
4894 static rtx
4895 expand_builtin_expect (tree arglist, rtx target)
4897 tree exp, c;
4899 if (arglist == NULL_TREE
4900 || TREE_CHAIN (arglist) == NULL_TREE)
4901 return const0_rtx;
4902 exp = TREE_VALUE (arglist);
4903 c = TREE_VALUE (TREE_CHAIN (arglist));
4905 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4906 /* When guessing was done, the hints should be already stripped away. */
4907 gcc_assert (!flag_guess_branch_prob);
4908 return target;
4911 void
4912 expand_builtin_trap (void)
4914 #ifdef HAVE_trap
4915 if (HAVE_trap)
4916 emit_insn (gen_trap ());
4917 else
4918 #endif
4919 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4920 emit_barrier ();
4923 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4924 Return 0 if a normal call should be emitted rather than expanding
4925 the function inline. If convenient, the result should be placed
4926 in TARGET. SUBTARGET may be used as the target for computing
4927 the operand. */
4929 static rtx
4930 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4932 enum machine_mode mode;
4933 tree arg;
4934 rtx op0;
4936 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4937 return 0;
4939 arg = TREE_VALUE (arglist);
4940 mode = TYPE_MODE (TREE_TYPE (arg));
4941 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4942 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4945 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4946 Return NULL is a normal call should be emitted rather than expanding the
4947 function inline. If convenient, the result should be placed in TARGET.
4948 SUBTARGET may be used as the target for computing the operand. */
4950 static rtx
4951 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4953 rtx op0, op1;
4954 tree arg;
4956 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4957 return 0;
4959 arg = TREE_VALUE (arglist);
4960 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4962 arg = TREE_VALUE (TREE_CHAIN (arglist));
4963 op1 = expand_normal (arg);
4965 return expand_copysign (op0, op1, target);
4968 /* Create a new constant string literal and return a char* pointer to it.
4969 The STRING_CST value is the LEN characters at STR. */
4970 tree
4971 build_string_literal (int len, const char *str)
4973 tree t, elem, index, type;
4975 t = build_string (len, str);
4976 elem = build_type_variant (char_type_node, 1, 0);
4977 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4978 type = build_array_type (elem, index);
4979 TREE_TYPE (t) = type;
4980 TREE_CONSTANT (t) = 1;
4981 TREE_INVARIANT (t) = 1;
4982 TREE_READONLY (t) = 1;
4983 TREE_STATIC (t) = 1;
4985 type = build_pointer_type (type);
4986 t = build1 (ADDR_EXPR, type, t);
4988 type = build_pointer_type (elem);
4989 t = build1 (NOP_EXPR, type, t);
4990 return t;
4993 /* Expand EXP, a call to printf or printf_unlocked.
4994 Return 0 if a normal call should be emitted rather than transforming
4995 the function inline. If convenient, the result should be placed in
4996 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4997 call. */
4998 static rtx
4999 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
5000 bool unlocked)
5002 tree arglist = TREE_OPERAND (exp, 1);
5003 /* If we're using an unlocked function, assume the other unlocked
5004 functions exist explicitly. */
5005 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5006 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5007 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5008 : implicit_built_in_decls[BUILT_IN_PUTS];
5009 const char *fmt_str;
5010 tree fn, fmt, arg;
5012 /* If the return value is used, don't do the transformation. */
5013 if (target != const0_rtx)
5014 return 0;
5016 /* Verify the required arguments in the original call. */
5017 if (! arglist)
5018 return 0;
5019 fmt = TREE_VALUE (arglist);
5020 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5021 return 0;
5022 arglist = TREE_CHAIN (arglist);
5024 /* Check whether the format is a literal string constant. */
5025 fmt_str = c_getstr (fmt);
5026 if (fmt_str == NULL)
5027 return 0;
5029 if (!init_target_chars())
5030 return 0;
5032 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
5033 if (strcmp (fmt_str, target_percent_s_newline) == 0)
5035 if (! arglist
5036 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5037 || TREE_CHAIN (arglist))
5038 return 0;
5039 fn = fn_puts;
5041 /* If the format specifier was "%c", call __builtin_putchar(arg). */
5042 else if (strcmp (fmt_str, target_percent_c) == 0)
5044 if (! arglist
5045 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5046 || TREE_CHAIN (arglist))
5047 return 0;
5048 fn = fn_putchar;
5050 else
5052 /* We can't handle anything else with % args or %% ... yet. */
5053 if (strchr (fmt_str, target_percent))
5054 return 0;
5056 if (arglist)
5057 return 0;
5059 /* If the format specifier was "", printf does nothing. */
5060 if (fmt_str[0] == '\0')
5061 return const0_rtx;
5062 /* If the format specifier has length of 1, call putchar. */
5063 if (fmt_str[1] == '\0')
5065 /* Given printf("c"), (where c is any one character,)
5066 convert "c"[0] to an int and pass that to the replacement
5067 function. */
5068 arg = build_int_cst (NULL_TREE, fmt_str[0]);
5069 arglist = build_tree_list (NULL_TREE, arg);
5070 fn = fn_putchar;
5072 else
5074 /* If the format specifier was "string\n", call puts("string"). */
5075 size_t len = strlen (fmt_str);
5076 if ((unsigned char)fmt_str[len - 1] == target_newline)
5078 /* Create a NUL-terminated string that's one char shorter
5079 than the original, stripping off the trailing '\n'. */
5080 char *newstr = alloca (len);
5081 memcpy (newstr, fmt_str, len - 1);
5082 newstr[len - 1] = 0;
5084 arg = build_string_literal (len, newstr);
5085 arglist = build_tree_list (NULL_TREE, arg);
5086 fn = fn_puts;
5088 else
5089 /* We'd like to arrange to call fputs(string,stdout) here,
5090 but we need stdout and don't have a way to get it yet. */
5091 return 0;
5095 if (!fn)
5096 return 0;
5097 fn = build_function_call_expr (fn, arglist);
5098 if (TREE_CODE (fn) == CALL_EXPR)
5099 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5100 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5103 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5104 Return 0 if a normal call should be emitted rather than transforming
5105 the function inline. If convenient, the result should be placed in
5106 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5107 call. */
5108 static rtx
5109 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5110 bool unlocked)
5112 tree arglist = TREE_OPERAND (exp, 1);
5113 /* If we're using an unlocked function, assume the other unlocked
5114 functions exist explicitly. */
5115 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5116 : implicit_built_in_decls[BUILT_IN_FPUTC];
5117 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5118 : implicit_built_in_decls[BUILT_IN_FPUTS];
5119 const char *fmt_str;
5120 tree fn, fmt, fp, arg;
5122 /* If the return value is used, don't do the transformation. */
5123 if (target != const0_rtx)
5124 return 0;
5126 /* Verify the required arguments in the original call. */
5127 if (! arglist)
5128 return 0;
5129 fp = TREE_VALUE (arglist);
5130 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5131 return 0;
5132 arglist = TREE_CHAIN (arglist);
5133 if (! arglist)
5134 return 0;
5135 fmt = TREE_VALUE (arglist);
5136 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5137 return 0;
5138 arglist = TREE_CHAIN (arglist);
5140 /* Check whether the format is a literal string constant. */
5141 fmt_str = c_getstr (fmt);
5142 if (fmt_str == NULL)
5143 return 0;
5145 if (!init_target_chars())
5146 return 0;
5148 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5149 if (strcmp (fmt_str, target_percent_s) == 0)
5151 if (! arglist
5152 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5153 || TREE_CHAIN (arglist))
5154 return 0;
5155 arg = TREE_VALUE (arglist);
5156 arglist = build_tree_list (NULL_TREE, fp);
5157 arglist = tree_cons (NULL_TREE, arg, arglist);
5158 fn = fn_fputs;
5160 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5161 else if (strcmp (fmt_str, target_percent_c) == 0)
5163 if (! arglist
5164 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5165 || TREE_CHAIN (arglist))
5166 return 0;
5167 arg = TREE_VALUE (arglist);
5168 arglist = build_tree_list (NULL_TREE, fp);
5169 arglist = tree_cons (NULL_TREE, arg, arglist);
5170 fn = fn_fputc;
5172 else
5174 /* We can't handle anything else with % args or %% ... yet. */
5175 if (strchr (fmt_str, target_percent))
5176 return 0;
5178 if (arglist)
5179 return 0;
5181 /* If the format specifier was "", fprintf does nothing. */
5182 if (fmt_str[0] == '\0')
5184 /* Evaluate and ignore FILE* argument for side-effects. */
5185 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5186 return const0_rtx;
5189 /* When "string" doesn't contain %, replace all cases of
5190 fprintf(stream,string) with fputs(string,stream). The fputs
5191 builtin will take care of special cases like length == 1. */
5192 arglist = build_tree_list (NULL_TREE, fp);
5193 arglist = tree_cons (NULL_TREE, fmt, arglist);
5194 fn = fn_fputs;
5197 if (!fn)
5198 return 0;
5199 fn = build_function_call_expr (fn, arglist);
5200 if (TREE_CODE (fn) == CALL_EXPR)
5201 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5202 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5205 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5206 a normal call should be emitted rather than expanding the function
5207 inline. If convenient, the result should be placed in TARGET with
5208 mode MODE. */
5210 static rtx
5211 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5213 tree orig_arglist, dest, fmt;
5214 const char *fmt_str;
5216 orig_arglist = arglist;
5218 /* Verify the required arguments in the original call. */
5219 if (! arglist)
5220 return 0;
5221 dest = TREE_VALUE (arglist);
5222 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5223 return 0;
5224 arglist = TREE_CHAIN (arglist);
5225 if (! arglist)
5226 return 0;
5227 fmt = TREE_VALUE (arglist);
5228 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5229 return 0;
5230 arglist = TREE_CHAIN (arglist);
5232 /* Check whether the format is a literal string constant. */
5233 fmt_str = c_getstr (fmt);
5234 if (fmt_str == NULL)
5235 return 0;
5237 if (!init_target_chars())
5238 return 0;
5240 /* If the format doesn't contain % args or %%, use strcpy. */
5241 if (strchr (fmt_str, target_percent) == 0)
5243 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5244 tree exp;
5246 if (arglist || ! fn)
5247 return 0;
5248 expand_expr (build_function_call_expr (fn, orig_arglist),
5249 const0_rtx, VOIDmode, EXPAND_NORMAL);
5250 if (target == const0_rtx)
5251 return const0_rtx;
5252 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5253 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5255 /* If the format is "%s", use strcpy if the result isn't used. */
5256 else if (strcmp (fmt_str, target_percent_s) == 0)
5258 tree fn, arg, len;
5259 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5261 if (! fn)
5262 return 0;
5264 if (! arglist || TREE_CHAIN (arglist))
5265 return 0;
5266 arg = TREE_VALUE (arglist);
5267 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5268 return 0;
5270 if (target != const0_rtx)
5272 len = c_strlen (arg, 1);
5273 if (! len || TREE_CODE (len) != INTEGER_CST)
5274 return 0;
5276 else
5277 len = NULL_TREE;
5279 arglist = build_tree_list (NULL_TREE, arg);
5280 arglist = tree_cons (NULL_TREE, dest, arglist);
5281 expand_expr (build_function_call_expr (fn, arglist),
5282 const0_rtx, VOIDmode, EXPAND_NORMAL);
5284 if (target == const0_rtx)
5285 return const0_rtx;
5286 return expand_expr (len, target, mode, EXPAND_NORMAL);
5289 return 0;
5292 /* Expand a call to either the entry or exit function profiler. */
5294 static rtx
5295 expand_builtin_profile_func (bool exitp)
5297 rtx this, which;
5299 this = DECL_RTL (current_function_decl);
5300 gcc_assert (MEM_P (this));
5301 this = XEXP (this, 0);
5303 if (exitp)
5304 which = profile_function_exit_libfunc;
5305 else
5306 which = profile_function_entry_libfunc;
5308 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5309 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5311 Pmode);
5313 return const0_rtx;
5316 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5318 static rtx
5319 round_trampoline_addr (rtx tramp)
5321 rtx temp, addend, mask;
5323 /* If we don't need too much alignment, we'll have been guaranteed
5324 proper alignment by get_trampoline_type. */
5325 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5326 return tramp;
5328 /* Round address up to desired boundary. */
5329 temp = gen_reg_rtx (Pmode);
5330 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5331 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5333 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5334 temp, 0, OPTAB_LIB_WIDEN);
5335 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5336 temp, 0, OPTAB_LIB_WIDEN);
5338 return tramp;
5341 static rtx
5342 expand_builtin_init_trampoline (tree arglist)
5344 tree t_tramp, t_func, t_chain;
5345 rtx r_tramp, r_func, r_chain;
5346 #ifdef TRAMPOLINE_TEMPLATE
5347 rtx blktramp;
5348 #endif
5350 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5351 POINTER_TYPE, VOID_TYPE))
5352 return NULL_RTX;
5354 t_tramp = TREE_VALUE (arglist);
5355 arglist = TREE_CHAIN (arglist);
5356 t_func = TREE_VALUE (arglist);
5357 arglist = TREE_CHAIN (arglist);
5358 t_chain = TREE_VALUE (arglist);
5360 r_tramp = expand_normal (t_tramp);
5361 r_func = expand_normal (t_func);
5362 r_chain = expand_normal (t_chain);
5364 /* Generate insns to initialize the trampoline. */
5365 r_tramp = round_trampoline_addr (r_tramp);
5366 #ifdef TRAMPOLINE_TEMPLATE
5367 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5368 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5369 emit_block_move (blktramp, assemble_trampoline_template (),
5370 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5371 #endif
5372 trampolines_created = 1;
5373 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5375 return const0_rtx;
5378 static rtx
5379 expand_builtin_adjust_trampoline (tree arglist)
5381 rtx tramp;
5383 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5384 return NULL_RTX;
5386 tramp = expand_normal (TREE_VALUE (arglist));
5387 tramp = round_trampoline_addr (tramp);
5388 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5389 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5390 #endif
5392 return tramp;
5395 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5396 Return NULL_RTX if a normal call should be emitted rather than expanding
5397 the function in-line. EXP is the expression that is a call to the builtin
5398 function; if convenient, the result should be placed in TARGET. */
5400 static rtx
5401 expand_builtin_signbit (tree exp, rtx target)
5403 const struct real_format *fmt;
5404 enum machine_mode fmode, imode, rmode;
5405 HOST_WIDE_INT hi, lo;
5406 tree arg, arglist;
5407 int word, bitpos;
5408 rtx temp;
5410 arglist = TREE_OPERAND (exp, 1);
5411 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5412 return 0;
5414 arg = TREE_VALUE (arglist);
5415 fmode = TYPE_MODE (TREE_TYPE (arg));
5416 rmode = TYPE_MODE (TREE_TYPE (exp));
5417 fmt = REAL_MODE_FORMAT (fmode);
5419 /* For floating point formats without a sign bit, implement signbit
5420 as "ARG < 0.0". */
5421 bitpos = fmt->signbit_ro;
5422 if (bitpos < 0)
5424 /* But we can't do this if the format supports signed zero. */
5425 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5426 return 0;
5428 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5429 build_real (TREE_TYPE (arg), dconst0));
5430 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5433 temp = expand_normal (arg);
5434 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5436 imode = int_mode_for_mode (fmode);
5437 if (imode == BLKmode)
5438 return 0;
5439 temp = gen_lowpart (imode, temp);
5441 else
5443 imode = word_mode;
5444 /* Handle targets with different FP word orders. */
5445 if (FLOAT_WORDS_BIG_ENDIAN)
5446 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5447 else
5448 word = bitpos / BITS_PER_WORD;
5449 temp = operand_subword_force (temp, word, fmode);
5450 bitpos = bitpos % BITS_PER_WORD;
5453 /* Force the intermediate word_mode (or narrower) result into a
5454 register. This avoids attempting to create paradoxical SUBREGs
5455 of floating point modes below. */
5456 temp = force_reg (imode, temp);
5458 /* If the bitpos is within the "result mode" lowpart, the operation
5459 can be implement with a single bitwise AND. Otherwise, we need
5460 a right shift and an AND. */
5462 if (bitpos < GET_MODE_BITSIZE (rmode))
5464 if (bitpos < HOST_BITS_PER_WIDE_INT)
5466 hi = 0;
5467 lo = (HOST_WIDE_INT) 1 << bitpos;
5469 else
5471 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5472 lo = 0;
5475 if (imode != rmode)
5476 temp = gen_lowpart (rmode, temp);
5477 temp = expand_binop (rmode, and_optab, temp,
5478 immed_double_const (lo, hi, rmode),
5479 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5481 else
5483 /* Perform a logical right shift to place the signbit in the least
5484 significant bit, then truncate the result to the desired mode
5485 and mask just this bit. */
5486 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5487 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5488 temp = gen_lowpart (rmode, temp);
5489 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5490 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5493 return temp;
5496 /* Expand fork or exec calls. TARGET is the desired target of the
5497 call. ARGLIST is the list of arguments of the call. FN is the
5498 identificator of the actual function. IGNORE is nonzero if the
5499 value is to be ignored. */
5501 static rtx
5502 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5504 tree id, decl;
5505 tree call;
5507 /* If we are not profiling, just call the function. */
5508 if (!profile_arc_flag)
5509 return NULL_RTX;
5511 /* Otherwise call the wrapper. This should be equivalent for the rest of
5512 compiler, so the code does not diverge, and the wrapper may run the
5513 code necessary for keeping the profiling sane. */
5515 switch (DECL_FUNCTION_CODE (fn))
5517 case BUILT_IN_FORK:
5518 id = get_identifier ("__gcov_fork");
5519 break;
5521 case BUILT_IN_EXECL:
5522 id = get_identifier ("__gcov_execl");
5523 break;
5525 case BUILT_IN_EXECV:
5526 id = get_identifier ("__gcov_execv");
5527 break;
5529 case BUILT_IN_EXECLP:
5530 id = get_identifier ("__gcov_execlp");
5531 break;
5533 case BUILT_IN_EXECLE:
5534 id = get_identifier ("__gcov_execle");
5535 break;
5537 case BUILT_IN_EXECVP:
5538 id = get_identifier ("__gcov_execvp");
5539 break;
5541 case BUILT_IN_EXECVE:
5542 id = get_identifier ("__gcov_execve");
5543 break;
5545 default:
5546 gcc_unreachable ();
5549 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5550 DECL_EXTERNAL (decl) = 1;
5551 TREE_PUBLIC (decl) = 1;
5552 DECL_ARTIFICIAL (decl) = 1;
5553 TREE_NOTHROW (decl) = 1;
5554 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5555 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5556 call = build_function_call_expr (decl, arglist);
5558 return expand_call (call, target, ignore);
5562 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5563 the pointer in these functions is void*, the tree optimizers may remove
5564 casts. The mode computed in expand_builtin isn't reliable either, due
5565 to __sync_bool_compare_and_swap.
5567 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5568 group of builtins. This gives us log2 of the mode size. */
5570 static inline enum machine_mode
5571 get_builtin_sync_mode (int fcode_diff)
5573 /* The size is not negotiable, so ask not to get BLKmode in return
5574 if the target indicates that a smaller size would be better. */
5575 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5578 /* Expand the memory expression LOC and return the appropriate memory operand
5579 for the builtin_sync operations. */
5581 static rtx
5582 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5584 rtx addr, mem;
5586 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5588 /* Note that we explicitly do not want any alias information for this
5589 memory, so that we kill all other live memories. Otherwise we don't
5590 satisfy the full barrier semantics of the intrinsic. */
5591 mem = validize_mem (gen_rtx_MEM (mode, addr));
5593 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5594 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5595 MEM_VOLATILE_P (mem) = 1;
5597 return mem;
5600 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5601 ARGLIST is the operands list to the function. CODE is the rtx code
5602 that corresponds to the arithmetic or logical operation from the name;
5603 an exception here is that NOT actually means NAND. TARGET is an optional
5604 place for us to store the results; AFTER is true if this is the
5605 fetch_and_xxx form. IGNORE is true if we don't actually care about
5606 the result of the operation at all. */
5608 static rtx
5609 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5610 enum rtx_code code, bool after,
5611 rtx target, bool ignore)
5613 rtx val, mem;
5615 /* Expand the operands. */
5616 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5618 arglist = TREE_CHAIN (arglist);
5619 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5620 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5621 val = convert_to_mode (mode, val, 1);
5623 if (ignore)
5624 return expand_sync_operation (mem, val, code);
5625 else
5626 return expand_sync_fetch_operation (mem, val, code, after, target);
5629 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5630 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5631 true if this is the boolean form. TARGET is a place for us to store the
5632 results; this is NOT optional if IS_BOOL is true. */
5634 static rtx
5635 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5636 bool is_bool, rtx target)
5638 rtx old_val, new_val, mem;
5640 /* Expand the operands. */
5641 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5643 arglist = TREE_CHAIN (arglist);
5644 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5645 /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */
5646 old_val = convert_to_mode (mode, old_val, 1);
5648 arglist = TREE_CHAIN (arglist);
5649 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5650 /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */
5651 new_val = convert_to_mode (mode, new_val, 1);
5653 if (is_bool)
5654 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5655 else
5656 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5659 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5660 general form is actually an atomic exchange, and some targets only
5661 support a reduced form with the second argument being a constant 1.
5662 ARGLIST is the operands list to the function; TARGET is an optional
5663 place for us to store the results. */
5665 static rtx
5666 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5667 rtx target)
5669 rtx val, mem;
5671 /* Expand the operands. */
5672 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5674 arglist = TREE_CHAIN (arglist);
5675 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5676 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5677 val = convert_to_mode (mode, val, 1);
5679 return expand_sync_lock_test_and_set (mem, val, target);
5682 /* Expand the __sync_synchronize intrinsic. */
5684 static void
5685 expand_builtin_synchronize (void)
5687 tree x;
5689 #ifdef HAVE_memory_barrier
5690 if (HAVE_memory_barrier)
5692 emit_insn (gen_memory_barrier ());
5693 return;
5695 #endif
5697 /* If no explicit memory barrier instruction is available, create an
5698 empty asm stmt with a memory clobber. */
5699 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5700 tree_cons (NULL, build_string (6, "memory"), NULL));
5701 ASM_VOLATILE_P (x) = 1;
5702 expand_asm_expr (x);
5705 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5706 to the function. */
5708 static void
5709 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5711 enum insn_code icode;
5712 rtx mem, insn;
5713 rtx val = const0_rtx;
5715 /* Expand the operands. */
5716 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5718 /* If there is an explicit operation in the md file, use it. */
5719 icode = sync_lock_release[mode];
5720 if (icode != CODE_FOR_nothing)
5722 if (!insn_data[icode].operand[1].predicate (val, mode))
5723 val = force_reg (mode, val);
5725 insn = GEN_FCN (icode) (mem, val);
5726 if (insn)
5728 emit_insn (insn);
5729 return;
5733 /* Otherwise we can implement this operation by emitting a barrier
5734 followed by a store of zero. */
5735 expand_builtin_synchronize ();
5736 emit_move_insn (mem, val);
5739 /* Expand an expression EXP that calls a built-in function,
5740 with result going to TARGET if that's convenient
5741 (and in mode MODE if that's convenient).
5742 SUBTARGET may be used as the target for computing one of EXP's operands.
5743 IGNORE is nonzero if the value is to be ignored. */
5746 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5747 int ignore)
5749 tree fndecl = get_callee_fndecl (exp);
5750 tree arglist = TREE_OPERAND (exp, 1);
5751 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5752 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5754 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5755 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5757 /* When not optimizing, generate calls to library functions for a certain
5758 set of builtins. */
5759 if (!optimize
5760 && !called_as_built_in (fndecl)
5761 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5762 && fcode != BUILT_IN_ALLOCA)
5763 return expand_call (exp, target, ignore);
5765 /* The built-in function expanders test for target == const0_rtx
5766 to determine whether the function's result will be ignored. */
5767 if (ignore)
5768 target = const0_rtx;
5770 /* If the result of a pure or const built-in function is ignored, and
5771 none of its arguments are volatile, we can avoid expanding the
5772 built-in call and just evaluate the arguments for side-effects. */
5773 if (target == const0_rtx
5774 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5776 bool volatilep = false;
5777 tree arg;
5779 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5780 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5782 volatilep = true;
5783 break;
5786 if (! volatilep)
5788 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5789 expand_expr (TREE_VALUE (arg), const0_rtx,
5790 VOIDmode, EXPAND_NORMAL);
5791 return const0_rtx;
5795 switch (fcode)
5797 CASE_FLT_FN (BUILT_IN_FABS):
5798 target = expand_builtin_fabs (arglist, target, subtarget);
5799 if (target)
5800 return target;
5801 break;
5803 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5804 target = expand_builtin_copysign (arglist, target, subtarget);
5805 if (target)
5806 return target;
5807 break;
5809 /* Just do a normal library call if we were unable to fold
5810 the values. */
5811 CASE_FLT_FN (BUILT_IN_CABS):
5812 break;
5814 CASE_FLT_FN (BUILT_IN_EXP):
5815 CASE_FLT_FN (BUILT_IN_EXP10):
5816 CASE_FLT_FN (BUILT_IN_POW10):
5817 CASE_FLT_FN (BUILT_IN_EXP2):
5818 CASE_FLT_FN (BUILT_IN_EXPM1):
5819 CASE_FLT_FN (BUILT_IN_LOGB):
5820 CASE_FLT_FN (BUILT_IN_ILOGB):
5821 CASE_FLT_FN (BUILT_IN_LOG):
5822 CASE_FLT_FN (BUILT_IN_LOG10):
5823 CASE_FLT_FN (BUILT_IN_LOG2):
5824 CASE_FLT_FN (BUILT_IN_LOG1P):
5825 CASE_FLT_FN (BUILT_IN_TAN):
5826 CASE_FLT_FN (BUILT_IN_ASIN):
5827 CASE_FLT_FN (BUILT_IN_ACOS):
5828 CASE_FLT_FN (BUILT_IN_ATAN):
5829 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5830 because of possible accuracy problems. */
5831 if (! flag_unsafe_math_optimizations)
5832 break;
5833 CASE_FLT_FN (BUILT_IN_SQRT):
5834 CASE_FLT_FN (BUILT_IN_FLOOR):
5835 CASE_FLT_FN (BUILT_IN_CEIL):
5836 CASE_FLT_FN (BUILT_IN_TRUNC):
5837 CASE_FLT_FN (BUILT_IN_ROUND):
5838 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5839 CASE_FLT_FN (BUILT_IN_RINT):
5840 target = expand_builtin_mathfn (exp, target, subtarget);
5841 if (target)
5842 return target;
5843 break;
5845 CASE_FLT_FN (BUILT_IN_LCEIL):
5846 CASE_FLT_FN (BUILT_IN_LLCEIL):
5847 CASE_FLT_FN (BUILT_IN_LFLOOR):
5848 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5849 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5850 if (target)
5851 return target;
5852 break;
5854 CASE_FLT_FN (BUILT_IN_LRINT):
5855 CASE_FLT_FN (BUILT_IN_LLRINT):
5856 CASE_FLT_FN (BUILT_IN_LROUND):
5857 CASE_FLT_FN (BUILT_IN_LLROUND):
5858 target = expand_builtin_int_roundingfn_2 (exp, target, subtarget);
5859 if (target)
5860 return target;
5861 break;
5863 CASE_FLT_FN (BUILT_IN_POW):
5864 target = expand_builtin_pow (exp, target, subtarget);
5865 if (target)
5866 return target;
5867 break;
5869 CASE_FLT_FN (BUILT_IN_POWI):
5870 target = expand_builtin_powi (exp, target, subtarget);
5871 if (target)
5872 return target;
5873 break;
5875 CASE_FLT_FN (BUILT_IN_ATAN2):
5876 CASE_FLT_FN (BUILT_IN_LDEXP):
5877 if (! flag_unsafe_math_optimizations)
5878 break;
5880 CASE_FLT_FN (BUILT_IN_FMOD):
5881 CASE_FLT_FN (BUILT_IN_REMAINDER):
5882 CASE_FLT_FN (BUILT_IN_DREM):
5883 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5884 if (target)
5885 return target;
5886 break;
5888 CASE_FLT_FN (BUILT_IN_CEXPI):
5889 target = expand_builtin_cexpi (exp, target, subtarget);
5890 gcc_assert (target);
5891 return target;
5893 CASE_FLT_FN (BUILT_IN_SIN):
5894 CASE_FLT_FN (BUILT_IN_COS):
5895 if (! flag_unsafe_math_optimizations)
5896 break;
5897 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5898 if (target)
5899 return target;
5900 break;
5902 CASE_FLT_FN (BUILT_IN_SINCOS):
5903 if (! flag_unsafe_math_optimizations)
5904 break;
5905 target = expand_builtin_sincos (exp);
5906 if (target)
5907 return target;
5908 break;
5910 case BUILT_IN_APPLY_ARGS:
5911 return expand_builtin_apply_args ();
5913 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5914 FUNCTION with a copy of the parameters described by
5915 ARGUMENTS, and ARGSIZE. It returns a block of memory
5916 allocated on the stack into which is stored all the registers
5917 that might possibly be used for returning the result of a
5918 function. ARGUMENTS is the value returned by
5919 __builtin_apply_args. ARGSIZE is the number of bytes of
5920 arguments that must be copied. ??? How should this value be
5921 computed? We'll also need a safe worst case value for varargs
5922 functions. */
5923 case BUILT_IN_APPLY:
5924 if (!validate_arglist (arglist, POINTER_TYPE,
5925 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5926 && !validate_arglist (arglist, REFERENCE_TYPE,
5927 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5928 return const0_rtx;
5929 else
5931 int i;
5932 tree t;
5933 rtx ops[3];
5935 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5936 ops[i] = expand_normal (TREE_VALUE (t));
5938 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5941 /* __builtin_return (RESULT) causes the function to return the
5942 value described by RESULT. RESULT is address of the block of
5943 memory returned by __builtin_apply. */
5944 case BUILT_IN_RETURN:
5945 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5946 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5947 return const0_rtx;
5949 case BUILT_IN_SAVEREGS:
5950 return expand_builtin_saveregs ();
5952 case BUILT_IN_ARGS_INFO:
5953 return expand_builtin_args_info (arglist);
5955 /* Return the address of the first anonymous stack arg. */
5956 case BUILT_IN_NEXT_ARG:
5957 if (fold_builtin_next_arg (arglist))
5958 return const0_rtx;
5959 return expand_builtin_next_arg ();
5961 case BUILT_IN_CLASSIFY_TYPE:
5962 return expand_builtin_classify_type (arglist);
5964 case BUILT_IN_CONSTANT_P:
5965 return const0_rtx;
5967 case BUILT_IN_FRAME_ADDRESS:
5968 case BUILT_IN_RETURN_ADDRESS:
5969 return expand_builtin_frame_address (fndecl, arglist);
5971 /* Returns the address of the area where the structure is returned.
5972 0 otherwise. */
5973 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5974 if (arglist != 0
5975 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5976 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5977 return const0_rtx;
5978 else
5979 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5981 case BUILT_IN_ALLOCA:
5982 target = expand_builtin_alloca (arglist, target);
5983 if (target)
5984 return target;
5985 break;
5987 case BUILT_IN_STACK_SAVE:
5988 return expand_stack_save ();
5990 case BUILT_IN_STACK_RESTORE:
5991 expand_stack_restore (TREE_VALUE (arglist));
5992 return const0_rtx;
5994 case BUILT_IN_BSWAP32:
5995 case BUILT_IN_BSWAP64:
5996 target = expand_builtin_bswap (arglist, target, subtarget);
5998 if (target)
5999 return target;
6000 break;
6002 CASE_INT_FN (BUILT_IN_FFS):
6003 case BUILT_IN_FFSIMAX:
6004 target = expand_builtin_unop (target_mode, arglist, target,
6005 subtarget, ffs_optab);
6006 if (target)
6007 return target;
6008 break;
6010 CASE_INT_FN (BUILT_IN_CLZ):
6011 case BUILT_IN_CLZIMAX:
6012 target = expand_builtin_unop (target_mode, arglist, target,
6013 subtarget, clz_optab);
6014 if (target)
6015 return target;
6016 break;
6018 CASE_INT_FN (BUILT_IN_CTZ):
6019 case BUILT_IN_CTZIMAX:
6020 target = expand_builtin_unop (target_mode, arglist, target,
6021 subtarget, ctz_optab);
6022 if (target)
6023 return target;
6024 break;
6026 CASE_INT_FN (BUILT_IN_POPCOUNT):
6027 case BUILT_IN_POPCOUNTIMAX:
6028 target = expand_builtin_unop (target_mode, arglist, target,
6029 subtarget, popcount_optab);
6030 if (target)
6031 return target;
6032 break;
6034 CASE_INT_FN (BUILT_IN_PARITY):
6035 case BUILT_IN_PARITYIMAX:
6036 target = expand_builtin_unop (target_mode, arglist, target,
6037 subtarget, parity_optab);
6038 if (target)
6039 return target;
6040 break;
6042 case BUILT_IN_STRLEN:
6043 target = expand_builtin_strlen (arglist, target, target_mode);
6044 if (target)
6045 return target;
6046 break;
6048 case BUILT_IN_STRCPY:
6049 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
6050 if (target)
6051 return target;
6052 break;
6054 case BUILT_IN_STRNCPY:
6055 target = expand_builtin_strncpy (exp, target, mode);
6056 if (target)
6057 return target;
6058 break;
6060 case BUILT_IN_STPCPY:
6061 target = expand_builtin_stpcpy (exp, target, mode);
6062 if (target)
6063 return target;
6064 break;
6066 case BUILT_IN_STRCAT:
6067 target = expand_builtin_strcat (fndecl, arglist, target, mode);
6068 if (target)
6069 return target;
6070 break;
6072 case BUILT_IN_STRNCAT:
6073 target = expand_builtin_strncat (arglist, target, mode);
6074 if (target)
6075 return target;
6076 break;
6078 case BUILT_IN_STRSPN:
6079 target = expand_builtin_strspn (arglist, target, mode);
6080 if (target)
6081 return target;
6082 break;
6084 case BUILT_IN_STRCSPN:
6085 target = expand_builtin_strcspn (arglist, target, mode);
6086 if (target)
6087 return target;
6088 break;
6090 case BUILT_IN_STRSTR:
6091 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
6092 if (target)
6093 return target;
6094 break;
6096 case BUILT_IN_STRPBRK:
6097 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
6098 if (target)
6099 return target;
6100 break;
6102 case BUILT_IN_INDEX:
6103 case BUILT_IN_STRCHR:
6104 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
6105 if (target)
6106 return target;
6107 break;
6109 case BUILT_IN_RINDEX:
6110 case BUILT_IN_STRRCHR:
6111 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
6112 if (target)
6113 return target;
6114 break;
6116 case BUILT_IN_MEMCPY:
6117 target = expand_builtin_memcpy (exp, target, mode);
6118 if (target)
6119 return target;
6120 break;
6122 case BUILT_IN_MEMPCPY:
6123 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6124 if (target)
6125 return target;
6126 break;
6128 case BUILT_IN_MEMMOVE:
6129 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6130 mode);
6131 if (target)
6132 return target;
6133 break;
6135 case BUILT_IN_BCOPY:
6136 target = expand_builtin_bcopy (exp);
6137 if (target)
6138 return target;
6139 break;
6141 case BUILT_IN_MEMSET:
6142 target = expand_builtin_memset (arglist, target, mode, exp);
6143 if (target)
6144 return target;
6145 break;
6147 case BUILT_IN_BZERO:
6148 target = expand_builtin_bzero (exp);
6149 if (target)
6150 return target;
6151 break;
6153 case BUILT_IN_STRCMP:
6154 target = expand_builtin_strcmp (exp, target, mode);
6155 if (target)
6156 return target;
6157 break;
6159 case BUILT_IN_STRNCMP:
6160 target = expand_builtin_strncmp (exp, target, mode);
6161 if (target)
6162 return target;
6163 break;
6165 case BUILT_IN_BCMP:
6166 case BUILT_IN_MEMCMP:
6167 target = expand_builtin_memcmp (exp, arglist, target, mode);
6168 if (target)
6169 return target;
6170 break;
6172 case BUILT_IN_SETJMP:
6173 /* This should have been lowered to the builtins below. */
6174 gcc_unreachable ();
6176 case BUILT_IN_SETJMP_SETUP:
6177 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6178 and the receiver label. */
6179 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6181 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6182 VOIDmode, EXPAND_NORMAL);
6183 tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
6184 rtx label_r = label_rtx (label);
6186 /* This is copied from the handling of non-local gotos. */
6187 expand_builtin_setjmp_setup (buf_addr, label_r);
6188 nonlocal_goto_handler_labels
6189 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6190 nonlocal_goto_handler_labels);
6191 /* ??? Do not let expand_label treat us as such since we would
6192 not want to be both on the list of non-local labels and on
6193 the list of forced labels. */
6194 FORCED_LABEL (label) = 0;
6195 return const0_rtx;
6197 break;
6199 case BUILT_IN_SETJMP_DISPATCHER:
6200 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6201 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6203 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6204 rtx label_r = label_rtx (label);
6206 /* Remove the dispatcher label from the list of non-local labels
6207 since the receiver labels have been added to it above. */
6208 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6209 return const0_rtx;
6211 break;
6213 case BUILT_IN_SETJMP_RECEIVER:
6214 /* __builtin_setjmp_receiver is passed the receiver label. */
6215 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6217 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6218 rtx label_r = label_rtx (label);
6220 expand_builtin_setjmp_receiver (label_r);
6221 return const0_rtx;
6223 break;
6225 /* __builtin_longjmp is passed a pointer to an array of five words.
6226 It's similar to the C library longjmp function but works with
6227 __builtin_setjmp above. */
6228 case BUILT_IN_LONGJMP:
6229 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6231 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6232 VOIDmode, EXPAND_NORMAL);
6233 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6235 if (value != const1_rtx)
6237 error ("%<__builtin_longjmp%> second argument must be 1");
6238 return const0_rtx;
6241 expand_builtin_longjmp (buf_addr, value);
6242 return const0_rtx;
6244 break;
6246 case BUILT_IN_NONLOCAL_GOTO:
6247 target = expand_builtin_nonlocal_goto (arglist);
6248 if (target)
6249 return target;
6250 break;
6252 /* This updates the setjmp buffer that is its argument with the value
6253 of the current stack pointer. */
6254 case BUILT_IN_UPDATE_SETJMP_BUF:
6255 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6257 rtx buf_addr
6258 = expand_normal (TREE_VALUE (arglist));
6260 expand_builtin_update_setjmp_buf (buf_addr);
6261 return const0_rtx;
6263 break;
6265 case BUILT_IN_TRAP:
6266 expand_builtin_trap ();
6267 return const0_rtx;
6269 case BUILT_IN_PRINTF:
6270 target = expand_builtin_printf (exp, target, mode, false);
6271 if (target)
6272 return target;
6273 break;
6275 case BUILT_IN_PRINTF_UNLOCKED:
6276 target = expand_builtin_printf (exp, target, mode, true);
6277 if (target)
6278 return target;
6279 break;
6281 case BUILT_IN_FPUTS:
6282 target = expand_builtin_fputs (arglist, target, false);
6283 if (target)
6284 return target;
6285 break;
6286 case BUILT_IN_FPUTS_UNLOCKED:
6287 target = expand_builtin_fputs (arglist, target, true);
6288 if (target)
6289 return target;
6290 break;
6292 case BUILT_IN_FPRINTF:
6293 target = expand_builtin_fprintf (exp, target, mode, false);
6294 if (target)
6295 return target;
6296 break;
6298 case BUILT_IN_FPRINTF_UNLOCKED:
6299 target = expand_builtin_fprintf (exp, target, mode, true);
6300 if (target)
6301 return target;
6302 break;
6304 case BUILT_IN_SPRINTF:
6305 target = expand_builtin_sprintf (arglist, target, mode);
6306 if (target)
6307 return target;
6308 break;
6310 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6311 target = expand_builtin_signbit (exp, target);
6312 if (target)
6313 return target;
6314 break;
6316 /* Various hooks for the DWARF 2 __throw routine. */
6317 case BUILT_IN_UNWIND_INIT:
6318 expand_builtin_unwind_init ();
6319 return const0_rtx;
6320 case BUILT_IN_DWARF_CFA:
6321 return virtual_cfa_rtx;
6322 #ifdef DWARF2_UNWIND_INFO
6323 case BUILT_IN_DWARF_SP_COLUMN:
6324 return expand_builtin_dwarf_sp_column ();
6325 case BUILT_IN_INIT_DWARF_REG_SIZES:
6326 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6327 return const0_rtx;
6328 #endif
6329 case BUILT_IN_FROB_RETURN_ADDR:
6330 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6331 case BUILT_IN_EXTRACT_RETURN_ADDR:
6332 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6333 case BUILT_IN_EH_RETURN:
6334 expand_builtin_eh_return (TREE_VALUE (arglist),
6335 TREE_VALUE (TREE_CHAIN (arglist)));
6336 return const0_rtx;
6337 #ifdef EH_RETURN_DATA_REGNO
6338 case BUILT_IN_EH_RETURN_DATA_REGNO:
6339 return expand_builtin_eh_return_data_regno (arglist);
6340 #endif
6341 case BUILT_IN_EXTEND_POINTER:
6342 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6344 case BUILT_IN_VA_START:
6345 case BUILT_IN_STDARG_START:
6346 return expand_builtin_va_start (arglist);
6347 case BUILT_IN_VA_END:
6348 return expand_builtin_va_end (arglist);
6349 case BUILT_IN_VA_COPY:
6350 return expand_builtin_va_copy (arglist);
6351 case BUILT_IN_EXPECT:
6352 return expand_builtin_expect (arglist, target);
6353 case BUILT_IN_PREFETCH:
6354 expand_builtin_prefetch (arglist);
6355 return const0_rtx;
6357 case BUILT_IN_PROFILE_FUNC_ENTER:
6358 return expand_builtin_profile_func (false);
6359 case BUILT_IN_PROFILE_FUNC_EXIT:
6360 return expand_builtin_profile_func (true);
6362 case BUILT_IN_INIT_TRAMPOLINE:
6363 return expand_builtin_init_trampoline (arglist);
6364 case BUILT_IN_ADJUST_TRAMPOLINE:
6365 return expand_builtin_adjust_trampoline (arglist);
6367 case BUILT_IN_FORK:
6368 case BUILT_IN_EXECL:
6369 case BUILT_IN_EXECV:
6370 case BUILT_IN_EXECLP:
6371 case BUILT_IN_EXECLE:
6372 case BUILT_IN_EXECVP:
6373 case BUILT_IN_EXECVE:
6374 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6375 if (target)
6376 return target;
6377 break;
6379 case BUILT_IN_FETCH_AND_ADD_1:
6380 case BUILT_IN_FETCH_AND_ADD_2:
6381 case BUILT_IN_FETCH_AND_ADD_4:
6382 case BUILT_IN_FETCH_AND_ADD_8:
6383 case BUILT_IN_FETCH_AND_ADD_16:
6384 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6385 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6386 false, target, ignore);
6387 if (target)
6388 return target;
6389 break;
6391 case BUILT_IN_FETCH_AND_SUB_1:
6392 case BUILT_IN_FETCH_AND_SUB_2:
6393 case BUILT_IN_FETCH_AND_SUB_4:
6394 case BUILT_IN_FETCH_AND_SUB_8:
6395 case BUILT_IN_FETCH_AND_SUB_16:
6396 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6397 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6398 false, target, ignore);
6399 if (target)
6400 return target;
6401 break;
6403 case BUILT_IN_FETCH_AND_OR_1:
6404 case BUILT_IN_FETCH_AND_OR_2:
6405 case BUILT_IN_FETCH_AND_OR_4:
6406 case BUILT_IN_FETCH_AND_OR_8:
6407 case BUILT_IN_FETCH_AND_OR_16:
6408 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6409 target = expand_builtin_sync_operation (mode, arglist, IOR,
6410 false, target, ignore);
6411 if (target)
6412 return target;
6413 break;
6415 case BUILT_IN_FETCH_AND_AND_1:
6416 case BUILT_IN_FETCH_AND_AND_2:
6417 case BUILT_IN_FETCH_AND_AND_4:
6418 case BUILT_IN_FETCH_AND_AND_8:
6419 case BUILT_IN_FETCH_AND_AND_16:
6420 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6421 target = expand_builtin_sync_operation (mode, arglist, AND,
6422 false, target, ignore);
6423 if (target)
6424 return target;
6425 break;
6427 case BUILT_IN_FETCH_AND_XOR_1:
6428 case BUILT_IN_FETCH_AND_XOR_2:
6429 case BUILT_IN_FETCH_AND_XOR_4:
6430 case BUILT_IN_FETCH_AND_XOR_8:
6431 case BUILT_IN_FETCH_AND_XOR_16:
6432 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6433 target = expand_builtin_sync_operation (mode, arglist, XOR,
6434 false, target, ignore);
6435 if (target)
6436 return target;
6437 break;
6439 case BUILT_IN_FETCH_AND_NAND_1:
6440 case BUILT_IN_FETCH_AND_NAND_2:
6441 case BUILT_IN_FETCH_AND_NAND_4:
6442 case BUILT_IN_FETCH_AND_NAND_8:
6443 case BUILT_IN_FETCH_AND_NAND_16:
6444 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6445 target = expand_builtin_sync_operation (mode, arglist, NOT,
6446 false, target, ignore);
6447 if (target)
6448 return target;
6449 break;
6451 case BUILT_IN_ADD_AND_FETCH_1:
6452 case BUILT_IN_ADD_AND_FETCH_2:
6453 case BUILT_IN_ADD_AND_FETCH_4:
6454 case BUILT_IN_ADD_AND_FETCH_8:
6455 case BUILT_IN_ADD_AND_FETCH_16:
6456 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6457 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6458 true, target, ignore);
6459 if (target)
6460 return target;
6461 break;
6463 case BUILT_IN_SUB_AND_FETCH_1:
6464 case BUILT_IN_SUB_AND_FETCH_2:
6465 case BUILT_IN_SUB_AND_FETCH_4:
6466 case BUILT_IN_SUB_AND_FETCH_8:
6467 case BUILT_IN_SUB_AND_FETCH_16:
6468 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6469 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6470 true, target, ignore);
6471 if (target)
6472 return target;
6473 break;
6475 case BUILT_IN_OR_AND_FETCH_1:
6476 case BUILT_IN_OR_AND_FETCH_2:
6477 case BUILT_IN_OR_AND_FETCH_4:
6478 case BUILT_IN_OR_AND_FETCH_8:
6479 case BUILT_IN_OR_AND_FETCH_16:
6480 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6481 target = expand_builtin_sync_operation (mode, arglist, IOR,
6482 true, target, ignore);
6483 if (target)
6484 return target;
6485 break;
6487 case BUILT_IN_AND_AND_FETCH_1:
6488 case BUILT_IN_AND_AND_FETCH_2:
6489 case BUILT_IN_AND_AND_FETCH_4:
6490 case BUILT_IN_AND_AND_FETCH_8:
6491 case BUILT_IN_AND_AND_FETCH_16:
6492 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6493 target = expand_builtin_sync_operation (mode, arglist, AND,
6494 true, target, ignore);
6495 if (target)
6496 return target;
6497 break;
6499 case BUILT_IN_XOR_AND_FETCH_1:
6500 case BUILT_IN_XOR_AND_FETCH_2:
6501 case BUILT_IN_XOR_AND_FETCH_4:
6502 case BUILT_IN_XOR_AND_FETCH_8:
6503 case BUILT_IN_XOR_AND_FETCH_16:
6504 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6505 target = expand_builtin_sync_operation (mode, arglist, XOR,
6506 true, target, ignore);
6507 if (target)
6508 return target;
6509 break;
6511 case BUILT_IN_NAND_AND_FETCH_1:
6512 case BUILT_IN_NAND_AND_FETCH_2:
6513 case BUILT_IN_NAND_AND_FETCH_4:
6514 case BUILT_IN_NAND_AND_FETCH_8:
6515 case BUILT_IN_NAND_AND_FETCH_16:
6516 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6517 target = expand_builtin_sync_operation (mode, arglist, NOT,
6518 true, target, ignore);
6519 if (target)
6520 return target;
6521 break;
6523 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6524 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6525 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6526 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6527 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6528 if (mode == VOIDmode)
6529 mode = TYPE_MODE (boolean_type_node);
6530 if (!target || !register_operand (target, mode))
6531 target = gen_reg_rtx (mode);
6533 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6534 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6535 if (target)
6536 return target;
6537 break;
6539 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6540 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6541 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6542 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6543 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6544 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6545 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6546 if (target)
6547 return target;
6548 break;
6550 case BUILT_IN_LOCK_TEST_AND_SET_1:
6551 case BUILT_IN_LOCK_TEST_AND_SET_2:
6552 case BUILT_IN_LOCK_TEST_AND_SET_4:
6553 case BUILT_IN_LOCK_TEST_AND_SET_8:
6554 case BUILT_IN_LOCK_TEST_AND_SET_16:
6555 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6556 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6557 if (target)
6558 return target;
6559 break;
6561 case BUILT_IN_LOCK_RELEASE_1:
6562 case BUILT_IN_LOCK_RELEASE_2:
6563 case BUILT_IN_LOCK_RELEASE_4:
6564 case BUILT_IN_LOCK_RELEASE_8:
6565 case BUILT_IN_LOCK_RELEASE_16:
6566 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6567 expand_builtin_lock_release (mode, arglist);
6568 return const0_rtx;
6570 case BUILT_IN_SYNCHRONIZE:
6571 expand_builtin_synchronize ();
6572 return const0_rtx;
6574 case BUILT_IN_OBJECT_SIZE:
6575 return expand_builtin_object_size (exp);
6577 case BUILT_IN_MEMCPY_CHK:
6578 case BUILT_IN_MEMPCPY_CHK:
6579 case BUILT_IN_MEMMOVE_CHK:
6580 case BUILT_IN_MEMSET_CHK:
6581 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6582 if (target)
6583 return target;
6584 break;
6586 case BUILT_IN_STRCPY_CHK:
6587 case BUILT_IN_STPCPY_CHK:
6588 case BUILT_IN_STRNCPY_CHK:
6589 case BUILT_IN_STRCAT_CHK:
6590 case BUILT_IN_STRNCAT_CHK:
6591 case BUILT_IN_SNPRINTF_CHK:
6592 case BUILT_IN_VSNPRINTF_CHK:
6593 maybe_emit_chk_warning (exp, fcode);
6594 break;
6596 case BUILT_IN_SPRINTF_CHK:
6597 case BUILT_IN_VSPRINTF_CHK:
6598 maybe_emit_sprintf_chk_warning (exp, fcode);
6599 break;
6601 default: /* just do library call, if unknown builtin */
6602 break;
6605 /* The switch statement above can drop through to cause the function
6606 to be called normally. */
6607 return expand_call (exp, target, ignore);
6610 /* Determine whether a tree node represents a call to a built-in
6611 function. If the tree T is a call to a built-in function with
6612 the right number of arguments of the appropriate types, return
6613 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6614 Otherwise the return value is END_BUILTINS. */
6616 enum built_in_function
6617 builtin_mathfn_code (tree t)
6619 tree fndecl, arglist, parmlist;
6620 tree argtype, parmtype;
6622 if (TREE_CODE (t) != CALL_EXPR
6623 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6624 return END_BUILTINS;
6626 fndecl = get_callee_fndecl (t);
6627 if (fndecl == NULL_TREE
6628 || TREE_CODE (fndecl) != FUNCTION_DECL
6629 || ! DECL_BUILT_IN (fndecl)
6630 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6631 return END_BUILTINS;
6633 arglist = TREE_OPERAND (t, 1);
6634 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6635 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6637 /* If a function doesn't take a variable number of arguments,
6638 the last element in the list will have type `void'. */
6639 parmtype = TREE_VALUE (parmlist);
6640 if (VOID_TYPE_P (parmtype))
6642 if (arglist)
6643 return END_BUILTINS;
6644 return DECL_FUNCTION_CODE (fndecl);
6647 if (! arglist)
6648 return END_BUILTINS;
6650 argtype = TREE_TYPE (TREE_VALUE (arglist));
6652 if (SCALAR_FLOAT_TYPE_P (parmtype))
6654 if (! SCALAR_FLOAT_TYPE_P (argtype))
6655 return END_BUILTINS;
6657 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6659 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6660 return END_BUILTINS;
6662 else if (POINTER_TYPE_P (parmtype))
6664 if (! POINTER_TYPE_P (argtype))
6665 return END_BUILTINS;
6667 else if (INTEGRAL_TYPE_P (parmtype))
6669 if (! INTEGRAL_TYPE_P (argtype))
6670 return END_BUILTINS;
6672 else
6673 return END_BUILTINS;
6675 arglist = TREE_CHAIN (arglist);
6678 /* Variable-length argument list. */
6679 return DECL_FUNCTION_CODE (fndecl);
6682 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6683 constant. ARGLIST is the argument list of the call. */
6685 static tree
6686 fold_builtin_constant_p (tree arglist)
6688 if (arglist == 0)
6689 return 0;
6691 arglist = TREE_VALUE (arglist);
6693 /* We return 1 for a numeric type that's known to be a constant
6694 value at compile-time or for an aggregate type that's a
6695 literal constant. */
6696 STRIP_NOPS (arglist);
6698 /* If we know this is a constant, emit the constant of one. */
6699 if (CONSTANT_CLASS_P (arglist)
6700 || (TREE_CODE (arglist) == CONSTRUCTOR
6701 && TREE_CONSTANT (arglist)))
6702 return integer_one_node;
6703 if (TREE_CODE (arglist) == ADDR_EXPR)
6705 tree op = TREE_OPERAND (arglist, 0);
6706 if (TREE_CODE (op) == STRING_CST
6707 || (TREE_CODE (op) == ARRAY_REF
6708 && integer_zerop (TREE_OPERAND (op, 1))
6709 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6710 return integer_one_node;
6713 /* If this expression has side effects, show we don't know it to be a
6714 constant. Likewise if it's a pointer or aggregate type since in
6715 those case we only want literals, since those are only optimized
6716 when generating RTL, not later.
6717 And finally, if we are compiling an initializer, not code, we
6718 need to return a definite result now; there's not going to be any
6719 more optimization done. */
6720 if (TREE_SIDE_EFFECTS (arglist)
6721 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6722 || POINTER_TYPE_P (TREE_TYPE (arglist))
6723 || cfun == 0
6724 || folding_initializer)
6725 return integer_zero_node;
6727 return 0;
6730 /* Fold a call to __builtin_expect, if we expect that a comparison against
6731 the argument will fold to a constant. In practice, this means a true
6732 constant or the address of a non-weak symbol. ARGLIST is the argument
6733 list of the call. */
6735 static tree
6736 fold_builtin_expect (tree arglist)
6738 tree arg, inner;
6740 if (arglist == 0)
6741 return 0;
6743 arg = TREE_VALUE (arglist);
6745 /* If the argument isn't invariant, then there's nothing we can do. */
6746 if (!TREE_INVARIANT (arg))
6747 return 0;
6749 /* If we're looking at an address of a weak decl, then do not fold. */
6750 inner = arg;
6751 STRIP_NOPS (inner);
6752 if (TREE_CODE (inner) == ADDR_EXPR)
6756 inner = TREE_OPERAND (inner, 0);
6758 while (TREE_CODE (inner) == COMPONENT_REF
6759 || TREE_CODE (inner) == ARRAY_REF);
6760 if (DECL_P (inner) && DECL_WEAK (inner))
6761 return 0;
6764 /* Otherwise, ARG already has the proper type for the return value. */
6765 return arg;
6768 /* Fold a call to __builtin_classify_type. */
6770 static tree
6771 fold_builtin_classify_type (tree arglist)
6773 if (arglist == 0)
6774 return build_int_cst (NULL_TREE, no_type_class);
6776 return build_int_cst (NULL_TREE,
6777 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6780 /* Fold a call to __builtin_strlen. */
6782 static tree
6783 fold_builtin_strlen (tree arglist)
6785 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6786 return NULL_TREE;
6787 else
6789 tree len = c_strlen (TREE_VALUE (arglist), 0);
6791 if (len)
6793 /* Convert from the internal "sizetype" type to "size_t". */
6794 if (size_type_node)
6795 len = fold_convert (size_type_node, len);
6796 return len;
6799 return NULL_TREE;
6803 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6805 static tree
6806 fold_builtin_inf (tree type, int warn)
6808 REAL_VALUE_TYPE real;
6810 /* __builtin_inff is intended to be usable to define INFINITY on all
6811 targets. If an infinity is not available, INFINITY expands "to a
6812 positive constant of type float that overflows at translation
6813 time", footnote "In this case, using INFINITY will violate the
6814 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6815 Thus we pedwarn to ensure this constraint violation is
6816 diagnosed. */
6817 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6818 pedwarn ("target format does not support infinity");
6820 real_inf (&real);
6821 return build_real (type, real);
6824 /* Fold a call to __builtin_nan or __builtin_nans. */
6826 static tree
6827 fold_builtin_nan (tree arglist, tree type, int quiet)
6829 REAL_VALUE_TYPE real;
6830 const char *str;
6832 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6833 return 0;
6834 str = c_getstr (TREE_VALUE (arglist));
6835 if (!str)
6836 return 0;
6838 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6839 return 0;
6841 return build_real (type, real);
6844 /* Return true if the floating point expression T has an integer value.
6845 We also allow +Inf, -Inf and NaN to be considered integer values. */
6847 static bool
6848 integer_valued_real_p (tree t)
6850 switch (TREE_CODE (t))
6852 case FLOAT_EXPR:
6853 return true;
6855 case ABS_EXPR:
6856 case SAVE_EXPR:
6857 case NON_LVALUE_EXPR:
6858 return integer_valued_real_p (TREE_OPERAND (t, 0));
6860 case COMPOUND_EXPR:
6861 case GIMPLE_MODIFY_STMT:
6862 case BIND_EXPR:
6863 return integer_valued_real_p (GENERIC_TREE_OPERAND (t, 1));
6865 case PLUS_EXPR:
6866 case MINUS_EXPR:
6867 case MULT_EXPR:
6868 case MIN_EXPR:
6869 case MAX_EXPR:
6870 return integer_valued_real_p (TREE_OPERAND (t, 0))
6871 && integer_valued_real_p (TREE_OPERAND (t, 1));
6873 case COND_EXPR:
6874 return integer_valued_real_p (TREE_OPERAND (t, 1))
6875 && integer_valued_real_p (TREE_OPERAND (t, 2));
6877 case REAL_CST:
6878 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
6880 case NOP_EXPR:
6882 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6883 if (TREE_CODE (type) == INTEGER_TYPE)
6884 return true;
6885 if (TREE_CODE (type) == REAL_TYPE)
6886 return integer_valued_real_p (TREE_OPERAND (t, 0));
6887 break;
6890 case CALL_EXPR:
6891 switch (builtin_mathfn_code (t))
6893 CASE_FLT_FN (BUILT_IN_CEIL):
6894 CASE_FLT_FN (BUILT_IN_FLOOR):
6895 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6896 CASE_FLT_FN (BUILT_IN_RINT):
6897 CASE_FLT_FN (BUILT_IN_ROUND):
6898 CASE_FLT_FN (BUILT_IN_TRUNC):
6899 return true;
6901 CASE_FLT_FN (BUILT_IN_FMIN):
6902 CASE_FLT_FN (BUILT_IN_FMAX):
6903 return integer_valued_real_p (TREE_VALUE (TREE_OPERAND (t, 1)))
6904 && integer_valued_real_p (TREE_VALUE (TREE_CHAIN (TREE_OPERAND (t, 1))));
6906 default:
6907 break;
6909 break;
6911 default:
6912 break;
6914 return false;
6917 /* EXP is assumed to be builtin call where truncation can be propagated
6918 across (for instance floor((double)f) == (double)floorf (f).
6919 Do the transformation. */
6921 static tree
6922 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6924 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6925 tree arg;
6927 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6928 return 0;
6930 arg = TREE_VALUE (arglist);
6931 /* Integer rounding functions are idempotent. */
6932 if (fcode == builtin_mathfn_code (arg))
6933 return arg;
6935 /* If argument is already integer valued, and we don't need to worry
6936 about setting errno, there's no need to perform rounding. */
6937 if (! flag_errno_math && integer_valued_real_p (arg))
6938 return arg;
6940 if (optimize)
6942 tree arg0 = strip_float_extensions (arg);
6943 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6944 tree newtype = TREE_TYPE (arg0);
6945 tree decl;
6947 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6948 && (decl = mathfn_built_in (newtype, fcode)))
6950 arglist =
6951 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6952 return fold_convert (ftype,
6953 build_function_call_expr (decl, arglist));
6956 return 0;
6959 /* EXP is assumed to be builtin call which can narrow the FP type of
6960 the argument, for instance lround((double)f) -> lroundf (f). */
6962 static tree
6963 fold_fixed_mathfn (tree fndecl, tree arglist)
6965 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6966 tree arg;
6968 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6969 return 0;
6971 arg = TREE_VALUE (arglist);
6973 /* If argument is already integer valued, and we don't need to worry
6974 about setting errno, there's no need to perform rounding. */
6975 if (! flag_errno_math && integer_valued_real_p (arg))
6976 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6978 if (optimize)
6980 tree ftype = TREE_TYPE (arg);
6981 tree arg0 = strip_float_extensions (arg);
6982 tree newtype = TREE_TYPE (arg0);
6983 tree decl;
6985 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6986 && (decl = mathfn_built_in (newtype, fcode)))
6988 arglist =
6989 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6990 return build_function_call_expr (decl, arglist);
6994 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6995 sizeof (long long) == sizeof (long). */
6996 if (TYPE_PRECISION (long_long_integer_type_node)
6997 == TYPE_PRECISION (long_integer_type_node))
6999 tree newfn = NULL_TREE;
7000 switch (fcode)
7002 CASE_FLT_FN (BUILT_IN_LLCEIL):
7003 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7004 break;
7006 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7007 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7008 break;
7010 CASE_FLT_FN (BUILT_IN_LLROUND):
7011 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7012 break;
7014 CASE_FLT_FN (BUILT_IN_LLRINT):
7015 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7016 break;
7018 default:
7019 break;
7022 if (newfn)
7024 tree newcall = build_function_call_expr (newfn, arglist);
7025 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7029 return 0;
7032 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
7033 is the argument list, TYPE is the return type and FNDECL is the
7034 original function DECL. Return NULL_TREE if no if no simplification
7035 can be made. */
7037 static tree
7038 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
7040 tree arg, res;
7042 if (!arglist || TREE_CHAIN (arglist))
7043 return NULL_TREE;
7045 arg = TREE_VALUE (arglist);
7046 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7047 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7048 return NULL_TREE;
7050 /* Calculate the result when the argument is a constant. */
7051 if (TREE_CODE (arg) == COMPLEX_CST
7052 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7053 type, mpfr_hypot)))
7054 return res;
7056 /* If either part is zero, cabs is fabs of the other. */
7057 if (TREE_CODE (arg) == COMPLEX_EXPR
7058 && real_zerop (TREE_OPERAND (arg, 0)))
7059 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
7060 if (TREE_CODE (arg) == COMPLEX_EXPR
7061 && real_zerop (TREE_OPERAND (arg, 1)))
7062 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
7064 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7065 if (TREE_CODE (arg) == NEGATE_EXPR
7066 || TREE_CODE (arg) == CONJ_EXPR)
7068 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
7069 return build_function_call_expr (fndecl, arglist);
7072 /* Don't do this when optimizing for size. */
7073 if (flag_unsafe_math_optimizations
7074 && optimize && !optimize_size)
7076 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7078 if (sqrtfn != NULL_TREE)
7080 tree rpart, ipart, result, arglist;
7082 arg = builtin_save_expr (arg);
7084 rpart = fold_build1 (REALPART_EXPR, type, arg);
7085 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
7087 rpart = builtin_save_expr (rpart);
7088 ipart = builtin_save_expr (ipart);
7090 result = fold_build2 (PLUS_EXPR, type,
7091 fold_build2 (MULT_EXPR, type,
7092 rpart, rpart),
7093 fold_build2 (MULT_EXPR, type,
7094 ipart, ipart));
7096 arglist = build_tree_list (NULL_TREE, result);
7097 return build_function_call_expr (sqrtfn, arglist);
7101 return NULL_TREE;
7104 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
7105 NULL_TREE if no simplification can be made. */
7107 static tree
7108 fold_builtin_sqrt (tree arglist, tree type)
7111 enum built_in_function fcode;
7112 tree arg = TREE_VALUE (arglist);
7114 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7115 return NULL_TREE;
7117 /* Optimize sqrt of constant value. */
7118 if (TREE_CODE (arg) == REAL_CST
7119 && !TREE_OVERFLOW (arg))
7121 REAL_VALUE_TYPE r, x;
7123 x = TREE_REAL_CST (arg);
7124 if (real_sqrt (&r, TYPE_MODE (type), &x)
7125 || (!flag_trapping_math && !flag_errno_math))
7126 return build_real (type, r);
7129 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7130 fcode = builtin_mathfn_code (arg);
7131 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7133 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7134 arg = fold_build2 (MULT_EXPR, type,
7135 TREE_VALUE (TREE_OPERAND (arg, 1)),
7136 build_real (type, dconsthalf));
7137 arglist = build_tree_list (NULL_TREE, arg);
7138 return build_function_call_expr (expfn, arglist);
7141 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7142 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7144 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7146 if (powfn)
7148 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7149 tree tree_root;
7150 /* The inner root was either sqrt or cbrt. */
7151 REAL_VALUE_TYPE dconstroot =
7152 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7154 /* Adjust for the outer root. */
7155 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7156 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7157 tree_root = build_real (type, dconstroot);
7158 arglist = tree_cons (NULL_TREE, arg0,
7159 build_tree_list (NULL_TREE, tree_root));
7160 return build_function_call_expr (powfn, arglist);
7164 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7165 if (flag_unsafe_math_optimizations
7166 && (fcode == BUILT_IN_POW
7167 || fcode == BUILT_IN_POWF
7168 || fcode == BUILT_IN_POWL))
7170 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7171 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7172 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7173 tree narg1;
7174 if (!tree_expr_nonnegative_p (arg0))
7175 arg0 = build1 (ABS_EXPR, type, arg0);
7176 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7177 build_real (type, dconsthalf));
7178 arglist = tree_cons (NULL_TREE, arg0,
7179 build_tree_list (NULL_TREE, narg1));
7180 return build_function_call_expr (powfn, arglist);
7183 return NULL_TREE;
7186 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7187 NULL_TREE if no simplification can be made. */
7188 static tree
7189 fold_builtin_cbrt (tree arglist, tree type)
7191 tree arg = TREE_VALUE (arglist);
7192 const enum built_in_function fcode = builtin_mathfn_code (arg);
7193 tree res;
7195 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7196 return NULL_TREE;
7198 /* Calculate the result when the argument is a constant. */
7199 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7200 return res;
7202 if (flag_unsafe_math_optimizations)
7204 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7205 if (BUILTIN_EXPONENT_P (fcode))
7207 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7208 const REAL_VALUE_TYPE third_trunc =
7209 real_value_truncate (TYPE_MODE (type), dconstthird);
7210 arg = fold_build2 (MULT_EXPR, type,
7211 TREE_VALUE (TREE_OPERAND (arg, 1)),
7212 build_real (type, third_trunc));
7213 arglist = build_tree_list (NULL_TREE, arg);
7214 return build_function_call_expr (expfn, arglist);
7217 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7218 if (BUILTIN_SQRT_P (fcode))
7220 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7222 if (powfn)
7224 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7225 tree tree_root;
7226 REAL_VALUE_TYPE dconstroot = dconstthird;
7228 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7229 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7230 tree_root = build_real (type, dconstroot);
7231 arglist = tree_cons (NULL_TREE, arg0,
7232 build_tree_list (NULL_TREE, tree_root));
7233 return build_function_call_expr (powfn, arglist);
7237 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7238 if (BUILTIN_CBRT_P (fcode))
7240 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7241 if (tree_expr_nonnegative_p (arg0))
7243 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7245 if (powfn)
7247 tree tree_root;
7248 REAL_VALUE_TYPE dconstroot;
7250 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7251 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7252 tree_root = build_real (type, dconstroot);
7253 arglist = tree_cons (NULL_TREE, arg0,
7254 build_tree_list (NULL_TREE, tree_root));
7255 return build_function_call_expr (powfn, arglist);
7260 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7261 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7262 || fcode == BUILT_IN_POWL)
7264 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7265 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7266 if (tree_expr_nonnegative_p (arg00))
7268 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7269 const REAL_VALUE_TYPE dconstroot
7270 = real_value_truncate (TYPE_MODE (type), dconstthird);
7271 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7272 build_real (type, dconstroot));
7273 arglist = tree_cons (NULL_TREE, arg00,
7274 build_tree_list (NULL_TREE, narg01));
7275 return build_function_call_expr (powfn, arglist);
7279 return NULL_TREE;
7282 /* Fold function call to builtin cos, cosf, or cosl. Return
7283 NULL_TREE if no simplification can be made. */
7284 static tree
7285 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7287 tree arg = TREE_VALUE (arglist);
7288 tree res, narg;
7290 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7291 return NULL_TREE;
7293 /* Calculate the result when the argument is a constant. */
7294 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7295 return res;
7297 /* Optimize cos(-x) into cos (x). */
7298 if ((narg = fold_strip_sign_ops (arg)))
7299 return build_function_call_expr (fndecl,
7300 build_tree_list (NULL_TREE, narg));
7302 return NULL_TREE;
7305 /* Fold function call to builtin cosh, coshf, or coshl. Return
7306 NULL_TREE if no simplification can be made. */
7307 static tree
7308 fold_builtin_cosh (tree arglist, tree type, tree fndecl)
7310 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7312 tree arg = TREE_VALUE (arglist);
7313 tree res, narg;
7315 /* Calculate the result when the argument is a constant. */
7316 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7317 return res;
7319 /* Optimize cosh(-x) into cosh (x). */
7320 if ((narg = fold_strip_sign_ops (arg)))
7321 return build_function_call_expr (fndecl,
7322 build_tree_list (NULL_TREE, narg));
7325 return NULL_TREE;
7328 /* Fold function call to builtin tan, tanf, or tanl. Return
7329 NULL_TREE if no simplification can be made. */
7330 static tree
7331 fold_builtin_tan (tree arglist, tree type)
7333 enum built_in_function fcode;
7334 tree arg = TREE_VALUE (arglist);
7335 tree res;
7337 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7338 return NULL_TREE;
7340 /* Calculate the result when the argument is a constant. */
7341 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7342 return res;
7344 /* Optimize tan(atan(x)) = x. */
7345 fcode = builtin_mathfn_code (arg);
7346 if (flag_unsafe_math_optimizations
7347 && (fcode == BUILT_IN_ATAN
7348 || fcode == BUILT_IN_ATANF
7349 || fcode == BUILT_IN_ATANL))
7350 return TREE_VALUE (TREE_OPERAND (arg, 1));
7352 return NULL_TREE;
7355 /* Fold function call to builtin sincos, sincosf, or sincosl. Return
7356 NULL_TREE if no simplification can be made. */
7358 static tree
7359 fold_builtin_sincos (tree arglist)
7361 tree type, arg0, arg1, arg2;
7362 tree res, fn, call;
7364 if (!validate_arglist (arglist, REAL_TYPE, POINTER_TYPE,
7365 POINTER_TYPE, VOID_TYPE))
7366 return NULL_TREE;
7368 arg0 = TREE_VALUE (arglist);
7369 type = TREE_TYPE (arg0);
7370 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7371 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7373 /* Calculate the result when the argument is a constant. */
7374 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7375 return res;
7377 /* Canonicalize sincos to cexpi. */
7378 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7379 if (!fn)
7380 return NULL_TREE;
7382 call = build_function_call_expr (fn, build_tree_list (NULL_TREE, arg0));
7383 call = builtin_save_expr (call);
7385 return build2 (COMPOUND_EXPR, type,
7386 build2 (MODIFY_EXPR, void_type_node,
7387 build_fold_indirect_ref (arg1),
7388 build1 (IMAGPART_EXPR, type, call)),
7389 build2 (MODIFY_EXPR, void_type_node,
7390 build_fold_indirect_ref (arg2),
7391 build1 (REALPART_EXPR, type, call)));
7394 /* Fold function call to builtin cexp, cexpf, or cexpl. Return
7395 NULL_TREE if no simplification can be made. */
7397 static tree
7398 fold_builtin_cexp (tree arglist, tree type)
7400 tree arg0, rtype;
7401 tree realp, imagp, ifn;
7403 if (!validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7404 return NULL_TREE;
7406 arg0 = TREE_VALUE (arglist);
7407 rtype = TREE_TYPE (TREE_TYPE (arg0));
7409 /* In case we can figure out the real part of arg0 and it is constant zero
7410 fold to cexpi. */
7411 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7412 if (!ifn)
7413 return NULL_TREE;
7415 if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
7416 && real_zerop (realp))
7418 tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
7419 return build_function_call_expr (ifn, build_tree_list (NULL_TREE, narg));
7422 /* In case we can easily decompose real and imaginary parts split cexp
7423 to exp (r) * cexpi (i). */
7424 if (flag_unsafe_math_optimizations
7425 && realp)
7427 tree rfn, rcall, icall;
7429 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7430 if (!rfn)
7431 return NULL_TREE;
7433 imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
7434 if (!imagp)
7435 return NULL_TREE;
7437 icall = build_function_call_expr (ifn,
7438 build_tree_list (NULL_TREE, imagp));
7439 icall = builtin_save_expr (icall);
7440 rcall = build_function_call_expr (rfn,
7441 build_tree_list (NULL_TREE, realp));
7442 rcall = builtin_save_expr (rcall);
7443 return build2 (COMPLEX_EXPR, type,
7444 build2 (MULT_EXPR, rtype,
7445 rcall,
7446 build1 (REALPART_EXPR, rtype, icall)),
7447 build2 (MULT_EXPR, rtype,
7448 rcall,
7449 build1 (IMAGPART_EXPR, rtype, icall)));
7452 return NULL_TREE;
7455 /* Fold function call to builtin trunc, truncf or truncl. Return
7456 NULL_TREE if no simplification can be made. */
7458 static tree
7459 fold_builtin_trunc (tree fndecl, tree arglist)
7461 tree arg;
7463 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7464 return 0;
7466 /* Optimize trunc of constant value. */
7467 arg = TREE_VALUE (arglist);
7468 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7470 REAL_VALUE_TYPE r, x;
7471 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7473 x = TREE_REAL_CST (arg);
7474 real_trunc (&r, TYPE_MODE (type), &x);
7475 return build_real (type, r);
7478 return fold_trunc_transparent_mathfn (fndecl, arglist);
7481 /* Fold function call to builtin floor, floorf or floorl. Return
7482 NULL_TREE if no simplification can be made. */
7484 static tree
7485 fold_builtin_floor (tree fndecl, tree arglist)
7487 tree arg;
7489 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7490 return 0;
7492 /* Optimize floor of constant value. */
7493 arg = TREE_VALUE (arglist);
7494 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7496 REAL_VALUE_TYPE x;
7498 x = TREE_REAL_CST (arg);
7499 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7501 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7502 REAL_VALUE_TYPE r;
7504 real_floor (&r, TYPE_MODE (type), &x);
7505 return build_real (type, r);
7509 /* Fold floor (x) where x is nonnegative to trunc (x). */
7510 if (tree_expr_nonnegative_p (arg))
7512 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7513 if (truncfn)
7514 return build_function_call_expr (truncfn, arglist);
7517 return fold_trunc_transparent_mathfn (fndecl, arglist);
7520 /* Fold function call to builtin ceil, ceilf or ceill. Return
7521 NULL_TREE if no simplification can be made. */
7523 static tree
7524 fold_builtin_ceil (tree fndecl, tree arglist)
7526 tree arg;
7528 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7529 return 0;
7531 /* Optimize ceil of constant value. */
7532 arg = TREE_VALUE (arglist);
7533 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7535 REAL_VALUE_TYPE x;
7537 x = TREE_REAL_CST (arg);
7538 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7540 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7541 REAL_VALUE_TYPE r;
7543 real_ceil (&r, TYPE_MODE (type), &x);
7544 return build_real (type, r);
7548 return fold_trunc_transparent_mathfn (fndecl, arglist);
7551 /* Fold function call to builtin round, roundf or roundl. Return
7552 NULL_TREE if no simplification can be made. */
7554 static tree
7555 fold_builtin_round (tree fndecl, tree arglist)
7557 tree arg;
7559 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7560 return 0;
7562 /* Optimize round of constant value. */
7563 arg = TREE_VALUE (arglist);
7564 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7566 REAL_VALUE_TYPE x;
7568 x = TREE_REAL_CST (arg);
7569 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7571 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7572 REAL_VALUE_TYPE r;
7574 real_round (&r, TYPE_MODE (type), &x);
7575 return build_real (type, r);
7579 return fold_trunc_transparent_mathfn (fndecl, arglist);
7582 /* Fold function call to builtin lround, lroundf or lroundl (or the
7583 corresponding long long versions) and other rounding functions.
7584 Return NULL_TREE if no simplification can be made. */
7586 static tree
7587 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7589 tree arg;
7591 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7592 return 0;
7594 /* Optimize lround of constant value. */
7595 arg = TREE_VALUE (arglist);
7596 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7598 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7600 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7602 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7603 tree ftype = TREE_TYPE (arg);
7604 unsigned HOST_WIDE_INT lo2;
7605 HOST_WIDE_INT hi, lo;
7606 REAL_VALUE_TYPE r;
7608 switch (DECL_FUNCTION_CODE (fndecl))
7610 CASE_FLT_FN (BUILT_IN_LFLOOR):
7611 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7612 real_floor (&r, TYPE_MODE (ftype), &x);
7613 break;
7615 CASE_FLT_FN (BUILT_IN_LCEIL):
7616 CASE_FLT_FN (BUILT_IN_LLCEIL):
7617 real_ceil (&r, TYPE_MODE (ftype), &x);
7618 break;
7620 CASE_FLT_FN (BUILT_IN_LROUND):
7621 CASE_FLT_FN (BUILT_IN_LLROUND):
7622 real_round (&r, TYPE_MODE (ftype), &x);
7623 break;
7625 default:
7626 gcc_unreachable ();
7629 REAL_VALUE_TO_INT (&lo, &hi, r);
7630 if (!fit_double_type (lo, hi, &lo2, &hi, itype))
7631 return build_int_cst_wide (itype, lo2, hi);
7635 switch (DECL_FUNCTION_CODE (fndecl))
7637 CASE_FLT_FN (BUILT_IN_LFLOOR):
7638 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7639 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7640 if (tree_expr_nonnegative_p (arg))
7641 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
7642 arg);
7643 break;
7644 default:;
7647 return fold_fixed_mathfn (fndecl, arglist);
7650 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7651 and their long and long long variants (i.e. ffsl and ffsll).
7652 Return NULL_TREE if no simplification can be made. */
7654 static tree
7655 fold_builtin_bitop (tree fndecl, tree arglist)
7657 tree arg;
7659 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7660 return NULL_TREE;
7662 /* Optimize for constant argument. */
7663 arg = TREE_VALUE (arglist);
7664 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
7666 HOST_WIDE_INT hi, width, result;
7667 unsigned HOST_WIDE_INT lo;
7668 tree type;
7670 type = TREE_TYPE (arg);
7671 width = TYPE_PRECISION (type);
7672 lo = TREE_INT_CST_LOW (arg);
7674 /* Clear all the bits that are beyond the type's precision. */
7675 if (width > HOST_BITS_PER_WIDE_INT)
7677 hi = TREE_INT_CST_HIGH (arg);
7678 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7679 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7681 else
7683 hi = 0;
7684 if (width < HOST_BITS_PER_WIDE_INT)
7685 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7688 switch (DECL_FUNCTION_CODE (fndecl))
7690 CASE_INT_FN (BUILT_IN_FFS):
7691 if (lo != 0)
7692 result = exact_log2 (lo & -lo) + 1;
7693 else if (hi != 0)
7694 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7695 else
7696 result = 0;
7697 break;
7699 CASE_INT_FN (BUILT_IN_CLZ):
7700 if (hi != 0)
7701 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7702 else if (lo != 0)
7703 result = width - floor_log2 (lo) - 1;
7704 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7705 result = width;
7706 break;
7708 CASE_INT_FN (BUILT_IN_CTZ):
7709 if (lo != 0)
7710 result = exact_log2 (lo & -lo);
7711 else if (hi != 0)
7712 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7713 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7714 result = width;
7715 break;
7717 CASE_INT_FN (BUILT_IN_POPCOUNT):
7718 result = 0;
7719 while (lo)
7720 result++, lo &= lo - 1;
7721 while (hi)
7722 result++, hi &= hi - 1;
7723 break;
7725 CASE_INT_FN (BUILT_IN_PARITY):
7726 result = 0;
7727 while (lo)
7728 result++, lo &= lo - 1;
7729 while (hi)
7730 result++, hi &= hi - 1;
7731 result &= 1;
7732 break;
7734 default:
7735 gcc_unreachable ();
7738 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7741 return NULL_TREE;
7744 /* Fold function call to builtin_bswap and the long and long long
7745 variants. Return NULL_TREE if no simplification can be made. */
7746 static tree
7747 fold_builtin_bswap (tree fndecl, tree arglist)
7749 tree arg;
7751 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7752 return 0;
7754 /* Optimize constant value. */
7755 arg = TREE_VALUE (arglist);
7756 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
7758 HOST_WIDE_INT hi, width, r_hi = 0;
7759 unsigned HOST_WIDE_INT lo, r_lo = 0;
7760 tree type;
7762 type = TREE_TYPE (arg);
7763 width = TYPE_PRECISION (type);
7764 lo = TREE_INT_CST_LOW (arg);
7765 hi = TREE_INT_CST_HIGH (arg);
7767 switch (DECL_FUNCTION_CODE (fndecl))
7769 case BUILT_IN_BSWAP32:
7770 case BUILT_IN_BSWAP64:
7772 int s;
7774 for (s = 0; s < width; s += 8)
7776 int d = width - s - 8;
7777 unsigned HOST_WIDE_INT byte;
7779 if (s < HOST_BITS_PER_WIDE_INT)
7780 byte = (lo >> s) & 0xff;
7781 else
7782 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
7784 if (d < HOST_BITS_PER_WIDE_INT)
7785 r_lo |= byte << d;
7786 else
7787 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
7791 break;
7793 default:
7794 gcc_unreachable ();
7797 if (width < HOST_BITS_PER_WIDE_INT)
7798 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
7799 else
7800 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
7803 return NULL_TREE;
7805 /* Return true if EXPR is the real constant contained in VALUE. */
7807 static bool
7808 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7810 STRIP_NOPS (expr);
7812 return ((TREE_CODE (expr) == REAL_CST
7813 && !TREE_OVERFLOW (expr)
7814 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7815 || (TREE_CODE (expr) == COMPLEX_CST
7816 && real_dconstp (TREE_REALPART (expr), value)
7817 && real_zerop (TREE_IMAGPART (expr))));
7820 /* A subroutine of fold_builtin to fold the various logarithmic
7821 functions. Return NULL_TREE if no simplification can me made.
7822 FUNC is the corresponding MPFR logarithm function. */
7824 static tree
7825 fold_builtin_logarithm (tree fndecl, tree arglist,
7826 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
7828 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7830 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7831 tree arg = TREE_VALUE (arglist);
7832 tree res;
7833 const enum built_in_function fcode = builtin_mathfn_code (arg);
7835 /* Optimize log(e) = 1.0. We're never passed an exact 'e',
7836 instead we'll look for 'e' truncated to MODE. So only do
7837 this if flag_unsafe_math_optimizations is set. */
7838 if (flag_unsafe_math_optimizations && func == mpfr_log)
7840 const REAL_VALUE_TYPE e_truncated =
7841 real_value_truncate (TYPE_MODE (type), dconste);
7842 if (real_dconstp (arg, &e_truncated))
7843 return build_real (type, dconst1);
7846 /* Calculate the result when the argument is a constant. */
7847 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
7848 return res;
7850 /* Special case, optimize logN(expN(x)) = x. */
7851 if (flag_unsafe_math_optimizations
7852 && ((func == mpfr_log
7853 && (fcode == BUILT_IN_EXP
7854 || fcode == BUILT_IN_EXPF
7855 || fcode == BUILT_IN_EXPL))
7856 || (func == mpfr_log2
7857 && (fcode == BUILT_IN_EXP2
7858 || fcode == BUILT_IN_EXP2F
7859 || fcode == BUILT_IN_EXP2L))
7860 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
7861 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7863 /* Optimize logN(func()) for various exponential functions. We
7864 want to determine the value "x" and the power "exponent" in
7865 order to transform logN(x**exponent) into exponent*logN(x). */
7866 if (flag_unsafe_math_optimizations)
7868 tree exponent = 0, x = 0;
7870 switch (fcode)
7872 CASE_FLT_FN (BUILT_IN_EXP):
7873 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7874 x = build_real (type,
7875 real_value_truncate (TYPE_MODE (type), dconste));
7876 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7877 break;
7878 CASE_FLT_FN (BUILT_IN_EXP2):
7879 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7880 x = build_real (type, dconst2);
7881 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7882 break;
7883 CASE_FLT_FN (BUILT_IN_EXP10):
7884 CASE_FLT_FN (BUILT_IN_POW10):
7885 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7886 x = build_real (type, dconst10);
7887 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7888 break;
7889 CASE_FLT_FN (BUILT_IN_SQRT):
7890 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7891 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7892 exponent = build_real (type, dconsthalf);
7893 break;
7894 CASE_FLT_FN (BUILT_IN_CBRT):
7895 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7896 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7897 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7898 dconstthird));
7899 break;
7900 CASE_FLT_FN (BUILT_IN_POW):
7901 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7902 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7903 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7904 break;
7905 default:
7906 break;
7909 /* Now perform the optimization. */
7910 if (x && exponent)
7912 tree logfn;
7913 arglist = build_tree_list (NULL_TREE, x);
7914 logfn = build_function_call_expr (fndecl, arglist);
7915 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7920 return 0;
7923 /* Fold a builtin function call to hypot, hypotf, or hypotl. Return
7924 NULL_TREE if no simplification can be made. */
7926 static tree
7927 fold_builtin_hypot (tree fndecl, tree arglist, tree type)
7929 tree arg0 = TREE_VALUE (arglist);
7930 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7931 tree res, narg0, narg1;
7933 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7934 return NULL_TREE;
7936 /* Calculate the result when the argument is a constant. */
7937 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
7938 return res;
7940 /* If either argument to hypot has a negate or abs, strip that off.
7941 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
7942 narg0 = fold_strip_sign_ops (arg0);
7943 narg1 = fold_strip_sign_ops (arg1);
7944 if (narg0 || narg1)
7946 tree narglist = tree_cons (NULL_TREE, narg0 ? narg0 : arg0,
7947 build_tree_list (NULL_TREE,
7948 narg1 ? narg1 : arg1));
7949 return build_function_call_expr (fndecl, narglist);
7952 /* If either argument is zero, hypot is fabs of the other. */
7953 if (real_zerop (arg0))
7954 return fold_build1 (ABS_EXPR, type, arg1);
7955 else if (real_zerop (arg1))
7956 return fold_build1 (ABS_EXPR, type, arg0);
7958 /* hypot(x,x) -> fabs(x)*sqrt(2). */
7959 if (flag_unsafe_math_optimizations
7960 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
7962 REAL_VALUE_TYPE sqrt2;
7964 real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2);
7965 return fold_build2 (MULT_EXPR, type,
7966 fold_build1 (ABS_EXPR, type, arg0),
7967 build_real (type, sqrt2));
7970 return NULL_TREE;
7974 /* Fold a builtin function call to pow, powf, or powl. Return
7975 NULL_TREE if no simplification can be made. */
7976 static tree
7977 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7979 tree arg0 = TREE_VALUE (arglist);
7980 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7981 tree res;
7983 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7984 return NULL_TREE;
7986 /* Calculate the result when the argument is a constant. */
7987 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
7988 return res;
7990 /* Optimize pow(1.0,y) = 1.0. */
7991 if (real_onep (arg0))
7992 return omit_one_operand (type, build_real (type, dconst1), arg1);
7994 if (TREE_CODE (arg1) == REAL_CST
7995 && !TREE_OVERFLOW (arg1))
7997 REAL_VALUE_TYPE cint;
7998 REAL_VALUE_TYPE c;
7999 HOST_WIDE_INT n;
8001 c = TREE_REAL_CST (arg1);
8003 /* Optimize pow(x,0.0) = 1.0. */
8004 if (REAL_VALUES_EQUAL (c, dconst0))
8005 return omit_one_operand (type, build_real (type, dconst1),
8006 arg0);
8008 /* Optimize pow(x,1.0) = x. */
8009 if (REAL_VALUES_EQUAL (c, dconst1))
8010 return arg0;
8012 /* Optimize pow(x,-1.0) = 1.0/x. */
8013 if (REAL_VALUES_EQUAL (c, dconstm1))
8014 return fold_build2 (RDIV_EXPR, type,
8015 build_real (type, dconst1), arg0);
8017 /* Optimize pow(x,0.5) = sqrt(x). */
8018 if (flag_unsafe_math_optimizations
8019 && REAL_VALUES_EQUAL (c, dconsthalf))
8021 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8023 if (sqrtfn != NULL_TREE)
8025 tree arglist = build_tree_list (NULL_TREE, arg0);
8026 return build_function_call_expr (sqrtfn, arglist);
8030 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8031 if (flag_unsafe_math_optimizations)
8033 const REAL_VALUE_TYPE dconstroot
8034 = real_value_truncate (TYPE_MODE (type), dconstthird);
8036 if (REAL_VALUES_EQUAL (c, dconstroot))
8038 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8039 if (cbrtfn != NULL_TREE)
8041 tree arglist = build_tree_list (NULL_TREE, arg0);
8042 return build_function_call_expr (cbrtfn, arglist);
8047 /* Check for an integer exponent. */
8048 n = real_to_integer (&c);
8049 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8050 if (real_identical (&c, &cint))
8052 /* Attempt to evaluate pow at compile-time. */
8053 if (TREE_CODE (arg0) == REAL_CST
8054 && !TREE_OVERFLOW (arg0))
8056 REAL_VALUE_TYPE x;
8057 bool inexact;
8059 x = TREE_REAL_CST (arg0);
8060 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8061 if (flag_unsafe_math_optimizations || !inexact)
8062 return build_real (type, x);
8065 /* Strip sign ops from even integer powers. */
8066 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8068 tree narg0 = fold_strip_sign_ops (arg0);
8069 if (narg0)
8071 arglist = build_tree_list (NULL_TREE, arg1);
8072 arglist = tree_cons (NULL_TREE, narg0, arglist);
8073 return build_function_call_expr (fndecl, arglist);
8079 if (flag_unsafe_math_optimizations)
8081 const enum built_in_function fcode = builtin_mathfn_code (arg0);
8083 /* Optimize pow(expN(x),y) = expN(x*y). */
8084 if (BUILTIN_EXPONENT_P (fcode))
8086 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8087 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8088 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
8089 arglist = build_tree_list (NULL_TREE, arg);
8090 return build_function_call_expr (expfn, arglist);
8093 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8094 if (BUILTIN_SQRT_P (fcode))
8096 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8097 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8098 build_real (type, dconsthalf));
8100 arglist = tree_cons (NULL_TREE, narg0,
8101 build_tree_list (NULL_TREE, narg1));
8102 return build_function_call_expr (fndecl, arglist);
8105 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8106 if (BUILTIN_CBRT_P (fcode))
8108 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8109 if (tree_expr_nonnegative_p (arg))
8111 const REAL_VALUE_TYPE dconstroot
8112 = real_value_truncate (TYPE_MODE (type), dconstthird);
8113 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8114 build_real (type, dconstroot));
8115 arglist = tree_cons (NULL_TREE, arg,
8116 build_tree_list (NULL_TREE, narg1));
8117 return build_function_call_expr (fndecl, arglist);
8121 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
8122 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
8123 || fcode == BUILT_IN_POWL)
8125 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8126 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8127 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
8128 arglist = tree_cons (NULL_TREE, arg00,
8129 build_tree_list (NULL_TREE, narg1));
8130 return build_function_call_expr (fndecl, arglist);
8134 return NULL_TREE;
8137 /* Fold a builtin function call to powi, powif, or powil. Return
8138 NULL_TREE if no simplification can be made. */
8139 static tree
8140 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
8142 tree arg0 = TREE_VALUE (arglist);
8143 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8145 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
8146 return NULL_TREE;
8148 /* Optimize pow(1.0,y) = 1.0. */
8149 if (real_onep (arg0))
8150 return omit_one_operand (type, build_real (type, dconst1), arg1);
8152 if (host_integerp (arg1, 0))
8154 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8156 /* Evaluate powi at compile-time. */
8157 if (TREE_CODE (arg0) == REAL_CST
8158 && !TREE_OVERFLOW (arg0))
8160 REAL_VALUE_TYPE x;
8161 x = TREE_REAL_CST (arg0);
8162 real_powi (&x, TYPE_MODE (type), &x, c);
8163 return build_real (type, x);
8166 /* Optimize pow(x,0) = 1.0. */
8167 if (c == 0)
8168 return omit_one_operand (type, build_real (type, dconst1),
8169 arg0);
8171 /* Optimize pow(x,1) = x. */
8172 if (c == 1)
8173 return arg0;
8175 /* Optimize pow(x,-1) = 1.0/x. */
8176 if (c == -1)
8177 return fold_build2 (RDIV_EXPR, type,
8178 build_real (type, dconst1), arg0);
8181 return NULL_TREE;
8184 /* A subroutine of fold_builtin to fold the various exponent
8185 functions. Return NULL_TREE if no simplification can me made.
8186 FUNC is the corresponding MPFR exponent function. */
8188 static tree
8189 fold_builtin_exponent (tree fndecl, tree arglist,
8190 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8192 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8194 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8195 tree arg = TREE_VALUE (arglist);
8196 tree res;
8198 /* Calculate the result when the argument is a constant. */
8199 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8200 return res;
8202 /* Optimize expN(logN(x)) = x. */
8203 if (flag_unsafe_math_optimizations)
8205 const enum built_in_function fcode = builtin_mathfn_code (arg);
8207 if ((func == mpfr_exp
8208 && (fcode == BUILT_IN_LOG
8209 || fcode == BUILT_IN_LOGF
8210 || fcode == BUILT_IN_LOGL))
8211 || (func == mpfr_exp2
8212 && (fcode == BUILT_IN_LOG2
8213 || fcode == BUILT_IN_LOG2F
8214 || fcode == BUILT_IN_LOG2L))
8215 || (func == mpfr_exp10
8216 && (fcode == BUILT_IN_LOG10
8217 || fcode == BUILT_IN_LOG10F
8218 || fcode == BUILT_IN_LOG10L)))
8219 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
8223 return 0;
8226 /* Return true if VAR is a VAR_DECL or a component thereof. */
8228 static bool
8229 var_decl_component_p (tree var)
8231 tree inner = var;
8232 while (handled_component_p (inner))
8233 inner = TREE_OPERAND (inner, 0);
8234 return SSA_VAR_P (inner);
8237 /* Fold function call to builtin memset. Return
8238 NULL_TREE if no simplification can be made. */
8240 static tree
8241 fold_builtin_memset (tree arglist, tree type, bool ignore)
8243 tree dest, c, len, var, ret;
8244 unsigned HOST_WIDE_INT length, cval;
8246 if (!validate_arglist (arglist,
8247 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
8248 return 0;
8250 dest = TREE_VALUE (arglist);
8251 c = TREE_VALUE (TREE_CHAIN (arglist));
8252 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8254 if (! host_integerp (len, 1))
8255 return 0;
8257 /* If the LEN parameter is zero, return DEST. */
8258 if (integer_zerop (len))
8259 return omit_one_operand (type, dest, c);
8261 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8262 return 0;
8264 var = dest;
8265 STRIP_NOPS (var);
8266 if (TREE_CODE (var) != ADDR_EXPR)
8267 return 0;
8269 var = TREE_OPERAND (var, 0);
8270 if (TREE_THIS_VOLATILE (var))
8271 return 0;
8273 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8274 && !POINTER_TYPE_P (TREE_TYPE (var)))
8275 return 0;
8277 if (! var_decl_component_p (var))
8278 return 0;
8280 length = tree_low_cst (len, 1);
8281 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8282 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8283 < (int) length)
8284 return 0;
8286 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8287 return 0;
8289 if (integer_zerop (c))
8290 cval = 0;
8291 else
8293 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8294 return 0;
8296 cval = tree_low_cst (c, 1);
8297 cval &= 0xff;
8298 cval |= cval << 8;
8299 cval |= cval << 16;
8300 cval |= (cval << 31) << 1;
8303 ret = build_int_cst_type (TREE_TYPE (var), cval);
8304 ret = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (var), var, ret);
8305 if (ignore)
8306 return ret;
8308 return omit_one_operand (type, dest, ret);
8311 /* Fold function call to builtin memset. Return
8312 NULL_TREE if no simplification can be made. */
8314 static tree
8315 fold_builtin_bzero (tree arglist, bool ignore)
8317 tree dest, size, newarglist;
8319 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8320 return 0;
8322 if (!ignore)
8323 return 0;
8325 dest = TREE_VALUE (arglist);
8326 size = TREE_VALUE (TREE_CHAIN (arglist));
8328 /* New argument list transforming bzero(ptr x, int y) to
8329 memset(ptr x, int 0, size_t y). This is done this way
8330 so that if it isn't expanded inline, we fallback to
8331 calling bzero instead of memset. */
8333 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8334 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
8335 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8336 return fold_builtin_memset (newarglist, void_type_node, ignore);
8339 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8340 NULL_TREE if no simplification can be made.
8341 If ENDP is 0, return DEST (like memcpy).
8342 If ENDP is 1, return DEST+LEN (like mempcpy).
8343 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8344 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8345 (memmove). */
8347 static tree
8348 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8350 tree dest, src, len, destvar, srcvar, expr;
8352 if (! validate_arglist (arglist,
8353 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8354 return 0;
8356 dest = TREE_VALUE (arglist);
8357 src = TREE_VALUE (TREE_CHAIN (arglist));
8358 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8360 /* If the LEN parameter is zero, return DEST. */
8361 if (integer_zerop (len))
8362 return omit_one_operand (type, dest, src);
8364 /* If SRC and DEST are the same (and not volatile), return
8365 DEST{,+LEN,+LEN-1}. */
8366 if (operand_equal_p (src, dest, 0))
8367 expr = len;
8368 else
8370 tree srctype, desttype;
8371 if (endp == 3)
8373 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8374 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8376 /* Both DEST and SRC must be pointer types.
8377 ??? This is what old code did. Is the testing for pointer types
8378 really mandatory?
8380 If either SRC is readonly or length is 1, we can use memcpy. */
8381 if (dest_align && src_align
8382 && (readonly_data_expr (src)
8383 || (host_integerp (len, 1)
8384 && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
8385 tree_low_cst (len, 1)))))
8387 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8388 if (!fn)
8389 return 0;
8390 return build_function_call_expr (fn, arglist);
8392 return 0;
8395 if (!host_integerp (len, 0))
8396 return 0;
8397 /* FIXME:
8398 This logic lose for arguments like (type *)malloc (sizeof (type)),
8399 since we strip the casts of up to VOID return value from malloc.
8400 Perhaps we ought to inherit type from non-VOID argument here? */
8401 STRIP_NOPS (src);
8402 STRIP_NOPS (dest);
8403 srctype = TREE_TYPE (TREE_TYPE (src));
8404 desttype = TREE_TYPE (TREE_TYPE (dest));
8405 if (!srctype || !desttype
8406 || !TYPE_SIZE_UNIT (srctype)
8407 || !TYPE_SIZE_UNIT (desttype)
8408 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
8409 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
8410 || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
8411 || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8412 return 0;
8414 if (get_pointer_alignment (dest, BIGGEST_ALIGNMENT)
8415 < (int) TYPE_ALIGN (desttype)
8416 || (get_pointer_alignment (src, BIGGEST_ALIGNMENT)
8417 < (int) TYPE_ALIGN (srctype)))
8418 return 0;
8420 if (!ignore)
8421 dest = builtin_save_expr (dest);
8423 srcvar = build_fold_indirect_ref (src);
8424 if (TREE_THIS_VOLATILE (srcvar))
8425 return 0;
8426 if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
8427 return 0;
8428 /* With memcpy, it is possible to bypass aliasing rules, so without
8429 this check i. e. execute/20060930-2.c would be misoptimized, because
8430 it use conflicting alias set to hold argument for the memcpy call.
8431 This check is probably unnecesary with -fno-strict-aliasing.
8432 Similarly for destvar. See also PR29286. */
8433 if (!var_decl_component_p (srcvar)
8434 /* Accept: memcpy (*char_var, "test", 1); that simplify
8435 to char_var='t'; */
8436 || is_gimple_min_invariant (srcvar)
8437 || readonly_data_expr (src))
8438 return 0;
8440 destvar = build_fold_indirect_ref (dest);
8441 if (TREE_THIS_VOLATILE (destvar))
8442 return 0;
8443 if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
8444 return 0;
8445 if (!var_decl_component_p (destvar))
8446 return 0;
8448 if (srctype == desttype
8449 || (gimple_in_ssa_p (cfun)
8450 && tree_ssa_useless_type_conversion_1 (desttype, srctype)))
8451 expr = srcvar;
8452 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8453 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8454 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8455 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8456 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8457 else
8458 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8459 expr = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (destvar), destvar, expr);
8462 if (ignore)
8463 return expr;
8465 if (endp == 0 || endp == 3)
8466 return omit_one_operand (type, dest, expr);
8468 if (expr == len)
8469 expr = 0;
8471 if (endp == 2)
8472 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8473 ssize_int (1));
8475 len = fold_convert (TREE_TYPE (dest), len);
8476 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8477 dest = fold_convert (type, dest);
8478 if (expr)
8479 dest = omit_one_operand (type, dest, expr);
8480 return dest;
8483 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8484 simplification can be made. */
8486 static tree
8487 fold_builtin_bcopy (tree arglist, bool ignore)
8489 tree src, dest, size, newarglist;
8491 if (!validate_arglist (arglist,
8492 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8493 return 0;
8495 if (! ignore)
8496 return 0;
8498 src = TREE_VALUE (arglist);
8499 dest = TREE_VALUE (TREE_CHAIN (arglist));
8500 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8502 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8503 memmove(ptr y, ptr x, size_t z). This is done this way
8504 so that if it isn't expanded inline, we fallback to
8505 calling bcopy instead of memmove. */
8507 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8508 newarglist = tree_cons (NULL_TREE, src, newarglist);
8509 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8511 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8514 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8515 the length of the string to be copied. Return NULL_TREE if no
8516 simplification can be made. */
8518 tree
8519 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8521 tree dest, src, fn;
8523 if (!validate_arglist (arglist,
8524 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8525 return 0;
8527 dest = TREE_VALUE (arglist);
8528 src = TREE_VALUE (TREE_CHAIN (arglist));
8530 /* If SRC and DEST are the same (and not volatile), return DEST. */
8531 if (operand_equal_p (src, dest, 0))
8532 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8534 if (optimize_size)
8535 return 0;
8537 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8538 if (!fn)
8539 return 0;
8541 if (!len)
8543 len = c_strlen (src, 1);
8544 if (! len || TREE_SIDE_EFFECTS (len))
8545 return 0;
8548 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8549 arglist = build_tree_list (NULL_TREE, len);
8550 arglist = tree_cons (NULL_TREE, src, arglist);
8551 arglist = tree_cons (NULL_TREE, dest, arglist);
8552 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8553 build_function_call_expr (fn, arglist));
8556 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8557 the length of the source string. Return NULL_TREE if no simplification
8558 can be made. */
8560 tree
8561 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8563 tree dest, src, len, fn;
8565 if (!validate_arglist (arglist,
8566 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8567 return 0;
8569 dest = TREE_VALUE (arglist);
8570 src = TREE_VALUE (TREE_CHAIN (arglist));
8571 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8573 /* If the LEN parameter is zero, return DEST. */
8574 if (integer_zerop (len))
8575 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8577 /* We can't compare slen with len as constants below if len is not a
8578 constant. */
8579 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8580 return 0;
8582 if (!slen)
8583 slen = c_strlen (src, 1);
8585 /* Now, we must be passed a constant src ptr parameter. */
8586 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8587 return 0;
8589 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8591 /* We do not support simplification of this case, though we do
8592 support it when expanding trees into RTL. */
8593 /* FIXME: generate a call to __builtin_memset. */
8594 if (tree_int_cst_lt (slen, len))
8595 return 0;
8597 /* OK transform into builtin memcpy. */
8598 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8599 if (!fn)
8600 return 0;
8601 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8602 build_function_call_expr (fn, arglist));
8605 /* Fold function call to builtin memcmp. Return
8606 NULL_TREE if no simplification can be made. */
8608 static tree
8609 fold_builtin_memcmp (tree arglist)
8611 tree arg1, arg2, len;
8612 const char *p1, *p2;
8614 if (!validate_arglist (arglist,
8615 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8616 return 0;
8618 arg1 = TREE_VALUE (arglist);
8619 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8620 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8622 /* If the LEN parameter is zero, return zero. */
8623 if (integer_zerop (len))
8624 return omit_two_operands (integer_type_node, integer_zero_node,
8625 arg1, arg2);
8627 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8628 if (operand_equal_p (arg1, arg2, 0))
8629 return omit_one_operand (integer_type_node, integer_zero_node, len);
8631 p1 = c_getstr (arg1);
8632 p2 = c_getstr (arg2);
8634 /* If all arguments are constant, and the value of len is not greater
8635 than the lengths of arg1 and arg2, evaluate at compile-time. */
8636 if (host_integerp (len, 1) && p1 && p2
8637 && compare_tree_int (len, strlen (p1) + 1) <= 0
8638 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8640 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8642 if (r > 0)
8643 return integer_one_node;
8644 else if (r < 0)
8645 return integer_minus_one_node;
8646 else
8647 return integer_zero_node;
8650 /* If len parameter is one, return an expression corresponding to
8651 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8652 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8654 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8655 tree cst_uchar_ptr_node
8656 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8658 tree ind1 = fold_convert (integer_type_node,
8659 build1 (INDIRECT_REF, cst_uchar_node,
8660 fold_convert (cst_uchar_ptr_node,
8661 arg1)));
8662 tree ind2 = fold_convert (integer_type_node,
8663 build1 (INDIRECT_REF, cst_uchar_node,
8664 fold_convert (cst_uchar_ptr_node,
8665 arg2)));
8666 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8669 return 0;
8672 /* Fold function call to builtin strcmp. Return
8673 NULL_TREE if no simplification can be made. */
8675 static tree
8676 fold_builtin_strcmp (tree arglist)
8678 tree arg1, arg2;
8679 const char *p1, *p2;
8681 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8682 return 0;
8684 arg1 = TREE_VALUE (arglist);
8685 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8687 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8688 if (operand_equal_p (arg1, arg2, 0))
8689 return integer_zero_node;
8691 p1 = c_getstr (arg1);
8692 p2 = c_getstr (arg2);
8694 if (p1 && p2)
8696 const int i = strcmp (p1, p2);
8697 if (i < 0)
8698 return integer_minus_one_node;
8699 else if (i > 0)
8700 return integer_one_node;
8701 else
8702 return integer_zero_node;
8705 /* If the second arg is "", return *(const unsigned char*)arg1. */
8706 if (p2 && *p2 == '\0')
8708 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8709 tree cst_uchar_ptr_node
8710 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8712 return fold_convert (integer_type_node,
8713 build1 (INDIRECT_REF, cst_uchar_node,
8714 fold_convert (cst_uchar_ptr_node,
8715 arg1)));
8718 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8719 if (p1 && *p1 == '\0')
8721 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8722 tree cst_uchar_ptr_node
8723 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8725 tree temp = fold_convert (integer_type_node,
8726 build1 (INDIRECT_REF, cst_uchar_node,
8727 fold_convert (cst_uchar_ptr_node,
8728 arg2)));
8729 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8732 return 0;
8735 /* Fold function call to builtin strncmp. Return
8736 NULL_TREE if no simplification can be made. */
8738 static tree
8739 fold_builtin_strncmp (tree arglist)
8741 tree arg1, arg2, len;
8742 const char *p1, *p2;
8744 if (!validate_arglist (arglist,
8745 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8746 return 0;
8748 arg1 = TREE_VALUE (arglist);
8749 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8750 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8752 /* If the LEN parameter is zero, return zero. */
8753 if (integer_zerop (len))
8754 return omit_two_operands (integer_type_node, integer_zero_node,
8755 arg1, arg2);
8757 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8758 if (operand_equal_p (arg1, arg2, 0))
8759 return omit_one_operand (integer_type_node, integer_zero_node, len);
8761 p1 = c_getstr (arg1);
8762 p2 = c_getstr (arg2);
8764 if (host_integerp (len, 1) && p1 && p2)
8766 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8767 if (i > 0)
8768 return integer_one_node;
8769 else if (i < 0)
8770 return integer_minus_one_node;
8771 else
8772 return integer_zero_node;
8775 /* If the second arg is "", and the length is greater than zero,
8776 return *(const unsigned char*)arg1. */
8777 if (p2 && *p2 == '\0'
8778 && TREE_CODE (len) == INTEGER_CST
8779 && tree_int_cst_sgn (len) == 1)
8781 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8782 tree cst_uchar_ptr_node
8783 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8785 return fold_convert (integer_type_node,
8786 build1 (INDIRECT_REF, cst_uchar_node,
8787 fold_convert (cst_uchar_ptr_node,
8788 arg1)));
8791 /* If the first arg is "", and the length is greater than zero,
8792 return -*(const unsigned char*)arg2. */
8793 if (p1 && *p1 == '\0'
8794 && TREE_CODE (len) == INTEGER_CST
8795 && tree_int_cst_sgn (len) == 1)
8797 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8798 tree cst_uchar_ptr_node
8799 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8801 tree temp = fold_convert (integer_type_node,
8802 build1 (INDIRECT_REF, cst_uchar_node,
8803 fold_convert (cst_uchar_ptr_node,
8804 arg2)));
8805 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8808 /* If len parameter is one, return an expression corresponding to
8809 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8810 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8812 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8813 tree cst_uchar_ptr_node
8814 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8816 tree ind1 = fold_convert (integer_type_node,
8817 build1 (INDIRECT_REF, cst_uchar_node,
8818 fold_convert (cst_uchar_ptr_node,
8819 arg1)));
8820 tree ind2 = fold_convert (integer_type_node,
8821 build1 (INDIRECT_REF, cst_uchar_node,
8822 fold_convert (cst_uchar_ptr_node,
8823 arg2)));
8824 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8827 return 0;
8830 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8831 NULL_TREE if no simplification can be made. */
8833 static tree
8834 fold_builtin_signbit (tree fndecl, tree arglist)
8836 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8837 tree arg, temp;
8839 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8840 return NULL_TREE;
8842 arg = TREE_VALUE (arglist);
8844 /* If ARG is a compile-time constant, determine the result. */
8845 if (TREE_CODE (arg) == REAL_CST
8846 && !TREE_OVERFLOW (arg))
8848 REAL_VALUE_TYPE c;
8850 c = TREE_REAL_CST (arg);
8851 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8852 return fold_convert (type, temp);
8855 /* If ARG is non-negative, the result is always zero. */
8856 if (tree_expr_nonnegative_p (arg))
8857 return omit_one_operand (type, integer_zero_node, arg);
8859 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8860 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8861 return fold_build2 (LT_EXPR, type, arg,
8862 build_real (TREE_TYPE (arg), dconst0));
8864 return NULL_TREE;
8867 /* Fold function call to builtin copysign, copysignf or copysignl.
8868 Return NULL_TREE if no simplification can be made. */
8870 static tree
8871 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8873 tree arg1, arg2, tem;
8875 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8876 return NULL_TREE;
8878 arg1 = TREE_VALUE (arglist);
8879 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8881 /* copysign(X,X) is X. */
8882 if (operand_equal_p (arg1, arg2, 0))
8883 return fold_convert (type, arg1);
8885 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8886 if (TREE_CODE (arg1) == REAL_CST
8887 && TREE_CODE (arg2) == REAL_CST
8888 && !TREE_OVERFLOW (arg1)
8889 && !TREE_OVERFLOW (arg2))
8891 REAL_VALUE_TYPE c1, c2;
8893 c1 = TREE_REAL_CST (arg1);
8894 c2 = TREE_REAL_CST (arg2);
8895 /* c1.sign := c2.sign. */
8896 real_copysign (&c1, &c2);
8897 return build_real (type, c1);
8900 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8901 Remember to evaluate Y for side-effects. */
8902 if (tree_expr_nonnegative_p (arg2))
8903 return omit_one_operand (type,
8904 fold_build1 (ABS_EXPR, type, arg1),
8905 arg2);
8907 /* Strip sign changing operations for the first argument. */
8908 tem = fold_strip_sign_ops (arg1);
8909 if (tem)
8911 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8912 return build_function_call_expr (fndecl, arglist);
8915 return NULL_TREE;
8918 /* Fold a call to builtin isascii. */
8920 static tree
8921 fold_builtin_isascii (tree arglist)
8923 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8924 return 0;
8925 else
8927 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8928 tree arg = TREE_VALUE (arglist);
8930 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8931 build_int_cst (NULL_TREE,
8932 ~ (unsigned HOST_WIDE_INT) 0x7f));
8933 return fold_build2 (EQ_EXPR, integer_type_node,
8934 arg, integer_zero_node);
8938 /* Fold a call to builtin toascii. */
8940 static tree
8941 fold_builtin_toascii (tree arglist)
8943 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8944 return 0;
8945 else
8947 /* Transform toascii(c) -> (c & 0x7f). */
8948 tree arg = TREE_VALUE (arglist);
8950 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8951 build_int_cst (NULL_TREE, 0x7f));
8955 /* Fold a call to builtin isdigit. */
8957 static tree
8958 fold_builtin_isdigit (tree arglist)
8960 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8961 return 0;
8962 else
8964 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8965 /* According to the C standard, isdigit is unaffected by locale.
8966 However, it definitely is affected by the target character set. */
8967 tree arg;
8968 unsigned HOST_WIDE_INT target_digit0
8969 = lang_hooks.to_target_charset ('0');
8971 if (target_digit0 == 0)
8972 return NULL_TREE;
8974 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8975 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8976 build_int_cst (unsigned_type_node, target_digit0));
8977 return fold_build2 (LE_EXPR, integer_type_node, arg,
8978 build_int_cst (unsigned_type_node, 9));
8982 /* Fold a call to fabs, fabsf or fabsl. */
8984 static tree
8985 fold_builtin_fabs (tree arglist, tree type)
8987 tree arg;
8989 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8990 return 0;
8992 arg = TREE_VALUE (arglist);
8993 arg = fold_convert (type, arg);
8994 if (TREE_CODE (arg) == REAL_CST)
8995 return fold_abs_const (arg, type);
8996 return fold_build1 (ABS_EXPR, type, arg);
8999 /* Fold a call to abs, labs, llabs or imaxabs. */
9001 static tree
9002 fold_builtin_abs (tree arglist, tree type)
9004 tree arg;
9006 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
9007 return 0;
9009 arg = TREE_VALUE (arglist);
9010 arg = fold_convert (type, arg);
9011 if (TREE_CODE (arg) == INTEGER_CST)
9012 return fold_abs_const (arg, type);
9013 return fold_build1 (ABS_EXPR, type, arg);
9016 /* Fold a call to builtin fmin or fmax. */
9018 static tree
9019 fold_builtin_fmin_fmax (tree arglist, tree type, bool max)
9021 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9023 tree arg0 = TREE_VALUE (arglist);
9024 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
9025 /* Calculate the result when the argument is a constant. */
9026 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9028 if (res)
9029 return res;
9031 /* If either argument is NaN, return the other one. Avoid the
9032 transformation if we get (and honor) a signalling NaN. Using
9033 omit_one_operand() ensures we create a non-lvalue. */
9034 if (TREE_CODE (arg0) == REAL_CST
9035 && real_isnan (&TREE_REAL_CST (arg0))
9036 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9037 || ! TREE_REAL_CST (arg0).signalling))
9038 return omit_one_operand (type, arg1, arg0);
9039 if (TREE_CODE (arg1) == REAL_CST
9040 && real_isnan (&TREE_REAL_CST (arg1))
9041 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9042 || ! TREE_REAL_CST (arg1).signalling))
9043 return omit_one_operand (type, arg0, arg1);
9045 /* Transform fmin/fmax(x,x) -> x. */
9046 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9047 return omit_one_operand (type, arg0, arg1);
9049 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9050 functions to return the numeric arg if the other one is NaN.
9051 These tree codes don't honor that, so only transform if
9052 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9053 handled, so we don't have to worry about it either. */
9054 if (flag_finite_math_only)
9055 return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
9056 fold_convert (type, arg0),
9057 fold_convert (type, arg1));
9059 return NULL_TREE;
9062 /* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
9064 static tree
9065 fold_builtin_carg(tree arglist, tree type)
9067 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9069 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9071 if (atan2_fn)
9073 tree arg = builtin_save_expr (TREE_VALUE (arglist));
9074 tree r_arg = fold_build1 (REALPART_EXPR, type, arg);
9075 tree i_arg = fold_build1 (IMAGPART_EXPR, type, arg);
9076 tree newarglist = tree_cons (NULL_TREE, i_arg,
9077 build_tree_list (NULL_TREE, r_arg));
9078 return build_function_call_expr (atan2_fn, newarglist);
9082 return NULL_TREE;
9085 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9086 EXP is the CALL_EXPR for the call. */
9088 static tree
9089 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
9091 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9092 tree arg;
9093 REAL_VALUE_TYPE r;
9095 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9097 /* Check that we have exactly one argument. */
9098 if (arglist == 0)
9100 error ("too few arguments to function %qs",
9101 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9102 return error_mark_node;
9104 else if (TREE_CHAIN (arglist) != 0)
9106 error ("too many arguments to function %qs",
9107 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9108 return error_mark_node;
9110 else
9112 error ("non-floating-point argument to function %qs",
9113 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9114 return error_mark_node;
9118 arg = TREE_VALUE (arglist);
9119 switch (builtin_index)
9121 case BUILT_IN_ISINF:
9122 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9123 return omit_one_operand (type, integer_zero_node, arg);
9125 if (TREE_CODE (arg) == REAL_CST)
9127 r = TREE_REAL_CST (arg);
9128 if (real_isinf (&r))
9129 return real_compare (GT_EXPR, &r, &dconst0)
9130 ? integer_one_node : integer_minus_one_node;
9131 else
9132 return integer_zero_node;
9135 return NULL_TREE;
9137 case BUILT_IN_FINITE:
9138 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9139 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9140 return omit_one_operand (type, integer_one_node, arg);
9142 if (TREE_CODE (arg) == REAL_CST)
9144 r = TREE_REAL_CST (arg);
9145 return real_isinf (&r) || real_isnan (&r)
9146 ? integer_zero_node : integer_one_node;
9149 return NULL_TREE;
9151 case BUILT_IN_ISNAN:
9152 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
9153 return omit_one_operand (type, integer_zero_node, arg);
9155 if (TREE_CODE (arg) == REAL_CST)
9157 r = TREE_REAL_CST (arg);
9158 return real_isnan (&r) ? integer_one_node : integer_zero_node;
9161 arg = builtin_save_expr (arg);
9162 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
9164 default:
9165 gcc_unreachable ();
9169 /* Fold a call to an unordered comparison function such as
9170 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
9171 being called and ARGLIST is the argument list for the call.
9172 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9173 the opposite of the desired result. UNORDERED_CODE is used
9174 for modes that can hold NaNs and ORDERED_CODE is used for
9175 the rest. */
9177 static tree
9178 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
9179 enum tree_code unordered_code,
9180 enum tree_code ordered_code)
9182 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9183 enum tree_code code;
9184 tree arg0, arg1;
9185 tree type0, type1;
9186 enum tree_code code0, code1;
9187 tree cmp_type = NULL_TREE;
9189 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9191 /* Check that we have exactly two arguments. */
9192 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
9194 error ("too few arguments to function %qs",
9195 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9196 return error_mark_node;
9198 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
9200 error ("too many arguments to function %qs",
9201 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9202 return error_mark_node;
9206 arg0 = TREE_VALUE (arglist);
9207 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
9209 type0 = TREE_TYPE (arg0);
9210 type1 = TREE_TYPE (arg1);
9212 code0 = TREE_CODE (type0);
9213 code1 = TREE_CODE (type1);
9215 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
9216 /* Choose the wider of two real types. */
9217 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
9218 ? type0 : type1;
9219 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
9220 cmp_type = type0;
9221 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
9222 cmp_type = type1;
9223 else
9225 error ("non-floating-point argument to function %qs",
9226 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9227 return error_mark_node;
9230 arg0 = fold_convert (cmp_type, arg0);
9231 arg1 = fold_convert (cmp_type, arg1);
9233 if (unordered_code == UNORDERED_EXPR)
9235 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
9236 return omit_two_operands (type, integer_zero_node, arg0, arg1);
9237 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
9240 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9241 : ordered_code;
9242 return fold_build1 (TRUTH_NOT_EXPR, type,
9243 fold_build2 (code, type, arg0, arg1));
9246 /* Used by constant folding to simplify calls to builtin functions. EXP is
9247 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
9248 result of the function call is ignored. This function returns NULL_TREE
9249 if no simplification was possible. */
9251 static tree
9252 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
9254 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9255 enum built_in_function fcode;
9257 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
9258 return targetm.fold_builtin (fndecl, arglist, ignore);
9260 fcode = DECL_FUNCTION_CODE (fndecl);
9261 switch (fcode)
9263 case BUILT_IN_FPUTS:
9264 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
9266 case BUILT_IN_FPUTS_UNLOCKED:
9267 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
9269 case BUILT_IN_STRSTR:
9270 return fold_builtin_strstr (arglist, type);
9272 case BUILT_IN_STRCAT:
9273 return fold_builtin_strcat (arglist);
9275 case BUILT_IN_STRNCAT:
9276 return fold_builtin_strncat (arglist);
9278 case BUILT_IN_STRSPN:
9279 return fold_builtin_strspn (arglist);
9281 case BUILT_IN_STRCSPN:
9282 return fold_builtin_strcspn (arglist);
9284 case BUILT_IN_STRCHR:
9285 case BUILT_IN_INDEX:
9286 return fold_builtin_strchr (arglist, type);
9288 case BUILT_IN_STRRCHR:
9289 case BUILT_IN_RINDEX:
9290 return fold_builtin_strrchr (arglist, type);
9292 case BUILT_IN_STRCPY:
9293 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
9295 case BUILT_IN_STRNCPY:
9296 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
9298 case BUILT_IN_STRCMP:
9299 return fold_builtin_strcmp (arglist);
9301 case BUILT_IN_STRNCMP:
9302 return fold_builtin_strncmp (arglist);
9304 case BUILT_IN_STRPBRK:
9305 return fold_builtin_strpbrk (arglist, type);
9307 case BUILT_IN_BCMP:
9308 case BUILT_IN_MEMCMP:
9309 return fold_builtin_memcmp (arglist);
9311 case BUILT_IN_SPRINTF:
9312 return fold_builtin_sprintf (arglist, ignore);
9314 case BUILT_IN_CONSTANT_P:
9316 tree val;
9318 val = fold_builtin_constant_p (arglist);
9319 /* Gimplification will pull the CALL_EXPR for the builtin out of
9320 an if condition. When not optimizing, we'll not CSE it back.
9321 To avoid link error types of regressions, return false now. */
9322 if (!val && !optimize)
9323 val = integer_zero_node;
9325 return val;
9328 case BUILT_IN_EXPECT:
9329 return fold_builtin_expect (arglist);
9331 case BUILT_IN_CLASSIFY_TYPE:
9332 return fold_builtin_classify_type (arglist);
9334 case BUILT_IN_STRLEN:
9335 return fold_builtin_strlen (arglist);
9337 CASE_FLT_FN (BUILT_IN_FABS):
9338 return fold_builtin_fabs (arglist, type);
9340 case BUILT_IN_ABS:
9341 case BUILT_IN_LABS:
9342 case BUILT_IN_LLABS:
9343 case BUILT_IN_IMAXABS:
9344 return fold_builtin_abs (arglist, type);
9346 CASE_FLT_FN (BUILT_IN_CONJ):
9347 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9348 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
9349 break;
9351 CASE_FLT_FN (BUILT_IN_CREAL):
9352 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9353 return non_lvalue (fold_build1 (REALPART_EXPR, type,
9354 TREE_VALUE (arglist)));
9355 break;
9357 CASE_FLT_FN (BUILT_IN_CIMAG):
9358 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9359 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
9360 TREE_VALUE (arglist)));
9361 break;
9363 CASE_FLT_FN (BUILT_IN_CCOS):
9364 CASE_FLT_FN (BUILT_IN_CCOSH):
9365 /* These functions are "even", i.e. f(x) == f(-x). */
9366 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9368 tree narg = fold_strip_sign_ops (TREE_VALUE (arglist));
9369 if (narg)
9370 return build_function_call_expr (fndecl,
9371 build_tree_list (NULL_TREE, narg));
9373 break;
9375 CASE_FLT_FN (BUILT_IN_CABS):
9376 return fold_builtin_cabs (arglist, type, fndecl);
9378 CASE_FLT_FN (BUILT_IN_CARG):
9379 return fold_builtin_carg (arglist, type);
9381 CASE_FLT_FN (BUILT_IN_SQRT):
9382 return fold_builtin_sqrt (arglist, type);
9384 CASE_FLT_FN (BUILT_IN_CBRT):
9385 return fold_builtin_cbrt (arglist, type);
9387 CASE_FLT_FN (BUILT_IN_ASIN):
9388 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9389 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asin,
9390 &dconstm1, &dconst1, true);
9391 break;
9393 CASE_FLT_FN (BUILT_IN_ACOS):
9394 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9395 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acos,
9396 &dconstm1, &dconst1, true);
9397 break;
9399 CASE_FLT_FN (BUILT_IN_ATAN):
9400 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9401 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atan,
9402 NULL, NULL, 0);
9403 break;
9405 CASE_FLT_FN (BUILT_IN_ASINH):
9406 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9407 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asinh,
9408 NULL, NULL, 0);
9409 break;
9411 CASE_FLT_FN (BUILT_IN_ACOSH):
9412 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9413 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acosh,
9414 &dconst1, NULL, true);
9415 break;
9417 CASE_FLT_FN (BUILT_IN_ATANH):
9418 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9419 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atanh,
9420 &dconstm1, &dconst1, false);
9421 break;
9423 CASE_FLT_FN (BUILT_IN_SIN):
9424 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9425 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sin,
9426 NULL, NULL, 0);
9427 break;
9429 CASE_FLT_FN (BUILT_IN_COS):
9430 return fold_builtin_cos (arglist, type, fndecl);
9432 CASE_FLT_FN (BUILT_IN_TAN):
9433 return fold_builtin_tan (arglist, type);
9435 CASE_FLT_FN (BUILT_IN_SINCOS):
9436 return fold_builtin_sincos (arglist);
9438 CASE_FLT_FN (BUILT_IN_CEXP):
9439 return fold_builtin_cexp (arglist, type);
9441 CASE_FLT_FN (BUILT_IN_CEXPI):
9442 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9443 return do_mpfr_sincos (TREE_VALUE (arglist), NULL_TREE, NULL_TREE);
9445 CASE_FLT_FN (BUILT_IN_SINH):
9446 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9447 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sinh,
9448 NULL, NULL, 0);
9449 break;
9451 CASE_FLT_FN (BUILT_IN_COSH):
9452 return fold_builtin_cosh (arglist, type, fndecl);
9454 CASE_FLT_FN (BUILT_IN_TANH):
9455 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9456 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_tanh,
9457 NULL, NULL, 0);
9458 break;
9460 CASE_FLT_FN (BUILT_IN_ERF):
9461 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9462 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erf,
9463 NULL, NULL, 0);
9464 break;
9466 CASE_FLT_FN (BUILT_IN_ERFC):
9467 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9468 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erfc,
9469 NULL, NULL, 0);
9470 break;
9472 CASE_FLT_FN (BUILT_IN_TGAMMA):
9473 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9474 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_gamma,
9475 NULL, NULL, 0);
9476 break;
9478 CASE_FLT_FN (BUILT_IN_EXP):
9479 return fold_builtin_exponent (fndecl, arglist, mpfr_exp);
9481 CASE_FLT_FN (BUILT_IN_EXP2):
9482 return fold_builtin_exponent (fndecl, arglist, mpfr_exp2);
9484 CASE_FLT_FN (BUILT_IN_EXP10):
9485 CASE_FLT_FN (BUILT_IN_POW10):
9486 return fold_builtin_exponent (fndecl, arglist, mpfr_exp10);
9488 CASE_FLT_FN (BUILT_IN_EXPM1):
9489 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9490 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_expm1,
9491 NULL, NULL, 0);
9492 break;
9494 CASE_FLT_FN (BUILT_IN_LOG):
9495 return fold_builtin_logarithm (fndecl, arglist, mpfr_log);
9497 CASE_FLT_FN (BUILT_IN_LOG2):
9498 return fold_builtin_logarithm (fndecl, arglist, mpfr_log2);
9500 CASE_FLT_FN (BUILT_IN_LOG10):
9501 return fold_builtin_logarithm (fndecl, arglist, mpfr_log10);
9503 CASE_FLT_FN (BUILT_IN_LOG1P):
9504 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9505 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_log1p,
9506 &dconstm1, NULL, false);
9507 break;
9509 CASE_FLT_FN (BUILT_IN_ATAN2):
9510 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9511 return do_mpfr_arg2 (TREE_VALUE (arglist),
9512 TREE_VALUE (TREE_CHAIN (arglist)),
9513 type, mpfr_atan2);
9514 break;
9516 CASE_FLT_FN (BUILT_IN_FDIM):
9517 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9518 return do_mpfr_arg2 (TREE_VALUE (arglist),
9519 TREE_VALUE (TREE_CHAIN (arglist)),
9520 type, mpfr_dim);
9521 break;
9523 CASE_FLT_FN (BUILT_IN_FMA):
9524 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9525 return do_mpfr_arg3 (TREE_VALUE (arglist),
9526 TREE_VALUE (TREE_CHAIN (arglist)),
9527 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
9528 type, mpfr_fma);
9529 break;
9531 CASE_FLT_FN (BUILT_IN_FMIN):
9532 return fold_builtin_fmin_fmax (arglist, type, /*max=*/false);
9534 CASE_FLT_FN (BUILT_IN_FMAX):
9535 return fold_builtin_fmin_fmax (arglist, type, /*max=*/true);
9537 CASE_FLT_FN (BUILT_IN_HYPOT):
9538 return fold_builtin_hypot (fndecl, arglist, type);
9540 CASE_FLT_FN (BUILT_IN_POW):
9541 return fold_builtin_pow (fndecl, arglist, type);
9543 CASE_FLT_FN (BUILT_IN_POWI):
9544 return fold_builtin_powi (fndecl, arglist, type);
9546 CASE_FLT_FN (BUILT_IN_INF):
9547 case BUILT_IN_INFD32:
9548 case BUILT_IN_INFD64:
9549 case BUILT_IN_INFD128:
9550 return fold_builtin_inf (type, true);
9552 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9553 return fold_builtin_inf (type, false);
9555 CASE_FLT_FN (BUILT_IN_NAN):
9556 case BUILT_IN_NAND32:
9557 case BUILT_IN_NAND64:
9558 case BUILT_IN_NAND128:
9559 return fold_builtin_nan (arglist, type, true);
9561 CASE_FLT_FN (BUILT_IN_NANS):
9562 return fold_builtin_nan (arglist, type, false);
9564 CASE_FLT_FN (BUILT_IN_FLOOR):
9565 return fold_builtin_floor (fndecl, arglist);
9567 CASE_FLT_FN (BUILT_IN_CEIL):
9568 return fold_builtin_ceil (fndecl, arglist);
9570 CASE_FLT_FN (BUILT_IN_TRUNC):
9571 return fold_builtin_trunc (fndecl, arglist);
9573 CASE_FLT_FN (BUILT_IN_ROUND):
9574 return fold_builtin_round (fndecl, arglist);
9576 CASE_FLT_FN (BUILT_IN_NEARBYINT):
9577 CASE_FLT_FN (BUILT_IN_RINT):
9578 return fold_trunc_transparent_mathfn (fndecl, arglist);
9580 CASE_FLT_FN (BUILT_IN_LCEIL):
9581 CASE_FLT_FN (BUILT_IN_LLCEIL):
9582 CASE_FLT_FN (BUILT_IN_LFLOOR):
9583 CASE_FLT_FN (BUILT_IN_LLFLOOR):
9584 CASE_FLT_FN (BUILT_IN_LROUND):
9585 CASE_FLT_FN (BUILT_IN_LLROUND):
9586 return fold_builtin_int_roundingfn (fndecl, arglist);
9588 CASE_FLT_FN (BUILT_IN_LRINT):
9589 CASE_FLT_FN (BUILT_IN_LLRINT):
9590 return fold_fixed_mathfn (fndecl, arglist);
9592 case BUILT_IN_BSWAP32:
9593 case BUILT_IN_BSWAP64:
9594 return fold_builtin_bswap (fndecl, arglist);
9596 CASE_INT_FN (BUILT_IN_FFS):
9597 CASE_INT_FN (BUILT_IN_CLZ):
9598 CASE_INT_FN (BUILT_IN_CTZ):
9599 CASE_INT_FN (BUILT_IN_POPCOUNT):
9600 CASE_INT_FN (BUILT_IN_PARITY):
9601 return fold_builtin_bitop (fndecl, arglist);
9603 case BUILT_IN_MEMSET:
9604 return fold_builtin_memset (arglist, type, ignore);
9606 case BUILT_IN_MEMCPY:
9607 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9609 case BUILT_IN_MEMPCPY:
9610 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9612 case BUILT_IN_MEMMOVE:
9613 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9615 case BUILT_IN_BZERO:
9616 return fold_builtin_bzero (arglist, ignore);
9618 case BUILT_IN_BCOPY:
9619 return fold_builtin_bcopy (arglist, ignore);
9621 CASE_FLT_FN (BUILT_IN_SIGNBIT):
9622 return fold_builtin_signbit (fndecl, arglist);
9624 case BUILT_IN_ISASCII:
9625 return fold_builtin_isascii (arglist);
9627 case BUILT_IN_TOASCII:
9628 return fold_builtin_toascii (arglist);
9630 case BUILT_IN_ISDIGIT:
9631 return fold_builtin_isdigit (arglist);
9633 CASE_FLT_FN (BUILT_IN_COPYSIGN):
9634 return fold_builtin_copysign (fndecl, arglist, type);
9636 CASE_FLT_FN (BUILT_IN_FINITE):
9637 case BUILT_IN_FINITED32:
9638 case BUILT_IN_FINITED64:
9639 case BUILT_IN_FINITED128:
9640 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9642 CASE_FLT_FN (BUILT_IN_ISINF):
9643 case BUILT_IN_ISINFD32:
9644 case BUILT_IN_ISINFD64:
9645 case BUILT_IN_ISINFD128:
9646 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9648 CASE_FLT_FN (BUILT_IN_ISNAN):
9649 case BUILT_IN_ISNAND32:
9650 case BUILT_IN_ISNAND64:
9651 case BUILT_IN_ISNAND128:
9652 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9654 case BUILT_IN_ISGREATER:
9655 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9656 case BUILT_IN_ISGREATEREQUAL:
9657 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9658 case BUILT_IN_ISLESS:
9659 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9660 case BUILT_IN_ISLESSEQUAL:
9661 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9662 case BUILT_IN_ISLESSGREATER:
9663 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9664 case BUILT_IN_ISUNORDERED:
9665 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9666 NOP_EXPR);
9668 /* We do the folding for va_start in the expander. */
9669 case BUILT_IN_VA_START:
9670 break;
9672 case BUILT_IN_OBJECT_SIZE:
9673 return fold_builtin_object_size (arglist);
9674 case BUILT_IN_MEMCPY_CHK:
9675 case BUILT_IN_MEMPCPY_CHK:
9676 case BUILT_IN_MEMMOVE_CHK:
9677 case BUILT_IN_MEMSET_CHK:
9678 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9679 DECL_FUNCTION_CODE (fndecl));
9680 case BUILT_IN_STRCPY_CHK:
9681 case BUILT_IN_STPCPY_CHK:
9682 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9683 DECL_FUNCTION_CODE (fndecl));
9684 case BUILT_IN_STRNCPY_CHK:
9685 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9686 case BUILT_IN_STRCAT_CHK:
9687 return fold_builtin_strcat_chk (fndecl, arglist);
9688 case BUILT_IN_STRNCAT_CHK:
9689 return fold_builtin_strncat_chk (fndecl, arglist);
9690 case BUILT_IN_SPRINTF_CHK:
9691 case BUILT_IN_VSPRINTF_CHK:
9692 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9693 case BUILT_IN_SNPRINTF_CHK:
9694 case BUILT_IN_VSNPRINTF_CHK:
9695 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9696 DECL_FUNCTION_CODE (fndecl));
9698 case BUILT_IN_PRINTF:
9699 case BUILT_IN_PRINTF_UNLOCKED:
9700 case BUILT_IN_VPRINTF:
9701 case BUILT_IN_PRINTF_CHK:
9702 case BUILT_IN_VPRINTF_CHK:
9703 return fold_builtin_printf (fndecl, arglist, ignore,
9704 DECL_FUNCTION_CODE (fndecl));
9706 case BUILT_IN_FPRINTF:
9707 case BUILT_IN_FPRINTF_UNLOCKED:
9708 case BUILT_IN_VFPRINTF:
9709 case BUILT_IN_FPRINTF_CHK:
9710 case BUILT_IN_VFPRINTF_CHK:
9711 return fold_builtin_fprintf (fndecl, arglist, ignore,
9712 DECL_FUNCTION_CODE (fndecl));
9714 default:
9715 break;
9718 return 0;
9721 /* A wrapper function for builtin folding that prevents warnings for
9722 "statement without effect" and the like, caused by removing the
9723 call node earlier than the warning is generated. */
9725 tree
9726 fold_builtin (tree fndecl, tree arglist, bool ignore)
9728 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9729 if (exp && !ignore)
9731 exp = build1 (NOP_EXPR, GENERIC_TREE_TYPE (exp), exp);
9732 TREE_NO_WARNING (exp) = 1;
9735 return exp;
9738 /* Conveniently construct a function call expression. */
9740 tree
9741 build_function_call_expr (tree fn, tree arglist)
9743 tree call_expr;
9745 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9746 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9747 call_expr, arglist, NULL_TREE);
9750 /* This function validates the types of a function call argument list
9751 represented as a tree chain of parameters against a specified list
9752 of tree_codes. If the last specifier is a 0, that represents an
9753 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9756 validate_arglist (tree arglist, ...)
9758 enum tree_code code;
9759 int res = 0;
9760 va_list ap;
9762 va_start (ap, arglist);
9766 code = va_arg (ap, enum tree_code);
9767 switch (code)
9769 case 0:
9770 /* This signifies an ellipses, any further arguments are all ok. */
9771 res = 1;
9772 goto end;
9773 case VOID_TYPE:
9774 /* This signifies an endlink, if no arguments remain, return
9775 true, otherwise return false. */
9776 res = arglist == 0;
9777 goto end;
9778 default:
9779 /* If no parameters remain or the parameter's code does not
9780 match the specified code, return false. Otherwise continue
9781 checking any remaining arguments. */
9782 if (arglist == 0)
9783 goto end;
9784 if (code == POINTER_TYPE)
9786 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9787 goto end;
9789 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9790 goto end;
9791 break;
9793 arglist = TREE_CHAIN (arglist);
9795 while (1);
9797 /* We need gotos here since we can only have one VA_CLOSE in a
9798 function. */
9799 end: ;
9800 va_end (ap);
9802 return res;
9805 /* Default target-specific builtin expander that does nothing. */
9808 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9809 rtx target ATTRIBUTE_UNUSED,
9810 rtx subtarget ATTRIBUTE_UNUSED,
9811 enum machine_mode mode ATTRIBUTE_UNUSED,
9812 int ignore ATTRIBUTE_UNUSED)
9814 return NULL_RTX;
9817 /* Returns true is EXP represents data that would potentially reside
9818 in a readonly section. */
9820 static bool
9821 readonly_data_expr (tree exp)
9823 STRIP_NOPS (exp);
9825 if (TREE_CODE (exp) != ADDR_EXPR)
9826 return false;
9828 exp = get_base_address (TREE_OPERAND (exp, 0));
9829 if (!exp)
9830 return false;
9832 /* Make sure we call decl_readonly_section only for trees it
9833 can handle (since it returns true for everything it doesn't
9834 understand). */
9835 if (TREE_CODE (exp) == STRING_CST
9836 || TREE_CODE (exp) == CONSTRUCTOR
9837 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9838 return decl_readonly_section (exp, 0);
9839 else
9840 return false;
9843 /* Simplify a call to the strstr builtin.
9845 Return 0 if no simplification was possible, otherwise return the
9846 simplified form of the call as a tree.
9848 The simplified form may be a constant or other expression which
9849 computes the same value, but in a more efficient manner (including
9850 calls to other builtin functions).
9852 The call may contain arguments which need to be evaluated, but
9853 which are not useful to determine the result of the call. In
9854 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9855 COMPOUND_EXPR will be an argument which must be evaluated.
9856 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9857 COMPOUND_EXPR in the chain will contain the tree for the simplified
9858 form of the builtin function call. */
9860 static tree
9861 fold_builtin_strstr (tree arglist, tree type)
9863 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9864 return 0;
9865 else
9867 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9868 tree fn;
9869 const char *p1, *p2;
9871 p2 = c_getstr (s2);
9872 if (p2 == NULL)
9873 return 0;
9875 p1 = c_getstr (s1);
9876 if (p1 != NULL)
9878 const char *r = strstr (p1, p2);
9879 tree tem;
9881 if (r == NULL)
9882 return build_int_cst (TREE_TYPE (s1), 0);
9884 /* Return an offset into the constant string argument. */
9885 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9886 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9887 return fold_convert (type, tem);
9890 /* The argument is const char *, and the result is char *, so we need
9891 a type conversion here to avoid a warning. */
9892 if (p2[0] == '\0')
9893 return fold_convert (type, s1);
9895 if (p2[1] != '\0')
9896 return 0;
9898 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9899 if (!fn)
9900 return 0;
9902 /* New argument list transforming strstr(s1, s2) to
9903 strchr(s1, s2[0]). */
9904 arglist = build_tree_list (NULL_TREE,
9905 build_int_cst (NULL_TREE, p2[0]));
9906 arglist = tree_cons (NULL_TREE, s1, arglist);
9907 return build_function_call_expr (fn, arglist);
9911 /* Simplify a call to the strchr builtin.
9913 Return 0 if no simplification was possible, otherwise return the
9914 simplified form of the call as a tree.
9916 The simplified form may be a constant or other expression which
9917 computes the same value, but in a more efficient manner (including
9918 calls to other builtin functions).
9920 The call may contain arguments which need to be evaluated, but
9921 which are not useful to determine the result of the call. In
9922 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9923 COMPOUND_EXPR will be an argument which must be evaluated.
9924 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9925 COMPOUND_EXPR in the chain will contain the tree for the simplified
9926 form of the builtin function call. */
9928 static tree
9929 fold_builtin_strchr (tree arglist, tree type)
9931 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9932 return 0;
9933 else
9935 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9936 const char *p1;
9938 if (TREE_CODE (s2) != INTEGER_CST)
9939 return 0;
9941 p1 = c_getstr (s1);
9942 if (p1 != NULL)
9944 char c;
9945 const char *r;
9946 tree tem;
9948 if (target_char_cast (s2, &c))
9949 return 0;
9951 r = strchr (p1, c);
9953 if (r == NULL)
9954 return build_int_cst (TREE_TYPE (s1), 0);
9956 /* Return an offset into the constant string argument. */
9957 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9958 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9959 return fold_convert (type, tem);
9961 return 0;
9965 /* Simplify a call to the strrchr builtin.
9967 Return 0 if no simplification was possible, otherwise return the
9968 simplified form of the call as a tree.
9970 The simplified form may be a constant or other expression which
9971 computes the same value, but in a more efficient manner (including
9972 calls to other builtin functions).
9974 The call may contain arguments which need to be evaluated, but
9975 which are not useful to determine the result of the call. In
9976 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9977 COMPOUND_EXPR will be an argument which must be evaluated.
9978 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9979 COMPOUND_EXPR in the chain will contain the tree for the simplified
9980 form of the builtin function call. */
9982 static tree
9983 fold_builtin_strrchr (tree arglist, tree type)
9985 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9986 return 0;
9987 else
9989 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9990 tree fn;
9991 const char *p1;
9993 if (TREE_CODE (s2) != INTEGER_CST)
9994 return 0;
9996 p1 = c_getstr (s1);
9997 if (p1 != NULL)
9999 char c;
10000 const char *r;
10001 tree tem;
10003 if (target_char_cast (s2, &c))
10004 return 0;
10006 r = strrchr (p1, c);
10008 if (r == NULL)
10009 return build_int_cst (TREE_TYPE (s1), 0);
10011 /* Return an offset into the constant string argument. */
10012 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
10013 s1, build_int_cst (TREE_TYPE (s1), r - p1));
10014 return fold_convert (type, tem);
10017 if (! integer_zerop (s2))
10018 return 0;
10020 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
10021 if (!fn)
10022 return 0;
10024 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
10025 return build_function_call_expr (fn, arglist);
10029 /* Simplify a call to the strpbrk builtin.
10031 Return 0 if no simplification was possible, otherwise return the
10032 simplified form of the call as a tree.
10034 The simplified form may be a constant or other expression which
10035 computes the same value, but in a more efficient manner (including
10036 calls to other builtin functions).
10038 The call may contain arguments which need to be evaluated, but
10039 which are not useful to determine the result of the call. In
10040 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10041 COMPOUND_EXPR will be an argument which must be evaluated.
10042 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10043 COMPOUND_EXPR in the chain will contain the tree for the simplified
10044 form of the builtin function call. */
10046 static tree
10047 fold_builtin_strpbrk (tree arglist, tree type)
10049 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10050 return 0;
10051 else
10053 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10054 tree fn;
10055 const char *p1, *p2;
10057 p2 = c_getstr (s2);
10058 if (p2 == NULL)
10059 return 0;
10061 p1 = c_getstr (s1);
10062 if (p1 != NULL)
10064 const char *r = strpbrk (p1, p2);
10065 tree tem;
10067 if (r == NULL)
10068 return build_int_cst (TREE_TYPE (s1), 0);
10070 /* Return an offset into the constant string argument. */
10071 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
10072 s1, build_int_cst (TREE_TYPE (s1), r - p1));
10073 return fold_convert (type, tem);
10076 if (p2[0] == '\0')
10077 /* strpbrk(x, "") == NULL.
10078 Evaluate and ignore s1 in case it had side-effects. */
10079 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
10081 if (p2[1] != '\0')
10082 return 0; /* Really call strpbrk. */
10084 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
10085 if (!fn)
10086 return 0;
10088 /* New argument list transforming strpbrk(s1, s2) to
10089 strchr(s1, s2[0]). */
10090 arglist = build_tree_list (NULL_TREE,
10091 build_int_cst (NULL_TREE, p2[0]));
10092 arglist = tree_cons (NULL_TREE, s1, arglist);
10093 return build_function_call_expr (fn, arglist);
10097 /* Simplify a call to the strcat builtin.
10099 Return 0 if no simplification was possible, otherwise return the
10100 simplified form of the call as a tree.
10102 The simplified form may be a constant or other expression which
10103 computes the same value, but in a more efficient manner (including
10104 calls to other builtin functions).
10106 The call may contain arguments which need to be evaluated, but
10107 which are not useful to determine the result of the call. In
10108 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10109 COMPOUND_EXPR will be an argument which must be evaluated.
10110 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10111 COMPOUND_EXPR in the chain will contain the tree for the simplified
10112 form of the builtin function call. */
10114 static tree
10115 fold_builtin_strcat (tree arglist)
10117 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10118 return 0;
10119 else
10121 tree dst = TREE_VALUE (arglist),
10122 src = TREE_VALUE (TREE_CHAIN (arglist));
10123 const char *p = c_getstr (src);
10125 /* If the string length is zero, return the dst parameter. */
10126 if (p && *p == '\0')
10127 return dst;
10129 return 0;
10133 /* Simplify a call to the strncat builtin.
10135 Return 0 if no simplification was possible, otherwise return the
10136 simplified form of the call as a tree.
10138 The simplified form may be a constant or other expression which
10139 computes the same value, but in a more efficient manner (including
10140 calls to other builtin functions).
10142 The call may contain arguments which need to be evaluated, but
10143 which are not useful to determine the result of the call. In
10144 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10145 COMPOUND_EXPR will be an argument which must be evaluated.
10146 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10147 COMPOUND_EXPR in the chain will contain the tree for the simplified
10148 form of the builtin function call. */
10150 static tree
10151 fold_builtin_strncat (tree arglist)
10153 if (!validate_arglist (arglist,
10154 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10155 return 0;
10156 else
10158 tree dst = TREE_VALUE (arglist);
10159 tree src = TREE_VALUE (TREE_CHAIN (arglist));
10160 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10161 const char *p = c_getstr (src);
10163 /* If the requested length is zero, or the src parameter string
10164 length is zero, return the dst parameter. */
10165 if (integer_zerop (len) || (p && *p == '\0'))
10166 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
10168 /* If the requested len is greater than or equal to the string
10169 length, call strcat. */
10170 if (TREE_CODE (len) == INTEGER_CST && p
10171 && compare_tree_int (len, strlen (p)) >= 0)
10173 tree newarglist
10174 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
10175 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
10177 /* If the replacement _DECL isn't initialized, don't do the
10178 transformation. */
10179 if (!fn)
10180 return 0;
10182 return build_function_call_expr (fn, newarglist);
10184 return 0;
10188 /* Simplify a call to the strspn builtin.
10190 Return 0 if no simplification was possible, otherwise return the
10191 simplified form of the call as a tree.
10193 The simplified form may be a constant or other expression which
10194 computes the same value, but in a more efficient manner (including
10195 calls to other builtin functions).
10197 The call may contain arguments which need to be evaluated, but
10198 which are not useful to determine the result of the call. In
10199 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10200 COMPOUND_EXPR will be an argument which must be evaluated.
10201 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10202 COMPOUND_EXPR in the chain will contain the tree for the simplified
10203 form of the builtin function call. */
10205 static tree
10206 fold_builtin_strspn (tree arglist)
10208 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10209 return 0;
10210 else
10212 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10213 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10215 /* If both arguments are constants, evaluate at compile-time. */
10216 if (p1 && p2)
10218 const size_t r = strspn (p1, p2);
10219 return size_int (r);
10222 /* If either argument is "", return 0. */
10223 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
10224 /* Evaluate and ignore both arguments in case either one has
10225 side-effects. */
10226 return omit_two_operands (integer_type_node, integer_zero_node,
10227 s1, s2);
10228 return 0;
10232 /* Simplify a call to the strcspn builtin.
10234 Return 0 if no simplification was possible, otherwise return the
10235 simplified form of the call as a tree.
10237 The simplified form may be a constant or other expression which
10238 computes the same value, but in a more efficient manner (including
10239 calls to other builtin functions).
10241 The call may contain arguments which need to be evaluated, but
10242 which are not useful to determine the result of the call. In
10243 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10244 COMPOUND_EXPR will be an argument which must be evaluated.
10245 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10246 COMPOUND_EXPR in the chain will contain the tree for the simplified
10247 form of the builtin function call. */
10249 static tree
10250 fold_builtin_strcspn (tree arglist)
10252 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10253 return 0;
10254 else
10256 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10257 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10259 /* If both arguments are constants, evaluate at compile-time. */
10260 if (p1 && p2)
10262 const size_t r = strcspn (p1, p2);
10263 return size_int (r);
10266 /* If the first argument is "", return 0. */
10267 if (p1 && *p1 == '\0')
10269 /* Evaluate and ignore argument s2 in case it has
10270 side-effects. */
10271 return omit_one_operand (integer_type_node,
10272 integer_zero_node, s2);
10275 /* If the second argument is "", return __builtin_strlen(s1). */
10276 if (p2 && *p2 == '\0')
10278 tree newarglist = build_tree_list (NULL_TREE, s1),
10279 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
10281 /* If the replacement _DECL isn't initialized, don't do the
10282 transformation. */
10283 if (!fn)
10284 return 0;
10286 return build_function_call_expr (fn, newarglist);
10288 return 0;
10292 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
10293 by the builtin will be ignored. UNLOCKED is true is true if this
10294 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
10295 the known length of the string. Return NULL_TREE if no simplification
10296 was possible. */
10298 tree
10299 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
10301 tree fn;
10302 /* If we're using an unlocked function, assume the other unlocked
10303 functions exist explicitly. */
10304 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
10305 : implicit_built_in_decls[BUILT_IN_FPUTC];
10306 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
10307 : implicit_built_in_decls[BUILT_IN_FWRITE];
10309 /* If the return value is used, don't do the transformation. */
10310 if (!ignore)
10311 return 0;
10313 /* Verify the arguments in the original call. */
10314 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10315 return 0;
10317 if (! len)
10318 len = c_strlen (TREE_VALUE (arglist), 0);
10320 /* Get the length of the string passed to fputs. If the length
10321 can't be determined, punt. */
10322 if (!len
10323 || TREE_CODE (len) != INTEGER_CST)
10324 return 0;
10326 switch (compare_tree_int (len, 1))
10328 case -1: /* length is 0, delete the call entirely . */
10329 return omit_one_operand (integer_type_node, integer_zero_node,
10330 TREE_VALUE (TREE_CHAIN (arglist)));
10332 case 0: /* length is 1, call fputc. */
10334 const char *p = c_getstr (TREE_VALUE (arglist));
10336 if (p != NULL)
10338 /* New argument list transforming fputs(string, stream) to
10339 fputc(string[0], stream). */
10340 arglist = build_tree_list (NULL_TREE,
10341 TREE_VALUE (TREE_CHAIN (arglist)));
10342 arglist = tree_cons (NULL_TREE,
10343 build_int_cst (NULL_TREE, p[0]),
10344 arglist);
10345 fn = fn_fputc;
10346 break;
10349 /* FALLTHROUGH */
10350 case 1: /* length is greater than 1, call fwrite. */
10352 tree string_arg;
10354 /* If optimizing for size keep fputs. */
10355 if (optimize_size)
10356 return 0;
10357 string_arg = TREE_VALUE (arglist);
10358 /* New argument list transforming fputs(string, stream) to
10359 fwrite(string, 1, len, stream). */
10360 arglist = build_tree_list (NULL_TREE,
10361 TREE_VALUE (TREE_CHAIN (arglist)));
10362 arglist = tree_cons (NULL_TREE, len, arglist);
10363 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
10364 arglist = tree_cons (NULL_TREE, string_arg, arglist);
10365 fn = fn_fwrite;
10366 break;
10368 default:
10369 gcc_unreachable ();
10372 /* If the replacement _DECL isn't initialized, don't do the
10373 transformation. */
10374 if (!fn)
10375 return 0;
10377 /* These optimizations are only performed when the result is ignored,
10378 hence there's no need to cast the result to integer_type_node. */
10379 return build_function_call_expr (fn, arglist);
10382 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
10383 produced. False otherwise. This is done so that we don't output the error
10384 or warning twice or three times. */
10385 bool
10386 fold_builtin_next_arg (tree arglist)
10388 tree fntype = TREE_TYPE (current_function_decl);
10390 if (TYPE_ARG_TYPES (fntype) == 0
10391 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
10392 == void_type_node))
10394 error ("%<va_start%> used in function with fixed args");
10395 return true;
10397 else if (!arglist)
10399 /* Evidently an out of date version of <stdarg.h>; can't validate
10400 va_start's second argument, but can still work as intended. */
10401 warning (0, "%<__builtin_next_arg%> called without an argument");
10402 return true;
10404 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
10405 when we checked the arguments and if needed issued a warning. */
10406 else if (!TREE_CHAIN (arglist)
10407 || !integer_zerop (TREE_VALUE (arglist))
10408 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
10409 || TREE_CHAIN (TREE_CHAIN (arglist)))
10411 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
10412 tree arg = TREE_VALUE (arglist);
10414 if (TREE_CHAIN (arglist))
10416 error ("%<va_start%> used with too many arguments");
10417 return true;
10420 /* Strip off all nops for the sake of the comparison. This
10421 is not quite the same as STRIP_NOPS. It does more.
10422 We must also strip off INDIRECT_EXPR for C++ reference
10423 parameters. */
10424 while (TREE_CODE (arg) == NOP_EXPR
10425 || TREE_CODE (arg) == CONVERT_EXPR
10426 || TREE_CODE (arg) == NON_LVALUE_EXPR
10427 || TREE_CODE (arg) == INDIRECT_REF)
10428 arg = TREE_OPERAND (arg, 0);
10429 if (arg != last_parm)
10431 /* FIXME: Sometimes with the tree optimizers we can get the
10432 not the last argument even though the user used the last
10433 argument. We just warn and set the arg to be the last
10434 argument so that we will get wrong-code because of
10435 it. */
10436 warning (0, "second parameter of %<va_start%> not last named argument");
10438 /* We want to verify the second parameter just once before the tree
10439 optimizers are run and then avoid keeping it in the tree,
10440 as otherwise we could warn even for correct code like:
10441 void foo (int i, ...)
10442 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
10443 TREE_VALUE (arglist) = integer_zero_node;
10444 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
10446 return false;
10450 /* Simplify a call to the sprintf builtin.
10452 Return 0 if no simplification was possible, otherwise return the
10453 simplified form of the call as a tree. If IGNORED is true, it means that
10454 the caller does not use the returned value of the function. */
10456 static tree
10457 fold_builtin_sprintf (tree arglist, int ignored)
10459 tree call, retval, dest, fmt;
10460 const char *fmt_str = NULL;
10462 /* Verify the required arguments in the original call. We deal with two
10463 types of sprintf() calls: 'sprintf (str, fmt)' and
10464 'sprintf (dest, "%s", orig)'. */
10465 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
10466 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
10467 VOID_TYPE))
10468 return NULL_TREE;
10470 /* Get the destination string and the format specifier. */
10471 dest = TREE_VALUE (arglist);
10472 fmt = TREE_VALUE (TREE_CHAIN (arglist));
10474 /* Check whether the format is a literal string constant. */
10475 fmt_str = c_getstr (fmt);
10476 if (fmt_str == NULL)
10477 return NULL_TREE;
10479 call = NULL_TREE;
10480 retval = NULL_TREE;
10482 if (!init_target_chars())
10483 return 0;
10485 /* If the format doesn't contain % args or %%, use strcpy. */
10486 if (strchr (fmt_str, target_percent) == NULL)
10488 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10490 if (!fn)
10491 return NULL_TREE;
10493 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10494 'format' is known to contain no % formats. */
10495 arglist = build_tree_list (NULL_TREE, fmt);
10496 arglist = tree_cons (NULL_TREE, dest, arglist);
10497 call = build_function_call_expr (fn, arglist);
10498 if (!ignored)
10499 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
10502 /* If the format is "%s", use strcpy if the result isn't used. */
10503 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
10505 tree fn, orig;
10506 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10508 if (!fn)
10509 return NULL_TREE;
10511 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
10512 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10513 arglist = build_tree_list (NULL_TREE, orig);
10514 arglist = tree_cons (NULL_TREE, dest, arglist);
10515 if (!ignored)
10517 retval = c_strlen (orig, 1);
10518 if (!retval || TREE_CODE (retval) != INTEGER_CST)
10519 return NULL_TREE;
10521 call = build_function_call_expr (fn, arglist);
10524 if (call && retval)
10526 retval = fold_convert
10527 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
10528 retval);
10529 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
10531 else
10532 return call;
10535 /* Expand a call to __builtin_object_size. */
10538 expand_builtin_object_size (tree exp)
10540 tree ost;
10541 int object_size_type;
10542 tree fndecl = get_callee_fndecl (exp);
10543 tree arglist = TREE_OPERAND (exp, 1);
10544 location_t locus = EXPR_LOCATION (exp);
10546 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10548 error ("%Hfirst argument of %D must be a pointer, second integer constant",
10549 &locus, fndecl);
10550 expand_builtin_trap ();
10551 return const0_rtx;
10554 ost = TREE_VALUE (TREE_CHAIN (arglist));
10555 STRIP_NOPS (ost);
10557 if (TREE_CODE (ost) != INTEGER_CST
10558 || tree_int_cst_sgn (ost) < 0
10559 || compare_tree_int (ost, 3) > 0)
10561 error ("%Hlast argument of %D is not integer constant between 0 and 3",
10562 &locus, fndecl);
10563 expand_builtin_trap ();
10564 return const0_rtx;
10567 object_size_type = tree_low_cst (ost, 0);
10569 return object_size_type < 2 ? constm1_rtx : const0_rtx;
10572 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10573 FCODE is the BUILT_IN_* to use.
10574 Return 0 if we failed; the caller should emit a normal call,
10575 otherwise try to get the result in TARGET, if convenient (and in
10576 mode MODE if that's convenient). */
10578 static rtx
10579 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10580 enum built_in_function fcode)
10582 tree arglist = TREE_OPERAND (exp, 1);
10583 tree dest, src, len, size;
10585 if (!validate_arglist (arglist,
10586 POINTER_TYPE,
10587 fcode == BUILT_IN_MEMSET_CHK
10588 ? INTEGER_TYPE : POINTER_TYPE,
10589 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10590 return 0;
10592 dest = TREE_VALUE (arglist);
10593 src = TREE_VALUE (TREE_CHAIN (arglist));
10594 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10595 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10597 if (! host_integerp (size, 1))
10598 return 0;
10600 if (host_integerp (len, 1) || integer_all_onesp (size))
10602 tree fn;
10604 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10606 location_t locus = EXPR_LOCATION (exp);
10607 warning (0, "%Hcall to %D will always overflow destination buffer",
10608 &locus, get_callee_fndecl (exp));
10609 return 0;
10612 arglist = build_tree_list (NULL_TREE, len);
10613 arglist = tree_cons (NULL_TREE, src, arglist);
10614 arglist = tree_cons (NULL_TREE, dest, arglist);
10616 fn = NULL_TREE;
10617 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10618 mem{cpy,pcpy,move,set} is available. */
10619 switch (fcode)
10621 case BUILT_IN_MEMCPY_CHK:
10622 fn = built_in_decls[BUILT_IN_MEMCPY];
10623 break;
10624 case BUILT_IN_MEMPCPY_CHK:
10625 fn = built_in_decls[BUILT_IN_MEMPCPY];
10626 break;
10627 case BUILT_IN_MEMMOVE_CHK:
10628 fn = built_in_decls[BUILT_IN_MEMMOVE];
10629 break;
10630 case BUILT_IN_MEMSET_CHK:
10631 fn = built_in_decls[BUILT_IN_MEMSET];
10632 break;
10633 default:
10634 break;
10637 if (! fn)
10638 return 0;
10640 fn = build_function_call_expr (fn, arglist);
10641 if (TREE_CODE (fn) == CALL_EXPR)
10642 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10643 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10645 else if (fcode == BUILT_IN_MEMSET_CHK)
10646 return 0;
10647 else
10649 unsigned int dest_align
10650 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10652 /* If DEST is not a pointer type, call the normal function. */
10653 if (dest_align == 0)
10654 return 0;
10656 /* If SRC and DEST are the same (and not volatile), do nothing. */
10657 if (operand_equal_p (src, dest, 0))
10659 tree expr;
10661 if (fcode != BUILT_IN_MEMPCPY_CHK)
10663 /* Evaluate and ignore LEN in case it has side-effects. */
10664 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10665 return expand_expr (dest, target, mode, EXPAND_NORMAL);
10668 len = fold_convert (TREE_TYPE (dest), len);
10669 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10670 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10673 /* __memmove_chk special case. */
10674 if (fcode == BUILT_IN_MEMMOVE_CHK)
10676 unsigned int src_align
10677 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10679 if (src_align == 0)
10680 return 0;
10682 /* If src is categorized for a readonly section we can use
10683 normal __memcpy_chk. */
10684 if (readonly_data_expr (src))
10686 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10687 if (!fn)
10688 return 0;
10689 fn = build_function_call_expr (fn, arglist);
10690 if (TREE_CODE (fn) == CALL_EXPR)
10691 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10692 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10695 return 0;
10699 /* Emit warning if a buffer overflow is detected at compile time. */
10701 static void
10702 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10704 int arg_mask, is_strlen = 0;
10705 tree arglist = TREE_OPERAND (exp, 1), a;
10706 tree len, size;
10707 location_t locus;
10709 switch (fcode)
10711 case BUILT_IN_STRCPY_CHK:
10712 case BUILT_IN_STPCPY_CHK:
10713 /* For __strcat_chk the warning will be emitted only if overflowing
10714 by at least strlen (dest) + 1 bytes. */
10715 case BUILT_IN_STRCAT_CHK:
10716 arg_mask = 6;
10717 is_strlen = 1;
10718 break;
10719 case BUILT_IN_STRNCAT_CHK:
10720 /* For __strncat_chk the warning will be emitted only if overflowing
10721 by at least strlen (dest) + 1 bytes. */
10722 arg_mask = 12;
10723 break;
10724 case BUILT_IN_STRNCPY_CHK:
10725 arg_mask = 12;
10726 break;
10727 case BUILT_IN_SNPRINTF_CHK:
10728 case BUILT_IN_VSNPRINTF_CHK:
10729 arg_mask = 10;
10730 break;
10731 default:
10732 gcc_unreachable ();
10735 len = NULL_TREE;
10736 size = NULL_TREE;
10737 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10738 if (arg_mask & 1)
10740 if (len)
10741 size = a;
10742 else
10743 len = a;
10746 if (!len || !size)
10747 return;
10749 len = TREE_VALUE (len);
10750 size = TREE_VALUE (size);
10752 if (! host_integerp (size, 1) || integer_all_onesp (size))
10753 return;
10755 if (is_strlen)
10757 len = c_strlen (len, 1);
10758 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10759 return;
10761 else if (fcode == BUILT_IN_STRNCAT_CHK)
10763 tree src = TREE_VALUE (TREE_CHAIN (arglist));
10764 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10765 return;
10766 src = c_strlen (src, 1);
10767 if (! src || ! host_integerp (src, 1))
10769 locus = EXPR_LOCATION (exp);
10770 warning (0, "%Hcall to %D might overflow destination buffer",
10771 &locus, get_callee_fndecl (exp));
10772 return;
10774 else if (tree_int_cst_lt (src, size))
10775 return;
10777 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10778 return;
10780 locus = EXPR_LOCATION (exp);
10781 warning (0, "%Hcall to %D will always overflow destination buffer",
10782 &locus, get_callee_fndecl (exp));
10785 /* Emit warning if a buffer overflow is detected at compile time
10786 in __sprintf_chk/__vsprintf_chk calls. */
10788 static void
10789 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10791 tree arglist = TREE_OPERAND (exp, 1);
10792 tree dest, size, len, fmt, flag;
10793 const char *fmt_str;
10795 /* Verify the required arguments in the original call. */
10796 if (! arglist)
10797 return;
10798 dest = TREE_VALUE (arglist);
10799 arglist = TREE_CHAIN (arglist);
10800 if (! arglist)
10801 return;
10802 flag = TREE_VALUE (arglist);
10803 arglist = TREE_CHAIN (arglist);
10804 if (! arglist)
10805 return;
10806 size = TREE_VALUE (arglist);
10807 arglist = TREE_CHAIN (arglist);
10808 if (! arglist)
10809 return;
10810 fmt = TREE_VALUE (arglist);
10811 arglist = TREE_CHAIN (arglist);
10813 if (! host_integerp (size, 1) || integer_all_onesp (size))
10814 return;
10816 /* Check whether the format is a literal string constant. */
10817 fmt_str = c_getstr (fmt);
10818 if (fmt_str == NULL)
10819 return;
10821 if (!init_target_chars())
10822 return;
10824 /* If the format doesn't contain % args or %%, we know its size. */
10825 if (strchr (fmt_str, target_percent) == 0)
10826 len = build_int_cstu (size_type_node, strlen (fmt_str));
10827 /* If the format is "%s" and first ... argument is a string literal,
10828 we know it too. */
10829 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10831 tree arg;
10833 if (! arglist)
10834 return;
10835 arg = TREE_VALUE (arglist);
10836 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10837 return;
10839 len = c_strlen (arg, 1);
10840 if (!len || ! host_integerp (len, 1))
10841 return;
10843 else
10844 return;
10846 if (! tree_int_cst_lt (len, size))
10848 location_t locus = EXPR_LOCATION (exp);
10849 warning (0, "%Hcall to %D will always overflow destination buffer",
10850 &locus, get_callee_fndecl (exp));
10854 /* Fold a call to __builtin_object_size, if possible. */
10856 tree
10857 fold_builtin_object_size (tree arglist)
10859 tree ptr, ost, ret = 0;
10860 int object_size_type;
10862 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10863 return 0;
10865 ptr = TREE_VALUE (arglist);
10866 ost = TREE_VALUE (TREE_CHAIN (arglist));
10867 STRIP_NOPS (ost);
10869 if (TREE_CODE (ost) != INTEGER_CST
10870 || tree_int_cst_sgn (ost) < 0
10871 || compare_tree_int (ost, 3) > 0)
10872 return 0;
10874 object_size_type = tree_low_cst (ost, 0);
10876 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10877 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10878 and (size_t) 0 for types 2 and 3. */
10879 if (TREE_SIDE_EFFECTS (ptr))
10880 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
10882 if (TREE_CODE (ptr) == ADDR_EXPR)
10883 ret = build_int_cstu (size_type_node,
10884 compute_builtin_object_size (ptr, object_size_type));
10886 else if (TREE_CODE (ptr) == SSA_NAME)
10888 unsigned HOST_WIDE_INT bytes;
10890 /* If object size is not known yet, delay folding until
10891 later. Maybe subsequent passes will help determining
10892 it. */
10893 bytes = compute_builtin_object_size (ptr, object_size_type);
10894 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10895 ? -1 : 0))
10896 ret = build_int_cstu (size_type_node, bytes);
10899 if (ret)
10901 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
10902 HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
10903 if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
10904 ret = NULL_TREE;
10907 return ret;
10910 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10911 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10912 code of the builtin. If MAXLEN is not NULL, it is maximum length
10913 passed as third argument. */
10915 tree
10916 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10917 enum built_in_function fcode)
10919 tree dest, src, len, size, fn;
10921 if (!validate_arglist (arglist,
10922 POINTER_TYPE,
10923 fcode == BUILT_IN_MEMSET_CHK
10924 ? INTEGER_TYPE : POINTER_TYPE,
10925 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10926 return 0;
10928 dest = TREE_VALUE (arglist);
10929 /* Actually val for __memset_chk, but it doesn't matter. */
10930 src = TREE_VALUE (TREE_CHAIN (arglist));
10931 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10932 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10934 /* If SRC and DEST are the same (and not volatile), return DEST
10935 (resp. DEST+LEN for __mempcpy_chk). */
10936 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10938 if (fcode != BUILT_IN_MEMPCPY_CHK)
10939 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10940 else
10942 tree temp = fold_convert (TREE_TYPE (dest), len);
10943 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10944 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10948 if (! host_integerp (size, 1))
10949 return 0;
10951 if (! integer_all_onesp (size))
10953 if (! host_integerp (len, 1))
10955 /* If LEN is not constant, try MAXLEN too.
10956 For MAXLEN only allow optimizing into non-_ocs function
10957 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10958 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10960 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10962 /* (void) __mempcpy_chk () can be optimized into
10963 (void) __memcpy_chk (). */
10964 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10965 if (!fn)
10966 return 0;
10968 return build_function_call_expr (fn, arglist);
10970 return 0;
10973 else
10974 maxlen = len;
10976 if (tree_int_cst_lt (size, maxlen))
10977 return 0;
10980 arglist = build_tree_list (NULL_TREE, len);
10981 arglist = tree_cons (NULL_TREE, src, arglist);
10982 arglist = tree_cons (NULL_TREE, dest, arglist);
10984 fn = NULL_TREE;
10985 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10986 mem{cpy,pcpy,move,set} is available. */
10987 switch (fcode)
10989 case BUILT_IN_MEMCPY_CHK:
10990 fn = built_in_decls[BUILT_IN_MEMCPY];
10991 break;
10992 case BUILT_IN_MEMPCPY_CHK:
10993 fn = built_in_decls[BUILT_IN_MEMPCPY];
10994 break;
10995 case BUILT_IN_MEMMOVE_CHK:
10996 fn = built_in_decls[BUILT_IN_MEMMOVE];
10997 break;
10998 case BUILT_IN_MEMSET_CHK:
10999 fn = built_in_decls[BUILT_IN_MEMSET];
11000 break;
11001 default:
11002 break;
11005 if (!fn)
11006 return 0;
11008 return build_function_call_expr (fn, arglist);
11011 /* Fold a call to the __st[rp]cpy_chk builtin.
11012 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
11013 code of the builtin. If MAXLEN is not NULL, it is maximum length of
11014 strings passed as second argument. */
11016 tree
11017 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
11018 enum built_in_function fcode)
11020 tree dest, src, size, len, fn;
11022 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11023 VOID_TYPE))
11024 return 0;
11026 dest = TREE_VALUE (arglist);
11027 src = TREE_VALUE (TREE_CHAIN (arglist));
11028 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11030 /* If SRC and DEST are the same (and not volatile), return DEST. */
11031 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
11032 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
11034 if (! host_integerp (size, 1))
11035 return 0;
11037 if (! integer_all_onesp (size))
11039 len = c_strlen (src, 1);
11040 if (! len || ! host_integerp (len, 1))
11042 /* If LEN is not constant, try MAXLEN too.
11043 For MAXLEN only allow optimizing into non-_ocs function
11044 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11045 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11047 if (fcode == BUILT_IN_STPCPY_CHK)
11049 if (! ignore)
11050 return 0;
11052 /* If return value of __stpcpy_chk is ignored,
11053 optimize into __strcpy_chk. */
11054 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
11055 if (!fn)
11056 return 0;
11058 return build_function_call_expr (fn, arglist);
11061 if (! len || TREE_SIDE_EFFECTS (len))
11062 return 0;
11064 /* If c_strlen returned something, but not a constant,
11065 transform __strcpy_chk into __memcpy_chk. */
11066 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
11067 if (!fn)
11068 return 0;
11070 len = size_binop (PLUS_EXPR, len, ssize_int (1));
11071 arglist = build_tree_list (NULL_TREE, size);
11072 arglist = tree_cons (NULL_TREE, len, arglist);
11073 arglist = tree_cons (NULL_TREE, src, arglist);
11074 arglist = tree_cons (NULL_TREE, dest, arglist);
11075 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
11076 build_function_call_expr (fn, arglist));
11079 else
11080 maxlen = len;
11082 if (! tree_int_cst_lt (maxlen, size))
11083 return 0;
11086 arglist = build_tree_list (NULL_TREE, src);
11087 arglist = tree_cons (NULL_TREE, dest, arglist);
11089 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
11090 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
11091 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
11092 if (!fn)
11093 return 0;
11095 return build_function_call_expr (fn, arglist);
11098 /* Fold a call to the __strncpy_chk builtin.
11099 If MAXLEN is not NULL, it is maximum length passed as third argument. */
11101 tree
11102 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
11104 tree dest, src, size, len, fn;
11106 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11107 INTEGER_TYPE, VOID_TYPE))
11108 return 0;
11110 dest = TREE_VALUE (arglist);
11111 src = TREE_VALUE (TREE_CHAIN (arglist));
11112 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11113 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
11115 if (! host_integerp (size, 1))
11116 return 0;
11118 if (! integer_all_onesp (size))
11120 if (! host_integerp (len, 1))
11122 /* If LEN is not constant, try MAXLEN too.
11123 For MAXLEN only allow optimizing into non-_ocs function
11124 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11125 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11126 return 0;
11128 else
11129 maxlen = len;
11131 if (tree_int_cst_lt (size, maxlen))
11132 return 0;
11135 arglist = build_tree_list (NULL_TREE, len);
11136 arglist = tree_cons (NULL_TREE, src, arglist);
11137 arglist = tree_cons (NULL_TREE, dest, arglist);
11139 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
11140 fn = built_in_decls[BUILT_IN_STRNCPY];
11141 if (!fn)
11142 return 0;
11144 return build_function_call_expr (fn, arglist);
11147 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
11149 static tree
11150 fold_builtin_strcat_chk (tree fndecl, tree arglist)
11152 tree dest, src, size, fn;
11153 const char *p;
11155 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11156 VOID_TYPE))
11157 return 0;
11159 dest = TREE_VALUE (arglist);
11160 src = TREE_VALUE (TREE_CHAIN (arglist));
11161 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11163 p = c_getstr (src);
11164 /* If the SRC parameter is "", return DEST. */
11165 if (p && *p == '\0')
11166 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
11168 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
11169 return 0;
11171 arglist = build_tree_list (NULL_TREE, src);
11172 arglist = tree_cons (NULL_TREE, dest, arglist);
11174 /* If __builtin_strcat_chk is used, assume strcat is available. */
11175 fn = built_in_decls[BUILT_IN_STRCAT];
11176 if (!fn)
11177 return 0;
11179 return build_function_call_expr (fn, arglist);
11182 /* Fold a call to the __strncat_chk builtin EXP. */
11184 static tree
11185 fold_builtin_strncat_chk (tree fndecl, tree arglist)
11187 tree dest, src, size, len, fn;
11188 const char *p;
11190 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11191 INTEGER_TYPE, VOID_TYPE))
11192 return 0;
11194 dest = TREE_VALUE (arglist);
11195 src = TREE_VALUE (TREE_CHAIN (arglist));
11196 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11197 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
11199 p = c_getstr (src);
11200 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
11201 if (p && *p == '\0')
11202 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
11203 else if (integer_zerop (len))
11204 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
11206 if (! host_integerp (size, 1))
11207 return 0;
11209 if (! integer_all_onesp (size))
11211 tree src_len = c_strlen (src, 1);
11212 if (src_len
11213 && host_integerp (src_len, 1)
11214 && host_integerp (len, 1)
11215 && ! tree_int_cst_lt (len, src_len))
11217 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
11218 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
11219 if (!fn)
11220 return 0;
11222 arglist = build_tree_list (NULL_TREE, size);
11223 arglist = tree_cons (NULL_TREE, src, arglist);
11224 arglist = tree_cons (NULL_TREE, dest, arglist);
11225 return build_function_call_expr (fn, arglist);
11227 return 0;
11230 arglist = build_tree_list (NULL_TREE, len);
11231 arglist = tree_cons (NULL_TREE, src, arglist);
11232 arglist = tree_cons (NULL_TREE, dest, arglist);
11234 /* If __builtin_strncat_chk is used, assume strncat is available. */
11235 fn = built_in_decls[BUILT_IN_STRNCAT];
11236 if (!fn)
11237 return 0;
11239 return build_function_call_expr (fn, arglist);
11242 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
11243 a normal call should be emitted rather than expanding the function
11244 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
11246 static tree
11247 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
11249 tree dest, size, len, fn, fmt, flag;
11250 const char *fmt_str;
11252 /* Verify the required arguments in the original call. */
11253 if (! arglist)
11254 return 0;
11255 dest = TREE_VALUE (arglist);
11256 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11257 return 0;
11258 arglist = TREE_CHAIN (arglist);
11259 if (! arglist)
11260 return 0;
11261 flag = TREE_VALUE (arglist);
11262 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
11263 return 0;
11264 arglist = TREE_CHAIN (arglist);
11265 if (! arglist)
11266 return 0;
11267 size = TREE_VALUE (arglist);
11268 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11269 return 0;
11270 arglist = TREE_CHAIN (arglist);
11271 if (! arglist)
11272 return 0;
11273 fmt = TREE_VALUE (arglist);
11274 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11275 return 0;
11276 arglist = TREE_CHAIN (arglist);
11278 if (! host_integerp (size, 1))
11279 return 0;
11281 len = NULL_TREE;
11283 if (!init_target_chars())
11284 return 0;
11286 /* Check whether the format is a literal string constant. */
11287 fmt_str = c_getstr (fmt);
11288 if (fmt_str != NULL)
11290 /* If the format doesn't contain % args or %%, we know the size. */
11291 if (strchr (fmt_str, target_percent) == 0)
11293 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
11294 len = build_int_cstu (size_type_node, strlen (fmt_str));
11296 /* If the format is "%s" and first ... argument is a string literal,
11297 we know the size too. */
11298 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
11300 tree arg;
11302 if (arglist && !TREE_CHAIN (arglist))
11304 arg = TREE_VALUE (arglist);
11305 if (POINTER_TYPE_P (TREE_TYPE (arg)))
11307 len = c_strlen (arg, 1);
11308 if (! len || ! host_integerp (len, 1))
11309 len = NULL_TREE;
11315 if (! integer_all_onesp (size))
11317 if (! len || ! tree_int_cst_lt (len, size))
11318 return 0;
11321 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
11322 or if format doesn't contain % chars or is "%s". */
11323 if (! integer_zerop (flag))
11325 if (fmt_str == NULL)
11326 return 0;
11327 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11328 return 0;
11331 arglist = tree_cons (NULL_TREE, fmt, arglist);
11332 arglist = tree_cons (NULL_TREE, dest, arglist);
11334 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
11335 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
11336 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
11337 if (!fn)
11338 return 0;
11340 return build_function_call_expr (fn, arglist);
11343 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
11344 a normal call should be emitted rather than expanding the function
11345 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
11346 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
11347 passed as second argument. */
11349 tree
11350 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
11351 enum built_in_function fcode)
11353 tree dest, size, len, fn, fmt, flag;
11354 const char *fmt_str;
11356 /* Verify the required arguments in the original call. */
11357 if (! arglist)
11358 return 0;
11359 dest = TREE_VALUE (arglist);
11360 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11361 return 0;
11362 arglist = TREE_CHAIN (arglist);
11363 if (! arglist)
11364 return 0;
11365 len = TREE_VALUE (arglist);
11366 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11367 return 0;
11368 arglist = TREE_CHAIN (arglist);
11369 if (! arglist)
11370 return 0;
11371 flag = TREE_VALUE (arglist);
11372 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11373 return 0;
11374 arglist = TREE_CHAIN (arglist);
11375 if (! arglist)
11376 return 0;
11377 size = TREE_VALUE (arglist);
11378 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11379 return 0;
11380 arglist = TREE_CHAIN (arglist);
11381 if (! arglist)
11382 return 0;
11383 fmt = TREE_VALUE (arglist);
11384 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11385 return 0;
11386 arglist = TREE_CHAIN (arglist);
11388 if (! host_integerp (size, 1))
11389 return 0;
11391 if (! integer_all_onesp (size))
11393 if (! host_integerp (len, 1))
11395 /* If LEN is not constant, try MAXLEN too.
11396 For MAXLEN only allow optimizing into non-_ocs function
11397 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11398 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11399 return 0;
11401 else
11402 maxlen = len;
11404 if (tree_int_cst_lt (size, maxlen))
11405 return 0;
11408 if (!init_target_chars())
11409 return 0;
11411 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
11412 or if format doesn't contain % chars or is "%s". */
11413 if (! integer_zerop (flag))
11415 fmt_str = c_getstr (fmt);
11416 if (fmt_str == NULL)
11417 return 0;
11418 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11419 return 0;
11422 arglist = tree_cons (NULL_TREE, fmt, arglist);
11423 arglist = tree_cons (NULL_TREE, len, arglist);
11424 arglist = tree_cons (NULL_TREE, dest, arglist);
11426 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
11427 available. */
11428 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
11429 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
11430 if (!fn)
11431 return 0;
11433 return build_function_call_expr (fn, arglist);
11436 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
11438 Return 0 if no simplification was possible, otherwise return the
11439 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11440 code of the function to be simplified. */
11442 static tree
11443 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
11444 enum built_in_function fcode)
11446 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
11447 const char *fmt_str = NULL;
11449 /* If the return value is used, don't do the transformation. */
11450 if (! ignore)
11451 return 0;
11453 /* Verify the required arguments in the original call. */
11454 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
11456 tree flag;
11458 if (! arglist)
11459 return 0;
11460 flag = TREE_VALUE (arglist);
11461 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11462 || TREE_SIDE_EFFECTS (flag))
11463 return 0;
11464 arglist = TREE_CHAIN (arglist);
11467 if (! arglist)
11468 return 0;
11469 fmt = TREE_VALUE (arglist);
11470 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11471 return 0;
11472 arglist = TREE_CHAIN (arglist);
11474 /* Check whether the format is a literal string constant. */
11475 fmt_str = c_getstr (fmt);
11476 if (fmt_str == NULL)
11477 return NULL_TREE;
11479 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
11481 /* If we're using an unlocked function, assume the other
11482 unlocked functions exist explicitly. */
11483 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
11484 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
11486 else
11488 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
11489 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
11492 if (!init_target_chars())
11493 return 0;
11495 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
11497 const char *str;
11499 if (strcmp (fmt_str, target_percent_s) == 0)
11501 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11502 return 0;
11504 if (! arglist
11505 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11506 || TREE_CHAIN (arglist))
11507 return 0;
11509 str = c_getstr (TREE_VALUE (arglist));
11510 if (str == NULL)
11511 return 0;
11513 else
11515 /* The format specifier doesn't contain any '%' characters. */
11516 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
11517 && arglist)
11518 return 0;
11519 str = fmt_str;
11522 /* If the string was "", printf does nothing. */
11523 if (str[0] == '\0')
11524 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11526 /* If the string has length of 1, call putchar. */
11527 if (str[1] == '\0')
11529 /* Given printf("c"), (where c is any one character,)
11530 convert "c"[0] to an int and pass that to the replacement
11531 function. */
11532 arg = build_int_cst (NULL_TREE, str[0]);
11533 arglist = build_tree_list (NULL_TREE, arg);
11534 fn = fn_putchar;
11536 else
11538 /* If the string was "string\n", call puts("string"). */
11539 size_t len = strlen (str);
11540 if ((unsigned char)str[len - 1] == target_newline)
11542 /* Create a NUL-terminated string that's one char shorter
11543 than the original, stripping off the trailing '\n'. */
11544 char *newstr = alloca (len);
11545 memcpy (newstr, str, len - 1);
11546 newstr[len - 1] = 0;
11548 arg = build_string_literal (len, newstr);
11549 arglist = build_tree_list (NULL_TREE, arg);
11550 fn = fn_puts;
11552 else
11553 /* We'd like to arrange to call fputs(string,stdout) here,
11554 but we need stdout and don't have a way to get it yet. */
11555 return 0;
11559 /* The other optimizations can be done only on the non-va_list variants. */
11560 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11561 return 0;
11563 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
11564 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11566 if (! arglist
11567 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11568 || TREE_CHAIN (arglist))
11569 return 0;
11570 fn = fn_puts;
11573 /* If the format specifier was "%c", call __builtin_putchar(arg). */
11574 else if (strcmp (fmt_str, target_percent_c) == 0)
11576 if (! arglist
11577 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11578 || TREE_CHAIN (arglist))
11579 return 0;
11580 fn = fn_putchar;
11583 if (!fn)
11584 return 0;
11586 call = build_function_call_expr (fn, arglist);
11587 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11590 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11592 Return 0 if no simplification was possible, otherwise return the
11593 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11594 code of the function to be simplified. */
11596 static tree
11597 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11598 enum built_in_function fcode)
11600 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11601 const char *fmt_str = NULL;
11603 /* If the return value is used, don't do the transformation. */
11604 if (! ignore)
11605 return 0;
11607 /* Verify the required arguments in the original call. */
11608 if (! arglist)
11609 return 0;
11610 fp = TREE_VALUE (arglist);
11611 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11612 return 0;
11613 arglist = TREE_CHAIN (arglist);
11615 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11617 tree flag;
11619 if (! arglist)
11620 return 0;
11621 flag = TREE_VALUE (arglist);
11622 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11623 || TREE_SIDE_EFFECTS (flag))
11624 return 0;
11625 arglist = TREE_CHAIN (arglist);
11628 if (! arglist)
11629 return 0;
11630 fmt = TREE_VALUE (arglist);
11631 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11632 return 0;
11633 arglist = TREE_CHAIN (arglist);
11635 /* Check whether the format is a literal string constant. */
11636 fmt_str = c_getstr (fmt);
11637 if (fmt_str == NULL)
11638 return NULL_TREE;
11640 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11642 /* If we're using an unlocked function, assume the other
11643 unlocked functions exist explicitly. */
11644 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11645 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11647 else
11649 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11650 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11653 if (!init_target_chars())
11654 return 0;
11656 /* If the format doesn't contain % args or %%, use strcpy. */
11657 if (strchr (fmt_str, target_percent) == NULL)
11659 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11660 && arglist)
11661 return 0;
11663 /* If the format specifier was "", fprintf does nothing. */
11664 if (fmt_str[0] == '\0')
11666 /* If FP has side-effects, just wait until gimplification is
11667 done. */
11668 if (TREE_SIDE_EFFECTS (fp))
11669 return 0;
11671 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11674 /* When "string" doesn't contain %, replace all cases of
11675 fprintf (fp, string) with fputs (string, fp). The fputs
11676 builtin will take care of special cases like length == 1. */
11677 arglist = build_tree_list (NULL_TREE, fp);
11678 arglist = tree_cons (NULL_TREE, fmt, arglist);
11679 fn = fn_fputs;
11682 /* The other optimizations can be done only on the non-va_list variants. */
11683 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11684 return 0;
11686 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11687 else if (strcmp (fmt_str, target_percent_s) == 0)
11689 if (! arglist
11690 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11691 || TREE_CHAIN (arglist))
11692 return 0;
11693 arg = TREE_VALUE (arglist);
11694 arglist = build_tree_list (NULL_TREE, fp);
11695 arglist = tree_cons (NULL_TREE, arg, arglist);
11696 fn = fn_fputs;
11699 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11700 else if (strcmp (fmt_str, target_percent_c) == 0)
11702 if (! arglist
11703 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11704 || TREE_CHAIN (arglist))
11705 return 0;
11706 arg = TREE_VALUE (arglist);
11707 arglist = build_tree_list (NULL_TREE, fp);
11708 arglist = tree_cons (NULL_TREE, arg, arglist);
11709 fn = fn_fputc;
11712 if (!fn)
11713 return 0;
11715 call = build_function_call_expr (fn, arglist);
11716 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11719 /* Initialize format string characters in the target charset. */
11721 static bool
11722 init_target_chars (void)
11724 static bool init;
11725 if (!init)
11727 target_newline = lang_hooks.to_target_charset ('\n');
11728 target_percent = lang_hooks.to_target_charset ('%');
11729 target_c = lang_hooks.to_target_charset ('c');
11730 target_s = lang_hooks.to_target_charset ('s');
11731 if (target_newline == 0 || target_percent == 0 || target_c == 0
11732 || target_s == 0)
11733 return false;
11735 target_percent_c[0] = target_percent;
11736 target_percent_c[1] = target_c;
11737 target_percent_c[2] = '\0';
11739 target_percent_s[0] = target_percent;
11740 target_percent_s[1] = target_s;
11741 target_percent_s[2] = '\0';
11743 target_percent_s_newline[0] = target_percent;
11744 target_percent_s_newline[1] = target_s;
11745 target_percent_s_newline[2] = target_newline;
11746 target_percent_s_newline[3] = '\0';
11748 init = true;
11750 return true;
11753 /* Helper function for do_mpfr_arg*(). Ensure M is a normal number
11754 and no overflow/underflow occurred. INEXACT is true if M was not
11755 exactly calculated. TYPE is the tree type for the result. This
11756 function assumes that you cleared the MPFR flags and then
11757 calculated M to see if anything subsequently set a flag prior to
11758 entering this function. Return NULL_TREE if any checks fail. */
11760 static tree
11761 do_mpfr_ckconv(mpfr_srcptr m, tree type, int inexact)
11763 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
11764 overflow/underflow occurred. If -frounding-math, proceed iff the
11765 result of calling FUNC was exact. */
11766 if (mpfr_number_p (m) && !mpfr_overflow_p() && !mpfr_underflow_p()
11767 && (!flag_rounding_math || !inexact))
11769 REAL_VALUE_TYPE rr;
11771 real_from_mpfr (&rr, m);
11772 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
11773 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
11774 but the mpft_t is not, then we underflowed in the
11775 conversion. */
11776 if (!real_isnan (&rr) && !real_isinf (&rr)
11777 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
11779 REAL_VALUE_TYPE rmode;
11781 real_convert (&rmode, TYPE_MODE (type), &rr);
11782 /* Proceed iff the specified mode can hold the value. */
11783 if (real_identical (&rmode, &rr))
11784 return build_real (type, rmode);
11787 return NULL_TREE;
11790 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
11791 FUNC on it and return the resulting value as a tree with type TYPE.
11792 If MIN and/or MAX are not NULL, then the supplied ARG must be
11793 within those bounds. If INCLUSIVE is true, then MIN/MAX are
11794 acceptable values, otherwise they are not. The mpfr precision is
11795 set to the precision of TYPE. We assume that function FUNC returns
11796 zero if the result could be calculated exactly within the requested
11797 precision. */
11799 static tree
11800 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
11801 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
11802 bool inclusive)
11804 tree result = NULL_TREE;
11806 STRIP_NOPS (arg);
11808 /* To proceed, MPFR must exactly represent the target floating point
11809 format, which only happens when the target base equals two. */
11810 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11811 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
11813 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11815 if (!real_isnan (ra) && !real_isinf (ra)
11816 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
11817 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
11819 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11820 int inexact;
11821 mpfr_t m;
11823 mpfr_init2 (m, prec);
11824 mpfr_from_real (m, ra);
11825 mpfr_clear_flags();
11826 inexact = func (m, m, GMP_RNDN);
11827 result = do_mpfr_ckconv (m, type, inexact);
11828 mpfr_clear (m);
11832 return result;
11835 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
11836 FUNC on it and return the resulting value as a tree with type TYPE.
11837 The mpfr precision is set to the precision of TYPE. We assume that
11838 function FUNC returns zero if the result could be calculated
11839 exactly within the requested precision. */
11841 static tree
11842 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
11843 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11845 tree result = NULL_TREE;
11847 STRIP_NOPS (arg1);
11848 STRIP_NOPS (arg2);
11850 /* To proceed, MPFR must exactly represent the target floating point
11851 format, which only happens when the target base equals two. */
11852 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11853 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
11854 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
11856 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11857 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11859 if (!real_isnan (ra1) && !real_isinf (ra1)
11860 && !real_isnan (ra2) && !real_isinf (ra2))
11862 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11863 int inexact;
11864 mpfr_t m1, m2;
11866 mpfr_inits2 (prec, m1, m2, NULL);
11867 mpfr_from_real (m1, ra1);
11868 mpfr_from_real (m2, ra2);
11869 mpfr_clear_flags();
11870 inexact = func (m1, m1, m2, GMP_RNDN);
11871 result = do_mpfr_ckconv (m1, type, inexact);
11872 mpfr_clears (m1, m2, NULL);
11876 return result;
11879 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
11880 FUNC on it and return the resulting value as a tree with type TYPE.
11881 The mpfr precision is set to the precision of TYPE. We assume that
11882 function FUNC returns zero if the result could be calculated
11883 exactly within the requested precision. */
11885 static tree
11886 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
11887 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11889 tree result = NULL_TREE;
11891 STRIP_NOPS (arg1);
11892 STRIP_NOPS (arg2);
11893 STRIP_NOPS (arg3);
11895 /* To proceed, MPFR must exactly represent the target floating point
11896 format, which only happens when the target base equals two. */
11897 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11898 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
11899 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
11900 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
11902 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11903 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11904 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
11906 if (!real_isnan (ra1) && !real_isinf (ra1)
11907 && !real_isnan (ra2) && !real_isinf (ra2)
11908 && !real_isnan (ra3) && !real_isinf (ra3))
11910 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11911 int inexact;
11912 mpfr_t m1, m2, m3;
11914 mpfr_inits2 (prec, m1, m2, m3, NULL);
11915 mpfr_from_real (m1, ra1);
11916 mpfr_from_real (m2, ra2);
11917 mpfr_from_real (m3, ra3);
11918 mpfr_clear_flags();
11919 inexact = func (m1, m1, m2, m3, GMP_RNDN);
11920 result = do_mpfr_ckconv (m1, type, inexact);
11921 mpfr_clears (m1, m2, m3, NULL);
11925 return result;
11928 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
11929 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
11930 If ARG_SINP and ARG_COSP are NULL then the result is returned
11931 as a complex value.
11932 The type is taken from the type of ARG and is used for setting the
11933 precision of the calculation and results. */
11935 static tree
11936 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
11938 tree const type = TREE_TYPE (arg);
11939 tree result = NULL_TREE;
11941 STRIP_NOPS (arg);
11943 /* To proceed, MPFR must exactly represent the target floating point
11944 format, which only happens when the target base equals two. */
11945 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11946 && TREE_CODE (arg) == REAL_CST
11947 && !TREE_OVERFLOW (arg))
11949 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11951 if (!real_isnan (ra) && !real_isinf (ra))
11953 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11954 tree result_s, result_c;
11955 int inexact;
11956 mpfr_t m, ms, mc;
11958 mpfr_inits2 (prec, m, ms, mc, NULL);
11959 mpfr_from_real (m, ra);
11960 mpfr_clear_flags();
11961 inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
11962 result_s = do_mpfr_ckconv (ms, type, inexact);
11963 result_c = do_mpfr_ckconv (mc, type, inexact);
11964 mpfr_clears (m, ms, mc, NULL);
11965 if (result_s && result_c)
11967 /* If we are to return in a complex value do so. */
11968 if (!arg_sinp && !arg_cosp)
11969 return build_complex (build_complex_type (type),
11970 result_c, result_s);
11972 /* Dereference the sin/cos pointer arguments. */
11973 arg_sinp = build_fold_indirect_ref (arg_sinp);
11974 arg_cosp = build_fold_indirect_ref (arg_cosp);
11975 /* Proceed if valid pointer type were passed in. */
11976 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
11977 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
11979 /* Set the values. */
11980 result_s = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_sinp,
11981 result_s);
11982 TREE_SIDE_EFFECTS (result_s) = 1;
11983 result_c = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_cosp,
11984 result_c);
11985 TREE_SIDE_EFFECTS (result_c) = 1;
11986 /* Combine the assignments into a compound expr. */
11987 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
11988 result_s, result_c));
11993 return result;