* expr.c (emit_block_move_via_movmem, emit_block_move_via_libcall): Add
[official-gcc.git] / gcc / builtins.c
blob7947907d3ecae1f89975e4df3e312f63adb6c015
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, -1, 0))
3704 goto do_libcall;
3706 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3707 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3708 return dest_mem;
3711 if (target_char_cast (val, &c))
3712 goto do_libcall;
3714 if (c)
3716 if (host_integerp (len, 1)
3717 && !(optimize_size && tree_low_cst (len, 1) > 1)
3718 && can_store_by_pieces (tree_low_cst (len, 1),
3719 builtin_memset_read_str, &c, dest_align))
3720 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3721 builtin_memset_read_str, &c, dest_align, 0);
3722 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3723 dest_align, expected_align,
3724 expected_size))
3725 goto do_libcall;
3727 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3728 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3729 return dest_mem;
3732 set_mem_align (dest_mem, dest_align);
3733 dest_addr = clear_storage_hints (dest_mem, len_rtx,
3734 CALL_EXPR_TAILCALL (orig_exp)
3735 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3736 expected_align, expected_size);
3738 if (dest_addr == 0)
3740 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3741 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3744 return dest_addr;
3746 do_libcall:
3747 fndecl = get_callee_fndecl (orig_exp);
3748 fcode = DECL_FUNCTION_CODE (fndecl);
3749 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3750 arglist = build_tree_list (NULL_TREE, len);
3751 if (fcode == BUILT_IN_MEMSET)
3752 arglist = tree_cons (NULL_TREE, val, arglist);
3753 arglist = tree_cons (NULL_TREE, dest, arglist);
3754 fn = build_function_call_expr (fndecl, arglist);
3755 if (TREE_CODE (fn) == CALL_EXPR)
3756 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3757 return expand_call (fn, target, target == const0_rtx);
3761 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3762 if we failed the caller should emit a normal call. */
3764 static rtx
3765 expand_builtin_bzero (tree exp)
3767 tree arglist = TREE_OPERAND (exp, 1);
3768 tree dest, size, newarglist;
3770 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3771 return NULL_RTX;
3773 dest = TREE_VALUE (arglist);
3774 size = TREE_VALUE (TREE_CHAIN (arglist));
3776 /* New argument list transforming bzero(ptr x, int y) to
3777 memset(ptr x, int 0, size_t y). This is done this way
3778 so that if it isn't expanded inline, we fallback to
3779 calling bzero instead of memset. */
3781 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3782 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3783 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3785 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3788 /* Expand expression EXP, which is a call to the memcmp built-in function.
3789 ARGLIST is the argument list for this call. Return 0 if we failed and the
3790 caller should emit a normal call, otherwise try to get the result in
3791 TARGET, if convenient (and in mode MODE, if that's convenient). */
3793 static rtx
3794 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3795 enum machine_mode mode)
3797 if (!validate_arglist (arglist,
3798 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3799 return 0;
3800 else
3802 tree result = fold_builtin_memcmp (arglist);
3803 if (result)
3804 return expand_expr (result, target, mode, EXPAND_NORMAL);
3807 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3809 tree arg1 = TREE_VALUE (arglist);
3810 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3811 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3812 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3813 rtx result;
3814 rtx insn;
3816 int arg1_align
3817 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3818 int arg2_align
3819 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3820 enum machine_mode insn_mode;
3822 #ifdef HAVE_cmpmemsi
3823 if (HAVE_cmpmemsi)
3824 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3825 else
3826 #endif
3827 #ifdef HAVE_cmpstrnsi
3828 if (HAVE_cmpstrnsi)
3829 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3830 else
3831 #endif
3832 return 0;
3834 /* If we don't have POINTER_TYPE, call the function. */
3835 if (arg1_align == 0 || arg2_align == 0)
3836 return 0;
3838 /* Make a place to write the result of the instruction. */
3839 result = target;
3840 if (! (result != 0
3841 && REG_P (result) && GET_MODE (result) == insn_mode
3842 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3843 result = gen_reg_rtx (insn_mode);
3845 arg1_rtx = get_memory_rtx (arg1, len);
3846 arg2_rtx = get_memory_rtx (arg2, len);
3847 arg3_rtx = expand_normal (len);
3849 /* Set MEM_SIZE as appropriate. */
3850 if (GET_CODE (arg3_rtx) == CONST_INT)
3852 set_mem_size (arg1_rtx, arg3_rtx);
3853 set_mem_size (arg2_rtx, arg3_rtx);
3856 #ifdef HAVE_cmpmemsi
3857 if (HAVE_cmpmemsi)
3858 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3859 GEN_INT (MIN (arg1_align, arg2_align)));
3860 else
3861 #endif
3862 #ifdef HAVE_cmpstrnsi
3863 if (HAVE_cmpstrnsi)
3864 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3865 GEN_INT (MIN (arg1_align, arg2_align)));
3866 else
3867 #endif
3868 gcc_unreachable ();
3870 if (insn)
3871 emit_insn (insn);
3872 else
3873 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3874 TYPE_MODE (integer_type_node), 3,
3875 XEXP (arg1_rtx, 0), Pmode,
3876 XEXP (arg2_rtx, 0), Pmode,
3877 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3878 TYPE_UNSIGNED (sizetype)),
3879 TYPE_MODE (sizetype));
3881 /* Return the value in the proper mode for this function. */
3882 mode = TYPE_MODE (TREE_TYPE (exp));
3883 if (GET_MODE (result) == mode)
3884 return result;
3885 else if (target != 0)
3887 convert_move (target, result, 0);
3888 return target;
3890 else
3891 return convert_to_mode (mode, result, 0);
3893 #endif
3895 return 0;
3898 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3899 if we failed the caller should emit a normal call, otherwise try to get
3900 the result in TARGET, if convenient. */
3902 static rtx
3903 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3905 tree arglist = TREE_OPERAND (exp, 1);
3907 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3908 return 0;
3909 else
3911 tree result = fold_builtin_strcmp (arglist);
3912 if (result)
3913 return expand_expr (result, target, mode, EXPAND_NORMAL);
3916 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3917 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3918 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3920 rtx arg1_rtx, arg2_rtx;
3921 rtx result, insn = NULL_RTX;
3922 tree fndecl, fn;
3924 tree arg1 = TREE_VALUE (arglist);
3925 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3926 int arg1_align
3927 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3928 int arg2_align
3929 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3931 /* If we don't have POINTER_TYPE, call the function. */
3932 if (arg1_align == 0 || arg2_align == 0)
3933 return 0;
3935 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3936 arg1 = builtin_save_expr (arg1);
3937 arg2 = builtin_save_expr (arg2);
3939 arg1_rtx = get_memory_rtx (arg1, NULL);
3940 arg2_rtx = get_memory_rtx (arg2, NULL);
3942 #ifdef HAVE_cmpstrsi
3943 /* Try to call cmpstrsi. */
3944 if (HAVE_cmpstrsi)
3946 enum machine_mode insn_mode
3947 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3949 /* Make a place to write the result of the instruction. */
3950 result = target;
3951 if (! (result != 0
3952 && REG_P (result) && GET_MODE (result) == insn_mode
3953 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3954 result = gen_reg_rtx (insn_mode);
3956 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3957 GEN_INT (MIN (arg1_align, arg2_align)));
3959 #endif
3960 #ifdef HAVE_cmpstrnsi
3961 /* Try to determine at least one length and call cmpstrnsi. */
3962 if (!insn && HAVE_cmpstrnsi)
3964 tree len;
3965 rtx arg3_rtx;
3967 enum machine_mode insn_mode
3968 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3969 tree len1 = c_strlen (arg1, 1);
3970 tree len2 = c_strlen (arg2, 1);
3972 if (len1)
3973 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3974 if (len2)
3975 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3977 /* If we don't have a constant length for the first, use the length
3978 of the second, if we know it. We don't require a constant for
3979 this case; some cost analysis could be done if both are available
3980 but neither is constant. For now, assume they're equally cheap,
3981 unless one has side effects. If both strings have constant lengths,
3982 use the smaller. */
3984 if (!len1)
3985 len = len2;
3986 else if (!len2)
3987 len = len1;
3988 else if (TREE_SIDE_EFFECTS (len1))
3989 len = len2;
3990 else if (TREE_SIDE_EFFECTS (len2))
3991 len = len1;
3992 else if (TREE_CODE (len1) != INTEGER_CST)
3993 len = len2;
3994 else if (TREE_CODE (len2) != INTEGER_CST)
3995 len = len1;
3996 else if (tree_int_cst_lt (len1, len2))
3997 len = len1;
3998 else
3999 len = len2;
4001 /* If both arguments have side effects, we cannot optimize. */
4002 if (!len || TREE_SIDE_EFFECTS (len))
4003 goto do_libcall;
4005 arg3_rtx = expand_normal (len);
4007 /* Make a place to write the result of the instruction. */
4008 result = target;
4009 if (! (result != 0
4010 && REG_P (result) && GET_MODE (result) == insn_mode
4011 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4012 result = gen_reg_rtx (insn_mode);
4014 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4015 GEN_INT (MIN (arg1_align, arg2_align)));
4017 #endif
4019 if (insn)
4021 emit_insn (insn);
4023 /* Return the value in the proper mode for this function. */
4024 mode = TYPE_MODE (TREE_TYPE (exp));
4025 if (GET_MODE (result) == mode)
4026 return result;
4027 if (target == 0)
4028 return convert_to_mode (mode, result, 0);
4029 convert_move (target, result, 0);
4030 return target;
4033 /* Expand the library call ourselves using a stabilized argument
4034 list to avoid re-evaluating the function's arguments twice. */
4035 #ifdef HAVE_cmpstrnsi
4036 do_libcall:
4037 #endif
4038 arglist = build_tree_list (NULL_TREE, arg2);
4039 arglist = tree_cons (NULL_TREE, arg1, arglist);
4040 fndecl = get_callee_fndecl (exp);
4041 fn = build_function_call_expr (fndecl, arglist);
4042 if (TREE_CODE (fn) == CALL_EXPR)
4043 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4044 return expand_call (fn, target, target == const0_rtx);
4046 #endif
4047 return 0;
4050 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
4051 if we failed the caller should emit a normal call, otherwise try to get
4052 the result in TARGET, if convenient. */
4054 static rtx
4055 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
4057 tree arglist = TREE_OPERAND (exp, 1);
4059 if (!validate_arglist (arglist,
4060 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4061 return 0;
4062 else
4064 tree result = fold_builtin_strncmp (arglist);
4065 if (result)
4066 return expand_expr (result, target, mode, EXPAND_NORMAL);
4069 /* If c_strlen can determine an expression for one of the string
4070 lengths, and it doesn't have side effects, then emit cmpstrnsi
4071 using length MIN(strlen(string)+1, arg3). */
4072 #ifdef HAVE_cmpstrnsi
4073 if (HAVE_cmpstrnsi)
4075 tree arg1 = TREE_VALUE (arglist);
4076 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
4077 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4078 tree len, len1, len2;
4079 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4080 rtx result, insn;
4081 tree fndecl, fn;
4083 int arg1_align
4084 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4085 int arg2_align
4086 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4087 enum machine_mode insn_mode
4088 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4090 len1 = c_strlen (arg1, 1);
4091 len2 = c_strlen (arg2, 1);
4093 if (len1)
4094 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4095 if (len2)
4096 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4098 /* If we don't have a constant length for the first, use the length
4099 of the second, if we know it. We don't require a constant for
4100 this case; some cost analysis could be done if both are available
4101 but neither is constant. For now, assume they're equally cheap,
4102 unless one has side effects. If both strings have constant lengths,
4103 use the smaller. */
4105 if (!len1)
4106 len = len2;
4107 else if (!len2)
4108 len = len1;
4109 else if (TREE_SIDE_EFFECTS (len1))
4110 len = len2;
4111 else if (TREE_SIDE_EFFECTS (len2))
4112 len = len1;
4113 else if (TREE_CODE (len1) != INTEGER_CST)
4114 len = len2;
4115 else if (TREE_CODE (len2) != INTEGER_CST)
4116 len = len1;
4117 else if (tree_int_cst_lt (len1, len2))
4118 len = len1;
4119 else
4120 len = len2;
4122 /* If both arguments have side effects, we cannot optimize. */
4123 if (!len || TREE_SIDE_EFFECTS (len))
4124 return 0;
4126 /* The actual new length parameter is MIN(len,arg3). */
4127 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
4128 fold_convert (TREE_TYPE (len), arg3));
4130 /* If we don't have POINTER_TYPE, call the function. */
4131 if (arg1_align == 0 || arg2_align == 0)
4132 return 0;
4134 /* Make a place to write the result of the instruction. */
4135 result = target;
4136 if (! (result != 0
4137 && REG_P (result) && GET_MODE (result) == insn_mode
4138 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4139 result = gen_reg_rtx (insn_mode);
4141 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4142 arg1 = builtin_save_expr (arg1);
4143 arg2 = builtin_save_expr (arg2);
4144 len = builtin_save_expr (len);
4146 arg1_rtx = get_memory_rtx (arg1, len);
4147 arg2_rtx = get_memory_rtx (arg2, len);
4148 arg3_rtx = expand_normal (len);
4149 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4150 GEN_INT (MIN (arg1_align, arg2_align)));
4151 if (insn)
4153 emit_insn (insn);
4155 /* Return the value in the proper mode for this function. */
4156 mode = TYPE_MODE (TREE_TYPE (exp));
4157 if (GET_MODE (result) == mode)
4158 return result;
4159 if (target == 0)
4160 return convert_to_mode (mode, result, 0);
4161 convert_move (target, result, 0);
4162 return target;
4165 /* Expand the library call ourselves using a stabilized argument
4166 list to avoid re-evaluating the function's arguments twice. */
4167 arglist = build_tree_list (NULL_TREE, len);
4168 arglist = tree_cons (NULL_TREE, arg2, arglist);
4169 arglist = tree_cons (NULL_TREE, arg1, arglist);
4170 fndecl = get_callee_fndecl (exp);
4171 fn = build_function_call_expr (fndecl, arglist);
4172 if (TREE_CODE (fn) == CALL_EXPR)
4173 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4174 return expand_call (fn, target, target == const0_rtx);
4176 #endif
4177 return 0;
4180 /* Expand expression EXP, which is a call to the strcat builtin.
4181 Return 0 if we failed the caller should emit a normal call,
4182 otherwise try to get the result in TARGET, if convenient. */
4184 static rtx
4185 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
4187 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4188 return 0;
4189 else
4191 tree dst = TREE_VALUE (arglist),
4192 src = TREE_VALUE (TREE_CHAIN (arglist));
4193 const char *p = c_getstr (src);
4195 /* If the string length is zero, return the dst parameter. */
4196 if (p && *p == '\0')
4197 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4199 if (!optimize_size)
4201 /* See if we can store by pieces into (dst + strlen(dst)). */
4202 tree newsrc, newdst,
4203 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4204 rtx insns;
4206 /* Stabilize the argument list. */
4207 newsrc = builtin_save_expr (src);
4208 if (newsrc != src)
4209 arglist = build_tree_list (NULL_TREE, newsrc);
4210 else
4211 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
4213 dst = builtin_save_expr (dst);
4215 start_sequence ();
4217 /* Create strlen (dst). */
4218 newdst =
4219 build_function_call_expr (strlen_fn,
4220 build_tree_list (NULL_TREE, dst));
4221 /* Create (dst + (cast) strlen (dst)). */
4222 newdst = fold_convert (TREE_TYPE (dst), newdst);
4223 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4225 newdst = builtin_save_expr (newdst);
4226 arglist = tree_cons (NULL_TREE, newdst, arglist);
4228 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
4230 end_sequence (); /* Stop sequence. */
4231 return 0;
4234 /* Output the entire sequence. */
4235 insns = get_insns ();
4236 end_sequence ();
4237 emit_insn (insns);
4239 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4242 return 0;
4246 /* Expand expression EXP, which is a call to the strncat builtin.
4247 Return 0 if we failed the caller should emit a normal call,
4248 otherwise try to get the result in TARGET, if convenient. */
4250 static rtx
4251 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4253 if (validate_arglist (arglist,
4254 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4256 tree result = fold_builtin_strncat (arglist);
4257 if (result)
4258 return expand_expr (result, target, mode, EXPAND_NORMAL);
4260 return 0;
4263 /* Expand expression EXP, which is a call to the strspn builtin.
4264 Return 0 if we failed the caller should emit a normal call,
4265 otherwise try to get the result in TARGET, if convenient. */
4267 static rtx
4268 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4270 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4272 tree result = fold_builtin_strspn (arglist);
4273 if (result)
4274 return expand_expr (result, target, mode, EXPAND_NORMAL);
4276 return 0;
4279 /* Expand expression EXP, which is a call to the strcspn builtin.
4280 Return 0 if we failed the caller should emit a normal call,
4281 otherwise try to get the result in TARGET, if convenient. */
4283 static rtx
4284 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4286 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4288 tree result = fold_builtin_strcspn (arglist);
4289 if (result)
4290 return expand_expr (result, target, mode, EXPAND_NORMAL);
4292 return 0;
4295 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4296 if that's convenient. */
4299 expand_builtin_saveregs (void)
4301 rtx val, seq;
4303 /* Don't do __builtin_saveregs more than once in a function.
4304 Save the result of the first call and reuse it. */
4305 if (saveregs_value != 0)
4306 return saveregs_value;
4308 /* When this function is called, it means that registers must be
4309 saved on entry to this function. So we migrate the call to the
4310 first insn of this function. */
4312 start_sequence ();
4314 /* Do whatever the machine needs done in this case. */
4315 val = targetm.calls.expand_builtin_saveregs ();
4317 seq = get_insns ();
4318 end_sequence ();
4320 saveregs_value = val;
4322 /* Put the insns after the NOTE that starts the function. If this
4323 is inside a start_sequence, make the outer-level insn chain current, so
4324 the code is placed at the start of the function. */
4325 push_topmost_sequence ();
4326 emit_insn_after (seq, entry_of_function ());
4327 pop_topmost_sequence ();
4329 return val;
4332 /* __builtin_args_info (N) returns word N of the arg space info
4333 for the current function. The number and meanings of words
4334 is controlled by the definition of CUMULATIVE_ARGS. */
4336 static rtx
4337 expand_builtin_args_info (tree arglist)
4339 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4340 int *word_ptr = (int *) &current_function_args_info;
4342 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4344 if (arglist != 0)
4346 if (!host_integerp (TREE_VALUE (arglist), 0))
4347 error ("argument of %<__builtin_args_info%> must be constant");
4348 else
4350 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4352 if (wordnum < 0 || wordnum >= nwords)
4353 error ("argument of %<__builtin_args_info%> out of range");
4354 else
4355 return GEN_INT (word_ptr[wordnum]);
4358 else
4359 error ("missing argument in %<__builtin_args_info%>");
4361 return const0_rtx;
4364 /* Expand a call to __builtin_next_arg. */
4366 static rtx
4367 expand_builtin_next_arg (void)
4369 /* Checking arguments is already done in fold_builtin_next_arg
4370 that must be called before this function. */
4371 return expand_binop (Pmode, add_optab,
4372 current_function_internal_arg_pointer,
4373 current_function_arg_offset_rtx,
4374 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4377 /* Make it easier for the backends by protecting the valist argument
4378 from multiple evaluations. */
4380 static tree
4381 stabilize_va_list (tree valist, int needs_lvalue)
4383 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4385 if (TREE_SIDE_EFFECTS (valist))
4386 valist = save_expr (valist);
4388 /* For this case, the backends will be expecting a pointer to
4389 TREE_TYPE (va_list_type_node), but it's possible we've
4390 actually been given an array (an actual va_list_type_node).
4391 So fix it. */
4392 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4394 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4395 valist = build_fold_addr_expr_with_type (valist, p1);
4398 else
4400 tree pt;
4402 if (! needs_lvalue)
4404 if (! TREE_SIDE_EFFECTS (valist))
4405 return valist;
4407 pt = build_pointer_type (va_list_type_node);
4408 valist = fold_build1 (ADDR_EXPR, pt, valist);
4409 TREE_SIDE_EFFECTS (valist) = 1;
4412 if (TREE_SIDE_EFFECTS (valist))
4413 valist = save_expr (valist);
4414 valist = build_fold_indirect_ref (valist);
4417 return valist;
4420 /* The "standard" definition of va_list is void*. */
4422 tree
4423 std_build_builtin_va_list (void)
4425 return ptr_type_node;
4428 /* The "standard" implementation of va_start: just assign `nextarg' to
4429 the variable. */
4431 void
4432 std_expand_builtin_va_start (tree valist, rtx nextarg)
4434 tree t;
4436 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist,
4437 make_tree (ptr_type_node, nextarg));
4438 TREE_SIDE_EFFECTS (t) = 1;
4440 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4443 /* Expand ARGLIST, from a call to __builtin_va_start. */
4445 static rtx
4446 expand_builtin_va_start (tree arglist)
4448 rtx nextarg;
4449 tree chain, valist;
4451 chain = TREE_CHAIN (arglist);
4453 if (!chain)
4455 error ("too few arguments to function %<va_start%>");
4456 return const0_rtx;
4459 if (fold_builtin_next_arg (chain))
4460 return const0_rtx;
4462 nextarg = expand_builtin_next_arg ();
4463 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4465 #ifdef EXPAND_BUILTIN_VA_START
4466 EXPAND_BUILTIN_VA_START (valist, nextarg);
4467 #else
4468 std_expand_builtin_va_start (valist, nextarg);
4469 #endif
4471 return const0_rtx;
4474 /* The "standard" implementation of va_arg: read the value from the
4475 current (padded) address and increment by the (padded) size. */
4477 tree
4478 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4480 tree addr, t, type_size, rounded_size, valist_tmp;
4481 unsigned HOST_WIDE_INT align, boundary;
4482 bool indirect;
4484 #ifdef ARGS_GROW_DOWNWARD
4485 /* All of the alignment and movement below is for args-grow-up machines.
4486 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4487 implement their own specialized gimplify_va_arg_expr routines. */
4488 gcc_unreachable ();
4489 #endif
4491 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4492 if (indirect)
4493 type = build_pointer_type (type);
4495 align = PARM_BOUNDARY / BITS_PER_UNIT;
4496 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4498 /* Hoist the valist value into a temporary for the moment. */
4499 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4501 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4502 requires greater alignment, we must perform dynamic alignment. */
4503 if (boundary > align
4504 && !integer_zerop (TYPE_SIZE (type)))
4506 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4507 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist_tmp,
4508 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4509 gimplify_and_add (t, pre_p);
4511 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4512 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist_tmp,
4513 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4514 gimplify_and_add (t, pre_p);
4516 else
4517 boundary = align;
4519 /* If the actual alignment is less than the alignment of the type,
4520 adjust the type accordingly so that we don't assume strict alignment
4521 when deferencing the pointer. */
4522 boundary *= BITS_PER_UNIT;
4523 if (boundary < TYPE_ALIGN (type))
4525 type = build_variant_type_copy (type);
4526 TYPE_ALIGN (type) = boundary;
4529 /* Compute the rounded size of the type. */
4530 type_size = size_in_bytes (type);
4531 rounded_size = round_up (type_size, align);
4533 /* Reduce rounded_size so it's sharable with the postqueue. */
4534 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4536 /* Get AP. */
4537 addr = valist_tmp;
4538 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4540 /* Small args are padded downward. */
4541 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4542 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4543 size_binop (MINUS_EXPR, rounded_size, type_size));
4544 t = fold_convert (TREE_TYPE (addr), t);
4545 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4548 /* Compute new value for AP. */
4549 t = fold_convert (TREE_TYPE (valist), rounded_size);
4550 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4551 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist, t);
4552 gimplify_and_add (t, pre_p);
4554 addr = fold_convert (build_pointer_type (type), addr);
4556 if (indirect)
4557 addr = build_va_arg_indirect_ref (addr);
4559 return build_va_arg_indirect_ref (addr);
4562 /* Build an indirect-ref expression over the given TREE, which represents a
4563 piece of a va_arg() expansion. */
4564 tree
4565 build_va_arg_indirect_ref (tree addr)
4567 addr = build_fold_indirect_ref (addr);
4569 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4570 mf_mark (addr);
4572 return addr;
4575 /* Return a dummy expression of type TYPE in order to keep going after an
4576 error. */
4578 static tree
4579 dummy_object (tree type)
4581 tree t = build_int_cst (build_pointer_type (type), 0);
4582 return build1 (INDIRECT_REF, type, t);
4585 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4586 builtin function, but a very special sort of operator. */
4588 enum gimplify_status
4589 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4591 tree promoted_type, want_va_type, have_va_type;
4592 tree valist = TREE_OPERAND (*expr_p, 0);
4593 tree type = TREE_TYPE (*expr_p);
4594 tree t;
4596 /* Verify that valist is of the proper type. */
4597 want_va_type = va_list_type_node;
4598 have_va_type = TREE_TYPE (valist);
4600 if (have_va_type == error_mark_node)
4601 return GS_ERROR;
4603 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4605 /* If va_list is an array type, the argument may have decayed
4606 to a pointer type, e.g. by being passed to another function.
4607 In that case, unwrap both types so that we can compare the
4608 underlying records. */
4609 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4610 || POINTER_TYPE_P (have_va_type))
4612 want_va_type = TREE_TYPE (want_va_type);
4613 have_va_type = TREE_TYPE (have_va_type);
4617 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4619 error ("first argument to %<va_arg%> not of type %<va_list%>");
4620 return GS_ERROR;
4623 /* Generate a diagnostic for requesting data of a type that cannot
4624 be passed through `...' due to type promotion at the call site. */
4625 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4626 != type)
4628 static bool gave_help;
4630 /* Unfortunately, this is merely undefined, rather than a constraint
4631 violation, so we cannot make this an error. If this call is never
4632 executed, the program is still strictly conforming. */
4633 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4634 type, promoted_type);
4635 if (! gave_help)
4637 gave_help = true;
4638 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4639 promoted_type, type);
4642 /* We can, however, treat "undefined" any way we please.
4643 Call abort to encourage the user to fix the program. */
4644 inform ("if this code is reached, the program will abort");
4645 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4646 NULL);
4647 append_to_statement_list (t, pre_p);
4649 /* This is dead code, but go ahead and finish so that the
4650 mode of the result comes out right. */
4651 *expr_p = dummy_object (type);
4652 return GS_ALL_DONE;
4654 else
4656 /* Make it easier for the backends by protecting the valist argument
4657 from multiple evaluations. */
4658 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4660 /* For this case, the backends will be expecting a pointer to
4661 TREE_TYPE (va_list_type_node), but it's possible we've
4662 actually been given an array (an actual va_list_type_node).
4663 So fix it. */
4664 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4666 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4667 valist = build_fold_addr_expr_with_type (valist, p1);
4669 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4671 else
4672 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4674 if (!targetm.gimplify_va_arg_expr)
4675 /* FIXME:Once most targets are converted we should merely
4676 assert this is non-null. */
4677 return GS_ALL_DONE;
4679 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4680 return GS_OK;
4684 /* Expand ARGLIST, from a call to __builtin_va_end. */
4686 static rtx
4687 expand_builtin_va_end (tree arglist)
4689 tree valist = TREE_VALUE (arglist);
4691 /* Evaluate for side effects, if needed. I hate macros that don't
4692 do that. */
4693 if (TREE_SIDE_EFFECTS (valist))
4694 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4696 return const0_rtx;
4699 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4700 builtin rather than just as an assignment in stdarg.h because of the
4701 nastiness of array-type va_list types. */
4703 static rtx
4704 expand_builtin_va_copy (tree arglist)
4706 tree dst, src, t;
4708 dst = TREE_VALUE (arglist);
4709 src = TREE_VALUE (TREE_CHAIN (arglist));
4711 dst = stabilize_va_list (dst, 1);
4712 src = stabilize_va_list (src, 0);
4714 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4716 t = build2 (GIMPLE_MODIFY_STMT, va_list_type_node, dst, src);
4717 TREE_SIDE_EFFECTS (t) = 1;
4718 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4720 else
4722 rtx dstb, srcb, size;
4724 /* Evaluate to pointers. */
4725 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4726 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4727 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4728 VOIDmode, EXPAND_NORMAL);
4730 dstb = convert_memory_address (Pmode, dstb);
4731 srcb = convert_memory_address (Pmode, srcb);
4733 /* "Dereference" to BLKmode memories. */
4734 dstb = gen_rtx_MEM (BLKmode, dstb);
4735 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4736 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4737 srcb = gen_rtx_MEM (BLKmode, srcb);
4738 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4739 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4741 /* Copy. */
4742 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4745 return const0_rtx;
4748 /* Expand a call to one of the builtin functions __builtin_frame_address or
4749 __builtin_return_address. */
4751 static rtx
4752 expand_builtin_frame_address (tree fndecl, tree arglist)
4754 /* The argument must be a nonnegative integer constant.
4755 It counts the number of frames to scan up the stack.
4756 The value is the return address saved in that frame. */
4757 if (arglist == 0)
4758 /* Warning about missing arg was already issued. */
4759 return const0_rtx;
4760 else if (! host_integerp (TREE_VALUE (arglist), 1))
4762 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4763 error ("invalid argument to %<__builtin_frame_address%>");
4764 else
4765 error ("invalid argument to %<__builtin_return_address%>");
4766 return const0_rtx;
4768 else
4770 rtx tem
4771 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4772 tree_low_cst (TREE_VALUE (arglist), 1));
4774 /* Some ports cannot access arbitrary stack frames. */
4775 if (tem == NULL)
4777 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4778 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4779 else
4780 warning (0, "unsupported argument to %<__builtin_return_address%>");
4781 return const0_rtx;
4784 /* For __builtin_frame_address, return what we've got. */
4785 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4786 return tem;
4788 if (!REG_P (tem)
4789 && ! CONSTANT_P (tem))
4790 tem = copy_to_mode_reg (Pmode, tem);
4791 return tem;
4795 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4796 we failed and the caller should emit a normal call, otherwise try to get
4797 the result in TARGET, if convenient. */
4799 static rtx
4800 expand_builtin_alloca (tree arglist, rtx target)
4802 rtx op0;
4803 rtx result;
4805 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4806 should always expand to function calls. These can be intercepted
4807 in libmudflap. */
4808 if (flag_mudflap)
4809 return 0;
4811 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4812 return 0;
4814 /* Compute the argument. */
4815 op0 = expand_normal (TREE_VALUE (arglist));
4817 /* Allocate the desired space. */
4818 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4819 result = convert_memory_address (ptr_mode, result);
4821 return result;
4824 /* Expand a call to a bswap builtin. The arguments are in ARGLIST. MODE
4825 is the mode to expand with. */
4827 static rtx
4828 expand_builtin_bswap (tree arglist, rtx target, rtx subtarget)
4830 enum machine_mode mode;
4831 tree arg;
4832 rtx op0;
4834 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4835 return 0;
4837 arg = TREE_VALUE (arglist);
4838 mode = TYPE_MODE (TREE_TYPE (arg));
4839 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4841 target = expand_unop (mode, bswap_optab, op0, target, 1);
4843 gcc_assert (target);
4845 return convert_to_mode (mode, target, 0);
4848 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4849 Return 0 if a normal call should be emitted rather than expanding the
4850 function in-line. If convenient, the result should be placed in TARGET.
4851 SUBTARGET may be used as the target for computing one of EXP's operands. */
4853 static rtx
4854 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4855 rtx subtarget, optab op_optab)
4857 rtx op0;
4858 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4859 return 0;
4861 /* Compute the argument. */
4862 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4863 /* Compute op, into TARGET if possible.
4864 Set TARGET to wherever the result comes back. */
4865 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4866 op_optab, op0, target, 1);
4867 gcc_assert (target);
4869 return convert_to_mode (target_mode, target, 0);
4872 /* If the string passed to fputs is a constant and is one character
4873 long, we attempt to transform this call into __builtin_fputc(). */
4875 static rtx
4876 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4878 /* Verify the arguments in the original call. */
4879 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4881 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4882 unlocked, NULL_TREE);
4883 if (result)
4884 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4886 return 0;
4889 /* Expand a call to __builtin_expect. We just return our argument
4890 as the builtin_expect semantic should've been already executed by
4891 tree branch prediction pass. */
4893 static rtx
4894 expand_builtin_expect (tree arglist, rtx target)
4896 tree exp, c;
4898 if (arglist == NULL_TREE
4899 || TREE_CHAIN (arglist) == NULL_TREE)
4900 return const0_rtx;
4901 exp = TREE_VALUE (arglist);
4902 c = TREE_VALUE (TREE_CHAIN (arglist));
4904 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4905 /* When guessing was done, the hints should be already stripped away. */
4906 gcc_assert (!flag_guess_branch_prob);
4907 return target;
4910 void
4911 expand_builtin_trap (void)
4913 #ifdef HAVE_trap
4914 if (HAVE_trap)
4915 emit_insn (gen_trap ());
4916 else
4917 #endif
4918 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4919 emit_barrier ();
4922 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4923 Return 0 if a normal call should be emitted rather than expanding
4924 the function inline. If convenient, the result should be placed
4925 in TARGET. SUBTARGET may be used as the target for computing
4926 the operand. */
4928 static rtx
4929 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4931 enum machine_mode mode;
4932 tree arg;
4933 rtx op0;
4935 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4936 return 0;
4938 arg = TREE_VALUE (arglist);
4939 mode = TYPE_MODE (TREE_TYPE (arg));
4940 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4941 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4944 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4945 Return NULL is a normal call should be emitted rather than expanding the
4946 function inline. If convenient, the result should be placed in TARGET.
4947 SUBTARGET may be used as the target for computing the operand. */
4949 static rtx
4950 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4952 rtx op0, op1;
4953 tree arg;
4955 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4956 return 0;
4958 arg = TREE_VALUE (arglist);
4959 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4961 arg = TREE_VALUE (TREE_CHAIN (arglist));
4962 op1 = expand_normal (arg);
4964 return expand_copysign (op0, op1, target);
4967 /* Create a new constant string literal and return a char* pointer to it.
4968 The STRING_CST value is the LEN characters at STR. */
4969 tree
4970 build_string_literal (int len, const char *str)
4972 tree t, elem, index, type;
4974 t = build_string (len, str);
4975 elem = build_type_variant (char_type_node, 1, 0);
4976 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4977 type = build_array_type (elem, index);
4978 TREE_TYPE (t) = type;
4979 TREE_CONSTANT (t) = 1;
4980 TREE_INVARIANT (t) = 1;
4981 TREE_READONLY (t) = 1;
4982 TREE_STATIC (t) = 1;
4984 type = build_pointer_type (type);
4985 t = build1 (ADDR_EXPR, type, t);
4987 type = build_pointer_type (elem);
4988 t = build1 (NOP_EXPR, type, t);
4989 return t;
4992 /* Expand EXP, a call to printf or printf_unlocked.
4993 Return 0 if a normal call should be emitted rather than transforming
4994 the function inline. If convenient, the result should be placed in
4995 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4996 call. */
4997 static rtx
4998 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4999 bool unlocked)
5001 tree arglist = TREE_OPERAND (exp, 1);
5002 /* If we're using an unlocked function, assume the other unlocked
5003 functions exist explicitly. */
5004 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5005 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5006 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5007 : implicit_built_in_decls[BUILT_IN_PUTS];
5008 const char *fmt_str;
5009 tree fn, fmt, arg;
5011 /* If the return value is used, don't do the transformation. */
5012 if (target != const0_rtx)
5013 return 0;
5015 /* Verify the required arguments in the original call. */
5016 if (! arglist)
5017 return 0;
5018 fmt = TREE_VALUE (arglist);
5019 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5020 return 0;
5021 arglist = TREE_CHAIN (arglist);
5023 /* Check whether the format is a literal string constant. */
5024 fmt_str = c_getstr (fmt);
5025 if (fmt_str == NULL)
5026 return 0;
5028 if (!init_target_chars())
5029 return 0;
5031 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
5032 if (strcmp (fmt_str, target_percent_s_newline) == 0)
5034 if (! arglist
5035 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5036 || TREE_CHAIN (arglist))
5037 return 0;
5038 fn = fn_puts;
5040 /* If the format specifier was "%c", call __builtin_putchar(arg). */
5041 else if (strcmp (fmt_str, target_percent_c) == 0)
5043 if (! arglist
5044 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5045 || TREE_CHAIN (arglist))
5046 return 0;
5047 fn = fn_putchar;
5049 else
5051 /* We can't handle anything else with % args or %% ... yet. */
5052 if (strchr (fmt_str, target_percent))
5053 return 0;
5055 if (arglist)
5056 return 0;
5058 /* If the format specifier was "", printf does nothing. */
5059 if (fmt_str[0] == '\0')
5060 return const0_rtx;
5061 /* If the format specifier has length of 1, call putchar. */
5062 if (fmt_str[1] == '\0')
5064 /* Given printf("c"), (where c is any one character,)
5065 convert "c"[0] to an int and pass that to the replacement
5066 function. */
5067 arg = build_int_cst (NULL_TREE, fmt_str[0]);
5068 arglist = build_tree_list (NULL_TREE, arg);
5069 fn = fn_putchar;
5071 else
5073 /* If the format specifier was "string\n", call puts("string"). */
5074 size_t len = strlen (fmt_str);
5075 if ((unsigned char)fmt_str[len - 1] == target_newline)
5077 /* Create a NUL-terminated string that's one char shorter
5078 than the original, stripping off the trailing '\n'. */
5079 char *newstr = alloca (len);
5080 memcpy (newstr, fmt_str, len - 1);
5081 newstr[len - 1] = 0;
5083 arg = build_string_literal (len, newstr);
5084 arglist = build_tree_list (NULL_TREE, arg);
5085 fn = fn_puts;
5087 else
5088 /* We'd like to arrange to call fputs(string,stdout) here,
5089 but we need stdout and don't have a way to get it yet. */
5090 return 0;
5094 if (!fn)
5095 return 0;
5096 fn = build_function_call_expr (fn, arglist);
5097 if (TREE_CODE (fn) == CALL_EXPR)
5098 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5099 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5102 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5103 Return 0 if a normal call should be emitted rather than transforming
5104 the function inline. If convenient, the result should be placed in
5105 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5106 call. */
5107 static rtx
5108 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5109 bool unlocked)
5111 tree arglist = TREE_OPERAND (exp, 1);
5112 /* If we're using an unlocked function, assume the other unlocked
5113 functions exist explicitly. */
5114 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5115 : implicit_built_in_decls[BUILT_IN_FPUTC];
5116 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5117 : implicit_built_in_decls[BUILT_IN_FPUTS];
5118 const char *fmt_str;
5119 tree fn, fmt, fp, arg;
5121 /* If the return value is used, don't do the transformation. */
5122 if (target != const0_rtx)
5123 return 0;
5125 /* Verify the required arguments in the original call. */
5126 if (! arglist)
5127 return 0;
5128 fp = TREE_VALUE (arglist);
5129 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5130 return 0;
5131 arglist = TREE_CHAIN (arglist);
5132 if (! arglist)
5133 return 0;
5134 fmt = TREE_VALUE (arglist);
5135 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5136 return 0;
5137 arglist = TREE_CHAIN (arglist);
5139 /* Check whether the format is a literal string constant. */
5140 fmt_str = c_getstr (fmt);
5141 if (fmt_str == NULL)
5142 return 0;
5144 if (!init_target_chars())
5145 return 0;
5147 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5148 if (strcmp (fmt_str, target_percent_s) == 0)
5150 if (! arglist
5151 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5152 || TREE_CHAIN (arglist))
5153 return 0;
5154 arg = TREE_VALUE (arglist);
5155 arglist = build_tree_list (NULL_TREE, fp);
5156 arglist = tree_cons (NULL_TREE, arg, arglist);
5157 fn = fn_fputs;
5159 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5160 else if (strcmp (fmt_str, target_percent_c) == 0)
5162 if (! arglist
5163 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5164 || TREE_CHAIN (arglist))
5165 return 0;
5166 arg = TREE_VALUE (arglist);
5167 arglist = build_tree_list (NULL_TREE, fp);
5168 arglist = tree_cons (NULL_TREE, arg, arglist);
5169 fn = fn_fputc;
5171 else
5173 /* We can't handle anything else with % args or %% ... yet. */
5174 if (strchr (fmt_str, target_percent))
5175 return 0;
5177 if (arglist)
5178 return 0;
5180 /* If the format specifier was "", fprintf does nothing. */
5181 if (fmt_str[0] == '\0')
5183 /* Evaluate and ignore FILE* argument for side-effects. */
5184 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5185 return const0_rtx;
5188 /* When "string" doesn't contain %, replace all cases of
5189 fprintf(stream,string) with fputs(string,stream). The fputs
5190 builtin will take care of special cases like length == 1. */
5191 arglist = build_tree_list (NULL_TREE, fp);
5192 arglist = tree_cons (NULL_TREE, fmt, arglist);
5193 fn = fn_fputs;
5196 if (!fn)
5197 return 0;
5198 fn = build_function_call_expr (fn, arglist);
5199 if (TREE_CODE (fn) == CALL_EXPR)
5200 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5201 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5204 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5205 a normal call should be emitted rather than expanding the function
5206 inline. If convenient, the result should be placed in TARGET with
5207 mode MODE. */
5209 static rtx
5210 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5212 tree orig_arglist, dest, fmt;
5213 const char *fmt_str;
5215 orig_arglist = arglist;
5217 /* Verify the required arguments in the original call. */
5218 if (! arglist)
5219 return 0;
5220 dest = TREE_VALUE (arglist);
5221 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5222 return 0;
5223 arglist = TREE_CHAIN (arglist);
5224 if (! arglist)
5225 return 0;
5226 fmt = TREE_VALUE (arglist);
5227 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5228 return 0;
5229 arglist = TREE_CHAIN (arglist);
5231 /* Check whether the format is a literal string constant. */
5232 fmt_str = c_getstr (fmt);
5233 if (fmt_str == NULL)
5234 return 0;
5236 if (!init_target_chars())
5237 return 0;
5239 /* If the format doesn't contain % args or %%, use strcpy. */
5240 if (strchr (fmt_str, target_percent) == 0)
5242 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5243 tree exp;
5245 if (arglist || ! fn)
5246 return 0;
5247 expand_expr (build_function_call_expr (fn, orig_arglist),
5248 const0_rtx, VOIDmode, EXPAND_NORMAL);
5249 if (target == const0_rtx)
5250 return const0_rtx;
5251 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5252 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5254 /* If the format is "%s", use strcpy if the result isn't used. */
5255 else if (strcmp (fmt_str, target_percent_s) == 0)
5257 tree fn, arg, len;
5258 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5260 if (! fn)
5261 return 0;
5263 if (! arglist || TREE_CHAIN (arglist))
5264 return 0;
5265 arg = TREE_VALUE (arglist);
5266 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5267 return 0;
5269 if (target != const0_rtx)
5271 len = c_strlen (arg, 1);
5272 if (! len || TREE_CODE (len) != INTEGER_CST)
5273 return 0;
5275 else
5276 len = NULL_TREE;
5278 arglist = build_tree_list (NULL_TREE, arg);
5279 arglist = tree_cons (NULL_TREE, dest, arglist);
5280 expand_expr (build_function_call_expr (fn, arglist),
5281 const0_rtx, VOIDmode, EXPAND_NORMAL);
5283 if (target == const0_rtx)
5284 return const0_rtx;
5285 return expand_expr (len, target, mode, EXPAND_NORMAL);
5288 return 0;
5291 /* Expand a call to either the entry or exit function profiler. */
5293 static rtx
5294 expand_builtin_profile_func (bool exitp)
5296 rtx this, which;
5298 this = DECL_RTL (current_function_decl);
5299 gcc_assert (MEM_P (this));
5300 this = XEXP (this, 0);
5302 if (exitp)
5303 which = profile_function_exit_libfunc;
5304 else
5305 which = profile_function_entry_libfunc;
5307 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5308 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5310 Pmode);
5312 return const0_rtx;
5315 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5317 static rtx
5318 round_trampoline_addr (rtx tramp)
5320 rtx temp, addend, mask;
5322 /* If we don't need too much alignment, we'll have been guaranteed
5323 proper alignment by get_trampoline_type. */
5324 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5325 return tramp;
5327 /* Round address up to desired boundary. */
5328 temp = gen_reg_rtx (Pmode);
5329 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5330 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5332 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5333 temp, 0, OPTAB_LIB_WIDEN);
5334 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5335 temp, 0, OPTAB_LIB_WIDEN);
5337 return tramp;
5340 static rtx
5341 expand_builtin_init_trampoline (tree arglist)
5343 tree t_tramp, t_func, t_chain;
5344 rtx r_tramp, r_func, r_chain;
5345 #ifdef TRAMPOLINE_TEMPLATE
5346 rtx blktramp;
5347 #endif
5349 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5350 POINTER_TYPE, VOID_TYPE))
5351 return NULL_RTX;
5353 t_tramp = TREE_VALUE (arglist);
5354 arglist = TREE_CHAIN (arglist);
5355 t_func = TREE_VALUE (arglist);
5356 arglist = TREE_CHAIN (arglist);
5357 t_chain = TREE_VALUE (arglist);
5359 r_tramp = expand_normal (t_tramp);
5360 r_func = expand_normal (t_func);
5361 r_chain = expand_normal (t_chain);
5363 /* Generate insns to initialize the trampoline. */
5364 r_tramp = round_trampoline_addr (r_tramp);
5365 #ifdef TRAMPOLINE_TEMPLATE
5366 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5367 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5368 emit_block_move (blktramp, assemble_trampoline_template (),
5369 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5370 #endif
5371 trampolines_created = 1;
5372 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5374 return const0_rtx;
5377 static rtx
5378 expand_builtin_adjust_trampoline (tree arglist)
5380 rtx tramp;
5382 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5383 return NULL_RTX;
5385 tramp = expand_normal (TREE_VALUE (arglist));
5386 tramp = round_trampoline_addr (tramp);
5387 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5388 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5389 #endif
5391 return tramp;
5394 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5395 Return NULL_RTX if a normal call should be emitted rather than expanding
5396 the function in-line. EXP is the expression that is a call to the builtin
5397 function; if convenient, the result should be placed in TARGET. */
5399 static rtx
5400 expand_builtin_signbit (tree exp, rtx target)
5402 const struct real_format *fmt;
5403 enum machine_mode fmode, imode, rmode;
5404 HOST_WIDE_INT hi, lo;
5405 tree arg, arglist;
5406 int word, bitpos;
5407 rtx temp;
5409 arglist = TREE_OPERAND (exp, 1);
5410 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5411 return 0;
5413 arg = TREE_VALUE (arglist);
5414 fmode = TYPE_MODE (TREE_TYPE (arg));
5415 rmode = TYPE_MODE (TREE_TYPE (exp));
5416 fmt = REAL_MODE_FORMAT (fmode);
5418 /* For floating point formats without a sign bit, implement signbit
5419 as "ARG < 0.0". */
5420 bitpos = fmt->signbit_ro;
5421 if (bitpos < 0)
5423 /* But we can't do this if the format supports signed zero. */
5424 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5425 return 0;
5427 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5428 build_real (TREE_TYPE (arg), dconst0));
5429 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5432 temp = expand_normal (arg);
5433 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5435 imode = int_mode_for_mode (fmode);
5436 if (imode == BLKmode)
5437 return 0;
5438 temp = gen_lowpart (imode, temp);
5440 else
5442 imode = word_mode;
5443 /* Handle targets with different FP word orders. */
5444 if (FLOAT_WORDS_BIG_ENDIAN)
5445 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5446 else
5447 word = bitpos / BITS_PER_WORD;
5448 temp = operand_subword_force (temp, word, fmode);
5449 bitpos = bitpos % BITS_PER_WORD;
5452 /* Force the intermediate word_mode (or narrower) result into a
5453 register. This avoids attempting to create paradoxical SUBREGs
5454 of floating point modes below. */
5455 temp = force_reg (imode, temp);
5457 /* If the bitpos is within the "result mode" lowpart, the operation
5458 can be implement with a single bitwise AND. Otherwise, we need
5459 a right shift and an AND. */
5461 if (bitpos < GET_MODE_BITSIZE (rmode))
5463 if (bitpos < HOST_BITS_PER_WIDE_INT)
5465 hi = 0;
5466 lo = (HOST_WIDE_INT) 1 << bitpos;
5468 else
5470 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5471 lo = 0;
5474 if (imode != rmode)
5475 temp = gen_lowpart (rmode, temp);
5476 temp = expand_binop (rmode, and_optab, temp,
5477 immed_double_const (lo, hi, rmode),
5478 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5480 else
5482 /* Perform a logical right shift to place the signbit in the least
5483 significant bit, then truncate the result to the desired mode
5484 and mask just this bit. */
5485 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5486 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5487 temp = gen_lowpart (rmode, temp);
5488 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5489 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5492 return temp;
5495 /* Expand fork or exec calls. TARGET is the desired target of the
5496 call. ARGLIST is the list of arguments of the call. FN is the
5497 identificator of the actual function. IGNORE is nonzero if the
5498 value is to be ignored. */
5500 static rtx
5501 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5503 tree id, decl;
5504 tree call;
5506 /* If we are not profiling, just call the function. */
5507 if (!profile_arc_flag)
5508 return NULL_RTX;
5510 /* Otherwise call the wrapper. This should be equivalent for the rest of
5511 compiler, so the code does not diverge, and the wrapper may run the
5512 code necessary for keeping the profiling sane. */
5514 switch (DECL_FUNCTION_CODE (fn))
5516 case BUILT_IN_FORK:
5517 id = get_identifier ("__gcov_fork");
5518 break;
5520 case BUILT_IN_EXECL:
5521 id = get_identifier ("__gcov_execl");
5522 break;
5524 case BUILT_IN_EXECV:
5525 id = get_identifier ("__gcov_execv");
5526 break;
5528 case BUILT_IN_EXECLP:
5529 id = get_identifier ("__gcov_execlp");
5530 break;
5532 case BUILT_IN_EXECLE:
5533 id = get_identifier ("__gcov_execle");
5534 break;
5536 case BUILT_IN_EXECVP:
5537 id = get_identifier ("__gcov_execvp");
5538 break;
5540 case BUILT_IN_EXECVE:
5541 id = get_identifier ("__gcov_execve");
5542 break;
5544 default:
5545 gcc_unreachable ();
5548 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5549 DECL_EXTERNAL (decl) = 1;
5550 TREE_PUBLIC (decl) = 1;
5551 DECL_ARTIFICIAL (decl) = 1;
5552 TREE_NOTHROW (decl) = 1;
5553 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5554 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5555 call = build_function_call_expr (decl, arglist);
5557 return expand_call (call, target, ignore);
5561 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5562 the pointer in these functions is void*, the tree optimizers may remove
5563 casts. The mode computed in expand_builtin isn't reliable either, due
5564 to __sync_bool_compare_and_swap.
5566 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5567 group of builtins. This gives us log2 of the mode size. */
5569 static inline enum machine_mode
5570 get_builtin_sync_mode (int fcode_diff)
5572 /* The size is not negotiable, so ask not to get BLKmode in return
5573 if the target indicates that a smaller size would be better. */
5574 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5577 /* Expand the memory expression LOC and return the appropriate memory operand
5578 for the builtin_sync operations. */
5580 static rtx
5581 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5583 rtx addr, mem;
5585 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5587 /* Note that we explicitly do not want any alias information for this
5588 memory, so that we kill all other live memories. Otherwise we don't
5589 satisfy the full barrier semantics of the intrinsic. */
5590 mem = validize_mem (gen_rtx_MEM (mode, addr));
5592 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5593 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5594 MEM_VOLATILE_P (mem) = 1;
5596 return mem;
5599 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5600 ARGLIST is the operands list to the function. CODE is the rtx code
5601 that corresponds to the arithmetic or logical operation from the name;
5602 an exception here is that NOT actually means NAND. TARGET is an optional
5603 place for us to store the results; AFTER is true if this is the
5604 fetch_and_xxx form. IGNORE is true if we don't actually care about
5605 the result of the operation at all. */
5607 static rtx
5608 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5609 enum rtx_code code, bool after,
5610 rtx target, bool ignore)
5612 rtx val, mem;
5614 /* Expand the operands. */
5615 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5617 arglist = TREE_CHAIN (arglist);
5618 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5619 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5620 val = convert_to_mode (mode, val, 1);
5622 if (ignore)
5623 return expand_sync_operation (mem, val, code);
5624 else
5625 return expand_sync_fetch_operation (mem, val, code, after, target);
5628 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5629 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5630 true if this is the boolean form. TARGET is a place for us to store the
5631 results; this is NOT optional if IS_BOOL is true. */
5633 static rtx
5634 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5635 bool is_bool, rtx target)
5637 rtx old_val, new_val, mem;
5639 /* Expand the operands. */
5640 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5642 arglist = TREE_CHAIN (arglist);
5643 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5644 /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */
5645 old_val = convert_to_mode (mode, old_val, 1);
5647 arglist = TREE_CHAIN (arglist);
5648 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5649 /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */
5650 new_val = convert_to_mode (mode, new_val, 1);
5652 if (is_bool)
5653 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5654 else
5655 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5658 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5659 general form is actually an atomic exchange, and some targets only
5660 support a reduced form with the second argument being a constant 1.
5661 ARGLIST is the operands list to the function; TARGET is an optional
5662 place for us to store the results. */
5664 static rtx
5665 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5666 rtx target)
5668 rtx val, mem;
5670 /* Expand the operands. */
5671 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5673 arglist = TREE_CHAIN (arglist);
5674 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5675 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5676 val = convert_to_mode (mode, val, 1);
5678 return expand_sync_lock_test_and_set (mem, val, target);
5681 /* Expand the __sync_synchronize intrinsic. */
5683 static void
5684 expand_builtin_synchronize (void)
5686 tree x;
5688 #ifdef HAVE_memory_barrier
5689 if (HAVE_memory_barrier)
5691 emit_insn (gen_memory_barrier ());
5692 return;
5694 #endif
5696 /* If no explicit memory barrier instruction is available, create an
5697 empty asm stmt with a memory clobber. */
5698 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5699 tree_cons (NULL, build_string (6, "memory"), NULL));
5700 ASM_VOLATILE_P (x) = 1;
5701 expand_asm_expr (x);
5704 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5705 to the function. */
5707 static void
5708 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5710 enum insn_code icode;
5711 rtx mem, insn;
5712 rtx val = const0_rtx;
5714 /* Expand the operands. */
5715 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5717 /* If there is an explicit operation in the md file, use it. */
5718 icode = sync_lock_release[mode];
5719 if (icode != CODE_FOR_nothing)
5721 if (!insn_data[icode].operand[1].predicate (val, mode))
5722 val = force_reg (mode, val);
5724 insn = GEN_FCN (icode) (mem, val);
5725 if (insn)
5727 emit_insn (insn);
5728 return;
5732 /* Otherwise we can implement this operation by emitting a barrier
5733 followed by a store of zero. */
5734 expand_builtin_synchronize ();
5735 emit_move_insn (mem, val);
5738 /* Expand an expression EXP that calls a built-in function,
5739 with result going to TARGET if that's convenient
5740 (and in mode MODE if that's convenient).
5741 SUBTARGET may be used as the target for computing one of EXP's operands.
5742 IGNORE is nonzero if the value is to be ignored. */
5745 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5746 int ignore)
5748 tree fndecl = get_callee_fndecl (exp);
5749 tree arglist = TREE_OPERAND (exp, 1);
5750 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5751 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5753 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5754 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5756 /* When not optimizing, generate calls to library functions for a certain
5757 set of builtins. */
5758 if (!optimize
5759 && !called_as_built_in (fndecl)
5760 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5761 && fcode != BUILT_IN_ALLOCA)
5762 return expand_call (exp, target, ignore);
5764 /* The built-in function expanders test for target == const0_rtx
5765 to determine whether the function's result will be ignored. */
5766 if (ignore)
5767 target = const0_rtx;
5769 /* If the result of a pure or const built-in function is ignored, and
5770 none of its arguments are volatile, we can avoid expanding the
5771 built-in call and just evaluate the arguments for side-effects. */
5772 if (target == const0_rtx
5773 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5775 bool volatilep = false;
5776 tree arg;
5778 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5779 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5781 volatilep = true;
5782 break;
5785 if (! volatilep)
5787 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5788 expand_expr (TREE_VALUE (arg), const0_rtx,
5789 VOIDmode, EXPAND_NORMAL);
5790 return const0_rtx;
5794 switch (fcode)
5796 CASE_FLT_FN (BUILT_IN_FABS):
5797 target = expand_builtin_fabs (arglist, target, subtarget);
5798 if (target)
5799 return target;
5800 break;
5802 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5803 target = expand_builtin_copysign (arglist, target, subtarget);
5804 if (target)
5805 return target;
5806 break;
5808 /* Just do a normal library call if we were unable to fold
5809 the values. */
5810 CASE_FLT_FN (BUILT_IN_CABS):
5811 break;
5813 CASE_FLT_FN (BUILT_IN_EXP):
5814 CASE_FLT_FN (BUILT_IN_EXP10):
5815 CASE_FLT_FN (BUILT_IN_POW10):
5816 CASE_FLT_FN (BUILT_IN_EXP2):
5817 CASE_FLT_FN (BUILT_IN_EXPM1):
5818 CASE_FLT_FN (BUILT_IN_LOGB):
5819 CASE_FLT_FN (BUILT_IN_ILOGB):
5820 CASE_FLT_FN (BUILT_IN_LOG):
5821 CASE_FLT_FN (BUILT_IN_LOG10):
5822 CASE_FLT_FN (BUILT_IN_LOG2):
5823 CASE_FLT_FN (BUILT_IN_LOG1P):
5824 CASE_FLT_FN (BUILT_IN_TAN):
5825 CASE_FLT_FN (BUILT_IN_ASIN):
5826 CASE_FLT_FN (BUILT_IN_ACOS):
5827 CASE_FLT_FN (BUILT_IN_ATAN):
5828 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5829 because of possible accuracy problems. */
5830 if (! flag_unsafe_math_optimizations)
5831 break;
5832 CASE_FLT_FN (BUILT_IN_SQRT):
5833 CASE_FLT_FN (BUILT_IN_FLOOR):
5834 CASE_FLT_FN (BUILT_IN_CEIL):
5835 CASE_FLT_FN (BUILT_IN_TRUNC):
5836 CASE_FLT_FN (BUILT_IN_ROUND):
5837 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5838 CASE_FLT_FN (BUILT_IN_RINT):
5839 target = expand_builtin_mathfn (exp, target, subtarget);
5840 if (target)
5841 return target;
5842 break;
5844 CASE_FLT_FN (BUILT_IN_LCEIL):
5845 CASE_FLT_FN (BUILT_IN_LLCEIL):
5846 CASE_FLT_FN (BUILT_IN_LFLOOR):
5847 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5848 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5849 if (target)
5850 return target;
5851 break;
5853 CASE_FLT_FN (BUILT_IN_LRINT):
5854 CASE_FLT_FN (BUILT_IN_LLRINT):
5855 CASE_FLT_FN (BUILT_IN_LROUND):
5856 CASE_FLT_FN (BUILT_IN_LLROUND):
5857 target = expand_builtin_int_roundingfn_2 (exp, target, subtarget);
5858 if (target)
5859 return target;
5860 break;
5862 CASE_FLT_FN (BUILT_IN_POW):
5863 target = expand_builtin_pow (exp, target, subtarget);
5864 if (target)
5865 return target;
5866 break;
5868 CASE_FLT_FN (BUILT_IN_POWI):
5869 target = expand_builtin_powi (exp, target, subtarget);
5870 if (target)
5871 return target;
5872 break;
5874 CASE_FLT_FN (BUILT_IN_ATAN2):
5875 CASE_FLT_FN (BUILT_IN_LDEXP):
5876 if (! flag_unsafe_math_optimizations)
5877 break;
5879 CASE_FLT_FN (BUILT_IN_FMOD):
5880 CASE_FLT_FN (BUILT_IN_REMAINDER):
5881 CASE_FLT_FN (BUILT_IN_DREM):
5882 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5883 if (target)
5884 return target;
5885 break;
5887 CASE_FLT_FN (BUILT_IN_CEXPI):
5888 target = expand_builtin_cexpi (exp, target, subtarget);
5889 gcc_assert (target);
5890 return target;
5892 CASE_FLT_FN (BUILT_IN_SIN):
5893 CASE_FLT_FN (BUILT_IN_COS):
5894 if (! flag_unsafe_math_optimizations)
5895 break;
5896 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5897 if (target)
5898 return target;
5899 break;
5901 CASE_FLT_FN (BUILT_IN_SINCOS):
5902 if (! flag_unsafe_math_optimizations)
5903 break;
5904 target = expand_builtin_sincos (exp);
5905 if (target)
5906 return target;
5907 break;
5909 case BUILT_IN_APPLY_ARGS:
5910 return expand_builtin_apply_args ();
5912 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5913 FUNCTION with a copy of the parameters described by
5914 ARGUMENTS, and ARGSIZE. It returns a block of memory
5915 allocated on the stack into which is stored all the registers
5916 that might possibly be used for returning the result of a
5917 function. ARGUMENTS is the value returned by
5918 __builtin_apply_args. ARGSIZE is the number of bytes of
5919 arguments that must be copied. ??? How should this value be
5920 computed? We'll also need a safe worst case value for varargs
5921 functions. */
5922 case BUILT_IN_APPLY:
5923 if (!validate_arglist (arglist, POINTER_TYPE,
5924 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5925 && !validate_arglist (arglist, REFERENCE_TYPE,
5926 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5927 return const0_rtx;
5928 else
5930 int i;
5931 tree t;
5932 rtx ops[3];
5934 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5935 ops[i] = expand_normal (TREE_VALUE (t));
5937 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5940 /* __builtin_return (RESULT) causes the function to return the
5941 value described by RESULT. RESULT is address of the block of
5942 memory returned by __builtin_apply. */
5943 case BUILT_IN_RETURN:
5944 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5945 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5946 return const0_rtx;
5948 case BUILT_IN_SAVEREGS:
5949 return expand_builtin_saveregs ();
5951 case BUILT_IN_ARGS_INFO:
5952 return expand_builtin_args_info (arglist);
5954 /* Return the address of the first anonymous stack arg. */
5955 case BUILT_IN_NEXT_ARG:
5956 if (fold_builtin_next_arg (arglist))
5957 return const0_rtx;
5958 return expand_builtin_next_arg ();
5960 case BUILT_IN_CLASSIFY_TYPE:
5961 return expand_builtin_classify_type (arglist);
5963 case BUILT_IN_CONSTANT_P:
5964 return const0_rtx;
5966 case BUILT_IN_FRAME_ADDRESS:
5967 case BUILT_IN_RETURN_ADDRESS:
5968 return expand_builtin_frame_address (fndecl, arglist);
5970 /* Returns the address of the area where the structure is returned.
5971 0 otherwise. */
5972 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5973 if (arglist != 0
5974 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5975 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5976 return const0_rtx;
5977 else
5978 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5980 case BUILT_IN_ALLOCA:
5981 target = expand_builtin_alloca (arglist, target);
5982 if (target)
5983 return target;
5984 break;
5986 case BUILT_IN_STACK_SAVE:
5987 return expand_stack_save ();
5989 case BUILT_IN_STACK_RESTORE:
5990 expand_stack_restore (TREE_VALUE (arglist));
5991 return const0_rtx;
5993 case BUILT_IN_BSWAP32:
5994 case BUILT_IN_BSWAP64:
5995 target = expand_builtin_bswap (arglist, target, subtarget);
5997 if (target)
5998 return target;
5999 break;
6001 CASE_INT_FN (BUILT_IN_FFS):
6002 case BUILT_IN_FFSIMAX:
6003 target = expand_builtin_unop (target_mode, arglist, target,
6004 subtarget, ffs_optab);
6005 if (target)
6006 return target;
6007 break;
6009 CASE_INT_FN (BUILT_IN_CLZ):
6010 case BUILT_IN_CLZIMAX:
6011 target = expand_builtin_unop (target_mode, arglist, target,
6012 subtarget, clz_optab);
6013 if (target)
6014 return target;
6015 break;
6017 CASE_INT_FN (BUILT_IN_CTZ):
6018 case BUILT_IN_CTZIMAX:
6019 target = expand_builtin_unop (target_mode, arglist, target,
6020 subtarget, ctz_optab);
6021 if (target)
6022 return target;
6023 break;
6025 CASE_INT_FN (BUILT_IN_POPCOUNT):
6026 case BUILT_IN_POPCOUNTIMAX:
6027 target = expand_builtin_unop (target_mode, arglist, target,
6028 subtarget, popcount_optab);
6029 if (target)
6030 return target;
6031 break;
6033 CASE_INT_FN (BUILT_IN_PARITY):
6034 case BUILT_IN_PARITYIMAX:
6035 target = expand_builtin_unop (target_mode, arglist, target,
6036 subtarget, parity_optab);
6037 if (target)
6038 return target;
6039 break;
6041 case BUILT_IN_STRLEN:
6042 target = expand_builtin_strlen (arglist, target, target_mode);
6043 if (target)
6044 return target;
6045 break;
6047 case BUILT_IN_STRCPY:
6048 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
6049 if (target)
6050 return target;
6051 break;
6053 case BUILT_IN_STRNCPY:
6054 target = expand_builtin_strncpy (exp, target, mode);
6055 if (target)
6056 return target;
6057 break;
6059 case BUILT_IN_STPCPY:
6060 target = expand_builtin_stpcpy (exp, target, mode);
6061 if (target)
6062 return target;
6063 break;
6065 case BUILT_IN_STRCAT:
6066 target = expand_builtin_strcat (fndecl, arglist, target, mode);
6067 if (target)
6068 return target;
6069 break;
6071 case BUILT_IN_STRNCAT:
6072 target = expand_builtin_strncat (arglist, target, mode);
6073 if (target)
6074 return target;
6075 break;
6077 case BUILT_IN_STRSPN:
6078 target = expand_builtin_strspn (arglist, target, mode);
6079 if (target)
6080 return target;
6081 break;
6083 case BUILT_IN_STRCSPN:
6084 target = expand_builtin_strcspn (arglist, target, mode);
6085 if (target)
6086 return target;
6087 break;
6089 case BUILT_IN_STRSTR:
6090 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
6091 if (target)
6092 return target;
6093 break;
6095 case BUILT_IN_STRPBRK:
6096 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
6097 if (target)
6098 return target;
6099 break;
6101 case BUILT_IN_INDEX:
6102 case BUILT_IN_STRCHR:
6103 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
6104 if (target)
6105 return target;
6106 break;
6108 case BUILT_IN_RINDEX:
6109 case BUILT_IN_STRRCHR:
6110 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
6111 if (target)
6112 return target;
6113 break;
6115 case BUILT_IN_MEMCPY:
6116 target = expand_builtin_memcpy (exp, target, mode);
6117 if (target)
6118 return target;
6119 break;
6121 case BUILT_IN_MEMPCPY:
6122 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6123 if (target)
6124 return target;
6125 break;
6127 case BUILT_IN_MEMMOVE:
6128 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6129 mode);
6130 if (target)
6131 return target;
6132 break;
6134 case BUILT_IN_BCOPY:
6135 target = expand_builtin_bcopy (exp);
6136 if (target)
6137 return target;
6138 break;
6140 case BUILT_IN_MEMSET:
6141 target = expand_builtin_memset (arglist, target, mode, exp);
6142 if (target)
6143 return target;
6144 break;
6146 case BUILT_IN_BZERO:
6147 target = expand_builtin_bzero (exp);
6148 if (target)
6149 return target;
6150 break;
6152 case BUILT_IN_STRCMP:
6153 target = expand_builtin_strcmp (exp, target, mode);
6154 if (target)
6155 return target;
6156 break;
6158 case BUILT_IN_STRNCMP:
6159 target = expand_builtin_strncmp (exp, target, mode);
6160 if (target)
6161 return target;
6162 break;
6164 case BUILT_IN_BCMP:
6165 case BUILT_IN_MEMCMP:
6166 target = expand_builtin_memcmp (exp, arglist, target, mode);
6167 if (target)
6168 return target;
6169 break;
6171 case BUILT_IN_SETJMP:
6172 /* This should have been lowered to the builtins below. */
6173 gcc_unreachable ();
6175 case BUILT_IN_SETJMP_SETUP:
6176 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6177 and the receiver label. */
6178 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6180 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6181 VOIDmode, EXPAND_NORMAL);
6182 tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
6183 rtx label_r = label_rtx (label);
6185 /* This is copied from the handling of non-local gotos. */
6186 expand_builtin_setjmp_setup (buf_addr, label_r);
6187 nonlocal_goto_handler_labels
6188 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6189 nonlocal_goto_handler_labels);
6190 /* ??? Do not let expand_label treat us as such since we would
6191 not want to be both on the list of non-local labels and on
6192 the list of forced labels. */
6193 FORCED_LABEL (label) = 0;
6194 return const0_rtx;
6196 break;
6198 case BUILT_IN_SETJMP_DISPATCHER:
6199 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6200 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6202 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6203 rtx label_r = label_rtx (label);
6205 /* Remove the dispatcher label from the list of non-local labels
6206 since the receiver labels have been added to it above. */
6207 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6208 return const0_rtx;
6210 break;
6212 case BUILT_IN_SETJMP_RECEIVER:
6213 /* __builtin_setjmp_receiver is passed the receiver label. */
6214 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6216 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6217 rtx label_r = label_rtx (label);
6219 expand_builtin_setjmp_receiver (label_r);
6220 return const0_rtx;
6222 break;
6224 /* __builtin_longjmp is passed a pointer to an array of five words.
6225 It's similar to the C library longjmp function but works with
6226 __builtin_setjmp above. */
6227 case BUILT_IN_LONGJMP:
6228 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6230 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6231 VOIDmode, EXPAND_NORMAL);
6232 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6234 if (value != const1_rtx)
6236 error ("%<__builtin_longjmp%> second argument must be 1");
6237 return const0_rtx;
6240 expand_builtin_longjmp (buf_addr, value);
6241 return const0_rtx;
6243 break;
6245 case BUILT_IN_NONLOCAL_GOTO:
6246 target = expand_builtin_nonlocal_goto (arglist);
6247 if (target)
6248 return target;
6249 break;
6251 /* This updates the setjmp buffer that is its argument with the value
6252 of the current stack pointer. */
6253 case BUILT_IN_UPDATE_SETJMP_BUF:
6254 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6256 rtx buf_addr
6257 = expand_normal (TREE_VALUE (arglist));
6259 expand_builtin_update_setjmp_buf (buf_addr);
6260 return const0_rtx;
6262 break;
6264 case BUILT_IN_TRAP:
6265 expand_builtin_trap ();
6266 return const0_rtx;
6268 case BUILT_IN_PRINTF:
6269 target = expand_builtin_printf (exp, target, mode, false);
6270 if (target)
6271 return target;
6272 break;
6274 case BUILT_IN_PRINTF_UNLOCKED:
6275 target = expand_builtin_printf (exp, target, mode, true);
6276 if (target)
6277 return target;
6278 break;
6280 case BUILT_IN_FPUTS:
6281 target = expand_builtin_fputs (arglist, target, false);
6282 if (target)
6283 return target;
6284 break;
6285 case BUILT_IN_FPUTS_UNLOCKED:
6286 target = expand_builtin_fputs (arglist, target, true);
6287 if (target)
6288 return target;
6289 break;
6291 case BUILT_IN_FPRINTF:
6292 target = expand_builtin_fprintf (exp, target, mode, false);
6293 if (target)
6294 return target;
6295 break;
6297 case BUILT_IN_FPRINTF_UNLOCKED:
6298 target = expand_builtin_fprintf (exp, target, mode, true);
6299 if (target)
6300 return target;
6301 break;
6303 case BUILT_IN_SPRINTF:
6304 target = expand_builtin_sprintf (arglist, target, mode);
6305 if (target)
6306 return target;
6307 break;
6309 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6310 target = expand_builtin_signbit (exp, target);
6311 if (target)
6312 return target;
6313 break;
6315 /* Various hooks for the DWARF 2 __throw routine. */
6316 case BUILT_IN_UNWIND_INIT:
6317 expand_builtin_unwind_init ();
6318 return const0_rtx;
6319 case BUILT_IN_DWARF_CFA:
6320 return virtual_cfa_rtx;
6321 #ifdef DWARF2_UNWIND_INFO
6322 case BUILT_IN_DWARF_SP_COLUMN:
6323 return expand_builtin_dwarf_sp_column ();
6324 case BUILT_IN_INIT_DWARF_REG_SIZES:
6325 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6326 return const0_rtx;
6327 #endif
6328 case BUILT_IN_FROB_RETURN_ADDR:
6329 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6330 case BUILT_IN_EXTRACT_RETURN_ADDR:
6331 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6332 case BUILT_IN_EH_RETURN:
6333 expand_builtin_eh_return (TREE_VALUE (arglist),
6334 TREE_VALUE (TREE_CHAIN (arglist)));
6335 return const0_rtx;
6336 #ifdef EH_RETURN_DATA_REGNO
6337 case BUILT_IN_EH_RETURN_DATA_REGNO:
6338 return expand_builtin_eh_return_data_regno (arglist);
6339 #endif
6340 case BUILT_IN_EXTEND_POINTER:
6341 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6343 case BUILT_IN_VA_START:
6344 case BUILT_IN_STDARG_START:
6345 return expand_builtin_va_start (arglist);
6346 case BUILT_IN_VA_END:
6347 return expand_builtin_va_end (arglist);
6348 case BUILT_IN_VA_COPY:
6349 return expand_builtin_va_copy (arglist);
6350 case BUILT_IN_EXPECT:
6351 return expand_builtin_expect (arglist, target);
6352 case BUILT_IN_PREFETCH:
6353 expand_builtin_prefetch (arglist);
6354 return const0_rtx;
6356 case BUILT_IN_PROFILE_FUNC_ENTER:
6357 return expand_builtin_profile_func (false);
6358 case BUILT_IN_PROFILE_FUNC_EXIT:
6359 return expand_builtin_profile_func (true);
6361 case BUILT_IN_INIT_TRAMPOLINE:
6362 return expand_builtin_init_trampoline (arglist);
6363 case BUILT_IN_ADJUST_TRAMPOLINE:
6364 return expand_builtin_adjust_trampoline (arglist);
6366 case BUILT_IN_FORK:
6367 case BUILT_IN_EXECL:
6368 case BUILT_IN_EXECV:
6369 case BUILT_IN_EXECLP:
6370 case BUILT_IN_EXECLE:
6371 case BUILT_IN_EXECVP:
6372 case BUILT_IN_EXECVE:
6373 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6374 if (target)
6375 return target;
6376 break;
6378 case BUILT_IN_FETCH_AND_ADD_1:
6379 case BUILT_IN_FETCH_AND_ADD_2:
6380 case BUILT_IN_FETCH_AND_ADD_4:
6381 case BUILT_IN_FETCH_AND_ADD_8:
6382 case BUILT_IN_FETCH_AND_ADD_16:
6383 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6384 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6385 false, target, ignore);
6386 if (target)
6387 return target;
6388 break;
6390 case BUILT_IN_FETCH_AND_SUB_1:
6391 case BUILT_IN_FETCH_AND_SUB_2:
6392 case BUILT_IN_FETCH_AND_SUB_4:
6393 case BUILT_IN_FETCH_AND_SUB_8:
6394 case BUILT_IN_FETCH_AND_SUB_16:
6395 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6396 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6397 false, target, ignore);
6398 if (target)
6399 return target;
6400 break;
6402 case BUILT_IN_FETCH_AND_OR_1:
6403 case BUILT_IN_FETCH_AND_OR_2:
6404 case BUILT_IN_FETCH_AND_OR_4:
6405 case BUILT_IN_FETCH_AND_OR_8:
6406 case BUILT_IN_FETCH_AND_OR_16:
6407 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6408 target = expand_builtin_sync_operation (mode, arglist, IOR,
6409 false, target, ignore);
6410 if (target)
6411 return target;
6412 break;
6414 case BUILT_IN_FETCH_AND_AND_1:
6415 case BUILT_IN_FETCH_AND_AND_2:
6416 case BUILT_IN_FETCH_AND_AND_4:
6417 case BUILT_IN_FETCH_AND_AND_8:
6418 case BUILT_IN_FETCH_AND_AND_16:
6419 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6420 target = expand_builtin_sync_operation (mode, arglist, AND,
6421 false, target, ignore);
6422 if (target)
6423 return target;
6424 break;
6426 case BUILT_IN_FETCH_AND_XOR_1:
6427 case BUILT_IN_FETCH_AND_XOR_2:
6428 case BUILT_IN_FETCH_AND_XOR_4:
6429 case BUILT_IN_FETCH_AND_XOR_8:
6430 case BUILT_IN_FETCH_AND_XOR_16:
6431 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6432 target = expand_builtin_sync_operation (mode, arglist, XOR,
6433 false, target, ignore);
6434 if (target)
6435 return target;
6436 break;
6438 case BUILT_IN_FETCH_AND_NAND_1:
6439 case BUILT_IN_FETCH_AND_NAND_2:
6440 case BUILT_IN_FETCH_AND_NAND_4:
6441 case BUILT_IN_FETCH_AND_NAND_8:
6442 case BUILT_IN_FETCH_AND_NAND_16:
6443 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6444 target = expand_builtin_sync_operation (mode, arglist, NOT,
6445 false, target, ignore);
6446 if (target)
6447 return target;
6448 break;
6450 case BUILT_IN_ADD_AND_FETCH_1:
6451 case BUILT_IN_ADD_AND_FETCH_2:
6452 case BUILT_IN_ADD_AND_FETCH_4:
6453 case BUILT_IN_ADD_AND_FETCH_8:
6454 case BUILT_IN_ADD_AND_FETCH_16:
6455 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6456 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6457 true, target, ignore);
6458 if (target)
6459 return target;
6460 break;
6462 case BUILT_IN_SUB_AND_FETCH_1:
6463 case BUILT_IN_SUB_AND_FETCH_2:
6464 case BUILT_IN_SUB_AND_FETCH_4:
6465 case BUILT_IN_SUB_AND_FETCH_8:
6466 case BUILT_IN_SUB_AND_FETCH_16:
6467 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6468 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6469 true, target, ignore);
6470 if (target)
6471 return target;
6472 break;
6474 case BUILT_IN_OR_AND_FETCH_1:
6475 case BUILT_IN_OR_AND_FETCH_2:
6476 case BUILT_IN_OR_AND_FETCH_4:
6477 case BUILT_IN_OR_AND_FETCH_8:
6478 case BUILT_IN_OR_AND_FETCH_16:
6479 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6480 target = expand_builtin_sync_operation (mode, arglist, IOR,
6481 true, target, ignore);
6482 if (target)
6483 return target;
6484 break;
6486 case BUILT_IN_AND_AND_FETCH_1:
6487 case BUILT_IN_AND_AND_FETCH_2:
6488 case BUILT_IN_AND_AND_FETCH_4:
6489 case BUILT_IN_AND_AND_FETCH_8:
6490 case BUILT_IN_AND_AND_FETCH_16:
6491 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6492 target = expand_builtin_sync_operation (mode, arglist, AND,
6493 true, target, ignore);
6494 if (target)
6495 return target;
6496 break;
6498 case BUILT_IN_XOR_AND_FETCH_1:
6499 case BUILT_IN_XOR_AND_FETCH_2:
6500 case BUILT_IN_XOR_AND_FETCH_4:
6501 case BUILT_IN_XOR_AND_FETCH_8:
6502 case BUILT_IN_XOR_AND_FETCH_16:
6503 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6504 target = expand_builtin_sync_operation (mode, arglist, XOR,
6505 true, target, ignore);
6506 if (target)
6507 return target;
6508 break;
6510 case BUILT_IN_NAND_AND_FETCH_1:
6511 case BUILT_IN_NAND_AND_FETCH_2:
6512 case BUILT_IN_NAND_AND_FETCH_4:
6513 case BUILT_IN_NAND_AND_FETCH_8:
6514 case BUILT_IN_NAND_AND_FETCH_16:
6515 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6516 target = expand_builtin_sync_operation (mode, arglist, NOT,
6517 true, target, ignore);
6518 if (target)
6519 return target;
6520 break;
6522 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6523 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6524 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6525 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6526 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6527 if (mode == VOIDmode)
6528 mode = TYPE_MODE (boolean_type_node);
6529 if (!target || !register_operand (target, mode))
6530 target = gen_reg_rtx (mode);
6532 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6533 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6534 if (target)
6535 return target;
6536 break;
6538 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6539 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6540 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6541 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6542 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6543 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6544 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6545 if (target)
6546 return target;
6547 break;
6549 case BUILT_IN_LOCK_TEST_AND_SET_1:
6550 case BUILT_IN_LOCK_TEST_AND_SET_2:
6551 case BUILT_IN_LOCK_TEST_AND_SET_4:
6552 case BUILT_IN_LOCK_TEST_AND_SET_8:
6553 case BUILT_IN_LOCK_TEST_AND_SET_16:
6554 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6555 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6556 if (target)
6557 return target;
6558 break;
6560 case BUILT_IN_LOCK_RELEASE_1:
6561 case BUILT_IN_LOCK_RELEASE_2:
6562 case BUILT_IN_LOCK_RELEASE_4:
6563 case BUILT_IN_LOCK_RELEASE_8:
6564 case BUILT_IN_LOCK_RELEASE_16:
6565 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6566 expand_builtin_lock_release (mode, arglist);
6567 return const0_rtx;
6569 case BUILT_IN_SYNCHRONIZE:
6570 expand_builtin_synchronize ();
6571 return const0_rtx;
6573 case BUILT_IN_OBJECT_SIZE:
6574 return expand_builtin_object_size (exp);
6576 case BUILT_IN_MEMCPY_CHK:
6577 case BUILT_IN_MEMPCPY_CHK:
6578 case BUILT_IN_MEMMOVE_CHK:
6579 case BUILT_IN_MEMSET_CHK:
6580 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6581 if (target)
6582 return target;
6583 break;
6585 case BUILT_IN_STRCPY_CHK:
6586 case BUILT_IN_STPCPY_CHK:
6587 case BUILT_IN_STRNCPY_CHK:
6588 case BUILT_IN_STRCAT_CHK:
6589 case BUILT_IN_STRNCAT_CHK:
6590 case BUILT_IN_SNPRINTF_CHK:
6591 case BUILT_IN_VSNPRINTF_CHK:
6592 maybe_emit_chk_warning (exp, fcode);
6593 break;
6595 case BUILT_IN_SPRINTF_CHK:
6596 case BUILT_IN_VSPRINTF_CHK:
6597 maybe_emit_sprintf_chk_warning (exp, fcode);
6598 break;
6600 default: /* just do library call, if unknown builtin */
6601 break;
6604 /* The switch statement above can drop through to cause the function
6605 to be called normally. */
6606 return expand_call (exp, target, ignore);
6609 /* Determine whether a tree node represents a call to a built-in
6610 function. If the tree T is a call to a built-in function with
6611 the right number of arguments of the appropriate types, return
6612 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6613 Otherwise the return value is END_BUILTINS. */
6615 enum built_in_function
6616 builtin_mathfn_code (tree t)
6618 tree fndecl, arglist, parmlist;
6619 tree argtype, parmtype;
6621 if (TREE_CODE (t) != CALL_EXPR
6622 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6623 return END_BUILTINS;
6625 fndecl = get_callee_fndecl (t);
6626 if (fndecl == NULL_TREE
6627 || TREE_CODE (fndecl) != FUNCTION_DECL
6628 || ! DECL_BUILT_IN (fndecl)
6629 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6630 return END_BUILTINS;
6632 arglist = TREE_OPERAND (t, 1);
6633 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6634 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6636 /* If a function doesn't take a variable number of arguments,
6637 the last element in the list will have type `void'. */
6638 parmtype = TREE_VALUE (parmlist);
6639 if (VOID_TYPE_P (parmtype))
6641 if (arglist)
6642 return END_BUILTINS;
6643 return DECL_FUNCTION_CODE (fndecl);
6646 if (! arglist)
6647 return END_BUILTINS;
6649 argtype = TREE_TYPE (TREE_VALUE (arglist));
6651 if (SCALAR_FLOAT_TYPE_P (parmtype))
6653 if (! SCALAR_FLOAT_TYPE_P (argtype))
6654 return END_BUILTINS;
6656 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6658 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6659 return END_BUILTINS;
6661 else if (POINTER_TYPE_P (parmtype))
6663 if (! POINTER_TYPE_P (argtype))
6664 return END_BUILTINS;
6666 else if (INTEGRAL_TYPE_P (parmtype))
6668 if (! INTEGRAL_TYPE_P (argtype))
6669 return END_BUILTINS;
6671 else
6672 return END_BUILTINS;
6674 arglist = TREE_CHAIN (arglist);
6677 /* Variable-length argument list. */
6678 return DECL_FUNCTION_CODE (fndecl);
6681 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6682 constant. ARGLIST is the argument list of the call. */
6684 static tree
6685 fold_builtin_constant_p (tree arglist)
6687 if (arglist == 0)
6688 return 0;
6690 arglist = TREE_VALUE (arglist);
6692 /* We return 1 for a numeric type that's known to be a constant
6693 value at compile-time or for an aggregate type that's a
6694 literal constant. */
6695 STRIP_NOPS (arglist);
6697 /* If we know this is a constant, emit the constant of one. */
6698 if (CONSTANT_CLASS_P (arglist)
6699 || (TREE_CODE (arglist) == CONSTRUCTOR
6700 && TREE_CONSTANT (arglist)))
6701 return integer_one_node;
6702 if (TREE_CODE (arglist) == ADDR_EXPR)
6704 tree op = TREE_OPERAND (arglist, 0);
6705 if (TREE_CODE (op) == STRING_CST
6706 || (TREE_CODE (op) == ARRAY_REF
6707 && integer_zerop (TREE_OPERAND (op, 1))
6708 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6709 return integer_one_node;
6712 /* If this expression has side effects, show we don't know it to be a
6713 constant. Likewise if it's a pointer or aggregate type since in
6714 those case we only want literals, since those are only optimized
6715 when generating RTL, not later.
6716 And finally, if we are compiling an initializer, not code, we
6717 need to return a definite result now; there's not going to be any
6718 more optimization done. */
6719 if (TREE_SIDE_EFFECTS (arglist)
6720 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6721 || POINTER_TYPE_P (TREE_TYPE (arglist))
6722 || cfun == 0
6723 || folding_initializer)
6724 return integer_zero_node;
6726 return 0;
6729 /* Fold a call to __builtin_expect, if we expect that a comparison against
6730 the argument will fold to a constant. In practice, this means a true
6731 constant or the address of a non-weak symbol. ARGLIST is the argument
6732 list of the call. */
6734 static tree
6735 fold_builtin_expect (tree arglist)
6737 tree arg, inner;
6739 if (arglist == 0)
6740 return 0;
6742 arg = TREE_VALUE (arglist);
6744 /* If the argument isn't invariant, then there's nothing we can do. */
6745 if (!TREE_INVARIANT (arg))
6746 return 0;
6748 /* If we're looking at an address of a weak decl, then do not fold. */
6749 inner = arg;
6750 STRIP_NOPS (inner);
6751 if (TREE_CODE (inner) == ADDR_EXPR)
6755 inner = TREE_OPERAND (inner, 0);
6757 while (TREE_CODE (inner) == COMPONENT_REF
6758 || TREE_CODE (inner) == ARRAY_REF);
6759 if (DECL_P (inner) && DECL_WEAK (inner))
6760 return 0;
6763 /* Otherwise, ARG already has the proper type for the return value. */
6764 return arg;
6767 /* Fold a call to __builtin_classify_type. */
6769 static tree
6770 fold_builtin_classify_type (tree arglist)
6772 if (arglist == 0)
6773 return build_int_cst (NULL_TREE, no_type_class);
6775 return build_int_cst (NULL_TREE,
6776 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6779 /* Fold a call to __builtin_strlen. */
6781 static tree
6782 fold_builtin_strlen (tree arglist)
6784 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6785 return NULL_TREE;
6786 else
6788 tree len = c_strlen (TREE_VALUE (arglist), 0);
6790 if (len)
6792 /* Convert from the internal "sizetype" type to "size_t". */
6793 if (size_type_node)
6794 len = fold_convert (size_type_node, len);
6795 return len;
6798 return NULL_TREE;
6802 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6804 static tree
6805 fold_builtin_inf (tree type, int warn)
6807 REAL_VALUE_TYPE real;
6809 /* __builtin_inff is intended to be usable to define INFINITY on all
6810 targets. If an infinity is not available, INFINITY expands "to a
6811 positive constant of type float that overflows at translation
6812 time", footnote "In this case, using INFINITY will violate the
6813 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6814 Thus we pedwarn to ensure this constraint violation is
6815 diagnosed. */
6816 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6817 pedwarn ("target format does not support infinity");
6819 real_inf (&real);
6820 return build_real (type, real);
6823 /* Fold a call to __builtin_nan or __builtin_nans. */
6825 static tree
6826 fold_builtin_nan (tree arglist, tree type, int quiet)
6828 REAL_VALUE_TYPE real;
6829 const char *str;
6831 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6832 return 0;
6833 str = c_getstr (TREE_VALUE (arglist));
6834 if (!str)
6835 return 0;
6837 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6838 return 0;
6840 return build_real (type, real);
6843 /* Return true if the floating point expression T has an integer value.
6844 We also allow +Inf, -Inf and NaN to be considered integer values. */
6846 static bool
6847 integer_valued_real_p (tree t)
6849 switch (TREE_CODE (t))
6851 case FLOAT_EXPR:
6852 return true;
6854 case ABS_EXPR:
6855 case SAVE_EXPR:
6856 case NON_LVALUE_EXPR:
6857 return integer_valued_real_p (TREE_OPERAND (t, 0));
6859 case COMPOUND_EXPR:
6860 case GIMPLE_MODIFY_STMT:
6861 case BIND_EXPR:
6862 return integer_valued_real_p (GENERIC_TREE_OPERAND (t, 1));
6864 case PLUS_EXPR:
6865 case MINUS_EXPR:
6866 case MULT_EXPR:
6867 case MIN_EXPR:
6868 case MAX_EXPR:
6869 return integer_valued_real_p (TREE_OPERAND (t, 0))
6870 && integer_valued_real_p (TREE_OPERAND (t, 1));
6872 case COND_EXPR:
6873 return integer_valued_real_p (TREE_OPERAND (t, 1))
6874 && integer_valued_real_p (TREE_OPERAND (t, 2));
6876 case REAL_CST:
6877 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
6879 case NOP_EXPR:
6881 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6882 if (TREE_CODE (type) == INTEGER_TYPE)
6883 return true;
6884 if (TREE_CODE (type) == REAL_TYPE)
6885 return integer_valued_real_p (TREE_OPERAND (t, 0));
6886 break;
6889 case CALL_EXPR:
6890 switch (builtin_mathfn_code (t))
6892 CASE_FLT_FN (BUILT_IN_CEIL):
6893 CASE_FLT_FN (BUILT_IN_FLOOR):
6894 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6895 CASE_FLT_FN (BUILT_IN_RINT):
6896 CASE_FLT_FN (BUILT_IN_ROUND):
6897 CASE_FLT_FN (BUILT_IN_TRUNC):
6898 return true;
6900 CASE_FLT_FN (BUILT_IN_FMIN):
6901 CASE_FLT_FN (BUILT_IN_FMAX):
6902 return integer_valued_real_p (TREE_VALUE (TREE_OPERAND (t, 1)))
6903 && integer_valued_real_p (TREE_VALUE (TREE_CHAIN (TREE_OPERAND (t, 1))));
6905 default:
6906 break;
6908 break;
6910 default:
6911 break;
6913 return false;
6916 /* EXP is assumed to be builtin call where truncation can be propagated
6917 across (for instance floor((double)f) == (double)floorf (f).
6918 Do the transformation. */
6920 static tree
6921 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6923 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6924 tree arg;
6926 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6927 return 0;
6929 arg = TREE_VALUE (arglist);
6930 /* Integer rounding functions are idempotent. */
6931 if (fcode == builtin_mathfn_code (arg))
6932 return arg;
6934 /* If argument is already integer valued, and we don't need to worry
6935 about setting errno, there's no need to perform rounding. */
6936 if (! flag_errno_math && integer_valued_real_p (arg))
6937 return arg;
6939 if (optimize)
6941 tree arg0 = strip_float_extensions (arg);
6942 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6943 tree newtype = TREE_TYPE (arg0);
6944 tree decl;
6946 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6947 && (decl = mathfn_built_in (newtype, fcode)))
6949 arglist =
6950 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6951 return fold_convert (ftype,
6952 build_function_call_expr (decl, arglist));
6955 return 0;
6958 /* EXP is assumed to be builtin call which can narrow the FP type of
6959 the argument, for instance lround((double)f) -> lroundf (f). */
6961 static tree
6962 fold_fixed_mathfn (tree fndecl, tree arglist)
6964 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6965 tree arg;
6967 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6968 return 0;
6970 arg = TREE_VALUE (arglist);
6972 /* If argument is already integer valued, and we don't need to worry
6973 about setting errno, there's no need to perform rounding. */
6974 if (! flag_errno_math && integer_valued_real_p (arg))
6975 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6977 if (optimize)
6979 tree ftype = TREE_TYPE (arg);
6980 tree arg0 = strip_float_extensions (arg);
6981 tree newtype = TREE_TYPE (arg0);
6982 tree decl;
6984 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6985 && (decl = mathfn_built_in (newtype, fcode)))
6987 arglist =
6988 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6989 return build_function_call_expr (decl, arglist);
6993 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6994 sizeof (long long) == sizeof (long). */
6995 if (TYPE_PRECISION (long_long_integer_type_node)
6996 == TYPE_PRECISION (long_integer_type_node))
6998 tree newfn = NULL_TREE;
6999 switch (fcode)
7001 CASE_FLT_FN (BUILT_IN_LLCEIL):
7002 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7003 break;
7005 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7006 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7007 break;
7009 CASE_FLT_FN (BUILT_IN_LLROUND):
7010 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7011 break;
7013 CASE_FLT_FN (BUILT_IN_LLRINT):
7014 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7015 break;
7017 default:
7018 break;
7021 if (newfn)
7023 tree newcall = build_function_call_expr (newfn, arglist);
7024 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7028 return 0;
7031 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
7032 is the argument list, TYPE is the return type and FNDECL is the
7033 original function DECL. Return NULL_TREE if no if no simplification
7034 can be made. */
7036 static tree
7037 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
7039 tree arg, res;
7041 if (!arglist || TREE_CHAIN (arglist))
7042 return NULL_TREE;
7044 arg = TREE_VALUE (arglist);
7045 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7046 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7047 return NULL_TREE;
7049 /* Calculate the result when the argument is a constant. */
7050 if (TREE_CODE (arg) == COMPLEX_CST
7051 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7052 type, mpfr_hypot)))
7053 return res;
7055 /* If either part is zero, cabs is fabs of the other. */
7056 if (TREE_CODE (arg) == COMPLEX_EXPR
7057 && real_zerop (TREE_OPERAND (arg, 0)))
7058 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
7059 if (TREE_CODE (arg) == COMPLEX_EXPR
7060 && real_zerop (TREE_OPERAND (arg, 1)))
7061 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
7063 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7064 if (TREE_CODE (arg) == NEGATE_EXPR
7065 || TREE_CODE (arg) == CONJ_EXPR)
7067 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
7068 return build_function_call_expr (fndecl, arglist);
7071 /* Don't do this when optimizing for size. */
7072 if (flag_unsafe_math_optimizations
7073 && optimize && !optimize_size)
7075 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7077 if (sqrtfn != NULL_TREE)
7079 tree rpart, ipart, result, arglist;
7081 arg = builtin_save_expr (arg);
7083 rpart = fold_build1 (REALPART_EXPR, type, arg);
7084 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
7086 rpart = builtin_save_expr (rpart);
7087 ipart = builtin_save_expr (ipart);
7089 result = fold_build2 (PLUS_EXPR, type,
7090 fold_build2 (MULT_EXPR, type,
7091 rpart, rpart),
7092 fold_build2 (MULT_EXPR, type,
7093 ipart, ipart));
7095 arglist = build_tree_list (NULL_TREE, result);
7096 return build_function_call_expr (sqrtfn, arglist);
7100 return NULL_TREE;
7103 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
7104 NULL_TREE if no simplification can be made. */
7106 static tree
7107 fold_builtin_sqrt (tree arglist, tree type)
7110 enum built_in_function fcode;
7111 tree arg = TREE_VALUE (arglist);
7113 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7114 return NULL_TREE;
7116 /* Optimize sqrt of constant value. */
7117 if (TREE_CODE (arg) == REAL_CST
7118 && !TREE_OVERFLOW (arg))
7120 REAL_VALUE_TYPE r, x;
7122 x = TREE_REAL_CST (arg);
7123 if (real_sqrt (&r, TYPE_MODE (type), &x)
7124 || (!flag_trapping_math && !flag_errno_math))
7125 return build_real (type, r);
7128 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7129 fcode = builtin_mathfn_code (arg);
7130 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7132 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7133 arg = fold_build2 (MULT_EXPR, type,
7134 TREE_VALUE (TREE_OPERAND (arg, 1)),
7135 build_real (type, dconsthalf));
7136 arglist = build_tree_list (NULL_TREE, arg);
7137 return build_function_call_expr (expfn, arglist);
7140 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7141 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7143 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7145 if (powfn)
7147 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7148 tree tree_root;
7149 /* The inner root was either sqrt or cbrt. */
7150 REAL_VALUE_TYPE dconstroot =
7151 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7153 /* Adjust for the outer root. */
7154 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7155 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7156 tree_root = build_real (type, dconstroot);
7157 arglist = tree_cons (NULL_TREE, arg0,
7158 build_tree_list (NULL_TREE, tree_root));
7159 return build_function_call_expr (powfn, arglist);
7163 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7164 if (flag_unsafe_math_optimizations
7165 && (fcode == BUILT_IN_POW
7166 || fcode == BUILT_IN_POWF
7167 || fcode == BUILT_IN_POWL))
7169 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7170 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7171 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7172 tree narg1;
7173 if (!tree_expr_nonnegative_p (arg0))
7174 arg0 = build1 (ABS_EXPR, type, arg0);
7175 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7176 build_real (type, dconsthalf));
7177 arglist = tree_cons (NULL_TREE, arg0,
7178 build_tree_list (NULL_TREE, narg1));
7179 return build_function_call_expr (powfn, arglist);
7182 return NULL_TREE;
7185 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7186 NULL_TREE if no simplification can be made. */
7187 static tree
7188 fold_builtin_cbrt (tree arglist, tree type)
7190 tree arg = TREE_VALUE (arglist);
7191 const enum built_in_function fcode = builtin_mathfn_code (arg);
7192 tree res;
7194 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7195 return NULL_TREE;
7197 /* Calculate the result when the argument is a constant. */
7198 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7199 return res;
7201 if (flag_unsafe_math_optimizations)
7203 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7204 if (BUILTIN_EXPONENT_P (fcode))
7206 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7207 const REAL_VALUE_TYPE third_trunc =
7208 real_value_truncate (TYPE_MODE (type), dconstthird);
7209 arg = fold_build2 (MULT_EXPR, type,
7210 TREE_VALUE (TREE_OPERAND (arg, 1)),
7211 build_real (type, third_trunc));
7212 arglist = build_tree_list (NULL_TREE, arg);
7213 return build_function_call_expr (expfn, arglist);
7216 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7217 if (BUILTIN_SQRT_P (fcode))
7219 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7221 if (powfn)
7223 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7224 tree tree_root;
7225 REAL_VALUE_TYPE dconstroot = dconstthird;
7227 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7228 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7229 tree_root = build_real (type, dconstroot);
7230 arglist = tree_cons (NULL_TREE, arg0,
7231 build_tree_list (NULL_TREE, tree_root));
7232 return build_function_call_expr (powfn, arglist);
7236 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7237 if (BUILTIN_CBRT_P (fcode))
7239 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7240 if (tree_expr_nonnegative_p (arg0))
7242 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7244 if (powfn)
7246 tree tree_root;
7247 REAL_VALUE_TYPE dconstroot;
7249 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7250 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7251 tree_root = build_real (type, dconstroot);
7252 arglist = tree_cons (NULL_TREE, arg0,
7253 build_tree_list (NULL_TREE, tree_root));
7254 return build_function_call_expr (powfn, arglist);
7259 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7260 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7261 || fcode == BUILT_IN_POWL)
7263 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7264 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7265 if (tree_expr_nonnegative_p (arg00))
7267 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7268 const REAL_VALUE_TYPE dconstroot
7269 = real_value_truncate (TYPE_MODE (type), dconstthird);
7270 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7271 build_real (type, dconstroot));
7272 arglist = tree_cons (NULL_TREE, arg00,
7273 build_tree_list (NULL_TREE, narg01));
7274 return build_function_call_expr (powfn, arglist);
7278 return NULL_TREE;
7281 /* Fold function call to builtin cos, cosf, or cosl. Return
7282 NULL_TREE if no simplification can be made. */
7283 static tree
7284 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7286 tree arg = TREE_VALUE (arglist);
7287 tree res, narg;
7289 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7290 return NULL_TREE;
7292 /* Calculate the result when the argument is a constant. */
7293 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7294 return res;
7296 /* Optimize cos(-x) into cos (x). */
7297 if ((narg = fold_strip_sign_ops (arg)))
7298 return build_function_call_expr (fndecl,
7299 build_tree_list (NULL_TREE, narg));
7301 return NULL_TREE;
7304 /* Fold function call to builtin cosh, coshf, or coshl. Return
7305 NULL_TREE if no simplification can be made. */
7306 static tree
7307 fold_builtin_cosh (tree arglist, tree type, tree fndecl)
7309 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7311 tree arg = TREE_VALUE (arglist);
7312 tree res, narg;
7314 /* Calculate the result when the argument is a constant. */
7315 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7316 return res;
7318 /* Optimize cosh(-x) into cosh (x). */
7319 if ((narg = fold_strip_sign_ops (arg)))
7320 return build_function_call_expr (fndecl,
7321 build_tree_list (NULL_TREE, narg));
7324 return NULL_TREE;
7327 /* Fold function call to builtin tan, tanf, or tanl. Return
7328 NULL_TREE if no simplification can be made. */
7329 static tree
7330 fold_builtin_tan (tree arglist, tree type)
7332 enum built_in_function fcode;
7333 tree arg = TREE_VALUE (arglist);
7334 tree res;
7336 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7337 return NULL_TREE;
7339 /* Calculate the result when the argument is a constant. */
7340 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7341 return res;
7343 /* Optimize tan(atan(x)) = x. */
7344 fcode = builtin_mathfn_code (arg);
7345 if (flag_unsafe_math_optimizations
7346 && (fcode == BUILT_IN_ATAN
7347 || fcode == BUILT_IN_ATANF
7348 || fcode == BUILT_IN_ATANL))
7349 return TREE_VALUE (TREE_OPERAND (arg, 1));
7351 return NULL_TREE;
7354 /* Fold function call to builtin sincos, sincosf, or sincosl. Return
7355 NULL_TREE if no simplification can be made. */
7357 static tree
7358 fold_builtin_sincos (tree arglist)
7360 tree type, arg0, arg1, arg2;
7361 tree res, fn, call;
7363 if (!validate_arglist (arglist, REAL_TYPE, POINTER_TYPE,
7364 POINTER_TYPE, VOID_TYPE))
7365 return NULL_TREE;
7367 arg0 = TREE_VALUE (arglist);
7368 type = TREE_TYPE (arg0);
7369 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7370 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7372 /* Calculate the result when the argument is a constant. */
7373 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7374 return res;
7376 /* Canonicalize sincos to cexpi. */
7377 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7378 if (!fn)
7379 return NULL_TREE;
7381 call = build_function_call_expr (fn, build_tree_list (NULL_TREE, arg0));
7382 call = builtin_save_expr (call);
7384 return build2 (COMPOUND_EXPR, type,
7385 build2 (MODIFY_EXPR, void_type_node,
7386 build_fold_indirect_ref (arg1),
7387 build1 (IMAGPART_EXPR, type, call)),
7388 build2 (MODIFY_EXPR, void_type_node,
7389 build_fold_indirect_ref (arg2),
7390 build1 (REALPART_EXPR, type, call)));
7393 /* Fold function call to builtin cexp, cexpf, or cexpl. Return
7394 NULL_TREE if no simplification can be made. */
7396 static tree
7397 fold_builtin_cexp (tree arglist, tree type)
7399 tree arg0, rtype;
7400 tree realp, imagp, ifn;
7402 if (!validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7403 return NULL_TREE;
7405 arg0 = TREE_VALUE (arglist);
7406 rtype = TREE_TYPE (TREE_TYPE (arg0));
7408 /* In case we can figure out the real part of arg0 and it is constant zero
7409 fold to cexpi. */
7410 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7411 if (!ifn)
7412 return NULL_TREE;
7414 if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
7415 && real_zerop (realp))
7417 tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
7418 return build_function_call_expr (ifn, build_tree_list (NULL_TREE, narg));
7421 /* In case we can easily decompose real and imaginary parts split cexp
7422 to exp (r) * cexpi (i). */
7423 if (flag_unsafe_math_optimizations
7424 && realp)
7426 tree rfn, rcall, icall;
7428 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7429 if (!rfn)
7430 return NULL_TREE;
7432 imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
7433 if (!imagp)
7434 return NULL_TREE;
7436 icall = build_function_call_expr (ifn,
7437 build_tree_list (NULL_TREE, imagp));
7438 icall = builtin_save_expr (icall);
7439 rcall = build_function_call_expr (rfn,
7440 build_tree_list (NULL_TREE, realp));
7441 rcall = builtin_save_expr (rcall);
7442 return build2 (COMPLEX_EXPR, type,
7443 build2 (MULT_EXPR, rtype,
7444 rcall,
7445 build1 (REALPART_EXPR, rtype, icall)),
7446 build2 (MULT_EXPR, rtype,
7447 rcall,
7448 build1 (IMAGPART_EXPR, rtype, icall)));
7451 return NULL_TREE;
7454 /* Fold function call to builtin trunc, truncf or truncl. Return
7455 NULL_TREE if no simplification can be made. */
7457 static tree
7458 fold_builtin_trunc (tree fndecl, tree arglist)
7460 tree arg;
7462 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7463 return 0;
7465 /* Optimize trunc of constant value. */
7466 arg = TREE_VALUE (arglist);
7467 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7469 REAL_VALUE_TYPE r, x;
7470 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7472 x = TREE_REAL_CST (arg);
7473 real_trunc (&r, TYPE_MODE (type), &x);
7474 return build_real (type, r);
7477 return fold_trunc_transparent_mathfn (fndecl, arglist);
7480 /* Fold function call to builtin floor, floorf or floorl. Return
7481 NULL_TREE if no simplification can be made. */
7483 static tree
7484 fold_builtin_floor (tree fndecl, tree arglist)
7486 tree arg;
7488 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7489 return 0;
7491 /* Optimize floor of constant value. */
7492 arg = TREE_VALUE (arglist);
7493 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7495 REAL_VALUE_TYPE x;
7497 x = TREE_REAL_CST (arg);
7498 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7500 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7501 REAL_VALUE_TYPE r;
7503 real_floor (&r, TYPE_MODE (type), &x);
7504 return build_real (type, r);
7508 /* Fold floor (x) where x is nonnegative to trunc (x). */
7509 if (tree_expr_nonnegative_p (arg))
7511 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7512 if (truncfn)
7513 return build_function_call_expr (truncfn, arglist);
7516 return fold_trunc_transparent_mathfn (fndecl, arglist);
7519 /* Fold function call to builtin ceil, ceilf or ceill. Return
7520 NULL_TREE if no simplification can be made. */
7522 static tree
7523 fold_builtin_ceil (tree fndecl, tree arglist)
7525 tree arg;
7527 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7528 return 0;
7530 /* Optimize ceil of constant value. */
7531 arg = TREE_VALUE (arglist);
7532 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7534 REAL_VALUE_TYPE x;
7536 x = TREE_REAL_CST (arg);
7537 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7539 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7540 REAL_VALUE_TYPE r;
7542 real_ceil (&r, TYPE_MODE (type), &x);
7543 return build_real (type, r);
7547 return fold_trunc_transparent_mathfn (fndecl, arglist);
7550 /* Fold function call to builtin round, roundf or roundl. Return
7551 NULL_TREE if no simplification can be made. */
7553 static tree
7554 fold_builtin_round (tree fndecl, tree arglist)
7556 tree arg;
7558 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7559 return 0;
7561 /* Optimize round of constant value. */
7562 arg = TREE_VALUE (arglist);
7563 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7565 REAL_VALUE_TYPE x;
7567 x = TREE_REAL_CST (arg);
7568 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7570 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7571 REAL_VALUE_TYPE r;
7573 real_round (&r, TYPE_MODE (type), &x);
7574 return build_real (type, r);
7578 return fold_trunc_transparent_mathfn (fndecl, arglist);
7581 /* Fold function call to builtin lround, lroundf or lroundl (or the
7582 corresponding long long versions) and other rounding functions.
7583 Return NULL_TREE if no simplification can be made. */
7585 static tree
7586 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7588 tree arg;
7590 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7591 return 0;
7593 /* Optimize lround of constant value. */
7594 arg = TREE_VALUE (arglist);
7595 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7597 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7599 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7601 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7602 tree ftype = TREE_TYPE (arg);
7603 unsigned HOST_WIDE_INT lo2;
7604 HOST_WIDE_INT hi, lo;
7605 REAL_VALUE_TYPE r;
7607 switch (DECL_FUNCTION_CODE (fndecl))
7609 CASE_FLT_FN (BUILT_IN_LFLOOR):
7610 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7611 real_floor (&r, TYPE_MODE (ftype), &x);
7612 break;
7614 CASE_FLT_FN (BUILT_IN_LCEIL):
7615 CASE_FLT_FN (BUILT_IN_LLCEIL):
7616 real_ceil (&r, TYPE_MODE (ftype), &x);
7617 break;
7619 CASE_FLT_FN (BUILT_IN_LROUND):
7620 CASE_FLT_FN (BUILT_IN_LLROUND):
7621 real_round (&r, TYPE_MODE (ftype), &x);
7622 break;
7624 default:
7625 gcc_unreachable ();
7628 REAL_VALUE_TO_INT (&lo, &hi, r);
7629 if (!fit_double_type (lo, hi, &lo2, &hi, itype))
7630 return build_int_cst_wide (itype, lo2, hi);
7634 switch (DECL_FUNCTION_CODE (fndecl))
7636 CASE_FLT_FN (BUILT_IN_LFLOOR):
7637 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7638 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7639 if (tree_expr_nonnegative_p (arg))
7640 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
7641 arg);
7642 break;
7643 default:;
7646 return fold_fixed_mathfn (fndecl, arglist);
7649 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7650 and their long and long long variants (i.e. ffsl and ffsll).
7651 Return NULL_TREE if no simplification can be made. */
7653 static tree
7654 fold_builtin_bitop (tree fndecl, tree arglist)
7656 tree arg;
7658 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7659 return NULL_TREE;
7661 /* Optimize for constant argument. */
7662 arg = TREE_VALUE (arglist);
7663 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
7665 HOST_WIDE_INT hi, width, result;
7666 unsigned HOST_WIDE_INT lo;
7667 tree type;
7669 type = TREE_TYPE (arg);
7670 width = TYPE_PRECISION (type);
7671 lo = TREE_INT_CST_LOW (arg);
7673 /* Clear all the bits that are beyond the type's precision. */
7674 if (width > HOST_BITS_PER_WIDE_INT)
7676 hi = TREE_INT_CST_HIGH (arg);
7677 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7678 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7680 else
7682 hi = 0;
7683 if (width < HOST_BITS_PER_WIDE_INT)
7684 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7687 switch (DECL_FUNCTION_CODE (fndecl))
7689 CASE_INT_FN (BUILT_IN_FFS):
7690 if (lo != 0)
7691 result = exact_log2 (lo & -lo) + 1;
7692 else if (hi != 0)
7693 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7694 else
7695 result = 0;
7696 break;
7698 CASE_INT_FN (BUILT_IN_CLZ):
7699 if (hi != 0)
7700 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7701 else if (lo != 0)
7702 result = width - floor_log2 (lo) - 1;
7703 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7704 result = width;
7705 break;
7707 CASE_INT_FN (BUILT_IN_CTZ):
7708 if (lo != 0)
7709 result = exact_log2 (lo & -lo);
7710 else if (hi != 0)
7711 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7712 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7713 result = width;
7714 break;
7716 CASE_INT_FN (BUILT_IN_POPCOUNT):
7717 result = 0;
7718 while (lo)
7719 result++, lo &= lo - 1;
7720 while (hi)
7721 result++, hi &= hi - 1;
7722 break;
7724 CASE_INT_FN (BUILT_IN_PARITY):
7725 result = 0;
7726 while (lo)
7727 result++, lo &= lo - 1;
7728 while (hi)
7729 result++, hi &= hi - 1;
7730 result &= 1;
7731 break;
7733 default:
7734 gcc_unreachable ();
7737 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7740 return NULL_TREE;
7743 /* Fold function call to builtin_bswap and the long and long long
7744 variants. Return NULL_TREE if no simplification can be made. */
7745 static tree
7746 fold_builtin_bswap (tree fndecl, tree arglist)
7748 tree arg;
7750 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7751 return 0;
7753 /* Optimize constant value. */
7754 arg = TREE_VALUE (arglist);
7755 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
7757 HOST_WIDE_INT hi, width, r_hi = 0;
7758 unsigned HOST_WIDE_INT lo, r_lo = 0;
7759 tree type;
7761 type = TREE_TYPE (arg);
7762 width = TYPE_PRECISION (type);
7763 lo = TREE_INT_CST_LOW (arg);
7764 hi = TREE_INT_CST_HIGH (arg);
7766 switch (DECL_FUNCTION_CODE (fndecl))
7768 case BUILT_IN_BSWAP32:
7769 case BUILT_IN_BSWAP64:
7771 int s;
7773 for (s = 0; s < width; s += 8)
7775 int d = width - s - 8;
7776 unsigned HOST_WIDE_INT byte;
7778 if (s < HOST_BITS_PER_WIDE_INT)
7779 byte = (lo >> s) & 0xff;
7780 else
7781 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
7783 if (d < HOST_BITS_PER_WIDE_INT)
7784 r_lo |= byte << d;
7785 else
7786 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
7790 break;
7792 default:
7793 gcc_unreachable ();
7796 if (width < HOST_BITS_PER_WIDE_INT)
7797 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
7798 else
7799 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
7802 return NULL_TREE;
7804 /* Return true if EXPR is the real constant contained in VALUE. */
7806 static bool
7807 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7809 STRIP_NOPS (expr);
7811 return ((TREE_CODE (expr) == REAL_CST
7812 && !TREE_OVERFLOW (expr)
7813 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7814 || (TREE_CODE (expr) == COMPLEX_CST
7815 && real_dconstp (TREE_REALPART (expr), value)
7816 && real_zerop (TREE_IMAGPART (expr))));
7819 /* A subroutine of fold_builtin to fold the various logarithmic
7820 functions. Return NULL_TREE if no simplification can me made.
7821 FUNC is the corresponding MPFR logarithm function. */
7823 static tree
7824 fold_builtin_logarithm (tree fndecl, tree arglist,
7825 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
7827 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7829 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7830 tree arg = TREE_VALUE (arglist);
7831 tree res;
7832 const enum built_in_function fcode = builtin_mathfn_code (arg);
7834 /* Optimize log(e) = 1.0. We're never passed an exact 'e',
7835 instead we'll look for 'e' truncated to MODE. So only do
7836 this if flag_unsafe_math_optimizations is set. */
7837 if (flag_unsafe_math_optimizations && func == mpfr_log)
7839 const REAL_VALUE_TYPE e_truncated =
7840 real_value_truncate (TYPE_MODE (type), dconste);
7841 if (real_dconstp (arg, &e_truncated))
7842 return build_real (type, dconst1);
7845 /* Calculate the result when the argument is a constant. */
7846 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
7847 return res;
7849 /* Special case, optimize logN(expN(x)) = x. */
7850 if (flag_unsafe_math_optimizations
7851 && ((func == mpfr_log
7852 && (fcode == BUILT_IN_EXP
7853 || fcode == BUILT_IN_EXPF
7854 || fcode == BUILT_IN_EXPL))
7855 || (func == mpfr_log2
7856 && (fcode == BUILT_IN_EXP2
7857 || fcode == BUILT_IN_EXP2F
7858 || fcode == BUILT_IN_EXP2L))
7859 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
7860 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7862 /* Optimize logN(func()) for various exponential functions. We
7863 want to determine the value "x" and the power "exponent" in
7864 order to transform logN(x**exponent) into exponent*logN(x). */
7865 if (flag_unsafe_math_optimizations)
7867 tree exponent = 0, x = 0;
7869 switch (fcode)
7871 CASE_FLT_FN (BUILT_IN_EXP):
7872 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7873 x = build_real (type,
7874 real_value_truncate (TYPE_MODE (type), dconste));
7875 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7876 break;
7877 CASE_FLT_FN (BUILT_IN_EXP2):
7878 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7879 x = build_real (type, dconst2);
7880 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7881 break;
7882 CASE_FLT_FN (BUILT_IN_EXP10):
7883 CASE_FLT_FN (BUILT_IN_POW10):
7884 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7885 x = build_real (type, dconst10);
7886 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7887 break;
7888 CASE_FLT_FN (BUILT_IN_SQRT):
7889 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7890 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7891 exponent = build_real (type, dconsthalf);
7892 break;
7893 CASE_FLT_FN (BUILT_IN_CBRT):
7894 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7895 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7896 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7897 dconstthird));
7898 break;
7899 CASE_FLT_FN (BUILT_IN_POW):
7900 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7901 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7902 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7903 break;
7904 default:
7905 break;
7908 /* Now perform the optimization. */
7909 if (x && exponent)
7911 tree logfn;
7912 arglist = build_tree_list (NULL_TREE, x);
7913 logfn = build_function_call_expr (fndecl, arglist);
7914 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7919 return 0;
7922 /* Fold a builtin function call to hypot, hypotf, or hypotl. Return
7923 NULL_TREE if no simplification can be made. */
7925 static tree
7926 fold_builtin_hypot (tree fndecl, tree arglist, tree type)
7928 tree arg0 = TREE_VALUE (arglist);
7929 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7930 tree res, narg0, narg1;
7932 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7933 return NULL_TREE;
7935 /* Calculate the result when the argument is a constant. */
7936 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
7937 return res;
7939 /* If either argument to hypot has a negate or abs, strip that off.
7940 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
7941 narg0 = fold_strip_sign_ops (arg0);
7942 narg1 = fold_strip_sign_ops (arg1);
7943 if (narg0 || narg1)
7945 tree narglist = tree_cons (NULL_TREE, narg0 ? narg0 : arg0,
7946 build_tree_list (NULL_TREE,
7947 narg1 ? narg1 : arg1));
7948 return build_function_call_expr (fndecl, narglist);
7951 /* If either argument is zero, hypot is fabs of the other. */
7952 if (real_zerop (arg0))
7953 return fold_build1 (ABS_EXPR, type, arg1);
7954 else if (real_zerop (arg1))
7955 return fold_build1 (ABS_EXPR, type, arg0);
7957 /* hypot(x,x) -> fabs(x)*sqrt(2). */
7958 if (flag_unsafe_math_optimizations
7959 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
7961 REAL_VALUE_TYPE sqrt2;
7963 real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2);
7964 return fold_build2 (MULT_EXPR, type,
7965 fold_build1 (ABS_EXPR, type, arg0),
7966 build_real (type, sqrt2));
7969 return NULL_TREE;
7973 /* Fold a builtin function call to pow, powf, or powl. Return
7974 NULL_TREE if no simplification can be made. */
7975 static tree
7976 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7978 tree arg0 = TREE_VALUE (arglist);
7979 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7980 tree res;
7982 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7983 return NULL_TREE;
7985 /* Calculate the result when the argument is a constant. */
7986 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
7987 return res;
7989 /* Optimize pow(1.0,y) = 1.0. */
7990 if (real_onep (arg0))
7991 return omit_one_operand (type, build_real (type, dconst1), arg1);
7993 if (TREE_CODE (arg1) == REAL_CST
7994 && !TREE_OVERFLOW (arg1))
7996 REAL_VALUE_TYPE cint;
7997 REAL_VALUE_TYPE c;
7998 HOST_WIDE_INT n;
8000 c = TREE_REAL_CST (arg1);
8002 /* Optimize pow(x,0.0) = 1.0. */
8003 if (REAL_VALUES_EQUAL (c, dconst0))
8004 return omit_one_operand (type, build_real (type, dconst1),
8005 arg0);
8007 /* Optimize pow(x,1.0) = x. */
8008 if (REAL_VALUES_EQUAL (c, dconst1))
8009 return arg0;
8011 /* Optimize pow(x,-1.0) = 1.0/x. */
8012 if (REAL_VALUES_EQUAL (c, dconstm1))
8013 return fold_build2 (RDIV_EXPR, type,
8014 build_real (type, dconst1), arg0);
8016 /* Optimize pow(x,0.5) = sqrt(x). */
8017 if (flag_unsafe_math_optimizations
8018 && REAL_VALUES_EQUAL (c, dconsthalf))
8020 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8022 if (sqrtfn != NULL_TREE)
8024 tree arglist = build_tree_list (NULL_TREE, arg0);
8025 return build_function_call_expr (sqrtfn, arglist);
8029 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8030 if (flag_unsafe_math_optimizations)
8032 const REAL_VALUE_TYPE dconstroot
8033 = real_value_truncate (TYPE_MODE (type), dconstthird);
8035 if (REAL_VALUES_EQUAL (c, dconstroot))
8037 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8038 if (cbrtfn != NULL_TREE)
8040 tree arglist = build_tree_list (NULL_TREE, arg0);
8041 return build_function_call_expr (cbrtfn, arglist);
8046 /* Check for an integer exponent. */
8047 n = real_to_integer (&c);
8048 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8049 if (real_identical (&c, &cint))
8051 /* Attempt to evaluate pow at compile-time. */
8052 if (TREE_CODE (arg0) == REAL_CST
8053 && !TREE_OVERFLOW (arg0))
8055 REAL_VALUE_TYPE x;
8056 bool inexact;
8058 x = TREE_REAL_CST (arg0);
8059 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8060 if (flag_unsafe_math_optimizations || !inexact)
8061 return build_real (type, x);
8064 /* Strip sign ops from even integer powers. */
8065 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8067 tree narg0 = fold_strip_sign_ops (arg0);
8068 if (narg0)
8070 arglist = build_tree_list (NULL_TREE, arg1);
8071 arglist = tree_cons (NULL_TREE, narg0, arglist);
8072 return build_function_call_expr (fndecl, arglist);
8078 if (flag_unsafe_math_optimizations)
8080 const enum built_in_function fcode = builtin_mathfn_code (arg0);
8082 /* Optimize pow(expN(x),y) = expN(x*y). */
8083 if (BUILTIN_EXPONENT_P (fcode))
8085 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8086 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8087 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
8088 arglist = build_tree_list (NULL_TREE, arg);
8089 return build_function_call_expr (expfn, arglist);
8092 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8093 if (BUILTIN_SQRT_P (fcode))
8095 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8096 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8097 build_real (type, dconsthalf));
8099 arglist = tree_cons (NULL_TREE, narg0,
8100 build_tree_list (NULL_TREE, narg1));
8101 return build_function_call_expr (fndecl, arglist);
8104 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8105 if (BUILTIN_CBRT_P (fcode))
8107 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8108 if (tree_expr_nonnegative_p (arg))
8110 const REAL_VALUE_TYPE dconstroot
8111 = real_value_truncate (TYPE_MODE (type), dconstthird);
8112 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8113 build_real (type, dconstroot));
8114 arglist = tree_cons (NULL_TREE, arg,
8115 build_tree_list (NULL_TREE, narg1));
8116 return build_function_call_expr (fndecl, arglist);
8120 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
8121 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
8122 || fcode == BUILT_IN_POWL)
8124 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8125 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8126 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
8127 arglist = tree_cons (NULL_TREE, arg00,
8128 build_tree_list (NULL_TREE, narg1));
8129 return build_function_call_expr (fndecl, arglist);
8133 return NULL_TREE;
8136 /* Fold a builtin function call to powi, powif, or powil. Return
8137 NULL_TREE if no simplification can be made. */
8138 static tree
8139 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
8141 tree arg0 = TREE_VALUE (arglist);
8142 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8144 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
8145 return NULL_TREE;
8147 /* Optimize pow(1.0,y) = 1.0. */
8148 if (real_onep (arg0))
8149 return omit_one_operand (type, build_real (type, dconst1), arg1);
8151 if (host_integerp (arg1, 0))
8153 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8155 /* Evaluate powi at compile-time. */
8156 if (TREE_CODE (arg0) == REAL_CST
8157 && !TREE_OVERFLOW (arg0))
8159 REAL_VALUE_TYPE x;
8160 x = TREE_REAL_CST (arg0);
8161 real_powi (&x, TYPE_MODE (type), &x, c);
8162 return build_real (type, x);
8165 /* Optimize pow(x,0) = 1.0. */
8166 if (c == 0)
8167 return omit_one_operand (type, build_real (type, dconst1),
8168 arg0);
8170 /* Optimize pow(x,1) = x. */
8171 if (c == 1)
8172 return arg0;
8174 /* Optimize pow(x,-1) = 1.0/x. */
8175 if (c == -1)
8176 return fold_build2 (RDIV_EXPR, type,
8177 build_real (type, dconst1), arg0);
8180 return NULL_TREE;
8183 /* A subroutine of fold_builtin to fold the various exponent
8184 functions. Return NULL_TREE if no simplification can me made.
8185 FUNC is the corresponding MPFR exponent function. */
8187 static tree
8188 fold_builtin_exponent (tree fndecl, tree arglist,
8189 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8191 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8193 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8194 tree arg = TREE_VALUE (arglist);
8195 tree res;
8197 /* Calculate the result when the argument is a constant. */
8198 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8199 return res;
8201 /* Optimize expN(logN(x)) = x. */
8202 if (flag_unsafe_math_optimizations)
8204 const enum built_in_function fcode = builtin_mathfn_code (arg);
8206 if ((func == mpfr_exp
8207 && (fcode == BUILT_IN_LOG
8208 || fcode == BUILT_IN_LOGF
8209 || fcode == BUILT_IN_LOGL))
8210 || (func == mpfr_exp2
8211 && (fcode == BUILT_IN_LOG2
8212 || fcode == BUILT_IN_LOG2F
8213 || fcode == BUILT_IN_LOG2L))
8214 || (func == mpfr_exp10
8215 && (fcode == BUILT_IN_LOG10
8216 || fcode == BUILT_IN_LOG10F
8217 || fcode == BUILT_IN_LOG10L)))
8218 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
8222 return 0;
8225 /* Return true if VAR is a VAR_DECL or a component thereof. */
8227 static bool
8228 var_decl_component_p (tree var)
8230 tree inner = var;
8231 while (handled_component_p (inner))
8232 inner = TREE_OPERAND (inner, 0);
8233 return SSA_VAR_P (inner);
8236 /* Fold function call to builtin memset. Return
8237 NULL_TREE if no simplification can be made. */
8239 static tree
8240 fold_builtin_memset (tree arglist, tree type, bool ignore)
8242 tree dest, c, len, var, ret;
8243 unsigned HOST_WIDE_INT length, cval;
8245 if (!validate_arglist (arglist,
8246 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
8247 return 0;
8249 dest = TREE_VALUE (arglist);
8250 c = TREE_VALUE (TREE_CHAIN (arglist));
8251 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8253 if (! host_integerp (len, 1))
8254 return 0;
8256 /* If the LEN parameter is zero, return DEST. */
8257 if (integer_zerop (len))
8258 return omit_one_operand (type, dest, c);
8260 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8261 return 0;
8263 var = dest;
8264 STRIP_NOPS (var);
8265 if (TREE_CODE (var) != ADDR_EXPR)
8266 return 0;
8268 var = TREE_OPERAND (var, 0);
8269 if (TREE_THIS_VOLATILE (var))
8270 return 0;
8272 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8273 && !POINTER_TYPE_P (TREE_TYPE (var)))
8274 return 0;
8276 if (! var_decl_component_p (var))
8277 return 0;
8279 length = tree_low_cst (len, 1);
8280 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8281 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8282 < (int) length)
8283 return 0;
8285 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8286 return 0;
8288 if (integer_zerop (c))
8289 cval = 0;
8290 else
8292 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8293 return 0;
8295 cval = tree_low_cst (c, 1);
8296 cval &= 0xff;
8297 cval |= cval << 8;
8298 cval |= cval << 16;
8299 cval |= (cval << 31) << 1;
8302 ret = build_int_cst_type (TREE_TYPE (var), cval);
8303 ret = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (var), var, ret);
8304 if (ignore)
8305 return ret;
8307 return omit_one_operand (type, dest, ret);
8310 /* Fold function call to builtin memset. Return
8311 NULL_TREE if no simplification can be made. */
8313 static tree
8314 fold_builtin_bzero (tree arglist, bool ignore)
8316 tree dest, size, newarglist;
8318 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8319 return 0;
8321 if (!ignore)
8322 return 0;
8324 dest = TREE_VALUE (arglist);
8325 size = TREE_VALUE (TREE_CHAIN (arglist));
8327 /* New argument list transforming bzero(ptr x, int y) to
8328 memset(ptr x, int 0, size_t y). This is done this way
8329 so that if it isn't expanded inline, we fallback to
8330 calling bzero instead of memset. */
8332 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8333 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
8334 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8335 return fold_builtin_memset (newarglist, void_type_node, ignore);
8338 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8339 NULL_TREE if no simplification can be made.
8340 If ENDP is 0, return DEST (like memcpy).
8341 If ENDP is 1, return DEST+LEN (like mempcpy).
8342 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8343 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8344 (memmove). */
8346 static tree
8347 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8349 tree dest, src, len, destvar, srcvar, expr;
8351 if (! validate_arglist (arglist,
8352 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8353 return 0;
8355 dest = TREE_VALUE (arglist);
8356 src = TREE_VALUE (TREE_CHAIN (arglist));
8357 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8359 /* If the LEN parameter is zero, return DEST. */
8360 if (integer_zerop (len))
8361 return omit_one_operand (type, dest, src);
8363 /* If SRC and DEST are the same (and not volatile), return
8364 DEST{,+LEN,+LEN-1}. */
8365 if (operand_equal_p (src, dest, 0))
8366 expr = len;
8367 else
8369 tree srctype, desttype;
8370 if (endp == 3)
8372 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8373 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8375 /* Both DEST and SRC must be pointer types.
8376 ??? This is what old code did. Is the testing for pointer types
8377 really mandatory?
8379 If either SRC is readonly or length is 1, we can use memcpy. */
8380 if (dest_align && src_align
8381 && (readonly_data_expr (src)
8382 || (host_integerp (len, 1)
8383 && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
8384 tree_low_cst (len, 1)))))
8386 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8387 if (!fn)
8388 return 0;
8389 return build_function_call_expr (fn, arglist);
8391 return 0;
8394 if (!host_integerp (len, 0))
8395 return 0;
8396 /* FIXME:
8397 This logic lose for arguments like (type *)malloc (sizeof (type)),
8398 since we strip the casts of up to VOID return value from malloc.
8399 Perhaps we ought to inherit type from non-VOID argument here? */
8400 STRIP_NOPS (src);
8401 STRIP_NOPS (dest);
8402 srctype = TREE_TYPE (TREE_TYPE (src));
8403 desttype = TREE_TYPE (TREE_TYPE (dest));
8404 if (!srctype || !desttype
8405 || !TYPE_SIZE_UNIT (srctype)
8406 || !TYPE_SIZE_UNIT (desttype)
8407 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
8408 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
8409 || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
8410 || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8411 return 0;
8413 if (get_pointer_alignment (dest, BIGGEST_ALIGNMENT)
8414 < (int) TYPE_ALIGN (desttype)
8415 || (get_pointer_alignment (src, BIGGEST_ALIGNMENT)
8416 < (int) TYPE_ALIGN (srctype)))
8417 return 0;
8419 if (!ignore)
8420 dest = builtin_save_expr (dest);
8422 srcvar = build_fold_indirect_ref (src);
8423 if (TREE_THIS_VOLATILE (srcvar))
8424 return 0;
8425 if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
8426 return 0;
8427 /* With memcpy, it is possible to bypass aliasing rules, so without
8428 this check i. e. execute/20060930-2.c would be misoptimized, because
8429 it use conflicting alias set to hold argument for the memcpy call.
8430 This check is probably unnecesary with -fno-strict-aliasing.
8431 Similarly for destvar. See also PR29286. */
8432 if (!var_decl_component_p (srcvar)
8433 /* Accept: memcpy (*char_var, "test", 1); that simplify
8434 to char_var='t'; */
8435 || is_gimple_min_invariant (srcvar)
8436 || readonly_data_expr (src))
8437 return 0;
8439 destvar = build_fold_indirect_ref (dest);
8440 if (TREE_THIS_VOLATILE (destvar))
8441 return 0;
8442 if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
8443 return 0;
8444 if (!var_decl_component_p (destvar))
8445 return 0;
8447 if (srctype == desttype
8448 || (gimple_in_ssa_p (cfun)
8449 && tree_ssa_useless_type_conversion_1 (desttype, srctype)))
8450 expr = srcvar;
8451 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8452 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8453 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8454 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8455 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8456 else
8457 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8458 expr = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (destvar), destvar, expr);
8461 if (ignore)
8462 return expr;
8464 if (endp == 0 || endp == 3)
8465 return omit_one_operand (type, dest, expr);
8467 if (expr == len)
8468 expr = 0;
8470 if (endp == 2)
8471 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8472 ssize_int (1));
8474 len = fold_convert (TREE_TYPE (dest), len);
8475 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8476 dest = fold_convert (type, dest);
8477 if (expr)
8478 dest = omit_one_operand (type, dest, expr);
8479 return dest;
8482 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8483 simplification can be made. */
8485 static tree
8486 fold_builtin_bcopy (tree arglist, bool ignore)
8488 tree src, dest, size, newarglist;
8490 if (!validate_arglist (arglist,
8491 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8492 return 0;
8494 if (! ignore)
8495 return 0;
8497 src = TREE_VALUE (arglist);
8498 dest = TREE_VALUE (TREE_CHAIN (arglist));
8499 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8501 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8502 memmove(ptr y, ptr x, size_t z). This is done this way
8503 so that if it isn't expanded inline, we fallback to
8504 calling bcopy instead of memmove. */
8506 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8507 newarglist = tree_cons (NULL_TREE, src, newarglist);
8508 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8510 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8513 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8514 the length of the string to be copied. Return NULL_TREE if no
8515 simplification can be made. */
8517 tree
8518 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8520 tree dest, src, fn;
8522 if (!validate_arglist (arglist,
8523 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8524 return 0;
8526 dest = TREE_VALUE (arglist);
8527 src = TREE_VALUE (TREE_CHAIN (arglist));
8529 /* If SRC and DEST are the same (and not volatile), return DEST. */
8530 if (operand_equal_p (src, dest, 0))
8531 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8533 if (optimize_size)
8534 return 0;
8536 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8537 if (!fn)
8538 return 0;
8540 if (!len)
8542 len = c_strlen (src, 1);
8543 if (! len || TREE_SIDE_EFFECTS (len))
8544 return 0;
8547 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8548 arglist = build_tree_list (NULL_TREE, len);
8549 arglist = tree_cons (NULL_TREE, src, arglist);
8550 arglist = tree_cons (NULL_TREE, dest, arglist);
8551 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8552 build_function_call_expr (fn, arglist));
8555 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8556 the length of the source string. Return NULL_TREE if no simplification
8557 can be made. */
8559 tree
8560 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8562 tree dest, src, len, fn;
8564 if (!validate_arglist (arglist,
8565 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8566 return 0;
8568 dest = TREE_VALUE (arglist);
8569 src = TREE_VALUE (TREE_CHAIN (arglist));
8570 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8572 /* If the LEN parameter is zero, return DEST. */
8573 if (integer_zerop (len))
8574 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8576 /* We can't compare slen with len as constants below if len is not a
8577 constant. */
8578 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8579 return 0;
8581 if (!slen)
8582 slen = c_strlen (src, 1);
8584 /* Now, we must be passed a constant src ptr parameter. */
8585 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8586 return 0;
8588 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8590 /* We do not support simplification of this case, though we do
8591 support it when expanding trees into RTL. */
8592 /* FIXME: generate a call to __builtin_memset. */
8593 if (tree_int_cst_lt (slen, len))
8594 return 0;
8596 /* OK transform into builtin memcpy. */
8597 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8598 if (!fn)
8599 return 0;
8600 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8601 build_function_call_expr (fn, arglist));
8604 /* Fold function call to builtin memcmp. Return
8605 NULL_TREE if no simplification can be made. */
8607 static tree
8608 fold_builtin_memcmp (tree arglist)
8610 tree arg1, arg2, len;
8611 const char *p1, *p2;
8613 if (!validate_arglist (arglist,
8614 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8615 return 0;
8617 arg1 = TREE_VALUE (arglist);
8618 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8619 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8621 /* If the LEN parameter is zero, return zero. */
8622 if (integer_zerop (len))
8623 return omit_two_operands (integer_type_node, integer_zero_node,
8624 arg1, arg2);
8626 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8627 if (operand_equal_p (arg1, arg2, 0))
8628 return omit_one_operand (integer_type_node, integer_zero_node, len);
8630 p1 = c_getstr (arg1);
8631 p2 = c_getstr (arg2);
8633 /* If all arguments are constant, and the value of len is not greater
8634 than the lengths of arg1 and arg2, evaluate at compile-time. */
8635 if (host_integerp (len, 1) && p1 && p2
8636 && compare_tree_int (len, strlen (p1) + 1) <= 0
8637 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8639 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8641 if (r > 0)
8642 return integer_one_node;
8643 else if (r < 0)
8644 return integer_minus_one_node;
8645 else
8646 return integer_zero_node;
8649 /* If len parameter is one, return an expression corresponding to
8650 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8651 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8653 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8654 tree cst_uchar_ptr_node
8655 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8657 tree ind1 = fold_convert (integer_type_node,
8658 build1 (INDIRECT_REF, cst_uchar_node,
8659 fold_convert (cst_uchar_ptr_node,
8660 arg1)));
8661 tree ind2 = fold_convert (integer_type_node,
8662 build1 (INDIRECT_REF, cst_uchar_node,
8663 fold_convert (cst_uchar_ptr_node,
8664 arg2)));
8665 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8668 return 0;
8671 /* Fold function call to builtin strcmp. Return
8672 NULL_TREE if no simplification can be made. */
8674 static tree
8675 fold_builtin_strcmp (tree arglist)
8677 tree arg1, arg2;
8678 const char *p1, *p2;
8680 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8681 return 0;
8683 arg1 = TREE_VALUE (arglist);
8684 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8686 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8687 if (operand_equal_p (arg1, arg2, 0))
8688 return integer_zero_node;
8690 p1 = c_getstr (arg1);
8691 p2 = c_getstr (arg2);
8693 if (p1 && p2)
8695 const int i = strcmp (p1, p2);
8696 if (i < 0)
8697 return integer_minus_one_node;
8698 else if (i > 0)
8699 return integer_one_node;
8700 else
8701 return integer_zero_node;
8704 /* If the second arg is "", return *(const unsigned char*)arg1. */
8705 if (p2 && *p2 == '\0')
8707 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8708 tree cst_uchar_ptr_node
8709 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8711 return fold_convert (integer_type_node,
8712 build1 (INDIRECT_REF, cst_uchar_node,
8713 fold_convert (cst_uchar_ptr_node,
8714 arg1)));
8717 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8718 if (p1 && *p1 == '\0')
8720 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8721 tree cst_uchar_ptr_node
8722 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8724 tree temp = fold_convert (integer_type_node,
8725 build1 (INDIRECT_REF, cst_uchar_node,
8726 fold_convert (cst_uchar_ptr_node,
8727 arg2)));
8728 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8731 return 0;
8734 /* Fold function call to builtin strncmp. Return
8735 NULL_TREE if no simplification can be made. */
8737 static tree
8738 fold_builtin_strncmp (tree arglist)
8740 tree arg1, arg2, len;
8741 const char *p1, *p2;
8743 if (!validate_arglist (arglist,
8744 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8745 return 0;
8747 arg1 = TREE_VALUE (arglist);
8748 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8749 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8751 /* If the LEN parameter is zero, return zero. */
8752 if (integer_zerop (len))
8753 return omit_two_operands (integer_type_node, integer_zero_node,
8754 arg1, arg2);
8756 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8757 if (operand_equal_p (arg1, arg2, 0))
8758 return omit_one_operand (integer_type_node, integer_zero_node, len);
8760 p1 = c_getstr (arg1);
8761 p2 = c_getstr (arg2);
8763 if (host_integerp (len, 1) && p1 && p2)
8765 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8766 if (i > 0)
8767 return integer_one_node;
8768 else if (i < 0)
8769 return integer_minus_one_node;
8770 else
8771 return integer_zero_node;
8774 /* If the second arg is "", and the length is greater than zero,
8775 return *(const unsigned char*)arg1. */
8776 if (p2 && *p2 == '\0'
8777 && TREE_CODE (len) == INTEGER_CST
8778 && tree_int_cst_sgn (len) == 1)
8780 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8781 tree cst_uchar_ptr_node
8782 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8784 return fold_convert (integer_type_node,
8785 build1 (INDIRECT_REF, cst_uchar_node,
8786 fold_convert (cst_uchar_ptr_node,
8787 arg1)));
8790 /* If the first arg is "", and the length is greater than zero,
8791 return -*(const unsigned char*)arg2. */
8792 if (p1 && *p1 == '\0'
8793 && TREE_CODE (len) == INTEGER_CST
8794 && tree_int_cst_sgn (len) == 1)
8796 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8797 tree cst_uchar_ptr_node
8798 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8800 tree temp = fold_convert (integer_type_node,
8801 build1 (INDIRECT_REF, cst_uchar_node,
8802 fold_convert (cst_uchar_ptr_node,
8803 arg2)));
8804 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8807 /* If len parameter is one, return an expression corresponding to
8808 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8809 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8811 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8812 tree cst_uchar_ptr_node
8813 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8815 tree ind1 = fold_convert (integer_type_node,
8816 build1 (INDIRECT_REF, cst_uchar_node,
8817 fold_convert (cst_uchar_ptr_node,
8818 arg1)));
8819 tree ind2 = fold_convert (integer_type_node,
8820 build1 (INDIRECT_REF, cst_uchar_node,
8821 fold_convert (cst_uchar_ptr_node,
8822 arg2)));
8823 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8826 return 0;
8829 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8830 NULL_TREE if no simplification can be made. */
8832 static tree
8833 fold_builtin_signbit (tree fndecl, tree arglist)
8835 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8836 tree arg, temp;
8838 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8839 return NULL_TREE;
8841 arg = TREE_VALUE (arglist);
8843 /* If ARG is a compile-time constant, determine the result. */
8844 if (TREE_CODE (arg) == REAL_CST
8845 && !TREE_OVERFLOW (arg))
8847 REAL_VALUE_TYPE c;
8849 c = TREE_REAL_CST (arg);
8850 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8851 return fold_convert (type, temp);
8854 /* If ARG is non-negative, the result is always zero. */
8855 if (tree_expr_nonnegative_p (arg))
8856 return omit_one_operand (type, integer_zero_node, arg);
8858 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8859 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8860 return fold_build2 (LT_EXPR, type, arg,
8861 build_real (TREE_TYPE (arg), dconst0));
8863 return NULL_TREE;
8866 /* Fold function call to builtin copysign, copysignf or copysignl.
8867 Return NULL_TREE if no simplification can be made. */
8869 static tree
8870 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8872 tree arg1, arg2, tem;
8874 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8875 return NULL_TREE;
8877 arg1 = TREE_VALUE (arglist);
8878 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8880 /* copysign(X,X) is X. */
8881 if (operand_equal_p (arg1, arg2, 0))
8882 return fold_convert (type, arg1);
8884 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8885 if (TREE_CODE (arg1) == REAL_CST
8886 && TREE_CODE (arg2) == REAL_CST
8887 && !TREE_OVERFLOW (arg1)
8888 && !TREE_OVERFLOW (arg2))
8890 REAL_VALUE_TYPE c1, c2;
8892 c1 = TREE_REAL_CST (arg1);
8893 c2 = TREE_REAL_CST (arg2);
8894 /* c1.sign := c2.sign. */
8895 real_copysign (&c1, &c2);
8896 return build_real (type, c1);
8899 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8900 Remember to evaluate Y for side-effects. */
8901 if (tree_expr_nonnegative_p (arg2))
8902 return omit_one_operand (type,
8903 fold_build1 (ABS_EXPR, type, arg1),
8904 arg2);
8906 /* Strip sign changing operations for the first argument. */
8907 tem = fold_strip_sign_ops (arg1);
8908 if (tem)
8910 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8911 return build_function_call_expr (fndecl, arglist);
8914 return NULL_TREE;
8917 /* Fold a call to builtin isascii. */
8919 static tree
8920 fold_builtin_isascii (tree arglist)
8922 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8923 return 0;
8924 else
8926 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8927 tree arg = TREE_VALUE (arglist);
8929 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8930 build_int_cst (NULL_TREE,
8931 ~ (unsigned HOST_WIDE_INT) 0x7f));
8932 return fold_build2 (EQ_EXPR, integer_type_node,
8933 arg, integer_zero_node);
8937 /* Fold a call to builtin toascii. */
8939 static tree
8940 fold_builtin_toascii (tree arglist)
8942 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8943 return 0;
8944 else
8946 /* Transform toascii(c) -> (c & 0x7f). */
8947 tree arg = TREE_VALUE (arglist);
8949 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8950 build_int_cst (NULL_TREE, 0x7f));
8954 /* Fold a call to builtin isdigit. */
8956 static tree
8957 fold_builtin_isdigit (tree arglist)
8959 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8960 return 0;
8961 else
8963 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8964 /* According to the C standard, isdigit is unaffected by locale.
8965 However, it definitely is affected by the target character set. */
8966 tree arg;
8967 unsigned HOST_WIDE_INT target_digit0
8968 = lang_hooks.to_target_charset ('0');
8970 if (target_digit0 == 0)
8971 return NULL_TREE;
8973 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8974 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8975 build_int_cst (unsigned_type_node, target_digit0));
8976 return fold_build2 (LE_EXPR, integer_type_node, arg,
8977 build_int_cst (unsigned_type_node, 9));
8981 /* Fold a call to fabs, fabsf or fabsl. */
8983 static tree
8984 fold_builtin_fabs (tree arglist, tree type)
8986 tree arg;
8988 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8989 return 0;
8991 arg = TREE_VALUE (arglist);
8992 arg = fold_convert (type, arg);
8993 if (TREE_CODE (arg) == REAL_CST)
8994 return fold_abs_const (arg, type);
8995 return fold_build1 (ABS_EXPR, type, arg);
8998 /* Fold a call to abs, labs, llabs or imaxabs. */
9000 static tree
9001 fold_builtin_abs (tree arglist, tree type)
9003 tree arg;
9005 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
9006 return 0;
9008 arg = TREE_VALUE (arglist);
9009 arg = fold_convert (type, arg);
9010 if (TREE_CODE (arg) == INTEGER_CST)
9011 return fold_abs_const (arg, type);
9012 return fold_build1 (ABS_EXPR, type, arg);
9015 /* Fold a call to builtin fmin or fmax. */
9017 static tree
9018 fold_builtin_fmin_fmax (tree arglist, tree type, bool max)
9020 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9022 tree arg0 = TREE_VALUE (arglist);
9023 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
9024 /* Calculate the result when the argument is a constant. */
9025 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9027 if (res)
9028 return res;
9030 /* If either argument is NaN, return the other one. Avoid the
9031 transformation if we get (and honor) a signalling NaN. Using
9032 omit_one_operand() ensures we create a non-lvalue. */
9033 if (TREE_CODE (arg0) == REAL_CST
9034 && real_isnan (&TREE_REAL_CST (arg0))
9035 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9036 || ! TREE_REAL_CST (arg0).signalling))
9037 return omit_one_operand (type, arg1, arg0);
9038 if (TREE_CODE (arg1) == REAL_CST
9039 && real_isnan (&TREE_REAL_CST (arg1))
9040 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9041 || ! TREE_REAL_CST (arg1).signalling))
9042 return omit_one_operand (type, arg0, arg1);
9044 /* Transform fmin/fmax(x,x) -> x. */
9045 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9046 return omit_one_operand (type, arg0, arg1);
9048 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9049 functions to return the numeric arg if the other one is NaN.
9050 These tree codes don't honor that, so only transform if
9051 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9052 handled, so we don't have to worry about it either. */
9053 if (flag_finite_math_only)
9054 return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
9055 fold_convert (type, arg0),
9056 fold_convert (type, arg1));
9058 return NULL_TREE;
9061 /* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
9063 static tree
9064 fold_builtin_carg(tree arglist, tree type)
9066 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9068 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9070 if (atan2_fn)
9072 tree arg = builtin_save_expr (TREE_VALUE (arglist));
9073 tree r_arg = fold_build1 (REALPART_EXPR, type, arg);
9074 tree i_arg = fold_build1 (IMAGPART_EXPR, type, arg);
9075 tree newarglist = tree_cons (NULL_TREE, i_arg,
9076 build_tree_list (NULL_TREE, r_arg));
9077 return build_function_call_expr (atan2_fn, newarglist);
9081 return NULL_TREE;
9084 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9085 EXP is the CALL_EXPR for the call. */
9087 static tree
9088 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
9090 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9091 tree arg;
9092 REAL_VALUE_TYPE r;
9094 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9096 /* Check that we have exactly one argument. */
9097 if (arglist == 0)
9099 error ("too few arguments to function %qs",
9100 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9101 return error_mark_node;
9103 else if (TREE_CHAIN (arglist) != 0)
9105 error ("too many arguments to function %qs",
9106 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9107 return error_mark_node;
9109 else
9111 error ("non-floating-point argument to function %qs",
9112 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9113 return error_mark_node;
9117 arg = TREE_VALUE (arglist);
9118 switch (builtin_index)
9120 case BUILT_IN_ISINF:
9121 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9122 return omit_one_operand (type, integer_zero_node, arg);
9124 if (TREE_CODE (arg) == REAL_CST)
9126 r = TREE_REAL_CST (arg);
9127 if (real_isinf (&r))
9128 return real_compare (GT_EXPR, &r, &dconst0)
9129 ? integer_one_node : integer_minus_one_node;
9130 else
9131 return integer_zero_node;
9134 return NULL_TREE;
9136 case BUILT_IN_FINITE:
9137 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9138 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9139 return omit_one_operand (type, integer_one_node, arg);
9141 if (TREE_CODE (arg) == REAL_CST)
9143 r = TREE_REAL_CST (arg);
9144 return real_isinf (&r) || real_isnan (&r)
9145 ? integer_zero_node : integer_one_node;
9148 return NULL_TREE;
9150 case BUILT_IN_ISNAN:
9151 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
9152 return omit_one_operand (type, integer_zero_node, arg);
9154 if (TREE_CODE (arg) == REAL_CST)
9156 r = TREE_REAL_CST (arg);
9157 return real_isnan (&r) ? integer_one_node : integer_zero_node;
9160 arg = builtin_save_expr (arg);
9161 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
9163 default:
9164 gcc_unreachable ();
9168 /* Fold a call to an unordered comparison function such as
9169 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
9170 being called and ARGLIST is the argument list for the call.
9171 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9172 the opposite of the desired result. UNORDERED_CODE is used
9173 for modes that can hold NaNs and ORDERED_CODE is used for
9174 the rest. */
9176 static tree
9177 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
9178 enum tree_code unordered_code,
9179 enum tree_code ordered_code)
9181 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9182 enum tree_code code;
9183 tree arg0, arg1;
9184 tree type0, type1;
9185 enum tree_code code0, code1;
9186 tree cmp_type = NULL_TREE;
9188 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9190 /* Check that we have exactly two arguments. */
9191 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
9193 error ("too few arguments to function %qs",
9194 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9195 return error_mark_node;
9197 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
9199 error ("too many arguments to function %qs",
9200 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9201 return error_mark_node;
9205 arg0 = TREE_VALUE (arglist);
9206 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
9208 type0 = TREE_TYPE (arg0);
9209 type1 = TREE_TYPE (arg1);
9211 code0 = TREE_CODE (type0);
9212 code1 = TREE_CODE (type1);
9214 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
9215 /* Choose the wider of two real types. */
9216 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
9217 ? type0 : type1;
9218 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
9219 cmp_type = type0;
9220 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
9221 cmp_type = type1;
9222 else
9224 error ("non-floating-point argument to function %qs",
9225 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9226 return error_mark_node;
9229 arg0 = fold_convert (cmp_type, arg0);
9230 arg1 = fold_convert (cmp_type, arg1);
9232 if (unordered_code == UNORDERED_EXPR)
9234 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
9235 return omit_two_operands (type, integer_zero_node, arg0, arg1);
9236 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
9239 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9240 : ordered_code;
9241 return fold_build1 (TRUTH_NOT_EXPR, type,
9242 fold_build2 (code, type, arg0, arg1));
9245 /* Used by constant folding to simplify calls to builtin functions. EXP is
9246 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
9247 result of the function call is ignored. This function returns NULL_TREE
9248 if no simplification was possible. */
9250 static tree
9251 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
9253 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9254 enum built_in_function fcode;
9256 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
9257 return targetm.fold_builtin (fndecl, arglist, ignore);
9259 fcode = DECL_FUNCTION_CODE (fndecl);
9260 switch (fcode)
9262 case BUILT_IN_FPUTS:
9263 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
9265 case BUILT_IN_FPUTS_UNLOCKED:
9266 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
9268 case BUILT_IN_STRSTR:
9269 return fold_builtin_strstr (arglist, type);
9271 case BUILT_IN_STRCAT:
9272 return fold_builtin_strcat (arglist);
9274 case BUILT_IN_STRNCAT:
9275 return fold_builtin_strncat (arglist);
9277 case BUILT_IN_STRSPN:
9278 return fold_builtin_strspn (arglist);
9280 case BUILT_IN_STRCSPN:
9281 return fold_builtin_strcspn (arglist);
9283 case BUILT_IN_STRCHR:
9284 case BUILT_IN_INDEX:
9285 return fold_builtin_strchr (arglist, type);
9287 case BUILT_IN_STRRCHR:
9288 case BUILT_IN_RINDEX:
9289 return fold_builtin_strrchr (arglist, type);
9291 case BUILT_IN_STRCPY:
9292 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
9294 case BUILT_IN_STRNCPY:
9295 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
9297 case BUILT_IN_STRCMP:
9298 return fold_builtin_strcmp (arglist);
9300 case BUILT_IN_STRNCMP:
9301 return fold_builtin_strncmp (arglist);
9303 case BUILT_IN_STRPBRK:
9304 return fold_builtin_strpbrk (arglist, type);
9306 case BUILT_IN_BCMP:
9307 case BUILT_IN_MEMCMP:
9308 return fold_builtin_memcmp (arglist);
9310 case BUILT_IN_SPRINTF:
9311 return fold_builtin_sprintf (arglist, ignore);
9313 case BUILT_IN_CONSTANT_P:
9315 tree val;
9317 val = fold_builtin_constant_p (arglist);
9318 /* Gimplification will pull the CALL_EXPR for the builtin out of
9319 an if condition. When not optimizing, we'll not CSE it back.
9320 To avoid link error types of regressions, return false now. */
9321 if (!val && !optimize)
9322 val = integer_zero_node;
9324 return val;
9327 case BUILT_IN_EXPECT:
9328 return fold_builtin_expect (arglist);
9330 case BUILT_IN_CLASSIFY_TYPE:
9331 return fold_builtin_classify_type (arglist);
9333 case BUILT_IN_STRLEN:
9334 return fold_builtin_strlen (arglist);
9336 CASE_FLT_FN (BUILT_IN_FABS):
9337 return fold_builtin_fabs (arglist, type);
9339 case BUILT_IN_ABS:
9340 case BUILT_IN_LABS:
9341 case BUILT_IN_LLABS:
9342 case BUILT_IN_IMAXABS:
9343 return fold_builtin_abs (arglist, type);
9345 CASE_FLT_FN (BUILT_IN_CONJ):
9346 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9347 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
9348 break;
9350 CASE_FLT_FN (BUILT_IN_CREAL):
9351 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9352 return non_lvalue (fold_build1 (REALPART_EXPR, type,
9353 TREE_VALUE (arglist)));
9354 break;
9356 CASE_FLT_FN (BUILT_IN_CIMAG):
9357 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9358 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
9359 TREE_VALUE (arglist)));
9360 break;
9362 CASE_FLT_FN (BUILT_IN_CCOS):
9363 CASE_FLT_FN (BUILT_IN_CCOSH):
9364 /* These functions are "even", i.e. f(x) == f(-x). */
9365 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9367 tree narg = fold_strip_sign_ops (TREE_VALUE (arglist));
9368 if (narg)
9369 return build_function_call_expr (fndecl,
9370 build_tree_list (NULL_TREE, narg));
9372 break;
9374 CASE_FLT_FN (BUILT_IN_CABS):
9375 return fold_builtin_cabs (arglist, type, fndecl);
9377 CASE_FLT_FN (BUILT_IN_CARG):
9378 return fold_builtin_carg (arglist, type);
9380 CASE_FLT_FN (BUILT_IN_SQRT):
9381 return fold_builtin_sqrt (arglist, type);
9383 CASE_FLT_FN (BUILT_IN_CBRT):
9384 return fold_builtin_cbrt (arglist, type);
9386 CASE_FLT_FN (BUILT_IN_ASIN):
9387 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9388 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asin,
9389 &dconstm1, &dconst1, true);
9390 break;
9392 CASE_FLT_FN (BUILT_IN_ACOS):
9393 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9394 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acos,
9395 &dconstm1, &dconst1, true);
9396 break;
9398 CASE_FLT_FN (BUILT_IN_ATAN):
9399 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9400 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atan,
9401 NULL, NULL, 0);
9402 break;
9404 CASE_FLT_FN (BUILT_IN_ASINH):
9405 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9406 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asinh,
9407 NULL, NULL, 0);
9408 break;
9410 CASE_FLT_FN (BUILT_IN_ACOSH):
9411 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9412 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acosh,
9413 &dconst1, NULL, true);
9414 break;
9416 CASE_FLT_FN (BUILT_IN_ATANH):
9417 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9418 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atanh,
9419 &dconstm1, &dconst1, false);
9420 break;
9422 CASE_FLT_FN (BUILT_IN_SIN):
9423 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9424 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sin,
9425 NULL, NULL, 0);
9426 break;
9428 CASE_FLT_FN (BUILT_IN_COS):
9429 return fold_builtin_cos (arglist, type, fndecl);
9431 CASE_FLT_FN (BUILT_IN_TAN):
9432 return fold_builtin_tan (arglist, type);
9434 CASE_FLT_FN (BUILT_IN_SINCOS):
9435 return fold_builtin_sincos (arglist);
9437 CASE_FLT_FN (BUILT_IN_CEXP):
9438 return fold_builtin_cexp (arglist, type);
9440 CASE_FLT_FN (BUILT_IN_CEXPI):
9441 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9442 return do_mpfr_sincos (TREE_VALUE (arglist), NULL_TREE, NULL_TREE);
9444 CASE_FLT_FN (BUILT_IN_SINH):
9445 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9446 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sinh,
9447 NULL, NULL, 0);
9448 break;
9450 CASE_FLT_FN (BUILT_IN_COSH):
9451 return fold_builtin_cosh (arglist, type, fndecl);
9453 CASE_FLT_FN (BUILT_IN_TANH):
9454 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9455 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_tanh,
9456 NULL, NULL, 0);
9457 break;
9459 CASE_FLT_FN (BUILT_IN_ERF):
9460 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9461 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erf,
9462 NULL, NULL, 0);
9463 break;
9465 CASE_FLT_FN (BUILT_IN_ERFC):
9466 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9467 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erfc,
9468 NULL, NULL, 0);
9469 break;
9471 CASE_FLT_FN (BUILT_IN_TGAMMA):
9472 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9473 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_gamma,
9474 NULL, NULL, 0);
9475 break;
9477 CASE_FLT_FN (BUILT_IN_EXP):
9478 return fold_builtin_exponent (fndecl, arglist, mpfr_exp);
9480 CASE_FLT_FN (BUILT_IN_EXP2):
9481 return fold_builtin_exponent (fndecl, arglist, mpfr_exp2);
9483 CASE_FLT_FN (BUILT_IN_EXP10):
9484 CASE_FLT_FN (BUILT_IN_POW10):
9485 return fold_builtin_exponent (fndecl, arglist, mpfr_exp10);
9487 CASE_FLT_FN (BUILT_IN_EXPM1):
9488 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9489 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_expm1,
9490 NULL, NULL, 0);
9491 break;
9493 CASE_FLT_FN (BUILT_IN_LOG):
9494 return fold_builtin_logarithm (fndecl, arglist, mpfr_log);
9496 CASE_FLT_FN (BUILT_IN_LOG2):
9497 return fold_builtin_logarithm (fndecl, arglist, mpfr_log2);
9499 CASE_FLT_FN (BUILT_IN_LOG10):
9500 return fold_builtin_logarithm (fndecl, arglist, mpfr_log10);
9502 CASE_FLT_FN (BUILT_IN_LOG1P):
9503 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9504 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_log1p,
9505 &dconstm1, NULL, false);
9506 break;
9508 CASE_FLT_FN (BUILT_IN_ATAN2):
9509 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9510 return do_mpfr_arg2 (TREE_VALUE (arglist),
9511 TREE_VALUE (TREE_CHAIN (arglist)),
9512 type, mpfr_atan2);
9513 break;
9515 CASE_FLT_FN (BUILT_IN_FDIM):
9516 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9517 return do_mpfr_arg2 (TREE_VALUE (arglist),
9518 TREE_VALUE (TREE_CHAIN (arglist)),
9519 type, mpfr_dim);
9520 break;
9522 CASE_FLT_FN (BUILT_IN_FMA):
9523 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9524 return do_mpfr_arg3 (TREE_VALUE (arglist),
9525 TREE_VALUE (TREE_CHAIN (arglist)),
9526 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
9527 type, mpfr_fma);
9528 break;
9530 CASE_FLT_FN (BUILT_IN_FMIN):
9531 return fold_builtin_fmin_fmax (arglist, type, /*max=*/false);
9533 CASE_FLT_FN (BUILT_IN_FMAX):
9534 return fold_builtin_fmin_fmax (arglist, type, /*max=*/true);
9536 CASE_FLT_FN (BUILT_IN_HYPOT):
9537 return fold_builtin_hypot (fndecl, arglist, type);
9539 CASE_FLT_FN (BUILT_IN_POW):
9540 return fold_builtin_pow (fndecl, arglist, type);
9542 CASE_FLT_FN (BUILT_IN_POWI):
9543 return fold_builtin_powi (fndecl, arglist, type);
9545 CASE_FLT_FN (BUILT_IN_INF):
9546 case BUILT_IN_INFD32:
9547 case BUILT_IN_INFD64:
9548 case BUILT_IN_INFD128:
9549 return fold_builtin_inf (type, true);
9551 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9552 return fold_builtin_inf (type, false);
9554 CASE_FLT_FN (BUILT_IN_NAN):
9555 case BUILT_IN_NAND32:
9556 case BUILT_IN_NAND64:
9557 case BUILT_IN_NAND128:
9558 return fold_builtin_nan (arglist, type, true);
9560 CASE_FLT_FN (BUILT_IN_NANS):
9561 return fold_builtin_nan (arglist, type, false);
9563 CASE_FLT_FN (BUILT_IN_FLOOR):
9564 return fold_builtin_floor (fndecl, arglist);
9566 CASE_FLT_FN (BUILT_IN_CEIL):
9567 return fold_builtin_ceil (fndecl, arglist);
9569 CASE_FLT_FN (BUILT_IN_TRUNC):
9570 return fold_builtin_trunc (fndecl, arglist);
9572 CASE_FLT_FN (BUILT_IN_ROUND):
9573 return fold_builtin_round (fndecl, arglist);
9575 CASE_FLT_FN (BUILT_IN_NEARBYINT):
9576 CASE_FLT_FN (BUILT_IN_RINT):
9577 return fold_trunc_transparent_mathfn (fndecl, arglist);
9579 CASE_FLT_FN (BUILT_IN_LCEIL):
9580 CASE_FLT_FN (BUILT_IN_LLCEIL):
9581 CASE_FLT_FN (BUILT_IN_LFLOOR):
9582 CASE_FLT_FN (BUILT_IN_LLFLOOR):
9583 CASE_FLT_FN (BUILT_IN_LROUND):
9584 CASE_FLT_FN (BUILT_IN_LLROUND):
9585 return fold_builtin_int_roundingfn (fndecl, arglist);
9587 CASE_FLT_FN (BUILT_IN_LRINT):
9588 CASE_FLT_FN (BUILT_IN_LLRINT):
9589 return fold_fixed_mathfn (fndecl, arglist);
9591 case BUILT_IN_BSWAP32:
9592 case BUILT_IN_BSWAP64:
9593 return fold_builtin_bswap (fndecl, arglist);
9595 CASE_INT_FN (BUILT_IN_FFS):
9596 CASE_INT_FN (BUILT_IN_CLZ):
9597 CASE_INT_FN (BUILT_IN_CTZ):
9598 CASE_INT_FN (BUILT_IN_POPCOUNT):
9599 CASE_INT_FN (BUILT_IN_PARITY):
9600 return fold_builtin_bitop (fndecl, arglist);
9602 case BUILT_IN_MEMSET:
9603 return fold_builtin_memset (arglist, type, ignore);
9605 case BUILT_IN_MEMCPY:
9606 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9608 case BUILT_IN_MEMPCPY:
9609 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9611 case BUILT_IN_MEMMOVE:
9612 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9614 case BUILT_IN_BZERO:
9615 return fold_builtin_bzero (arglist, ignore);
9617 case BUILT_IN_BCOPY:
9618 return fold_builtin_bcopy (arglist, ignore);
9620 CASE_FLT_FN (BUILT_IN_SIGNBIT):
9621 return fold_builtin_signbit (fndecl, arglist);
9623 case BUILT_IN_ISASCII:
9624 return fold_builtin_isascii (arglist);
9626 case BUILT_IN_TOASCII:
9627 return fold_builtin_toascii (arglist);
9629 case BUILT_IN_ISDIGIT:
9630 return fold_builtin_isdigit (arglist);
9632 CASE_FLT_FN (BUILT_IN_COPYSIGN):
9633 return fold_builtin_copysign (fndecl, arglist, type);
9635 CASE_FLT_FN (BUILT_IN_FINITE):
9636 case BUILT_IN_FINITED32:
9637 case BUILT_IN_FINITED64:
9638 case BUILT_IN_FINITED128:
9639 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9641 CASE_FLT_FN (BUILT_IN_ISINF):
9642 case BUILT_IN_ISINFD32:
9643 case BUILT_IN_ISINFD64:
9644 case BUILT_IN_ISINFD128:
9645 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9647 CASE_FLT_FN (BUILT_IN_ISNAN):
9648 case BUILT_IN_ISNAND32:
9649 case BUILT_IN_ISNAND64:
9650 case BUILT_IN_ISNAND128:
9651 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9653 case BUILT_IN_ISGREATER:
9654 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9655 case BUILT_IN_ISGREATEREQUAL:
9656 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9657 case BUILT_IN_ISLESS:
9658 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9659 case BUILT_IN_ISLESSEQUAL:
9660 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9661 case BUILT_IN_ISLESSGREATER:
9662 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9663 case BUILT_IN_ISUNORDERED:
9664 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9665 NOP_EXPR);
9667 /* We do the folding for va_start in the expander. */
9668 case BUILT_IN_VA_START:
9669 break;
9671 case BUILT_IN_OBJECT_SIZE:
9672 return fold_builtin_object_size (arglist);
9673 case BUILT_IN_MEMCPY_CHK:
9674 case BUILT_IN_MEMPCPY_CHK:
9675 case BUILT_IN_MEMMOVE_CHK:
9676 case BUILT_IN_MEMSET_CHK:
9677 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9678 DECL_FUNCTION_CODE (fndecl));
9679 case BUILT_IN_STRCPY_CHK:
9680 case BUILT_IN_STPCPY_CHK:
9681 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9682 DECL_FUNCTION_CODE (fndecl));
9683 case BUILT_IN_STRNCPY_CHK:
9684 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9685 case BUILT_IN_STRCAT_CHK:
9686 return fold_builtin_strcat_chk (fndecl, arglist);
9687 case BUILT_IN_STRNCAT_CHK:
9688 return fold_builtin_strncat_chk (fndecl, arglist);
9689 case BUILT_IN_SPRINTF_CHK:
9690 case BUILT_IN_VSPRINTF_CHK:
9691 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9692 case BUILT_IN_SNPRINTF_CHK:
9693 case BUILT_IN_VSNPRINTF_CHK:
9694 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9695 DECL_FUNCTION_CODE (fndecl));
9697 case BUILT_IN_PRINTF:
9698 case BUILT_IN_PRINTF_UNLOCKED:
9699 case BUILT_IN_VPRINTF:
9700 case BUILT_IN_PRINTF_CHK:
9701 case BUILT_IN_VPRINTF_CHK:
9702 return fold_builtin_printf (fndecl, arglist, ignore,
9703 DECL_FUNCTION_CODE (fndecl));
9705 case BUILT_IN_FPRINTF:
9706 case BUILT_IN_FPRINTF_UNLOCKED:
9707 case BUILT_IN_VFPRINTF:
9708 case BUILT_IN_FPRINTF_CHK:
9709 case BUILT_IN_VFPRINTF_CHK:
9710 return fold_builtin_fprintf (fndecl, arglist, ignore,
9711 DECL_FUNCTION_CODE (fndecl));
9713 default:
9714 break;
9717 return 0;
9720 /* A wrapper function for builtin folding that prevents warnings for
9721 "statement without effect" and the like, caused by removing the
9722 call node earlier than the warning is generated. */
9724 tree
9725 fold_builtin (tree fndecl, tree arglist, bool ignore)
9727 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9728 if (exp && !ignore)
9730 exp = build1 (NOP_EXPR, GENERIC_TREE_TYPE (exp), exp);
9731 TREE_NO_WARNING (exp) = 1;
9734 return exp;
9737 /* Conveniently construct a function call expression. */
9739 tree
9740 build_function_call_expr (tree fn, tree arglist)
9742 tree call_expr;
9744 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9745 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9746 call_expr, arglist, NULL_TREE);
9749 /* This function validates the types of a function call argument list
9750 represented as a tree chain of parameters against a specified list
9751 of tree_codes. If the last specifier is a 0, that represents an
9752 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9755 validate_arglist (tree arglist, ...)
9757 enum tree_code code;
9758 int res = 0;
9759 va_list ap;
9761 va_start (ap, arglist);
9765 code = va_arg (ap, enum tree_code);
9766 switch (code)
9768 case 0:
9769 /* This signifies an ellipses, any further arguments are all ok. */
9770 res = 1;
9771 goto end;
9772 case VOID_TYPE:
9773 /* This signifies an endlink, if no arguments remain, return
9774 true, otherwise return false. */
9775 res = arglist == 0;
9776 goto end;
9777 default:
9778 /* If no parameters remain or the parameter's code does not
9779 match the specified code, return false. Otherwise continue
9780 checking any remaining arguments. */
9781 if (arglist == 0)
9782 goto end;
9783 if (code == POINTER_TYPE)
9785 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9786 goto end;
9788 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9789 goto end;
9790 break;
9792 arglist = TREE_CHAIN (arglist);
9794 while (1);
9796 /* We need gotos here since we can only have one VA_CLOSE in a
9797 function. */
9798 end: ;
9799 va_end (ap);
9801 return res;
9804 /* Default target-specific builtin expander that does nothing. */
9807 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9808 rtx target ATTRIBUTE_UNUSED,
9809 rtx subtarget ATTRIBUTE_UNUSED,
9810 enum machine_mode mode ATTRIBUTE_UNUSED,
9811 int ignore ATTRIBUTE_UNUSED)
9813 return NULL_RTX;
9816 /* Returns true is EXP represents data that would potentially reside
9817 in a readonly section. */
9819 static bool
9820 readonly_data_expr (tree exp)
9822 STRIP_NOPS (exp);
9824 if (TREE_CODE (exp) != ADDR_EXPR)
9825 return false;
9827 exp = get_base_address (TREE_OPERAND (exp, 0));
9828 if (!exp)
9829 return false;
9831 /* Make sure we call decl_readonly_section only for trees it
9832 can handle (since it returns true for everything it doesn't
9833 understand). */
9834 if (TREE_CODE (exp) == STRING_CST
9835 || TREE_CODE (exp) == CONSTRUCTOR
9836 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9837 return decl_readonly_section (exp, 0);
9838 else
9839 return false;
9842 /* Simplify a call to the strstr builtin.
9844 Return 0 if no simplification was possible, otherwise return the
9845 simplified form of the call as a tree.
9847 The simplified form may be a constant or other expression which
9848 computes the same value, but in a more efficient manner (including
9849 calls to other builtin functions).
9851 The call may contain arguments which need to be evaluated, but
9852 which are not useful to determine the result of the call. In
9853 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9854 COMPOUND_EXPR will be an argument which must be evaluated.
9855 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9856 COMPOUND_EXPR in the chain will contain the tree for the simplified
9857 form of the builtin function call. */
9859 static tree
9860 fold_builtin_strstr (tree arglist, tree type)
9862 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9863 return 0;
9864 else
9866 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9867 tree fn;
9868 const char *p1, *p2;
9870 p2 = c_getstr (s2);
9871 if (p2 == NULL)
9872 return 0;
9874 p1 = c_getstr (s1);
9875 if (p1 != NULL)
9877 const char *r = strstr (p1, p2);
9878 tree tem;
9880 if (r == NULL)
9881 return build_int_cst (TREE_TYPE (s1), 0);
9883 /* Return an offset into the constant string argument. */
9884 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9885 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9886 return fold_convert (type, tem);
9889 /* The argument is const char *, and the result is char *, so we need
9890 a type conversion here to avoid a warning. */
9891 if (p2[0] == '\0')
9892 return fold_convert (type, s1);
9894 if (p2[1] != '\0')
9895 return 0;
9897 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9898 if (!fn)
9899 return 0;
9901 /* New argument list transforming strstr(s1, s2) to
9902 strchr(s1, s2[0]). */
9903 arglist = build_tree_list (NULL_TREE,
9904 build_int_cst (NULL_TREE, p2[0]));
9905 arglist = tree_cons (NULL_TREE, s1, arglist);
9906 return build_function_call_expr (fn, arglist);
9910 /* Simplify a call to the strchr builtin.
9912 Return 0 if no simplification was possible, otherwise return the
9913 simplified form of the call as a tree.
9915 The simplified form may be a constant or other expression which
9916 computes the same value, but in a more efficient manner (including
9917 calls to other builtin functions).
9919 The call may contain arguments which need to be evaluated, but
9920 which are not useful to determine the result of the call. In
9921 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9922 COMPOUND_EXPR will be an argument which must be evaluated.
9923 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9924 COMPOUND_EXPR in the chain will contain the tree for the simplified
9925 form of the builtin function call. */
9927 static tree
9928 fold_builtin_strchr (tree arglist, tree type)
9930 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9931 return 0;
9932 else
9934 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9935 const char *p1;
9937 if (TREE_CODE (s2) != INTEGER_CST)
9938 return 0;
9940 p1 = c_getstr (s1);
9941 if (p1 != NULL)
9943 char c;
9944 const char *r;
9945 tree tem;
9947 if (target_char_cast (s2, &c))
9948 return 0;
9950 r = strchr (p1, c);
9952 if (r == NULL)
9953 return build_int_cst (TREE_TYPE (s1), 0);
9955 /* Return an offset into the constant string argument. */
9956 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9957 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9958 return fold_convert (type, tem);
9960 return 0;
9964 /* Simplify a call to the strrchr builtin.
9966 Return 0 if no simplification was possible, otherwise return the
9967 simplified form of the call as a tree.
9969 The simplified form may be a constant or other expression which
9970 computes the same value, but in a more efficient manner (including
9971 calls to other builtin functions).
9973 The call may contain arguments which need to be evaluated, but
9974 which are not useful to determine the result of the call. In
9975 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9976 COMPOUND_EXPR will be an argument which must be evaluated.
9977 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9978 COMPOUND_EXPR in the chain will contain the tree for the simplified
9979 form of the builtin function call. */
9981 static tree
9982 fold_builtin_strrchr (tree arglist, tree type)
9984 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9985 return 0;
9986 else
9988 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9989 tree fn;
9990 const char *p1;
9992 if (TREE_CODE (s2) != INTEGER_CST)
9993 return 0;
9995 p1 = c_getstr (s1);
9996 if (p1 != NULL)
9998 char c;
9999 const char *r;
10000 tree tem;
10002 if (target_char_cast (s2, &c))
10003 return 0;
10005 r = strrchr (p1, c);
10007 if (r == NULL)
10008 return build_int_cst (TREE_TYPE (s1), 0);
10010 /* Return an offset into the constant string argument. */
10011 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
10012 s1, build_int_cst (TREE_TYPE (s1), r - p1));
10013 return fold_convert (type, tem);
10016 if (! integer_zerop (s2))
10017 return 0;
10019 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
10020 if (!fn)
10021 return 0;
10023 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
10024 return build_function_call_expr (fn, arglist);
10028 /* Simplify a call to the strpbrk builtin.
10030 Return 0 if no simplification was possible, otherwise return the
10031 simplified form of the call as a tree.
10033 The simplified form may be a constant or other expression which
10034 computes the same value, but in a more efficient manner (including
10035 calls to other builtin functions).
10037 The call may contain arguments which need to be evaluated, but
10038 which are not useful to determine the result of the call. In
10039 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10040 COMPOUND_EXPR will be an argument which must be evaluated.
10041 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10042 COMPOUND_EXPR in the chain will contain the tree for the simplified
10043 form of the builtin function call. */
10045 static tree
10046 fold_builtin_strpbrk (tree arglist, tree type)
10048 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10049 return 0;
10050 else
10052 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10053 tree fn;
10054 const char *p1, *p2;
10056 p2 = c_getstr (s2);
10057 if (p2 == NULL)
10058 return 0;
10060 p1 = c_getstr (s1);
10061 if (p1 != NULL)
10063 const char *r = strpbrk (p1, p2);
10064 tree tem;
10066 if (r == NULL)
10067 return build_int_cst (TREE_TYPE (s1), 0);
10069 /* Return an offset into the constant string argument. */
10070 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
10071 s1, build_int_cst (TREE_TYPE (s1), r - p1));
10072 return fold_convert (type, tem);
10075 if (p2[0] == '\0')
10076 /* strpbrk(x, "") == NULL.
10077 Evaluate and ignore s1 in case it had side-effects. */
10078 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
10080 if (p2[1] != '\0')
10081 return 0; /* Really call strpbrk. */
10083 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
10084 if (!fn)
10085 return 0;
10087 /* New argument list transforming strpbrk(s1, s2) to
10088 strchr(s1, s2[0]). */
10089 arglist = build_tree_list (NULL_TREE,
10090 build_int_cst (NULL_TREE, p2[0]));
10091 arglist = tree_cons (NULL_TREE, s1, arglist);
10092 return build_function_call_expr (fn, arglist);
10096 /* Simplify a call to the strcat builtin.
10098 Return 0 if no simplification was possible, otherwise return the
10099 simplified form of the call as a tree.
10101 The simplified form may be a constant or other expression which
10102 computes the same value, but in a more efficient manner (including
10103 calls to other builtin functions).
10105 The call may contain arguments which need to be evaluated, but
10106 which are not useful to determine the result of the call. In
10107 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10108 COMPOUND_EXPR will be an argument which must be evaluated.
10109 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10110 COMPOUND_EXPR in the chain will contain the tree for the simplified
10111 form of the builtin function call. */
10113 static tree
10114 fold_builtin_strcat (tree arglist)
10116 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10117 return 0;
10118 else
10120 tree dst = TREE_VALUE (arglist),
10121 src = TREE_VALUE (TREE_CHAIN (arglist));
10122 const char *p = c_getstr (src);
10124 /* If the string length is zero, return the dst parameter. */
10125 if (p && *p == '\0')
10126 return dst;
10128 return 0;
10132 /* Simplify a call to the strncat builtin.
10134 Return 0 if no simplification was possible, otherwise return the
10135 simplified form of the call as a tree.
10137 The simplified form may be a constant or other expression which
10138 computes the same value, but in a more efficient manner (including
10139 calls to other builtin functions).
10141 The call may contain arguments which need to be evaluated, but
10142 which are not useful to determine the result of the call. In
10143 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10144 COMPOUND_EXPR will be an argument which must be evaluated.
10145 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10146 COMPOUND_EXPR in the chain will contain the tree for the simplified
10147 form of the builtin function call. */
10149 static tree
10150 fold_builtin_strncat (tree arglist)
10152 if (!validate_arglist (arglist,
10153 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10154 return 0;
10155 else
10157 tree dst = TREE_VALUE (arglist);
10158 tree src = TREE_VALUE (TREE_CHAIN (arglist));
10159 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10160 const char *p = c_getstr (src);
10162 /* If the requested length is zero, or the src parameter string
10163 length is zero, return the dst parameter. */
10164 if (integer_zerop (len) || (p && *p == '\0'))
10165 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
10167 /* If the requested len is greater than or equal to the string
10168 length, call strcat. */
10169 if (TREE_CODE (len) == INTEGER_CST && p
10170 && compare_tree_int (len, strlen (p)) >= 0)
10172 tree newarglist
10173 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
10174 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
10176 /* If the replacement _DECL isn't initialized, don't do the
10177 transformation. */
10178 if (!fn)
10179 return 0;
10181 return build_function_call_expr (fn, newarglist);
10183 return 0;
10187 /* Simplify a call to the strspn builtin.
10189 Return 0 if no simplification was possible, otherwise return the
10190 simplified form of the call as a tree.
10192 The simplified form may be a constant or other expression which
10193 computes the same value, but in a more efficient manner (including
10194 calls to other builtin functions).
10196 The call may contain arguments which need to be evaluated, but
10197 which are not useful to determine the result of the call. In
10198 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10199 COMPOUND_EXPR will be an argument which must be evaluated.
10200 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10201 COMPOUND_EXPR in the chain will contain the tree for the simplified
10202 form of the builtin function call. */
10204 static tree
10205 fold_builtin_strspn (tree arglist)
10207 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10208 return 0;
10209 else
10211 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10212 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10214 /* If both arguments are constants, evaluate at compile-time. */
10215 if (p1 && p2)
10217 const size_t r = strspn (p1, p2);
10218 return size_int (r);
10221 /* If either argument is "", return 0. */
10222 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
10223 /* Evaluate and ignore both arguments in case either one has
10224 side-effects. */
10225 return omit_two_operands (integer_type_node, integer_zero_node,
10226 s1, s2);
10227 return 0;
10231 /* Simplify a call to the strcspn builtin.
10233 Return 0 if no simplification was possible, otherwise return the
10234 simplified form of the call as a tree.
10236 The simplified form may be a constant or other expression which
10237 computes the same value, but in a more efficient manner (including
10238 calls to other builtin functions).
10240 The call may contain arguments which need to be evaluated, but
10241 which are not useful to determine the result of the call. In
10242 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10243 COMPOUND_EXPR will be an argument which must be evaluated.
10244 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10245 COMPOUND_EXPR in the chain will contain the tree for the simplified
10246 form of the builtin function call. */
10248 static tree
10249 fold_builtin_strcspn (tree arglist)
10251 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10252 return 0;
10253 else
10255 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10256 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10258 /* If both arguments are constants, evaluate at compile-time. */
10259 if (p1 && p2)
10261 const size_t r = strcspn (p1, p2);
10262 return size_int (r);
10265 /* If the first argument is "", return 0. */
10266 if (p1 && *p1 == '\0')
10268 /* Evaluate and ignore argument s2 in case it has
10269 side-effects. */
10270 return omit_one_operand (integer_type_node,
10271 integer_zero_node, s2);
10274 /* If the second argument is "", return __builtin_strlen(s1). */
10275 if (p2 && *p2 == '\0')
10277 tree newarglist = build_tree_list (NULL_TREE, s1),
10278 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
10280 /* If the replacement _DECL isn't initialized, don't do the
10281 transformation. */
10282 if (!fn)
10283 return 0;
10285 return build_function_call_expr (fn, newarglist);
10287 return 0;
10291 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
10292 by the builtin will be ignored. UNLOCKED is true is true if this
10293 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
10294 the known length of the string. Return NULL_TREE if no simplification
10295 was possible. */
10297 tree
10298 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
10300 tree fn;
10301 /* If we're using an unlocked function, assume the other unlocked
10302 functions exist explicitly. */
10303 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
10304 : implicit_built_in_decls[BUILT_IN_FPUTC];
10305 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
10306 : implicit_built_in_decls[BUILT_IN_FWRITE];
10308 /* If the return value is used, don't do the transformation. */
10309 if (!ignore)
10310 return 0;
10312 /* Verify the arguments in the original call. */
10313 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10314 return 0;
10316 if (! len)
10317 len = c_strlen (TREE_VALUE (arglist), 0);
10319 /* Get the length of the string passed to fputs. If the length
10320 can't be determined, punt. */
10321 if (!len
10322 || TREE_CODE (len) != INTEGER_CST)
10323 return 0;
10325 switch (compare_tree_int (len, 1))
10327 case -1: /* length is 0, delete the call entirely . */
10328 return omit_one_operand (integer_type_node, integer_zero_node,
10329 TREE_VALUE (TREE_CHAIN (arglist)));
10331 case 0: /* length is 1, call fputc. */
10333 const char *p = c_getstr (TREE_VALUE (arglist));
10335 if (p != NULL)
10337 /* New argument list transforming fputs(string, stream) to
10338 fputc(string[0], stream). */
10339 arglist = build_tree_list (NULL_TREE,
10340 TREE_VALUE (TREE_CHAIN (arglist)));
10341 arglist = tree_cons (NULL_TREE,
10342 build_int_cst (NULL_TREE, p[0]),
10343 arglist);
10344 fn = fn_fputc;
10345 break;
10348 /* FALLTHROUGH */
10349 case 1: /* length is greater than 1, call fwrite. */
10351 tree string_arg;
10353 /* If optimizing for size keep fputs. */
10354 if (optimize_size)
10355 return 0;
10356 string_arg = TREE_VALUE (arglist);
10357 /* New argument list transforming fputs(string, stream) to
10358 fwrite(string, 1, len, stream). */
10359 arglist = build_tree_list (NULL_TREE,
10360 TREE_VALUE (TREE_CHAIN (arglist)));
10361 arglist = tree_cons (NULL_TREE, len, arglist);
10362 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
10363 arglist = tree_cons (NULL_TREE, string_arg, arglist);
10364 fn = fn_fwrite;
10365 break;
10367 default:
10368 gcc_unreachable ();
10371 /* If the replacement _DECL isn't initialized, don't do the
10372 transformation. */
10373 if (!fn)
10374 return 0;
10376 /* These optimizations are only performed when the result is ignored,
10377 hence there's no need to cast the result to integer_type_node. */
10378 return build_function_call_expr (fn, arglist);
10381 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
10382 produced. False otherwise. This is done so that we don't output the error
10383 or warning twice or three times. */
10384 bool
10385 fold_builtin_next_arg (tree arglist)
10387 tree fntype = TREE_TYPE (current_function_decl);
10389 if (TYPE_ARG_TYPES (fntype) == 0
10390 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
10391 == void_type_node))
10393 error ("%<va_start%> used in function with fixed args");
10394 return true;
10396 else if (!arglist)
10398 /* Evidently an out of date version of <stdarg.h>; can't validate
10399 va_start's second argument, but can still work as intended. */
10400 warning (0, "%<__builtin_next_arg%> called without an argument");
10401 return true;
10403 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
10404 when we checked the arguments and if needed issued a warning. */
10405 else if (!TREE_CHAIN (arglist)
10406 || !integer_zerop (TREE_VALUE (arglist))
10407 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
10408 || TREE_CHAIN (TREE_CHAIN (arglist)))
10410 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
10411 tree arg = TREE_VALUE (arglist);
10413 if (TREE_CHAIN (arglist))
10415 error ("%<va_start%> used with too many arguments");
10416 return true;
10419 /* Strip off all nops for the sake of the comparison. This
10420 is not quite the same as STRIP_NOPS. It does more.
10421 We must also strip off INDIRECT_EXPR for C++ reference
10422 parameters. */
10423 while (TREE_CODE (arg) == NOP_EXPR
10424 || TREE_CODE (arg) == CONVERT_EXPR
10425 || TREE_CODE (arg) == NON_LVALUE_EXPR
10426 || TREE_CODE (arg) == INDIRECT_REF)
10427 arg = TREE_OPERAND (arg, 0);
10428 if (arg != last_parm)
10430 /* FIXME: Sometimes with the tree optimizers we can get the
10431 not the last argument even though the user used the last
10432 argument. We just warn and set the arg to be the last
10433 argument so that we will get wrong-code because of
10434 it. */
10435 warning (0, "second parameter of %<va_start%> not last named argument");
10437 /* We want to verify the second parameter just once before the tree
10438 optimizers are run and then avoid keeping it in the tree,
10439 as otherwise we could warn even for correct code like:
10440 void foo (int i, ...)
10441 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
10442 TREE_VALUE (arglist) = integer_zero_node;
10443 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
10445 return false;
10449 /* Simplify a call to the sprintf builtin.
10451 Return 0 if no simplification was possible, otherwise return the
10452 simplified form of the call as a tree. If IGNORED is true, it means that
10453 the caller does not use the returned value of the function. */
10455 static tree
10456 fold_builtin_sprintf (tree arglist, int ignored)
10458 tree call, retval, dest, fmt;
10459 const char *fmt_str = NULL;
10461 /* Verify the required arguments in the original call. We deal with two
10462 types of sprintf() calls: 'sprintf (str, fmt)' and
10463 'sprintf (dest, "%s", orig)'. */
10464 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
10465 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
10466 VOID_TYPE))
10467 return NULL_TREE;
10469 /* Get the destination string and the format specifier. */
10470 dest = TREE_VALUE (arglist);
10471 fmt = TREE_VALUE (TREE_CHAIN (arglist));
10473 /* Check whether the format is a literal string constant. */
10474 fmt_str = c_getstr (fmt);
10475 if (fmt_str == NULL)
10476 return NULL_TREE;
10478 call = NULL_TREE;
10479 retval = NULL_TREE;
10481 if (!init_target_chars())
10482 return 0;
10484 /* If the format doesn't contain % args or %%, use strcpy. */
10485 if (strchr (fmt_str, target_percent) == NULL)
10487 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10489 if (!fn)
10490 return NULL_TREE;
10492 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10493 'format' is known to contain no % formats. */
10494 arglist = build_tree_list (NULL_TREE, fmt);
10495 arglist = tree_cons (NULL_TREE, dest, arglist);
10496 call = build_function_call_expr (fn, arglist);
10497 if (!ignored)
10498 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
10501 /* If the format is "%s", use strcpy if the result isn't used. */
10502 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
10504 tree fn, orig;
10505 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10507 if (!fn)
10508 return NULL_TREE;
10510 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
10511 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10512 arglist = build_tree_list (NULL_TREE, orig);
10513 arglist = tree_cons (NULL_TREE, dest, arglist);
10514 if (!ignored)
10516 retval = c_strlen (orig, 1);
10517 if (!retval || TREE_CODE (retval) != INTEGER_CST)
10518 return NULL_TREE;
10520 call = build_function_call_expr (fn, arglist);
10523 if (call && retval)
10525 retval = fold_convert
10526 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
10527 retval);
10528 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
10530 else
10531 return call;
10534 /* Expand a call to __builtin_object_size. */
10537 expand_builtin_object_size (tree exp)
10539 tree ost;
10540 int object_size_type;
10541 tree fndecl = get_callee_fndecl (exp);
10542 tree arglist = TREE_OPERAND (exp, 1);
10543 location_t locus = EXPR_LOCATION (exp);
10545 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10547 error ("%Hfirst argument of %D must be a pointer, second integer constant",
10548 &locus, fndecl);
10549 expand_builtin_trap ();
10550 return const0_rtx;
10553 ost = TREE_VALUE (TREE_CHAIN (arglist));
10554 STRIP_NOPS (ost);
10556 if (TREE_CODE (ost) != INTEGER_CST
10557 || tree_int_cst_sgn (ost) < 0
10558 || compare_tree_int (ost, 3) > 0)
10560 error ("%Hlast argument of %D is not integer constant between 0 and 3",
10561 &locus, fndecl);
10562 expand_builtin_trap ();
10563 return const0_rtx;
10566 object_size_type = tree_low_cst (ost, 0);
10568 return object_size_type < 2 ? constm1_rtx : const0_rtx;
10571 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10572 FCODE is the BUILT_IN_* to use.
10573 Return 0 if we failed; the caller should emit a normal call,
10574 otherwise try to get the result in TARGET, if convenient (and in
10575 mode MODE if that's convenient). */
10577 static rtx
10578 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10579 enum built_in_function fcode)
10581 tree arglist = TREE_OPERAND (exp, 1);
10582 tree dest, src, len, size;
10584 if (!validate_arglist (arglist,
10585 POINTER_TYPE,
10586 fcode == BUILT_IN_MEMSET_CHK
10587 ? INTEGER_TYPE : POINTER_TYPE,
10588 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10589 return 0;
10591 dest = TREE_VALUE (arglist);
10592 src = TREE_VALUE (TREE_CHAIN (arglist));
10593 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10594 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10596 if (! host_integerp (size, 1))
10597 return 0;
10599 if (host_integerp (len, 1) || integer_all_onesp (size))
10601 tree fn;
10603 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10605 location_t locus = EXPR_LOCATION (exp);
10606 warning (0, "%Hcall to %D will always overflow destination buffer",
10607 &locus, get_callee_fndecl (exp));
10608 return 0;
10611 arglist = build_tree_list (NULL_TREE, len);
10612 arglist = tree_cons (NULL_TREE, src, arglist);
10613 arglist = tree_cons (NULL_TREE, dest, arglist);
10615 fn = NULL_TREE;
10616 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10617 mem{cpy,pcpy,move,set} is available. */
10618 switch (fcode)
10620 case BUILT_IN_MEMCPY_CHK:
10621 fn = built_in_decls[BUILT_IN_MEMCPY];
10622 break;
10623 case BUILT_IN_MEMPCPY_CHK:
10624 fn = built_in_decls[BUILT_IN_MEMPCPY];
10625 break;
10626 case BUILT_IN_MEMMOVE_CHK:
10627 fn = built_in_decls[BUILT_IN_MEMMOVE];
10628 break;
10629 case BUILT_IN_MEMSET_CHK:
10630 fn = built_in_decls[BUILT_IN_MEMSET];
10631 break;
10632 default:
10633 break;
10636 if (! fn)
10637 return 0;
10639 fn = build_function_call_expr (fn, arglist);
10640 if (TREE_CODE (fn) == CALL_EXPR)
10641 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10642 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10644 else if (fcode == BUILT_IN_MEMSET_CHK)
10645 return 0;
10646 else
10648 unsigned int dest_align
10649 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10651 /* If DEST is not a pointer type, call the normal function. */
10652 if (dest_align == 0)
10653 return 0;
10655 /* If SRC and DEST are the same (and not volatile), do nothing. */
10656 if (operand_equal_p (src, dest, 0))
10658 tree expr;
10660 if (fcode != BUILT_IN_MEMPCPY_CHK)
10662 /* Evaluate and ignore LEN in case it has side-effects. */
10663 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10664 return expand_expr (dest, target, mode, EXPAND_NORMAL);
10667 len = fold_convert (TREE_TYPE (dest), len);
10668 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10669 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10672 /* __memmove_chk special case. */
10673 if (fcode == BUILT_IN_MEMMOVE_CHK)
10675 unsigned int src_align
10676 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10678 if (src_align == 0)
10679 return 0;
10681 /* If src is categorized for a readonly section we can use
10682 normal __memcpy_chk. */
10683 if (readonly_data_expr (src))
10685 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10686 if (!fn)
10687 return 0;
10688 fn = build_function_call_expr (fn, arglist);
10689 if (TREE_CODE (fn) == CALL_EXPR)
10690 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10691 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10694 return 0;
10698 /* Emit warning if a buffer overflow is detected at compile time. */
10700 static void
10701 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10703 int arg_mask, is_strlen = 0;
10704 tree arglist = TREE_OPERAND (exp, 1), a;
10705 tree len, size;
10706 location_t locus;
10708 switch (fcode)
10710 case BUILT_IN_STRCPY_CHK:
10711 case BUILT_IN_STPCPY_CHK:
10712 /* For __strcat_chk the warning will be emitted only if overflowing
10713 by at least strlen (dest) + 1 bytes. */
10714 case BUILT_IN_STRCAT_CHK:
10715 arg_mask = 6;
10716 is_strlen = 1;
10717 break;
10718 case BUILT_IN_STRNCAT_CHK:
10719 /* For __strncat_chk the warning will be emitted only if overflowing
10720 by at least strlen (dest) + 1 bytes. */
10721 arg_mask = 12;
10722 break;
10723 case BUILT_IN_STRNCPY_CHK:
10724 arg_mask = 12;
10725 break;
10726 case BUILT_IN_SNPRINTF_CHK:
10727 case BUILT_IN_VSNPRINTF_CHK:
10728 arg_mask = 10;
10729 break;
10730 default:
10731 gcc_unreachable ();
10734 len = NULL_TREE;
10735 size = NULL_TREE;
10736 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10737 if (arg_mask & 1)
10739 if (len)
10740 size = a;
10741 else
10742 len = a;
10745 if (!len || !size)
10746 return;
10748 len = TREE_VALUE (len);
10749 size = TREE_VALUE (size);
10751 if (! host_integerp (size, 1) || integer_all_onesp (size))
10752 return;
10754 if (is_strlen)
10756 len = c_strlen (len, 1);
10757 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10758 return;
10760 else if (fcode == BUILT_IN_STRNCAT_CHK)
10762 tree src = TREE_VALUE (TREE_CHAIN (arglist));
10763 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10764 return;
10765 src = c_strlen (src, 1);
10766 if (! src || ! host_integerp (src, 1))
10768 locus = EXPR_LOCATION (exp);
10769 warning (0, "%Hcall to %D might overflow destination buffer",
10770 &locus, get_callee_fndecl (exp));
10771 return;
10773 else if (tree_int_cst_lt (src, size))
10774 return;
10776 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10777 return;
10779 locus = EXPR_LOCATION (exp);
10780 warning (0, "%Hcall to %D will always overflow destination buffer",
10781 &locus, get_callee_fndecl (exp));
10784 /* Emit warning if a buffer overflow is detected at compile time
10785 in __sprintf_chk/__vsprintf_chk calls. */
10787 static void
10788 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10790 tree arglist = TREE_OPERAND (exp, 1);
10791 tree dest, size, len, fmt, flag;
10792 const char *fmt_str;
10794 /* Verify the required arguments in the original call. */
10795 if (! arglist)
10796 return;
10797 dest = TREE_VALUE (arglist);
10798 arglist = TREE_CHAIN (arglist);
10799 if (! arglist)
10800 return;
10801 flag = TREE_VALUE (arglist);
10802 arglist = TREE_CHAIN (arglist);
10803 if (! arglist)
10804 return;
10805 size = TREE_VALUE (arglist);
10806 arglist = TREE_CHAIN (arglist);
10807 if (! arglist)
10808 return;
10809 fmt = TREE_VALUE (arglist);
10810 arglist = TREE_CHAIN (arglist);
10812 if (! host_integerp (size, 1) || integer_all_onesp (size))
10813 return;
10815 /* Check whether the format is a literal string constant. */
10816 fmt_str = c_getstr (fmt);
10817 if (fmt_str == NULL)
10818 return;
10820 if (!init_target_chars())
10821 return;
10823 /* If the format doesn't contain % args or %%, we know its size. */
10824 if (strchr (fmt_str, target_percent) == 0)
10825 len = build_int_cstu (size_type_node, strlen (fmt_str));
10826 /* If the format is "%s" and first ... argument is a string literal,
10827 we know it too. */
10828 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10830 tree arg;
10832 if (! arglist)
10833 return;
10834 arg = TREE_VALUE (arglist);
10835 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10836 return;
10838 len = c_strlen (arg, 1);
10839 if (!len || ! host_integerp (len, 1))
10840 return;
10842 else
10843 return;
10845 if (! tree_int_cst_lt (len, size))
10847 location_t locus = EXPR_LOCATION (exp);
10848 warning (0, "%Hcall to %D will always overflow destination buffer",
10849 &locus, get_callee_fndecl (exp));
10853 /* Fold a call to __builtin_object_size, if possible. */
10855 tree
10856 fold_builtin_object_size (tree arglist)
10858 tree ptr, ost, ret = 0;
10859 int object_size_type;
10861 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10862 return 0;
10864 ptr = TREE_VALUE (arglist);
10865 ost = TREE_VALUE (TREE_CHAIN (arglist));
10866 STRIP_NOPS (ost);
10868 if (TREE_CODE (ost) != INTEGER_CST
10869 || tree_int_cst_sgn (ost) < 0
10870 || compare_tree_int (ost, 3) > 0)
10871 return 0;
10873 object_size_type = tree_low_cst (ost, 0);
10875 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10876 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10877 and (size_t) 0 for types 2 and 3. */
10878 if (TREE_SIDE_EFFECTS (ptr))
10879 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
10881 if (TREE_CODE (ptr) == ADDR_EXPR)
10882 ret = build_int_cstu (size_type_node,
10883 compute_builtin_object_size (ptr, object_size_type));
10885 else if (TREE_CODE (ptr) == SSA_NAME)
10887 unsigned HOST_WIDE_INT bytes;
10889 /* If object size is not known yet, delay folding until
10890 later. Maybe subsequent passes will help determining
10891 it. */
10892 bytes = compute_builtin_object_size (ptr, object_size_type);
10893 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10894 ? -1 : 0))
10895 ret = build_int_cstu (size_type_node, bytes);
10898 if (ret)
10900 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
10901 HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
10902 if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
10903 ret = NULL_TREE;
10906 return ret;
10909 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10910 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10911 code of the builtin. If MAXLEN is not NULL, it is maximum length
10912 passed as third argument. */
10914 tree
10915 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10916 enum built_in_function fcode)
10918 tree dest, src, len, size, fn;
10920 if (!validate_arglist (arglist,
10921 POINTER_TYPE,
10922 fcode == BUILT_IN_MEMSET_CHK
10923 ? INTEGER_TYPE : POINTER_TYPE,
10924 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10925 return 0;
10927 dest = TREE_VALUE (arglist);
10928 /* Actually val for __memset_chk, but it doesn't matter. */
10929 src = TREE_VALUE (TREE_CHAIN (arglist));
10930 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10931 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10933 /* If SRC and DEST are the same (and not volatile), return DEST
10934 (resp. DEST+LEN for __mempcpy_chk). */
10935 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10937 if (fcode != BUILT_IN_MEMPCPY_CHK)
10938 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10939 else
10941 tree temp = fold_convert (TREE_TYPE (dest), len);
10942 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10943 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10947 if (! host_integerp (size, 1))
10948 return 0;
10950 if (! integer_all_onesp (size))
10952 if (! host_integerp (len, 1))
10954 /* If LEN is not constant, try MAXLEN too.
10955 For MAXLEN only allow optimizing into non-_ocs function
10956 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10957 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10959 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10961 /* (void) __mempcpy_chk () can be optimized into
10962 (void) __memcpy_chk (). */
10963 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10964 if (!fn)
10965 return 0;
10967 return build_function_call_expr (fn, arglist);
10969 return 0;
10972 else
10973 maxlen = len;
10975 if (tree_int_cst_lt (size, maxlen))
10976 return 0;
10979 arglist = build_tree_list (NULL_TREE, len);
10980 arglist = tree_cons (NULL_TREE, src, arglist);
10981 arglist = tree_cons (NULL_TREE, dest, arglist);
10983 fn = NULL_TREE;
10984 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10985 mem{cpy,pcpy,move,set} is available. */
10986 switch (fcode)
10988 case BUILT_IN_MEMCPY_CHK:
10989 fn = built_in_decls[BUILT_IN_MEMCPY];
10990 break;
10991 case BUILT_IN_MEMPCPY_CHK:
10992 fn = built_in_decls[BUILT_IN_MEMPCPY];
10993 break;
10994 case BUILT_IN_MEMMOVE_CHK:
10995 fn = built_in_decls[BUILT_IN_MEMMOVE];
10996 break;
10997 case BUILT_IN_MEMSET_CHK:
10998 fn = built_in_decls[BUILT_IN_MEMSET];
10999 break;
11000 default:
11001 break;
11004 if (!fn)
11005 return 0;
11007 return build_function_call_expr (fn, arglist);
11010 /* Fold a call to the __st[rp]cpy_chk builtin.
11011 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
11012 code of the builtin. If MAXLEN is not NULL, it is maximum length of
11013 strings passed as second argument. */
11015 tree
11016 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
11017 enum built_in_function fcode)
11019 tree dest, src, size, len, fn;
11021 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11022 VOID_TYPE))
11023 return 0;
11025 dest = TREE_VALUE (arglist);
11026 src = TREE_VALUE (TREE_CHAIN (arglist));
11027 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11029 /* If SRC and DEST are the same (and not volatile), return DEST. */
11030 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
11031 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
11033 if (! host_integerp (size, 1))
11034 return 0;
11036 if (! integer_all_onesp (size))
11038 len = c_strlen (src, 1);
11039 if (! len || ! host_integerp (len, 1))
11041 /* If LEN is not constant, try MAXLEN too.
11042 For MAXLEN only allow optimizing into non-_ocs function
11043 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11044 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11046 if (fcode == BUILT_IN_STPCPY_CHK)
11048 if (! ignore)
11049 return 0;
11051 /* If return value of __stpcpy_chk is ignored,
11052 optimize into __strcpy_chk. */
11053 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
11054 if (!fn)
11055 return 0;
11057 return build_function_call_expr (fn, arglist);
11060 if (! len || TREE_SIDE_EFFECTS (len))
11061 return 0;
11063 /* If c_strlen returned something, but not a constant,
11064 transform __strcpy_chk into __memcpy_chk. */
11065 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
11066 if (!fn)
11067 return 0;
11069 len = size_binop (PLUS_EXPR, len, ssize_int (1));
11070 arglist = build_tree_list (NULL_TREE, size);
11071 arglist = tree_cons (NULL_TREE, len, arglist);
11072 arglist = tree_cons (NULL_TREE, src, arglist);
11073 arglist = tree_cons (NULL_TREE, dest, arglist);
11074 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
11075 build_function_call_expr (fn, arglist));
11078 else
11079 maxlen = len;
11081 if (! tree_int_cst_lt (maxlen, size))
11082 return 0;
11085 arglist = build_tree_list (NULL_TREE, src);
11086 arglist = tree_cons (NULL_TREE, dest, arglist);
11088 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
11089 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
11090 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
11091 if (!fn)
11092 return 0;
11094 return build_function_call_expr (fn, arglist);
11097 /* Fold a call to the __strncpy_chk builtin.
11098 If MAXLEN is not NULL, it is maximum length passed as third argument. */
11100 tree
11101 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
11103 tree dest, src, size, len, fn;
11105 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11106 INTEGER_TYPE, VOID_TYPE))
11107 return 0;
11109 dest = TREE_VALUE (arglist);
11110 src = TREE_VALUE (TREE_CHAIN (arglist));
11111 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11112 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
11114 if (! host_integerp (size, 1))
11115 return 0;
11117 if (! integer_all_onesp (size))
11119 if (! host_integerp (len, 1))
11121 /* If LEN is not constant, try MAXLEN too.
11122 For MAXLEN only allow optimizing into non-_ocs function
11123 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11124 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11125 return 0;
11127 else
11128 maxlen = len;
11130 if (tree_int_cst_lt (size, maxlen))
11131 return 0;
11134 arglist = build_tree_list (NULL_TREE, len);
11135 arglist = tree_cons (NULL_TREE, src, arglist);
11136 arglist = tree_cons (NULL_TREE, dest, arglist);
11138 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
11139 fn = built_in_decls[BUILT_IN_STRNCPY];
11140 if (!fn)
11141 return 0;
11143 return build_function_call_expr (fn, arglist);
11146 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
11148 static tree
11149 fold_builtin_strcat_chk (tree fndecl, tree arglist)
11151 tree dest, src, size, fn;
11152 const char *p;
11154 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11155 VOID_TYPE))
11156 return 0;
11158 dest = TREE_VALUE (arglist);
11159 src = TREE_VALUE (TREE_CHAIN (arglist));
11160 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11162 p = c_getstr (src);
11163 /* If the SRC parameter is "", return DEST. */
11164 if (p && *p == '\0')
11165 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
11167 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
11168 return 0;
11170 arglist = build_tree_list (NULL_TREE, src);
11171 arglist = tree_cons (NULL_TREE, dest, arglist);
11173 /* If __builtin_strcat_chk is used, assume strcat is available. */
11174 fn = built_in_decls[BUILT_IN_STRCAT];
11175 if (!fn)
11176 return 0;
11178 return build_function_call_expr (fn, arglist);
11181 /* Fold a call to the __strncat_chk builtin EXP. */
11183 static tree
11184 fold_builtin_strncat_chk (tree fndecl, tree arglist)
11186 tree dest, src, size, len, fn;
11187 const char *p;
11189 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11190 INTEGER_TYPE, VOID_TYPE))
11191 return 0;
11193 dest = TREE_VALUE (arglist);
11194 src = TREE_VALUE (TREE_CHAIN (arglist));
11195 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11196 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
11198 p = c_getstr (src);
11199 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
11200 if (p && *p == '\0')
11201 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
11202 else if (integer_zerop (len))
11203 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
11205 if (! host_integerp (size, 1))
11206 return 0;
11208 if (! integer_all_onesp (size))
11210 tree src_len = c_strlen (src, 1);
11211 if (src_len
11212 && host_integerp (src_len, 1)
11213 && host_integerp (len, 1)
11214 && ! tree_int_cst_lt (len, src_len))
11216 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
11217 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
11218 if (!fn)
11219 return 0;
11221 arglist = build_tree_list (NULL_TREE, size);
11222 arglist = tree_cons (NULL_TREE, src, arglist);
11223 arglist = tree_cons (NULL_TREE, dest, arglist);
11224 return build_function_call_expr (fn, arglist);
11226 return 0;
11229 arglist = build_tree_list (NULL_TREE, len);
11230 arglist = tree_cons (NULL_TREE, src, arglist);
11231 arglist = tree_cons (NULL_TREE, dest, arglist);
11233 /* If __builtin_strncat_chk is used, assume strncat is available. */
11234 fn = built_in_decls[BUILT_IN_STRNCAT];
11235 if (!fn)
11236 return 0;
11238 return build_function_call_expr (fn, arglist);
11241 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
11242 a normal call should be emitted rather than expanding the function
11243 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
11245 static tree
11246 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
11248 tree dest, size, len, fn, fmt, flag;
11249 const char *fmt_str;
11251 /* Verify the required arguments in the original call. */
11252 if (! arglist)
11253 return 0;
11254 dest = TREE_VALUE (arglist);
11255 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11256 return 0;
11257 arglist = TREE_CHAIN (arglist);
11258 if (! arglist)
11259 return 0;
11260 flag = TREE_VALUE (arglist);
11261 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
11262 return 0;
11263 arglist = TREE_CHAIN (arglist);
11264 if (! arglist)
11265 return 0;
11266 size = TREE_VALUE (arglist);
11267 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11268 return 0;
11269 arglist = TREE_CHAIN (arglist);
11270 if (! arglist)
11271 return 0;
11272 fmt = TREE_VALUE (arglist);
11273 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11274 return 0;
11275 arglist = TREE_CHAIN (arglist);
11277 if (! host_integerp (size, 1))
11278 return 0;
11280 len = NULL_TREE;
11282 if (!init_target_chars())
11283 return 0;
11285 /* Check whether the format is a literal string constant. */
11286 fmt_str = c_getstr (fmt);
11287 if (fmt_str != NULL)
11289 /* If the format doesn't contain % args or %%, we know the size. */
11290 if (strchr (fmt_str, target_percent) == 0)
11292 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
11293 len = build_int_cstu (size_type_node, strlen (fmt_str));
11295 /* If the format is "%s" and first ... argument is a string literal,
11296 we know the size too. */
11297 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
11299 tree arg;
11301 if (arglist && !TREE_CHAIN (arglist))
11303 arg = TREE_VALUE (arglist);
11304 if (POINTER_TYPE_P (TREE_TYPE (arg)))
11306 len = c_strlen (arg, 1);
11307 if (! len || ! host_integerp (len, 1))
11308 len = NULL_TREE;
11314 if (! integer_all_onesp (size))
11316 if (! len || ! tree_int_cst_lt (len, size))
11317 return 0;
11320 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
11321 or if format doesn't contain % chars or is "%s". */
11322 if (! integer_zerop (flag))
11324 if (fmt_str == NULL)
11325 return 0;
11326 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11327 return 0;
11330 arglist = tree_cons (NULL_TREE, fmt, arglist);
11331 arglist = tree_cons (NULL_TREE, dest, arglist);
11333 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
11334 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
11335 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
11336 if (!fn)
11337 return 0;
11339 return build_function_call_expr (fn, arglist);
11342 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
11343 a normal call should be emitted rather than expanding the function
11344 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
11345 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
11346 passed as second argument. */
11348 tree
11349 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
11350 enum built_in_function fcode)
11352 tree dest, size, len, fn, fmt, flag;
11353 const char *fmt_str;
11355 /* Verify the required arguments in the original call. */
11356 if (! arglist)
11357 return 0;
11358 dest = TREE_VALUE (arglist);
11359 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11360 return 0;
11361 arglist = TREE_CHAIN (arglist);
11362 if (! arglist)
11363 return 0;
11364 len = TREE_VALUE (arglist);
11365 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11366 return 0;
11367 arglist = TREE_CHAIN (arglist);
11368 if (! arglist)
11369 return 0;
11370 flag = TREE_VALUE (arglist);
11371 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11372 return 0;
11373 arglist = TREE_CHAIN (arglist);
11374 if (! arglist)
11375 return 0;
11376 size = TREE_VALUE (arglist);
11377 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11378 return 0;
11379 arglist = TREE_CHAIN (arglist);
11380 if (! arglist)
11381 return 0;
11382 fmt = TREE_VALUE (arglist);
11383 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11384 return 0;
11385 arglist = TREE_CHAIN (arglist);
11387 if (! host_integerp (size, 1))
11388 return 0;
11390 if (! integer_all_onesp (size))
11392 if (! host_integerp (len, 1))
11394 /* If LEN is not constant, try MAXLEN too.
11395 For MAXLEN only allow optimizing into non-_ocs function
11396 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11397 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11398 return 0;
11400 else
11401 maxlen = len;
11403 if (tree_int_cst_lt (size, maxlen))
11404 return 0;
11407 if (!init_target_chars())
11408 return 0;
11410 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
11411 or if format doesn't contain % chars or is "%s". */
11412 if (! integer_zerop (flag))
11414 fmt_str = c_getstr (fmt);
11415 if (fmt_str == NULL)
11416 return 0;
11417 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11418 return 0;
11421 arglist = tree_cons (NULL_TREE, fmt, arglist);
11422 arglist = tree_cons (NULL_TREE, len, arglist);
11423 arglist = tree_cons (NULL_TREE, dest, arglist);
11425 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
11426 available. */
11427 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
11428 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
11429 if (!fn)
11430 return 0;
11432 return build_function_call_expr (fn, arglist);
11435 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
11437 Return 0 if no simplification was possible, otherwise return the
11438 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11439 code of the function to be simplified. */
11441 static tree
11442 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
11443 enum built_in_function fcode)
11445 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
11446 const char *fmt_str = NULL;
11448 /* If the return value is used, don't do the transformation. */
11449 if (! ignore)
11450 return 0;
11452 /* Verify the required arguments in the original call. */
11453 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
11455 tree flag;
11457 if (! arglist)
11458 return 0;
11459 flag = TREE_VALUE (arglist);
11460 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11461 || TREE_SIDE_EFFECTS (flag))
11462 return 0;
11463 arglist = TREE_CHAIN (arglist);
11466 if (! arglist)
11467 return 0;
11468 fmt = TREE_VALUE (arglist);
11469 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11470 return 0;
11471 arglist = TREE_CHAIN (arglist);
11473 /* Check whether the format is a literal string constant. */
11474 fmt_str = c_getstr (fmt);
11475 if (fmt_str == NULL)
11476 return NULL_TREE;
11478 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
11480 /* If we're using an unlocked function, assume the other
11481 unlocked functions exist explicitly. */
11482 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
11483 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
11485 else
11487 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
11488 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
11491 if (!init_target_chars())
11492 return 0;
11494 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
11496 const char *str;
11498 if (strcmp (fmt_str, target_percent_s) == 0)
11500 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11501 return 0;
11503 if (! arglist
11504 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11505 || TREE_CHAIN (arglist))
11506 return 0;
11508 str = c_getstr (TREE_VALUE (arglist));
11509 if (str == NULL)
11510 return 0;
11512 else
11514 /* The format specifier doesn't contain any '%' characters. */
11515 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
11516 && arglist)
11517 return 0;
11518 str = fmt_str;
11521 /* If the string was "", printf does nothing. */
11522 if (str[0] == '\0')
11523 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11525 /* If the string has length of 1, call putchar. */
11526 if (str[1] == '\0')
11528 /* Given printf("c"), (where c is any one character,)
11529 convert "c"[0] to an int and pass that to the replacement
11530 function. */
11531 arg = build_int_cst (NULL_TREE, str[0]);
11532 arglist = build_tree_list (NULL_TREE, arg);
11533 fn = fn_putchar;
11535 else
11537 /* If the string was "string\n", call puts("string"). */
11538 size_t len = strlen (str);
11539 if ((unsigned char)str[len - 1] == target_newline)
11541 /* Create a NUL-terminated string that's one char shorter
11542 than the original, stripping off the trailing '\n'. */
11543 char *newstr = alloca (len);
11544 memcpy (newstr, str, len - 1);
11545 newstr[len - 1] = 0;
11547 arg = build_string_literal (len, newstr);
11548 arglist = build_tree_list (NULL_TREE, arg);
11549 fn = fn_puts;
11551 else
11552 /* We'd like to arrange to call fputs(string,stdout) here,
11553 but we need stdout and don't have a way to get it yet. */
11554 return 0;
11558 /* The other optimizations can be done only on the non-va_list variants. */
11559 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11560 return 0;
11562 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
11563 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11565 if (! arglist
11566 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11567 || TREE_CHAIN (arglist))
11568 return 0;
11569 fn = fn_puts;
11572 /* If the format specifier was "%c", call __builtin_putchar(arg). */
11573 else if (strcmp (fmt_str, target_percent_c) == 0)
11575 if (! arglist
11576 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11577 || TREE_CHAIN (arglist))
11578 return 0;
11579 fn = fn_putchar;
11582 if (!fn)
11583 return 0;
11585 call = build_function_call_expr (fn, arglist);
11586 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11589 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11591 Return 0 if no simplification was possible, otherwise return the
11592 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11593 code of the function to be simplified. */
11595 static tree
11596 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11597 enum built_in_function fcode)
11599 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11600 const char *fmt_str = NULL;
11602 /* If the return value is used, don't do the transformation. */
11603 if (! ignore)
11604 return 0;
11606 /* Verify the required arguments in the original call. */
11607 if (! arglist)
11608 return 0;
11609 fp = TREE_VALUE (arglist);
11610 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11611 return 0;
11612 arglist = TREE_CHAIN (arglist);
11614 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11616 tree flag;
11618 if (! arglist)
11619 return 0;
11620 flag = TREE_VALUE (arglist);
11621 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11622 || TREE_SIDE_EFFECTS (flag))
11623 return 0;
11624 arglist = TREE_CHAIN (arglist);
11627 if (! arglist)
11628 return 0;
11629 fmt = TREE_VALUE (arglist);
11630 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11631 return 0;
11632 arglist = TREE_CHAIN (arglist);
11634 /* Check whether the format is a literal string constant. */
11635 fmt_str = c_getstr (fmt);
11636 if (fmt_str == NULL)
11637 return NULL_TREE;
11639 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11641 /* If we're using an unlocked function, assume the other
11642 unlocked functions exist explicitly. */
11643 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11644 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11646 else
11648 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11649 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11652 if (!init_target_chars())
11653 return 0;
11655 /* If the format doesn't contain % args or %%, use strcpy. */
11656 if (strchr (fmt_str, target_percent) == NULL)
11658 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11659 && arglist)
11660 return 0;
11662 /* If the format specifier was "", fprintf does nothing. */
11663 if (fmt_str[0] == '\0')
11665 /* If FP has side-effects, just wait until gimplification is
11666 done. */
11667 if (TREE_SIDE_EFFECTS (fp))
11668 return 0;
11670 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11673 /* When "string" doesn't contain %, replace all cases of
11674 fprintf (fp, string) with fputs (string, fp). The fputs
11675 builtin will take care of special cases like length == 1. */
11676 arglist = build_tree_list (NULL_TREE, fp);
11677 arglist = tree_cons (NULL_TREE, fmt, arglist);
11678 fn = fn_fputs;
11681 /* The other optimizations can be done only on the non-va_list variants. */
11682 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11683 return 0;
11685 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11686 else if (strcmp (fmt_str, target_percent_s) == 0)
11688 if (! arglist
11689 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11690 || TREE_CHAIN (arglist))
11691 return 0;
11692 arg = TREE_VALUE (arglist);
11693 arglist = build_tree_list (NULL_TREE, fp);
11694 arglist = tree_cons (NULL_TREE, arg, arglist);
11695 fn = fn_fputs;
11698 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11699 else if (strcmp (fmt_str, target_percent_c) == 0)
11701 if (! arglist
11702 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11703 || TREE_CHAIN (arglist))
11704 return 0;
11705 arg = TREE_VALUE (arglist);
11706 arglist = build_tree_list (NULL_TREE, fp);
11707 arglist = tree_cons (NULL_TREE, arg, arglist);
11708 fn = fn_fputc;
11711 if (!fn)
11712 return 0;
11714 call = build_function_call_expr (fn, arglist);
11715 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11718 /* Initialize format string characters in the target charset. */
11720 static bool
11721 init_target_chars (void)
11723 static bool init;
11724 if (!init)
11726 target_newline = lang_hooks.to_target_charset ('\n');
11727 target_percent = lang_hooks.to_target_charset ('%');
11728 target_c = lang_hooks.to_target_charset ('c');
11729 target_s = lang_hooks.to_target_charset ('s');
11730 if (target_newline == 0 || target_percent == 0 || target_c == 0
11731 || target_s == 0)
11732 return false;
11734 target_percent_c[0] = target_percent;
11735 target_percent_c[1] = target_c;
11736 target_percent_c[2] = '\0';
11738 target_percent_s[0] = target_percent;
11739 target_percent_s[1] = target_s;
11740 target_percent_s[2] = '\0';
11742 target_percent_s_newline[0] = target_percent;
11743 target_percent_s_newline[1] = target_s;
11744 target_percent_s_newline[2] = target_newline;
11745 target_percent_s_newline[3] = '\0';
11747 init = true;
11749 return true;
11752 /* Helper function for do_mpfr_arg*(). Ensure M is a normal number
11753 and no overflow/underflow occurred. INEXACT is true if M was not
11754 exactly calculated. TYPE is the tree type for the result. This
11755 function assumes that you cleared the MPFR flags and then
11756 calculated M to see if anything subsequently set a flag prior to
11757 entering this function. Return NULL_TREE if any checks fail. */
11759 static tree
11760 do_mpfr_ckconv(mpfr_srcptr m, tree type, int inexact)
11762 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
11763 overflow/underflow occurred. If -frounding-math, proceed iff the
11764 result of calling FUNC was exact. */
11765 if (mpfr_number_p (m) && !mpfr_overflow_p() && !mpfr_underflow_p()
11766 && (!flag_rounding_math || !inexact))
11768 REAL_VALUE_TYPE rr;
11770 real_from_mpfr (&rr, m);
11771 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
11772 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
11773 but the mpft_t is not, then we underflowed in the
11774 conversion. */
11775 if (!real_isnan (&rr) && !real_isinf (&rr)
11776 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
11778 REAL_VALUE_TYPE rmode;
11780 real_convert (&rmode, TYPE_MODE (type), &rr);
11781 /* Proceed iff the specified mode can hold the value. */
11782 if (real_identical (&rmode, &rr))
11783 return build_real (type, rmode);
11786 return NULL_TREE;
11789 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
11790 FUNC on it and return the resulting value as a tree with type TYPE.
11791 If MIN and/or MAX are not NULL, then the supplied ARG must be
11792 within those bounds. If INCLUSIVE is true, then MIN/MAX are
11793 acceptable values, otherwise they are not. The mpfr precision is
11794 set to the precision of TYPE. We assume that function FUNC returns
11795 zero if the result could be calculated exactly within the requested
11796 precision. */
11798 static tree
11799 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
11800 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
11801 bool inclusive)
11803 tree result = NULL_TREE;
11805 STRIP_NOPS (arg);
11807 /* To proceed, MPFR must exactly represent the target floating point
11808 format, which only happens when the target base equals two. */
11809 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11810 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
11812 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11814 if (!real_isnan (ra) && !real_isinf (ra)
11815 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
11816 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
11818 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11819 int inexact;
11820 mpfr_t m;
11822 mpfr_init2 (m, prec);
11823 mpfr_from_real (m, ra);
11824 mpfr_clear_flags();
11825 inexact = func (m, m, GMP_RNDN);
11826 result = do_mpfr_ckconv (m, type, inexact);
11827 mpfr_clear (m);
11831 return result;
11834 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
11835 FUNC on it and return the resulting value as a tree with type TYPE.
11836 The mpfr precision is set to the precision of TYPE. We assume that
11837 function FUNC returns zero if the result could be calculated
11838 exactly within the requested precision. */
11840 static tree
11841 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
11842 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11844 tree result = NULL_TREE;
11846 STRIP_NOPS (arg1);
11847 STRIP_NOPS (arg2);
11849 /* To proceed, MPFR must exactly represent the target floating point
11850 format, which only happens when the target base equals two. */
11851 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11852 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
11853 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
11855 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11856 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11858 if (!real_isnan (ra1) && !real_isinf (ra1)
11859 && !real_isnan (ra2) && !real_isinf (ra2))
11861 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11862 int inexact;
11863 mpfr_t m1, m2;
11865 mpfr_inits2 (prec, m1, m2, NULL);
11866 mpfr_from_real (m1, ra1);
11867 mpfr_from_real (m2, ra2);
11868 mpfr_clear_flags();
11869 inexact = func (m1, m1, m2, GMP_RNDN);
11870 result = do_mpfr_ckconv (m1, type, inexact);
11871 mpfr_clears (m1, m2, NULL);
11875 return result;
11878 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
11879 FUNC on it and return the resulting value as a tree with type TYPE.
11880 The mpfr precision is set to the precision of TYPE. We assume that
11881 function FUNC returns zero if the result could be calculated
11882 exactly within the requested precision. */
11884 static tree
11885 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
11886 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11888 tree result = NULL_TREE;
11890 STRIP_NOPS (arg1);
11891 STRIP_NOPS (arg2);
11892 STRIP_NOPS (arg3);
11894 /* To proceed, MPFR must exactly represent the target floating point
11895 format, which only happens when the target base equals two. */
11896 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11897 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
11898 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
11899 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
11901 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11902 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11903 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
11905 if (!real_isnan (ra1) && !real_isinf (ra1)
11906 && !real_isnan (ra2) && !real_isinf (ra2)
11907 && !real_isnan (ra3) && !real_isinf (ra3))
11909 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11910 int inexact;
11911 mpfr_t m1, m2, m3;
11913 mpfr_inits2 (prec, m1, m2, m3, NULL);
11914 mpfr_from_real (m1, ra1);
11915 mpfr_from_real (m2, ra2);
11916 mpfr_from_real (m3, ra3);
11917 mpfr_clear_flags();
11918 inexact = func (m1, m1, m2, m3, GMP_RNDN);
11919 result = do_mpfr_ckconv (m1, type, inexact);
11920 mpfr_clears (m1, m2, m3, NULL);
11924 return result;
11927 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
11928 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
11929 If ARG_SINP and ARG_COSP are NULL then the result is returned
11930 as a complex value.
11931 The type is taken from the type of ARG and is used for setting the
11932 precision of the calculation and results. */
11934 static tree
11935 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
11937 tree const type = TREE_TYPE (arg);
11938 tree result = NULL_TREE;
11940 STRIP_NOPS (arg);
11942 /* To proceed, MPFR must exactly represent the target floating point
11943 format, which only happens when the target base equals two. */
11944 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11945 && TREE_CODE (arg) == REAL_CST
11946 && !TREE_OVERFLOW (arg))
11948 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11950 if (!real_isnan (ra) && !real_isinf (ra))
11952 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11953 tree result_s, result_c;
11954 int inexact;
11955 mpfr_t m, ms, mc;
11957 mpfr_inits2 (prec, m, ms, mc, NULL);
11958 mpfr_from_real (m, ra);
11959 mpfr_clear_flags();
11960 inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
11961 result_s = do_mpfr_ckconv (ms, type, inexact);
11962 result_c = do_mpfr_ckconv (mc, type, inexact);
11963 mpfr_clears (m, ms, mc, NULL);
11964 if (result_s && result_c)
11966 /* If we are to return in a complex value do so. */
11967 if (!arg_sinp && !arg_cosp)
11968 return build_complex (build_complex_type (type),
11969 result_c, result_s);
11971 /* Dereference the sin/cos pointer arguments. */
11972 arg_sinp = build_fold_indirect_ref (arg_sinp);
11973 arg_cosp = build_fold_indirect_ref (arg_cosp);
11974 /* Proceed if valid pointer type were passed in. */
11975 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
11976 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
11978 /* Set the values. */
11979 result_s = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_sinp,
11980 result_s);
11981 TREE_SIDE_EFFECTS (result_s) = 1;
11982 result_c = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_cosp,
11983 result_c);
11984 TREE_SIDE_EFFECTS (result_c) = 1;
11985 /* Combine the assignments into a compound expr. */
11986 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
11987 result_s, result_c));
11992 return result;