PR c++/15745
[official-gcc.git] / gcc / builtins.c
blob566e1cc2e1b883038440f559e506b67a85af44e4
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 3, 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 COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
50 #include "tree-flow.h"
51 #include "value-prof.h"
52 #include "diagnostic.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_interclass_mathfn (tree, rtx, rtx);
99 static rtx expand_builtin_sincos (tree);
100 static rtx expand_builtin_cexpi (tree, rtx, rtx);
101 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
102 static rtx expand_builtin_int_roundingfn_2 (tree, rtx, rtx);
103 static rtx expand_builtin_args_info (tree);
104 static rtx expand_builtin_next_arg (void);
105 static rtx expand_builtin_va_start (tree);
106 static rtx expand_builtin_va_end (tree);
107 static rtx expand_builtin_va_copy (tree);
108 static rtx expand_builtin_memchr (tree, rtx, enum machine_mode);
109 static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
112 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
113 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
114 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
115 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
117 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
119 static rtx expand_builtin_mempcpy_args (tree, tree, tree, tree, rtx,
120 enum machine_mode, int);
121 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode, int);
122 static rtx expand_builtin_memmove_args (tree, tree, tree, tree, rtx,
123 enum machine_mode, int);
124 static rtx expand_builtin_bcopy (tree, int);
125 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
129 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
130 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
131 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
132 static rtx expand_builtin_bzero (tree);
133 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
134 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
135 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
136 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
137 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
138 static rtx expand_builtin_alloca (tree, rtx);
139 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
140 static rtx expand_builtin_frame_address (tree, tree);
141 static rtx expand_builtin_fputs (tree, rtx, bool);
142 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
143 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
144 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
145 static tree stabilize_va_list (tree, int);
146 static rtx expand_builtin_expect (tree, rtx);
147 static tree fold_builtin_constant_p (tree);
148 static tree fold_builtin_expect (tree, tree);
149 static tree fold_builtin_classify_type (tree);
150 static tree fold_builtin_strlen (tree);
151 static tree fold_builtin_inf (tree, int);
152 static tree fold_builtin_nan (tree, tree, int);
153 static tree rewrite_call_expr (tree, int, tree, int, ...);
154 static bool validate_arg (const_tree, enum tree_code code);
155 static bool integer_valued_real_p (tree);
156 static tree fold_trunc_transparent_mathfn (tree, tree);
157 static bool readonly_data_expr (tree);
158 static rtx expand_builtin_fabs (tree, rtx, rtx);
159 static rtx expand_builtin_signbit (tree, rtx);
160 static tree fold_builtin_sqrt (tree, tree);
161 static tree fold_builtin_cbrt (tree, tree);
162 static tree fold_builtin_pow (tree, tree, tree, tree);
163 static tree fold_builtin_powi (tree, tree, tree, tree);
164 static tree fold_builtin_cos (tree, tree, tree);
165 static tree fold_builtin_cosh (tree, tree, tree);
166 static tree fold_builtin_tan (tree, tree);
167 static tree fold_builtin_trunc (tree, tree);
168 static tree fold_builtin_floor (tree, tree);
169 static tree fold_builtin_ceil (tree, tree);
170 static tree fold_builtin_round (tree, tree);
171 static tree fold_builtin_int_roundingfn (tree, tree);
172 static tree fold_builtin_bitop (tree, tree);
173 static tree fold_builtin_memory_op (tree, tree, tree, tree, bool, int);
174 static tree fold_builtin_strchr (tree, tree, tree);
175 static tree fold_builtin_memchr (tree, tree, tree, tree);
176 static tree fold_builtin_memcmp (tree, tree, tree);
177 static tree fold_builtin_strcmp (tree, tree);
178 static tree fold_builtin_strncmp (tree, tree, tree);
179 static tree fold_builtin_signbit (tree, tree);
180 static tree fold_builtin_copysign (tree, tree, tree, tree);
181 static tree fold_builtin_isascii (tree);
182 static tree fold_builtin_toascii (tree);
183 static tree fold_builtin_isdigit (tree);
184 static tree fold_builtin_fabs (tree, tree);
185 static tree fold_builtin_abs (tree, tree);
186 static tree fold_builtin_unordered_cmp (tree, tree, tree, enum tree_code,
187 enum tree_code);
188 static tree fold_builtin_n (tree, tree *, int, bool);
189 static tree fold_builtin_0 (tree, bool);
190 static tree fold_builtin_1 (tree, tree, bool);
191 static tree fold_builtin_2 (tree, tree, tree, bool);
192 static tree fold_builtin_3 (tree, tree, tree, tree, bool);
193 static tree fold_builtin_4 (tree, tree, tree, tree, tree, bool);
194 static tree fold_builtin_varargs (tree, tree, bool);
196 static tree fold_builtin_strpbrk (tree, tree, tree);
197 static tree fold_builtin_strstr (tree, tree, tree);
198 static tree fold_builtin_strrchr (tree, tree, tree);
199 static tree fold_builtin_strcat (tree, tree);
200 static tree fold_builtin_strncat (tree, tree, tree);
201 static tree fold_builtin_strspn (tree, tree);
202 static tree fold_builtin_strcspn (tree, tree);
203 static tree fold_builtin_sprintf (tree, tree, tree, int);
205 static rtx expand_builtin_object_size (tree);
206 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
207 enum built_in_function);
208 static void maybe_emit_chk_warning (tree, enum built_in_function);
209 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
210 static tree fold_builtin_object_size (tree, tree);
211 static tree fold_builtin_strcat_chk (tree, tree, tree, tree);
212 static tree fold_builtin_strncat_chk (tree, tree, tree, tree, tree);
213 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
214 static tree fold_builtin_printf (tree, tree, tree, bool, enum built_in_function);
215 static tree fold_builtin_fprintf (tree, tree, tree, tree, bool,
216 enum built_in_function);
217 static bool init_target_chars (void);
219 static unsigned HOST_WIDE_INT target_newline;
220 static unsigned HOST_WIDE_INT target_percent;
221 static unsigned HOST_WIDE_INT target_c;
222 static unsigned HOST_WIDE_INT target_s;
223 static char target_percent_c[3];
224 static char target_percent_s[3];
225 static char target_percent_s_newline[4];
226 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
227 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
228 static tree do_mpfr_arg2 (tree, tree, tree,
229 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
230 static tree do_mpfr_arg3 (tree, tree, tree, tree,
231 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
232 static tree do_mpfr_sincos (tree, tree, tree);
233 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
234 static tree do_mpfr_bessel_n (tree, tree, tree,
235 int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
236 const REAL_VALUE_TYPE *, bool);
237 static tree do_mpfr_remquo (tree, tree, tree);
238 static tree do_mpfr_lgamma_r (tree, tree, tree);
239 #endif
241 /* Return true if NODE should be considered for inline expansion regardless
242 of the optimization level. This means whenever a function is invoked with
243 its "internal" name, which normally contains the prefix "__builtin". */
245 static bool called_as_built_in (tree node)
247 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
248 if (strncmp (name, "__builtin_", 10) == 0)
249 return true;
250 if (strncmp (name, "__sync_", 7) == 0)
251 return true;
252 return false;
255 /* Return the alignment in bits of EXP, a pointer valued expression.
256 But don't return more than MAX_ALIGN no matter what.
257 The alignment returned is, by default, the alignment of the thing that
258 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
260 Otherwise, look at the expression to see if we can do better, i.e., if the
261 expression is actually pointing at an object whose alignment is tighter. */
264 get_pointer_alignment (tree exp, unsigned int max_align)
266 unsigned int align, inner;
268 /* We rely on TER to compute accurate alignment information. */
269 if (!(optimize && flag_tree_ter))
270 return 0;
272 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
273 return 0;
275 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
276 align = MIN (align, max_align);
278 while (1)
280 switch (TREE_CODE (exp))
282 case NOP_EXPR:
283 case CONVERT_EXPR:
284 case NON_LVALUE_EXPR:
285 exp = TREE_OPERAND (exp, 0);
286 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
287 return align;
289 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
290 align = MIN (inner, max_align);
291 break;
293 case POINTER_PLUS_EXPR:
294 /* If sum of pointer + int, restrict our maximum alignment to that
295 imposed by the integer. If not, we can't do any better than
296 ALIGN. */
297 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
298 return align;
300 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
301 & (max_align / BITS_PER_UNIT - 1))
302 != 0)
303 max_align >>= 1;
305 exp = TREE_OPERAND (exp, 0);
306 break;
308 case ADDR_EXPR:
309 /* See what we are pointing at and look at its alignment. */
310 exp = TREE_OPERAND (exp, 0);
311 inner = max_align;
312 if (handled_component_p (exp))
314 HOST_WIDE_INT bitsize, bitpos;
315 tree offset;
316 enum machine_mode mode;
317 int unsignedp, volatilep;
319 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
320 &mode, &unsignedp, &volatilep, true);
321 if (bitpos)
322 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
323 if (offset && TREE_CODE (offset) == PLUS_EXPR
324 && host_integerp (TREE_OPERAND (offset, 1), 1))
326 /* Any overflow in calculating offset_bits won't change
327 the alignment. */
328 unsigned offset_bits
329 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
330 * BITS_PER_UNIT);
332 if (offset_bits)
333 inner = MIN (inner, (offset_bits & -offset_bits));
334 offset = TREE_OPERAND (offset, 0);
336 if (offset && TREE_CODE (offset) == MULT_EXPR
337 && host_integerp (TREE_OPERAND (offset, 1), 1))
339 /* Any overflow in calculating offset_factor won't change
340 the alignment. */
341 unsigned offset_factor
342 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
343 * BITS_PER_UNIT);
345 if (offset_factor)
346 inner = MIN (inner, (offset_factor & -offset_factor));
348 else if (offset)
349 inner = MIN (inner, BITS_PER_UNIT);
351 if (DECL_P (exp))
352 align = MIN (inner, DECL_ALIGN (exp));
353 #ifdef CONSTANT_ALIGNMENT
354 else if (CONSTANT_CLASS_P (exp))
355 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
356 #endif
357 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
358 || TREE_CODE (exp) == INDIRECT_REF)
359 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
360 else
361 align = MIN (align, inner);
362 return MIN (align, max_align);
364 default:
365 return align;
370 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
371 way, because it could contain a zero byte in the middle.
372 TREE_STRING_LENGTH is the size of the character array, not the string.
374 ONLY_VALUE should be nonzero if the result is not going to be emitted
375 into the instruction stream and zero if it is going to be expanded.
376 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
377 is returned, otherwise NULL, since
378 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
379 evaluate the side-effects.
381 The value returned is of type `ssizetype'.
383 Unfortunately, string_constant can't access the values of const char
384 arrays with initializers, so neither can we do so here. */
386 tree
387 c_strlen (tree src, int only_value)
389 tree offset_node;
390 HOST_WIDE_INT offset;
391 int max;
392 const char *ptr;
394 STRIP_NOPS (src);
395 if (TREE_CODE (src) == COND_EXPR
396 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
398 tree len1, len2;
400 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
401 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
402 if (tree_int_cst_equal (len1, len2))
403 return len1;
406 if (TREE_CODE (src) == COMPOUND_EXPR
407 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
408 return c_strlen (TREE_OPERAND (src, 1), only_value);
410 src = string_constant (src, &offset_node);
411 if (src == 0)
412 return NULL_TREE;
414 max = TREE_STRING_LENGTH (src) - 1;
415 ptr = TREE_STRING_POINTER (src);
417 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
419 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
420 compute the offset to the following null if we don't know where to
421 start searching for it. */
422 int i;
424 for (i = 0; i < max; i++)
425 if (ptr[i] == 0)
426 return NULL_TREE;
428 /* We don't know the starting offset, but we do know that the string
429 has no internal zero bytes. We can assume that the offset falls
430 within the bounds of the string; otherwise, the programmer deserves
431 what he gets. Subtract the offset from the length of the string,
432 and return that. This would perhaps not be valid if we were dealing
433 with named arrays in addition to literal string constants. */
435 return size_diffop (size_int (max), offset_node);
438 /* We have a known offset into the string. Start searching there for
439 a null character if we can represent it as a single HOST_WIDE_INT. */
440 if (offset_node == 0)
441 offset = 0;
442 else if (! host_integerp (offset_node, 0))
443 offset = -1;
444 else
445 offset = tree_low_cst (offset_node, 0);
447 /* If the offset is known to be out of bounds, warn, and call strlen at
448 runtime. */
449 if (offset < 0 || offset > max)
451 warning (0, "offset outside bounds of constant string");
452 return NULL_TREE;
455 /* Use strlen to search for the first zero byte. Since any strings
456 constructed with build_string will have nulls appended, we win even
457 if we get handed something like (char[4])"abcd".
459 Since OFFSET is our starting index into the string, no further
460 calculation is needed. */
461 return ssize_int (strlen (ptr + offset));
464 /* Return a char pointer for a C string if it is a string constant
465 or sum of string constant and integer constant. */
467 static const char *
468 c_getstr (tree src)
470 tree offset_node;
472 src = string_constant (src, &offset_node);
473 if (src == 0)
474 return 0;
476 if (offset_node == 0)
477 return TREE_STRING_POINTER (src);
478 else if (!host_integerp (offset_node, 1)
479 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
480 return 0;
482 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
485 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
486 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
488 static rtx
489 c_readstr (const char *str, enum machine_mode mode)
491 HOST_WIDE_INT c[2];
492 HOST_WIDE_INT ch;
493 unsigned int i, j;
495 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
497 c[0] = 0;
498 c[1] = 0;
499 ch = 1;
500 for (i = 0; i < GET_MODE_SIZE (mode); i++)
502 j = i;
503 if (WORDS_BIG_ENDIAN)
504 j = GET_MODE_SIZE (mode) - i - 1;
505 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
506 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
507 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
508 j *= BITS_PER_UNIT;
509 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
511 if (ch)
512 ch = (unsigned char) str[i];
513 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
515 return immed_double_const (c[0], c[1], mode);
518 /* Cast a target constant CST to target CHAR and if that value fits into
519 host char type, return zero and put that value into variable pointed to by
520 P. */
522 static int
523 target_char_cast (tree cst, char *p)
525 unsigned HOST_WIDE_INT val, hostval;
527 if (!host_integerp (cst, 1)
528 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
529 return 1;
531 val = tree_low_cst (cst, 1);
532 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
533 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
535 hostval = val;
536 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
537 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
539 if (val != hostval)
540 return 1;
542 *p = hostval;
543 return 0;
546 /* Similar to save_expr, but assumes that arbitrary code is not executed
547 in between the multiple evaluations. In particular, we assume that a
548 non-addressable local variable will not be modified. */
550 static tree
551 builtin_save_expr (tree exp)
553 if (TREE_ADDRESSABLE (exp) == 0
554 && (TREE_CODE (exp) == PARM_DECL
555 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
556 return exp;
558 return save_expr (exp);
561 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
562 times to get the address of either a higher stack frame, or a return
563 address located within it (depending on FNDECL_CODE). */
565 static rtx
566 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
568 int i;
570 #ifdef INITIAL_FRAME_ADDRESS_RTX
571 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
572 #else
573 rtx tem;
575 /* For a zero count with __builtin_return_address, we don't care what
576 frame address we return, because target-specific definitions will
577 override us. Therefore frame pointer elimination is OK, and using
578 the soft frame pointer is OK.
580 For a nonzero count, or a zero count with __builtin_frame_address,
581 we require a stable offset from the current frame pointer to the
582 previous one, so we must use the hard frame pointer, and
583 we must disable frame pointer elimination. */
584 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
585 tem = frame_pointer_rtx;
586 else
588 tem = hard_frame_pointer_rtx;
590 /* Tell reload not to eliminate the frame pointer. */
591 current_function_accesses_prior_frames = 1;
593 #endif
595 /* Some machines need special handling before we can access
596 arbitrary frames. For example, on the SPARC, we must first flush
597 all register windows to the stack. */
598 #ifdef SETUP_FRAME_ADDRESSES
599 if (count > 0)
600 SETUP_FRAME_ADDRESSES ();
601 #endif
603 /* On the SPARC, the return address is not in the frame, it is in a
604 register. There is no way to access it off of the current frame
605 pointer, but it can be accessed off the previous frame pointer by
606 reading the value from the register window save area. */
607 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
608 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
609 count--;
610 #endif
612 /* Scan back COUNT frames to the specified frame. */
613 for (i = 0; i < count; i++)
615 /* Assume the dynamic chain pointer is in the word that the
616 frame address points to, unless otherwise specified. */
617 #ifdef DYNAMIC_CHAIN_ADDRESS
618 tem = DYNAMIC_CHAIN_ADDRESS (tem);
619 #endif
620 tem = memory_address (Pmode, tem);
621 tem = gen_frame_mem (Pmode, tem);
622 tem = copy_to_reg (tem);
625 /* For __builtin_frame_address, return what we've got. But, on
626 the SPARC for example, we may have to add a bias. */
627 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
628 #ifdef FRAME_ADDR_RTX
629 return FRAME_ADDR_RTX (tem);
630 #else
631 return tem;
632 #endif
634 /* For __builtin_return_address, get the return address from that frame. */
635 #ifdef RETURN_ADDR_RTX
636 tem = RETURN_ADDR_RTX (count, tem);
637 #else
638 tem = memory_address (Pmode,
639 plus_constant (tem, GET_MODE_SIZE (Pmode)));
640 tem = gen_frame_mem (Pmode, tem);
641 #endif
642 return tem;
645 /* Alias set used for setjmp buffer. */
646 static alias_set_type setjmp_alias_set = -1;
648 /* Construct the leading half of a __builtin_setjmp call. Control will
649 return to RECEIVER_LABEL. This is also called directly by the SJLJ
650 exception handling code. */
652 void
653 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
655 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
656 rtx stack_save;
657 rtx mem;
659 if (setjmp_alias_set == -1)
660 setjmp_alias_set = new_alias_set ();
662 buf_addr = convert_memory_address (Pmode, buf_addr);
664 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
666 /* We store the frame pointer and the address of receiver_label in
667 the buffer and use the rest of it for the stack save area, which
668 is machine-dependent. */
670 mem = gen_rtx_MEM (Pmode, buf_addr);
671 set_mem_alias_set (mem, setjmp_alias_set);
672 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
674 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
675 set_mem_alias_set (mem, setjmp_alias_set);
677 emit_move_insn (validize_mem (mem),
678 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
680 stack_save = gen_rtx_MEM (sa_mode,
681 plus_constant (buf_addr,
682 2 * GET_MODE_SIZE (Pmode)));
683 set_mem_alias_set (stack_save, setjmp_alias_set);
684 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
686 /* If there is further processing to do, do it. */
687 #ifdef HAVE_builtin_setjmp_setup
688 if (HAVE_builtin_setjmp_setup)
689 emit_insn (gen_builtin_setjmp_setup (buf_addr));
690 #endif
692 /* Tell optimize_save_area_alloca that extra work is going to
693 need to go on during alloca. */
694 current_function_calls_setjmp = 1;
696 /* We have a nonlocal label. */
697 current_function_has_nonlocal_label = 1;
700 /* Construct the trailing part of a __builtin_setjmp call. This is
701 also called directly by the SJLJ exception handling code. */
703 void
704 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
706 /* Clobber the FP when we get here, so we have to make sure it's
707 marked as used by this function. */
708 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
710 /* Mark the static chain as clobbered here so life information
711 doesn't get messed up for it. */
712 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
714 /* Now put in the code to restore the frame pointer, and argument
715 pointer, if needed. */
716 #ifdef HAVE_nonlocal_goto
717 if (! HAVE_nonlocal_goto)
718 #endif
720 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
721 /* This might change the hard frame pointer in ways that aren't
722 apparent to early optimization passes, so force a clobber. */
723 emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx));
726 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
727 if (fixed_regs[ARG_POINTER_REGNUM])
729 #ifdef ELIMINABLE_REGS
730 size_t i;
731 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
733 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
734 if (elim_regs[i].from == ARG_POINTER_REGNUM
735 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
736 break;
738 if (i == ARRAY_SIZE (elim_regs))
739 #endif
741 /* Now restore our arg pointer from the address at which it
742 was saved in our stack frame. */
743 emit_move_insn (virtual_incoming_args_rtx,
744 copy_to_reg (get_arg_pointer_save_area (cfun)));
747 #endif
749 #ifdef HAVE_builtin_setjmp_receiver
750 if (HAVE_builtin_setjmp_receiver)
751 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
752 else
753 #endif
754 #ifdef HAVE_nonlocal_goto_receiver
755 if (HAVE_nonlocal_goto_receiver)
756 emit_insn (gen_nonlocal_goto_receiver ());
757 else
758 #endif
759 { /* Nothing */ }
761 /* We must not allow the code we just generated to be reordered by
762 scheduling. Specifically, the update of the frame pointer must
763 happen immediately, not later. */
764 emit_insn (gen_blockage ());
767 /* __builtin_longjmp is passed a pointer to an array of five words (not
768 all will be used on all machines). It operates similarly to the C
769 library function of the same name, but is more efficient. Much of
770 the code below is copied from the handling of non-local gotos. */
772 static void
773 expand_builtin_longjmp (rtx buf_addr, rtx value)
775 rtx fp, lab, stack, insn, last;
776 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
778 if (setjmp_alias_set == -1)
779 setjmp_alias_set = new_alias_set ();
781 buf_addr = convert_memory_address (Pmode, buf_addr);
783 buf_addr = force_reg (Pmode, buf_addr);
785 /* We used to store value in static_chain_rtx, but that fails if pointers
786 are smaller than integers. We instead require that the user must pass
787 a second argument of 1, because that is what builtin_setjmp will
788 return. This also makes EH slightly more efficient, since we are no
789 longer copying around a value that we don't care about. */
790 gcc_assert (value == const1_rtx);
792 last = get_last_insn ();
793 #ifdef HAVE_builtin_longjmp
794 if (HAVE_builtin_longjmp)
795 emit_insn (gen_builtin_longjmp (buf_addr));
796 else
797 #endif
799 fp = gen_rtx_MEM (Pmode, buf_addr);
800 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
801 GET_MODE_SIZE (Pmode)));
803 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
804 2 * GET_MODE_SIZE (Pmode)));
805 set_mem_alias_set (fp, setjmp_alias_set);
806 set_mem_alias_set (lab, setjmp_alias_set);
807 set_mem_alias_set (stack, setjmp_alias_set);
809 /* Pick up FP, label, and SP from the block and jump. This code is
810 from expand_goto in stmt.c; see there for detailed comments. */
811 #ifdef HAVE_nonlocal_goto
812 if (HAVE_nonlocal_goto)
813 /* We have to pass a value to the nonlocal_goto pattern that will
814 get copied into the static_chain pointer, but it does not matter
815 what that value is, because builtin_setjmp does not use it. */
816 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
817 else
818 #endif
820 lab = copy_to_reg (lab);
822 emit_insn (gen_rtx_CLOBBER (VOIDmode,
823 gen_rtx_MEM (BLKmode,
824 gen_rtx_SCRATCH (VOIDmode))));
825 emit_insn (gen_rtx_CLOBBER (VOIDmode,
826 gen_rtx_MEM (BLKmode,
827 hard_frame_pointer_rtx)));
829 emit_move_insn (hard_frame_pointer_rtx, fp);
830 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
832 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
833 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
834 emit_indirect_jump (lab);
838 /* Search backwards and mark the jump insn as a non-local goto.
839 Note that this precludes the use of __builtin_longjmp to a
840 __builtin_setjmp target in the same function. However, we've
841 already cautioned the user that these functions are for
842 internal exception handling use only. */
843 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
845 gcc_assert (insn != last);
847 if (JUMP_P (insn))
849 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
850 REG_NOTES (insn));
851 break;
853 else if (CALL_P (insn))
854 break;
858 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
859 and the address of the save area. */
861 static rtx
862 expand_builtin_nonlocal_goto (tree exp)
864 tree t_label, t_save_area;
865 rtx r_label, r_save_area, r_fp, r_sp, insn;
867 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
868 return NULL_RTX;
870 t_label = CALL_EXPR_ARG (exp, 0);
871 t_save_area = CALL_EXPR_ARG (exp, 1);
873 r_label = expand_normal (t_label);
874 r_label = convert_memory_address (Pmode, r_label);
875 r_save_area = expand_normal (t_save_area);
876 r_save_area = convert_memory_address (Pmode, r_save_area);
877 r_fp = gen_rtx_MEM (Pmode, r_save_area);
878 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
879 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
881 current_function_has_nonlocal_goto = 1;
883 #ifdef HAVE_nonlocal_goto
884 /* ??? We no longer need to pass the static chain value, afaik. */
885 if (HAVE_nonlocal_goto)
886 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
887 else
888 #endif
890 r_label = copy_to_reg (r_label);
892 emit_insn (gen_rtx_CLOBBER (VOIDmode,
893 gen_rtx_MEM (BLKmode,
894 gen_rtx_SCRATCH (VOIDmode))));
896 emit_insn (gen_rtx_CLOBBER (VOIDmode,
897 gen_rtx_MEM (BLKmode,
898 hard_frame_pointer_rtx)));
900 /* Restore frame pointer for containing function.
901 This sets the actual hard register used for the frame pointer
902 to the location of the function's incoming static chain info.
903 The non-local goto handler will then adjust it to contain the
904 proper value and reload the argument pointer, if needed. */
905 emit_move_insn (hard_frame_pointer_rtx, r_fp);
906 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
908 /* USE of hard_frame_pointer_rtx added for consistency;
909 not clear if really needed. */
910 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
911 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
912 emit_indirect_jump (r_label);
915 /* Search backwards to the jump insn and mark it as a
916 non-local goto. */
917 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
919 if (JUMP_P (insn))
921 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
922 const0_rtx, REG_NOTES (insn));
923 break;
925 else if (CALL_P (insn))
926 break;
929 return const0_rtx;
932 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
933 (not all will be used on all machines) that was passed to __builtin_setjmp.
934 It updates the stack pointer in that block to correspond to the current
935 stack pointer. */
937 static void
938 expand_builtin_update_setjmp_buf (rtx buf_addr)
940 enum machine_mode sa_mode = Pmode;
941 rtx stack_save;
944 #ifdef HAVE_save_stack_nonlocal
945 if (HAVE_save_stack_nonlocal)
946 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
947 #endif
948 #ifdef STACK_SAVEAREA_MODE
949 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
950 #endif
952 stack_save
953 = gen_rtx_MEM (sa_mode,
954 memory_address
955 (sa_mode,
956 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
958 #ifdef HAVE_setjmp
959 if (HAVE_setjmp)
960 emit_insn (gen_setjmp ());
961 #endif
963 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
966 /* Expand a call to __builtin_prefetch. For a target that does not support
967 data prefetch, evaluate the memory address argument in case it has side
968 effects. */
970 static void
971 expand_builtin_prefetch (tree exp)
973 tree arg0, arg1, arg2;
974 int nargs;
975 rtx op0, op1, op2;
977 if (!validate_arglist (exp, POINTER_TYPE, 0))
978 return;
980 arg0 = CALL_EXPR_ARG (exp, 0);
982 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
983 zero (read) and argument 2 (locality) defaults to 3 (high degree of
984 locality). */
985 nargs = call_expr_nargs (exp);
986 if (nargs > 1)
987 arg1 = CALL_EXPR_ARG (exp, 1);
988 else
989 arg1 = integer_zero_node;
990 if (nargs > 2)
991 arg2 = CALL_EXPR_ARG (exp, 2);
992 else
993 arg2 = build_int_cst (NULL_TREE, 3);
995 /* Argument 0 is an address. */
996 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
998 /* Argument 1 (read/write flag) must be a compile-time constant int. */
999 if (TREE_CODE (arg1) != INTEGER_CST)
1001 error ("second argument to %<__builtin_prefetch%> must be a constant");
1002 arg1 = integer_zero_node;
1004 op1 = expand_normal (arg1);
1005 /* Argument 1 must be either zero or one. */
1006 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1008 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1009 " using zero");
1010 op1 = const0_rtx;
1013 /* Argument 2 (locality) must be a compile-time constant int. */
1014 if (TREE_CODE (arg2) != INTEGER_CST)
1016 error ("third argument to %<__builtin_prefetch%> must be a constant");
1017 arg2 = integer_zero_node;
1019 op2 = expand_normal (arg2);
1020 /* Argument 2 must be 0, 1, 2, or 3. */
1021 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1023 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1024 op2 = const0_rtx;
1027 #ifdef HAVE_prefetch
1028 if (HAVE_prefetch)
1030 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1031 (op0,
1032 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1033 || (GET_MODE (op0) != Pmode))
1035 op0 = convert_memory_address (Pmode, op0);
1036 op0 = force_reg (Pmode, op0);
1038 emit_insn (gen_prefetch (op0, op1, op2));
1040 #endif
1042 /* Don't do anything with direct references to volatile memory, but
1043 generate code to handle other side effects. */
1044 if (!MEM_P (op0) && side_effects_p (op0))
1045 emit_insn (op0);
1048 /* Get a MEM rtx for expression EXP which is the address of an operand
1049 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1050 the maximum length of the block of memory that might be accessed or
1051 NULL if unknown. */
1053 static rtx
1054 get_memory_rtx (tree exp, tree len)
1056 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1057 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1059 /* Get an expression we can use to find the attributes to assign to MEM.
1060 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1061 we can. First remove any nops. */
1062 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1063 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1064 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1065 exp = TREE_OPERAND (exp, 0);
1067 if (TREE_CODE (exp) == ADDR_EXPR)
1068 exp = TREE_OPERAND (exp, 0);
1069 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1070 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1071 else
1072 exp = NULL;
1074 /* Honor attributes derived from exp, except for the alias set
1075 (as builtin stringops may alias with anything) and the size
1076 (as stringops may access multiple array elements). */
1077 if (exp)
1079 set_mem_attributes (mem, exp, 0);
1081 /* Allow the string and memory builtins to overflow from one
1082 field into another, see http://gcc.gnu.org/PR23561.
1083 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1084 memory accessed by the string or memory builtin will fit
1085 within the field. */
1086 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1088 tree mem_expr = MEM_EXPR (mem);
1089 HOST_WIDE_INT offset = -1, length = -1;
1090 tree inner = exp;
1092 while (TREE_CODE (inner) == ARRAY_REF
1093 || TREE_CODE (inner) == NOP_EXPR
1094 || TREE_CODE (inner) == CONVERT_EXPR
1095 || TREE_CODE (inner) == NON_LVALUE_EXPR
1096 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1097 || TREE_CODE (inner) == SAVE_EXPR)
1098 inner = TREE_OPERAND (inner, 0);
1100 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1102 if (MEM_OFFSET (mem)
1103 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1104 offset = INTVAL (MEM_OFFSET (mem));
1106 if (offset >= 0 && len && host_integerp (len, 0))
1107 length = tree_low_cst (len, 0);
1109 while (TREE_CODE (inner) == COMPONENT_REF)
1111 tree field = TREE_OPERAND (inner, 1);
1112 gcc_assert (! DECL_BIT_FIELD (field));
1113 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1114 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1116 if (length >= 0
1117 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1118 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1120 HOST_WIDE_INT size
1121 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1122 /* If we can prove the memory starting at XEXP (mem, 0)
1123 and ending at XEXP (mem, 0) + LENGTH will fit into
1124 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1125 if (offset <= size
1126 && length <= size
1127 && offset + length <= size)
1128 break;
1131 if (offset >= 0
1132 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1133 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1134 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1135 / BITS_PER_UNIT;
1136 else
1138 offset = -1;
1139 length = -1;
1142 mem_expr = TREE_OPERAND (mem_expr, 0);
1143 inner = TREE_OPERAND (inner, 0);
1146 if (mem_expr == NULL)
1147 offset = -1;
1148 if (mem_expr != MEM_EXPR (mem))
1150 set_mem_expr (mem, mem_expr);
1151 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1154 set_mem_alias_set (mem, 0);
1155 set_mem_size (mem, NULL_RTX);
1158 return mem;
1161 /* Built-in functions to perform an untyped call and return. */
1163 /* For each register that may be used for calling a function, this
1164 gives a mode used to copy the register's value. VOIDmode indicates
1165 the register is not used for calling a function. If the machine
1166 has register windows, this gives only the outbound registers.
1167 INCOMING_REGNO gives the corresponding inbound register. */
1168 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1170 /* For each register that may be used for returning values, this gives
1171 a mode used to copy the register's value. VOIDmode indicates the
1172 register is not used for returning values. If the machine has
1173 register windows, this gives only the outbound registers.
1174 INCOMING_REGNO gives the corresponding inbound register. */
1175 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1177 /* For each register that may be used for calling a function, this
1178 gives the offset of that register into the block returned by
1179 __builtin_apply_args. 0 indicates that the register is not
1180 used for calling a function. */
1181 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1183 /* Return the size required for the block returned by __builtin_apply_args,
1184 and initialize apply_args_mode. */
1186 static int
1187 apply_args_size (void)
1189 static int size = -1;
1190 int align;
1191 unsigned int regno;
1192 enum machine_mode mode;
1194 /* The values computed by this function never change. */
1195 if (size < 0)
1197 /* The first value is the incoming arg-pointer. */
1198 size = GET_MODE_SIZE (Pmode);
1200 /* The second value is the structure value address unless this is
1201 passed as an "invisible" first argument. */
1202 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1203 size += GET_MODE_SIZE (Pmode);
1205 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1206 if (FUNCTION_ARG_REGNO_P (regno))
1208 mode = reg_raw_mode[regno];
1210 gcc_assert (mode != VOIDmode);
1212 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1213 if (size % align != 0)
1214 size = CEIL (size, align) * align;
1215 apply_args_reg_offset[regno] = size;
1216 size += GET_MODE_SIZE (mode);
1217 apply_args_mode[regno] = mode;
1219 else
1221 apply_args_mode[regno] = VOIDmode;
1222 apply_args_reg_offset[regno] = 0;
1225 return size;
1228 /* Return the size required for the block returned by __builtin_apply,
1229 and initialize apply_result_mode. */
1231 static int
1232 apply_result_size (void)
1234 static int size = -1;
1235 int align, regno;
1236 enum machine_mode mode;
1238 /* The values computed by this function never change. */
1239 if (size < 0)
1241 size = 0;
1243 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1244 if (FUNCTION_VALUE_REGNO_P (regno))
1246 mode = reg_raw_mode[regno];
1248 gcc_assert (mode != VOIDmode);
1250 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1251 if (size % align != 0)
1252 size = CEIL (size, align) * align;
1253 size += GET_MODE_SIZE (mode);
1254 apply_result_mode[regno] = mode;
1256 else
1257 apply_result_mode[regno] = VOIDmode;
1259 /* Allow targets that use untyped_call and untyped_return to override
1260 the size so that machine-specific information can be stored here. */
1261 #ifdef APPLY_RESULT_SIZE
1262 size = APPLY_RESULT_SIZE;
1263 #endif
1265 return size;
1268 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1269 /* Create a vector describing the result block RESULT. If SAVEP is true,
1270 the result block is used to save the values; otherwise it is used to
1271 restore the values. */
1273 static rtx
1274 result_vector (int savep, rtx result)
1276 int regno, size, align, nelts;
1277 enum machine_mode mode;
1278 rtx reg, mem;
1279 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1281 size = nelts = 0;
1282 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1283 if ((mode = apply_result_mode[regno]) != VOIDmode)
1285 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1286 if (size % align != 0)
1287 size = CEIL (size, align) * align;
1288 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1289 mem = adjust_address (result, mode, size);
1290 savevec[nelts++] = (savep
1291 ? gen_rtx_SET (VOIDmode, mem, reg)
1292 : gen_rtx_SET (VOIDmode, reg, mem));
1293 size += GET_MODE_SIZE (mode);
1295 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1297 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1299 /* Save the state required to perform an untyped call with the same
1300 arguments as were passed to the current function. */
1302 static rtx
1303 expand_builtin_apply_args_1 (void)
1305 rtx registers, tem;
1306 int size, align, regno;
1307 enum machine_mode mode;
1308 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1310 /* Create a block where the arg-pointer, structure value address,
1311 and argument registers can be saved. */
1312 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1314 /* Walk past the arg-pointer and structure value address. */
1315 size = GET_MODE_SIZE (Pmode);
1316 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1317 size += GET_MODE_SIZE (Pmode);
1319 /* Save each register used in calling a function to the block. */
1320 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1321 if ((mode = apply_args_mode[regno]) != VOIDmode)
1323 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1324 if (size % align != 0)
1325 size = CEIL (size, align) * align;
1327 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1329 emit_move_insn (adjust_address (registers, mode, size), tem);
1330 size += GET_MODE_SIZE (mode);
1333 /* Save the arg pointer to the block. */
1334 tem = copy_to_reg (virtual_incoming_args_rtx);
1335 #ifdef STACK_GROWS_DOWNWARD
1336 /* We need the pointer as the caller actually passed them to us, not
1337 as we might have pretended they were passed. Make sure it's a valid
1338 operand, as emit_move_insn isn't expected to handle a PLUS. */
1340 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1341 NULL_RTX);
1342 #endif
1343 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1345 size = GET_MODE_SIZE (Pmode);
1347 /* Save the structure value address unless this is passed as an
1348 "invisible" first argument. */
1349 if (struct_incoming_value)
1351 emit_move_insn (adjust_address (registers, Pmode, size),
1352 copy_to_reg (struct_incoming_value));
1353 size += GET_MODE_SIZE (Pmode);
1356 /* Return the address of the block. */
1357 return copy_addr_to_reg (XEXP (registers, 0));
1360 /* __builtin_apply_args returns block of memory allocated on
1361 the stack into which is stored the arg pointer, structure
1362 value address, static chain, and all the registers that might
1363 possibly be used in performing a function call. The code is
1364 moved to the start of the function so the incoming values are
1365 saved. */
1367 static rtx
1368 expand_builtin_apply_args (void)
1370 /* Don't do __builtin_apply_args more than once in a function.
1371 Save the result of the first call and reuse it. */
1372 if (apply_args_value != 0)
1373 return apply_args_value;
1375 /* When this function is called, it means that registers must be
1376 saved on entry to this function. So we migrate the
1377 call to the first insn of this function. */
1378 rtx temp;
1379 rtx seq;
1381 start_sequence ();
1382 temp = expand_builtin_apply_args_1 ();
1383 seq = get_insns ();
1384 end_sequence ();
1386 apply_args_value = temp;
1388 /* Put the insns after the NOTE that starts the function.
1389 If this is inside a start_sequence, make the outer-level insn
1390 chain current, so the code is placed at the start of the
1391 function. */
1392 push_topmost_sequence ();
1393 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1394 pop_topmost_sequence ();
1395 return temp;
1399 /* Perform an untyped call and save the state required to perform an
1400 untyped return of whatever value was returned by the given function. */
1402 static rtx
1403 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1405 int size, align, regno;
1406 enum machine_mode mode;
1407 rtx incoming_args, result, reg, dest, src, call_insn;
1408 rtx old_stack_level = 0;
1409 rtx call_fusage = 0;
1410 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1412 arguments = convert_memory_address (Pmode, arguments);
1414 /* Create a block where the return registers can be saved. */
1415 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1417 /* Fetch the arg pointer from the ARGUMENTS block. */
1418 incoming_args = gen_reg_rtx (Pmode);
1419 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1420 #ifndef STACK_GROWS_DOWNWARD
1421 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1422 incoming_args, 0, OPTAB_LIB_WIDEN);
1423 #endif
1425 /* Push a new argument block and copy the arguments. Do not allow
1426 the (potential) memcpy call below to interfere with our stack
1427 manipulations. */
1428 do_pending_stack_adjust ();
1429 NO_DEFER_POP;
1431 /* Save the stack with nonlocal if available. */
1432 #ifdef HAVE_save_stack_nonlocal
1433 if (HAVE_save_stack_nonlocal)
1434 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1435 else
1436 #endif
1437 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1439 /* Allocate a block of memory onto the stack and copy the memory
1440 arguments to the outgoing arguments address. */
1441 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1442 dest = virtual_outgoing_args_rtx;
1443 #ifndef STACK_GROWS_DOWNWARD
1444 if (GET_CODE (argsize) == CONST_INT)
1445 dest = plus_constant (dest, -INTVAL (argsize));
1446 else
1447 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1448 #endif
1449 dest = gen_rtx_MEM (BLKmode, dest);
1450 set_mem_align (dest, PARM_BOUNDARY);
1451 src = gen_rtx_MEM (BLKmode, incoming_args);
1452 set_mem_align (src, PARM_BOUNDARY);
1453 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1455 /* Refer to the argument block. */
1456 apply_args_size ();
1457 arguments = gen_rtx_MEM (BLKmode, arguments);
1458 set_mem_align (arguments, PARM_BOUNDARY);
1460 /* Walk past the arg-pointer and structure value address. */
1461 size = GET_MODE_SIZE (Pmode);
1462 if (struct_value)
1463 size += GET_MODE_SIZE (Pmode);
1465 /* Restore each of the registers previously saved. Make USE insns
1466 for each of these registers for use in making the call. */
1467 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1468 if ((mode = apply_args_mode[regno]) != VOIDmode)
1470 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1471 if (size % align != 0)
1472 size = CEIL (size, align) * align;
1473 reg = gen_rtx_REG (mode, regno);
1474 emit_move_insn (reg, adjust_address (arguments, mode, size));
1475 use_reg (&call_fusage, reg);
1476 size += GET_MODE_SIZE (mode);
1479 /* Restore the structure value address unless this is passed as an
1480 "invisible" first argument. */
1481 size = GET_MODE_SIZE (Pmode);
1482 if (struct_value)
1484 rtx value = gen_reg_rtx (Pmode);
1485 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1486 emit_move_insn (struct_value, value);
1487 if (REG_P (struct_value))
1488 use_reg (&call_fusage, struct_value);
1489 size += GET_MODE_SIZE (Pmode);
1492 /* All arguments and registers used for the call are set up by now! */
1493 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1495 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1496 and we don't want to load it into a register as an optimization,
1497 because prepare_call_address already did it if it should be done. */
1498 if (GET_CODE (function) != SYMBOL_REF)
1499 function = memory_address (FUNCTION_MODE, function);
1501 /* Generate the actual call instruction and save the return value. */
1502 #ifdef HAVE_untyped_call
1503 if (HAVE_untyped_call)
1504 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1505 result, result_vector (1, result)));
1506 else
1507 #endif
1508 #ifdef HAVE_call_value
1509 if (HAVE_call_value)
1511 rtx valreg = 0;
1513 /* Locate the unique return register. It is not possible to
1514 express a call that sets more than one return register using
1515 call_value; use untyped_call for that. In fact, untyped_call
1516 only needs to save the return registers in the given block. */
1517 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1518 if ((mode = apply_result_mode[regno]) != VOIDmode)
1520 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1522 valreg = gen_rtx_REG (mode, regno);
1525 emit_call_insn (GEN_CALL_VALUE (valreg,
1526 gen_rtx_MEM (FUNCTION_MODE, function),
1527 const0_rtx, NULL_RTX, const0_rtx));
1529 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1531 else
1532 #endif
1533 gcc_unreachable ();
1535 /* Find the CALL insn we just emitted, and attach the register usage
1536 information. */
1537 call_insn = last_call_insn ();
1538 add_function_usage_to (call_insn, call_fusage);
1540 /* Restore the stack. */
1541 #ifdef HAVE_save_stack_nonlocal
1542 if (HAVE_save_stack_nonlocal)
1543 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1544 else
1545 #endif
1546 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1548 OK_DEFER_POP;
1550 /* Return the address of the result block. */
1551 result = copy_addr_to_reg (XEXP (result, 0));
1552 return convert_memory_address (ptr_mode, result);
1555 /* Perform an untyped return. */
1557 static void
1558 expand_builtin_return (rtx result)
1560 int size, align, regno;
1561 enum machine_mode mode;
1562 rtx reg;
1563 rtx call_fusage = 0;
1565 result = convert_memory_address (Pmode, result);
1567 apply_result_size ();
1568 result = gen_rtx_MEM (BLKmode, result);
1570 #ifdef HAVE_untyped_return
1571 if (HAVE_untyped_return)
1573 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1574 emit_barrier ();
1575 return;
1577 #endif
1579 /* Restore the return value and note that each value is used. */
1580 size = 0;
1581 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1582 if ((mode = apply_result_mode[regno]) != VOIDmode)
1584 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1585 if (size % align != 0)
1586 size = CEIL (size, align) * align;
1587 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1588 emit_move_insn (reg, adjust_address (result, mode, size));
1590 push_to_sequence (call_fusage);
1591 emit_insn (gen_rtx_USE (VOIDmode, reg));
1592 call_fusage = get_insns ();
1593 end_sequence ();
1594 size += GET_MODE_SIZE (mode);
1597 /* Put the USE insns before the return. */
1598 emit_insn (call_fusage);
1600 /* Return whatever values was restored by jumping directly to the end
1601 of the function. */
1602 expand_naked_return ();
1605 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1607 static enum type_class
1608 type_to_class (tree type)
1610 switch (TREE_CODE (type))
1612 case VOID_TYPE: return void_type_class;
1613 case INTEGER_TYPE: return integer_type_class;
1614 case ENUMERAL_TYPE: return enumeral_type_class;
1615 case BOOLEAN_TYPE: return boolean_type_class;
1616 case POINTER_TYPE: return pointer_type_class;
1617 case REFERENCE_TYPE: return reference_type_class;
1618 case OFFSET_TYPE: return offset_type_class;
1619 case REAL_TYPE: return real_type_class;
1620 case COMPLEX_TYPE: return complex_type_class;
1621 case FUNCTION_TYPE: return function_type_class;
1622 case METHOD_TYPE: return method_type_class;
1623 case RECORD_TYPE: return record_type_class;
1624 case UNION_TYPE:
1625 case QUAL_UNION_TYPE: return union_type_class;
1626 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1627 ? string_type_class : array_type_class);
1628 case LANG_TYPE: return lang_type_class;
1629 default: return no_type_class;
1633 /* Expand a call EXP to __builtin_classify_type. */
1635 static rtx
1636 expand_builtin_classify_type (tree exp)
1638 if (call_expr_nargs (exp))
1639 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
1640 return GEN_INT (no_type_class);
1643 /* This helper macro, meant to be used in mathfn_built_in below,
1644 determines which among a set of three builtin math functions is
1645 appropriate for a given type mode. The `F' and `L' cases are
1646 automatically generated from the `double' case. */
1647 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1648 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1649 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1650 fcodel = BUILT_IN_MATHFN##L ; break;
1651 /* Similar to above, but appends _R after any F/L suffix. */
1652 #define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1653 case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1654 fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1655 fcodel = BUILT_IN_MATHFN##L_R ; break;
1657 /* Return mathematic function equivalent to FN but operating directly
1658 on TYPE, if available. If we can't do the conversion, return zero. */
1659 tree
1660 mathfn_built_in (tree type, enum built_in_function fn)
1662 enum built_in_function fcode, fcodef, fcodel;
1664 switch (fn)
1666 CASE_MATHFN (BUILT_IN_ACOS)
1667 CASE_MATHFN (BUILT_IN_ACOSH)
1668 CASE_MATHFN (BUILT_IN_ASIN)
1669 CASE_MATHFN (BUILT_IN_ASINH)
1670 CASE_MATHFN (BUILT_IN_ATAN)
1671 CASE_MATHFN (BUILT_IN_ATAN2)
1672 CASE_MATHFN (BUILT_IN_ATANH)
1673 CASE_MATHFN (BUILT_IN_CBRT)
1674 CASE_MATHFN (BUILT_IN_CEIL)
1675 CASE_MATHFN (BUILT_IN_CEXPI)
1676 CASE_MATHFN (BUILT_IN_COPYSIGN)
1677 CASE_MATHFN (BUILT_IN_COS)
1678 CASE_MATHFN (BUILT_IN_COSH)
1679 CASE_MATHFN (BUILT_IN_DREM)
1680 CASE_MATHFN (BUILT_IN_ERF)
1681 CASE_MATHFN (BUILT_IN_ERFC)
1682 CASE_MATHFN (BUILT_IN_EXP)
1683 CASE_MATHFN (BUILT_IN_EXP10)
1684 CASE_MATHFN (BUILT_IN_EXP2)
1685 CASE_MATHFN (BUILT_IN_EXPM1)
1686 CASE_MATHFN (BUILT_IN_FABS)
1687 CASE_MATHFN (BUILT_IN_FDIM)
1688 CASE_MATHFN (BUILT_IN_FLOOR)
1689 CASE_MATHFN (BUILT_IN_FMA)
1690 CASE_MATHFN (BUILT_IN_FMAX)
1691 CASE_MATHFN (BUILT_IN_FMIN)
1692 CASE_MATHFN (BUILT_IN_FMOD)
1693 CASE_MATHFN (BUILT_IN_FREXP)
1694 CASE_MATHFN (BUILT_IN_GAMMA)
1695 CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
1696 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1697 CASE_MATHFN (BUILT_IN_HYPOT)
1698 CASE_MATHFN (BUILT_IN_ILOGB)
1699 CASE_MATHFN (BUILT_IN_INF)
1700 CASE_MATHFN (BUILT_IN_ISINF)
1701 CASE_MATHFN (BUILT_IN_J0)
1702 CASE_MATHFN (BUILT_IN_J1)
1703 CASE_MATHFN (BUILT_IN_JN)
1704 CASE_MATHFN (BUILT_IN_LCEIL)
1705 CASE_MATHFN (BUILT_IN_LDEXP)
1706 CASE_MATHFN (BUILT_IN_LFLOOR)
1707 CASE_MATHFN (BUILT_IN_LGAMMA)
1708 CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
1709 CASE_MATHFN (BUILT_IN_LLCEIL)
1710 CASE_MATHFN (BUILT_IN_LLFLOOR)
1711 CASE_MATHFN (BUILT_IN_LLRINT)
1712 CASE_MATHFN (BUILT_IN_LLROUND)
1713 CASE_MATHFN (BUILT_IN_LOG)
1714 CASE_MATHFN (BUILT_IN_LOG10)
1715 CASE_MATHFN (BUILT_IN_LOG1P)
1716 CASE_MATHFN (BUILT_IN_LOG2)
1717 CASE_MATHFN (BUILT_IN_LOGB)
1718 CASE_MATHFN (BUILT_IN_LRINT)
1719 CASE_MATHFN (BUILT_IN_LROUND)
1720 CASE_MATHFN (BUILT_IN_MODF)
1721 CASE_MATHFN (BUILT_IN_NAN)
1722 CASE_MATHFN (BUILT_IN_NANS)
1723 CASE_MATHFN (BUILT_IN_NEARBYINT)
1724 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1725 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1726 CASE_MATHFN (BUILT_IN_POW)
1727 CASE_MATHFN (BUILT_IN_POWI)
1728 CASE_MATHFN (BUILT_IN_POW10)
1729 CASE_MATHFN (BUILT_IN_REMAINDER)
1730 CASE_MATHFN (BUILT_IN_REMQUO)
1731 CASE_MATHFN (BUILT_IN_RINT)
1732 CASE_MATHFN (BUILT_IN_ROUND)
1733 CASE_MATHFN (BUILT_IN_SCALB)
1734 CASE_MATHFN (BUILT_IN_SCALBLN)
1735 CASE_MATHFN (BUILT_IN_SCALBN)
1736 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1737 CASE_MATHFN (BUILT_IN_SIN)
1738 CASE_MATHFN (BUILT_IN_SINCOS)
1739 CASE_MATHFN (BUILT_IN_SINH)
1740 CASE_MATHFN (BUILT_IN_SQRT)
1741 CASE_MATHFN (BUILT_IN_TAN)
1742 CASE_MATHFN (BUILT_IN_TANH)
1743 CASE_MATHFN (BUILT_IN_TGAMMA)
1744 CASE_MATHFN (BUILT_IN_TRUNC)
1745 CASE_MATHFN (BUILT_IN_Y0)
1746 CASE_MATHFN (BUILT_IN_Y1)
1747 CASE_MATHFN (BUILT_IN_YN)
1749 default:
1750 return NULL_TREE;
1753 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1754 return implicit_built_in_decls[fcode];
1755 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1756 return implicit_built_in_decls[fcodef];
1757 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1758 return implicit_built_in_decls[fcodel];
1759 else
1760 return NULL_TREE;
1763 /* If errno must be maintained, expand the RTL to check if the result,
1764 TARGET, of a built-in function call, EXP, is NaN, and if so set
1765 errno to EDOM. */
1767 static void
1768 expand_errno_check (tree exp, rtx target)
1770 rtx lab = gen_label_rtx ();
1772 /* Test the result; if it is NaN, set errno=EDOM because
1773 the argument was not in the domain. */
1774 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1775 0, lab);
1777 #ifdef TARGET_EDOM
1778 /* If this built-in doesn't throw an exception, set errno directly. */
1779 if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
1781 #ifdef GEN_ERRNO_RTX
1782 rtx errno_rtx = GEN_ERRNO_RTX;
1783 #else
1784 rtx errno_rtx
1785 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1786 #endif
1787 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1788 emit_label (lab);
1789 return;
1791 #endif
1793 /* We can't set errno=EDOM directly; let the library call do it.
1794 Pop the arguments right away in case the call gets deleted. */
1795 NO_DEFER_POP;
1796 expand_call (exp, target, 0);
1797 OK_DEFER_POP;
1798 emit_label (lab);
1801 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1802 Return NULL_RTX if a normal call should be emitted rather than expanding
1803 the function in-line. EXP is the expression that is a call to the builtin
1804 function; if convenient, the result should be placed in TARGET.
1805 SUBTARGET may be used as the target for computing one of EXP's operands. */
1807 static rtx
1808 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1810 optab builtin_optab;
1811 rtx op0, insns, before_call;
1812 tree fndecl = get_callee_fndecl (exp);
1813 enum machine_mode mode;
1814 bool errno_set = false;
1815 tree arg;
1817 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1818 return NULL_RTX;
1820 arg = CALL_EXPR_ARG (exp, 0);
1822 switch (DECL_FUNCTION_CODE (fndecl))
1824 CASE_FLT_FN (BUILT_IN_SQRT):
1825 errno_set = ! tree_expr_nonnegative_p (arg);
1826 builtin_optab = sqrt_optab;
1827 break;
1828 CASE_FLT_FN (BUILT_IN_EXP):
1829 errno_set = true; builtin_optab = exp_optab; break;
1830 CASE_FLT_FN (BUILT_IN_EXP10):
1831 CASE_FLT_FN (BUILT_IN_POW10):
1832 errno_set = true; builtin_optab = exp10_optab; break;
1833 CASE_FLT_FN (BUILT_IN_EXP2):
1834 errno_set = true; builtin_optab = exp2_optab; break;
1835 CASE_FLT_FN (BUILT_IN_EXPM1):
1836 errno_set = true; builtin_optab = expm1_optab; break;
1837 CASE_FLT_FN (BUILT_IN_LOGB):
1838 errno_set = true; builtin_optab = logb_optab; break;
1839 CASE_FLT_FN (BUILT_IN_LOG):
1840 errno_set = true; builtin_optab = log_optab; break;
1841 CASE_FLT_FN (BUILT_IN_LOG10):
1842 errno_set = true; builtin_optab = log10_optab; break;
1843 CASE_FLT_FN (BUILT_IN_LOG2):
1844 errno_set = true; builtin_optab = log2_optab; break;
1845 CASE_FLT_FN (BUILT_IN_LOG1P):
1846 errno_set = true; builtin_optab = log1p_optab; break;
1847 CASE_FLT_FN (BUILT_IN_ASIN):
1848 builtin_optab = asin_optab; break;
1849 CASE_FLT_FN (BUILT_IN_ACOS):
1850 builtin_optab = acos_optab; break;
1851 CASE_FLT_FN (BUILT_IN_TAN):
1852 builtin_optab = tan_optab; break;
1853 CASE_FLT_FN (BUILT_IN_ATAN):
1854 builtin_optab = atan_optab; break;
1855 CASE_FLT_FN (BUILT_IN_FLOOR):
1856 builtin_optab = floor_optab; break;
1857 CASE_FLT_FN (BUILT_IN_CEIL):
1858 builtin_optab = ceil_optab; break;
1859 CASE_FLT_FN (BUILT_IN_TRUNC):
1860 builtin_optab = btrunc_optab; break;
1861 CASE_FLT_FN (BUILT_IN_ROUND):
1862 builtin_optab = round_optab; break;
1863 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1864 builtin_optab = nearbyint_optab;
1865 if (flag_trapping_math)
1866 break;
1867 /* Else fallthrough and expand as rint. */
1868 CASE_FLT_FN (BUILT_IN_RINT):
1869 builtin_optab = rint_optab; break;
1870 default:
1871 gcc_unreachable ();
1874 /* Make a suitable register to place result in. */
1875 mode = TYPE_MODE (TREE_TYPE (exp));
1877 if (! flag_errno_math || ! HONOR_NANS (mode))
1878 errno_set = false;
1880 /* Before working hard, check whether the instruction is available. */
1881 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
1883 target = gen_reg_rtx (mode);
1885 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1886 need to expand the argument again. This way, we will not perform
1887 side-effects more the once. */
1888 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
1890 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
1892 start_sequence ();
1894 /* Compute into TARGET.
1895 Set TARGET to wherever the result comes back. */
1896 target = expand_unop (mode, builtin_optab, op0, target, 0);
1898 if (target != 0)
1900 if (errno_set)
1901 expand_errno_check (exp, target);
1903 /* Output the entire sequence. */
1904 insns = get_insns ();
1905 end_sequence ();
1906 emit_insn (insns);
1907 return target;
1910 /* If we were unable to expand via the builtin, stop the sequence
1911 (without outputting the insns) and call to the library function
1912 with the stabilized argument list. */
1913 end_sequence ();
1916 before_call = get_last_insn ();
1918 target = expand_call (exp, target, target == const0_rtx);
1920 /* If this is a sqrt operation and we don't care about errno, try to
1921 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1922 This allows the semantics of the libcall to be visible to the RTL
1923 optimizers. */
1924 if (builtin_optab == sqrt_optab && !errno_set)
1926 /* Search backwards through the insns emitted by expand_call looking
1927 for the instruction with the REG_RETVAL note. */
1928 rtx last = get_last_insn ();
1929 while (last != before_call)
1931 if (find_reg_note (last, REG_RETVAL, NULL))
1933 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1934 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1935 two elements, i.e. symbol_ref(sqrt) and the operand. */
1936 if (note
1937 && GET_CODE (note) == EXPR_LIST
1938 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1939 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1940 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1942 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1943 /* Check operand is a register with expected mode. */
1944 if (operand
1945 && REG_P (operand)
1946 && GET_MODE (operand) == mode)
1948 /* Replace the REG_EQUAL note with a SQRT rtx. */
1949 rtx equiv = gen_rtx_SQRT (mode, operand);
1950 set_unique_reg_note (last, REG_EQUAL, equiv);
1953 break;
1955 last = PREV_INSN (last);
1959 return target;
1962 /* Expand a call to the builtin binary math functions (pow and atan2).
1963 Return NULL_RTX if a normal call should be emitted rather than expanding the
1964 function in-line. EXP is the expression that is a call to the builtin
1965 function; if convenient, the result should be placed in TARGET.
1966 SUBTARGET may be used as the target for computing one of EXP's
1967 operands. */
1969 static rtx
1970 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1972 optab builtin_optab;
1973 rtx op0, op1, insns;
1974 int op1_type = REAL_TYPE;
1975 tree fndecl = get_callee_fndecl (exp);
1976 tree arg0, arg1;
1977 enum machine_mode mode;
1978 bool errno_set = true;
1980 switch (DECL_FUNCTION_CODE (fndecl))
1982 CASE_FLT_FN (BUILT_IN_SCALBN):
1983 CASE_FLT_FN (BUILT_IN_SCALBLN):
1984 CASE_FLT_FN (BUILT_IN_LDEXP):
1985 op1_type = INTEGER_TYPE;
1986 default:
1987 break;
1990 if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
1991 return NULL_RTX;
1993 arg0 = CALL_EXPR_ARG (exp, 0);
1994 arg1 = CALL_EXPR_ARG (exp, 1);
1996 switch (DECL_FUNCTION_CODE (fndecl))
1998 CASE_FLT_FN (BUILT_IN_POW):
1999 builtin_optab = pow_optab; break;
2000 CASE_FLT_FN (BUILT_IN_ATAN2):
2001 builtin_optab = atan2_optab; break;
2002 CASE_FLT_FN (BUILT_IN_SCALB):
2003 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2004 return 0;
2005 builtin_optab = scalb_optab; break;
2006 CASE_FLT_FN (BUILT_IN_SCALBN):
2007 CASE_FLT_FN (BUILT_IN_SCALBLN):
2008 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2009 return 0;
2010 /* Fall through... */
2011 CASE_FLT_FN (BUILT_IN_LDEXP):
2012 builtin_optab = ldexp_optab; break;
2013 CASE_FLT_FN (BUILT_IN_FMOD):
2014 builtin_optab = fmod_optab; break;
2015 CASE_FLT_FN (BUILT_IN_REMAINDER):
2016 CASE_FLT_FN (BUILT_IN_DREM):
2017 builtin_optab = remainder_optab; break;
2018 default:
2019 gcc_unreachable ();
2022 /* Make a suitable register to place result in. */
2023 mode = TYPE_MODE (TREE_TYPE (exp));
2025 /* Before working hard, check whether the instruction is available. */
2026 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
2027 return NULL_RTX;
2029 target = gen_reg_rtx (mode);
2031 if (! flag_errno_math || ! HONOR_NANS (mode))
2032 errno_set = false;
2034 /* Always stabilize the argument list. */
2035 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2036 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2038 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2039 op1 = expand_normal (arg1);
2041 start_sequence ();
2043 /* Compute into TARGET.
2044 Set TARGET to wherever the result comes back. */
2045 target = expand_binop (mode, builtin_optab, op0, op1,
2046 target, 0, OPTAB_DIRECT);
2048 /* If we were unable to expand via the builtin, stop the sequence
2049 (without outputting the insns) and call to the library function
2050 with the stabilized argument list. */
2051 if (target == 0)
2053 end_sequence ();
2054 return expand_call (exp, target, target == const0_rtx);
2057 if (errno_set)
2058 expand_errno_check (exp, target);
2060 /* Output the entire sequence. */
2061 insns = get_insns ();
2062 end_sequence ();
2063 emit_insn (insns);
2065 return target;
2068 /* Expand a call to the builtin sin and cos math functions.
2069 Return NULL_RTX if a normal call should be emitted rather than expanding the
2070 function in-line. EXP is the expression that is a call to the builtin
2071 function; if convenient, the result should be placed in TARGET.
2072 SUBTARGET may be used as the target for computing one of EXP's
2073 operands. */
2075 static rtx
2076 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2078 optab builtin_optab;
2079 rtx op0, insns;
2080 tree fndecl = get_callee_fndecl (exp);
2081 enum machine_mode mode;
2082 tree arg;
2084 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2085 return NULL_RTX;
2087 arg = CALL_EXPR_ARG (exp, 0);
2089 switch (DECL_FUNCTION_CODE (fndecl))
2091 CASE_FLT_FN (BUILT_IN_SIN):
2092 CASE_FLT_FN (BUILT_IN_COS):
2093 builtin_optab = sincos_optab; break;
2094 default:
2095 gcc_unreachable ();
2098 /* Make a suitable register to place result in. */
2099 mode = TYPE_MODE (TREE_TYPE (exp));
2101 /* Check if sincos insn is available, otherwise fallback
2102 to sin or cos insn. */
2103 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
2104 switch (DECL_FUNCTION_CODE (fndecl))
2106 CASE_FLT_FN (BUILT_IN_SIN):
2107 builtin_optab = sin_optab; break;
2108 CASE_FLT_FN (BUILT_IN_COS):
2109 builtin_optab = cos_optab; break;
2110 default:
2111 gcc_unreachable ();
2114 /* Before working hard, check whether the instruction is available. */
2115 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
2117 target = gen_reg_rtx (mode);
2119 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2120 need to expand the argument again. This way, we will not perform
2121 side-effects more the once. */
2122 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2124 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2126 start_sequence ();
2128 /* Compute into TARGET.
2129 Set TARGET to wherever the result comes back. */
2130 if (builtin_optab == sincos_optab)
2132 int result;
2134 switch (DECL_FUNCTION_CODE (fndecl))
2136 CASE_FLT_FN (BUILT_IN_SIN):
2137 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2138 break;
2139 CASE_FLT_FN (BUILT_IN_COS):
2140 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2141 break;
2142 default:
2143 gcc_unreachable ();
2145 gcc_assert (result);
2147 else
2149 target = expand_unop (mode, builtin_optab, op0, target, 0);
2152 if (target != 0)
2154 /* Output the entire sequence. */
2155 insns = get_insns ();
2156 end_sequence ();
2157 emit_insn (insns);
2158 return target;
2161 /* If we were unable to expand via the builtin, stop the sequence
2162 (without outputting the insns) and call to the library function
2163 with the stabilized argument list. */
2164 end_sequence ();
2167 target = expand_call (exp, target, target == const0_rtx);
2169 return target;
2172 /* Expand a call to one of the builtin math functions that operate on
2173 floating point argument and output an integer result (ilogb, isinf,
2174 isnan, etc).
2175 Return 0 if a normal call should be emitted rather than expanding the
2176 function in-line. EXP is the expression that is a call to the builtin
2177 function; if convenient, the result should be placed in TARGET.
2178 SUBTARGET may be used as the target for computing one of EXP's operands. */
2180 static rtx
2181 expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
2183 optab builtin_optab = 0;
2184 enum insn_code icode = CODE_FOR_nothing;
2185 rtx op0;
2186 tree fndecl = get_callee_fndecl (exp);
2187 enum machine_mode mode;
2188 bool errno_set = false;
2189 tree arg;
2191 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2192 return NULL_RTX;
2194 arg = CALL_EXPR_ARG (exp, 0);
2196 switch (DECL_FUNCTION_CODE (fndecl))
2198 CASE_FLT_FN (BUILT_IN_ILOGB):
2199 errno_set = true; builtin_optab = ilogb_optab; break;
2200 CASE_FLT_FN (BUILT_IN_ISINF):
2201 builtin_optab = isinf_optab; break;
2202 case BUILT_IN_ISNORMAL:
2203 case BUILT_IN_ISFINITE:
2204 CASE_FLT_FN (BUILT_IN_FINITE):
2205 /* These builtins have no optabs (yet). */
2206 break;
2207 default:
2208 gcc_unreachable ();
2211 /* There's no easy way to detect the case we need to set EDOM. */
2212 if (flag_errno_math && errno_set)
2213 return NULL_RTX;
2215 /* Optab mode depends on the mode of the input argument. */
2216 mode = TYPE_MODE (TREE_TYPE (arg));
2218 if (builtin_optab)
2219 icode = optab_handler (builtin_optab, mode)->insn_code;
2221 /* Before working hard, check whether the instruction is available. */
2222 if (icode != CODE_FOR_nothing)
2224 /* Make a suitable register to place result in. */
2225 if (!target
2226 || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
2227 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
2229 gcc_assert (insn_data[icode].operand[0].predicate
2230 (target, GET_MODE (target)));
2232 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2233 need to expand the argument again. This way, we will not perform
2234 side-effects more the once. */
2235 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2237 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2239 if (mode != GET_MODE (op0))
2240 op0 = convert_to_mode (mode, op0, 0);
2242 /* Compute into TARGET.
2243 Set TARGET to wherever the result comes back. */
2244 emit_unop_insn (icode, target, op0, UNKNOWN);
2245 return target;
2248 /* If there is no optab, try generic code. */
2249 switch (DECL_FUNCTION_CODE (fndecl))
2251 tree result;
2253 CASE_FLT_FN (BUILT_IN_ISINF):
2255 /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */
2256 tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
2257 tree const type = TREE_TYPE (arg);
2258 REAL_VALUE_TYPE r;
2259 char buf[128];
2261 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2262 real_from_string (&r, buf);
2263 result = build_call_expr (isgr_fn, 2,
2264 fold_build1 (ABS_EXPR, type, arg),
2265 build_real (type, r));
2266 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2268 CASE_FLT_FN (BUILT_IN_FINITE):
2269 case BUILT_IN_ISFINITE:
2271 /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */
2272 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2273 tree const type = TREE_TYPE (arg);
2274 REAL_VALUE_TYPE r;
2275 char buf[128];
2277 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2278 real_from_string (&r, buf);
2279 result = build_call_expr (isle_fn, 2,
2280 fold_build1 (ABS_EXPR, type, arg),
2281 build_real (type, r));
2282 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2284 case BUILT_IN_ISNORMAL:
2286 /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
2287 islessequal(fabs(x),DBL_MAX). */
2288 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2289 tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
2290 tree const type = TREE_TYPE (arg);
2291 REAL_VALUE_TYPE rmax, rmin;
2292 char buf[128];
2294 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2295 real_from_string (&rmax, buf);
2296 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
2297 real_from_string (&rmin, buf);
2298 arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
2299 result = build_call_expr (isle_fn, 2, arg,
2300 build_real (type, rmax));
2301 result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
2302 build_call_expr (isge_fn, 2, arg,
2303 build_real (type, rmin)));
2304 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2306 default:
2307 break;
2310 target = expand_call (exp, target, target == const0_rtx);
2312 return target;
2315 /* Expand a call to the builtin sincos math function.
2316 Return NULL_RTX if a normal call should be emitted rather than expanding the
2317 function in-line. EXP is the expression that is a call to the builtin
2318 function. */
2320 static rtx
2321 expand_builtin_sincos (tree exp)
2323 rtx op0, op1, op2, target1, target2;
2324 enum machine_mode mode;
2325 tree arg, sinp, cosp;
2326 int result;
2328 if (!validate_arglist (exp, REAL_TYPE,
2329 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2330 return NULL_RTX;
2332 arg = CALL_EXPR_ARG (exp, 0);
2333 sinp = CALL_EXPR_ARG (exp, 1);
2334 cosp = CALL_EXPR_ARG (exp, 2);
2336 /* Make a suitable register to place result in. */
2337 mode = TYPE_MODE (TREE_TYPE (arg));
2339 /* Check if sincos insn is available, otherwise emit the call. */
2340 if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing)
2341 return NULL_RTX;
2343 target1 = gen_reg_rtx (mode);
2344 target2 = gen_reg_rtx (mode);
2346 op0 = expand_normal (arg);
2347 op1 = expand_normal (build_fold_indirect_ref (sinp));
2348 op2 = expand_normal (build_fold_indirect_ref (cosp));
2350 /* Compute into target1 and target2.
2351 Set TARGET to wherever the result comes back. */
2352 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2353 gcc_assert (result);
2355 /* Move target1 and target2 to the memory locations indicated
2356 by op1 and op2. */
2357 emit_move_insn (op1, target1);
2358 emit_move_insn (op2, target2);
2360 return const0_rtx;
2363 /* Expand a call to the internal cexpi builtin to the sincos math function.
2364 EXP is the expression that is a call to the builtin function; if convenient,
2365 the result should be placed in TARGET. SUBTARGET may be used as the target
2366 for computing one of EXP's operands. */
2368 static rtx
2369 expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2371 tree fndecl = get_callee_fndecl (exp);
2372 tree arg, type;
2373 enum machine_mode mode;
2374 rtx op0, op1, op2;
2376 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2377 return NULL_RTX;
2379 arg = CALL_EXPR_ARG (exp, 0);
2380 type = TREE_TYPE (arg);
2381 mode = TYPE_MODE (TREE_TYPE (arg));
2383 /* Try expanding via a sincos optab, fall back to emitting a libcall
2384 to sincos or cexp. We are sure we have sincos or cexp because cexpi
2385 is only generated from sincos, cexp or if we have either of them. */
2386 if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing)
2388 op1 = gen_reg_rtx (mode);
2389 op2 = gen_reg_rtx (mode);
2391 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2393 /* Compute into op1 and op2. */
2394 expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2396 else if (TARGET_HAS_SINCOS)
2398 tree call, fn = NULL_TREE;
2399 tree top1, top2;
2400 rtx op1a, op2a;
2402 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2403 fn = built_in_decls[BUILT_IN_SINCOSF];
2404 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2405 fn = built_in_decls[BUILT_IN_SINCOS];
2406 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2407 fn = built_in_decls[BUILT_IN_SINCOSL];
2408 else
2409 gcc_unreachable ();
2411 op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2412 op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2413 op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2414 op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2415 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2416 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2418 /* Make sure not to fold the sincos call again. */
2419 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2420 expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2421 call, 3, arg, top1, top2));
2423 else
2425 tree call, fn = NULL_TREE, narg;
2426 tree ctype = build_complex_type (type);
2428 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2429 fn = built_in_decls[BUILT_IN_CEXPF];
2430 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2431 fn = built_in_decls[BUILT_IN_CEXP];
2432 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2433 fn = built_in_decls[BUILT_IN_CEXPL];
2434 else
2435 gcc_unreachable ();
2437 /* If we don't have a decl for cexp create one. This is the
2438 friendliest fallback if the user calls __builtin_cexpi
2439 without full target C99 function support. */
2440 if (fn == NULL_TREE)
2442 tree fntype;
2443 const char *name = NULL;
2445 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2446 name = "cexpf";
2447 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2448 name = "cexp";
2449 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2450 name = "cexpl";
2452 fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2453 fn = build_fn_decl (name, fntype);
2456 narg = fold_build2 (COMPLEX_EXPR, ctype,
2457 build_real (type, dconst0), arg);
2459 /* Make sure not to fold the cexp call again. */
2460 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2461 return expand_expr (build_call_nary (ctype, call, 1, narg),
2462 target, VOIDmode, EXPAND_NORMAL);
2465 /* Now build the proper return type. */
2466 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2467 make_tree (TREE_TYPE (arg), op2),
2468 make_tree (TREE_TYPE (arg), op1)),
2469 target, VOIDmode, EXPAND_NORMAL);
2472 /* Expand a call to one of the builtin rounding functions gcc defines
2473 as an extension (lfloor and lceil). As these are gcc extensions we
2474 do not need to worry about setting errno to EDOM.
2475 If expanding via optab fails, lower expression to (int)(floor(x)).
2476 EXP is the expression that is a call to the builtin function;
2477 if convenient, the result should be placed in TARGET. SUBTARGET may
2478 be used as the target for computing one of EXP's operands. */
2480 static rtx
2481 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2483 convert_optab builtin_optab;
2484 rtx op0, insns, tmp;
2485 tree fndecl = get_callee_fndecl (exp);
2486 enum built_in_function fallback_fn;
2487 tree fallback_fndecl;
2488 enum machine_mode mode;
2489 tree arg;
2491 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2492 gcc_unreachable ();
2494 arg = CALL_EXPR_ARG (exp, 0);
2496 switch (DECL_FUNCTION_CODE (fndecl))
2498 CASE_FLT_FN (BUILT_IN_LCEIL):
2499 CASE_FLT_FN (BUILT_IN_LLCEIL):
2500 builtin_optab = lceil_optab;
2501 fallback_fn = BUILT_IN_CEIL;
2502 break;
2504 CASE_FLT_FN (BUILT_IN_LFLOOR):
2505 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2506 builtin_optab = lfloor_optab;
2507 fallback_fn = BUILT_IN_FLOOR;
2508 break;
2510 default:
2511 gcc_unreachable ();
2514 /* Make a suitable register to place result in. */
2515 mode = TYPE_MODE (TREE_TYPE (exp));
2517 target = gen_reg_rtx (mode);
2519 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2520 need to expand the argument again. This way, we will not perform
2521 side-effects more the once. */
2522 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2524 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2526 start_sequence ();
2528 /* Compute into TARGET. */
2529 if (expand_sfix_optab (target, op0, builtin_optab))
2531 /* Output the entire sequence. */
2532 insns = get_insns ();
2533 end_sequence ();
2534 emit_insn (insns);
2535 return target;
2538 /* If we were unable to expand via the builtin, stop the sequence
2539 (without outputting the insns). */
2540 end_sequence ();
2542 /* Fall back to floating point rounding optab. */
2543 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2545 /* For non-C99 targets we may end up without a fallback fndecl here
2546 if the user called __builtin_lfloor directly. In this case emit
2547 a call to the floor/ceil variants nevertheless. This should result
2548 in the best user experience for not full C99 targets. */
2549 if (fallback_fndecl == NULL_TREE)
2551 tree fntype;
2552 const char *name = NULL;
2554 switch (DECL_FUNCTION_CODE (fndecl))
2556 case BUILT_IN_LCEIL:
2557 case BUILT_IN_LLCEIL:
2558 name = "ceil";
2559 break;
2560 case BUILT_IN_LCEILF:
2561 case BUILT_IN_LLCEILF:
2562 name = "ceilf";
2563 break;
2564 case BUILT_IN_LCEILL:
2565 case BUILT_IN_LLCEILL:
2566 name = "ceill";
2567 break;
2568 case BUILT_IN_LFLOOR:
2569 case BUILT_IN_LLFLOOR:
2570 name = "floor";
2571 break;
2572 case BUILT_IN_LFLOORF:
2573 case BUILT_IN_LLFLOORF:
2574 name = "floorf";
2575 break;
2576 case BUILT_IN_LFLOORL:
2577 case BUILT_IN_LLFLOORL:
2578 name = "floorl";
2579 break;
2580 default:
2581 gcc_unreachable ();
2584 fntype = build_function_type_list (TREE_TYPE (arg),
2585 TREE_TYPE (arg), NULL_TREE);
2586 fallback_fndecl = build_fn_decl (name, fntype);
2589 exp = build_call_expr (fallback_fndecl, 1, arg);
2591 tmp = expand_normal (exp);
2593 /* Truncate the result of floating point optab to integer
2594 via expand_fix (). */
2595 target = gen_reg_rtx (mode);
2596 expand_fix (target, tmp, 0);
2598 return target;
2601 /* Expand a call to one of the builtin math functions doing integer
2602 conversion (lrint).
2603 Return 0 if a normal call should be emitted rather than expanding the
2604 function in-line. EXP is the expression that is a call to the builtin
2605 function; if convenient, the result should be placed in TARGET.
2606 SUBTARGET may be used as the target for computing one of EXP's operands. */
2608 static rtx
2609 expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
2611 convert_optab builtin_optab;
2612 rtx op0, insns;
2613 tree fndecl = get_callee_fndecl (exp);
2614 tree arg;
2615 enum machine_mode mode;
2617 /* There's no easy way to detect the case we need to set EDOM. */
2618 if (flag_errno_math)
2619 return NULL_RTX;
2621 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2622 gcc_unreachable ();
2624 arg = CALL_EXPR_ARG (exp, 0);
2626 switch (DECL_FUNCTION_CODE (fndecl))
2628 CASE_FLT_FN (BUILT_IN_LRINT):
2629 CASE_FLT_FN (BUILT_IN_LLRINT):
2630 builtin_optab = lrint_optab; break;
2631 CASE_FLT_FN (BUILT_IN_LROUND):
2632 CASE_FLT_FN (BUILT_IN_LLROUND):
2633 builtin_optab = lround_optab; break;
2634 default:
2635 gcc_unreachable ();
2638 /* Make a suitable register to place result in. */
2639 mode = TYPE_MODE (TREE_TYPE (exp));
2641 target = gen_reg_rtx (mode);
2643 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2644 need to expand the argument again. This way, we will not perform
2645 side-effects more the once. */
2646 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2648 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2650 start_sequence ();
2652 if (expand_sfix_optab (target, op0, builtin_optab))
2654 /* Output the entire sequence. */
2655 insns = get_insns ();
2656 end_sequence ();
2657 emit_insn (insns);
2658 return target;
2661 /* If we were unable to expand via the builtin, stop the sequence
2662 (without outputting the insns) and call to the library function
2663 with the stabilized argument list. */
2664 end_sequence ();
2666 target = expand_call (exp, target, target == const0_rtx);
2668 return target;
2671 /* To evaluate powi(x,n), the floating point value x raised to the
2672 constant integer exponent n, we use a hybrid algorithm that
2673 combines the "window method" with look-up tables. For an
2674 introduction to exponentiation algorithms and "addition chains",
2675 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2676 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2677 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2678 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2680 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2681 multiplications to inline before calling the system library's pow
2682 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2683 so this default never requires calling pow, powf or powl. */
2685 #ifndef POWI_MAX_MULTS
2686 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2687 #endif
2689 /* The size of the "optimal power tree" lookup table. All
2690 exponents less than this value are simply looked up in the
2691 powi_table below. This threshold is also used to size the
2692 cache of pseudo registers that hold intermediate results. */
2693 #define POWI_TABLE_SIZE 256
2695 /* The size, in bits of the window, used in the "window method"
2696 exponentiation algorithm. This is equivalent to a radix of
2697 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2698 #define POWI_WINDOW_SIZE 3
2700 /* The following table is an efficient representation of an
2701 "optimal power tree". For each value, i, the corresponding
2702 value, j, in the table states than an optimal evaluation
2703 sequence for calculating pow(x,i) can be found by evaluating
2704 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2705 100 integers is given in Knuth's "Seminumerical algorithms". */
2707 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2709 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2710 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2711 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2712 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2713 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2714 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2715 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2716 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2717 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2718 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2719 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2720 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2721 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2722 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2723 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2724 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2725 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2726 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2727 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2728 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2729 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2730 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2731 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2732 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2733 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2734 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2735 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2736 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2737 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2738 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2739 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2740 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2744 /* Return the number of multiplications required to calculate
2745 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2746 subroutine of powi_cost. CACHE is an array indicating
2747 which exponents have already been calculated. */
2749 static int
2750 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2752 /* If we've already calculated this exponent, then this evaluation
2753 doesn't require any additional multiplications. */
2754 if (cache[n])
2755 return 0;
2757 cache[n] = true;
2758 return powi_lookup_cost (n - powi_table[n], cache)
2759 + powi_lookup_cost (powi_table[n], cache) + 1;
2762 /* Return the number of multiplications required to calculate
2763 powi(x,n) for an arbitrary x, given the exponent N. This
2764 function needs to be kept in sync with expand_powi below. */
2766 static int
2767 powi_cost (HOST_WIDE_INT n)
2769 bool cache[POWI_TABLE_SIZE];
2770 unsigned HOST_WIDE_INT digit;
2771 unsigned HOST_WIDE_INT val;
2772 int result;
2774 if (n == 0)
2775 return 0;
2777 /* Ignore the reciprocal when calculating the cost. */
2778 val = (n < 0) ? -n : n;
2780 /* Initialize the exponent cache. */
2781 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2782 cache[1] = true;
2784 result = 0;
2786 while (val >= POWI_TABLE_SIZE)
2788 if (val & 1)
2790 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2791 result += powi_lookup_cost (digit, cache)
2792 + POWI_WINDOW_SIZE + 1;
2793 val >>= POWI_WINDOW_SIZE;
2795 else
2797 val >>= 1;
2798 result++;
2802 return result + powi_lookup_cost (val, cache);
2805 /* Recursive subroutine of expand_powi. This function takes the array,
2806 CACHE, of already calculated exponents and an exponent N and returns
2807 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2809 static rtx
2810 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2812 unsigned HOST_WIDE_INT digit;
2813 rtx target, result;
2814 rtx op0, op1;
2816 if (n < POWI_TABLE_SIZE)
2818 if (cache[n])
2819 return cache[n];
2821 target = gen_reg_rtx (mode);
2822 cache[n] = target;
2824 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2825 op1 = expand_powi_1 (mode, powi_table[n], cache);
2827 else if (n & 1)
2829 target = gen_reg_rtx (mode);
2830 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2831 op0 = expand_powi_1 (mode, n - digit, cache);
2832 op1 = expand_powi_1 (mode, digit, cache);
2834 else
2836 target = gen_reg_rtx (mode);
2837 op0 = expand_powi_1 (mode, n >> 1, cache);
2838 op1 = op0;
2841 result = expand_mult (mode, op0, op1, target, 0);
2842 if (result != target)
2843 emit_move_insn (target, result);
2844 return target;
2847 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2848 floating point operand in mode MODE, and N is the exponent. This
2849 function needs to be kept in sync with powi_cost above. */
2851 static rtx
2852 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2854 unsigned HOST_WIDE_INT val;
2855 rtx cache[POWI_TABLE_SIZE];
2856 rtx result;
2858 if (n == 0)
2859 return CONST1_RTX (mode);
2861 val = (n < 0) ? -n : n;
2863 memset (cache, 0, sizeof (cache));
2864 cache[1] = x;
2866 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2868 /* If the original exponent was negative, reciprocate the result. */
2869 if (n < 0)
2870 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2871 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2873 return result;
2876 /* Expand a call to the pow built-in mathematical function. Return NULL_RTX if
2877 a normal call should be emitted rather than expanding the function
2878 in-line. EXP is the expression that is a call to the builtin
2879 function; if convenient, the result should be placed in TARGET. */
2881 static rtx
2882 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2884 tree arg0, arg1;
2885 tree fn, narg0;
2886 tree type = TREE_TYPE (exp);
2887 REAL_VALUE_TYPE cint, c, c2;
2888 HOST_WIDE_INT n;
2889 rtx op, op2;
2890 enum machine_mode mode = TYPE_MODE (type);
2892 if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2893 return NULL_RTX;
2895 arg0 = CALL_EXPR_ARG (exp, 0);
2896 arg1 = CALL_EXPR_ARG (exp, 1);
2898 if (TREE_CODE (arg1) != REAL_CST
2899 || TREE_OVERFLOW (arg1))
2900 return expand_builtin_mathfn_2 (exp, target, subtarget);
2902 /* Handle constant exponents. */
2904 /* For integer valued exponents we can expand to an optimal multiplication
2905 sequence using expand_powi. */
2906 c = TREE_REAL_CST (arg1);
2907 n = real_to_integer (&c);
2908 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2909 if (real_identical (&c, &cint)
2910 && ((n >= -1 && n <= 2)
2911 || (flag_unsafe_math_optimizations
2912 && !optimize_size
2913 && powi_cost (n) <= POWI_MAX_MULTS)))
2915 op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2916 if (n != 1)
2918 op = force_reg (mode, op);
2919 op = expand_powi (op, mode, n);
2921 return op;
2924 narg0 = builtin_save_expr (arg0);
2926 /* If the exponent is not integer valued, check if it is half of an integer.
2927 In this case we can expand to sqrt (x) * x**(n/2). */
2928 fn = mathfn_built_in (type, BUILT_IN_SQRT);
2929 if (fn != NULL_TREE)
2931 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2932 n = real_to_integer (&c2);
2933 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2934 if (real_identical (&c2, &cint)
2935 && ((flag_unsafe_math_optimizations
2936 && !optimize_size
2937 && powi_cost (n/2) <= POWI_MAX_MULTS)
2938 || n == 1))
2940 tree call_expr = build_call_expr (fn, 1, narg0);
2941 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
2942 if (n != 1)
2944 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
2945 op2 = force_reg (mode, op2);
2946 op2 = expand_powi (op2, mode, abs (n / 2));
2947 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2948 0, OPTAB_LIB_WIDEN);
2949 /* If the original exponent was negative, reciprocate the
2950 result. */
2951 if (n < 0)
2952 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2953 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2955 return op;
2959 /* Try if the exponent is a third of an integer. In this case
2960 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
2961 different from pow (x, 1./3.) due to rounding and behavior
2962 with negative x we need to constrain this transformation to
2963 unsafe math and positive x or finite math. */
2964 fn = mathfn_built_in (type, BUILT_IN_CBRT);
2965 if (fn != NULL_TREE
2966 && flag_unsafe_math_optimizations
2967 && (tree_expr_nonnegative_p (arg0)
2968 || !HONOR_NANS (mode)))
2970 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
2971 real_round (&c2, mode, &c2);
2972 n = real_to_integer (&c2);
2973 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2974 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
2975 real_convert (&c2, mode, &c2);
2976 if (real_identical (&c2, &c)
2977 && ((!optimize_size
2978 && powi_cost (n/3) <= POWI_MAX_MULTS)
2979 || n == 1))
2981 tree call_expr = build_call_expr (fn, 1,narg0);
2982 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
2983 if (abs (n) % 3 == 2)
2984 op = expand_simple_binop (mode, MULT, op, op, op,
2985 0, OPTAB_LIB_WIDEN);
2986 if (n != 1)
2988 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
2989 op2 = force_reg (mode, op2);
2990 op2 = expand_powi (op2, mode, abs (n / 3));
2991 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2992 0, OPTAB_LIB_WIDEN);
2993 /* If the original exponent was negative, reciprocate the
2994 result. */
2995 if (n < 0)
2996 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2997 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2999 return op;
3003 /* Fall back to optab expansion. */
3004 return expand_builtin_mathfn_2 (exp, target, subtarget);
3007 /* Expand a call to the powi built-in mathematical function. Return NULL_RTX if
3008 a normal call should be emitted rather than expanding the function
3009 in-line. EXP is the expression that is a call to the builtin
3010 function; if convenient, the result should be placed in TARGET. */
3012 static rtx
3013 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
3015 tree arg0, arg1;
3016 rtx op0, op1;
3017 enum machine_mode mode;
3018 enum machine_mode mode2;
3020 if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
3021 return NULL_RTX;
3023 arg0 = CALL_EXPR_ARG (exp, 0);
3024 arg1 = CALL_EXPR_ARG (exp, 1);
3025 mode = TYPE_MODE (TREE_TYPE (exp));
3027 /* Handle constant power. */
3029 if (TREE_CODE (arg1) == INTEGER_CST
3030 && !TREE_OVERFLOW (arg1))
3032 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
3034 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
3035 Otherwise, check the number of multiplications required. */
3036 if ((TREE_INT_CST_HIGH (arg1) == 0
3037 || TREE_INT_CST_HIGH (arg1) == -1)
3038 && ((n >= -1 && n <= 2)
3039 || (! optimize_size
3040 && powi_cost (n) <= POWI_MAX_MULTS)))
3042 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
3043 op0 = force_reg (mode, op0);
3044 return expand_powi (op0, mode, n);
3048 /* Emit a libcall to libgcc. */
3050 /* Mode of the 2nd argument must match that of an int. */
3051 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
3053 if (target == NULL_RTX)
3054 target = gen_reg_rtx (mode);
3056 op0 = expand_expr (arg0, subtarget, mode, EXPAND_NORMAL);
3057 if (GET_MODE (op0) != mode)
3058 op0 = convert_to_mode (mode, op0, 0);
3059 op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
3060 if (GET_MODE (op1) != mode2)
3061 op1 = convert_to_mode (mode2, op1, 0);
3063 target = emit_library_call_value (optab_libfunc (powi_optab, mode),
3064 target, LCT_CONST_MAKE_BLOCK, mode, 2,
3065 op0, mode, op1, mode2);
3067 return target;
3070 /* Expand expression EXP which is a call to the strlen builtin. Return
3071 NULL_RTX if we failed the caller should emit a normal call, otherwise
3072 try to get the result in TARGET, if convenient. */
3074 static rtx
3075 expand_builtin_strlen (tree exp, rtx target,
3076 enum machine_mode target_mode)
3078 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
3079 return NULL_RTX;
3080 else
3082 rtx pat;
3083 tree len;
3084 tree src = CALL_EXPR_ARG (exp, 0);
3085 rtx result, src_reg, char_rtx, before_strlen;
3086 enum machine_mode insn_mode = target_mode, char_mode;
3087 enum insn_code icode = CODE_FOR_nothing;
3088 int align;
3090 /* If the length can be computed at compile-time, return it. */
3091 len = c_strlen (src, 0);
3092 if (len)
3093 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3095 /* If the length can be computed at compile-time and is constant
3096 integer, but there are side-effects in src, evaluate
3097 src for side-effects, then return len.
3098 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
3099 can be optimized into: i++; x = 3; */
3100 len = c_strlen (src, 1);
3101 if (len && TREE_CODE (len) == INTEGER_CST)
3103 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3104 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3107 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3109 /* If SRC is not a pointer type, don't do this operation inline. */
3110 if (align == 0)
3111 return NULL_RTX;
3113 /* Bail out if we can't compute strlen in the right mode. */
3114 while (insn_mode != VOIDmode)
3116 icode = optab_handler (strlen_optab, insn_mode)->insn_code;
3117 if (icode != CODE_FOR_nothing)
3118 break;
3120 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
3122 if (insn_mode == VOIDmode)
3123 return NULL_RTX;
3125 /* Make a place to write the result of the instruction. */
3126 result = target;
3127 if (! (result != 0
3128 && REG_P (result)
3129 && GET_MODE (result) == insn_mode
3130 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3131 result = gen_reg_rtx (insn_mode);
3133 /* Make a place to hold the source address. We will not expand
3134 the actual source until we are sure that the expansion will
3135 not fail -- there are trees that cannot be expanded twice. */
3136 src_reg = gen_reg_rtx (Pmode);
3138 /* Mark the beginning of the strlen sequence so we can emit the
3139 source operand later. */
3140 before_strlen = get_last_insn ();
3142 char_rtx = const0_rtx;
3143 char_mode = insn_data[(int) icode].operand[2].mode;
3144 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
3145 char_mode))
3146 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
3148 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
3149 char_rtx, GEN_INT (align));
3150 if (! pat)
3151 return NULL_RTX;
3152 emit_insn (pat);
3154 /* Now that we are assured of success, expand the source. */
3155 start_sequence ();
3156 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
3157 if (pat != src_reg)
3158 emit_move_insn (src_reg, pat);
3159 pat = get_insns ();
3160 end_sequence ();
3162 if (before_strlen)
3163 emit_insn_after (pat, before_strlen);
3164 else
3165 emit_insn_before (pat, get_insns ());
3167 /* Return the value in the proper mode for this function. */
3168 if (GET_MODE (result) == target_mode)
3169 target = result;
3170 else if (target != 0)
3171 convert_move (target, result, 0);
3172 else
3173 target = convert_to_mode (target_mode, result, 0);
3175 return target;
3179 /* Expand a call to the strstr builtin. Return NULL_RTX if we failed the
3180 caller should emit a normal call, otherwise try to get the result
3181 in TARGET, if convenient (and in mode MODE if that's convenient). */
3183 static rtx
3184 expand_builtin_strstr (tree exp, rtx target, enum machine_mode mode)
3186 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3188 tree type = TREE_TYPE (exp);
3189 tree result = fold_builtin_strstr (CALL_EXPR_ARG (exp, 0),
3190 CALL_EXPR_ARG (exp, 1), type);
3191 if (result)
3192 return expand_expr (result, target, mode, EXPAND_NORMAL);
3194 return NULL_RTX;
3197 /* Expand a call to the strchr builtin. Return NULL_RTX if we failed the
3198 caller should emit a normal call, otherwise try to get the result
3199 in TARGET, if convenient (and in mode MODE if that's convenient). */
3201 static rtx
3202 expand_builtin_strchr (tree exp, rtx target, enum machine_mode mode)
3204 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3206 tree type = TREE_TYPE (exp);
3207 tree result = fold_builtin_strchr (CALL_EXPR_ARG (exp, 0),
3208 CALL_EXPR_ARG (exp, 1), type);
3209 if (result)
3210 return expand_expr (result, target, mode, EXPAND_NORMAL);
3212 /* FIXME: Should use strchrM optab so that ports can optimize this. */
3214 return NULL_RTX;
3217 /* Expand a call to the strrchr builtin. Return NULL_RTX if we failed the
3218 caller should emit a normal call, otherwise try to get the result
3219 in TARGET, if convenient (and in mode MODE if that's convenient). */
3221 static rtx
3222 expand_builtin_strrchr (tree exp, rtx target, enum machine_mode mode)
3224 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3226 tree type = TREE_TYPE (exp);
3227 tree result = fold_builtin_strrchr (CALL_EXPR_ARG (exp, 0),
3228 CALL_EXPR_ARG (exp, 1), type);
3229 if (result)
3230 return expand_expr (result, target, mode, EXPAND_NORMAL);
3232 return NULL_RTX;
3235 /* Expand a call to the strpbrk builtin. Return NULL_RTX if we failed the
3236 caller should emit a normal call, otherwise try to get the result
3237 in TARGET, if convenient (and in mode MODE if that's convenient). */
3239 static rtx
3240 expand_builtin_strpbrk (tree exp, rtx target, enum machine_mode mode)
3242 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3244 tree type = TREE_TYPE (exp);
3245 tree result = fold_builtin_strpbrk (CALL_EXPR_ARG (exp, 0),
3246 CALL_EXPR_ARG (exp, 1), type);
3247 if (result)
3248 return expand_expr (result, target, mode, EXPAND_NORMAL);
3250 return NULL_RTX;
3253 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3254 bytes from constant string DATA + OFFSET and return it as target
3255 constant. */
3257 static rtx
3258 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3259 enum machine_mode mode)
3261 const char *str = (const char *) data;
3263 gcc_assert (offset >= 0
3264 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3265 <= strlen (str) + 1));
3267 return c_readstr (str + offset, mode);
3270 /* Expand a call EXP to the memcpy builtin.
3271 Return NULL_RTX if we failed, the caller should emit a normal call,
3272 otherwise try to get the result in TARGET, if convenient (and in
3273 mode MODE if that's convenient). */
3275 static rtx
3276 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
3278 tree fndecl = get_callee_fndecl (exp);
3280 if (!validate_arglist (exp,
3281 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3282 return NULL_RTX;
3283 else
3285 tree dest = CALL_EXPR_ARG (exp, 0);
3286 tree src = CALL_EXPR_ARG (exp, 1);
3287 tree len = CALL_EXPR_ARG (exp, 2);
3288 const char *src_str;
3289 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3290 unsigned int dest_align
3291 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3292 rtx dest_mem, src_mem, dest_addr, len_rtx;
3293 tree result = fold_builtin_memory_op (dest, src, len,
3294 TREE_TYPE (TREE_TYPE (fndecl)),
3295 false, /*endp=*/0);
3296 HOST_WIDE_INT expected_size = -1;
3297 unsigned int expected_align = 0;
3299 if (result)
3301 while (TREE_CODE (result) == COMPOUND_EXPR)
3303 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3304 EXPAND_NORMAL);
3305 result = TREE_OPERAND (result, 1);
3307 return expand_expr (result, target, mode, EXPAND_NORMAL);
3310 /* If DEST is not a pointer type, call the normal function. */
3311 if (dest_align == 0)
3312 return NULL_RTX;
3314 /* If either SRC is not a pointer type, don't do this
3315 operation in-line. */
3316 if (src_align == 0)
3317 return NULL_RTX;
3319 stringop_block_profile (exp, &expected_align, &expected_size);
3320 if (expected_align < dest_align)
3321 expected_align = dest_align;
3322 dest_mem = get_memory_rtx (dest, len);
3323 set_mem_align (dest_mem, dest_align);
3324 len_rtx = expand_normal (len);
3325 src_str = c_getstr (src);
3327 /* If SRC is a string constant and block move would be done
3328 by pieces, we can avoid loading the string from memory
3329 and only stored the computed constants. */
3330 if (src_str
3331 && GET_CODE (len_rtx) == CONST_INT
3332 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3333 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3334 (void *) src_str, dest_align, false))
3336 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3337 builtin_memcpy_read_str,
3338 (void *) src_str, dest_align, false, 0);
3339 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3340 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3341 return dest_mem;
3344 src_mem = get_memory_rtx (src, len);
3345 set_mem_align (src_mem, src_align);
3347 /* Copy word part most expediently. */
3348 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3349 CALL_EXPR_TAILCALL (exp)
3350 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3351 expected_align, expected_size);
3353 if (dest_addr == 0)
3355 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3356 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3358 return dest_addr;
3362 /* Expand a call EXP to the mempcpy builtin.
3363 Return NULL_RTX if we failed; the caller should emit a normal call,
3364 otherwise try to get the result in TARGET, if convenient (and in
3365 mode MODE if that's convenient). If ENDP is 0 return the
3366 destination pointer, if ENDP is 1 return the end pointer ala
3367 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3368 stpcpy. */
3370 static rtx
3371 expand_builtin_mempcpy(tree exp, rtx target, enum machine_mode mode)
3373 if (!validate_arglist (exp,
3374 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3375 return NULL_RTX;
3376 else
3378 tree dest = CALL_EXPR_ARG (exp, 0);
3379 tree src = CALL_EXPR_ARG (exp, 1);
3380 tree len = CALL_EXPR_ARG (exp, 2);
3381 return expand_builtin_mempcpy_args (dest, src, len,
3382 TREE_TYPE (exp),
3383 target, mode, /*endp=*/ 1);
3387 /* Helper function to do the actual work for expand_builtin_mempcpy. The
3388 arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3389 so that this can also be called without constructing an actual CALL_EXPR.
3390 TYPE is the return type of the call. The other arguments and return value
3391 are the same as for expand_builtin_mempcpy. */
3393 static rtx
3394 expand_builtin_mempcpy_args (tree dest, tree src, tree len, tree type,
3395 rtx target, enum machine_mode mode, int endp)
3397 /* If return value is ignored, transform mempcpy into memcpy. */
3398 if (target == const0_rtx)
3400 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3402 if (!fn)
3403 return NULL_RTX;
3405 return expand_expr (build_call_expr (fn, 3, dest, src, len),
3406 target, mode, EXPAND_NORMAL);
3408 else
3410 const char *src_str;
3411 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3412 unsigned int dest_align
3413 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3414 rtx dest_mem, src_mem, len_rtx;
3415 tree result = fold_builtin_memory_op (dest, src, len, type, false, endp);
3417 if (result)
3419 while (TREE_CODE (result) == COMPOUND_EXPR)
3421 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3422 EXPAND_NORMAL);
3423 result = TREE_OPERAND (result, 1);
3425 return expand_expr (result, target, mode, EXPAND_NORMAL);
3428 /* If either SRC or DEST is not a pointer type, don't do this
3429 operation in-line. */
3430 if (dest_align == 0 || src_align == 0)
3431 return NULL_RTX;
3433 /* If LEN is not constant, call the normal function. */
3434 if (! host_integerp (len, 1))
3435 return NULL_RTX;
3437 len_rtx = expand_normal (len);
3438 src_str = c_getstr (src);
3440 /* If SRC is a string constant and block move would be done
3441 by pieces, we can avoid loading the string from memory
3442 and only stored the computed constants. */
3443 if (src_str
3444 && GET_CODE (len_rtx) == CONST_INT
3445 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3446 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3447 (void *) src_str, dest_align, false))
3449 dest_mem = get_memory_rtx (dest, len);
3450 set_mem_align (dest_mem, dest_align);
3451 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3452 builtin_memcpy_read_str,
3453 (void *) src_str, dest_align,
3454 false, endp);
3455 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3456 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3457 return dest_mem;
3460 if (GET_CODE (len_rtx) == CONST_INT
3461 && can_move_by_pieces (INTVAL (len_rtx),
3462 MIN (dest_align, src_align)))
3464 dest_mem = get_memory_rtx (dest, len);
3465 set_mem_align (dest_mem, dest_align);
3466 src_mem = get_memory_rtx (src, len);
3467 set_mem_align (src_mem, src_align);
3468 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3469 MIN (dest_align, src_align), endp);
3470 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3471 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3472 return dest_mem;
3475 return NULL_RTX;
3479 /* Expand expression EXP, which is a call to the memmove builtin. Return
3480 NULL_RTX if we failed; the caller should emit a normal call. */
3482 static rtx
3483 expand_builtin_memmove (tree exp, rtx target, enum machine_mode mode, int ignore)
3485 if (!validate_arglist (exp,
3486 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3487 return NULL_RTX;
3488 else
3490 tree dest = CALL_EXPR_ARG (exp, 0);
3491 tree src = CALL_EXPR_ARG (exp, 1);
3492 tree len = CALL_EXPR_ARG (exp, 2);
3493 return expand_builtin_memmove_args (dest, src, len, TREE_TYPE (exp),
3494 target, mode, ignore);
3498 /* Helper function to do the actual work for expand_builtin_memmove. The
3499 arguments to the builtin_memmove call DEST, SRC, and LEN are broken out
3500 so that this can also be called without constructing an actual CALL_EXPR.
3501 TYPE is the return type of the call. The other arguments and return value
3502 are the same as for expand_builtin_memmove. */
3504 static rtx
3505 expand_builtin_memmove_args (tree dest, tree src, tree len,
3506 tree type, rtx target, enum machine_mode mode,
3507 int ignore)
3509 tree result = fold_builtin_memory_op (dest, src, len, type, ignore, /*endp=*/3);
3511 if (result)
3513 STRIP_TYPE_NOPS (result);
3514 while (TREE_CODE (result) == COMPOUND_EXPR)
3516 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3517 EXPAND_NORMAL);
3518 result = TREE_OPERAND (result, 1);
3520 return expand_expr (result, target, mode, EXPAND_NORMAL);
3523 /* Otherwise, call the normal function. */
3524 return NULL_RTX;
3527 /* Expand expression EXP, which is a call to the bcopy builtin. Return
3528 NULL_RTX if we failed the caller should emit a normal call. */
3530 static rtx
3531 expand_builtin_bcopy (tree exp, int ignore)
3533 tree type = TREE_TYPE (exp);
3534 tree src, dest, size;
3536 if (!validate_arglist (exp,
3537 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3538 return NULL_RTX;
3540 src = CALL_EXPR_ARG (exp, 0);
3541 dest = CALL_EXPR_ARG (exp, 1);
3542 size = CALL_EXPR_ARG (exp, 2);
3544 /* Transform bcopy(ptr x, ptr y, int z) to memmove(ptr y, ptr x, size_t z).
3545 This is done this way so that if it isn't expanded inline, we fall
3546 back to calling bcopy instead of memmove. */
3547 return expand_builtin_memmove_args (dest, src,
3548 fold_convert (sizetype, size),
3549 type, const0_rtx, VOIDmode,
3550 ignore);
3553 #ifndef HAVE_movstr
3554 # define HAVE_movstr 0
3555 # define CODE_FOR_movstr CODE_FOR_nothing
3556 #endif
3558 /* Expand into a movstr instruction, if one is available. Return NULL_RTX if
3559 we failed, the caller should emit a normal call, otherwise try to
3560 get the result in TARGET, if convenient. If ENDP is 0 return the
3561 destination pointer, if ENDP is 1 return the end pointer ala
3562 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3563 stpcpy. */
3565 static rtx
3566 expand_movstr (tree dest, tree src, rtx target, int endp)
3568 rtx end;
3569 rtx dest_mem;
3570 rtx src_mem;
3571 rtx insn;
3572 const struct insn_data * data;
3574 if (!HAVE_movstr)
3575 return NULL_RTX;
3577 dest_mem = get_memory_rtx (dest, NULL);
3578 src_mem = get_memory_rtx (src, NULL);
3579 if (!endp)
3581 target = force_reg (Pmode, XEXP (dest_mem, 0));
3582 dest_mem = replace_equiv_address (dest_mem, target);
3583 end = gen_reg_rtx (Pmode);
3585 else
3587 if (target == 0 || target == const0_rtx)
3589 end = gen_reg_rtx (Pmode);
3590 if (target == 0)
3591 target = end;
3593 else
3594 end = target;
3597 data = insn_data + CODE_FOR_movstr;
3599 if (data->operand[0].mode != VOIDmode)
3600 end = gen_lowpart (data->operand[0].mode, end);
3602 insn = data->genfun (end, dest_mem, src_mem);
3604 gcc_assert (insn);
3606 emit_insn (insn);
3608 /* movstr is supposed to set end to the address of the NUL
3609 terminator. If the caller requested a mempcpy-like return value,
3610 adjust it. */
3611 if (endp == 1 && target != const0_rtx)
3613 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3614 emit_move_insn (target, force_operand (tem, NULL_RTX));
3617 return target;
3620 /* Expand expression EXP, which is a call to the strcpy builtin. Return
3621 NULL_RTX if we failed the caller should emit a normal call, otherwise
3622 try to get the result in TARGET, if convenient (and in mode MODE if that's
3623 convenient). */
3625 static rtx
3626 expand_builtin_strcpy (tree fndecl, tree exp, rtx target, enum machine_mode mode)
3628 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3630 tree dest = CALL_EXPR_ARG (exp, 0);
3631 tree src = CALL_EXPR_ARG (exp, 1);
3632 return expand_builtin_strcpy_args (fndecl, dest, src, target, mode);
3634 return NULL_RTX;
3637 /* Helper function to do the actual work for expand_builtin_strcpy. The
3638 arguments to the builtin_strcpy call DEST and SRC are broken out
3639 so that this can also be called without constructing an actual CALL_EXPR.
3640 The other arguments and return value are the same as for
3641 expand_builtin_strcpy. */
3643 static rtx
3644 expand_builtin_strcpy_args (tree fndecl, tree dest, tree src,
3645 rtx target, enum machine_mode mode)
3647 tree result = fold_builtin_strcpy (fndecl, dest, src, 0);
3648 if (result)
3649 return expand_expr (result, target, mode, EXPAND_NORMAL);
3650 return expand_movstr (dest, src, target, /*endp=*/0);
3654 /* Expand a call EXP to the stpcpy builtin.
3655 Return NULL_RTX if we failed the caller should emit a normal call,
3656 otherwise try to get the result in TARGET, if convenient (and in
3657 mode MODE if that's convenient). */
3659 static rtx
3660 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3662 tree dst, src;
3664 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3665 return NULL_RTX;
3667 dst = CALL_EXPR_ARG (exp, 0);
3668 src = CALL_EXPR_ARG (exp, 1);
3670 /* If return value is ignored, transform stpcpy into strcpy. */
3671 if (target == const0_rtx)
3673 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3674 if (!fn)
3675 return NULL_RTX;
3677 return expand_expr (build_call_expr (fn, 2, dst, src),
3678 target, mode, EXPAND_NORMAL);
3680 else
3682 tree len, lenp1;
3683 rtx ret;
3685 /* Ensure we get an actual string whose length can be evaluated at
3686 compile-time, not an expression containing a string. This is
3687 because the latter will potentially produce pessimized code
3688 when used to produce the return value. */
3689 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3690 return expand_movstr (dst, src, target, /*endp=*/2);
3692 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3693 ret = expand_builtin_mempcpy_args (dst, src, lenp1, TREE_TYPE (exp),
3694 target, mode, /*endp=*/2);
3696 if (ret)
3697 return ret;
3699 if (TREE_CODE (len) == INTEGER_CST)
3701 rtx len_rtx = expand_normal (len);
3703 if (GET_CODE (len_rtx) == CONST_INT)
3705 ret = expand_builtin_strcpy_args (get_callee_fndecl (exp),
3706 dst, src, target, mode);
3708 if (ret)
3710 if (! target)
3712 if (mode != VOIDmode)
3713 target = gen_reg_rtx (mode);
3714 else
3715 target = gen_reg_rtx (GET_MODE (ret));
3717 if (GET_MODE (target) != GET_MODE (ret))
3718 ret = gen_lowpart (GET_MODE (target), ret);
3720 ret = plus_constant (ret, INTVAL (len_rtx));
3721 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3722 gcc_assert (ret);
3724 return target;
3729 return expand_movstr (dst, src, target, /*endp=*/2);
3733 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3734 bytes from constant string DATA + OFFSET and return it as target
3735 constant. */
3738 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3739 enum machine_mode mode)
3741 const char *str = (const char *) data;
3743 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3744 return const0_rtx;
3746 return c_readstr (str + offset, mode);
3749 /* Expand expression EXP, which is a call to the strncpy builtin. Return
3750 NULL_RTX if we failed the caller should emit a normal call. */
3752 static rtx
3753 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3755 tree fndecl = get_callee_fndecl (exp);
3757 if (validate_arglist (exp,
3758 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3760 tree dest = CALL_EXPR_ARG (exp, 0);
3761 tree src = CALL_EXPR_ARG (exp, 1);
3762 tree len = CALL_EXPR_ARG (exp, 2);
3763 tree slen = c_strlen (src, 1);
3764 tree result = fold_builtin_strncpy (fndecl, dest, src, len, slen);
3766 if (result)
3768 while (TREE_CODE (result) == COMPOUND_EXPR)
3770 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3771 EXPAND_NORMAL);
3772 result = TREE_OPERAND (result, 1);
3774 return expand_expr (result, target, mode, EXPAND_NORMAL);
3777 /* We must be passed a constant len and src parameter. */
3778 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3779 return NULL_RTX;
3781 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3783 /* We're required to pad with trailing zeros if the requested
3784 len is greater than strlen(s2)+1. In that case try to
3785 use store_by_pieces, if it fails, punt. */
3786 if (tree_int_cst_lt (slen, len))
3788 unsigned int dest_align
3789 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3790 const char *p = c_getstr (src);
3791 rtx dest_mem;
3793 if (!p || dest_align == 0 || !host_integerp (len, 1)
3794 || !can_store_by_pieces (tree_low_cst (len, 1),
3795 builtin_strncpy_read_str,
3796 (void *) p, dest_align, false))
3797 return NULL_RTX;
3799 dest_mem = get_memory_rtx (dest, len);
3800 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3801 builtin_strncpy_read_str,
3802 (void *) p, dest_align, false, 0);
3803 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3804 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3805 return dest_mem;
3808 return NULL_RTX;
3811 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3812 bytes from constant string DATA + OFFSET and return it as target
3813 constant. */
3816 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3817 enum machine_mode mode)
3819 const char *c = (const char *) data;
3820 char *p = alloca (GET_MODE_SIZE (mode));
3822 memset (p, *c, GET_MODE_SIZE (mode));
3824 return c_readstr (p, mode);
3827 /* Callback routine for store_by_pieces. Return the RTL of a register
3828 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3829 char value given in the RTL register data. For example, if mode is
3830 4 bytes wide, return the RTL for 0x01010101*data. */
3832 static rtx
3833 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3834 enum machine_mode mode)
3836 rtx target, coeff;
3837 size_t size;
3838 char *p;
3840 size = GET_MODE_SIZE (mode);
3841 if (size == 1)
3842 return (rtx) data;
3844 p = alloca (size);
3845 memset (p, 1, size);
3846 coeff = c_readstr (p, mode);
3848 target = convert_to_mode (mode, (rtx) data, 1);
3849 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3850 return force_reg (mode, target);
3853 /* Expand expression EXP, which is a call to the memset builtin. Return
3854 NULL_RTX if we failed the caller should emit a normal call, otherwise
3855 try to get the result in TARGET, if convenient (and in mode MODE if that's
3856 convenient). */
3858 static rtx
3859 expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
3861 if (!validate_arglist (exp,
3862 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3863 return NULL_RTX;
3864 else
3866 tree dest = CALL_EXPR_ARG (exp, 0);
3867 tree val = CALL_EXPR_ARG (exp, 1);
3868 tree len = CALL_EXPR_ARG (exp, 2);
3869 return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3873 /* Helper function to do the actual work for expand_builtin_memset. The
3874 arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3875 so that this can also be called without constructing an actual CALL_EXPR.
3876 The other arguments and return value are the same as for
3877 expand_builtin_memset. */
3879 static rtx
3880 expand_builtin_memset_args (tree dest, tree val, tree len,
3881 rtx target, enum machine_mode mode, tree orig_exp)
3883 tree fndecl, fn;
3884 enum built_in_function fcode;
3885 char c;
3886 unsigned int dest_align;
3887 rtx dest_mem, dest_addr, len_rtx;
3888 HOST_WIDE_INT expected_size = -1;
3889 unsigned int expected_align = 0;
3891 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3893 /* If DEST is not a pointer type, don't do this operation in-line. */
3894 if (dest_align == 0)
3895 return NULL_RTX;
3897 stringop_block_profile (orig_exp, &expected_align, &expected_size);
3898 if (expected_align < dest_align)
3899 expected_align = dest_align;
3901 /* If the LEN parameter is zero, return DEST. */
3902 if (integer_zerop (len))
3904 /* Evaluate and ignore VAL in case it has side-effects. */
3905 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3906 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3909 /* Stabilize the arguments in case we fail. */
3910 dest = builtin_save_expr (dest);
3911 val = builtin_save_expr (val);
3912 len = builtin_save_expr (len);
3914 len_rtx = expand_normal (len);
3915 dest_mem = get_memory_rtx (dest, len);
3917 if (TREE_CODE (val) != INTEGER_CST)
3919 rtx val_rtx;
3921 val_rtx = expand_normal (val);
3922 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3923 val_rtx, 0);
3925 /* Assume that we can memset by pieces if we can store
3926 * the coefficients by pieces (in the required modes).
3927 * We can't pass builtin_memset_gen_str as that emits RTL. */
3928 c = 1;
3929 if (host_integerp (len, 1)
3930 && can_store_by_pieces (tree_low_cst (len, 1),
3931 builtin_memset_read_str, &c, dest_align,
3932 true))
3934 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3935 val_rtx);
3936 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3937 builtin_memset_gen_str, val_rtx, dest_align,
3938 true, 0);
3940 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3941 dest_align, expected_align,
3942 expected_size))
3943 goto do_libcall;
3945 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3946 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3947 return dest_mem;
3950 if (target_char_cast (val, &c))
3951 goto do_libcall;
3953 if (c)
3955 if (host_integerp (len, 1)
3956 && can_store_by_pieces (tree_low_cst (len, 1),
3957 builtin_memset_read_str, &c, dest_align,
3958 true))
3959 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3960 builtin_memset_read_str, &c, dest_align, true, 0);
3961 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3962 dest_align, expected_align,
3963 expected_size))
3964 goto do_libcall;
3966 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3967 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3968 return dest_mem;
3971 set_mem_align (dest_mem, dest_align);
3972 dest_addr = clear_storage_hints (dest_mem, len_rtx,
3973 CALL_EXPR_TAILCALL (orig_exp)
3974 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3975 expected_align, expected_size);
3977 if (dest_addr == 0)
3979 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3980 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3983 return dest_addr;
3985 do_libcall:
3986 fndecl = get_callee_fndecl (orig_exp);
3987 fcode = DECL_FUNCTION_CODE (fndecl);
3988 if (fcode == BUILT_IN_MEMSET)
3989 fn = build_call_expr (fndecl, 3, dest, val, len);
3990 else if (fcode == BUILT_IN_BZERO)
3991 fn = build_call_expr (fndecl, 2, dest, len);
3992 else
3993 gcc_unreachable ();
3994 if (TREE_CODE (fn) == CALL_EXPR)
3995 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3996 return expand_call (fn, target, target == const0_rtx);
3999 /* Expand expression EXP, which is a call to the bzero builtin. Return
4000 NULL_RTX if we failed the caller should emit a normal call. */
4002 static rtx
4003 expand_builtin_bzero (tree exp)
4005 tree dest, size;
4007 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4008 return NULL_RTX;
4010 dest = CALL_EXPR_ARG (exp, 0);
4011 size = CALL_EXPR_ARG (exp, 1);
4013 /* New argument list transforming bzero(ptr x, int y) to
4014 memset(ptr x, int 0, size_t y). This is done this way
4015 so that if it isn't expanded inline, we fallback to
4016 calling bzero instead of memset. */
4018 return expand_builtin_memset_args (dest, integer_zero_node,
4019 fold_convert (sizetype, size),
4020 const0_rtx, VOIDmode, exp);
4023 /* Expand a call to the memchr builtin. Return NULL_RTX if we failed the
4024 caller should emit a normal call, otherwise try to get the result
4025 in TARGET, if convenient (and in mode MODE if that's convenient). */
4027 static rtx
4028 expand_builtin_memchr (tree exp, rtx target, enum machine_mode mode)
4030 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE,
4031 INTEGER_TYPE, VOID_TYPE))
4033 tree type = TREE_TYPE (exp);
4034 tree result = fold_builtin_memchr (CALL_EXPR_ARG (exp, 0),
4035 CALL_EXPR_ARG (exp, 1),
4036 CALL_EXPR_ARG (exp, 2), type);
4037 if (result)
4038 return expand_expr (result, target, mode, EXPAND_NORMAL);
4040 return NULL_RTX;
4043 /* Expand expression EXP, which is a call to the memcmp built-in function.
4044 Return NULL_RTX if we failed and the
4045 caller should emit a normal call, otherwise try to get the result in
4046 TARGET, if convenient (and in mode MODE, if that's convenient). */
4048 static rtx
4049 expand_builtin_memcmp (tree exp, rtx target, enum machine_mode mode)
4051 if (!validate_arglist (exp,
4052 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4053 return NULL_RTX;
4054 else
4056 tree result = fold_builtin_memcmp (CALL_EXPR_ARG (exp, 0),
4057 CALL_EXPR_ARG (exp, 1),
4058 CALL_EXPR_ARG (exp, 2));
4059 if (result)
4060 return expand_expr (result, target, mode, EXPAND_NORMAL);
4063 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
4065 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4066 rtx result;
4067 rtx insn;
4068 tree arg1 = CALL_EXPR_ARG (exp, 0);
4069 tree arg2 = CALL_EXPR_ARG (exp, 1);
4070 tree len = CALL_EXPR_ARG (exp, 2);
4072 int arg1_align
4073 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4074 int arg2_align
4075 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4076 enum machine_mode insn_mode;
4078 #ifdef HAVE_cmpmemsi
4079 if (HAVE_cmpmemsi)
4080 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
4081 else
4082 #endif
4083 #ifdef HAVE_cmpstrnsi
4084 if (HAVE_cmpstrnsi)
4085 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4086 else
4087 #endif
4088 return NULL_RTX;
4090 /* If we don't have POINTER_TYPE, call the function. */
4091 if (arg1_align == 0 || arg2_align == 0)
4092 return NULL_RTX;
4094 /* Make a place to write the result of the instruction. */
4095 result = target;
4096 if (! (result != 0
4097 && REG_P (result) && GET_MODE (result) == insn_mode
4098 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4099 result = gen_reg_rtx (insn_mode);
4101 arg1_rtx = get_memory_rtx (arg1, len);
4102 arg2_rtx = get_memory_rtx (arg2, len);
4103 arg3_rtx = expand_normal (len);
4105 /* Set MEM_SIZE as appropriate. */
4106 if (GET_CODE (arg3_rtx) == CONST_INT)
4108 set_mem_size (arg1_rtx, arg3_rtx);
4109 set_mem_size (arg2_rtx, arg3_rtx);
4112 #ifdef HAVE_cmpmemsi
4113 if (HAVE_cmpmemsi)
4114 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4115 GEN_INT (MIN (arg1_align, arg2_align)));
4116 else
4117 #endif
4118 #ifdef HAVE_cmpstrnsi
4119 if (HAVE_cmpstrnsi)
4120 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4121 GEN_INT (MIN (arg1_align, arg2_align)));
4122 else
4123 #endif
4124 gcc_unreachable ();
4126 if (insn)
4127 emit_insn (insn);
4128 else
4129 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
4130 TYPE_MODE (integer_type_node), 3,
4131 XEXP (arg1_rtx, 0), Pmode,
4132 XEXP (arg2_rtx, 0), Pmode,
4133 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
4134 TYPE_UNSIGNED (sizetype)),
4135 TYPE_MODE (sizetype));
4137 /* Return the value in the proper mode for this function. */
4138 mode = TYPE_MODE (TREE_TYPE (exp));
4139 if (GET_MODE (result) == mode)
4140 return result;
4141 else if (target != 0)
4143 convert_move (target, result, 0);
4144 return target;
4146 else
4147 return convert_to_mode (mode, result, 0);
4149 #endif
4151 return NULL_RTX;
4154 /* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX
4155 if we failed the caller should emit a normal call, otherwise try to get
4156 the result in TARGET, if convenient. */
4158 static rtx
4159 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
4161 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4162 return NULL_RTX;
4163 else
4165 tree result = fold_builtin_strcmp (CALL_EXPR_ARG (exp, 0),
4166 CALL_EXPR_ARG (exp, 1));
4167 if (result)
4168 return expand_expr (result, target, mode, EXPAND_NORMAL);
4171 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
4172 if (cmpstr_optab[SImode] != CODE_FOR_nothing
4173 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
4175 rtx arg1_rtx, arg2_rtx;
4176 rtx result, insn = NULL_RTX;
4177 tree fndecl, fn;
4178 tree arg1 = CALL_EXPR_ARG (exp, 0);
4179 tree arg2 = CALL_EXPR_ARG (exp, 1);
4181 int arg1_align
4182 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4183 int arg2_align
4184 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4186 /* If we don't have POINTER_TYPE, call the function. */
4187 if (arg1_align == 0 || arg2_align == 0)
4188 return NULL_RTX;
4190 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
4191 arg1 = builtin_save_expr (arg1);
4192 arg2 = builtin_save_expr (arg2);
4194 arg1_rtx = get_memory_rtx (arg1, NULL);
4195 arg2_rtx = get_memory_rtx (arg2, NULL);
4197 #ifdef HAVE_cmpstrsi
4198 /* Try to call cmpstrsi. */
4199 if (HAVE_cmpstrsi)
4201 enum machine_mode insn_mode
4202 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
4204 /* Make a place to write the result of the instruction. */
4205 result = target;
4206 if (! (result != 0
4207 && REG_P (result) && GET_MODE (result) == insn_mode
4208 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4209 result = gen_reg_rtx (insn_mode);
4211 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
4212 GEN_INT (MIN (arg1_align, arg2_align)));
4214 #endif
4215 #ifdef HAVE_cmpstrnsi
4216 /* Try to determine at least one length and call cmpstrnsi. */
4217 if (!insn && HAVE_cmpstrnsi)
4219 tree len;
4220 rtx arg3_rtx;
4222 enum machine_mode insn_mode
4223 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4224 tree len1 = c_strlen (arg1, 1);
4225 tree len2 = c_strlen (arg2, 1);
4227 if (len1)
4228 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4229 if (len2)
4230 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4232 /* If we don't have a constant length for the first, use the length
4233 of the second, if we know it. We don't require a constant for
4234 this case; some cost analysis could be done if both are available
4235 but neither is constant. For now, assume they're equally cheap,
4236 unless one has side effects. If both strings have constant lengths,
4237 use the smaller. */
4239 if (!len1)
4240 len = len2;
4241 else if (!len2)
4242 len = len1;
4243 else if (TREE_SIDE_EFFECTS (len1))
4244 len = len2;
4245 else if (TREE_SIDE_EFFECTS (len2))
4246 len = len1;
4247 else if (TREE_CODE (len1) != INTEGER_CST)
4248 len = len2;
4249 else if (TREE_CODE (len2) != INTEGER_CST)
4250 len = len1;
4251 else if (tree_int_cst_lt (len1, len2))
4252 len = len1;
4253 else
4254 len = len2;
4256 /* If both arguments have side effects, we cannot optimize. */
4257 if (!len || TREE_SIDE_EFFECTS (len))
4258 goto do_libcall;
4260 arg3_rtx = expand_normal (len);
4262 /* Make a place to write the result of the instruction. */
4263 result = target;
4264 if (! (result != 0
4265 && REG_P (result) && GET_MODE (result) == insn_mode
4266 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4267 result = gen_reg_rtx (insn_mode);
4269 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4270 GEN_INT (MIN (arg1_align, arg2_align)));
4272 #endif
4274 if (insn)
4276 emit_insn (insn);
4278 /* Return the value in the proper mode for this function. */
4279 mode = TYPE_MODE (TREE_TYPE (exp));
4280 if (GET_MODE (result) == mode)
4281 return result;
4282 if (target == 0)
4283 return convert_to_mode (mode, result, 0);
4284 convert_move (target, result, 0);
4285 return target;
4288 /* Expand the library call ourselves using a stabilized argument
4289 list to avoid re-evaluating the function's arguments twice. */
4290 #ifdef HAVE_cmpstrnsi
4291 do_libcall:
4292 #endif
4293 fndecl = get_callee_fndecl (exp);
4294 fn = build_call_expr (fndecl, 2, arg1, arg2);
4295 if (TREE_CODE (fn) == CALL_EXPR)
4296 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4297 return expand_call (fn, target, target == const0_rtx);
4299 #endif
4300 return NULL_RTX;
4303 /* Expand expression EXP, which is a call to the strncmp builtin. Return
4304 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
4305 the result in TARGET, if convenient. */
4307 static rtx
4308 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
4310 if (!validate_arglist (exp,
4311 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4312 return NULL_RTX;
4313 else
4315 tree result = fold_builtin_strncmp (CALL_EXPR_ARG (exp, 0),
4316 CALL_EXPR_ARG (exp, 1),
4317 CALL_EXPR_ARG (exp, 2));
4318 if (result)
4319 return expand_expr (result, target, mode, EXPAND_NORMAL);
4322 /* If c_strlen can determine an expression for one of the string
4323 lengths, and it doesn't have side effects, then emit cmpstrnsi
4324 using length MIN(strlen(string)+1, arg3). */
4325 #ifdef HAVE_cmpstrnsi
4326 if (HAVE_cmpstrnsi)
4328 tree len, len1, len2;
4329 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4330 rtx result, insn;
4331 tree fndecl, fn;
4332 tree arg1 = CALL_EXPR_ARG (exp, 0);
4333 tree arg2 = CALL_EXPR_ARG (exp, 1);
4334 tree arg3 = CALL_EXPR_ARG (exp, 2);
4336 int arg1_align
4337 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4338 int arg2_align
4339 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4340 enum machine_mode insn_mode
4341 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4343 len1 = c_strlen (arg1, 1);
4344 len2 = c_strlen (arg2, 1);
4346 if (len1)
4347 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4348 if (len2)
4349 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4351 /* If we don't have a constant length for the first, use the length
4352 of the second, if we know it. We don't require a constant for
4353 this case; some cost analysis could be done if both are available
4354 but neither is constant. For now, assume they're equally cheap,
4355 unless one has side effects. If both strings have constant lengths,
4356 use the smaller. */
4358 if (!len1)
4359 len = len2;
4360 else if (!len2)
4361 len = len1;
4362 else if (TREE_SIDE_EFFECTS (len1))
4363 len = len2;
4364 else if (TREE_SIDE_EFFECTS (len2))
4365 len = len1;
4366 else if (TREE_CODE (len1) != INTEGER_CST)
4367 len = len2;
4368 else if (TREE_CODE (len2) != INTEGER_CST)
4369 len = len1;
4370 else if (tree_int_cst_lt (len1, len2))
4371 len = len1;
4372 else
4373 len = len2;
4375 /* If both arguments have side effects, we cannot optimize. */
4376 if (!len || TREE_SIDE_EFFECTS (len))
4377 return NULL_RTX;
4379 /* The actual new length parameter is MIN(len,arg3). */
4380 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
4381 fold_convert (TREE_TYPE (len), arg3));
4383 /* If we don't have POINTER_TYPE, call the function. */
4384 if (arg1_align == 0 || arg2_align == 0)
4385 return NULL_RTX;
4387 /* Make a place to write the result of the instruction. */
4388 result = target;
4389 if (! (result != 0
4390 && REG_P (result) && GET_MODE (result) == insn_mode
4391 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4392 result = gen_reg_rtx (insn_mode);
4394 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4395 arg1 = builtin_save_expr (arg1);
4396 arg2 = builtin_save_expr (arg2);
4397 len = builtin_save_expr (len);
4399 arg1_rtx = get_memory_rtx (arg1, len);
4400 arg2_rtx = get_memory_rtx (arg2, len);
4401 arg3_rtx = expand_normal (len);
4402 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4403 GEN_INT (MIN (arg1_align, arg2_align)));
4404 if (insn)
4406 emit_insn (insn);
4408 /* Return the value in the proper mode for this function. */
4409 mode = TYPE_MODE (TREE_TYPE (exp));
4410 if (GET_MODE (result) == mode)
4411 return result;
4412 if (target == 0)
4413 return convert_to_mode (mode, result, 0);
4414 convert_move (target, result, 0);
4415 return target;
4418 /* Expand the library call ourselves using a stabilized argument
4419 list to avoid re-evaluating the function's arguments twice. */
4420 fndecl = get_callee_fndecl (exp);
4421 fn = build_call_expr (fndecl, 3, arg1, arg2, len);
4422 if (TREE_CODE (fn) == CALL_EXPR)
4423 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4424 return expand_call (fn, target, target == const0_rtx);
4426 #endif
4427 return NULL_RTX;
4430 /* Expand expression EXP, which is a call to the strcat builtin.
4431 Return NULL_RTX if we failed the caller should emit a normal call,
4432 otherwise try to get the result in TARGET, if convenient. */
4434 static rtx
4435 expand_builtin_strcat (tree fndecl, tree exp, rtx target, enum machine_mode mode)
4437 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4438 return NULL_RTX;
4439 else
4441 tree dst = CALL_EXPR_ARG (exp, 0);
4442 tree src = CALL_EXPR_ARG (exp, 1);
4443 const char *p = c_getstr (src);
4445 /* If the string length is zero, return the dst parameter. */
4446 if (p && *p == '\0')
4447 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4449 if (!optimize_size)
4451 /* See if we can store by pieces into (dst + strlen(dst)). */
4452 tree newsrc, newdst,
4453 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4454 rtx insns;
4456 /* Stabilize the argument list. */
4457 newsrc = builtin_save_expr (src);
4458 dst = builtin_save_expr (dst);
4460 start_sequence ();
4462 /* Create strlen (dst). */
4463 newdst = build_call_expr (strlen_fn, 1, dst);
4464 /* Create (dst p+ strlen (dst)). */
4466 newdst = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4467 newdst = builtin_save_expr (newdst);
4469 if (!expand_builtin_strcpy_args (fndecl, newdst, newsrc, target, mode))
4471 end_sequence (); /* Stop sequence. */
4472 return NULL_RTX;
4475 /* Output the entire sequence. */
4476 insns = get_insns ();
4477 end_sequence ();
4478 emit_insn (insns);
4480 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4483 return NULL_RTX;
4487 /* Expand expression EXP, which is a call to the strncat builtin.
4488 Return NULL_RTX if we failed the caller should emit a normal call,
4489 otherwise try to get the result in TARGET, if convenient. */
4491 static rtx
4492 expand_builtin_strncat (tree exp, rtx target, enum machine_mode mode)
4494 if (validate_arglist (exp,
4495 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4497 tree result = fold_builtin_strncat (CALL_EXPR_ARG (exp, 0),
4498 CALL_EXPR_ARG (exp, 1),
4499 CALL_EXPR_ARG (exp, 2));
4500 if (result)
4501 return expand_expr (result, target, mode, EXPAND_NORMAL);
4503 return NULL_RTX;
4506 /* Expand expression EXP, which is a call to the strspn builtin.
4507 Return NULL_RTX if we failed the caller should emit a normal call,
4508 otherwise try to get the result in TARGET, if convenient. */
4510 static rtx
4511 expand_builtin_strspn (tree exp, rtx target, enum machine_mode mode)
4513 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4515 tree result = fold_builtin_strspn (CALL_EXPR_ARG (exp, 0),
4516 CALL_EXPR_ARG (exp, 1));
4517 if (result)
4518 return expand_expr (result, target, mode, EXPAND_NORMAL);
4520 return NULL_RTX;
4523 /* Expand expression EXP, which is a call to the strcspn builtin.
4524 Return NULL_RTX if we failed the caller should emit a normal call,
4525 otherwise try to get the result in TARGET, if convenient. */
4527 static rtx
4528 expand_builtin_strcspn (tree exp, rtx target, enum machine_mode mode)
4530 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4532 tree result = fold_builtin_strcspn (CALL_EXPR_ARG (exp, 0),
4533 CALL_EXPR_ARG (exp, 1));
4534 if (result)
4535 return expand_expr (result, target, mode, EXPAND_NORMAL);
4537 return NULL_RTX;
4540 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4541 if that's convenient. */
4544 expand_builtin_saveregs (void)
4546 rtx val, seq;
4548 /* Don't do __builtin_saveregs more than once in a function.
4549 Save the result of the first call and reuse it. */
4550 if (saveregs_value != 0)
4551 return saveregs_value;
4553 /* When this function is called, it means that registers must be
4554 saved on entry to this function. So we migrate the call to the
4555 first insn of this function. */
4557 start_sequence ();
4559 /* Do whatever the machine needs done in this case. */
4560 val = targetm.calls.expand_builtin_saveregs ();
4562 seq = get_insns ();
4563 end_sequence ();
4565 saveregs_value = val;
4567 /* Put the insns after the NOTE that starts the function. If this
4568 is inside a start_sequence, make the outer-level insn chain current, so
4569 the code is placed at the start of the function. */
4570 push_topmost_sequence ();
4571 emit_insn_after (seq, entry_of_function ());
4572 pop_topmost_sequence ();
4574 return val;
4577 /* __builtin_args_info (N) returns word N of the arg space info
4578 for the current function. The number and meanings of words
4579 is controlled by the definition of CUMULATIVE_ARGS. */
4581 static rtx
4582 expand_builtin_args_info (tree exp)
4584 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4585 int *word_ptr = (int *) &current_function_args_info;
4587 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4589 if (call_expr_nargs (exp) != 0)
4591 if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0))
4592 error ("argument of %<__builtin_args_info%> must be constant");
4593 else
4595 HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0);
4597 if (wordnum < 0 || wordnum >= nwords)
4598 error ("argument of %<__builtin_args_info%> out of range");
4599 else
4600 return GEN_INT (word_ptr[wordnum]);
4603 else
4604 error ("missing argument in %<__builtin_args_info%>");
4606 return const0_rtx;
4609 /* Expand a call to __builtin_next_arg. */
4611 static rtx
4612 expand_builtin_next_arg (void)
4614 /* Checking arguments is already done in fold_builtin_next_arg
4615 that must be called before this function. */
4616 return expand_binop (ptr_mode, add_optab,
4617 current_function_internal_arg_pointer,
4618 current_function_arg_offset_rtx,
4619 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4622 /* Make it easier for the backends by protecting the valist argument
4623 from multiple evaluations. */
4625 static tree
4626 stabilize_va_list (tree valist, int needs_lvalue)
4628 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4630 if (TREE_SIDE_EFFECTS (valist))
4631 valist = save_expr (valist);
4633 /* For this case, the backends will be expecting a pointer to
4634 TREE_TYPE (va_list_type_node), but it's possible we've
4635 actually been given an array (an actual va_list_type_node).
4636 So fix it. */
4637 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4639 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4640 valist = build_fold_addr_expr_with_type (valist, p1);
4643 else
4645 tree pt;
4647 if (! needs_lvalue)
4649 if (! TREE_SIDE_EFFECTS (valist))
4650 return valist;
4652 pt = build_pointer_type (va_list_type_node);
4653 valist = fold_build1 (ADDR_EXPR, pt, valist);
4654 TREE_SIDE_EFFECTS (valist) = 1;
4657 if (TREE_SIDE_EFFECTS (valist))
4658 valist = save_expr (valist);
4659 valist = build_fold_indirect_ref (valist);
4662 return valist;
4665 /* The "standard" definition of va_list is void*. */
4667 tree
4668 std_build_builtin_va_list (void)
4670 return ptr_type_node;
4673 /* The "standard" implementation of va_start: just assign `nextarg' to
4674 the variable. */
4676 void
4677 std_expand_builtin_va_start (tree valist, rtx nextarg)
4679 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4680 convert_move (va_r, nextarg, 0);
4683 /* Expand EXP, a call to __builtin_va_start. */
4685 static rtx
4686 expand_builtin_va_start (tree exp)
4688 rtx nextarg;
4689 tree valist;
4691 if (call_expr_nargs (exp) < 2)
4693 error ("too few arguments to function %<va_start%>");
4694 return const0_rtx;
4697 if (fold_builtin_next_arg (exp, true))
4698 return const0_rtx;
4700 nextarg = expand_builtin_next_arg ();
4701 valist = stabilize_va_list (CALL_EXPR_ARG (exp, 0), 1);
4703 #ifdef EXPAND_BUILTIN_VA_START
4704 EXPAND_BUILTIN_VA_START (valist, nextarg);
4705 #else
4706 std_expand_builtin_va_start (valist, nextarg);
4707 #endif
4709 return const0_rtx;
4712 /* The "standard" implementation of va_arg: read the value from the
4713 current (padded) address and increment by the (padded) size. */
4715 tree
4716 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4718 tree addr, t, type_size, rounded_size, valist_tmp;
4719 unsigned HOST_WIDE_INT align, boundary;
4720 bool indirect;
4722 #ifdef ARGS_GROW_DOWNWARD
4723 /* All of the alignment and movement below is for args-grow-up machines.
4724 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4725 implement their own specialized gimplify_va_arg_expr routines. */
4726 gcc_unreachable ();
4727 #endif
4729 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4730 if (indirect)
4731 type = build_pointer_type (type);
4733 align = PARM_BOUNDARY / BITS_PER_UNIT;
4734 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4736 /* Hoist the valist value into a temporary for the moment. */
4737 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4739 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4740 requires greater alignment, we must perform dynamic alignment. */
4741 if (boundary > align
4742 && !integer_zerop (TYPE_SIZE (type)))
4744 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4745 fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist),
4746 valist_tmp, size_int (boundary - 1)));
4747 gimplify_and_add (t, pre_p);
4749 t = fold_convert (sizetype, valist_tmp);
4750 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4751 fold_convert (TREE_TYPE (valist),
4752 fold_build2 (BIT_AND_EXPR, sizetype, t,
4753 size_int (-boundary))));
4754 gimplify_and_add (t, pre_p);
4756 else
4757 boundary = align;
4759 /* If the actual alignment is less than the alignment of the type,
4760 adjust the type accordingly so that we don't assume strict alignment
4761 when deferencing the pointer. */
4762 boundary *= BITS_PER_UNIT;
4763 if (boundary < TYPE_ALIGN (type))
4765 type = build_variant_type_copy (type);
4766 TYPE_ALIGN (type) = boundary;
4769 /* Compute the rounded size of the type. */
4770 type_size = size_in_bytes (type);
4771 rounded_size = round_up (type_size, align);
4773 /* Reduce rounded_size so it's sharable with the postqueue. */
4774 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4776 /* Get AP. */
4777 addr = valist_tmp;
4778 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4780 /* Small args are padded downward. */
4781 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4782 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4783 size_binop (MINUS_EXPR, rounded_size, type_size));
4784 addr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr), addr, t);
4787 /* Compute new value for AP. */
4788 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
4789 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4790 gimplify_and_add (t, pre_p);
4792 addr = fold_convert (build_pointer_type (type), addr);
4794 if (indirect)
4795 addr = build_va_arg_indirect_ref (addr);
4797 return build_va_arg_indirect_ref (addr);
4800 /* Build an indirect-ref expression over the given TREE, which represents a
4801 piece of a va_arg() expansion. */
4802 tree
4803 build_va_arg_indirect_ref (tree addr)
4805 addr = build_fold_indirect_ref (addr);
4807 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4808 mf_mark (addr);
4810 return addr;
4813 /* Return a dummy expression of type TYPE in order to keep going after an
4814 error. */
4816 static tree
4817 dummy_object (tree type)
4819 tree t = build_int_cst (build_pointer_type (type), 0);
4820 return build1 (INDIRECT_REF, type, t);
4823 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4824 builtin function, but a very special sort of operator. */
4826 enum gimplify_status
4827 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4829 tree promoted_type, want_va_type, have_va_type;
4830 tree valist = TREE_OPERAND (*expr_p, 0);
4831 tree type = TREE_TYPE (*expr_p);
4832 tree t;
4834 /* Verify that valist is of the proper type. */
4835 want_va_type = va_list_type_node;
4836 have_va_type = TREE_TYPE (valist);
4838 if (have_va_type == error_mark_node)
4839 return GS_ERROR;
4841 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4843 /* If va_list is an array type, the argument may have decayed
4844 to a pointer type, e.g. by being passed to another function.
4845 In that case, unwrap both types so that we can compare the
4846 underlying records. */
4847 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4848 || POINTER_TYPE_P (have_va_type))
4850 want_va_type = TREE_TYPE (want_va_type);
4851 have_va_type = TREE_TYPE (have_va_type);
4855 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4857 error ("first argument to %<va_arg%> not of type %<va_list%>");
4858 return GS_ERROR;
4861 /* Generate a diagnostic for requesting data of a type that cannot
4862 be passed through `...' due to type promotion at the call site. */
4863 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4864 != type)
4866 static bool gave_help;
4868 /* Unfortunately, this is merely undefined, rather than a constraint
4869 violation, so we cannot make this an error. If this call is never
4870 executed, the program is still strictly conforming. */
4871 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4872 type, promoted_type);
4873 if (! gave_help)
4875 gave_help = true;
4876 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4877 promoted_type, type);
4880 /* We can, however, treat "undefined" any way we please.
4881 Call abort to encourage the user to fix the program. */
4882 inform ("if this code is reached, the program will abort");
4883 t = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
4884 append_to_statement_list (t, pre_p);
4886 /* This is dead code, but go ahead and finish so that the
4887 mode of the result comes out right. */
4888 *expr_p = dummy_object (type);
4889 return GS_ALL_DONE;
4891 else
4893 /* Make it easier for the backends by protecting the valist argument
4894 from multiple evaluations. */
4895 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4897 /* For this case, the backends will be expecting a pointer to
4898 TREE_TYPE (va_list_type_node), but it's possible we've
4899 actually been given an array (an actual va_list_type_node).
4900 So fix it. */
4901 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4903 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4904 valist = build_fold_addr_expr_with_type (valist, p1);
4906 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4908 else
4909 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4911 if (!targetm.gimplify_va_arg_expr)
4912 /* FIXME:Once most targets are converted we should merely
4913 assert this is non-null. */
4914 return GS_ALL_DONE;
4916 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4917 return GS_OK;
4921 /* Expand EXP, a call to __builtin_va_end. */
4923 static rtx
4924 expand_builtin_va_end (tree exp)
4926 tree valist = CALL_EXPR_ARG (exp, 0);
4928 /* Evaluate for side effects, if needed. I hate macros that don't
4929 do that. */
4930 if (TREE_SIDE_EFFECTS (valist))
4931 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4933 return const0_rtx;
4936 /* Expand EXP, a call to __builtin_va_copy. We do this as a
4937 builtin rather than just as an assignment in stdarg.h because of the
4938 nastiness of array-type va_list types. */
4940 static rtx
4941 expand_builtin_va_copy (tree exp)
4943 tree dst, src, t;
4945 dst = CALL_EXPR_ARG (exp, 0);
4946 src = CALL_EXPR_ARG (exp, 1);
4948 dst = stabilize_va_list (dst, 1);
4949 src = stabilize_va_list (src, 0);
4951 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4953 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4954 TREE_SIDE_EFFECTS (t) = 1;
4955 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4957 else
4959 rtx dstb, srcb, size;
4961 /* Evaluate to pointers. */
4962 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4963 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4964 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4965 VOIDmode, EXPAND_NORMAL);
4967 dstb = convert_memory_address (Pmode, dstb);
4968 srcb = convert_memory_address (Pmode, srcb);
4970 /* "Dereference" to BLKmode memories. */
4971 dstb = gen_rtx_MEM (BLKmode, dstb);
4972 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4973 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4974 srcb = gen_rtx_MEM (BLKmode, srcb);
4975 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4976 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4978 /* Copy. */
4979 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4982 return const0_rtx;
4985 /* Expand a call to one of the builtin functions __builtin_frame_address or
4986 __builtin_return_address. */
4988 static rtx
4989 expand_builtin_frame_address (tree fndecl, tree exp)
4991 /* The argument must be a nonnegative integer constant.
4992 It counts the number of frames to scan up the stack.
4993 The value is the return address saved in that frame. */
4994 if (call_expr_nargs (exp) == 0)
4995 /* Warning about missing arg was already issued. */
4996 return const0_rtx;
4997 else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
4999 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5000 error ("invalid argument to %<__builtin_frame_address%>");
5001 else
5002 error ("invalid argument to %<__builtin_return_address%>");
5003 return const0_rtx;
5005 else
5007 rtx tem
5008 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
5009 tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
5011 /* Some ports cannot access arbitrary stack frames. */
5012 if (tem == NULL)
5014 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5015 warning (0, "unsupported argument to %<__builtin_frame_address%>");
5016 else
5017 warning (0, "unsupported argument to %<__builtin_return_address%>");
5018 return const0_rtx;
5021 /* For __builtin_frame_address, return what we've got. */
5022 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5023 return tem;
5025 if (!REG_P (tem)
5026 && ! CONSTANT_P (tem))
5027 tem = copy_to_mode_reg (Pmode, tem);
5028 return tem;
5032 /* Expand EXP, a call to the alloca builtin. Return NULL_RTX if
5033 we failed and the caller should emit a normal call, otherwise try to get
5034 the result in TARGET, if convenient. */
5036 static rtx
5037 expand_builtin_alloca (tree exp, rtx target)
5039 rtx op0;
5040 rtx result;
5042 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
5043 should always expand to function calls. These can be intercepted
5044 in libmudflap. */
5045 if (flag_mudflap)
5046 return NULL_RTX;
5048 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5049 return NULL_RTX;
5051 /* Compute the argument. */
5052 op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
5054 /* Allocate the desired space. */
5055 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
5056 result = convert_memory_address (ptr_mode, result);
5058 return result;
5061 /* Expand a call to a bswap builtin with argument ARG0. MODE
5062 is the mode to expand with. */
5064 static rtx
5065 expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
5067 enum machine_mode mode;
5068 tree arg;
5069 rtx op0;
5071 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5072 return NULL_RTX;
5074 arg = CALL_EXPR_ARG (exp, 0);
5075 mode = TYPE_MODE (TREE_TYPE (arg));
5076 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
5078 target = expand_unop (mode, bswap_optab, op0, target, 1);
5080 gcc_assert (target);
5082 return convert_to_mode (mode, target, 0);
5085 /* Expand a call to a unary builtin in EXP.
5086 Return NULL_RTX if a normal call should be emitted rather than expanding the
5087 function in-line. If convenient, the result should be placed in TARGET.
5088 SUBTARGET may be used as the target for computing one of EXP's operands. */
5090 static rtx
5091 expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
5092 rtx subtarget, optab op_optab)
5094 rtx op0;
5096 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5097 return NULL_RTX;
5099 /* Compute the argument. */
5100 op0 = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
5101 VOIDmode, EXPAND_NORMAL);
5102 /* Compute op, into TARGET if possible.
5103 Set TARGET to wherever the result comes back. */
5104 target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
5105 op_optab, op0, target, 1);
5106 gcc_assert (target);
5108 return convert_to_mode (target_mode, target, 0);
5111 /* If the string passed to fputs is a constant and is one character
5112 long, we attempt to transform this call into __builtin_fputc(). */
5114 static rtx
5115 expand_builtin_fputs (tree exp, rtx target, bool unlocked)
5117 /* Verify the arguments in the original call. */
5118 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5120 tree result = fold_builtin_fputs (CALL_EXPR_ARG (exp, 0),
5121 CALL_EXPR_ARG (exp, 1),
5122 (target == const0_rtx),
5123 unlocked, NULL_TREE);
5124 if (result)
5125 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
5127 return NULL_RTX;
5130 /* Expand a call to __builtin_expect. We just return our argument
5131 as the builtin_expect semantic should've been already executed by
5132 tree branch prediction pass. */
5134 static rtx
5135 expand_builtin_expect (tree exp, rtx target)
5137 tree arg, c;
5139 if (call_expr_nargs (exp) < 2)
5140 return const0_rtx;
5141 arg = CALL_EXPR_ARG (exp, 0);
5142 c = CALL_EXPR_ARG (exp, 1);
5144 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5145 /* When guessing was done, the hints should be already stripped away. */
5146 gcc_assert (!flag_guess_branch_prob
5147 || optimize == 0 || errorcount || sorrycount);
5148 return target;
5151 void
5152 expand_builtin_trap (void)
5154 #ifdef HAVE_trap
5155 if (HAVE_trap)
5156 emit_insn (gen_trap ());
5157 else
5158 #endif
5159 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5160 emit_barrier ();
5163 /* Expand EXP, a call to fabs, fabsf or fabsl.
5164 Return NULL_RTX if a normal call should be emitted rather than expanding
5165 the function inline. If convenient, the result should be placed
5166 in TARGET. SUBTARGET may be used as the target for computing
5167 the operand. */
5169 static rtx
5170 expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
5172 enum machine_mode mode;
5173 tree arg;
5174 rtx op0;
5176 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5177 return NULL_RTX;
5179 arg = CALL_EXPR_ARG (exp, 0);
5180 mode = TYPE_MODE (TREE_TYPE (arg));
5181 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
5182 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5185 /* Expand EXP, a call to copysign, copysignf, or copysignl.
5186 Return NULL is a normal call should be emitted rather than expanding the
5187 function inline. If convenient, the result should be placed in TARGET.
5188 SUBTARGET may be used as the target for computing the operand. */
5190 static rtx
5191 expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
5193 rtx op0, op1;
5194 tree arg;
5196 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
5197 return NULL_RTX;
5199 arg = CALL_EXPR_ARG (exp, 0);
5200 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
5202 arg = CALL_EXPR_ARG (exp, 1);
5203 op1 = expand_normal (arg);
5205 return expand_copysign (op0, op1, target);
5208 /* Create a new constant string literal and return a char* pointer to it.
5209 The STRING_CST value is the LEN characters at STR. */
5210 tree
5211 build_string_literal (int len, const char *str)
5213 tree t, elem, index, type;
5215 t = build_string (len, str);
5216 elem = build_type_variant (char_type_node, 1, 0);
5217 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
5218 type = build_array_type (elem, index);
5219 TREE_TYPE (t) = type;
5220 TREE_CONSTANT (t) = 1;
5221 TREE_INVARIANT (t) = 1;
5222 TREE_READONLY (t) = 1;
5223 TREE_STATIC (t) = 1;
5225 type = build_pointer_type (type);
5226 t = build1 (ADDR_EXPR, type, t);
5228 type = build_pointer_type (elem);
5229 t = build1 (NOP_EXPR, type, t);
5230 return t;
5233 /* Expand EXP, a call to printf or printf_unlocked.
5234 Return NULL_RTX if a normal call should be emitted rather than transforming
5235 the function inline. If convenient, the result should be placed in
5236 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
5237 call. */
5238 static rtx
5239 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
5240 bool unlocked)
5242 /* If we're using an unlocked function, assume the other unlocked
5243 functions exist explicitly. */
5244 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5245 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5246 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5247 : implicit_built_in_decls[BUILT_IN_PUTS];
5248 const char *fmt_str;
5249 tree fn = 0;
5250 tree fmt, arg;
5251 int nargs = call_expr_nargs (exp);
5253 /* If the return value is used, don't do the transformation. */
5254 if (target != const0_rtx)
5255 return NULL_RTX;
5257 /* Verify the required arguments in the original call. */
5258 if (nargs == 0)
5259 return NULL_RTX;
5260 fmt = CALL_EXPR_ARG (exp, 0);
5261 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5262 return NULL_RTX;
5264 /* Check whether the format is a literal string constant. */
5265 fmt_str = c_getstr (fmt);
5266 if (fmt_str == NULL)
5267 return NULL_RTX;
5269 if (!init_target_chars ())
5270 return NULL_RTX;
5272 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
5273 if (strcmp (fmt_str, target_percent_s_newline) == 0)
5275 if ((nargs != 2)
5276 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 1))))
5277 return NULL_RTX;
5278 if (fn_puts)
5279 fn = build_call_expr (fn_puts, 1, CALL_EXPR_ARG (exp, 1));
5281 /* If the format specifier was "%c", call __builtin_putchar(arg). */
5282 else if (strcmp (fmt_str, target_percent_c) == 0)
5284 if ((nargs != 2)
5285 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))) != INTEGER_TYPE)
5286 return NULL_RTX;
5287 if (fn_putchar)
5288 fn = build_call_expr (fn_putchar, 1, CALL_EXPR_ARG (exp, 1));
5290 else
5292 /* We can't handle anything else with % args or %% ... yet. */
5293 if (strchr (fmt_str, target_percent))
5294 return NULL_RTX;
5296 if (nargs > 1)
5297 return NULL_RTX;
5299 /* If the format specifier was "", printf does nothing. */
5300 if (fmt_str[0] == '\0')
5301 return const0_rtx;
5302 /* If the format specifier has length of 1, call putchar. */
5303 if (fmt_str[1] == '\0')
5305 /* Given printf("c"), (where c is any one character,)
5306 convert "c"[0] to an int and pass that to the replacement
5307 function. */
5308 arg = build_int_cst (NULL_TREE, fmt_str[0]);
5309 if (fn_putchar)
5310 fn = build_call_expr (fn_putchar, 1, arg);
5312 else
5314 /* If the format specifier was "string\n", call puts("string"). */
5315 size_t len = strlen (fmt_str);
5316 if ((unsigned char)fmt_str[len - 1] == target_newline)
5318 /* Create a NUL-terminated string that's one char shorter
5319 than the original, stripping off the trailing '\n'. */
5320 char *newstr = alloca (len);
5321 memcpy (newstr, fmt_str, len - 1);
5322 newstr[len - 1] = 0;
5323 arg = build_string_literal (len, newstr);
5324 if (fn_puts)
5325 fn = build_call_expr (fn_puts, 1, arg);
5327 else
5328 /* We'd like to arrange to call fputs(string,stdout) here,
5329 but we need stdout and don't have a way to get it yet. */
5330 return NULL_RTX;
5334 if (!fn)
5335 return NULL_RTX;
5336 if (TREE_CODE (fn) == CALL_EXPR)
5337 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5338 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5341 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5342 Return NULL_RTX if a normal call should be emitted rather than transforming
5343 the function inline. If convenient, the result should be placed in
5344 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5345 call. */
5346 static rtx
5347 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5348 bool unlocked)
5350 /* If we're using an unlocked function, assume the other unlocked
5351 functions exist explicitly. */
5352 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5353 : implicit_built_in_decls[BUILT_IN_FPUTC];
5354 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5355 : implicit_built_in_decls[BUILT_IN_FPUTS];
5356 const char *fmt_str;
5357 tree fn = 0;
5358 tree fmt, fp, arg;
5359 int nargs = call_expr_nargs (exp);
5361 /* If the return value is used, don't do the transformation. */
5362 if (target != const0_rtx)
5363 return NULL_RTX;
5365 /* Verify the required arguments in the original call. */
5366 if (nargs < 2)
5367 return NULL_RTX;
5368 fp = CALL_EXPR_ARG (exp, 0);
5369 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5370 return NULL_RTX;
5371 fmt = CALL_EXPR_ARG (exp, 1);
5372 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5373 return NULL_RTX;
5375 /* Check whether the format is a literal string constant. */
5376 fmt_str = c_getstr (fmt);
5377 if (fmt_str == NULL)
5378 return NULL_RTX;
5380 if (!init_target_chars ())
5381 return NULL_RTX;
5383 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5384 if (strcmp (fmt_str, target_percent_s) == 0)
5386 if ((nargs != 3)
5387 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 2))))
5388 return NULL_RTX;
5389 arg = CALL_EXPR_ARG (exp, 2);
5390 if (fn_fputs)
5391 fn = build_call_expr (fn_fputs, 2, arg, fp);
5393 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5394 else if (strcmp (fmt_str, target_percent_c) == 0)
5396 if ((nargs != 3)
5397 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))) != INTEGER_TYPE)
5398 return NULL_RTX;
5399 arg = CALL_EXPR_ARG (exp, 2);
5400 if (fn_fputc)
5401 fn = build_call_expr (fn_fputc, 2, arg, fp);
5403 else
5405 /* We can't handle anything else with % args or %% ... yet. */
5406 if (strchr (fmt_str, target_percent))
5407 return NULL_RTX;
5409 if (nargs > 2)
5410 return NULL_RTX;
5412 /* If the format specifier was "", fprintf does nothing. */
5413 if (fmt_str[0] == '\0')
5415 /* Evaluate and ignore FILE* argument for side-effects. */
5416 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5417 return const0_rtx;
5420 /* When "string" doesn't contain %, replace all cases of
5421 fprintf(stream,string) with fputs(string,stream). The fputs
5422 builtin will take care of special cases like length == 1. */
5423 if (fn_fputs)
5424 fn = build_call_expr (fn_fputs, 2, fmt, fp);
5427 if (!fn)
5428 return NULL_RTX;
5429 if (TREE_CODE (fn) == CALL_EXPR)
5430 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5431 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5434 /* Expand a call EXP to sprintf. Return NULL_RTX if
5435 a normal call should be emitted rather than expanding the function
5436 inline. If convenient, the result should be placed in TARGET with
5437 mode MODE. */
5439 static rtx
5440 expand_builtin_sprintf (tree exp, rtx target, enum machine_mode mode)
5442 tree dest, fmt;
5443 const char *fmt_str;
5444 int nargs = call_expr_nargs (exp);
5446 /* Verify the required arguments in the original call. */
5447 if (nargs < 2)
5448 return NULL_RTX;
5449 dest = CALL_EXPR_ARG (exp, 0);
5450 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5451 return NULL_RTX;
5452 fmt = CALL_EXPR_ARG (exp, 0);
5453 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5454 return NULL_RTX;
5456 /* Check whether the format is a literal string constant. */
5457 fmt_str = c_getstr (fmt);
5458 if (fmt_str == NULL)
5459 return NULL_RTX;
5461 if (!init_target_chars ())
5462 return NULL_RTX;
5464 /* If the format doesn't contain % args or %%, use strcpy. */
5465 if (strchr (fmt_str, target_percent) == 0)
5467 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5468 tree exp;
5470 if ((nargs > 2) || ! fn)
5471 return NULL_RTX;
5472 expand_expr (build_call_expr (fn, 2, dest, fmt),
5473 const0_rtx, VOIDmode, EXPAND_NORMAL);
5474 if (target == const0_rtx)
5475 return const0_rtx;
5476 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5477 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5479 /* If the format is "%s", use strcpy if the result isn't used. */
5480 else if (strcmp (fmt_str, target_percent_s) == 0)
5482 tree fn, arg, len;
5483 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5485 if (! fn)
5486 return NULL_RTX;
5487 if (nargs != 3)
5488 return NULL_RTX;
5489 arg = CALL_EXPR_ARG (exp, 2);
5490 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5491 return NULL_RTX;
5493 if (target != const0_rtx)
5495 len = c_strlen (arg, 1);
5496 if (! len || TREE_CODE (len) != INTEGER_CST)
5497 return NULL_RTX;
5499 else
5500 len = NULL_TREE;
5502 expand_expr (build_call_expr (fn, 2, dest, arg),
5503 const0_rtx, VOIDmode, EXPAND_NORMAL);
5505 if (target == const0_rtx)
5506 return const0_rtx;
5507 return expand_expr (len, target, mode, EXPAND_NORMAL);
5510 return NULL_RTX;
5513 /* Expand a call to either the entry or exit function profiler. */
5515 static rtx
5516 expand_builtin_profile_func (bool exitp)
5518 rtx this, which;
5520 this = DECL_RTL (current_function_decl);
5521 gcc_assert (MEM_P (this));
5522 this = XEXP (this, 0);
5524 if (exitp)
5525 which = profile_function_exit_libfunc;
5526 else
5527 which = profile_function_entry_libfunc;
5529 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5530 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5532 Pmode);
5534 return const0_rtx;
5537 /* Expand a call to __builtin___clear_cache. */
5539 static rtx
5540 expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
5542 #ifndef HAVE_clear_cache
5543 #ifdef CLEAR_INSN_CACHE
5544 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5545 does something. Just do the default expansion to a call to
5546 __clear_cache(). */
5547 return NULL_RTX;
5548 #else
5549 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5550 does nothing. There is no need to call it. Do nothing. */
5551 return const0_rtx;
5552 #endif /* CLEAR_INSN_CACHE */
5553 #else
5554 /* We have a "clear_cache" insn, and it will handle everything. */
5555 tree begin, end;
5556 rtx begin_rtx, end_rtx;
5557 enum insn_code icode;
5559 /* We must not expand to a library call. If we did, any
5560 fallback library function in libgcc that might contain a call to
5561 __builtin___clear_cache() would recurse infinitely. */
5562 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5564 error ("both arguments to %<__builtin___clear_cache%> must be pointers");
5565 return const0_rtx;
5568 if (HAVE_clear_cache)
5570 icode = CODE_FOR_clear_cache;
5572 begin = CALL_EXPR_ARG (exp, 0);
5573 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
5574 begin_rtx = convert_memory_address (Pmode, begin_rtx);
5575 if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
5576 begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
5578 end = CALL_EXPR_ARG (exp, 1);
5579 end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
5580 end_rtx = convert_memory_address (Pmode, end_rtx);
5581 if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
5582 end_rtx = copy_to_mode_reg (Pmode, end_rtx);
5584 emit_insn (gen_clear_cache (begin_rtx, end_rtx));
5586 return const0_rtx;
5587 #endif /* HAVE_clear_cache */
5590 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5592 static rtx
5593 round_trampoline_addr (rtx tramp)
5595 rtx temp, addend, mask;
5597 /* If we don't need too much alignment, we'll have been guaranteed
5598 proper alignment by get_trampoline_type. */
5599 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5600 return tramp;
5602 /* Round address up to desired boundary. */
5603 temp = gen_reg_rtx (Pmode);
5604 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5605 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5607 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5608 temp, 0, OPTAB_LIB_WIDEN);
5609 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5610 temp, 0, OPTAB_LIB_WIDEN);
5612 return tramp;
5615 static rtx
5616 expand_builtin_init_trampoline (tree exp)
5618 tree t_tramp, t_func, t_chain;
5619 rtx r_tramp, r_func, r_chain;
5620 #ifdef TRAMPOLINE_TEMPLATE
5621 rtx blktramp;
5622 #endif
5624 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
5625 POINTER_TYPE, VOID_TYPE))
5626 return NULL_RTX;
5628 t_tramp = CALL_EXPR_ARG (exp, 0);
5629 t_func = CALL_EXPR_ARG (exp, 1);
5630 t_chain = CALL_EXPR_ARG (exp, 2);
5632 r_tramp = expand_normal (t_tramp);
5633 r_func = expand_normal (t_func);
5634 r_chain = expand_normal (t_chain);
5636 /* Generate insns to initialize the trampoline. */
5637 r_tramp = round_trampoline_addr (r_tramp);
5638 #ifdef TRAMPOLINE_TEMPLATE
5639 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5640 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5641 emit_block_move (blktramp, assemble_trampoline_template (),
5642 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5643 #endif
5644 trampolines_created = 1;
5645 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5647 return const0_rtx;
5650 static rtx
5651 expand_builtin_adjust_trampoline (tree exp)
5653 rtx tramp;
5655 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
5656 return NULL_RTX;
5658 tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
5659 tramp = round_trampoline_addr (tramp);
5660 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5661 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5662 #endif
5664 return tramp;
5667 /* Expand the call EXP to the built-in signbit, signbitf or signbitl
5668 function. The function first checks whether the back end provides
5669 an insn to implement signbit for the respective mode. If not, it
5670 checks whether the floating point format of the value is such that
5671 the sign bit can be extracted. If that is not the case, the
5672 function returns NULL_RTX to indicate that a normal call should be
5673 emitted rather than expanding the function in-line. EXP is the
5674 expression that is a call to the builtin function; if convenient,
5675 the result should be placed in TARGET. */
5676 static rtx
5677 expand_builtin_signbit (tree exp, rtx target)
5679 const struct real_format *fmt;
5680 enum machine_mode fmode, imode, rmode;
5681 HOST_WIDE_INT hi, lo;
5682 tree arg;
5683 int word, bitpos;
5684 enum insn_code icode;
5685 rtx temp;
5687 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5688 return NULL_RTX;
5690 arg = CALL_EXPR_ARG (exp, 0);
5691 fmode = TYPE_MODE (TREE_TYPE (arg));
5692 rmode = TYPE_MODE (TREE_TYPE (exp));
5693 fmt = REAL_MODE_FORMAT (fmode);
5695 arg = builtin_save_expr (arg);
5697 /* Expand the argument yielding a RTX expression. */
5698 temp = expand_normal (arg);
5700 /* Check if the back end provides an insn that handles signbit for the
5701 argument's mode. */
5702 icode = signbit_optab->handlers [(int) fmode].insn_code;
5703 if (icode != CODE_FOR_nothing)
5705 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
5706 emit_unop_insn (icode, target, temp, UNKNOWN);
5707 return target;
5710 /* For floating point formats without a sign bit, implement signbit
5711 as "ARG < 0.0". */
5712 bitpos = fmt->signbit_ro;
5713 if (bitpos < 0)
5715 /* But we can't do this if the format supports signed zero. */
5716 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5717 return NULL_RTX;
5719 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5720 build_real (TREE_TYPE (arg), dconst0));
5721 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5724 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5726 imode = int_mode_for_mode (fmode);
5727 if (imode == BLKmode)
5728 return NULL_RTX;
5729 temp = gen_lowpart (imode, temp);
5731 else
5733 imode = word_mode;
5734 /* Handle targets with different FP word orders. */
5735 if (FLOAT_WORDS_BIG_ENDIAN)
5736 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5737 else
5738 word = bitpos / BITS_PER_WORD;
5739 temp = operand_subword_force (temp, word, fmode);
5740 bitpos = bitpos % BITS_PER_WORD;
5743 /* Force the intermediate word_mode (or narrower) result into a
5744 register. This avoids attempting to create paradoxical SUBREGs
5745 of floating point modes below. */
5746 temp = force_reg (imode, temp);
5748 /* If the bitpos is within the "result mode" lowpart, the operation
5749 can be implement with a single bitwise AND. Otherwise, we need
5750 a right shift and an AND. */
5752 if (bitpos < GET_MODE_BITSIZE (rmode))
5754 if (bitpos < HOST_BITS_PER_WIDE_INT)
5756 hi = 0;
5757 lo = (HOST_WIDE_INT) 1 << bitpos;
5759 else
5761 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5762 lo = 0;
5765 if (imode != rmode)
5766 temp = gen_lowpart (rmode, temp);
5767 temp = expand_binop (rmode, and_optab, temp,
5768 immed_double_const (lo, hi, rmode),
5769 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5771 else
5773 /* Perform a logical right shift to place the signbit in the least
5774 significant bit, then truncate the result to the desired mode
5775 and mask just this bit. */
5776 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5777 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5778 temp = gen_lowpart (rmode, temp);
5779 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5780 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5783 return temp;
5786 /* Expand fork or exec calls. TARGET is the desired target of the
5787 call. EXP is the call. FN is the
5788 identificator of the actual function. IGNORE is nonzero if the
5789 value is to be ignored. */
5791 static rtx
5792 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
5794 tree id, decl;
5795 tree call;
5797 /* If we are not profiling, just call the function. */
5798 if (!profile_arc_flag)
5799 return NULL_RTX;
5801 /* Otherwise call the wrapper. This should be equivalent for the rest of
5802 compiler, so the code does not diverge, and the wrapper may run the
5803 code necessary for keeping the profiling sane. */
5805 switch (DECL_FUNCTION_CODE (fn))
5807 case BUILT_IN_FORK:
5808 id = get_identifier ("__gcov_fork");
5809 break;
5811 case BUILT_IN_EXECL:
5812 id = get_identifier ("__gcov_execl");
5813 break;
5815 case BUILT_IN_EXECV:
5816 id = get_identifier ("__gcov_execv");
5817 break;
5819 case BUILT_IN_EXECLP:
5820 id = get_identifier ("__gcov_execlp");
5821 break;
5823 case BUILT_IN_EXECLE:
5824 id = get_identifier ("__gcov_execle");
5825 break;
5827 case BUILT_IN_EXECVP:
5828 id = get_identifier ("__gcov_execvp");
5829 break;
5831 case BUILT_IN_EXECVE:
5832 id = get_identifier ("__gcov_execve");
5833 break;
5835 default:
5836 gcc_unreachable ();
5839 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5840 DECL_EXTERNAL (decl) = 1;
5841 TREE_PUBLIC (decl) = 1;
5842 DECL_ARTIFICIAL (decl) = 1;
5843 TREE_NOTHROW (decl) = 1;
5844 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5845 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5846 call = rewrite_call_expr (exp, 0, decl, 0);
5847 return expand_call (call, target, ignore);
5852 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5853 the pointer in these functions is void*, the tree optimizers may remove
5854 casts. The mode computed in expand_builtin isn't reliable either, due
5855 to __sync_bool_compare_and_swap.
5857 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5858 group of builtins. This gives us log2 of the mode size. */
5860 static inline enum machine_mode
5861 get_builtin_sync_mode (int fcode_diff)
5863 /* The size is not negotiable, so ask not to get BLKmode in return
5864 if the target indicates that a smaller size would be better. */
5865 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5868 /* Expand the memory expression LOC and return the appropriate memory operand
5869 for the builtin_sync operations. */
5871 static rtx
5872 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5874 rtx addr, mem;
5876 addr = expand_expr (loc, NULL_RTX, Pmode, EXPAND_SUM);
5878 /* Note that we explicitly do not want any alias information for this
5879 memory, so that we kill all other live memories. Otherwise we don't
5880 satisfy the full barrier semantics of the intrinsic. */
5881 mem = validize_mem (gen_rtx_MEM (mode, addr));
5883 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5884 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5885 MEM_VOLATILE_P (mem) = 1;
5887 return mem;
5890 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5891 EXP is the CALL_EXPR. CODE is the rtx code
5892 that corresponds to the arithmetic or logical operation from the name;
5893 an exception here is that NOT actually means NAND. TARGET is an optional
5894 place for us to store the results; AFTER is true if this is the
5895 fetch_and_xxx form. IGNORE is true if we don't actually care about
5896 the result of the operation at all. */
5898 static rtx
5899 expand_builtin_sync_operation (enum machine_mode mode, tree exp,
5900 enum rtx_code code, bool after,
5901 rtx target, bool ignore)
5903 rtx val, mem;
5904 enum machine_mode old_mode;
5906 /* Expand the operands. */
5907 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5909 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
5910 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5911 of CONST_INTs, where we know the old_mode only from the call argument. */
5912 old_mode = GET_MODE (val);
5913 if (old_mode == VOIDmode)
5914 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5915 val = convert_modes (mode, old_mode, val, 1);
5917 if (ignore)
5918 return expand_sync_operation (mem, val, code);
5919 else
5920 return expand_sync_fetch_operation (mem, val, code, after, target);
5923 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5924 intrinsics. EXP is the CALL_EXPR. IS_BOOL is
5925 true if this is the boolean form. TARGET is a place for us to store the
5926 results; this is NOT optional if IS_BOOL is true. */
5928 static rtx
5929 expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
5930 bool is_bool, rtx target)
5932 rtx old_val, new_val, mem;
5933 enum machine_mode old_mode;
5935 /* Expand the operands. */
5936 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5939 old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
5940 mode, EXPAND_NORMAL);
5941 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5942 of CONST_INTs, where we know the old_mode only from the call argument. */
5943 old_mode = GET_MODE (old_val);
5944 if (old_mode == VOIDmode)
5945 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5946 old_val = convert_modes (mode, old_mode, old_val, 1);
5948 new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
5949 mode, EXPAND_NORMAL);
5950 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5951 of CONST_INTs, where we know the old_mode only from the call argument. */
5952 old_mode = GET_MODE (new_val);
5953 if (old_mode == VOIDmode)
5954 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
5955 new_val = convert_modes (mode, old_mode, new_val, 1);
5957 if (is_bool)
5958 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5959 else
5960 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5963 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5964 general form is actually an atomic exchange, and some targets only
5965 support a reduced form with the second argument being a constant 1.
5966 EXP is the CALL_EXPR; TARGET is an optional place for us to store
5967 the results. */
5969 static rtx
5970 expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
5971 rtx target)
5973 rtx val, mem;
5974 enum machine_mode old_mode;
5976 /* Expand the operands. */
5977 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5978 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
5979 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5980 of CONST_INTs, where we know the old_mode only from the call argument. */
5981 old_mode = GET_MODE (val);
5982 if (old_mode == VOIDmode)
5983 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5984 val = convert_modes (mode, old_mode, val, 1);
5986 return expand_sync_lock_test_and_set (mem, val, target);
5989 /* Expand the __sync_synchronize intrinsic. */
5991 static void
5992 expand_builtin_synchronize (void)
5994 tree x;
5996 #ifdef HAVE_memory_barrier
5997 if (HAVE_memory_barrier)
5999 emit_insn (gen_memory_barrier ());
6000 return;
6002 #endif
6004 /* If no explicit memory barrier instruction is available, create an
6005 empty asm stmt with a memory clobber. */
6006 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
6007 tree_cons (NULL, build_string (6, "memory"), NULL));
6008 ASM_VOLATILE_P (x) = 1;
6009 expand_asm_expr (x);
6012 /* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
6014 static void
6015 expand_builtin_lock_release (enum machine_mode mode, tree exp)
6017 enum insn_code icode;
6018 rtx mem, insn;
6019 rtx val = const0_rtx;
6021 /* Expand the operands. */
6022 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
6024 /* If there is an explicit operation in the md file, use it. */
6025 icode = sync_lock_release[mode];
6026 if (icode != CODE_FOR_nothing)
6028 if (!insn_data[icode].operand[1].predicate (val, mode))
6029 val = force_reg (mode, val);
6031 insn = GEN_FCN (icode) (mem, val);
6032 if (insn)
6034 emit_insn (insn);
6035 return;
6039 /* Otherwise we can implement this operation by emitting a barrier
6040 followed by a store of zero. */
6041 expand_builtin_synchronize ();
6042 emit_move_insn (mem, val);
6045 /* Expand an expression EXP that calls a built-in function,
6046 with result going to TARGET if that's convenient
6047 (and in mode MODE if that's convenient).
6048 SUBTARGET may be used as the target for computing one of EXP's operands.
6049 IGNORE is nonzero if the value is to be ignored. */
6052 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
6053 int ignore)
6055 tree fndecl = get_callee_fndecl (exp);
6056 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6057 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
6059 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6060 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
6062 /* When not optimizing, generate calls to library functions for a certain
6063 set of builtins. */
6064 if (!optimize
6065 && !called_as_built_in (fndecl)
6066 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
6067 && fcode != BUILT_IN_ALLOCA)
6068 return expand_call (exp, target, ignore);
6070 /* The built-in function expanders test for target == const0_rtx
6071 to determine whether the function's result will be ignored. */
6072 if (ignore)
6073 target = const0_rtx;
6075 /* If the result of a pure or const built-in function is ignored, and
6076 none of its arguments are volatile, we can avoid expanding the
6077 built-in call and just evaluate the arguments for side-effects. */
6078 if (target == const0_rtx
6079 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
6081 bool volatilep = false;
6082 tree arg;
6083 call_expr_arg_iterator iter;
6085 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6086 if (TREE_THIS_VOLATILE (arg))
6088 volatilep = true;
6089 break;
6092 if (! volatilep)
6094 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6095 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
6096 return const0_rtx;
6100 switch (fcode)
6102 CASE_FLT_FN (BUILT_IN_FABS):
6103 target = expand_builtin_fabs (exp, target, subtarget);
6104 if (target)
6105 return target;
6106 break;
6108 CASE_FLT_FN (BUILT_IN_COPYSIGN):
6109 target = expand_builtin_copysign (exp, target, subtarget);
6110 if (target)
6111 return target;
6112 break;
6114 /* Just do a normal library call if we were unable to fold
6115 the values. */
6116 CASE_FLT_FN (BUILT_IN_CABS):
6117 break;
6119 CASE_FLT_FN (BUILT_IN_EXP):
6120 CASE_FLT_FN (BUILT_IN_EXP10):
6121 CASE_FLT_FN (BUILT_IN_POW10):
6122 CASE_FLT_FN (BUILT_IN_EXP2):
6123 CASE_FLT_FN (BUILT_IN_EXPM1):
6124 CASE_FLT_FN (BUILT_IN_LOGB):
6125 CASE_FLT_FN (BUILT_IN_LOG):
6126 CASE_FLT_FN (BUILT_IN_LOG10):
6127 CASE_FLT_FN (BUILT_IN_LOG2):
6128 CASE_FLT_FN (BUILT_IN_LOG1P):
6129 CASE_FLT_FN (BUILT_IN_TAN):
6130 CASE_FLT_FN (BUILT_IN_ASIN):
6131 CASE_FLT_FN (BUILT_IN_ACOS):
6132 CASE_FLT_FN (BUILT_IN_ATAN):
6133 /* Treat these like sqrt only if unsafe math optimizations are allowed,
6134 because of possible accuracy problems. */
6135 if (! flag_unsafe_math_optimizations)
6136 break;
6137 CASE_FLT_FN (BUILT_IN_SQRT):
6138 CASE_FLT_FN (BUILT_IN_FLOOR):
6139 CASE_FLT_FN (BUILT_IN_CEIL):
6140 CASE_FLT_FN (BUILT_IN_TRUNC):
6141 CASE_FLT_FN (BUILT_IN_ROUND):
6142 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6143 CASE_FLT_FN (BUILT_IN_RINT):
6144 target = expand_builtin_mathfn (exp, target, subtarget);
6145 if (target)
6146 return target;
6147 break;
6149 CASE_FLT_FN (BUILT_IN_ILOGB):
6150 if (! flag_unsafe_math_optimizations)
6151 break;
6152 CASE_FLT_FN (BUILT_IN_ISINF):
6153 CASE_FLT_FN (BUILT_IN_FINITE):
6154 case BUILT_IN_ISFINITE:
6155 case BUILT_IN_ISNORMAL:
6156 target = expand_builtin_interclass_mathfn (exp, target, subtarget);
6157 if (target)
6158 return target;
6159 break;
6161 CASE_FLT_FN (BUILT_IN_LCEIL):
6162 CASE_FLT_FN (BUILT_IN_LLCEIL):
6163 CASE_FLT_FN (BUILT_IN_LFLOOR):
6164 CASE_FLT_FN (BUILT_IN_LLFLOOR):
6165 target = expand_builtin_int_roundingfn (exp, target, subtarget);
6166 if (target)
6167 return target;
6168 break;
6170 CASE_FLT_FN (BUILT_IN_LRINT):
6171 CASE_FLT_FN (BUILT_IN_LLRINT):
6172 CASE_FLT_FN (BUILT_IN_LROUND):
6173 CASE_FLT_FN (BUILT_IN_LLROUND):
6174 target = expand_builtin_int_roundingfn_2 (exp, target, subtarget);
6175 if (target)
6176 return target;
6177 break;
6179 CASE_FLT_FN (BUILT_IN_POW):
6180 target = expand_builtin_pow (exp, target, subtarget);
6181 if (target)
6182 return target;
6183 break;
6185 CASE_FLT_FN (BUILT_IN_POWI):
6186 target = expand_builtin_powi (exp, target, subtarget);
6187 if (target)
6188 return target;
6189 break;
6191 CASE_FLT_FN (BUILT_IN_ATAN2):
6192 CASE_FLT_FN (BUILT_IN_LDEXP):
6193 CASE_FLT_FN (BUILT_IN_SCALB):
6194 CASE_FLT_FN (BUILT_IN_SCALBN):
6195 CASE_FLT_FN (BUILT_IN_SCALBLN):
6196 if (! flag_unsafe_math_optimizations)
6197 break;
6199 CASE_FLT_FN (BUILT_IN_FMOD):
6200 CASE_FLT_FN (BUILT_IN_REMAINDER):
6201 CASE_FLT_FN (BUILT_IN_DREM):
6202 target = expand_builtin_mathfn_2 (exp, target, subtarget);
6203 if (target)
6204 return target;
6205 break;
6207 CASE_FLT_FN (BUILT_IN_CEXPI):
6208 target = expand_builtin_cexpi (exp, target, subtarget);
6209 gcc_assert (target);
6210 return target;
6212 CASE_FLT_FN (BUILT_IN_SIN):
6213 CASE_FLT_FN (BUILT_IN_COS):
6214 if (! flag_unsafe_math_optimizations)
6215 break;
6216 target = expand_builtin_mathfn_3 (exp, target, subtarget);
6217 if (target)
6218 return target;
6219 break;
6221 CASE_FLT_FN (BUILT_IN_SINCOS):
6222 if (! flag_unsafe_math_optimizations)
6223 break;
6224 target = expand_builtin_sincos (exp);
6225 if (target)
6226 return target;
6227 break;
6229 case BUILT_IN_APPLY_ARGS:
6230 return expand_builtin_apply_args ();
6232 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6233 FUNCTION with a copy of the parameters described by
6234 ARGUMENTS, and ARGSIZE. It returns a block of memory
6235 allocated on the stack into which is stored all the registers
6236 that might possibly be used for returning the result of a
6237 function. ARGUMENTS is the value returned by
6238 __builtin_apply_args. ARGSIZE is the number of bytes of
6239 arguments that must be copied. ??? How should this value be
6240 computed? We'll also need a safe worst case value for varargs
6241 functions. */
6242 case BUILT_IN_APPLY:
6243 if (!validate_arglist (exp, POINTER_TYPE,
6244 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
6245 && !validate_arglist (exp, REFERENCE_TYPE,
6246 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6247 return const0_rtx;
6248 else
6250 rtx ops[3];
6252 ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6253 ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6254 ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
6256 return expand_builtin_apply (ops[0], ops[1], ops[2]);
6259 /* __builtin_return (RESULT) causes the function to return the
6260 value described by RESULT. RESULT is address of the block of
6261 memory returned by __builtin_apply. */
6262 case BUILT_IN_RETURN:
6263 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6264 expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
6265 return const0_rtx;
6267 case BUILT_IN_SAVEREGS:
6268 return expand_builtin_saveregs ();
6270 case BUILT_IN_ARGS_INFO:
6271 return expand_builtin_args_info (exp);
6273 case BUILT_IN_VA_ARG_PACK:
6274 /* All valid uses of __builtin_va_arg_pack () are removed during
6275 inlining. */
6276 error ("invalid use of %<__builtin_va_arg_pack ()%>");
6277 return const0_rtx;
6279 /* Return the address of the first anonymous stack arg. */
6280 case BUILT_IN_NEXT_ARG:
6281 if (fold_builtin_next_arg (exp, false))
6282 return const0_rtx;
6283 return expand_builtin_next_arg ();
6285 case BUILT_IN_CLEAR_CACHE:
6286 target = expand_builtin___clear_cache (exp);
6287 if (target)
6288 return target;
6289 break;
6291 case BUILT_IN_CLASSIFY_TYPE:
6292 return expand_builtin_classify_type (exp);
6294 case BUILT_IN_CONSTANT_P:
6295 return const0_rtx;
6297 case BUILT_IN_FRAME_ADDRESS:
6298 case BUILT_IN_RETURN_ADDRESS:
6299 return expand_builtin_frame_address (fndecl, exp);
6301 /* Returns the address of the area where the structure is returned.
6302 0 otherwise. */
6303 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
6304 if (call_expr_nargs (exp) != 0
6305 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
6306 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
6307 return const0_rtx;
6308 else
6309 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
6311 case BUILT_IN_ALLOCA:
6312 target = expand_builtin_alloca (exp, target);
6313 if (target)
6314 return target;
6315 break;
6317 case BUILT_IN_STACK_SAVE:
6318 return expand_stack_save ();
6320 case BUILT_IN_STACK_RESTORE:
6321 expand_stack_restore (CALL_EXPR_ARG (exp, 0));
6322 return const0_rtx;
6324 case BUILT_IN_BSWAP32:
6325 case BUILT_IN_BSWAP64:
6326 target = expand_builtin_bswap (exp, target, subtarget);
6328 if (target)
6329 return target;
6330 break;
6332 CASE_INT_FN (BUILT_IN_FFS):
6333 case BUILT_IN_FFSIMAX:
6334 target = expand_builtin_unop (target_mode, exp, target,
6335 subtarget, ffs_optab);
6336 if (target)
6337 return target;
6338 break;
6340 CASE_INT_FN (BUILT_IN_CLZ):
6341 case BUILT_IN_CLZIMAX:
6342 target = expand_builtin_unop (target_mode, exp, target,
6343 subtarget, clz_optab);
6344 if (target)
6345 return target;
6346 break;
6348 CASE_INT_FN (BUILT_IN_CTZ):
6349 case BUILT_IN_CTZIMAX:
6350 target = expand_builtin_unop (target_mode, exp, target,
6351 subtarget, ctz_optab);
6352 if (target)
6353 return target;
6354 break;
6356 CASE_INT_FN (BUILT_IN_POPCOUNT):
6357 case BUILT_IN_POPCOUNTIMAX:
6358 target = expand_builtin_unop (target_mode, exp, target,
6359 subtarget, popcount_optab);
6360 if (target)
6361 return target;
6362 break;
6364 CASE_INT_FN (BUILT_IN_PARITY):
6365 case BUILT_IN_PARITYIMAX:
6366 target = expand_builtin_unop (target_mode, exp, target,
6367 subtarget, parity_optab);
6368 if (target)
6369 return target;
6370 break;
6372 case BUILT_IN_STRLEN:
6373 target = expand_builtin_strlen (exp, target, target_mode);
6374 if (target)
6375 return target;
6376 break;
6378 case BUILT_IN_STRCPY:
6379 target = expand_builtin_strcpy (fndecl, exp, target, mode);
6380 if (target)
6381 return target;
6382 break;
6384 case BUILT_IN_STRNCPY:
6385 target = expand_builtin_strncpy (exp, target, mode);
6386 if (target)
6387 return target;
6388 break;
6390 case BUILT_IN_STPCPY:
6391 target = expand_builtin_stpcpy (exp, target, mode);
6392 if (target)
6393 return target;
6394 break;
6396 case BUILT_IN_STRCAT:
6397 target = expand_builtin_strcat (fndecl, exp, target, mode);
6398 if (target)
6399 return target;
6400 break;
6402 case BUILT_IN_STRNCAT:
6403 target = expand_builtin_strncat (exp, target, mode);
6404 if (target)
6405 return target;
6406 break;
6408 case BUILT_IN_STRSPN:
6409 target = expand_builtin_strspn (exp, target, mode);
6410 if (target)
6411 return target;
6412 break;
6414 case BUILT_IN_STRCSPN:
6415 target = expand_builtin_strcspn (exp, target, mode);
6416 if (target)
6417 return target;
6418 break;
6420 case BUILT_IN_STRSTR:
6421 target = expand_builtin_strstr (exp, target, mode);
6422 if (target)
6423 return target;
6424 break;
6426 case BUILT_IN_STRPBRK:
6427 target = expand_builtin_strpbrk (exp, target, mode);
6428 if (target)
6429 return target;
6430 break;
6432 case BUILT_IN_INDEX:
6433 case BUILT_IN_STRCHR:
6434 target = expand_builtin_strchr (exp, target, mode);
6435 if (target)
6436 return target;
6437 break;
6439 case BUILT_IN_RINDEX:
6440 case BUILT_IN_STRRCHR:
6441 target = expand_builtin_strrchr (exp, target, mode);
6442 if (target)
6443 return target;
6444 break;
6446 case BUILT_IN_MEMCPY:
6447 target = expand_builtin_memcpy (exp, target, mode);
6448 if (target)
6449 return target;
6450 break;
6452 case BUILT_IN_MEMPCPY:
6453 target = expand_builtin_mempcpy (exp, target, mode);
6454 if (target)
6455 return target;
6456 break;
6458 case BUILT_IN_MEMMOVE:
6459 target = expand_builtin_memmove (exp, target, mode, ignore);
6460 if (target)
6461 return target;
6462 break;
6464 case BUILT_IN_BCOPY:
6465 target = expand_builtin_bcopy (exp, ignore);
6466 if (target)
6467 return target;
6468 break;
6470 case BUILT_IN_MEMSET:
6471 target = expand_builtin_memset (exp, target, mode);
6472 if (target)
6473 return target;
6474 break;
6476 case BUILT_IN_BZERO:
6477 target = expand_builtin_bzero (exp);
6478 if (target)
6479 return target;
6480 break;
6482 case BUILT_IN_STRCMP:
6483 target = expand_builtin_strcmp (exp, target, mode);
6484 if (target)
6485 return target;
6486 break;
6488 case BUILT_IN_STRNCMP:
6489 target = expand_builtin_strncmp (exp, target, mode);
6490 if (target)
6491 return target;
6492 break;
6494 case BUILT_IN_MEMCHR:
6495 target = expand_builtin_memchr (exp, target, mode);
6496 if (target)
6497 return target;
6498 break;
6500 case BUILT_IN_BCMP:
6501 case BUILT_IN_MEMCMP:
6502 target = expand_builtin_memcmp (exp, target, mode);
6503 if (target)
6504 return target;
6505 break;
6507 case BUILT_IN_SETJMP:
6508 /* This should have been lowered to the builtins below. */
6509 gcc_unreachable ();
6511 case BUILT_IN_SETJMP_SETUP:
6512 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6513 and the receiver label. */
6514 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6516 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6517 VOIDmode, EXPAND_NORMAL);
6518 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
6519 rtx label_r = label_rtx (label);
6521 /* This is copied from the handling of non-local gotos. */
6522 expand_builtin_setjmp_setup (buf_addr, label_r);
6523 nonlocal_goto_handler_labels
6524 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6525 nonlocal_goto_handler_labels);
6526 /* ??? Do not let expand_label treat us as such since we would
6527 not want to be both on the list of non-local labels and on
6528 the list of forced labels. */
6529 FORCED_LABEL (label) = 0;
6530 return const0_rtx;
6532 break;
6534 case BUILT_IN_SETJMP_DISPATCHER:
6535 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6536 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6538 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6539 rtx label_r = label_rtx (label);
6541 /* Remove the dispatcher label from the list of non-local labels
6542 since the receiver labels have been added to it above. */
6543 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6544 return const0_rtx;
6546 break;
6548 case BUILT_IN_SETJMP_RECEIVER:
6549 /* __builtin_setjmp_receiver is passed the receiver label. */
6550 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6552 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6553 rtx label_r = label_rtx (label);
6555 expand_builtin_setjmp_receiver (label_r);
6556 return const0_rtx;
6558 break;
6560 /* __builtin_longjmp is passed a pointer to an array of five words.
6561 It's similar to the C library longjmp function but works with
6562 __builtin_setjmp above. */
6563 case BUILT_IN_LONGJMP:
6564 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6566 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6567 VOIDmode, EXPAND_NORMAL);
6568 rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
6570 if (value != const1_rtx)
6572 error ("%<__builtin_longjmp%> second argument must be 1");
6573 return const0_rtx;
6576 expand_builtin_longjmp (buf_addr, value);
6577 return const0_rtx;
6579 break;
6581 case BUILT_IN_NONLOCAL_GOTO:
6582 target = expand_builtin_nonlocal_goto (exp);
6583 if (target)
6584 return target;
6585 break;
6587 /* This updates the setjmp buffer that is its argument with the value
6588 of the current stack pointer. */
6589 case BUILT_IN_UPDATE_SETJMP_BUF:
6590 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6592 rtx buf_addr
6593 = expand_normal (CALL_EXPR_ARG (exp, 0));
6595 expand_builtin_update_setjmp_buf (buf_addr);
6596 return const0_rtx;
6598 break;
6600 case BUILT_IN_TRAP:
6601 expand_builtin_trap ();
6602 return const0_rtx;
6604 case BUILT_IN_PRINTF:
6605 target = expand_builtin_printf (exp, target, mode, false);
6606 if (target)
6607 return target;
6608 break;
6610 case BUILT_IN_PRINTF_UNLOCKED:
6611 target = expand_builtin_printf (exp, target, mode, true);
6612 if (target)
6613 return target;
6614 break;
6616 case BUILT_IN_FPUTS:
6617 target = expand_builtin_fputs (exp, target, false);
6618 if (target)
6619 return target;
6620 break;
6621 case BUILT_IN_FPUTS_UNLOCKED:
6622 target = expand_builtin_fputs (exp, target, true);
6623 if (target)
6624 return target;
6625 break;
6627 case BUILT_IN_FPRINTF:
6628 target = expand_builtin_fprintf (exp, target, mode, false);
6629 if (target)
6630 return target;
6631 break;
6633 case BUILT_IN_FPRINTF_UNLOCKED:
6634 target = expand_builtin_fprintf (exp, target, mode, true);
6635 if (target)
6636 return target;
6637 break;
6639 case BUILT_IN_SPRINTF:
6640 target = expand_builtin_sprintf (exp, target, mode);
6641 if (target)
6642 return target;
6643 break;
6645 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6646 case BUILT_IN_SIGNBITD32:
6647 case BUILT_IN_SIGNBITD64:
6648 case BUILT_IN_SIGNBITD128:
6649 target = expand_builtin_signbit (exp, target);
6650 if (target)
6651 return target;
6652 break;
6654 /* Various hooks for the DWARF 2 __throw routine. */
6655 case BUILT_IN_UNWIND_INIT:
6656 expand_builtin_unwind_init ();
6657 return const0_rtx;
6658 case BUILT_IN_DWARF_CFA:
6659 return virtual_cfa_rtx;
6660 #ifdef DWARF2_UNWIND_INFO
6661 case BUILT_IN_DWARF_SP_COLUMN:
6662 return expand_builtin_dwarf_sp_column ();
6663 case BUILT_IN_INIT_DWARF_REG_SIZES:
6664 expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
6665 return const0_rtx;
6666 #endif
6667 case BUILT_IN_FROB_RETURN_ADDR:
6668 return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
6669 case BUILT_IN_EXTRACT_RETURN_ADDR:
6670 return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
6671 case BUILT_IN_EH_RETURN:
6672 expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6673 CALL_EXPR_ARG (exp, 1));
6674 return const0_rtx;
6675 #ifdef EH_RETURN_DATA_REGNO
6676 case BUILT_IN_EH_RETURN_DATA_REGNO:
6677 return expand_builtin_eh_return_data_regno (exp);
6678 #endif
6679 case BUILT_IN_EXTEND_POINTER:
6680 return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
6682 case BUILT_IN_VA_START:
6683 case BUILT_IN_STDARG_START:
6684 return expand_builtin_va_start (exp);
6685 case BUILT_IN_VA_END:
6686 return expand_builtin_va_end (exp);
6687 case BUILT_IN_VA_COPY:
6688 return expand_builtin_va_copy (exp);
6689 case BUILT_IN_EXPECT:
6690 return expand_builtin_expect (exp, target);
6691 case BUILT_IN_PREFETCH:
6692 expand_builtin_prefetch (exp);
6693 return const0_rtx;
6695 case BUILT_IN_PROFILE_FUNC_ENTER:
6696 return expand_builtin_profile_func (false);
6697 case BUILT_IN_PROFILE_FUNC_EXIT:
6698 return expand_builtin_profile_func (true);
6700 case BUILT_IN_INIT_TRAMPOLINE:
6701 return expand_builtin_init_trampoline (exp);
6702 case BUILT_IN_ADJUST_TRAMPOLINE:
6703 return expand_builtin_adjust_trampoline (exp);
6705 case BUILT_IN_FORK:
6706 case BUILT_IN_EXECL:
6707 case BUILT_IN_EXECV:
6708 case BUILT_IN_EXECLP:
6709 case BUILT_IN_EXECLE:
6710 case BUILT_IN_EXECVP:
6711 case BUILT_IN_EXECVE:
6712 target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
6713 if (target)
6714 return target;
6715 break;
6717 case BUILT_IN_FETCH_AND_ADD_1:
6718 case BUILT_IN_FETCH_AND_ADD_2:
6719 case BUILT_IN_FETCH_AND_ADD_4:
6720 case BUILT_IN_FETCH_AND_ADD_8:
6721 case BUILT_IN_FETCH_AND_ADD_16:
6722 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6723 target = expand_builtin_sync_operation (mode, exp, PLUS,
6724 false, target, ignore);
6725 if (target)
6726 return target;
6727 break;
6729 case BUILT_IN_FETCH_AND_SUB_1:
6730 case BUILT_IN_FETCH_AND_SUB_2:
6731 case BUILT_IN_FETCH_AND_SUB_4:
6732 case BUILT_IN_FETCH_AND_SUB_8:
6733 case BUILT_IN_FETCH_AND_SUB_16:
6734 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6735 target = expand_builtin_sync_operation (mode, exp, MINUS,
6736 false, target, ignore);
6737 if (target)
6738 return target;
6739 break;
6741 case BUILT_IN_FETCH_AND_OR_1:
6742 case BUILT_IN_FETCH_AND_OR_2:
6743 case BUILT_IN_FETCH_AND_OR_4:
6744 case BUILT_IN_FETCH_AND_OR_8:
6745 case BUILT_IN_FETCH_AND_OR_16:
6746 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6747 target = expand_builtin_sync_operation (mode, exp, IOR,
6748 false, target, ignore);
6749 if (target)
6750 return target;
6751 break;
6753 case BUILT_IN_FETCH_AND_AND_1:
6754 case BUILT_IN_FETCH_AND_AND_2:
6755 case BUILT_IN_FETCH_AND_AND_4:
6756 case BUILT_IN_FETCH_AND_AND_8:
6757 case BUILT_IN_FETCH_AND_AND_16:
6758 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6759 target = expand_builtin_sync_operation (mode, exp, AND,
6760 false, target, ignore);
6761 if (target)
6762 return target;
6763 break;
6765 case BUILT_IN_FETCH_AND_XOR_1:
6766 case BUILT_IN_FETCH_AND_XOR_2:
6767 case BUILT_IN_FETCH_AND_XOR_4:
6768 case BUILT_IN_FETCH_AND_XOR_8:
6769 case BUILT_IN_FETCH_AND_XOR_16:
6770 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6771 target = expand_builtin_sync_operation (mode, exp, XOR,
6772 false, target, ignore);
6773 if (target)
6774 return target;
6775 break;
6777 case BUILT_IN_FETCH_AND_NAND_1:
6778 case BUILT_IN_FETCH_AND_NAND_2:
6779 case BUILT_IN_FETCH_AND_NAND_4:
6780 case BUILT_IN_FETCH_AND_NAND_8:
6781 case BUILT_IN_FETCH_AND_NAND_16:
6782 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6783 target = expand_builtin_sync_operation (mode, exp, NOT,
6784 false, target, ignore);
6785 if (target)
6786 return target;
6787 break;
6789 case BUILT_IN_ADD_AND_FETCH_1:
6790 case BUILT_IN_ADD_AND_FETCH_2:
6791 case BUILT_IN_ADD_AND_FETCH_4:
6792 case BUILT_IN_ADD_AND_FETCH_8:
6793 case BUILT_IN_ADD_AND_FETCH_16:
6794 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6795 target = expand_builtin_sync_operation (mode, exp, PLUS,
6796 true, target, ignore);
6797 if (target)
6798 return target;
6799 break;
6801 case BUILT_IN_SUB_AND_FETCH_1:
6802 case BUILT_IN_SUB_AND_FETCH_2:
6803 case BUILT_IN_SUB_AND_FETCH_4:
6804 case BUILT_IN_SUB_AND_FETCH_8:
6805 case BUILT_IN_SUB_AND_FETCH_16:
6806 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6807 target = expand_builtin_sync_operation (mode, exp, MINUS,
6808 true, target, ignore);
6809 if (target)
6810 return target;
6811 break;
6813 case BUILT_IN_OR_AND_FETCH_1:
6814 case BUILT_IN_OR_AND_FETCH_2:
6815 case BUILT_IN_OR_AND_FETCH_4:
6816 case BUILT_IN_OR_AND_FETCH_8:
6817 case BUILT_IN_OR_AND_FETCH_16:
6818 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6819 target = expand_builtin_sync_operation (mode, exp, IOR,
6820 true, target, ignore);
6821 if (target)
6822 return target;
6823 break;
6825 case BUILT_IN_AND_AND_FETCH_1:
6826 case BUILT_IN_AND_AND_FETCH_2:
6827 case BUILT_IN_AND_AND_FETCH_4:
6828 case BUILT_IN_AND_AND_FETCH_8:
6829 case BUILT_IN_AND_AND_FETCH_16:
6830 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6831 target = expand_builtin_sync_operation (mode, exp, AND,
6832 true, target, ignore);
6833 if (target)
6834 return target;
6835 break;
6837 case BUILT_IN_XOR_AND_FETCH_1:
6838 case BUILT_IN_XOR_AND_FETCH_2:
6839 case BUILT_IN_XOR_AND_FETCH_4:
6840 case BUILT_IN_XOR_AND_FETCH_8:
6841 case BUILT_IN_XOR_AND_FETCH_16:
6842 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6843 target = expand_builtin_sync_operation (mode, exp, XOR,
6844 true, target, ignore);
6845 if (target)
6846 return target;
6847 break;
6849 case BUILT_IN_NAND_AND_FETCH_1:
6850 case BUILT_IN_NAND_AND_FETCH_2:
6851 case BUILT_IN_NAND_AND_FETCH_4:
6852 case BUILT_IN_NAND_AND_FETCH_8:
6853 case BUILT_IN_NAND_AND_FETCH_16:
6854 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6855 target = expand_builtin_sync_operation (mode, exp, NOT,
6856 true, target, ignore);
6857 if (target)
6858 return target;
6859 break;
6861 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6862 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6863 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6864 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6865 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6866 if (mode == VOIDmode)
6867 mode = TYPE_MODE (boolean_type_node);
6868 if (!target || !register_operand (target, mode))
6869 target = gen_reg_rtx (mode);
6871 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6872 target = expand_builtin_compare_and_swap (mode, exp, true, target);
6873 if (target)
6874 return target;
6875 break;
6877 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6878 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6879 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6880 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6881 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6882 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6883 target = expand_builtin_compare_and_swap (mode, exp, false, target);
6884 if (target)
6885 return target;
6886 break;
6888 case BUILT_IN_LOCK_TEST_AND_SET_1:
6889 case BUILT_IN_LOCK_TEST_AND_SET_2:
6890 case BUILT_IN_LOCK_TEST_AND_SET_4:
6891 case BUILT_IN_LOCK_TEST_AND_SET_8:
6892 case BUILT_IN_LOCK_TEST_AND_SET_16:
6893 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6894 target = expand_builtin_lock_test_and_set (mode, exp, target);
6895 if (target)
6896 return target;
6897 break;
6899 case BUILT_IN_LOCK_RELEASE_1:
6900 case BUILT_IN_LOCK_RELEASE_2:
6901 case BUILT_IN_LOCK_RELEASE_4:
6902 case BUILT_IN_LOCK_RELEASE_8:
6903 case BUILT_IN_LOCK_RELEASE_16:
6904 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6905 expand_builtin_lock_release (mode, exp);
6906 return const0_rtx;
6908 case BUILT_IN_SYNCHRONIZE:
6909 expand_builtin_synchronize ();
6910 return const0_rtx;
6912 case BUILT_IN_OBJECT_SIZE:
6913 return expand_builtin_object_size (exp);
6915 case BUILT_IN_MEMCPY_CHK:
6916 case BUILT_IN_MEMPCPY_CHK:
6917 case BUILT_IN_MEMMOVE_CHK:
6918 case BUILT_IN_MEMSET_CHK:
6919 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6920 if (target)
6921 return target;
6922 break;
6924 case BUILT_IN_STRCPY_CHK:
6925 case BUILT_IN_STPCPY_CHK:
6926 case BUILT_IN_STRNCPY_CHK:
6927 case BUILT_IN_STRCAT_CHK:
6928 case BUILT_IN_STRNCAT_CHK:
6929 case BUILT_IN_SNPRINTF_CHK:
6930 case BUILT_IN_VSNPRINTF_CHK:
6931 maybe_emit_chk_warning (exp, fcode);
6932 break;
6934 case BUILT_IN_SPRINTF_CHK:
6935 case BUILT_IN_VSPRINTF_CHK:
6936 maybe_emit_sprintf_chk_warning (exp, fcode);
6937 break;
6939 default: /* just do library call, if unknown builtin */
6940 break;
6943 /* The switch statement above can drop through to cause the function
6944 to be called normally. */
6945 return expand_call (exp, target, ignore);
6948 /* Determine whether a tree node represents a call to a built-in
6949 function. If the tree T is a call to a built-in function with
6950 the right number of arguments of the appropriate types, return
6951 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6952 Otherwise the return value is END_BUILTINS. */
6954 enum built_in_function
6955 builtin_mathfn_code (const_tree t)
6957 const_tree fndecl, arg, parmlist;
6958 const_tree argtype, parmtype;
6959 const_call_expr_arg_iterator iter;
6961 if (TREE_CODE (t) != CALL_EXPR
6962 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
6963 return END_BUILTINS;
6965 fndecl = get_callee_fndecl (t);
6966 if (fndecl == NULL_TREE
6967 || TREE_CODE (fndecl) != FUNCTION_DECL
6968 || ! DECL_BUILT_IN (fndecl)
6969 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6970 return END_BUILTINS;
6972 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6973 init_const_call_expr_arg_iterator (t, &iter);
6974 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6976 /* If a function doesn't take a variable number of arguments,
6977 the last element in the list will have type `void'. */
6978 parmtype = TREE_VALUE (parmlist);
6979 if (VOID_TYPE_P (parmtype))
6981 if (more_const_call_expr_args_p (&iter))
6982 return END_BUILTINS;
6983 return DECL_FUNCTION_CODE (fndecl);
6986 if (! more_const_call_expr_args_p (&iter))
6987 return END_BUILTINS;
6989 arg = next_const_call_expr_arg (&iter);
6990 argtype = TREE_TYPE (arg);
6992 if (SCALAR_FLOAT_TYPE_P (parmtype))
6994 if (! SCALAR_FLOAT_TYPE_P (argtype))
6995 return END_BUILTINS;
6997 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6999 if (! COMPLEX_FLOAT_TYPE_P (argtype))
7000 return END_BUILTINS;
7002 else if (POINTER_TYPE_P (parmtype))
7004 if (! POINTER_TYPE_P (argtype))
7005 return END_BUILTINS;
7007 else if (INTEGRAL_TYPE_P (parmtype))
7009 if (! INTEGRAL_TYPE_P (argtype))
7010 return END_BUILTINS;
7012 else
7013 return END_BUILTINS;
7016 /* Variable-length argument list. */
7017 return DECL_FUNCTION_CODE (fndecl);
7020 /* Fold a call to __builtin_constant_p, if we know its argument ARG will
7021 evaluate to a constant. */
7023 static tree
7024 fold_builtin_constant_p (tree arg)
7026 /* We return 1 for a numeric type that's known to be a constant
7027 value at compile-time or for an aggregate type that's a
7028 literal constant. */
7029 STRIP_NOPS (arg);
7031 /* If we know this is a constant, emit the constant of one. */
7032 if (CONSTANT_CLASS_P (arg)
7033 || (TREE_CODE (arg) == CONSTRUCTOR
7034 && TREE_CONSTANT (arg)))
7035 return integer_one_node;
7036 if (TREE_CODE (arg) == ADDR_EXPR)
7038 tree op = TREE_OPERAND (arg, 0);
7039 if (TREE_CODE (op) == STRING_CST
7040 || (TREE_CODE (op) == ARRAY_REF
7041 && integer_zerop (TREE_OPERAND (op, 1))
7042 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
7043 return integer_one_node;
7046 /* If this expression has side effects, show we don't know it to be a
7047 constant. Likewise if it's a pointer or aggregate type since in
7048 those case we only want literals, since those are only optimized
7049 when generating RTL, not later.
7050 And finally, if we are compiling an initializer, not code, we
7051 need to return a definite result now; there's not going to be any
7052 more optimization done. */
7053 if (TREE_SIDE_EFFECTS (arg)
7054 || AGGREGATE_TYPE_P (TREE_TYPE (arg))
7055 || POINTER_TYPE_P (TREE_TYPE (arg))
7056 || cfun == 0
7057 || folding_initializer)
7058 return integer_zero_node;
7060 return NULL_TREE;
7063 /* Create builtin_expect with PRED and EXPECTED as its arguments and
7064 return it as a truthvalue. */
7066 static tree
7067 build_builtin_expect_predicate (tree pred, tree expected)
7069 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
7071 fn = built_in_decls[BUILT_IN_EXPECT];
7072 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
7073 ret_type = TREE_TYPE (TREE_TYPE (fn));
7074 pred_type = TREE_VALUE (arg_types);
7075 expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
7077 pred = fold_convert (pred_type, pred);
7078 expected = fold_convert (expected_type, expected);
7079 call_expr = build_call_expr (fn, 2, pred, expected);
7081 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
7082 build_int_cst (ret_type, 0));
7085 /* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return
7086 NULL_TREE if no simplification is possible. */
7088 static tree
7089 fold_builtin_expect (tree arg0, tree arg1)
7091 tree inner, fndecl;
7092 enum tree_code code;
7094 /* If this is a builtin_expect within a builtin_expect keep the
7095 inner one. See through a comparison against a constant. It
7096 might have been added to create a thruthvalue. */
7097 inner = arg0;
7098 if (COMPARISON_CLASS_P (inner)
7099 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
7100 inner = TREE_OPERAND (inner, 0);
7102 if (TREE_CODE (inner) == CALL_EXPR
7103 && (fndecl = get_callee_fndecl (inner))
7104 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
7105 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
7106 return arg0;
7108 /* Distribute the expected value over short-circuiting operators.
7109 See through the cast from truthvalue_type_node to long. */
7110 inner = arg0;
7111 while (TREE_CODE (inner) == NOP_EXPR
7112 && INTEGRAL_TYPE_P (TREE_TYPE (inner))
7113 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0))))
7114 inner = TREE_OPERAND (inner, 0);
7116 code = TREE_CODE (inner);
7117 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7119 tree op0 = TREE_OPERAND (inner, 0);
7120 tree op1 = TREE_OPERAND (inner, 1);
7122 op0 = build_builtin_expect_predicate (op0, arg1);
7123 op1 = build_builtin_expect_predicate (op1, arg1);
7124 inner = build2 (code, TREE_TYPE (inner), op0, op1);
7126 return fold_convert (TREE_TYPE (arg0), inner);
7129 /* If the argument isn't invariant then there's nothing else we can do. */
7130 if (!TREE_INVARIANT (arg0))
7131 return NULL_TREE;
7133 /* If we expect that a comparison against the argument will fold to
7134 a constant return the constant. In practice, this means a true
7135 constant or the address of a non-weak symbol. */
7136 inner = arg0;
7137 STRIP_NOPS (inner);
7138 if (TREE_CODE (inner) == ADDR_EXPR)
7142 inner = TREE_OPERAND (inner, 0);
7144 while (TREE_CODE (inner) == COMPONENT_REF
7145 || TREE_CODE (inner) == ARRAY_REF);
7146 if (DECL_P (inner) && DECL_WEAK (inner))
7147 return NULL_TREE;
7150 /* Otherwise, ARG0 already has the proper type for the return value. */
7151 return arg0;
7154 /* Fold a call to __builtin_classify_type with argument ARG. */
7156 static tree
7157 fold_builtin_classify_type (tree arg)
7159 if (arg == 0)
7160 return build_int_cst (NULL_TREE, no_type_class);
7162 return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg)));
7165 /* Fold a call to __builtin_strlen with argument ARG. */
7167 static tree
7168 fold_builtin_strlen (tree arg)
7170 if (!validate_arg (arg, POINTER_TYPE))
7171 return NULL_TREE;
7172 else
7174 tree len = c_strlen (arg, 0);
7176 if (len)
7178 /* Convert from the internal "sizetype" type to "size_t". */
7179 if (size_type_node)
7180 len = fold_convert (size_type_node, len);
7181 return len;
7184 return NULL_TREE;
7188 /* Fold a call to __builtin_inf or __builtin_huge_val. */
7190 static tree
7191 fold_builtin_inf (tree type, int warn)
7193 REAL_VALUE_TYPE real;
7195 /* __builtin_inff is intended to be usable to define INFINITY on all
7196 targets. If an infinity is not available, INFINITY expands "to a
7197 positive constant of type float that overflows at translation
7198 time", footnote "In this case, using INFINITY will violate the
7199 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7200 Thus we pedwarn to ensure this constraint violation is
7201 diagnosed. */
7202 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
7203 pedwarn ("target format does not support infinity");
7205 real_inf (&real);
7206 return build_real (type, real);
7209 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG. */
7211 static tree
7212 fold_builtin_nan (tree arg, tree type, int quiet)
7214 REAL_VALUE_TYPE real;
7215 const char *str;
7217 if (!validate_arg (arg, POINTER_TYPE))
7218 return NULL_TREE;
7219 str = c_getstr (arg);
7220 if (!str)
7221 return NULL_TREE;
7223 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
7224 return NULL_TREE;
7226 return build_real (type, real);
7229 /* Return true if the floating point expression T has an integer value.
7230 We also allow +Inf, -Inf and NaN to be considered integer values. */
7232 static bool
7233 integer_valued_real_p (tree t)
7235 switch (TREE_CODE (t))
7237 case FLOAT_EXPR:
7238 return true;
7240 case ABS_EXPR:
7241 case SAVE_EXPR:
7242 case NON_LVALUE_EXPR:
7243 return integer_valued_real_p (TREE_OPERAND (t, 0));
7245 case COMPOUND_EXPR:
7246 case MODIFY_EXPR:
7247 case BIND_EXPR:
7248 return integer_valued_real_p (GENERIC_TREE_OPERAND (t, 1));
7250 case PLUS_EXPR:
7251 case MINUS_EXPR:
7252 case MULT_EXPR:
7253 case MIN_EXPR:
7254 case MAX_EXPR:
7255 return integer_valued_real_p (TREE_OPERAND (t, 0))
7256 && integer_valued_real_p (TREE_OPERAND (t, 1));
7258 case COND_EXPR:
7259 return integer_valued_real_p (TREE_OPERAND (t, 1))
7260 && integer_valued_real_p (TREE_OPERAND (t, 2));
7262 case REAL_CST:
7263 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
7265 case NOP_EXPR:
7267 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7268 if (TREE_CODE (type) == INTEGER_TYPE)
7269 return true;
7270 if (TREE_CODE (type) == REAL_TYPE)
7271 return integer_valued_real_p (TREE_OPERAND (t, 0));
7272 break;
7275 case CALL_EXPR:
7276 switch (builtin_mathfn_code (t))
7278 CASE_FLT_FN (BUILT_IN_CEIL):
7279 CASE_FLT_FN (BUILT_IN_FLOOR):
7280 CASE_FLT_FN (BUILT_IN_NEARBYINT):
7281 CASE_FLT_FN (BUILT_IN_RINT):
7282 CASE_FLT_FN (BUILT_IN_ROUND):
7283 CASE_FLT_FN (BUILT_IN_TRUNC):
7284 return true;
7286 CASE_FLT_FN (BUILT_IN_FMIN):
7287 CASE_FLT_FN (BUILT_IN_FMAX):
7288 return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7289 && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
7291 default:
7292 break;
7294 break;
7296 default:
7297 break;
7299 return false;
7302 /* FNDECL is assumed to be a builtin where truncation can be propagated
7303 across (for instance floor((double)f) == (double)floorf (f).
7304 Do the transformation for a call with argument ARG. */
7306 static tree
7307 fold_trunc_transparent_mathfn (tree fndecl, tree arg)
7309 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7311 if (!validate_arg (arg, REAL_TYPE))
7312 return NULL_TREE;
7314 /* Integer rounding functions are idempotent. */
7315 if (fcode == builtin_mathfn_code (arg))
7316 return arg;
7318 /* If argument is already integer valued, and we don't need to worry
7319 about setting errno, there's no need to perform rounding. */
7320 if (! flag_errno_math && integer_valued_real_p (arg))
7321 return arg;
7323 if (optimize)
7325 tree arg0 = strip_float_extensions (arg);
7326 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
7327 tree newtype = TREE_TYPE (arg0);
7328 tree decl;
7330 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7331 && (decl = mathfn_built_in (newtype, fcode)))
7332 return fold_convert (ftype,
7333 build_call_expr (decl, 1,
7334 fold_convert (newtype, arg0)));
7336 return NULL_TREE;
7339 /* FNDECL is assumed to be builtin which can narrow the FP type of
7340 the argument, for instance lround((double)f) -> lroundf (f).
7341 Do the transformation for a call with argument ARG. */
7343 static tree
7344 fold_fixed_mathfn (tree fndecl, tree arg)
7346 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7348 if (!validate_arg (arg, REAL_TYPE))
7349 return NULL_TREE;
7351 /* If argument is already integer valued, and we don't need to worry
7352 about setting errno, there's no need to perform rounding. */
7353 if (! flag_errno_math && integer_valued_real_p (arg))
7354 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
7356 if (optimize)
7358 tree ftype = TREE_TYPE (arg);
7359 tree arg0 = strip_float_extensions (arg);
7360 tree newtype = TREE_TYPE (arg0);
7361 tree decl;
7363 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7364 && (decl = mathfn_built_in (newtype, fcode)))
7365 return build_call_expr (decl, 1, fold_convert (newtype, arg0));
7368 /* Canonicalize llround (x) to lround (x) on LP64 targets where
7369 sizeof (long long) == sizeof (long). */
7370 if (TYPE_PRECISION (long_long_integer_type_node)
7371 == TYPE_PRECISION (long_integer_type_node))
7373 tree newfn = NULL_TREE;
7374 switch (fcode)
7376 CASE_FLT_FN (BUILT_IN_LLCEIL):
7377 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7378 break;
7380 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7381 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7382 break;
7384 CASE_FLT_FN (BUILT_IN_LLROUND):
7385 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7386 break;
7388 CASE_FLT_FN (BUILT_IN_LLRINT):
7389 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7390 break;
7392 default:
7393 break;
7396 if (newfn)
7398 tree newcall = build_call_expr(newfn, 1, arg);
7399 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7403 return NULL_TREE;
7406 /* Fold call to builtin cabs, cabsf or cabsl with argument ARG. TYPE is the
7407 return type. Return NULL_TREE if no simplification can be made. */
7409 static tree
7410 fold_builtin_cabs (tree arg, tree type, tree fndecl)
7412 tree res;
7414 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7415 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7416 return NULL_TREE;
7418 /* Calculate the result when the argument is a constant. */
7419 if (TREE_CODE (arg) == COMPLEX_CST
7420 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7421 type, mpfr_hypot)))
7422 return res;
7424 if (TREE_CODE (arg) == COMPLEX_EXPR)
7426 tree real = TREE_OPERAND (arg, 0);
7427 tree imag = TREE_OPERAND (arg, 1);
7429 /* If either part is zero, cabs is fabs of the other. */
7430 if (real_zerop (real))
7431 return fold_build1 (ABS_EXPR, type, imag);
7432 if (real_zerop (imag))
7433 return fold_build1 (ABS_EXPR, type, real);
7435 /* cabs(x+xi) -> fabs(x)*sqrt(2). */
7436 if (flag_unsafe_math_optimizations
7437 && operand_equal_p (real, imag, OEP_PURE_SAME))
7439 const REAL_VALUE_TYPE sqrt2_trunc
7440 = real_value_truncate (TYPE_MODE (type), dconstsqrt2);
7441 STRIP_NOPS (real);
7442 return fold_build2 (MULT_EXPR, type,
7443 fold_build1 (ABS_EXPR, type, real),
7444 build_real (type, sqrt2_trunc));
7448 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7449 if (TREE_CODE (arg) == NEGATE_EXPR
7450 || TREE_CODE (arg) == CONJ_EXPR)
7451 return build_call_expr (fndecl, 1, TREE_OPERAND (arg, 0));
7453 /* Don't do this when optimizing for size. */
7454 if (flag_unsafe_math_optimizations
7455 && optimize && !optimize_size)
7457 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7459 if (sqrtfn != NULL_TREE)
7461 tree rpart, ipart, result;
7463 arg = builtin_save_expr (arg);
7465 rpart = fold_build1 (REALPART_EXPR, type, arg);
7466 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
7468 rpart = builtin_save_expr (rpart);
7469 ipart = builtin_save_expr (ipart);
7471 result = fold_build2 (PLUS_EXPR, type,
7472 fold_build2 (MULT_EXPR, type,
7473 rpart, rpart),
7474 fold_build2 (MULT_EXPR, type,
7475 ipart, ipart));
7477 return build_call_expr (sqrtfn, 1, result);
7481 return NULL_TREE;
7484 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7485 Return NULL_TREE if no simplification can be made. */
7487 static tree
7488 fold_builtin_sqrt (tree arg, tree type)
7491 enum built_in_function fcode;
7492 tree res;
7494 if (!validate_arg (arg, REAL_TYPE))
7495 return NULL_TREE;
7497 /* Calculate the result when the argument is a constant. */
7498 if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7499 return res;
7501 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7502 fcode = builtin_mathfn_code (arg);
7503 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7505 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7506 arg = fold_build2 (MULT_EXPR, type,
7507 CALL_EXPR_ARG (arg, 0),
7508 build_real (type, dconsthalf));
7509 return build_call_expr (expfn, 1, arg);
7512 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7513 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7515 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7517 if (powfn)
7519 tree arg0 = CALL_EXPR_ARG (arg, 0);
7520 tree tree_root;
7521 /* The inner root was either sqrt or cbrt. */
7522 REAL_VALUE_TYPE dconstroot =
7523 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7525 /* Adjust for the outer root. */
7526 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7527 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7528 tree_root = build_real (type, dconstroot);
7529 return build_call_expr (powfn, 2, arg0, tree_root);
7533 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7534 if (flag_unsafe_math_optimizations
7535 && (fcode == BUILT_IN_POW
7536 || fcode == BUILT_IN_POWF
7537 || fcode == BUILT_IN_POWL))
7539 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7540 tree arg0 = CALL_EXPR_ARG (arg, 0);
7541 tree arg1 = CALL_EXPR_ARG (arg, 1);
7542 tree narg1;
7543 if (!tree_expr_nonnegative_p (arg0))
7544 arg0 = build1 (ABS_EXPR, type, arg0);
7545 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7546 build_real (type, dconsthalf));
7547 return build_call_expr (powfn, 2, arg0, narg1);
7550 return NULL_TREE;
7553 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7554 Return NULL_TREE if no simplification can be made. */
7556 static tree
7557 fold_builtin_cbrt (tree arg, tree type)
7559 const enum built_in_function fcode = builtin_mathfn_code (arg);
7560 tree res;
7562 if (!validate_arg (arg, REAL_TYPE))
7563 return NULL_TREE;
7565 /* Calculate the result when the argument is a constant. */
7566 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7567 return res;
7569 if (flag_unsafe_math_optimizations)
7571 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7572 if (BUILTIN_EXPONENT_P (fcode))
7574 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7575 const REAL_VALUE_TYPE third_trunc =
7576 real_value_truncate (TYPE_MODE (type), dconstthird);
7577 arg = fold_build2 (MULT_EXPR, type,
7578 CALL_EXPR_ARG (arg, 0),
7579 build_real (type, third_trunc));
7580 return build_call_expr (expfn, 1, arg);
7583 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7584 if (BUILTIN_SQRT_P (fcode))
7586 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7588 if (powfn)
7590 tree arg0 = CALL_EXPR_ARG (arg, 0);
7591 tree tree_root;
7592 REAL_VALUE_TYPE dconstroot = dconstthird;
7594 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7595 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7596 tree_root = build_real (type, dconstroot);
7597 return build_call_expr (powfn, 2, arg0, tree_root);
7601 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7602 if (BUILTIN_CBRT_P (fcode))
7604 tree arg0 = CALL_EXPR_ARG (arg, 0);
7605 if (tree_expr_nonnegative_p (arg0))
7607 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7609 if (powfn)
7611 tree tree_root;
7612 REAL_VALUE_TYPE dconstroot;
7614 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7615 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7616 tree_root = build_real (type, dconstroot);
7617 return build_call_expr (powfn, 2, arg0, tree_root);
7622 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7623 if (fcode == BUILT_IN_POW
7624 || fcode == BUILT_IN_POWF
7625 || fcode == BUILT_IN_POWL)
7627 tree arg00 = CALL_EXPR_ARG (arg, 0);
7628 tree arg01 = CALL_EXPR_ARG (arg, 1);
7629 if (tree_expr_nonnegative_p (arg00))
7631 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7632 const REAL_VALUE_TYPE dconstroot
7633 = real_value_truncate (TYPE_MODE (type), dconstthird);
7634 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7635 build_real (type, dconstroot));
7636 return build_call_expr (powfn, 2, arg00, narg01);
7640 return NULL_TREE;
7643 /* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7644 TYPE is the type of the return value. Return NULL_TREE if no
7645 simplification can be made. */
7647 static tree
7648 fold_builtin_cos (tree arg, tree type, tree fndecl)
7650 tree res, narg;
7652 if (!validate_arg (arg, REAL_TYPE))
7653 return NULL_TREE;
7655 /* Calculate the result when the argument is a constant. */
7656 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7657 return res;
7659 /* Optimize cos(-x) into cos (x). */
7660 if ((narg = fold_strip_sign_ops (arg)))
7661 return build_call_expr (fndecl, 1, narg);
7663 return NULL_TREE;
7666 /* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7667 Return NULL_TREE if no simplification can be made. */
7669 static tree
7670 fold_builtin_cosh (tree arg, tree type, tree fndecl)
7672 if (validate_arg (arg, REAL_TYPE))
7674 tree res, narg;
7676 /* Calculate the result when the argument is a constant. */
7677 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7678 return res;
7680 /* Optimize cosh(-x) into cosh (x). */
7681 if ((narg = fold_strip_sign_ops (arg)))
7682 return build_call_expr (fndecl, 1, narg);
7685 return NULL_TREE;
7688 /* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7689 Return NULL_TREE if no simplification can be made. */
7691 static tree
7692 fold_builtin_tan (tree arg, tree type)
7694 enum built_in_function fcode;
7695 tree res;
7697 if (!validate_arg (arg, REAL_TYPE))
7698 return NULL_TREE;
7700 /* Calculate the result when the argument is a constant. */
7701 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7702 return res;
7704 /* Optimize tan(atan(x)) = x. */
7705 fcode = builtin_mathfn_code (arg);
7706 if (flag_unsafe_math_optimizations
7707 && (fcode == BUILT_IN_ATAN
7708 || fcode == BUILT_IN_ATANF
7709 || fcode == BUILT_IN_ATANL))
7710 return CALL_EXPR_ARG (arg, 0);
7712 return NULL_TREE;
7715 /* Fold function call to builtin sincos, sincosf, or sincosl. Return
7716 NULL_TREE if no simplification can be made. */
7718 static tree
7719 fold_builtin_sincos (tree arg0, tree arg1, tree arg2)
7721 tree type;
7722 tree res, fn, call;
7724 if (!validate_arg (arg0, REAL_TYPE)
7725 || !validate_arg (arg1, POINTER_TYPE)
7726 || !validate_arg (arg2, POINTER_TYPE))
7727 return NULL_TREE;
7729 type = TREE_TYPE (arg0);
7731 /* Calculate the result when the argument is a constant. */
7732 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7733 return res;
7735 /* Canonicalize sincos to cexpi. */
7736 if (!TARGET_C99_FUNCTIONS)
7737 return NULL_TREE;
7738 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7739 if (!fn)
7740 return NULL_TREE;
7742 call = build_call_expr (fn, 1, arg0);
7743 call = builtin_save_expr (call);
7745 return build2 (COMPOUND_EXPR, type,
7746 build2 (MODIFY_EXPR, void_type_node,
7747 build_fold_indirect_ref (arg1),
7748 build1 (IMAGPART_EXPR, type, call)),
7749 build2 (MODIFY_EXPR, void_type_node,
7750 build_fold_indirect_ref (arg2),
7751 build1 (REALPART_EXPR, type, call)));
7754 /* Fold function call to builtin cexp, cexpf, or cexpl. Return
7755 NULL_TREE if no simplification can be made. */
7757 static tree
7758 fold_builtin_cexp (tree arg0, tree type)
7760 tree rtype;
7761 tree realp, imagp, ifn;
7763 if (!validate_arg (arg0, COMPLEX_TYPE))
7764 return NULL_TREE;
7766 rtype = TREE_TYPE (TREE_TYPE (arg0));
7768 /* In case we can figure out the real part of arg0 and it is constant zero
7769 fold to cexpi. */
7770 if (!TARGET_C99_FUNCTIONS)
7771 return NULL_TREE;
7772 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7773 if (!ifn)
7774 return NULL_TREE;
7776 if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
7777 && real_zerop (realp))
7779 tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
7780 return build_call_expr (ifn, 1, narg);
7783 /* In case we can easily decompose real and imaginary parts split cexp
7784 to exp (r) * cexpi (i). */
7785 if (flag_unsafe_math_optimizations
7786 && realp)
7788 tree rfn, rcall, icall;
7790 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7791 if (!rfn)
7792 return NULL_TREE;
7794 imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
7795 if (!imagp)
7796 return NULL_TREE;
7798 icall = build_call_expr (ifn, 1, imagp);
7799 icall = builtin_save_expr (icall);
7800 rcall = build_call_expr (rfn, 1, realp);
7801 rcall = builtin_save_expr (rcall);
7802 return build2 (COMPLEX_EXPR, type,
7803 build2 (MULT_EXPR, rtype,
7804 rcall,
7805 build1 (REALPART_EXPR, rtype, icall)),
7806 build2 (MULT_EXPR, rtype,
7807 rcall,
7808 build1 (IMAGPART_EXPR, rtype, icall)));
7811 return NULL_TREE;
7814 /* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7815 Return NULL_TREE if no simplification can be made. */
7817 static tree
7818 fold_builtin_trunc (tree fndecl, tree arg)
7820 if (!validate_arg (arg, REAL_TYPE))
7821 return NULL_TREE;
7823 /* Optimize trunc of constant value. */
7824 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7826 REAL_VALUE_TYPE r, x;
7827 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7829 x = TREE_REAL_CST (arg);
7830 real_trunc (&r, TYPE_MODE (type), &x);
7831 return build_real (type, r);
7834 return fold_trunc_transparent_mathfn (fndecl, arg);
7837 /* Fold function call to builtin floor, floorf or floorl with argument ARG.
7838 Return NULL_TREE if no simplification can be made. */
7840 static tree
7841 fold_builtin_floor (tree fndecl, tree arg)
7843 if (!validate_arg (arg, REAL_TYPE))
7844 return NULL_TREE;
7846 /* Optimize floor of constant value. */
7847 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7849 REAL_VALUE_TYPE x;
7851 x = TREE_REAL_CST (arg);
7852 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7854 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7855 REAL_VALUE_TYPE r;
7857 real_floor (&r, TYPE_MODE (type), &x);
7858 return build_real (type, r);
7862 /* Fold floor (x) where x is nonnegative to trunc (x). */
7863 if (tree_expr_nonnegative_p (arg))
7865 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7866 if (truncfn)
7867 return build_call_expr (truncfn, 1, arg);
7870 return fold_trunc_transparent_mathfn (fndecl, arg);
7873 /* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7874 Return NULL_TREE if no simplification can be made. */
7876 static tree
7877 fold_builtin_ceil (tree fndecl, tree arg)
7879 if (!validate_arg (arg, REAL_TYPE))
7880 return NULL_TREE;
7882 /* Optimize ceil of constant value. */
7883 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7885 REAL_VALUE_TYPE x;
7887 x = TREE_REAL_CST (arg);
7888 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7890 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7891 REAL_VALUE_TYPE r;
7893 real_ceil (&r, TYPE_MODE (type), &x);
7894 return build_real (type, r);
7898 return fold_trunc_transparent_mathfn (fndecl, arg);
7901 /* Fold function call to builtin round, roundf or roundl with argument ARG.
7902 Return NULL_TREE if no simplification can be made. */
7904 static tree
7905 fold_builtin_round (tree fndecl, tree arg)
7907 if (!validate_arg (arg, REAL_TYPE))
7908 return NULL_TREE;
7910 /* Optimize round of constant value. */
7911 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7913 REAL_VALUE_TYPE x;
7915 x = TREE_REAL_CST (arg);
7916 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7918 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7919 REAL_VALUE_TYPE r;
7921 real_round (&r, TYPE_MODE (type), &x);
7922 return build_real (type, r);
7926 return fold_trunc_transparent_mathfn (fndecl, arg);
7929 /* Fold function call to builtin lround, lroundf or lroundl (or the
7930 corresponding long long versions) and other rounding functions. ARG
7931 is the argument to the call. Return NULL_TREE if no simplification
7932 can be made. */
7934 static tree
7935 fold_builtin_int_roundingfn (tree fndecl, tree arg)
7937 if (!validate_arg (arg, REAL_TYPE))
7938 return NULL_TREE;
7940 /* Optimize lround of constant value. */
7941 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7943 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7945 if (real_isfinite (&x))
7947 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7948 tree ftype = TREE_TYPE (arg);
7949 unsigned HOST_WIDE_INT lo2;
7950 HOST_WIDE_INT hi, lo;
7951 REAL_VALUE_TYPE r;
7953 switch (DECL_FUNCTION_CODE (fndecl))
7955 CASE_FLT_FN (BUILT_IN_LFLOOR):
7956 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7957 real_floor (&r, TYPE_MODE (ftype), &x);
7958 break;
7960 CASE_FLT_FN (BUILT_IN_LCEIL):
7961 CASE_FLT_FN (BUILT_IN_LLCEIL):
7962 real_ceil (&r, TYPE_MODE (ftype), &x);
7963 break;
7965 CASE_FLT_FN (BUILT_IN_LROUND):
7966 CASE_FLT_FN (BUILT_IN_LLROUND):
7967 real_round (&r, TYPE_MODE (ftype), &x);
7968 break;
7970 default:
7971 gcc_unreachable ();
7974 REAL_VALUE_TO_INT (&lo, &hi, r);
7975 if (!fit_double_type (lo, hi, &lo2, &hi, itype))
7976 return build_int_cst_wide (itype, lo2, hi);
7980 switch (DECL_FUNCTION_CODE (fndecl))
7982 CASE_FLT_FN (BUILT_IN_LFLOOR):
7983 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7984 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7985 if (tree_expr_nonnegative_p (arg))
7986 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
7987 arg);
7988 break;
7989 default:;
7992 return fold_fixed_mathfn (fndecl, arg);
7995 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7996 and their long and long long variants (i.e. ffsl and ffsll). ARG is
7997 the argument to the call. Return NULL_TREE if no simplification can
7998 be made. */
8000 static tree
8001 fold_builtin_bitop (tree fndecl, tree arg)
8003 if (!validate_arg (arg, INTEGER_TYPE))
8004 return NULL_TREE;
8006 /* Optimize for constant argument. */
8007 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8009 HOST_WIDE_INT hi, width, result;
8010 unsigned HOST_WIDE_INT lo;
8011 tree type;
8013 type = TREE_TYPE (arg);
8014 width = TYPE_PRECISION (type);
8015 lo = TREE_INT_CST_LOW (arg);
8017 /* Clear all the bits that are beyond the type's precision. */
8018 if (width > HOST_BITS_PER_WIDE_INT)
8020 hi = TREE_INT_CST_HIGH (arg);
8021 if (width < 2 * HOST_BITS_PER_WIDE_INT)
8022 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
8024 else
8026 hi = 0;
8027 if (width < HOST_BITS_PER_WIDE_INT)
8028 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8031 switch (DECL_FUNCTION_CODE (fndecl))
8033 CASE_INT_FN (BUILT_IN_FFS):
8034 if (lo != 0)
8035 result = exact_log2 (lo & -lo) + 1;
8036 else if (hi != 0)
8037 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
8038 else
8039 result = 0;
8040 break;
8042 CASE_INT_FN (BUILT_IN_CLZ):
8043 if (hi != 0)
8044 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8045 else if (lo != 0)
8046 result = width - floor_log2 (lo) - 1;
8047 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8048 result = width;
8049 break;
8051 CASE_INT_FN (BUILT_IN_CTZ):
8052 if (lo != 0)
8053 result = exact_log2 (lo & -lo);
8054 else if (hi != 0)
8055 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
8056 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8057 result = width;
8058 break;
8060 CASE_INT_FN (BUILT_IN_POPCOUNT):
8061 result = 0;
8062 while (lo)
8063 result++, lo &= lo - 1;
8064 while (hi)
8065 result++, hi &= hi - 1;
8066 break;
8068 CASE_INT_FN (BUILT_IN_PARITY):
8069 result = 0;
8070 while (lo)
8071 result++, lo &= lo - 1;
8072 while (hi)
8073 result++, hi &= hi - 1;
8074 result &= 1;
8075 break;
8077 default:
8078 gcc_unreachable ();
8081 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
8084 return NULL_TREE;
8087 /* Fold function call to builtin_bswap and the long and long long
8088 variants. Return NULL_TREE if no simplification can be made. */
8089 static tree
8090 fold_builtin_bswap (tree fndecl, tree arg)
8092 if (! validate_arg (arg, INTEGER_TYPE))
8093 return NULL_TREE;
8095 /* Optimize constant value. */
8096 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8098 HOST_WIDE_INT hi, width, r_hi = 0;
8099 unsigned HOST_WIDE_INT lo, r_lo = 0;
8100 tree type;
8102 type = TREE_TYPE (arg);
8103 width = TYPE_PRECISION (type);
8104 lo = TREE_INT_CST_LOW (arg);
8105 hi = TREE_INT_CST_HIGH (arg);
8107 switch (DECL_FUNCTION_CODE (fndecl))
8109 case BUILT_IN_BSWAP32:
8110 case BUILT_IN_BSWAP64:
8112 int s;
8114 for (s = 0; s < width; s += 8)
8116 int d = width - s - 8;
8117 unsigned HOST_WIDE_INT byte;
8119 if (s < HOST_BITS_PER_WIDE_INT)
8120 byte = (lo >> s) & 0xff;
8121 else
8122 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8124 if (d < HOST_BITS_PER_WIDE_INT)
8125 r_lo |= byte << d;
8126 else
8127 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8131 break;
8133 default:
8134 gcc_unreachable ();
8137 if (width < HOST_BITS_PER_WIDE_INT)
8138 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
8139 else
8140 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
8143 return NULL_TREE;
8146 /* Return true if EXPR is the real constant contained in VALUE. */
8148 static bool
8149 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
8151 STRIP_NOPS (expr);
8153 return ((TREE_CODE (expr) == REAL_CST
8154 && !TREE_OVERFLOW (expr)
8155 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
8156 || (TREE_CODE (expr) == COMPLEX_CST
8157 && real_dconstp (TREE_REALPART (expr), value)
8158 && real_zerop (TREE_IMAGPART (expr))));
8161 /* A subroutine of fold_builtin to fold the various logarithmic
8162 functions. Return NULL_TREE if no simplification can me made.
8163 FUNC is the corresponding MPFR logarithm function. */
8165 static tree
8166 fold_builtin_logarithm (tree fndecl, tree arg,
8167 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8169 if (validate_arg (arg, REAL_TYPE))
8171 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8172 tree res;
8173 const enum built_in_function fcode = builtin_mathfn_code (arg);
8175 /* Optimize log(e) = 1.0. We're never passed an exact 'e',
8176 instead we'll look for 'e' truncated to MODE. So only do
8177 this if flag_unsafe_math_optimizations is set. */
8178 if (flag_unsafe_math_optimizations && func == mpfr_log)
8180 const REAL_VALUE_TYPE e_truncated =
8181 real_value_truncate (TYPE_MODE (type), dconste);
8182 if (real_dconstp (arg, &e_truncated))
8183 return build_real (type, dconst1);
8186 /* Calculate the result when the argument is a constant. */
8187 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8188 return res;
8190 /* Special case, optimize logN(expN(x)) = x. */
8191 if (flag_unsafe_math_optimizations
8192 && ((func == mpfr_log
8193 && (fcode == BUILT_IN_EXP
8194 || fcode == BUILT_IN_EXPF
8195 || fcode == BUILT_IN_EXPL))
8196 || (func == mpfr_log2
8197 && (fcode == BUILT_IN_EXP2
8198 || fcode == BUILT_IN_EXP2F
8199 || fcode == BUILT_IN_EXP2L))
8200 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
8201 return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8203 /* Optimize logN(func()) for various exponential functions. We
8204 want to determine the value "x" and the power "exponent" in
8205 order to transform logN(x**exponent) into exponent*logN(x). */
8206 if (flag_unsafe_math_optimizations)
8208 tree exponent = 0, x = 0;
8210 switch (fcode)
8212 CASE_FLT_FN (BUILT_IN_EXP):
8213 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
8214 x = build_real (type,
8215 real_value_truncate (TYPE_MODE (type), dconste));
8216 exponent = CALL_EXPR_ARG (arg, 0);
8217 break;
8218 CASE_FLT_FN (BUILT_IN_EXP2):
8219 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
8220 x = build_real (type, dconst2);
8221 exponent = CALL_EXPR_ARG (arg, 0);
8222 break;
8223 CASE_FLT_FN (BUILT_IN_EXP10):
8224 CASE_FLT_FN (BUILT_IN_POW10):
8225 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
8226 x = build_real (type, dconst10);
8227 exponent = CALL_EXPR_ARG (arg, 0);
8228 break;
8229 CASE_FLT_FN (BUILT_IN_SQRT):
8230 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
8231 x = CALL_EXPR_ARG (arg, 0);
8232 exponent = build_real (type, dconsthalf);
8233 break;
8234 CASE_FLT_FN (BUILT_IN_CBRT):
8235 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
8236 x = CALL_EXPR_ARG (arg, 0);
8237 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
8238 dconstthird));
8239 break;
8240 CASE_FLT_FN (BUILT_IN_POW):
8241 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
8242 x = CALL_EXPR_ARG (arg, 0);
8243 exponent = CALL_EXPR_ARG (arg, 1);
8244 break;
8245 default:
8246 break;
8249 /* Now perform the optimization. */
8250 if (x && exponent)
8252 tree logfn = build_call_expr (fndecl, 1, x);
8253 return fold_build2 (MULT_EXPR, type, exponent, logfn);
8258 return NULL_TREE;
8261 /* Fold a builtin function call to hypot, hypotf, or hypotl. Return
8262 NULL_TREE if no simplification can be made. */
8264 static tree
8265 fold_builtin_hypot (tree fndecl, tree arg0, tree arg1, tree type)
8267 tree res, narg0, narg1;
8269 if (!validate_arg (arg0, REAL_TYPE)
8270 || !validate_arg (arg1, REAL_TYPE))
8271 return NULL_TREE;
8273 /* Calculate the result when the argument is a constant. */
8274 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8275 return res;
8277 /* If either argument to hypot has a negate or abs, strip that off.
8278 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
8279 narg0 = fold_strip_sign_ops (arg0);
8280 narg1 = fold_strip_sign_ops (arg1);
8281 if (narg0 || narg1)
8283 return build_call_expr (fndecl, 2, narg0 ? narg0 : arg0,
8284 narg1 ? narg1 : arg1);
8287 /* If either argument is zero, hypot is fabs of the other. */
8288 if (real_zerop (arg0))
8289 return fold_build1 (ABS_EXPR, type, arg1);
8290 else if (real_zerop (arg1))
8291 return fold_build1 (ABS_EXPR, type, arg0);
8293 /* hypot(x,x) -> fabs(x)*sqrt(2). */
8294 if (flag_unsafe_math_optimizations
8295 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8297 const REAL_VALUE_TYPE sqrt2_trunc
8298 = real_value_truncate (TYPE_MODE (type), dconstsqrt2);
8299 return fold_build2 (MULT_EXPR, type,
8300 fold_build1 (ABS_EXPR, type, arg0),
8301 build_real (type, sqrt2_trunc));
8304 return NULL_TREE;
8308 /* Fold a builtin function call to pow, powf, or powl. Return
8309 NULL_TREE if no simplification can be made. */
8310 static tree
8311 fold_builtin_pow (tree fndecl, tree arg0, tree arg1, tree type)
8313 tree res;
8315 if (!validate_arg (arg0, REAL_TYPE)
8316 || !validate_arg (arg1, REAL_TYPE))
8317 return NULL_TREE;
8319 /* Calculate the result when the argument is a constant. */
8320 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8321 return res;
8323 /* Optimize pow(1.0,y) = 1.0. */
8324 if (real_onep (arg0))
8325 return omit_one_operand (type, build_real (type, dconst1), arg1);
8327 if (TREE_CODE (arg1) == REAL_CST
8328 && !TREE_OVERFLOW (arg1))
8330 REAL_VALUE_TYPE cint;
8331 REAL_VALUE_TYPE c;
8332 HOST_WIDE_INT n;
8334 c = TREE_REAL_CST (arg1);
8336 /* Optimize pow(x,0.0) = 1.0. */
8337 if (REAL_VALUES_EQUAL (c, dconst0))
8338 return omit_one_operand (type, build_real (type, dconst1),
8339 arg0);
8341 /* Optimize pow(x,1.0) = x. */
8342 if (REAL_VALUES_EQUAL (c, dconst1))
8343 return arg0;
8345 /* Optimize pow(x,-1.0) = 1.0/x. */
8346 if (REAL_VALUES_EQUAL (c, dconstm1))
8347 return fold_build2 (RDIV_EXPR, type,
8348 build_real (type, dconst1), arg0);
8350 /* Optimize pow(x,0.5) = sqrt(x). */
8351 if (flag_unsafe_math_optimizations
8352 && REAL_VALUES_EQUAL (c, dconsthalf))
8354 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8356 if (sqrtfn != NULL_TREE)
8357 return build_call_expr (sqrtfn, 1, arg0);
8360 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8361 if (flag_unsafe_math_optimizations)
8363 const REAL_VALUE_TYPE dconstroot
8364 = real_value_truncate (TYPE_MODE (type), dconstthird);
8366 if (REAL_VALUES_EQUAL (c, dconstroot))
8368 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8369 if (cbrtfn != NULL_TREE)
8370 return build_call_expr (cbrtfn, 1, arg0);
8374 /* Check for an integer exponent. */
8375 n = real_to_integer (&c);
8376 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8377 if (real_identical (&c, &cint))
8379 /* Attempt to evaluate pow at compile-time. */
8380 if (TREE_CODE (arg0) == REAL_CST
8381 && !TREE_OVERFLOW (arg0))
8383 REAL_VALUE_TYPE x;
8384 bool inexact;
8386 x = TREE_REAL_CST (arg0);
8387 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8388 if (flag_unsafe_math_optimizations || !inexact)
8389 return build_real (type, x);
8392 /* Strip sign ops from even integer powers. */
8393 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8395 tree narg0 = fold_strip_sign_ops (arg0);
8396 if (narg0)
8397 return build_call_expr (fndecl, 2, narg0, arg1);
8402 if (flag_unsafe_math_optimizations)
8404 const enum built_in_function fcode = builtin_mathfn_code (arg0);
8406 /* Optimize pow(expN(x),y) = expN(x*y). */
8407 if (BUILTIN_EXPONENT_P (fcode))
8409 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8410 tree arg = CALL_EXPR_ARG (arg0, 0);
8411 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
8412 return build_call_expr (expfn, 1, arg);
8415 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8416 if (BUILTIN_SQRT_P (fcode))
8418 tree narg0 = CALL_EXPR_ARG (arg0, 0);
8419 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8420 build_real (type, dconsthalf));
8421 return build_call_expr (fndecl, 2, narg0, narg1);
8424 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8425 if (BUILTIN_CBRT_P (fcode))
8427 tree arg = CALL_EXPR_ARG (arg0, 0);
8428 if (tree_expr_nonnegative_p (arg))
8430 const REAL_VALUE_TYPE dconstroot
8431 = real_value_truncate (TYPE_MODE (type), dconstthird);
8432 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8433 build_real (type, dconstroot));
8434 return build_call_expr (fndecl, 2, arg, narg1);
8438 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
8439 if (fcode == BUILT_IN_POW
8440 || fcode == BUILT_IN_POWF
8441 || fcode == BUILT_IN_POWL)
8443 tree arg00 = CALL_EXPR_ARG (arg0, 0);
8444 tree arg01 = CALL_EXPR_ARG (arg0, 1);
8445 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
8446 return build_call_expr (fndecl, 2, arg00, narg1);
8450 return NULL_TREE;
8453 /* Fold a builtin function call to powi, powif, or powil with argument ARG.
8454 Return NULL_TREE if no simplification can be made. */
8455 static tree
8456 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED,
8457 tree arg0, tree arg1, tree type)
8459 if (!validate_arg (arg0, REAL_TYPE)
8460 || !validate_arg (arg1, INTEGER_TYPE))
8461 return NULL_TREE;
8463 /* Optimize pow(1.0,y) = 1.0. */
8464 if (real_onep (arg0))
8465 return omit_one_operand (type, build_real (type, dconst1), arg1);
8467 if (host_integerp (arg1, 0))
8469 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8471 /* Evaluate powi at compile-time. */
8472 if (TREE_CODE (arg0) == REAL_CST
8473 && !TREE_OVERFLOW (arg0))
8475 REAL_VALUE_TYPE x;
8476 x = TREE_REAL_CST (arg0);
8477 real_powi (&x, TYPE_MODE (type), &x, c);
8478 return build_real (type, x);
8481 /* Optimize pow(x,0) = 1.0. */
8482 if (c == 0)
8483 return omit_one_operand (type, build_real (type, dconst1),
8484 arg0);
8486 /* Optimize pow(x,1) = x. */
8487 if (c == 1)
8488 return arg0;
8490 /* Optimize pow(x,-1) = 1.0/x. */
8491 if (c == -1)
8492 return fold_build2 (RDIV_EXPR, type,
8493 build_real (type, dconst1), arg0);
8496 return NULL_TREE;
8499 /* A subroutine of fold_builtin to fold the various exponent
8500 functions. Return NULL_TREE if no simplification can be made.
8501 FUNC is the corresponding MPFR exponent function. */
8503 static tree
8504 fold_builtin_exponent (tree fndecl, tree arg,
8505 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8507 if (validate_arg (arg, REAL_TYPE))
8509 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8510 tree res;
8512 /* Calculate the result when the argument is a constant. */
8513 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8514 return res;
8516 /* Optimize expN(logN(x)) = x. */
8517 if (flag_unsafe_math_optimizations)
8519 const enum built_in_function fcode = builtin_mathfn_code (arg);
8521 if ((func == mpfr_exp
8522 && (fcode == BUILT_IN_LOG
8523 || fcode == BUILT_IN_LOGF
8524 || fcode == BUILT_IN_LOGL))
8525 || (func == mpfr_exp2
8526 && (fcode == BUILT_IN_LOG2
8527 || fcode == BUILT_IN_LOG2F
8528 || fcode == BUILT_IN_LOG2L))
8529 || (func == mpfr_exp10
8530 && (fcode == BUILT_IN_LOG10
8531 || fcode == BUILT_IN_LOG10F
8532 || fcode == BUILT_IN_LOG10L)))
8533 return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8537 return NULL_TREE;
8540 /* Return true if VAR is a VAR_DECL or a component thereof. */
8542 static bool
8543 var_decl_component_p (tree var)
8545 tree inner = var;
8546 while (handled_component_p (inner))
8547 inner = TREE_OPERAND (inner, 0);
8548 return SSA_VAR_P (inner);
8551 /* Fold function call to builtin memset. Return
8552 NULL_TREE if no simplification can be made. */
8554 static tree
8555 fold_builtin_memset (tree dest, tree c, tree len, tree type, bool ignore)
8557 tree var, ret;
8558 unsigned HOST_WIDE_INT length, cval;
8560 if (! validate_arg (dest, POINTER_TYPE)
8561 || ! validate_arg (c, INTEGER_TYPE)
8562 || ! validate_arg (len, INTEGER_TYPE))
8563 return NULL_TREE;
8565 if (! host_integerp (len, 1))
8566 return NULL_TREE;
8568 /* If the LEN parameter is zero, return DEST. */
8569 if (integer_zerop (len))
8570 return omit_one_operand (type, dest, c);
8572 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8573 return NULL_TREE;
8575 var = dest;
8576 STRIP_NOPS (var);
8577 if (TREE_CODE (var) != ADDR_EXPR)
8578 return NULL_TREE;
8580 var = TREE_OPERAND (var, 0);
8581 if (TREE_THIS_VOLATILE (var))
8582 return NULL_TREE;
8584 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8585 && !POINTER_TYPE_P (TREE_TYPE (var)))
8586 return NULL_TREE;
8588 if (! var_decl_component_p (var))
8589 return NULL_TREE;
8591 length = tree_low_cst (len, 1);
8592 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8593 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8594 < (int) length)
8595 return NULL_TREE;
8597 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8598 return NULL_TREE;
8600 if (integer_zerop (c))
8601 cval = 0;
8602 else
8604 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8605 return NULL_TREE;
8607 cval = tree_low_cst (c, 1);
8608 cval &= 0xff;
8609 cval |= cval << 8;
8610 cval |= cval << 16;
8611 cval |= (cval << 31) << 1;
8614 ret = build_int_cst_type (TREE_TYPE (var), cval);
8615 ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
8616 if (ignore)
8617 return ret;
8619 return omit_one_operand (type, dest, ret);
8622 /* Fold function call to builtin memset. Return
8623 NULL_TREE if no simplification can be made. */
8625 static tree
8626 fold_builtin_bzero (tree dest, tree size, bool ignore)
8628 if (! validate_arg (dest, POINTER_TYPE)
8629 || ! validate_arg (size, INTEGER_TYPE))
8630 return NULL_TREE;
8632 if (!ignore)
8633 return NULL_TREE;
8635 /* New argument list transforming bzero(ptr x, int y) to
8636 memset(ptr x, int 0, size_t y). This is done this way
8637 so that if it isn't expanded inline, we fallback to
8638 calling bzero instead of memset. */
8640 return fold_builtin_memset (dest, integer_zero_node,
8641 fold_convert (sizetype, size),
8642 void_type_node, ignore);
8645 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8646 NULL_TREE if no simplification can be made.
8647 If ENDP is 0, return DEST (like memcpy).
8648 If ENDP is 1, return DEST+LEN (like mempcpy).
8649 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8650 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8651 (memmove). */
8653 static tree
8654 fold_builtin_memory_op (tree dest, tree src, tree len, tree type, bool ignore, int endp)
8656 tree destvar, srcvar, expr;
8658 if (! validate_arg (dest, POINTER_TYPE)
8659 || ! validate_arg (src, POINTER_TYPE)
8660 || ! validate_arg (len, INTEGER_TYPE))
8661 return NULL_TREE;
8663 /* If the LEN parameter is zero, return DEST. */
8664 if (integer_zerop (len))
8665 return omit_one_operand (type, dest, src);
8667 /* If SRC and DEST are the same (and not volatile), return
8668 DEST{,+LEN,+LEN-1}. */
8669 if (operand_equal_p (src, dest, 0))
8670 expr = len;
8671 else
8673 tree srctype, desttype;
8674 if (endp == 3)
8676 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8677 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8679 /* Both DEST and SRC must be pointer types.
8680 ??? This is what old code did. Is the testing for pointer types
8681 really mandatory?
8683 If either SRC is readonly or length is 1, we can use memcpy. */
8684 if (dest_align && src_align
8685 && (readonly_data_expr (src)
8686 || (host_integerp (len, 1)
8687 && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
8688 tree_low_cst (len, 1)))))
8690 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8691 if (!fn)
8692 return NULL_TREE;
8693 return build_call_expr (fn, 3, dest, src, len);
8695 return NULL_TREE;
8698 if (!host_integerp (len, 0))
8699 return NULL_TREE;
8700 /* FIXME:
8701 This logic lose for arguments like (type *)malloc (sizeof (type)),
8702 since we strip the casts of up to VOID return value from malloc.
8703 Perhaps we ought to inherit type from non-VOID argument here? */
8704 STRIP_NOPS (src);
8705 STRIP_NOPS (dest);
8706 srctype = TREE_TYPE (TREE_TYPE (src));
8707 desttype = TREE_TYPE (TREE_TYPE (dest));
8708 if (!srctype || !desttype
8709 || !TYPE_SIZE_UNIT (srctype)
8710 || !TYPE_SIZE_UNIT (desttype)
8711 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
8712 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
8713 || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
8714 || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8715 return NULL_TREE;
8717 if (get_pointer_alignment (dest, BIGGEST_ALIGNMENT)
8718 < (int) TYPE_ALIGN (desttype)
8719 || (get_pointer_alignment (src, BIGGEST_ALIGNMENT)
8720 < (int) TYPE_ALIGN (srctype)))
8721 return NULL_TREE;
8723 if (!ignore)
8724 dest = builtin_save_expr (dest);
8726 srcvar = build_fold_indirect_ref (src);
8727 if (TREE_THIS_VOLATILE (srcvar))
8728 return NULL_TREE;
8729 if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
8730 return NULL_TREE;
8731 /* With memcpy, it is possible to bypass aliasing rules, so without
8732 this check i. e. execute/20060930-2.c would be misoptimized, because
8733 it use conflicting alias set to hold argument for the memcpy call.
8734 This check is probably unnecesary with -fno-strict-aliasing.
8735 Similarly for destvar. See also PR29286. */
8736 if (!var_decl_component_p (srcvar)
8737 /* Accept: memcpy (*char_var, "test", 1); that simplify
8738 to char_var='t'; */
8739 || is_gimple_min_invariant (srcvar)
8740 || readonly_data_expr (src))
8741 return NULL_TREE;
8743 destvar = build_fold_indirect_ref (dest);
8744 if (TREE_THIS_VOLATILE (destvar))
8745 return NULL_TREE;
8746 if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
8747 return NULL_TREE;
8748 if (!var_decl_component_p (destvar))
8749 return NULL_TREE;
8751 if (srctype == desttype
8752 || (gimple_in_ssa_p (cfun)
8753 && useless_type_conversion_p (desttype, srctype)))
8754 expr = srcvar;
8755 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8756 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8757 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8758 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8759 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8760 else
8761 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8762 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
8765 if (ignore)
8766 return expr;
8768 if (endp == 0 || endp == 3)
8769 return omit_one_operand (type, dest, expr);
8771 if (expr == len)
8772 expr = NULL_TREE;
8774 if (endp == 2)
8775 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8776 ssize_int (1));
8778 dest = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
8779 dest = fold_convert (type, dest);
8780 if (expr)
8781 dest = omit_one_operand (type, dest, expr);
8782 return dest;
8785 /* Fold function call to builtin strcpy with arguments DEST and SRC.
8786 If LEN is not NULL, it represents the length of the string to be
8787 copied. Return NULL_TREE if no simplification can be made. */
8789 tree
8790 fold_builtin_strcpy (tree fndecl, tree dest, tree src, tree len)
8792 tree fn;
8794 if (!validate_arg (dest, POINTER_TYPE)
8795 || !validate_arg (src, POINTER_TYPE))
8796 return NULL_TREE;
8798 /* If SRC and DEST are the same (and not volatile), return DEST. */
8799 if (operand_equal_p (src, dest, 0))
8800 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8802 if (optimize_size)
8803 return NULL_TREE;
8805 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8806 if (!fn)
8807 return NULL_TREE;
8809 if (!len)
8811 len = c_strlen (src, 1);
8812 if (! len || TREE_SIDE_EFFECTS (len))
8813 return NULL_TREE;
8816 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8817 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8818 build_call_expr (fn, 3, dest, src, len));
8821 /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
8822 If SLEN is not NULL, it represents the length of the source string.
8823 Return NULL_TREE if no simplification can be made. */
8825 tree
8826 fold_builtin_strncpy (tree fndecl, tree dest, tree src, tree len, tree slen)
8828 tree fn;
8830 if (!validate_arg (dest, POINTER_TYPE)
8831 || !validate_arg (src, POINTER_TYPE)
8832 || !validate_arg (len, INTEGER_TYPE))
8833 return NULL_TREE;
8835 /* If the LEN parameter is zero, return DEST. */
8836 if (integer_zerop (len))
8837 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8839 /* We can't compare slen with len as constants below if len is not a
8840 constant. */
8841 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8842 return NULL_TREE;
8844 if (!slen)
8845 slen = c_strlen (src, 1);
8847 /* Now, we must be passed a constant src ptr parameter. */
8848 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8849 return NULL_TREE;
8851 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8853 /* We do not support simplification of this case, though we do
8854 support it when expanding trees into RTL. */
8855 /* FIXME: generate a call to __builtin_memset. */
8856 if (tree_int_cst_lt (slen, len))
8857 return NULL_TREE;
8859 /* OK transform into builtin memcpy. */
8860 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8861 if (!fn)
8862 return NULL_TREE;
8863 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8864 build_call_expr (fn, 3, dest, src, len));
8867 /* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
8868 arguments to the call, and TYPE is its return type.
8869 Return NULL_TREE if no simplification can be made. */
8871 static tree
8872 fold_builtin_memchr (tree arg1, tree arg2, tree len, tree type)
8874 if (!validate_arg (arg1, POINTER_TYPE)
8875 || !validate_arg (arg2, INTEGER_TYPE)
8876 || !validate_arg (len, INTEGER_TYPE))
8877 return NULL_TREE;
8878 else
8880 const char *p1;
8882 if (TREE_CODE (arg2) != INTEGER_CST
8883 || !host_integerp (len, 1))
8884 return NULL_TREE;
8886 p1 = c_getstr (arg1);
8887 if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
8889 char c;
8890 const char *r;
8891 tree tem;
8893 if (target_char_cast (arg2, &c))
8894 return NULL_TREE;
8896 r = memchr (p1, c, tree_low_cst (len, 1));
8898 if (r == NULL)
8899 return build_int_cst (TREE_TYPE (arg1), 0);
8901 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
8902 size_int (r - p1));
8903 return fold_convert (type, tem);
8905 return NULL_TREE;
8909 /* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
8910 Return NULL_TREE if no simplification can be made. */
8912 static tree
8913 fold_builtin_memcmp (tree arg1, tree arg2, tree len)
8915 const char *p1, *p2;
8917 if (!validate_arg (arg1, POINTER_TYPE)
8918 || !validate_arg (arg2, POINTER_TYPE)
8919 || !validate_arg (len, INTEGER_TYPE))
8920 return NULL_TREE;
8922 /* If the LEN parameter is zero, return zero. */
8923 if (integer_zerop (len))
8924 return omit_two_operands (integer_type_node, integer_zero_node,
8925 arg1, arg2);
8927 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8928 if (operand_equal_p (arg1, arg2, 0))
8929 return omit_one_operand (integer_type_node, integer_zero_node, len);
8931 p1 = c_getstr (arg1);
8932 p2 = c_getstr (arg2);
8934 /* If all arguments are constant, and the value of len is not greater
8935 than the lengths of arg1 and arg2, evaluate at compile-time. */
8936 if (host_integerp (len, 1) && p1 && p2
8937 && compare_tree_int (len, strlen (p1) + 1) <= 0
8938 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8940 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8942 if (r > 0)
8943 return integer_one_node;
8944 else if (r < 0)
8945 return integer_minus_one_node;
8946 else
8947 return integer_zero_node;
8950 /* If len parameter is one, return an expression corresponding to
8951 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8952 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8954 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8955 tree cst_uchar_ptr_node
8956 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8958 tree ind1 = fold_convert (integer_type_node,
8959 build1 (INDIRECT_REF, cst_uchar_node,
8960 fold_convert (cst_uchar_ptr_node,
8961 arg1)));
8962 tree ind2 = fold_convert (integer_type_node,
8963 build1 (INDIRECT_REF, cst_uchar_node,
8964 fold_convert (cst_uchar_ptr_node,
8965 arg2)));
8966 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8969 return NULL_TREE;
8972 /* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
8973 Return NULL_TREE if no simplification can be made. */
8975 static tree
8976 fold_builtin_strcmp (tree arg1, tree arg2)
8978 const char *p1, *p2;
8980 if (!validate_arg (arg1, POINTER_TYPE)
8981 || !validate_arg (arg2, POINTER_TYPE))
8982 return NULL_TREE;
8984 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8985 if (operand_equal_p (arg1, arg2, 0))
8986 return integer_zero_node;
8988 p1 = c_getstr (arg1);
8989 p2 = c_getstr (arg2);
8991 if (p1 && p2)
8993 const int i = strcmp (p1, p2);
8994 if (i < 0)
8995 return integer_minus_one_node;
8996 else if (i > 0)
8997 return integer_one_node;
8998 else
8999 return integer_zero_node;
9002 /* If the second arg is "", return *(const unsigned char*)arg1. */
9003 if (p2 && *p2 == '\0')
9005 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9006 tree cst_uchar_ptr_node
9007 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9009 return fold_convert (integer_type_node,
9010 build1 (INDIRECT_REF, cst_uchar_node,
9011 fold_convert (cst_uchar_ptr_node,
9012 arg1)));
9015 /* If the first arg is "", return -*(const unsigned char*)arg2. */
9016 if (p1 && *p1 == '\0')
9018 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9019 tree cst_uchar_ptr_node
9020 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9022 tree temp = fold_convert (integer_type_node,
9023 build1 (INDIRECT_REF, cst_uchar_node,
9024 fold_convert (cst_uchar_ptr_node,
9025 arg2)));
9026 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
9029 return NULL_TREE;
9032 /* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9033 Return NULL_TREE if no simplification can be made. */
9035 static tree
9036 fold_builtin_strncmp (tree arg1, tree arg2, tree len)
9038 const char *p1, *p2;
9040 if (!validate_arg (arg1, POINTER_TYPE)
9041 || !validate_arg (arg2, POINTER_TYPE)
9042 || !validate_arg (len, INTEGER_TYPE))
9043 return NULL_TREE;
9045 /* If the LEN parameter is zero, return zero. */
9046 if (integer_zerop (len))
9047 return omit_two_operands (integer_type_node, integer_zero_node,
9048 arg1, arg2);
9050 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9051 if (operand_equal_p (arg1, arg2, 0))
9052 return omit_one_operand (integer_type_node, integer_zero_node, len);
9054 p1 = c_getstr (arg1);
9055 p2 = c_getstr (arg2);
9057 if (host_integerp (len, 1) && p1 && p2)
9059 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
9060 if (i > 0)
9061 return integer_one_node;
9062 else if (i < 0)
9063 return integer_minus_one_node;
9064 else
9065 return integer_zero_node;
9068 /* If the second arg is "", and the length is greater than zero,
9069 return *(const unsigned char*)arg1. */
9070 if (p2 && *p2 == '\0'
9071 && TREE_CODE (len) == INTEGER_CST
9072 && tree_int_cst_sgn (len) == 1)
9074 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9075 tree cst_uchar_ptr_node
9076 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9078 return fold_convert (integer_type_node,
9079 build1 (INDIRECT_REF, cst_uchar_node,
9080 fold_convert (cst_uchar_ptr_node,
9081 arg1)));
9084 /* If the first arg is "", and the length is greater than zero,
9085 return -*(const unsigned char*)arg2. */
9086 if (p1 && *p1 == '\0'
9087 && TREE_CODE (len) == INTEGER_CST
9088 && tree_int_cst_sgn (len) == 1)
9090 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9091 tree cst_uchar_ptr_node
9092 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9094 tree temp = fold_convert (integer_type_node,
9095 build1 (INDIRECT_REF, cst_uchar_node,
9096 fold_convert (cst_uchar_ptr_node,
9097 arg2)));
9098 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
9101 /* If len parameter is one, return an expression corresponding to
9102 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9103 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9105 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9106 tree cst_uchar_ptr_node
9107 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9109 tree ind1 = fold_convert (integer_type_node,
9110 build1 (INDIRECT_REF, cst_uchar_node,
9111 fold_convert (cst_uchar_ptr_node,
9112 arg1)));
9113 tree ind2 = fold_convert (integer_type_node,
9114 build1 (INDIRECT_REF, cst_uchar_node,
9115 fold_convert (cst_uchar_ptr_node,
9116 arg2)));
9117 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
9120 return NULL_TREE;
9123 /* Fold function call to builtin signbit, signbitf or signbitl with argument
9124 ARG. Return NULL_TREE if no simplification can be made. */
9126 static tree
9127 fold_builtin_signbit (tree arg, tree type)
9129 tree temp;
9131 if (!validate_arg (arg, REAL_TYPE))
9132 return NULL_TREE;
9134 /* If ARG is a compile-time constant, determine the result. */
9135 if (TREE_CODE (arg) == REAL_CST
9136 && !TREE_OVERFLOW (arg))
9138 REAL_VALUE_TYPE c;
9140 c = TREE_REAL_CST (arg);
9141 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
9142 return fold_convert (type, temp);
9145 /* If ARG is non-negative, the result is always zero. */
9146 if (tree_expr_nonnegative_p (arg))
9147 return omit_one_operand (type, integer_zero_node, arg);
9149 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
9150 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
9151 return fold_build2 (LT_EXPR, type, arg,
9152 build_real (TREE_TYPE (arg), dconst0));
9154 return NULL_TREE;
9157 /* Fold function call to builtin copysign, copysignf or copysignl with
9158 arguments ARG1 and ARG2. Return NULL_TREE if no simplification can
9159 be made. */
9161 static tree
9162 fold_builtin_copysign (tree fndecl, tree arg1, tree arg2, tree type)
9164 tree tem;
9166 if (!validate_arg (arg1, REAL_TYPE)
9167 || !validate_arg (arg2, REAL_TYPE))
9168 return NULL_TREE;
9170 /* copysign(X,X) is X. */
9171 if (operand_equal_p (arg1, arg2, 0))
9172 return fold_convert (type, arg1);
9174 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
9175 if (TREE_CODE (arg1) == REAL_CST
9176 && TREE_CODE (arg2) == REAL_CST
9177 && !TREE_OVERFLOW (arg1)
9178 && !TREE_OVERFLOW (arg2))
9180 REAL_VALUE_TYPE c1, c2;
9182 c1 = TREE_REAL_CST (arg1);
9183 c2 = TREE_REAL_CST (arg2);
9184 /* c1.sign := c2.sign. */
9185 real_copysign (&c1, &c2);
9186 return build_real (type, c1);
9189 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9190 Remember to evaluate Y for side-effects. */
9191 if (tree_expr_nonnegative_p (arg2))
9192 return omit_one_operand (type,
9193 fold_build1 (ABS_EXPR, type, arg1),
9194 arg2);
9196 /* Strip sign changing operations for the first argument. */
9197 tem = fold_strip_sign_ops (arg1);
9198 if (tem)
9199 return build_call_expr (fndecl, 2, tem, arg2);
9201 return NULL_TREE;
9204 /* Fold a call to builtin isascii with argument ARG. */
9206 static tree
9207 fold_builtin_isascii (tree arg)
9209 if (!validate_arg (arg, INTEGER_TYPE))
9210 return NULL_TREE;
9211 else
9213 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
9214 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
9215 build_int_cst (NULL_TREE,
9216 ~ (unsigned HOST_WIDE_INT) 0x7f));
9217 return fold_build2 (EQ_EXPR, integer_type_node,
9218 arg, integer_zero_node);
9222 /* Fold a call to builtin toascii with argument ARG. */
9224 static tree
9225 fold_builtin_toascii (tree arg)
9227 if (!validate_arg (arg, INTEGER_TYPE))
9228 return NULL_TREE;
9230 /* Transform toascii(c) -> (c & 0x7f). */
9231 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9232 build_int_cst (NULL_TREE, 0x7f));
9235 /* Fold a call to builtin isdigit with argument ARG. */
9237 static tree
9238 fold_builtin_isdigit (tree arg)
9240 if (!validate_arg (arg, INTEGER_TYPE))
9241 return NULL_TREE;
9242 else
9244 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
9245 /* According to the C standard, isdigit is unaffected by locale.
9246 However, it definitely is affected by the target character set. */
9247 unsigned HOST_WIDE_INT target_digit0
9248 = lang_hooks.to_target_charset ('0');
9250 if (target_digit0 == 0)
9251 return NULL_TREE;
9253 arg = fold_convert (unsigned_type_node, arg);
9254 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
9255 build_int_cst (unsigned_type_node, target_digit0));
9256 return fold_build2 (LE_EXPR, integer_type_node, arg,
9257 build_int_cst (unsigned_type_node, 9));
9261 /* Fold a call to fabs, fabsf or fabsl with argument ARG. */
9263 static tree
9264 fold_builtin_fabs (tree arg, tree type)
9266 if (!validate_arg (arg, REAL_TYPE))
9267 return NULL_TREE;
9269 arg = fold_convert (type, arg);
9270 if (TREE_CODE (arg) == REAL_CST)
9271 return fold_abs_const (arg, type);
9272 return fold_build1 (ABS_EXPR, type, arg);
9275 /* Fold a call to abs, labs, llabs or imaxabs with argument ARG. */
9277 static tree
9278 fold_builtin_abs (tree arg, tree type)
9280 if (!validate_arg (arg, INTEGER_TYPE))
9281 return NULL_TREE;
9283 arg = fold_convert (type, arg);
9284 if (TREE_CODE (arg) == INTEGER_CST)
9285 return fold_abs_const (arg, type);
9286 return fold_build1 (ABS_EXPR, type, arg);
9289 /* Fold a call to builtin fmin or fmax. */
9291 static tree
9292 fold_builtin_fmin_fmax (tree arg0, tree arg1, tree type, bool max)
9294 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
9296 /* Calculate the result when the argument is a constant. */
9297 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9299 if (res)
9300 return res;
9302 /* If either argument is NaN, return the other one. Avoid the
9303 transformation if we get (and honor) a signalling NaN. Using
9304 omit_one_operand() ensures we create a non-lvalue. */
9305 if (TREE_CODE (arg0) == REAL_CST
9306 && real_isnan (&TREE_REAL_CST (arg0))
9307 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9308 || ! TREE_REAL_CST (arg0).signalling))
9309 return omit_one_operand (type, arg1, arg0);
9310 if (TREE_CODE (arg1) == REAL_CST
9311 && real_isnan (&TREE_REAL_CST (arg1))
9312 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9313 || ! TREE_REAL_CST (arg1).signalling))
9314 return omit_one_operand (type, arg0, arg1);
9316 /* Transform fmin/fmax(x,x) -> x. */
9317 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9318 return omit_one_operand (type, arg0, arg1);
9320 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9321 functions to return the numeric arg if the other one is NaN.
9322 These tree codes don't honor that, so only transform if
9323 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9324 handled, so we don't have to worry about it either. */
9325 if (flag_finite_math_only)
9326 return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
9327 fold_convert (type, arg0),
9328 fold_convert (type, arg1));
9330 return NULL_TREE;
9333 /* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
9335 static tree
9336 fold_builtin_carg (tree arg, tree type)
9338 if (validate_arg (arg, COMPLEX_TYPE))
9340 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9342 if (atan2_fn)
9344 tree new_arg = builtin_save_expr (arg);
9345 tree r_arg = fold_build1 (REALPART_EXPR, type, new_arg);
9346 tree i_arg = fold_build1 (IMAGPART_EXPR, type, new_arg);
9347 return build_call_expr (atan2_fn, 2, i_arg, r_arg);
9351 return NULL_TREE;
9354 /* Fold a call to builtin logb/ilogb. */
9356 static tree
9357 fold_builtin_logb (tree arg, tree rettype)
9359 if (! validate_arg (arg, REAL_TYPE))
9360 return NULL_TREE;
9362 STRIP_NOPS (arg);
9364 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9366 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9368 switch (value->cl)
9370 case rvc_nan:
9371 case rvc_inf:
9372 /* If arg is Inf or NaN and we're logb, return it. */
9373 if (TREE_CODE (rettype) == REAL_TYPE)
9374 return fold_convert (rettype, arg);
9375 /* Fall through... */
9376 case rvc_zero:
9377 /* Zero may set errno and/or raise an exception for logb, also
9378 for ilogb we don't know FP_ILOGB0. */
9379 return NULL_TREE;
9380 case rvc_normal:
9381 /* For normal numbers, proceed iff radix == 2. In GCC,
9382 normalized significands are in the range [0.5, 1.0). We
9383 want the exponent as if they were [1.0, 2.0) so get the
9384 exponent and subtract 1. */
9385 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9386 return fold_convert (rettype, build_int_cst (NULL_TREE,
9387 REAL_EXP (value)-1));
9388 break;
9392 return NULL_TREE;
9395 /* Fold a call to builtin significand, if radix == 2. */
9397 static tree
9398 fold_builtin_significand (tree arg, tree rettype)
9400 if (! validate_arg (arg, REAL_TYPE))
9401 return NULL_TREE;
9403 STRIP_NOPS (arg);
9405 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9407 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9409 switch (value->cl)
9411 case rvc_zero:
9412 case rvc_nan:
9413 case rvc_inf:
9414 /* If arg is +-0, +-Inf or +-NaN, then return it. */
9415 return fold_convert (rettype, arg);
9416 case rvc_normal:
9417 /* For normal numbers, proceed iff radix == 2. */
9418 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9420 REAL_VALUE_TYPE result = *value;
9421 /* In GCC, normalized significands are in the range [0.5,
9422 1.0). We want them to be [1.0, 2.0) so set the
9423 exponent to 1. */
9424 SET_REAL_EXP (&result, 1);
9425 return build_real (rettype, result);
9427 break;
9431 return NULL_TREE;
9434 /* Fold a call to builtin frexp, we can assume the base is 2. */
9436 static tree
9437 fold_builtin_frexp (tree arg0, tree arg1, tree rettype)
9439 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9440 return NULL_TREE;
9442 STRIP_NOPS (arg0);
9444 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9445 return NULL_TREE;
9447 arg1 = build_fold_indirect_ref (arg1);
9449 /* Proceed if a valid pointer type was passed in. */
9450 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9452 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9453 tree frac, exp;
9455 switch (value->cl)
9457 case rvc_zero:
9458 /* For +-0, return (*exp = 0, +-0). */
9459 exp = integer_zero_node;
9460 frac = arg0;
9461 break;
9462 case rvc_nan:
9463 case rvc_inf:
9464 /* For +-NaN or +-Inf, *exp is unspecified, return arg0. */
9465 return omit_one_operand (rettype, arg0, arg1);
9466 case rvc_normal:
9468 /* Since the frexp function always expects base 2, and in
9469 GCC normalized significands are already in the range
9470 [0.5, 1.0), we have exactly what frexp wants. */
9471 REAL_VALUE_TYPE frac_rvt = *value;
9472 SET_REAL_EXP (&frac_rvt, 0);
9473 frac = build_real (rettype, frac_rvt);
9474 exp = build_int_cst (NULL_TREE, REAL_EXP (value));
9476 break;
9477 default:
9478 gcc_unreachable ();
9481 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9482 arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1, exp);
9483 TREE_SIDE_EFFECTS (arg1) = 1;
9484 return fold_build2 (COMPOUND_EXPR, rettype, arg1, frac);
9487 return NULL_TREE;
9490 /* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true
9491 then we can assume the base is two. If it's false, then we have to
9492 check the mode of the TYPE parameter in certain cases. */
9494 static tree
9495 fold_builtin_load_exponent (tree arg0, tree arg1, tree type, bool ldexp)
9497 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9499 STRIP_NOPS (arg0);
9500 STRIP_NOPS (arg1);
9502 /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */
9503 if (real_zerop (arg0) || integer_zerop (arg1)
9504 || (TREE_CODE (arg0) == REAL_CST
9505 && !real_isfinite (&TREE_REAL_CST (arg0))))
9506 return omit_one_operand (type, arg0, arg1);
9508 /* If both arguments are constant, then try to evaluate it. */
9509 if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9510 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9511 && host_integerp (arg1, 0))
9513 /* Bound the maximum adjustment to twice the range of the
9514 mode's valid exponents. Use abs to ensure the range is
9515 positive as a sanity check. */
9516 const long max_exp_adj = 2 *
9517 labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9518 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9520 /* Get the user-requested adjustment. */
9521 const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9523 /* The requested adjustment must be inside this range. This
9524 is a preliminary cap to avoid things like overflow, we
9525 may still fail to compute the result for other reasons. */
9526 if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9528 REAL_VALUE_TYPE initial_result;
9530 real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9532 /* Ensure we didn't overflow. */
9533 if (! real_isinf (&initial_result))
9535 const REAL_VALUE_TYPE trunc_result
9536 = real_value_truncate (TYPE_MODE (type), initial_result);
9538 /* Only proceed if the target mode can hold the
9539 resulting value. */
9540 if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9541 return build_real (type, trunc_result);
9547 return NULL_TREE;
9550 /* Fold a call to builtin modf. */
9552 static tree
9553 fold_builtin_modf (tree arg0, tree arg1, tree rettype)
9555 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9556 return NULL_TREE;
9558 STRIP_NOPS (arg0);
9560 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9561 return NULL_TREE;
9563 arg1 = build_fold_indirect_ref (arg1);
9565 /* Proceed if a valid pointer type was passed in. */
9566 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9568 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9569 REAL_VALUE_TYPE trunc, frac;
9571 switch (value->cl)
9573 case rvc_nan:
9574 case rvc_zero:
9575 /* For +-NaN or +-0, return (*arg1 = arg0, arg0). */
9576 trunc = frac = *value;
9577 break;
9578 case rvc_inf:
9579 /* For +-Inf, return (*arg1 = arg0, +-0). */
9580 frac = dconst0;
9581 frac.sign = value->sign;
9582 trunc = *value;
9583 break;
9584 case rvc_normal:
9585 /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */
9586 real_trunc (&trunc, VOIDmode, value);
9587 real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9588 /* If the original number was negative and already
9589 integral, then the fractional part is -0.0. */
9590 if (value->sign && frac.cl == rvc_zero)
9591 frac.sign = value->sign;
9592 break;
9595 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9596 arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1,
9597 build_real (rettype, trunc));
9598 TREE_SIDE_EFFECTS (arg1) = 1;
9599 return fold_build2 (COMPOUND_EXPR, rettype, arg1,
9600 build_real (rettype, frac));
9603 return NULL_TREE;
9606 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9607 ARG is the argument for the call. */
9609 static tree
9610 fold_builtin_classify (tree fndecl, tree arg, int builtin_index)
9612 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9613 REAL_VALUE_TYPE r;
9615 if (!validate_arg (arg, REAL_TYPE))
9617 error ("non-floating-point argument to function %qs",
9618 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9619 return error_mark_node;
9622 switch (builtin_index)
9624 case BUILT_IN_ISINF:
9625 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9626 return omit_one_operand (type, integer_zero_node, arg);
9628 if (TREE_CODE (arg) == REAL_CST)
9630 r = TREE_REAL_CST (arg);
9631 if (real_isinf (&r))
9632 return real_compare (GT_EXPR, &r, &dconst0)
9633 ? integer_one_node : integer_minus_one_node;
9634 else
9635 return integer_zero_node;
9638 return NULL_TREE;
9640 case BUILT_IN_ISFINITE:
9641 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9642 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9643 return omit_one_operand (type, integer_one_node, arg);
9645 if (TREE_CODE (arg) == REAL_CST)
9647 r = TREE_REAL_CST (arg);
9648 return real_isfinite (&r) ? integer_one_node : integer_zero_node;
9651 return NULL_TREE;
9653 case BUILT_IN_ISNAN:
9654 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
9655 return omit_one_operand (type, integer_zero_node, arg);
9657 if (TREE_CODE (arg) == REAL_CST)
9659 r = TREE_REAL_CST (arg);
9660 return real_isnan (&r) ? integer_one_node : integer_zero_node;
9663 arg = builtin_save_expr (arg);
9664 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
9666 default:
9667 gcc_unreachable ();
9671 /* Fold a call to an unordered comparison function such as
9672 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
9673 being called and ARG0 and ARG1 are the arguments for the call.
9674 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9675 the opposite of the desired result. UNORDERED_CODE is used
9676 for modes that can hold NaNs and ORDERED_CODE is used for
9677 the rest. */
9679 static tree
9680 fold_builtin_unordered_cmp (tree fndecl, tree arg0, tree arg1,
9681 enum tree_code unordered_code,
9682 enum tree_code ordered_code)
9684 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9685 enum tree_code code;
9686 tree type0, type1;
9687 enum tree_code code0, code1;
9688 tree cmp_type = NULL_TREE;
9690 type0 = TREE_TYPE (arg0);
9691 type1 = TREE_TYPE (arg1);
9693 code0 = TREE_CODE (type0);
9694 code1 = TREE_CODE (type1);
9696 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
9697 /* Choose the wider of two real types. */
9698 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
9699 ? type0 : type1;
9700 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
9701 cmp_type = type0;
9702 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
9703 cmp_type = type1;
9704 else
9706 error ("non-floating-point argument to function %qs",
9707 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9708 return error_mark_node;
9711 arg0 = fold_convert (cmp_type, arg0);
9712 arg1 = fold_convert (cmp_type, arg1);
9714 if (unordered_code == UNORDERED_EXPR)
9716 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
9717 return omit_two_operands (type, integer_zero_node, arg0, arg1);
9718 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
9721 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9722 : ordered_code;
9723 return fold_build1 (TRUTH_NOT_EXPR, type,
9724 fold_build2 (code, type, arg0, arg1));
9727 /* Fold a call to built-in function FNDECL with 0 arguments.
9728 IGNORE is true if the result of the function call is ignored. This
9729 function returns NULL_TREE if no simplification was possible. */
9731 static tree
9732 fold_builtin_0 (tree fndecl, bool ignore ATTRIBUTE_UNUSED)
9734 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9735 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9736 switch (fcode)
9738 CASE_FLT_FN (BUILT_IN_INF):
9739 case BUILT_IN_INFD32:
9740 case BUILT_IN_INFD64:
9741 case BUILT_IN_INFD128:
9742 return fold_builtin_inf (type, true);
9744 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9745 return fold_builtin_inf (type, false);
9747 case BUILT_IN_CLASSIFY_TYPE:
9748 return fold_builtin_classify_type (NULL_TREE);
9750 default:
9751 break;
9753 return NULL_TREE;
9756 /* Fold a call to built-in function FNDECL with 1 argument, ARG0.
9757 IGNORE is true if the result of the function call is ignored. This
9758 function returns NULL_TREE if no simplification was possible. */
9760 static tree
9761 fold_builtin_1 (tree fndecl, tree arg0, bool ignore)
9763 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9764 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9765 switch (fcode)
9768 case BUILT_IN_CONSTANT_P:
9770 tree val = fold_builtin_constant_p (arg0);
9772 /* Gimplification will pull the CALL_EXPR for the builtin out of
9773 an if condition. When not optimizing, we'll not CSE it back.
9774 To avoid link error types of regressions, return false now. */
9775 if (!val && !optimize)
9776 val = integer_zero_node;
9778 return val;
9781 case BUILT_IN_CLASSIFY_TYPE:
9782 return fold_builtin_classify_type (arg0);
9784 case BUILT_IN_STRLEN:
9785 return fold_builtin_strlen (arg0);
9787 CASE_FLT_FN (BUILT_IN_FABS):
9788 return fold_builtin_fabs (arg0, type);
9790 case BUILT_IN_ABS:
9791 case BUILT_IN_LABS:
9792 case BUILT_IN_LLABS:
9793 case BUILT_IN_IMAXABS:
9794 return fold_builtin_abs (arg0, type);
9796 CASE_FLT_FN (BUILT_IN_CONJ):
9797 if (validate_arg (arg0, COMPLEX_TYPE))
9798 return fold_build1 (CONJ_EXPR, type, arg0);
9799 break;
9801 CASE_FLT_FN (BUILT_IN_CREAL):
9802 if (validate_arg (arg0, COMPLEX_TYPE))
9803 return non_lvalue (fold_build1 (REALPART_EXPR, type, arg0));;
9804 break;
9806 CASE_FLT_FN (BUILT_IN_CIMAG):
9807 if (validate_arg (arg0, COMPLEX_TYPE))
9808 return non_lvalue (fold_build1 (IMAGPART_EXPR, type, arg0));
9809 break;
9811 CASE_FLT_FN (BUILT_IN_CCOS):
9812 CASE_FLT_FN (BUILT_IN_CCOSH):
9813 /* These functions are "even", i.e. f(x) == f(-x). */
9814 if (validate_arg (arg0, COMPLEX_TYPE))
9816 tree narg = fold_strip_sign_ops (arg0);
9817 if (narg)
9818 return build_call_expr (fndecl, 1, narg);
9820 break;
9822 CASE_FLT_FN (BUILT_IN_CABS):
9823 return fold_builtin_cabs (arg0, type, fndecl);
9825 CASE_FLT_FN (BUILT_IN_CARG):
9826 return fold_builtin_carg (arg0, type);
9828 CASE_FLT_FN (BUILT_IN_SQRT):
9829 return fold_builtin_sqrt (arg0, type);
9831 CASE_FLT_FN (BUILT_IN_CBRT):
9832 return fold_builtin_cbrt (arg0, type);
9834 CASE_FLT_FN (BUILT_IN_ASIN):
9835 if (validate_arg (arg0, REAL_TYPE))
9836 return do_mpfr_arg1 (arg0, type, mpfr_asin,
9837 &dconstm1, &dconst1, true);
9838 break;
9840 CASE_FLT_FN (BUILT_IN_ACOS):
9841 if (validate_arg (arg0, REAL_TYPE))
9842 return do_mpfr_arg1 (arg0, type, mpfr_acos,
9843 &dconstm1, &dconst1, true);
9844 break;
9846 CASE_FLT_FN (BUILT_IN_ATAN):
9847 if (validate_arg (arg0, REAL_TYPE))
9848 return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
9849 break;
9851 CASE_FLT_FN (BUILT_IN_ASINH):
9852 if (validate_arg (arg0, REAL_TYPE))
9853 return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
9854 break;
9856 CASE_FLT_FN (BUILT_IN_ACOSH):
9857 if (validate_arg (arg0, REAL_TYPE))
9858 return do_mpfr_arg1 (arg0, type, mpfr_acosh,
9859 &dconst1, NULL, true);
9860 break;
9862 CASE_FLT_FN (BUILT_IN_ATANH):
9863 if (validate_arg (arg0, REAL_TYPE))
9864 return do_mpfr_arg1 (arg0, type, mpfr_atanh,
9865 &dconstm1, &dconst1, false);
9866 break;
9868 CASE_FLT_FN (BUILT_IN_SIN):
9869 if (validate_arg (arg0, REAL_TYPE))
9870 return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
9871 break;
9873 CASE_FLT_FN (BUILT_IN_COS):
9874 return fold_builtin_cos (arg0, type, fndecl);
9875 break;
9877 CASE_FLT_FN (BUILT_IN_TAN):
9878 return fold_builtin_tan (arg0, type);
9880 CASE_FLT_FN (BUILT_IN_CEXP):
9881 return fold_builtin_cexp (arg0, type);
9883 CASE_FLT_FN (BUILT_IN_CEXPI):
9884 if (validate_arg (arg0, REAL_TYPE))
9885 return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
9886 break;
9888 CASE_FLT_FN (BUILT_IN_SINH):
9889 if (validate_arg (arg0, REAL_TYPE))
9890 return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
9891 break;
9893 CASE_FLT_FN (BUILT_IN_COSH):
9894 return fold_builtin_cosh (arg0, type, fndecl);
9896 CASE_FLT_FN (BUILT_IN_TANH):
9897 if (validate_arg (arg0, REAL_TYPE))
9898 return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
9899 break;
9901 CASE_FLT_FN (BUILT_IN_ERF):
9902 if (validate_arg (arg0, REAL_TYPE))
9903 return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
9904 break;
9906 CASE_FLT_FN (BUILT_IN_ERFC):
9907 if (validate_arg (arg0, REAL_TYPE))
9908 return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
9909 break;
9911 CASE_FLT_FN (BUILT_IN_TGAMMA):
9912 if (validate_arg (arg0, REAL_TYPE))
9913 return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
9914 break;
9916 CASE_FLT_FN (BUILT_IN_EXP):
9917 return fold_builtin_exponent (fndecl, arg0, mpfr_exp);
9919 CASE_FLT_FN (BUILT_IN_EXP2):
9920 return fold_builtin_exponent (fndecl, arg0, mpfr_exp2);
9922 CASE_FLT_FN (BUILT_IN_EXP10):
9923 CASE_FLT_FN (BUILT_IN_POW10):
9924 return fold_builtin_exponent (fndecl, arg0, mpfr_exp10);
9926 CASE_FLT_FN (BUILT_IN_EXPM1):
9927 if (validate_arg (arg0, REAL_TYPE))
9928 return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
9929 break;
9931 CASE_FLT_FN (BUILT_IN_LOG):
9932 return fold_builtin_logarithm (fndecl, arg0, mpfr_log);
9934 CASE_FLT_FN (BUILT_IN_LOG2):
9935 return fold_builtin_logarithm (fndecl, arg0, mpfr_log2);
9937 CASE_FLT_FN (BUILT_IN_LOG10):
9938 return fold_builtin_logarithm (fndecl, arg0, mpfr_log10);
9940 CASE_FLT_FN (BUILT_IN_LOG1P):
9941 if (validate_arg (arg0, REAL_TYPE))
9942 return do_mpfr_arg1 (arg0, type, mpfr_log1p,
9943 &dconstm1, NULL, false);
9944 break;
9946 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
9947 CASE_FLT_FN (BUILT_IN_J0):
9948 if (validate_arg (arg0, REAL_TYPE))
9949 return do_mpfr_arg1 (arg0, type, mpfr_j0,
9950 NULL, NULL, 0);
9951 break;
9953 CASE_FLT_FN (BUILT_IN_J1):
9954 if (validate_arg (arg0, REAL_TYPE))
9955 return do_mpfr_arg1 (arg0, type, mpfr_j1,
9956 NULL, NULL, 0);
9957 break;
9959 CASE_FLT_FN (BUILT_IN_Y0):
9960 if (validate_arg (arg0, REAL_TYPE))
9961 return do_mpfr_arg1 (arg0, type, mpfr_y0,
9962 &dconst0, NULL, false);
9963 break;
9965 CASE_FLT_FN (BUILT_IN_Y1):
9966 if (validate_arg (arg0, REAL_TYPE))
9967 return do_mpfr_arg1 (arg0, type, mpfr_y1,
9968 &dconst0, NULL, false);
9969 break;
9970 #endif
9972 CASE_FLT_FN (BUILT_IN_NAN):
9973 case BUILT_IN_NAND32:
9974 case BUILT_IN_NAND64:
9975 case BUILT_IN_NAND128:
9976 return fold_builtin_nan (arg0, type, true);
9978 CASE_FLT_FN (BUILT_IN_NANS):
9979 return fold_builtin_nan (arg0, type, false);
9981 CASE_FLT_FN (BUILT_IN_FLOOR):
9982 return fold_builtin_floor (fndecl, arg0);
9984 CASE_FLT_FN (BUILT_IN_CEIL):
9985 return fold_builtin_ceil (fndecl, arg0);
9987 CASE_FLT_FN (BUILT_IN_TRUNC):
9988 return fold_builtin_trunc (fndecl, arg0);
9990 CASE_FLT_FN (BUILT_IN_ROUND):
9991 return fold_builtin_round (fndecl, arg0);
9993 CASE_FLT_FN (BUILT_IN_NEARBYINT):
9994 CASE_FLT_FN (BUILT_IN_RINT):
9995 return fold_trunc_transparent_mathfn (fndecl, arg0);
9997 CASE_FLT_FN (BUILT_IN_LCEIL):
9998 CASE_FLT_FN (BUILT_IN_LLCEIL):
9999 CASE_FLT_FN (BUILT_IN_LFLOOR):
10000 CASE_FLT_FN (BUILT_IN_LLFLOOR):
10001 CASE_FLT_FN (BUILT_IN_LROUND):
10002 CASE_FLT_FN (BUILT_IN_LLROUND):
10003 return fold_builtin_int_roundingfn (fndecl, arg0);
10005 CASE_FLT_FN (BUILT_IN_LRINT):
10006 CASE_FLT_FN (BUILT_IN_LLRINT):
10007 return fold_fixed_mathfn (fndecl, arg0);
10009 case BUILT_IN_BSWAP32:
10010 case BUILT_IN_BSWAP64:
10011 return fold_builtin_bswap (fndecl, arg0);
10013 CASE_INT_FN (BUILT_IN_FFS):
10014 CASE_INT_FN (BUILT_IN_CLZ):
10015 CASE_INT_FN (BUILT_IN_CTZ):
10016 CASE_INT_FN (BUILT_IN_POPCOUNT):
10017 CASE_INT_FN (BUILT_IN_PARITY):
10018 return fold_builtin_bitop (fndecl, arg0);
10020 CASE_FLT_FN (BUILT_IN_SIGNBIT):
10021 return fold_builtin_signbit (arg0, type);
10023 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10024 return fold_builtin_significand (arg0, type);
10026 CASE_FLT_FN (BUILT_IN_ILOGB):
10027 CASE_FLT_FN (BUILT_IN_LOGB):
10028 return fold_builtin_logb (arg0, type);
10030 case BUILT_IN_ISASCII:
10031 return fold_builtin_isascii (arg0);
10033 case BUILT_IN_TOASCII:
10034 return fold_builtin_toascii (arg0);
10036 case BUILT_IN_ISDIGIT:
10037 return fold_builtin_isdigit (arg0);
10039 CASE_FLT_FN (BUILT_IN_FINITE):
10040 case BUILT_IN_FINITED32:
10041 case BUILT_IN_FINITED64:
10042 case BUILT_IN_FINITED128:
10043 case BUILT_IN_ISFINITE:
10044 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISFINITE);
10046 CASE_FLT_FN (BUILT_IN_ISINF):
10047 case BUILT_IN_ISINFD32:
10048 case BUILT_IN_ISINFD64:
10049 case BUILT_IN_ISINFD128:
10050 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF);
10052 CASE_FLT_FN (BUILT_IN_ISNAN):
10053 case BUILT_IN_ISNAND32:
10054 case BUILT_IN_ISNAND64:
10055 case BUILT_IN_ISNAND128:
10056 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISNAN);
10058 case BUILT_IN_PRINTF:
10059 case BUILT_IN_PRINTF_UNLOCKED:
10060 case BUILT_IN_VPRINTF:
10061 return fold_builtin_printf (fndecl, arg0, NULL_TREE, ignore, fcode);
10063 default:
10064 break;
10067 return NULL_TREE;
10071 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10072 IGNORE is true if the result of the function call is ignored. This
10073 function returns NULL_TREE if no simplification was possible. */
10075 static tree
10076 fold_builtin_2 (tree fndecl, tree arg0, tree arg1, bool ignore)
10078 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10079 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10081 switch (fcode)
10083 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
10084 CASE_FLT_FN (BUILT_IN_JN):
10085 if (validate_arg (arg0, INTEGER_TYPE)
10086 && validate_arg (arg1, REAL_TYPE))
10087 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10088 break;
10090 CASE_FLT_FN (BUILT_IN_YN):
10091 if (validate_arg (arg0, INTEGER_TYPE)
10092 && validate_arg (arg1, REAL_TYPE))
10093 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10094 &dconst0, false);
10095 break;
10097 CASE_FLT_FN (BUILT_IN_DREM):
10098 CASE_FLT_FN (BUILT_IN_REMAINDER):
10099 if (validate_arg (arg0, REAL_TYPE)
10100 && validate_arg(arg1, REAL_TYPE))
10101 return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10102 break;
10104 CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10105 CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10106 if (validate_arg (arg0, REAL_TYPE)
10107 && validate_arg(arg1, POINTER_TYPE))
10108 return do_mpfr_lgamma_r (arg0, arg1, type);
10109 break;
10110 #endif
10112 CASE_FLT_FN (BUILT_IN_ATAN2):
10113 if (validate_arg (arg0, REAL_TYPE)
10114 && validate_arg(arg1, REAL_TYPE))
10115 return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10116 break;
10118 CASE_FLT_FN (BUILT_IN_FDIM):
10119 if (validate_arg (arg0, REAL_TYPE)
10120 && validate_arg(arg1, REAL_TYPE))
10121 return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10122 break;
10124 CASE_FLT_FN (BUILT_IN_HYPOT):
10125 return fold_builtin_hypot (fndecl, arg0, arg1, type);
10127 CASE_FLT_FN (BUILT_IN_LDEXP):
10128 return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/true);
10129 CASE_FLT_FN (BUILT_IN_SCALBN):
10130 CASE_FLT_FN (BUILT_IN_SCALBLN):
10131 return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/false);
10133 CASE_FLT_FN (BUILT_IN_FREXP):
10134 return fold_builtin_frexp (arg0, arg1, type);
10136 CASE_FLT_FN (BUILT_IN_MODF):
10137 return fold_builtin_modf (arg0, arg1, type);
10139 case BUILT_IN_BZERO:
10140 return fold_builtin_bzero (arg0, arg1, ignore);
10142 case BUILT_IN_FPUTS:
10143 return fold_builtin_fputs (arg0, arg1, ignore, false, NULL_TREE);
10145 case BUILT_IN_FPUTS_UNLOCKED:
10146 return fold_builtin_fputs (arg0, arg1, ignore, true, NULL_TREE);
10148 case BUILT_IN_STRSTR:
10149 return fold_builtin_strstr (arg0, arg1, type);
10151 case BUILT_IN_STRCAT:
10152 return fold_builtin_strcat (arg0, arg1);
10154 case BUILT_IN_STRSPN:
10155 return fold_builtin_strspn (arg0, arg1);
10157 case BUILT_IN_STRCSPN:
10158 return fold_builtin_strcspn (arg0, arg1);
10160 case BUILT_IN_STRCHR:
10161 case BUILT_IN_INDEX:
10162 return fold_builtin_strchr (arg0, arg1, type);
10164 case BUILT_IN_STRRCHR:
10165 case BUILT_IN_RINDEX:
10166 return fold_builtin_strrchr (arg0, arg1, type);
10168 case BUILT_IN_STRCPY:
10169 return fold_builtin_strcpy (fndecl, arg0, arg1, NULL_TREE);
10171 case BUILT_IN_STRCMP:
10172 return fold_builtin_strcmp (arg0, arg1);
10174 case BUILT_IN_STRPBRK:
10175 return fold_builtin_strpbrk (arg0, arg1, type);
10177 case BUILT_IN_EXPECT:
10178 return fold_builtin_expect (arg0, arg1);
10180 CASE_FLT_FN (BUILT_IN_POW):
10181 return fold_builtin_pow (fndecl, arg0, arg1, type);
10183 CASE_FLT_FN (BUILT_IN_POWI):
10184 return fold_builtin_powi (fndecl, arg0, arg1, type);
10186 CASE_FLT_FN (BUILT_IN_COPYSIGN):
10187 return fold_builtin_copysign (fndecl, arg0, arg1, type);
10189 CASE_FLT_FN (BUILT_IN_FMIN):
10190 return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/false);
10192 CASE_FLT_FN (BUILT_IN_FMAX):
10193 return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/true);
10195 case BUILT_IN_ISGREATER:
10196 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLE_EXPR, LE_EXPR);
10197 case BUILT_IN_ISGREATEREQUAL:
10198 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLT_EXPR, LT_EXPR);
10199 case BUILT_IN_ISLESS:
10200 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGE_EXPR, GE_EXPR);
10201 case BUILT_IN_ISLESSEQUAL:
10202 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGT_EXPR, GT_EXPR);
10203 case BUILT_IN_ISLESSGREATER:
10204 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNEQ_EXPR, EQ_EXPR);
10205 case BUILT_IN_ISUNORDERED:
10206 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNORDERED_EXPR,
10207 NOP_EXPR);
10209 /* We do the folding for va_start in the expander. */
10210 case BUILT_IN_VA_START:
10211 break;
10213 case BUILT_IN_SPRINTF:
10214 return fold_builtin_sprintf (arg0, arg1, NULL_TREE, ignore);
10216 case BUILT_IN_OBJECT_SIZE:
10217 return fold_builtin_object_size (arg0, arg1);
10219 case BUILT_IN_PRINTF:
10220 case BUILT_IN_PRINTF_UNLOCKED:
10221 case BUILT_IN_VPRINTF:
10222 return fold_builtin_printf (fndecl, arg0, arg1, ignore, fcode);
10224 case BUILT_IN_PRINTF_CHK:
10225 case BUILT_IN_VPRINTF_CHK:
10226 if (!validate_arg (arg0, INTEGER_TYPE)
10227 || TREE_SIDE_EFFECTS (arg0))
10228 return NULL_TREE;
10229 else
10230 return fold_builtin_printf (fndecl, arg1, NULL_TREE, ignore, fcode);
10231 break;
10233 case BUILT_IN_FPRINTF:
10234 case BUILT_IN_FPRINTF_UNLOCKED:
10235 case BUILT_IN_VFPRINTF:
10236 return fold_builtin_fprintf (fndecl, arg0, arg1, NULL_TREE,
10237 ignore, fcode);
10239 default:
10240 break;
10242 return NULL_TREE;
10245 /* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10246 and ARG2. IGNORE is true if the result of the function call is ignored.
10247 This function returns NULL_TREE if no simplification was possible. */
10249 static tree
10250 fold_builtin_3 (tree fndecl, tree arg0, tree arg1, tree arg2, bool ignore)
10252 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10253 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10254 switch (fcode)
10257 CASE_FLT_FN (BUILT_IN_SINCOS):
10258 return fold_builtin_sincos (arg0, arg1, arg2);
10260 CASE_FLT_FN (BUILT_IN_FMA):
10261 if (validate_arg (arg0, REAL_TYPE)
10262 && validate_arg(arg1, REAL_TYPE)
10263 && validate_arg(arg2, REAL_TYPE))
10264 return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
10265 break;
10267 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
10268 CASE_FLT_FN (BUILT_IN_REMQUO):
10269 if (validate_arg (arg0, REAL_TYPE)
10270 && validate_arg(arg1, REAL_TYPE)
10271 && validate_arg(arg2, POINTER_TYPE))
10272 return do_mpfr_remquo (arg0, arg1, arg2);
10273 break;
10274 #endif
10276 case BUILT_IN_MEMSET:
10277 return fold_builtin_memset (arg0, arg1, arg2, type, ignore);
10279 case BUILT_IN_BCOPY:
10280 return fold_builtin_memory_op (arg1, arg0, arg2, void_type_node, true, /*endp=*/3);
10282 case BUILT_IN_MEMCPY:
10283 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/0);
10285 case BUILT_IN_MEMPCPY:
10286 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/1);
10288 case BUILT_IN_MEMMOVE:
10289 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/3);
10291 case BUILT_IN_STRNCAT:
10292 return fold_builtin_strncat (arg0, arg1, arg2);
10294 case BUILT_IN_STRNCPY:
10295 return fold_builtin_strncpy (fndecl, arg0, arg1, arg2, NULL_TREE);
10297 case BUILT_IN_STRNCMP:
10298 return fold_builtin_strncmp (arg0, arg1, arg2);
10300 case BUILT_IN_MEMCHR:
10301 return fold_builtin_memchr (arg0, arg1, arg2, type);
10303 case BUILT_IN_BCMP:
10304 case BUILT_IN_MEMCMP:
10305 return fold_builtin_memcmp (arg0, arg1, arg2);;
10307 case BUILT_IN_SPRINTF:
10308 return fold_builtin_sprintf (arg0, arg1, arg2, ignore);
10310 case BUILT_IN_STRCPY_CHK:
10311 case BUILT_IN_STPCPY_CHK:
10312 return fold_builtin_stxcpy_chk (fndecl, arg0, arg1, arg2, NULL_TREE,
10313 ignore, fcode);
10315 case BUILT_IN_STRCAT_CHK:
10316 return fold_builtin_strcat_chk (fndecl, arg0, arg1, arg2);
10318 case BUILT_IN_PRINTF_CHK:
10319 case BUILT_IN_VPRINTF_CHK:
10320 if (!validate_arg (arg0, INTEGER_TYPE)
10321 || TREE_SIDE_EFFECTS (arg0))
10322 return NULL_TREE;
10323 else
10324 return fold_builtin_printf (fndecl, arg1, arg2, ignore, fcode);
10325 break;
10327 case BUILT_IN_FPRINTF:
10328 case BUILT_IN_FPRINTF_UNLOCKED:
10329 case BUILT_IN_VFPRINTF:
10330 return fold_builtin_fprintf (fndecl, arg0, arg1, arg2, ignore, fcode);
10332 case BUILT_IN_FPRINTF_CHK:
10333 case BUILT_IN_VFPRINTF_CHK:
10334 if (!validate_arg (arg1, INTEGER_TYPE)
10335 || TREE_SIDE_EFFECTS (arg1))
10336 return NULL_TREE;
10337 else
10338 return fold_builtin_fprintf (fndecl, arg0, arg2, NULL_TREE,
10339 ignore, fcode);
10341 default:
10342 break;
10344 return NULL_TREE;
10347 /* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10348 ARG2, and ARG3. IGNORE is true if the result of the function call is
10349 ignored. This function returns NULL_TREE if no simplification was
10350 possible. */
10352 static tree
10353 fold_builtin_4 (tree fndecl, tree arg0, tree arg1, tree arg2, tree arg3,
10354 bool ignore)
10356 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10358 switch (fcode)
10360 case BUILT_IN_MEMCPY_CHK:
10361 case BUILT_IN_MEMPCPY_CHK:
10362 case BUILT_IN_MEMMOVE_CHK:
10363 case BUILT_IN_MEMSET_CHK:
10364 return fold_builtin_memory_chk (fndecl, arg0, arg1, arg2, arg3,
10365 NULL_TREE, ignore,
10366 DECL_FUNCTION_CODE (fndecl));
10368 case BUILT_IN_STRNCPY_CHK:
10369 return fold_builtin_strncpy_chk (arg0, arg1, arg2, arg3, NULL_TREE);
10371 case BUILT_IN_STRNCAT_CHK:
10372 return fold_builtin_strncat_chk (fndecl, arg0, arg1, arg2, arg3);
10374 case BUILT_IN_FPRINTF_CHK:
10375 case BUILT_IN_VFPRINTF_CHK:
10376 if (!validate_arg (arg1, INTEGER_TYPE)
10377 || TREE_SIDE_EFFECTS (arg1))
10378 return NULL_TREE;
10379 else
10380 return fold_builtin_fprintf (fndecl, arg0, arg2, arg3,
10381 ignore, fcode);
10382 break;
10384 default:
10385 break;
10387 return NULL_TREE;
10390 /* Fold a call to built-in function FNDECL. ARGS is an array of NARGS
10391 arguments, where NARGS <= 4. IGNORE is true if the result of the
10392 function call is ignored. This function returns NULL_TREE if no
10393 simplification was possible. Note that this only folds builtins with
10394 fixed argument patterns. Foldings that do varargs-to-varargs
10395 transformations, or that match calls with more than 4 arguments,
10396 need to be handled with fold_builtin_varargs instead. */
10398 #define MAX_ARGS_TO_FOLD_BUILTIN 4
10400 static tree
10401 fold_builtin_n (tree fndecl, tree *args, int nargs, bool ignore)
10403 tree ret = NULL_TREE;
10404 switch (nargs)
10406 case 0:
10407 ret = fold_builtin_0 (fndecl, ignore);
10408 break;
10409 case 1:
10410 ret = fold_builtin_1 (fndecl, args[0], ignore);
10411 break;
10412 case 2:
10413 ret = fold_builtin_2 (fndecl, args[0], args[1], ignore);
10414 break;
10415 case 3:
10416 ret = fold_builtin_3 (fndecl, args[0], args[1], args[2], ignore);
10417 break;
10418 case 4:
10419 ret = fold_builtin_4 (fndecl, args[0], args[1], args[2], args[3],
10420 ignore);
10421 break;
10422 default:
10423 break;
10425 if (ret)
10427 ret = build1 (NOP_EXPR, GENERIC_TREE_TYPE (ret), ret);
10428 TREE_NO_WARNING (ret) = 1;
10429 return ret;
10431 return NULL_TREE;
10434 /* Builtins with folding operations that operate on "..." arguments
10435 need special handling; we need to store the arguments in a convenient
10436 data structure before attempting any folding. Fortunately there are
10437 only a few builtins that fall into this category. FNDECL is the
10438 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
10439 result of the function call is ignored. */
10441 static tree
10442 fold_builtin_varargs (tree fndecl, tree exp, bool ignore ATTRIBUTE_UNUSED)
10444 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10445 tree ret = NULL_TREE;
10447 switch (fcode)
10449 case BUILT_IN_SPRINTF_CHK:
10450 case BUILT_IN_VSPRINTF_CHK:
10451 ret = fold_builtin_sprintf_chk (exp, fcode);
10452 break;
10454 case BUILT_IN_SNPRINTF_CHK:
10455 case BUILT_IN_VSNPRINTF_CHK:
10456 ret = fold_builtin_snprintf_chk (exp, NULL_TREE, fcode);
10458 default:
10459 break;
10461 if (ret)
10463 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
10464 TREE_NO_WARNING (ret) = 1;
10465 return ret;
10467 return NULL_TREE;
10470 /* A wrapper function for builtin folding that prevents warnings for
10471 "statement without effect" and the like, caused by removing the
10472 call node earlier than the warning is generated. */
10474 tree
10475 fold_call_expr (tree exp, bool ignore)
10477 tree ret = NULL_TREE;
10478 tree fndecl = get_callee_fndecl (exp);
10479 if (fndecl
10480 && TREE_CODE (fndecl) == FUNCTION_DECL
10481 && DECL_BUILT_IN (fndecl)
10482 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
10483 yet. Defer folding until we see all the arguments
10484 (after inlining). */
10485 && !CALL_EXPR_VA_ARG_PACK (exp))
10487 int nargs = call_expr_nargs (exp);
10489 /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
10490 instead last argument is __builtin_va_arg_pack (). Defer folding
10491 even in that case, until arguments are finalized. */
10492 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
10494 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
10495 if (fndecl2
10496 && TREE_CODE (fndecl2) == FUNCTION_DECL
10497 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10498 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10499 return NULL_TREE;
10502 /* FIXME: Don't use a list in this interface. */
10503 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10504 return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
10505 else
10507 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
10509 tree *args = CALL_EXPR_ARGP (exp);
10510 ret = fold_builtin_n (fndecl, args, nargs, ignore);
10512 if (!ret)
10513 ret = fold_builtin_varargs (fndecl, exp, ignore);
10514 if (ret)
10516 /* Propagate location information from original call to
10517 expansion of builtin. Otherwise things like
10518 maybe_emit_chk_warning, that operate on the expansion
10519 of a builtin, will use the wrong location information. */
10520 if (CAN_HAVE_LOCATION_P (exp) && EXPR_HAS_LOCATION (exp))
10522 tree realret = ret;
10523 if (TREE_CODE (ret) == NOP_EXPR)
10524 realret = TREE_OPERAND (ret, 0);
10525 if (CAN_HAVE_LOCATION_P (realret)
10526 && !EXPR_HAS_LOCATION (realret))
10527 SET_EXPR_LOCATION (realret, EXPR_LOCATION (exp));
10529 return ret;
10533 return NULL_TREE;
10536 /* Conveniently construct a function call expression. FNDECL names the
10537 function to be called and ARGLIST is a TREE_LIST of arguments. */
10539 tree
10540 build_function_call_expr (tree fndecl, tree arglist)
10542 tree fntype = TREE_TYPE (fndecl);
10543 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10544 int n = list_length (arglist);
10545 tree *argarray = (tree *) alloca (n * sizeof (tree));
10546 int i;
10548 for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
10549 argarray[i] = TREE_VALUE (arglist);
10550 return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
10553 /* Conveniently construct a function call expression. FNDECL names the
10554 function to be called, N is the number of arguments, and the "..."
10555 parameters are the argument expressions. */
10557 tree
10558 build_call_expr (tree fndecl, int n, ...)
10560 va_list ap;
10561 tree fntype = TREE_TYPE (fndecl);
10562 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10563 tree *argarray = (tree *) alloca (n * sizeof (tree));
10564 int i;
10566 va_start (ap, n);
10567 for (i = 0; i < n; i++)
10568 argarray[i] = va_arg (ap, tree);
10569 va_end (ap);
10570 return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
10573 /* Construct a CALL_EXPR with type TYPE with FN as the function expression.
10574 N arguments are passed in the array ARGARRAY. */
10576 tree
10577 fold_builtin_call_array (tree type,
10578 tree fn,
10579 int n,
10580 tree *argarray)
10582 tree ret = NULL_TREE;
10583 int i;
10584 tree exp;
10586 if (TREE_CODE (fn) == ADDR_EXPR)
10588 tree fndecl = TREE_OPERAND (fn, 0);
10589 if (TREE_CODE (fndecl) == FUNCTION_DECL
10590 && DECL_BUILT_IN (fndecl))
10592 /* If last argument is __builtin_va_arg_pack (), arguments to this
10593 function are not finalized yet. Defer folding until they are. */
10594 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
10596 tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
10597 if (fndecl2
10598 && TREE_CODE (fndecl2) == FUNCTION_DECL
10599 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10600 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10601 return build_call_array (type, fn, n, argarray);
10603 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10605 tree arglist = NULL_TREE;
10606 for (i = n - 1; i >= 0; i--)
10607 arglist = tree_cons (NULL_TREE, argarray[i], arglist);
10608 ret = targetm.fold_builtin (fndecl, arglist, false);
10609 if (ret)
10610 return ret;
10612 else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
10614 /* First try the transformations that don't require consing up
10615 an exp. */
10616 ret = fold_builtin_n (fndecl, argarray, n, false);
10617 if (ret)
10618 return ret;
10621 /* If we got this far, we need to build an exp. */
10622 exp = build_call_array (type, fn, n, argarray);
10623 ret = fold_builtin_varargs (fndecl, exp, false);
10624 return ret ? ret : exp;
10628 return build_call_array (type, fn, n, argarray);
10631 /* Construct a new CALL_EXPR using the tail of the argument list of EXP
10632 along with N new arguments specified as the "..." parameters. SKIP
10633 is the number of arguments in EXP to be omitted. This function is used
10634 to do varargs-to-varargs transformations. */
10636 static tree
10637 rewrite_call_expr (tree exp, int skip, tree fndecl, int n, ...)
10639 int oldnargs = call_expr_nargs (exp);
10640 int nargs = oldnargs - skip + n;
10641 tree fntype = TREE_TYPE (fndecl);
10642 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10643 tree *buffer;
10645 if (n > 0)
10647 int i, j;
10648 va_list ap;
10650 buffer = alloca (nargs * sizeof (tree));
10651 va_start (ap, n);
10652 for (i = 0; i < n; i++)
10653 buffer[i] = va_arg (ap, tree);
10654 va_end (ap);
10655 for (j = skip; j < oldnargs; j++, i++)
10656 buffer[i] = CALL_EXPR_ARG (exp, j);
10658 else
10659 buffer = CALL_EXPR_ARGP (exp) + skip;
10661 return fold (build_call_array (TREE_TYPE (exp), fn, nargs, buffer));
10664 /* Validate a single argument ARG against a tree code CODE representing
10665 a type. */
10667 static bool
10668 validate_arg (const_tree arg, enum tree_code code)
10670 if (!arg)
10671 return false;
10672 else if (code == POINTER_TYPE)
10673 return POINTER_TYPE_P (TREE_TYPE (arg));
10674 return code == TREE_CODE (TREE_TYPE (arg));
10677 /* This function validates the types of a function call argument list
10678 against a specified list of tree_codes. If the last specifier is a 0,
10679 that represents an ellipses, otherwise the last specifier must be a
10680 VOID_TYPE. */
10682 bool
10683 validate_arglist (const_tree callexpr, ...)
10685 enum tree_code code;
10686 bool res = 0;
10687 va_list ap;
10688 const_call_expr_arg_iterator iter;
10689 const_tree arg;
10691 va_start (ap, callexpr);
10692 init_const_call_expr_arg_iterator (callexpr, &iter);
10696 code = va_arg (ap, enum tree_code);
10697 switch (code)
10699 case 0:
10700 /* This signifies an ellipses, any further arguments are all ok. */
10701 res = true;
10702 goto end;
10703 case VOID_TYPE:
10704 /* This signifies an endlink, if no arguments remain, return
10705 true, otherwise return false. */
10706 res = !more_const_call_expr_args_p (&iter);
10707 goto end;
10708 default:
10709 /* If no parameters remain or the parameter's code does not
10710 match the specified code, return false. Otherwise continue
10711 checking any remaining arguments. */
10712 arg = next_const_call_expr_arg (&iter);
10713 if (!validate_arg (arg, code))
10714 goto end;
10715 break;
10718 while (1);
10720 /* We need gotos here since we can only have one VA_CLOSE in a
10721 function. */
10722 end: ;
10723 va_end (ap);
10725 return res;
10728 /* Default target-specific builtin expander that does nothing. */
10731 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
10732 rtx target ATTRIBUTE_UNUSED,
10733 rtx subtarget ATTRIBUTE_UNUSED,
10734 enum machine_mode mode ATTRIBUTE_UNUSED,
10735 int ignore ATTRIBUTE_UNUSED)
10737 return NULL_RTX;
10740 /* Returns true is EXP represents data that would potentially reside
10741 in a readonly section. */
10743 static bool
10744 readonly_data_expr (tree exp)
10746 STRIP_NOPS (exp);
10748 if (TREE_CODE (exp) != ADDR_EXPR)
10749 return false;
10751 exp = get_base_address (TREE_OPERAND (exp, 0));
10752 if (!exp)
10753 return false;
10755 /* Make sure we call decl_readonly_section only for trees it
10756 can handle (since it returns true for everything it doesn't
10757 understand). */
10758 if (TREE_CODE (exp) == STRING_CST
10759 || TREE_CODE (exp) == CONSTRUCTOR
10760 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
10761 return decl_readonly_section (exp, 0);
10762 else
10763 return false;
10766 /* Simplify a call to the strstr builtin. S1 and S2 are the arguments
10767 to the call, and TYPE is its return type.
10769 Return NULL_TREE if no simplification was possible, otherwise return the
10770 simplified form of the call as a tree.
10772 The simplified form may be a constant or other expression which
10773 computes the same value, but in a more efficient manner (including
10774 calls to other builtin functions).
10776 The call may contain arguments which need to be evaluated, but
10777 which are not useful to determine the result of the call. In
10778 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10779 COMPOUND_EXPR will be an argument which must be evaluated.
10780 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10781 COMPOUND_EXPR in the chain will contain the tree for the simplified
10782 form of the builtin function call. */
10784 static tree
10785 fold_builtin_strstr (tree s1, tree s2, tree type)
10787 if (!validate_arg (s1, POINTER_TYPE)
10788 || !validate_arg (s2, POINTER_TYPE))
10789 return NULL_TREE;
10790 else
10792 tree fn;
10793 const char *p1, *p2;
10795 p2 = c_getstr (s2);
10796 if (p2 == NULL)
10797 return NULL_TREE;
10799 p1 = c_getstr (s1);
10800 if (p1 != NULL)
10802 const char *r = strstr (p1, p2);
10803 tree tem;
10805 if (r == NULL)
10806 return build_int_cst (TREE_TYPE (s1), 0);
10808 /* Return an offset into the constant string argument. */
10809 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
10810 s1, size_int (r - p1));
10811 return fold_convert (type, tem);
10814 /* The argument is const char *, and the result is char *, so we need
10815 a type conversion here to avoid a warning. */
10816 if (p2[0] == '\0')
10817 return fold_convert (type, s1);
10819 if (p2[1] != '\0')
10820 return NULL_TREE;
10822 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
10823 if (!fn)
10824 return NULL_TREE;
10826 /* New argument list transforming strstr(s1, s2) to
10827 strchr(s1, s2[0]). */
10828 return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
10832 /* Simplify a call to the strchr builtin. S1 and S2 are the arguments to
10833 the call, and TYPE is its return type.
10835 Return NULL_TREE if no simplification was possible, otherwise return the
10836 simplified form of the call as a tree.
10838 The simplified form may be a constant or other expression which
10839 computes the same value, but in a more efficient manner (including
10840 calls to other builtin functions).
10842 The call may contain arguments which need to be evaluated, but
10843 which are not useful to determine the result of the call. In
10844 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10845 COMPOUND_EXPR will be an argument which must be evaluated.
10846 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10847 COMPOUND_EXPR in the chain will contain the tree for the simplified
10848 form of the builtin function call. */
10850 static tree
10851 fold_builtin_strchr (tree s1, tree s2, tree type)
10853 if (!validate_arg (s1, POINTER_TYPE)
10854 || !validate_arg (s2, INTEGER_TYPE))
10855 return NULL_TREE;
10856 else
10858 const char *p1;
10860 if (TREE_CODE (s2) != INTEGER_CST)
10861 return NULL_TREE;
10863 p1 = c_getstr (s1);
10864 if (p1 != NULL)
10866 char c;
10867 const char *r;
10868 tree tem;
10870 if (target_char_cast (s2, &c))
10871 return NULL_TREE;
10873 r = strchr (p1, c);
10875 if (r == NULL)
10876 return build_int_cst (TREE_TYPE (s1), 0);
10878 /* Return an offset into the constant string argument. */
10879 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
10880 s1, size_int (r - p1));
10881 return fold_convert (type, tem);
10883 return NULL_TREE;
10887 /* Simplify a call to the strrchr builtin. S1 and S2 are the arguments to
10888 the call, and TYPE is its return type.
10890 Return NULL_TREE if no simplification was possible, otherwise return the
10891 simplified form of the call as a tree.
10893 The simplified form may be a constant or other expression which
10894 computes the same value, but in a more efficient manner (including
10895 calls to other builtin functions).
10897 The call may contain arguments which need to be evaluated, but
10898 which are not useful to determine the result of the call. In
10899 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10900 COMPOUND_EXPR will be an argument which must be evaluated.
10901 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10902 COMPOUND_EXPR in the chain will contain the tree for the simplified
10903 form of the builtin function call. */
10905 static tree
10906 fold_builtin_strrchr (tree s1, tree s2, tree type)
10908 if (!validate_arg (s1, POINTER_TYPE)
10909 || !validate_arg (s2, INTEGER_TYPE))
10910 return NULL_TREE;
10911 else
10913 tree fn;
10914 const char *p1;
10916 if (TREE_CODE (s2) != INTEGER_CST)
10917 return NULL_TREE;
10919 p1 = c_getstr (s1);
10920 if (p1 != NULL)
10922 char c;
10923 const char *r;
10924 tree tem;
10926 if (target_char_cast (s2, &c))
10927 return NULL_TREE;
10929 r = strrchr (p1, c);
10931 if (r == NULL)
10932 return build_int_cst (TREE_TYPE (s1), 0);
10934 /* Return an offset into the constant string argument. */
10935 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
10936 s1, size_int (r - p1));
10937 return fold_convert (type, tem);
10940 if (! integer_zerop (s2))
10941 return NULL_TREE;
10943 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
10944 if (!fn)
10945 return NULL_TREE;
10947 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
10948 return build_call_expr (fn, 2, s1, s2);
10952 /* Simplify a call to the strpbrk builtin. S1 and S2 are the arguments
10953 to the call, and TYPE is its return type.
10955 Return NULL_TREE if no simplification was possible, otherwise return the
10956 simplified form of the call as a tree.
10958 The simplified form may be a constant or other expression which
10959 computes the same value, but in a more efficient manner (including
10960 calls to other builtin functions).
10962 The call may contain arguments which need to be evaluated, but
10963 which are not useful to determine the result of the call. In
10964 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10965 COMPOUND_EXPR will be an argument which must be evaluated.
10966 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10967 COMPOUND_EXPR in the chain will contain the tree for the simplified
10968 form of the builtin function call. */
10970 static tree
10971 fold_builtin_strpbrk (tree s1, tree s2, tree type)
10973 if (!validate_arg (s1, POINTER_TYPE)
10974 || !validate_arg (s2, POINTER_TYPE))
10975 return NULL_TREE;
10976 else
10978 tree fn;
10979 const char *p1, *p2;
10981 p2 = c_getstr (s2);
10982 if (p2 == NULL)
10983 return NULL_TREE;
10985 p1 = c_getstr (s1);
10986 if (p1 != NULL)
10988 const char *r = strpbrk (p1, p2);
10989 tree tem;
10991 if (r == NULL)
10992 return build_int_cst (TREE_TYPE (s1), 0);
10994 /* Return an offset into the constant string argument. */
10995 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
10996 s1, size_int (r - p1));
10997 return fold_convert (type, tem);
11000 if (p2[0] == '\0')
11001 /* strpbrk(x, "") == NULL.
11002 Evaluate and ignore s1 in case it had side-effects. */
11003 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
11005 if (p2[1] != '\0')
11006 return NULL_TREE; /* Really call strpbrk. */
11008 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11009 if (!fn)
11010 return NULL_TREE;
11012 /* New argument list transforming strpbrk(s1, s2) to
11013 strchr(s1, s2[0]). */
11014 return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
11018 /* Simplify a call to the strcat builtin. DST and SRC are the arguments
11019 to the call.
11021 Return NULL_TREE if no simplification was possible, otherwise return the
11022 simplified form of the call as a tree.
11024 The simplified form may be a constant or other expression which
11025 computes the same value, but in a more efficient manner (including
11026 calls to other builtin functions).
11028 The call may contain arguments which need to be evaluated, but
11029 which are not useful to determine the result of the call. In
11030 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11031 COMPOUND_EXPR will be an argument which must be evaluated.
11032 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11033 COMPOUND_EXPR in the chain will contain the tree for the simplified
11034 form of the builtin function call. */
11036 static tree
11037 fold_builtin_strcat (tree dst, tree src)
11039 if (!validate_arg (dst, POINTER_TYPE)
11040 || !validate_arg (src, POINTER_TYPE))
11041 return NULL_TREE;
11042 else
11044 const char *p = c_getstr (src);
11046 /* If the string length is zero, return the dst parameter. */
11047 if (p && *p == '\0')
11048 return dst;
11050 return NULL_TREE;
11054 /* Simplify a call to the strncat builtin. DST, SRC, and LEN are the
11055 arguments to the call.
11057 Return NULL_TREE if no simplification was possible, otherwise return the
11058 simplified form of the call as a tree.
11060 The simplified form may be a constant or other expression which
11061 computes the same value, but in a more efficient manner (including
11062 calls to other builtin functions).
11064 The call may contain arguments which need to be evaluated, but
11065 which are not useful to determine the result of the call. In
11066 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11067 COMPOUND_EXPR will be an argument which must be evaluated.
11068 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11069 COMPOUND_EXPR in the chain will contain the tree for the simplified
11070 form of the builtin function call. */
11072 static tree
11073 fold_builtin_strncat (tree dst, tree src, tree len)
11075 if (!validate_arg (dst, POINTER_TYPE)
11076 || !validate_arg (src, POINTER_TYPE)
11077 || !validate_arg (len, INTEGER_TYPE))
11078 return NULL_TREE;
11079 else
11081 const char *p = c_getstr (src);
11083 /* If the requested length is zero, or the src parameter string
11084 length is zero, return the dst parameter. */
11085 if (integer_zerop (len) || (p && *p == '\0'))
11086 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
11088 /* If the requested len is greater than or equal to the string
11089 length, call strcat. */
11090 if (TREE_CODE (len) == INTEGER_CST && p
11091 && compare_tree_int (len, strlen (p)) >= 0)
11093 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
11095 /* If the replacement _DECL isn't initialized, don't do the
11096 transformation. */
11097 if (!fn)
11098 return NULL_TREE;
11100 return build_call_expr (fn, 2, dst, src);
11102 return NULL_TREE;
11106 /* Simplify a call to the strspn builtin. S1 and S2 are the arguments
11107 to the call.
11109 Return NULL_TREE if no simplification was possible, otherwise return the
11110 simplified form of the call as a tree.
11112 The simplified form may be a constant or other expression which
11113 computes the same value, but in a more efficient manner (including
11114 calls to other builtin functions).
11116 The call may contain arguments which need to be evaluated, but
11117 which are not useful to determine the result of the call. In
11118 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11119 COMPOUND_EXPR will be an argument which must be evaluated.
11120 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11121 COMPOUND_EXPR in the chain will contain the tree for the simplified
11122 form of the builtin function call. */
11124 static tree
11125 fold_builtin_strspn (tree s1, tree s2)
11127 if (!validate_arg (s1, POINTER_TYPE)
11128 || !validate_arg (s2, POINTER_TYPE))
11129 return NULL_TREE;
11130 else
11132 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11134 /* If both arguments are constants, evaluate at compile-time. */
11135 if (p1 && p2)
11137 const size_t r = strspn (p1, p2);
11138 return size_int (r);
11141 /* If either argument is "", return NULL_TREE. */
11142 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
11143 /* Evaluate and ignore both arguments in case either one has
11144 side-effects. */
11145 return omit_two_operands (integer_type_node, integer_zero_node,
11146 s1, s2);
11147 return NULL_TREE;
11151 /* Simplify a call to the strcspn builtin. S1 and S2 are the arguments
11152 to the call.
11154 Return NULL_TREE if no simplification was possible, otherwise return the
11155 simplified form of the call as a tree.
11157 The simplified form may be a constant or other expression which
11158 computes the same value, but in a more efficient manner (including
11159 calls to other builtin functions).
11161 The call may contain arguments which need to be evaluated, but
11162 which are not useful to determine the result of the call. In
11163 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11164 COMPOUND_EXPR will be an argument which must be evaluated.
11165 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11166 COMPOUND_EXPR in the chain will contain the tree for the simplified
11167 form of the builtin function call. */
11169 static tree
11170 fold_builtin_strcspn (tree s1, tree s2)
11172 if (!validate_arg (s1, POINTER_TYPE)
11173 || !validate_arg (s2, POINTER_TYPE))
11174 return NULL_TREE;
11175 else
11177 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11179 /* If both arguments are constants, evaluate at compile-time. */
11180 if (p1 && p2)
11182 const size_t r = strcspn (p1, p2);
11183 return size_int (r);
11186 /* If the first argument is "", return NULL_TREE. */
11187 if (p1 && *p1 == '\0')
11189 /* Evaluate and ignore argument s2 in case it has
11190 side-effects. */
11191 return omit_one_operand (integer_type_node,
11192 integer_zero_node, s2);
11195 /* If the second argument is "", return __builtin_strlen(s1). */
11196 if (p2 && *p2 == '\0')
11198 tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
11200 /* If the replacement _DECL isn't initialized, don't do the
11201 transformation. */
11202 if (!fn)
11203 return NULL_TREE;
11205 return build_call_expr (fn, 1, s1);
11207 return NULL_TREE;
11211 /* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
11212 to the call. IGNORE is true if the value returned
11213 by the builtin will be ignored. UNLOCKED is true is true if this
11214 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
11215 the known length of the string. Return NULL_TREE if no simplification
11216 was possible. */
11218 tree
11219 fold_builtin_fputs (tree arg0, tree arg1, bool ignore, bool unlocked, tree len)
11221 /* If we're using an unlocked function, assume the other unlocked
11222 functions exist explicitly. */
11223 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
11224 : implicit_built_in_decls[BUILT_IN_FPUTC];
11225 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
11226 : implicit_built_in_decls[BUILT_IN_FWRITE];
11228 /* If the return value is used, don't do the transformation. */
11229 if (!ignore)
11230 return NULL_TREE;
11232 /* Verify the arguments in the original call. */
11233 if (!validate_arg (arg0, POINTER_TYPE)
11234 || !validate_arg (arg1, POINTER_TYPE))
11235 return NULL_TREE;
11237 if (! len)
11238 len = c_strlen (arg0, 0);
11240 /* Get the length of the string passed to fputs. If the length
11241 can't be determined, punt. */
11242 if (!len
11243 || TREE_CODE (len) != INTEGER_CST)
11244 return NULL_TREE;
11246 switch (compare_tree_int (len, 1))
11248 case -1: /* length is 0, delete the call entirely . */
11249 return omit_one_operand (integer_type_node, integer_zero_node, arg1);;
11251 case 0: /* length is 1, call fputc. */
11253 const char *p = c_getstr (arg0);
11255 if (p != NULL)
11257 if (fn_fputc)
11258 return build_call_expr (fn_fputc, 2,
11259 build_int_cst (NULL_TREE, p[0]), arg1);
11260 else
11261 return NULL_TREE;
11264 /* FALLTHROUGH */
11265 case 1: /* length is greater than 1, call fwrite. */
11267 /* If optimizing for size keep fputs. */
11268 if (optimize_size)
11269 return NULL_TREE;
11270 /* New argument list transforming fputs(string, stream) to
11271 fwrite(string, 1, len, stream). */
11272 if (fn_fwrite)
11273 return build_call_expr (fn_fwrite, 4, arg0, size_one_node, len, arg1);
11274 else
11275 return NULL_TREE;
11277 default:
11278 gcc_unreachable ();
11280 return NULL_TREE;
11283 /* Fold the next_arg or va_start call EXP. Returns true if there was an error
11284 produced. False otherwise. This is done so that we don't output the error
11285 or warning twice or three times. */
11286 bool
11287 fold_builtin_next_arg (tree exp, bool va_start_p)
11289 tree fntype = TREE_TYPE (current_function_decl);
11290 int nargs = call_expr_nargs (exp);
11291 tree arg;
11293 if (TYPE_ARG_TYPES (fntype) == 0
11294 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
11295 == void_type_node))
11297 error ("%<va_start%> used in function with fixed args");
11298 return true;
11301 if (va_start_p)
11303 if (va_start_p && (nargs != 2))
11305 error ("wrong number of arguments to function %<va_start%>");
11306 return true;
11308 arg = CALL_EXPR_ARG (exp, 1);
11310 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
11311 when we checked the arguments and if needed issued a warning. */
11312 else
11314 if (nargs == 0)
11316 /* Evidently an out of date version of <stdarg.h>; can't validate
11317 va_start's second argument, but can still work as intended. */
11318 warning (0, "%<__builtin_next_arg%> called without an argument");
11319 return true;
11321 else if (nargs > 1)
11323 error ("wrong number of arguments to function %<__builtin_next_arg%>");
11324 return true;
11326 arg = CALL_EXPR_ARG (exp, 0);
11329 /* We destructively modify the call to be __builtin_va_start (ap, 0)
11330 or __builtin_next_arg (0) the first time we see it, after checking
11331 the arguments and if needed issuing a warning. */
11332 if (!integer_zerop (arg))
11334 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
11336 /* Strip off all nops for the sake of the comparison. This
11337 is not quite the same as STRIP_NOPS. It does more.
11338 We must also strip off INDIRECT_EXPR for C++ reference
11339 parameters. */
11340 while (TREE_CODE (arg) == NOP_EXPR
11341 || TREE_CODE (arg) == CONVERT_EXPR
11342 || TREE_CODE (arg) == NON_LVALUE_EXPR
11343 || TREE_CODE (arg) == INDIRECT_REF)
11344 arg = TREE_OPERAND (arg, 0);
11345 if (arg != last_parm)
11347 /* FIXME: Sometimes with the tree optimizers we can get the
11348 not the last argument even though the user used the last
11349 argument. We just warn and set the arg to be the last
11350 argument so that we will get wrong-code because of
11351 it. */
11352 warning (0, "second parameter of %<va_start%> not last named argument");
11354 /* We want to verify the second parameter just once before the tree
11355 optimizers are run and then avoid keeping it in the tree,
11356 as otherwise we could warn even for correct code like:
11357 void foo (int i, ...)
11358 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
11359 if (va_start_p)
11360 CALL_EXPR_ARG (exp, 1) = integer_zero_node;
11361 else
11362 CALL_EXPR_ARG (exp, 0) = integer_zero_node;
11364 return false;
11368 /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
11369 ORIG may be null if this is a 2-argument call. We don't attempt to
11370 simplify calls with more than 3 arguments.
11372 Return NULL_TREE if no simplification was possible, otherwise return the
11373 simplified form of the call as a tree. If IGNORED is true, it means that
11374 the caller does not use the returned value of the function. */
11376 static tree
11377 fold_builtin_sprintf (tree dest, tree fmt, tree orig, int ignored)
11379 tree call, retval;
11380 const char *fmt_str = NULL;
11382 /* Verify the required arguments in the original call. We deal with two
11383 types of sprintf() calls: 'sprintf (str, fmt)' and
11384 'sprintf (dest, "%s", orig)'. */
11385 if (!validate_arg (dest, POINTER_TYPE)
11386 || !validate_arg (fmt, POINTER_TYPE))
11387 return NULL_TREE;
11388 if (orig && !validate_arg (orig, POINTER_TYPE))
11389 return NULL_TREE;
11391 /* Check whether the format is a literal string constant. */
11392 fmt_str = c_getstr (fmt);
11393 if (fmt_str == NULL)
11394 return NULL_TREE;
11396 call = NULL_TREE;
11397 retval = NULL_TREE;
11399 if (!init_target_chars ())
11400 return NULL_TREE;
11402 /* If the format doesn't contain % args or %%, use strcpy. */
11403 if (strchr (fmt_str, target_percent) == NULL)
11405 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11407 if (!fn)
11408 return NULL_TREE;
11410 /* Don't optimize sprintf (buf, "abc", ptr++). */
11411 if (orig)
11412 return NULL_TREE;
11414 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
11415 'format' is known to contain no % formats. */
11416 call = build_call_expr (fn, 2, dest, fmt);
11417 if (!ignored)
11418 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
11421 /* If the format is "%s", use strcpy if the result isn't used. */
11422 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
11424 tree fn;
11425 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11427 if (!fn)
11428 return NULL_TREE;
11430 /* Don't crash on sprintf (str1, "%s"). */
11431 if (!orig)
11432 return NULL_TREE;
11434 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
11435 if (!ignored)
11437 retval = c_strlen (orig, 1);
11438 if (!retval || TREE_CODE (retval) != INTEGER_CST)
11439 return NULL_TREE;
11441 call = build_call_expr (fn, 2, dest, orig);
11444 if (call && retval)
11446 retval = fold_convert
11447 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
11448 retval);
11449 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
11451 else
11452 return call;
11455 /* Expand a call EXP to __builtin_object_size. */
11458 expand_builtin_object_size (tree exp)
11460 tree ost;
11461 int object_size_type;
11462 tree fndecl = get_callee_fndecl (exp);
11463 location_t locus = EXPR_LOCATION (exp);
11465 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
11467 error ("%Hfirst argument of %D must be a pointer, second integer constant",
11468 &locus, fndecl);
11469 expand_builtin_trap ();
11470 return const0_rtx;
11473 ost = CALL_EXPR_ARG (exp, 1);
11474 STRIP_NOPS (ost);
11476 if (TREE_CODE (ost) != INTEGER_CST
11477 || tree_int_cst_sgn (ost) < 0
11478 || compare_tree_int (ost, 3) > 0)
11480 error ("%Hlast argument of %D is not integer constant between 0 and 3",
11481 &locus, fndecl);
11482 expand_builtin_trap ();
11483 return const0_rtx;
11486 object_size_type = tree_low_cst (ost, 0);
11488 return object_size_type < 2 ? constm1_rtx : const0_rtx;
11491 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
11492 FCODE is the BUILT_IN_* to use.
11493 Return NULL_RTX if we failed; the caller should emit a normal call,
11494 otherwise try to get the result in TARGET, if convenient (and in
11495 mode MODE if that's convenient). */
11497 static rtx
11498 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
11499 enum built_in_function fcode)
11501 tree dest, src, len, size;
11503 if (!validate_arglist (exp,
11504 POINTER_TYPE,
11505 fcode == BUILT_IN_MEMSET_CHK
11506 ? INTEGER_TYPE : POINTER_TYPE,
11507 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
11508 return NULL_RTX;
11510 dest = CALL_EXPR_ARG (exp, 0);
11511 src = CALL_EXPR_ARG (exp, 1);
11512 len = CALL_EXPR_ARG (exp, 2);
11513 size = CALL_EXPR_ARG (exp, 3);
11515 if (! host_integerp (size, 1))
11516 return NULL_RTX;
11518 if (host_integerp (len, 1) || integer_all_onesp (size))
11520 tree fn;
11522 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
11524 location_t locus = EXPR_LOCATION (exp);
11525 warning (0, "%Hcall to %D will always overflow destination buffer",
11526 &locus, get_callee_fndecl (exp));
11527 return NULL_RTX;
11530 fn = NULL_TREE;
11531 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
11532 mem{cpy,pcpy,move,set} is available. */
11533 switch (fcode)
11535 case BUILT_IN_MEMCPY_CHK:
11536 fn = built_in_decls[BUILT_IN_MEMCPY];
11537 break;
11538 case BUILT_IN_MEMPCPY_CHK:
11539 fn = built_in_decls[BUILT_IN_MEMPCPY];
11540 break;
11541 case BUILT_IN_MEMMOVE_CHK:
11542 fn = built_in_decls[BUILT_IN_MEMMOVE];
11543 break;
11544 case BUILT_IN_MEMSET_CHK:
11545 fn = built_in_decls[BUILT_IN_MEMSET];
11546 break;
11547 default:
11548 break;
11551 if (! fn)
11552 return NULL_RTX;
11554 fn = build_call_expr (fn, 3, dest, src, len);
11555 if (TREE_CODE (fn) == CALL_EXPR)
11556 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
11557 return expand_expr (fn, target, mode, EXPAND_NORMAL);
11559 else if (fcode == BUILT_IN_MEMSET_CHK)
11560 return NULL_RTX;
11561 else
11563 unsigned int dest_align
11564 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
11566 /* If DEST is not a pointer type, call the normal function. */
11567 if (dest_align == 0)
11568 return NULL_RTX;
11570 /* If SRC and DEST are the same (and not volatile), do nothing. */
11571 if (operand_equal_p (src, dest, 0))
11573 tree expr;
11575 if (fcode != BUILT_IN_MEMPCPY_CHK)
11577 /* Evaluate and ignore LEN in case it has side-effects. */
11578 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
11579 return expand_expr (dest, target, mode, EXPAND_NORMAL);
11582 expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
11583 return expand_expr (expr, target, mode, EXPAND_NORMAL);
11586 /* __memmove_chk special case. */
11587 if (fcode == BUILT_IN_MEMMOVE_CHK)
11589 unsigned int src_align
11590 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
11592 if (src_align == 0)
11593 return NULL_RTX;
11595 /* If src is categorized for a readonly section we can use
11596 normal __memcpy_chk. */
11597 if (readonly_data_expr (src))
11599 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
11600 if (!fn)
11601 return NULL_RTX;
11602 fn = build_call_expr (fn, 4, dest, src, len, size);
11603 if (TREE_CODE (fn) == CALL_EXPR)
11604 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
11605 return expand_expr (fn, target, mode, EXPAND_NORMAL);
11608 return NULL_RTX;
11612 /* Emit warning if a buffer overflow is detected at compile time. */
11614 static void
11615 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
11617 int is_strlen = 0;
11618 tree len, size;
11619 location_t locus;
11621 switch (fcode)
11623 case BUILT_IN_STRCPY_CHK:
11624 case BUILT_IN_STPCPY_CHK:
11625 /* For __strcat_chk the warning will be emitted only if overflowing
11626 by at least strlen (dest) + 1 bytes. */
11627 case BUILT_IN_STRCAT_CHK:
11628 len = CALL_EXPR_ARG (exp, 1);
11629 size = CALL_EXPR_ARG (exp, 2);
11630 is_strlen = 1;
11631 break;
11632 case BUILT_IN_STRNCAT_CHK:
11633 case BUILT_IN_STRNCPY_CHK:
11634 len = CALL_EXPR_ARG (exp, 2);
11635 size = CALL_EXPR_ARG (exp, 3);
11636 break;
11637 case BUILT_IN_SNPRINTF_CHK:
11638 case BUILT_IN_VSNPRINTF_CHK:
11639 len = CALL_EXPR_ARG (exp, 1);
11640 size = CALL_EXPR_ARG (exp, 3);
11641 break;
11642 default:
11643 gcc_unreachable ();
11646 if (!len || !size)
11647 return;
11649 if (! host_integerp (size, 1) || integer_all_onesp (size))
11650 return;
11652 if (is_strlen)
11654 len = c_strlen (len, 1);
11655 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
11656 return;
11658 else if (fcode == BUILT_IN_STRNCAT_CHK)
11660 tree src = CALL_EXPR_ARG (exp, 1);
11661 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
11662 return;
11663 src = c_strlen (src, 1);
11664 if (! src || ! host_integerp (src, 1))
11666 locus = EXPR_LOCATION (exp);
11667 warning (0, "%Hcall to %D might overflow destination buffer",
11668 &locus, get_callee_fndecl (exp));
11669 return;
11671 else if (tree_int_cst_lt (src, size))
11672 return;
11674 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
11675 return;
11677 locus = EXPR_LOCATION (exp);
11678 warning (0, "%Hcall to %D will always overflow destination buffer",
11679 &locus, get_callee_fndecl (exp));
11682 /* Emit warning if a buffer overflow is detected at compile time
11683 in __sprintf_chk/__vsprintf_chk calls. */
11685 static void
11686 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
11688 tree dest, size, len, fmt, flag;
11689 const char *fmt_str;
11690 int nargs = call_expr_nargs (exp);
11692 /* Verify the required arguments in the original call. */
11694 if (nargs < 4)
11695 return;
11696 dest = CALL_EXPR_ARG (exp, 0);
11697 flag = CALL_EXPR_ARG (exp, 1);
11698 size = CALL_EXPR_ARG (exp, 2);
11699 fmt = CALL_EXPR_ARG (exp, 3);
11701 if (! host_integerp (size, 1) || integer_all_onesp (size))
11702 return;
11704 /* Check whether the format is a literal string constant. */
11705 fmt_str = c_getstr (fmt);
11706 if (fmt_str == NULL)
11707 return;
11709 if (!init_target_chars ())
11710 return;
11712 /* If the format doesn't contain % args or %%, we know its size. */
11713 if (strchr (fmt_str, target_percent) == 0)
11714 len = build_int_cstu (size_type_node, strlen (fmt_str));
11715 /* If the format is "%s" and first ... argument is a string literal,
11716 we know it too. */
11717 else if (fcode == BUILT_IN_SPRINTF_CHK
11718 && strcmp (fmt_str, target_percent_s) == 0)
11720 tree arg;
11722 if (nargs < 5)
11723 return;
11724 arg = CALL_EXPR_ARG (exp, 4);
11725 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
11726 return;
11728 len = c_strlen (arg, 1);
11729 if (!len || ! host_integerp (len, 1))
11730 return;
11732 else
11733 return;
11735 if (! tree_int_cst_lt (len, size))
11737 location_t locus = EXPR_LOCATION (exp);
11738 warning (0, "%Hcall to %D will always overflow destination buffer",
11739 &locus, get_callee_fndecl (exp));
11743 /* Fold a call to __builtin_object_size with arguments PTR and OST,
11744 if possible. */
11746 tree
11747 fold_builtin_object_size (tree ptr, tree ost)
11749 tree ret = NULL_TREE;
11750 int object_size_type;
11752 if (!validate_arg (ptr, POINTER_TYPE)
11753 || !validate_arg (ost, INTEGER_TYPE))
11754 return NULL_TREE;
11756 STRIP_NOPS (ost);
11758 if (TREE_CODE (ost) != INTEGER_CST
11759 || tree_int_cst_sgn (ost) < 0
11760 || compare_tree_int (ost, 3) > 0)
11761 return NULL_TREE;
11763 object_size_type = tree_low_cst (ost, 0);
11765 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
11766 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
11767 and (size_t) 0 for types 2 and 3. */
11768 if (TREE_SIDE_EFFECTS (ptr))
11769 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
11771 if (TREE_CODE (ptr) == ADDR_EXPR)
11772 ret = build_int_cstu (size_type_node,
11773 compute_builtin_object_size (ptr, object_size_type));
11775 else if (TREE_CODE (ptr) == SSA_NAME)
11777 unsigned HOST_WIDE_INT bytes;
11779 /* If object size is not known yet, delay folding until
11780 later. Maybe subsequent passes will help determining
11781 it. */
11782 bytes = compute_builtin_object_size (ptr, object_size_type);
11783 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
11784 ? -1 : 0))
11785 ret = build_int_cstu (size_type_node, bytes);
11788 if (ret)
11790 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
11791 HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
11792 if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
11793 ret = NULL_TREE;
11796 return ret;
11799 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
11800 DEST, SRC, LEN, and SIZE are the arguments to the call.
11801 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
11802 code of the builtin. If MAXLEN is not NULL, it is maximum length
11803 passed as third argument. */
11805 tree
11806 fold_builtin_memory_chk (tree fndecl,
11807 tree dest, tree src, tree len, tree size,
11808 tree maxlen, bool ignore,
11809 enum built_in_function fcode)
11811 tree fn;
11813 if (!validate_arg (dest, POINTER_TYPE)
11814 || !validate_arg (src,
11815 (fcode == BUILT_IN_MEMSET_CHK
11816 ? INTEGER_TYPE : POINTER_TYPE))
11817 || !validate_arg (len, INTEGER_TYPE)
11818 || !validate_arg (size, INTEGER_TYPE))
11819 return NULL_TREE;
11821 /* If SRC and DEST are the same (and not volatile), return DEST
11822 (resp. DEST+LEN for __mempcpy_chk). */
11823 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
11825 if (fcode != BUILT_IN_MEMPCPY_CHK)
11826 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
11827 else
11829 tree temp = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
11830 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
11834 if (! host_integerp (size, 1))
11835 return NULL_TREE;
11837 if (! integer_all_onesp (size))
11839 if (! host_integerp (len, 1))
11841 /* If LEN is not constant, try MAXLEN too.
11842 For MAXLEN only allow optimizing into non-_ocs function
11843 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11844 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11846 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
11848 /* (void) __mempcpy_chk () can be optimized into
11849 (void) __memcpy_chk (). */
11850 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
11851 if (!fn)
11852 return NULL_TREE;
11854 return build_call_expr (fn, 4, dest, src, len, size);
11856 return NULL_TREE;
11859 else
11860 maxlen = len;
11862 if (tree_int_cst_lt (size, maxlen))
11863 return NULL_TREE;
11866 fn = NULL_TREE;
11867 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
11868 mem{cpy,pcpy,move,set} is available. */
11869 switch (fcode)
11871 case BUILT_IN_MEMCPY_CHK:
11872 fn = built_in_decls[BUILT_IN_MEMCPY];
11873 break;
11874 case BUILT_IN_MEMPCPY_CHK:
11875 fn = built_in_decls[BUILT_IN_MEMPCPY];
11876 break;
11877 case BUILT_IN_MEMMOVE_CHK:
11878 fn = built_in_decls[BUILT_IN_MEMMOVE];
11879 break;
11880 case BUILT_IN_MEMSET_CHK:
11881 fn = built_in_decls[BUILT_IN_MEMSET];
11882 break;
11883 default:
11884 break;
11887 if (!fn)
11888 return NULL_TREE;
11890 return build_call_expr (fn, 3, dest, src, len);
11893 /* Fold a call to the __st[rp]cpy_chk builtin.
11894 DEST, SRC, and SIZE are the arguments to the call.
11895 IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
11896 code of the builtin. If MAXLEN is not NULL, it is maximum length of
11897 strings passed as second argument. */
11899 tree
11900 fold_builtin_stxcpy_chk (tree fndecl, tree dest, tree src, tree size,
11901 tree maxlen, bool ignore,
11902 enum built_in_function fcode)
11904 tree len, fn;
11906 if (!validate_arg (dest, POINTER_TYPE)
11907 || !validate_arg (src, POINTER_TYPE)
11908 || !validate_arg (size, INTEGER_TYPE))
11909 return NULL_TREE;
11911 /* If SRC and DEST are the same (and not volatile), return DEST. */
11912 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
11913 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
11915 if (! host_integerp (size, 1))
11916 return NULL_TREE;
11918 if (! integer_all_onesp (size))
11920 len = c_strlen (src, 1);
11921 if (! len || ! host_integerp (len, 1))
11923 /* If LEN is not constant, try MAXLEN too.
11924 For MAXLEN only allow optimizing into non-_ocs function
11925 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11926 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11928 if (fcode == BUILT_IN_STPCPY_CHK)
11930 if (! ignore)
11931 return NULL_TREE;
11933 /* If return value of __stpcpy_chk is ignored,
11934 optimize into __strcpy_chk. */
11935 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
11936 if (!fn)
11937 return NULL_TREE;
11939 return build_call_expr (fn, 3, dest, src, size);
11942 if (! len || TREE_SIDE_EFFECTS (len))
11943 return NULL_TREE;
11945 /* If c_strlen returned something, but not a constant,
11946 transform __strcpy_chk into __memcpy_chk. */
11947 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
11948 if (!fn)
11949 return NULL_TREE;
11951 len = size_binop (PLUS_EXPR, len, ssize_int (1));
11952 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
11953 build_call_expr (fn, 4,
11954 dest, src, len, size));
11957 else
11958 maxlen = len;
11960 if (! tree_int_cst_lt (maxlen, size))
11961 return NULL_TREE;
11964 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
11965 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
11966 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
11967 if (!fn)
11968 return NULL_TREE;
11970 return build_call_expr (fn, 2, dest, src);
11973 /* Fold a call to the __strncpy_chk builtin. DEST, SRC, LEN, and SIZE
11974 are the arguments to the call. If MAXLEN is not NULL, it is maximum
11975 length passed as third argument. */
11977 tree
11978 fold_builtin_strncpy_chk (tree dest, tree src, tree len, tree size,
11979 tree maxlen)
11981 tree fn;
11983 if (!validate_arg (dest, POINTER_TYPE)
11984 || !validate_arg (src, POINTER_TYPE)
11985 || !validate_arg (len, INTEGER_TYPE)
11986 || !validate_arg (size, INTEGER_TYPE))
11987 return NULL_TREE;
11989 if (! host_integerp (size, 1))
11990 return NULL_TREE;
11992 if (! integer_all_onesp (size))
11994 if (! host_integerp (len, 1))
11996 /* If LEN is not constant, try MAXLEN too.
11997 For MAXLEN only allow optimizing into non-_ocs function
11998 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11999 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12000 return NULL_TREE;
12002 else
12003 maxlen = len;
12005 if (tree_int_cst_lt (size, maxlen))
12006 return NULL_TREE;
12009 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
12010 fn = built_in_decls[BUILT_IN_STRNCPY];
12011 if (!fn)
12012 return NULL_TREE;
12014 return build_call_expr (fn, 3, dest, src, len);
12017 /* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE
12018 are the arguments to the call. */
12020 static tree
12021 fold_builtin_strcat_chk (tree fndecl, tree dest, tree src, tree size)
12023 tree fn;
12024 const char *p;
12026 if (!validate_arg (dest, POINTER_TYPE)
12027 || !validate_arg (src, POINTER_TYPE)
12028 || !validate_arg (size, INTEGER_TYPE))
12029 return NULL_TREE;
12031 p = c_getstr (src);
12032 /* If the SRC parameter is "", return DEST. */
12033 if (p && *p == '\0')
12034 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12036 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
12037 return NULL_TREE;
12039 /* If __builtin_strcat_chk is used, assume strcat is available. */
12040 fn = built_in_decls[BUILT_IN_STRCAT];
12041 if (!fn)
12042 return NULL_TREE;
12044 return build_call_expr (fn, 2, dest, src);
12047 /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12048 LEN, and SIZE. */
12050 static tree
12051 fold_builtin_strncat_chk (tree fndecl,
12052 tree dest, tree src, tree len, tree size)
12054 tree fn;
12055 const char *p;
12057 if (!validate_arg (dest, POINTER_TYPE)
12058 || !validate_arg (src, POINTER_TYPE)
12059 || !validate_arg (size, INTEGER_TYPE)
12060 || !validate_arg (size, INTEGER_TYPE))
12061 return NULL_TREE;
12063 p = c_getstr (src);
12064 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
12065 if (p && *p == '\0')
12066 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12067 else if (integer_zerop (len))
12068 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12070 if (! host_integerp (size, 1))
12071 return NULL_TREE;
12073 if (! integer_all_onesp (size))
12075 tree src_len = c_strlen (src, 1);
12076 if (src_len
12077 && host_integerp (src_len, 1)
12078 && host_integerp (len, 1)
12079 && ! tree_int_cst_lt (len, src_len))
12081 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
12082 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
12083 if (!fn)
12084 return NULL_TREE;
12086 return build_call_expr (fn, 3, dest, src, size);
12088 return NULL_TREE;
12091 /* If __builtin_strncat_chk is used, assume strncat is available. */
12092 fn = built_in_decls[BUILT_IN_STRNCAT];
12093 if (!fn)
12094 return NULL_TREE;
12096 return build_call_expr (fn, 3, dest, src, len);
12099 /* Fold a call EXP to __{,v}sprintf_chk. Return NULL_TREE if
12100 a normal call should be emitted rather than expanding the function
12101 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
12103 static tree
12104 fold_builtin_sprintf_chk (tree exp, enum built_in_function fcode)
12106 tree dest, size, len, fn, fmt, flag;
12107 const char *fmt_str;
12108 int nargs = call_expr_nargs (exp);
12110 /* Verify the required arguments in the original call. */
12111 if (nargs < 4)
12112 return NULL_TREE;
12113 dest = CALL_EXPR_ARG (exp, 0);
12114 if (!validate_arg (dest, POINTER_TYPE))
12115 return NULL_TREE;
12116 flag = CALL_EXPR_ARG (exp, 1);
12117 if (!validate_arg (flag, INTEGER_TYPE))
12118 return NULL_TREE;
12119 size = CALL_EXPR_ARG (exp, 2);
12120 if (!validate_arg (size, INTEGER_TYPE))
12121 return NULL_TREE;
12122 fmt = CALL_EXPR_ARG (exp, 3);
12123 if (!validate_arg (fmt, POINTER_TYPE))
12124 return NULL_TREE;
12126 if (! host_integerp (size, 1))
12127 return NULL_TREE;
12129 len = NULL_TREE;
12131 if (!init_target_chars ())
12132 return NULL_TREE;
12134 /* Check whether the format is a literal string constant. */
12135 fmt_str = c_getstr (fmt);
12136 if (fmt_str != NULL)
12138 /* If the format doesn't contain % args or %%, we know the size. */
12139 if (strchr (fmt_str, target_percent) == 0)
12141 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
12142 len = build_int_cstu (size_type_node, strlen (fmt_str));
12144 /* If the format is "%s" and first ... argument is a string literal,
12145 we know the size too. */
12146 else if (fcode == BUILT_IN_SPRINTF_CHK
12147 && strcmp (fmt_str, target_percent_s) == 0)
12149 tree arg;
12151 if (nargs == 5)
12153 arg = CALL_EXPR_ARG (exp, 4);
12154 if (validate_arg (arg, POINTER_TYPE))
12156 len = c_strlen (arg, 1);
12157 if (! len || ! host_integerp (len, 1))
12158 len = NULL_TREE;
12164 if (! integer_all_onesp (size))
12166 if (! len || ! tree_int_cst_lt (len, size))
12167 return NULL_TREE;
12170 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
12171 or if format doesn't contain % chars or is "%s". */
12172 if (! integer_zerop (flag))
12174 if (fmt_str == NULL)
12175 return NULL_TREE;
12176 if (strchr (fmt_str, target_percent) != NULL
12177 && strcmp (fmt_str, target_percent_s))
12178 return NULL_TREE;
12181 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
12182 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
12183 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
12184 if (!fn)
12185 return NULL_TREE;
12187 return rewrite_call_expr (exp, 4, fn, 2, dest, fmt);
12190 /* Fold a call EXP to {,v}snprintf. Return NULL_TREE if
12191 a normal call should be emitted rather than expanding the function
12192 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
12193 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
12194 passed as second argument. */
12196 tree
12197 fold_builtin_snprintf_chk (tree exp, tree maxlen,
12198 enum built_in_function fcode)
12200 tree dest, size, len, fn, fmt, flag;
12201 const char *fmt_str;
12203 /* Verify the required arguments in the original call. */
12204 if (call_expr_nargs (exp) < 5)
12205 return NULL_TREE;
12206 dest = CALL_EXPR_ARG (exp, 0);
12207 if (!validate_arg (dest, POINTER_TYPE))
12208 return NULL_TREE;
12209 len = CALL_EXPR_ARG (exp, 1);
12210 if (!validate_arg (len, INTEGER_TYPE))
12211 return NULL_TREE;
12212 flag = CALL_EXPR_ARG (exp, 2);
12213 if (!validate_arg (flag, INTEGER_TYPE))
12214 return NULL_TREE;
12215 size = CALL_EXPR_ARG (exp, 3);
12216 if (!validate_arg (size, INTEGER_TYPE))
12217 return NULL_TREE;
12218 fmt = CALL_EXPR_ARG (exp, 4);
12219 if (!validate_arg (fmt, POINTER_TYPE))
12220 return NULL_TREE;
12222 if (! host_integerp (size, 1))
12223 return NULL_TREE;
12225 if (! integer_all_onesp (size))
12227 if (! host_integerp (len, 1))
12229 /* If LEN is not constant, try MAXLEN too.
12230 For MAXLEN only allow optimizing into non-_ocs function
12231 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12232 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12233 return NULL_TREE;
12235 else
12236 maxlen = len;
12238 if (tree_int_cst_lt (size, maxlen))
12239 return NULL_TREE;
12242 if (!init_target_chars ())
12243 return NULL_TREE;
12245 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
12246 or if format doesn't contain % chars or is "%s". */
12247 if (! integer_zerop (flag))
12249 fmt_str = c_getstr (fmt);
12250 if (fmt_str == NULL)
12251 return NULL_TREE;
12252 if (strchr (fmt_str, target_percent) != NULL
12253 && strcmp (fmt_str, target_percent_s))
12254 return NULL_TREE;
12257 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
12258 available. */
12259 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
12260 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
12261 if (!fn)
12262 return NULL_TREE;
12264 return rewrite_call_expr (exp, 5, fn, 3, dest, len, fmt);
12267 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
12268 FMT and ARG are the arguments to the call; we don't fold cases with
12269 more than 2 arguments, and ARG may be null if this is a 1-argument case.
12271 Return NULL_TREE if no simplification was possible, otherwise return the
12272 simplified form of the call as a tree. FCODE is the BUILT_IN_*
12273 code of the function to be simplified. */
12275 static tree
12276 fold_builtin_printf (tree fndecl, tree fmt, tree arg, bool ignore,
12277 enum built_in_function fcode)
12279 tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
12280 const char *fmt_str = NULL;
12282 /* If the return value is used, don't do the transformation. */
12283 if (! ignore)
12284 return NULL_TREE;
12286 /* Verify the required arguments in the original call. */
12287 if (!validate_arg (fmt, POINTER_TYPE))
12288 return NULL_TREE;
12290 /* Check whether the format is a literal string constant. */
12291 fmt_str = c_getstr (fmt);
12292 if (fmt_str == NULL)
12293 return NULL_TREE;
12295 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
12297 /* If we're using an unlocked function, assume the other
12298 unlocked functions exist explicitly. */
12299 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
12300 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
12302 else
12304 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
12305 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
12308 if (!init_target_chars ())
12309 return NULL_TREE;
12311 if (strcmp (fmt_str, target_percent_s) == 0
12312 || strchr (fmt_str, target_percent) == NULL)
12314 const char *str;
12316 if (strcmp (fmt_str, target_percent_s) == 0)
12318 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
12319 return NULL_TREE;
12321 if (!arg || !validate_arg (arg, POINTER_TYPE))
12322 return NULL_TREE;
12324 str = c_getstr (arg);
12325 if (str == NULL)
12326 return NULL_TREE;
12328 else
12330 /* The format specifier doesn't contain any '%' characters. */
12331 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
12332 && arg)
12333 return NULL_TREE;
12334 str = fmt_str;
12337 /* If the string was "", printf does nothing. */
12338 if (str[0] == '\0')
12339 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12341 /* If the string has length of 1, call putchar. */
12342 if (str[1] == '\0')
12344 /* Given printf("c"), (where c is any one character,)
12345 convert "c"[0] to an int and pass that to the replacement
12346 function. */
12347 newarg = build_int_cst (NULL_TREE, str[0]);
12348 if (fn_putchar)
12349 call = build_call_expr (fn_putchar, 1, newarg);
12351 else
12353 /* If the string was "string\n", call puts("string"). */
12354 size_t len = strlen (str);
12355 if ((unsigned char)str[len - 1] == target_newline)
12357 /* Create a NUL-terminated string that's one char shorter
12358 than the original, stripping off the trailing '\n'. */
12359 char *newstr = alloca (len);
12360 memcpy (newstr, str, len - 1);
12361 newstr[len - 1] = 0;
12363 newarg = build_string_literal (len, newstr);
12364 if (fn_puts)
12365 call = build_call_expr (fn_puts, 1, newarg);
12367 else
12368 /* We'd like to arrange to call fputs(string,stdout) here,
12369 but we need stdout and don't have a way to get it yet. */
12370 return NULL_TREE;
12374 /* The other optimizations can be done only on the non-va_list variants. */
12375 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
12376 return NULL_TREE;
12378 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
12379 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
12381 if (!arg || !validate_arg (arg, POINTER_TYPE))
12382 return NULL_TREE;
12383 if (fn_puts)
12384 call = build_call_expr (fn_puts, 1, arg);
12387 /* If the format specifier was "%c", call __builtin_putchar(arg). */
12388 else if (strcmp (fmt_str, target_percent_c) == 0)
12390 if (!arg || !validate_arg (arg, INTEGER_TYPE))
12391 return NULL_TREE;
12392 if (fn_putchar)
12393 call = build_call_expr (fn_putchar, 1, arg);
12396 if (!call)
12397 return NULL_TREE;
12399 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
12402 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
12403 FP, FMT, and ARG are the arguments to the call. We don't fold calls with
12404 more than 3 arguments, and ARG may be null in the 2-argument case.
12406 Return NULL_TREE if no simplification was possible, otherwise return the
12407 simplified form of the call as a tree. FCODE is the BUILT_IN_*
12408 code of the function to be simplified. */
12410 static tree
12411 fold_builtin_fprintf (tree fndecl, tree fp, tree fmt, tree arg, bool ignore,
12412 enum built_in_function fcode)
12414 tree fn_fputc, fn_fputs, call = NULL_TREE;
12415 const char *fmt_str = NULL;
12417 /* If the return value is used, don't do the transformation. */
12418 if (! ignore)
12419 return NULL_TREE;
12421 /* Verify the required arguments in the original call. */
12422 if (!validate_arg (fp, POINTER_TYPE))
12423 return NULL_TREE;
12424 if (!validate_arg (fmt, POINTER_TYPE))
12425 return NULL_TREE;
12427 /* Check whether the format is a literal string constant. */
12428 fmt_str = c_getstr (fmt);
12429 if (fmt_str == NULL)
12430 return NULL_TREE;
12432 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
12434 /* If we're using an unlocked function, assume the other
12435 unlocked functions exist explicitly. */
12436 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
12437 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
12439 else
12441 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
12442 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
12445 if (!init_target_chars ())
12446 return NULL_TREE;
12448 /* If the format doesn't contain % args or %%, use strcpy. */
12449 if (strchr (fmt_str, target_percent) == NULL)
12451 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
12452 && arg)
12453 return NULL_TREE;
12455 /* If the format specifier was "", fprintf does nothing. */
12456 if (fmt_str[0] == '\0')
12458 /* If FP has side-effects, just wait until gimplification is
12459 done. */
12460 if (TREE_SIDE_EFFECTS (fp))
12461 return NULL_TREE;
12463 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12466 /* When "string" doesn't contain %, replace all cases of
12467 fprintf (fp, string) with fputs (string, fp). The fputs
12468 builtin will take care of special cases like length == 1. */
12469 if (fn_fputs)
12470 call = build_call_expr (fn_fputs, 2, fmt, fp);
12473 /* The other optimizations can be done only on the non-va_list variants. */
12474 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
12475 return NULL_TREE;
12477 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
12478 else if (strcmp (fmt_str, target_percent_s) == 0)
12480 if (!arg || !validate_arg (arg, POINTER_TYPE))
12481 return NULL_TREE;
12482 if (fn_fputs)
12483 call = build_call_expr (fn_fputs, 2, arg, fp);
12486 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
12487 else if (strcmp (fmt_str, target_percent_c) == 0)
12489 if (!arg || !validate_arg (arg, INTEGER_TYPE))
12490 return NULL_TREE;
12491 if (fn_fputc)
12492 call = build_call_expr (fn_fputc, 2, arg, fp);
12495 if (!call)
12496 return NULL_TREE;
12497 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
12500 /* Initialize format string characters in the target charset. */
12502 static bool
12503 init_target_chars (void)
12505 static bool init;
12506 if (!init)
12508 target_newline = lang_hooks.to_target_charset ('\n');
12509 target_percent = lang_hooks.to_target_charset ('%');
12510 target_c = lang_hooks.to_target_charset ('c');
12511 target_s = lang_hooks.to_target_charset ('s');
12512 if (target_newline == 0 || target_percent == 0 || target_c == 0
12513 || target_s == 0)
12514 return false;
12516 target_percent_c[0] = target_percent;
12517 target_percent_c[1] = target_c;
12518 target_percent_c[2] = '\0';
12520 target_percent_s[0] = target_percent;
12521 target_percent_s[1] = target_s;
12522 target_percent_s[2] = '\0';
12524 target_percent_s_newline[0] = target_percent;
12525 target_percent_s_newline[1] = target_s;
12526 target_percent_s_newline[2] = target_newline;
12527 target_percent_s_newline[3] = '\0';
12529 init = true;
12531 return true;
12534 /* Helper function for do_mpfr_arg*(). Ensure M is a normal number
12535 and no overflow/underflow occurred. INEXACT is true if M was not
12536 exactly calculated. TYPE is the tree type for the result. This
12537 function assumes that you cleared the MPFR flags and then
12538 calculated M to see if anything subsequently set a flag prior to
12539 entering this function. Return NULL_TREE if any checks fail. */
12541 static tree
12542 do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
12544 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
12545 overflow/underflow occurred. If -frounding-math, proceed iff the
12546 result of calling FUNC was exact. */
12547 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
12548 && (!flag_rounding_math || !inexact))
12550 REAL_VALUE_TYPE rr;
12552 real_from_mpfr (&rr, m, type, GMP_RNDN);
12553 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
12554 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
12555 but the mpft_t is not, then we underflowed in the
12556 conversion. */
12557 if (real_isfinite (&rr)
12558 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
12560 REAL_VALUE_TYPE rmode;
12562 real_convert (&rmode, TYPE_MODE (type), &rr);
12563 /* Proceed iff the specified mode can hold the value. */
12564 if (real_identical (&rmode, &rr))
12565 return build_real (type, rmode);
12568 return NULL_TREE;
12571 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
12572 FUNC on it and return the resulting value as a tree with type TYPE.
12573 If MIN and/or MAX are not NULL, then the supplied ARG must be
12574 within those bounds. If INCLUSIVE is true, then MIN/MAX are
12575 acceptable values, otherwise they are not. The mpfr precision is
12576 set to the precision of TYPE. We assume that function FUNC returns
12577 zero if the result could be calculated exactly within the requested
12578 precision. */
12580 static tree
12581 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
12582 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
12583 bool inclusive)
12585 tree result = NULL_TREE;
12587 STRIP_NOPS (arg);
12589 /* To proceed, MPFR must exactly represent the target floating point
12590 format, which only happens when the target base equals two. */
12591 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12592 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
12594 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
12596 if (real_isfinite (ra)
12597 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
12598 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
12600 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12601 int inexact;
12602 mpfr_t m;
12604 mpfr_init2 (m, prec);
12605 mpfr_from_real (m, ra, GMP_RNDN);
12606 mpfr_clear_flags ();
12607 inexact = func (m, m, GMP_RNDN);
12608 result = do_mpfr_ckconv (m, type, inexact);
12609 mpfr_clear (m);
12613 return result;
12616 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
12617 FUNC on it and return the resulting value as a tree with type TYPE.
12618 The mpfr precision is set to the precision of TYPE. We assume that
12619 function FUNC returns zero if the result could be calculated
12620 exactly within the requested precision. */
12622 static tree
12623 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
12624 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
12626 tree result = NULL_TREE;
12628 STRIP_NOPS (arg1);
12629 STRIP_NOPS (arg2);
12631 /* To proceed, MPFR must exactly represent the target floating point
12632 format, which only happens when the target base equals two. */
12633 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12634 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
12635 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
12637 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
12638 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
12640 if (real_isfinite (ra1) && real_isfinite (ra2))
12642 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12643 int inexact;
12644 mpfr_t m1, m2;
12646 mpfr_inits2 (prec, m1, m2, NULL);
12647 mpfr_from_real (m1, ra1, GMP_RNDN);
12648 mpfr_from_real (m2, ra2, GMP_RNDN);
12649 mpfr_clear_flags ();
12650 inexact = func (m1, m1, m2, GMP_RNDN);
12651 result = do_mpfr_ckconv (m1, type, inexact);
12652 mpfr_clears (m1, m2, NULL);
12656 return result;
12659 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
12660 FUNC on it and return the resulting value as a tree with type TYPE.
12661 The mpfr precision is set to the precision of TYPE. We assume that
12662 function FUNC returns zero if the result could be calculated
12663 exactly within the requested precision. */
12665 static tree
12666 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
12667 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
12669 tree result = NULL_TREE;
12671 STRIP_NOPS (arg1);
12672 STRIP_NOPS (arg2);
12673 STRIP_NOPS (arg3);
12675 /* To proceed, MPFR must exactly represent the target floating point
12676 format, which only happens when the target base equals two. */
12677 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12678 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
12679 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
12680 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
12682 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
12683 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
12684 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
12686 if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
12688 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12689 int inexact;
12690 mpfr_t m1, m2, m3;
12692 mpfr_inits2 (prec, m1, m2, m3, NULL);
12693 mpfr_from_real (m1, ra1, GMP_RNDN);
12694 mpfr_from_real (m2, ra2, GMP_RNDN);
12695 mpfr_from_real (m3, ra3, GMP_RNDN);
12696 mpfr_clear_flags ();
12697 inexact = func (m1, m1, m2, m3, GMP_RNDN);
12698 result = do_mpfr_ckconv (m1, type, inexact);
12699 mpfr_clears (m1, m2, m3, NULL);
12703 return result;
12706 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
12707 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
12708 If ARG_SINP and ARG_COSP are NULL then the result is returned
12709 as a complex value.
12710 The type is taken from the type of ARG and is used for setting the
12711 precision of the calculation and results. */
12713 static tree
12714 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
12716 tree const type = TREE_TYPE (arg);
12717 tree result = NULL_TREE;
12719 STRIP_NOPS (arg);
12721 /* To proceed, MPFR must exactly represent the target floating point
12722 format, which only happens when the target base equals two. */
12723 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12724 && TREE_CODE (arg) == REAL_CST
12725 && !TREE_OVERFLOW (arg))
12727 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
12729 if (real_isfinite (ra))
12731 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12732 tree result_s, result_c;
12733 int inexact;
12734 mpfr_t m, ms, mc;
12736 mpfr_inits2 (prec, m, ms, mc, NULL);
12737 mpfr_from_real (m, ra, GMP_RNDN);
12738 mpfr_clear_flags ();
12739 inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
12740 result_s = do_mpfr_ckconv (ms, type, inexact);
12741 result_c = do_mpfr_ckconv (mc, type, inexact);
12742 mpfr_clears (m, ms, mc, NULL);
12743 if (result_s && result_c)
12745 /* If we are to return in a complex value do so. */
12746 if (!arg_sinp && !arg_cosp)
12747 return build_complex (build_complex_type (type),
12748 result_c, result_s);
12750 /* Dereference the sin/cos pointer arguments. */
12751 arg_sinp = build_fold_indirect_ref (arg_sinp);
12752 arg_cosp = build_fold_indirect_ref (arg_cosp);
12753 /* Proceed if valid pointer type were passed in. */
12754 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
12755 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
12757 /* Set the values. */
12758 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
12759 result_s);
12760 TREE_SIDE_EFFECTS (result_s) = 1;
12761 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
12762 result_c);
12763 TREE_SIDE_EFFECTS (result_c) = 1;
12764 /* Combine the assignments into a compound expr. */
12765 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
12766 result_s, result_c));
12771 return result;
12774 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
12775 /* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
12776 two-argument mpfr order N Bessel function FUNC on them and return
12777 the resulting value as a tree with type TYPE. The mpfr precision
12778 is set to the precision of TYPE. We assume that function FUNC
12779 returns zero if the result could be calculated exactly within the
12780 requested precision. */
12781 static tree
12782 do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
12783 int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
12784 const REAL_VALUE_TYPE *min, bool inclusive)
12786 tree result = NULL_TREE;
12788 STRIP_NOPS (arg1);
12789 STRIP_NOPS (arg2);
12791 /* To proceed, MPFR must exactly represent the target floating point
12792 format, which only happens when the target base equals two. */
12793 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12794 && host_integerp (arg1, 0)
12795 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
12797 const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
12798 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
12800 if (n == (long)n
12801 && real_isfinite (ra)
12802 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
12804 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12805 int inexact;
12806 mpfr_t m;
12808 mpfr_init2 (m, prec);
12809 mpfr_from_real (m, ra, GMP_RNDN);
12810 mpfr_clear_flags ();
12811 inexact = func (m, n, m, GMP_RNDN);
12812 result = do_mpfr_ckconv (m, type, inexact);
12813 mpfr_clear (m);
12817 return result;
12820 /* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
12821 the pointer *(ARG_QUO) and return the result. The type is taken
12822 from the type of ARG0 and is used for setting the precision of the
12823 calculation and results. */
12825 static tree
12826 do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
12828 tree const type = TREE_TYPE (arg0);
12829 tree result = NULL_TREE;
12831 STRIP_NOPS (arg0);
12832 STRIP_NOPS (arg1);
12834 /* To proceed, MPFR must exactly represent the target floating point
12835 format, which only happens when the target base equals two. */
12836 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12837 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
12838 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
12840 const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
12841 const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
12843 if (real_isfinite (ra0) && real_isfinite (ra1))
12845 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12846 tree result_rem;
12847 long integer_quo;
12848 mpfr_t m0, m1;
12850 mpfr_inits2 (prec, m0, m1, NULL);
12851 mpfr_from_real (m0, ra0, GMP_RNDN);
12852 mpfr_from_real (m1, ra1, GMP_RNDN);
12853 mpfr_clear_flags ();
12854 mpfr_remquo (m0, &integer_quo, m0, m1, GMP_RNDN);
12855 /* Remquo is independent of the rounding mode, so pass
12856 inexact=0 to do_mpfr_ckconv(). */
12857 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
12858 mpfr_clears (m0, m1, NULL);
12859 if (result_rem)
12861 /* MPFR calculates quo in the host's long so it may
12862 return more bits in quo than the target int can hold
12863 if sizeof(host long) > sizeof(target int). This can
12864 happen even for native compilers in LP64 mode. In
12865 these cases, modulo the quo value with the largest
12866 number that the target int can hold while leaving one
12867 bit for the sign. */
12868 if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
12869 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
12871 /* Dereference the quo pointer argument. */
12872 arg_quo = build_fold_indirect_ref (arg_quo);
12873 /* Proceed iff a valid pointer type was passed in. */
12874 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
12876 /* Set the value. */
12877 tree result_quo = fold_build2 (MODIFY_EXPR,
12878 TREE_TYPE (arg_quo), arg_quo,
12879 build_int_cst (NULL, integer_quo));
12880 TREE_SIDE_EFFECTS (result_quo) = 1;
12881 /* Combine the quo assignment with the rem. */
12882 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
12883 result_quo, result_rem));
12888 return result;
12891 /* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
12892 resulting value as a tree with type TYPE. The mpfr precision is
12893 set to the precision of TYPE. We assume that this mpfr function
12894 returns zero if the result could be calculated exactly within the
12895 requested precision. In addition, the integer pointer represented
12896 by ARG_SG will be dereferenced and set to the appropriate signgam
12897 (-1,1) value. */
12899 static tree
12900 do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
12902 tree result = NULL_TREE;
12904 STRIP_NOPS (arg);
12906 /* To proceed, MPFR must exactly represent the target floating point
12907 format, which only happens when the target base equals two. Also
12908 verify ARG is a constant and that ARG_SG is an int pointer. */
12909 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12910 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
12911 && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
12912 && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
12914 const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
12916 /* In addition to NaN and Inf, the argument cannot be zero or a
12917 negative integer. */
12918 if (real_isfinite (ra)
12919 && ra->cl != rvc_zero
12920 && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
12922 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12923 int inexact, sg;
12924 mpfr_t m;
12925 tree result_lg;
12927 mpfr_init2 (m, prec);
12928 mpfr_from_real (m, ra, GMP_RNDN);
12929 mpfr_clear_flags ();
12930 inexact = mpfr_lgamma (m, &sg, m, GMP_RNDN);
12931 result_lg = do_mpfr_ckconv (m, type, inexact);
12932 mpfr_clear (m);
12933 if (result_lg)
12935 tree result_sg;
12937 /* Dereference the arg_sg pointer argument. */
12938 arg_sg = build_fold_indirect_ref (arg_sg);
12939 /* Assign the signgam value into *arg_sg. */
12940 result_sg = fold_build2 (MODIFY_EXPR,
12941 TREE_TYPE (arg_sg), arg_sg,
12942 build_int_cst (NULL, sg));
12943 TREE_SIDE_EFFECTS (result_sg) = 1;
12944 /* Combine the signgam assignment with the lgamma result. */
12945 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
12946 result_sg, result_lg));
12951 return result;
12953 #endif