* configure.in: When removing Makefiles to force a reconfigure, also
[official-gcc.git] / gcc / builtins.c
blob6f79b2931bfefe09e18097820246fb6506919101
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
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"
52 #ifndef PAD_VARARGS_DOWN
53 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
54 #endif
56 /* Define the names of the builtin function types and codes. */
57 const char *const built_in_class_names[4]
58 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
60 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
61 const char * built_in_names[(int) END_BUILTINS] =
63 #include "builtins.def"
65 #undef DEF_BUILTIN
67 /* Setup an array of _DECL trees, make sure each element is
68 initialized to NULL_TREE. */
69 tree built_in_decls[(int) END_BUILTINS];
70 /* Declarations used when constructing the builtin implicitly in the compiler.
71 It may be NULL_TREE when this is invalid (for instance runtime is not
72 required to implement the function call in all cases). */
73 tree implicit_built_in_decls[(int) END_BUILTINS];
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static void expand_builtin_update_setjmp_buf (rtx);
85 static void expand_builtin_prefetch (tree);
86 static rtx expand_builtin_apply_args (void);
87 static rtx expand_builtin_apply_args_1 (void);
88 static rtx expand_builtin_apply (rtx, rtx, rtx);
89 static void expand_builtin_return (rtx);
90 static enum type_class type_to_class (tree);
91 static rtx expand_builtin_classify_type (tree);
92 static void expand_errno_check (tree, rtx);
93 static rtx expand_builtin_mathfn (tree, rtx, rtx);
94 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
96 static rtx expand_builtin_sincos (tree);
97 static rtx expand_builtin_cexpi (tree, rtx, rtx);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_int_roundingfn_2 (tree, rtx, rtx);
100 static rtx expand_builtin_args_info (tree);
101 static rtx expand_builtin_next_arg (void);
102 static rtx expand_builtin_va_start (tree);
103 static rtx expand_builtin_va_end (tree);
104 static rtx expand_builtin_va_copy (tree);
105 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
107 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
108 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
109 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
115 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode);
116 static rtx expand_builtin_bcopy (tree);
117 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
118 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
119 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static bool integer_valued_real_p (tree);
144 static tree fold_trunc_transparent_mathfn (tree, tree);
145 static bool readonly_data_expr (tree);
146 static rtx expand_builtin_fabs (tree, rtx, rtx);
147 static rtx expand_builtin_signbit (tree, rtx);
148 static tree fold_builtin_sqrt (tree, tree);
149 static tree fold_builtin_cbrt (tree, tree);
150 static tree fold_builtin_pow (tree, tree, tree);
151 static tree fold_builtin_powi (tree, tree, tree);
152 static tree fold_builtin_cos (tree, tree, tree);
153 static tree fold_builtin_cosh (tree, tree, tree);
154 static tree fold_builtin_tan (tree, tree);
155 static tree fold_builtin_trunc (tree, tree);
156 static tree fold_builtin_floor (tree, tree);
157 static tree fold_builtin_ceil (tree, tree);
158 static tree fold_builtin_round (tree, tree);
159 static tree fold_builtin_int_roundingfn (tree, tree);
160 static tree fold_builtin_bitop (tree, tree);
161 static tree fold_builtin_memory_op (tree, tree, bool, int);
162 static tree fold_builtin_strchr (tree, tree);
163 static tree fold_builtin_memcmp (tree);
164 static tree fold_builtin_strcmp (tree);
165 static tree fold_builtin_strncmp (tree);
166 static tree fold_builtin_signbit (tree, tree);
167 static tree fold_builtin_copysign (tree, tree, tree);
168 static tree fold_builtin_isascii (tree);
169 static tree fold_builtin_toascii (tree);
170 static tree fold_builtin_isdigit (tree);
171 static tree fold_builtin_fabs (tree, tree);
172 static tree fold_builtin_abs (tree, tree);
173 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
174 enum tree_code);
175 static tree fold_builtin_1 (tree, tree, bool);
177 static tree fold_builtin_strpbrk (tree, tree);
178 static tree fold_builtin_strstr (tree, tree);
179 static tree fold_builtin_strrchr (tree, tree);
180 static tree fold_builtin_strcat (tree);
181 static tree fold_builtin_strncat (tree);
182 static tree fold_builtin_strspn (tree);
183 static tree fold_builtin_strcspn (tree);
184 static tree fold_builtin_sprintf (tree, int);
186 static rtx expand_builtin_object_size (tree);
187 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
188 enum built_in_function);
189 static void maybe_emit_chk_warning (tree, enum built_in_function);
190 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
191 static tree fold_builtin_object_size (tree);
192 static tree fold_builtin_strcat_chk (tree, tree);
193 static tree fold_builtin_strncat_chk (tree, tree);
194 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
195 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
196 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
197 static bool init_target_chars (void);
199 static unsigned HOST_WIDE_INT target_newline;
200 static unsigned HOST_WIDE_INT target_percent;
201 static unsigned HOST_WIDE_INT target_c;
202 static unsigned HOST_WIDE_INT target_s;
203 static char target_percent_c[3];
204 static char target_percent_s[3];
205 static char target_percent_s_newline[4];
206 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
207 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
208 static tree do_mpfr_arg2 (tree, tree, tree,
209 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
210 static tree do_mpfr_arg3 (tree, tree, tree, tree,
211 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
212 static tree do_mpfr_sincos (tree, tree, tree);
214 /* Return true if NODE should be considered for inline expansion regardless
215 of the optimization level. This means whenever a function is invoked with
216 its "internal" name, which normally contains the prefix "__builtin". */
218 static bool called_as_built_in (tree node)
220 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
221 if (strncmp (name, "__builtin_", 10) == 0)
222 return true;
223 if (strncmp (name, "__sync_", 7) == 0)
224 return true;
225 return false;
228 /* Return the alignment in bits of EXP, a pointer valued expression.
229 But don't return more than MAX_ALIGN no matter what.
230 The alignment returned is, by default, the alignment of the thing that
231 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
233 Otherwise, look at the expression to see if we can do better, i.e., if the
234 expression is actually pointing at an object whose alignment is tighter. */
237 get_pointer_alignment (tree exp, unsigned int max_align)
239 unsigned int align, inner;
241 /* We rely on TER to compute accurate alignment information. */
242 if (!(optimize && flag_tree_ter))
243 return 0;
245 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
246 return 0;
248 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
249 align = MIN (align, max_align);
251 while (1)
253 switch (TREE_CODE (exp))
255 case NOP_EXPR:
256 case CONVERT_EXPR:
257 case NON_LVALUE_EXPR:
258 exp = TREE_OPERAND (exp, 0);
259 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
260 return align;
262 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
263 align = MIN (inner, max_align);
264 break;
266 case PLUS_EXPR:
267 /* If sum of pointer + int, restrict our maximum alignment to that
268 imposed by the integer. If not, we can't do any better than
269 ALIGN. */
270 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
271 return align;
273 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
274 & (max_align / BITS_PER_UNIT - 1))
275 != 0)
276 max_align >>= 1;
278 exp = TREE_OPERAND (exp, 0);
279 break;
281 case ADDR_EXPR:
282 /* See what we are pointing at and look at its alignment. */
283 exp = TREE_OPERAND (exp, 0);
284 inner = max_align;
285 if (handled_component_p (exp))
287 HOST_WIDE_INT bitsize, bitpos;
288 tree offset;
289 enum machine_mode mode;
290 int unsignedp, volatilep;
292 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
293 &mode, &unsignedp, &volatilep, true);
294 if (bitpos)
295 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
296 if (offset && TREE_CODE (offset) == PLUS_EXPR
297 && host_integerp (TREE_OPERAND (offset, 1), 1))
299 /* Any overflow in calculating offset_bits won't change
300 the alignment. */
301 unsigned offset_bits
302 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
303 * BITS_PER_UNIT);
305 if (offset_bits)
306 inner = MIN (inner, (offset_bits & -offset_bits));
307 offset = TREE_OPERAND (offset, 0);
309 if (offset && TREE_CODE (offset) == MULT_EXPR
310 && host_integerp (TREE_OPERAND (offset, 1), 1))
312 /* Any overflow in calculating offset_factor won't change
313 the alignment. */
314 unsigned offset_factor
315 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
316 * BITS_PER_UNIT);
318 if (offset_factor)
319 inner = MIN (inner, (offset_factor & -offset_factor));
321 else if (offset)
322 inner = MIN (inner, BITS_PER_UNIT);
324 if (TREE_CODE (exp) == FUNCTION_DECL)
325 align = FUNCTION_BOUNDARY;
326 else if (DECL_P (exp))
327 align = MIN (inner, DECL_ALIGN (exp));
328 #ifdef CONSTANT_ALIGNMENT
329 else if (CONSTANT_CLASS_P (exp))
330 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
331 #endif
332 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
333 || TREE_CODE (exp) == INDIRECT_REF)
334 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
335 else
336 align = MIN (align, inner);
337 return MIN (align, max_align);
339 default:
340 return align;
345 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
346 way, because it could contain a zero byte in the middle.
347 TREE_STRING_LENGTH is the size of the character array, not the string.
349 ONLY_VALUE should be nonzero if the result is not going to be emitted
350 into the instruction stream and zero if it is going to be expanded.
351 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
352 is returned, otherwise NULL, since
353 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
354 evaluate the side-effects.
356 The value returned is of type `ssizetype'.
358 Unfortunately, string_constant can't access the values of const char
359 arrays with initializers, so neither can we do so here. */
361 tree
362 c_strlen (tree src, int only_value)
364 tree offset_node;
365 HOST_WIDE_INT offset;
366 int max;
367 const char *ptr;
369 STRIP_NOPS (src);
370 if (TREE_CODE (src) == COND_EXPR
371 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
373 tree len1, len2;
375 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
376 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
377 if (tree_int_cst_equal (len1, len2))
378 return len1;
381 if (TREE_CODE (src) == COMPOUND_EXPR
382 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
383 return c_strlen (TREE_OPERAND (src, 1), only_value);
385 src = string_constant (src, &offset_node);
386 if (src == 0)
387 return 0;
389 max = TREE_STRING_LENGTH (src) - 1;
390 ptr = TREE_STRING_POINTER (src);
392 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
394 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
395 compute the offset to the following null if we don't know where to
396 start searching for it. */
397 int i;
399 for (i = 0; i < max; i++)
400 if (ptr[i] == 0)
401 return 0;
403 /* We don't know the starting offset, but we do know that the string
404 has no internal zero bytes. We can assume that the offset falls
405 within the bounds of the string; otherwise, the programmer deserves
406 what he gets. Subtract the offset from the length of the string,
407 and return that. This would perhaps not be valid if we were dealing
408 with named arrays in addition to literal string constants. */
410 return size_diffop (size_int (max), offset_node);
413 /* We have a known offset into the string. Start searching there for
414 a null character if we can represent it as a single HOST_WIDE_INT. */
415 if (offset_node == 0)
416 offset = 0;
417 else if (! host_integerp (offset_node, 0))
418 offset = -1;
419 else
420 offset = tree_low_cst (offset_node, 0);
422 /* If the offset is known to be out of bounds, warn, and call strlen at
423 runtime. */
424 if (offset < 0 || offset > max)
426 warning (0, "offset outside bounds of constant string");
427 return 0;
430 /* Use strlen to search for the first zero byte. Since any strings
431 constructed with build_string will have nulls appended, we win even
432 if we get handed something like (char[4])"abcd".
434 Since OFFSET is our starting index into the string, no further
435 calculation is needed. */
436 return ssize_int (strlen (ptr + offset));
439 /* Return a char pointer for a C string if it is a string constant
440 or sum of string constant and integer constant. */
442 static const char *
443 c_getstr (tree src)
445 tree offset_node;
447 src = string_constant (src, &offset_node);
448 if (src == 0)
449 return 0;
451 if (offset_node == 0)
452 return TREE_STRING_POINTER (src);
453 else if (!host_integerp (offset_node, 1)
454 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
455 return 0;
457 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
460 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
461 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
463 static rtx
464 c_readstr (const char *str, enum machine_mode mode)
466 HOST_WIDE_INT c[2];
467 HOST_WIDE_INT ch;
468 unsigned int i, j;
470 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
472 c[0] = 0;
473 c[1] = 0;
474 ch = 1;
475 for (i = 0; i < GET_MODE_SIZE (mode); i++)
477 j = i;
478 if (WORDS_BIG_ENDIAN)
479 j = GET_MODE_SIZE (mode) - i - 1;
480 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
481 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
482 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
483 j *= BITS_PER_UNIT;
484 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
486 if (ch)
487 ch = (unsigned char) str[i];
488 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
490 return immed_double_const (c[0], c[1], mode);
493 /* Cast a target constant CST to target CHAR and if that value fits into
494 host char type, return zero and put that value into variable pointed to by
495 P. */
497 static int
498 target_char_cast (tree cst, char *p)
500 unsigned HOST_WIDE_INT val, hostval;
502 if (!host_integerp (cst, 1)
503 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
504 return 1;
506 val = tree_low_cst (cst, 1);
507 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
508 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
510 hostval = val;
511 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
512 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
514 if (val != hostval)
515 return 1;
517 *p = hostval;
518 return 0;
521 /* Similar to save_expr, but assumes that arbitrary code is not executed
522 in between the multiple evaluations. In particular, we assume that a
523 non-addressable local variable will not be modified. */
525 static tree
526 builtin_save_expr (tree exp)
528 if (TREE_ADDRESSABLE (exp) == 0
529 && (TREE_CODE (exp) == PARM_DECL
530 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
531 return exp;
533 return save_expr (exp);
536 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
537 times to get the address of either a higher stack frame, or a return
538 address located within it (depending on FNDECL_CODE). */
540 static rtx
541 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
543 int i;
545 #ifdef INITIAL_FRAME_ADDRESS_RTX
546 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
547 #else
548 rtx tem;
550 /* For a zero count with __builtin_return_address, we don't care what
551 frame address we return, because target-specific definitions will
552 override us. Therefore frame pointer elimination is OK, and using
553 the soft frame pointer is OK.
555 For a nonzero count, or a zero count with __builtin_frame_address,
556 we require a stable offset from the current frame pointer to the
557 previous one, so we must use the hard frame pointer, and
558 we must disable frame pointer elimination. */
559 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
560 tem = frame_pointer_rtx;
561 else
563 tem = hard_frame_pointer_rtx;
565 /* Tell reload not to eliminate the frame pointer. */
566 current_function_accesses_prior_frames = 1;
568 #endif
570 /* Some machines need special handling before we can access
571 arbitrary frames. For example, on the SPARC, we must first flush
572 all register windows to the stack. */
573 #ifdef SETUP_FRAME_ADDRESSES
574 if (count > 0)
575 SETUP_FRAME_ADDRESSES ();
576 #endif
578 /* On the SPARC, the return address is not in the frame, it is in a
579 register. There is no way to access it off of the current frame
580 pointer, but it can be accessed off the previous frame pointer by
581 reading the value from the register window save area. */
582 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
583 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
584 count--;
585 #endif
587 /* Scan back COUNT frames to the specified frame. */
588 for (i = 0; i < count; i++)
590 /* Assume the dynamic chain pointer is in the word that the
591 frame address points to, unless otherwise specified. */
592 #ifdef DYNAMIC_CHAIN_ADDRESS
593 tem = DYNAMIC_CHAIN_ADDRESS (tem);
594 #endif
595 tem = memory_address (Pmode, tem);
596 tem = gen_frame_mem (Pmode, tem);
597 tem = copy_to_reg (tem);
600 /* For __builtin_frame_address, return what we've got. But, on
601 the SPARC for example, we may have to add a bias. */
602 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
603 #ifdef FRAME_ADDR_RTX
604 return FRAME_ADDR_RTX (tem);
605 #else
606 return tem;
607 #endif
609 /* For __builtin_return_address, get the return address from that frame. */
610 #ifdef RETURN_ADDR_RTX
611 tem = RETURN_ADDR_RTX (count, tem);
612 #else
613 tem = memory_address (Pmode,
614 plus_constant (tem, GET_MODE_SIZE (Pmode)));
615 tem = gen_frame_mem (Pmode, tem);
616 #endif
617 return tem;
620 /* Alias set used for setjmp buffer. */
621 static HOST_WIDE_INT setjmp_alias_set = -1;
623 /* Construct the leading half of a __builtin_setjmp call. Control will
624 return to RECEIVER_LABEL. This is also called directly by the SJLJ
625 exception handling code. */
627 void
628 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
630 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
631 rtx stack_save;
632 rtx mem;
634 if (setjmp_alias_set == -1)
635 setjmp_alias_set = new_alias_set ();
637 buf_addr = convert_memory_address (Pmode, buf_addr);
639 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
641 /* We store the frame pointer and the address of receiver_label in
642 the buffer and use the rest of it for the stack save area, which
643 is machine-dependent. */
645 mem = gen_rtx_MEM (Pmode, buf_addr);
646 set_mem_alias_set (mem, setjmp_alias_set);
647 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
649 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
650 set_mem_alias_set (mem, setjmp_alias_set);
652 emit_move_insn (validize_mem (mem),
653 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
655 stack_save = gen_rtx_MEM (sa_mode,
656 plus_constant (buf_addr,
657 2 * GET_MODE_SIZE (Pmode)));
658 set_mem_alias_set (stack_save, setjmp_alias_set);
659 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
661 /* If there is further processing to do, do it. */
662 #ifdef HAVE_builtin_setjmp_setup
663 if (HAVE_builtin_setjmp_setup)
664 emit_insn (gen_builtin_setjmp_setup (buf_addr));
665 #endif
667 /* Tell optimize_save_area_alloca that extra work is going to
668 need to go on during alloca. */
669 current_function_calls_setjmp = 1;
671 /* Set this so all the registers get saved in our frame; we need to be
672 able to copy the saved values for any registers from frames we unwind. */
673 current_function_has_nonlocal_label = 1;
676 /* Construct the trailing part of a __builtin_setjmp call. This is
677 also called directly by the SJLJ exception handling code. */
679 void
680 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
682 /* Clobber the FP when we get here, so we have to make sure it's
683 marked as used by this function. */
684 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
686 /* Mark the static chain as clobbered here so life information
687 doesn't get messed up for it. */
688 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
690 /* Now put in the code to restore the frame pointer, and argument
691 pointer, if needed. */
692 #ifdef HAVE_nonlocal_goto
693 if (! HAVE_nonlocal_goto)
694 #endif
696 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
697 /* This might change the hard frame pointer in ways that aren't
698 apparent to early optimization passes, so force a clobber. */
699 emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx));
702 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
703 if (fixed_regs[ARG_POINTER_REGNUM])
705 #ifdef ELIMINABLE_REGS
706 size_t i;
707 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
709 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
710 if (elim_regs[i].from == ARG_POINTER_REGNUM
711 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
712 break;
714 if (i == ARRAY_SIZE (elim_regs))
715 #endif
717 /* Now restore our arg pointer from the address at which it
718 was saved in our stack frame. */
719 emit_move_insn (virtual_incoming_args_rtx,
720 copy_to_reg (get_arg_pointer_save_area (cfun)));
723 #endif
725 #ifdef HAVE_builtin_setjmp_receiver
726 if (HAVE_builtin_setjmp_receiver)
727 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
728 else
729 #endif
730 #ifdef HAVE_nonlocal_goto_receiver
731 if (HAVE_nonlocal_goto_receiver)
732 emit_insn (gen_nonlocal_goto_receiver ());
733 else
734 #endif
735 { /* Nothing */ }
737 /* @@@ This is a kludge. Not all machine descriptions define a blockage
738 insn, but we must not allow the code we just generated to be reordered
739 by scheduling. Specifically, the update of the frame pointer must
740 happen immediately, not later. So emit an ASM_INPUT to act as blockage
741 insn. */
742 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
745 /* __builtin_longjmp is passed a pointer to an array of five words (not
746 all will be used on all machines). It operates similarly to the C
747 library function of the same name, but is more efficient. Much of
748 the code below is copied from the handling of non-local gotos. */
750 static void
751 expand_builtin_longjmp (rtx buf_addr, rtx value)
753 rtx fp, lab, stack, insn, last;
754 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
756 if (setjmp_alias_set == -1)
757 setjmp_alias_set = new_alias_set ();
759 buf_addr = convert_memory_address (Pmode, buf_addr);
761 buf_addr = force_reg (Pmode, buf_addr);
763 /* We used to store value in static_chain_rtx, but that fails if pointers
764 are smaller than integers. We instead require that the user must pass
765 a second argument of 1, because that is what builtin_setjmp will
766 return. This also makes EH slightly more efficient, since we are no
767 longer copying around a value that we don't care about. */
768 gcc_assert (value == const1_rtx);
770 last = get_last_insn ();
771 #ifdef HAVE_builtin_longjmp
772 if (HAVE_builtin_longjmp)
773 emit_insn (gen_builtin_longjmp (buf_addr));
774 else
775 #endif
777 fp = gen_rtx_MEM (Pmode, buf_addr);
778 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
779 GET_MODE_SIZE (Pmode)));
781 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
782 2 * GET_MODE_SIZE (Pmode)));
783 set_mem_alias_set (fp, setjmp_alias_set);
784 set_mem_alias_set (lab, setjmp_alias_set);
785 set_mem_alias_set (stack, setjmp_alias_set);
787 /* Pick up FP, label, and SP from the block and jump. This code is
788 from expand_goto in stmt.c; see there for detailed comments. */
789 #ifdef HAVE_nonlocal_goto
790 if (HAVE_nonlocal_goto)
791 /* We have to pass a value to the nonlocal_goto pattern that will
792 get copied into the static_chain pointer, but it does not matter
793 what that value is, because builtin_setjmp does not use it. */
794 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
795 else
796 #endif
798 lab = copy_to_reg (lab);
800 emit_insn (gen_rtx_CLOBBER (VOIDmode,
801 gen_rtx_MEM (BLKmode,
802 gen_rtx_SCRATCH (VOIDmode))));
803 emit_insn (gen_rtx_CLOBBER (VOIDmode,
804 gen_rtx_MEM (BLKmode,
805 hard_frame_pointer_rtx)));
807 emit_move_insn (hard_frame_pointer_rtx, fp);
808 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
810 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
811 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
812 emit_indirect_jump (lab);
816 /* Search backwards and mark the jump insn as a non-local goto.
817 Note that this precludes the use of __builtin_longjmp to a
818 __builtin_setjmp target in the same function. However, we've
819 already cautioned the user that these functions are for
820 internal exception handling use only. */
821 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
823 gcc_assert (insn != last);
825 if (JUMP_P (insn))
827 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
828 REG_NOTES (insn));
829 break;
831 else if (CALL_P (insn))
832 break;
836 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
837 and the address of the save area. */
839 static rtx
840 expand_builtin_nonlocal_goto (tree arglist)
842 tree t_label, t_save_area;
843 rtx r_label, r_save_area, r_fp, r_sp, insn;
845 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
846 return NULL_RTX;
848 t_label = TREE_VALUE (arglist);
849 arglist = TREE_CHAIN (arglist);
850 t_save_area = TREE_VALUE (arglist);
852 r_label = expand_normal (t_label);
853 r_label = convert_memory_address (Pmode, r_label);
854 r_save_area = expand_normal (t_save_area);
855 r_save_area = convert_memory_address (Pmode, r_save_area);
856 r_fp = gen_rtx_MEM (Pmode, r_save_area);
857 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
858 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
860 current_function_has_nonlocal_goto = 1;
862 #ifdef HAVE_nonlocal_goto
863 /* ??? We no longer need to pass the static chain value, afaik. */
864 if (HAVE_nonlocal_goto)
865 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
866 else
867 #endif
869 r_label = copy_to_reg (r_label);
871 emit_insn (gen_rtx_CLOBBER (VOIDmode,
872 gen_rtx_MEM (BLKmode,
873 gen_rtx_SCRATCH (VOIDmode))));
875 emit_insn (gen_rtx_CLOBBER (VOIDmode,
876 gen_rtx_MEM (BLKmode,
877 hard_frame_pointer_rtx)));
879 /* Restore frame pointer for containing function.
880 This sets the actual hard register used for the frame pointer
881 to the location of the function's incoming static chain info.
882 The non-local goto handler will then adjust it to contain the
883 proper value and reload the argument pointer, if needed. */
884 emit_move_insn (hard_frame_pointer_rtx, r_fp);
885 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
887 /* USE of hard_frame_pointer_rtx added for consistency;
888 not clear if really needed. */
889 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
890 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
891 emit_indirect_jump (r_label);
894 /* Search backwards to the jump insn and mark it as a
895 non-local goto. */
896 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
898 if (JUMP_P (insn))
900 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
901 const0_rtx, REG_NOTES (insn));
902 break;
904 else if (CALL_P (insn))
905 break;
908 return const0_rtx;
911 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
912 (not all will be used on all machines) that was passed to __builtin_setjmp.
913 It updates the stack pointer in that block to correspond to the current
914 stack pointer. */
916 static void
917 expand_builtin_update_setjmp_buf (rtx buf_addr)
919 enum machine_mode sa_mode = Pmode;
920 rtx stack_save;
923 #ifdef HAVE_save_stack_nonlocal
924 if (HAVE_save_stack_nonlocal)
925 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
926 #endif
927 #ifdef STACK_SAVEAREA_MODE
928 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
929 #endif
931 stack_save
932 = gen_rtx_MEM (sa_mode,
933 memory_address
934 (sa_mode,
935 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
937 #ifdef HAVE_setjmp
938 if (HAVE_setjmp)
939 emit_insn (gen_setjmp ());
940 #endif
942 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
945 /* Expand a call to __builtin_prefetch. For a target that does not support
946 data prefetch, evaluate the memory address argument in case it has side
947 effects. */
949 static void
950 expand_builtin_prefetch (tree arglist)
952 tree arg0, arg1, arg2;
953 rtx op0, op1, op2;
955 if (!validate_arglist (arglist, POINTER_TYPE, 0))
956 return;
958 arg0 = TREE_VALUE (arglist);
959 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
960 zero (read) and argument 2 (locality) defaults to 3 (high degree of
961 locality). */
962 if (TREE_CHAIN (arglist))
964 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
965 if (TREE_CHAIN (TREE_CHAIN (arglist)))
966 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
967 else
968 arg2 = build_int_cst (NULL_TREE, 3);
970 else
972 arg1 = integer_zero_node;
973 arg2 = build_int_cst (NULL_TREE, 3);
976 /* Argument 0 is an address. */
977 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
979 /* Argument 1 (read/write flag) must be a compile-time constant int. */
980 if (TREE_CODE (arg1) != INTEGER_CST)
982 error ("second argument to %<__builtin_prefetch%> must be a constant");
983 arg1 = integer_zero_node;
985 op1 = expand_normal (arg1);
986 /* Argument 1 must be either zero or one. */
987 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
989 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
990 " using zero");
991 op1 = const0_rtx;
994 /* Argument 2 (locality) must be a compile-time constant int. */
995 if (TREE_CODE (arg2) != INTEGER_CST)
997 error ("third argument to %<__builtin_prefetch%> must be a constant");
998 arg2 = integer_zero_node;
1000 op2 = expand_normal (arg2);
1001 /* Argument 2 must be 0, 1, 2, or 3. */
1002 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1004 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1005 op2 = const0_rtx;
1008 #ifdef HAVE_prefetch
1009 if (HAVE_prefetch)
1011 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1012 (op0,
1013 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1014 || (GET_MODE (op0) != Pmode))
1016 op0 = convert_memory_address (Pmode, op0);
1017 op0 = force_reg (Pmode, op0);
1019 emit_insn (gen_prefetch (op0, op1, op2));
1021 #endif
1023 /* Don't do anything with direct references to volatile memory, but
1024 generate code to handle other side effects. */
1025 if (!MEM_P (op0) && side_effects_p (op0))
1026 emit_insn (op0);
1029 /* Get a MEM rtx for expression EXP which is the address of an operand
1030 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1031 the maximum length of the block of memory that might be accessed or
1032 NULL if unknown. */
1034 static rtx
1035 get_memory_rtx (tree exp, tree len)
1037 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1038 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1040 /* Get an expression we can use to find the attributes to assign to MEM.
1041 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1042 we can. First remove any nops. */
1043 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1044 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1045 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1046 exp = TREE_OPERAND (exp, 0);
1048 if (TREE_CODE (exp) == ADDR_EXPR)
1049 exp = TREE_OPERAND (exp, 0);
1050 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1051 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1052 else
1053 exp = NULL;
1055 /* Honor attributes derived from exp, except for the alias set
1056 (as builtin stringops may alias with anything) and the size
1057 (as stringops may access multiple array elements). */
1058 if (exp)
1060 set_mem_attributes (mem, exp, 0);
1062 /* Allow the string and memory builtins to overflow from one
1063 field into another, see http://gcc.gnu.org/PR23561.
1064 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1065 memory accessed by the string or memory builtin will fit
1066 within the field. */
1067 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1069 tree mem_expr = MEM_EXPR (mem);
1070 HOST_WIDE_INT offset = -1, length = -1;
1071 tree inner = exp;
1073 while (TREE_CODE (inner) == ARRAY_REF
1074 || TREE_CODE (inner) == NOP_EXPR
1075 || TREE_CODE (inner) == CONVERT_EXPR
1076 || TREE_CODE (inner) == NON_LVALUE_EXPR
1077 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1078 || TREE_CODE (inner) == SAVE_EXPR)
1079 inner = TREE_OPERAND (inner, 0);
1081 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1083 if (MEM_OFFSET (mem)
1084 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1085 offset = INTVAL (MEM_OFFSET (mem));
1087 if (offset >= 0 && len && host_integerp (len, 0))
1088 length = tree_low_cst (len, 0);
1090 while (TREE_CODE (inner) == COMPONENT_REF)
1092 tree field = TREE_OPERAND (inner, 1);
1093 gcc_assert (! DECL_BIT_FIELD (field));
1094 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1095 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1097 if (length >= 0
1098 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1099 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1101 HOST_WIDE_INT size
1102 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1103 /* If we can prove the memory starting at XEXP (mem, 0)
1104 and ending at XEXP (mem, 0) + LENGTH will fit into
1105 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1106 if (offset <= size
1107 && length <= size
1108 && offset + length <= size)
1109 break;
1112 if (offset >= 0
1113 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1114 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1115 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1116 / BITS_PER_UNIT;
1117 else
1119 offset = -1;
1120 length = -1;
1123 mem_expr = TREE_OPERAND (mem_expr, 0);
1124 inner = TREE_OPERAND (inner, 0);
1127 if (mem_expr == NULL)
1128 offset = -1;
1129 if (mem_expr != MEM_EXPR (mem))
1131 set_mem_expr (mem, mem_expr);
1132 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1135 set_mem_alias_set (mem, 0);
1136 set_mem_size (mem, NULL_RTX);
1139 return mem;
1142 /* Built-in functions to perform an untyped call and return. */
1144 /* For each register that may be used for calling a function, this
1145 gives a mode used to copy the register's value. VOIDmode indicates
1146 the register is not used for calling a function. If the machine
1147 has register windows, this gives only the outbound registers.
1148 INCOMING_REGNO gives the corresponding inbound register. */
1149 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1151 /* For each register that may be used for returning values, this gives
1152 a mode used to copy the register's value. VOIDmode indicates the
1153 register is not used for returning values. If the machine has
1154 register windows, this gives only the outbound registers.
1155 INCOMING_REGNO gives the corresponding inbound register. */
1156 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1158 /* For each register that may be used for calling a function, this
1159 gives the offset of that register into the block returned by
1160 __builtin_apply_args. 0 indicates that the register is not
1161 used for calling a function. */
1162 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1164 /* Return the size required for the block returned by __builtin_apply_args,
1165 and initialize apply_args_mode. */
1167 static int
1168 apply_args_size (void)
1170 static int size = -1;
1171 int align;
1172 unsigned int regno;
1173 enum machine_mode mode;
1175 /* The values computed by this function never change. */
1176 if (size < 0)
1178 /* The first value is the incoming arg-pointer. */
1179 size = GET_MODE_SIZE (Pmode);
1181 /* The second value is the structure value address unless this is
1182 passed as an "invisible" first argument. */
1183 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1184 size += GET_MODE_SIZE (Pmode);
1186 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1187 if (FUNCTION_ARG_REGNO_P (regno))
1189 mode = reg_raw_mode[regno];
1191 gcc_assert (mode != VOIDmode);
1193 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1194 if (size % align != 0)
1195 size = CEIL (size, align) * align;
1196 apply_args_reg_offset[regno] = size;
1197 size += GET_MODE_SIZE (mode);
1198 apply_args_mode[regno] = mode;
1200 else
1202 apply_args_mode[regno] = VOIDmode;
1203 apply_args_reg_offset[regno] = 0;
1206 return size;
1209 /* Return the size required for the block returned by __builtin_apply,
1210 and initialize apply_result_mode. */
1212 static int
1213 apply_result_size (void)
1215 static int size = -1;
1216 int align, regno;
1217 enum machine_mode mode;
1219 /* The values computed by this function never change. */
1220 if (size < 0)
1222 size = 0;
1224 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1225 if (FUNCTION_VALUE_REGNO_P (regno))
1227 mode = reg_raw_mode[regno];
1229 gcc_assert (mode != VOIDmode);
1231 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1232 if (size % align != 0)
1233 size = CEIL (size, align) * align;
1234 size += GET_MODE_SIZE (mode);
1235 apply_result_mode[regno] = mode;
1237 else
1238 apply_result_mode[regno] = VOIDmode;
1240 /* Allow targets that use untyped_call and untyped_return to override
1241 the size so that machine-specific information can be stored here. */
1242 #ifdef APPLY_RESULT_SIZE
1243 size = APPLY_RESULT_SIZE;
1244 #endif
1246 return size;
1249 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1250 /* Create a vector describing the result block RESULT. If SAVEP is true,
1251 the result block is used to save the values; otherwise it is used to
1252 restore the values. */
1254 static rtx
1255 result_vector (int savep, rtx result)
1257 int regno, size, align, nelts;
1258 enum machine_mode mode;
1259 rtx reg, mem;
1260 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1262 size = nelts = 0;
1263 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1264 if ((mode = apply_result_mode[regno]) != VOIDmode)
1266 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1267 if (size % align != 0)
1268 size = CEIL (size, align) * align;
1269 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1270 mem = adjust_address (result, mode, size);
1271 savevec[nelts++] = (savep
1272 ? gen_rtx_SET (VOIDmode, mem, reg)
1273 : gen_rtx_SET (VOIDmode, reg, mem));
1274 size += GET_MODE_SIZE (mode);
1276 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1278 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1280 /* Save the state required to perform an untyped call with the same
1281 arguments as were passed to the current function. */
1283 static rtx
1284 expand_builtin_apply_args_1 (void)
1286 rtx registers, tem;
1287 int size, align, regno;
1288 enum machine_mode mode;
1289 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1291 /* Create a block where the arg-pointer, structure value address,
1292 and argument registers can be saved. */
1293 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1295 /* Walk past the arg-pointer and structure value address. */
1296 size = GET_MODE_SIZE (Pmode);
1297 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1298 size += GET_MODE_SIZE (Pmode);
1300 /* Save each register used in calling a function to the block. */
1301 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1302 if ((mode = apply_args_mode[regno]) != VOIDmode)
1304 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1305 if (size % align != 0)
1306 size = CEIL (size, align) * align;
1308 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1310 emit_move_insn (adjust_address (registers, mode, size), tem);
1311 size += GET_MODE_SIZE (mode);
1314 /* Save the arg pointer to the block. */
1315 tem = copy_to_reg (virtual_incoming_args_rtx);
1316 #ifdef STACK_GROWS_DOWNWARD
1317 /* We need the pointer as the caller actually passed them to us, not
1318 as we might have pretended they were passed. Make sure it's a valid
1319 operand, as emit_move_insn isn't expected to handle a PLUS. */
1321 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1322 NULL_RTX);
1323 #endif
1324 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1326 size = GET_MODE_SIZE (Pmode);
1328 /* Save the structure value address unless this is passed as an
1329 "invisible" first argument. */
1330 if (struct_incoming_value)
1332 emit_move_insn (adjust_address (registers, Pmode, size),
1333 copy_to_reg (struct_incoming_value));
1334 size += GET_MODE_SIZE (Pmode);
1337 /* Return the address of the block. */
1338 return copy_addr_to_reg (XEXP (registers, 0));
1341 /* __builtin_apply_args returns block of memory allocated on
1342 the stack into which is stored the arg pointer, structure
1343 value address, static chain, and all the registers that might
1344 possibly be used in performing a function call. The code is
1345 moved to the start of the function so the incoming values are
1346 saved. */
1348 static rtx
1349 expand_builtin_apply_args (void)
1351 /* Don't do __builtin_apply_args more than once in a function.
1352 Save the result of the first call and reuse it. */
1353 if (apply_args_value != 0)
1354 return apply_args_value;
1356 /* When this function is called, it means that registers must be
1357 saved on entry to this function. So we migrate the
1358 call to the first insn of this function. */
1359 rtx temp;
1360 rtx seq;
1362 start_sequence ();
1363 temp = expand_builtin_apply_args_1 ();
1364 seq = get_insns ();
1365 end_sequence ();
1367 apply_args_value = temp;
1369 /* Put the insns after the NOTE that starts the function.
1370 If this is inside a start_sequence, make the outer-level insn
1371 chain current, so the code is placed at the start of the
1372 function. */
1373 push_topmost_sequence ();
1374 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1375 pop_topmost_sequence ();
1376 return temp;
1380 /* Perform an untyped call and save the state required to perform an
1381 untyped return of whatever value was returned by the given function. */
1383 static rtx
1384 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1386 int size, align, regno;
1387 enum machine_mode mode;
1388 rtx incoming_args, result, reg, dest, src, call_insn;
1389 rtx old_stack_level = 0;
1390 rtx call_fusage = 0;
1391 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1393 arguments = convert_memory_address (Pmode, arguments);
1395 /* Create a block where the return registers can be saved. */
1396 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1398 /* Fetch the arg pointer from the ARGUMENTS block. */
1399 incoming_args = gen_reg_rtx (Pmode);
1400 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1401 #ifndef STACK_GROWS_DOWNWARD
1402 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1403 incoming_args, 0, OPTAB_LIB_WIDEN);
1404 #endif
1406 /* Push a new argument block and copy the arguments. Do not allow
1407 the (potential) memcpy call below to interfere with our stack
1408 manipulations. */
1409 do_pending_stack_adjust ();
1410 NO_DEFER_POP;
1412 /* Save the stack with nonlocal if available. */
1413 #ifdef HAVE_save_stack_nonlocal
1414 if (HAVE_save_stack_nonlocal)
1415 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1416 else
1417 #endif
1418 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1420 /* Allocate a block of memory onto the stack and copy the memory
1421 arguments to the outgoing arguments address. */
1422 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1423 dest = virtual_outgoing_args_rtx;
1424 #ifndef STACK_GROWS_DOWNWARD
1425 if (GET_CODE (argsize) == CONST_INT)
1426 dest = plus_constant (dest, -INTVAL (argsize));
1427 else
1428 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1429 #endif
1430 dest = gen_rtx_MEM (BLKmode, dest);
1431 set_mem_align (dest, PARM_BOUNDARY);
1432 src = gen_rtx_MEM (BLKmode, incoming_args);
1433 set_mem_align (src, PARM_BOUNDARY);
1434 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1436 /* Refer to the argument block. */
1437 apply_args_size ();
1438 arguments = gen_rtx_MEM (BLKmode, arguments);
1439 set_mem_align (arguments, PARM_BOUNDARY);
1441 /* Walk past the arg-pointer and structure value address. */
1442 size = GET_MODE_SIZE (Pmode);
1443 if (struct_value)
1444 size += GET_MODE_SIZE (Pmode);
1446 /* Restore each of the registers previously saved. Make USE insns
1447 for each of these registers for use in making the call. */
1448 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1449 if ((mode = apply_args_mode[regno]) != VOIDmode)
1451 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1452 if (size % align != 0)
1453 size = CEIL (size, align) * align;
1454 reg = gen_rtx_REG (mode, regno);
1455 emit_move_insn (reg, adjust_address (arguments, mode, size));
1456 use_reg (&call_fusage, reg);
1457 size += GET_MODE_SIZE (mode);
1460 /* Restore the structure value address unless this is passed as an
1461 "invisible" first argument. */
1462 size = GET_MODE_SIZE (Pmode);
1463 if (struct_value)
1465 rtx value = gen_reg_rtx (Pmode);
1466 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1467 emit_move_insn (struct_value, value);
1468 if (REG_P (struct_value))
1469 use_reg (&call_fusage, struct_value);
1470 size += GET_MODE_SIZE (Pmode);
1473 /* All arguments and registers used for the call are set up by now! */
1474 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1476 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1477 and we don't want to load it into a register as an optimization,
1478 because prepare_call_address already did it if it should be done. */
1479 if (GET_CODE (function) != SYMBOL_REF)
1480 function = memory_address (FUNCTION_MODE, function);
1482 /* Generate the actual call instruction and save the return value. */
1483 #ifdef HAVE_untyped_call
1484 if (HAVE_untyped_call)
1485 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1486 result, result_vector (1, result)));
1487 else
1488 #endif
1489 #ifdef HAVE_call_value
1490 if (HAVE_call_value)
1492 rtx valreg = 0;
1494 /* Locate the unique return register. It is not possible to
1495 express a call that sets more than one return register using
1496 call_value; use untyped_call for that. In fact, untyped_call
1497 only needs to save the return registers in the given block. */
1498 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1499 if ((mode = apply_result_mode[regno]) != VOIDmode)
1501 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1503 valreg = gen_rtx_REG (mode, regno);
1506 emit_call_insn (GEN_CALL_VALUE (valreg,
1507 gen_rtx_MEM (FUNCTION_MODE, function),
1508 const0_rtx, NULL_RTX, const0_rtx));
1510 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1512 else
1513 #endif
1514 gcc_unreachable ();
1516 /* Find the CALL insn we just emitted, and attach the register usage
1517 information. */
1518 call_insn = last_call_insn ();
1519 add_function_usage_to (call_insn, call_fusage);
1521 /* Restore the stack. */
1522 #ifdef HAVE_save_stack_nonlocal
1523 if (HAVE_save_stack_nonlocal)
1524 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1525 else
1526 #endif
1527 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1529 OK_DEFER_POP;
1531 /* Return the address of the result block. */
1532 result = copy_addr_to_reg (XEXP (result, 0));
1533 return convert_memory_address (ptr_mode, result);
1536 /* Perform an untyped return. */
1538 static void
1539 expand_builtin_return (rtx result)
1541 int size, align, regno;
1542 enum machine_mode mode;
1543 rtx reg;
1544 rtx call_fusage = 0;
1546 result = convert_memory_address (Pmode, result);
1548 apply_result_size ();
1549 result = gen_rtx_MEM (BLKmode, result);
1551 #ifdef HAVE_untyped_return
1552 if (HAVE_untyped_return)
1554 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1555 emit_barrier ();
1556 return;
1558 #endif
1560 /* Restore the return value and note that each value is used. */
1561 size = 0;
1562 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1563 if ((mode = apply_result_mode[regno]) != VOIDmode)
1565 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1566 if (size % align != 0)
1567 size = CEIL (size, align) * align;
1568 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1569 emit_move_insn (reg, adjust_address (result, mode, size));
1571 push_to_sequence (call_fusage);
1572 emit_insn (gen_rtx_USE (VOIDmode, reg));
1573 call_fusage = get_insns ();
1574 end_sequence ();
1575 size += GET_MODE_SIZE (mode);
1578 /* Put the USE insns before the return. */
1579 emit_insn (call_fusage);
1581 /* Return whatever values was restored by jumping directly to the end
1582 of the function. */
1583 expand_naked_return ();
1586 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1588 static enum type_class
1589 type_to_class (tree type)
1591 switch (TREE_CODE (type))
1593 case VOID_TYPE: return void_type_class;
1594 case INTEGER_TYPE: return integer_type_class;
1595 case ENUMERAL_TYPE: return enumeral_type_class;
1596 case BOOLEAN_TYPE: return boolean_type_class;
1597 case POINTER_TYPE: return pointer_type_class;
1598 case REFERENCE_TYPE: return reference_type_class;
1599 case OFFSET_TYPE: return offset_type_class;
1600 case REAL_TYPE: return real_type_class;
1601 case COMPLEX_TYPE: return complex_type_class;
1602 case FUNCTION_TYPE: return function_type_class;
1603 case METHOD_TYPE: return method_type_class;
1604 case RECORD_TYPE: return record_type_class;
1605 case UNION_TYPE:
1606 case QUAL_UNION_TYPE: return union_type_class;
1607 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1608 ? string_type_class : array_type_class);
1609 case LANG_TYPE: return lang_type_class;
1610 default: return no_type_class;
1614 /* Expand a call to __builtin_classify_type with arguments found in
1615 ARGLIST. */
1617 static rtx
1618 expand_builtin_classify_type (tree arglist)
1620 if (arglist != 0)
1621 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1622 return GEN_INT (no_type_class);
1625 /* This helper macro, meant to be used in mathfn_built_in below,
1626 determines which among a set of three builtin math functions is
1627 appropriate for a given type mode. The `F' and `L' cases are
1628 automatically generated from the `double' case. */
1629 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1630 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1631 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1632 fcodel = BUILT_IN_MATHFN##L ; break;
1634 /* Return mathematic function equivalent to FN but operating directly
1635 on TYPE, if available. If we can't do the conversion, return zero. */
1636 tree
1637 mathfn_built_in (tree type, enum built_in_function fn)
1639 enum built_in_function fcode, fcodef, fcodel;
1641 switch (fn)
1643 CASE_MATHFN (BUILT_IN_ACOS)
1644 CASE_MATHFN (BUILT_IN_ACOSH)
1645 CASE_MATHFN (BUILT_IN_ASIN)
1646 CASE_MATHFN (BUILT_IN_ASINH)
1647 CASE_MATHFN (BUILT_IN_ATAN)
1648 CASE_MATHFN (BUILT_IN_ATAN2)
1649 CASE_MATHFN (BUILT_IN_ATANH)
1650 CASE_MATHFN (BUILT_IN_CBRT)
1651 CASE_MATHFN (BUILT_IN_CEIL)
1652 CASE_MATHFN (BUILT_IN_CEXPI)
1653 CASE_MATHFN (BUILT_IN_COPYSIGN)
1654 CASE_MATHFN (BUILT_IN_COS)
1655 CASE_MATHFN (BUILT_IN_COSH)
1656 CASE_MATHFN (BUILT_IN_DREM)
1657 CASE_MATHFN (BUILT_IN_ERF)
1658 CASE_MATHFN (BUILT_IN_ERFC)
1659 CASE_MATHFN (BUILT_IN_EXP)
1660 CASE_MATHFN (BUILT_IN_EXP10)
1661 CASE_MATHFN (BUILT_IN_EXP2)
1662 CASE_MATHFN (BUILT_IN_EXPM1)
1663 CASE_MATHFN (BUILT_IN_FABS)
1664 CASE_MATHFN (BUILT_IN_FDIM)
1665 CASE_MATHFN (BUILT_IN_FLOOR)
1666 CASE_MATHFN (BUILT_IN_FMA)
1667 CASE_MATHFN (BUILT_IN_FMAX)
1668 CASE_MATHFN (BUILT_IN_FMIN)
1669 CASE_MATHFN (BUILT_IN_FMOD)
1670 CASE_MATHFN (BUILT_IN_FREXP)
1671 CASE_MATHFN (BUILT_IN_GAMMA)
1672 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1673 CASE_MATHFN (BUILT_IN_HYPOT)
1674 CASE_MATHFN (BUILT_IN_ILOGB)
1675 CASE_MATHFN (BUILT_IN_INF)
1676 CASE_MATHFN (BUILT_IN_J0)
1677 CASE_MATHFN (BUILT_IN_J1)
1678 CASE_MATHFN (BUILT_IN_JN)
1679 CASE_MATHFN (BUILT_IN_LCEIL)
1680 CASE_MATHFN (BUILT_IN_LDEXP)
1681 CASE_MATHFN (BUILT_IN_LFLOOR)
1682 CASE_MATHFN (BUILT_IN_LGAMMA)
1683 CASE_MATHFN (BUILT_IN_LLCEIL)
1684 CASE_MATHFN (BUILT_IN_LLFLOOR)
1685 CASE_MATHFN (BUILT_IN_LLRINT)
1686 CASE_MATHFN (BUILT_IN_LLROUND)
1687 CASE_MATHFN (BUILT_IN_LOG)
1688 CASE_MATHFN (BUILT_IN_LOG10)
1689 CASE_MATHFN (BUILT_IN_LOG1P)
1690 CASE_MATHFN (BUILT_IN_LOG2)
1691 CASE_MATHFN (BUILT_IN_LOGB)
1692 CASE_MATHFN (BUILT_IN_LRINT)
1693 CASE_MATHFN (BUILT_IN_LROUND)
1694 CASE_MATHFN (BUILT_IN_MODF)
1695 CASE_MATHFN (BUILT_IN_NAN)
1696 CASE_MATHFN (BUILT_IN_NANS)
1697 CASE_MATHFN (BUILT_IN_NEARBYINT)
1698 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1699 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1700 CASE_MATHFN (BUILT_IN_POW)
1701 CASE_MATHFN (BUILT_IN_POWI)
1702 CASE_MATHFN (BUILT_IN_POW10)
1703 CASE_MATHFN (BUILT_IN_REMAINDER)
1704 CASE_MATHFN (BUILT_IN_REMQUO)
1705 CASE_MATHFN (BUILT_IN_RINT)
1706 CASE_MATHFN (BUILT_IN_ROUND)
1707 CASE_MATHFN (BUILT_IN_SCALB)
1708 CASE_MATHFN (BUILT_IN_SCALBLN)
1709 CASE_MATHFN (BUILT_IN_SCALBN)
1710 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1711 CASE_MATHFN (BUILT_IN_SIN)
1712 CASE_MATHFN (BUILT_IN_SINCOS)
1713 CASE_MATHFN (BUILT_IN_SINH)
1714 CASE_MATHFN (BUILT_IN_SQRT)
1715 CASE_MATHFN (BUILT_IN_TAN)
1716 CASE_MATHFN (BUILT_IN_TANH)
1717 CASE_MATHFN (BUILT_IN_TGAMMA)
1718 CASE_MATHFN (BUILT_IN_TRUNC)
1719 CASE_MATHFN (BUILT_IN_Y0)
1720 CASE_MATHFN (BUILT_IN_Y1)
1721 CASE_MATHFN (BUILT_IN_YN)
1723 default:
1724 return 0;
1727 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1728 return implicit_built_in_decls[fcode];
1729 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1730 return implicit_built_in_decls[fcodef];
1731 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1732 return implicit_built_in_decls[fcodel];
1733 else
1734 return 0;
1737 /* If errno must be maintained, expand the RTL to check if the result,
1738 TARGET, of a built-in function call, EXP, is NaN, and if so set
1739 errno to EDOM. */
1741 static void
1742 expand_errno_check (tree exp, rtx target)
1744 rtx lab = gen_label_rtx ();
1746 /* Test the result; if it is NaN, set errno=EDOM because
1747 the argument was not in the domain. */
1748 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1749 0, lab);
1751 #ifdef TARGET_EDOM
1752 /* If this built-in doesn't throw an exception, set errno directly. */
1753 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1755 #ifdef GEN_ERRNO_RTX
1756 rtx errno_rtx = GEN_ERRNO_RTX;
1757 #else
1758 rtx errno_rtx
1759 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1760 #endif
1761 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1762 emit_label (lab);
1763 return;
1765 #endif
1767 /* We can't set errno=EDOM directly; let the library call do it.
1768 Pop the arguments right away in case the call gets deleted. */
1769 NO_DEFER_POP;
1770 expand_call (exp, target, 0);
1771 OK_DEFER_POP;
1772 emit_label (lab);
1776 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1777 Return 0 if a normal call should be emitted rather than expanding the
1778 function in-line. EXP is the expression that is a call to the builtin
1779 function; if convenient, the result should be placed in TARGET.
1780 SUBTARGET may be used as the target for computing one of EXP's operands. */
1782 static rtx
1783 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1785 optab builtin_optab;
1786 rtx op0, insns, before_call;
1787 tree fndecl = get_callee_fndecl (exp);
1788 tree arglist = TREE_OPERAND (exp, 1);
1789 enum machine_mode mode;
1790 bool errno_set = false;
1791 tree arg, narg;
1793 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1794 return 0;
1796 arg = TREE_VALUE (arglist);
1798 switch (DECL_FUNCTION_CODE (fndecl))
1800 CASE_FLT_FN (BUILT_IN_SQRT):
1801 errno_set = ! tree_expr_nonnegative_p (arg);
1802 builtin_optab = sqrt_optab;
1803 break;
1804 CASE_FLT_FN (BUILT_IN_EXP):
1805 errno_set = true; builtin_optab = exp_optab; break;
1806 CASE_FLT_FN (BUILT_IN_EXP10):
1807 CASE_FLT_FN (BUILT_IN_POW10):
1808 errno_set = true; builtin_optab = exp10_optab; break;
1809 CASE_FLT_FN (BUILT_IN_EXP2):
1810 errno_set = true; builtin_optab = exp2_optab; break;
1811 CASE_FLT_FN (BUILT_IN_EXPM1):
1812 errno_set = true; builtin_optab = expm1_optab; break;
1813 CASE_FLT_FN (BUILT_IN_LOGB):
1814 errno_set = true; builtin_optab = logb_optab; break;
1815 CASE_FLT_FN (BUILT_IN_ILOGB):
1816 errno_set = true; builtin_optab = ilogb_optab; break;
1817 CASE_FLT_FN (BUILT_IN_LOG):
1818 errno_set = true; builtin_optab = log_optab; break;
1819 CASE_FLT_FN (BUILT_IN_LOG10):
1820 errno_set = true; builtin_optab = log10_optab; break;
1821 CASE_FLT_FN (BUILT_IN_LOG2):
1822 errno_set = true; builtin_optab = log2_optab; break;
1823 CASE_FLT_FN (BUILT_IN_LOG1P):
1824 errno_set = true; builtin_optab = log1p_optab; break;
1825 CASE_FLT_FN (BUILT_IN_ASIN):
1826 builtin_optab = asin_optab; break;
1827 CASE_FLT_FN (BUILT_IN_ACOS):
1828 builtin_optab = acos_optab; break;
1829 CASE_FLT_FN (BUILT_IN_TAN):
1830 builtin_optab = tan_optab; break;
1831 CASE_FLT_FN (BUILT_IN_ATAN):
1832 builtin_optab = atan_optab; break;
1833 CASE_FLT_FN (BUILT_IN_FLOOR):
1834 builtin_optab = floor_optab; break;
1835 CASE_FLT_FN (BUILT_IN_CEIL):
1836 builtin_optab = ceil_optab; break;
1837 CASE_FLT_FN (BUILT_IN_TRUNC):
1838 builtin_optab = btrunc_optab; break;
1839 CASE_FLT_FN (BUILT_IN_ROUND):
1840 builtin_optab = round_optab; break;
1841 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1842 builtin_optab = nearbyint_optab;
1843 if (flag_trapping_math)
1844 break;
1845 /* Else fallthrough and expand as rint. */
1846 CASE_FLT_FN (BUILT_IN_RINT):
1847 builtin_optab = rint_optab; break;
1848 default:
1849 gcc_unreachable ();
1852 /* Make a suitable register to place result in. */
1853 mode = TYPE_MODE (TREE_TYPE (exp));
1855 if (! flag_errno_math || ! HONOR_NANS (mode))
1856 errno_set = false;
1858 /* Before working hard, check whether the instruction is available. */
1859 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1861 target = gen_reg_rtx (mode);
1863 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1864 need to expand the argument again. This way, we will not perform
1865 side-effects more the once. */
1866 narg = builtin_save_expr (arg);
1867 if (narg != arg)
1869 arg = narg;
1870 arglist = build_tree_list (NULL_TREE, arg);
1871 exp = build_function_call_expr (fndecl, arglist);
1874 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1876 start_sequence ();
1878 /* Compute into TARGET.
1879 Set TARGET to wherever the result comes back. */
1880 target = expand_unop (mode, builtin_optab, op0, target, 0);
1882 if (target != 0)
1884 if (errno_set)
1885 expand_errno_check (exp, target);
1887 /* Output the entire sequence. */
1888 insns = get_insns ();
1889 end_sequence ();
1890 emit_insn (insns);
1891 return target;
1894 /* If we were unable to expand via the builtin, stop the sequence
1895 (without outputting the insns) and call to the library function
1896 with the stabilized argument list. */
1897 end_sequence ();
1900 before_call = get_last_insn ();
1902 target = expand_call (exp, target, target == const0_rtx);
1904 /* If this is a sqrt operation and we don't care about errno, try to
1905 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1906 This allows the semantics of the libcall to be visible to the RTL
1907 optimizers. */
1908 if (builtin_optab == sqrt_optab && !errno_set)
1910 /* Search backwards through the insns emitted by expand_call looking
1911 for the instruction with the REG_RETVAL note. */
1912 rtx last = get_last_insn ();
1913 while (last != before_call)
1915 if (find_reg_note (last, REG_RETVAL, NULL))
1917 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1918 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1919 two elements, i.e. symbol_ref(sqrt) and the operand. */
1920 if (note
1921 && GET_CODE (note) == EXPR_LIST
1922 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1923 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1924 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1926 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1927 /* Check operand is a register with expected mode. */
1928 if (operand
1929 && REG_P (operand)
1930 && GET_MODE (operand) == mode)
1932 /* Replace the REG_EQUAL note with a SQRT rtx. */
1933 rtx equiv = gen_rtx_SQRT (mode, operand);
1934 set_unique_reg_note (last, REG_EQUAL, equiv);
1937 break;
1939 last = PREV_INSN (last);
1943 return target;
1946 /* Expand a call to the builtin binary math functions (pow and atan2).
1947 Return 0 if a normal call should be emitted rather than expanding the
1948 function in-line. EXP is the expression that is a call to the builtin
1949 function; if convenient, the result should be placed in TARGET.
1950 SUBTARGET may be used as the target for computing one of EXP's
1951 operands. */
1953 static rtx
1954 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1956 optab builtin_optab;
1957 rtx op0, op1, insns;
1958 int op1_type = REAL_TYPE;
1959 tree fndecl = get_callee_fndecl (exp);
1960 tree arglist = TREE_OPERAND (exp, 1);
1961 tree arg0, arg1, temp, narg;
1962 enum machine_mode mode;
1963 bool errno_set = true;
1964 bool stable = true;
1966 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1967 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1968 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1969 op1_type = INTEGER_TYPE;
1971 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1972 return 0;
1974 arg0 = TREE_VALUE (arglist);
1975 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1977 switch (DECL_FUNCTION_CODE (fndecl))
1979 CASE_FLT_FN (BUILT_IN_POW):
1980 builtin_optab = pow_optab; break;
1981 CASE_FLT_FN (BUILT_IN_ATAN2):
1982 builtin_optab = atan2_optab; break;
1983 CASE_FLT_FN (BUILT_IN_LDEXP):
1984 builtin_optab = ldexp_optab; break;
1985 CASE_FLT_FN (BUILT_IN_FMOD):
1986 builtin_optab = fmod_optab; break;
1987 CASE_FLT_FN (BUILT_IN_REMAINDER):
1988 CASE_FLT_FN (BUILT_IN_DREM):
1989 builtin_optab = remainder_optab; break;
1990 default:
1991 gcc_unreachable ();
1994 /* Make a suitable register to place result in. */
1995 mode = TYPE_MODE (TREE_TYPE (exp));
1997 /* Before working hard, check whether the instruction is available. */
1998 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1999 return 0;
2001 target = gen_reg_rtx (mode);
2003 if (! flag_errno_math || ! HONOR_NANS (mode))
2004 errno_set = false;
2006 /* Always stabilize the argument list. */
2007 narg = builtin_save_expr (arg1);
2008 if (narg != arg1)
2010 arg1 = narg;
2011 temp = build_tree_list (NULL_TREE, narg);
2012 stable = false;
2014 else
2015 temp = TREE_CHAIN (arglist);
2017 narg = builtin_save_expr (arg0);
2018 if (narg != arg0)
2020 arg0 = narg;
2021 arglist = tree_cons (NULL_TREE, narg, temp);
2022 stable = false;
2024 else if (! stable)
2025 arglist = tree_cons (NULL_TREE, arg0, temp);
2027 if (! stable)
2028 exp = build_function_call_expr (fndecl, arglist);
2030 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2031 op1 = expand_normal (arg1);
2033 start_sequence ();
2035 /* Compute into TARGET.
2036 Set TARGET to wherever the result comes back. */
2037 target = expand_binop (mode, builtin_optab, op0, op1,
2038 target, 0, OPTAB_DIRECT);
2040 /* If we were unable to expand via the builtin, stop the sequence
2041 (without outputting the insns) and call to the library function
2042 with the stabilized argument list. */
2043 if (target == 0)
2045 end_sequence ();
2046 return expand_call (exp, target, target == const0_rtx);
2049 if (errno_set)
2050 expand_errno_check (exp, target);
2052 /* Output the entire sequence. */
2053 insns = get_insns ();
2054 end_sequence ();
2055 emit_insn (insns);
2057 return target;
2060 /* Expand a call to the builtin sin and cos math functions.
2061 Return 0 if a normal call should be emitted rather than expanding the
2062 function in-line. EXP is the expression that is a call to the builtin
2063 function; if convenient, the result should be placed in TARGET.
2064 SUBTARGET may be used as the target for computing one of EXP's
2065 operands. */
2067 static rtx
2068 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2070 optab builtin_optab;
2071 rtx op0, insns;
2072 tree fndecl = get_callee_fndecl (exp);
2073 tree arglist = TREE_OPERAND (exp, 1);
2074 enum machine_mode mode;
2075 tree arg, narg;
2077 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2078 return 0;
2080 arg = TREE_VALUE (arglist);
2082 switch (DECL_FUNCTION_CODE (fndecl))
2084 CASE_FLT_FN (BUILT_IN_SIN):
2085 CASE_FLT_FN (BUILT_IN_COS):
2086 builtin_optab = sincos_optab; break;
2087 default:
2088 gcc_unreachable ();
2091 /* Make a suitable register to place result in. */
2092 mode = TYPE_MODE (TREE_TYPE (exp));
2094 /* Check if sincos insn is available, otherwise fallback
2095 to sin or cos insn. */
2096 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2097 switch (DECL_FUNCTION_CODE (fndecl))
2099 CASE_FLT_FN (BUILT_IN_SIN):
2100 builtin_optab = sin_optab; break;
2101 CASE_FLT_FN (BUILT_IN_COS):
2102 builtin_optab = cos_optab; break;
2103 default:
2104 gcc_unreachable ();
2107 /* Before working hard, check whether the instruction is available. */
2108 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2110 target = gen_reg_rtx (mode);
2112 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2113 need to expand the argument again. This way, we will not perform
2114 side-effects more the once. */
2115 narg = save_expr (arg);
2116 if (narg != arg)
2118 arg = narg;
2119 arglist = build_tree_list (NULL_TREE, arg);
2120 exp = build_function_call_expr (fndecl, arglist);
2123 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2125 start_sequence ();
2127 /* Compute into TARGET.
2128 Set TARGET to wherever the result comes back. */
2129 if (builtin_optab == sincos_optab)
2131 int result;
2133 switch (DECL_FUNCTION_CODE (fndecl))
2135 CASE_FLT_FN (BUILT_IN_SIN):
2136 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2137 break;
2138 CASE_FLT_FN (BUILT_IN_COS):
2139 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2140 break;
2141 default:
2142 gcc_unreachable ();
2144 gcc_assert (result);
2146 else
2148 target = expand_unop (mode, builtin_optab, op0, target, 0);
2151 if (target != 0)
2153 /* Output the entire sequence. */
2154 insns = get_insns ();
2155 end_sequence ();
2156 emit_insn (insns);
2157 return target;
2160 /* If we were unable to expand via the builtin, stop the sequence
2161 (without outputting the insns) and call to the library function
2162 with the stabilized argument list. */
2163 end_sequence ();
2166 target = expand_call (exp, target, target == const0_rtx);
2168 return target;
2171 /* Expand a call to the builtin sincos math function.
2172 Return 0 if a normal call should be emitted rather than expanding the
2173 function in-line. EXP is the expression that is a call to the builtin
2174 function. */
2176 static rtx
2177 expand_builtin_sincos (tree exp)
2179 rtx op0, op1, op2, target1, target2;
2180 tree arglist = TREE_OPERAND (exp, 1);
2181 enum machine_mode mode;
2182 tree arg, sinp, cosp;
2183 int result;
2185 if (!validate_arglist (arglist, REAL_TYPE,
2186 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2187 return 0;
2189 arg = TREE_VALUE (arglist);
2190 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2191 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2193 /* Make a suitable register to place result in. */
2194 mode = TYPE_MODE (TREE_TYPE (arg));
2196 /* Check if sincos insn is available, otherwise emit the call. */
2197 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2198 return NULL_RTX;
2200 target1 = gen_reg_rtx (mode);
2201 target2 = gen_reg_rtx (mode);
2203 op0 = expand_normal (arg);
2204 op1 = expand_normal (build_fold_indirect_ref (sinp));
2205 op2 = expand_normal (build_fold_indirect_ref (cosp));
2207 /* Compute into target1 and target2.
2208 Set TARGET to wherever the result comes back. */
2209 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2210 gcc_assert (result);
2212 /* Move target1 and target2 to the memory locations indicated
2213 by op1 and op2. */
2214 emit_move_insn (op1, target1);
2215 emit_move_insn (op2, target2);
2217 return const0_rtx;
2220 /* Expand a call to the internal cexpi builtin to the sincos math function.
2221 EXP is the expression that is a call to the builtin function; if convenient,
2222 the result should be placed in TARGET. SUBTARGET may be used as the target
2223 for computing one of EXP's operands. */
2225 static rtx
2226 expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2228 tree fndecl = get_callee_fndecl (exp);
2229 tree arglist = TREE_OPERAND (exp, 1);
2230 enum machine_mode mode;
2231 tree arg, type;
2232 rtx op0, op1, op2;
2234 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2235 return 0;
2237 arg = TREE_VALUE (arglist);
2238 type = TREE_TYPE (arg);
2239 mode = TYPE_MODE (TREE_TYPE (arg));
2241 /* Try expanding via a sincos optab, fall back to emitting a libcall
2242 to sincos. We are sure we have sincos either way because cexpi
2243 is only generated from sincos. */
2244 if (sincos_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2246 op1 = gen_reg_rtx (mode);
2247 op2 = gen_reg_rtx (mode);
2249 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2251 /* Compute into op1 and op2. */
2252 expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2254 else
2256 tree call, narglist, fn = NULL_TREE;
2257 tree top1, top2;
2258 rtx op1a, op2a;
2260 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2261 fn = built_in_decls[BUILT_IN_SINCOSF];
2262 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2263 fn = built_in_decls[BUILT_IN_SINCOS];
2264 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2265 fn = built_in_decls[BUILT_IN_SINCOSL];
2266 gcc_assert (fn);
2268 op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2269 op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2270 op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2271 op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2272 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2273 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2275 narglist = build_tree_list (NULL_TREE, top2);
2276 narglist = tree_cons (NULL_TREE, top1, narglist);
2277 narglist = tree_cons (NULL_TREE, arg, narglist);
2279 /* Make sure not to fold the sincos call again. */
2280 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2281 expand_normal (build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
2282 call, narglist, NULL_TREE));
2285 /* Now build the proper return type. */
2286 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2287 make_tree (TREE_TYPE (arg), op2),
2288 make_tree (TREE_TYPE (arg), op1)),
2289 target, VOIDmode, 0);
2292 /* Expand a call to one of the builtin rounding functions gcc defines
2293 as an extension (lfloor and lceil). As these are gcc extensions we
2294 do not need to worry about setting errno to EDOM.
2295 If expanding via optab fails, lower expression to (int)(floor(x)).
2296 EXP is the expression that is a call to the builtin function;
2297 if convenient, the result should be placed in TARGET. SUBTARGET may
2298 be used as the target for computing one of EXP's operands. */
2300 static rtx
2301 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2303 convert_optab builtin_optab;
2304 rtx op0, insns, tmp;
2305 tree fndecl = get_callee_fndecl (exp);
2306 tree arglist = TREE_OPERAND (exp, 1);
2307 enum built_in_function fallback_fn;
2308 tree fallback_fndecl;
2309 enum machine_mode mode;
2310 tree arg, narg;
2312 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2313 gcc_unreachable ();
2315 arg = TREE_VALUE (arglist);
2317 switch (DECL_FUNCTION_CODE (fndecl))
2319 CASE_FLT_FN (BUILT_IN_LCEIL):
2320 CASE_FLT_FN (BUILT_IN_LLCEIL):
2321 builtin_optab = lceil_optab;
2322 fallback_fn = BUILT_IN_CEIL;
2323 break;
2325 CASE_FLT_FN (BUILT_IN_LFLOOR):
2326 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2327 builtin_optab = lfloor_optab;
2328 fallback_fn = BUILT_IN_FLOOR;
2329 break;
2331 default:
2332 gcc_unreachable ();
2335 /* Make a suitable register to place result in. */
2336 mode = TYPE_MODE (TREE_TYPE (exp));
2338 target = gen_reg_rtx (mode);
2340 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2341 need to expand the argument again. This way, we will not perform
2342 side-effects more the once. */
2343 narg = builtin_save_expr (arg);
2344 if (narg != arg)
2346 arg = narg;
2347 arglist = build_tree_list (NULL_TREE, arg);
2348 exp = build_function_call_expr (fndecl, arglist);
2351 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2353 start_sequence ();
2355 /* Compute into TARGET. */
2356 if (expand_sfix_optab (target, op0, builtin_optab))
2358 /* Output the entire sequence. */
2359 insns = get_insns ();
2360 end_sequence ();
2361 emit_insn (insns);
2362 return target;
2365 /* If we were unable to expand via the builtin, stop the sequence
2366 (without outputting the insns). */
2367 end_sequence ();
2369 /* Fall back to floating point rounding optab. */
2370 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2371 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2372 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2373 gcc_assert (fallback_fndecl != NULL_TREE);
2374 exp = build_function_call_expr (fallback_fndecl, arglist);
2376 tmp = expand_normal (exp);
2378 /* Truncate the result of floating point optab to integer
2379 via expand_fix (). */
2380 target = gen_reg_rtx (mode);
2381 expand_fix (target, tmp, 0);
2383 return target;
2386 /* Expand a call to one of the builtin math functions doing integer
2387 conversion (lrint).
2388 Return 0 if a normal call should be emitted rather than expanding the
2389 function in-line. EXP is the expression that is a call to the builtin
2390 function; if convenient, the result should be placed in TARGET.
2391 SUBTARGET may be used as the target for computing one of EXP's operands. */
2393 static rtx
2394 expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
2396 convert_optab builtin_optab;
2397 rtx op0, insns;
2398 tree fndecl = get_callee_fndecl (exp);
2399 tree arglist = TREE_OPERAND (exp, 1);
2400 enum machine_mode mode;
2401 tree arg, narg;
2403 /* There's no easy way to detect the case we need to set EDOM. */
2404 if (flag_errno_math)
2405 return NULL_RTX;
2407 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2408 return NULL_RTX;
2410 arg = TREE_VALUE (arglist);
2412 switch (DECL_FUNCTION_CODE (fndecl))
2414 CASE_FLT_FN (BUILT_IN_LRINT):
2415 CASE_FLT_FN (BUILT_IN_LLRINT):
2416 builtin_optab = lrint_optab; break;
2417 CASE_FLT_FN (BUILT_IN_LROUND):
2418 CASE_FLT_FN (BUILT_IN_LLROUND):
2419 builtin_optab = lround_optab; break;
2420 default:
2421 gcc_unreachable ();
2424 /* Make a suitable register to place result in. */
2425 mode = TYPE_MODE (TREE_TYPE (exp));
2427 target = gen_reg_rtx (mode);
2429 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2430 need to expand the argument again. This way, we will not perform
2431 side-effects more the once. */
2432 narg = builtin_save_expr (arg);
2433 if (narg != arg)
2435 arg = narg;
2436 arglist = build_tree_list (NULL_TREE, arg);
2437 exp = build_function_call_expr (fndecl, arglist);
2440 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2442 start_sequence ();
2444 if (expand_sfix_optab (target, op0, builtin_optab))
2446 /* Output the entire sequence. */
2447 insns = get_insns ();
2448 end_sequence ();
2449 emit_insn (insns);
2450 return target;
2453 /* If we were unable to expand via the builtin, stop the sequence
2454 (without outputting the insns) and call to the library function
2455 with the stabilized argument list. */
2456 end_sequence ();
2458 target = expand_call (exp, target, target == const0_rtx);
2460 return target;
2463 /* To evaluate powi(x,n), the floating point value x raised to the
2464 constant integer exponent n, we use a hybrid algorithm that
2465 combines the "window method" with look-up tables. For an
2466 introduction to exponentiation algorithms and "addition chains",
2467 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2468 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2469 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2470 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2472 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2473 multiplications to inline before calling the system library's pow
2474 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2475 so this default never requires calling pow, powf or powl. */
2477 #ifndef POWI_MAX_MULTS
2478 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2479 #endif
2481 /* The size of the "optimal power tree" lookup table. All
2482 exponents less than this value are simply looked up in the
2483 powi_table below. This threshold is also used to size the
2484 cache of pseudo registers that hold intermediate results. */
2485 #define POWI_TABLE_SIZE 256
2487 /* The size, in bits of the window, used in the "window method"
2488 exponentiation algorithm. This is equivalent to a radix of
2489 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2490 #define POWI_WINDOW_SIZE 3
2492 /* The following table is an efficient representation of an
2493 "optimal power tree". For each value, i, the corresponding
2494 value, j, in the table states than an optimal evaluation
2495 sequence for calculating pow(x,i) can be found by evaluating
2496 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2497 100 integers is given in Knuth's "Seminumerical algorithms". */
2499 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2501 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2502 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2503 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2504 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2505 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2506 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2507 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2508 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2509 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2510 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2511 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2512 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2513 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2514 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2515 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2516 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2517 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2518 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2519 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2520 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2521 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2522 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2523 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2524 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2525 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2526 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2527 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2528 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2529 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2530 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2531 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2532 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2536 /* Return the number of multiplications required to calculate
2537 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2538 subroutine of powi_cost. CACHE is an array indicating
2539 which exponents have already been calculated. */
2541 static int
2542 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2544 /* If we've already calculated this exponent, then this evaluation
2545 doesn't require any additional multiplications. */
2546 if (cache[n])
2547 return 0;
2549 cache[n] = true;
2550 return powi_lookup_cost (n - powi_table[n], cache)
2551 + powi_lookup_cost (powi_table[n], cache) + 1;
2554 /* Return the number of multiplications required to calculate
2555 powi(x,n) for an arbitrary x, given the exponent N. This
2556 function needs to be kept in sync with expand_powi below. */
2558 static int
2559 powi_cost (HOST_WIDE_INT n)
2561 bool cache[POWI_TABLE_SIZE];
2562 unsigned HOST_WIDE_INT digit;
2563 unsigned HOST_WIDE_INT val;
2564 int result;
2566 if (n == 0)
2567 return 0;
2569 /* Ignore the reciprocal when calculating the cost. */
2570 val = (n < 0) ? -n : n;
2572 /* Initialize the exponent cache. */
2573 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2574 cache[1] = true;
2576 result = 0;
2578 while (val >= POWI_TABLE_SIZE)
2580 if (val & 1)
2582 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2583 result += powi_lookup_cost (digit, cache)
2584 + POWI_WINDOW_SIZE + 1;
2585 val >>= POWI_WINDOW_SIZE;
2587 else
2589 val >>= 1;
2590 result++;
2594 return result + powi_lookup_cost (val, cache);
2597 /* Recursive subroutine of expand_powi. This function takes the array,
2598 CACHE, of already calculated exponents and an exponent N and returns
2599 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2601 static rtx
2602 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2604 unsigned HOST_WIDE_INT digit;
2605 rtx target, result;
2606 rtx op0, op1;
2608 if (n < POWI_TABLE_SIZE)
2610 if (cache[n])
2611 return cache[n];
2613 target = gen_reg_rtx (mode);
2614 cache[n] = target;
2616 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2617 op1 = expand_powi_1 (mode, powi_table[n], cache);
2619 else if (n & 1)
2621 target = gen_reg_rtx (mode);
2622 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2623 op0 = expand_powi_1 (mode, n - digit, cache);
2624 op1 = expand_powi_1 (mode, digit, cache);
2626 else
2628 target = gen_reg_rtx (mode);
2629 op0 = expand_powi_1 (mode, n >> 1, cache);
2630 op1 = op0;
2633 result = expand_mult (mode, op0, op1, target, 0);
2634 if (result != target)
2635 emit_move_insn (target, result);
2636 return target;
2639 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2640 floating point operand in mode MODE, and N is the exponent. This
2641 function needs to be kept in sync with powi_cost above. */
2643 static rtx
2644 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2646 unsigned HOST_WIDE_INT val;
2647 rtx cache[POWI_TABLE_SIZE];
2648 rtx result;
2650 if (n == 0)
2651 return CONST1_RTX (mode);
2653 val = (n < 0) ? -n : n;
2655 memset (cache, 0, sizeof (cache));
2656 cache[1] = x;
2658 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2660 /* If the original exponent was negative, reciprocate the result. */
2661 if (n < 0)
2662 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2663 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2665 return result;
2668 /* Expand a call to the pow built-in mathematical function. Return 0 if
2669 a normal call should be emitted rather than expanding the function
2670 in-line. EXP is the expression that is a call to the builtin
2671 function; if convenient, the result should be placed in TARGET. */
2673 static rtx
2674 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2676 tree arg0, arg1, fn, narg0, narglist;
2677 tree arglist = TREE_OPERAND (exp, 1);
2678 tree type = TREE_TYPE (exp);
2679 REAL_VALUE_TYPE cint, c, c2;
2680 HOST_WIDE_INT n;
2681 rtx op, op2;
2682 enum machine_mode mode = TYPE_MODE (type);
2684 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2685 return 0;
2687 arg0 = TREE_VALUE (arglist);
2688 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2690 if (TREE_CODE (arg1) != REAL_CST
2691 || TREE_CONSTANT_OVERFLOW (arg1))
2692 return expand_builtin_mathfn_2 (exp, target, subtarget);
2694 /* Handle constant exponents. */
2696 /* For integer valued exponents we can expand to an optimal multiplication
2697 sequence using expand_powi. */
2698 c = TREE_REAL_CST (arg1);
2699 n = real_to_integer (&c);
2700 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2701 if (real_identical (&c, &cint)
2702 && ((n >= -1 && n <= 2)
2703 || (flag_unsafe_math_optimizations
2704 && !optimize_size
2705 && powi_cost (n) <= POWI_MAX_MULTS)))
2707 op = expand_expr (arg0, subtarget, VOIDmode, 0);
2708 if (n != 1)
2710 op = force_reg (mode, op);
2711 op = expand_powi (op, mode, n);
2713 return op;
2716 narg0 = builtin_save_expr (arg0);
2717 narglist = build_tree_list (NULL_TREE, narg0);
2719 /* If the exponent is not integer valued, check if it is half of an integer.
2720 In this case we can expand to sqrt (x) * x**(n/2). */
2721 fn = mathfn_built_in (type, BUILT_IN_SQRT);
2722 if (fn != NULL_TREE)
2724 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2725 n = real_to_integer (&c2);
2726 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2727 if (real_identical (&c2, &cint)
2728 && ((flag_unsafe_math_optimizations
2729 && !optimize_size
2730 && powi_cost (n/2) <= POWI_MAX_MULTS)
2731 || n == 1))
2733 tree call_expr = build_function_call_expr (fn, narglist);
2734 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
2735 if (n != 1)
2737 op2 = expand_expr (narg0, subtarget, VOIDmode, 0);
2738 op2 = force_reg (mode, op2);
2739 op2 = expand_powi (op2, mode, abs (n / 2));
2740 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2741 0, OPTAB_LIB_WIDEN);
2742 /* If the original exponent was negative, reciprocate the
2743 result. */
2744 if (n < 0)
2745 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2746 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2748 return op;
2752 /* Try if the exponent is a third of an integer. In this case
2753 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
2754 different from pow (x, 1./3.) due to rounding and behavior
2755 with negative x we need to constrain this transformation to
2756 unsafe math and positive x or finite math. */
2757 fn = mathfn_built_in (type, BUILT_IN_CBRT);
2758 if (fn != NULL_TREE
2759 && flag_unsafe_math_optimizations
2760 && (tree_expr_nonnegative_p (arg0)
2761 || !HONOR_NANS (mode)))
2763 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
2764 real_round (&c2, mode, &c2);
2765 n = real_to_integer (&c2);
2766 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2767 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
2768 real_convert (&c2, mode, &c2);
2769 if (real_identical (&c2, &c)
2770 && ((!optimize_size
2771 && powi_cost (n/3) <= POWI_MAX_MULTS)
2772 || n == 1))
2774 tree call_expr = build_function_call_expr (fn, narglist);
2775 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
2776 if (abs (n) % 3 == 2)
2777 op = expand_simple_binop (mode, MULT, op, op, op,
2778 0, OPTAB_LIB_WIDEN);
2779 if (n != 1)
2781 op2 = expand_expr (narg0, subtarget, VOIDmode, 0);
2782 op2 = force_reg (mode, op2);
2783 op2 = expand_powi (op2, mode, abs (n / 3));
2784 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2785 0, OPTAB_LIB_WIDEN);
2786 /* If the original exponent was negative, reciprocate the
2787 result. */
2788 if (n < 0)
2789 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2790 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2792 return op;
2796 /* Fall back to optab expansion. */
2797 return expand_builtin_mathfn_2 (exp, target, subtarget);
2800 /* Expand a call to the powi built-in mathematical function. Return 0 if
2801 a normal call should be emitted rather than expanding the function
2802 in-line. EXP is the expression that is a call to the builtin
2803 function; if convenient, the result should be placed in TARGET. */
2805 static rtx
2806 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2808 tree arglist = TREE_OPERAND (exp, 1);
2809 tree arg0, arg1;
2810 rtx op0, op1;
2811 enum machine_mode mode;
2812 enum machine_mode mode2;
2814 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2815 return 0;
2817 arg0 = TREE_VALUE (arglist);
2818 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2819 mode = TYPE_MODE (TREE_TYPE (exp));
2821 /* Handle constant power. */
2823 if (TREE_CODE (arg1) == INTEGER_CST
2824 && ! TREE_CONSTANT_OVERFLOW (arg1))
2826 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2828 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2829 Otherwise, check the number of multiplications required. */
2830 if ((TREE_INT_CST_HIGH (arg1) == 0
2831 || TREE_INT_CST_HIGH (arg1) == -1)
2832 && ((n >= -1 && n <= 2)
2833 || (! optimize_size
2834 && powi_cost (n) <= POWI_MAX_MULTS)))
2836 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2837 op0 = force_reg (mode, op0);
2838 return expand_powi (op0, mode, n);
2842 /* Emit a libcall to libgcc. */
2844 /* Mode of the 2nd argument must match that of an int. */
2845 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2847 if (target == NULL_RTX)
2848 target = gen_reg_rtx (mode);
2850 op0 = expand_expr (arg0, subtarget, mode, 0);
2851 if (GET_MODE (op0) != mode)
2852 op0 = convert_to_mode (mode, op0, 0);
2853 op1 = expand_expr (arg1, 0, mode2, 0);
2854 if (GET_MODE (op1) != mode2)
2855 op1 = convert_to_mode (mode2, op1, 0);
2857 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2858 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2859 op0, mode, op1, mode2);
2861 return target;
2864 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2865 if we failed the caller should emit a normal call, otherwise
2866 try to get the result in TARGET, if convenient. */
2868 static rtx
2869 expand_builtin_strlen (tree arglist, rtx target,
2870 enum machine_mode target_mode)
2872 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2873 return 0;
2874 else
2876 rtx pat;
2877 tree len, src = TREE_VALUE (arglist);
2878 rtx result, src_reg, char_rtx, before_strlen;
2879 enum machine_mode insn_mode = target_mode, char_mode;
2880 enum insn_code icode = CODE_FOR_nothing;
2881 int align;
2883 /* If the length can be computed at compile-time, return it. */
2884 len = c_strlen (src, 0);
2885 if (len)
2886 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2888 /* If the length can be computed at compile-time and is constant
2889 integer, but there are side-effects in src, evaluate
2890 src for side-effects, then return len.
2891 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2892 can be optimized into: i++; x = 3; */
2893 len = c_strlen (src, 1);
2894 if (len && TREE_CODE (len) == INTEGER_CST)
2896 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2897 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2900 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2902 /* If SRC is not a pointer type, don't do this operation inline. */
2903 if (align == 0)
2904 return 0;
2906 /* Bail out if we can't compute strlen in the right mode. */
2907 while (insn_mode != VOIDmode)
2909 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2910 if (icode != CODE_FOR_nothing)
2911 break;
2913 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2915 if (insn_mode == VOIDmode)
2916 return 0;
2918 /* Make a place to write the result of the instruction. */
2919 result = target;
2920 if (! (result != 0
2921 && REG_P (result)
2922 && GET_MODE (result) == insn_mode
2923 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2924 result = gen_reg_rtx (insn_mode);
2926 /* Make a place to hold the source address. We will not expand
2927 the actual source until we are sure that the expansion will
2928 not fail -- there are trees that cannot be expanded twice. */
2929 src_reg = gen_reg_rtx (Pmode);
2931 /* Mark the beginning of the strlen sequence so we can emit the
2932 source operand later. */
2933 before_strlen = get_last_insn ();
2935 char_rtx = const0_rtx;
2936 char_mode = insn_data[(int) icode].operand[2].mode;
2937 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2938 char_mode))
2939 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2941 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2942 char_rtx, GEN_INT (align));
2943 if (! pat)
2944 return 0;
2945 emit_insn (pat);
2947 /* Now that we are assured of success, expand the source. */
2948 start_sequence ();
2949 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2950 if (pat != src_reg)
2951 emit_move_insn (src_reg, pat);
2952 pat = get_insns ();
2953 end_sequence ();
2955 if (before_strlen)
2956 emit_insn_after (pat, before_strlen);
2957 else
2958 emit_insn_before (pat, get_insns ());
2960 /* Return the value in the proper mode for this function. */
2961 if (GET_MODE (result) == target_mode)
2962 target = result;
2963 else if (target != 0)
2964 convert_move (target, result, 0);
2965 else
2966 target = convert_to_mode (target_mode, result, 0);
2968 return target;
2972 /* Expand a call to the strstr builtin. Return 0 if we failed the
2973 caller should emit a normal call, otherwise try to get the result
2974 in TARGET, if convenient (and in mode MODE if that's convenient). */
2976 static rtx
2977 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2979 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2981 tree result = fold_builtin_strstr (arglist, type);
2982 if (result)
2983 return expand_expr (result, target, mode, EXPAND_NORMAL);
2985 return 0;
2988 /* Expand a call to the strchr builtin. Return 0 if we failed the
2989 caller should emit a normal call, otherwise try to get the result
2990 in TARGET, if convenient (and in mode MODE if that's convenient). */
2992 static rtx
2993 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2995 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2997 tree result = fold_builtin_strchr (arglist, type);
2998 if (result)
2999 return expand_expr (result, target, mode, EXPAND_NORMAL);
3001 /* FIXME: Should use strchrM optab so that ports can optimize this. */
3003 return 0;
3006 /* Expand a call to the strrchr builtin. Return 0 if we failed the
3007 caller should emit a normal call, otherwise try to get the result
3008 in TARGET, if convenient (and in mode MODE if that's convenient). */
3010 static rtx
3011 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
3013 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3015 tree result = fold_builtin_strrchr (arglist, type);
3016 if (result)
3017 return expand_expr (result, target, mode, EXPAND_NORMAL);
3019 return 0;
3022 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
3023 caller should emit a normal call, otherwise try to get the result
3024 in TARGET, if convenient (and in mode MODE if that's convenient). */
3026 static rtx
3027 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
3029 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3031 tree result = fold_builtin_strpbrk (arglist, type);
3032 if (result)
3033 return expand_expr (result, target, mode, EXPAND_NORMAL);
3035 return 0;
3038 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3039 bytes from constant string DATA + OFFSET and return it as target
3040 constant. */
3042 static rtx
3043 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3044 enum machine_mode mode)
3046 const char *str = (const char *) data;
3048 gcc_assert (offset >= 0
3049 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3050 <= strlen (str) + 1));
3052 return c_readstr (str + offset, mode);
3055 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
3056 Return 0 if we failed, the caller should emit a normal call,
3057 otherwise try to get the result in TARGET, if convenient (and in
3058 mode MODE if that's convenient). */
3059 static rtx
3060 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
3062 tree fndecl = get_callee_fndecl (exp);
3063 tree arglist = TREE_OPERAND (exp, 1);
3064 if (!validate_arglist (arglist,
3065 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3066 return 0;
3067 else
3069 tree dest = TREE_VALUE (arglist);
3070 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3071 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3072 const char *src_str;
3073 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3074 unsigned int dest_align
3075 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3076 rtx dest_mem, src_mem, dest_addr, len_rtx;
3077 tree result = fold_builtin_memory_op (arglist, TREE_TYPE (TREE_TYPE (fndecl)),
3078 false, /*endp=*/0);
3080 if (result)
3082 while (TREE_CODE (result) == COMPOUND_EXPR)
3084 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3085 EXPAND_NORMAL);
3086 result = TREE_OPERAND (result, 1);
3088 return expand_expr (result, target, mode, EXPAND_NORMAL);
3091 /* If DEST is not a pointer type, call the normal function. */
3092 if (dest_align == 0)
3093 return 0;
3095 /* If either SRC is not a pointer type, don't do this
3096 operation in-line. */
3097 if (src_align == 0)
3098 return 0;
3100 dest_mem = get_memory_rtx (dest, len);
3101 set_mem_align (dest_mem, dest_align);
3102 len_rtx = expand_normal (len);
3103 src_str = c_getstr (src);
3105 /* If SRC is a string constant and block move would be done
3106 by pieces, we can avoid loading the string from memory
3107 and only stored the computed constants. */
3108 if (src_str
3109 && GET_CODE (len_rtx) == CONST_INT
3110 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3111 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3112 (void *) src_str, dest_align))
3114 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3115 builtin_memcpy_read_str,
3116 (void *) src_str, dest_align, 0);
3117 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3118 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3119 return dest_mem;
3122 src_mem = get_memory_rtx (src, len);
3123 set_mem_align (src_mem, src_align);
3125 /* Copy word part most expediently. */
3126 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
3127 CALL_EXPR_TAILCALL (exp)
3128 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3130 if (dest_addr == 0)
3132 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3133 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3135 return dest_addr;
3139 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
3140 Return 0 if we failed; the caller should emit a normal call,
3141 otherwise try to get the result in TARGET, if convenient (and in
3142 mode MODE if that's convenient). If ENDP is 0 return the
3143 destination pointer, if ENDP is 1 return the end pointer ala
3144 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3145 stpcpy. */
3147 static rtx
3148 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
3149 int endp)
3151 if (!validate_arglist (arglist,
3152 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3153 return 0;
3154 /* If return value is ignored, transform mempcpy into memcpy. */
3155 else if (target == const0_rtx)
3157 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3159 if (!fn)
3160 return 0;
3162 return expand_expr (build_function_call_expr (fn, arglist),
3163 target, mode, EXPAND_NORMAL);
3165 else
3167 tree dest = TREE_VALUE (arglist);
3168 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3169 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3170 const char *src_str;
3171 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3172 unsigned int dest_align
3173 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3174 rtx dest_mem, src_mem, len_rtx;
3175 tree result = fold_builtin_memory_op (arglist, type, false, endp);
3177 if (result)
3179 while (TREE_CODE (result) == COMPOUND_EXPR)
3181 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3182 EXPAND_NORMAL);
3183 result = TREE_OPERAND (result, 1);
3185 return expand_expr (result, target, mode, EXPAND_NORMAL);
3188 /* If either SRC or DEST is not a pointer type, don't do this
3189 operation in-line. */
3190 if (dest_align == 0 || src_align == 0)
3191 return 0;
3193 /* If LEN is not constant, call the normal function. */
3194 if (! host_integerp (len, 1))
3195 return 0;
3197 len_rtx = expand_normal (len);
3198 src_str = c_getstr (src);
3200 /* If SRC is a string constant and block move would be done
3201 by pieces, we can avoid loading the string from memory
3202 and only stored the computed constants. */
3203 if (src_str
3204 && GET_CODE (len_rtx) == CONST_INT
3205 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3206 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3207 (void *) src_str, dest_align))
3209 dest_mem = get_memory_rtx (dest, len);
3210 set_mem_align (dest_mem, dest_align);
3211 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3212 builtin_memcpy_read_str,
3213 (void *) src_str, dest_align, endp);
3214 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3215 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3216 return dest_mem;
3219 if (GET_CODE (len_rtx) == CONST_INT
3220 && can_move_by_pieces (INTVAL (len_rtx),
3221 MIN (dest_align, src_align)))
3223 dest_mem = get_memory_rtx (dest, len);
3224 set_mem_align (dest_mem, dest_align);
3225 src_mem = get_memory_rtx (src, len);
3226 set_mem_align (src_mem, src_align);
3227 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3228 MIN (dest_align, src_align), endp);
3229 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3230 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3231 return dest_mem;
3234 return 0;
3238 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3239 if we failed; the caller should emit a normal call. */
3241 static rtx
3242 expand_builtin_memmove (tree arglist, tree type, rtx target,
3243 enum machine_mode mode)
3245 if (!validate_arglist (arglist,
3246 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3247 return 0;
3248 else
3250 tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3);
3252 if (result)
3254 while (TREE_CODE (result) == COMPOUND_EXPR)
3256 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3257 EXPAND_NORMAL);
3258 result = TREE_OPERAND (result, 1);
3260 return expand_expr (result, target, mode, EXPAND_NORMAL);
3263 /* Otherwise, call the normal function. */
3264 return 0;
3268 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3269 if we failed the caller should emit a normal call. */
3271 static rtx
3272 expand_builtin_bcopy (tree exp)
3274 tree arglist = TREE_OPERAND (exp, 1);
3275 tree type = TREE_TYPE (exp);
3276 tree src, dest, size, newarglist;
3278 if (!validate_arglist (arglist,
3279 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3280 return NULL_RTX;
3282 src = TREE_VALUE (arglist);
3283 dest = TREE_VALUE (TREE_CHAIN (arglist));
3284 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3286 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3287 memmove(ptr y, ptr x, size_t z). This is done this way
3288 so that if it isn't expanded inline, we fallback to
3289 calling bcopy instead of memmove. */
3291 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3292 newarglist = tree_cons (NULL_TREE, src, newarglist);
3293 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3295 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode);
3298 #ifndef HAVE_movstr
3299 # define HAVE_movstr 0
3300 # define CODE_FOR_movstr CODE_FOR_nothing
3301 #endif
3303 /* Expand into a movstr instruction, if one is available. Return 0 if
3304 we failed, the caller should emit a normal call, otherwise try to
3305 get the result in TARGET, if convenient. If ENDP is 0 return the
3306 destination pointer, if ENDP is 1 return the end pointer ala
3307 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3308 stpcpy. */
3310 static rtx
3311 expand_movstr (tree dest, tree src, rtx target, int endp)
3313 rtx end;
3314 rtx dest_mem;
3315 rtx src_mem;
3316 rtx insn;
3317 const struct insn_data * data;
3319 if (!HAVE_movstr)
3320 return 0;
3322 dest_mem = get_memory_rtx (dest, NULL);
3323 src_mem = get_memory_rtx (src, NULL);
3324 if (!endp)
3326 target = force_reg (Pmode, XEXP (dest_mem, 0));
3327 dest_mem = replace_equiv_address (dest_mem, target);
3328 end = gen_reg_rtx (Pmode);
3330 else
3332 if (target == 0 || target == const0_rtx)
3334 end = gen_reg_rtx (Pmode);
3335 if (target == 0)
3336 target = end;
3338 else
3339 end = target;
3342 data = insn_data + CODE_FOR_movstr;
3344 if (data->operand[0].mode != VOIDmode)
3345 end = gen_lowpart (data->operand[0].mode, end);
3347 insn = data->genfun (end, dest_mem, src_mem);
3349 gcc_assert (insn);
3351 emit_insn (insn);
3353 /* movstr is supposed to set end to the address of the NUL
3354 terminator. If the caller requested a mempcpy-like return value,
3355 adjust it. */
3356 if (endp == 1 && target != const0_rtx)
3358 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3359 emit_move_insn (target, force_operand (tem, NULL_RTX));
3362 return target;
3365 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3366 if we failed the caller should emit a normal call, otherwise try to get
3367 the result in TARGET, if convenient (and in mode MODE if that's
3368 convenient). */
3370 static rtx
3371 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3373 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3375 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3376 if (result)
3378 while (TREE_CODE (result) == COMPOUND_EXPR)
3380 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3381 EXPAND_NORMAL);
3382 result = TREE_OPERAND (result, 1);
3384 return expand_expr (result, target, mode, EXPAND_NORMAL);
3387 return expand_movstr (TREE_VALUE (arglist),
3388 TREE_VALUE (TREE_CHAIN (arglist)),
3389 target, /*endp=*/0);
3391 return 0;
3394 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3395 Return 0 if we failed the caller should emit a normal call,
3396 otherwise try to get the result in TARGET, if convenient (and in
3397 mode MODE if that's convenient). */
3399 static rtx
3400 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3402 tree arglist = TREE_OPERAND (exp, 1);
3403 /* If return value is ignored, transform stpcpy into strcpy. */
3404 if (target == const0_rtx)
3406 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3407 if (!fn)
3408 return 0;
3410 return expand_expr (build_function_call_expr (fn, arglist),
3411 target, mode, EXPAND_NORMAL);
3414 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3415 return 0;
3416 else
3418 tree dst, src, len, lenp1;
3419 tree narglist;
3420 rtx ret;
3422 /* Ensure we get an actual string whose length can be evaluated at
3423 compile-time, not an expression containing a string. This is
3424 because the latter will potentially produce pessimized code
3425 when used to produce the return value. */
3426 src = TREE_VALUE (TREE_CHAIN (arglist));
3427 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3428 return expand_movstr (TREE_VALUE (arglist),
3429 TREE_VALUE (TREE_CHAIN (arglist)),
3430 target, /*endp=*/2);
3432 dst = TREE_VALUE (arglist);
3433 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3434 narglist = build_tree_list (NULL_TREE, lenp1);
3435 narglist = tree_cons (NULL_TREE, src, narglist);
3436 narglist = tree_cons (NULL_TREE, dst, narglist);
3437 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3438 target, mode, /*endp=*/2);
3440 if (ret)
3441 return ret;
3443 if (TREE_CODE (len) == INTEGER_CST)
3445 rtx len_rtx = expand_normal (len);
3447 if (GET_CODE (len_rtx) == CONST_INT)
3449 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3450 arglist, target, mode);
3452 if (ret)
3454 if (! target)
3456 if (mode != VOIDmode)
3457 target = gen_reg_rtx (mode);
3458 else
3459 target = gen_reg_rtx (GET_MODE (ret));
3461 if (GET_MODE (target) != GET_MODE (ret))
3462 ret = gen_lowpart (GET_MODE (target), ret);
3464 ret = plus_constant (ret, INTVAL (len_rtx));
3465 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3466 gcc_assert (ret);
3468 return target;
3473 return expand_movstr (TREE_VALUE (arglist),
3474 TREE_VALUE (TREE_CHAIN (arglist)),
3475 target, /*endp=*/2);
3479 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3480 bytes from constant string DATA + OFFSET and return it as target
3481 constant. */
3483 static rtx
3484 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3485 enum machine_mode mode)
3487 const char *str = (const char *) data;
3489 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3490 return const0_rtx;
3492 return c_readstr (str + offset, mode);
3495 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3496 if we failed the caller should emit a normal call. */
3498 static rtx
3499 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3501 tree fndecl = get_callee_fndecl (exp);
3502 tree arglist = TREE_OPERAND (exp, 1);
3503 if (validate_arglist (arglist,
3504 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3506 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3507 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3508 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3510 if (result)
3512 while (TREE_CODE (result) == COMPOUND_EXPR)
3514 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3515 EXPAND_NORMAL);
3516 result = TREE_OPERAND (result, 1);
3518 return expand_expr (result, target, mode, EXPAND_NORMAL);
3521 /* We must be passed a constant len and src parameter. */
3522 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3523 return 0;
3525 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3527 /* We're required to pad with trailing zeros if the requested
3528 len is greater than strlen(s2)+1. In that case try to
3529 use store_by_pieces, if it fails, punt. */
3530 if (tree_int_cst_lt (slen, len))
3532 tree dest = TREE_VALUE (arglist);
3533 unsigned int dest_align
3534 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3535 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3536 rtx dest_mem;
3538 if (!p || dest_align == 0 || !host_integerp (len, 1)
3539 || !can_store_by_pieces (tree_low_cst (len, 1),
3540 builtin_strncpy_read_str,
3541 (void *) p, dest_align))
3542 return 0;
3544 dest_mem = get_memory_rtx (dest, len);
3545 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3546 builtin_strncpy_read_str,
3547 (void *) p, dest_align, 0);
3548 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3549 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3550 return dest_mem;
3553 return 0;
3556 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3557 bytes from constant string DATA + OFFSET and return it as target
3558 constant. */
3561 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3562 enum machine_mode mode)
3564 const char *c = (const char *) data;
3565 char *p = alloca (GET_MODE_SIZE (mode));
3567 memset (p, *c, GET_MODE_SIZE (mode));
3569 return c_readstr (p, mode);
3572 /* Callback routine for store_by_pieces. Return the RTL of a register
3573 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3574 char value given in the RTL register data. For example, if mode is
3575 4 bytes wide, return the RTL for 0x01010101*data. */
3577 static rtx
3578 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3579 enum machine_mode mode)
3581 rtx target, coeff;
3582 size_t size;
3583 char *p;
3585 size = GET_MODE_SIZE (mode);
3586 if (size == 1)
3587 return (rtx) data;
3589 p = alloca (size);
3590 memset (p, 1, size);
3591 coeff = c_readstr (p, mode);
3593 target = convert_to_mode (mode, (rtx) data, 1);
3594 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3595 return force_reg (mode, target);
3598 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3599 if we failed the caller should emit a normal call, otherwise try to get
3600 the result in TARGET, if convenient (and in mode MODE if that's
3601 convenient). */
3603 static rtx
3604 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3605 tree orig_exp)
3607 if (!validate_arglist (arglist,
3608 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3609 return 0;
3610 else
3612 tree dest = TREE_VALUE (arglist);
3613 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3614 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3615 tree fndecl, fn;
3616 enum built_in_function fcode;
3617 char c;
3618 unsigned int dest_align;
3619 rtx dest_mem, dest_addr, len_rtx;
3621 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3623 /* If DEST is not a pointer type, don't do this
3624 operation in-line. */
3625 if (dest_align == 0)
3626 return 0;
3628 /* If the LEN parameter is zero, return DEST. */
3629 if (integer_zerop (len))
3631 /* Evaluate and ignore VAL in case it has side-effects. */
3632 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3633 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3636 /* Stabilize the arguments in case we fail. */
3637 dest = builtin_save_expr (dest);
3638 val = builtin_save_expr (val);
3639 len = builtin_save_expr (len);
3641 len_rtx = expand_normal (len);
3642 dest_mem = get_memory_rtx (dest, len);
3644 if (TREE_CODE (val) != INTEGER_CST)
3646 rtx val_rtx;
3648 val_rtx = expand_normal (val);
3649 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3650 val_rtx, 0);
3652 /* Assume that we can memset by pieces if we can store the
3653 * the coefficients by pieces (in the required modes).
3654 * We can't pass builtin_memset_gen_str as that emits RTL. */
3655 c = 1;
3656 if (host_integerp (len, 1)
3657 && !(optimize_size && tree_low_cst (len, 1) > 1)
3658 && can_store_by_pieces (tree_low_cst (len, 1),
3659 builtin_memset_read_str, &c, dest_align))
3661 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3662 val_rtx);
3663 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3664 builtin_memset_gen_str, val_rtx, dest_align, 0);
3666 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3667 dest_align))
3668 goto do_libcall;
3670 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3671 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3672 return dest_mem;
3675 if (target_char_cast (val, &c))
3676 goto do_libcall;
3678 if (c)
3680 if (host_integerp (len, 1)
3681 && !(optimize_size && tree_low_cst (len, 1) > 1)
3682 && can_store_by_pieces (tree_low_cst (len, 1),
3683 builtin_memset_read_str, &c, dest_align))
3684 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3685 builtin_memset_read_str, &c, dest_align, 0);
3686 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3687 dest_align))
3688 goto do_libcall;
3690 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3691 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3692 return dest_mem;
3695 set_mem_align (dest_mem, dest_align);
3696 dest_addr = clear_storage (dest_mem, len_rtx,
3697 CALL_EXPR_TAILCALL (orig_exp)
3698 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3700 if (dest_addr == 0)
3702 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3703 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3706 return dest_addr;
3708 do_libcall:
3709 fndecl = get_callee_fndecl (orig_exp);
3710 fcode = DECL_FUNCTION_CODE (fndecl);
3711 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3712 arglist = build_tree_list (NULL_TREE, len);
3713 if (fcode == BUILT_IN_MEMSET)
3714 arglist = tree_cons (NULL_TREE, val, arglist);
3715 arglist = tree_cons (NULL_TREE, dest, arglist);
3716 fn = build_function_call_expr (fndecl, arglist);
3717 if (TREE_CODE (fn) == CALL_EXPR)
3718 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3719 return expand_call (fn, target, target == const0_rtx);
3723 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3724 if we failed the caller should emit a normal call. */
3726 static rtx
3727 expand_builtin_bzero (tree exp)
3729 tree arglist = TREE_OPERAND (exp, 1);
3730 tree dest, size, newarglist;
3732 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3733 return NULL_RTX;
3735 dest = TREE_VALUE (arglist);
3736 size = TREE_VALUE (TREE_CHAIN (arglist));
3738 /* New argument list transforming bzero(ptr x, int y) to
3739 memset(ptr x, int 0, size_t y). This is done this way
3740 so that if it isn't expanded inline, we fallback to
3741 calling bzero instead of memset. */
3743 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3744 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3745 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3747 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3750 /* Expand expression EXP, which is a call to the memcmp built-in function.
3751 ARGLIST is the argument list for this call. Return 0 if we failed and the
3752 caller should emit a normal call, otherwise try to get the result in
3753 TARGET, if convenient (and in mode MODE, if that's convenient). */
3755 static rtx
3756 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3757 enum machine_mode mode)
3759 if (!validate_arglist (arglist,
3760 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3761 return 0;
3762 else
3764 tree result = fold_builtin_memcmp (arglist);
3765 if (result)
3766 return expand_expr (result, target, mode, EXPAND_NORMAL);
3769 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3771 tree arg1 = TREE_VALUE (arglist);
3772 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3773 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3774 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3775 rtx result;
3776 rtx insn;
3778 int arg1_align
3779 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3780 int arg2_align
3781 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3782 enum machine_mode insn_mode;
3784 #ifdef HAVE_cmpmemsi
3785 if (HAVE_cmpmemsi)
3786 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3787 else
3788 #endif
3789 #ifdef HAVE_cmpstrnsi
3790 if (HAVE_cmpstrnsi)
3791 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3792 else
3793 #endif
3794 return 0;
3796 /* If we don't have POINTER_TYPE, call the function. */
3797 if (arg1_align == 0 || arg2_align == 0)
3798 return 0;
3800 /* Make a place to write the result of the instruction. */
3801 result = target;
3802 if (! (result != 0
3803 && REG_P (result) && GET_MODE (result) == insn_mode
3804 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3805 result = gen_reg_rtx (insn_mode);
3807 arg1_rtx = get_memory_rtx (arg1, len);
3808 arg2_rtx = get_memory_rtx (arg2, len);
3809 arg3_rtx = expand_normal (len);
3811 /* Set MEM_SIZE as appropriate. */
3812 if (GET_CODE (arg3_rtx) == CONST_INT)
3814 set_mem_size (arg1_rtx, arg3_rtx);
3815 set_mem_size (arg2_rtx, arg3_rtx);
3818 #ifdef HAVE_cmpmemsi
3819 if (HAVE_cmpmemsi)
3820 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3821 GEN_INT (MIN (arg1_align, arg2_align)));
3822 else
3823 #endif
3824 #ifdef HAVE_cmpstrnsi
3825 if (HAVE_cmpstrnsi)
3826 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3827 GEN_INT (MIN (arg1_align, arg2_align)));
3828 else
3829 #endif
3830 gcc_unreachable ();
3832 if (insn)
3833 emit_insn (insn);
3834 else
3835 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3836 TYPE_MODE (integer_type_node), 3,
3837 XEXP (arg1_rtx, 0), Pmode,
3838 XEXP (arg2_rtx, 0), Pmode,
3839 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3840 TYPE_UNSIGNED (sizetype)),
3841 TYPE_MODE (sizetype));
3843 /* Return the value in the proper mode for this function. */
3844 mode = TYPE_MODE (TREE_TYPE (exp));
3845 if (GET_MODE (result) == mode)
3846 return result;
3847 else if (target != 0)
3849 convert_move (target, result, 0);
3850 return target;
3852 else
3853 return convert_to_mode (mode, result, 0);
3855 #endif
3857 return 0;
3860 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3861 if we failed the caller should emit a normal call, otherwise try to get
3862 the result in TARGET, if convenient. */
3864 static rtx
3865 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3867 tree arglist = TREE_OPERAND (exp, 1);
3869 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3870 return 0;
3871 else
3873 tree result = fold_builtin_strcmp (arglist);
3874 if (result)
3875 return expand_expr (result, target, mode, EXPAND_NORMAL);
3878 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3879 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3880 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3882 rtx arg1_rtx, arg2_rtx;
3883 rtx result, insn = NULL_RTX;
3884 tree fndecl, fn;
3886 tree arg1 = TREE_VALUE (arglist);
3887 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3888 int arg1_align
3889 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3890 int arg2_align
3891 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3893 /* If we don't have POINTER_TYPE, call the function. */
3894 if (arg1_align == 0 || arg2_align == 0)
3895 return 0;
3897 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3898 arg1 = builtin_save_expr (arg1);
3899 arg2 = builtin_save_expr (arg2);
3901 arg1_rtx = get_memory_rtx (arg1, NULL);
3902 arg2_rtx = get_memory_rtx (arg2, NULL);
3904 #ifdef HAVE_cmpstrsi
3905 /* Try to call cmpstrsi. */
3906 if (HAVE_cmpstrsi)
3908 enum machine_mode insn_mode
3909 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3911 /* Make a place to write the result of the instruction. */
3912 result = target;
3913 if (! (result != 0
3914 && REG_P (result) && GET_MODE (result) == insn_mode
3915 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3916 result = gen_reg_rtx (insn_mode);
3918 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3919 GEN_INT (MIN (arg1_align, arg2_align)));
3921 #endif
3922 #ifdef HAVE_cmpstrnsi
3923 /* Try to determine at least one length and call cmpstrnsi. */
3924 if (!insn && HAVE_cmpstrnsi)
3926 tree len;
3927 rtx arg3_rtx;
3929 enum machine_mode insn_mode
3930 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3931 tree len1 = c_strlen (arg1, 1);
3932 tree len2 = c_strlen (arg2, 1);
3934 if (len1)
3935 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3936 if (len2)
3937 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3939 /* If we don't have a constant length for the first, use the length
3940 of the second, if we know it. We don't require a constant for
3941 this case; some cost analysis could be done if both are available
3942 but neither is constant. For now, assume they're equally cheap,
3943 unless one has side effects. If both strings have constant lengths,
3944 use the smaller. */
3946 if (!len1)
3947 len = len2;
3948 else if (!len2)
3949 len = len1;
3950 else if (TREE_SIDE_EFFECTS (len1))
3951 len = len2;
3952 else if (TREE_SIDE_EFFECTS (len2))
3953 len = len1;
3954 else if (TREE_CODE (len1) != INTEGER_CST)
3955 len = len2;
3956 else if (TREE_CODE (len2) != INTEGER_CST)
3957 len = len1;
3958 else if (tree_int_cst_lt (len1, len2))
3959 len = len1;
3960 else
3961 len = len2;
3963 /* If both arguments have side effects, we cannot optimize. */
3964 if (!len || TREE_SIDE_EFFECTS (len))
3965 goto do_libcall;
3967 arg3_rtx = expand_normal (len);
3969 /* Make a place to write the result of the instruction. */
3970 result = target;
3971 if (! (result != 0
3972 && REG_P (result) && GET_MODE (result) == insn_mode
3973 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3974 result = gen_reg_rtx (insn_mode);
3976 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3977 GEN_INT (MIN (arg1_align, arg2_align)));
3979 #endif
3981 if (insn)
3983 emit_insn (insn);
3985 /* Return the value in the proper mode for this function. */
3986 mode = TYPE_MODE (TREE_TYPE (exp));
3987 if (GET_MODE (result) == mode)
3988 return result;
3989 if (target == 0)
3990 return convert_to_mode (mode, result, 0);
3991 convert_move (target, result, 0);
3992 return target;
3995 /* Expand the library call ourselves using a stabilized argument
3996 list to avoid re-evaluating the function's arguments twice. */
3997 #ifdef HAVE_cmpstrnsi
3998 do_libcall:
3999 #endif
4000 arglist = build_tree_list (NULL_TREE, arg2);
4001 arglist = tree_cons (NULL_TREE, arg1, arglist);
4002 fndecl = get_callee_fndecl (exp);
4003 fn = build_function_call_expr (fndecl, arglist);
4004 if (TREE_CODE (fn) == CALL_EXPR)
4005 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4006 return expand_call (fn, target, target == const0_rtx);
4008 #endif
4009 return 0;
4012 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
4013 if we failed the caller should emit a normal call, otherwise try to get
4014 the result in TARGET, if convenient. */
4016 static rtx
4017 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
4019 tree arglist = TREE_OPERAND (exp, 1);
4021 if (!validate_arglist (arglist,
4022 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4023 return 0;
4024 else
4026 tree result = fold_builtin_strncmp (arglist);
4027 if (result)
4028 return expand_expr (result, target, mode, EXPAND_NORMAL);
4031 /* If c_strlen can determine an expression for one of the string
4032 lengths, and it doesn't have side effects, then emit cmpstrnsi
4033 using length MIN(strlen(string)+1, arg3). */
4034 #ifdef HAVE_cmpstrnsi
4035 if (HAVE_cmpstrnsi)
4037 tree arg1 = TREE_VALUE (arglist);
4038 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
4039 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4040 tree len, len1, len2;
4041 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4042 rtx result, insn;
4043 tree fndecl, fn;
4045 int arg1_align
4046 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4047 int arg2_align
4048 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4049 enum machine_mode insn_mode
4050 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4052 len1 = c_strlen (arg1, 1);
4053 len2 = c_strlen (arg2, 1);
4055 if (len1)
4056 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4057 if (len2)
4058 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4060 /* If we don't have a constant length for the first, use the length
4061 of the second, if we know it. We don't require a constant for
4062 this case; some cost analysis could be done if both are available
4063 but neither is constant. For now, assume they're equally cheap,
4064 unless one has side effects. If both strings have constant lengths,
4065 use the smaller. */
4067 if (!len1)
4068 len = len2;
4069 else if (!len2)
4070 len = len1;
4071 else if (TREE_SIDE_EFFECTS (len1))
4072 len = len2;
4073 else if (TREE_SIDE_EFFECTS (len2))
4074 len = len1;
4075 else if (TREE_CODE (len1) != INTEGER_CST)
4076 len = len2;
4077 else if (TREE_CODE (len2) != INTEGER_CST)
4078 len = len1;
4079 else if (tree_int_cst_lt (len1, len2))
4080 len = len1;
4081 else
4082 len = len2;
4084 /* If both arguments have side effects, we cannot optimize. */
4085 if (!len || TREE_SIDE_EFFECTS (len))
4086 return 0;
4088 /* The actual new length parameter is MIN(len,arg3). */
4089 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
4090 fold_convert (TREE_TYPE (len), arg3));
4092 /* If we don't have POINTER_TYPE, call the function. */
4093 if (arg1_align == 0 || arg2_align == 0)
4094 return 0;
4096 /* Make a place to write the result of the instruction. */
4097 result = target;
4098 if (! (result != 0
4099 && REG_P (result) && GET_MODE (result) == insn_mode
4100 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4101 result = gen_reg_rtx (insn_mode);
4103 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4104 arg1 = builtin_save_expr (arg1);
4105 arg2 = builtin_save_expr (arg2);
4106 len = builtin_save_expr (len);
4108 arg1_rtx = get_memory_rtx (arg1, len);
4109 arg2_rtx = get_memory_rtx (arg2, len);
4110 arg3_rtx = expand_normal (len);
4111 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4112 GEN_INT (MIN (arg1_align, arg2_align)));
4113 if (insn)
4115 emit_insn (insn);
4117 /* Return the value in the proper mode for this function. */
4118 mode = TYPE_MODE (TREE_TYPE (exp));
4119 if (GET_MODE (result) == mode)
4120 return result;
4121 if (target == 0)
4122 return convert_to_mode (mode, result, 0);
4123 convert_move (target, result, 0);
4124 return target;
4127 /* Expand the library call ourselves using a stabilized argument
4128 list to avoid re-evaluating the function's arguments twice. */
4129 arglist = build_tree_list (NULL_TREE, len);
4130 arglist = tree_cons (NULL_TREE, arg2, arglist);
4131 arglist = tree_cons (NULL_TREE, arg1, arglist);
4132 fndecl = get_callee_fndecl (exp);
4133 fn = build_function_call_expr (fndecl, arglist);
4134 if (TREE_CODE (fn) == CALL_EXPR)
4135 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4136 return expand_call (fn, target, target == const0_rtx);
4138 #endif
4139 return 0;
4142 /* Expand expression EXP, which is a call to the strcat builtin.
4143 Return 0 if we failed the caller should emit a normal call,
4144 otherwise try to get the result in TARGET, if convenient. */
4146 static rtx
4147 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
4149 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4150 return 0;
4151 else
4153 tree dst = TREE_VALUE (arglist),
4154 src = TREE_VALUE (TREE_CHAIN (arglist));
4155 const char *p = c_getstr (src);
4157 /* If the string length is zero, return the dst parameter. */
4158 if (p && *p == '\0')
4159 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4161 if (!optimize_size)
4163 /* See if we can store by pieces into (dst + strlen(dst)). */
4164 tree newsrc, newdst,
4165 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4166 rtx insns;
4168 /* Stabilize the argument list. */
4169 newsrc = builtin_save_expr (src);
4170 if (newsrc != src)
4171 arglist = build_tree_list (NULL_TREE, newsrc);
4172 else
4173 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
4175 dst = builtin_save_expr (dst);
4177 start_sequence ();
4179 /* Create strlen (dst). */
4180 newdst =
4181 build_function_call_expr (strlen_fn,
4182 build_tree_list (NULL_TREE, dst));
4183 /* Create (dst + (cast) strlen (dst)). */
4184 newdst = fold_convert (TREE_TYPE (dst), newdst);
4185 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4187 newdst = builtin_save_expr (newdst);
4188 arglist = tree_cons (NULL_TREE, newdst, arglist);
4190 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
4192 end_sequence (); /* Stop sequence. */
4193 return 0;
4196 /* Output the entire sequence. */
4197 insns = get_insns ();
4198 end_sequence ();
4199 emit_insn (insns);
4201 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4204 return 0;
4208 /* Expand expression EXP, which is a call to the strncat builtin.
4209 Return 0 if we failed the caller should emit a normal call,
4210 otherwise try to get the result in TARGET, if convenient. */
4212 static rtx
4213 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4215 if (validate_arglist (arglist,
4216 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4218 tree result = fold_builtin_strncat (arglist);
4219 if (result)
4220 return expand_expr (result, target, mode, EXPAND_NORMAL);
4222 return 0;
4225 /* Expand expression EXP, which is a call to the strspn builtin.
4226 Return 0 if we failed the caller should emit a normal call,
4227 otherwise try to get the result in TARGET, if convenient. */
4229 static rtx
4230 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4232 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4234 tree result = fold_builtin_strspn (arglist);
4235 if (result)
4236 return expand_expr (result, target, mode, EXPAND_NORMAL);
4238 return 0;
4241 /* Expand expression EXP, which is a call to the strcspn builtin.
4242 Return 0 if we failed the caller should emit a normal call,
4243 otherwise try to get the result in TARGET, if convenient. */
4245 static rtx
4246 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4248 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4250 tree result = fold_builtin_strcspn (arglist);
4251 if (result)
4252 return expand_expr (result, target, mode, EXPAND_NORMAL);
4254 return 0;
4257 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4258 if that's convenient. */
4261 expand_builtin_saveregs (void)
4263 rtx val, seq;
4265 /* Don't do __builtin_saveregs more than once in a function.
4266 Save the result of the first call and reuse it. */
4267 if (saveregs_value != 0)
4268 return saveregs_value;
4270 /* When this function is called, it means that registers must be
4271 saved on entry to this function. So we migrate the call to the
4272 first insn of this function. */
4274 start_sequence ();
4276 /* Do whatever the machine needs done in this case. */
4277 val = targetm.calls.expand_builtin_saveregs ();
4279 seq = get_insns ();
4280 end_sequence ();
4282 saveregs_value = val;
4284 /* Put the insns after the NOTE that starts the function. If this
4285 is inside a start_sequence, make the outer-level insn chain current, so
4286 the code is placed at the start of the function. */
4287 push_topmost_sequence ();
4288 emit_insn_after (seq, entry_of_function ());
4289 pop_topmost_sequence ();
4291 return val;
4294 /* __builtin_args_info (N) returns word N of the arg space info
4295 for the current function. The number and meanings of words
4296 is controlled by the definition of CUMULATIVE_ARGS. */
4298 static rtx
4299 expand_builtin_args_info (tree arglist)
4301 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4302 int *word_ptr = (int *) &current_function_args_info;
4304 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4306 if (arglist != 0)
4308 if (!host_integerp (TREE_VALUE (arglist), 0))
4309 error ("argument of %<__builtin_args_info%> must be constant");
4310 else
4312 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4314 if (wordnum < 0 || wordnum >= nwords)
4315 error ("argument of %<__builtin_args_info%> out of range");
4316 else
4317 return GEN_INT (word_ptr[wordnum]);
4320 else
4321 error ("missing argument in %<__builtin_args_info%>");
4323 return const0_rtx;
4326 /* Expand a call to __builtin_next_arg. */
4328 static rtx
4329 expand_builtin_next_arg (void)
4331 /* Checking arguments is already done in fold_builtin_next_arg
4332 that must be called before this function. */
4333 return expand_binop (Pmode, add_optab,
4334 current_function_internal_arg_pointer,
4335 current_function_arg_offset_rtx,
4336 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4339 /* Make it easier for the backends by protecting the valist argument
4340 from multiple evaluations. */
4342 static tree
4343 stabilize_va_list (tree valist, int needs_lvalue)
4345 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4347 if (TREE_SIDE_EFFECTS (valist))
4348 valist = save_expr (valist);
4350 /* For this case, the backends will be expecting a pointer to
4351 TREE_TYPE (va_list_type_node), but it's possible we've
4352 actually been given an array (an actual va_list_type_node).
4353 So fix it. */
4354 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4356 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4357 valist = build_fold_addr_expr_with_type (valist, p1);
4360 else
4362 tree pt;
4364 if (! needs_lvalue)
4366 if (! TREE_SIDE_EFFECTS (valist))
4367 return valist;
4369 pt = build_pointer_type (va_list_type_node);
4370 valist = fold_build1 (ADDR_EXPR, pt, valist);
4371 TREE_SIDE_EFFECTS (valist) = 1;
4374 if (TREE_SIDE_EFFECTS (valist))
4375 valist = save_expr (valist);
4376 valist = build_fold_indirect_ref (valist);
4379 return valist;
4382 /* The "standard" definition of va_list is void*. */
4384 tree
4385 std_build_builtin_va_list (void)
4387 return ptr_type_node;
4390 /* The "standard" implementation of va_start: just assign `nextarg' to
4391 the variable. */
4393 void
4394 std_expand_builtin_va_start (tree valist, rtx nextarg)
4396 tree t;
4398 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist,
4399 make_tree (ptr_type_node, nextarg));
4400 TREE_SIDE_EFFECTS (t) = 1;
4402 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4405 /* Expand ARGLIST, from a call to __builtin_va_start. */
4407 static rtx
4408 expand_builtin_va_start (tree arglist)
4410 rtx nextarg;
4411 tree chain, valist;
4413 chain = TREE_CHAIN (arglist);
4415 if (!chain)
4417 error ("too few arguments to function %<va_start%>");
4418 return const0_rtx;
4421 if (fold_builtin_next_arg (chain))
4422 return const0_rtx;
4424 nextarg = expand_builtin_next_arg ();
4425 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4427 #ifdef EXPAND_BUILTIN_VA_START
4428 EXPAND_BUILTIN_VA_START (valist, nextarg);
4429 #else
4430 std_expand_builtin_va_start (valist, nextarg);
4431 #endif
4433 return const0_rtx;
4436 /* The "standard" implementation of va_arg: read the value from the
4437 current (padded) address and increment by the (padded) size. */
4439 tree
4440 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4442 tree addr, t, type_size, rounded_size, valist_tmp;
4443 unsigned HOST_WIDE_INT align, boundary;
4444 bool indirect;
4446 #ifdef ARGS_GROW_DOWNWARD
4447 /* All of the alignment and movement below is for args-grow-up machines.
4448 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4449 implement their own specialized gimplify_va_arg_expr routines. */
4450 gcc_unreachable ();
4451 #endif
4453 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4454 if (indirect)
4455 type = build_pointer_type (type);
4457 align = PARM_BOUNDARY / BITS_PER_UNIT;
4458 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4460 /* Hoist the valist value into a temporary for the moment. */
4461 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4463 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4464 requires greater alignment, we must perform dynamic alignment. */
4465 if (boundary > align
4466 && !integer_zerop (TYPE_SIZE (type)))
4468 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4469 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist_tmp,
4470 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4471 gimplify_and_add (t, pre_p);
4473 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4474 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist_tmp,
4475 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4476 gimplify_and_add (t, pre_p);
4478 else
4479 boundary = align;
4481 /* If the actual alignment is less than the alignment of the type,
4482 adjust the type accordingly so that we don't assume strict alignment
4483 when deferencing the pointer. */
4484 boundary *= BITS_PER_UNIT;
4485 if (boundary < TYPE_ALIGN (type))
4487 type = build_variant_type_copy (type);
4488 TYPE_ALIGN (type) = boundary;
4491 /* Compute the rounded size of the type. */
4492 type_size = size_in_bytes (type);
4493 rounded_size = round_up (type_size, align);
4495 /* Reduce rounded_size so it's sharable with the postqueue. */
4496 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4498 /* Get AP. */
4499 addr = valist_tmp;
4500 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4502 /* Small args are padded downward. */
4503 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4504 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4505 size_binop (MINUS_EXPR, rounded_size, type_size));
4506 t = fold_convert (TREE_TYPE (addr), t);
4507 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4510 /* Compute new value for AP. */
4511 t = fold_convert (TREE_TYPE (valist), rounded_size);
4512 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4513 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist, t);
4514 gimplify_and_add (t, pre_p);
4516 addr = fold_convert (build_pointer_type (type), addr);
4518 if (indirect)
4519 addr = build_va_arg_indirect_ref (addr);
4521 return build_va_arg_indirect_ref (addr);
4524 /* Build an indirect-ref expression over the given TREE, which represents a
4525 piece of a va_arg() expansion. */
4526 tree
4527 build_va_arg_indirect_ref (tree addr)
4529 addr = build_fold_indirect_ref (addr);
4531 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4532 mf_mark (addr);
4534 return addr;
4537 /* Return a dummy expression of type TYPE in order to keep going after an
4538 error. */
4540 static tree
4541 dummy_object (tree type)
4543 tree t = build_int_cst (build_pointer_type (type), 0);
4544 return build1 (INDIRECT_REF, type, t);
4547 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4548 builtin function, but a very special sort of operator. */
4550 enum gimplify_status
4551 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4553 tree promoted_type, want_va_type, have_va_type;
4554 tree valist = TREE_OPERAND (*expr_p, 0);
4555 tree type = TREE_TYPE (*expr_p);
4556 tree t;
4558 /* Verify that valist is of the proper type. */
4559 want_va_type = va_list_type_node;
4560 have_va_type = TREE_TYPE (valist);
4562 if (have_va_type == error_mark_node)
4563 return GS_ERROR;
4565 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4567 /* If va_list is an array type, the argument may have decayed
4568 to a pointer type, e.g. by being passed to another function.
4569 In that case, unwrap both types so that we can compare the
4570 underlying records. */
4571 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4572 || POINTER_TYPE_P (have_va_type))
4574 want_va_type = TREE_TYPE (want_va_type);
4575 have_va_type = TREE_TYPE (have_va_type);
4579 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4581 error ("first argument to %<va_arg%> not of type %<va_list%>");
4582 return GS_ERROR;
4585 /* Generate a diagnostic for requesting data of a type that cannot
4586 be passed through `...' due to type promotion at the call site. */
4587 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4588 != type)
4590 static bool gave_help;
4592 /* Unfortunately, this is merely undefined, rather than a constraint
4593 violation, so we cannot make this an error. If this call is never
4594 executed, the program is still strictly conforming. */
4595 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4596 type, promoted_type);
4597 if (! gave_help)
4599 gave_help = true;
4600 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4601 promoted_type, type);
4604 /* We can, however, treat "undefined" any way we please.
4605 Call abort to encourage the user to fix the program. */
4606 inform ("if this code is reached, the program will abort");
4607 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4608 NULL);
4609 append_to_statement_list (t, pre_p);
4611 /* This is dead code, but go ahead and finish so that the
4612 mode of the result comes out right. */
4613 *expr_p = dummy_object (type);
4614 return GS_ALL_DONE;
4616 else
4618 /* Make it easier for the backends by protecting the valist argument
4619 from multiple evaluations. */
4620 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4622 /* For this case, the backends will be expecting a pointer to
4623 TREE_TYPE (va_list_type_node), but it's possible we've
4624 actually been given an array (an actual va_list_type_node).
4625 So fix it. */
4626 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4628 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4629 valist = build_fold_addr_expr_with_type (valist, p1);
4631 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4633 else
4634 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4636 if (!targetm.gimplify_va_arg_expr)
4637 /* FIXME:Once most targets are converted we should merely
4638 assert this is non-null. */
4639 return GS_ALL_DONE;
4641 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4642 return GS_OK;
4646 /* Expand ARGLIST, from a call to __builtin_va_end. */
4648 static rtx
4649 expand_builtin_va_end (tree arglist)
4651 tree valist = TREE_VALUE (arglist);
4653 /* Evaluate for side effects, if needed. I hate macros that don't
4654 do that. */
4655 if (TREE_SIDE_EFFECTS (valist))
4656 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4658 return const0_rtx;
4661 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4662 builtin rather than just as an assignment in stdarg.h because of the
4663 nastiness of array-type va_list types. */
4665 static rtx
4666 expand_builtin_va_copy (tree arglist)
4668 tree dst, src, t;
4670 dst = TREE_VALUE (arglist);
4671 src = TREE_VALUE (TREE_CHAIN (arglist));
4673 dst = stabilize_va_list (dst, 1);
4674 src = stabilize_va_list (src, 0);
4676 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4678 t = build2 (GIMPLE_MODIFY_STMT, va_list_type_node, dst, src);
4679 TREE_SIDE_EFFECTS (t) = 1;
4680 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4682 else
4684 rtx dstb, srcb, size;
4686 /* Evaluate to pointers. */
4687 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4688 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4689 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4690 VOIDmode, EXPAND_NORMAL);
4692 dstb = convert_memory_address (Pmode, dstb);
4693 srcb = convert_memory_address (Pmode, srcb);
4695 /* "Dereference" to BLKmode memories. */
4696 dstb = gen_rtx_MEM (BLKmode, dstb);
4697 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4698 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4699 srcb = gen_rtx_MEM (BLKmode, srcb);
4700 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4701 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4703 /* Copy. */
4704 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4707 return const0_rtx;
4710 /* Expand a call to one of the builtin functions __builtin_frame_address or
4711 __builtin_return_address. */
4713 static rtx
4714 expand_builtin_frame_address (tree fndecl, tree arglist)
4716 /* The argument must be a nonnegative integer constant.
4717 It counts the number of frames to scan up the stack.
4718 The value is the return address saved in that frame. */
4719 if (arglist == 0)
4720 /* Warning about missing arg was already issued. */
4721 return const0_rtx;
4722 else if (! host_integerp (TREE_VALUE (arglist), 1))
4724 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4725 error ("invalid argument to %<__builtin_frame_address%>");
4726 else
4727 error ("invalid argument to %<__builtin_return_address%>");
4728 return const0_rtx;
4730 else
4732 rtx tem
4733 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4734 tree_low_cst (TREE_VALUE (arglist), 1));
4736 /* Some ports cannot access arbitrary stack frames. */
4737 if (tem == NULL)
4739 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4740 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4741 else
4742 warning (0, "unsupported argument to %<__builtin_return_address%>");
4743 return const0_rtx;
4746 /* For __builtin_frame_address, return what we've got. */
4747 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4748 return tem;
4750 if (!REG_P (tem)
4751 && ! CONSTANT_P (tem))
4752 tem = copy_to_mode_reg (Pmode, tem);
4753 return tem;
4757 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4758 we failed and the caller should emit a normal call, otherwise try to get
4759 the result in TARGET, if convenient. */
4761 static rtx
4762 expand_builtin_alloca (tree arglist, rtx target)
4764 rtx op0;
4765 rtx result;
4767 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4768 should always expand to function calls. These can be intercepted
4769 in libmudflap. */
4770 if (flag_mudflap)
4771 return 0;
4773 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4774 return 0;
4776 /* Compute the argument. */
4777 op0 = expand_normal (TREE_VALUE (arglist));
4779 /* Allocate the desired space. */
4780 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4781 result = convert_memory_address (ptr_mode, result);
4783 return result;
4786 /* Expand a call to a bswap builtin. The arguments are in ARGLIST. MODE
4787 is the mode to expand with. */
4789 static rtx
4790 expand_builtin_bswap (tree arglist, rtx target, rtx subtarget)
4792 enum machine_mode mode;
4793 tree arg;
4794 rtx op0;
4796 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4797 return 0;
4799 arg = TREE_VALUE (arglist);
4800 mode = TYPE_MODE (TREE_TYPE (arg));
4801 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4803 target = expand_unop (mode, bswap_optab, op0, target, 1);
4805 gcc_assert (target);
4807 return convert_to_mode (mode, target, 0);
4810 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4811 Return 0 if a normal call should be emitted rather than expanding the
4812 function in-line. If convenient, the result should be placed in TARGET.
4813 SUBTARGET may be used as the target for computing one of EXP's operands. */
4815 static rtx
4816 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4817 rtx subtarget, optab op_optab)
4819 rtx op0;
4820 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4821 return 0;
4823 /* Compute the argument. */
4824 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4825 /* Compute op, into TARGET if possible.
4826 Set TARGET to wherever the result comes back. */
4827 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4828 op_optab, op0, target, 1);
4829 gcc_assert (target);
4831 return convert_to_mode (target_mode, target, 0);
4834 /* If the string passed to fputs is a constant and is one character
4835 long, we attempt to transform this call into __builtin_fputc(). */
4837 static rtx
4838 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4840 /* Verify the arguments in the original call. */
4841 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4843 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4844 unlocked, NULL_TREE);
4845 if (result)
4846 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4848 return 0;
4851 /* Expand a call to __builtin_expect. We just return our argument
4852 as the builtin_expect semantic should've been already executed by
4853 tree branch prediction pass. */
4855 static rtx
4856 expand_builtin_expect (tree arglist, rtx target)
4858 tree exp, c;
4860 if (arglist == NULL_TREE
4861 || TREE_CHAIN (arglist) == NULL_TREE)
4862 return const0_rtx;
4863 exp = TREE_VALUE (arglist);
4864 c = TREE_VALUE (TREE_CHAIN (arglist));
4866 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4867 /* When guessing was done, the hints should be already stripped away. */
4868 gcc_assert (!flag_guess_branch_prob);
4869 return target;
4872 void
4873 expand_builtin_trap (void)
4875 #ifdef HAVE_trap
4876 if (HAVE_trap)
4877 emit_insn (gen_trap ());
4878 else
4879 #endif
4880 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4881 emit_barrier ();
4884 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4885 Return 0 if a normal call should be emitted rather than expanding
4886 the function inline. If convenient, the result should be placed
4887 in TARGET. SUBTARGET may be used as the target for computing
4888 the operand. */
4890 static rtx
4891 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4893 enum machine_mode mode;
4894 tree arg;
4895 rtx op0;
4897 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4898 return 0;
4900 arg = TREE_VALUE (arglist);
4901 mode = TYPE_MODE (TREE_TYPE (arg));
4902 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4903 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4906 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4907 Return NULL is a normal call should be emitted rather than expanding the
4908 function inline. If convenient, the result should be placed in TARGET.
4909 SUBTARGET may be used as the target for computing the operand. */
4911 static rtx
4912 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4914 rtx op0, op1;
4915 tree arg;
4917 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4918 return 0;
4920 arg = TREE_VALUE (arglist);
4921 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4923 arg = TREE_VALUE (TREE_CHAIN (arglist));
4924 op1 = expand_normal (arg);
4926 return expand_copysign (op0, op1, target);
4929 /* Create a new constant string literal and return a char* pointer to it.
4930 The STRING_CST value is the LEN characters at STR. */
4931 tree
4932 build_string_literal (int len, const char *str)
4934 tree t, elem, index, type;
4936 t = build_string (len, str);
4937 elem = build_type_variant (char_type_node, 1, 0);
4938 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4939 type = build_array_type (elem, index);
4940 TREE_TYPE (t) = type;
4941 TREE_CONSTANT (t) = 1;
4942 TREE_INVARIANT (t) = 1;
4943 TREE_READONLY (t) = 1;
4944 TREE_STATIC (t) = 1;
4946 type = build_pointer_type (type);
4947 t = build1 (ADDR_EXPR, type, t);
4949 type = build_pointer_type (elem);
4950 t = build1 (NOP_EXPR, type, t);
4951 return t;
4954 /* Expand EXP, a call to printf or printf_unlocked.
4955 Return 0 if a normal call should be emitted rather than transforming
4956 the function inline. If convenient, the result should be placed in
4957 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4958 call. */
4959 static rtx
4960 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4961 bool unlocked)
4963 tree arglist = TREE_OPERAND (exp, 1);
4964 /* If we're using an unlocked function, assume the other unlocked
4965 functions exist explicitly. */
4966 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4967 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4968 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4969 : implicit_built_in_decls[BUILT_IN_PUTS];
4970 const char *fmt_str;
4971 tree fn, fmt, arg;
4973 /* If the return value is used, don't do the transformation. */
4974 if (target != const0_rtx)
4975 return 0;
4977 /* Verify the required arguments in the original call. */
4978 if (! arglist)
4979 return 0;
4980 fmt = TREE_VALUE (arglist);
4981 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4982 return 0;
4983 arglist = TREE_CHAIN (arglist);
4985 /* Check whether the format is a literal string constant. */
4986 fmt_str = c_getstr (fmt);
4987 if (fmt_str == NULL)
4988 return 0;
4990 if (!init_target_chars())
4991 return 0;
4993 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4994 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4996 if (! arglist
4997 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4998 || TREE_CHAIN (arglist))
4999 return 0;
5000 fn = fn_puts;
5002 /* If the format specifier was "%c", call __builtin_putchar(arg). */
5003 else if (strcmp (fmt_str, target_percent_c) == 0)
5005 if (! arglist
5006 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5007 || TREE_CHAIN (arglist))
5008 return 0;
5009 fn = fn_putchar;
5011 else
5013 /* We can't handle anything else with % args or %% ... yet. */
5014 if (strchr (fmt_str, target_percent))
5015 return 0;
5017 if (arglist)
5018 return 0;
5020 /* If the format specifier was "", printf does nothing. */
5021 if (fmt_str[0] == '\0')
5022 return const0_rtx;
5023 /* If the format specifier has length of 1, call putchar. */
5024 if (fmt_str[1] == '\0')
5026 /* Given printf("c"), (where c is any one character,)
5027 convert "c"[0] to an int and pass that to the replacement
5028 function. */
5029 arg = build_int_cst (NULL_TREE, fmt_str[0]);
5030 arglist = build_tree_list (NULL_TREE, arg);
5031 fn = fn_putchar;
5033 else
5035 /* If the format specifier was "string\n", call puts("string"). */
5036 size_t len = strlen (fmt_str);
5037 if ((unsigned char)fmt_str[len - 1] == target_newline)
5039 /* Create a NUL-terminated string that's one char shorter
5040 than the original, stripping off the trailing '\n'. */
5041 char *newstr = alloca (len);
5042 memcpy (newstr, fmt_str, len - 1);
5043 newstr[len - 1] = 0;
5045 arg = build_string_literal (len, newstr);
5046 arglist = build_tree_list (NULL_TREE, arg);
5047 fn = fn_puts;
5049 else
5050 /* We'd like to arrange to call fputs(string,stdout) here,
5051 but we need stdout and don't have a way to get it yet. */
5052 return 0;
5056 if (!fn)
5057 return 0;
5058 fn = build_function_call_expr (fn, arglist);
5059 if (TREE_CODE (fn) == CALL_EXPR)
5060 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5061 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5064 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5065 Return 0 if a normal call should be emitted rather than transforming
5066 the function inline. If convenient, the result should be placed in
5067 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5068 call. */
5069 static rtx
5070 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5071 bool unlocked)
5073 tree arglist = TREE_OPERAND (exp, 1);
5074 /* If we're using an unlocked function, assume the other unlocked
5075 functions exist explicitly. */
5076 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5077 : implicit_built_in_decls[BUILT_IN_FPUTC];
5078 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5079 : implicit_built_in_decls[BUILT_IN_FPUTS];
5080 const char *fmt_str;
5081 tree fn, fmt, fp, arg;
5083 /* If the return value is used, don't do the transformation. */
5084 if (target != const0_rtx)
5085 return 0;
5087 /* Verify the required arguments in the original call. */
5088 if (! arglist)
5089 return 0;
5090 fp = TREE_VALUE (arglist);
5091 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5092 return 0;
5093 arglist = TREE_CHAIN (arglist);
5094 if (! arglist)
5095 return 0;
5096 fmt = TREE_VALUE (arglist);
5097 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5098 return 0;
5099 arglist = TREE_CHAIN (arglist);
5101 /* Check whether the format is a literal string constant. */
5102 fmt_str = c_getstr (fmt);
5103 if (fmt_str == NULL)
5104 return 0;
5106 if (!init_target_chars())
5107 return 0;
5109 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5110 if (strcmp (fmt_str, target_percent_s) == 0)
5112 if (! arglist
5113 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5114 || TREE_CHAIN (arglist))
5115 return 0;
5116 arg = TREE_VALUE (arglist);
5117 arglist = build_tree_list (NULL_TREE, fp);
5118 arglist = tree_cons (NULL_TREE, arg, arglist);
5119 fn = fn_fputs;
5121 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5122 else if (strcmp (fmt_str, target_percent_c) == 0)
5124 if (! arglist
5125 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5126 || TREE_CHAIN (arglist))
5127 return 0;
5128 arg = TREE_VALUE (arglist);
5129 arglist = build_tree_list (NULL_TREE, fp);
5130 arglist = tree_cons (NULL_TREE, arg, arglist);
5131 fn = fn_fputc;
5133 else
5135 /* We can't handle anything else with % args or %% ... yet. */
5136 if (strchr (fmt_str, target_percent))
5137 return 0;
5139 if (arglist)
5140 return 0;
5142 /* If the format specifier was "", fprintf does nothing. */
5143 if (fmt_str[0] == '\0')
5145 /* Evaluate and ignore FILE* argument for side-effects. */
5146 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5147 return const0_rtx;
5150 /* When "string" doesn't contain %, replace all cases of
5151 fprintf(stream,string) with fputs(string,stream). The fputs
5152 builtin will take care of special cases like length == 1. */
5153 arglist = build_tree_list (NULL_TREE, fp);
5154 arglist = tree_cons (NULL_TREE, fmt, arglist);
5155 fn = fn_fputs;
5158 if (!fn)
5159 return 0;
5160 fn = build_function_call_expr (fn, arglist);
5161 if (TREE_CODE (fn) == CALL_EXPR)
5162 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5163 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5166 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5167 a normal call should be emitted rather than expanding the function
5168 inline. If convenient, the result should be placed in TARGET with
5169 mode MODE. */
5171 static rtx
5172 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5174 tree orig_arglist, dest, fmt;
5175 const char *fmt_str;
5177 orig_arglist = arglist;
5179 /* Verify the required arguments in the original call. */
5180 if (! arglist)
5181 return 0;
5182 dest = TREE_VALUE (arglist);
5183 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5184 return 0;
5185 arglist = TREE_CHAIN (arglist);
5186 if (! arglist)
5187 return 0;
5188 fmt = TREE_VALUE (arglist);
5189 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5190 return 0;
5191 arglist = TREE_CHAIN (arglist);
5193 /* Check whether the format is a literal string constant. */
5194 fmt_str = c_getstr (fmt);
5195 if (fmt_str == NULL)
5196 return 0;
5198 if (!init_target_chars())
5199 return 0;
5201 /* If the format doesn't contain % args or %%, use strcpy. */
5202 if (strchr (fmt_str, target_percent) == 0)
5204 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5205 tree exp;
5207 if (arglist || ! fn)
5208 return 0;
5209 expand_expr (build_function_call_expr (fn, orig_arglist),
5210 const0_rtx, VOIDmode, EXPAND_NORMAL);
5211 if (target == const0_rtx)
5212 return const0_rtx;
5213 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5214 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5216 /* If the format is "%s", use strcpy if the result isn't used. */
5217 else if (strcmp (fmt_str, target_percent_s) == 0)
5219 tree fn, arg, len;
5220 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5222 if (! fn)
5223 return 0;
5225 if (! arglist || TREE_CHAIN (arglist))
5226 return 0;
5227 arg = TREE_VALUE (arglist);
5228 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5229 return 0;
5231 if (target != const0_rtx)
5233 len = c_strlen (arg, 1);
5234 if (! len || TREE_CODE (len) != INTEGER_CST)
5235 return 0;
5237 else
5238 len = NULL_TREE;
5240 arglist = build_tree_list (NULL_TREE, arg);
5241 arglist = tree_cons (NULL_TREE, dest, arglist);
5242 expand_expr (build_function_call_expr (fn, arglist),
5243 const0_rtx, VOIDmode, EXPAND_NORMAL);
5245 if (target == const0_rtx)
5246 return const0_rtx;
5247 return expand_expr (len, target, mode, EXPAND_NORMAL);
5250 return 0;
5253 /* Expand a call to either the entry or exit function profiler. */
5255 static rtx
5256 expand_builtin_profile_func (bool exitp)
5258 rtx this, which;
5260 this = DECL_RTL (current_function_decl);
5261 gcc_assert (MEM_P (this));
5262 this = XEXP (this, 0);
5264 if (exitp)
5265 which = profile_function_exit_libfunc;
5266 else
5267 which = profile_function_entry_libfunc;
5269 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5270 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5272 Pmode);
5274 return const0_rtx;
5277 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5279 static rtx
5280 round_trampoline_addr (rtx tramp)
5282 rtx temp, addend, mask;
5284 /* If we don't need too much alignment, we'll have been guaranteed
5285 proper alignment by get_trampoline_type. */
5286 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5287 return tramp;
5289 /* Round address up to desired boundary. */
5290 temp = gen_reg_rtx (Pmode);
5291 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5292 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5294 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5295 temp, 0, OPTAB_LIB_WIDEN);
5296 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5297 temp, 0, OPTAB_LIB_WIDEN);
5299 return tramp;
5302 static rtx
5303 expand_builtin_init_trampoline (tree arglist)
5305 tree t_tramp, t_func, t_chain;
5306 rtx r_tramp, r_func, r_chain;
5307 #ifdef TRAMPOLINE_TEMPLATE
5308 rtx blktramp;
5309 #endif
5311 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5312 POINTER_TYPE, VOID_TYPE))
5313 return NULL_RTX;
5315 t_tramp = TREE_VALUE (arglist);
5316 arglist = TREE_CHAIN (arglist);
5317 t_func = TREE_VALUE (arglist);
5318 arglist = TREE_CHAIN (arglist);
5319 t_chain = TREE_VALUE (arglist);
5321 r_tramp = expand_normal (t_tramp);
5322 r_func = expand_normal (t_func);
5323 r_chain = expand_normal (t_chain);
5325 /* Generate insns to initialize the trampoline. */
5326 r_tramp = round_trampoline_addr (r_tramp);
5327 #ifdef TRAMPOLINE_TEMPLATE
5328 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5329 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5330 emit_block_move (blktramp, assemble_trampoline_template (),
5331 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5332 #endif
5333 trampolines_created = 1;
5334 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5336 return const0_rtx;
5339 static rtx
5340 expand_builtin_adjust_trampoline (tree arglist)
5342 rtx tramp;
5344 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5345 return NULL_RTX;
5347 tramp = expand_normal (TREE_VALUE (arglist));
5348 tramp = round_trampoline_addr (tramp);
5349 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5350 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5351 #endif
5353 return tramp;
5356 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5357 Return NULL_RTX if a normal call should be emitted rather than expanding
5358 the function in-line. EXP is the expression that is a call to the builtin
5359 function; if convenient, the result should be placed in TARGET. */
5361 static rtx
5362 expand_builtin_signbit (tree exp, rtx target)
5364 const struct real_format *fmt;
5365 enum machine_mode fmode, imode, rmode;
5366 HOST_WIDE_INT hi, lo;
5367 tree arg, arglist;
5368 int word, bitpos;
5369 rtx temp;
5371 arglist = TREE_OPERAND (exp, 1);
5372 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5373 return 0;
5375 arg = TREE_VALUE (arglist);
5376 fmode = TYPE_MODE (TREE_TYPE (arg));
5377 rmode = TYPE_MODE (TREE_TYPE (exp));
5378 fmt = REAL_MODE_FORMAT (fmode);
5380 /* For floating point formats without a sign bit, implement signbit
5381 as "ARG < 0.0". */
5382 bitpos = fmt->signbit_ro;
5383 if (bitpos < 0)
5385 /* But we can't do this if the format supports signed zero. */
5386 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5387 return 0;
5389 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5390 build_real (TREE_TYPE (arg), dconst0));
5391 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5394 temp = expand_normal (arg);
5395 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5397 imode = int_mode_for_mode (fmode);
5398 if (imode == BLKmode)
5399 return 0;
5400 temp = gen_lowpart (imode, temp);
5402 else
5404 imode = word_mode;
5405 /* Handle targets with different FP word orders. */
5406 if (FLOAT_WORDS_BIG_ENDIAN)
5407 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5408 else
5409 word = bitpos / BITS_PER_WORD;
5410 temp = operand_subword_force (temp, word, fmode);
5411 bitpos = bitpos % BITS_PER_WORD;
5414 /* Force the intermediate word_mode (or narrower) result into a
5415 register. This avoids attempting to create paradoxical SUBREGs
5416 of floating point modes below. */
5417 temp = force_reg (imode, temp);
5419 /* If the bitpos is within the "result mode" lowpart, the operation
5420 can be implement with a single bitwise AND. Otherwise, we need
5421 a right shift and an AND. */
5423 if (bitpos < GET_MODE_BITSIZE (rmode))
5425 if (bitpos < HOST_BITS_PER_WIDE_INT)
5427 hi = 0;
5428 lo = (HOST_WIDE_INT) 1 << bitpos;
5430 else
5432 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5433 lo = 0;
5436 if (imode != rmode)
5437 temp = gen_lowpart (rmode, temp);
5438 temp = expand_binop (rmode, and_optab, temp,
5439 immed_double_const (lo, hi, rmode),
5440 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5442 else
5444 /* Perform a logical right shift to place the signbit in the least
5445 significant bit, then truncate the result to the desired mode
5446 and mask just this bit. */
5447 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5448 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5449 temp = gen_lowpart (rmode, temp);
5450 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5451 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5454 return temp;
5457 /* Expand fork or exec calls. TARGET is the desired target of the
5458 call. ARGLIST is the list of arguments of the call. FN is the
5459 identificator of the actual function. IGNORE is nonzero if the
5460 value is to be ignored. */
5462 static rtx
5463 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5465 tree id, decl;
5466 tree call;
5468 /* If we are not profiling, just call the function. */
5469 if (!profile_arc_flag)
5470 return NULL_RTX;
5472 /* Otherwise call the wrapper. This should be equivalent for the rest of
5473 compiler, so the code does not diverge, and the wrapper may run the
5474 code necessary for keeping the profiling sane. */
5476 switch (DECL_FUNCTION_CODE (fn))
5478 case BUILT_IN_FORK:
5479 id = get_identifier ("__gcov_fork");
5480 break;
5482 case BUILT_IN_EXECL:
5483 id = get_identifier ("__gcov_execl");
5484 break;
5486 case BUILT_IN_EXECV:
5487 id = get_identifier ("__gcov_execv");
5488 break;
5490 case BUILT_IN_EXECLP:
5491 id = get_identifier ("__gcov_execlp");
5492 break;
5494 case BUILT_IN_EXECLE:
5495 id = get_identifier ("__gcov_execle");
5496 break;
5498 case BUILT_IN_EXECVP:
5499 id = get_identifier ("__gcov_execvp");
5500 break;
5502 case BUILT_IN_EXECVE:
5503 id = get_identifier ("__gcov_execve");
5504 break;
5506 default:
5507 gcc_unreachable ();
5510 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5511 DECL_EXTERNAL (decl) = 1;
5512 TREE_PUBLIC (decl) = 1;
5513 DECL_ARTIFICIAL (decl) = 1;
5514 TREE_NOTHROW (decl) = 1;
5515 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5516 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5517 call = build_function_call_expr (decl, arglist);
5519 return expand_call (call, target, ignore);
5523 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5524 the pointer in these functions is void*, the tree optimizers may remove
5525 casts. The mode computed in expand_builtin isn't reliable either, due
5526 to __sync_bool_compare_and_swap.
5528 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5529 group of builtins. This gives us log2 of the mode size. */
5531 static inline enum machine_mode
5532 get_builtin_sync_mode (int fcode_diff)
5534 /* The size is not negotiable, so ask not to get BLKmode in return
5535 if the target indicates that a smaller size would be better. */
5536 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5539 /* Expand the memory expression LOC and return the appropriate memory operand
5540 for the builtin_sync operations. */
5542 static rtx
5543 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5545 rtx addr, mem;
5547 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5549 /* Note that we explicitly do not want any alias information for this
5550 memory, so that we kill all other live memories. Otherwise we don't
5551 satisfy the full barrier semantics of the intrinsic. */
5552 mem = validize_mem (gen_rtx_MEM (mode, addr));
5554 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5555 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5556 MEM_VOLATILE_P (mem) = 1;
5558 return mem;
5561 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5562 ARGLIST is the operands list to the function. CODE is the rtx code
5563 that corresponds to the arithmetic or logical operation from the name;
5564 an exception here is that NOT actually means NAND. TARGET is an optional
5565 place for us to store the results; AFTER is true if this is the
5566 fetch_and_xxx form. IGNORE is true if we don't actually care about
5567 the result of the operation at all. */
5569 static rtx
5570 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5571 enum rtx_code code, bool after,
5572 rtx target, bool ignore)
5574 rtx val, mem;
5576 /* Expand the operands. */
5577 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5579 arglist = TREE_CHAIN (arglist);
5580 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5581 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5582 val = convert_to_mode (mode, val, 1);
5584 if (ignore)
5585 return expand_sync_operation (mem, val, code);
5586 else
5587 return expand_sync_fetch_operation (mem, val, code, after, target);
5590 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5591 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5592 true if this is the boolean form. TARGET is a place for us to store the
5593 results; this is NOT optional if IS_BOOL is true. */
5595 static rtx
5596 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5597 bool is_bool, rtx target)
5599 rtx old_val, new_val, mem;
5601 /* Expand the operands. */
5602 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5604 arglist = TREE_CHAIN (arglist);
5605 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5606 /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */
5607 old_val = convert_to_mode (mode, old_val, 1);
5609 arglist = TREE_CHAIN (arglist);
5610 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5611 /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */
5612 new_val = convert_to_mode (mode, new_val, 1);
5614 if (is_bool)
5615 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5616 else
5617 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5620 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5621 general form is actually an atomic exchange, and some targets only
5622 support a reduced form with the second argument being a constant 1.
5623 ARGLIST is the operands list to the function; TARGET is an optional
5624 place for us to store the results. */
5626 static rtx
5627 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5628 rtx target)
5630 rtx val, mem;
5632 /* Expand the operands. */
5633 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5635 arglist = TREE_CHAIN (arglist);
5636 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5637 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5638 val = convert_to_mode (mode, val, 1);
5640 return expand_sync_lock_test_and_set (mem, val, target);
5643 /* Expand the __sync_synchronize intrinsic. */
5645 static void
5646 expand_builtin_synchronize (void)
5648 tree x;
5650 #ifdef HAVE_memory_barrier
5651 if (HAVE_memory_barrier)
5653 emit_insn (gen_memory_barrier ());
5654 return;
5656 #endif
5658 /* If no explicit memory barrier instruction is available, create an
5659 empty asm stmt with a memory clobber. */
5660 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5661 tree_cons (NULL, build_string (6, "memory"), NULL));
5662 ASM_VOLATILE_P (x) = 1;
5663 expand_asm_expr (x);
5666 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5667 to the function. */
5669 static void
5670 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5672 enum insn_code icode;
5673 rtx mem, insn;
5674 rtx val = const0_rtx;
5676 /* Expand the operands. */
5677 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5679 /* If there is an explicit operation in the md file, use it. */
5680 icode = sync_lock_release[mode];
5681 if (icode != CODE_FOR_nothing)
5683 if (!insn_data[icode].operand[1].predicate (val, mode))
5684 val = force_reg (mode, val);
5686 insn = GEN_FCN (icode) (mem, val);
5687 if (insn)
5689 emit_insn (insn);
5690 return;
5694 /* Otherwise we can implement this operation by emitting a barrier
5695 followed by a store of zero. */
5696 expand_builtin_synchronize ();
5697 emit_move_insn (mem, val);
5700 /* Expand an expression EXP that calls a built-in function,
5701 with result going to TARGET if that's convenient
5702 (and in mode MODE if that's convenient).
5703 SUBTARGET may be used as the target for computing one of EXP's operands.
5704 IGNORE is nonzero if the value is to be ignored. */
5707 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5708 int ignore)
5710 tree fndecl = get_callee_fndecl (exp);
5711 tree arglist = TREE_OPERAND (exp, 1);
5712 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5713 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5715 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5716 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5718 /* When not optimizing, generate calls to library functions for a certain
5719 set of builtins. */
5720 if (!optimize
5721 && !called_as_built_in (fndecl)
5722 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5723 && fcode != BUILT_IN_ALLOCA)
5724 return expand_call (exp, target, ignore);
5726 /* The built-in function expanders test for target == const0_rtx
5727 to determine whether the function's result will be ignored. */
5728 if (ignore)
5729 target = const0_rtx;
5731 /* If the result of a pure or const built-in function is ignored, and
5732 none of its arguments are volatile, we can avoid expanding the
5733 built-in call and just evaluate the arguments for side-effects. */
5734 if (target == const0_rtx
5735 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5737 bool volatilep = false;
5738 tree arg;
5740 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5741 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5743 volatilep = true;
5744 break;
5747 if (! volatilep)
5749 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5750 expand_expr (TREE_VALUE (arg), const0_rtx,
5751 VOIDmode, EXPAND_NORMAL);
5752 return const0_rtx;
5756 switch (fcode)
5758 CASE_FLT_FN (BUILT_IN_FABS):
5759 target = expand_builtin_fabs (arglist, target, subtarget);
5760 if (target)
5761 return target;
5762 break;
5764 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5765 target = expand_builtin_copysign (arglist, target, subtarget);
5766 if (target)
5767 return target;
5768 break;
5770 /* Just do a normal library call if we were unable to fold
5771 the values. */
5772 CASE_FLT_FN (BUILT_IN_CABS):
5773 break;
5775 CASE_FLT_FN (BUILT_IN_EXP):
5776 CASE_FLT_FN (BUILT_IN_EXP10):
5777 CASE_FLT_FN (BUILT_IN_POW10):
5778 CASE_FLT_FN (BUILT_IN_EXP2):
5779 CASE_FLT_FN (BUILT_IN_EXPM1):
5780 CASE_FLT_FN (BUILT_IN_LOGB):
5781 CASE_FLT_FN (BUILT_IN_ILOGB):
5782 CASE_FLT_FN (BUILT_IN_LOG):
5783 CASE_FLT_FN (BUILT_IN_LOG10):
5784 CASE_FLT_FN (BUILT_IN_LOG2):
5785 CASE_FLT_FN (BUILT_IN_LOG1P):
5786 CASE_FLT_FN (BUILT_IN_TAN):
5787 CASE_FLT_FN (BUILT_IN_ASIN):
5788 CASE_FLT_FN (BUILT_IN_ACOS):
5789 CASE_FLT_FN (BUILT_IN_ATAN):
5790 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5791 because of possible accuracy problems. */
5792 if (! flag_unsafe_math_optimizations)
5793 break;
5794 CASE_FLT_FN (BUILT_IN_SQRT):
5795 CASE_FLT_FN (BUILT_IN_FLOOR):
5796 CASE_FLT_FN (BUILT_IN_CEIL):
5797 CASE_FLT_FN (BUILT_IN_TRUNC):
5798 CASE_FLT_FN (BUILT_IN_ROUND):
5799 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5800 CASE_FLT_FN (BUILT_IN_RINT):
5801 target = expand_builtin_mathfn (exp, target, subtarget);
5802 if (target)
5803 return target;
5804 break;
5806 CASE_FLT_FN (BUILT_IN_LCEIL):
5807 CASE_FLT_FN (BUILT_IN_LLCEIL):
5808 CASE_FLT_FN (BUILT_IN_LFLOOR):
5809 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5810 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5811 if (target)
5812 return target;
5813 break;
5815 CASE_FLT_FN (BUILT_IN_LRINT):
5816 CASE_FLT_FN (BUILT_IN_LLRINT):
5817 CASE_FLT_FN (BUILT_IN_LROUND):
5818 CASE_FLT_FN (BUILT_IN_LLROUND):
5819 target = expand_builtin_int_roundingfn_2 (exp, target, subtarget);
5820 if (target)
5821 return target;
5822 break;
5824 CASE_FLT_FN (BUILT_IN_POW):
5825 target = expand_builtin_pow (exp, target, subtarget);
5826 if (target)
5827 return target;
5828 break;
5830 CASE_FLT_FN (BUILT_IN_POWI):
5831 target = expand_builtin_powi (exp, target, subtarget);
5832 if (target)
5833 return target;
5834 break;
5836 CASE_FLT_FN (BUILT_IN_ATAN2):
5837 CASE_FLT_FN (BUILT_IN_LDEXP):
5838 if (! flag_unsafe_math_optimizations)
5839 break;
5841 CASE_FLT_FN (BUILT_IN_FMOD):
5842 CASE_FLT_FN (BUILT_IN_REMAINDER):
5843 CASE_FLT_FN (BUILT_IN_DREM):
5844 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5845 if (target)
5846 return target;
5847 break;
5849 CASE_FLT_FN (BUILT_IN_CEXPI):
5850 target = expand_builtin_cexpi (exp, target, subtarget);
5851 gcc_assert (target);
5852 return target;
5854 CASE_FLT_FN (BUILT_IN_SIN):
5855 CASE_FLT_FN (BUILT_IN_COS):
5856 if (! flag_unsafe_math_optimizations)
5857 break;
5858 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5859 if (target)
5860 return target;
5861 break;
5863 CASE_FLT_FN (BUILT_IN_SINCOS):
5864 if (! flag_unsafe_math_optimizations)
5865 break;
5866 target = expand_builtin_sincos (exp);
5867 if (target)
5868 return target;
5869 break;
5871 case BUILT_IN_APPLY_ARGS:
5872 return expand_builtin_apply_args ();
5874 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5875 FUNCTION with a copy of the parameters described by
5876 ARGUMENTS, and ARGSIZE. It returns a block of memory
5877 allocated on the stack into which is stored all the registers
5878 that might possibly be used for returning the result of a
5879 function. ARGUMENTS is the value returned by
5880 __builtin_apply_args. ARGSIZE is the number of bytes of
5881 arguments that must be copied. ??? How should this value be
5882 computed? We'll also need a safe worst case value for varargs
5883 functions. */
5884 case BUILT_IN_APPLY:
5885 if (!validate_arglist (arglist, POINTER_TYPE,
5886 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5887 && !validate_arglist (arglist, REFERENCE_TYPE,
5888 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5889 return const0_rtx;
5890 else
5892 int i;
5893 tree t;
5894 rtx ops[3];
5896 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5897 ops[i] = expand_normal (TREE_VALUE (t));
5899 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5902 /* __builtin_return (RESULT) causes the function to return the
5903 value described by RESULT. RESULT is address of the block of
5904 memory returned by __builtin_apply. */
5905 case BUILT_IN_RETURN:
5906 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5907 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5908 return const0_rtx;
5910 case BUILT_IN_SAVEREGS:
5911 return expand_builtin_saveregs ();
5913 case BUILT_IN_ARGS_INFO:
5914 return expand_builtin_args_info (arglist);
5916 /* Return the address of the first anonymous stack arg. */
5917 case BUILT_IN_NEXT_ARG:
5918 if (fold_builtin_next_arg (arglist))
5919 return const0_rtx;
5920 return expand_builtin_next_arg ();
5922 case BUILT_IN_CLASSIFY_TYPE:
5923 return expand_builtin_classify_type (arglist);
5925 case BUILT_IN_CONSTANT_P:
5926 return const0_rtx;
5928 case BUILT_IN_FRAME_ADDRESS:
5929 case BUILT_IN_RETURN_ADDRESS:
5930 return expand_builtin_frame_address (fndecl, arglist);
5932 /* Returns the address of the area where the structure is returned.
5933 0 otherwise. */
5934 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5935 if (arglist != 0
5936 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5937 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5938 return const0_rtx;
5939 else
5940 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5942 case BUILT_IN_ALLOCA:
5943 target = expand_builtin_alloca (arglist, target);
5944 if (target)
5945 return target;
5946 break;
5948 case BUILT_IN_STACK_SAVE:
5949 return expand_stack_save ();
5951 case BUILT_IN_STACK_RESTORE:
5952 expand_stack_restore (TREE_VALUE (arglist));
5953 return const0_rtx;
5955 case BUILT_IN_BSWAP32:
5956 case BUILT_IN_BSWAP64:
5957 target = expand_builtin_bswap (arglist, target, subtarget);
5959 if (target)
5960 return target;
5961 break;
5963 CASE_INT_FN (BUILT_IN_FFS):
5964 case BUILT_IN_FFSIMAX:
5965 target = expand_builtin_unop (target_mode, arglist, target,
5966 subtarget, ffs_optab);
5967 if (target)
5968 return target;
5969 break;
5971 CASE_INT_FN (BUILT_IN_CLZ):
5972 case BUILT_IN_CLZIMAX:
5973 target = expand_builtin_unop (target_mode, arglist, target,
5974 subtarget, clz_optab);
5975 if (target)
5976 return target;
5977 break;
5979 CASE_INT_FN (BUILT_IN_CTZ):
5980 case BUILT_IN_CTZIMAX:
5981 target = expand_builtin_unop (target_mode, arglist, target,
5982 subtarget, ctz_optab);
5983 if (target)
5984 return target;
5985 break;
5987 CASE_INT_FN (BUILT_IN_POPCOUNT):
5988 case BUILT_IN_POPCOUNTIMAX:
5989 target = expand_builtin_unop (target_mode, arglist, target,
5990 subtarget, popcount_optab);
5991 if (target)
5992 return target;
5993 break;
5995 CASE_INT_FN (BUILT_IN_PARITY):
5996 case BUILT_IN_PARITYIMAX:
5997 target = expand_builtin_unop (target_mode, arglist, target,
5998 subtarget, parity_optab);
5999 if (target)
6000 return target;
6001 break;
6003 case BUILT_IN_STRLEN:
6004 target = expand_builtin_strlen (arglist, target, target_mode);
6005 if (target)
6006 return target;
6007 break;
6009 case BUILT_IN_STRCPY:
6010 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
6011 if (target)
6012 return target;
6013 break;
6015 case BUILT_IN_STRNCPY:
6016 target = expand_builtin_strncpy (exp, target, mode);
6017 if (target)
6018 return target;
6019 break;
6021 case BUILT_IN_STPCPY:
6022 target = expand_builtin_stpcpy (exp, target, mode);
6023 if (target)
6024 return target;
6025 break;
6027 case BUILT_IN_STRCAT:
6028 target = expand_builtin_strcat (fndecl, arglist, target, mode);
6029 if (target)
6030 return target;
6031 break;
6033 case BUILT_IN_STRNCAT:
6034 target = expand_builtin_strncat (arglist, target, mode);
6035 if (target)
6036 return target;
6037 break;
6039 case BUILT_IN_STRSPN:
6040 target = expand_builtin_strspn (arglist, target, mode);
6041 if (target)
6042 return target;
6043 break;
6045 case BUILT_IN_STRCSPN:
6046 target = expand_builtin_strcspn (arglist, target, mode);
6047 if (target)
6048 return target;
6049 break;
6051 case BUILT_IN_STRSTR:
6052 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
6053 if (target)
6054 return target;
6055 break;
6057 case BUILT_IN_STRPBRK:
6058 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
6059 if (target)
6060 return target;
6061 break;
6063 case BUILT_IN_INDEX:
6064 case BUILT_IN_STRCHR:
6065 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
6066 if (target)
6067 return target;
6068 break;
6070 case BUILT_IN_RINDEX:
6071 case BUILT_IN_STRRCHR:
6072 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
6073 if (target)
6074 return target;
6075 break;
6077 case BUILT_IN_MEMCPY:
6078 target = expand_builtin_memcpy (exp, target, mode);
6079 if (target)
6080 return target;
6081 break;
6083 case BUILT_IN_MEMPCPY:
6084 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6085 if (target)
6086 return target;
6087 break;
6089 case BUILT_IN_MEMMOVE:
6090 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6091 mode);
6092 if (target)
6093 return target;
6094 break;
6096 case BUILT_IN_BCOPY:
6097 target = expand_builtin_bcopy (exp);
6098 if (target)
6099 return target;
6100 break;
6102 case BUILT_IN_MEMSET:
6103 target = expand_builtin_memset (arglist, target, mode, exp);
6104 if (target)
6105 return target;
6106 break;
6108 case BUILT_IN_BZERO:
6109 target = expand_builtin_bzero (exp);
6110 if (target)
6111 return target;
6112 break;
6114 case BUILT_IN_STRCMP:
6115 target = expand_builtin_strcmp (exp, target, mode);
6116 if (target)
6117 return target;
6118 break;
6120 case BUILT_IN_STRNCMP:
6121 target = expand_builtin_strncmp (exp, target, mode);
6122 if (target)
6123 return target;
6124 break;
6126 case BUILT_IN_BCMP:
6127 case BUILT_IN_MEMCMP:
6128 target = expand_builtin_memcmp (exp, arglist, target, mode);
6129 if (target)
6130 return target;
6131 break;
6133 case BUILT_IN_SETJMP:
6134 /* This should have been lowered to the builtins below. */
6135 gcc_unreachable ();
6137 case BUILT_IN_SETJMP_SETUP:
6138 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6139 and the receiver label. */
6140 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6142 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6143 VOIDmode, EXPAND_NORMAL);
6144 tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
6145 rtx label_r = label_rtx (label);
6147 /* This is copied from the handling of non-local gotos. */
6148 expand_builtin_setjmp_setup (buf_addr, label_r);
6149 nonlocal_goto_handler_labels
6150 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6151 nonlocal_goto_handler_labels);
6152 /* ??? Do not let expand_label treat us as such since we would
6153 not want to be both on the list of non-local labels and on
6154 the list of forced labels. */
6155 FORCED_LABEL (label) = 0;
6156 return const0_rtx;
6158 break;
6160 case BUILT_IN_SETJMP_DISPATCHER:
6161 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6162 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6164 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6165 rtx label_r = label_rtx (label);
6167 /* Remove the dispatcher label from the list of non-local labels
6168 since the receiver labels have been added to it above. */
6169 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6170 return const0_rtx;
6172 break;
6174 case BUILT_IN_SETJMP_RECEIVER:
6175 /* __builtin_setjmp_receiver is passed the receiver label. */
6176 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6178 tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6179 rtx label_r = label_rtx (label);
6181 expand_builtin_setjmp_receiver (label_r);
6182 return const0_rtx;
6184 break;
6186 /* __builtin_longjmp is passed a pointer to an array of five words.
6187 It's similar to the C library longjmp function but works with
6188 __builtin_setjmp above. */
6189 case BUILT_IN_LONGJMP:
6190 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6192 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6193 VOIDmode, EXPAND_NORMAL);
6194 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6196 if (value != const1_rtx)
6198 error ("%<__builtin_longjmp%> second argument must be 1");
6199 return const0_rtx;
6202 expand_builtin_longjmp (buf_addr, value);
6203 return const0_rtx;
6205 break;
6207 case BUILT_IN_NONLOCAL_GOTO:
6208 target = expand_builtin_nonlocal_goto (arglist);
6209 if (target)
6210 return target;
6211 break;
6213 /* This updates the setjmp buffer that is its argument with the value
6214 of the current stack pointer. */
6215 case BUILT_IN_UPDATE_SETJMP_BUF:
6216 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6218 rtx buf_addr
6219 = expand_normal (TREE_VALUE (arglist));
6221 expand_builtin_update_setjmp_buf (buf_addr);
6222 return const0_rtx;
6224 break;
6226 case BUILT_IN_TRAP:
6227 expand_builtin_trap ();
6228 return const0_rtx;
6230 case BUILT_IN_PRINTF:
6231 target = expand_builtin_printf (exp, target, mode, false);
6232 if (target)
6233 return target;
6234 break;
6236 case BUILT_IN_PRINTF_UNLOCKED:
6237 target = expand_builtin_printf (exp, target, mode, true);
6238 if (target)
6239 return target;
6240 break;
6242 case BUILT_IN_FPUTS:
6243 target = expand_builtin_fputs (arglist, target, false);
6244 if (target)
6245 return target;
6246 break;
6247 case BUILT_IN_FPUTS_UNLOCKED:
6248 target = expand_builtin_fputs (arglist, target, true);
6249 if (target)
6250 return target;
6251 break;
6253 case BUILT_IN_FPRINTF:
6254 target = expand_builtin_fprintf (exp, target, mode, false);
6255 if (target)
6256 return target;
6257 break;
6259 case BUILT_IN_FPRINTF_UNLOCKED:
6260 target = expand_builtin_fprintf (exp, target, mode, true);
6261 if (target)
6262 return target;
6263 break;
6265 case BUILT_IN_SPRINTF:
6266 target = expand_builtin_sprintf (arglist, target, mode);
6267 if (target)
6268 return target;
6269 break;
6271 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6272 target = expand_builtin_signbit (exp, target);
6273 if (target)
6274 return target;
6275 break;
6277 /* Various hooks for the DWARF 2 __throw routine. */
6278 case BUILT_IN_UNWIND_INIT:
6279 expand_builtin_unwind_init ();
6280 return const0_rtx;
6281 case BUILT_IN_DWARF_CFA:
6282 return virtual_cfa_rtx;
6283 #ifdef DWARF2_UNWIND_INFO
6284 case BUILT_IN_DWARF_SP_COLUMN:
6285 return expand_builtin_dwarf_sp_column ();
6286 case BUILT_IN_INIT_DWARF_REG_SIZES:
6287 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6288 return const0_rtx;
6289 #endif
6290 case BUILT_IN_FROB_RETURN_ADDR:
6291 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6292 case BUILT_IN_EXTRACT_RETURN_ADDR:
6293 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6294 case BUILT_IN_EH_RETURN:
6295 expand_builtin_eh_return (TREE_VALUE (arglist),
6296 TREE_VALUE (TREE_CHAIN (arglist)));
6297 return const0_rtx;
6298 #ifdef EH_RETURN_DATA_REGNO
6299 case BUILT_IN_EH_RETURN_DATA_REGNO:
6300 return expand_builtin_eh_return_data_regno (arglist);
6301 #endif
6302 case BUILT_IN_EXTEND_POINTER:
6303 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6305 case BUILT_IN_VA_START:
6306 case BUILT_IN_STDARG_START:
6307 return expand_builtin_va_start (arglist);
6308 case BUILT_IN_VA_END:
6309 return expand_builtin_va_end (arglist);
6310 case BUILT_IN_VA_COPY:
6311 return expand_builtin_va_copy (arglist);
6312 case BUILT_IN_EXPECT:
6313 return expand_builtin_expect (arglist, target);
6314 case BUILT_IN_PREFETCH:
6315 expand_builtin_prefetch (arglist);
6316 return const0_rtx;
6318 case BUILT_IN_PROFILE_FUNC_ENTER:
6319 return expand_builtin_profile_func (false);
6320 case BUILT_IN_PROFILE_FUNC_EXIT:
6321 return expand_builtin_profile_func (true);
6323 case BUILT_IN_INIT_TRAMPOLINE:
6324 return expand_builtin_init_trampoline (arglist);
6325 case BUILT_IN_ADJUST_TRAMPOLINE:
6326 return expand_builtin_adjust_trampoline (arglist);
6328 case BUILT_IN_FORK:
6329 case BUILT_IN_EXECL:
6330 case BUILT_IN_EXECV:
6331 case BUILT_IN_EXECLP:
6332 case BUILT_IN_EXECLE:
6333 case BUILT_IN_EXECVP:
6334 case BUILT_IN_EXECVE:
6335 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6336 if (target)
6337 return target;
6338 break;
6340 case BUILT_IN_FETCH_AND_ADD_1:
6341 case BUILT_IN_FETCH_AND_ADD_2:
6342 case BUILT_IN_FETCH_AND_ADD_4:
6343 case BUILT_IN_FETCH_AND_ADD_8:
6344 case BUILT_IN_FETCH_AND_ADD_16:
6345 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6346 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6347 false, target, ignore);
6348 if (target)
6349 return target;
6350 break;
6352 case BUILT_IN_FETCH_AND_SUB_1:
6353 case BUILT_IN_FETCH_AND_SUB_2:
6354 case BUILT_IN_FETCH_AND_SUB_4:
6355 case BUILT_IN_FETCH_AND_SUB_8:
6356 case BUILT_IN_FETCH_AND_SUB_16:
6357 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6358 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6359 false, target, ignore);
6360 if (target)
6361 return target;
6362 break;
6364 case BUILT_IN_FETCH_AND_OR_1:
6365 case BUILT_IN_FETCH_AND_OR_2:
6366 case BUILT_IN_FETCH_AND_OR_4:
6367 case BUILT_IN_FETCH_AND_OR_8:
6368 case BUILT_IN_FETCH_AND_OR_16:
6369 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6370 target = expand_builtin_sync_operation (mode, arglist, IOR,
6371 false, target, ignore);
6372 if (target)
6373 return target;
6374 break;
6376 case BUILT_IN_FETCH_AND_AND_1:
6377 case BUILT_IN_FETCH_AND_AND_2:
6378 case BUILT_IN_FETCH_AND_AND_4:
6379 case BUILT_IN_FETCH_AND_AND_8:
6380 case BUILT_IN_FETCH_AND_AND_16:
6381 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6382 target = expand_builtin_sync_operation (mode, arglist, AND,
6383 false, target, ignore);
6384 if (target)
6385 return target;
6386 break;
6388 case BUILT_IN_FETCH_AND_XOR_1:
6389 case BUILT_IN_FETCH_AND_XOR_2:
6390 case BUILT_IN_FETCH_AND_XOR_4:
6391 case BUILT_IN_FETCH_AND_XOR_8:
6392 case BUILT_IN_FETCH_AND_XOR_16:
6393 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6394 target = expand_builtin_sync_operation (mode, arglist, XOR,
6395 false, target, ignore);
6396 if (target)
6397 return target;
6398 break;
6400 case BUILT_IN_FETCH_AND_NAND_1:
6401 case BUILT_IN_FETCH_AND_NAND_2:
6402 case BUILT_IN_FETCH_AND_NAND_4:
6403 case BUILT_IN_FETCH_AND_NAND_8:
6404 case BUILT_IN_FETCH_AND_NAND_16:
6405 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6406 target = expand_builtin_sync_operation (mode, arglist, NOT,
6407 false, target, ignore);
6408 if (target)
6409 return target;
6410 break;
6412 case BUILT_IN_ADD_AND_FETCH_1:
6413 case BUILT_IN_ADD_AND_FETCH_2:
6414 case BUILT_IN_ADD_AND_FETCH_4:
6415 case BUILT_IN_ADD_AND_FETCH_8:
6416 case BUILT_IN_ADD_AND_FETCH_16:
6417 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6418 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6419 true, target, ignore);
6420 if (target)
6421 return target;
6422 break;
6424 case BUILT_IN_SUB_AND_FETCH_1:
6425 case BUILT_IN_SUB_AND_FETCH_2:
6426 case BUILT_IN_SUB_AND_FETCH_4:
6427 case BUILT_IN_SUB_AND_FETCH_8:
6428 case BUILT_IN_SUB_AND_FETCH_16:
6429 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6430 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6431 true, target, ignore);
6432 if (target)
6433 return target;
6434 break;
6436 case BUILT_IN_OR_AND_FETCH_1:
6437 case BUILT_IN_OR_AND_FETCH_2:
6438 case BUILT_IN_OR_AND_FETCH_4:
6439 case BUILT_IN_OR_AND_FETCH_8:
6440 case BUILT_IN_OR_AND_FETCH_16:
6441 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6442 target = expand_builtin_sync_operation (mode, arglist, IOR,
6443 true, target, ignore);
6444 if (target)
6445 return target;
6446 break;
6448 case BUILT_IN_AND_AND_FETCH_1:
6449 case BUILT_IN_AND_AND_FETCH_2:
6450 case BUILT_IN_AND_AND_FETCH_4:
6451 case BUILT_IN_AND_AND_FETCH_8:
6452 case BUILT_IN_AND_AND_FETCH_16:
6453 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6454 target = expand_builtin_sync_operation (mode, arglist, AND,
6455 true, target, ignore);
6456 if (target)
6457 return target;
6458 break;
6460 case BUILT_IN_XOR_AND_FETCH_1:
6461 case BUILT_IN_XOR_AND_FETCH_2:
6462 case BUILT_IN_XOR_AND_FETCH_4:
6463 case BUILT_IN_XOR_AND_FETCH_8:
6464 case BUILT_IN_XOR_AND_FETCH_16:
6465 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6466 target = expand_builtin_sync_operation (mode, arglist, XOR,
6467 true, target, ignore);
6468 if (target)
6469 return target;
6470 break;
6472 case BUILT_IN_NAND_AND_FETCH_1:
6473 case BUILT_IN_NAND_AND_FETCH_2:
6474 case BUILT_IN_NAND_AND_FETCH_4:
6475 case BUILT_IN_NAND_AND_FETCH_8:
6476 case BUILT_IN_NAND_AND_FETCH_16:
6477 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6478 target = expand_builtin_sync_operation (mode, arglist, NOT,
6479 true, target, ignore);
6480 if (target)
6481 return target;
6482 break;
6484 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6485 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6486 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6487 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6488 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6489 if (mode == VOIDmode)
6490 mode = TYPE_MODE (boolean_type_node);
6491 if (!target || !register_operand (target, mode))
6492 target = gen_reg_rtx (mode);
6494 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6495 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6496 if (target)
6497 return target;
6498 break;
6500 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6501 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6502 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6503 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6504 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6505 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6506 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6507 if (target)
6508 return target;
6509 break;
6511 case BUILT_IN_LOCK_TEST_AND_SET_1:
6512 case BUILT_IN_LOCK_TEST_AND_SET_2:
6513 case BUILT_IN_LOCK_TEST_AND_SET_4:
6514 case BUILT_IN_LOCK_TEST_AND_SET_8:
6515 case BUILT_IN_LOCK_TEST_AND_SET_16:
6516 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6517 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6518 if (target)
6519 return target;
6520 break;
6522 case BUILT_IN_LOCK_RELEASE_1:
6523 case BUILT_IN_LOCK_RELEASE_2:
6524 case BUILT_IN_LOCK_RELEASE_4:
6525 case BUILT_IN_LOCK_RELEASE_8:
6526 case BUILT_IN_LOCK_RELEASE_16:
6527 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6528 expand_builtin_lock_release (mode, arglist);
6529 return const0_rtx;
6531 case BUILT_IN_SYNCHRONIZE:
6532 expand_builtin_synchronize ();
6533 return const0_rtx;
6535 case BUILT_IN_OBJECT_SIZE:
6536 return expand_builtin_object_size (exp);
6538 case BUILT_IN_MEMCPY_CHK:
6539 case BUILT_IN_MEMPCPY_CHK:
6540 case BUILT_IN_MEMMOVE_CHK:
6541 case BUILT_IN_MEMSET_CHK:
6542 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6543 if (target)
6544 return target;
6545 break;
6547 case BUILT_IN_STRCPY_CHK:
6548 case BUILT_IN_STPCPY_CHK:
6549 case BUILT_IN_STRNCPY_CHK:
6550 case BUILT_IN_STRCAT_CHK:
6551 case BUILT_IN_STRNCAT_CHK:
6552 case BUILT_IN_SNPRINTF_CHK:
6553 case BUILT_IN_VSNPRINTF_CHK:
6554 maybe_emit_chk_warning (exp, fcode);
6555 break;
6557 case BUILT_IN_SPRINTF_CHK:
6558 case BUILT_IN_VSPRINTF_CHK:
6559 maybe_emit_sprintf_chk_warning (exp, fcode);
6560 break;
6562 default: /* just do library call, if unknown builtin */
6563 break;
6566 /* The switch statement above can drop through to cause the function
6567 to be called normally. */
6568 return expand_call (exp, target, ignore);
6571 /* Determine whether a tree node represents a call to a built-in
6572 function. If the tree T is a call to a built-in function with
6573 the right number of arguments of the appropriate types, return
6574 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6575 Otherwise the return value is END_BUILTINS. */
6577 enum built_in_function
6578 builtin_mathfn_code (tree t)
6580 tree fndecl, arglist, parmlist;
6581 tree argtype, parmtype;
6583 if (TREE_CODE (t) != CALL_EXPR
6584 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6585 return END_BUILTINS;
6587 fndecl = get_callee_fndecl (t);
6588 if (fndecl == NULL_TREE
6589 || TREE_CODE (fndecl) != FUNCTION_DECL
6590 || ! DECL_BUILT_IN (fndecl)
6591 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6592 return END_BUILTINS;
6594 arglist = TREE_OPERAND (t, 1);
6595 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6596 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6598 /* If a function doesn't take a variable number of arguments,
6599 the last element in the list will have type `void'. */
6600 parmtype = TREE_VALUE (parmlist);
6601 if (VOID_TYPE_P (parmtype))
6603 if (arglist)
6604 return END_BUILTINS;
6605 return DECL_FUNCTION_CODE (fndecl);
6608 if (! arglist)
6609 return END_BUILTINS;
6611 argtype = TREE_TYPE (TREE_VALUE (arglist));
6613 if (SCALAR_FLOAT_TYPE_P (parmtype))
6615 if (! SCALAR_FLOAT_TYPE_P (argtype))
6616 return END_BUILTINS;
6618 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6620 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6621 return END_BUILTINS;
6623 else if (POINTER_TYPE_P (parmtype))
6625 if (! POINTER_TYPE_P (argtype))
6626 return END_BUILTINS;
6628 else if (INTEGRAL_TYPE_P (parmtype))
6630 if (! INTEGRAL_TYPE_P (argtype))
6631 return END_BUILTINS;
6633 else
6634 return END_BUILTINS;
6636 arglist = TREE_CHAIN (arglist);
6639 /* Variable-length argument list. */
6640 return DECL_FUNCTION_CODE (fndecl);
6643 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6644 constant. ARGLIST is the argument list of the call. */
6646 static tree
6647 fold_builtin_constant_p (tree arglist)
6649 if (arglist == 0)
6650 return 0;
6652 arglist = TREE_VALUE (arglist);
6654 /* We return 1 for a numeric type that's known to be a constant
6655 value at compile-time or for an aggregate type that's a
6656 literal constant. */
6657 STRIP_NOPS (arglist);
6659 /* If we know this is a constant, emit the constant of one. */
6660 if (CONSTANT_CLASS_P (arglist)
6661 || (TREE_CODE (arglist) == CONSTRUCTOR
6662 && TREE_CONSTANT (arglist)))
6663 return integer_one_node;
6664 if (TREE_CODE (arglist) == ADDR_EXPR)
6666 tree op = TREE_OPERAND (arglist, 0);
6667 if (TREE_CODE (op) == STRING_CST
6668 || (TREE_CODE (op) == ARRAY_REF
6669 && integer_zerop (TREE_OPERAND (op, 1))
6670 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6671 return integer_one_node;
6674 /* If this expression has side effects, show we don't know it to be a
6675 constant. Likewise if it's a pointer or aggregate type since in
6676 those case we only want literals, since those are only optimized
6677 when generating RTL, not later.
6678 And finally, if we are compiling an initializer, not code, we
6679 need to return a definite result now; there's not going to be any
6680 more optimization done. */
6681 if (TREE_SIDE_EFFECTS (arglist)
6682 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6683 || POINTER_TYPE_P (TREE_TYPE (arglist))
6684 || cfun == 0
6685 || folding_initializer)
6686 return integer_zero_node;
6688 return 0;
6691 /* Fold a call to __builtin_expect, if we expect that a comparison against
6692 the argument will fold to a constant. In practice, this means a true
6693 constant or the address of a non-weak symbol. ARGLIST is the argument
6694 list of the call. */
6696 static tree
6697 fold_builtin_expect (tree arglist)
6699 tree arg, inner;
6701 if (arglist == 0)
6702 return 0;
6704 arg = TREE_VALUE (arglist);
6706 /* If the argument isn't invariant, then there's nothing we can do. */
6707 if (!TREE_INVARIANT (arg))
6708 return 0;
6710 /* If we're looking at an address of a weak decl, then do not fold. */
6711 inner = arg;
6712 STRIP_NOPS (inner);
6713 if (TREE_CODE (inner) == ADDR_EXPR)
6717 inner = TREE_OPERAND (inner, 0);
6719 while (TREE_CODE (inner) == COMPONENT_REF
6720 || TREE_CODE (inner) == ARRAY_REF);
6721 if (DECL_P (inner) && DECL_WEAK (inner))
6722 return 0;
6725 /* Otherwise, ARG already has the proper type for the return value. */
6726 return arg;
6729 /* Fold a call to __builtin_classify_type. */
6731 static tree
6732 fold_builtin_classify_type (tree arglist)
6734 if (arglist == 0)
6735 return build_int_cst (NULL_TREE, no_type_class);
6737 return build_int_cst (NULL_TREE,
6738 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6741 /* Fold a call to __builtin_strlen. */
6743 static tree
6744 fold_builtin_strlen (tree arglist)
6746 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6747 return NULL_TREE;
6748 else
6750 tree len = c_strlen (TREE_VALUE (arglist), 0);
6752 if (len)
6754 /* Convert from the internal "sizetype" type to "size_t". */
6755 if (size_type_node)
6756 len = fold_convert (size_type_node, len);
6757 return len;
6760 return NULL_TREE;
6764 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6766 static tree
6767 fold_builtin_inf (tree type, int warn)
6769 REAL_VALUE_TYPE real;
6771 /* __builtin_inff is intended to be usable to define INFINITY on all
6772 targets. If an infinity is not available, INFINITY expands "to a
6773 positive constant of type float that overflows at translation
6774 time", footnote "In this case, using INFINITY will violate the
6775 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6776 Thus we pedwarn to ensure this constraint violation is
6777 diagnosed. */
6778 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6779 pedwarn ("target format does not support infinity");
6781 real_inf (&real);
6782 return build_real (type, real);
6785 /* Fold a call to __builtin_nan or __builtin_nans. */
6787 static tree
6788 fold_builtin_nan (tree arglist, tree type, int quiet)
6790 REAL_VALUE_TYPE real;
6791 const char *str;
6793 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6794 return 0;
6795 str = c_getstr (TREE_VALUE (arglist));
6796 if (!str)
6797 return 0;
6799 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6800 return 0;
6802 return build_real (type, real);
6805 /* Return true if the floating point expression T has an integer value.
6806 We also allow +Inf, -Inf and NaN to be considered integer values. */
6808 static bool
6809 integer_valued_real_p (tree t)
6811 switch (TREE_CODE (t))
6813 case FLOAT_EXPR:
6814 return true;
6816 case ABS_EXPR:
6817 case SAVE_EXPR:
6818 case NON_LVALUE_EXPR:
6819 return integer_valued_real_p (TREE_OPERAND (t, 0));
6821 case COMPOUND_EXPR:
6822 case GIMPLE_MODIFY_STMT:
6823 case BIND_EXPR:
6824 return integer_valued_real_p (GENERIC_TREE_OPERAND (t, 1));
6826 case PLUS_EXPR:
6827 case MINUS_EXPR:
6828 case MULT_EXPR:
6829 case MIN_EXPR:
6830 case MAX_EXPR:
6831 return integer_valued_real_p (TREE_OPERAND (t, 0))
6832 && integer_valued_real_p (TREE_OPERAND (t, 1));
6834 case COND_EXPR:
6835 return integer_valued_real_p (TREE_OPERAND (t, 1))
6836 && integer_valued_real_p (TREE_OPERAND (t, 2));
6838 case REAL_CST:
6839 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
6841 case NOP_EXPR:
6843 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6844 if (TREE_CODE (type) == INTEGER_TYPE)
6845 return true;
6846 if (TREE_CODE (type) == REAL_TYPE)
6847 return integer_valued_real_p (TREE_OPERAND (t, 0));
6848 break;
6851 case CALL_EXPR:
6852 switch (builtin_mathfn_code (t))
6854 CASE_FLT_FN (BUILT_IN_CEIL):
6855 CASE_FLT_FN (BUILT_IN_FLOOR):
6856 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6857 CASE_FLT_FN (BUILT_IN_RINT):
6858 CASE_FLT_FN (BUILT_IN_ROUND):
6859 CASE_FLT_FN (BUILT_IN_TRUNC):
6860 return true;
6862 CASE_FLT_FN (BUILT_IN_FMIN):
6863 CASE_FLT_FN (BUILT_IN_FMAX):
6864 return integer_valued_real_p (TREE_VALUE (TREE_OPERAND (t, 1)))
6865 && integer_valued_real_p (TREE_VALUE (TREE_CHAIN (TREE_OPERAND (t, 1))));
6867 default:
6868 break;
6870 break;
6872 default:
6873 break;
6875 return false;
6878 /* EXP is assumed to be builtin call where truncation can be propagated
6879 across (for instance floor((double)f) == (double)floorf (f).
6880 Do the transformation. */
6882 static tree
6883 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6885 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6886 tree arg;
6888 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6889 return 0;
6891 arg = TREE_VALUE (arglist);
6892 /* Integer rounding functions are idempotent. */
6893 if (fcode == builtin_mathfn_code (arg))
6894 return arg;
6896 /* If argument is already integer valued, and we don't need to worry
6897 about setting errno, there's no need to perform rounding. */
6898 if (! flag_errno_math && integer_valued_real_p (arg))
6899 return arg;
6901 if (optimize)
6903 tree arg0 = strip_float_extensions (arg);
6904 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6905 tree newtype = TREE_TYPE (arg0);
6906 tree decl;
6908 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6909 && (decl = mathfn_built_in (newtype, fcode)))
6911 arglist =
6912 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6913 return fold_convert (ftype,
6914 build_function_call_expr (decl, arglist));
6917 return 0;
6920 /* EXP is assumed to be builtin call which can narrow the FP type of
6921 the argument, for instance lround((double)f) -> lroundf (f). */
6923 static tree
6924 fold_fixed_mathfn (tree fndecl, tree arglist)
6926 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6927 tree arg;
6929 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6930 return 0;
6932 arg = TREE_VALUE (arglist);
6934 /* If argument is already integer valued, and we don't need to worry
6935 about setting errno, there's no need to perform rounding. */
6936 if (! flag_errno_math && integer_valued_real_p (arg))
6937 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6939 if (optimize)
6941 tree ftype = TREE_TYPE (arg);
6942 tree arg0 = strip_float_extensions (arg);
6943 tree newtype = TREE_TYPE (arg0);
6944 tree decl;
6946 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6947 && (decl = mathfn_built_in (newtype, fcode)))
6949 arglist =
6950 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6951 return build_function_call_expr (decl, arglist);
6955 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6956 sizeof (long long) == sizeof (long). */
6957 if (TYPE_PRECISION (long_long_integer_type_node)
6958 == TYPE_PRECISION (long_integer_type_node))
6960 tree newfn = NULL_TREE;
6961 switch (fcode)
6963 CASE_FLT_FN (BUILT_IN_LLCEIL):
6964 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6965 break;
6967 CASE_FLT_FN (BUILT_IN_LLFLOOR):
6968 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6969 break;
6971 CASE_FLT_FN (BUILT_IN_LLROUND):
6972 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6973 break;
6975 CASE_FLT_FN (BUILT_IN_LLRINT):
6976 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6977 break;
6979 default:
6980 break;
6983 if (newfn)
6985 tree newcall = build_function_call_expr (newfn, arglist);
6986 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6990 return 0;
6993 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6994 is the argument list, TYPE is the return type and FNDECL is the
6995 original function DECL. Return NULL_TREE if no if no simplification
6996 can be made. */
6998 static tree
6999 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
7001 tree arg;
7003 if (!arglist || TREE_CHAIN (arglist))
7004 return NULL_TREE;
7006 arg = TREE_VALUE (arglist);
7007 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7008 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7009 return NULL_TREE;
7011 /* Evaluate cabs of a constant at compile-time. */
7012 if (flag_unsafe_math_optimizations
7013 && TREE_CODE (arg) == COMPLEX_CST
7014 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
7015 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
7016 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
7017 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
7019 REAL_VALUE_TYPE r, i;
7021 r = TREE_REAL_CST (TREE_REALPART (arg));
7022 i = TREE_REAL_CST (TREE_IMAGPART (arg));
7024 real_arithmetic (&r, MULT_EXPR, &r, &r);
7025 real_arithmetic (&i, MULT_EXPR, &i, &i);
7026 real_arithmetic (&r, PLUS_EXPR, &r, &i);
7027 if (real_sqrt (&r, TYPE_MODE (type), &r)
7028 || ! flag_trapping_math)
7029 return build_real (type, r);
7032 /* If either part is zero, cabs is fabs of the other. */
7033 if (TREE_CODE (arg) == COMPLEX_EXPR
7034 && real_zerop (TREE_OPERAND (arg, 0)))
7035 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
7036 if (TREE_CODE (arg) == COMPLEX_EXPR
7037 && real_zerop (TREE_OPERAND (arg, 1)))
7038 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
7040 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7041 if (TREE_CODE (arg) == NEGATE_EXPR
7042 || TREE_CODE (arg) == CONJ_EXPR)
7044 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
7045 return build_function_call_expr (fndecl, arglist);
7048 /* Don't do this when optimizing for size. */
7049 if (flag_unsafe_math_optimizations
7050 && optimize && !optimize_size)
7052 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7054 if (sqrtfn != NULL_TREE)
7056 tree rpart, ipart, result, arglist;
7058 arg = builtin_save_expr (arg);
7060 rpart = fold_build1 (REALPART_EXPR, type, arg);
7061 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
7063 rpart = builtin_save_expr (rpart);
7064 ipart = builtin_save_expr (ipart);
7066 result = fold_build2 (PLUS_EXPR, type,
7067 fold_build2 (MULT_EXPR, type,
7068 rpart, rpart),
7069 fold_build2 (MULT_EXPR, type,
7070 ipart, ipart));
7072 arglist = build_tree_list (NULL_TREE, result);
7073 return build_function_call_expr (sqrtfn, arglist);
7077 return NULL_TREE;
7080 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
7081 NULL_TREE if no simplification can be made. */
7083 static tree
7084 fold_builtin_sqrt (tree arglist, tree type)
7087 enum built_in_function fcode;
7088 tree arg = TREE_VALUE (arglist);
7090 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7091 return NULL_TREE;
7093 /* Optimize sqrt of constant value. */
7094 if (TREE_CODE (arg) == REAL_CST
7095 && ! TREE_CONSTANT_OVERFLOW (arg))
7097 REAL_VALUE_TYPE r, x;
7099 x = TREE_REAL_CST (arg);
7100 if (real_sqrt (&r, TYPE_MODE (type), &x)
7101 || (!flag_trapping_math && !flag_errno_math))
7102 return build_real (type, r);
7105 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7106 fcode = builtin_mathfn_code (arg);
7107 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7109 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7110 arg = fold_build2 (MULT_EXPR, type,
7111 TREE_VALUE (TREE_OPERAND (arg, 1)),
7112 build_real (type, dconsthalf));
7113 arglist = build_tree_list (NULL_TREE, arg);
7114 return build_function_call_expr (expfn, arglist);
7117 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7118 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7120 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7122 if (powfn)
7124 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7125 tree tree_root;
7126 /* The inner root was either sqrt or cbrt. */
7127 REAL_VALUE_TYPE dconstroot =
7128 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7130 /* Adjust for the outer root. */
7131 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7132 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7133 tree_root = build_real (type, dconstroot);
7134 arglist = tree_cons (NULL_TREE, arg0,
7135 build_tree_list (NULL_TREE, tree_root));
7136 return build_function_call_expr (powfn, arglist);
7140 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7141 if (flag_unsafe_math_optimizations
7142 && (fcode == BUILT_IN_POW
7143 || fcode == BUILT_IN_POWF
7144 || fcode == BUILT_IN_POWL))
7146 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7147 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7148 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7149 tree narg1;
7150 if (!tree_expr_nonnegative_p (arg0))
7151 arg0 = build1 (ABS_EXPR, type, arg0);
7152 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7153 build_real (type, dconsthalf));
7154 arglist = tree_cons (NULL_TREE, arg0,
7155 build_tree_list (NULL_TREE, narg1));
7156 return build_function_call_expr (powfn, arglist);
7159 return NULL_TREE;
7162 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7163 NULL_TREE if no simplification can be made. */
7164 static tree
7165 fold_builtin_cbrt (tree arglist, tree type)
7167 tree arg = TREE_VALUE (arglist);
7168 const enum built_in_function fcode = builtin_mathfn_code (arg);
7169 tree res;
7171 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7172 return NULL_TREE;
7174 /* Calculate the result when the argument is a constant. */
7175 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7176 return res;
7178 if (flag_unsafe_math_optimizations)
7180 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7181 if (BUILTIN_EXPONENT_P (fcode))
7183 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7184 const REAL_VALUE_TYPE third_trunc =
7185 real_value_truncate (TYPE_MODE (type), dconstthird);
7186 arg = fold_build2 (MULT_EXPR, type,
7187 TREE_VALUE (TREE_OPERAND (arg, 1)),
7188 build_real (type, third_trunc));
7189 arglist = build_tree_list (NULL_TREE, arg);
7190 return build_function_call_expr (expfn, arglist);
7193 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7194 if (BUILTIN_SQRT_P (fcode))
7196 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7198 if (powfn)
7200 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7201 tree tree_root;
7202 REAL_VALUE_TYPE dconstroot = dconstthird;
7204 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7205 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7206 tree_root = build_real (type, dconstroot);
7207 arglist = tree_cons (NULL_TREE, arg0,
7208 build_tree_list (NULL_TREE, tree_root));
7209 return build_function_call_expr (powfn, arglist);
7213 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7214 if (BUILTIN_CBRT_P (fcode))
7216 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7217 if (tree_expr_nonnegative_p (arg0))
7219 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7221 if (powfn)
7223 tree tree_root;
7224 REAL_VALUE_TYPE dconstroot;
7226 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7227 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7228 tree_root = build_real (type, dconstroot);
7229 arglist = tree_cons (NULL_TREE, arg0,
7230 build_tree_list (NULL_TREE, tree_root));
7231 return build_function_call_expr (powfn, arglist);
7236 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7237 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7238 || fcode == BUILT_IN_POWL)
7240 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7241 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7242 if (tree_expr_nonnegative_p (arg00))
7244 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7245 const REAL_VALUE_TYPE dconstroot
7246 = real_value_truncate (TYPE_MODE (type), dconstthird);
7247 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7248 build_real (type, dconstroot));
7249 arglist = tree_cons (NULL_TREE, arg00,
7250 build_tree_list (NULL_TREE, narg01));
7251 return build_function_call_expr (powfn, arglist);
7255 return NULL_TREE;
7258 /* Fold function call to builtin cos, cosf, or cosl. Return
7259 NULL_TREE if no simplification can be made. */
7260 static tree
7261 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7263 tree arg = TREE_VALUE (arglist);
7264 tree res, narg;
7266 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7267 return NULL_TREE;
7269 /* Calculate the result when the argument is a constant. */
7270 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7271 return res;
7273 /* Optimize cos(-x) into cos (x). */
7274 if ((narg = fold_strip_sign_ops (arg)))
7275 return build_function_call_expr (fndecl,
7276 build_tree_list (NULL_TREE, narg));
7278 return NULL_TREE;
7281 /* Fold function call to builtin cosh, coshf, or coshl. Return
7282 NULL_TREE if no simplification can be made. */
7283 static tree
7284 fold_builtin_cosh (tree arglist, tree type, tree fndecl)
7286 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7288 tree arg = TREE_VALUE (arglist);
7289 tree res, narg;
7291 /* Calculate the result when the argument is a constant. */
7292 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7293 return res;
7295 /* Optimize cosh(-x) into cosh (x). */
7296 if ((narg = fold_strip_sign_ops (arg)))
7297 return build_function_call_expr (fndecl,
7298 build_tree_list (NULL_TREE, narg));
7301 return NULL_TREE;
7304 /* Fold function call to builtin tan, tanf, or tanl. Return
7305 NULL_TREE if no simplification can be made. */
7306 static tree
7307 fold_builtin_tan (tree arglist, tree type)
7309 enum built_in_function fcode;
7310 tree arg = TREE_VALUE (arglist);
7311 tree res;
7313 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7314 return NULL_TREE;
7316 /* Calculate the result when the argument is a constant. */
7317 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7318 return res;
7320 /* Optimize tan(atan(x)) = x. */
7321 fcode = builtin_mathfn_code (arg);
7322 if (flag_unsafe_math_optimizations
7323 && (fcode == BUILT_IN_ATAN
7324 || fcode == BUILT_IN_ATANF
7325 || fcode == BUILT_IN_ATANL))
7326 return TREE_VALUE (TREE_OPERAND (arg, 1));
7328 return NULL_TREE;
7331 /* Fold function call to builtin sincos, sincosf, or sincosl. Return
7332 NULL_TREE if no simplification can be made. */
7334 static tree
7335 fold_builtin_sincos (tree arglist)
7337 tree type, arg0, arg1, arg2;
7338 tree res, fn, call;
7340 if (!validate_arglist (arglist, REAL_TYPE, POINTER_TYPE,
7341 POINTER_TYPE, VOID_TYPE))
7342 return NULL_TREE;
7344 arg0 = TREE_VALUE (arglist);
7345 type = TREE_TYPE (arg0);
7346 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7347 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7349 /* Calculate the result when the argument is a constant. */
7350 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7351 return res;
7353 /* Canonicalize sincos to cexpi. */
7354 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7355 if (!fn)
7356 return NULL_TREE;
7358 call = build_function_call_expr (fn, build_tree_list (NULL_TREE, arg0));
7359 call = builtin_save_expr (call);
7361 return build2 (COMPOUND_EXPR, type,
7362 build2 (MODIFY_EXPR, void_type_node,
7363 build_fold_indirect_ref (arg1),
7364 build1 (IMAGPART_EXPR, type, call)),
7365 build2 (MODIFY_EXPR, void_type_node,
7366 build_fold_indirect_ref (arg2),
7367 build1 (REALPART_EXPR, type, call)));
7370 /* Fold function call to builtin cexp, cexpf, or cexpl. Return
7371 NULL_TREE if no simplification can be made. */
7373 static tree
7374 fold_builtin_cexp (tree arglist, tree type)
7376 tree arg0, rtype;
7377 tree realp, imagp, ifn;
7379 if (!validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7380 return NULL_TREE;
7382 arg0 = TREE_VALUE (arglist);
7383 rtype = TREE_TYPE (TREE_TYPE (arg0));
7385 /* In case we can figure out the real part of arg0 and it is constant zero
7386 fold to cexpi. */
7387 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7388 if (!ifn)
7389 return NULL_TREE;
7391 if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
7392 && real_zerop (realp))
7394 tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
7395 return build_function_call_expr (ifn, build_tree_list (NULL_TREE, narg));
7398 /* In case we can easily decompose real and imaginary parts split cexp
7399 to exp (r) * cexpi (i). */
7400 if (flag_unsafe_math_optimizations
7401 && realp)
7403 tree rfn, rcall, icall;
7405 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7406 if (!rfn)
7407 return NULL_TREE;
7409 imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
7410 if (!imagp)
7411 return NULL_TREE;
7413 icall = build_function_call_expr (ifn,
7414 build_tree_list (NULL_TREE, imagp));
7415 icall = builtin_save_expr (icall);
7416 rcall = build_function_call_expr (rfn,
7417 build_tree_list (NULL_TREE, realp));
7418 rcall = builtin_save_expr (rcall);
7419 return build2 (COMPLEX_EXPR, type,
7420 build2 (MULT_EXPR, rtype,
7421 rcall,
7422 build1 (REALPART_EXPR, rtype, icall)),
7423 build2 (MULT_EXPR, rtype,
7424 rcall,
7425 build1 (IMAGPART_EXPR, rtype, icall)));
7428 return NULL_TREE;
7431 /* Fold function call to builtin trunc, truncf or truncl. Return
7432 NULL_TREE if no simplification can be made. */
7434 static tree
7435 fold_builtin_trunc (tree fndecl, tree arglist)
7437 tree arg;
7439 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7440 return 0;
7442 /* Optimize trunc of constant value. */
7443 arg = TREE_VALUE (arglist);
7444 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7446 REAL_VALUE_TYPE r, x;
7447 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7449 x = TREE_REAL_CST (arg);
7450 real_trunc (&r, TYPE_MODE (type), &x);
7451 return build_real (type, r);
7454 return fold_trunc_transparent_mathfn (fndecl, arglist);
7457 /* Fold function call to builtin floor, floorf or floorl. Return
7458 NULL_TREE if no simplification can be made. */
7460 static tree
7461 fold_builtin_floor (tree fndecl, tree arglist)
7463 tree arg;
7465 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7466 return 0;
7468 /* Optimize floor of constant value. */
7469 arg = TREE_VALUE (arglist);
7470 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7472 REAL_VALUE_TYPE x;
7474 x = TREE_REAL_CST (arg);
7475 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7477 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7478 REAL_VALUE_TYPE r;
7480 real_floor (&r, TYPE_MODE (type), &x);
7481 return build_real (type, r);
7485 /* Fold floor (x) where x is nonnegative to trunc (x). */
7486 if (tree_expr_nonnegative_p (arg))
7488 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7489 if (truncfn)
7490 return build_function_call_expr (truncfn, arglist);
7493 return fold_trunc_transparent_mathfn (fndecl, arglist);
7496 /* Fold function call to builtin ceil, ceilf or ceill. Return
7497 NULL_TREE if no simplification can be made. */
7499 static tree
7500 fold_builtin_ceil (tree fndecl, tree arglist)
7502 tree arg;
7504 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7505 return 0;
7507 /* Optimize ceil of constant value. */
7508 arg = TREE_VALUE (arglist);
7509 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7511 REAL_VALUE_TYPE x;
7513 x = TREE_REAL_CST (arg);
7514 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7516 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7517 REAL_VALUE_TYPE r;
7519 real_ceil (&r, TYPE_MODE (type), &x);
7520 return build_real (type, r);
7524 return fold_trunc_transparent_mathfn (fndecl, arglist);
7527 /* Fold function call to builtin round, roundf or roundl. Return
7528 NULL_TREE if no simplification can be made. */
7530 static tree
7531 fold_builtin_round (tree fndecl, tree arglist)
7533 tree arg;
7535 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7536 return 0;
7538 /* Optimize round of constant value. */
7539 arg = TREE_VALUE (arglist);
7540 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7542 REAL_VALUE_TYPE x;
7544 x = TREE_REAL_CST (arg);
7545 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7547 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7548 REAL_VALUE_TYPE r;
7550 real_round (&r, TYPE_MODE (type), &x);
7551 return build_real (type, r);
7555 return fold_trunc_transparent_mathfn (fndecl, arglist);
7558 /* Fold function call to builtin lround, lroundf or lroundl (or the
7559 corresponding long long versions) and other rounding functions.
7560 Return NULL_TREE if no simplification can be made. */
7562 static tree
7563 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7565 tree arg;
7567 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7568 return 0;
7570 /* Optimize lround of constant value. */
7571 arg = TREE_VALUE (arglist);
7572 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7574 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7576 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7578 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7579 tree ftype = TREE_TYPE (arg), result;
7580 HOST_WIDE_INT hi, lo;
7581 REAL_VALUE_TYPE r;
7583 switch (DECL_FUNCTION_CODE (fndecl))
7585 CASE_FLT_FN (BUILT_IN_LFLOOR):
7586 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7587 real_floor (&r, TYPE_MODE (ftype), &x);
7588 break;
7590 CASE_FLT_FN (BUILT_IN_LCEIL):
7591 CASE_FLT_FN (BUILT_IN_LLCEIL):
7592 real_ceil (&r, TYPE_MODE (ftype), &x);
7593 break;
7595 CASE_FLT_FN (BUILT_IN_LROUND):
7596 CASE_FLT_FN (BUILT_IN_LLROUND):
7597 real_round (&r, TYPE_MODE (ftype), &x);
7598 break;
7600 default:
7601 gcc_unreachable ();
7604 REAL_VALUE_TO_INT (&lo, &hi, r);
7605 result = build_int_cst_wide (NULL_TREE, lo, hi);
7606 if (int_fits_type_p (result, itype))
7607 return fold_convert (itype, result);
7611 switch (DECL_FUNCTION_CODE (fndecl))
7613 CASE_FLT_FN (BUILT_IN_LFLOOR):
7614 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7615 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7616 if (tree_expr_nonnegative_p (arg))
7617 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
7618 arg);
7619 break;
7620 default:;
7623 return fold_fixed_mathfn (fndecl, arglist);
7626 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7627 and their long and long long variants (i.e. ffsl and ffsll).
7628 Return NULL_TREE if no simplification can be made. */
7630 static tree
7631 fold_builtin_bitop (tree fndecl, tree arglist)
7633 tree arg;
7635 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7636 return NULL_TREE;
7638 /* Optimize for constant argument. */
7639 arg = TREE_VALUE (arglist);
7640 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7642 HOST_WIDE_INT hi, width, result;
7643 unsigned HOST_WIDE_INT lo;
7644 tree type;
7646 type = TREE_TYPE (arg);
7647 width = TYPE_PRECISION (type);
7648 lo = TREE_INT_CST_LOW (arg);
7650 /* Clear all the bits that are beyond the type's precision. */
7651 if (width > HOST_BITS_PER_WIDE_INT)
7653 hi = TREE_INT_CST_HIGH (arg);
7654 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7655 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7657 else
7659 hi = 0;
7660 if (width < HOST_BITS_PER_WIDE_INT)
7661 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7664 switch (DECL_FUNCTION_CODE (fndecl))
7666 CASE_INT_FN (BUILT_IN_FFS):
7667 if (lo != 0)
7668 result = exact_log2 (lo & -lo) + 1;
7669 else if (hi != 0)
7670 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7671 else
7672 result = 0;
7673 break;
7675 CASE_INT_FN (BUILT_IN_CLZ):
7676 if (hi != 0)
7677 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7678 else if (lo != 0)
7679 result = width - floor_log2 (lo) - 1;
7680 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7681 result = width;
7682 break;
7684 CASE_INT_FN (BUILT_IN_CTZ):
7685 if (lo != 0)
7686 result = exact_log2 (lo & -lo);
7687 else if (hi != 0)
7688 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7689 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7690 result = width;
7691 break;
7693 CASE_INT_FN (BUILT_IN_POPCOUNT):
7694 result = 0;
7695 while (lo)
7696 result++, lo &= lo - 1;
7697 while (hi)
7698 result++, hi &= hi - 1;
7699 break;
7701 CASE_INT_FN (BUILT_IN_PARITY):
7702 result = 0;
7703 while (lo)
7704 result++, lo &= lo - 1;
7705 while (hi)
7706 result++, hi &= hi - 1;
7707 result &= 1;
7708 break;
7710 default:
7711 gcc_unreachable ();
7714 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7717 return NULL_TREE;
7720 /* Fold function call to builtin_bswap and the long and long long
7721 variants. Return NULL_TREE if no simplification can be made. */
7722 static tree
7723 fold_builtin_bswap (tree fndecl, tree arglist)
7725 tree arg;
7727 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7728 return 0;
7730 /* Optimize constant value. */
7731 arg = TREE_VALUE (arglist);
7732 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7734 HOST_WIDE_INT hi, width, r_hi = 0;
7735 unsigned HOST_WIDE_INT lo, r_lo = 0;
7736 tree type;
7738 type = TREE_TYPE (arg);
7739 width = TYPE_PRECISION (type);
7740 lo = TREE_INT_CST_LOW (arg);
7741 hi = TREE_INT_CST_HIGH (arg);
7743 switch (DECL_FUNCTION_CODE (fndecl))
7745 case BUILT_IN_BSWAP32:
7746 case BUILT_IN_BSWAP64:
7748 int s;
7750 for (s = 0; s < width; s += 8)
7752 int d = width - s - 8;
7753 unsigned HOST_WIDE_INT byte;
7755 if (s < HOST_BITS_PER_WIDE_INT)
7756 byte = (lo >> s) & 0xff;
7757 else
7758 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
7760 if (d < HOST_BITS_PER_WIDE_INT)
7761 r_lo |= byte << d;
7762 else
7763 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
7767 break;
7769 default:
7770 gcc_unreachable ();
7773 if (width < HOST_BITS_PER_WIDE_INT)
7774 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
7775 else
7776 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
7779 return NULL_TREE;
7781 /* Return true if EXPR is the real constant contained in VALUE. */
7783 static bool
7784 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7786 STRIP_NOPS (expr);
7788 return ((TREE_CODE (expr) == REAL_CST
7789 && ! TREE_CONSTANT_OVERFLOW (expr)
7790 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7791 || (TREE_CODE (expr) == COMPLEX_CST
7792 && real_dconstp (TREE_REALPART (expr), value)
7793 && real_zerop (TREE_IMAGPART (expr))));
7796 /* A subroutine of fold_builtin to fold the various logarithmic
7797 functions. Return NULL_TREE if no simplification can me made.
7798 FUNC is the corresponding MPFR logarithm function. */
7800 static tree
7801 fold_builtin_logarithm (tree fndecl, tree arglist,
7802 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
7804 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7806 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7807 tree arg = TREE_VALUE (arglist);
7808 tree res;
7809 const enum built_in_function fcode = builtin_mathfn_code (arg);
7811 /* Optimize log(e) = 1.0. We're never passed an exact 'e',
7812 instead we'll look for 'e' truncated to MODE. So only do
7813 this if flag_unsafe_math_optimizations is set. */
7814 if (flag_unsafe_math_optimizations && func == mpfr_log)
7816 const REAL_VALUE_TYPE e_truncated =
7817 real_value_truncate (TYPE_MODE (type), dconste);
7818 if (real_dconstp (arg, &e_truncated))
7819 return build_real (type, dconst1);
7822 /* Calculate the result when the argument is a constant. */
7823 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
7824 return res;
7826 /* Special case, optimize logN(expN(x)) = x. */
7827 if (flag_unsafe_math_optimizations
7828 && ((func == mpfr_log
7829 && (fcode == BUILT_IN_EXP
7830 || fcode == BUILT_IN_EXPF
7831 || fcode == BUILT_IN_EXPL))
7832 || (func == mpfr_log2
7833 && (fcode == BUILT_IN_EXP2
7834 || fcode == BUILT_IN_EXP2F
7835 || fcode == BUILT_IN_EXP2L))
7836 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
7837 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7839 /* Optimize logN(func()) for various exponential functions. We
7840 want to determine the value "x" and the power "exponent" in
7841 order to transform logN(x**exponent) into exponent*logN(x). */
7842 if (flag_unsafe_math_optimizations)
7844 tree exponent = 0, x = 0;
7846 switch (fcode)
7848 CASE_FLT_FN (BUILT_IN_EXP):
7849 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7850 x = build_real (type,
7851 real_value_truncate (TYPE_MODE (type), dconste));
7852 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7853 break;
7854 CASE_FLT_FN (BUILT_IN_EXP2):
7855 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7856 x = build_real (type, dconst2);
7857 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7858 break;
7859 CASE_FLT_FN (BUILT_IN_EXP10):
7860 CASE_FLT_FN (BUILT_IN_POW10):
7861 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7862 x = build_real (type, dconst10);
7863 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7864 break;
7865 CASE_FLT_FN (BUILT_IN_SQRT):
7866 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7867 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7868 exponent = build_real (type, dconsthalf);
7869 break;
7870 CASE_FLT_FN (BUILT_IN_CBRT):
7871 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7872 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7873 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7874 dconstthird));
7875 break;
7876 CASE_FLT_FN (BUILT_IN_POW):
7877 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7878 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7879 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7880 break;
7881 default:
7882 break;
7885 /* Now perform the optimization. */
7886 if (x && exponent)
7888 tree logfn;
7889 arglist = build_tree_list (NULL_TREE, x);
7890 logfn = build_function_call_expr (fndecl, arglist);
7891 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7896 return 0;
7899 /* Fold a builtin function call to hypot, hypotf, or hypotl. Return
7900 NULL_TREE if no simplification can be made. */
7902 static tree
7903 fold_builtin_hypot (tree fndecl, tree arglist, tree type)
7905 tree arg0 = TREE_VALUE (arglist);
7906 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7907 tree res, narg0, narg1;
7909 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7910 return NULL_TREE;
7912 /* Calculate the result when the argument is a constant. */
7913 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
7914 return res;
7916 /* If either argument to hypot has a negate or abs, strip that off.
7917 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
7918 narg0 = fold_strip_sign_ops (arg0);
7919 narg1 = fold_strip_sign_ops (arg1);
7920 if (narg0 || narg1)
7922 tree narglist = tree_cons (NULL_TREE, narg0 ? narg0 : arg0,
7923 build_tree_list (NULL_TREE,
7924 narg1 ? narg1 : arg1));
7925 return build_function_call_expr (fndecl, narglist);
7928 /* If either argument is zero, hypot is fabs of the other. */
7929 if (real_zerop (arg0))
7930 return fold_build1 (ABS_EXPR, type, arg1);
7931 else if (real_zerop (arg1))
7932 return fold_build1 (ABS_EXPR, type, arg0);
7934 /* hypot(x,x) -> fabs(x)*sqrt(2). */
7935 if (flag_unsafe_math_optimizations
7936 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
7938 REAL_VALUE_TYPE sqrt2;
7940 real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2);
7941 return fold_build2 (MULT_EXPR, type,
7942 fold_build1 (ABS_EXPR, type, arg0),
7943 build_real (type, sqrt2));
7946 return NULL_TREE;
7950 /* Fold a builtin function call to pow, powf, or powl. Return
7951 NULL_TREE if no simplification can be made. */
7952 static tree
7953 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7955 tree arg0 = TREE_VALUE (arglist);
7956 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7957 tree res;
7959 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7960 return NULL_TREE;
7962 /* Calculate the result when the argument is a constant. */
7963 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
7964 return res;
7966 /* Optimize pow(1.0,y) = 1.0. */
7967 if (real_onep (arg0))
7968 return omit_one_operand (type, build_real (type, dconst1), arg1);
7970 if (TREE_CODE (arg1) == REAL_CST
7971 && ! TREE_CONSTANT_OVERFLOW (arg1))
7973 REAL_VALUE_TYPE cint;
7974 REAL_VALUE_TYPE c;
7975 HOST_WIDE_INT n;
7977 c = TREE_REAL_CST (arg1);
7979 /* Optimize pow(x,0.0) = 1.0. */
7980 if (REAL_VALUES_EQUAL (c, dconst0))
7981 return omit_one_operand (type, build_real (type, dconst1),
7982 arg0);
7984 /* Optimize pow(x,1.0) = x. */
7985 if (REAL_VALUES_EQUAL (c, dconst1))
7986 return arg0;
7988 /* Optimize pow(x,-1.0) = 1.0/x. */
7989 if (REAL_VALUES_EQUAL (c, dconstm1))
7990 return fold_build2 (RDIV_EXPR, type,
7991 build_real (type, dconst1), arg0);
7993 /* Optimize pow(x,0.5) = sqrt(x). */
7994 if (flag_unsafe_math_optimizations
7995 && REAL_VALUES_EQUAL (c, dconsthalf))
7997 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7999 if (sqrtfn != NULL_TREE)
8001 tree arglist = build_tree_list (NULL_TREE, arg0);
8002 return build_function_call_expr (sqrtfn, arglist);
8006 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8007 if (flag_unsafe_math_optimizations)
8009 const REAL_VALUE_TYPE dconstroot
8010 = real_value_truncate (TYPE_MODE (type), dconstthird);
8012 if (REAL_VALUES_EQUAL (c, dconstroot))
8014 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8015 if (cbrtfn != NULL_TREE)
8017 tree arglist = build_tree_list (NULL_TREE, arg0);
8018 return build_function_call_expr (cbrtfn, arglist);
8023 /* Check for an integer exponent. */
8024 n = real_to_integer (&c);
8025 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8026 if (real_identical (&c, &cint))
8028 /* Attempt to evaluate pow at compile-time. */
8029 if (TREE_CODE (arg0) == REAL_CST
8030 && ! TREE_CONSTANT_OVERFLOW (arg0))
8032 REAL_VALUE_TYPE x;
8033 bool inexact;
8035 x = TREE_REAL_CST (arg0);
8036 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8037 if (flag_unsafe_math_optimizations || !inexact)
8038 return build_real (type, x);
8041 /* Strip sign ops from even integer powers. */
8042 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8044 tree narg0 = fold_strip_sign_ops (arg0);
8045 if (narg0)
8047 arglist = build_tree_list (NULL_TREE, arg1);
8048 arglist = tree_cons (NULL_TREE, narg0, arglist);
8049 return build_function_call_expr (fndecl, arglist);
8055 if (flag_unsafe_math_optimizations)
8057 const enum built_in_function fcode = builtin_mathfn_code (arg0);
8059 /* Optimize pow(expN(x),y) = expN(x*y). */
8060 if (BUILTIN_EXPONENT_P (fcode))
8062 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8063 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8064 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
8065 arglist = build_tree_list (NULL_TREE, arg);
8066 return build_function_call_expr (expfn, arglist);
8069 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8070 if (BUILTIN_SQRT_P (fcode))
8072 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8073 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8074 build_real (type, dconsthalf));
8076 arglist = tree_cons (NULL_TREE, narg0,
8077 build_tree_list (NULL_TREE, narg1));
8078 return build_function_call_expr (fndecl, arglist);
8081 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8082 if (BUILTIN_CBRT_P (fcode))
8084 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8085 if (tree_expr_nonnegative_p (arg))
8087 const REAL_VALUE_TYPE dconstroot
8088 = real_value_truncate (TYPE_MODE (type), dconstthird);
8089 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8090 build_real (type, dconstroot));
8091 arglist = tree_cons (NULL_TREE, arg,
8092 build_tree_list (NULL_TREE, narg1));
8093 return build_function_call_expr (fndecl, arglist);
8097 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
8098 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
8099 || fcode == BUILT_IN_POWL)
8101 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8102 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8103 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
8104 arglist = tree_cons (NULL_TREE, arg00,
8105 build_tree_list (NULL_TREE, narg1));
8106 return build_function_call_expr (fndecl, arglist);
8110 return NULL_TREE;
8113 /* Fold a builtin function call to powi, powif, or powil. Return
8114 NULL_TREE if no simplification can be made. */
8115 static tree
8116 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
8118 tree arg0 = TREE_VALUE (arglist);
8119 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8121 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
8122 return NULL_TREE;
8124 /* Optimize pow(1.0,y) = 1.0. */
8125 if (real_onep (arg0))
8126 return omit_one_operand (type, build_real (type, dconst1), arg1);
8128 if (host_integerp (arg1, 0))
8130 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8132 /* Evaluate powi at compile-time. */
8133 if (TREE_CODE (arg0) == REAL_CST
8134 && ! TREE_CONSTANT_OVERFLOW (arg0))
8136 REAL_VALUE_TYPE x;
8137 x = TREE_REAL_CST (arg0);
8138 real_powi (&x, TYPE_MODE (type), &x, c);
8139 return build_real (type, x);
8142 /* Optimize pow(x,0) = 1.0. */
8143 if (c == 0)
8144 return omit_one_operand (type, build_real (type, dconst1),
8145 arg0);
8147 /* Optimize pow(x,1) = x. */
8148 if (c == 1)
8149 return arg0;
8151 /* Optimize pow(x,-1) = 1.0/x. */
8152 if (c == -1)
8153 return fold_build2 (RDIV_EXPR, type,
8154 build_real (type, dconst1), arg0);
8157 return NULL_TREE;
8160 /* A subroutine of fold_builtin to fold the various exponent
8161 functions. Return NULL_TREE if no simplification can me made.
8162 FUNC is the corresponding MPFR exponent function. */
8164 static tree
8165 fold_builtin_exponent (tree fndecl, tree arglist,
8166 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8168 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8170 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8171 tree arg = TREE_VALUE (arglist);
8172 tree res;
8174 /* Calculate the result when the argument is a constant. */
8175 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8176 return res;
8178 /* Optimize expN(logN(x)) = x. */
8179 if (flag_unsafe_math_optimizations)
8181 const enum built_in_function fcode = builtin_mathfn_code (arg);
8183 if ((func == mpfr_exp
8184 && (fcode == BUILT_IN_LOG
8185 || fcode == BUILT_IN_LOGF
8186 || fcode == BUILT_IN_LOGL))
8187 || (func == mpfr_exp2
8188 && (fcode == BUILT_IN_LOG2
8189 || fcode == BUILT_IN_LOG2F
8190 || fcode == BUILT_IN_LOG2L))
8191 || (func == mpfr_exp10
8192 && (fcode == BUILT_IN_LOG10
8193 || fcode == BUILT_IN_LOG10F
8194 || fcode == BUILT_IN_LOG10L)))
8195 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
8199 return 0;
8202 /* Return true if VAR is a VAR_DECL or a component thereof. */
8204 static bool
8205 var_decl_component_p (tree var)
8207 tree inner = var;
8208 while (handled_component_p (inner))
8209 inner = TREE_OPERAND (inner, 0);
8210 return SSA_VAR_P (inner);
8213 /* Fold function call to builtin memset. Return
8214 NULL_TREE if no simplification can be made. */
8216 static tree
8217 fold_builtin_memset (tree arglist, tree type, bool ignore)
8219 tree dest, c, len, var, ret;
8220 unsigned HOST_WIDE_INT length, cval;
8222 if (!validate_arglist (arglist,
8223 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
8224 return 0;
8226 dest = TREE_VALUE (arglist);
8227 c = TREE_VALUE (TREE_CHAIN (arglist));
8228 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8230 if (! host_integerp (len, 1))
8231 return 0;
8233 /* If the LEN parameter is zero, return DEST. */
8234 if (integer_zerop (len))
8235 return omit_one_operand (type, dest, c);
8237 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8238 return 0;
8240 var = dest;
8241 STRIP_NOPS (var);
8242 if (TREE_CODE (var) != ADDR_EXPR)
8243 return 0;
8245 var = TREE_OPERAND (var, 0);
8246 if (TREE_THIS_VOLATILE (var))
8247 return 0;
8249 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8250 && !POINTER_TYPE_P (TREE_TYPE (var)))
8251 return 0;
8253 if (! var_decl_component_p (var))
8254 return 0;
8256 length = tree_low_cst (len, 1);
8257 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8258 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8259 < (int) length)
8260 return 0;
8262 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8263 return 0;
8265 if (integer_zerop (c))
8266 cval = 0;
8267 else
8269 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8270 return 0;
8272 cval = tree_low_cst (c, 1);
8273 cval &= 0xff;
8274 cval |= cval << 8;
8275 cval |= cval << 16;
8276 cval |= (cval << 31) << 1;
8279 ret = build_int_cst_type (TREE_TYPE (var), cval);
8280 ret = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (var), var, ret);
8281 if (ignore)
8282 return ret;
8284 return omit_one_operand (type, dest, ret);
8287 /* Fold function call to builtin memset. Return
8288 NULL_TREE if no simplification can be made. */
8290 static tree
8291 fold_builtin_bzero (tree arglist, bool ignore)
8293 tree dest, size, newarglist;
8295 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8296 return 0;
8298 if (!ignore)
8299 return 0;
8301 dest = TREE_VALUE (arglist);
8302 size = TREE_VALUE (TREE_CHAIN (arglist));
8304 /* New argument list transforming bzero(ptr x, int y) to
8305 memset(ptr x, int 0, size_t y). This is done this way
8306 so that if it isn't expanded inline, we fallback to
8307 calling bzero instead of memset. */
8309 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8310 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
8311 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8312 return fold_builtin_memset (newarglist, void_type_node, ignore);
8315 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8316 NULL_TREE if no simplification can be made.
8317 If ENDP is 0, return DEST (like memcpy).
8318 If ENDP is 1, return DEST+LEN (like mempcpy).
8319 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8320 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8321 (memmove). */
8323 static tree
8324 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8326 tree dest, src, len, destvar, srcvar, expr;
8328 if (! validate_arglist (arglist,
8329 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8330 return 0;
8332 dest = TREE_VALUE (arglist);
8333 src = TREE_VALUE (TREE_CHAIN (arglist));
8334 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8336 /* If the LEN parameter is zero, return DEST. */
8337 if (integer_zerop (len))
8338 return omit_one_operand (type, dest, src);
8340 /* If SRC and DEST are the same (and not volatile), return
8341 DEST{,+LEN,+LEN-1}. */
8342 if (operand_equal_p (src, dest, 0))
8343 expr = len;
8344 else
8346 tree srctype, desttype;
8347 if (endp == 3)
8349 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8350 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8352 /* Both DEST and SRC must be pointer types.
8353 ??? This is what old code did. Is the testing for pointer types
8354 really mandatory?
8356 If either SRC is readonly or length is 1, we can use memcpy. */
8357 if (dest_align && src_align
8358 && (readonly_data_expr (src)
8359 || (host_integerp (len, 1)
8360 && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
8361 tree_low_cst (len, 1)))))
8363 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8364 if (!fn)
8365 return 0;
8366 return build_function_call_expr (fn, arglist);
8368 return 0;
8371 if (!host_integerp (len, 0))
8372 return 0;
8373 /* FIXME:
8374 This logic lose for arguments like (type *)malloc (sizeof (type)),
8375 since we strip the casts of up to VOID return value from malloc.
8376 Perhaps we ought to inherit type from non-VOID argument here? */
8377 STRIP_NOPS (src);
8378 STRIP_NOPS (dest);
8379 srctype = TREE_TYPE (TREE_TYPE (src));
8380 desttype = TREE_TYPE (TREE_TYPE (dest));
8381 if (!srctype || !desttype
8382 || !TYPE_SIZE_UNIT (srctype)
8383 || !TYPE_SIZE_UNIT (desttype)
8384 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
8385 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
8386 || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
8387 || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8388 return 0;
8390 if (get_pointer_alignment (dest, BIGGEST_ALIGNMENT)
8391 < (int) TYPE_ALIGN (desttype)
8392 || (get_pointer_alignment (src, BIGGEST_ALIGNMENT)
8393 < (int) TYPE_ALIGN (srctype)))
8394 return 0;
8396 if (!ignore)
8397 dest = builtin_save_expr (dest);
8399 srcvar = build_fold_indirect_ref (src);
8400 if (TREE_THIS_VOLATILE (srcvar))
8401 return 0;
8402 if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
8403 return 0;
8404 /* With memcpy, it is possible to bypass aliasing rules, so without
8405 this check i. e. execute/20060930-2.c would be misoptimized, because
8406 it use conflicting alias set to hold argument for the memcpy call.
8407 This check is probably unnecesary with -fno-strict-aliasing.
8408 Similarly for destvar. See also PR29286. */
8409 if (!var_decl_component_p (srcvar)
8410 /* Accept: memcpy (*char_var, "test", 1); that simplify
8411 to char_var='t'; */
8412 || is_gimple_min_invariant (srcvar)
8413 || readonly_data_expr (src))
8414 return 0;
8416 destvar = build_fold_indirect_ref (dest);
8417 if (TREE_THIS_VOLATILE (destvar))
8418 return 0;
8419 if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
8420 return 0;
8421 if (!var_decl_component_p (destvar))
8422 return 0;
8424 if (srctype == desttype
8425 || (gimple_in_ssa_p (cfun)
8426 && tree_ssa_useless_type_conversion_1 (desttype, srctype)))
8427 expr = srcvar;
8428 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8429 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8430 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8431 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8432 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8433 else
8434 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8435 expr = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (destvar), destvar, expr);
8438 if (ignore)
8439 return expr;
8441 if (endp == 0 || endp == 3)
8442 return omit_one_operand (type, dest, expr);
8444 if (expr == len)
8445 expr = 0;
8447 if (endp == 2)
8448 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8449 ssize_int (1));
8451 len = fold_convert (TREE_TYPE (dest), len);
8452 dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8453 dest = fold_convert (type, dest);
8454 if (expr)
8455 dest = omit_one_operand (type, dest, expr);
8456 return dest;
8459 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8460 simplification can be made. */
8462 static tree
8463 fold_builtin_bcopy (tree arglist, bool ignore)
8465 tree src, dest, size, newarglist;
8467 if (!validate_arglist (arglist,
8468 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8469 return 0;
8471 if (! ignore)
8472 return 0;
8474 src = TREE_VALUE (arglist);
8475 dest = TREE_VALUE (TREE_CHAIN (arglist));
8476 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8478 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8479 memmove(ptr y, ptr x, size_t z). This is done this way
8480 so that if it isn't expanded inline, we fallback to
8481 calling bcopy instead of memmove. */
8483 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8484 newarglist = tree_cons (NULL_TREE, src, newarglist);
8485 newarglist = tree_cons (NULL_TREE, dest, newarglist);
8487 return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8490 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8491 the length of the string to be copied. Return NULL_TREE if no
8492 simplification can be made. */
8494 tree
8495 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8497 tree dest, src, fn;
8499 if (!validate_arglist (arglist,
8500 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8501 return 0;
8503 dest = TREE_VALUE (arglist);
8504 src = TREE_VALUE (TREE_CHAIN (arglist));
8506 /* If SRC and DEST are the same (and not volatile), return DEST. */
8507 if (operand_equal_p (src, dest, 0))
8508 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8510 if (optimize_size)
8511 return 0;
8513 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8514 if (!fn)
8515 return 0;
8517 if (!len)
8519 len = c_strlen (src, 1);
8520 if (! len || TREE_SIDE_EFFECTS (len))
8521 return 0;
8524 len = size_binop (PLUS_EXPR, len, ssize_int (1));
8525 arglist = build_tree_list (NULL_TREE, len);
8526 arglist = tree_cons (NULL_TREE, src, arglist);
8527 arglist = tree_cons (NULL_TREE, dest, arglist);
8528 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8529 build_function_call_expr (fn, arglist));
8532 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8533 the length of the source string. Return NULL_TREE if no simplification
8534 can be made. */
8536 tree
8537 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8539 tree dest, src, len, fn;
8541 if (!validate_arglist (arglist,
8542 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8543 return 0;
8545 dest = TREE_VALUE (arglist);
8546 src = TREE_VALUE (TREE_CHAIN (arglist));
8547 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8549 /* If the LEN parameter is zero, return DEST. */
8550 if (integer_zerop (len))
8551 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8553 /* We can't compare slen with len as constants below if len is not a
8554 constant. */
8555 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8556 return 0;
8558 if (!slen)
8559 slen = c_strlen (src, 1);
8561 /* Now, we must be passed a constant src ptr parameter. */
8562 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8563 return 0;
8565 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8567 /* We do not support simplification of this case, though we do
8568 support it when expanding trees into RTL. */
8569 /* FIXME: generate a call to __builtin_memset. */
8570 if (tree_int_cst_lt (slen, len))
8571 return 0;
8573 /* OK transform into builtin memcpy. */
8574 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8575 if (!fn)
8576 return 0;
8577 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8578 build_function_call_expr (fn, arglist));
8581 /* Fold function call to builtin memcmp. Return
8582 NULL_TREE if no simplification can be made. */
8584 static tree
8585 fold_builtin_memcmp (tree arglist)
8587 tree arg1, arg2, len;
8588 const char *p1, *p2;
8590 if (!validate_arglist (arglist,
8591 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8592 return 0;
8594 arg1 = TREE_VALUE (arglist);
8595 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8596 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8598 /* If the LEN parameter is zero, return zero. */
8599 if (integer_zerop (len))
8600 return omit_two_operands (integer_type_node, integer_zero_node,
8601 arg1, arg2);
8603 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8604 if (operand_equal_p (arg1, arg2, 0))
8605 return omit_one_operand (integer_type_node, integer_zero_node, len);
8607 p1 = c_getstr (arg1);
8608 p2 = c_getstr (arg2);
8610 /* If all arguments are constant, and the value of len is not greater
8611 than the lengths of arg1 and arg2, evaluate at compile-time. */
8612 if (host_integerp (len, 1) && p1 && p2
8613 && compare_tree_int (len, strlen (p1) + 1) <= 0
8614 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8616 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8618 if (r > 0)
8619 return integer_one_node;
8620 else if (r < 0)
8621 return integer_minus_one_node;
8622 else
8623 return integer_zero_node;
8626 /* If len parameter is one, return an expression corresponding to
8627 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8628 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8630 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8631 tree cst_uchar_ptr_node
8632 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8634 tree ind1 = fold_convert (integer_type_node,
8635 build1 (INDIRECT_REF, cst_uchar_node,
8636 fold_convert (cst_uchar_ptr_node,
8637 arg1)));
8638 tree ind2 = fold_convert (integer_type_node,
8639 build1 (INDIRECT_REF, cst_uchar_node,
8640 fold_convert (cst_uchar_ptr_node,
8641 arg2)));
8642 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8645 return 0;
8648 /* Fold function call to builtin strcmp. Return
8649 NULL_TREE if no simplification can be made. */
8651 static tree
8652 fold_builtin_strcmp (tree arglist)
8654 tree arg1, arg2;
8655 const char *p1, *p2;
8657 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8658 return 0;
8660 arg1 = TREE_VALUE (arglist);
8661 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8663 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8664 if (operand_equal_p (arg1, arg2, 0))
8665 return integer_zero_node;
8667 p1 = c_getstr (arg1);
8668 p2 = c_getstr (arg2);
8670 if (p1 && p2)
8672 const int i = strcmp (p1, p2);
8673 if (i < 0)
8674 return integer_minus_one_node;
8675 else if (i > 0)
8676 return integer_one_node;
8677 else
8678 return integer_zero_node;
8681 /* If the second arg is "", return *(const unsigned char*)arg1. */
8682 if (p2 && *p2 == '\0')
8684 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8685 tree cst_uchar_ptr_node
8686 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8688 return fold_convert (integer_type_node,
8689 build1 (INDIRECT_REF, cst_uchar_node,
8690 fold_convert (cst_uchar_ptr_node,
8691 arg1)));
8694 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8695 if (p1 && *p1 == '\0')
8697 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8698 tree cst_uchar_ptr_node
8699 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8701 tree temp = fold_convert (integer_type_node,
8702 build1 (INDIRECT_REF, cst_uchar_node,
8703 fold_convert (cst_uchar_ptr_node,
8704 arg2)));
8705 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8708 return 0;
8711 /* Fold function call to builtin strncmp. Return
8712 NULL_TREE if no simplification can be made. */
8714 static tree
8715 fold_builtin_strncmp (tree arglist)
8717 tree arg1, arg2, len;
8718 const char *p1, *p2;
8720 if (!validate_arglist (arglist,
8721 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8722 return 0;
8724 arg1 = TREE_VALUE (arglist);
8725 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8726 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8728 /* If the LEN parameter is zero, return zero. */
8729 if (integer_zerop (len))
8730 return omit_two_operands (integer_type_node, integer_zero_node,
8731 arg1, arg2);
8733 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8734 if (operand_equal_p (arg1, arg2, 0))
8735 return omit_one_operand (integer_type_node, integer_zero_node, len);
8737 p1 = c_getstr (arg1);
8738 p2 = c_getstr (arg2);
8740 if (host_integerp (len, 1) && p1 && p2)
8742 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8743 if (i > 0)
8744 return integer_one_node;
8745 else if (i < 0)
8746 return integer_minus_one_node;
8747 else
8748 return integer_zero_node;
8751 /* If the second arg is "", and the length is greater than zero,
8752 return *(const unsigned char*)arg1. */
8753 if (p2 && *p2 == '\0'
8754 && TREE_CODE (len) == INTEGER_CST
8755 && tree_int_cst_sgn (len) == 1)
8757 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8758 tree cst_uchar_ptr_node
8759 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8761 return fold_convert (integer_type_node,
8762 build1 (INDIRECT_REF, cst_uchar_node,
8763 fold_convert (cst_uchar_ptr_node,
8764 arg1)));
8767 /* If the first arg is "", and the length is greater than zero,
8768 return -*(const unsigned char*)arg2. */
8769 if (p1 && *p1 == '\0'
8770 && TREE_CODE (len) == INTEGER_CST
8771 && tree_int_cst_sgn (len) == 1)
8773 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8774 tree cst_uchar_ptr_node
8775 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8777 tree temp = fold_convert (integer_type_node,
8778 build1 (INDIRECT_REF, cst_uchar_node,
8779 fold_convert (cst_uchar_ptr_node,
8780 arg2)));
8781 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8784 /* If len parameter is one, return an expression corresponding to
8785 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8786 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8788 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8789 tree cst_uchar_ptr_node
8790 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8792 tree ind1 = fold_convert (integer_type_node,
8793 build1 (INDIRECT_REF, cst_uchar_node,
8794 fold_convert (cst_uchar_ptr_node,
8795 arg1)));
8796 tree ind2 = fold_convert (integer_type_node,
8797 build1 (INDIRECT_REF, cst_uchar_node,
8798 fold_convert (cst_uchar_ptr_node,
8799 arg2)));
8800 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8803 return 0;
8806 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8807 NULL_TREE if no simplification can be made. */
8809 static tree
8810 fold_builtin_signbit (tree fndecl, tree arglist)
8812 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8813 tree arg, temp;
8815 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8816 return NULL_TREE;
8818 arg = TREE_VALUE (arglist);
8820 /* If ARG is a compile-time constant, determine the result. */
8821 if (TREE_CODE (arg) == REAL_CST
8822 && !TREE_CONSTANT_OVERFLOW (arg))
8824 REAL_VALUE_TYPE c;
8826 c = TREE_REAL_CST (arg);
8827 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8828 return fold_convert (type, temp);
8831 /* If ARG is non-negative, the result is always zero. */
8832 if (tree_expr_nonnegative_p (arg))
8833 return omit_one_operand (type, integer_zero_node, arg);
8835 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8836 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8837 return fold_build2 (LT_EXPR, type, arg,
8838 build_real (TREE_TYPE (arg), dconst0));
8840 return NULL_TREE;
8843 /* Fold function call to builtin copysign, copysignf or copysignl.
8844 Return NULL_TREE if no simplification can be made. */
8846 static tree
8847 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8849 tree arg1, arg2, tem;
8851 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8852 return NULL_TREE;
8854 arg1 = TREE_VALUE (arglist);
8855 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8857 /* copysign(X,X) is X. */
8858 if (operand_equal_p (arg1, arg2, 0))
8859 return fold_convert (type, arg1);
8861 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8862 if (TREE_CODE (arg1) == REAL_CST
8863 && TREE_CODE (arg2) == REAL_CST
8864 && !TREE_CONSTANT_OVERFLOW (arg1)
8865 && !TREE_CONSTANT_OVERFLOW (arg2))
8867 REAL_VALUE_TYPE c1, c2;
8869 c1 = TREE_REAL_CST (arg1);
8870 c2 = TREE_REAL_CST (arg2);
8871 /* c1.sign := c2.sign. */
8872 real_copysign (&c1, &c2);
8873 return build_real (type, c1);
8876 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8877 Remember to evaluate Y for side-effects. */
8878 if (tree_expr_nonnegative_p (arg2))
8879 return omit_one_operand (type,
8880 fold_build1 (ABS_EXPR, type, arg1),
8881 arg2);
8883 /* Strip sign changing operations for the first argument. */
8884 tem = fold_strip_sign_ops (arg1);
8885 if (tem)
8887 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8888 return build_function_call_expr (fndecl, arglist);
8891 return NULL_TREE;
8894 /* Fold a call to builtin isascii. */
8896 static tree
8897 fold_builtin_isascii (tree arglist)
8899 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8900 return 0;
8901 else
8903 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8904 tree arg = TREE_VALUE (arglist);
8906 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8907 build_int_cst (NULL_TREE,
8908 ~ (unsigned HOST_WIDE_INT) 0x7f));
8909 return fold_build2 (EQ_EXPR, integer_type_node,
8910 arg, integer_zero_node);
8914 /* Fold a call to builtin toascii. */
8916 static tree
8917 fold_builtin_toascii (tree arglist)
8919 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8920 return 0;
8921 else
8923 /* Transform toascii(c) -> (c & 0x7f). */
8924 tree arg = TREE_VALUE (arglist);
8926 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8927 build_int_cst (NULL_TREE, 0x7f));
8931 /* Fold a call to builtin isdigit. */
8933 static tree
8934 fold_builtin_isdigit (tree arglist)
8936 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8937 return 0;
8938 else
8940 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8941 /* According to the C standard, isdigit is unaffected by locale.
8942 However, it definitely is affected by the target character set. */
8943 tree arg;
8944 unsigned HOST_WIDE_INT target_digit0
8945 = lang_hooks.to_target_charset ('0');
8947 if (target_digit0 == 0)
8948 return NULL_TREE;
8950 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8951 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8952 build_int_cst (unsigned_type_node, target_digit0));
8953 return fold_build2 (LE_EXPR, integer_type_node, arg,
8954 build_int_cst (unsigned_type_node, 9));
8958 /* Fold a call to fabs, fabsf or fabsl. */
8960 static tree
8961 fold_builtin_fabs (tree arglist, tree type)
8963 tree arg;
8965 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8966 return 0;
8968 arg = TREE_VALUE (arglist);
8969 arg = fold_convert (type, arg);
8970 if (TREE_CODE (arg) == REAL_CST)
8971 return fold_abs_const (arg, type);
8972 return fold_build1 (ABS_EXPR, type, arg);
8975 /* Fold a call to abs, labs, llabs or imaxabs. */
8977 static tree
8978 fold_builtin_abs (tree arglist, tree type)
8980 tree arg;
8982 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8983 return 0;
8985 arg = TREE_VALUE (arglist);
8986 arg = fold_convert (type, arg);
8987 if (TREE_CODE (arg) == INTEGER_CST)
8988 return fold_abs_const (arg, type);
8989 return fold_build1 (ABS_EXPR, type, arg);
8992 /* Fold a call to builtin fmin or fmax. */
8994 static tree
8995 fold_builtin_fmin_fmax (tree arglist, tree type, bool max)
8997 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8999 tree arg0 = TREE_VALUE (arglist);
9000 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
9001 /* Calculate the result when the argument is a constant. */
9002 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9004 if (res)
9005 return res;
9007 /* If either argument is NaN, return the other one. Avoid the
9008 transformation if we get (and honor) a signalling NaN. Using
9009 omit_one_operand() ensures we create a non-lvalue. */
9010 if (TREE_CODE (arg0) == REAL_CST
9011 && real_isnan (&TREE_REAL_CST (arg0))
9012 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9013 || ! TREE_REAL_CST (arg0).signalling))
9014 return omit_one_operand (type, arg1, arg0);
9015 if (TREE_CODE (arg1) == REAL_CST
9016 && real_isnan (&TREE_REAL_CST (arg1))
9017 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9018 || ! TREE_REAL_CST (arg1).signalling))
9019 return omit_one_operand (type, arg0, arg1);
9021 /* Transform fmin/fmax(x,x) -> x. */
9022 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9023 return omit_one_operand (type, arg0, arg1);
9025 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9026 functions to return the numeric arg if the other one is NaN.
9027 These tree codes don't honor that, so only transform if
9028 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9029 handled, so we don't have to worry about it either. */
9030 if (flag_finite_math_only)
9031 return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
9032 fold_convert (type, arg0),
9033 fold_convert (type, arg1));
9035 return NULL_TREE;
9038 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9039 EXP is the CALL_EXPR for the call. */
9041 static tree
9042 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
9044 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9045 tree arg;
9046 REAL_VALUE_TYPE r;
9048 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9050 /* Check that we have exactly one argument. */
9051 if (arglist == 0)
9053 error ("too few arguments to function %qs",
9054 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9055 return error_mark_node;
9057 else if (TREE_CHAIN (arglist) != 0)
9059 error ("too many arguments to function %qs",
9060 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9061 return error_mark_node;
9063 else
9065 error ("non-floating-point argument to function %qs",
9066 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9067 return error_mark_node;
9071 arg = TREE_VALUE (arglist);
9072 switch (builtin_index)
9074 case BUILT_IN_ISINF:
9075 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9076 return omit_one_operand (type, integer_zero_node, arg);
9078 if (TREE_CODE (arg) == REAL_CST)
9080 r = TREE_REAL_CST (arg);
9081 if (real_isinf (&r))
9082 return real_compare (GT_EXPR, &r, &dconst0)
9083 ? integer_one_node : integer_minus_one_node;
9084 else
9085 return integer_zero_node;
9088 return NULL_TREE;
9090 case BUILT_IN_FINITE:
9091 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9092 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9093 return omit_one_operand (type, integer_one_node, arg);
9095 if (TREE_CODE (arg) == REAL_CST)
9097 r = TREE_REAL_CST (arg);
9098 return real_isinf (&r) || real_isnan (&r)
9099 ? integer_zero_node : integer_one_node;
9102 return NULL_TREE;
9104 case BUILT_IN_ISNAN:
9105 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
9106 return omit_one_operand (type, integer_zero_node, arg);
9108 if (TREE_CODE (arg) == REAL_CST)
9110 r = TREE_REAL_CST (arg);
9111 return real_isnan (&r) ? integer_one_node : integer_zero_node;
9114 arg = builtin_save_expr (arg);
9115 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
9117 default:
9118 gcc_unreachable ();
9122 /* Fold a call to an unordered comparison function such as
9123 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
9124 being called and ARGLIST is the argument list for the call.
9125 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9126 the opposite of the desired result. UNORDERED_CODE is used
9127 for modes that can hold NaNs and ORDERED_CODE is used for
9128 the rest. */
9130 static tree
9131 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
9132 enum tree_code unordered_code,
9133 enum tree_code ordered_code)
9135 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9136 enum tree_code code;
9137 tree arg0, arg1;
9138 tree type0, type1;
9139 enum tree_code code0, code1;
9140 tree cmp_type = NULL_TREE;
9142 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9144 /* Check that we have exactly two arguments. */
9145 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
9147 error ("too few arguments to function %qs",
9148 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9149 return error_mark_node;
9151 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
9153 error ("too many arguments to function %qs",
9154 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9155 return error_mark_node;
9159 arg0 = TREE_VALUE (arglist);
9160 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
9162 type0 = TREE_TYPE (arg0);
9163 type1 = TREE_TYPE (arg1);
9165 code0 = TREE_CODE (type0);
9166 code1 = TREE_CODE (type1);
9168 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
9169 /* Choose the wider of two real types. */
9170 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
9171 ? type0 : type1;
9172 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
9173 cmp_type = type0;
9174 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
9175 cmp_type = type1;
9176 else
9178 error ("non-floating-point argument to function %qs",
9179 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9180 return error_mark_node;
9183 arg0 = fold_convert (cmp_type, arg0);
9184 arg1 = fold_convert (cmp_type, arg1);
9186 if (unordered_code == UNORDERED_EXPR)
9188 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
9189 return omit_two_operands (type, integer_zero_node, arg0, arg1);
9190 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
9193 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9194 : ordered_code;
9195 return fold_build1 (TRUTH_NOT_EXPR, type,
9196 fold_build2 (code, type, arg0, arg1));
9199 /* Used by constant folding to simplify calls to builtin functions. EXP is
9200 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
9201 result of the function call is ignored. This function returns NULL_TREE
9202 if no simplification was possible. */
9204 static tree
9205 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
9207 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9208 enum built_in_function fcode;
9210 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
9211 return targetm.fold_builtin (fndecl, arglist, ignore);
9213 fcode = DECL_FUNCTION_CODE (fndecl);
9214 switch (fcode)
9216 case BUILT_IN_FPUTS:
9217 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
9219 case BUILT_IN_FPUTS_UNLOCKED:
9220 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
9222 case BUILT_IN_STRSTR:
9223 return fold_builtin_strstr (arglist, type);
9225 case BUILT_IN_STRCAT:
9226 return fold_builtin_strcat (arglist);
9228 case BUILT_IN_STRNCAT:
9229 return fold_builtin_strncat (arglist);
9231 case BUILT_IN_STRSPN:
9232 return fold_builtin_strspn (arglist);
9234 case BUILT_IN_STRCSPN:
9235 return fold_builtin_strcspn (arglist);
9237 case BUILT_IN_STRCHR:
9238 case BUILT_IN_INDEX:
9239 return fold_builtin_strchr (arglist, type);
9241 case BUILT_IN_STRRCHR:
9242 case BUILT_IN_RINDEX:
9243 return fold_builtin_strrchr (arglist, type);
9245 case BUILT_IN_STRCPY:
9246 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
9248 case BUILT_IN_STRNCPY:
9249 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
9251 case BUILT_IN_STRCMP:
9252 return fold_builtin_strcmp (arglist);
9254 case BUILT_IN_STRNCMP:
9255 return fold_builtin_strncmp (arglist);
9257 case BUILT_IN_STRPBRK:
9258 return fold_builtin_strpbrk (arglist, type);
9260 case BUILT_IN_BCMP:
9261 case BUILT_IN_MEMCMP:
9262 return fold_builtin_memcmp (arglist);
9264 case BUILT_IN_SPRINTF:
9265 return fold_builtin_sprintf (arglist, ignore);
9267 case BUILT_IN_CONSTANT_P:
9269 tree val;
9271 val = fold_builtin_constant_p (arglist);
9272 /* Gimplification will pull the CALL_EXPR for the builtin out of
9273 an if condition. When not optimizing, we'll not CSE it back.
9274 To avoid link error types of regressions, return false now. */
9275 if (!val && !optimize)
9276 val = integer_zero_node;
9278 return val;
9281 case BUILT_IN_EXPECT:
9282 return fold_builtin_expect (arglist);
9284 case BUILT_IN_CLASSIFY_TYPE:
9285 return fold_builtin_classify_type (arglist);
9287 case BUILT_IN_STRLEN:
9288 return fold_builtin_strlen (arglist);
9290 CASE_FLT_FN (BUILT_IN_FABS):
9291 return fold_builtin_fabs (arglist, type);
9293 case BUILT_IN_ABS:
9294 case BUILT_IN_LABS:
9295 case BUILT_IN_LLABS:
9296 case BUILT_IN_IMAXABS:
9297 return fold_builtin_abs (arglist, type);
9299 CASE_FLT_FN (BUILT_IN_CONJ):
9300 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9301 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
9302 break;
9304 CASE_FLT_FN (BUILT_IN_CREAL):
9305 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9306 return non_lvalue (fold_build1 (REALPART_EXPR, type,
9307 TREE_VALUE (arglist)));
9308 break;
9310 CASE_FLT_FN (BUILT_IN_CIMAG):
9311 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9312 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
9313 TREE_VALUE (arglist)));
9314 break;
9316 CASE_FLT_FN (BUILT_IN_CABS):
9317 return fold_builtin_cabs (arglist, type, fndecl);
9319 CASE_FLT_FN (BUILT_IN_SQRT):
9320 return fold_builtin_sqrt (arglist, type);
9322 CASE_FLT_FN (BUILT_IN_CBRT):
9323 return fold_builtin_cbrt (arglist, type);
9325 CASE_FLT_FN (BUILT_IN_ASIN):
9326 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9327 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asin,
9328 &dconstm1, &dconst1, true);
9329 break;
9331 CASE_FLT_FN (BUILT_IN_ACOS):
9332 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9333 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acos,
9334 &dconstm1, &dconst1, true);
9335 break;
9337 CASE_FLT_FN (BUILT_IN_ATAN):
9338 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9339 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atan,
9340 NULL, NULL, 0);
9341 break;
9343 CASE_FLT_FN (BUILT_IN_ASINH):
9344 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9345 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asinh,
9346 NULL, NULL, 0);
9347 break;
9349 CASE_FLT_FN (BUILT_IN_ACOSH):
9350 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9351 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acosh,
9352 &dconst1, NULL, true);
9353 break;
9355 CASE_FLT_FN (BUILT_IN_ATANH):
9356 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9357 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atanh,
9358 &dconstm1, &dconst1, false);
9359 break;
9361 CASE_FLT_FN (BUILT_IN_SIN):
9362 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9363 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sin,
9364 NULL, NULL, 0);
9365 break;
9367 CASE_FLT_FN (BUILT_IN_COS):
9368 return fold_builtin_cos (arglist, type, fndecl);
9370 CASE_FLT_FN (BUILT_IN_TAN):
9371 return fold_builtin_tan (arglist, type);
9373 CASE_FLT_FN (BUILT_IN_SINCOS):
9374 return fold_builtin_sincos (arglist);
9376 CASE_FLT_FN (BUILT_IN_CEXP):
9377 return fold_builtin_cexp (arglist, type);
9379 CASE_FLT_FN (BUILT_IN_CEXPI):
9380 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9381 return do_mpfr_sincos (TREE_VALUE (arglist), NULL_TREE, NULL_TREE);
9383 CASE_FLT_FN (BUILT_IN_SINH):
9384 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9385 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sinh,
9386 NULL, NULL, 0);
9387 break;
9389 CASE_FLT_FN (BUILT_IN_COSH):
9390 return fold_builtin_cosh (arglist, type, fndecl);
9392 CASE_FLT_FN (BUILT_IN_TANH):
9393 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9394 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_tanh,
9395 NULL, NULL, 0);
9396 break;
9398 CASE_FLT_FN (BUILT_IN_ERF):
9399 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9400 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erf,
9401 NULL, NULL, 0);
9402 break;
9404 CASE_FLT_FN (BUILT_IN_ERFC):
9405 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9406 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erfc,
9407 NULL, NULL, 0);
9408 break;
9410 CASE_FLT_FN (BUILT_IN_TGAMMA):
9411 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9412 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_gamma,
9413 NULL, NULL, 0);
9414 break;
9416 CASE_FLT_FN (BUILT_IN_EXP):
9417 return fold_builtin_exponent (fndecl, arglist, mpfr_exp);
9419 CASE_FLT_FN (BUILT_IN_EXP2):
9420 return fold_builtin_exponent (fndecl, arglist, mpfr_exp2);
9422 CASE_FLT_FN (BUILT_IN_EXP10):
9423 CASE_FLT_FN (BUILT_IN_POW10):
9424 return fold_builtin_exponent (fndecl, arglist, mpfr_exp10);
9426 CASE_FLT_FN (BUILT_IN_EXPM1):
9427 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9428 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_expm1,
9429 NULL, NULL, 0);
9430 break;
9432 CASE_FLT_FN (BUILT_IN_LOG):
9433 return fold_builtin_logarithm (fndecl, arglist, mpfr_log);
9435 CASE_FLT_FN (BUILT_IN_LOG2):
9436 return fold_builtin_logarithm (fndecl, arglist, mpfr_log2);
9438 CASE_FLT_FN (BUILT_IN_LOG10):
9439 return fold_builtin_logarithm (fndecl, arglist, mpfr_log10);
9441 CASE_FLT_FN (BUILT_IN_LOG1P):
9442 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9443 return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_log1p,
9444 &dconstm1, NULL, false);
9445 break;
9447 CASE_FLT_FN (BUILT_IN_ATAN2):
9448 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9449 return do_mpfr_arg2 (TREE_VALUE (arglist),
9450 TREE_VALUE (TREE_CHAIN (arglist)),
9451 type, mpfr_atan2);
9452 break;
9454 CASE_FLT_FN (BUILT_IN_FMA):
9455 if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9456 return do_mpfr_arg3 (TREE_VALUE (arglist),
9457 TREE_VALUE (TREE_CHAIN (arglist)),
9458 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
9459 type, mpfr_fma);
9460 break;
9462 CASE_FLT_FN (BUILT_IN_FMIN):
9463 return fold_builtin_fmin_fmax (arglist, type, /*max=*/false);
9465 CASE_FLT_FN (BUILT_IN_FMAX):
9466 return fold_builtin_fmin_fmax (arglist, type, /*max=*/true);
9468 CASE_FLT_FN (BUILT_IN_HYPOT):
9469 return fold_builtin_hypot (fndecl, arglist, type);
9471 CASE_FLT_FN (BUILT_IN_POW):
9472 return fold_builtin_pow (fndecl, arglist, type);
9474 CASE_FLT_FN (BUILT_IN_POWI):
9475 return fold_builtin_powi (fndecl, arglist, type);
9477 CASE_FLT_FN (BUILT_IN_INF):
9478 case BUILT_IN_INFD32:
9479 case BUILT_IN_INFD64:
9480 case BUILT_IN_INFD128:
9481 return fold_builtin_inf (type, true);
9483 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9484 return fold_builtin_inf (type, false);
9486 CASE_FLT_FN (BUILT_IN_NAN):
9487 case BUILT_IN_NAND32:
9488 case BUILT_IN_NAND64:
9489 case BUILT_IN_NAND128:
9490 return fold_builtin_nan (arglist, type, true);
9492 CASE_FLT_FN (BUILT_IN_NANS):
9493 return fold_builtin_nan (arglist, type, false);
9495 CASE_FLT_FN (BUILT_IN_FLOOR):
9496 return fold_builtin_floor (fndecl, arglist);
9498 CASE_FLT_FN (BUILT_IN_CEIL):
9499 return fold_builtin_ceil (fndecl, arglist);
9501 CASE_FLT_FN (BUILT_IN_TRUNC):
9502 return fold_builtin_trunc (fndecl, arglist);
9504 CASE_FLT_FN (BUILT_IN_ROUND):
9505 return fold_builtin_round (fndecl, arglist);
9507 CASE_FLT_FN (BUILT_IN_NEARBYINT):
9508 CASE_FLT_FN (BUILT_IN_RINT):
9509 return fold_trunc_transparent_mathfn (fndecl, arglist);
9511 CASE_FLT_FN (BUILT_IN_LCEIL):
9512 CASE_FLT_FN (BUILT_IN_LLCEIL):
9513 CASE_FLT_FN (BUILT_IN_LFLOOR):
9514 CASE_FLT_FN (BUILT_IN_LLFLOOR):
9515 CASE_FLT_FN (BUILT_IN_LROUND):
9516 CASE_FLT_FN (BUILT_IN_LLROUND):
9517 return fold_builtin_int_roundingfn (fndecl, arglist);
9519 CASE_FLT_FN (BUILT_IN_LRINT):
9520 CASE_FLT_FN (BUILT_IN_LLRINT):
9521 return fold_fixed_mathfn (fndecl, arglist);
9523 case BUILT_IN_BSWAP32:
9524 case BUILT_IN_BSWAP64:
9525 return fold_builtin_bswap (fndecl, arglist);
9527 CASE_INT_FN (BUILT_IN_FFS):
9528 CASE_INT_FN (BUILT_IN_CLZ):
9529 CASE_INT_FN (BUILT_IN_CTZ):
9530 CASE_INT_FN (BUILT_IN_POPCOUNT):
9531 CASE_INT_FN (BUILT_IN_PARITY):
9532 return fold_builtin_bitop (fndecl, arglist);
9534 case BUILT_IN_MEMSET:
9535 return fold_builtin_memset (arglist, type, ignore);
9537 case BUILT_IN_MEMCPY:
9538 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9540 case BUILT_IN_MEMPCPY:
9541 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9543 case BUILT_IN_MEMMOVE:
9544 return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9546 case BUILT_IN_BZERO:
9547 return fold_builtin_bzero (arglist, ignore);
9549 case BUILT_IN_BCOPY:
9550 return fold_builtin_bcopy (arglist, ignore);
9552 CASE_FLT_FN (BUILT_IN_SIGNBIT):
9553 return fold_builtin_signbit (fndecl, arglist);
9555 case BUILT_IN_ISASCII:
9556 return fold_builtin_isascii (arglist);
9558 case BUILT_IN_TOASCII:
9559 return fold_builtin_toascii (arglist);
9561 case BUILT_IN_ISDIGIT:
9562 return fold_builtin_isdigit (arglist);
9564 CASE_FLT_FN (BUILT_IN_COPYSIGN):
9565 return fold_builtin_copysign (fndecl, arglist, type);
9567 CASE_FLT_FN (BUILT_IN_FINITE):
9568 case BUILT_IN_FINITED32:
9569 case BUILT_IN_FINITED64:
9570 case BUILT_IN_FINITED128:
9571 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9573 CASE_FLT_FN (BUILT_IN_ISINF):
9574 case BUILT_IN_ISINFD32:
9575 case BUILT_IN_ISINFD64:
9576 case BUILT_IN_ISINFD128:
9577 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9579 CASE_FLT_FN (BUILT_IN_ISNAN):
9580 case BUILT_IN_ISNAND32:
9581 case BUILT_IN_ISNAND64:
9582 case BUILT_IN_ISNAND128:
9583 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9585 case BUILT_IN_ISGREATER:
9586 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9587 case BUILT_IN_ISGREATEREQUAL:
9588 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9589 case BUILT_IN_ISLESS:
9590 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9591 case BUILT_IN_ISLESSEQUAL:
9592 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9593 case BUILT_IN_ISLESSGREATER:
9594 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9595 case BUILT_IN_ISUNORDERED:
9596 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9597 NOP_EXPR);
9599 /* We do the folding for va_start in the expander. */
9600 case BUILT_IN_VA_START:
9601 break;
9603 case BUILT_IN_OBJECT_SIZE:
9604 return fold_builtin_object_size (arglist);
9605 case BUILT_IN_MEMCPY_CHK:
9606 case BUILT_IN_MEMPCPY_CHK:
9607 case BUILT_IN_MEMMOVE_CHK:
9608 case BUILT_IN_MEMSET_CHK:
9609 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9610 DECL_FUNCTION_CODE (fndecl));
9611 case BUILT_IN_STRCPY_CHK:
9612 case BUILT_IN_STPCPY_CHK:
9613 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9614 DECL_FUNCTION_CODE (fndecl));
9615 case BUILT_IN_STRNCPY_CHK:
9616 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9617 case BUILT_IN_STRCAT_CHK:
9618 return fold_builtin_strcat_chk (fndecl, arglist);
9619 case BUILT_IN_STRNCAT_CHK:
9620 return fold_builtin_strncat_chk (fndecl, arglist);
9621 case BUILT_IN_SPRINTF_CHK:
9622 case BUILT_IN_VSPRINTF_CHK:
9623 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9624 case BUILT_IN_SNPRINTF_CHK:
9625 case BUILT_IN_VSNPRINTF_CHK:
9626 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9627 DECL_FUNCTION_CODE (fndecl));
9629 case BUILT_IN_PRINTF:
9630 case BUILT_IN_PRINTF_UNLOCKED:
9631 case BUILT_IN_VPRINTF:
9632 case BUILT_IN_PRINTF_CHK:
9633 case BUILT_IN_VPRINTF_CHK:
9634 return fold_builtin_printf (fndecl, arglist, ignore,
9635 DECL_FUNCTION_CODE (fndecl));
9637 case BUILT_IN_FPRINTF:
9638 case BUILT_IN_FPRINTF_UNLOCKED:
9639 case BUILT_IN_VFPRINTF:
9640 case BUILT_IN_FPRINTF_CHK:
9641 case BUILT_IN_VFPRINTF_CHK:
9642 return fold_builtin_fprintf (fndecl, arglist, ignore,
9643 DECL_FUNCTION_CODE (fndecl));
9645 default:
9646 break;
9649 return 0;
9652 /* A wrapper function for builtin folding that prevents warnings for
9653 "statement without effect" and the like, caused by removing the
9654 call node earlier than the warning is generated. */
9656 tree
9657 fold_builtin (tree fndecl, tree arglist, bool ignore)
9659 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9660 if (exp && !ignore)
9662 exp = build1 (NOP_EXPR, GENERIC_TREE_TYPE (exp), exp);
9663 TREE_NO_WARNING (exp) = 1;
9666 return exp;
9669 /* Conveniently construct a function call expression. */
9671 tree
9672 build_function_call_expr (tree fn, tree arglist)
9674 tree call_expr;
9676 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9677 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9678 call_expr, arglist, NULL_TREE);
9681 /* This function validates the types of a function call argument list
9682 represented as a tree chain of parameters against a specified list
9683 of tree_codes. If the last specifier is a 0, that represents an
9684 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9687 validate_arglist (tree arglist, ...)
9689 enum tree_code code;
9690 int res = 0;
9691 va_list ap;
9693 va_start (ap, arglist);
9697 code = va_arg (ap, enum tree_code);
9698 switch (code)
9700 case 0:
9701 /* This signifies an ellipses, any further arguments are all ok. */
9702 res = 1;
9703 goto end;
9704 case VOID_TYPE:
9705 /* This signifies an endlink, if no arguments remain, return
9706 true, otherwise return false. */
9707 res = arglist == 0;
9708 goto end;
9709 default:
9710 /* If no parameters remain or the parameter's code does not
9711 match the specified code, return false. Otherwise continue
9712 checking any remaining arguments. */
9713 if (arglist == 0)
9714 goto end;
9715 if (code == POINTER_TYPE)
9717 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9718 goto end;
9720 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9721 goto end;
9722 break;
9724 arglist = TREE_CHAIN (arglist);
9726 while (1);
9728 /* We need gotos here since we can only have one VA_CLOSE in a
9729 function. */
9730 end: ;
9731 va_end (ap);
9733 return res;
9736 /* Default target-specific builtin expander that does nothing. */
9739 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9740 rtx target ATTRIBUTE_UNUSED,
9741 rtx subtarget ATTRIBUTE_UNUSED,
9742 enum machine_mode mode ATTRIBUTE_UNUSED,
9743 int ignore ATTRIBUTE_UNUSED)
9745 return NULL_RTX;
9748 /* Returns true is EXP represents data that would potentially reside
9749 in a readonly section. */
9751 static bool
9752 readonly_data_expr (tree exp)
9754 STRIP_NOPS (exp);
9756 if (TREE_CODE (exp) != ADDR_EXPR)
9757 return false;
9759 exp = get_base_address (TREE_OPERAND (exp, 0));
9760 if (!exp)
9761 return false;
9763 /* Make sure we call decl_readonly_section only for trees it
9764 can handle (since it returns true for everything it doesn't
9765 understand). */
9766 if (TREE_CODE (exp) == STRING_CST
9767 || TREE_CODE (exp) == CONSTRUCTOR
9768 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9769 return decl_readonly_section (exp, 0);
9770 else
9771 return false;
9774 /* Simplify a call to the strstr builtin.
9776 Return 0 if no simplification was possible, otherwise return the
9777 simplified form of the call as a tree.
9779 The simplified form may be a constant or other expression which
9780 computes the same value, but in a more efficient manner (including
9781 calls to other builtin functions).
9783 The call may contain arguments which need to be evaluated, but
9784 which are not useful to determine the result of the call. In
9785 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9786 COMPOUND_EXPR will be an argument which must be evaluated.
9787 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9788 COMPOUND_EXPR in the chain will contain the tree for the simplified
9789 form of the builtin function call. */
9791 static tree
9792 fold_builtin_strstr (tree arglist, tree type)
9794 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9795 return 0;
9796 else
9798 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9799 tree fn;
9800 const char *p1, *p2;
9802 p2 = c_getstr (s2);
9803 if (p2 == NULL)
9804 return 0;
9806 p1 = c_getstr (s1);
9807 if (p1 != NULL)
9809 const char *r = strstr (p1, p2);
9810 tree tem;
9812 if (r == NULL)
9813 return build_int_cst (TREE_TYPE (s1), 0);
9815 /* Return an offset into the constant string argument. */
9816 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9817 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9818 return fold_convert (type, tem);
9821 /* The argument is const char *, and the result is char *, so we need
9822 a type conversion here to avoid a warning. */
9823 if (p2[0] == '\0')
9824 return fold_convert (type, s1);
9826 if (p2[1] != '\0')
9827 return 0;
9829 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9830 if (!fn)
9831 return 0;
9833 /* New argument list transforming strstr(s1, s2) to
9834 strchr(s1, s2[0]). */
9835 arglist = build_tree_list (NULL_TREE,
9836 build_int_cst (NULL_TREE, p2[0]));
9837 arglist = tree_cons (NULL_TREE, s1, arglist);
9838 return build_function_call_expr (fn, arglist);
9842 /* Simplify a call to the strchr builtin.
9844 Return 0 if no simplification was possible, otherwise return the
9845 simplified form of the call as a tree.
9847 The simplified form may be a constant or other expression which
9848 computes the same value, but in a more efficient manner (including
9849 calls to other builtin functions).
9851 The call may contain arguments which need to be evaluated, but
9852 which are not useful to determine the result of the call. In
9853 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9854 COMPOUND_EXPR will be an argument which must be evaluated.
9855 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9856 COMPOUND_EXPR in the chain will contain the tree for the simplified
9857 form of the builtin function call. */
9859 static tree
9860 fold_builtin_strchr (tree arglist, tree type)
9862 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9863 return 0;
9864 else
9866 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9867 const char *p1;
9869 if (TREE_CODE (s2) != INTEGER_CST)
9870 return 0;
9872 p1 = c_getstr (s1);
9873 if (p1 != NULL)
9875 char c;
9876 const char *r;
9877 tree tem;
9879 if (target_char_cast (s2, &c))
9880 return 0;
9882 r = strchr (p1, c);
9884 if (r == NULL)
9885 return build_int_cst (TREE_TYPE (s1), 0);
9887 /* Return an offset into the constant string argument. */
9888 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9889 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9890 return fold_convert (type, tem);
9892 return 0;
9896 /* Simplify a call to the strrchr builtin.
9898 Return 0 if no simplification was possible, otherwise return the
9899 simplified form of the call as a tree.
9901 The simplified form may be a constant or other expression which
9902 computes the same value, but in a more efficient manner (including
9903 calls to other builtin functions).
9905 The call may contain arguments which need to be evaluated, but
9906 which are not useful to determine the result of the call. In
9907 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9908 COMPOUND_EXPR will be an argument which must be evaluated.
9909 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9910 COMPOUND_EXPR in the chain will contain the tree for the simplified
9911 form of the builtin function call. */
9913 static tree
9914 fold_builtin_strrchr (tree arglist, tree type)
9916 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9917 return 0;
9918 else
9920 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9921 tree fn;
9922 const char *p1;
9924 if (TREE_CODE (s2) != INTEGER_CST)
9925 return 0;
9927 p1 = c_getstr (s1);
9928 if (p1 != NULL)
9930 char c;
9931 const char *r;
9932 tree tem;
9934 if (target_char_cast (s2, &c))
9935 return 0;
9937 r = strrchr (p1, c);
9939 if (r == NULL)
9940 return build_int_cst (TREE_TYPE (s1), 0);
9942 /* Return an offset into the constant string argument. */
9943 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9944 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9945 return fold_convert (type, tem);
9948 if (! integer_zerop (s2))
9949 return 0;
9951 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9952 if (!fn)
9953 return 0;
9955 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9956 return build_function_call_expr (fn, arglist);
9960 /* Simplify a call to the strpbrk builtin.
9962 Return 0 if no simplification was possible, otherwise return the
9963 simplified form of the call as a tree.
9965 The simplified form may be a constant or other expression which
9966 computes the same value, but in a more efficient manner (including
9967 calls to other builtin functions).
9969 The call may contain arguments which need to be evaluated, but
9970 which are not useful to determine the result of the call. In
9971 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9972 COMPOUND_EXPR will be an argument which must be evaluated.
9973 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9974 COMPOUND_EXPR in the chain will contain the tree for the simplified
9975 form of the builtin function call. */
9977 static tree
9978 fold_builtin_strpbrk (tree arglist, tree type)
9980 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9981 return 0;
9982 else
9984 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9985 tree fn;
9986 const char *p1, *p2;
9988 p2 = c_getstr (s2);
9989 if (p2 == NULL)
9990 return 0;
9992 p1 = c_getstr (s1);
9993 if (p1 != NULL)
9995 const char *r = strpbrk (p1, p2);
9996 tree tem;
9998 if (r == NULL)
9999 return build_int_cst (TREE_TYPE (s1), 0);
10001 /* Return an offset into the constant string argument. */
10002 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
10003 s1, build_int_cst (TREE_TYPE (s1), r - p1));
10004 return fold_convert (type, tem);
10007 if (p2[0] == '\0')
10008 /* strpbrk(x, "") == NULL.
10009 Evaluate and ignore s1 in case it had side-effects. */
10010 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
10012 if (p2[1] != '\0')
10013 return 0; /* Really call strpbrk. */
10015 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
10016 if (!fn)
10017 return 0;
10019 /* New argument list transforming strpbrk(s1, s2) to
10020 strchr(s1, s2[0]). */
10021 arglist = build_tree_list (NULL_TREE,
10022 build_int_cst (NULL_TREE, p2[0]));
10023 arglist = tree_cons (NULL_TREE, s1, arglist);
10024 return build_function_call_expr (fn, arglist);
10028 /* Simplify a call to the strcat builtin.
10030 Return 0 if no simplification was possible, otherwise return the
10031 simplified form of the call as a tree.
10033 The simplified form may be a constant or other expression which
10034 computes the same value, but in a more efficient manner (including
10035 calls to other builtin functions).
10037 The call may contain arguments which need to be evaluated, but
10038 which are not useful to determine the result of the call. In
10039 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10040 COMPOUND_EXPR will be an argument which must be evaluated.
10041 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10042 COMPOUND_EXPR in the chain will contain the tree for the simplified
10043 form of the builtin function call. */
10045 static tree
10046 fold_builtin_strcat (tree arglist)
10048 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10049 return 0;
10050 else
10052 tree dst = TREE_VALUE (arglist),
10053 src = TREE_VALUE (TREE_CHAIN (arglist));
10054 const char *p = c_getstr (src);
10056 /* If the string length is zero, return the dst parameter. */
10057 if (p && *p == '\0')
10058 return dst;
10060 return 0;
10064 /* Simplify a call to the strncat builtin.
10066 Return 0 if no simplification was possible, otherwise return the
10067 simplified form of the call as a tree.
10069 The simplified form may be a constant or other expression which
10070 computes the same value, but in a more efficient manner (including
10071 calls to other builtin functions).
10073 The call may contain arguments which need to be evaluated, but
10074 which are not useful to determine the result of the call. In
10075 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10076 COMPOUND_EXPR will be an argument which must be evaluated.
10077 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10078 COMPOUND_EXPR in the chain will contain the tree for the simplified
10079 form of the builtin function call. */
10081 static tree
10082 fold_builtin_strncat (tree arglist)
10084 if (!validate_arglist (arglist,
10085 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10086 return 0;
10087 else
10089 tree dst = TREE_VALUE (arglist);
10090 tree src = TREE_VALUE (TREE_CHAIN (arglist));
10091 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10092 const char *p = c_getstr (src);
10094 /* If the requested length is zero, or the src parameter string
10095 length is zero, return the dst parameter. */
10096 if (integer_zerop (len) || (p && *p == '\0'))
10097 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
10099 /* If the requested len is greater than or equal to the string
10100 length, call strcat. */
10101 if (TREE_CODE (len) == INTEGER_CST && p
10102 && compare_tree_int (len, strlen (p)) >= 0)
10104 tree newarglist
10105 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
10106 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
10108 /* If the replacement _DECL isn't initialized, don't do the
10109 transformation. */
10110 if (!fn)
10111 return 0;
10113 return build_function_call_expr (fn, newarglist);
10115 return 0;
10119 /* Simplify a call to the strspn builtin.
10121 Return 0 if no simplification was possible, otherwise return the
10122 simplified form of the call as a tree.
10124 The simplified form may be a constant or other expression which
10125 computes the same value, but in a more efficient manner (including
10126 calls to other builtin functions).
10128 The call may contain arguments which need to be evaluated, but
10129 which are not useful to determine the result of the call. In
10130 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10131 COMPOUND_EXPR will be an argument which must be evaluated.
10132 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10133 COMPOUND_EXPR in the chain will contain the tree for the simplified
10134 form of the builtin function call. */
10136 static tree
10137 fold_builtin_strspn (tree arglist)
10139 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10140 return 0;
10141 else
10143 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10144 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10146 /* If both arguments are constants, evaluate at compile-time. */
10147 if (p1 && p2)
10149 const size_t r = strspn (p1, p2);
10150 return size_int (r);
10153 /* If either argument is "", return 0. */
10154 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
10155 /* Evaluate and ignore both arguments in case either one has
10156 side-effects. */
10157 return omit_two_operands (integer_type_node, integer_zero_node,
10158 s1, s2);
10159 return 0;
10163 /* Simplify a call to the strcspn builtin.
10165 Return 0 if no simplification was possible, otherwise return the
10166 simplified form of the call as a tree.
10168 The simplified form may be a constant or other expression which
10169 computes the same value, but in a more efficient manner (including
10170 calls to other builtin functions).
10172 The call may contain arguments which need to be evaluated, but
10173 which are not useful to determine the result of the call. In
10174 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10175 COMPOUND_EXPR will be an argument which must be evaluated.
10176 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10177 COMPOUND_EXPR in the chain will contain the tree for the simplified
10178 form of the builtin function call. */
10180 static tree
10181 fold_builtin_strcspn (tree arglist)
10183 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10184 return 0;
10185 else
10187 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10188 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10190 /* If both arguments are constants, evaluate at compile-time. */
10191 if (p1 && p2)
10193 const size_t r = strcspn (p1, p2);
10194 return size_int (r);
10197 /* If the first argument is "", return 0. */
10198 if (p1 && *p1 == '\0')
10200 /* Evaluate and ignore argument s2 in case it has
10201 side-effects. */
10202 return omit_one_operand (integer_type_node,
10203 integer_zero_node, s2);
10206 /* If the second argument is "", return __builtin_strlen(s1). */
10207 if (p2 && *p2 == '\0')
10209 tree newarglist = build_tree_list (NULL_TREE, s1),
10210 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
10212 /* If the replacement _DECL isn't initialized, don't do the
10213 transformation. */
10214 if (!fn)
10215 return 0;
10217 return build_function_call_expr (fn, newarglist);
10219 return 0;
10223 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
10224 by the builtin will be ignored. UNLOCKED is true is true if this
10225 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
10226 the known length of the string. Return NULL_TREE if no simplification
10227 was possible. */
10229 tree
10230 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
10232 tree fn;
10233 /* If we're using an unlocked function, assume the other unlocked
10234 functions exist explicitly. */
10235 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
10236 : implicit_built_in_decls[BUILT_IN_FPUTC];
10237 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
10238 : implicit_built_in_decls[BUILT_IN_FWRITE];
10240 /* If the return value is used, don't do the transformation. */
10241 if (!ignore)
10242 return 0;
10244 /* Verify the arguments in the original call. */
10245 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10246 return 0;
10248 if (! len)
10249 len = c_strlen (TREE_VALUE (arglist), 0);
10251 /* Get the length of the string passed to fputs. If the length
10252 can't be determined, punt. */
10253 if (!len
10254 || TREE_CODE (len) != INTEGER_CST)
10255 return 0;
10257 switch (compare_tree_int (len, 1))
10259 case -1: /* length is 0, delete the call entirely . */
10260 return omit_one_operand (integer_type_node, integer_zero_node,
10261 TREE_VALUE (TREE_CHAIN (arglist)));
10263 case 0: /* length is 1, call fputc. */
10265 const char *p = c_getstr (TREE_VALUE (arglist));
10267 if (p != NULL)
10269 /* New argument list transforming fputs(string, stream) to
10270 fputc(string[0], stream). */
10271 arglist = build_tree_list (NULL_TREE,
10272 TREE_VALUE (TREE_CHAIN (arglist)));
10273 arglist = tree_cons (NULL_TREE,
10274 build_int_cst (NULL_TREE, p[0]),
10275 arglist);
10276 fn = fn_fputc;
10277 break;
10280 /* FALLTHROUGH */
10281 case 1: /* length is greater than 1, call fwrite. */
10283 tree string_arg;
10285 /* If optimizing for size keep fputs. */
10286 if (optimize_size)
10287 return 0;
10288 string_arg = TREE_VALUE (arglist);
10289 /* New argument list transforming fputs(string, stream) to
10290 fwrite(string, 1, len, stream). */
10291 arglist = build_tree_list (NULL_TREE,
10292 TREE_VALUE (TREE_CHAIN (arglist)));
10293 arglist = tree_cons (NULL_TREE, len, arglist);
10294 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
10295 arglist = tree_cons (NULL_TREE, string_arg, arglist);
10296 fn = fn_fwrite;
10297 break;
10299 default:
10300 gcc_unreachable ();
10303 /* If the replacement _DECL isn't initialized, don't do the
10304 transformation. */
10305 if (!fn)
10306 return 0;
10308 /* These optimizations are only performed when the result is ignored,
10309 hence there's no need to cast the result to integer_type_node. */
10310 return build_function_call_expr (fn, arglist);
10313 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
10314 produced. False otherwise. This is done so that we don't output the error
10315 or warning twice or three times. */
10316 bool
10317 fold_builtin_next_arg (tree arglist)
10319 tree fntype = TREE_TYPE (current_function_decl);
10321 if (TYPE_ARG_TYPES (fntype) == 0
10322 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
10323 == void_type_node))
10325 error ("%<va_start%> used in function with fixed args");
10326 return true;
10328 else if (!arglist)
10330 /* Evidently an out of date version of <stdarg.h>; can't validate
10331 va_start's second argument, but can still work as intended. */
10332 warning (0, "%<__builtin_next_arg%> called without an argument");
10333 return true;
10335 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
10336 when we checked the arguments and if needed issued a warning. */
10337 else if (!TREE_CHAIN (arglist)
10338 || !integer_zerop (TREE_VALUE (arglist))
10339 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
10340 || TREE_CHAIN (TREE_CHAIN (arglist)))
10342 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
10343 tree arg = TREE_VALUE (arglist);
10345 if (TREE_CHAIN (arglist))
10347 error ("%<va_start%> used with too many arguments");
10348 return true;
10351 /* Strip off all nops for the sake of the comparison. This
10352 is not quite the same as STRIP_NOPS. It does more.
10353 We must also strip off INDIRECT_EXPR for C++ reference
10354 parameters. */
10355 while (TREE_CODE (arg) == NOP_EXPR
10356 || TREE_CODE (arg) == CONVERT_EXPR
10357 || TREE_CODE (arg) == NON_LVALUE_EXPR
10358 || TREE_CODE (arg) == INDIRECT_REF)
10359 arg = TREE_OPERAND (arg, 0);
10360 if (arg != last_parm)
10362 /* FIXME: Sometimes with the tree optimizers we can get the
10363 not the last argument even though the user used the last
10364 argument. We just warn and set the arg to be the last
10365 argument so that we will get wrong-code because of
10366 it. */
10367 warning (0, "second parameter of %<va_start%> not last named argument");
10369 /* We want to verify the second parameter just once before the tree
10370 optimizers are run and then avoid keeping it in the tree,
10371 as otherwise we could warn even for correct code like:
10372 void foo (int i, ...)
10373 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
10374 TREE_VALUE (arglist) = integer_zero_node;
10375 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
10377 return false;
10381 /* Simplify a call to the sprintf builtin.
10383 Return 0 if no simplification was possible, otherwise return the
10384 simplified form of the call as a tree. If IGNORED is true, it means that
10385 the caller does not use the returned value of the function. */
10387 static tree
10388 fold_builtin_sprintf (tree arglist, int ignored)
10390 tree call, retval, dest, fmt;
10391 const char *fmt_str = NULL;
10393 /* Verify the required arguments in the original call. We deal with two
10394 types of sprintf() calls: 'sprintf (str, fmt)' and
10395 'sprintf (dest, "%s", orig)'. */
10396 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
10397 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
10398 VOID_TYPE))
10399 return NULL_TREE;
10401 /* Get the destination string and the format specifier. */
10402 dest = TREE_VALUE (arglist);
10403 fmt = TREE_VALUE (TREE_CHAIN (arglist));
10405 /* Check whether the format is a literal string constant. */
10406 fmt_str = c_getstr (fmt);
10407 if (fmt_str == NULL)
10408 return NULL_TREE;
10410 call = NULL_TREE;
10411 retval = NULL_TREE;
10413 if (!init_target_chars())
10414 return 0;
10416 /* If the format doesn't contain % args or %%, use strcpy. */
10417 if (strchr (fmt_str, target_percent) == NULL)
10419 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10421 if (!fn)
10422 return NULL_TREE;
10424 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10425 'format' is known to contain no % formats. */
10426 arglist = build_tree_list (NULL_TREE, fmt);
10427 arglist = tree_cons (NULL_TREE, dest, arglist);
10428 call = build_function_call_expr (fn, arglist);
10429 if (!ignored)
10430 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
10433 /* If the format is "%s", use strcpy if the result isn't used. */
10434 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
10436 tree fn, orig;
10437 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10439 if (!fn)
10440 return NULL_TREE;
10442 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
10443 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10444 arglist = build_tree_list (NULL_TREE, orig);
10445 arglist = tree_cons (NULL_TREE, dest, arglist);
10446 if (!ignored)
10448 retval = c_strlen (orig, 1);
10449 if (!retval || TREE_CODE (retval) != INTEGER_CST)
10450 return NULL_TREE;
10452 call = build_function_call_expr (fn, arglist);
10455 if (call && retval)
10457 retval = fold_convert
10458 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
10459 retval);
10460 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
10462 else
10463 return call;
10466 /* Expand a call to __builtin_object_size. */
10469 expand_builtin_object_size (tree exp)
10471 tree ost;
10472 int object_size_type;
10473 tree fndecl = get_callee_fndecl (exp);
10474 tree arglist = TREE_OPERAND (exp, 1);
10475 location_t locus = EXPR_LOCATION (exp);
10477 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10479 error ("%Hfirst argument of %D must be a pointer, second integer constant",
10480 &locus, fndecl);
10481 expand_builtin_trap ();
10482 return const0_rtx;
10485 ost = TREE_VALUE (TREE_CHAIN (arglist));
10486 STRIP_NOPS (ost);
10488 if (TREE_CODE (ost) != INTEGER_CST
10489 || tree_int_cst_sgn (ost) < 0
10490 || compare_tree_int (ost, 3) > 0)
10492 error ("%Hlast argument of %D is not integer constant between 0 and 3",
10493 &locus, fndecl);
10494 expand_builtin_trap ();
10495 return const0_rtx;
10498 object_size_type = tree_low_cst (ost, 0);
10500 return object_size_type < 2 ? constm1_rtx : const0_rtx;
10503 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10504 FCODE is the BUILT_IN_* to use.
10505 Return 0 if we failed; the caller should emit a normal call,
10506 otherwise try to get the result in TARGET, if convenient (and in
10507 mode MODE if that's convenient). */
10509 static rtx
10510 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10511 enum built_in_function fcode)
10513 tree arglist = TREE_OPERAND (exp, 1);
10514 tree dest, src, len, size;
10516 if (!validate_arglist (arglist,
10517 POINTER_TYPE,
10518 fcode == BUILT_IN_MEMSET_CHK
10519 ? INTEGER_TYPE : POINTER_TYPE,
10520 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10521 return 0;
10523 dest = TREE_VALUE (arglist);
10524 src = TREE_VALUE (TREE_CHAIN (arglist));
10525 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10526 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10528 if (! host_integerp (size, 1))
10529 return 0;
10531 if (host_integerp (len, 1) || integer_all_onesp (size))
10533 tree fn;
10535 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10537 location_t locus = EXPR_LOCATION (exp);
10538 warning (0, "%Hcall to %D will always overflow destination buffer",
10539 &locus, get_callee_fndecl (exp));
10540 return 0;
10543 arglist = build_tree_list (NULL_TREE, len);
10544 arglist = tree_cons (NULL_TREE, src, arglist);
10545 arglist = tree_cons (NULL_TREE, dest, arglist);
10547 fn = NULL_TREE;
10548 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10549 mem{cpy,pcpy,move,set} is available. */
10550 switch (fcode)
10552 case BUILT_IN_MEMCPY_CHK:
10553 fn = built_in_decls[BUILT_IN_MEMCPY];
10554 break;
10555 case BUILT_IN_MEMPCPY_CHK:
10556 fn = built_in_decls[BUILT_IN_MEMPCPY];
10557 break;
10558 case BUILT_IN_MEMMOVE_CHK:
10559 fn = built_in_decls[BUILT_IN_MEMMOVE];
10560 break;
10561 case BUILT_IN_MEMSET_CHK:
10562 fn = built_in_decls[BUILT_IN_MEMSET];
10563 break;
10564 default:
10565 break;
10568 if (! fn)
10569 return 0;
10571 fn = build_function_call_expr (fn, arglist);
10572 if (TREE_CODE (fn) == CALL_EXPR)
10573 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10574 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10576 else if (fcode == BUILT_IN_MEMSET_CHK)
10577 return 0;
10578 else
10580 unsigned int dest_align
10581 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10583 /* If DEST is not a pointer type, call the normal function. */
10584 if (dest_align == 0)
10585 return 0;
10587 /* If SRC and DEST are the same (and not volatile), do nothing. */
10588 if (operand_equal_p (src, dest, 0))
10590 tree expr;
10592 if (fcode != BUILT_IN_MEMPCPY_CHK)
10594 /* Evaluate and ignore LEN in case it has side-effects. */
10595 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10596 return expand_expr (dest, target, mode, EXPAND_NORMAL);
10599 len = fold_convert (TREE_TYPE (dest), len);
10600 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10601 return expand_expr (expr, target, mode, EXPAND_NORMAL);
10604 /* __memmove_chk special case. */
10605 if (fcode == BUILT_IN_MEMMOVE_CHK)
10607 unsigned int src_align
10608 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10610 if (src_align == 0)
10611 return 0;
10613 /* If src is categorized for a readonly section we can use
10614 normal __memcpy_chk. */
10615 if (readonly_data_expr (src))
10617 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10618 if (!fn)
10619 return 0;
10620 fn = build_function_call_expr (fn, arglist);
10621 if (TREE_CODE (fn) == CALL_EXPR)
10622 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10623 return expand_expr (fn, target, mode, EXPAND_NORMAL);
10626 return 0;
10630 /* Emit warning if a buffer overflow is detected at compile time. */
10632 static void
10633 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10635 int arg_mask, is_strlen = 0;
10636 tree arglist = TREE_OPERAND (exp, 1), a;
10637 tree len, size;
10638 location_t locus;
10640 switch (fcode)
10642 case BUILT_IN_STRCPY_CHK:
10643 case BUILT_IN_STPCPY_CHK:
10644 /* For __strcat_chk the warning will be emitted only if overflowing
10645 by at least strlen (dest) + 1 bytes. */
10646 case BUILT_IN_STRCAT_CHK:
10647 arg_mask = 6;
10648 is_strlen = 1;
10649 break;
10650 case BUILT_IN_STRNCAT_CHK:
10651 /* For __strncat_chk the warning will be emitted only if overflowing
10652 by at least strlen (dest) + 1 bytes. */
10653 arg_mask = 12;
10654 break;
10655 case BUILT_IN_STRNCPY_CHK:
10656 arg_mask = 12;
10657 break;
10658 case BUILT_IN_SNPRINTF_CHK:
10659 case BUILT_IN_VSNPRINTF_CHK:
10660 arg_mask = 10;
10661 break;
10662 default:
10663 gcc_unreachable ();
10666 len = NULL_TREE;
10667 size = NULL_TREE;
10668 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10669 if (arg_mask & 1)
10671 if (len)
10672 size = a;
10673 else
10674 len = a;
10677 if (!len || !size)
10678 return;
10680 len = TREE_VALUE (len);
10681 size = TREE_VALUE (size);
10683 if (! host_integerp (size, 1) || integer_all_onesp (size))
10684 return;
10686 if (is_strlen)
10688 len = c_strlen (len, 1);
10689 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10690 return;
10692 else if (fcode == BUILT_IN_STRNCAT_CHK)
10694 tree src = TREE_VALUE (TREE_CHAIN (arglist));
10695 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10696 return;
10697 src = c_strlen (src, 1);
10698 if (! src || ! host_integerp (src, 1))
10700 locus = EXPR_LOCATION (exp);
10701 warning (0, "%Hcall to %D might overflow destination buffer",
10702 &locus, get_callee_fndecl (exp));
10703 return;
10705 else if (tree_int_cst_lt (src, size))
10706 return;
10708 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10709 return;
10711 locus = EXPR_LOCATION (exp);
10712 warning (0, "%Hcall to %D will always overflow destination buffer",
10713 &locus, get_callee_fndecl (exp));
10716 /* Emit warning if a buffer overflow is detected at compile time
10717 in __sprintf_chk/__vsprintf_chk calls. */
10719 static void
10720 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10722 tree arglist = TREE_OPERAND (exp, 1);
10723 tree dest, size, len, fmt, flag;
10724 const char *fmt_str;
10726 /* Verify the required arguments in the original call. */
10727 if (! arglist)
10728 return;
10729 dest = TREE_VALUE (arglist);
10730 arglist = TREE_CHAIN (arglist);
10731 if (! arglist)
10732 return;
10733 flag = TREE_VALUE (arglist);
10734 arglist = TREE_CHAIN (arglist);
10735 if (! arglist)
10736 return;
10737 size = TREE_VALUE (arglist);
10738 arglist = TREE_CHAIN (arglist);
10739 if (! arglist)
10740 return;
10741 fmt = TREE_VALUE (arglist);
10742 arglist = TREE_CHAIN (arglist);
10744 if (! host_integerp (size, 1) || integer_all_onesp (size))
10745 return;
10747 /* Check whether the format is a literal string constant. */
10748 fmt_str = c_getstr (fmt);
10749 if (fmt_str == NULL)
10750 return;
10752 if (!init_target_chars())
10753 return;
10755 /* If the format doesn't contain % args or %%, we know its size. */
10756 if (strchr (fmt_str, target_percent) == 0)
10757 len = build_int_cstu (size_type_node, strlen (fmt_str));
10758 /* If the format is "%s" and first ... argument is a string literal,
10759 we know it too. */
10760 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10762 tree arg;
10764 if (! arglist)
10765 return;
10766 arg = TREE_VALUE (arglist);
10767 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10768 return;
10770 len = c_strlen (arg, 1);
10771 if (!len || ! host_integerp (len, 1))
10772 return;
10774 else
10775 return;
10777 if (! tree_int_cst_lt (len, size))
10779 location_t locus = EXPR_LOCATION (exp);
10780 warning (0, "%Hcall to %D will always overflow destination buffer",
10781 &locus, get_callee_fndecl (exp));
10785 /* Fold a call to __builtin_object_size, if possible. */
10787 tree
10788 fold_builtin_object_size (tree arglist)
10790 tree ptr, ost, ret = 0;
10791 int object_size_type;
10793 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10794 return 0;
10796 ptr = TREE_VALUE (arglist);
10797 ost = TREE_VALUE (TREE_CHAIN (arglist));
10798 STRIP_NOPS (ost);
10800 if (TREE_CODE (ost) != INTEGER_CST
10801 || tree_int_cst_sgn (ost) < 0
10802 || compare_tree_int (ost, 3) > 0)
10803 return 0;
10805 object_size_type = tree_low_cst (ost, 0);
10807 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10808 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10809 and (size_t) 0 for types 2 and 3. */
10810 if (TREE_SIDE_EFFECTS (ptr))
10811 return fold_convert (size_type_node,
10812 object_size_type < 2
10813 ? integer_minus_one_node : integer_zero_node);
10815 if (TREE_CODE (ptr) == ADDR_EXPR)
10816 ret = build_int_cstu (size_type_node,
10817 compute_builtin_object_size (ptr, object_size_type));
10819 else if (TREE_CODE (ptr) == SSA_NAME)
10821 unsigned HOST_WIDE_INT bytes;
10823 /* If object size is not known yet, delay folding until
10824 later. Maybe subsequent passes will help determining
10825 it. */
10826 bytes = compute_builtin_object_size (ptr, object_size_type);
10827 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10828 ? -1 : 0))
10829 ret = build_int_cstu (size_type_node, bytes);
10832 if (ret)
10834 ret = force_fit_type (ret, -1, false, false);
10835 if (TREE_CONSTANT_OVERFLOW (ret))
10836 ret = 0;
10839 return ret;
10842 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10843 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10844 code of the builtin. If MAXLEN is not NULL, it is maximum length
10845 passed as third argument. */
10847 tree
10848 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10849 enum built_in_function fcode)
10851 tree dest, src, len, size, fn;
10853 if (!validate_arglist (arglist,
10854 POINTER_TYPE,
10855 fcode == BUILT_IN_MEMSET_CHK
10856 ? INTEGER_TYPE : POINTER_TYPE,
10857 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10858 return 0;
10860 dest = TREE_VALUE (arglist);
10861 /* Actually val for __memset_chk, but it doesn't matter. */
10862 src = TREE_VALUE (TREE_CHAIN (arglist));
10863 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10864 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10866 /* If SRC and DEST are the same (and not volatile), return DEST
10867 (resp. DEST+LEN for __mempcpy_chk). */
10868 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10870 if (fcode != BUILT_IN_MEMPCPY_CHK)
10871 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10872 else
10874 tree temp = fold_convert (TREE_TYPE (dest), len);
10875 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10876 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10880 if (! host_integerp (size, 1))
10881 return 0;
10883 if (! integer_all_onesp (size))
10885 if (! host_integerp (len, 1))
10887 /* If LEN is not constant, try MAXLEN too.
10888 For MAXLEN only allow optimizing into non-_ocs function
10889 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10890 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10892 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10894 /* (void) __mempcpy_chk () can be optimized into
10895 (void) __memcpy_chk (). */
10896 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10897 if (!fn)
10898 return 0;
10900 return build_function_call_expr (fn, arglist);
10902 return 0;
10905 else
10906 maxlen = len;
10908 if (tree_int_cst_lt (size, maxlen))
10909 return 0;
10912 arglist = build_tree_list (NULL_TREE, len);
10913 arglist = tree_cons (NULL_TREE, src, arglist);
10914 arglist = tree_cons (NULL_TREE, dest, arglist);
10916 fn = NULL_TREE;
10917 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10918 mem{cpy,pcpy,move,set} is available. */
10919 switch (fcode)
10921 case BUILT_IN_MEMCPY_CHK:
10922 fn = built_in_decls[BUILT_IN_MEMCPY];
10923 break;
10924 case BUILT_IN_MEMPCPY_CHK:
10925 fn = built_in_decls[BUILT_IN_MEMPCPY];
10926 break;
10927 case BUILT_IN_MEMMOVE_CHK:
10928 fn = built_in_decls[BUILT_IN_MEMMOVE];
10929 break;
10930 case BUILT_IN_MEMSET_CHK:
10931 fn = built_in_decls[BUILT_IN_MEMSET];
10932 break;
10933 default:
10934 break;
10937 if (!fn)
10938 return 0;
10940 return build_function_call_expr (fn, arglist);
10943 /* Fold a call to the __st[rp]cpy_chk builtin.
10944 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10945 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10946 strings passed as second argument. */
10948 tree
10949 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10950 enum built_in_function fcode)
10952 tree dest, src, size, len, fn;
10954 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10955 VOID_TYPE))
10956 return 0;
10958 dest = TREE_VALUE (arglist);
10959 src = TREE_VALUE (TREE_CHAIN (arglist));
10960 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10962 /* If SRC and DEST are the same (and not volatile), return DEST. */
10963 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10964 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10966 if (! host_integerp (size, 1))
10967 return 0;
10969 if (! integer_all_onesp (size))
10971 len = c_strlen (src, 1);
10972 if (! len || ! host_integerp (len, 1))
10974 /* If LEN is not constant, try MAXLEN too.
10975 For MAXLEN only allow optimizing into non-_ocs function
10976 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10977 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10979 if (fcode == BUILT_IN_STPCPY_CHK)
10981 if (! ignore)
10982 return 0;
10984 /* If return value of __stpcpy_chk is ignored,
10985 optimize into __strcpy_chk. */
10986 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10987 if (!fn)
10988 return 0;
10990 return build_function_call_expr (fn, arglist);
10993 if (! len || TREE_SIDE_EFFECTS (len))
10994 return 0;
10996 /* If c_strlen returned something, but not a constant,
10997 transform __strcpy_chk into __memcpy_chk. */
10998 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10999 if (!fn)
11000 return 0;
11002 len = size_binop (PLUS_EXPR, len, ssize_int (1));
11003 arglist = build_tree_list (NULL_TREE, size);
11004 arglist = tree_cons (NULL_TREE, len, arglist);
11005 arglist = tree_cons (NULL_TREE, src, arglist);
11006 arglist = tree_cons (NULL_TREE, dest, arglist);
11007 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
11008 build_function_call_expr (fn, arglist));
11011 else
11012 maxlen = len;
11014 if (! tree_int_cst_lt (maxlen, size))
11015 return 0;
11018 arglist = build_tree_list (NULL_TREE, src);
11019 arglist = tree_cons (NULL_TREE, dest, arglist);
11021 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
11022 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
11023 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
11024 if (!fn)
11025 return 0;
11027 return build_function_call_expr (fn, arglist);
11030 /* Fold a call to the __strncpy_chk builtin.
11031 If MAXLEN is not NULL, it is maximum length passed as third argument. */
11033 tree
11034 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
11036 tree dest, src, size, len, fn;
11038 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11039 INTEGER_TYPE, VOID_TYPE))
11040 return 0;
11042 dest = TREE_VALUE (arglist);
11043 src = TREE_VALUE (TREE_CHAIN (arglist));
11044 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11045 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
11047 if (! host_integerp (size, 1))
11048 return 0;
11050 if (! integer_all_onesp (size))
11052 if (! host_integerp (len, 1))
11054 /* If LEN is not constant, try MAXLEN too.
11055 For MAXLEN only allow optimizing into non-_ocs function
11056 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11057 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11058 return 0;
11060 else
11061 maxlen = len;
11063 if (tree_int_cst_lt (size, maxlen))
11064 return 0;
11067 arglist = build_tree_list (NULL_TREE, len);
11068 arglist = tree_cons (NULL_TREE, src, arglist);
11069 arglist = tree_cons (NULL_TREE, dest, arglist);
11071 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
11072 fn = built_in_decls[BUILT_IN_STRNCPY];
11073 if (!fn)
11074 return 0;
11076 return build_function_call_expr (fn, arglist);
11079 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
11081 static tree
11082 fold_builtin_strcat_chk (tree fndecl, tree arglist)
11084 tree dest, src, size, fn;
11085 const char *p;
11087 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11088 VOID_TYPE))
11089 return 0;
11091 dest = TREE_VALUE (arglist);
11092 src = TREE_VALUE (TREE_CHAIN (arglist));
11093 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11095 p = c_getstr (src);
11096 /* If the SRC parameter is "", return DEST. */
11097 if (p && *p == '\0')
11098 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
11100 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
11101 return 0;
11103 arglist = build_tree_list (NULL_TREE, src);
11104 arglist = tree_cons (NULL_TREE, dest, arglist);
11106 /* If __builtin_strcat_chk is used, assume strcat is available. */
11107 fn = built_in_decls[BUILT_IN_STRCAT];
11108 if (!fn)
11109 return 0;
11111 return build_function_call_expr (fn, arglist);
11114 /* Fold a call to the __strncat_chk builtin EXP. */
11116 static tree
11117 fold_builtin_strncat_chk (tree fndecl, tree arglist)
11119 tree dest, src, size, len, fn;
11120 const char *p;
11122 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11123 INTEGER_TYPE, VOID_TYPE))
11124 return 0;
11126 dest = TREE_VALUE (arglist);
11127 src = TREE_VALUE (TREE_CHAIN (arglist));
11128 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11129 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
11131 p = c_getstr (src);
11132 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
11133 if (p && *p == '\0')
11134 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
11135 else if (integer_zerop (len))
11136 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
11138 if (! host_integerp (size, 1))
11139 return 0;
11141 if (! integer_all_onesp (size))
11143 tree src_len = c_strlen (src, 1);
11144 if (src_len
11145 && host_integerp (src_len, 1)
11146 && host_integerp (len, 1)
11147 && ! tree_int_cst_lt (len, src_len))
11149 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
11150 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
11151 if (!fn)
11152 return 0;
11154 arglist = build_tree_list (NULL_TREE, size);
11155 arglist = tree_cons (NULL_TREE, src, arglist);
11156 arglist = tree_cons (NULL_TREE, dest, arglist);
11157 return build_function_call_expr (fn, arglist);
11159 return 0;
11162 arglist = build_tree_list (NULL_TREE, len);
11163 arglist = tree_cons (NULL_TREE, src, arglist);
11164 arglist = tree_cons (NULL_TREE, dest, arglist);
11166 /* If __builtin_strncat_chk is used, assume strncat is available. */
11167 fn = built_in_decls[BUILT_IN_STRNCAT];
11168 if (!fn)
11169 return 0;
11171 return build_function_call_expr (fn, arglist);
11174 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
11175 a normal call should be emitted rather than expanding the function
11176 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
11178 static tree
11179 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
11181 tree dest, size, len, fn, fmt, flag;
11182 const char *fmt_str;
11184 /* Verify the required arguments in the original call. */
11185 if (! arglist)
11186 return 0;
11187 dest = TREE_VALUE (arglist);
11188 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11189 return 0;
11190 arglist = TREE_CHAIN (arglist);
11191 if (! arglist)
11192 return 0;
11193 flag = TREE_VALUE (arglist);
11194 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
11195 return 0;
11196 arglist = TREE_CHAIN (arglist);
11197 if (! arglist)
11198 return 0;
11199 size = TREE_VALUE (arglist);
11200 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11201 return 0;
11202 arglist = TREE_CHAIN (arglist);
11203 if (! arglist)
11204 return 0;
11205 fmt = TREE_VALUE (arglist);
11206 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11207 return 0;
11208 arglist = TREE_CHAIN (arglist);
11210 if (! host_integerp (size, 1))
11211 return 0;
11213 len = NULL_TREE;
11215 if (!init_target_chars())
11216 return 0;
11218 /* Check whether the format is a literal string constant. */
11219 fmt_str = c_getstr (fmt);
11220 if (fmt_str != NULL)
11222 /* If the format doesn't contain % args or %%, we know the size. */
11223 if (strchr (fmt_str, target_percent) == 0)
11225 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
11226 len = build_int_cstu (size_type_node, strlen (fmt_str));
11228 /* If the format is "%s" and first ... argument is a string literal,
11229 we know the size too. */
11230 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
11232 tree arg;
11234 if (arglist && !TREE_CHAIN (arglist))
11236 arg = TREE_VALUE (arglist);
11237 if (POINTER_TYPE_P (TREE_TYPE (arg)))
11239 len = c_strlen (arg, 1);
11240 if (! len || ! host_integerp (len, 1))
11241 len = NULL_TREE;
11247 if (! integer_all_onesp (size))
11249 if (! len || ! tree_int_cst_lt (len, size))
11250 return 0;
11253 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
11254 or if format doesn't contain % chars or is "%s". */
11255 if (! integer_zerop (flag))
11257 if (fmt_str == NULL)
11258 return 0;
11259 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11260 return 0;
11263 arglist = tree_cons (NULL_TREE, fmt, arglist);
11264 arglist = tree_cons (NULL_TREE, dest, arglist);
11266 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
11267 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
11268 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
11269 if (!fn)
11270 return 0;
11272 return build_function_call_expr (fn, arglist);
11275 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
11276 a normal call should be emitted rather than expanding the function
11277 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
11278 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
11279 passed as second argument. */
11281 tree
11282 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
11283 enum built_in_function fcode)
11285 tree dest, size, len, fn, fmt, flag;
11286 const char *fmt_str;
11288 /* Verify the required arguments in the original call. */
11289 if (! arglist)
11290 return 0;
11291 dest = TREE_VALUE (arglist);
11292 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11293 return 0;
11294 arglist = TREE_CHAIN (arglist);
11295 if (! arglist)
11296 return 0;
11297 len = TREE_VALUE (arglist);
11298 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11299 return 0;
11300 arglist = TREE_CHAIN (arglist);
11301 if (! arglist)
11302 return 0;
11303 flag = TREE_VALUE (arglist);
11304 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11305 return 0;
11306 arglist = TREE_CHAIN (arglist);
11307 if (! arglist)
11308 return 0;
11309 size = TREE_VALUE (arglist);
11310 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11311 return 0;
11312 arglist = TREE_CHAIN (arglist);
11313 if (! arglist)
11314 return 0;
11315 fmt = TREE_VALUE (arglist);
11316 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11317 return 0;
11318 arglist = TREE_CHAIN (arglist);
11320 if (! host_integerp (size, 1))
11321 return 0;
11323 if (! integer_all_onesp (size))
11325 if (! host_integerp (len, 1))
11327 /* If LEN is not constant, try MAXLEN too.
11328 For MAXLEN only allow optimizing into non-_ocs function
11329 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11330 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11331 return 0;
11333 else
11334 maxlen = len;
11336 if (tree_int_cst_lt (size, maxlen))
11337 return 0;
11340 if (!init_target_chars())
11341 return 0;
11343 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
11344 or if format doesn't contain % chars or is "%s". */
11345 if (! integer_zerop (flag))
11347 fmt_str = c_getstr (fmt);
11348 if (fmt_str == NULL)
11349 return 0;
11350 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11351 return 0;
11354 arglist = tree_cons (NULL_TREE, fmt, arglist);
11355 arglist = tree_cons (NULL_TREE, len, arglist);
11356 arglist = tree_cons (NULL_TREE, dest, arglist);
11358 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
11359 available. */
11360 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
11361 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
11362 if (!fn)
11363 return 0;
11365 return build_function_call_expr (fn, arglist);
11368 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
11370 Return 0 if no simplification was possible, otherwise return the
11371 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11372 code of the function to be simplified. */
11374 static tree
11375 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
11376 enum built_in_function fcode)
11378 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
11379 const char *fmt_str = NULL;
11381 /* If the return value is used, don't do the transformation. */
11382 if (! ignore)
11383 return 0;
11385 /* Verify the required arguments in the original call. */
11386 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
11388 tree flag;
11390 if (! arglist)
11391 return 0;
11392 flag = TREE_VALUE (arglist);
11393 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11394 || TREE_SIDE_EFFECTS (flag))
11395 return 0;
11396 arglist = TREE_CHAIN (arglist);
11399 if (! arglist)
11400 return 0;
11401 fmt = TREE_VALUE (arglist);
11402 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11403 return 0;
11404 arglist = TREE_CHAIN (arglist);
11406 /* Check whether the format is a literal string constant. */
11407 fmt_str = c_getstr (fmt);
11408 if (fmt_str == NULL)
11409 return NULL_TREE;
11411 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
11413 /* If we're using an unlocked function, assume the other
11414 unlocked functions exist explicitly. */
11415 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
11416 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
11418 else
11420 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
11421 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
11424 if (!init_target_chars())
11425 return 0;
11427 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
11429 const char *str;
11431 if (strcmp (fmt_str, target_percent_s) == 0)
11433 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11434 return 0;
11436 if (! arglist
11437 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11438 || TREE_CHAIN (arglist))
11439 return 0;
11441 str = c_getstr (TREE_VALUE (arglist));
11442 if (str == NULL)
11443 return 0;
11445 else
11447 /* The format specifier doesn't contain any '%' characters. */
11448 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
11449 && arglist)
11450 return 0;
11451 str = fmt_str;
11454 /* If the string was "", printf does nothing. */
11455 if (str[0] == '\0')
11456 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11458 /* If the string has length of 1, call putchar. */
11459 if (str[1] == '\0')
11461 /* Given printf("c"), (where c is any one character,)
11462 convert "c"[0] to an int and pass that to the replacement
11463 function. */
11464 arg = build_int_cst (NULL_TREE, str[0]);
11465 arglist = build_tree_list (NULL_TREE, arg);
11466 fn = fn_putchar;
11468 else
11470 /* If the string was "string\n", call puts("string"). */
11471 size_t len = strlen (str);
11472 if ((unsigned char)str[len - 1] == target_newline)
11474 /* Create a NUL-terminated string that's one char shorter
11475 than the original, stripping off the trailing '\n'. */
11476 char *newstr = alloca (len);
11477 memcpy (newstr, str, len - 1);
11478 newstr[len - 1] = 0;
11480 arg = build_string_literal (len, newstr);
11481 arglist = build_tree_list (NULL_TREE, arg);
11482 fn = fn_puts;
11484 else
11485 /* We'd like to arrange to call fputs(string,stdout) here,
11486 but we need stdout and don't have a way to get it yet. */
11487 return 0;
11491 /* The other optimizations can be done only on the non-va_list variants. */
11492 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11493 return 0;
11495 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
11496 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11498 if (! arglist
11499 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11500 || TREE_CHAIN (arglist))
11501 return 0;
11502 fn = fn_puts;
11505 /* If the format specifier was "%c", call __builtin_putchar(arg). */
11506 else if (strcmp (fmt_str, target_percent_c) == 0)
11508 if (! arglist
11509 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11510 || TREE_CHAIN (arglist))
11511 return 0;
11512 fn = fn_putchar;
11515 if (!fn)
11516 return 0;
11518 call = build_function_call_expr (fn, arglist);
11519 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11522 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11524 Return 0 if no simplification was possible, otherwise return the
11525 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11526 code of the function to be simplified. */
11528 static tree
11529 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11530 enum built_in_function fcode)
11532 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11533 const char *fmt_str = NULL;
11535 /* If the return value is used, don't do the transformation. */
11536 if (! ignore)
11537 return 0;
11539 /* Verify the required arguments in the original call. */
11540 if (! arglist)
11541 return 0;
11542 fp = TREE_VALUE (arglist);
11543 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11544 return 0;
11545 arglist = TREE_CHAIN (arglist);
11547 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11549 tree flag;
11551 if (! arglist)
11552 return 0;
11553 flag = TREE_VALUE (arglist);
11554 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11555 || TREE_SIDE_EFFECTS (flag))
11556 return 0;
11557 arglist = TREE_CHAIN (arglist);
11560 if (! arglist)
11561 return 0;
11562 fmt = TREE_VALUE (arglist);
11563 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11564 return 0;
11565 arglist = TREE_CHAIN (arglist);
11567 /* Check whether the format is a literal string constant. */
11568 fmt_str = c_getstr (fmt);
11569 if (fmt_str == NULL)
11570 return NULL_TREE;
11572 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11574 /* If we're using an unlocked function, assume the other
11575 unlocked functions exist explicitly. */
11576 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11577 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11579 else
11581 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11582 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11585 if (!init_target_chars())
11586 return 0;
11588 /* If the format doesn't contain % args or %%, use strcpy. */
11589 if (strchr (fmt_str, target_percent) == NULL)
11591 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11592 && arglist)
11593 return 0;
11595 /* If the format specifier was "", fprintf does nothing. */
11596 if (fmt_str[0] == '\0')
11598 /* If FP has side-effects, just wait until gimplification is
11599 done. */
11600 if (TREE_SIDE_EFFECTS (fp))
11601 return 0;
11603 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11606 /* When "string" doesn't contain %, replace all cases of
11607 fprintf (fp, string) with fputs (string, fp). The fputs
11608 builtin will take care of special cases like length == 1. */
11609 arglist = build_tree_list (NULL_TREE, fp);
11610 arglist = tree_cons (NULL_TREE, fmt, arglist);
11611 fn = fn_fputs;
11614 /* The other optimizations can be done only on the non-va_list variants. */
11615 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11616 return 0;
11618 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11619 else if (strcmp (fmt_str, target_percent_s) == 0)
11621 if (! arglist
11622 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11623 || TREE_CHAIN (arglist))
11624 return 0;
11625 arg = TREE_VALUE (arglist);
11626 arglist = build_tree_list (NULL_TREE, fp);
11627 arglist = tree_cons (NULL_TREE, arg, arglist);
11628 fn = fn_fputs;
11631 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11632 else if (strcmp (fmt_str, target_percent_c) == 0)
11634 if (! arglist
11635 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11636 || TREE_CHAIN (arglist))
11637 return 0;
11638 arg = TREE_VALUE (arglist);
11639 arglist = build_tree_list (NULL_TREE, fp);
11640 arglist = tree_cons (NULL_TREE, arg, arglist);
11641 fn = fn_fputc;
11644 if (!fn)
11645 return 0;
11647 call = build_function_call_expr (fn, arglist);
11648 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11651 /* Initialize format string characters in the target charset. */
11653 static bool
11654 init_target_chars (void)
11656 static bool init;
11657 if (!init)
11659 target_newline = lang_hooks.to_target_charset ('\n');
11660 target_percent = lang_hooks.to_target_charset ('%');
11661 target_c = lang_hooks.to_target_charset ('c');
11662 target_s = lang_hooks.to_target_charset ('s');
11663 if (target_newline == 0 || target_percent == 0 || target_c == 0
11664 || target_s == 0)
11665 return false;
11667 target_percent_c[0] = target_percent;
11668 target_percent_c[1] = target_c;
11669 target_percent_c[2] = '\0';
11671 target_percent_s[0] = target_percent;
11672 target_percent_s[1] = target_s;
11673 target_percent_s[2] = '\0';
11675 target_percent_s_newline[0] = target_percent;
11676 target_percent_s_newline[1] = target_s;
11677 target_percent_s_newline[2] = target_newline;
11678 target_percent_s_newline[3] = '\0';
11680 init = true;
11682 return true;
11685 /* Helper function for do_mpfr_arg*(). Ensure M is a normal number
11686 and no overflow/underflow occurred. INEXACT is true if M was not
11687 exactly calculated. TYPE is the tree type for the result. This
11688 function assumes that you cleared the MPFR flags and then
11689 calculated M to see if anything subsequently set a flag prior to
11690 entering this function. Return NULL_TREE if any checks fail. */
11692 static tree
11693 do_mpfr_ckconv(mpfr_srcptr m, tree type, int inexact)
11695 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
11696 overflow/underflow occurred. If -frounding-math, proceed iff the
11697 result of calling FUNC was exact. */
11698 if (mpfr_number_p (m) && !mpfr_overflow_p() && !mpfr_underflow_p()
11699 && (!flag_rounding_math || !inexact))
11701 REAL_VALUE_TYPE rr;
11703 real_from_mpfr (&rr, m);
11704 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
11705 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
11706 but the mpft_t is not, then we underflowed in the
11707 conversion. */
11708 if (!real_isnan (&rr) && !real_isinf (&rr)
11709 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
11711 REAL_VALUE_TYPE rmode;
11713 real_convert (&rmode, TYPE_MODE (type), &rr);
11714 /* Proceed iff the specified mode can hold the value. */
11715 if (real_identical (&rmode, &rr))
11716 return build_real (type, rmode);
11719 return NULL_TREE;
11722 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
11723 FUNC on it and return the resulting value as a tree with type TYPE.
11724 If MIN and/or MAX are not NULL, then the supplied ARG must be
11725 within those bounds. If INCLUSIVE is true, then MIN/MAX are
11726 acceptable values, otherwise they are not. The mpfr precision is
11727 set to the precision of TYPE. We assume that function FUNC returns
11728 zero if the result could be calculated exactly within the requested
11729 precision. */
11731 static tree
11732 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
11733 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
11734 bool inclusive)
11736 tree result = NULL_TREE;
11738 STRIP_NOPS (arg);
11740 /* To proceed, MPFR must exactly represent the target floating point
11741 format, which only happens when the target base equals two. */
11742 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11743 && TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11745 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11747 if (!real_isnan (ra) && !real_isinf (ra)
11748 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
11749 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
11751 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11752 int inexact;
11753 mpfr_t m;
11755 mpfr_init2 (m, prec);
11756 mpfr_from_real (m, ra);
11757 mpfr_clear_flags();
11758 inexact = func (m, m, GMP_RNDN);
11759 result = do_mpfr_ckconv (m, type, inexact);
11760 mpfr_clear (m);
11764 return result;
11767 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
11768 FUNC on it and return the resulting value as a tree with type TYPE.
11769 The mpfr precision is set to the precision of TYPE. We assume that
11770 function FUNC returns zero if the result could be calculated
11771 exactly within the requested precision. */
11773 static tree
11774 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
11775 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11777 tree result = NULL_TREE;
11779 STRIP_NOPS (arg1);
11780 STRIP_NOPS (arg2);
11782 /* To proceed, MPFR must exactly represent the target floating point
11783 format, which only happens when the target base equals two. */
11784 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11785 && TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
11786 && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2))
11788 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11789 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11791 if (!real_isnan (ra1) && !real_isinf (ra1)
11792 && !real_isnan (ra2) && !real_isinf (ra2))
11794 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11795 int inexact;
11796 mpfr_t m1, m2;
11798 mpfr_inits2 (prec, m1, m2, NULL);
11799 mpfr_from_real (m1, ra1);
11800 mpfr_from_real (m2, ra2);
11801 mpfr_clear_flags();
11802 inexact = func (m1, m1, m2, GMP_RNDN);
11803 result = do_mpfr_ckconv (m1, type, inexact);
11804 mpfr_clears (m1, m2, NULL);
11808 return result;
11811 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
11812 FUNC on it and return the resulting value as a tree with type TYPE.
11813 The mpfr precision is set to the precision of TYPE. We assume that
11814 function FUNC returns zero if the result could be calculated
11815 exactly within the requested precision. */
11817 static tree
11818 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
11819 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11821 tree result = NULL_TREE;
11823 STRIP_NOPS (arg1);
11824 STRIP_NOPS (arg2);
11825 STRIP_NOPS (arg3);
11827 /* To proceed, MPFR must exactly represent the target floating point
11828 format, which only happens when the target base equals two. */
11829 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11830 && TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
11831 && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2)
11832 && TREE_CODE (arg3) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg3))
11834 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11835 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11836 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
11838 if (!real_isnan (ra1) && !real_isinf (ra1)
11839 && !real_isnan (ra2) && !real_isinf (ra2)
11840 && !real_isnan (ra3) && !real_isinf (ra3))
11842 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11843 int inexact;
11844 mpfr_t m1, m2, m3;
11846 mpfr_inits2 (prec, m1, m2, m3, NULL);
11847 mpfr_from_real (m1, ra1);
11848 mpfr_from_real (m2, ra2);
11849 mpfr_from_real (m3, ra3);
11850 mpfr_clear_flags();
11851 inexact = func (m1, m1, m2, m3, GMP_RNDN);
11852 result = do_mpfr_ckconv (m1, type, inexact);
11853 mpfr_clears (m1, m2, m3, NULL);
11857 return result;
11860 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
11861 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
11862 If ARG_SINP and ARG_COSP are NULL then the result is returned
11863 as a complex value.
11864 The type is taken from the type of ARG and is used for setting the
11865 precision of the calculation and results. */
11867 static tree
11868 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
11870 tree const type = TREE_TYPE (arg);
11871 tree result = NULL_TREE;
11873 STRIP_NOPS (arg);
11875 /* To proceed, MPFR must exactly represent the target floating point
11876 format, which only happens when the target base equals two. */
11877 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11878 && TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11880 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11882 if (!real_isnan (ra) && !real_isinf (ra))
11884 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11885 tree result_s, result_c;
11886 int inexact;
11887 mpfr_t m, ms, mc;
11889 mpfr_inits2 (prec, m, ms, mc, NULL);
11890 mpfr_from_real (m, ra);
11891 mpfr_clear_flags();
11892 inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
11893 result_s = do_mpfr_ckconv (ms, type, inexact);
11894 result_c = do_mpfr_ckconv (mc, type, inexact);
11895 mpfr_clears (m, ms, mc, NULL);
11896 if (result_s && result_c)
11898 /* If we are to return in a complex value do so. */
11899 if (!arg_sinp && !arg_cosp)
11900 return build_complex (build_complex_type (type),
11901 result_c, result_s);
11903 /* Dereference the sin/cos pointer arguments. */
11904 arg_sinp = build_fold_indirect_ref (arg_sinp);
11905 arg_cosp = build_fold_indirect_ref (arg_cosp);
11906 /* Proceed if valid pointer type were passed in. */
11907 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
11908 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
11910 /* Set the values. */
11911 result_s = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_sinp,
11912 result_s);
11913 TREE_SIDE_EFFECTS (result_s) = 1;
11914 result_c = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_cosp,
11915 result_c);
11916 TREE_SIDE_EFFECTS (result_c) = 1;
11917 /* Combine the assignments into a compound expr. */
11918 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
11919 result_s, result_c));
11924 return result;